diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2006-11-27 18:41:24 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2006-11-27 18:41:24 +0000 |
commit | 7e177a786bb321be1c7f03e7805dc1139b9339c0 (patch) | |
tree | 523b22f0ffa51f1a416c25f8eebbbfa1a3dca05f | |
parent | 7c51ad67b81086e88fd2d0cd99479d5edd6f0595 (diff) |
Make normal pic interrupt routing work too.
-rw-r--r-- | sys/dev/acpi/acpiprt.c | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/sys/dev/acpi/acpiprt.c b/sys/dev/acpi/acpiprt.c index d8e7653b5fc..96f8eaca473 100644 --- a/sys/dev/acpi/acpiprt.c +++ b/sys/dev/acpi/acpiprt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpiprt.c,v 1.5 2006/11/27 16:32:43 marco Exp $ */ +/* $OpenBSD: acpiprt.c,v 1.6 2006/11/27 18:41:23 kettenis Exp $ */ /* * Copyright (c) 2006 Mark Kettenis <kettenis@openbsd.org> * @@ -38,6 +38,8 @@ #include <machine/mpbiosvar.h> +#include "ioapic.h" + int acpiprt_match(struct device *, void *, void *); void acpiprt_attach(struct device *, struct device *, void *); @@ -134,9 +136,17 @@ acpiprt_prt_add(struct acpiprt_softc *sc, struct aml_value *v) { struct aml_node *node; struct aml_value res, *pp; - int addr, pin, irq; + u_int64_t addr; + int pin, irq; +#if NIOAPIC > 0 struct mp_intr_map *map; struct ioapic_softc *apic; +#else + pci_chipset_tag_t pc = NULL; + pcitag_t tag; + pcireg_t reg; + int bus, dev, func, nfuncs; +#endif if (v->type != AML_OBJTYPE_PACKAGE || v->length != 4) { printf("invalid mapping object\n"); @@ -181,6 +191,12 @@ acpiprt_prt_add(struct acpiprt_softc *sc, struct aml_value *v) } else { irq = aml_val2int(v->v_package[3]); } + +#ifdef ACPI_DEBUG + printf("%s: addr 0x%llx pin %d irq %d\n", DEVNAME(sc), addr, pin, irq); +#endif + +#if NIOAPIC > 0 apic = ioapic_find_bybase(irq); if (apic == NULL) { printf("%s: no apic found for irq %d\n", DEVNAME(sc), irq); @@ -191,10 +207,6 @@ acpiprt_prt_add(struct acpiprt_softc *sc, struct aml_value *v) if (map == NULL) return; -#ifdef ACPI_DEBUG - printf("%s: addr 0x%x pin %d irq %d\n", DEVNAME(sc), addr, pin, irq); -#endif - memset(map, 0, sizeof *map); map->ioapic = apic; map->ioapic_pin = irq - apic->sc_apic_vecbase; @@ -210,6 +222,27 @@ acpiprt_prt_add(struct acpiprt_softc *sc, struct aml_value *v) map->next = mp_busses[sc->sc_bus].mb_intrs; mp_busses[sc->sc_bus].mb_intrs = map; +#else + bus = sc->sc_bus; + dev = ACPI_PCI_DEV(addr << 16); + tag = pci_make_tag(pc, bus, dev, 0); + + reg = pci_conf_read(pc, tag, PCI_BHLC_REG); + if (PCI_HDRTYPE_MULTIFN(reg)) + nfuncs = 8; + else + nfuncs = 1; + + for (func = 0; func < nfuncs; func++) { + tag = pci_make_tag(pc, bus, dev, func); + reg = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); + if (PCI_INTERRUPT_PIN(reg) == pin + 1) { + reg &= ~(PCI_INTERRUPT_LINE_MASK << PCI_INTERRUPT_LINE_SHIFT); + reg |= irq << PCI_INTERRUPT_LINE_SHIFT; + pci_conf_write(pc, tag, PCI_INTERRUPT_REG, reg); + } + } +#endif } int |