[linux-cirrus] Re: u-boot_edb93xx-20060405.patch

  • From: "Dubb, Benjamin" <Benjamin.Dubb@xxxxxxx>
  • To: <linux-cirrus@xxxxxxxxxxxxx>
  • Date: Mon, 22 May 2006 12:53:40 -0400

> I have an AT25F1024, so the problem is not with the ID but it is not
> working. I can programm ascii file without any error, but programming
> binary file does not work. I posted a message about this on the
> arm.cirrus.com forums :
> http://arm.cirrus.com/forum/viewtopic.php?t=765

I suppose it's not something as easy as u-boot.bin being over 128K. Do
you know where it fails, is it the same area all the time? Perhaps you
may want to verify that the spi interface on your board is setup the
same way as it is on the eval board.

I had a BDI probe available to me when I implemented u-boot on the eval
board. I was able to dump the MAC internal ram and see what the bootrom
was copying out of spi flash.

See the patch below that shows the changes I made to the download.c. If
you are using the same atmel flash part, the flasher.S don't need to
change.
 
> > Anyhow, either the download utility, BDI flash programmer or linux
mtd
> > device driver can be used to update SPI flash.
> >
> If the flasher.S routine worked with your board and don't with mine,
> then it will probably will be the same with your u-boot modification.

Yes, but debugging u-boot spi writes is a lot easier, since you have a
console to print debug info to.

> > In my spi_write function I poll waiting on the Write in Progress
bit.
> > When it's zero that means the data is written.
> Yes, sorry, I meant you were not waiting for the tx fifo to empty.
> for example instead of
> spi_tx_wait();
> spi_rx_clear();
> 
> you have
> udelay(1000);
> spi_rx_clear();
> 
> Since the SPI part looks quite sensitive to me, I am looking at every
> detail, trying to know why it is not working with the board I am
working
> on.

I don't remember now why I did it that way. It makes sense to do call
spi_tx_wait() to make sure the command get's written. I'll implement the
change and try it out.

 - Ben


--- download.c_old      2005-10-26 17:44:15.000000000 -0400
+++ download.c  2006-04-06 11:32:01.000000000 -0400
@@ -24,6 +24,14 @@
 #include <unistd.h>
 #endif
 
+unsigned long crc32(unsigned long crc, const unsigned char *buf,
unsigned int len);
+#define CFG_ENV_SIZE 0x400
+#define ENV_DATA_OFFSET 4
+#define ENV_BASE_ADDRESS 0x20000
+#define MAC_PREFIX "00:E0:A7"    // IPC reserved 802.3 mac address
+char tmp_buf[CFG_ENV_SIZE];
+
+
 
//**********************************************************************
******
 //
 // lSerialPort is the serial port which is being used.
