Example #1
0
// 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];

}
Example #2
0
int fileXio_getstat_RPC(char *filename, void* eeptr)
{
	iox_stat_t localStat;
	int res = 0;
	struct t_SifDmaTransfer dmaStruct;
	int intStatus;	// interrupt status - for dis/en-abling interrupts

	res = getstat(filename, &localStat);

	if(res >= 0)
	{
		// DMA localStat to the address specified by eeptr
		// setup the dma struct
		dmaStruct.src = &localStat;
		dmaStruct.dest = eeptr;
		dmaStruct.size = sizeof(iox_stat_t);
		dmaStruct.attr = 0;
		// Do the DMA transfer
		CpuSuspendIntr(&intStatus);
		SifSetDma(&dmaStruct, 1);
		CpuResumeIntr(intStatus);
	}

	return(res);
}
Example #3
0
int fileXio_GetDeviceList_RPC(struct fileXioDevice* ee_devices, int eecount)
{
    int device_count = 0;
    iop_device_t **devices = GetDeviceList();
    struct fileXioDevice local_devices[FILEXIO_MAX_DEVICES];
    while (devices[device_count] && device_count < eecount)
    {
        iop_device_t *device = devices[device_count];
        strncpy(local_devices[device_count].name, device->name, 128);
        local_devices[device_count].name[127] = '\0';
        local_devices[device_count].type = device->type;
        local_devices[device_count].version = device->version;
        strncpy(local_devices[device_count].desc, device->desc, 128);
        local_devices[device_count].desc[127] = '\0';
        ++device_count;
    }
    if (device_count)
    {
        struct t_SifDmaTransfer dmaStruct;
        int intStatus;	// interrupt status - for dis/en-abling interrupts

        dmaStruct.src = local_devices;
        dmaStruct.dest = ee_devices;
        dmaStruct.size = sizeof(struct fileXioDevice) * device_count;
        dmaStruct.attr = 0;

        // Do the DMA transfer
        CpuSuspendIntr(&intStatus);
        SifSetDma(&dmaStruct, 1);
        CpuResumeIntr(intStatus);
    }
    return device_count;
}
Example #4
0
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);
}
Example #5
0
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;
}
Example #6
0
static void TxThread(void *arg){
	struct TxFIFOData *TxFIFODataToTransmit;
	SifDmaTransfer_t dmat;
	int dmat_id, ThreadToWakeUp;

	while(1){
		SleepThread();

		WaitSema(TxBankAccessSema);

		if(CurrentTxFIFOData->PacketReqs.NumPackets>0){
			// Switch banks
			TxFIFODataToTransmit=CurrentTxFIFOData;
			if(TxActiveBankID==0){
				CurrentTxFIFOData=&TxFIFOData2;
				TxActiveBankID=1;
			}
			else{
				CurrentTxFIFOData=&TxFIFOData1;
				TxActiveBankID=0;
			}

			SignalSema(TxBankAccessSema);

			SifWriteBackDCache(&TxFIFODataToTransmit->PacketReqs, sizeof(TxFIFODataToTransmit->PacketReqs));

			dmat.src=&TxFIFODataToTransmit->PacketReqs;
			dmat.dest=TxFrameTagBuffer;
			dmat.size=8+sizeof(struct PacketTag)*TxFIFODataToTransmit->PacketReqs.NumPackets;
			dmat.attr=0;

			while((dmat_id=SifSetDma(&dmat, 1))==0){};

			WaitSema(NetManIOSemaID);
			SifCallRpc(&NETMAN_rpc_cd, NETMAN_IOP_RPC_FUNC_SEND_PACKETS, 0, TxFIFODataToTransmit->FrameBuffer, TxFIFODataToTransmit->PacketReqs.TotalLength, NULL, 0, NULL, NULL);
			SignalSema(NetManIOSemaID);

			TxFIFODataToTransmit->PacketReqs.NumPackets=0;
			TxFIFODataToTransmit->PacketReqs.TotalLength=0;
		}
		else SignalSema(TxBankAccessSema);

		if(NetmanTxWaitingThread>=0){
			ThreadToWakeUp=NetmanTxWaitingThread;
			NetmanTxWaitingThread=-1;	//To prevent a race condition from occurring, invalidate NetmanTxWaitingThread before invoking WakeupThread.
			WakeupThread(ThreadToWakeUp);
		}
	}
}
Example #7
0
unsigned int sendCmd(unsigned int pos, int mode, SifCmdHdr *cp, int ps, void *src, void *dst, int size){
	u32 x;
	struct sifman_DMA dma[2];
	register int count, y;

	if (ps<16 || ps>112)	return 0;

	count=0;
	if (size>0){
		count=1;
		dma[0].addr=dst;
		dma[0].size=size;
		dma[0].attr=0;
		dma[0].data=src;
		cp->daddr=(u32)dst;
		cp->dsize=size;
	}else{
		cp->daddr=0;
		cp->dsize=0;
	}
	count++;
	cp->psize=ps;
	cp->fcode=pos;
	dma[count-1].data=cp;
	dma[count-1].attr=SIF_DMA_INT_O;	//calls SIF0 handler
	dma[count-1].size=ps;			//on EE side after transfer;)
	dma[count-1].addr=cmd_common.saddr;
	if (mode & 1)	//interrupt mode
		return SifSetDma(dma, count);
	else{
		CpuSuspendIntr(&x);
		y=SifSetDma(dma, count);
		CpuResumeIntr(x);
		return y;
	}
}
Example #8
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);
	}
}
Example #9
0
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);
}
Example #10
0
static u32 _SifSendCmd(int cid, int mode, void *pkt, u32 pktsize, void *src,
		void *dest, int size)
{
	SifDmaTransfer_t dmat[2];
	SifCmdHeader_t *header;
	int count = 0;

	pktsize &= 0xff;

	if (pktsize > CMD_PACKET_DATA_MAX)
		return 0;

	header = (SifCmdHeader_t *)pkt;
	header->cid  = cid;
	header->size = pktsize;
	header->dest = NULL;

	if (size > 0) {
		header->size = pktsize | (size << 8);
		header->dest = dest;

		if (mode & 4)	/* if mode is & 4, flush reference cache */
			SifWriteBackDCache(src, size);

		dmat[count].src  = src;
		dmat[count].dest = dest;
		dmat[count].size = size;
		dmat[count].attr = 0;
		count++;
	}

	dmat[count].src  = pkt;
	dmat[count].dest = _sif_cmd_data.iopbuf;
	dmat[count].size = pktsize;
	dmat[count].attr = 0x40 | SIF_DMA_INT_O;
	count++;

	SifWriteBackDCache(pkt, pktsize);

	if (mode & 1)  /* INTERRUPT DMA TRANSFER */
		return iSifSetDma(dmat, count);
	else
		return SifSetDma(dmat, count);
}
Example #11
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;
}
Example #12
0
//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){};
}
Example #13
0
//int io_ioctl2(int fd, int cmd, void *arg, unsigned int arglen, void *bufp,
//		unsigned int buflen);
void* fileXioRpc_Ioctl2(unsigned int* sbuff)
{
	struct fxio_ioctl2_packet *packet = (struct fxio_ioctl2_packet *)sbuff;
	struct fxio_ctl_return_pkt *ret_buf = (struct fxio_ctl_return_pkt *)rwbuf;
	SifDmaTransfer_t dmatrans;
	int intStatus;
	int ret;

	#ifdef DEBUG
		printf("RPC ioctl2 Request\n");
	#endif

	ret = ioctl2(packet->fd, packet->cmd, packet->arg, packet->arglen, ret_buf->buf, packet->buflen);

	// Transfer buffer back to EE
	if(packet->buflen != 0)
	{
		dmatrans.src = ret_buf;
		dmatrans.dest = packet->intr_data;
		dmatrans.attr = 0;
		dmatrans.size = sizeof(struct fxio_ctl_return_pkt);

		ret_buf->dest = packet->buf;

		// EE is expecting data.. on error, simply use size of 0 so no data is copied.
		if(ret >= 0)
			ret_buf->len = packet->buflen;
		else
			ret_buf->len = 0;

		CpuSuspendIntr(&intStatus);
		SifSetDma(&dmatrans, 1);
		CpuResumeIntr(intStatus);
	}

	sbuff[0] = ret;
	return sbuff;
}
Example #14
0
/**
 * Send SIF1 command from EE to IOP using DMA.
 * @param src EE memory source address.
 * @param dest IOP memory destination address.
 * @param size Size of data to be copied in bytes. 0, if nothing should be
 *   transfered.
 * @return 0, on error.
 * @return ID, describing DMA transfers.
 */
