diff --git a/include/sys/amd64/asm/asm_cpu.h b/include/sys/amd64/asm/asm_cpu.h index c341341..531a403 100644 --- a/include/sys/amd64/asm/asm_cpu.h +++ b/include/sys/amd64/asm/asm_cpu.h @@ -20,4 +20,30 @@ 1: .endm +#define CPU_SELF 0x00 +#define CPU_THREAD 0x08 +#define CPU_TSS 0x10 +#define CPU_SYSCALL_RSP 0x18 + +#define TSS_RSP0 0x04 + +#else +#include "sys/types.h" + +struct cpu { + // TODO: somehow export offsets to asm + struct cpu *self; // 0x00 + + struct thread *thread; // 0x08 + amd64_tss_t *tss; // 0x10 + uint64_t syscall_rsp; // 0x18 + uint64_t ticks; + + uint64_t processor_id; + + // No need to define offsets for these: ther're not accessed + // from assembly + uint64_t flags; + uint64_t apic_id; +}; #endif diff --git a/include/sys/amd64/cpu.h b/include/sys/amd64/cpu.h index 65f8eae..2e67ec4 100644 --- a/include/sys/amd64/cpu.h +++ b/include/sys/amd64/cpu.h @@ -5,33 +5,8 @@ #define FXSAVE_REGION 512 -struct cpu { - // TODO: somehow export offsets to asm - struct cpu *self; // 0x00 - - uint64_t ticks; // 0x08 - amd64_tss_t *tss; // 0x10 - - uint64_t processor_id; - - // No need to define offsets for these: ther're not accessed - // from assembly - uint64_t flags; - uint64_t apic_id; -}; - -struct cpu_context { -#if defined(AMD64_STACK_CTX_CANARY) - uintptr_t __canary; -#endif - uintptr_t fs, es, ds; - uintptr_t cr3; - uintptr_t r15, r14, r13, r12; - uintptr_t r11, r10, r9, r8; - uintptr_t rdi, rsi, rbp; - uintptr_t rbx, rdx, rcx, rax; - uintptr_t rip, cs, rflags, rsp, ss; -}; +#include "sys/amd64/asm/asm_cpu.h" +#define thread_self get_cpu()->thread #if defined(AMD64_SMP) extern struct cpu cpus[AMD64_MAX_SMP]; @@ -47,8 +22,6 @@ extern struct cpu __amd64_cpu; #define get_cpu() ((struct cpu *) &__amd64_cpu) #endif -void cpu_print_context(int level, struct cpu_context *ctx); - #define MSR_IA32_APIC_BASE 0x1B #define IA32_APIC_BASE_BSP 0x100 #define IA32_APIC_BASE_ENABLE 0x800 diff --git a/sys/amd64/cpu.c b/sys/amd64/cpu.c index 50ea6f6..b7d324b 100644 --- a/sys/amd64/cpu.c +++ b/sys/amd64/cpu.c @@ -6,14 +6,3 @@ struct cpu cpus[AMD64_MAX_SMP] = { 0 }; #else struct cpu __amd64_cpu; #endif - -void cpu_print_context(int level, struct cpu_context *ctx) { - kprint(level, "RAX = %p, RCX = %p\n", ctx->rax, ctx->rcx); - kprint(level, "RDX = %p, RBX = %p\n", ctx->rdx, ctx->rbx); - kprint(level, "RSP = %p, RBP = %p\n", ctx->rsp, ctx->rbp); - kprint(level, "RSI = %p, RDI = %p\n", ctx->rsi, ctx->rdi); - kprint(level, " R8 = %p, R9 = %p\n", ctx->r8, ctx->r9); - kprint(level, "R10 = %p, R11 = %p\n", ctx->r10, ctx->r11); - kprint(level, "R12 = %p, R13 = %p\n", ctx->r12, ctx->r13); - kprint(level, "R14 = %p, R15 = %p\n", ctx->r12, ctx->r15); -} diff --git a/sys/amd64/sched_s.S b/sys/amd64/sched_s.S index 2bb5696..0dbef4e 100644 --- a/sys/amd64/sched_s.S +++ b/sys/amd64/sched_s.S @@ -83,9 +83,9 @@ context_switch_first: // %rax = top of task's stack movq THREAD_RSP0_TOP(%rdi), %rax // %rcx = &tss - movq get_cpu(0x10), %rcx + movq get_cpu(CPU_TSS), %rcx // &tss->rsp0 = %rax - movq %rax, 4(%rcx) + movq %rax, TSS_RSP0(%rcx) // Load new %cr3 if changed movq THREAD_CR3(%rdi), %rax diff --git a/sys/amd64/syscall_s.S b/sys/amd64/syscall_s.S index 1111fa9..ec4f244 100644 --- a/sys/amd64/syscall_s.S +++ b/sys/amd64/syscall_s.S @@ -1,8 +1,5 @@ #include "sys/amd64/asm/asm_thread.h" -.section .bss -tmp0: - .quad 0 - +#include "sys/amd64/asm/asm_cpu.h" .section .text .global syscall_entry syscall_entry: @@ -11,8 +8,8 @@ syscall_entry: // %r11 - user rflags // Switch to kernel stack - movq %rsp, tmp0(%rip) - movq thread_current(%rip), %rsp + movq %rsp, get_cpu(CPU_SYSCALL_RSP) + movq get_cpu(CPU_THREAD), %rsp movq THREAD_RSP0(%rsp), %rsp cmpq $123, %rax @@ -20,7 +17,7 @@ syscall_entry: pushq %rcx pushq %r11 - movq tmp0(%rip), %rcx + movq get_cpu(CPU_SYSCALL_RSP), %rcx pushq %rcx cmpq $256, %rax @@ -49,7 +46,7 @@ syscall_entry: _syscall_fork: pushq %rcx pushq %r11 - movq tmp0(%rip), %rcx + movq get_cpu(CPU_SYSCALL_RSP), %rcx pushq %rcx pushq %r15 diff --git a/sys/sched.c b/sys/sched.c index b3a9f93..072776f 100644 --- a/sys/sched.c +++ b/sys/sched.c @@ -13,7 +13,6 @@ void yield(void); static struct thread *queue_head = NULL; static struct thread thread_idle = {0}; -struct thread *thread_current = NULL; static void *idle(void *arg) { while (1) { @@ -41,12 +40,13 @@ void sched_queue(struct thread *thr) { } void sched_unqueue(struct thread *thr) { + struct cpu *cpu = get_cpu(); struct thread *prev = thr->prev; struct thread *next = thr->next; if (next == thr) { queue_head = NULL; - thread_current = &thread_idle; + get_cpu()->thread = &thread_idle; context_switch_to(&thread_idle, thr); return; } @@ -61,14 +61,14 @@ void sched_unqueue(struct thread *thr) { thr->prev = NULL; thr->next = NULL; - if (thr == thread_current) { - thread_current = next; + if (thr == cpu->thread) { + cpu->thread = next; context_switch_to(next, thr); } } void yield(void) { - struct thread *from = thread_current; + struct thread *from = get_cpu()->thread; struct thread *to; if (from && from->next) { @@ -79,7 +79,7 @@ void yield(void) { to = &thread_idle; } - thread_current = to; + get_cpu()->thread = to; context_switch_to(to, from); } @@ -91,11 +91,12 @@ void sched_init(void) { void sched_enter(void) { extern void amd64_irq0(void); amd64_idt_set(0, 32, (uintptr_t) amd64_irq0, 0x08, IDT_FLG_P | IDT_FLG_R0 | IDT_FLG_INT32); - if (queue_head) { - thread_current = queue_head; - context_switch_first(thread_current); - } else { - thread_current = &thread_idle; - context_switch_first(&thread_idle); + + struct thread *first_task = queue_head; + if (!first_task) { + first_task = &thread_idle; } + + get_cpu()->thread = first_task; + context_switch_first(first_task); } diff --git a/sys/thread.c b/sys/thread.c index 3ec6acc..ff646ea 100644 --- a/sys/thread.c +++ b/sys/thread.c @@ -1,5 +1,6 @@ #include "sys/amd64/mm/phys.h" #include "sys/amd64/mm/pool.h" +#include "sys/amd64/cpu.h" #include "sys/vmalloc.h" #include "sys/assert.h" #include "sys/thread.h" @@ -7,8 +8,6 @@ #include "sys/debug.h" #include "sys/mm.h" -extern struct thread *thread_current; - struct sys_fork_frame { uint64_t rdi, rsi, rdx, rcx; uint64_t r8, r9, r10, r11; @@ -154,7 +153,7 @@ int sys_fork(struct sys_fork_frame *frame) { static struct thread forkt[3] = {0}; struct thread *dst = &forkt[nfork++]; - struct thread *src = thread_current; + struct thread *src = thread_self; uintptr_t stack_pages = amd64_phys_alloc_page(); _assert(stack_pages != MM_NADDR); @@ -240,7 +239,7 @@ int sys_fork(struct sys_fork_frame *frame) { } __attribute__((noreturn)) void sys_exit(int status) { - struct thread *thr = thread_current; + struct thread *thr = thread_self; kdebug("Thread %d exited with status %d\n", thr->pid, status); sched_unqueue(thr);