Add OS<->GPU IPC

This commit is contained in:
DH 2023-06-24 23:48:25 +03:00
parent df5f8055fa
commit 2ab5cfb1f3
10 changed files with 271 additions and 124 deletions

View file

@ -83,18 +83,17 @@ enum class BridgeFlags {
PullLock = 1 << 2,
};
class BridgePusher {
BridgeHeader *buffer = nullptr;
struct BridgePusher {
BridgeHeader *header = nullptr;
public:
BridgePusher() = default;
BridgePusher(BridgeHeader *buffer) : buffer(buffer) {}
BridgePusher(BridgeHeader *header) : header(header) {}
void setVm(std::uint64_t address, std::uint64_t size, const char *name) {
buffer->vmAddress = address;
buffer->vmSize = size;
std::strncpy(buffer->vmName, name, sizeof(buffer->vmName));
buffer->flags |= static_cast<std::uint64_t>(BridgeFlags::VmConfigured);
header->vmAddress = address;
header->vmSize = size;
std::strncpy(header->vmName, name, sizeof(header->vmName));
header->flags |= static_cast<std::uint64_t>(BridgeFlags::VmConfigured);
}
void sendMemoryProtect(std::uint64_t address, std::uint64_t size,
@ -124,7 +123,7 @@ public:
void sendDoFlip() { sendCommand(CommandId::DoFlip, {}); }
void wait() {
while (buffer->pull != buffer->push)
while (header->pull != header->push)
;
}
@ -138,21 +137,21 @@ private:
std::size_t cmdSize = args.size() + 1;
std::uint64_t pos = getPushPosition(cmdSize);
buffer->commands[pos++] = makeCommandHeader(CommandId::Flip, cmdSize);
header->commands[pos++] = makeCommandHeader(CommandId::Flip, cmdSize);
for (auto arg : args) {
buffer->commands[pos++] = arg;
header->commands[pos++] = arg;
}
buffer->push = pos;
header->push = pos;
}
std::uint64_t getPushPosition(std::uint64_t cmdSize) {
std::uint64_t position = buffer->push;
std::uint64_t position = header->push;
if (position + cmdSize > buffer->size) {
if (position < buffer->size) {
buffer->commands[position] =
if (position + cmdSize > header->size) {
if (position < header->size) {
header->commands[position] =
static_cast<std::uint64_t>(CommandId::Nop) |
((buffer->size - position - 1) << 32);
((header->size - position - 1) << 32);
}
position = 0;
@ -162,44 +161,43 @@ private:
return position;
}
void waitPuller(std::uint64_t pullValue) {
while (buffer->pull < pullValue) {
while (header->pull < pullValue) {
;
}
}
};
class BridgePuller {
BridgeHeader *buffer = nullptr;
struct BridgePuller {
BridgeHeader *header = nullptr;
public:
BridgePuller() = default;
BridgePuller(BridgeHeader *buffer) : buffer(buffer) {}
BridgePuller(BridgeHeader *header) : header(header) {}
std::size_t pullCommands(Command *commands, std::size_t maxCount) {
std::size_t processed = 0;
while (processed < maxCount) {
if (buffer->pull == buffer->push) {
if (header->pull == header->push) {
break;
}
auto pos = buffer->pull;
auto cmd = buffer->commands[pos];
auto pos = header->pull;
auto cmd = header->commands[pos];
CommandId cmdId = static_cast<CommandId>(cmd);
std::uint32_t argsCount = cmd >> 32;
if (cmdId != CommandId::Nop) {
commands[processed++] =
unpackCommand(cmdId, buffer->commands + pos + 1, argsCount);
unpackCommand(cmdId, header->commands + pos + 1, argsCount);
}
auto newPull = pos + argsCount + 1;
if (newPull >= buffer->size) {
if (newPull >= header->size) {
newPull = 0;
}
buffer->pull = newPull;
header->pull = newPull;
}
return processed;

View file

@ -14,7 +14,7 @@ amdgpu::bridge::createShmCommandBuffer(const char *name) {
return nullptr;
}
unlinkShm(name);
// unlinkShm(name);
int fd = ::shm_open(name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
@ -54,6 +54,11 @@ amdgpu::bridge::openShmCommandBuffer(const char *name) {
return nullptr;
}
if (ftruncate(fd, kShmSize) < 0) {
::close(fd);
return nullptr;
}
void *memory =
::mmap(nullptr, kShmSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

View file

@ -2,11 +2,17 @@
#include <amdgpu/bridge/bridge.hpp>
#include <amdgpu/device/device.hpp>
#include <chrono>
#include <csignal>
#include <cstdio>
#include <fcntl.h>
#include <sys/mman.h>
#include <thread>
#include <unistd.h>
#include <util/VerifyVulkan.hpp>
#include <vulkan/vulkan.h>
#include <vulkan/vulkan_core.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <GLFW/glfw3.h> // TODO: make in optional
@ -262,8 +268,8 @@ int main(int argc, const char *argv[]) {
&queueFamilyCount, nullptr);
Verify() << (queueFamilyCount > 0);
queueFamilyProperties.resize(queueFamilyCount);
for (auto &propery : queueFamilyProperties) {
propery.sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
for (auto &property : queueFamilyProperties) {
property.sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
}
vkGetPhysicalDeviceQueueFamilyProperties2(
@ -424,27 +430,33 @@ int main(int argc, const char *argv[]) {
&vkDevice);
std::vector<VkQueue> computeQueues;
std::vector<VkQueue> transferQueues;
std::vector<VkQueue> graphicsQueues;
std::vector<std::pair<VkQueue, unsigned>> computeQueues;
std::vector<std::pair<VkQueue, unsigned>> transferQueues;
std::vector<std::pair<VkQueue, unsigned>> graphicsQueues;
VkQueue presentQueue = VK_NULL_HANDLE;
for (auto &queueInfo : requestedQueues) {
if (queueFamiliesWithComputeSupport.contains(queueInfo.queueFamilyIndex)) {
for (uint32_t queueIndex = 0; queueIndex < queueInfo.queueCount; ++queueIndex) {
vkGetDeviceQueue(vkDevice, queueInfo.queueFamilyIndex, queueIndex, &computeQueues.emplace_back());
auto &[queue, index] = computeQueues.emplace_back();
index = queueInfo.queueFamilyIndex;
vkGetDeviceQueue(vkDevice, queueInfo.queueFamilyIndex, queueIndex, &queue);
}
}
if (queueFamiliesWithGraphicsSupport.contains(queueInfo.queueFamilyIndex)) {
for (uint32_t queueIndex = 0; queueIndex < queueInfo.queueCount; ++queueIndex) {
vkGetDeviceQueue(vkDevice, queueInfo.queueFamilyIndex, queueIndex, &graphicsQueues.emplace_back());
auto &[queue, index] = graphicsQueues.emplace_back();
index = queueInfo.queueFamilyIndex;
vkGetDeviceQueue(vkDevice, queueInfo.queueFamilyIndex, queueIndex, &queue);
}
}
if (queueFamiliesWithTransferSupport.contains(queueInfo.queueFamilyIndex)) {
for (uint32_t queueIndex = 0; queueIndex < queueInfo.queueCount; ++queueIndex) {
vkGetDeviceQueue(vkDevice, queueInfo.queueFamilyIndex, queueIndex, &transferQueues.emplace_back());
auto &[queue, index] = transferQueues.emplace_back();
index = queueInfo.queueFamilyIndex;
vkGetDeviceQueue(vkDevice, queueInfo.queueFamilyIndex, queueIndex, &queue);
}
}
@ -460,16 +472,56 @@ int main(int argc, const char *argv[]) {
amdgpu::device::setVkDevice(vkDevice, vkPhyDeviceMemoryProperties);
std::printf("Initialization was succesful\n");
std::printf("Initialization was successful\n");
// TODO: open emulator shared memory
auto bridge = amdgpu::bridge::createShmCommandBuffer(cmdBridgeName);
auto bridge = amdgpu::bridge::openShmCommandBuffer(cmdBridgeName);
if (bridge == nullptr) {
bridge = amdgpu::bridge::createShmCommandBuffer(cmdBridgeName);
}
if (bridge->pullerPid > 0 && ::kill(bridge->pullerPid, 0) == 0) {
// another instance of rpcsx-gpu on the same bridge, kill self after that
std::fprintf(stderr, "Another instance already exists\n");
return 1;
}
bridge->pullerPid = ::getpid();
amdgpu::bridge::BridgePuller bridgePuller { bridge };
amdgpu::bridge::Command commandsBuffer[32];
amdgpu::device::DrawContext dc{
// TODO
int memoryFd = ::shm_open(shmName, O_RDWR, S_IRUSR | S_IWUSR);
if (memoryFd < 0) {
std::printf("failed to open shared memory\n");
}
struct stat memoryStat;
::fstat(memoryFd, &memoryStat);
amdgpu::RemoteMemory memory {
(char *)::mmap(nullptr, memoryStat.st_size, PROT_NONE, MAP_SHARED, memoryFd, 0)
};
VkCommandPoolCreateInfo commandPoolCreateInfo = {
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.queueFamilyIndex = graphicsQueues.front().second
};
VkCommandPool commandPool;
Verify() << vkCreateCommandPool(vkDevice, &commandPoolCreateInfo, nullptr, &commandPool);
VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
};
VkPipelineCache pipelineCache;
Verify() << vkCreatePipelineCache(vkDevice, &pipelineCacheCreateInfo, nullptr, &pipelineCache);
amdgpu::device::DrawContext dc{ // TODO
.pipelineCache = pipelineCache,
.queue = graphicsQueues.front().first,
.commandPool = commandPool,
};
amdgpu::device::AmdgpuDevice device{ dc };
@ -484,11 +536,31 @@ int main(int argc, const char *argv[]) {
continue;
}
for (std::size_t i = 0; i < pulledCount; ++i) {
// TODO: handle command
for (auto cmd : std::span(commandsBuffer, pulledCount)) {
switch (cmd.id) {
case amdgpu::bridge::CommandId::SetUpSharedMemory:
break;
case amdgpu::bridge::CommandId::ProtectMemory:
break;
case amdgpu::bridge::CommandId::CommandBuffer:
break;
case amdgpu::bridge::CommandId::Flip:
break;
case amdgpu::bridge::CommandId::DoFlip:
break;
case amdgpu::bridge::CommandId::SetBuffer:
break;
default:
util::unreachable("Unexpected command id %u\n", (unsigned)cmd.id);
}
}
}
if (bridge->pusherPid > 0) {
kill(bridge->pusherPid, SIGINT);
}
amdgpu::bridge::destroyShmCommandBuffer(bridge);
amdgpu::bridge::unlinkShm(cmdBridgeName);
return 0;

View file

@ -20,6 +20,7 @@ add_executable(rpcsx-os
iodev/zero.cpp
main.cpp
bridge.cpp
vm.cpp
ops.cpp
linker.cpp
@ -27,7 +28,7 @@ add_executable(rpcsx-os
vfs.cpp
)
target_include_directories(rpcsx-os PUBLIC .)
target_link_libraries(rpcsx-os PUBLIC orbis::kernel libcrypto unwind unwind-x86_64)
target_link_libraries(rpcsx-os PUBLIC orbis::kernel amdgpu::bridge libcrypto unwind unwind-x86_64)
target_link_options(rpcsx-os PUBLIC "LINKER:-Ttext-segment,0x0000010000000000")
target_compile_options(rpcsx-os PRIVATE "-march=native")

4
rpcsx-os/bridge.cpp Normal file
View file

@ -0,0 +1,4 @@
#include "bridge.hpp"
amdgpu::bridge::BridgePusher rx::bridge;

7
rpcsx-os/bridge.hpp Normal file
View file

@ -0,0 +1,7 @@
#pragma once
#include <amdgpu/bridge/bridge.hpp>
namespace rx {
extern amdgpu::bridge::BridgePusher bridge;
}

View file

@ -1,3 +1,4 @@
#include "bridge.hpp"
#include "io-device.hpp"
#include <cinttypes>
#include <cstddef>
@ -15,54 +16,8 @@ struct VideoOutBuffer {
struct DceDevice : public IoDevice {};
// template <typename T>
// inline bool
// atomic_compare_exchange_weak(volatile T *ptr, T *expected, T desired,
// int successMemOrder = __ATOMIC_SEQ_CST,
// int failureMemOrder = __ATOMIC_SEQ_CST) {
// return __atomic_compare_exchange_n(ptr, expected, desired, true,
// __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
// }
struct DceInstance : public IoDeviceInstance {
VideoOutBuffer bufferAttributes{};
// std::uint64_t flipStatusOffset =
// mem::allocateInternal(sizeof(liverpool::bridge::FlipStatus),
// alignof(liverpool::bridge::FlipStatus));
// liverpool::bridge::FlipStatus *flipStatus = new (
// mem::mapInternal(flipStatusOffset, sizeof(liverpool::bridge::FlipStatus)))
// liverpool::bridge::FlipStatus();
DceInstance() {
// *flipStatus = {};
// orbis::bridge.sendSetFlipStatus(flipStatusOffset);
}
void registerBuffer(int index, std::uint64_t address) {
// orbis::bridge.sendSetBuffer(index, address, bufferAttributes.width,
// bufferAttributes.height, bufferAttributes.pitch,
// bufferAttributes.pixelFormat,
// bufferAttributes.tilingMode);
}
void flip(std::uint32_t bufferIndex, std::uint64_t flipMode,
std::uint64_t flipArg) {
// orbis::bridge.sendFlip(bufferIndex, flipArg);
// orbis::bridge.wait();
}
// liverpool::bridge::FlipStatus getFlipStatus() {
// int expected = 0;
// while (!atomic_compare_exchange_weak(&flipStatus->locked, &expected, 1)) {
// expected = 0;
// }
// liverpool::bridge::FlipStatus result = *flipStatus;
// flipStatus->locked = 0;
// return result;
// }
};
struct RegisterBuffer {
@ -149,14 +104,13 @@ static std::int64_t dce_instance_ioctl(IoDeviceInstance *instance,
return 0;
}
// auto currentStatus = dceInstance->getFlipStatus();
FlipControlStatus flipStatus{};
// flipStatus.flipArg = currentStatus.arg;
// flipStatus.count = currentStatus.count;
// TODO: lock bridge header
flipStatus.flipArg = rx::bridge.header->flipArg;
flipStatus.count = rx::bridge.header->flipCount;
flipStatus.processTime = 0; // TODO
flipStatus.tsc = 0; // TODO
// flipStatus.currentBuffer = currentStatus.currentBuffer;
flipStatus.currentBuffer = rx::bridge.header->flipBuffer;
flipStatus.unkQueueNum = 0; // TODO
flipStatus.gcQueueNum = 0; // TODO
flipStatus.unk2QueueNum = 0; // TODO
@ -196,7 +150,22 @@ static std::int64_t dce_instance_ioctl(IoDeviceInstance *instance,
std::fprintf(stderr, "dce: RegisterBuffer(%lx, %lx, %lx, %lx)\n",
args->attributeIndex, args->index, args->address, args->unk);
dceInstance->registerBuffer(args->index, args->address);
if (args->index >= std::size(rx::bridge.header->buffers)) {
// TODO
std::fprintf(stderr, "dce: out of buffers!\n");
return -1;
}
// TODO: lock bridge header
rx::bridge.header->buffers[args->index] = {
.bufferIndex = static_cast<uint32_t>(args->index),
.width = dceInstance->bufferAttributes.width,
.height = dceInstance->bufferAttributes.height,
.pitch = dceInstance->bufferAttributes.pitch,
.pixelFormat = dceInstance->bufferAttributes.pixelFormat,
.tilingMode = dceInstance->bufferAttributes.tilingMode
};
return 0;
}
@ -235,7 +204,7 @@ static std::int64_t dce_instance_ioctl(IoDeviceInstance *instance,
args->arg1, args->displayBufferIndex, args->flipMode, args->flipArg,
args->arg5, args->arg6, args->arg7, args->arg8);
dceInstance->flip(args->displayBufferIndex, args->flipMode, args->flipArg);
rx::bridge.sendFlip(args->displayBufferIndex, /*args->flipMode,*/ args->flipArg);
if (args->flipMode == 1 || args->arg7 == 0) {
// orbis::bridge.sendDoFlip();

View file

@ -1,3 +1,4 @@
#include "bridge.hpp"
#include "io-device.hpp"
#include <atomic>
#include <cinttypes>
@ -58,7 +59,7 @@ static std::int64_t gc_instance_ioctl(IoDeviceInstance *instance,
std::fprintf(stderr, " unkPreservedVal = %lx\n", unkPreservedVal);
std::fprintf(stderr, " size = %lu\n", size);
// orbis::bridge.sendCommandBuffer(address, size);
rx::bridge.sendCommandBuffer(cmdId, address, size);
}
break;
@ -108,7 +109,7 @@ static std::int64_t gc_instance_ioctl(IoDeviceInstance *instance,
std::fprintf(stderr, " unkPreservedVal = %lx\n", unkPreservedVal);
std::fprintf(stderr, " size = %lu\n", size);
// orbis::bridge.sendCommandBuffer(address, size);
rx::bridge.sendCommandBuffer(cmdId, address, size);
}
//orbis::bridge.sendDoFlip();

View file

@ -1,4 +1,6 @@
#include "align.hpp"
#include "amdgpu/bridge/bridge.hpp"
#include "bridge.hpp"
#include "io-device.hpp"
#include "io-devices.hpp"
#include "linker.hpp"
@ -6,6 +8,8 @@
#include "vfs.hpp"
#include "vm.hpp"
#include <filesystem>
#include <linux/limits.h>
#include <orbis/KernelContext.hpp>
#include <orbis/module.hpp>
#include <orbis/module/Module.hpp>
@ -27,6 +31,8 @@
#include <cstddef>
#include <cstdint>
static int g_gpuPid;
struct LibcInfo {
std::uint64_t textBegin = ~static_cast<std::uint64_t>(0);
std::uint64_t textSize = 0;
@ -159,7 +165,9 @@ static void printStackTrace(ucontext_t *context, orbis::Thread *thread,
__attribute__((no_stack_protector)) static void
handle_signal(int sig, siginfo_t *info, void *ucontext) {
std::uint64_t hostFs = _readgsbase_u64();
_writefsbase_u64(hostFs);
if (hostFs != 0) {
_writefsbase_u64(hostFs);
}
// syscall(SYS_arch_prctl, ARCH_GET_GS, &hostFs);
// syscall(SYS_arch_prctl, ARCH_SET_FS, hostFs);
@ -173,20 +181,32 @@ handle_signal(int sig, siginfo_t *info, void *ucontext) {
return;
}
const char message[] = "Signal handler!\n";
write(2, message, sizeof(message) - 1);
if (g_gpuPid > 0) {
// stop gpu thread
::kill(g_gpuPid, SIGINT);
}
char buf[128] = "";
int len = snprintf(buf, sizeof(buf), " [%s] %u: Signal address=%p\n",
g_currentThread ? "guest" : "host",
g_currentThread ? g_currentThread->tid : ::gettid(),
info->si_addr);
write(2, buf, len);
if (sig != SIGINT) {
char buf[128] = "";
int len = snprintf(buf, sizeof(buf), " [%s] %u: Signal address=%p\n",
g_currentThread ? "guest" : "host",
g_currentThread ? g_currentThread->tid : ::gettid(),
info->si_addr);
write(2, buf, len);
if (std::size_t printed = printAddressLocation(
buf, sizeof(buf), g_currentThread, (std::uint64_t)info->si_addr)) {
printed += std::snprintf(buf + printed, sizeof(buf) - printed, "\n");
write(2, buf, printed);
if (std::size_t printed = printAddressLocation(
buf, sizeof(buf), g_currentThread, (std::uint64_t)info->si_addr)) {
printed += std::snprintf(buf + printed, sizeof(buf) - printed, "\n");
write(2, buf, printed);
}
if (g_currentThread) {
printStackTrace(reinterpret_cast<ucontext_t *>(ucontext), g_currentThread,
2);
} else {
printStackTrace(reinterpret_cast<ucontext_t *>(ucontext), 2);
}
}
struct sigaction act {};
@ -202,11 +222,8 @@ handle_signal(int sig, siginfo_t *info, void *ucontext) {
std::exit(-1);
}
if (g_currentThread) {
printStackTrace(reinterpret_cast<ucontext_t *>(ucontext), g_currentThread,
2);
} else {
printStackTrace(reinterpret_cast<ucontext_t *>(ucontext), 2);
if (sig == SIGINT) {
std::raise(SIGINT);
}
}
@ -260,6 +277,11 @@ static void setupSigHandlers() {
perror("Error sigaction:");
exit(-1);
}
if (sigaction(SIGINT, &act, NULL)) {
perror("Error sigaction:");
exit(-1);
}
}
__attribute__((no_stack_protector)) static void *
@ -515,6 +537,72 @@ static void usage(const char *argv0) {
std::printf(" --trace\n");
}
static std::filesystem::path getSelfDir() {
char path[PATH_MAX];
int len = ::readlink("/proc/self/exe", path, sizeof(path));
if (len < 0 || len >= sizeof(path)) {
// TODO
return std::filesystem::current_path();
}
return std::filesystem::path(path).parent_path();
}
static bool isRpsxGpuPid(int pid) {
if (pid <= 0 || ::kill(pid, 0) != 0) {
return false;
}
char path[PATH_MAX];
std::string procPath = "/proc/" + std::to_string(pid) + "/exe";
auto len = ::readlink(procPath.c_str(), path, sizeof(path));
if (len < 0 || len >= std::size(path)) {
return false;
}
path[len] = 0;
std::printf("filename is '%s'\n", std::filesystem::path(path).filename().c_str());
return std::filesystem::path(path).filename() == "rpcsx-gpu";
}
static void runRpsxGpu() {
const char *cmdBufferName = "/rpcsx-gpu-cmds";
amdgpu::bridge::BridgeHeader *bridgeHeader = amdgpu::bridge::openShmCommandBuffer(cmdBufferName);
if (bridgeHeader != nullptr && bridgeHeader->pullerPid > 0 && isRpsxGpuPid(bridgeHeader->pullerPid)) {
bridgeHeader->pusherPid = ::getpid();
g_gpuPid = bridgeHeader->pullerPid;
rx::bridge = bridgeHeader;
return;
}
std::printf("Starting rpcsx-gpu\n");
if (bridgeHeader == nullptr) {
bridgeHeader = amdgpu::bridge::createShmCommandBuffer(cmdBufferName);
}
bridgeHeader->pusherPid = ::getpid();
rx::bridge = bridgeHeader;
auto rpcsxGpuPath = getSelfDir() / "rpcsx-gpu";
if (!std::filesystem::is_regular_file(rpcsxGpuPath)) {
std::printf("failed to find rpcsx-gpu, continue without GPU emulation\n");
return;
}
g_gpuPid = ::fork();
if (g_gpuPid == 0) {
// TODO
const char *argv[] = {rpcsxGpuPath.c_str(), nullptr};
::execv(rpcsxGpuPath.c_str(), const_cast<char **>(argv));
}
}
int main(int argc, const char *argv[]) {
if (argc == 2) {
if (std::strcmp(argv[1], "-h") == 0 ||
@ -606,6 +694,8 @@ int main(int argc, const char *argv[]) {
}
rx::vm::initialize();
runRpsxGpu();
// rx::vm::printHostStats();
auto initProcess = context.createProcess(10);
initProcess->sysent = &orbis::ps4_sysvec;

View file

@ -1,5 +1,6 @@
#include "vm.hpp"
#include "align.hpp"
#include "bridge.hpp"
#include <bit>
#include <cassert>
#include <cinttypes>
@ -596,15 +597,15 @@ static void reserve(std::uint64_t startAddress, std::uint64_t endAddress) {
void rx::vm::initialize() {
std::printf("Memory: initialization\n");
gMemoryShm = ::shm_open("/orbis-memory", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
gMemoryShm = ::shm_open("/rpcsx-os-memory", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (gMemoryShm == -1) {
std::printf("Memory: failed to open /orbis-memory\n");
std::printf("Memory: failed to open /rpcsx-os-memory\n");
std::abort();
}
if (::ftruncate64(gMemoryShm, kMemorySize) < 0) {
std::printf("Memory: failed to allocate /orbis-memory\n");
std::printf("Memory: failed to allocate /rpcsx-os-memory\n");
std::abort();
}
@ -798,7 +799,6 @@ void *rx::vm::map(void *addr, std::uint64_t len, std::int32_t prot,
allocInfo.flags = kBlockFlagDirectMemory; // TODO
allocInfo.name[0] = '\0'; // TODO
// orbis::bridge.sendMemoryProtect(address, len, prot);
auto result =
utils::map(reinterpret_cast<void *>(address), len, prot & kMapProtCpuAll,
realFlags, gMemoryShm, address - kMinAddress);
@ -814,6 +814,7 @@ void *rx::vm::map(void *addr, std::uint64_t len, std::int32_t prot,
}
}
rx::bridge.sendMemoryProtect(address, len, prot);
return result;
}
@ -841,7 +842,7 @@ bool rx::vm::unmap(void *addr, std::uint64_t size) {
gBlocks[(address >> kBlockShift) - kFirstBlock].removeFlags(
(address & kBlockMask) >> kPageShift, pages, ~0);
// orbis::bridge.sendMemoryProtect(address, size, 0);
rx::bridge.sendMemoryProtect(reinterpret_cast<std::uint64_t>(addr), size, 0);
return utils::unmap(addr, size);
}
@ -871,8 +872,7 @@ bool rx::vm::protect(void *addr, std::uint64_t size, std::int32_t prot) {
(address & kBlockMask) >> kPageShift, pages,
kAllocated | (prot & (kMapProtCpuAll | kMapProtGpuAll)));
// orbis::bridge.sendMemoryProtect(reinterpret_cast<std::uint64_t>(addr),
// size, prot);
rx::bridge.sendMemoryProtect(reinterpret_cast<std::uint64_t>(addr), size, prot);
return ::mprotect(addr, size, prot & kMapProtCpuAll) == 0;
}