int SIF1_handler(void *common){ int buf[112/4]; register int i, ps; register SifCmdData *scd; SifCmdHdr *packet; struct tag_cmd_common *c = (struct tag_cmd_common *)common; if (c->func) c->func(c->param); packet=(SifCmdHdr*)c->sif1_rcvBuffer; if ((ps=packet->psize & 0xFF)==0){ SifSetDChain(); return 1; } packet->psize=0; ps=(ps+3<0 ? ps+6 : ps+3)/4; for (i=0; i<ps; i++) buf[i]=((u32*)packet)[i]; SifSetDChain(); packet=(SifCmdHdr*)buf; if (packet->fcode<0){ if (packet->fcode & 0x7FFFFFFF>=c->sysCmdBufferSize) return 1; scd=&c->sysCmdBuffer[packet->fcode & 0x7FFFFFFF]; }else{ if (packet->fcode>=c->cmdBufferSize) return 1; scd=&c->cmdBuffer[packet->fcode]; } if (scd->func) scd->func(packet, scd->data); return 1; }
int iop_heap_dma_upload(void *src,u32 dst,int size) { int i=0,len=0,size2; u8 *pkt; int ret=0; int ret2=0; int p=0; int cont1=0; while(size>0) // send data with src unaligned { if(size>512) size2=512; else size2=size; CD_memcpy2(memsend,((unsigned char *) src)+p,size2); do { FlushCache(0); /* build packet */ pkt = send_buffer2; PUSHDATA( u32, pkt, (u32)memsend, i); pkt += i; len += i; PUSHDATA( u32, pkt, dst, i); pkt += i; len += i; PUSHDATA( int, pkt, size2, i); pkt += i; len += i; PUSHDATA( int, pkt, 0, i); pkt += i; len += i; ret = SifSetDma((SifDmaTransfer_t*)send_buffer2,1); if(ret==0) {nopdelay();cont1++;} if(ret==0 && cont1>=3) {cont1=0;SifSetDChain();} }while(ret==0); // modificado por Hermes while((ret2 = SifDmaStat(ret))>=0); FlushCache(0); size-=size2; p+=size2; dst+=size2; } return (ret2 < -1); }
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); } }