From 7d9800f1ebaa1da1804d0ec8b2f739080f276a74 Mon Sep 17 00:00:00 2001 From: shockrah Date: Sun, 13 Oct 2019 23:14:49 -0700 Subject: [PATCH] starting point for interrupt handlers though some of this code isn't ready to be used, it serves as a reference point for later --- idt.h | 3 ++ idt.s | 7 ++++ interrupt_entry.s | 96 +++++++++++++++++++++++++++++++++++++++++++++++ interrupts.c | 5 +++ interrupts.h | 34 +++++++++++++++++ kernel.c | 14 +++++++ kernel.h | 8 ++++ 7 files changed, 167 insertions(+) create mode 100644 idt.h create mode 100644 idt.s create mode 100644 interrupt_entry.s create mode 100644 interrupts.c create mode 100644 interrupts.h create mode 100644 kernel.c create mode 100644 kernel.h diff --git a/idt.h b/idt.h new file mode 100644 index 0000000..dd3c685 --- /dev/null +++ b/idt.h @@ -0,0 +1,3 @@ +#include "types.h" + +void load_idt(void* idt_addr); diff --git a/idt.s b/idt.s new file mode 100644 index 0000000..69d0f46 --- /dev/null +++ b/idt.s @@ -0,0 +1,7 @@ +global load_idt + +load_idt: + ; takes the address of the first element in the Interrupt descriptor table + mov eax, [esp+4] + lidt eax + ret diff --git a/interrupt_entry.s b/interrupt_entry.s new file mode 100644 index 0000000..da7f767 --- /dev/null +++ b/interrupt_entry.s @@ -0,0 +1,96 @@ +; Dispatching to our interrupt handler code from assembly because some of this is +; enourmous pain in C + +; Save the register state +; call the C handler +; executes iret(expects the stack to look like struct stack_state) + + +; If the interrupt we need to handle doesn't produce an error code then must provide a 0 +; for consistency + +extern interrupt_handler + +%macro no_err_handler 1 +global interrupt_handler_%1 ; defined in interrupts.h +interrupt_handler_%1: + push dword 0 + push dword %1 + jmp common_int_handler +%endmacro + +; deals with the intterrupts that do give us an error code +%macro err_code_handler 1 +global interrupt_handler_%1 +interrupt_handler_%1: + push dword %1 + jmp common_int_handler +%endmacro + +common_int_handler: + ; save thigns before do our C-call + push eax + push ebx + push ecx + push edx + + push cs + push ds + push es + push fs + push gs + push ss + + push esi + push edi + push ebp + push esp + + call interrupt_handler + ; restore state to the function + pop eax + pop ebx + pop ecx + pop edx + + pop cs + pop ds + pop es + pop fs + pop gs + pop ss + + pop esi + pop edi + pop ebp + pop esp + + add esp, 8 + ; special instruction which lets us jump back to code + ; which was previously interrupted + iret + + +no_err_handler 1 +no_err_handler 2 +no_err_handler 3 +no_err_handler 4 +no_err_handler 5 +no_err_handler 6 +no_err_handler 7 + +err_code_handler 8 + +no_err_handler 9 + +err_code_handler 10 +err_code_handler 11 +err_code_handler 12 +err_code_handler 13 +err_code_handler 14 + +no_err_handler 15 +no_err_handler 16 + +err_code_handler 17 + diff --git a/interrupts.c b/interrupts.c new file mode 100644 index 0000000..d12c4d9 --- /dev/null +++ b/interrupts.c @@ -0,0 +1,5 @@ +#include "interrupts.h" +#include "types.h" + +void interrupt_handler(struct cpu_reg_state cpu, struct stack_state stack, u32 interrupt_code) { +} diff --git a/interrupts.h b/interrupts.h new file mode 100644 index 0000000..fd27eb2 --- /dev/null +++ b/interrupts.h @@ -0,0 +1,34 @@ +#include "types.h" + +struct cpu_reg_state { + u32 eax; + u32 ebx; + u32 ecx; + u32 edx; + + u16 cs; + u16 ds; + u16 es; + u16 fs; + u16 gs; + u16 ss; + + u32 esi; + u32 edi; + u32 ebp; + u32 eip; + u32 esp; + + u32 eflags; +}__attribute__((packed)); + +// Populated by the interrupt handler itself +struct stack_state { + u32 error_code; // 8 10 11 12 13 14 17 <= ony interrupts that actually use the error code + u32 eip; + u16 cs; + u32 eflags; +}; + + +void interrupt_handler(struct cpu_reg_state, struct stack_state, u32); diff --git a/kernel.c b/kernel.c new file mode 100644 index 0000000..0076ed2 --- /dev/null +++ b/kernel.c @@ -0,0 +1,14 @@ +#include "kernel.h" +#include "types.h" +#include "gdt.h" +#include "idt.h" + +GDT GDT_PTR; +GDT _GDT[6]; // because there are only 6 segments we care about + +u32 kinit() { + init_segment_selectors(); // found in gdt.s +} +void kmain() { +} + diff --git a/kernel.h b/kernel.h new file mode 100644 index 0000000..bf7a4ff --- /dev/null +++ b/kernel.h @@ -0,0 +1,8 @@ +#include "types.h" +#include "interrupts.h" + + +// handles the main initialization things for the main kernel routine later on +u32 kinit(); + +void kmain();