From 4e20d4d9f4bacbd966e855a3aee4430e34e6d198 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 4 Apr 2023 16:06:54 +0300 Subject: [PATCH] Enable compilation of project on AArch64 architecture --- .vscode/c_cpp_properties.json | 62 +++++++++++++++++++++++++++++++ Core/CPU.cpp | 20 +++++----- Core/Crash/CrashDetails.cpp | 5 +++ Core/Crash/CrashHandler.cpp | 11 ++++++ Core/Crash/KBDrv.cpp | 11 +++++- Core/Crash/SFrame.cpp | 1 + Core/Crash/Screens/Details.cpp | 7 +++- Core/Crash/Screens/StackFrame.cpp | 1 + Core/Crash/UserHandler.cpp | 9 ++++- Core/Crash/chfcts.hpp | 11 +++++- Core/Driver/Driver.cpp | 4 +- Core/InterruptsManager.cpp | 4 +- Core/Random.cpp | 12 +++--- DAPI.hpp | 2 +- KThread.cpp | 6 +++ Library/Convert.cpp | 2 +- Makefile | 8 +++- Profiling/cyg.cpp | 8 ++++ SystemCalls/Linux.cpp | 2 + Tasking/Scheduler.cpp | 4 +- Tasking/Task.cpp | 14 +++++-- Tests/RandomNumberGenerator.cpp | 4 +- include/abi.h | 1 + include/cpu.hpp | 35 +++++++++++++++-- include/driver.hpp | 2 +- include/intrin.hpp | 40 +++++++++++++++++--- include/ints.hpp | 2 +- include/task.hpp | 4 +- 28 files changed, 242 insertions(+), 50 deletions(-) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index ce59b72..bbbe814 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -136,6 +136,68 @@ "-fstack-check", "-fsanitize=undefined", + // VSCode flags + "-ffreestanding", + "-nostdinc", + "-nostdinc++" + ] + }, + { + "name": "Fennix Aarch64 (Linux, GCC, debug)", + "includePath": [ + "${workspaceFolder}/include/**" + ], + "defines": [ + "__debug_vscode__", + "KERNEL_NAME=\"Fennix\"", + "KERNEL_VERSION=\"1.0\"", + "GIT_COMMIT=\"0000000000000000000000000000000000000000\"", + "GIT_COMMIT_SHORT=\"0000000\"", + "aa64", + "DEBUG=\"1\"" + ], + "compilerPath": "${workspaceFolder}/../tools/cross/bin/aarch64-elf-gcc", + "cStandard": "c17", + "cppStandard": "c++20", + "intelliSenseMode": "linux-gcc-arm64", + "configurationProvider": "ms-vscode.makefile-tools", + "compilerArgs": [ + // Compiler flags + "-pipe", + "-fno-builtin", + "-msoft-float", + "-fPIC", + "-Wstack-protector", + + // Warnings + "-Wall", + "-Wextra", + "-Wfloat-equal", + "-Wpointer-arith", + "-Wcast-align", + "-Wredundant-decls", + "-Winit-self", + "-Wswitch-default", + "-Wstrict-overflow=5", + "-Wconversion", + + // C++ flags + "-fno-rtti", + "-fexceptions", + + // Linker flags + "-T${workspaceFolder}/Architecture/aarch64/linker.ld", + "-fPIC", + + // Debug flags + "-ggdb3", + "-O0", + "-fdiagnostics-color=always", + "-fverbose-asm", + "-fstack-usage", + "-fstack-check", + "-fsanitize=undefined", + // VSCode flags "-ffreestanding", "-nostdinc", diff --git a/Core/CPU.cpp b/Core/CPU.cpp index 7457cf5..d526805 100644 --- a/Core/CPU.cpp +++ b/Core/CPU.cpp @@ -366,8 +366,9 @@ namespace CPU if (unlikely(!SSEEnabled)) return SIMD_NONE; - // return SIMD_SSE; + // return SIMD_SSE; +#if defined(a64) || defined(a32) static uint64_t SIMDType = SIMD_NONE; if (likely(SIMDType != SIMD_NONE)) @@ -380,11 +381,10 @@ namespace CPU #elif defined(a32) CPU::x32::AMD::CPUID0x1 cpuid1amd; #endif -#if defined(a64) || defined(a32) asmv("cpuid" : "=a"(cpuid1amd.EAX.raw), "=b"(cpuid1amd.EBX.raw), "=c"(cpuid1amd.ECX.raw), "=d"(cpuid1amd.EDX.raw) : "a"(0x1)); -#endif + if (cpuid1amd.ECX.SSE4_2) SIMDType |= SIMD_SSE42; else if (cpuid1amd.ECX.SSE4_1) @@ -418,11 +418,10 @@ namespace CPU #elif defined(a32) CPU::x32::Intel::CPUID0x1 cpuid1intel; #endif -#if defined(a64) || defined(a32) asmv("cpuid" : "=a"(cpuid1intel.EAX.raw), "=b"(cpuid1intel.EBX.raw), "=c"(cpuid1intel.ECX.raw), "=d"(cpuid1intel.EDX.raw) : "a"(0x1)); -#endif + if (cpuid1intel.ECX.SSE4_2) SIMDType |= SIMD_SSE42; else if (cpuid1intel.ECX.SSE4_1) @@ -446,11 +445,11 @@ namespace CPU if (cpuid1intel.EDX.SSE) debug("SSE is supported."); #endif - return SIMDType; } debug("No SIMD support."); +#endif // a64 || a32 return SIMD_NONE; } @@ -459,6 +458,7 @@ namespace CPU if (unlikely(!SSEEnabled)) return false; +#if defined(a64) || defined(a32) if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { #if defined(a64) @@ -466,11 +466,10 @@ namespace CPU #elif defined(a32) CPU::x32::AMD::CPUID0x1 cpuid1amd; #endif -#if defined(a64) || defined(a32) asmv("cpuid" : "=a"(cpuid1amd.EAX.raw), "=b"(cpuid1amd.EBX.raw), "=c"(cpuid1amd.ECX.raw), "=d"(cpuid1amd.EDX.raw) : "a"(0x1)); -#endif + if (Type == SIMD_SSE42) return cpuid1amd.ECX.SSE4_2; else if (Type == SIMD_SSE41) @@ -489,11 +488,10 @@ namespace CPU #elif defined(a32) CPU::x32::Intel::CPUID0x1 cpuid1intel; #endif -#if defined(a64) || defined(a32) asmv("cpuid" : "=a"(cpuid1intel.EAX.raw), "=b"(cpuid1intel.EBX.raw), "=c"(cpuid1intel.ECX.raw), "=d"(cpuid1intel.EDX.raw) : "a"(0x1)); -#endif + if (Type == SIMD_SSE42) return cpuid1intel.ECX.SSE4_2; else if (Type == SIMD_SSE41) @@ -505,7 +503,7 @@ namespace CPU else if (Type == SIMD_SSE) return cpuid1intel.EDX.SSE; } - +#endif // a64 || a32 return false; } } diff --git a/Core/Crash/CrashDetails.cpp b/Core/Crash/CrashDetails.cpp index 25d464a..bc1b85e 100644 --- a/Core/Crash/CrashDetails.cpp +++ b/Core/Crash/CrashDetails.cpp @@ -195,7 +195,10 @@ SafeFunction void PageFaultExceptionHandler(CHArchTrapFrame *Frame) #elif defined(a32) Memory::Virtual vma = Memory::Virtual(((Memory::PageTable4 *)CPU::x32::readcr3().raw)); #elif defined(aa64) + Memory::Virtual vma = Memory::Virtual(); +#warning "TODO: aa64" #endif + bool PageAvailable = vma.Check((void *)CheckPageFaultAddress); debug("Page available (Check(...)): %s. %s", PageAvailable ? "Yes" : "No", @@ -240,6 +243,8 @@ SafeFunction void PageFaultExceptionHandler(CHArchTrapFrame *Frame) #elif defined(a32) Memory::PageMapLevel4 PML4 = ((Memory::PageTable4 *)CPU::x32::readcr3().raw)->Entries[Index.PMLIndex]; #elif defined(aa64) + Memory::PageMapLevel4 PML4 = {.raw = 0}; +#warning "TODO: aa64" #endif Memory::PageDirectoryPointerTableEntryPtr *PDPTE = (Memory::PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.GetAddress() << 12); diff --git a/Core/Crash/CrashHandler.cpp b/Core/Crash/CrashHandler.cpp index fc0d3c4..dbbf655 100644 --- a/Core/Crash/CrashHandler.cpp +++ b/Core/Crash/CrashHandler.cpp @@ -375,8 +375,10 @@ namespace CrashHandler int tmpidx = SBIdx; SBIdx = atoi(arg); Display->SetBuffer(SBIdx); +#if defined(a64) || defined(a32) for (int i = 0; i < 5000000; i++) inb(0x80); +#endif // a64 || a32 SBIdx = tmpidx; Display->SetBuffer(SBIdx); } @@ -408,12 +410,15 @@ namespace CrashHandler #elif defined(a32) if ((uintptr_t)EHIntFrames[i] >= 0xC0000000 && (uintptr_t)EHIntFrames[i] <= (uintptr_t)&_kernel_end) #elif defined(aa64) + if ((uintptr_t)EHIntFrames[i] >= 0xFFFFFFFF80000000 && (uintptr_t)EHIntFrames[i] <= (uintptr_t)&_kernel_end) #endif EHPrint("\e25CCC9%s", KernelSymbolTable->GetSymbolFromAddress((uintptr_t)EHIntFrames[i])); else EHPrint("\eFF4CA9Outside Kernel"); +#if defined(a64) || defined(a32) for (int i = 0; i < 20000; i++) inb(0x80); +#endif // a64 || a32 Display->SetBuffer(SBIdx); } } @@ -619,6 +624,7 @@ namespace CrashHandler } else { +#if defined(a64) || defined(a32) GlobalDescriptorTable::TaskStateSegment tss = GlobalDescriptorTable::tss[TSSIndex]; EHPrint("\eFAFAFAStack Pointer 0: \eAABB22%#lx\n", tss.StackPointer[0]); EHPrint("\eFAFAFAStack Pointer 1: \eAABB22%#lx\n", tss.StackPointer[1]); @@ -637,6 +643,9 @@ namespace CrashHandler EHPrint("\eFAFAFAReserved 0: \eAABB22%#lx\n", tss.Reserved0); EHPrint("\eFAFAFAReserved 1: \eAABB22%#lx\n", tss.Reserved1); EHPrint("\eFAFAFAReserved 2: \eAABB22%#lx\n", tss.Reserved2); +#elif defined(aa64) + EHPrint("\eFF0000AArch64 does not have TSS\n"); +#endif } } else if (strncmp(Input, "dump", 4) == 0) @@ -1058,7 +1067,9 @@ namespace CrashHandler goto CrashEnd; #elif defined(a32) + goto CrashEnd; #elif defined(aa64) + goto CrashEnd; #endif CrashEnd: diff --git a/Core/Crash/KBDrv.cpp b/Core/Crash/KBDrv.cpp index 559f152..80416aa 100644 --- a/Core/Crash/KBDrv.cpp +++ b/Core/Crash/KBDrv.cpp @@ -96,6 +96,7 @@ namespace CrashHandler { CrashKeyboardDriver::CrashKeyboardDriver() : Interrupts::Handler(1) /* IRQ1 */ { +#if defined(a64) || defined(a32) while (inb(0x64) & 0x1) inb(0x60); @@ -108,6 +109,8 @@ namespace CrashHandler outb(0x21, 0xFD); outb(0xA1, 0xFF); +#endif // defined(a64) || defined(a32) + CPU::Interrupts(CPU::Enable); // Just to be sure. } @@ -124,9 +127,10 @@ namespace CrashHandler #elif defined(a32) SafeFunction void CrashKeyboardDriver::OnInterruptReceived(CPU::x32::TrapFrame *Frame) #elif defined(aa64) - SafeFunction void CrashKeyboardDriver::OnInterruptReceived(void *Frame) + SafeFunction void CrashKeyboardDriver::OnInterruptReceived(CPU::aarch64::TrapFrame *Frame) #endif { +#if defined(a64) || defined(a32) UNUSED(Frame); uint8_t scanCode = inb(0x60); if (scanCode == KEY_D_TAB || @@ -174,12 +178,17 @@ namespace CrashHandler } Display->SetBuffer(SBIdx); // Update as we type. } +#endif // a64 || a32 } SafeFunction void HookKeyboard() { CrashKeyboardDriver kbd; // We don't want to allocate memory. +#if defined(a64) || defined(a32) asmv("KeyboardHookLoop: nop; jmp KeyboardHookLoop;"); +#elif defined(aa64) + asmv("KeyboardHookLoop: nop; b KeyboardHookLoop;"); +#endif // CPU::Halt(true); // This is an infinite loop. } } diff --git a/Core/Crash/SFrame.cpp b/Core/Crash/SFrame.cpp index e9d0dec..026177f 100644 --- a/Core/Crash/SFrame.cpp +++ b/Core/Crash/SFrame.cpp @@ -132,6 +132,7 @@ namespace CrashHandler #elif defined(a32) if ((frames->rip >= 0xC0000000 && frames->rip <= (uintptr_t)&_kernel_end) || !Kernel) #elif defined(aa64) + if ((frames->rip >= 0xFFFFFFFF80000000 && frames->rip <= (uintptr_t)&_kernel_end) || !Kernel) #endif EHPrint("\e25CCC9%s", SymHandle->GetSymbolFromAddress(frames->rip)); else diff --git a/Core/Crash/Screens/Details.cpp b/Core/Crash/Screens/Details.cpp index e85cc6a..d793f50 100644 --- a/Core/Crash/Screens/Details.cpp +++ b/Core/Crash/Screens/Details.cpp @@ -86,6 +86,8 @@ namespace CrashHandler 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(aa64) #endif + +#if defined(a64) || defined(a32) 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); @@ -111,10 +113,9 @@ namespace CrashHandler data.cr4.Reserved0, data.cr4.Reserved1, data.cr4.Reserved2); #elif defined(a32) data.cr4.Reserved0, data.cr4.Reserved1, 0); -#elif defined(aa64) #endif - EHPrint("\e79FCF5CR8: TPL:%d\n", data.cr8.TPL); +#endif // a64 || a32 #if defined(a64) 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", @@ -135,6 +136,7 @@ namespace CrashHandler #elif defined(aa64) #endif +#if defined(a64) || defined(a32) 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", data.dr7.LocalDR2 ? "True " : "False", data.dr7.GlobalDR2 ? "True " : "False", data.dr7.LocalDR3 ? "True " : "False", data.dr7.GlobalDR3 ? "True " : "False", @@ -146,6 +148,7 @@ namespace CrashHandler data.efer.SCE ? "True " : "False", data.efer.LME ? "True " : "False", data.efer.LMA ? "True " : "False", data.efer.NXE ? "True " : "False", data.efer.SVME ? "True " : "False", data.efer.LMSLE ? "True " : "False", data.efer.FFXSR ? "True " : "False", data.efer.TCE ? "True " : "False", data.efer.Reserved0, data.efer.Reserved1, data.efer.Reserved2); +#endif switch (data.Frame->InterruptNumber) { diff --git a/Core/Crash/Screens/StackFrame.cpp b/Core/Crash/Screens/StackFrame.cpp index 93411ab..0b23cf5 100644 --- a/Core/Crash/Screens/StackFrame.cpp +++ b/Core/Crash/Screens/StackFrame.cpp @@ -62,6 +62,7 @@ namespace CrashHandler #elif defined(a32) if ((uintptr_t)EHIntFrames[i] >= 0xC0000000 && (uintptr_t)EHIntFrames[i] <= (uintptr_t)&_kernel_end) #elif defined(aa64) + if ((uintptr_t)EHIntFrames[i] >= 0xFFFFFFFF80000000 && (uintptr_t)EHIntFrames[i] <= (uintptr_t)&_kernel_end) #endif EHPrint("\e25CCC9%s", KernelSymbolTable->GetSymbolFromAddress((uintptr_t)EHIntFrames[i])); else diff --git a/Core/Crash/UserHandler.cpp b/Core/Crash/UserHandler.cpp index 7405a5a..f908f46 100644 --- a/Core/Crash/UserHandler.cpp +++ b/Core/Crash/UserHandler.cpp @@ -98,6 +98,8 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame) error("EIP=%#llx EFL=%#llx INT=%#llx ERR=%#llx EFER=%#llx", Frame->eip, Frame->eflags.raw, Frame->InterruptNumber, Frame->ErrorCode, efer.raw); #elif defined(aa64) #endif + +#if defined(a64) || defined(a32) 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", @@ -111,6 +113,7 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame) error("CR3: PWT:%s PCD:%s PDBR:%#llx", cr3.PWT ? "True " : "False", cr3.PCD ? "True " : "False", cr3.PDBR); +#endif // defined(a64) || defined(a32) #if defined(a64) error("CR4: VME:%s PVI:%s TSD:%s DE:%s PSE:%s PAE:%s MCE:%s PGE:%s PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s LA57:%s VMXE:%s SMXE:%s PCIDE:%s OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s R0:%#x R1:%#x R2:%#x", @@ -121,7 +124,7 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame) cr4.OSXSAVE ? "True " : "False", cr4.SMEP ? "True " : "False", cr4.SMAP ? "True " : "False", cr4.PKE ? "True " : "False", cr4.Reserved0, cr4.Reserved1, cr4.Reserved2); #elif defined(a32) - error("CR4: VME:%s PVI:%s TSD:%s DE:%s PSE:%s PAE:%s MCE:%s PGE:%s PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s LA57:%s VMXE:%s SMXE:%s PCIDE:%s OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s R0:%#x R1:%#x", + error("CR4: VME:%s PVI:%s TSD:%s DE:%s PSE:%s PAE:%s MCE:%s PGE:%s PCE:%s UMIP:%s OSFXSR:%s OSXMMEXCPT:%s LA57:%s VMXE:%s SMXE:%s PCIDE:%s OSXSAVE:%s SMEP:%s SMAP:%s PKE:%s R0:%#x R1:%#x", cr4.VME ? "True " : "False", cr4.PVI ? "True " : "False", cr4.TSD ? "True " : "False", cr4.DE ? "True " : "False", cr4.PSE ? "True " : "False", cr4.PAE ? "True " : "False", cr4.MCE ? "True " : "False", cr4.PGE ? "True " : "False", cr4.PCE ? "True " : "False", cr4.UMIP ? "True " : "False", cr4.OSFXSR ? "True " : "False", cr4.OSXMMEXCPT ? "True " : "False", @@ -130,7 +133,9 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame) cr4.Reserved0, cr4.Reserved1); #endif +#if defined(a64) || defined(a32) error("CR8: TPL:%d", cr8.TPL); +#endif // defined(a64) || defined(a32) #if defined(a64) 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", @@ -151,10 +156,12 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame) #elif defined(aa64) #endif +#if defined(a64) || defined(a32) 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", efer.SVME ? "True " : "False", efer.LMSLE ? "True " : "False", efer.FFXSR ? "True " : "False", efer.TCE ? "True " : "False", efer.Reserved0, efer.Reserved1, efer.Reserved2); +#endif // a64 || a32 } switch (Frame->InterruptNumber) diff --git a/Core/Crash/chfcts.hpp b/Core/Crash/chfcts.hpp index e31e9a9..41a7a70 100644 --- a/Core/Crash/chfcts.hpp +++ b/Core/Crash/chfcts.hpp @@ -68,6 +68,15 @@ struct CRData }; #elif defined(aa64) typedef struct CPU::aarch64::TrapFrame CHArchTrapFrame; + +struct CRData +{ + CHArchTrapFrame *Frame; + + long ID; + Tasking::PCB *Process; + Tasking::TCB *Thread; +}; #endif enum Keys @@ -266,7 +275,7 @@ namespace CrashHandler #elif defined(a32) void OnInterruptReceived(CPU::x32::TrapFrame *Frame); #elif defined(aa64) - void OnInterruptReceived(void *Frame); + void OnInterruptReceived(CPU::aarch64::TrapFrame *Frame); #endif public: CrashKeyboardDriver(); diff --git a/Core/Driver/Driver.cpp b/Core/Driver/Driver.cpp index 84171de..24565b0 100644 --- a/Core/Driver/Driver.cpp +++ b/Core/Driver/Driver.cpp @@ -267,7 +267,7 @@ namespace Driver #elif defined(a32) SafeFunction void DriverInterruptHook::OnInterruptReceived(CPU::x32::TrapFrame *Frame) #elif defined(aa64) - SafeFunction void DriverInterruptHook::OnInterruptReceived(void *Frame) + SafeFunction void DriverInterruptHook::OnInterruptReceived(CPU::aarch64::TrapFrame *Frame) #endif { SmartLock(DriverInterruptLock); /* Lock in case of multiple interrupts firing at the same time */ @@ -335,7 +335,7 @@ namespace Driver #if defined(a64) || defined(a32) trace("Interrupt %d hooked to driver %ld", Interrupt, Handle.DriverUID); #elif defined(aa64) - trace("Interrupt %d hooked to driver %ld", Interrupt, Handle->DriverUID); + trace("Interrupt %d hooked to driver %ld", Interrupt, Handle.DriverUID); #endif } } diff --git a/Core/InterruptsManager.cpp b/Core/InterruptsManager.cpp index 757c88e..3e64817 100644 --- a/Core/InterruptsManager.cpp +++ b/Core/InterruptsManager.cpp @@ -184,7 +184,7 @@ namespace Interrupts #elif defined(a32) void *Frame = Data; #elif defined(aa64) - void *Frame = Data; + CPU::aarch64::TrapFrame *Frame = (CPU::aarch64::TrapFrame *)Data; #endif error("HALT HALT HALT HALT HALT HALT HALT HALT HALT"); CPU::Stop(); @@ -228,7 +228,7 @@ namespace Interrupts { trace("Unhandled interrupt received"); #elif defined(aa64) - void Handler::OnInterruptReceived(void *Frame) + void Handler::OnInterruptReceived(CPU::aarch64::TrapFrame *Frame) { trace("Unhandled interrupt received"); #endif diff --git a/Core/Random.cpp b/Core/Random.cpp index ae2c5d5..5d2ec7d 100644 --- a/Core/Random.cpp +++ b/Core/Random.cpp @@ -36,8 +36,8 @@ namespace Random asmv("cpuid" : "=a"(cpuid1amd.EAX.raw), "=b"(cpuid1amd.EBX.raw), "=c"(cpuid1amd.ECX.raw), "=d"(cpuid1amd.EDX.raw) : "a"(0x1)); -#endif RDRANDFlag = cpuid1amd.ECX.RDRAND; +#endif // a64 || a32 } else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { @@ -50,8 +50,8 @@ namespace Random asmv("cpuid" : "=a"(cpuid1intel.EAX.raw), "=b"(cpuid1intel.EBX.raw), "=c"(cpuid1intel.ECX.raw), "=d"(cpuid1intel.EDX.raw) : "a"(0x1)); -#endif RDRANDFlag = cpuid1intel.ECX.RDRAND; +#endif // a64 || a32 } if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) @@ -85,8 +85,8 @@ namespace Random asmv("cpuid" : "=a"(cpuid1amd.EAX.raw), "=b"(cpuid1amd.EBX.raw), "=c"(cpuid1amd.ECX.raw), "=d"(cpuid1amd.EDX.raw) : "a"(0x1)); -#endif RDRANDFlag = cpuid1amd.ECX.RDRAND; +#endif // a64 || a32 } else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { @@ -99,8 +99,8 @@ namespace Random asmv("cpuid" : "=a"(cpuid1intel.EAX.raw), "=b"(cpuid1intel.EBX.raw), "=c"(cpuid1intel.ECX.raw), "=d"(cpuid1intel.EDX.raw) : "a"(0x1)); -#endif RDRANDFlag = cpuid1intel.ECX.RDRAND; +#endif // a64 || a32 } if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) @@ -134,8 +134,8 @@ namespace Random asmv("cpuid" : "=a"(cpuid1amd.EAX.raw), "=b"(cpuid1amd.EBX.raw), "=c"(cpuid1amd.ECX.raw), "=d"(cpuid1amd.EDX.raw) : "a"(0x1)); -#endif RDRANDFlag = cpuid1amd.ECX.RDRAND; +#endif // a64 || a32 } else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { @@ -148,8 +148,8 @@ namespace Random asmv("cpuid" : "=a"(cpuid1intel.EAX.raw), "=b"(cpuid1intel.EBX.raw), "=c"(cpuid1intel.ECX.raw), "=d"(cpuid1intel.EDX.raw) : "a"(0x1)); -#endif RDRANDFlag = cpuid1intel.ECX.RDRAND; +#endif // a64 || a32 } if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) diff --git a/DAPI.hpp b/DAPI.hpp index 23557fb..8a0a573 100644 --- a/DAPI.hpp +++ b/DAPI.hpp @@ -421,7 +421,7 @@ union CPURegisters unsigned int esp; unsigned int ss; #else -#error "Unsupported architecture" +#warning "Unsupported architecture" #endif }; unsigned long raw; diff --git a/KThread.cpp b/KThread.cpp index f4d270b..02faf0f 100644 --- a/KThread.cpp +++ b/KThread.cpp @@ -125,7 +125,13 @@ void TaskMgr() Statuses[Status], Thd->Name, StatusesSign[Status]); } } +#if defined(a64) register uintptr_t CurrentStackAddress asm("rsp"); +#elif defined(a32) + register uintptr_t CurrentStackAddress asm("esp"); +#elif defined(aa64) + register uintptr_t CurrentStackAddress asm("sp"); +#endif printf("Sanity: %d, Stack: %#lx", sanity++, CurrentStackAddress); if (sanity > 1000) sanity = 0; diff --git a/Library/Convert.cpp b/Library/Convert.cpp index 6ea9845..3acf34e 100644 --- a/Library/Convert.cpp +++ b/Library/Convert.cpp @@ -752,7 +752,7 @@ __noreturn __always_inline static inline void __convert_chk_fail(void) #if defined(a64) || defined(a32) asmv("int3"); #else -#error "Not implemented!" +#warning "Not implemented!" #endif __builtin_unreachable(); } diff --git a/Makefile b/Makefile index 4cc2b3f..6fef8cf 100644 --- a/Makefile +++ b/Makefile @@ -111,7 +111,10 @@ ifeq ($(DEBUG), 1) # CFLAGS += --coverage # CFLAGS += -pg # CFLAGS += -finstrument-functions - CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm -fstack-usage -fstack-check -fsanitize=undefined + CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm -fstack-usage -fsanitize=undefined +ifneq ($(OSARCH), aarch64) + CFLAGS += -fstack-check +endif LDFLAGS += -ggdb3 -O0 NASMFLAGS += -F dwarf -g WARNCFLAG += -Wno-unused-function -Wno-maybe-uninitialized -Wno-builtin-declaration-mismatch -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-variable @@ -155,6 +158,9 @@ $(KERNEL_FILENAME): $(OBJ) $(RUSTC) $< -C panic=abort -C soft-float --emit=obj -o $@ %.o: %.asm +ifeq ($(OSARCH), aarch64) + $(error aarch64 does not support NASM) +endif $(info Compiling $<) $(NASM) $< $(NASMFLAGS) -o $@ diff --git a/Profiling/cyg.cpp b/Profiling/cyg.cpp index bcdf733..5c50318 100644 --- a/Profiling/cyg.cpp +++ b/Profiling/cyg.cpp @@ -43,7 +43,11 @@ EXTERNC SafeFunction NIF void __cyg_profile_func_enter(void *Function, void *Cal return; while (Wait) +#if defined(a64) || defined(a32) asmv("pause"); +#elif defined(aa64) + asmv("yield"); +#endif Wait = true; if (Level > 40) @@ -76,7 +80,11 @@ EXTERNC SafeFunction NIF void __cyg_profile_func_exit(void *Function, void *Call return; while (Wait) +#if defined(a64) || defined(a32) asmv("pause"); +#elif defined(aa64) + asmv("yield"); +#endif Wait = true; if (Level > 40) diff --git a/SystemCalls/Linux.cpp b/SystemCalls/Linux.cpp index 0def10b..9cf71ce 100644 --- a/SystemCalls/Linux.cpp +++ b/SystemCalls/Linux.cpp @@ -2451,6 +2451,8 @@ uintptr_t HandleLinuxSyscalls(SyscallsFrame *Frame) Frame->rax = ret; return ret; #elif defined(a32) + return 0; #elif defined(aa64) + return 0; #endif } diff --git a/Tasking/Scheduler.cpp b/Tasking/Scheduler.cpp index edcc0e0..cb8803c 100644 --- a/Tasking/Scheduler.cpp +++ b/Tasking/Scheduler.cpp @@ -726,11 +726,11 @@ namespace Tasking fixme("unimplemented"); } - SafeFunction void Task::Schedule(void *Frame) + SafeFunction void Task::Schedule(CPU::aarch64::TrapFrame *Frame) { fixme("unimplemented"); } - SafeFunction void Task::OnInterruptReceived(void *Frame) { this->Schedule(Frame); } + SafeFunction void Task::OnInterruptReceived(CPU::aarch64::TrapFrame *Frame) { this->Schedule(Frame); } #endif } diff --git a/Tasking/Task.cpp b/Tasking/Task.cpp index 193c6e5..2468bd8 100644 --- a/Tasking/Task.cpp +++ b/Tasking/Task.cpp @@ -58,13 +58,15 @@ namespace Tasking // ((APIC::APIC *)Interrupts::apic[0])->IPI(GetCurrentCPU()->ID, icr); } +#if defined(a64) || defined(a32) __naked __used __no_stack_protector NIF void IdleProcessLoop() { -#if defined(a64) || defined(a32) asmv("IdleLoop:\n" "hlt\n" "jmp IdleLoop\n"); #elif defined(aa64) + __used __no_stack_protector NIF void IdleProcessLoop() + { asmv("IdleLoop:\n" "wfe\n" "b IdleLoop\n"); @@ -291,7 +293,11 @@ namespace Tasking // TaskingScheduler_OneShot(1); // IRQ16 TaskingLock.Unlock(); +#if defined(a64) || defined(a32) asmv("int $0x30"); /* This will trigger the IRQ16 instantly so we won't execute the next instruction */ +#elif defined(aa64) + asmv("svc #0x30"); /* This will trigger the IRQ16 instantly so we won't execute the next instruction */ +#endif } void Task::SignalShutdown() @@ -786,7 +792,7 @@ namespace Tasking #elif defined(a32) TaskArchitecture Arch = TaskArchitecture::x32; #elif defined(aa64) - TaskArchitecture Arch = TaskArchitecture::ARM64; + TaskArchitecture Arch = TaskArchitecture::ARM64; #endif PCB *kproc = CreateProcess(nullptr, "Kernel", TaskTrustLevel::Kernel); TCB *kthrd = CreateThread(kproc, EntryPoint, nullptr, nullptr, std::vector(), 0, Arch); @@ -806,8 +812,8 @@ namespace Tasking asmv("cpuid" : "=a"(cpuid1amd.EAX.raw), "=b"(cpuid1amd.EBX.raw), "=c"(cpuid1amd.ECX.raw), "=d"(cpuid1amd.EDX.raw) : "a"(0x1)); -#endif MONITORSupported = cpuid1amd.ECX.MONITOR; +#endif } else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { @@ -820,8 +826,8 @@ namespace Tasking asmv("cpuid" : "=a"(cpuid1intel.EAX.raw), "=b"(cpuid1intel.EBX.raw), "=c"(cpuid1intel.ECX.raw), "=d"(cpuid1intel.EDX.raw) : "a"(0x1)); -#endif MONITORSupported = cpuid1intel.ECX.MONITOR; +#endif } if (MONITORSupported) diff --git a/Tests/RandomNumberGenerator.cpp b/Tests/RandomNumberGenerator.cpp index fd4a790..11ed9f5 100644 --- a/Tests/RandomNumberGenerator.cpp +++ b/Tests/RandomNumberGenerator.cpp @@ -35,8 +35,8 @@ __constructor void TestRandom() asmv("cpuid" : "=a"(cpuid1amd.EAX.raw), "=b"(cpuid1amd.EBX.raw), "=c"(cpuid1amd.ECX.raw), "=d"(cpuid1amd.EDX.raw) : "a"(0x1)); -#endif RDRANDFlag = cpuid1amd.ECX.RDRAND; +#endif } else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { @@ -49,8 +49,8 @@ __constructor void TestRandom() asmv("cpuid" : "=a"(cpuid1intel.EAX.raw), "=b"(cpuid1intel.EBX.raw), "=c"(cpuid1intel.ECX.raw), "=d"(cpuid1intel.EDX.raw) : "a"(0x1)); -#endif RDRANDFlag = cpuid1intel.ECX.RDRAND; +#endif } if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) diff --git a/include/abi.h b/include/abi.h index 036b29d..1bfb9ab 100644 --- a/include/abi.h +++ b/include/abi.h @@ -84,6 +84,7 @@ typedef struct #elif defined(a32) Elf32_auxv_t archaux; #elif defined(aa64) + Elf64_auxv_t archaux; #endif } AuxiliaryVector; diff --git a/include/cpu.hpp b/include/cpu.hpp index a9fe13a..b2daaa1 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -156,16 +156,20 @@ namespace CPU /** * @brief Stop the CPU (infinite loop) */ +#if defined(a64) || defined(a32) SafeFunction __noreturn __naked __used inline void Stop() { -#if defined(a64) || defined(a32) asmv("CPUStopLoop:\n" "cli\n" "hlt\n" "jmp CPUStopLoop"); -#elif defined(aa64) - asmv("msr daifset, #2"); - asmv("wfe"); +#elif defined(aa64) // annoying warning: "‘noreturn’ function does return" and "‘naked’ attribute directive ignored" + SafeFunction __used inline void Stop() + { + asmv("CPUStopLoop:\n" + "msr daifset, #2\n" // Disable IRQs (bit 1 of the DAIF register) + "wfi\n" // Wait for Interrupt (puts the processor in low-power state until an interrupt occurs) + "b CPUStopLoop"); // Branch to the beginning of the loop #endif } @@ -772,6 +776,29 @@ namespace CPU namespace aarch64 { + typedef struct TrapFrame + { + uint64_t x19; // General purpose + uint64_t x20; // General purpose + uint64_t x21; // General purpose + uint64_t x22; // General purpose + uint64_t x23; // General purpose + uint64_t x24; // General purpose + uint64_t x25; // General purpose + uint64_t x26; // General purpose + + uint64_t x27; // Stack frame pointer + uint64_t x28; // Link register + uint64_t x29; // Frame pointer + uint64_t x30; // Program counter + + uint64_t sp_el0; // Stack pointer + uint64_t elr_el1; // Exception Link Register + uint64_t spsr_el1; // Saved Program Status Register + uint64_t ErrorCode /* esr_el1 */; // Exception Syndrome Register + + uint64_t InterruptNumber /* iar_el1 */; // Interrupt Acknowledge Register + } TrapFrame; } } diff --git a/include/driver.hpp b/include/driver.hpp index 7180bd6..31c8f65 100644 --- a/include/driver.hpp +++ b/include/driver.hpp @@ -65,7 +65,7 @@ namespace Driver #elif defined(a32) void OnInterruptReceived(CPU::x32::TrapFrame *Frame); #elif defined(aa64) - void OnInterruptReceived(void *Frame); + void OnInterruptReceived(CPU::aarch64::TrapFrame *Frame); #endif public: diff --git a/include/intrin.hpp b/include/intrin.hpp index 387e06b..39b30fb 100644 --- a/include/intrin.hpp +++ b/include/intrin.hpp @@ -21,6 +21,7 @@ #include #include +#if defined(a64) || defined(a32) #define MMX_FN_ATTR __always_inline __target("mmx") #define SSE_FN_ATTR __always_inline __target("sse") #define SSE2_FN_ATTR __always_inline __target("sse2") @@ -30,6 +31,18 @@ #define SSE4_2_FN_ATTR __always_inline __target("sse4.2") #define AVX_FN_ATTR __always_inline __target("avx") #define AVX2_FN_ATTR __always_inline __target("avx2") +#elif defined(aa64) +#define MMX_FN_ATTR __always_inline +#define SSE_FN_ATTR __always_inline +#define SSE2_FN_ATTR __always_inline +#define SSE3_FN_ATTR __always_inline +#define SSSE3_FN_ATTR __always_inline +#define SSE4_1_FN_ATTR __always_inline +#define SSE4_2_FN_ATTR __always_inline +#define AVX_FN_ATTR __always_inline +#define AVX2_FN_ATTR __always_inline +#endif + #define ST_IN static inline namespace FXSR @@ -73,19 +86,24 @@ namespace SMAP { void _clac(void) { +#if defined(a64) || defined(a32) asmv("clac" :: : "cc"); +#endif // a64 || a32 } void _stac(void) { +#if defined(a64) || defined(a32) asmv("stac" :: : "cc"); +#endif // a64 || a32 } } namespace MMX { +#if defined(a64) || defined(a32) typedef long long __m64 __attribute__((__vector_size__(8), __aligned__(8))); typedef long long __v1di __attribute__((__vector_size__(8))); @@ -97,10 +115,12 @@ namespace MMX { __builtin_ia32_emms(); } +#endif // a64 || a32 } namespace SSE { +#if defined(a64) || defined(a32) typedef int __v4si __attribute__((__vector_size__(16))); typedef unsigned int __v4su __attribute__((__vector_size__(16))); typedef float __v4sf __attribute__((__vector_size__(16))); @@ -119,10 +139,12 @@ namespace SSE { return (__m128)((__v4sf)a + (__v4sf)b); } +#endif // a64 || a32 } namespace SSE2 { +#if defined(a64) || defined(a32) typedef double __v2df __attribute__((__vector_size__(16))); typedef long long __v2di __attribute__((__vector_size__(16))); @@ -178,41 +200,49 @@ namespace SSE2 : "=m"(*mem_addr) : "x"(a)); } +#endif // a64 || a32 } namespace SSE3 { - +#if defined(a64) || defined(a32) +#endif // a64 || a32 } namespace SSSE3 { - +#if defined(a64) || defined(a32) +#endif // a64 || a32 } namespace SSE4_1 { +#if defined(a64) || defined(a32) typedef long long __m128i __attribute__((__vector_size__(16), __aligned__(16))); ST_IN SSE4_1_FN_ATTR __m128i _mm_cvtepu8_epi32(__m128i a); ST_IN SSE4_1_FN_ATTR __m128i _mm_mullo_epi32(__m128i a, __m128i b); ST_IN SSE4_1_FN_ATTR __m128i _mm_srli_epi32(__m128i a, int imm8); ST_IN SSE4_1_FN_ATTR int _mm_cvtsi128_si32(__m128i a); +#endif // a64 || a32 } namespace SSE4_2 { - +#if defined(a64) || defined(a32) +#endif // a64 || a32 } namespace AVX { - +#if defined(a64) || defined(a32) +#endif // a64 || a32 } namespace AVX2 { - +#if defined(a64) || defined(a32) +#endif // a64 || a32 } #endif // !__FENNIX_KERNEL_SIMD_H__ diff --git a/include/ints.hpp b/include/ints.hpp index a8ec3de..99affe5 100644 --- a/include/ints.hpp +++ b/include/ints.hpp @@ -70,7 +70,7 @@ namespace Interrupts #elif defined(a32) virtual void OnInterruptReceived(CPU::x32::TrapFrame *Frame); #elif defined(aa64) - virtual void OnInterruptReceived(void *Frame); + virtual void OnInterruptReceived(CPU::aarch64::TrapFrame *Frame); #endif }; } diff --git a/include/task.hpp b/include/task.hpp index 73aa47f..96df5e6 100644 --- a/include/task.hpp +++ b/include/task.hpp @@ -274,8 +274,8 @@ namespace Tasking void Schedule(void *Frame); void OnInterruptReceived(CPU::x32::TrapFrame *Frame); #elif defined(aa64) - void Schedule(void *Frame); - void OnInterruptReceived(void *Frame); + void Schedule(CPU::aarch64::TrapFrame *Frame); + void OnInterruptReceived(CPU::aarch64::TrapFrame *Frame); #endif public: