diff --git a/src/hulk/acpi.d b/src/hulk/acpi.d index f4f9ee3..eb76c10 100644 --- a/src/hulk/acpi.d +++ b/src/hulk/acpi.d @@ -42,6 +42,8 @@ struct Acpi { static struct Entry { + enum LOCAL_APIC_ADDRESS_OVERRIDE = 5; + ubyte type; ubyte length; } @@ -49,6 +51,24 @@ struct Acpi Header header; uint local_apic_address; uint flags; + + void initialize() + { + apic_address = local_apic_address; + Klog.writefln("Found 32-bit APIC address: 0x%x", apic_address); + const(void) * end = cast(const(void) *)(&this) + header.length; + const(Entry) * entry = cast(const(Entry) *)(cast(ulong)&this + MADT.sizeof); + while (entry < end) + { + entry = cast(const(Entry) *)(cast(size_t)entry + entry.length); + if (entry.type == Entry.LOCAL_APIC_ADDRESS_OVERRIDE) + { + /* Found a 64-bit Local APIC Address Override entry. */ + Klog.writefln("Found 64-bit APIC address: 0x%x", apic_address); + memcpy(cast(void *)&apic_address, cast(const(void) *)entry + 4u, apic_address.sizeof); + } + } + } } static struct MCFG @@ -73,6 +93,22 @@ struct Acpi Header header; uint[2] _reserved; SGMADesc[0] sgma_descs; + + void initialize() + { + Klog.writefln("MCFG length = %u", header.length); + size_t n_sgma_descs = (header.length - MCFG.sgma_descs.offsetof) / MCFG.SGMADesc.sizeof; + Klog.writefln("# SGMA descriptors = %u", (header.length - MCFG.sgma_descs.offsetof) / MCFG.SGMADesc.sizeof); + for (size_t i = 0; i < n_sgma_descs; i++) + { + Klog.writefln("SGMA %u: SG %u; Bus %u-%u; addr %p", + i, + sgma_descs[i].pci_segment_group_number, + sgma_descs[i].start_pci_bus_number, + sgma_descs[i].end_pci_bus_number, + sgma_descs[i].base_address); + } + } } public static __gshared ulong apic_address; @@ -80,7 +116,7 @@ struct Acpi public static void initialize(ulong acpi_xsdt_phys) { /* Map the XSDT header. */ - Hurl.identity_map_range(acpi_xsdt_phys, XSDT.sizeof, 0u); + Hurl.identity_map_range(acpi_xsdt_phys, PAGE_SIZE, 0u); const(XSDT) * xsdt = cast(const(XSDT) *)acpi_xsdt_phys; if (xsdt.header.signature != XSDT_SIGNATURE) { @@ -88,13 +124,22 @@ struct Acpi return; } /* Map the entire XSDT. */ - Hurl.identity_map_range(acpi_xsdt_phys, xsdt.header.length, 0u); + if (xsdt.header.length > PAGE_SIZE) + { + Hurl.identity_map_range(acpi_xsdt_phys, xsdt.header.length, 0u); + } size_t n_entries = (xsdt.header.length - xsdt.header.sizeof) / xsdt.tables[0].sizeof; for (size_t i = 0u; i < n_entries; i++) { ulong address = xsdt.tables[i]; - Hurl.identity_map_range(address, 4u, 0u); - uint signature = *cast(const(uint) *)address; + Hurl.identity_map_range(address, PAGE_SIZE, 0u); + const(Header) * header = cast(const(Header) *)address; + uint length = header.length; + if (length > PAGE_SIZE) + { + Hurl.identity_map_range(address, length, 0u); + } + uint signature = header.signature; Klog.writefln("Found ACPI table %08x (%c%c%c%c)", signature, signature & 0xFFu, @@ -103,50 +148,12 @@ struct Acpi (signature >> 24u) & 0xFFu); if (signature == APIC_SIGNATURE) { - parse_apic_table(address); + (cast(MADT *)address).initialize(); } else if (signature == MCFG_SIGNATURE) { - parse_mcfg_table(address); + (cast(MCFG *)address).initialize(); } } } - - private static parse_apic_table(ulong address) - { - const(MADT) * madt = cast(const(MADT) *)address; - Hurl.identity_map_range(address, madt.header.length, 0u); - apic_address = madt.local_apic_address; - Klog.writefln("Found 32-bit APIC address: 0x%x", apic_address); - const(void) * madt_end = cast(const(void) *)(address + madt.header.length); - const(MADT.Entry) * madt_entry = cast(const(MADT.Entry) *)(address + MADT.sizeof); - while (madt_entry < madt_end) - { - madt_entry = cast(const(MADT.Entry) *)(cast(size_t)madt_entry + madt_entry.length); - if (madt_entry.type == 5u) - { - /* Found a 64-bit Local APIC Address Override entry. */ - Klog.writefln("Found 64-bit APIC address: 0x%x", apic_address); - memcpy(cast(void *)&apic_address, cast(const(void) *)madt_entry + 4u, 8u); - } - } - } - - private static parse_mcfg_table(ulong address) - { - const(MCFG) * mcfg = cast(const(MCFG) *)address; - Hurl.identity_map_range(address, mcfg.header.length, 0u); - Klog.writefln("MCFG length = %u", mcfg.header.length); - size_t n_sgma_descs = (mcfg.header.length - MCFG.sgma_descs.offsetof) / MCFG.SGMADesc.sizeof; - Klog.writefln("# SGMA descriptors = %u", (mcfg.header.length - MCFG.sgma_descs.offsetof) / MCFG.SGMADesc.sizeof); - for (size_t i = 0; i < n_sgma_descs; i++) - { - Klog.writefln("SGMA %u: SG %u; Bus %u-%u; addr %p", - i, - mcfg.sgma_descs[i].pci_segment_group_number, - mcfg.sgma_descs[i].start_pci_bus_number, - mcfg.sgma_descs[i].end_pci_bus_number, - mcfg.sgma_descs[i].base_address); - } - } }