Added RBL EMAC boot example
authorHao Zhang <hzhang@ti.com>
Thu, 5 May 2011 16:25:33 +0000 (12:25 -0400)
committerHao Zhang <hzhang@ti.com>
Thu, 5 May 2011 16:25:33 +0000 (12:25 -0400)
30 files changed:
boot_loader/boot_loader.zip [new file with mode: 0644]
boot_loader/examples/emac/Ethernet_boot/README [new file with mode: 0644]
boot_loader/examples/emac/Ethernet_boot/pcsendpkt.c [new file with mode: 0644]
boot_loader/examples/emac/Ethernet_boot/pcsendpkt.exe [new file with mode: 0644]
boot_loader/examples/emac/Ethernet_boot/simple.eth [new file with mode: 0644]
boot_loader/examples/emac/Utilities/b2ccs.c [new file with mode: 0644]
boot_loader/examples/emac/Utilities/b2ccs.exe [new file with mode: 0644]
boot_loader/examples/emac/Utilities/b2i2c.c [new file with mode: 0644]
boot_loader/examples/emac/Utilities/b2i2c.exe [new file with mode: 0644]
boot_loader/examples/emac/Utilities/bconvert64x.c [new file with mode: 0644]
boot_loader/examples/emac/Utilities/bconvert64x.exe [new file with mode: 0644]
boot_loader/examples/emac/Utilities/bootpacket.c [new file with mode: 0644]
boot_loader/examples/emac/Utilities/bootpacket.exe [new file with mode: 0644]
boot_loader/examples/emac/Utilities/bootpacket.h [new file with mode: 0644]
boot_loader/examples/emac/Utilities/build-msvc.bat [new file with mode: 0644]
boot_loader/examples/emac/Utilities/mergebtbl.c [new file with mode: 0644]
boot_loader/examples/emac/Utilities/mergebtbl.exe [new file with mode: 0644]
boot_loader/examples/emac/Utilities/myparser.c [new file with mode: 0644]
boot_loader/examples/emac/Utilities/myparser.exe [new file with mode: 0644]
boot_loader/examples/emac/simple/makefile [new file with mode: 0644]
boot_loader/examples/emac/simple/simple.btbl [new file with mode: 0644]
boot_loader/examples/emac/simple/simple.cmd [new file with mode: 0644]
boot_loader/examples/emac/simple/simple.le.btbl [new file with mode: 0644]
boot_loader/examples/emac/simple/simple.map [new file with mode: 0644]
boot_loader/examples/emac/simple/simple.obj [new file with mode: 0644]
boot_loader/examples/emac/simple/simple.out [new file with mode: 0644]
boot_loader/examples/emac/simple/simple.rmd [new file with mode: 0644]
boot_loader/examples/emac/simple/simple.s [new file with mode: 0644]
boot_loader/examples/i2c/emac/docs/README.txt
post/src/post.c

