1 #include <cstring>
2 #include "Iop_SifCmd.h"
3 #include "IopBios.h"
4 #include "../ee/SIF.h"
5 #include "../Log.h"
6 #include "../states/StructCollectionStateFile.h"
7
8 using namespace Iop;
9
10 #define LOG_NAME ("iop_sifcmd")
11 #define STATE_MODULES ("iop_sifcmd/modules.xml")
12 #define STATE_MODULE ("Module")
13 #define STATE_MODULE_SERVER_DATA_ADDRESS ("ServerDataAddress")
14
15 #define CUSTOM_FINISHEXECREQUEST 0x666
16 #define CUSTOM_FINISHEXECCMD 0x667
17 #define CUSTOM_FINISHBINDRPC 0x668
18 #define CUSTOM_SLEEPTHREAD 0x669
19 #define CUSTOM_DELAYTHREAD 0x66A
20
21 #define MODULE_NAME "sifcmd"
22 #define MODULE_VERSION 0x101
23
24 #define FUNCTION_SIFGETSREG "SifGetSreg"
25 #define FUNCTION_SIFSETCMDBUFFER "SifSetCmdBuffer"
26 #define FUNCTION_SIFADDCMDHANDLER "SifAddCmdHandler"
27 #define FUNCTION_SIFSENDCMD "SifSendCmd"
28 #define FUNCTION_ISIFSENDCMD "iSifSendCmd"
29 #define FUNCTION_SIFINITRPC "SifInitRpc"
30 #define FUNCTION_SIFBINDRPC "SifBindRpc"
31 #define FUNCTION_SIFCALLRPC "SifCallRpc"
32 #define FUNCTION_SIFREGISTERRPC "SifRegisterRpc"
33 #define FUNCTION_SIFCHECKSTATRPC "SifCheckStatRpc"
34 #define FUNCTION_SIFSETRPCQUEUE "SifSetRpcQueue"
35 #define FUNCTION_SIFGETNEXTREQUEST "SifGetNextRequest"
36 #define FUNCTION_SIFEXECREQUEST "SifExecRequest"
37 #define FUNCTION_SIFRPCLOOP "SifRpcLoop"
38 #define FUNCTION_SIFGETOTHERDATA "SifGetOtherData"
39 #define FUNCTION_SIFREMOVERPC "SifRemoveRpc"
40 #define FUNCTION_SIFREMOVERPCQUEUE "SifRemoveRpcQueue"
41 #define FUNCTION_SIFSENDCMDINTR "SifSendCmdIntr"
42 #define FUNCTION_FINISHEXECREQUEST "FinishExecRequest"
43 #define FUNCTION_FINISHEXECCMD "FinishExecCmd"
44 #define FUNCTION_FINISHBINDRPC "FinishBindRpc"
45 #define FUNCTION_SLEEPTHREAD "SleepThread"
46 #define FUNCTION_DELAYTHREAD "DelayThread"
47
48 #define SYSTEM_COMMAND_ID 0x80000000
49
CSifCmd(CIopBios & bios,CSifMan & sifMan,CSysmem & sysMem,uint8 * ram)50 CSifCmd::CSifCmd(CIopBios& bios, CSifMan& sifMan, CSysmem& sysMem, uint8* ram)
51 : m_bios(bios)
52 , m_sifMan(sifMan)
53 , m_sysMem(sysMem)
54 , m_ram(ram)
55 {
56 m_moduleDataAddr = m_sysMem.AllocateMemory(sizeof(MODULEDATA), 0, 0);
57 memset(m_ram + m_moduleDataAddr, 0, sizeof(MODULEDATA));
58 m_trampolineAddr = m_moduleDataAddr + offsetof(MODULEDATA, trampoline);
59 m_sendCmdExtraStructAddr = m_moduleDataAddr + offsetof(MODULEDATA, sendCmdExtraStruct);
60 m_sysCmdBufferAddr = m_moduleDataAddr + offsetof(MODULEDATA, sysCmdBuffer);
61 sifMan.SetModuleResetHandler([&](const std::string& path) { bios.ProcessModuleReset(path); });
62 sifMan.SetCustomCommandHandler([&](uint32 commandHeaderAddr) { ProcessCustomCommand(commandHeaderAddr); });
63 BuildExportTable();
64 }
65
~CSifCmd()66 CSifCmd::~CSifCmd()
67 {
68 ClearServers();
69 }
70
LoadState(Framework::CZipArchiveReader & archive)71 void CSifCmd::LoadState(Framework::CZipArchiveReader& archive)
72 {
73 ClearServers();
74
75 auto modulesFile = CStructCollectionStateFile(*archive.BeginReadFile(STATE_MODULES));
76 {
77 for(CStructCollectionStateFile::StructIterator structIterator(modulesFile.GetStructBegin());
78 structIterator != modulesFile.GetStructEnd(); ++structIterator)
79 {
80 const auto& structFile(structIterator->second);
81 uint32 serverDataAddress = structFile.GetRegister32(STATE_MODULE_SERVER_DATA_ADDRESS);
82 auto serverData = reinterpret_cast<SIFRPCSERVERDATA*>(m_ram + serverDataAddress);
83 auto module = new CSifDynamic(*this, serverDataAddress);
84 m_servers.push_back(module);
85 m_sifMan.RegisterModule(serverData->serverId, module);
86 }
87 }
88 }
89
SaveState(Framework::CZipArchiveWriter & archive) const90 void CSifCmd::SaveState(Framework::CZipArchiveWriter& archive) const
91 {
92 auto modulesFile = new CStructCollectionStateFile(STATE_MODULES);
93 {
94 int moduleIndex = 0;
95 for(const auto& module : m_servers)
96 {
97 auto moduleName = std::string(STATE_MODULE) + std::to_string(moduleIndex++);
98 CStructFile moduleStruct;
99 {
100 uint32 serverDataAddress = module->GetServerDataAddress();
101 moduleStruct.SetRegister32(STATE_MODULE_SERVER_DATA_ADDRESS, serverDataAddress);
102 }
103 modulesFile->InsertStruct(moduleName.c_str(), moduleStruct);
104 }
105 }
106 archive.InsertFile(modulesFile);
107 }
108
GetId() const109 std::string CSifCmd::GetId() const
110 {
111 return MODULE_NAME;
112 }
113
GetFunctionName(unsigned int functionId) const114 std::string CSifCmd::GetFunctionName(unsigned int functionId) const
115 {
116 switch(functionId)
117 {
118 case 6:
119 return FUNCTION_SIFGETSREG;
120 break;
121 case 8:
122 return FUNCTION_SIFSETCMDBUFFER;
123 break;
124 case 10:
125 return FUNCTION_SIFADDCMDHANDLER;
126 break;
127 case 12:
128 return FUNCTION_SIFSENDCMD;
129 break;
130 case 13:
131 return FUNCTION_ISIFSENDCMD;
132 break;
133 case 14:
134 return FUNCTION_SIFINITRPC;
135 break;
136 case 15:
137 return FUNCTION_SIFBINDRPC;
138 break;
139 case 16:
140 return FUNCTION_SIFCALLRPC;
141 break;
142 case 17:
143 return FUNCTION_SIFREGISTERRPC;
144 break;
145 case 18:
146 return FUNCTION_SIFCHECKSTATRPC;
147 break;
148 case 19:
149 return FUNCTION_SIFSETRPCQUEUE;
150 break;
151 case 20:
152 return FUNCTION_SIFGETNEXTREQUEST;
153 break;
154 case 21:
155 return FUNCTION_SIFEXECREQUEST;
156 break;
157 case 22:
158 return FUNCTION_SIFRPCLOOP;
159 break;
160 case 23:
161 return FUNCTION_SIFGETOTHERDATA;
162 break;
163 case 24:
164 return FUNCTION_SIFREMOVERPC;
165 break;
166 case 25:
167 return FUNCTION_SIFREMOVERPCQUEUE;
168 break;
169 case 28:
170 return FUNCTION_SIFSENDCMDINTR;
171 break;
172 case CUSTOM_FINISHEXECREQUEST:
173 return FUNCTION_FINISHEXECREQUEST;
174 break;
175 case CUSTOM_FINISHEXECCMD:
176 return FUNCTION_FINISHEXECCMD;
177 break;
178 case CUSTOM_FINISHBINDRPC:
179 return FUNCTION_FINISHBINDRPC;
180 break;
181 case CUSTOM_SLEEPTHREAD:
182 return FUNCTION_SLEEPTHREAD;
183 break;
184 case CUSTOM_DELAYTHREAD:
185 return FUNCTION_DELAYTHREAD;
186 break;
187 default:
188 return "unknown";
189 break;
190 }
191 }
192
Invoke(CMIPS & context,unsigned int functionId)193 void CSifCmd::Invoke(CMIPS& context, unsigned int functionId)
194 {
195 switch(functionId)
196 {
197 case 6:
198 context.m_State.nGPR[CMIPS::V0].nV0 = SifGetSreg(
199 context.m_State.nGPR[CMIPS::A0].nV0);
200 break;
201 case 8:
202 context.m_State.nGPR[CMIPS::V0].nV0 = SifSetCmdBuffer(
203 context.m_State.nGPR[CMIPS::A0].nV0,
204 context.m_State.nGPR[CMIPS::A1].nV0);
205 break;
206 case 10:
207 SifAddCmdHandler(
208 context.m_State.nGPR[CMIPS::A0].nV0,
209 context.m_State.nGPR[CMIPS::A1].nV0,
210 context.m_State.nGPR[CMIPS::A2].nV0);
211 break;
212 case 12:
213 case 13:
214 context.m_State.nGPR[CMIPS::V0].nV0 = SifSendCmd(
215 context.m_State.nGPR[CMIPS::A0].nV0,
216 context.m_State.nGPR[CMIPS::A1].nV0,
217 context.m_State.nGPR[CMIPS::A2].nV0,
218 context.m_State.nGPR[CMIPS::A3].nV0,
219 context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x10),
220 context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x14));
221 break;
222 case 14:
223 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFINITRPC "();\r\n");
224 break;
225 case 15:
226 SifBindRpc(context);
227 break;
228 case 16:
229 SifCallRpc(context);
230 break;
231 case 17:
232 SifRegisterRpc(context);
233 break;
234 case 18:
235 context.m_State.nGPR[CMIPS::V0].nV0 = SifCheckStatRpc(
236 context.m_State.nGPR[CMIPS::A0].nV0);
237 break;
238 case 19:
239 SifSetRpcQueue(context.m_State.nGPR[CMIPS::A0].nV0,
240 context.m_State.nGPR[CMIPS::A1].nV0);
241 break;
242 case 20:
243 context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(SifGetNextRequest(
244 context.m_State.nGPR[CMIPS::A0].nV0));
245 break;
246 case 21:
247 SifExecRequest(context);
248 break;
249 case 22:
250 SifRpcLoop(context);
251 break;
252 case 23:
253 context.m_State.nGPR[CMIPS::V0].nV0 = SifGetOtherData(
254 context.m_State.nGPR[CMIPS::A0].nV0,
255 context.m_State.nGPR[CMIPS::A1].nV0,
256 context.m_State.nGPR[CMIPS::A2].nV0,
257 context.m_State.nGPR[CMIPS::A3].nV0,
258 context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x10));
259 break;
260 case 24:
261 context.m_State.nGPR[CMIPS::V0].nV0 = SifRemoveRpc(
262 context.m_State.nGPR[CMIPS::A0].nV0,
263 context.m_State.nGPR[CMIPS::A1].nV0);
264 break;
265 case 25:
266 context.m_State.nGPR[CMIPS::V0].nV0 = SifRemoveRpcQueue(
267 context.m_State.nGPR[CMIPS::A0].nV0);
268 break;
269 case 28:
270 context.m_State.nGPR[CMIPS::V0].nV0 = SifSendCmdIntr(
271 context.m_State.nGPR[CMIPS::A0].nV0,
272 context.m_State.nGPR[CMIPS::A1].nV0,
273 context.m_State.nGPR[CMIPS::A2].nV0,
274 context.m_State.nGPR[CMIPS::A3].nV0,
275 context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x10),
276 context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x14),
277 context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x18),
278 context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x1C));
279 break;
280 case CUSTOM_FINISHEXECREQUEST:
281 FinishExecRequest(
282 context.m_State.nGPR[CMIPS::A0].nV0,
283 context.m_State.nGPR[CMIPS::A1].nV0);
284 break;
285 case CUSTOM_FINISHBINDRPC:
286 FinishBindRpc(
287 context.m_State.nGPR[CMIPS::A0].nV0,
288 context.m_State.nGPR[CMIPS::A1].nV0);
289 break;
290 case CUSTOM_FINISHEXECCMD:
291 FinishExecCmd();
292 break;
293 case CUSTOM_SLEEPTHREAD:
294 SleepThread();
295 break;
296 case CUSTOM_DELAYTHREAD:
297 DelayThread(
298 context.m_State.nGPR[CMIPS::A0].nV0);
299 break;
300 default:
301 CLog::GetInstance().Warn(LOG_NAME, "Unknown function called (%d).\r\n",
302 functionId);
303 break;
304 }
305 }
306
ClearServers()307 void CSifCmd::ClearServers()
308 {
309 for(const auto& server : m_servers)
310 {
311 auto serverData = reinterpret_cast<SIFRPCSERVERDATA*>(m_ram + server->GetServerDataAddress());
312 m_sifMan.UnregisterModule(serverData->serverId);
313 delete server;
314 }
315 m_servers.clear();
316 }
317
BuildExportTable()318 void CSifCmd::BuildExportTable()
319 {
320 auto exportTable = reinterpret_cast<uint32*>(m_ram + m_trampolineAddr);
321 *(exportTable++) = 0x41E00000;
322 *(exportTable++) = 0;
323 *(exportTable++) = MODULE_VERSION;
324 strcpy(reinterpret_cast<char*>(exportTable), MODULE_NAME);
325 exportTable += (strlen(MODULE_NAME) + 3) / 4;
326
327 {
328 CMIPSAssembler assembler(exportTable);
329
330 //Trampoline for SifGetNextRequest
331 uint32 sifGetNextRequestAddr = (reinterpret_cast<uint8*>(exportTable) - m_ram) + (assembler.GetProgramSize() * 4);
332 assembler.JR(CMIPS::RA);
333 assembler.ADDIU(CMIPS::R0, CMIPS::R0, 20);
334
335 //Trampoline for SifExecRequest
336 uint32 sifExecRequestAddr = (reinterpret_cast<uint8*>(exportTable) - m_ram) + (assembler.GetProgramSize() * 4);
337 assembler.JR(CMIPS::RA);
338 assembler.ADDIU(CMIPS::R0, CMIPS::R0, 21);
339
340 uint32 finishExecRequestAddr = (reinterpret_cast<uint8*>(exportTable) - m_ram) + (assembler.GetProgramSize() * 4);
341 assembler.JR(CMIPS::RA);
342 assembler.ADDIU(CMIPS::R0, CMIPS::R0, CUSTOM_FINISHEXECREQUEST);
343
344 uint32 finishExecCmdAddr = (reinterpret_cast<uint8*>(exportTable) - m_ram) + (assembler.GetProgramSize() * 4);
345 assembler.JR(CMIPS::RA);
346 assembler.ADDIU(CMIPS::R0, CMIPS::R0, CUSTOM_FINISHEXECCMD);
347
348 uint32 finishBindRpcAddr = (reinterpret_cast<uint8*>(exportTable) - m_ram) + (assembler.GetProgramSize() * 4);
349 assembler.JR(CMIPS::RA);
350 assembler.ADDIU(CMIPS::R0, CMIPS::R0, CUSTOM_FINISHBINDRPC);
351
352 uint32 sleepThreadAddr = (reinterpret_cast<uint8*>(exportTable) - m_ram) + (assembler.GetProgramSize() * 4);
353 assembler.JR(CMIPS::RA);
354 assembler.ADDIU(CMIPS::R0, CMIPS::R0, CUSTOM_SLEEPTHREAD);
355
356 uint32 delayThreadAddr = (reinterpret_cast<uint8*>(exportTable) - m_ram) + (assembler.GetProgramSize() * 4);
357 assembler.JR(CMIPS::RA);
358 assembler.ADDIU(CMIPS::R0, CMIPS::R0, CUSTOM_DELAYTHREAD);
359
360 //Assemble SifRpcLoop
361 {
362 static const int16 stackAlloc = 0x10;
363
364 m_sifRpcLoopAddr = (reinterpret_cast<uint8*>(exportTable) - m_ram) + (assembler.GetProgramSize() * 4);
365 auto checkNextRequestLabel = assembler.CreateLabel();
366 auto sleepThreadLabel = assembler.CreateLabel();
367
368 assembler.ADDIU(CMIPS::SP, CMIPS::SP, -stackAlloc);
369 assembler.SW(CMIPS::RA, 0x00, CMIPS::SP);
370 assembler.SW(CMIPS::S0, 0x04, CMIPS::SP);
371 assembler.ADDU(CMIPS::S0, CMIPS::A0, CMIPS::R0);
372
373 //checkNextRequest:
374 assembler.MarkLabel(checkNextRequestLabel);
375 assembler.JAL(sifGetNextRequestAddr);
376 assembler.ADDU(CMIPS::A0, CMIPS::S0, CMIPS::R0);
377 assembler.BEQ(CMIPS::V0, CMIPS::R0, sleepThreadLabel);
378 assembler.NOP();
379
380 assembler.JAL(sifExecRequestAddr);
381 assembler.ADDU(CMIPS::A0, CMIPS::V0, CMIPS::R0);
382
383 //sleepThread:
384 assembler.MarkLabel(sleepThreadLabel);
385 assembler.JAL(sleepThreadAddr);
386 assembler.NOP();
387 assembler.BEQ(CMIPS::R0, CMIPS::R0, checkNextRequestLabel);
388 assembler.NOP();
389
390 assembler.LW(CMIPS::S0, 0x04, CMIPS::SP);
391 assembler.LW(CMIPS::RA, 0x00, CMIPS::SP);
392 assembler.JR(CMIPS::RA);
393 assembler.ADDIU(CMIPS::SP, CMIPS::SP, stackAlloc);
394 }
395
396 //Assemble SifExecRequest
397 {
398 static const int16 stackAlloc = 0x20;
399
400 m_sifExecRequestAddr = (reinterpret_cast<uint8*>(exportTable) - m_ram) + (assembler.GetProgramSize() * 4);
401
402 assembler.ADDIU(CMIPS::SP, CMIPS::SP, -stackAlloc);
403 assembler.SW(CMIPS::RA, 0x1C, CMIPS::SP);
404 assembler.SW(CMIPS::S0, 0x18, CMIPS::SP);
405 assembler.ADDU(CMIPS::S0, CMIPS::A0, CMIPS::R0);
406
407 assembler.LW(CMIPS::A0, offsetof(SIFRPCSERVERDATA, rid), CMIPS::S0);
408 assembler.LW(CMIPS::A1, offsetof(SIFRPCSERVERDATA, buffer), CMIPS::S0);
409 assembler.LW(CMIPS::A2, offsetof(SIFRPCSERVERDATA, rsize), CMIPS::S0);
410 assembler.LW(CMIPS::T0, offsetof(SIFRPCSERVERDATA, function), CMIPS::S0);
411 assembler.JALR(CMIPS::T0);
412 assembler.NOP();
413
414 assembler.ADDU(CMIPS::A0, CMIPS::S0, CMIPS::R0);
415 assembler.JAL(finishExecRequestAddr);
416 assembler.ADDU(CMIPS::A1, CMIPS::V0, CMIPS::R0);
417
418 assembler.LW(CMIPS::S0, 0x18, CMIPS::SP);
419 assembler.LW(CMIPS::RA, 0x1C, CMIPS::SP);
420 assembler.JR(CMIPS::RA);
421 assembler.ADDIU(CMIPS::SP, CMIPS::SP, stackAlloc);
422 }
423
424 //Assemble SifExecCmdHandler
425 {
426 static const int16 stackAlloc = 0x20;
427
428 m_sifExecCmdHandlerAddr = (reinterpret_cast<uint8*>(exportTable) - m_ram) + (assembler.GetProgramSize() * 4);
429
430 assembler.ADDIU(CMIPS::SP, CMIPS::SP, -stackAlloc);
431 assembler.SW(CMIPS::RA, 0x1C, CMIPS::SP);
432 assembler.SW(CMIPS::S0, 0x18, CMIPS::SP);
433 assembler.ADDU(CMIPS::S0, CMIPS::A0, CMIPS::R0);
434
435 assembler.ADDU(CMIPS::A0, CMIPS::A1, CMIPS::R0); //A0 = Packet Address
436 assembler.LW(CMIPS::A1, offsetof(SIFCMDDATA, data), CMIPS::S0);
437 assembler.LW(CMIPS::T0, offsetof(SIFCMDDATA, sifCmdHandler), CMIPS::S0);
438 assembler.JALR(CMIPS::T0);
439 assembler.NOP();
440
441 assembler.JAL(finishExecCmdAddr);
442 assembler.NOP();
443
444 assembler.LW(CMIPS::S0, 0x18, CMIPS::SP);
445 assembler.LW(CMIPS::RA, 0x1C, CMIPS::SP);
446 assembler.JR(CMIPS::RA);
447 assembler.ADDIU(CMIPS::SP, CMIPS::SP, stackAlloc);
448 }
449
450 //Assemble SifBindRpc
451 {
452 static const int16 stackAlloc = 0x20;
453
454 m_sifBindRpcAddr = (reinterpret_cast<uint8*>(exportTable) - m_ram) + (assembler.GetProgramSize() * 4);
455
456 assembler.ADDIU(CMIPS::SP, CMIPS::SP, -stackAlloc);
457 assembler.SW(CMIPS::RA, 0x1C, CMIPS::SP);
458 assembler.SW(CMIPS::S0, 0x18, CMIPS::SP);
459 assembler.SW(CMIPS::S1, 0x14, CMIPS::SP);
460 assembler.ADDU(CMIPS::S0, CMIPS::A0, CMIPS::R0);
461 assembler.ADDU(CMIPS::S1, CMIPS::A1, CMIPS::R0);
462
463 assembler.LI(CMIPS::A0, 500);
464 assembler.JAL(delayThreadAddr);
465 assembler.NOP();
466
467 assembler.ADDU(CMIPS::A0, CMIPS::S0, CMIPS::R0);
468 assembler.ADDU(CMIPS::A1, CMIPS::S1, CMIPS::R0);
469 assembler.JAL(finishBindRpcAddr);
470 assembler.NOP();
471
472 assembler.ADDU(CMIPS::V0, CMIPS::R0, CMIPS::R0);
473
474 assembler.LW(CMIPS::S1, 0x14, CMIPS::SP);
475 assembler.LW(CMIPS::S0, 0x18, CMIPS::SP);
476 assembler.LW(CMIPS::RA, 0x1C, CMIPS::SP);
477 assembler.JR(CMIPS::RA);
478 assembler.ADDIU(CMIPS::SP, CMIPS::SP, stackAlloc);
479 }
480 }
481 }
482
ProcessInvocation(uint32 serverDataAddr,uint32 methodId,uint32 * params,uint32 size)483 void CSifCmd::ProcessInvocation(uint32 serverDataAddr, uint32 methodId, uint32* params, uint32 size)
484 {
485 auto serverData = reinterpret_cast<SIFRPCSERVERDATA*>(m_ram + serverDataAddr);
486 auto queueData = reinterpret_cast<SIFRPCQUEUEDATA*>(m_ram + serverData->queueAddr);
487
488 //Copy params
489 if(serverData->buffer != 0)
490 {
491 memcpy(&m_ram[serverData->buffer], params, size);
492 }
493 serverData->rid = methodId;
494 serverData->rsize = size;
495
496 assert(queueData->serverDataLink == 0);
497 assert(queueData->serverDataStart == serverDataAddr);
498 queueData->serverDataLink = serverDataAddr;
499
500 auto thread = m_bios.GetThread(queueData->threadId);
501 assert(thread->status == CIopBios::THREAD_STATUS_SLEEPING);
502 m_bios.WakeupThread(queueData->threadId, true);
503 m_bios.Reschedule();
504 }
505
FinishExecRequest(uint32 serverDataAddr,uint32 returnDataAddr)506 void CSifCmd::FinishExecRequest(uint32 serverDataAddr, uint32 returnDataAddr)
507 {
508 auto serverData = reinterpret_cast<SIFRPCSERVERDATA*>(m_ram + serverDataAddr);
509 auto returnData = m_ram + returnDataAddr;
510 m_sifMan.SendCallReply(serverData->serverId, returnData);
511 }
512
FinishExecCmd()513 void CSifCmd::FinishExecCmd()
514 {
515 auto moduleData = reinterpret_cast<MODULEDATA*>(m_ram + m_moduleDataAddr);
516
517 assert(moduleData->executingCmd);
518 moduleData->executingCmd = false;
519
520 auto pendingCmdBuffer = moduleData->pendingCmdBuffer;
521 auto commandHeader = reinterpret_cast<const SIFCMDHEADER*>(pendingCmdBuffer);
522
523 uint8 commandPacketSize = commandHeader->packetSize;
524 assert(moduleData->pendingCmdBufferSize >= commandPacketSize);
525 memmove(pendingCmdBuffer, pendingCmdBuffer + commandPacketSize, PENDING_CMD_BUFFER_SIZE - moduleData->pendingCmdBufferSize);
526 moduleData->pendingCmdBufferSize -= commandPacketSize;
527
528 if(moduleData->pendingCmdBufferSize > 0)
529 {
530 ProcessNextDynamicCommand();
531 }
532 }
533
FinishBindRpc(uint32 clientDataAddr,uint32 serverId)534 void CSifCmd::FinishBindRpc(uint32 clientDataAddr, uint32 serverId)
535 {
536 auto clientData = reinterpret_cast<SIFRPCCLIENTDATA*>(m_ram + clientDataAddr);
537 clientData->serverDataAddr = serverId;
538 clientData->header.semaId = m_bios.CreateSemaphore(0, 1);
539
540 int32 result = CIopBios::KERNEL_RESULT_OK;
541 result = m_bios.WaitSemaphore(clientData->header.semaId);
542 assert(result == CIopBios::KERNEL_RESULT_OK);
543
544 SIFRPCBIND bindPacket;
545 memset(&bindPacket, 0, sizeof(SIFRPCBIND));
546 bindPacket.header.commandId = SIF_CMD_BIND;
547 bindPacket.header.packetSize = sizeof(SIFRPCBIND);
548 bindPacket.serverId = serverId;
549 bindPacket.clientDataAddr = clientDataAddr;
550 m_sifMan.SendPacket(&bindPacket, sizeof(bindPacket));
551 }
552
ProcessCustomCommand(uint32 commandHeaderAddr)553 void CSifCmd::ProcessCustomCommand(uint32 commandHeaderAddr)
554 {
555 auto commandHeader = reinterpret_cast<const SIFCMDHEADER*>(m_ram + commandHeaderAddr);
556 switch(commandHeader->commandId)
557 {
558 case SIF_CMD_SETSREG:
559 ProcessSetSreg(commandHeaderAddr);
560 break;
561 case 0x80000004:
562 //No clue what this is used for, but seems to be used after "WriteToIop" is used.
563 //Could be FlushCache or something like that
564 break;
565 case SIF_CMD_REND:
566 ProcessRpcRequestEnd(commandHeaderAddr);
567 break;
568 default:
569 ProcessDynamicCommand(commandHeaderAddr);
570 break;
571 }
572 }
573
ProcessSetSreg(uint32 commandHeaderAddr)574 void CSifCmd::ProcessSetSreg(uint32 commandHeaderAddr)
575 {
576 auto setSreg = reinterpret_cast<const SIFSETSREG*>(m_ram + commandHeaderAddr);
577 assert(setSreg->header.packetSize == sizeof(SIFSETSREG));
578 assert(setSreg->index < MAX_SREG);
579 if(setSreg->index >= MAX_SREG) return;
580 auto moduleData = reinterpret_cast<MODULEDATA*>(m_ram + m_moduleDataAddr);
581 moduleData->sreg[setSreg->index] = setSreg->value;
582 }
583
ProcessRpcRequestEnd(uint32 commandHeaderAddr)584 void CSifCmd::ProcessRpcRequestEnd(uint32 commandHeaderAddr)
585 {
586 auto requestEnd = reinterpret_cast<const SIFRPCREQUESTEND*>(m_ram + commandHeaderAddr);
587 assert(requestEnd->clientDataAddr != 0);
588 auto clientData = reinterpret_cast<SIFRPCCLIENTDATA*>(m_ram + requestEnd->clientDataAddr);
589 if(requestEnd->commandId == SIF_CMD_BIND)
590 {
591 //When serverDataAddr is 0, EE failed to find requested server ID
592 assert(requestEnd->serverDataAddr != 0);
593 clientData->serverDataAddr = requestEnd->serverDataAddr;
594 clientData->buffPtr = requestEnd->buffer;
595 clientData->cbuffPtr = requestEnd->cbuffer;
596 }
597 else if(requestEnd->commandId == SIF_CMD_CALL)
598 {
599 if(clientData->endFctPtr != 0)
600 {
601 m_bios.TriggerCallback(clientData->endFctPtr, clientData->endParam);
602 }
603 }
604 else
605 {
606 assert(0);
607 }
608 //Unlock/delete semaphore
609 {
610 assert(clientData->header.semaId != 0);
611 int32 result = CIopBios::KERNEL_RESULT_OK;
612 result = m_bios.SignalSemaphore(clientData->header.semaId, true);
613 assert(result == CIopBios::KERNEL_RESULT_OK);
614 result = m_bios.DeleteSemaphore(clientData->header.semaId);
615 assert(result == CIopBios::KERNEL_RESULT_OK);
616 clientData->header.semaId = 0;
617 }
618 }
619
ProcessDynamicCommand(uint32 commandHeaderAddr)620 void CSifCmd::ProcessDynamicCommand(uint32 commandHeaderAddr)
621 {
622 auto moduleData = reinterpret_cast<MODULEDATA*>(m_ram + m_moduleDataAddr);
623 auto commandHeader = reinterpret_cast<const SIFCMDHEADER*>(m_ram + commandHeaderAddr);
624
625 uint8 commandPacketSize = commandHeader->packetSize;
626 assert((moduleData->pendingCmdBufferSize + commandPacketSize) <= PENDING_CMD_BUFFER_SIZE);
627
628 if((moduleData->pendingCmdBufferSize + commandPacketSize) <= PENDING_CMD_BUFFER_SIZE)
629 {
630 memcpy(moduleData->pendingCmdBuffer + moduleData->pendingCmdBufferSize, commandHeader, commandPacketSize);
631 moduleData->pendingCmdBufferSize += commandPacketSize;
632
633 if(!moduleData->executingCmd)
634 {
635 ProcessNextDynamicCommand();
636 }
637 }
638 }
639
ProcessNextDynamicCommand()640 void CSifCmd::ProcessNextDynamicCommand()
641 {
642 auto moduleData = reinterpret_cast<MODULEDATA*>(m_ram + m_moduleDataAddr);
643
644 assert(!moduleData->executingCmd);
645 moduleData->executingCmd = true;
646
647 uint32 commandHeaderAddr = m_moduleDataAddr + offsetof(MODULEDATA, pendingCmdBuffer);
648 auto commandHeader = reinterpret_cast<const SIFCMDHEADER*>(m_ram + commandHeaderAddr);
649 bool isSystemCommand = (commandHeader->commandId & SYSTEM_COMMAND_ID) != 0;
650 uint32 cmd = commandHeader->commandId & ~SYSTEM_COMMAND_ID;
651 uint32 cmdBufferAddr = isSystemCommand ? m_sysCmdBufferAddr : moduleData->usrCmdBufferAddr;
652 uint32 cmdBufferLen = isSystemCommand ? MAX_SYSTEM_COMMAND : moduleData->usrCmdBufferLen;
653
654 if((cmdBufferAddr != 0) && (cmd < cmdBufferLen))
655 {
656 const auto& cmdDataEntry = reinterpret_cast<SIFCMDDATA*>(m_ram + cmdBufferAddr)[cmd];
657
658 CLog::GetInstance().Print(LOG_NAME, "Calling SIF command handler for command 0x%08X at 0x%08X with data 0x%08X.\r\n",
659 commandHeader->commandId, cmdDataEntry.sifCmdHandler, cmdDataEntry.data);
660
661 assert(cmdDataEntry.sifCmdHandler != 0);
662 if(cmdDataEntry.sifCmdHandler != 0)
663 {
664 //This expects to be in an interrupt and the handler is called in the interrupt.
665 //That's not the case here though, so we try for the same effect by calling the handler outside of an interrupt.
666 uint32 cmdDataEntryAddr = reinterpret_cast<const uint8*>(&cmdDataEntry) - m_ram;
667 m_bios.TriggerCallback(m_sifExecCmdHandlerAddr, cmdDataEntryAddr, commandHeaderAddr);
668 m_bios.Reschedule();
669 }
670 else
671 {
672 FinishExecCmd();
673 }
674 }
675 else
676 {
677 assert(false);
678 FinishExecCmd();
679 }
680 }
681
SifGetSreg(uint32 regIndex)682 int32 CSifCmd::SifGetSreg(uint32 regIndex)
683 {
684 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFGETSREG "(regIndex = %d);\r\n",
685 regIndex);
686 assert(regIndex < MAX_SREG);
687 if(regIndex >= MAX_SREG)
688 {
689 return 0;
690 }
691 auto moduleData = reinterpret_cast<const MODULEDATA*>(m_ram + m_moduleDataAddr);
692 uint32 result = moduleData->sreg[regIndex];
693 return result;
694 }
695
SifSetCmdBuffer(uint32 cmdBufferAddr,uint32 length)696 uint32 CSifCmd::SifSetCmdBuffer(uint32 cmdBufferAddr, uint32 length)
697 {
698 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFSETCMDBUFFER "(cmdBufferAddr = 0x%08X, length = %d);\r\n",
699 cmdBufferAddr, length);
700
701 auto moduleData = reinterpret_cast<MODULEDATA*>(m_ram + m_moduleDataAddr);
702 uint32 originalBuffer = moduleData->usrCmdBufferAddr;
703 moduleData->usrCmdBufferAddr = cmdBufferAddr;
704 moduleData->usrCmdBufferLen = length;
705
706 return originalBuffer;
707 }
708
SifAddCmdHandler(uint32 pos,uint32 handler,uint32 data)709 void CSifCmd::SifAddCmdHandler(uint32 pos, uint32 handler, uint32 data)
710 {
711 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFADDCMDHANDLER "(pos = 0x%08X, handler = 0x%08X, data = 0x%08X);\r\n",
712 pos, handler, data);
713
714 auto moduleData = reinterpret_cast<const MODULEDATA*>(m_ram + m_moduleDataAddr);
715 bool isSystemCommand = (pos & SYSTEM_COMMAND_ID) != 0;
716 uint32 cmd = pos & ~SYSTEM_COMMAND_ID;
717 uint32 cmdBufferAddr = isSystemCommand ? m_sysCmdBufferAddr : moduleData->usrCmdBufferAddr;
718 uint32 cmdBufferLen = isSystemCommand ? MAX_SYSTEM_COMMAND : moduleData->usrCmdBufferLen;
719
720 if((cmdBufferAddr != 0) && (cmd < cmdBufferLen))
721 {
722 auto& cmdDataEntry = reinterpret_cast<SIFCMDDATA*>(m_ram + cmdBufferAddr)[cmd];
723 cmdDataEntry.sifCmdHandler = handler;
724 cmdDataEntry.data = data;
725 }
726 else
727 {
728 CLog::GetInstance().Print(LOG_NAME, "SifAddCmdHandler - error command buffer too small or not set.\r\n");
729 }
730 }
731
SifSendCmd(uint32 commandId,uint32 packetPtr,uint32 packetSize,uint32 srcExtraPtr,uint32 dstExtraPtr,uint32 sizeExtra)732 uint32 CSifCmd::SifSendCmd(uint32 commandId, uint32 packetPtr, uint32 packetSize, uint32 srcExtraPtr, uint32 dstExtraPtr, uint32 sizeExtra)
733 {
734 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFSENDCMD "(commandId = 0x%08X, packetPtr = 0x%08X, packetSize = 0x%08X, srcExtraPtr = 0x%08X, dstExtraPtr = 0x%08X, sizeExtra = 0x%08X);\r\n",
735 commandId, packetPtr, packetSize, srcExtraPtr, dstExtraPtr, sizeExtra);
736
737 assert(packetSize >= 0x10);
738
739 auto packetData = m_ram + packetPtr;
740 auto header = reinterpret_cast<SIFCMDHEADER*>(packetData);
741 header->commandId = commandId;
742 header->packetSize = packetSize;
743 header->destSize = 0;
744 header->dest = 0;
745
746 if(sizeExtra != 0 && srcExtraPtr != 0 && dstExtraPtr != 0)
747 {
748 header->destSize = sizeExtra;
749 header->dest = dstExtraPtr;
750
751 auto dmaReg = reinterpret_cast<SIFDMAREG*>(m_ram + m_sendCmdExtraStructAddr);
752 dmaReg->srcAddr = srcExtraPtr;
753 dmaReg->dstAddr = dstExtraPtr;
754 dmaReg->size = sizeExtra;
755 dmaReg->flags = 0;
756
757 m_sifMan.SifSetDma(m_sendCmdExtraStructAddr, 1);
758 }
759
760 m_sifMan.SendPacket(packetData, packetSize);
761
762 return 1;
763 }
764
SifBindRpc(CMIPS & context)765 void CSifCmd::SifBindRpc(CMIPS& context)
766 {
767 uint32 clientDataAddr = context.m_State.nGPR[CMIPS::A0].nV0;
768 uint32 serverId = context.m_State.nGPR[CMIPS::A1].nV0;
769 uint32 mode = context.m_State.nGPR[CMIPS::A2].nV0;
770
771 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFBINDRPC "(clientDataAddr = 0x%08X, serverId = 0x%08X, mode = 0x%08X);\r\n",
772 clientDataAddr, serverId, mode);
773
774 //Could be in non waiting mode
775 assert(mode == 0);
776
777 context.m_State.nPC = m_sifBindRpcAddr;
778 }
779
SifCallRpc(CMIPS & context)780 void CSifCmd::SifCallRpc(CMIPS& context)
781 {
782 uint32 clientDataAddr = context.m_State.nGPR[CMIPS::A0].nV0;
783 uint32 rpcNumber = context.m_State.nGPR[CMIPS::A1].nV0;
784 uint32 mode = context.m_State.nGPR[CMIPS::A2].nV0;
785 uint32 sendAddr = context.m_State.nGPR[CMIPS::A3].nV0;
786 uint32 sendSize = context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x10);
787 uint32 recvAddr = context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x14);
788 uint32 recvSize = context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x18);
789 uint32 endFctAddr = context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x1C);
790 uint32 endParam = context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x20);
791
792 assert(mode == 0);
793
794 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFCALLRPC "(clientDataAddr = 0x%08X, rpcNumber = 0x%08X, mode = 0x%08X, sendAddr = 0x%08X, sendSize = 0x%08X, "
795 "recvAddr = 0x%08X, recvSize = 0x%08X, endFctAddr = 0x%08X, endParam = 0x%08X);\r\n",
796 clientDataAddr, rpcNumber, mode, sendAddr, sendSize, recvAddr, recvSize, endFctAddr, endParam);
797
798 auto clientData = reinterpret_cast<SIFRPCCLIENTDATA*>(m_ram + clientDataAddr);
799 assert(clientData->serverDataAddr != 0);
800 clientData->endFctPtr = endFctAddr;
801 clientData->endParam = endParam;
802 clientData->header.semaId = m_bios.CreateSemaphore(0, 1);
803 int32 result = CIopBios::KERNEL_RESULT_OK;
804 result = m_bios.WaitSemaphore(clientData->header.semaId);
805 assert(result == CIopBios::KERNEL_RESULT_OK);
806
807 {
808 auto dmaReg = reinterpret_cast<SIFDMAREG*>(m_ram + m_sendCmdExtraStructAddr);
809 dmaReg->srcAddr = sendAddr;
810 dmaReg->dstAddr = clientData->buffPtr;
811 dmaReg->size = sendSize;
812 dmaReg->flags = 0;
813
814 m_sifMan.SifSetDma(m_sendCmdExtraStructAddr, 1);
815 }
816
817 SIFRPCCALL callPacket;
818 memset(&callPacket, 0, sizeof(SIFRPCCALL));
819 callPacket.header.commandId = SIF_CMD_CALL;
820 callPacket.header.packetSize = sizeof(SIFRPCCALL);
821 callPacket.header.destSize = sendSize;
822 callPacket.header.dest = clientData->buffPtr;
823 callPacket.rpcNumber = rpcNumber;
824 callPacket.sendSize = sendSize;
825 callPacket.recv = recvAddr;
826 callPacket.recvSize = recvSize;
827 callPacket.recvMode = 1;
828 callPacket.clientDataAddr = clientDataAddr;
829 callPacket.serverDataAddr = clientData->serverDataAddr;
830
831 m_sifMan.SendPacket(&callPacket, sizeof(callPacket));
832
833 context.m_State.nGPR[CMIPS::V0].nD0 = 0;
834 }
835
SifRegisterRpc(CMIPS & context)836 void CSifCmd::SifRegisterRpc(CMIPS& context)
837 {
838 uint32 serverDataAddr = context.m_State.nGPR[CMIPS::A0].nV0;
839 uint32 serverId = context.m_State.nGPR[CMIPS::A1].nV0;
840 uint32 function = context.m_State.nGPR[CMIPS::A2].nV0;
841 uint32 buffer = context.m_State.nGPR[CMIPS::A3].nV0;
842 uint32 cfunction = context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x10);
843 uint32 cbuffer = context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x14);
844 uint32 queueAddr = context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x18);
845
846 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFREGISTERRPC "(serverData = 0x%08X, serverId = 0x%08X, function = 0x%08X, buffer = 0x%08X, cfunction = 0x%08X, cbuffer = 0x%08X, queue = 0x%08X);\r\n",
847 serverDataAddr, serverId, function, buffer, cfunction, cbuffer, queueAddr);
848
849 bool moduleRegistered = m_sifMan.IsModuleRegistered(serverId);
850 if(!moduleRegistered)
851 {
852 auto module = new CSifDynamic(*this, serverDataAddr);
853 m_servers.push_back(module);
854 m_sifMan.RegisterModule(serverId, module);
855 }
856
857 if(serverDataAddr != 0)
858 {
859 auto serverData = reinterpret_cast<SIFRPCSERVERDATA*>(&m_ram[serverDataAddr]);
860 serverData->serverId = serverId;
861 serverData->function = function;
862 serverData->buffer = buffer;
863 serverData->cfunction = cfunction;
864 serverData->cbuffer = cbuffer;
865 serverData->queueAddr = queueAddr;
866 //If a serverId was already registed before this call to SifRegisterRpc, we mark serverData as
867 //not being active. This is important for SifRemoveRpc because it might try to unregister
868 //something that was present before (ex.: FF12 with MCSERV)
869 serverData->active = moduleRegistered ? false : true;
870 }
871
872 if(queueAddr != 0)
873 {
874 auto queueData = reinterpret_cast<SIFRPCQUEUEDATA*>(m_ram + queueAddr);
875 assert(queueData->serverDataStart == 0);
876 queueData->serverDataStart = serverDataAddr;
877 }
878
879 context.m_State.nGPR[CMIPS::V0].nD0 = 0;
880 }
881
SifSetRpcQueue(uint32 queueDataAddr,uint32 threadId)882 void CSifCmd::SifSetRpcQueue(uint32 queueDataAddr, uint32 threadId)
883 {
884 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFSETRPCQUEUE "(queueData = 0x%08X, threadId = %d);\r\n",
885 queueDataAddr, threadId);
886
887 if(queueDataAddr != 0)
888 {
889 auto queueData = reinterpret_cast<SIFRPCQUEUEDATA*>(m_ram + queueDataAddr);
890 queueData->threadId = threadId;
891 queueData->active = 0;
892 queueData->serverDataLink = 0;
893 queueData->serverDataStart = 0;
894 queueData->serverDataEnd = 0;
895 queueData->queueNext = 0;
896 }
897 }
898
SifGetNextRequest(uint32 queueDataAddr)899 uint32 CSifCmd::SifGetNextRequest(uint32 queueDataAddr)
900 {
901 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFGETNEXTREQUEST "(queueData = 0x%08X);\r\n",
902 queueDataAddr);
903
904 uint32 result = 0;
905 if(queueDataAddr != 0)
906 {
907 auto queueData = reinterpret_cast<SIFRPCQUEUEDATA*>(m_ram + queueDataAddr);
908 result = queueData->serverDataLink;
909 queueData->serverDataLink = 0;
910 }
911 return result;
912 }
913
SifExecRequest(CMIPS & context)914 void CSifCmd::SifExecRequest(CMIPS& context)
915 {
916 uint32 serverDataAddr = context.m_State.nGPR[CMIPS::A0].nV0;
917 auto serverData = reinterpret_cast<SIFRPCSERVERDATA*>(&m_ram[serverDataAddr]);
918 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFEXECREQUEST "(serverData = 0x%08X, serverId=0x%x, function=0x%x, rid=0x%x, buffer=0x%x, rsize=0x%x);\r\n",
919 serverDataAddr, serverData->serverId, serverData->function, serverData->rid, serverData->buffer, serverData->rsize);
920 context.m_State.nPC = m_sifExecRequestAddr;
921 }
922
SifCheckStatRpc(uint32 clientDataAddress)923 uint32 CSifCmd::SifCheckStatRpc(uint32 clientDataAddress)
924 {
925 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFCHECKSTATRPC "(clientData = 0x%08X);\r\n",
926 clientDataAddress);
927 return 0;
928 }
929
SifRpcLoop(CMIPS & context)930 void CSifCmd::SifRpcLoop(CMIPS& context)
931 {
932 uint32 queueAddr = context.m_State.nGPR[CMIPS::A0].nV0;
933 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFRPCLOOP "(queue = 0x%08X);\r\n",
934 queueAddr);
935 context.m_State.nPC = m_sifRpcLoopAddr;
936 }
937
SifRemoveRpc(uint32 serverDataAddr,uint32 queueDataAddr)938 uint32 CSifCmd::SifRemoveRpc(uint32 serverDataAddr, uint32 queueDataAddr)
939 {
940 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFREMOVERPC "(server = 0x%08X, queue = 0x%08X);\r\n",
941 serverDataAddr, queueDataAddr);
942
943 if(serverDataAddr == 0)
944 {
945 CLog::GetInstance().Warn(LOG_NAME, FUNCTION_SIFREMOVERPC ": serverDataAddr is null.\r\n");
946 return 0;
947 }
948
949 auto serverData = reinterpret_cast<const SIFRPCSERVERDATA*>(&m_ram[serverDataAddr]);
950 if(!serverData->active)
951 {
952 //Server was not active, don't bother unregistering it
953 return 1;
954 }
955
956 bool registered = m_sifMan.IsModuleRegistered(serverData->serverId);
957 if(!registered)
958 {
959 CLog::GetInstance().Warn(LOG_NAME, FUNCTION_SIFREMOVERPC ": server not registered.\r\n");
960 return 0;
961 }
962
963 m_sifMan.UnregisterModule(serverData->serverId);
964
965 return 1;
966 }
967
SifRemoveRpcQueue(uint32 queueDataAddr)968 uint32 CSifCmd::SifRemoveRpcQueue(uint32 queueDataAddr)
969 {
970 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFREMOVERPCQUEUE "(queue = 0x%08X);\r\n",
971 queueDataAddr);
972 return 1;
973 }
974
SifGetOtherData(uint32 packetPtr,uint32 src,uint32 dst,uint32 size,uint32 mode)975 uint32 CSifCmd::SifGetOtherData(uint32 packetPtr, uint32 src, uint32 dst, uint32 size, uint32 mode)
976 {
977 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFGETOTHERDATA "(packetPtr = 0x%08X, src = 0x%08X, dst = 0x%08X, size = 0x%08X, mode = %d);\r\n",
978 packetPtr, src, dst, size, mode);
979 m_sifMan.GetOtherData(dst, src, size);
980 return 0;
981 }
982
SifSendCmdIntr(uint32 commandId,uint32 packetPtr,uint32 packetSize,uint32 srcExtraPtr,uint32 dstExtraPtr,uint32 sizeExtra,uint32 callbackPtr,uint32 callbackDataPtr)983 uint32 CSifCmd::SifSendCmdIntr(uint32 commandId, uint32 packetPtr, uint32 packetSize, uint32 srcExtraPtr, uint32 dstExtraPtr, uint32 sizeExtra, uint32 callbackPtr, uint32 callbackDataPtr)
984 {
985 CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFSENDCMDINTR "(commandId = 0x%08X, packetPtr = 0x%08X, packetSize = 0x%08X, srcExtraPtr = 0x%08X, dstExtraPtr = 0x%08X, sizeExtra = 0x%08X, callbackPtr = 0x%08X, callbackDataPtr = 0x%08X);\r\n",
986 commandId, packetPtr, packetSize, srcExtraPtr, dstExtraPtr, sizeExtra, callbackPtr, callbackDataPtr);
987
988 uint32 result = SifSendCmd(commandId, packetPtr, packetSize, srcExtraPtr, dstExtraPtr, sizeExtra);
989 m_bios.TriggerCallback(callbackPtr, callbackDataPtr);
990 return result;
991 }
992
SleepThread()993 void CSifCmd::SleepThread()
994 {
995 m_bios.SleepThread();
996 }
997
DelayThread(uint32 delay)998 void CSifCmd::DelayThread(uint32 delay)
999 {
1000 m_bios.DelayThread(delay);
1001 }
1002