GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / arch / mips / board / bcm96345 / src / dev_bcm6345_flash.c
blob6e050b078a5ad87d7f9a31937d5c504a05ee3822
1 /***************************************************************************
2 * Broadcom Corp. Confidential
3 * Copyright 2001 Broadcom Corp. All Rights Reserved.
5 * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED
6 * SOFTWARE LICENSE AGREEMENT BETWEEN THE USER AND BROADCOM.
7 * YOU HAVE NO RIGHT TO USE OR EXPLOIT THIS MATERIAL EXCEPT
8 * SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
10 ***************************************************************************
11 * File Name : bcm6345_flash.c
13 * Description: This file contains the flash device driver for bcm6345 board. Very similar to
14 * board.c in linux development.
16 * Created on : 4/18/2002 seanl: use cfiflash.c, cfliflash.h (AMD specific)
18 ***************************************************************************/
21 /* Includes. */
22 #include "lib_types.h"
23 #include "lib_malloc.h"
24 #include "lib_string.h"
25 #include "lib_printf.h"
27 // use the smae include as linux development: linux/inlcude/asm-mip/bcm6345
28 #include "6345_map.h"
29 #include "board.h"
30 #include "dev_bcm63xx_flash.h"
31 #include "cfiflash.h"
33 //#define DEBUG_FLASH
35 extern void dumpHex(unsigned char*, int);
36 extern NVRAM_DATA nvramData;
37 extern int readNvramData(void);
39 /* This driver determines the NVRAM and persistent storage flash address and
40 * length.
43 static FLASH_ADDR_INFO fInfo;
45 //**************************************************************************************
46 // Flash read/write and image downloading..
47 //**************************************************************************************
49 void kerSysFlashInit( void )
51 int i = 0;
52 int totalBlks = 0;
53 int totalSize = 0;
54 int startAddr = 0;
55 int usedBlkSize = 0;
57 flash_init();
59 totalBlks = flash_get_numsectors();
60 totalSize = flash_get_total_size();
62 #if defined(DEBUG_FLASH)
63 printf("totalBlks=%d\n", totalBlks);
64 printf("totalSize=%dK\n", totalSize/1024);
65 #endif
67 /* nvram is always at the end of flash */
68 fInfo.flash_nvram_length = NVRAM_LENGTH;
69 startAddr = totalSize - NVRAM_LENGTH;
70 fInfo.flash_nvram_start_blk = flash_get_blk(startAddr+FLASH_BASE_ADDR_REG);
71 fInfo.flash_nvram_number_blk = totalBlks - fInfo.flash_nvram_start_blk;
73 // find out the offset in the start_blk
74 for (i = fInfo.flash_nvram_start_blk;
75 i < (fInfo.flash_nvram_start_blk + fInfo.flash_nvram_number_blk); i++)
76 usedBlkSize += flash_get_sector_size((byte) i);
78 #if defined(DEBUG_FLASH)
79 printf("i=%d, usedBlkSize=%d\n", i, usedBlkSize);
80 #endif
82 fInfo.flash_nvram_blk_offset = usedBlkSize - NVRAM_LENGTH;
84 if (readNvramData() != 0)
86 printf("Board is not initialized: Using the default PSI size: %d\n", NVRAM_PSI_DEFAULT_6345);
87 fInfo.flash_persistent_length = NVRAM_PSI_DEFAULT_6345;
89 else
90 fInfo.flash_persistent_length = nvramData.ulPsiSize;
92 /* PSI is right below NVRAM */
93 fInfo.flash_persistent_length *= ONEK;
94 startAddr -= fInfo.flash_persistent_length; // PSI start address
95 fInfo.flash_persistent_start_blk = flash_get_blk(startAddr+FLASH_BASE_ADDR_REG);
96 if (fInfo.flash_nvram_start_blk == fInfo.flash_persistent_start_blk) // share blk
98 fInfo.flash_persistent_number_blk = 1;
99 fInfo.flash_persistent_blk_offset = fInfo.flash_nvram_blk_offset - fInfo.flash_persistent_length;
101 else // on different blk
103 fInfo.flash_persistent_number_blk = totalBlks - fInfo.flash_persistent_start_blk;
104 // find out the offset in the start_blk
105 usedBlkSize = 0;
106 for (i = fInfo.flash_persistent_start_blk;
107 i < (fInfo.flash_persistent_start_blk + fInfo.flash_persistent_number_blk); i++)
108 usedBlkSize += flash_get_sector_size((byte) i);
110 fInfo.flash_persistent_blk_offset = usedBlkSize - fInfo.flash_persistent_length - fInfo.flash_nvram_length;
113 #if defined(DEBUG_FLASH)
114 printf("fInfo.flash_nvram_start_blk = %d\n", fInfo.flash_nvram_start_blk);
115 printf("fInfo.flash_nvram_blk_offset = 0x%x\n", fInfo.flash_nvram_blk_offset);
116 printf("fInfo.flash_nvram_number_blk = %d\n", fInfo.flash_nvram_number_blk);
118 printf("psi startAddr = %x\n", startAddr+FLASH_BASE_ADDR_REG);
119 printf("fInfo.flash_persistent_start_blk = %d\n", fInfo.flash_persistent_start_blk);
120 printf("fInfo.flash_persistent_blk_offset = 0x%x\n", fInfo.flash_persistent_blk_offset);
121 printf("fInfo.flash_persistent_number_blk = %d\n", fInfo.flash_persistent_number_blk);
122 #endif
126 /***********************************************************************
127 * Function Name: kerSysFlashAddrInfoGet
128 * Description : Fills in a structure with information about the NVRAM
129 * and persistent storage sections of flash memory.
130 * Returns : None.
131 ***********************************************************************/
132 void kerSysFlashAddrInfoGet(PFLASH_ADDR_INFO pflash_addr_info)
134 pflash_addr_info->flash_nvram_blk_offset = fInfo.flash_nvram_blk_offset;
135 pflash_addr_info->flash_nvram_length = fInfo.flash_nvram_length;
136 pflash_addr_info->flash_nvram_number_blk = fInfo.flash_nvram_number_blk;
137 pflash_addr_info->flash_nvram_start_blk = fInfo.flash_nvram_start_blk;
138 pflash_addr_info->flash_persistent_blk_offset = fInfo.flash_persistent_blk_offset;
139 pflash_addr_info->flash_persistent_length = fInfo.flash_persistent_length;
140 pflash_addr_info->flash_persistent_number_blk = fInfo.flash_persistent_number_blk;
141 pflash_addr_info->flash_persistent_start_blk = fInfo.flash_persistent_start_blk;
145 // get shared blks into *** pTempBuf *** which has to be released bye the caller!
146 // return: if pTempBuf != NULL, poits to the data with the dataSize of the buffer
147 // !NULL -- ok
148 // NULL -- fail
149 static char *getSharedBlks(int start_blk, int end_blk)
151 int i = 0;
152 int usedBlkSize = 0;
153 int sect_size = 0;
154 char *pTempBuf = NULL;
155 char *pBuf = NULL;
157 for (i = start_blk; i < end_blk; i++)
158 usedBlkSize += flash_get_sector_size((byte) i);
160 if ((pTempBuf = (char *) KMALLOC(usedBlkSize, sizeof(long))) == NULL)
162 printf("failed to allocate memory with size: %d\n", usedBlkSize);
163 return pTempBuf;
166 pBuf = pTempBuf;
167 for (i = start_blk; i < end_blk; i++)
169 sect_size = flash_get_sector_size((byte) i);
170 #if defined(DEBUG_FLASH)
171 printf("getShareBlks: i=%d, sect_size=%d, end_blk=%d\n", i, sect_size, end_blk);
172 #endif
173 flash_read_buf((byte)i, 0, pBuf, sect_size);
174 pBuf += sect_size;
177 return pTempBuf;
182 // Set the pTempBuf to flash from start_blk to end_blk
183 // return:
184 // 0 -- ok
185 // -1 -- fail
186 static int setSharedBlks(int start_blk, int end_blk, char *pTempBuf)
188 int i = 0;
189 int sect_size = 0;
190 int sts = 0;
191 char *pBuf = pTempBuf;
193 for (i = start_blk; i < end_blk; i++)
195 sect_size = flash_get_sector_size((byte) i);
196 flash_sector_erase_int(i);
197 flash_ub(0);
198 if (flash_write_buf_ub(i, 0, pBuf, sect_size) != sect_size)
200 printf("Error writing flash sector %d.", i);
201 sts = -1;
202 break;
204 pBuf += sect_size;
205 flash_reset_ub();
208 return sts;
213 /*******************************************************************************
214 * NVRAM functions
215 *******************************************************************************/
217 // get nvram data
218 // return:
219 // 0 - ok
220 // -1 - fail
221 int kerSysNvRamGet(char *string, int strLen, int offset)
223 char *pBuf = NULL;
225 if (strLen > NVRAM_LENGTH)
226 return -1;
228 if ((pBuf = getSharedBlks(fInfo.flash_nvram_start_blk,
229 (fInfo.flash_nvram_start_blk + fInfo.flash_nvram_number_blk))) == NULL)
230 return -1;
232 // get string off the memory buffer
233 memcpy(string, (pBuf + fInfo.flash_nvram_blk_offset + offset), strLen);
235 KFREE(pBuf);
237 return 0;
241 // set nvram
242 // return:
243 // 0 - ok
244 // -1 - fail
245 int kerSysNvRamSet(char *string, int strLen, int offset)
247 int sts = 0;
248 char *pBuf = NULL;
250 if (strLen > NVRAM_LENGTH)
251 return -1;
253 if ((pBuf = getSharedBlks(fInfo.flash_nvram_start_blk,
254 (fInfo.flash_nvram_start_blk + fInfo.flash_nvram_number_blk))) == NULL)
255 return -1;
257 // set string to the memory buffer
258 memcpy((pBuf + fInfo.flash_nvram_blk_offset + offset), string, strLen);
260 if (setSharedBlks(fInfo.flash_nvram_start_blk,
261 (fInfo.flash_nvram_number_blk + fInfo.flash_nvram_start_blk), pBuf) != 0)
262 sts = -1;
264 KFREE(pBuf);
266 return sts;
270 /***********************************************************************
271 * Function Name: kerSysEraseNvRam
272 * Description : Erase the NVRAM storage section of flash memory.
273 * Returns : 1 -- ok, 0 -- fail
274 ***********************************************************************/
275 int kerSysEraseNvRam(void)
277 int sts = 1;
278 int memType = MEMORY_8MB_1_CHIP;
279 char *tempStorage = KMALLOC(NVRAM_LENGTH, sizeof(long));
281 // just write the whole buf with '0xff' to the flash
282 if (!tempStorage)
283 sts = 0;
284 else
286 memset(tempStorage, 0xff, NVRAM_LENGTH);
287 if (kerSysNvRamSet(tempStorage, NVRAM_LENGTH, 0) != 0)
288 sts = 0;
289 KFREE(tempStorage);
292 // set memory type to default
293 kerSysMemoryTypeSet((int) FLASH63XX_ADDR_BOOT_ROM, (char *)&memType, sizeof(int));
295 return sts;
299 /*******************************************************************************
300 * PSI functions
301 *******************************************************************************/
302 // get psi data
303 // return:
304 // 0 - ok
305 // -1 - fail
306 int kerSysPsiGet(char *string, int strLen, int offset)
308 char *pBuf = NULL;
310 if (strLen > fInfo.flash_persistent_length)
311 return -1;
313 if ((pBuf = getSharedBlks(fInfo.flash_persistent_start_blk,
314 (fInfo.flash_persistent_start_blk + fInfo.flash_persistent_number_blk))) == NULL)
315 return -1;
317 // get string off the memory buffer
318 memcpy(string, (pBuf + fInfo.flash_persistent_blk_offset + offset), strLen);
320 KFREE(pBuf);
322 return 0;
326 // set psi
327 // return:
328 // 0 - ok
329 // -1 - fail
330 int kerSysPsiSet(char *string, int strLen, int offset)
332 int sts = 0;
333 char *pBuf = NULL;
335 if (strLen > fInfo.flash_persistent_length)
336 return -1;
338 if ((pBuf = getSharedBlks(fInfo.flash_persistent_start_blk,
339 (fInfo.flash_persistent_start_blk + fInfo.flash_persistent_number_blk))) == NULL)
340 return -1;
342 // set string to the memory buffer
343 memcpy((pBuf + fInfo.flash_persistent_blk_offset + offset), string, strLen);
345 if (setSharedBlks(fInfo.flash_persistent_start_blk,
346 (fInfo.flash_persistent_number_blk + fInfo.flash_persistent_start_blk), pBuf) != 0)
347 sts = -1;
349 KFREE(pBuf);
351 return sts;
355 /***********************************************************************
356 * Function Name: kerSysErasePsi
357 * Description : Erase the Psi storage section of flash memory.
358 * Returns : 1 -- ok, 0 -- fail
359 ***********************************************************************/
360 int kerSysErasePsi(void)
362 int sts = 1;
363 char *tempStorage = KMALLOC(fInfo.flash_persistent_length, sizeof(long));
365 // just write the whole buf with '0xff' to the flash
366 if (!tempStorage)
367 sts = 0;
368 else
370 memset(tempStorage, 0xff, fInfo.flash_persistent_length);
371 if (kerSysPsiSet(tempStorage, fInfo.flash_persistent_length, 0) != 0)
372 sts = 0;
373 KFREE(tempStorage);
376 return sts;
379 /***********************************************************************
380 * Function Name: kerSysMemoryTypeSet
381 * Description : set the memory type 4 bytes
382 * Returns : 1 -- ok, 0 -- fail
383 ***********************************************************************/
384 int kerSysMemoryTypeSet(int flash_start_addr, char *string, int size)
386 int sect_size;
387 int blk_start;
388 char *pTempBuf;
390 blk_start = flash_get_blk(flash_start_addr);
391 sect_size = flash_get_sector_size(blk_start);
393 flash_ub(0);
394 if ((pTempBuf = (char *) KMALLOC(sect_size, sizeof(long))) == NULL)
396 printf("Failed to allocate memory with size: %d\n", sect_size);
397 return 0;
400 flash_read_buf((byte)blk_start, 0, pTempBuf, sect_size);
401 memcpy(pTempBuf+SDRAM_TYPE_ADDRESS_OFFSET, string, size);
403 flash_sector_erase_int(blk_start); // erase blk before flash
404 flash_reset();
405 flash_ub(0);
406 if (flash_write_buf_ub(blk_start, 0, pTempBuf, sect_size) != sect_size)
407 printf("Failed to flash the memory type\n");
409 flash_reset_ub();
410 flash_reset();
412 return 1;
416 /***********************************************************************
417 * Function Name: kerSysMemoryTypeGet
418 * Description : get the memory type 4 bytes
419 * Returns : memory type
420 ***********************************************************************/
421 int kerSysMemoryTypeGet(void)
423 int sdramType = BOARD_SDRAM_TYPE;
425 return sdramType;
428 // flash bcm image
429 // return:
430 // 0 - ok
431 // !0 - the sector number fail to be flashed (should not be 0)
432 int kerSysBcmImageSet( int flash_start_addr, char *string, int size, int fWholeImage)
434 int sts;
435 int sect_size;
436 int blk_start;
437 int i;
438 char *pTempBuf = NULL;
441 blk_start = flash_get_blk(flash_start_addr);
442 if( blk_start < 0 )
443 return( -1 );
445 /* write image to flash memory */
446 flash_ub(0);
450 sect_size = flash_get_sector_size(blk_start);
452 #if defined(DEBUG_FLASH)
453 printf("Image flasing on block: %d\n", blk_start);
454 #endif
456 // share the blk with nvram only when fWholeImage == 0
457 if (!fWholeImage && blk_start == fInfo.flash_persistent_start_blk)
459 if (size > (sect_size - fInfo.flash_persistent_length))
461 printf("Image is too big\n");
462 break; // image is too big. Can not overwrite to psi
464 if ((pTempBuf = (char *) KMALLOC(sect_size, sizeof(long))) == NULL)
466 printf("Failed to allocate memory with size: %d\n", sect_size);
467 break;
469 flash_read_buf((byte)blk_start, 0, pTempBuf, sect_size);
470 memcpy(pTempBuf, string, size);
471 flash_sector_erase_int(blk_start); // erase blk before flash
472 flash_ub(0);
473 if (flash_write_buf_ub(blk_start, 0, pTempBuf, sect_size) == sect_size)
474 size = 0; // break out and say all is ok
475 break;
478 flash_sector_erase_int(blk_start); // erase blk before flash
479 flash_ub(0);
481 if (sect_size > size)
483 if (size & 1)
484 size++;
485 sect_size = size;
487 if ((i = flash_write_buf_ub(blk_start, 0, string, sect_size)) != sect_size)
488 break;
489 printf(".");
490 blk_start++;
491 string += sect_size;
492 size -= sect_size;
493 flash_reset_ub();
494 } while (size > 0);
496 flash_reset_ub();
497 flash_reset();
499 if( size == 0 )
500 sts = 0; // ok
501 else
502 sts = blk_start; // failed to flash this sector
504 return sts;