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); }
void start() { ACPI_STATUS status = AE_OK; printf("acpica: starting...\n"); // NB! Must be at least as large as physical memory - the ACPI tables could // be anywhere. (Could be handled by AcpiOsMapMemory though.) map(0, MAP_PHYS | PROT_READ | PROT_WRITE | PROT_NO_CACHE, (void*)ACPI_PHYS_BASE, 0, USER_MAP_MAX - ACPI_PHYS_BASE); __default_section_init(); AcpiDbgLayer = 0; AcpiDbgLevel = ACPI_LV_REPAIR | ACPI_LV_INTERRUPTS; status = InitializeFullAcpi (); CHECK_STATUS("InitializeFullAcpi"); int pic_mode = 0; // Default is PIC mode if something fails status = PrintAPICTable(); CHECK_STATUS("PrintAPICTable"); status = FindIOAPICs(&pic_mode); CHECK_STATUS("Find IOAPIC"); status = ExecuteOSI(pic_mode); CHECK_STATUS("ExecuteOSI"); // Tables we get in Bochs: // * DSDT: All the AML code // * FACS // * FACP // * APIC (= MADT) // * SSDT: Secondary System Description Table // Contains more AML code loaded automatically by ACPICA // More tables on qemu: // * Another SSDT (Loaded by ACPICA) // * HPET table // PrintFACSTable(); // PrintFACPTable(); // TODO Iterate through and disable all pci interrupt link devices (call // _DIS). Then we'll enable the ones we actually intend to use. EnumeratePCI(); AcpiWriteBitRegister(ACPI_BITREG_SCI_ENABLE, 1); //AcpiWriteBitRegister(ACPI_BITREG_POWER_BUTTON_ENABLE, 1); AcpiInstallGlobalEventHandler(GlobalEventHandler, NULL); AcpiEnableEvent(ACPI_EVENT_POWER_BUTTON, 0); for (;;) { ipc_dest_t rcpt = 0x100; ipc_arg_t arg = 0; ipc_arg_t arg2 = 0; ipc_msg_t msg = recv2(&rcpt, &arg, &arg2); //printf("acpica: Received %#lx from %#lx: %#lx %#lx\n", msg, rcpt, arg, arg2); if (msg == MSG_PULSE) { if (AcpiOsCheckInterrupt(rcpt, arg)) { continue; } else { printf("acpica: Unhandled pulse: %#x from %#lx\n", arg, rcpt); } } switch (msg & 0xff) { case MSG_ACPI_FIND_PCI: MsgFindPci(rcpt, arg); break; case MSG_ACPI_CLAIM_PCI: MsgClaimPci(rcpt, arg, arg2); break; // This feels a bit wrong, but as long as we use PIO access to PCI // configuration space, we need to serialize all accesses. case MSG_ACPI_READ_PCI: arg = PciReadWord((arg & 0x7ffffffc) | 0x80000000); send1(MSG_ACPI_READ_PCI, rcpt, arg); break; case MSG_ACPI_DEBUGGER_INIT: debugger_pre_cmd(); send0(MSG_ACPI_DEBUGGER_INIT, rcpt); break; case MSG_ACPI_DEBUGGER_BUFFER: assert(debugger_buffer_pos < ACPI_DB_LINE_BUFFER_SIZE); AcpiGbl_DbLineBuf[debugger_buffer_pos++] = arg; send0(MSG_ACPI_DEBUGGER_BUFFER, rcpt); break; case MSG_ACPI_DEBUGGER_CMD: assert(debugger_buffer_pos < ACPI_DB_LINE_BUFFER_SIZE); AcpiGbl_DbLineBuf[debugger_buffer_pos++] = 0; putchar('\n'); AcpiDbCommandDispatch(AcpiGbl_DbLineBuf, NULL, NULL); debugger_pre_cmd(); send0(MSG_ACPI_DEBUGGER_CMD, rcpt); break; case MSG_ACPI_DEBUGGER_CLR_BUFFER: debugger_pre_cmd(); send0(MSG_ACPI_DEBUGGER_CLR_BUFFER, rcpt); break; case MSG_REG_IRQ: RegIRQ(rcpt, arg); continue; case MSG_IRQ_ACK: AckIRQ(rcpt); continue; } // TODO Handle other stuff. if (rcpt == 0x100) { hmod(rcpt, 0, 0); } } __builtin_unreachable(); failed: printf("ACPI failed :( (status %x)\n", status); abort(); }