diff --git a/include/kernel.h b/include/kernel.h index 48796ab..e714ded 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -576,13 +576,13 @@ typedef struct __attribute__((aligned(64), packed)) { } XSAVE_AREA; -static void* irq_routines[16] = { +static void* IRQ_Handlers[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static const char* exception_messages[] = { +static const char* ExceptionStrings[] = { "Division by Zero", "Debug", "Non Maskable Interrupt", @@ -686,9 +686,11 @@ void ScanCPUFeatures(size_t RAX, size_t RCX); /* ==================== Interrupts ==================== */ -void IRQ_Common(INTERRUPT_FRAME* Frame); -void ISR_Common(INTERRUPT_FRAME* Frame); -void ISR_Error_Common(EXCEPTION_FRAME* Frame); +void IRQ_Common(INTERRUPT_FRAME* Frame, size_t Interupt); +void ISR_Common(INTERRUPT_FRAME* Frame, size_t Interrupt); +void ISR_Error_Common(EXCEPTION_FRAME* Frame, size_t Exception); + +void RemapIRQControllers(); void ISR0Handler(INTERRUPT_FRAME* Frame); // Divide-By-Zero void ISR1Handler(INTERRUPT_FRAME* Frame); // Debug @@ -726,7 +728,6 @@ void DumpSegmentRegisters(void); void irq_install_handler(int irq, void (*handler)(INTERRUPT_FRAME* r)); void irq_uninstall_handler(int); void irq_install(); -void irq_remap(); void timer_install(); /* ==================== Memory ==================== */ diff --git a/kernel/interrupts.c b/kernel/interrupts.c index f738d87..7899ae5 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -12,6 +12,10 @@ * functions are in their own file to * accomodate this. * + * Additionally, the kernel now has SSE/AVX support. + * So this file and this file *alone* must be compiled with + * -mgeneral-regs-only + * * Calling a function like so: * * __attribute__((interrupt)) isr1(registers_t* frame) {} @@ -28,10 +32,7 @@ * these having a size_t input as an error code. */ - -#include -#include -#include "kernel/descriptor_tables.h" +#include #ifdef __x86_64__ typedef unsigned long long int uword_t; @@ -39,6 +40,90 @@ typedef unsigned long long int uword_t; typedef unsigned int uword_t; #endif + +/* All of the ISR routines call this function for now. + ! This function is NOT leaf, and it might clobber the stack. + ! Be careful! +*/ +void ISR_Common(INTERRUPT_FRAME* Frame, size_t Exception) { + /* Only the first 32 ISR/IRQs are reserved for exceptions by the CPU. We can handle up to 512 interrupts total, though. */ + if(Exception < 32) { + /* exception_messages is an array of c-strings defined in kernel.h */ + // TODO: Serial! + //serial_print(0x3F8, exception_messages[Exception]); + //serial_print(0x3F8, " Exception.\r\n"); + printf("%s exception!", ExceptionStrings[Exception]); + panic(); + } +} + +/* The common handler for exceptions that throw error codes, which give us useful insight + into what went wrong. In pure Curle style, though, we just ignore the error code. */ +void ISR_Error_Common(EXCEPTION_FRAME* Frame, size_t Exception) { + if(Exception < 32) { + //serial_print(0x3F8, ExceptionStrings[Exception]); + //serial_printf(0x3F8, " Exception. Context given: %d\r\n", Frame->ErrorCode); + printf("%s exception. Context: %x", ExceptionStrings[Exception], Frame->ErrorCode); + panic(); + } + +} + +/* Likewise, this function is common to all IRQ handlers. It calls the assigned routine, + which was set up earlier by irq_install.*/ +void IRQ_Common(INTERRUPT_FRAME* Frame, size_t Interrupt) { + // First we need to define a function pointer.. + void (*Handler)(INTERRUPT_FRAME* Frame); + + // Tell the user we've got an interrupt in.. + //serial_print(0x3F8, "[INFO] Received IRQ: " + interrupt); + printf("[INFO] Received IRQ: %x", Interrupt); + + /* We set all uninitialized routines to 0, so the if(handler) check here allows us to + safely tell whether we've actually got something for this IRQ. */ + Handler = IRQ_Handlers[Interrupt]; + // If there's something there, + if(Handler) + // Call the handler. + Handler(Frame); + + /* The Slave PIC must be told it's been read in order to receive another 8+ IRQ. */ + if(Interrupt > 7) + WritePort(0xA0, 0x20, 8); + + /* In either case, we tell the Master PIC it's been read to receive any IRQ. */ + WritePort(0x20, 0x20, 8); +} + +/* However, in order to actually be able to receive IRQs, we need to remap the PICs. */ +void RemapIRQControllers() { + /* 0x20 is the Master PIC, + 0xA0 is the Slave PIC. */ + WritePort(0x20, 0x11, 8); + WritePort(0xA0, 0x11, 8); + WritePort(0x21, 0x20, 8); + WritePort(0xA1, 0x28, 8); + WritePort(0x21, 0x04, 8); + WritePort(0xA1, 0x02, 8); + WritePort(0x21, 0x01, 8); + WritePort(0xA1, 0x01, 8); + WritePort(0x21, 0x0, 8); + WritePort(0xA1, 0x0, 8); +} + +/* In order to actually handle the IRQs, though, we need to tell the kernel *where* the handlers are. */ +/* A simple wrapper that adds a function pointer to the IRQ array. */ +void InstallIRQHandler(int IRQ, void (*Handler)(INTERRUPT_FRAME* Frame)) { + IRQ_Handlers[IRQ] = Handler; +} + +/* A simple wrapper that unlinks a function pointer, rendering the IRQ unused. */ +void UninstallIRQHandler(int IRQ) { + IRQ_Handlers[IRQ] = 0; // 0 is used in the common check to make sure that the function is callable. + // This removes this irq from that check, ergo the function will no longer be called. +} + + /* The interrupt numbers, their meanings, and * special information is laid out below: * @@ -64,149 +149,149 @@ typedef unsigned int uword_t; * 19 to 31 - Reserved */ -__attribute__((interrupt)) void isr0(struct int_frame* r) { - isr_common(r, 0); +__attribute__((interrupt)) void ISR0Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 0); } -__attribute__((interrupt)) void isr1(struct int_frame* r) { - isr_common(r, 1); +__attribute__((interrupt)) void ISR1Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 1); } -__attribute__((interrupt)) void isr2(struct int_frame* r) { - isr_common(r, 2); +__attribute__((interrupt)) void ISR2Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 2); } -__attribute__((interrupt)) void isr3(struct int_frame* r) { - isr_common(r, 3); +__attribute__((interrupt)) void ISR3Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 3); } -__attribute__((interrupt)) void isr4(struct int_frame* r) { - isr_common(r, 4); +__attribute__((interrupt)) void ISR4Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 4); } -__attribute__((interrupt)) void isr5(struct int_frame* r) { - isr_common(r, 5); +__attribute__((interrupt)) void ISR5Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 5); } -__attribute__((interrupt)) void isr6(struct int_frame* r) { - isr_common(r, 6); +__attribute__((interrupt)) void ISR6Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 6); } -__attribute__((interrupt)) void isr7(struct int_frame* r) { - isr_common(r, 7); +__attribute__((interrupt)) void ISR7Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 7); } -__attribute__((interrupt)) void isr8(struct int_frame* r, size_t error) { - isr_error_common(r, 8, error); +__attribute__((interrupt)) void ISR8Handler(EXCEPTION_FRAME* Frame) { + ISR_Error_Common(Frame, 8); } -__attribute__((interrupt)) void isr9(struct int_frame* r) { - isr_common(r, 9); +__attribute__((interrupt)) void ISR9Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 9); } -__attribute__((interrupt)) void isr10(struct int_frame* r, size_t error) { - isr_error_common(r, 10, error); +__attribute__((interrupt)) void ISR10Handler(EXCEPTION_FRAME* Frame) { + ISR_Error_Common(Frame, 10); } -__attribute__((interrupt)) void isr11(struct int_frame* r, size_t error) { - isr_error_common(r, 11, error); +__attribute__((interrupt)) void ISR11Handler(EXCEPTION_FRAME* Frame) { + ISR_Error_Common(Frame, 11); } -__attribute__((interrupt)) void isr12(struct int_frame* r, size_t error) { - isr_error_common(r, 12, error); +__attribute__((interrupt)) void ISR12Handler(EXCEPTION_FRAME* Frame) { + ISR_Error_Common(Frame, 12); } -__attribute__((interrupt)) void isr13(struct int_frame* r, size_t error) { - isr_error_common(r, 13, error); +__attribute__((interrupt)) void ISR13Handler(EXCEPTION_FRAME* Frame) { + ISR_Error_Common(Frame, 13); } -__attribute__((interrupt)) void isr14(struct int_frame* r, size_t error) { - isr_error_common(r, 14, error); +__attribute__((interrupt)) void ISR14Handler(EXCEPTION_FRAME* Frame) { + ISR_Error_Common(Frame, 14); } -__attribute__((interrupt)) void isr15(struct int_frame* r) { - isr_common(r, 15); +__attribute__((interrupt)) void ISR15Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 15); } -__attribute__((interrupt)) void isr16(struct int_frame* r) { - isr_common(r, 16); +__attribute__((interrupt)) void ISR16Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 16); } -__attribute__((interrupt)) void isr17(struct int_frame* r) { - isr_common(r, 17); +__attribute__((interrupt)) void ISR17Handler(EXCEPTION_FRAME* Frame) { + ISR_Error_Common(Frame, 17); } -__attribute__((interrupt)) void isr18(struct int_frame* r) { - isr_common(r, 18); +__attribute__((interrupt)) void ISR18Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 18); } -__attribute__((interrupt)) void isr19(struct int_frame* r) { - isr_common(r, 19); +__attribute__((interrupt)) void ISR19Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 19); } -__attribute__((interrupt)) void isr20(struct int_frame* r) { - isr_common(r, 20); +__attribute__((interrupt)) void ISR20Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 20); } -__attribute__((interrupt)) void isr21(struct int_frame* r) { - isr_common(r, 21); +__attribute__((interrupt)) void ISR21Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 21); } -__attribute__((interrupt)) void isr22(struct int_frame* r) { - isr_common(r, 22); +__attribute__((interrupt)) void ISR22Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 22); } -__attribute__((interrupt)) void isr23(struct int_frame* r) { - isr_common(r, 23); +__attribute__((interrupt)) void ISR23Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 23); } -__attribute__((interrupt)) void isr24(struct int_frame* r) { - isr_common(r, 24); +__attribute__((interrupt)) void ISR24Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 24); } -__attribute__((interrupt)) void isr25(struct int_frame* r) { - isr_common(r, 25); +__attribute__((interrupt)) void ISR25Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 25); } -__attribute__((interrupt)) void isr26(struct int_frame* r) { - isr_common(r, 26); +__attribute__((interrupt)) void ISR26Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 26); } -__attribute__((interrupt)) void isr27(struct int_frame* r) { - isr_common(r, 27); +__attribute__((interrupt)) void ISR27Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 27); } -__attribute__((interrupt)) void isr28(struct int_frame* r) { - isr_common(r, 28); +__attribute__((interrupt)) void ISR28Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 28); } -__attribute__((interrupt)) void isr29(struct int_frame* r) { - isr_common(r, 29); +__attribute__((interrupt)) void ISR29Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 29); } -__attribute__((interrupt)) void isr30(struct int_frame* r) { - isr_common(r, 30); +__attribute__((interrupt)) void ISR30Handler(EXCEPTION_FRAME* Frame) { + ISR_Error_Common(Frame, 30); } -__attribute__((interrupt)) void isr31(struct int_frame* r) { - isr_common(r, 31); +__attribute__((interrupt)) void ISR31Handler(INTERRUPT_FRAME* Frame) { + ISR_Common(Frame, 31); } -__attribute__((interrupt)) void irq0(struct int_frame* r) { - irq_common(r, 0); +__attribute__((interrupt)) void irq0(INTERRUPT_FRAME* Frame) { + IRQ_Common(Frame, 0); } -__attribute__((interrupt)) void irq1(struct int_frame* r) { - irq_common(r, 1); +__attribute__((interrupt)) void irq1(INTERRUPT_FRAME* Frame) { + IRQ_Common(Frame, 1); } -__attribute__((interrupt)) void irq2(struct int_frame* r) { - irq_common(r, 2); +__attribute__((interrupt)) void irq2(INTERRUPT_FRAME* Frame) { + IRQ_Common(Frame, 2); } -__attribute__((interrupt)) void irq3(struct int_frame* r) { - irq_common(r, 3); +__attribute__((interrupt)) void irq3(INTERRUPT_FRAME* Frame) { + IRQ_Common(Frame, 3); } -__attribute__((interrupt)) void irq4(struct int_frame* r) { - irq_common(r, 4); +__attribute__((interrupt)) void irq4(INTERRUPT_FRAME* Frame) { + IRQ_Common(Frame, 4); } -__attribute__((interrupt)) void irq5(struct int_frame* r) { - irq_common(r, 5); +__attribute__((interrupt)) void irq5(INTERRUPT_FRAME* Frame) { + IRQ_Common(Frame, 5); } -__attribute__((interrupt)) void irq6(struct int_frame* r) { - irq_common(r, 6); +__attribute__((interrupt)) void irq6(INTERRUPT_FRAME* Frame) { + IRQ_Common(Frame, 6); } -__attribute__((interrupt)) void irq7(struct int_frame* r) { - irq_common(r, 7); +__attribute__((interrupt)) void irq7(INTERRUPT_FRAME* Frame) { + IRQ_Common(Frame, 7); } -__attribute__((interrupt)) void irq8(struct int_frame* r) { - irq_common(r, 8); +__attribute__((interrupt)) void irq8(INTERRUPT_FRAME* Frame) { + IRQ_Common(Frame, 8); } -__attribute__((interrupt)) void irq9(struct int_frame* r) { - irq_common(r, 9); +__attribute__((interrupt)) void irq9(INTERRUPT_FRAME* Frame) { + IRQ_Common(Frame, 9); } -__attribute__((interrupt)) void irq10(struct int_frame* r) { - irq_common(r, 10); +__attribute__((interrupt)) void irq10(INTERRUPT_FRAME* Frame) { + IRQ_Common(Frame, 10); } -__attribute__((interrupt)) void irq11(struct int_frame* r) { - irq_common(r, 11); +__attribute__((interrupt)) void irq11(INTERRUPT_FRAME* Frame) { + IRQ_Common(Frame, 11); } -__attribute__((interrupt)) void irq12(struct int_frame* r) { - irq_common(r, 12); +__attribute__((interrupt)) void irq12(INTERRUPT_FRAME* Frame) { + IRQ_Common(Frame, 12); } -__attribute__((interrupt)) void irq13(struct int_frame* r) { - irq_common(r, 13); +__attribute__((interrupt)) void irq13(INTERRUPT_FRAME* Frame) { + IRQ_Common(Frame, 13); } -__attribute__((interrupt)) void irq14(struct int_frame* r) { - irq_common(r, 14); +__attribute__((interrupt)) void irq14(INTERRUPT_FRAME* Frame) { + IRQ_Common(Frame, 14); } -__attribute__((interrupt)) void irq15(struct int_frame* r) { - irq_common(r, 15); +__attribute__((interrupt)) void irq15(INTERRUPT_FRAME* Frame) { + IRQ_Common(Frame, 15); } \ No newline at end of file