It's interrupt time, baby.
This should bring the kernel to a working state. Don't forget that the interrupts.c file absolutely must be compiled with -mgeneral-regs-only. All the other files absolutely must be compiled with -mavx2. :)
This commit is contained in:
parent
debd7ef91a
commit
f92114539c
|
@ -576,13 +576,13 @@ typedef struct __attribute__((aligned(64), packed)) {
|
||||||
} XSAVE_AREA;
|
} 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,
|
||||||
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",
|
"Division by Zero",
|
||||||
"Debug",
|
"Debug",
|
||||||
"Non Maskable Interrupt",
|
"Non Maskable Interrupt",
|
||||||
|
@ -686,9 +686,11 @@ void ScanCPUFeatures(size_t RAX, size_t RCX);
|
||||||
|
|
||||||
/* ==================== Interrupts ==================== */
|
/* ==================== Interrupts ==================== */
|
||||||
|
|
||||||
void IRQ_Common(INTERRUPT_FRAME* Frame);
|
void IRQ_Common(INTERRUPT_FRAME* Frame, size_t Interupt);
|
||||||
void ISR_Common(INTERRUPT_FRAME* Frame);
|
void ISR_Common(INTERRUPT_FRAME* Frame, size_t Interrupt);
|
||||||
void ISR_Error_Common(EXCEPTION_FRAME* Frame);
|
void ISR_Error_Common(EXCEPTION_FRAME* Frame, size_t Exception);
|
||||||
|
|
||||||
|
void RemapIRQControllers();
|
||||||
|
|
||||||
void ISR0Handler(INTERRUPT_FRAME* Frame); // Divide-By-Zero
|
void ISR0Handler(INTERRUPT_FRAME* Frame); // Divide-By-Zero
|
||||||
void ISR1Handler(INTERRUPT_FRAME* Frame); // Debug
|
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_install_handler(int irq, void (*handler)(INTERRUPT_FRAME* r));
|
||||||
void irq_uninstall_handler(int);
|
void irq_uninstall_handler(int);
|
||||||
void irq_install();
|
void irq_install();
|
||||||
void irq_remap();
|
|
||||||
void timer_install();
|
void timer_install();
|
||||||
|
|
||||||
/* ==================== Memory ==================== */
|
/* ==================== Memory ==================== */
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
* functions are in their own file to
|
* functions are in their own file to
|
||||||
* accomodate this.
|
* 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:
|
* Calling a function like so:
|
||||||
*
|
*
|
||||||
* __attribute__((interrupt)) isr1(registers_t* frame) {}
|
* __attribute__((interrupt)) isr1(registers_t* frame) {}
|
||||||
|
@ -28,10 +32,7 @@
|
||||||
* these having a size_t input as an error code.
|
* these having a size_t input as an error code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <kernel.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "kernel/descriptor_tables.h"
|
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
typedef unsigned long long int uword_t;
|
typedef unsigned long long int uword_t;
|
||||||
|
@ -39,6 +40,90 @@ typedef unsigned long long int uword_t;
|
||||||
typedef unsigned int uword_t;
|
typedef unsigned int uword_t;
|
||||||
#endif
|
#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
|
/* The interrupt numbers, their meanings, and
|
||||||
* special information is laid out below:
|
* special information is laid out below:
|
||||||
*
|
*
|
||||||
|
@ -64,149 +149,149 @@ typedef unsigned int uword_t;
|
||||||
* 19 to 31 - Reserved
|
* 19 to 31 - Reserved
|
||||||
*/
|
*/
|
||||||
|
|
||||||
__attribute__((interrupt)) void isr0(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR0Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 0);
|
ISR_Common(Frame, 0);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr1(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR1Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 1);
|
ISR_Common(Frame, 1);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr2(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR2Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 2);
|
ISR_Common(Frame, 2);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr3(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR3Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 3);
|
ISR_Common(Frame, 3);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr4(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR4Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 4);
|
ISR_Common(Frame, 4);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr5(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR5Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 5);
|
ISR_Common(Frame, 5);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr6(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR6Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 6);
|
ISR_Common(Frame, 6);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr7(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR7Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 7);
|
ISR_Common(Frame, 7);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr8(struct int_frame* r, size_t error) {
|
__attribute__((interrupt)) void ISR8Handler(EXCEPTION_FRAME* Frame) {
|
||||||
isr_error_common(r, 8, error);
|
ISR_Error_Common(Frame, 8);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr9(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR9Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 9);
|
ISR_Common(Frame, 9);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr10(struct int_frame* r, size_t error) {
|
__attribute__((interrupt)) void ISR10Handler(EXCEPTION_FRAME* Frame) {
|
||||||
isr_error_common(r, 10, error);
|
ISR_Error_Common(Frame, 10);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr11(struct int_frame* r, size_t error) {
|
__attribute__((interrupt)) void ISR11Handler(EXCEPTION_FRAME* Frame) {
|
||||||
isr_error_common(r, 11, error);
|
ISR_Error_Common(Frame, 11);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr12(struct int_frame* r, size_t error) {
|
__attribute__((interrupt)) void ISR12Handler(EXCEPTION_FRAME* Frame) {
|
||||||
isr_error_common(r, 12, error);
|
ISR_Error_Common(Frame, 12);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr13(struct int_frame* r, size_t error) {
|
__attribute__((interrupt)) void ISR13Handler(EXCEPTION_FRAME* Frame) {
|
||||||
isr_error_common(r, 13, error);
|
ISR_Error_Common(Frame, 13);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr14(struct int_frame* r, size_t error) {
|
__attribute__((interrupt)) void ISR14Handler(EXCEPTION_FRAME* Frame) {
|
||||||
isr_error_common(r, 14, error);
|
ISR_Error_Common(Frame, 14);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr15(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR15Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 15);
|
ISR_Common(Frame, 15);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr16(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR16Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 16);
|
ISR_Common(Frame, 16);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr17(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR17Handler(EXCEPTION_FRAME* Frame) {
|
||||||
isr_common(r, 17);
|
ISR_Error_Common(Frame, 17);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr18(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR18Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 18);
|
ISR_Common(Frame, 18);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr19(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR19Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 19);
|
ISR_Common(Frame, 19);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr20(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR20Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 20);
|
ISR_Common(Frame, 20);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr21(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR21Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 21);
|
ISR_Common(Frame, 21);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr22(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR22Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 22);
|
ISR_Common(Frame, 22);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr23(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR23Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 23);
|
ISR_Common(Frame, 23);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr24(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR24Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 24);
|
ISR_Common(Frame, 24);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr25(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR25Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 25);
|
ISR_Common(Frame, 25);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr26(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR26Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 26);
|
ISR_Common(Frame, 26);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr27(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR27Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 27);
|
ISR_Common(Frame, 27);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr28(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR28Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 28);
|
ISR_Common(Frame, 28);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr29(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR29Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 29);
|
ISR_Common(Frame, 29);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr30(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR30Handler(EXCEPTION_FRAME* Frame) {
|
||||||
isr_common(r, 30);
|
ISR_Error_Common(Frame, 30);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void isr31(struct int_frame* r) {
|
__attribute__((interrupt)) void ISR31Handler(INTERRUPT_FRAME* Frame) {
|
||||||
isr_common(r, 31);
|
ISR_Common(Frame, 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
__attribute__((interrupt)) void irq0(struct int_frame* r) {
|
__attribute__((interrupt)) void irq0(INTERRUPT_FRAME* Frame) {
|
||||||
irq_common(r, 0);
|
IRQ_Common(Frame, 0);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void irq1(struct int_frame* r) {
|
__attribute__((interrupt)) void irq1(INTERRUPT_FRAME* Frame) {
|
||||||
irq_common(r, 1);
|
IRQ_Common(Frame, 1);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void irq2(struct int_frame* r) {
|
__attribute__((interrupt)) void irq2(INTERRUPT_FRAME* Frame) {
|
||||||
irq_common(r, 2);
|
IRQ_Common(Frame, 2);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void irq3(struct int_frame* r) {
|
__attribute__((interrupt)) void irq3(INTERRUPT_FRAME* Frame) {
|
||||||
irq_common(r, 3);
|
IRQ_Common(Frame, 3);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void irq4(struct int_frame* r) {
|
__attribute__((interrupt)) void irq4(INTERRUPT_FRAME* Frame) {
|
||||||
irq_common(r, 4);
|
IRQ_Common(Frame, 4);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void irq5(struct int_frame* r) {
|
__attribute__((interrupt)) void irq5(INTERRUPT_FRAME* Frame) {
|
||||||
irq_common(r, 5);
|
IRQ_Common(Frame, 5);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void irq6(struct int_frame* r) {
|
__attribute__((interrupt)) void irq6(INTERRUPT_FRAME* Frame) {
|
||||||
irq_common(r, 6);
|
IRQ_Common(Frame, 6);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void irq7(struct int_frame* r) {
|
__attribute__((interrupt)) void irq7(INTERRUPT_FRAME* Frame) {
|
||||||
irq_common(r, 7);
|
IRQ_Common(Frame, 7);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void irq8(struct int_frame* r) {
|
__attribute__((interrupt)) void irq8(INTERRUPT_FRAME* Frame) {
|
||||||
irq_common(r, 8);
|
IRQ_Common(Frame, 8);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void irq9(struct int_frame* r) {
|
__attribute__((interrupt)) void irq9(INTERRUPT_FRAME* Frame) {
|
||||||
irq_common(r, 9);
|
IRQ_Common(Frame, 9);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void irq10(struct int_frame* r) {
|
__attribute__((interrupt)) void irq10(INTERRUPT_FRAME* Frame) {
|
||||||
irq_common(r, 10);
|
IRQ_Common(Frame, 10);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void irq11(struct int_frame* r) {
|
__attribute__((interrupt)) void irq11(INTERRUPT_FRAME* Frame) {
|
||||||
irq_common(r, 11);
|
IRQ_Common(Frame, 11);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void irq12(struct int_frame* r) {
|
__attribute__((interrupt)) void irq12(INTERRUPT_FRAME* Frame) {
|
||||||
irq_common(r, 12);
|
IRQ_Common(Frame, 12);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void irq13(struct int_frame* r) {
|
__attribute__((interrupt)) void irq13(INTERRUPT_FRAME* Frame) {
|
||||||
irq_common(r, 13);
|
IRQ_Common(Frame, 13);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void irq14(struct int_frame* r) {
|
__attribute__((interrupt)) void irq14(INTERRUPT_FRAME* Frame) {
|
||||||
irq_common(r, 14);
|
IRQ_Common(Frame, 14);
|
||||||
}
|
}
|
||||||
__attribute__((interrupt)) void irq15(struct int_frame* r) {
|
__attribute__((interrupt)) void irq15(INTERRUPT_FRAME* Frame) {
|
||||||
irq_common(r, 15);
|
IRQ_Common(Frame, 15);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user