X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/fef29e9e993e62f025d8cbfeb6b8d51588083b7e..4f966b9a6710d138d6e921bf2a1e40f2abc76f9a:/lunaix-os/hal/apic.c diff --git a/lunaix-os/hal/apic.c b/lunaix-os/hal/apic.c index 32bfed5..0099525 100644 --- a/lunaix-os/hal/apic.c +++ b/lunaix-os/hal/apic.c @@ -15,13 +15,13 @@ #include +#include #include #include LOG_MODULE("APIC") -void -apic_setup_timer(); +static volatile uintptr_t _apic_base; void apic_setup_lvts(); @@ -39,53 +39,55 @@ apic_init() // As we are going to use APIC, disable the old 8259 PIC pic_disable(); + _apic_base = 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) - asm volatile ( - "movl %0, %%ecx\n" - "rdmsr\n" - "orl %1, %%eax\n" - "wrmsr\n" - ::"i"(IA32_APIC_BASE_MSR), "i"(IA32_APIC_ENABLE) - : "eax", "ecx", "edx" - ); + // 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" + "wrmsr\n" ::"i"(IA32_MSR_APIC_BASE), + "i"(IA32_APIC_ENABLE) + : "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); kprintf(KINFO "ID: %x, Version: %x, Max LVT: %u\n", - apic_id, - apic_ver & 0xff, - (apic_ver >> 16) & 0xff); + apic_id, + apic_ver & 0xff, + (apic_ver >> 16) & 0xff); // initialize the local vector table (LVT) apic_setup_lvts(); // initialize priority registers - - // set the task priority to the lowest possible, so all external interrupts are acceptable - // Note, the lowest possible priority class is 2, not 0, 1, as they are reserved for - // internal interrupts (vector 0-31, and each p-class resposible for 16 vectors). - // See Intel Manual Vol. 3A, 10-29 + + // set the task priority to the lowest possible, so all external interrupts + // are acceptable + // Note, the lowest possible priority class is 2, not 0, 1, as they are + // reserved for internal interrupts (vector 0-31, and each p-class + // resposible for 16 vectors). See Intel Manual Vol. 3A, 10-29 apic_write_reg(APIC_TPR, APIC_PRIORITY(2, 0)); // enable APIC uint32_t spiv = apic_read_reg(APIC_SPIVR); // install our handler for spurious interrupt. - spiv = (spiv & ~0xff) | APIC_SPIV_APIC_ENABLE | APIC_SPIV_IV; + spiv = (spiv & ~0xff) | APIC_SPIV_APIC_ENABLE | APIC_SPIV_IV; apic_write_reg(APIC_SPIVR, spiv); } -#define LVT_ENTRY_LINT0(vector) (LVT_DELIVERY_FIXED | vector) +#define LVT_ENTRY_LINT0(vector) (LVT_DELIVERY_FIXED | vector) // Pin LINT#1 is configured for relaying NMI, but we masked it here as I think // it is too early for that // LINT#1 *must* be edge trigged (Intel manual vol3. 10-14) -#define LVT_ENTRY_LINT1 (LVT_DELIVERY_NMI | LVT_MASKED | LVT_TRIGGER_EDGE) -#define LVT_ENTRY_ERROR(vector) (LVT_DELIVERY_FIXED | vector) +#define LVT_ENTRY_LINT1 (LVT_DELIVERY_NMI | LVT_MASKED | LVT_TRIGGER_EDGE) +#define LVT_ENTRY_ERROR(vector) (LVT_DELIVERY_FIXED | vector) void apic_setup_lvts() @@ -94,3 +96,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