26#define RPC_PACKET_SIZE 64
29#define PACKET_F_ALLOC 0x01
31static inline void rpc_packet_free(
void *packet)
33 SifRpcRendPkt_t *rendpkt = (SifRpcRendPkt_t *)packet;
61 SifRpcPktHeader_t *packet;
69 packet = (SifRpcPktHeader_t *)
rpc_data->pkt_table;
71 for (rid = 0; rid < len; rid++, packet = (SifRpcPktHeader_t *)(((
unsigned char *)packet) + RPC_PACKET_SIZE)) {
90 packet->pkt_addr = packet;
103 rpc_data->rdata_table_idx = index + 1;
105 return (
void *)(
rpc_data->rdata_table + (index * RPC_PACKET_SIZE));
108int sceSifBindRpc(SifRpcClientData_t *cd,
int sid,
int mode)
111 SifRpcBindPkt_t *bind;
113 bind = (SifRpcBindPkt_t *)_rpc_get_packet(&_sif_rpc_data);
119 cd->hdr.pkt_addr = bind;
120 cd->hdr.rpc_id = bind->rpc_id;
121 cd->hdr.sema_id = -1;
124 bind->pkt_addr = bind;
128 if (!sceSifSendCmd(SIF_CMD_RPC_BIND, bind, RPC_PACKET_SIZE, NULL, NULL, 0)) {
129 rpc_packet_free(bind);
138 cd->hdr.sema_id = CreateSema(&sema);
139 if (cd->hdr.sema_id < 0) {
140 rpc_packet_free(bind);
144 if (!sceSifSendCmd(SIF_CMD_RPC_BIND, bind, RPC_PACKET_SIZE, NULL, NULL, 0)) {
145 rpc_packet_free(bind);
146 DeleteSema(cd->hdr.sema_id);
150 WaitSema(cd->hdr.sema_id);
151 DeleteSema(cd->hdr.sema_id);
156int sceSifCallRpc(SifRpcClientData_t *cd,
int rpc_number,
int mode,
void *sendbuf,
157 int ssize,
void *recvbuf,
int rsize, SifRpcEndFunc_t end_function,
void *end_param)
160 SifRpcCallPkt_t *call;
162 call = (SifRpcCallPkt_t *)_rpc_get_packet(&_sif_rpc_data);
166 cd->hdr.pkt_addr = call;
167 cd->hdr.rpc_id = call->rpc_id;
168 cd->hdr.sema_id = -1;
169 cd->end_function = end_function;
170 cd->end_param = end_param;
172 call->rpc_number = rpc_number;
173 call->send_size = ssize;
174 call->recvbuf = recvbuf;
175 call->recv_size = rsize;
177 call->pkt_addr = call;
179 call->sd = cd->server;
183 sceSifWriteBackDCache(sendbuf, ssize);
185 sceSifWriteBackDCache(recvbuf, rsize);
192 if (!sceSifSendCmd(SIF_CMD_RPC_CALL, call, RPC_PACKET_SIZE, sendbuf, cd->buf, ssize)) {
193 rpc_packet_free(call);
202 cd->hdr.sema_id = CreateSema(&sema);
203 if (cd->hdr.sema_id < 0) {
204 rpc_packet_free(call);
208 if (!sceSifSendCmd(SIF_CMD_RPC_CALL, call, RPC_PACKET_SIZE, sendbuf, cd->buf, ssize)) {
209 rpc_packet_free(call);
210 DeleteSema(cd->hdr.sema_id);
214 WaitSema(cd->hdr.sema_id);
215 DeleteSema(cd->hdr.sema_id);
220int sceSifGetOtherData(SifRpcReceiveData_t *rd,
void *src,
void *dest,
int size,
int mode)
223 SifRpcOtherDataPkt_t *other;
225 other = (SifRpcOtherDataPkt_t *)_rpc_get_packet(&_sif_rpc_data);
229 rd->hdr.pkt_addr = other;
230 rd->hdr.rpc_id = other->rpc_id;
231 rd->hdr.sema_id = -1;
239 if (!sceSifSendCmd(SIF_CMD_RPC_RDATA, other, RPC_PACKET_SIZE, NULL, NULL, 0)) {
240 rpc_packet_free(other);
249 rd->hdr.sema_id = CreateSema(&sema);
250 if (rd->hdr.sema_id < 0) {
251 rpc_packet_free(other);
255 if (!sceSifSendCmd(SIF_CMD_RPC_RDATA, other, RPC_PACKET_SIZE, NULL, NULL, 0)) {
256 rpc_packet_free(other);
257 DeleteSema(rd->hdr.sema_id);
261 WaitSema(rd->hdr.sema_id);
262 DeleteSema(rd->hdr.sema_id);
269static u8 pkt_table[32][RPC_PACKET_SIZE]
__attribute__((aligned(64)));
271static u8 rdata_table[32][RPC_PACKET_SIZE]
__attribute__((aligned(64)));
272static u8 client_table[32][RPC_PACKET_SIZE]
__attribute__((aligned(64)));
280static void _request_end(SifRpcRendPkt_t *
request,
void *data)
282 SifRpcClientData_t *cd =
request->cd;
286 if (
request->cid == SIF_CMD_RPC_CALL) {
287 if (cd->end_function)
288 cd->end_function(cd->end_param);
289 }
else if (
request->cid == SIF_CMD_RPC_BIND) {
295 if (cd->hdr.sema_id >= 0)
296 iSignalSema(cd->hdr.sema_id);
298 rpc_packet_free(cd->hdr.pkt_addr);
299 cd->hdr.pkt_addr = NULL;
304 SifRpcServerData_t *sd;
305 SifRpcDataQueue_t *queue =
rpc_data->active_queue;
313 if ((u32)(sd->sid) == sid)
326static void _request_bind(SifRpcBindPkt_t *bind,
void *data)
328 SifRpcRendPkt_t *rend;
329 SifRpcServerData_t *sd;
331 rend = _rpc_get_fpacket(data);
332 rend->pkt_addr = bind->pkt_addr;
334 rend->cid = SIF_CMD_RPC_BIND;
336 sd = search_svdata(bind->sid, data);
344 rend->cbuf = sd->cbuf;
347 isceSifSendCmd(SIF_CMD_RPC_END, rend, RPC_PACKET_SIZE, NULL, NULL, 0);
351static void _request_call(SifRpcCallPkt_t *
request,
void *data)
353 SifRpcServerData_t *sd =
request->sd;
354 SifRpcDataQueue_t *base = sd->base;
359 base->end->next = sd;
364 sd->pkt_addr =
request->pkt_addr;
366 sd->rpc_number =
request->rpc_number;
368 sd->recvbuf =
request->recvbuf;
369 sd->rsize =
request->recv_size;
373 if (base->thread_id < 0 || base->active != 0)
376 iWakeupThread(base->thread_id);
380static void _request_rdata(SifRpcOtherDataPkt_t *rdata,
void *data)
382 SifRpcRendPkt_t *rend;
384 rend = (SifRpcRendPkt_t *)_rpc_get_fpacket(data);
385 rend->pkt_addr = rdata->pkt_addr;
386 rend->cd = (SifRpcClientData_t *)rdata->recvbuf;
387 rend->cid = SIF_CMD_RPC_RDATA;
389 isceSifSendCmd(SIF_CMD_RPC_END, rend, RPC_PACKET_SIZE, rdata->src, rdata->dest, rdata->size);
392void sceSifInitRpc(
int mode)
398 if (HasIopRebootedSinceLastCall()) {
409 _sif_rpc_data.pid = 1;
411 _sif_rpc_data.pkt_table = UNCACHED_SEG(pkt_table);
412 _sif_rpc_data.pkt_table_len =
sizeof(pkt_table) /
sizeof(pkt_table[0]);
413 _sif_rpc_data.rdata_table = UNCACHED_SEG(rdata_table);
414 _sif_rpc_data.rdata_table_len =
sizeof(rdata_table) /
sizeof(rdata_table[0]);
415 _sif_rpc_data.client_table = UNCACHED_SEG(client_table);
416 _sif_rpc_data.client_table_len =
sizeof(client_table) /
sizeof(client_table[0]);
418 _sif_rpc_data.rdata_table_idx = 0;
424 SifRpcPktHeader_t *packet = (SifRpcPktHeader_t *)
rpc_data->pkt_table;
426 for (rid = 0; rid < len; rid++, packet = (SifRpcPktHeader_t *)(((
unsigned char *)packet) + RPC_PACKET_SIZE)) {
427 rpc_packet_free(packet);
431 sceSifAddCmdHandler(SIF_CMD_RPC_END, (
void *)_request_end, &_sif_rpc_data);
432 sceSifAddCmdHandler(SIF_CMD_RPC_BIND, (
void *)_request_bind, &_sif_rpc_data);
433 sceSifAddCmdHandler(SIF_CMD_RPC_CALL, (
void *)_request_call, &_sif_rpc_data);
434 sceSifAddCmdHandler(SIF_CMD_RPC_RDATA, (
void *)_request_rdata, &_sif_rpc_data);
437 if (sceSifGetReg(SIF_SYSREG_RPCINIT))
440 cmdp = (u32 *)&((u8 *)_sif_rpc_data.pkt_table)[64];
442 sceSifSendCmd(SIF_CMD_INIT_CMD, cmdp, 16, NULL, NULL, 0);
446 sceSifSetReg(SIF_SYSREG_RPCINIT, 1);
449void sceSifExitRpc(
void)
455void sceSifRegisterRpc(SifRpcServerData_t *sd,
int sid, SifRpcFunc_t func,
void *buf,
456 SifRpcFunc_t cfunc,
void *cbuf, SifRpcDataQueue_t *qd)
458 SifRpcServerData_t *server;
471 if (!(server = qd->link)) {
474 while (server->link != NULL) {
475 server = server->link;
484SifRpcServerData_t *sceSifRemoveRpc(SifRpcServerData_t *sd, SifRpcDataQueue_t *qd)
486 SifRpcServerData_t *server;
490 if ((server = qd->link) == sd) {
491 qd->link = server->link;
493 while (server != NULL) {
494 if (server->link == sd) {
495 server->link = sd->link;
499 server = server->link;
508void sceSifSetRpcQueue(SifRpcDataQueue_t *qd,
int thread_id)
510 SifRpcDataQueue_t *queue = NULL;
514 qd->thread_id = thread_id;
521 if (_sif_rpc_data.active_queue == NULL) {
522 _sif_rpc_data.active_queue = qd;
524 queue = _sif_rpc_data.active_queue;
526 while (queue->next != NULL)
535SifRpcDataQueue_t *sceSifRemoveRpcQueue(SifRpcDataQueue_t *qd)
537 SifRpcDataQueue_t *queue;
541 if ((queue = _sif_rpc_data.active_queue) == qd) {
542 _sif_rpc_data.active_queue = queue->next;
544 while (queue != NULL) {
545 if (queue->next == qd) {
546 queue->next = qd->next;
559SifRpcServerData_t *sceSifGetNextRequest(SifRpcDataQueue_t *qd)
561 SifRpcServerData_t *sd;
568 qd->start = sd->next;
580 if (rid < 0 || rid < rpc_data->client_table_len)
583 return rpc_data->client_table + (rid * RPC_PACKET_SIZE);
585void sceSifExecRequest(SifRpcServerData_t *sd)
587 SifDmaTransfer_t dmat;
588 SifRpcRendPkt_t *rend;
591 rec = sd->func(sd->rpc_number, sd->buf, sd->size);
594 sceSifWriteBackDCache(sd->buf, sd->size);
597 sceSifWriteBackDCache(rec, sd->rsize);
602 rend = (SifRpcRendPkt_t *)
603 _rpc_get_fpacket2(&_sif_rpc_data, (sd->rid >> 16) & 0xffff);
605 rend = (SifRpcRendPkt_t *)
606 _rpc_get_fpacket(&_sif_rpc_data);
610 rend->cd = sd->client;
611 rend->cid = SIF_CMD_RPC_CALL;
614 if (!sceSifSendCmd(SIF_CMD_RPC_END, rend, RPC_PACKET_SIZE, rec, sd->recvbuf,
624 dmat.dest = sd->recvbuf;
625 dmat.size = sd->rsize;
629 dmat.dest = sd->pkt_addr;
634 while (!sceSifSetDma(&dmat, 1))
638void sceSifRpcLoop(SifRpcDataQueue_t *qd)
641 SifRpcServerData_t *sd;
643 while ((sd = sceSifGetNextRequest(qd)))
644 sceSifExecRequest(sd);
650int sceSifCheckStatRpc(SifRpcClientData_t *cd)
652 SifRpcPktHeader_t *packet = (SifRpcPktHeader_t *)cd->hdr.pkt_addr;
657 if (cd->hdr.rpc_id != (u32)(packet->rpc_id))