[rpcsx-os] mbus_av: emit events

This commit is contained in:
DH 2023-12-31 17:07:46 +03:00
parent 6e25f347d3
commit f5c8fce5aa
4 changed files with 89 additions and 17 deletions

View file

@ -1,5 +1,7 @@
#pragma once
#include "orbis-config.hpp"
#include "error/ErrorCode.hpp"
#include <cstddef>
#include <cstdint>
#include <cstring>
@ -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<const std::byte *>(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<typename T>
std::size_t write(const T &object) {
ErrorCode write(const T &object) {
return write(&object, sizeof(T));
}
};

View file

@ -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 <mutex>
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<MBusAVDevice>();
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<orbis::File> *file, const char *path,
std::uint32_t flags, std::uint32_t mode,
orbis::Thread *thread) override {
auto newFile = orbis::knew<MBusAVFile>();
newFile->ops = &fileOps;
newFile->device = this;
orbis::ErrorCode MBusAVDevice::open(orbis::Ref<orbis::File> *file,
const char *path, std::uint32_t flags,
std::uint32_t mode, orbis::Thread *thread) {
auto newFile = orbis::knew<MBusAVFile>();
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<MBusAVDevice>(); }

View file

@ -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<MBusAVEvent> events;
orbis::ErrorCode open(orbis::Ref<orbis::File> *file, const char *path,
std::uint32_t flags, std::uint32_t mode,
orbis::Thread *thread) override;
void emitEvent(const MBusAVEvent &event);
};

View file

@ -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<MBusAVDevice *>(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) {