diff --git a/arch/x86_64/acpi/io_apic.cpp b/arch/x86_64/acpi/io_apic.cpp index 98498df..c5f28e1 100644 --- a/arch/x86_64/acpi/io_apic.cpp +++ b/arch/x86_64/acpi/io_apic.cpp @@ -8,58 +8,58 @@ #define IOAPICREDTBL(n) (0x10 + 2 * n) namespace arch::acpi { - io_apic::io_apic(uint32_t *base, unsigned int first_irq) : io_base(base), io_first_irq(first_irq) - { - io_nr_irq = ((read(IOAPICVER) >> 16) + 1) & 0xFF; - } - - uint32_t io_apic::read(uint32_t reg) - { - *(volatile uint32_t *)(io_base) = reg & 0xFF; - return *(volatile uint32_t *)((char *)io_base + 0x10); - } - - void io_apic::write(uint32_t reg, uint32_t val) - { - *(volatile uint32_t *)(io_base) = reg & 0xFF; - *(volatile uint32_t *)((char *)io_base + 0x10) = val; - } - - kern_status_t io_apic::read_irq(unsigned int index, irq_entry &entry) - { - if (index >= io_nr_irq) { - return KERN_NO_ENTRY; - } - - uint32_t *entry_data = (uint32_t *)&entry; - entry_data[0] = read(IOAPICREDTBL(index)); - entry_data[1] = read(IOAPICREDTBL(index) + 1); - - return KERN_OK; - } - - void io_apic::write_irq(unsigned int index, const irq_entry &entry) - { - if (index >= io_nr_irq) { - return; - } - - const uint32_t *entry_data = (const uint32_t *)&entry; - write(IOAPICREDTBL(index), entry_data[0]); - write(IOAPICREDTBL(index) + 1, entry_data[1]); - } - - void io_apic::map_irq(unsigned int src, unsigned int dest) - { - io_apic::irq_entry irq{}; - irq.irq_vec = dest; - irq.irq_delivery = 0; - irq.irq_destmode = 0; - irq.irq_polarity = 0; - irq.irq_triggermode = 0; - irq.irq_mask = 0; - irq.irq_dest = 0; - - write_irq(src, irq); - } +io_apic::io_apic(uint32_t *base, unsigned int first_irq) : io_base(base), io_first_irq(first_irq) +{ + io_nr_irq = ((read(IOAPICVER) >> 16) + 1) & 0xFF; +} + +uint32_t io_apic::read(uint32_t reg) +{ + write_once(io_base, reg & 0xFF); + return read_once(io_base + 4); +} + +void io_apic::write(uint32_t reg, uint32_t val) +{ + write_once(io_base, reg & 0xFF); + write_once(io_base + 4, val); +} + +kern_status_t io_apic::read_irq(unsigned int index, irq_entry &entry) +{ + if (index >= io_nr_irq) { + return KERN_NO_ENTRY; + } + + uint32_t *entry_data = (uint32_t *)&entry; + entry_data[0] = read(IOAPICREDTBL(index)); + entry_data[1] = read(IOAPICREDTBL(index) + 1); + + return KERN_OK; +} + +void io_apic::write_irq(unsigned int index, const irq_entry &entry) +{ + if (index >= io_nr_irq) { + return; + } + + const uint32_t *entry_data = (const uint32_t *)&entry; + write(IOAPICREDTBL(index), entry_data[0]); + write(IOAPICREDTBL(index) + 1, entry_data[1]); +} + +void io_apic::map_irq(unsigned int src, unsigned int dest) +{ + io_apic::irq_entry irq{}; + irq.irq_vec = dest; + irq.irq_delivery = 0; + irq.irq_destmode = 0; + irq.irq_polarity = 0; + irq.irq_triggermode = 0; + irq.irq_mask = 0; + irq.irq_dest = 0; + + write_irq(src, irq); +} } diff --git a/arch/x86_64/acpi/local_apic.cpp b/arch/x86_64/acpi/local_apic.cpp index 159348f..87ede23 100644 --- a/arch/x86_64/acpi/local_apic.cpp +++ b/arch/x86_64/acpi/local_apic.cpp @@ -1,25 +1,26 @@ #include #include +#include #define LAPIC_REG_EOI 0xB0 namespace arch::acpi { - local_apic::local_apic(uint32_t *base) : base_(base) - { - } - - uint32_t local_apic::read(uint32_t reg) - { - return *(volatile uint32_t *)((char *)base_ + reg); - } - - void local_apic::write(uint32_t reg, uint32_t val) - { - *(volatile uint32_t *)((char *)base_ + reg) = val; - } - - void local_apic::ack() - { - *(volatile uint32_t *)((char *)base_ + LAPIC_REG_EOI) = 0; - } +local_apic::local_apic(uint32_t *base) : base_(base) +{ +} + +uint32_t local_apic::read(uint32_t reg) +{ + return read_once(base_ + (reg >> 2)); +} + +void local_apic::write(uint32_t reg, uint32_t val) +{ + write_once(base_ + (reg >> 2), val); +} + +void local_apic::ack() +{ + write(LAPIC_REG_EOI, 0); +} } diff --git a/include/socks/compiler.h b/include/socks/compiler.h index dd00c2e..f0d3308 100644 --- a/include/socks/compiler.h +++ b/include/socks/compiler.h @@ -4,6 +4,20 @@ #define READ_ONCE(t, p) (*((const volatile t *)&(p))) #define WRITE_ONCE(t, p, v) *(volatile t *)&(p) = (v) +#ifdef __cplusplus +template +T read_once(const volatile T *ptr) +{ + return *ptr; +} + +template +void write_once(volatile T *ptr, T value) +{ + *ptr = value; +} +#endif + #undef __used #define __used __attribute__((used))