diff options
author | Anton Kling <anton@kling.gg> | 2024-02-21 20:06:35 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-02-21 20:06:35 +0100 |
commit | 9b475d3db3275d4c34f02161ae70ced5595a0fdb (patch) | |
tree | 0c50e4af3ce52017f295c44f6f4319e4a43de085 /kernel/cpu | |
parent | 6c9cb0bd8ceb039ce387c850e25adc6f99cfcd6f (diff) |
Kernel: Remove all inline assembly.
Now the kernel does not rely upon inline assembly which is often very
error prone. This also means that the kernel could probably be compiled
with any c99 compiler which would help future bootstrapping.
Diffstat (limited to 'kernel/cpu')
-rw-r--r-- | kernel/cpu/arch_inst.h | 11 | ||||
-rw-r--r-- | kernel/cpu/arch_inst.s | 60 | ||||
-rw-r--r-- | kernel/cpu/gdt.c | 4 | ||||
-rw-r--r-- | kernel/cpu/idt.c | 19 |
4 files changed, 80 insertions, 14 deletions
diff --git a/kernel/cpu/arch_inst.h b/kernel/cpu/arch_inst.h new file mode 100644 index 0000000..54faffb --- /dev/null +++ b/kernel/cpu/arch_inst.h @@ -0,0 +1,11 @@ +#include <stdint.h> +uintptr_t get_current_sp(void); +uintptr_t get_current_sbp(void); +__attribute__((__noreturn__)) void halt(void); +uintptr_t get_cr2(void); +void flush_tlb(void); +void set_sp(uintptr_t); +void set_sbp(uintptr_t); +void set_cr3(uintptr_t); +uintptr_t get_cr3(void); +void enable_paging(void); diff --git a/kernel/cpu/arch_inst.s b/kernel/cpu/arch_inst.s new file mode 100644 index 0000000..aaf34b6 --- /dev/null +++ b/kernel/cpu/arch_inst.s @@ -0,0 +1,60 @@ +.intel_syntax noprefix +.global get_current_sp +.global get_current_sbp +.global halt +.global get_cr2 +.global set_sp +.global set_sbp +.global flush_tlb +.global set_cr3 +.global get_cr3 +.global enable_paging + +get_current_sp: + mov eax, esp + sub eax, 4 + ret + +get_current_sbp: + mov eax, ebp + ret + +set_sp: + mov ecx, [esp] # store the return address in ecx + mov eax, [esp + 4] + mov esp, eax + jmp ecx # jump to the return address instead of doing a ret as the stack values may have changed + +set_sbp: + mov eax, [esp + 4] + mov ebp, eax + ret + +halt: + hlt + jmp $ + ret + +get_cr2: + mov eax, cr2 + ret + +flush_tlb: + mov eax, cr3 + mov cr3, eax + ret + +set_cr3: + mov eax, [esp + 4] + mov cr3, eax + ret + +get_cr3: + mov eax, cr3 + ret + +enable_paging: + mov eax, cr0 + or eax, 0b10000000000000000000000000000000 + mov cr0, eax + ret diff --git a/kernel/cpu/gdt.c b/kernel/cpu/gdt.c index 2f9f90b..d91abed 100644 --- a/kernel/cpu/gdt.c +++ b/kernel/cpu/gdt.c @@ -1,4 +1,5 @@ #include "gdt.h" +#include <cpu/arch_inst.h> #include <interrupts.h> extern void flush_tss(void); @@ -39,8 +40,7 @@ void write_tss(struct GDT_Entry *gdt_entry) { memset(&tss_entry, 0, sizeof tss_entry); tss_entry.ss0 = GDT_KERNEL_DATA_SEGMENT * GDT_ENTRY_SIZE; - register u32 esp asm("esp"); - tss_entry.esp0 = esp; + tss_entry.esp0 = get_current_sp(); } void gdt_init() { diff --git a/kernel/cpu/idt.c b/kernel/cpu/idt.c index 3d866e5..ec7ca63 100644 --- a/kernel/cpu/idt.c +++ b/kernel/cpu/idt.c @@ -1,4 +1,6 @@ +#include <cpu/arch_inst.h> #include <cpu/idt.h> +#include <interrupts.h> #include <sched/scheduler.h> #include <stdio.h> @@ -52,25 +54,20 @@ void general_protection_fault(reg_t *regs) { kprintf(" Error Code: %x\n", regs->error_code); kprintf("Instruction Pointer: %x\n", regs->eip); dump_backtrace(12); - asm("hlt"); - for (;;) - ; + halt(); EOI(0xD - 8); } void double_fault(registers_t *regs) { (void)regs; klog("DOUBLE FAULT", LOG_ERROR); - asm("hlt"); - for (;;) - ; + halt(); } void page_fault(reg_t *regs) { - volatile uint32_t cr2; - asm volatile("mov %%cr2, %0" : "=r"(cr2)); + uint32_t cr2 = get_cr2(); if (0xDEADC0DE == cr2) { - asm("cli"); + disable_interrupts(); EOI(0xB); process_pop_restore_context(NULL, regs); return; @@ -105,9 +102,7 @@ void page_fault(reg_t *regs) { } dump_backtrace(12); - asm("hlt"); - for (;;) - ; + halt(); } static inline void io_wait(void) { |