summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2025-09-26 13:17:41 -0400
committerJon Santmyer <jon@jonsantmyer.com>2025-09-26 13:17:41 -0400
commit2dadbfc899df4179ca70c4ea04f74a5e190c2ae7 (patch)
treeb166aaa9af42406cd07fbaf150f93aefeb2fbe33 /arch
parentddc4fbc15223e362896a9f42beca73f05f48e664 (diff)
downloadjove-kernel-main.tar.gz
jove-kernel-main.tar.bz2
jove-kernel-main.zip
fix usermode interrupts. add ability to define custom interrupt handlersmain
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/device/processor.c4
-rw-r--r--arch/x86_64/gdt.c16
-rw-r--r--arch/x86_64/idt.c16
-rw-r--r--arch/x86_64/init.c2
-rw-r--r--arch/x86_64/ivt.s21
-rw-r--r--arch/x86_64/lgdt.s4
-rw-r--r--arch/x86_64/memory/pml4.c24
-rw-r--r--arch/x86_64/panic.c3
-rw-r--r--arch/x86_64/syscall/invoke-mapping.c11
-rw-r--r--arch/x86_64/syscall/syscall.c24
-rw-r--r--arch/x86_64/tasking/tcb.c6
-rw-r--r--arch/x86_64/usermode.c1
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");