From c9b6c92cc901e3f75bf123860844d35355f26147 Mon Sep 17 00:00:00 2001 From: msmith Date: Thu, 19 Oct 2000 08:06:50 +0000 Subject: Call the BIOS to route the selected interrupt. Correctly calculate the interrupt from the PCI routing table (ffs returns 1 for the rightmost bit, not 0). --- sys/amd64/pci/pci_cfgreg.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'sys/amd64/pci/pci_cfgreg.c') diff --git a/sys/amd64/pci/pci_cfgreg.c b/sys/amd64/pci/pci_cfgreg.c index 0de51ed..56107fc 100644 --- a/sys/amd64/pci/pci_cfgreg.c +++ b/sys/amd64/pci/pci_cfgreg.c @@ -133,12 +133,16 @@ pci_cfgregwrite(int bus, int slot, int func, int reg, u_int32_t data, int bytes) * * XXX this needs to learn to actually route uninitialised interrupts as well * as just returning interrupts for stuff that's already initialised. + * + * XXX we don't do anything "right" with the function number in the PIR table + * (because the consumer isn't currently passing it in). */ int pci_cfgintr(int bus, int device, int pin) { struct PIR_entry *pe; - int i; + int i, irq; + struct bios_regs args; if ((bus < 0) || (bus > 255) || (device < 0) || (device > 255) || (pin < 1) || (pin > 4)) @@ -151,11 +155,25 @@ pci_cfgintr(int bus, int device, int pin) if ((bus != pe->pe_bus) || (device != pe->pe_device)) continue; if (!powerof2(pe->pe_intpin[pin - 1].irqs)) { - printf("pci_cfgintr: %d:%d:%c is not routed to a unique interrupt\n", bus, device, 'A' + pin - 1); + printf("pci_cfgintr: %d:%d:%c is not routed to a unique interrupt\n", + bus, device, 'A' + pin - 1); break; } - printf("pci_cfgintr: %d:%d:%c routed to irq %d\n", bus, device, 'A' + pin - 1, ffs(pe->pe_intpin[pin - 1].irqs)); - return(ffs(pe->pe_intpin[pin - 1].irqs)); + irq = ffs(pe->pe_intpin[pin - 1].irqs) - 1; + printf("pci_cfgintr: %d:%d:%c routed to irq %d\n", + bus, device, 'A' + pin - 1, irq); + + /* + * Ask the BIOS to route the interrupt + */ + args.eax = PCIBIOS_ROUTE_INTERRUPT; + args.ebx = (bus << 8) | (device << 3); + args.ecx = (irq << 8) | (0xa + pin - 1); /* pin value is 0xa - 0xd */ + bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); + + /* XXX if it fails, we should smack the router hardware directly */ + + return(irq); } return(255); } -- cgit v1.1