diff --git a/orbis-kernel/include/orbis/uio.hpp b/orbis-kernel/include/orbis/uio.hpp index d822af465..959445114 100644 --- a/orbis-kernel/include/orbis/uio.hpp +++ b/orbis-kernel/include/orbis/uio.hpp @@ -1,5 +1,7 @@ #pragma once +#include "orbis-config.hpp" +#include "error/ErrorCode.hpp" #include #include #include @@ -29,7 +31,7 @@ struct Uio { UioRw rw; void *td; - std::size_t write(const void *data, std::size_t size) { + ErrorCode write(const void *data, std::size_t size) { auto pos = reinterpret_cast(data); auto end = pos + size; @@ -39,15 +41,16 @@ struct Uio { } auto nextPos = std::min(pos + vec.len, end); - std::memcpy(vec.base, pos, nextPos - pos); + ORBIS_RET_ON_ERROR(uwriteRaw(vec.base, pos, nextPos - pos)); + offset += nextPos - pos; pos = nextPos; } - return size - (end - pos); + return {}; } template - std::size_t write(const T &object) { + ErrorCode write(const T &object) { return write(&object, sizeof(T)); } }; diff --git a/rpcsx-os/iodev/mbus_av.cpp b/rpcsx-os/iodev/mbus_av.cpp index 3d5646417..6bc20a4aa 100644 --- a/rpcsx-os/iodev/mbus_av.cpp +++ b/rpcsx-os/iodev/mbus_av.cpp @@ -1,32 +1,67 @@ +#include "mbus_av.hpp" #include "io-device.hpp" #include "orbis/KernelAllocator.hpp" #include "orbis/file.hpp" +#include "orbis/uio.hpp" #include "orbis/utils/Logs.hpp" +#include "orbis/utils/SharedCV.hpp" +#include "orbis/utils/SharedMutex.hpp" +#include struct MBusAVFile : orbis::File {}; static orbis::ErrorCode mbus_av_ioctl(orbis::File *file, std::uint64_t request, - void *argp, orbis::Thread *thread) { + void *argp, orbis::Thread *thread) { ORBIS_LOG_FATAL("Unhandled mbus_av ioctl", request); return {}; } +static orbis::ErrorCode mbus_av_read(orbis::File *file, orbis::Uio *uio, + orbis::Thread *thread) { + auto mbusAv = file->device.staticCast(); + + MBusAVEvent event; + { + std::lock_guard lock(mbusAv->mtx); + + // while (mbusAv->events.empty()) { + // file->mtx.unlock(); + // mbusAv->cv.wait(mbusAv->mtx); + // file->mtx.lock(); + // } + + if (mbusAv->events.empty()) { + return orbis::ErrorCode::BUSY; + } + + event = mbusAv->events.front(); + mbusAv->events.pop_front(); + } + + return uio->write(event); +} + static const orbis::FileOps fileOps = { .ioctl = mbus_av_ioctl, + .read = mbus_av_read, }; -struct MBusAVDevice : IoDevice { - orbis::ErrorCode open(orbis::Ref *file, const char *path, - std::uint32_t flags, std::uint32_t mode, - orbis::Thread *thread) override { - auto newFile = orbis::knew(); - newFile->ops = &fileOps; - newFile->device = this; +orbis::ErrorCode MBusAVDevice::open(orbis::Ref *file, + const char *path, std::uint32_t flags, + std::uint32_t mode, orbis::Thread *thread) { + auto newFile = orbis::knew(); + newFile->ops = &fileOps; + newFile->device = this; - *file = newFile; - return {}; - } -}; + *file = newFile; + return {}; +} + +void MBusAVDevice::emitEvent(const MBusAVEvent &event) { + std::lock_guard lock(mtx); + events.push_back(event); + cv.notify_one(mtx); +} IoDevice *createMBusAVCharacterDevice() { return orbis::knew(); } diff --git a/rpcsx-os/iodev/mbus_av.hpp b/rpcsx-os/iodev/mbus_av.hpp new file mode 100644 index 000000000..7be7ca330 --- /dev/null +++ b/rpcsx-os/iodev/mbus_av.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "io-device.hpp" +#include "orbis/utils/SharedCV.hpp" +#include "orbis/utils/SharedMutex.hpp" + +struct MBusAVEvent { + orbis::uint32_t unk0; + orbis::uint32_t unk1; + orbis::uint64_t unk2; + char unk3[0x20]; +}; + +static_assert(sizeof(MBusAVEvent) == 0x30); + +struct MBusAVDevice : IoDevice { + orbis::shared_mutex mtx; + orbis::shared_cv cv; + orbis::kdeque events; + + orbis::ErrorCode open(orbis::Ref *file, const char *path, + std::uint32_t flags, std::uint32_t mode, + orbis::Thread *thread) override; + + void emitEvent(const MBusAVEvent &event); +}; diff --git a/rpcsx-os/main.cpp b/rpcsx-os/main.cpp index 802d371d7..8c1133a4b 100644 --- a/rpcsx-os/main.cpp +++ b/rpcsx-os/main.cpp @@ -4,6 +4,7 @@ #include "bridge.hpp" #include "io-device.hpp" #include "io-devices.hpp" +#include "iodev/mbus_av.hpp" #include "linker.hpp" #include "ops.hpp" #include "thread.hpp" @@ -387,7 +388,8 @@ static void ps4InitDev() { rx::vfs::addDevice("aout2", createAoutCharacterDevice()); rx::vfs::addDevice("av_control", createAVControlCharacterDevice()); rx::vfs::addDevice("hdmi", createHDMICharacterDevice()); - rx::vfs::addDevice("mbus_av", createMBusAVCharacterDevice()); + auto mbusAv = static_cast(createMBusAVCharacterDevice()); + rx::vfs::addDevice("mbus_av", mbusAv); rx::vfs::addDevice("scanin", createScaninCharacterDevice()); rx::vfs::addDevice("s3da", createS3DACharacterDevice()); rx::vfs::addDevice("gbase", createGbaseCharacterDevice()); @@ -401,6 +403,12 @@ static void ps4InitDev() { rx::vfs::addDevice("shm", shm); orbis::g_context.shmDevice = shm; orbis::g_context.blockpoolDevice = createBlockPoolDevice(); + + mbusAv->emitEvent({ + .unk0 = 9, + .unk1 = 1, + .unk2 = 1, + }); } static void ps4InitFd(orbis::Thread *mainThread) {