summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2025-08-17 14:16:55 -0400
committerJon Santmyer <jon@jonsantmyer.com>2025-08-17 14:16:55 -0400
commit7ee9347560768641096df68c545ac085a20233e4 (patch)
tree5b567f2e98cd9e6aeee33eeecd7fbf6f2fafdeab
parentf466364b8a3858e7b3f19258d142851cb4a7e6d6 (diff)
downloadjove-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.c93
-rw-r--r--arch/x86_64/idt.c15
-rw-r--r--arch/x86_64/ivt.s12
-rw-r--r--arch/x86_64/lgdt.s3
-rw-r--r--arch/x86_64/processor.c4
-rw-r--r--arch/x86_64/syscall-invoke-mapping.c58
-rw-r--r--arch/x86_64/usermode.c9
-rw-r--r--config.mk2
-rw-r--r--include/arch/x86_64/idt.h1
-rw-r--r--include/arch/x86_64/object.h1
-rw-r--r--include/arch/x86_64/page.h1
-rw-r--r--include/arch/x86_64/processor.h27
-rw-r--r--include/arch/x86_64/tables.h48
-rw-r--r--include/syscall.h4
-rw-r--r--lib/itoa.c1
-rw-r--r--main.c2
-rw-r--r--syscall/handler.c8
-rw-r--r--syscall/invoke-untyped.c19
-rw-r--r--syscall/invoke_objdir.c40
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);
}
diff --git a/config.mk b/config.mk
index 0d26458..a73ae0b 100644
--- a/config.mk
+++ b/config.mk
@@ -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
diff --git a/lib/itoa.c b/lib/itoa.c
index 57f0c22..722c610 100644
--- a/lib/itoa.c
+++ b/lib/itoa.c
@@ -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) {
diff --git a/main.c b/main.c
index 7315f50..8dc7838 100644
--- a/main.c
+++ b/main.c
@@ -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*);