mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-27 23:14:38 +00:00
Fixed tasking SSE
This commit is contained in:
parent
5da3b3ae6c
commit
e53bc14240
@ -1,11 +0,0 @@
|
||||
[bits 64]
|
||||
|
||||
[global _amd64_fxsave]
|
||||
_amd64_fxsave:
|
||||
fxsave [rdi]
|
||||
ret
|
||||
|
||||
[global _amd64_fxrstor]
|
||||
_amd64_fxrstor:
|
||||
fxrstor [rdi]
|
||||
ret
|
@ -1,11 +0,0 @@
|
||||
[bits 64]
|
||||
|
||||
[global _i386_fxsave]
|
||||
_i386_fxsave:
|
||||
fxsave [edi]
|
||||
ret
|
||||
|
||||
[global _i386_fxrstor]
|
||||
_i386_fxrstor:
|
||||
fxrstor [edi]
|
||||
ret
|
27
Core/CPU.cpp
27
Core/CPU.cpp
@ -209,30 +209,35 @@ namespace CPU
|
||||
|
||||
debug("Enabling UMIP, SMEP & SMAP support...");
|
||||
x64::cpuid(0x1, &rax, &rbx, &rcx, &rdx);
|
||||
if (rdx & x64::CPUID_FEAT_RDX_UMIP)
|
||||
if (rdx & x64::CPUID_FEAT_RDX_UMIP) // https://en.wikipedia.org/wiki/Control_register
|
||||
{
|
||||
if (!BSP)
|
||||
KPrint("UMIP is supported.");
|
||||
fixme("Not going to enable UMIP.");
|
||||
cr4.UMIP = 1;
|
||||
debug("UMIP is supported.");
|
||||
// cr4.UMIP = 1;
|
||||
}
|
||||
if (rdx & x64::CPUID_FEAT_RDX_SMEP)
|
||||
if (rdx & x64::CPUID_FEAT_RDX_SMEP) // https://en.wikipedia.org/wiki/Control_register#SMEP
|
||||
// https://web.archive.org/web/20160312223150/http://ncsi.com/nsatc11/presentations/wednesday/emerging_technologies/fischer.pdf
|
||||
{
|
||||
if (!BSP)
|
||||
KPrint("SMEP is supported.");
|
||||
fixme("Not going to enable SMEP.");
|
||||
cr4.SMEP = 1;
|
||||
debug("SMEP is supported.");
|
||||
// cr4.SMEP = 1;
|
||||
}
|
||||
if (rdx & x64::CPUID_FEAT_RDX_SMAP)
|
||||
if (rdx & x64::CPUID_FEAT_RDX_SMAP) // https://en.wikipedia.org/wiki/Supervisor_Mode_Access_Prevention
|
||||
{
|
||||
if (!BSP)
|
||||
KPrint("SMAP is supported.");
|
||||
fixme("Not going to enable SMAP.");
|
||||
cr4.SMAP = 1;
|
||||
debug("SMAP is supported.");
|
||||
// cr4.SMAP = 1;
|
||||
}
|
||||
if (strcmp(Hypervisor(), x86_CPUID_VENDOR_VIRTUALBOX) == 0 &&
|
||||
strcmp(Hypervisor(), x86_CPUID_VENDOR_TCG) == 0)
|
||||
if (strcmp(Hypervisor(), x86_CPUID_VENDOR_VIRTUALBOX) != 0 &&
|
||||
strcmp(Hypervisor(), x86_CPUID_VENDOR_TCG) != 0)
|
||||
{
|
||||
debug("Writing CR4...");
|
||||
x64::writecr4(cr4);
|
||||
debug("Wrote CR4.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!BSP)
|
||||
|
4
Makefile
4
Makefile
@ -61,8 +61,8 @@ CFLAGS := \
|
||||
|
||||
ifeq ($(OSARCH), amd64)
|
||||
|
||||
CFLAGS += -fno-pic -fno-pie -mno-80387 -mno-mmx -mno-3dnow \
|
||||
-mno-red-zone -march=x86-64 -pipe \
|
||||
CFLAGS += -fno-pic -fno-pie \
|
||||
-mno-red-zone -march=x86-64 -pipe \
|
||||
-mcmodel=kernel -msoft-float -fno-builtin
|
||||
CFLAG_STACK_PROTECTOR := -fstack-protector-all
|
||||
LDFLAGS += -TArchitecture/amd64/linker.ld \
|
||||
|
@ -379,6 +379,10 @@ namespace Tasking
|
||||
tcb->Info.SleepUntil = 0;
|
||||
schedbg("Thread \"%s\"(%d) woke up.", tcb->Name, tcb->ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
schedbg("Thread \"%s\"(%d) is not ready to wake up. (SleepUntil: %d, Counter: %d)", tcb->Name, tcb->ID, tcb->Info.SleepUntil, TimeManager->GetCounter());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -433,7 +437,7 @@ namespace Tasking
|
||||
{
|
||||
// Save current process and thread registries, gs, fs, fpu, etc...
|
||||
CurrentCPU->CurrentThread->Registers = *Frame;
|
||||
CPU::x64::fxsave(CurrentCPU->CurrentThread->FXRegion);
|
||||
CPU::x64::fxsave(CurrentCPU->CurrentThread->FPU);
|
||||
CurrentCPU->CurrentThread->GSBase = CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE);
|
||||
CurrentCPU->CurrentThread->FSBase = CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE);
|
||||
|
||||
@ -548,7 +552,7 @@ namespace Tasking
|
||||
// Not sure if this is needed, but it's better to be safe than sorry.
|
||||
asmv("movq %cr3, %rax");
|
||||
asmv("movq %rax, %cr3");
|
||||
CPU::x64::fxrstor(CurrentCPU->CurrentThread->FXRegion);
|
||||
CPU::x64::fxrstor(CurrentCPU->CurrentThread->FPU);
|
||||
CPU::x64::wrmsr(CPU::x64::MSR_GS_BASE, CurrentCPU->CurrentThread->GSBase);
|
||||
CPU::x64::wrmsr(CPU::x64::MSR_FS_BASE, CurrentCPU->CurrentThread->FSBase);
|
||||
|
||||
@ -729,10 +733,11 @@ namespace Tasking
|
||||
|
||||
void Task::Sleep(uint64_t Milliseconds)
|
||||
{
|
||||
SmartCriticalSection(SchedulerLock);
|
||||
SmartCriticalSection(TaskingLock);
|
||||
TCB *thread = this->GetCurrentThread();
|
||||
thread->Status = TaskStatus::Sleeping;
|
||||
thread->Info.SleepUntil = TimeManager->CalculateTarget(Milliseconds);
|
||||
schedbg("Thread \"%s\"(%d) is going to sleep until %llu", thread->Name, thread->ID, thread->Info.SleepUntil);
|
||||
OneShot(1);
|
||||
}
|
||||
|
||||
@ -773,6 +778,27 @@ namespace Tasking
|
||||
Thread->Offset = Offset;
|
||||
Thread->ExitCode = 0xdead;
|
||||
Thread->Status = TaskStatus::Ready;
|
||||
Thread->Memory = new Memory::MemMgr(Parent->PageTable);
|
||||
Thread->FPU = (FXState *)Thread->Memory->RequestPages(TO_PAGES(sizeof(FXState)));
|
||||
memset(Thread->FPU, 0, FROM_PAGES(TO_PAGES(sizeof(FXState))));
|
||||
|
||||
// TODO: Is really a good idea to use the FPU in kernel mode?
|
||||
Thread->FPU->mxcsr = 0b0001111110000000;
|
||||
Thread->FPU->mxcsrmask = 0b1111111110111111;
|
||||
Thread->FPU->fcw = 0b0000001100111111;
|
||||
|
||||
CPU::x64::fxrstor(Thread->FPU);
|
||||
// uint16_t FCW = 0b1100111111;
|
||||
// asmv("fldcw %0"
|
||||
// :
|
||||
// : "m"(FCW)
|
||||
// : "memory");
|
||||
// uint32_t MXCSR = 0b1111110000000;
|
||||
// asmv("ldmxcsr %0"
|
||||
// :
|
||||
// : "m"(MXCSR)
|
||||
// : "memory");
|
||||
// CPU::x64::fxsave(Thread->FPU);
|
||||
|
||||
#if defined(__amd64__)
|
||||
memset(&Thread->Registers, 0, sizeof(CPU::x64::TrapFrame)); // Just in case
|
||||
@ -808,7 +834,6 @@ namespace Tasking
|
||||
case TaskTrustLevel::User:
|
||||
{
|
||||
Thread->Stack = new Memory::StackGuard(true, Parent->PageTable);
|
||||
Thread->Memory = new Memory::MemMgr(Parent->PageTable);
|
||||
#if defined(__amd64__)
|
||||
SecurityManager.TrustToken(Thread->Security.UniqueToken, TokenTrustLevel::Untrusted);
|
||||
Thread->GSBase = 0;
|
||||
@ -823,6 +848,8 @@ namespace Tasking
|
||||
Thread->Registers.rflags.ID = 1;
|
||||
Thread->Registers.rsp = ((uintptr_t)Thread->Stack->GetStackTop());
|
||||
|
||||
#pragma region
|
||||
|
||||
size_t ArgvSize = 0;
|
||||
if (argv)
|
||||
while (argv[ArgvSize] != nullptr)
|
||||
@ -942,6 +969,8 @@ namespace Tasking
|
||||
Thread->Registers.rcx = (uintptr_t)EnvpSize; // envc
|
||||
Thread->Registers.rdx = (uintptr_t)(Thread->Registers.rsp + 8 + (8 * ArgvSize) + 8); // envp
|
||||
|
||||
#pragma endregion
|
||||
|
||||
/* We need to leave the libc's crt to make a syscall when the Thread is exited or we are going to get GPF or PF exception. */
|
||||
|
||||
Memory::Virtual uva = Memory::Virtual(Parent->PageTable);
|
||||
|
@ -5,11 +5,6 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
extern "C" void _amd64_fxsave(char *Buffer);
|
||||
extern "C" void _amd64_fxrstor(char *Buffer);
|
||||
extern "C" void _i386_fxsave(char *Buffer);
|
||||
extern "C" void _i386_fxrstor(char *Buffer);
|
||||
|
||||
#define x86_CPUID_VENDOR_OLDAMD "AMDisbetter!" /* Early engineering samples of AMD K5 processor */
|
||||
#define x86_CPUID_VENDOR_AMD "AuthenticAMD"
|
||||
#define x86_CPUID_VENDOR_INTEL "GenuineIntel"
|
||||
@ -3404,31 +3399,29 @@ namespace CPU
|
||||
#endif
|
||||
}
|
||||
|
||||
SafeFunction static inline void fxsave(char *FXSaveArea)
|
||||
SafeFunction static inline void fxsave(void *FXSaveArea)
|
||||
{
|
||||
#if defined(__amd64__)
|
||||
if (!FXSaveArea || FXSaveArea >= (char *)0xfffffffffffff000)
|
||||
return;
|
||||
|
||||
_amd64_fxsave(FXSaveArea);
|
||||
// asmv("fxsaveq (%0)"
|
||||
// :
|
||||
// : "r"(FXSaveArea)
|
||||
// : "memory");
|
||||
asmv("fxsaveq (%0)"
|
||||
:
|
||||
: "r"(FXSaveArea)
|
||||
: "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
SafeFunction static inline void fxrstor(char *FXRstorArea)
|
||||
SafeFunction static inline void fxrstor(void *FXRstorArea)
|
||||
{
|
||||
#if defined(__amd64__)
|
||||
if (!FXRstorArea || FXRstorArea >= (char *)0xfffffffffffff000)
|
||||
return;
|
||||
|
||||
_amd64_fxrstor(FXRstorArea);
|
||||
// asmv("fxrstorq (%0)"
|
||||
// :
|
||||
// : "r"(FXRstorArea)
|
||||
// : "memory");
|
||||
asmv("fxrstorq (%0)"
|
||||
:
|
||||
: "r"(FXRstorArea)
|
||||
: "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,32 @@ namespace Tasking
|
||||
Terminated
|
||||
};
|
||||
|
||||
struct FXState
|
||||
{
|
||||
/** @brief FPU control word */
|
||||
uint16_t fcw;
|
||||
/** @brief FPU status word */
|
||||
uint16_t fsw;
|
||||
/** @brief FPU tag words */
|
||||
uint8_t ftw;
|
||||
/** @brief Reserved (zero) */
|
||||
uint8_t Reserved;
|
||||
/** @brief FPU opcode */
|
||||
uint16_t fop;
|
||||
/** @brief PFU instruction pointer */
|
||||
uint64_t rip;
|
||||
/** @brief FPU data pointer */
|
||||
uint64_t rdp;
|
||||
/** @brief SSE control register */
|
||||
uint32_t mxcsr;
|
||||
/** @brief SSE control register mask */
|
||||
uint32_t mxcsrmask;
|
||||
/** @brief FPU registers (last 6 bytes reserved) */
|
||||
uint8_t st[8][16];
|
||||
/** @brief XMM registers */
|
||||
uint8_t xmm[16][16];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct TaskSecurity
|
||||
{
|
||||
TaskTrustLevel TrustLevel;
|
||||
@ -104,7 +130,7 @@ namespace Tasking
|
||||
uintptr_t IPHistory[128];
|
||||
TaskSecurity Security;
|
||||
TaskInfo Info;
|
||||
char FXRegion[512] __attribute__((aligned(16)));
|
||||
FXState *FPU;
|
||||
|
||||
void Rename(const char *name)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user