summaryrefslogtreecommitdiff
path: root/kernel/cpu/idt.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/cpu/idt.c')
-rw-r--r--kernel/cpu/idt.c44
1 files changed, 37 insertions, 7 deletions
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();
}