diff --git a/src/hulk/acpi.d b/src/hulk/acpi.d index 05051ad..c893a03 100644 --- a/src/hulk/acpi.d +++ b/src/hulk/acpi.d @@ -6,37 +6,45 @@ module hulk.acpi; import hulk.hurl; import hulk.klog; import hulk.memory; +import hulk.list; struct Acpi { - private static uint signature(string s) - { - return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24); - } + /** + * List of ACPI tables. + */ + private static __gshared List!Header tables; enum uint APIC_SIGNATURE = signature("APIC"); enum uint MCFG_SIGNATURE = signature("MCFG"); enum uint XSDT_SIGNATURE = signature("XSDT"); - static align(4) struct Header + /** + * ACPI table header structure. + */ + static struct Header { uint signature; uint length; ubyte revision; ubyte checksum; char[6] oemid; - ulong oemtableid; + char[8] oemtableid; uint oem_revision; uint creator_id; uint creator_revision; } + /** + * XSDT table. + */ static struct XSDT { Header header; /* Table pointers are not ulong-aligned! They begin at offset 36. */ align(4) ulong[1] tables; } + static assert(XSDT.tables.offsetof == 36); static struct MADT { @@ -106,7 +114,7 @@ struct Acpi public static void initialize(ulong acpi_xsdt_phys) { - Klog.writefln("\a3Initialize ACPI"); + Klog.writefln("\a3Initializing ACPI"); /* Map the XSDT header. */ map_table(acpi_xsdt_phys, PAGE_SIZE); @@ -126,19 +134,20 @@ struct Acpi { ulong address = xsdt.tables[i]; map_table(address, PAGE_SIZE); - const(Header) * header = cast(const(Header) *)address; + Header * header = cast(Header *)address; uint length = header.length; if (length > PAGE_SIZE) { map_table(address, length); } + tables.add(header); uint signature = header.signature; - Klog.writefln("Found ACPI table %08x (%c%c%c%c)", - signature, + Klog.writefln("Found ACPI table '%c%c%c%c' at %p", signature & 0xFFu, (signature >> 8u) & 0xFFu, (signature >> 16u) & 0xFFu, - (signature >> 24u) & 0xFFu); + (signature >> 24u) & 0xFFu, + address); if (signature == APIC_SIGNATURE) { madt = cast(MADT *)address; @@ -159,8 +168,36 @@ struct Acpi } } + /** + * Get pointer to ACPI table by name. + * + * @param name + * Table name. + */ + public Header * get_table(string name) + { + uint signature = signature(name); + foreach (table; tables) + { + if (table.signature == signature) + { + return &table; + } + } + Klog.fatal_error("Could not find requested ACPI table"); + return null; + } + private static void map_table(ulong address, ulong length) { Hurl.identity_map_range(address, length, PT_WRITABLE | PT_DISABLE_CACHE | PT_NO_EXECUTE); } + + /** + * Convert table signature from string to 32-bit unsigned integer. + */ + private static uint signature(string s) + { + return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24); + } }