diff options
author | Jon Santmyer <jon@jonsantmyer.com> | 2025-08-17 14:16:55 -0400 |
---|---|---|
committer | Jon Santmyer <jon@jonsantmyer.com> | 2025-08-17 14:16:55 -0400 |
commit | 7ee9347560768641096df68c545ac085a20233e4 (patch) | |
tree | 5b567f2e98cd9e6aeee33eeecd7fbf6f2fafdeab | |
parent | f466364b8a3858e7b3f19258d142851cb4a7e6d6 (diff) | |
download | jove-kernel-7ee9347560768641096df68c545ac085a20233e4.tar.gz jove-kernel-7ee9347560768641096df68c545ac085a20233e4.tar.bz2 jove-kernel-7ee9347560768641096df68c545ac085a20233e4.zip |
working usermode pager. fix usermode interrupts
-rw-r--r-- | arch/x86_64/gdt.c | 93 | ||||
-rw-r--r-- | arch/x86_64/idt.c | 15 | ||||
-rw-r--r-- | arch/x86_64/ivt.s | 12 | ||||
-rw-r--r-- | arch/x86_64/lgdt.s | 3 | ||||
-rw-r--r-- | arch/x86_64/processor.c | 4 | ||||
-rw-r--r-- | arch/x86_64/syscall-invoke-mapping.c | 58 | ||||
-rw-r--r-- | arch/x86_64/usermode.c | 9 | ||||
-rw-r--r-- | config.mk | 2 | ||||
-rw-r--r-- | include/arch/x86_64/idt.h | 1 | ||||
-rw-r--r-- | include/arch/x86_64/object.h | 1 | ||||
-rw-r--r-- | include/arch/x86_64/page.h | 1 | ||||
-rw-r--r-- | include/arch/x86_64/processor.h | 27 | ||||
-rw-r--r-- | include/arch/x86_64/tables.h | 48 | ||||
-rw-r--r-- | include/syscall.h | 4 | ||||
-rw-r--r-- | lib/itoa.c | 1 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | syscall/handler.c | 8 | ||||
-rw-r--r-- | syscall/invoke-untyped.c | 19 | ||||
-rw-r--r-- | syscall/invoke_objdir.c | 40 |
19 files changed, 212 insertions, 136 deletions
diff --git a/arch/x86_64/gdt.c b/arch/x86_64/gdt.c index e8ca912..3756d21 100644 --- a/arch/x86_64/gdt.c +++ b/arch/x86_64/gdt.c @@ -1,105 +1,96 @@ #include "arch/x86_64/tables.h" #include "arch/x86_64/processor.h" #include "string.h" +#include "print.h" static segment_descriptor_t s_gdt[] = { + [GDT_ENTRY_KERNEL_NULL] = { 0 }, //Kernel NULL + [GDT_ENTRY_KERNEL_CODE] = { //Kernel Code .limit_0_15 = 0xFFFF, .base_0_15 = 0x0, - .type = CD_SEGMENT_TYPE_CODE | CD_SEGMENT_TYPE_WRITEABLE, - .s = 1, - .dpl = 0, - .p = 1, - .limit_16_19 = 0xF, - .avl = 0, - .l = 1, - .d_b = 0, - .g = 1, + .type_flags = CD_SEGMENT_TYPE_CODE | CD_SEGMENT_TYPE_WRITEABLE | + GDT_SEGMENT_FLAG_S | + GDT_SEGMENT_FLAG_DPL(0) | + GDT_SEGMENT_FLAG_P, + .limit_16_19_avlx = 0xF | GDT_SEGMENT_AVLX_L | GDT_SEGMENT_AVLX_G, .base_24_31 = 0x0 }, + [GDT_ENTRY_KERNEL_DATA] = { //Kernel Data .limit_0_15 = 0xFFFF, .base_0_15 = 0x0, - .type = CD_SEGMENT_TYPE_WRITEABLE, - .s = 1, - .dpl = 0, - .p = 1, - .limit_16_19 = 0xF, - .avl = 0, - .l = 0, - .d_b = 1, - .g = 1, + .type_flags = CD_SEGMENT_TYPE_WRITEABLE | + GDT_SEGMENT_FLAG_S | + GDT_SEGMENT_FLAG_DPL(0) | + GDT_SEGMENT_FLAG_P, + .limit_16_19_avlx = 0xF | GDT_SEGMENT_AVLX_L | GDT_SEGMENT_AVLX_G, .base_24_31 = 0x0 }, + [GDT_ENTRY_USER_NULL] = { 0 }, //User NULL + [GDT_ENTRY_USER_DATA] = { //User Data .limit_0_15 = 0xFFFF, .base_0_15 = 0x0, - .type = CD_SEGMENT_TYPE_WRITEABLE, - .s = 1, - .dpl = 3, - .p = 1, - .limit_16_19 = 0xF, - .avl = 0, - .l = 0, - .d_b = 1, - .g = 1, + .type_flags = CD_SEGMENT_TYPE_WRITEABLE | + GDT_SEGMENT_FLAG_S | + GDT_SEGMENT_FLAG_DPL(3) | + GDT_SEGMENT_FLAG_P, + .limit_16_19_avlx = 0xF | GDT_SEGMENT_AVLX_L | GDT_SEGMENT_AVLX_G, .base_24_31 = 0x0 }, + [GDT_ENTRY_USER_CODE] = { //User Code .limit_0_15 = 0xFFFF, .base_0_15 = 0x0, - .type = CD_SEGMENT_TYPE_CODE | CD_SEGMENT_TYPE_WRITEABLE, - .s = 1, - .dpl = 3, - .p = 1, - .limit_16_19 = 0xF, - .avl = 0, - .l = 1, - .d_b = 0, - .g = 1, + .type_flags = CD_SEGMENT_TYPE_CODE | CD_SEGMENT_TYPE_WRITEABLE | + GDT_SEGMENT_FLAG_S | + GDT_SEGMENT_FLAG_DPL(3) | + GDT_SEGMENT_FLAG_P, + .limit_16_19_avlx = 0xF | GDT_SEGMENT_AVLX_L | GDT_SEGMENT_AVLX_G, .base_24_31 = 0x0 }, + [GDT_ENTRY_TSS_LOW] = { //TSS Low .limit_0_15 = 0, .base_0_15 = 0, .base_16_23 = 0, - .type = S_SEGMENT_TYPE_TSS_AVAIL, - .avl = 0, - .s = 0, - .dpl = 0, - .p = 1, - .limit_16_19 = 0, - .l = 0, - .d_b = 0, - .g = 0, + .type_flags = GDT_SEGMENT_TYPE_TSS_AVAIL | + GDT_SEGMENT_FLAG_DPL(0) | + GDT_SEGMENT_FLAG_P, + .limit_16_19_avlx = 0, .base_24_31 = 0 }, + [GDT_ENTRY_TSS_HIGH] = { 0 } //TSS High }; void gdt_setup(processor_t *processor) { - memcpy(processor->gdt, s_gdt, sizeof(s_gdt)); + 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.length = sizeof(s_gdt) - 1; + 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); + + 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; - size_t tssl = sizeof(tss_t); - tss_lo->limit_0_15 = tssl & 0xFFFF; - tss_lo->limit_16_19 = (tssl >> 16) & 0xF; + tss_lo->limit_16_19_avlx = (tssl >> 16) & 0xF; processor->tss.iopb = tssl; @@ -107,5 +98,5 @@ gdt_setup(processor_t *processor) gdt_load(&processor->gdtr); extern void tss_flush(uint16_t); - tss_flush(GDT_ENTRY_TSS_LOW * sizeof(segment_descriptor_t)); + tss_flush(GDT_OFFSET_TSS); } diff --git a/arch/x86_64/idt.c b/arch/x86_64/idt.c index 99e1da1..1080f92 100644 --- a/arch/x86_64/idt.c +++ b/arch/x86_64/idt.c @@ -1,16 +1,13 @@ #include "arch/x86_64/tables.h" #include "arch/x86_64/idt.h" -__attribute__((aligned(4096))) +__attribute__((aligned(0x10))) interrupt_gate_t s_idtd[256]; -int64_t __isr_err; -int64_t __isr_num; - void isr_handle(ivt_state_t* state) { - kpanic_state(state, "Unhandled interrupt %i", __isr_num); + kpanic_state(state, "Unhandled interrupt %i", state->num); } void @@ -21,13 +18,9 @@ ivt_setup(void) uintptr_t base = __ivt[i]; s_idtd[i] = (interrupt_gate_t) { .base_0_15 = (base & 0xFFFF), - .segment_selector = 0x8, + .cs = GDT_OFFSET_KERNEL_CODE, .ist = 0, - .zero_0 = 0, - .type = 0xE, - .zero_1 = 0, - .dpl = 0, - .p = 1, + .type_flags = IDT_TYPE_INT_GATE | IDT_FLAG_DPL(0) | IDT_FLAG_P, .base_16_31 = (base >> 16) & 0xFFFF, .base_32_63 = (base >> 32) & 0xFFFFFFFF, .resv = 0 diff --git a/arch/x86_64/ivt.s b/arch/x86_64/ivt.s index d2d504b..0005686 100644 --- a/arch/x86_64/ivt.s +++ b/arch/x86_64/ivt.s @@ -18,6 +18,8 @@ __isr_head: call isr_handle popall + + addq $16, %rsp iretq .extern __isr_err @@ -26,12 +28,7 @@ __isr_head: .macro defn_isr_err num:req .type __isr\num @function __isr\num: - pushq %rbx - movq 8(%rsp), %rbx - movq %rbx, __isr_err - popq %rbx - addq $8, %rsp - movq $\num, __isr_num + pushq $\num jmp __isr_head .size __isr\num, . - __isr\num .endm @@ -39,7 +36,8 @@ __isr\num: .macro defn_isr num:req .type __isr\num @function __isr\num: - movq $\num, __isr_num + pushq $0 + pushq $\num jmp __isr_head .size __isr\num, . - __isr\num .endm diff --git a/arch/x86_64/lgdt.s b/arch/x86_64/lgdt.s index 7122ef9..55e37b5 100644 --- a/arch/x86_64/lgdt.s +++ b/arch/x86_64/lgdt.s @@ -20,7 +20,6 @@ gdt_load: .global tss_flush .type tss_flush @function tss_flush: - movw %di, %ax - ltr %ax + ltr %di retq .size tss_flush, . - tss_flush diff --git a/arch/x86_64/processor.c b/arch/x86_64/processor.c index 3ebf1ee..f7e5cac 100644 --- a/arch/x86_64/processor.c +++ b/arch/x86_64/processor.c @@ -66,8 +66,8 @@ s_enable_sce(void) wrmsr(MSR_EFER, feat.v[0], feat.v[1]); msr_star_t star; - star.kcs = GDT_ENTRY_KERNEL_CODE * sizeof(segment_descriptor_t); - star.ucs = GDT_ENTRY_USER_CODE * sizeof(segment_descriptor_t); + star.kcs = GDT_OFFSET_KERNEL_CODE; + star.ucs = GDT_OFFSET_USER_CODE; wrmsr(MSR_STAR, star.v[0], star.v[1]); extern void _syscall_entry(void); diff --git a/arch/x86_64/syscall-invoke-mapping.c b/arch/x86_64/syscall-invoke-mapping.c index efecbdf..5b79239 100644 --- a/arch/x86_64/syscall-invoke-mapping.c +++ b/arch/x86_64/syscall-invoke-mapping.c @@ -4,6 +4,9 @@ #include <stddef.h> #include "error.h" #include "lock.h" +#include "string.h" +#include "memory.h" +#include "print.h" static int s_handle_invoke_mapping_release( @@ -13,6 +16,9 @@ s_handle_invoke_mapping_release( size_t payload_at ) { +#ifdef DBG_SYSCALL + klogf("release mapping %p\n", target_entry); +#endif target_entry->data = 0; target_entry->type = KO_NONE; return 0; @@ -29,25 +35,29 @@ s_handle_invoke_mapping_get( pmli_t pmli; SYSCALL_PAYLOAD_TAKEL(payload, payload_at, pmli, pmli_t); - if(pmli > 511) return -KE_OOB; + if(pmli > 511) return KE_OOB; uint8_t level = target_entry->data & 3; pmle_t *target_pml = (pmle_t*)vmem_phys_tovirt(target_entry->data & ~3ULL); - if(level == 3 && pmli > 255) return -KE_OOB; - if(level == 0) return -KE_BADOBJ; - + if(level == 3 && pmli > 255) return KE_OOB; + if(level < 0) return KE_BADOBJ; + size_t dest_pathw; objdir_entry_t *dest_entry; SYSCALL_PAYLOAD_TAKEOBJ(payload, payload_at, dest_pathw, dest_entry); - if(dest_entry->type != KO_NONE) return -KE_FULL; + + if(dest_entry->type != KO_NONE) return KE_FULL; pmle_t pmle = target_pml[pmli]; - if(!pmle.p) return -KE_DNE; + if(!pmle.p) return KE_DNE; *dest_entry = (objdir_entry_t) { .type = KO_MEMORY_MAPPING, .data = (((uintptr_t)target_pml[pmli].paddr) << 12ULL) | (level - 1) }; +#ifdef DBG_SYSCALL + klogf("Get pml%i %p[%i] -> %p\n", level, target_pml, pmli, dest_entry->data & ~3ULL); +#endif return 0; } @@ -65,37 +75,47 @@ s_handle_invoke_mapping_map( pmli_t pmli; SYSCALL_PAYLOAD_TAKEL(payload, payload_at, pmli, pmli_t); - if(pmli > 511) return -KE_OOB; - if(level == 3 && pmli > 255) return -KE_OOB; + if(pmli > 511) return KE_OOB; + if(level == 3 && pmli > 255) return KE_OOB; + if(level < 0) return KE_BADOBJ; size_t untyped_pathw; 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) { mtx_release(&untyped_entry->lock); - return -KE_ALIGN; + return KE_ALIGN; } - size_t *untyped_data = (size_t*)untyped_entry->data; - size_t untyped_size = *untyped_data; + + uintptr_t untyped_phys = untyped_entry->data; + size_t *untyped = ko_entry_data(untyped_entry); + size_t untyped_size = *untyped; if(untyped_size != 0x1000) { mtx_release(&untyped_entry->lock); - return -KE_BADSIZE; + return KE_BADSIZE; } pmle_t pmle = target_pml[pmli]; if(pmle.p) { mtx_release(&untyped_entry->lock); - return -KE_OCCUPIED; + return KE_OCCUPIED; } - target_pml[pmli].value = vmem_ident_tophys((void*)untyped_entry->data) | PAGE_RW | PAGE_US | PAGE_PRESENT; + target_pml[pmli].value = untyped_phys | PAGE_RW | PAGE_US | PAGE_PRESENT; + if(level != 0) { + memset(untyped, 0, 0x1000); + } untyped_entry->type = KO_MEMORY_MAPPING; untyped_entry->data |= level - 1; +#ifdef DBG_SYSCALL + klogf("map %p[%p] to pml%i %p[%i]\n", untyped_entry, untyped_phys, level, target_pml, pmli); +#endif + mtx_release(&untyped_entry->lock); return 0; } @@ -119,6 +139,10 @@ syscall_handle_invoke_mapping( uint8_t funcid; SYSCALL_PAYLOAD_TAKEL(payload, payload_at, funcid, uint8_t); - if(funcid >= s_invoke_handles_count) return -KE_BADFUNC; - return s_invoke_handles[funcid](root_dir, target, payload, payload_at); + if(funcid >= s_invoke_handles_count) return KE_BADFUNC; + int r = s_invoke_handles[funcid](root_dir, target, payload, payload_at); +#ifdef DBG_SYSCALL + klogf("Call returns %i\n", r); +#endif + return r; } diff --git a/arch/x86_64/usermode.c b/arch/x86_64/usermode.c index 68cb45a..99ee128 100644 --- a/arch/x86_64/usermode.c +++ b/arch/x86_64/usermode.c @@ -7,6 +7,7 @@ #include "string.h" #include "device/processor.h" #include "arch/x86_64/page.h" +#include "print.h" static tcb_t s_init_tcb; @@ -99,7 +100,7 @@ init_load(void) _initDirectory.entries[INIT_OBJECT_TCB] = (objdir_entry_t) { .type = KO_TCB, - .data = (uintptr_t)&s_init_tcb + .data = vmem_tophys_koff((uintptr_t)&s_init_tcb) }; objdir_t *untyped_dir = (objdir_t*)_initDirectory.entries[INIT_OBJECT_UNTYPED_DIR].data; @@ -123,11 +124,12 @@ init_load(void) uintptr_t sp = stack_base + 0xFF0; //Create a kernel stack for the init TCB - uintptr_t ksp_base = (uintptr_t)s_init_tcb.kstack; + uintptr_t ksp_base = (uintptr_t)&s_init_tcb.kstack; s_init_tcb.ksp = ksp_base + 0xFF0; processor_t *proc = (processor_t*)processor_current(); - proc->tss.rsp[0] = ksp_base; + proc->tss.rsp0 = s_init_tcb.ksp; + klogf("RSP0 %p\n", s_init_tcb.ksp); //Create a message object for init uintptr_t message_base = init_base + (init_pages << 12); @@ -145,6 +147,5 @@ init_load(void) //Setup usermode and jump proc->tcb = &s_init_tcb; - proc->tss.rsp[0] = s_init_tcb.ksp; s_enter_usermode((void*)init_base, (void*)sp); } @@ -8,7 +8,7 @@ ENABLE_SSE=y ENABLE_AVX=n DBG_MEM=y -DBG_SYSCALL=n +DBG_SYSCALL=y DBG_LOCK=n CFLAGS = \ diff --git a/include/arch/x86_64/idt.h b/include/arch/x86_64/idt.h index 90ce48b..ca1c484 100644 --- a/include/arch/x86_64/idt.h +++ b/include/arch/x86_64/idt.h @@ -8,6 +8,7 @@ typedef struct jove_IVTState uint64_t r15, r14, r13, r12, r11, r10, r9, r8; uint64_t rbp, rdi, rsi, rdx, rcx, rbx, rax; uint64_t rip, cs, rflags, rsp, ss; + uint64_t num, err; } ivt_state_t; void kpanic_state(ivt_state_t *state, const char *fmt, ...); diff --git a/include/arch/x86_64/object.h b/include/arch/x86_64/object.h index 770487b..e13a987 100644 --- a/include/arch/x86_64/object.h +++ b/include/arch/x86_64/object.h @@ -12,6 +12,7 @@ typedef struct jove_ThreadControlBlock void *stack; uintptr_t sp, ksp; void *pml4; + void *mailbox; uint8_t kstack[KERNEL_STACKBYTES]; } tcb_t; diff --git a/include/arch/x86_64/page.h b/include/arch/x86_64/page.h index 4460720..e62b8d6 100644 --- a/include/arch/x86_64/page.h +++ b/include/arch/x86_64/page.h @@ -38,6 +38,7 @@ typedef uint16_t pmli_t; uintptr_t vmem_ident_tophys(void *vptr); void *vmem_phys_tovirt(uintptr_t pptr); +uintptr_t vmem_tophys_koff(uintptr_t v); void *pmle_get_page(pmle_t entry); uint8_t pmle_level(pmle_t entry); diff --git a/include/arch/x86_64/processor.h b/include/arch/x86_64/processor.h index f8a93ce..1afa6cc 100644 --- a/include/arch/x86_64/processor.h +++ b/include/arch/x86_64/processor.h @@ -18,13 +18,22 @@ typedef struct jove_TSS { uint32_t resv0; - uint64_t rsp[3]; - uint32_t resv1; - uint64_t ist[8]; - uint32_t resv2[2]; - uint16_t resv3; + uint64_t rsp0; + uint64_t rsp1; + uint64_t rsp2; + uint64_t resv1; + uint64_t resv2; + uint64_t ist1; + uint64_t ist2; + uint64_t ist3; + uint64_t ist4; + uint64_t ist5; + uint64_t ist6; + uint64_t ist7; + uint64_t resv3; + uint16_t resv4; uint16_t iopb; -} tss_t; +} __attribute__((packed)) tss_t; enum { @@ -39,6 +48,12 @@ enum GDT_ENTRY_COUNT }; +#define GDT_OFFSET_KERNEL_CODE (GDT_ENTRY_KERNEL_CODE * sizeof(segment_descriptor_t)) +#define GDT_OFFSET_KERNEL_DATA (GDT_ENTRY_KERNEL_DATA * sizeof(segment_descriptor_t)) +#define GDT_OFFSET_USER_DATA (GDT_ENTRY_USER_DATA * sizeof(segment_descriptor_t)) +#define GDT_OFFSET_USER_CODE (GDT_ENTRY_USER_CODE * sizeof(segment_descriptor_t)) +#define GDT_OFFSET_TSS (GDT_ENTRY_TSS_LOW * sizeof(segment_descriptor_t)) + typedef struct jove_Processor { physptr_t pdir; diff --git a/include/arch/x86_64/tables.h b/include/arch/x86_64/tables.h index 42651a1..b35dd43 100644 --- a/include/arch/x86_64/tables.h +++ b/include/arch/x86_64/tables.h @@ -9,40 +9,44 @@ #define CD_SEGMENT_TYPE_CODE_CONFORMING 4 #define CD_SEGMENT_TYPE_CODE 8 -#define S_SEGMENT_TYPE_LDT 2 -#define S_SEGMENT_TYPE_TSS_AVAIL 9 -#define S_SEGMENT_TYPE_TSS_BUSY 11 -#define S_SEGMENT_TYPE_CALLGATE 12 -#define S_SEGMENT_TYPE_INT_GATE 14 -#define S_SEGMENT_TYPE_TRAP_GATE 15 +#define GDT_SEGMENT_TYPE_LDT 2 +#define GDT_SEGMENT_TYPE_TSS_AVAIL 0b1001 +#define GDT_SEGMENT_TYPE_TSS_BUSY 11 + +#define GDT_SEGMENT_FLAG_S (1 << 4) +#define GDT_SEGMENT_FLAG_DPL(l) (l << 5) +#define GDT_SEGMENT_FLAG_P (1 << 7) + +#define GDT_SEGMENT_AVLX_AVL (1 << 4) +#define GDT_SEGMENT_AVLX_L (1 << 5) +#define GDT_SEGMENT_AVLX_DB (1 << 6) +#define GDT_SEGMENT_AVLX_G (1 << 7) typedef struct jove_SegmentDescriptor { uint16_t limit_0_15; /* Segment limit. */ uint16_t base_0_15; /* Segment base. */ uint8_t base_16_23; - uint8_t type : 4; /* Segment type. */ - uint8_t s : 1; /* Descriptor type (0 = system, 1 = code/data)*/ - uint8_t dpl : 2; /* Descriptor privilege level. */ - uint8_t p : 1; /* Present. */ - uint8_t limit_16_19 : 4; - uint8_t avl : 1; /* Available for use by system software. */ - uint8_t l : 1; /* 64-bit segment (Ext). */ - uint8_t d_b : 1; /* Default operation size (0 = 16-bit, 1 = 32-bit)*/ - uint8_t g : 1; /* Granularity. */ + uint8_t type_flags; + uint8_t limit_16_19_avlx; uint8_t base_24_31; }__attribute__((packed)) segment_descriptor_t; +#define IDT_IST(v) (v & 7) + +#define IDT_TYPE_CALLGATE 12 +#define IDT_TYPE_INT_GATE 0b1110 +#define IDT_TYPE_TRAP_GATE 0b1111 + +#define IDT_FLAG_DPL(l) (l << 5) +#define IDT_FLAG_P (1 << 7) + typedef struct jove_InterruptGate { uint16_t base_0_15; - uint16_t segment_selector; - uint8_t ist : 3; - uint8_t zero_0 : 5; - uint8_t type : 4; - uint8_t zero_1 : 1; - uint8_t dpl : 2; - uint8_t p : 1; + uint16_t cs; + uint8_t ist; + uint8_t type_flags; uint16_t base_16_31; uint32_t base_32_63; uint32_t resv; diff --git a/include/syscall.h b/include/syscall.h index 9025f57..7410acc 100644 --- a/include/syscall.h +++ b/include/syscall.h @@ -24,7 +24,9 @@ enum /*[target path][u8 funcid][u8 memb][u16 ret]*/ INVOKE_OBJDIR_GETMEMB, /*[target path][u8 funcid][u8 ret]*/ - INVOKE_OBJDIR_LASTMEMB + INVOKE_OBJDIR_LASTMEMB, + /*[target path][u8 funcid][u8 memb][dest path]*/ + INVOKE_OBJDIR_MOVE }; /**@ENUM untyped invokes*/ enum @@ -8,7 +8,6 @@ ltostr(char *s, int size, unsigned long l, bool sign, int radix) if((long)l < 0 && sign) { l = -((long)l); if(size > wsize && s != 0) s[wsize] = '-'; - wsize++; } for(unsigned long lv = l; lv != 0; lv /= radix) { @@ -20,10 +20,10 @@ struct jove_ObjectDirectory _initDirectory = { void _jove_main(void) { - bsp_setup(); #ifdef ENABLE_PORTIO_UART portio_uart_setup(); #endif + bsp_setup(); pmem_setup(); vmem_setup(); diff --git a/syscall/handler.c b/syscall/handler.c index 6ac71da..b3eea99 100644 --- a/syscall/handler.c +++ b/syscall/handler.c @@ -31,6 +31,12 @@ s_syscall_handle_invoke(objdir_t *root_dir, uint8_t *payload) objdir_entry_t *target_entry; SYSCALL_PAYLOAD_TAKEOBJ(payload, payload_at, target_pathw, target_entry); +#ifdef DBG_SYSCALL + klogf("Calling invoke on obj %p [%i:%i] type %i\n", + target_entry, target_pathw, + payload[payload_at - 1], target_entry->type); +#endif + switch(target_entry->type) { case KO_NONE: return -KE_BADOBJ; @@ -38,8 +44,6 @@ s_syscall_handle_invoke(objdir_t *root_dir, uint8_t *payload) return s_invoke_release(root_dir, target_entry, payload, payload_at, syscall_handle_invoke_objdir); case KO_MEMORY_UNTYPED: return s_invoke_release(root_dir, target_entry, payload, payload_at, syscall_handle_invoke_untyped); - case KO_MEMORY_MAPPING: - return s_invoke_release(root_dir, target_entry, payload, payload_at, syscall_handle_invoke_mapping); default: return _syscall_handler_arch(root_dir, target_entry, payload, payload_at); } diff --git a/syscall/invoke-untyped.c b/syscall/invoke-untyped.c index 6b9199f..fe34ce9 100644 --- a/syscall/invoke-untyped.c +++ b/syscall/invoke-untyped.c @@ -56,20 +56,27 @@ s_handle_invoke_untyped_split( SYSCALL_PAYLOAD_TAKEOBJ(payload, payload_at, dest_pathw, dest_entry); if(dest_entry->type != KO_NONE) return -KE_BADOBJ; - size_t *untyped = (size_t*)target->data; + uintptr_t untyped_phys = target->data; + size_t *untyped = ko_entry_data(target); size_t untyped_size = *untyped; SYSCALL_PAYLOAD_TAKEL(payload, payload_at, dest_bytes, size_t); if(untyped_size - sizeof(size_t) <= dest_bytes) return -KE_TOOSMALL; - size_t *split = (size_t*)(((uintptr_t)untyped) + untyped_size - dest_bytes); - *untyped -= dest_bytes; - *split = dest_bytes; - *dest_entry = (objdir_entry_t) { .type = KO_MEMORY_UNTYPED, - .data = (uintptr_t)split + .data = untyped_phys + untyped_size - dest_bytes }; + + size_t *split = ko_entry_data(dest_entry); + *untyped -= dest_bytes; + *split = dest_bytes; + +#ifdef DBG_SYSCALL + klogf("split %p[%p:%i] into %p[%p:%i]\n", + target, target->data, untyped_size, + dest_entry, dest_entry->data, dest_bytes); +#endif return 0; } diff --git a/syscall/invoke_objdir.c b/syscall/invoke_objdir.c index 97dd126..0cc5a44 100644 --- a/syscall/invoke_objdir.c +++ b/syscall/invoke_objdir.c @@ -2,6 +2,7 @@ #include "syscall.h" #include "error.h" #include "lock.h" +#include "string.h" #include "print.h" static int @@ -40,15 +41,50 @@ s_handle_invoke_objdir_lastmemb( uint8_t lastfull = 0; for(int i = 1; i < 256; i++) { if(target_dir->entries[i].type != KO_NONE) lastfull = i; - } +} +#ifdef DBG_SYSCALL + klogf("%i\n", lastfull); +#endif *dest = lastfull; return 0; } +static int +s_handle_invoke_objdir_move( + objdir_t *root_dir, + objdir_t *target_dir, + uint8_t *payload, + size_t payload_at + ) +{ + uint8_t target_memb; + size_t dest_pathw; + objdir_entry_t *dest_entry; + + SYSCALL_PAYLOAD_TAKEL(payload, payload_at, target_memb, uint8_t); + SYSCALL_PAYLOAD_TAKEOBJ(payload, payload_at, dest_pathw, dest_entry); + + if(target_memb == 0) return KE_OOB; + if(dest_entry->type != KO_NONE) return KE_FULL; + + objdir_entry_t *move_entry = &target_dir->entries[target_memb]; + if(move_entry->type == KO_NONE) return KE_BADOBJ; + +#ifdef DBG_SYSCALL + klogf("move %p -> %p\n", move_entry, dest_entry); +#endif + + memcpy(dest_entry, move_entry, sizeof(objdir_entry_t)); + memset(move_entry, 0, sizeof(objdir_entry_t)); + + return KE_OK; +} + static int (*s_invoke_handles[])(objdir_t*, objdir_t*, uint8_t*, size_t) = { [INVOKE_OBJDIR_GETMEMB] = s_handle_invoke_objdir_getmemb, - [INVOKE_OBJDIR_LASTMEMB] = s_handle_invoke_objdir_lastmemb + [INVOKE_OBJDIR_LASTMEMB] = s_handle_invoke_objdir_lastmemb, + [INVOKE_OBJDIR_MOVE] = s_handle_invoke_objdir_move, }; static size_t s_invoke_handles_count = sizeof(s_invoke_handles) / sizeof(void*); |