summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/hal/obj.c18
-rw-r--r--arch/x86_64/hal/paging.c105
-rw-r--r--arch/x86_64/hal/paging.h8
-rw-r--r--arch/x86_64/hal/process.c8
-rw-r--r--arch/x86_64/sys/syscall.c48
-rw-r--r--arch/x86_64/sys/syscall.h2
-rw-r--r--arch/x86_64/sys/syscall_serial.c (renamed from arch/x86_64/sys/serial.c)20
7 files changed, 122 insertions, 87 deletions
diff --git a/arch/x86_64/hal/obj.c b/arch/x86_64/hal/obj.c
index cb0e13d..9844a54 100644
--- a/arch/x86_64/hal/obj.c
+++ b/arch/x86_64/hal/obj.c
@@ -79,7 +79,7 @@ objdir_peeklocal(
jove_owned_obj_t *objdir_obj,
uint16_t entry)
{
- if(obj_gettype_linked(objdir_obj) != JOVE_OBJ_OBJDIR) {
+ if(obj_gettype(objdir_obj) != JOVE_OBJ_OBJDIR) {
errno = EBADOBJ;
return (jove_obj_t) { 0 };
}
@@ -88,7 +88,7 @@ objdir_peeklocal(
return (jove_obj_t) { 0 };
}
- jove_objdir_t *objtab = obj_deref_linked(objdir_obj);
+ jove_objdir_t *objtab = obj_deref(objdir_obj);
return objtab->entries[entry];
}
@@ -97,14 +97,17 @@ objdir_getlocal(
jove_owned_obj_t *objdir_obj,
uint16_t entry)
{
- if(obj_gettype_linked(objdir_obj) != JOVE_OBJ_OBJDIR) {
+ while(obj_gettype(objdir_obj) == JOVE_OBJ_LINK) {
+ objdir_obj = link_deref(objdir_obj);
+ }
+ if(obj_gettype(objdir_obj) != JOVE_OBJ_OBJDIR) {
reterr(EBADOBJ);
}
if(entry >= JOVE_OBJDIR_ENTRIES) {
reterr(EBADPATH);
}
- jove_objdir_t *objtab = obj_deref_linked(objdir_obj);
+ jove_objdir_t *objtab = obj_deref(objdir_obj);
return obj_take(&objtab->entries[entry]);
}
@@ -113,14 +116,17 @@ objdir_trygetlocal(
jove_owned_obj_t *objdir_obj,
uint16_t entry)
{
- if(obj_gettype_linked(objdir_obj) != JOVE_OBJ_OBJDIR) {
+ while(obj_gettype(objdir_obj) == JOVE_OBJ_LINK) {
+ objdir_obj = link_deref(objdir_obj);
+ }
+ if(obj_gettype(objdir_obj) != JOVE_OBJ_OBJDIR) {
reterr(EBADOBJ);
}
if(entry >= JOVE_OBJDIR_ENTRIES) {
reterr(EBADPATH);
}
- jove_objdir_t *objtab = obj_deref_linked(objdir_obj);
+ jove_objdir_t *objtab = obj_deref(objdir_obj);
return obj_trytake(&objtab->entries[entry]);
}
diff --git a/arch/x86_64/hal/paging.c b/arch/x86_64/hal/paging.c
index 9947e9c..2fbf26c 100644
--- a/arch/x86_64/hal/paging.c
+++ b/arch/x86_64/hal/paging.c
@@ -106,7 +106,7 @@ s_pagedir_get_pml1(page_t *pml4, uintptr_t vptr)
}
int pagedir_map_frame(page_t *pml4,
- uintptr_t pptr, uintptr_t vptr,
+ uintptr_t pptr, uintptr_t vptr,
uintmax_t flg)
{
page_t *pml1 = s_pagedir_get_pml1(pml4, vptr);
@@ -121,41 +121,35 @@ int pagedir_map_frame(page_t *pml4,
return 0;
}
-int pagedir_map_untyped_frame(
- jove_owned_obj_t *tgt, jove_owned_obj_t *untyped_obj,
- uintptr_t vptr, struct syscall_pagedir_flags flg)
+int pagedir_map_shmem(page_t *pml4,
+ uintptr_t pptr, uintptr_t vptr,
+ struct syscall_pagedir_flags flg)
{
- page_t *pml4 = obj_deref(tgt);
- uintptr_t frame = obj_getvalue(untyped_obj);
-
- return pagedir_map_frame(pml4, frame, vptr,
- (flg.writeable ? PAGE_WRITEABLE : 0) |
- PAGE_USER |
- (flg.executable ? PAGE_XD : 0));
+ uintmax_t real_flg = PAGE_USER | PAGE_SHMEM;
+ if(flg.writeable) {
+ real_flg |= PAGE_WRITEABLE;
+ }
+ if(!flg.executable) {
+ real_flg |= PAGE_XD;
+ }
+ return pagedir_map_frame(pml4, pptr, vptr, real_flg);
}
-int pagedir_unmap_untyped_frame(
- jove_owned_obj_t *tgt, jove_owned_obj_t *dst, uintptr_t vptr)
+int pagedir_map_untyped_frame(
+ jove_owned_obj_t *tgt, jove_perm_obj_t *untyped,
+ uintptr_t vptr, struct syscall_pagedir_flags flg)
{
page_t *pml4 = obj_deref(tgt);
- size_t pml4i = PML4I(vptr);
- if(!pml4[pml4i].p) return ENOMAP;
-
- page_t *pml1 = s_pagedir_get_pml1(pml4, vptr);
- size_t pml1i = PML1I(vptr);
- if(!pml1[pml1i].p) return ENOMAP;
-
- uintptr_t untyped_pptr = (pml1[pml1i].paddr << 12);
-
- obj_settype(dst, JOVE_OBJ_UNTYPED);
- obj_setvalue(dst, untyped_pptr);
-
- jove_untyped_t *untyped_data = obj_deref(dst);
- untyped_data->limit = 0x1000;
- __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory");
+ if(flg.writeable && (untyped->permissions & JOVE_PERM_WRITE) == 0) {
+ kprintf("%s: Untyped object flagged for writeable mapping missing write permissions!\n", __func__);
+ return -EPERM;
+ }
- return 0;
+ uintptr_t frame = obj_getvalue(untyped->obj);
+ return pagedir_map_frame(pml4, frame, vptr, PAGE_USER |
+ (flg.writeable ? PAGE_WRITEABLE : 0) |
+ (flg.executable ? 0 : PAGE_XD));
}
int pagedir_map_table(page_t *pml4,
@@ -199,14 +193,63 @@ map_table:
}
int pagedir_map_untyped_table(
- jove_owned_obj_t *tgt, jove_owned_obj_t *untyped_obj, uintptr_t vptr)
+ jove_owned_obj_t *tgt, jove_perm_obj_t *untyped, uintptr_t vptr)
{
page_t *pml4 = obj_deref(tgt);
- uintptr_t frame = obj_getvalue(untyped_obj);
+
+ if((untyped->permissions & JOVE_PERM_WRITE) == 0) {
+ kprintf("%s: Untyped object flagged for table mapping missing write permissions!\n", __func__);
+ return -EPERM;
+ }
+ uintptr_t frame = obj_getvalue(untyped->obj);
return pagedir_map_table(pml4, frame, vptr);
}
+int pagedir_map_shmem_frame(
+ jove_owned_obj_t *tgt, jove_perm_obj_t *shmem, uint8_t page_offset,
+ uintptr_t vptr, struct syscall_pagedir_flags flg)
+{
+ page_t *pml4 = obj_deref(tgt);
+
+ if(flg.writeable && (shmem->permissions & JOVE_PERM_WRITE) != 0) {
+ kprintf("%s: Shared memory object flagged for writeable mapping missing write permissions!\n", __func__);
+ return -EPERM;
+ }
+
+ uintmax_t value = obj_getvalue(shmem->obj);
+ uintptr_t frame = value & ~0xFF;
+ frame += (uintmax_t)page_offset << 12;
+
+ return pagedir_map_frame(pml4, frame, vptr, PAGE_USER |
+ (flg.writeable ? PAGE_WRITEABLE : 0) |
+ (flg.executable ? 0 : PAGE_XD));
+}
+
+int pagedir_unmap_untyped_frame(
+ jove_owned_obj_t *tgt, jove_owned_obj_t *dst, uintptr_t vptr)
+{
+ page_t *pml4 = obj_deref(tgt);
+
+ size_t pml4i = PML4I(vptr);
+ if(!pml4[pml4i].p) return ENOMAP;
+
+ page_t *pml1 = s_pagedir_get_pml1(pml4, vptr);
+ size_t pml1i = PML1I(vptr);
+ if(!pml1[pml1i].p) return ENOMAP;
+
+ uintptr_t untyped_pptr = (pml1[pml1i].paddr << 12);
+
+ obj_settype(dst, JOVE_OBJ_UNTYPED);
+ obj_setvalue(dst, untyped_pptr);
+
+ jove_untyped_t *untyped_data = obj_deref(dst);
+ untyped_data->limit = 0x1000;
+ __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory");
+
+ return 0;
+}
+
int pagedir_unmap_untyped_table(
jove_owned_obj_t *tgt, jove_owned_obj_t *dst, uintptr_t vptr)
{
diff --git a/arch/x86_64/hal/paging.h b/arch/x86_64/hal/paging.h
index 5b7260c..becf353 100644
--- a/arch/x86_64/hal/paging.h
+++ b/arch/x86_64/hal/paging.h
@@ -17,7 +17,8 @@ typedef union page_table_entry
uint8_t d : 1;
uint8_t ps : 1;
uint8_t g : 1;
- uint8_t ign_0 : 2;
+ uint8_t shm : 1;
+ uint8_t ign_0 : 1;
uint8_t r : 1;
uint64_t paddr : 35;
uint8_t ign_1 : 4;
@@ -35,8 +36,9 @@ typedef union page_table_entry
#define PAGE_ACCESSED 0b100000
#define PAGE_DIRTY 0b1000000
#define PAGE_PS 0b10000000
-#define PAGE_GLOBAL 0b000000000
-#define PAGE_XD (0ULL << 63)
+#define PAGE_GLOBAL 0b100000000
+#define PAGE_SHMEM 0b1000000000
+#define PAGE_XD (1ULL << 63)
extern void *_kernel_physptr;
diff --git a/arch/x86_64/hal/process.c b/arch/x86_64/hal/process.c
index f30d703..aa51f45 100644
--- a/arch/x86_64/hal/process.c
+++ b/arch/x86_64/hal/process.c
@@ -22,7 +22,7 @@ process_current(void)
pcb_t*
pcb_from_obj(jove_owned_obj_t *obj)
{
- if(obj_gettype(obj) != JOVE_OBJ_PROCESS) {
+ if(obj_gettype(obj) != JOVE_OBJ_PCB) {
reterr(EBADOBJ);
}
return obj_deref(obj);
@@ -34,10 +34,10 @@ pcb_pid(pcb_t *pcb)
return pcb->pid;
}
-jove_owned_obj_t*
+jove_obj_t*
pcb_rootdir(pcb_t *pcb)
{
- return obj_take(pcb->rootdir);
+ return pcb->rootdir;
}
void
@@ -62,7 +62,7 @@ processing_setup(void (*process_main))
{
jove_owned_obj_t *process_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_PCB_I);
- obj_settype(process_obj, JOVE_OBJ_PROCESS);
+ obj_settype(process_obj, JOVE_OBJ_PCB);
obj_setvalue(process_obj, (uintptr_t)s_init_pcb);
proc->pcb_obj = obj_release(process_obj);
diff --git a/arch/x86_64/sys/syscall.c b/arch/x86_64/sys/syscall.c
index 53351e7..a694674 100644
--- a/arch/x86_64/sys/syscall.c
+++ b/arch/x86_64/sys/syscall.c
@@ -10,24 +10,17 @@ syscall_handle_t s_arch_handles[128] = {
};
int
-_syscall_handle_arch(
- jove_owned_obj_t *pcb_obj,
- jove_owned_obj_t *objdir,
- jove_owned_obj_t *message_obj,
- jove_owned_obj_t *target_obj,
- struct syscall_header *header,
- size_t bytes_left,
- void *payload)
+_syscall_handle_arch(syscall_context_t *ctx)
{
- uint8_t target_type = obj_gettype(target_obj) - 0x80;
+ uint8_t target_type = obj_gettype(ctx->target.obj) - 0x80;
syscall_handle_t call_handle = s_arch_handles[target_type];
if(call_handle == NULL) {
kprintf("syscall: Process %i tried to call syscall on object %P which doesn't support syscalls!\n",
- pcb_pid(obj_deref(pcb_obj)), header->path, header->pathlen);
- return EBADOBJ;
+ pcb_pid(obj_deref(ctx->pcb)), ctx->header->path, ctx->header->pathlen);
+ return -EBADOBJ;
}
- return call_handle(pcb_obj, objdir, message_obj, target_obj, header, bytes_left, payload);
+ return call_handle(ctx);
}
__attribute__((naked))
@@ -38,32 +31,29 @@ void _syscall_entry(void)
movq %%gs:%c[pcb], %%rax; \
movq %%rsp, %%rdx; \
movq %c[ksp](%%rax), %%rsp; \
+ pushq %%rcx; \
pushq %%rdx; \
pushq %%r11; \
- pushq %%rbx; \
- pushq %%rcx; \
pushq %%rbp; \
- pushq %%r12; \
- pushq %%r13; \
- pushq %%r14; \
- pushq %%r15; \
callq syscall_handler; \
swapgs; \
- popq %%r15; \
- popq %%r14; \
- popq %%r13; \
- popq %%r12; \
- popq %%rbp; \
- popq %%rcx; \
- popq %%rbx; \
- xorq %%rdx, %%rdx; \
+ xorq %%r15, %%r15; \
+ xorq %%r14, %%r14; \
+ xorq %%r13, %%r13; \
+ xorq %%r12, %%r12; \
+ xorq %%r10, %%r10; \
+ xorq %%r9, %%r9; \
+ xorq %%r8, %%r8; \
xorq %%rsi, %%rsi; \
xorq %%rdi, %%rdi; \
- xorq %%r8, %%r8; \
- xorq %%r9, %%r9; \
- xorq %%r10, %%r10; \
+ xorq %%rbp, %%rbp; \
+ xorq %%rdx, %%rdx; \
+ xorq %%rcx, %%rcx; \
+ xorq %%rbx, %%rbx; \
+ popq %%rbp; \
popq %%r11; \
popq %%rsp; \
+ popq %%rcx; \
sysretq;"
::
[pcb] "i"(offsetof(processor_t, pcb)),
diff --git a/arch/x86_64/sys/syscall.h b/arch/x86_64/sys/syscall.h
index 868ce0b..34f6a2a 100644
--- a/arch/x86_64/sys/syscall.h
+++ b/arch/x86_64/sys/syscall.h
@@ -3,7 +3,7 @@
#include "sys/syscall.h"
-int _syscall_handle_serial(SYSCALL_FUNCTION_ARGS);
+int _syscall_handle_serial(syscall_context_t *ctx);
#define SYSCALL_SERIAL_COM_WRITE 0
diff --git a/arch/x86_64/sys/serial.c b/arch/x86_64/sys/syscall_serial.c
index 12db6fd..786a78b 100644
--- a/arch/x86_64/sys/serial.c
+++ b/arch/x86_64/sys/syscall_serial.c
@@ -1,5 +1,6 @@
#include "jove.h"
#include "lib/printf.h"
+#include "sys/syscall.h"
#include "syscall.h"
#include "arch/x86_64/hal/serial_com.h"
@@ -20,20 +21,13 @@ s_syscall_serial_write(
}
int
-_syscall_handle_serial(
- jove_owned_obj_t *pcb_obj,
- jove_owned_obj_t *objdir,
- jove_owned_obj_t *message_obj,
- jove_owned_obj_t *target_obj,
- struct syscall_header *header,
- size_t bytes_left,
- void *payload_data)
+_syscall_handle_serial(syscall_context_t *ctx)
{
- switch(header->callid) {
- case 0:
- return s_syscall_serial_write(target_obj, bytes_left, payload_data);
+ switch(ctx->header->callid) {
+ case SYSCALL_SERIAL_COM_WRITE:
+ return s_syscall_serial_write(ctx->target.obj, ctx->bytes_left, ctx->payload);
default:
- kprintf("syscall_serial: serial com object does not support syscall %i\n", header->callid);
- return EOOB;
+ kprintf("syscall_serial: serial com object does not support syscall %i\n", ctx->header->callid);
+ return -EBADCALL;
}
}