From 3542dfca8bf675ecfb132c41424b2ed88991a792 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 15 Nov 2022 01:50:07 +0200 Subject: [PATCH] Code fixes and stability --- ...dvancedProgrammableInterruptController.cpp | 28 ++++---- Core/Crash/CrashHandler.cpp | 1 + SystemCalls/Native.cpp | 2 +- Tasking/Task.cpp | 72 +++++++++++++++++-- include/syscalls.hpp | 1 - include/task.hpp | 19 +---- 6 files changed, 86 insertions(+), 37 deletions(-) diff --git a/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp b/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp index 5a3f9fea..2fefd2f7 100644 --- a/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp +++ b/Architecture/amd64/cpu/AdvancedProgrammableInterruptController.cpp @@ -278,13 +278,23 @@ namespace APIC this->Write(APIC_LINT1, nmi); } - // Disable PIT - outb(0x43, 0x28); - outb(0x40, 0x0); + // Setup the spurrious interrupt vector + Spurious Spurious = {.raw = this->Read(APIC_SVR)}; + Spurious.Vector = IRQ223; // TODO: Should I map the IRQ to something? + Spurious.Software = 1; + this->Write(APIC_SVR, Spurious.raw); - // Disable PIC - outb(0x21, 0xFF); - outb(0xA1, 0xFF); + static int once = 0; + if (!once++) + { + // Disable PIT + outb(0x43, 0x28); + outb(0x40, 0x0); + + // Disable PIC + outb(0x21, 0xFF); + outb(0xA1, 0xFF); + } } APIC::~APIC() @@ -315,12 +325,6 @@ namespace APIC trace("Initializing APIC timer on CPU %d", GetCurrentCPU()->ID); - // Setup the spurrious interrupt vector - Spurious Spurious = {.raw = this->lapic->Read(APIC_SVR)}; - Spurious.Vector = IRQ223; // TODO: Should I map the IRQ to something? - Spurious.Software = 1; - this->lapic->Write(APIC_SVR, Spurious.raw); - this->lapic->Write(APIC_TDCR, Divider); this->lapic->Write(APIC_TICR, 0xFFFFFFFF); diff --git a/Core/Crash/CrashHandler.cpp b/Core/Crash/CrashHandler.cpp index 84713a9f..21fd2518 100644 --- a/Core/Crash/CrashHandler.cpp +++ b/Core/Crash/CrashHandler.cpp @@ -288,6 +288,7 @@ namespace CrashHandler __no_stack_protector void Handle(void *Data) { + // TODO: SUPPORT SMP CPU::Interrupts(CPU::Disable); error("An exception occurred!"); if (TaskManager) diff --git a/SystemCalls/Native.cpp b/SystemCalls/Native.cpp index b9717272..68609430 100644 --- a/SystemCalls/Native.cpp +++ b/SystemCalls/Native.cpp @@ -40,7 +40,7 @@ uint64_t HandleNativeSyscalls(SyscallsFrame *Frame) error("Syscall %#llx failed.", Frame->rax); return -1; } - debug("%#lx %#lx %#lx %#lx %#lx %#lx", Frame->rdi, Frame->rsi, Frame->rdx, Frame->rcx, Frame->r8, Frame->r9); + debug("[%#lx]->( %#lx %#lx %#lx %#lx %#lx %#lx )", Frame->rax, Frame->rdi, Frame->rsi, Frame->rdx, Frame->rcx, Frame->r8, Frame->r9); uint64_t ret = call((uint64_t)Frame, Frame->rdi, Frame->rsi, Frame->rdx, Frame->r10, Frame->r8, Frame->r9); Frame->rax = ret; return ret; diff --git a/Tasking/Task.cpp b/Tasking/Task.cpp index b090b194..2ddd092c 100644 --- a/Tasking/Task.cpp +++ b/Tasking/Task.cpp @@ -39,7 +39,14 @@ namespace Tasking #endif } - void Task::Schedule() { OneShot(100); } + void Task::Schedule() + { + OneShot(100); + // APIC::InterruptCommandRegisterLow icr; + // icr.Vector = CPU::x64::IRQ16; + // icr.Level = APIC::APICLevel::Assert; + // ((APIC::APIC *)Interrupts::apic[0])->IPI(GetCurrentCPU()->ID, icr); + } __attribute__((naked, used, no_stack_protector)) void IdleProcessLoop() { @@ -54,6 +61,28 @@ namespace Tasking #endif } + __no_stack_protector bool Task::InvalidPCB(PCB *pcb) + { + if (!pcb) + return true; + if (pcb >= (PCB *)0xfffffffffffff000) + return true; + if (!Memory::Virtual().Check((void *)pcb)) + return true; + return false; + } + + __no_stack_protector bool Task::InvalidTCB(TCB *tcb) + { + if (!tcb) + return true; + if (tcb >= (TCB *)0xfffffffffffff000) + return true; + if (!Memory::Virtual().Check((void *)tcb)) + return true; + return false; + } + __no_stack_protector void Task::RemoveThread(TCB *Thread) { for (uint64_t i = 0; i < Thread->Parent->Threads.size(); i++) @@ -324,6 +353,8 @@ namespace Tasking return; } CPUData *CurrentCPU = GetCurrentCPU(); + // if (CurrentCPU->ID != 0) + // debug("Scheduler called from CPU %d", CurrentCPU->ID); schedbg("Scheduler called on CPU %d.", CurrentCPU->ID); schedbg("%d: %ld%%", CurrentCPU->ID, GetUsage(CurrentCPU->ID)); @@ -448,6 +479,31 @@ namespace Tasking CurrentCPU->CurrentProcess->Status = TaskStatus::Running; CurrentCPU->CurrentThread->Status = TaskStatus::Running; + // This should never happen, but if it does, we can fix it. + if (CurrentCPU->CurrentThread->Security.TrustLevel == TaskTrustLevel::User) + { + if (CurrentCPU->CurrentThread->Registers.cs != GDT_USER_CODE || + CurrentCPU->CurrentThread->Registers.ss != GDT_USER_DATA) + { + warn("Wrong CS or SS for user process! (Code:%#lx, Data:%#lx != Code:%#lx, Data:%#lx)", + CurrentCPU->CurrentThread->Registers.cs, CurrentCPU->CurrentThread->Registers.ss, + GDT_USER_CODE, GDT_USER_DATA); + CurrentCPU->CurrentThread->Registers.cs = GDT_USER_CODE; + CurrentCPU->CurrentThread->Registers.ss = GDT_USER_DATA; + } + } + else + { + if (CurrentCPU->CurrentThread->Registers.cs != GDT_KERNEL_CODE || + CurrentCPU->CurrentThread->Registers.ss != GDT_KERNEL_DATA) + { + warn("Wrong CS or SS for kernel process! (Code:%#lx, Data:%#lx != Code:%#lx, Data:%#lx", + CurrentCPU->CurrentThread->Registers.cs, CurrentCPU->CurrentThread->Registers.ss, + GDT_KERNEL_CODE, GDT_KERNEL_DATA); + CurrentCPU->CurrentThread->Registers.cs = GDT_KERNEL_CODE; + CurrentCPU->CurrentThread->Registers.ss = GDT_KERNEL_DATA; + } + } *Frame = CurrentCPU->CurrentThread->Registers; GlobalDescriptorTable::SetKernelStack((void *)((uint64_t)CurrentCPU->CurrentThread->Stack + STACK_SIZE)); CPU::x64::writecr3({.raw = (uint64_t)CurrentCPU->CurrentProcess->PageTable}); @@ -514,7 +570,7 @@ namespace Tasking } RealEnd: { - schedbg("Scheduler end"); + __sync_synchronize(); // TODO: Is this really needed? } } @@ -691,6 +747,9 @@ namespace Tasking Thread->Registers.ds = GDT_USER_DATA; Thread->Registers.ss = GDT_USER_DATA; Thread->Registers.rflags.AlwaysOne = 1; + // Thread->Registers.rflags.PF = 1; + // Thread->Registers.rflags.SF = 1; + // Thread->Registers.rflags.IOPL = 3; Thread->Registers.rflags.IF = 1; Thread->Registers.rflags.ID = 1; Thread->Registers.rsp = ((uint64_t)Thread->Stack + STACK_SIZE); @@ -975,18 +1034,19 @@ namespace Tasking debug("Tasking Started"); #if defined(__amd64__) ((APIC::Timer *)Interrupts::apicTimer[0])->OneShot(CPU::x64::IRQ16, 100); -#elif defined(__i386__) -#elif defined(__aarch64__) -#endif for (int i = 1; i < SMP::CPUCores; i++) { - // TODO: Start other cores will end up in a deadlock. HOW? + // ((APIC::Timer *)Interrupts::apicTimer[i])->OneShot(CPU::x64::IRQ16, 100); + // TODO: Lock was the fault here. Now crash handler should support SMP. // APIC::InterruptCommandRegisterLow icr; // icr.Vector = CPU::x64::IRQ16; // icr.Level = APIC::APICLevel::Assert; // ((APIC::APIC *)Interrupts::apic[0])->IPI(i, icr); } +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif } Task::~Task() diff --git a/include/syscalls.hpp b/include/syscalls.hpp index 8155a959..6949faa4 100644 --- a/include/syscalls.hpp +++ b/include/syscalls.hpp @@ -10,7 +10,6 @@ typedef struct SyscallsFrame uint64_t rbp, rdi, rsi, rdx, rcx, rbx, rax; uint64_t InterruptNumber, ErrorCode, rip, cs, rflags, rsp, ss; #elif defined(__i386__) - uint64_t r15, r14, r13, r12, r11, r10, r9, r8; uint64_t ebp, edi, esi, edx, ecx, ebx, eax; uint64_t InterruptNumber, ErrorCode, eip, cs, eflags, esp, ss; #elif defined(__aarch64__) diff --git a/include/task.hpp b/include/task.hpp index 323dfcc5..feeade55 100644 --- a/include/task.hpp +++ b/include/task.hpp @@ -172,23 +172,8 @@ namespace Tasking PCB *IdleProcess = nullptr; TCB *IdleThread = nullptr; - __no_stack_protector bool InvalidPCB(PCB *pcb) - { - if (pcb >= (PCB *)0xfffffffffffff000) - return true; - if (!pcb) - return true; - return false; - } - - __no_stack_protector bool InvalidTCB(TCB *tcb) - { - if (tcb >= (TCB *)0xfffffffffffff000) - return true; - if (!tcb) - return true; - return false; - } + bool InvalidPCB(PCB *pcb); + bool InvalidTCB(TCB *tcb); void RemoveThread(TCB *tcb); void RemoveProcess(PCB *pcb);