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
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 ***************************************************************************/
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"
40 #include "dev_bcm63xx_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.
52 ***********************************************************************/
53 static void flashAddrReadBlock(char *string
, char *addr
, int strLen
, int offset
)
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
++ )
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
);
82 dest
= (unsigned short*) string
;
83 src
= (unsigned short*) (addr
+ offset
);
85 for( i
= 0; i
< strLen
/ 2; i
++ )
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 )
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);
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
);
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
;
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
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
);
182 /***********************************************************************
183 * Function Name: kerSysFlashAddrInfoGet
184 * Description : Fills in a structure with information about the NVRAM
185 * and persistent storage sections of flash memory.
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
205 static char *getSharedBlks(int start_blk
, int end_blk
)
210 char *pTempBuf
= 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
);
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
);
231 flashAddrReadBlock(pBuf
, (char *) flash_get_memptr(i
), sect_size
, 0);
240 // Set the pTempBuf to flash from start_blk to end_blk
244 static int setSharedBlks(int start_blk
, int end_blk
, char *pTempBuf
)
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");
262 if (EraseFlashBlock(i
) != 0)
264 printf("Failed to erase flash sector: %d\n", i
);
268 if( FlashWordWrite((unsigned short *) dest
, (unsigned short *) src
,
269 sect_size
/ sizeof(short), &esr
) != 0 )
274 AddrWriteProtect((unsigned short *) dest
, LOCK
);
281 cfe_sleep(1); /* mdelay(100); */
289 /*******************************************************************************
291 *******************************************************************************/
297 int kerSysNvRamGet(char *string
, int strLen
, int offset
)
301 if (strLen
> NVRAM_LENGTH
)
304 if ((pBuf
= getSharedBlks(fInfo
.flash_nvram_start_blk
,
305 (fInfo
.flash_nvram_start_blk
+ fInfo
.flash_nvram_number_blk
))) == NULL
)
308 // get string off the memory buffer
309 memcpy(string
, (pBuf
+ fInfo
.flash_nvram_blk_offset
+ offset
), strLen
);
321 int kerSysNvRamSet(char *string
, int strLen
, int offset
)
326 if (strLen
> NVRAM_LENGTH
)
329 if ((pBuf
= getSharedBlks(fInfo
.flash_nvram_start_blk
,
330 (fInfo
.flash_nvram_start_blk
+ fInfo
.flash_nvram_number_blk
))) == NULL
)
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)
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)
354 char *tempStorage
= KMALLOC(NVRAM_LENGTH
, sizeof(long));
356 // just write the whole buf with '0xff' to the flash
361 memset(tempStorage
, 0xff, NVRAM_LENGTH
);
362 if (kerSysNvRamSet(tempStorage
, NVRAM_LENGTH
, 0) != 0)
371 /*******************************************************************************
373 *******************************************************************************/
378 int kerSysPsiGet(char *string
, int strLen
, int offset
)
382 if (strLen
> fInfo
.flash_persistent_length
)
385 if ((pBuf
= getSharedBlks(fInfo
.flash_persistent_start_blk
,
386 (fInfo
.flash_persistent_start_blk
+ fInfo
.flash_persistent_number_blk
))) == NULL
)
389 // get string off the memory buffer
390 memcpy(string
, (pBuf
+ fInfo
.flash_persistent_blk_offset
+ offset
), strLen
);
402 int kerSysPsiSet(char *string
, int strLen
, int offset
)
407 if (strLen
> fInfo
.flash_persistent_length
)
410 if ((pBuf
= getSharedBlks(fInfo
.flash_persistent_start_blk
,
411 (fInfo
.flash_persistent_start_blk
+ fInfo
.flash_persistent_number_blk
))) == NULL
)
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)
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)
435 char *tempStorage
= KMALLOC(fInfo
.flash_persistent_length
, sizeof(long));
437 // just write the whole buf with '0xff' to the flash
442 memset(tempStorage
, 0xff, fInfo
.flash_persistent_length
);
443 if (kerSysPsiSet(tempStorage
, fInfo
.flash_persistent_length
, 0) != 0)
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
)
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
);
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
);
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");
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
;
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
)
517 char *pTempBuf
= NULL
;
518 unsigned char *flash_address
= NULL
;
521 //printf("flash_start_addr = 0x%x\n", flash_start_addr);
523 blk_start
= flash_get_blk(flash_start_addr
);
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
);
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
);
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");
558 if (EraseFlashBlock(blk_start
) != 0)
560 printf("Failed to erase flash sector: %d\n", blk_start
);
563 if( FlashWordWrite((unsigned short *)flash_address
, (unsigned short *) pTempBuf
,
564 sect_size
/ sizeof(short), &esr
) == 0 ) // write ok
566 AddrWriteProtect((unsigned short *)flash_address
, LOCK
);
567 // break out and say all is ok
571 if (sect_size
> size
)
578 EraseFlashBlock(blk_start
);
579 if( FlashWordWrite((unsigned short *)flash_address
, (unsigned short *) string
,
580 sect_size
/ sizeof(short), &esr
) != 0 )
594 sts
= blk_start
; // failed to flash this sector