ACPI_STATUS AcpiExPciConfigSpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, UINT64 *Value, void *HandlerContext, void *RegionContext) { ACPI_STATUS Status = AE_OK; ACPI_PCI_ID *PciId; UINT16 PciRegister; ACPI_FUNCTION_TRACE (ExPciConfigSpaceHandler); /* * The arguments to AcpiOs(Read|Write)PciConfiguration are: * * PciSegment is the PCI bus segment range 0-31 * PciBus is the PCI bus number range 0-255 * PciDevice is the PCI device number range 0-31 * PciFunction is the PCI device function number * PciRegister is the Config space register range 0-255 bytes * * Value - input value for write, output address for read * */ PciId = (ACPI_PCI_ID *) RegionContext; PciRegister = (UINT16) (UINT32) Address; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Pci-Config %u (%u) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n", Function, BitWidth, PciId->Segment, PciId->Bus, PciId->Device, PciId->Function, PciRegister)); switch (Function) { case ACPI_READ: *Value = 0; Status = AcpiOsReadPciConfiguration (PciId, PciRegister, Value, BitWidth); break; case ACPI_WRITE: Status = AcpiOsWritePciConfiguration (PciId, PciRegister, *Value, BitWidth); break; default: Status = AE_BAD_PARAMETER; break; } return_ACPI_STATUS (Status); }
static void MsgClaimPci(uintptr_t rcpt, uintptr_t addr, uintptr_t pins) { addr &= 0xffff; ACPI_PCI_ID id = { 0, (addr >> 8) & 0xff, (addr >> 3) & 31, addr & 7 }; log(claim_pci, "claim pci %02x:%02x.%x\n", id.Bus, id.Device, id.Function); // Set up whatever stuff to track PCI device drivers in general int irqs[4] = {0}; for (int pin = 0; pin < 4; pin++) { if (!(pins & (1 << pin))) continue; ACPI_STATUS status = RouteIRQ(&id, 0, &irqs[pin]); CHECK_STATUS("RouteIRQ"); log(claim_pci, "%02x:%02x.%x pin %d routed to IRQ %#x\n", id.Bus, id.Device, id.Function, pin, irqs[pin]); } if (pins & ACPI_PCI_CLAIM_MASTER) { u64 value; AcpiOsReadPciConfiguration(&id, PCI_COMMAND, &value, 16); if (!(value & PCI_COMMAND_MASTER)) { value |= PCI_COMMAND_MASTER; AcpiOsWritePciConfiguration(&id, PCI_COMMAND, value, 16); } } pins = (u64)irqs[3] << 48 | (u64)irqs[2] << 32 | irqs[1] << 16 | irqs[0]; send2(MSG_ACPI_CLAIM_PCI, rcpt, addr, pins); hmod(rcpt, (uintptr_t)pci_device_handles + addr, 0); return; failed: send2(MSG_ACPI_CLAIM_PCI, rcpt, 0, 0); } static size_t debugger_buffer_pos = 0; static void debugger_pre_cmd(void) { debugger_buffer_pos = 0; AcpiGbl_MethodExecuting = FALSE; AcpiGbl_StepToNextCall = FALSE; AcpiDbSetOutputDestination(ACPI_DB_CONSOLE_OUTPUT); }
static ACPI_STATUS AcpiHwGetPciDeviceInfo ( ACPI_PCI_ID *PciId, ACPI_HANDLE PciDevice, UINT16 *BusNumber, BOOLEAN *IsBridge) { ACPI_STATUS Status; ACPI_OBJECT_TYPE ObjectType; UINT64 ReturnValue; UINT64 PciValue; /* We only care about objects of type Device */ Status = AcpiGetType (PciDevice, &ObjectType); if (ACPI_FAILURE (Status)) { return (Status); } if (ObjectType != ACPI_TYPE_DEVICE) { return (AE_OK); } /* We need an _ADR. Ignore device if not present */ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, PciDevice, &ReturnValue); if (ACPI_FAILURE (Status)) { return (AE_OK); } /* * From _ADR, get the PCI Device and Function and * update the PCI ID. */ PciId->Device = ACPI_HIWORD (ACPI_LODWORD (ReturnValue)); PciId->Function = ACPI_LOWORD (ACPI_LODWORD (ReturnValue)); /* * If the previous device was a bridge, use the previous * device bus number */ if (*IsBridge) { PciId->Bus = *BusNumber; } /* * Get the bus numbers from PCI Config space: * * First, get the PCI HeaderType */ *IsBridge = FALSE; Status = AcpiOsReadPciConfiguration (PciId, PCI_CFG_HEADER_TYPE_REG, &PciValue, 8); if (ACPI_FAILURE (Status)) { return (Status); } /* We only care about bridges (1=PciBridge, 2=CardBusBridge) */ PciValue &= PCI_HEADER_TYPE_MASK; if ((PciValue != PCI_TYPE_BRIDGE) && (PciValue != PCI_TYPE_CARDBUS_BRIDGE)) { return (AE_OK); } /* Bridge: Get the Primary BusNumber */ Status = AcpiOsReadPciConfiguration (PciId, PCI_CFG_PRIMARY_BUS_NUMBER_REG, &PciValue, 8); if (ACPI_FAILURE (Status)) { return (Status); } *IsBridge = TRUE; PciId->Bus = (UINT16) PciValue; /* Bridge: Get the Secondary BusNumber */ Status = AcpiOsReadPciConfiguration (PciId, PCI_CFG_SECONDARY_BUS_NUMBER_REG, &PciValue, 8); if (ACPI_FAILURE (Status)) { return (Status); } *BusNumber = (UINT16) PciValue; return (AE_OK); }
void main(int argc, char *argv[]) { int set = -1, enable = -1; int seg = 0, bus = 0, dev = 2, fn = 0, pin = 0; ACPI_STATUS status; int verbose = 0; AcpiDbgLevel = 0; ARGBEGIN{ case 'v': AcpiDbgLevel = ACPI_LV_VERBOSITY1; verbose++; break; case 's': set = open("#P/irqmap", OWRITE); if (set < 0) sysfatal("%r"); break; default: sysfatal("usage: acpi/irq [-v] [-s]"); break; }ARGEND; status = AcpiInitializeSubsystem(); if (ACPI_FAILURE(status)) { sysfatal("Error %d\n", status); } status = AcpiInitializeTables(NULL, 0, FALSE); if (ACPI_FAILURE(status)) sysfatal("can't set up acpi tables: %d", status); if (verbose) print("init dables\n"); status = AcpiLoadTables(); if (ACPI_FAILURE(status)) sysfatal("Can't load ACPI tables: %d", status); /* from acpi: */ /* If the Hardware Reduced flag is set, machine is always in acpi mode */ AcpiGbl_ReducedHardware = 1; if (verbose) print("LOADED TABLES.\n"); status = AcpiEnableSubsystem(0); if (ACPI_FAILURE(status)) print("Probably does not matter: Can't enable ACPI subsystem"); if (verbose) print("enabled subsystem.\n"); status = AcpiInitializeObjects(0); if (ACPI_FAILURE(status)) sysfatal("Can't Initialize ACPI objects"); int picmode; status = FindIOAPICs(&picmode); if (picmode == 0) sysfatal("PANIC: Can't handle picmode 0!"); ACPI_STATUS ExecuteOSI(int pic_mode); if (verbose) print("FindIOAPICs returns status %d picmode %d\n", status, picmode); status = ExecuteOSI(picmode); CHECK_STATUS("ExecuteOSI"); failed: if (verbose) print("inited objects.\n"); if (verbose) AcpiDbgLevel |= ACPI_LV_VERBOSITY1 | ACPI_LV_FUNCTIONS; status = AcpiInitializeDebugger(); if (ACPI_FAILURE(status)) { sysfatal("Error %d\n", status); } int GetPRT(); status = GetPRT(); if (ACPI_FAILURE(status)) { sysfatal("Error %d\n", status); } while (1) { if (scanf("%x %x", &bus, &dev) < 0) break; ACPI_STATUS RouteIRQ(ACPI_PCI_ID* device, int pin, int* irq); AcpiDbgLevel = 0; ACPI_PCI_ID id = (ACPI_PCI_ID){seg, bus, dev, fn}; status = AcpiOsReadPciConfiguration (&id, 0x3d, &pin, 8); if (!ACPI_SUCCESS(status)){ printf("Can't read pin for bus %d dev %d\n", bus, dev); continue; } print("ROUTE {%d, %d, %d, %d}, pin %d\n", seg, bus, dev, fn, pin); int irq; status = RouteIRQ(&id, pin, &irq); print("status %d, irq %d\n", status, irq); AcpiDbgLevel = 0; print("echo %d %d %d %d 0x%x > /dev/irqmap", seg, bus, dev, fn, irq); //ACPI_STATUS PrintDevices(void); //status = PrintDevices(); if (set > -1) fprint(set, "%d %d %d %d 0x%x", seg, bus, dev, fn, irq); } /* we're done. Enable the IRQs we might have set up. */ enable = open("/dev/irqenable", OWRITE); if (enable < 0) sysfatal("/dev/irqenable: %r"); if (write(enable, "", 1) < 1) sysfatal("Write irqenable: %r"); exits(0); }