diff --git a/include/interrupt_handlers.h b/include/interrupt_handlers.h new file mode 100644 index 0000000..4d5c7ce --- /dev/null +++ b/include/interrupt_handlers.h @@ -0,0 +1,14 @@ +#ifndef INTERRUPTHANDLERS_H +#define INTERRUPTHANDLERS_H +#include +extern void* isr_ptrs; + +typedef struct StateSnapshot_s { + uint32_t eax, ecx, edx, ebx, esp, esi, edi; + uint32_t interrupt_id, error_code; + uint32_t eip, cs, eflags; +} StateSnapshot_t; + +void generic_isr_handler(StateSnapshot_t* cpu_state); + +#endif diff --git a/src/idt.s b/src/allocidt.s similarity index 62% rename from src/idt.s rename to src/allocidt.s index 3693c09..18f6f6b 100644 --- a/src/idt.s +++ b/src/allocidt.s @@ -1,7 +1,9 @@ global idtr, idt_start section .idtr idtr: - dw idt_end - idt_start + ;Normally, the size would be the size of the whole table, but i'm only defining 32 interrupts for now. + ;dw idt_end - idt_start + dw 32 dd idt_start section .idt nobits diff --git a/src/idt.c b/src/idt.c new file mode 100644 index 0000000..1daa346 --- /dev/null +++ b/src/idt.c @@ -0,0 +1,19 @@ +#include "idt.h" + + +void setup_idt() { + write_descriptors(); + load_idt(); +} + +void write_descriptors() { + + for(int i = 0; i < idtr.size; i+=(sizeof(InterruptDescriptor_t))) { + + } + return; +} + +void load_idt() { + return; +} diff --git a/src/interrupt_handlers.c b/src/interrupt_handlers.c new file mode 100644 index 0000000..4005b7b --- /dev/null +++ b/src/interrupt_handlers.c @@ -0,0 +1,13 @@ +#include "interrupt_handlers.h" +#include "kio.h" + +void generic_isr_handler(StateSnapshot_t* cpu_state) { + //We made it to C for our interrupt! For now, let's just print our interrupt to the screen. + vga_clear(); + vga_printf("INTERRUPT TRIGGERED! Info below.\n"); + vga_printf("Int_ID|ERR: %X|%X\n", cpu_state->interrupt_id, cpu_state->error_code); + vga_printf("EFLAGS|CS|EIP: %X|%X|%X\n", cpu_state->eflags, cpu_state->cs,cpu_state->eip); + vga_printf("GP Registers:\neax:%X\nebx:%X\necx:%X\nedx:%X\nesp:%X\nesi:%X\nedi:%X\n"); + vga_printf("HALT!"); + while(1); +} diff --git a/src/interrupts.s b/src/interrupts.s index 6fb1d2f..47eae1a 100644 --- a/src/interrupts.s +++ b/src/interrupts.s @@ -2,11 +2,50 @@ ;Let's make an interrupt pointer table so C can reference it and build the IDT. +global isr_ptrs +extern generic_isr_handler + +;By the time we get here, we actually have a rather consistent stack: +; dword [Interrupt ID] +; dword [Error code (0 if int has no error code field)] +; dword [EIP] +; dword [CS] +; dword [EFLAGS] +; We can pass this to C. First, we might want to push all of our registers or something. +isr_common: + pusha + push esp ;Throwing a pointer to ESP in there for referencing the aforementioned stuff as a struct + call generic_isr_handler + add esp,4 ;Remove that esp ref from the stack + popad ;restore our gp registers + add esp,4 ;deallocate the error code from the stack before heading out + iret + +%macro ISR_ENTRY 1 +isr_%1: + cli + %if %1 = 8 || %1 = 10 || %1 = 11 || %1 = 12 || %1 = 13 || %1 = 14 || %1 = 17 || %1 = 21 + %else + push dword 0 + %endif + push dword %1 ; saving our interrupt so C knows + jmp isr_common +%endmacro -isr_table: +%assign j 0 +%rep 32 + isr_ %+ j: + ISR_ENTRY j +%assign j j+1 +%endrep +; Generate a table of pointers that point to each of our ISRs. This will be accessed from C to setup our IDT. +isr_ptrs: %assign i 0 - %rep 21 - isr_stub_ %+ i: + %rep 32 + dd isr_ %+ i + %assign i i+1 + %endrep +isr_ptrs_end: + -