From 77078f73b3da11bd69969edcf5247b3b3e111a4b Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Tue, 20 Sep 2022 16:50:20 +0300 Subject: [PATCH] [Kernel] Fix ArbitrateAddress --- include/kernel/kernel.hpp | 1 + include/kernel/kernel_types.hpp | 17 ++++++++++------- src/core/kernel/address_arbiter.cpp | 10 +++++----- src/core/kernel/threads.cpp | 8 ++++++++ src/core/memory.cpp | 2 +- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp index 9b36923c..14be3fa2 100644 --- a/include/kernel/kernel.hpp +++ b/include/kernel/kernel.hpp @@ -66,6 +66,7 @@ class Kernel { Handle makeSession(Handle port); Handle makeThread(u32 entrypoint, u32 initialSP, u32 priority, u32 id, ThreadStatus status = ThreadStatus::Dormant); + void sleepThreadOnArbiter(u32 waitingAddress); void switchThread(int newThreadIndex); std::optional getPortHandle(const char* name); diff --git a/include/kernel/kernel_types.hpp b/include/kernel/kernel_types.hpp index a20b4c15..f6a21dfb 100644 --- a/include/kernel/kernel_types.hpp +++ b/include/kernel/kernel_types.hpp @@ -88,13 +88,13 @@ struct Session { }; enum class ThreadStatus { - Running, // Currently running - Ready, // Ready to run - WaitArb, // Waiting on an address arbiter - WaitSleep, // Waiting due to a SleepThread SVC - WaitIPC, // Waiting for the reply from an IPC request - Dormant, // Created but not yet made ready - Dead // Run to completion, or forcefully terminated + Running, // Currently running + Ready, // Ready to run + WaitArbiter, // Waiting on an address arbiter + WaitSleep, // Waiting due to a SleepThread SVC + WaitIPC, // Waiting for the reply from an IPC request + Dormant, // Created but not yet made ready + Dead // Run to completion, or forcefully terminated }; struct Thread { @@ -104,6 +104,9 @@ struct Thread { u32 processorID; ThreadStatus status; Handle handle; // OS handle for this thread + + // The waiting address for threads that are waiting on an AddressArbiter + u32 waitingAddress; // Thread context used for switching between threads std::array gprs; diff --git a/src/core/kernel/address_arbiter.cpp b/src/core/kernel/address_arbiter.cpp index 2cd9b749..451921ed 100644 --- a/src/core/kernel/address_arbiter.cpp +++ b/src/core/kernel/address_arbiter.cpp @@ -34,7 +34,7 @@ void Kernel::arbitrateAddress() { const Handle handle = regs[0]; const u32 address = regs[1]; const u32 type = regs[2]; - const s32 value = regs[3]; + const s32 value = s32(regs[3]); const s64 ns = s64(u64(regs[4]) | (u64(regs[5]) << 32)); printf("ArbitrateAddress(Handle = %X, address = %08X, type = %s, value = %d, ns = %lld)\n", handle, address, @@ -50,17 +50,19 @@ void Kernel::arbitrateAddress() { Helpers::panic("ArbitrateAddres:: Unaligned address"); } - if (value > 4) [[unlikely]] { + if (type > 4) [[unlikely]] { regs[0] = SVCResult::InvalidEnumValueAlt; return; } + // This needs to put the error code in r0 before we change threats + regs[0] = SVCResult::Success; switch (static_cast(type)) { // Puts this thread to sleep if word < value until another thread signals the address with the type SIGNAL case ArbitrationType::WaitIfLess: { s32 word = static_cast(mem.read32(address)); // Yes this is meant to be signed if (word < value) { - Helpers::panic("Needa sleep"); + sleepThreadOnArbiter(address); } break; } @@ -68,6 +70,4 @@ void Kernel::arbitrateAddress() { default: Helpers::panic("ArbitrateAddress: Unimplemented type %s", arbitrationTypeToString(type)); } - - regs[0] = SVCResult::Success; } \ No newline at end of file diff --git a/src/core/kernel/threads.cpp b/src/core/kernel/threads.cpp index c71cb020..a5d3273f 100644 --- a/src/core/kernel/threads.cpp +++ b/src/core/kernel/threads.cpp @@ -80,4 +80,12 @@ void Kernel::createThread() { regs[0] = SVCResult::Success; regs[1] = makeThread(entrypoint, initialSP, priority, id); +} + +void Kernel::sleepThreadOnArbiter(u32 waitingAddress) { + Thread& t = threads[currentThreadIndex]; + + t.status = ThreadStatus::WaitArbiter; + t.waitingAddress = waitingAddress; + Helpers::panic("AOWPWOOOPDQ"); } \ No newline at end of file diff --git a/src/core/memory.cpp b/src/core/memory.cpp index c0af43be..3cd34f1f 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -302,7 +302,7 @@ void Memory::mapGSPSharedMemory(u32 vaddr, u32 myPerms, u32 otherPerms) { // Wipe the GSP memory allocation from existence gspMemIndex = std::nullopt; - //std::erase(lockedMemoryInfo, index); + lockedMemoryInfo.erase(lockedMemoryInfo.begin() + index); if (myPerms == 0x10000000) { myPerms = 3;