diff options
Diffstat (limited to 'arch/x86_64/tasking.c')
-rw-r--r-- | arch/x86_64/tasking.c | 93 |
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; +} |