/// <summary> /// Parses the MADT /// </summary> /// <param name="madt">The MADT</param> private static void parseMADT(MADT *madt) { m_madt = madt; LocalApic.SetLocalControllerAddress(madt->LocalControllerAddress); m_intSourceOverrides = new ISAOverride[16]; for (uint i = 0; i < 16; i++) { m_intSourceOverrides[i].GSI = i; m_intSourceOverrides[i].Polarity = IOApic.IOAPIC_REDIR_POLARITY_HIGH; m_intSourceOverrides[i].Trigger = IOApic.IOAPIC_REDIR_TRIGGER_EDGE; } // After the flags field, the rest of the table contains a variable length of records uint current = (uint)madt + (uint)sizeof(MADT); uint end = current + madt->Header.Length - (uint)sizeof(MADT); while (current < end) { ApicEntryHeader * header = (ApicEntryHeader *)current; ApicEntryHeaderType type = (ApicEntryHeaderType)header->Type; switch (type) { case ApicEntryHeaderType.LOCAL_APIC: ApicLocalApic *localAPIC = (ApicLocalApic *)(current + sizeof(ApicEntryHeader)); Console.Write("[ACPI] Found CPU "); Console.WriteNum(localAPIC->ProcessorID); Console.Write('\n'); break; case ApicEntryHeaderType.IO_APIC: ApicIOApic *IOApicStruct = (ApicIOApic *)(current + sizeof(ApicEntryHeader)); Console.Write("[ACPI] Found IO APIC at "); Console.WriteHex(IOApicStruct->IOAPICAddress); Console.Write('\n'); IOApic IOApic = new IOApic(IOApicStruct->IOAPIC_ID, (void *)IOApicStruct->IOAPICAddress, IOApicStruct->GlobalSystemInterruptBase); IOApicManager.Add(IOApic); break; case ApicEntryHeaderType.INTERRUPT_SOURCE_OVERRIDE: ApicInterruptSourceOverride *intSourceOverride = (ApicInterruptSourceOverride *)(current + sizeof(ApicEntryHeader)); m_intSourceOverrides[intSourceOverride->IRQSource].GSI = intSourceOverride->GlobalSystemInterrupt; m_intSourceOverrides[intSourceOverride->IRQSource].Polarity = (uint)(intSourceOverride->Flags & 0x3); m_intSourceOverrides[intSourceOverride->IRQSource].Trigger = (uint)((intSourceOverride->Flags >> 2) & 0x3); break; } current += header->Length; } }
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); } } } } } }