From a5384095df616cc88482ee99a39e96371d0c9b65 Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Sun, 18 Sep 2022 19:08:16 +0300 Subject: [PATCH] Fix GSP::GPU::RegisterInterruptRelayQueue and add ResetType defs --- include/kernel/kernel.hpp | 4 +++- include/kernel/kernel_types.hpp | 11 +++++++++++ include/services/gsp_gpu.hpp | 1 + src/core/kernel/events.cpp | 25 +++++++++++++++++++++---- src/core/services/gsp_gpu.cpp | 21 +++++++++++++++++++-- 5 files changed, 55 insertions(+), 7 deletions(-) diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp index cbb9e293..f8bdb0ee 100644 --- a/include/kernel/kernel.hpp +++ b/include/kernel/kernel.hpp @@ -49,7 +49,7 @@ class Kernel { return handleCounter++; } - Handle makeEvent(u32 resetType); + Handle makeEvent(ResetType resetType); Handle makeProcess(); Handle makePort(const char* name); Handle makeSession(Handle port); @@ -61,7 +61,9 @@ class Kernel { s32 getCurrentResourceValue(const KernelObject* limit, u32 resourceName); u32 getMaxForResource(const KernelObject* limit, u32 resourceName); u32 getTLSPointer(); + std::string getProcessName(u32 pid); + const char* resetTypeToString(u32 type); // SVC implementations void createAddressArbiter(); diff --git a/include/kernel/kernel_types.hpp b/include/kernel/kernel_types.hpp index f7c36fae..d4859eab 100644 --- a/include/kernel/kernel_types.hpp +++ b/include/kernel/kernel_types.hpp @@ -38,6 +38,13 @@ enum ResourceTypes { CPU_TIME = 9 }; +// Reset types (for use with events and timers) +enum ResetType { + RESET_ONESHOT = 0, // When the primitive is signaled, it will wake up exactly one thread and will clear itself automatically. + RESET_STICKY = 1, // When the primitive is signaled, it will wake up all threads and it won't clear itself automatically. + RESET_PULSE = 2, // Only meaningful for timers: same as ONESHOT but it will periodically signal the timer instead of just once. +}; + struct ResourceLimits { Handle handle; @@ -49,6 +56,10 @@ struct ProcessData { ResourceLimits limits; }; +struct EventData { + ResetType resetType = RESET_ONESHOT; +}; + enum class PortType { Generic, ServiceManager // For the service manager port "srv:" diff --git a/include/services/gsp_gpu.hpp b/include/services/gsp_gpu.hpp index 55ba66f6..305130e5 100644 --- a/include/services/gsp_gpu.hpp +++ b/include/services/gsp_gpu.hpp @@ -14,6 +14,7 @@ class GPUService { // Service commands void acquireRight(u32 messagePointer); + void registerInterruptRelayQueue(u32 messagePointer); public: GPUService(Memory& mem, u32& currentPID) : mem(mem), currentPID(currentPID) {} diff --git a/src/core/kernel/events.cpp b/src/core/kernel/events.cpp index ed87c314..46ae4a2b 100644 --- a/src/core/kernel/events.cpp +++ b/src/core/kernel/events.cpp @@ -1,8 +1,21 @@ #include "kernel.hpp" -// TODO: What the fuck is resetType meant to be? -Handle Kernel::makeEvent(u32 resetType) { +const char* Kernel::resetTypeToString(u32 type) { + switch (type) { + case 0: return "RESET_ONESHOT"; + case 1: return "RESET_STICKY"; + case 2: return "RESET_PULSE"; + default: return "Invalid"; + } +} + +Handle Kernel::makeEvent(ResetType resetType) { Handle ret = makeObject(KernelObjectType::Event); + objects[ret].data = new EventData(); + + auto eventData = static_cast(objects[ret].data); + eventData->resetType = resetType; + return ret; } @@ -12,9 +25,13 @@ Handle Kernel::makeEvent(u32 resetType) { void Kernel::createEvent() { const u32 outPointer = regs[0]; const u32 resetType = regs[1]; - printf("CreateEvent(handle pointer = %08X, resetType = %d)\n", outPointer, resetType); - Handle handle = makeEvent(resetType); + if (resetType > 2) + Helpers::panic("Invalid reset type for event %d", resetType); + + printf("CreateEvent(handle pointer = %08X, resetType = %s)\n", outPointer, resetTypeToString(resetType)); + + Handle handle = makeEvent(static_cast(resetType)); regs[0] = SVCResult::Success; regs[1] = handle; mem.write32(outPointer, handle); diff --git a/src/core/services/gsp_gpu.cpp b/src/core/services/gsp_gpu.cpp index 6d83e951..0225cbef 100644 --- a/src/core/services/gsp_gpu.cpp +++ b/src/core/services/gsp_gpu.cpp @@ -2,13 +2,15 @@ namespace GPUCommands { enum : u32 { - AcquireRight = 0x00160042 + AcquireRight = 0x00160042, + RegisterInterruptRelayQueue = 0x00130042 }; } namespace Result { enum : u32 { Success = 0, + SuccessRegisterIRQ = 0x2A07 }; } @@ -20,6 +22,7 @@ void GPUService::handleSyncRequest(u32 messagePointer) { const u32 command = mem.read32(messagePointer); switch (command) { case GPUCommands::AcquireRight: acquireRight(messagePointer); break; + case GPUCommands::RegisterInterruptRelayQueue: registerInterruptRelayQueue(messagePointer); break; ; default: Helpers::panic("GPU service requested. Command: %08X\n", command); } } @@ -27,7 +30,7 @@ void GPUService::handleSyncRequest(u32 messagePointer) { void GPUService::acquireRight(u32 messagePointer) { const u32 flag = mem.read32(messagePointer + 4); const u32 pid = mem.read32(messagePointer + 12); - printf("GSP::GPU::acquireRight (flag = %d, pid = %X)\n", flag, pid); + printf("GSP::GPU::AcquireRight (flag = %X, pid = %X)\n", flag, pid); if (flag != 0) { Helpers::panic("GSP::GPU::acquireRight with flag != 0 needs to perform additional initialization"); @@ -40,4 +43,18 @@ void GPUService::acquireRight(u32 messagePointer) { } mem.write32(messagePointer + 4, Result::Success); +} + +// TODO: What is the flags field meant to be? +// What is the "GSP module thread index" meant to be? +// How does the shared memory handle thing work? +void GPUService::registerInterruptRelayQueue(u32 messagePointer) { + const u32 flags = mem.read32(messagePointer + 4); + const u32 eventHandle = mem.read32(messagePointer + 12); + printf("GSP::GPU::RegisterInterruptRelayQueue (flags = %X, event handle = %X)\n", flags, eventHandle); + + mem.write32(messagePointer + 4, Result::SuccessRegisterIRQ); + mem.write32(messagePointer + 8, 0); // TODO: GSP module thread index + mem.write32(messagePointer + 12, 0); // Translation descriptor + mem.write32(messagePointer + 16, 0); // TODO: shared memory handle } \ No newline at end of file