From 0987da90f491d7f82ccb08b0c37e41fce6b29255 Mon Sep 17 00:00:00 2001 From: DH Date: Sun, 6 Aug 2023 17:29:28 +0300 Subject: [PATCH] [rpcsx-os] implement compute queue mapping --- rpcsx-os/iodev/dce.cpp | 10 +++--- rpcsx-os/iodev/dmem.cpp | 8 +++-- rpcsx-os/iodev/gc.cpp | 69 +++++++++++++++++++++++++++++------------ 3 files changed, 60 insertions(+), 27 deletions(-) diff --git a/rpcsx-os/iodev/dce.cpp b/rpcsx-os/iodev/dce.cpp index be0e11ae5..5fa339ebb 100644 --- a/rpcsx-os/iodev/dce.cpp +++ b/rpcsx-os/iodev/dce.cpp @@ -121,8 +121,8 @@ static orbis::ErrorCode dce_ioctl(orbis::File *file, std::uint64_t request, // 0x21 - adjust color auto args = reinterpret_cast(argp); - ORBIS_LOG_NOTICE("dce: FlipControl", args->id, args->arg2, args->ptr, - args->size); + // ORBIS_LOG_NOTICE("dce: FlipControl", args->id, args->arg2, args->ptr, + // args->size); if (args->id == 6) { // set flip rate? ORBIS_LOG_NOTICE("dce: FlipControl: set flip rate", args->arg2, args->ptr, @@ -218,9 +218,9 @@ static orbis::ErrorCode dce_ioctl(orbis::File *file, std::uint64_t request, // flip request auto args = reinterpret_cast(argp); - ORBIS_LOG_ERROR("dce: FlipRequestArgs", args->arg1, - args->displayBufferIndex, args->flipMode, args->flipArg, - args->arg5, args->arg6, args->arg7, args->arg8); + // ORBIS_LOG_ERROR("dce: FlipRequestArgs", args->arg1, + // args->displayBufferIndex, args->flipMode, args->flipArg, + // args->arg5, args->arg6, args->arg7, args->arg8); rx::bridge.sendFlip(args->displayBufferIndex, /*args->flipMode,*/ args->flipArg); diff --git a/rpcsx-os/iodev/dmem.cpp b/rpcsx-os/iodev/dmem.cpp index 7acc97d0f..e51dc2f85 100644 --- a/rpcsx-os/iodev/dmem.cpp +++ b/rpcsx-os/iodev/dmem.cpp @@ -17,7 +17,7 @@ struct AllocateDirectMemoryArgs { std::uint32_t memoryType; }; -static constexpr auto dmemSize = 4ul * 1024 * 1024 * 1024; +static constexpr auto dmemSize = 8ul * 1024 * 1024 * 1024; // static const std::uint64_t nextOffset = 0; // static const std::uint64_t memBeginAddress = 0xfe0000000; @@ -25,10 +25,11 @@ orbis::ErrorCode DmemDevice::mmap(void **address, std::uint64_t len, std::int32_t memoryType, std::int32_t prot, std::int32_t flags, std::int64_t directMemoryStart) { - ORBIS_LOG_WARNING("dmem mmap", index, directMemoryStart, memoryType); auto result = rx::vm::map(*address, len, prot, flags); + ORBIS_LOG_WARNING("dmem mmap", index, directMemoryStart, prot, flags, + memoryType, result); if (result == (void *)-1) { return orbis::ErrorCode::NOMEM; // TODO } @@ -75,6 +76,9 @@ static orbis::ErrorCode dmem_ioctl(orbis::File *file, std::uint64_t request, args->alignment, args->memoryType, alignedOffset); if (alignedOffset + args->len > dmemSize) { + ORBIS_LOG_ERROR("dmem allocateDirectMemory: out of memory", alignedOffset, + args->len, alignedOffset + args->len); + return orbis::ErrorCode::NOMEM; } diff --git a/rpcsx-os/iodev/gc.cpp b/rpcsx-os/iodev/gc.cpp index 2e7cb213e..c3b57867c 100644 --- a/rpcsx-os/iodev/gc.cpp +++ b/rpcsx-os/iodev/gc.cpp @@ -2,12 +2,25 @@ #include "io-device.hpp" #include "orbis/KernelAllocator.hpp" #include "orbis/file.hpp" +#include "orbis/thread/Thread.hpp" #include "orbis/utils/Logs.hpp" +#include "orbis/utils/SharedMutex.hpp" #include "vm.hpp" #include +#include #include +struct ComputeQueue { + std::uint64_t ringBaseAddress{}; + std::uint64_t readPtrAddress{}; + std::uint64_t dingDongPtr{}; + std::uint64_t offset{}; + std::uint64_t len{}; +}; + struct GcDevice : public IoDevice { + orbis::shared_mutex mtx; + orbis::kmap computeQueues; orbis::ErrorCode open(orbis::Ref *file, const char *path, std::uint32_t flags, std::uint32_t mode, orbis::Thread *thread) override; @@ -20,6 +33,9 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request, // 0xc00c8110 // 0xc0848119 + auto device = static_cast(file->device.get()); + std::lock_guard lock(device->mtx); + switch (request) { case 0xc008811b: // get submit done flag ptr? // TODO @@ -50,11 +66,11 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request, // std::fprintf(stderr, " %lx\n", cmd[0]); // std::fprintf(stderr, " %lx\n", cmd[1]); - std::fprintf(stderr, " %u:\n", i); - std::fprintf(stderr, " cmdId = %lx\n", cmdId); - std::fprintf(stderr, " address = %lx\n", address); - std::fprintf(stderr, " unkPreservedVal = %lx\n", unkPreservedVal); - std::fprintf(stderr, " size = %lu\n", size); + // std::fprintf(stderr, " %u:\n", i); + // std::fprintf(stderr, " cmdId = %lx\n", cmdId); + // std::fprintf(stderr, " address = %lx\n", address); + // std::fprintf(stderr, " unkPreservedVal = %lx\n", unkPreservedVal); + // std::fprintf(stderr, " size = %lu\n", size); rx::bridge.sendCommandBuffer(cmdId, address, size); } @@ -101,11 +117,11 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request, // std::fprintf(stderr, " %lx\n", cmd[0]); // std::fprintf(stderr, " %lx\n", cmd[1]); - std::fprintf(stderr, " %u:\n", i); - std::fprintf(stderr, " cmdId = %lx\n", cmdId); - std::fprintf(stderr, " address = %lx\n", address); - std::fprintf(stderr, " unkPreservedVal = %lx\n", unkPreservedVal); - std::fprintf(stderr, " size = %lu\n", size); + // std::fprintf(stderr, " %u:\n", i); + // std::fprintf(stderr, " cmdId = %lx\n", cmdId); + // std::fprintf(stderr, " address = %lx\n", address); + // std::fprintf(stderr, " unkPreservedVal = %lx\n", unkPreservedVal); + // std::fprintf(stderr, " size = %lu\n", size); rx::bridge.sendCommandBuffer(cmdId, address, size); } @@ -117,6 +133,7 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request, case 0xc0048116: { ORBIS_LOG_ERROR("gc ioctl 0xc0048116", *(std::uint32_t *)argp); + thread->where(); break; } @@ -163,29 +180,32 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request, std::uint32_t pipeHi; std::uint32_t pipeLo; std::uint32_t queueId; - std::uint32_t queuePipe; + std::uint32_t offset; std::uint64_t ringBaseAddress; std::uint64_t readPtrAddress; std::uint64_t dingDongPtr; - std::uint32_t count; + std::uint32_t lenLog2; }; auto args = reinterpret_cast(argp); ORBIS_LOG_ERROR("gc ioctl map compute queue", args->pipeHi, args->pipeLo, - args->queueId, args->queuePipe, args->ringBaseAddress, - args->readPtrAddress, args->dingDongPtr, args->count); + args->queueId, args->offset, args->ringBaseAddress, + args->readPtrAddress, args->dingDongPtr, args->lenLog2); + auto id = ((args->pipeHi * 4) + args->pipeLo) * 8 + args->queueId; + device->computeQueues[id] = { + .ringBaseAddress = args->ringBaseAddress, + .readPtrAddress = args->readPtrAddress, + .dingDongPtr = args->dingDongPtr, + .len = static_cast(1) << args->lenLog2, + }; args->pipeHi = 0x769c766; args->pipeLo = 0x72e8e3c1; args->queueId = -0x248d50d8; - args->queuePipe = 0xd245ed58; + args->offset = 0xd245ed58; ((std::uint64_t *)args->dingDongPtr)[0xf0 / sizeof(std::uint64_t)] = 1; - - // TODO: implement - // std::fflush(stdout); - //__builtin_trap(); break; } @@ -202,8 +222,16 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request, ORBIS_LOG_ERROR("gc ioctl ding dong for workload", args->pipeHi, args->pipeLo, args->queueId, args->nextStartOffsetInDw); - // TODO: implement + auto id = ((args->pipeHi * 4) + args->pipeLo) * 8 + args->queueId; + auto queue = device->computeQueues.at(id); + auto address = (queue.ringBaseAddress + queue.offset); + auto endOffset = static_cast(args->nextStartOffsetInDw) << 2; + auto size = endOffset - queue.offset; + + rx::bridge.sendCommandBuffer(id, address, size); + + queue.offset = endOffset; break; } @@ -211,6 +239,7 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request, // SetWaveLimitMultipliers ORBIS_LOG_WARNING("Unknown gc ioctl", request, (unsigned long)*(std::uint32_t *)argp); + thread->where(); break; }