diff options
| author | Aleksa Vuckovic <aleksa@vuckovic.cc> | 2023-02-27 01:59:33 +0100 |
|---|---|---|
| committer | Aleksa Vuckovic <aleksa@vuckovic.cc> | 2023-02-27 01:59:33 +0100 |
| commit | 15f3911599a8d005edee46247470afe2a7a0b4aa (patch) | |
| tree | 3113b84e1ddddc1f4937ca5596d8e32aacc4f51f /kernel/src/scheduler/process.c | |
| parent | a164ca67174ba6179170dea573479f23122513cc (diff) | |
almost done multitasking
Diffstat (limited to 'kernel/src/scheduler/process.c')
| -rw-r--r-- | kernel/src/scheduler/process.c | 96 |
1 files changed, 84 insertions, 12 deletions
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 <heap.h> #include <scheduler.h> #include <libk/list.h> +#include <libk/stdio.h> #include <process.h> +#include <timer.h> +#include <panic.h> 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); } |
