summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--api/obj.h23
-rw-r--r--api/syscall.h48
-rw-r--r--arch/x86_64/sys/serial.c16
-rw-r--r--arch/x86_64/sys/syscall.h5
-rw-r--r--hal/memory.h12
-rw-r--r--hal/obj.h15
-rw-r--r--hal/untyped.c54
-rw-r--r--jove.h3
-rw-r--r--sys/syscall.c4
-rw-r--r--sys/syscall.h32
-rw-r--r--sys/syscall_objdir.c46
-rw-r--r--sys/syscall_untyped.c69
-rw-r--r--sys/syscall_vtt.c17
14 files changed, 291 insertions, 55 deletions
diff --git a/Makefile b/Makefile
index cd8e128..76c913b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
include $(CONFIG)
include config.mk
-CDIRS := boot lib hal sys
+CDIRS := boot lib hal sys api
CDIRS += boot/$(TARGET_BOOTLOADER)
CFILES := $(wildcard *.c)
diff --git a/api/obj.h b/api/obj.h
new file mode 100644
index 0000000..4d5e829
--- /dev/null
+++ b/api/obj.h
@@ -0,0 +1,23 @@
+#ifndef _JOVE_API_OBJ_H
+#define _JOVE_API_OBJ_H 1
+
+#include <stdint.h>
+
+enum
+{
+ JOVE_OBJ_NONE = 0,
+ JOVE_OBJ_UNTYPED,
+ JOVE_OBJ_OBJDIR,
+ JOVE_OBJ_PAGEDIR,
+ JOVE_OBJ_PROCESSOR,
+ JOVE_OBJ_PROCESS,
+ JOVE_OBJ_PAGEFRAME,
+ JOVE_OBJ_INITRD_FILE,
+ JOVE_OBJ_FRAMEBUFFER,
+ JOVE_OBJ_VIRTTERM,
+ JOVE_OBJ_MESSAGE
+};
+
+typedef uint16_t objpath_part_t;
+
+#endif
diff --git a/api/syscall.h b/api/syscall.h
new file mode 100644
index 0000000..cf8b1c1
--- /dev/null
+++ b/api/syscall.h
@@ -0,0 +1,48 @@
+#ifndef _JOVE_API_SYSCALL_H
+#define _JOVE_API_SYSCALL_H 1
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "obj.h"
+
+struct syscall_header
+{
+ uint16_t callid;
+ uint16_t pathlen;
+ uint16_t path[];
+};
+
+#define SYSCALL_VTT_WRITE 0
+struct syscall_generic_write
+{
+ size_t len;
+ char data[];
+};
+
+#define SYSCALL_UNTYPED_SIZE 0
+#define SYSCALL_UNTYPED_ALIGN 1
+
+#define SYSCALL_UNTYPED_RETYPE 2
+struct syscall_untyped_retype
+{
+ uint16_t newtype;
+};
+
+#define SYSCALL_UNTYPED_SPLIT 3
+#define SYSCALL_UNTYPED_MERGE 4
+struct syscall_untyped_split
+{
+ size_t bytes;
+ uint16_t dest_pathlen;
+ objpath_part_t dest_path[];
+};
+struct syscall_generic_objpath
+{
+ uint16_t second_pathlen;
+ objpath_part_t second_path[];
+};
+
+#define SYSCALL_OBJDIR_OBJTYPE 0
+
+#endif
diff --git a/arch/x86_64/sys/serial.c b/arch/x86_64/sys/serial.c
index 48a14c7..12db6fd 100644
--- a/arch/x86_64/sys/serial.c
+++ b/arch/x86_64/sys/serial.c
@@ -9,15 +9,13 @@ s_syscall_serial_write(
size_t payload_bytes,
void *payload_data)
{
- if(payload_bytes < sizeof(struct syscall_serial_write)) {
- kprintf("syscall_serial_write: message is too small for this syscall!\n");
- return EOOB;
- }
- struct syscall_serial_write *payload = payload_data;
- if(payload_bytes < sizeof(struct syscall_serial_write) + payload->len) {
- kprintf("syscall_serial_write: message is to small for payload!\n");
- return EOOB;
- }
+ size_t bytes_needed = sizeof(struct syscall_generic_write);
+ CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for this syscall!");
+
+ struct syscall_generic_write *payload = payload_data;
+ bytes_needed += payload->len * 2;
+ CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for write buffer!");
+
return serial_com_write(serial_com, payload->data, payload->len);
}
diff --git a/arch/x86_64/sys/syscall.h b/arch/x86_64/sys/syscall.h
index 9138101..868ce0b 100644
--- a/arch/x86_64/sys/syscall.h
+++ b/arch/x86_64/sys/syscall.h
@@ -3,11 +3,6 @@
#include "sys/syscall.h"
-struct syscall_serial_write
-{
- size_t len;
- char data[];
-};
int _syscall_handle_serial(SYSCALL_FUNCTION_ARGS);
#define SYSCALL_SERIAL_COM_WRITE 0
diff --git a/hal/memory.h b/hal/memory.h
index 4d866d0..659263c 100644
--- a/hal/memory.h
+++ b/hal/memory.h
@@ -1,16 +1,24 @@
#ifndef _JOVE_HAL_MEMORY_H
#define _JOVE_HAL_MEMORY_H 1
-#include <stddef.h>
-#include <stdint.h>
+#include "obj.h"
typedef struct jove_obj_untyped
{
size_t limit;
} jove_untyped_t;
+#define JOVE_UNTYPED_MINSIZE 0x10
+
void mem_setup_untyped(void);
void *phys_tovirt(uintptr_t phys);
+size_t untyped_size(jove_owned_obj_t *tgt);
+size_t untyped_align(jove_owned_obj_t *tgt);
+
+int untyped_split(jove_owned_obj_t *tgt, jove_owned_obj_t *dst, size_t bytes);
+int untyped_merge(jove_owned_obj_t *a, jove_owned_obj_t *b);
+int untyped_retype(jove_owned_obj_t *tgt, uint8_t newtype);
+
#endif
diff --git a/hal/obj.h b/hal/obj.h
index 93825fd..7a6ab76 100644
--- a/hal/obj.h
+++ b/hal/obj.h
@@ -3,20 +3,7 @@
#include <stddef.h>
-enum
-{
- JOVE_OBJ_NONE = 0,
- JOVE_OBJ_UNTYPED,
- JOVE_OBJ_OBJDIR,
- JOVE_OBJ_PAGEDIR,
- JOVE_OBJ_PROCESSOR,
- JOVE_OBJ_PROCESS,
- JOVE_OBJ_PAGEFRAME,
- JOVE_OBJ_INITRD_FILE,
- JOVE_OBJ_FRAMEBUFFER,
- JOVE_OBJ_VIRTTERM,
- JOVE_OBJ_MESSAGE
-};
+#include "api/obj.h"
#ifdef __x86_64__
#include "arch/x86_64/hal/obj.h"
diff --git a/hal/untyped.c b/hal/untyped.c
new file mode 100644
index 0000000..243f3ec
--- /dev/null
+++ b/hal/untyped.c
@@ -0,0 +1,54 @@
+#include "arch/x86_64/hal/obj.h"
+#include "jove.h"
+#include "memory.h"
+
+size_t
+untyped_size(jove_owned_obj_t *tgt)
+{
+ return ((jove_untyped_t*)obj_deref(tgt))->limit;
+}
+
+size_t
+untyped_align(jove_owned_obj_t *tgt)
+{
+ return (uintptr_t)obj_deref(tgt) & 0xFFF;
+}
+
+int
+untyped_split(jove_owned_obj_t *tgt, jove_owned_obj_t *dst, size_t bytes)
+{
+ jove_untyped_t *tgt_untyped = obj_deref(tgt);
+ if(bytes < JOVE_UNTYPED_MINSIZE) return EBADARG;
+ if(tgt_untyped->limit - bytes < JOVE_UNTYPED_MINSIZE) return ETOOSMALL;
+
+ tgt_untyped->limit -= bytes;
+ obj_settype(dst, JOVE_OBJ_UNTYPED);
+ obj_setvalue(dst, (uintptr_t)tgt_untyped + tgt_untyped->limit);
+
+ jove_untyped_t *dst_untyped = obj_deref(dst);
+ dst_untyped->limit = bytes;
+ return 0;
+}
+
+int
+untyped_merge(jove_owned_obj_t *a, jove_owned_obj_t *b)
+{
+ jove_untyped_t *a_untyped = obj_deref(a);
+ jove_untyped_t *b_untyped = obj_deref(b);
+ if((uintptr_t)a_untyped + a_untyped->limit == (uintptr_t)b_untyped) {
+ return EBADARG;
+ }
+ if((uintptr_t)b_untyped + b_untyped->limit == (uintptr_t)a_untyped) {
+ return untyped_merge(b, a);
+ }
+
+ a_untyped->limit += b_untyped->limit;
+ obj_settype(b, JOVE_OBJ_NONE);
+ return 0;
+}
+
+int untyped_retype(jove_owned_obj_t *tgt, uint8_t newtype)
+{
+ obj_settype(tgt, newtype);
+ return 0;
+}
diff --git a/jove.h b/jove.h
index 05cd5cd..0c0b181 100644
--- a/jove.h
+++ b/jove.h
@@ -17,5 +17,8 @@ extern int errno;
#define EBADOBJ -1
#define EOOB -2
#define EBADPATH -3
+#define EBADARG -4
+#define ETOOSMALL -5
+#define ETOOBIG -6
#endif
diff --git a/sys/syscall.c b/sys/syscall.c
index 6c3fa33..68a5ae6 100644
--- a/sys/syscall.c
+++ b/sys/syscall.c
@@ -23,8 +23,8 @@ _syscall_handle_generic(
static const syscall_handle_t s_syscall_handles[128] = {
[JOVE_OBJ_NONE] = NULL,
- [JOVE_OBJ_UNTYPED] = _syscall_handle_generic,
- [JOVE_OBJ_OBJDIR] = _syscall_handle_generic,
+ [JOVE_OBJ_UNTYPED] = _syscall_handle_untyped,
+ [JOVE_OBJ_OBJDIR] = _syscall_handle_objdir,
[JOVE_OBJ_PAGEDIR] = _syscall_handle_generic,
[JOVE_OBJ_PROCESSOR] = _syscall_handle_generic,
[JOVE_OBJ_PROCESS] = _syscall_handle_generic,
diff --git a/sys/syscall.h b/sys/syscall.h
index 6ad221f..ea75152 100644
--- a/sys/syscall.h
+++ b/sys/syscall.h
@@ -1,15 +1,27 @@
#ifndef _JOVE_SYS_SYSCALL_H
#define _JOVE_SYS_SYSCALL_H 1
+#include "api/syscall.h"
#include "hal/obj.h"
#include <stdint.h>
-struct syscall_header
-{
- uint16_t callid;
- uint16_t pathlen;
- uint16_t path[];
-};
+#define CHECK_TOOSMALL(required, present, fail_msg) \
+ do { if(present < required) { \
+ kprintf("%s: %s\n", __func__, fail_msg); \
+ return ETOOSMALL; \
+ } } while(0)
+
+#define CHECK_OBJEXISTS(obj, fail_msg) \
+do { if(obj == NULL) { \
+ kprintf("%s: %s\n", __func__, fail_msg); \
+ return EBADOBJ; \
+} } while(0)
+
+#define CHECK_OBJTYPE(obj, type, fail_msg) \
+ do { if(obj_gettype(obj) != type) { \
+ kprintf("%s: %s\n", __func__, fail_msg); \
+ return EBADOBJ; \
+ } } while(0)
#define SYSCALL_FUNCTION_ARGS \
jove_owned_obj_t*, /*PCB object*/ \
@@ -25,12 +37,8 @@ typedef int (*syscall_handle_t)(SYSCALL_FUNCTION_ARGS);
int _syscall_handle_generic(SYSCALL_FUNCTION_ARGS);
int _syscall_handle_arch(SYSCALL_FUNCTION_ARGS);
-#define SYSCALL_VTT_WRITE 0
-struct syscall_vtt_write
-{
- size_t len;
- char data[];
-};
int _syscall_handle_vtt(SYSCALL_FUNCTION_ARGS);
+int _syscall_handle_objdir(SYSCALL_FUNCTION_ARGS);
+int _syscall_handle_untyped(SYSCALL_FUNCTION_ARGS);
#endif
diff --git a/sys/syscall_objdir.c b/sys/syscall_objdir.c
new file mode 100644
index 0000000..cf1e5b7
--- /dev/null
+++ b/sys/syscall_objdir.c
@@ -0,0 +1,46 @@
+#include "hal/process.h"
+#include "jove.h"
+#include "lib/printf.h"
+#include "syscall.h"
+
+int
+s_syscall_objdir_objtype(
+ jove_owned_obj_t *objdir,
+ jove_owned_obj_t *target_dir,
+ size_t payload_size,
+ void *payload_data)
+{
+ int bytes_needed = sizeof(struct syscall_generic_objpath);
+ CHECK_TOOSMALL(bytes_needed, payload_size, "Message is too small for this payload!");
+
+ struct syscall_generic_objpath *payload = payload_data;
+ bytes_needed += payload->second_pathlen * 2;
+ CHECK_TOOSMALL(bytes_needed, payload_size, "Message is too small for second target path!");
+
+ int retval = 0;
+ jove_owned_obj_t *second_obj = objdir_getobj(objdir, payload->second_path, payload->second_pathlen);
+ CHECK_OBJEXISTS(second_obj, "Second target does not exist!");
+
+ retval = obj_gettype(second_obj);
+ obj_release(second_obj);
+ return retval;
+}
+
+int
+_syscall_handle_objdir(
+ 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)
+{
+ switch(header->callid) {
+ case SYSCALL_OBJDIR_OBJTYPE:
+ return s_syscall_objdir_objtype(objdir, target_obj, bytes_left, payload);
+ default:
+ kprintf("syscall_handle_objdir: Objdir does not support syscall %i\n", header->callid);
+ return EOOB;
+ }
+}
diff --git a/sys/syscall_untyped.c b/sys/syscall_untyped.c
new file mode 100644
index 0000000..52a0715
--- /dev/null
+++ b/sys/syscall_untyped.c
@@ -0,0 +1,69 @@
+#include "arch/x86_64/hal/obj.h"
+#include "hal/memory.h"
+#include "jove.h"
+#include "lib/printf.h"
+#include "syscall.h"
+
+static int
+s_syscall_untyped_split(
+ jove_owned_obj_t *objdir,
+ jove_owned_obj_t *target_obj,
+ size_t payload_bytes,
+ void *payload_data)
+{
+ int bytes_needed = sizeof(struct syscall_untyped_split);
+ CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for payload!");
+
+ struct syscall_untyped_split *payload = payload_data;
+ bytes_needed += payload->dest_pathlen * 2;
+ CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for destination path!");
+
+ jove_owned_obj_t *dst_obj = objdir_getobj(objdir, payload->dest_path, payload->dest_pathlen);
+ CHECK_OBJTYPE(dst_obj, JOVE_OBJ_NONE, "Destination path is occupied!");
+
+ return untyped_split(target_obj, dst_obj, payload->bytes);
+}
+
+static int
+s_syscall_untyped_merge(
+ jove_owned_obj_t *objdir,
+ jove_owned_obj_t *target_obj,
+ size_t payload_bytes,
+ void *payload_data)
+{
+ int bytes_needed = sizeof(struct syscall_generic_objpath);
+ CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for payload!");
+
+ struct syscall_generic_objpath *payload = payload_data;
+ bytes_needed += payload->second_pathlen * 2;
+ CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for second path!");
+
+ jove_owned_obj_t *snd_obj = objdir_getobj(objdir, payload->second_path, payload->second_pathlen);
+ CHECK_OBJTYPE(snd_obj, JOVE_OBJ_UNTYPED, "Second object is not an untyped!");
+
+ return untyped_merge(target_obj, snd_obj);
+}
+
+
+int _syscall_handle_untyped(
+ 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 payload_bytes,
+ void* payload)
+{
+ switch(header->callid) {
+ case SYSCALL_UNTYPED_SIZE:
+ return untyped_size(target_obj);
+ case SYSCALL_UNTYPED_ALIGN:
+ return untyped_align(target_obj);
+ case SYSCALL_UNTYPED_SPLIT:
+ return s_syscall_untyped_split(objdir, target_obj, payload_bytes, payload);
+ default:
+ kprintf("syscall_untyped: Untyped object does not support syscall %i\n", header->callid);
+ return EBADARG;
+ }
+ return 0;
+}
diff --git a/sys/syscall_vtt.c b/sys/syscall_vtt.c
index 4b58b2c..4dadd6c 100644
--- a/sys/syscall_vtt.c
+++ b/sys/syscall_vtt.c
@@ -9,16 +9,13 @@ s_syscall_vtt_write(
size_t payload_bytes,
void *payload_data)
{
- if(payload_bytes < sizeof(struct syscall_vtt_write)) {
- kprintf("syscall_vtt_write: message is too small for this syscall!\n");
- return EOOB;
- }
- struct syscall_vtt_write *payload = payload_data;
- if(payload_bytes < sizeof(struct syscall_vtt_write) + payload->len) {
- kprintf("syscall_vtt_write: message is to small for payload! (%i vs %i)\n",
- payload->len, payload_bytes);
- return EOOB;
- }
+ size_t bytes_needed = sizeof(struct syscall_generic_write);
+ CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for this syscall!");
+
+ struct syscall_generic_write *payload = payload_data;
+ bytes_needed += payload->len * 2;
+ CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for write buffer!");
+
return vt_write(vtt, payload->data, payload->len);
}