diff --git a/Kernel.cpp b/Kernel.cpp index 5d03f3c..ce3733b 100644 --- a/Kernel.cpp +++ b/Kernel.cpp @@ -1,6 +1,8 @@ #include "kernel.h" +#include #include +#include #include #include #include @@ -9,6 +11,7 @@ BootInfo *bInfo = nullptr; Video::Display *Display = nullptr; +SymbolResolver::Symbols *KernelSymbolTable = nullptr; // For the Display class. Printing on first buffer. extern "C" void putchar(char c) { Display->Print(c, 0); } @@ -39,17 +42,25 @@ EXTERNC void kernel_aarch64_entry(uint64_t dtb_ptr32, uint64_t x1, uint64_t x2, EXTERNC void kernel_entry(BootInfo *Info) { - InitializeMemoryManagement(Info); trace("Hello, World!"); + InitializeMemoryManagement(Info); bInfo = (BootInfo *)KernelAllocator.RequestPages(TO_PAGES(sizeof(BootInfo))); memcpy(bInfo, Info, sizeof(BootInfo)); debug("BootInfo structure is at %p", bInfo); Display = new Video::Display(bInfo->Framebuffer[0]); printf_("%s - %s(%s)\n", KERNEL_NAME, KERNEL_VERSION, GIT_COMMIT_SHORT); + /**************************************************************************************/ + KPrint("Initializing GDT and IDT"); + Interrupts::Initialize(); + KPrint("Loading kernel symbols"); + KernelSymbolTable = new SymbolResolver::Symbols((uint64_t)Info->Kernel.FileBase); + // printf_("%s\n", CPU::Vendor()); + // printf_("%s\n", CPU::Name()); + // printf_("%s\n", CPU::Hypervisor()); Display->SetBuffer(0); - for (size_t i = 0; i < 70; i++) - KPrint("Hello, World! (%ld)", i); - + for (size_t i = 0; i < 250; i++) + KPrint("Hello, World! (%02ld)", i); + asm("int $0x1"); while (1) CPU::Halt(); } diff --git a/arch/amd64/cpu/GlobalDescriptorTable.cpp b/arch/amd64/cpu/GlobalDescriptorTable.cpp new file mode 100644 index 0000000..a74ffe3 --- /dev/null +++ b/arch/amd64/cpu/GlobalDescriptorTable.cpp @@ -0,0 +1,73 @@ +#include "gdt.hpp" + +#include +#include +#include + +namespace GlobalDescriptorTable +{ + static GlobalDescriptorTableEntries GDTEntries = { + {.Length = 0x0000, .BaseLow = 0x0000, .BaseMiddle = 0x00, .Access = 0b00000000, .Flags = 0b00000000, .BaseHigh = 0x00}, // null + {.Length = 0x0000, .BaseLow = 0x0000, .BaseMiddle = 0x00, .Access = 0b10011010, .Flags = 0b00100000, .BaseHigh = 0x00}, // kernel code + {.Length = 0x0000, .BaseLow = 0x0000, .BaseMiddle = 0x00, .Access = 0b10010010, .Flags = 0b00000000, .BaseHigh = 0x00}, // kernel data + {.Length = 0x0000, .BaseLow = 0x0000, .BaseMiddle = 0x00, .Access = 0b11111010, .Flags = 0b00100000, .BaseHigh = 0x00}, // user code + {.Length = 0x0000, .BaseLow = 0x0000, .BaseMiddle = 0x00, .Access = 0b11110010, .Flags = 0b00000000, .BaseHigh = 0x00}, // user data + {.Length = 0, .Low = 0, .Middle = 0, .Flags1 = 0b10001001, .Flags2 = 0b00000000, .High = 0, .Upper32 = 0, .Reserved = 0}}; // tss + + GlobalDescriptorTableDescriptor gdt = {.Length = sizeof(GlobalDescriptorTableEntries) - 1, .Entries = &GDTEntries}; + + TaskStateSegment tss[256] = { + 0, + {0, 0, 0}, + 0, + {0, 0, 0, 0, 0, 0, 0}, + 0, + 0, + }; + + void Init(int Core) + { + CPU::x64::lgdt(&gdt); + + asmv("movq %%rsp, %%rax\n" + "pushq $16\n" + "pushq %%rax\n" + "pushfq\n" + "pushq $8\n" + "pushq $1f\n" + "iretq\n" + "1:\n" + "movw $16, %%ax\n" + "movw %%ax, %%ds\n" + "movw %%ax, %%es\n" + "movw $0x1b, %%ax\n" + "movw %%ax, %%fs\n" + "movw %%ax, %%gs\n" :: + : "memory", "rax"); + + uint64_t Base = (uint64_t)&tss[Core]; + gdt.Entries->TaskStateSegment.Length = Base + sizeof(tss[0]); + gdt.Entries->TaskStateSegment.Low = (uint16_t)(Base & 0xFFFF); + gdt.Entries->TaskStateSegment.Middle = (uint8_t)((Base >> 16) & 0xFF); + gdt.Entries->TaskStateSegment.High = (uint8_t)((Base >> 24) & 0xFF); + gdt.Entries->TaskStateSegment.Upper32 = (uint32_t)((Base >> 32) & 0xFFFFFFFF); + gdt.Entries->TaskStateSegment.Flags1 = 0b10001001; + gdt.Entries->TaskStateSegment.Flags2 = 0b00000000; + tss[Core].IOMapBaseAddressOffset = sizeof(TaskStateSegment); + tss[Core].StackPointer[0] = (uint64_t)KernelAllocator.RequestPage(); + tss[Core].InterruptStackTable[0] = (uint64_t)KernelAllocator.RequestPage(); + tss[Core].InterruptStackTable[1] = (uint64_t)KernelAllocator.RequestPage(); + tss[Core].InterruptStackTable[2] = (uint64_t)KernelAllocator.RequestPage(); + + CPU::x64::ltr(GDT_TSS); + asm volatile("mov %%rsp, %0" + : "=r"(tss[Core].StackPointer[0])); + + trace("GDT_KERNEL_CODE: %#lx", GDT_KERNEL_CODE); + trace("GDT_KERNEL_DATA: %#lx", GDT_KERNEL_DATA); + trace("GDT_USER_DATA: %#lx", GDT_USER_DATA); + trace("GDT_USER_CODE: %#lx", GDT_USER_CODE); + trace("GDT_TSS: %#lx", GDT_TSS); + trace("Global Descriptor Table initialized"); + } +} \ No newline at end of file diff --git a/arch/amd64/cpu/InterruptDescriptorTable.cpp b/arch/amd64/cpu/InterruptDescriptorTable.cpp new file mode 100644 index 0000000..2f44a03 --- /dev/null +++ b/arch/amd64/cpu/InterruptDescriptorTable.cpp @@ -0,0 +1,696 @@ +#include "idt.hpp" + +#include +#include + +#include "gdt.hpp" + +// TODO: IMPLEMENT "MainInterruptHandler" +extern "C" void MainInterruptHandler(void *Data) +{ + debug("Interrupt: %p", Data); + asmv("cli"); + asmv("hlt"); +} + +// TODO: IMPLEMENT "ExceptionHandler" +extern "C" void ExceptionHandler(void *Data) +{ + debug("Exception: %p", Data); + asmv("cli"); + asmv("hlt"); +} + +namespace InterruptDescriptorTable +{ + static InterruptDescriptorTableEntry Entries[0x100]; + + InterruptDescriptorTableDescriptor idtd = {.Length = sizeof(Entries) - 1, + .Entries = Entries}; + + void SetEntry(uint8_t Index, + void (*Base)(), + InterruptDescriptorTableFlags Attribute, + uint8_t InterruptStackTable, + InterruptDescriptorTableFlags Ring, + uint16_t SegmentSelector) + { + Entries[Index].BaseLow = (uint16_t)((uint64_t)Base & 0xFFFF); + Entries[Index].BaseHigh = (uint64_t)((uint64_t)Base >> 16 /* & 0xFFFF */); + Entries[Index].SegmentSelector = SegmentSelector; + Entries[Index].Flags = Attribute; + Entries[Index].Reserved1 = 0; + Entries[Index].Reserved2 = 0; + Entries[Index].Reserved3 = 0; + Entries[Index].InterruptStackTable = InterruptStackTable; + Entries[Index].Ring = Ring; + Entries[Index].Present = 1; + } + + extern "C" __attribute__((naked, used, no_stack_protector)) void ExceptionHandlerStub() + { + asm("cld\n" // clear direction flag + + // push all registers + "pushq %rax\n" + "pushq %rbx\n" + "pushq %rcx\n" + "pushq %rdx\n" + "pushq %rsi\n" + "pushq %rdi\n" + "pushq %rbp\n" + "pushq %r8\n" + "pushq %r9\n" + "pushq %r10\n" + "pushq %r11\n" + "pushq %r12\n" + "pushq %r13\n" + "pushq %r14\n" + "pushq %r15\n" + // push ds segment + "movq %ds, %rax\n" + "pushq %rax\n" + + "movq %rsp, %rdi\n" + "call ExceptionHandler\n" + + // pop ds segment + "popq %rax\n" + + // pop all registers + "popq %r15\n" + "popq %r14\n" + "popq %r13\n" + "popq %r12\n" + "popq %r11\n" + "popq %r10\n" + "popq %r9\n" + "popq %r8\n" + "popq %rbp\n" + "popq %rdi\n" + "popq %rsi\n" + "popq %rdx\n" + "popq %rcx\n" + "popq %rbx\n" + "popq %rax\n" + + "addq $16, %rsp\n" + "iretq"); // pop CS RIP RFLAGS SS ESP + } + + extern "C" __attribute__((naked, used, no_stack_protector)) void InterruptHandlerStub() + { + asm("cld\n" + "pushq %rax\n" + "pushq %rbx\n" + "pushq %rcx\n" + "pushq %rdx\n" + "pushq %rsi\n" + "pushq %rdi\n" + "pushq %rbp\n" + "pushq %r8\n" + "pushq %r9\n" + "pushq %r10\n" + "pushq %r11\n" + "pushq %r12\n" + "pushq %r13\n" + "pushq %r14\n" + "pushq %r15\n" + // push ds segment + "movq %ds, %rax\n" + "pushq %rax\n" + + "movq %rsp, %rdi\n" + "call MainInterruptHandler\n" + + // pop ds segment + "popq %rax\n" + + "popq %r15\n" + "popq %r14\n" + "popq %r13\n" + "popq %r12\n" + "popq %r11\n" + "popq %r10\n" + "popq %r9\n" + "popq %r8\n" + "popq %rbp\n" + "popq %rdi\n" + "popq %rsi\n" + "popq %rdx\n" + "popq %rcx\n" + "popq %rbx\n" + "popq %rax\n" + + "addq $16, %rsp\n" + "iretq"); + } + +#pragma region Exceptions + +#define EXCEPTION_HANDLER(num) \ + __attribute__((naked, no_stack_protector)) static void InterruptHandler_##num() \ + { \ + asm("pushq $0\npushq $" #num "\n" \ + "jmp ExceptionHandlerStub"); \ + } + +#define EXCEPTION_ERROR_HANDLER(num) \ + __attribute__((naked, no_stack_protector)) static void InterruptHandler_##num() \ + { \ + asm("pushq $" #num "\n" \ + "jmp ExceptionHandlerStub"); \ + } + +#define INTERRUPT_HANDLER(num) \ + __attribute__((naked, used, no_stack_protector)) void InterruptHandler_##num() \ + { \ + asm("pushq $0\npushq $" #num "\n" \ + "jmp InterruptHandlerStub\n"); \ + } + + // ISR + EXCEPTION_HANDLER(0x0); + EXCEPTION_HANDLER(0x1); + EXCEPTION_HANDLER(0x2); + EXCEPTION_HANDLER(0x3); + EXCEPTION_HANDLER(0x4); + EXCEPTION_HANDLER(0x5); + EXCEPTION_HANDLER(0x6); + EXCEPTION_HANDLER(0x7); + EXCEPTION_ERROR_HANDLER(0x8); + EXCEPTION_HANDLER(0x9); + EXCEPTION_ERROR_HANDLER(0xa); + EXCEPTION_ERROR_HANDLER(0xb); + EXCEPTION_ERROR_HANDLER(0xc); + EXCEPTION_ERROR_HANDLER(0xd); + EXCEPTION_ERROR_HANDLER(0xe); + EXCEPTION_HANDLER(0xf); + EXCEPTION_ERROR_HANDLER(0x10); + EXCEPTION_HANDLER(0x11); + EXCEPTION_HANDLER(0x12); + EXCEPTION_HANDLER(0x13); + EXCEPTION_HANDLER(0x14); + EXCEPTION_HANDLER(0x15); + EXCEPTION_HANDLER(0x16); + EXCEPTION_HANDLER(0x17); + EXCEPTION_HANDLER(0x18); + EXCEPTION_HANDLER(0x19); + EXCEPTION_HANDLER(0x1a); + EXCEPTION_HANDLER(0x1b); + EXCEPTION_HANDLER(0x1c); + EXCEPTION_HANDLER(0x1d); + EXCEPTION_HANDLER(0x1e); + EXCEPTION_HANDLER(0x1f); + // IRQ + INTERRUPT_HANDLER(0x20) + INTERRUPT_HANDLER(0x21) + INTERRUPT_HANDLER(0x22) + INTERRUPT_HANDLER(0x23) + INTERRUPT_HANDLER(0x24) + INTERRUPT_HANDLER(0x25) + INTERRUPT_HANDLER(0x26) + INTERRUPT_HANDLER(0x27) + INTERRUPT_HANDLER(0x28) + INTERRUPT_HANDLER(0x29) + INTERRUPT_HANDLER(0x2a) + INTERRUPT_HANDLER(0x2b) + INTERRUPT_HANDLER(0x2c) + INTERRUPT_HANDLER(0x2d) + INTERRUPT_HANDLER(0x2e) + INTERRUPT_HANDLER(0x2f) + + INTERRUPT_HANDLER(0x30) + INTERRUPT_HANDLER(0x31) + INTERRUPT_HANDLER(0x32) + INTERRUPT_HANDLER(0x33) + INTERRUPT_HANDLER(0x34) + INTERRUPT_HANDLER(0x35) + INTERRUPT_HANDLER(0x36) + INTERRUPT_HANDLER(0x37) + INTERRUPT_HANDLER(0x38) + INTERRUPT_HANDLER(0x39) + INTERRUPT_HANDLER(0x3a) + INTERRUPT_HANDLER(0x3b) + INTERRUPT_HANDLER(0x3c) + INTERRUPT_HANDLER(0x3d) + INTERRUPT_HANDLER(0x3e) + INTERRUPT_HANDLER(0x3f) + INTERRUPT_HANDLER(0x40) + INTERRUPT_HANDLER(0x41) + INTERRUPT_HANDLER(0x42) + INTERRUPT_HANDLER(0x43) + INTERRUPT_HANDLER(0x44) + INTERRUPT_HANDLER(0x45) + INTERRUPT_HANDLER(0x46) + INTERRUPT_HANDLER(0x47) + INTERRUPT_HANDLER(0x48) + INTERRUPT_HANDLER(0x49) + INTERRUPT_HANDLER(0x4a) + INTERRUPT_HANDLER(0x4b) + INTERRUPT_HANDLER(0x4c) + INTERRUPT_HANDLER(0x4d) + INTERRUPT_HANDLER(0x4e) + INTERRUPT_HANDLER(0x4f) + INTERRUPT_HANDLER(0x50) + INTERRUPT_HANDLER(0x51) + INTERRUPT_HANDLER(0x52) + INTERRUPT_HANDLER(0x53) + INTERRUPT_HANDLER(0x54) + INTERRUPT_HANDLER(0x55) + INTERRUPT_HANDLER(0x56) + INTERRUPT_HANDLER(0x57) + INTERRUPT_HANDLER(0x58) + INTERRUPT_HANDLER(0x59) + INTERRUPT_HANDLER(0x5a) + INTERRUPT_HANDLER(0x5b) + INTERRUPT_HANDLER(0x5c) + INTERRUPT_HANDLER(0x5d) + INTERRUPT_HANDLER(0x5e) + INTERRUPT_HANDLER(0x5f) + INTERRUPT_HANDLER(0x60) + INTERRUPT_HANDLER(0x61) + INTERRUPT_HANDLER(0x62) + INTERRUPT_HANDLER(0x63) + INTERRUPT_HANDLER(0x64) + INTERRUPT_HANDLER(0x65) + INTERRUPT_HANDLER(0x66) + INTERRUPT_HANDLER(0x67) + INTERRUPT_HANDLER(0x68) + INTERRUPT_HANDLER(0x69) + INTERRUPT_HANDLER(0x6a) + INTERRUPT_HANDLER(0x6b) + INTERRUPT_HANDLER(0x6c) + INTERRUPT_HANDLER(0x6d) + INTERRUPT_HANDLER(0x6e) + INTERRUPT_HANDLER(0x6f) + INTERRUPT_HANDLER(0x70) + INTERRUPT_HANDLER(0x71) + INTERRUPT_HANDLER(0x72) + INTERRUPT_HANDLER(0x73) + INTERRUPT_HANDLER(0x74) + INTERRUPT_HANDLER(0x75) + INTERRUPT_HANDLER(0x76) + INTERRUPT_HANDLER(0x77) + INTERRUPT_HANDLER(0x78) + INTERRUPT_HANDLER(0x79) + INTERRUPT_HANDLER(0x7a) + INTERRUPT_HANDLER(0x7b) + INTERRUPT_HANDLER(0x7c) + INTERRUPT_HANDLER(0x7d) + INTERRUPT_HANDLER(0x7e) + INTERRUPT_HANDLER(0x7f) + INTERRUPT_HANDLER(0x80) + INTERRUPT_HANDLER(0x81) + INTERRUPT_HANDLER(0x82) + INTERRUPT_HANDLER(0x83) + INTERRUPT_HANDLER(0x84) + INTERRUPT_HANDLER(0x85) + INTERRUPT_HANDLER(0x86) + INTERRUPT_HANDLER(0x87) + INTERRUPT_HANDLER(0x88) + INTERRUPT_HANDLER(0x89) + INTERRUPT_HANDLER(0x8a) + INTERRUPT_HANDLER(0x8b) + INTERRUPT_HANDLER(0x8c) + INTERRUPT_HANDLER(0x8d) + INTERRUPT_HANDLER(0x8e) + INTERRUPT_HANDLER(0x8f) + INTERRUPT_HANDLER(0x90) + INTERRUPT_HANDLER(0x91) + INTERRUPT_HANDLER(0x92) + INTERRUPT_HANDLER(0x93) + INTERRUPT_HANDLER(0x94) + INTERRUPT_HANDLER(0x95) + INTERRUPT_HANDLER(0x96) + INTERRUPT_HANDLER(0x97) + INTERRUPT_HANDLER(0x98) + INTERRUPT_HANDLER(0x99) + INTERRUPT_HANDLER(0x9a) + INTERRUPT_HANDLER(0x9b) + INTERRUPT_HANDLER(0x9c) + INTERRUPT_HANDLER(0x9d) + INTERRUPT_HANDLER(0x9e) + INTERRUPT_HANDLER(0x9f) + INTERRUPT_HANDLER(0xa0) + INTERRUPT_HANDLER(0xa1) + INTERRUPT_HANDLER(0xa2) + INTERRUPT_HANDLER(0xa3) + INTERRUPT_HANDLER(0xa4) + INTERRUPT_HANDLER(0xa5) + INTERRUPT_HANDLER(0xa6) + INTERRUPT_HANDLER(0xa7) + INTERRUPT_HANDLER(0xa8) + INTERRUPT_HANDLER(0xa9) + INTERRUPT_HANDLER(0xaa) + INTERRUPT_HANDLER(0xab) + INTERRUPT_HANDLER(0xac) + INTERRUPT_HANDLER(0xad) + INTERRUPT_HANDLER(0xae) + INTERRUPT_HANDLER(0xaf) + INTERRUPT_HANDLER(0xb0) + INTERRUPT_HANDLER(0xb1) + INTERRUPT_HANDLER(0xb2) + INTERRUPT_HANDLER(0xb3) + INTERRUPT_HANDLER(0xb4) + INTERRUPT_HANDLER(0xb5) + INTERRUPT_HANDLER(0xb6) + INTERRUPT_HANDLER(0xb7) + INTERRUPT_HANDLER(0xb8) + INTERRUPT_HANDLER(0xb9) + INTERRUPT_HANDLER(0xba) + INTERRUPT_HANDLER(0xbb) + INTERRUPT_HANDLER(0xbc) + INTERRUPT_HANDLER(0xbd) + INTERRUPT_HANDLER(0xbe) + INTERRUPT_HANDLER(0xbf) + INTERRUPT_HANDLER(0xc0) + INTERRUPT_HANDLER(0xc1) + INTERRUPT_HANDLER(0xc2) + INTERRUPT_HANDLER(0xc3) + INTERRUPT_HANDLER(0xc4) + INTERRUPT_HANDLER(0xc5) + INTERRUPT_HANDLER(0xc6) + INTERRUPT_HANDLER(0xc7) + INTERRUPT_HANDLER(0xc8) + INTERRUPT_HANDLER(0xc9) + INTERRUPT_HANDLER(0xca) + INTERRUPT_HANDLER(0xcb) + INTERRUPT_HANDLER(0xcc) + INTERRUPT_HANDLER(0xcd) + INTERRUPT_HANDLER(0xce) + INTERRUPT_HANDLER(0xcf) + INTERRUPT_HANDLER(0xd0) + INTERRUPT_HANDLER(0xd1) + INTERRUPT_HANDLER(0xd2) + INTERRUPT_HANDLER(0xd3) + INTERRUPT_HANDLER(0xd4) + INTERRUPT_HANDLER(0xd5) + INTERRUPT_HANDLER(0xd6) + INTERRUPT_HANDLER(0xd7) + INTERRUPT_HANDLER(0xd8) + INTERRUPT_HANDLER(0xd9) + INTERRUPT_HANDLER(0xda) + INTERRUPT_HANDLER(0xdb) + INTERRUPT_HANDLER(0xdc) + INTERRUPT_HANDLER(0xdd) + INTERRUPT_HANDLER(0xde) + INTERRUPT_HANDLER(0xdf) + INTERRUPT_HANDLER(0xe0) + INTERRUPT_HANDLER(0xe1) + INTERRUPT_HANDLER(0xe2) + INTERRUPT_HANDLER(0xe3) + INTERRUPT_HANDLER(0xe4) + INTERRUPT_HANDLER(0xe5) + INTERRUPT_HANDLER(0xe6) + INTERRUPT_HANDLER(0xe7) + INTERRUPT_HANDLER(0xe8) + INTERRUPT_HANDLER(0xe9) + INTERRUPT_HANDLER(0xea) + INTERRUPT_HANDLER(0xeb) + INTERRUPT_HANDLER(0xec) + INTERRUPT_HANDLER(0xed) + INTERRUPT_HANDLER(0xee) + INTERRUPT_HANDLER(0xef) + INTERRUPT_HANDLER(0xf0) + INTERRUPT_HANDLER(0xf1) + INTERRUPT_HANDLER(0xf2) + INTERRUPT_HANDLER(0xf3) + INTERRUPT_HANDLER(0xf4) + INTERRUPT_HANDLER(0xf5) + INTERRUPT_HANDLER(0xf6) + INTERRUPT_HANDLER(0xf7) + INTERRUPT_HANDLER(0xf8) + INTERRUPT_HANDLER(0xf9) + INTERRUPT_HANDLER(0xfa) + INTERRUPT_HANDLER(0xfb) + INTERRUPT_HANDLER(0xfc) + INTERRUPT_HANDLER(0xfd) + INTERRUPT_HANDLER(0xfe) + INTERRUPT_HANDLER(0xff) + +#pragma endregion Exceptions + + void Init(int Core) + { + SetEntry(0x0, InterruptHandler_0x0, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x1, InterruptHandler_0x1, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x2, InterruptHandler_0x2, FlagGate_32BIT_TRAP, 2, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x3, InterruptHandler_0x3, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x4, InterruptHandler_0x4, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x5, InterruptHandler_0x5, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x6, InterruptHandler_0x6, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x7, InterruptHandler_0x7, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x8, InterruptHandler_0x8, FlagGate_32BIT_TRAP, 3, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x9, InterruptHandler_0x9, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xa, InterruptHandler_0xa, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xb, InterruptHandler_0xb, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xc, InterruptHandler_0xc, FlagGate_32BIT_TRAP, 3, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xd, InterruptHandler_0xd, FlagGate_32BIT_TRAP, 3, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xe, InterruptHandler_0xe, FlagGate_32BIT_TRAP, 3, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xf, InterruptHandler_0xf, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x10, InterruptHandler_0x10, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x11, InterruptHandler_0x11, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x12, InterruptHandler_0x12, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x13, InterruptHandler_0x13, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x14, InterruptHandler_0x14, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x15, InterruptHandler_0x15, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x16, InterruptHandler_0x16, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x17, InterruptHandler_0x17, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x18, InterruptHandler_0x18, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x19, InterruptHandler_0x19, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x1a, InterruptHandler_0x1a, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x1b, InterruptHandler_0x1b, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x1c, InterruptHandler_0x1c, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x1d, InterruptHandler_0x1d, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x1e, InterruptHandler_0x1e, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x1f, InterruptHandler_0x1f, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); + // IRQ + SetEntry(0x20, InterruptHandler_0x20, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x21, InterruptHandler_0x21, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x22, InterruptHandler_0x22, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x23, InterruptHandler_0x23, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x24, InterruptHandler_0x24, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x25, InterruptHandler_0x25, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x26, InterruptHandler_0x26, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x27, InterruptHandler_0x27, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x28, InterruptHandler_0x28, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x29, InterruptHandler_0x29, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x2a, InterruptHandler_0x2a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x2b, InterruptHandler_0x2b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x2c, InterruptHandler_0x2c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x2d, InterruptHandler_0x2d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x2e, InterruptHandler_0x2e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x2f, InterruptHandler_0x2f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + + SetEntry(0x30, InterruptHandler_0x30, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x31, InterruptHandler_0x31, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x32, InterruptHandler_0x32, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x33, InterruptHandler_0x33, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x34, InterruptHandler_0x34, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x35, InterruptHandler_0x35, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x36, InterruptHandler_0x36, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x37, InterruptHandler_0x37, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x38, InterruptHandler_0x38, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x39, InterruptHandler_0x39, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x3a, InterruptHandler_0x3a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x3b, InterruptHandler_0x3b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x3c, InterruptHandler_0x3c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x3d, InterruptHandler_0x3d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x3e, InterruptHandler_0x3e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x3f, InterruptHandler_0x3f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x40, InterruptHandler_0x40, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x41, InterruptHandler_0x41, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x42, InterruptHandler_0x42, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x43, InterruptHandler_0x43, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x44, InterruptHandler_0x44, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x45, InterruptHandler_0x45, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x46, InterruptHandler_0x46, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x47, InterruptHandler_0x47, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x48, InterruptHandler_0x48, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x49, InterruptHandler_0x49, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x4a, InterruptHandler_0x4a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x4b, InterruptHandler_0x4b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x4c, InterruptHandler_0x4c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x4d, InterruptHandler_0x4d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x4e, InterruptHandler_0x4e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x4f, InterruptHandler_0x4f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x50, InterruptHandler_0x50, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x51, InterruptHandler_0x51, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x52, InterruptHandler_0x52, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x53, InterruptHandler_0x53, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x54, InterruptHandler_0x54, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x55, InterruptHandler_0x55, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x56, InterruptHandler_0x56, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x57, InterruptHandler_0x57, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x58, InterruptHandler_0x58, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x59, InterruptHandler_0x59, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x5a, InterruptHandler_0x5a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x5b, InterruptHandler_0x5b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x5c, InterruptHandler_0x5c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x5d, InterruptHandler_0x5d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x5e, InterruptHandler_0x5e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x5f, InterruptHandler_0x5f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x60, InterruptHandler_0x60, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x61, InterruptHandler_0x61, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x62, InterruptHandler_0x62, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x63, InterruptHandler_0x63, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x64, InterruptHandler_0x64, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x65, InterruptHandler_0x65, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x66, InterruptHandler_0x66, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x67, InterruptHandler_0x67, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x68, InterruptHandler_0x68, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x69, InterruptHandler_0x69, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x6a, InterruptHandler_0x6a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x6b, InterruptHandler_0x6b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x6c, InterruptHandler_0x6c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x6d, InterruptHandler_0x6d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x6e, InterruptHandler_0x6e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x6f, InterruptHandler_0x6f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x70, InterruptHandler_0x70, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x71, InterruptHandler_0x71, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x72, InterruptHandler_0x72, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x73, InterruptHandler_0x73, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x74, InterruptHandler_0x74, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x75, InterruptHandler_0x75, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x76, InterruptHandler_0x76, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x77, InterruptHandler_0x77, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x78, InterruptHandler_0x78, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x79, InterruptHandler_0x79, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x7a, InterruptHandler_0x7a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x7b, InterruptHandler_0x7b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x7c, InterruptHandler_0x7c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x7d, InterruptHandler_0x7d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x7e, InterruptHandler_0x7e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x7f, InterruptHandler_0x7f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x80, InterruptHandler_0x80, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x81, InterruptHandler_0x81, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x82, InterruptHandler_0x82, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x83, InterruptHandler_0x83, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x84, InterruptHandler_0x84, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x85, InterruptHandler_0x85, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x86, InterruptHandler_0x86, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x87, InterruptHandler_0x87, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x88, InterruptHandler_0x88, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x89, InterruptHandler_0x89, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x8a, InterruptHandler_0x8a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x8b, InterruptHandler_0x8b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x8c, InterruptHandler_0x8c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x8d, InterruptHandler_0x8d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x8e, InterruptHandler_0x8e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x8f, InterruptHandler_0x8f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x90, InterruptHandler_0x90, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x91, InterruptHandler_0x91, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x92, InterruptHandler_0x92, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x93, InterruptHandler_0x93, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x94, InterruptHandler_0x94, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x95, InterruptHandler_0x95, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x96, InterruptHandler_0x96, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x97, InterruptHandler_0x97, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x98, InterruptHandler_0x98, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x99, InterruptHandler_0x99, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x9a, InterruptHandler_0x9a, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x9b, InterruptHandler_0x9b, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x9c, InterruptHandler_0x9c, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x9d, InterruptHandler_0x9d, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x9e, InterruptHandler_0x9e, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0x9f, InterruptHandler_0x9f, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xa0, InterruptHandler_0xa0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xa1, InterruptHandler_0xa1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xa2, InterruptHandler_0xa2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xa3, InterruptHandler_0xa3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xa4, InterruptHandler_0xa4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xa5, InterruptHandler_0xa5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xa6, InterruptHandler_0xa6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xa7, InterruptHandler_0xa7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xa8, InterruptHandler_0xa8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xa9, InterruptHandler_0xa9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xaa, InterruptHandler_0xaa, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xab, InterruptHandler_0xab, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xac, InterruptHandler_0xac, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xad, InterruptHandler_0xad, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xae, InterruptHandler_0xae, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xaf, InterruptHandler_0xaf, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xb0, InterruptHandler_0xb0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xb1, InterruptHandler_0xb1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xb2, InterruptHandler_0xb2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xb3, InterruptHandler_0xb3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xb4, InterruptHandler_0xb4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xb5, InterruptHandler_0xb5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xb6, InterruptHandler_0xb6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xb7, InterruptHandler_0xb7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xb8, InterruptHandler_0xb8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xb9, InterruptHandler_0xb9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xba, InterruptHandler_0xba, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xbb, InterruptHandler_0xbb, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xbc, InterruptHandler_0xbc, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xbd, InterruptHandler_0xbd, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xbe, InterruptHandler_0xbe, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xbf, InterruptHandler_0xbf, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xc0, InterruptHandler_0xc0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xc1, InterruptHandler_0xc1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xc2, InterruptHandler_0xc2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xc3, InterruptHandler_0xc3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xc4, InterruptHandler_0xc4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xc5, InterruptHandler_0xc5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xc6, InterruptHandler_0xc6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xc7, InterruptHandler_0xc7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xc8, InterruptHandler_0xc8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xc9, InterruptHandler_0xc9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xca, InterruptHandler_0xca, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xcb, InterruptHandler_0xcb, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xcc, InterruptHandler_0xcc, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xcd, InterruptHandler_0xcd, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xce, InterruptHandler_0xce, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xcf, InterruptHandler_0xcf, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xd0, InterruptHandler_0xd0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xd1, InterruptHandler_0xd1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xd2, InterruptHandler_0xd2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xd3, InterruptHandler_0xd3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xd4, InterruptHandler_0xd4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xd5, InterruptHandler_0xd5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xd6, InterruptHandler_0xd6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xd7, InterruptHandler_0xd7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xd8, InterruptHandler_0xd8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xd9, InterruptHandler_0xd9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xda, InterruptHandler_0xda, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xdb, InterruptHandler_0xdb, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xdc, InterruptHandler_0xdc, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xdd, InterruptHandler_0xdd, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xde, InterruptHandler_0xde, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xdf, InterruptHandler_0xdf, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xe0, InterruptHandler_0xe0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xe1, InterruptHandler_0xe1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xe2, InterruptHandler_0xe2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xe3, InterruptHandler_0xe3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xe4, InterruptHandler_0xe4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xe5, InterruptHandler_0xe5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xe6, InterruptHandler_0xe6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xe7, InterruptHandler_0xe7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xe8, InterruptHandler_0xe8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xe9, InterruptHandler_0xe9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xea, InterruptHandler_0xea, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xeb, InterruptHandler_0xeb, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xec, InterruptHandler_0xec, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xed, InterruptHandler_0xed, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xee, InterruptHandler_0xee, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xef, InterruptHandler_0xef, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xf0, InterruptHandler_0xf0, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xf1, InterruptHandler_0xf1, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xf2, InterruptHandler_0xf2, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xf3, InterruptHandler_0xf3, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xf4, InterruptHandler_0xf4, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xf5, InterruptHandler_0xf5, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xf6, InterruptHandler_0xf6, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xf7, InterruptHandler_0xf7, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xf8, InterruptHandler_0xf8, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xf9, InterruptHandler_0xf9, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xfa, InterruptHandler_0xfa, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xfb, InterruptHandler_0xfb, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xfc, InterruptHandler_0xfc, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xfd, InterruptHandler_0xfd, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xfe, InterruptHandler_0xfe, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + SetEntry(0xff, InterruptHandler_0xff, FlagGate_32BIT_TRAP, 0, FlagGate_RING0, GDT_KERNEL_CODE); + CPU::x64::lidt(&idtd); + } +} diff --git a/arch/amd64/cpu/gdt.hpp b/arch/amd64/cpu/gdt.hpp new file mode 100644 index 0000000..a94b403 --- /dev/null +++ b/arch/amd64/cpu/gdt.hpp @@ -0,0 +1,73 @@ +#ifndef __FENNIX_KERNEL_GDT_H__ +#define __FENNIX_KERNEL_GDT_H__ + +#include + +namespace GlobalDescriptorTable +{ + typedef struct _TaskStateSegmentEntry + { + uint16_t Length; + uint16_t Low; + uint8_t Middle; + uint8_t Flags1; + uint8_t Flags2; + uint8_t High; + uint32_t Upper32; + uint32_t Reserved; + } __attribute__((packed)) TaskStateSegmentEntry; + + typedef struct _TaskStateSegment + { + uint32_t Reserved0; + uint64_t StackPointer[3]; + uint64_t Reserved1; + uint64_t InterruptStackTable[7]; + uint16_t Reserved2; + uint16_t IOMapBaseAddressOffset; + } __attribute__((packed)) TaskStateSegment; + + typedef struct _GlobalDescriptorTableEntry + { + /** @brief Length [Bits 0-15] */ + uint16_t Length; + /** @brief Low Base [Bits 0-15] */ + uint16_t BaseLow; + /** @brief Middle Base [Bits 0-23] */ + uint8_t BaseMiddle; + /** @brief Access */ + uint8_t Access; + /** @brief Flags [Bits 16-19] */ + uint8_t Flags; + /** @brief High Base [Bits 24-31] */ + uint8_t BaseHigh; + } __attribute__((packed)) GlobalDescriptorTableEntry; + + typedef struct _GlobalDescriptorTableEntries + { + GlobalDescriptorTableEntry Null; + GlobalDescriptorTableEntry Code; + GlobalDescriptorTableEntry Data; + GlobalDescriptorTableEntry UserCode; + GlobalDescriptorTableEntry UserData; + TaskStateSegmentEntry TaskStateSegment; + } __attribute__((packed)) GlobalDescriptorTableEntries; + + typedef struct _GlobalDescriptorTableDescriptor + { + /** @brief GDT entries length */ + uint16_t Length; + /** @brief GDT entries address */ + GlobalDescriptorTableEntries *Entries; + } __attribute__((packed)) GlobalDescriptorTableDescriptor; + + void Init(int Core); +} + +#define GDT_KERNEL_CODE offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, Code) +#define GDT_KERNEL_DATA offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, Data) +#define GDT_USER_DATA (offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, UserData) | 3) +#define GDT_USER_CODE (offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, UserCode) | 3) +#define GDT_TSS (offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, TaskStateSegment) | 3) + +#endif // !__FENNIX_KERNEL_GDT_H__ diff --git a/arch/amd64/cpu/idt.hpp b/arch/amd64/cpu/idt.hpp new file mode 100644 index 0000000..ecea884 --- /dev/null +++ b/arch/amd64/cpu/idt.hpp @@ -0,0 +1,46 @@ +#ifndef __FENNIX_KERNEL_IDT_H__ +#define __FENNIX_KERNEL_IDT_H__ + +#include + +namespace InterruptDescriptorTable +{ + typedef enum _InterruptDescriptorTableFlags + { + FlagGate_TASK = 0b0101, + FlagGate_16BIT_INT = 0b0110, + FlagGate_16BIT_TRAP = 0b0111, + FlagGate_32BIT_INT = 0b1110, + FlagGate_32BIT_TRAP = 0b1111, + FlagGate_RING0 = 0b0, + FlagGate_RING1 = 0b1, + FlagGate_RING2 = 0b10, + FlagGate_RING3 = 0b11, + FlagGate_PRESENT = 0b1, // Not sure if this is correct. + } InterruptDescriptorTableFlags; + + typedef struct _InterruptDescriptorTableEntry + { + uint64_t BaseLow : 16; + uint64_t SegmentSelector : 16; + uint64_t InterruptStackTable : 3; + uint64_t Reserved1 : 5; + InterruptDescriptorTableFlags Flags : 4; + uint64_t Reserved2 : 1; + uint64_t Ring : 2; + uint64_t Present : 1; + uint64_t BaseHigh : 48; + uint64_t Reserved3 : 32; + } __attribute__((packed)) InterruptDescriptorTableEntry; + + typedef struct _InterruptDescriptorTableDescriptor + { + uint16_t Length; + InterruptDescriptorTableEntry *Entries; + } __attribute__((packed)) InterruptDescriptorTableDescriptor; + + void SetEntry(uint8_t Index, void (*Base)(), InterruptDescriptorTableFlags Attribute, uint8_t InterruptStackTable, InterruptDescriptorTableFlags Ring, uint16_t SegmentSelector); + void Init(int Core); +} + +#endif // !__FENNIX_KERNEL_IDT_H__ diff --git a/core/Interrupts/IntManager.cpp b/core/Interrupts/IntManager.cpp new file mode 100644 index 0000000..8abc412 --- /dev/null +++ b/core/Interrupts/IntManager.cpp @@ -0,0 +1,25 @@ +#include + +#if defined(__amd64__) +#include "../arch/amd64/cpu/gdt.hpp" +#include "../arch/amd64/cpu/idt.hpp" +#elif defined(__i386__) +#include "../arch/i686/cpu/gdt.hpp" +#include "../arch/i686/cpu/idt.hpp" +#elif defined(__aarch64__) +#include "../arch/aarch64/cpu/gdt.hpp" +#include "../arch/aarch64/cpu/idt.hpp" +#endif + +namespace Interrupts +{ + void Initialize() + { +#if defined(__amd64__) + GlobalDescriptorTable::Init(0); + InterruptDescriptorTable::Init(0); +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif + } +} diff --git a/core/README.md b/core/README.md index df98851..7d3b7b3 100644 --- a/core/README.md +++ b/core/README.md @@ -9,3 +9,14 @@ This directory contains the core components of the project. These components are Contains the memory management code. It is responsible for allocating and freeing memory. It also provides the `kmalloc`, `kcalloc`, `krealloc` and `kfree` functions that are used by the rest of the kernel. + +## 📺 Video + +Contains the video management code. +It is responsible for printing text to the screen. + +## 🖥 CPU + +Contains the CPU management code. +It is responsible for initializing the GDT and IDT. +More code related is in the `arch` directory. diff --git a/include/cpu.hpp b/include/cpu.hpp index 9a634b9..c6dc2ee 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -8,167 +8,256 @@ */ namespace CPU { + /** + * @brief Enum for CPU::Interrupts() function. + */ + enum InterruptsType + { /** - * @brief Enum for CPU::Interrupts() function. + * @brief Check if interrupts are enabled. */ - enum InterruptsType + Check, + /** + * @brief Enable interrupts. + */ + Enable, + /** + * @brief Disable interrupts. + */ + Disable + }; + + /** + * @brief Get CPU vendor identifier. + * + * @return char* CPU Vendor ID. + */ + char *Vendor(); + + /** + * @brief Get CPU name. + * + * @return char* CPU Name. + */ + char *Name(); + + /** + * @brief Get CPU hypervisor vendor. + * + * @return char* Hypervisor vendor. + */ + char *Hypervisor(); + + /** + * @brief Pause the CPU + */ + void Pause(); + + /** + * @brief Halt the CPU + */ + void Halt(); + + /** + * @brief Check if interrupts are enabled + * + * @return true If InterruptsType::Check and interrupts are enabled, or if other InterruptsType were executed successfully + * @return false If InterruptsType::Check and interrupts are disabled, or if other InterruptsType failed + */ + bool Interrupts(InterruptsType Type = Check); + + /** + * @brief Get/Set the CPU's page table + * + * @param PT The new page table, if empty, the current page table will be returned + * @return void* The current page table + */ + void *PageTable(void *PT = nullptr); + + namespace MemBar + { + static inline void Barrier() { - /** - * @brief Check if interrupts are enabled. - */ - Check, - /** - * @brief Enable interrupts. - */ - Enable, - /** - * @brief Disable interrupts. - */ - Disable - }; - - /** - * @brief Get CPU vendor identifier. - * - * @return char* CPU Vendor ID. - */ - char *Vendor(); - - /** - * @brief Get CPU name. - * - * @return char* CPU Name. - */ - char *Name(); - - /** - * @brief Get CPU hypervisor vendor. - * - * @return char* Hypervisor vendor. - */ - char *Hypervisor(); - - /** - * @brief Pause the CPU - */ - void Pause(); - - /** - * @brief Halt the CPU - */ - void Halt(); - - /** - * @brief Check if interrupts are enabled - * - * @return true If InterruptsType::Check and interrupts are enabled, or if other InterruptsType were executed successfully - * @return false If InterruptsType::Check and interrupts are disabled, or if other InterruptsType failed - */ - bool Interrupts(InterruptsType Type = Check); - - /** - * @brief Get/Set the CPU's page table - * - * @param PT The new page table, if empty, the current page table will be returned - * @return void* The current page table - */ - void *PageTable(void *PT = nullptr); - - namespace MemBar - { - static inline void Barrier() - { #if defined(__amd64__) || defined(__i386__) - asmv("" :: - : "memory"); + asmv("" :: + : "memory"); #elif defined(__aarch64__) - asmv("dmb ish" :: - : "memory"); + asmv("dmb ish" :: + : "memory"); #endif - } - - static inline void Fence() - { -#if defined(__amd64__) || defined(__i386__) - asmv("mfence" :: - : "memory"); -#elif defined(__aarch64__) - asmv("dmb ish" :: - : "memory"); -#endif - } - - static inline void StoreFence() - { -#if defined(__amd64__) || defined(__i386__) - asmv("sfence" :: - : "memory"); -#elif defined(__aarch64__) - asmv("dmb ishst" :: - : "memory"); -#endif - } - - static inline void LoadFence() - { -#if defined(__amd64__) || defined(__i386__) - asmv("lfence" :: - : "memory"); -#elif defined(__aarch64__) - asmv("dmb ishld" :: - : "memory"); -#endif - } } - namespace x86 + static inline void Fence() { - static inline void lgdt(void *gdt) - { #if defined(__amd64__) || defined(__i386__) - asmv("lgdt (%0)" - : - : "r"(gdt)); + asmv("mfence" :: + : "memory"); +#elif defined(__aarch64__) + asmv("dmb ish" :: + : "memory"); #endif - } - - static inline void lidt(void *idt) - { -#if defined(__amd64__) || defined(__i386__) - asmv("lidt (%0)" - : - : "r"(idt)); -#endif - } - - static inline void ltr(uint16_t Segment) - { -#if defined(__amd64__) || defined(__i386__) - asmv("ltr %0" - : - : "r"(Segment)); -#endif - } - - static inline void invlpg(void *Address) - { -#if defined(__amd64__) || defined(__i386__) - asmv("invlpg (%0)" - : - : "r"(Address) - : "memory"); -#endif - } - - static inline void cpuid(uint32_t Function, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) - { -#if defined(__amd64__) || defined(__i386__) - asmv("cpuid" - : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) - : "a"(Function)); -#endif - } } + + static inline void StoreFence() + { +#if defined(__amd64__) || defined(__i386__) + asmv("sfence" :: + : "memory"); +#elif defined(__aarch64__) + asmv("dmb ishst" :: + : "memory"); +#endif + } + + static inline void LoadFence() + { +#if defined(__amd64__) || defined(__i386__) + asmv("lfence" :: + : "memory"); +#elif defined(__aarch64__) + asmv("dmb ishld" :: + : "memory"); +#endif + } + } + + namespace x32 + { + } + + namespace x64 + { + typedef union + { + struct + { + /** @brief Carry Flag */ + uint64_t CF : 1; + /** @brief Reserved */ + uint64_t always_one : 1; + /** @brief Parity Flag */ + uint64_t PF : 1; + /** @brief Reserved */ + uint64_t _reserved0 : 1; + /** @brief Auxiliary Carry Flag */ + uint64_t AF : 1; + /** @brief Reserved */ + uint64_t _reserved1 : 1; + /** @brief Zero Flag */ + uint64_t ZF : 1; + /** @brief Sign Flag */ + uint64_t SF : 1; + /** @brief Trap Flag */ + uint64_t TF : 1; + /** @brief Interrupt Enable Flag */ + uint64_t IF : 1; + /** @brief Direction Flag */ + uint64_t DF : 1; + /** @brief Overflow Flag */ + uint64_t OF : 1; + /** @brief I/O Privilege Level */ + uint64_t IOPL : 2; + /** @brief Nested Task */ + uint64_t NT : 1; + /** @brief Reserved */ + uint64_t _reserved2 : 1; + /** @brief Resume Flag */ + uint64_t RF : 1; + /** @brief Virtual 8086 Mode */ + uint64_t VM : 1; + /** @brief Alignment Check */ + uint64_t AC : 1; + /** @brief Virtual Interrupt Flag */ + uint64_t VIF : 1; + /** @brief Virtual Interrupt Pending */ + uint64_t VIP : 1; + /** @brief ID Flag */ + uint64_t ID : 1; + /** @brief Reserved */ + uint64_t _reserved3 : 10; + }; + uint64_t raw; + } RFLAGS; + + typedef struct _TrapFrame + { + // uint64_t gs; // General-purpose Segment + // uint64_t fs; // General-purpose Segment + // uint64_t es; // Extra Segment (used for string operations) + uint64_t ds; // Data Segment + + uint64_t r15; // General purpose + uint64_t r14; // General purpose + uint64_t r13; // General purpose + uint64_t r12; // General purpose + uint64_t r11; // General purpose + uint64_t r10; // General purpose + uint64_t r9; // General purpose + uint64_t r8; // General purpose + + uint64_t rbp; // Base Pointer (meant for stack frames) + uint64_t rdi; // Destination index for string operations + uint64_t rsi; // Source index for string operations + uint64_t rdx; // Data (commonly extends the A register) + uint64_t rcx; // Counter + uint64_t rbx; // Base + uint64_t rax; // Accumulator + + uint64_t int_num; // Interrupt Number + uint64_t error_code; // Error code + uint64_t rip; // Instruction Pointer + uint64_t cs; // Code Segment + RFLAGS rflags; // Register Flags + uint64_t rsp; // Stack Pointer + uint64_t ss; // Stack Segment + } TrapFrame; + + static inline void lgdt(void *gdt) + { +#if defined(__amd64__) + asmv("lgdt (%0)" + : + : "r"(gdt)); +#endif + } + + static inline void lidt(void *idt) + { +#if defined(__amd64__) + asmv("lidt (%0)" + : + : "r"(idt)); +#endif + } + + static inline void ltr(uint16_t Segment) + { +#if defined(__amd64__) + asmv("ltr %0" + : + : "r"(Segment)); +#endif + } + + static inline void invlpg(void *Address) + { +#if defined(__amd64__) + asmv("invlpg (%0)" + : + : "r"(Address) + : "memory"); +#endif + } + + static inline void cpuid(uint32_t Function, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) + { +#if defined(__amd64__) + asmv("cpuid" + : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) + : "a"(Function)); +#endif + } + } } #endif // !__FENNIX_KERNEL_CPU_H__ diff --git a/include/interrupts.hpp b/include/interrupts.hpp new file mode 100644 index 0000000..a8736f8 --- /dev/null +++ b/include/interrupts.hpp @@ -0,0 +1,11 @@ +#ifndef __FENNIX_KERNEL_INTERRUPTS_H__ +#define __FENNIX_KERNEL_INTERRUPTS_H__ + +#include + +namespace Interrupts +{ + void Initialize(); +} + +#endif // !__FENNIX_KERNEL_INTERRUPTS_H__ diff --git a/include/types.h b/include/types.h index 891a9dd..b5cea7c 100644 --- a/include/types.h +++ b/include/types.h @@ -45,6 +45,8 @@ typedef __builtin_va_list va_list; #define ALIGN_UP(x, align) ((__typeof__(x))(((uint64_t)(x) + ((align)-1)) & (~((align)-1)))) #define ALIGN_DOWN(x, align) ((__typeof__(x))((x) & (~((align)-1)))) +#define offsetof(type, member) __builtin_offsetof(type, member) + typedef __INT8_TYPE__ int8_t; typedef __INT16_TYPE__ int16_t; typedef __INT32_TYPE__ int32_t;