/// <summary> /// Power shutdown /// </summary> public static void Shutdown() { Acpica.AcpiEnterSleepStatePrep(5); CPU.CLI(); Acpica.AcpiEnterSleepState(5); CPU.HLT(); }
/// <summary> /// Sets the IRQ routing /// </summary> private static void setIRQRouting() { m_irqTable = new PciIRQEntry[PCI_BUS_DEV_MAX * PCI_PINS]; // Find root PCI device and handle it int status = Acpica.AcpiGetDevices("PNP0A03", onRootDevice, null, null); if (status != Acpica.AE_OK) { Panic.DoPanic("[PCI] Couldn't get root device"); } }
/// <summary> /// Called as callback when a root device is found /// </summary> /// <param name="Object">The object</param> /// <param name="NestingLevel">Nesting level</param> /// <param name="Context">User context</param> /// <param name="ReturnValue">Return value if early returned</param> /// <returns>Status</returns> private static int onRootDevice(void *Object, uint NestingLevel, void *Context, void **ReturnValue) { // Get routing table AcpiObjects.Buffer buffer; buffer.Length = Acpica.ACPI_ALLOCATE_BUFFER; int status = Acpica.AcpiGetIrqRoutingTable(Object, &buffer); if (status != Acpica.AE_OK) { Panic.DoPanic("[PCI] Couldn't get ACPI IRQ Routing Table"); } // The last entry will have Length 0 Acpica.PCIRoutingTable *table = (Acpica.PCIRoutingTable *)buffer.Pointer; while (table->Length > 0) { // No reference source if (table->Source[0] == 0) { uint slot = (uint)(table->Address >> 16); addIRQ(slot, table->Pin, table->SourceIndex, 0, 0); } // Source is not null, that means we need to lookup the reference resource else { void *handle = null; status = Acpica.AcpiGetHandle(Object, Util.CharPtrToString(table->Source), &handle); if (status != Acpica.AE_OK) { Panic.DoPanic("[PCI] Couldn't load references handle"); } status = Acpica.AcpiWalkResources(handle, Acpica.METHOD_NAME__CRS, onIRQResource, table); if (status != Acpica.AE_OK) { Panic.DoPanic("[PCI] Couldn't process resources for IRQ"); } } // Next entry table = (Acpica.PCIRoutingTable *)((byte *)table + table->Length); } // The object returned should be freed by us Acpica.AcpiOsFree(buffer.Pointer); return(Acpica.AE_OK); }
/// <summary> /// Power reset /// </summary> public static void Reboot() { Acpica.AcpiReset(); }
/// <summary> /// Initializes ACPI /// </summary> public static void Init() { int status = Acpica.AcpiInitializeSubsystem(); if (status != Acpica.AE_OK) { Panic.DoPanic("[ACPI] Couldn't initialize ACPICA subsystem"); } status = Acpica.AcpiInitializeTables(null, 16, false); if (status != Acpica.AE_OK) { Panic.DoPanic("[ACPI] Couldn't initialize tables"); } status = Acpica.AcpiInstallAddressSpaceHandler((void *)Acpica.ACPI_ROOT_OBJECT, Acpica.ACPI_ADR_SPACE_SYSTEM_MEMORY, (void *)Acpica.ACPI_DEFAULT_HANDLER, null, null); if (status != Acpica.AE_OK) { Panic.DoPanic("[ACPI] Could not install address space handler for system memory"); } status = Acpica.AcpiInstallAddressSpaceHandler((void *)Acpica.ACPI_ROOT_OBJECT, Acpica.ACPI_ADR_SPACE_SYSTEM_IO, (void *)Acpica.ACPI_DEFAULT_HANDLER, null, null); if (status != Acpica.AE_OK) { Panic.DoPanic("[ACPI] Could not install address space handler for system IO"); } status = Acpica.AcpiInstallAddressSpaceHandler((void *)Acpica.ACPI_ROOT_OBJECT, Acpica.ACPI_ADR_SPACE_PCI_CONFIG, (void *)Acpica.ACPI_DEFAULT_HANDLER, null, null); if (status != Acpica.AE_OK) { Panic.DoPanic("[ACPI] Could not install address space handler for PCI"); } status = Acpica.AcpiLoadTables(); if (status != Acpica.AE_OK) { Panic.DoPanic("[ACPI] Couldn't load tables"); } status = Acpica.AcpiEnableSubsystem(Acpica.ACPI_FULL_INITIALIZATION); if (status != Acpica.AE_OK) { Panic.DoPanic("[ACPI] Couldn't enable subsystems:"); } status = Acpica.AcpiInitializeObjects(Acpica.ACPI_FULL_INITIALIZATION); if (status != Acpica.AE_OK) { Panic.DoPanic("[ACPI] Couldn't initialize objects"); } // MADT table contains info about APIC, processors, ... Acpica.TableHeader *table; status = Acpica.AcpiGetTable("APIC", 1, &table); if (status != Acpica.AE_OK) { Panic.DoPanic("[ACPI] Couldn't find MADT table"); } parseMADT((MADT *)table); // Set ACPI to APIC using the "_PIC" method, note that this method is not always present // so we "can" ignore the AE_NOT_FOUND error AcpiObjects.IntegerObject arg1; arg1.Type = AcpiObjects.ObjectType.Integer; arg1.Value = 1; AcpiObjects.ObjectList args; args.Count = 1; args.Pointer = &arg1; status = Acpica.AcpiEvaluateObject((void *)Acpica.ACPI_ROOT_OBJECT, "_PIC", &args, null); if (status != Acpica.AE_NOT_FOUND && status != Acpica.AE_OK) { Panic.DoPanic("[ACPI] Couldn't call _PIC method"); } // We are done here Console.WriteLine("[ACPI] Initialized"); }