📄 flash.c
字号:
//
// 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 (C) 2004, Motorola Inc. All Rights Reserved
//
//-----------------------------------------------------------------------------
//
// Copyright (C) 2004-2006, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//-----------------------------------------------------------------------------
//
// File: flash.c
//
// Contains all the flash routines that are called by BLCOMMON.
//
//-----------------------------------------------------------------------------
#include <windows.h>
#include <nkintr.h>
#include <blcommon.h>
#include <ethdbg.h>
#include <halether.h>
#include "loader.h"
#include "nor.h"
//------------------------------------------------------------------------------
// Defines
#define FLASH_START FLASH_CVBASE
#define FLASH_LENGTH 0x04000000
//------------------------------------------------------------------------------
//
// Function: OEMIsFlashAddr
//
// This function is called by BLCOMMON to check whether an address is a flash
// address.
//
// Parameters:
// dwAddr
// [in] Address that needs to be checked
//
// Returns:
// TRUE - if the address is a flash address
// FALSE - if the address is not a flash address
//
//------------------------------------------------------------------------------
BOOL OEMIsFlashAddr (DWORD dwAddr)
{
// Does the specified address fall in the flash address range?
if ((dwAddr >= FLASH_START) && (dwAddr < (FLASH_START + FLASH_LENGTH)))
return TRUE;
return FALSE;
}
//------------------------------------------------------------------------------
//
// Function: OEMMapMemAddr
//
// This function is called by BLCOMMON to map a temporary cache space in RAM for
// download while the slower flash erase is being done.
//
// Parameters:
// dwImageStart
// [in] The start of the image.
// dwAddr
// [in] The address to be mapped.
//
// Returns:
// dwAddr - the cache address.
//
//------------------------------------------------------------------------------
LPBYTE OEMMapMemAddr (DWORD dwImageStart, DWORD dwAddr)
{
extern DWORD g_dwMinImageStart;
if (!g_dwMinImageStart)
g_dwMinImageStart = dwImageStart;
if (OEMIsFlashAddr(dwAddr)) {
//
// This image is destined for flash, cache it in RAM temporarily.
//
//dwAddr -= dwImageStart;
dwAddr -= FLASH_CVBASE;
dwAddr += EBOOT_FCACHE_START;
}
// TODO: Find out if this code is no longer necessary.
// - if executed this causes an error during XIP boot from RAM
// This is needed in order to be able to download and store RAM eboot image
// into NAND.
#if 1
else {
// Ram image. Check if within flash cache range. cache it in
// flash cache region if not.
if (dwAddr >= RAM_CVBASE && dwAddr < EBOOT_FCACHE_START) {
dwAddr -= RAM_CVBASE;
dwAddr += EBOOT_FCACHE_START;
}
}
#endif
return((LPBYTE) dwAddr);
}
//------------------------------------------------------------------------------
//
// Function: OEMStartEraseFlash
//
// This function is called by BLCOMMON to setup flash erase operation by
// calculating the num of blocks needs to be erased currently it's just a stub.
//
// Parameters:
// None.
//
// Returns:
// TRUE
//
//------------------------------------------------------------------------------
BOOL OEMStartEraseFlash (DWORD dwStartAddr, DWORD dwLength)
{
OALMSG(OAL_FUNC, (TEXT("OEMStartEraseFlash 0X%08x 0x%08X\r\n"), dwStartAddr, dwLength));
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: OEMContinueEraseFlash
//
// This function is called by BLCOMMON to erase the flash region needed by
// the image.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void OEMContinueEraseFlash(void)
{
OALMSG(OAL_FUNC, (TEXT("OEMContinueEraseFlash\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: OEMFinishEraseFlash
//
// This function is called by BLCOMMON to erase the rest of the flash region
// since the download is completed.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
BOOL OEMFinishEraseFlash(void)
{
OALMSG(OAL_FUNC, (TEXT("OEMFinishEraseFlash\r\n")));
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: OEMWriteFlash
//
// This function is called by BLCOMMON to write the newly downloaded image
// from the cached region in RAM.
//
// Parameters:
// dwStartAddr
// [in] The start address.
// dwLength
// [in] The length.
//
// Returns:
// TRUE.
//
//------------------------------------------------------------------------------
BOOL OEMWriteFlash(DWORD dwStartAddr, DWORD dwLength)
{
CHAR selection;
BOOL bIsPaired;
ULONG ulDeviceWidth;
DWORD dwBusWidth;
DWORD dwEraseLen;
OALMSG(OAL_INFO, (TEXT("\nFlash Programming is about to start!\r\n")));
OALMSG(OAL_INFO, (TEXT("Image Start: 0x%08X Length: 0x%08X\r\n"), dwStartAddr, dwLength));
OALMSG(OAL_INFO, (TEXT("Hit \"F\" to proceed! ")));
while (1) {
selection = OEMReadDebugByte();
if (selection == 'F') {
OEMWriteDebugByte(selection);
OEMWriteDebugByte('\r');
OEMWriteDebugByte('\n');
break;
}
}
// Init NOR flash library. No need to relocate since EBOOT is running in RAM
if (!NORLibInit((ULONG)OALCAtoUA(FLASH_START), 0, 0)) {
OALMSG(OAL_ERROR, (TEXT("ERROR: Init NOR flash driver failed.\r\n")));
return FALSE;
}
// Get Flash device and bus width
if (!NORGetDeviceWidth(&bIsPaired, &ulDeviceWidth)) {
OALMSG(OAL_ERROR, (TEXT("ERROR: Cannot get device and bus width information.\r\n")));
return FALSE;
}
dwBusWidth = bIsPaired ? (2 * (ulDeviceWidth >> 3)) : (ulDeviceWidth >> 3);
// Enable progress indicator every 64kB.
NORShowProgress(TRUE, 0x10000);
// Erash the region
OALMSG(OAL_INFO, (TEXT("Erasing flash...\r\n")));
dwEraseLen = NORErase((ULONG)OALCAtoUA(dwStartAddr), (ULONG)dwLength);
if (!dwEraseLen) {
OALMSG(OAL_ERROR, (TEXT("ERROR: Erasing flash failed.\r\n")));
return FALSE;
}
OALMSG(OAL_INFO, (TEXT("Erase completed! Erased length: 0x%x\r\n"), dwEraseLen));
OALMSG(OAL_INFO, (TEXT("Programming flash...\r\n")));
// Align data length to bus width
if (!NORProgram((ULONG)OALCAtoUA(dwStartAddr), (UCHAR *)(OEMMapMemAddr(dwStartAddr, dwStartAddr)),
(ULONG)(((dwLength + 1) / dwBusWidth) * dwBusWidth), FALSE)) {
OALMSG(OAL_ERROR, (TEXT("ERROR: Programming flash failed.\r\n")));
return FALSE;
}
OALMSG(OAL_INFO, (TEXT("Programming completed! Verifying Flash...\r\n")));
if (!NORVerifyData(dwStartAddr, OEMMapMemAddr(dwStartAddr, dwStartAddr),
(ULONG)(((dwLength + 1) / dwBusWidth) * dwBusWidth)) != 0) {
OALMSG(OAL_INFO, (TEXT("ERROR: Verification failed.\r\n")));
return FALSE;
}
else
OALMSG(OAL_INFO, (TEXT("INFO: Verification passed.\r\n")));
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -