mirror of
https://github.com/libretro/Play-.git
synced 2025-03-04 09:17:50 +00:00
Induce a delay in SifBindRpc.
To give some time to the EE to register its RPC server.
This commit is contained in:
parent
54aaa2f3c7
commit
3217abd531
@ -13,7 +13,9 @@ using namespace Iop;
|
||||
|
||||
#define CUSTOM_FINISHEXECREQUEST 0x666
|
||||
#define CUSTOM_FINISHEXECCMD 0x667
|
||||
#define CUSTOM_SLEEPTHREAD 0x668
|
||||
#define CUSTOM_FINISHBINDRPC 0x668
|
||||
#define CUSTOM_SLEEPTHREAD 0x669
|
||||
#define CUSTOM_DELAYTHREAD 0x66A
|
||||
|
||||
#define MODULE_NAME "sifcmd"
|
||||
#define MODULE_VERSION 0x101
|
||||
@ -35,7 +37,9 @@ using namespace Iop;
|
||||
#define FUNCTION_SIFGETOTHERDATA "SifGetOtherData"
|
||||
#define FUNCTION_FINISHEXECREQUEST "FinishExecRequest"
|
||||
#define FUNCTION_FINISHEXECCMD "FinishExecCmd"
|
||||
#define FUNCTION_FINISHBINDRPC "FinishBindRpc"
|
||||
#define FUNCTION_SLEEPTHREAD "SleepThread"
|
||||
#define FUNCTION_DELAYTHREAD "DelayThread"
|
||||
|
||||
#define SYSTEM_COMMAND_ID 0x80000000
|
||||
|
||||
@ -158,9 +162,15 @@ std::string CSifCmd::GetFunctionName(unsigned int functionId) const
|
||||
case CUSTOM_FINISHEXECCMD:
|
||||
return FUNCTION_FINISHEXECCMD;
|
||||
break;
|
||||
case CUSTOM_FINISHBINDRPC:
|
||||
return FUNCTION_FINISHBINDRPC;
|
||||
break;
|
||||
case CUSTOM_SLEEPTHREAD:
|
||||
return FUNCTION_SLEEPTHREAD;
|
||||
break;
|
||||
case CUSTOM_DELAYTHREAD:
|
||||
return FUNCTION_DELAYTHREAD;
|
||||
break;
|
||||
default:
|
||||
return "unknown";
|
||||
break;
|
||||
@ -201,10 +211,7 @@ void CSifCmd::Invoke(CMIPS& context, unsigned int functionId)
|
||||
CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFINITRPC "();\r\n");
|
||||
break;
|
||||
case 15:
|
||||
context.m_State.nGPR[CMIPS::V0].nV0 = SifBindRpc(
|
||||
context.m_State.nGPR[CMIPS::A0].nV0,
|
||||
context.m_State.nGPR[CMIPS::A1].nV0,
|
||||
context.m_State.nGPR[CMIPS::A2].nV0);
|
||||
SifBindRpc(context);
|
||||
break;
|
||||
case 16:
|
||||
SifCallRpc(context);
|
||||
@ -245,12 +252,23 @@ void CSifCmd::Invoke(CMIPS& context, unsigned int functionId)
|
||||
context.m_State.nGPR[CMIPS::A1].nV0
|
||||
);
|
||||
break;
|
||||
case CUSTOM_FINISHBINDRPC:
|
||||
FinishBindRpc(
|
||||
context.m_State.nGPR[CMIPS::A0].nV0,
|
||||
context.m_State.nGPR[CMIPS::A1].nV0
|
||||
);
|
||||
break;
|
||||
case CUSTOM_FINISHEXECCMD:
|
||||
FinishExecCmd();
|
||||
break;
|
||||
case CUSTOM_SLEEPTHREAD:
|
||||
SleepThread();
|
||||
break;
|
||||
case CUSTOM_DELAYTHREAD:
|
||||
DelayThread(
|
||||
context.m_State.nGPR[CMIPS::A0].nV0
|
||||
);
|
||||
break;
|
||||
default:
|
||||
CLog::GetInstance().Print(LOG_NAME, "Unknown function called (%d).\r\n",
|
||||
functionId);
|
||||
@ -299,10 +317,18 @@ void CSifCmd::BuildExportTable()
|
||||
assembler.JR(CMIPS::RA);
|
||||
assembler.ADDIU(CMIPS::R0, CMIPS::R0, CUSTOM_FINISHEXECCMD);
|
||||
|
||||
uint32 finishBindRpcAddr = (reinterpret_cast<uint8*>(exportTable) - m_ram) + (assembler.GetProgramSize() * 4);
|
||||
assembler.JR(CMIPS::RA);
|
||||
assembler.ADDIU(CMIPS::R0, CMIPS::R0, CUSTOM_FINISHBINDRPC);
|
||||
|
||||
uint32 sleepThreadAddr = (reinterpret_cast<uint8*>(exportTable) - m_ram) + (assembler.GetProgramSize() * 4);
|
||||
assembler.JR(CMIPS::RA);
|
||||
assembler.ADDIU(CMIPS::R0, CMIPS::R0, CUSTOM_SLEEPTHREAD);
|
||||
|
||||
uint32 delayThreadAddr = (reinterpret_cast<uint8*>(exportTable) - m_ram) + (assembler.GetProgramSize() * 4);
|
||||
assembler.JR(CMIPS::RA);
|
||||
assembler.ADDIU(CMIPS::R0, CMIPS::R0, CUSTOM_DELAYTHREAD);
|
||||
|
||||
//Assemble SifRpcLoop
|
||||
{
|
||||
static const int16 stackAlloc = 0x10;
|
||||
@ -392,6 +418,37 @@ void CSifCmd::BuildExportTable()
|
||||
assembler.JR(CMIPS::RA);
|
||||
assembler.ADDIU(CMIPS::SP, CMIPS::SP, stackAlloc);
|
||||
}
|
||||
|
||||
//Assemble SifBindRpc
|
||||
{
|
||||
static const int16 stackAlloc = 0x20;
|
||||
|
||||
m_sifBindRpcAddr = (reinterpret_cast<uint8*>(exportTable) - m_ram) + (assembler.GetProgramSize() * 4);
|
||||
|
||||
assembler.ADDIU(CMIPS::SP, CMIPS::SP, -stackAlloc);
|
||||
assembler.SW(CMIPS::RA, 0x1C, CMIPS::SP);
|
||||
assembler.SW(CMIPS::S0, 0x18, CMIPS::SP);
|
||||
assembler.SW(CMIPS::S1, 0x14, CMIPS::SP);
|
||||
assembler.ADDU(CMIPS::S0, CMIPS::A0, CMIPS::R0);
|
||||
assembler.ADDU(CMIPS::S1, CMIPS::A1, CMIPS::R0);
|
||||
|
||||
assembler.LI(CMIPS::A0, 1000);
|
||||
assembler.JAL(delayThreadAddr);
|
||||
assembler.NOP();
|
||||
|
||||
assembler.ADDU(CMIPS::A0, CMIPS::S0, CMIPS::R0);
|
||||
assembler.ADDU(CMIPS::A1, CMIPS::S1, CMIPS::R0);
|
||||
assembler.JAL(finishBindRpcAddr);
|
||||
assembler.NOP();
|
||||
|
||||
assembler.ADDU(CMIPS::V0, CMIPS::R0, CMIPS::R0);
|
||||
|
||||
assembler.LW(CMIPS::S1, 0x14, CMIPS::SP);
|
||||
assembler.LW(CMIPS::S0, 0x18, CMIPS::SP);
|
||||
assembler.LW(CMIPS::RA, 0x1C, CMIPS::SP);
|
||||
assembler.JR(CMIPS::RA);
|
||||
assembler.ADDIU(CMIPS::SP, CMIPS::SP, stackAlloc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -446,6 +503,25 @@ void CSifCmd::FinishExecCmd()
|
||||
}
|
||||
}
|
||||
|
||||
void CSifCmd::FinishBindRpc(uint32 clientDataAddr, uint32 serverId)
|
||||
{
|
||||
auto clientData = reinterpret_cast<SIFRPCCLIENTDATA*>(m_ram + clientDataAddr);
|
||||
clientData->serverDataAddr = serverId;
|
||||
clientData->header.semaId = m_bios.CreateSemaphore(0, 1);
|
||||
|
||||
int32 result = CIopBios::KERNEL_RESULT_OK;
|
||||
result = m_bios.WaitSemaphore(clientData->header.semaId);
|
||||
assert(result == CIopBios::KERNEL_RESULT_OK);
|
||||
|
||||
SIFRPCBIND bindPacket;
|
||||
memset(&bindPacket, 0, sizeof(SIFRPCBIND));
|
||||
bindPacket.header.commandId = SIF_CMD_BIND;
|
||||
bindPacket.header.packetSize = sizeof(SIFRPCBIND);
|
||||
bindPacket.serverId = serverId;
|
||||
bindPacket.clientDataAddr = clientDataAddr;
|
||||
m_sifMan.SendPacket(&bindPacket, sizeof(bindPacket));
|
||||
}
|
||||
|
||||
void CSifCmd::ProcessCustomCommand(uint32 commandHeaderAddr)
|
||||
{
|
||||
auto commandHeader = reinterpret_cast<const SIFCMDHEADER*>(m_ram + commandHeaderAddr);
|
||||
@ -655,30 +731,19 @@ uint32 CSifCmd::SifSendCmd(uint32 commandId, uint32 packetPtr, uint32 packetSize
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32 CSifCmd::SifBindRpc(uint32 clientDataAddr, uint32 serverId, uint32 mode)
|
||||
void CSifCmd::SifBindRpc(CMIPS& context)
|
||||
{
|
||||
uint32 clientDataAddr = context.m_State.nGPR[CMIPS::A0].nV0;
|
||||
uint32 serverId = context.m_State.nGPR[CMIPS::A1].nV0;
|
||||
uint32 mode = context.m_State.nGPR[CMIPS::A2].nV0;
|
||||
|
||||
CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFBINDRPC "(clientDataAddr = 0x%0.8X, serverId = 0x%0.8X, mode = 0x%0.8X);\r\n",
|
||||
clientDataAddr, serverId, mode);
|
||||
|
||||
//Could be in non waiting mode
|
||||
assert(mode == 0);
|
||||
|
||||
auto clientData = reinterpret_cast<SIFRPCCLIENTDATA*>(m_ram + clientDataAddr);
|
||||
clientData->serverDataAddr = serverId;
|
||||
clientData->header.semaId = m_bios.CreateSemaphore(0, 1);
|
||||
int32 result = CIopBios::KERNEL_RESULT_OK;
|
||||
result = m_bios.WaitSemaphore(clientData->header.semaId);
|
||||
assert(result == CIopBios::KERNEL_RESULT_OK);
|
||||
|
||||
SIFRPCBIND bindPacket;
|
||||
memset(&bindPacket, 0, sizeof(SIFRPCBIND));
|
||||
bindPacket.header.commandId = SIF_CMD_BIND;
|
||||
bindPacket.header.packetSize = sizeof(SIFRPCBIND);
|
||||
bindPacket.serverId = serverId;
|
||||
bindPacket.clientDataAddr = clientDataAddr;
|
||||
m_sifMan.SendPacket(&bindPacket, sizeof(bindPacket));
|
||||
|
||||
return 0;
|
||||
context.m_State.nPC = m_sifBindRpcAddr;
|
||||
}
|
||||
|
||||
void CSifCmd::SifCallRpc(CMIPS& context)
|
||||
@ -842,3 +907,8 @@ void CSifCmd::SleepThread()
|
||||
{
|
||||
m_bios.SleepThread();
|
||||
}
|
||||
|
||||
void CSifCmd::DelayThread(uint32 delay)
|
||||
{
|
||||
m_bios.DelayThread(delay);
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ namespace Iop
|
||||
uint32 SifSetCmdBuffer(uint32, uint32);
|
||||
void SifAddCmdHandler(uint32, uint32, uint32);
|
||||
uint32 SifSendCmd(uint32, uint32, uint32, uint32, uint32, uint32);
|
||||
uint32 SifBindRpc(uint32, uint32, uint32);
|
||||
void SifBindRpc(CMIPS&);
|
||||
void SifCallRpc(CMIPS&);
|
||||
void SifRegisterRpc(CMIPS&);
|
||||
uint32 SifCheckStatRpc(uint32);
|
||||
@ -109,7 +109,9 @@ namespace Iop
|
||||
uint32 SifGetOtherData(uint32, uint32, uint32, uint32, uint32);
|
||||
void FinishExecRequest(uint32, uint32);
|
||||
void FinishExecCmd();
|
||||
void FinishBindRpc(uint32, uint32);
|
||||
void SleepThread();
|
||||
void DelayThread(uint32);
|
||||
|
||||
CIopBios& m_bios;
|
||||
CSifMan& m_sifMan;
|
||||
@ -122,6 +124,7 @@ namespace Iop
|
||||
uint32 m_sifRpcLoopAddr = 0;
|
||||
uint32 m_sifExecRequestAddr = 0;
|
||||
uint32 m_sifExecCmdHandlerAddr = 0;
|
||||
uint32 m_sifBindRpcAddr = 0;
|
||||
DynamicModuleList m_servers;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user