iotestsi.c 5.89 KB

/*************************************************************************
 *
 *  File: iotestsi.c
 *
 *  This file contains test routines for the Serial Interface (SI).
 *
 *  $Header: /root/leakn64/depot/rf/sw/bbplayer/iosim/src/iotestsi.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 SI
 *
 * Note: The SI DRAM address reg (SI_DRAM_ADDR_REG) supports only 24-bit 
 *	 address; the most significant byte and the least significant 2 bits 
 *	 are masked off. The address needs to be word-aligned.
 */
static int
siPollStatus(unsigned int statBits)
{
	/* Poll PI status register for the statBits set */

	unsigned int stat;

	do {
		stat = IO_READ(SI_STATUS_REG);
		_TRACE(DSTATUS, 
			fprintf(LogFp, "\n\tSI Status Reg = 0x%08x\t\t", stat));
		if (stat & SI_STATUS_DMA_ERROR) {
			_TRACE(DERROR, 
			fprintf(LogFp,
				"\n\t****ERROR: SI error bit set: %08x\t\t",
				stat));
			statBits &= ~SI_STATUS_DMA_ERROR;
		}
	}
	while (stat & statBits);

	return((int)stat);

}  /* siPollStatus */


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

	siPollStatus(SI_STATUS_DMA_ERROR | SI_STATUS_RD_BUSY);
	IO_WRITE(address, data);

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

}  /* IoSiWrite */


int	
IoSiRead(unsigned int address)
{
	unsigned int stat;

	siPollStatus(SI_STATUS_DMA_ERROR | SI_STATUS_RD_BUSY);
	return(IO_READ(address));

}  /* IoSiRead */


int
IoSiDmaCopy(int type, unsigned int pifAddr, unsigned int dramAddr)
{
	int ret;

	ret = 0;

#ifdef CHECK_STATUS
	siPollStatus(SI_STATUS_DMA_ERROR | SI_STATUS_DMA_BUSY);
#endif
	IO_WRITE(SI_DRAM_ADDR_REG, dramAddr);

	switch (type) {
		case SI_RD64B: {
			_TRACE(DLOG,
			printf("\tIoSiDmaCopy: RD64B: R=%08x P=%08x\n", 
				dramAddr, pifAddr));
			IO_WRITE(SI_PIF_ADDR_RD64B_REG, pifAddr);
			break;
		}
		case SI_WR64B: {
			_TRACE(DLOG,
			printf("\tIoSiDmaCopy: WR64B: R=%08x P=%08x\n", 
				dramAddr, pifAddr));
			IO_WRITE(SI_PIF_ADDR_WR64B_REG, pifAddr);
			break;
		}
		default: {
			_TRACE(DERROR, fprintf(LogFp,
				"\t****ERROR: Illegal SiDmaCopy type!\t"));
			ret = -1;
		}
	}

	return(ret);

}  /* IoSiDmaCopy */


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

	siPollStatus(testBits);

	return(1);	/* Return 1 to avoid test passed printout */

}  /* SiTestStatus */


int	
SiTestReg(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 */

	/* 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);

	siPollStatus(SI_STATUS_RD_BUSY);

	ret = IO_READ(regAddr);

	/* 
	 * Since the only valid register R/W test is for SI_DRAM_ADDR_REG.
	 * We need to mask off upper 2 bytes and lower 2 bits so that data
	 * is word-aligned and within 24-bit addressing of RDRAM
	 */
	if ((data & 0x00FFFFFC) != ret) {
		errorCount++;
		_TRACE(DERROR, LOG_ERROR(data, ret));
	}

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

}  /* SiTestReg */


int
SiTestIoRead(int pifAddr, int data, int a3, int failExpected)
{
	/* CPU performs read from PIF address space */

	unsigned int ret;

	errorCount = 0;

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

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

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

}  /* SiTestIoRead */


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

	unsigned int ret;

	errorCount = 0;

	pifAddr &= 0xFFFFFFFC;  /* Make sure that it's word aligned */
	
	_TRACE(DLOG, printf("\tSI Status Reg = 0x%08x\n",
		IO_READ(SI_STATUS_REG)));

	IoSiWrite((unsigned int)pifAddr, (unsigned int)data);
	ret = IoSiRead((unsigned int)pifAddr);
	if (data != ret) {
		if (!failExpected)
			errorCount++;
		_TRACE(DERROR, LOG_ERROR(data, ret));
	}
	errorTotal += errorCount;

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

}  /* SiTestIoWrite */


int
SiTestDma(int type, int pifAddr, int dramAddr, int a4)
{
	/* CPU issues DMA (read/write) requests between SI devices and RDRAM */

	unsigned int i, d1, d2;

	errorCount = 0;

	dramAddr &= 0xFFFFFFFC;		/* Make sure it's word aligned */
	pifAddr  &= 0xFFFFFFFC;		/* Make sure it's word aligned */

	/* 
	 * DMA WRITE tests: 
	 *	- Transfer 4/64 bytes between PI <-> RAM 
	 *	- Read each word from RAM and compare it against SI
	 */
	if (IoSiDmaCopy(type, (unsigned int)pifAddr, 
		(unsigned int)dramAddr) < 0) {
		errorCount++;
	}

	errorTotal += errorCount;

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

}  /* SiTestDma */


int
SiTestDmaPg(int type, int pifAddr, 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;
	unsigned int	address;

	errorCount = 0;

	dramAddr &= 0xFFFFFFFC;	    /* Make sure addresses are word aligned */
	pifAddr  &= 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
		siPollStatus(SI_STATUS_DMA_ERROR | SI_STATUS_DMA_BUSY);
#endif
		address = (dramAddr + (i*RDRAM_PAGE_SIZE)) & 0xFFFFFFFC;
		if (IoSiDmaCopy(type, (unsigned int)pifAddr, 
			(unsigned int)address) < 0) {
			errorCount++;
		}
	}
	errorTotal += errorCount;

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

}  /* SiTestDmaPg */