diff --git a/boot_loader/boot_loader.zip b/boot_loader/boot_loader.zip
new file mode 100644 (file)
index 0000000..d6f3ec1
Binary files /dev/null and b/boot_loader/boot_loader.zip differ
diff --git a/boot_loader/examples/emac/Ethernet_boot/README b/boot_loader/examples/emac/Ethernet_boot/README
new file mode 100644 (file)
index 0000000..acd5b86
--- /dev/null
@@ -0,0 +1,18 @@
+/****** Steps to send the image from the Host to the target DSP. ***********/
+
+1. Boot the target the DSP in Ethernet boot mode.
+
+2. Once the DSP boots up, it transmits BOOTP packet at regular interval which will have the MAC id of the DSP.
+
+3. Create a image of the simple code in the simple folder using the "make simple.eth".
+
+4. The resulting simple.eth file is the desired image.
+
+5. Add an ARP entry for the DSP mac address associating with an IP local to the host. For example if the host PC's 
+IP is 192.168.1.1, then add an ARP entry with the DSP's MAC address associated with IP address 192.168.1.2.
+
+5. Use the pcsendpkt.exe to send the image to the DSP using the associated IP address. For example 
+pcsendpkt.exe simple.eth 192.168.1.2  
+
+6. In order to compile the pcsendpkt.c file please compile with -lwsock32 option for using windows socket.
+
diff --git a/boot_loader/examples/emac/Ethernet_boot/pcsendpkt.c b/boot_loader/examples/emac/Ethernet_boot/pcsendpkt.c
new file mode 100644 (file)
index 0000000..587ca2f
--- /dev/null
@@ -0,0 +1,177 @@
+#include <windows.h>
+#include <stdio.h>
+#include <time.h>
+#include <winsock.h>
+
+#define UDP_LOW   42
+#define UDP_HIGH  1504  // Note: Windows FRAGMENTS higher UDP sizes
+
+#define SRCPORT   1234
+#define DSTPORT   9
+
+#define DELAY 60000
+
+/* convert ascii to decimal number */
+int toNum(unsigned char c)
+{
+  if ((c >= '0') && (c <= '9'))
+     return(c - '0');
+
+  else  if ((c >= 'A') && (c <= 'F'))
+         return(c -'A' + 10);
+
+  else  if ((c >= 'a') && (c <= 'f'))
+         return(c - 'a' + 10);
+
+  return(-1);
+}
+
+
+int main( int argc, char *argv[] )
+{
+    WORD                wVersionRequested;
+    WSADATA             wsaData;
+    SOCKET              s;
+    struct sockaddr_in  sin;
+    unsigned char       *pBuf = 0;
+    int                 tmp1,tmp2,tmp3,tmp4;
+    time_t              ts,tn;
+       FILE *strin;
+       char iline[132];
+       int i,j,length;
+       int packetno;
+
+    if( (argc != 3) ||
+        sscanf(argv[2],"%03d.%03d.%03d.%03d",&tmp1,&tmp2,&tmp3,&tmp4)!=4 ||
+        (tmp1 < 0 || tmp1 > 255 || tmp2 < 0 || tmp2 > 255 ||
+         tmp3 < 0 || tmp3 > 255 || tmp4 < 0 || tmp4 > 255) )
+    {
+        printf("\nUsage: %s packetfile ipaddress\n",argv[0]);
+        exit(-1);
+    }
+
+    tmp1 |= tmp2 << 8;
+    tmp1 |= tmp3 << 16;
+    tmp1 |= tmp4 << 24;
+
+    strin = fopen (argv[1], "r");
+    if (strin == NULL)  {
+        printf ("could not open input file %s\n", argv[1]);
+        exit(-1);
+       }
+
+    /* Skip the first two lines */
+    fgets (iline, 131, strin);
+       fgets (iline, 131, strin);
+
+    wVersionRequested = MAKEWORD(1, 1);
+    tmp2 = WSAStartup(wVersionRequested, &wsaData);
+    if (tmp2 != 0)
+    {
+        printf("\r\nUnable to initialize WinSock for host info");
+        exit(0);
+    }
+
+    s = socket( AF_INET, SOCK_DGRAM, 0 );
+    if( s < 0 )
+    {
+        printf("failed connect (%d)\n",WSAGetLastError());
+        goto end;
+    }
+
+    sin.sin_family      = AF_INET;
+    sin.sin_addr.s_addr = 0;
+    sin.sin_port        = htons(SRCPORT);
+
+    if ( bind( s, (struct sockaddr *)&sin, sizeof(sin) ) < 0 )
+    {
+        printf("failed bind (%d)\n",WSAGetLastError());
+        goto end;
+    }
+
+    /* Allocate a working buffer */
+    if( !(pBuf = malloc( 2000 )) )
+    {
+        printf("failed packetno buffer allocation\n");
+        goto end;
+    }
+
+    sin.sin_addr.s_addr = tmp1;
+    sin.sin_port        = htons(DSTPORT);
+
+    ts = time(0);
+
+    packetno = 0;
+
+    printf("\nSending packets to %d.%d.%d.%d\n",
+                tmp1&255, (tmp1>>8)&255, (tmp1>>16)&255, (tmp1>>24)&255 );
+
+    while(1)
+    {
+               /* get length in bytes */
+               if(fgets(iline, 131, strin)==NULL) break;
+           length = toNum(iline[2])<<12 | toNum(iline[3])<<8 | toNum(iline[4])<<4 | toNum(iline[5]);
+               if(length == 0) break; 
+               else if(length < UDP_LOW || length > UDP_HIGH) {
+                       printf("Invalid length = %d\n",length);
+                       goto end;
+               }
+
+               /* skip the next 21 lines, 14 mac + 20 IP + 8 UDP = 42 bytes = 21 lines */
+               for(i=0; i<21; i++) {
+                       if(fgets(iline,131,strin)==NULL) break;
+               }
+
+               length -= 42;
+               if(length < 0) {
+                       printf("Invalid length = %d\n",length);
+                       goto end;
+               }
+
+               /* copy the payload: magicno + seq no + boot table */
+               for(i=0,j=0; i< length/2; i++) {
+                       if(fgets(iline, 131, strin)==NULL) break;
+
+                       *(pBuf+j) = toNum(iline[2])<<4 | toNum(iline[3]);
+                       j++;
+                       *(pBuf+j) = toNum(iline[4])<<4 | toNum(iline[5]);
+                       j++;
+               }
+
+               /* send out the packet */
+        if( sendto( s, pBuf, length, 0, (struct sockaddr *)&sin, sizeof(sin) ) < 0 )
+        {
+            printf("send failed (%d)\n",WSAGetLastError());
+            break;
+        }
+
+               /* packet number */
+        packetno++;
+               printf("Packet %d sent\n",packetno);
+               
+               /* add delay between packets */
+               for(i=0; i<DELAY; i++) {
+                       tmp4 = tmp3;
+                       tmp3 = tmp4;
+               }
+
+               /* skip the next two lines */
+           if(fgets (iline, 131, strin)==NULL) break;
+               if(fgets (iline, 131, strin)==NULL) break;
+    }
+
+    tn = time(0) - ts;
+    printf("Exiting . Time = %d seconds, Total Packets = %d",tn,packetno);
+
+       /* clean up */
+end:
+       fclose(strin);
+
+    if( pBuf )
+        free( pBuf );
+    if( s >= 0 )
+        closesocket( s );
+
+    WSACleanup();
+}
+
diff --git a/boot_loader/examples/emac/Ethernet_boot/pcsendpkt.exe b/boot_loader/examples/emac/Ethernet_boot/pcsendpkt.exe
new file mode 100644 (file)
index 0000000..4e7173d
Binary files /dev/null and b/boot_loader/examples/emac/Ethernet_boot/pcsendpkt.exe differ
diff --git a/boot_loader/examples/emac/Ethernet_boot/simple.eth b/boot_loader/examples/emac/Ethernet_boot/simple.eth
new file mode 100644 (file)
index 0000000..fcbbb2c
--- /dev/null
@@ -0,0 +1,87 @@
+1651 1 890000 1 56
+0x0000
+0x00A2
+0x0008
+0x7433
+0x2630
+0x000D
+0x5676
+0x2F1A
+0x0800
+0x4500
+0x0094
+0x4567
+0x0000
+0x1011
+0x58CC
+0x9EDA
+0x674E
+0x9EDA
+0x6723
+0x0000
+0x0009
+0x0080
+0x0ED8
+0x544B
+0x0100
+0x0081
+0x0000
+0x0000
+0x0040
+0x0081
+0x0000
+0x0099
+0xA228
+0x0088
+0x9168
+0x0101
+0x00A8
+0x0100
+0x40E8
+0x0108
+0x0226
+0x0181
+0x0828
+0x0180
+0x40E8
+0x018C
+0x3626
+0x020C
+0x0226
+0x0001
+0xA120
+0x0000
+0x0000
+0x0000
+0x0000
+0x0000
+0x0000
+0x0000
+0x0000
+0x0000
+0x0000
+0x0000
+0x0000
+0x0000
+0x0004
+0x0081
+0x0100
+0x1234
+0xABCD
+0x0000
+0x0001
+0x0081
+0x0201
+0x1200
+0x0000
+0x0000
+0x0002
+0x0081
+0x0210
+0x1234
+0x0000
+0x0000
+0x0000
+0xEA00
+0x0000
+0x0000
diff --git a/boot_loader/examples/emac/Utilities/b2ccs.c b/boot_loader/examples/emac/Utilities/b2ccs.c
new file mode 100644 (file)
index 0000000..61018be
--- /dev/null
@@ -0,0 +1,164 @@
+/* Convert a hex b file into a ccs data file */
+
+#include <stdio.h>
+#include <malloc.h>
+
+
+int asciiByte (unsigned char c)
+{
+  if ((c >= '0') && (c <= '9'))
+    return (1);
+
+  if ((c >= 'A') && (c <= 'F'))
+    return (1);
+
+  return (0);
+}
+
+int toNum (unsigned char c)
+{
+  if ((c >= '0') && (c <= '9'))
+    return (c - '0');
+
+  return (c - 'A' + 10);
+
+}
+
+
+void  stripLine (FILE *s)
+{
+  char iline[132];
+
+  fgets (iline, 131, s);
+
+}
+
+/* Read a .b file. */
+unsigned long readBFile (FILE *s, unsigned char *data, unsigned long maxSize)
+{
+  unsigned char x, y;
+  unsigned long byteCount = 0;
+
+  /* Strip the 1st two lines */
+  stripLine (s);
+  stripLine (s);
+
+  for (;;) {
+
+    /* read the 1st ascii char */
+    do  {
+      x = fgetc (s);
+      if (x == (unsigned char)EOF)
+        return (byteCount);
+
+    } while (!asciiByte(x));
+
+    /* Read the next ascii char */
+    y = fgetc (s);
+    if (y == (unsigned char)EOF)
+      return (byteCount);
+    if (asciiByte(y))
+      data[byteCount++] = (toNum(x) << 4) | toNum (y);
+
+    if (byteCount >= maxSize)  {
+      fprintf (stderr, "Max input array size exceeded\n");
+      return (-1);
+    }
+  }
+}
+
+
+unsigned dwordConvert (unsigned char *data, unsigned long idx, unsigned long iMax)
+{
+  unsigned value;
+  unsigned char c[4];
+  int i;
+
+  c[0] = c[1] = c[2] = c[3] = 0;
+
+  for (i = 0; i < 4; i++)  {
+    if (idx >= iMax)
+      break;
+    c[i] = data[idx++];
+  }
+
+  value = c[3] | (c[2] << 8) | (c[1] << 16) | (c[0] << 24);
+
+  return (value);
+
+}
+
+
+
+#define SIZE    (1024 * 1024 * 2)   /* max array size 2MB */
+
+int main (int argc, char *argv[])
+{
+  FILE *strin;
+  FILE *strout;
+
+  unsigned char *dataSet1;
+
+  unsigned char block[128];
+  unsigned blockSize;
+
+  unsigned long pIn;
+  unsigned long pOut;
+
+  unsigned long inSize;
+  unsigned long i;
+
+  /* Arg check */
+  if (argc != 3)  {
+    fprintf (stderr, "usage: %s infile outfile\n", argv[0]);
+    return (-1);
+  }
+
+  /* Open the input file */
+  strin = fopen (argv[1], "r");
+  if (strin == NULL)  {
+    fprintf (stderr, "%s: Could not open file %s for reading\n", argv[0], argv[1]);
+    return (-1);
+  }
+
+  /* Allocate the two data set memories */
+  dataSet1 = malloc (SIZE * sizeof (unsigned char));
+  if (dataSet1 == NULL)  {
+    fprintf (stderr, "%s: Malloc failure\n", argv[0]);
+    return (-1);
+  }
+
+  /* Read the data into the byte stream */
+  if ((inSize = readBFile (strin, dataSet1, SIZE)) < 0)
+    return (inSize);
+  fclose (strin);
+
+  strout = fopen (argv[2], "w");
+  if (strout == NULL)  {
+    fprintf (stderr, "%s error: Could not open output file %s\n", argv[0], argv[2]);
+    free (dataSet1);
+    return (-1);
+  }
+
+  /* Write the CCS header */
+  fprintf (strout, "1651 1 10000 1 %x\n", (inSize + 3) / 4);
+
+  /* Write out each 32 bit line. */
+  for (i = 0; i < inSize; i += 4)
+    fprintf (strout, "0x%08x\n", dwordConvert (dataSet1, i, inSize));
+
+  free (dataSet1);
+  fclose (strout);
+
+
+  return (0);
+
+}
+
+
+
+
+
+
+
+
diff --git a/boot_loader/examples/emac/Utilities/b2ccs.exe b/boot_loader/examples/emac/Utilities/b2ccs.exe
new file mode 100644 (file)
index 0000000..b11083e
Binary files /dev/null and b/boot_loader/examples/emac/Utilities/b2ccs.exe differ
diff --git a/boot_loader/examples/emac/Utilities/b2i2c.c b/boot_loader/examples/emac/Utilities/b2i2c.c
new file mode 100644 (file)
index 0000000..54e2a95
--- /dev/null
@@ -0,0 +1,226 @@
+/* Create an ascii hex i2c data file */
+
+#include <stdio.h>
+#include <malloc.h>
+
+unsigned onesComplementAdd (unsigned value1, unsigned value2)
+{
+  unsigned result;
+
+  result = (unsigned)value1 + (unsigned)value2;
+
+  result = (result >> 16) + (result & 0xFFFF); /* add in carry   */
+  result += (result >> 16);                    /* maybe one more */
+  result = (result & 0xffff);
+  return (unsigned)result;
+
+} /* end of beth_ones_complement_add() */
+
+
+int asciiByte (unsigned char c)
+{
+  if ((c >= '0') && (c <= '9'))
+    return (1);
+
+  if ((c >= 'A') && (c <= 'F'))
+    return (1);
+
+  return (0);
+}
+
+int toNum (unsigned char c)
+{
+  if ((c >= '0') && (c <= '9'))
+    return (c - '0');
+
+  return (c - 'A' + 10);
+
+}
+
+
+void  stripLine (FILE *s)
+{
+  char iline[132];
+
+  fgets (iline, 131, s);
+
+}
+
+/* Read a .b file. */
+unsigned long readBFile (FILE *s, unsigned char *data, unsigned long maxSize)
+{
+  unsigned char x, y;
+  unsigned long byteCount = 0;
+
+  /* Strip the 1st two lines */
+  stripLine (s);
+  stripLine (s);
+
+  for (;;) {
+
+    /* read the 1st ascii char */
+    do  {
+      x = fgetc (s);
+      if (x == (unsigned char)EOF)
+        return (byteCount);
+
+    } while (!asciiByte(x));
+
+    /* Read the next ascii char */
+    y = fgetc (s);
+    if (y == (unsigned char)EOF)
+      return (byteCount);
+    if (asciiByte(y))
+      data[byteCount++] = (toNum(x) << 4) | toNum (y);
+
+    if (byteCount >= maxSize)  {
+      fprintf (stderr, "Max input array size exceeded\n");
+      return (-1);
+    }
+  }
+}
+
+
+int copyBlock (unsigned char *source, unsigned long idx, unsigned long maxSize,
+               unsigned char *dest, unsigned long count)
+{
+  unsigned long i;
+
+  for (i = 0; i < count; i++)  {
+    if (idx >= maxSize)
+      break;
+
+    dest[i] = source[idx++];
+  }
+
+  return (i);
+
+}
+
+void blockCheckSum (unsigned char *block, unsigned long blockSize)
+{
+  unsigned checksum = 0;
+  unsigned value;
+  unsigned long i;
+
+  if (blockSize & 0x0001)  {
+    fprintf (stderr, "program requires an even blocksize\n");
+    exit (-1);
+  }
+
+  for (i = 0; i < blockSize; i += 2) {
+    value = (block[i] << 8) | block[i+1];
+    checksum = onesComplementAdd (checksum, value);
+  }
+
+  /* Put the checksum into the block starting at byte 2. Use big endian */
+  checksum = ~checksum;
+  block[3] = checksum & 0xff;
+  block[2] = (checksum >> 8) & 0xff;
+
+}
+
+#define SIZE    (1024 * 1024 * 2)   /* max array size 2MB */
+
+int main (int argc, char *argv[])
+{
+  FILE *strin;
+  FILE *strout;
+
+  unsigned char *dataSet1;
+  unsigned char *dataSet2;
+
+  unsigned char block[128];
+  unsigned blockSize;
+
+  unsigned long pIn;
+  unsigned long pOut;
+
+  unsigned long inSize;
+  unsigned long i;
+
+  /* Arg check */
+  if (argc != 3)  {
+    fprintf (stderr, "usage: %s infile outfile\n", argv[0]);
+    return (-1);
+  }
+
+  /* Open the input file */
+  strin = fopen (argv[1], "r");
+  if (strin == NULL)  {
+    fprintf (stderr, "%s: Could not open file %s for reading\n", argv[0], argv[1]);
+    return (-1);
+  }
+
+  /* Allocate the two data set memories */
+  dataSet1 = malloc (SIZE * sizeof (unsigned char));
+  dataSet2 = malloc (SIZE * sizeof (unsigned char));
+  if ((dataSet1 == NULL) || (dataSet2 == NULL))  {
+    fprintf (stderr, "%s: Malloc failure\n", argv[0]);
+    return (-1);
+  }
+
+  /* Read the data into the byte stream */
+  if ((inSize = readBFile (strin, dataSet1, SIZE)) < 0)
+    return (inSize);
+  fclose (strin);
+
+  /* Perform the i2c block formatting. The block size will be fixed at 128 bytes,
+   * 2 bytes of length, 2 bytes checksum, 124 bytes of data. */
+  pIn = 0;
+  pOut = 0;
+
+  do  {
+
+    /* Copy the block, leave 4 bytes at the top */
+    blockSize = copyBlock (dataSet1, pIn, inSize, &block[4], 124);
+    pIn += blockSize; /* advance to next data in source */
+
+    if (blockSize)  {
+      blockSize += 4;   /* Add room for the header - big endian */
+      block[1] = blockSize & 0xff;
+      block[0] = (blockSize >> 8) & 0xff;
+      block[2] = block[3] = 0;
+
+      /* Checksum the block */
+      blockCheckSum (block, blockSize);
+
+      /* Copy the results to the destination block */
+      if ((pOut + blockSize) >= SIZE)  {
+        fprintf (stderr, "%s: destination array size exceeded\n", argv[0]);
+        return (-1);
+      }
+      for (i = 0; i < blockSize; i++)
+        dataSet2[pOut++] = block[i];
+    }
+
+  } while (blockSize == 128);
+
+
+  /* Copy the resulting data set into the output file in ccs format */
+  strout = fopen (argv[2], "w");
+  if (strout == NULL)  {
+    fprintf (stderr, "%s: Could not open %s for writing\n", argv[0], argv[2]);
+    return (-1);
+  }
+
+
+  /* Write the two line header */
+  fprintf (strout, "%c\n$A000000\n", (unsigned char)2);
+
+  /* Write out the data */
+  for (i = 0; i < pOut; i++)  {
+    if ( ((i+1)%24) )
+      fprintf (strout, "%02X ", dataSet2[i]);
+    else
+      fprintf (strout, "%02X\n", dataSet2[i]);
+  }
+
+  /* Write the close character */
+  fprintf (strout, "\n%c", (unsigned char)3);
+
+  fclose (strout);
+
+  return (0);
+
+}
diff --git a/boot_loader/examples/emac/Utilities/b2i2c.exe b/boot_loader/examples/emac/Utilities/b2i2c.exe
new file mode 100644 (file)
index 0000000..a1d1822
Binary files /dev/null and b/boot_loader/examples/emac/Utilities/b2i2c.exe differ
diff --git a/boot_loader/examples/emac/Utilities/bconvert64x.c b/boot_loader/examples/emac/Utilities/bconvert64x.c
new file mode 100644 (file)
index 0000000..98b0dfd
--- /dev/null
@@ -0,0 +1,668 @@
+/************************************************************************************
+ * FILE PURPOSE: Convert a hex6x boot table file into the format required
+ *               by the c6x chip boot loader. 
+ ************************************************************************************
+ * FILE NAME: bconvert.c
+ *
+ * DESCRIPTION: Converts a boot table. The boot table format is:
+ *
+ *    /--------------------------------------------------------\
+ *    |              32 bit entry point address                |
+ *    +--------------------------------------------------------+
+ *    |              32 bit section byte count                 | \
+ *    +--------------------------------------------------------+  \
+ *    |         32 bit section byte start address              |   \
+ *    +-------------+-------------+-------------+--------------+    repeat each section
+ *    |  Data byte  |  Data byte  |  Data byte  |  Data byte   |   /
+ *    +-------------+-------------+-------------+--------------+  /
+ *    |  Data byte  |  Data byte  |  Data byte  |  Data byte   | /
+ *    +-------------+-------------+-------------+--------------+ 
+ *    |        32 bit zero byte count (end of boot table)      | 
+ *    \--------------------------------------------------------/
+ *
+ *
+ *  The C6x boot loader expects all 32 bit values to be in big endian
+ *  (most significant byte arrives first). Data bytes are also arranged to be 32 bit
+ *  big endian represented.
+ *
+ *  This program handles conversion of data values that are in sections that are
+ *  not multiples of 4 bytes. For example, a program compiled in big endian format
+ *  with a 1 byte section will have the following table entry (address 0x22222222), value
+ *  0x33
+ *
+ *  00 00 00 01   22 22 22 22   33 00 00 00
+ *
+ *  The same file compiled with little endian mode will have the entry
+ *
+ *  00 00 00 01   22 22 22 22   00 00 00 33
+ *
+ *
+ *  Since the boot loader has no idea what endianness the code was compiled for, this
+ *  program performs an endian conversion on any section that does not have a length
+ *  that is a multiple of 4 bytes, if the little endian option is specified. Nothing
+ *  is changed for the big endian mode.
+ *
+ *  Invokation:
+ *
+ *  bconvert -be|-le [input_file] [output_file]
+ *
+ ***************************************************************************************/
+
+#include "stdio.h"
+#include "malloc.h"
+#include "string.h"
+
+/* Global variable storing the invokation name */
+char *invok;
+
+/* Error values */
+enum {
+  ERR_PARSE_TOO_MANY_ARGS = 1000,
+  ERR_PARSE_NO_ENDIAN,
+  ERR_PARSE_INPUT_OPEN_FAIL,
+  ERR_PARSE_OUTPUT_OPEN_FAIL,
+  ERR_READ_BFILE_INITIAL_MALLOC_FAIL,
+  ERR_READ_BFILE_REALLOC_FAIL,
+  ERR_VALUE32_SIZE_ERR,
+  ERR_VALUE16_SIZE_ERR,
+  ERR_DATA32_SIZE_ERR,
+  ERR_REG32_PARSE_ERROR,
+  ERR_DATA32_REMAIN_ERR 
+};
+
+enum {
+  LITTLE,
+  BIG
+};
+
+/************************************************************************************
+ * FUNTION PURPOSE: Send an error string
+ ************************************************************************************
+ * DESCRIPTION: Prints an error to stderr
+ ************************************************************************************/
+void showErr (int errflag)
+{
+  char *s;
+
+  switch (errflag)  {
+    case ERR_PARSE_TOO_MANY_ARGS:
+       s = "Parse error: too many args specified";
+       break;
+
+    case ERR_PARSE_NO_ENDIAN:
+       s = "Parse error: no endian mode specified";
+       break;
+
+    case ERR_PARSE_INPUT_OPEN_FAIL:
+       s = "File error: failed to open specified input file";
+       break;
+
+    case ERR_PARSE_OUTPUT_OPEN_FAIL:
+       s = "File error: Failed to open specified output file";
+       break;
+
+    case ERR_READ_BFILE_INITIAL_MALLOC_FAIL:
+       s = "Memory error: Initial malloc call failed";
+       break;
+
+    case ERR_READ_BFILE_REALLOC_FAIL:
+       s = "Memory error: Subsequent realloc call failed";
+       break;
+
+    case ERR_VALUE32_SIZE_ERR:
+       s = "Data format error: End of data on 32 bit value read";
+       break;
+
+    case ERR_VALUE16_SIZE_ERR:
+       s = "Data format error: End of data on 16 bit value read";
+       break;
+
+    case ERR_REG32_PARSE_ERROR:
+       s = "Parse error: error parsing after reg32 arg";
+       break;
+
+    case ERR_DATA32_REMAIN_ERR:
+       s = "Parse error: A remainder size greater then four was found";
+       break;
+
+    default:
+       s = "Unspecified error";
+       break;
+
+  }
+
+  fprintf (stderr, "%s: %s\n", invok, s);
+
+} /* showErr */
+
+
+/*************************************************************************************
+ * FUNCTION PURPOSE: Check if a string is prefixed with "0x".
+ *************************************************************************************
+ * DESCRIPTION: Returns non-zero if the string begins with "0x"
+ *************************************************************************************/
+int isChex (char *s)
+{
+  if ((s[0] == '0') && (s[1] == 'x'))
+    return (1);
+
+  return (0);
+
+} /* isChex */
+
+
+
+/*************************************************************************************
+ * FUNCTION PURPOSE: Parse the input parameters
+ *************************************************************************************
+ * DESCRIPTION: Checks for required args, opens source and destination streams.
+ *************************************************************************************/
+int parseit (int argc, char *argv[], FILE **fin, FILE **fout, int *endian)
+{
+  int inspec  = 0;
+  int outspec = 0;
+  int espec   = 0;
+  int c       = 1;
+
+  char *iname;
+  char *oname;
+
+  *endian = -1;
+
+  /* Store the invokation name */
+  invok = argv[0];
+
+  while (c < argc)  {
+
+    /* -be | -le */
+    if (!espec)  {
+      if (!strcmp (argv[c], "-be"))  {
+        *endian = BIG;
+        espec = 1;
+        c += 1;
+        continue;
+      } else if (!strcmp (argv[c], "-le"))  {
+        *endian = LITTLE;
+        espec = 1;
+        c += 1;
+        continue;
+      }
+    }
+
+
+    /* input file */
+    if (!inspec)  {
+      inspec = 1;
+      iname = argv[c];
+      c += 1;
+      continue;
+    }
+
+    /* output file */
+    if (!outspec)  {
+      outspec = 1;
+      oname = argv[c];
+      c += 1;
+      continue;
+    }
+
+    /* Don't know what to do with the arg */
+    return (ERR_PARSE_TOO_MANY_ARGS);
+
+  }
+
+
+  /* Make sure endian is known */
+  if (!espec) 
+    return (ERR_PARSE_NO_ENDIAN);
+
+  /* Open input file if not stdin */
+  if (inspec)  {
+    *fin = fopen (iname, "r");
+    if (*fin == NULL)
+      return (ERR_PARSE_INPUT_OPEN_FAIL);
+  }
+
+  /* Open output file if not stdin */
+  if (outspec)  {
+    *fout = fopen (oname, "w");
+    if (*fout == NULL)
+      return (ERR_PARSE_OUTPUT_OPEN_FAIL);
+  }
+  return (0);
+
+} /* parseit */
+
+
+
+/***************************************************************************************
+ * FUNCTION PURPOSE: Check if data is ascii
+ ***************************************************************************************
+ * DESCRIPTION: Returns 1 if a byte is 0-9, a-f, 0 otherwise
+ ***************************************************************************************/
+int asciiByte (unsigned char c)
+{
+  if ((c >= '0') && (c <= '9'))
+    return (1);
+
+  if ((c >= 'A') && (c <= 'F'))
+    return (1);
+
+  return (0);
+} /* asciiByte */
+
+/**************************************************************************************
+ * FUNCTION PURPOSE: Returns the binary equivalent of an ascii byte
+ **************************************************************************************
+ * DESCRIPTION: Conversion from ascii to binary
+ **************************************************************************************/
+int toNum (unsigned char c)
+{
+  if ((c >= '0') && (c <= '9'))
+    return (c - '0');
+
+  return (c - 'A' + 10);
+
+} /* toNum */
+
+
+/**********************************************************************************
+ * FUNCTION PURPOSE: Read a line from a file, toss it
+ **********************************************************************************
+ * DESCRIPTION: Reads a line, including the newline character, and throws it away.
+ **********************************************************************************/
+void  stripLine (FILE *s)
+{
+  char iline[132];
+
+  fgets (iline, 131, s);
+
+} /* stripLine */
+
+/************************************************************************************
+ * FILE PURPOSE: Read the hex55 data file
+ ************************************************************************************
+ * DESCRIPTION: Reads the input data file. Strips the first two lines, reads
+ *              the byte stream.
+ ************************************************************************************/
+#define MALLOC_BLOCK_SIZE   512000
+unsigned char *readBFile (FILE *fin, unsigned *n, int *errcode)
+{
+  unsigned char *d;
+  unsigned allocSize;
+  unsigned m;
+  unsigned char x, y;
+
+  /* Create a block of data */
+  allocSize = MALLOC_BLOCK_SIZE;
+  d = malloc (allocSize * sizeof (unsigned char));
+  if (d == NULL)  {
+    *errcode = ERR_READ_BFILE_INITIAL_MALLOC_FAIL;
+    if (fin != stdin)
+      fclose (fin);
+    return (NULL);
+  }
+
+  /* Strip the 1st two lines */
+  stripLine (fin);
+  stripLine (fin);
+
+  *errcode = 0;
+  m = 0;
+
+  for (;;)  {
+
+    /* Read the 1st ascii char */
+    do  {
+      x = fgetc (fin);
+      if (x == (unsigned char)EOF)  {
+        *errcode = 0;
+        *n = m;
+        if (fin != stdin)
+          fclose (fin);
+        return (d);
+      }
+    } while (!asciiByte(x));
+
+    /* Read the next ascii char */
+    y = fgetc(fin);
+    if (y == (unsigned char)EOF)  {
+      *errcode = 0;
+      *n = m;
+      if (fin != stdin)
+        fclose (fin);
+      return (d);
+    }
+
+    /* Convert the two characters into a byte */
+    if (asciiByte(y))
+      d[m++] = (toNum(x) << 4) | toNum(y);
+
+    /* Verify memory bounds */
+    if (m >= allocSize)  {
+      allocSize += MALLOC_BLOCK_SIZE;
+      d= realloc (d, allocSize);
+      if (d== NULL)  {
+        *errcode = ERR_READ_BFILE_REALLOC_FAIL;
+        if (fin != stdin)
+          fclose (fin);
+        return (NULL);
+      }
+    }
+
+  } /* end for */
+
+} /* readBFile */
+
+/**************************************************************************************
+ * FUNCTION PURPOSE: converts four bytes into an unsigned value
+ **************************************************************************************
+ * DESCRIPTION: Converts bytes to a value
+ **************************************************************************************/
+unsigned value32bitAdd (int endian, unsigned char *data, unsigned n, unsigned *p, int *errflag, unsigned add)
+{
+  unsigned v;
+  unsigned w;
+  unsigned q;
+
+  /* Verify that there are 4 values still in the character array */
+  if ((*p + 4) > n)  {
+    *errflag = ERR_VALUE32_SIZE_ERR;
+    return (0);
+  }
+
+  /* Store the original pointer */
+  q = w = *p;
+
+  v = (unsigned)data[w+0] << 24 |
+      (unsigned)data[w+1] << 16 |
+      (unsigned)data[w+2] <<  8 |
+      (unsigned)data[w+3] <<  0 ; 
+
+  *errflag = 0;
+
+  /* Add any additional value */
+  v = v + add;
+
+  /* Write the data back in big endian format */
+  data[q+0] = (v >> 24) & 0xff;
+  data[q+1] = (v >> 16) & 0xff;
+  data[q+2] = (v >>  8) & 0xff;
+  data[q+3] = (v >>  0) & 0xff;
+
+  *p = q+4;
+  return (v);
+
+} /* value32bitAdd */
+
+/**************************************************************************************
+ * FUNCTION PURPOSE: converts four bytes into an unsigned value
+ **************************************************************************************
+ * DESCRIPTION: Converts bytes to a value, depending on the endian configuration.
+ **************************************************************************************/
+unsigned value32bit (int endian, unsigned char *data, unsigned n, unsigned *p, int *errflag)
+{
+  return (value32bitAdd (endian, data, n, p, errflag, 0));
+
+} /* value32bit */
+
+
+
+
+/*********************************************************************************
+ * FUNCTION PURPOSE: Convert up to four bytes to big endian 
+ *********************************************************************************
+ * DESCRIPTION: Data bytes are converted. 
+ *********************************************************************************/
+#define SWAP(x,y,z)  (z)=(x);(x)=(y);(y)=(z)
+void data32bit (int endian, unsigned char *data, unsigned n, unsigned *p, unsigned m, int *errflag)
+{
+
+  /* Calculate the number of bytes to convert, limited to four bytes */
+  if (m > 4)
+    m = 4;
+
+  /* return an error if there are not enough values in the array */
+  if ((*p + m) >= n)  {
+    *errflag = ERR_DATA32_SIZE_ERR;
+    return;
+  }
+
+  /* Clear the error flag */
+  *errflag = 0;
+
+
+  /* The data is always already in big endian, there is nothing to do but advance the pointer */
+  *p += m;
+
+} /* data32bit */
+
+void remain32bit (int endian, unsigned char *data, unsigned n, unsigned *p, unsigned m, int *errflag)
+{
+  unsigned w;
+  unsigned char h;
+
+  /* return an error if the size is greater then or equal to 4 */
+  if (m >= 4)  {
+    *errflag = ERR_DATA32_REMAIN_ERR;
+    return;
+  }
+
+  /* return an error if there are not enough values in the array */
+  if ((*p + m) >= n)  {
+    *errflag = ERR_DATA32_SIZE_ERR;
+    return;
+  }
+
+  w = *p;
+
+  /* Only swap if endianness is little */
+  if (endian == LITTLE)  {
+    /* Swap the next four bytes */
+    SWAP(data[w+0], data[w+3], h);
+    SWAP(data[w+1], data[w+2], h);
+  }
+
+  /* Update the full four elements */
+  *p = *p + 4;
+
+
+} /* remain32bit */
+
+
+/*********************************************************************************
+ * FUNCTION PURPOSE: Convert 2 bytes into an unsigned value
+ *********************************************************************************
+ * DESCRIPTION: Converts the next two bytes into an unsigned value based on
+ *              the endian configuration.
+ *********************************************************************************/
+unsigned value16bit (int endian, unsigned char *data, unsigned n, unsigned *p, int *errflag)
+{
+  unsigned v;
+  unsigned q;
+
+  /* Verify that there are 4 values still in the character array */
+  if ((*p + 2) > n)  {
+    *errflag = ERR_VALUE16_SIZE_ERR;
+    return (0);
+  }
+
+  /* Store the original pointer */
+  q = *p;
+
+  /* convert based on endianness. For little endain the 16 bit words are actually
+   * big endian, but the bytes in those words are not */
+  if (endian == BIG)  {
+    v = data[(*p)++] <<  8 |
+        data[(*p)++] <<  0 ;
+
+  }  else  {
+    v = data[(*p)++] <<  0 |
+        data[(*p)++] <<  8 ;
+  }
+
+  *errflag = 0;
+
+  /* Write the data back in big endian format */
+  data[q++] = (v >>  8) & 0xff;
+  data[q++] = (v >>  0) & 0xff;
+
+  return (v);
+
+} /* value16bit */
+
+/**************************************************************************************
+ * FUNCTION PURPOSE: Writes a 16 bit value into the array
+ **************************************************************************************
+ * DESCRIPTION: Writes a big endian 16 bit value, increments the array pointer.
+ **************************************************************************************/
+void write16bit (unsigned value, unsigned char *data, unsigned *p)
+{
+  data[(*p)++] = (value >> 8) & 0xff;
+  data[(*p)++] = (value >> 0) & 0xff;
+
+} /* write16bit */
+
+
+/*************************************************************************************
+ * FUNCTION PURPOSE: Write the output file
+ *************************************************************************************
+ * DESCRIPTION: Writes the resulting output.
+ *************************************************************************************/
+void writeBFile (FILE *fout, unsigned char *data, unsigned n)
+{
+  unsigned i;
+
+  /* Write the two line header */
+  fprintf (fout, "%c\n$A000000\n", (unsigned char)2);
+
+  for (i = 0; i < n; i++)  {
+    if ( ((i+1)%24)  )
+      fprintf (fout, "%02X ", data[i]);
+    else
+      fprintf (fout, "%02X\n", data[i]);
+  }
+
+  /* Write the close character */
+  fprintf (fout, "\n%c", (unsigned char)3);
+
+  if (fout != stdout)
+    fclose (fout);
+
+} /* writeBFile */
+  
+
+/**************************************************************************************
+ * FUNCTION PURPOSE: Main 
+ **************************************************************************************
+ * DESCRIPTION: Provides the top level program flow.
+ **************************************************************************************/
+int main (int argc, char *argv[])
+{
+  FILE *fin;            /* input stream  */
+  FILE *fout;           /* output stream */
+
+  unsigned char *data;  /* The data set  */
+  unsigned n;           /* Data set size */
+  unsigned p;           /* Data index    */
+  unsigned v;           /* Data value    */
+  unsigned n32;         /* Number of bytes that form complete 32 bit values */
+  unsigned r32;         /* Number of bytes remaining (0-3) */
+
+  int endian;           /* Endian          */  
+  int errflag;          /* error indicator */
+  int i, j;             /* loop var        */
+  int origRegs;         /* original reg count */
+  int shift;            /* data shift amount  */
+
+
+  /* Parse the input */
+  if (errflag = parseit (argc, argv, &fin, &fout, &endian))  {
+    showErr (errflag);
+    return (-1);
+  }
+
+  /* Read the raw data file */
+  data = readBFile (fin, &n, &errflag);
+  if (data == NULL)  {
+    showErr (errflag);
+    return(-1);
+  }
+
+  /* Parse the sections */
+  p = 0;
+
+  /* The entry point */
+  v = value32bit (endian, data, n, &p, &errflag);
+  if (errflag)  {
+    showErr (errflag);
+    return(-1);
+  }
+
+
+  /* The sections */
+  do  {
+  
+    /* Get the section byte count */   
+    v = value32bit (endian, data, n, &p, &errflag);
+    if (errflag)  {
+      showErr (errflag);
+      return(-1);
+    }
+
+    if (v)  {
+      /* Convert the start address (adjusts the array index) */
+      value32bit (endian, data, n, &p, &errflag);
+      if (errflag)  {
+        showErr (errflag);
+        return(-1);
+      }
+    }
+
+    /* Determine how many bytes form complete 32 bit fields, and how many are left over */
+    n32 = v & 0xfffffffc;
+    r32 = v & 0x00000003;
+
+    /* Convert the data to big endian format  */
+    for (i = 0; i < n32; i += 4)  {
+      data32bit (endian, data, n, &p, v-i, &errflag);
+      if (errflag)  {
+        showErr (errflag);
+        return (-1);
+      }
+    }
+
+    /* Convert any remaining bytes. */
+    if (r32)  {
+      remain32bit (endian, data, n, &p, r32, &errflag);
+      if (errflag)  {
+        showErr (errflag);
+        return (-1);
+      }
+    }
+
+  } while (v);
+
+  /*  Write out the data file */
+  writeBFile (fout, data, n);
+
+  /* Return resources */
+  free (data);
+
+  return (0); 
+
+}
+    
+
+
+
+
+
+
+
+
+
+
+
diff --git a/boot_loader/examples/emac/Utilities/bconvert64x.exe b/boot_loader/examples/emac/Utilities/bconvert64x.exe
new file mode 100644 (file)
index 0000000..f17b5f7
Binary files /dev/null and b/boot_loader/examples/emac/Utilities/bconvert64x.exe differ
diff --git a/boot_loader/examples/emac/Utilities/bootpacket.c b/boot_loader/examples/emac/Utilities/bootpacket.c
new file mode 100644 (file)
index 0000000..e11d4f5
--- /dev/null
@@ -0,0 +1,478 @@
+/* Convert a boot table to Ethernet boot format */
+/* A simple utility program written by D.Zhou */
+/* Version: 0.3 */
+/* Last modified on: June 14,2006 */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include "bootpacket.h"
+
+unsigned int line=0;
+
+
+
+void writeheader(FILE *s, INT16* pdata)
+{
+       int i;
+
+       for (i = 0; i < TOTAL_HEADER_LEN/2; i++)
+               fprintf (s, "0x%04X\n",(unsigned short int)(*pdata++));
+}
+
+
+void writeboottable(FILE *s, INT16* pdata, int size)
+{
+       int i;
+
+       for (i = 0; i < size; i++)
+               fprintf (s, "0x%04X\n",(unsigned short int)(*pdata++));
+}
+
+
+void  stripLine (FILE *s)
+{
+  char iline[132];
+
+  fgets (iline, 131, s);
+
+}
+
+
+int asciiByte (unsigned char c)
+{
+  if ((c >= '0') && (c <= '9'))
+    return (1);
+
+  if ((c >= 'A') && (c <= 'F'))
+    return (1);
+
+  return (0);
+}
+
+
+int toNum (unsigned char c)
+{
+  if ((c >= '0') && (c <= '9'))
+    return (c - '0');
+
+  return (c - 'A' + 10);
+
+}
+
+int toNumMAC (unsigned char c)
+{
+  if ((c >= '0') && (c <= '9'))
+     return(c - '0');
+
+  else  if ((c >= 'A') && (c <= 'F'))
+         return(c -'A' + 10);
+
+  else  if ((c >= 'a') && (c <= 'f'))
+         return(c - 'a' + 10);
+
+  else if(c == ':') 
+         return(100);
+
+  return(200);
+}
+
+
+
+/* Read the file size in bytes*/
+int getFileSize (FILE *s)
+{
+  unsigned char x, y;
+  unsigned int byteCount = 0;
+
+  /* Strip the 1st two lines */
+  stripLine (s);
+  stripLine (s);
+
+  for (;;) {
+
+    /* read the 1st ascii char */
+    do  {
+      x = fgetc (s);
+      if (x == (unsigned char)EOF)
+        return (byteCount);
+
+    } while (!asciiByte(x));
+
+    /* Read the next ascii char */
+    y = fgetc (s);
+    if (y == (unsigned char)EOF)
+      return (byteCount);
+    if (asciiByte(y)) 
+               byteCount++;
+  }
+}
+
+
+
+int getDataIn(FILE *s, int size_bytes, unsigned short int *output)
+{
+  int i;
+  unsigned char x, y;
+  unsigned char c[2];
+
+  for(i= 0; i< size_bytes/2; i++) {
+         c[0] = 0;
+         c[1] = 0;
+
+            /* read the 1st ascii char */
+           do  {
+                 x = fgetc (s);
+                 if (x == (unsigned char)EOF) {
+                       printf("file parsing error\n");
+                       return(-1);
+                 }
+           } while (!asciiByte(x));
+
+
+               /* Read the next ascii char */
+               y = fgetc (s);
+               if (y == (unsigned char)EOF) {
+                       printf("file parsing error\n");
+                       return(-1);
+               }
+
+        if (asciiByte(y)) {
+                       c[0] =  (toNum(x) << 4) | toNum (y);
+               }
+
+           do  {
+                 x = fgetc (s);
+                 if (x == (unsigned char)EOF) {
+                       printf("file parsing error\n");
+                       return(-1);
+                 }
+           } while (!asciiByte(x));
+
+
+               /* Read the next ascii char */
+               y = fgetc (s);
+               if (y == (unsigned char)EOF) {
+                       printf("file parsing error\n");
+                       return(-1);
+               }
+
+        if (asciiByte(y)) {
+                       c[1] =  (toNum(x) << 4) | toNum (y);
+               }
+
+               *output++ = (c[0] << 8) | c[1] ;
+               line++;
+  }
+   return(0);
+}
+
+
+
+UINT16 bootmiscOnesComplementAdd (UINT16 value1, UINT16 value2)
+{
+  UINT32 result;
+
+  result = (UINT32)value1 + (UINT32)value2;
+
+  result = (result >> 16) + (result & 0xFFFF); /* add in carry   */
+  result += (result >> 16);                    /* maybe one more */
+  return (UINT16)result;
+} 
+
+
+
+/*  Description: Calculate an Internet style one's complement checksum */
+ UINT16 bootmiscOnesComplementChksum (UINT16 base, UINT16 *p_data, UINT16 len)
+{
+  UINT16 chksum = base;
+
+  while (len > 0)
+  {
+    chksum = bootmiscOnesComplementAdd(chksum,*p_data);
+    p_data++;
+    len--;
+  }
+  return ((unsigned short) ~chksum); 
+}
+
+
+
+/* 
+  Input file format: boot table in big endian format
+
+  Output file format: 
+
+       1st line: CCS data format
+       2nd line: 0x0000
+       3rd line: length of first packet in bytes, length counts not include itself
+       .......
+       first packet 
+       .......
+
+       0xEA00
+       0x0000
+       length of the second packet in bytes, length counts not include itself
+       .......
+       second packet
+       .......
+       
+
+       0xEA00
+       0x0000
+       length of the other packet in bytes, length counts not include itself
+       .......
+       other packets
+       .......
+
+       0xEA00 
+       0X0000
+       0X0000: end of the file
+*/
+
+struct BootPacket data;
+
+
+void main (int argc, char *argv[])
+{
+       UINT32 j;
+       UINT32 inSize;
+       UINT32 counter;
+       UINT16 UDPchecksum;
+       FILE *strin, *strout;
+       UINT32 temp;
+       unsigned int MACaddr[6];
+
+        /* Arg check */
+       if (argc <3 || argc> 5)  {
+               fprintf (stderr, "usage: %s infile outfile\n\n", argv[0]);
+               fprintf (stderr, "To generates the same result as bt-pkt.exe\n");
+               fprintf (stderr, "usage: %s infile outfile btpkt\n\n", argv[0]);
+               fprintf (stderr, "To use your own MAC address\n");
+               fprintf (stderr, "usage: %s infile outfile dstMAC srcMAC\n", argv[0]);
+               return;
+       }
+
+       strin = fopen(argv[1],"rb");
+       if(strin == NULL){
+           fprintf (stderr, "%s: Could not open file %s for reading\n", argv[0], argv[1]);
+               return;
+       }
+
+       /* Get the file size of data file */
+       inSize = getFileSize (strin);
+       printf("File size = %d bytes.\n",inSize);
+       fclose (strin);
+       strin = fopen(argv[1],"rb");
+    /* Strip the 1st two lines */
+    stripLine (strin);
+    stripLine (strin);
+
+       strout = fopen(argv[2],"w");
+       if(strout == NULL) {
+           fprintf (stderr, "%s error: Could not open output file %s\n", argv[0], argv[2]);
+               return;
+       }
+
+
+       // MAC header, 14 bytes
+       if(argc == 5) {
+
+               /* get destination MAC address */
+        if((sscanf(argv[3],"%02x-%02x-%02x-%02x-%02x-%02x",&MACaddr[0],&MACaddr[1], \
+                       &MACaddr[2],&MACaddr[3],&MACaddr[4],&MACaddr[5])!=6) || \
+                       (MACaddr[0] < 0 || MACaddr[0] > 255 || \
+                       MACaddr[1] < 0 || MACaddr[1] > 255 || \
+                       MACaddr[2] < 0 || MACaddr[2] > 255 || \
+                       MACaddr[3] < 0 || MACaddr[3] > 255 || \
+                       MACaddr[4] < 0 || MACaddr[4] > 255 || \
+                       MACaddr[5] < 0 || MACaddr[5] > 255) ) {
+
+                       printf("Error in dstMAC address\n");
+                       fclose(strin);
+                       fclose(strout);
+                       return;
+               }
+
+               data.dstMAC_H = (unsigned short)(MACaddr[0]<<8 | MACaddr[1]);
+               data.dstMAC_M = (unsigned short)(MACaddr[2]<<8 | MACaddr[3]);
+               data.dstMAC_L = (unsigned short)(MACaddr[4]<<8 | MACaddr[5]);
+
+               /* get source MAC address */
+       if((sscanf(argv[4],"%02x-%02x-%02x-%02x-%02x-%02x",&MACaddr[0],&MACaddr[1], \
+                       &MACaddr[2],&MACaddr[3],&MACaddr[4],&MACaddr[5])!=6) || \
+                       (MACaddr[0] < 0 || MACaddr[0] > 255 || \
+                       MACaddr[1] < 0 || MACaddr[1] > 255 || \
+                       MACaddr[2] < 0 || MACaddr[2] > 255 || \
+                       MACaddr[3] < 0 || MACaddr[3] > 255 || \
+                       MACaddr[4] < 0 || MACaddr[4] > 255 || \
+                       MACaddr[5] < 0 || MACaddr[5] > 255) ) {
+
+                       printf("Error in srcMAC address\n");
+                       fclose(strin);
+                       fclose(strout);
+                       return;
+               }
+
+               data.srcMAC_H = (unsigned short)(MACaddr[0]<<8 | MACaddr[1]);
+               data.srcMAC_M = (unsigned short)(MACaddr[2]<<8 | MACaddr[3]);
+               data.srcMAC_L = (unsigned short)(MACaddr[4]<<8 | MACaddr[5]);
+
+       } else {  /* use default MAC address */
+               data.dstMAC_H = (unsigned short)DST_MAC_H;   
+               data.dstMAC_M = (unsigned short)DST_MAC_M;
+               data.dstMAC_L = (unsigned short)DST_MAC_L;
+               data.srcMAC_H = (unsigned short)SRC_MAC_H;
+               data.srcMAC_M = (unsigned short)SRC_MAC_M;
+               data.srcMAC_L = (unsigned short)SRC_MAC_L;
+       }
+       data.EtherType = ETHER_TYPE_IP;
+
+       // IP header, 20 bytes
+       data.VerTOS = 0x4500;
+       data.IPlength = 0x0000;
+       data.ID = 0x4567;
+       data.FlagsFrag = 0x0000;
+       data.TTLProtocol = 0x1000 | IP_TYPE_UDP;
+       data.IPchecksum = 0x0000;
+       data.srcIPAddr_H = (unsigned short)SRC_IP_ADDR_H;
+       data.srcIPAddr_L = (unsigned short)SRC_IP_ADDR_L;
+       data.dstIPAddr_H = (unsigned short)DST_IP_ADDR_H;
+       data.dstIPAddr_L = (unsigned short)DST_IP_ADDR_L;
+
+       // UDP header, 8 bytes
+       if(argc != 4) {
+               data.srcPort = (unsigned short)UDP_SRC_PORT;
+       } else {
+               data.srcPort = (unsigned short)UDP_SRC_PORT_BTPKT;
+       }
+       data.dstPort = (unsigned short)UDP_DST_PORT;
+       data.UDPlength = 0x0000;
+       data.UDPchecksum = 0x0000;
+
+       // Payload header, 4 bytes
+       data.MagicNo = MAGICNO;
+       data.SeqNo = 0x100;
+
+       memset(&data.BootTable,0, sizeof(data.BootTable));
+
+       counter = inSize / MAX_BOOTTBL_LEN;  // calculate how many packets
+
+       // If there is only one packet
+       if(counter <=1) {
+               data.UDPlength = UDP_HEADER_LEN + BOOTTBL_HEADER_LEN + inSize;
+
+               data.IPlength = data.UDPlength + IP_HEADER_LEN;
+               data.IPchecksum=bootmiscOnesComplementChksum(0,&data.VerTOS,IP_HEADER_LEN/2);
+
+               if(getDataIn(strin, inSize, data.BootTable)!=0) {
+                       fclose(strin);
+                       fclose(strout);
+                       return;
+               }
+
+               UDPchecksum = bootmiscOnesComplementAdd(IP_TYPE_UDP, data.UDPlength);
+               data.UDPchecksum=bootmiscOnesComplementChksum(UDPchecksum, &data.srcIPAddr_H,\
+                                                  (UINT16)((4+4+UDP_HEADER_LEN+BOOTTBL_HEADER_LEN+inSize)/2));
+
+               temp = BGN_BYTE_LEN+TOTAL_HEADER_LEN+inSize+END_BYTE_LEN;
+
+               if(argc != 4) {
+                       fprintf(strout,"1651 1 890000 1 %x\n",temp/2); // CCS format
+               } else {
+                       fprintf(strout,"1651 1 10000 1 %x\n",temp/2); // CCS format
+               }
+
+               fprintf (strout, "0x%04X\n",0x0000);
+               fprintf (strout, "0x%04X\n",TOTAL_HEADER_LEN+inSize); /* length in bytes */
+
+               writeheader(strout, &data.dstMAC_H);
+
+               writeboottable(strout,&data.BootTable[0],inSize/2);
+
+               fprintf (strout, "0x%04X\n",(unsigned short)(SYMBOL));
+               fprintf (strout, "0x%04X\n",0x0000);
+               fprintf (strout, "0x%04X\n",0x0000);
+
+       } else { // If there are many packets
+
+               temp = BGN_BYTE_LEN + (counter+1)*(TOTAL_HEADER_LEN + END_BYTE_LEN) + inSize;
+
+               if(argc != 4) {
+                       fprintf(strout,"1651 1 890000 1 %x\n",temp/2); // CCS format
+               } else {
+                       fprintf(strout,"1651 1 10000 1 %x\n",temp/2); // CCS format
+               }
+
+               fprintf (strout, "0x%04X\n",0x0000);
+               fprintf (strout, "0x%04X\n",TOTAL_HEADER_LEN+MAX_BOOTTBL_LEN); /* length in bytes */
+       
+               data.UDPlength = UDP_HEADER_LEN + BOOTTBL_HEADER_LEN + MAX_BOOTTBL_LEN;
+               data.IPlength = data.UDPlength + IP_HEADER_LEN;
+               UDPchecksum = bootmiscOnesComplementAdd(IP_TYPE_UDP, data.UDPlength);
+
+               for(j=0; j<counter; j++) { // For first and middle packets
+                                       
+                               data.IPchecksum=bootmiscOnesComplementChksum(0,&data.VerTOS,IP_HEADER_LEN/2);
+               
+                               if(getDataIn(strin, MAX_BOOTTBL_LEN, data.BootTable)!=0) {
+                                       fclose(strin);
+                                       fclose(strout);
+                                       return; 
+                               };
+
+                               data.UDPchecksum=bootmiscOnesComplementChksum(UDPchecksum, &data.srcIPAddr_H,\
+                                                         (UINT16)((4+4+UDP_HEADER_LEN+BOOTTBL_HEADER_LEN+MAX_BOOTTBL_LEN)/2));
+
+                               writeheader(strout, &data.dstMAC_H);
+                               writeboottable(strout,&data.BootTable[0],MAX_BOOTTBL_LEN/2);
+
+                               fprintf (strout, "0x%04X\n",(unsigned short)(SYMBOL));
+                               fprintf (strout, "0x%04X\n",0x0000);
+
+                               if(j != counter-1) fprintf (strout,"0x%04X\n",TOTAL_HEADER_LEN+MAX_BOOTTBL_LEN);
+
+                               // make ready for the next packet
+                               data.ID++;
+                               data.SeqNo++;
+
+                               if(data.SeqNo >= 0x200) {
+                                       data.SeqNo = 0x100;
+                               }
+
+                               data.IPchecksum = 0x0000;
+                               data.UDPchecksum = 0x0000;
+
+               }       
+
+               // For the last packet
+               temp = counter*MAX_BOOTTBL_LEN;
+               counter = inSize - temp; // how many bytes remained
+               fprintf (strout,"0x%04X\n",TOTAL_HEADER_LEN+counter);
+
+               data.UDPlength = UDP_HEADER_LEN + BOOTTBL_HEADER_LEN + counter;
+
+               data.IPlength = data.UDPlength + IP_HEADER_LEN;
+               data.IPchecksum = bootmiscOnesComplementChksum(0,&data.VerTOS,IP_HEADER_LEN/2);
+
+               if(getDataIn(strin, counter, data.BootTable)!=0) {
+                       fclose(strin);
+                       fclose(strout);
+                       return;
+               }
+
+               UDPchecksum = bootmiscOnesComplementAdd(IP_TYPE_UDP, data.UDPlength);
+               data.UDPchecksum=bootmiscOnesComplementChksum(UDPchecksum, &data.srcIPAddr_H,\
+                                                         (UINT16)((4+4+UDP_HEADER_LEN+BOOTTBL_HEADER_LEN+counter)/2));
+               writeheader(strout, &data.dstMAC_H);
+               writeboottable(strout,&data.BootTable[0],counter/2);
+
+               fprintf (strout, "0x%04X\n",(unsigned short)(SYMBOL));
+               fprintf (strout, "0x%04X\n",0x0000);
+               fprintf (strout, "0x%04X\n",0x0000);
+       }
+
+       fclose(strin);
+       fclose(strout);
+}
diff --git a/boot_loader/examples/emac/Utilities/bootpacket.exe b/boot_loader/examples/emac/Utilities/bootpacket.exe
new file mode 100644 (file)
index 0000000..cc11e0e
Binary files /dev/null and b/boot_loader/examples/emac/Utilities/bootpacket.exe differ
diff --git a/boot_loader/examples/emac/Utilities/bootpacket.h b/boot_loader/examples/emac/Utilities/bootpacket.h
new file mode 100644 (file)
index 0000000..9d298de
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef bootpacket
+#define bootpacket
+
+typedef short int INT16;
+typedef int INT32;
+typedef unsigned short int UINT16;
+typedef unsigned int UINT32;
+
+#define DST_MAC_H 0x0008
+#define DST_MAC_M 0x7433
+#define DST_MAC_L 0x2630
+
+#define SRC_MAC_H 0x000D
+#define SRC_MAC_M 0x5676
+#define SRC_MAC_L 0x2F1A
+
+#define SRC_IP_ADDR_H 0x9EDA
+#define SRC_IP_ADDR_L 0x674E
+#define DST_IP_ADDR_H 0x9EDA
+#define DST_IP_ADDR_L 0x6723
+
+#define UDP_SRC_PORT 0x0
+#define UDP_SRC_PORT_BTPKT 0xBEEF  /* Bill's bt-pkt.exe use this value */
+#define UDP_DST_PORT 0x9
+
+#define ETHER_TYPE_IP 0x800
+#define IP_TYPE_UDP 0x11    
+
+#define MAGICNO 0x544B
+
+/* Actual packets has 14 +20 + 8 + 244 = 42 + 244 = 286 bytes */
+
+#define MAC_HEADER_LEN     14
+#define IP_HEADER_LEN      20
+#define UDP_HEADER_LEN     8
+#define BOOTTBL_HEADER_LEN 4
+#define TOTAL_HEADER_LEN   46  /* 14 + 20 + 8 + 4 = 46 bytes */
+
+#define MAX_PAYLOAD_LEN    244
+//#define MAX_PAYLOAD_LEN    1176
+#define MAX_BOOTTBL_LEN (MAX_PAYLOAD_LEN - BOOTTBL_HEADER_LEN) /* 240 bytes */
+
+#define SYMBOL 0xEA00
+#define BGN_BYTE_LEN 0x04  /* ex: 0x0000, 0x00A2 */
+#define END_BYTE_LEN 0x06  /* ex: EA00, 0000, 0000 */
+
+
+struct BootPacket {
+               INT16 dstMAC_H;       /* MAC */
+               INT16 dstMAC_M;
+               INT16 dstMAC_L;
+               INT16 srcMAC_H;
+               INT16 srcMAC_M;
+               INT16 srcMAC_L;
+               INT16 EtherType;
+               INT16 VerTOS;         /* IP */
+               UINT16 IPlength;
+               INT16 ID;
+               INT16 FlagsFrag;
+               INT16 TTLProtocol;
+               UINT16 IPchecksum;
+               INT16 srcIPAddr_H;
+               INT16 srcIPAddr_L;
+               INT16 dstIPAddr_H;
+               INT16 dstIPAddr_L;
+               INT16 srcPort;        /* UDP */
+               INT16 dstPort;
+               UINT16 UDPlength;
+               UINT16 UDPchecksum;
+               INT16 MagicNo;        /* Payload */
+               INT16 SeqNo;
+               INT16 BootTable[MAX_BOOTTBL_LEN/2];
+};
+
+
+
+#endif
\ No newline at end of file
diff --git a/boot_loader/examples/emac/Utilities/build-msvc.bat b/boot_loader/examples/emac/Utilities/build-msvc.bat
new file mode 100644 (file)
index 0000000..99e3c83
--- /dev/null
@@ -0,0 +1,12 @@
+;local
+set MSVCROOT=c:\progtool\msvc60\
+set PATH=%MSVCROOT%\vc98\bin;%MSVCROOT%\common\msdev98\bin;%PATH%
+set INCLUDE=%MSVCROOT%\vc98\include
+set LIB=%MSVCROOT%\vc98\lib
+
+cl b2ccs.c
+cl b2i2c.c
+cl bconvert64x.c
+cl bootpacket.c
+cl mergebtbl.c
+cl myparser.c
diff --git a/boot_loader/examples/emac/Utilities/mergebtbl.c b/boot_loader/examples/emac/Utilities/mergebtbl.c
new file mode 100644 (file)
index 0000000..c237f23
--- /dev/null
@@ -0,0 +1,127 @@
+/**************************************************************************************
+ * FILE PURPOSE: Merge multiple boot tables into one boot table
+ **************************************************************************************
+ * FILE NAME: mergebtbl.c
+ *
+ *   Usage: mergebtbl inputfile1 inputfile2 ... outputfile
+ *          Note: may not support single line boot table(hardly possible)
+ *
+ **************************************************************************************/
+#include <stdio.h>
+#include <string.h>
+
+
+int asciiByte (unsigned char c)
+{
+  if ((c >= '0') && (c <= '9'))
+    return (1);
+
+  if ((c >= 'A') && (c <= 'F'))
+    return (1);
+
+  return (0);
+}
+
+
+int main (int argc, char *argv[])
+{
+  FILE *strin;
+  FILE *strout;
+  int i,j,k;
+  int line;
+  int start;
+  char iline[132];
+  char iline2nd[132];
+
+  /* Verify the number of args */
+   if (argc < 3)  {
+    printf ("usage: %s inpfile[1] ... infile[n] outfile\n", argv[0]);
+    return (-1);
+  }
+
+  strout = fopen (argv[argc-1], "w");
+  if (strout == NULL)  {
+    printf ("could not open file %s to write\n",argv[argc-1]);
+    return (-1);
+  }
+
+  fputs("first line\n",strout);
+  fputs("second line\n",strout);
+
+  for(i=1; i<argc-1;i++) {
+       
+        strin = fopen (argv[i], "r");
+               if (strin == NULL)  {
+                       printf ("could not open input file %s\n", argv[i]);
+                       return (-1);
+               }
+
+               line = 0;
+
+               /* skip the next two lines */
+               fgets (iline, 132, strin);
+               fgets (iline, 132, strin);
+
+               if(fgets(iline2nd, 132, strin)==NULL) {
+                       printf("error in boot table\n");
+               }
+
+               while(1) {
+                       fgets(iline, 132, strin);
+                       if(!asciiByte(iline[0])) break;
+                       line++;
+
+                       if(i!=1 && line==1) { /* if not the first file, get rid of entry point */
+                               for(j=12; j<132; j++) {
+                                       if(iline2nd[j]=='\0') break;
+                                       fputc(iline2nd[j],strout);
+                               }
+                       } else {
+                               fputs(iline2nd,strout);
+                       }
+               strcpy(iline2nd,iline);
+               } /* while */
+               
+               if(i!=argc-2) { /* If not the last file, get rid of ending 00 00 00 00 */
+                       for(j=0,start=0;j<132;j+=2){
+                               if((iline2nd[j]=='0')&&(iline2nd[j+1]=='0')) {
+                                       if(start) k++;
+                                       else if((j-j/4*4)==0) {
+                                               start = 1; /* not count from any 00 */
+                                               k=1;
+                                       }
+                               }
+                               else { 
+                                       start = 0;
+                                       k=0;
+                               }
+               
+                               if(k==4) {  // when 00 00 00 00 reached
+                                       if(asciiByte(iline2nd[j+3])) { //if the next char is still ASCII
+                                               start = 0;
+                                       } else break; /* Ending 00 00 00 00 reach */
+                               }
+                               j++;            /* skip the space */
+                       }
+
+                       if((k==4) && (j>10)) {
+                       for(k=0;k<j-10;k++){
+                               fputc(iline2nd[k],strout);
+                               }
+                               fputc('\n',strout);
+                       }
+               } else {
+                       fputs(iline2nd,strout);
+               }
+
+               fclose(strin);
+  } /* for */
+
+  fputc(0x04,strout); /* any non-ASCII character */
+
+  fclose(strout);
+
+  return (0);
+}
+
diff --git a/boot_loader/examples/emac/Utilities/mergebtbl.exe b/boot_loader/examples/emac/Utilities/mergebtbl.exe
new file mode 100644 (file)
index 0000000..8fbc185
Binary files /dev/null and b/boot_loader/examples/emac/Utilities/mergebtbl.exe differ
diff --git a/boot_loader/examples/emac/Utilities/myparser.c b/boot_loader/examples/emac/Utilities/myparser.c
new file mode 100644 (file)
index 0000000..fe986f7
--- /dev/null
@@ -0,0 +1,157 @@
+/**************************************************************************************
+ * FILE PURPOSE: Merge I2C boot parameter and boot table into one final .ccs file
+ **************************************************************************************
+ * FILE NAME: myparser.c
+ *
+ *   Usage: myparser input.ccs input.txt output.ccs
+ *
+ *   Note: this code can be improved to support read boot table not from offset 0x20 but anywhere
+ *
+ **************************************************************************************/
+#include <stdio.h>
+#include <string.h>
+
+
+/***************************************************************************************
+ * FUNCTION PURPOSE: The main program
+ ***************************************************************************************
+ * DESCRIPTION: Performs the conversion from ccs format to qt format
+ ***************************************************************************************/
+int main (int argc, char *argv[])
+{
+  FILE *strin1;
+  FILE *strin2;
+  FILE *strout;
+
+  int a,b,c,d,n1,n;
+  int i, table;
+  int num_tables;
+  int table_size;
+  int rem_lines;
+  long int temp;
+
+  char iline[132];
+  char iline2[132];
+
+  /* Verify the number of args */
+  if (argc != 4)  {
+    printf ("usage: %s input.ccs input.txt output.ccs\n", argv[0]);
+    return (-1);
+  }
+
+  /* Open all the files */
+  strin1 = fopen (argv[1], "r");
+  if (strin1 == NULL)  {
+    printf ("could not open input file %s\n", argv[1]);
+    return (-1);
+  }
+
+  strin2 = fopen (argv[2], "r");
+  if (strin2 == NULL)  {
+    printf ("could not open input file %s\n", argv[2]);
+    return (-1);
+  }
+
+  strout = fopen (argv[3], "w");
+  if (strout == NULL)  {
+    printf ("could not open file %s to write\n",argv[3]);
+    return (-1);
+  }
+
+  /* Read the header */
+  fgets (iline, 132, strin1);
+  sscanf (iline, "%x %x %x %x %x", &a, &b, &c, &d, &n1);
+
+  /* read the first config line - get number of tables in the file */
+  fgets(iline,132,strin2);
+  sscanf (iline, "%x", &num_tables);
+
+  if (num_tables == 0)
+  {
+    printf("Error in I2C configure file, num tables = 0.\n");
+    return(-1);
+  }
+  printf("Reading %d tables from I2C configure file\n", num_tables);
+
+  n = n1 + (32 * num_tables) + 2;
+
+  /* Write the CCS header */
+  fprintf (strout, "1651 1 10890000 1 %x\n", n);
+  fprintf (strout, "0x%08x\n",n*4-8);
+  fprintf (strout, "0x%08x\n",0);
+
+
+  /* Prime the loop: read the table size from the first line */
+  if (fgets(iline,132,strin2)==NULL)
+  {
+    fclose(strin1);
+    fclose(strin2);
+    fclose(strout);
+    printf("Error in I2C configure file\n");
+    return(-1);
+  }
+
+  for (table = 0; table < num_tables; table++)
+  {
+    strncpy(iline2, iline, 6); //get the first 16 bits (0xffff)
+    iline2[6] = 0;             //make sure it's null terminated
+    sscanf (iline2, "%x", &table_size);
+    fprintf(strout, "%s", iline);
+
+    printf("  Table %d size %d\n", table+1, table_size);
+
+    /* There must be table_size / 4 lines in the file. */
+    for (i = 1; i < (table_size / 4); i++)
+    {
+      if (fgets(iline,132,strin2)==NULL)
+      {
+        fclose(strin1);
+        fclose(strin2);
+        fclose(strout);
+        printf("Error in I2C configure file\n");
+        return(-1);
+      }
+
+      fprintf (strout, "%s",iline);
+    }
+
+    rem_lines = (128 - table_size) / 4;
+
+    /* Read remaining lines, or encounter the next header early. */
+    for (i = 0; i < rem_lines; i++)
+    {
+      if (fgets(iline,132,strin2)==NULL) break;
+
+      strncpy(iline2, iline, 10); //get just the hex number
+      iline2[10] = 0;             //make sure it's null terminated
+      sscanf (iline2, "%x", &temp);
+      if (temp != 0) break;
+      fprintf (strout, "%s",iline);
+    }
+
+    if (i < rem_lines) //encountered next header early, add remaining lines
+    {
+      rem_lines -= i;
+
+      for (i = 0; i < rem_lines; i++)
+        fprintf (strout, "0x%08x\n",0);
+    }
+    else if (table < (num_tables - 1))
+    {
+      fgets(iline,132,strin2);  //read the next header
+    }
+  }
+
+  fclose(strin2);
+
+  for (i=0; i < n1; i++)
+  {
+    fgets(iline,132,strin1);
+    fprintf (strout, "%s",iline);
+  }
+
+  fclose(strin1);
+  fclose(strout);
+
+  return (0);
+}
diff --git a/boot_loader/examples/emac/Utilities/myparser.exe b/boot_loader/examples/emac/Utilities/myparser.exe
new file mode 100644 (file)
index 0000000..3c1839c
Binary files /dev/null and b/boot_loader/examples/emac/Utilities/myparser.exe differ
diff --git a/boot_loader/examples/emac/simple/makefile b/boot_loader/examples/emac/simple/makefile
new file mode 100644 (file)
index 0000000..136d6bd
--- /dev/null
@@ -0,0 +1,45 @@
+#**************************************************************************
+#* FILE PURPOSE: Build the simple test program
+#**************************************************************************
+#* FILE NAME: makefile
+#*
+#* DESCRIPTION: Builds the following:
+#*
+#*              simple_him.out    - little endian himalaya mapped program.
+#*              simple.le.btbl    - Simple program in boot table format.
+#*                 simple.eth      - Simple Program in ETH format.     
+#*              
+#***************************************************************************
+
+AOPTS_LE= -g -c -k -mi200 -ml3 -pm -mv6400
+AOPTS_BE= -me $(AOPTS_LE)
+
+all: simple.eth
+
+simple.eth: simple.out
+       hex6x simple.rmd
+       ../Utilities/bconvert64x -le simple.btbl simple.le.btbl
+       ../Utilities/bootpacket simple.le.btbl simple.eth
+       cp simple.eth ../Ethernet_boot/simple.eth
+       rm simple.eth
+
+simple.out: simple.obj simple.cmd
+       cl6x -z simple.cmd -o simple.out -m simple.map
+
+simple.obj: simple.s
+       cl6x $(AOPTS_LE) simple.s
+
+clean:
+       rm simple.obj
+       rm simple.out
+       rm simple.btbl
+       rm simple.le.btbl
+       rm simple.map
+       
+       
+
+       
+
+
+
+
diff --git a/boot_loader/examples/emac/simple/simple.btbl b/boot_loader/examples/emac/simple/simple.btbl
new file mode 100644 (file)
index 0000000..eb67ebb
--- /dev/null
@@ -0,0 +1,10 @@
+\ 2
+$A0400,
+00 81 00 00 00 00 00 40 00 81 00 00 00 99 A2 28 00 88 91 68 01 01 00 A8 
+01 00 40 E8 01 08 02 26 01 81 08 28 01 80 40 E8 01 8C 36 26 02 0C 02 26 
+00 01 A1 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
+00 00 00 00 
+00 00 00 04 00 81 01 00 12 34 AB CD 
+00 00 00 01 00 81 02 01 00 00 00 12 
+00 00 00 02 00 81 02 10 00 00 34 12 00 00 00 00 
+\ 3
\ No newline at end of file
diff --git a/boot_loader/examples/emac/simple/simple.cmd b/boot_loader/examples/emac/simple/simple.cmd
new file mode 100644 (file)
index 0000000..6b7cf3d
--- /dev/null
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * FILE PURPOSE: The Himalaya linker command file for program simple
+ ***************************************************************************
+ * FILE NAME: simple_him.cmd
+ *
+ * DESCRIPTION: Maps the program simple into the Himalaya memory space
+ *
+ ***************************************************************************/
+/* Object file */
+simple.obj
+
+/* Linker options */
+-c
+-a
+
+MEMORY
+{
+   PAGE 0:
+   
+     TEXT    :   origin = 0x810000,  length = 0x0040
+     DATA    :   origin = 0x810100,  length = 0x0004
+        BYTE1   :   origin = 0x810201,  length = 0x0001
+        BYTE2   :   origin = 0x810210,  length = 0x0002
+     
+}
+
+SECTIONS
+{
+     .text  >  TEXT  PAGE 0
+     .data  >  DATA  PAGE 0
+        .byte1 >  BYTE1 PAGE 0
+        .byte2 >  BYTE2 PAGE 0
+}     
+
+
+
+
+
+
+
diff --git a/boot_loader/examples/emac/simple/simple.le.btbl b/boot_loader/examples/emac/simple/simple.le.btbl
new file mode 100644 (file)
index 0000000..c528049
--- /dev/null
@@ -0,0 +1,8 @@
+\ 2
+$A000000
+00 81 00 00 00 00 00 40 00 81 00 00 00 99 A2 28 00 88 91 68 01 01 00 A8
+01 00 40 E8 01 08 02 26 01 81 08 28 01 80 40 E8 01 8C 36 26 02 0C 02 26
+00 01 A1 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 04 00 81 01 00 12 34 AB CD 00 00 00 01 00 81 02 01
+12 00 00 00 00 00 00 02 00 81 02 10 12 34 00 00 00 00 00 00 
+\ 3
\ No newline at end of file
diff --git a/boot_loader/examples/emac/simple/simple.map b/boot_loader/examples/emac/simple/simple.map
new file mode 100644 (file)
index 0000000..fbfc4f9
--- /dev/null
@@ -0,0 +1,95 @@
+******************************************************************************
+               TMS320C6x Linker PC v7.2.0                      
+******************************************************************************
+>> Linked Mon May 02 11:08:25 2011
+
+OUTPUT FILE NAME:   <simple.out>
+ENTRY POINT SYMBOL: "_c_int00"  address: 00810000
+
+
+MEMORY CONFIGURATION
+
+         name            origin    length      used     unused   attr    fill
+----------------------  --------  ---------  --------  --------  ----  --------
+  TEXT                  00810000   00000040  00000040  00000000  RWIX
+  DATA                  00810100   00000004  00000004  00000000  RWIX
+  BYTE1                 00810201   00000001  00000001  00000000  RWIX
+  BYTE2                 00810210   00000002  00000002  00000000  RWIX
+
+
+SECTION ALLOCATION MAP
+
+ output                                  attributes/
+section   page    origin      length       input sections
+--------  ----  ----------  ----------   ----------------
+.text      0    00810000    00000040     
+                  00810000    00000040     simple.obj (.text)
+
+.data      0    00810100    00000004     
+                  00810100    00000004     simple.obj (.data)
+
+.byte1     0    00810201    00000001     
+                  00810201    00000001     simple.obj (.byte1)
+
+.byte2     0    00810210    00000002     
+                  00810210    00000002     simple.obj (.byte2)
+
+
+GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name 
+
+address    name
+--------   ----
+00000000   $bss
+00810100   .data
+00810000   .text
+ffffffff   ___TI_pprof_out_hndl
+ffffffff   ___TI_prof_data_size
+ffffffff   ___TI_prof_data_start
+ffffffff   ___binit__
+ffffffff   ___c_args__
+ffffffff   ___cinit__
+00810100   ___data__
+00810104   ___edata__
+00810040   ___etext__
+ffffffff   ___pinit__
+00810000   ___text__
+00810000   _c_int00
+ffffffff   binit
+00810201   byte1
+00810210   byte2
+ffffffff   cinit
+00810104   edata
+00810040   etext
+ffffffff   pinit
+00810100   someData
+
+
+GLOBAL SYMBOLS: SORTED BY Symbol Address 
+
+address    name
+--------   ----
+00000000   $bss
+00810000   .text
+00810000   ___text__
+00810000   _c_int00
+00810040   ___etext__
+00810040   etext
+00810100   .data
+00810100   ___data__
+00810100   someData
+00810104   ___edata__
+00810104   edata
+00810201   byte1
+00810210   byte2
+ffffffff   ___TI_pprof_out_hndl
+ffffffff   ___TI_prof_data_size
+ffffffff   ___TI_prof_data_start
+ffffffff   ___binit__
+ffffffff   ___c_args__
+ffffffff   ___cinit__
+ffffffff   ___pinit__
+ffffffff   binit
+ffffffff   cinit
+ffffffff   pinit
+
+[23 symbols]
diff --git a/boot_loader/examples/emac/simple/simple.obj b/boot_loader/examples/emac/simple/simple.obj
new file mode 100644 (file)
index 0000000..59de594
Binary files /dev/null and b/boot_loader/examples/emac/simple/simple.obj differ
diff --git a/boot_loader/examples/emac/simple/simple.out b/boot_loader/examples/emac/simple/simple.out
new file mode 100644 (file)
index 0000000..54460bc
Binary files /dev/null and b/boot_loader/examples/emac/simple/simple.out differ
diff --git a/boot_loader/examples/emac/simple/simple.rmd b/boot_loader/examples/emac/simple/simple.rmd
new file mode 100644 (file)
index 0000000..7b0bf5c
--- /dev/null
@@ -0,0 +1,15 @@
+simple.out
+-a
+-boot
+-e _c_int00
+-order L
+
+ROMS
+{
+   ROM1:  org = 0x0400, length = 0x0080, memwidth = 32, romwidth = 32
+          files = { simple.btbl }
+          
+}          
+          
+          
+          
\ No newline at end of file
diff --git a/boot_loader/examples/emac/simple/simple.s b/boot_loader/examples/emac/simple/simple.s
new file mode 100644 (file)
index 0000000..1e233a1
--- /dev/null
@@ -0,0 +1,64 @@
+;****************************************************************************
+;* FILE PURPOSE: Code a simple endian independent example
+;****************************************************************************
+;* FILE NAME: Simple.s
+;*
+;* DESCRIPTION: This program is part of the Himalaya I2C boot test plan.
+;*              It is a simple program that defines two initialized
+;*              sections, text and data, and performs a simple
+;*              execution with a self check on the results in register a0.
+;*
+;*              The code is also designed to be relocatable, so it will
+;*              function in the himsim program running on the DM642.
+;*
+;*****************************************************************************
+
+;*****************************************************************************
+;*  Initialized data
+;*****************************************************************************
+   .data
+   .def     someData
+someData   .word   01234ABCDh
+
+    .def  byte1
+       .sect ".byte1"
+byte1: .byte 0x12
+
+       .def byte2
+       .sect ".byte2"
+byte2: .byte 0x12, 0x34
+
+;*****************************************************************************
+;*  code
+;*****************************************************************************
+   .text
+   .def _c_int00
+   
+myConst    .equ    011223344h
+   
+_c_int00:
+
+   MVKL.S1     myConst, A1
+   MVKH.S1     myConst, A1
+
+   MVKL.S1     byte1, A2
+   MVKH.S1     byte1, A2
+   LDB.D1         *A2, B2
+
+   MVKL.S1     byte2, A3
+   MVKH.S1     byte2, A3
+   LDB.D1         *A3++, B3
+   LDB.D1      *A3,   B4
+   
+   
+etrap:
+
+   BNOP.S1 etrap, 5
+   
+   
+   
+
+
+
+
+
index 99a59d2ec7249db2663e650473c8cada572a844c..c637ccc669debac75abed0497fed68e0983de30e 100644 (file)
@@ -26,24 +26,33 @@ Steps to run i2cemacboot in CCSv5:
 
 Steps to program i2cemacboot to EMAC:
 
