Hi,
Reposting as this has gone nowhere. Regenerated for line changes and
with Nikolai's Tested-by annotation for 2/2, which now have been verified
in combination with generic PIRQ router updates posted separately (there's
no ordering dependency between the two patch series).
Nikolai has observed the trigger mode not being fixed up once it has been
incorrectly set by the BIOS for PCI devices, causing all kinds of usual
issues. As it turns out we don't have a PIRQ router defined for the
SiS85C497 southbridge, which Nikolai's system uses, and which is different
from the SiS85C503 southbridge we have support for.
As we use the generic `sis' infix (capitalised or not) for the SiS85C503
southbridge I have prepared this small patch series to first make the
existing SiS program entities use a more specific `sis503' infix, and then
provide a suitable PIRQ router for the SiS85C497 device.
See individual change descriptions for further details.
Please apply.
Maciej
In preparation to adding support for the SiS85C497 PIRQ router add `503'
to the names of SiS85C503 PIRQ router code entities so that they clearly
indicate which device they refer to.
Also restructure `sis_router_probe' such that new device IDs will be
just new switch cases.
No functional change.
Signed-off-by: Maciej W. Rozycki <[email protected]>
---
No change from v1.
---
arch/x86/pci/irq.c | 33 ++++++++++++++++++---------------
1 file changed, 18 insertions(+), 15 deletions(-)
linux-x86-pirq-router-sis85c503.diff
Index: linux-macro/arch/x86/pci/irq.c
===================================================================
--- linux-macro.orig/arch/x86/pci/irq.c
+++ linux-macro/arch/x86/pci/irq.c
@@ -641,11 +641,12 @@ static int pirq_cyrix_set(struct pci_dev
* bit 6-4 are probably unused, not like 5595
*/
-#define PIRQ_SIS_IRQ_MASK 0x0f
-#define PIRQ_SIS_IRQ_DISABLE 0x80
-#define PIRQ_SIS_USB_ENABLE 0x40
+#define PIRQ_SIS503_IRQ_MASK 0x0f
+#define PIRQ_SIS503_IRQ_DISABLE 0x80
+#define PIRQ_SIS503_USB_ENABLE 0x40
-static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+static int pirq_sis503_get(struct pci_dev *router, struct pci_dev *dev,
+ int pirq)
{
u8 x;
int reg;
@@ -654,10 +655,11 @@ static int pirq_sis_get(struct pci_dev *
if (reg >= 0x01 && reg <= 0x04)
reg += 0x40;
pci_read_config_byte(router, reg, &x);
- return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK);
+ return (x & PIRQ_SIS503_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS503_IRQ_MASK);
}
-static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+static int pirq_sis503_set(struct pci_dev *router, struct pci_dev *dev,
+ int pirq, int irq)
{
u8 x;
int reg;
@@ -666,8 +668,8 @@ static int pirq_sis_set(struct pci_dev *
if (reg >= 0x01 && reg <= 0x04)
reg += 0x40;
pci_read_config_byte(router, reg, &x);
- x &= ~(PIRQ_SIS_IRQ_MASK | PIRQ_SIS_IRQ_DISABLE);
- x |= irq ? irq: PIRQ_SIS_IRQ_DISABLE;
+ x &= ~(PIRQ_SIS503_IRQ_MASK | PIRQ_SIS503_IRQ_DISABLE);
+ x |= irq ? irq : PIRQ_SIS503_IRQ_DISABLE;
pci_write_config_byte(router, reg, x);
return 1;
}
@@ -966,13 +968,14 @@ static __init int serverworks_router_pro
static __init int sis_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
{
- if (device != PCI_DEVICE_ID_SI_503)
- return 0;
-
- r->name = "SIS";
- r->get = pirq_sis_get;
- r->set = pirq_sis_set;
- return 1;
+ switch (device) {
+ case PCI_DEVICE_ID_SI_503:
+ r->name = "SiS85C503";
+ r->get = pirq_sis503_get;
+ r->set = pirq_sis503_set;
+ return 1;
+ }
+ return 0;
}
static __init int cyrix_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
The SiS 85C496/497 486 Green PC VESA/ISA/PCI Chipset has support for PCI
steering and the ELCR register implemented. These features are handled
by the SiS85C497 AT Bus Controller & Megacell (ATM) ISA bridge, however
the device is wired as a peer bridge directly to the host bus and has
its PCI configuration registers decoded at addresses 0x80-0xff by the
accompanying SiS85C496 PCI & CPU Memory Controller (PCM) host bridge[1].
Therefore we need to match on the host bridge's vendor and device ID.
Like with the SiS85C503 PIRQ router handle link value ranges of 1-4 and
0xc0-0xc3, corresponding respectively to PIRQ line numbers counted from
1 and link register PCI configuration space addresses.
References:
[1] "486 Green PC VESA/ISA/PCI Chipset, SiS 85C496/497", Rev 3.0,
Silicon Integrated Systems Corp., July 1995, Part IV, Section 3.
"PCI Configuration Space Registers (00h ~ FFh)", p. 114
Signed-off-by: Maciej W. Rozycki <[email protected]>
Tested-by: Nikolai Zhubr <[email protected]>
---
arch/x86/pci/irq.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 80 insertions(+)
linux-x86-pirq-router-sis85c497.diff
Index: linux-macro/arch/x86/pci/irq.c
===================================================================
--- linux-macro.orig/arch/x86/pci/irq.c
+++ linux-macro/arch/x86/pci/irq.c
@@ -580,6 +580,81 @@ static int pirq_cyrix_set(struct pci_dev
return 1;
}
+
+/*
+ * PIRQ routing for the SiS85C497 AT Bus Controller & Megacell (ATM)
+ * ISA bridge used with the SiS 85C496/497 486 Green PC VESA/ISA/PCI
+ * Chipset.
+ *
+ * There are four PCI INTx#-to-IRQ Link registers provided in the
+ * SiS85C497 part of the peculiar combined 85C496/497 configuration
+ * space decoded by the SiS85C496 PCI & CPU Memory Controller (PCM)
+ * host bridge, at 0xc0/0xc1/0xc2/0xc3 respectively for the PCI INT
+ * A/B/C/D lines. Bit 7 enables the respective link if set and bits
+ * 3:0 select the 8259A IRQ line as follows:
+ *
+ * 0000 : Reserved
+ * 0001 : Reserved
+ * 0010 : Reserved
+ * 0011 : IRQ3
+ * 0100 : IRQ4
+ * 0101 : IRQ5
+ * 0110 : IRQ6
+ * 0111 : IRQ7
+ * 1000 : Reserved
+ * 1001 : IRQ9
+ * 1010 : IRQ10
+ * 1011 : IRQ11
+ * 1100 : IRQ12
+ * 1101 : Reserved
+ * 1110 : IRQ14
+ * 1111 : IRQ15
+ *
+ * We avoid using a reserved value for disabled links, hence the
+ * choice of IRQ15 for that case.
+ *
+ * References:
+ *
+ * "486 Green PC VESA/ISA/PCI Chipset, SiS 85C496/497", Rev 3.0,
+ * Silicon Integrated Systems Corp., July 1995
+ */
+
+#define PCI_SIS497_INTA_TO_IRQ_LINK 0xc0u
+
+#define PIRQ_SIS497_IRQ_MASK 0x0fu
+#define PIRQ_SIS497_IRQ_ENABLE 0x80u
+
+static int pirq_sis497_get(struct pci_dev *router, struct pci_dev *dev,
+ int pirq)
+{
+ int reg;
+ u8 x;
+
+ reg = pirq;
+ if (reg >= 1 && reg <= 4)
+ reg += PCI_SIS497_INTA_TO_IRQ_LINK - 1;
+
+ pci_read_config_byte(router, reg, &x);
+ return (x & PIRQ_SIS497_IRQ_ENABLE) ? (x & PIRQ_SIS497_IRQ_MASK) : 0;
+}
+
+static int pirq_sis497_set(struct pci_dev *router, struct pci_dev *dev,
+ int pirq, int irq)
+{
+ int reg;
+ u8 x;
+
+ reg = pirq;
+ if (reg >= 1 && reg <= 4)
+ reg += PCI_SIS497_INTA_TO_IRQ_LINK - 1;
+
+ pci_read_config_byte(router, reg, &x);
+ x &= ~(PIRQ_SIS497_IRQ_MASK | PIRQ_SIS497_IRQ_ENABLE);
+ x |= irq ? (PIRQ_SIS497_IRQ_ENABLE | irq) : PIRQ_SIS497_IRQ_MASK;
+ pci_write_config_byte(router, reg, x);
+ return 1;
+}
+
/*
* PIRQ routing for SiS 85C503 router used in several SiS chipsets.
* We have to deal with the following issues here:
@@ -969,6 +1044,11 @@ static __init int serverworks_router_pro
static __init int sis_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
{
switch (device) {
+ case PCI_DEVICE_ID_SI_496:
+ r->name = "SiS85C497";
+ r->get = pirq_sis497_get;
+ r->set = pirq_sis497_set;
+ return 1;
case PCI_DEVICE_ID_SI_503:
r->name = "SiS85C503";
r->get = pirq_sis503_get;
Hello Maciej,
Apparently, my previous replies (of 11-sep-2021 to 16-sep-2021) with
some observations somehow went to spam box or whatever. I was going to
retry but got too busy with unrelated stuff at that time. I can re-send
them if necessary.
Anyway. Yes, your patch is very usefull. I've tested it quite thoroughly
back then, including sharing IRQs for 2 unrelated PCI devices etc. I
have it always automatically applied in my private trees since then.
One peculiarity with my specific board is that I had to also patch ROM
BIOS because it included some non-standard $IRT table instead of $PIR
table. With that in place, it now Just Works.
Thank you again for your effort,
Regards,
Nikolai
03.01.2022 2:24, Maciej W. Rozycki:
> Hi,
>
> Reposting as this has gone nowhere. Regenerated for line changes and
> with Nikolai's Tested-by annotation for 2/2, which now have been verified
> in combination with generic PIRQ router updates posted separately (there's
> no ordering dependency between the two patch series).
>
> Nikolai has observed the trigger mode not being fixed up once it has been
> incorrectly set by the BIOS for PCI devices, causing all kinds of usual
> issues. As it turns out we don't have a PIRQ router defined for the
> SiS85C497 southbridge, which Nikolai's system uses, and which is different
> from the SiS85C503 southbridge we have support for.
>
> As we use the generic `sis' infix (capitalised or not) for the SiS85C503
> southbridge I have prepared this small patch series to first make the
> existing SiS program entities use a more specific `sis503' infix, and then
> provide a suitable PIRQ router for the SiS85C497 device.
>
> See individual change descriptions for further details.
>
> Please apply.
>
> Maciej
>
On Mon, 3 Jan 2022, Nikolai Zhubr wrote:
> One peculiarity with my specific board is that I had to also patch ROM BIOS
> because it included some non-standard $IRT table instead of $PIR table. With
> that in place, it now Just Works.
I have a patch in the queue for $IRT table support too, according to your
and some later findings about it. Just waiting for an ack off-list from
someone, so I'll hopefully post it sometime this week. Sadly I've been
quite loaded with higher-priority stuff recently meaning I can't dedicate
so much time to these patches as I would like to. We'll get there though
sooner or later.
Thanks for your confirmation as to the usability of these changes.
Maciej
On Sun, Jan 02, 2022 at 11:24:59PM +0000, Maciej W. Rozycki wrote:
> Hi,
>
> Reposting as this has gone nowhere. Regenerated for line changes and
> with Nikolai's Tested-by annotation for 2/2, which now have been verified
> in combination with generic PIRQ router updates posted separately (there's
> no ordering dependency between the two patch series).
I assume the x86/IRQ folks will handle this, too.
On Thu, 6 Jan 2022, Bjorn Helgaas wrote:
> On Sun, Jan 02, 2022 at 11:24:59PM +0000, Maciej W. Rozycki wrote:
> >
> > Reposting as this has gone nowhere. Regenerated for line changes and
> > with Nikolai's Tested-by annotation for 2/2, which now have been verified
> > in combination with generic PIRQ router updates posted separately (there's
> > no ordering dependency between the two patch series).
>
> I assume the x86/IRQ folks will handle this, too.
Ping for:
<https://lore.kernel.org/lkml/[email protected]/>.
Series re-verified against 5.17-rc2. Thank you for your input, Bjorn!
Maciej
The following commit has been merged into the x86/irq branch of tip:
Commit-ID: 040a35f1a327d6ffaf7bce58d429339ac96e3712
Gitweb: https://git.kernel.org/tip/040a35f1a327d6ffaf7bce58d429339ac96e3712
Author: Maciej W. Rozycki <[email protected]>
AuthorDate: Sun, 02 Jan 2022 23:25:05
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 02 Feb 2022 21:27:55 +01:00
x86/PCI: Disambiguate SiS85C503 PIRQ router code entities
In preparation to adding support for the SiS85C497 PIRQ router add `503'
to the names of SiS85C503 PIRQ router code entities so that they clearly
indicate which device they refer to.
Also restructure `sis_router_probe' such that new device IDs will be
just new switch cases.
No functional change.
Signed-off-by: Maciej W. Rozycki <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
arch/x86/pci/irq.c | 33 ++++++++++++++++++---------------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 23c69c4..e003541 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -641,11 +641,12 @@ static int pirq_cyrix_set(struct pci_dev *router, struct pci_dev *dev, int pirq,
* bit 6-4 are probably unused, not like 5595
*/
-#define PIRQ_SIS_IRQ_MASK 0x0f
-#define PIRQ_SIS_IRQ_DISABLE 0x80
-#define PIRQ_SIS_USB_ENABLE 0x40
+#define PIRQ_SIS503_IRQ_MASK 0x0f
+#define PIRQ_SIS503_IRQ_DISABLE 0x80
+#define PIRQ_SIS503_USB_ENABLE 0x40
-static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+static int pirq_sis503_get(struct pci_dev *router, struct pci_dev *dev,
+ int pirq)
{
u8 x;
int reg;
@@ -654,10 +655,11 @@ static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
if (reg >= 0x01 && reg <= 0x04)
reg += 0x40;
pci_read_config_byte(router, reg, &x);
- return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK);
+ return (x & PIRQ_SIS503_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS503_IRQ_MASK);
}
-static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+static int pirq_sis503_set(struct pci_dev *router, struct pci_dev *dev,
+ int pirq, int irq)
{
u8 x;
int reg;
@@ -666,8 +668,8 @@ static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i
if (reg >= 0x01 && reg <= 0x04)
reg += 0x40;
pci_read_config_byte(router, reg, &x);
- x &= ~(PIRQ_SIS_IRQ_MASK | PIRQ_SIS_IRQ_DISABLE);
- x |= irq ? irq: PIRQ_SIS_IRQ_DISABLE;
+ x &= ~(PIRQ_SIS503_IRQ_MASK | PIRQ_SIS503_IRQ_DISABLE);
+ x |= irq ? irq : PIRQ_SIS503_IRQ_DISABLE;
pci_write_config_byte(router, reg, x);
return 1;
}
@@ -966,13 +968,14 @@ static __init int serverworks_router_probe(struct irq_router *r,
static __init int sis_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
{
- if (device != PCI_DEVICE_ID_SI_503)
- return 0;
-
- r->name = "SIS";
- r->get = pirq_sis_get;
- r->set = pirq_sis_set;
- return 1;
+ switch (device) {
+ case PCI_DEVICE_ID_SI_503:
+ r->name = "SiS85C503";
+ r->get = pirq_sis503_get;
+ r->set = pirq_sis503_set;
+ return 1;
+ }
+ return 0;
}
static __init int cyrix_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
The following commit has been merged into the x86/irq branch of tip:
Commit-ID: d1f37bac9bebf1b983770ff61e6fd1310db8dc1f
Gitweb: https://git.kernel.org/tip/d1f37bac9bebf1b983770ff61e6fd1310db8dc1f
Author: Maciej W. Rozycki <[email protected]>
AuthorDate: Sun, 02 Jan 2022 23:25:10
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Wed, 02 Feb 2022 21:27:55 +01:00
x86/PCI: Add support for the SiS85C497 PIRQ router
The SiS 85C496/497 486 Green PC VESA/ISA/PCI Chipset has support for PCI
steering and the ELCR register implemented. These features are handled
by the SiS85C497 AT Bus Controller & Megacell (ATM) ISA bridge, however
the device is wired as a peer bridge directly to the host bus and has
its PCI configuration registers decoded at addresses 0x80-0xff by the
accompanying SiS85C496 PCI & CPU Memory Controller (PCM) host bridge[1].
Therefore we need to match on the host bridge's vendor and device ID.
Like with the SiS85C503 PIRQ router handle link value ranges of 1-4 and
0xc0-0xc3, corresponding respectively to PIRQ line numbers counted from
1 and link register PCI configuration space addresses.
References:
[1] "486 Green PC VESA/ISA/PCI Chipset, SiS 85C496/497", Rev 3.0,
Silicon Integrated Systems Corp., July 1995, Part IV, Section 3.
"PCI Configuration Space Registers (00h ~ FFh)", p. 114
Signed-off-by: Maciej W. Rozycki <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Tested-by: Nikolai Zhubr <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
arch/x86/pci/irq.c | 80 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 80 insertions(+)
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index e003541..2abfcfc 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -580,6 +580,81 @@ static int pirq_cyrix_set(struct pci_dev *router, struct pci_dev *dev, int pirq,
return 1;
}
+
+/*
+ * PIRQ routing for the SiS85C497 AT Bus Controller & Megacell (ATM)
+ * ISA bridge used with the SiS 85C496/497 486 Green PC VESA/ISA/PCI
+ * Chipset.
+ *
+ * There are four PCI INTx#-to-IRQ Link registers provided in the
+ * SiS85C497 part of the peculiar combined 85C496/497 configuration
+ * space decoded by the SiS85C496 PCI & CPU Memory Controller (PCM)
+ * host bridge, at 0xc0/0xc1/0xc2/0xc3 respectively for the PCI INT
+ * A/B/C/D lines. Bit 7 enables the respective link if set and bits
+ * 3:0 select the 8259A IRQ line as follows:
+ *
+ * 0000 : Reserved
+ * 0001 : Reserved
+ * 0010 : Reserved
+ * 0011 : IRQ3
+ * 0100 : IRQ4
+ * 0101 : IRQ5
+ * 0110 : IRQ6
+ * 0111 : IRQ7
+ * 1000 : Reserved
+ * 1001 : IRQ9
+ * 1010 : IRQ10
+ * 1011 : IRQ11
+ * 1100 : IRQ12
+ * 1101 : Reserved
+ * 1110 : IRQ14
+ * 1111 : IRQ15
+ *
+ * We avoid using a reserved value for disabled links, hence the
+ * choice of IRQ15 for that case.
+ *
+ * References:
+ *
+ * "486 Green PC VESA/ISA/PCI Chipset, SiS 85C496/497", Rev 3.0,
+ * Silicon Integrated Systems Corp., July 1995
+ */
+
+#define PCI_SIS497_INTA_TO_IRQ_LINK 0xc0u
+
+#define PIRQ_SIS497_IRQ_MASK 0x0fu
+#define PIRQ_SIS497_IRQ_ENABLE 0x80u
+
+static int pirq_sis497_get(struct pci_dev *router, struct pci_dev *dev,
+ int pirq)
+{
+ int reg;
+ u8 x;
+
+ reg = pirq;
+ if (reg >= 1 && reg <= 4)
+ reg += PCI_SIS497_INTA_TO_IRQ_LINK - 1;
+
+ pci_read_config_byte(router, reg, &x);
+ return (x & PIRQ_SIS497_IRQ_ENABLE) ? (x & PIRQ_SIS497_IRQ_MASK) : 0;
+}
+
+static int pirq_sis497_set(struct pci_dev *router, struct pci_dev *dev,
+ int pirq, int irq)
+{
+ int reg;
+ u8 x;
+
+ reg = pirq;
+ if (reg >= 1 && reg <= 4)
+ reg += PCI_SIS497_INTA_TO_IRQ_LINK - 1;
+
+ pci_read_config_byte(router, reg, &x);
+ x &= ~(PIRQ_SIS497_IRQ_MASK | PIRQ_SIS497_IRQ_ENABLE);
+ x |= irq ? (PIRQ_SIS497_IRQ_ENABLE | irq) : PIRQ_SIS497_IRQ_MASK;
+ pci_write_config_byte(router, reg, x);
+ return 1;
+}
+
/*
* PIRQ routing for SiS 85C503 router used in several SiS chipsets.
* We have to deal with the following issues here:
@@ -969,6 +1044,11 @@ static __init int serverworks_router_probe(struct irq_router *r,
static __init int sis_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
{
switch (device) {
+ case PCI_DEVICE_ID_SI_496:
+ r->name = "SiS85C497";
+ r->get = pirq_sis497_get;
+ r->set = pirq_sis497_set;
+ return 1;
case PCI_DEVICE_ID_SI_503:
r->name = "SiS85C503";
r->get = pirq_sis503_get;