Compare commits
No commits in common. "7264a31ff3387682277196d79cfa10191848d5b5" and "9f8a4ea10074d330593e885f99c64e667279ab85" have entirely different histories.
7264a31ff3
...
9f8a4ea100
@ -199,7 +199,6 @@ task "run", desc: "Run HOS in QEMU" do
|
|||||||
qemu-system-x86_64
|
qemu-system-x86_64
|
||||||
-machine q35
|
-machine q35
|
||||||
-cpu max
|
-cpu max
|
||||||
-smp cpus=4
|
|
||||||
-serial file:qemu/serial.out
|
-serial file:qemu/serial.out
|
||||||
-bios #{ovmf}
|
-bios #{ovmf}
|
||||||
-drive file=qemu/HOS.img,format=raw
|
-drive file=qemu/HOS.img,format=raw
|
||||||
|
195
src/hulk/apic.d
195
src/hulk/apic.d
@ -13,8 +13,6 @@ import hulk.memory;
|
|||||||
|
|
||||||
struct Apic
|
struct Apic
|
||||||
{
|
{
|
||||||
private enum DEBUG = false;
|
|
||||||
private enum DEFAULT_IO_APIC_ADDRESS = 0xFEC0_0000u;
|
|
||||||
private enum uint PERIODIC_MODE = 0x2_0000u;
|
private enum uint PERIODIC_MODE = 0x2_0000u;
|
||||||
|
|
||||||
private enum ulong IRQ_PIT = 2u;
|
private enum ulong IRQ_PIT = 2u;
|
||||||
@ -30,112 +28,16 @@ struct Apic
|
|||||||
*/
|
*/
|
||||||
static struct Entry
|
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 LOCAL_APIC_ADDRESS_OVERRIDE = 5;
|
||||||
enum PROCESSOR_LOCAL_X2APIC = 9;
|
|
||||||
|
|
||||||
ubyte type;
|
ubyte type;
|
||||||
ubyte length;
|
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;
|
Acpi.Header header;
|
||||||
uint local_apic_address;
|
uint local_apic_address;
|
||||||
uint flags;
|
uint flags;
|
||||||
|
|
||||||
static assert(MADT.sizeof == 0x2C);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scan the MADT table.
|
* Scan the MADT table.
|
||||||
*/
|
*/
|
||||||
@ -144,99 +46,14 @@ struct Apic
|
|||||||
apic_registers = cast(ApicRegisters *)local_apic_address;
|
apic_registers = cast(ApicRegisters *)local_apic_address;
|
||||||
const(void) * end = cast(const(void) *)(&this) + header.length;
|
const(void) * end = cast(const(void) *)(&this) + header.length;
|
||||||
const(Entry) * entry = cast(const(Entry) *)(cast(ulong)&this + MADT.sizeof);
|
const(Entry) * entry = cast(const(Entry) *)(cast(ulong)&this + MADT.sizeof);
|
||||||
bool first_io_apic = true;
|
|
||||||
size_t n_cpus = 0u;
|
|
||||||
while (entry < end)
|
while (entry < end)
|
||||||
{
|
{
|
||||||
if (DEBUG)
|
|
||||||
{
|
|
||||||
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);
|
entry = cast(const(Entry) *)(cast(size_t)entry + entry.length);
|
||||||
}
|
if (entry.type == Entry.LOCAL_APIC_ADDRESS_OVERRIDE)
|
||||||
if (n_cpus > 0u)
|
{
|
||||||
{
|
/* Found a 64-bit Local APIC Address Override entry. */
|
||||||
Klog.writefln("%u CPU(s) found", n_cpus);
|
memcpy(cast(void *)&apic_registers, cast(const(void) *)entry + 4u, apic_registers.sizeof);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -305,7 +122,7 @@ struct Apic
|
|||||||
public static void initialize()
|
public static void initialize()
|
||||||
{
|
{
|
||||||
Klog.writefln("\a3Initializing APIC");
|
Klog.writefln("\a3Initializing APIC");
|
||||||
io_apic_registers = cast(IoApicRegisters *)DEFAULT_IO_APIC_ADDRESS;
|
io_apic_registers = cast(IoApicRegisters *)0xFEC0_0000u;
|
||||||
MADT * madt = cast(MADT *)Acpi.get_table("APIC");
|
MADT * madt = cast(MADT *)Acpi.get_table("APIC");
|
||||||
madt.scan();
|
madt.scan();
|
||||||
Klog.writefln("APIC found at %p", apic_registers);
|
Klog.writefln("APIC found at %p", apic_registers);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user