[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