3 Copyright 2002 Broadcom Corp. All Rights Reserved.
5 This program is free software; you can distribute it and/or modify it
6 under the terms of the GNU General Public License (Version 2) as
7 published by the Free Software Foundation.
9 This program is distributed in the hope it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
20 ***************************************************************************
21 * File Name : bcm63xx_flash.c
23 * Description: This file contains the flash device driver APIs for bcm63xx board.
25 * Created on : 8/10/2002 seanl: use cfiflash.c, cfliflash.h (AMD specific)
27 ***************************************************************************/
32 #include <linux/capability.h>
33 #include <linux/slab.h>
34 #include <linux/errno.h>
35 #include <linux/module.h>
36 #include <linux/interrupt.h>
37 #include <asm/uaccess.h>
39 #include <bcm_map_part.h>
41 #define BCMTAG_EXE_USE
43 #include "flash_api.h"
44 #include "boardparms.h"
48 extern PFILE_TAG kerSysImageTagGet(void);
50 static FLASH_ADDR_INFO fInfo;
51 static int flashInitialized = 0;
53 void *retriedKmalloc(size_t size)
57 int allocType = GFP_KERNEL;
61 allocType = GFP_ATOMIC;
65 // try 1000 times before quit
66 while (((pBuf = kmalloc(size, allocType)) == NULL) && (++tryCount < 1000))
68 current->state = TASK_INTERRUPTIBLE;
69 schedule_timeout(HZ/10);
74 memset(pBuf, 0, size);
79 void retriedKfree(void *pBuf)
84 /***************************************************************************
85 // Function Name: getCrc32
86 // Description : caculate the CRC 32 of the given data.
87 // Parameters : pdata - array of data.
88 // size - number of input data bytes.
89 // crc - either CRC32_INIT_VALUE or previous return value.
91 ****************************************************************************/
92 UINT32 getCrc32(byte *pdata, UINT32 size, UINT32 crc)
95 crc = (crc >> 8) ^ Crc32_table[(crc ^ *pdata++) & 0xff];
100 // get the nvram start addr
102 unsigned long get_nvram_start_addr(void)
104 return ((unsigned long)
105 (flash_get_memptr(fInfo.flash_nvram_start_blk) + fInfo.flash_nvram_blk_offset));
108 // get the scratch_pad start addr
110 unsigned long get_scratch_pad_start_addr(void)
112 return ((unsigned long)
113 (flash_get_memptr(fInfo.flash_scratch_pad_start_blk) + fInfo.flash_scratch_pad_blk_offset));
116 // Initialize the flash and fill out the fInfo structure
117 void kerSysFlashInit( void )
124 NVRAM_DATA nvramData;
125 UINT32 crc = CRC32_INIT_VALUE, savedCrc;
126 PFILE_TAG pTag = NULL;
127 unsigned long kernelEndAddr = 0;
128 unsigned long spAddr = 0;
130 if (flashInitialized)
133 flashInitialized = 1;
136 totalBlks = flash_get_numsectors();
137 totalSize = flash_get_total_size();
139 printk("Total Flash size: %dK with %d sectors\n", totalSize/1024, totalBlks);
141 /* nvram is always at the end of flash */
142 fInfo.flash_nvram_length = NVRAM_LENGTH;
143 fInfo.flash_nvram_start_blk = 0; /* always the first block */
144 fInfo.flash_nvram_number_blk = 1; /*always fits in the first block */
145 fInfo.flash_nvram_blk_offset = NVRAM_DATA_OFFSET;
148 memcpy((char *)&nvramData, (char *)get_nvram_start_addr(), sizeof(NVRAM_DATA));
149 savedCrc = nvramData.ulCheckSum;
150 nvramData.ulCheckSum = 0;
151 crc = getCrc32((char *)&nvramData, (UINT32) sizeof(NVRAM_DATA), crc);
153 BpSetBoardId( nvramData.szBoardId );
155 fInfo.flash_persistent_length = NVRAM_PSI_DEFAULT;
158 printk("***Board is not initialized****: Using the default PSI size: %d\n",
159 fInfo.flash_persistent_length);
163 unsigned long ulPsiSize;
164 if( BpGetPsiSize( &ulPsiSize ) == BP_SUCCESS )
165 fInfo.flash_persistent_length = ulPsiSize;
168 printk("***Board id is not set****: Using the default PSI size: %d\n",
169 fInfo.flash_persistent_length);
173 fInfo.flash_persistent_length *= ONEK;
174 startAddr = totalSize - fInfo.flash_persistent_length;
175 fInfo.flash_persistent_start_blk = flash_get_blk(startAddr+FLASH_BASE);
176 fInfo.flash_persistent_number_blk = totalBlks - fInfo.flash_persistent_start_blk;
177 // save abs SP address (Scratch Pad). it is before PSI
178 spAddr = startAddr - SP_MAX_LEN ;
179 // find out the offset in the start_blk
181 for (i = fInfo.flash_persistent_start_blk;
182 i < (fInfo.flash_persistent_start_blk + fInfo.flash_persistent_number_blk); i++)
184 usedBlkSize += flash_get_sector_size((unsigned short) i);
186 fInfo.flash_persistent_blk_offset = usedBlkSize - fInfo.flash_persistent_length;
188 // get the info for sp
189 if (!(pTag = kerSysImageTagGet()))
191 printk("Failed to read image tag from flash\n");
194 kernelEndAddr = (unsigned long)simple_strtoul(pTag->kernelAddress,NULL,10)+ \
195 (unsigned long) simple_strtoul(pTag->kernelLen, NULL, 10) + BOOT_OFFSET;
197 // make suer sp does not share kernel block
198 fInfo.flash_scratch_pad_start_blk = flash_get_blk(spAddr+FLASH_BASE);
199 if (fInfo.flash_scratch_pad_start_blk != flash_get_blk(kernelEndAddr))
201 fInfo.flash_scratch_pad_length = SP_MAX_LEN;
202 if (fInfo.flash_persistent_start_blk == fInfo.flash_scratch_pad_start_blk) // share blk
204 #if 0 /* do not used scratch pad unless it's in its own sector */
205 printk("Scratch pad is not used for this flash part.\n");
206 fInfo.flash_scratch_pad_length = 0; // no sp
207 #else /* allow scratch pad to share a sector with another section such as PSI */
208 fInfo.flash_scratch_pad_number_blk = 1;
209 fInfo.flash_scratch_pad_blk_offset = fInfo.flash_persistent_blk_offset - fInfo.flash_scratch_pad_length;
212 else // on different blk
214 fInfo.flash_scratch_pad_number_blk = fInfo.flash_persistent_start_blk\
215 - fInfo.flash_scratch_pad_start_blk;
216 // find out the offset in the start_blk
218 for (i = fInfo.flash_scratch_pad_start_blk;
219 i < (fInfo.flash_scratch_pad_start_blk + fInfo.flash_scratch_pad_number_blk); i++)
220 usedBlkSize += flash_get_sector_size((unsigned short) i);
221 fInfo.flash_scratch_pad_blk_offset = usedBlkSize - fInfo.flash_scratch_pad_length;
226 printk("No flash for scratch pad!\n");
227 fInfo.flash_scratch_pad_length = 0; // no sp
230 #if defined(DEBUG_FLASH)
231 printk("fInfo.flash_scratch_pad_start_blk = %d\n", fInfo.flash_scratch_pad_start_blk);
232 printk("fInfo.flash_scratch_pad_number_blk = %d\n", fInfo.flash_scratch_pad_number_blk);
233 printk("fInfo.flash_scratch_pad_length = 0x%x\n", fInfo.flash_scratch_pad_length);
234 printk("fInfo.flash_scratch_pad_blk_offset = 0x%x\n", (unsigned int)fInfo.flash_scratch_pad_blk_offset);
236 printk("fInfo.flash_nvram_start_blk = %d\n", fInfo.flash_nvram_start_blk);
237 printk("fInfo.flash_nvram_blk_offset = 0x%x\n", (unsigned int)fInfo.flash_nvram_blk_offset);
238 printk("fInfo.flash_nvram_number_blk = %d\n", fInfo.flash_nvram_number_blk);
240 printk("psi startAddr = %x\n", startAddr+FLASH_BASE);
241 printk("fInfo.flash_persistent_start_blk = %d\n", fInfo.flash_persistent_start_blk);
242 printk("fInfo.flash_persistent_blk_offset = 0x%x\n", (unsigned int)fInfo.flash_persistent_blk_offset);
243 printk("fInfo.flash_persistent_number_blk = %d\n", fInfo.flash_persistent_number_blk);
250 /***********************************************************************
251 * Function Name: kerSysFlashAddrInfoGet
252 * Description : Fills in a structure with information about the NVRAM
253 * and persistent storage sections of flash memory.
254 * Fro physmap.c to mount the fs vol.
256 ***********************************************************************/
257 void kerSysFlashAddrInfoGet(PFLASH_ADDR_INFO pflash_addr_info)
259 pflash_addr_info->flash_nvram_blk_offset = fInfo.flash_nvram_blk_offset;
260 pflash_addr_info->flash_nvram_length = fInfo.flash_nvram_length;
261 pflash_addr_info->flash_nvram_number_blk = fInfo.flash_nvram_number_blk;
262 pflash_addr_info->flash_nvram_start_blk = fInfo.flash_nvram_start_blk;
263 pflash_addr_info->flash_persistent_blk_offset = fInfo.flash_persistent_blk_offset;
264 pflash_addr_info->flash_persistent_length = fInfo.flash_persistent_length;
265 pflash_addr_info->flash_persistent_number_blk = fInfo.flash_persistent_number_blk;
266 pflash_addr_info->flash_persistent_start_blk = fInfo.flash_persistent_start_blk;
270 // get shared blks into *** pTempBuf *** which has to be released bye the caller!
271 // return: if pTempBuf != NULL, poits to the data with the dataSize of the buffer
274 static char *getSharedBlks(int start_blk, int end_blk)
279 char *pTempBuf = NULL;
282 for (i = start_blk; i < end_blk; i++)
283 usedBlkSize += flash_get_sector_size((unsigned short) i);
285 #if defined(DEBUG_FLASH)
286 printk("usedBlkSize = %d\n", usedBlkSize);
289 if ((pTempBuf = (char *) retriedKmalloc(usedBlkSize)) == NULL)
291 printk("failed to allocate memory with size: %d\n", usedBlkSize);
296 for (i = start_blk; i < end_blk; i++)
298 sect_size = flash_get_sector_size((unsigned short) i);
300 #if defined(DEBUG_FLASH)
301 printk("i = %d, sect_size = %d, end_blk = %d\n", i, sect_size, end_blk);
303 flash_read_buf((unsigned short)i, 0, pBuf, sect_size);
312 // Set the pTempBuf to flash from start_blk to end_blk
316 static int setSharedBlks(int start_blk, int end_blk, char *pTempBuf)
321 char *pBuf = pTempBuf;
323 for (i = start_blk; i < end_blk; i++)
325 sect_size = flash_get_sector_size((unsigned short) i);
326 flash_sector_erase_int(i);
327 if (flash_write_buf(i, 0, pBuf, sect_size) != sect_size)
329 printk("Error writing flash sector %d.", i);
341 /*******************************************************************************
343 *******************************************************************************/
349 int kerSysNvRamGet(char *string, int strLen, int offset)
353 if (!flashInitialized)
356 if (strLen > NVRAM_LENGTH)
359 if ((pBuf = getSharedBlks(fInfo.flash_nvram_start_blk,
360 (fInfo.flash_nvram_start_blk + fInfo.flash_nvram_number_blk))) == NULL)
363 // get string off the memory buffer
364 memcpy(string, (pBuf + fInfo.flash_nvram_blk_offset + offset), strLen);
376 int kerSysNvRamSet(char *string, int strLen, int offset)
381 if (strLen > NVRAM_LENGTH)
384 if ((pBuf = getSharedBlks(fInfo.flash_nvram_start_blk,
385 (fInfo.flash_nvram_start_blk + fInfo.flash_nvram_number_blk))) == NULL)
388 // set string to the memory buffer
389 memcpy((pBuf + fInfo.flash_nvram_blk_offset + offset), string, strLen);
391 if (setSharedBlks(fInfo.flash_nvram_start_blk,
392 (fInfo.flash_nvram_number_blk + fInfo.flash_nvram_start_blk), pBuf) != 0)
401 /***********************************************************************
402 * Function Name: kerSysEraseNvRam
403 * Description : Erase the NVRAM storage section of flash memory.
404 * Returns : 1 -- ok, 0 -- fail
405 ***********************************************************************/
406 int kerSysEraseNvRam(void)
409 char *tempStorage = retriedKmalloc(NVRAM_LENGTH);
411 // just write the whole buf with '0xff' to the flash
416 memset(tempStorage, 0xff, NVRAM_LENGTH);
417 if (kerSysNvRamSet(tempStorage, NVRAM_LENGTH, 0) != 0)
419 retriedKfree(tempStorage);
426 /*******************************************************************************
428 *******************************************************************************/
433 int kerSysPersistentGet(char *string, int strLen, int offset)
437 if (strLen > fInfo.flash_persistent_length)
440 if ((pBuf = getSharedBlks(fInfo.flash_persistent_start_blk,
441 (fInfo.flash_persistent_start_blk + fInfo.flash_persistent_number_blk))) == NULL)
444 // get string off the memory buffer
445 memcpy(string, (pBuf + fInfo.flash_persistent_blk_offset + offset), strLen);
457 int kerSysPersistentSet(char *string, int strLen, int offset)
462 if (strLen > fInfo.flash_persistent_length)
465 if ((pBuf = getSharedBlks(fInfo.flash_persistent_start_blk,
466 (fInfo.flash_persistent_start_blk + fInfo.flash_persistent_number_blk))) == NULL)
469 // set string to the memory buffer
470 memcpy((pBuf + fInfo.flash_persistent_blk_offset + offset), string, strLen);
471 // USR9108 add two terminating zeros to the end of the string
472 if ( strLen <= fInfo.flash_persistent_length - 2 )
473 memcpy((pBuf + fInfo.flash_persistent_blk_offset + offset + strLen), "\0\0", 2);
475 if (setSharedBlks(fInfo.flash_persistent_start_blk,
476 (fInfo.flash_persistent_number_blk + fInfo.flash_persistent_start_blk), pBuf) != 0)
488 // !0 - the sector number fail to be flashed (should not be 0)
489 int kerSysBcmImageSet( int flash_start_addr, char *string, int size)
495 char *pTempBuf = NULL;
498 blk_start = flash_get_blk(flash_start_addr);
502 if (flash_start_addr == FLASH_BASE && size > FLASH_LENGTH_BOOT_ROM)
505 /* write image to flash memory */
508 sect_size = flash_get_sector_size(blk_start);
509 // NOTE: for memory problem in multiple PVC configuration, temporary get rid of kmalloc this 64K for now.
510 // if ((pTempBuf = (char *)retriedKmalloc(sect_size)) == NULL)
512 // printk("Failed to allocate memory with size: %d. Reset the router...\n", sect_size);
513 // kerSysMipsSoftReset(); // reset the board right away.
515 // for whole image, no check on psi
516 if (!whole_image && blk_start == fInfo.flash_persistent_start_blk) // share the blk with psi
518 if (size > (sect_size - fInfo.flash_persistent_length))
520 printk("Image is too big\n");
521 break; // image is too big. Can not overwrite to nvram
523 if ((pTempBuf = (char *)retriedKmalloc(sect_size)) == NULL)
525 printk("Failed to allocate memory with size: %d. Reset the router...\n", sect_size);
526 kerSysMipsSoftReset(); // reset the board right away.
528 flash_read_buf((unsigned short)blk_start, 0, pTempBuf, sect_size);
529 if (copy_from_user((void *)pTempBuf,(void *)string, size) != 0)
531 flash_sector_erase_int(blk_start); // erase blk before flash
532 if (flash_write_buf(blk_start, 0, pTempBuf, sect_size) == sect_size)
533 size = 0; // break out and say all is ok
534 retriedKfree(pTempBuf);
538 flash_sector_erase_int(blk_start); // erase blk before flash
540 if (sect_size > size)
547 if ((i = flash_write_buf(blk_start, 0, string, sect_size)) != sect_size) {
557 // If flashing a whole image, erase to end of flash.
558 int total_blks = flash_get_numsectors();
559 while( blk_start < total_blks )
561 flash_sector_erase_int(blk_start);
566 retriedKfree(pTempBuf);
571 sts = blk_start; // failed to flash this sector
576 /*******************************************************************************
578 *******************************************************************************/
579 // get sp data. NOTE: memcpy work here -- not using copy_from/to_user
581 // >0 - number of bytes copied to tokBuf
583 int kerSysScratchPadGet(char *tokenId, char *tokBuf, int bufLen)
585 PSP_TOKEN pToken = NULL;
587 char *pShareBuf = NULL;
588 char *startPtr = NULL;
592 if (fInfo.flash_scratch_pad_length == 0)
595 if( bufLen >= (fInfo.flash_scratch_pad_length - sizeof(SP_HEADER) -
598 printk("Exceed scratch pad space by %d\n", bufLen -
599 fInfo.flash_scratch_pad_length - sizeof(SP_HEADER) -
604 if( (pShareBuf = getSharedBlks(fInfo.flash_scratch_pad_start_blk,
605 (fInfo.flash_scratch_pad_start_blk +
606 fInfo.flash_scratch_pad_number_blk))) == NULL )
611 // pBuf points to SP buf
612 pBuf = pShareBuf + fInfo.flash_scratch_pad_blk_offset;
614 if(memcmp(((PSP_HEADER)pBuf)->SPMagicNum, MAGIC_NUMBER, MAGIC_NUM_LEN) != 0)
616 printk("Scratch pad is not initialized.\n");
617 retriedKfree(pShareBuf);
621 // search for the token
622 usedLen = sizeof(SP_HEADER);
623 startPtr = pBuf + sizeof(SP_HEADER);
624 pToken = (PSP_TOKEN) startPtr;
625 while( pToken->tokenName[0] != '\0' && pToken->tokenLen > 0 &&
626 pToken->tokenLen < fInfo.flash_scratch_pad_length &&
627 usedLen < fInfo.flash_scratch_pad_length )
630 if (strncmp(pToken->tokenName, tokenId, TOKEN_NAME_LEN) == 0)
632 if ( pToken->tokenLen > bufLen )
634 printk("The length %d of token %s is greater than buffer len %d.\n", pToken->tokenLen, pToken->tokenName, bufLen);
637 sts = pToken->tokenLen;
638 memcpy(tokBuf, startPtr + sizeof(SP_TOKEN), sts);
642 usedLen += ((pToken->tokenLen + 0x03) & ~0x03);
643 startPtr += sizeof(SP_TOKEN) + ((pToken->tokenLen + 0x03) & ~0x03);
644 pToken = (PSP_TOKEN) startPtr;
647 retriedKfree(pShareBuf);
653 // set sp. NOTE: memcpy work here -- not using copy_from/to_user
657 int kerSysScratchPadSet(char *tokenId, char *tokBuf, int bufLen)
659 PSP_TOKEN pToken = NULL;
660 char *pShareBuf = NULL;
667 if (fInfo.flash_scratch_pad_length == 0)
670 if( bufLen >= fInfo.flash_scratch_pad_length - sizeof(SP_HEADER) -
673 printk("Scratch pad overflow by %d bytes. Information not saved.\n",
674 bufLen - fInfo.flash_scratch_pad_length - sizeof(SP_HEADER) -
679 if( (pShareBuf = getSharedBlks( fInfo.flash_scratch_pad_start_blk,
680 (fInfo.flash_scratch_pad_start_blk +
681 fInfo.flash_scratch_pad_number_blk) )) == NULL )
686 // pBuf points to SP buf
687 pBuf = pShareBuf + fInfo.flash_scratch_pad_blk_offset;
690 memset((char *)&SPHead, 0, sizeof(SP_HEADER));
691 memcpy(SPHead.SPMagicNum, MAGIC_NUMBER, MAGIC_NUM_LEN);
692 SPHead.SPVersion = SP_VERSION;
695 memset((char*)&SPToken, 0, sizeof(SP_TOKEN));
696 strncpy(SPToken.tokenName, tokenId, TOKEN_NAME_LEN - 1);
697 SPToken.tokenLen = bufLen;
699 if(memcmp(((PSP_HEADER)pBuf)->SPMagicNum, MAGIC_NUMBER, MAGIC_NUM_LEN) != 0)
701 // new sp, so just flash the token
702 printk("No scratch pad found. Initialize scratch pad...\n");
703 memcpy(pBuf, (char *)&SPHead, sizeof(SP_HEADER));
704 curPtr = pBuf + sizeof(SP_HEADER);
705 memcpy(curPtr, (char *)&SPToken, sizeof(SP_TOKEN));
706 curPtr += sizeof(SP_TOKEN);
708 memcpy(curPtr, tokBuf, bufLen);
717 /* Calculate the used length. */
718 usedLen = sizeof(SP_HEADER);
719 curPtr = pBuf + sizeof(SP_HEADER);
720 pToken = (PSP_TOKEN) curPtr;
721 skipLen = (pToken->tokenLen + 0x03) & ~0x03;
722 while( pToken->tokenName[0] >= 'A' && pToken->tokenName[0] <= 'z' &&
723 strlen(pToken->tokenName) < TOKEN_NAME_LEN &&
724 pToken->tokenLen > 0 &&
725 pToken->tokenLen < fInfo.flash_scratch_pad_length &&
726 usedLen < fInfo.flash_scratch_pad_length )
728 usedLen += sizeof(SP_TOKEN) + skipLen;
729 curPtr += sizeof(SP_TOKEN) + skipLen;
730 pToken = (PSP_TOKEN) curPtr;
731 skipLen = (pToken->tokenLen + 0x03) & ~0x03;
734 if( usedLen + SPToken.tokenLen + sizeof(SP_TOKEN) >
735 fInfo.flash_scratch_pad_length )
737 printk("Scratch pad overflow by %d bytes. Information not saved.\n",
738 (usedLen + SPToken.tokenLen + sizeof(SP_TOKEN)) -
739 fInfo.flash_scratch_pad_length);
743 curPtr = pBuf + sizeof(SP_HEADER);
744 curLen = sizeof(SP_HEADER);
745 while( curLen < usedLen )
747 pToken = (PSP_TOKEN) curPtr;
748 skipLen = (pToken->tokenLen + 0x03) & ~0x03;
749 if (strncmp(pToken->tokenName, tokenId, TOKEN_NAME_LEN) == 0)
751 // The token id already exists.
752 if( tokBuf && pToken->tokenLen == bufLen )
754 // The length of the new data and the existing data is the
755 // same. Overwrite the existing data.
756 memcpy((curPtr+sizeof(SP_TOKEN)), tokBuf, bufLen);
761 // The length of the new data and the existing data is
762 // different. Shift the rest of the scratch pad to this
763 // token's location and put this token's data at the end.
764 char *nextPtr = curPtr + sizeof(SP_TOKEN) + skipLen;
765 int copyLen = usedLen - (curLen+sizeof(SP_TOKEN) + skipLen);
766 memcpy( curPtr, nextPtr, copyLen );
767 memset( curPtr + copyLen, 0x00,
768 fInfo.flash_scratch_pad_length - (curLen + copyLen) );
769 usedLen -= sizeof(SP_TOKEN) + skipLen;
775 curPtr += sizeof(SP_TOKEN) + skipLen;
776 curLen += sizeof(SP_TOKEN) + skipLen;
783 memcpy( pBuf + usedLen, &SPToken, sizeof(SP_TOKEN) );
784 memcpy( pBuf + usedLen + sizeof(SP_TOKEN), tokBuf, bufLen );
786 memcpy( pBuf, &SPHead, sizeof(SP_HEADER) );
789 } // else if not new sp
791 sts = setSharedBlks(fInfo.flash_scratch_pad_start_blk,
792 (fInfo.flash_scratch_pad_number_blk + fInfo.flash_scratch_pad_start_blk),
795 retriedKfree(pShareBuf);
802 // wipe out the scratchPad
806 int kerSysScratchPadClearAll(void)
809 char *pShareBuf = NULL;
813 if (fInfo.flash_scratch_pad_length == 0)
815 if( (pShareBuf = getSharedBlks( fInfo.flash_scratch_pad_start_blk,
816 (fInfo.flash_scratch_pad_start_blk + fInfo.flash_scratch_pad_number_blk) )) == NULL )
818 pBuf = pShareBuf + fInfo.flash_scratch_pad_blk_offset;
819 memset(pBuf, 0x00, fInfo.flash_scratch_pad_length);
820 sts = setSharedBlks(fInfo.flash_scratch_pad_start_blk,
821 (fInfo.flash_scratch_pad_number_blk + fInfo.flash_scratch_pad_start_blk), pShareBuf);
823 retriedKfree(pShareBuf);
828 int kerSysFlashSizeGet(void)
830 return flash_get_total_size();
833 int kerSysMemoryMappedFlashSizeGet(void)
835 return( flash_get_total_memory_mapped_size() );
838 unsigned long kerSysReadFromFlash( void *toaddr, unsigned long fromaddr,
841 int sect = flash_get_blk((int) fromaddr);
842 unsigned char *start = flash_get_memptr(sect);
843 flash_read_buf( sect, (int) fromaddr - (int) start, toaddr, len );