diff --git a/src/hulk/acpi.d b/src/hulk/acpi.d index c893a03..1dad759 100644 --- a/src/hulk/acpi.d +++ b/src/hulk/acpi.d @@ -15,14 +15,13 @@ struct Acpi */ private static __gshared List!Header tables; - enum uint APIC_SIGNATURE = signature("APIC"); enum uint MCFG_SIGNATURE = signature("MCFG"); enum uint XSDT_SIGNATURE = signature("XSDT"); /** * ACPI table header structure. */ - static struct Header + public static struct Header { uint signature; uint length; @@ -46,37 +45,6 @@ struct Acpi } 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 { /* 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 static void initialize(ulong acpi_xsdt_phys) @@ -148,20 +112,11 @@ struct Acpi (signature >> 16u) & 0xFFu, (signature >> 24u) & 0xFFu, address); - if (signature == APIC_SIGNATURE) - { - madt = cast(MADT *)address; - madt.initialize(); - } - else if (signature == MCFG_SIGNATURE) + if (signature == MCFG_SIGNATURE) { mcfg = cast(MCFG *)address; } } - if (madt == null) - { - Klog.fatal_error("MADT table not found"); - } if (mcfg == null) { Klog.fatal_error("MCFG table not found"); @@ -174,14 +129,14 @@ struct Acpi * @param name * Table name. */ - public Header * get_table(string name) + public static Header * get_table(string name) { uint signature = signature(name); foreach (table; tables) { if (table.signature == signature) { - return &table; + return table; } } Klog.fatal_error("Could not find requested ACPI table"); diff --git a/src/hulk/apic.d b/src/hulk/apic.d index 2fa25e0..e0a7947 100644 --- a/src/hulk/apic.d +++ b/src/hulk/apic.d @@ -9,6 +9,7 @@ import hulk.idt; import hulk.rtc; import hulk.pit; import hulk.klog; +import hulk.memory; struct Apic { @@ -17,6 +18,49 @@ struct Apic private enum ulong IRQ_PIT = 2u; 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 { public uint value; @@ -25,6 +69,9 @@ struct Apic private ubyte[12] _padding; } + /** + * APIC registers. + */ static struct ApicRegisters { ApicRegister[2] _reserved0; @@ -57,6 +104,9 @@ struct Apic ApicRegister divide_configuration; } + /** + * I/O APIC registers. + */ static struct IoApicRegisters { ApicRegister address; @@ -66,10 +116,17 @@ struct Apic private static __gshared ApicRegisters * apic_registers; private static __gshared IoApicRegisters * io_apic_registers; + /** + * Initialize APIC. + */ public static void initialize() { - apic_registers = cast(ApicRegisters *)Acpi.apic_address; + Klog.writefln("\a3Initializing APIC"); 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, PT_WRITABLE | PT_WRITE_THROUGH | PT_DISABLE_CACHE | PT_NO_EXECUTE); 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 routing for an I/O APIC IRQ. + */ private static void configure_io_apic_irq(size_t io_apic_irq, size_t interrupt_id) { ulong entry = interrupt_id; @@ -95,11 +155,17 @@ struct Apic io_apic_registers.data.value = entry >> 32u; } + /** + * Signal APIC end of interrupt. + */ public static void eoi() { apic_registers.eoi.value = 0u; } + /** + * APIC interrupt handler. + */ public static void isr(ulong vector) { switch (vector) diff --git a/src/hulk/list.d b/src/hulk/list.d index f9f9879..e3777c1 100644 --- a/src/hulk/list.d +++ b/src/hulk/list.d @@ -34,12 +34,12 @@ struct List(T) /** * 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; while (entry.next != null) { - int result = dg(*entry.item); + int result = dg(entry.item); if (result != 0) { return result; diff --git a/src/hulk/usb/usb.d b/src/hulk/usb/usb.d index 1528911..95c9ec4 100644 --- a/src/hulk/usb/usb.d +++ b/src/hulk/usb/usb.d @@ -17,7 +17,7 @@ struct Usb { if (pci_device.type == Pci.XHCI_CONTROLLER) { - XHCI.build(&pci_device); + XHCI.build(pci_device); } } }