int SifCallRpc(SifRpcClientData_t *cd, int rpc_number, int mode, void *sendbuf, int ssize, void *recvbuf, int rsize, SifRpcEndFunc_t endfunc, void *efarg) { ee_sema_t sema; SifRpcCallPkt_t *call; call = (SifRpcCallPkt_t *)_rpc_get_packet(&_sif_rpc_data); if (!call) return -E_SIF_PKT_ALLOC; cd->hdr.pkt_addr = call; cd->hdr.rpc_id = call->rpc_id; cd->hdr.sema_id = -1; cd->end_function = endfunc; cd->end_param = efarg; call->rpc_number = rpc_number; call->send_size = ssize; call->receive = recvbuf; call->recv_size = rsize; call->rmode = 1; call->pkt_addr = call; call->client = cd; call->server = cd->server; if (!(mode & SIF_RPC_M_NOWBDC)) { if (ssize > 0) SifWriteBackDCache(sendbuf, ssize); if (rsize > 0) SifWriteBackDCache(recvbuf, rsize); } if (mode & SIF_RPC_M_NOWAIT) { if (!endfunc) call->rmode = 0; if (!SifSendCmd(0x8000000a, call, RPC_PACKET_SIZE, sendbuf, cd->buff, ssize)) return -E_SIF_PKT_SEND; return 0; } sema.max_count = 1; sema.init_count = 0; cd->hdr.sema_id = CreateSema(&sema); if (cd->hdr.sema_id < 0) return -E_LIB_SEMA_CREATE; if (!SifSendCmd(0x8000000a, call, RPC_PACKET_SIZE, sendbuf, cd->buff, ssize)) return -E_SIF_PKT_SEND; WaitSema(cd->hdr.sema_id); DeleteSema(cd->hdr.sema_id); return 0; }
int SifRpcGetOtherData(SifRpcReceiveData_t *rd, void *src, void *dest, int size, int mode) { ee_sema_t sema; SifRpcOtherDataPkt_t *other; other = (SifRpcOtherDataPkt_t *)_rpc_get_packet(&_sif_rpc_data); if (!other) return -E_SIF_PKT_ALLOC; rd->hdr.pkt_addr = other; rd->hdr.rpc_id = other->rpc_id; rd->hdr.sema_id = -1; other->src = src; other->dest = dest; other->size = size; other->receive = rd; if (mode & SIF_RPC_M_NOWAIT) { if (!SifSendCmd(0x8000000c, other, 64, NULL, NULL, 0)) return -E_SIF_PKT_SEND; return 0; } sema.max_count = 1; sema.init_count = 1; rd->hdr.sema_id = CreateSema(&sema); if (rd->hdr.sema_id < 0) return -E_LIB_SEMA_CREATE; if (!SifSendCmd(0x8000000c, other, 64, NULL, NULL, 0)) return -E_SIF_PKT_SEND; WaitSema(rd->hdr.sema_id); DeleteSema(rd->hdr.sema_id); return 0; }
int SifBindRpc(SifRpcClientData_t *cd, int sid, int mode) { ee_sema_t sema; SifRpcBindPkt_t *bind; bind = (SifRpcBindPkt_t *)_rpc_get_packet(&_sif_rpc_data); if (!bind) return -E_SIF_PKT_ALLOC; cd->command = 0; cd->server = NULL; cd->hdr.pkt_addr = bind; cd->hdr.rpc_id = bind->rpc_id; cd->hdr.sema_id = -1; bind->sid = sid; bind->pkt_addr = bind; bind->client = cd; if (mode & SIF_RPC_M_NOWAIT) { if (!SifSendCmd(0x80000009, bind, RPC_PACKET_SIZE, NULL, NULL, 0)) return -E_SIF_PKT_SEND; return 0; } sema.max_count = 1; sema.init_count = 0; cd->hdr.sema_id = CreateSema(&sema); if (cd->hdr.sema_id < 0) return -E_LIB_SEMA_CREATE; if (!SifSendCmd(0x80000009, bind, RPC_PACKET_SIZE, NULL, NULL, 0)) return -E_SIF_PKT_SEND; WaitSema(cd->hdr.sema_id); DeleteSema(cd->hdr.sema_id); return 0; }
int SifCallRpc(SifRpcClientData_t *cd, int rpc_number, int mode, void *sendbuf, int ssize, void *recvbuf, int rsize, SifRpcEndFunc_t endfunc, void *efarg) { SifRpcCallPkt_t *call; u32 status; if ((((u32) recvbuf) & 0x0f) != 0) { /* This is fatal and will lead to write accesses on wrong memory addresses. */ printf("SifCallRpc 0x%x is not aligned (cd 0x%08x rpc nr 0x%x).\n", (uint32_t) recvbuf, (uint32_t) cd, rpc_number); return -E_LIB_INVALID_ARG; } call = (SifRpcCallPkt_t *)_rpc_get_packet(&_sif_rpc_data); if (!call) { return -E_SIF_PKT_ALLOC; } core_save_disable(&status); if (cd->hdr.pkt_addr != 0) { core_restore(status); rpc_packet_free(call); printf("SifCallRpc: Client 0x%x rpc_number 0x%x is already in use.\n", (uint32_t) cd, rpc_number); return -E_SIF_PKT_ALLOC; } cd->end_function = endfunc; cd->end_param = efarg; cd->hdr.pkt_addr = call; cd->hdr.rpc_id = call->rpc_id; cd->hdr.sema_id = 0; core_restore(status); call->rpc_number = rpc_number; call->send_size = ssize; call->receive = recvbuf; call->recv_size = rsize; call->rmode = 1; call->pkt_addr = call; call->client = cd; call->server = cd->server; if (!(mode & SIF_RPC_M_NOWBDC)) { if (ssize > 0) SifWriteBackDCache(sendbuf, ssize); if (rsize > 0) SifWriteBackDCache(recvbuf, rsize); } if (mode & SIF_RPC_M_NOWAIT) { if (!endfunc) call->rmode = 0; if (!SifSendCmd(0x8000000a, call, RPC_PACKET_SIZE, sendbuf, cd->buff, ssize)) { rpc_packet_free(call); return -E_SIF_PKT_SEND; } return 0; } /* The following code is normally not executed. */ if (!SifSendCmd(0x8000000a, call, RPC_PACKET_SIZE, sendbuf, cd->buff, ssize)) { rpc_packet_free(call); return -E_SIF_PKT_SEND; } core_save_disable(&status); while(cd->hdr.sema_id == 0) { /* Wait until something is received. */ core_restore(status); /* Preemption point. */ core_save_disable(&status); } cd->hdr.sema_id--; core_restore(status); return 0; }
int SifBindRpc(SifRpcClientData_t *cd, int sid, int mode, SifRpcEndFunc_t endfunc, void *efarg) { SifRpcBindPkt_t *bind; u32 status; bind = (SifRpcBindPkt_t *)_rpc_get_packet(&_sif_rpc_data); if (!bind) { return -E_SIF_PKT_ALLOC; } /* Callback is required by linux. */ core_save_disable(&status); if (cd->hdr.pkt_addr != NULL) { core_restore(status); rpc_packet_free(bind); printf("SifBindRpc: Client 0x%x sid 0x%x is already in use.\n", (uint32_t) cd, sid); return -E_SIF_PKT_ALLOC; } cd->end_function = endfunc; cd->end_param = efarg; cd->command = 0; cd->server = NULL; cd->hdr.pkt_addr = bind; cd->hdr.rpc_id = bind->rpc_id; cd->hdr.sema_id = 0; core_restore(status); bind->sid = sid; bind->pkt_addr = bind; bind->client = cd; if (mode & SIF_RPC_M_NOWAIT) { if (!SifSendCmd(0x80000009, bind, RPC_PACKET_SIZE, NULL, NULL, 0)) { rpc_packet_free(bind); return -E_SIF_PKT_SEND; } return 0; } /* The following code is normally not executed. */ if (!SifSendCmd(0x80000009, bind, RPC_PACKET_SIZE, NULL, NULL, 0)) { rpc_packet_free(bind); return -E_SIF_PKT_SEND; } core_save_disable(&status); while(cd->hdr.sema_id == 0) { /* Wait until something is received. */ core_restore(status); /* Preemption point. */ core_save_disable(&status); } cd->hdr.sema_id--; core_restore(status); return 0; }