From 30855b250e9f5014ec359d066697190400120d7b Mon Sep 17 00:00:00 2001 From: Morten Delenk Date: Sun, 30 Apr 2017 18:43:20 +0000 Subject: [PATCH] added x86 and x86_64 interrupt support --- kernel/arch/x86/interrupt.cpp | 38 ++++++++++++++++++++++++++ kernel/arch/x86/pc/start.cpp | 6 +++++ kernel/arch/x86/sourcegen.py | 3 ++- kernel/arch/x86_64/interrupt.cpp | 46 ++++++++++++++++++++++++++++++++ kernel/arch/x86_64/pc/start.cpp | 7 +++++ kernel/hw/pc/idt/idt.cpp | 4 +-- kernel/src/include/kobject.hpp | 1 + 7 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 kernel/arch/x86/interrupt.cpp create mode 100644 kernel/arch/x86_64/interrupt.cpp diff --git a/kernel/arch/x86/interrupt.cpp b/kernel/arch/x86/interrupt.cpp new file mode 100644 index 0000000..7ec7d53 --- /dev/null +++ b/kernel/arch/x86/interrupt.cpp @@ -0,0 +1,38 @@ +#include "../../hw/pc/8259/pic.hpp" +#include +#include +void print_regdump(cpu_state *state) { + (*out << "eax: ").puti(state->eax); + (*out << " ebx: ").puti(state->ebx); + (*out << " ecx: ").puti(state->ecx); + (*out << " edx: ").puti(state->edx); + (*out << " esi: ").puti(state->esi); + (*out << " edi: ").puti(state->edi); + (*out << " ebp: ").puti(state->ebp); + (*out << " eip: ").puti(state->eip); + (*out << " esp: ").puti(state->esp); + *out << "\n"; +} +extern "C" void panic2(cpu_state *state); +extern "C" cpu_state *handleINT(cpu_state *state) { + *out << "Interrupt "; + out->puti(state->intr); + *out << " occurred!\n"; + if (state->intr < 32) { + out->setColor(Color::RED); + print_regdump(state); + *out << "KERNEL PANIC: Unhandled CPU exception\n"; + for (;;) + ; + } + return state; +} +extern "C" void panic2(cpu_state *state) { + state->esp = (uintptr_t)state; + state->eip = state->intr; + out->setColor(Color::RED); + *out << "KERNEL PANIC: " << (char *)state->error << "\n"; + print_regdump(state); + for (;;) + ; +} diff --git a/kernel/arch/x86/pc/start.cpp b/kernel/arch/x86/pc/start.cpp index 6c96869..d9d2c8c 100644 --- a/kernel/arch/x86/pc/start.cpp +++ b/kernel/arch/x86/pc/start.cpp @@ -5,6 +5,8 @@ #else #include "../../../hw/pc/vesafb/vesafb.hpp" #endif +#include "../../../hw/pc/8259/pic.hpp" +#include "../../../hw/pc/idt/idt.hpp" #include static multiboot_info_t *mb_info; #ifndef ENABLE_FRAMEBUFFER @@ -20,4 +22,8 @@ extern "C" void start(int eax, multiboot_info_t *ebx) { void drivers_init() { setMainTTY(&term); --term; + initIDT(); + PIC::initPIC(0x20, 0x28); + asm volatile("sti"); + asm volatile("int $0"); } diff --git a/kernel/arch/x86/sourcegen.py b/kernel/arch/x86/sourcegen.py index 951a49b..4d917c8 100644 --- a/kernel/arch/x86/sourcegen.py +++ b/kernel/arch/x86/sourcegen.py @@ -24,7 +24,8 @@ if config["ENABLE_FPU"] and not config["ENABLE_SSE"]: if config["ENABLE_SSE"]: data_section+=".align 16\nfxsave_reg:\n .space 512" all_regs_push.append("fxsave fxsave_reg") - all_regs_pop.append("fxrstor fxsave_reg") + all_regs_pop.append("fxrstor (%eax)") + all_regs_pop.append("pop %eax") all_regs_push.append("pushl $fxsave_reg") print("Writing interrupt handler") diff --git a/kernel/arch/x86_64/interrupt.cpp b/kernel/arch/x86_64/interrupt.cpp new file mode 100644 index 0000000..d912a9d --- /dev/null +++ b/kernel/arch/x86_64/interrupt.cpp @@ -0,0 +1,46 @@ +#include "../../hw/pc/8259/pic.hpp" +#include +#include +void print_regdump(cpu_state *state) { + (*out << "rax: ").puti(state->rax); + (*out << " rbx: ").puti(state->rbx); + (*out << " rcx: ").puti(state->rcx); + (*out << " rdx: ").puti(state->rdx); + (*out << " rsi: ").puti(state->rsi); + (*out << " rdi: ").puti(state->rdi); + (*out << " rbp: ").puti(state->rbp); + (*out << " rip: ").puti(state->rip); + (*out << " rsp: ").puti(state->rsp); + (*out << " r8: ").puti(state->r8); + (*out << " r9: ").puti(state->r9); + (*out << " r10: ").puti(state->r10); + (*out << " r11: ").puti(state->r11); + (*out << " r12: ").puti(state->r12); + (*out << " r13: ").puti(state->r13); + (*out << " r14: ").puti(state->r14); + (*out << " r15: ").puti(state->r15); + *out << "\n"; +} +extern "C" void panic2(cpu_state *state); +extern "C" cpu_state *handleINT(cpu_state *state) { + *out << "Interrupt "; + out->puti(state->intr); + *out << " occurred!\n"; + if (state->intr < 32) { + out->setColor(Color::RED); + print_regdump(state); + *out << "KERNEL PANIC: Unhandled CPU exception\n"; + for (;;) + ; + } + return state; +} +extern "C" void panic2(cpu_state *state) { + state->rsp = (uintptr_t)state; + state->rip = state->intr; + out->setColor(Color::RED); + *out << "KERNEL PANIC: " << (char *)state->rdi << "\n"; + print_regdump(state); + for (;;) + ; +} diff --git a/kernel/arch/x86_64/pc/start.cpp b/kernel/arch/x86_64/pc/start.cpp index 6c96869..58f3798 100644 --- a/kernel/arch/x86_64/pc/start.cpp +++ b/kernel/arch/x86_64/pc/start.cpp @@ -5,6 +5,9 @@ #else #include "../../../hw/pc/vesafb/vesafb.hpp" #endif +#include "../../../hw/pc/8259/pic.hpp" +#include "../../../hw/pc/idt/idt.hpp" + #include static multiboot_info_t *mb_info; #ifndef ENABLE_FRAMEBUFFER @@ -20,4 +23,8 @@ extern "C" void start(int eax, multiboot_info_t *ebx) { void drivers_init() { setMainTTY(&term); --term; + initIDT(); + PIC::initPIC(0x20, 0x28); + asm volatile("sti"); + asm volatile("int $0"); } diff --git a/kernel/hw/pc/idt/idt.cpp b/kernel/hw/pc/idt/idt.cpp index ee5ef09..7bc46ea 100644 --- a/kernel/hw/pc/idt/idt.cpp +++ b/kernel/hw/pc/idt/idt.cpp @@ -27,9 +27,9 @@ void initIDT() { for (int i = 0; i < 256; i++) setIDTEntry(i, start_vectors + 16 * i); struct { uint16_t size; - uint32_t off; + IDT_entry *off; } __attribute__((packed)) idtr; idtr.size = sizeof(entries); - idtr.off = (uint32_t)((uintptr_t)entries); + idtr.off = (IDT_entry *)(&entries); asm volatile("lidt %0" : : "m"(idtr)); } diff --git a/kernel/src/include/kobject.hpp b/kernel/src/include/kobject.hpp index 11aa316..1e7c982 100644 --- a/kernel/src/include/kobject.hpp +++ b/kernel/src/include/kobject.hpp @@ -77,6 +77,7 @@ class Kobject { refctr--; if (refctr == 0) { // TODO delete this; + this->~Kobject(); return *((Kobject *)nullptr); } return *this;