refactor: decouple i386 specific instruction invocation
[lunaix-os.git] / lunaix-os / hal / apic.c
index 289dd564b7fd9b3a0a340facdee7ed1b4d769e33..29794eb11d74e715ecd663506d2d10fb77c8c422 100644 (file)
 #include <hal/pic.h>
 #include <hal/rtc.h>
 
-#include <arch/x86/interrupts.h>
+#include <arch/i386/interrupts.h>
 
+#include <lunaix/mm/mmio.h>
 #include <lunaix/spike.h>
 #include <lunaix/syslog.h>
 
 LOG_MODULE("APIC")
 
+static volatile uintptr_t _apic_base;
+
 void
 apic_setup_lvts();
 
@@ -31,15 +34,19 @@ apic_init()
 
     // Make sure the APIC is there
     //  FUTURE: Use 8259 as fallback
-    assert_msg(cpu_has_apic(), "No APIC detected!");
+
+    // FIXME apic abstraction as local interrupt controller
+    // assert_msg(cpu_has_apic(), "No APIC detected!");
 
     // As we are going to use APIC, disable the old 8259 PIC
     pic_disable();
 
+    _apic_base = (ptr_t)ioremap(__APIC_BASE_PADDR, 4096);
+
     // Hardware enable the APIC
     // By setting bit 11 of IA32_APIC_BASE register
-    // Note: After this point, you can't disable then re-enable it until a reset
-    // (i.e., reboot)
+    // Note: After this point, you can't disable then re-enable it until a
+    // reset (i.e., reboot)
     asm volatile("movl %0, %%ecx\n"
                  "rdmsr\n"
                  "orl %1, %%eax\n"
@@ -48,8 +55,8 @@ apic_init()
                  : "eax", "ecx", "edx");
 
     // Print the basic information of our current local APIC
-    uint32_t apic_id = apic_read_reg(APIC_IDR) >> 24;
-    uint32_t apic_ver = apic_read_reg(APIC_VER);
+    u32_t apic_id = apic_read_reg(APIC_IDR) >> 24;
+    u32_t apic_ver = apic_read_reg(APIC_VER);
 
     kprintf(KINFO "ID: %x, Version: %x, Max LVT: %u\n",
             apic_id,
@@ -69,7 +76,7 @@ apic_init()
     apic_write_reg(APIC_TPR, APIC_PRIORITY(2, 0));
 
     // enable APIC
-    uint32_t spiv = apic_read_reg(APIC_SPIVR);
+    u32_t spiv = apic_read_reg(APIC_SPIVR);
 
     // install our handler for spurious interrupt.
     spiv = (spiv & ~0xff) | APIC_SPIV_APIC_ENABLE | APIC_SPIV_IV;
@@ -91,3 +98,21 @@ apic_setup_lvts()
     apic_write_reg(APIC_LVT_LINT1, LVT_ENTRY_LINT1);
     apic_write_reg(APIC_LVT_ERROR, LVT_ENTRY_ERROR(APIC_ERROR_IV));
 }
+
+void
+apic_done_servicing()
+{
+    *(unsigned int*)(_apic_base + APIC_EOI) = 0;
+}
+
+unsigned int
+apic_read_reg(unsigned int reg)
+{
+    return *(unsigned int*)(_apic_base + (reg));
+}
+
+void
+apic_write_reg(unsigned int reg, unsigned int val)
+{
+    *(unsigned int*)(_apic_base + reg) = val;
+}
\ No newline at end of file