mirror of
https://github.com/ringtailsoftware/uvm32.git
synced 2026-06-05 22:43:39 +00:00
Basic memory test
This commit is contained in:
parent
6878c5210f
commit
0ded19d04a
4 changed files with 286 additions and 0 deletions
13
apps/memtest/Makefile
Normal file
13
apps/memtest/Makefile
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
TOPDIR=../../
|
||||
PROJECT:=$(shell basename ${PWD})
|
||||
|
||||
HEAP_SIZE=$(shell echo "1024 * 1024 * 32" | bc)
|
||||
OPT=-Os
|
||||
CFLAGS=-DHEAP_SIZE=${HEAP_SIZE}
|
||||
SRCS=${PROJECT}.c ${TOPDIR}/apps/crt0.S barr_memtest.c
|
||||
|
||||
HOST_EXTRA=-e ${HEAP_SIZE} -i 4294967295
|
||||
all: all_common
|
||||
test: test_common
|
||||
clean: clean_common
|
||||
include ${TOPDIR}/apps/makefile.common
|
||||
221
apps/memtest/barr_memtest.c
Normal file
221
apps/memtest/barr_memtest.c
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
/**********************************************************************
|
||||
*
|
||||
* Filename: memtest.c
|
||||
*
|
||||
* Description: General-purpose memory testing functions.
|
||||
*
|
||||
* Notes: This software can be easily ported to systems with
|
||||
* different data bus widths by redefining 'datum'.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1998 by Michael Barr. This software is placed into
|
||||
* the public domain and may be used for any purpose. However, this
|
||||
* notice must not be changed or removed and no warranty is either
|
||||
* expressed or implied by its publication or distribution.
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#include "barr_memtest.h"
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Function: memTestDataBus()
|
||||
*
|
||||
* Description: Test the data bus wiring in a memory region by
|
||||
* performing a walking 1's test at a fixed address
|
||||
* within that region. The address (and hence the
|
||||
* memory region) is selected by the caller.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Returns: 0 if the test succeeds.
|
||||
* A non-zero result is the first pattern that failed.
|
||||
*
|
||||
**********************************************************************/
|
||||
datum
|
||||
memTestDataBus(volatile datum * address)
|
||||
{
|
||||
datum pattern;
|
||||
|
||||
|
||||
/*
|
||||
* Perform a walking 1's test at the given address.
|
||||
*/
|
||||
for (pattern = 1; pattern != 0; pattern <<= 1)
|
||||
{
|
||||
/*
|
||||
* Write the test pattern.
|
||||
*/
|
||||
*address = pattern;
|
||||
|
||||
/*
|
||||
* Read it back (immediately is okay for this test).
|
||||
*/
|
||||
if (*address != pattern)
|
||||
{
|
||||
return (pattern);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
||||
} /* memTestDataBus() */
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Function: memTestAddressBus()
|
||||
*
|
||||
* Description: Test the address bus wiring in a memory region by
|
||||
* performing a walking 1's test on the relevant bits
|
||||
* of the address and checking for aliasing. This test
|
||||
* will find single-bit address failures such as stuck
|
||||
* -high, stuck-low, and shorted pins. The base address
|
||||
* and size of the region are selected by the caller.
|
||||
*
|
||||
* Notes: For best results, the selected base address should
|
||||
* have enough LSB 0's to guarantee single address bit
|
||||
* changes. For example, to test a 64-Kbyte region,
|
||||
* select a base address on a 64-Kbyte boundary. Also,
|
||||
* select the region size as a power-of-two--if at all
|
||||
* possible.
|
||||
*
|
||||
* Returns: NULL if the test succeeds.
|
||||
* A non-zero result is the first address at which an
|
||||
* aliasing problem was uncovered. By examining the
|
||||
* contents of memory, it may be possible to gather
|
||||
* additional information about the problem.
|
||||
*
|
||||
**********************************************************************/
|
||||
datum *
|
||||
memTestAddressBus(volatile datum * baseAddress, unsigned long nBytes)
|
||||
{
|
||||
unsigned long addressMask = (nBytes/sizeof(datum) - 1);
|
||||
unsigned long offset;
|
||||
unsigned long testOffset;
|
||||
|
||||
datum pattern = (datum) 0xAAAAAAAA;
|
||||
datum antipattern = (datum) 0x55555555;
|
||||
|
||||
|
||||
/*
|
||||
* Write the default pattern at each of the power-of-two offsets.
|
||||
*/
|
||||
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
|
||||
{
|
||||
baseAddress[offset] = pattern;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for address bits stuck high.
|
||||
*/
|
||||
testOffset = 0;
|
||||
baseAddress[testOffset] = antipattern;
|
||||
|
||||
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
|
||||
{
|
||||
if (baseAddress[offset] != pattern)
|
||||
{
|
||||
return ((datum *) &baseAddress[offset]);
|
||||
}
|
||||
}
|
||||
|
||||
baseAddress[testOffset] = pattern;
|
||||
|
||||
/*
|
||||
* Check for address bits stuck low or shorted.
|
||||
*/
|
||||
for (testOffset = 1; (testOffset & addressMask) != 0; testOffset <<= 1)
|
||||
{
|
||||
baseAddress[testOffset] = antipattern;
|
||||
|
||||
if (baseAddress[0] != pattern)
|
||||
{
|
||||
return ((datum *) &baseAddress[testOffset]);
|
||||
}
|
||||
|
||||
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
|
||||
{
|
||||
if ((baseAddress[offset] != pattern) && (offset != testOffset))
|
||||
{
|
||||
return ((datum *) &baseAddress[testOffset]);
|
||||
}
|
||||
}
|
||||
|
||||
baseAddress[testOffset] = pattern;
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
|
||||
} /* memTestAddressBus() */
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Function: memTestDevice()
|
||||
*
|
||||
* Description: Test the integrity of a physical memory device by
|
||||
* performing an increment/decrement test over the
|
||||
* entire region. In the process every storage bit
|
||||
* in the device is tested as a zero and a one. The
|
||||
* base address and the size of the region are
|
||||
* selected by the caller.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Returns: NULL if the test succeeds.
|
||||
*
|
||||
* A non-zero result is the first address at which an
|
||||
* incorrect value was read back. By examining the
|
||||
* contents of memory, it may be possible to gather
|
||||
* additional information about the problem.
|
||||
*
|
||||
**********************************************************************/
|
||||
datum *
|
||||
memTestDevice(volatile datum * baseAddress, unsigned long nBytes)
|
||||
{
|
||||
unsigned long offset;
|
||||
unsigned long nWords = nBytes / sizeof(datum);
|
||||
|
||||
datum pattern;
|
||||
datum antipattern;
|
||||
|
||||
|
||||
/*
|
||||
* Fill memory with a known pattern.
|
||||
*/
|
||||
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
|
||||
{
|
||||
baseAddress[offset] = pattern;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check each location and invert it for the second pass.
|
||||
*/
|
||||
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
|
||||
{
|
||||
if (baseAddress[offset] != pattern)
|
||||
{
|
||||
return ((datum *) &baseAddress[offset]);
|
||||
}
|
||||
|
||||
antipattern = ~pattern;
|
||||
baseAddress[offset] = antipattern;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check each location for the inverted pattern and zero it.
|
||||
*/
|
||||
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
|
||||
{
|
||||
antipattern = ~pattern;
|
||||
if (baseAddress[offset] != antipattern)
|
||||
{
|
||||
return ((datum *) &baseAddress[offset]);
|
||||
}
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
|
||||
} /* memTestDevice() */
|
||||
41
apps/memtest/barr_memtest.h
Normal file
41
apps/memtest/barr_memtest.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/**********************************************************************
|
||||
*
|
||||
* Filename: memtest.h
|
||||
*
|
||||
* Description: Memory-testing module API.
|
||||
*
|
||||
* Notes: The memory tests can be easily ported to systems with
|
||||
* different data bus widths by redefining 'datum' type.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2000 by Michael Barr. This software is placed into
|
||||
* the public domain and may be used for any purpose. However, this
|
||||
* notice must not be changed or removed and no warranty is either
|
||||
* expressed or implied by its publication or distribution.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef _memtest_h
|
||||
#define _memtest_h
|
||||
|
||||
|
||||
/*
|
||||
* Define NULL pointer value.
|
||||
*/
|
||||
#ifndef NULL
|
||||
#define NULL (void *) 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the data bus width.
|
||||
*/
|
||||
typedef unsigned long datum;
|
||||
|
||||
/*
|
||||
* Function prototypes.
|
||||
*/
|
||||
datum memTestDataBus(volatile datum * address);
|
||||
datum * memTestAddressBus(volatile datum * baseAddress, unsigned long nBytes);
|
||||
datum * memTestDevice(volatile datum * baseAddress, unsigned long nBytes);
|
||||
|
||||
|
||||
#endif /* _memtest_h */
|
||||
11
apps/memtest/memtest.c
Normal file
11
apps/memtest/memtest.c
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#include "uvm32_target.h"
|
||||
#include "barr_memtest.h"
|
||||
|
||||
void main(void) {
|
||||
datum * base = (datum *)UVM32_EXTRAM_BASE;
|
||||
if ((memTestDataBus(base) != 0) || (memTestAddressBus(base, HEAP_SIZE) != NULL) || (memTestDevice(base, HEAP_SIZE) != NULL)) {
|
||||
println("Memory error!");
|
||||
} else {
|
||||
println("Memory ok");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue