From 446a57101844a084eb449df1af9bca5917243a2e Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 7 Sep 2023 04:22:34 +0300 Subject: [PATCH] Tasking is now working under 32-bit --- .../i386/cpu/InterruptDescriptorTable.cpp | 30 +------ Core/Crash/CrashHandler.cpp | 8 +- Core/Crash/Screens/Details.cpp | 4 +- Core/Crash/UserHandler.cpp | 4 +- Core/Driver/Driver.cpp | 9 +- DAPI.hpp | 16 ++-- Tasking/Scheduler.cpp | 88 +++++++++++-------- Tasking/Task.cpp | 5 +- Tasking/Thread.cpp | 4 +- include/cpu.hpp | 13 +-- include/task.hpp | 2 +- 11 files changed, 83 insertions(+), 100 deletions(-) diff --git a/Architecture/i386/cpu/InterruptDescriptorTable.cpp b/Architecture/i386/cpu/InterruptDescriptorTable.cpp index 1c3584f..e5b6d87 100644 --- a/Architecture/i386/cpu/InterruptDescriptorTable.cpp +++ b/Architecture/i386/cpu/InterruptDescriptorTable.cpp @@ -102,26 +102,13 @@ namespace InterruptDescriptorTable asm("cld\n" "cli\n" - // "push %eax\n" - // "push %ebx\n" - // "push %ecx\n" - // "push %edx\n" - // "push %esi\n" - // "push %edi\n" - // "push %ebp\n" "pusha\n" "push %esp\n" "call ExceptionHandler\n" + "pop %esp\n" "popa\n" - // "pop %ebp\n" - // "pop %edi\n" - // "pop %esi\n" - // "pop %edx\n" - // "pop %ecx\n" - // "pop %ebx\n" - // "pop %eax\n" "add $8, %esp\n" @@ -133,26 +120,13 @@ namespace InterruptDescriptorTable asm("cld\n" "cli\n" - // "push %eax\n" - // "push %ebx\n" - // "push %ecx\n" - // "push %edx\n" - // "push %esi\n" - // "push %edi\n" - // "push %ebp\n" "pusha\n" "push %esp\n" "call MainInterruptHandler\n" + "pop %esp\n" "popa\n" - // "pop %ebp\n" - // "pop %edi\n" - // "pop %esi\n" - // "pop %edx\n" - // "pop %ecx\n" - // "pop %ebx\n" - // "pop %eax\n" "add $8, %esp\n" diff --git a/Core/Crash/CrashHandler.cpp b/Core/Crash/CrashHandler.cpp index b07841d..ebd21f2 100644 --- a/Core/Crash/CrashHandler.cpp +++ b/Core/Crash/CrashHandler.cpp @@ -1082,10 +1082,10 @@ namespace CrashHandler asmv("mov %%ds, %0" : "=r"(ds)); - EHPrint("\eFF2525FS=%#x GS=%#x SS=%#x CS=%#x DS=%#x\n", + EHPrint("\eFF2525FS=%#x GS=%#x CS=%#x DS=%#x\n", CPU::x32::rdmsr(CPU::x32::MSR_FS_BASE), CPU::x32::rdmsr(CPU::x32::MSR_GS_BASE), - Frame->ss, Frame->cs, ds); + Frame->cs, ds); EHPrint("EAX=%#x EBX=%#x ECX=%#x EDX=%#x\n", Frame->eax, Frame->ebx, Frame->ecx, Frame->edx); @@ -1300,9 +1300,9 @@ namespace CrashHandler crashdata.efer.SVME ? "True " : "False", crashdata.efer.LMSLE ? "True " : "False", crashdata.efer.FFXSR ? "True " : "False", crashdata.efer.TCE ? "True " : "False", crashdata.efer.Reserved0, crashdata.efer.Reserved1, crashdata.efer.Reserved2); #elif defined(a32) - error("FS=%#x GS=%#x SS=%#x CS=%#x DS=%#x", + error("FS=%#x GS=%#x CS=%#x DS=%#x", CPU::x32::rdmsr(CPU::x32::MSR_FS_BASE), CPU::x32::rdmsr(CPU::x32::MSR_GS_BASE), - Frame->ss, Frame->cs, ds); + Frame->cs, ds); error("EAX=%#x EBX=%#x ECX=%#x EDX=%#x", Frame->eax, Frame->ebx, Frame->ecx, Frame->edx); diff --git a/Core/Crash/Screens/Details.cpp b/Core/Crash/Screens/Details.cpp index dcfe635..28a0215 100644 --- a/Core/Crash/Screens/Details.cpp +++ b/Core/Crash/Screens/Details.cpp @@ -79,9 +79,9 @@ namespace CrashHandler EHPrint("RSI=%#lx RDI=%#lx RBP=%#lx RSP=%#lx\n", data.Frame->rsi, data.Frame->rdi, data.Frame->rbp, data.Frame->rsp); EHPrint("RIP=%#lx RFL=%#lx INT=%#lx ERR=%#lx EFER=%#lx\n", data.Frame->rip, data.Frame->rflags.raw, data.Frame->InterruptNumber, data.Frame->ErrorCode, data.efer.raw); #elif defined(a32) - EHPrint("\e7981FCFS=%#x GS=%#x SS=%#x CS=%#x DS=%#x\n", + EHPrint("\e7981FCFS=%#x GS=%#x CS=%#x DS=%#x\n", CPU::x32::rdmsr(CPU::x32::MSR_FS_BASE), CPU::x32::rdmsr(CPU::x32::MSR_GS_BASE), - data.Frame->ss, data.Frame->cs, ds); + data.Frame->cs, ds); EHPrint("EAX=%#x EBX=%#x ECX=%#x EDX=%#x\n", data.Frame->eax, data.Frame->ebx, data.Frame->ecx, data.Frame->edx); EHPrint("ESI=%#x EDI=%#x EBP=%#x ESP=%#x\n", data.Frame->esi, data.Frame->edi, data.Frame->ebp, data.Frame->esp); EHPrint("EIP=%#x EFL=%#x INT=%#x ERR=%#x\n", data.Frame->eip, data.Frame->eflags.raw, data.Frame->InterruptNumber, data.Frame->ErrorCode); diff --git a/Core/Crash/UserHandler.cpp b/Core/Crash/UserHandler.cpp index 985493f..5a070f4 100644 --- a/Core/Crash/UserHandler.cpp +++ b/Core/Crash/UserHandler.cpp @@ -88,9 +88,9 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame) error("RSI=%#lx RDI=%#lx RBP=%#lx RSP=%#lx", Frame->rsi, Frame->rdi, Frame->rbp, Frame->rsp); error("RIP=%#lx RFL=%#lx INT=%#lx ERR=%#lx EFER=%#lx", Frame->rip, Frame->rflags.raw, Frame->InterruptNumber, Frame->ErrorCode, efer.raw); #elif defined(a32) - error("FS=%#x GS=%#x SS=%#x CS=%#x DS=%#x", + error("FS=%#x GS=%#x CS=%#x DS=%#x", CPU::x32::rdmsr(CPU::x32::MSR_FS_BASE), CPU::x32::rdmsr(CPU::x32::MSR_GS_BASE), - Frame->ss, Frame->cs, ds); + Frame->cs, ds); error("EAX=%#x EBX=%#x ECX=%#x EDX=%#x", Frame->eax, Frame->ebx, Frame->ecx, Frame->edx); error("ESI=%#x EDI=%#x EBP=%#x ESP=%#x", Frame->esi, Frame->edi, Frame->ebp, Frame->esp); error("EIP=%#x EFL=%#x INT=%#x ERR=%#x", Frame->eip, Frame->eflags.raw, Frame->InterruptNumber, Frame->ErrorCode); diff --git a/Core/Driver/Driver.cpp b/Core/Driver/Driver.cpp index 1b560bc..280dace 100644 --- a/Core/Driver/Driver.cpp +++ b/Core/Driver/Driver.cpp @@ -305,12 +305,13 @@ namespace Driver regs.rsp = Frame->rsp; regs.ss = Frame->ss; #elif defined(a32) - regs.ebp = Frame->ebp; regs.edi = Frame->edi; regs.esi = Frame->esi; + regs.ebp = Frame->ebp; + regs.esp = Frame->esp; + regs.ebx = Frame->ebx; regs.edx = Frame->edx; regs.ecx = Frame->ecx; - regs.ebx = Frame->ebx; regs.eax = Frame->eax; regs.InterruptNumber = Frame->InterruptNumber; @@ -318,8 +319,8 @@ namespace Driver regs.eip = Frame->eip; regs.cs = Frame->cs; regs.eflags = Frame->eflags.raw; - regs.esp = Frame->esp; - regs.ss = Frame->ss; + regs.r3_esp = Frame->r3_esp; + regs.r3_ss = Frame->r3_ss; #elif defined(aa64) #endif ((int (*)(void *))(Handle.InterruptCallback))(®s); diff --git a/DAPI.hpp b/DAPI.hpp index dc818eb..642a738 100644 --- a/DAPI.hpp +++ b/DAPI.hpp @@ -135,8 +135,10 @@ struct KernelAPI struct KAPIDisplay { - __UINT32_TYPE__ (*GetWidth)(void); - __UINT32_TYPE__ (*GetHeight)(void); + __UINT32_TYPE__ (*GetWidth) + (void); + __UINT32_TYPE__ (*GetHeight) + (void); /* TODO: Add more */ } Display; } __attribute__((packed)); @@ -428,21 +430,23 @@ union CPURegisters __UINT64_TYPE__ rsp; __UINT64_TYPE__ ss; #elif defined(__i386__) - __UINT32_TYPE__ ebp; __UINT32_TYPE__ edi; __UINT32_TYPE__ esi; + __UINT32_TYPE__ ebp; + __UINT32_TYPE__ esp; + __UINT32_TYPE__ ebx; __UINT32_TYPE__ edx; __UINT32_TYPE__ ecx; - __UINT32_TYPE__ ebx; __UINT32_TYPE__ eax; __UINT32_TYPE__ InterruptNumber; __UINT32_TYPE__ ErrorCode; + __UINT32_TYPE__ eip; __UINT32_TYPE__ cs; __UINT32_TYPE__ eflags; - __UINT32_TYPE__ esp; - __UINT32_TYPE__ ss; + __UINT32_TYPE__ r3_esp; + __UINT32_TYPE__ r3_ss; #else #warning "Unsupported architecture" #endif diff --git a/Tasking/Scheduler.cpp b/Tasking/Scheduler.cpp index 07a6702..48f87fa 100644 --- a/Tasking/Scheduler.cpp +++ b/Tasking/Scheduler.cpp @@ -31,6 +31,7 @@ #include "../Architecture/amd64/cpu/gdt.hpp" #elif defined(a32) #include "../Architecture/i386/cpu/apic.hpp" +#include "../Architecture/i386/cpu/gdt.hpp" #elif defined(aa64) #endif @@ -109,16 +110,15 @@ extern "C" SafeFunction NIF void TaskingScheduler_OneShot(int TimeSlice) { if (TimeSlice == 0) TimeSlice = Tasking::TaskPriority::Normal; -#if defined(a64) +#if defined(a86) ((APIC::Timer *)Interrupts::apicTimer[GetCurrentCPU()->ID])->OneShot(CPU::x86::IRQ16, TimeSlice); -#elif defined(a32) #elif defined(aa64) #endif } namespace Tasking { -#if defined(a64) +#if defined(a86) SafeFunction NIF bool Task::FindNewProcess(void *CPUDataPointer) { CPUData *CurrentCPU = (CPUData *)CPUDataPointer; @@ -473,7 +473,11 @@ namespace Tasking } #endif +#ifdef a64 SafeFunction NIF void Task::Schedule(CPU::x64::TrapFrame *Frame) +#else + SafeFunction NIF void Task::Schedule(CPU::x32::TrapFrame *Frame) +#endif { if (StopScheduler) { @@ -481,9 +485,14 @@ namespace Tasking return; } bool ProcessNotChanged = false; - CPU::x64::writecr3({.raw = (uint64_t)KernelPageTable}); /* Restore kernel page table for safety reasons. */ +/* Restore kernel page table for safety reasons. */ +#ifdef a64 + CPU::x64::writecr3({.raw = (uint64_t)KernelPageTable}); +#else + CPU::x32::writecr3({.raw = (uint32_t)KernelPageTable}); +#endif uint64_t SchedTmpTicks = TimeManager->GetCounter(); - this->LastTaskTicks.store(SchedTmpTicks - this->SchedulerTicks.load()); + this->LastTaskTicks.store(size_t(SchedTmpTicks - this->SchedulerTicks.load())); CPUData *CurrentCPU = GetCurrentCPU(); this->LastCore.store(CurrentCPU->ID); schedbg("Scheduler called on CPU %d.", CurrentCPU->ID); @@ -526,9 +535,15 @@ namespace Tasking { CurrentCPU->CurrentThread->Registers = *Frame; CPU::x64::fxsave(&CurrentCPU->CurrentThread->FPU); +#ifdef a64 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)); +#endif if (CurrentCPU->CurrentProcess->Status.load() == TaskStatus::Running) CurrentCPU->CurrentProcess->Status.store(TaskStatus::Ready); @@ -609,6 +624,7 @@ namespace Tasking for (size_t i = 0; i < (sizeof(CurrentCPU->CurrentThread->IPHistory) / sizeof(CurrentCPU->CurrentThread->IPHistory[0])) - 1; i++) CurrentCPU->CurrentThread->IPHistory[i + 1] = CurrentCPU->CurrentThread->IPHistory[i]; +#ifdef a64 CurrentCPU->CurrentThread->IPHistory[0] = Frame->rip; GlobalDescriptorTable::SetKernelStack((void *)((uintptr_t)CurrentCPU->CurrentThread->Stack->GetStackTop())); @@ -620,6 +636,19 @@ namespace Tasking 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 + CurrentCPU->CurrentThread->IPHistory[0] = Frame->eip; + + GlobalDescriptorTable::SetKernelStack((void *)((uintptr_t)CurrentCPU->CurrentThread->Stack->GetStackTop())); + CPU::x32::writecr3({.raw = (uint32_t)CurrentCPU->CurrentProcess->PageTable}); + /* Not sure if this is needed, but it's better to be safe than sorry. */ + asmv("movl %cr3, %eax"); + asmv("movl %eax, %cr3"); + 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); +#endif #ifdef ON_SCREEN_SCHEDULER_TASK_MANAGER OnScreenTaskManagerUpdate(); @@ -646,16 +675,26 @@ namespace Tasking TaskingScheduler_OneShot(CurrentCPU->CurrentThread->Info.Priority); if (CurrentCPU->CurrentThread->Security.IsDebugEnabled && CurrentCPU->CurrentThread->Security.IsKernelDebugEnabled) + { +#ifdef a64 trace("%s[%ld]: RIP=%#lx RBP=%#lx RSP=%#lx", CurrentCPU->CurrentThread->Name, CurrentCPU->CurrentThread->ID, CurrentCPU->CurrentThread->Registers.rip, CurrentCPU->CurrentThread->Registers.rbp, CurrentCPU->CurrentThread->Registers.rsp); +#else + trace("%s[%ld]: EIP=%#lx EBP=%#lx ESP=%#lx", + CurrentCPU->CurrentThread->Name, CurrentCPU->CurrentThread->ID, + CurrentCPU->CurrentThread->Registers.eip, + CurrentCPU->CurrentThread->Registers.ebp, + CurrentCPU->CurrentThread->Registers.esp); +#endif + } schedbg("================================================================"); schedbg("Technical Informations on Thread %s[%ld]:", CurrentCPU->CurrentThread->Name, CurrentCPU->CurrentThread->ID); - uint64_t ds; + uintptr_t ds; asmv("mov %%ds, %0" : "=r"(ds)); schedbg("FS=%#lx GS=%#lx SS=%#lx CS=%#lx DS=%#lx", @@ -674,45 +713,18 @@ namespace Tasking schedbg("================================================================"); End: - this->SchedulerTicks.store(TimeManager->GetCounter() - SchedTmpTicks); + this->SchedulerTicks.store(size_t(TimeManager->GetCounter() - SchedTmpTicks)); } +#ifdef a64 SafeFunction NIF void Task::OnInterruptReceived(CPU::x64::TrapFrame *Frame) +#else + SafeFunction NIF void Task::OnInterruptReceived(CPU::x32::TrapFrame *Frame) +#endif { SmartCriticalSection(SchedulerLock); this->Schedule(Frame); } -#elif defined(a32) - SafeFunction bool Task::FindNewProcess(void *CPUDataPointer) - { - fixme("unimplemented"); - return false; - } - - SafeFunction bool Task::GetNextAvailableThread(void *CPUDataPointer) - { - fixme("unimplemented"); - return false; - } - - SafeFunction bool Task::GetNextAvailableProcess(void *CPUDataPointer) - { - fixme("unimplemented"); - return false; - } - - SafeFunction bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) - { - fixme("unimplemented"); - return false; - } - - SafeFunction void Task::Schedule(void *Frame) - { - fixme("unimplemented"); - } - - SafeFunction void Task::OnInterruptReceived(CPU::x32::TrapFrame *Frame) { this->Schedule(Frame); } #elif defined(aa64) SafeFunction bool Task::FindNewProcess(void *CPUDataPointer) { diff --git a/Tasking/Task.cpp b/Tasking/Task.cpp index 12e745e..84dadef 100644 --- a/Tasking/Task.cpp +++ b/Tasking/Task.cpp @@ -377,7 +377,7 @@ namespace Tasking IdleProcess->ELFSymbolTable = KernelSymbolTable; for (int i = 0; i < SMP::CPUCores; i++) { - IdleThread = CreateThread(IdleProcess, reinterpret_cast(IdleProcessLoop)); + IdleThread = CreateThread(IdleProcess, IP(IdleProcessLoop)); char IdleName[16]; sprintf(IdleName, "Idle Thread %d", i); IdleThread->Rename(IdleName); @@ -387,7 +387,7 @@ namespace Tasking IdleThread->Info.Affinity[i] = true; } debug("Tasking Started"); -#if defined(a64) +#if defined(a86) if (Interrupts::apicTimer[0]) { ((APIC::Timer *)Interrupts::apicTimer[0])->OneShot(CPU::x86::IRQ16, 100); @@ -402,7 +402,6 @@ namespace Tasking // ((APIC::APIC *)Interrupts::apic[0])->IPI(i, icr); // } } -#elif defined(a32) #elif defined(aa64) #endif } diff --git a/Tasking/Thread.cpp b/Tasking/Thread.cpp index 7000a4e..3653af8 100644 --- a/Tasking/Thread.cpp +++ b/Tasking/Thread.cpp @@ -388,7 +388,7 @@ namespace Tasking POKE(uintptr_t, this->Registers.rsp) = (uintptr_t)ThreadDoExit; #elif defined(a32) this->Registers.cs = GDT_KERNEL_CODE; - this->Registers.ss = GDT_KERNEL_DATA; + this->Registers.r3_ss = GDT_KERNEL_DATA; this->Registers.eflags.AlwaysOne = 1; this->Registers.eflags.IF = 1; this->Registers.eflags.ID = 1; @@ -431,7 +431,7 @@ namespace Tasking this->SetupUserStack_x86_64(argv, envp, auxv); #elif defined(a32) this->Registers.cs = GDT_USER_CODE; - this->Registers.ss = GDT_USER_DATA; + this->Registers.r3_ss = GDT_USER_DATA; this->Registers.eflags.AlwaysOne = 1; this->Registers.eflags.IF = 1; this->Registers.eflags.ID = 1; diff --git a/include/cpu.hpp b/include/cpu.hpp index 89f9bac..f724b35 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -291,14 +291,6 @@ namespace CPU typedef struct TrapFrame { - // 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 edi; // Destination index for string operations uint32_t esi; // Source index for string operations uint32_t ebp; // Base Pointer (meant for stack frames) @@ -314,8 +306,9 @@ namespace CPU 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 } TrapFrame; typedef union DR6 diff --git a/include/task.hpp b/include/task.hpp index 7e6afa4..60ac230 100644 --- a/include/task.hpp +++ b/include/task.hpp @@ -391,7 +391,7 @@ namespace Tasking /** * @note This function is NOT thread safe */ - void Schedule(void *Frame); + void Schedule(CPU::x32::TrapFrame *Frame); void OnInterruptReceived(CPU::x32::TrapFrame *Frame); #elif defined(aa64)