Fixed C6670 SRIO boot issue
[keystone-rtos/mcsdk-tools.git] / writer / eeprom / src / eepromwriter.c
1 /******************************************************************************
2  * Copyright (c) 2011 Texas Instruments Incorporated - http://www.ti.com
3  *
4  *  Redistribution and use in source and binary forms, with or without
5  *  modification, are permitted provided that the following conditions
6  *  are met:
7  *
8  *    Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  *    Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the
14  *    distribution.
15  *
16  *    Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  *****************************************************************************/
34 /**************************************************************************************
35  * FILE PURPOSE: EEPROM writer utility
36  **************************************************************************************
37  * FILE NAME: eepromwriter.c
38  *
39  * DESCRIPTION: A simple EEPROM writer using platform lib APIs to program the EEPROM
40  *              with an image that the ibl can read.
41  *
42  ***************************************************************************************/
43 #include <stdlib.h>
44 #include <stdio.h>
45 #include<ctype.h>
46 #include <string.h>
47 #include "platform.h"
48 #include "types.h"
49 #include "ti/csl/csl_semAux.h"
51 /* EEPROM writer utility version */
52 char version[] = "01.00.00.03";
54 /* The input file name is hard coded */
55 char *input_file = "eepromwriter_input.txt";
57 /* Parameters defined in the input_file */
58 #define FILE_NAME      "file_name"
59 #define BUS_ADDR       "bus_addr"
60 #define START_ADDR     "start_addr"
61 #define SWAP_DATA      "swap_data"
63 /* Memory address to store the write data */
64 #define WRITE_DATA_ADDRESS     0x80000000
66 /******************************************************************************
67  * Structure:   EEPROM_WRITER_INFO_T
68  *
69  *              EEPROM writer control data. This structure should be filled in
70  *              by the user before running
71  ******************************************************************************/
72 #define MAX_LINE_LENGTH 40
73 typedef struct EEPROM_WRITER_INFO_tag
74 {
75     char        file_name[MAX_LINE_LENGTH]; /* CCS format data file name */
76     uint32_t    busAddr;                    /* Slave bus address */
77     uint32_t    startAddr;                  /* Start address to write */
78     uint32_t    swapData;                   /* Swap byte in the 32-bit word of the data */
79     uint32_t    deviceTotalBytes;           /* Total number of bytes available in the device */
80     uint32_t    writeBytes;                 /* Number of bytes to be written into the device */
81     uint8_t     *writeData;                 /* Address to store the write data */
82     uint8_t     *readData;                  /* Address to store the read data */
84 } EEPROM_WRITER_INFO_T;
86 EEPROM_WRITER_INFO_T eepromWriterInfo;
88 /* OSAL functions for Platform Library */
89 uint8_t *Osal_platformMalloc (uint32_t num_bytes, uint32_t alignment)
90 {
91         return malloc(num_bytes);
92 }
94 void Osal_platformFree (uint8_t *dataPtr, uint32_t num_bytes)
95 {
96     /* Free up the memory */
97     if (dataPtr)
98     {
99         free(dataPtr);
100     }
103 void Osal_platformSpiCsEnter(void)
105     /* Get the hardware semaphore.
106      *
107      * Acquire Multi core CPPI synchronization lock
108      */
109     while ((CSL_semAcquireDirect (3)) == 0);
111     return;
114 void Osal_platformSpiCsExit (void)
116     /* Release the hardware semaphore
117      *
118      * Release multi-core lock.
119      */
120     CSL_semReleaseSemaphore (3);
122     return;
125 /******************************************************************************
126  * Function:    print_platform_errno
127  ******************************************************************************/
128 void
129 print_platform_errno
131     void
134     printf ("Returned platform error number is %d\n", platform_errno);
137 /******************************************************************************
138  * Function:    form_block
139  *
140  *      Form a block of data to write to the NOR. The block is
141  *      created as a byte stream from the 4 byte stream in which
142  *      the MSB is always sent first.
143  ******************************************************************************/
144 void
145 formBlock
147     uint32_t      *data,
148     uint32_t      blockSize,
149     uint8_t       *scratch
152     uint32_t i, j;
154     /* Convert the data to a byte stream */
155     for (i = j = 0; j < blockSize; i++, j+=4)
156     {
157         scratch[j+0] = (data[i] >> 24) & 0xff;
158         scratch[j+1] = (data[i] >> 16) & 0xff;
159         scratch[j+2] = (data[i] >>  8) & 0xff;
160         scratch[j+3] = (data[i] >>  0) & 0xff;
161     }
164 /******************************************************************************
165  * Function:    flash_eeprom
166  *
167  *              Write the data from memory to EEPROM.
168  *              Returns TRUE if the data is written successfully
169  *                      FALSE if the data write fails
170  ******************************************************************************/
171 Bool
172 flash_eeprom
174     PLATFORM_DEVICE_info    *p_device
177     uint8_t       *scrach_block;
179     printf ("Writing %d bytes from DSP memory address 0x%08x to EEPROM bus address 0x%04x starting from device address 0x%04x ...\n",
180             eepromWriterInfo.writeBytes,
181             (uint32_t)eepromWriterInfo.writeData,
182             eepromWriterInfo.busAddr,
183             eepromWriterInfo.startAddr);
185     if (eepromWriterInfo.swapData)
186     {
187             scrach_block = malloc(eepromWriterInfo.deviceTotalBytes);
188             if (scrach_block == NULL)
189             {
190                 printf ("Can not allocate scratch block memory!\n");
191                 return (FALSE);
192             }
193         formBlock((uint32_t *)(eepromWriterInfo.writeData), eepromWriterInfo.deviceTotalBytes, scrach_block);
194         }
195         else
196         {
197                 scrach_block = eepromWriterInfo.writeData;
198         }
200     if(platform_device_write(p_device->handle, eepromWriterInfo.startAddr, scrach_block, eepromWriterInfo.writeBytes) != Platform_EOK)
201     {
202         print_platform_errno();
203         if (eepromWriterInfo.swapData)
204                 free (scrach_block);
205         return FALSE;
206     }
208         if(eepromWriterInfo.swapData)
209         free (scrach_block);
211     return TRUE;
214 /******************************************************************************
215  * Function:    flash_verify
216  *
217  *              Read back the data file that was just flashed.
218  *              Returns TRUE if the data verified correctly.
219  *                      FALSE if the data verification failed
220  ******************************************************************************/
221 Bool
222 flash_verify
224     PLATFORM_DEVICE_info    *p_device
227     uint32_t    i, j;
228     uint8_t     *scrach_block;
229     uint32_t    *read_data_w;
231     printf ("Reading %d bytes from EEPROM bus address 0x%04x to DSP memory address 0x%08x starting from device address 0x%04x ...\n",
232             eepromWriterInfo.writeBytes,
233             eepromWriterInfo.busAddr,
234             (uint32_t)eepromWriterInfo.readData,
235             eepromWriterInfo.startAddr);
237     if (eepromWriterInfo.swapData)
238     {
239             scrach_block = malloc(eepromWriterInfo.deviceTotalBytes);
240             if (scrach_block == NULL)
241             {
242                 printf ("Can not allocate scratch block memory!\n");
243                 return (FALSE);
244             }
245         }
246         else
247         {
248                 scrach_block = eepromWriterInfo.readData;
249         }
251     if(platform_device_read(p_device->handle, eepromWriterInfo.startAddr, scrach_block, eepromWriterInfo.writeBytes) != Platform_EOK)
252     {
253         print_platform_errno();
254         return FALSE;
255     }
257     printf ("Verifying data read ...\n");
259     if (eepromWriterInfo.swapData)
260     {
261         /* Convert the packed data */
262         read_data_w = (uint32_t *)(eepromWriterInfo.readData);
263         for  (i = 0, j = 0; i < eepromWriterInfo.deviceTotalBytes; i += 4)
264             read_data_w[j++] = (scrach_block[i+0] << 24) | (scrach_block[i+1] << 16) | (scrach_block[i+2] << 8) | scrach_block[i+3];
265    }
268     for (i = 0; i < eepromWriterInfo.writeBytes; i++)
269     {
270         if (eepromWriterInfo.readData[i] != eepromWriterInfo.writeData[i])
271         {
272             printf ("Failure at byte %d, expected 0x%08x, read 0x%08x\n", i, eepromWriterInfo.writeData[i], eepromWriterInfo.readData[i]);
273             return (FALSE);
274         }
275     }
277     return (TRUE);
280 int32_t 
281 xtoi
283     char            *xs, 
284     uint32_t        *result
287     uint32_t    szlen = strlen(xs);
288     int32_t     i, xv, fact;
289     
290     if (szlen > 0)
291     {
292         /* Converting more than 32bit hexadecimal value? */
293         if (szlen>8) return 2; /* exit */
294         
295         /* Begin conversion here */
296         *result = 0;
297         fact = 1;
298         
299         /* Run until no more character to convert */
300         for(i=szlen-1; i>=0 ;i--)
301         {
302             if (isxdigit(*(xs+i)))
303             {
304                 if (*(xs+i)>=97)
305                 {
306                     xv = ( *(xs+i) - 97) + 10;
307                 }
308                 else if ( *(xs+i) >= 65)
309                 {
310                     xv = (*(xs+i) - 65) + 10;
311                 }
312                 else
313                 {
314                     xv = *(xs+i) - 48;
315                 }
316                 *result += (xv * fact);
317                 fact *= 16;
318             }
319             else
320             {
321                 // Conversion was abnormally terminated
322                 // by non hexadecimal digit, hence
323                 // returning only the converted with
324                 // an error value 4 (illegal hex character)
325                 return 4;
326             }
327         }
328         return 0;
329     }
330     
331     // Nothing to convert
332     return 1;
336 /******************************************************************************
337  * Function:    parse_input_file
338  ******************************************************************************/
339 static Bool
340 parse_input_file
342     FILE*               fp
345     char line[MAX_LINE_LENGTH];
346     char tokens[] = " :=;\n";
347     char *key, *data;
349     memset(line, 0, MAX_LINE_LENGTH);
351     fgets(line, MAX_LINE_LENGTH, fp);
352     key  = (char *)strtok(line, tokens);
353     data = (char *)strtok(NULL, tokens);
355     if(strlen(data) == 0)
356     {
357        return FALSE;
358     }
360     if(strcmp(key, FILE_NAME) != 0)
361     {
362         return FALSE;
363     }
365     strcpy (eepromWriterInfo.file_name, data);
367     fgets(line, MAX_LINE_LENGTH, fp);
368     key  = (char *)strtok(line, tokens);
369     data = (char *)strtok(NULL, tokens);
371     if(strlen(data) == 0)
372     {
373        return FALSE;
374     }
376     if(strcmp(key, BUS_ADDR) != 0)
377     {
378         return FALSE;
379     }
381     if ((data[0] == '0') && (data[1] == 'x' || data[1] == 'X'))
382     {
383         if (xtoi (&data[2], &eepromWriterInfo.busAddr) != 0)
384         {
385             return FALSE;
386         }
387     }
388     else
389     {
390         eepromWriterInfo.busAddr = (uint32_t)atoi(data);
391     }
393     fgets(line, MAX_LINE_LENGTH, fp);
394     key  = (char *)strtok(line, tokens);
395     data = (char *)strtok(NULL, tokens);
397     if(strlen(data) == 0)
398     {
399        return FALSE;
400     }
402     if(strcmp(key, START_ADDR) != 0)
403     {
404         return FALSE;
405     }
407     eepromWriterInfo.startAddr = (uint32_t)atoi(data);
409     fgets(line, MAX_LINE_LENGTH, fp);
410     key  = (char *)strtok(line, tokens);
411     data = (char *)strtok(NULL, tokens);
413     if(strlen(data) == 0)
414     {
415        return FALSE;
416     }
418     if(strcmp(key, SWAP_DATA) != 0)
419     {
420         return FALSE;
421     }
423     eepromWriterInfo.swapData = (uint32_t)atoi(data);
425     return TRUE;
428 /******************************************************************************
429  * Function:    find_file_length
430  ******************************************************************************/
431 static Bool
432 find_file_length
434     FILE*               fp
437     char        line[MAX_LINE_LENGTH];
438     char        *pEnd;
439     char        *ext;
440     uint32_t    data_len, write_addr;
442     memset(line, 0, MAX_LINE_LENGTH);
444     ext = strrchr(eepromWriterInfo.file_name, '.');
447     if (ext && (strcmp(ext, ".dat") == 0))
448     {
449         
450         fgets(line, MAX_LINE_LENGTH, fp);
451         
452         /* Read the write address from the CCS header */
453         strtoul (line,&pEnd,16);
454         strtoul (pEnd,&pEnd,16);
455         write_addr = strtoul (pEnd,&pEnd,16);
456         strtoul (pEnd,&pEnd,16);
457         
458         /* Read the data length */
459         data_len = (strtoul (pEnd,NULL,16)) * 4;
460     }
461     else
462     {
463         /* find the data length by seeking to the end and getting position */
464         fseek(fp, 0, SEEK_END);
465         data_len = ftell(fp);
466         fseek(fp, 0, SEEK_SET);
467     }
469     if (data_len > (eepromWriterInfo.deviceTotalBytes - eepromWriterInfo.startAddr))
470     {
471         printf ("The data file is too big to fit into the device.\n");
472         return FALSE;
473     }
475     eepromWriterInfo.writeBytes = data_len;
476     if (write_addr != WRITE_DATA_ADDRESS)
477         write_addr = WRITE_DATA_ADDRESS;
478     eepromWriterInfo.writeData  = (uint8_t *)write_addr;
479     eepromWriterInfo.readData   = (uint8_t *)(write_addr + eepromWriterInfo.deviceTotalBytes);
481     return TRUE;
484 /******************************************************************************
485  * Function:    main
486  ******************************************************************************/
487 void main ()
489     FILE                    *fp;
490     platform_init_flags     init_flags;
491     platform_init_config    init_config;
492     PLATFORM_DEVICE_info    *p_device;
493     Bool                    ret;
495     printf("EEPROM Writer Utility Version %s\n\n", version);
497     fp = fopen(input_file, "r");
498     if (fp == NULL)
499     {
500         printf("Error in opening %s input file\n", input_file);
501         return;
502     }
504     ret = parse_input_file(fp);
505     fclose (fp);
507     if (ret == FALSE)
508     {
509         printf("Error in parsing %s input file\n", input_file);
510         return;
511     }
513     /* Initialize main Platform lib */
514     memset(&init_config, 0, sizeof(platform_init_config));
515     memset(&init_flags, 0x01, sizeof(platform_init_flags));
516     init_flags.phy = 0;
518     if (platform_init(&init_flags, &init_config) != Platform_EOK)
519     {
520         printf ("Platform init failed!\n");
521         print_platform_errno();
522         return;
523     }
525     p_device = platform_device_open(eepromWriterInfo.busAddr, 0);
526     if (p_device == NULL)
527     {
528         printf ("EEPROM device open failed!\n");
529         print_platform_errno();
530         return;
531     }
532     eepromWriterInfo.deviceTotalBytes = p_device->block_count * p_device->page_count * p_device->page_size;
534     /* Open and find the length of the data file */
535     fp = fopen (eepromWriterInfo.file_name, "rb");
536     if (fp == NULL)
537     {
538         printf ("Failed to open file %s\n", eepromWriterInfo.file_name);
539         print_platform_errno();
540         platform_device_close(p_device->handle);
541         return;
542     }
544     /* Parse the CCS format file */
545     ret = find_file_length(fp);
546     fclose (fp);
547     if (ret == FALSE)
548     {
549         printf("Error in parsing CCS file %s\n", eepromWriterInfo.file_name);
550         platform_device_close(p_device->handle);
551         return;
552     }
554     /* Write the EEPROM */
555     if (flash_eeprom (p_device) == FALSE)
556     {
557         printf ("EEPROM write failed\n");
558         platform_device_close(p_device->handle);
559         return;
560     }
562     /* verify the flash */
563     if(flash_verify (p_device) == FALSE)
564     {
565         printf ("EEPROM read verify failed\n");
566         platform_device_close(p_device->handle);
567         return;
568     }
571     printf ("EEPROM programming completed successfully\n");
573     platform_device_close(p_device->handle);
575     return;