[rpcsx-os] implement compute queue mapping

This commit is contained in:
DH 2023-08-06 17:29:28 +03:00
parent 1c6ec7e157
commit 0987da90f4
3 changed files with 60 additions and 27 deletions

View file

@ -121,8 +121,8 @@ static orbis::ErrorCode dce_ioctl(orbis::File *file, std::uint64_t request,
// 0x21 - adjust color
auto args = reinterpret_cast<FlipControlArgs *>(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<FlipRequestArgs *>(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);

View file

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

View file

@ -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 <cstdio>
#include <mutex>
#include <sys/mman.h>
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<std::uint64_t, ComputeQueue> computeQueues;
orbis::ErrorCode open(orbis::Ref<orbis::File> *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<GcDevice *>(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<Args *>(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<std::uint64_t>(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<std::uint64_t>(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;
}