Move MADT table processing from ACPI to APIC
This commit is contained in:
parent
2b87792c67
commit
e32282f6f0
@ -15,14 +15,13 @@ struct Acpi
|
|||||||
*/
|
*/
|
||||||
private static __gshared List!Header tables;
|
private static __gshared List!Header tables;
|
||||||
|
|
||||||
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");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ACPI table header structure.
|
* ACPI table header structure.
|
||||||
*/
|
*/
|
||||||
static struct Header
|
public static struct Header
|
||||||
{
|
{
|
||||||
uint signature;
|
uint signature;
|
||||||
uint length;
|
uint length;
|
||||||
@ -46,37 +45,6 @@ struct Acpi
|
|||||||
}
|
}
|
||||||
static assert(XSDT.tables.offsetof == 36);
|
static assert(XSDT.tables.offsetof == 36);
|
||||||
|
|
||||||
static struct MADT
|
|
||||||
{
|
|
||||||
static struct Entry
|
|
||||||
{
|
|
||||||
enum LOCAL_APIC_ADDRESS_OVERRIDE = 5;
|
|
||||||
|
|
||||||
ubyte type;
|
|
||||||
ubyte length;
|
|
||||||
}
|
|
||||||
|
|
||||||
Header header;
|
|
||||||
uint local_apic_address;
|
|
||||||
uint flags;
|
|
||||||
|
|
||||||
void initialize()
|
|
||||||
{
|
|
||||||
apic_address = local_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. */
|
|
||||||
memcpy(cast(void *)&apic_address, cast(const(void) *)entry + 4u, apic_address.sizeof);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct MCFG
|
static struct MCFG
|
||||||
{
|
{
|
||||||
/* PCI Segment Group Memory Area Descriptor. */
|
/* PCI Segment Group Memory Area Descriptor. */
|
||||||
@ -106,10 +74,6 @@ struct Acpi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public __gshared ulong apic_address;
|
|
||||||
|
|
||||||
public __gshared MADT * madt;
|
|
||||||
|
|
||||||
public __gshared MCFG * mcfg;
|
public __gshared MCFG * mcfg;
|
||||||
|
|
||||||
public static void initialize(ulong acpi_xsdt_phys)
|
public static void initialize(ulong acpi_xsdt_phys)
|
||||||
@ -148,20 +112,11 @@ struct Acpi
|
|||||||
(signature >> 16u) & 0xFFu,
|
(signature >> 16u) & 0xFFu,
|
||||||
(signature >> 24u) & 0xFFu,
|
(signature >> 24u) & 0xFFu,
|
||||||
address);
|
address);
|
||||||
if (signature == APIC_SIGNATURE)
|
if (signature == MCFG_SIGNATURE)
|
||||||
{
|
|
||||||
madt = cast(MADT *)address;
|
|
||||||
madt.initialize();
|
|
||||||
}
|
|
||||||
else if (signature == MCFG_SIGNATURE)
|
|
||||||
{
|
{
|
||||||
mcfg = cast(MCFG *)address;
|
mcfg = cast(MCFG *)address;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (madt == null)
|
|
||||||
{
|
|
||||||
Klog.fatal_error("MADT table not found");
|
|
||||||
}
|
|
||||||
if (mcfg == null)
|
if (mcfg == null)
|
||||||
{
|
{
|
||||||
Klog.fatal_error("MCFG table not found");
|
Klog.fatal_error("MCFG table not found");
|
||||||
@ -174,14 +129,14 @@ struct Acpi
|
|||||||
* @param name
|
* @param name
|
||||||
* Table name.
|
* Table name.
|
||||||
*/
|
*/
|
||||||
public Header * get_table(string name)
|
public static Header * get_table(string name)
|
||||||
{
|
{
|
||||||
uint signature = signature(name);
|
uint signature = signature(name);
|
||||||
foreach (table; tables)
|
foreach (table; tables)
|
||||||
{
|
{
|
||||||
if (table.signature == signature)
|
if (table.signature == signature)
|
||||||
{
|
{
|
||||||
return &table;
|
return table;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Klog.fatal_error("Could not find requested ACPI table");
|
Klog.fatal_error("Could not find requested ACPI table");
|
||||||
|
@ -9,6 +9,7 @@ import hulk.idt;
|
|||||||
import hulk.rtc;
|
import hulk.rtc;
|
||||||
import hulk.pit;
|
import hulk.pit;
|
||||||
import hulk.klog;
|
import hulk.klog;
|
||||||
|
import hulk.memory;
|
||||||
|
|
||||||
struct Apic
|
struct Apic
|
||||||
{
|
{
|
||||||
@ -17,6 +18,49 @@ struct Apic
|
|||||||
private enum ulong IRQ_PIT = 2u;
|
private enum ulong IRQ_PIT = 2u;
|
||||||
private enum ulong IRQ_RTC = 8u;
|
private enum ulong IRQ_RTC = 8u;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MADT ACPI table structure.
|
||||||
|
*/
|
||||||
|
static struct MADT
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* MADT table entry header.
|
||||||
|
*/
|
||||||
|
static struct Entry
|
||||||
|
{
|
||||||
|
enum LOCAL_APIC_ADDRESS_OVERRIDE = 5;
|
||||||
|
|
||||||
|
ubyte type;
|
||||||
|
ubyte length;
|
||||||
|
}
|
||||||
|
|
||||||
|
Acpi.Header header;
|
||||||
|
uint local_apic_address;
|
||||||
|
uint flags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scan the MADT table.
|
||||||
|
*/
|
||||||
|
public void scan()
|
||||||
|
{
|
||||||
|
apic_registers = cast(ApicRegisters *)local_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. */
|
||||||
|
memcpy(cast(void *)&apic_registers, cast(const(void) *)entry + 4u, apic_registers.sizeof);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APIC register structure.
|
||||||
|
*/
|
||||||
static struct ApicRegister
|
static struct ApicRegister
|
||||||
{
|
{
|
||||||
public uint value;
|
public uint value;
|
||||||
@ -25,6 +69,9 @@ struct Apic
|
|||||||
private ubyte[12] _padding;
|
private ubyte[12] _padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APIC registers.
|
||||||
|
*/
|
||||||
static struct ApicRegisters
|
static struct ApicRegisters
|
||||||
{
|
{
|
||||||
ApicRegister[2] _reserved0;
|
ApicRegister[2] _reserved0;
|
||||||
@ -57,6 +104,9 @@ struct Apic
|
|||||||
ApicRegister divide_configuration;
|
ApicRegister divide_configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* I/O APIC registers.
|
||||||
|
*/
|
||||||
static struct IoApicRegisters
|
static struct IoApicRegisters
|
||||||
{
|
{
|
||||||
ApicRegister address;
|
ApicRegister address;
|
||||||
@ -66,10 +116,17 @@ struct Apic
|
|||||||
private static __gshared ApicRegisters * apic_registers;
|
private static __gshared ApicRegisters * apic_registers;
|
||||||
private static __gshared IoApicRegisters * io_apic_registers;
|
private static __gshared IoApicRegisters * io_apic_registers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize APIC.
|
||||||
|
*/
|
||||||
public static void initialize()
|
public static void initialize()
|
||||||
{
|
{
|
||||||
apic_registers = cast(ApicRegisters *)Acpi.apic_address;
|
Klog.writefln("\a3Initializing APIC");
|
||||||
io_apic_registers = cast(IoApicRegisters *)0xFEC0_0000u;
|
io_apic_registers = cast(IoApicRegisters *)0xFEC0_0000u;
|
||||||
|
MADT * madt = cast(MADT *)Acpi.get_table("APIC");
|
||||||
|
madt.scan();
|
||||||
|
Klog.writefln("APIC found at %p", apic_registers);
|
||||||
|
Klog.writefln("I/O APIC found at %p", io_apic_registers);
|
||||||
Hurl.map(cast(ulong)apic_registers, cast(ulong)apic_registers,
|
Hurl.map(cast(ulong)apic_registers, cast(ulong)apic_registers,
|
||||||
PT_WRITABLE | PT_WRITE_THROUGH | PT_DISABLE_CACHE | PT_NO_EXECUTE);
|
PT_WRITABLE | PT_WRITE_THROUGH | PT_DISABLE_CACHE | PT_NO_EXECUTE);
|
||||||
Hurl.map(cast(ulong)io_apic_registers, cast(ulong)io_apic_registers,
|
Hurl.map(cast(ulong)io_apic_registers, cast(ulong)io_apic_registers,
|
||||||
@ -86,6 +143,9 @@ struct Apic
|
|||||||
configure_io_apic_irq(IRQ_RTC, Idt.INT_APIC_BASE + IRQ_RTC);
|
configure_io_apic_irq(IRQ_RTC, Idt.INT_APIC_BASE + IRQ_RTC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure routing for an I/O APIC IRQ.
|
||||||
|
*/
|
||||||
private static void configure_io_apic_irq(size_t io_apic_irq, size_t interrupt_id)
|
private static void configure_io_apic_irq(size_t io_apic_irq, size_t interrupt_id)
|
||||||
{
|
{
|
||||||
ulong entry = interrupt_id;
|
ulong entry = interrupt_id;
|
||||||
@ -95,11 +155,17 @@ struct Apic
|
|||||||
io_apic_registers.data.value = entry >> 32u;
|
io_apic_registers.data.value = entry >> 32u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signal APIC end of interrupt.
|
||||||
|
*/
|
||||||
public static void eoi()
|
public static void eoi()
|
||||||
{
|
{
|
||||||
apic_registers.eoi.value = 0u;
|
apic_registers.eoi.value = 0u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APIC interrupt handler.
|
||||||
|
*/
|
||||||
public static void isr(ulong vector)
|
public static void isr(ulong vector)
|
||||||
{
|
{
|
||||||
switch (vector)
|
switch (vector)
|
||||||
|
@ -34,12 +34,12 @@ struct List(T)
|
|||||||
/**
|
/**
|
||||||
* Allow foreach iteration across a List.
|
* Allow foreach iteration across a List.
|
||||||
*/
|
*/
|
||||||
public int opApply(scope int delegate(ref T) dg)
|
public int opApply(scope int delegate(T *) dg)
|
||||||
{
|
{
|
||||||
List!T * entry = &this;
|
List!T * entry = &this;
|
||||||
while (entry.next != null)
|
while (entry.next != null)
|
||||||
{
|
{
|
||||||
int result = dg(*entry.item);
|
int result = dg(entry.item);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
|
@ -17,7 +17,7 @@ struct Usb
|
|||||||
{
|
{
|
||||||
if (pci_device.type == Pci.XHCI_CONTROLLER)
|
if (pci_device.type == Pci.XHCI_CONTROLLER)
|
||||||
{
|
{
|
||||||
XHCI.build(&pci_device);
|
XHCI.build(pci_device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user