[rpcsx-os] implement fw simulation

implement impi messages
This commit is contained in:
DH 2023-12-27 20:07:30 +03:00
parent 2278a298ac
commit 6ba0ad0832
8 changed files with 516 additions and 153 deletions

View file

@ -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)) {}
};
@ -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,
@ -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);

View file

@ -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,

View file

@ -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 {};
}
@ -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:
@ -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 {};
@ -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 {};