summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Egge <tegge@FreeBSD.org>1998-04-01 21:07:37 +0000
committerTor Egge <tegge@FreeBSD.org>1998-04-01 21:07:37 +0000
commit5758c2de94dafd19a144039cb0a2b7f62196fae7 (patch)
treedf5d22c731fbeff7db5b4ca54307272883f66d32
parent300e9a7696dceecb6d5684aee4b634da021d9bdc (diff)
Notes
-rw-r--r--sys/amd64/amd64/mp_machdep.c51
-rw-r--r--sys/amd64/amd64/mptable.c51
-rw-r--r--sys/amd64/include/mptable.h51
-rw-r--r--sys/amd64/include/smp.h3
-rw-r--r--sys/dev/pci/pci.c24
-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
-rw-r--r--sys/kern/subr_smp.c51
-rw-r--r--sys/pci/pci.c24
-rw-r--r--sys/pci/pci_compat.c48
-rw-r--r--sys/sys/smp.h3
14 files changed, 443 insertions, 44 deletions
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
index aa6adb9120d8..6657ae48dac8 100644
--- a/sys/amd64/amd64/mp_machdep.c
+++ b/sys/amd64/amd64/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/amd64/amd64/mptable.c b/sys/amd64/amd64/mptable.c
index aa6adb9120d8..6657ae48dac8 100644
--- a/sys/amd64/amd64/mptable.c
+++ b/sys/amd64/amd64/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/amd64/include/mptable.h b/sys/amd64/include/mptable.h
index aa6adb9120d8..6657ae48dac8 100644
--- a/sys/amd64/include/mptable.h
+++ b/sys/amd64/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/amd64/include/smp.h b/sys/amd64/include/smp.h
index b31aadd9cd0f..283c925f2955 100644
--- a/sys/amd64/include/smp.h
+++ b/sys/amd64/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));
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 6ecd4b78b1fe..530408b87963 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: pci.c,v 1.80 1997/11/07 08:53:28 phk Exp $
+ * $Id: pci.c,v 1.81 1998/01/24 02:54:47 eivind Exp $
*
*/
@@ -340,9 +340,25 @@ pci_readcfg(pcicfgregs *probe)
int airq;
airq = pci_apic_pin(cfg->bus, cfg->slot, cfg->intpin);
- if ((airq >= 0) && (airq != cfg->intline)) {
- undirect_pci_irq(cfg->intline);
- cfg->intline = airq;
+ if (airq >= 0) {
+ /* PCI specific entry found in MP table */
+ if (airq != cfg->intline) {
+ undirect_pci_irq(cfg->intline);
+ cfg->intline = airq;
+ }
+ } else {
+ /*
+ * PCI interrupts might be redirected to the
+ * ISA bus according to some MP tables. Use the
+ * same methods as used by the ISA devices
+ * devices to find the proper IOAPIC int pin.
+ */
+ airq = isa_apic_pin(cfg->intline);
+ if ((airq >= 0) && (airq != cfg->intline)) {
+ /* XXX: undirect_pci_irq() ? */
+ undirect_isa_irq(cfg->intline);
+ cfg->intline = airq;
+ }
}
}
#endif /* APIC_IO */
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index aa6adb9120d8..6657ae48dac8 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 24f5072b4342..f2d545b81024 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 aa6adb9120d8..6657ae48dac8 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 aa6adb9120d8..6657ae48dac8 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 b31aadd9cd0f..283c925f2955 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));
diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c
index aa6adb9120d8..6657ae48dac8 100644
--- a/sys/kern/subr_smp.c
+++ b/sys/kern/subr_smp.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/pci/pci.c b/sys/pci/pci.c
index 6ecd4b78b1fe..530408b87963 100644
--- a/sys/pci/pci.c
+++ b/sys/pci/pci.c
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: pci.c,v 1.80 1997/11/07 08:53:28 phk Exp $
+ * $Id: pci.c,v 1.81 1998/01/24 02:54:47 eivind Exp $
*
*/
@@ -340,9 +340,25 @@ pci_readcfg(pcicfgregs *probe)
int airq;
airq = pci_apic_pin(cfg->bus, cfg->slot, cfg->intpin);
- if ((airq >= 0) && (airq != cfg->intline)) {
- undirect_pci_irq(cfg->intline);
- cfg->intline = airq;
+ if (airq >= 0) {
+ /* PCI specific entry found in MP table */
+ if (airq != cfg->intline) {
+ undirect_pci_irq(cfg->intline);
+ cfg->intline = airq;
+ }
+ } else {
+ /*
+ * PCI interrupts might be redirected to the
+ * ISA bus according to some MP tables. Use the
+ * same methods as used by the ISA devices
+ * devices to find the proper IOAPIC int pin.
+ */
+ airq = isa_apic_pin(cfg->intline);
+ if ((airq >= 0) && (airq != cfg->intline)) {
+ /* XXX: undirect_pci_irq() ? */
+ undirect_isa_irq(cfg->intline);
+ cfg->intline = airq;
+ }
}
}
#endif /* APIC_IO */
diff --git a/sys/pci/pci_compat.c b/sys/pci/pci_compat.c
index 904115661a41..8499fcf0115f 100644
--- a/sys/pci/pci_compat.c
+++ b/sys/pci/pci_compat.c
@@ -23,7 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: pci_compat.c,v 1.5 1997/08/21 07:05:48 fsmp Exp $
+ * $Id: pci_compat.c,v 1.6 1997/08/21 08:42:59 fsmp Exp $
*
*/
@@ -164,13 +164,57 @@ int pci_map_mem(pcici_t cfg, u_long reg, vm_offset_t* va, vm_offset_t* pa)
int
pci_map_int(pcici_t cfg, pci_inthand_t *func, void *arg, unsigned *maskptr)
{
+ int error;
+#ifdef APIC_IO
+ int nextpin, muxcnt;
+#endif
if (cfg->intpin != 0) {
int irq = cfg->intline;
void *dev_instance = (void *)-1; /* XXX use cfg->devdata */
void *idesc;
idesc = intr_create(dev_instance, irq, func, arg, maskptr, 0);
- return (intr_connect(idesc) == 0);
+ error = intr_connect(idesc);
+ if (error != 0)
+ return 0;
+#ifdef APIC_IO
+ nextpin = next_apic_pin(irq);
+
+ if (nextpin < 0)
+ return 1;
+
+ /*
+ * Attempt handling of some broken mp tables.
+ *
+ * It's OK to yell (since the mp tables are broken).
+ *
+ * Hanging in the boot is not OK
+ */
+
+ muxcnt = 2;
+ nextpin = next_apic_pin(nextpin);
+ while (muxcnt < 5 && nextpin >= 0) {
+ muxcnt++;
+ nextpin = next_apic_pin(nextpin);
+ }
+ if (muxcnt >= 5) {
+ printf("bogus MP table, more than 4 IO APIC pins connected to the same PCI device or ISA/EISA interrupt\n");
+ return 0;
+ }
+
+ printf("bogus MP table, %d IO APIC pins connected to the same PCI device or ISA/EISA interrupt\n", muxcnt);
+
+ nextpin = next_apic_pin(irq);
+ while (nextpin >= 0) {
+ idesc = intr_create(dev_instance, nextpin, func, arg,
+ maskptr, 0);
+ error = intr_connect(idesc);
+ if (error != 0)
+ return 0;
+ printf("Registered extra interrupt handler for int %d (in addition to int %d)\n", nextpin, irq);
+ nextpin = next_apic_pin(nextpin);
+ }
+#endif
}
return (1);
}
diff --git a/sys/sys/smp.h b/sys/sys/smp.h
index b31aadd9cd0f..283c925f2955 100644
--- a/sys/sys/smp.h
+++ b/sys/sys/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));