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++;
}
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();

View file

@ -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:"

View file

@ -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) {}

View file

@ -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<EventData*>(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>(resetType));
regs[0] = SVCResult::Success;
regs[1] = handle;
mem.write32(outPointer, handle);

View file

@ -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
}