diff options
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/arch/i386/driver/ps2.c | 12 | ||||
-rw-r--r-- | src/kernel/arch/i386/driver/ps2.h | 2 | ||||
-rw-r--r-- | src/kernel/arch/i386/driver/serial.c | 15 | ||||
-rw-r--r-- | src/kernel/arch/i386/driver/serial.h | 2 | ||||
-rw-r--r-- | src/kernel/arch/i386/registers.h | 3 | ||||
-rw-r--r-- | src/kernel/arch/i386/sysenter.c | 1 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 55 | ||||
-rw-r--r-- | src/kernel/vfs/request.c | 26 | ||||
-rw-r--r-- | src/kernel/vfs/request.h | 17 | ||||
-rw-r--r-- | src/kernel/vfs/root.c | 8 | ||||
-rw-r--r-- | src/kernel/vfs/root.h | 2 |
11 files changed, 74 insertions, 69 deletions
diff --git a/src/kernel/arch/i386/driver/ps2.c b/src/kernel/arch/i386/driver/ps2.c index 666fa76..8955100 100644 --- a/src/kernel/arch/i386/driver/ps2.c +++ b/src/kernel/arch/i386/driver/ps2.c @@ -28,14 +28,15 @@ size_t ps2_read(uint8_t *buf, size_t len) { return ring_get((void*)&backlog, buf, len); } -int vfs_ps2_accept(struct vfs_request *req) { +void vfs_ps2_accept(struct vfs_request *req) { // when you fix something here go also fix it in the COM1 driver static uint8_t buf[32]; // pretty damn stupid int ret; switch (req->type) { case VFSOP_OPEN: // allows opening /ps2/anything, TODO don't - return vfsreq_finish(req, 0); // fake file handle, whatever + vfsreq_finish(req, 0); // fake file handle, whatever + break; case VFSOP_READ: if (ps2_ready()) { // TODO FUKKEN MESS @@ -48,13 +49,14 @@ int vfs_ps2_accept(struct vfs_request *req) { ret = ps2_read(buf, ret); virt_cpy_to(req->caller->pages, req->output.buf, buf, ret); } else ret = -1; - return vfsreq_finish(req, ret); + vfsreq_finish(req, ret); } else { blocked_on = req; - return -1; } + break; default: - return vfsreq_finish(req, -1); + vfsreq_finish(req, -1); + break; } } diff --git a/src/kernel/arch/i386/driver/ps2.h b/src/kernel/arch/i386/driver/ps2.h index 1bbc2f1..c5d0ce1 100644 --- a/src/kernel/arch/i386/driver/ps2.h +++ b/src/kernel/arch/i386/driver/ps2.h @@ -8,5 +8,5 @@ bool ps2_ready(void); void ps2_recv(uint8_t scancode); size_t ps2_read(uint8_t *buf, size_t max_len); -int vfs_ps2_accept(struct vfs_request *); +void vfs_ps2_accept(struct vfs_request *); bool vfs_ps2_ready(struct vfs_backend *); diff --git a/src/kernel/arch/i386/driver/serial.c b/src/kernel/arch/i386/driver/serial.c index 4e274d8..170cc4d 100644 --- a/src/kernel/arch/i386/driver/serial.c +++ b/src/kernel/arch/i386/driver/serial.c @@ -69,12 +69,13 @@ void serial_write(const char *buf, size_t len) { } -int vfs_com1_accept(struct vfs_request *req) { +void vfs_com1_accept(struct vfs_request *req) { static uint8_t buf[32]; int ret; switch (req->type) { case VFSOP_OPEN: - return vfsreq_finish(req, 0); + vfsreq_finish(req, 0); + break; case VFSOP_READ: if (serial_ready()) { if (req->caller) { @@ -86,11 +87,11 @@ int vfs_com1_accept(struct vfs_request *req) { ret = serial_read(buf, ret); virt_cpy_to(req->caller->pages, req->output.buf, buf, ret); } else ret = -1; - return vfsreq_finish(req, ret); + vfsreq_finish(req, ret); } else { blocked_on = req; - return -1; } + break; case VFSOP_WRITE: if (req->caller) { struct virt_iter iter; @@ -100,9 +101,11 @@ int vfs_com1_accept(struct vfs_request *req) { serial_write(iter.frag, iter.frag_len); ret = iter.prior; } else ret = -1; - return vfsreq_finish(req, ret); + vfsreq_finish(req, ret); + break; default: - return vfsreq_finish(req, -1); + vfsreq_finish(req, -1); + break; } } diff --git a/src/kernel/arch/i386/driver/serial.h b/src/kernel/arch/i386/driver/serial.h index e7f9b7c..6aff142 100644 --- a/src/kernel/arch/i386/driver/serial.h +++ b/src/kernel/arch/i386/driver/serial.h @@ -11,5 +11,5 @@ size_t serial_read(char *buf, size_t len); void serial_write(const char *buf, size_t len); -int vfs_com1_accept(struct vfs_request *); +void vfs_com1_accept(struct vfs_request *); bool vfs_com1_ready(struct vfs_backend *); diff --git a/src/kernel/arch/i386/registers.h b/src/kernel/arch/i386/registers.h index 8bd090d..9f481d3 100644 --- a/src/kernel/arch/i386/registers.h +++ b/src/kernel/arch/i386/registers.h @@ -14,7 +14,8 @@ struct registers { } __attribute__((__packed__)); // saves a return value according to the SysV ABI -static inline void regs_savereturn(struct registers *regs, uint64_t value) { +static inline uint64_t regs_savereturn(struct registers *regs, uint64_t value) { regs->eax = value; regs->edx = value >> 32; + return value; } diff --git a/src/kernel/arch/i386/sysenter.c b/src/kernel/arch/i386/sysenter.c index 1d2a333..71dfbe9 100644 --- a/src/kernel/arch/i386/sysenter.c +++ b/src/kernel/arch/i386/sysenter.c @@ -23,6 +23,5 @@ _Noreturn void sysenter_stage2(void) { val = _syscall(regs->eax, regs->ebx, regs->esi, regs->edi, (uintptr_t)regs->ebp); - regs_savereturn(&process_current->regs, val); process_switch_any(); } diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index c5e25b7..aa2d45f 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -9,6 +9,8 @@ #include <shared/syscalls.h> #include <stdint.h> +#define SYSCALL_RETURN(val) return regs_savereturn(&process_current->regs, val) + _Noreturn void _syscall_exit(int ret) { process_kill(process_current, ret); process_switch_any(); @@ -22,23 +24,23 @@ int _syscall_await(void) { for (struct process *iter = process_current->child; iter; iter = iter->sibling) { if (iter->state == PS_DEAD && !iter->noreap) - return process_try2collect(iter); + SYSCALL_RETURN(process_try2collect(iter)); if (iter->state != PS_DEADER) has_children = true; } if (!has_children) { process_transition(process_current, PS_RUNNING); - return ~0; // TODO errno + SYSCALL_RETURN(~0); // TODO errno } else { - return -1; + SYSCALL_RETURN(-1); } } int _syscall_fork(int flags) { struct process *child = process_fork(process_current, flags); regs_savereturn(&child->regs, 0); - return 1; + SYSCALL_RETURN(1); } handle_t _syscall_open(const char __user *path, int len) { @@ -46,9 +48,9 @@ handle_t _syscall_open(const char __user *path, int len) { char *path_buf = NULL; if (PATH_MAX < len) - return -1; + SYSCALL_RETURN(-1); if (process_find_handle(process_current, 0) < 0) - return -1; + SYSCALL_RETURN(-1); path_buf = virt_cpy2kmalloc(process_current->pages, path, len); if (!path_buf) goto fail; @@ -66,7 +68,7 @@ handle_t _syscall_open(const char __user *path, int len) { memcpy(path_buf, path_buf + mount->prefix_len, len); } - return vfsreq_create((struct vfs_request) { + vfsreq_create((struct vfs_request) { .type = VFSOP_OPEN, .input = { .kern = true, @@ -76,9 +78,10 @@ handle_t _syscall_open(const char __user *path, int len) { .caller = process_current, .backend = mount->backend, }); + return -1; // dummy fail: kfree(path_buf); - return -1; + SYSCALL_RETURN(-1); } int _syscall_mount(handle_t hid, const char __user *path, int len) { @@ -86,7 +89,8 @@ int _syscall_mount(handle_t hid, const char __user *path, int len) { struct vfs_backend *backend = NULL; char *path_buf = NULL; - if (PATH_MAX < len) return -1; + if (PATH_MAX < len) + SYSCALL_RETURN(-1); // copy the path to the kernel to simplify it path_buf = virt_cpy2kmalloc(process_current->pages, path, len); @@ -122,18 +126,18 @@ int _syscall_mount(handle_t hid, const char __user *path, int len) { kmalloc_sanity(mount); kmalloc_sanity(mount->prefix); - return 0; + SYSCALL_RETURN(0); fail: kfree(path_buf); kfree(mount); - return -1; + SYSCALL_RETURN(-1); } int _syscall_read(handle_t handle_num, void __user *buf, size_t len, int offset) { struct handle *handle = process_handle_get(process_current, handle_num, HANDLE_FILE); - if (!handle) return -1; - return vfsreq_create((struct vfs_request) { + if (!handle) SYSCALL_RETURN(-1); + vfsreq_create((struct vfs_request) { .type = VFSOP_READ, .output = { .buf = (userptr_t) buf, @@ -144,12 +148,13 @@ int _syscall_read(handle_t handle_num, void __user *buf, size_t len, int offset) .caller = process_current, .backend = handle->file.backend, }); + return -1; // dummy } int _syscall_write(handle_t handle_num, const void __user *buf, size_t len, int offset) { struct handle *handle = process_handle_get(process_current, handle_num, HANDLE_FILE); - if (!handle) return -1; - return vfsreq_create((struct vfs_request) { + if (!handle) SYSCALL_RETURN(-1); + vfsreq_create((struct vfs_request) { .type = VFSOP_WRITE, .input = { .buf = (userptr_t) buf, @@ -160,15 +165,16 @@ int _syscall_write(handle_t handle_num, const void __user *buf, size_t len, int .caller = process_current, .backend = handle->file.backend, }); + return -1; // dummy } int _syscall_close(handle_t hid) { if (hid < 0 || hid >= HANDLE_MAX) return -1; struct handle **h = &process_current->handles[hid]; - if (!*h) return -1; + if (!*h) SYSCALL_RETURN(-1); handle_close(*h); *h = NULL; - return 0; + SYSCALL_RETURN(0); } handle_t _syscall_fs_fork2(void) { @@ -177,7 +183,7 @@ handle_t _syscall_fs_fork2(void) { handle_t front; front = process_find_handle(process_current, 1); - if (front < 0) return -1; + if (front < 0) SYSCALL_RETURN(-1); process_current->handles[front] = handle_init(HANDLE_FS_FRONT); backend = kmalloc(sizeof *backend); // TODO never freed @@ -193,12 +199,12 @@ handle_t _syscall_fs_fork2(void) { regs_savereturn(&child->regs, 0); process_current->handles[front]->fs.backend = backend; - return front; + SYSCALL_RETURN(front); } int _syscall_fs_wait(char __user *buf, int max_len, struct fs_wait_response __user *res) { struct vfs_backend *backend = process_current->controlled; - if (!backend) return -1; + if (!backend) SYSCALL_RETURN(-1); process_transition(process_current, PS_WAITS4REQUEST); assert(!backend->user.handler); // TODO allow multiple processes to wait on the same backend @@ -209,12 +215,13 @@ int _syscall_fs_wait(char __user *buf, int max_len, struct fs_wait_response __us process_current->awaited_req.max_len = max_len; process_current->awaited_req.res = res; - return vfs_backend_tryaccept(backend); + vfs_backend_tryaccept(backend); // sets return value + return -1; // dummy } int _syscall_fs_respond(char __user *buf, int ret) { struct vfs_request *req = process_current->handled_req; - if (!req) return -1; + if (!req) SYSCALL_RETURN(-1); if (req->output.len > 0 && ret > 0) { // if this vfsop outputs data and ret is positive, it's the length of the buffer @@ -228,7 +235,7 @@ int _syscall_fs_respond(char __user *buf, int ret) { process_current->handled_req = NULL; vfsreq_finish(req, ret); - return 0; + SYSCALL_RETURN(0); } int _syscall_memflag(void __user *addr, size_t len, int flags) { @@ -247,7 +254,7 @@ int _syscall_memflag(void __user *addr, size_t len, int flags) { } } - return -1; + SYSCALL_RETURN(-1); } int _syscall(int num, int a, int b, int c, int d) { diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c index f463b86..3e7c9f0 100644 --- a/src/kernel/vfs/request.c +++ b/src/kernel/vfs/request.c @@ -6,7 +6,7 @@ #include <kernel/vfs/root.h> #include <shared/mem.h> -int vfsreq_create(struct vfs_request req_) { +void vfsreq_create(struct vfs_request req_) { struct vfs_request *req = kmalloc(sizeof *req); // freed in vfsreq_finish memcpy(req, &req_, sizeof *req); @@ -19,17 +19,17 @@ int vfsreq_create(struct vfs_request req_) { } if (!req->backend || !req->backend->potential_handlers) - return vfsreq_finish(req, -1); + vfsreq_finish(req, -1); struct vfs_request **iter = &req->backend->queue; while (*iter != NULL) // find free spot in queue iter = &(*iter)->queue_next; *iter = req; - return vfs_backend_tryaccept(req->backend); + vfs_backend_tryaccept(req->backend); } -int vfsreq_finish(struct vfs_request *req, int ret) { +void vfsreq_finish(struct vfs_request *req, int ret) { if (req->type == VFSOP_OPEN && ret >= 0) { // open() calls need special handling // we need to wrap the id returned by the VFS in a handle passed to @@ -63,32 +63,32 @@ int vfsreq_finish(struct vfs_request *req, int ret) { vfs_backend_refdown(req->backend); kfree(req); - return ret; + return; } -int vfs_backend_tryaccept(struct vfs_backend *backend) { +void vfs_backend_tryaccept(struct vfs_backend *backend) { struct vfs_request *req = backend->queue; - if (!req) return -1; + if (!req) return; /* ensure backend is ready to accept request */ if (backend->is_user) { - if (!backend->user.handler) return -1; + if (!backend->user.handler) return; } else { assert(backend->kern.ready); - if (!backend->kern.ready(backend)) return -1; + if (!backend->kern.ready(backend)) return; } backend->queue = req->queue_next; if (backend->is_user) { - return vfs_backend_user_accept(req); + vfs_backend_user_accept(req); } else { assert(backend->kern.accept); - return backend->kern.accept(req); + backend->kern.accept(req); } } -int vfs_backend_user_accept(struct vfs_request *req) { +void vfs_backend_user_accept(struct vfs_request *req) { struct process *handler; struct fs_wait_response res = {0}; int len = 0; @@ -123,7 +123,7 @@ int vfs_backend_user_accept(struct vfs_request *req) { handler->handled_req = req; req->backend->user.handler = NULL; regs_savereturn(&handler->regs, 0); - return 0; + return; fail: panic_unimplemented(); // TODO } diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h index b4624fa..9dc6088 100644 --- a/src/kernel/vfs/request.h +++ b/src/kernel/vfs/request.h @@ -25,10 +25,7 @@ struct vfs_backend { } user; struct { bool (*ready)(struct vfs_backend *); - - // return value might be passed to caller - // TODO make return void - int (*accept)(struct vfs_request *); + void (*accept)(struct vfs_request *); } kern; }; }; @@ -59,13 +56,11 @@ struct vfs_request { }; /** Assigns the vfs_request to the caller, and dispatches the call */ -int vfsreq_create(struct vfs_request); -int vfsreq_finish(struct vfs_request *, int ret); +void vfsreq_create(struct vfs_request); +void vfsreq_finish(struct vfs_request *, int ret); -/** Try to accept an enqueued request - * @return same as _syscall_fs_wait, passed to it. except on calls to kern backend, where it returns the result of the fs op - also gets directly passed to caller. it's a mess */ -// TODO fix the return value mess -int vfs_backend_tryaccept(struct vfs_backend *); -int vfs_backend_user_accept(struct vfs_request *req); +/** Try to accept an enqueued request */ +void vfs_backend_tryaccept(struct vfs_backend *); +void vfs_backend_user_accept(struct vfs_request *req); void vfs_backend_refdown(struct vfs_backend *); diff --git a/src/kernel/vfs/root.c b/src/kernel/vfs/root.c index c7bd717..989c77e 100644 --- a/src/kernel/vfs/root.c +++ b/src/kernel/vfs/root.c @@ -130,17 +130,15 @@ static int handle(struct vfs_request *req, bool *ready) { } } -int vfs_root_accept(struct vfs_request *req) { +void vfs_root_accept(struct vfs_request *req) { if (req->caller) { bool ready = true; int ret = handle(req, &ready); if (ready) { - return vfsreq_finish(req, ret); - } else { - return -1; + vfsreq_finish(req, ret); } } else { - return vfsreq_finish(req, -1); + vfsreq_finish(req, -1); } } diff --git a/src/kernel/vfs/root.h b/src/kernel/vfs/root.h index f10fb85..3db958d 100644 --- a/src/kernel/vfs/root.h +++ b/src/kernel/vfs/root.h @@ -1,5 +1,5 @@ #pragma once #include <kernel/vfs/request.h> -int vfs_root_accept(struct vfs_request *); +void vfs_root_accept(struct vfs_request *); bool vfs_root_ready(struct vfs_backend *); |