diff options
| author | Ian Moffett <ian@osmora.org> | 2025-11-19 22:57:27 -0500 |
|---|---|---|
| committer | Ian Moffett <ian@osmora.org> | 2025-11-19 22:57:27 -0500 |
| commit | c478ba925b29990df2426ee06c2e629c0a2d7246 (patch) | |
| tree | 9a11ee818603129f4241eb809e69b23fefb00df4 /sys | |
| parent | 7ea67beff9fdf4b57381b5c197f1f8c362bb9099 (diff) | |
kern/amd64: sched: Implement context switching
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/arch/amd64/cpu/idt.S | 5 | ||||
| -rw-r--r-- | sys/arch/amd64/cpu/mp.c | 17 | ||||
| -rw-r--r-- | sys/arch/amd64/os/os_process.c | 53 | ||||
| -rw-r--r-- | sys/inc/mu/process.h | 8 | ||||
| -rw-r--r-- | sys/kern/kern_init.c | 1 |
5 files changed, 76 insertions, 8 deletions
diff --git a/sys/arch/amd64/cpu/idt.S b/sys/arch/amd64/cpu/idt.S index 729d958..cf31fbb 100644 --- a/sys/arch/amd64/cpu/idt.S +++ b/sys/arch/amd64/cpu/idt.S @@ -309,9 +309,12 @@ page_fault: .globl lapic_tmr_isr lapic_tmr_isr: KFENCE + subq $8, %rsp push_frame 0x81 - nop + mov %rsp, %rdi + call mu_process_switch pop_frame 0x81 + add $8, %rsp KFENCE iretq diff --git a/sys/arch/amd64/cpu/mp.c b/sys/arch/amd64/cpu/mp.c index 6911a49..ea36829 100644 --- a/sys/arch/amd64/cpu/mp.c +++ b/sys/arch/amd64/cpu/mp.c @@ -40,6 +40,7 @@ #include <md/lapic.h> #include <md/msr.h> #include <md/cpu.h> +#include <md/gdt.h> #include <mu/cpu.h> #include <os/process.h> #include <os/sched.h> @@ -116,10 +117,11 @@ static volatile uint32_t aps_up = 0; __section(".trampoline") static char ap_code[4096]; static void -cpu_idle(void) +cpu_idle(struct mcb *mcb) { + lapic_oneshot_usec(mcb, SCHED_QUANTUM); for (;;) { - __asmv("hlt"); + __asmv("sti; hlt"); } } @@ -308,7 +310,7 @@ cpu_lm_entry(void) ); idt_load(); - cpu_idle(); + cpu_idle(&ci->mcb); __builtin_unreachable(); } @@ -391,9 +393,10 @@ static void cpu_start_idle(void) { struct process *p; + struct cpu_info *core; int error; - for (size_t i = 0; i < ap_count; ++i) { + for (size_t i = 0; i < ap_count + 1; ++i) { p = kalloc(sizeof(*p)); if (p == NULL) { panic("mp: could not allocate idle thread\n"); @@ -405,7 +408,8 @@ cpu_start_idle(void) panic("mp: could not initialize process\n"); } - sched_enqueue_proc(p); + core = sched_enqueue_proc(p); + core->curproc = NULL; } } @@ -451,6 +455,7 @@ cpu_start_aps(struct cpu_info *ci) /* Copy the bring up code to the BUA */ bua = AP_BUA_VADDR; memcpy(bua, ap_code, AP_BUA_LEN); + cpu_start_idle(); /* Start up the APs */ mcb = &self->mcb; @@ -471,6 +476,4 @@ cpu_start_aps(struct cpu_info *ci) } else { dtrace("%d processor(s) up\n", aps_up); } - - cpu_start_idle(); } diff --git a/sys/arch/amd64/os/os_process.c b/sys/arch/amd64/os/os_process.c index 21bdd86..60bdcb0 100644 --- a/sys/arch/amd64/os/os_process.c +++ b/sys/arch/amd64/os/os_process.c @@ -30,11 +30,64 @@ #include <sys/errno.h> #include <mu/process.h> #include <mu/mmu.h> +#include <mu/cpu.h> +#include <md/gdt.h> +#include <md/lapic.h> +#include <os/process.h> +#include <os/sched.h> #include <vm/phys.h> +#include <vm/vm.h> #include <lib/string.h> #define STACK_TOP 0xBFFFFFFF +static void +sched_enter(struct cpu_info *ci) +{ + lapic_oneshot_usec(&ci->mcb, SCHED_QUANTUM); + for (;;) { + __asmv("sti; hlt"); + } +} + +void +mu_process_switch(struct trapframe *tf) +{ + struct cpu_info *ci = cpu_self(); + struct process *self, *next; + struct pcb *pcb; + + if (ci == NULL) { + goto done; + } + + if ((self = ci->curproc) == NULL) { + ci->curproc = sched_dequeue_proc(); + goto done; + } + + /* Save current process */ + sched_enqueue_proc(self); + pcb = &self->pcb; + memcpy(&pcb->tf, tf, sizeof(pcb->tf)); + + /* Get the next process */ + next = sched_dequeue_proc(); + if (next == NULL) { + sched_enter(ci); + } + + /* Switch to the next process */ + pcb = &next->pcb; + memcpy(tf, &pcb->tf, sizeof(*tf)); + ci->curproc = next; + + /* Switch address space and go */ + mu_pmap_writevas(&pcb->vas); +done: + lapic_eoi(&ci->mcb); + lapic_oneshot_usec(&ci->mcb, SCHED_QUANTUM); +} int mu_process_init(struct process *process, uintptr_t ip, int flags) diff --git a/sys/inc/mu/process.h b/sys/inc/mu/process.h index 2e69140..895ecf7 100644 --- a/sys/inc/mu/process.h +++ b/sys/inc/mu/process.h @@ -32,6 +32,7 @@ #include <sys/types.h> #include <os/process.h> +#include <md/frame.h> /* shared */ /* * Initialize machine specific process fields @@ -41,4 +42,11 @@ */ int mu_process_init(struct process *process, uintptr_t ip, int flags); +/* + * Context switch to the next process + * + * @tf: Trapframe + */ +void mu_process_switch(struct trapframe *tf); + #endif /* !_MU_PROCESS_H_ */ diff --git a/sys/kern/kern_init.c b/sys/kern/kern_init.c index 701f214..0c4f286 100644 --- a/sys/kern/kern_init.c +++ b/sys/kern/kern_init.c @@ -30,6 +30,7 @@ #include <sys/types.h> #include <dev/cons/cons.h> #include <os/trace.h> +#include <os/sched.h> #include <acpi/acpi.h> #include <mu/cpu.h> #include <vm/phys.h> |
