Fix GSP::GPU::RegisterInterruptRelayQueue and add ResetType defs

This commit is contained in:
wheremyfoodat 2022-09-18 19:08:16 +03:00
parent a91035abf4
commit a5384095df
5 changed files with 55 additions and 7 deletions

View file

@ -49,7 +49,7 @@ class Kernel {
return handleCounter++; return handleCounter++;
} }
Handle makeEvent(u32 resetType); Handle makeEvent(ResetType resetType);
Handle makeProcess(); Handle makeProcess();
Handle makePort(const char* name); Handle makePort(const char* name);
Handle makeSession(Handle port); Handle makeSession(Handle port);
@ -61,7 +61,9 @@ class Kernel {
s32 getCurrentResourceValue(const KernelObject* limit, u32 resourceName); s32 getCurrentResourceValue(const KernelObject* limit, u32 resourceName);
u32 getMaxForResource(const KernelObject* limit, u32 resourceName); u32 getMaxForResource(const KernelObject* limit, u32 resourceName);
u32 getTLSPointer(); u32 getTLSPointer();
std::string getProcessName(u32 pid); std::string getProcessName(u32 pid);
const char* resetTypeToString(u32 type);
// SVC implementations // SVC implementations
void createAddressArbiter(); void createAddressArbiter();

View file

@ -38,6 +38,13 @@ enum ResourceTypes {
CPU_TIME = 9 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 { struct ResourceLimits {
Handle handle; Handle handle;
@ -49,6 +56,10 @@ struct ProcessData {
ResourceLimits limits; ResourceLimits limits;
}; };
struct EventData {
ResetType resetType = RESET_ONESHOT;
};
enum class PortType { enum class PortType {
Generic, Generic,
ServiceManager // For the service manager port "srv:" ServiceManager // For the service manager port "srv:"

View file

@ -14,6 +14,7 @@ class GPUService {
// Service commands // Service commands
void acquireRight(u32 messagePointer); void acquireRight(u32 messagePointer);
void registerInterruptRelayQueue(u32 messagePointer);
public: public:
GPUService(Memory& mem, u32& currentPID) : mem(mem), currentPID(currentPID) {} GPUService(Memory& mem, u32& currentPID) : mem(mem), currentPID(currentPID) {}

View file

@ -1,8 +1,21 @@
#include "kernel.hpp" #include "kernel.hpp"
// TODO: What the fuck is resetType meant to be? const char* Kernel::resetTypeToString(u32 type) {
Handle Kernel::makeEvent(u32 resetType) { 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); Handle ret = makeObject(KernelObjectType::Event);
objects[ret].data = new EventData();
auto eventData = static_cast<EventData*>(objects[ret].data);
eventData->resetType = resetType;
return ret; return ret;
} }
@ -12,9 +25,13 @@ Handle Kernel::makeEvent(u32 resetType) {
void Kernel::createEvent() { void Kernel::createEvent() {
const u32 outPointer = regs[0]; const u32 outPointer = regs[0];
const u32 resetType = regs[1]; 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>(resetType));
regs[0] = SVCResult::Success; regs[0] = SVCResult::Success;
regs[1] = handle; regs[1] = handle;
mem.write32(outPointer, handle); mem.write32(outPointer, handle);

View file

@ -2,13 +2,15 @@
namespace GPUCommands { namespace GPUCommands {
enum : u32 { enum : u32 {
AcquireRight = 0x00160042 AcquireRight = 0x00160042,
RegisterInterruptRelayQueue = 0x00130042
}; };
} }
namespace Result { namespace Result {
enum : u32 { enum : u32 {
Success = 0, Success = 0,
SuccessRegisterIRQ = 0x2A07
}; };
} }
@ -20,6 +22,7 @@ void GPUService::handleSyncRequest(u32 messagePointer) {
const u32 command = mem.read32(messagePointer); const u32 command = mem.read32(messagePointer);
switch (command) { switch (command) {
case GPUCommands::AcquireRight: acquireRight(messagePointer); break; case GPUCommands::AcquireRight: acquireRight(messagePointer); break;
case GPUCommands::RegisterInterruptRelayQueue: registerInterruptRelayQueue(messagePointer); break;
; default: Helpers::panic("GPU service requested. Command: %08X\n", command); ; default: Helpers::panic("GPU service requested. Command: %08X\n", command);
} }
} }
@ -27,7 +30,7 @@ void GPUService::handleSyncRequest(u32 messagePointer) {
void GPUService::acquireRight(u32 messagePointer) { void GPUService::acquireRight(u32 messagePointer) {
const u32 flag = mem.read32(messagePointer + 4); const u32 flag = mem.read32(messagePointer + 4);
const u32 pid = mem.read32(messagePointer + 12); 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) { if (flag != 0) {
Helpers::panic("GSP::GPU::acquireRight with flag != 0 needs to perform additional initialization"); 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); 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
} }