mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-12 09:09:47 +12:00
[GSP] Add interrupt relay event
This commit is contained in:
parent
d0db2eefce
commit
5daade05d8
4 changed files with 25 additions and 5 deletions
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
#include "PICA/gpu.hpp"
|
#include "PICA/gpu.hpp"
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
#include "kernel_types.hpp"
|
#include "kernel_types.hpp"
|
||||||
|
@ -16,16 +17,21 @@ enum class GPUInterrupt : u8 {
|
||||||
DMA = 6
|
DMA = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// More circular dependencies
|
||||||
|
class Kernel;
|
||||||
|
|
||||||
class GPUService {
|
class GPUService {
|
||||||
Handle handle = KernelHandles::GPU;
|
Handle handle = KernelHandles::GPU;
|
||||||
Memory& mem;
|
Memory& mem;
|
||||||
GPU& gpu;
|
GPU& gpu;
|
||||||
|
Kernel& kernel;
|
||||||
u32& currentPID; // Process ID of the current process
|
u32& currentPID; // Process ID of the current process
|
||||||
u8* sharedMem; // Pointer to GSP shared memory
|
u8* sharedMem; // Pointer to GSP shared memory
|
||||||
|
|
||||||
// At any point in time only 1 process has privileges to use rendering functions
|
// At any point in time only 1 process has privileges to use rendering functions
|
||||||
// This is the PID of that process
|
// This is the PID of that process
|
||||||
u32 privilegedProcess;
|
u32 privilegedProcess;
|
||||||
|
std::optional<Handle> interruptEvent;
|
||||||
|
|
||||||
MAKE_LOG_FUNCTION(log, gspGPULogger)
|
MAKE_LOG_FUNCTION(log, gspGPULogger)
|
||||||
void processCommandBuffer();
|
void processCommandBuffer();
|
||||||
|
@ -51,7 +57,8 @@ class GPUService {
|
||||||
void flushCacheRegions(u32* cmd);
|
void flushCacheRegions(u32* cmd);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GPUService(Memory& mem, GPU& gpu, u32& currentPID) : mem(mem), gpu(gpu), currentPID(currentPID) {}
|
GPUService(Memory& mem, GPU& gpu, Kernel& kernel, u32& currentPID) : mem(mem), gpu(gpu),
|
||||||
|
kernel(kernel), currentPID(currentPID) {}
|
||||||
void reset();
|
void reset();
|
||||||
void handleSyncRequest(u32 messagePointer);
|
void handleSyncRequest(u32 messagePointer);
|
||||||
void requestInterrupt(GPUInterrupt type);
|
void requestInterrupt(GPUInterrupt type);
|
||||||
|
|
|
@ -213,9 +213,8 @@ void Kernel::waitSynchronizationN() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Helpers::panic("WaitSyncAny can't instantly acquire :(");
|
regs[0] = SVCResult::Success; // If the thread times out, this should be adjusted to SVCResult::Timeout
|
||||||
regs[0] = SVCResult::Success;
|
regs[1] = handleCount - 1; // When the thread exits, this will be adjusted to mirror which handle woke us up
|
||||||
regs[1] = handleCount - 1; // FIX THIS
|
|
||||||
t.waitList.resize(handleCount);
|
t.waitList.resize(handleCount);
|
||||||
t.status = ThreadStatus::WaitSyncAny;
|
t.status = ThreadStatus::WaitSyncAny;
|
||||||
t.outPointer = outPointer;
|
t.outPointer = outPointer;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "services/gsp_gpu.hpp"
|
#include "services/gsp_gpu.hpp"
|
||||||
#include "ipc.hpp"
|
#include "ipc.hpp"
|
||||||
|
#include "kernel.hpp"
|
||||||
|
|
||||||
// Commands used with SendSyncRequest targetted to the GSP::GPU service
|
// Commands used with SendSyncRequest targetted to the GSP::GPU service
|
||||||
namespace ServiceCommands {
|
namespace ServiceCommands {
|
||||||
|
@ -38,6 +39,7 @@ namespace Result {
|
||||||
|
|
||||||
void GPUService::reset() {
|
void GPUService::reset() {
|
||||||
privilegedProcess = 0xFFFFFFFF; // Set the privileged process to an invalid handle
|
privilegedProcess = 0xFFFFFFFF; // Set the privileged process to an invalid handle
|
||||||
|
interruptEvent = std::nullopt;
|
||||||
sharedMem = nullptr;
|
sharedMem = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +92,13 @@ void GPUService::registerInterruptRelayQueue(u32 messagePointer) {
|
||||||
const u32 eventHandle = mem.read32(messagePointer + 12);
|
const u32 eventHandle = mem.read32(messagePointer + 12);
|
||||||
log("GSP::GPU::RegisterInterruptRelayQueue (flags = %X, event handle = %X)\n", flags, eventHandle);
|
log("GSP::GPU::RegisterInterruptRelayQueue (flags = %X, event handle = %X)\n", flags, eventHandle);
|
||||||
|
|
||||||
|
const auto event = kernel.getObject(eventHandle, KernelObjectType::Event);
|
||||||
|
if (event == nullptr) { // Check if interrupt event is invalid
|
||||||
|
Helpers::panic("Invalid event passed to GSP::GPU::RegisterInterruptRelayQueue");
|
||||||
|
} else {
|
||||||
|
interruptEvent = eventHandle;
|
||||||
|
}
|
||||||
|
|
||||||
mem.write32(messagePointer, IPC::responseHeader(0x13, 2, 2));
|
mem.write32(messagePointer, IPC::responseHeader(0x13, 2, 2));
|
||||||
mem.write32(messagePointer + 4, Result::SuccessRegisterIRQ); // First init returns a unique result
|
mem.write32(messagePointer + 4, Result::SuccessRegisterIRQ); // First init returns a unique result
|
||||||
mem.write32(messagePointer + 8, 0); // TODO: GSP module thread index
|
mem.write32(messagePointer + 8, 0); // TODO: GSP module thread index
|
||||||
|
@ -109,6 +118,11 @@ void GPUService::requestInterrupt(GPUInterrupt type) {
|
||||||
|
|
||||||
sharedMem[2] = 0; // Set error code to 0
|
sharedMem[2] = 0; // Set error code to 0
|
||||||
sharedMem[0xC + flagIndex] = static_cast<u8>(type); // Write interrupt type to queue
|
sharedMem[0xC + flagIndex] = static_cast<u8>(type); // Write interrupt type to queue
|
||||||
|
|
||||||
|
// Signal interrupt event
|
||||||
|
if (interruptEvent.has_value()) {
|
||||||
|
kernel.signalEvent(interruptEvent.value());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPUService::writeHwRegs(u32 messagePointer) {
|
void GPUService::writeHwRegs(u32 messagePointer) {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
ServiceManager::ServiceManager(std::array<u32, 16>& regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel)
|
ServiceManager::ServiceManager(std::array<u32, 16>& regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel)
|
||||||
: regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), apt(mem, kernel), cam(mem), cecd(mem), cfg(mem),
|
: regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), apt(mem, kernel), cam(mem), cecd(mem), cfg(mem),
|
||||||
dsp(mem), hid(mem), frd(mem), fs(mem, kernel), gsp_gpu(mem, gpu, currentPID), gsp_lcd(mem), ldr(mem), mic(mem),
|
dsp(mem), hid(mem), frd(mem), fs(mem, kernel), gsp_gpu(mem, gpu, kernel, currentPID), gsp_lcd(mem), ldr(mem), mic(mem),
|
||||||
nim(mem), ndm(mem), ptm(mem), y2r(mem, kernel) {}
|
nim(mem), ndm(mem), ptm(mem), y2r(mem, kernel) {}
|
||||||
|
|
||||||
static constexpr int MAX_NOTIFICATION_COUNT = 16;
|
static constexpr int MAX_NOTIFICATION_COUNT = 16;
|
||||||
|
|
Loading…
Add table
Reference in a new issue