diff --git a/Architecture/i686/LockAssembly.S b/Architecture/i686/LockAssembly.S new file mode 100644 index 0000000..f918193 --- /dev/null +++ b/Architecture/i686/LockAssembly.S @@ -0,0 +1,70 @@ +# https://en.wikipedia.org/wiki/Spinlock + +.text + +# void SpinLock_Lock(volatile uint32_t *LockData) +.global SpinLock_Lock + +# void SpinLock_Unlock(volatile uint32_t *LockData) +.global SpinLock_Unlock + +# uint32_t SpinLock_CheckAndLock(volatile uint32_t *LockData) +.global SpinLock_CheckAndLock + +# uint32_t SpinLock_WithTimeout(volatile uint32_t *LockData, volatile uint32_t Iterations) +.global SpinLock_WithTimeout + +# DeadLockHandler(volatile *LockStructure) +.extern DeadLockHandler + +SpinLock_Lock: + xor %eax,%eax + lock btsl $0,(%edi) + jc Spin + ret +Spin: + inc %eax + cmp $0x10000000,%eax + je Deadlock + pause + test $1,(%edi) + jnz Spin + jmp SpinLock_Lock + +SpinLock_Unlock: + lock btrl $0,(%edi) + ret + +Deadlock: + push %edi + push %edi + xor %eax,%eax + call DeadLockHandler + pop %edi + pop %edi + jmp Spin + +SpinLock_CheckAndLock: + xor %eax,%eax + lock btsl $0,(%edi) + setc %al + ret + +SpinLock_WithTimeout: + xor %eax,%eax +SpinTimeout: + inc %eax + lock btsl $0,(%edi) + setc %bl + cmp $0,%bl + je LockAquired + cmp %esi,%eax + je LockTimedOut + pause + jmp SpinTimeout +LockAquired: + mov $1,%eax + ret +LockTimedOut: + xor %eax,%eax + ret diff --git a/Tasking/Task.cpp b/Tasking/Task.cpp index 0658726..25b290b 100644 --- a/Tasking/Task.cpp +++ b/Tasking/Task.cpp @@ -577,9 +577,13 @@ namespace Tasking Task::Task(const IP EntryPoint) : Interrupts::Handler(CPU::x64::IRQ16) { SmartCriticalSection(TaskingLock); + +#if defined(__amd64__) for (int i = 0; i < SMP::CPUCores; i++) ((APIC::APIC *)Interrupts::apic[i])->RedirectIRQ(i, CPU::x64::IRQ16 - CPU::x64::IRQ0, 1); - +#elif defined(__i386__) +#elif defined(__aarch64__) +#endif KPrint("Starting Tasking With Instruction Pointer: %p (\e666666%s\eCCCCCC)", EntryPoint, KernelSymbolTable->GetSymbolFromAddress(EntryPoint)); TaskingLock.Unlock(); @@ -597,7 +601,7 @@ namespace Tasking debug("Created Kernel Process: %s and Thread: %s", kproc->Name, kthrd->Name); TaskingLock.Lock(__FUNCTION__); -#if defined(__amd64__) || defined(__i386__) +#if defined(__amd64__) uint32_t rax, rbx, rcx, rdx; CPU::x64::cpuid(0x1, &rax, &rbx, &rcx, &rdx); if (rcx & CPU::x64::CPUID_FEAT_RCX_MONITOR) diff --git a/include/cpu.hpp b/include/cpu.hpp index 28ea19e..f064a52 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -252,6 +252,23 @@ namespace CPU namespace x32 { + /** + * @brief CPUID + * + * @param Function Leaf + * @param eax EAX + * @param ebx EBX + * @param ecx ECX + * @param edx EDX + */ + static inline void cpuid(uint32_t Function, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) + { +#if defined(__i386__) + asmv("cpuid" + : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) + : "a"(Function)); +#endif + } } namespace x64 diff --git a/include/task.hpp b/include/task.hpp index 361a3d0..dca5f8c 100644 --- a/include/task.hpp +++ b/include/task.hpp @@ -20,7 +20,7 @@ namespace Tasking enum TaskArchitecture { UnknownArchitecture, - x86, + x32, x64, ARM, ARM64