Skip to content

Commit

Permalink
[rpcsx-os] implement fw simulation
Browse files Browse the repository at this point in the history
implement impi messages
  • Loading branch information
DHrpcs3 committed Dec 27, 2023
1 parent 2278a29 commit 6ba0ad0
Show file tree
Hide file tree
Showing 8 changed files with 516 additions and 153 deletions.
9 changes: 5 additions & 4 deletions hw/amdgpu/bridge/include/amdgpu/bridge/bridge.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#pragma once

#include "orbis/utils/SharedMutex.hpp"
#include <atomic>
#include <cstdint>
#include <cstring>
#include <initializer_list>
#include <orbis/utils/SharedCV.hpp>

namespace amdgpu::bridge {
extern std::uint32_t expGpuPid;

struct PadState {
std::uint64_t timestamp;
std::uint32_t unk;
Expand Down Expand Up @@ -149,21 +150,21 @@ struct BridgePusher {

void sendMemoryProtect(std::uint32_t pid, std::uint64_t address,
std::uint64_t size, std::uint32_t prot) {
if (pid == 50001) {
if (pid == expGpuPid) {
sendCommand(CommandId::ProtectMemory, {pid, address, size, prot});
}
}

void sendCommandBuffer(std::uint32_t pid, std::uint64_t queue,
std::uint64_t address, std::uint64_t size) {
if (pid == 50001) {
if (pid == expGpuPid) {
sendCommand(CommandId::CommandBuffer, {pid, queue, address, size});
}
}

void sendFlip(std::uint32_t pid, std::uint32_t bufferIndex,
std::uint64_t arg) {
if (pid == 50001) {
if (pid == expGpuPid) {
sendCommand(CommandId::Flip, {pid, bufferIndex, arg});
}
}
Expand Down
2 changes: 2 additions & 0 deletions hw/amdgpu/bridge/src/bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
static int gShmFd = -1;
static constexpr std::size_t kShmSize = sizeof(amdgpu::bridge::BridgeHeader) +
(sizeof(std::uint64_t) * (1024 * 1024));
std::uint32_t amdgpu::bridge::expGpuPid = 0;

amdgpu::bridge::BridgeHeader *
amdgpu::bridge::createShmCommandBuffer(const char *name) {
if (gShmFd != -1) {
Expand Down
9 changes: 6 additions & 3 deletions orbis-kernel/include/orbis/ipmi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ struct IpmiClient : RcBase {
shared_mutex mutex;
shared_cv sessionCv;
sint pid;
kdeque<kvector<std::byte>> messages;
shared_cv messageCv;

explicit IpmiClient(kstring name) : name(std::move(name)) {}
};
Expand Down Expand Up @@ -150,6 +152,8 @@ SysResult sysIpmiSendConnectResult(Thread *thread, ptr<uint> result, uint kid,
ptr<void> params, uint64_t paramsSz);
SysResult sysIpmiSessionRespondSync(Thread *thread, ptr<uint> result, uint kid,
ptr<void> params, uint64_t paramsSz);
SysResult sysIpmiClientTryGetMessage(Thread *thread, ptr<uint> result, uint kid,
ptr<void> params, uint64_t paramsSz);
SysResult sysIpmiSessionGetClientPid(Thread *thread, ptr<uint> result, uint kid,
ptr<void> params, uint64_t paramsSz);
SysResult sysIpmiClientInvokeSyncMethod(Thread *thread, ptr<uint> result,
Expand All @@ -161,9 +165,8 @@ SysResult sysIpmiSessionGetUserData(Thread *thread, ptr<uint> result, uint kid,
ptr<void> params, uint64_t paramsSz);
SysResult sysIpmiServerGetName(Thread *thread, ptr<uint> result, uint kid,
ptr<void> params, uint64_t paramsSz);
SysResult sysIpmiClientPollEventFlag(Thread *thread, ptr<uint> result,
uint kid, ptr<void> params,
uint64_t paramsSz);
SysResult sysIpmiClientPollEventFlag(Thread *thread, ptr<uint> result, uint kid,
ptr<void> params, uint64_t paramsSz);
SysResult sysIpmiSessionWaitEventFlag(Thread *thread, ptr<uint> result,
uint kid, ptr<void> params,
uint64_t paramsSz);
Expand Down
48 changes: 48 additions & 0 deletions orbis-kernel/src/ipmi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,54 @@ orbis::SysResult orbis::sysIpmiSessionRespondSync(Thread *thread,
return uwrite(result, 0u);
}

orbis::SysResult orbis::sysIpmiClientTryGetMessage(Thread *thread,
ptr<uint> result, uint kid,
ptr<void> params,
uint64_t paramsSz) {
struct SceIpmiClientTryGetArgs {
uint32_t unk; // 0
uint32_t padding;
ptr<std::byte> message;
ptr<uint64_t> pSize;
uint64_t maxSize;
};

static_assert(sizeof(SceIpmiClientTryGetArgs) == 0x20);

if (paramsSz != sizeof(SceIpmiClientTryGetArgs)) {
return ErrorCode::INVAL;
}

auto client = thread->tproc->ipmiMap.get(kid).cast<IpmiClient>();

if (client == nullptr) {
return ErrorCode::INVAL;
}

SceIpmiClientTryGetArgs _params;
ORBIS_RET_ON_ERROR(uread(_params, ptr<SceIpmiClientTryGetArgs>(params)));

std::lock_guard lock(client->mutex);
if (client->messages.empty()) {
return uwrite<uint>(result,
0x80020000 + static_cast<int>(ErrorCode::AGAIN));
}

auto &message = client->messages.front();

if (_params.maxSize < message.size()) {
ORBIS_LOG_ERROR(__FUNCTION__, "too small buffer");
return uwrite<uint>(result,
0x80020000 + static_cast<int>(ErrorCode::INVAL));
}

ORBIS_RET_ON_ERROR(uwrite(_params.pSize, message.size()));
ORBIS_RET_ON_ERROR(
uwriteRaw(_params.message, message.data(), message.size()));
client->messages.pop_front();
return uwrite<uint>(result, 0);
}

orbis::SysResult orbis::sysIpmiSessionGetClientPid(Thread *thread,
ptr<uint> result, uint kid,
ptr<void> params,
Expand Down
50 changes: 25 additions & 25 deletions orbis-kernel/src/sys/sys_sce.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -950,25 +950,26 @@ orbis::SysResult orbis::sys_get_self_auth_info(Thread *thread,
ORBIS_LOG_ERROR(__FUNCTION__, path, result);
thread->where();

return uwrite(
result, {
.unk0 = 0x3100000000000001,
.caps =
{
~0ull, ~0ull, ~0ull, ~0ull,
// 0x2000038000000000,
// 0x000000000000FF00,
// 0x0000000000000000,
// 0x0000000000000000,
},
.attrs =
{
0x4000400040000000,
0x4000000000000000,
0x0080000000000004, // lower byte is application type
0xF0000000FFFF4000,
},
});
char _path[512];
ORBIS_RET_ON_ERROR(ureadString(_path, sizeof(_path), path));

struct Result {
std::uint64_t authorityId;
std::uint64_t programType;
std::uint64_t programVersion;
std::uint64_t systemVersion;
char contentId[32];
char hash[32];
};

Result _result{};
_result.authorityId = 0x1000;
_result.programType = 1;
_result.programVersion = 1;
_result.systemVersion = 1;
_result.contentId[24] = 4;

return uwrite((ptr<Result>)result, _result);

return {};
}
Expand Down Expand Up @@ -1095,8 +1096,7 @@ orbis::SysResult orbis::sys_ipmimgr_call(Thread *thread, uint op, uint kid,
case 0x232:
return sysIpmiSessionRespondSync(thread, result, kid, params, paramsSz);
case 0x252:
// TODO: try get message
return uwrite<uint>(result, 0x80020023);
return sysIpmiClientTryGetMessage(thread, result, kid, params, paramsSz);
case 0x302:
return sysIpmiSessionGetClientPid(thread, result, kid, params, paramsSz);
case 0x320:
Expand Down Expand Up @@ -1225,8 +1225,8 @@ orbis::SysResult
orbis::sys_get_kernel_mem_statistics(Thread *thread /* TODO */) {
return ErrorCode::NOSYS;
}
orbis::SysResult
orbis::sys_get_sdk_compiled_version(Thread *thread, ptr<const char> path) {
orbis::SysResult orbis::sys_get_sdk_compiled_version(Thread *thread,
ptr<const char> path) {
ORBIS_LOG_ERROR(__FUNCTION__, path);
thread->retval[0] = g_context.sdkVersion;
return {};
Expand All @@ -1244,8 +1244,8 @@ orbis::SysResult orbis::sys_dynlib_get_obj_member(Thread *thread,

return ErrorCode::NOSYS;
}
orbis::SysResult
orbis::sys_budget_get_ptype_of_budget(Thread *thread, sint budgetId) {
orbis::SysResult orbis::sys_budget_get_ptype_of_budget(Thread *thread,
sint budgetId) {
ORBIS_LOG_WARNING(__FUNCTION__, budgetId);
thread->retval[0] = budgetId;
return {};
Expand Down
12 changes: 1 addition & 11 deletions rpcsx-gpu/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ int main(int argc, const char *argv[]) {
}

const char *cmdBridgeName = "/rpcsx-gpu-cmds";
const char *shmName = "/rpcsx-os-memory-50001";
const char *shmName = "/rpcsx-os-memory";
unsigned long gpuIndex = 0;
auto presenter = PresenterMode::Window;
bool enableValidation = false;
Expand Down Expand Up @@ -945,25 +945,15 @@ int main(int argc, const char *argv[]) {
for (auto cmd : std::span(commandsBuffer, pulledCount)) {
switch (cmd.id) {
case amdgpu::bridge::CommandId::ProtectMemory:
if (cmd.memoryProt.pid != 50001) {
continue;
}
device.handleProtectMemory(cmd.memoryProt.address,
cmd.memoryProt.size, cmd.memoryProt.prot);
break;
case amdgpu::bridge::CommandId::CommandBuffer:
if (cmd.memoryProt.pid != 50001) {
continue;
}
device.handleCommandBuffer(cmd.commandBuffer.queue,
cmd.commandBuffer.address,
cmd.commandBuffer.size);
break;
case amdgpu::bridge::CommandId::Flip: {
if (cmd.memoryProt.pid != 50001) {
continue;
}

if (!isImageAcquired) {
Verify() << vkAcquireNextImageKHR(vkDevice, swapchain, UINT64_MAX,
presentCompleteSemaphore, nullptr,
Expand Down
Loading

0 comments on commit 6ba0ad0

Please sign in to comment.