summaryrefslogtreecommitdiff
path: root/kernel/src/scheduler/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/src/scheduler/process.c')
-rw-r--r--kernel/src/scheduler/process.c96
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);
}