mirror of
https://github.com/RPCSX/rpcsx.git
synced 2024-11-26 21:00:35 +00:00
ipmi: fix dead lock on connection error
improved ipmi client simulators
This commit is contained in:
parent
2bf0824a5c
commit
c19c70eb77
@ -330,6 +330,7 @@ orbis::SysResult orbis::sysIpmiSendConnectResult(Thread *thread,
|
||||
std::lock_guard lock(client->mutex);
|
||||
client->connectionStatus = status;
|
||||
client->connectCv.notify_all(client->mutex);
|
||||
client->sessionCv.notify_all(client->mutex);
|
||||
return uwrite(result, 0u);
|
||||
}
|
||||
orbis::SysResult orbis::sysIpmiSessionRespondSync(Thread *thread,
|
||||
@ -386,12 +387,6 @@ orbis::SysResult orbis::sysIpmiSessionRespondSync(Thread *thread,
|
||||
if (_params.errorCode != 0) {
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, session->client->name, _params.errorCode);
|
||||
thread->where();
|
||||
|
||||
// HACK: completely broken audio support should not be visible
|
||||
if (session->client->name == "SceSysAudioSystemIpc" &&
|
||||
_params.errorCode == -1) {
|
||||
_params.errorCode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
session->syncResponses.push_front({
|
||||
@ -990,10 +985,6 @@ orbis::sysIpmiClientInvokeSyncMethod(Thread *thread, ptr<uint> result, uint kid,
|
||||
}
|
||||
}
|
||||
|
||||
if (response.errorCode != 0) {
|
||||
thread->where();
|
||||
}
|
||||
|
||||
ORBIS_RET_ON_ERROR(uwrite(_params.pResult, response.errorCode));
|
||||
|
||||
if (response.data.size() != _params.numOutData) {
|
||||
@ -1019,8 +1010,9 @@ orbis::sysIpmiClientInvokeSyncMethod(Thread *thread, ptr<uint> result, uint kid,
|
||||
continue;
|
||||
}
|
||||
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, i, _outData.data, _outData.capacity,
|
||||
data.size());
|
||||
// ORBIS_LOG_ERROR(__FUNCTION__, server->name, i, _outData.data,
|
||||
// _outData.capacity,
|
||||
// data.size());
|
||||
|
||||
_outData.size = data.size();
|
||||
ORBIS_RET_ON_ERROR(uwriteRaw(_outData.data, data.data(), data.size()));
|
||||
@ -1138,7 +1130,7 @@ orbis::SysResult orbis::sysIpmiClientConnect(Thread *thread, ptr<uint> result,
|
||||
server->receiveCv.notify_one(server->mutex);
|
||||
}
|
||||
|
||||
while (client->session == nullptr) {
|
||||
while (client->session == nullptr && !client->connectionStatus) {
|
||||
client->sessionCv.wait(client->mutex);
|
||||
}
|
||||
|
||||
|
198
rpcsx/ipmi.cpp
198
rpcsx/ipmi.cpp
@ -584,9 +584,9 @@ void ipmi::createShellCoreObjects(orbis::Process *process) {
|
||||
}
|
||||
|
||||
*(SceLncServiceAppStatus *)out = {
|
||||
.unk0 = 1,
|
||||
.unk1 = 1,
|
||||
.unk2 = 1,
|
||||
.unk0 = 1u,
|
||||
.unk1 = 0u,
|
||||
.unk2 = 5u,
|
||||
};
|
||||
|
||||
size = sizeof(SceLncServiceAppStatus);
|
||||
@ -685,7 +685,10 @@ void ipmi::createShellCoreObjects(orbis::Process *process) {
|
||||
});
|
||||
createIpmiServer(process, "SceAppMessaging");
|
||||
createIpmiServer(process, "SceShellCoreUtil");
|
||||
createIpmiServer(process, "SceNetCtl");
|
||||
createIpmiServer(process, "SceNetCtl")
|
||||
.addSyncMethod(0x20004, [](void *out, std::uint64_t &size) {
|
||||
return 0x8002'0000 + static_cast<int>(orbis::ErrorCode::AUTH);
|
||||
});
|
||||
createIpmiServer(process, "SceNpMgrIpc")
|
||||
.addSyncMethod(
|
||||
0,
|
||||
@ -825,26 +828,157 @@ void ipmi::createShellCoreObjects(orbis::Process *process) {
|
||||
})
|
||||
.addSyncMethod(
|
||||
0x12340001,
|
||||
[](void *out, std::uint64_t &size) -> std::int32_t {
|
||||
{
|
||||
auto [dev, devPath] = vfs::get("/app0");
|
||||
if (auto hostFs = dev.cast<HostFsDevice>()) {
|
||||
std::error_code ec;
|
||||
auto saveDir = hostFs->hostPath + "/.rpcsx/savedata/";
|
||||
if (!std::filesystem::exists(saveDir)) {
|
||||
return 0x8002'0000 +
|
||||
static_cast<int>(orbis::ErrorCode::NOENT);
|
||||
[](std::vector<std::vector<std::byte>> &outData,
|
||||
const std::vector<std::span<std::byte>> &inData) -> std::int32_t {
|
||||
std::println(stderr, "SceSaveData: 0x12340001");
|
||||
if (inData.size() != 2 || outData.size() != 2) {
|
||||
return 0x8002000 +
|
||||
static_cast<std::uint32_t>(orbis::ErrorCode::INVAL);
|
||||
}
|
||||
if (inData[0].size() != sizeof(orbis::uint64_t) ||
|
||||
outData[1].size() != sizeof(orbis::uint64_t)) {
|
||||
return 0x8002000 +
|
||||
static_cast<std::uint32_t>(orbis::ErrorCode::INVAL);
|
||||
}
|
||||
|
||||
auto outputLen =
|
||||
*reinterpret_cast<orbis::uint64_t *>(inData[0].data());
|
||||
|
||||
if (outputLen != outData[0].size()) {
|
||||
return 0x8002000 +
|
||||
static_cast<std::uint32_t>(orbis::ErrorCode::INVAL);
|
||||
}
|
||||
|
||||
struct Request {
|
||||
orbis::uint32_t unk0;
|
||||
orbis::uint32_t id;
|
||||
orbis::uint32_t unk1[31];
|
||||
};
|
||||
|
||||
static_assert(sizeof(Request) == 132);
|
||||
|
||||
if (inData[1].size() != sizeof(Request)) {
|
||||
return 0x8002000 +
|
||||
static_cast<std::uint32_t>(orbis::ErrorCode::INVAL);
|
||||
}
|
||||
|
||||
auto request = reinterpret_cast<Request *>(inData[1].data());
|
||||
|
||||
std::println(stderr, "SceSaveData: 0x12340001, message {}",
|
||||
request->id);
|
||||
|
||||
for (std::size_t index = 0; auto &in : inData) {
|
||||
std::println(stderr, "in {} - {}", index++, in.size());
|
||||
rx::hexdump(in);
|
||||
}
|
||||
|
||||
for (std::size_t index = 0; auto &out : outData) {
|
||||
std::println(stderr, "out {} - {}", index++, out.size());
|
||||
}
|
||||
|
||||
if (request->id == 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (request->id == 3) {
|
||||
struct MountInfo {
|
||||
std::uint64_t blocks;
|
||||
std::uint64_t freeBlocks;
|
||||
};
|
||||
|
||||
std::memset(outData[0].data(), 0xff, outData[0].size());
|
||||
|
||||
auto info = (MountInfo *)outData[0].data();
|
||||
info->blocks = 1024 * 32;
|
||||
info->freeBlocks = 1024 * 16;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (request->id == 4) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (request->id == 6) {
|
||||
struct Entry {
|
||||
char string[32];
|
||||
};
|
||||
|
||||
struct SearchResults {
|
||||
std::uint32_t totalCount;
|
||||
std::uint32_t count;
|
||||
Entry entries[];
|
||||
};
|
||||
|
||||
std::uint32_t fillOffset = 4 + sizeof(Entry) + 1024;
|
||||
|
||||
std::memset(outData[0].data() + fillOffset, 0xff,
|
||||
outData[0].size() - fillOffset);
|
||||
|
||||
auto results = (SearchResults *)outData[0].data();
|
||||
std::vector<std::string> searchResults;
|
||||
searchResults.emplace_back("TEST");
|
||||
results->totalCount = searchResults.size();
|
||||
|
||||
Entry *entries = results->entries;
|
||||
results->count = searchResults.size();
|
||||
|
||||
for (auto &str : searchResults) {
|
||||
std::strncpy(entries->string, str.data(),
|
||||
sizeof(entries->string));
|
||||
entries->string[std::size(entries->string) - 1] = 0;
|
||||
|
||||
entries++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (request->id == 7) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (request->id == 8) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (request->id == 9) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (request->id == 10) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (request->id == 1 || request->id == 60) {
|
||||
{
|
||||
auto [dev, devPath] = vfs::get("/app0");
|
||||
if (auto hostFs = dev.cast<HostFsDevice>()) {
|
||||
std::error_code ec;
|
||||
auto saveDir = hostFs->hostPath + "/.rpcsx/savedata/";
|
||||
if (!std::filesystem::exists(saveDir)) {
|
||||
return 0x8002'0000 +
|
||||
static_cast<int>(orbis::ErrorCode::NOENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// umount
|
||||
std::string_view result = "/savedata";
|
||||
if (outData[0].size() < result.size() + 1) {
|
||||
return 0x8002'0000 + static_cast<int>(orbis::ErrorCode::INVAL);
|
||||
}
|
||||
std::strncpy((char *)outData[0].data(), result.data(),
|
||||
result.size() + 1);
|
||||
outData[0].resize(result.size() + 1);
|
||||
orbis::g_context.createEventFlag(orbis::kstring(result), 0x200,
|
||||
0);
|
||||
|
||||
outData[1] = toBytes<orbis::uint64_t>(0);
|
||||
return 0;
|
||||
}
|
||||
std::string_view result = "/savedata";
|
||||
if (size < result.size() + 1) {
|
||||
return 0x8002'0000 + static_cast<int>(orbis::ErrorCode::INVAL);
|
||||
}
|
||||
std::strncpy((char *)out, result.data(), result.size() + 1);
|
||||
size = result.size() + 1;
|
||||
orbis::g_context.createEventFlag(orbis::kstring(result), 0x200, 0);
|
||||
return 0;
|
||||
|
||||
return 0x8002000 +
|
||||
static_cast<std::uint32_t>(orbis::ErrorCode::INVAL);
|
||||
})
|
||||
.addSyncMethod(0x12340002, [](void *, std::uint64_t &) -> std::int32_t {
|
||||
{
|
||||
@ -878,7 +1012,27 @@ void ipmi::createShellCoreObjects(orbis::Process *process) {
|
||||
createIpmiServer(process, "SceScreenShot");
|
||||
createIpmiServer(process, "SceAppDbIpc");
|
||||
createIpmiServer(process, "SceAppInst");
|
||||
createIpmiServer(process, "SceAppContent");
|
||||
createIpmiServer(process, "SceAppContent")
|
||||
.addSyncMethod<orbis::uint32_t, orbis::uint32_t>(
|
||||
0x20001,
|
||||
[](orbis::uint32_t &out, orbis::uint32_t param) -> std::int32_t {
|
||||
switch (param) {
|
||||
case 0: // sku
|
||||
out = 3;
|
||||
return 0;
|
||||
|
||||
case 1: // user defined param 0
|
||||
case 2: // user defined param 1
|
||||
case 3: // user defined param 2
|
||||
case 4: // user defined param 3
|
||||
ORBIS_LOG_ERROR("SceAppContent: get user defined param");
|
||||
out = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0x8002000 + static_cast<std::uint32_t>(orbis::ErrorCode::INVAL);
|
||||
});
|
||||
|
||||
createIpmiServer(process, "SceNpEntAccess");
|
||||
createIpmiServer(process, "SceMwIPMIServer");
|
||||
createIpmiServer(process, "SceAutoMounterIpc");
|
||||
|
Loading…
Reference in New Issue
Block a user