iomem.c 4.86 KB

/*************************************************************************
 *
 *  File: iomem.c
 *
 *  This file contains the generic routines to read/write/poll memory.
 *
 *  $Header: /root/leakn64/depot/rf/sw/bbplayer/iosim/src/iomem.c,v 1.3 2002/11/01 19:40:23 whs Exp $
 *
 */

#include <stdio.h>
#include "trace.h"
#include "iomap.h"
#include "iotest.h"
#include <time.h>
#define POLLING_TIMEOUT  2700    /* 45 minutes */

/***********************************************************************
 * Routines
 */
int
MemRead(int addr, int a2, int a3, int a4)
{
	unsigned int ret;

	ret = IO_READ(addr);

	_TRACE(DALL, fprintf(LogFp, "\n\tRead: %08x: %08x", addr, ret));

	return(1);
 
}  /* MemRead */


int
MemReadCompare(int addr, int data, int a3, int failExpected)
{
	unsigned int ret;

	errorCount = 0;

	ret = IO_READ(addr);
	if (data != ret) {
		if (!failExpected)
			errorCount++;
		_TRACE(DERROR, LOG_ERROR(data, ret));
	}
	errorTotal += errorCount;

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

}  /* MemReadCompare */


int
MemWrite(int addr, int data, int a3, int a4)
{
	IO_WRITE(addr, data);
	return(1);
 
}  /* MemWrite */


int
MemWriteRead(int addr, int data, int exp, int failExpected)
{
	unsigned int ret;

	errorCount = 0;

	IO_WRITE(addr, data);
	ret = IO_READ(addr);
	if (exp != ret) {
		if (!failExpected)
			errorCount++;
		_TRACE(DERROR, LOG_ERROR(exp, ret));
	}

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

}  /* MemWrite */

int
MemReadWrite(int addr1, int addr2, int a3, int a4)
{
        unsigned int data;

        data = IO_READ(addr1);
	IO_WRITE(addr2, data);

	return(1);
}  /* MemWrite */

int
MemReadWriteMask(int addr1, int addr2, int mask, int a4)
{
	unsigned int data;

	data = IO_READ(addr1);
	data &= mask;
	IO_WRITE(addr2, data);

	return(1);
}  /* MemWrite */

int
MemPollStatus(int addr, int bits, int cleared, int a4)
{
        /* Poll a register status until the bits are either set or cleared */

        int stat;
	time_t start, end;

	start = time(NULL);
        while (1) {
                stat = IO_READ(addr);
                _TRACE(DSTATUS, fprintf(LogFp, "\n\tStatus = 0x%08x\n",stat));
		if (cleared) {
        		if (!(stat & bits)) break;
		}
		else {
        		if (stat & bits) break;
		}
		end = time(NULL);
		if ((end-start) >= POLLING_TIMEOUT) {
			fprintf(stderr, "\n Failed Polling Status timeout");	
			return 1;
		}
        }

        return(1);

}  /* MemPollStatus */


int
MemCompare(int src, int dst, int nbytes, int failExpected)
{
	/* Compare 'nbytes' bytes between source 'src' and destination 'dst' */
	/* 'nbytes' must be even and addresses word-aligned */

        int i;
	unsigned int w1, w2;

	errorCount = 0;

	_TRACE(DCOMPARE, fprintf(LogFp,"\n\tSRC\t\t\t\tDST\n"));

	src &= 0xFFFFFFFC;	/* Ensure addresses are word-aligned */
	dst &= 0xFFFFFFFC;

	i = 0;
	while (i < nbytes) {
                w1 = IO_READ(src+i);
                w2 = IO_READ(dst+i);
		i += 4;

		_TRACE(DCOMPARE, fprintf(LogFp, 
			"\n\t%08x: %08x\t%08x: %08x\t",
			src+i, w1, dst+i, w2));

		if (i > nbytes ) {
			/* Here, compare the LSB 2 bytes only */
			if ((w1 & 0xFFFF0000) != (w2 & 0xFFFF0000)) {
				if (!failExpected)
					errorCount++;
                        	_TRACE(DERROR, LOG_ERROR((w1 & 0xFFFF0000),
					 (w2 & 0xFFFF0000)));
				break;
			}
		} else if (w1 != w2) {
			if (!failExpected)
				errorCount++;
                        _TRACE(DERROR, LOG_ERROR(w1, w2));
			break;
		}

	}

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

}  /* MemCompare */


int
MemDump(int addr, int nwords, int a3, int a4)
{
	/* Dump data starting at address */

	unsigned int i, d1;

	addr &= 0xFFFFFFFC;

	for (i = 0; i < nwords; i++) {
		d1 = IO_READ((unsigned int)addr+(i*4));
		_TRACE(DALL, fprintf(LogFp,"\n\t%08x: %08x", addr+(i*4), d1));
	}
	_TRACE(DALL, fprintf(LogFp,"\n"));

	return(1);

}  /* MemDump */

int
MemReadUntil(int addr, int mask, int data, int a4)
{
        /* Poll a register status until the bits are either set or cleared */

        int rdata;

        while (1) {
                rdata = IO_READ(addr);
                _TRACE(DSTATUS, fprintf(LogFp, "\n\tData = 0x%08x\n", rdata));
		if ((rdata & mask) == (data & mask)) break;
        }

        return(1);

}  /* MemReadUntil */


int
MemReadCompMask(int addr, int data, int mask, int failExpected)
{
	unsigned int ret;

	errorCount = 0;

	ret = IO_READ(addr);
	if ((data & mask) != (ret & mask)) {
		if (!failExpected)
			errorCount++;
		_TRACE(DERROR, LOG_ERROR(data, ret));
	}
	errorTotal += errorCount;

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

}  /* MemReadCompMask */

int
MemReadCompMaskNoError(int addr, int data, int mask, int failExpected)
{
	unsigned int ret;

	errorCount = 0;

	ret = IO_READ(addr);
	if ((data & mask) != (ret & mask)) {
		if (!failExpected)
			errorCount++;
		_TRACE(DERROR, LOG_ERROR(data, ret));
	}

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

}  /* MemReadCompMaskNoError */