@@ -586,8 +594,8 @@
 Usage(void)
 {
     fprintf(stderr, "\
-Usage: download {-b <baud>} {-h} {-n <number>} {-o <offset>} {-p
<port>}\n\
-                {-s} {-t <type>} {-v} <filename>\n\
+Usage: download {-b <baud>} {-h} {-n <SeqNum>} {-p <port>}\n\
+                {-o} {-v} <filename>\n\
 \n\
 Downloads a program image into the NOR FLASH of a Cirrus Logic EP73xx
or\n\
 EP93xx board, or into the serial EEPROM of a EP93xx board.  The Intel
B3\n\
@@ -617,22 +625,12 @@
 #endif
     fprintf(stderr, "\
 \n\
-  -s            Program the EEPROM instead of the NOR FLASH (only valid
for\n\
-                an EP93xx).\n\
-\n\
-  -t            Specifies the board type, used in conjunction with
-n\n\
-                (default is \"9312\").  Valid values are 9301, 9302,
9307,\n\
-                9312, or 9315.\n\
-\n\
   -v            Prints the version of this program.\n\
 \n\
 When -n is used to specify the board number, the board type and number
are\n\
 used together to generate the Ethernet MAC address.  This information
is\n\
-placed at offset 0x1000 in the EEPROM; the 32 bytes of file data at
that\n\
-position will be overwritten (or the data will be padded with zeros up
to\n\
-that offset).  It is valid to not specify a file when the Ethernet
MAC\n\
-address is being programmed, in which case the first 0x1000 bytes of
the\n\
-EEPROM will be filled with zeros.\n\
+placed at offset 0x20000 in the EEPROM; It is valid to not specify a
file\n\
+when the Ethernet MAC address is being programmed.\n\
 \n");
 }
 
@@ -648,10 +646,10 @@
 int
 main(int argc, char *argv[])
 {
-    long lPort = 1, lRate = 115200, lFileSize, lIdx, lLoop, lSum,
lOffset = 0;
-    long lType = 9312, lNumber;
+    long lPort = 1, lRate = 115200, lFileSize, lTotalSize, lIdx, lLoop,
lSum, lOffset = 0;
+    long lType = 9307, lNumber;
     char cChar, cFirstChar, cRateChar, cBuffer[1024], *pcString;
-    int bError = 0, bEEPROM = 0, bMAC = 0, bHaveFile = 0;
+    int bError = 0, bEEPROM = 1, bMAC = 0, bHaveFile = 0;
     FILE *pFile;
 
     //
@@ -737,12 +735,12 @@
                 //
                 // Get the board number from the command line.
                 //
-                lNumber = atoi(optarg);
+                lNumber = strtol(optarg, NULL, 16);
 
                 //
                 // Make sure that the specified board number is valid.
                 //
-                if((lNumber < 1) || (lNumber > 65535))
+                if(lNumber == 0)
                 {
                     //
                     // Tell the user that the board number is invalid.
@@ -760,6 +758,9 @@
                     return(1);
                 }
 
+                printf("Using MAC Address
"MAC_PREFIX":%02X:%02X:%02X\n", 
+                       (lNumber >> 16) & 0xff, (lNumber >> 8) & 0xff,
lNumber & 0xff);;
+
                 //
                 // Indicate that the EEPROM is to be programmed, and
that we
                 // have a MAC address.
@@ -845,6 +846,7 @@
                 break;
             }
 
+#if 0
             //
             // See if this argument is "-s".
             //
@@ -898,6 +900,7 @@
                 //
                 break;
             }
+#endif
 
             //
             // See if this argument is "-v".
@@ -965,6 +968,10 @@
         //
         return(1);
     }
+    if(!bMAC)
+    {
+        fprintf(stderr, "\nWarning: Board MAC address will not be
modified!\n\n");
+    }
 
     //
     // Open the serial port to be used.
@@ -995,7 +1002,17 @@
         //
         fseek(pFile, 0, SEEK_END);
         lFileSize = ftell(pFile);
+        if (lFileSize > ENV_BASE_ADDRESS)
+        {
+            fprintf(stderr, "File is too big for environment\n");
+            ClosePort(lPort);
+            return(1);
+        }
         fseek(pFile, 0, SEEK_SET);
+
+        lTotalSize = lFileSize;
+        if (bMAC)
+            lTotalSize = ENV_BASE_ADDRESS + CFG_ENV_SIZE; //0x20400;
     }
     else
     {
@@ -1003,14 +1020,16 @@
         // Only the MAC address is to be programmed, so set the file
size to
         // the size of the board info structure.
         //
-        lOffset = 0;
-        lFileSize = 0x1020;
+        lOffset = ENV_BASE_ADDRESS;
+        lFileSize = CFG_ENV_SIZE; //0x400;
+        lTotalSize = lFileSize;
     }
 
     //
     // Round the file size up to the next 1K boundary.
     //
     lFileSize = (lFileSize + 1023) & ~1023;
+    lTotalSize = (lTotalSize + 1023) & ~1023;
 
     //
     // Program the initial baud rate of 9600, 8 data bits, and no
parity.
@@ -1196,6 +1215,8 @@
         return(1);
     }
 
+printf("program 0x%x bytes starting from offset 0x%x\n", lTotalSize,
lOffset);
+
     //
     // Send the starting offset.
     //
@@ -1207,10 +1228,10 @@
     //
     // Send the length of the data file.
     //
-    SendChar((char)(lFileSize & 0xFF));
-    SendChar((char)((lFileSize >> 8) & 0xFF));
-    SendChar((char)((lFileSize >> 16) & 0xFF));
-    SendChar((char)((lFileSize >> 24) & 0xFF));
+    SendChar((char)(lTotalSize & 0xFF));
+    SendChar((char)((lTotalSize >> 8) & 0xFF));
+    SendChar((char)((lTotalSize >> 16) & 0xFF));
+    SendChar((char)((lTotalSize >> 24) & 0xFF));
 
     //
     // Tell the user that we are erasing the FLASH.
@@ -1268,12 +1289,12 @@
     //
     // Send the actual data in the file.
     //
