diff options
| author | Aleksa Vuckovic <aleksa@vuckovic.cc> | 2023-02-26 13:22:31 +0100 |
|---|---|---|
| committer | Aleksa Vuckovic <aleksa@vuckovic.cc> | 2023-02-26 13:22:31 +0100 |
| commit | a164ca67174ba6179170dea573479f23122513cc (patch) | |
| tree | 88bd5afa1633449e0db867cb480b9d772c96c1f6 | |
| parent | 950649760927a7c33ddecd1944fd0ad20e731ee9 (diff) | |
process.c
| -rw-r--r-- | kernel/Makefile | 1 | ||||
| -rw-r--r-- | kernel/include/process.h | 21 | ||||
| -rw-r--r-- | kernel/include/scheduler.h | 4 | ||||
| -rw-r--r-- | kernel/include/timer.h | 1 | ||||
| -rw-r--r-- | kernel/src/devices/timer.c | 16 | ||||
| -rw-r--r-- | kernel/src/scheduler/process.c | 60 | ||||
| -rw-r--r-- | kernel/src/scheduler/scheduler.c | 8 | ||||
| -rw-r--r-- | kernel/src/scheduler/switch.S | 4 |
8 files changed, 106 insertions, 9 deletions
diff --git a/kernel/Makefile b/kernel/Makefile index 741e158..5e6cb9d 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -41,6 +41,7 @@ OBJS = \ src/scheduler/ap_init.o \ src/scheduler/ap_startup.o \ src/scheduler/atomic.o \ + src/scheduler/process.o \ src/scheduler/scheduler.o \ src/scheduler/switch.o \ src/sys/syscall_asm.o \ diff --git a/kernel/include/process.h b/kernel/include/process.h new file mode 100644 index 0000000..ff82924 --- /dev/null +++ b/kernel/include/process.h @@ -0,0 +1,21 @@ +#ifndef PROCESS_H +#define PROCESS_H + +#include <types.h> +#include <libk/list.h> + +void save_context_to_rsp(uint64_t irq_rsp, uint64_t task_rsp); +__attribute__((noreturn)) void restore_context_from_rsp(uint64_t task_rsp); + +struct process_t { + uint64_t rsp; + list_t list; +}; +typedef struct process_t process_t; + +extern process_t process_queue; +extern process_t *curr_process; + +__attribute__((noreturn)) void context_switch(uint64_t irq_rsp); + +#endif diff --git a/kernel/include/scheduler.h b/kernel/include/scheduler.h index 2f751f0..73a9d2b 100644 --- a/kernel/include/scheduler.h +++ b/kernel/include/scheduler.h @@ -1,6 +1,8 @@ #ifndef SCHEDULER_H #define SCHEDULER_H -void scheduler(void); +#include <process.h> + +process_t *scheduler(void); #endif diff --git a/kernel/include/timer.h b/kernel/include/timer.h index 899f09f..a86bfe7 100644 --- a/kernel/include/timer.h +++ b/kernel/include/timer.h @@ -4,6 +4,7 @@ #include <types.h> #define TICKS_PER_SECOND 1000 +#define CONTEXT_SWITCHES_PER_SECOND 20 void timer_handler(uint64_t rsp); void wait(uint64_t ms); diff --git a/kernel/src/devices/timer.c b/kernel/src/devices/timer.c index 0f6fc20..7971b20 100644 --- a/kernel/src/devices/timer.c +++ b/kernel/src/devices/timer.c @@ -4,8 +4,10 @@ #include <libk/list.h> #include <io.h> #include <idt.h> +#include <process.h> -uint32_t tick = 0; +uint32_t scheduler_ticks = 0; +uint32_t seconds_tick = 0; uint32_t seconds = 0; struct wait_queue { @@ -23,12 +25,16 @@ void timer_handler(uint64_t rsp) pos->ticks--; } - tick++; - - if (tick >= TICKS_PER_SECOND) { - tick = 0; + seconds_tick++; + if (seconds_tick >= TICKS_PER_SECOND) { + seconds_tick = 0; seconds++; } + scheduler_ticks++; + if (scheduler_ticks >= TICKS_PER_SECOND / CONTEXT_SWITCHES_PER_SECOND) { + scheduler_ticks = 0; +/* context_switch(rsp); */ + } } void wait(uint64_t ms) diff --git a/kernel/src/scheduler/process.c b/kernel/src/scheduler/process.c index e69de29..e85cc11 100644 --- a/kernel/src/scheduler/process.c +++ b/kernel/src/scheduler/process.c @@ -0,0 +1,60 @@ +#include <types.h> +#include <regs.h> +#include <heap.h> +#include <scheduler.h> +#include <libk/list.h> +#include <process.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) +{ + 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)); + + regs->rax = 0; + regs->rbx = 0; + regs->rcx = 0; + regs->rdx = rdx; + regs->rdi = rdi; + regs->rsi = rsi; + regs->rsp = rsp; + regs->rbp = 0; + regs->r8 = 0; + regs->r9 = 0; + regs->r10 = 0; + regs->r11 = 0; + regs->r12 = 0; + regs->r13 = 0; + regs->r14 = 0; + regs->r15 = 0; + regs->rip = rip; + regs->rflags = 0; + regs->error = 0; + + if (priv_lvl == 0) { + regs->cs = 0x8; + regs->ss = 0x10; + regs->seg = 0x0010001000100010; + } else { + regs->cs = 0x23; + regs->ss = 0x1b; + regs->seg = 0x001b001b001b001b; + } + + process_t *new_process = (process_t *)kalloc(sizeof(process_t)); + add_to_list(&new_process->list, &process_queue.list, + process_queue.list.next); +} + +__attribute__((noreturn)) void context_switch(uint64_t irq_rsp) +{ + save_context_to_rsp(irq_rsp, curr_process->rsp); + + process_t *next_process = scheduler(); + + restore_context_from_rsp(next_process->rsp); +} diff --git a/kernel/src/scheduler/scheduler.c b/kernel/src/scheduler/scheduler.c index b8f3dab..263c11a 100644 --- a/kernel/src/scheduler/scheduler.c +++ b/kernel/src/scheduler/scheduler.c @@ -1,6 +1,12 @@ #include <types.h> #include <scheduler.h> +#include <libk/list.h> +#include <process.h> -void schedule(void) +process_t *scheduler(void) { + process_t *pos = curr_process; + process_t *next_process = list_next_entry(pos, list); + + return next_process; } diff --git a/kernel/src/scheduler/switch.S b/kernel/src/scheduler/switch.S index 4e216e0..4d5dfb6 100644 --- a/kernel/src/scheduler/switch.S +++ b/kernel/src/scheduler/switch.S @@ -2,7 +2,7 @@ /* %rdi - irq's rsp */ /* %rsi - task's rsp */ -.global save_to_rsp +.global save_context_to_rsp save_context_to_rsp: mov %rsi, %rsp push SS_OFF(%rdi) @@ -29,7 +29,7 @@ save_context_to_rsp: push R15_OFF(%rdi) /* %rdi - task's rsp */ -.global restore_from_rsp +.global restore_context_from_rsp restore_context_from_rsp: mov %rdi, %rsp pop_callee_saved |
