Enable compilation of project on AArch64 architecture

This commit is contained in:
Alex 2023-04-04 16:06:54 +03:00
parent c4ae288ef1
commit 4e20d4d9f4
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
28 changed files with 242 additions and 50 deletions

View File

@ -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",

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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:

View File

@ -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.
}
}

View File

@ -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

View File

@ -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)
{

View File

@ -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

View File

@ -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)

View File

@ -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();

View File

@ -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
}
}

View File

@ -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

View File

@ -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)

View File

@ -421,7 +421,7 @@ union CPURegisters
unsigned int esp;
unsigned int ss;
#else
#error "Unsupported architecture"
#warning "Unsupported architecture"
#endif
};
unsigned long raw;

View File

@ -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;

View File

@ -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();
}

View File

@ -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 $@

View File

@ -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)

View File

@ -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
}

View File

@ -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
}

View File

@ -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<AuxiliaryVector>(), 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)

View File

@ -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)

View File

@ -84,6 +84,7 @@ typedef struct
#elif defined(a32)
Elf32_auxv_t archaux;
#elif defined(aa64)
Elf64_auxv_t archaux;
#endif
} AuxiliaryVector;

View File

@ -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;
}
}

View File

@ -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:

View File

@ -21,6 +21,7 @@
#include <types.h>
#include <debug.h>
#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__

View File

@ -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
};
}

View File

@ -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: