From aa11d25fa8768214e1cd1fd48a0fe3caa490d27f Mon Sep 17 00:00:00 2001 From: Edgaru089 Date: Thu, 14 Oct 2021 15:51:50 +0800 Subject: [PATCH] interrupt: load GDT/IDT on the stack We have to use a separate Assembly function to do that, but maybe with some effort we can make that inline too --- interrupt/init.c | 21 +++------------------ interrupt/interrupt.h | 10 ++-------- interrupt/load_gdt.S | 29 +++++++++++++++++++++++++++++ memory/memory.h | 7 ++----- 4 files changed, 36 insertions(+), 31 deletions(-) diff --git a/interrupt/init.c b/interrupt/init.c index 0b4e0ea..903c3e9 100644 --- a/interrupt/init.c +++ b/interrupt/init.c @@ -36,16 +36,9 @@ void interrupt_Init() { assert(sizeof(interrupt_DescriptorTableReference) == 10 && "GDTR/IDTR size must be 10 bytes"); assert(offsetof(interrupt_DescriptorTableReference, base) == 2 && "GDTR/IDTR must be packed"); - assert(KERNEL_IDTR_MAPPING % 4 == 0 && "IDTR not aligned to 4-byte"); - assert(KERNEL_GDTR_MAPPING % 4 == 0 && "GDTR not aligned to 4-byte"); - // allocate GDTR io_WriteConsoleASCII("interrupt_Init() calling\n"); - interrupt_GDTR = (interrupt_DescriptorTableReference *)KERNEL_GDTR_MAPPING; - interrupt_GDTR->length = 4 * GDT_SIZE_BYTES - 1; - interrupt_GDTR->base = (void *)KERNEL_GDT_MAPPING; - io_WriteConsoleASCII("GDTR Written\n"); // set the 2 dummy gdts uint64_t *gdt = (uint64_t *)KERNEL_GDT_MAPPING; @@ -56,20 +49,13 @@ void interrupt_Init() { gdt[4] = GDT_DATA_RING3; io_WriteConsoleASCII("GDT Installed\n"); - interrupt_LoadGDT(interrupt_GDTR); // set it! + interrupt_LoadGDT(4 * GDT_SIZE_BYTES - 1, (void *)KERNEL_GDT_MAPPING); // set it! io_WriteConsoleASCII("GDT OK\n"); //interrupt_Testcode(); io_WriteConsoleASCII("Testcode OK\n"); - // allocate IDTR - //interrupt_IDTR = kMalloc(sizeof(interrupt_DescriptorTableReference)); - interrupt_IDTR = (interrupt_DescriptorTableReference *)KERNEL_IDTR_MAPPING; - interrupt_IDTR->length = KERNEL_IDT_SIZE - 1; - interrupt_IDTR->base = (void *)KERNEL_IDT_MAPPING; - io_WriteConsoleASCII("IDT Written\n"); - interrupt_MapHandler(interrupt_Int0, 0); interrupt_MapHandler(interrupt_Int1, 1); interrupt_MapHandler(interrupt_Int2, 2); @@ -105,11 +91,10 @@ void interrupt_Init() { interrupt_MapHandler(interrupt_Int128, 128); io_WriteConsoleASCII("IDT Installed\n"); - interrupt_LoadIDT(interrupt_IDTR); // set it! - - + interrupt_LoadIDT(KERNEL_IDT_SIZE - 1, (void *)KERNEL_IDT_MAPPING); // set it! io_WriteConsoleASCII("IDT OK\n"); + interrupt_Enabled = true; asm volatile("sti"); diff --git a/interrupt/interrupt.h b/interrupt/interrupt.h index 335272d..7f2e5d3 100644 --- a/interrupt/interrupt.h +++ b/interrupt/interrupt.h @@ -53,14 +53,8 @@ SYSV_ABI void interrupt_Handler(int vec, int errcode, uint64_t rip, uint64_t rax // defined in assembly SYSV_ABI void interrupt_ReloadSegments(); -inline void interrupt_LoadGDT(interrupt_DescriptorTableReference *gdtr) { - asm volatile("lgdt %0" - : "=m"(*gdtr)); -} -inline void interrupt_LoadIDT(interrupt_DescriptorTableReference *idtr) { - asm volatile("lidt %0" - : "=m"(*idtr)); -} +SYSV_ABI void interrupt_LoadGDT(uint16_t length_sub1, void *base_ptr); +SYSV_ABI void interrupt_LoadIDT(uint16_t length_sub1, void *base_ptr); #define INTERRUPT_DISABLE \ diff --git a/interrupt/load_gdt.S b/interrupt/load_gdt.S index 8f549a6..09d12bc 100644 --- a/interrupt/load_gdt.S +++ b/interrupt/load_gdt.S @@ -1,6 +1,8 @@ format elf64 public interrupt_ReloadSegments +public interrupt_LoadGDT +public interrupt_LoadIDT section '.text' executable @@ -25,3 +27,30 @@ interrupt_ReloadSegments: push rax retfq +; sysvx64call void interrupt_LoadGDT(uint16_t length_sub1, void* base_ptr) +; +; Input: (uint16_t di, void* rsi) +; Clobbers: rax, flags +interrupt_LoadGDT: + mov rax, rsp ; save old RSP + sub rsp, 10 + and rsp, 0xfffffffffffffffc ; align RSP to 4-byte + mov [rsp], di + mov [rsp+2], rsi + lgdt [rsp] + mov rsp, rax ; restore old RSP + ret + +; sysvx64call void interrupt_LoadIDT(uint16_t length_sub1, void* base_ptr) +; +; Input: (uint16_t di, void* rsi) +; Clobbers: rax, flags +interrupt_LoadIDT: + mov rax, rsp ; save old RSP + sub rsp, 10 + and rsp, 0xfffffffffffffffc ; align RSP to 4-byte + mov [rsp], di + mov [rsp+2], rsi + lidt [rsp] + mov rsp, rax ; restore old RSP + ret diff --git a/memory/memory.h b/memory/memory.h index 87f7d78..9af73ea 100644 --- a/memory/memory.h +++ b/memory/memory.h @@ -21,12 +21,9 @@ extern "C" { #define KERNEL_GDT_MAPPING (KERNEL_MISC_MAPPING + KERNEL_IDT_SIZE) #define KERNEL_GDT_SIZE (16ull * 8) -#define KERNEL_IDTR_MAPPING (KERNEL_MISC_MAPPING + KERNEL_IDT_SIZE + KERNEL_GDT_SIZE) -#define KERNEL_GDTR_MAPPING (KERNEL_MISC_MAPPING + KERNEL_IDT_SIZE + KERNEL_GDT_SIZE + 12) +#define KERNEL_MISC_NEXT (KERNEL_MISC_MAPPING + KERNEL_IDT_SIZE + KERNEL_GDT_SIZE) -#define KERNEL_MISC_NEXT (KERNEL_MISC_MAPPING + KERNEL_IDT_SIZE + KERNEL_GDT_SIZE + 24) - -#define KERNEL_MISC_SIZE (KERNEL_IDT_SIZE + KERNEL_GDT_SIZE + 24) // add all the misc sizes +#define KERNEL_MISC_SIZE (KERNEL_IDT_SIZE + KERNEL_GDT_SIZE) // add all the misc sizes extern uint64_t paging_LoaderCodeAddress, paging_LoaderCodeSize; // physical address for loader code section