aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-03-08 14:48:55 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-03-08 14:48:55 +0100
commit0985c6237b8592652d57efee2a964c4bc91ee455 (patch)
tree1ac06e7c924f9d34d738e23694d4efbbe9725123 /src
parentad63830f0d841c41291fc01aed6e54726bd0b93f (diff)
downloadkogata-0985c6237b8592652d57efee2a964c4bc91ee455.tar.gz
kogata-0985c6237b8592652d57efee2a964c4bc91ee455.zip
Implement missing syscalls.
Diffstat (limited to 'src')
-rw-r--r--src/common/include/syscallproto.h12
-rw-r--r--src/kernel/user/syscall.c83
-rw-r--r--src/lib/include/syscall.h10
-rw-r--r--src/lib/libkogata/syscall.c21
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,