?? amd.c
字號:
//****************************************************************************//// AMD.c - The amd flash function definition.//// Copyright (c) 2006 Cirrus Logic, Inc.////****************************************************************************#include "ep93xx.h"#include "flash.h"#include "amd.h"#include <string.h>#define AMD_compatible_MAX 3static struct sFlashManufactureId sAMD_ManufactureId[AMD_compatible_MAX]={ {0x0001,"AMD"}, {0x0004,"Spansion"}, {0x0020,"ST"}};//****************************************************************************// Name : AmdFlashQuery// Description: This routine read the flash manufactureid and deviceid.// Return : 0 - succuss.// 1 - failure.// Note(s) ://****************************************************************************int AmdFlashQuery(struct FlashInfo *pInfo){ volatile unsigned short *ptr16 = (volatile unsigned short *)pInfo->FlashBase; volatile unsigned long *ptr32 = (volatile unsigned long *)pInfo->FlashBase; unsigned short usByteWidth = pInfo->ByteWidth; int iIdx, iResult; int timeout = 500000; if (usByteWidth == 1){ unsigned short usWord; usWord = *ptr16; // Query 16 bitwidth id. *(ptr16 + AMD_SETUP_ADDR1) = AMD_SETUP_CODE1; *(ptr16 + AMD_SETUP_ADDR2) = AMD_SETUP_CODE2; *(ptr16 + AMD_SETUP_ADDR1) = AMD_READ_ID; pInfo->ManufactureId = *(ptr16 + AMD_VENDORID_ADDR); pInfo->DeviceId[0] = *(ptr16 + AMD_DEVICEID_ADDR1); // Query 16 bitwidth flash. *(ptr16 + AMD_QUERY_ADDR) = AMD_READ_QUERY; pInfo->pQuery->DeviceSize = 1 << (*(ptr16 + 0x27) & 0xFF); pInfo->pQuery->NumEraseBlocks = *(ptr16 + 0x2c) & 0xFFFF; for(iIdx = 0; iIdx < pInfo->pQuery->NumEraseBlocks; iIdx++){ pInfo->pQuery->sBlockInfo[iIdx].blocks = (*(ptr16 + 0x2d + (iIdx<<2)) & 0xFFFF) + 1; pInfo->pQuery->sBlockInfo[iIdx].block_size = (((*(ptr16 + 0x30 + (iIdx<<2)) & 0xFFFF) << 8) + (*(ptr16 + 0x2f + (iIdx<<2)) & 0xFFFF)) << 8; } // Put the FLASH into read array mode. *ptr16 = AMD_RESET; // Stall, waiting for flash to return to read mode. while ((--timeout != 0) && (usWord != *ptr16)); iResult = 0; } else if (usByteWidth == 2){ unsigned long ulWord; ulWord = *ptr32; // Query 16 bitwidth id. *(ptr32 + AMD_SETUP_ADDR1) = (AMD_SETUP_CODE1 << 16) | AMD_SETUP_CODE1; *(ptr32 + AMD_SETUP_ADDR2) = (AMD_SETUP_CODE2 << 16) | AMD_SETUP_CODE2; *(ptr32 + AMD_SETUP_ADDR1) = (AMD_READ_ID << 16) | AMD_READ_ID; pInfo->ManufactureId = (unsigned short) ((*(ptr32 + AMD_VENDORID_ADDR) >> 16) & ((*(ptr32 + AMD_VENDORID_ADDR)) & 0xFFFF)); pInfo->DeviceId[0] = (unsigned short) (*(ptr32 + AMD_DEVICEID_ADDR1) ); // Query 32 bitwidth flash. *(ptr32 + AMD_QUERY_ADDR) = (AMD_READ_QUERY << 16) | AMD_READ_QUERY; pInfo->pQuery->DeviceSize = 2 << (*(ptr32 + 0x27) & 0xFF); pInfo->pQuery->NumEraseBlocks = *(ptr32 + 0x2c) & 0xFFFF; for(iIdx = 0; iIdx < pInfo->pQuery->NumEraseBlocks; iIdx++){ pInfo->pQuery->sBlockInfo[iIdx].blocks = (*(ptr32 + 0x2d + (iIdx<<2)) & 0xFFFF) + 1; pInfo->pQuery->sBlockInfo[iIdx].block_size = (((*(ptr32 + 0x30 + (iIdx<<2)) & 0xFFFF) << 8) + (*(ptr32 + 0x2f + (iIdx<<2)) & 0xFFFF)) << 8; } // Put the FLASH into read array mode. *ptr32 = (AMD_RESET << 16) | AMD_RESET; // Stall, waiting for flash to return to read mode. while ((--timeout != 0) && (ulWord != *ptr32)); iResult = 0; } else{ // No such parameter. iResult = 1; } //if(pInfo->ManufactureId == 0x0001) return 0; //else return 1; for(iIdx=0;iIdx<AMD_compatible_MAX;iIdx++) { if(pInfo->ManufactureId == sAMD_ManufactureId[iIdx].manufacture_id) { return 0; } } return 1; }//****************************************************************************// Name : AmdFlashEraseSector// Description: This routine erase the specified sector of amd.// Arguments : iOffset - the offset address.// len - the length.// Return : 0 - succuss.// 1 - failure.// Note(s) ://****************************************************************************int AmdFlashEraseSector(struct FlashInfo *pInfo, int iSector){ volatile unsigned short *ptr16 = (volatile unsigned short *)pInfo->FlashBase; volatile unsigned long *ptr32 = (volatile unsigned long *)pInfo->FlashBase; unsigned short usByteWidth = pInfo->ByteWidth; int iResult = FLASH_ERR_OK; int timeout = 50000; if (usByteWidth == 1){ // Send erase block command - six step sequence *(ptr16 + AMD_SETUP_ADDR1) = AMD_SETUP_CODE1; *(ptr16 + AMD_SETUP_ADDR2) = AMD_SETUP_CODE2; *(ptr16 + AMD_SETUP_ADDR1) = AMD_SETUP_ERASE; *(ptr16 + AMD_SETUP_ADDR1) = AMD_SETUP_CODE1; *(ptr16 + AMD_SETUP_ADDR2) = AMD_SETUP_CODE2; *(ptr16 + (iSector >> 1)) = AMD_BLOCK_ERASE; // Now poll for the completion of the sector erase timer (50us) timeout = 10000000; // how many retries? while (1) { if (((*(ptr16 + (iSector >> 1))) & AMD_SECTOR_ERASE_TIMER) == AMD_SECTOR_ERASE_TIMER) break; if (--timeout == 0) { iResult = FLASH_ERR_DRV_TIMEOUT; break; } } // Then wait for erase completion. if (FLASH_ERR_OK == iResult) { timeout = 10000000; while (1) { if (0xffff == (*(ptr16 + (iSector >> 1)))) { break; } // Don't check for FLASH_Err here since it will fail // with devices in parallel because these may finish // at different times. if (--timeout == 0) { iResult = FLASH_ERR_DRV_TIMEOUT; break; } } } if (FLASH_ERR_OK != iResult) *ptr16 = AMD_RESET; } else if (usByteWidth == 2){ // Send erase block command - six step sequence *(ptr32 + AMD_SETUP_ADDR1) = (AMD_SETUP_CODE1 << 16) | AMD_SETUP_CODE1; *(ptr32 + AMD_SETUP_ADDR2) = (AMD_SETUP_CODE2 << 16) | AMD_SETUP_CODE2; *(ptr32 + AMD_SETUP_ADDR1) = (AMD_SETUP_ERASE << 16) | AMD_SETUP_ERASE; *(ptr32 + AMD_SETUP_ADDR1) = (AMD_SETUP_CODE1 << 16) | AMD_SETUP_CODE1; *(ptr32 + AMD_SETUP_ADDR2) = (AMD_SETUP_CODE2 << 16) | AMD_SETUP_CODE2; *(ptr32 + (iSector >> 2)) = (AMD_BLOCK_ERASE << 16) | AMD_BLOCK_ERASE; // Now poll for the completion of the sector erase timer (50us) timeout = 10000000; // how many retries? while (1) { if (((*(ptr32 + (iSector >> 2))) & AMD_SECTOR_ERASE_TIMER) == AMD_SECTOR_ERASE_TIMER) break; if (--timeout == 0) { iResult = FLASH_ERR_DRV_TIMEOUT; break; } } // Then wait for erase completion. if (FLASH_ERR_OK == iResult) { timeout = 10000000; while (1) { if (0xffffffff == (*(ptr32 + (iSector >> 2)))) { break; } // Don't check for FLASH_Err here since it will fail // with devices in parallel because these may finish // at different times. if (--timeout == 0) { iResult = FLASH_ERR_DRV_TIMEOUT; break; } } } if (FLASH_ERR_OK != iResult) *ptr32 = (AMD_RESET << 16) | AMD_RESET; } else{ // No such parameter. return 1; } return iResult;}//****************************************************************************// Name : GetSectorIndex// Description: This routine erase the sectors of intel.// Arguments : iOffset - the offset address.// len - the length.// Return : 0 - succuss.// 1 - failure.// Note(s) ://****************************************************************************int Amd_GetSectorIndex(struct FlashInfo *pInfo,long lStartAddress, unsigned long * pulSectorBase,int * piCurEraseRegion, int * piCurEraseBlock ){ unsigned short usByteWidth = pInfo->ByteWidth; int i, j; long iEraseBase = lStartAddress; *pulSectorBase = 0; if (usByteWidth == 1) { for(i = 0; i < pInfo->pQuery->NumEraseBlocks; i++) { for(j = 0; j< pInfo->pQuery->sBlockInfo[i].blocks; j++) { if(iEraseBase >= pInfo->pQuery->sBlockInfo[i].block_size) { *pulSectorBase = *pulSectorBase + pInfo->pQuery->sBlockInfo[i].block_size; iEraseBase = iEraseBase - pInfo->pQuery->sBlockInfo[i].block_size; } else { *piCurEraseRegion = i; *piCurEraseBlock = j; return 0; } } } } else if (usByteWidth == 2) { for(i = 0; i < pInfo->pQuery->NumEraseBlocks; i++) { for(j = 0; j< pInfo->pQuery->sBlockInfo[i].blocks; j++) { if(iEraseBase >= pInfo->pQuery->sBlockInfo[i].block_size*2) { *pulSectorBase = *pulSectorBase + pInfo->pQuery->sBlockInfo[i].block_size*2; iEraseBase = iEraseBase - pInfo->pQuery->sBlockInfo[i].block_size*2; } else { *piCurEraseRegion = i; *piCurEraseBlock = j; return 0; } } } } else { // No such parameter. return 1; } return 1; }//****************************************************************************// Name : AmdFlashErase// Description: This routine erase the amd flash.// Arguments : iOffset - the offset address.// len - the length.// Return : 0 - succuss.// 1 - failure.// Note(s) ://****************************************************************************int AmdFlashErase(struct FlashInfo *pInfo, int iOffset, int len){ volatile unsigned short *ptr16 = (volatile unsigned short *)pInfo->FlashBase; volatile unsigned long *ptr32 = (volatile unsigned long *)pInfo->FlashBase; unsigned short usByteWidth = pInfo->ByteWidth; long i, j,iIdx; //long iEraseLen = len; //long iEraseBase = iOffset; unsigned long pulSectorBase=0,pulSectorEnd=0; int piCurEraseRegionStart=0,piCurEraseBlockStart=0,piCurEraseRegionEnd=0,piCurEraseBlockEnd=0; if(Amd_GetSectorIndex(pInfo,iOffset,&pulSectorBase, &piCurEraseRegionStart, &piCurEraseBlockStart)==1) return 1; if(Amd_GetSectorIndex(pInfo,iOffset+len,&pulSectorEnd, &piCurEraseRegionEnd, &piCurEraseBlockEnd)==1) return 1; if (usByteWidth == 1) { if(piCurEraseRegionStart!=piCurEraseRegionEnd) { for(i = piCurEraseRegionStart; i <= piCurEraseRegionEnd; i++) { if(i==piCurEraseRegionStart) { for(j = piCurEraseBlockStart; j< pInfo->pQuery->sBlockInfo[i].blocks; j++) { AmdFlashEraseSector(pInfo,pulSectorBase); // //#if 1 for(iIdx = 0; iIdx < (pInfo->pQuery->sBlockInfo[i].block_size>>1); iIdx++) { if(*(ptr16 + (pulSectorBase >> 1) + iIdx) != 0xffff) { return 1; } } //#endif pulSectorBase = pulSectorBase + pInfo->pQuery->sBlockInfo[i].block_size; } } else if(i==piCurEraseRegionEnd) { for(j = 0; j<= piCurEraseBlockEnd; j++) { AmdFlashEraseSector(pInfo,pulSectorBase); // //#if 1 for(iIdx = 0; iIdx < (pInfo->pQuery->sBlockInfo[i].block_size>>1); iIdx++) { if(*(ptr16 + (pulSectorBase >> 1) + iIdx) != 0xffff) { return 1; } } //#endif pulSectorBase = pulSectorBase + pInfo->pQuery->sBlockInfo[i].block_size; } } else { for(j = 0; j< pInfo->pQuery->sBlockInfo[i].blocks; j++) { AmdFlashEraseSector(pInfo,pulSectorBase); // //#if 1 for(iIdx = 0; iIdx < (pInfo->pQuery->sBlockInfo[i].block_size>>1); iIdx++) { if(*(ptr16 + (pulSectorBase >> 1) + iIdx) != 0xffff) { return 1; } } //#endif pulSectorBase = pulSectorBase + pInfo->pQuery->sBlockInfo[i].block_size; } } } } else { for(j = piCurEraseBlockStart; j<= piCurEraseBlockEnd; j++) { AmdFlashEraseSector(pInfo,pulSectorBase); // //#if 1 for(iIdx = 0; iIdx < (pInfo->pQuery->sBlockInfo[piCurEraseRegionStart].block_size>>1); iIdx++) { if(*(ptr16 + (pulSectorBase >> 1) + iIdx) != 0xffff) { return 1; } } //#endif pulSectorBase = pulSectorBase + pInfo->pQuery->sBlockInfo[piCurEraseRegionStart].block_size; } } return 0; } // //32 bit // else if (usByteWidth == 2) { if(piCurEraseRegionStart!=piCurEraseRegionEnd) { for(i = piCurEraseRegionStart; i <= piCurEraseRegionEnd; i++) { if(i==piCurEraseRegionStart) { for(j = piCurEraseBlockStart; j< pInfo->pQuery->sBlockInfo[i].blocks; j++) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -