📄 intelj3_1x16.c
字号:
//**********************************************************************
//
// Filename: intelj3_1x16.c
//
// Description: Flashing program for intel j3. One j3 flash chips
// in 16 bit mode.
//
// 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
// LICENSE.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2002, All Rights Reserved
//
//**********************************************************************
#include <windows.h>
#include <hwdefs.h>
#include <halether.h>
#include <debugtimer.h>
#include "intelj3_1x16.h"
//
// Definitions for Flash erasing.
//
#define FLASH_BLOCK_SIZE 0x20000
#define FLASH_BLOCK_MASK ~(FLASH_BLOCK_SIZE - 1)
#define FLASH_BUFFER_SIZE 32
#define FLASH_READ_MODE 0x00FF
#define FLASH_BLOCK_ERASE 0x0020
#define FLASH_CLEAR_STATUS 0x0050
#define FLASH_BLOCK_ERASE_RESUME 0x00d0
#define FLASH_BLOCK_PROGRAM_RESUME 0x00d0
#define FLASH_WRITE_TO_BUFFER 0x00E8
#define FLASH_READ_STATUS 0x0070
#define FLASH_LOCK_BIT 0x0060
#define FLASH_LOCK_SET 0x0001
#define FLASH_LOCK_CLEAR 0x00d0
#define STATUS_WRITE_READY 0x0080
#define EXT_STATUS_WBUFFER_READY 0x0080
static DWORD gdwStartAddr = 0;
static DWORD gdwLength = 0;
static volatile PUSHORT gpusCurAddr = 0;
static BOOL gbFlashEraseComplete = FALSE;
static BOOL gbUnlocked = TRUE;
//
// Private functions.
//
static BOOL WaitForReady(volatile USHORT *pusFlash, ULONG ulTimeoutInMsec, USHORT ulBitField);
//****************************************************************************
// StartEraseFlashJ3_1x16
//****************************************************************************
// 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 StartEraseFlashJ3_1x16(DWORD dwStartAddr, DWORD dwLength)
{
//
// Make sure that the flash addresses are valid.
//
if(dwStartAddr + dwLength >FLASH_VIRTUAL_MEMORY + FLASH_SIZE ||
dwStartAddr < FLASH_VIRTUAL_MEMORY )
{
EdbgOutputDebugString
(
"ERROR: No Flash located in the locations from %x to %xr\r\n",
dwStartAddr,
dwLength
);
return FALSE;
}
//
// Check to make sure that the flash is on a Block boundary.
//
if(dwStartAddr & (FLASH_BLOCK_SIZE - 1))
{
EdbgOutputDebugString
(
"ERROR: Address %x is not on a flash block boundary.\r\n",
dwStartAddr
);
return FALSE;
}
//
// Save off the start address and the length.
//
gdwStartAddr = dwStartAddr;
gdwLength = dwLength;
gpusCurAddr = (PUSHORT) dwStartAddr;
//
// Put the flash in read mode to make sure that we are not in the middle
// of a command.
//
*gpusCurAddr = FLASH_READ_MODE;
//
// Clear the lock bit.
//
*gpusCurAddr = FLASH_LOCK_BIT;
*gpusCurAddr = FLASH_LOCK_CLEAR;
*gpusCurAddr = FLASH_READ_STATUS;
gbUnlocked = TRUE;
return TRUE;
}
//****************************************************************************
// ContinueEraseFlashJ3_1x16
//****************************************************************************
// Continues the flash erasing processes for J3 Flash. See
// OEMContinueEraseFlash for Parameter description.
//
//
void ContinueEraseFlashJ3_1x16(void)
{
//
// Check to see if the flash has been completely erased. If so just
// return.
//
if(gbFlashEraseComplete)
{
return;
}
//
// Check to see if the last block has been erased.
//
if((*gpusCurAddr & EXT_STATUS_WBUFFER_READY) != EXT_STATUS_WBUFFER_READY)
{
return;
}
//
// Clear Status.
//
*gpusCurAddr = FLASH_CLEAR_STATUS;
if(gbUnlocked)
{
//
// Erase the flash block
//
*gpusCurAddr = FLASH_BLOCK_ERASE;
*gpusCurAddr = FLASH_BLOCK_ERASE_RESUME;
//
// Read erase status.
//
*gpusCurAddr = FLASH_READ_STATUS;
gbUnlocked = FALSE;
}
else
{
//
// Check to see if we have finished erasing the flash memory.
//
if(gdwStartAddr + gdwLength < ((DWORD)gpusCurAddr) + FLASH_BLOCK_SIZE)
{
gbFlashEraseComplete = TRUE;
return;
}
//
// Advance to the next block.
//
gpusCurAddr+= FLASH_BLOCK_SIZE>>1;
//
// Clear the lock bits if the flash block was locked.
//
*gpusCurAddr = FLASH_LOCK_BIT;
*gpusCurAddr = FLASH_LOCK_CLEAR;
*gpusCurAddr = FLASH_READ_STATUS;
gbUnlocked = TRUE;
}
}
//****************************************************************************
// FinishEraseFlashJ3_1x16
//****************************************************************************
// Finishes the flash eraseing processes for J3 Flash. See
// OEMFinishEraseFlash for paramter description.
//
BOOL FinishEraseFlashJ3_1x16 (void)
{
BOOL bSuccess;
//
// Check to see if the flash has been completely erased. If so just
// return.
//
if(gbFlashEraseComplete)
{
return TRUE;
}
//
// Wait for the Flash block command to succed.
//
bSuccess = WaitForReady(gpusCurAddr, 10000, EXT_STATUS_WBUFFER_READY);
if(bSuccess == FALSE)
{
return FALSE;
}
*gpusCurAddr = FLASH_CLEAR_STATUS;
//
// Erase the block before unlocking the next block.
//
if(gbUnlocked)
{
//
// Erase the flash block
//
*gpusCurAddr = FLASH_BLOCK_ERASE;
*gpusCurAddr = FLASH_BLOCK_ERASE_RESUME;
//
// Read erase status.
//
*gpusCurAddr = FLASH_READ_STATUS;
//
// Wait for the Flash block command to succed.
//
bSuccess = WaitForReady(gpusCurAddr, 10000, EXT_STATUS_WBUFFER_READY);
if(bSuccess == FALSE)
{
return FALSE;
}
*gpusCurAddr = FLASH_CLEAR_STATUS;
gbUnlocked = FALSE;
//
// Increment to the next block.
//
gpusCurAddr += FLASH_BLOCK_SIZE>>1;
}
//
// Erase the Flash
//
while((DWORD)gpusCurAddr < (gdwStartAddr + gdwLength))
{
//
// Clear the lock bits if the flash block was locked.
//
*gpusCurAddr = FLASH_LOCK_BIT;
*gpusCurAddr = FLASH_LOCK_CLEAR;
*gpusCurAddr = FLASH_READ_STATUS;
//
// Wait for the Flash block command to succed.
//
bSuccess = WaitForReady(gpusCurAddr, 10000, EXT_STATUS_WBUFFER_READY);
*gpusCurAddr = FLASH_CLEAR_STATUS;
if(!bSuccess)
{
break;
}
//
// Erase the flash block
//
*gpusCurAddr = FLASH_BLOCK_ERASE;
*gpusCurAddr = FLASH_BLOCK_ERASE_RESUME;
*gpusCurAddr = FLASH_READ_STATUS;
//
// Wait for the Flash block command to succed.
//
bSuccess = WaitForReady(gpusCurAddr, 10000, EXT_STATUS_WBUFFER_READY);
*gpusCurAddr = FLASH_CLEAR_STATUS;
if(!bSuccess)
{
break;
}
//
// Occasionally write out a dot so they don't think
// the system is dead.
//
EdbgOutputDebugString(".");
//
// Increment to the next block.
//
gpusCurAddr += FLASH_BLOCK_SIZE>>1;
}
return bSuccess;
}
//****************************************************************************
// WriteFlashJ3_1x16
//****************************************************************************
// Writes to J3 Flash. Different from parameters than OEMWriteFlash.
//
// dwDest - 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.
//
// dwSource - Location of the Flash Cache.
//
// dwLength - Length of the image, in bytes, to be written to flash.
//
//
BOOL WriteFlashJ3_1x16(DWORD dwDest, DWORD dwSource, DWORD dwLength)
{
ULONG ulCount;
ULONG ulEndCount;
volatile PUSHORT pusBlockAddress;
volatile PUSHORT pusDest, pusSource;
USHORT usWordsToWrite;
ULONG ulStart,ulCurrent;
BOOL bSuccess;
ULONG ulAddDelay;
ulCount = 0;
pusDest = (PUSHORT)dwDest;
pusSource = (PUSHORT)dwSource;
while( ulCount < dwLength)
{
//
// Calculate the block address
//
pusBlockAddress = (USHORT *)(((ULONG)&pusDest[ulCount>>1]) & FLASH_BLOCK_MASK);
//
// Write the Flash to buffer command until the flash is ready.
//
ulStart = GetSystemTimeInMsec();
ulAddDelay = 1;
do
{
*pusBlockAddress = FLASH_WRITE_TO_BUFFER;
//
// Check to make sure that we are not in a loop.
//
ulCurrent = GetSystemTimeInMsec();
if(ulStart + 1000 <ulCurrent)
{
EdbgOutputDebugString("FLASH_WRITE_TO_BUFFER - Failed\n.");
EdbgOutputDebugString("pusBlockAddress = %x.\n",(ULONG)pusBlockAddress);
EdbgOutputDebugString("*pusBlockAddress = %x.\n",(ULONG)*pusBlockAddress);
*pusBlockAddress = FLASH_READ_STATUS;
EdbgOutputDebugString("*FLASH_READ_STATUS pusBlockAddress = %x.\n",(ULONG)*pusBlockAddress);
while(1);
return FALSE;
}
}
while((*pusBlockAddress & EXT_STATUS_WBUFFER_READY)!= EXT_STATUS_WBUFFER_READY);
//
// Program the Flash size to be written.
//
usWordsToWrite = (FLASH_BUFFER_SIZE - 1)>>1;
*pusBlockAddress = usWordsToWrite;
ulEndCount = ulCount + FLASH_BUFFER_SIZE;
do
{
pusDest[ulCount>>1] = pusSource[ulCount>>1];
ulCount += sizeof(USHORT);
} while(ulCount < ulEndCount);
//
// End of programming the block.
//
*pusBlockAddress = FLASH_BLOCK_PROGRAM_RESUME;
//
// Occasionally write out a dot so they don't think
// the system is dead.
//
if(((ULONG)&pusDest[ulCount>>1] & (FLASH_BLOCK_SIZE - 1)) == 0)
{
EdbgOutputDebugString(".");
}
//
// Wait for the Flash block command to succed.
//
bSuccess = WaitForReady(pusBlockAddress, 6000, EXT_STATUS_WBUFFER_READY);
if(!bSuccess)
{
EdbgOutputDebugString("FLASH_BLOCK_PROGRAM_RESUME - Failed\n.");
EdbgOutputDebugString("pulBlockAddress = %x.\n",(ULONG)pusBlockAddress);
EdbgOutputDebugString("*pulBlockAddress = %x.\n",(ULONG)*pusBlockAddress);
*pusBlockAddress = FLASH_READ_STATUS;
EdbgOutputDebugString("*FLASH_READ_STATUS pulBlockAddress = %x.\n",(ULONG)*pusBlockAddress);
while(1);
break;
}
}
*pusBlockAddress = FLASH_READ_MODE;
return TRUE;
}
//****************************************************************************
// WaitForReady
//****************************************************************************
// Wait until the flash is ready.
//
//
static BOOL WaitForReady
(
volatile USHORT *pusFlash,
ULONG ulTimeoutInMsec,
USHORT usBitField
)
{
ULONG ulStart;
ULONG ulCurrent;
BOOL bSuccess = FALSE;
ulStart = GetSystemTimeInMsec();
do
{
//
// See if there are errors.
//
if((*pusFlash & usBitField)== usBitField)
{
bSuccess = TRUE;
break;
}
//
// Get the current time.
//
ulCurrent = GetSystemTimeInMsec();
} while(ulCurrent<ulStart + ulTimeoutInMsec);
if(!bSuccess)
{
EdbgOutputDebugString("*pusFlash = %x .\n",(ULONG)*pusFlash);
}
return bSuccess;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -