summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/arch/mips/board/bcm63xx_rom/src/memtest.c
diff options
context:
space:
mode:
Diffstat (limited to 'cfe/cfe/arch/mips/board/bcm63xx_rom/src/memtest.c')
-rwxr-xr-xcfe/cfe/arch/mips/board/bcm63xx_rom/src/memtest.c1031
1 files changed, 1031 insertions, 0 deletions
diff --git a/cfe/cfe/arch/mips/board/bcm63xx_rom/src/memtest.c b/cfe/cfe/arch/mips/board/bcm63xx_rom/src/memtest.c
new file mode 100755
index 0000000..310fb40
--- /dev/null
+++ b/cfe/cfe/arch/mips/board/bcm63xx_rom/src/memtest.c
@@ -0,0 +1,1031 @@
+/*
+ *----------------------------------------------------------------------------*
+ * Collection of Memory Tests.
+ *----------------------------------------------------------------------------*
+ */
+
+//
+// NOTE: Blatant inlining ... (not sure whether caller supports EABI calls).
+// WARNING CFE: Must NOT use function calls !!!
+//
+#define _ALWAYS_INLINE_ __attribute__((always_inline))
+#define _INLINE_ inline static
+
+typedef enum memTestResult {
+ MEMTEST_FAILURE = 0,
+ MEMTEST_SUCCESS,
+ MEMTEST_ERROR,
+} MemTestResult_t;
+
+/* ------------------------------------------------------------------------- */
+
+#undef PATTERN
+#define PATTERN(x) PATTERN_##x,
+
+/*
+ * For each pattern listed, the inverse pattern is also automatically used.
+ * E.g. 0x55555555, the inverse of defined 0xAAAAAAAA is covered.
+ */
+typedef enum pattern {
+ PATTERN(0x00000000)
+ PATTERN(0xAAAAAAAA)
+ PATTERN(0xCCCCCCCC)
+ PATTERN(0x77777777)
+ PATTERN(0xF0F0F0F0)
+ PATTERN(0xFF00FF00)
+ PATTERN(0xFFFF0000)
+ PATTERN(0x01234567)
+ PATTERN(0x89ABCDEF)
+ PATTERN_MAX,
+} Pattern_t;
+
+#undef PATTERN
+#define PATTERN(x) x,
+const uint32_t pattern[] = {
+ PATTERN(0x00000000)
+ PATTERN(0xAAAAAAAA)
+ PATTERN(0xCCCCCCCC)
+ PATTERN(0x77777777)
+ PATTERN(0xF0F0F0F0)
+ PATTERN(0xFF00FF00)
+ PATTERN(0xFFFF0000)
+ PATTERN(0x01234567)
+ PATTERN(0x89ABCDEF)
+ PATTERN_MAX,
+};
+
+/* ------------------------------------------------------------------------- */
+
+#ifndef NBBY
+#define NBBY 8 /* FreeBSD style: Number Bits per BYte */
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+#define NBITS(type) (sizeof(type) * NBBY)
+#define NBITVAL(nbits) (1 << (nbits))
+#define MAXBITVAL(nbits) ( NBITVAL(nbits) - 1)
+#define NBITMASK(nbits) MAXBITVAL(nbits)
+#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * NBBY)
+
+#define DIVBY(val32,by) ((val32)>>(by))
+#define MODBY(val32,by) ((val32) & ((1 <<(by)) - 1) )
+
+#define IS_POWEROF2(val32) ( (((val32)-1) & (val32)) == 0 )
+
+#define ROUNDDN(addr, align) ( (addr) & ~((align) - 1) )
+#define ROUNDUP(addr, align) ( ((addr) + (align) - 1) & ~((align) - 1) )
+//#define ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y))
+#define ALIGN_ADDR(addr, bytes) (void *)( ((uint32_t *)(addr) + (bytes) - 1) \
+ & ~((bytes) - 1) )
+#define IS_ALIGNED(addr, bytes) (((uint32_t)(addr) & ((bytes)-1)) == 0)
+
+#define OFFSET_OF(stype,member) ((uint32_t) &((struct stype *)0)->member)
+#define RELOC(base,stype,member) ((base) + OFFSET_OF(stype, member))
+
+#define RROTATE32(val32) (((val32) << 31) | ((val32) >> 1))
+#define LROTATE32(val32) (((val32) << 1) | ((val32) >> 31))
+
+/* ------------------------------------------------------------------------- */
+
+/* Aligned (32bit register) read/write access */
+#define RD16(addr16) (*(volatile uint32_t *)(addr16))
+#define WR16(addr16,val16) (*(volatile uint32_t *)(addr16))=(val16)
+#define RD32(addr32) (*(volatile uint32_t *)(addr32))
+#define WR32(addr32,val32) (*(volatile uint32_t *)(addr32))=(val32)
+
+/*---------------------------------------------------------------------------*/
+
+/* Forward declaration */
+_INLINE_ void fill_memory( uint32_t * addr, uint32_t bytes, uint32_t fill32)
+ _ALWAYS_INLINE_;
+_INLINE_ void fill_alt_memory(uint32_t * addr, uint32_t bytes,
+ uint32_t fillA32, uint32_t fillB32) _ALWAYS_INLINE_;
+
+void fill_memory( uint32_t * addr, uint32_t bytes, uint32_t fill32)
+{
+ uint32_t * at, * end_p;
+ uint32_t words;
+ words = bytes / sizeof(uint32_t);
+ if ( words == 0 ) return;
+
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ WR32( at, fill32 );
+}
+
+void fill_alt_memory( uint32_t * addr, uint32_t bytes,
+ uint32_t fillA32, uint32_t fillB32)
+{
+ uint32_t * at, * end_p;
+ uint32_t words;
+ words = bytes / sizeof(uint32_t);
+ words = ROUNDDN( words, 2 );
+ if ( words == 0 ) return;
+
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at+=2 )
+ {
+ WR32( at+0, fillA32 );
+ WR32( at+1, fillB32 );
+ }
+}
+
+/* Forward declaration */
+_INLINE_ MemTestResult_t scanWordValue( uint32_t * addr, uint32_t bytes,
+ uint32_t pat32 ) _ALWAYS_INLINE_;
+_INLINE_ MemTestResult_t scanBulkValue( uint32_t * addr, uint32_t bytes,
+ uint32_t pat32 ) _ALWAYS_INLINE_;
+_INLINE_ MemTestResult_t scanBulkAltInv( uint32_t * addr, uint32_t bytes,
+ uint32_t pat32 ) _ALWAYS_INLINE_;
+_INLINE_ MemTestResult_t scanWordSelf( uint32_t * addr, uint32_t bytes )
+ _ALWAYS_INLINE_;
+_INLINE_ MemTestResult_t scanBulkSelf( uint32_t * addr, uint32_t bytes )
+ _ALWAYS_INLINE_;
+_INLINE_ MemTestResult_t slidingAltInv( uint32_t * addr, uint32_t bytes,
+ uint32_t pat32 ) _ALWAYS_INLINE_;
+_INLINE_ MemTestResult_t slidingDiag( uint32_t * addr, uint32_t bytes,
+ uint32_t pat32 ) _ALWAYS_INLINE_;
+_INLINE_ MemTestResult_t memoryBulkCopy( uint32_t * saddr, uint32_t * daddr,
+ uint32_t bytes ) _ALWAYS_INLINE_;
+
+/*
+ *-----------------------------------------------------------------------------
+ * Function: scanWordValue
+ *
+ * Description:
+ * 4 Passes are conducted on the memory region.
+ * Pass 1. In INcreasing memory address, write a word with value and verify.
+ * Pass 2. In DEcreasing memory address, write a word with value and verify.
+ * Pass 3. In INcreasing memory address, write a word with INVERSE and verify.
+ * Pass 4. In DEcreasing memory address, write a word with INVERSE and verify.
+ * Pass 5. In INcreasing shifted memory address, write word with value verify.
+ * Pass 6. In INcreasing shifted memory address, write word with INVERSE verify.
+ *
+ * Parameters:
+ * addr: word aligned pointer to memory region
+ * bytes: size in bytes of memory region to test
+ * pat32: 32bit pattern, e.g. 0x0U, 0xAAAAAAAA, 0xFF00FF00, 0xFFFF0000,
+ * 0xF0F0F0F0, 0xC3C3C3C3, 0x87878787
+ *-----------------------------------------------------------------------------
+ */
+MemTestResult_t scanWordValue( uint32_t * addr, uint32_t bytes, uint32_t pat32 )
+{
+ volatile uint32_t * at, * end_p;
+ uint32_t expected, read, words;
+ uint32_t shift;
+
+ if ( ! IS_ALIGNED(addr,4) ) return MEMTEST_ERROR;
+
+ words = bytes / sizeof(uint32_t); /* in whole words (4byte multiple) */
+ if ( words == 0 )
+ return MEMTEST_ERROR;
+
+ expected = pat32; /* ORIGINAL value */
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ WR32( at, expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ WR32( at, expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ expected = ~pat32; /* INVERSE value */
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ WR32( at, expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ WR32( at, expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* PASS 5: Shifting address walk, ORIGINAL */
+ expected = pat32; /* ORIGINAL value */
+
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ WR32( at, expected );
+ WR32( addr, ~expected ); /* noise at base addr */
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ expected = ~pat32; /* INVERSE value */
+
+ /* PASS 6: Shifting address walk, INVERSE */
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ WR32( at, expected );
+ WR32( addr, ~expected ); /* noise at base addr */
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ return MEMTEST_SUCCESS;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ * Function: scanBulkValue
+ *
+ * Description:
+ * Pass 1. Fill entire memory in INcreasing memory address with value
+ * then in INcreasing memory address read and verify.
+ * Pass 2. Fill entire memory in DEcreasing memory address with value
+ * then in DEcreasing memory address read and verify.
+ * Pass 3. Fill entire memory in INcreasing memory address with inverse value
+ * then in INcreasing memory address read and verify.
+ * Pass 4. Fill entire memory in DEcreasing memory address with inverse value
+ * then in DEcreasing memory address read and verify.
+ * Pass 5. INcreasing shifted, ORIGINAL
+ * Pass 6. INcreasing shifted, INVERSE
+ *
+ * Parameters:
+ * addr: word aligned pointer to memory region
+ * bytes: size in bytes of memory region to test
+ * pat32: 32bit pattern, e.g. 0x0U, 0xAAAAAAAA, 0xFF00FF00, 0xFFFF0000,
+ * 0xF0F0F0F0, 0xC3C3C3C3, 0x87878787
+ *-----------------------------------------------------------------------------
+ */
+MemTestResult_t scanBulkValue( uint32_t * addr, uint32_t bytes, uint32_t pat32 )
+{
+ volatile uint32_t * at, * end_p;
+ uint32_t expected, read, words;
+ uint32_t shift;
+
+ if ( ! IS_ALIGNED(addr,4) ) return MEMTEST_ERROR;
+
+ words = bytes / sizeof(uint32_t); /* in whole words (4byte multiple) */
+ if ( words == 0 ) return MEMTEST_ERROR;
+
+ expected = pat32; /* ORIGINAL value */
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ WR32( at, expected );
+ }
+ for ( at = addr; at < end_p; at++ )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ WR32( at, expected );
+ }
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ expected = ~pat32; /* INVERSE value */
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ WR32( at, expected );
+ }
+ for ( at = addr; at < end_p; at++ )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ WR32( at, expected );
+ }
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* Pass 5. INCREASING Shifted traversal */
+ expected = pat32; /* ORIGINAL value */
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ WR32( at, expected );
+ WR32( addr, ~expected ); /* noise at base addr */
+ }
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ expected = ~pat32; /* INVERSE value */
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ WR32( at, expected );
+ WR32( addr, ~expected ); /* noise at base addr */
+ }
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ return MEMTEST_SUCCESS;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ * Function: scanBulkAltInv
+ *
+ * Description:
+ * Pass 1. Fill entire memory in INcreasing memory address with alternating
+ * value, then in INcreasing memory address read and verify.
+ * Pass 2. Fill entire memory in DEcreasing memory address with alternating
+ * value, then in DEcreasing memory address read and verify.
+ * Pass 3. Same as one but with shifted address.
+ *
+ * Parameters:
+ * addr: word aligned pointer to memory region
+ * bytes: size in bytes of memory region to test
+ * pat32: 32bit pattern, e.g. 0x0U, 0xAAAAAAAA, 0xFF00FF00, 0xFFFF0000,
+ * 0xF0F0F0F0, 0xC3C3C3C3, 0x87878787
+ *-----------------------------------------------------------------------------
+ */
+MemTestResult_t scanBulkAltInv( uint32_t * addr, uint32_t bytes, uint32_t pat32 )
+{
+ volatile uint32_t * at, * end_p;
+ uint32_t read, words;
+ uint32_t shift;
+
+ if ( ! IS_ALIGNED(addr,4) ) return MEMTEST_ERROR;
+
+ words = bytes / sizeof(uint32_t); /* in whole words (4byte multiple) */
+ words = ROUNDDN( words, 2 );
+ if ( words == 0 ) return MEMTEST_ERROR;
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at+=2 )
+ {
+ WR32( at+0, pat32 );
+ WR32( at+1, ~pat32 );
+ }
+ for ( at = addr; at < end_p; at+=2 )
+ {
+ read = RD32( at+0 );
+ if ( read != pat32 )
+ {
+ return MEMTEST_FAILURE;
+ }
+ read = RD32( at+1 );
+ if ( read != ~pat32 )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-=2 )
+ {
+ WR32( at+0, pat32 );
+ WR32( at+1, ~pat32 );
+ }
+ for ( at = addr + words - 1; at >= end_p; at-=2 )
+ {
+ read = RD32( at+0 );
+ if ( read != pat32 )
+ {
+ return MEMTEST_FAILURE;
+ }
+ read = RD32( at+1 );
+ if ( read != ~pat32 )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* INCREASING SHIFTED traversal */
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ WR32( at+0, pat32 );
+ WR32( addr, 0 );
+ WR32( at+1, ~pat32 );
+ WR32( addr, 0 );
+ }
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ read = RD32( at+0 );
+ if ( read != pat32 )
+ {
+ return MEMTEST_FAILURE;
+ }
+ read = RD32( at+1 );
+ if ( read != ~pat32 )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ return MEMTEST_SUCCESS;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ * Function: scanWordSelf
+ *
+ * Description:
+ * 4 Passes are conducted on the memory region.
+ * Pass 1. In INcreasing memory address, write a word with selfaddr and verify.
+ * Pass 2. In DEcreasing memory address, write a word with INVERSE and verify.
+ * Pass 3. In INcreasing memory address, write a word with INVERSE and verify.
+ * Pass 4. In DEcreasing memory address, write a word with selfaddr and verify.
+ * Pass 5. value = ORIGINAL address, INCREASING SHIFTED traversal.
+ * Pass 6. value = INVERSE address, INCREASING SHIFTED traversal.
+ *
+ * In Pass 2 Read+Modify+Write, and in Pass 3, Read+Write is used
+ *
+ * Parameters:
+ * addr: word aligned pointer to memory region
+ * bytes: size in bytes of memory region to test
+ *
+ *-----------------------------------------------------------------------------
+ */
+MemTestResult_t scanWordSelf( uint32_t * addr, uint32_t bytes )
+{
+ volatile uint32_t * at, * end_p;
+ uint32_t expected, read, words;
+ uint32_t shift;
+
+ if ( ! IS_ALIGNED(addr,4) ) return MEMTEST_FAILURE;
+
+ words = bytes / sizeof(uint32_t); /* in whole words (4byte multiple) */
+ if ( words == 0 ) return MEMTEST_ERROR;
+
+ /* ORIGINAL value */
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ expected = (uint32_t)at;
+ WR32( at, expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ expected = ~( (uint32_t)RD32(at) );
+ WR32( at, expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ expected = ((uint32_t)RD32(at));
+ WR32( at, expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ expected = ~((uint32_t)at);
+ WR32( at, expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* value = ORIGINAL address, INCREASING SHIFTED traversal */
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ expected = (uint32_t)at; /* Not read modify write */
+ WR32( at, expected );
+ WR32( addr, ~expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* value = INVERSE address, INCREASING SHIFTED traversal */
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ expected = ~(uint32_t)(at); /* Not read modify write */
+ WR32( at, expected );
+ WR32( addr, ~expected );
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ return MEMTEST_SUCCESS;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ * Function: scanBulkSelf
+ *
+ * Description:
+ * Pass 1. Fill entire memory in INcreasing memory address with self address
+ * then in INcreasing memory address read and verify.
+ * Pass 2. Fill entire memory in DEcreasing memory address with self address
+ * then in DEcreasing memory address read and verify.
+ * Pass 3. Fill entire memory in INcreasing memory address with inverse addr
+ * then in INcreasing memory address read and verify.
+ * Pass 4. Fill entire memory in DEcreasing memory address with inverse addr
+ * then in DEcreasing memory address read and verify.
+ * Pass 5. Same as Pass 1 but with shifted address
+ * Pass 6. Same as Pass 3 but with shifted address
+ *
+ * Parameters:
+ * addr: word aligned pointer to memory region
+ * bytes: size in bytes of memory region to test
+ *-----------------------------------------------------------------------------
+ */
+MemTestResult_t scanBulkSelf( uint32_t * addr, uint32_t bytes )
+{
+ volatile uint32_t * at, * end_p;
+ uint32_t read, words;
+ uint32_t shift;
+
+ if ( ! IS_ALIGNED(addr,4) ) return MEMTEST_ERROR;
+
+ words = bytes / sizeof(uint32_t); /* in whole words (4byte multiple) */
+ if ( words == 0 ) return MEMTEST_ERROR;
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ WR32( at, (uint32_t)at );
+ }
+ for ( at = addr; at < end_p; at++ )
+ {
+ read = RD32(at);
+ if ( read != (uint32_t)at )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ WR32( at, (uint32_t)at );
+ }
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ read = RD32(at);
+ if ( read != (uint32_t)at )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ WR32( at, ~((uint32_t)at) );
+ }
+ for ( at = addr; at < end_p; at++ )
+ {
+ read = RD32(at);
+ if ( read != ~((uint32_t)at) )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ WR32( at, ~((uint32_t)at) );
+ }
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ read = RD32(at);
+ if ( read != ~((uint32_t)at) )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ WR32( at, (uint32_t)at );
+ WR32( addr, ~((uint32_t)at) );
+ }
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ read = RD32(at);
+ if ( read != (uint32_t)at )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ WR32( at, ~((uint32_t)at) );
+ WR32( addr, ((uint32_t)at) );
+ }
+ shift = sizeof(uint32_t);
+ for ( at = addr + shift; at < end_p; shift <<= 1, at = addr + shift )
+ {
+ read = RD32(at);
+ if ( read != ~((uint32_t)at) )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ return MEMTEST_SUCCESS;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ * Function: slidingAltInv
+ *
+ * Description:
+ * This is the same as scanBulkAltInv, where in each invocation the value is
+ * rotated to the right. The starting value is usedefined.
+ *
+ * Parameters:
+ * addr: word aligned pointer to memory region
+ * bytes: size in bytes of memory region to test
+ * pat32: pattern to slide per pass
+ *-----------------------------------------------------------------------------
+ */
+MemTestResult_t slidingAltInv( uint32_t * addr, uint32_t bytes, uint32_t pat32 )
+{
+ uint32_t sliding_pat32, i;
+
+ if ( pat32 == 0x0 ) pat32 = 0x80000000;
+ if ( pat32 == ~0x0 ) pat32 = 0x7FFFFFFF;
+
+ sliding_pat32 = pat32;
+
+ for ( i=0; i<32; i++ )
+ {
+ if ( scanBulkAltInv( addr, bytes, sliding_pat32 )
+ == MEMTEST_FAILURE )
+ {
+ return MEMTEST_FAILURE;
+ }
+
+ sliding_pat32 = RROTATE32( sliding_pat32 );
+ }
+
+ sliding_pat32 = pat32;
+ for (i=0; i<32; i++)
+ {
+ if ( scanBulkAltInv( addr, bytes, sliding_pat32 )
+ == MEMTEST_FAILURE )
+ {
+ return MEMTEST_FAILURE;
+ }
+
+ sliding_pat32 = LROTATE32( sliding_pat32 );
+ }
+
+ return MEMTEST_SUCCESS;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ * Function: slidingDiag
+ *
+ * Description:
+ * Pass 1. Fill entire memory in INcreasing memory address with pattern right
+ * shifted. Then read in INcreasing order and verify.
+ * Pass 2. Fill entire memory in DEcreasing memory address with inverse of
+ * read value. Then read in DEcreasing order and verify.
+ * Pass 3. Fill entire memory in DEcreasing memory address with pattern right
+ * shifted. Then read in DEcreasing order and verify.
+ * Pass 4. Fill entire memory in INcreasing memory address with inverse of
+ * read value. Then read in INcreasing order and verify.
+ *
+ * Parameters:
+ * addr: word aligned pointer to memory region
+ * bytes: size in bytes of memory region to test
+ * pat32: pattern to be filled shifted each write
+ *-----------------------------------------------------------------------------
+ */
+MemTestResult_t slidingDiag( uint32_t * addr, uint32_t bytes, uint32_t pat32 )
+{
+ volatile uint32_t * at, * end_p;
+ uint32_t expected, read = 0, words, last;
+
+ if ( ! IS_ALIGNED(addr,4) ) return MEMTEST_ERROR;
+
+ words = bytes / sizeof(uint32_t); /* in whole words (4byte multiple) */
+ if ( words == 0 ) return MEMTEST_ERROR;
+
+
+ /* INCREASING traversal */
+ expected = pat32; /* ORIGINAL value */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ WR32( at, expected );
+ expected = RROTATE32( expected ); /* next expected */
+ }
+ expected = pat32; /* ORIGINAL value */
+ for ( at = addr; at < end_p; at++ )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ expected = RROTATE32( expected ); /* next expected */
+ }
+
+ last = ~( read ); /* Starting value for decreasing traversal, next */
+
+ /* DECREASING traversal */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ expected = ~( RD32(at) );
+ WR32( at, expected );
+ }
+ expected = last;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ expected = LROTATE32( expected );
+ }
+
+ /* DECREASING traversal */
+ expected = pat32; /* ORIGINAL value */
+ end_p = addr;
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ WR32( at, expected );
+ expected = RROTATE32( expected ); /* next expected */
+ }
+ expected = pat32; /* ORIGINAL value */
+ for ( at = addr + words - 1; at >= end_p; at-- )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ expected = RROTATE32( expected ); /* next expected */
+ }
+
+ last = ~( read );
+
+ /* INCREASING traversal */
+ end_p = addr + words;
+ for ( at = addr; at < end_p; at++ )
+ {
+ expected = ~( RD32(at) );
+ WR32( at, expected );
+ }
+ expected = last;
+ for ( at = addr; at < end_p; at++ )
+ {
+ read = RD32(at);
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ expected = LROTATE32( expected );
+ }
+
+ return MEMTEST_SUCCESS;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ * Function: memoryBulkCopy
+ *
+ * Description:
+ * Pass 1. Copy entire ORIGINAL memory in INcreasing memory address, then verify
+ * Pass 2. Copy entire ORIGINAL memory in DEcreasing memory address, then verify
+ * Pass 3. Copy entire INVERSE memory in INcreasing memory address, then verify
+ * Pass 4. Copy entire INVERSE memory in DEcreasing memory address, then verify
+ *-----------------------------------------------------------------------------
+ */
+MemTestResult_t memoryBulkCopy( uint32_t * saddr, uint32_t * daddr,
+ uint32_t bytes )
+{
+ volatile uint32_t * src_p, * dst_p, * end_p;
+ uint32_t expected, read, words;
+
+ if ( ! IS_ALIGNED(saddr,4) ) return MEMTEST_ERROR;
+ if ( ! IS_ALIGNED(daddr,4) ) return MEMTEST_ERROR;
+
+ words = bytes / sizeof(uint32_t); /* in whole words (4byte multiple) */
+ if ( words == 0 ) return MEMTEST_ERROR;
+
+ if ( (uint32_t)saddr < (uint32_t)daddr )
+ {
+ if ( (uint32_t)(saddr + words) > (uint32_t)daddr )
+ return MEMTEST_ERROR;
+ }
+ else if ( (uint32_t)daddr < (uint32_t)saddr )
+ {
+ if ( (uint32_t)(daddr + words) > (uint32_t)saddr )
+ return MEMTEST_ERROR;
+ }
+
+ /* INCREASING traversal ORIGINAL */
+ end_p = saddr + words;
+ for ( src_p = saddr, dst_p = daddr; src_p < end_p; src_p++, dst_p++ )
+ {
+ expected = RD32( dst_p );
+ WR32( src_p, expected );
+ }
+ for ( src_p = saddr, dst_p = daddr; src_p < end_p; src_p++, dst_p++ )
+ {
+ expected = RD32( dst_p );
+ read = RD32( src_p );
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal ORIGINAL */
+ end_p = saddr;
+ for ( src_p = saddr + words - 1, dst_p = daddr + words - 1;
+ src_p >= end_p; src_p--, dst_p-- )
+ {
+ expected = RD32( dst_p );
+ WR32( src_p, expected );
+ }
+ for ( src_p = saddr + words - 1, dst_p = daddr + words - 1;
+ src_p >= end_p; src_p--, dst_p-- )
+ {
+ expected = RD32( dst_p );
+ read = RD32( src_p );
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* INCREASING traversal INVERSE */
+ end_p = saddr + words;
+ for ( src_p = saddr, dst_p = daddr; src_p < end_p; src_p++, dst_p++ )
+ {
+ expected = ~( RD32( dst_p ) );
+ WR32( src_p, expected );
+ }
+ for ( src_p = saddr, dst_p = daddr; src_p < end_p; src_p++, dst_p++ )
+ {
+ expected = ~( RD32( dst_p ) );
+ read = RD32( src_p );
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ /* DECREASING traversal INVERSE */
+ end_p = saddr;
+ for ( src_p = saddr + words - 1, dst_p = daddr + words - 1;
+ src_p >= end_p; src_p--, dst_p-- )
+ {
+ expected = ~( RD32( dst_p ) );
+ WR32( src_p, expected );
+ }
+ for ( src_p = saddr + words - 1, dst_p = daddr + words - 1;
+ src_p >= end_p; src_p--, dst_p-- )
+ {
+ expected = ~( RD32( dst_p ) );
+ read = RD32( src_p );
+ if ( read != expected )
+ {
+ return MEMTEST_FAILURE;
+ }
+ }
+
+ return MEMTEST_SUCCESS;
+}
+
+/*---------------------------------------------------------------------------*/