fmdhal.c
来自「该BSP是基于PXA270+WINCE的BSP」· C语言 代码 · 共 683 行 · 第 1/2 页
C
683 行
/* Disable interrupts again */
g_RelocFuncStruct.FMDHAL_ASMInterruptDisable();
g_RelocFuncStruct.WriteCommand(pBlockAddress, FMDHAL_FLASH_READ_STATUS, g_FMDConfig);
if (!g_RelocFuncStruct.ReadStatus(pBlockAddress, FMDHAL_FLASH_ERASE_SUSPENDED, g_FMDConfig))
{
/* in case Vcc low or dropped during suspend. Erase suspend will not resume. */
g_RelocFuncStruct.WriteCommand(pBlockAddress, FMDHAL_FLASH_CLEAR_STATUS, g_FMDConfig);
g_RelocFuncStruct.WriteCommand(pBlockAddress, FMDHAL_FLASH_READ_ARRAY, g_FMDConfig);
g_RelocFuncStruct.FMDHAL_ASMInterruptEnable();
return(FALSE);
} else
{
/* Specs recommend to Clear-Status before
* Erase-Resume to avoid errors in other operation
* still there before the Resume
*/
g_RelocFuncStruct.WriteCommand(pBlockAddress, FMDHAL_FLASH_CLEAR_STATUS, g_FMDConfig);
g_RelocFuncStruct.WriteCommand(pBlockAddress, FMDHAL_FLASH_ERASE_RESUME, g_FMDConfig);
}
/* put the flash into Status mode */
g_RelocFuncStruct.WriteCommand(pBlockAddress, FMDHAL_FLASH_READ_STATUS, g_FMDConfig);
}
}
#endif
/* Check for Errors */
flash_status = g_RelocFuncStruct.ReadStatus(pBlockAddress, 0, g_FMDConfig);
if (flash_status & ~mFMDHAL_CmdCreate(g_FMDConfig, FMDHAL_FLASH_STATUS_READY))
{
// clear status here might be back for the top of the FMD to find out what went wrong
g_RelocFuncStruct.WriteCommand(pBlockAddress, FMDHAL_FLASH_CLEAR_STATUS, g_FMDConfig);
g_RelocFuncStruct.WriteCommand(pBlockAddress, FMDHAL_FLASH_READ_ARRAY, g_FMDConfig);
if (g_SWRWW_Enable)
{
g_RelocFuncStruct.FMDHAL_ASMInterruptEnable();
}
return(FALSE);
}
/* Put the flash back into Read Array mode */
g_RelocFuncStruct.WriteCommand(pBlockAddress, FMDHAL_FLASH_READ_ARRAY, g_FMDConfig);
if (g_SWRWW_Enable)
{
g_RelocFuncStruct.FMDHAL_ASMInterruptEnable();
}
return(TRUE);
}
BOOL FMDHAL_WriteCommand(volatile ULONG* pBaseAddress, ULONG uCmd, ULONG uConfig)
{
// if (uConfig & FMDHAL_BusConfigx16)
// {
// *(volatile UINT16 *)pBaseAddress = mFMDHAL_CmdCreate(uConfig, uCmd);
// } else
// {
*(volatile UINT32 *)pBaseAddress = mFMDHAL_CmdCreate(uConfig, uCmd);
// }
return(TRUE);
}
BOOL FMDHAL_ReadStatus(volatile ULONG* pBaseAddress, ULONG uMask, ULONG uConfig)
{
unsigned long status, mask;
status = mFMDHAL_ReadFlash(uConfig, pBaseAddress);
last_status = status;
if (uMask == 0)
return(status);
else
{
mask = mFMDHAL_CmdCreate(uConfig, uMask);
return((status & mask) == mask);
}
}
BOOL FMDHAL_IsInterruptPending(void)
{
/* A '1' in any of the bits in the following
registers is considered a pending intr */
/* if (g_pIRQ_Address->icip && !g_pIRQ_Address->icfp)
{
return(g_pIRQ_Address->icip || g_pIRQ_Address->icfp);
} else if (g_pIRQ_Address->icip && g_pIRQ_Address->icfp)
{
return(g_pIRQ_Address->icip);
} else
{
return(FALSE);
}
*/
return(FALSE);
}
BOOL FMDHAL_CFIQuery(void)
{
ULONG *pBaseAddress = g_CurrCmdStruct.pTargetAddress;
BOOL bPairedFlash = TRUE;
BOOL g_bPairedFlash = TRUE; // To Make the Macros work, please fix cnc
UINT nCount;
volatile ULONG output;
ULONG iteration =0, working_val =0, temp_val =0;
//fill the structure
g_CFIInfo.ParameterLocation = BOTTOM_BOOT;
g_CFIInfo.StartSmallBlockAddress = g_CFIInfo.ActualFlashBase;
if (g_FMDConfig & FMDHAL_BusConfigx16)
{
bPairedFlash = FALSE;
g_bPairedFlash = FALSE;
}
if (g_SWRWW_Enable)
{
//FMDHAL_ASMInterruptDisable();
g_RelocFuncStruct.FMDHAL_ASMInterruptDisable();
}
g_RelocFuncStruct.WriteCommand(pBaseAddress, READ_QUERY_CMD, g_FMDConfig);
if (!CHECK_STATUS_INDEXED(pBaseAddress, QS_IDSTRING_OFFSET, IDSTRING_Q) ||
!CHECK_STATUS_INDEXED(pBaseAddress, QS_IDSTRING_OFFSET + 1, IDSTRING_R) ||
!CHECK_STATUS_INDEXED(pBaseAddress, QS_IDSTRING_OFFSET + 2, IDSTRING_Y))
{
// This flash doesn't support CFI, so it's not a Strataflash.
DEBUGMSG(1, (TEXT("ERROR: InitializeFlash: didn't find StrataFlash CFI.\r\n")));
return(FALSE);
}
// We're pretty sure this is an Intel Strataflash part at this point - use the CFI to
// collect information on it (we're still in query mode). Also, we'll assume that both
// high and low word flash parts are the same from here on out (if paired).
//
for (nCount = 0 ; nCount < sizeof(FLASH_SYSINTERFACE_INFO) ; nCount++)
{
*((PUCHAR)&g_CFIInfo.SysInt + nCount) = (UCHAR)(READ_FLASH_INDEXED(pBaseAddress, QS_SYSINTF_OFFSET + nCount) & 0xFF);
}
for (nCount = 0 ; nCount < sizeof(FLASH_GEOMETRY_INFO) ; nCount++)
{
*((PUCHAR)&g_CFIInfo.Geometry + nCount) = (UCHAR)(READ_FLASH_INDEXED(pBaseAddress, QS_DEVGEOM_OFFSET + nCount) & 0xFF);
}
// The block erase code assumes a single block per erase region - check for that here...
//For Tyax there are 2 types of erase blocks
// if (g_CFIInfo.Geometry.NumEraseBlocks == 1)
// {
// return(FALSE);
// }
// Compute block size and the total number of blocks here. Since we know an erase region contains
// only one block, the erase region size is equal to the block size.
// Note that the flash block size is 128KB, if paired, we have two of the 16-bit parts and the block size is effectively 256KB.
g_CFIInfo.BlockSize = (g_CFIInfo.Geometry.EraseRegionSize1 * REGION_SIZE_MULT);
g_CFIInfo.TotalFlashBlocks = g_CFIInfo.Geometry.NumIdentEraseBlocks1 + 1;
if (bPairedFlash)
{
g_CFIInfo.BlockSize *= 2;
}
if (g_CFIInfo.Geometry.NumEraseBlocks > 1)
{
//this is for BB
g_CFIInfo.SmallBlockSize = g_CFIInfo.BlockSize;
g_CFIInfo. CompositeBlockSize = g_CFIInfo.SmallBlockSize * NUM_SMALL_BLKS;
g_CFIInfo.EndSmallBlockAddress = g_CFIInfo.StartSmallBlockAddress + g_CFIInfo.CompositeBlockSize;
if (((int)((g_CFIInfo.BlockSize * g_CFIInfo.TotalFlashBlocks*
g_CFIInfo.Geometry.NumEraseBlocks)) < (int)(1<<g_CFIInfo.Geometry.DevSize))
)
{
output = (ULONG)pBaseAddress + FLASH_CFIREGION2OFFSET;
while (iteration < sizeof(ULONG))
{
working_val = *((ULONG *)output + iteration)&(ULONG)QUERYTABLEMASK;
temp_val |= working_val << (BITS_IN_BYTE *iteration);
iteration++;
}
g_CFIInfo.Geometry.NumIdentEraseBlocks2 = (USHORT)(temp_val & 0xffff);
g_CFIInfo.TotalFlashBlocks+= g_CFIInfo.Geometry.NumIdentEraseBlocks2+ 1;
g_CFIInfo.Geometry.EraseRegionSize2 = (USHORT)(temp_val >> FLASH_CFIREGION_UPPERWORD);
g_CFIInfo.BlockSize = g_CFIInfo.Geometry.EraseRegionSize2* REGION_SIZE_MULT;
if (bPairedFlash)
{
g_CFIInfo.BlockSize *= 2;
}
} else // update the block count for top boot part
{
output = (ULONG)pBaseAddress + FLASH_CFIREGION1OFFSET;
while (iteration < sizeof(ULONG))
{
working_val = *((ULONG *)output + iteration)&(ULONG)QUERYTABLEMASK;
temp_val |= working_val << (BITS_IN_BYTE *iteration);
iteration++;
}
g_CFIInfo.TotalFlashBlocks+= ((temp_val & 0xffff) + 1);
}
}
g_CFIInfo.TotalFlashSizeMB =((g_CFIInfo.TotalFlashBlocks - g_CFIInfo.Geometry.NumIdentEraseBlocks1 )*(g_CFIInfo.BlockSize))>>MB;
// Put the Flash into a known state (READ_ARRAY mode with WRITE-ENABLE disabled).
g_RelocFuncStruct.WriteCommand(pBaseAddress, READ_ARRAY_CMD, g_FMDConfig);
if (g_SWRWW_Enable)
{
g_RelocFuncStruct.FMDHAL_ASMInterruptEnable();
}
return(TRUE);
}
BOOL FMDHAL_DoUnlockBlock(void)
{
volatile ULONG *pCurrBlockAddr = (volatile ULONG *)g_CurrCmdStruct.pTargetAddress;
UINT idx;
if (g_SWRWW_Enable)
{
g_RelocFuncStruct.FMDHAL_ASMInterruptDisable();
}
for (idx = 0; idx < g_CurrCmdStruct.ulNumBlocks; idx++)
{
g_RelocFuncStruct.WriteCommand(pCurrBlockAddr, FMDHAL_FLASH_UNLOCK_BLOCK_SETUP, g_FMDConfig);
g_RelocFuncStruct.WriteCommand(pCurrBlockAddr, FMDHAL_FLASH_UNLOCK_BLOCK_CONFIRM, g_FMDConfig);
while (!g_RelocFuncStruct.ReadStatus(pCurrBlockAddr, FMDHAL_FLASH_STATUS_READY, g_FMDConfig));
/* Check for Errors */
if (g_RelocFuncStruct.ReadStatus(pCurrBlockAddr,
(IntelSCSStatusVoltageError |
IntelSCSStatusBlockLockError |
IntelSCSStatusEraseError),
g_FMDConfig))
{
g_RelocFuncStruct.WriteCommand(pCurrBlockAddr, FMDHAL_FLASH_CLEAR_STATUS, g_FMDConfig);
g_RelocFuncStruct.WriteCommand(pCurrBlockAddr, FMDHAL_FLASH_READ_ARRAY, g_FMDConfig);
if (g_SWRWW_Enable)
{
g_RelocFuncStruct.FMDHAL_ASMInterruptEnable();
}
return(FALSE);
}
}
g_RelocFuncStruct.WriteCommand(pCurrBlockAddr, FMDHAL_FLASH_READ_ARRAY, g_FMDConfig);
if (g_SWRWW_Enable)
{
g_RelocFuncStruct.FMDHAL_ASMInterruptEnable();
}
return(TRUE);
}
BOOL FMDHAL_DoLockBlock(void)
{
volatile ULONG *pCurrBlockAddr = (volatile ULONG *)g_CurrCmdStruct.pTargetAddress;
UINT idx;
if (g_SWRWW_Enable)
{
g_RelocFuncStruct.FMDHAL_ASMInterruptDisable();
}
for (idx = 0; idx < g_CurrCmdStruct.ulNumBlocks; idx++)
{
g_RelocFuncStruct.WriteCommand(pCurrBlockAddr, FMDHAL_FLASH_LOCK_BLOCK_SETUP, g_FMDConfig);
g_RelocFuncStruct.WriteCommand(pCurrBlockAddr, FMDHAL_FLASH_LOCK_BLOCK_CONFIRM, g_FMDConfig);
while (!g_RelocFuncStruct.ReadStatus(pCurrBlockAddr, FMDHAL_FLASH_STATUS_READY, g_FMDConfig));
/* Check for Errors */
if (g_RelocFuncStruct.ReadStatus(pCurrBlockAddr,
(IntelSCSStatusVoltageError |
IntelSCSStatusBlockLockError |
IntelSCSStatusEraseError),
g_FMDConfig))
{
g_RelocFuncStruct.WriteCommand(pCurrBlockAddr, FMDHAL_FLASH_CLEAR_STATUS, g_FMDConfig);
g_RelocFuncStruct.WriteCommand(pCurrBlockAddr, FMDHAL_FLASH_READ_ARRAY, g_FMDConfig);
if (g_SWRWW_Enable)
{
g_RelocFuncStruct.FMDHAL_ASMInterruptEnable();
}
return(FALSE);
}
}
g_RelocFuncStruct.WriteCommand(pCurrBlockAddr, FMDHAL_FLASH_READ_ARRAY, g_FMDConfig);
if (g_SWRWW_Enable)
{
g_RelocFuncStruct.FMDHAL_ASMInterruptEnable();
}
return(TRUE);
}
BOOL FMDHAL_RelocateCode(ULONG *pSourceAddress, ULONG *pDestinationAddress, ULONG uFunctionSize)
{
ULONG align;
if ( (uFunctionSize + g_RelocOffset) > FMDHAL_MAX_RELOCATED_AREA)
{
pDestinationAddress = NULL;
NKDbgPrintfW(L"FMDHAL:RelocCode:RelocOffset(%d)Too far\n\r\r\n", g_RelocOffset);
return(FALSE);
} else
{
*pDestinationAddress = (ULONG)&g_FMDHAL_RelocateRegion[g_RelocOffset];
//pDestinationAddress = (LPVOID)&g_FMDHAL_RelocateRegion[g_RelocOffset];
memcpy(&g_FMDHAL_RelocateRegion[g_RelocOffset], pSourceAddress, uFunctionSize);
g_RelocOffset += uFunctionSize;
/* Stay DWORD aligned */
align = g_RelocOffset & 0x3;
if (align != 0)
{
g_RelocOffset += (4 - align);
}
}
// force cache line clean to sync memory with data cache
// This is needed for imediate execution after the copy. The CPU does not fetch
// the code through the data cache. It must be written down into ram.
//
CleanDataCache( (DWORD)*pDestinationAddress, (DWORD)&g_FMDHAL_RelocateRegion[g_RelocOffset] );
return(TRUE);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?