summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authortegge <tegge@FreeBSD.org>1998-04-01 21:07:37 +0000
committertegge <tegge@FreeBSD.org>1998-04-01 21:07:37 +0000
commit028480bfb1299a0a34ad19f20e2cc3f24b402235 (patch)
tree77436497a16e77fa303820d1d60caeb109f2acad /sys/i386
parent574d6dcedfc1e96deb88ef6e7f5540eab053fe2d (diff)
downloadFreeBSD-src-028480bfb1299a0a34ad19f20e2cc3f24b402235.zip
FreeBSD-src-028480bfb1299a0a34ad19f20e2cc3f24b402235.tar.gz
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.
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/mp_machdep.c51
-rw-r--r--sys/i386/i386/mpapic.c25
-rw-r--r--sys/i386/i386/mptable.c51
-rw-r--r--sys/i386/include/mptable.h51
-rw-r--r--sys/i386/include/smp.h3
5 files changed, 157 insertions, 24 deletions
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index aa6adb9..6657ae48 100644
--- a/sys/i386/i386/mp_machdep.c
+++ b/sys/i386/i386/mp_machdep.c
@@ -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/i386/mpapic.c b/sys/i386/i386/mpapic.c
index 24f5072..f2d545b 100644
--- a/sys/i386/i386/mpapic.c
+++ b/sys/i386/i386/mpapic.c
@@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: mpapic.c,v 1.27 1997/12/08 18:36:02 fsmp Exp $
+ * $Id: mpapic.c,v 1.28 1998/03/03 19:54:49 tegge Exp $
*/
#include "opt_smp.h"
@@ -164,7 +164,7 @@ io_apic_setup(int apic)
if (apic == 0) {
maxpin = REDIRCNT_IOAPIC(apic); /* pins in APIC */
for (pin = 0; pin < maxpin; ++pin) {
- int bus, bustype;
+ int bus;
/* we only deal with vectored INTs here */
if (apic_int_type(apic, pin) != 0)
@@ -174,21 +174,12 @@ io_apic_setup(int apic)
bus = apic_src_bus_id(apic, pin);
if (bus == -1)
continue;
- bustype = apic_bus_type(bus);
-
- /* the "ISA" type INTerrupts */
- if ((bustype == ISA) || (bustype == EISA)) {
- flags = DEFAULT_ISA_FLAGS;
- }
-
- /* PCI or other bus */
- else {
- flags = DEFAULT_FLAGS;
- level = trigger(apic, pin, &flags);
- if (level == 1)
- apic_pin_trigger[apic] |= (1 << pin);
- polarity(apic, pin, &flags, level);
- }
+
+ flags = DEFAULT_FLAGS;
+ level = trigger(apic, pin, &flags);
+ if (level == 1)
+ apic_pin_trigger[apic] |= (1 << pin);
+ polarity(apic, pin, &flags, level);
/* program the appropriate registers */
select = pin * 2 + IOAPIC_REDTBL0; /* register */
diff --git a/sys/i386/i386/mptable.c b/sys/i386/i386/mptable.c
index aa6adb9..6657ae48 100644
--- a/sys/i386/i386/mptable.c
+++ b/sys/i386/i386/mptable.c
@@ -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/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));
OpenPOWER on IntegriCloud