diff --git a/orbis-kernel/include/orbis/sys/sysproto.hpp b/orbis-kernel/include/orbis/sys/sysproto.hpp index ec95ced58..09f97bff6 100644 --- a/orbis-kernel/include/orbis/sys/sysproto.hpp +++ b/orbis-kernel/include/orbis/sys/sysproto.hpp @@ -728,7 +728,9 @@ SysResult sys_get_vm_map_timestamp(Thread *thread /* TODO */); SysResult sys_opmc_set_hw(Thread *thread /* TODO */); SysResult sys_opmc_get_hw(Thread *thread /* TODO */); SysResult sys_get_cpu_usage_all(Thread *thread /* TODO */); -SysResult sys_mmap_dmem(Thread *thread /* TODO */); +SysResult sys_mmap_dmem(Thread *thread, caddr_t addr, size_t len, + sint memoryType, sint prot, sint flags, + off_t directMemoryStart); SysResult sys_physhm_open(Thread *thread /* TODO */); SysResult sys_physhm_unlink(Thread *thread /* TODO */); SysResult sys_resume_internal_hdd(Thread *thread /* TODO */); diff --git a/orbis-kernel/include/orbis/thread/ProcessOps.hpp b/orbis-kernel/include/orbis/thread/ProcessOps.hpp index d218ff652..6113cc0f8 100644 --- a/orbis-kernel/include/orbis/thread/ProcessOps.hpp +++ b/orbis-kernel/include/orbis/thread/ProcessOps.hpp @@ -14,6 +14,9 @@ struct File; struct ProcessOps { SysResult (*mmap)(Thread *thread, caddr_t addr, size_t len, sint prot, sint flags, sint fd, off_t pos); + SysResult (*dmem_mmap)(Thread *thread, caddr_t addr, size_t len, + sint memoryType, sint prot, sint flags, + off_t directMemoryStart); SysResult (*munmap)(Thread *thread, ptr addr, size_t len); SysResult (*msync)(Thread *thread, ptr addr, size_t len, sint flags); SysResult (*mprotect)(Thread *thread, ptr addr, size_t len, diff --git a/orbis-kernel/src/sys/sys_sce.cpp b/orbis-kernel/src/sys/sys_sce.cpp index 84decafd7..b26d95d8b 100644 --- a/orbis-kernel/src/sys/sys_sce.cpp +++ b/orbis-kernel/src/sys/sys_sce.cpp @@ -1093,7 +1093,13 @@ orbis::SysResult orbis::sys_opmc_get_hw(Thread *thread /* TODO */) { orbis::SysResult orbis::sys_get_cpu_usage_all(Thread *thread /* TODO */) { return ErrorCode::NOSYS; } -orbis::SysResult orbis::sys_mmap_dmem(Thread *thread /* TODO */) { +orbis::SysResult orbis::sys_mmap_dmem(Thread *thread, caddr_t addr, size_t len, + sint memoryType, sint prot, sint flags, + off_t directMemoryStart) { + if (auto dmem_mmap = thread->tproc->ops->dmem_mmap) { + return dmem_mmap(thread, addr, len, memoryType, prot, flags, + directMemoryStart); + } return ErrorCode::NOSYS; } orbis::SysResult orbis::sys_physhm_open(Thread *thread /* TODO */) { diff --git a/rpcsx-os/iodev/dmem.cpp b/rpcsx-os/iodev/dmem.cpp index b3a96c6dc..c079976b3 100644 --- a/rpcsx-os/iodev/dmem.cpp +++ b/rpcsx-os/iodev/dmem.cpp @@ -1,23 +1,12 @@ +#include "dmem.hpp" #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 -struct DmemDevice : public IoDevice { - orbis::shared_mutex mtx; - int index; - std::uint64_t nextOffset; - std::uint64_t memBeginAddress; - - orbis::ErrorCode open(orbis::Ref *file, const char *path, - std::uint32_t flags, std::uint32_t mode, - orbis::Thread *thread) override; -}; - struct DmemFile : public orbis::File {}; struct AllocateDirectMemoryArgs { @@ -32,6 +21,22 @@ static constexpr auto dmemSize = 4ul * 1024 * 1024 * 1024; // static const std::uint64_t nextOffset = 0; // static const std::uint64_t memBeginAddress = 0xfe0000000; +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); + + if (result == (void *)-1) { + return orbis::ErrorCode::NOMEM; // TODO + } + + *address = result; + return {}; +} + static orbis::ErrorCode dmem_ioctl(orbis::File *file, std::uint64_t request, void *argp, orbis::Thread *thread) { auto device = static_cast(file->device.get()); diff --git a/rpcsx-os/iodev/dmem.hpp b/rpcsx-os/iodev/dmem.hpp new file mode 100644 index 000000000..a129573b5 --- /dev/null +++ b/rpcsx-os/iodev/dmem.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include "io-device.hpp" +#include "orbis/error/ErrorCode.hpp" +#include "orbis/file.hpp" +#include "orbis/utils/Rc.hpp" +#include "orbis/utils/SharedMutex.hpp" +#include +#include + +struct DmemDevice : public IoDevice { + orbis::shared_mutex mtx; + int index; + std::uint64_t nextOffset; + std::uint64_t memBeginAddress; + + orbis::ErrorCode open(orbis::Ref *file, const char *path, + std::uint32_t flags, std::uint32_t mode, + orbis::Thread *thread) override; + + orbis::ErrorCode mmap(void **address, std::uint64_t len, + std::int32_t memoryType, std::int32_t prot, + std::int32_t flags, std::int64_t directMemoryStart); +}; diff --git a/rpcsx-os/main.cpp b/rpcsx-os/main.cpp index 43822fc22..b9c397cb9 100644 --- a/rpcsx-os/main.cpp +++ b/rpcsx-os/main.cpp @@ -307,8 +307,11 @@ static int ps4Exec(orbis::Thread *mainThread, mainThread->stackEnd = reinterpret_cast(mainThread->stackStart) + stackSize; + auto dmem1 = createDmemCharacterDevice(1); + orbis::g_context.dmemDevice = dmem1; + rx::vfs::mount("/dev/dmem0", createDmemCharacterDevice(0)); - rx::vfs::mount("/dev/dmem1", createDmemCharacterDevice(1)); + rx::vfs::mount("/dev/dmem1", dmem1); rx::vfs::mount("/dev/dmem2", createDmemCharacterDevice(2)); rx::vfs::mount("/dev/stdout", createFdWrapDevice(STDOUT_FILENO)); rx::vfs::mount("/dev/stderr", createFdWrapDevice(STDERR_FILENO)); diff --git a/rpcsx-os/ops.cpp b/rpcsx-os/ops.cpp index 2577caa35..d83fb5d88 100644 --- a/rpcsx-os/ops.cpp +++ b/rpcsx-os/ops.cpp @@ -2,6 +2,7 @@ #include "align.hpp" #include "backtrace.hpp" #include "io-device.hpp" +#include "iodev/dmem.hpp" #include "linker.hpp" #include "orbis/KernelContext.hpp" #include "orbis/module/ModuleHandle.hpp" @@ -170,6 +171,22 @@ orbis::SysResult mmap(orbis::Thread *thread, orbis::caddr_t addr, return {}; } +orbis::SysResult dmem_mmap(orbis::Thread *thread, orbis::caddr_t addr, + orbis::size_t len, orbis::sint memoryType, + orbis::sint prot, sint flags, + orbis::off_t directMemoryStart) { + auto dmem = static_cast(orbis::g_context.dmemDevice.get()); + void *address = addr; + auto result = + dmem->mmap(&address, len, memoryType, prot, flags, directMemoryStart); + if (result != ErrorCode{}) { + return result; + } + + thread->retval[0] = reinterpret_cast(address); + return {}; +} + orbis::SysResult munmap(orbis::Thread *, orbis::ptr addr, orbis::size_t len) { if (rx::vm::unmap(addr, len)) { @@ -531,6 +548,7 @@ void where(Thread *thread) { ProcessOps rx::procOpsTable = { .mmap = mmap, + .dmem_mmap = dmem_mmap, .munmap = munmap, .msync = msync, .mprotect = mprotect,