diff options
| author | Loic Guegan <manzerbredes@mailbox.org> | 2021-05-02 14:46:18 +0200 |
|---|---|---|
| committer | Loic Guegan <manzerbredes@mailbox.org> | 2021-05-02 14:46:18 +0200 |
| commit | e59104ffb55abe522c82d658f1f285149cca2cb1 (patch) | |
| tree | eb3cc1e46d0dd5b684864903b95ae32e245010da /src/core/scheduler.cc | |
| parent | 4f08ba2b1d0ad7ea90d4d97a483b56b891b9c902 (diff) | |
Debug GDT enable multitasking
Diffstat (limited to 'src/core/scheduler.cc')
| -rw-r--r-- | src/core/scheduler.cc | 91 |
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 |
