iotestpi.c 5.72 KB

/*************************************************************************
 *
 *  File: iotestpi.c
 *
 *  This file contains test routines for the Peripheral Interface (PI).
 *
 *  $Header: /root/leakn64/depot/rf/sw/n64os20l/iosim/src/iotestpi.c,v 1.2 2002/05/30 05:52:50 whs Exp $
 *
 */

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


/***********************************************************************
 * Test routines for PI
 */
static int
piPollStatus(unsigned int statBits, int reset)
{
	/* Poll PI status register for the statBits set */

	unsigned int stat;

	do {
		stat = IO_READ(PI_STATUS_REG);
		_TRACE(DSTATUS, 
			fprintf(LogFp, "\n\tPI Status Reg = 0x%08x\t", stat));
		if (stat & PI_STATUS_ERROR) {
			_TRACE(DERROR,
			fprintf(LogFp,"\n\tERROR: PI error bit set: %08x\t",
				stat));
			if (reset)
				PI_RESET();
			statBits &= ~PI_STATUS_ERROR;
		}
	}
	while (stat & statBits);

	return((int)stat);

}  /* piPollStatus */


int	
IoPiWrite(unsigned int address, unsigned int data)
{

	piPollStatus(PI_STATUS_ERROR | PI_STATUS_DMA_BUSY |
		PI_STATUS_IO_BUSY, FALSE);
	IO_WRITE(address, data);

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

}  /* IoPiWrite */


int	
IoPiRead(unsigned int address)
{

	piPollStatus(PI_STATUS_ERROR | PI_STATUS_DMA_BUSY |
		PI_STATUS_IO_BUSY, FALSE);
	return(IO_READ(address));

}  /* IoPiRead */


int
IoPiDmaCopy(int dir, unsigned int piAddr, unsigned int dramAddr, int length)
{
	int ret;
	unsigned int stat;

	ret = 0;

#ifdef CHECK_STATUS
	piPollStatus(PI_STATUS_ERROR | PI_STATUS_DMA_BUSY |
		PI_STATUS_IO_BUSY, FALSE);
#endif
	IO_WRITE(PI_DRAM_ADDR_REG, dramAddr);
	IO_WRITE(PI_CART_ADDR_REG, piAddr);

	switch (dir) {
		case DIR_FROM_RAM: {
			IO_WRITE(PI_RD_LEN_REG, length);
			break;
		}
		case DIR_TO_RAM: {
			IO_WRITE(PI_WR_LEN_REG, length);
			break;
		}
		default: {
                        _TRACE(DERROR,
			fprintf(LogFp,
				"\tERROR: Illegal PiDmaCopy direction!\n"));

                        ret = -1;
		}
	}  /* switch */

	return(ret);

}  /* IoPiDmaCopy */


int	
PiTestStatus(int testBits, int reset, int a3, int a4)
{
	/* Read the PI status reg and compare it against testBits */

	piPollStatus(testBits, reset);
	return(1);		/* Return 1 to avoid printing Passed test */

}  /* PiTestStatus */


int	
PiTestReg(int regAddr, int data, int a3, 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("\tPI Status Reg = 0x%08x\n", 
		IO_READ(PI_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 (data != ret) {
		errorCount++;
		_TRACE(DERROR, LOG_ERROR(data, ret));
	}

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

}  /* PiTestReg */


int
PiTestIoRead(int domAddr, int data, int a3, int failExpected)
{
	/* CPU performs read from cartridge devices */

	unsigned int ret;

	errorCount = 0;

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

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

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

}  /* PiTestIoRead */


int
PiTestIoWrite(int domAddr, int data, int a3, int failExpected)
{
	/* CPU performs write to cartridge devices */

	unsigned int ret;

	errorCount = 0;

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

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

	IoPiWrite((unsigned int)domAddr, (unsigned int)data);
	ret = IoPiRead((unsigned int)domAddr);
	if (data != ret) {
		if (!failExpected)
			errorCount++;
		_TRACE(DERROR, LOG_ERROR(data, ret));
	}
	errorTotal += errorCount;
		
	return((errorCount == 0) ? 0 : -1);

}  /* PiTestIoWrite */


int
PiTestDma(int dir, int piAddr, int ramAddr, int nbytes)
{
	/* CPU issues DMA (read/write) requests between PI devices and RDRAM */

	unsigned int i, d1, d2;

	errorCount = 0;

	piAddr &= 0xFFFFFFFE;		/* Make sure it's half-word aligned */
	ramAddr &= 0xFFFFFFFE;		/* Make sure it's half-word aligned */

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

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

}  /* PiTestDma */


int
PiTestDmaPg(int type, int piAddr, int dramAddr, int npages)
{
	/* 
	 * CPU issues DMA (read/write) requests between SI devices 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 */
	piAddr  &= 0xFFFFFFFC;

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

	for (i=0; i < npages; i++) {
#ifndef CHECK_STATUS
		piPollStatus(PI_STATUS_ERROR | PI_STATUS_DMA_BUSY |
			PI_STATUS_IO_BUSY, FALSE);
#endif
		nbytes	+= (i*2);
		address = (dramAddr + (i*RDRAM_PAGE_SIZE)) & 0xFFFFFFFC;
		if (IoPiDmaCopy(dir, (unsigned int)piAddr, 
			(unsigned int)address, nbytes-1) < 0) {
			errorCount++;
		}
	}
	errorTotal += errorCount;

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

}  /* PiTestDmaPg */