From 7eeeaf1d2d4edd9784fd497b6cfc69c8b8ad09c0 Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 3 Nov 2023 22:12:59 +0300 Subject: [PATCH 01/21] [orbis-kernel] kevent: implement EVFILT_USER --- orbis-kernel/src/sys/sys_event.cpp | 189 +++++++++++++++++++++++++---- 1 file changed, 163 insertions(+), 26 deletions(-) diff --git a/orbis-kernel/src/sys/sys_event.cpp b/orbis-kernel/src/sys/sys_event.cpp index 687b521d..f4418e50 100644 --- a/orbis-kernel/src/sys/sys_event.cpp +++ b/orbis-kernel/src/sys/sys_event.cpp @@ -67,6 +67,15 @@ static constexpr auto kEvFlag1 = 0x2000; static constexpr auto kEvEof = 0x8000; static constexpr auto kEvError = 0x4000; + +// kEvFiltUser +static constexpr auto kNoteFFNop = 0x00000000; +static constexpr auto kNoteFFAnd = 0x40000000; +static constexpr auto kNoteFFOr = 0x80000000; +static constexpr auto kNoteFFCopy = 0xc0000000; +static constexpr auto kNoteFFCtrlMask = 0xc0000000; +static constexpr auto kNoteFFlagsMask = 0x00ffffff; +static constexpr auto kNoteTrigger = 0x01000000; } // namespace orbis orbis::SysResult orbis::sys_kqueue(Thread *thread) { @@ -81,7 +90,8 @@ orbis::SysResult orbis::sys_kqueue(Thread *thread) { return {}; } -orbis::SysResult orbis::sys_kqueueex(Thread *thread, ptr name, sint flags) { +orbis::SysResult orbis::sys_kqueueex(Thread *thread, ptr name, + sint flags) { auto queue = knew(); if (queue == nullptr) { return ErrorCode::NOMEM; @@ -93,6 +103,88 @@ orbis::SysResult orbis::sys_kqueueex(Thread *thread, ptr name, sint flags) return {}; } +namespace orbis { +static SysResult keventChange(KQueue *kq, KEvent &change) { + auto nodeIt = kq->notes.end(); + for (auto it = kq->notes.begin(); it != kq->notes.end(); ++it) { + if (it->event.ident == change.ident && it->event.filter == change.filter) { + nodeIt = it; + break; + } + } + + if (change.flags & kEvDelete) { + if (nodeIt == kq->notes.end()) { + return orbis::ErrorCode::NOENT; + } + + kq->notes.erase(nodeIt); + nodeIt = kq->notes.end(); + } + + if (change.flags & kEvAdd) { + if (nodeIt == kq->notes.end()) { + KNote note { + .event = change, + .enabled = true, + }; + + note.event.flags &= ~(kEvAdd | kEvDelete | kEvDisable | kEvEnable); + kq->notes.push_front(note); + nodeIt = kq->notes.begin(); + } + } + + if (nodeIt == kq->notes.end()) { + if (change.flags & kEvDelete) { + return{}; + } + + return orbis::ErrorCode::NOENT; + } + + if (change.flags & kEvDisable) { + nodeIt->enabled = false; + } + if (change.flags & kEvEnable) { + nodeIt->enabled = true; + } + + if (change.filter == kEvFiltUser) { + auto fflags = 0; + switch (change.fflags & kNoteFFCtrlMask) { + case kNoteFFAnd: fflags = nodeIt->event.fflags & change.fflags; break; + case kNoteFFOr: fflags = nodeIt->event.fflags | change.fflags; break; + case kNoteFFCopy: fflags = change.fflags; break; + } + + nodeIt->event.fflags = (nodeIt->event.fflags & ~kNoteFFlagsMask) | (fflags & kNoteFFlagsMask); + + if (change.fflags & kNoteTrigger) { + nodeIt->event.fflags |= kNoteTrigger; + } + + if (change.flags & kEvClear) { + nodeIt->event.fflags &= ~kNoteTrigger; + } + } + + return{}; +} + +static orbis::ErrorCode ureadTimespec(orbis::timespec &ts, + orbis::ptr addr) { + orbis::ErrorCode error = uread(ts, addr); + if (error != orbis::ErrorCode{}) + return error; + if (ts.sec < 0 || ts.nsec < 0 || ts.nsec > 1000000000) { + return orbis::ErrorCode::INVAL; + } + + return {}; +} +} // namespace orbis + orbis::SysResult orbis::sys_kevent(Thread *thread, sint fd, ptr changelist, sint nchanges, ptr eventlist, sint nevents, @@ -117,43 +209,88 @@ orbis::SysResult orbis::sys_kevent(Thread *thread, sint fd, ORBIS_LOG_TODO(__FUNCTION__, change.ident, change.filter, change.flags, change.fflags, change.data, change.udata); - if (change.flags & kEvAdd) { - // if (change.filter != kEvFiltDisplay && change.filter != kEvFiltGraphicsCore) { - // std::abort(); - // } + if (auto result = keventChange(kq, change); result.value() != 0) { + return result; + } + } + } - kq->notes.push_back({ - .event = change, - .enabled = (change.flags & kEvDisable) == 0 - }); + if (nevents == 0) { + return{}; + } - kq->notes.back().event.flags &= ~(kEvAdd | kEvClear | kEvDelete | kEvDisable); - } + using clock = std::chrono::high_resolution_clock; + clock::time_point timeoutPoint = clock::time_point::max(); + if (timeout != nullptr) { + timespec _timeout; + auto result = ureadTimespec(_timeout, timeout); + if (result != ErrorCode{}) { + return result; + } + + __uint128_t nsec = _timeout.sec; + nsec *= 1000'000'000; + nsec += _timeout.nsec; - // TODO + if (nsec < INT64_MAX) { + auto now = clock::now(); + auto nowValue = now.time_since_epoch().count(); + + if (nowValue < nowValue + nsec) { + timeoutPoint = now + std::chrono::nanoseconds(nsec); + } } } std::vector result; result.reserve(nevents); - for (auto ¬e : kq->notes) { - if (result.size() >= nevents) { - break; - } + while (result.empty()) { + for (auto it = kq->notes.begin(); it != kq->notes.end();) { + if (result.size() >= nevents) { + break; + } - if (!note.enabled) { - continue; - } + auto ¬e = *it; + + if (!note.enabled) { + ++it; + continue; + } + + if (note.event.filter == kEvFiltUser) { + if ((note.event.fflags & kNoteTrigger) == 0) { + ++it; + continue; + } + + auto event = note.event; + event.fflags &= kNoteFFlagsMask; + result.push_back(event); + } else if (note.event.filter == kEvFiltDisplay || + note.event.filter == kEvFiltGraphicsCore) { + result.push_back(note.event); + } else if (note.event.filter == kEvFiltProc) { + // TODO + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + note.event.data = 0; + result.push_back(note.event); + } else { + ++it; + continue; + } - if (note.event.filter == kEvFiltDisplay || note.event.filter == kEvFiltGraphicsCore) { - result.push_back(note.event); + if (note.event.flags & kEvOneshot) { + it = kq->notes.erase(it); + } else { + ++it; + } } - if (note.event.filter == kEvFiltProc) { - // TODO - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - note.event.data = 0; - result.push_back(note.event); + + if (result.empty() && timeoutPoint != clock::time_point::max()) { + if (clock::now() >= timeoutPoint) { + break; + } } } From a9d385d42412e2281b759ad445674432dfe93def Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 3 Nov 2023 22:41:32 +0300 Subject: [PATCH 02/21] [rpcsx-os] stub aout, av_control, hdmi, mbus_av, scanin devices --- rpcsx-os/CMakeLists.txt | 5 +++ rpcsx-os/io-devices.hpp | 5 +++ rpcsx-os/iodev/aout.cpp | 32 +++++++++++++++++++ rpcsx-os/iodev/av_control.cpp | 32 +++++++++++++++++++ rpcsx-os/iodev/hdmi.cpp | 32 +++++++++++++++++++ rpcsx-os/iodev/mbus_av.cpp | 32 +++++++++++++++++++ rpcsx-os/iodev/scanin.cpp | 32 +++++++++++++++++++ rpcsx-os/main.cpp | 5 +++ rpcsx-os/orbis-kernel-config/orbis-config.hpp | 4 +-- 9 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 rpcsx-os/iodev/aout.cpp create mode 100644 rpcsx-os/iodev/av_control.cpp create mode 100644 rpcsx-os/iodev/hdmi.cpp create mode 100644 rpcsx-os/iodev/mbus_av.cpp create mode 100644 rpcsx-os/iodev/scanin.cpp diff --git a/rpcsx-os/CMakeLists.txt b/rpcsx-os/CMakeLists.txt index 194607d6..ed732150 100644 --- a/rpcsx-os/CMakeLists.txt +++ b/rpcsx-os/CMakeLists.txt @@ -31,6 +31,11 @@ add_executable(rpcsx-os iodev/urandom.cpp iodev/xpt.cpp iodev/zero.cpp + iodev/aout.cpp + iodev/av_control.cpp + iodev/hdmi.cpp + iodev/mbus_av.cpp + iodev/scanin.cpp main.cpp backtrace.cpp diff --git a/rpcsx-os/io-devices.hpp b/rpcsx-os/io-devices.hpp index a55b6beb..3bba5e82 100644 --- a/rpcsx-os/io-devices.hpp +++ b/rpcsx-os/io-devices.hpp @@ -30,3 +30,8 @@ IoDevice *createXptCharacterDevice(); IoDevice *createCdCharacterDevice(); IoDevice *createMetaDbgCharacterDevice(); IoDevice *createHddCharacterDevice(); +IoDevice *createAoutCharacterDevice(); +IoDevice *createAVControlCharacterDevice(); +IoDevice *createHDMICharacterDevice(); +IoDevice *createMBusAVCharacterDevice(); +IoDevice *createScaninCharacterDevice(); diff --git a/rpcsx-os/iodev/aout.cpp b/rpcsx-os/iodev/aout.cpp new file mode 100644 index 00000000..9613be81 --- /dev/null +++ b/rpcsx-os/iodev/aout.cpp @@ -0,0 +1,32 @@ +#include "io-device.hpp" +#include "orbis/KernelAllocator.hpp" +#include "orbis/file.hpp" +#include "orbis/utils/Logs.hpp" + +struct AoutFile : orbis::File {}; + +static orbis::ErrorCode aout_ioctl(orbis::File *file, std::uint64_t request, + void *argp, orbis::Thread *thread) { + + ORBIS_LOG_FATAL("Unhandled aout ioctl", request); + return {}; +} + +static const orbis::FileOps fileOps = { + .ioctl = aout_ioctl, +}; + +struct AoutDevice : 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; + + *file = newFile; + return {}; + } +}; + +IoDevice *createAoutCharacterDevice() { return orbis::knew(); } diff --git a/rpcsx-os/iodev/av_control.cpp b/rpcsx-os/iodev/av_control.cpp new file mode 100644 index 00000000..328317a2 --- /dev/null +++ b/rpcsx-os/iodev/av_control.cpp @@ -0,0 +1,32 @@ +#include "io-device.hpp" +#include "orbis/KernelAllocator.hpp" +#include "orbis/file.hpp" +#include "orbis/utils/Logs.hpp" + +struct AVControlFile : orbis::File {}; + +static orbis::ErrorCode av_control_ioctl(orbis::File *file, std::uint64_t request, + void *argp, orbis::Thread *thread) { + + ORBIS_LOG_FATAL("Unhandled av_control ioctl", request); + return {}; +} + +static const orbis::FileOps fileOps = { + .ioctl = av_control_ioctl, +}; + +struct AVControlDevice : 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; + + *file = newFile; + return {}; + } +}; + +IoDevice *createAVControlCharacterDevice() { return orbis::knew(); } diff --git a/rpcsx-os/iodev/hdmi.cpp b/rpcsx-os/iodev/hdmi.cpp new file mode 100644 index 00000000..b892a75e --- /dev/null +++ b/rpcsx-os/iodev/hdmi.cpp @@ -0,0 +1,32 @@ +#include "io-device.hpp" +#include "orbis/KernelAllocator.hpp" +#include "orbis/file.hpp" +#include "orbis/utils/Logs.hpp" + +struct HDMIFile : orbis::File {}; + +static orbis::ErrorCode hdmi_ioctl(orbis::File *file, std::uint64_t request, + void *argp, orbis::Thread *thread) { + + ORBIS_LOG_FATAL("Unhandled hdmi ioctl", request); + return {}; +} + +static const orbis::FileOps fileOps = { + .ioctl = hdmi_ioctl, +}; + +struct HDMIDevice : 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; + + *file = newFile; + return {}; + } +}; + +IoDevice *createHDMICharacterDevice() { return orbis::knew(); } diff --git a/rpcsx-os/iodev/mbus_av.cpp b/rpcsx-os/iodev/mbus_av.cpp new file mode 100644 index 00000000..3d564641 --- /dev/null +++ b/rpcsx-os/iodev/mbus_av.cpp @@ -0,0 +1,32 @@ +#include "io-device.hpp" +#include "orbis/KernelAllocator.hpp" +#include "orbis/file.hpp" +#include "orbis/utils/Logs.hpp" + +struct MBusAVFile : orbis::File {}; + +static orbis::ErrorCode mbus_av_ioctl(orbis::File *file, std::uint64_t request, + void *argp, orbis::Thread *thread) { + + ORBIS_LOG_FATAL("Unhandled mbus_av ioctl", request); + return {}; +} + +static const orbis::FileOps fileOps = { + .ioctl = mbus_av_ioctl, +}; + +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; + + *file = newFile; + return {}; + } +}; + +IoDevice *createMBusAVCharacterDevice() { return orbis::knew(); } diff --git a/rpcsx-os/iodev/scanin.cpp b/rpcsx-os/iodev/scanin.cpp new file mode 100644 index 00000000..a5c1e20d --- /dev/null +++ b/rpcsx-os/iodev/scanin.cpp @@ -0,0 +1,32 @@ +#include "io-device.hpp" +#include "orbis/KernelAllocator.hpp" +#include "orbis/file.hpp" +#include "orbis/utils/Logs.hpp" + +struct ScaninFile : orbis::File {}; + +static orbis::ErrorCode scanin_ioctl(orbis::File *file, std::uint64_t request, + void *argp, orbis::Thread *thread) { + + ORBIS_LOG_FATAL("Unhandled scanin ioctl", request); + return {}; +} + +static const orbis::FileOps fileOps = { + .ioctl = scanin_ioctl, +}; + +struct ScaninDevice : 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; + + *file = newFile; + return {}; + } +}; + +IoDevice *createScaninCharacterDevice() { return orbis::knew(); } diff --git a/rpcsx-os/main.cpp b/rpcsx-os/main.cpp index f09cf9b9..f08b6107 100644 --- a/rpcsx-os/main.cpp +++ b/rpcsx-os/main.cpp @@ -373,6 +373,11 @@ static void ps4InitDev() { rx::vfs::addDevice("notification3", createNotificationCharacterDevice(3)); rx::vfs::addDevice("notification4", createNotificationCharacterDevice(4)); rx::vfs::addDevice("notification5", createNotificationCharacterDevice(5)); + rx::vfs::addDevice("aout0", createAoutCharacterDevice()); + rx::vfs::addDevice("av_control", createAVControlCharacterDevice()); + rx::vfs::addDevice("hdmi", createHDMICharacterDevice()); + rx::vfs::addDevice("mbus_av", createMBusAVCharacterDevice()); + rx::vfs::addDevice("scanin", createScaninCharacterDevice()); orbis::g_context.shmDevice = createShmDevice(); orbis::g_context.blockpoolDevice = createBlockPoolDevice(); diff --git a/rpcsx-os/orbis-kernel-config/orbis-config.hpp b/rpcsx-os/orbis-kernel-config/orbis-config.hpp index fa52bf94..9f44e951 100644 --- a/rpcsx-os/orbis-kernel-config/orbis-config.hpp +++ b/rpcsx-os/orbis-kernel-config/orbis-config.hpp @@ -73,7 +73,7 @@ uwriteRaw(ptr userAddress, const void *kernelAddress, size_t size) { return {}; } -template [[nodiscard]] ErrorCode uread(T &result, ptr pointer) { +template [[nodiscard]] ErrorCode uread(T &result, ptr pointer) { return ureadRaw(&result, pointer, sizeof(T)); } @@ -90,7 +90,7 @@ template } template -[[nodiscard]] ErrorCode uread(T *result, ptr pointer, std::size_t count) { +[[nodiscard]] ErrorCode uread(T *result, ptr pointer, std::size_t count) { return ureadRaw(&result, pointer, sizeof(T) * count); } From 8ecfc4979c2b4fd55cace14f3f6738211d2eb029 Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 20:48:51 +0300 Subject: [PATCH 03/21] [orbis-kernel] compete kallocator interface --- orbis-kernel/include/orbis/KernelAllocator.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/orbis-kernel/include/orbis/KernelAllocator.hpp b/orbis-kernel/include/orbis/KernelAllocator.hpp index a4371324..f3dd5dd1 100644 --- a/orbis-kernel/include/orbis/KernelAllocator.hpp +++ b/orbis-kernel/include/orbis/KernelAllocator.hpp @@ -15,6 +15,12 @@ void *kalloc(std::size_t size, std::size_t align); void kfree(void *ptr, std::size_t size); template struct kallocator { using value_type = T; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + using propagate_on_container_move_assignment = std::true_type; + + constexpr kallocator() = default; + template constexpr kallocator(const kallocator &) noexcept {} template struct rebind { using other = kallocator; From a847e739fc6b3da302cd4e60aab147e80543b5c6 Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 20:50:34 +0300 Subject: [PATCH 04/21] [orbis-kernel] fix saving ipmi server name --- orbis-kernel/include/orbis/KernelContext.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orbis-kernel/include/orbis/KernelContext.hpp b/orbis-kernel/include/orbis/KernelContext.hpp index bea77455..f8c07ad7 100644 --- a/orbis-kernel/include/orbis/KernelContext.hpp +++ b/orbis-kernel/include/orbis/KernelContext.hpp @@ -120,7 +120,7 @@ class alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) KernelContext final { std::lock_guard lock(m_sem_mtx); auto [it, inserted] = mIpmiServers.try_emplace(std::move(name), nullptr); if (inserted) { - it->second = knew(name); + it->second = knew(it->first); } return {it->second.get(), inserted}; From dc44b619b2956d00dadac86a214e83d767df9aff Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 20:53:41 +0300 Subject: [PATCH 05/21] [orbis-kernel] store sdk version to the context --- orbis-kernel/include/orbis/KernelContext.hpp | 1 + orbis-kernel/src/sys/sys_sysctl.cpp | 13 ++----------- rpcsx-os/main.cpp | 12 ++++++++++++ 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/orbis-kernel/include/orbis/KernelContext.hpp b/orbis-kernel/include/orbis/KernelContext.hpp index f8c07ad7..15bfeb98 100644 --- a/orbis-kernel/include/orbis/KernelContext.hpp +++ b/orbis-kernel/include/orbis/KernelContext.hpp @@ -159,6 +159,7 @@ class alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) KernelContext final { Ref dmemDevice; Ref blockpoolDevice; AudioOut *audioOut = nullptr; + uint sdkVersion{}; private: mutable pthread_mutex_t m_heap_mtx; diff --git a/orbis-kernel/src/sys/sys_sysctl.cpp b/orbis-kernel/src/sys/sys_sysctl.cpp index a1d3ab90..97fee7c1 100644 --- a/orbis-kernel/src/sys/sys_sysctl.cpp +++ b/orbis-kernel/src/sys/sys_sysctl.cpp @@ -372,17 +372,8 @@ orbis::SysResult orbis::sys___sysctl(Thread *thread, ptr name, return ErrorCode::INVAL; } - auto processParam = - reinterpret_cast(thread->tproc->processParam); - - auto sdkVersion = processParam // - + sizeof(uint64_t) // size - + sizeof(uint32_t) // magic - + sizeof(uint32_t); // entryCount - - std::printf("Reporting SDK version %x\n", - *reinterpret_cast(sdkVersion)); - *(uint32_t *)old = *reinterpret_cast(sdkVersion); + std::printf("Reporting SDK version %x\n", g_context.sdkVersion); + *(uint32_t *)old = g_context.sdkVersion; return {}; } diff --git a/rpcsx-os/main.cpp b/rpcsx-os/main.cpp index f08b6107..99bdaeb7 100644 --- a/rpcsx-os/main.cpp +++ b/rpcsx-os/main.cpp @@ -417,6 +417,18 @@ int ps4Exec(orbis::Thread *mainThread, std::uint64_t interpBase = 0; std::uint64_t entryPoint = executableModule->entryPoint; + if (orbis::g_context.sdkVersion == 0 && mainThread->tproc->processParam) { + auto processParam = + reinterpret_cast(mainThread->tproc->processParam); + + auto sdkVersion = processParam // + + sizeof(uint64_t) // size + + sizeof(uint32_t) // magic + + sizeof(uint32_t); // entryCount + + orbis::g_context.sdkVersion = *(uint32_t *)sdkVersion; + } + if (executableModule->type != rx::linker::kElfTypeExec) { auto libSceLibcInternal = rx::linker::loadModuleFile( "/system/common/lib/libSceLibcInternal.sprx", mainThread); From 8e0f6b0319ff8646699763c982cf3eebb5f66673 Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 20:55:28 +0300 Subject: [PATCH 06/21] [orbis-kernel] add ORBIS_RET_ON_ERROR macro utility --- orbis-kernel/include/orbis/error/ErrorCode.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/orbis-kernel/include/orbis/error/ErrorCode.hpp b/orbis-kernel/include/orbis/error/ErrorCode.hpp index d5254bc4..04be1bfa 100644 --- a/orbis-kernel/include/orbis/error/ErrorCode.hpp +++ b/orbis-kernel/include/orbis/error/ErrorCode.hpp @@ -109,3 +109,10 @@ enum class ErrorCode : int { CAPMODE = 94, // Not permitted in capability mode }; } // namespace orbis + +#define ORBIS_RET_ON_ERROR(...) \ + do { \ + if (auto errc___ = (__VA_ARGS__); errc___ != ::orbis::ErrorCode{}) { \ + return errc___; \ + } \ + } while (false) From 985a41a5d2cd1e5826986118107c5df57bded26d Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 20:58:25 +0300 Subject: [PATCH 07/21] [rpcsx-os] fork: fix vm name --- rpcsx-os/ops.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcsx-os/ops.cpp b/rpcsx-os/ops.cpp index a4c0172d..33141300 100644 --- a/rpcsx-os/ops.cpp +++ b/rpcsx-os/ops.cpp @@ -656,7 +656,7 @@ SysResult fork(Thread *thread, slong flags) { } } - rx::vm::fork(thread->tproc->pid); + rx::vm::fork(childPid); rx::vfs::fork(); *flag = true; From d778e5cbe1ce0926c96c95344abf9ef5e45be580 Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 20:59:25 +0300 Subject: [PATCH 08/21] [rpcsx-os] execve: fix process name setup --- rpcsx-os/ops.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rpcsx-os/ops.cpp b/rpcsx-os/ops.cpp index 33141300..860cad9c 100644 --- a/rpcsx-os/ops.cpp +++ b/rpcsx-os/ops.cpp @@ -739,6 +739,10 @@ SysResult execve(Thread *thread, ptr fname, ptr> argv, name = name.substr(slashP + 1); } + if (name.size() > 15) { + name.resize(15); + } + pthread_setname_np(pthread_self(), name.c_str()); std::thread([&] { From 84a8523568b926f53ebd0689491e0d5380c31083 Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 21:01:55 +0300 Subject: [PATCH 09/21] [orbis-kernel] devfs: implement device as directory --- rpcsx-os/vfs.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/rpcsx-os/vfs.cpp b/rpcsx-os/vfs.cpp index c419e610..c84ac339 100644 --- a/rpcsx-os/vfs.cpp +++ b/rpcsx-os/vfs.cpp @@ -10,13 +10,23 @@ #include struct DevFs : IoDevice { - std::map> devices; + std::map, std::less<>> devices; orbis::ErrorCode open(orbis::Ref *file, const char *path, std::uint32_t flags, std::uint32_t mode, orbis::Thread *thread) override { - if (auto it = devices.find(path); it != devices.end()) { - return it->second->open(file, path, flags, mode, thread); + std::string_view devPath = path; + if (auto pos = devPath.find('/'); pos != std::string_view::npos) { + auto deviceName = devPath.substr(0, pos); + devPath.remove_prefix(pos + 1); + + if (auto it = devices.find(deviceName); it != devices.end()) { + return it->second->open(file, std::string(devPath).c_str(), flags, mode, thread); + } + } else { + if (auto it = devices.find(devPath); it != devices.end()) { + return it->second->open(file, "", flags, mode, thread); + } } std::fprintf(stderr, "device %s not exists\n", path); From a98ac71b8347401a2e8e075a20bb9a65c57b11bb Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 21:04:33 +0300 Subject: [PATCH 10/21] [rpcsx-os] dmem: fix allocator --- rpcsx-os/iodev/dmem.hpp | 3 ++- rx/include/rx/MemoryTable.hpp | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/rpcsx-os/iodev/dmem.hpp b/rpcsx-os/iodev/dmem.hpp index bff4efd0..77816ae4 100644 --- a/rpcsx-os/iodev/dmem.hpp +++ b/rpcsx-os/iodev/dmem.hpp @@ -1,6 +1,7 @@ #pragma once #include "io-device.hpp" +#include "orbis/KernelAllocator.hpp" #include "orbis/error/ErrorCode.hpp" #include "orbis/file.hpp" #include "orbis/utils/Rc.hpp" @@ -21,7 +22,7 @@ struct DmemDevice : public IoDevice { auto operator<=>(const AllocationInfo &) const = default; }; - rx::MemoryTableWithPayload allocations; + rx::MemoryTableWithPayload allocations; orbis::ErrorCode allocate(std::uint64_t *start, std::uint64_t searchEnd, std::uint64_t len, std::uint64_t alignment, diff --git a/rx/include/rx/MemoryTable.hpp b/rx/include/rx/MemoryTable.hpp index a8538307..70d7530f 100644 --- a/rx/include/rx/MemoryTable.hpp +++ b/rx/include/rx/MemoryTable.hpp @@ -202,9 +202,13 @@ class MemoryAreaTable : public InvalidationHandleT { } }; -template class MemoryTableWithPayload { +template typename Allocator = std::allocator> +class MemoryTableWithPayload { enum class Kind { O, X, XO }; - std::map> mAreas; + std::map, std::less<>, + Allocator>>> + mAreas; public: struct AreaInfo { From 8b99eb1b02ca1efe25a573ec45f54ebe24cb0422 Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 21:06:44 +0300 Subject: [PATCH 11/21] [orbis-kernel] dmem: fix deallocation --- rpcsx-os/iodev/dmem.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rpcsx-os/iodev/dmem.cpp b/rpcsx-os/iodev/dmem.cpp index dfb47a18..68615f94 100644 --- a/rpcsx-os/iodev/dmem.cpp +++ b/rpcsx-os/iodev/dmem.cpp @@ -81,7 +81,7 @@ static orbis::ErrorCode dmem_ioctl(orbis::File *file, std::uint64_t request, args->size); device->allocations.map(args->address, args->address + args->size, - {.memoryType = 0}); + {.memoryType = -1u}); return {}; } @@ -128,7 +128,7 @@ static orbis::ErrorCode dmem_ioctl(orbis::File *file, std::uint64_t request, auto queryInfo = *it; - if (queryInfo.payload.memoryType == 0) { + if (queryInfo.payload.memoryType == -1u) { return orbis::ErrorCode::ACCES; } @@ -201,7 +201,7 @@ orbis::ErrorCode DmemDevice::allocate(std::uint64_t *start, if (it != allocations.end()) { auto allocation = *it; - if (allocation.payload.memoryType == 0) { + if (allocation.payload.memoryType == -1u) { if (offset < allocation.beginAddress) { offset = allocation.beginAddress + alignment - 1; offset &= ~(alignment - 1); @@ -261,7 +261,7 @@ orbis::ErrorCode DmemDevice::queryMaxFreeChunkSize(std::uint64_t *start, } auto allocation = *it; - if (allocation.payload.memoryType == 0) { + if (allocation.payload.memoryType == -1u) { if (offset < allocation.beginAddress) { offset = allocation.beginAddress + alignment - 1; offset &= ~(alignment - 1); From bfa5510eec4b18e0fe305d60e236143a5f5e6c04 Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 21:08:31 +0300 Subject: [PATCH 12/21] [orbis-kernel] kevent: fix deadlock --- orbis-kernel/src/sys/sys_event.cpp | 123 +++++++++++++++++------------ 1 file changed, 74 insertions(+), 49 deletions(-) diff --git a/orbis-kernel/src/sys/sys_event.cpp b/orbis-kernel/src/sys/sys_event.cpp index f4418e50..d2a6ddcc 100644 --- a/orbis-kernel/src/sys/sys_event.cpp +++ b/orbis-kernel/src/sys/sys_event.cpp @@ -76,6 +76,11 @@ static constexpr auto kNoteFFCopy = 0xc0000000; static constexpr auto kNoteFFCtrlMask = 0xc0000000; static constexpr auto kNoteFFlagsMask = 0x00ffffff; static constexpr auto kNoteTrigger = 0x01000000; + +// kEvFiltProc +static constexpr auto kNoteExit = 0x80000000; +static constexpr auto kNoteFork = 0x40000000; +static constexpr auto kNoteExec = 0x20000000; } // namespace orbis orbis::SysResult orbis::sys_kqueue(Thread *thread) { @@ -124,9 +129,9 @@ static SysResult keventChange(KQueue *kq, KEvent &change) { if (change.flags & kEvAdd) { if (nodeIt == kq->notes.end()) { - KNote note { - .event = change, - .enabled = true, + KNote note{ + .event = change, + .enabled = true, }; note.event.flags &= ~(kEvAdd | kEvDelete | kEvDisable | kEvEnable); @@ -137,7 +142,7 @@ static SysResult keventChange(KQueue *kq, KEvent &change) { if (nodeIt == kq->notes.end()) { if (change.flags & kEvDelete) { - return{}; + return {}; } return orbis::ErrorCode::NOENT; @@ -153,12 +158,19 @@ static SysResult keventChange(KQueue *kq, KEvent &change) { if (change.filter == kEvFiltUser) { auto fflags = 0; switch (change.fflags & kNoteFFCtrlMask) { - case kNoteFFAnd: fflags = nodeIt->event.fflags & change.fflags; break; - case kNoteFFOr: fflags = nodeIt->event.fflags | change.fflags; break; - case kNoteFFCopy: fflags = change.fflags; break; + case kNoteFFAnd: + fflags = nodeIt->event.fflags & change.fflags; + break; + case kNoteFFOr: + fflags = nodeIt->event.fflags | change.fflags; + break; + case kNoteFFCopy: + fflags = change.fflags; + break; } - nodeIt->event.fflags = (nodeIt->event.fflags & ~kNoteFFlagsMask) | (fflags & kNoteFFlagsMask); + nodeIt->event.fflags = + (nodeIt->event.fflags & ~kNoteFFlagsMask) | (fflags & kNoteFFlagsMask); if (change.fflags & kNoteTrigger) { nodeIt->event.fflags |= kNoteTrigger; @@ -169,7 +181,7 @@ static SysResult keventChange(KQueue *kq, KEvent &change) { } } - return{}; + return {}; } static orbis::ErrorCode ureadTimespec(orbis::timespec &ts, @@ -196,27 +208,29 @@ orbis::SysResult orbis::sys_kevent(Thread *thread, sint fd, return orbis::ErrorCode::BADF; } - std::lock_guard lock(kqf->mtx); - auto kq = dynamic_cast(kqf.get()); if (kq == nullptr) { return orbis::ErrorCode::BADF; } - if (nchanges != 0) { - for (auto change : std::span(changelist, nchanges)) { - ORBIS_LOG_TODO(__FUNCTION__, change.ident, change.filter, change.flags, - change.fflags, change.data, change.udata); + { + std::lock_guard lock(kqf->mtx); - if (auto result = keventChange(kq, change); result.value() != 0) { - return result; + if (nchanges != 0) { + for (auto change : std::span(changelist, nchanges)) { + ORBIS_LOG_TODO(__FUNCTION__, change.ident, change.filter, change.flags, + change.fflags, change.data, change.udata); + + if (auto result = keventChange(kq, change); result.value() != 0) { + return result; + } } } } if (nevents == 0) { - return{}; + return {}; } using clock = std::chrono::high_resolution_clock; @@ -246,52 +260,63 @@ orbis::SysResult orbis::sys_kevent(Thread *thread, sint fd, result.reserve(nevents); while (result.empty()) { - for (auto it = kq->notes.begin(); it != kq->notes.end();) { - if (result.size() >= nevents) { - break; - } + { + std::lock_guard lock(kqf->mtx); + for (auto it = kq->notes.begin(); it != kq->notes.end();) { + if (result.size() >= nevents) { + break; + } - auto ¬e = *it; + auto ¬e = *it; - if (!note.enabled) { - ++it; - continue; - } + if (!note.enabled) { + ++it; + continue; + } - if (note.event.filter == kEvFiltUser) { - if ((note.event.fflags & kNoteTrigger) == 0) { + if (note.event.filter == kEvFiltUser) { + if ((note.event.fflags & kNoteTrigger) == 0) { + ++it; + continue; + } + + auto event = note.event; + event.fflags &= kNoteFFlagsMask; + result.push_back(event); + } else if (note.event.filter == kEvFiltDisplay || + note.event.filter == kEvFiltGraphicsCore) { + result.push_back(note.event); + } else if (note.event.filter == kEvFiltProc) { + // TODO + if (note.event.fflags & kNoteExec) { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + note.event.data = 0; + result.push_back(note.event); + } + } else { ++it; continue; } - auto event = note.event; - event.fflags &= kNoteFFlagsMask; - result.push_back(event); - } else if (note.event.filter == kEvFiltDisplay || - note.event.filter == kEvFiltGraphicsCore) { - result.push_back(note.event); - } else if (note.event.filter == kEvFiltProc) { - // TODO - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - note.event.data = 0; - result.push_back(note.event); - } else { - ++it; - continue; + if (note.event.flags & kEvOneshot) { + it = kq->notes.erase(it); + } else { + ++it; + } } + } - if (note.event.flags & kEvOneshot) { - it = kq->notes.erase(it); - } else { - ++it; - } + if (!result.empty()) { + break; } - if (result.empty() && timeoutPoint != clock::time_point::max()) { + if (timeoutPoint != clock::time_point::max()) { if (clock::now() >= timeoutPoint) { break; } } + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); } std::memcpy(eventlist, result.data(), result.size() * sizeof(KEvent)); From 7dd0b10f7a5cf499d417c859ff0a1ee8245fd4b6 Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 21:11:17 +0300 Subject: [PATCH 13/21] [orbis-kernel] osem: implement wait with timeout --- orbis-kernel/src/sys/sys_sce.cpp | 49 +++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/orbis-kernel/src/sys/sys_sce.cpp b/orbis-kernel/src/sys/sys_sce.cpp index bca15913..5cd5899a 100644 --- a/orbis-kernel/src/sys/sys_sce.cpp +++ b/orbis-kernel/src/sys/sys_sce.cpp @@ -418,7 +418,7 @@ orbis::SysResult orbis::sys_osem_delete(Thread *thread, sint id) { ORBIS_LOG_TRACE(__FUNCTION__, id); Ref sem = thread->tproc->semMap.get(id); if (sem == nullptr) { - return ErrorCode::SRCH; + return ErrorCode::NOENT; } thread->tproc->semMap.destroy(id); @@ -449,7 +449,7 @@ orbis::SysResult orbis::sys_osem_open(Thread *thread, ORBIS_LOG_WARNING(__FUNCTION__, _name, result.value(), thread->retval[0]); return result; } - return ErrorCode::SRCH; + return ErrorCode::NOENT; } thread->retval[0] = thread->tproc->semMap.insert(sem); @@ -458,7 +458,7 @@ orbis::SysResult orbis::sys_osem_open(Thread *thread, orbis::SysResult orbis::sys_osem_close(Thread *thread, sint id) { ORBIS_LOG_TRACE(__FUNCTION__, id); if (!thread->tproc->semMap.close(id)) { - return ErrorCode::SRCH; + return ErrorCode::NOENT; } return {}; @@ -467,12 +467,17 @@ orbis::SysResult orbis::sys_osem_wait(Thread *thread, sint id, sint need, ptr pTimeout) { ORBIS_LOG_NOTICE(__FUNCTION__, thread, id, need, pTimeout); Ref sem = thread->tproc->semMap.get(id); - if (pTimeout) - ORBIS_LOG_FATAL("sys_osem_wait timeout is not implemented!"); if (need < 1 || need > sem->maxValue) return ErrorCode::INVAL; + auto deadline = std::chrono::steady_clock::time_point::max(); + if (pTimeout != nullptr) { + deadline = + std::chrono::steady_clock::now() + std::chrono::microseconds(*pTimeout); + } + std::lock_guard lock(sem->mtx); + bool timedout = false; while (true) { if (sem->isDeleted) return ErrorCode::ACCES; @@ -480,7 +485,37 @@ orbis::SysResult orbis::sys_osem_wait(Thread *thread, sint id, sint need, sem->value -= need; break; } - sem->cond.wait(sem->mtx); + long ut = -1; + if (deadline != std::chrono::steady_clock::time_point::max()) { + ut = std::chrono::duration_cast( + deadline - std::chrono::steady_clock::now()) + .count(); + if (ut < 0) { + timedout = true; + break; + } + } + sem->cond.wait(sem->mtx, ut); + } + + if (pTimeout) { + if (timedout) { + *pTimeout = 0; + } else { + auto timeout = std::chrono::duration_cast( + deadline - std::chrono::steady_clock::now()) + .count(); + + if (timeout > 0) { + *pTimeout = timeout; + } else { + *pTimeout = 0; + } + } + } + + if (timedout) { + return ErrorCode::TIMEDOUT; } return {}; } @@ -910,7 +945,7 @@ orbis::SysResult orbis::sys_rdup(Thread *thread, sint pid, sint fd) { } thread->retval[0] = thread->tproc->fileDescriptors.insert(std::move(file)); - return{}; + return {}; } return ErrorCode::SRCH; } From c998b3760ad17dfe2d0d48c10916e3c3ca4c6a7c Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 21:12:19 +0300 Subject: [PATCH 14/21] [orbis-kernel] osem: fix saving name on create --- orbis-kernel/src/sys/sys_sce.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/orbis-kernel/src/sys/sys_sce.cpp b/orbis-kernel/src/sys/sys_sce.cpp index 5cd5899a..407b11cc 100644 --- a/orbis-kernel/src/sys/sys_sce.cpp +++ b/orbis-kernel/src/sys/sys_sce.cpp @@ -406,6 +406,7 @@ orbis::SysResult orbis::sys_osem_create(Thread *thread, return ErrorCode::EXIST; // FIXME: verify } + std::strncpy(insertedSem->name, _name, 32); sem = insertedSem; } else { sem = knew(attrs, initCount, maxCount); From 5a61682b84185120c5e9d07dddae74376e961e7e Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 21:15:10 +0300 Subject: [PATCH 15/21] [rpcsx-os] getdirent: do not report .. --- rpcsx-os/io-device.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rpcsx-os/io-device.cpp b/rpcsx-os/io-device.cpp index a755d275..5ba10f0b 100644 --- a/rpcsx-os/io-device.cpp +++ b/rpcsx-os/io-device.cpp @@ -509,6 +509,10 @@ orbis::ErrorCode HostFsDevice::open(orbis::Ref *file, if (r <= 0) break; + if (hostEntry.d_name == std::string_view("..")) { + continue; + } + auto &entry = dirEntries.emplace_back(); entry.fileno = dirEntries.size(); // TODO entry.reclen = sizeof(entry); From 1d3a3949f3d7b20f2b74fe7493fd49f7afcfc4ea Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 21:16:43 +0300 Subject: [PATCH 16/21] [rpcsx-os] dynlib_load_prx: early return error if prx not exists --- rpcsx-os/ops.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rpcsx-os/ops.cpp b/rpcsx-os/ops.cpp index 860cad9c..bceacc11 100644 --- a/rpcsx-os/ops.cpp +++ b/rpcsx-os/ops.cpp @@ -429,6 +429,14 @@ orbis::SysResult dynlib_load_prx(orbis::Thread *thread, return errorCode; } + { + orbis::Ref file; + if (auto result = rx::vfs::open(_name, 0, 0, &file, thread); + result.isError()) { + return result; + } + } + auto [result, module] = loadPrx(thread, _name, true); if (result.isError()) { return result; From 74aa1a112e874b87e94b253fdd9a91b834cd44d1 Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 21:30:43 +0300 Subject: [PATCH 17/21] [rpcsx-os] shm: escape subdirectories --- rpcsx-os/iodev/shm.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rpcsx-os/iodev/shm.cpp b/rpcsx-os/iodev/shm.cpp index e5578da7..5cf905da 100644 --- a/rpcsx-os/iodev/shm.cpp +++ b/rpcsx-os/iodev/shm.cpp @@ -19,12 +19,16 @@ orbis::ErrorCode ShmDevice::open(orbis::Ref *file, ORBIS_LOG_WARNING("shm_open", path, flags, mode); std::string name = "/rpcsx-"; - if (std::string_view{path}.starts_with("/")) { + if (path[0] == '/') { name += path + 1; } else { name += path; } + for (auto pos = name.find('/', 1); pos != std::string::npos; pos = name.find('/', pos + 1)) { + name[pos] = '$'; + } + auto realFlags = O_RDWR; // TODO std::size_t size = 0; From 135c63117b441dd5f8daf630083360b1f55034bb Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 23:41:44 +0300 Subject: [PATCH 18/21] Add version utility --- CMakeLists.txt | 5 +++ rpcsx-gpu/CMakeLists.txt | 2 +- rpcsx-gpu/main.cpp | 18 ++++++++--- rpcsx-os/main.cpp | 41 +++++++++++++++---------- rx/CMakeLists.txt | 39 ++++++++++++++++++++++-- rx/include/rx/Version.hpp | 64 +++++++++++++++++++++++++++++++++++++++ rx/src/Version.cpp | 11 +++++++ 7 files changed, 157 insertions(+), 23 deletions(-) create mode 100644 rx/include/rx/Version.hpp create mode 100644 rx/src/Version.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f85f4c0..aaf1d22a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,3 +12,8 @@ add_subdirectory(rpcsx-os) add_subdirectory(rpcsx-gpu) add_subdirectory(hw/amdgpu) add_subdirectory(rx) + +target_compile_definitions(rx PRIVATE + RX_TAG=0 + RX_TAG_VERSION=0 +) diff --git a/rpcsx-gpu/CMakeLists.txt b/rpcsx-gpu/CMakeLists.txt index d33fe9ae..b148c0dd 100644 --- a/rpcsx-gpu/CMakeLists.txt +++ b/rpcsx-gpu/CMakeLists.txt @@ -6,6 +6,6 @@ add_executable(rpcsx-gpu ) target_include_directories(rpcsx-gpu PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(rpcsx-gpu PUBLIC amdgpu::bridge amdgpu::device glfw Vulkan::Vulkan) +target_link_libraries(rpcsx-gpu PUBLIC amdgpu::bridge amdgpu::device glfw Vulkan::Vulkan rx) set_target_properties(rpcsx-gpu PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) install(TARGETS rpcsx-gpu RUNTIME DESTINATION bin) diff --git a/rpcsx-gpu/main.cpp b/rpcsx-gpu/main.cpp index e7e82467..7f5cfcf5 100644 --- a/rpcsx-gpu/main.cpp +++ b/rpcsx-gpu/main.cpp @@ -1,6 +1,7 @@ #include "amdgpu/RemoteMemory.hpp" #include "amdgpu/device/gpu-scheduler.hpp" #include "amdgpu/device/vk.hpp" +#include "rx/Version.hpp" #include "util/unreachable.hpp" #include #include @@ -30,6 +31,7 @@ extern amdgpu::RemoteMemory g_hostMemory; static void usage(std::FILE *out, const char *argv0) { std::fprintf(out, "usage: %s [options...]\n", argv0); std::fprintf(out, " options:\n"); + std::fprintf(out, " --version, -v - print version\n"); std::fprintf(out, " --cmd-bridge - setup command queue bridge name\n"); std::fprintf(out, " --shm - setup shared memory name\n"); @@ -75,10 +77,18 @@ static VkResult _vkCreateDebugUtilsMessengerEXT( } int main(int argc, const char *argv[]) { - if (argc == 2 && (argv[1] == std::string_view("-h") || - argv[1] == std::string_view("--help"))) { - usage(stdout, argv[0]); - return 0; + if (argc == 2) { + if (argv[1] == std::string_view("-h") || + argv[1] == std::string_view("--help")) { + usage(stdout, argv[0]); + return 0; + } + + if (argv[1] == std::string_view("-v") || + argv[1] == std::string_view("--version")) { + std::printf("v%s\n", rx::getVersion().toString().c_str()); + return 0; + } } const char *cmdBridgeName = "/rpcsx-gpu-cmds"; diff --git a/rpcsx-os/main.cpp b/rpcsx-os/main.cpp index 99bdaeb7..fba2c68f 100644 --- a/rpcsx-os/main.cpp +++ b/rpcsx-os/main.cpp @@ -9,6 +9,7 @@ #include "thread.hpp" #include "vfs.hpp" #include "vm.hpp" +#include #include #include @@ -165,25 +166,26 @@ void setupSigHandlers() { stack_t oss{}; // if (sigaltstack(nullptr, &oss) < 0 || oss.ss_size == 0) { - auto sigStackSize = std::max( - SIGSTKSZ, utils::alignUp(64 * 1024 * 1024, sysconf(_SC_PAGE_SIZE))); - - stack_t ss{}; - ss.ss_sp = malloc(sigStackSize); - if (ss.ss_sp == NULL) { - perror("malloc"); - exit(EXIT_FAILURE); - } + auto sigStackSize = std::max( + SIGSTKSZ, utils::alignUp(64 * 1024 * 1024, sysconf(_SC_PAGE_SIZE))); + + stack_t ss{}; + ss.ss_sp = malloc(sigStackSize); + if (ss.ss_sp == NULL) { + perror("malloc"); + exit(EXIT_FAILURE); + } - ss.ss_size = sigStackSize; - ss.ss_flags = 1 << 31; + ss.ss_size = sigStackSize; + ss.ss_flags = 1 << 31; - std::fprintf(stderr, "installing sp [%p, %p]\n", ss.ss_sp, (char *)ss.ss_sp + ss.ss_size); + std::fprintf(stderr, "installing sp [%p, %p]\n", ss.ss_sp, + (char *)ss.ss_sp + ss.ss_size); - if (sigaltstack(&ss, NULL) == -1) { - perror("sigaltstack"); - exit(EXIT_FAILURE); - } + if (sigaltstack(&ss, NULL) == -1) { + perror("sigaltstack"); + exit(EXIT_FAILURE); + } // } struct sigaction act {}; @@ -521,6 +523,7 @@ int ps4Exec(orbis::Thread *mainThread, static void usage(const char *argv0) { std::printf("%s [...] [args...]\n", argv0); std::printf(" options:\n"); + std::printf(" --version, -v - print version\n"); std::printf(" -m, --mount \n"); std::printf(" -a, --enable-audio\n"); std::printf(" -o, --override +#include +#include + +namespace rx { +enum class VersionTag { Draft, RC, Release }; + +struct Version { + std::uint32_t raw{}; + VersionTag tag{}; + std::uint32_t tagVersion{}; + std::uint32_t gitTag{}; + bool dirty{}; + + std::string toString() const { + std::string result = std::to_string(raw); + + if (tag == VersionTag::Draft && gitTag != 0) { + result += '-'; + auto value = gitTag; + char buf[7]; + for (int i = 0; i < 7; ++i) { + auto digit = value & 0xf; + value >>= 4; + if (digit >= 10) { + buf[i] = 'a' + (digit - 10); + } else { + buf[i] += '0' + digit; + } + } + + for (int i = 0; i < 7; ++i) { + result += buf[6 - i]; + } + } + + switch (tag) { + case VersionTag::Draft: + result += " Draft"; + break; + case VersionTag::RC: + result += " RC"; + break; + case VersionTag::Release: + break; + } + + if (tagVersion) { + result += std::to_string(tagVersion); + } + + + if (dirty) { + result += '+'; + } + + return result; + } +}; + +Version getVersion(); +} // namespace rx diff --git a/rx/src/Version.cpp b/rx/src/Version.cpp new file mode 100644 index 00000000..9e99aaed --- /dev/null +++ b/rx/src/Version.cpp @@ -0,0 +1,11 @@ +#include "rx/Version.hpp" + +rx::Version rx::getVersion() { + return { + .raw = RX_RAW_VERSION, + .tag = static_cast(RX_TAG), + .tagVersion = RX_TAG_VERSION, + .gitTag = RX_GIT_REV, + .dirty = (RX_GIT_DIRTY != 0), + }; +} From d29fcf1f6f930d7e0d4aedb037e7207344d80add Mon Sep 17 00:00:00 2001 From: DH Date: Fri, 10 Nov 2023 23:57:20 +0300 Subject: [PATCH 19/21] [orbis-kernel] avoid useless logs on initialization --- 3rdparty/crypto/CMakeLists.txt | 2 +- orbis-kernel/src/KernelContext.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/3rdparty/crypto/CMakeLists.txt b/3rdparty/crypto/CMakeLists.txt index af96e4da..25770d84 100644 --- a/3rdparty/crypto/CMakeLists.txt +++ b/3rdparty/crypto/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.20) project(libcrypto) set(PROJECT_PATH crypto) diff --git a/orbis-kernel/src/KernelContext.cpp b/orbis-kernel/src/KernelContext.cpp index a1407ee0..dea01d77 100644 --- a/orbis-kernel/src/KernelContext.cpp +++ b/orbis-kernel/src/KernelContext.cpp @@ -29,8 +29,8 @@ KernelContext::KernelContext() { pthread_mutex_init(&m_heap_mtx, &mtx_attr); pthread_mutexattr_destroy(&mtx_attr); - std::printf("orbis::KernelContext initialized, addr=%p\n", this); - std::printf("TSC frequency: %lu\n", getTscFreq()); + // std::printf("orbis::KernelContext initialized, addr=%p\n", this); + // std::printf("TSC frequency: %lu\n", getTscFreq()); } KernelContext::~KernelContext() {} From 4096df70f491c80c26eedb1c4165479c91d5340e Mon Sep 17 00:00:00 2001 From: DH Date: Sat, 11 Nov 2023 00:02:56 +0300 Subject: [PATCH 20/21] Fix git draft --- rx/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rx/CMakeLists.txt b/rx/CMakeLists.txt index 01db52c5..26b039ab 100644 --- a/rx/CMakeLists.txt +++ b/rx/CMakeLists.txt @@ -17,7 +17,7 @@ execute_process(COMMAND git log --pretty=format:'%h' -n 1 OUTPUT_VARIABLE GIT_REV) execute_process( - COMMAND bash git diff --quiet --exit-code + COMMAND git diff --quiet --exit-code RESULT_VARIABLE GIT_DIRTY ERROR_QUIET) execute_process( From 37295c16a1940dd7aafe256a4e54b7ff14f4db4f Mon Sep 17 00:00:00 2001 From: DH Date: Sat, 11 Nov 2023 00:20:08 +0300 Subject: [PATCH 21/21] [rpcsx-os][orbis-kernel] Remove hacks Removed evf_create, osem_create, ipmi and shm hacks --- orbis-kernel/src/sys/sys_sce.cpp | 474 +------------------------------ rpcsx-os/iodev/shm.cpp | 26 +- 2 files changed, 5 insertions(+), 495 deletions(-) diff --git a/orbis-kernel/src/sys/sys_sce.cpp b/orbis-kernel/src/sys/sys_sce.cpp index 407b11cc..2d050d3b 100644 --- a/orbis-kernel/src/sys/sys_sce.cpp +++ b/orbis-kernel/src/sys/sys_sce.cpp @@ -192,7 +192,7 @@ orbis::SysResult orbis::sys_evf_delete(Thread *thread, sint id) { ORBIS_LOG_WARNING(__FUNCTION__, id); Ref evf = thread->tproc->evfMap.get(id); if (evf == nullptr) { - return ErrorCode::SRCH; + return ErrorCode::NOENT; } thread->tproc->evfMap.destroy(id); @@ -209,29 +209,7 @@ orbis::SysResult orbis::sys_evf_open(Thread *thread, ptr name) { auto eventFlag = thread->tproc->context->findEventFlag(_name); if (eventFlag == nullptr) { - // if (_name[0] == '\0') { - // return ErrorCode::NOENT; - // } - - // HACK :) - if (std::string_view(_name).starts_with("SceAppMessaging")) { - // change pattern on system window open - return sys_evf_create(thread, name, kEvfAttrShared, 1); - } - - if (std::string_view("SceShellCoreUtilPowerControl") == _name) { - return sys_evf_create(thread, name, kEvfAttrShared, 0x400000); - } - - if (std::string_view("SceShellCoreUtilAppFocus") == _name) { - return sys_evf_create(thread, name, kEvfAttrShared, 1); - } - - if (std::string_view("SceBootStatusFlags") == _name) { - return sys_evf_create(thread, name, kEvfAttrShared, 0x2408); - } - return sys_evf_create(thread, name, kEvfAttrShared, 0); - return ErrorCode::SRCH; + return ErrorCode::NOENT; } thread->retval[0] = thread->tproc->evfMap.insert(eventFlag); @@ -240,7 +218,7 @@ orbis::SysResult orbis::sys_evf_open(Thread *thread, ptr name) { orbis::SysResult orbis::sys_evf_close(Thread *thread, sint id) { ORBIS_LOG_WARNING(__FUNCTION__, thread->tid, id); if (!thread->tproc->evfMap.close(id)) { - return ErrorCode::SRCH; + return ErrorCode::NOENT; } return {}; @@ -436,20 +414,6 @@ orbis::SysResult orbis::sys_osem_open(Thread *thread, auto sem = thread->tproc->context->findSemaphore(_name); if (sem == nullptr) { - // FIXME: hack :) - if (std::string_view(_name).starts_with("SceLncSuspendBlock")) { - auto result = sys_osem_create(thread, name, kSemaAttrShared, 1, 10000); - ORBIS_LOG_WARNING(__FUNCTION__, _name, result.value(), thread->retval[0]); - return result; - } else if (std::string_view(_name).starts_with("SceAppMessaging")) { - auto result = sys_osem_create(thread, name, kSemaAttrShared, 1, 10000); - ORBIS_LOG_WARNING(__FUNCTION__, _name, result.value(), thread->retval[0]); - return result; - } else { - auto result = sys_osem_create(thread, name, kSemaAttrShared, 0, 10000); - ORBIS_LOG_WARNING(__FUNCTION__, _name, result.value(), thread->retval[0]); - return result; - } return ErrorCode::NOENT; } @@ -1116,437 +1080,7 @@ orbis::SysResult orbis::sys_ipmimgr_call(Thread *thread, uint op, uint kid, ORBIS_LOG_TODO("sys_ipmimgr_call", thread->tid, op, kid, result, params, paramsSz, arg6); thread->where(); - - if (op == kImpiCreateServer) { - if (paramsSz != sizeof(IpmiCreateServerParams)) { - return ErrorCode::INVAL; - } - - auto createParams = (ptr)params; - - ORBIS_LOG_TODO("IPMI: create server", createParams->arg0, - createParams->name, createParams->arg2); - - auto [server, inserted] = g_context.createIpmiServer(createParams->name); - if (!inserted) { - return ErrorCode::EXIST; - } - - auto id = thread->tproc->ipmiServerMap.insert(server); - return uwrite(result, id); - } - - if (op == 0x10) { - // IPMI server start? - - return uwrite(result, 0); - } - - if (op == 0x201) { - // IPMI server receive packet? - return uwrite(result, 0x80020023); - } - - if (op == kIpmiCreateClient) { - if (paramsSz != sizeof(IpmiCreateClientParams)) { - return ErrorCode::INVAL; - } - - auto createParams = (ptr)params; - - ORBIS_LOG_TODO("IPMI: create client", createParams->arg0, - createParams->name, createParams->arg2); - // auto server = g_context.findIpmiServer(createParams->name); - - // if (server == nullptr) { - // ORBIS_LOG_TODO("IPMI: failed to find server", createParams->name); - // } - - auto ipmiClient = knew(createParams->name); - // ipmiClient->connection = server; - auto id = thread->tproc->ipmiClientMap.insert(ipmiClient); - return uwrite(result, id); - } - - if (op == kImpiDestroyClient) { - ORBIS_LOG_TODO("IPMI: destroy client"); - thread->tproc->ipmiClientMap.close(kid); - if (result) { - return uwrite(result, 0); - } - - return {}; - } - - auto client = thread->tproc->ipmiClientMap.get(kid); - - if (client == nullptr) { - return ErrorCode::INVAL; - } - - if (op == 0x241) { - if (result) { - return uwrite(result, 0); - } - } - - if (op == 0x400) { - if (paramsSz != sizeof(IpmiClientConnectParams)) { - return ErrorCode::INVAL; - } - - auto connectParams = (ptr)params; - ORBIS_LOG_TODO("IPMI: connect?", client->name, connectParams->arg0, - connectParams->name, connectParams->arg2, - connectParams->arg3); - if (result) { - return uwrite(result, 0); - } - } - - if (op == 0x320) { - ORBIS_LOG_TODO("IPMI: invoke sync method"); - - if (paramsSz != sizeof(IpmiSyncCallParams)) { - return ErrorCode::INVAL; - } - - IpmiSyncCallParams syncCallParams; - auto errorCode = uread(syncCallParams, (ptr)params); - if (errorCode != ErrorCode{}) { - return errorCode; - } - - ORBIS_LOG_TODO("IPMI: invokeSyncMethod", client->name, - syncCallParams.method, syncCallParams.dataCount, - syncCallParams.flags, syncCallParams.pData, - syncCallParams.pBuffers, syncCallParams.pResult, - syncCallParams.resultCount); - - IpmiDataInfo dataInfo; - uread(dataInfo, syncCallParams.pData); - - ORBIS_LOG_TODO("", dataInfo.data, dataInfo.size); - - if (client->name == "SceMbusIpc") { - if (syncCallParams.method == 0xce110007) { // SceMbusIpcAddHandleByUserId - struct SceMbusIpcAddHandleByUserIdMethodArgs { - uint32_t unk; // 0 - uint32_t deviceId; - uint32_t userId; - uint32_t type; - uint32_t index; - uint32_t reserved; - uint32_t pid; - }; - - static_assert(sizeof(SceMbusIpcAddHandleByUserIdMethodArgs) == 0x1c); - - if (dataInfo.size != sizeof(SceMbusIpcAddHandleByUserIdMethodArgs)) { - return ErrorCode::INVAL; - } - - SceMbusIpcAddHandleByUserIdMethodArgs args; - uread(args, ptr(dataInfo.data)); - - ORBIS_LOG_TODO("IPMI: SceMbusIpcAddHandleByUserId", args.unk, - args.deviceId, args.userId, args.type, args.index, - args.reserved, args.pid); - } else if (syncCallParams.method == 0xce11002a || - syncCallParams.method == 0xce110029) { - std::this_thread::sleep_for(std::chrono::seconds(60)); - } else { - std::abort(); - } - - return uwrite(result, 1); - } else if (client->name == "SceUserService") { - ORBIS_LOG_TODO("SceUserService"); - if (syncCallParams.method == 0x30011) { // get initial user id - ORBIS_LOG_TODO("SceUserService: get_initial_user_id"); - auto err = uwrite(syncCallParams.pResult, 0); - if (err != ErrorCode{}) { - return err; - } - IpmiBufferInfo bufferInfo; - err = uread(bufferInfo, syncCallParams.pBuffers); - if (err != ErrorCode{}) { - return err; - } - - if (bufferInfo.size != sizeof(uint32_t)) { - return uwrite(result, -1); - } - - err = uwrite((ptr)bufferInfo.data, 1u); // initial user id - if (err != ErrorCode{}) { - return err; - } - return uwrite(result, 0); - } - } else if (client->name == "SceLncService") { - if (syncCallParams.method == 0x30010 || - syncCallParams.method == 0x30013) { // get app status - // returns pending system events - ORBIS_LOG_TODO("SceUserService: get_app_status"); - auto err = uwrite(syncCallParams.pResult, 0); - if (err != ErrorCode{}) { - return err; - } - IpmiBufferInfo bufferInfo; - err = uread(bufferInfo, syncCallParams.pBuffers); - if (err != ErrorCode{}) { - return err; - } - - struct Result { - std::uint32_t unk0; - std::uint32_t unk1; - std::uint32_t unk2; - }; - - static_assert(sizeof(Result) == 0xc); - - if (bufferInfo.size != sizeof(Result)) { - return uwrite(result, -1); - } - - Result bufferResult{ - .unk0 = 1, - .unk1 = 1, - .unk2 = 1, - }; - - err = uwrite((ptr)bufferInfo.data, bufferResult); - if (err != ErrorCode{}) { - return err; - } - return uwrite(result, 0); - } - } else if (client->name == "SceSysAudioSystemIpc") { - if (syncCallParams.method == 0x12340000) { // check shared memory control - struct SceSysAudioSystemIpcCheckSharedMemoryControlMethodArgs { - uint32_t channelId; - }; - - static_assert( - sizeof(SceSysAudioSystemIpcCheckSharedMemoryControlMethodArgs) == - 0x4); - - if (dataInfo.size != - sizeof(SceSysAudioSystemIpcCheckSharedMemoryControlMethodArgs)) { - return ErrorCode::INVAL; - } - - SceSysAudioSystemIpcCheckSharedMemoryControlMethodArgs args; - uread(args, ptr( - dataInfo.data)); - - ORBIS_LOG_TODO( - "impi: SceSysAudioSystemIpcCheckSharedMemoryControlMethodArgs", - args.channelId); - if (auto audioOut = g_context.audioOut) { - audioOut->channelInfo.idControl = args.channelId; - } - } else if (syncCallParams.method == 0x1234000f) { // create event flag - struct SceSysAudioSystemIpcCreateEventFlagMethodArgs { - uint32_t channelId; - }; - - static_assert(sizeof(SceSysAudioSystemIpcCreateEventFlagMethodArgs) == - 0x4); - - if (dataInfo.size != - sizeof(SceSysAudioSystemIpcCreateEventFlagMethodArgs)) { - return ErrorCode::INVAL; - } - - SceSysAudioSystemIpcCreateEventFlagMethodArgs args; - uread(args, ptr( - dataInfo.data)); - - if (auto audioOut = g_context.audioOut) { - // very bad - char buffer[32]; - std::snprintf(buffer, sizeof(buffer), "sceAudioOutMix%x", - args.channelId); - // const char* eventName = &buffer; - auto [eventFlag, inserted] = thread->tproc->context->createEventFlag( - buffer, kEvfAttrShared, 0); - - if (!inserted) { - return ErrorCode::EXIST; // FIXME: verify - } - - audioOut->channelInfo.evf = eventFlag; - } - } else if (syncCallParams.method == - 0x12340001) { // check shared memory audio - struct SceSysAudioSystemIpcCheckSharedMemoryAudioMethodArgs { - uint32_t audioPort; - uint32_t channelId; - }; - - static_assert( - sizeof(SceSysAudioSystemIpcCheckSharedMemoryAudioMethodArgs) == - 0x8); - - if (dataInfo.size != - sizeof(SceSysAudioSystemIpcCheckSharedMemoryAudioMethodArgs)) { - return ErrorCode::INVAL; - } - - SceSysAudioSystemIpcCheckSharedMemoryAudioMethodArgs args; - uread(args, ptr( - dataInfo.data)); - - ORBIS_LOG_TODO( - "IPMI: SceSysAudioSystemIpcCheckSharedMemoryAudioMethodArgs", - args.audioPort, args.channelId); - if (auto audioOut = g_context.audioOut) { - audioOut->channelInfo.port = args.audioPort; - audioOut->channelInfo.channel = args.channelId; - } - } else if (syncCallParams.method == 0x12340002) { // something like open - struct SceSysAudioSystemIpcSomethingMethodArgs { - uint32_t audioPort; - uint32_t channelId; - }; - - static_assert(sizeof(SceSysAudioSystemIpcSomethingMethodArgs) == 0x8); - - if (dataInfo.size != sizeof(SceSysAudioSystemIpcSomethingMethodArgs)) { - return ErrorCode::INVAL; - } - - SceSysAudioSystemIpcSomethingMethodArgs args; - uread(args, - ptr(dataInfo.data)); - - ORBIS_LOG_TODO("IPMI: SceSysAudioSystemIpcSomethingMethodArgs", - args.audioPort, args.channelId); - - if (auto audioOut = g_context.audioOut) { - // here startToListen - audioOut->start(); - } - } else if (syncCallParams.method == 0x12340006) { // close port - struct SceSysAudioSystemIpcCloseAudioMethodArgs { - uint32_t audioPort; - uint32_t channelId; - }; - - static_assert(sizeof(SceSysAudioSystemIpcCloseAudioMethodArgs) == 0x8); - - if (dataInfo.size != sizeof(SceSysAudioSystemIpcCloseAudioMethodArgs)) { - return ErrorCode::INVAL; - } - - SceSysAudioSystemIpcCloseAudioMethodArgs args; - uread(args, - ptr(dataInfo.data)); - - ORBIS_LOG_TODO("IPMI: SceSysAudioSystemIpcCloseAudioMethodArgs", - args.audioPort, args.channelId); - } - } - - if (result != nullptr) { - return uwrite(result, 0); - } - - return {}; - } - - if (op == 0x310) { - ORBIS_LOG_TODO("IPMI: disconnect?"); - if (result) { - return uwrite(result, 0); - } - - return {}; - } - - if (op == 0x252) { - ORBIS_LOG_TODO("IPMI: client:tryGet", client->name); - thread->where(); - - struct SceIpmiClientTryGetArgs { - uint32_t unk; // 0 - uint32_t padding; - ptr message; - ptr pSize; - uint64_t maxSize; - }; - - static_assert(sizeof(SceIpmiClientTryGetArgs) == 0x20); - - if (paramsSz != sizeof(SceIpmiClientTryGetArgs)) { - return ErrorCode::INVAL; - } - - SceIpmiClientTryGetArgs tryGetParams; - auto errorCode = uread(tryGetParams, (ptr)params); - if (errorCode != ErrorCode{}) { - return errorCode; - } - - ORBIS_LOG_WARNING("IPMI: client: tryGet", tryGetParams.unk, - tryGetParams.message, tryGetParams.pSize, - tryGetParams.maxSize); - - if (client->name == "SceUserService") { - static bool isFirst = true; // TODO: implement ipmi hooks at os side - - if (isFirst) { - isFirst = false; - - struct SceUserServiceEvent { - std::uint32_t eventType; // 0 - login, 1 - logout - std::uint32_t user; - }; - - if (tryGetParams.maxSize < sizeof(SceUserServiceEvent)) { - return uwrite(result, 0x80020003); - } - - errorCode = uwrite(tryGetParams.pSize, sizeof(SceUserServiceEvent)); - if (errorCode != ErrorCode{}) { - return errorCode; - } - - errorCode = uwrite((ptr)tryGetParams.message, - {.eventType = 0, .user = 1}); - - if (errorCode != ErrorCode{}) { - return errorCode; - } - - return uwrite(result, 0); - } else { - return uwrite(result, 0x80020003); - } - } - if (result) { - return uwrite(result, 0x80020003); - } - return {}; - } - - if (op == 0x46b) { - thread->retval[0] = -0x40004; // HACK - return {}; - } - - if (op == 0x243) { - return uwrite(result, 0); - } - - if (op == 0x491) { - return uwrite(result, 0); - } - - return ErrorCode::INVAL; + return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_get_gpo(Thread *thread /* TODO */) { return ErrorCode::NOSYS; diff --git a/rpcsx-os/iodev/shm.cpp b/rpcsx-os/iodev/shm.cpp index 5cf905da..34f1a291 100644 --- a/rpcsx-os/iodev/shm.cpp +++ b/rpcsx-os/iodev/shm.cpp @@ -32,31 +32,7 @@ orbis::ErrorCode ShmDevice::open(orbis::Ref *file, auto realFlags = O_RDWR; // TODO std::size_t size = 0; - if (~flags & 0x200) { - if (name == "/rpcsx-SceShellCoreUtil") { - // TODO - realFlags |= O_CREAT; - size = 0x4000; - } else if (name == "/rpcsx-vmicDdShmAin") { - // TODO - realFlags |= O_CREAT; - size = 0x4000; - } else if (name == "/rpcsx-SceNpTpip") { - // TODO - realFlags |= O_CREAT; - size = 0x4000; - } else if (name == "/rpcsx-SceNpPlusLogger") { - realFlags |= O_CREAT; - size = 0x4400; - } else if (name == "/rpcsx-SceAvSetting") { - realFlags |= O_CREAT; - size = 0x4400; - } else { - ORBIS_LOG_ERROR("SHM: unknown shared memory", path); - thread->where(); - std::abort(); - } - } else { + if (flags & 0x200) { realFlags |= O_CREAT; }