summaryrefslogtreecommitdiff
path: root/kernel/cpu
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--kernel/cpu/cpu.c62
-rw-r--r--kernel/cpu/idt.S107
-rw-r--r--kernel/cpu/idt.c40
-rw-r--r--kernel/cpu/tss.c7
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)
{