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(
void *userdata)
230 if ( isceSifSendCmd(SIF_CMD_RPC_END, a1, 64, a1->sd, a1->buf, (
int)a1->cbuf) != 0 )
242 rec_id = data->rec_id;
243 if ( (rec_id & 4) != 0 )
244 fpacket2 = (
SifRpcRendPkt_t *)sif_rpc_get_fpacket2(harg, (rec_id >> 16) & 0xFFFF);
247 fpacket2->pkt_addr = data->pkt_addr;
249 fpacket2->cid = SIF_CMD_RPC_RDATA;
250 fpacket2->cd = recvbuf;
252 fpacket2->buf = data->dest;
253 fpacket2->cbuf = (
void *)data->size;
254 if ( !isceSifSendCmd(SIF_CMD_RPC_END, fpacket2, 64, data->src, data->dest, data->size) )
258 iSetAlarm(&clk, sif_cmd_handler_rdata_alarm_retry, fpacket2);
269 rd->hdr.pkt_addr = other;
270 rd->hdr.rpc_id = other->rpc_id;
271 other->pkt_addr = other;
278 rd->hdr.sema_id = -1;
279 if ( sceSifSendCmd(SIF_CMD_RPC_RDATA, other, 64, 0, 0, 0) == 0 )
290 sema = sif_rpc_get_sema(&sif_rpc_data);
291 rd->hdr.sema_id = sema;
294 if ( sceSifSendCmd(SIF_CMD_RPC_RDATA, other, 64, 0, 0, 0) )
296 WaitEventFlag(sif_rpc_data.sif_rpc_sema_ef, 1 << rd->hdr.sema_id, 0, 0);
297 ClearEventFlag(sif_rpc_data.sif_rpc_sema_ef, ~(1 << rd->hdr.sema_id));
298 sif_rpc_free_sema(&sif_rpc_data, rd->hdr.sema_id);
304 sif_rpc_free_sema(&sif_rpc_data, rd->hdr.sema_id);
329 if ( sd->sid == sid )
339static unsigned int sif_cmd_handler_bind_alarm_retry(
void *a1)
341 if ( isceSifSendCmd(SIF_CMD_RPC_END, a1, 64, 0, 0, 0) != 0 )
346static void sif_cmd_handler_bind(
SifRpcBindPkt_t *data, sif_rpc_data_t *harg)
354 fpacket->pkt_addr = data->pkt_addr;
356 fpacket->cid = SIF_CMD_RPC_BIND;
358 sd = sif_search_svdata(data->sid, harg);
362 fpacket->buf = sd->buf;
369 if ( !isceSifSendCmd(SIF_CMD_RPC_END, fpacket, 64, 0, 0, 0) )
373 iSetAlarm(&clk, sif_cmd_handler_bind_alarm_retry, fpacket);
386 cd->hdr.pkt_addr = bind;
387 cd->hdr.rpc_id = bind->rpc_id;
388 bind->pkt_addr = bind;
393 cd->hdr.sema_id = -1;
394 if ( sceSifSendCmd(SIF_CMD_RPC_BIND, bind, 64, 0, 0, 0) == 0 )
405 sema = sif_rpc_get_sema(&sif_rpc_data);
406 cd->hdr.sema_id = sema;
409 if ( sceSifSendCmd(SIF_CMD_RPC_BIND, bind, 64, 0, 0, 0) )
411 WaitEventFlag(sif_rpc_data.sif_rpc_sema_ef, 1 << cd->hdr.sema_id, 0, 0);
412 ClearEventFlag(sif_rpc_data.sif_rpc_sema_ef, ~(1 << cd->hdr.sema_id));
413 sif_rpc_free_sema(&sif_rpc_data, cd->hdr.sema_id);
419 sif_rpc_free_sema(&sif_rpc_data, cd->hdr.sema_id);
433static void sif_cmd_handler_call(
SifRpcCallPkt_t *data, sif_rpc_data_t *harg)
443 base->end->next = sd;
447 sd->pkt_addr = data->pkt_addr;
448 sd->client = data->cd;
449 sd->rpc_number = data->rpc_number;
450 sd->size = data->send_size;
451 sd->recvbuf = data->recvbuf;
452 sd->rsize = data->recv_size;
453 sd->rmode = data->rmode;
454 sd->rid = data->rec_id;
455 if ( base->thread_id >= 0 && !base->active )
456 iWakeupThread(base->thread_id);
467 SifRpcEndFunc_t end_function,
477 cd->hdr.pkt_addr = call;
478 rpc_id = call->rpc_id;
479 cd->end_function = end_function;
480 cd->end_param = end_param;
481 cd->hdr.rpc_id = rpc_id;
482 call->pkt_addr = call;
484 call->rpc_number = rpc_number;
485 call->send_size = ssize;
486 call->recvbuf = recvbuf;
487 call->recv_size = rsize;
488 call->sd = cd->server;
497 dest_extra = cd->buf;
498 cd->hdr.sema_id = -1;
499 if ( sceSifSendCmd(SIF_CMD_RPC_CALL, call, 64, sendbuf, dest_extra, ssize) == 0 )
511 sema = sif_rpc_get_sema(&sif_rpc_data);
512 cd->hdr.sema_id = sema;
515 if ( sceSifSendCmd(SIF_CMD_RPC_CALL, call, 64, sendbuf, cd->buf, ssize) )
517 WaitEventFlag(sif_rpc_data.sif_rpc_sema_ef, 1 << cd->hdr.sema_id, 0, 0);
518 ClearEventFlag(sif_rpc_data.sif_rpc_sema_ef, ~(1 << cd->hdr.sema_id));
519 sif_rpc_free_sema(&sif_rpc_data, cd->hdr.sema_id);
525 sif_rpc_free_sema(&sif_rpc_data, cd->hdr.sema_id);
544 return cd->hdr.pkt_addr && (int)(cd->hdr.rpc_id) == pkt_addr->rpc_id && (pkt_addr->rec_id & 2) != 0;
553 qd->thread_id = thread_id;
559 if ( sif_rpc_data.active_queue )
561 for ( queue = sif_rpc_data.active_queue; queue->next; queue = queue->next )
567 sif_rpc_data.active_queue = qd;
572void sceSifRegisterRpc(
590 for ( ; server->link; server = server->link )
611 qd->link = server1->link;
617 server2 = server1->link;
620 server1->link = server2->link;
623 server1 = server1->link;
641 queue1 = sif_rpc_data.active_queue;
642 if ( sif_rpc_data.active_queue == qd )
644 sif_rpc_data.active_queue = sif_rpc_data.active_queue->next;
646 else if ( sif_rpc_data.active_queue )
650 queue2 = queue1->next;
653 queue1->next = queue2->next;
656 queue1 = queue1->next;
675 qd->start = sd->next;
700 rec = (
void *)sd->func(sd->rpc_number, sd->buf, sd->size);
702 size_extra = sd->rsize;
705 if ( (rid & 4) != 0 )
706 fpacket2 = (
SifRpcRendPkt_t *)sif_rpc_get_fpacket2(&sif_rpc_data, (rid >> 16) & 0xFFFF);
712 rend->cid = SIF_CMD_RPC_CALL;
717 while ( !sceSifSendCmd(SIF_CMD_RPC_END, rend, 64, rec, sd->recvbuf, size_extra) )
728 if ( size_extra > 0 )
732 recvbuf = sd->recvbuf;
733 dmat2[0].size = size_extra;
735 dmat2[0].dest = recvbuf;
739 dmat1 = &dmat2[exsz1];
741 pkt_addr = sd->pkt_addr;
744 dmat1->dest = pkt_addr;
751 dmar = sceSifSetDma(dmat2, exsz2);
756 while ( busywait-- != -1 )
768 sd = sceSifGetNextRequest(qd);
770 sceSifExecRequest(sd);
int CpuResumeIntr(int state)
int CpuSuspendIntr(int *state)