[processor-sdk/performance-audio-sr.git] / psdk_cust / pdk_k2g_1_0_1_2_eng / packages / ti / boot / writer / nor / src / norwriter.c
1 /*
2 * Copyright (c) 2011-2015, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the 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 "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * 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.04";
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)
101 {
102 return;
103 }
105 void Osal_platformSpiCsExit (void)
106 {
107 return;
108 }
110 /******************************************************************************
111 * Function: print_platform_errno
112 ******************************************************************************/
113 void
114 print_platform_errno
115 (
116 void
117 )
118 {
119 printf ("Returned platform error number is %d\n", platform_errno);
120 }
122 /******************************************************************************
123 * Function: formBlock
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
131 (
132 uint32_t *data,
133 uint32_t blockSize,
134 uint8_t *scratch
135 )
136 {
137 uint32_t i, j;
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 }
147 }
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
158 (
159 PLATFORM_DEVICE_info *p_device
160 )
161 {
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);
211 }
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
222 (
223 PLATFORM_DEVICE_info *p_device
224 )
225 {
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);
295 }
297 /******************************************************************************
298 * Function: parse_input_file
299 ******************************************************************************/
300 static Bool
301 parse_input_file
302 (
303 FILE* fp
304 )
305 {
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;
345 }
347 /******************************************************************************
348 * Function: find_file_length
349 ******************************************************************************/
350 static Bool
351 find_file_length
352 (
353 FILE* fp
354 )
355 {
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;
400 }
402 /******************************************************************************
403 * Function: main
404 ******************************************************************************/
405 void main ()
406 {
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 init_flags.phy = 0;
437 if (platform_init(&init_flags, &init_config) != Platform_EOK)
438 {
439 printf ("Platform init failed!\n");
440 print_platform_errno();
441 return;
442 }
443 #if !(defined(_EVMC6657L_))
445 #if (defined(DEVICE_K2G) || defined(SOC_K2G))
446 p_device = platform_device_open(PLATFORM_DEVID_NORN25Q128A13ESF40F, 0);
447 #else
448 p_device = platform_device_open(PLATFORM_DEVID_NORN25Q128, 0);
449 #endif
451 #else
452 p_device = platform_device_open(PLATFORM_DEVID_NORN25Q032A, 0);
453 #endif
454 if (p_device == NULL)
455 {
456 printf ("NOR device open failed!\n");
457 print_platform_errno();
458 return;
459 }
460 norWriterInfo.deviceTotalBytes = p_device->block_count * p_device->page_count * p_device->page_size;
461 norWriterInfo.blockSizeBytes = p_device->page_count * p_device->page_size;
463 if ((norWriterInfo.startAddr % norWriterInfo.blockSizeBytes) != 0)
464 {
465 printf ("The start programming address 0x%8x set in %s is not at the beginning of a block, block size = 0x%4x\n",
466 norWriterInfo.startAddr,
467 norWriterInfo.file_name,
468 norWriterInfo.blockSizeBytes);
469 return;
470 }
472 /* Open and find the length of the data file */
473 fp = fopen (norWriterInfo.file_name, "rb");
474 if (fp == NULL)
475 {
476 printf ("Failed to open file %s\n", norWriterInfo.file_name);
477 platform_device_close(p_device->handle);
478 return;
479 }
481 /* Parse the CCS format file */
482 ret = find_file_length(fp);
483 fclose (fp);
485 norWriterInfo.writeBytes += norWriterInfo.blockSizeBytes - 1;
486 norWriterInfo.writeBytes -= norWriterInfo.writeBytes % norWriterInfo.blockSizeBytes;
488 if (ret == FALSE)
489 {
490 printf("Error in parsing CCS file %s\n", norWriterInfo.file_name);
491 platform_device_close(p_device->handle);
492 return;
493 }
495 /* Write the flash */
496 if (flash_nor (p_device) == FALSE)
497 {
498 printf ("NOR write failed\n");
499 platform_device_close(p_device->handle);
500 return;
501 }
503 /* verify the flash */
504 if(flash_verify (p_device) == FALSE)
505 {
506 printf ("NOR read verify failed\n");
507 platform_device_close(p_device->handle);
508 return;
509 }
512 printf ("NOR programming completed successfully\n");
514 platform_device_close(p_device->handle);
516 return;
517 }