public override void Initialize() { Device.Name = "ACPI"; Pointer rsdpPtr; for (uint addr = 0x000E0000; addr <= 0x000FFFFF; addr += 8) { rsdpPtr = (Pointer)addr; if (rsdpPtr.Load64() == 0x2052545020445352) // 'RSD PTR ' { Descriptor = (RSDPDescriptor *)rsdpPtr; } } if (Descriptor == null) { return; } /*if (Descriptor->Revision == 2) // ACPI v2.0+ * { * Descriptor20 = (RSDPDescriptor20*)rsdpPtr; * * XSDT = (XSDT*)HAL.GetPhysicalMemory((Pointer)Descriptor20->XsdtAddress, 0xFFFF).Address; * FADT = (FADT*)HAL.GetPhysicalMemory((Pointer)FindBySignature("FACP", true), 0xFFFF).Address; * MADT = (MADT*)HAL.GetPhysicalMemory((Pointer)FindBySignature("APIC", true), 0xFFFF).Address; * } * else * {*/ RSDT = (RSDT *)HAL.GetPhysicalMemory((Pointer)Descriptor->RsdtAddress, 0xFFFF).Address; FADT = (FADT *)HAL.GetPhysicalMemory((Pointer)FindBySignature("FACP", false), 0xFFFF).Address; MADT = (MADT *)HAL.GetPhysicalMemory((Pointer)FindBySignature("APIC", false), 0xFFFF).Address; //} if (FADT == null) { return; } if (MADT != null) { ProcessorIDs = new byte[256]; LocalApicAddress = MADT->LocalApicAddress; Pointer ptr = (Pointer)MADT; Pointer ptr2 = ptr + MADT->h.Length; for (ptr += 0x2C; ptr < ptr2;) { MADTEntry *entry = (MADTEntry *)ptr; switch (entry->Type) { case 0: // Processor Local APIC ProcessorLocalAPICEntry *plan = (ProcessorLocalAPICEntry *)ptr; if ((plan->Flags & 1) != 0) { ProcessorIDs[ProcessorCount++] = plan->ApicID; } break; case 1: // I/O APIC IOAPICEntry *ipe = (IOAPICEntry *)ptr; IOApicAddress = ipe->ApicAddress; break; case 5: // 64-bit LAPIC LongLocalAPICEntry *llpe = (LongLocalAPICEntry *)ptr; LocalApicAddress = (uint)(llpe->ApicAddress); break; } ptr += entry->Length; } } Pointer dsdt = (Pointer)FADT->Dsdt; if (dsdt.Load32() == 0x54445344) //DSDT { Pointer S5Addr = dsdt + sizeof(ACPISDTHeader); int dsdtLength = (int)dsdt.Load32() + 1 - sizeof(ACPISDTHeader); for (int k = 0; k < dsdtLength; k++) { if (S5Addr.Load32() == 0x5f35535f) //_S5_ { break; } S5Addr++; } if (dsdtLength > 0) { if (((S5Addr - 1).Load8() == 0x08 || ((S5Addr - 2).Load8() == 0x08 && (S5Addr - 1).Load8() == '\\')) && (S5Addr + 4).Load8() == 0x12) { S5Addr += 5; S5Addr += ((S5Addr.Load32() & 0xC0) >> 6) + 2; if (S5Addr.Load8() == 0x0A) { S5Addr++; } SLP_TYPa = (short)(S5Addr.Load16() << 10); S5Addr++; if (S5Addr.Load8() == 0x0A) { S5Addr++; } SLP_TYPb = (short)(S5Addr.Load16() << 10); SLP_EN = 1 << 13; SMI_CommandPort = HAL.GetWriteIOPort((ushort)FADT->SMI_CommandPort); bool has64BitPtr = false; if (Descriptor->Revision == 2) { ResetAddress = HAL.GetWriteIOPort((ushort)FADT->ResetReg.Address); ResetValue = FADT->ResetValue; if (Pointer.Size == 8) // 64-bit { has64BitPtr = true; PM1aControlBlock = HAL.GetWriteIOPort((ushort)FADT->X_PM1aControlBlock.Address); if (FADT->X_PM1bControlBlock.Address != 0) { PM1bControlBlock = HAL.GetWriteIOPort((ushort)FADT->X_PM1bControlBlock.Address); } } } if (!has64BitPtr) { PM1aControlBlock = HAL.GetWriteIOPort((ushort)FADT->PM1aControlBlock); if (FADT->PM1bControlBlock != 0) { PM1bControlBlock = HAL.GetWriteIOPort((ushort)FADT->PM1bControlBlock); } } } } } }