11#include "irx_imports.h"
28 int used_sema_bitfield;
31static sif_rpc_data_t sif_rpc_data;
37static
void sif_cmd_handler_end(
SifRpcRendPkt_t *data, sif_rpc_data_t *harg);
38static
void sif_cmd_handler_bind(
SifRpcBindPkt_t *data, sif_rpc_data_t *harg);
39static
void sif_cmd_handler_call(
SifRpcCallPkt_t *data, sif_rpc_data_t *harg);
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);
86static int sif_rpc_get_sema(sif_rpc_data_t *
rpc_data)
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);
108static void sif_rpc_free_sema(sif_rpc_data_t *
rpc_data,
char sema_id)
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;
171static void *sif_rpc_get_fpacket(sif_rpc_data_t *
rpc_data)
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];
186static void *sif_rpc_get_fpacket2(sif_rpc_data_t *
rpc_data,
int rid)
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);
194static void sif_cmd_handler_end(
SifRpcRendPkt_t *data, sif_rpc_data_t *harg)
198 SifRpcEndFunc_t end_function;
204 if ( cid == SIF_CMD_RPC_CALL )
207 end_function = client1->end_function;
209 end_function(client1->end_param);
211 else if ( cid == SIF_CMD_RPC_BIND )
214 client2->server = data->sd;
215 client2->buf = data->buf;
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->sd, a1->buf, (
int)a1->cbuf) != 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->cd = recvbuf;
249 fpacket2->buf = data->dest;
250 fpacket2->cbuf = (
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);
326 if ( sd->sid == sid )
336static unsigned int sif_cmd_handler_bind_alarm_retry(
void *a1)
338 if ( isceSifSendCmd(SIF_CMD_RPC_END, a1, 64, 0, 0, 0) != 0 )
343static void sif_cmd_handler_bind(
SifRpcBindPkt_t *data, sif_rpc_data_t *harg)
351 fpacket->pkt_addr = data->pkt_addr;
353 fpacket->cid = SIF_CMD_RPC_BIND;
355 sd = sif_search_svdata(data->sid, harg);
359 fpacket->buf = sd->buf;
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 cd->hdr.pkt_addr = bind;
384 cd->hdr.rpc_id = bind->rpc_id;
385 bind->pkt_addr = bind;
390 cd->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 cd->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 << cd->hdr.sema_id, 0, 0);
409 ClearEventFlag(sif_rpc_data.sif_rpc_sema_ef, ~(1 << cd->hdr.sema_id));
410 sif_rpc_free_sema(&sif_rpc_data, cd->hdr.sema_id);
416 sif_rpc_free_sema(&sif_rpc_data, cd->hdr.sema_id);
430static void sif_cmd_handler_call(
SifRpcCallPkt_t *data, sif_rpc_data_t *harg)
440 base->end->next = sd;
444 sd->pkt_addr = data->pkt_addr;
445 sd->client = data->cd;
446 sd->rpc_number = data->rpc_number;
447 sd->size = data->send_size;
448 sd->recvbuf = data->recvbuf;
449 sd->rsize = data->recv_size;
450 sd->rmode = data->rmode;
451 sd->rid = data->rec_id;
452 if ( base->thread_id >= 0 && !base->active )
453 iWakeupThread(base->thread_id);
464 SifRpcEndFunc_t end_function,
474 cd->hdr.pkt_addr = call;
475 rpc_id = call->rpc_id;
476 cd->end_function = end_function;
477 cd->end_param = end_param;
478 cd->hdr.rpc_id = rpc_id;
479 call->pkt_addr = call;
481 call->rpc_number = rpc_number;
482 call->send_size = ssize;
483 call->recvbuf = recvbuf;
484 call->recv_size = rsize;
485 call->sd = cd->server;
494 dest_extra = cd->buf;
495 cd->hdr.sema_id = -1;
496 if ( sceSifSendCmd(SIF_CMD_RPC_CALL, call, 64, sendbuf, dest_extra, ssize) == 0 )
508 sema = sif_rpc_get_sema(&sif_rpc_data);
509 cd->hdr.sema_id = sema;
512 if ( sceSifSendCmd(SIF_CMD_RPC_CALL, call, 64, sendbuf, cd->buf, ssize) )
514 WaitEventFlag(sif_rpc_data.sif_rpc_sema_ef, 1 << cd->hdr.sema_id, 0, 0);
515 ClearEventFlag(sif_rpc_data.sif_rpc_sema_ef, ~(1 << cd->hdr.sema_id));
516 sif_rpc_free_sema(&sif_rpc_data, cd->hdr.sema_id);
522 sif_rpc_free_sema(&sif_rpc_data, cd->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 qd->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 = qd;
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 = sd->next;
697 rec = (
void *)sd->func(sd->rpc_number, sd->buf, sd->size);
699 size_extra = sd->rsize;
702 if ( (rid & 4) != 0 )
703 fpacket2 = (
SifRpcRendPkt_t *)sif_rpc_get_fpacket2(&sif_rpc_data, (rid >> 16) & 0xFFFF);
709 rend->cid = SIF_CMD_RPC_CALL;
714 while ( !sceSifSendCmd(SIF_CMD_RPC_END, rend, 64, rec, sd->recvbuf, size_extra) )
725 if ( size_extra > 0 )
729 recvbuf = sd->recvbuf;
730 dmat2[0].size = size_extra;
732 dmat2[0].dest = recvbuf;
736 dmat1 = &dmat2[exsz1];
738 pkt_addr = sd->pkt_addr;
741 dmat1->dest = pkt_addr;
748 dmar = sceSifSetDma(dmat2, exsz2);
753 while ( busywait-- != -1 )
765 sd = sceSifGetNextRequest(qd);
767 sceSifExecRequest(sd);
int CpuResumeIntr(int state)
int CpuSuspendIntr(int *state)