Rework scanning MADT table entries
Get I/O APIC address from MADT entry. Add DEBUG flag for APIC. Show number of CPUs found.
This commit is contained in:
parent
c0a00b528e
commit
7264a31ff3
193
src/hulk/apic.d
193
src/hulk/apic.d
@ -13,6 +13,8 @@ import hulk.memory;
|
||||
|
||||
struct Apic
|
||||
{
|
||||
private enum DEBUG = false;
|
||||
private enum DEFAULT_IO_APIC_ADDRESS = 0xFEC0_0000u;
|
||||
private enum uint PERIODIC_MODE = 0x2_0000u;
|
||||
|
||||
private enum ulong IRQ_PIT = 2u;
|
||||
@ -28,16 +30,112 @@ struct Apic
|
||||
*/
|
||||
static struct Entry
|
||||
{
|
||||
enum PROCESSOR_LOCAL_APIC = 0;
|
||||
enum IO_APIC = 1;
|
||||
enum IO_APIC_INTERRUPT_SOURCE_OVERRIDE = 2;
|
||||
enum IO_APIC_NMI_SOURCE = 3;
|
||||
enum LOCAL_APIC_NMI = 4;
|
||||
enum LOCAL_APIC_ADDRESS_OVERRIDE = 5;
|
||||
enum PROCESSOR_LOCAL_X2APIC = 9;
|
||||
|
||||
ubyte type;
|
||||
ubyte length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processor Local APIC.
|
||||
*/
|
||||
static struct Entry0
|
||||
{
|
||||
Entry header;
|
||||
ubyte acpi_processor_id;
|
||||
ubyte apic_id;
|
||||
uint flags;
|
||||
}
|
||||
static assert(Entry0.sizeof == 8);
|
||||
|
||||
/**
|
||||
* I/O APIC.
|
||||
*/
|
||||
static struct Entry1
|
||||
{
|
||||
Entry header;
|
||||
ubyte io_apic_id;
|
||||
ubyte _reserved;
|
||||
uint io_apic_address;
|
||||
uint global_system_interrupt_base;
|
||||
}
|
||||
static assert(Entry1.sizeof == 12);
|
||||
|
||||
/**
|
||||
* IO/APIC Interrupt Source Override.
|
||||
*/
|
||||
static struct Entry2
|
||||
{
|
||||
Entry header;
|
||||
ubyte bus_source;
|
||||
ubyte irq_source;
|
||||
uint global_system_interrupt;
|
||||
ushort flags;
|
||||
ushort _reserved;
|
||||
}
|
||||
static assert(Entry2.sizeof == 12);
|
||||
|
||||
/**
|
||||
* IO/APIC Non-maskable interrupt source.
|
||||
*/
|
||||
static struct Entry3
|
||||
{
|
||||
Entry header;
|
||||
ubyte nmi_source;
|
||||
ubyte _reserved;
|
||||
ushort flags;
|
||||
ubyte[4] global_system_interrupt;
|
||||
}
|
||||
static assert(Entry3.sizeof == 10);
|
||||
|
||||
/**
|
||||
* Local APIC Non-maskable interrupts.
|
||||
*/
|
||||
static struct Entry4
|
||||
{
|
||||
Entry header;
|
||||
ubyte acpi_processor_id;
|
||||
ubyte[2] flags;
|
||||
ubyte lint_nr;
|
||||
}
|
||||
static assert(Entry4.sizeof == 6);
|
||||
|
||||
/**
|
||||
* Local APIC Address Override.
|
||||
*/
|
||||
static struct Entry5
|
||||
{
|
||||
Entry header;
|
||||
ushort _reserved;
|
||||
ubyte[8] local_apic_address;
|
||||
}
|
||||
static assert(Entry5.sizeof == 12);
|
||||
|
||||
/**
|
||||
* Processor Local x2APIC.
|
||||
*/
|
||||
static struct Entry9
|
||||
{
|
||||
Entry header;
|
||||
ushort _reserved;
|
||||
uint local_x2apic_id;
|
||||
uint flags;
|
||||
uint acpi_id;
|
||||
}
|
||||
static assert(Entry9.sizeof == 16);
|
||||
|
||||
Acpi.Header header;
|
||||
uint local_apic_address;
|
||||
uint flags;
|
||||
|
||||
static assert(MADT.sizeof == 0x2C);
|
||||
|
||||
/**
|
||||
* Scan the MADT table.
|
||||
*/
|
||||
@ -46,14 +144,99 @@ struct Apic
|
||||
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);
|
||||
bool first_io_apic = true;
|
||||
size_t n_cpus = 0u;
|
||||
while (entry < end)
|
||||
{
|
||||
entry = cast(const(Entry) *)(cast(size_t)entry + entry.length);
|
||||
if (entry.type == Entry.LOCAL_APIC_ADDRESS_OVERRIDE)
|
||||
if (DEBUG)
|
||||
{
|
||||
/* Found a 64-bit Local APIC Address Override entry. */
|
||||
memcpy(cast(void *)&apic_registers, cast(const(void) *)entry + 4u, apic_registers.sizeof);
|
||||
Klog.writefln("MADT entry type %u, length %u", entry.type, entry.length);
|
||||
}
|
||||
switch (entry.type)
|
||||
{
|
||||
case Entry.PROCESSOR_LOCAL_APIC:
|
||||
Entry0 * e = cast(Entry0 *)entry;
|
||||
n_cpus++;
|
||||
if (DEBUG)
|
||||
{
|
||||
Klog.writefln(" ACPI processor ID: %u, APIC ID: %u, Flags: 0x%x",
|
||||
e.acpi_processor_id, e.apic_id, e.flags);
|
||||
}
|
||||
break;
|
||||
|
||||
case Entry.IO_APIC:
|
||||
Entry1 * e = cast(Entry1 *)entry;
|
||||
if (first_io_apic)
|
||||
{
|
||||
io_apic_registers = cast(IoApicRegisters *)e.io_apic_address;
|
||||
first_io_apic = false;
|
||||
}
|
||||
if (DEBUG)
|
||||
{
|
||||
Klog.writefln(" I/O APIC ID: %u, I/O APIC Address: 0x%x, GSIB: %u",
|
||||
e.io_apic_id, e.io_apic_address, e.global_system_interrupt_base);
|
||||
}
|
||||
break;
|
||||
|
||||
case Entry.IO_APIC_INTERRUPT_SOURCE_OVERRIDE:
|
||||
Entry2 * e = cast(Entry2 *)entry;
|
||||
if (DEBUG)
|
||||
{
|
||||
Klog.writefln(" Bus %u IRQ %u GSI %u Flags: 0x%x",
|
||||
e.bus_source, e.irq_source, e.global_system_interrupt, e.flags);
|
||||
}
|
||||
break;
|
||||
|
||||
case Entry.IO_APIC_NMI_SOURCE:
|
||||
Entry3 * e = cast(Entry3 *)entry;
|
||||
if (DEBUG)
|
||||
{
|
||||
uint global_system_interrupt;
|
||||
memcpy(&global_system_interrupt, &e.global_system_interrupt, 4u);
|
||||
Klog.writefln(" NMI Source: %u, Flags: 0x%x, GSI: %u",
|
||||
e.nmi_source, e.flags, global_system_interrupt);
|
||||
}
|
||||
break;
|
||||
|
||||
case Entry.LOCAL_APIC_NMI:
|
||||
Entry4 * e = cast(Entry4 *)entry;
|
||||
if (DEBUG)
|
||||
{
|
||||
ushort flags;
|
||||
memcpy(&flags, &e.flags, 2u);
|
||||
Klog.writefln(" ACPI Processor ID: %u, Flags: 0x%x, LINT#: %u",
|
||||
e.acpi_processor_id, flags, e.lint_nr);
|
||||
}
|
||||
break;
|
||||
|
||||
case Entry.LOCAL_APIC_ADDRESS_OVERRIDE:
|
||||
Entry5 * e = cast(Entry5 *)entry;
|
||||
if (DEBUG)
|
||||
{
|
||||
memcpy(&apic_registers, &e.local_apic_address, 8u);
|
||||
Klog.writefln(" Local APIC Address: 0x%x", apic_registers);
|
||||
}
|
||||
break;
|
||||
|
||||
case Entry.PROCESSOR_LOCAL_X2APIC:
|
||||
Entry9 * e = cast(Entry9 *)entry;
|
||||
if (DEBUG)
|
||||
{
|
||||
Klog.writefln(" x2APIC ID: %u, Flags: 0x%x, ACPI ID: %u",
|
||||
e.local_x2apic_id, e.flags, e.acpi_id);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Move to next entry. */
|
||||
entry = cast(const(Entry) *)(cast(size_t)entry + entry.length);
|
||||
}
|
||||
if (n_cpus > 0u)
|
||||
{
|
||||
Klog.writefln("%u CPU(s) found", n_cpus);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -122,7 +305,7 @@ struct Apic
|
||||
public static void initialize()
|
||||
{
|
||||
Klog.writefln("\a3Initializing APIC");
|
||||
io_apic_registers = cast(IoApicRegisters *)0xFEC0_0000u;
|
||||
io_apic_registers = cast(IoApicRegisters *)DEFAULT_IO_APIC_ADDRESS;
|
||||
MADT * madt = cast(MADT *)Acpi.get_table("APIC");
|
||||
madt.scan();
|
||||
Klog.writefln("APIC found at %p", apic_registers);
|
||||
|
Loading…
x
Reference in New Issue
Block a user