From 21b926fb7089ab3e1fc0ef505296efa113c95ada Mon Sep 17 00:00:00 2001 From: mintsuki Date: Tue, 21 Sep 2021 17:44:01 +0200 Subject: [PATCH] idt: Move flush_irq() logic to stage 3 --- stage23/sys/cpu.h | 2 +- stage23/sys/idt.c | 55 ++++++++++++++++++++++++++++++++++++++++++++ stage23/sys/idt.s2.c | 52 ----------------------------------------- 3 files changed, 56 insertions(+), 53 deletions(-) create mode 100644 stage23/sys/idt.c diff --git a/stage23/sys/cpu.h b/stage23/sys/cpu.h index 1979a158..70434cf9 100644 --- a/stage23/sys/cpu.h +++ b/stage23/sys/cpu.h @@ -160,7 +160,7 @@ inline uint64_t rdtsc(void) { return ((uint64_t)edx << 32) | eax; } -static inline void delay(uint64_t cycles) { +inline void delay(uint64_t cycles) { uint64_t next_stop = rdtsc() + cycles; while (rdtsc() < next_stop); diff --git a/stage23/sys/idt.c b/stage23/sys/idt.c new file mode 100644 index 00000000..8140219f --- /dev/null +++ b/stage23/sys/idt.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include +#include +#include + +static struct idt_entry *dummy_idt = NULL; + +__attribute__((interrupt)) +static void dummy_isr(void *p) { + (void)p; + lapic_eoi(); +} + +void init_flush_irqs(void) { + dummy_idt = ext_mem_alloc(256 * sizeof(struct idt_entry)); + + for (size_t i = 0; i < 256; i++) { + dummy_idt[i].offset_lo = (uint16_t)(uintptr_t)dummy_isr; + dummy_idt[i].type_attr = 0x8e; +#if defined (__i386__) + dummy_idt[i].selector = 0x18; + dummy_idt[i].offset_hi = (uint16_t)((uintptr_t)dummy_isr >> 16); +#elif defined (__x86_64__) + dummy_idt[i].selector = 0x28; + dummy_idt[i].offset_mid = (uint16_t)((uintptr_t)dummy_isr >> 16); + dummy_idt[i].offset_hi = (uint32_t)((uintptr_t)dummy_isr >> 32); +#endif + } +} + +void flush_irqs(void) { + struct idtr old_idt; + asm volatile ("sidt %0" : "=m"(old_idt) :: "memory"); + + struct idtr new_idt = { + 256 * sizeof(struct idt_entry) - 1, + (uintptr_t)dummy_idt + }; + asm volatile ("lidt %0" :: "m"(new_idt) : "memory"); + + // Flush the legacy PIC so we know the remaining ints come from the LAPIC + pic_flush(); + + asm volatile ("sti" ::: "memory"); + + // Delay a while to make sure we catch ALL pending IRQs + delay(10000000); + + asm volatile ("cli" ::: "memory"); + + asm volatile ("lidt %0" :: "m"(old_idt) : "memory"); +} diff --git a/stage23/sys/idt.s2.c b/stage23/sys/idt.s2.c index b8a59419..e5baf3e9 100644 --- a/stage23/sys/idt.s2.c +++ b/stage23/sys/idt.s2.c @@ -1,11 +1,7 @@ #include #include #include -#include -#include -#include #include -#include #if bios == 1 @@ -37,51 +33,3 @@ void init_idt(void) { } #endif - -static struct idt_entry *dummy_idt = NULL; - -__attribute__((interrupt)) -static void dummy_isr(void *p) { - (void)p; - lapic_eoi(); -} - -void init_flush_irqs(void) { - dummy_idt = ext_mem_alloc(256 * sizeof(struct idt_entry)); - - for (size_t i = 0; i < 256; i++) { - dummy_idt[i].offset_lo = (uint16_t)(uintptr_t)dummy_isr; - dummy_idt[i].type_attr = 0x8e; -#if defined (__i386__) - dummy_idt[i].selector = 0x18; - dummy_idt[i].offset_hi = (uint16_t)((uintptr_t)dummy_isr >> 16); -#elif defined (__x86_64__) - dummy_idt[i].selector = 0x28; - dummy_idt[i].offset_mid = (uint16_t)((uintptr_t)dummy_isr >> 16); - dummy_idt[i].offset_hi = (uint32_t)((uintptr_t)dummy_isr >> 32); -#endif - } -} - -void flush_irqs(void) { - struct idtr old_idt; - asm volatile ("sidt %0" : "=m"(old_idt) :: "memory"); - - struct idtr new_idt = { - 256 * sizeof(struct idt_entry) - 1, - (uintptr_t)dummy_idt - }; - asm volatile ("lidt %0" :: "m"(new_idt) : "memory"); - - // Flush the legacy PIC so we know the remaining ints come from the LAPIC - pic_flush(); - - asm volatile ("sti" ::: "memory"); - - // Delay a while to make sure we catch ALL pending IRQs - delay(10000000); - - asm volatile ("cli" ::: "memory"); - - asm volatile ("lidt %0" :: "m"(old_idt) : "memory"); -}