From cabdc5263e8a93264baeb6d928b5a4412ba89807 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 14 Nov 2022 14:54:18 +0200 Subject: [PATCH] Kernel now compiles on x32 --- .vscode/c_cpp_properties.json | 8 +- .vscode/settings.json | 2 +- .../i686/cpu/SymmetricMultiprocessing.cpp | 2 + Architecture/i686/cpu/apic.hpp | 337 ++++++++++++++++++ .../i686/runtime/{crt1.S => crt1.asm} | 0 Architecture/i686/runtime/crti.S | 4 +- Architecture/i686/runtime/crtn.S | 4 +- Core/Crash/CrashDetails.cpp | 10 + Core/Crash/CrashHandler.cpp | 2 - Core/Crash/SFrame.cpp | 31 ++ Core/Crash/Screens/Details.cpp | 23 ++ Core/Crash/Screens/Main.cpp | 10 + Core/Crash/Screens/Tasks.cpp | 7 +- Core/Crash/UserHandler.cpp | 23 ++ Core/Crash/chfcts.hpp | 20 +- Core/Memory/VirtualMemoryManager.cpp | 2 +- Execute/Spawn.cpp | 15 +- Kernel.cpp | 5 + Library/cargs.c | 2 +- Makefile | 2 +- SystemCalls/Linux.cpp | 4 + SystemCalls/Native.cpp | 4 + SystemCalls/Syscalls.cpp | 2 +- Tasking/Task.cpp | 5 + include/abi.h | 1 + include/cpu.hpp | 294 ++++++++++++++- include/interrupts.hpp | 3 +- 27 files changed, 803 insertions(+), 19 deletions(-) create mode 100644 Architecture/i686/cpu/apic.hpp rename Architecture/i686/runtime/{crt1.S => crt1.asm} (100%) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index f03c3fd..97b2fc3 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -16,9 +16,11 @@ "compilerPath": "/usr/bin/gcc", "cStandard": "c17", "cppStandard": "c++20", - "intelliSenseMode": "gcc-x64", + "intelliSenseMode": "gcc-x86", "configurationProvider": "ms-vscode.makefile-tools", "compilerArgs": [ + "-m32", + //"-mcmodel=kernel", /* 64-bit only */ "-fno-rtti", "-fexceptions", "-fno-pic", @@ -31,11 +33,13 @@ "-mno-sse2", "-march=nehalem", "-pipe", - "-mcmodel=kernel", "-msoft-float", "-fno-builtin", "-ffreestanding", "-nostdinc", + "-Wl,-static,--no-dynamic-linker,-ztext", + "-shared", + "-zmax-page-size=0x1000", "-nostdinc++" ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 3776eb0..fb7fda8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,7 +3,7 @@ "C_Cpp.autocompleteAddParentheses": true, "C_Cpp.codeAnalysis.clangTidy.enabled": true, "C_Cpp.clang_format_style": "Visual Studio", - "C_Cpp.default.intelliSenseMode": "gcc-x64", + "C_Cpp.default.intelliSenseMode": "gcc-x86", "C_Cpp.default.cStandard": "c17", "C_Cpp.default.cppStandard": "c++20", "C_Cpp.intelliSenseMemoryLimit": 16384, diff --git a/Architecture/i686/cpu/SymmetricMultiprocessing.cpp b/Architecture/i686/cpu/SymmetricMultiprocessing.cpp index ed41f7b..20ad696 100644 --- a/Architecture/i686/cpu/SymmetricMultiprocessing.cpp +++ b/Architecture/i686/cpu/SymmetricMultiprocessing.cpp @@ -28,6 +28,8 @@ CPUData *GetCurrentCPU() namespace SMP { + int CPUCores = 0; + void Initialize(void *madt) { fixme("SMP::Initialize() is not implemented!"); diff --git a/Architecture/i686/cpu/apic.hpp b/Architecture/i686/cpu/apic.hpp new file mode 100644 index 0000000..48a574c --- /dev/null +++ b/Architecture/i686/cpu/apic.hpp @@ -0,0 +1,337 @@ +#ifndef __FENNIX_KERNEL_APIC_H__ +#define __FENNIX_KERNEL_APIC_H__ + +#include + +#include +#include + +namespace APIC +{ + enum APICRegisters + { + // source from: https://github.com/pdoane/osdev/blob/master/intr/local_apic.c + APIC_ID = 0x20, // Local APIC ID + APIC_VER = 0x30, // Local APIC Version + APIC_TPR = 0x80, // Task Priority + APIC_APR = 0x90, // Arbitration Priority + APIC_PPR = 0xA0, // Processor Priority + APIC_EOI = 0xB0, // EOI + APIC_RRD = 0xC0, // Remote Read + APIC_LDR = 0xD0, // Logical Destination + APIC_DFR = 0xE0, // Destination Format + APIC_SVR = 0xF0, // Spurious Interrupt Vector + APIC_ISR = 0x100, // In-Service (8 registers) + APIC_TMR = 0x180, // Trigger Mode (8 registers) + APIC_IRR = 0x200, // Interrupt Request (8 registers) + APIC_ESR = 0x280, // Error Status + APIC_ICRLO = 0x300, // Interrupt Command + APIC_ICRHI = 0x310, // Interrupt Command [63:32] + APIC_TIMER = 0x320, // LVT Timer + APIC_THERMAL = 0x330, // LVT Thermal Sensor + APIC_PERF = 0x340, // LVT Performance Counter + APIC_LINT0 = 0x350, // LVT LINT0 + APIC_LINT1 = 0x360, // LVT LINT1 + APIC_ERROR = 0x370, // LVT Error + APIC_TICR = 0x380, // Initial Count (for Timer) + APIC_TCCR = 0x390, // Current Count (for Timer) + APIC_TDCR = 0x3E0, // Divide Configuration (for Timer) + }; + + enum IOAPICRegisters + { + GetIOAPICVersion = 0x1 + }; + + enum IOAPICFlags + { + ActiveHighLow = 2, + EdgeLevel = 8 + }; + + enum APICDeliveryMode + { + Fixed = 0b000, + LowestPriority = 0b001, /* Reserved */ + SMI = 0b010, + APIC_DELIVERY_MODE_RESERVED0 = 0b011, /* Reserved */ + NMI = 0b100, + INIT = 0b101, + Startup = 0b110, + ExtINT = 0b111 /* Reserved */ + }; + + enum APICDestinationMode + { + Physical = 0b0, + Logical = 0b1 + }; + + enum APICDeliveryStatus + { + Idle = 0b0, + SendPending = 0b1 + }; + + enum APICLevel + { + DeAssert = 0b0, + Assert = 0b1 + }; + + enum APICTriggerMode + { + Edge = 0b0, + Level = 0b1 + }; + + enum APICDestinationShorthand + { + NoShorthand = 0b00, + Self = 0b01, + AllIncludingSelf = 0b10, + AllExcludingSelf = 0b11 + }; + + enum LVTTimerDivide + { + DivideBy2 = 0b000, + DivideBy4 = 0b001, + DivideBy8 = 0b010, + DivideBy16 = 0b011, + DivideBy32 = 0b100, + DivideBy64 = 0b101, + DivideBy128 = 0b110, + DivideBy1 = 0b111 + }; + + enum LVTTimerMask + { + Unmasked = 0b0, + Masked = 0b1 + }; + + enum LVTTimerMode + { + OneShot = 0b00, + Periodic = 0b01, + TSCDeadline = 0b10 + }; + + typedef union + { + struct + { + /** @brief Interrupt Vector */ + uint64_t Vector : 8; + /** @brief Reserved */ + uint64_t Reserved0 : 4; + /** + * @brief Delivery Status + * + * 0: Idle + * 1: Send Pending + */ + uint64_t DeliveryStatus : 1; + /** @brief Reserved */ + uint64_t Reserved1 : 3; + /** + * @brief Mask + * + * 0: Not masked + * 1: Masked + */ + uint64_t Mask : 1; + /** @brief Timer Mode + * + * 0: One-shot + * 1: Periodic + * 2: TSC-Deadline + */ + uint64_t TimerMode : 1; + /** @brief Reserved */ + uint64_t Reserved2 : 14; + }; + uint64_t raw; + } __attribute__((packed)) LVTTimer; + + typedef union + { + struct + { + /** @brief Spurious Vector */ + uint64_t Vector : 8; + /** @brief Enable or disable APIC software */ + uint64_t Software : 1; + /** @brief Focus Processor Checking */ + uint64_t FocusProcessorChecking : 1; + /** @brief Reserved */ + uint64_t Reserved : 2; + /** @brief Disable EOI Broadcast */ + uint64_t DisableEOIBroadcast : 1; + /** @brief Reserved */ + uint64_t Reserved1 : 19; + }; + uint64_t raw; + } __attribute__((packed)) Spurious; + + typedef union + { + struct + { + /** @brief Interrupt Vector */ + uint64_t Vector : 8; + /** @brief Delivery Mode */ + uint64_t DeliveryMode : 3; + /** @brief Destination Mode + * + * 0: Physical + * 1: Logical + */ + uint64_t DestinationMode : 1; + /** @brief Delivery Status + * + * @note Reserved when in x2APIC mode + */ + uint64_t DeliveryStatus : 1; + /** @brief Reserved */ + uint64_t Reserved0 : 1; + /** @brief Level + * + * 0: Deassert + * 1: Assert + */ + uint64_t Level : 1; + /** @brief Trigger Mode + * + * 0: Edge + * 1: Level + */ + uint64_t TriggerMode : 1; + /** @brief Reserved */ + uint64_t Reserved1 : 2; + /** @brief Destination Shorthand + * + * 0: No shorthand + * 1: Self + * 2: All including self + * 3: All excluding self + */ + uint64_t DestinationShorthand : 2; + /** @brief Reserved */ + uint64_t Reserved2 : 12; + }; + uint64_t raw; + } __attribute__((packed)) InterruptCommandRegisterLow; + + typedef union + { + struct + { + /** @brief Reserved */ + uint64_t Reserved0 : 24; + /** @brief Destination */ + uint64_t Destination : 8; + }; + uint64_t raw; + } __attribute__((packed)) InterruptCommandRegisterHigh; + + typedef union + { + struct + { + /** @brief Interrupt Vector */ + uint64_t Vector : 8; + /** @brief Delivery Mode */ + uint64_t DeliveryMode : 3; + /** @brief Destination Mode + * + * 0: Physical + * 1: Logical + */ + uint64_t DestinationMode : 1; + /** @brief Delivery Status */ + uint64_t DeliveryStatus : 1; + /** @brief Interrupt Input Pin Polarity + * + * 0: Active High + * 1: Active Low + */ + uint64_t Polarity : 1; + /** @brief Remote IRR */ + uint64_t RemoteIRR : 1; + /** @brief Trigger Mode + * + * 0: Edge + * 1: Level + */ + uint64_t TriggerMode : 1; + /** @brief Mask */ + uint64_t Mask : 1; + /** @brief Reserved */ + uint64_t Reserved0 : 15; + /** @brief Reserved */ + uint64_t Reserved1 : 24; + /** @brief Destination */ + uint64_t DestinationID : 8; + }; + struct + { + uint64_t Low; + uint64_t High; + } split; + uint64_t raw; + } __attribute__((packed)) IOAPICRedirectEntry; + + typedef union + { + struct + { + uint64_t Version : 8; + uint64_t Reserved : 8; + uint64_t MaximumRedirectionEntry : 8; + uint64_t Reserved2 : 8; + }; + uint64_t raw; + } __attribute__((packed)) IOAPICVersion; + + class APIC + { + private: + bool x2APICSupported = false; + uint64_t APICBaseAddress = 0; + + public: + uint32_t Read(uint32_t Register); + void Write(uint32_t Register, uint32_t Value); + void IOWrite(uint64_t Base, uint32_t Register, uint32_t Value); + uint32_t IORead(uint64_t Base, uint32_t Register); + void EOI(); + void RedirectIRQs(int CPU = 0); + void WaitForIPI(); + void IPI(uint8_t CPU, InterruptCommandRegisterLow icr); + void SendInitIPI(uint8_t CPU); + void SendStartupIPI(uint8_t CPU, uint64_t StartupAddress); + uint32_t IOGetMaxRedirect(uint32_t APICID); + void RawRedirectIRQ(uint8_t Vector, uint32_t GSI, uint16_t Flags, int CPU, int Status); + void RedirectIRQ(int CPU, uint8_t IRQ, int Status); + APIC(int Core); + ~APIC(); + }; + + class Timer : public Interrupts::Handler + { + private: + APIC *lapic; + uint64_t Ticks = 0; + void OnInterruptReceived(CPU::x64::TrapFrame *Frame); + + public: + uint64_t GetTicks() { return Ticks; } + void OneShot(uint32_t Vector, uint64_t Miliseconds); + Timer(APIC *apic); + ~Timer(); + }; +} + +#endif // !__FENNIX_KERNEL_APIC_H__ diff --git a/Architecture/i686/runtime/crt1.S b/Architecture/i686/runtime/crt1.asm similarity index 100% rename from Architecture/i686/runtime/crt1.S rename to Architecture/i686/runtime/crt1.asm diff --git a/Architecture/i686/runtime/crti.S b/Architecture/i686/runtime/crti.S index 7e721ed..7f9924a 100644 --- a/Architecture/i686/runtime/crti.S +++ b/Architecture/i686/runtime/crti.S @@ -3,11 +3,11 @@ .type _init, @function _init: push %ebp - movq %esp, %ebp + mov %esp, %ebp .section .fini .global _fini .type _fini, @function _fini: push %ebp - movq %esp, %ebp + mov %esp, %ebp diff --git a/Architecture/i686/runtime/crtn.S b/Architecture/i686/runtime/crtn.S index f09ced9..aa67ce1 100644 --- a/Architecture/i686/runtime/crtn.S +++ b/Architecture/i686/runtime/crtn.S @@ -1,7 +1,7 @@ .section .init - popq %ebp + pop %ebp ret .section .fini - popq %ebp + pop %ebp ret diff --git a/Core/Crash/CrashDetails.cpp b/Core/Crash/CrashDetails.cpp index 491abb3..aa71fba 100644 --- a/Core/Crash/CrashDetails.cpp +++ b/Core/Crash/CrashDetails.cpp @@ -53,7 +53,12 @@ __no_stack_protector void StackFaultExceptionHandler(CHArchTrapFrame *Frame) CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode}; CrashHandler::EHPrint("\eDD2920System crashed!\n"); CrashHandler::EHPrint("More info about the exception:\n"); +#if defined(__amd64__) CrashHandler::EHPrint("Stack segment fault at address %#lx\n", Frame->rip); +#elif defined(__i386__) + CrashHandler::EHPrint("Stack segment fault at address %#lx\n", Frame->eip); +#elif defined(__aarch64__) +#endif CrashHandler::EHPrint("External: %d\n", SelCode.External); CrashHandler::EHPrint("Table: %d\n", SelCode.Table); CrashHandler::EHPrint("Index: %#x\n", SelCode.Idx); @@ -96,7 +101,12 @@ __no_stack_protector void PageFaultExceptionHandler(CHArchTrapFrame *Frame) { CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode}; CrashHandler::EHPrint("\eDD2920System crashed!\n\eFFFFFF"); +#if defined(__amd64__) CrashHandler::EHPrint("An exception occurred at %#lx by %#lx\n", CPU::x64::readcr2().PFLA, Frame->rip); +#elif defined(__i386__) + CrashHandler::EHPrint("An exception occurred at %#lx by %#lx\n", CPU::x64::readcr2().PFLA, Frame->eip); +#elif defined(__aarch64__) +#endif CrashHandler::EHPrint("Page: %s\n", params.P ? "Present" : "Not Present"); CrashHandler::EHPrint("Write Operation: %s\n", params.W ? "Read-Only" : "Read-Write"); CrashHandler::EHPrint("Processor Mode: %s\n", params.U ? "User-Mode" : "Kernel-Mode"); diff --git a/Core/Crash/CrashHandler.cpp b/Core/Crash/CrashHandler.cpp index 8fa2c20..84713a9 100644 --- a/Core/Crash/CrashHandler.cpp +++ b/Core/Crash/CrashHandler.cpp @@ -511,9 +511,7 @@ namespace CrashHandler goto CrashEnd; #elif defined(__i386__) - void *Frame = Data; #elif defined(__aarch64__) - void *Frame = Data; #endif CrashEnd: diff --git a/Core/Crash/SFrame.cpp b/Core/Crash/SFrame.cpp index ea012bf..d5226c3 100644 --- a/Core/Crash/SFrame.cpp +++ b/Core/Crash/SFrame.cpp @@ -25,25 +25,51 @@ namespace CrashHandler __no_stack_protector void TraceFrames(CHArchTrapFrame *Frame, int Count) { + +#if defined(__amd64__) struct StackFrame *frames = (struct StackFrame *)Frame->rbp; // (struct StackFrame *)__builtin_frame_address(0); +#elif defined(__i386__) + struct StackFrame *frames = (struct StackFrame *)Frame->ebp; // (struct StackFrame *)__builtin_frame_address(0); +#elif defined(__aarch64__) +#endif debug("Stack tracing..."); EHPrint("\e7981FC\nStack Trace:\n"); if (!frames || !frames->rip || !frames->rbp) { +#if defined(__amd64__) EHPrint("\e2565CC%p", (void *)Frame->rip); +#elif defined(__i386__) + EHPrint("\e2565CC%p", (void *)Frame->eip); +#elif defined(__aarch64__) +#endif EHPrint("\e7925CC-"); +#if defined(__amd64__) EHPrint("\eAA25CC%s", KernelSymbolTable->GetSymbolFromAddress(Frame->rip)); +#elif defined(__i386__) + EHPrint("\eAA25CC%s", KernelSymbolTable->GetSymbolFromAddress(Frame->eip)); +#elif defined(__aarch64__) +#endif EHPrint("\e7981FC <- Exception"); EHPrint("\eFF0000\n< No stack trace available. >\n"); } else { +#if defined(__amd64__) EHPrint("\e2565CC%p", (void *)Frame->rip); EHPrint("\e7925CC-"); if (Frame->rip >= 0xFFFFFFFF80000000 && Frame->rip <= (uint64_t)&_kernel_end) EHPrint("\eAA25CC%s", KernelSymbolTable->GetSymbolFromAddress(Frame->rip)); else EHPrint("Outside Kernel"); +#elif defined(__i386__) + EHPrint("\e2565CC%p", (void *)Frame->eip); + EHPrint("\e7925CC-"); + if (Frame->eip >= 0xC0000000 && Frame->eip <= (uint64_t)&_kernel_end) + EHPrint("\eAA25CC%s", KernelSymbolTable->GetSymbolFromAddress(Frame->eip)); + else + EHPrint("Outside Kernel"); +#elif defined(__aarch64__) +#endif EHPrint("\e7981FC <- Exception"); for (int frame = 0; frame < Count; ++frame) { @@ -51,7 +77,12 @@ namespace CrashHandler break; EHPrint("\n\e2565CC%p", (void *)frames->rip); EHPrint("\e7925CC-"); +#if defined(__amd64__) if (frames->rip >= 0xFFFFFFFF80000000 && frames->rip <= (uint64_t)&_kernel_end) +#elif defined(__i386__) + if (frames->rip >= 0xC0000000 && frames->rip <= (uint64_t)&_kernel_end) +#elif defined(__aarch64__) +#endif EHPrint("\e25CCC9%s", KernelSymbolTable->GetSymbolFromAddress(frames->rip)); else EHPrint("\eFF4CA9Outside Kernel"); diff --git a/Core/Crash/Screens/Details.cpp b/Core/Crash/Screens/Details.cpp index 90f110b..3544693 100644 --- a/Core/Crash/Screens/Details.cpp +++ b/Core/Crash/Screens/Details.cpp @@ -31,11 +31,18 @@ namespace CrashHandler EHPrint("\e7981FCFS=%#llx GS=%#llx SS=%#llx CS=%#llx DS=%#llx\n", CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE), CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE), data.Frame->ss, data.Frame->cs, data.Frame->ds); +#if defined(__amd64__) EHPrint("R8=%#llx R9=%#llx R10=%#llx R11=%#llx\n", data.Frame->r8, data.Frame->r9, data.Frame->r10, data.Frame->r11); EHPrint("R12=%#llx R13=%#llx R14=%#llx R15=%#llx\n", data.Frame->r12, data.Frame->r13, data.Frame->r14, data.Frame->r15); EHPrint("RAX=%#llx RBX=%#llx RCX=%#llx RDX=%#llx\n", data.Frame->rax, data.Frame->rbx, data.Frame->rcx, data.Frame->rdx); EHPrint("RSI=%#llx RDI=%#llx RBP=%#llx RSP=%#llx\n", data.Frame->rsi, data.Frame->rdi, data.Frame->rbp, data.Frame->rsp); EHPrint("RIP=%#llx RFL=%#llx INT=%#llx ERR=%#llx EFER=%#llx\n", data.Frame->rip, data.Frame->rflags.raw, data.Frame->InterruptNumber, data.Frame->ErrorCode, data.efer.raw); +#elif defined(__i386__) + EHPrint("EAX=%#llx EBX=%#llx ECX=%#llx EDX=%#llx\n", data.Frame->eax, data.Frame->ebx, data.Frame->ecx, data.Frame->edx); + EHPrint("ESI=%#llx EDI=%#llx EBP=%#llx ESP=%#llx\n", data.Frame->esi, data.Frame->edi, data.Frame->ebp, data.Frame->esp); + EHPrint("EIP=%#llx EFL=%#llx INT=%#llx ERR=%#llx EFER=%#llx\n", data.Frame->eip, data.Frame->eflags.raw, data.Frame->InterruptNumber, data.Frame->ErrorCode, data.efer.raw); +#elif defined(__aarch64__) +#endif EHPrint("CR0=%#llx CR2=%#llx CR3=%#llx CR4=%#llx CR8=%#llx\n", data.cr0.raw, data.cr2.raw, data.cr3.raw, data.cr4.raw, data.cr8.raw); EHPrint("DR0=%#llx DR1=%#llx DR2=%#llx DR3=%#llx DR6=%#llx DR7=%#llx\n", data.dr0, data.dr1, data.dr2, data.dr3, data.dr6, data.dr7.raw); @@ -57,10 +64,16 @@ namespace CrashHandler data.cr4.PCE ? "True " : "False", data.cr4.UMIP ? "True " : "False", data.cr4.OSFXSR ? "True " : "False", data.cr4.OSXMMEXCPT ? "True " : "False", data.cr4.LA57 ? "True " : "False", data.cr4.VMXE ? "True " : "False", data.cr4.SMXE ? "True " : "False", data.cr4.PCIDE ? "True " : "False", data.cr4.OSXSAVE ? "True " : "False", data.cr4.SMEP ? "True " : "False", data.cr4.SMAP ? "True " : "False", data.cr4.PKE ? "True " : "False", +#if defined(__amd64__) data.cr4.Reserved0, data.cr4.Reserved1, data.cr4.Reserved2); +#elif defined(__i386__) + data.cr4.Reserved0, data.cr4.Reserved1, 0); +#elif defined(__aarch64__) +#endif EHPrint("\e79FCF5CR8: TPL:%d\n", data.cr8.TPL); +#if defined(__amd64__) EHPrint("\eFCFC02RFL: CF:%s PF:%s AF:%s ZF:%s\n SF:%s TF:%s IF:%s DF:%s\n OF:%s IOPL:%s NT:%s RF:%s\n VM:%s AC:%s VIF:%s VIP:%s\n ID:%s AlwaysOne:%d\n R0:%#x R1:%#x R2:%#x R3:%#x\n", data.Frame->rflags.CF ? "True " : "False", data.Frame->rflags.PF ? "True " : "False", data.Frame->rflags.AF ? "True " : "False", data.Frame->rflags.ZF ? "True " : "False", data.Frame->rflags.SF ? "True " : "False", data.Frame->rflags.TF ? "True " : "False", data.Frame->rflags.IF ? "True " : "False", data.Frame->rflags.DF ? "True " : "False", @@ -68,6 +81,16 @@ namespace CrashHandler data.Frame->rflags.VM ? "True " : "False", data.Frame->rflags.AC ? "True " : "False", data.Frame->rflags.VIF ? "True " : "False", data.Frame->rflags.VIP ? "True " : "False", data.Frame->rflags.ID ? "True " : "False", data.Frame->rflags.AlwaysOne, data.Frame->rflags.Reserved0, data.Frame->rflags.Reserved1, data.Frame->rflags.Reserved2, data.Frame->rflags.Reserved3); +#elif defined(__i386__) + EHPrint("\eFCFC02EFL: CF:%s PF:%s AF:%s ZF:%s\n SF:%s TF:%s IF:%s DF:%s\n OF:%s IOPL:%s NT:%s RF:%s\n VM:%s AC:%s VIF:%s VIP:%s\n ID:%s AlwaysOne:%d\n R0:%#x R1:%#x R2:%#x\n", + data.Frame->eflags.CF ? "True " : "False", data.Frame->eflags.PF ? "True " : "False", data.Frame->eflags.AF ? "True " : "False", data.Frame->eflags.ZF ? "True " : "False", + data.Frame->eflags.SF ? "True " : "False", data.Frame->eflags.TF ? "True " : "False", data.Frame->eflags.IF ? "True " : "False", data.Frame->eflags.DF ? "True " : "False", + data.Frame->eflags.OF ? "True " : "False", data.Frame->eflags.IOPL ? "True " : "False", data.Frame->eflags.NT ? "True " : "False", data.Frame->eflags.RF ? "True " : "False", + data.Frame->eflags.VM ? "True " : "False", data.Frame->eflags.AC ? "True " : "False", data.Frame->eflags.VIF ? "True " : "False", data.Frame->eflags.VIP ? "True " : "False", + data.Frame->eflags.ID ? "True " : "False", data.Frame->eflags.AlwaysOne, + data.Frame->eflags.Reserved0, data.Frame->eflags.Reserved1, data.Frame->eflags.Reserved2); +#elif defined(__aarch64__) +#endif EHPrint("\eA0F0F0DR7: LDR0:%s GDR0:%s LDR1:%s GDR1:%s\n LDR2:%s GDR2:%s LDR3:%s GDR3:%s\n CDR0:%s SDR0:%s CDR1:%s SDR1:%s\n CDR2:%s SDR2:%s CDR3:%s SDR3:%s\n R:%#x\n", data.dr7.LocalDR0 ? "True " : "False", data.dr7.GlobalDR0 ? "True " : "False", data.dr7.LocalDR1 ? "True " : "False", data.dr7.GlobalDR1 ? "True " : "False", diff --git a/Core/Crash/Screens/Main.cpp b/Core/Crash/Screens/Main.cpp index 8363cd9..f095806 100644 --- a/Core/Crash/Screens/Main.cpp +++ b/Core/Crash/Screens/Main.cpp @@ -269,7 +269,12 @@ namespace CrashHandler EHPrint("The processor attempted to access a page that is not present.\n"); CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode}; +#if defined(__amd64__) EHPrint("At \e8888FF%#lx \eFAFAFAby \e8888FF%#lx\eFAFAFA\n", CPU::x64::readcr2().PFLA, Frame->rip); +#elif defined(__i386__) + EHPrint("At \e8888FF%#lx \eFAFAFAby \e8888FF%#lx\eFAFAFA\n", CPU::x64::readcr2().PFLA, Frame->eip); +#elif defined(__aarch64__) +#endif EHPrint("Page: %s\eFAFAFA\n", params.P ? "\e058C19Present" : "\eE85230Not Present"); EHPrint("Write Operation: \e8888FF%s\eFAFAFA\n", params.W ? "Read-Only" : "Read-Write"); EHPrint("Processor Mode: \e8888FF%s\eFAFAFA\n", params.U ? "User-Mode" : "Kernel-Mode"); @@ -330,6 +335,11 @@ namespace CrashHandler } } +#if defined(__amd64__) EHPrint("The exception happened at \e8888FF%#lx\eFAFAFA\n", Frame->rip); +#elif defined(__i386__) + EHPrint("The exception happened at \e8888FF%#lx\eFAFAFA\n", Frame->eip); +#elif defined(__aarch64__) +#endif } } diff --git a/Core/Crash/Screens/Tasks.cpp b/Core/Crash/Screens/Tasks.cpp index 326b752..14fcb27 100644 --- a/Core/Crash/Screens/Tasks.cpp +++ b/Core/Crash/Screens/Tasks.cpp @@ -44,7 +44,12 @@ namespace CrashHandler if (TaskManager) { if (data.Thread) +#if defined(__amd64__) EHPrint("\eFAFAFACrash occured in thread \eAA0F0F%s\eFAFAFA(%ld) at \e00AAAA%#lx\n", data.Thread->Name, data.Thread->ID, data.Frame->rip); +#elif defined(__i386__) + EHPrint("\eFAFAFACrash occured in thread \eAA0F0F%s\eFAFAFA(%ld) at \e00AAAA%#lx\n", data.Thread->Name, data.Thread->ID, data.Frame->eip); +#elif defined(__aarch64__) +#endif EHPrint("\eFAFAFAProcess list (%ld):\n", Plist.size()); foreach (auto Process in Plist) @@ -56,7 +61,7 @@ namespace CrashHandler foreach (auto Thread in Process->Threads) EHPrint("\e%s -> \eFAFAFA%s\eCCCCCC(%ld) \e00AAAA%s\eFAFAFA Stack:\e00AAAA%#lx\n", StatusColor[Thread->Status], Thread->Name, Thread->ID, StatusString[Thread->Status], - Thread->Stack); + Thread->Stack); } } else diff --git a/Core/Crash/UserHandler.cpp b/Core/Crash/UserHandler.cpp index 06bc748..b1ecfbc 100644 --- a/Core/Crash/UserHandler.cpp +++ b/Core/Crash/UserHandler.cpp @@ -45,11 +45,18 @@ __no_stack_protector void UserModeExceptionHandler(CHArchTrapFrame *Frame) error("FS=%#llx GS=%#llx SS=%#llx CS=%#llx DS=%#llx", CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE), CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE), Frame->ss, Frame->cs, Frame->ds); + #if defined(__amd64__) error("R8=%#llx R9=%#llx R10=%#llx R11=%#llx", Frame->r8, Frame->r9, Frame->r10, Frame->r11); error("R12=%#llx R13=%#llx R14=%#llx R15=%#llx", Frame->r12, Frame->r13, Frame->r14, Frame->r15); error("RAX=%#llx RBX=%#llx RCX=%#llx RDX=%#llx", Frame->rax, Frame->rbx, Frame->rcx, Frame->rdx); error("RSI=%#llx RDI=%#llx RBP=%#llx RSP=%#llx", Frame->rsi, Frame->rdi, Frame->rbp, Frame->rsp); error("RIP=%#llx RFL=%#llx INT=%#llx ERR=%#llx EFER=%#llx", Frame->rip, Frame->rflags.raw, Frame->InterruptNumber, Frame->ErrorCode, efer.raw); +#elif defined(__i386__) + error("EAX=%#llx EBX=%#llx ECX=%#llx EDX=%#llx", Frame->eax, Frame->ebx, Frame->ecx, Frame->edx); + error("ESI=%#llx EDI=%#llx EBP=%#llx ESP=%#llx", Frame->esi, Frame->edi, Frame->ebp, Frame->esp); + error("EIP=%#llx EFL=%#llx INT=%#llx ERR=%#llx EFER=%#llx", Frame->eip, Frame->eflags.raw, Frame->InterruptNumber, Frame->ErrorCode, efer.raw); +#elif defined(__aarch64__) +#endif error("CR0=%#llx CR2=%#llx CR3=%#llx CR4=%#llx CR8=%#llx", cr0.raw, cr2.raw, cr3.raw, cr4.raw, cr8.raw); error("CR0: PE:%s MP:%s EM:%s TS:%s ET:%s NE:%s WP:%s AM:%s NW:%s CD:%s PG:%s R0:%#x R1:%#x R2:%#x", @@ -74,6 +81,7 @@ __no_stack_protector void UserModeExceptionHandler(CHArchTrapFrame *Frame) error("CR8: TPL:%d", cr8.TPL); +#if defined(__amd64__) error("RFL: CF:%s PF:%s AF:%s ZF:%s SF:%s TF:%s IF:%s DF:%s OF:%s IOPL:%s NT:%s RF:%s VM:%s AC:%s VIF:%s VIP:%s ID:%s AlwaysOne:%d R0:%#x R1:%#x R2:%#x R3:%#x", Frame->rflags.CF ? "True " : "False", Frame->rflags.PF ? "True " : "False", Frame->rflags.AF ? "True " : "False", Frame->rflags.ZF ? "True " : "False", Frame->rflags.SF ? "True " : "False", Frame->rflags.TF ? "True " : "False", Frame->rflags.IF ? "True " : "False", Frame->rflags.DF ? "True " : "False", @@ -81,6 +89,16 @@ __no_stack_protector void UserModeExceptionHandler(CHArchTrapFrame *Frame) Frame->rflags.VM ? "True " : "False", Frame->rflags.AC ? "True " : "False", Frame->rflags.VIF ? "True " : "False", Frame->rflags.VIP ? "True " : "False", Frame->rflags.ID ? "True " : "False", Frame->rflags.AlwaysOne, Frame->rflags.Reserved0, Frame->rflags.Reserved1, Frame->rflags.Reserved2, Frame->rflags.Reserved3); +#elif defined(__i386__) + error("EFL: CF:%s PF:%s AF:%s ZF:%s SF:%s TF:%s IF:%s DF:%s OF:%s IOPL:%s NT:%s RF:%s VM:%s AC:%s VIF:%s VIP:%s ID:%s AlwaysOne:%d R0:%#x R1:%#x R2:%#x", + Frame->eflags.CF ? "True " : "False", Frame->eflags.PF ? "True " : "False", Frame->eflags.AF ? "True " : "False", Frame->eflags.ZF ? "True " : "False", + Frame->eflags.SF ? "True " : "False", Frame->eflags.TF ? "True " : "False", Frame->eflags.IF ? "True " : "False", Frame->eflags.DF ? "True " : "False", + Frame->eflags.OF ? "True " : "False", Frame->eflags.IOPL ? "True " : "False", Frame->eflags.NT ? "True " : "False", Frame->eflags.RF ? "True " : "False", + Frame->eflags.VM ? "True " : "False", Frame->eflags.AC ? "True " : "False", Frame->eflags.VIF ? "True " : "False", Frame->eflags.VIP ? "True " : "False", + Frame->eflags.ID ? "True " : "False", Frame->eflags.AlwaysOne, + Frame->eflags.Reserved0, Frame->eflags.Reserved1, Frame->eflags.Reserved2); +#elif defined(__aarch64__) +#endif error("EFER: SCE:%s LME:%s LMA:%s NXE:%s SVME:%s LMSLE:%s FFXSR:%s TCE:%s R0:%#x R1:%#x R2:%#x", efer.SCE ? "True " : "False", efer.LME ? "True " : "False", efer.LMA ? "True " : "False", efer.NXE ? "True " : "False", @@ -149,7 +167,12 @@ __no_stack_protector void UserModeExceptionHandler(CHArchTrapFrame *Frame) case CPU::x64::PageFault: { CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode}; +#if defined(__amd64__) error("An exception occurred at %#lx by %#lx", CPU::x64::readcr2().PFLA, Frame->rip); +#elif defined(__i386__) + error("An exception occurred at %#lx by %#lx", CPU::x64::readcr2().PFLA, Frame->eip); +#elif defined(__aarch64__) +#endif error("Page: %s", params.P ? "Present" : "Not Present"); error("Write Operation: %s", params.W ? "Read-Only" : "Read-Write"); error("Processor Mode: %s", params.U ? "User-Mode" : "Kernel-Mode"); diff --git a/Core/Crash/chfcts.hpp b/Core/Crash/chfcts.hpp index dfc3b53..78670de 100644 --- a/Core/Crash/chfcts.hpp +++ b/Core/Crash/chfcts.hpp @@ -29,7 +29,25 @@ struct CRData }; #elif defined(__i386__) -typedef struct CPU::x86::TrapFrame CHArchTrapFrame; +typedef struct CPU::x32::TrapFrame CHArchTrapFrame; + +struct CRData +{ + CHArchTrapFrame *Frame; + + CPU::x32::CR0 cr0; + CPU::x32::CR2 cr2; + CPU::x32::CR3 cr3; + CPU::x32::CR4 cr4; + CPU::x32::CR8 cr8; + CPU::x32::EFER efer; + uint64_t dr0, dr1, dr2, dr3, dr6; + CPU::x32::DR7 dr7; + + long ID; + Tasking::PCB *Process; + Tasking::TCB *Thread; +}; #elif defined(__aarch64__) typedef struct CPU::aarch64::TrapFrame CHArchTrapFrame; #endif diff --git a/Core/Memory/VirtualMemoryManager.cpp b/Core/Memory/VirtualMemoryManager.cpp index 8376ee5..7350504 100644 --- a/Core/Memory/VirtualMemoryManager.cpp +++ b/Core/Memory/VirtualMemoryManager.cpp @@ -101,7 +101,7 @@ namespace Memory #if defined(__amd64__) CPU::x64::invlpg(VirtualAddress); #elif defined(__i386__) - CPU::x86::invlpg(VirtualAddress); + CPU::x32::invlpg(VirtualAddress); #elif defined(__aarch64__) asmv("dsb sy"); asmv("tlbi vae1is, %0" diff --git a/Execute/Spawn.cpp b/Execute/Spawn.cpp index 2be6c5c..f733120 100644 --- a/Execute/Spawn.cpp +++ b/Execute/Spawn.cpp @@ -29,6 +29,8 @@ namespace Execute { case BinaryType::BinTypeFex: { +#if defined(__amd64__) + Fex *FexHdr = (Fex *)ExFile->Node->Address; if (FexHdr->Type == FexFormatType::FexFormatType_Executable) { @@ -54,6 +56,13 @@ namespace Execute ret.Process = Process; ret.Thread = Thread; ret.Status = ExStatus::OK; +#elif defined(__i386__) + if (1) + { +#elif defined(__aarch64__) + if (1) + { +#endif goto Exit; } ret.Status = ExStatus::InvalidFileHeader; @@ -61,6 +70,8 @@ namespace Execute } case BinaryType::BinTypeELF: { +#if defined(__amd64__) + const char *BaseName; cwk_path_get_basename(Path, &BaseName, nullptr); PCB *Process = TaskManager->CreateProcess(TaskManager->GetCurrentProcess(), BaseName, TaskTrustLevel::User); @@ -191,8 +202,10 @@ namespace Execute { fixme("Unknown"); } - ret.Status = ExStatus::InvalidFileHeader; +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif goto Exit; } default: diff --git a/Kernel.cpp b/Kernel.cpp index 11e4045..ef3bae0 100644 --- a/Kernel.cpp +++ b/Kernel.cpp @@ -79,7 +79,12 @@ EXTERNC void Entry(BootInfo *Info) } KPrint("Enabling Interrupts on Bootstrap Processor"); Interrupts::Enable(0); + #if defined(__amd64__) PowerManager->InitDSDT(); +#elif defined(__i386__) + // FIXME: Add ACPI support for i386 +#elif defined(__aarch64__) +#endif KPrint("Initializing Timers"); #if defined(__amd64__) TimeManager = new Time::time(PowerManager->GetACPI()); diff --git a/Library/cargs.c b/Library/cargs.c index 57abae9..ef43ed8 100644 --- a/Library/cargs.c +++ b/Library/cargs.c @@ -404,7 +404,7 @@ static int cag_option_find_next(cag_option_context *context) // Grab a pointer to the string and verify that it is not the end. If it is // the end, we have to return false to indicate that we finished. c = context->argv[next_option_index]; - if (context->forced_end || c == NULL || (uint64_t)c == (uint64_t)0xffffffffffffffff /* TODO: workaround */) + if (context->forced_end || c == NULL || (uint64_t)c == (uint64_t)0xfffffffffffff000 /* TODO: workaround */) { return -1; } diff --git a/Makefile b/Makefile index b688952..8348dd0 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ INCLUDE_DIR = ./include LDFLAGS := -Wl,-Map kernel.map -shared -nostdlib -nodefaultlibs -nolibc # Disable all warnings by adding "-w" in WARNCFLAG and if you want to treat the warnings as errors, add "-Werror" -WARNCFLAG = -Wall -Wextra +WARNCFLAG = -w #-Wall -Wextra # https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html CFLAGS := \ diff --git a/SystemCalls/Linux.cpp b/SystemCalls/Linux.cpp index 094ed20..72fbf83 100644 --- a/SystemCalls/Linux.cpp +++ b/SystemCalls/Linux.cpp @@ -2391,6 +2391,7 @@ static void *LinuxSyscallsTable[] = { uint64_t HandleLinuxSyscalls(SyscallsFrame *Frame) { +#if defined(__amd64__) if (Frame->rax > sizeof(LinuxSyscallsTable)) { fixme("Syscall %lld not implemented", Frame->rax); @@ -2406,4 +2407,7 @@ uint64_t HandleLinuxSyscalls(SyscallsFrame *Frame) uint64_t ret = call(Frame->rdi, Frame->rsi, Frame->rdx, Frame->r10, Frame->r8, Frame->r9); Frame->rax = ret; return ret; +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif } diff --git a/SystemCalls/Native.cpp b/SystemCalls/Native.cpp index 22f1022..b971727 100644 --- a/SystemCalls/Native.cpp +++ b/SystemCalls/Native.cpp @@ -26,6 +26,7 @@ static void *NativeSyscallsTable[] = { uint64_t HandleNativeSyscalls(SyscallsFrame *Frame) { +#if defined(__amd64__) debug("rax: %#llx, rbx: %#llx, rcx: %#llx, rdx: %#llx, rsi: %#llx, rdi: %#llx, rbp: %#llx, r8: %#llx, r9: %#llx, r10: %#llx, r11: %#llx, r12: %#llx, r13: %#llx, r14: %#llx, r15: %#llx", Frame->rax, Frame->rbx, Frame->rcx, Frame->rdx, Frame->rsi, Frame->rdi, Frame->rbp, Frame->r8, Frame->r9, Frame->r10, Frame->r11, Frame->r12, Frame->r13, Frame->r14, Frame->r15); if (Frame->rax > sizeof(NativeSyscallsTable)) { @@ -43,4 +44,7 @@ uint64_t HandleNativeSyscalls(SyscallsFrame *Frame) uint64_t ret = call((uint64_t)Frame, Frame->rdi, Frame->rsi, Frame->rdx, Frame->r10, Frame->r8, Frame->r9); Frame->rax = ret; return ret; +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif } diff --git a/SystemCalls/Syscalls.cpp b/SystemCalls/Syscalls.cpp index 43a7f55..bec512d 100644 --- a/SystemCalls/Syscalls.cpp +++ b/SystemCalls/Syscalls.cpp @@ -26,7 +26,7 @@ extern "C" uint64_t SystemCallsHandler(SyscallsFrame *Frame) } } #elif defined(__i386__) - fixme("System call %lld", regs->eax); + fixme("System call %lld", Frame->eax); #elif defined(__aarch64__) fixme("System call"); #endif diff --git a/Tasking/Task.cpp b/Tasking/Task.cpp index c8988da..37089d5 100644 --- a/Tasking/Task.cpp +++ b/Tasking/Task.cpp @@ -11,6 +11,7 @@ #include "../Architecture/amd64/cpu/apic.hpp" #include "../Architecture/amd64/cpu/gdt.hpp" #elif defined(__i386__) +#include "../Architecture/i686/cpu/apic.hpp" #elif defined(__aarch64__) #endif @@ -972,7 +973,11 @@ namespace Tasking break; } debug("Tasking Started"); +#if defined(__amd64__) ((APIC::Timer *)Interrupts::apicTimer[0])->OneShot(CPU::x64::IRQ16, 100); +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif for (int i = 1; i < SMP::CPUCores; i++) { diff --git a/include/abi.h b/include/abi.h index 8821601..3228455 100644 --- a/include/abi.h +++ b/include/abi.h @@ -65,6 +65,7 @@ typedef struct #if defined(__amd64__) Elf64_auxv_t archaux; #elif defined(__i386__) + Elf32_auxv_t archaux; #elif defined(__aarch64__) #endif } AuxiliaryVector; diff --git a/include/cpu.hpp b/include/cpu.hpp index c4bd090..2d27fe6 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -260,6 +260,282 @@ namespace CPU namespace x32 { + typedef union + { + struct + { + /** @brief Carry Flag */ + uint32_t CF : 1; + /** @brief Reserved */ + uint32_t AlwaysOne : 1; + /** @brief Parity Flag */ + uint32_t PF : 1; + /** @brief Reserved */ + uint32_t Reserved0 : 1; + /** @brief Auxiliary Carry Flag */ + uint32_t AF : 1; + /** @brief Reserved */ + uint32_t Reserved1 : 1; + /** @brief Zero Flag */ + uint32_t ZF : 1; + /** @brief Sign Flag */ + uint32_t SF : 1; + /** @brief Trap Flag */ + uint32_t TF : 1; + /** @brief Interrupt Enable Flag */ + uint32_t IF : 1; + /** @brief Direction Flag */ + uint32_t DF : 1; + /** @brief Overflow Flag */ + uint32_t OF : 1; + /** @brief I/O Privilege Level */ + uint32_t IOPL : 2; + /** @brief Nested Task */ + uint32_t NT : 1; + /** @brief Reserved */ + uint32_t Reserved2 : 1; + /** @brief Resume Flag */ + uint32_t RF : 1; + /** @brief Virtual 8086 Mode */ + uint32_t VM : 1; + /** @brief Alignment Check */ + uint32_t AC : 1; + /** @brief Virtual Interrupt Flag */ + uint32_t VIF : 1; + /** @brief Virtual Interrupt Pending */ + uint32_t VIP : 1; + /** @brief ID Flag */ + uint32_t ID : 1; + }; + uint32_t raw; + } EFLAGS; + + typedef struct TrapFrame + { + // uint32_t gs; // General-purpose Segment + // uint32_t fs; // General-purpose Segment + // uint32_t es; // Extra Segment (used for string operations) + uint32_t ds; // Data Segment + + uint32_t ebp; // Base Pointer (meant for stack frames) + uint32_t edi; // Destination index for string operations + uint32_t esi; // Source index for string operations + uint32_t edx; // Data (commonly extends the A register) + uint32_t ecx; // Counter + uint32_t ebx; // Base + uint32_t eax; // Accumulator + + uint32_t InterruptNumber; // Interrupt Number + uint32_t ErrorCode; // Error code + uint32_t eip; // Instruction Pointer + uint32_t cs; // Code Segment + EFLAGS eflags; // Register Flags + uint32_t esp; // Stack Pointer + uint32_t ss; // Stack Segment + } TrapFrame; + + typedef union CR0 + { + struct + { + /** @brief Protection Enable */ + uint32_t PE : 1; + /** @brief Monitor Coprocessor */ + uint32_t MP : 1; + /** @brief Emulation */ + uint32_t EM : 1; + /** @brief Task Switched */ + uint32_t TS : 1; + /** @brief Extension Type */ + uint32_t ET : 1; + /** @brief Numeric Error */ + uint32_t NE : 1; + /** @brief Reserved */ + uint32_t Reserved0 : 10; + /** @brief Write Protect */ + uint32_t WP : 1; + /** @brief Reserved */ + uint32_t Reserved1 : 1; + /** @brief Alignment Mask */ + uint32_t AM : 1; + /** @brief Reserved */ + uint32_t Reserved2 : 10; + /** @brief Not Write-through */ + uint32_t NW : 1; + /** @brief Cache Disable */ + uint32_t CD : 1; + /** @brief Paging */ + uint32_t PG : 1; + }; + uint32_t raw; + } CR0; + + typedef union CR2 + { + struct + { + /** @brief Page Fault Linear Address */ + uint32_t PFLA; + }; + uint32_t raw; + } CR2; + + typedef union CR3 + { + struct + { + /** @brief Not used if bit 17 of CR4 is 1 */ + uint32_t PWT : 1; + /** @brief Not used if bit 17 of CR4 is 1 */ + uint32_t PCD : 1; + /** @brief Base of PML4T/PML5T */ + uint32_t PDBR; + }; + uint32_t raw; + } CR3; + + typedef union CR4 + { + struct + { + /** @brief Virtual-8086 Mode Extensions */ + uint32_t VME : 1; + /** @brief Protected-Mode Virtual Interrupts */ + uint32_t PVI : 1; + /** @brief Time Stamp Disable */ + uint32_t TSD : 1; + /** @brief Debugging Extensions */ + uint32_t DE : 1; + /** @brief Page Size Extensions */ + uint32_t PSE : 1; + /** @brief Physical Address Extension */ + uint32_t PAE : 1; + /** @brief Machine Check Enable */ + uint32_t MCE : 1; + /** @brief Page Global Enable */ + uint32_t PGE : 1; + /** @brief Performance Monitoring Counter */ + uint32_t PCE : 1; + /** @brief Operating System Support */ + uint32_t OSFXSR : 1; + /** @brief Operating System Support */ + uint32_t OSXMMEXCPT : 1; + /** @brief User-Mode Instruction Prevention */ + uint32_t UMIP : 1; + /** @brief Linear Address 57bit */ + uint32_t LA57 : 1; + /** @brief VMX Enable */ + uint32_t VMXE : 1; + /** @brief SMX Enable */ + uint32_t SMXE : 1; + /** @brief Reserved */ + uint32_t Reserved0 : 1; + /** @brief FSGSBASE Enable */ + uint32_t FSGSBASE : 1; + /** @brief PCID Enable */ + uint32_t PCIDE : 1; + /** @brief XSAVE and Processor Extended States Enable */ + uint32_t OSXSAVE : 1; + /** @brief Reserved */ + uint32_t Reserved1 : 1; + /** @brief SMEP Enable */ + uint32_t SMEP : 1; + /** @brief SMAP Enable */ + uint32_t SMAP : 1; + /** @brief Protection-Key Enable */ + uint32_t PKE : 1; + /** @brief Control-flow Enforcement Technology*/ + uint32_t CET : 1; + /* @brief Enable Protection Keys for Supervisor Mode Pages */ + uint32_t PKS : 1; + }; + uint32_t raw; + } CR4; + + typedef union CR8 + { + struct + { + /** @brief Task Priority Level */ + uint32_t TPL : 1; + }; + uint32_t raw; + } CR8; + + /* TODO: Does EFER exists in x32? */ + typedef union EFER + { + struct + { + /** @brief Enable syscall & sysret instructions in 64-bit mode. */ + uint32_t SCE : 1; + /** @brief Reserved */ + uint32_t Reserved0 : 7; + /** @brief Enable long mode. */ + uint32_t LME : 1; + /** @brief Reserved */ + uint32_t Reserved1 : 1; + /** @brief Indicates long. */ + uint32_t LMA : 1; + /** @brief Enable No-Execute Bit */ + uint32_t NXE : 1; + /** @brief Enable Secure Virtual Machine */ + uint32_t SVME : 1; + /** @brief Enable Long Mode Segment Limit */ + uint32_t LMSLE : 1; + /** @brief Enable Fast FXSAVE/FXRSTOR */ + uint32_t FFXSR : 1; + /** @brief Enable Translation Cache Extension */ + uint32_t TCE : 1; + /** @brief Reserved */ + uint32_t Reserved2 : 32; + }; + uint32_t raw; + } __attribute__((packed)) EFER; + + // ! TODO: UNTESTED! + typedef union DR7 + { + struct + { + /** @brief Local DR0 Breakpoint (0) */ + uint32_t LocalDR0 : 1; + /** @brief Global DR0 Breakpoint (1) */ + uint32_t GlobalDR0 : 1; + /** @brief Local DR1 Breakpoint (2) */ + uint32_t LocalDR1 : 1; + /** @brief Global DR1 Breakpoint (3) */ + uint32_t GlobalDR1 : 1; + /** @brief Local DR2 Breakpoint (4) */ + uint32_t LocalDR2 : 1; + /** @brief Global DR2 Breakpoint (5) */ + uint32_t GlobalDR2 : 1; + /** @brief Local DR3 Breakpoint (6) */ + uint32_t LocalDR3 : 1; + /** @brief Global DR3 Breakpoint (7) */ + uint32_t GlobalDR3 : 1; + /** @brief Reserved [7 - (16-17)] */ + uint32_t Reserved : 9; + /** @brief Conditions for DR0 (16-17) */ + uint32_t ConditionsDR0 : 1; + /** @brief Size of DR0 Breakpoint (18-19) */ + uint32_t SizeDR0 : 1; + /** @brief Conditions for DR1 (20-21) */ + uint32_t ConditionsDR1 : 1; + /** @brief Size of DR1 Breakpoint (22-23) */ + uint32_t SizeDR1 : 1; + /** @brief Conditions for DR2 (24-25) */ + uint32_t ConditionsDR2 : 1; + /** @brief Size of DR2 Breakpoint (26-27) */ + uint32_t SizeDR2 : 1; + /** @brief Conditions for DR3 (28-29) */ + uint32_t ConditionsDR3 : 1; + /** @brief Size of DR3 Breakpoint (30-31) */ + uint32_t SizeDR3 : 1; + }; + uint32_t raw; + } DR7; + /** * @brief CPUID * @@ -275,6 +551,16 @@ namespace CPU asmv("cpuid" : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "a"(Function)); +#endif + } + + __no_stack_protector static inline void invlpg(void *Address) + { +#if defined(__i386__) + asmv("invlpg (%0)" + : + : "r"(Address) + : "memory"); #endif } } @@ -1167,7 +1453,7 @@ namespace CPU uint64_t AM : 1; /** @brief Reserved */ uint64_t Reserved2 : 10; - /** @brief Mot Write-through */ + /** @brief Not Write-through */ uint64_t NW : 1; /** @brief Cache Disable */ uint64_t CD : 1; @@ -1251,8 +1537,12 @@ namespace CPU uint64_t SMAP : 1; /** @brief Protection-Key Enable */ uint64_t PKE : 1; + /** @brief Control-flow Enforcement Technology*/ + uint32_t CET : 1; + /* @brief Enable Protection Keys for Supervisor Mode Pages */ + uint32_t PKS : 1; /** @brief Reserved */ - uint64_t Reserved2 : 9; + uint64_t Reserved2 : 7; // TODO: This could be wrong }; uint64_t raw; } CR4; diff --git a/include/interrupts.hpp b/include/interrupts.hpp index a71acff..35e7797 100644 --- a/include/interrupts.hpp +++ b/include/interrupts.hpp @@ -10,7 +10,8 @@ namespace Interrupts /* APIC::APIC */ extern void *apic[256]; // MAX_CPU /* APIC::Timer */ extern void *apicTimer[256]; // MAX_CPU #elif defined(__i386__) - extern void *apic[256]; // MAX_CPU + /* APIC::APIC */ extern void *apic[256]; // MAX_CPU + /* APIC::Timer */ extern void *apicTimer[256]; // MAX_CPU #elif defined(__aarch64__) #endif void Initialize(int Core);