///////////////////////////////////////////////////////////////////////[0F] int SifBindRpc(struct sifcmd_RPC_CLIENT_DATA *client, unsigned int number, unsigned int mode) { RPC_PACKET_BIND *packet; client->command=0; client->server=0; packet = (RPC_PACKET_BIND *)rpc_get_packet(&rpc_common); if (packet==NULL) return -1; client->hdr.pkt_addr = packet; client->hdr.rpc_id = packet->packet.pid; packet->packet.paddr = packet; packet->client = client; packet->fno = number; if (mode & 1==0){ client->hdr.tid=GetThreadId(); if (SifSendCmd(0x80000009, packet, 0x40, 0, 0, 0)==0) return -2; SleepThread(); }else{ //async client->hdr.tid=-1; if (SifSendCmd(0x80000009, packet, 0x40, 0, 0, 0)==0) return -2; } return 0; }
///////////////////////////////////////////////////////////////////////[10] int SifCallRpc(struct sifcmd_RPC_CLIENT_DATA *client, unsigned int fno, unsigned int mode, void *send, int ssize, void *receive, int rsize, void (*end_func)(void*), void *end_para){ RPC_PACKET_CALL *packet; if ((packet=(RPC_PACKET_CALL *)rpc_get_packet(&rpc_common))==0) return -1; client->hdr.pkt_addr=(void*)packet; client->func = end_func; client->param = end_para; client->hdr.rpc_id= packet->packet.packet.pid; packet->packet.packet.paddr = packet; packet->packet.client = client; packet->packet.fno = fno; packet->size = ssize; packet->receive= receive; packet->rsize = rsize; packet->server = client->server; if (mode & 1){ packet->rmode=(end_func!=0); client->hdr.tid=-1; if (SifSendCmd(0x8000000A, packet, 0x40, send, client->buff, ssize)) return 0; return -2; }else{ packet->rmode=1; client->hdr.tid=GetThreadId(); if (SifSendCmd(0x8000000A, packet, 0x40, send, client->buff, ssize)==0) return -2; SleepThread(); return 0; } }
///////////////////////////////////////////////////////////////////////[17] int SifGetOtherData(struct sifcmd_RPC_RECEIVE_DATA *rd, void *src, void *dst, int size, int mode){ RPC_PACKET_RDATA *packet; if ((packet=(RPC_PACKET_RDATA *)rpc_get_packet(&rpc_common))==0) return -1; rd->hdr.pkt_addr=packet; rd->hdr.rpc_id =packet->packet.pid; packet->packet.paddr=packet; packet->client=(struct sifcmd_RPC_CLIENT_DATA*)rd; packet->src=src; packet->dst=dst; packet->size=size; if (mode & 1==0){ rd->hdr.tid=GetThreadId(); if (SifSendCmd(0x8000000C, packet, 0x40, 0, 0, 0)==0) return -2; SleepThread(); }else{ //async rd->hdr.tid=-1; if (SifSendCmd(0x8000000C, packet, 0x40, 0, 0, 0)==0) return -2; } 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) { 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; }
///////////////////////////////////////////////////////////////////////[0E] void SifInitRpc(int mode){ u32 x; _dprintf("%s\n", __FUNCTION__); SifInitCmd(); CpuSuspendIntr(&x); if (sifInitRpc){ CpuResumeIntr(x); }else{ sifInitRpc=1; rpc_common.paddr=(RPC_PACKET*)bufx; rpc_common.size=32; rpc_common.paddr2=0; rpc_common.size2=0; rpc_common.next=(RPC_PACKET*)bufy; rpc_common.count=32; rpc_common.base=0; rpc_common.pid=1; SifAddCmdHandler(0x80000008, (cmdh_func)cmd80000008_END, &rpc_common); SifAddCmdHandler(0x80000009, (cmdh_func)cmd80000009_BIND, &rpc_common); SifAddCmdHandler(0x8000000A, (cmdh_func)cmd8000000A_CALL, &rpc_common); SifAddCmdHandler(0x8000000C, (cmdh_func)cmd8000000C_RDATA, &rpc_common); CpuResumeIntr(x); ((SifCmdSRData*)bufx)->rno =0; ((SifCmdSRData*)bufx)->value=1; SifSendCmd(0x80000001, (void*)bufx, sizeof(SifCmdSRData), 0, 0, 0); } WaitEventFlag(GetSystemStatusFlag(), 0x800, 0, 0); }
/* RTE function has a return value of 0. */ void SifInitCmd(void) { u32 status; int i; core_save_disable(&status); if (initialized) { core_restore(status); return; } initialized = 1; _sif_cmd_data.pktbuf = KSEG1ADDR((u32 *)pktbuf); _sif_cmd_data.cmdbuf = KSEG1ADDR((u32 *)cmdbuf); _sif_cmd_data.iopbuf = 0; _sif_cmd_data.sys_cmd_handlers = sifCmdSysBuffer; _sif_cmd_data.nr_sys_handlers = 32; _sif_cmd_data.usr_cmd_handlers = NULL; _sif_cmd_data.nr_usr_handlers = 0; _sif_cmd_data.sregs = sregs; for(i = 0; i < CMD_HANDLER_MAX; i++) { sifCmdSysBuffer[i].handler = NULL; sifCmdSysBuffer[i].harg = NULL; } for(i = 0; i < 32; i++) { sregs[i] = 0; } sifCmdSysBuffer[0].handler = change_addr; sifCmdSysBuffer[0].harg = &_sif_cmd_data; sifCmdSysBuffer[1].handler = set_sreg; sifCmdSysBuffer[1].harg = &_sif_cmd_data; core_restore(status); /* No check here if IOP is already initialized. Assumption is that it is * already initialized */ /* give it our new receive address. */ _sif_cmd_data.iopbuf = (void *) sbios_iopaddr; /* XXX: inserted for test. */ ((ca_pkt_t *)(sifCmdInitPkt))->buf = (void *) PHYSADDR((u32 *)_sif_cmd_data.pktbuf); SifSendCmd(SIF_CMD_CHANGE_SADDR, sifCmdInitPkt, sizeof(ca_pkt_t), NULL, NULL, 0); #if 0 /* RTE does the following: */ SifSetReg(SIF_CMD_CHANGE_SADDR, sbios_iopaddr); SifSetReg(0x80000001, sbios_iopaddr); #else /* XXX: PS2SDK code looks better: */ SifSetReg(SIF_CMD_CHANGE_SADDR, (uint32_t) _sif_cmd_data.iopbuf); SifSetReg(0x80000001, (uint32_t) &_sif_cmd_data); #endif }
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; }
///////////////////////////////////////////////////////////////////////[15] void SifExecRequest(struct sifcmd_RPC_SERVER_DATA *sd){ u32 x; register int size, id, count, i; register void *buff; RPC_PACKET_END *epacket; struct sifman_DMA dma[2]; size=0; if (buff=sd->func(sd->fno, sd->buff, sd->size)) size=sd->rsize; CpuSuspendIntr(&x); epacket=(RPC_PACKET_END *)rpc_get_fpacket(&rpc_common); CpuResumeIntr(x); epacket->command=0x8000000A; epacket->client=sd->client; count=0; if (sd->rmode){ while (SifSendCmd(0x80000008, epacket, 0x40, buff, sd->receive, size)==0); return; }else{ epacket->packet.pid=0; epacket->packet.rec_id=0; if (size>0){ count=1; dma[count-1].data=buff; dma[count-1].size=size; dma[count-1].attr=0; dma[count-1].addr=sd->receive; } count++; dma[count-1].data=epacket; dma[count-1].size=0x40; dma[count-1].attr=0; dma[count-1].addr=sd->pkt_addr; do{ CpuSuspendIntr(&x); id=SifSetDma(dma, count); CpuResumeIntr(x); if (id) break; i=0xFFFF; do --i; while (i!=-1); } while (id==0); } }
void SifInitRpc(int mode) { u32 *cmdp; static int _rb_count = 0; if(_rb_count != _iop_reboot_count) { _rb_count = _iop_reboot_count; SifExitCmd(); init = 0; } if (init) return; init = 1; SifInitCmd(); DI(); _sif_rpc_data.pkt_table = UNCACHED_SEG(_sif_rpc_data.pkt_table); _sif_rpc_data.rdata_table = UNCACHED_SEG(_sif_rpc_data.rdata_table); _sif_rpc_data.client_table = UNCACHED_SEG(_sif_rpc_data.client_table); SifAddCmdHandler(0x80000008, (void *)_request_end, &_sif_rpc_data); SifAddCmdHandler(0x80000009, (void *)_request_bind, &_sif_rpc_data); SifAddCmdHandler(0x8000000a, (void *)_request_call, &_sif_rpc_data); SifAddCmdHandler(0x8000000c, (void *)_request_rdata, &_sif_rpc_data); EI(); if (SifGetReg(0x80000002)) return; cmdp = (u32 *)&pkt_table[64]; cmdp[3] = 1; SifSendCmd(0x80000002, cmdp, 16, NULL, NULL, 0); while (!SifGetSreg(0)) ; SifSetReg(0x80000002, 1); }
void SifInitRpc(void) { u32 status; core_save_disable(&status); if (init) { core_restore(status); return; } init = 1; SifInitCmd(); _sif_rpc_data.pkt_table = UNCACHED_SEG(_sif_rpc_data.pkt_table); _sif_rpc_data.rdata_table = UNCACHED_SEG(_sif_rpc_data.rdata_table); _sif_rpc_data.client_table = UNCACHED_SEG(_sif_rpc_data.client_table); SifAddCmdHandler(0x80000008, (void *)_request_end, &_sif_rpc_data); SifAddCmdHandler(0x80000009, (void *)_request_bind, &_sif_rpc_data); SifAddCmdHandler(0x8000000a, (void *)_request_call, &_sif_rpc_data); SifAddCmdHandler(0x8000000c, (void *)_request_rdata, &_sif_rpc_data); #if 0 /* XXX: IOP is already initialized, we can't do this. */ if (SifGetReg(0x80000002)) return; cmdp = (u32 *)&pkt_table[64]; cmdp[3] = 1; SifSendCmd(0x80000002, cmdp, 16, NULL, NULL, 0); while (!SifGetSreg(0)) ; #endif SifSetReg(0x80000002, 1); core_restore(status); }
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; }
void SifInitCmd() { u32 packet[5]; /* Implicitly aligned to 16 bytes */ int i; static int _rb_count = 0; if(_rb_count != _iop_reboot_count) { _rb_count = _iop_reboot_count; if (sif0_id >= 0) { DisableDmac(5); RemoveDmacHandler(5, sif0_id); } init = 0; } if (init) return; DI(); _sif_cmd_data.pktbuf = UNCACHED_SEG(_sif_cmd_data.pktbuf); _sif_cmd_data.unused = UNCACHED_SEG(_sif_cmd_data.unused); for (i = 0; i < CMD_HANDLER_MAX; i++) { _sif_cmd_data.sys_cmd_handlers[i].handler = NULL; _sif_cmd_data.sys_cmd_handlers[i].harg = NULL; } for (i = 0; i < 32; i++) _sif_cmd_data.sregs[i] = 0; _sif_cmd_data.sys_cmd_handlers[0].handler = change_addr; _sif_cmd_data.sys_cmd_handlers[0].harg = &_sif_cmd_data; _sif_cmd_data.sys_cmd_handlers[1].handler = set_sreg; _sif_cmd_data.sys_cmd_handlers[1].harg = &_sif_cmd_data; EI(); FlushCache(0); if (_lw(DMAC_COMM_STAT) & STAT_SIF0) _sw(STAT_SIF0, DMAC_COMM_STAT); if (!(_lw(DMAC_SIF0_CHCR) & CHCR_STR)) SifSetDChain(); sif0_id = AddDmacHandler(5, _SifCmdIntHandler, 0); EnableDmac(5); init = 1; _sif_cmd_data.iopbuf = (void *)SifGetReg(0x80000000); if (_sif_cmd_data.iopbuf) { /* IOP SIF CMD is already initialized, so give it our new receive address. */ ((struct ca_pkt *)(packet))->buf = _sif_cmd_data.pktbuf; SifSendCmd(0x80000000, packet, sizeof packet, NULL, NULL, 0); } else { /* Sync */ while (!(SifGetReg(SIF_REG_SMFLAG) & 0x20000)) ; _sif_cmd_data.iopbuf = (void *)SifGetReg(SIF_REG_SUBADDR); SifSetReg(0x80000000, (u32)_sif_cmd_data.iopbuf); /* See the note above about struct cmd_data, and the use of this register. */ SifSetReg(0x80000001, (u32)&_sif_cmd_data); packet[3] = 0; packet[4] = (u32)_sif_cmd_data.pktbuf; SifSendCmd(0x80000002, packet, sizeof packet, NULL, NULL, 0); } }