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.hurl;
|
||||||
import hulk.klog;
|
import hulk.klog;
|
||||||
import hulk.memory;
|
import hulk.memory;
|
||||||
|
import hulk.list;
|
||||||
|
|
||||||
struct Acpi
|
struct Acpi
|
||||||
{
|
{
|
||||||
private static uint signature(string s)
|
/**
|
||||||
{
|
* List of ACPI tables.
|
||||||
return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24);
|
*/
|
||||||
}
|
private static __gshared List!Header tables;
|
||||||
|
|
||||||
enum uint APIC_SIGNATURE = signature("APIC");
|
enum uint APIC_SIGNATURE = signature("APIC");
|
||||||
enum uint MCFG_SIGNATURE = signature("MCFG");
|
enum uint MCFG_SIGNATURE = signature("MCFG");
|
||||||
enum uint XSDT_SIGNATURE = signature("XSDT");
|
enum uint XSDT_SIGNATURE = signature("XSDT");
|
||||||
|
|
||||||
static align(4) struct Header
|
/**
|
||||||
|
* ACPI table header structure.
|
||||||
|
*/
|
||||||
|
static struct Header
|
||||||
{
|
{
|
||||||
uint signature;
|
uint signature;
|
||||||
uint length;
|
uint length;
|
||||||
ubyte revision;
|
ubyte revision;
|
||||||
ubyte checksum;
|
ubyte checksum;
|
||||||
char[6] oemid;
|
char[6] oemid;
|
||||||
ulong oemtableid;
|
char[8] oemtableid;
|
||||||
uint oem_revision;
|
uint oem_revision;
|
||||||
uint creator_id;
|
uint creator_id;
|
||||||
uint creator_revision;
|
uint creator_revision;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XSDT table.
|
||||||
|
*/
|
||||||
static struct XSDT
|
static struct XSDT
|
||||||
{
|
{
|
||||||
Header header;
|
Header header;
|
||||||
/* Table pointers are not ulong-aligned! They begin at offset 36. */
|
/* Table pointers are not ulong-aligned! They begin at offset 36. */
|
||||||
align(4) ulong[1] tables;
|
align(4) ulong[1] tables;
|
||||||
}
|
}
|
||||||
|
static assert(XSDT.tables.offsetof == 36);
|
||||||
|
|
||||||
static struct MADT
|
static struct MADT
|
||||||
{
|
{
|
||||||
@ -106,7 +114,7 @@ struct Acpi
|
|||||||
|
|
||||||
public static void initialize(ulong acpi_xsdt_phys)
|
public static void initialize(ulong acpi_xsdt_phys)
|
||||||
{
|
{
|
||||||
Klog.writefln("\a3Initialize ACPI");
|
Klog.writefln("\a3Initializing ACPI");
|
||||||
|
|
||||||
/* Map the XSDT header. */
|
/* Map the XSDT header. */
|
||||||
map_table(acpi_xsdt_phys, PAGE_SIZE);
|
map_table(acpi_xsdt_phys, PAGE_SIZE);
|
||||||
@ -126,19 +134,20 @@ struct Acpi
|
|||||||
{
|
{
|
||||||
ulong address = xsdt.tables[i];
|
ulong address = xsdt.tables[i];
|
||||||
map_table(address, PAGE_SIZE);
|
map_table(address, PAGE_SIZE);
|
||||||
const(Header) * header = cast(const(Header) *)address;
|
Header * header = cast(Header *)address;
|
||||||
uint length = header.length;
|
uint length = header.length;
|
||||||
if (length > PAGE_SIZE)
|
if (length > PAGE_SIZE)
|
||||||
{
|
{
|
||||||
map_table(address, length);
|
map_table(address, length);
|
||||||
}
|
}
|
||||||
|
tables.add(header);
|
||||||
uint signature = header.signature;
|
uint signature = header.signature;
|
||||||
Klog.writefln("Found ACPI table %08x (%c%c%c%c)",
|
Klog.writefln("Found ACPI table '%c%c%c%c' at %p",
|
||||||
signature,
|
|
||||||
signature & 0xFFu,
|
signature & 0xFFu,
|
||||||
(signature >> 8u) & 0xFFu,
|
(signature >> 8u) & 0xFFu,
|
||||||
(signature >> 16u) & 0xFFu,
|
(signature >> 16u) & 0xFFu,
|
||||||
(signature >> 24u) & 0xFFu);
|
(signature >> 24u) & 0xFFu,
|
||||||
|
address);
|
||||||
if (signature == APIC_SIGNATURE)
|
if (signature == APIC_SIGNATURE)
|
||||||
{
|
{
|
||||||
madt = cast(MADT *)address;
|
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)
|
private static void map_table(ulong address, ulong length)
|
||||||
{
|
{
|
||||||
Hurl.identity_map_range(address, length, PT_WRITABLE | PT_DISABLE_CACHE | PT_NO_EXECUTE);
|
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