-1. Be sure IBL and boot configuration table are programmed to I2C EEPROM bus address 81 (0x51), if IBL and/or
-   boot configuration table are not programmed, refer to tools\boot_loader\ibl\doc\README.txt on how to program 
-   the IBL and boot configuration table to EEPROM. 
-
-2. Copy tools\boot_loader\examples\i2c\emac\evmc66xxl\bin\i2cemacboot_evm66xxl.out to tools\bin2ccs and rename
+1. Be sure IBL is programmed to I2C EEPROM bus address 81 (0x51), if IBL is not programmed, refer to
+   tools\boot_loader\ibl\doc\README.txt on how to program the IBL to EEPROM. 
+
+2. By default, IBL will boot a BBLOB image from EMAC, to run this example, we need to change the
+   EMAC boot image format to ELF:
+   a. In setConfig_c66xx_main() of tools\boot_loader\ibl\src\util\i2cConfig\i2cConfig.gel, 
+      replace 
+          ibl.bootModes[2].u.ethBoot.bootFormat        = ibl_BOOT_FORMAT_BBLOB;
+      with
+          ibl.bootModes[2].u.ethBoot.bootFormat        = ibl_BOOT_FORMAT_ELF;
+   b. Re-program the boot configuration table, refer to tools\boot_loader\ibl\doc\README.txt on how to program 
+      the boot configuration table to EEPROM. 
+      
+3. Copy tools\boot_loader\examples\i2c\emac\evmc66xxl\bin\i2cemacboot_evm66xxl.out to tools\bin2ccs and rename
    the file to app.out.
 
