#include "interrupt.h" #include "handlers.h" #include "../memory/memory.h" #include "../runtime/stdio.h" #include "../runtime/panic_assert.h" #include "testcode.h" interrupt_DescriptorTableReference *interrupt_IDTR, *interrupt_GDTR; bool interrupt_Enabled; /* SYSV_ABI void interrupt_MapHandler(void *handler, int interrupt) { //io_Printf("interrupt_MapHandler: handler %llx, int %d\n", handler, interrupt); uint64_t *base = (uint64_t *)(KERNEL_IDT_MAPPING + interrupt * 16ull); uint64_t b = 0; b |= (uint64_t)handler & 0xFFFFull; // Offset[15:0], 15:0 b |= (uint64_t)GDT_EXEC_SELECTOR << 16; // Segment Selector, 31:16 b |= IDT_TYPE_32_INTERRUPT_GATE; // Type = 32-bit Interrupt Gate, 44:40 b |= IDT_RING0; // Ring 0, 46:45 b |= IDT_PRESENT; // Present, 47 b |= ((uint64_t)handler & 0xFFFF0000ull) << 32; // Offset[31:16], 63:48 *base = b; *(base + 1) = (uint64_t)handler >> 32; } */ // defined in assembly SYSV_ABI void interrupt_MapHandler(void *handler, int interrupt); void interrupt_Init() { assert(sizeof(interrupt_DescriptorTableReference) == 10 && "GDTR/IDTR size must be 10 bytes"); assert(offsetof(interrupt_DescriptorTableReference, base) == 2 && "GDTR/IDTR must be packed"); // allocate GDTR io_WriteConsoleASCII("interrupt_Init() calling\n"); // set the 2 dummy gdts uint64_t *gdt = (uint64_t *)KERNEL_GDT_MAPPING; gdt[0] = 0; gdt[1] = GDT_EXEC; gdt[2] = GDT_DATA; gdt[3] = GDT_EXEC_RING3; gdt[4] = GDT_DATA_RING3; io_WriteConsoleASCII("GDT Installed\n"); interrupt_LoadGDT(4 * GDT_SIZE_BYTES - 1, (void *)KERNEL_GDT_MAPPING); // set it! io_WriteConsoleASCII("GDT OK\n"); //interrupt_Testcode(); io_WriteConsoleASCII("Testcode OK\n"); interrupt_MapHandler(interrupt_Int0, 0); interrupt_MapHandler(interrupt_Int1, 1); interrupt_MapHandler(interrupt_Int2, 2); interrupt_MapHandler(interrupt_Int3, 3); interrupt_MapHandler(interrupt_Int4, 4); interrupt_MapHandler(interrupt_Int5, 5); interrupt_MapHandler(interrupt_Int6, 6); interrupt_MapHandler(interrupt_Int7, 7); interrupt_MapHandler(interrupt_Int8, 8); interrupt_MapHandler(interrupt_Int9, 9); interrupt_MapHandler(interrupt_Int10, 10); interrupt_MapHandler(interrupt_Int11, 11); interrupt_MapHandler(interrupt_Int12, 12); interrupt_MapHandler(interrupt_Int13, 13); interrupt_MapHandler(interrupt_Int14, 14); interrupt_MapHandler(interrupt_Int15, 15); interrupt_MapHandler(interrupt_Int16, 16); interrupt_MapHandler(interrupt_Int17, 17); interrupt_MapHandler(interrupt_Int18, 18); interrupt_MapHandler(interrupt_Int19, 19); interrupt_MapHandler(interrupt_Int20, 20); interrupt_MapHandler(interrupt_Int21, 21); interrupt_MapHandler(interrupt_Int22, 22); interrupt_MapHandler(interrupt_Int23, 23); interrupt_MapHandler(interrupt_Int24, 24); interrupt_MapHandler(interrupt_Int25, 25); interrupt_MapHandler(interrupt_Int26, 26); interrupt_MapHandler(interrupt_Int27, 27); interrupt_MapHandler(interrupt_Int28, 28); interrupt_MapHandler(interrupt_Int29, 29); interrupt_MapHandler(interrupt_Int30, 30); interrupt_MapHandler(interrupt_Int31, 31); interrupt_MapHandler(interrupt_Int128, 128); io_WriteConsoleASCII("IDT Installed\n"); interrupt_LoadIDT(KERNEL_IDT_SIZE - 1, (void *)KERNEL_IDT_MAPPING); // set it! io_WriteConsoleASCII("IDT OK\n"); interrupt_Enabled = true; asm volatile("sti"); interrupt_ReloadSegments(); io_WriteConsoleASCII("Segment Registers Reloaded\n"); }