diff options
author | Freya Murphy <freya@freyacat.org> | 2025-04-28 11:09:43 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2025-04-28 11:09:43 -0400 |
commit | 103e9e001036dce5cd34209b62a416fd1f34abbf (patch) | |
tree | 4363f631c929f23b618c94f4d1a05ce51c4e6de8 /kernel/cpu | |
parent | add stderr (diff) | |
download | comus-103e9e001036dce5cd34209b62a416fd1f34abbf.tar.gz comus-103e9e001036dce5cd34209b62a416fd1f34abbf.tar.bz2 comus-103e9e001036dce5cd34209b62a416fd1f34abbf.zip |
move context save area to pcb not in stack
Diffstat (limited to 'kernel/cpu')
-rw-r--r-- | kernel/cpu/cpu.c | 62 | ||||
-rw-r--r-- | kernel/cpu/idt.S | 107 | ||||
-rw-r--r-- | kernel/cpu/idt.c | 40 | ||||
-rw-r--r-- | kernel/cpu/tss.c | 7 |
4 files changed, 135 insertions, 81 deletions
diff --git a/kernel/cpu/cpu.c b/kernel/cpu/cpu.c index 6ef5ef5..f607b36 100644 --- a/kernel/cpu/cpu.c +++ b/kernel/cpu/cpu.c @@ -1,5 +1,6 @@ #include <lib.h> #include <comus/cpu.h> +#include <comus/asm.h> #include "pic.h" #include "idt.h" @@ -61,8 +62,10 @@ void cpu_init(void) struct cpu_feat feats; cpu_feats(&feats); - pic_remap(); + cli(); idt_init(); + tss_init(); + pic_remap(); if (feats.fpu) fpu_init(); if (feats.sse) { @@ -74,8 +77,6 @@ void cpu_init(void) if (feats.avx) avx_init(); } - - tss_init(); } void cpu_report(void) @@ -181,25 +182,26 @@ void cpu_feats(struct cpu_feat *feats) void cpu_print_regs(struct cpu_regs *regs) { - kprintf("rax: %#016lx (%lu)\n", regs->rax, regs->rax); - kprintf("rbx: %#016lx (%lu)\n", regs->rbx, regs->rbx); - kprintf("rcx: %#016lx (%lu)\n", regs->rcx, regs->rcx); - kprintf("rdx: %#016lx (%lu)\n", regs->rdx, regs->rdx); - kprintf("rsi: %#016lx (%lu)\n", regs->rsi, regs->rsi); - kprintf("rdi: %#016lx (%lu)\n", regs->rdi, regs->rdi); - kprintf("rsp: %#016lx (%lu)\n", regs->rsp, regs->rsp); - kprintf("rbp: %#016lx (%lu)\n", regs->rbp, regs->rbp); - kprintf("r8 : %#016lx (%lu)\n", regs->r8, regs->r8); - kprintf("r9 : %#016lx (%lu)\n", regs->r9, regs->r9); - kprintf("r10: %#016lx (%lu)\n", regs->r10, regs->r10); - kprintf("r11: %#016lx (%lu)\n", regs->r11, regs->r11); - kprintf("r12: %#016lx (%lu)\n", regs->r12, regs->r12); - kprintf("r13: %#016lx (%lu)\n", regs->r13, regs->r13); - kprintf("r14: %#016lx (%lu)\n", regs->r14, regs->r14); - kprintf("r15: %#016lx (%lu)\n", regs->r15, regs->r15); - kprintf("rip: %#016lx (%lu)\n", regs->rip, regs->rip); - kprintf("rflags: %#016lx (%lu)\n", regs->rflags, regs->rflags); - kputs("rflags: "); + kprintf("rax:\t%#016lx (%lu)\n", regs->rax, regs->rax); + kprintf("rbx:\t%#016lx (%lu)\n", regs->rbx, regs->rbx); + kprintf("rcx:\t%#016lx (%lu)\n", regs->rcx, regs->rcx); + kprintf("rdx:\t%#016lx (%lu)\n", regs->rdx, regs->rdx); + kprintf("rsi:\t%#016lx (%lu)\n", regs->rsi, regs->rsi); + kprintf("rdi:\t%#016lx (%lu)\n", regs->rdi, regs->rdi); + kprintf("rsp:\t%#016lx (%lu)\n", regs->rsp, regs->rsp); + kprintf("rbp:\t%#016lx (%lu)\n", regs->rbp, regs->rbp); + kprintf("r8:\t%#016lx (%lu)\n", regs->r8, regs->r8); + kprintf("r9:\t%#016lx (%lu)\n", regs->r9, regs->r9); + kprintf("r10:\t%#016lx (%lu)\n", regs->r10, regs->r10); + kprintf("r11:\t%#016lx (%lu)\n", regs->r11, regs->r11); + kprintf("r12:\t%#016lx (%lu)\n", regs->r12, regs->r12); + kprintf("r13:\t%#016lx (%lu)\n", regs->r13, regs->r13); + kprintf("r14:\t%#016lx (%lu)\n", regs->r14, regs->r14); + kprintf("r15:\t%#016lx (%lu)\n", regs->r15, regs->r15); + kprintf("rip:\t%#016lx (%lu)\n", regs->rip, regs->rip); + kprintf("rflags: %#016lx (%lu) [ ", regs->rflags, regs->rflags); + if (regs->rflags & (3 << 12)) + kprintf("IOPL=%lu ", (regs->rflags >> 12) & 0x3); if (regs->rflags & (1 << 0)) kputs("CF "); if (regs->rflags & (1 << 2)) @@ -218,8 +220,6 @@ void cpu_print_regs(struct cpu_regs *regs) kputs("DF "); if (regs->rflags & (1 << 11)) kputs("OF "); - if (regs->rflags & (3 << 12)) - kputs("IOPL "); if (regs->rflags & (1 << 14)) kputs("NT "); if (regs->rflags & (1 << 15)) @@ -236,5 +236,19 @@ void cpu_print_regs(struct cpu_regs *regs) kputs("VIP "); if (regs->rflags & (1 << 21)) kputs("ID "); + kputs("]\n"); + kprintf("cs:\t%#04lx (%lu) [ DPL=%lu ]\n", regs->cs, regs->cs, + regs->cs & 0x3); + kprintf("ss:\t%#04lx (%lu) [ DPL=%lu ]\n", regs->ss, regs->ss, + regs->ss & 0x3); + kprintf("ds:\t%#04hx (%hu) [ DPL=%hu ]\n", regs->ds, regs->ds, + regs->ds & 0x3); + kprintf("es:\t%#04hx (%hu) [ DPL=%hu ]\n", regs->es, regs->es, + regs->es & 0x3); + kprintf("fs:\t%#04hx (%hu) [ DPL=%hu ]\n", regs->fs, regs->fs, + regs->fs & 0x3); + kprintf("gs:\t%#04hx (%hu) [ DPL=%hu ]\n", regs->gs, regs->gs, + regs->gs & 0x3); + kprintf("cr3:\t%#016lx (%lu)\n", regs->cr3, regs->cr3); kputs("\n"); } diff --git a/kernel/cpu/idt.S b/kernel/cpu/idt.S index 06c70a0..05c34f5 100644 --- a/kernel/cpu/idt.S +++ b/kernel/cpu/idt.S @@ -1,6 +1,5 @@ .global isr_stub_table .global syscall_return - .global awd .extern idt_exception_handler .extern idt_pic_timer @@ -9,8 +8,10 @@ .extern idt_pic_eoi .extern syscall_handler .extern current_pcb + .extern isr_save .macro PUSHALL + # regs pushq %rax pushq %rbx pushq %rcx @@ -26,9 +27,38 @@ pushq %r13 pushq %r14 pushq %r15 + + # segments + movw %ds, %ax + pushw %ax + movw %es, %ax + pushw %ax + movw %fs, %ax + pushw %ax + movw %gs, %ax + pushw %ax + + # pgdir + movq %cr3, %rax + pushq %rax .endm .macro POPALL + # pgdir + popq %rax + movq %rax, %cr3 + + # segments + popw %ax + movw %ax, %gs + movw %ax, %fs + popw %ax + movw %ax, %es + popw %ax + movw %ax, %ds + popw %ax + + # regs popq %r15 popq %r14 popq %r13 @@ -46,19 +76,28 @@ popq %rax .endm +.macro ISRSave + PUSHALL + cld + movq %rsp, %rdi + callq isr_save +.endm + +.macro ISRRestore + POPALL + iretq +.endm + # call the exception handler with the interrupt number # args: interrupt number .macro ISRException num .align 8 isr_stub_\num: - PUSHALL - cld - movq $\num, %rdi # exception number + ISRSave + movq $\num, %rdi # exception number movq $0, %rsi # placeholder error code - movq %rsp, %rdx # top of stack callq idt_exception_handler - POPALL - iretq + ISRRestore .endm # call the exception handler with the interrupt number @@ -68,26 +107,21 @@ isr_stub_\num: .align 8 isr_stub_\num: # retrieve the error code without corrupting registers - mov %eax, isr_tmp + movq %rax, isr_tmp popq %rax - mov %eax, isr_err_code + movq %rax, isr_err_code movq isr_tmp, %rax - PUSHALL - cld + ISRSave movq $\num, %rdi # exception number movq isr_err_code, %rsi # error code - movq %rsp, %rdx # top of stack callq idt_exception_handler - POPALL - iretq + ISRRestore .endm .macro SYSCALL num .align 8 isr_stub_\num: - PUSHALL - cld - movq %rsp, %rdi # top of stack + ISRSave callq syscall_handler jmp syscall_return .endm @@ -95,48 +129,40 @@ isr_stub_\num: .macro PICGeneric num .align 8 isr_stub_\num: - PUSHALL - cld + ISRSave movq $\num, %rdi callq idt_pic_eoi - POPALL - iretq + ISRRestore .endm .macro PICTimer num .align 8 isr_stub_\num: - PUSHALL - cld + ISRSave callq idt_pic_timer movq $\num, %rdi callq idt_pic_eoi - POPALL - iretq + ISRRestore .endm .macro PICKeyboard num .align 8 isr_stub_\num: - PUSHALL - cld + ISRSave callq idt_pic_keyboard movq $\num, %rdi callq idt_pic_eoi - POPALL - iretq + ISRRestore .endm .macro PICMouse num .align 8 isr_stub_\num: - PUSHALL - cld + ISRSave callq idt_pic_mouse movq $\num, %rdi callq idt_pic_eoi - POPALL - iretq + ISRRestore .endm # do nothing @@ -421,18 +447,13 @@ isr_stub_table: # isr restore syscall_return: - movq current_pcb, %rbx // return user stack - movq 0(%rbx), %rsp // esp - movq 8(%rbx), %rcx // pml4 - movq (%rcx), %rcx - movq %rcx, %cr3 + // get current pcb address + movq current_pcb, %rbx - movw $(0x20 | 3), %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs + // load user stack + leaq 8(%rbx), %rsp + // return POPALL iretq diff --git a/kernel/cpu/idt.c b/kernel/cpu/idt.c index 8bddc21..d071d29 100644 --- a/kernel/cpu/idt.c +++ b/kernel/cpu/idt.c @@ -3,6 +3,7 @@ #include <comus/asm.h> #include <comus/cpu.h> #include <comus/drivers/pit.h> +#include <comus/procs.h> #include <comus/memory.h> #include "idt.h" @@ -42,8 +43,12 @@ struct idtr { __attribute__((aligned(0x10))) static struct idt_entry idt[256]; static struct idtr idtr; -// from idt.S extern void *isr_stub_table[]; +extern char kern_stack_start[]; +extern char kern_stack_end[]; + +// current register state on interrupt +static struct cpu_regs *state; // initialize and load the IDT void idt_init(void) @@ -58,11 +63,10 @@ void idt_init(void) uint64_t isr = (uint64_t)isr_stub_table[vector]; // interrupts before 0x20 are for cpu exceptions - uint8_t gate_type = (vector < 0x20) ? GATE_64BIT_TRAP : GATE_64BIT_INT; entry->kernel_cs = 0x08; // offset of 1 into GDT entry->ist = 0; - entry->flags = PRESENT | RING0 | gate_type; + entry->flags = PRESENT | RING0 | GATE_64BIT_INT; entry->isr_low = isr & 0xffff; entry->isr_mid = (isr >> 16) & 0xffff; entry->isr_high = (isr >> 32) & 0xffffffff; @@ -115,14 +119,11 @@ char *EXCEPTIONS[] = { "Reserved", }; -void idt_exception_handler(uint64_t exception, uint64_t code, - struct cpu_regs *state) +__attribute__((noreturn)) void idt_exception_handler(uint64_t exception, + uint64_t code) { uint64_t cr2; - // make sure were in the kernel memory context - mem_ctx_switch(kernel_mem_ctx); - switch (exception) { case EX_PAGE_FAULT: // page faults store the offending address in cr2 @@ -151,16 +152,35 @@ void idt_exception_handler(uint64_t exception, uint64_t code, } } +void isr_save(struct cpu_regs *regs) +{ + // make sure were in the kernel memory context + mem_ctx_switch(kernel_mem_ctx); + + // save pointer to registers + state = regs; + + // if we have a kernel stack pointer + // we should return to not save kernel context + // data to userspace + if (regs->rsp >= (size_t)kern_stack_start && + regs->rsp <= (size_t)kern_stack_end) + return; + + // save registers in current_pcb + if (current_pcb != NULL) + current_pcb->regs = *regs; +} + void idt_pic_eoi(uint8_t exception) { pic_eoi(exception - PIC_REMAP_OFFSET); } -int counter = 0; - void idt_pic_timer(void) { ticks++; + pcb_on_tick(); } void idt_pic_keyboard(void) diff --git a/kernel/cpu/tss.c b/kernel/cpu/tss.c index 184b884..bca979d 100644 --- a/kernel/cpu/tss.c +++ b/kernel/cpu/tss.c @@ -1,6 +1,5 @@ -#include "comus/memory.h" -#include "lib/kstring.h" -#include <stdint.h> +#include <comus/memory.h> +#include <lib.h> #include "tss.h" @@ -48,7 +47,7 @@ extern volatile uint8_t GDT[]; static volatile struct sys_seg_descriptor *GDT_TSS; // kernel stack pointer -static char interrupt_stack[PAGE_SIZE*2]; +static char interrupt_stack[PAGE_SIZE * 2]; void tss_init(void) { |