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;
30
31static sif_rpc_data_t sif_rpc_data;
32static u32 init = 0;
33static u8 pkt_table[0x800];
34static u8 rdata_table[0x800];
35static u8 client_data[0x800];
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 int 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 return 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->client;
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->client;
214 client2->server = data->server;
215 client2->buff = data->buff;
216 }
217 client3 = data->client;
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(SifRpcRendPkt_t *a1)
226{
227 if ( isceSifSendCmd(SIF_CMD_RPC_END, a1, 64, a1->server, a1->buff, (int)a1->cbuff) != 0 )
228 return 0;
229 return 0xF000;
230}
231
232static void sif_cmd_handler_rdata(SifRpcOtherDataPkt_t *data, sif_rpc_data_t *harg)
233{
234 unsigned int rec_id;
235 SifRpcRendPkt_t *fpacket2;
236 SifRpcClientData_t *receive;
237 iop_sys_clock_t clk;
238
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);
242 else
243 fpacket2 = (SifRpcRendPkt_t *)sif_rpc_get_fpacket(harg);
244 fpacket2->pkt_addr = data->pkt_addr;
245 receive = (SifRpcClientData_t *)data->receive;
246 fpacket2->cid = SIF_CMD_RPC_RDATA;
247 fpacket2->client = receive;
248 fpacket2->server = (SifRpcServerData_t *)data->src;
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) )
252 {
253 clk.hi = 0;
254 clk.lo = 0xF000;
255 iSetAlarm(&clk, (unsigned int (*)(void *))sif_cmd_handler_rdata_alarm_retry, fpacket2);
256 }
257}
258
259int sceSifGetOtherData(SifRpcReceiveData_t *rd, void *src, void *dest, int size, int mode)
260{
262
263 other = (SifRpcOtherDataPkt_t *)sif_rpc_packet_get(&sif_rpc_data);
264 if ( other )
265 {
266 rd->hdr.pkt_addr = other;
267 rd->hdr.rpc_id = other->rpc_id;
268 other->pkt_addr = other;
269 other->receive = rd;
270 other->src = src;
271 other->dest = dest;
272 other->size = size;
273 if ( (mode & SIF_RPC_M_NOWAIT) != 0 )
274 {
275 rd->hdr.sema_id = -1;
276 if ( sceSifSendCmd(SIF_CMD_RPC_RDATA, other, 64, 0, 0, 0) == 0 )
277 {
278 sif_rpc_packet_free((SifRpcRendPkt_t *)other);
279 return -2;
280 }
281 return 0;
282 }
283 else
284 {
285 int sema;
286
287 sema = sif_rpc_get_sema(&sif_rpc_data);
288 rd->hdr.sema_id = sema;
289 if ( sema >= 0 )
290 {
291 if ( sceSifSendCmd(SIF_CMD_RPC_RDATA, other, 64, 0, 0, 0) )
292 {
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);
296 return 0;
297 }
298 else
299 {
300 sif_rpc_packet_free((SifRpcRendPkt_t *)other);
301 sif_rpc_free_sema(&sif_rpc_data, rd->hdr.sema_id);
302 return -2;
303 }
304 }
305 else
306 {
307 sif_rpc_packet_free((SifRpcRendPkt_t *)other);
308 return -4;
309 }
310 }
311 }
312 return -1;
313}
314
315static SifRpcServerData_t *sif_search_svdata(int sid, const sif_rpc_data_t *rpc_data)
316{
317 const SifRpcDataQueue_t *queue;
318 SifRpcServerData_t *server;
319
320 queue = rpc_data->active_queue;
321 while ( queue )
322 {
323 server = queue->link;
324 while ( server )
325 {
326 if ( server->sid == sid )
327 return server;
328 server = server->link;
329 }
330 queue = queue->next;
331 }
332
333 return NULL;
334}
335
336static unsigned int sif_cmd_handler_bind_alarm_retry(void *a1)
337{
338 if ( isceSifSendCmd(SIF_CMD_RPC_END, a1, 64, 0, 0, 0) != 0 )
339 return 0;
340 return 0xF000;
341}
342
343static void sif_cmd_handler_bind(SifRpcBindPkt_t *data, sif_rpc_data_t *harg)
344{
345 SifRpcRendPkt_t *fpacket;
346 SifRpcClientData_t *client;
347 SifRpcServerData_t *server;
348 iop_sys_clock_t clk;
349
350 fpacket = (SifRpcRendPkt_t *)sif_rpc_get_fpacket(harg);
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);
356 if ( server )
357 {
358 fpacket->server = server;
359 fpacket->buff = server->buff;
360 }
361 else
362 {
363 fpacket->server = 0;
364 fpacket->buff = 0;
365 }
366 if ( !isceSifSendCmd(SIF_CMD_RPC_END, fpacket, 64, 0, 0, 0) )
367 {
368 clk.hi = 0;
369 clk.lo = 0xF000;
370 iSetAlarm(&clk, (unsigned int (*)(void *))sif_cmd_handler_bind_alarm_retry, fpacket);
371 }
372}
373
374int sceSifBindRpc(SifRpcClientData_t *client, int rpc_number, int mode)
375{
376 SifRpcBindPkt_t *bind;
377
378 client->command = 0;
379 client->server = 0;
380 bind = (SifRpcBindPkt_t *)sif_rpc_packet_get(&sif_rpc_data);
381 if ( bind )
382 {
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;
388 if ( (mode & SIF_RPC_M_NOWAIT) != 0 )
389 {
390 client->hdr.sema_id = -1;
391 if ( sceSifSendCmd(SIF_CMD_RPC_BIND, bind, 64, 0, 0, 0) == 0 )
392 {
393 sif_rpc_packet_free((SifRpcRendPkt_t *)bind);
394 return -2;
395 }
396 return 0;
397 }
398 else
399 {
400 int sema;
401
402 sema = sif_rpc_get_sema(&sif_rpc_data);
403 client->hdr.sema_id = sema;
404 if ( sema >= 0 )
405 {
406 if ( sceSifSendCmd(SIF_CMD_RPC_BIND, bind, 64, 0, 0, 0) )
407 {
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);
411 return 0;
412 }
413 else
414 {
415 sif_rpc_packet_free((SifRpcRendPkt_t *)bind);
416 sif_rpc_free_sema(&sif_rpc_data, client->hdr.sema_id);
417 return -2;
418 }
419 }
420 else
421 {
422 sif_rpc_packet_free((SifRpcRendPkt_t *)bind);
423 return -4;
424 }
425 }
426 }
427 return -1;
428}
429
430static void sif_cmd_handler_call(SifRpcCallPkt_t *data, sif_rpc_data_t *harg)
431{
432 SifRpcServerData_t *server;
433 SifRpcDataQueue_t *base;
434
435 (void)harg;
436
437 server = data->server;
438 base = server->base;
439 if ( base->start )
440 base->end->next = server;
441 else
442 base->start = server;
443 base->end = 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);
454}
455
456int sceSifCallRpc(
457 SifRpcClientData_t *client,
458 int rpc_number,
459 int mode,
460 void *send,
461 int ssize,
462 void *receive,
463 int rsize,
464 SifRpcEndFunc_t end_function,
465 void *end_param)
466{
467 SifRpcCallPkt_t *call;
468
469 call = (SifRpcCallPkt_t *)sif_rpc_packet_get(&sif_rpc_data);
470 if ( call )
471 {
472 int rpc_id;
473
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;
486 if ( (mode & SIF_RPC_M_NOWAIT) != 0 )
487 {
488 void *dest_extra;
489
490 if ( end_function )
491 call->rmode = 1;
492 else
493 call->rmode = 0;
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 )
497 {
498 sif_rpc_packet_free((SifRpcRendPkt_t *)call);
499 return -2;
500 }
501 return 0;
502 }
503 else
504 {
505 int sema;
506
507 call->rmode = 1;
508 sema = sif_rpc_get_sema(&sif_rpc_data);
509 client->hdr.sema_id = sema;
510 if ( sema >= 0 )
511 {
512 if ( sceSifSendCmd(SIF_CMD_RPC_CALL, call, 64, send, client->buff, ssize) )
513 {
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);
517 return 0;
518 }
519 else
520 {
521 sif_rpc_packet_free((SifRpcRendPkt_t *)call);
522 sif_rpc_free_sema(&sif_rpc_data, client->hdr.sema_id);
523 return -2;
524 }
525 }
526 else
527 {
528 sif_rpc_packet_free((SifRpcRendPkt_t *)call);
529 return -4;
530 }
531 }
532 }
533 return -1;
534}
535
536int sceSifCheckStatRpc(SifRpcClientData_t *cd)
537{
538 const SifRpcPktHeader_t *pkt_addr;
539
540 pkt_addr = (SifRpcPktHeader_t *)cd->hdr.pkt_addr;
541 return cd->hdr.pkt_addr && (int)(cd->hdr.rpc_id) == pkt_addr->rpc_id && (pkt_addr->rec_id & 2) != 0;
542}
543
544SifRpcDataQueue_t *sceSifSetRpcQueue(SifRpcDataQueue_t *q, int thread_id)
545{
546 SifRpcDataQueue_t *queue;
547 int state;
548
549 CpuSuspendIntr(&state);
550 q->thread_id = thread_id;
551 q->active = 0;
552 q->link = 0;
553 q->start = 0;
554 q->end = 0;
555 q->next = 0;
556 if ( sif_rpc_data.active_queue )
557 {
558 for ( queue = sif_rpc_data.active_queue; queue->next; queue = queue->next )
559 ;
560 queue->next = q;
561 }
562 else
563 {
564 sif_rpc_data.active_queue = q;
565 }
566 return (SifRpcDataQueue_t *)CpuResumeIntr(state);
567}
568
569void sceSifRegisterRpc(
570 SifRpcServerData_t *sd, int sid, SifRpcFunc_t func, void *buf, SifRpcFunc_t cfunc, void *cbuf, SifRpcDataQueue_t *qd)
571{
572 SifRpcServerData_t *server;
573 int state;
574
575 CpuSuspendIntr(&state);
576 sd->sid = sid;
577 sd->func = func;
578 sd->buff = buf;
579 sd->next = 0;
580 sd->link = 0;
581 sd->cfunc = cfunc;
582 sd->cbuff = cbuf;
583 sd->base = qd;
584 server = qd->link;
585 if ( server )
586 {
587 for ( ; server->link; server = server->link )
588 ;
589 server->link = sd;
590 }
591 else
592 {
593 qd->link = sd;
594 }
595 CpuResumeIntr(state);
596}
597
599{
600 SifRpcServerData_t *server1;
601 const SifRpcServerData_t *server2;
602 int state;
603
604 CpuSuspendIntr(&state);
605 server1 = qd->link;
606 if ( server1 == sd )
607 {
608 qd->link = server1->link;
609 }
610 else if ( server1 )
611 {
612 while ( 1 )
613 {
614 server2 = server1->link;
615 if ( server2 == sd )
616 {
617 server1->link = server2->link;
618 break;
619 }
620 server1 = server1->link;
621 if ( !server2 )
622 {
623 break;
624 }
625 }
626 }
627 CpuResumeIntr(state);
628 return server1;
629}
630
631SifRpcDataQueue_t *sceSifRemoveRpcQueue(SifRpcDataQueue_t *qd)
632{
633 SifRpcDataQueue_t *queue1;
634 const SifRpcDataQueue_t *queue2;
635 int state;
636
637 CpuSuspendIntr(&state);
638 queue1 = sif_rpc_data.active_queue;
639 if ( sif_rpc_data.active_queue == qd )
640 {
641 sif_rpc_data.active_queue = sif_rpc_data.active_queue->next;
642 }
643 else if ( sif_rpc_data.active_queue )
644 {
645 while ( 1 )
646 {
647 queue2 = queue1->next;
648 if ( queue2 == qd )
649 {
650 queue1->next = queue2->next;
651 break;
652 }
653 queue1 = queue1->next;
654 if ( !queue2 )
655 break;
656 }
657 }
658 CpuResumeIntr(state);
659 return queue1;
660}
661
662SifRpcServerData_t *sceSifGetNextRequest(SifRpcDataQueue_t *qd)
663{
664 SifRpcServerData_t *server;
665 int state;
666
667 CpuSuspendIntr(&state);
668 server = qd->start;
669 if ( server )
670 {
671 qd->active = 1;
672 qd->start = server->next;
673 }
674 else
675 {
676 qd->active = 0;
677 }
678 CpuResumeIntr(state);
679 return server;
680}
681
682void sceSifExecRequest(SifRpcServerData_t *srv)
683{
684 int size_extra;
685 void *rec;
686 unsigned int rid;
687 SifRpcRendPkt_t *fpacket2;
688 SifRpcRendPkt_t *rend;
689 SifRpcClientData_t *client;
690 int exsz;
691 void *receive;
692 void *pkt_addr;
693 SifDmaTransfer_t dmat2[2];
694 int state[2];
695
696 size_extra = 0;
697 rec = (void *)srv->func(srv->rpc_number, srv->buff, srv->size);
698 if ( rec )
699 size_extra = srv->rsize;
700 CpuSuspendIntr(state);
701 rid = srv->rid;
702 if ( (rid & 4) != 0 )
703 fpacket2 = (SifRpcRendPkt_t *)sif_rpc_get_fpacket2(&sif_rpc_data, (rid >> 16) & 0xFFFF);
704 else
705 fpacket2 = (SifRpcRendPkt_t *)sif_rpc_get_fpacket(&sif_rpc_data);
706 rend = fpacket2;
707 CpuResumeIntr(state[0]);
708 client = srv->client;
709 rend->cid = SIF_CMD_RPC_CALL;
710 rend->client = client;
711 exsz = 0;
712 if ( srv->rmode )
713 {
714 while ( !sceSifSendCmd(SIF_CMD_RPC_END, rend, 64, rec, srv->receive, size_extra) )
715 ;
716 }
717 else
718 {
719 int exsz1;
720 int exsz2;
721 SifDmaTransfer_t *dmat1;
722
723 rend->rpc_id = 0;
724 rend->rec_id = 0;
725 if ( size_extra > 0 )
726 {
727 exsz = 1;
728 dmat2[0].src = rec;
729 receive = srv->receive;
730 dmat2[0].size = size_extra;
731 dmat2[0].attr = 0;
732 dmat2[0].dest = receive;
733 }
734 exsz1 = exsz;
735 exsz2 = exsz + 1;
736 dmat1 = &dmat2[exsz1];
737 dmat1->src = rend;
738 pkt_addr = srv->pkt_addr;
739 dmat1->size = 64;
740 dmat1->attr = 0;
741 dmat1->dest = pkt_addr;
742 while ( 1 )
743 {
744 int dmar;
745 int busywait;
746
747 CpuSuspendIntr(state);
748 dmar = sceSifSetDma(dmat2, exsz2);
749 CpuResumeIntr(state[0]);
750 if ( dmar )
751 break;
752 busywait = 0xFFFE;
753 while ( busywait-- != -1 )
754 ;
755 }
756 }
757}
758
759void sceSifRpcLoop(SifRpcDataQueue_t *qd)
760{
761 while ( 1 )
762 {
763 SifRpcServerData_t *server;
764
765 server = sceSifGetNextRequest(qd);
766 if ( server )
767 sceSifExecRequest(server);
768 else
769 SleepThread();
770 }
771}
#define SIF_RPC_M_NOWAIT
Definition sifrpc.h:24
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205
#define EA_MULTI
Definition thevent.h:35