/* get the sector offset */ MV_U32 mvFlashSecOffsGet(MV_FLASH_INFO *pFlash, MV_U32 secNum) { if((NULL == pFlash)|| (secNum > mvFlashNumOfSecsGet(pFlash))) return 0; return pFlash->sector[secNum].baseOffs; }
/* get the lock status of a sector in the flash */ MV_BOOL mvFlashSecLockGet(MV_FLASH_INFO *pFlash, MV_U32 secNum) { if((NULL == pFlash)|| (secNum > mvFlashNumOfSecsGet(pFlash)) ) return MV_FALSE; return pFlash->sector[secNum].protect; }
/******************************************************************************* * flashIsSecErased - Check if a given Sector is erased. * * DESCRIPTION: * Go over the sector and check if its entire data is 0xFF. * INPUT: * secNum - sector Number. * pFlash - flash information. * * OUTPUT: * None * * RETURN: * MV_BAD_PARAM if one of the inputs values is illegal, * MV_TRUE if sector is already erased, * MV_FALSE otherwise. * *******************************************************************************/ MV_BOOL flashIsSecErased(MV_FLASH_INFO *pFlash, MV_U32 secNum) { MV_U32 i; DB(mvOsPrintf("Flash: flashIsSecErased. \n")); if((NULL == pFlash) || (secNum >= mvFlashNumOfSecsGet(pFlash)) ) return MV_BAD_PARAM; /* reset the flash */ flashReset(pFlash); /* go over the sector */ for(i = mvFlashSecOffsGet(pFlash,secNum); i < mvFlashSecOffsGet(pFlash,secNum) + mvFlashSecSizeGet(pFlash,secNum); i+= 4) { if(mvFlash32Rd(pFlash,i) != FLASH_WR_ERASED ) { DB(mvOsPrintf("Flash: Not erased addr %x is %x \n", i ,mvFlash32Rd(pFlash,i))); return MV_FALSE; } } return MV_TRUE; }
/******************************************************************************* * mvFlash32Wr - Write 32bit (word) to flash. * * DESCRIPTION: * This function writes 32bit data to a given flash offset. * * INPUT: * pFlash - Flash identifier structure (flash cockie). * offset - Offset from flash base address. * data - 32bit data to be written to flash. * * OUTPUT: * None. * * RETURN: * MV_BAD_PARAM if one of the inputs values is illegal, * MV_OK if write completed successfully, * MV_FAIL otherwise (e.g. sector protected). * *******************************************************************************/ MV_STATUS mvFlash32Wr(MV_FLASH_INFO *pFlash, MV_U32 offset, MV_U32 data) { MV_U32 i, status = MV_OK, temp,secNum; DB(mvOsPrintf("Flash: mvFlash32Wr offset %x data %x \n",offset,data)); /* check that the offset is aligned to 32 bit */ if((NULL == pFlash) || (offset % 4)) return MV_BAD_PARAM; secNum = mvFlashInWhichSec(pFlash,offset); DB(mvOsPrintf("Flash: mvFlashProg \n")); /* check if offset is in flash range */ if( secNum >= mvFlashNumOfSecsGet(pFlash)) { DB(mvOsPrintf("Flash: mvFlashProg offset out of flash range \n")); return MV_BAD_PARAM; } /* check if sector is locked */ if(MV_TRUE == mvFlashSecLockGet(pFlash, secNum) ) { mvOsPrintf("Flash: ERROR mvFlashProg protected sector.\n"); return MV_FAIL; } /* check if offset is erased enough */ if((mvFlash32Rd(pFlash, offset) & data) != data ) { mvOsPrintf("%s ERROR: offset 0x%x (sector %d) isn't erased !!!.\n", __FUNCTION__, offset, secNum); return MV_FAIL; } /* bus width is 32 bit */ if(mvFlashBusWidthGet(pFlash) == 4) { data = MV_32BIT_BE(data); status = mvFlashProg(pFlash, offset,data); } /* bus width is 16 bit */ else if(mvFlashBusWidthGet(pFlash) == 2) { for(i = 0; i < 2; i++) { /* 0x44556677 -> [44][55][66][77] */ temp = MV_16BIT_BE(((data >> (16*(1-i))) & FLASH_MASK_16BIT)); if(MV_OK != mvFlashProg(pFlash, offset + (i*2), temp) ) { status = MV_FAIL; break; } } } /* bus width is 8 bit */ else if(mvFlashBusWidthGet(pFlash) == 1)
/******************************************************************************* * mvFlashErase - Completly Erase a flash. * * DESCRIPTION: * This function completly erase the given flash, by erasing all the * flash sectors one by one (Currently there is no support for HW * flash erase). * * INPUT: * pFlash - Flash identifier structure. * * OUTPUT: * None. * * RETURN: * MV_BAD_PARAM if pFlash is NULL, * MV_OK if erased completed successfully, * MV_FAIL otherwise. * *******************************************************************************/ MV_STATUS mvFlashErase(MV_FLASH_INFO *pFlash) { MV_U32 i; if (NULL == pFlash) return MV_BAD_PARAM; DB(mvOsPrintf("Flash: mvFlashErase \n")); /* erase all sectors in the flash one by one */ for (i = 0; i < mvFlashNumOfSecsGet(pFlash); i++) { if (MV_OK != mvFlashSecErase(pFlash, i)) return MV_FAIL; } return MV_OK; }
/******************************************************************************* * mvFlashInWhichSec - Return which Sector rap the offset address. * * DESCRIPTION: * * INPUT: * pFlash - Flash identifier structure. * offset - offset address. * * OUTPUT: * None * * RETURN: * MV_U32 - The Sector Number that the offset sits in. * BAD_SEC_NUM if not found. * *******************************************************************************/ MV_U32 mvFlashInWhichSec(MV_FLASH_INFO *pFlash, MV_U32 offset) { MV_U32 secNum; if(NULL == pFlash) return 0; for( secNum = 0; secNum < mvFlashNumOfSecsGet(pFlash); secNum++){ if((offset >= mvFlashSecOffsGet(pFlash, secNum)) && (offset < mvFlashSecOffsGet(pFlash, secNum) + mvFlashSecSizeGet(pFlash, secNum)) ) { return secNum; } } /* return illegal sector Number */ return FLASH_BAD_SEC_NUM; }
/******************************************************************************* * mvFlashSecErase - Erase a flash sector. * * DESCRIPTION: * This function checks if the sector isn't protected and if the sector * isn't already erased. * * INPUT: * pFlash - Flash identifier structure. * sectorNum - secrot number to erase. * * OUTPUT: * None. * * RETURN: * MV_BAD_PARAM if one of the inputs values is illegal, * MV_OK if erased completed successfully, * MV_FAIL otherwise (e.g. sector protected). * *******************************************************************************/ MV_STATUS mvFlashSecErase(MV_FLASH_INFO *pFlash, MV_U32 sectorNum) { MV_U32 status; DB(mvOsPrintf("Flash: mvFlashSecErase \n")); /* check parametrs values */ if((NULL == pFlash) || (sectorNum >= mvFlashNumOfSecsGet(pFlash)) ) { return MV_BAD_PARAM; } /* check if sector is locked */ if(MV_TRUE == mvFlashSecLockGet(pFlash, sectorNum)) { mvOsPrintf("Flash: ERROR mvFlashSecErase protected sector.\n"); return MV_FAIL; } /* check if already erased */ if(MV_TRUE == flashIsSecErased(pFlash,sectorNum)) { DB(mvOsPrintf("Flash: FlashSecErase sector already erased \n")); return MV_OK; } /* erase sector using the Flash Ven Alg. */ switch(mvFlashVenIdGet(pFlash)) { case INTEL_MANUF: /* INTEL/MT */ status = intelFlashSecErase(pFlash,sectorNum); break; case AMD_MANUF: case STM_MANUF: case SST_MANUF: status = amdFlashSecErase(pFlash,sectorNum); break; default: mvOsPrintf("Flash: ERROR mvFlashErase. unsupported flash vendor\n"); return MV_FAIL; } /* reset the flash */ flashReset(pFlash); return status; }
/******************************************************************************* * flashPrint - Print flash information structure. * * DESCRIPTION: * Prints all the feilds in the flash info structure. * * INPUT: * pFlash - Flash information. * * OUTPUT: * None * * RETURN: * None * *******************************************************************************/ MV_VOID flashPrint(MV_FLASH_INFO *pFlash) { MV_U32 i; if ((NULL == pFlash) || (mvFlashVenIdGet(pFlash) == 0)) { mvOsOutput ("missing or unknown FLASH type\n"); return; } switch (mvFlashVenIdGet(pFlash)) { case STM_MANUF: mvOsOutput ("STM "); break; case AMD_MANUF: mvOsOutput ("AMD "); break; case FUJ_MANUF: mvOsOutput ("FUJITSU "); break; case INTEL_MANUF: mvOsOutput ("INTEL "); break; case SST_MANUF: mvOsOutput ("SST "); break; case MX_MANUF: mvOsOutput ("MX "); break; default: mvOsOutput ("Unknown Vendor 0x%x",mvFlashVenIdGet(pFlash)); break; } switch (mvFlashDevIdGet(pFlash)) { case AMD_FID_LV040B: mvOsOutput ("AM29LV040B (4 Mbit, bottom boot sect)"); break; case AMD_FID_LV400B: mvOsOutput ("AM29LV400B (4 Mbit, bottom boot sect)"); break; case AMD_FID_LV400T: mvOsOutput ("AM29LV400T (4 Mbit, top boot sector)"); break; case AMD_FID_LV800B: mvOsOutput ("AM29LV800B (8 Mbit, bottom boot sect)"); break; case AMD_FID_LV800T: mvOsOutput ("AM29LV800T (8 Mbit, top boot sector)"); break; case AMD_FID_LV160B: mvOsOutput ("AM29LV160B (16 Mbit, bottom boot sect)"); break; case AMD_FID_LV160T: mvOsOutput ("AM29LV160T (16 Mbit, top boot sector)"); break; case AMD_FID_LV320B: mvOsOutput ("AM29LV320B (32 Mbit, bottom boot sect)"); break; case AMD_FID_LV320T: mvOsOutput ("AM29LV320T (32 Mbit, top boot sector)"); break; case STM_FID_29W040B: mvOsOutput ("M29W040B (4Mbit = 512K x 8) "); break; case INTEL_FID_28F320J3A: mvOsOutput ("28F320J3A (32 Mbit)"); break; case INTEL_FID_28F640J3A: mvOsOutput ("28F640J3A (64 Mbit)"); break; case INTEL_FID_28F128J3A: mvOsOutput ("28F128J3A (128 Mbit)"); break; case INTEL_FID_28F128P30T: mvOsOutput ("28F128P30 TOP (128 Mbit)"); break; case INTEL_FID_28F128P30B: mvOsOutput ("28F128P30 BOTTOM (128 Mbit)"); break; case INTEL_FID_28F256P30T: mvOsOutput ("28F256P30 TOP (256 Mbit)"); break; #if defined (DB_88F1281) case INTEL_FID_28F256P30B: mvOsOutput ("28F256P30 BOTTOM (128 Mbit)"); break; #else case INTEL_FID_28F256P30B: mvOsOutput ("28F256P30 BOTTOM (256 Mbit)"); break; #endif case SST_39VF_020: mvOsOutput ("SST39VF020 (2 Mbit)"); break; default: mvOsOutput ("Unknown Chip Type id 0x%x",mvFlashDevIdGet(pFlash)); break; } if(mvFlashNumOfDevGet(pFlash) > 1) mvOsOutput(" X %d",mvFlashNumOfDevGet(pFlash)); mvOsOutput("\nSize: "); sizePrint(mvFlashSizeGet(pFlash)," in "); mvOsOutput("%d Sectors\n",mvFlashNumOfSecsGet(pFlash)); mvOsOutput("Bus Width: %dbit, device Width: %dbit, type: ", (8 * mvFlashBusWidthGet(pFlash)), (8 * mvFlashDevWidthGet(pFlash))); switch (mvFlashSecTypeGet(pFlash)) { case TOP: mvOsOutput ("TOP"); break; case BOTTOM: mvOsOutput ("BOTTOM"); break; case REGULAR: mvOsOutput ("REGULAR"); break; default: mvOsOutput ("Unknown Type"); break; } mvOsOutput(".\n"); mvOsOutput (" Sector Start Addresses:"); for (i=0; i<mvFlashNumOfSecsGet(pFlash); ++i) { if ((i % 5) == 0) mvOsOutput ("\n "); mvOsOutput (" %08lX%s", (mvFlashSecOffsGet(pFlash, i) + mvFlashBaseAddrGet(pFlash)), mvFlashSecLockGet(pFlash,i) ? " (RO)" : " " ); } mvOsOutput("\n"); return; }