-    for(lIdx = 0; lIdx < lFileSize; lIdx += 1024)
+    for(lIdx = 0; lIdx < lTotalSize; lIdx += 1024)
     {
         //
         // See if the data should come from a file.
         //
-        if(bHaveFile)
+        if((bHaveFile) && (lIdx < lFileSize))
         {
             //
             // Read the next 1K block from the file.
@@ -1293,58 +1314,55 @@
         // See if the Ethernet MAC address is to be programmed, and the
correct
         // memory location has been reached.
         //
-        if(bMAC && (lIdx == 0x1000))
+        if(bMAC && ((lOffset + lIdx) == ENV_BASE_ADDRESS))
         {
+                       char *env[] = {
+                               "ethaddr="MAC_PREFIX":00:00:00\0",
+                               "bootcmd=dhcp; echo Using MAC ${ethaddr}
IP ${ipaddr}; " \
+                "setenv bootargs root=/dev/nfs nfsroot=${rootpath}
ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off;
bootm\0",
+                               "bootdelay=0\0",
+                               "baudrate=57600\0",
+                               "dhcp_vendor-class-identifier=IPCPTU\0",
+                           NULL};
+                       char *end;
+                       int i = 0, n;
+
+                       memset(tmp_buf, 0, CFG_ENV_SIZE);
+                       end = tmp_buf;
+                       while(env[i] != NULL)
+                       {
+                               int n;
+
+                               n = strlen(env[i]);
+                               strncpy(end, env[i], n);

+                               end += n;
+                               *end++ = '\0';
+
+                               //printf("\t%s\n", env[i]);
+                               i++;
+                       }
+                       sprintf(&tmp_buf[17], "%02X:%02X:%02X", 
+                    (lNumber >> 16) & 0xff, (lNumber >> 8) & 0xff,
lNumber & 0xff);
+#if 0
+            for(i=0; i<end-tmp_buf; i++)
+            {
+                printf("%02x", tmp_buf[i]);
+                if ((i % 16) == 0)
+                    printf("\n");
+                else if ((i % 4) == 0)
+                    printf(" ");
+            }
+#endif
+
             //
-            // The first four bytes should be "EMAC", the tag to
indicate a
-            // Ethernet MAC block.
+            // The first 4 bytes are crc, followed by u-boot
environment.
             //
-            cBuffer[0] = 'E';
-            cBuffer[1] = 'M';
-            cBuffer[2] = 'A';
-            cBuffer[3] = 'C';
-
-            //
-            // The next six bytes are the Ethernet MAC address.
-            //
-            cBuffer[4] = 0x00;
-            cBuffer[5] = 0xdc;
-            cBuffer[6] = 0x6c;
-            cBuffer[7] = lType - 9300;
-            cBuffer[8] = lNumber / 256;
-            cBuffer[9] = lNumber & 255;
-
-            //
-            // The next six bytes are reserved.
-            //
-            cBuffer[10] = 0x00;
-            cBuffer[11] = 0x00;
-            cBuffer[12] = 0x00;
-            cBuffer[13] = 0x00;
-            cBuffer[14] = 0x00;
-            cBuffer[15] = 0x00;
-
-            //
-            // The next 16 bytes are the string name for this board.
-            //
-            cBuffer[16] = 'e';
-            cBuffer[17] = 'd';
-            cBuffer[18] = 'b';
-            cBuffer[19] = '0' + (lType / 1000);
-            cBuffer[20] = '0' + ((lType / 100) % 10);
-            cBuffer[21] = '0' + ((lType / 10) % 10);
-            cBuffer[22] = '0' + (lType % 10);
-            cBuffer[23] = '-';
-            cBuffer[24] = '0' + (lNumber / 10000);
-            cBuffer[25] = '0' + ((lNumber / 1000) % 10);
-            cBuffer[26] = '0' + ((lNumber / 100) % 10);
-            cBuffer[27] = '0' + ((lNumber / 10) % 10);
-            cBuffer[28] = '0' + (lNumber % 10);
-            cBuffer[29] = 0x00;
-            cBuffer[30] = 0x00;
-            cBuffer[31] = 0x00;
+            cBuffer[4] = 0x01; // flag (not used?)
+            memcpy(&cBuffer[ENV_DATA_OFFSET], tmp_buf, end-tmp_buf);
+                       *(unsigned long *)cBuffer = crc32(0, tmp_buf,
CFG_ENV_SIZE-ENV_DATA_OFFSET);
         }
 
+
         //
         // If we could not read 1K from the file, then fill the
remainder of
         // the buffer with zeros.
@@ -1446,7 +1464,7 @@
         // Print out our progress.
         //
         printf("\b\b\b\b\b%3d%%)",
-               (((lIdx + 1024) / 1024) * 100) / (lFileSize / 1024));
+               (((lIdx + 1024) / 1024) * 100) / (lTotalSize / 1024));
     }
     printf("\r                               \r");
 
