diff options
author | Alex Auvolat <alex.auvolat@ens.fr> | 2015-02-13 22:44:10 +0100 |
---|---|---|
committer | Alex Auvolat <alex.auvolat@ens.fr> | 2015-02-13 22:44:10 +0100 |
commit | 706c69d40fcc46e7d7f170dab932d3c7fcc7c34e (patch) | |
tree | 5248ff8712eced5bc4fdd76e9399654ce5224a37 /src/kernel/user | |
parent | 47e6cd42f0744f6c04b8347093f6549339a856c9 (diff) | |
download | kogata-706c69d40fcc46e7d7f170dab932d3c7fcc7c34e.tar.gz kogata-706c69d40fcc46e7d7f170dab932d3c7fcc7c34e.zip |
Begin implementation of syscalls.
Diffstat (limited to 'src/kernel/user')
-rw-r--r-- | src/kernel/user/process.c | 26 | ||||
-rw-r--r-- | src/kernel/user/syscall.c | 64 |
2 files changed, 89 insertions, 1 deletions
diff --git a/src/kernel/user/process.c b/src/kernel/user/process.c index 0f4892d..579c33d 100644 --- a/src/kernel/user/process.c +++ b/src/kernel/user/process.c @@ -118,6 +118,10 @@ pagedir_t *proc_pagedir(process_t *p) { return p->pd; } +int proc_pid(process_t *p) { + return p->pid; +} + // ================================== // // MANAGING FILESYSTEMS FOR PROCESSES // // ================================== // @@ -143,7 +147,7 @@ fs_t *proc_find_fs(process_t *p, const char* name) { // USER MEMORY REGION MANAGEMENT // // ============================= // -static user_region_t *find_user_region(process_t *proc, void* addr) { +static user_region_t *find_user_region(process_t *proc, const void* addr) { for (user_region_t *it = proc->regions; it != 0; it = it->next) { if (addr >= it->addr && addr < it->addr + it->size) return it; } @@ -287,4 +291,24 @@ static void proc_usermem_pf(void* p, registers_t *regs, void* addr) { } } +void probe_for_read(const void* addr, size_t len) { + process_t *proc = current_process(); + user_region_t *r = find_user_region(proc, addr); + if (r == 0 || addr + len > r->addr + r->size || !(r->mode & MM_READ)) { + dbg_printf("Access violation on read at 0x%p len 0x%p in process %d : exiting.\n", + addr, len, proc->pid); + exit(); + } +} + +void probe_for_write(const void* addr, size_t len) { + process_t *proc = current_process(); + user_region_t *r = find_user_region(proc, addr); + if (r == 0 || addr + len > r->addr + r->size || !(r->mode & MM_WRITE)) { + dbg_printf("Access violation on write at 0x%p len 0x%p in process %d : exiting.\n", + addr, len, proc->pid); + exit(); + } +} + /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/kernel/user/syscall.c b/src/kernel/user/syscall.c new file mode 100644 index 0000000..563957c --- /dev/null +++ b/src/kernel/user/syscall.c @@ -0,0 +1,64 @@ +#include <string.h> +#include <process.h> +#include <vfs.h> + +#include <syscall.h> + +typedef uint32_t (*syscall_handler_t)(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + +static syscall_handler_t sc_handlers[SC_MAX] = { 0 }; + +// ==================== // +// THE SYSCALLS CODE !! // +// ==================== // + +static uint32_t exit_sc(uint32_t code, uint32_t uu1, uint32_t uu2, uint32_t uu3, uint32_t uu4) { + dbg_printf("Proc %d exit with code %d\n", proc_pid(current_process()), code); + // TODO : use code... and process exiting is not supposed to be done this way + + exit(); + return 0; +} + +static uint32_t yield_sc() { + yield(); + return 0; +} + +static uint32_t dbg_print_sc(uint32_t x, uint32_t uu1, uint32_t uu2, uint32_t uu3, uint32_t uu4) { + const char* addr = (const char*)x; + probe_for_read(addr, 256); + + char buf[256]; + memcpy(buf, addr, 256); + buf[255] = 0; + + dbg_print(buf); + + return 0; +} + +// ====================== // +// SYSCALLS SETUP ROUTINE // +// ====================== // + +void setup_syscalls() { + sc_handlers[SC_EXIT] = exit_sc; + sc_handlers[SC_YIELD] = yield_sc; + sc_handlers[SC_DBG_PRINT] = dbg_print_sc; +} + +void syscall_handler(registers_t *regs) { + ASSERT(regs->int_no == 64); + + if (regs->eax < SC_MAX) { + syscall_handler_t h = sc_handlers[regs->eax]; + if (h != 0) { + regs->eax = h(regs->ebx, regs->ecx, regs->edx, regs->esi, regs->edi); + } else { + regs->eax = -1; + } + } +} + +/* vim: set ts=4 sw=4 tw=0 noet :*/ |