diff options
author | Alex Auvolat <alex.auvolat@ens.fr> | 2015-03-08 14:48:55 +0100 |
---|---|---|
committer | Alex Auvolat <alex.auvolat@ens.fr> | 2015-03-08 14:48:55 +0100 |
commit | 0985c6237b8592652d57efee2a964c4bc91ee455 (patch) | |
tree | 1ac06e7c924f9d34d738e23694d4efbbe9725123 | |
parent | ad63830f0d841c41291fc01aed6e54726bd0b93f (diff) | |
download | kogata-0985c6237b8592652d57efee2a964c4bc91ee455.tar.gz kogata-0985c6237b8592652d57efee2a964c4bc91ee455.zip |
Implement missing syscalls.
-rw-r--r-- | src/common/include/syscallproto.h | 12 | ||||
-rw-r--r-- | src/kernel/user/syscall.c | 83 | ||||
-rw-r--r-- | src/lib/include/syscall.h | 10 | ||||
-rw-r--r-- | src/lib/libkogata/syscall.c | 21 |
4 files changed, 121 insertions, 5 deletions
diff --git a/src/common/include/syscallproto.h b/src/common/include/syscallproto.h index 9673cde..bbb49b3 100644 --- a/src/common/include/syscallproto.h +++ b/src/common/include/syscallproto.h @@ -2,12 +2,18 @@ #include <proc.h> +typedef int fd_t; +typedef int pid_t; +typedef struct { fd_t a, b; } fd_pair_t; + #define SC_MAX 128 // maximum number of syscalls #define SC_DBG_PRINT 0 // args: msg, msg_strlen #define SC_EXIT 1 // args: code #define SC_YIELD 2 // args: () #define SC_USLEEP 3 // args: usecs +#define SC_NEW_THREAD 4 // args: eip, esp +#define SC_EXIT_THREAD 5 // args: () #define SC_MMAP 10 // args: addr, size, mode #define SC_MMAP_FILE 11 // args: handle, offset, addr, size, mode @@ -57,12 +63,12 @@ typedef struct { const char* fs_name; size_t fs_name_strlen; - int source_fd; + fd_t source_fd; const char* opts; size_t opts_strlen; - int bind_to_pid; // zero = bind to current proc + pid_t bind_to_pid; // zero = bind to current proc } sc_make_fs_args_t; typedef struct { @@ -77,7 +83,7 @@ typedef struct { int ok_modes; - int bind_to_pid; // 0 = bind to current proc + pid_t bind_to_pid; // 0 = bind to current proc } sc_subfs_args_t; /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/kernel/user/syscall.c b/src/kernel/user/syscall.c index 04144d4..c352ff4 100644 --- a/src/kernel/user/syscall.c +++ b/src/kernel/user/syscall.c @@ -1,7 +1,9 @@ #include <string.h> + #include <process.h> #include <vfs.h> #include <elf.h> +#include <ipc.h> #include <sct.h> @@ -63,6 +65,15 @@ static uint32_t dbg_print_sc(sc_args_t args) { return 0; } +static uint32_t new_thread_sc(sc_args_t args) { + return process_new_thread(current_process(), (proc_entry_t)args.a, (void*)args.b); +} + +static uint32_t exit_thread_sc(sc_args_t args) { + exit(); + return 0; +} + // ---- Memory management related static uint32_t mmap_sc(sc_args_t args) { @@ -271,6 +282,72 @@ static uint32_t get_mode_sc(sc_args_t args) { return file_get_mode(h); } +// ---- IPC + +static uint32_t make_channel_sc(sc_args_t args) { + // messy messy messy + + bool blocking = (args.a != 0); + + fd_pair_t *f = (fd_pair_t*)args.b; + probe_for_write(f, sizeof(fd_pair_t)); + + f->a = f->b = 0; + + fs_handle_pair_t ch = make_channel(blocking); + + if (ch.a == 0 || ch.b == 0) goto error; + + f->a = proc_add_fd(current_process(), ch.a); + if (f->a == 0) goto error; + + f->b = proc_add_fd(current_process(), ch.b); + if (f->b == 0) goto error; + + return true; + +error: + if (f->a) { + proc_close_fd(current_process(), f->a); + f->a = 0; + } else { + if (ch.a) unref_file(ch.a); + } + if (f->b) { + proc_close_fd(current_process(), f->b); + f->b = 0; + } else { + if (ch.b) unref_file(ch.b); + } + return false; +} + +static uint32_t gen_token_sc(sc_args_t args) { + fs_handle_t *h = proc_read_fd(current_process(), args.a); + if (h == 0) return false; + + token_t *tok = (token_t*)args.b; + probe_for_write(tok, sizeof(token_t)); + + return gen_token_for(h, tok); +} + +static uint32_t use_token_sc(sc_args_t args) { + token_t *tok = (token_t*)args.a; + probe_for_read(tok, sizeof(token_t)); + + fs_handle_t *h = use_token(tok); + + if (h == 0) return 0; + + int fd = proc_add_fd(current_process(), h); + if (fd == 0) unref_file(h); + + return fd; + + return 0; //TODO +} + // ---- Managing file systems static uint32_t make_fs_sc(sc_args_t args) { @@ -544,6 +621,8 @@ void setup_syscall_table() { sc_handlers[SC_YIELD] = yield_sc; sc_handlers[SC_DBG_PRINT] = dbg_print_sc; sc_handlers[SC_USLEEP] = usleep_sc; + sc_handlers[SC_NEW_THREAD] = new_thread_sc; + sc_handlers[SC_EXIT_THREAD] = exit_thread_sc; sc_handlers[SC_MMAP] = mmap_sc; sc_handlers[SC_MMAP_FILE] = mmap_file_sc; @@ -564,6 +643,10 @@ void setup_syscall_table() { sc_handlers[SC_IOCTL] = ioctl_sc; sc_handlers[SC_GET_MODE] = get_mode_sc; + sc_handlers[SC_MK_CHANNEL] = make_channel_sc; + sc_handlers[SC_GEN_TOKEN] = gen_token_sc; + sc_handlers[SC_USE_TOKEN] = use_token_sc; + sc_handlers[SC_MAKE_FS] = make_fs_sc; sc_handlers[SC_FS_ADD_SRC] = fs_add_src_sc; sc_handlers[SC_SUBFS] = fs_subfs_sc; diff --git a/src/lib/include/syscall.h b/src/lib/include/syscall.h index b94c7fd..7579be3 100644 --- a/src/lib/include/syscall.h +++ b/src/lib/include/syscall.h @@ -9,14 +9,16 @@ #include <fs.h> #include <debug.h> +#include <token.h> -typedef int fd_t; -typedef int pid_t; +typedef void (*entry_t)(void*); void dbg_print(const char* str); void yield(); void exit(int code); void usleep(int usecs); +bool new_thread(entry_t entry, void* data); +void exit_thread(); bool mmap(void* addr, size_t size, int mode); bool mmap_file(fd_t file, size_t offset, void* addr, size_t size, int mode); @@ -37,6 +39,10 @@ bool stat_open(fd_t file, stat_t *s); int ioctl(fd_t file, int command, void* data); int get_mode(fd_t file); +fd_pair_t make_channel(bool blocking); +bool gen_token(fd_t file, token_t *tok); +fd_t use_token(token_t *tok); + bool make_fs(const char* name, const char* driver, fd_t source, const char* options); bool fs_add_source(const char* fs, fd_t source, const char* options); bool fs_subfs(const char* name, const char* orig_fs, const char* root, int ok_modes); diff --git a/src/lib/libkogata/syscall.c b/src/lib/libkogata/syscall.c index c79096e..7ae0283 100644 --- a/src/lib/libkogata/syscall.c +++ b/src/lib/libkogata/syscall.c @@ -39,6 +39,15 @@ void usleep(int usecs) { call(SC_USLEEP, usecs, 0, 0, 0, 0); } +bool new_thread(entry_t entry, void* data) { + // TODO + return false; +} + +void exit_thread() { + call(SC_EXIT_THREAD, 0, 0, 0, 0, 0); +} + bool mmap(void* addr, size_t size, int mode) { return call(SC_MMAP, (uint32_t)addr, size, mode, 0, 0); } @@ -90,6 +99,18 @@ int get_mode(fd_t file) { return call(SC_GET_MODE, file, 0, 0, 0, 0); } +fd_pair_t make_channel(bool blocking) { + fd_pair_t ret; + call(SC_MK_CHANNEL, blocking, (uint32_t)&ret, 0, 0, 0); + return ret; +} +bool gen_token(fd_t file, token_t *tok) { + return call(SC_GEN_TOKEN, file, (uint32_t)tok, 0, 0, 0); +} +fd_t use_token(token_t *tok) { + return call(SC_USE_TOKEN, (uint32_t)tok, 0, 0, 0, 0); +} + bool make_fs(const char* name, const char* driver, fd_t source, const char* options) { volatile sc_make_fs_args_t args = { .driver = driver, |