mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-06 22:25:41 +12:00
Fix GSP::GPU::RegisterInterruptRelayQueue and add ResetType defs
This commit is contained in:
parent
a91035abf4
commit
a5384095df
5 changed files with 55 additions and 7 deletions
|
@ -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();
|
||||||
|
|
|
@ -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:"
|
||||||
|
|
|
@ -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) {}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue