GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / arch / mips / board / bcm9635x / src / dev_bcm635x_flash.c
blobae2426e58a475dd5595bd759eac025b9b7a3f69f
1 /*
2 <:copyright-gpl
4 Copyright 2002 Broadcom Corp. All Rights Reserved.
6 This program is free software; you can distribute it and/or modify it
7 under the terms of the GNU General Public License (Version 2) as
8 published by the Free Software Foundation.
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
21 /***************************************************************************
22 * File Name : dev_bcm6352_flash.c
24 * Description: This file contains flash entry point functions.
26 * Created on : 05/20/2002 lat. Lifted from BCM96352 board.c.
28 ***************************************************************************/
31 /* Includes. */
32 #include "lib_types.h"
33 #include "lib_malloc.h"
34 #include "lib_string.h"
35 #include "lib_printf.h"
36 #include "cfe_timer.h"
38 #include "board.h"
39 #include "6352_map.h"
40 #include "dev_bcm63xx_flash.h"
41 #include "flash.h"
43 static FLASH_ADDR_INFO fInfo;
44 extern NVRAM_DATA nvramData;
45 extern int readNvramData(void);
48 /***********************************************************************
49 * Function Name: flashAddrReadBlock
50 * Description : Reads an array of bytes from flash memory.
51 * Returns : None.
52 ***********************************************************************/
53 static void flashAddrReadBlock(char *string, char *addr, int strLen, int offset)
55 int i;
57 if( (offset & 0x01) != ((unsigned long) string & 0x01) )
59 /* Source and destination addresses are on different odd/even
60 * boundaries. Do a byte copy.
62 unsigned char *dest = (unsigned char *) string;
63 unsigned char *src = (unsigned char *) (addr + offset);
65 for( i = 0; i < strLen; i++ )
66 *dest++ = *src++;
68 else
70 /* Source and destination addresses are on the same odd/even
71 * boundaries. Do a word (16 bit) copy.
73 unsigned short *dest, *src;
75 if( (offset & 0x01) == 0x01 )
77 *string++ = (char) *(addr + offset);
78 strLen--;
79 offset++;
82 dest = (unsigned short*) string;
83 src = (unsigned short*) (addr + offset);
85 for( i = 0; i < strLen / 2; i++ )
86 *dest++ = *src++;
88 if( (strLen & 0x01) == 0x01 )
89 string[strLen - 1] = *(addr + offset + strLen - 1);
92 } /* flashAddrReadBlock */
95 //**************************************************************************************
96 // Flash read/write and image downloading..
97 //**************************************************************************************
99 void kerSysFlashInit( void )
101 int i = 0;
102 int totalBlks = 0;
103 int totalSize = 0;
104 int startAddr = 0;
105 int usedBlkSize = 0;
107 flash_init();
109 totalBlks = flash_get_numsectors();
110 totalSize = flash_get_total_size();
112 #if defined(DEBUG_FLASH)
113 printf("totalBlks=%d\n", totalBlks);
114 printf("totalSize=%dK\n", totalSize/1024);
115 #endif
118 /* nvram is always at the end of flash */
119 fInfo.flash_nvram_length = NVRAM_LENGTH;
120 startAddr = totalSize - NVRAM_LENGTH;
121 fInfo.flash_nvram_start_blk = flash_get_blk(startAddr+FLASH_BASE_ADDR_REG);
122 fInfo.flash_nvram_number_blk = totalBlks - fInfo.flash_nvram_start_blk;
124 printf("nvram startaddr = 0x%x, start_blk = %d\n", startAddr, fInfo.flash_nvram_start_blk);
126 // find out the offset in the start_blk
127 for (i = fInfo.flash_nvram_start_blk;
128 i < (fInfo.flash_nvram_start_blk + fInfo.flash_nvram_number_blk); i++)
129 usedBlkSize += flash_get_sector_size((byte) i);
131 #if defined(DEBUG_FLASH)
132 printf("i=%d, usedBlkSize=%d\n", i, usedBlkSize);
133 #endif
135 fInfo.flash_nvram_blk_offset = usedBlkSize - NVRAM_LENGTH;
137 if (readNvramData() != 0)
139 printf("Board is not initialized: Using the default PSI size: %d\n", NVRAM_PSI_DEFAULT_635X);
140 fInfo.flash_persistent_length = NVRAM_PSI_DEFAULT_635X;
142 else
143 fInfo.flash_persistent_length = nvramData.ulPsiSize;
145 /* PSI is right below NVRAM */
146 fInfo.flash_persistent_length *= ONEK;
147 startAddr -= fInfo.flash_persistent_length; // PSI start address
148 fInfo.flash_persistent_start_blk = flash_get_blk(startAddr+FLASH_BASE_ADDR_REG);
149 if (fInfo.flash_nvram_start_blk == fInfo.flash_persistent_start_blk) // share blk
151 fInfo.flash_persistent_number_blk = 1;
152 fInfo.flash_persistent_blk_offset = fInfo.flash_nvram_blk_offset - fInfo.flash_persistent_length;
154 else // on different blk
156 fInfo.flash_persistent_number_blk = totalBlks - fInfo.flash_persistent_start_blk;
157 // find out the offset in the start_blk
158 usedBlkSize = 0;
159 for (i = fInfo.flash_persistent_start_blk;
160 i < (fInfo.flash_persistent_start_blk + fInfo.flash_persistent_number_blk); i++)
161 usedBlkSize += flash_get_sector_size((byte) i);
163 printf("usesize=%d\n", usedBlkSize);
165 fInfo.flash_persistent_blk_offset = usedBlkSize - fInfo.flash_persistent_length - fInfo.flash_nvram_length;
168 #if defined(DEBUG_FLASH)
169 printf("fInfo.flash_nvram_start_blk = %d\n", fInfo.flash_nvram_start_blk);
170 printf("fInfo.flash_nvram_blk_offset = 0x%x\n", fInfo.flash_nvram_blk_offset);
171 printf("fInfo.flash_nvram_number_blk = %d\n", fInfo.flash_nvram_number_blk);
173 printf("psi startAddr = %x\n", startAddr+FLASH_BASE_ADDR_REG);
174 printf("fInfo.flash_persistent_start_blk = %d\n", fInfo.flash_persistent_start_blk);
175 printf("fInfo.flash_persistent_blk_offset = 0x%x\n", fInfo.flash_persistent_blk_offset);
176 printf("fInfo.flash_persistent_number_blk = %d\n", fInfo.flash_persistent_number_blk);
177 #endif
182 /***********************************************************************
183 * Function Name: kerSysFlashAddrInfoGet
184 * Description : Fills in a structure with information about the NVRAM
185 * and persistent storage sections of flash memory.
186 * Returns : None.
187 ***********************************************************************/
188 void kerSysFlashAddrInfoGet(PFLASH_ADDR_INFO pflash_addr_info)
190 pflash_addr_info->flash_nvram_blk_offset = fInfo.flash_nvram_blk_offset;
191 pflash_addr_info->flash_nvram_length = fInfo.flash_nvram_length;
192 pflash_addr_info->flash_nvram_number_blk = fInfo.flash_nvram_number_blk;
193 pflash_addr_info->flash_nvram_start_blk = fInfo.flash_nvram_start_blk;
194 pflash_addr_info->flash_persistent_blk_offset = fInfo.flash_persistent_blk_offset;
195 pflash_addr_info->flash_persistent_length = fInfo.flash_persistent_length;
196 pflash_addr_info->flash_persistent_number_blk = fInfo.flash_persistent_number_blk;
197 pflash_addr_info->flash_persistent_start_blk = fInfo.flash_persistent_start_blk;
201 // get shared blks into *** pTempBuf *** which has to be released bye the caller!
202 // return: if pTempBuf != NULL, poits to the data with the dataSize of the buffer
203 // !NULL -- ok
204 // NULL -- fail
205 static char *getSharedBlks(int start_blk, int end_blk)
207 int i = 0;
208 int usedBlkSize = 0;
209 int sect_size = 0;
210 char *pTempBuf = NULL;
211 char *pBuf = NULL;
213 for (i = start_blk; i < end_blk; i++)
214 usedBlkSize += flash_get_sector_size((byte) i);
216 //printf("usedBlkSize = %d\n", usedBlkSize);
218 if ((pTempBuf = (char *) KMALLOC(usedBlkSize, sizeof(long))) == NULL)
220 printf("failed to allocate memory with size: %d\n", usedBlkSize);
221 return pTempBuf;
224 pBuf = pTempBuf;
225 for (i = start_blk; i < end_blk; i++)
227 sect_size = flash_get_sector_size((byte) i);
228 #if defined(DEBUG_FLASH)
229 printf("getShareBlks: i=%d, sect_size=%d, end_blk=%d\n", i, sect_size, end_blk);
230 #endif
231 flashAddrReadBlock(pBuf, (char *) flash_get_memptr(i), sect_size, 0);
232 pBuf += sect_size;
235 return pTempBuf;
240 // Set the pTempBuf to flash from start_blk to end_blk
241 // return:
242 // 0 -- ok
243 // -1 -- fail
244 static int setSharedBlks(int start_blk, int end_blk, char *pTempBuf)
246 int i = 0;
247 int sect_size = 0;
248 int sts = 0;
249 unsigned short esr;
250 unsigned char *src = (unsigned char *) pTempBuf;
251 unsigned char *dest = flash_get_memptr(start_blk);
253 for (i = start_blk; i < end_blk; i++)
255 sect_size = flash_get_sector_size((byte) i);
256 if (AddrWriteProtect((unsigned short *) dest, UNLOCK) != 0)
258 printf("Failed on unlock\n");
259 sts = -1;
260 break;
262 if (EraseFlashBlock(i) != 0)
264 printf("Failed to erase flash sector: %d\n", i);
265 sts = -1;
266 break;
268 if( FlashWordWrite((unsigned short *) dest, (unsigned short *) src,
269 sect_size / sizeof(short), &esr) != 0 )
271 sts = -1;
272 break;
274 AddrWriteProtect((unsigned short *) dest, LOCK);
276 src += sect_size;
277 dest += sect_size;
278 printf(".");
281 cfe_sleep(1); /* mdelay(100); */
282 Set_Read_Array();
284 return sts;
289 /*******************************************************************************
290 * NVRAM functions
291 *******************************************************************************/
293 // get nvram data
294 // return:
295 // 0 - ok
296 // -1 - fail
297 int kerSysNvRamGet(char *string, int strLen, int offset)
299 char *pBuf = NULL;
301 if (strLen > NVRAM_LENGTH)
302 return -1;
304 if ((pBuf = getSharedBlks(fInfo.flash_nvram_start_blk,
305 (fInfo.flash_nvram_start_blk + fInfo.flash_nvram_number_blk))) == NULL)
306 return -1;
308 // get string off the memory buffer
309 memcpy(string, (pBuf + fInfo.flash_nvram_blk_offset + offset), strLen);
311 KFREE(pBuf);
313 return 0;
317 // set nvram
318 // return:
319 // 0 - ok
320 // -1 - fail
321 int kerSysNvRamSet(char *string, int strLen, int offset)
323 int sts = 0;
324 char *pBuf = NULL;
326 if (strLen > NVRAM_LENGTH)
327 return -1;
329 if ((pBuf = getSharedBlks(fInfo.flash_nvram_start_blk,
330 (fInfo.flash_nvram_start_blk + fInfo.flash_nvram_number_blk))) == NULL)
331 return -1;
333 // set string to the memory buffer
334 memcpy((pBuf + fInfo.flash_nvram_blk_offset + offset), string, strLen);
336 if (setSharedBlks(fInfo.flash_nvram_start_blk,
337 (fInfo.flash_nvram_number_blk + fInfo.flash_nvram_start_blk), pBuf) != 0)
338 sts = -1;
340 KFREE(pBuf);
342 return sts;
346 /***********************************************************************
347 * Function Name: kerSysEraseNvRam
348 * Description : Erase the NVRAM storage section of flash memory.
349 * Returns : 1 -- ok, 0 -- fail
350 ***********************************************************************/
351 int kerSysEraseNvRam(void)
353 int sts = 1;
354 char *tempStorage = KMALLOC(NVRAM_LENGTH, sizeof(long));
356 // just write the whole buf with '0xff' to the flash
357 if (!tempStorage)
358 sts = 0;
359 else
361 memset(tempStorage, 0xff, NVRAM_LENGTH);
362 if (kerSysNvRamSet(tempStorage, NVRAM_LENGTH, 0) != 0)
363 sts = 0;
364 KFREE(tempStorage);
367 return sts;
371 /*******************************************************************************
372 * PSI functions
373 *******************************************************************************/
374 // get psi data
375 // return:
376 // 0 - ok
377 // -1 - fail
378 int kerSysPsiGet(char *string, int strLen, int offset)
380 char *pBuf = NULL;
382 if (strLen > fInfo.flash_persistent_length)
383 return -1;
385 if ((pBuf = getSharedBlks(fInfo.flash_persistent_start_blk,
386 (fInfo.flash_persistent_start_blk + fInfo.flash_persistent_number_blk))) == NULL)
387 return -1;
389 // get string off the memory buffer
390 memcpy(string, (pBuf + fInfo.flash_persistent_blk_offset + offset), strLen);
392 KFREE(pBuf);
394 return 0;
398 // set psi
399 // return:
400 // 0 - ok
401 // -1 - fail
402 int kerSysPsiSet(char *string, int strLen, int offset)
404 int sts = 0;
405 char *pBuf = NULL;
407 if (strLen > fInfo.flash_persistent_length)
408 return -1;
410 if ((pBuf = getSharedBlks(fInfo.flash_persistent_start_blk,
411 (fInfo.flash_persistent_start_blk + fInfo.flash_persistent_number_blk))) == NULL)
412 return -1;
414 // set string to the memory buffer
415 memcpy((pBuf + fInfo.flash_persistent_blk_offset + offset), string, strLen);
417 if (setSharedBlks(fInfo.flash_persistent_start_blk,
418 (fInfo.flash_persistent_number_blk + fInfo.flash_persistent_start_blk), pBuf) != 0)
419 sts = -1;
421 KFREE(pBuf);
423 return sts;
427 /***********************************************************************
428 * Function Name: kerSysErasePsi
429 * Description : Erase the Psi storage section of flash memory.
430 * Returns : 1 -- ok, 0 -- fail
431 ***********************************************************************/
432 int kerSysErasePsi(void)
434 int sts = 1;
435 char *tempStorage = KMALLOC(fInfo.flash_persistent_length, sizeof(long));
437 // just write the whole buf with '0xff' to the flash
438 if (!tempStorage)
439 sts = 0;
440 else
442 memset(tempStorage, 0xff, fInfo.flash_persistent_length);
443 if (kerSysPsiSet(tempStorage, fInfo.flash_persistent_length, 0) != 0)
444 sts = 0;
445 KFREE(tempStorage);
448 return sts;
452 /***********************************************************************
453 * Function Name: kerSysMemoryTypeSet
454 * Description : set the memory type 4 bytes
455 * Returns : 1 -- ok, 0 -- fail
456 ***********************************************************************/
457 int kerSysMemoryTypeSet(int flash_address, char *string, int size)
459 int sect_size;
460 int blk_start;
461 char *pTempBuf;
462 unsigned short esr;
464 blk_start = flash_get_blk(flash_address);
465 sect_size = flash_get_sector_size(blk_start);
467 if ((pTempBuf = (char *) KMALLOC(sect_size, sizeof(long))) == NULL)
469 printf("Failed to allocate memory with size: %d\n", sect_size);
470 return 0;
473 flashAddrReadBlock(pTempBuf, (char *) flash_address, sect_size, 0);
474 memcpy(pTempBuf+SDRAM_TYPE_ADDRESS_OFFSET, string, size);
476 if (EraseFlashBlock(blk_start) != 0)
478 printf("Failed to erase flash sector: %d\n", blk_start);
479 return 0;
482 if(FlashWordWrite((unsigned short *)flash_address,(unsigned short *)pTempBuf,sect_size/sizeof(short), &esr) != 0) // failed
484 printf("Failed to flash the memory type\n");
485 return 0;
488 cfe_sleep(1);
489 Set_Read_Array();
491 return 1;
495 /***********************************************************************
496 * Function Name: kerSysMemoryTypeGet
497 * Description : get the memory type 4 bytes
498 * Returns : memory type
499 ***********************************************************************/
500 int kerSysMemoryTypeGet(void)
502 int sdramType = BOARD_SDRAM_TYPE;
504 return sdramType;
508 // flash bcm image
509 // return:
510 // 0 - ok
511 // !0 - the sector number fail to be flashed (should not be 0)
512 int kerSysBcmImageSet( int flash_start_addr, char *string, int size, int fWholeImage)
514 int sts = -1;
515 int sect_size;
516 int blk_start;
517 char *pTempBuf = NULL;
518 unsigned char *flash_address = NULL;
519 unsigned short esr;
521 //printf("flash_start_addr = 0x%x\n", flash_start_addr);
523 blk_start = flash_get_blk(flash_start_addr);
524 if( blk_start < 0 )
525 return sts;
527 /* write image to flash memory */
530 sect_size = flash_get_sector_size(blk_start);
531 flash_address = flash_get_memptr(blk_start);
533 #if defined(DEBUG_FLASH)
534 printf("Image flasing on block: %d\n", blk_start);
535 #endif
537 // share the blk with nvram only when fWholeImage == 0
538 if (!fWholeImage && blk_start == fInfo.flash_nvram_start_blk)
540 if (size > (sect_size - NVRAM_LENGTH))
542 printf("Image is too big\n");
543 return sts; // image is too big. Can not overwrite to nvram
545 if ((pTempBuf = (char *) KMALLOC(sect_size, sizeof(long))) == NULL)
547 printf("Failed to allocate memory with size: %d\n", sect_size);
548 return sts;
550 flashAddrReadBlock(pTempBuf, (char *) flash_address, sect_size, 0);
551 memcpy(pTempBuf, string, size);
553 if (AddrWriteProtect((unsigned short *) flash_address, UNLOCK) != 0)
555 printf("Failed on unlock\n");
556 return sts;
558 if (EraseFlashBlock(blk_start) != 0)
560 printf("Failed to erase flash sector: %d\n", blk_start);
561 return sts;
563 if( FlashWordWrite((unsigned short *)flash_address, (unsigned short *) pTempBuf,
564 sect_size / sizeof(short), &esr) == 0 ) // write ok
565 size = 0;
566 AddrWriteProtect((unsigned short *)flash_address, LOCK);
567 // break out and say all is ok
568 break;
571 if (sect_size > size)
573 if (size & 1)
574 size++;
575 sect_size = size;
578 EraseFlashBlock(blk_start);
579 if( FlashWordWrite((unsigned short *)flash_address, (unsigned short *) string,
580 sect_size / sizeof(short), &esr) != 0 )
581 break;
582 printf(".");
583 blk_start++;
584 string += sect_size;
585 size -= sect_size;
586 } while (size > 0);
588 cfe_sleep(1);
589 Set_Read_Array();
591 if( size == 0 )
592 sts = 0; // ok
593 else
594 sts = blk_start; // failed to flash this sector
596 return sts;