diff options
Diffstat (limited to 'cfe/cfe/arch/mips/board/bcm63xx_rom/src/memtest.c')
-rwxr-xr-x | cfe/cfe/arch/mips/board/bcm63xx_rom/src/memtest.c | 1031 |
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; +} + +/*---------------------------------------------------------------------------*/ |