diff options
author | Galen Sagarin <gps5307@rit.edu> | 2025-04-29 14:18:40 -0400 |
---|---|---|
committer | Galen Sagarin <gps5307@rit.edu> | 2025-04-29 14:18:40 -0400 |
commit | ae2cdd83ba4a0cae161db0b29031d5591005fa34 (patch) | |
tree | 82fbdfcbb1fe4e3b5e232db195c8c331d69489fd /kernel/cpu | |
parent | Started writing fat.c (diff) | |
parent | fs header changes (diff) | |
download | comus-ae2cdd83ba4a0cae161db0b29031d5591005fa34.tar.gz comus-ae2cdd83ba4a0cae161db0b29031d5591005fa34.tar.bz2 comus-ae2cdd83ba4a0cae161db0b29031d5591005fa34.zip |
Merge branch 'main' of https://github.com/kenshineto/kern into fat32
Merging main into here
Diffstat (limited to 'kernel/cpu')
-rw-r--r-- | kernel/cpu/cpu.c | 61 | ||||
-rw-r--r-- | kernel/cpu/idt.S | 121 | ||||
-rw-r--r-- | kernel/cpu/idt.c | 44 | ||||
-rw-r--r-- | kernel/cpu/tss.S | 6 | ||||
-rw-r--r-- | kernel/cpu/tss.c | 82 | ||||
-rw-r--r-- | kernel/cpu/tss.h | 31 |
6 files changed, 283 insertions, 62 deletions
diff --git a/kernel/cpu/cpu.c b/kernel/cpu/cpu.c index 136a1d8..f607b36 100644 --- a/kernel/cpu/cpu.c +++ b/kernel/cpu/cpu.c @@ -1,8 +1,10 @@ #include <lib.h> #include <comus/cpu.h> +#include <comus/asm.h> #include "pic.h" #include "idt.h" +#include "tss.h" static inline void fpu_init(void) { @@ -60,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) { @@ -178,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)) @@ -215,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)) @@ -233,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 0ba35f8..b3a8454 100644 --- a/kernel/cpu/idt.S +++ b/kernel/cpu/idt.S @@ -1,12 +1,17 @@ .global isr_stub_table + .global syscall_return .extern idt_exception_handler .extern idt_pic_timer .extern idt_pic_keyboard .extern idt_pic_mouse .extern idt_pic_eoi + .extern syscall_handler + .extern current_pcb + .extern isr_save .macro PUSHALL + # regs pushq %rax pushq %rbx pushq %rcx @@ -22,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 + popw %ax + movw %ax, %fs + popw %ax + movw %ax, %es + popw %ax + movw %ax, %ds + + # regs popq %r15 popq %r14 popq %r13 @@ -42,19 +76,29 @@ 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 @@ -64,65 +108,64 @@ 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: + ISRSave + callq syscall_handler + jmp syscall_return .endm .macro PICGeneric num .align 8 isr_stub_\num: - PUSHALL - cld + ISRSave movq $\num, %rdi callq idt_pic_eoi - POPALL - iretq + ISRRestore .endm +# we have to send eoi first since +# idt_pic_timer may not return .macro PICTimer num .align 8 isr_stub_\num: - PUSHALL - cld - callq idt_pic_timer - movq $\num, %rdi + ISRSave callq idt_pic_eoi - POPALL - iretq + movq $\num, %rdi + callq idt_pic_timer + 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 @@ -402,10 +445,22 @@ isr_stub_table: .quad isr_stub_254 .quad isr_stub_255 -# isr stubs .section .text .code64 +# isr restore +syscall_return: + // get current pcb address + movq current_pcb, %rbx + + // load user stack + leaq 8(%rbx), %rsp + + // return + POPALL + iretq + +# isr stubs ISRException 0 ISRException 1 ISRException 2 @@ -536,7 +591,7 @@ ISRIgnore 124 ISRIgnore 125 ISRIgnore 126 ISRIgnore 127 -ISRIgnore 128 +SYSCALL 128 ISRIgnore 129 ISRIgnore 130 ISRIgnore 131 diff --git a/kernel/cpu/idt.c b/kernel/cpu/idt.c index bf4b499..2eab7ec 100644 --- a/kernel/cpu/idt.c +++ b/kernel/cpu/idt.c @@ -2,7 +2,10 @@ #include <comus/memory.h> #include <comus/asm.h> #include <comus/cpu.h> +#include <comus/drivers/ps2.h> #include <comus/drivers/pit.h> +#include <comus/procs.h> +#include <comus/memory.h> #include "idt.h" #include "pic.h" @@ -41,8 +44,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) @@ -57,15 +64,17 @@ 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; entry->reserved = 0; + + if (vector == 0x80) + entry->flags |= RING3; } __asm__ volatile("lidt %0" : : "m"(idtr)); @@ -111,8 +120,8 @@ 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; @@ -144,22 +153,43 @@ 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) { + ps2kb_recv(); } void idt_pic_mouse(void) { + ps2mouse_recv(); } diff --git a/kernel/cpu/tss.S b/kernel/cpu/tss.S new file mode 100644 index 0000000..27f2955 --- /dev/null +++ b/kernel/cpu/tss.S @@ -0,0 +1,6 @@ + .globl tss_flush + +tss_flush: + movw $0x28, %ax + ltr %ax + ret diff --git a/kernel/cpu/tss.c b/kernel/cpu/tss.c new file mode 100644 index 0000000..bca979d --- /dev/null +++ b/kernel/cpu/tss.c @@ -0,0 +1,82 @@ +#include <comus/memory.h> +#include <lib.h> + +#include "tss.h" + +struct sys_seg_descriptor { + uint64_t limit0_15 : 16; + uint64_t base0_15 : 16; + uint64_t base16_23 : 8; + uint64_t type : 4; + uint64_t : 1; + uint64_t DPL : 2; + uint64_t present : 1; + uint64_t limit16_19 : 4; + uint64_t available : 1; + uint64_t : 1; + uint64_t : 1; + uint64_t gran : 1; + uint64_t base24_31 : 8; + uint64_t base32_63 : 32; + uint64_t : 32; +} __attribute__((packed)); + +struct tss { + uint64_t : 32; + uint64_t rsp0 : 64; + uint64_t rsp1 : 64; + uint64_t rsp2 : 64; + uint64_t : 64; + uint64_t ist1 : 64; + uint64_t ist2 : 64; + uint64_t ist3 : 64; + uint64_t ist4 : 64; + uint64_t ist5 : 64; + uint64_t ist6 : 64; + uint64_t ist7 : 64; + uint64_t : 64; + uint64_t : 16; + uint64_t iopb : 16; +} __attribute__((packed)); + +// tss entry +static volatile struct tss tss; + +// gdt entries +extern volatile uint8_t GDT[]; +static volatile struct sys_seg_descriptor *GDT_TSS; + +// kernel stack pointer +static char interrupt_stack[PAGE_SIZE * 2]; + +void tss_init(void) +{ + uint64_t base = (uint64_t)&tss; + uint64_t limit = sizeof tss - 1; + + // setup tss entry + memsetv(&tss, 0, sizeof(struct tss)); + tss.rsp0 = (uint64_t)interrupt_stack + sizeof(interrupt_stack); + + // map tss into gdt + GDT_TSS = (volatile struct sys_seg_descriptor *)(GDT + 0x28); + memsetv(GDT_TSS, 0, sizeof(struct sys_seg_descriptor)); + GDT_TSS->limit0_15 = limit & 0xFFFF; + GDT_TSS->base0_15 = base & 0xFFFF; + GDT_TSS->base16_23 = (base >> 16) & 0xFF; + GDT_TSS->type = 0x9; + GDT_TSS->DPL = 0; + GDT_TSS->present = 1; + GDT_TSS->limit16_19 = (limit >> 16) & 0xF; + GDT_TSS->available = 0; + GDT_TSS->gran = 0; + GDT_TSS->base24_31 = (base >> 24) & 0xFF; + GDT_TSS->base32_63 = (base >> 32) & 0xFFFFFFFF; + + tss_flush(); +} + +void tss_set_stack(uint64_t stack) +{ + tss.rsp0 = stack; +} diff --git a/kernel/cpu/tss.h b/kernel/cpu/tss.h new file mode 100644 index 0000000..f17b619 --- /dev/null +++ b/kernel/cpu/tss.h @@ -0,0 +1,31 @@ +/** + * @file tss.h + * + * @author Freya Murphy <freya@freyacat.org> + * + * TSS functions + */ + +#ifndef TSS_H_ +#define TSS_H_ + +#define TSS_REMAP_OFFSET 0x20 + +#include <stdint.h> + +/** + * Load the TSS selector + */ +void tss_init(void); + +/** + * Flush the tss + */ +void tss_flush(void); + +/** + * Set the kernel stack pointer in the tss + */ +void tss_set_stack(uint64_t stack); + +#endif /* tss.h */ |