mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-01-11 03:00:16 +01:00
[rpcsx-os] implement blockpool device
This commit is contained in:
parent
e967c8cf80
commit
89db63ca46
|
|
@ -149,6 +149,7 @@ public:
|
|||
|
||||
Ref<RcBase> shmDevice;
|
||||
Ref<RcBase> dmemDevice;
|
||||
Ref<RcBase> blockpoolDevice;
|
||||
|
||||
private:
|
||||
mutable pthread_mutex_t m_heap_mtx;
|
||||
|
|
|
|||
|
|
@ -759,9 +759,11 @@ SysResult sys_dynlib_get_obj_member(Thread *thread, SceKernelModule handle,
|
|||
SysResult sys_budget_get_ptype_of_budget(Thread *thread /* TODO */);
|
||||
SysResult sys_prepare_to_resume_process(Thread *thread /* TODO */);
|
||||
SysResult sys_process_terminate(Thread *thread /* TODO */);
|
||||
SysResult sys_blockpool_open(Thread *thread /* TODO */);
|
||||
SysResult sys_blockpool_map(Thread *thread /* TODO */);
|
||||
SysResult sys_blockpool_unmap(Thread *thread /* TODO */);
|
||||
SysResult sys_blockpool_open(Thread *thread);
|
||||
SysResult sys_blockpool_map(Thread *thread, caddr_t addr, size_t len, sint prot,
|
||||
sint flags);
|
||||
SysResult sys_blockpool_unmap(Thread *thread, caddr_t addr, size_t len,
|
||||
sint flags);
|
||||
SysResult sys_dynlib_get_info_for_libdbg(Thread *thread /* TODO */);
|
||||
SysResult sys_blockpool_batch(Thread *thread /* TODO */);
|
||||
SysResult sys_fdatasync(Thread *thread /* TODO */);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@ struct ProcessOps {
|
|||
Ref<File> *file);
|
||||
SysResult (*shm_open)(Thread *thread, const char *path, sint flags, sint mode,
|
||||
Ref<File> *file);
|
||||
SysResult (*blockpool_open)(Thread *thread, Ref<File> *file);
|
||||
SysResult (*blockpool_map)(Thread *thread, caddr_t addr, size_t len,
|
||||
sint prot, sint flags);
|
||||
SysResult (*blockpool_unmap)(Thread *thread, caddr_t addr, size_t len);
|
||||
SysResult (*socket)(Thread *thread, ptr<const char> name, sint domain,
|
||||
sint type, sint protocol, Ref<File> *file);
|
||||
SysResult (*shm_unlink)(Thread *thread, const char *path);
|
||||
|
|
|
|||
|
|
@ -1217,13 +1217,31 @@ orbis::sys_prepare_to_resume_process(Thread *thread /* TODO */) {
|
|||
orbis::SysResult orbis::sys_process_terminate(Thread *thread /* TODO */) {
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
orbis::SysResult orbis::sys_blockpool_open(Thread *thread /* TODO */) {
|
||||
orbis::SysResult orbis::sys_blockpool_open(Thread *thread) {
|
||||
if (auto blockpool_open = thread->tproc->ops->blockpool_open) {
|
||||
Ref<File> file;
|
||||
auto result = blockpool_open(thread, &file);
|
||||
if (result.isError()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
thread->retval[0] = thread->tproc->fileDescriptors.insert(file);
|
||||
return {};
|
||||
}
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
orbis::SysResult orbis::sys_blockpool_map(Thread *thread /* TODO */) {
|
||||
orbis::SysResult orbis::sys_blockpool_map(Thread *thread, caddr_t addr,
|
||||
size_t len, sint prot, sint flags) {
|
||||
if (auto blockpool_map = thread->tproc->ops->blockpool_map) {
|
||||
return blockpool_map(thread, addr, len, prot, flags);
|
||||
}
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
orbis::SysResult orbis::sys_blockpool_unmap(Thread *thread /* TODO */) {
|
||||
orbis::SysResult orbis::sys_blockpool_unmap(Thread *thread, caddr_t addr,
|
||||
size_t len, sint flags) {
|
||||
if (auto blockpool_unmap = thread->tproc->ops->blockpool_unmap) {
|
||||
return blockpool_unmap(thread, addr, len);
|
||||
}
|
||||
return ErrorCode::NOSYS;
|
||||
}
|
||||
orbis::SysResult
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ add_library(orbis::kernel::config ALIAS standalone-config)
|
|||
|
||||
add_executable(rpcsx-os
|
||||
iodev/ajm.cpp
|
||||
iodev/blockpool.cpp
|
||||
iodev/dce.cpp
|
||||
iodev/dipsw.cpp
|
||||
iodev/dmem.cpp
|
||||
|
|
|
|||
|
|
@ -17,3 +17,4 @@ IoDevice *createRngCharacterDevice();
|
|||
IoDevice *createAjmCharacterDevice();
|
||||
IoDevice *createSblSrvCharacterDevice();
|
||||
IoDevice *createShmDevice();
|
||||
IoDevice *createBlockPoolDevice();
|
||||
|
|
|
|||
117
rpcsx-os/iodev/blockpool.cpp
Normal file
117
rpcsx-os/iodev/blockpool.cpp
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
#include "blockpool.hpp"
|
||||
#include "dmem.hpp"
|
||||
#include "io-device.hpp"
|
||||
#include "orbis/KernelAllocator.hpp"
|
||||
#include "orbis/KernelContext.hpp"
|
||||
#include "orbis/file.hpp"
|
||||
#include "orbis/thread/Thread.hpp"
|
||||
#include "orbis/utils/Logs.hpp"
|
||||
#include "vm.hpp"
|
||||
#include <mutex>
|
||||
#include <sys/mman.h>
|
||||
|
||||
struct BlockPoolFile : public orbis::File {};
|
||||
|
||||
static orbis::ErrorCode blockpool_ioctl(orbis::File *file,
|
||||
std::uint64_t request, void *argp,
|
||||
orbis::Thread *thread) {
|
||||
auto blockPool = static_cast<BlockPoolDevice *>(file->device.get());
|
||||
std::lock_guard lock(blockPool->mtx);
|
||||
|
||||
switch (request) {
|
||||
case 0xc020a801: {
|
||||
auto dmem = static_cast<DmemDevice *>(orbis::g_context.dmemDevice.get());
|
||||
std::lock_guard lock(dmem->mtx);
|
||||
|
||||
struct Args {
|
||||
std::uint64_t len;
|
||||
std::uint64_t searchStart;
|
||||
std::uint64_t searchEnd;
|
||||
std::uint32_t flags;
|
||||
};
|
||||
auto args = reinterpret_cast<Args *>(argp);
|
||||
ORBIS_LOG_TODO("blockpool expand", args->len, args->searchStart,
|
||||
args->searchEnd, args->flags);
|
||||
|
||||
std::uint64_t start = args->searchStart;
|
||||
std::uint64_t len = std::min(args->searchEnd - start, args->len);
|
||||
if (dmem->nextOffset > args->searchEnd) {
|
||||
ORBIS_LOG_TODO("blockpool out of allocation", args->len,
|
||||
args->searchStart, args->searchEnd, args->flags);
|
||||
return orbis::ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
start = std::max(dmem->nextOffset, start);
|
||||
auto end = std::min(start + len, args->searchEnd);
|
||||
dmem->nextOffset = end;
|
||||
args->searchStart = start;
|
||||
|
||||
blockPool->len += end - start;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
ORBIS_LOG_FATAL("Unhandled blockpool ioctl", request);
|
||||
thread->where();
|
||||
return {};
|
||||
}
|
||||
|
||||
static orbis::ErrorCode blockpool_mmap(orbis::File *file, void **address,
|
||||
std::uint64_t size, std::int32_t prot,
|
||||
std::int32_t flags, std::int64_t offset,
|
||||
orbis::Thread *thread) {
|
||||
auto blockPool = static_cast<BlockPoolDevice *>(file->device.get());
|
||||
std::lock_guard lock(blockPool->mtx);
|
||||
ORBIS_LOG_FATAL("blockpool mmap", *address, size, offset, blockPool->len);
|
||||
size = std::min<std::uint64_t>(
|
||||
0x1000000, size); // FIXME: hack, investigate why we report so many memory
|
||||
size = std::min(blockPool->len, size);
|
||||
auto result = rx::vm::map(*address, size, prot, flags);
|
||||
|
||||
if (result == (void *)-1) {
|
||||
return orbis::ErrorCode::INVAL; // TODO
|
||||
}
|
||||
|
||||
blockPool->len -= size;
|
||||
*address = result;
|
||||
return {};
|
||||
}
|
||||
|
||||
static const orbis::FileOps ops = {
|
||||
.ioctl = blockpool_ioctl,
|
||||
.mmap = blockpool_mmap,
|
||||
};
|
||||
|
||||
orbis::ErrorCode BlockPoolDevice::open(orbis::Ref<orbis::File> *file,
|
||||
const char *path, std::uint32_t flags,
|
||||
std::uint32_t mode,
|
||||
orbis::Thread *thread) {
|
||||
auto newFile = orbis::knew<BlockPoolFile>();
|
||||
newFile->device = this;
|
||||
newFile->ops = &ops;
|
||||
*file = newFile;
|
||||
return {};
|
||||
}
|
||||
|
||||
orbis::ErrorCode BlockPoolDevice::map(void **address, std::uint64_t len,
|
||||
std::int32_t prot, std::int32_t flags,
|
||||
orbis::Thread *thread) {
|
||||
ORBIS_LOG_FATAL("blockpool device map", *address, len);
|
||||
auto result = rx::vm::map(*address, len, prot, flags);
|
||||
|
||||
if (result == (void *)-1) {
|
||||
return orbis::ErrorCode::NOMEM;
|
||||
}
|
||||
|
||||
*address = result;
|
||||
return {};
|
||||
}
|
||||
orbis::ErrorCode BlockPoolDevice::unmap(void *address, std::uint64_t len,
|
||||
orbis::Thread *thread) {
|
||||
ORBIS_LOG_FATAL("blockpool device unmap", address, len);
|
||||
if (rx::vm::unmap(address, len)) {
|
||||
return {};
|
||||
}
|
||||
return orbis::ErrorCode::INVAL;
|
||||
}
|
||||
IoDevice *createBlockPoolDevice() { return orbis::knew<BlockPoolDevice>(); }
|
||||
21
rpcsx-os/iodev/blockpool.hpp
Normal file
21
rpcsx-os/iodev/blockpool.hpp
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#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 <cstdint>
|
||||
|
||||
struct BlockPoolDevice : public IoDevice {
|
||||
orbis::shared_mutex mtx;
|
||||
std::uint64_t len = 0;
|
||||
|
||||
orbis::ErrorCode open(orbis::Ref<orbis::File> *file, const char *path,
|
||||
std::uint32_t flags, std::uint32_t mode,
|
||||
orbis::Thread *thread) override;
|
||||
orbis::ErrorCode map(void **address, std::uint64_t len, std::int32_t prot,
|
||||
std::int32_t flags, orbis::Thread *thread);
|
||||
orbis::ErrorCode unmap(void *address, std::uint64_t len,
|
||||
orbis::Thread *thread);
|
||||
};
|
||||
|
|
@ -342,6 +342,7 @@ static int ps4Exec(orbis::Thread *mainThread,
|
|||
mainThread->tproc->fileDescriptors.insert(stderrFile);
|
||||
|
||||
orbis::g_context.shmDevice = createShmDevice();
|
||||
orbis::g_context.blockpoolDevice = createBlockPoolDevice();
|
||||
|
||||
std::vector<std::uint64_t> argvOffsets;
|
||||
std::vector<std::uint64_t> envpOffsets;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "align.hpp"
|
||||
#include "backtrace.hpp"
|
||||
#include "io-device.hpp"
|
||||
#include "iodev/blockpool.hpp"
|
||||
#include "iodev/dmem.hpp"
|
||||
#include "linker.hpp"
|
||||
#include "orbis/KernelContext.hpp"
|
||||
|
|
@ -259,6 +260,33 @@ orbis::SysResult shm_open(orbis::Thread *thread, const char *path,
|
|||
return dev->open(file, path, flags, mode, thread);
|
||||
}
|
||||
|
||||
orbis::SysResult blockpool_open(orbis::Thread *thread,
|
||||
orbis::Ref<orbis::File> *file) {
|
||||
auto dev = static_cast<IoDevice *>(orbis::g_context.blockpoolDevice.get());
|
||||
return dev->open(file, nullptr, 0, 0, thread);
|
||||
}
|
||||
|
||||
orbis::SysResult blockpool_map(orbis::Thread *thread, orbis::caddr_t addr,
|
||||
orbis::size_t len, orbis::sint prot,
|
||||
orbis::sint flags) {
|
||||
auto blockpool =
|
||||
static_cast<BlockPoolDevice *>(orbis::g_context.blockpoolDevice.get());
|
||||
void *address = addr;
|
||||
auto result = blockpool->map(&address, len, prot, flags, thread);
|
||||
if (result != ErrorCode{}) {
|
||||
return result;
|
||||
}
|
||||
|
||||
thread->retval[0] = reinterpret_cast<std::uint64_t>(address);
|
||||
return {};
|
||||
}
|
||||
orbis::SysResult blockpool_unmap(orbis::Thread *thread, orbis::caddr_t addr,
|
||||
orbis::size_t len) {
|
||||
auto blockpool =
|
||||
static_cast<BlockPoolDevice *>(orbis::g_context.blockpoolDevice.get());
|
||||
return blockpool->unmap(addr, len, thread);
|
||||
}
|
||||
|
||||
orbis::SysResult socket(orbis::Thread *thread, orbis::ptr<const char> name,
|
||||
orbis::sint domain, orbis::sint type,
|
||||
orbis::sint protocol, Ref<File> *file) {
|
||||
|
|
@ -562,6 +590,9 @@ ProcessOps rx::procOpsTable = {
|
|||
.virtual_query = virtual_query,
|
||||
.open = open,
|
||||
.shm_open = shm_open,
|
||||
.blockpool_open = blockpool_open,
|
||||
.blockpool_map = blockpool_map,
|
||||
.blockpool_unmap = blockpool_unmap,
|
||||
.socket = socket,
|
||||
.shm_unlink = shm_unlink,
|
||||
.dynlib_get_obj_member = dynlib_get_obj_member,
|
||||
|
|
|
|||
Loading…
Reference in a new issue