11#include "irx_imports.h"
28 int used_sema_bitfield;
33static u8 pkt_table[0x800];
34static u8 rdata_table[0x800];
35static u8 client_data[0x800];
42void sceSifInitRpc(
int mode)
58 sif_rpc_data.rdata_table = (u8 *)rdata_table;
60 sif_rpc_data.pkt_table = pkt_table;
61 sif_rpc_data.pkt_table_len = 32;
62 sif_rpc_data.unused1 = 0;
63 sif_rpc_data.unused2 = 0;
64 sif_rpc_data.rdata_table_len = 32;
65 sif_rpc_data.client_table = (u8 *)client_data;
66 sif_rpc_data.client_table_len = 32;
67 sif_rpc_data.rdata_table_idx = 0;
69 sceSifAddCmdHandler(SIF_CMD_RPC_END, (SifCmdHandler_t)sif_cmd_handler_end, &sif_rpc_data);
70 sceSifAddCmdHandler(SIF_CMD_RPC_BIND, (SifCmdHandler_t)sif_cmd_handler_bind, &sif_rpc_data);
71 sceSifAddCmdHandler(SIF_CMD_RPC_CALL, (SifCmdHandler_t)sif_cmd_handler_call, &sif_rpc_data);
72 sceSifAddCmdHandler(SIF_CMD_RPC_RDATA, (SifCmdHandler_t)sif_cmd_handler_rdata, &sif_rpc_data);
75 sif_rpc_data.sif_rpc_sema_ef = CreateEventFlag(&efp);
76 sif_rpc_data.used_sema_bitfield = 0;
80 sceSifSendCmd(SIF_CMD_SET_SREG, pkt_table, 24, 0, 0, 0);
82 SystemStatusFlag = GetSystemStatusFlag();
83 WaitEventFlag(SystemStatusFlag, 0x800u, 0, 0);
92 for ( i = 0; i < 32; ++i )
94 int used_sema_bitfield;
96 used_sema_bitfield =
rpc_data->used_sema_bitfield;
97 if ( (used_sema_bitfield & ((u32)1 << i)) == 0 )
99 rpc_data->used_sema_bitfield = used_sema_bitfield | (1 << i);
113 rpc_data->used_sema_bitfield &= ~(1 << sema_id);
137 p_pkt_addr = &pkt_table_0->pkt_addr;
138 while ( ((
unsigned int)*(p_pkt_addr - 1) & 2) != 0 )
149 *(p_pkt_addr - 1) = (
void *)((i << 16) | 6);
153 if ( pid_1_tmp == 1 )
158 p_pkt_addr[1] = (
void *)pid_1_tmp;
159 *p_pkt_addr = pkt_table_0;
168 pkt->rec_id &= 0xFFFFFFFD;
177 rdata_table_idx =
rpc_data->rdata_table_idx;
178 rdata_table_len =
rpc_data->rdata_table_len;
179 index_calc = rdata_table_idx % rdata_table_len;
180 if ( rdata_table_len == -1 && (u32)rdata_table_idx == 0x80000000 )
182 rpc_data->rdata_table_idx = index_calc + 1;
183 return &
rpc_data->rdata_table[64 * index_calc];
188 if ( rid >= 0 && rid < rpc_data->client_table_len )
189 return &
rpc_data->client_table[64 * rid];
191 return sif_rpc_get_fpacket(
rpc_data);
198 SifRpcEndFunc_t end_function;
204 if ( cid == SIF_CMD_RPC_CALL )
206 client1 = data->client;
207 end_function = client1->end_function;
209 end_function(client1->end_param);
211 else if ( cid == SIF_CMD_RPC_BIND )
213 client2 = data->client;
214 client2->server = data->server;
215 client2->buff = data->buff;
217 client3 = data->client;
218 sema_id = client3->hdr.sema_id;
220 iSetEventFlag(harg->sif_rpc_sema_ef, 1 << sema_id);
222 client3->hdr.pkt_addr = 0;
225static unsigned int sif_cmd_handler_rdata_alarm_retry(
SifRpcRendPkt_t *a1)
227 if ( isceSifSendCmd(SIF_CMD_RPC_END, a1, 64, a1->server, a1->buff, (
int)a1->cbuff) != 0 )
239 rec_id = data->rec_id;
240 if ( (rec_id & 4) != 0 )
241 fpacket2 = (
SifRpcRendPkt_t *)sif_rpc_get_fpacket2(harg, (rec_id >> 16) & 0xFFFF);
244 fpacket2->pkt_addr = data->pkt_addr;
246 fpacket2->cid = SIF_CMD_RPC_RDATA;
247 fpacket2->client = receive;
249 fpacket2->buff = data->dest;
250 fpacket2->cbuff = (
void *)data->size;
251 if ( !isceSifSendCmd(SIF_CMD_RPC_END, fpacket2, 64, data->src, data->dest, data->size) )
255 iSetAlarm(&clk, (
unsigned int (*)(
void *))sif_cmd_handler_rdata_alarm_retry, fpacket2);
266 rd->hdr.pkt_addr = other;
267 rd->hdr.rpc_id = other->rpc_id;
268 other->pkt_addr = other;
275 rd->hdr.sema_id = -1;
276 if ( sceSifSendCmd(SIF_CMD_RPC_RDATA, other, 64, 0, 0, 0) == 0 )
287 sema = sif_rpc_get_sema(&sif_rpc_data);
288 rd->hdr.sema_id = sema;
291 if ( sceSifSendCmd(SIF_CMD_RPC_RDATA, other, 64, 0, 0, 0) )
293 WaitEventFlag(sif_rpc_data.sif_rpc_sema_ef, 1 << rd->hdr.sema_id, 0, 0);
294 ClearEventFlag(sif_rpc_data.sif_rpc_sema_ef, ~(1 << rd->hdr.sema_id));
295 sif_rpc_free_sema(&sif_rpc_data, rd->hdr.sema_id);
301 sif_rpc_free_sema(&sif_rpc_data, rd->hdr.sema_id);
323 server = queue->link;
326 if ( server->sid == sid )
328 server = server->link;
336static unsigned int sif_cmd_handler_bind_alarm_retry(
void *a1)
338 if ( isceSifSendCmd(SIF_CMD_RPC_END, a1, 64, 0, 0, 0) != 0 )
351 fpacket->pkt_addr = data->pkt_addr;
352 client = data->client;
353 fpacket->cid = SIF_CMD_RPC_BIND;
354 fpacket->client = client;
355 server = sif_search_svdata(data->sid, harg);
358 fpacket->server = server;
359 fpacket->buff = server->buff;
366 if ( !isceSifSendCmd(SIF_CMD_RPC_END, fpacket, 64, 0, 0, 0) )
370 iSetAlarm(&clk, (
unsigned int (*)(
void *))sif_cmd_handler_bind_alarm_retry, fpacket);
383 client->hdr.pkt_addr = bind;
384 client->hdr.rpc_id = bind->rpc_id;
385 bind->pkt_addr = bind;
386 bind->client = client;
387 bind->sid = rpc_number;
390 client->hdr.sema_id = -1;
391 if ( sceSifSendCmd(SIF_CMD_RPC_BIND, bind, 64, 0, 0, 0) == 0 )
402 sema = sif_rpc_get_sema(&sif_rpc_data);
403 client->hdr.sema_id = sema;
406 if ( sceSifSendCmd(SIF_CMD_RPC_BIND, bind, 64, 0, 0, 0) )
408 WaitEventFlag(sif_rpc_data.sif_rpc_sema_ef, 1 << client->hdr.sema_id, 0, 0);
409 ClearEventFlag(sif_rpc_data.sif_rpc_sema_ef, ~(1 << client->hdr.sema_id));
410 sif_rpc_free_sema(&sif_rpc_data, client->hdr.sema_id);
416 sif_rpc_free_sema(&sif_rpc_data, client->hdr.sema_id);
437 server = data->server;
440 base->end->next = server;
442 base->start = server;
444 server->pkt_addr = data->pkt_addr;
445 server->client = data->client;
446 server->rpc_number = data->rpc_number;
447 server->size = data->send_size;
448 server->receive = data->receive;
449 server->rsize = data->recv_size;
450 server->rmode = data->rmode;
451 server->rid = data->rec_id;
452 if ( base->thread_id >= 0 && !base->active )
453 iWakeupThread(base->thread_id);
464 SifRpcEndFunc_t end_function,
474 client->hdr.pkt_addr = call;
475 rpc_id = call->rpc_id;
476 client->end_function = end_function;
477 client->end_param = end_param;
478 client->hdr.rpc_id = rpc_id;
479 call->pkt_addr = call;
480 call->client = client;
481 call->rpc_number = rpc_number;
482 call->send_size = ssize;
483 call->receive = receive;
484 call->recv_size = rsize;
485 call->server = client->server;
494 dest_extra = client->buff;
495 client->hdr.sema_id = -1;
496 if ( sceSifSendCmd(SIF_CMD_RPC_CALL, call, 64, send, dest_extra, ssize) == 0 )
508 sema = sif_rpc_get_sema(&sif_rpc_data);
509 client->hdr.sema_id = sema;
512 if ( sceSifSendCmd(SIF_CMD_RPC_CALL, call, 64, send, client->buff, ssize) )
514 WaitEventFlag(sif_rpc_data.sif_rpc_sema_ef, 1 << client->hdr.sema_id, 0, 0);
515 ClearEventFlag(sif_rpc_data.sif_rpc_sema_ef, ~(1 << client->hdr.sema_id));
516 sif_rpc_free_sema(&sif_rpc_data, client->hdr.sema_id);
522 sif_rpc_free_sema(&sif_rpc_data, client->hdr.sema_id);
541 return cd->hdr.pkt_addr && (int)(cd->hdr.rpc_id) == pkt_addr->rpc_id && (pkt_addr->rec_id & 2) != 0;
550 q->thread_id = thread_id;
556 if ( sif_rpc_data.active_queue )
558 for ( queue = sif_rpc_data.active_queue; queue->next; queue = queue->next )
564 sif_rpc_data.active_queue = q;
569void sceSifRegisterRpc(
587 for ( ; server->link; server = server->link )
608 qd->link = server1->link;
614 server2 = server1->link;
617 server1->link = server2->link;
620 server1 = server1->link;
638 queue1 = sif_rpc_data.active_queue;
639 if ( sif_rpc_data.active_queue == qd )
641 sif_rpc_data.active_queue = sif_rpc_data.active_queue->next;
643 else if ( sif_rpc_data.active_queue )
647 queue2 = queue1->next;
650 queue1->next = queue2->next;
653 queue1 = queue1->next;
672 qd->start = server->next;
697 rec = (
void *)srv->func(srv->rpc_number, srv->buff, srv->size);
699 size_extra = srv->rsize;
702 if ( (rid & 4) != 0 )
703 fpacket2 = (
SifRpcRendPkt_t *)sif_rpc_get_fpacket2(&sif_rpc_data, (rid >> 16) & 0xFFFF);
708 client = srv->client;
709 rend->cid = SIF_CMD_RPC_CALL;
710 rend->client = client;
714 while ( !sceSifSendCmd(SIF_CMD_RPC_END, rend, 64, rec, srv->receive, size_extra) )
725 if ( size_extra > 0 )
729 receive = srv->receive;
730 dmat2[0].size = size_extra;
732 dmat2[0].dest = receive;
736 dmat1 = &dmat2[exsz1];
738 pkt_addr = srv->pkt_addr;
741 dmat1->dest = pkt_addr;
748 dmar = sceSifSetDma(dmat2, exsz2);
753 while ( busywait-- != -1 )
765 server = sceSifGetNextRequest(qd);
767 sceSifExecRequest(server);
int CpuResumeIntr(int state)
int CpuSuspendIntr(int *state)