iotestsp.c 5.37 KB

/*************************************************************************
 *
 *  File: iotestsp.c
 *
 *  This file contains test routines for the RSP.
 *
 *  $Header: /root/leakn64/depot/rf/sw/bbplayer/iosim/src/iotestsp.c,v 1.5 2003/01/31 03:06:11 whs Exp $
 *
 */

#include <stdio.h>
#include "trace.h"
#include "iomap.h"
#include "iotest.h"
#include "bcp_util.h"


/***********************************************************************
 * Test routines for SP
 */
int
spPollStatus(unsigned int statBits)
{
	/* Poll SP status register for the statBits set */

	unsigned int stat;

	do {
		BCP_STALL(32);
		stat = IO_READ(SP_STATUS_REG);
		_TRACE(DSTATUS, 
			fprintf(LogFp, "\n\tSP Status Reg = 0x%08x\t", stat));
	}
	while (stat & statBits);

	return((int)stat);

}  /* spPollStatus */


int	
IoSpWrite(unsigned int address, unsigned int data)
{
	spPollStatus(SP_STATUS_IO_FULL);	/* Should check DMA busy/full */
	IO_WRITE(address, data);

	return(1);	/* Return 1 to avoid printing Passed test */

}  /* IoSpWrite */


int	
IoSpRead(unsigned int address)
{
	spPollStatus(SP_STATUS_IO_FULL);	/* Should check DMA busy/full */
	return(IO_READ(address));

}  /* IoSpRead */


int
IoSpDmaCopy(int dir, unsigned int spAddr, unsigned int dramAddr, int length)
{
	int ret;

	/* Length = {[31:20] skip, [19:12] count, [11:0] length} */
	ret = 0;

	spPollStatus(SP_STATUS_DMA_FULL);	/* Should check for IO full */

	IO_WRITE(SP_MEM_ADDR_REG, spAddr);
	IO_WRITE(SP_DRAM_ADDR_REG, dramAddr);

	switch (dir) {
		case DIR_FROM_RAM: {
			IO_WRITE(SP_RD_LEN_REG, length);
			break;
		}
		case DIR_TO_RAM: {
			IO_WRITE(SP_WR_LEN_REG, length);
			break;
		}
		default: {
                        _TRACE(DERROR, fprintf(LogFp,
			"\n\t****ERROR: Illegal SpDmaCopy direction!\t"));
                        ret = -1;
		}
	}  /* switch */

	return(ret);

}  /* IoSpDmaCopy */


int	
SpTestStatus(int testBits, int a2, int a3, int a4)
{
	/* Read the SP status reg and compare it against testBits */

	spPollStatus(testBits);
	return(1);		/* Return 1 to avoid printing Passed test */

}  /* SpTestStatus */


int	
SpTestReg(int regAddr, int data, int compared, int a4)
{
	/* a1 = register address */
	/* a2 = test data */
	/* Write/Read to/from DRAM address and Cartridge registers */

	unsigned int ret;

	errorCount = 0;

	regAddr &= 0xFFFFFFFC;		/* Make sure that it's word-aligned */

	_TRACE(DLOG, printf("\tSP Status Reg = 0x%08x\n", 
		IO_READ(SP_STATUS_REG)));

	/* Hw reset the address to be 2-byte aligned 
	 * Also, DMA RAM address is only 24-bit, upper 8 bits are
	 * also set to 0.
	 */
	IO_WRITE(regAddr, data);
	ret = IO_READ(regAddr);
	if (compared) {
		if (data != ret) {
			errorCount++;
			_TRACE(DERROR, LOG_ERROR(data, ret));
		}
	}

	errorTotal += errorCount;
	return((errorCount == 0) ? 0 : -1);

}  /* SpTestReg */


int
SpTestIoRead(int spAddr, int data, int compared, int a4)
{
	/* CPU performs read from I/DMEM */

	unsigned int ret;

	errorCount = 0;

	spAddr &= 0xFFFFFFFC;	/* Make sure that it's word aligned */

	_TRACE(DLOG, printf("\tSP Status Reg = 0x%08x\n", 
		IO_READ(SP_STATUS_REG)));

	ret = IoSpRead((unsigned int)spAddr);
	if (compared) {
		if (data != ret) {
			errorCount++;
			_TRACE(DERROR, LOG_ERROR(data, ret));
		}
	}
	errorTotal += errorCount;
		
	return((errorCount == 0) ? 0 : -1);

}  /* SpTestIoRead */


int
SpTestIoWrite(int spAddr, int data, int compared, int a4)
{
	/* CPU performs write to I/DMEM */

	unsigned int ret;

	errorCount = 0;

	spAddr &= 0xFFFFFFFC;	/* Make sure that it's word aligned */

	_TRACE(DLOG, printf("\tSP Status Reg = 0x%08x\n", 
		IO_READ(SP_STATUS_REG)));

	IoSpWrite((unsigned int)spAddr, (unsigned int)data);
	ret = IoSpRead((unsigned int)spAddr);
	if (compared) {
		if (data != ret) {
			errorCount++;
			_TRACE(DERROR, LOG_ERROR(data, ret));
		}
	}
	errorTotal += errorCount;
		
	return((errorCount == 0) ? 0 : -1);

}  /* SpTestIoWrite */


int
SpTestDma(int dir, int spAddr, int ramAddr, int nbytes)
{
	/* CPU issues DMA (read/write) requests between SP and RDRAM */

	unsigned int i, d1, d2;

	errorCount = 0;

	spAddr &= 0xFFFFFFFC;		/* Make sure it's word aligned */
	ramAddr &= 0xFFFFFFFC;		/* Make sure it's word aligned */

	/* 
	 * DMA WRITE tests: 
	 *	- Assume that RDRAM has been pre-loaded with data
	 *	- Transfer nbytes from I/DMEM <-> RDRAM 
	 *	- Read each word from RDRAM and compare it against I/DMEM
	 *	- Note that size of transfer = nbytes - 1
	 */
	if (IoSpDmaCopy(dir, (unsigned int)spAddr, 
		(unsigned int)ramAddr, nbytes-1) < 0) {
		errorCount++;
	}

	errorTotal += errorCount;
	return((errorCount == 0) ? 0 : -1);

}  /* SpTestDma */


int
SpTestDmaPg(int type, int spAddr, int dramAddr, int npages)
{
	/* 
	 * CPU issues DMA (read/write) requests between I/DMEM and
	 * RDRAM pages
	 *	2 RDRAMs: 1 RDRAM = 1 MBytes = 2 banks;
	 *		  1 bank  = 256 pages; 1 page = 2 KBytes
	 */

	int		i, startPg, nbytes, dir;
	unsigned int	address;

	errorCount = 0;
	nbytes	   = 8;
	dir	   = DIR_TO_RAM;

	dramAddr &= 0xFFFFFFFC;	    /* Make sure addresses are word aligned */
	spAddr  &= 0xFFFFFFFC;

	startPg = dramAddr / RDRAM_PAGE_SIZE;
	i = MAX_RDRAM_PAGES - startPg;
	if (npages > i)
		npages = i;

	for (i=0; i < npages; i++) {
		nbytes += (i*2);
		address = (dramAddr + (i*RDRAM_PAGE_SIZE)) & 0xFFFFFFFC;
		if (IoSpDmaCopy(dir, (unsigned int)spAddr, 
			(unsigned int)address, nbytes-1) < 0) {
			errorCount++;
		}
	}
	errorTotal += errorCount;

	return((errorCount == 0) ? 0 : -1);

}  /* SpTestDmaPg */