Store ACPI table pointers in list
This commit is contained in:
parent
e480bd0ed0
commit
2b87792c67
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user