From 028480bfb1299a0a34ad19f20e2cc3f24b402235 Mon Sep 17 00:00:00 2001 From: tegge Date: Wed, 1 Apr 1998 21:07:37 +0000 Subject: Add two workarounds for broken MP tables: - Attempt to handle PCI devices where the interrupt is an ISA/EISA interrupt according to the mp table. - Attempt to handle multiple IO APIC pins connected to the same PCI or ISA/EISA interrupt source. Print a warning if this happens, since performance is suboptimal. This workaround is only used for PCI devices. With these two workarounds, the -SMP kernel is capable of running on my Asus P/I-P65UP5 motherboard when version 1.4 of the MP table is disabled. --- sys/i386/include/mptable.h | 51 ++++++++++++++++++++++++++++++++++++++++++++-- sys/i386/include/smp.h | 3 ++- 2 files changed, 51 insertions(+), 3 deletions(-) (limited to 'sys/i386/include') diff --git a/sys/i386/include/mptable.h b/sys/i386/include/mptable.h index aa6adb9..6657ae48 100644 --- a/sys/i386/include/mptable.h +++ b/sys/i386/include/mptable.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.69 1998/03/03 22:56:24 tegge Exp $ + * $Id: mp_machdep.c,v 1.70 1998/03/07 20:16:49 tegge Exp $ */ #include "opt_smp.h" @@ -1199,7 +1199,6 @@ isa_apic_pin(int isa_irq) } return -1; /* NOT found */ } -#undef SRCBUSIRQ /* @@ -1225,9 +1224,57 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt) return -1; /* NOT found */ } + +int +next_apic_pin(int pin) +{ + int intr, ointr; + int bus, bustype; + + bus = 0; + bustype = 0; + for (intr = 0; intr < nintrs; intr++) { + if (INTPIN(intr) != pin || INTTYPE(intr) != 0) + continue; + bus = SRCBUSID(intr); + bustype = apic_bus_type(bus); + if (bustype != ISA && + bustype != EISA && + bustype != PCI) + continue; + break; + } + if (intr >= nintrs) { + return -1; + } + for (ointr = intr + 1; ointr < nintrs; ointr++) { + if (INTTYPE(ointr) != 0) + continue; + if (bus != SRCBUSID(ointr)) + continue; + if (bustype == PCI) { + if (SRCBUSDEVICE(intr) != SRCBUSDEVICE(ointr)) + continue; + if (SRCBUSLINE(intr) != SRCBUSLINE(ointr)) + continue; + } + if (bustype == ISA || bustype == EISA) { + if (SRCBUSIRQ(intr) != SRCBUSIRQ(ointr)) + continue; + } + if (INTPIN(intr) == INTPIN(ointr)) + continue; + break; + } + if (ointr >= nintrs) { + return -1; + } + return INTPIN(ointr); +} #undef SRCBUSLINE #undef SRCBUSDEVICE #undef SRCBUSID +#undef SRCBUSIRQ #undef INTPIN #undef INTTYPE diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h index b31aadd..283c925 100644 --- a/sys/i386/include/smp.h +++ b/sys/i386/include/smp.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: smp.h,v 1.40 1998/03/07 21:34:59 dyson Exp $ + * $Id: smp.h,v 1.41 1998/04/01 20:38:28 tegge Exp $ * */ @@ -112,6 +112,7 @@ void mp_announce __P((void)); u_int isa_apic_mask __P((u_int)); int isa_apic_pin __P((int)); int pci_apic_pin __P((int, int, int)); +int next_apic_pin __P((int)); int undirect_isa_irq __P((int)); int undirect_pci_irq __P((int)); int apic_bus_type __P((int)); -- cgit v1.1