]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/mcsdk-tools.git/blob - writer/nor/src/norwriter.c
Merge from master for mcsdk-210
[keystone-rtos/mcsdk-tools.git] / writer / nor / src / norwriter.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: NOR writer utility
36  **************************************************************************************
37  * FILE NAME: norwriter.c
38  *
39  * DESCRIPTION: A simple nor writer using platform lib APIs to program the NOR flash
40  *              with an image that the ibl can read.
41  *
42  ***************************************************************************************/
43 #include <stdlib.h>
44 #include <stdio.h>
45 #include <string.h>
46 #include "platform.h"
47 #include "types.h"
49 /* NOR writer utility version */
50 char version[] = "01.00.00.03";
52 /* The input file name is hard coded */
53 char *input_file = "nor_writer_input.txt";
55 uint32_t swap_byte = 0;
57 /* Parameters defined in the input_file */
58 #define FILE_NAME      "file_name"
59 #define START_ADDR     "start_addr"
61 /* Memory address to store the write data */
62 #define WRITE_DATA_ADDRESS     0x80000000
64 /******************************************************************************
65  * Structure:   NOR_WRITER_INFO_T
66  *
67  *              NOR writer control data. This structure should be filled in
68  *              by the user before running
69  ******************************************************************************/
70 #define MAX_LINE_LENGTH 40
71 typedef struct NOR_WRITER_INFO_tag
72 {
73     char        file_name[MAX_LINE_LENGTH]; /* CCS format data file name */
74     uint32_t    blockSizeBytes;             /* The size of each sector */
75     uint32_t    deviceTotalBytes;           /* Total number of bytes available in the device */
76     uint32_t    startAddr;                  /* Start address to write */
77     uint32_t    writeBytes;                 /* Number of bytes to be written into the device */
78     uint8_t     *writeData;                 /* Address to store the write data */
79     uint8_t     *readData;                  /* Address to store the read data */
81 } NOR_WRITER_INFO_T;
83 NOR_WRITER_INFO_T norWriterInfo;
85 /* OSAL functions for Platform Library */
86 uint8_t *Osal_platformMalloc (uint32_t num_bytes, uint32_t alignment)
87 {
88         return malloc(num_bytes);
89 }
91 void Osal_platformFree (uint8_t *dataPtr, uint32_t num_bytes)
92 {
93     /* Free up the memory */
94     if (dataPtr)
95     {
96         free(dataPtr);
97     }
98 }
100 void Osal_platformSpiCsEnter(void)
102     return;
105 void Osal_platformSpiCsExit (void)
107     return;
110 /******************************************************************************
111  * Function:    print_platform_errno
112  ******************************************************************************/
113 void
114 print_platform_errno
116     void
119     printf ("Returned platform error number is %d\n", platform_errno);
122 /******************************************************************************
123  * Function:    form_block
124  *
125  *      Form a block of data to write to the NOR. The block is
126  *      created as a byte stream from the 4 byte stream in which
127  *      the MSB is always sent first.
128  ******************************************************************************/
129 void
130 formBlock
132     uint32_t      *data,
133     uint32_t      blockSize,
134     uint8_t       *scratch
137     uint32_t i, j;
138     
139     /* Convert the data to a byte stream */
140     for (i = j = 0; j < blockSize; i++, j+=4)
141     {
142         scratch[j+0] = (data[i] >> 24) & 0xff;
143         scratch[j+1] = (data[i] >> 16) & 0xff;
144         scratch[j+2] = (data[i] >>  8) & 0xff;
145         scratch[j+3] = (data[i] >>  0) & 0xff;
146     }
149 /******************************************************************************
150  * Function:    flash_nor
151  *
152  *              Write the image to flash.
153  *              Returns TRUE if the image is written successfully
154  *                      FALSE if the image write fails
155  ******************************************************************************/
156 Bool
157 flash_nor
159     PLATFORM_DEVICE_info    *p_device
162     uint32_t      wPos, wLen;
163     uint32_t      block, start_block;
164     uint8_t       *scrach_block;
166     if (swap_byte)
167     {
168         scrach_block = malloc(norWriterInfo.blockSizeBytes);
169         if (scrach_block == NULL)
170         {
171             printf ("Can not allocate scratch block memory!\n");
172             return (FALSE);
173         }
174     }
176     start_block = norWriterInfo.startAddr / norWriterInfo.blockSizeBytes;
178     /* Program the NOR */
179     for (block = start_block, wPos = 0; wPos < norWriterInfo.writeBytes; block++, wPos += norWriterInfo.blockSizeBytes)
180     {
181         printf ("Flashing sector %d (%d bytes of %d)\n", block, wPos, norWriterInfo.writeBytes);
183         wLen = norWriterInfo.blockSizeBytes;
184         if (norWriterInfo.writeBytes - wPos < norWriterInfo.blockSizeBytes)
185         {
186             wLen = norWriterInfo.writeBytes - wPos;
187         }
189         if (swap_byte)
190         {
191             formBlock((uint32_t *)(&norWriterInfo.writeData[wPos]), norWriterInfo.blockSizeBytes, scrach_block);
192         }
193         else
194         {
195             scrach_block = &norWriterInfo.writeData[wPos];
196         }
197         if (platform_device_write(p_device->handle,
198                                   block*norWriterInfo.blockSizeBytes,
199                                   scrach_block,
200                                   wLen) != Platform_EOK)
201         {
202             printf ("platform_nor_write sector # %d failed!\n", block);
203             print_platform_errno();
204             if (swap_byte) free (scrach_block);
205             return (FALSE);
206         }
207     }
209     if (swap_byte) free (scrach_block);
210     return (TRUE);
213 /******************************************************************************
214  * Function:    flash_verify
215  *
216  *              Read back the data file that was just flashed. On errors mark the block as bad.
217  *              Returns TRUE if the image verified correctly.
218  *                      FALSE if the image verification failed
219  ******************************************************************************/
220 Bool
221 flash_verify
223     PLATFORM_DEVICE_info    *p_device
226     uint32_t      rPos, rLen;
227     uint32_t      i, j;
228     uint32_t      block, start_block;
229     uint8_t       *scrach_block;
230     uint32_t      *read_data_w;
232     if (swap_byte) 
233     {
234         scrach_block = malloc(norWriterInfo.blockSizeBytes);
235         if (scrach_block == NULL)
236         {
237             printf ("Can not allocate scratch block memory!\n");
238             return (FALSE);
239         }
240     }
242     start_block = norWriterInfo.startAddr / norWriterInfo.blockSizeBytes;
244     for (block = start_block, rPos = 0; rPos < norWriterInfo.writeBytes; block++, rPos += norWriterInfo.blockSizeBytes)
245     {
246         printf ("Reading and verifying sector %d (%d bytes of %d)\n", block, rPos, norWriterInfo.writeBytes);
248         if (!swap_byte)
249         {
250             scrach_block = &norWriterInfo.readData[rPos];
252         }
253         /* Read a sector of data */
254         if(platform_device_read(p_device->handle,
255                                 block*norWriterInfo.blockSizeBytes,
256                                 scrach_block,
257                                 norWriterInfo.blockSizeBytes) != Platform_EOK)
258         {
259             printf ("Failure in sector %d\n", block);
260             print_platform_errno();
261             if (swap_byte) free (scrach_block);
262             return (FALSE);
263         }
265         /* Convert the packed data */
266         if (swap_byte)
267         {
268             read_data_w = (uint32_t *)(&norWriterInfo.readData[rPos]);
269             for  (i = 0, j = 0; i < norWriterInfo.blockSizeBytes; i += 4)
270                 read_data_w[j++] = (scrach_block[i+0] << 24) | (scrach_block[i+1] << 16) | (scrach_block[i+2] << 8) | scrach_block[i+3];
271         }
273         /* Read the data from the file */
274         rLen = norWriterInfo.blockSizeBytes;
275         if (norWriterInfo.writeBytes - rPos < norWriterInfo.blockSizeBytes)
276         {
277             rLen = norWriterInfo.writeBytes - rPos;
278         }
280         for (i = rPos; i < rLen; i++)
281         {
282             if (norWriterInfo.readData[i] != norWriterInfo.writeData[i])
283             {
284                 printf ("Failure in sector %d, at byte %d, (at byte %d in the data file) expected 0x%08x, read 0x%08x\n",
285                         block, i, rPos, norWriterInfo.writeData[i], norWriterInfo.readData[i]);
286                 if (swap_byte) free (scrach_block);
287                 return (FALSE);
288             }
289         }
291     }
293     if (swap_byte) free (scrach_block);
294     return (TRUE);
297 /******************************************************************************
298  * Function:    parse_input_file
299  ******************************************************************************/
300 static Bool
301 parse_input_file
303     FILE*               fp
306     char line[MAX_LINE_LENGTH];
307     char tokens[] = " :=;\n\r";
308     char *key, *data;
310     memset(line, 0, MAX_LINE_LENGTH);
312     fgets(line, MAX_LINE_LENGTH, fp);
313     key  = (char *)strtok(line, tokens);
314     data = (char *)strtok(NULL, tokens);
316     if(strlen(data) == 0)
317     {
318        return FALSE;
319     }
321     if(strcmp(key, FILE_NAME) != 0)
322     {
323         return FALSE;
324     }
326     strcpy (norWriterInfo.file_name, data);
328     fgets(line, MAX_LINE_LENGTH, fp);
329     key  = (char *)strtok(line, tokens);
330     data = (char *)strtok(NULL, tokens);
332     if(strlen(data) == 0)
333     {
334        return FALSE;
335     }
337     if(strcmp(key, START_ADDR) != 0)
338     {
339         return FALSE;
340     }
342     norWriterInfo.startAddr = (uint32_t)atoi(data);
344     return TRUE;
347 /******************************************************************************
348  * Function:    find_file_length
349  ******************************************************************************/
350 static Bool
351 find_file_length
353     FILE*               fp
356     char        line[MAX_LINE_LENGTH];
357     char        *pEnd;
358     char        *ext;
359     uint32_t    data_len, write_addr;
361     memset(line, 0, MAX_LINE_LENGTH);
363     ext = strrchr(norWriterInfo.file_name, '.');
366     if (ext && (strcmp(ext, ".dat") == 0))
367     {
368     fgets(line, MAX_LINE_LENGTH, fp);
370     /* Read the write address from the CCS header */
371     strtoul (line,&pEnd,16);
372     strtoul (pEnd,&pEnd,16);
373     write_addr = strtoul (pEnd,&pEnd,16);
374     strtoul (pEnd,&pEnd,16);
376     /* Read the data length */
377     data_len = (strtoul (pEnd,NULL,16)) * 4;
378     }
379     else
380     {
381         /* find the data length by seeking to the end and getting position */
382         fseek(fp, 0, SEEK_END);
383         data_len = ftell(fp);
384         fseek(fp, 0, SEEK_SET);
385     }
387     if (data_len > (norWriterInfo.deviceTotalBytes - norWriterInfo.startAddr))
388     {
389         printf ("The data file is too big to fit into the device.\n");
390         return FALSE;
391     }
393     norWriterInfo.writeBytes = data_len;
394     if (write_addr != WRITE_DATA_ADDRESS)
395         write_addr = WRITE_DATA_ADDRESS;
396     norWriterInfo.writeData  = (uint8_t *)write_addr;
397     norWriterInfo.readData   = (uint8_t *)(write_addr + norWriterInfo.deviceTotalBytes);
399     return TRUE;
402 /******************************************************************************
403  * Function:    main
404  ******************************************************************************/
405 void main ()
407     FILE                    *fp;
408     platform_init_flags     init_flags;
409     platform_init_config    init_config;
410     PLATFORM_DEVICE_info    *p_device;
411     Bool                    ret;
413     printf("NOR Writer Utility Version %s\n\n", version);
415     fp = fopen(input_file, "r");
416     if (fp == NULL)
417     {
418         printf("Error in opening %s input file\n", input_file);
419         return;
420     }
422     ret = parse_input_file(fp);
423     fclose (fp);
425     if (ret == FALSE)
426     {
427         printf("Error in parsing %s input file\n", input_file);
428         return;
429     }
431     /* Initialize main Platform lib */
432     memset(&init_config, 0, sizeof(platform_init_config));
433     memset(&init_flags, 1, sizeof(platform_init_flags));
434     init_flags.pll = 0;
435     init_flags.ddr = 0;
436     if (platform_init(&init_flags, &init_config) != Platform_EOK)
437     {
438         printf ("Platform init failed!\n");
439         print_platform_errno();
440         return;
441     }
443     p_device = platform_device_open(PLATFORM_DEVID_NORN25Q128, 0);
444     if (p_device == NULL)
445     {
446         printf ("NOR device open failed!\n");
447         print_platform_errno();
448         return;
449     }
450     norWriterInfo.deviceTotalBytes  = p_device->block_count * p_device->page_count * p_device->page_size;
451     norWriterInfo.blockSizeBytes    = p_device->page_count * p_device->page_size;
453     if ((norWriterInfo.startAddr % norWriterInfo.blockSizeBytes) != 0)
454     {
455         printf ("The start programming address 0x%8x set in %s is not at the beginning of a block, block size = 0x%4x\n",
456                 norWriterInfo.startAddr,
457                 norWriterInfo.file_name,
458                 norWriterInfo.blockSizeBytes);
459         return;
460     }
462     /* Open and find the length of the data file */
463     fp = fopen (norWriterInfo.file_name, "rb");
464     if (fp == NULL)
465     {
466       printf ("Failed to open file %s\n", norWriterInfo.file_name);
467       platform_device_close(p_device->handle);
468       return;
469     }
471     /* Parse the CCS format file */
472     ret = find_file_length(fp);
473     fclose (fp);
474     if (ret == FALSE)
475     {
476         printf("Error in parsing CCS file %s\n", norWriterInfo.file_name);
477         platform_device_close(p_device->handle);
478         return;
479     }
481     /* Write the flash */
482     if (flash_nor (p_device) == FALSE)
483     {
484         printf ("NOR write failed\n");
485         platform_device_close(p_device->handle);
486         return;
487     }
489     /* verify the flash */
490     if(flash_verify (p_device) == FALSE)
491     {
492         printf ("NOR read verify failed\n");
493         platform_device_close(p_device->handle);
494         return;
495     }
498     printf ("NOR programming completed successfully\n");
500     platform_device_close(p_device->handle);
502     return;