aboutsummaryrefslogtreecommitdiff
path: root/src/core/scheduler.cc
diff options
context:
space:
mode:
authorLoic Guegan <manzerbredes@mailbox.org>2021-05-02 14:46:18 +0200
committerLoic Guegan <manzerbredes@mailbox.org>2021-05-02 14:46:18 +0200
commite59104ffb55abe522c82d658f1f285149cca2cb1 (patch)
treeeb3cc1e46d0dd5b684864903b95ae32e245010da /src/core/scheduler.cc
parent4f08ba2b1d0ad7ea90d4d97a483b56b891b9c902 (diff)
Debug GDT enable multitasking
Diffstat (limited to 'src/core/scheduler.cc')
-rw-r--r--src/core/scheduler.cc91
1 files changed, 79 insertions, 12 deletions
diff --git a/src/core/scheduler.cc b/src/core/scheduler.cc
index 00741fe..fee5716 100644
--- a/src/core/scheduler.cc
+++ b/src/core/scheduler.cc
@@ -1,40 +1,107 @@
#include "scheduler.hpp"
+#include "boucane.hpp"
+#include "core/apic.hpp"
-TASK tasks[MAX_TASK];
-u32 ntasks=0;
+PROC procs[MAX_TASK];
+u32 nproc=0;
char show_ticks=0;
+char scheduling=0;
+u32 active_process=0;
extern "C" void clock(){
if(show_ticks)
print(".");
+ if(scheduling)
+ schedule();
}
void schedule(){
+ // First get a pointer to the first process saved register.
+ // Since this is called by clock(), %rbp contains a pointer
+ // to the clock() %rbp value and then we access to the registers SAVE_REGS in int.S
+ u64* stack;
+ asm("mov %%rbp, %%rax;mov (%%rax), %%rbx; add $16, %%rbx; mov %%rbx,%0": "=m"(stack)::"rax","rbx");
+
+ // Save current task
+ PROC *t=&procs[active_process];
+ t->registers.r8=stack[0];
+ t->registers.r9=stack[1];
+ t->registers.r10=stack[2];
+ t->registers.r11=stack[3];
+ t->registers.r12=stack[4];
+ t->registers.r13=stack[5];
+ t->registers.r14=stack[6];
+ t->registers.r15=stack[7];
+ t->registers.rdi=stack[8];
+ t->registers.rsi=stack[9];
+ t->registers.rbp=stack[10];
+ t->registers.rdx=stack[11];
+ t->registers.rcx=stack[12];
+ t->registers.rbx=stack[13];
+ t->registers.rax=stack[14];
+ t->registers.rip=stack[15];
+ t->registers.cs=stack[16];
+ t->registers.eflags=stack[17];
+ t->registers.rsp=stack[18];
+ t->registers.ds=stack[19];
+ // Goto next task
+ active_process++;
+ if(active_process>=nproc)
+ active_process=0;
+
+ t=&procs[active_process];
+ kvar_tss.rsp0=t->registers.rsp0;
+
+ // Clock acknownledgement
+ apic_ack();
+
+ asm volatile(
+ "mov %0, %%rdi \n\t"
+ "jmp switch \n\t"
+ :: "a" (t)
+ );
}
void create_task(void* task, u32 size){
- if(ntasks>=MAX_TASK){
+ if(nproc>=MAX_TASK){
printk("Could not create more tasks.");
return;
}
- TASK *t=&tasks[ntasks];
- t->id=ntasks;
- t->pid=ntasks;
+ PROC *t=&procs[nproc];
+ t->id=nproc;
+ t->pid=nproc;
t->size=size;
- t->pml4=paging_create_task(size/4096+1);
+
+ u32 npages=size%4096 ? size/4096 + 1 : size/4096;
+ // Note that paging_create_task() allocate 2 more pages (one for the user stack and
+ // the other for the kernel stack)
+ t->pml4=paging_create_task(npages);
+ t->registers.rsp=TASK_VMA+npages*4096+4096; // User stack
+ t->registers.rsp0=TASK_VMA+npages*4096+4096*2; // Kernel stack on the last page
+
+ t->registers.rip=TASK_VMA;
+ t->registers.cs=0x1B; // 0x18 and 0x3 privilege
+ t->registers.ds=0x23; // 0x20 and 0x3 privilege
// Load task using
lpml4(t->pml4);
memcpy(task, TASK_VMA, size);
lpml4(kpml4);
-
- ntasks++;
+
+ nproc++;
}
void scheduler_start(){
- TASK *t=&tasks[0];
- lpml4(t->pml4);
- asm("jmp switch");
+ scheduling=1;
+ active_process=0;
+ PROC *t=&procs[active_process];
+ kvar_tss.rsp0=t->registers.rsp0;
+ asm(
+ "cli \n\t"
+ "mov %0, %%rdi \n\t"
+ "jmp switch \n\t"
+ :: "r" (t)
+ );
} \ No newline at end of file