From 15f3911599a8d005edee46247470afe2a7a0b4aa Mon Sep 17 00:00:00 2001 From: Aleksa Vuckovic Date: Mon, 27 Feb 2023 01:59:33 +0100 Subject: almost done multitasking --- kernel/src/scheduler/process.c | 96 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 84 insertions(+), 12 deletions(-) (limited to 'kernel/src/scheduler/process.c') diff --git a/kernel/src/scheduler/process.c b/kernel/src/scheduler/process.c index e85cc11..e7ef7e5 100644 --- a/kernel/src/scheduler/process.c +++ b/kernel/src/scheduler/process.c @@ -3,24 +3,27 @@ #include #include #include +#include #include +#include +#include process_t process_queue; process_t *curr_process; -void init_process(uint64_t priv_lvl, uint64_t rip, uint64_t rdi, uint64_t rsi, - uint64_t rdx) +process_t *init_process(uint64_t priv_lvl, uint64_t rip, uint64_t argc, + uint64_t *argv) { uint32_t stack_size = 32 * 1024; - uint64_t rsp = (uint64_t)kalloc(stack_size) + stack_size; - regs_t *regs = (regs_t *)(rsp + sizeof(regs_t)); + uint64_t rsp = (uint64_t)kalloc(stack_size) + stack_size - 8; + regs_t *regs = (regs_t *)(rsp - sizeof(regs_t)); regs->rax = 0; regs->rbx = 0; regs->rcx = 0; - regs->rdx = rdx; - regs->rdi = rdi; - regs->rsi = rsi; + regs->rdx = (uint64_t)argv; + regs->rdi = rip; + regs->rsi = argc; regs->rsp = rsp; regs->rbp = 0; regs->r8 = 0; @@ -31,7 +34,7 @@ void init_process(uint64_t priv_lvl, uint64_t rip, uint64_t rdi, uint64_t rsi, regs->r13 = 0; regs->r14 = 0; regs->r15 = 0; - regs->rip = rip; + regs->rip = (uint64_t)process_init_wrapper; regs->rflags = 0; regs->error = 0; @@ -46,15 +49,84 @@ void init_process(uint64_t priv_lvl, uint64_t rip, uint64_t rdi, uint64_t rsi, } process_t *new_process = (process_t *)kalloc(sizeof(process_t)); + new_process->rsp = rsp - sizeof(regs_t); add_to_list(&new_process->list, &process_queue.list, process_queue.list.next); + return new_process; } -__attribute__((noreturn)) void context_switch(uint64_t irq_rsp) +void process_init_wrapper(uint64_t rip, uint64_t argc, uint64_t *argv) +{ + void (*f)(uint64_t rdi, ...) = (void (*)(uint64_t rdi, ...))rip; + switch (argc) { + case 0: + (*f)(argv[0]); + break; + case 1: + (*f)(argv[0]); + break; + case 2: + (*f)(argv[0], argv[1]); + break; + case 3: + (*f)(argv[0], argv[1], argv[2]); + break; + case 4: + (*f)(argv[0], argv[1], argv[2], argv[3]); + break; + case 5: + (*f)(argv[0], argv[1], argv[2], argv[3], argv[4]); + break; + default: + (*f)(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); + break; + } + kfree(argv); + remove_current_process(); +} + +__attribute__((noreturn)) void idle_thread() +{ + uint64_t x = 0; + __asm__ __volatile__("mov %%rsp, %0;" : "=r"(x) : :); + printf("current rsp: 0x%x\n", x); + printf("idle_thread()\n"); + for (;;) { + printf("1"); + wait(2000); + __asm__ __volatile__("pause; hlt;"); + } +} + +__attribute__((noreturn)) void idle_thread2() { - save_context_to_rsp(irq_rsp, curr_process->rsp); + printf("idle_thread2()\n"); + for (;;) { + printf("2"); + wait(1000); + __asm__ __volatile__("pause; hlt;"); + } +} - process_t *next_process = scheduler(); +__attribute__((noreturn)) void remove_current_process() +{ + free_node(&curr_process->list); + kfree(curr_process); + curr_process = scheduler(); + if (curr_process == NULL) { + printf("no processes left\n"); + for (;;) { + __asm__ __volatile__("pause; hlt;"); + } + } + restore_context_from_rsp(curr_process->rsp); +} - restore_context_from_rsp(next_process->rsp); +__attribute__((noreturn)) void context_switch(uint64_t irq_rsp) +{ + printf("irq_rsp: 0x%x\n", irq_rsp); + print_regs_from_rsp(irq_rsp); + curr_process->rsp = save_context_from_rsp(irq_rsp); + curr_process = scheduler(); + restore_context_from_rsp(curr_process->rsp); } -- cgit v1.2.3