fmdhal.c
来自「该BSP是基于PXA270+WINCE的BSP」· C语言 代码 · 共 683 行 · 第 1/2 页
C
683 行
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/**************************************************************************
** Copyright 2000-2003 Intel Corporation. All Rights Reserved.
**
** Portions of the source code contained or described herein and all documents
** related to such source code (Material) are owned by Intel Corporation
** or its suppliers or licensors and is licensed by Microsoft Corporation for distribution.
** Title to the Material remains with Intel Corporation or its suppliers and licensors.
** Use of the Materials is subject to the terms of the Microsoft license agreement which accompanied the Materials.
** No other license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise
** Some portion of the Materials may be copyrighted by Microsoft Corporation.
Module Name:
Abstract:
**************************************************************************/
//********************************************************************************************
// NOTE!!!
// Much of the code in this module runs on a small stack so logging often causes stack faults.
// FMDHAL_IOCOntrol invokes the switch to a small stack so it is safe for logging.
// Other FMDHAL_... routines are unsafe.
//********************************************************************************************
#define ENABLE_DEBUG_MESSAGES 0
#define ENABLE_LOG_MESSAGES 1
#if ENABLE_DEBUG_MESSAGES
#define DBGMSG(cond, pargs) NKDbgPrintfW pargs
#else
#define DBGMSG(cond, pargs) 0
#endif
#if ENABLE_LOG_MESSAGES
#define LOGMSG(cond, pargs) NKDbgPrintfW pargs
#else
#define LOGMSG(cond, pargs) 0
#endif
#define LOGGING_ENABLED (ENABLE_DEBUG_MESSAGES || ENABLE_LOG_MESSAGES)
#if LOGGING_ENABLED
#include <windows.h> // for NKDbgPrintfW()
#endif
//Includes
#include <bsp.h>
#include <mainstoneii.h>
#include "tyax.h"
#include "fmdhal.h"
unsigned long last_status = 0;
// note, don't move the order of the fuctions ever unless you modify the
// relocation informaton cnc
struct FMDHAL_RelocFuncStruct_t g_RelocFuncStruct;
static UCHAR g_FMDHAL_RelocateRegion[8192];
static ULONG g_RelocOffset = 0;
FMDHAL_ConfigStruct g_CFIInfo;
static struct FMDHAL_CmdStruct g_CurrCmdStruct;
/* reduce the size when known before shipping */
/* make sure to match the .s file's value with the new one */
UINT g_FMDHAL_Stack[4096];
DWORD FMDHAL_OrigStack;
void *g_FMDHAL_FuncPtr;
#define FLASH_CFIREGION2OFFSET (0x31*4)
#define FLASH_CFIREGION1OFFSET (0x2D*4)
#define QUERYTABLEMASK 0x000000FFUL
#define BITS_IN_BYTE 8
#define FLASH_CFIREGION_UPPERWORD 16
#define BOTTOM_BOOT 0
#define MB 20
/************************************
* Customer settable area. Move to
* global .h file
************************************
*/
ULONG g_FMDConfig = FMDHAL_BusConfigx32;
BOOL g_SWRWW_Enable = TRUE;
/* CPU addresses */
// XSCALE ONLY
ULONG *g_pFIQ_Address = (ULONG *)0x0L;
ULONG *g_pIRQ_Address = (ULONG *)0xA5200000;
// volatile BULVERDE_INTR_REG *g_pIRQ_Address= NULL; // XSCALE ONLY\
/* End Customer Area */
extern void FMD_CleanCacheLine( DWORD );
static void CleanDataCache( DWORD StartAddr, DWORD EndAddr )
{
DWORD CurrAddr;
if ( EndAddr < StartAddr ) {
return;
}
// align startaddr to cache line
//
CurrAddr = StartAddr & (~0x1F);
// clean the lines
//
while ( CurrAddr <= EndAddr ) {
FMD_CleanCacheLine( CurrAddr );
FMD_CleanCacheLine( CurrAddr |0x04000000 ); // TODO: Get PID for filesys dynamically ?
CurrAddr += 0x20;
}
}
BOOL FMDHAL_IOControl(ULONG uCmd, void *pOutVar, void *pInVar)
{
BOOL bRetVal = FALSE;
switch (uCmd)
{
case FMDHAL_CMD_INIT:
memcpy(&g_CurrCmdStruct, (FMDHAL_CmdStruct *)pInVar, sizeof(struct FMDHAL_CmdStruct));
if (FMDHAL_Init(((FMDHAL_CmdStruct *)pInVar)->pTargetAddress, ((FMDHAL_CmdStruct *)pInVar)->uOffset))
{
bRetVal = TRUE;
}
ASSERT(pOutVar);
memcpy(pOutVar, &g_CFIInfo, sizeof(FMDHAL_ConfigStruct));
break;
case FMDHAL_CMD_WRITE:
g_FMDHAL_FuncPtr = g_RelocFuncStruct.DoWrite;
memcpy(&g_CurrCmdStruct, pInVar, sizeof(struct FMDHAL_CmdStruct));
bRetVal = FMDHAL_ASM_CallFuncWithNewStack();
ASSERT(pOutVar);
memcpy(pOutVar, &g_CurrCmdStruct, sizeof(struct FMDHAL_CmdStruct));
break;
case FMDHAL_CMD_ERASE:
g_FMDHAL_FuncPtr = g_RelocFuncStruct.DoErase;
memcpy(&g_CurrCmdStruct, pInVar, sizeof(struct FMDHAL_CmdStruct));
bRetVal = FMDHAL_ASM_CallFuncWithNewStack();
break;
case FMDHAL_CMD_UNLOCK_BLOCK:
g_FMDHAL_FuncPtr = g_RelocFuncStruct.DoBlockUnlock;
memcpy(&g_CurrCmdStruct, (FMDHAL_CmdStruct *)pInVar, sizeof(struct FMDHAL_CmdStruct));
bRetVal = FMDHAL_ASM_CallFuncWithNewStack();
break;
case FMDHAL_CMD_LOCK_BLOCK:
g_FMDHAL_FuncPtr = g_RelocFuncStruct.DoBlockLock;
memcpy(&g_CurrCmdStruct, (FMDHAL_CmdStruct *)pInVar, sizeof(struct FMDHAL_CmdStruct));
bRetVal = FMDHAL_ASM_CallFuncWithNewStack();
break;
default:
bRetVal = FALSE;
break;
}
if (!bRetVal)
LOGMSG(1, (TEXT("FMD:FMDHAL_IOControl: ERROR: command=x%08x, status=x%08x\r\n"), uCmd, last_status));
return(bRetVal);
}
BOOL FMDHAL_Init(volatile ULONG* pBaseAddress, ULONG uFlashLength)
{
/* Relocate Functions that take the flash offline */
FMDHAL_RelocateCode((ULONG *)FMDHAL_CFIQuery, (ULONG *)&g_RelocFuncStruct.CFIQuery,
(ULONG)FMDHAL_DoUnlockBlock - (ULONG)FMDHAL_CFIQuery);
FMDHAL_RelocateCode((ULONG *)FMDHAL_WriteCommand, (ULONG *)&g_RelocFuncStruct.WriteCommand,
(ULONG)FMDHAL_ReadStatus - (ULONG)FMDHAL_WriteCommand);
FMDHAL_RelocateCode((ULONG *)FMDHAL_ReadStatus, (ULONG *)&g_RelocFuncStruct.ReadStatus,
(ULONG)FMDHAL_IsInterruptPending - (ULONG)FMDHAL_ReadStatus);
FMDHAL_RelocateCode((ULONG *)FMDHAL_DoWrite, (ULONG *)&g_RelocFuncStruct.DoWrite,
(ULONG)FMDHAL_DoErase - (ULONG)FMDHAL_DoWrite);
FMDHAL_RelocateCode((ULONG *)FMDHAL_DoErase, (ULONG *)&g_RelocFuncStruct.DoErase,
(ULONG)FMDHAL_WriteCommand - (ULONG)FMDHAL_DoErase);
FMDHAL_RelocateCode((ULONG *)FMDHAL_IsInterruptPending, (ULONG *)&g_RelocFuncStruct.IsInterruptPending,
(ULONG)FMDHAL_CFIQuery - (ULONG)FMDHAL_IsInterruptPending);
FMDHAL_RelocateCode((ULONG *)FMDHAL_DoUnlockBlock, (ULONG *)&g_RelocFuncStruct.DoBlockUnlock,
(ULONG)FMDHAL_DoLockBlock - (ULONG)FMDHAL_DoUnlockBlock);
FMDHAL_RelocateCode((ULONG *)FMDHAL_DoLockBlock, (ULONG *)&g_RelocFuncStruct.DoBlockLock,
(ULONG)FMDHAL_RelocateCode - (ULONG)FMDHAL_DoLockBlock);
g_RelocFuncStruct.FMDHAL_ASMInterruptEnable = FMDHAL_ASMInterruptEnable;
g_RelocFuncStruct.FMDHAL_ASMInterruptDisable = FMDHAL_ASMInterruptDisable;
// Setup the Int Controller reg
// g_pIRQ_Address = (volatile BULVERDE_INTR_REG *) OALPAtoVA(BULVERDE_BASE_REG_PA_INTC, FALSE);
//run CFI
g_FMDHAL_FuncPtr = g_RelocFuncStruct.CFIQuery;
return(FMDHAL_ASM_CallFuncWithNewStack());
}
BOOL FMDHAL_DoWrite(void)
{
ULONG uWriteSize = g_CurrCmdStruct.uBytesToWrite;
volatile ULONG *pStartAddress = g_CurrCmdStruct.pTargetAddress;
volatile ULONG *pSrcBuffer = g_CurrCmdStruct.pWriteBufferPtr;
ULONG flash_status;
DWORD dwBusWidth;
DWORD dwWordCount;
DWORD k =0;
if (g_FMDConfig & FMDHAL_BusConfigx16)
{
dwBusWidth = sizeof(USHORT);
dwWordCount = (uWriteSize >> 0x1) -1;
} else
{
dwBusWidth = sizeof(ULONG);
dwWordCount = (uWriteSize >> 0x2) -1;
}
if (g_SWRWW_Enable == TRUE)
{
/* Disable interrupts */
g_RelocFuncStruct.FMDHAL_ASMInterruptDisable();
}
g_RelocFuncStruct.WriteCommand(pStartAddress, FMDHAL_FLASH_WRITE_BUFFER_CMD, g_FMDConfig);
while (!g_RelocFuncStruct.ReadStatus(pStartAddress, FMDHAL_FLASH_STATUS_READY, g_FMDConfig));
if (g_FMDConfig & FMDHAL_BusConfigx16)
{
PUSHORT pShortBuffer = (PUSHORT)g_CurrCmdStruct.pWriteBufferPtr;
g_RelocFuncStruct.WriteCommand(pStartAddress, dwWordCount, g_FMDConfig);
for (k = 0; k <uWriteSize;k += dwBusWidth)
{
*(volatile USHORT *)g_CurrCmdStruct.pTargetAddress = *pShortBuffer;
(USHORT)g_CurrCmdStruct.pTargetAddress+=sizeof(USHORT);
pShortBuffer++;
}
} else
{
PULONG pLongBuffer = g_CurrCmdStruct.pWriteBufferPtr;
g_RelocFuncStruct.WriteCommand(pStartAddress, dwWordCount, g_FMDConfig);
for (k = 0; k <uWriteSize;k += dwBusWidth)
{
*(volatile ULONG *)g_CurrCmdStruct.pTargetAddress = *pLongBuffer;
(ULONG)g_CurrCmdStruct.pTargetAddress+=sizeof(ULONG);
pLongBuffer++;
}
}
g_RelocFuncStruct.WriteCommand(pStartAddress, FMDHAL_FLASH_WRITE_CONFIRM, g_FMDConfig);
while (!g_RelocFuncStruct.ReadStatus(pStartAddress, FMDHAL_FLASH_STATUS_READY, g_FMDConfig));
//err check
// cnc fix formatting
flash_status = g_RelocFuncStruct.ReadStatus(pStartAddress, 0, g_FMDConfig);
if (flash_status & ~mFMDHAL_CmdCreate(g_FMDConfig, FMDHAL_FLASH_STATUS_READY))
{
g_RelocFuncStruct.WriteCommand(pStartAddress, FMDHAL_FLASH_CLEAR_STATUS, g_FMDConfig);
g_RelocFuncStruct.WriteCommand(pStartAddress, FMDHAL_FLASH_READ_ARRAY, g_FMDConfig);
if (g_SWRWW_Enable)
{
g_RelocFuncStruct.FMDHAL_ASMInterruptEnable();
}
return(FALSE);
}
g_RelocFuncStruct.WriteCommand(pStartAddress, FMDHAL_FLASH_READ_ARRAY, g_FMDConfig);
if (g_SWRWW_Enable)
{
g_RelocFuncStruct.FMDHAL_ASMInterruptEnable();
}
g_CurrCmdStruct.uBytesWritten = uWriteSize;
return(TRUE);
}
BOOL FMDHAL_DoErase(void)
{
volatile ULONG *pBlockAddress = (volatile ULONG *)g_CurrCmdStruct.pTargetAddress;
ULONG flash_status;
/* Do interrupts need to be disabled? */
if (g_SWRWW_Enable == TRUE)
{
/* Disable interrupts */
g_RelocFuncStruct.FMDHAL_ASMInterruptDisable();
}
/* Issue the erase command */
g_RelocFuncStruct.WriteCommand(pBlockAddress,
FMDHAL_FLASH_ERASE_CMD,
g_FMDConfig);
/* Issue the erase confirm commands */
g_RelocFuncStruct.WriteCommand(pBlockAddress,
FMDHAL_FLASH_ERASE_CONFIRM,
g_FMDConfig);
/* Wait for the erase to finish */
while (!g_RelocFuncStruct.ReadStatus(pBlockAddress, FMDHAL_FLASH_STATUS_READY, g_FMDConfig));
#if 0 /* Wait for the erase to finish */
while (!g_RelocFuncStruct.ReadStatus(pBlockAddress, FMDHAL_FLASH_STATUS_READY, g_FMDConfig))
{
if ((g_SWRWW_Enable == TRUE) && (g_RelocFuncStruct.IsInterruptPending() == TRUE))
{
g_RelocFuncStruct.WriteCommand(pBlockAddress, FMDHAL_FLASH_ERASE_SUSPEND, g_FMDConfig);
/* Wait for the erase to suspend */
while (!g_RelocFuncStruct.ReadStatus(pBlockAddress, FMDHAL_FLASH_STATUS_READY, g_FMDConfig));
if (!g_RelocFuncStruct.ReadStatus(pBlockAddress, FMDHAL_FLASH_ERASE_SUSPENDED, g_FMDConfig))
{
/* We are done */
break;
}
/* Check for Errors */
flash_status g_RelocFuncStruct.ReadStatus(pBlockAddress, 0, g_FMDConfig);
if (flash_status & ~mFMDHAL_CmdCreate(g_FMDConfig, FMDHAL_FLASH_STATUS_READY)
{
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);
}
/* put Flash back in Read Array Mode */
g_RelocFuncStruct.WriteCommand(pBlockAddress, FMDHAL_FLASH_READ_ARRAY, g_FMDConfig);
/* Re-enable interrupts */
g_RelocFuncStruct.FMDHAL_ASMInterruptEnable();
/* cnc - Do we need a reschedule here? */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?