u32 sif_cmd_send(u32 fid, u32 flags, void *packet, u32 packet_size, void *src, void *dest, u32 size)
{
	tge_sifdma_transfer_t transfer[2];
	tge_sifcmd_header_t *header = packet;
	u32 count = 0;

	if (packet_size > CMD_PACKET_DATA_MAX) {
		return -E_LIB_INVALID_ARG;
	}
	header = (tge_sifcmd_header_t *) packet;
	header->fid = fid;
	header->size = packet_size;
	header->dest = NULL;

	if (size > 0) {
		header->dest = dest;
		header->size = packet_size | (size << 8);
		if (flags & 4) {
			SifWriteBackDCache(src, size);
		}
		transfer[count].src = src;
		transfer[count].dest = dest;
		transfer[count].size = size;
		transfer[count].attr = 0;
		count++;
	} else {
		header->option = 0;
	}
	transfer[count].src = packet;
	transfer[count].dest = _sif_cmd_data.iopbuf;
	transfer[count].size = packet_size;
	transfer[count].attr = TGE_SIFDMA_ATTR_ERT | TGE_SIFDMA_ATTR_INT_O;
	count++;

	SifWriteBackDCache(packet, packet_size);
	return SifSetDma(transfer, count);
}
Example #15
0
int fileXio_dread_RPC(int fd, void* eeptr)
{
      int res=0;
	iox_dirent_t localDir;
      struct t_SifDmaTransfer dmaStruct;
      int intStatus;	// interrupt status - for dis/en-abling interrupts

	res = dread(fd, &localDir);
      if (res > 0)
      {
	  // DMA localStat to the address specified by eeptr
	  // setup the dma struct
	  dmaStruct.src = &localDir;
	  dmaStruct.dest = eeptr;
	  dmaStruct.size = 64+256;
	  dmaStruct.attr = 0;
	  // Do the DMA transfer
	  CpuSuspendIntr(&intStatus);
	  SifSetDma(&dmaStruct, 1);
	  CpuResumeIntr(intStatus);
      }

      return(res);
}
Example #16
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);
}
Example #17
0
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);
}