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 ***************************************************************************/
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
30 #include "dev_bcm63xx_flash.h"
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
43 static FLASH_ADDR_INFO fInfo
;
45 //**************************************************************************************
46 // Flash read/write and image downloading..
47 //**************************************************************************************
49 void kerSysFlashInit( void )
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);
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
);
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
;
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
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
);
126 /***********************************************************************
127 * Function Name: kerSysFlashAddrInfoGet
128 * Description : Fills in a structure with information about the NVRAM
129 * and persistent storage sections of flash memory.
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
149 static char *getSharedBlks(int start_blk
, int end_blk
)
154 char *pTempBuf
= 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
);
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
);
173 flash_read_buf((byte
)i
, 0, pBuf
, sect_size
);
182 // Set the pTempBuf to flash from start_blk to end_blk
186 static int setSharedBlks(int start_blk
, int end_blk
, char *pTempBuf
)
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
);
198 if (flash_write_buf_ub(i
, 0, pBuf
, sect_size
) != sect_size
)
200 printf("Error writing flash sector %d.", i
);
213 /*******************************************************************************
215 *******************************************************************************/
221 int kerSysNvRamGet(char *string
, int strLen
, int offset
)
225 if (strLen
> NVRAM_LENGTH
)
228 if ((pBuf
= getSharedBlks(fInfo
.flash_nvram_start_blk
,
229 (fInfo
.flash_nvram_start_blk
+ fInfo
.flash_nvram_number_blk
))) == NULL
)
232 // get string off the memory buffer
233 memcpy(string
, (pBuf
+ fInfo
.flash_nvram_blk_offset
+ offset
), strLen
);
245 int kerSysNvRamSet(char *string
, int strLen
, int offset
)
250 if (strLen
> NVRAM_LENGTH
)
253 if ((pBuf
= getSharedBlks(fInfo
.flash_nvram_start_blk
,
254 (fInfo
.flash_nvram_start_blk
+ fInfo
.flash_nvram_number_blk
))) == NULL
)
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)
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)
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
286 memset(tempStorage
, 0xff, NVRAM_LENGTH
);
287 if (kerSysNvRamSet(tempStorage
, NVRAM_LENGTH
, 0) != 0)
292 // set memory type to default
293 kerSysMemoryTypeSet((int) FLASH63XX_ADDR_BOOT_ROM
, (char *)&memType
, sizeof(int));
299 /*******************************************************************************
301 *******************************************************************************/
306 int kerSysPsiGet(char *string
, int strLen
, int offset
)
310 if (strLen
> fInfo
.flash_persistent_length
)
313 if ((pBuf
= getSharedBlks(fInfo
.flash_persistent_start_blk
,
314 (fInfo
.flash_persistent_start_blk
+ fInfo
.flash_persistent_number_blk
))) == NULL
)
317 // get string off the memory buffer
318 memcpy(string
, (pBuf
+ fInfo
.flash_persistent_blk_offset
+ offset
), strLen
);
330 int kerSysPsiSet(char *string
, int strLen
, int offset
)
335 if (strLen
> fInfo
.flash_persistent_length
)
338 if ((pBuf
= getSharedBlks(fInfo
.flash_persistent_start_blk
,
339 (fInfo
.flash_persistent_start_blk
+ fInfo
.flash_persistent_number_blk
))) == NULL
)
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)
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)
363 char *tempStorage
= KMALLOC(fInfo
.flash_persistent_length
, sizeof(long));
365 // just write the whole buf with '0xff' to the flash
370 memset(tempStorage
, 0xff, fInfo
.flash_persistent_length
);
371 if (kerSysPsiSet(tempStorage
, fInfo
.flash_persistent_length
, 0) != 0)
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
)
390 blk_start
= flash_get_blk(flash_start_addr
);
391 sect_size
= flash_get_sector_size(blk_start
);
394 if ((pTempBuf
= (char *) KMALLOC(sect_size
, sizeof(long))) == NULL
)
396 printf("Failed to allocate memory with size: %d\n", sect_size
);
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
406 if (flash_write_buf_ub(blk_start
, 0, pTempBuf
, sect_size
) != sect_size
)
407 printf("Failed to flash the memory type\n");
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
;
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
)
438 char *pTempBuf
= NULL
;
441 blk_start
= flash_get_blk(flash_start_addr
);
445 /* write image to flash memory */
450 sect_size
= flash_get_sector_size(blk_start
);
452 #if defined(DEBUG_FLASH)
453 printf("Image flasing on block: %d\n", blk_start
);
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
);
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
473 if (flash_write_buf_ub(blk_start
, 0, pTempBuf
, sect_size
) == sect_size
)
474 size
= 0; // break out and say all is ok
478 flash_sector_erase_int(blk_start
); // erase blk before flash
481 if (sect_size
> size
)
487 if ((i
= flash_write_buf_ub(blk_start
, 0, string
, sect_size
)) != sect_size
)
502 sts
= blk_start
; // failed to flash this sector