summaryrefslogtreecommitdiff
path: root/sys/arch/i386/pci
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2000-09-07 20:50:40 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2000-09-07 20:50:40 +0000
commit29bb9cba423fdfd54211fd5d414aa4982374c69d (patch)
treeef99ada0ee0753d0ae19ffa4c99be068881d1475 /sys/arch/i386/pci
parent59b7026f487e7e6d642c8e08839c62d653f4a798 (diff)
do not call pcibios_pir_init() if intr_fixup was disabled; also, sync w/ latetest netbsd developments
Diffstat (limited to 'sys/arch/i386/pci')
-rw-r--r--sys/arch/i386/pci/pci_addr_fixup.c43
-rw-r--r--sys/arch/i386/pci/pci_intr_fixup.c136
-rw-r--r--sys/arch/i386/pci/pcibios.c154
-rw-r--r--sys/arch/i386/pci/pcibios.h3
4 files changed, 208 insertions, 128 deletions
diff --git a/sys/arch/i386/pci/pci_addr_fixup.c b/sys/arch/i386/pci/pci_addr_fixup.c
index f0b4ca476d3..1e9dc657beb 100644
--- a/sys/arch/i386/pci/pci_addr_fixup.c
+++ b/sys/arch/i386/pci/pci_addr_fixup.c
@@ -1,4 +1,5 @@
-/* $NetBSD: pci_addr_fixup.c,v 1.3 2000/05/31 16:38:55 uch Exp $ */
+/* $OpenBSD: pci_addr_fixup.c,v 1.2 2000/09/07 20:50:38 mickey Exp $ */
+/* $NetBSD: pci_addr_fixup.c,v 1.7 2000/08/03 20:10:45 nathanw Exp $ */
/*-
* Copyright (c) 2000 UCHIYAMA Yasushi. All rights reserved.
@@ -70,9 +71,9 @@ void pciaddr_print_devid __P((pci_chipset_tag_t, pcitag_t));
#define PCIADDR_ISAMEM_RESERVE (16 * 1024 * 1024)
void
-pci_addr_fixup(pc, bus)
+pci_addr_fixup(pc, maxbus)
pci_chipset_tag_t pc;
- int bus;
+ int maxbus;
{
extern paddr_t avail_end;
#ifdef PCIBIOSVERBOSE
@@ -96,7 +97,7 @@ pci_addr_fixup(pc, bus)
}, *srp;
paddr_t start;
int error;
-
+
pciaddr.extent_mem = extent_create("PCI I/O memory space",
PCIADDR_MEM_START,
PCIADDR_MEM_END,
@@ -112,7 +113,7 @@ pci_addr_fixup(pc, bus)
* 1. check & reserve system BIOS setting.
*/
PCIBIOS_PRINTV((verbose_header, "System BIOS Setting"));
- pci_device_foreach(pc, bus, pciaddr_resource_reserve);
+ pci_device_foreach(pc, maxbus, pciaddr_resource_reserve);
PCIBIOS_PRINTV((verbose_footer, pciaddr.nbogus));
/*
@@ -148,7 +149,8 @@ pci_addr_fixup(pc, bus)
*/
PCIBIOS_PRINTV((verbose_header, "PCIBIOS fixup stage"));
pciaddr.nbogus = 0;
- pci_device_foreach(pc, bus, pciaddr_resource_allocate);
+ /* XXX bus #0 only */
+ pci_device_foreach(pc, 0, pciaddr_resource_allocate);
PCIBIOS_PRINTV((verbose_footer, pciaddr.nbogus));
}
@@ -187,7 +189,7 @@ pciaddr_resource_manage(pc, tag, func)
pcireg_t val, mask;
bus_addr_t addr;
bus_size_t size;
- int error, useport, usemem, mapreg, type, reg_start, reg_end;
+ int error, useport, usemem, mapreg, type, reg_start, reg_end, width;
val = pci_conf_read(pc, tag, PCI_BHLC_REG);
switch (PCI_HDRTYPE_TYPE(val)) {
@@ -210,7 +212,7 @@ pciaddr_resource_manage(pc, tag, func)
}
error = useport = usemem = 0;
- for (mapreg = reg_start; mapreg < reg_end; mapreg += 4) {
+ for (mapreg = reg_start; mapreg < reg_end; mapreg += width) {
/* inquire PCI device bus space requirement */
val = pci_conf_read(pc, tag, mapreg);
pci_conf_write(pc, tag, mapreg, ~0);
@@ -219,7 +221,21 @@ pciaddr_resource_manage(pc, tag, func)
pci_conf_write(pc, tag, mapreg, val);
type = PCI_MAPREG_TYPE(val);
+ width = 4;
if (type == PCI_MAPREG_TYPE_MEM) {
+ if (PCI_MAPREG_MEM_TYPE(val) ==
+ PCI_MAPREG_MEM_TYPE_64BIT) {
+ /* XXX We could examine the upper 32 bits
+ * XXX of the BAR here, but we are totally
+ * XXX unprepared to handle a non-zero value,
+ * XXX either here or anywhere else in
+ * XXX i386-land.
+ * XXX So just arrange to not look at the
+ * XXX upper 32 bits, lest we misinterpret
+ * XXX it as a 32-bit BAR set to zero.
+ */
+ width = 8;
+ }
size = PCI_MAPREG_MEM_SIZE(mask);
ex = pciaddr.extent_mem;
} else {
@@ -293,17 +309,22 @@ pciaddr_do_resource_allocate(pc, tag, mapreg, ex, type, addr, size)
pci_conf_write(pc, tag, mapreg, *addr);
/* check */
#ifdef PCIBIOSVERBOSE
- if (!pcibiosverbose) {
+ if (!pcibiosverbose)
+#endif
+ {
printf("pci_addr_fixup: ");
pciaddr_print_devid(pc, tag);
}
-#endif
+
if (pciaddr_ioaddr(pci_conf_read(pc, tag, mapreg)) != *addr) {
pci_conf_write(pc, tag, mapreg, 0); /* clear */
printf("fixup failed. (new address=%#x)\n", (unsigned)*addr);
return (1);
}
- PCIBIOS_PRINTV(("new address 0x%08x\n", (unsigned)*addr));
+#ifdef PCIBIOSVERBOSE
+ if (!pcibiosverbose)
+#endif
+ printf("new address 0x%08x\n", *addr);
return (0);
}
diff --git a/sys/arch/i386/pci/pci_intr_fixup.c b/sys/arch/i386/pci/pci_intr_fixup.c
index 9fb60cef950..207e33d16a3 100644
--- a/sys/arch/i386/pci/pci_intr_fixup.c
+++ b/sys/arch/i386/pci/pci_intr_fixup.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: pci_intr_fixup.c,v 1.5 2000/08/08 19:12:48 mickey Exp $ */
-/* $NetBSD: pci_intr_fixup.c,v 1.9 2000/07/22 17:43:36 soda Exp $ */
+/* $OpenBSD: pci_intr_fixup.c,v 1.6 2000/09/07 20:50:38 mickey Exp $ */
+/* $NetBSD: pci_intr_fixup.c,v 1.10 2000/08/10 21:18:27 soda Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -94,7 +94,7 @@ struct pciintr_link_map {
SIMPLEQ_ENTRY(pciintr_link_map) list;
};
-pciintr_icu_tag_t pciintr_icu_tag;
+pciintr_icu_tag_t pciintr_icu_tag = NULL;
pciintr_icu_handle_t pciintr_icu_handle;
#ifdef PCIBIOS_IRQS_HINT
@@ -108,6 +108,7 @@ struct pcibios_intr_routing *pciintr_pir_lookup __P((int, int));
static int pciintr_bitmap_count_irq __P((int, int *));
static int pciintr_bitmap_find_lowest_irq __P((int, int *));
int pciintr_link_init __P((void));
+int pciintr_guess_irq __P((void));
int pciintr_link_fixup __P((void));
int pciintr_link_route __P((u_int16_t *));
int pciintr_irq_release __P((u_int16_t *));
@@ -191,39 +192,43 @@ pciintr_link_alloc(pir, pin)
int link = pir->linkmap[pin].link, clink, irq;
struct pciintr_link_map *l, *lstart;
- /*
- * Get the canonical link value for this entry.
- */
- if (pciintr_icu_getclink(pciintr_icu_tag, pciintr_icu_handle, link,
- &clink) != 0) {
+ if (pciintr_icu_tag != NULL) {
/*
- * ICU doesn't understand the link value.
- * Just ignore this PIR entry.
+ * Get the canonical link value for this entry.
*/
+ if (pciintr_icu_getclink(pciintr_icu_tag, pciintr_icu_handle,
+ link, &clink) != 0) {
+ /*
+ * ICU doesn't understand the link value.
+ * Just ignore this PIR entry.
+ */
#ifdef PCIBIOSVERBOSE
- printf("pciintr_link_alloc: bus %d device %d: "
- "ignoring link 0x%02x\n",
- pir->bus, PIR_DEVFUNC_DEVICE(pir->device), link);
+ printf("pciintr_link_alloc: bus %d device %d: "
+ "ignoring link 0x%02x\n",
+ pir->bus, PIR_DEVFUNC_DEVICE(pir->device), link);
#endif
- return (NULL);
- }
+ return (NULL);
+ }
- /*
- * Check the link value by asking the ICU for the canonical link value.
- * Also, determine if this PIRQ is mapped to an IRQ.
- */
- if (pciintr_icu_get_intr(pciintr_icu_tag, pciintr_icu_handle, clink,
- &irq) != 0) {
/*
- * ICU doesn't understand the canonical link value.
- * Just ignore this PIR entry.
+ * Check the link value by asking the ICU for the
+ * canonical link value.
+ * Also, determine if this PIRQ is mapped to an IRQ.
*/
+ if (pciintr_icu_get_intr(pciintr_icu_tag, pciintr_icu_handle,
+ clink, &irq) != 0) {
+ /*
+ * ICU doesn't understand the canonical link value.
+ * Just ignore this PIR entry.
+ */
#ifdef PCIBIOSVERBOSE
- printf("pciintr_link_alloc: bus %d device %d link 0x%02x: "
- "ignoring PIRQ 0x%02x\n",
- pir->bus, PIR_DEVFUNC_DEVICE(pir->device), link, clink);
+ printf("pciintr_link_alloc: "
+ "bus %d device %d link 0x%02x: "
+ "ignoring PIRQ 0x%02x\n", pir->bus,
+ PIR_DEVFUNC_DEVICE(pir->device), link, clink);
#endif
- return (NULL);
+ return (NULL);
+ }
}
l = malloc(sizeof(*l), M_DEVBUF, M_NOWAIT);
@@ -234,8 +239,13 @@ pciintr_link_alloc(pir, pin)
l->link = link;
l->bitmap = pir->linkmap[pin].bitmap;
- l->clink = clink;
- l->irq = irq; /* may be I386_PCI_INTERRUPT_LINE_NO_CONNECTION */
+ if (pciintr_icu_tag != NULL) { /* compatible PCI ICU found */
+ l->clink = clink;
+ l->irq = irq; /* maybe I386_PCI_INTERRUPT_LINE_NO_CONNECTION */
+ } else {
+ l->clink = link; /* only for PCIBIOSVERBOSE diagnostic */
+ l->irq = I386_PCI_INTERRUPT_LINE_NO_CONNECTION;
+ }
lstart = SIMPLEQ_FIRST(&pciintr_link_map_list);
if (lstart == NULL || lstart->link < l->link)
@@ -304,7 +314,7 @@ pciintr_bitmap_find_lowest_irq(irq_bitmap, irqp)
int
pciintr_link_init()
{
- int entry, pin, error, link;
+ int entry, pin, link;
struct pcibios_intr_routing *pir;
struct pciintr_link_map *l;
@@ -314,7 +324,6 @@ pciintr_link_init()
return (1);
}
- error = 0;
SIMPLEQ_INIT(&pciintr_link_map_list);
for (entry = 0; entry < pcibios_pir_table_nentries; entry++) {
@@ -353,7 +362,39 @@ pciintr_link_init()
}
}
- return (error);
+ return (0);
+}
+
+/*
+ * No compatible PCI ICU found.
+ * Hopes the BIOS already setup the ICU.
+ */
+int
+pciintr_guess_irq()
+{
+ struct pciintr_link_map *l;
+ int irq, guessed = 0;
+
+ /*
+ * Stage 1: If only one IRQ is available for the link, use it.
+ */
+ for (l = SIMPLEQ_FIRST(&pciintr_link_map_list); l != NULL;
+ l = SIMPLEQ_NEXT(l, list)) {
+ if (l->irq != I386_PCI_INTERRUPT_LINE_NO_CONNECTION)
+ continue;
+ if (pciintr_bitmap_count_irq(l->bitmap, &irq) == 1) {
+ l->irq = irq;
+ l->fixup_stage = 1;
+#ifdef PCIINTR_DEBUG
+ printf("pciintr_guess_irq (stage 1): "
+ "guessing PIRQ 0x%02x to be IRQ %d\n",
+ l->clink, l->irq);
+#endif
+ guessed = 1;
+ }
+ }
+
+ return (guessed ? 0 : -1);
}
int
@@ -611,7 +652,17 @@ pciintr_do_header_fixup(pc, tag)
if (l->irq == I386_PCI_INTERRUPT_LINE_NO_CONNECTION) {
/* Appropriate interrupt was not found. */
- PCIBIOS_PRINTV((" WARNING: missing IRQ\n"));
+ if (pciintr_icu_tag == NULL &&
+ irq != 0 && irq != I386_PCI_INTERRUPT_LINE_NO_CONNECTION) {
+ /*
+ * Do not print warning,
+ * if no compatible PCI ICU found,
+ * but the irq is already assigned by BIOS.
+ */
+ PCIBIOS_PRINTV(("\n"));
+ } else {
+ PCIBIOS_PRINTV((" WARNING: missing IRQ\n"));
+ }
return;
}
@@ -629,7 +680,7 @@ pciintr_do_header_fixup(pc, tag)
/* believe PCI IRQ Routing table */
PCIBIOS_PRINTV((" WARNING: overriding irq %d\n", irq));
#else
- /* believe PCI Interrupt Configuration Register (default) */
+ /* believe PCI Interrupt Configuration Register (default) */
PCIBIOS_PRINTV((" WARNING: preserving irq %d\n", irq));
return;
#endif
@@ -697,8 +748,21 @@ pci_intr_fixup(pc, iot, pciirq)
}
if (piit == NULL) {
- printf("pci_intr_fixup: no compatible PCI ICU found\n");
- return (-1); /* non-fatal */
+ printf("pci_intr_fixup: no compatible PCI ICU found");
+ if (pcibios_pir_header.signature != 0 && icuid != 0)
+ printf(": ICU vendor 0x%04x product 0x%04x",
+ PCI_VENDOR(icuid), PCI_PRODUCT(icuid));
+ printf("\n");
+ if (!(pcibios_flags & PCIBIOS_INTR_GUESS)) {
+ if (pciintr_link_init())
+ return (-1); /* non-fatal */
+ if (pciintr_guess_irq())
+ return (-1); /* non-fatal */
+ if (pciintr_header_fixup(pc))
+ return (1); /* fatal */
+ return (0); /* success! */
+ } else
+ return (-1); /* non-fatal */
}
/*
diff --git a/sys/arch/i386/pci/pcibios.c b/sys/arch/i386/pci/pcibios.c
index f2a21d095ac..d5df6c265f5 100644
--- a/sys/arch/i386/pci/pcibios.c
+++ b/sys/arch/i386/pci/pcibios.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcibios.c,v 1.11 2000/09/05 21:44:14 mickey Exp $ */
+/* $OpenBSD: pcibios.c,v 1.12 2000/09/07 20:50:39 mickey Exp $ */
/* $NetBSD: pcibios.c,v 1.5 2000/08/01 05:23:59 uch Exp $ */
/*
@@ -133,7 +133,7 @@ struct pcibios_softc {
struct device sc_dev;
};
-void pcibios_pir_init __P((struct pcibios_softc *));
+struct pcibios_intr_routing *pcibios_pir_init __P((struct pcibios_softc *));
int pcibios_get_status __P((struct pcibios_softc *,
u_int32_t *, u_int32_t *, u_int32_t *,
@@ -216,10 +216,9 @@ pcibiosattach(parent, self, aux)
/*
* Find the PCI IRQ Routing table.
*/
- pcibios_pir_init((struct pcibios_softc *)self);
if (!(pcibios_flags & PCIBIOS_INTR_FIXUP) &&
- pcibios_pir_table != NULL) {
+ pcibios_pir_init((struct pcibios_softc *)self) != NULL) {
int rv;
u_int16_t pciirq;
@@ -256,35 +255,31 @@ pcibiosattach(parent, self, aux)
pci_addr_fixup(NULL, pcibios_max_bus);
}
-void
+struct pcibios_intr_routing *
pcibios_pir_init(sc)
struct pcibios_softc *sc;
{
- char devinfo[256];
paddr_t pa;
- caddr_t p;
- unsigned char cksum;
- u_int16_t tablesize;
- u_int8_t rev_maj, rev_min;
- int i;
+ pcibios_pir_table = NULL;
for (pa = PCI_IRQ_TABLE_START; pa < PCI_IRQ_TABLE_END; pa += 16) {
- p = (caddr_t)ISA_HOLE_VADDR(pa);
- if (*(int *)p != BIOS32_MAKESIG('$', 'P', 'I', 'R'))
+ char devinfo[256];
+ u_int8_t *p, cksum;
+ struct pcibios_pir_header *pirh;
+ int i;
+
+ pirh = (struct pcibios_pir_header *)p = ISA_HOLE_VADDR(pa);
+ if (pirh->signature != BIOS32_MAKESIG('$', 'P', 'I', 'R'))
continue;
- rev_min = *(p + 4);
- rev_maj = *(p + 5);
- tablesize = *(u_int16_t *)(p + 6);
-
cksum = 0;
- for (i = 0; i < tablesize; i++)
- cksum += *(unsigned char *)(p + i);
+ for (i = 0; i < pirh->tablesize; i++)
+ cksum += p[i];
printf("%s: PCI IRQ Routing Table rev. %d.%d found at 0x%lx, "
- "size %d bytes (%d entries)\n",
- sc->sc_dev.dv_xname, rev_maj, rev_min, pa,
- tablesize, (tablesize - 32) / 16);
+ "size %d bytes (%d entries)\n", sc->sc_dev.dv_xname,
+ pirh->version >> 8, pirh->version & 0xff, pa,
+ pirh->tablesize, (pirh->tablesize - 32) / 16);
if (cksum != 0) {
printf("%s: bad IRQ table checksum\n",
@@ -292,13 +287,12 @@ pcibios_pir_init(sc)
continue;
}
- if (tablesize < 32 || (tablesize % 16) != 0) {
- printf("%s: bad IRQ table size\n",
- sc->sc_dev.dv_xname);
+ if (pirh->tablesize < 32 || (pirh->tablesize % 16) != 0) {
+ printf("%s: bad IRQ table size\n", sc->sc_dev.dv_xname);
continue;
}
- if (rev_maj != 1 || rev_min != 0) {
+ if (pirh->version != 0x0100) {
printf("%s: unsupported IRQ table version\n",
sc->sc_dev.dv_xname);
continue;
@@ -307,32 +301,25 @@ pcibios_pir_init(sc)
/*
* We can handle this table! Make a copy of it.
*/
- bcopy(p, &pcibios_pir_header, 32);
- pcibios_pir_table = malloc(tablesize - 32, M_DEVBUF,
- M_NOWAIT);
+ pcibios_pir_header = *pirh;
+ pcibios_pir_table =
+ malloc(pirh->tablesize - 32, M_DEVBUF, M_NOWAIT);
if (pcibios_pir_table == NULL) {
- printf("%s: no memory for $PIR\n",
- sc->sc_dev.dv_xname);
- return;
+ printf("%s: no memory for $PIR\n", sc->sc_dev.dv_xname);
+ return NULL;
}
- bcopy(p + 32, pcibios_pir_table, tablesize - 32);
- pcibios_pir_table_nentries = (tablesize - 32) / 16;
+ bcopy(p + 32, pcibios_pir_table, pirh->tablesize - 32);
+ pcibios_pir_table_nentries = (pirh->tablesize - 32) / 16;
printf("%s: PCI Interrupt Router at %03d:%02d:%01d",
- sc->sc_dev.dv_xname, pcibios_pir_header.router_bus,
- PIR_DEVFUNC_DEVICE(pcibios_pir_header.router_devfunc),
- PIR_DEVFUNC_FUNCTION(pcibios_pir_header.router_devfunc));
- if (pcibios_pir_header.compat_router != 0) {
- pci_devinfo(pcibios_pir_header.compat_router, 0, 0,
- devinfo);
+ sc->sc_dev.dv_xname, pirh->router_bus,
+ PIR_DEVFUNC_DEVICE(pirh->router_devfunc),
+ PIR_DEVFUNC_FUNCTION(pirh->router_devfunc));
+ if (pirh->compat_router != 0) {
+ pci_devinfo(pirh->compat_router, 0, 0, devinfo);
printf(" (%s)", devinfo);
}
printf("\n");
- pcibios_print_exclirq(sc);
-#ifdef PCIINTR_DEBUG
- pcibios_print_pir_table();
-#endif
- return;
}
/*
@@ -342,30 +329,34 @@ pcibios_pir_init(sc)
* XXX The interface to this call sucks; just allocate enough
* XXX room for 32 entries.
*/
- pcibios_pir_table_nentries = 32;
- pcibios_pir_table = malloc(pcibios_pir_table_nentries *
- sizeof(*pcibios_pir_table), M_DEVBUF, M_NOWAIT);
if (pcibios_pir_table == NULL) {
- printf("%s: no memory for $PIR\n",
- sc->sc_dev.dv_xname);
- return;
- }
- if (pcibios_get_intr_routing(sc, pcibios_pir_table,
- &pcibios_pir_table_nentries,
- &pcibios_pir_header.exclusive_irq) != PCIBIOS_SUCCESS) {
- printf("%s: No PCI IRQ Routing information available.\n",
- sc->sc_dev.dv_xname);
- free(pcibios_pir_table, M_DEVBUF);
- pcibios_pir_table = NULL;
- pcibios_pir_table_nentries = 0;
- return;
+
+ pcibios_pir_table_nentries = 32;
+ pcibios_pir_table = malloc(pcibios_pir_table_nentries *
+ sizeof(*pcibios_pir_table), M_DEVBUF, M_NOWAIT);
+ if (pcibios_pir_table == NULL) {
+ printf("%s: no memory for $PIR\n", sc->sc_dev.dv_xname);
+ return NULL;
+ }
+ if (pcibios_get_intr_routing(sc, pcibios_pir_table,
+ &pcibios_pir_table_nentries,
+ &pcibios_pir_header.exclusive_irq) != PCIBIOS_SUCCESS) {
+ printf("%s: PCI IRQ Routing information unavailable.\n",
+ sc->sc_dev.dv_xname);
+ free(pcibios_pir_table, M_DEVBUF);
+ pcibios_pir_table = NULL;
+ pcibios_pir_table_nentries = 0;
+ return NULL;
+ }
+ printf("%s: PCI BIOS has %d Interrupt Routing table entries\n",
+ sc->sc_dev.dv_xname, pcibios_pir_table_nentries);
}
- printf("%s: PCI BIOS has %d Interrupt Routing table entries\n",
- sc->sc_dev.dv_xname, pcibios_pir_table_nentries);
+
pcibios_print_exclirq(sc);
#ifdef PCIINTR_DEBUG
pcibios_print_pir_table();
#endif
+ return pcibios_pir_table;
}
int
@@ -374,16 +365,16 @@ pcibios_get_status(sc, rev_maj, rev_min, mech1, mech2, scmech1, scmech2, maxbus)
u_int32_t *rev_maj, *rev_min, *mech1, *mech2, *scmech1, *scmech2,
*maxbus;
{
- u_int16_t ax, bx, cx;
- u_int32_t edx;
+ u_int32_t ax, bx, cx, edx;
int rv;
- __asm __volatile("lcall (%%edi) ; \
- jc 1f ; \
- xor %%ah, %%ah ; \
- 1:"
+ __asm __volatile("lcall (%%edi)\n\t"
+ "jc 1f\n\t"
+ "xor %%ah, %%ah\n"
+ "1:"
: "=a" (ax), "=b" (bx), "=c" (cx), "=d" (edx)
- : "0" (0xb101), "D" (&pcibios_entry));
+ : "0" (0xb101), "D" (&pcibios_entry)
+ : "cc", "memory");
rv = pcibios_return_code(sc, ax, "pcibios_get_status");
if (rv != PCIBIOS_SUCCESS)
@@ -413,28 +404,31 @@ pcibios_get_intr_routing(sc, table, nentries, exclirq)
int *nentries;
u_int16_t *exclirq;
{
- u_int16_t ax, bx;
+ u_int32_t ax, bx;
int rv;
struct {
u_int16_t size;
- caddr_t offset;
+ u_int32_t offset;
u_int16_t segment;
} __attribute__((__packed__)) args;
args.size = *nentries * sizeof(*table);
- args.offset = (caddr_t)table;
+ args.offset = (u_int32_t)table;
args.segment = GSEL(GDATA_SEL, SEL_KPL);
memset(table, 0, args.size);
- __asm __volatile("lcall (%%esi) ; \
- jc 1f ; \
- xor %%ah, %%ah ; \
- 1: movw %w2, %%ds ; \
- movw %w2, %%es"
+ __asm __volatile("pushl %%ds\n\t"
+ "pushl %%es\n\t"
+ "lcall (%%esi)\n\t"
+ "jc 1f\n\t"
+ "xor %%ah, %%ah\n"
+ "1:\n\t"
+ "popl %%es\n\t"
+ "popl %%ds"
: "=a" (ax), "=b" (bx)
- : "r" GSEL(GDATA_SEL, SEL_KPL), "0" (0xb10e), "1" (0),
- "D" (&args), "S" (&pcibios_entry));
+ : "0" (0xb10e), "1" (0), "D" (&args), "S" (&pcibios_entry)
+ : "cc", "memory");
rv = pcibios_return_code(sc, ax, "pcibios_get_intr_routing");
if (rv != PCIBIOS_SUCCESS)
diff --git a/sys/arch/i386/pci/pcibios.h b/sys/arch/i386/pci/pcibios.h
index e8a94841463..5a67d895323 100644
--- a/sys/arch/i386/pci/pcibios.h
+++ b/sys/arch/i386/pci/pcibios.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcibios.h,v 1.6 2000/09/04 16:58:41 mickey Exp $ */
+/* $OpenBSD: pcibios.h,v 1.7 2000/09/07 20:50:39 mickey Exp $ */
/* $NetBSD: pcibios.h,v 1.2 2000/04/28 17:15:16 uch Exp $ */
/*
@@ -33,6 +33,7 @@
#define PCIBIOS_ADDR_FIXUP 0x001
#define PCIBIOS_BUS_FIXUP 0x002
#define PCIBIOS_INTR_FIXUP 0x004
+#define PCIBIOS_INTR_GUESS 0x008
/*
* PCI BIOS return codes.