PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
sifrpc.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include "irx_imports.h"
12#include "sifcmd.h"
13
14typedef struct sif_rpc_data_
15{
16 int pid;
17 void *pkt_table;
18 int pkt_table_len;
19 int unused1;
20 int unused2;
21 u8 *rdata_table;
22 int rdata_table_len;
23 u8 *client_table;
24 int client_table_len;
25 int rdata_table_idx;
26 SifRpcDataQueue_t *active_queue;
27 int sif_rpc_sema_ef;
28 int used_sema_bitfield;
29} __attribute__((aligned(16))) sif_rpc_data_t;
30
31static sif_rpc_data_t sif_rpc_data;
32static u32 init = 0;
33static u8 pkt_table[0x800] __attribute__((aligned(16)));
34static u8 rdata_table[0x800] __attribute__((aligned(16)));
35static u8 client_data[0x800] __attribute__((aligned(16)));
36
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);
40static void sif_cmd_handler_rdata(SifRpcOtherDataPkt_t *data, sif_rpc_data_t *harg);
41
42void sceSifInitRpc(int mode)
43{
44 int SystemStatusFlag;
45 iop_event_t efp;
46 int state;
47
48 (void)mode;
49
50 sceSifInitCmd();
51 CpuSuspendIntr(&state);
52 if ( init )
53 {
54 CpuResumeIntr(state);
55 }
56 else
57 {
58 sif_rpc_data.rdata_table = (u8 *)rdata_table;
59 init = 1;
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;
68 sif_rpc_data.pid = 1;
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);
73 efp.attr = EA_MULTI;
74 efp.bits = 0;
75 sif_rpc_data.sif_rpc_sema_ef = CreateEventFlag(&efp);
76 sif_rpc_data.used_sema_bitfield = 0;
77 CpuResumeIntr(state);
78 pkt_table[4] = 0;
79 pkt_table[5] = 1;
80 sceSifSendCmd(SIF_CMD_SET_SREG, pkt_table, 24, 0, 0, 0);
81 }
82 SystemStatusFlag = GetSystemStatusFlag();
83 WaitEventFlag(SystemStatusFlag, 0x800u, 0, 0);
84}
85
86static int sif_rpc_get_sema(sif_rpc_data_t *rpc_data)
87{
88 int i;
89 int state;
90
91 CpuSuspendIntr(&state);
92 for ( i = 0; i < 32; ++i )
93 {
94 int used_sema_bitfield;
95
96 used_sema_bitfield = rpc_data->used_sema_bitfield;
97 if ( (used_sema_bitfield & ((u32)1 << i)) == 0 )
98 {
99 rpc_data->used_sema_bitfield = used_sema_bitfield | (1 << i);
100 CpuResumeIntr(state);
101 return i;
102 }
103 }
104 CpuResumeIntr(state);
105 return -1;
106}
107
108static void sif_rpc_free_sema(sif_rpc_data_t *rpc_data, char sema_id)
109{
110 int state;
111
112 CpuSuspendIntr(&state);
113 rpc_data->used_sema_bitfield &= ~(1 << sema_id);
114 CpuResumeIntr(state);
115}
116
117static SifRpcPktHeader_t *sif_rpc_packet_get(sif_rpc_data_t *rpc_data)
118{
119 SifRpcPktHeader_t *pkt_table_0;
120 int i;
121 int state;
122
123 CpuSuspendIntr(&state);
124 pkt_table_0 = (SifRpcPktHeader_t *)rpc_data->pkt_table;
125 i = 0;
126 if ( rpc_data->pkt_table_len <= 0 )
127 {
128 CpuResumeIntr(state);
129 return 0;
130 }
131 else
132 {
133 void **p_pkt_addr;
134 int pid;
135 int pid_1_tmp;
136
137 p_pkt_addr = &pkt_table_0->pkt_addr;
138 while ( ((unsigned int)*(p_pkt_addr - 1) & 2) != 0 )
139 {
140 ++i;
141 p_pkt_addr += 16;
142 pkt_table_0 = (SifRpcPktHeader_t *)((char *)pkt_table_0 + 64);
143 if ( i >= rpc_data->pkt_table_len )
144 {
145 CpuResumeIntr(state);
146 return 0;
147 }
148 }
149 *(p_pkt_addr - 1) = (void *)((i << 16) | 6);
150 pid = rpc_data->pid;
151 pid_1_tmp = rpc_data->pid + 1;
152 rpc_data->pid = pid_1_tmp;
153 if ( pid_1_tmp == 1 )
154 {
155 pid_1_tmp = 1;
156 rpc_data->pid = pid + 2;
157 }
158 p_pkt_addr[1] = (void *)pid_1_tmp;
159 *p_pkt_addr = pkt_table_0;
160 CpuResumeIntr(state);
161 return pkt_table_0;
162 }
163}
164
165static void sif_rpc_packet_free(SifRpcRendPkt_t *pkt)
166{
167 pkt->rpc_id = 0;
168 pkt->rec_id &= 0xFFFFFFFD;
169}
170
171static void *sif_rpc_get_fpacket(sif_rpc_data_t *rpc_data)
172{
173 int rdata_table_idx;
174 int rdata_table_len;
175 int index_calc;
176
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 )
181 __builtin_trap();
182 rpc_data->rdata_table_idx = index_calc + 1;
183 return &rpc_data->rdata_table[64 * index_calc];
184}
185
186static void *sif_rpc_get_fpacket2(sif_rpc_data_t *rpc_data, int rid)
187{
188 if ( rid >= 0 && rid < rpc_data->client_table_len )
189 return &rpc_data->client_table[64 * rid];
190 else
191 return sif_rpc_get_fpacket(rpc_data);
192}
193
194static void sif_cmd_handler_end(SifRpcRendPkt_t *data, sif_rpc_data_t *harg)
195{
196 u32 cid;
197 SifRpcClientData_t *client1;
198 SifRpcEndFunc_t end_function;
199 SifRpcClientData_t *client2;
200 SifRpcClientData_t *client3;
201 int sema_id;
202
203 cid = data->cid;
204 if ( cid == SIF_CMD_RPC_CALL )
205 {
206 client1 = data->cd;
207 end_function = client1->end_function;
208 if ( end_function )
209 end_function(client1->end_param);
210 }
211 else if ( cid == SIF_CMD_RPC_BIND )
212 {
213 client2 = data->cd;
214 client2->server = data->sd;
215 client2->buf = data->buf;
216 }
217 client3 = data->cd;
218 sema_id = client3->hdr.sema_id;
219 if ( sema_id >= 0 )
220 iSetEventFlag(harg->sif_rpc_sema_ef, 1 << sema_id);
221 sif_rpc_packet_free((SifRpcRendPkt_t *)client3->hdr.pkt_addr);
222 client3->hdr.pkt_addr = 0;
223}
224
225static unsigned int sif_cmd_handler_rdata_alarm_retry(void *userdata)
226{
227 SifRpcRendPkt_t *a1;
228
229 a1 = (SifRpcRendPkt_t *)userdata;
230 if ( isceSifSendCmd(SIF_CMD_RPC_END, a1, 64, a1->sd, a1->buf, (int)a1->cbuf) != 0 )
231 return 0;
232 return 0xF000;
233}
234
235static void sif_cmd_handler_rdata(SifRpcOtherDataPkt_t *data, sif_rpc_data_t *harg)
236{
237 unsigned int rec_id;
238 SifRpcRendPkt_t *fpacket2;
239 SifRpcClientData_t *recvbuf;
240 iop_sys_clock_t clk;
241
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);
245 else
246 fpacket2 = (SifRpcRendPkt_t *)sif_rpc_get_fpacket(harg);
247 fpacket2->pkt_addr = data->pkt_addr;
248 recvbuf = (SifRpcClientData_t *)data->recvbuf;
249 fpacket2->cid = SIF_CMD_RPC_RDATA;
250 fpacket2->cd = recvbuf;
251 fpacket2->sd = (SifRpcServerData_t *)data->src;
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) )
255 {
256 clk.hi = 0;
257 clk.lo = 0xF000;
258 iSetAlarm(&clk, sif_cmd_handler_rdata_alarm_retry, fpacket2);
259 }
260}
261
262int sceSifGetOtherData(SifRpcReceiveData_t *rd, void *src, void *dest, int size, int mode)
263{
265
266 other = (SifRpcOtherDataPkt_t *)sif_rpc_packet_get(&sif_rpc_data);
267 if ( other )
268 {
269 rd->hdr.pkt_addr = other;
270 rd->hdr.rpc_id = other->rpc_id;
271 other->pkt_addr = other;
272 other->recvbuf = rd;
273 other->src = src;
274 other->dest = dest;
275 other->size = size;
276 if ( (mode & SIF_RPC_M_NOWAIT) != 0 )
277 {
278 rd->hdr.sema_id = -1;
279 if ( sceSifSendCmd(SIF_CMD_RPC_RDATA, other, 64, 0, 0, 0) == 0 )
280 {
281 sif_rpc_packet_free((SifRpcRendPkt_t *)other);
282 return -2;
283 }
284 return 0;
285 }
286 else
287 {
288 int sema;
289
290 sema = sif_rpc_get_sema(&sif_rpc_data);
291 rd->hdr.sema_id = sema;
292 if ( sema >= 0 )
293 {
294 if ( sceSifSendCmd(SIF_CMD_RPC_RDATA, other, 64, 0, 0, 0) )
295 {
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);
299 return 0;
300 }
301 else
302 {
303 sif_rpc_packet_free((SifRpcRendPkt_t *)other);
304 sif_rpc_free_sema(&sif_rpc_data, rd->hdr.sema_id);
305 return -2;
306 }
307 }
308 else
309 {
310 sif_rpc_packet_free((SifRpcRendPkt_t *)other);
311 return -4;
312 }
313 }
314 }
315 return -1;
316}
317
318static SifRpcServerData_t *sif_search_svdata(int sid, const sif_rpc_data_t *rpc_data)
319{
320 const SifRpcDataQueue_t *queue;
322
323 queue = rpc_data->active_queue;
324 while ( queue )
325 {
326 sd = queue->link;
327 while ( sd )
328 {
329 if ( sd->sid == sid )
330 return sd;
331 sd = sd->link;
332 }
333 queue = queue->next;
334 }
335
336 return NULL;
337}
338
339static unsigned int sif_cmd_handler_bind_alarm_retry(void *a1)
340{
341 if ( isceSifSendCmd(SIF_CMD_RPC_END, a1, 64, 0, 0, 0) != 0 )
342 return 0;
343 return 0xF000;
344}
345
346static void sif_cmd_handler_bind(SifRpcBindPkt_t *data, sif_rpc_data_t *harg)
347{
348 SifRpcRendPkt_t *fpacket;
351 iop_sys_clock_t clk;
352
353 fpacket = (SifRpcRendPkt_t *)sif_rpc_get_fpacket(harg);
354 fpacket->pkt_addr = data->pkt_addr;
355 cd = data->cd;
356 fpacket->cid = SIF_CMD_RPC_BIND;
357 fpacket->cd = cd;
358 sd = sif_search_svdata(data->sid, harg);
359 if ( sd )
360 {
361 fpacket->sd = sd;
362 fpacket->buf = sd->buf;
363 }
364 else
365 {
366 fpacket->sd = 0;
367 fpacket->buf = 0;
368 }
369 if ( !isceSifSendCmd(SIF_CMD_RPC_END, fpacket, 64, 0, 0, 0) )
370 {
371 clk.hi = 0;
372 clk.lo = 0xF000;
373 iSetAlarm(&clk, sif_cmd_handler_bind_alarm_retry, fpacket);
374 }
375}
376
377int sceSifBindRpc(SifRpcClientData_t *cd, int sid, int mode)
378{
379 SifRpcBindPkt_t *bind;
380
381 cd->command = 0;
382 cd->server = 0;
383 bind = (SifRpcBindPkt_t *)sif_rpc_packet_get(&sif_rpc_data);
384 if ( bind )
385 {
386 cd->hdr.pkt_addr = bind;
387 cd->hdr.rpc_id = bind->rpc_id;
388 bind->pkt_addr = bind;
389 bind->cd = cd;
390 bind->sid = sid;
391 if ( (mode & SIF_RPC_M_NOWAIT) != 0 )
392 {
393 cd->hdr.sema_id = -1;
394 if ( sceSifSendCmd(SIF_CMD_RPC_BIND, bind, 64, 0, 0, 0) == 0 )
395 {
396 sif_rpc_packet_free((SifRpcRendPkt_t *)bind);
397 return -2;
398 }
399 return 0;
400 }
401 else
402 {
403 int sema;
404
405 sema = sif_rpc_get_sema(&sif_rpc_data);
406 cd->hdr.sema_id = sema;
407 if ( sema >= 0 )
408 {
409 if ( sceSifSendCmd(SIF_CMD_RPC_BIND, bind, 64, 0, 0, 0) )
410 {
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);
414 return 0;
415 }
416 else
417 {
418 sif_rpc_packet_free((SifRpcRendPkt_t *)bind);
419 sif_rpc_free_sema(&sif_rpc_data, cd->hdr.sema_id);
420 return -2;
421 }
422 }
423 else
424 {
425 sif_rpc_packet_free((SifRpcRendPkt_t *)bind);
426 return -4;
427 }
428 }
429 }
430 return -1;
431}
432
433static void sif_cmd_handler_call(SifRpcCallPkt_t *data, sif_rpc_data_t *harg)
434{
436 SifRpcDataQueue_t *base;
437
438 (void)harg;
439
440 sd = data->sd;
441 base = sd->base;
442 if ( base->start )
443 base->end->next = sd;
444 else
445 base->start = sd;
446 base->end = 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);
457}
458
459int sceSifCallRpc(
461 int rpc_number,
462 int mode,
463 void *sendbuf,
464 int ssize,
465 void *recvbuf,
466 int rsize,
467 SifRpcEndFunc_t end_function,
468 void *end_param)
469{
470 SifRpcCallPkt_t *call;
471
472 call = (SifRpcCallPkt_t *)sif_rpc_packet_get(&sif_rpc_data);
473 if ( call )
474 {
475 int rpc_id;
476
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;
483 call->cd = cd;
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;
489 if ( (mode & SIF_RPC_M_NOWAIT) != 0 )
490 {
491 void *dest_extra;
492
493 if ( end_function )
494 call->rmode = 1;
495 else
496 call->rmode = 0;
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 )
500 {
501 sif_rpc_packet_free((SifRpcRendPkt_t *)call);
502 return -2;
503 }
504 return 0;
505 }
506 else
507 {
508 int sema;
509
510 call->rmode = 1;
511 sema = sif_rpc_get_sema(&sif_rpc_data);
512 cd->hdr.sema_id = sema;
513 if ( sema >= 0 )
514 {
515 if ( sceSifSendCmd(SIF_CMD_RPC_CALL, call, 64, sendbuf, cd->buf, ssize) )
516 {
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);
520 return 0;
521 }
522 else
523 {
524 sif_rpc_packet_free((SifRpcRendPkt_t *)call);
525 sif_rpc_free_sema(&sif_rpc_data, cd->hdr.sema_id);
526 return -2;
527 }
528 }
529 else
530 {
531 sif_rpc_packet_free((SifRpcRendPkt_t *)call);
532 return -4;
533 }
534 }
535 }
536 return -1;
537}
538
539int sceSifCheckStatRpc(SifRpcClientData_t *cd)
540{
541 const SifRpcPktHeader_t *pkt_addr;
542
543 pkt_addr = (SifRpcPktHeader_t *)cd->hdr.pkt_addr;
544 return cd->hdr.pkt_addr && (int)(cd->hdr.rpc_id) == pkt_addr->rpc_id && (pkt_addr->rec_id & 2) != 0;
545}
546
547void sceSifSetRpcQueue(SifRpcDataQueue_t *qd, int thread_id)
548{
549 SifRpcDataQueue_t *queue;
550 int state;
551
552 CpuSuspendIntr(&state);
553 qd->thread_id = thread_id;
554 qd->active = 0;
555 qd->link = 0;
556 qd->start = 0;
557 qd->end = 0;
558 qd->next = 0;
559 if ( sif_rpc_data.active_queue )
560 {
561 for ( queue = sif_rpc_data.active_queue; queue->next; queue = queue->next )
562 ;
563 queue->next = qd;
564 }
565 else
566 {
567 sif_rpc_data.active_queue = qd;
568 }
569 CpuResumeIntr(state);
570}
571
572void sceSifRegisterRpc(
573 SifRpcServerData_t *sd, int sid, SifRpcFunc_t func, void *buf, SifRpcFunc_t cfunc, void *cbuf, SifRpcDataQueue_t *qd)
574{
575 SifRpcServerData_t *server;
576 int state;
577
578 CpuSuspendIntr(&state);
579 sd->sid = sid;
580 sd->func = func;
581 sd->buf = buf;
582 sd->next = 0;
583 sd->link = 0;
584 sd->cfunc = cfunc;
585 sd->cbuf = cbuf;
586 sd->base = qd;
587 server = qd->link;
588 if ( server )
589 {
590 for ( ; server->link; server = server->link )
591 ;
592 server->link = sd;
593 }
594 else
595 {
596 qd->link = sd;
597 }
598 CpuResumeIntr(state);
599}
600
602{
603 SifRpcServerData_t *server1;
604 const SifRpcServerData_t *server2;
605 int state;
606
607 CpuSuspendIntr(&state);
608 server1 = qd->link;
609 if ( server1 == sd )
610 {
611 qd->link = server1->link;
612 }
613 else if ( server1 )
614 {
615 while ( 1 )
616 {
617 server2 = server1->link;
618 if ( server2 == sd )
619 {
620 server1->link = server2->link;
621 break;
622 }
623 server1 = server1->link;
624 if ( !server2 )
625 {
626 break;
627 }
628 }
629 }
630 CpuResumeIntr(state);
631 return server1;
632}
633
634SifRpcDataQueue_t *sceSifRemoveRpcQueue(SifRpcDataQueue_t *qd)
635{
636 SifRpcDataQueue_t *queue1;
637 const SifRpcDataQueue_t *queue2;
638 int state;
639
640 CpuSuspendIntr(&state);
641 queue1 = sif_rpc_data.active_queue;
642 if ( sif_rpc_data.active_queue == qd )
643 {
644 sif_rpc_data.active_queue = sif_rpc_data.active_queue->next;
645 }
646 else if ( sif_rpc_data.active_queue )
647 {
648 while ( 1 )
649 {
650 queue2 = queue1->next;
651 if ( queue2 == qd )
652 {
653 queue1->next = queue2->next;
654 break;
655 }
656 queue1 = queue1->next;
657 if ( !queue2 )
658 break;
659 }
660 }
661 CpuResumeIntr(state);
662 return queue1;
663}
664
665SifRpcServerData_t *sceSifGetNextRequest(SifRpcDataQueue_t *qd)
666{
668 int state;
669
670 CpuSuspendIntr(&state);
671 sd = qd->start;
672 if ( sd )
673 {
674 qd->active = 1;
675 qd->start = sd->next;
676 }
677 else
678 {
679 qd->active = 0;
680 }
681 CpuResumeIntr(state);
682 return sd;
683}
684
685void sceSifExecRequest(SifRpcServerData_t *sd)
686{
687 int size_extra;
688 void *rec;
689 unsigned int rid;
690 SifRpcRendPkt_t *fpacket2;
691 SifRpcRendPkt_t *rend;
693 int exsz;
694 void *recvbuf;
695 void *pkt_addr;
696 SifDmaTransfer_t dmat2[2];
697 int state[2];
698
699 size_extra = 0;
700 rec = (void *)sd->func(sd->rpc_number, sd->buf, sd->size);
701 if ( rec )
702 size_extra = sd->rsize;
703 CpuSuspendIntr(state);
704 rid = sd->rid;
705 if ( (rid & 4) != 0 )
706 fpacket2 = (SifRpcRendPkt_t *)sif_rpc_get_fpacket2(&sif_rpc_data, (rid >> 16) & 0xFFFF);
707 else
708 fpacket2 = (SifRpcRendPkt_t *)sif_rpc_get_fpacket(&sif_rpc_data);
709 rend = fpacket2;
710 CpuResumeIntr(state[0]);
711 cd = sd->client;
712 rend->cid = SIF_CMD_RPC_CALL;
713 rend->cd = cd;
714 exsz = 0;
715 if ( sd->rmode )
716 {
717 while ( !sceSifSendCmd(SIF_CMD_RPC_END, rend, 64, rec, sd->recvbuf, size_extra) )
718 ;
719 }
720 else
721 {
722 int exsz1;
723 int exsz2;
724 SifDmaTransfer_t *dmat1;
725
726 rend->rpc_id = 0;
727 rend->rec_id = 0;
728 if ( size_extra > 0 )
729 {
730 exsz = 1;
731 dmat2[0].src = rec;
732 recvbuf = sd->recvbuf;
733 dmat2[0].size = size_extra;
734 dmat2[0].attr = 0;
735 dmat2[0].dest = recvbuf;
736 }
737 exsz1 = exsz;
738 exsz2 = exsz + 1;
739 dmat1 = &dmat2[exsz1];
740 dmat1->src = rend;
741 pkt_addr = sd->pkt_addr;
742 dmat1->size = 64;
743 dmat1->attr = 0;
744 dmat1->dest = pkt_addr;
745 while ( 1 )
746 {
747 int dmar;
748 int busywait;
749
750 CpuSuspendIntr(state);
751 dmar = sceSifSetDma(dmat2, exsz2);
752 CpuResumeIntr(state[0]);
753 if ( dmar )
754 break;
755 busywait = 0xFFFE;
756 while ( busywait-- != -1 )
757 ;
758 }
759 }
760}
761
762void sceSifRpcLoop(SifRpcDataQueue_t *qd)
763{
764 while ( 1 )
765 {
767
768 sd = sceSifGetNextRequest(qd);
769 if ( sd )
770 sceSifExecRequest(sd);
771 else
772 SleepThread();
773 }
774}
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205
typedef __attribute__
Definition tlbfunc.c:60
#define SIF_RPC_M_NOWAIT
#define EA_MULTI
Definition thevent.h:35