📄 flash.c
字号:
//**********************************************************************
//
// Filename: flash.c
//
// Description: Contains the CE flash routines.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Use of this source code is subject to the terms of the Cirrus 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
// EULA.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2002, All Rights Reserved
//
//**********************************************************************
#include <windows.h>
#include <memorymap.h>
#include <hwdefs.h>
#include <halether.h>
#include "intel_j3_2x16.h"
#include "flash.h"
//
// Function pointer to Flash routines.
//
static PFN_START_ERASE_FLASH pfnStartErase = 0;
static PFN_CONTINUE_ERASE_FLASH pfnContinueErase = 0;
static PFN_FINISH_ERASE_FLASH pfnFinishErase = 0;
static PFN_WRITE_FLASH pfnWriteFlash = 0;
//****************************************************************************
// OEMIsFlashAddr
//****************************************************************************
// dwAddr - Address of a BIN file record. This is the address checked to see
// whether it lies in flash or RAM.
//
// return TRUE - SUCESS
// FALSE - ERROR
//
BOOL OEMIsFlashAddr (DWORD dwAddr)
{
BOOL bReturnValue = FALSE;
if(PHYSICAL_ADDR_FLASH_INTEL <= dwAddr &&
dwAddr < (PHYSICAL_ADDR_FLASH_INTEL + SIZE_FLASH_INTEL))
{
bReturnValue = TRUE;
}
return bReturnValue;
}
//****************************************************************************
// OEMMapMemAddr
//****************************************************************************
// dwImageStart - Start address of image.
//
// dwAddr - Address of a BIN record. If this address lies in a
// platforms flash address space, typically the offset
// from dwImageStart is computed and added to a RAM-based file
// cache area.
//
// Return Values Address at which the BIN record should be copied to
// provide file caching before and during the flash update
// process.
//
LPBYTE OEMMapMemAddr
(
DWORD dwImageStart,
DWORD dwAddr
)
{
LPBYTE pReturnValue;
if(OEMIsFlashAddr(dwImageStart))
{
pReturnValue = (LPBYTE)( (dwAddr - FLASH_VIRTUAL_MEMORY) + FLASH_CACHE_PHYSICAL_MEMORY );
}
//
// Hack hack hack. Looks like eboot thinks that this is the wrong address.
//
else if((0x80000000 < dwAddr) && (dwAddr < 0x84000000 ))
{
pReturnValue = (LPBYTE)(dwAddr & 0x7FFFFFFF);
}
else
{
pReturnValue = (LPBYTE)(dwAddr);
}
//EdbgOutputDebugString
//(
// "OEMMapMemAddr: dwImageStart = 0x%x, dwAddr= 0x%x, pReturnValue = 0x%x\n",
// dwImageStart,
// dwAddr,
// (ULONG)pReturnValue
//);
return pReturnValue;
}
//****************************************************************************
// OEMStartEraseFlash
//****************************************************************************
// dwStartAddr - Start address, in flash, to start erasing from. The
// platform loader code needs to ensure this is a flash
// block-aligned address or needs to handle it specially if
// it is not.
//
// dwLength - Number of bytes of flash to be erased.
//
// return TRUE indicates success. FALSE indicates failure.
//
BOOL OEMStartEraseFlash (DWORD dwStartAddr, DWORD dwLength)
{
ULONG i = 0;
ULONG nNumBlocks = 0;
ULONG ulSMC;
//
// Make sure the start and end addresses are in flash.
//
if (!OEMIsFlashAddr(dwStartAddr) || !OEMIsFlashAddr(dwStartAddr + dwLength - 1))
{
EdbgOutputDebugString
(
"ERROR: OEMStartEraseFlash - not a flash address (0x%x or 0x%x).\r\n",
dwStartAddr,
(dwStartAddr + dwLength - 1)
);
return(FALSE);
}
//
// Make sure start address is block-aligned.
//
//if (dwStartAddr % FLASH_BLOCK_SIZE)
//{
// EdbgOutputDebugString("ERROR: OEMStartEraseFlash - start address isn't block aligned (0x%x).\r\n", dwStartAddr);
// return(FALSE);
//}
if (dwLength & 0x03)
{
EdbgOutputDebugString
(
"ERROR: OEMStartEraseFlash - length isn't an integral number of longwords (0x%x).\r\n",
dwLength
);
return(FALSE);
}
EdbgOutputDebugString("Erasing flash blocks: start Addr = 0x%x length = 0x%x\r\n", dwStartAddr, dwLength);
//
// Clear the Flash write protect for chip select 6.
//
ulSMC = *SMC_SMCBCR6;
ulSMC |= SMCBCR_WPERR;
ulSMC &= ~SMCBCR_WP;
*SMC_SMCBCR6 = ulSMC ;
//
// Fill in the pointers for the following.
//
pfnStartErase = StartEraseFlashJ3_2x16;
pfnContinueErase = ContinueEraseFlashJ3_2x16;
pfnFinishErase = FinishEraseFlashJ3_2x16;
pfnWriteFlash = WriteFlashJ3_2x16;
return(pfnStartErase(dwStartAddr, dwLength));
}
//****************************************************************************
// OEMContinueEraseFlash
//****************************************************************************
//
//
//
void OEMContinueEraseFlash (void)
{
if(pfnContinueErase)
pfnContinueErase();
}
//****************************************************************************
// OEMFinishEraseFlash
//****************************************************************************
//
//
//
BOOL OEMFinishEraseFlash (void)
{
BOOL bSuccess = FALSE;
EdbgOutputDebugString("Continue to Erase the rest of Flash.\r\n" );
//
// Finish erasing the flash.
//
if(pfnFinishErase)
{
bSuccess = pfnFinishErase();
}
if(bSuccess)
{
EdbgOutputDebugString("\r\nFlash Erase Successfully Finished\r\n" );
}
else
{
EdbgOutputDebugString("\r\nERROR: Error while erasing flash\r\n" );
}
return bSuccess;
}
//****************************************************************************
// OEMWriteFlash
//****************************************************************************
// dwStartAddr - Address in flash where the start of the downloaded image
// is to be written. Note that if this is not a flash
// block-aligned address, the platform code will need
// to take this into account and handle it as a special
// case.
//
// dwLength - Length of the image, in bytes, to be written to flash.
//
//
BOOL OEMWriteFlash (DWORD dwStartAddr, DWORD dwLength)
{
ULONG ulSMC;
ULONG ulCount;
BOOL bSuccess = TRUE;
PULONG pulSource, pulDest;
EdbgOutputDebugString
(
"Writing to flash at Address= 0x%x, Length = 0x%x\r\n",
dwStartAddr,
dwLength
);
//
// Check to make sure that the flash routine exists.
//
if(!pfnWriteFlash)
{
bSuccess = FALSE;
}
//
// Make sure the start and end addresses are in flash.
//
if(bSuccess)
{
if (!OEMIsFlashAddr(dwStartAddr) || !OEMIsFlashAddr(dwStartAddr + dwLength - 1))
{
EdbgOutputDebugString
(
"ERROR: OEMWriteFlash - not a flash address (0x%x or 0x%x).\r\n",
dwStartAddr,
(dwStartAddr + dwLength - 1)
);
bSuccess = FALSE;
}
}
//
// Perform a quick check to make sure that the flash is erased.
//
if(bSuccess)
{
pulDest =(PULONG) dwStartAddr;
for(ulCount = 0; ulCount < (dwLength>>2) ; ulCount++)
{
if(*pulDest != 0xFFFFFFFF)
{
EdbgOutputDebugString
(
"ERROR: OEMWriteFlash - Flash not erased at location = 0x%x, value = 0x%x \r\n",
(ULONG)pulDest,
*pulDest
);
bSuccess = FALSE;
while(1);
break;
}
pulDest++;
}
}
//
// Write the flash
//
if(pfnWriteFlash && bSuccess)
{
bSuccess = pfnWriteFlash( dwStartAddr, FLASH_CACHE_VIRTUAL_MEMORY ,dwLength);
}
//
// Clear the Flash write protect for chip select 6.
//
ulSMC = *SMC_SMCBCR6;
*SMC_SMCBCR6 = ulSMC | SMCBCR_WP | SMCBCR_WPERR ;
//
// Check to make sure that the image has been flashed correctly.
//
if(bSuccess)
{
pulSource = (PULONG) FLASH_CACHE_VIRTUAL_MEMORY;
pulDest = (PULONG) dwStartAddr;
for(ulCount = 0; ulCount < (dwLength>>2) ; ulCount++)
{
if(*pulSource != *pulDest)
{
EdbgOutputDebugString
(
"ERROR: OEMWriteFlash - Miscompare at pSource = 0x%x, pDest = 0x%x, 0x%x != 0x%x \r\n",
(ULONG)pulSource,
(ULONG)pulDest,
*pulSource,
*pulDest
);
bSuccess = FALSE;
break;
}
pulSource++;
pulDest++;
}
}
return bSuccess;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -