diff options
author | Jon Santmyer <jon@jonsantmyer.com> | 2025-09-26 13:17:41 -0400 |
---|---|---|
committer | Jon Santmyer <jon@jonsantmyer.com> | 2025-09-26 13:17:41 -0400 |
commit | 2dadbfc899df4179ca70c4ea04f74a5e190c2ae7 (patch) | |
tree | b166aaa9af42406cd07fbaf150f93aefeb2fbe33 /arch | |
parent | ddc4fbc15223e362896a9f42beca73f05f48e664 (diff) | |
download | jove-kernel-2dadbfc899df4179ca70c4ea04f74a5e190c2ae7.tar.gz jove-kernel-2dadbfc899df4179ca70c4ea04f74a5e190c2ae7.tar.bz2 jove-kernel-2dadbfc899df4179ca70c4ea04f74a5e190c2ae7.zip |
fix usermode interrupts. add ability to define custom interrupt handlersmain
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86_64/device/processor.c | 4 | ||||
-rw-r--r-- | arch/x86_64/gdt.c | 16 | ||||
-rw-r--r-- | arch/x86_64/idt.c | 16 | ||||
-rw-r--r-- | arch/x86_64/init.c | 2 | ||||
-rw-r--r-- | arch/x86_64/ivt.s | 21 | ||||
-rw-r--r-- | arch/x86_64/lgdt.s | 4 | ||||
-rw-r--r-- | arch/x86_64/memory/pml4.c | 24 | ||||
-rw-r--r-- | arch/x86_64/panic.c | 3 | ||||
-rw-r--r-- | arch/x86_64/syscall/invoke-mapping.c | 11 | ||||
-rw-r--r-- | arch/x86_64/syscall/syscall.c | 24 | ||||
-rw-r--r-- | arch/x86_64/tasking/tcb.c | 6 | ||||
-rw-r--r-- | arch/x86_64/usermode.c | 1 |
12 files changed, 93 insertions, 39 deletions
diff --git a/arch/x86_64/device/processor.c b/arch/x86_64/device/processor.c index ff920c8..1b3daa2 100644 --- a/arch/x86_64/device/processor.c +++ b/arch/x86_64/device/processor.c @@ -44,7 +44,7 @@ typedef union msr_star uint32_t eip; uint16_t kcs; uint16_t ucs; - }; + }__attribute__((packed)); uint32_t v[2]; } msr_star_t; @@ -65,7 +65,7 @@ s_enable_sce(void) msr_star_t star; star.kcs = GDT_OFFSET_KERNEL_CODE; - star.ucs = GDT_OFFSET_USER_CODE; + star.ucs = GDT_OFFSET_USER_NULL; wrmsr(MSR_STAR, star.v[0], star.v[1]); extern void _syscall_entry(void); diff --git a/arch/x86_64/gdt.c b/arch/x86_64/gdt.c index 3756d21..9c172d2 100644 --- a/arch/x86_64/gdt.c +++ b/arch/x86_64/gdt.c @@ -57,9 +57,7 @@ static segment_descriptor_t s_gdt[] = { .limit_0_15 = 0, .base_0_15 = 0, .base_16_23 = 0, - .type_flags = GDT_SEGMENT_TYPE_TSS_AVAIL | - GDT_SEGMENT_FLAG_DPL(0) | - GDT_SEGMENT_FLAG_P, + .type_flags = 0x89, .limit_16_19_avlx = 0, .base_24_31 = 0 }, @@ -71,29 +69,25 @@ void gdt_setup(processor_t *processor) { size_t gdtw = GDT_ENTRY_COUNT * sizeof(segment_descriptor_t); - klogf("%X\n", gdtw); memcpy(processor->gdt, &s_gdt, gdtw); - processor->gdtr.base = (uintptr_t)&s_gdt; + processor->gdtr.base = (uintptr_t)&processor->gdt; processor->gdtr.length = gdtw - 1; segment_descriptor_t *tss_lo = &processor->gdt[GDT_ENTRY_TSS_LOW]; segment_descriptor_t *tss_hi = &processor->gdt[GDT_ENTRY_TSS_HIGH]; uintptr_t tssb = (uintptr_t)&processor->tss; - size_t tssl = sizeof(tss_t); + size_t tssl = sizeof(tss_t) - 1; tss_lo->limit_0_15 = tssl & 0xFF; tss_lo->base_0_15 = tssb & 0xFFFF; tss_lo->base_16_23 = (tssb >> 16) & 0xFF; tss_lo->base_24_31 = (tssb >> 24) & 0xFF; - tss_hi->limit_0_15 = (tssb >> 32) & 0xFFFF; - tss_hi->base_0_15 = (tssb >> 48) & 0xFFFF; - - tss_lo->limit_16_19_avlx = (tssl >> 16) & 0xF; + *(uint32_t*)tss_hi = (tssb >> 32) & 0xFFFFFFFF; processor->tss.iopb = tssl; - + extern void gdt_load(void*); gdt_load(&processor->gdtr); diff --git a/arch/x86_64/idt.c b/arch/x86_64/idt.c index 1080f92..2eebf41 100644 --- a/arch/x86_64/idt.c +++ b/arch/x86_64/idt.c @@ -1,12 +1,20 @@ #include "arch/x86_64/tables.h" #include "arch/x86_64/idt.h" +#include "print.h" __attribute__((aligned(0x10))) -interrupt_gate_t s_idtd[256]; +static interrupt_gate_t s_idtd[256]; + +kernel_isr_handler_t kernel_isr_handles[256]; void isr_handle(ivt_state_t* state) { + kernel_isr_handler_t kernel_handle = kernel_isr_handles[state->num]; + if(kernel_handle) { + kernel_handle(state); + return; + } kpanic_state(state, "Unhandled interrupt %i", state->num); } @@ -34,6 +42,8 @@ idt_setup(processor_t *processor) processor->idtr.base = (uintptr_t)&s_idtd; processor->idtr.length = sizeof(s_idtd) - 1; - extern void idt_load(void* idtr); - idt_load(&processor->idtr); + klogf("%X\n", s_idtd[0].type_flags); + + __asm__ volatile("lidt %0":: "m"(processor->idtr)); + __asm__ volatile("cli"); } diff --git a/arch/x86_64/init.c b/arch/x86_64/init.c index 7a2f67d..9e32898 100644 --- a/arch/x86_64/init.c +++ b/arch/x86_64/init.c @@ -1,6 +1,7 @@ #include "init.h" #include "bootargs.h" #include "device/initrd.h" +#include "api/init.h" #include "arch/x86_64/page.h" #include "arch/x86_64/processor.h" #include "device/processor.h" @@ -180,5 +181,6 @@ init_load(void) extern tcb_t *_init_tcb; _init_tcb->sp = (uintptr_t)usermode_sp; + extern void usermode(void*, void*); usermode((void*)init_ehdr->e_entry, usermode_sp); } diff --git a/arch/x86_64/ivt.s b/arch/x86_64/ivt.s index a64f6b7..a1592be 100644 --- a/arch/x86_64/ivt.s +++ b/arch/x86_64/ivt.s @@ -1,14 +1,13 @@ .section .text -.global idt_load -.type idt_load @function -idt_load: - lidt (%rdi) - sti - retq -.size idt_load, . - idt_load - .include "arch/x86_64/savestate.s" +.macro swapgs_if_necessary + cmp $0x08, 0x8(%rsp) + je 1f + swapgs +1: +.endm + .extern isr_handle .type __isr_head @function __isr_head: @@ -20,14 +19,13 @@ __isr_head: popall addq $16, %rsp + swapgs_if_necessary iretq -.extern __isr_err -.extern __isr_num - .macro defn_isr_err num:req .type __isr\num @function __isr\num: + swapgs_if_necessary pushq $\num jmp __isr_head .size __isr\num, . - __isr\num @@ -36,6 +34,7 @@ __isr\num: .macro defn_isr num:req .type __isr\num @function __isr\num: + swapgs_if_necessary pushq $0 pushq $\num jmp __isr_head diff --git a/arch/x86_64/lgdt.s b/arch/x86_64/lgdt.s index 55e37b5..ccafe42 100644 --- a/arch/x86_64/lgdt.s +++ b/arch/x86_64/lgdt.s @@ -4,9 +4,9 @@ gdt_load: lgdt (%rdi) .reload_segments: pushq $0x8 - leaq .reload_cs, %rax + leaq .reload_cs(%rip), %rax pushq %rax - lretq + retfq .reload_cs: movw $0x10, %ax movw %ax, %ds diff --git a/arch/x86_64/memory/pml4.c b/arch/x86_64/memory/pml4.c index d5fb56b..b42ce06 100644 --- a/arch/x86_64/memory/pml4.c +++ b/arch/x86_64/memory/pml4.c @@ -1,5 +1,6 @@ #include "arch/x86_64/page.h" #include "arch/x86_64/processor.h" +#include "arch/x86_64/idt.h" #include "device/processor.h" #include "memory.h" #include "boot.h" @@ -7,6 +8,7 @@ #include "init.h" #include "string.h" #include "jove.h" +#include "print.h" #include "api/error.h" #include <stdint.h> @@ -81,6 +83,27 @@ pml4_try_map(pmle_t *pml4, uintptr_t pptr, uintptr_t vptr) return KE_OK; } +static void +s_handle_pagefault(ivt_state_t *state) +{ + int eflags = state->err; + bool e_present = eflags & 1; + bool e_write = (eflags & 2) > 0; + bool e_user = (eflags & 4) > 0; + bool e_insf = (eflags & 16) > 0; + + uintptr_t faultaddr; + __asm__ volatile("movq %%cr2, %0": "=r"(faultaddr)); + + kprintf("\n%s %s %s page for %s\n", + e_user ? "User" : "Kernel", + e_write ? "wrote to" : "read from", + e_present ? "present" : "non-present", + e_insf ? "instruction" : "memory"); + kprintf("Faulting address: %p\n", faultaddr); + kpanic_state(state, "Unhandled page fault"); +} + __attribute__((aligned(0x1000))) pmle_t s_kernel_pml4[512]; // Page L4 __attribute__((aligned(0x1000))) pmle_t s_kernel_pml3[512]; // Page L3 __attribute__((aligned(0x1000))) pmle_t s_kernel_pml2[512]; // Page directory @@ -139,6 +162,7 @@ pml4_setup_init(void) } __asm__ volatile("mov %0, %%cr3":: "r"(kernel_pml4_base)); + kernel_isr_handles[EXCEPTION_PF] = s_handle_pagefault; //Add page mapping object to init directory. _initDirectory.entries[INIT_OBJECT_PAGEMAP] = (objdir_entry_t) { diff --git a/arch/x86_64/panic.c b/arch/x86_64/panic.c index 2e34500..522550f 100644 --- a/arch/x86_64/panic.c +++ b/arch/x86_64/panic.c @@ -25,12 +25,13 @@ kpanic_state(ivt_state_t *state, const char *fmt, ...) kprintf("R12 %p | R13 %p | R14 %p | R15 %p\n", state->r12, state->r13, state->r14, state->r15); kprintf("RIP %p\n", state->rip); + /* kprintf("\nStack trace:\n"); struct stackFrame *frame = (struct stackFrame*)state->rbp; for(size_t framei = 0; frame && framei < 64; ++framei) { kprintf("%i %p : %p\n", framei, frame, frame->eip); frame = frame->ebp; - } + }*/ hcf(); } diff --git a/arch/x86_64/syscall/invoke-mapping.c b/arch/x86_64/syscall/invoke-mapping.c index 186b420..e470034 100644 --- a/arch/x86_64/syscall/invoke-mapping.c +++ b/arch/x86_64/syscall/invoke-mapping.c @@ -1,5 +1,5 @@ #include "arch/x86_64/syscall/wrappers.h" -#include "arch/x86_64/syscall.h" +#include "arch/x86_64/api/syscall.h" #include "arch/x86_64/page.h" #include <stddef.h> #include "api/error.h" @@ -20,7 +20,9 @@ s_handle_invoke_mapping_exists( pmle_t *target_pml; uint8_t target_depth; SYSCALL_PAYLOAD_TAKEPML(payload, payload_at, pml4, target_depth, target_pml); - if(target_pml == NULL || !target_pml->p) return KE_DNE; + if(target_pml == NULL || !target_pml->p) { + return KE_DNE; + } #ifdef DBG_SYSCALL klogf("pml d%i %p from %p exists\n", target_depth, target_pml, pml4); @@ -46,7 +48,9 @@ s_handle_invoke_mapping_map( objdir_entry_t *untyped_entry; SYSCALL_PAYLOAD_TAKEOBJ(payload, payload_at, untyped_pathw, untyped_entry); - if(untyped_entry->type != KO_MEMORY_UNTYPED) return KE_BADOBJ; + if(untyped_entry->type != KO_MEMORY_UNTYPED) { + return KE_BADOBJ; + } mtx_acquire(&untyped_entry->lock); if((untyped_entry->data & 0xFFF) != 0) { @@ -69,6 +73,7 @@ s_handle_invoke_mapping_map( memset(untyped, 0, 0x1000); } untyped_entry->type = KO_NONE; + untyped_entry->data = 0; #ifdef DBG_SYSCALL klogf("map %p[%i] to %p[%i]\n", untyped_phys, target_depth, target_pml, ((uintptr_t)target_pml & 0xFFF) / 8); #endif diff --git a/arch/x86_64/syscall/syscall.c b/arch/x86_64/syscall/syscall.c index 7ddd179..1ed991d 100644 --- a/arch/x86_64/syscall/syscall.c +++ b/arch/x86_64/syscall/syscall.c @@ -35,18 +35,36 @@ __attribute__((naked)) void _syscall_entry(void) { __asm__ volatile(" \ - pushq %%r11; \ - pushq %%rcx; \ swapgs; \ movq %%gs:%c[tcb], %%rax; \ movq %%rsp, %c[sp](%%rax); \ movq %c[ksp](%%rax), %%rsp; \ pushq %c[sp](%%rax); \ + pushq %%r11; \ + pushq %%rcx; \ + pushq %%rbx; \ + pushq %%rbp; \ + pushq %%r12; \ + pushq %%r13; \ + pushq %%r14; \ + pushq %%r15; \ callq _syscall_handler; \ swapgs; \ - popq %%rsp; \ + popq %%r15; \ + popq %%r14; \ + popq %%r13; \ + popq %%r12; \ + popq %%rbp; \ + popq %%rbx; \ + xorq %%rdx, %%rdx; \ + xorq %%rsi, %%rsi; \ + xorq %%rdi, %%rdi; \ + xorq %%r8, %%r8; \ + xorq %%r9, %%r9; \ + xorq %%r10, %%r10; \ popq %%rcx; \ popq %%r11; \ + popq %%rsp; \ sysretq;" :: [tcb] "i"(offsetof(processor_t, tcb)), diff --git a/arch/x86_64/tasking/tcb.c b/arch/x86_64/tasking/tcb.c index 9877455..3cae29f 100644 --- a/arch/x86_64/tasking/tcb.c +++ b/arch/x86_64/tasking/tcb.c @@ -24,8 +24,10 @@ tcb_init(void *task_main) .type = KO_TCB, .data = vptr_tophys_koff((uintptr_t)_init_tcb) }; - - ((processor_t*)processor_current())->tcb = _init_tcb; + + processor_t* proc = processor_current(); + proc->tcb = _init_tcb; + proc->tss.rsp0 = _init_tcb->ksp; __asm__ volatile("\ movq %0, %%rsp; \ diff --git a/arch/x86_64/usermode.c b/arch/x86_64/usermode.c index 24a31a1..0285e7d 100644 --- a/arch/x86_64/usermode.c +++ b/arch/x86_64/usermode.c @@ -6,7 +6,6 @@ void usermode(void *ip, void *sp) __asm__ volatile("mov %0, %%rsp; \ movq %1, %%rcx; \ movq $0x202, %%r11; \ - cli; \ swapgs; \ sysretq":: "r"(sp), "r"(ip): "memory"); |