Store ACPI table pointers in list

This commit is contained in:
Josh Holtrop 2023-10-25 19:13:36 -04:00
parent e480bd0ed0
commit 2b87792c67

View File

@ -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);
}
}