diff options
| author | Tor Egge <tegge@FreeBSD.org> | 1998-04-01 21:07:37 +0000 |
|---|---|---|
| committer | Tor Egge <tegge@FreeBSD.org> | 1998-04-01 21:07:37 +0000 |
| commit | 5758c2de94dafd19a144039cb0a2b7f62196fae7 (patch) | |
| tree | df5d22c731fbeff7db5b4ca54307272883f66d32 | |
| parent | 300e9a7696dceecb6d5684aee4b634da021d9bdc (diff) | |
Notes
| -rw-r--r-- | sys/amd64/amd64/mp_machdep.c | 51 | ||||
| -rw-r--r-- | sys/amd64/amd64/mptable.c | 51 | ||||
| -rw-r--r-- | sys/amd64/include/mptable.h | 51 | ||||
| -rw-r--r-- | sys/amd64/include/smp.h | 3 | ||||
| -rw-r--r-- | sys/dev/pci/pci.c | 24 | ||||
| -rw-r--r-- | sys/i386/i386/mp_machdep.c | 51 | ||||
| -rw-r--r-- | sys/i386/i386/mpapic.c | 25 | ||||
| -rw-r--r-- | sys/i386/i386/mptable.c | 51 | ||||
| -rw-r--r-- | sys/i386/include/mptable.h | 51 | ||||
| -rw-r--r-- | sys/i386/include/smp.h | 3 | ||||
| -rw-r--r-- | sys/kern/subr_smp.c | 51 | ||||
| -rw-r--r-- | sys/pci/pci.c | 24 | ||||
| -rw-r--r-- | sys/pci/pci_compat.c | 48 | ||||
| -rw-r--r-- | sys/sys/smp.h | 3 |
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)); |
