[U-Boot-Users] Interactive Memory test patch & new tests
atul.sabharwal at exgate.tek.com
atul.sabharwal at exgate.tek.com
Wed Oct 19 00:23:21 CEST 2005
Description:
Enclosed is a patch to run memory tests using an interactive menu over the
serial port in U-Boot. The patch includes
1. serial_gets() routine
2. New memory tests
1. address/complement address test
2. pattern/complement pattern test
3. peek/poke routines
4. infinite memory test
5. Flash/Ram copy test
The tests are useful to have an interactive Bring Up Diagnostics for a
system.
--- /login/asabharw/lxhome/u-boot-1.1.3/common/serial.c 2005-08-13
16:53:35.000000000 -0700
+++ u-boot-1.1.2/common/serial.c 2005-09-26 17:58:06.000000000 -0700
@@ -38,9 +38,6 @@
#elif defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \
|| defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4)
return &serial_scc_device;
-#elif defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440)
\
- || defined(CONFIG_405EP)
- return &serial0_device;
#else
#error No default console
#endif
@@ -74,12 +71,6 @@
serial_register (&serial_scc_device);
#endif
-#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \
- || defined(CONFIG_405EP)
- serial_register(&serial0_device);
- serial_register(&serial1_device);
-#endif
-
serial_assign (default_serial_console ()->name);
}
@@ -210,4 +201,17 @@
serial_current->puts (s);
}
+void serial_gets (char *s)
+{
+ unsigned int c;
+
+ c = serial_getc();
+ /* Typically <enter> key is lf on linux systems. under minicom it is
<cr>. maybe terminal settings ?? */
+ while(( c != '\r') && (c != '\n'))
+ {
+ *s++ = (char)c;
+ c = serial_getc();
+ }
+ return;
+}
#endif /* CONFIG_SERIAL_MULTI */
--- /login/asabharw/lxhome/u-boot-1.1.3/post/memory.c 2005-08-13
16:53:35.000000000 -0700
+++ u-boot-1.1.2/post/memory.c 2005-10-18 14:53:36.000000000 -0700
@@ -173,6 +173,28 @@
#endif
+#ifdef CFG_POST_MEMORY_INTERACTIVE
+const static unsigned char testpattern[]=
+{
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2F,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+ 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9,
0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+ 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+ 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+ 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
+ 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9,
0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9,
0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
+};
+#endif
+
/*
* This function performs a double word move from the data at
* the source pointer to the location at the destination pointer.
@@ -222,6 +244,9 @@
const unsigned long long otherpattern = 0x0123456789abcdefULL;
+int pattern_copy_test(unsigned long address, unsigned long bytecount,
unsigned char type);
+int inverse_pattern_copy_test(unsigned long address, unsigned long
bytecount, unsigned char type);
+
static int memory_post_dataline(unsigned long long * pmem)
{
unsigned long long temp64;
@@ -413,6 +438,115 @@
return ret;
}
+
+
+/* This is a thorough address/data line test by writting the address value
as *
+ * data value on the memory part.
*/
+int memory_combined_address_data_line_test(const unsigned long start, const
unsigned long end)
+{
+ volatile unsigned long * startptr;
+ unsigned long data;
+
+ printf("Write cycle\n");
+ for( startptr = (unsigned long *) start; startptr < (unsigned long
*) end; startptr++ )
+ {
+ *startptr = (unsigned long) startptr;
+ }
+
+ printf("Verify cycle\n");
+ for( startptr = (unsigned long *) start; startptr < (unsigned long *)
end; startptr++ )
+ {
+ /* Need to read once from the memory location as subsequent read
maybe fine */
+ data = *startptr;
+ if(data != (unsigned long) startptr)
+ {
+ printf("Data mismatch at address %p Expected 0x%08x. Value
0x%08x\n\n", (unsigned long) startptr,
+ (unsigned long)startptr, data);
+ return -1;
+ }
+ }
+ printf("Test Passed\n");
+ return 0;
+}
+
+/* This is a thorough address/data line test by writting the inverse of
address value as *
+ * data value on the memory part.
*/
+int memory_combined_inverse_address_data_line_test(const unsigned long
start, const unsigned long end)
+{
+ volatile unsigned long * startptr;
+ unsigned long data;
+
+ printf("Write cycle\n");
+ for( startptr = (unsigned long *) start; startptr < (unsigned long
*) end; startptr++ )
+ {
+ *startptr = ~((unsigned long) startptr);
+ }
+
+ printf("Verify cycle\n");
+ for( startptr = (unsigned long *) start; startptr < (unsigned long *)
end; startptr++ )
+ {
+ /* Need to read once from the memory location as subsequent read
maybe fine */
+ data = *startptr;
+ if(data != (~(unsigned long) startptr))
+ {
+ printf("Data mismatch at address %p Expected 0x%08x. Value
0x%08x\n\n", (unsigned long) startptr,
+ (~(unsigned long)startptr), data);
+ return -1;
+ }
+ }
+ printf("Test Passed\n");
+ return 0;
+}
+static void memory_read(unsigned long location)
+{
+ int subchoice;
+
+
+ printf("Read mode [ b : byte, h : half word , w : word , d : double
word ] : ");
+ subchoice = serial_getc();
+ printf("\n\n");
+
+ switch(subchoice)
+ {
+ /* Byte Read */
+ case 'b' :
+ {
+ unsigned char * ptr = (unsigned char *) location;
+ printf("\n\nByte Value at location %p is 0x%02x \n\n",
location, *ptr );
+ }
+ break;
+
+ /* Half word Read */
+ case 'h' :
+ {
+ unsigned short * ptr = (unsigned short *) location;
+ printf("\n\n16 bit Value at location %p is 0x%04x \n\n",
location, *ptr);
+ }
+ break;
+
+ /* Word Read */
+ case 'w' :
+ {
+ unsigned long * ptr = (unsigned long *) location;
+ printf("\n32 bit Value at location %p is 0x%08x \n\n",
location, *ptr);
+ }
+ break;
+
+ /* Double Word Read */
+ case 'd' :
+ {
+ unsigned long long * ptr = (unsigned long long *) location;
+ printf("\n64 bit Value at location %p is 0x%08x%08x \n\n",
location,
+ *(unsigned long *)ptr, *(((unsigned long *) ptr)+1));
+ }
+ break;
+
+ default:
+ printf("\nInvalid Choice\n");
+ }
+ return;
+}
+
static int memory_post_tests (unsigned long start, unsigned long size)
{
int ret = 0;
@@ -447,7 +581,30 @@
WATCHDOG_RESET ();
if (ret == 0)
ret = memory_post_test4 (start, size);
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = pattern_copy_test(start, size, 'm');
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_combined_address_data_line_test(start, (start +
(size & 0xFFFFFFFC)));
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_combined_inverse_address_data_line_test(start,
(start + (size & 0xFFFFFFFC)));
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = pattern_copy_test(start, size, 'b');
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = inverse_pattern_copy_test(start, size, 'h');
WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = pattern_copy_test(start, size, 'w');
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = inverse_pattern_copy_test(start, size, 'd');
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = pattern_copy_test(start, size, 's');
return ret;
}
@@ -478,5 +635,589 @@
return ret;
}
+#warning "printf prints junk when we have a parameter in format string but
no argument"
+
+static void memory_write(const unsigned long location)
+{
+ int subchoice;
+ unsigned char input[32];
+ unsigned long long data;
+
+
+ memset(input, 0, strlen(input));
+ printf("Write mode [ b : byte, h : half word , w : word , d : double
word ] : ");
+ subchoice = serial_getc();
+ printf("\n\n");
+
+ switch(subchoice)
+ {
+ /* Byte write */
+ case 'b' :
+ {
+ unsigned char * ptr = (unsigned char *) location;
+
+ printf("Enter Data : 0x ");
+ serial_gets(input);
+ data = simple_strtoul(input, NULL, 16);
+
+ /* Write Data */
+ *ptr = (unsigned char) data;
+ printf("\n\nByte Value at location %p is 0x%02x \n\n",
location, *ptr);
+ }
+ break;
+
+ /* Half Word Write */
+ case 'h' :
+ {
+ unsigned short * ptr = (unsigned short *) location;
+
+ printf("Enter Data : 0x ");
+ serial_gets(input);
+ data = simple_strtoul(input, NULL, 16);
+
+ /* Write Data */
+ *ptr = (unsigned short) data;
+ printf("\n\n16 bit Value at location %p is 0x%04x \n\n",
location, *ptr);
+ }
+ break;
+
+ /* Single word write */
+ case 'w' :
+ {
+ unsigned long * ptr = (unsigned long *) location;
+
+ printf("Enter Data : 0x ");
+ serial_gets(input);
+ data = simple_strtoul(input, NULL, 16);
+
+ /* Write Data */
+ *ptr = (unsigned long) data;
+ printf("\n32 bit Value at location %p is 0x%08x \n\n",
location, *ptr);
+ }
+ break;
+
+ /* Double word write */
+ case 'd' :
+ {
+ unsigned long long * ptr = (unsigned long long *) location;
+
+ printf("Enter Data : 0x ");
+ serial_gets(input);
+ data = simple_strtoul(input, NULL, 16);
+
+ /* Write Data */
+ *ptr = (unsigned long long) data;
+ printf("\nByte Value at location %p is 0x%08x%08x \n\n",
location,
+ *(unsigned long *)ptr, *(((unsigned long *) ptr)+1));
+ }
+ break;
+
+
+ default:
+ printf("\nInvalid Choice\n");
+ }
+ return;
+}
+
+#define MAX_BLOCKS 16
+
+int flash_block_copy_test(unsigned long RamAddress, unsigned long
bytecount, unsigned long blockSize)
+{
+ // break test region into max 16 equal sized blocks
+ /* We copy U-Boot code around as we can compare/verify with JTAG &
network dump's*/
+ const unsigned long flashBase = CFG_FLASH_BASE;
+ unsigned long blockStart[MAX_BLOCKS];
+ unsigned long blockEnd[MAX_BLOCKS];
+ unsigned int numBlocks = ((bytecount / blockSize ) % MAX_BLOCKS);
+ int index;
+
+ blockStart[0] = RamAddress;
+
+ //Setup start & end address for each block
+ for( index = 0; index < numBlocks ; index++ )
+ {
+ blockEnd[index] = (blockStart[index] + blockSize) - 1;
+ blockStart[index + 1] = blockEnd[index] + 1;
+ }
+ blockEnd[index] = (blockStart[index] + blockSize) - 1;
+
+ printf("\n");
+ for( index = 0; index < numBlocks; index++ )
+ {
+ printf( "block %d: %08x - %08x\n", index, blockStart[index],
blockEnd[index] );
+ }
+
+ /* initialize block 0 with contents from the flash ROM. Duplicate
remaining */
+ /* 15 blocks. COPY CYCLE.
*/
+ printf("Copy cycle\n");
+ memcpy((void *)blockStart[0], (void *)flashBase, blockSize);
+ for (index = 1; index < numBlocks; index++)
+ {
+ memcpy((void *)blockStart[index], (void *)blockStart[index - 1],
blockSize);
+ }
+
+ /* Verify CYCLE. */
+ printf("Verify cycle\n");
+ for( index = 1; index < numBlocks; index++ )
+ {
+ if(memcmp((void *) blockStart[index], (void *) blockStart[0],
blockSize) != 0)
+ {
+ printf("Verification error at block %d\n", index);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int pattern_copy_test(unsigned long address, unsigned long bytecount,
unsigned char type)
+{
+ unsigned int i = 0;
+
+ switch(type)
+ {
+ /* Byte Copy Test */
+ case 'b':
+ {
+ /* Write Cycle */
+ printf("\n%u byte copy test starting at address %p\n",
sizeof(unsigned char), address);
+ printf("write cycle\n");
+ for( i = 0; i < bytecount; i += sizeof(unsigned char))
+ *((unsigned char *) (address + i) ) = (unsigned char)
*(testpattern + (i % sizeof(testpattern)));
+
+ printf("read cycle\n");
+ /* Read Cycle */
+ for( i = 0; i < bytecount; i += sizeof(unsigned char))
+ if(*((unsigned char *) (address + i) ) != (unsigned
char) *(testpattern + (i % sizeof(testpattern))))
+ {
+ printf("Data mismatch at address %p Value : 0x%02x
Expected : 0x%02x\n\n",
+ address + i, *((unsigned char *)(address + i)),
+ (unsigned char) *(testpattern + ( i %
sizeof(testpattern))));
+ return -1;
+ }
+
+ }
+ break;
+
+ /* 16 bit Copy Test */
+ case 'h':
+ {
+ /* Write Cycle */
+ printf("\n%u byte copy test starting at address %p\n",
sizeof(unsigned short), address);
+ printf("write cycle\n");
+ for( i = 0; i < bytecount ; i += sizeof(unsigned short))
+ *((unsigned short *) (address + i) ) =
+ *(unsigned short *)(testpattern + (i %
sizeof(testpattern)));
+
+ /* Read Cycle */
+ printf("read cycle\n");
+ for( i = 0; i < bytecount ; i += sizeof(unsigned short))
+ if(*((unsigned short *) (address + i) ) !=
+ *(unsigned short *)(testpattern + (i %
sizeof(testpattern))))
+ {
+ printf("Data mismatch at address %p Value : 0x%04x
Expected : 0x%04x\n\n",
+ (address + i), *((unsigned short *)address +
i),
+ *(unsigned short *)(testpattern + ( i %
sizeof(testpattern))));
+ return -1;
+ }
+ }
+ break;
+
+ /* 32 bit Copy Test */
+ case 'w':
+ {
+ /* Write Cycle */
+ printf("\n%u byte copy test starting at address %p\n\n",
sizeof(unsigned int), address);
+ printf("write cycle\n");
+ for( i = 0; i < bytecount; i += sizeof(unsigned int))
+ *((unsigned int *) (address + i) ) =
+ *(unsigned int *)(testpattern + (i %
sizeof(testpattern)));
+
+ /* Read Cycle */
+ printf("read cycle\n");
+ for( i = 0; i < bytecount; i += sizeof(unsigned int))
+ if(*((unsigned int *) (address + i) ) !=
+ *(unsigned int *)(testpattern + (i %
sizeof(testpattern))))
+ {
+ printf("Data mismatch at address %p Value : 0x%08x
Expected : 0x%08x\n",
+ address + i, *(unsigned int *)(address + i),
+ *(unsigned int *)(testpattern + ( i %
sizeof(testpattern))));
+ return -1;
+ }
+ }
+ break;
+
+ /* 64 bit copy test */
+ case 'd':
+ {
+ /* Write Cycle */
+ printf("\n%u byte copy test starting at address %p\n\n",
sizeof(unsigned long long), address);
+ printf("write cycle\n");
+ for( i = 0; i < bytecount; i += sizeof(unsigned long
long))
+ *((unsigned long long *) (address + i) ) =
+ *(unsigned long long *)(testpattern + (i %
sizeof(testpattern)));
+
+ /* Read Cycle */
+ printf("read cycle\n");
+ for( i = 0; i < bytecount; i += sizeof(unsigned long
long))
+ if(*((unsigned long long *) (address + i) ) !=
+ *(unsigned long long *)(testpattern + (i %
sizeof(testpattern))))
+ {
+ printf("Data mismatch at address %p Value :
0x%08x%08x Expected : 0x%08x%08x\n",
+ address + i, *(unsigned long *)(address + i),
+ *(unsigned long *)(address + i +
sizeof(unsigned long)),
+ *(unsigned long *)(testpattern + ( i %
sizeof(testpattern))),
+ *(unsigned long *)(testpattern + ( (i +
sizeof(unsigned long)) % sizeof(testpattern))));
+ return -1;
+ }
+ }
+ break;
+
+ /* strncpy based block copy */
+ case 's':
+ {
+ unsigned short pattern_length = sizeof(testpattern);
+ unsigned long blockcount = 0;
+
+ /* Write Cycle */
+ printf("\nstrncpy test starting at address %p\n\n",
address);
+ printf("write cycle with pattern size of %u\n",
pattern_length);
+ for( i = 0; i < bytecount; i += pattern_length,
blockcount+=1)
+ strncpy(address + i, testpattern, pattern_length);
+
+ /* Read Cycle */
+ printf("read cycle\n");
+ for( i = 0; (i < bytecount) && (blockcount); i +=
pattern_length)
+ {
+ if(strncmp(address + i, testpattern, pattern_length) !=
0)
+ {
+ printf("Data mismatch on block %u\n", blockcount);
+ return -1;
+ }
+ }
+ printf("strcpy based Block Copy Test Passed\n");
+ return 0;
+ }
+ break;
+
+ /* bcopy/memcpy based block copy */
+ /* Note: In ppc_String.S, the strncpy code is less computation
intensive. Hence, *
+ * two different versions of the test as different timing
behavior. */
+ case 'm':
+ {
+ unsigned short pattern_length = sizeof(testpattern);
+ unsigned long blockcount = 0;
+
+ /* Write Cycle */
+ printf("\nmemcpy test starting at address %p\n\n",
address);
+ printf("write cycle with pattern size of %u\n",
pattern_length);
+ for( i = 0; i < bytecount; i += pattern_length,
blockcount+=1)
+ memcpy(address + i, testpattern, pattern_length);
+
+ /* Read Cycle */
+ printf("read cycle\n");
+ for( i = 0; (i < bytecount) && (blockcount); i +=
pattern_length)
+ {
+ if(memcmp(address + i, testpattern, pattern_length) !=
0)
+ {
+ printf("Data mismatch on block %u\n", blockcount);
+ return -1;
+ }
+ }
+ printf("memcpy based Block Copy Test Passed\n");
+ return 0;
+ }
+ }
+
+ if (i >= bytecount)
+ printf("Test Passed.\n");
+ return 0;
+}
+
+/* The inverse of pattern copy is a seperate test to keep the memory load
at a higher rate */
+int inverse_pattern_copy_test(unsigned long address, unsigned long
bytecount, unsigned char type)
+{
+ unsigned int i;
+
+ switch(type)
+ {
+ /* Byte Copy Test */
+ case 'b':
+ {
+ /* Write Cycle */
+ printf("\n%u inverse byte copy test starting at address
%p\n", sizeof(unsigned char), address);
+ printf("write cycle\n");
+ for( i = 0; i < bytecount; i += sizeof(unsigned char))
+ *((unsigned char *) (address + i) ) = (unsigned char)
~(*(testpattern + (i % sizeof(testpattern))));
+
+ printf("read cycle\n");
+ /* Read Cycle */
+ for( i = 0; i < bytecount; i += sizeof(unsigned char))
+ if(*((unsigned char *) (address + i) ) != (unsigned
char)(~(*(testpattern + (i % sizeof(testpattern))))))
+ {
+ printf("Data mismatch at address %p Value : 0x%02x
Expected : 0x%02x\n\n",
+ address + i, *((unsigned char *)(address + i)),
+ (unsigned char)~(*(testpattern + ( i %
sizeof(testpattern)))));
+ return -1;
+ }
+
+ }
+ break;
+
+ /* 16 bit Copy Test */
+ case 'h':
+ {
+ /* Write Cycle */
+ printf("\n%u inverse byte copy test starting at address
%p\n", sizeof(unsigned short), address);
+ printf("write cycle\n");
+ for( i = 0; i < bytecount ; i += sizeof(unsigned short))
+ *((unsigned short *) (address + i) ) =
+ (unsigned short)~(*(unsigned short *)(testpattern
+ (i % sizeof(testpattern))));
+
+ /* Read Cycle */
+ printf("read cycle\n");
+ for( i = 0; i < bytecount ; i += sizeof(unsigned short))
+ if(*((unsigned short *) (address + i) ) !=
+ ((unsigned short)~(*(unsigned short *)(testpattern
+ (i % sizeof(testpattern))))))
+ {
+ printf("Data mismatch at address %p Value : 0x%04x
Expected : 0x%04x\n\n",
+ (address + i), *((unsigned short *)address +
i),
+ (unsigned short)~(*(unsigned short
*)(testpattern + ( i % sizeof(testpattern)))));
+ return -1;
+ }
+ }
+ break;
+
+ /* 32 bit Copy Test */
+ case 'w':
+ {
+ /* Write Cycle */
+ printf("\n%u inverse byte copy test starting at address
%p\n\n", sizeof(unsigned int), address);
+ printf("write cycle\n");
+ for( i = 0; i < bytecount; i += sizeof(unsigned int))
+ *((unsigned int *) (address + i) ) =
+ (unsigned int)(~(*(unsigned int *)(testpattern +
(i % sizeof(testpattern)))));
+
+ /* Read Cycle */
+ printf("read cycle\n");
+ for( i = 0; i < bytecount; i += sizeof(unsigned int))
+ if(*((unsigned int *) (address + i) ) !=
+ (~(*(unsigned int *)(testpattern + (i %
sizeof(testpattern))))))
+ {
+ printf("Data mismatch at address %p Value : 0x%08x
Expected : 0x%08x\n",
+ address + i, *(unsigned int *)(address + i),
+ (unsigned int)(~(*(unsigned int
*)(testpattern + ( i % sizeof(testpattern))))));
+ return -1;
+ }
+ }
+ break;
+
+ /* 64 bit copy test */
+ case 'd':
+ {
+ /* Write Cycle */
+ printf("\n%u inverse byte copy test starting at address
%p\n\n", sizeof(unsigned long long), address);
+ printf("write cycle\n");
+ for( i = 0; i < bytecount; i += sizeof(unsigned long
long))
+ *((unsigned long long *) (address + i) ) =
+ (unsigned long long) (~(*(unsigned long long
*)(testpattern + (i % sizeof(testpattern)))));
+
+ /* Read Cycle */
+ printf("read cycle\n");
+ for( i = 0; i < bytecount; i += sizeof(unsigned long
long))
+ if(*((unsigned long long *) (address + i) ) !=
+ (unsigned long long)(~(*(unsigned long long
*)(testpattern + (i % sizeof(testpattern))))))
+ {
+ printf("Data mismatch at address %p Value :
0x%08x%08x Expected : 0x%08x%08x\n",
+ address + i, *(unsigned long *)(address + i),
+ *(unsigned long *)(address + i +
sizeof(unsigned long)),
+ (unsigned long)~(*(unsigned long *)(testpattern
+ ( i % sizeof(testpattern)))),
+ (unsigned long)~(*(unsigned long *)(testpattern
+ ( (i + sizeof(unsigned long)) % sizeof(testpattern)))));
+ return -1;
+ }
+ }
+ break;
+ }
+
+ if (i >= bytecount)
+ printf("Test Passed.\n");
+ return 0;
+}
+
+#ifdef CFG_POST_MEMORY_INTERACTIVE
+int memory_test_interactive(void)
+{
+
+ int choice, subchoice;
+ unsigned long address = 0;
+ unsigned long bytecount = 0;
+ unsigned char input[32];
+ unsigned int j = 0;
+ int i;
+
+ for(;;)
+ {
+ memset(input, 0, strlen(input));
+
+ printf("0 memory post dataline test\n");
+ printf("1 memory post addrline test\n");
+ printf("2 memory_post_test1\n");
+ printf("3 memory_post_test2\n");
+ printf("4 memory_post_test3\n");
+ printf("5 memory_post_test4\n");
+ printf("6 pattern copy test\n");
+ printf("7 inverse pattern copy test\n");
+ printf("a combined address/data line test\n");
+ printf("b Inverse combined address/data line test\n");
+ printf("c memory peek test\n");
+ printf("d memory poke test\n");
+ printf("i Infinite memory tests over entire 64MB\n");
+ printf("j Flash/Ram Block Copy Test\n");
+ printf("e exit & proceed to normal execution\n\n\n");
+
+ printf("Test to perform ? ");
+ choice = serial_getc();
+
+ if(choice == 'e')
+ break;
+
+ /* Start address to test memory. Could be on a odd/even boundary
*/
+ printf("\n\nTest Selected %c\n", choice);
+ printf("\n\nMemory Address to verify : 0x ");
+ serial_gets(input);
+ address = simple_strtoul(input, NULL, 16);
+
+ /* We do not test length size for simple address/data line test to
memory read operation */
+ if (( choice != '0' ) && (choice != '1') && (choice != 'c') &&
(choice != 'd'))
+ {
+ /* Amount of test pattern to write & verify */
+ printf("\n\nLength of test : 0x");
+ serial_gets(input);
+ bytecount = simple_strtoul(input, NULL, 16);
+ }
+
+ switch(choice)
+ {
+
+ case '0':
+ printf("\nDoing simplified Data Line test at address
%p.\n", address);
+ if(memory_post_dataline((unsigned long long *) address) !=
0)
+ printf("Test Failed\n\n");
+ else
+ printf("Test Passed\n\n");
+ break;
+
+ case '1':
+ printf("\nDoing simplified Address Line test at address
%p.\n", address);
+ if( memory_post_addrline((unsigned long *) address,
(unsigned long *) address, bytecount) != 0)
+ printf("Test Failed\n\n");
+ else
+ printf("Test Passed\n\n");
+ break;
+
+ case '2':
+ printf("\nDoing POST Test1 at address %p. Bytecount
0x%08x\n", address, bytecount);
+ if( memory_post_test1((unsigned long ) address, bytecount,
0xCC55AAFF) != 0)
+ printf("Test Failed\n\n");
+ else
+ printf("Test Passed\n\n");
+ break;
+
+ case '3':
+ printf("\nDoing POST Test2 at address %p. Bytecount
0x%08x\n", address, bytecount);
+ if( memory_post_test2((unsigned long ) address, bytecount)
!= 0)
+ printf("Test Failed\n\n");
+ else
+ printf("Test Passed\n\n");
+ break;
+
+ case '4':
+ printf("\nDoing POST Test3 at address %p. Bytecount
0x%08x\n", address, bytecount);
+ if( memory_post_test3((unsigned long ) address, bytecount)
!= 0)
+ printf("Test Failed\n\n");
+ else
+ printf("Test Passed\n\n");
+ break;
+
+ case '5':
+ printf("\nDoing POST Test4 at address %p. Bytecount
0x%08x\n", address, bytecount);
+ if( memory_post_test4((unsigned long )address, bytecount)
!= 0)
+ printf("Test Failed\n\n");
+ else
+ printf("Test Passed\n\n");
+ break;
+
+ case '6':
+ printf("Test mode [ b : byte, h : half word , w : word , d
: double word," \
+ " s : strncpy, m : memcpy ] : ");
+ subchoice = serial_getc();
+ printf("\n\n");
+ pattern_copy_test(address, bytecount, subchoice);
+ break;
+
+ case '7':
+ printf("Test mode [ b : byte, h : half word , w : word , d
: double word ] : ");
+ subchoice = serial_getc();
+ printf("\n\n");
+ inverse_pattern_copy_test(address, bytecount, subchoice);
+ break;
+
+ case 'a':
+ case 'b':
+ {
+ if(choice == 'a')
+ {
+ memory_combined_address_data_line_test(address,
(address + bytecount ));
+ }
+ else
+ {
+
memory_combined_inverse_address_data_line_test(address, (address + bytecount
));
+ }
+ }
+ break;
+
+ case 'c':
+ memory_read(address);
+ break;
+
+ case 'd':
+ memory_write(address);
+ break;
+
+ case 'i':
+ j = 0;
+ while(1)
+ {
+
+ printf("ITN:%u\n", j );
+ if(memory_post_tests(address, bytecount) != 0)
+ break;
+ //Wait for 2000 ticks. Based on Timebase register
+ wait_ticks(20000);
+ j++;
+ }
+ break;
+
+ case 'j':
+ {
+ unsigned short blockSize;
+
+ printf("\n\nBlock Size : 0x ");
+ serial_gets(input);
+ blockSize = simple_strtoul(input, NULL, 16);
+ if(blockSize > 512*1024 )
+ {
+ printf("We have a 8MB flash. So, max block size is
512KB\n");
+ }
+ flash_block_copy_test(address, bytecount, blockSize);
+ }
+ break;
+
+ default:
+ printf("Invalid Choice\n");
+ }
+ }
+ return 0;
+}
+#endif
#endif /* CONFIG_POST & CFG_POST_MEMORY */
#endif /* CONFIG_POST */
--- /login/asabharw/lxhome/u-boot-1.1.3/post/tests.c 2005-08-13
16:53:35.000000000 -0700
+++ u-boot-1.1.2/post/tests.c 2005-10-10 14:30:11.000000000 -0700
@@ -45,6 +45,7 @@
extern int sysmon_post_test (int flags);
extern int dsp_post_test (int flags);
extern int codec_post_test (int flags);
+extern int memory_test_interactive(void);
extern int sysmon_init_f (void);
@@ -58,7 +59,7 @@
"Cache test",
"cache",
"This test verifies the CPU cache operation.",
- POST_RAM | POST_ALWAYS,
+ POST_POWERON | POST_RAM | POST_ALWAYS,
&cache_post_test,
NULL,
NULL,
@@ -113,6 +114,18 @@
CFG_POST_MEMORY
},
#endif
+#if CONFIG_POST & CFG_POST_MEMORY_INTERACTIVE
+ {
+ "Memory test interactive",
+ "memory controller",
+ "This test checks external memory controller.",
+ POST_ROM | POST_POWERON | POST_ALWAYS | POST_SLOWTEST | POST_PREREL,
+ &memory_test_interactive,
+ NULL,
+ NULL,
+ CFG_POST_MEMORY_INTERACTIVE
+ },
+#endif
#if CONFIG_POST & CFG_POST_CPU
{
"CPU test",
--- /login/asabharw/lxhome/u-boot-1.1.3/include/post.h 2005-08-13
16:53:35.000000000 -0700
+++ u-boot-1.1.2/include/post.h 2005-10-06 11:58:47.000000000 -0700
@@ -77,20 +77,21 @@
#endif /* __ASSEMBLY__ */
-#define CFG_POST_RTC 0x00000001
-#define CFG_POST_WATCHDOG 0x00000002
-#define CFG_POST_MEMORY 0x00000004
-#define CFG_POST_CPU 0x00000008
-#define CFG_POST_I2C 0x00000010
-#define CFG_POST_CACHE 0x00000020
-#define CFG_POST_UART 0x00000040
-#define CFG_POST_ETHER 0x00000080
-#define CFG_POST_SPI 0x00000100
-#define CFG_POST_USB 0x00000200
-#define CFG_POST_SPR 0x00000400
-#define CFG_POST_SYSMON 0x00000800
-#define CFG_POST_DSP 0x00001000
-#define CFG_POST_CODEC 0x00002000
+#define CFG_POST_RTC 0x00000001
+#define CFG_POST_WATCHDOG 0x00000002
+#define CFG_POST_MEMORY 0x00000004
+#define CFG_POST_CPU 0x00000008
+#define CFG_POST_I2C 0x00000010
+#define CFG_POST_CACHE 0x00000020
+#define CFG_POST_UART 0x00000040
+#define CFG_POST_ETHER 0x00000080
+#define CFG_POST_SPI 0x00000100
+#define CFG_POST_USB 0x00000200
+#define CFG_POST_SPR 0x00000400
+#define CFG_POST_SYSMON 0x00000800
+#define CFG_POST_DSP 0x00001000
+#define CFG_POST_CODEC 0x00002000
+#define CFG_POST_MEMORY_INTERACTIVE 0x00004000
#endif /* CONFIG_POST */
More information about the U-Boot
mailing list