diff --git a/Architecture/amd64/linker.ld b/Architecture/amd64/linker.ld index 1046b98..357c4cd 100644 --- a/Architecture/amd64/linker.ld +++ b/Architecture/amd64/linker.ld @@ -46,7 +46,6 @@ SECTIONS } . += CONSTANT(MAXPAGESIZE); - .bss : { *(COMMON) diff --git a/Architecture/i686/cpu/GlobalDescriptorTable.cpp b/Architecture/i686/cpu/GlobalDescriptorTable.cpp new file mode 100644 index 0000000..bb227da --- /dev/null +++ b/Architecture/i686/cpu/GlobalDescriptorTable.cpp @@ -0,0 +1,99 @@ +#include "gdt.hpp" + +#include +#include +#include +#include + +namespace GlobalDescriptorTable +{ + static GlobalDescriptorTableEntries GDTEntriesTemplate = { + // null + {.Length = 0x0, + .BaseLow = 0x0, + .BaseMiddle = 0x0, + .Access = {.Raw = 0x0}, + .Flags = {.Raw = 0x0}, + .BaseHigh = 0x0}, + + // kernel code + {.Length = 0x0, + .BaseLow = 0x0, + .BaseMiddle = 0x0, + .Access = {.A = 0, + .RW = 1, + .DC = 0, + .E = 1, + .S = 1, + .DPL = 0, + .P = 1}, + .Flags = {.Unknown = 0x0, .L = 1}, + .BaseHigh = 0x0}, + + // kernel data + {.Length = 0x0, + .BaseLow = 0x0, + .BaseMiddle = 0x0, + .Access = {.A = 0, + .RW = 1, + .DC = 0, + .E = 0, + .S = 1, + .DPL = 0, + .P = 1}, + .Flags = {.Raw = 0x0}, + .BaseHigh = 0x0}, + + // user data + {.Length = 0x0, + .BaseLow = 0x0, + .BaseMiddle = 0x0, + .Access = {.A = 0, + .RW = 1, + .DC = 0, + .E = 0, + .S = 1, + .DPL = 3, + .P = 1}, + .Flags = {.Raw = 0x0}, + .BaseHigh = 0x0}, + + // user code + {.Length = 0x0, + .BaseLow = 0x0, + .BaseMiddle = 0x0, + .Access = {.A = 0, + .RW = 1, + .DC = 0, + .E = 1, + .S = 1, + .DPL = 3, + .P = 1}, + .Flags = {.Unknown = 0x0, .L = 1}, + .BaseHigh = 0x0}, + + // tss + {}}; + + GlobalDescriptorTableEntries GDTEntries[MAX_CPU]; + GlobalDescriptorTableDescriptor gdt[MAX_CPU]; + + TaskStateSegment tss[MAX_CPU] = { + 0, + {0, 0, 0}, + 0, + {0, 0, 0, 0, 0, 0, 0}, + 0, + 0, + }; + + void *CPUStackPointer[MAX_CPU]; + + SafeFunction void Init(int Core) + { + } + + SafeFunction void SetKernelStack(void *Stack) + { + } +} diff --git a/Architecture/i686/cpu/gdt.hpp b/Architecture/i686/cpu/gdt.hpp index 86ce86a..900c6b9 100644 --- a/Architecture/i686/cpu/gdt.hpp +++ b/Architecture/i686/cpu/gdt.hpp @@ -5,7 +5,141 @@ namespace GlobalDescriptorTable { + /** @brief The GDT Access Table + * @details For more information, see https://wiki.osdev.org/Global_Descriptor_Table + */ + union GlobalDescriptorTableAccess + { + struct + { + /** @brief Access bit. + * @note The CPU sets this bit to 1 when the segment is accessed. + */ + uint8_t A : 1; + + /** @brief Readable bit for code segments, writable bit for data segments. + * @details For code segments, this bit must be 1 for the segment to be readable. + * @details For data segments, this bit must be 1 for the segment to be writable. + */ + uint8_t RW : 1; + + /** @brief Direction bit for data segments, conforming bit for code segments. + * @details For data segments, this bit must be 1 for the segment to grow up (higher addresses). + * @details For code segments, this bit must be 1 for code in the segment to be able to be executed from an equal or lower privilege level. + */ + uint8_t DC : 1; + + /** @brief Executable bit. + * @details This bit must be 1 for code-segment descriptors. + * @details This bit must be 0 for data-segment and system descriptors. + */ + uint8_t E : 1; + + /** @brief Descriptor type. + * @details This bit must be 0 for system descriptors. + * @details This bit must be 1 for code or data segment descriptor. + */ + uint8_t S : 1; + + /** @brief Descriptor privilege level. + * @details This field determines the privilege level of the segment. + * @details 0 = kernel mode, 3 = user mode. + */ + uint8_t DPL : 2; + + /** @brief Present bit. + * @details This bit must be 1 for all valid descriptors. + */ + uint8_t P : 1; + } __attribute__((packed)); + uint8_t Raw; + }; + + union GlobalDescriptorTableFlags + { + // TODO: Add more flags. + struct + { + /** @brief Unknown. */ + uint8_t Unknown : 5; + + /** @brief Long mode. + * @details If the long mode bit is clear, the segment is in 32-bit protected mode. + * @details If the long mode bit is set, the segment is in 64-bit long mode. + */ + uint8_t L : 1; + } __attribute__((packed)); + uint8_t Raw; + }; + + typedef struct _TaskStateSegmentEntry + { + /* LOW */ + uint16_t Length; + uint16_t BaseLow; + uint8_t BaseMiddle; + GlobalDescriptorTableAccess Flags; + uint8_t Granularity; + uint8_t BaseHigh; + /* HIGH */ + uint32_t BaseUpper; + uint32_t Reserved; + } __attribute__((packed)) TaskStateSegmentEntry; + + typedef struct _TaskStateSegment + { + uint32_t Reserved0 __attribute__((aligned(16))); + 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 */ + uint16_t Length; + /** @brief Low Base */ + uint16_t BaseLow; + /** @brief Middle Base */ + uint8_t BaseMiddle; + /** @brief Access */ + GlobalDescriptorTableAccess Access; + /** @brief Flags */ + GlobalDescriptorTableFlags Flags; + /** @brief High Base */ + uint8_t BaseHigh; + } __attribute__((packed)) GlobalDescriptorTableEntry; + + typedef struct _GlobalDescriptorTableEntries + { + GlobalDescriptorTableEntry Null; + GlobalDescriptorTableEntry Code; + GlobalDescriptorTableEntry Data; + GlobalDescriptorTableEntry UserData; + GlobalDescriptorTableEntry UserCode; + TaskStateSegmentEntry TaskStateSegment; + } __attribute__((packed)) GlobalDescriptorTableEntries; + + typedef struct _GlobalDescriptorTableDescriptor + { + /** @brief GDT entries length */ + uint16_t Length; + /** @brief GDT entries address */ + GlobalDescriptorTableEntries *Entries; + } __attribute__((packed)) GlobalDescriptorTableDescriptor; + + extern void *CPUStackPointer[]; + extern TaskStateSegment tss[]; void Init(int Core); + void SetKernelStack(void *Stack); } +#define GDT_KERNEL_CODE offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, Code) +#define GDT_KERNEL_DATA offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, Data) +#define GDT_USER_CODE (offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, UserCode) | 3) +#define GDT_USER_DATA (offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, UserData) | 3) +#define GDT_TSS (offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, TaskStateSegment) | 3) + #endif // !__FENNIX_KERNEL_GDT_H__ diff --git a/Architecture/i686/linker.ld b/Architecture/i686/linker.ld index d604c42..1917158 100644 --- a/Architecture/i686/linker.ld +++ b/Architecture/i686/linker.ld @@ -27,6 +27,23 @@ SECTIONS } _kernel_rodata_end = .; + .init_array : + { + PROVIDE_HIDDEN(__init_array_start = .); + KEEP(*(.init_array .ctors)) + KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + PROVIDE_HIDDEN (__init_array_end = .); + } + + .fini_array : + { + PROVIDE_HIDDEN(__fini_array_start = .); + KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP(*(.fini_array .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + . += CONSTANT(MAXPAGESIZE); + .bss ALIGN (4096) : AT(ADDR(.bss) - 0xC0000000) { *(COMMON) diff --git a/Core/Crash/CrashDetails.cpp b/Core/Crash/CrashDetails.cpp index e3517b8..63e7a05 100644 --- a/Core/Crash/CrashDetails.cpp +++ b/Core/Crash/CrashDetails.cpp @@ -124,7 +124,13 @@ SafeFunction void PageFaultExceptionHandler(CHArchTrapFrame *Frame) uintptr_t CheckPageFaultAddress = 0; CheckPageFaultAddress = CPU::x64::readcr2().PFLA; if (CheckPageFaultAddress == 0) +#ifdef __amd64__ CheckPageFaultAddress = Frame->rip; +#elif defined(__i386__) + CheckPageFaultAddress = Frame->eip; +#elif defined(__aarch64__) + CheckPageFaultAddress = 0; +#endif Memory::Virtual vma = Memory::Virtual(((Memory::PageTable4 *)CPU::x64::readcr3().raw)); bool PageAvailable = vma.Check((void *)CheckPageFaultAddress); diff --git a/Core/Crash/CrashHandler.cpp b/Core/Crash/CrashHandler.cpp index 057442f..a512204 100644 --- a/Core/Crash/CrashHandler.cpp +++ b/Core/Crash/CrashHandler.cpp @@ -14,6 +14,7 @@ #if defined(__amd64__) #include "../../Architecture/amd64/cpu/gdt.hpp" #elif defined(__i386__) +#include "../../Architecture/i686/cpu/gdt.hpp" #elif defined(__aarch64__) #endif diff --git a/Core/Crash/SFrame.cpp b/Core/Crash/SFrame.cpp index da9d8c9..265929a 100644 --- a/Core/Crash/SFrame.cpp +++ b/Core/Crash/SFrame.cpp @@ -40,7 +40,12 @@ namespace CrashHandler #elif defined(__aarch64__) #endif { + #if defined(__amd64__) EHPrint("Invalid rbp pointer: %p\n", Frame->rbp); + #elif defined(__i386__) + EHPrint("Invalid ebp pointer: %p\n", Frame->ebp); + #elif defined(__aarch64__) +#endif return; } diff --git a/Core/Crash/Screens/StackFrame.cpp b/Core/Crash/Screens/StackFrame.cpp index c95528e..00477fe 100644 --- a/Core/Crash/Screens/StackFrame.cpp +++ b/Core/Crash/Screens/StackFrame.cpp @@ -61,9 +61,9 @@ namespace CrashHandler uintptr_t LastRIP = 0; for (int i = 0; i < 128; i++) { - if (data.Thread->RIPHistory[i] == 0) + if (data.Thread->IPHistory[i] == 0) break; - if (data.Thread->RIPHistory[i] == LastRIP) + if (data.Thread->IPHistory[i] == LastRIP) { SameItr++; if (SameItr > 3) @@ -71,11 +71,11 @@ namespace CrashHandler } else SameItr = 0; - LastRIP = data.Thread->RIPHistory[i]; + LastRIP = data.Thread->IPHistory[i]; if (!sh) - EHPrint("\n\e2565CC%p", data.Thread->RIPHistory[i]); + EHPrint("\n\e2565CC%p", data.Thread->IPHistory[i]); else - EHPrint("\n\e2565CC%p\e7925CC-\e25CCC9%s", data.Thread->RIPHistory[i], sh->GetSymbolFromAddress(data.Thread->RIPHistory[i])); + EHPrint("\n\e2565CC%p\e7925CC-\e25CCC9%s", data.Thread->IPHistory[i], sh->GetSymbolFromAddress(data.Thread->IPHistory[i])); } EHPrint("\n\e7925CCNote: \e2565CCSame RIPs are not shown more than 3 times.\n"); } diff --git a/Core/PeripheralComponentInterconnect.cpp b/Core/PeripheralComponentInterconnect.cpp index b0bf025..b699288 100644 --- a/Core/PeripheralComponentInterconnect.cpp +++ b/Core/PeripheralComponentInterconnect.cpp @@ -772,7 +772,7 @@ namespace PCI } #endif - void PCI::EnumerateFunction(uintptr_t DeviceAddress, uintptr_t Function) + void PCI::EnumerateFunction(uintptr_t DeviceAddress, uint64_t Function) { uintptr_t Offset = Function << 12; uintptr_t FunctionAddress = DeviceAddress + Offset; @@ -788,7 +788,7 @@ namespace PCI #endif } - void PCI::EnumerateDevice(uintptr_t BusAddress, uintptr_t Device) + void PCI::EnumerateDevice(uintptr_t BusAddress, uint64_t Device) { uintptr_t Offset = Device << 15; uintptr_t DeviceAddress = BusAddress + Offset; @@ -802,7 +802,7 @@ namespace PCI EnumerateFunction(DeviceAddress, Function); } - void PCI::EnumerateBus(uintptr_t BaseAddress, uintptr_t Bus) + void PCI::EnumerateBus(uintptr_t BaseAddress, uint64_t Bus) { uintptr_t Offset = Bus << 20; uintptr_t BusAddress = BaseAddress + Offset; diff --git a/Core/Timer.cpp b/Core/Timer.cpp index ff95c01..b74ab0a 100644 --- a/Core/Timer.cpp +++ b/Core/Timer.cpp @@ -12,7 +12,7 @@ namespace Time { - void time::Sleep(uintptr_t Milliseconds) + void time::Sleep(uint64_t Milliseconds) { #if defined(__amd64__) || defined(__i386__) uintptr_t Target = mminq(&((HPET *)hpet)->MainCounterValue) + (Milliseconds * 1000000000) / clk; diff --git a/SystemCalls/Linux.cpp b/SystemCalls/Linux.cpp index 607db0d..bf63a25 100644 --- a/SystemCalls/Linux.cpp +++ b/SystemCalls/Linux.cpp @@ -2391,7 +2391,7 @@ static void *LinuxSyscallsTable[] = { [335] = (void *)pkey_mprotect_, }; -uint64_t HandleLinuxSyscalls(SyscallsFrame *Frame) +uintptr_t HandleLinuxSyscalls(SyscallsFrame *Frame) { #if defined(__amd64__) if (Frame->rax > sizeof(LinuxSyscallsTable)) diff --git a/Tasking/Task.cpp b/Tasking/Task.cpp index 900a531..c0a79da 100644 --- a/Tasking/Task.cpp +++ b/Tasking/Task.cpp @@ -493,17 +493,17 @@ namespace Tasking // FIXME: Untested for (int i = 0; i < 128; i++) { - if (CurrentCPU->CurrentThread->RIPHistory[i] == 0) + if (CurrentCPU->CurrentThread->IPHistory[i] == 0) { - CurrentCPU->CurrentThread->RIPHistory[i] = Frame->rip; + CurrentCPU->CurrentThread->IPHistory[i] = Frame->rip; break; } if (i == 127) { for (int j = 0; j < 127; j++) - CurrentCPU->CurrentThread->RIPHistory[j] = CurrentCPU->CurrentThread->RIPHistory[j + 1]; - CurrentCPU->CurrentThread->RIPHistory[127] = Frame->rip; + CurrentCPU->CurrentThread->IPHistory[j] = CurrentCPU->CurrentThread->IPHistory[j + 1]; + CurrentCPU->CurrentThread->IPHistory[127] = Frame->rip; } } GlobalDescriptorTable::SetKernelStack((void *)((uintptr_t)CurrentCPU->CurrentThread->Stack->GetStackTop())); @@ -942,14 +942,25 @@ namespace Tasking Thread->Info.Architecture = Architecture; Thread->Info.Compatibility = Compatibility; +#ifdef DEBUG +#ifdef __amd64__ debug("Thread offset is %#lx (EntryPoint: %#lx) => RIP: %#lx", Thread->Offset, Thread->EntryPoint, Thread->Registers.rip); if (Parent->Security.TrustLevel == TaskTrustLevel::User) debug("Thread stack region is %#lx-%#lx (U) and rsp is %#lx", Thread->Stack->GetStackBottom(), Thread->Stack->GetStackTop(), Thread->Registers.rsp); else debug("Thread stack region is %#lx-%#lx (K) and rsp is %#lx", Thread->Stack->GetStackBottom(), Thread->Stack->GetStackTop(), Thread->Registers.rsp); +#elif defined(__i386__) + debug("Thread offset is %#lx (EntryPoint: %#lx) => RIP: %#lx", Thread->Offset, Thread->EntryPoint, Thread->Registers.eip); + if (Parent->Security.TrustLevel == TaskTrustLevel::User) + debug("Thread stack region is %#lx-%#lx (U) and rsp is %#lx", Thread->Stack->GetStackBottom(), Thread->Stack->GetStackTop(), Thread->Registers.esp); + else + debug("Thread stack region is %#lx-%#lx (K) and rsp is %#lx", Thread->Stack->GetStackBottom(), Thread->Stack->GetStackTop(), Thread->Registers.esp); +#elif defined(__aarch64__) +#endif debug("Created thread \"%s\"(%d) in process \"%s\"(%d)", Thread->Name, Thread->ID, Thread->Parent->Name, Thread->Parent->ID); +#endif Parent->Threads.push_back(Thread); return Thread; diff --git a/include/bitmap.hpp b/include/bitmap.hpp index a64611c..b34d5be 100644 --- a/include/bitmap.hpp +++ b/include/bitmap.hpp @@ -6,7 +6,7 @@ class Bitmap public: size_t Size; uint8_t *Buffer; - bool operator[](uintptr_t index); - bool Set(uintptr_t index, bool value); - bool Get(uintptr_t index); + bool operator[](uint64_t index); + bool Set(uint64_t index, bool value); + bool Get(uint64_t index); }; diff --git a/include/cpu.hpp b/include/cpu.hpp index 5edc3c6..ff28680 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -209,7 +209,7 @@ namespace CPU void InitializeFeatures(); /** @brief Get CPU counter value. */ - uint64_t Counter(); + uintptr_t Counter(); namespace MemBar { @@ -558,6 +558,1540 @@ namespace CPU : "memory"); #endif } + + /** @brief EXPERIMENTAL IMPLEMENTATION */ + namespace Intel + { + /** @brief Basic CPU information */ + struct CPUID0x0 + { + union + { + struct + { + uint32_t HighestFunctionSupported : 32; + }; + uint32_t raw; + } EAX; + union + { + struct + { + char rbx[4]; + }; + uint32_t raw; + } EBX; + union + { + struct + { + char rcx[4]; + }; + uint32_t raw; + } ECX; + union + { + struct + { + char rdx[4]; + }; + uint32_t raw; + } EDX; + }; + + /** @brief Additional CPU information */ + struct CPUID0x1 + { + union + { + struct + { + uint32_t SteppingID : 4; + uint32_t ModelID : 4; + uint32_t FamilyID : 4; + uint32_t Type : 2; + uint32_t Reserved0 : 2; + uint32_t ExtendedModel : 4; + uint32_t ExtendedFamily : 8; + uint32_t Reserved1 : 4; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t BrandIndex : 8; + uint32_t CLFLUSHLineSize : 8; + uint32_t LogicalProcessorsPerPackage : 8; + uint32_t LocalAPICID : 8; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t SSE3 : 1; + uint32_t PCLMULQDQ : 1; + uint32_t DTES64 : 1; + uint32_t MONITOR : 1; + uint32_t DS_CPL : 1; + uint32_t VMX : 1; + uint32_t SMX : 1; + uint32_t EIST : 1; + uint32_t TM2 : 1; + uint32_t SSSE3 : 1; + uint32_t CNXT_ID : 1; + uint32_t Reserved0 : 1; + uint32_t FMA : 1; + uint32_t CMPXCHG16B : 1; + uint32_t xTPRUpdateControl : 1; + uint32_t PDCM : 1; + uint32_t Reserved1 : 1; + uint32_t PCID : 1; + uint32_t DCA : 1; + uint32_t SSE4_1 : 1; + uint32_t SSE4_2 : 1; + uint32_t x2APIC : 1; + uint32_t MOVBE : 1; + uint32_t POPCNT : 1; + uint32_t TSCDeadline : 1; + uint32_t AES : 1; + uint32_t XSAVE : 1; + uint32_t OSXSAVE : 1; + uint32_t AVX : 1; + uint32_t F16C : 1; + uint32_t RDRAND : 1; + uint32_t Reserved2 : 1; + uint32_t Hypervisor : 1; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t FPU : 1; + uint32_t VME : 1; + uint32_t DE : 1; + uint32_t PSE : 1; + uint32_t TSC : 1; + uint32_t MSR : 1; + uint32_t PAE : 1; + uint32_t MCE : 1; + uint32_t CX8 : 1; + uint32_t APIC : 1; + uint32_t Reserved0 : 1; + uint32_t SEP : 1; + uint32_t MTRR : 1; + uint32_t PGE : 1; + uint32_t MCA : 1; + uint32_t CMOV : 1; + uint32_t PAT : 1; + uint32_t PSE36 : 1; + uint32_t PSN : 1; + uint32_t CLFSH : 1; + uint32_t Reserved1 : 1; + uint32_t DS : 1; + uint32_t ACPI : 1; + uint32_t MMX : 1; + uint32_t FXSR : 1; + uint32_t SSE : 1; + uint32_t SSE2 : 1; + uint32_t SS : 1; + uint32_t HTT : 1; + uint32_t TM : 1; + uint32_t Reserved2 : 1; + uint32_t PBE : 1; + }; + uint32_t raw; + } EDX; + }; + + /** @brief CPU cache and TLB */ + struct CPUID0x2 + { + union + { + struct + { + uint32_t CacheLineSize : 8; + uint32_t CacheLinesPerTag : 8; + uint32_t Associativity : 8; + uint32_t CacheSize : 8; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t CacheLineSize : 8; + uint32_t CacheLinesPerTag : 8; + uint32_t Associativity : 8; + uint32_t CacheSize : 8; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t CacheLineSize : 8; + uint32_t CacheLinesPerTag : 8; + uint32_t Associativity : 8; + uint32_t CacheSize : 8; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t CacheLineSize : 8; + uint32_t CacheLinesPerTag : 8; + uint32_t Associativity : 8; + uint32_t CacheSize : 8; + }; + uint32_t raw; + } EDX; + }; + + /** @brief CPU serial number */ + struct CPUID0x3 + { + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t ProcessorSerialNumber : 32; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t ProcessorSerialNumber : 32; + }; + uint32_t raw; + } EDX; + }; + + /** @brief Cache information */ + struct CPUID0x4_1 + { + union + { + struct + { + uint32_t Type : 5; + uint32_t Level : 3; + uint32_t SelfInitializing : 1; + uint32_t FullyAssociative : 1; + uint32_t Reserved : 4; + uint32_t MaxAddressableIdsForLogicalProcessors : 12; + uint32_t CoresPerPackage : 6; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t SystemCoherencyLineSize : 12; + uint32_t PhysicalLinePartitions : 10; + uint32_t WaysOfAssociativity : 10; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EDX; + }; + + /** @brief MONITOR information */ + struct CPUID0x5 + { + union + { + struct + { + uint32_t SmallestMonitorLineSize : 16; + uint32_t Reserved : 16; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t LargestMonitorLineSize : 16; + uint32_t Reserved : 16; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t MWAITEnumerationSupported : 1; + uint32_t InterruptsAsBreakEvent : 1; + uint32_t Reserved : 30; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t C0 : 4; + uint32_t C1 : 4; + uint32_t C2 : 4; + uint32_t C3 : 4; + uint32_t C4 : 4; + uint32_t Reserved : 12; + }; + uint32_t raw; + } EDX; + }; + + /** @brief Thermal and power management information */ + struct CPUID0x6 + { + union + { + struct + { + uint32_t SensorSupported : 1; + uint32_t Reserved : 31; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t InterruptThreshold : 4; + uint32_t Reserved : 26; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t ACNT_MCNT : 1; + uint32_t Reserved : 31; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EDX; + }; + + /** @brief Performance monitors */ + struct CPUID0xA + { + union + { + struct + { + uint32_t VersionID : 8; + uint32_t NumberCounters : 8; + uint32_t BitWidthOfCounters : 8; + uint32_t LengthOfEBXBitVector : 8; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t CoreCycles : 1; + uint32_t InstructionsRetired : 1; + uint32_t ReferenceCycles : 1; + uint32_t CacheReferences : 1; + uint32_t CacheMisses : 1; + uint32_t BranchInstructionsRetired : 1; + uint32_t BranchMissesRetired : 1; + uint32_t Reserved : 25; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t FixedFunctionCounters : 5; + uint32_t CounterWidth : 8; + uint32_t Reserved : 19; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EDX; + }; + + /** @brief Get CPU frequency information */ + struct CPUID0x15 + { + union + { + struct + { + uint32_t VersionID : 8; + uint32_t NumberCounters : 8; + uint32_t BitWidthOfCounters : 8; + uint32_t LengthOfEBXBitVector : 8; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t CoreCycles : 1; + uint32_t InstructionsRetired : 1; + uint32_t ReferenceCycles : 1; + uint32_t CacheReferences : 1; + uint32_t CacheMisses : 1; + uint32_t BranchInstructionsRetired : 1; + uint32_t BranchMissesRetired : 1; + uint32_t Reserved : 25; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t FixedFunctionCounters : 5; + uint32_t CounterWidth : 8; + uint32_t Reserved : 19; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EDX; + }; + + /** @brief Get CPU frequency information */ + struct CPUID0x16 + { + union + { + struct + { + /** + * @brief Denominator of the TSC frequency + * + * @note TSC frequency = core crystal clock frequency * EBX/EAX + */ + uint32_t Denominator : 31; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + /** + * @brief Numerator of the TSC frequency + * + * @note TSC frequency = core crystal clock frequency * EBX/EAX + */ + uint32_t Numerator : 31; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + /** @brief Core crystal clock frequency in Hz */ + uint32_t CoreCrystalClock : 31; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + /** @brief Reserved */ + uint32_t Reserved : 31; + }; + uint32_t raw; + } EDX; + }; + + /** @brief Get CPU hypervisor information */ + struct CPUID0x40000000 + { + union + { + struct + { + /** + * @brief Maximum input value for hypervisor CPUID information. + * @note Can be from 0x40000001 to 0x400000FF + */ + uint32_t MaximumInputValue : 32; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + /** @brief Hypervisor vendor signature */ + char Hypervisor[4]; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + /** @brief Hypervisor vendor signature */ + char Hypervisor[4]; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + /** @brief Hypervisor vendor signature */ + char Hypervisor[4]; + }; + uint32_t raw; + } EDX; + }; + + /** @brief Extended CPU information */ + struct CPUID0x80000000 + { + union + { + struct + { + uint32_t HighestExtendedFunctionSupported : 32; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EDX; + uint32_t raw; + }; + + /** @brief Extended CPU information */ + struct CPUID0x80000001 + { + union + { + struct + { + uint32_t Unknown : 32; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t LAHF_SAHF : 1; + uint32_t Reserved : 31; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t Reserved0 : 11; + uint32_t SYSCALL : 1; + uint32_t Reserved1 : 8; + uint32_t ExecuteDisable : 1; + uint32_t Reserved2 : 8; + uint32_t EMT64T : 1; + uint32_t Reserved3 : 2; + }; + uint32_t raw; + } EDX; + uint32_t raw; + }; + + /** @brief CPU brand string */ + struct CPUID0x80000002 + { + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EDX; + uint32_t raw; + }; + + /** @brief CPU brand string */ + struct CPUID0x80000003 + { + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EDX; + uint32_t raw; + }; + + /** @brief CPU brand string */ + struct CPUID0x80000004 + { + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EDX; + uint32_t raw; + }; + + /** @brief CPU cache line information */ + struct CPUID0x80000006 + { + union + { + struct + { + uint32_t InstructionCount : 12; + uint32_t InstructionAssociativity : 4; + uint32_t DataCount : 12; + uint32_t DataAssociativity : 4; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t InstructionCount : 12; + uint32_t InstructionAssociativity : 4; + uint32_t DataCount : 12; + uint32_t DataAssociativity : 4; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t LineSize : 8; + uint32_t LinePerTag : 4; + uint32_t Associativity : 4; + uint32_t CacheSize : 16; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EDX; + uint32_t raw; + }; + + /** @brief Virtual and physical memory size */ + struct CPUID0x80000008 + { + union + { + struct + { + uint32_t PhysicalAddressBits : 8; + uint32_t LinearAddressBits : 8; + uint32_t Reserved : 16; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EDX; + uint32_t raw; + }; + + /** @brief Secure virtual machine parameters */ + struct CPUID0x8000000A + { + union + { + struct + { + uint32_t SVMRevision : 8; + uint32_t Reserved : 24; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EDX; + uint32_t raw; + }; + } + + /** @brief EXPERIMENTAL IMPLEMENTATION */ + namespace AMD + { + /** @brief Basic CPU information */ + struct CPUID0x0 + { + union + { + struct + { + uint32_t HighestFunctionSupported : 32; + }; + uint32_t raw; + } EAX; + union + { + struct + { + char Vendor[4]; + }; + uint32_t raw; + } EBX; + union + { + struct + { + char Vendor[4]; + }; + uint32_t raw; + } ECX; + union + { + struct + { + char Vendor[4]; + }; + uint32_t raw; + } EDX; + }; + + /** @brief Additional CPU information */ + struct CPUID0x1 + { + union + { + struct + { + uint32_t SteppingID : 4; + uint32_t ModelID : 4; + uint32_t FamilyID : 4; + uint32_t Reserved0 : 4; + uint32_t ExtendedModel : 4; + uint32_t ExtendedFamily : 8; + uint32_t Reserved1 : 4; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t BrandIndex : 8; + uint32_t CLFLUSHLineSize : 8; + uint32_t LogicalProcessorsPerPackage : 8; + uint32_t LocalAPICID : 8; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t SSE3 : 1; + uint32_t Reserved0 : 1; + uint32_t MONITOR : 1; + uint32_t Reserved1 : 1; + uint32_t DS_CPL : 1; + uint32_t Reserved2 : 1; + uint32_t SMX : 1; + uint32_t Reserved3 : 1; + uint32_t TM2 : 1; + uint32_t Reserved4 : 1; + uint32_t CNXT_ID : 1; + uint32_t Reserved5 : 1; + uint32_t CMPXCHG16B : 1; + uint32_t Reserved6 : 1; + uint32_t xTPRUpdateControl : 1; + uint32_t Reserved7 : 1; + uint32_t Reserved8 : 1; + uint32_t DCA : 1; + uint32_t Reserved9 : 1; + uint32_t SSE4_1 : 1; + uint32_t SSE4_2 : 1; + uint32_t Reserved10 : 1; + uint32_t MOVBE : 1; + uint32_t POPCNT : 1; + uint32_t Reserved11 : 1; + uint32_t AES : 1; + uint32_t Reserved12 : 1; + uint32_t XSAVE : 1; + uint32_t OSXSAVE : 1; + uint32_t AVX : 1; + uint32_t Reserved13 : 1; + uint32_t RDRAND : 1; + uint32_t Reserved14 : 1; + uint32_t Hypervisor : 1; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t FPU : 1; + uint32_t VME : 1; + uint32_t DE : 1; + uint32_t PSE : 1; + uint32_t TSC : 1; + uint32_t MSR : 1; + uint32_t PAE : 1; + uint32_t MCE : 1; + uint32_t CX8 : 1; + uint32_t APIC : 1; + uint32_t Reserved0 : 1; + uint32_t SEP : 1; + uint32_t MTRR : 1; + uint32_t PGE : 1; + uint32_t MCA : 1; + uint32_t CMOV : 1; + uint32_t PAT : 1; + uint32_t PSE36 : 1; + uint32_t PSN : 1; + uint32_t CLFSH : 1; + uint32_t Reserved1 : 1; + uint32_t DS : 1; + uint32_t ACPI : 1; + uint32_t MMX : 1; + uint32_t FXSR : 1; + uint32_t SSE : 1; + uint32_t SSE2 : 1; + uint32_t SS : 1; + uint32_t HTT : 1; + uint32_t TM : 1; + uint32_t Reserved2 : 1; + uint32_t PBE : 1; + }; + uint32_t raw; + } EDX; + }; + + /** @brief CPU cache and TLB */ + struct CPUID0x2 + { + union + { + struct + { + uint32_t L1DataCacheSize : 8; + uint32_t L1DataCacheAssociativity : 8; + uint32_t L1DataCacheLineSize : 8; + uint32_t L1DataCachePartitions : 8; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t L1InstructionCacheSize : 8; + uint32_t L1InstructionCacheAssociativity : 8; + uint32_t L1InstructionCacheLineSize : 8; + uint32_t L1InstructionCachePartitions : 8; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t L2UnifiedCacheSize : 16; + uint32_t L2UnifiedCacheAssociativity : 8; + uint32_t L2UnifiedCacheLineSize : 8; + uint32_t L2UnifiedCachePartitions : 8; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t L3UnifiedCacheSize : 18; + uint32_t L3UnifiedCacheAssociativity : 8; + uint32_t L3UnifiedCacheLineSize : 8; + uint32_t L3UnifiedCachePartitions : 8; + }; + uint32_t raw; + } EDX; + }; + + /** @brief Get CPU hypervisor information */ + struct CPUID0x40000000 + { + union + { + struct + { + /** + * @brief Maximum input value for hypervisor CPUID information. + * @note Can be from 0x40000001 to 0x400000FF + */ + uint32_t MaximumInputValue : 32; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + /** @brief Hypervisor vendor signature */ + char Hypervisor[4]; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + /** @brief Hypervisor vendor signature */ + char Hypervisor[4]; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + /** @brief Hypervisor vendor signature */ + char Hypervisor[4]; + }; + uint32_t raw; + } EDX; + }; + + /** @brief Extended CPU information */ + struct CPUID0x80000001 + { + union + { + struct + { + uint32_t SteppingID : 4; + uint32_t ModelID : 4; + uint32_t FamilyID : 4; + uint32_t Reserved0 : 4; + uint32_t ExtendedModel : 4; + uint32_t ExtendedFamily : 8; + uint32_t Reserved1 : 4; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t BranchID : 16; + uint32_t Reserved0 : 16; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t LAHF_SAHF : 1; + uint32_t CmpLegacy : 1; + uint32_t SVM : 1; + uint32_t Reserved0 : 1; + uint32_t AltMovCr8 : 1; + uint32_t Reserved1 : 26; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t FPU : 1; + uint32_t VME : 1; + uint32_t DE : 1; + uint32_t PSE : 1; + uint32_t TSC : 1; + uint32_t MSR : 1; + uint32_t PAE : 1; + uint32_t MCE : 1; + uint32_t CMPXCHG8B : 1; + uint32_t APIC : 1; + uint32_t Reserved0 : 1; + uint32_t SYSCALL : 1; + uint32_t MTRR : 1; + uint32_t PGE : 1; + uint32_t MCA : 1; + uint32_t CMOV : 1; + uint32_t PAT : 1; + uint32_t PSE36 : 1; + uint32_t Reserved1 : 1; + uint32_t ExeDisable : 1; + uint32_t Reserved2 : 1; + uint32_t MMXExtended : 1; + uint32_t MMX : 1; + uint32_t FXSR : 1; + uint32_t FFXSR : 1; + uint32_t Reserved3 : 1; + uint32_t RDTSCP : 1; + uint32_t Reserved4 : 1; + uint32_t LongMode : 1; + uint32_t ThreeDNowExtended : 1; + uint32_t ThreeDNow : 1; + }; + uint32_t raw; + } EDX; + }; + + /** @brief CPU brand string */ + struct CPUID0x80000002 + { + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EDX; + }; + + /** @brief CPU brand string */ + struct CPUID0x80000003 + { + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EDX; + }; + + /** @brief CPU brand string */ + struct CPUID0x80000004 + { + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + char Brand[4]; + }; + uint32_t raw; + } EDX; + }; + + /** @brief Cache and TLB information */ + struct CPUID0x80000005 + { + union + { + struct + { + uint32_t InstructionCount : 8; + uint32_t InstructionAssociativity : 8; + uint32_t DataCount : 8; + uint32_t DataAssociativity : 8; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t InstructionCount : 8; + uint32_t InstructionAssociativity : 8; + uint32_t DataCount : 8; + uint32_t DataAssociativity : 8; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t LineSize : 8; + uint32_t LinePerTag : 8; + uint32_t Associativity : 8; + uint32_t CacheSize : 8; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t LineSize : 8; + uint32_t LinePerTag : 8; + uint32_t Associativity : 8; + uint32_t CacheSize : 8; + }; + uint32_t raw; + } EDX; + }; + + /** @brief CPU cache line information */ + struct CPUID0x80000006 + { + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t LineSize : 8; + uint32_t LinePerTag : 4; + uint32_t Associativity : 4; + uint32_t CacheSize : 16; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EDX; + }; + + /** @brief APM */ + struct CPUID0x80000007 + { + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EAX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } EBX; + + union + { + struct + { + uint32_t Reserved : 32; + }; + uint32_t raw; + } ECX; + + union + { + struct + { + uint32_t TemperatureSensor : 1; + uint32_t FrequencyID : 1; + uint32_t VoltageID : 1; + uint32_t ThermaTrip : 1; + uint32_t HarwareThermalControl : 1; + uint32_t SoftwareThermalControl : 1; + uint32_t Reserved0 : 2; + uint32_t TSCInvariant : 1; + uint32_t Reserved1 : 23; + }; + uint32_t raw; + } EDX; + }; + } } namespace x64 @@ -1764,7 +3298,7 @@ namespace CPU SafeFunction static inline CR0 readcr0() { - uint64_t Result; + uint64_t Result = 0; #if defined(__amd64__) asmv("mov %%cr0, %[Result]" : [Result] "=q"(Result)); @@ -1774,7 +3308,7 @@ namespace CPU SafeFunction static inline CR2 readcr2() { - uint64_t Result; + uint64_t Result = 0; #if defined(__amd64__) asmv("mov %%cr2, %[Result]" : [Result] "=q"(Result)); @@ -1784,7 +3318,7 @@ namespace CPU SafeFunction static inline CR3 readcr3() { - uint64_t Result; + uint64_t Result = 0; #if defined(__amd64__) asmv("mov %%cr3, %[Result]" : [Result] "=q"(Result)); @@ -1794,7 +3328,7 @@ namespace CPU SafeFunction static inline CR4 readcr4() { - uint64_t Result; + uint64_t Result = 0; #if defined(__amd64__) asmv("mov %%cr4, %[Result]" : [Result] "=q"(Result)); @@ -1804,7 +3338,7 @@ namespace CPU SafeFunction static inline CR8 readcr8() { - uint64_t Result; + uint64_t Result = 0; #if defined(__amd64__) asmv("mov %%cr8, %[Result]" : [Result] "=q"(Result)); diff --git a/include/display.hpp b/include/display.hpp index eeed7aa..517f868 100644 --- a/include/display.hpp +++ b/include/display.hpp @@ -110,7 +110,7 @@ namespace Video size_t Size = this->framebuffer.Pitch * Height; if (!this->Buffers[Index]) { - if (this->Buffers[Index]->Checksum != 0xDEAD5C9EE7) + if (this->Buffers[Index]->Checksum != 0xDEAD) { ScreenBuffer *buffer = new ScreenBuffer; buffer->Buffer = KernelAllocator.RequestPages(TO_PAGES(Size)); @@ -122,7 +122,7 @@ namespace Video buffer->CursorY = 0; this->Buffers[Index] = buffer; memset(this->Buffers[Index]->Buffer, 0, Size); - this->Buffers[Index]->Checksum = 0xDEAD5C9EE7; + this->Buffers[Index]->Checksum = 0xDEAD; } else warn("Buffer %d already exists, skipping creation", Index); diff --git a/include/task.hpp b/include/task.hpp index bc396c7..af8a8da 100644 --- a/include/task.hpp +++ b/include/task.hpp @@ -94,14 +94,13 @@ namespace Tasking #if defined(__amd64__) CPU::x64::TrapFrame Registers; uint64_t GSBase, FSBase; - uint64_t RIPHistory[128]; #elif defined(__i386__) - uint32_t Registers; // TODO + CPU::x32::TrapFrame Registers; // TODO uint64_t GSBase, FSBase; - uint32_t EIPHistory[128]; #elif defined(__aarch64__) uint64_t Registers; // TODO #endif + uintptr_t IPHistory[128]; TaskSecurity Security; TaskInfo Info; char FXRegion[512] __attribute__((aligned(16)));