// size should either be either 800 (NTSC) or 960 (PAL) void SjPCM_Enqueue(short *left, short *right, int size, int wait) { int i; struct t_SifDmaTransfer sdt; if (!sjpcm_inited) return; sdt.src = (void *)left; sdt.dest = (void *)(pcmbufl + bufpos); sdt.size = size*2; sdt.attr = 0; FlushCache(0); i = SifSetDma(&sdt, 1); // start dma transfer while ((wait != 0) && (SifDmaStat(i) >= 0)); // wait for completion of dma transfer sdt.src = (void *)right; sdt.dest = (void *)(pcmbufr + bufpos); sdt.size = size*2; sdt.attr = 0; FlushCache(0); i = SifSetDma(&sdt, 1); while ((wait != 0) && (SifDmaStat(i) >= 0)); sbuff[0] = size; SifCallRpc(&cd0,SJPCM_ENQUEUE,0,(void*)(&sbuff[0]),64,(void*)(&sbuff[0]),64,0,0); bufpos = sbuff[3]; }
int sndLoadSample(void *buf, u32 spuaddr, int size) { void *iopbuf; int id, iopfree; SifDmaTransfer_t sifdma; iopfree = sndQueryMaxFreeMemSize()/2; if (size>iopfree) { return(-1); } iopbuf = SifAllocIopHeap(size); if (iopbuf==0) return(-1); FlushCache(0); sifdma.src = buf; sifdma.dest = iopbuf; sifdma.size = size; sifdma.attr = 0; id = SifSetDma(&sifdma, 1); while(SifDmaStat(id) >= 0);; FlushCache(0); SdVoiceTrans(0, SD_TRANS_WRITE, iopbuf, (void*)spuaddr, size); SdVoiceTransStatus(0, 1); SifFreeIopHeap(iopbuf); return(size); }
int audsrv_load_adpcm(audsrv_adpcm_t *adpcm, void *buffer, int size) { void* iop_addr; SifDmaTransfer_t sifdma; int id, ret; iop_addr = SifAllocIopHeap(size); if (iop_addr == 0) { return -AUDSRV_ERR_OUT_OF_MEMORY; } sifdma.src = buffer; sifdma.dest = iop_addr; sifdma.size = size; sifdma.attr = 0; /* send by dma */ while((id = SifSetDma(&sifdma, 1)) == 0); while(SifDmaStat(id) >= 0); WaitSema(completion_sema); sbuff[0] = (int)iop_addr; sbuff[1] = size; sbuff[2] = (int)adpcm; /* use as id */ SifCallRpc(&cd0, AUDSRV_LOAD_ADPCM, 0, sbuff, 12, sbuff, 16, NULL, NULL); if(sbuff[0] != 0) { adpcm->buffer = 0; ret = sbuff[0]; } else { adpcm->buffer = buffer; adpcm->size = size; adpcm->pitch = sbuff[1]; adpcm->loop = sbuff[2]; adpcm->channels = sbuff[3]; ret = AUDSRV_ERR_NOERROR; } SignalSema(completion_sema); SifFreeIopHeap(iop_addr); return ret; }
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); }
//Only one thread can enter this critical section! static void EnQFrame(const void *frame, unsigned int length) { SifDmaTransfer_t dmat; int dmat_id; //Write back D-cache, before performing a DMA transfer. SifWriteBackDCache((void*)frame, length); //Wait for a spot to be freed up. while(PacketReqs.count + 1 >= NETMAN_RPC_BLOCK_SIZE) { NetmanTxWaitingThread = GetThreadId(); WakeupThread(TxThreadID); SleepThread(); } //Transfer to IOP RAM dmat.src = (void*)frame; dmat.dest = &IOPFrameBuffer[IOPFrameBufferWrPtr * NETMAN_MAX_FRAME_SIZE]; dmat.size = length; dmat.attr = 0; while((dmat_id = SifSetDma(&dmat, 1))==0){}; //Record the frame length. PacketReqs.length[IOPFrameBufferWrPtr] = length; DI(); //Update the frame count. PacketReqs.count++; EI(); //Increase write pointer by one position. IOPFrameBufferWrPtr = (IOPFrameBufferWrPtr + 1) % NETMAN_RPC_BLOCK_SIZE; //Signal the transmission thread that there are more frames to transmit. WakeupThread(TxThreadID); //Ensure that the frame is copied over before returning (so that the buffer can be freed). while(SifDmaStat(dmat_id) >= 0){}; }
// This is the getdir for use by the EE RPC client // It DMA's entries to the specified buffer in EE memory int fileXio_GetDir_RPC(const char* pathname, struct fileXioDirEntry dirEntry[], unsigned int req_entries) { int matched_entries; int fd, res; iox_dirent_t dirbuf; struct fileXioDirEntry localDirEntry; int intStatus; // interrupt status - for dis/en-abling interrupts struct t_SifDmaTransfer dmaStruct; int dmaID; dmaID = 0; #ifdef DEBUG printf("RPC GetDir Request\n"); printf("dirname: %s\n",pathname); #endif matched_entries = 0; fd = dopen(pathname); if (fd <= 0) { return fd; } { res = 1; while (res > 0) { memset(&dirbuf, 0, sizeof(dirbuf)); res = dread(fd, &dirbuf); if (res > 0) { // check for too many entries if (matched_entries == req_entries) { close(fd); return (matched_entries); } // wait for any previous DMA to complete // before over-writing localDirEntry while(SifDmaStat(dmaID)>=0); DirEntryCopy(&localDirEntry, &dirbuf); // DMA localDirEntry to the address specified by dirEntry[matched_entries] // setup the dma struct dmaStruct.src = &localDirEntry; dmaStruct.dest = &dirEntry[matched_entries]; dmaStruct.size = sizeof(struct fileXioDirEntry); dmaStruct.attr = 0; // Do the DMA transfer CpuSuspendIntr(&intStatus); dmaID = SifSetDma(&dmaStruct, 1); CpuResumeIntr(intStatus); matched_entries++; } // if res } // while } // if dirs and files // cleanup and return # of entries close(fd); return (matched_entries); }
int fileXio_Read_RPC(int infd, char *read_buf, int read_size, void *intr_data) { int srest; int erest; int asize; int abuffer; int rlen; int total; int readlen; int status; struct t_SifDmaTransfer dmaStruct; void *buffer; void *aebuffer; int intStatus; // interrupt status - for dis/en-abling interrupts int read_buf2 = (int)read_buf; total = 0; if(read_size < 64) { srest = read_size; erest = asize = abuffer = 0; buffer = read_buf; aebuffer = 0; }else{ if ((read_buf2 & 0x3F) == 0) srest=0; else srest=(int)RDOWN_64(read_buf2) - read_buf2 + 64; buffer = read_buf; abuffer = read_buf2 + srest; aebuffer=(void *)RDOWN_64(read_buf2 + read_size); asize = (int)aebuffer - (int)abuffer; erest = (read_buf2 + read_size) - (int)aebuffer; } if (srest>0) { if (srest!=(rlen=read(infd, rests.sbuffer, srest))) { total += srest = (rlen>0 ? rlen:0); goto EXIT; } else total += srest; } status=0; while (asize>0) { readlen=MIN(RWBufferSize, asize); while(SifDmaStat(status)>=0); rlen=read(infd, rwbuf, readlen); if (readlen!=rlen){ if (rlen<=0)goto EXIT; dmaStruct.dest=(void *)abuffer; dmaStruct.size=rlen; dmaStruct.attr=0; dmaStruct.src =rwbuf; CpuSuspendIntr(&intStatus); SifSetDma(&dmaStruct, 1); CpuResumeIntr(intStatus); total +=rlen; goto EXIT; }else{ //read ok total += rlen; asize -=rlen; dmaStruct.dest=(void *)abuffer; abuffer +=rlen; dmaStruct.size=rlen; dmaStruct.attr=0; dmaStruct.src =rwbuf; CpuSuspendIntr(&intStatus); status=SifSetDma(&dmaStruct, 1); CpuResumeIntr(intStatus); } } if (erest>0) { rlen = read(infd, rests.ebuffer, erest); total += (rlen>0 ? rlen : 0); } EXIT: rests.ssize=srest; rests.esize=erest; rests.sbuf =buffer; rests.ebuf =aebuffer; dmaStruct.src =&rests; dmaStruct.size=sizeof(rests_pkt); dmaStruct.attr=0; dmaStruct.dest=intr_data; CpuSuspendIntr(&intStatus); SifSetDma(&dmaStruct, 1); CpuResumeIntr(intStatus); return (total); }