@@ -1526,3 +1544,87 @@
         return(1);
     }
 }
+
+
+/* U-Boot CRC32 stuff */
+/*
========================================================================
*/
+
+/*
========================================================================
+ * Table of CRC-32's of all single-byte values (made by make_crc_table)
+ */
+const unsigned long crc_table[256] = {
+               0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
0x076dc419L,
+               0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L,
0x79dcb8a4L,
+               0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL,
0xe7b82d07L,
+               0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L,
0x84be41deL,
+               0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
0x136c9856L,
+               0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL,
0x63066cd9L,
+               0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL,
0xd56041e4L,
+               0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL,
0xa50ab56bL,
+               0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
0x32d86ce3L,
+               0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL,
0x51de003aL,
+               0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L,
0xcfba9599L,
+               0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L,
0xb10be924L,
+               0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
0x76dc4190L,
+               0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L,
0x06b6b51fL,
+               0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L,
0x9609a88eL,
+               0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L,
0xe6635c01L,
+               0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
0x6c0695edL,
+               0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L,
0x12b7e950L,
+               0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L,
0x8cd37cf3L,
+               0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L,
0xd4bb30e2L,
+               0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
0x4369e96aL,
+               0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L,
0x33031de5L,
+               0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL,
0xbe0b1010L,
+               0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L,
0xce61e49fL,
+               0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,
0x59b33d17L,
+               0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L,
0x9abfb3b6L,
+               0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL,
0x04db2615L,
+               0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL,
0x7a6a5aa8L,
+               0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
0xf00f9344L,
+               0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL,
0x806567cbL,
+               0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L,
0x10da7a5aL,
+               0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L,
0x60b08ed5L,
+               0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,
0xd1bb67f1L,
+               0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL,
0xaf0a1b4cL,
+               0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L,
0x316e8eefL,
+               0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L,
0x5268e236L,
+               0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
0xc5ba3bbeL,
+               0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L,
0xb5d0cf31L,
+               0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L,
0x756aa39cL,
+               0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L,
0x05005713L,
+               0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
0x92d28e9bL,
+               0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L,
0xf1d4e242L,
+               0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL,
0x6fb077e1L,
+               0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL,
0x11010b5cL,
+               0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
0xa00ae278L,
+               0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L,
0xd06016f7L,
+               0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL,
0x40df0b66L,
+               0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL,
0x30b5ffe9L,
+               0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L,
0xbad03605L,
+               0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL,
0xc4614ab8L,
+               0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L,
0x5a05df1bL,
+               0x2d02ef8dL
+};
+
+
+/*
========================================================================
= */
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc
>> 8);
+#define DO2(buf)  DO1(buf); DO1(buf);
+#define DO4(buf)  DO2(buf); DO2(buf);
+#define DO8(buf)  DO4(buf); DO4(buf);
+
+/*
========================================================================
= */
+unsigned long crc32(unsigned long crc, const unsigned char *buf,
unsigned int len)
+{
+    crc = crc ^ 0xffffffffL;
+    while (len >= 8)
+    {
+      DO8(buf);
+      len -= 8;
+    }
+    if (len) do {
+      DO1(buf);
+    } while (--len);
+    return crc ^ 0xffffffffL;
+}


DISCLAIMER:
Important Notice *************************************************
This e-mail may contain information that is confidential, privileged or 
otherwise protected from disclosure. If you are not an intended recipient of 
this e-mail, do not duplicate or redistribute it by any means. Please delete it 
and any attachments and notify the sender that you have received it in error. 
Unintended recipients are prohibited from taking action on the basis of 
information in this e-mail.E-mail messages may contain computer viruses or 
other defects, may not be accurately replicated on other systems, or may be 
intercepted, deleted or interfered with without the knowledge of the sender or 
the intended recipient. If you are not comfortable with the risks associated 
with e-mail messages, you may decide not to use e-mail to communicate with IPC. 
IPC reserves the right, to the extent and under circumstances permitted by 
applicable law, to retain, monitor and intercept e-mail messages to and from 
its systems.

Other related posts: