commit d06837bca243482704cb1f5077d0c180a88f17f9 from: Onana Onana Xavier Manuel date: Fri Sep 11 13:57:34 2026 UTC Setup Round Robin scheduling with APIC commit - 17683e896fc6162a038d5fb2711ca94055188dfb commit + d06837bca243482704cb1f5077d0c180a88f17f9 blob - 89788503a89a7d78c692d45b4e8240c5b2eaa64f blob + 0cedacc0e680a7dd1060bcee065eeaf36a744393 --- alpha/main.c +++ alpha/main.c @@ -22,18 +22,13 @@ void alpha_main(struct mmap *km) { struct task *t = task_new((void *)XHCI_ENTRY); - struct sysc_context_switch scs; + u64 *ptr = (u64 *)0; if (t == nil) send_msg("alpha: failed to create task!\n"); send_msg("alpha: running\n"); - scs.sysc.type = SYSC_CONTEXT_SWITCH; - scs.threadid = t->thread; - - sys_send((struct sysc *)&scs); - for (;;); } blob - c03eeaa10e4b75159709cacf3ae014e5987bf1f1 blob + 30b8a7dd5b4fe5fe44a7d27e8602741b79984258 --- kernel/idt.c +++ kernel/idt.c @@ -1,5 +1,7 @@ #include "kdebug.h" #include "types.h" +#include "kpic.h" +#include "kthreads.h" #define APIC_EOI_REG ((volatile u32*)0xFEE000B0) @@ -112,10 +114,19 @@ general_protection_handler_c() u64 tint = 0; -void +struct thread* timer_handler_c() { - kprint("Timer interrupt: "); kprinti(tint++); kprint("\n"); + struct thread *next; + next = thread_next(); + + if (next != nil) { + tss_switch_rsp0((u64)next->base + PAGE_SIZE * 3); + cthread = next; + } + *APIC_EOI_REG = 0; // Tells register interrupt was received + + return next; } blob - 34ebc5a87627fa395b52dc5677e1bf73d40d3eaa blob + b2366e527a26372c6ecb83786edcd572fdce0e7c --- kernel/kgdt.c +++ kernel/kgdt.c @@ -122,3 +122,9 @@ setup_tss() gdt.tss.ubase = (base >> 32) & 0xff; gdt.tss.reserved = 0; } + +void +tss_switch_rsp0(u64 rsp0) +{ + tss.rsp0 = rsp0; +} blob - 5ebcf6e1480e25bb0cbe91bb902bdc7fb8c72303 blob + cdc2d5b4dc9a349890c07f32c786f010284c9a41 --- kernel/kmain.c +++ kernel/kmain.c @@ -50,10 +50,8 @@ kloop(struct module *amodule, struct mmap *ammap) { struct thread *athread = thread_create((void (*)(void))(u64)amodule->entry); - if (athread == nil) { + if (athread == nil) kprint("Failed to create thread\n"); - repeat: goto repeat; - } thread_schedule(ammap, athread); } blob - d211bc91c43c414d564c555a3e919631416d419e blob + 5d47634680e64c171b408ace77a8a70e18c5ad0f --- kernel/kpic.h +++ kernel/kpic.h @@ -1,3 +1,4 @@ #pragma once void kpic_setup(void); +void tss_switch_rsp0(u64 rsp0); blob - 2accf334df9298693dd6ee50980ab5275610c0a0 blob + fe438fa7f5b494e80edf47a178b5aaf4e06d97f9 --- kernel/kthreads.c +++ kernel/kthreads.c @@ -1,4 +1,5 @@ #include "types.h" +#include "kpic.h" #include "kmmap.h" #include "kdebug.h" #include "kthreads.h" @@ -6,7 +7,7 @@ #define MAX_USER_THREADS 64 static struct thread uthreads[MAX_USER_THREADS]; -static struct thread *cthread; +struct thread *cthread; struct thread* thread_create(void (*entry)(void)) @@ -28,7 +29,7 @@ thread_create(void (*entry)(void)) return nil; } - thread->base = allocate_memory(PAGE_SIZE); + thread->base = allocate_memory(PAGE_SIZE * 3); if (thread->base == nil) { thread->assigned = 0; @@ -36,11 +37,13 @@ thread_create(void (*entry)(void)) } usp = (u64)thread->base + PAGE_SIZE; - sp = (u64 *)((u8*)thread->base + PAGE_SIZE); + sp = (u64 *)((u8*)thread->base + PAGE_SIZE * 3); + *(--sp) = 0x1B; // user SS/DS see kgdt.c *(--sp) = usp; // user sp - *(--sp) = (u64)entry; // RIP *(--sp) = 0x202; // RFLAGS + *(--sp) = 0x23; // User CS + *(--sp) = (u64)entry; // RIP *(--sp) = 0; // rbp *(--sp) = 0; // rbx @@ -50,6 +53,7 @@ thread_create(void (*entry)(void)) *(--sp) = 0; // r15 thread->top = sp; thread->rsp = (u64)sp; + thread->state = THREAD_READY; return thread; } @@ -68,32 +72,15 @@ thread_getuid(struct thread *th) // This is defined in switch.s void start_alpha(struct mmap *ammap, struct thread *thread); -void switch_context(struct thread *old, struct thread *new); void thread_schedule(struct mmap *ammap, struct thread *th) { cthread = th; + tss_switch_rsp0((u64)th->base + PAGE_SIZE * 3); start_alpha(ammap, th); - - repeat: goto repeat; } -void -thread_switch(struct thread *th) -{ - struct thread *othread; - - if (th == cthread) { - kprint("Huh?\n"); - return; - } - - othread = cthread; - cthread = th; - switch_context(othread, cthread); -} - struct thread* thread_get_uthread(u64 id) { @@ -101,3 +88,20 @@ thread_get_uthread(u64 id) return &uthreads[id]; return nil; } + +struct thread* +thread_next() +{ + s64 cid = thread_getuid(cthread); + s64 uid = cid; + + for (u64 count = 0; count < MAX_USER_THREADS; count++) { + uid = (uid + 1) % MAX_USER_THREADS; + + struct thread *th = &uthreads[uid]; + + if (th->assigned) + return th; + } + return nil; +} blob - b962ab43fc5883d0f878a41c640fde2977e15761 blob + db7769a823069ca6a111484422253a3d2584125a --- kernel/kthreads.h +++ kernel/kthreads.h @@ -13,11 +13,13 @@ struct thread { u64 rsp; u8 assigned; - enum thread_state sate; + enum thread_state state; }; +extern struct thread *cthread; + struct thread *thread_create(void (*entry)(void)); s64 thread_getuid(struct thread *th); void thread_schedule(struct mmap *, struct thread *); -void thread_switch(struct thread *); +struct thread* thread_next(void); struct thread *thread_get_uthread(u64 id); blob - 086afdfc65590671baca91ac1a342feeec475041 blob + f575e2ff8206bacbd765276605e8d4a67a36add4 --- kernel/lidt.s +++ kernel/lidt.s @@ -1,6 +1,7 @@ [bits 64] global load_idt +extern cthread global debug_exception_handler extern debug_exception_handler_c @@ -38,5 +39,35 @@ general_protection_handler: hlt timer_handler: + cli + push rbp + push rbx + push r12 + push r13 + push r14 + push r15 + + mov rax, [rel cthread] + test rax, rax + jz .schedule + + mov [rax + RSP_OFFSET], rsp + +.schedule: call timer_handler_c + + test rax, rax + jz .same_thread + mov rsp, [rax + RSP_OFFSET] + +.same_thread: + pop r15 + pop r14 + pop r13 + pop r12 + pop rbx + pop rbp + iretq + +RSP_OFFSET equ 16 blob - 3f9d9b17844b3cce85cd36d45a2155f652ce8dbd blob + 616bc48d63becb64fdcaab0c1cbdb7d1689e51f1 --- kernel/switch.s +++ kernel/switch.s @@ -2,36 +2,11 @@ ; ; We are forced to push rbp-r15 because SystemV -global switch_context global start_alpha start_alpha: cli - push rbp - push rbx - push r12 - push r13 - push r14 - push r15 - - jmp switch_context.load - -switch_context: - cli - push rbp - push rbx - push r12 - push r13 - push r14 - push r15 - - test rdi, rdi - jz .load - mov [rdi + RSP_OFFSET], rsp ; Save stack - -.load: - mov rsp, [rsi + RSP_OFFSET] ; Loads stack - + mov rsp, [rsi + RSP_OFFSET] pop r15 pop r14 pop r13 @@ -39,13 +14,7 @@ switch_context: pop rbx pop rbp - pop r11 ; pop RFLAGS in r11 - pop rcx ; pop RIP into RCX - pop rax ; pop userspace rsp into rax + iretq - mov rsp, rax - - o64 sysret - ; See kthread struct RSP_OFFSET equ 16 blob - 97983d5a50a7c11a00eb9b8167610e5a3babe57c blob + 506f0acdbc5f659191e10538612fa9e4b82aa5cd --- kernel/syscalls.c +++ kernel/syscalls.c @@ -51,19 +51,6 @@ syscall_new_thread_h(struct sysc_new_thread *nthread) } void -syscall_context_switch_h(struct sysc_context_switch *scs) -{ - struct thread *cthread = thread_get_uthread(scs->threadid); - - if (cthread == nil) { - kprint("No current thread :/\n"); - return; - } - - thread_switch(cthread); -} - -void syscall_handler(struct sysc *call) { switch (call->type) { @@ -73,9 +60,6 @@ syscall_handler(struct sysc *call) case SYSC_NEW_THREAD: syscall_new_thread_h((struct sysc_new_thread *)call); break; - case SYSC_CONTEXT_SWITCH: - syscall_context_switch_h((struct sysc_context_switch *)call); - break; default: break; } blob - 21f83e7165a15cd1c685c241a710f00554ce5f0a blob + 9e460d889acdd7664a8a494521a753f1e9ed08d5 --- kernel/sysentry.s +++ kernel/sysentry.s @@ -1,5 +1,6 @@ [bits 64] +extern cthread extern syscall_handler global rdmsr @@ -8,8 +9,10 @@ global syscall_entry syscall_entry: mov rax, rsp - mov rsp, 0x90000 + mov r10, [rel cthread] + mov rsp, [r10 + RSP_OFFSET] + push rax push rcx push r11 @@ -35,3 +38,5 @@ rdmsr: shl rdx, 32 or rax, rdx ret + +RSP_OFFSET equ 16 ; see kthreads.h blob - da421226ae4e2a0a08618efb2483844a76f2533d blob + ee332a1157cd391ca49fd5dec16b823f91d3c4dd --- syscalls/syscalls.s +++ syscalls/syscalls.s @@ -7,11 +7,5 @@ sys_send: ret sys_recv: - mov rax, SYS_RECV syscall ret - -; List of system calls IDs - -SYS_SEND equ 1 -SYS_RECV equ 2