summaryrefslogtreecommitdiffstats
path: root/arch/x86_64/tasking.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/tasking.c')
-rw-r--r--arch/x86_64/tasking.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/arch/x86_64/tasking.c b/arch/x86_64/tasking.c
new file mode 100644
index 0000000..fe6ecdb
--- /dev/null
+++ b/arch/x86_64/tasking.c
@@ -0,0 +1,93 @@
+#include "tsk/tasking.h"
+#include "mem/memory.h"
+#include "io/log.h"
+#include "lib/hashtable.h"
+#include "lib/string.h"
+#include "paging.h"
+#include "cpu.h"
+#include "tss.h"
+
+struct TaskBody {
+ struct Task base;
+ struct PageDirectory *pd;
+ struct Registers state;
+};
+
+struct Task *task_current;
+uintptr_t _kernel_task_bp = 0;
+
+//static struct SLinkedList s_tasks;
+static struct HashTable s_tasks;
+
+static struct SlabCache s_task_cache;
+static struct SlabCache s_kbp_cache;
+
+static tid_t s_task_id_next = 1;
+
+static size_t
+s_task_hash_func(const void* tid, size_t _)
+{
+ return (tid_t)tid;
+}
+
+void
+tasking_setup(void)
+{
+ hashtable_new(&s_tasks, struct TaskBody*, tid_t);
+ s_tasks.hash_function = s_task_hash_func;
+
+ mem_slabcache_new(&s_task_cache, "tasks", sizeof(struct TaskBody));
+ mem_slabcache_new(&s_kbp_cache, "kernel stacks", 4096);
+
+ struct TaskBody *ktask = mem_slab_alloc(&s_task_cache);
+ *ktask = (struct TaskBody){
+ .base.id = s_task_id_next++,
+ .base.kbp = ((uintptr_t)mem_slab_alloc(&s_kbp_cache)) + 0xFF0,
+ .base.perm = (size_t)-1,
+ .pd = mem_current_pd
+ };
+ hashtable_insert(&s_tasks, 0, ktask);
+
+ task_current = (struct Task*)ktask;
+ tss_set_rsp(0, task_current->kbp);
+ _kernel_task_bp = task_current->kbp;
+}
+
+struct Task*
+task_new(struct Task *parent)
+{
+ struct TaskBody *new = mem_slab_alloc(&s_task_cache);
+ memcpy(new, parent, sizeof(struct TaskBody));
+ new->base.id = s_task_id_next++;
+
+ uintptr_t ksp_base = (uintptr_t)mem_slab_alloc(&s_kbp_cache);
+ new->base.kbp = ksp_base + 0xFFF;
+ new->base.perm = parent->perm;
+
+ hashtable_insert(&s_tasks, (void*)new->base.id, new);
+ return (struct Task*)new;
+}
+
+struct Task*
+task_get(tid_t id)
+{
+ struct Task **task = hashtable_get(&s_tasks, (void*)id, struct Task*);
+ if(task == NULL) return NULL;
+ return *task;
+}
+
+void
+task_free(struct Task *task)
+{
+ struct TaskBody *body = (struct TaskBody*)task;
+ body->pd->references--;
+ task->kbp -= 0xFFF;
+ mem_slab_free(&s_kbp_cache, (void*)(task->kbp));
+ klogf("Need impl for task_free\n");
+}
+
+void*
+task_get_pd(struct Task *task)
+{
+ return ((struct TaskBody*)task)->pd;
+}