diff --git a/Drivers/include/fs.h b/Drivers/include/fs.h
index 27718cd7..23e19f14 100644
--- a/Drivers/include/fs.h
+++ b/Drivers/include/fs.h
@@ -146,10 +146,10 @@ static_assert(sizeof(blkcnt_t) == 8, "blkcnt_t must be 64 bits");
#else
static_assert(sizeof(dev_t) == 4, "dev_t must be 32 bits");
static_assert(sizeof(ino_t) == 4, "ino_t must be 32 bits");
-static_assert(sizeof(mode_t) == 2, "mode_t must be 16 bits");
-static_assert(sizeof(nlink_t) == 2, "nlink_t must be 16 bits");
-static_assert(sizeof(uid_t) == 2, "uid_t must be 16 bits");
-static_assert(sizeof(gid_t) == 2, "gid_t must be 16 bits");
+static_assert(sizeof(mode_t) == 4, "mode_t must be 32 bits");
+static_assert(sizeof(nlink_t) == 4, "nlink_t must be 32 bits");
+static_assert(sizeof(uid_t) == 4, "uid_t must be 32 bits");
+static_assert(sizeof(gid_t) == 4, "gid_t must be 32 bits");
static_assert(sizeof(off_t) == 4, "off_t must be 32 bits");
static_assert(sizeof(time_t) == 4, "time_t must be 32 bits");
static_assert(sizeof(blksize_t) == 4, "blksize_t must be 32 bits");
diff --git a/Drivers/include/io.h b/Drivers/include/io.h
index cb1d9d98..4e0e3374 100644
--- a/Drivers/include/io.h
+++ b/Drivers/include/io.h
@@ -75,7 +75,7 @@ extern "C"
: "dN"(Port), "a"(Data));
}
- static inline uint8_t mmioin8(uint64_t Address)
+ static inline uint8_t mmioin8(uintptr_t Address)
{
__asm__ volatile("" ::
: "memory");
@@ -85,7 +85,7 @@ extern "C"
return Result;
}
- static inline uint16_t mmioin16(uint64_t Address)
+ static inline uint16_t mmioin16(uintptr_t Address)
{
__asm__ volatile("" ::
: "memory");
@@ -95,7 +95,7 @@ extern "C"
return Result;
}
- static inline uint32_t mmioin32(uint64_t Address)
+ static inline uint32_t mmioin32(uintptr_t Address)
{
__asm__ volatile("" ::
: "memory");
@@ -105,17 +105,17 @@ extern "C"
return Result;
}
- static inline uint64_t mmioin64(uint64_t Address)
+ static inline uintptr_t mmioin64(uintptr_t Address)
{
__asm__ volatile("" ::
: "memory");
- uint64_t Result = *(volatile uint64_t *)Address;
+ uintptr_t Result = *(volatile uintptr_t *)Address;
__asm__ volatile("" ::
: "memory");
return Result;
}
- static inline void mmioout8(uint64_t Address, uint8_t Data)
+ static inline void mmioout8(uintptr_t Address, uint8_t Data)
{
__asm__ volatile("" ::
: "memory");
@@ -124,7 +124,7 @@ extern "C"
: "memory");
}
- static inline void mmioout16(uint64_t Address, uint16_t Data)
+ static inline void mmioout16(uintptr_t Address, uint16_t Data)
{
__asm__ volatile("" ::
: "memory");
@@ -133,7 +133,7 @@ extern "C"
: "memory");
}
- static inline void mmioout32(uint64_t Address, uint32_t Data)
+ static inline void mmioout32(uintptr_t Address, uint32_t Data)
{
__asm__ volatile("" ::
: "memory");
@@ -142,11 +142,11 @@ extern "C"
: "memory");
}
- static inline void mmioout64(uint64_t Address, uint64_t Data)
+ static inline void mmioout64(uintptr_t Address, uintptr_t Data)
{
__asm__ volatile("" ::
: "memory");
- *(volatile uint64_t *)Address = Data;
+ *(volatile uintptr_t *)Address = Data;
__asm__ volatile("" ::
: "memory");
}
@@ -175,10 +175,10 @@ extern "C"
: "memory");
}
- static inline void mmoutq(void *Address, uint64_t Value)
+ static inline void mmoutq(void *Address, uintptr_t Value)
{
__asm__ volatile("mov %1, %0"
- : "=m"((*(uint64_t *)(Address)))
+ : "=m"((*(uintptr_t *)(Address)))
: "r"(Value)
: "memory");
}
@@ -213,12 +213,12 @@ extern "C"
return Result;
}
- static inline uint64_t mminq(void *Address)
+ static inline uintptr_t mminq(void *Address)
{
- uint64_t Result;
+ uintptr_t Result;
__asm__ volatile("mov %1, %0"
: "=r"(Result)
- : "m"((*(uint64_t *)(Address)))
+ : "m"((*(uintptr_t *)(Address)))
: "memory");
return Result;
}
diff --git a/Drivers/include/syscalls.h b/Drivers/include/syscalls.h
index bde19d03..d0cab647 100644
--- a/Drivers/include/syscalls.h
+++ b/Drivers/include/syscalls.h
@@ -33,10 +33,16 @@
static inline scarg syscall0(scarg syscall)
{
scarg ret;
+#if defined(__amd64__)
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -52,10 +58,16 @@ static inline scarg syscall0(scarg syscall)
static inline scarg syscall1(scarg syscall, scarg arg1)
{
scarg ret;
+#if defined(__amd64__)
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -72,10 +84,16 @@ static inline scarg syscall1(scarg syscall, scarg arg1)
static inline scarg syscall2(scarg syscall, scarg arg1, scarg arg2)
{
scarg ret;
+#if defined(__amd64__)
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -93,10 +111,16 @@ static inline scarg syscall2(scarg syscall, scarg arg1, scarg arg2)
static inline scarg syscall3(scarg syscall, scarg arg1, scarg arg2, scarg arg3)
{
scarg ret;
+#if defined(__amd64__)
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -115,11 +139,17 @@ static inline scarg syscall3(scarg syscall, scarg arg1, scarg arg2, scarg arg3)
static inline scarg syscall4(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4)
{
scarg ret;
+#if defined(__amd64__)
register scarg r10 __asm__("r10") = arg4;
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -139,12 +169,18 @@ static inline scarg syscall4(scarg syscall, scarg arg1, scarg arg2, scarg arg3,
static inline scarg syscall5(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4, scarg arg5)
{
scarg ret;
+#if defined(__amd64__)
register scarg r10 __asm__("r10") = arg4;
register scarg r8 __asm__("r8") = arg5;
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -165,6 +201,7 @@ static inline scarg syscall5(scarg syscall, scarg arg1, scarg arg2, scarg arg3,
static inline scarg syscall6(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4, scarg arg5, scarg arg6)
{
scarg ret;
+#if defined(__amd64__)
register scarg r10 __asm__("r10") = arg4;
register scarg r8 __asm__("r8") = arg5;
register scarg r9 __asm__("r9") = arg6;
@@ -172,6 +209,11 @@ static inline scarg syscall6(scarg syscall, scarg arg1, scarg arg2, scarg arg3,
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8), "r"(r9)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
diff --git a/Drivers/include/types.h b/Drivers/include/types.h
index 03fee4a2..e4547dbb 100644
--- a/Drivers/include/types.h
+++ b/Drivers/include/types.h
@@ -71,7 +71,7 @@ typedef uint32_t uid_t;
typedef uint32_t gid_t;
typedef int64_t clock_t;
typedef int32_t pid_t;
-#elif defined(__LP32__)
+#else
typedef int32_t off_t;
typedef long long off64_t;
typedef __INT32_TYPE__ mode_t;
diff --git a/Drivers/misc/vmware/main.c b/Drivers/misc/vmware/main.c
index d4ea5f64..4519c7cf 100644
--- a/Drivers/misc/vmware/main.c
+++ b/Drivers/misc/vmware/main.c
@@ -107,6 +107,8 @@ typedef struct
#define MESSAGE_RECV_PAYLOAD ToMsg(MSG_RECVPAYLOAD)
#define MESSAGE_RECV_STATUS ToMsg(MSG_RECVSTATUS)
+#if defined(__amd64__)
+
#define VM_PORT(cmd, in_ebx, isi, idi, \
flags, magic, \
ax, bx, cx, dx, si, di) \
@@ -169,6 +171,23 @@ typedef struct
"D"(idi), \
"r"(bp) : "memory", "cc")
+#elif defined(__i386__)
+
+#define VM_PORT(cmd, in_ebx, isi, idi, \
+ flags, magic, \
+ ax, bx, cx, dx, si, di)
+
+#define VM_PORT_HB_OUT(cmd, in_ecx, isi, idi, \
+ flags, \
+ magic, bp, ax, \
+ bx, cx, dx, si, di)
+
+#define VM_PORT_HB_IN(cmd, in_ecx, isi, idi, \
+ flags, magic, bp, \
+ ax, bx, cx, dx, si, di)
+
+#endif
+
/* TODO:
- use vmcall or vmmcall instead of "out" and "in" if available
*/
diff --git a/Kernel/Makefile b/Kernel/Makefile
index 2f3455bf..32e26276 100644
--- a/Kernel/Makefile
+++ b/Kernel/Makefile
@@ -32,7 +32,7 @@ WARNCFLAG = -Wall -Wextra \
-Wfloat-equal -Wpointer-arith -Wcast-align \
-Wredundant-decls -Winit-self -Wswitch-default \
-Wstrict-overflow=5 -Wno-error=cpp -Werror \
- -Wno-unused-parameter
+ -Wno-unused-parameter -Wno-error=format
CFLAG_STACK_PROTECTOR := -fstack-protector-all
diff --git a/Kernel/arch/aarch64/core/panic/ui.cpp b/Kernel/arch/aarch64/core/panic/ui.cpp
new file mode 100644
index 00000000..eeae5743
--- /dev/null
+++ b/Kernel/arch/aarch64/core/panic/ui.cpp
@@ -0,0 +1,46 @@
+/*
+ This file is part of Fennix Kernel.
+
+ Fennix Kernel is free software: you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ Fennix Kernel is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fennix Kernel. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#if defined(__amd64__)
+#include "../../arch/amd64/cpu/gdt.hpp"
+#include "../arch/amd64/cpu/apic.hpp"
+#elif defined(__i386__)
+#include "../../arch/i386/cpu/gdt.hpp"
+#include "../arch/i386/cpu/apic.hpp"
+#elif defined(__aarch64__)
+#endif
+
+#include "../../../../kernel.h"
+
+extern void ExPrint(const char *Format, ...);
+
+arch nsa void DisplayDetailsScreen(CPU::ExceptionFrame *Frame)
+{
+ ExPrint("\nException Frame:\n");
+}
diff --git a/Kernel/arch/amd64/core/panic/ui.cpp b/Kernel/arch/amd64/core/panic/ui.cpp
new file mode 100644
index 00000000..1c3895d2
--- /dev/null
+++ b/Kernel/arch/amd64/core/panic/ui.cpp
@@ -0,0 +1,134 @@
+/*
+ This file is part of Fennix Kernel.
+
+ Fennix Kernel is free software: you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ Fennix Kernel is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fennix Kernel. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "../../cpu/gdt.hpp"
+#include "../../cpu/apic.hpp"
+#include "../../../../kernel.h"
+
+extern void ExPrint(const char *Format, ...);
+
+static const char *x86PageFaultDescriptions[9] = {
+ "Supervisor tried to read a non-present page entry\n",
+ "Supervisor tried to read a page and caused a protection fault\n",
+ "Supervisor tried to write to a non-present page entry\n",
+ "Supervisor tried to write a page and caused a protection fault\n",
+ "User tried to read a non-present page entry\n",
+ "User tried to read a page and caused a protection fault\n",
+ "User tried to write to a non-present page entry\n",
+ "User tried to write a page and caused a protection fault\n",
+ "One or more page directory entries contain reserved bits which are set to 1.\n"};
+
+arch nsa void DisplayDetailsScreen(CPU::ExceptionFrame *Frame)
+{
+ ExPrint("\nException Frame:\n");
+ ExPrint(" General Purpose Registers:\n");
+ ExPrint(" RAX: %#lx RBX: %#lx RCX: %#lx RDX: %#lx\n",
+ Frame->rax, Frame->rbx, Frame->rcx, Frame->rdx);
+ ExPrint(" RSI: %#lx RDI: %#lx R8: %#lx R9: %#lx\n",
+ Frame->rsi, Frame->rdi, Frame->r8, Frame->r9);
+ ExPrint(" R10: %#lx R11: %#lx R12: %#lx R13: %#lx\n",
+ Frame->r10, Frame->r11, Frame->r12, Frame->r13);
+ ExPrint(" R14: %#lx R15: %#lx\n", Frame->r14, Frame->r15);
+
+ ExPrint(" Control Registers:\n");
+ ExPrint(" CR0: %#lx CR2: %#lx CR3: %#lx CR4: %#lx\n",
+ Frame->cr0, Frame->cr2, Frame->cr3, Frame->cr4);
+ ExPrint(" CR8: %#lx\n", Frame->cr8);
+
+ ExPrint(" Segment Registers:\n");
+ ExPrint(" CS: %#lx SS: %#lx DS: %#lx ES: %#lx FS: %#lx GS: %#lx\n",
+ Frame->cs, Frame->ss, Frame->ds, Frame->es, Frame->fs, Frame->gs);
+
+ ExPrint(" Debug Registers:\n");
+ ExPrint(" DR0: %#lx DR1: %#lx DR2: %#lx DR3: %#lx\n",
+ Frame->dr0, Frame->dr1, Frame->dr2, Frame->dr3);
+ ExPrint(" DR6: %#lx DR7: %#lx\n", Frame->dr6, Frame->dr7);
+
+ ExPrint(" Other:\n");
+ ExPrint(" INT: %#lx ERR: %#lx RIP: %#lx RFLAGS: %#lx\n",
+ Frame->InterruptNumber, Frame->ErrorCode,
+ Frame->rip, Frame->rflags.raw);
+ ExPrint(" RSP: %#lx RBP: %#lx\n",
+ Frame->rsp, Frame->rbp);
+
+ ExPrint("Exception Details:\n");
+ switch (Frame->InterruptNumber)
+ {
+ case CPU::x86::PageFault:
+ {
+ CPU::x64::PageFaultErrorCode pfCode = {.raw = (uint32_t)Frame->ErrorCode};
+ ExPrint("PFEC: P:%d W:%d U:%d R:%d I:%d PK:%d SS:%d SGX:%d\n",
+ pfCode.P, pfCode.W, pfCode.U, pfCode.R,
+ pfCode.I, pfCode.PK, pfCode.SS, pfCode.SGX);
+
+ {
+ Memory::Virtual vmm((Memory::PageTable *)Frame->cr3);
+ if (vmm.GetMapType((void *)Frame->cr2) != Memory::Virtual::FourKiB)
+ ExPrint("Can't display page %#lx\n", Frame->cr2);
+ else
+ {
+ Memory::PageTableEntry *pte = vmm.GetPTE((void *)Frame->cr2);
+ ExPrint("Page %#lx: P:%d W:%d U:%d G:%d CoW:%d KRsv:%d NX:%d\n",
+ ALIGN_DOWN(Frame->cr2, 0x1000), pte->Present, pte->ReadWrite,
+ pte->UserSupervisor, pte->Global, pte->CopyOnWrite,
+ pte->KernelReserve, pte->ExecuteDisable);
+ }
+ }
+
+ ExPrint("%s", x86PageFaultDescriptions[Frame->ErrorCode & 0b111]);
+ if (Frame->ErrorCode & 0x8)
+ ExPrint("%s", x86PageFaultDescriptions[8]);
+ break;
+ }
+ case CPU::x86::StackSegmentFault:
+ case CPU::x86::GeneralProtectionFault:
+ {
+ CPU::x64::SelectorErrorCode sCode = {.raw = Frame->ErrorCode};
+ ExPrint("Kernel performed an illegal operation.\n");
+ ExPrint("External: %d\n", sCode.External);
+ ExPrint("Table: %d\n", sCode.Table);
+ ExPrint("Index: %#x\n", sCode.Idx);
+ break;
+ }
+ default:
+ ExPrint("No additional information available for this exception.\n");
+ break;
+ }
+
+ if (!TaskManager)
+ return;
+
+ CPUData *core = GetCurrentCPU();
+ Tasking::PCB *proc = core->CurrentProcess.load();
+ Tasking::TCB *thread = core->CurrentThread.load();
+ ExPrint("Exception in %s process %s(%d) thread %s(%d)\n",
+ proc->Security.ExecutionMode == Tasking::User ? "user" : "kernel",
+ proc->Name, proc->ID,
+ thread->Name, thread->ID);
+}
diff --git a/Kernel/arch/amd64/cpu/smp.cpp b/Kernel/arch/amd64/cpu/smp.cpp
index d4c765a4..428d66c2 100644
--- a/Kernel/arch/amd64/cpu/smp.cpp
+++ b/Kernel/arch/amd64/cpu/smp.cpp
@@ -61,7 +61,7 @@ nsa CPUData *GetCurrentCPU()
Memory::SwapPT(KernelPageTable, thisPageTable);
if (apic->x2APIC)
- CoreID = int(CPU::x64::rdmsr(CPU::x64::MSR_X2APIC_APICID));
+ CoreID = int(CPU::x86::rdmsr(CPU::x86::MSR_X2APIC_APICID));
else
CoreID = apic->Read(APIC::APIC_ID) >> 24;
}
@@ -151,7 +151,7 @@ namespace SMP
debug("Initializing CPU %d", lapic->APICId);
uint8_t APIC_ID = 0;
if (apic->x2APIC)
- APIC_ID = uint8_t(CPU::x64::rdmsr(CPU::x64::MSR_X2APIC_APICID));
+ APIC_ID = uint8_t(CPU::x86::rdmsr(CPU::x86::MSR_X2APIC_APICID));
else
APIC_ID = uint8_t(apic->Read(APIC::APIC_ID) >> 24);
diff --git a/Kernel/arch/amd64/memory/vmm.cpp b/Kernel/arch/amd64/memory/vmm.cpp
index c8d64158..b0113e53 100644
--- a/Kernel/arch/amd64/memory/vmm.cpp
+++ b/Kernel/arch/amd64/memory/vmm.cpp
@@ -22,7 +22,7 @@
namespace Memory
{
- bool Virtual::Check(void *VirtualAddress, PTFlag Flag)
+ bool Virtual::Check(void *VirtualAddress, PTFlag Flag, MapType Type)
{
uintptr_t Address = (uintptr_t)VirtualAddress;
Address &= 0xFFFFFFFFFFFFF000;
diff --git a/Kernel/arch/amd64/syscalls.cpp b/Kernel/arch/amd64/syscalls.cpp
index 4e750521..d2751d97 100644
--- a/Kernel/arch/amd64/syscalls.cpp
+++ b/Kernel/arch/amd64/syscalls.cpp
@@ -92,8 +92,8 @@ extern "C" __naked __used __no_stack_protector __aligned(16) void SystemCallHand
void InitializeSystemCalls()
{
- wrmsr(MSR_EFER, rdmsr(MSR_EFER) | 1);
- wrmsr(MSR_STAR, ((uint64_t)(GDT_KERNEL_CODE) << 32) | ((uint64_t)(GDT_KERNEL_DATA | 3) << 48));
- wrmsr(MSR_LSTAR, (uint64_t)SystemCallHandlerStub);
- wrmsr(MSR_SYSCALL_MASK, (uint64_t)(1 << 9));
+ CPU::x86::wrmsr(CPU::x86::MSR_EFER, CPU::x86::rdmsr(CPU::x86::MSR_EFER) | 1);
+ CPU::x86::wrmsr(CPU::x86::MSR_STAR, ((uint64_t)(GDT_KERNEL_CODE) << 32) | ((uint64_t)(GDT_KERNEL_DATA | 3) << 48));
+ CPU::x86::wrmsr(CPU::x86::MSR_LSTAR, (uint64_t)SystemCallHandlerStub);
+ CPU::x86::wrmsr(CPU::x86::MSR_SYSCALL_MASK, (uint64_t)(1 << 9));
}
diff --git a/Kernel/arch/amd64/tasking/signal.cpp b/Kernel/arch/amd64/tasking/signal.cpp
new file mode 100644
index 00000000..912fbd2a
--- /dev/null
+++ b/Kernel/arch/amd64/tasking/signal.cpp
@@ -0,0 +1,172 @@
+/*
+ This file is part of Fennix Kernel.
+
+ Fennix Kernel is free software: you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ Fennix Kernel is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fennix Kernel. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+
+#include "../cpu/gdt.hpp"
+
+/* subsystem/linux/syscall.cpp */
+extern int ConvertSignalToLinux(signal_t sig);
+
+namespace Tasking
+{
+ bool Signal::HandleSignal(CPU::SchedulerFrame *tf, void *thread)
+ {
+ /* We don't want to do this in kernel mode */
+ if (tf->cs != GDT_USER_CODE)
+ return false;
+
+ if (Queue.empty())
+ return false;
+
+ debug("We have %d signals to handle", Queue.size());
+
+ SmartLock(SignalLock);
+ SignalInfo sigI = GetAvailableSignal(thread);
+ if (sigI.sig == SIGNULL)
+ return false;
+
+ uintptr_t _p_rsp = ((PCB *)ctx)->PageTable->Get(tf->rsp);
+ uint64_t paRsp = _p_rsp;
+ paRsp &= ~0xF; /* Align */
+ paRsp -= 128; /* Red zone */
+
+ /* Calculate the virtual rsp */
+ uintptr_t _v_rsp = tf->rsp;
+ _v_rsp &= ~0xF; /* Align */
+ _v_rsp -= 128; /* Red zone */
+ uint64_t *vRsp = (uint64_t *)(_v_rsp - sizeof(StackInfo));
+ vRsp--; /* Alignment */
+ vRsp--; /* Handler Address */
+ assert(!((uintptr_t)vRsp & 0xF));
+
+ /* Add the stack info */
+ StackInfo si{};
+ CPU::x86::fxsave(&si.fx);
+ si.tf = *tf;
+ si.GSBase = CPU::x86::rdmsr(CPU::x86::MSR_GS_BASE);
+ si.FSBase = CPU::x86::rdmsr(CPU::x86::MSR_FS_BASE);
+ si.ShadowGSBase = CPU::x86::rdmsr(CPU::x86::MSR_SHADOW_GS_BASE);
+ si.SignalMask = ((TCB *)thread)->Signals.Mask.to_ulong();
+ si.Compatibility = ((PCB *)ctx)->Info.Compatibility;
+
+ debug("gs: %#lx fs: %#lx shadow: %#lx",
+ si.GSBase, si.FSBase, si.ShadowGSBase);
+
+ /* Copy the stack info */
+ uint64_t *pRsp = (uint64_t *)(paRsp - sizeof(StackInfo));
+ memcpy(pRsp, &si, sizeof(StackInfo));
+
+ /* Set the handler address */
+ pRsp--; /* Alignment */
+ pRsp--;
+ *pRsp = uint64_t(sa[sigI.sig].sa_handler.Handler);
+
+ assert(!((uintptr_t)pRsp & 0xF));
+
+ int cSig = LinuxSig() ? ConvertSignalToLinux((signal_t)sigI.sig) : sigI.sig;
+
+#ifdef DEBUG
+ DumpData("Stack Data", (void *)pRsp,
+ paRsp - uint64_t(pRsp));
+ debug("initial stack tf->rsp: %#lx after: %#lx",
+ tf->rsp, uint64_t(vRsp));
+ debug("sig: %d -> %d", sigI.sig, cSig);
+#endif
+
+ tf->rsp = uint64_t(vRsp);
+ tf->rip = uint64_t(TrampAddr);
+
+ /* void func(int signo); */
+ /* void func(int signo, siginfo_t *info, void *context); */
+ tf->rdi = cSig;
+ if (sa[sigI.sig].Flags & SA_SIGINFO)
+ {
+ fixme("SA_SIGINFO not implemented");
+ siginfo_t *info = 0;
+ void *context = 0;
+ tf->rsi = uint64_t(info);
+ tf->rdx = uint64_t(context);
+ tf->rcx = 0;
+ tf->r8 = 0;
+ tf->r9 = 0;
+ }
+ else
+ {
+ tf->rsi = 0;
+ tf->rdx = 0;
+ tf->rcx = 0;
+ tf->r8 = 0;
+ tf->r9 = 0;
+ }
+
+ ((TCB *)thread)->Signals.Mask = sa[sigI.sig].Mask;
+ assert(TrampAddr != nullptr);
+ return true;
+ }
+
+ void Signal::RestoreHandleSignal(SyscallsFrame *sf, void *thread)
+ {
+ debug("Restoring signal handler");
+ SmartLock(SignalLock);
+
+ gsTCB *gs = (gsTCB *)CPU::x86::rdmsr(CPU::x86::MSR_GS_BASE);
+ uint64_t *sp = (uint64_t *)((PCB *)ctx)->PageTable->Get(gs->TempStack);
+ sp++; /* Alignment */
+ sp++; /* Handler Address */
+
+ assert(!((uintptr_t)sp & 0xF));
+
+ StackInfo *si = (StackInfo *)sp;
+ assert(si != nullptr);
+
+ sf->r15 = si->tf.r15;
+ sf->r14 = si->tf.r14;
+ sf->r13 = si->tf.r13;
+ sf->r12 = si->tf.r12;
+ sf->r11 = si->tf.r11;
+ sf->r10 = si->tf.r10;
+ sf->r9 = si->tf.r9;
+ sf->r8 = si->tf.r8;
+ sf->bp = si->tf.rbp;
+ sf->di = si->tf.rdi;
+ sf->si = si->tf.rsi;
+ sf->dx = si->tf.rdx;
+ sf->cx = si->tf.rcx;
+ sf->bx = si->tf.rbx;
+ sf->ax = si->tf.rax;
+ sf->Flags = si->tf.rflags.raw;
+ sf->ReturnAddress = si->tf.rip;
+ gs->TempStack = (void *)si->tf.rsp;
+
+ ((TCB *)thread)->Signals.Mask = si->SignalMask;
+
+ CPU::x86::fxrstor(&si->fx);
+ CPU::x86::wrmsr(CPU::x86::MSR_GS_BASE, si->ShadowGSBase);
+ CPU::x86::wrmsr(CPU::x86::MSR_FS_BASE, si->FSBase);
+ CPU::x86::wrmsr(CPU::x86::MSR_SHADOW_GS_BASE, si->GSBase);
+ debug("gs: %#lx fs: %#lx shadow: %#lx",
+ si->GSBase, si->FSBase, si->ShadowGSBase);
+
+ // ((PCB *)ctx)->GetContext()->Yield();
+ // __builtin_unreachable();
+ /* Return because we will restore at sysretq */
+ }
+}
diff --git a/Kernel/arch/i386/core/panic/ui.cpp b/Kernel/arch/i386/core/panic/ui.cpp
new file mode 100644
index 00000000..defa3c6e
--- /dev/null
+++ b/Kernel/arch/i386/core/panic/ui.cpp
@@ -0,0 +1,131 @@
+/*
+ This file is part of Fennix Kernel.
+
+ Fennix Kernel is free software: you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ Fennix Kernel is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fennix Kernel. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "../../cpu/gdt.hpp"
+#include "../../cpu/apic.hpp"
+#include "../../../../kernel.h"
+
+extern void ExPrint(const char *Format, ...);
+
+static const char *x86PageFaultDescriptions[9] = {
+ "Supervisor tried to read a non-present page entry\n",
+ "Supervisor tried to read a page and caused a protection fault\n",
+ "Supervisor tried to write to a non-present page entry\n",
+ "Supervisor tried to write a page and caused a protection fault\n",
+ "User tried to read a non-present page entry\n",
+ "User tried to read a page and caused a protection fault\n",
+ "User tried to write to a non-present page entry\n",
+ "User tried to write a page and caused a protection fault\n",
+ "One or more page directory entries contain reserved bits which are set to 1.\n"};
+
+arch nsa void DisplayDetailsScreen(CPU::ExceptionFrame *Frame)
+{
+ ExPrint("\nException Frame:\n");
+ ExPrint(" General Purpose Registers:\n");
+ ExPrint(" EAX: %#lx EBX: %#lx ECX: %#lx EDX: %#lx\n",
+ Frame->eax, Frame->ebx, Frame->ecx, Frame->edx);
+ ExPrint(" ESI: %#lx EDI: %#lx\n",
+ Frame->esi, Frame->edi);
+
+ ExPrint(" Control Registers:\n");
+ ExPrint(" CR0: %#lx CR2: %#lx CR3: %#lx CR4: %#lx\n",
+ Frame->cr0, Frame->cr2, Frame->cr3, Frame->cr4);
+ ExPrint(" CR8: %#lx\n", Frame->cr8);
+
+ ExPrint(" Segment Registers:\n");
+ ExPrint(" CS: %#lx SS: %#lx DS: %#lx ES: %#lx FS: %#lx GS: %#lx\n",
+ Frame->cs, Frame->ss, Frame->ds, Frame->es, Frame->fs, Frame->gs);
+
+ ExPrint(" Debug Registers:\n");
+ ExPrint(" DR0: %#lx DR1: %#lx DR2: %#lx DR3: %#lx\n",
+ Frame->dr0, Frame->dr1, Frame->dr2, Frame->dr3);
+ ExPrint(" DR6: %#lx DR7: %#lx\n", Frame->dr6, Frame->dr7);
+
+ ExPrint(" Other:\n");
+ ExPrint(" INT: %#lx ERR: %#lx EIP: %#lx RFLAGS: %#lx\n",
+ Frame->InterruptNumber, Frame->ErrorCode,
+ Frame->eip, Frame->eflags.raw);
+ ExPrint(" RSP: %#lx RBP: %#lx\n",
+ Frame->esp, Frame->ebp);
+
+ ExPrint("Exception Details:\n");
+ switch (Frame->InterruptNumber)
+ {
+ case CPU::x86::PageFault:
+ {
+ CPU::x64::PageFaultErrorCode pfCode = {.raw = (uint32_t)Frame->ErrorCode};
+ ExPrint("PFEC: P:%d W:%d U:%d R:%d I:%d PK:%d SS:%d SGX:%d\n",
+ pfCode.P, pfCode.W, pfCode.U, pfCode.R,
+ pfCode.I, pfCode.PK, pfCode.SS, pfCode.SGX);
+
+ {
+ Memory::Virtual vmm((Memory::PageTable *)Frame->cr3);
+ if (vmm.GetMapType((void *)Frame->cr2) != Memory::Virtual::FourKiB)
+ ExPrint("Can't display page %#lx\n", Frame->cr2);
+ else
+ {
+ Memory::PageTableEntry *pte = vmm.GetPTE((void *)Frame->cr2);
+ ExPrint("Page %#lx: P:%d W:%d U:%d G:%d CoW:%d KRsv:%d\n",
+ ALIGN_DOWN(Frame->cr2, 0x1000), pte->Present, pte->ReadWrite,
+ pte->UserSupervisor, pte->Global, pte->CopyOnWrite,
+ pte->KernelReserve);
+ }
+ }
+
+ ExPrint("%s", x86PageFaultDescriptions[Frame->ErrorCode & 0b111]);
+ if (Frame->ErrorCode & 0x8)
+ ExPrint("%s", x86PageFaultDescriptions[8]);
+ break;
+ }
+ case CPU::x86::StackSegmentFault:
+ case CPU::x86::GeneralProtectionFault:
+ {
+ CPU::x64::SelectorErrorCode sCode = {.raw = Frame->ErrorCode};
+ ExPrint("Kernel performed an illegal operation.\n");
+ ExPrint("External: %d\n", sCode.External);
+ ExPrint("Table: %d\n", sCode.Table);
+ ExPrint("Index: %#x\n", sCode.Idx);
+ break;
+ }
+ default:
+ ExPrint("No additional information available for this exception.\n");
+ break;
+ }
+
+ if (!TaskManager)
+ return;
+
+ CPUData *core = GetCurrentCPU();
+ Tasking::PCB *proc = core->CurrentProcess.load();
+ Tasking::TCB *thread = core->CurrentThread.load();
+ ExPrint("Exception in %s process %s(%d) thread %s(%d)\n",
+ proc->Security.ExecutionMode == Tasking::User ? "user" : "kernel",
+ proc->Name, proc->ID,
+ thread->Name, thread->ID);
+}
diff --git a/Kernel/arch/i386/cpu/smp.cpp b/Kernel/arch/i386/cpu/smp.cpp
index cf5dccd3..b678c0db 100644
--- a/Kernel/arch/i386/cpu/smp.cpp
+++ b/Kernel/arch/i386/cpu/smp.cpp
@@ -55,7 +55,7 @@ nsa CPUData *GetCurrentCPU()
if (CPUEnabled.load(std::memory_order_acquire) == true)
{
if (apic->x2APIC)
- CoreID = int(CPU::x32::rdmsr(CPU::x32::MSR_X2APIC_APICID));
+ CoreID = int(CPU::x86::rdmsr(CPU::x86::MSR_X2APIC_APICID));
else
CoreID = apic->Read(APIC::APIC_ID) >> 24;
}
diff --git a/Kernel/arch/i386/memory/vmm.cpp b/Kernel/arch/i386/memory/vmm.cpp
index ec7a5bd7..a16eb084 100644
--- a/Kernel/arch/i386/memory/vmm.cpp
+++ b/Kernel/arch/i386/memory/vmm.cpp
@@ -29,7 +29,7 @@ namespace Memory
Address &= 0xFFFFF000;
PageMapIndexer Index = PageMapIndexer(Address);
- PageDirectoryEntry *PDE = &this->Table->Entries[Index.PDEIndex];
+ PageDirectoryEntry *PDE = &this->pTable->Entries[Index.PDEIndex];
PageTableEntryPtr *PTE = nullptr;
if ((PDE->raw & Flag) > 0)
@@ -54,7 +54,7 @@ namespace Memory
Address &= 0xFFFFF000;
PageMapIndexer Index = PageMapIndexer(Address);
- PageDirectoryEntry *PDE = &this->Table->Entries[Index.PDEIndex];
+ PageDirectoryEntry *PDE = &this->pTable->Entries[Index.PDEIndex];
PageTableEntryPtr *PTE = nullptr;
if (PDE->Present)
@@ -80,7 +80,7 @@ namespace Memory
PageMapIndexer Index = PageMapIndexer(Address);
- PageDirectoryEntry *PDE = &this->Table->Entries[Index.PDEIndex];
+ PageDirectoryEntry *PDE = &this->pTable->Entries[Index.PDEIndex];
PageTableEntryPtr *PTE = nullptr;
if (PDE->Present)
@@ -104,7 +104,7 @@ namespace Memory
Address &= 0xFFFFF000;
PageMapIndexer Index = PageMapIndexer(Address);
- PageDirectoryEntry *PDE = &this->Table->Entries[Index.PDEIndex];
+ PageDirectoryEntry *PDE = &this->pTable->Entries[Index.PDEIndex];
if (PDE->Present)
return PDE;
return nullptr;
@@ -116,7 +116,7 @@ namespace Memory
Address &= 0xFFFFF000;
PageMapIndexer Index = PageMapIndexer(Address);
- PageDirectoryEntry *PDE = &this->Table->Entries[Index.PDEIndex];
+ PageDirectoryEntry *PDE = &this->pTable->Entries[Index.PDEIndex];
if (!PDE->Present)
return nullptr;
@@ -130,7 +130,7 @@ namespace Memory
void Virtual::Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags, MapType Type)
{
SmartLock(this->MemoryLock);
- if (unlikely(!this->Table))
+ if (unlikely(!this->pTable))
{
error("No page table");
return;
@@ -142,7 +142,7 @@ namespace Memory
// Clear any flags that are not 1 << 0 (Present) - 1 << 5 (Accessed) because rest are for page table entries only
uint64_t DirectoryFlags = Flags & 0x3F;
- PageDirectoryEntry *PDE = &this->Table->Entries[Index.PDEIndex];
+ PageDirectoryEntry *PDE = &this->pTable->Entries[Index.PDEIndex];
if (Type == MapType::FourMiB)
{
PDE->raw |= (uintptr_t)Flags;
@@ -191,14 +191,14 @@ namespace Memory
void Virtual::Unmap(void *VirtualAddress, MapType Type)
{
SmartLock(this->MemoryLock);
- if (!this->Table)
+ if (!this->pTable)
{
error("No page table");
return;
}
PageMapIndexer Index = PageMapIndexer((uintptr_t)VirtualAddress);
- PageDirectoryEntry *PDE = &this->Table->Entries[Index.PDEIndex];
+ PageDirectoryEntry *PDE = &this->pTable->Entries[Index.PDEIndex];
if (!PDE->Present)
{
warn("Page %#lx not present", PDE->GetAddress());
@@ -223,4 +223,18 @@ namespace Memory
PTEPtr->Entries[Index.PTEIndex] = PTE;
CPU::x32::invlpg(VirtualAddress);
}
+
+ void Virtual::Remap(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags, MapType Type)
+ {
+ SmartLock(this->MemoryLock);
+ if (unlikely(!this->pTable))
+ {
+ error("No page table");
+ return;
+ }
+
+#warning "Remap is not properly implemented"
+ this->Unmap(VirtualAddress, Type);
+ this->Map(VirtualAddress, PhysicalAddress, Flags, Type);
+ }
}
diff --git a/Kernel/arch/i386/tasking/signal.cpp b/Kernel/arch/i386/tasking/signal.cpp
new file mode 100644
index 00000000..ff5492f4
--- /dev/null
+++ b/Kernel/arch/i386/tasking/signal.cpp
@@ -0,0 +1,160 @@
+/*
+ This file is part of Fennix Kernel.
+
+ Fennix Kernel is free software: you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ Fennix Kernel is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fennix Kernel. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+
+#include "../cpu/gdt.hpp"
+
+/* subsystem/linux/syscall.cpp */
+extern int ConvertSignalToLinux(signal_t sig);
+
+namespace Tasking
+{
+ bool Signal::HandleSignal(CPU::SchedulerFrame *tf, void *thread)
+ {
+ /* We don't want to do this in kernel mode */
+ if (tf->cs != GDT_USER_CODE)
+ return false;
+
+ if (Queue.empty())
+ return false;
+
+ debug("We have %d signals to handle", Queue.size());
+
+ SmartLock(SignalLock);
+ SignalInfo sigI = GetAvailableSignal(thread);
+ if (sigI.sig == SIGNULL)
+ return false;
+
+ uintptr_t _p_esp = ((PCB *)ctx)->PageTable->Get(tf->esp);
+ uint64_t paEsp = _p_esp;
+ paEsp &= ~0xF; /* Align */
+ paEsp -= 128; /* Red zone */
+
+ /* Calculate the virtual rsp */
+ uintptr_t _v_esp = tf->esp;
+ _v_esp &= ~0xF; /* Align */
+ _v_esp -= 128; /* Red zone */
+ uint64_t *vEsp = (uint64_t *)(_v_esp - sizeof(StackInfo));
+ vEsp--; /* Alignment */
+ vEsp--; /* Handler Address */
+ assert(!((uintptr_t)vEsp & 0xF));
+
+ /* Add the stack info */
+ StackInfo si{};
+ CPU::x86::fxsave(&si.fx);
+ si.tf = *tf;
+ si.GSBase = CPU::x86::rdmsr(CPU::x86::MSR_GS_BASE);
+ si.FSBase = CPU::x86::rdmsr(CPU::x86::MSR_FS_BASE);
+ si.ShadowGSBase = CPU::x86::rdmsr(CPU::x86::MSR_SHADOW_GS_BASE);
+ si.SignalMask = ((TCB *)thread)->Signals.Mask.to_ulong();
+ si.Compatibility = ((PCB *)ctx)->Info.Compatibility;
+
+ debug("gs: %#lx fs: %#lx shadow: %#lx",
+ si.GSBase, si.FSBase, si.ShadowGSBase);
+
+ /* Copy the stack info */
+ uint64_t *pEsp = (uint64_t *)(paEsp - sizeof(StackInfo));
+ memcpy(pEsp, &si, sizeof(StackInfo));
+
+ /* Set the handler address */
+ pEsp--; /* Alignment */
+ pEsp--;
+ *pEsp = uint64_t(sa[sigI.sig].sa_handler.Handler);
+
+ assert(!((uintptr_t)pEsp & 0xF));
+
+ int cSig = LinuxSig() ? ConvertSignalToLinux((signal_t)sigI.sig) : sigI.sig;
+
+#ifdef DEBUG
+ DumpData("Stack Data", (void *)pEsp,
+ paEsp - uint64_t(pEsp));
+ debug("initial stack tf->rsp: %#lx after: %#lx",
+ tf->esp, uint64_t(vEsp));
+ debug("sig: %d -> %d", sigI.sig, cSig);
+#endif
+
+ tf->esp = uint64_t(vEsp);
+ tf->eip = uint64_t(TrampAddr);
+
+ /* void func(int signo); */
+ /* void func(int signo, siginfo_t *info, void *context); */
+ tf->edi = cSig;
+ if (sa[sigI.sig].Flags & SA_SIGINFO)
+ {
+ fixme("SA_SIGINFO not implemented");
+ siginfo_t *info = 0;
+ void *context = 0;
+ tf->eax = uint64_t(info);
+ tf->edx = uint64_t(context);
+ tf->ecx = 0;
+ }
+ else
+ {
+ tf->eax = 0;
+ tf->edx = 0;
+ tf->ecx = 0;
+ }
+
+ ((TCB *)thread)->Signals.Mask = sa[sigI.sig].Mask;
+ assert(TrampAddr != nullptr);
+ return true;
+ }
+
+ void Signal::RestoreHandleSignal(SyscallsFrame *sf, void *thread)
+ {
+ debug("Restoring signal handler");
+ SmartLock(SignalLock);
+
+ gsTCB *gs = (gsTCB *)CPU::x86::rdmsr(CPU::x86::MSR_GS_BASE);
+ uint64_t *sp = (uint64_t *)((PCB *)ctx)->PageTable->Get(gs->TempStack);
+ sp++; /* Alignment */
+ sp++; /* Handler Address */
+
+ assert(!((uintptr_t)sp & 0xF));
+
+ StackInfo *si = (StackInfo *)sp;
+ assert(si != nullptr);
+
+ sf->bp = si->tf.ebp;
+ sf->di = si->tf.edi;
+ sf->si = si->tf.esi;
+ sf->dx = si->tf.edx;
+ sf->cx = si->tf.ecx;
+ sf->bx = si->tf.ebx;
+ sf->ax = si->tf.eax;
+ sf->Flags = si->tf.eflags.raw;
+ sf->ReturnAddress = si->tf.eip;
+ gs->TempStack = (void *)si->tf.esp;
+
+ ((TCB *)thread)->Signals.Mask = si->SignalMask;
+
+ CPU::x86::fxrstor(&si->fx);
+ CPU::x86::wrmsr(CPU::x86::MSR_GS_BASE, si->ShadowGSBase);
+ CPU::x86::wrmsr(CPU::x86::MSR_FS_BASE, si->FSBase);
+ CPU::x86::wrmsr(CPU::x86::MSR_SHADOW_GS_BASE, si->GSBase);
+ debug("gs: %#lx fs: %#lx shadow: %#lx",
+ si->GSBase, si->FSBase, si->ShadowGSBase);
+
+ // ((PCB *)ctx)->GetContext()->Yield();
+ // __builtin_unreachable();
+ /* Return because we will restore at sysretq */
+ }
+}
diff --git a/Kernel/arch/i386/tasking/signal_trampoline.s b/Kernel/arch/i386/tasking/signal_trampoline.s
new file mode 100644
index 00000000..08a6e2f0
--- /dev/null
+++ b/Kernel/arch/i386/tasking/signal_trampoline.s
@@ -0,0 +1,38 @@
+/*
+ This file is part of Fennix Kernel.
+
+ Fennix Kernel is free software: you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ Fennix Kernel is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fennix Kernel. If not, see .
+*/
+
+.code64
+
+.global _sig_native_trampoline_start
+_sig_native_trampoline_start:
+ int $0x3
+
+.global _sig_native_trampoline_end
+_sig_native_trampoline_end:
+
+.global _sig_linux_trampoline_start
+_sig_linux_trampoline_start:
+ movq %rsp, %rbp
+ movq (%rbp), %rax
+ call *%rax
+ mov %rbp, %rsp
+ /* rt_sigreturn = 15 */
+ movq $15, %rax
+ syscall
+
+.global _sig_linux_trampoline_end
+_sig_linux_trampoline_end:
diff --git a/Kernel/core/cpu.cpp b/Kernel/core/cpu.cpp
index 3d507af5..2bc4f120 100644
--- a/Kernel/core/cpu.cpp
+++ b/Kernel/core/cpu.cpp
@@ -313,7 +313,7 @@ namespace CPU
CoreData->Data.FPU.mxcsr = 0b0001111110000000;
CoreData->Data.FPU.mxcsrmask = 0b1111111110111111;
CoreData->Data.FPU.fcw = 0b0000001100111111;
- fxrstor(&CoreData->Data.FPU);
+ CPU::x86::fxrstor(&CoreData->Data.FPU);
SSEEnableAfter = true;
}
@@ -378,7 +378,7 @@ namespace CPU
debug("Updated CR4.");
debug("Enabling PAT support...");
- wrmsr(MSR_CR_PAT, 0x6 | (0x0 << 8) | (0x1 << 16));
+ CPU::x86::wrmsr(CPU::x86::MSR_CR_PAT, 0x6 | (0x0 << 8) | (0x1 << 16));
if (!BSP++)
trace("Features for BSP initialized.");
if (SSEEnableAfter)
diff --git a/Kernel/core/driver/driver.cpp b/Kernel/core/driver/driver.cpp
index cda5fea6..e75f28ef 100644
--- a/Kernel/core/driver/driver.cpp
+++ b/Kernel/core/driver/driver.cpp
@@ -245,8 +245,8 @@ namespace Driver
debug("Driver %s has entry point %#lx and base %#lx",
File->Name.c_str(), Drv.EntryPoint, Drv.BaseAddress);
- Elf64_Shdr sht_strtab{};
- Elf64_Shdr sht_symtab{};
+ Elf_Shdr sht_strtab{};
+ Elf_Shdr sht_symtab{};
Elf_Shdr shstrtab{};
Elf_Shdr shdr{};
__DriverInfo driverInfo{};
diff --git a/Kernel/core/interrupts_manager.cpp b/Kernel/core/interrupts_manager.cpp
index 15f05f19..d25e7f98 100644
--- a/Kernel/core/interrupts_manager.cpp
+++ b/Kernel/core/interrupts_manager.cpp
@@ -114,13 +114,13 @@ namespace Interrupts
void Initialize(int Core)
{
-#if defined(__amd64__)
+#if defined(__amd64__) || defined(__i386__)
GlobalDescriptorTable::Init(Core);
InterruptDescriptorTable::Init(Core);
CPUData *CoreData = GetCPU(Core);
CoreData->Checksum = CPU_DATA_CHECKSUM;
- CPU::x64::wrmsr(CPU::x64::MSR_GS_BASE, (uint64_t)CoreData);
- CPU::x64::wrmsr(CPU::x64::MSR_SHADOW_GS_BASE, (uint64_t)CoreData);
+ CPU::x86::wrmsr(CPU::x86::MSR_GS_BASE, (uint64_t)CoreData);
+ CPU::x86::wrmsr(CPU::x86::MSR_SHADOW_GS_BASE, (uint64_t)CoreData);
CoreData->ID = Core;
CoreData->IsActive = true;
CoreData->Stack = (uintptr_t)StackManager.Allocate(STACK_SIZE) + STACK_SIZE;
@@ -133,24 +133,6 @@ namespace Interrupts
debug("Stack for core %d is %#lx (Address: %#lx)",
Core, CoreData->Stack, CoreData->Stack - STACK_SIZE);
InitializeSystemCalls();
-#elif defined(__i386__)
- GlobalDescriptorTable::Init(Core);
- InterruptDescriptorTable::Init(Core);
- CPUData *CoreData = GetCPU(Core);
- CoreData->Checksum = CPU_DATA_CHECKSUM;
- CPU::x32::wrmsr(CPU::x32::MSR_GS_BASE, (uint64_t)CoreData);
- CPU::x32::wrmsr(CPU::x32::MSR_SHADOW_GS_BASE, (uint64_t)CoreData);
- CoreData->ID = Core;
- CoreData->IsActive = true;
- CoreData->Stack = (uintptr_t)StackManager.Allocate(STACK_SIZE) + STACK_SIZE;
- if (CoreData->Checksum != CPU_DATA_CHECKSUM)
- {
- KPrint("CPU %d checksum mismatch! %x != %x",
- Core, CoreData->Checksum, CPU_DATA_CHECKSUM);
- CPU::Stop();
- }
- debug("Stack for core %d is %#lx (Address: %#lx)",
- Core, CoreData->Stack, CoreData->Stack - STACK_SIZE);
#elif defined(__aarch64__)
warn("aarch64 is not supported yet");
#endif
diff --git a/Kernel/core/memory/heap_allocators/rpmalloc/rpmalloc.c b/Kernel/core/memory/heap_allocators/rpmalloc/rpmalloc.c
index 11e6b0f2..e155c96f 100644
--- a/Kernel/core/memory/heap_allocators/rpmalloc/rpmalloc.c
+++ b/Kernel/core/memory/heap_allocators/rpmalloc/rpmalloc.c
@@ -551,7 +551,9 @@ struct heap_t
};
/* Keep in sync with heap_t inside rpmalloc_compat.cpp */
+#ifndef __i386__
static_assert(sizeof(heap_t) == 56408, "heap_t size mismatch");
+#endif // __i386__
// Size class for defining a block size bucket
struct size_class_t
diff --git a/Kernel/core/memory/page_table.cpp b/Kernel/core/memory/page_table.cpp
index 36620601..d4ab3d7f 100644
--- a/Kernel/core/memory/page_table.cpp
+++ b/Kernel/core/memory/page_table.cpp
@@ -73,7 +73,7 @@ namespace Memory
}
}
#else
-#error "PageTable::Fork() not implemented for other architectures"
+#warning "PageTable::Fork() not implemented for other architectures"
#endif
debug("Forked page table %#lx to %#lx", this, NewTable);
diff --git a/Kernel/core/memory/vma.cpp b/Kernel/core/memory/vma.cpp
index 03074b73..87dc9494 100644
--- a/Kernel/core/memory/vma.cpp
+++ b/Kernel/core/memory/vma.cpp
@@ -236,7 +236,9 @@ namespace Memory
assert(pte->Present == true);
pte->ReadWrite = sr.Write;
pte->UserSupervisor = sr.Read;
+#if defined(__amd64__)
pte->ExecuteDisable = sr.Exec;
+#endif
pte->CopyOnWrite = false;
debug("PFA %#lx is CoW (pt %#lx, flags %#lx)",
diff --git a/Kernel/core/panic/handler.cpp b/Kernel/core/panic/handler.cpp
index 5ca3f022..788dab10 100644
--- a/Kernel/core/panic/handler.cpp
+++ b/Kernel/core/panic/handler.cpp
@@ -100,7 +100,7 @@ nsa void HaltAllCores()
if (SMP::CPUCores <= 1)
return;
-#if defined(__amd64__) || defined(__i386__)
+#if defined(__amd64__)
if (Interrupts::apic[0] == nullptr)
return;
diff --git a/Kernel/core/panic/kbd/xhci.cpp b/Kernel/core/panic/kbd/xhci.cpp
index 36bd8506..7e8177cd 100644
--- a/Kernel/core/panic/kbd/xhci.cpp
+++ b/Kernel/core/panic/kbd/xhci.cpp
@@ -140,9 +140,9 @@ nsa CrashXHCIKeyboardDriver::CrashXHCIKeyboardDriver(PCIDevice xhci)
debug("IO %d 64-BIT %d", BAR[0] & 0x1, BAR[0] & 0x4);
- uintptr_t baseAddress = BAR[0];
+ uint64_t baseAddress = BAR[0];
if (BAR[0] & 0x4)
- baseAddress |= (uintptr_t)BAR[1] << 32;
+ baseAddress |= (uint64_t)BAR[1] << 32;
if (baseAddress & 0x1)
baseAddress &= 0xFFFFFFFFFFFFFFFC;
@@ -158,7 +158,7 @@ nsa CrashXHCIKeyboardDriver::CrashXHCIKeyboardDriver(PCIDevice xhci)
runtime = (XHCIruntime *)(baseAddress + (caps->RTSOFF & ~0x1F));
doorbell = (XHCIdoorbell *)(baseAddress + (caps->DBOFF & ~0x3));
uint16_t exCapOffset = caps->HCCPARAMS1.xHCIExtendedCapacitiesPointer << 2;
- ExtendedCaps = (uintptr_t)caps + exCapOffset;
+ ExtendedCaps = (uint64_t)caps + exCapOffset;
debug("ExtendedCaps: %#lx (%#lx + %#lx)", ExtendedCaps, caps, exCapOffset);
#pragma GCC diagnostic push
diff --git a/Kernel/core/panic/ui.cpp b/Kernel/core/panic/ui.cpp
index 73b95fc7..af37abd6 100644
--- a/Kernel/core/panic/ui.cpp
+++ b/Kernel/core/panic/ui.cpp
@@ -95,17 +95,6 @@ x86ExceptionName x86Exceptions[] = {
/*31*/ {"#r7", "Reserved", "Reserved"},
};
-static const char *x86PageFaultDescriptions[9] = {
- "Supervisor tried to read a non-present page entry\n",
- "Supervisor tried to read a page and caused a protection fault\n",
- "Supervisor tried to write to a non-present page entry\n",
- "Supervisor tried to write a page and caused a protection fault\n",
- "User tried to read a non-present page entry\n",
- "User tried to read a page and caused a protection fault\n",
- "User tried to write to a non-present page entry\n",
- "User tried to write a page and caused a protection fault\n",
- "One or more page directory entries contain reserved bits which are set to 1.\n"};
-
int ActiveScreen = 0;
char __modSym[20];
@@ -139,9 +128,19 @@ nsa const char *ExGetKSymbolByAddress(uintptr_t Address)
nsa const char *ExGetKSymbol(CPU::ExceptionFrame *Frame)
{
+#if defined(__amd64__)
if (Frame->rip < (uintptr_t)&_kernel_start &&
Frame->rip > (uintptr_t)&_kernel_end)
return "";
+#elif defined(__i386__)
+ if (Frame->eip < (uintptr_t)&_kernel_start &&
+ Frame->eip > (uintptr_t)&_kernel_end)
+ return "";
+#elif defined(__aarch64__)
+ if (Frame->pc < (uintptr_t)&_kernel_start &&
+ Frame->pc > (uintptr_t)&_kernel_end)
+ return "";
+#endif
#if defined(__amd64__)
return ExGetKSymbolByAddress(Frame->rip);
@@ -338,94 +337,7 @@ nsa void DisplayMainScreen(CPU::ExceptionFrame *Frame)
ExPrint("\nUse command 'diag' to create a diagnostic report.\n");
}
-nsa void DisplayDetailsScreen(CPU::ExceptionFrame *Frame)
-{
- ExPrint("\nException Frame:\n");
- ExPrint(" General Purpose Registers:\n");
- ExPrint(" RAX: %#lx RBX: %#lx RCX: %#lx RDX: %#lx\n",
- Frame->rax, Frame->rbx, Frame->rcx, Frame->rdx);
- ExPrint(" RSI: %#lx RDI: %#lx R8: %#lx R9: %#lx\n",
- Frame->rsi, Frame->rdi, Frame->r8, Frame->r9);
- ExPrint(" R10: %#lx R11: %#lx R12: %#lx R13: %#lx\n",
- Frame->r10, Frame->r11, Frame->r12, Frame->r13);
- ExPrint(" R14: %#lx R15: %#lx\n", Frame->r14, Frame->r15);
-
- ExPrint(" Control Registers:\n");
- ExPrint(" CR0: %#lx CR2: %#lx CR3: %#lx CR4: %#lx\n",
- Frame->cr0, Frame->cr2, Frame->cr3, Frame->cr4);
- ExPrint(" CR8: %#lx\n", Frame->cr8);
-
- ExPrint(" Segment Registers:\n");
- ExPrint(" CS: %#lx SS: %#lx DS: %#lx ES: %#lx FS: %#lx GS: %#lx\n",
- Frame->cs, Frame->ss, Frame->ds, Frame->es, Frame->fs, Frame->gs);
-
- ExPrint(" Debug Registers:\n");
- ExPrint(" DR0: %#lx DR1: %#lx DR2: %#lx DR3: %#lx\n",
- Frame->dr0, Frame->dr1, Frame->dr2, Frame->dr3);
- ExPrint(" DR6: %#lx DR7: %#lx\n", Frame->dr6, Frame->dr7);
-
- ExPrint(" Other:\n");
- ExPrint(" INT: %#lx ERR: %#lx RIP: %#lx RFLAGS: %#lx\n",
- Frame->InterruptNumber, Frame->ErrorCode,
- Frame->rip, Frame->rflags.raw);
- ExPrint(" RSP: %#lx RBP: %#lx\n",
- Frame->rsp, Frame->rbp);
-
- ExPrint("Exception Details:\n");
- switch (Frame->InterruptNumber)
- {
- case CPU::x86::PageFault:
- {
- CPU::x64::PageFaultErrorCode pfCode = {.raw = (uint32_t)Frame->ErrorCode};
- ExPrint("PFEC: P:%d W:%d U:%d R:%d I:%d PK:%d SS:%d SGX:%d\n",
- pfCode.P, pfCode.W, pfCode.U, pfCode.R,
- pfCode.I, pfCode.PK, pfCode.SS, pfCode.SGX);
-
- {
- Memory::Virtual vmm((Memory::PageTable *)Frame->cr3);
- if (vmm.GetMapType((void *)Frame->cr2) != Memory::Virtual::FourKiB)
- ExPrint("Can't display page %#lx\n", Frame->cr2);
- else
- {
- Memory::PageTableEntry *pte = vmm.GetPTE((void *)Frame->cr2);
- ExPrint("Page %#lx: P:%d W:%d U:%d G:%d CoW:%d KRsv:%d NX:%d\n",
- ALIGN_DOWN(Frame->cr2, 0x1000), pte->Present, pte->ReadWrite,
- pte->UserSupervisor, pte->Global, pte->CopyOnWrite,
- pte->KernelReserve, pte->ExecuteDisable);
- }
- }
-
- ExPrint("%s", x86PageFaultDescriptions[Frame->ErrorCode & 0b111]);
- if (Frame->ErrorCode & 0x8)
- ExPrint("%s", x86PageFaultDescriptions[8]);
- break;
- }
- case CPU::x86::StackSegmentFault:
- case CPU::x86::GeneralProtectionFault:
- {
- CPU::x64::SelectorErrorCode sCode = {.raw = Frame->ErrorCode};
- ExPrint("Kernel performed an illegal operation.\n");
- ExPrint("External: %d\n", sCode.External);
- ExPrint("Table: %d\n", sCode.Table);
- ExPrint("Index: %#x\n", sCode.Idx);
- break;
- }
- default:
- ExPrint("No additional information available for this exception.\n");
- break;
- }
-
- if (!TaskManager)
- return;
-
- CPUData *core = GetCurrentCPU();
- Tasking::PCB *proc = core->CurrentProcess.load();
- Tasking::TCB *thread = core->CurrentThread.load();
- ExPrint("Exception in %s process %s(%d) thread %s(%d)\n",
- proc->Security.ExecutionMode == Tasking::User ? "user" : "kernel",
- proc->Name, proc->ID,
- thread->Name, thread->ID);
-}
+arch void DisplayDetailsScreen(CPU::ExceptionFrame *Frame);
nsa void DisplayStackScreen(CPU::ExceptionFrame *Frame)
{
diff --git a/Kernel/include/cpu.hpp b/Kernel/include/cpu.hpp
index 15167679..490ab86a 100644
--- a/Kernel/include/cpu.hpp
+++ b/Kernel/include/cpu.hpp
@@ -23,13 +23,13 @@
#include
#include
#include
-#include
#include
-#include
#include
#include
#include
+#include
#include
+#include
#include
/**
@@ -211,6 +211,41 @@ namespace CPU
/** @brief Get CPU counter value. */
uint64_t Counter();
+ namespace x86
+ {
+ nsa static inline void fxsave(void *FXSaveArea)
+ {
+ assert(FXSaveArea != nullptr);
+#if defined(__amd64__)
+ asmv("fxsaveq (%0)"
+ :
+ : "r"(FXSaveArea)
+ : "memory");
+#elif defined(__i386__)
+ asmv("fxsave (%0)"
+ :
+ : "r"(FXSaveArea)
+ : "memory");
+#endif
+ }
+
+ nsa static inline void fxrstor(void *FXRstorArea)
+ {
+ assert(FXRstorArea != nullptr);
+#if defined(__amd64__)
+ asmv("fxrstorq (%0)"
+ :
+ : "r"(FXRstorArea)
+ : "memory");
+#elif defined(__i386__)
+ asmv("fxrstor (%0)"
+ :
+ : "r"(FXRstorArea)
+ : "memory");
+#endif
+ }
+ }
+
namespace x32
{
/**
@@ -294,24 +329,83 @@ namespace CPU
struct TrapFrame
{
- uint32_t edi; // Destination index for string operations
- uint32_t esi; // Source index for string operations
- uint32_t ebp; // Base Pointer (meant for stack frames)
- uint32_t esp; // Stack Pointer
- uint32_t ebx; // Base
- uint32_t edx; // Data (commonly extends the A register)
- uint32_t ecx; // Counter
- uint32_t eax; // Accumulator
+ uint32_t edi; /* Destination index for string operations */
+ uint32_t esi; /* Source index for string operations */
+ uint32_t ebp; /* Base Pointer (meant for stack frames) */
+ uint32_t ebx; /* Base */
+ uint32_t edx; /* Data (commonly extends the A register) */
+ uint32_t ecx; /* Counter */
+ uint32_t eax; /* Accumulator */
- uint32_t InterruptNumber; // Interrupt Number
- uint32_t ErrorCode; // Error code
+ uint32_t InterruptNumber; /* Interrupt Number */
+ uint32_t ErrorCode; /* Error code */
- uint32_t eip; // Instruction Pointer
- uint32_t cs; // Code Segment
- EFLAGS eflags; // Register Flags
+ uint32_t eip; /* Instruction Pointer */
+ uint32_t cs; /* Code Segment */
+ EFLAGS eflags; /* Register Flags */
+ uint32_t esp; /* Stack Pointer */
+ uint32_t ss; /* Stack Segment */
+ };
- uint32_t r3_esp; // Stack Pointer
- uint32_t r3_ss; // Stack Segment
+ struct SchedulerFrame
+ {
+ uint32_t ppt; /* Process Page Table */
+ uint32_t opt; /* Original Page Table */
+
+ uint32_t ebp; /* Base Pointer (meant for stack frames) */
+ uint32_t edi; /* Destination index for string operations */
+ uint32_t esi; /* Source index for string operations */
+ uint32_t edx; /* Data (commonly extends the A register) */
+ uint32_t ecx; /* Counter */
+ uint32_t ebx; /* Base */
+ uint32_t eax; /* Accumulator */
+
+ uint32_t InterruptNumber; /* Interrupt Number */
+ uint32_t ErrorCode; /* Error code */
+
+ uint32_t eip; /* Instruction Pointer */
+ uint32_t cs; /* Code Segment */
+ EFLAGS eflags; /* Register Flags */
+ uint32_t esp; /* Stack Pointer */
+ uint32_t ss; /* Stack Segment */
+ };
+
+ struct ExceptionFrame
+ {
+ uint32_t cr0; /* Control Register 0 (system control) */
+ uint32_t cr2; /* Control Register 2 (page fault linear address) */
+ uint32_t cr3; /* Control Register 3 (page directory base) */
+ uint32_t cr4; /* Control Register 4 (system control) */
+ uint32_t cr8; /* Control Register 8 (task priority) */
+
+ uint32_t dr0; /* Debug Register */
+ uint32_t dr1; /* Debug Register */
+ uint32_t dr2; /* Debug Register */
+ uint32_t dr3; /* Debug Register */
+ uint32_t dr6; /* Debug Register */
+ uint32_t dr7; /* Debug Register */
+
+ uint32_t gs; /* General purpose */
+ uint32_t fs; /* General purpose */
+ uint32_t es; /* Extra Segment */
+ uint32_t ds; /* Data Segment */
+
+ uint32_t ebp; /* Base Pointer (meant for stack frames) */
+ uint32_t edi; /* Destination index for string operations */
+ uint32_t esi; /* Source index for string operations */
+ uint32_t edx; /* Data (commonly extends the A register) */
+ uint32_t ecx; /* Counter */
+ uint32_t ebx; /* Base */
+ uint32_t eax; /* Accumulator */
+
+ uint32_t InterruptNumber; /* Interrupt Number */
+ uint32_t ErrorCode; /* Error code */
+
+ uint32_t eip; /* Instruction Pointer */
+ uint32_t cs; /* Code Segment */
+ EFLAGS eflags; /* Register Flags */
+ uint32_t esp; /* Stack Pointer */
+ uint32_t ss; /* Stack Segment */
};
typedef union DR6
@@ -319,27 +413,27 @@ namespace CPU
struct
{
/** @brief Breakpoint #0 Condition Detected */
- uint64_t B0 : 1;
+ uint32_t B0 : 1;
/** @brief Breakpoint #1 Condition Detected */
- uint64_t B1 : 1;
+ uint32_t B1 : 1;
/** @brief Breakpoint #2 Condition Detected */
- uint64_t B2 : 1;
+ uint32_t B2 : 1;
/** @brief Breakpoint #3 Condition Detected */
- uint64_t B3 : 1;
+ uint32_t B3 : 1;
/** @brief Reserved */
- uint64_t Reserved0 : 8;
+ uint32_t Reserved0 : 8;
/** @brief Reserved */
- uint64_t Reserved1 : 1;
+ uint32_t Reserved1 : 1;
/** @brief Breakpoint Debug Access Detected */
- uint64_t BD : 1;
+ uint32_t BD : 1;
/** @brief Breakpoint Single Step */
- uint64_t BS : 1;
+ uint32_t BS : 1;
/** @brief Breakpoint Task Switch */
- uint64_t BT : 1;
+ uint32_t BT : 1;
/** @brief Reserved */
- uint64_t Reserved2 : 15;
+ uint32_t Reserved2 : 15;
};
- uint64_t raw;
+ uint32_t raw;
} DR6;
typedef union DR7
@@ -978,32 +1072,6 @@ namespace CPU
cpuid(0x0, &eax, &ebx, &ecx, &edx);
return eax;
}
-
- nsa static inline void fxsave(void *FXSaveArea)
- {
-#ifdef __amd64__
- if (!FXSaveArea || FXSaveArea >= (char *)0xfffffffffffff000)
- return;
-
- asmv("fxsaveq (%0)"
- :
- : "r"(FXSaveArea)
- : "memory");
-#endif
- }
-
- nsa static inline void fxrstor(void *FXRstorArea)
- {
-#ifdef __amd64__
- if (!FXRstorArea || FXRstorArea >= (char *)0xfffffffffffff000)
- return;
-
- asmv("fxrstorq (%0)"
- :
- : "r"(FXRstorArea)
- : "memory");
-#endif
- }
}
namespace aarch64
diff --git a/Kernel/include/cpu/x86/x64/msr.hpp b/Kernel/include/cpu/x86/msr.hpp
similarity index 91%
rename from Kernel/include/cpu/x86/x64/msr.hpp
rename to Kernel/include/cpu/x86/msr.hpp
index 8b54418f..3390bcd1 100644
--- a/Kernel/include/cpu/x86/x64/msr.hpp
+++ b/Kernel/include/cpu/x86/msr.hpp
@@ -1,18 +1,18 @@
/*
- This file is part of Fennix Kernel.
+ This file is part of Fennix Kernel.
- Fennix Kernel is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation, either version 3 of
- the License, or (at your option) any later version.
+ Fennix Kernel is free software: you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
- Fennix Kernel is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ Fennix Kernel is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Fennix Kernel. If not, see .
+ You should have received a copy of the GNU General Public License
+ along with Fennix Kernel. If not, see .
*/
#ifndef __FENNIX_KERNEL_CPU_x64_MSR_H__
@@ -22,7 +22,7 @@
namespace CPU
{
- namespace x64
+ namespace x86
{
enum MSRID
{
@@ -420,6 +420,25 @@ namespace CPU
: "c"(msr), "a"(Low), "d"(High)
: "memory");
}
+#elif defined(__i386__)
+ nsa static inline uint64_t rdmsr(uint32_t msr)
+ {
+ uint32_t Low, High;
+ asmv("rdmsr"
+ : "=a"(Low), "=d"(High)
+ : "c"(msr)
+ : "memory");
+ return ((uint64_t)Low) | (((uint64_t)High) << 32);
+ }
+
+ nsa static inline void wrmsr(uint32_t msr, uint64_t Value)
+ {
+ uint32_t Low = (uint32_t)Value, High = (uint32_t)(Value >> 32);
+ asmv("wrmsr"
+ :
+ : "c"(msr), "a"(Low), "d"(High)
+ : "memory");
+ }
#endif
}
}
diff --git a/Kernel/include/cpu/x86/x32/cr.hpp b/Kernel/include/cpu/x86/x32/cr.hpp
index d650c5e9..98b87b5d 100644
--- a/Kernel/include/cpu/x86/x32/cr.hpp
+++ b/Kernel/include/cpu/x86/x32/cr.hpp
@@ -174,14 +174,6 @@ namespace CPU
return (CR4){.raw = Result};
}
- nsa static inline CR8 readcr8()
- {
- uint32_t Result = 0;
- asmv("mov %%cr8, %[Result]"
- : [Result] "=q"(Result));
- return (CR8){.raw = Result};
- }
-
nsa static inline void writecr0(CR0 ControlRegister)
{
asmv("mov %[ControlRegister], %%cr0"
@@ -213,14 +205,6 @@ namespace CPU
: [ControlRegister] "q"(ControlRegister.raw)
: "memory");
}
-
- nsa static inline void writecr8(CR8 ControlRegister)
- {
- asmv("mov %[ControlRegister], %%cr8"
- :
- : [ControlRegister] "q"(ControlRegister.raw)
- : "memory");
- }
#endif
}
}
diff --git a/Kernel/include/cpu/x86/x32/msr.hpp b/Kernel/include/cpu/x86/x32/msr.hpp
deleted file mode 100644
index 42244b88..00000000
--- a/Kernel/include/cpu/x86/x32/msr.hpp
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- This file is part of Fennix Kernel.
-
- Fennix Kernel is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation, either version 3 of
- the License, or (at your option) any later version.
-
- Fennix Kernel is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Fennix Kernel. If not, see .
-*/
-
-#ifndef __FENNIX_KERNEL_CPU_x32_MSR_H__
-#define __FENNIX_KERNEL_CPU_x32_MSR_H__
-
-#include
-
-namespace CPU
-{
- namespace x32
- {
- enum MSRID
- {
- MSR_MONITOR_FILTER_SIZE = 0x6,
- MSR_TIME_STAMP_COUNTER = 0x10,
- MSR_PLATFORM_ID = 0x17,
- MSR_APIC_BASE = 0x1B,
- MSR_FEATURE_CONTROL = 0x3A,
- MSR_TSC_ADJUST = 0x3B,
- MSR_SPEC_CTRL = 0x48,
- MSR_PRED_CMD = 0x49,
- MSR_BIOS_UPDT_TRIG = 0x79,
- MSR_BIOS_SIGN_ID = 0x8B,
- MSR_SGXLEPUBKEYHASH0 = 0x8C,
- MSR_SGXLEPUBKEYHASH1 = 0x8D,
- MSR_SGXLEPUBKEYHASH2 = 0x8E,
- MSR_SGXLEPUBKEYHASH3 = 0x8F,
- MSR_SMM_MONITOR_CTL = 0x9B,
- MSR_SMBASE = 0x9E,
- MSR_PMC0 = 0xC1,
- MSR_PMC1 = 0xC2,
- MSR_PMC2 = 0xC3,
- MSR_PMC3 = 0xC4,
- MSR_PMC4 = 0xC5,
- MSR_PMC5 = 0xC6,
- MSR_PMC6 = 0xC7,
- MSR_PMC7 = 0xC8,
- MSR_UMWAIT_CONTROL = 0xE1,
- MSR_MPERF = 0xE7,
- MSR_APERF = 0xE8,
- MSR_MTRRCAP = 0xFE,
- MSR_ARCH_CAPABILITIES = 0x10A,
- MSR_FLUSH_CMD = 0x10B,
- MSR_SYSENTER_CS = 0x17A,
- MSR_SYSENTER_ESP = 0x175,
- MSR_SYSENTER_EIP = 0x176,
- MSR_MCG_CAP = 0x179,
- MSR_MCG_STATUS = 0x17A,
- MSR_MCG_CTL = 0x17B,
- MSR_PERFEVTSEL0 = 0x186,
- MSR_PERFEVTSEL1 = 0x187,
- MSR_PERFEVTSEL2 = 0x188,
- MSR_PERFEVTSEL3 = 0x189,
- MSR_PERF_STATUS = 0x198,
- MSR_PERF_CTL = 0x199,
- MSR_CLOCK_MODULATION = 0x19A,
- MSR_THERM_INTERRUPT = 0x19B,
- MSR_THERM_STATUS = 0x19C,
- MSR_MISC_ENABLE = 0x1A0,
- MSR_ENERGY_PERF_BIAS = 0x1B0,
- MSR_PACKAGE_THERM_STATUS = 0x1B1,
- MSR_PACKAGE_THERM_INTERRUPT = 0x1B2,
- MSR_DEBUGCTL = 0x1D9,
- MSR_SMRR_PHYSBASE = 0x1F2,
- MSR_SMRR_PHYSMASK = 0x1F3,
- MSR_PLATFORM_DCA_CAP = 0x1F8,
- MSR_CPU_DCA_CAP = 0x1F9,
- MSR_DCA_0_CAP = 0x1FA,
- MSR_MTRR_PHYSBASE0 = 0x200,
- MSR_MTRR_PHYSMASK0 = 0x201,
- MSR_MTRR_PHYSBASE1 = 0x202,
- MSR_MTRR_PHYSMASK1 = 0x203,
- MSR_MTRR_PHYSBASE2 = 0x204,
- MSR_MTRR_PHYSMASK2 = 0x205,
- MSR_MTRR_PHYSBASE3 = 0x206,
- MSR_MTRR_PHYSMASK3 = 0x207,
- MSR_MTRR_PHYSBASE4 = 0x208,
- MSR_MTRR_PHYSMASK4 = 0x209,
- MSR_MTRR_PHYSBASE5 = 0x20A,
- MSR_MTRR_PHYSMASK5 = 0x20B,
- MSR_MTRR_PHYSBASE6 = 0x20C,
- MSR_MTRR_PHYSMASK6 = 0x20D,
- MSR_MTRR_PHYSBASE7 = 0x20E,
- MSR_MTRR_PHYSMASK7 = 0x20F,
- MSR_MTRR_PHYSBASE8 = 0x210,
- MSR_MTRR_PHYSMASK8 = 0x211,
- MSR_MTRR_PHYSBASE9 = 0x212,
- MSR_MTRR_PHYSMASK9 = 0x213,
- MSR_MTRR_FIX64K_00000 = 0x250,
- MSR_MTRR_FIX16K_80000 = 0x258,
- MSR_MTRR_FIX16K_A0000 = 0x259,
- MSR_MTRR_FIX4K_C0000 = 0x268,
- MSR_MTRR_FIX4K_C8000 = 0x269,
- MSR_MTRR_FIX4K_D0000 = 0x26A,
- MSR_MTRR_FIX4K_D8000 = 0x26B,
- MSR_MTRR_FIX4K_E0000 = 0x26C,
- MSR_MTRR_FIX4K_E8000 = 0x26D,
- MSR_MTRR_FIX4K_F0000 = 0x26E,
- MSR_MTRR_FIX4K_F8000 = 0x26F,
- MSR_PAT = 0x277,
- MSR_MC0_CTL2 = 0x280,
- MSR_MC1_CTL2 = 0x281,
- MSR_MC2_CTL2 = 0x282,
- MSR_MC3_CTL2 = 0x283,
- MSR_MC4_CTL2 = 0x284,
- MSR_MC5_CTL2 = 0x285,
- MSR_MC6_CTL2 = 0x286,
- MSR_MC7_CTL2 = 0x287,
- MSR_MC8_CTL2 = 0x288,
- MSR_MC9_CTL2 = 0x289,
- MSR_MC10_CTL2 = 0x28A,
- MSR_MC11_CTL2 = 0x28B,
- MSR_MC12_CTL2 = 0x28C,
- MSR_MC13_CTL2 = 0x28D,
- MSR_MC14_CTL2 = 0x28E,
- MSR_MC15_CTL2 = 0x28F,
- MSR_MC16_CTL2 = 0x290,
- MSR_MC17_CTL2 = 0x291,
- MSR_MC18_CTL2 = 0x292,
- MSR_MC19_CTL2 = 0x293,
- MSR_MC20_CTL2 = 0x294,
- MSR_MC21_CTL2 = 0x295,
- MSR_MC22_CTL2 = 0x296,
- MSR_MC23_CTL2 = 0x297,
- MSR_MC24_CTL2 = 0x298,
- MSR_MC25_CTL2 = 0x299,
- MSR_MC26_CTL2 = 0x29A,
- MSR_MC27_CTL2 = 0x29B,
- MSR_MC28_CTL2 = 0x29C,
- MSR_MC29_CTL2 = 0x29D,
- MSR_MC30_CTL2 = 0x29E,
- MSR_MC31_CTL2 = 0x29F,
- MSR_MTRR_DEF_TYPE = 0x2FF,
- MSR_FIXED_CTR0 = 0x309,
- MSR_FIXED_CTR1 = 0x30A,
- MSR_FIXED_CTR2 = 0x30B,
- MSR_PERF_CAPABILITIES = 0x345,
- MSR_FIXED_CTR_CTRL = 0x38D,
- MSR_PERF_GLOBAL_STATUS = 0x38E,
- MSR_PERF_GLOBAL_CTRL = 0x38F,
- MSR_PERF_GLOBAL_STATUS_RESET = 0x390,
- MSR_PERF_GLOBAL_STATUS_SET = 0x391,
- MSR_PERF_GLOBAL_INUSE = 0x392,
- MSR_PEBS_ENABLE = 0x3F1,
- MSR_MC0_CTL = 0x400,
- MSR_MC0_STATUS = 0x401,
- MSR_MC0_ADDR = 0x402,
- MSR_MC0_MISC = 0x403,
- MSR_MC1_CTL = 0x404,
- MSR_MC1_STATUS = 0x405,
- MSR_MC1_ADDR = 0x406,
- MSR_MC1_MISC = 0x407,
- MSR_MC2_CTL = 0x408,
- MSR_MC2_STATUS = 0x409,
- MSR_MC2_ADDR = 0x40A,
- MSR_MC2_MISC = 0x40B,
- MSR_MC3_CTL = 0x40C,
- MSR_MC3_STATUS = 0x40D,
- MSR_MC3_ADDR = 0x40E,
- MSR_MC3_MISC = 0x40F,
- MSR_MC4_CTL = 0x410,
- MSR_MC4_STATUS = 0x411,
- MSR_MC4_ADDR = 0x412,
- MSR_MC4_MISC = 0x413,
- MSR_MC5_CTL = 0x414,
- MSR_MC5_STATUS = 0x415,
- MSR_MC5_ADDR = 0x416,
- MSR_MC5_MISC = 0x417,
- MSR_MC6_CTL = 0x418,
- MSR_MC6_STATUS = 0x419,
- MSR_MC6_ADDR = 0x41A,
- MSR_MC6_MISC = 0x41B,
- MSR_MC7_CTL = 0x41C,
- MSR_MC7_STATUS = 0x41D,
- MSR_MC7_ADDR = 0x41E,
- MSR_MC7_MISC = 0x41F,
- MSR_MC8_CTL = 0x420,
- MSR_MC8_STATUS = 0x421,
- MSR_MC8_ADDR = 0x422,
- MSR_MC8_MISC = 0x423,
- MSR_MC9_CTL = 0x424,
- MSR_MC9_STATUS = 0x425,
- MSR_MC9_ADDR = 0x426,
- MSR_MC9_MISC = 0x427,
- MSR_MC10_CTL = 0x428,
- MSR_MC10_STATUS = 0x429,
- MSR_MC10_ADDR = 0x42A,
- MSR_MC10_MISC = 0x42B,
- MSR_MC11_CTL = 0x42C,
- MSR_MC11_STATUS = 0x42D,
- MSR_MC11_ADDR = 0x42E,
- MSR_MC11_MISC = 0x42F,
- MSR_MC12_CTL = 0x430,
- MSR_MC12_STATUS = 0x431,
- MSR_MC12_ADDR = 0x432,
- MSR_MC12_MISC = 0x433,
- MSR_MC13_CTL = 0x434,
- MSR_MC13_STATUS = 0x435,
- MSR_MC13_ADDR = 0x436,
- MSR_MC13_MISC = 0x437,
- MSR_MC14_CTL = 0x438,
- MSR_MC14_STATUS = 0x439,
- MSR_MC14_ADDR = 0x43A,
- MSR_MC14_MISC = 0x43B,
- MSR_MC15_CTL = 0x43C,
- MSR_MC15_STATUS = 0x43D,
- MSR_MC15_ADDR = 0x43E,
- MSR_MC15_MISC = 0x43F,
- MSR_MC16_CTL = 0x440,
- MSR_MC16_STATUS = 0x441,
- MSR_MC16_ADDR = 0x442,
- MSR_MC16_MISC = 0x443,
- MSR_MC17_CTL = 0x444,
- MSR_MC17_STATUS = 0x445,
- MSR_MC17_ADDR = 0x446,
- MSR_MC17_MISC = 0x447,
- MSR_MC18_CTL = 0x448,
- MSR_MC18_STATUS = 0x449,
- MSR_MC18_ADDR = 0x44A,
- MSR_MC18_MISC = 0x44B,
- MSR_MC19_CTL = 0x44C,
- MSR_MC19_STATUS = 0x44D,
- MSR_MC19_ADDR = 0x44E,
- MSR_MC19_MISC = 0x44F,
- MSR_MC20_CTL = 0x450,
- MSR_MC20_STATUS = 0x451,
- MSR_MC20_ADDR = 0x452,
- MSR_MC20_MISC = 0x453,
- MSR_MC21_CTL = 0x454,
- MSR_MC21_STATUS = 0x455,
- MSR_MC21_ADDR = 0x456,
- MSR_MC21_MISC = 0x457,
- MSR_MC22_CTL = 0x458,
- MSR_MC22_STATUS = 0x459,
- MSR_MC22_ADDR = 0x45A,
- MSR_MC22_MISC = 0x45B,
- MSR_MC23_CTL = 0x45C,
- MSR_MC23_STATUS = 0x45D,
- MSR_MC23_ADDR = 0x45E,
- MSR_MC23_MISC = 0x45F,
- MSR_MC24_CTL = 0x460,
- MSR_MC24_STATUS = 0x461,
- MSR_MC24_ADDR = 0x462,
- MSR_MC24_MISC = 0x463,
- MSR_MC25_CTL = 0x464,
- MSR_MC25_STATUS = 0x465,
- MSR_MC25_ADDR = 0x466,
- MSR_MC25_MISC = 0x467,
- MSR_MC26_CTL = 0x468,
- MSR_MC26_STATUS = 0x469,
- MSR_MC26_ADDR = 0x46A,
- MSR_MC26_MISC = 0x46B,
- MSR_MC27_CTL = 0x46C,
- MSR_MC27_STATUS = 0x46D,
- MSR_MC27_ADDR = 0x46E,
- MSR_MC27_MISC = 0x46F,
- MSR_MC28_CTL = 0x470,
- MSR_MC28_STATUS = 0x471,
- MSR_MC28_ADDR = 0x472,
- MSR_MC28_MISC = 0x473,
- MSR_VMX_BASIC = 0x480,
- MSR_VMX_PINBASED_CTLS = 0x481,
- MSR_VMX_PROCBASED_CTLS = 0x482,
- MSR_VMX_EXIT_CTLS = 0x483,
- MSR_VMX_ENTRY_CTLS = 0x484,
- MSR_VMX_MISC = 0x485,
- MSR_VMX_CR0_FIXED0 = 0x486,
- MSR_VMX_CR0_FIXED1 = 0x487,
- MSR_VMX_CR4_FIXED0 = 0x488,
- MSR_VMX_CR4_FIXED1 = 0x489,
- MSR_VMX_VMCS_ENUM = 0x48A,
- MSR_VMX_PROCBASED_CTLS2 = 0x48B,
- MSR_VMX_EPT_VPID_CAP = 0x48C,
- MSR_VMX_TRUE_PINBASED_CTLS = 0x48D,
- MSR_VMX_TRUE_PROCBASED_CTLS = 0x48E,
- MSR_VMX_TRUE_EXIT_CTLS = 0x48F,
- MSR_VMX_TRUE_ENTRY_CTLS = 0x490,
- MSR_VMX_VMFUNC = 0x491,
- MSR_A_PMC0 = 0x4C1,
- MSR_A_PMC1 = 0x4C2,
- MSR_A_PMC2 = 0x4C3,
- MSR_A_PMC3 = 0x4C4,
- MSR_A_PMC4 = 0x4C5,
- MSR_A_PMC5 = 0x4C6,
- MSR_A_PMC6 = 0x4C7,
- MSR_A_PMC7 = 0x4C8,
- MSR_MCG_EXT_CTL = 0x4D0,
- MSR_SGX_SVN_STATUS = 0x500,
- MSR_RTIT_OUTPUT_BASE = 0x560,
- MSR_RTIT_OUTPUT_MASK_PTRS = 0x561,
- MSR_RTIT_CTL = 0x570,
- MSR_RTIT_STATUS = 0x571,
- MSR_RTIT_CR3_MATCH = 0x572,
- MSR_RTIT_ADDR0_A = 0x580,
- MSR_RTIT_ADDR0_B = 0x581,
- MSR_RTIT_ADDR1_A = 0x582,
- MSR_RTIT_ADDR1_B = 0x583,
- MSR_RTIT_ADDR2_A = 0x584,
- MSR_RTIT_ADDR2_B = 0x585,
- MSR_RTIT_ADDR3_A = 0x586,
- MSR_RTIT_ADDR3_B = 0x587,
- MSR_DS_AREA = 0x600,
- MSR_TSC_DEADLINE = 0x6E0,
- MSR_PM_ENABLE = 0x770,
- MSR_HWP_CAPABILITIES = 0x771,
- MSR_HWP_REQUEST_PKG = 0x772,
- MSR_HWP_INTERRUPT = 0x773,
- MSR_HWP_REQUEST = 0x774,
- MSR_HWP_STATUS = 0x777,
- MSR_X2APIC_APICID = 0x802,
- MSR_X2APIC_VERSION = 0x803,
- MSR_X2APIC_TPR = 0x808,
- MSR_X2APIC_PPR = 0x80A,
- MSR_X2APIC_EOI = 0x80B,
- MSR_X2APIC_LDR = 0x80D,
- MSR_X2APIC_SIVR = 0x80F,
- MSR_X2APIC_ISR0 = 0x810,
- MSR_X2APIC_ISR1 = 0x811,
- MSR_X2APIC_ISR2 = 0x812,
- MSR_X2APIC_ISR3 = 0x813,
- MSR_X2APIC_ISR4 = 0x814,
- MSR_X2APIC_ISR5 = 0x815,
- MSR_X2APIC_ISR6 = 0x816,
- MSR_X2APIC_ISR7 = 0x817,
- MSR_X2APIC_TMR0 = 0x818,
- MSR_X2APIC_TMR1 = 0x819,
- MSR_X2APIC_TMR2 = 0x81A,
- MSR_X2APIC_TMR3 = 0x81B,
- MSR_X2APIC_TMR4 = 0x81C,
- MSR_X2APIC_TMR5 = 0x81D,
- MSR_X2APIC_TMR6 = 0x81E,
- MSR_X2APIC_TMR7 = 0x81F,
- MSR_X2APIC_IRR0 = 0x820,
- MSR_X2APIC_IRR1 = 0x821,
- MSR_X2APIC_IRR2 = 0x822,
- MSR_X2APIC_IRR3 = 0x823,
- MSR_X2APIC_IRR4 = 0x824,
- MSR_X2APIC_IRR5 = 0x825,
- MSR_X2APIC_IRR6 = 0x826,
- MSR_X2APIC_IRR7 = 0x827,
- MSR_X2APIC_ESR = 0x828,
- MSR_X2APIC_LVT_CMCI = 0x82F,
- MSR_X2APIC_ICR = 0x830,
- MSR_X2APIC_LVT_TIMER = 0x832,
- MSR_X2APIC_LVT_THERMAL = 0x833,
- MSR_X2APIC_LVT_PMI = 0x834,
- MSR_X2APIC_LVT_LINT0 = 0x835,
- MSR_X2APIC_LVT_LINT1 = 0x836,
- MSR_X2APIC_LVT_ERROR = 0x837,
- MSR_X2APIC_INIT_COUNT = 0x838,
- MSR_X2APIC_CUR_COUNT = 0x839,
- MSR_X2APIC_DIV_CONF = 0x83E,
- MSR_X2APIC_SELF_IPI = 0x83F,
- MSR_DEBUG_INTERFACE = 0xC80,
- MSR_L3_QOS_CFG = 0xC81,
- MSR_L2_QOS_CFG = 0xC82,
- MSR_QM_EVTSEL = 0xC8D,
- MSR_QM_CTR = 0xC8E,
- MSR_PQR_ASSOC = 0xC8F,
- MSR_L3_MASK_0 = 0xC90,
- MSR_L2_MASK_0 = 0xD10,
- MSR_BNDCFGS = 0xD90,
- MSR_XSS = 0xDA0,
- MSR_PKG_HDC_CTL = 0xDB0,
- MSR_PM_CTL1 = 0xDB1,
- MSR_THREAD_STALL = 0xDB2,
- /** @brief Extended Feature Enable Register (0xc0000080) */
- MSR_EFER = 0xC0000080,
- /** @brief legacy SYSCALL (0xC0000081) */
- MSR_STAR = 0xC0000081,
- /** @brief 64bit SYSCALL (0xC0000082) */
- MSR_LSTAR = 0xC0000082,
- /** @brief compatibility mode SYSCALL (0xC0000083) */
- MSR_CSTAR = 0xC0000083,
- /** @brief EFLAGS mask for syscall (0xC0000084) */
- MSR_SYSCALL_MASK = 0xC0000084,
- /** @brief 64bit FS base (0xC0000100) */
- MSR_FS_BASE = 0xC0000100,
- /** @brief 64bit GS base (0xC0000101) */
- MSR_GS_BASE = 0xC0000101,
- /** @brief SwapGS GS shadow (0xC0000102) */
- MSR_SHADOW_GS_BASE = 0xC0000102,
- /** @brief Auxiliary TSC (0xC0000103) */
- MSR_TSC_AUX = 0xC0000103,
- MSR_CR_PAT = 0x00000277,
- };
-
-#if defined(__i386__)
- nsa static inline uint64_t rdmsr(uint32_t msr)
- {
- uint32_t Low, High;
- asmv("rdmsr"
- : "=a"(Low), "=d"(High)
- : "c"(msr)
- : "memory");
- return ((uint64_t)Low) | (((uint64_t)High) << 32);
- }
-
- nsa static inline void wrmsr(uint32_t msr, uint64_t Value)
- {
- uint32_t Low = (uint32_t)Value, High = (uint32_t)(Value >> 32);
- asmv("wrmsr"
- :
- : "c"(msr), "a"(Low), "d"(High)
- : "memory");
- }
-#endif
- }
-}
-
-#endif // !__FENNIX_KERNEL_CPU_x32_MSR_H__
diff --git a/Kernel/include/interface/fs.h b/Kernel/include/interface/fs.h
index 27718cd7..23e19f14 100644
--- a/Kernel/include/interface/fs.h
+++ b/Kernel/include/interface/fs.h
@@ -146,10 +146,10 @@ static_assert(sizeof(blkcnt_t) == 8, "blkcnt_t must be 64 bits");
#else
static_assert(sizeof(dev_t) == 4, "dev_t must be 32 bits");
static_assert(sizeof(ino_t) == 4, "ino_t must be 32 bits");
-static_assert(sizeof(mode_t) == 2, "mode_t must be 16 bits");
-static_assert(sizeof(nlink_t) == 2, "nlink_t must be 16 bits");
-static_assert(sizeof(uid_t) == 2, "uid_t must be 16 bits");
-static_assert(sizeof(gid_t) == 2, "gid_t must be 16 bits");
+static_assert(sizeof(mode_t) == 4, "mode_t must be 32 bits");
+static_assert(sizeof(nlink_t) == 4, "nlink_t must be 32 bits");
+static_assert(sizeof(uid_t) == 4, "uid_t must be 32 bits");
+static_assert(sizeof(gid_t) == 4, "gid_t must be 32 bits");
static_assert(sizeof(off_t) == 4, "off_t must be 32 bits");
static_assert(sizeof(time_t) == 4, "time_t must be 32 bits");
static_assert(sizeof(blksize_t) == 4, "blksize_t must be 32 bits");
diff --git a/Kernel/include/interface/syscalls.h b/Kernel/include/interface/syscalls.h
index bde19d03..d0cab647 100644
--- a/Kernel/include/interface/syscalls.h
+++ b/Kernel/include/interface/syscalls.h
@@ -33,10 +33,16 @@
static inline scarg syscall0(scarg syscall)
{
scarg ret;
+#if defined(__amd64__)
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -52,10 +58,16 @@ static inline scarg syscall0(scarg syscall)
static inline scarg syscall1(scarg syscall, scarg arg1)
{
scarg ret;
+#if defined(__amd64__)
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -72,10 +84,16 @@ static inline scarg syscall1(scarg syscall, scarg arg1)
static inline scarg syscall2(scarg syscall, scarg arg1, scarg arg2)
{
scarg ret;
+#if defined(__amd64__)
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -93,10 +111,16 @@ static inline scarg syscall2(scarg syscall, scarg arg1, scarg arg2)
static inline scarg syscall3(scarg syscall, scarg arg1, scarg arg2, scarg arg3)
{
scarg ret;
+#if defined(__amd64__)
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -115,11 +139,17 @@ static inline scarg syscall3(scarg syscall, scarg arg1, scarg arg2, scarg arg3)
static inline scarg syscall4(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4)
{
scarg ret;
+#if defined(__amd64__)
register scarg r10 __asm__("r10") = arg4;
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -139,12 +169,18 @@ static inline scarg syscall4(scarg syscall, scarg arg1, scarg arg2, scarg arg3,
static inline scarg syscall5(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4, scarg arg5)
{
scarg ret;
+#if defined(__amd64__)
register scarg r10 __asm__("r10") = arg4;
register scarg r8 __asm__("r8") = arg5;
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -165,6 +201,7 @@ static inline scarg syscall5(scarg syscall, scarg arg1, scarg arg2, scarg arg3,
static inline scarg syscall6(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4, scarg arg5, scarg arg6)
{
scarg ret;
+#if defined(__amd64__)
register scarg r10 __asm__("r10") = arg4;
register scarg r8 __asm__("r8") = arg5;
register scarg r9 __asm__("r9") = arg6;
@@ -172,6 +209,11 @@ static inline scarg syscall6(scarg syscall, scarg arg1, scarg arg2, scarg arg3,
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8), "r"(r9)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
diff --git a/Kernel/include/memory/virtual.hpp b/Kernel/include/memory/virtual.hpp
index aa336421..4afc5d65 100644
--- a/Kernel/include/memory/virtual.hpp
+++ b/Kernel/include/memory/virtual.hpp
@@ -61,7 +61,7 @@ namespace Memory
* @param Flag Flag to check
* @return true if page has the specified flag, false otherwise.
*/
- bool Check(void *VirtualAddress, PTFlag Flag = PTFlag::P);
+ bool Check(void *VirtualAddress, PTFlag Flag = PTFlag::P, MapType Type = MapType::FourKiB);
/**
* @brief Check if the region has the specified flag.
diff --git a/Kernel/include/signal.hpp b/Kernel/include/signal.hpp
index bbafb57d..3b338452 100644
--- a/Kernel/include/signal.hpp
+++ b/Kernel/include/signal.hpp
@@ -249,7 +249,7 @@ namespace Tasking
#else
CPU::x32::FXState fx;
CPU::x32::SchedulerFrame tf;
- uintptr_t GSBase, FSBase;
+ uintptr_t GSBase, FSBase, ShadowGSBase;
#endif
sigset_t SignalMask;
int Compatibility;
@@ -354,8 +354,8 @@ namespace Tasking
int AddSignal(signal_t sig, union sigval val = {0}, pid_t tid = -1);
int RemoveSignal(signal_t sig);
- bool HandleSignal(CPU::SchedulerFrame *tf, void *thread);
- void RestoreHandleSignal(SyscallsFrame *tf, void *thread);
+ arch bool HandleSignal(CPU::SchedulerFrame *tf, void *thread);
+ arch void RestoreHandleSignal(SyscallsFrame *tf, void *thread);
int SetAction(signal_t sig, const SignalAction *act);
int GetAction(signal_t sig, SignalAction *act);
diff --git a/Kernel/include/task.hpp b/Kernel/include/task.hpp
index eb3cc68d..cf3ab26e 100644
--- a/Kernel/include/task.hpp
+++ b/Kernel/include/task.hpp
@@ -355,11 +355,10 @@ namespace Tasking
ThreadSignal Signals;
/* CPU state */
+ CPU::SchedulerFrame Registers{};
#if defined(__amd64__)
- CPU::x64::SchedulerFrame Registers{};
uintptr_t ShadowGSBase, GSBase, FSBase;
#elif defined(__i386__)
- CPU::x32::SchedulerFrame Registers{};
uintptr_t ShadowGSBase, GSBase, FSBase;
#elif defined(__aarch64__)
uintptr_t Registers; // TODO
diff --git a/Kernel/include/types.h b/Kernel/include/types.h
index 2438007c..5b782c42 100644
--- a/Kernel/include/types.h
+++ b/Kernel/include/types.h
@@ -20,6 +20,14 @@
#include
+/**
+ * It doesn't do anything.
+ *
+ * Used to specify a function that is dependent on the architecture.
+ * It's architecture specific variant is defined in arch//...
+ */
+#define arch
+
#ifdef __cplusplus
#define EXTERNC extern "C"
#define START_EXTERNC \
@@ -166,17 +174,17 @@ typedef int32_t pid_t;
#elif defined(__i386__)
typedef int32_t off_t;
typedef long long off64_t;
-typedef __INT32_TYPE__ mode_t;
+typedef uint32_t mode_t;
typedef int32_t dev_t;
typedef int32_t ino64_t;
typedef int32_t ino_t;
-typedef unsigned int nlink_t;
+typedef uint32_t nlink_t;
typedef int blksize_t;
typedef int32_t blkcnt_t;
typedef int32_t blkcnt64_t;
typedef int32_t time_t;
-typedef unsigned uid_t;
-typedef unsigned gid_t;
+typedef uint32_t uid_t;
+typedef uint32_t gid_t;
typedef long clock_t;
typedef int pid_t;
#endif
diff --git a/Kernel/library/simd_memset.cpp b/Kernel/library/simd_memset.cpp
index a5647aad..acb3fdde 100644
--- a/Kernel/library/simd_memset.cpp
+++ b/Kernel/library/simd_memset.cpp
@@ -54,6 +54,7 @@ EXTERNC void *memset_sse2(void *dest, int c, size_t n)
for (; i + 64 <= n; i += 64)
{
+#if defined(__amd64__)
asmv("movd %0, %%xmm0\n"
"movdqa %%xmm0, (%1)\n"
"movdqa %%xmm0, 16(%1)\n"
@@ -62,6 +63,9 @@ EXTERNC void *memset_sse2(void *dest, int c, size_t n)
:
: "r"(c), "r"(((size_t)dest) + i)
: "xmm0");
+#else
+#warning "memset_sse2 not implemented for other arch"
+#endif
}
asmv("rep stosb\n" ::"a"((size_t)(c)),
diff --git a/Kernel/subsystem/linux/syscall.cpp b/Kernel/subsystem/linux/syscall.cpp
index 031d6b14..60c970ff 100644
--- a/Kernel/subsystem/linux/syscall.cpp
+++ b/Kernel/subsystem/linux/syscall.cpp
@@ -627,9 +627,15 @@ void SetSigActToNative(const k_sigaction *linux, SignalAction *native)
native->Flags = linux->flags;
native->Restorer = linux->restorer;
+#if defined(__amd64__)
unsigned long mask = ((unsigned long)linux->mask[1] << 32) | linux->mask[0];
native->Mask = std::bitset<64>(ConvertMaskToNative(mask));
debug("m0:%#lx m1:%#lx | n:%#lx", linux->mask[0], linux->mask[1], native->Mask);
+#elif defined(__i386__)
+#warning "SetSigActToNative not implemented for i386"
+#elif defined(__aarch64__)
+#warning "SetSigActToNative not implemented for aarch64"
+#endif
}
void SetSigActToLinux(const SignalAction *native, k_sigaction *linux)
@@ -638,12 +644,18 @@ void SetSigActToLinux(const SignalAction *native, k_sigaction *linux)
linux->flags = native->Flags;
linux->restorer = native->Restorer;
+#if defined(__amd64__)
unsigned long mask = native->Mask.to_ulong();
mask = ConvertMaskToLinux(mask);
linux->mask[0] = mask & 0xFFFFFFFF;
linux->mask[1] = (uint32_t)((mask >> 32) & 0xFFFFFFFF);
debug("m0:%#lx m1:%#lx | n:%#lx", linux->mask[0], linux->mask[1], native->Mask);
+#elif defined(__i386__)
+#warning "SetSigActToLinux not implemented for i386"
+#elif defined(__aarch64__)
+#warning "SetSigActToLinux not implemented for aarch64"
+#endif
}
struct kstat KStatToStat(struct linux_kstat linux_stat)
@@ -2501,41 +2513,31 @@ static int linux_arch_prctl(SysFrm *, int code, unsigned long addr)
{
case linux_ARCH_SET_GS:
{
-#if defined(__amd64__)
- CPU::x64::wrmsr(CPU::x64::MSRID::MSR_GS_BASE, addr);
-#elif defined(__i386__)
- CPU::x32::wrmsr(CPU::x32::MSRID::MSR_GS_BASE, addr);
+#if defined(__amd64__) || defined(__i386__)
+ CPU::x86::wrmsr(CPU::x86::MSRID::MSR_GS_BASE, addr);
#endif
return 0;
}
case linux_ARCH_SET_FS:
{
-#if defined(__amd64__)
- CPU::x64::wrmsr(CPU::x64::MSRID::MSR_FS_BASE, addr);
-#elif defined(__i386__)
- CPU::x32::wrmsr(CPU::x32::MSRID::MSR_FS_BASE, addr);
+#if defined(__amd64__) || defined(__i386__)
+ CPU::x86::wrmsr(CPU::x86::MSRID::MSR_FS_BASE, addr);
#endif
return 0;
}
case linux_ARCH_GET_FS:
{
-#if defined(__amd64__)
+#if defined(__amd64__) || defined(__i386__)
*r_cst(uint64_t *, addr) =
- CPU::x64::rdmsr(CPU::x64::MSRID::MSR_FS_BASE);
-#elif defined(__i386__)
- *r_cst(uint64_t *, addr) =
- CPU::x32::rdmsr(CPU::x32::MSRID::MSR_FS_BASE);
+ CPU::x86::rdmsr(CPU::x86::MSRID::MSR_FS_BASE);
#endif
return 0;
}
case linux_ARCH_GET_GS:
{
-#if defined(__amd64__)
+#if defined(__amd64__) || defined(__i386__)
*r_cst(uint64_t *, addr) =
- CPU::x64::rdmsr(CPU::x64::MSRID::MSR_GS_BASE);
-#elif defined(__i386__)
- *r_cst(uint64_t *, addr) =
- CPU::x32::rdmsr(CPU::x32::MSRID::MSR_GS_BASE);
+ CPU::x86::rdmsr(CPU::x86::MSRID::MSR_GS_BASE);
#endif
return 0;
}
@@ -2899,13 +2901,17 @@ __no_sanitize("undefined") static ssize_t linux_getdents64(SysFrm *,
if (pDirp == nullptr)
return -linux_EFAULT;
- /* Sanity checks */
+/* Sanity checks */
+#ifdef __LP64__
static_assert(sizeof(kdirent) == sizeof(linux_dirent64));
static_assert(offsetof(kdirent, d_ino) == offsetof(linux_dirent64, d_ino));
static_assert(offsetof(kdirent, d_off) == offsetof(linux_dirent64, d_off));
static_assert(offsetof(kdirent, d_reclen) == offsetof(linux_dirent64, d_reclen));
static_assert(offsetof(kdirent, d_type) == offsetof(linux_dirent64, d_type));
static_assert(offsetof(kdirent, d_name) == offsetof(linux_dirent64, d_name));
+#else
+#warning "Not implemented for 32-bit"
+#endif
/* The structs are the same, no need for conversion. */
ssize_t ret = fildes.Node->ReadDir((struct kdirent *)pDirp, count, fildes.Offset,
@@ -4290,14 +4296,14 @@ uintptr_t HandleLinuxSyscalls(SyscallsFrame *Frame)
debug("< [%ld:\"%s\"] = %ld", Frame->ax, Syscall.Name, sc_ret);
return sc_ret;
#elif defined(__i386__)
- if (Frame->eax > sizeof(LinuxSyscallsTableI386) / sizeof(SyscallData))
+ if (Frame->ax > sizeof(LinuxSyscallsTableI386) / sizeof(SyscallData))
{
fixme("Syscall %d not implemented",
- Frame->eax);
+ Frame->ax);
return -linux_ENOSYS;
}
- SyscallData Syscall = LinuxSyscallsTableI386[Frame->eax];
+ SyscallData Syscall = LinuxSyscallsTableI386[Frame->ax];
long (*call)(SysFrm *, long, ...) = r_cst(long (*)(SysFrm *, long, ...),
Syscall.Handler);
@@ -4305,20 +4311,20 @@ uintptr_t HandleLinuxSyscalls(SyscallsFrame *Frame)
if (unlikely(!call))
{
fixme("Syscall %s(%d) not implemented",
- Syscall.Name, Frame->eax);
+ Syscall.Name, Frame->ax);
return -linux_ENOSYS;
}
debug("> [%d:\"%s\"]( %#lx %#lx %#lx %#lx %#lx %#lx )",
- Frame->eax, Syscall.Name,
- Frame->ebx, Frame->ecx, Frame->edx,
- Frame->esi, Frame->edi, Frame->ebp);
+ Frame->ax, Syscall.Name,
+ Frame->bx, Frame->cx, Frame->dx,
+ Frame->si, Frame->di, Frame->bp);
int sc_ret = call(Frame,
- Frame->ebx, Frame->ecx, Frame->edx,
- Frame->esi, Frame->edi, Frame->ebp);
+ Frame->bx, Frame->cx, Frame->dx,
+ Frame->si, Frame->di, Frame->bp);
- debug("< [%d:\"%s\"] = %d", Frame->eax, Syscall.Name, sc_ret);
+ debug("< [%d:\"%s\"] = %d", Frame->ax, Syscall.Name, sc_ret);
return sc_ret;
#elif defined(__aarch64__)
return -linux_ENOSYS;
diff --git a/Kernel/syscalls/native.cpp b/Kernel/syscalls/native.cpp
index 9a8649c8..abdf91e3 100644
--- a/Kernel/syscalls/native.cpp
+++ b/Kernel/syscalls/native.cpp
@@ -255,19 +255,15 @@ static int sys_prctl(SysFrm *Frame, prctl_options_t option, unsigned long arg1,
if (arg == nullptr)
return -EFAULT;
-#if defined(__amd64__)
- *r_cst(uintptr_t *, arg) = CPU::x64::rdmsr(CPU::x64::MSRID::MSR_GS_BASE);
-#elif defined(__i386__)
- *r_cst(uintptr_t *, arg) = CPU::x32::rdmsr(CPU::x32::MSRID::MSR_GS_BASE);
+#if defined(__amd64__) || defined(__i386__)
+ *r_cst(uintptr_t *, arg) = CPU::x86::rdmsr(CPU::x86::MSRID::MSR_GS_BASE);
#endif
return 0;
}
case __SYS_SET_GS:
{
-#if defined(__amd64__)
- CPU::x64::wrmsr(CPU::x64::MSRID::MSR_GS_BASE, arg1);
-#elif defined(__i386__)
- CPU::x32::wrmsr(CPU::x32::MSRID::MSR_GS_BASE, arg1);
+#if defined(__amd64__) || defined(__i386__)
+ CPU::x86::wrmsr(CPU::x86::MSRID::MSR_GS_BASE, arg1);
#endif
return 0;
}
@@ -277,19 +273,15 @@ static int sys_prctl(SysFrm *Frame, prctl_options_t option, unsigned long arg1,
if (arg == nullptr)
return -EFAULT;
-#if defined(__amd64__)
- *r_cst(uintptr_t *, arg) = CPU::x64::rdmsr(CPU::x64::MSRID::MSR_FS_BASE);
-#elif defined(__i386__)
- *r_cst(uintptr_t *, arg) = CPU::x32::rdmsr(CPU::x32::MSRID::MSR_FS_BASE);
+#if defined(__amd64__) || defined(__i386__)
+ *r_cst(uintptr_t *, arg) = CPU::x86::rdmsr(CPU::x86::MSRID::MSR_FS_BASE);
#endif
return 0;
}
case __SYS_SET_FS:
{
-#if defined(__amd64__)
- CPU::x64::wrmsr(CPU::x64::MSRID::MSR_FS_BASE, arg1);
-#elif defined(__i386__)
- CPU::x32::wrmsr(CPU::x32::MSRID::MSR_FS_BASE, arg1);
+#if defined(__amd64__) || defined(__i386__)
+ CPU::x86::wrmsr(CPU::x86::MSRID::MSR_FS_BASE, arg1);
#endif
return 0;
}
diff --git a/Kernel/tasking/scheduler/custom.cpp b/Kernel/tasking/scheduler/custom.cpp
index 4558f1b9..3153923c 100644
--- a/Kernel/tasking/scheduler/custom.cpp
+++ b/Kernel/tasking/scheduler/custom.cpp
@@ -195,7 +195,7 @@ namespace Tasking::Scheduler
void Custom::StartScheduler()
{
-#if defined(__amd64__) || defined(__i386__)
+#if defined(__amd64__)
if (Interrupts::apicTimer[0])
{
((APIC::Timer *)Interrupts::apicTimer[0])->OneShot(CPU::x86::IRQ16, 100);
@@ -587,15 +587,11 @@ namespace Tasking::Scheduler
else
{
CurrentCPU->CurrentThread->Registers = *Frame;
- CPU::x64::fxsave(&CurrentCPU->CurrentThread->FPU);
-#ifdef __amd64__
- CurrentCPU->CurrentThread->ShadowGSBase = CPU::x64::rdmsr(CPU::x64::MSR_SHADOW_GS_BASE);
- CurrentCPU->CurrentThread->GSBase = CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE);
- CurrentCPU->CurrentThread->FSBase = CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE);
-#else
- CurrentCPU->CurrentThread->ShadowGSBase = uintptr_t(CPU::x32::rdmsr(CPU::x32::MSR_SHADOW_GS_BASE));
- CurrentCPU->CurrentThread->GSBase = uintptr_t(CPU::x32::rdmsr(CPU::x32::MSR_GS_BASE));
- CurrentCPU->CurrentThread->FSBase = uintptr_t(CPU::x32::rdmsr(CPU::x32::MSR_FS_BASE));
+#if defined(__amd64__) || defined(__i386__)
+ CPU::x86::fxsave(&CurrentCPU->CurrentThread->FPU);
+ CurrentCPU->CurrentThread->ShadowGSBase = CPU::x86::rdmsr(CPU::x86::MSR_SHADOW_GS_BASE);
+ CurrentCPU->CurrentThread->GSBase = CPU::x86::rdmsr(CPU::x86::MSR_GS_BASE);
+ CurrentCPU->CurrentThread->FSBase = CPU::x86::rdmsr(CPU::x86::MSR_FS_BASE);
#endif
if (CurrentCPU->CurrentProcess->State.load() == TaskState::Running)
@@ -681,18 +677,12 @@ namespace Tasking::Scheduler
*Frame = CurrentCPU->CurrentThread->Registers;
-#ifdef __amd64__
+#if defined(__amd64__) || defined(__i386__)
GlobalDescriptorTable::SetKernelStack((void *)((uintptr_t)CurrentCPU->CurrentThread->Stack->GetStackTop()));
- CPU::x64::fxrstor(&CurrentCPU->CurrentThread->FPU);
- CPU::x64::wrmsr(CPU::x64::MSR_SHADOW_GS_BASE, CurrentCPU->CurrentThread->ShadowGSBase);
- CPU::x64::wrmsr(CPU::x64::MSR_GS_BASE, CurrentCPU->CurrentThread->GSBase);
- CPU::x64::wrmsr(CPU::x64::MSR_FS_BASE, CurrentCPU->CurrentThread->FSBase);
-#else
- GlobalDescriptorTable::SetKernelStack((void *)((uintptr_t)CurrentCPU->CurrentThread->Stack->GetStackTop()));
- CPU::x32::fxrstor(&CurrentCPU->CurrentThread->FPU);
- CPU::x32::wrmsr(CPU::x32::MSR_SHADOW_GS_BASE, CurrentCPU->CurrentThread->ShadowGSBase);
- CPU::x32::wrmsr(CPU::x32::MSR_GS_BASE, CurrentCPU->CurrentThread->GSBase);
- CPU::x32::wrmsr(CPU::x32::MSR_FS_BASE, CurrentCPU->CurrentThread->FSBase);
+ CPU::x86::fxrstor(&CurrentCPU->CurrentThread->FPU);
+ CPU::x86::wrmsr(CPU::x86::MSR_SHADOW_GS_BASE, CurrentCPU->CurrentThread->ShadowGSBase);
+ CPU::x86::wrmsr(CPU::x86::MSR_GS_BASE, CurrentCPU->CurrentThread->GSBase);
+ CPU::x86::wrmsr(CPU::x86::MSR_FS_BASE, CurrentCPU->CurrentThread->FSBase);
#endif
CurrentCPU->CurrentProcess->Signals.HandleSignal(Frame, CurrentCPU->CurrentThread.load());
diff --git a/Kernel/tasking/signal.cpp b/Kernel/tasking/signal.cpp
index 488b5fa8..765bee9c 100644
--- a/Kernel/tasking/signal.cpp
+++ b/Kernel/tasking/signal.cpp
@@ -20,13 +20,6 @@
#include
#include
-#if defined(__amd64__)
-#include "../arch/amd64/cpu/gdt.hpp"
-#elif defined(__i386__)
-#include "../arch/i386/cpu/gdt.hpp"
-#elif defined(__aarch64__)
-#endif
-
#include "../kernel.h"
#ifdef DEBUG
@@ -344,149 +337,6 @@ namespace Tasking
return {};
}
- bool Signal::HandleSignal(CPU::SchedulerFrame *tf, void *thread)
- {
- /* We don't want to do this in kernel mode */
- if (tf->cs != GDT_USER_CODE)
- return false;
-
- if (Queue.empty())
- return false;
-
- debug("We have %d signals to handle", Queue.size());
-
- SmartLock(SignalLock);
- SignalInfo sigI = GetAvailableSignal(thread);
- if (sigI.sig == SIGNULL)
- return false;
-
- uintptr_t _p_rsp = ((PCB *)ctx)->PageTable->Get(tf->rsp);
- uint64_t paRsp = _p_rsp;
- paRsp &= ~0xF; /* Align */
- paRsp -= 128; /* Red zone */
-
- /* Calculate the virtual rsp */
- uintptr_t _v_rsp = tf->rsp;
- _v_rsp &= ~0xF; /* Align */
- _v_rsp -= 128; /* Red zone */
- uint64_t *vRsp = (uint64_t *)(_v_rsp - sizeof(StackInfo));
- vRsp--; /* Alignment */
- vRsp--; /* Handler Address */
- assert(!((uintptr_t)vRsp & 0xF));
-
- /* Add the stack info */
- StackInfo si{};
- CPU::x64::fxsave(&si.fx);
- si.tf = *tf;
- si.GSBase = CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE);
- si.FSBase = CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE);
- si.ShadowGSBase = CPU::x64::rdmsr(CPU::x64::MSR_SHADOW_GS_BASE);
- si.SignalMask = ((TCB *)thread)->Signals.Mask.to_ulong();
- si.Compatibility = ((PCB *)ctx)->Info.Compatibility;
-
- debug("gs: %#lx fs: %#lx shadow: %#lx",
- si.GSBase, si.FSBase, si.ShadowGSBase);
-
- /* Copy the stack info */
- uint64_t *pRsp = (uint64_t *)(paRsp - sizeof(StackInfo));
- memcpy(pRsp, &si, sizeof(StackInfo));
-
- /* Set the handler address */
- pRsp--; /* Alignment */
- pRsp--;
- *pRsp = uint64_t(sa[sigI.sig].sa_handler.Handler);
-
- assert(!((uintptr_t)pRsp & 0xF));
-
- int cSig = LinuxSig() ? ConvertSignalToLinux((signal_t)sigI.sig) : sigI.sig;
-
-#ifdef DEBUG
- DumpData("Stack Data", (void *)pRsp,
- paRsp - uint64_t(pRsp));
- debug("initial stack tf->rsp: %#lx after: %#lx",
- tf->rsp, uint64_t(vRsp));
- debug("sig: %d -> %d", sigI.sig, cSig);
-#endif
-
- tf->rsp = uint64_t(vRsp);
- tf->rip = uint64_t(TrampAddr);
-
- /* void func(int signo); */
- /* void func(int signo, siginfo_t *info, void *context); */
- tf->rdi = cSig;
- if (sa[sigI.sig].Flags & SA_SIGINFO)
- {
- fixme("SA_SIGINFO not implemented");
- siginfo_t *info = 0;
- void *context = 0;
- tf->rsi = uint64_t(info);
- tf->rdx = uint64_t(context);
- tf->rcx = 0;
- tf->r8 = 0;
- tf->r9 = 0;
- }
- else
- {
- tf->rsi = 0;
- tf->rdx = 0;
- tf->rcx = 0;
- tf->r8 = 0;
- tf->r9 = 0;
- }
-
- ((TCB *)thread)->Signals.Mask = sa[sigI.sig].Mask;
- assert(TrampAddr != nullptr);
- return true;
- }
-
- void Signal::RestoreHandleSignal(SyscallsFrame *sf, void *thread)
- {
- debug("Restoring signal handler");
- SmartLock(SignalLock);
-
- gsTCB *gs = (gsTCB *)CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE);
- uint64_t *sp = (uint64_t *)((PCB *)ctx)->PageTable->Get(gs->TempStack);
- sp++; /* Alignment */
- sp++; /* Handler Address */
-
- assert(!((uintptr_t)sp & 0xF));
-
- StackInfo *si = (StackInfo *)sp;
- assert(si != nullptr);
-
- sf->r15 = si->tf.r15;
- sf->r14 = si->tf.r14;
- sf->r13 = si->tf.r13;
- sf->r12 = si->tf.r12;
- sf->r11 = si->tf.r11;
- sf->r10 = si->tf.r10;
- sf->r9 = si->tf.r9;
- sf->r8 = si->tf.r8;
- sf->bp = si->tf.rbp;
- sf->di = si->tf.rdi;
- sf->si = si->tf.rsi;
- sf->dx = si->tf.rdx;
- sf->cx = si->tf.rcx;
- sf->bx = si->tf.rbx;
- sf->ax = si->tf.rax;
- sf->Flags = si->tf.rflags.raw;
- sf->ReturnAddress = si->tf.rip;
- gs->TempStack = (void *)si->tf.rsp;
-
- ((TCB *)thread)->Signals.Mask = si->SignalMask;
-
- CPU::x64::fxrstor(&si->fx);
- CPU::x64::wrmsr(CPU::x64::MSR_GS_BASE, si->ShadowGSBase);
- CPU::x64::wrmsr(CPU::x64::MSR_FS_BASE, si->FSBase);
- CPU::x64::wrmsr(CPU::x64::MSR_SHADOW_GS_BASE, si->GSBase);
- debug("gs: %#lx fs: %#lx shadow: %#lx",
- si->GSBase, si->FSBase, si->ShadowGSBase);
-
- // ((PCB *)ctx)->GetContext()->Yield();
- // __builtin_unreachable();
- /* Return because we will restore at sysretq */
- }
-
int Signal::SetAction(signal_t sig, const SignalAction *act)
{
SmartLock(SignalLock);
diff --git a/Kernel/tasking/task.cpp b/Kernel/tasking/task.cpp
index 0f42053b..6b051ed3 100644
--- a/Kernel/tasking/task.cpp
+++ b/Kernel/tasking/task.cpp
@@ -222,12 +222,12 @@ namespace Tasking
TCB *Task::CreateThread(PCB *Parent, IP EntryPoint,
const char **argv, const char **envp,
const std::vector &auxv,
- TaskArchitecture arch, TaskCompatibility Compatibility,
+ TaskArchitecture _arch, TaskCompatibility Compatibility,
bool ThreadNotReady)
{
SmartLock(TaskingLock);
return new TCB(this, Parent, EntryPoint,
- argv, envp, auxv, arch,
+ argv, envp, auxv, _arch,
Compatibility, ThreadNotReady);
}
diff --git a/Kernel/tasking/thread.cpp b/Kernel/tasking/thread.cpp
index 374d0b1e..d15a9421 100644
--- a/Kernel/tasking/thread.cpp
+++ b/Kernel/tasking/thread.cpp
@@ -485,9 +485,9 @@ namespace Tasking
#if defined(__amd64__)
this->ShadowGSBase =
- CPU::x64::rdmsr(CPU::x64::MSRID::MSR_SHADOW_GS_BASE);
- this->GSBase = CPU::x64::rdmsr(CPU::x64::MSRID::MSR_GS_BASE);
- this->FSBase = CPU::x64::rdmsr(CPU::x64::MSRID::MSR_FS_BASE);
+ CPU::x86::rdmsr(CPU::x86::MSRID::MSR_SHADOW_GS_BASE);
+ this->GSBase = CPU::x86::rdmsr(CPU::x86::MSRID::MSR_GS_BASE);
+ this->FSBase = CPU::x86::rdmsr(CPU::x86::MSRID::MSR_FS_BASE);
this->Registers.cs = GDT_KERNEL_CODE;
this->Registers.ss = GDT_KERNEL_DATA;
this->Registers.rflags.AlwaysOne = 1;
@@ -498,7 +498,7 @@ namespace Tasking
POKE(uintptr_t, this->Registers.rsp) = (uintptr_t)ThreadDoExit;
#elif defined(__i386__)
this->Registers.cs = GDT_KERNEL_CODE;
- this->Registers.r3_ss = GDT_KERNEL_DATA;
+ this->Registers.ss = GDT_KERNEL_DATA;
this->Registers.eflags.AlwaysOne = 1;
this->Registers.eflags.IF = 1;
this->Registers.eflags.ID = 1;
@@ -520,7 +520,13 @@ namespace Tasking
this->ctx->va.MapTo(gst, this->Parent->PageTable);
gsTCB *gsT = (gsTCB *)gst.PhysicalAddress;
#ifdef DEBUG
+#if defined(__amd64__)
gsT->__stub = 0xFFFFFFFFFFFFFFFF;
+#elif defined(__i386__)
+ gsT->__stub = 0xFFFFFFFF;
+#elif defined(__aarch64__)
+ gsT->__stub = 0xFFFFFFFFFFFFFFFF;
+#endif
#endif
gsT->ScPages = TO_PAGES(STACK_SIZE);
@@ -552,7 +558,7 @@ namespace Tasking
this->SetupUserStack_x86_64(argv, envp, auxv, Compatibility);
#elif defined(__i386__)
this->Registers.cs = GDT_USER_CODE;
- this->Registers.r3_ss = GDT_USER_DATA;
+ this->Registers.ss = GDT_USER_DATA;
this->Registers.eflags.AlwaysOne = 1;
this->Registers.eflags.IF = 1;
this->Registers.eflags.ID = 1;
@@ -562,9 +568,9 @@ namespace Tasking
is exited or we are going to get
an exception. */
- this->SetupUserStack_x86_32(argv, envp, auxv);
+ this->SetupUserStack_x86_32(argv, envp, auxv, Compatibility);
#elif defined(__aarch64__)
- this->SetupUserStack_aarch64(argv, envp, auxv);
+ this->SetupUserStack_aarch64(argv, envp, auxv, Compatibility);
#endif
#ifdef DEBUG_TASKING
DumpData(this->Name, this->Stack, STACK_SIZE);
diff --git a/Kernel/tty/vt.cpp b/Kernel/tty/vt.cpp
index ded1eed1..15db878c 100644
--- a/Kernel/tty/vt.cpp
+++ b/Kernel/tty/vt.cpp
@@ -121,9 +121,6 @@ namespace KernelConsole
switch (Request)
{
- case 0xffffffff80045430: /* FIXME: ???? */
- debug("???");
- [[fallthrough]];
case TIOCGPTN:
{
fixme("stub ioctl TIOCGPTN");
diff --git a/LICENSES.md b/LICENSES.md
index 621bdaf2..4208f37b 100644
--- a/LICENSES.md
+++ b/LICENSES.md
@@ -54,6 +54,11 @@ Make sure to read and comply with these licenses before using or redistributing
- **License:** Unlicense and 0BSD
- **Location(s):** [Userspace/libc/interpreter/nanoprintf.h](Userspace/libc/interpreter/nanoprintf.h)
+## arith64.c
+
+- **License:** Unlicense
+- **Location(s):** [Userspace/libc/src/arith64.c](Userspace/libc/src/arith64.c)
+
---
Please refer to the respective license files for the full text of each license.
diff --git a/Userspace/Makefile b/Userspace/Makefile
index 1c4dccfd..1b5d48a4 100644
--- a/Userspace/Makefile
+++ b/Userspace/Makefile
@@ -14,7 +14,7 @@ export LDFLAGS := --sysroot=$(WORKSPACE_DIR)/out/ \
export CFLAGS := \
--sysroot=$(WORKSPACE_DIR)/out/ \
-I$(WORKSPACE_DIR)/out/include \
- -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm
+ -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always
else # DEBUG
diff --git a/Userspace/apps/test/utest/userspace_test.c b/Userspace/apps/test/utest/userspace_test.c
index efae0af1..e99e366a 100644
--- a/Userspace/apps/test/utest/userspace_test.c
+++ b/Userspace/apps/test/utest/userspace_test.c
@@ -92,10 +92,12 @@ typedef struct
static __inline long __musl_syscall1(long n, long a1)
{
unsigned long ret;
+#if defined(__amd64__)
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(n), "D"(a1)
: "rcx", "r11", "memory");
+#endif
return ret;
}
diff --git a/Userspace/libc/include/fennix/syscalls.h b/Userspace/libc/include/fennix/syscalls.h
index bde19d03..d0cab647 100644
--- a/Userspace/libc/include/fennix/syscalls.h
+++ b/Userspace/libc/include/fennix/syscalls.h
@@ -33,10 +33,16 @@
static inline scarg syscall0(scarg syscall)
{
scarg ret;
+#if defined(__amd64__)
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -52,10 +58,16 @@ static inline scarg syscall0(scarg syscall)
static inline scarg syscall1(scarg syscall, scarg arg1)
{
scarg ret;
+#if defined(__amd64__)
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -72,10 +84,16 @@ static inline scarg syscall1(scarg syscall, scarg arg1)
static inline scarg syscall2(scarg syscall, scarg arg1, scarg arg2)
{
scarg ret;
+#if defined(__amd64__)
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -93,10 +111,16 @@ static inline scarg syscall2(scarg syscall, scarg arg1, scarg arg2)
static inline scarg syscall3(scarg syscall, scarg arg1, scarg arg2, scarg arg3)
{
scarg ret;
+#if defined(__amd64__)
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -115,11 +139,17 @@ static inline scarg syscall3(scarg syscall, scarg arg1, scarg arg2, scarg arg3)
static inline scarg syscall4(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4)
{
scarg ret;
+#if defined(__amd64__)
register scarg r10 __asm__("r10") = arg4;
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -139,12 +169,18 @@ static inline scarg syscall4(scarg syscall, scarg arg1, scarg arg2, scarg arg3,
static inline scarg syscall5(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4, scarg arg5)
{
scarg ret;
+#if defined(__amd64__)
register scarg r10 __asm__("r10") = arg4;
register scarg r8 __asm__("r8") = arg5;
__asm__ __volatile__("syscall"
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
@@ -165,6 +201,7 @@ static inline scarg syscall5(scarg syscall, scarg arg1, scarg arg2, scarg arg3,
static inline scarg syscall6(scarg syscall, scarg arg1, scarg arg2, scarg arg3, scarg arg4, scarg arg5, scarg arg6)
{
scarg ret;
+#if defined(__amd64__)
register scarg r10 __asm__("r10") = arg4;
register scarg r8 __asm__("r8") = arg5;
register scarg r9 __asm__("r9") = arg6;
@@ -172,6 +209,11 @@ static inline scarg syscall6(scarg syscall, scarg arg1, scarg arg2, scarg arg3,
: "=a"(ret)
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8), "r"(r9)
: "rcx", "r11", "memory");
+#elif defined(__i386__)
+#warning "i386 syscall wrapper not implemented"
+#else
+#error "Unsupported architecture"
+#endif
return ret;
}
diff --git a/Userspace/libc/interpreter/Makefile b/Userspace/libc/interpreter/Makefile
index d68811a5..27713cc1 100644
--- a/Userspace/libc/interpreter/Makefile
+++ b/Userspace/libc/interpreter/Makefile
@@ -14,7 +14,7 @@ OBJ = ${S_SOURCES:.S=.o} ${C_SOURCES:.c=.o} ${CXX_SOURCES:.cpp=.o}
CFLAGS := -fvisibility=hidden -fPIC -I$(WORKSPACE_DIR)/out/include -DLIBC_GIT_COMMIT='"$(shell git rev-parse HEAD)"'
ifeq ($(DEBUG), 1)
- CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm
+ CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always
endif
build: $(OBJECT_NAME)
diff --git a/Userspace/libc/interpreter/load.c b/Userspace/libc/interpreter/load.c
index 4670a75d..ce8e7dd8 100644
--- a/Userspace/libc/interpreter/load.c
+++ b/Userspace/libc/interpreter/load.c
@@ -124,6 +124,7 @@ ElfInfo *SearchLib(char *Path)
__attribute__((naked, used, no_stack_protector)) void _dl_runtime_resolve()
{
+#if defined(__amd64__)
__asm__(
"pop %r11\n" /* Pop lazy resolve arguments */
"pop %r10\n"
@@ -148,6 +149,11 @@ __attribute__((naked, used, no_stack_protector)) void _dl_runtime_resolve()
"pop %rdi\n"
"jmp *%r11\n"); /* Jump to the return value */
+#elif defined(__i386__)
+#warning "i386 _dl_runtime_resolve not implemented"
+#else
+#error "Unsupported architecture"
+#endif
}
int RelocateHelper(ElfInfo *Info, Elf_Rela *Rela, short IsRel, void **Relocated);
@@ -561,7 +567,7 @@ int CheckElfEhdr(Elf_Ehdr *ehdr, char *Path)
if (ehdr->e_ident[EI_CLASS] != elfClass)
{
printf("dl: %s is not a %s-bit ELF file\n",
- Path, __LP64__ ? "64" : "32");
+ Path, elfClass == ELFCLASS64 ? "64" : "32");
return -EINVAL;
}
@@ -804,6 +810,7 @@ int RelocateHelper(ElfInfo *Info, Elf_Rela *Rela, short IsRel, void **Relocated)
addAddend = 1;
break;
}
+#if __LP64__
case R_DTPMOD64:
{
printf("dl: i don't know what to do with DTPMOD64\n");
@@ -822,6 +829,7 @@ int RelocateHelper(ElfInfo *Info, Elf_Rela *Rela, short IsRel, void **Relocated)
reloc = symAddress + Rela->r_addend;
break;
}
+#endif // __LP64__
default:
{
printf("dl: Unsupported relocation type %d\n", relType);
diff --git a/Userspace/libc/interpreter/start.c b/Userspace/libc/interpreter/start.c
index 4b695a61..f2b44cb2 100644
--- a/Userspace/libc/interpreter/start.c
+++ b/Userspace/libc/interpreter/start.c
@@ -99,6 +99,7 @@ void __fini_print_buffer();
__attribute__((naked, used, no_stack_protector)) void _start()
{
+#if defined(__amd64__)
__asm__(
"xorq %rbp, %rbp\n" /* Clear rbp */
@@ -125,14 +126,21 @@ __attribute__((naked, used, no_stack_protector)) void _start()
"call main\n" /* Call _dl_main */
"movl %eax, %edi\n" /* Move return value to edi */
"call _exit\n"); /* Call _exit */
+#elif defined(__i386__)
+#warning "i386 _start not implemented"
+#else
+#error "Unsupported architecture"
+#endif
}
__attribute__((no_stack_protector)) _Noreturn void _exit(int status)
{
__fini_print_buffer();
call_exit(status);
- /* At this point, the program *SHOULD* have exited. */
+/* At this point, the program *SHOULD* have exited. */
+#if defined(__amd64__) || defined(__i386__)
__asm__("ud2\n");
+#endif
__builtin_unreachable();
}
diff --git a/Userspace/libc/runtime/Scrt1.c b/Userspace/libc/runtime/Scrt1.c
index 671767b1..20837a53 100644
--- a/Userspace/libc/runtime/Scrt1.c
+++ b/Userspace/libc/runtime/Scrt1.c
@@ -39,6 +39,7 @@ void __crt_fini_array(void)
__attribute__((naked, used, no_stack_protector, section(".text"))) void _start()
{
+#if defined(__amd64__)
asm("movq $0, %rbp\n"
"pushq %rbp\n"
"pushq %rbp\n"
@@ -65,6 +66,11 @@ __attribute__((naked, used, no_stack_protector, section(".text"))) void _start()
"movl %eax, %edi\n"
"call _exit\n");
+#elif defined(__i386__)
+#warning "i386 _start not implemented"
+#else
+#error "Unsupported architecture"
+#endif
}
/* These are declared in GNU ld */
diff --git a/Userspace/libc/runtime/crt1.c b/Userspace/libc/runtime/crt1.c
index 671767b1..20837a53 100644
--- a/Userspace/libc/runtime/crt1.c
+++ b/Userspace/libc/runtime/crt1.c
@@ -39,6 +39,7 @@ void __crt_fini_array(void)
__attribute__((naked, used, no_stack_protector, section(".text"))) void _start()
{
+#if defined(__amd64__)
asm("movq $0, %rbp\n"
"pushq %rbp\n"
"pushq %rbp\n"
@@ -65,6 +66,11 @@ __attribute__((naked, used, no_stack_protector, section(".text"))) void _start()
"movl %eax, %edi\n"
"call _exit\n");
+#elif defined(__i386__)
+#warning "i386 _start not implemented"
+#else
+#error "Unsupported architecture"
+#endif
}
/* These are declared in GNU ld */
diff --git a/Userspace/libc/src/Makefile b/Userspace/libc/src/Makefile
index 9ce59780..fca5c2bd 100644
--- a/Userspace/libc/src/Makefile
+++ b/Userspace/libc/src/Makefile
@@ -15,7 +15,7 @@ OBJ = ${S_SOURCES:.S=.o} ${C_SOURCES:.c=.o} ${CXX_SOURCES:.cpp=.o}
CFLAGS := -fvisibility=hidden -fPIC -I../include -I$(WORKSPACE_DIR)/out/include -DLIBC_GIT_COMMIT='"$(shell git rev-parse HEAD)"'
ifeq ($(DEBUG), 1)
- CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm
+ CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always
endif
build: $(DYNAMIC_NAME) $(STATIC_NAME)
diff --git a/Userspace/libc/src/arith64.c b/Userspace/libc/src/arith64.c
new file mode 100644
index 00000000..1a7ff727
--- /dev/null
+++ b/Userspace/libc/src/arith64.c
@@ -0,0 +1,290 @@
+/*
+ This file is part of Fennix C Library.
+
+ Fennix C Library is free software: you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ Fennix C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fennix C Library. If not, see .
+*/
+
+#if defined(__amd64__) || defined(__i386__)
+
+// GCC 32/64-bit integer arithmetic support for 32-bit systems that can't link
+// to libgcc.
+
+// Function prototypes and descriptions are taken from
+// https://gcc.gnu.org/onlinedocs/gccint/Integer-library-routines.html.
+
+// This file may be #include'd by another file, so we try not to pollute the
+// namespace and we don't import any headers.
+
+// All functions must be resolvable by the linker and therefore can't be inline
+// or static, even if they're #included into the file where they'll be used.
+
+// For best performance we try to avoid branching. This makes the code a little
+// weird in places.
+
+// See https://github.com/glitchub/arith64 for more information.
+// This software is released as-is into the public domain, as described at
+// https://unlicense.org. Do whatever you like with it.
+
+#define arith64_u64 unsigned long long int
+#define arith64_s64 signed long long int
+#define arith64_u32 unsigned int
+#define arith64_s32 int
+
+typedef union
+{
+ arith64_u64 u64;
+ arith64_s64 s64;
+ struct
+ {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ arith64_u32 hi; arith64_u32 lo;
+#else
+ arith64_u32 lo; arith64_u32 hi;
+#endif
+ } u32;
+ struct
+ {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ arith64_s32 hi; arith64_s32 lo;
+#else
+ arith64_s32 lo; arith64_s32 hi;
+#endif
+ } s32;
+} arith64_word;
+
+// extract hi and lo 32-bit words from 64-bit value
+#define arith64_hi(n) (arith64_word){.u64=n}.u32.hi
+#define arith64_lo(n) (arith64_word){.u64=n}.u32.lo
+
+// Negate a if b is negative, via invert and increment.
+#define arith64_neg(a, b) (((a) ^ ((((arith64_s64)(b)) >= 0) - 1)) + (((arith64_s64)(b)) < 0))
+#define arith64_abs(a) arith64_neg(a, a)
+
+// Return the absolute value of a.
+// Note LLINT_MIN cannot be negated.
+arith64_s64 __absvdi2(arith64_s64 a)
+{
+ return arith64_abs(a);
+}
+
+// Return the result of shifting a left by b bits.
+arith64_s64 __ashldi3(arith64_s64 a, int b)
+{
+ arith64_word w = {.s64 = a};
+
+ b &= 63;
+
+ if (b >= 32)
+ {
+ w.u32.hi = w.u32.lo << (b - 32);
+ w.u32.lo = 0;
+ } else if (b)
+ {
+ w.u32.hi = (w.u32.lo >> (32 - b)) | (w.u32.hi << b);
+ w.u32.lo <<= b;
+ }
+ return w.s64;
+}
+
+// Return the result of arithmetically shifting a right by b bits.
+arith64_s64 __ashrdi3(arith64_s64 a, int b)
+{
+ arith64_word w = {.s64 = a};
+
+ b &= 63;
+
+ if (b >= 32)
+ {
+ w.s32.lo = w.s32.hi >> (b - 32);
+ w.s32.hi >>= 31; // 0xFFFFFFFF or 0
+ } else if (b)
+ {
+ w.u32.lo = (w.u32.hi << (32 - b)) | (w.u32.lo >> b);
+ w.s32.hi >>= b;
+ }
+ return w.s64;
+}
+
+// These functions return the number of leading 0-bits in a, starting at the
+// most significant bit position. If a is zero, the result is undefined.
+int __clzsi2(arith64_u32 a)
+{
+ int b, n = 0;
+ b = !(a & 0xffff0000) << 4; n += b; a <<= b;
+ b = !(a & 0xff000000) << 3; n += b; a <<= b;
+ b = !(a & 0xf0000000) << 2; n += b; a <<= b;
+ b = !(a & 0xc0000000) << 1; n += b; a <<= b;
+ return n + !(a & 0x80000000);
+}
+
+int __clzdi2(arith64_u64 a)
+{
+ int b, n = 0;
+ b = !(a & 0xffffffff00000000ULL) << 5; n += b; a <<= b;
+ b = !(a & 0xffff000000000000ULL) << 4; n += b; a <<= b;
+ b = !(a & 0xff00000000000000ULL) << 3; n += b; a <<= b;
+ b = !(a & 0xf000000000000000ULL) << 2; n += b; a <<= b;
+ b = !(a & 0xc000000000000000ULL) << 1; n += b; a <<= b;
+ return n + !(a & 0x8000000000000000ULL);
+}
+
+// These functions return the number of trailing 0-bits in a, starting at the
+// least significant bit position. If a is zero, the result is undefined.
+int __ctzsi2(arith64_u32 a)
+{
+ int b, n = 0;
+ b = !(a & 0x0000ffff) << 4; n += b; a >>= b;
+ b = !(a & 0x000000ff) << 3; n += b; a >>= b;
+ b = !(a & 0x0000000f) << 2; n += b; a >>= b;
+ b = !(a & 0x00000003) << 1; n += b; a >>= b;
+ return n + !(a & 0x00000001);
+}
+
+int __ctzdi2(arith64_u64 a)
+{
+ int b, n = 0;
+ b = !(a & 0x00000000ffffffffULL) << 5; n += b; a >>= b;
+ b = !(a & 0x000000000000ffffULL) << 4; n += b; a >>= b;
+ b = !(a & 0x00000000000000ffULL) << 3; n += b; a >>= b;
+ b = !(a & 0x000000000000000fULL) << 2; n += b; a >>= b;
+ b = !(a & 0x0000000000000003ULL) << 1; n += b; a >>= b;
+ return n + !(a & 0x0000000000000001ULL);
+}
+
+// Calculate both the quotient and remainder of the unsigned division of a by
+// b. The return value is the quotient, and the remainder is placed in variable
+// pointed to by c (if it's not NULL).
+arith64_u64 __divmoddi4(arith64_u64 a, arith64_u64 b, arith64_u64 *c)
+{
+ if (b > a) // divisor > numerator?
+ {
+ if (c) *c = a; // remainder = numerator
+ return 0; // quotient = 0
+ }
+ if (!arith64_hi(b)) // divisor is 32-bit
+ {
+ if (b == 0) // divide by 0
+ {
+ volatile char x = 0; x = 1 / x; // force an exception
+ }
+ if (b == 1) // divide by 1
+ {
+ if (c) *c = 0; // remainder = 0
+ return a; // quotient = numerator
+ }
+ if (!arith64_hi(a)) // numerator is also 32-bit
+ {
+ if (c) // use generic 32-bit operators
+ *c = arith64_lo(a) % arith64_lo(b);
+ return arith64_lo(a) / arith64_lo(b);
+ }
+ }
+
+ // let's do long division
+ char bits = __clzdi2(b) - __clzdi2(a) + 1; // number of bits to iterate (a and b are non-zero)
+ arith64_u64 rem = a >> bits; // init remainder
+ a <<= 64 - bits; // shift numerator to the high bit
+ arith64_u64 wrap = 0; // start with wrap = 0
+ while (bits-- > 0) // for each bit
+ {
+ rem = (rem << 1) | (a >> 63); // shift numerator MSB to remainder LSB
+ a = (a << 1) | (wrap & 1); // shift out the numerator, shift in wrap
+ wrap = ((arith64_s64)(b - rem - 1) >> 63); // wrap = (b > rem) ? 0 : 0xffffffffffffffff (via sign extension)
+ rem -= b & wrap; // if (wrap) rem -= b
+ }
+ if (c) *c = rem; // maybe set remainder
+ return (a << 1) | (wrap & 1); // return the quotient
+}
+
+// Return the quotient of the signed division of a by b.
+arith64_s64 __divdi3(arith64_s64 a, arith64_s64 b)
+{
+ arith64_u64 q = __divmoddi4(arith64_abs(a), arith64_abs(b), (void *)0);
+ return arith64_neg(q, a^b); // negate q if a and b signs are different
+}
+
+// Return the index of the least significant 1-bit in a, or the value zero if a
+// is zero. The least significant bit is index one.
+int __ffsdi2(arith64_u64 a)
+{
+ return a ? __ctzdi2(a) + 1 : 0;
+}
+
+// Return the result of logically shifting a right by b bits.
+arith64_u64 __lshrdi3(arith64_u64 a, int b)
+{
+ arith64_word w = {.u64 = a};
+
+ b &= 63;
+
+ if (b >= 32)
+ {
+ w.u32.lo = w.u32.hi >> (b - 32);
+ w.u32.hi = 0;
+ } else if (b)
+ {
+ w.u32.lo = (w.u32.hi << (32 - b)) | (w.u32.lo >> b);
+ w.u32.hi >>= b;
+ }
+ return w.u64;
+}
+
+// Return the remainder of the signed division of a by b.
+arith64_s64 __moddi3(arith64_s64 a, arith64_s64 b)
+{
+ arith64_u64 r;
+ __divmoddi4(arith64_abs(a), arith64_abs(b), &r);
+ return arith64_neg(r, a); // negate remainder if numerator is negative
+}
+
+// Return the number of bits set in a.
+int __popcountsi2(arith64_u32 a)
+{
+ // collect sums into two low bytes
+ a = a - ((a >> 1) & 0x55555555);
+ a = ((a >> 2) & 0x33333333) + (a & 0x33333333);
+ a = (a + (a >> 4)) & 0x0F0F0F0F;
+ a = (a + (a >> 16));
+ // add the bytes, return bottom 6 bits
+ return (a + (a >> 8)) & 63;
+}
+
+// Return the number of bits set in a.
+int __popcountdi2(arith64_u64 a)
+{
+ // collect sums into two low bytes
+ a = a - ((a >> 1) & 0x5555555555555555ULL);
+ a = ((a >> 2) & 0x3333333333333333ULL) + (a & 0x3333333333333333ULL);
+ a = (a + (a >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
+ a = (a + (a >> 32));
+ a = (a + (a >> 16));
+ // add the bytes, return bottom 7 bits
+ return (a + (a >> 8)) & 127;
+}
+
+// Return the quotient of the unsigned division of a by b.
+arith64_u64 __udivdi3(arith64_u64 a, arith64_u64 b)
+{
+ return __divmoddi4(a, b, (void *)0);
+}
+
+// Return the remainder of the unsigned division of a by b.
+arith64_u64 __umoddi3(arith64_u64 a, arith64_u64 b)
+{
+ arith64_u64 r;
+ __divmoddi4(a, b, &r);
+ return r;
+}
+
+#endif
diff --git a/Userspace/libc/src/main.c b/Userspace/libc/src/main.c
index 47d12bd0..591f0fba 100644
--- a/Userspace/libc/src/main.c
+++ b/Userspace/libc/src/main.c
@@ -114,6 +114,7 @@ void __crt_fini_array(void)
__attribute__((naked, used, no_stack_protector, section(".text"))) void _start()
{
+#if defined(__amd64__)
asm("movq $0, %rbp\n"
"pushq %rbp\n"
"pushq %rbp\n"
@@ -140,6 +141,11 @@ __attribute__((naked, used, no_stack_protector, section(".text"))) void _start()
"movl %eax, %edi\n"
"call _exit\n");
+#elif defined(__i386__)
+#warning "i386 _start not implemented"
+#else
+#warning "unknown architecture"
+#endif
}
int main(int argc, char *argv[], char *envp[])
diff --git a/config.mk b/config.mk
index 1e697c58..3bf48d6f 100644
--- a/config.mk
+++ b/config.mk
@@ -6,7 +6,7 @@ DEBUG = 1
OSNAME = Fennix
# OS architecture, check AVAILABLE_ARCHS for available options.
-OSARCH = i386
+OSARCH = amd64
# Kernel version.
KERNEL_VERSION = dev