-3. Double click bin2ccs.bat, which will convert app.out to a CCS format data file app.dat.
+4. Double click bin2ccs.bat, which will convert app.out to a CCS format data file app.dat.
 
-4. Start a TFTP server (you can download a free, open source application from http://tftpd32.jounin.net) and copy
+5. Start a TFTP server (you can download a free, open source application from http://tftpd32.jounin.net) and copy
    app.dat to the TFTP base directory.
 
-5. Set the IP address of the PC that is running the TFTP server to 192.168.2.101, since by default IBL will set the EVM 
+6. Set the IP address of the PC that is running the TFTP server to 192.168.2.101, since by default IBL will set the EVM 
    IP address to 192.168.2.100 and the TFTP server IP address to 192.168.2.101. 
 
-6. Set the boot dip switches to I2C master mode, bus address 81 (0x51) and boot parameter index to be 4.
+7. Set the boot dip switches to I2C master mode, bus address 81 (0x51) and boot parameter index to be 4.
 
-7. Be sure the EVM and the PC are connected in the same subnet of a local network, after POR, IBL will download the
+8. Be sure the EVM and the PC are connected in the same subnet of a local network, after POR, IBL will download the
    boot image from TFTP server and boot from it. By default IBL will boot an ELF format image, if user wants to boot 
    an image of other formats, he/she needs to change the boot configuration table accordingly, and re-program the table
    to the EEPROM.
index 2902574a9e300f90fe1b792bdcd07d7a0c7b9b53..1044dc9dfe0dc664237d0c554e7196e43504b4ef 100644 (file)
@@ -1,34 +1,34 @@
 /******************************************************************************
  * Copyright (c) 2011 Texas Instruments Incorporated - http://www.ti.com
- * 
- *  Redistribution and use in source and binary forms, with or without 
- *  modification, are permitted provided that the following conditions 
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
  *  are met:
  *
- *    Redistributions of source code must retain the above copyright 
+ *    Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  *
  *    Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the 
- *    documentation and/or other materials provided with the   
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the
  *    distribution.
  *
  *    Neither the name of Texas Instruments Incorporated nor the names of
  *    its contributors may be used to endorse or promote products derived
  *    from this software without specific prior written permission.
  *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * 
+ *
  *****************************************************************************/
 
 #include <string.h>
@@ -42,9 +42,9 @@
 char post_version[] = POST_VERSION;
 
 /******************************************************************************
- * Function:    post_display_led_error  
+ * Function:    post_display_led_error
  ******************************************************************************/
-void 
+void
 post_display_led_error
 (
     POST_TEST_ID     test_id
@@ -52,7 +52,7 @@ post_display_led_error
 {
     uint8_t     led_status[POST_MAX_NUM_LED];
     uint32_t    i;
-        
+
     memset(led_status, POST_LED_ON, POST_MAX_NUM_LED);
     while (TRUE)
     {
@@ -81,9 +81,9 @@ post_display_led_error
 }
 
 /******************************************************************************
- * Function:    post_write_uart  
+ * Function:    post_write_uart
  ******************************************************************************/
-Bool 
+Bool
 post_write_uart
 (
     char*      msg
@@ -105,9 +105,9 @@ post_write_uart
 }
 
 /******************************************************************************
- * Function:    post_display_status  
+ * Function:    post_display_status
  ******************************************************************************/
-void 
+void
 post_display_status
 (
     POST_TEST_ID        test_id,
@@ -156,7 +156,7 @@ post_display_status
             if (post_write_uart(msg) != TRUE)
             {
                 post_display_led_error(POST_TEST_UART);   /* Never return from this function */
-            }      
+            }
             post_display_led_error(test_id);  /* Never return from this function */
         }
         break;
@@ -164,9 +164,9 @@ post_display_status
 }
 
 /******************************************************************************
- * Function:    post_test_external_memory  
+ * Function:    post_test_external_memory
  ******************************************************************************/
-Bool 
+Bool
 post_test_external_memory
 (
     void
@@ -174,7 +174,7 @@ post_test_external_memory
 {
     Bool    test_passed = TRUE;
 
-    if(platform_external_memory_test(0, 0) != Platform_EOK) 
+    if(platform_external_memory_test(0, 0) != Platform_EOK)
     {
         test_passed = FALSE;
     }
@@ -183,9 +183,9 @@ post_test_external_memory
 }
 
 /******************************************************************************
- * Function:    post_test_eeprom  
+ * Function:    post_test_eeprom
  ******************************************************************************/
-Bool 
+Bool
 post_test_eeprom
 (
     void
@@ -196,15 +196,15 @@ post_test_eeprom
     PLATFORM_DEVICE_info    *p_device;
 
     p_device = platform_device_open(POST_EEPROM_TEST_DEVICE_ID, 0);
-    if (p_device == NULL) 
+    if (p_device == NULL)
     {
         return FALSE;
     }
 
-    if(platform_device_read(p_device->handle, 
-                            POST_EEPROM_TEST_READ_ADDRESS, 
-                            test_buf, 
-                            POST_EEPROM_TEST_READ_LENGTH) != Platform_EOK) 
+    if(platform_device_read(p_device->handle,
+                            POST_EEPROM_TEST_READ_ADDRESS,
+                            test_buf,
+                            POST_EEPROM_TEST_READ_LENGTH) != Platform_EOK)
     {
         test_passed = FALSE;
     }
@@ -214,9 +214,9 @@ post_test_eeprom
 }
 
 /******************************************************************************
- * Function:    post_test_nand  
+ * Function:    post_test_nand
  ******************************************************************************/
-Bool 
+Bool
 post_test_nand
 (
     void
@@ -228,16 +228,16 @@ post_test_nand
     PLATFORM_DEVICE_info    *p_device;
 
     p_device = platform_device_open(POST_NAND_TEST_DEVICE_ID, 0);
-    if (p_device == NULL) 
+    if (p_device == NULL)
     {
         return FALSE;
     }
 
     addr = (POST_NAND_TEST_READ_BLOCK_NUM * p_device->page_count + POST_NAND_TEST_READ_PAGE_NUM) * p_device->page_size;
-    if(platform_device_read(p_device->handle, 
-                            addr, 
-                            test_buf, 
-                            POST_NAND_TEST_READ_LENGTH) != Platform_EOK) 
+    if(platform_device_read(p_device->handle,
+                            addr,
+                            test_buf,
+                            POST_NAND_TEST_READ_LENGTH) != Platform_EOK)
     {
         test_passed = FALSE;
     }
@@ -247,9 +247,9 @@ post_test_nand
 }
 
 /******************************************************************************
- * Function:    post_test_nor 
+ * Function:    post_test_nor
  ******************************************************************************/
-Bool 
+Bool
 post_test_nor
 (
     void
@@ -260,15 +260,15 @@ post_test_nor
     PLATFORM_DEVICE_info    *p_device;
 
     p_device = platform_device_open(POST_NOR_TEST_DEVICE_ID, 0);
-    if (p_device == NULL) 
+    if (p_device == NULL)
     {
         return FALSE;
     }
 
-    if(platform_device_read(p_device->handle, 
-                            POST_NOR_TEST_READ_ADDR, 
-                            test_buf, 
-                            POST_NOR_TEST_READ_LENGTH) != Platform_EOK) 
+    if(platform_device_read(p_device->handle,
+                            POST_NOR_TEST_READ_ADDR,
+                            test_buf,
+                            POST_NOR_TEST_READ_LENGTH) != Platform_EOK)
     {
         test_passed = FALSE;
     }
@@ -327,9 +327,9 @@ post_serial_num_isvalid
 }
 
 /******************************************************************************
- * Function:    post_write_serial_no  
+ * Function:    post_write_serial_no
  ******************************************************************************/
-void 
+void
 post_write_serial_no
 (
     void
@@ -338,9 +338,9 @@ post_write_serial_no
     uint32_t                i, j;
     uint8_t                 msg[20], msg2[2];
     PLATFORM_DEVICE_info    *p_device;
-   
+
     /* Check if user key in the passcode "ti" to enter board serial number */
-    if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK) 
+    if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK)
     {
         return;
     }
@@ -349,7 +349,7 @@ post_write_serial_no
         return;
     }
 
-    if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK) 
+    if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK)
     {
         return;
     }
@@ -360,7 +360,7 @@ post_write_serial_no
 
     /* Passcode verified, prompt the user to enter serial number */
     p_device = platform_device_open(PLATFORM_DEVID_EEPROM50, 0);
-    if (p_device == NULL) 
+    if (p_device == NULL)
     {
         return;
     }
@@ -397,7 +397,7 @@ post_write_serial_no
             msg[j] = 0xff;
         }
     }
-    
+
     if(platform_device_write(p_device->handle, POST_SERIAL_NUM_ADDR, msg, 16) == Platform_EOK)
     {
         post_write_uart("\r\n\r\nSerial number programmed to EEPROM successfully! ");
@@ -413,7 +413,7 @@ post_write_serial_no
 /******************************************************************************
  * Function:    main function for POST
  ******************************************************************************/
-void 
+void
 main
 (
     void
@@ -494,7 +494,7 @@ main
             post_write_uart(msg);
         }
 
-        sa_enable = *(volatile uint32_t *)0x20c0000;
+        sa_enable = *(volatile uint32_t *)0x20c0004;
         sa_enable &= 0x1;
 
         if (sa_enable)