diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2005-11-23 09:24:58 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2005-11-23 09:24:58 +0000 |
commit | b798e30277e3f181d9ea559fa8f352c70f5bbcb9 (patch) | |
tree | a6d8f3334d4f670787880b4709e724a4fc3c0b43 /sys/arch/i386/pci | |
parent | c56c28566cdd540950b965d8db45d6e49cc60434 (diff) |
resolve a couple of problems in mpbios-mapped interrupts:
- synthesise isa mappings (as 1-1) should those be missing in mpbios;
- for rcc osb* firce "special" ints into isa mappings always.
niklas@ ok and testing by many since
Diffstat (limited to 'sys/arch/i386/pci')
-rw-r--r-- | sys/arch/i386/pci/pci_intr_fixup.c | 31 | ||||
-rw-r--r-- | sys/arch/i386/pci/pci_machdep.c | 28 | ||||
-rw-r--r-- | sys/arch/i386/pci/pcibiosvar.h | 4 | ||||
-rw-r--r-- | sys/arch/i386/pci/rccosb4.c | 14 | ||||
-rw-r--r-- | sys/arch/i386/pci/rccosb4reg.h | 3 |
5 files changed, 44 insertions, 36 deletions
diff --git a/sys/arch/i386/pci/pci_intr_fixup.c b/sys/arch/i386/pci/pci_intr_fixup.c index 5a1be5e0c3b..7fd8492e10e 100644 --- a/sys/arch/i386/pci/pci_intr_fixup.c +++ b/sys/arch/i386/pci/pci_intr_fixup.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_intr_fixup.c,v 1.48 2005/11/21 22:28:13 brad Exp $ */ +/* $OpenBSD: pci_intr_fixup.c,v 1.49 2005/11/23 09:24:57 mickey Exp $ */ /* $NetBSD: pci_intr_fixup.c,v 1.10 2000/08/10 21:18:27 soda Exp $ */ /* @@ -101,6 +101,7 @@ #include <machine/bus.h> #include <machine/intr.h> #include <machine/i8259.h> +#include <machine/i82093var.h> #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> @@ -535,15 +536,15 @@ pci_intr_route_link(pc, ihp) { struct pciintr_link_map *l; pcireg_t intr; - int rv = 1; + int irq, rv = 1; char *p = NULL; if (pcibios_flags & PCIBIOS_INTR_FIXUP) return 1; - if (ihp->line != 0 && - ihp->line != I386_PCI_INTERRUPT_LINE_NO_CONNECTION) - pcibios_pir_header.exclusive_irq |= (1 << ihp->line); + irq = ihp->line & APIC_INT_LINE_MASK; + if (irq != 0 && irq != I386_PCI_INTERRUPT_LINE_NO_CONNECTION) + pcibios_pir_header.exclusive_irq |= 1 << irq; l = ihp->link; if (!l || pciintr_icu_tag == NULL) @@ -584,13 +585,13 @@ pci_intr_route_link(pc, ihp) * IRQs 14 and 15 are reserved for PCI IDE interrupts; don't muck * with them. */ - if (ihp->line == 14 || ihp->line == 15) + if (irq == 14 || irq == 15) return (1); intr = pci_conf_read(pc, ihp->tag, PCI_INTERRUPT_REG); - if (ihp->line != PCI_INTERRUPT_LINE(intr)) { + if (irq != PCI_INTERRUPT_LINE(intr)) { intr &= ~(PCI_INTERRUPT_LINE_MASK << PCI_INTERRUPT_LINE_SHIFT); - intr |= (ihp->line << PCI_INTERRUPT_LINE_SHIFT); + intr |= irq << PCI_INTERRUPT_LINE_SHIFT; pci_conf_write(pc, ihp->tag, PCI_INTERRUPT_REG, intr); } @@ -651,7 +652,7 @@ pci_intr_header_fixup(pc, tag, ihp) if (pcibios_flags & PCIBIOS_INTR_FIXUP) return 1; - irq = ihp->line; + irq = ihp->line & APIC_INT_LINE_MASK; ihp->link = NULL; ihp->tag = tag; pci_decompose_tag(pc, tag, &bus, &device, &function); @@ -666,7 +667,7 @@ pci_intr_header_fixup(pc, tag, ihp) /* * No link map entry. * Probably pciintr_icu_getclink() or pciintr_icu_get_intr() - * was failed. + * has failed. */ if (pcibios_flags & PCIBIOS_INTRDEBUG) printf("pci_intr_header_fixup: no entry for link " @@ -682,8 +683,8 @@ pci_intr_header_fixup(pc, tag, ihp) } else if (l->irq == I386_PCI_INTERRUPT_LINE_NO_CONNECTION) { /* Appropriate interrupt was not found. */ - if (pciintr_icu_tag == NULL && ihp->line != 0 && - ihp->line != I386_PCI_INTERRUPT_LINE_NO_CONNECTION) + if (pciintr_icu_tag == NULL && irq != 0 && + irq != I386_PCI_INTERRUPT_LINE_NO_CONNECTION) /* * Do not print warning, * if no compatible PCI ICU found, @@ -695,17 +696,17 @@ pci_intr_header_fixup(pc, tag, ihp) } else if (irq == 0 || irq == I386_PCI_INTERRUPT_LINE_NO_CONNECTION) { p = " fixed up"; - ihp->line = l->irq; + ihp->line = irq = l->irq; } else if (pcibios_flags & PCIBIOS_FIXUP_FORCE) { /* routed by BIOS, but inconsistent */ /* believe PCI IRQ Routing table */ p = " WARNING: overriding"; - ihp->line = l->irq; + ihp->line = irq = l->irq; } else { /* believe PCI Interrupt Configuration Register (default) */ p = " WARNING: preserving"; - ihp->line = l->irq = irq; + ihp->line = (l->irq = irq) | (l->clink & PCI_INT_VIA_ISA); } if (pcibios_flags & PCIBIOS_INTRDEBUG) { diff --git a/sys/arch/i386/pci/pci_machdep.c b/sys/arch/i386/pci/pci_machdep.c index 8e8764428f8..a84bd091173 100644 --- a/sys/arch/i386/pci/pci_machdep.c +++ b/sys/arch/i386/pci/pci_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_machdep.c,v 1.29 2005/07/28 17:22:28 brad Exp $ */ +/* $OpenBSD: pci_machdep.c,v 1.30 2005/11/23 09:24:57 mickey Exp $ */ /* $NetBSD: pci_machdep.c,v 1.28 1997/06/06 23:29:17 thorpej Exp $ */ /*- @@ -107,8 +107,8 @@ extern bios_pciinfo_t *bios_pciinfo; #include "ioapic.h" -#if NIOAPIC > 0 #include <machine/i82093var.h> +#if NIOAPIC > 0 #include <machine/mpbiosvar.h> #endif @@ -510,7 +510,7 @@ pci_intr_map(pa, ihp) ihp->pin = pin; #if NPCIBIOS > 0 pci_intr_header_fixup(pc, intrtag, ihp); - line = ihp->line; + line = ihp->line & APIC_INT_LINE_MASK; #endif /* @@ -543,7 +543,7 @@ pci_intr_map(pa, ihp) #if NIOAPIC > 0 pci_decompose_tag (pc, intrtag, &bus, &dev, &func); - if (mp_busses != NULL) { + if (!(ihp->line & PCI_INT_VIA_ISA) && mp_busses != NULL) { /* * Assumes 1:1 mapping between PCI bus numbers and * the numbers given by the MP bios. @@ -597,20 +597,20 @@ pci_intr_string(pc, ih) pci_intr_handle_t ih; { static char irqstr[64]; + int line = ih.line & APIC_INT_LINE_MASK; - if (ih.line == 0 || (ih.line & 0xff) >= ICU_LEN || ih.line == 2) - panic("pci_intr_string: bogus handle 0x%x", ih.line); + if (line == 0 || line >= ICU_LEN || line == 2) + panic("pci_intr_string: bogus handle 0x%x", line); #if NIOAPIC > 0 if (ih.line & APIC_INT_VIA_APIC) { snprintf(irqstr, sizeof irqstr, "apic %d int %d (irq %d)", - APIC_IRQ_APIC(ih.line), APIC_IRQ_PIN(ih.line), - ih.line & 0xff); + APIC_IRQ_APIC(ih.line), APIC_IRQ_PIN(ih.line), line); return (irqstr); } #endif - snprintf(irqstr, sizeof irqstr, "irq %d", ih.line); + snprintf(irqstr, sizeof irqstr, "irq %d", line); return (irqstr); } @@ -623,17 +623,17 @@ pci_intr_establish(pc, ih, level, func, arg, what) char *what; { void *ret; + int l = ih.line & APIC_INT_LINE_MASK; #if NIOAPIC > 0 - if (ih.line != -1 && ih.line & APIC_INT_VIA_APIC) + if (l != -1 && ih.line & APIC_INT_VIA_APIC) return (apic_intr_establish(ih.line, IST_LEVEL, level, func, arg, what)); #endif - if (ih.line == 0 || ih.line >= ICU_LEN || ih.line == 2) - panic("pci_intr_establish: bogus handle 0x%x", ih.line); + if (l == 0 || l >= ICU_LEN || l == 2) + panic("pci_intr_establish: bogus handle 0x%x", l); - ret = isa_intr_establish(NULL, ih.line, IST_LEVEL, level, func, arg, - what); + ret = isa_intr_establish(NULL, l, IST_LEVEL, level, func, arg, what); #if NPCIBIOS > 0 if (ret) pci_intr_route_link(pc, &ih); diff --git a/sys/arch/i386/pci/pcibiosvar.h b/sys/arch/i386/pci/pcibiosvar.h index 41ec746be6b..e0ec0d7bfee 100644 --- a/sys/arch/i386/pci/pcibiosvar.h +++ b/sys/arch/i386/pci/pcibiosvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pcibiosvar.h,v 1.14 2004/09/26 20:17:42 mickey Exp $ */ +/* $OpenBSD: pcibiosvar.h,v 1.15 2005/11/23 09:24:57 mickey Exp $ */ /* $NetBSD: pcibios.h,v 1.2 2000/04/28 17:15:16 uch Exp $ */ /* @@ -146,6 +146,8 @@ typedef const struct pciintr_icu *pciintr_icu_tag_t; #define PCIADDR_SEARCH_MEM 1 struct extent *pciaddr_search(int, bus_addr_t *, bus_size_t); +#define PCI_INT_VIA_ISA 0x20000000 /* XXX see APIC_INT_VIA_APIC */ + int pci_intr_fixup(struct pcibios_softc *, pci_chipset_tag_t, bus_space_tag_t); int pci_bus_fixup(pci_chipset_tag_t, int); void pci_addr_fixup(struct pcibios_softc *, pci_chipset_tag_t, int); diff --git a/sys/arch/i386/pci/rccosb4.c b/sys/arch/i386/pci/rccosb4.c index fcef7bbcc6b..160b4772a2a 100644 --- a/sys/arch/i386/pci/rccosb4.c +++ b/sys/arch/i386/pci/rccosb4.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rccosb4.c,v 1.3 2005/11/10 15:14:09 mickey Exp $ */ +/* $OpenBSD: rccosb4.c,v 1.4 2005/11/23 09:24:57 mickey Exp $ */ /* * Copyright (c) 2004,2005 Michael Shalayeff @@ -98,6 +98,8 @@ osb4_getclink(pciintr_icu_handle_t v, int link, int *clinkp) { if (OSB4_LEGAL_LINK(link - 1)) { *clinkp = link; + if (link <= OSB4_PISP) + *clinkp |= PCI_INT_VIA_ISA; return (0); } @@ -108,11 +110,12 @@ int osb4_get_intr(pciintr_icu_handle_t v, int clink, int *irqp) { struct osb4_handle *ph = v; + int link = clink & 0xff; - if (!OSB4_LEGAL_LINK(clink)) + if (!OSB4_LEGAL_LINK(link)) return (1); - bus_space_write_1(ph->osb4_iot, ph->osb4_ioh, 0, clink); + bus_space_write_1(ph->osb4_iot, ph->osb4_ioh, 0, link); *irqp = bus_space_read_1(ph->osb4_iot, ph->osb4_ioh, 1) & 0xf; if (*irqp == 0) *irqp = I386_PCI_INTERRUPT_LINE_NO_CONNECTION; @@ -124,11 +127,12 @@ int osb4_set_intr(pciintr_icu_handle_t v, int clink, int irq) { struct osb4_handle *ph = v; + int link = clink & 0xff; - if (!OSB4_LEGAL_LINK(clink) || !OSB4_LEGAL_IRQ(irq & 0xf)) + if (!OSB4_LEGAL_LINK(link) || !OSB4_LEGAL_IRQ(irq & 0xf)) return (1); - bus_space_write_1(ph->osb4_iot, ph->osb4_ioh, 0, clink); + bus_space_write_1(ph->osb4_iot, ph->osb4_ioh, 0, link); bus_space_write_1(ph->osb4_iot, ph->osb4_ioh, 1, irq & 0xf); return (0); diff --git a/sys/arch/i386/pci/rccosb4reg.h b/sys/arch/i386/pci/rccosb4reg.h index bc38b9653d6..69a9407e156 100644 --- a/sys/arch/i386/pci/rccosb4reg.h +++ b/sys/arch/i386/pci/rccosb4reg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rccosb4reg.h,v 1.2 2005/10/27 20:01:13 mickey Exp $ */ +/* $OpenBSD: rccosb4reg.h,v 1.3 2005/11/23 09:24:57 mickey Exp $ */ /* * Copyright (c) 2004,2005 Michael Shalayeff @@ -41,6 +41,7 @@ */ #define OSB4_PIAIR 0xc00 #define OSB4_PIRR 0xc01 +#define OSB4_PISP 3 /* special lines assumed to route thru ISA */ /* * ELCR - EDGE/LEVEL CONTROL REGISTER |