int SifIopSync() { if (SifGetReg(SIF_REG_SMFLAG) & 0x40000) { return 1; } return 0; }
int SifIopReset(const char *arg, int mode) { struct _iop_reset_pkt reset_pkt; /* Implicitly aligned. */ struct t_SifDmaTransfer dmat; _iop_reboot_count++; // increment reboot counter to allow RPC clients to detect unbinding! SifStopDma(); memset(&reset_pkt, 0, sizeof reset_pkt); reset_pkt.header.size = sizeof reset_pkt; reset_pkt.header.cid = 0x80000003; reset_pkt.mode = mode; if (arg != NULL) { strncpy(reset_pkt.arg, arg, RESET_ARG_MAX); reset_pkt.arg[RESET_ARG_MAX] = '\0'; reset_pkt.arglen = strlen(reset_pkt.arg) + 1; } dmat.src = &reset_pkt; dmat.dest = (void *)SifGetReg(SIF_REG_SUBADDR); dmat.size = sizeof reset_pkt; dmat.attr = 0x40 | SIF_DMA_INT_O; SifWriteBackDCache(&reset_pkt, sizeof reset_pkt); SifSetReg(SIF_REG_SMFLAG, 0x40000); if (!SifSetDma(&dmat, 1)) return 0; SifSetReg(SIF_REG_SMFLAG, 0x10000); SifSetReg(SIF_REG_SMFLAG, 0x20000); SifSetReg(0x80000002, 0); SifSetReg(0x80000000, 0); return 1; }
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); }
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); } }
int SifIopIsAlive() { return ((SifGetReg(SIF_REG_SMFLAG) & 0x10000) != 0); }