From 2bb4e7fb4c0f5895148bb32da64381b985c8dcef Mon Sep 17 00:00:00 2001 From: Aleksa Vuckovic Date: Thu, 16 Feb 2023 21:46:25 +0100 Subject: code refactoring --- kernel/src/apic/ioapic.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 kernel/src/apic/ioapic.c (limited to 'kernel/src/apic/ioapic.c') diff --git a/kernel/src/apic/ioapic.c b/kernel/src/apic/ioapic.c new file mode 100644 index 0000000..a8c3452 --- /dev/null +++ b/kernel/src/apic/ioapic.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include + +void ioapic_eoi() +{ + *((volatile uint32_t*)((uint64_t)lapic_addr + 0xB0)) = 0; +} + +uint32_t ioapic_read(const uint8_t offset) +{ + /* tell IOREGSEL where we want to read from */ + *(volatile uint32_t*)(uint64_t)ioapic_addr = offset; + /* return the data from IOWIN */ + return *(volatile uint32_t*)((uint64_t)ioapic_addr + 0x10); +} + +void ioapic_write(const uint8_t offset, const uint32_t val) +{ + /* tell IOREGSEL where we want to write to */ + *(volatile uint32_t*)(uint64_t)ioapic_addr = offset; + /* write the value to IOWIN */ + *(volatile uint32_t*)((uint64_t)ioapic_addr + 0x10) = val; +} + +void ioapic_set_irq(uint8_t irq, uint64_t apic_id, uint8_t vector) +{ + const uint32_t low_index = (uint32_t)0x10 + irq*2; + const uint32_t high_index = (uint32_t)0x10 + irq*2 + 1; + + uint32_t high = ioapic_read((uint8_t)high_index); + // set APIC ID + high &= (uint32_t)~0xff000000; + high |= (uint32_t)apic_id << 24; + ioapic_write((uint8_t)high_index, high); + + uint32_t low = ioapic_read((uint8_t)low_index); + + // unmask the IRQ + low &= (uint32_t)~(1<<16); + + // set to physical delivery mode + low &= (uint32_t)~(1<<11); + + // set to fixed delivery mode + low &= (uint32_t)~0x700; + + // set delivery vector + low &= (uint32_t)~0xff; + low |= vector; + + ioapic_write((uint8_t)low_index, low); +} + +void apic_remap_interrupts() +{ + uint8_t bspid = curr_cpu_apic_id(); + + map_addr(ioapic_addr, ioapic_addr, FLAG_PRESENT); + map_addr(lapic_addr, lapic_addr, FLAG_PRESENT); + + // irq is 2 because of gsi remap + ioapic_set_irq(0x2, bspid, 0x20); // timer + ioapic_set_irq(0x1, bspid, 0x21); // keyboard + __asm__ volatile ("sti;"); +} -- cgit v1.2.3