ethdown.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 914 行 · 第 1/3 页
C
914 行
/*
Copyright(c) 1998,1999 SIC/Hitachi,Ltd.
Module Name:
ethdown.c
Revision History:
26th April 1999 Released
*/
#include <windows.h>
#include <halether.h>
#include <pehdr.h>
#include <romldr.h>
#include "ethdown.h"
#include "platform.h"
extern ROMHDR RomHdr; // ROM Table of Contents structure
extern void DumpDwords(PDWORD pdw, int len);
// static EraseStatusType EraseStatus[TOTAL_FLASH_BLOCKS];
DWORD fWriteToFlash; // This flag indicates whether or not the data is being written to flash.
DWORD dwPhysStart; // image physical starting address
DWORD dwPhysLen; // image physical length
DWORD dwOffset;
DWORD dwLaunchAddr;
DWORD v_PacketNum;
DWORD v_FlashBlock;
BOOL bFirst=TRUE;
LPDWORD pdwRecStart=0, pdwRecNext=0; // saved record address, length and checksum pointers
void DumpDwords(PDWORD pdw, int len)
{
int lc;
lc = 0;
EdbgOutputDebugString("Dumpping %d dwords", len);
for (lc = 0 ; len ; ++pdw, ++lc, --len) {
if (!(lc & 3))
EdbgOutputDebugString("\r\n%X -", pdw);
EdbgOutputDebugString(" %X", *pdw);
}
EdbgOutputDebugString("\r\n");
}
#if ((SH_PLATFORM != PLATFORM_ASPEN)&&(SH_PLATFORM != PLATFORM_BIGSUR))
// If DIP switch S2-2 is set, writing impossible to FLASH (write protected).
UINT16 CheckFlashWriteProtect(void)
{
DWORD dwDIPs;
dwDIPs = READ_REGISTER_ULONG(0xA3E00000) & 0xFF;
// Polarity is reversed, so this is actually testing the "Off" position
if (dwDIPs & 2) {
return 0;
}
else {
EdbgOutputDebugString("Switch S2-2 on, writing impossible to FLASH.\r\n");
return 1;
}
}
void FlashWriteCommand(volatile DWORD *pdwReg, DWORD val)
{
*(pdwReg ) = val;
*(pdwReg+1) = val;
// EdbgOutputDebugString( "W (%Xh,%Xh)=%X%Xh\r\n",pdwReg,pdwReg+1,val,val);
}
// if (BSR & val) == 0 then TRUE else FLASE
DWORD FlashBSR0(volatile DWORD *pdwBSR, DWORD val)
{
DWORD dwBSR1, dwBSR2;
dwBSR1 = *(pdwBSR);
dwBSR2 = *(pdwBSR+1);
// EdbgOutputDebugString( "R BSR(%Xh,%Xh)=%X%Xh\r\n",pdwBSR,pdwBSR+1,dwBSR1,dwBSR2);
if(((dwBSR1 & val) == 0) && ((dwBSR2 & val) == 0))
return TRUE;
else
return FALSE;
}
// if (BSR & val) == val then TRUE else FLASE
DWORD FlashBSR1(volatile DWORD *pdwBSR, DWORD val)
{
DWORD dwBSR1, dwBSR2;
dwBSR1 = *(pdwBSR);
dwBSR2 = *(pdwBSR+1);
// EdbgOutputDebugString( "R BSR(%Xh,%Xh)=%X%Xh\r\n",pdwBSR,pdwBSR+1,dwBSR1,dwBSR2);
if(((dwBSR1 & val) == val) && ((dwBSR2 & val) == val))
return TRUE;
else
return FALSE;
}
// if (GSR & val) == 0 then TRUE else FLASE
DWORD FlashGSR0(volatile DWORD *pdwGSR, DWORD val)
{
DWORD dwGSR1, dwGSR2;
dwGSR1 = *(pdwGSR);
dwGSR2 = *(pdwGSR+1);
// EdbgOutputDebugString( "R GSR(%Xh,%Xh)=%X%Xh\r\n",pdwGSR,pdwGSR+1,dwGSR1,dwGSR2);
if(((dwGSR1 & val) == 0) && ((dwGSR2 & val) == 0))
return TRUE;
else
return FALSE;
}
// if (GSR & val) == val then TRUE else FLASE
DWORD FlashGSR1(volatile DWORD *pdwGSR, DWORD val)
{
DWORD dwGSR1, dwGSR2;
dwGSR1 = *(pdwGSR);
dwGSR2 = *(pdwGSR+1);
// EdbgOutputDebugString( "R GSR(%Xh,%Xh)=%X%Xh\r\n",pdwGSR,pdwGSR+1,dwGSR1,dwGSR2);
if(((dwGSR1 & val) == val) && ((dwGSR2 & val) == val))
return TRUE;
else
return FALSE;
}
// volatile UINT16 *pwCpuCsr = (UINT16 *)CPU_STATUS_BASE;
VOID
DisplayAlphaLED (DWORD Value)
{
// BOOL OldMode = SetKMode (TRUE);
*((DWORD *)LED_ALPHA) = Value;
// SetKMode (OldMode);
}
#endif ((SH_PLATFORM != PLATFORM_ASPEN)&&(SH_PLATFORM != PLATFORM_BIGSUR))
DWORD VerifyCheckSum(void)
{
DWORD dwRecordLen; // Total length of the record being processed
DWORD dwRecordAddr; // starting address of the record
DWORD dwPerfectCRC; // Theoretical CRC over the record being processed
DWORD dwPartialCRC; // Running CRC over the record being processed
DWORD dwCurDataWord; // Usually, this is the data word at the current position within the
BYTE *pbCRC; // Pointer used to run through memory to calculate CRC
DWORD i;
if (!pdwRecNext)
return 0;
EdbgOutputDebugString( "Verify checksums...\r\n");
*pdwRecNext++=0;
*pdwRecNext++=0;
*pdwRecNext++=0;
pdwRecNext=pdwRecStart;
do {
dwRecordAddr=dwCurDataWord=*pdwRecNext++;
dwRecordLen=*pdwRecNext++;
dwPerfectCRC=*pdwRecNext++;
if (dwRecordAddr && dwPerfectCRC) {
if (fWriteToFlash) {
// Offset the start address so that flash data is written to the FlashCache[]
dwCurDataWord = (dwCurDataWord & 0x0FFFFFFFUL) - (dwPhysStart & 0x0FFFFFFFUL);
pbCRC = (BYTE *)(FLASH_CACHE + dwCurDataWord);
}
else {
pbCRC = (BYTE *)dwCurDataWord;
}
// Check the CRC
dwPartialCRC = 0;
for( i = 0; i < dwRecordLen; i++ )
dwPartialCRC += *pbCRC++;
if (dwPartialCRC != dwPerfectCRC) {
EdbgOutputDebugString( "Checksum Error Addr %Xh Len %Xh Expected %Xh Calculated %Xh\r\n",
dwRecordAddr, dwRecordLen, dwPerfectCRC, dwPartialCRC);
return 1;
}
}
} while (dwRecordAddr && dwPerfectCRC);
EdbgOutputDebugString( "Checksums verified correct.\r\n");
return 0;
}
UINT16 EthDown( char *pszFileName, TFtpdCallBackOps Operation, BYTE *pbData, UINT16 *cwLength, char **ppszErrorMsg )
{
static BINFileParseStates BINFileParseState;
// Because the signature of the BIN file is 7 bytes long and the length of a TFTP data packet
// is typically 512 bytes long, it is very probable that the last 4 byte DWORD will be broken
// across two TFTP packets. I use these two variables to store the broken DWORD.
static DWORD dwDataTailFromLastPacket; // The beginning of the broken DWORD that has been
// retained from the last packet.
static BYTE bNumBytesInDataTail; // The number of bytes that have been carried over from
// the last packet. Note that these are numbered starting
// from low byte to high byte because this is little endian.
// DANGER - This may not be true on all processors.
DWORD UNALIGNED *pdwBuffer; // Pointer to current data position within the current TFTP packet
int iBufferPos; // Position of processing within the pbData packet buffer
DWORD dwCurDataWord; // Usually, this is the data word at the current position within the
// TFTP packet. However, in order to compensate for the 7 byte preamble
// misalignment, this word may be "doctored" at the beginning of parsing
// a packet in order to include carry over byte(s) from the last packet.
static DWORD UNALIGNED *pdwDest; // Pointer to the address that the data is to be written too.
static DWORD dwRecordLen; // Total length of the record being processed
static DWORD dwRecordPos; // Position of processing within the record being processed
static DWORD dwRecordAddr; // starting address of the record
static DWORD dwROMHDRAddr; // table of contents address
static DWORD dwPerfectCRC; // Theoretical CRC over the record being processed
static BYTE *pbCRC; // Pointer used to run through memory to calculate CRC
DWORD dwPartialCRC; // Running CRC over the record being processed
DWORD i;
switch( Operation ) {
case TFTPD_OPEN:
// EdbgOutputDebugString( "EthDown::TFTPD_OPEN::%s\r\n", pszFileName );
dwPhysLen = 0;
break;
case TFTPD_READ:
*cwLength = 0;
// EdbgOutputDebugString( "EthDown::TFTPD_READ::%s returning %u bytes\r\n", pszFileName, *cwLength );
break;
case TFTPD_WRITE:
// EdbgOutputDebugString( "EthDown::TFTPD_WRITE::%s with %u bytes\r\n", pszFileName, *cwLength );
// EdbgOutputDebugString( "EthDown::TFTPD_WRITE::dwPhysLen=0x%x, v_PacketNum=%d\r\n", dwPhysLen, v_PacketNum );
iBufferPos = 0;
pdwBuffer = (DWORD *)pbData;
if (dwPhysLen == 0) {
v_PacketNum = 0;
} else {
v_PacketNum++;
}
#if ((SH_PLATFORM != PLATFORM_ASPEN)&&(SH_PLATFORM != PLATFORM_BIGSUR))
DisplayAlphaLED (MAKELONG(v_PacketNum, v_FlashBlock));
#endif ((SH_PLATFORM != PLATFORM_ASPEN)&&(SH_PLATFORM != PLATFORM_BIGSUR))
// If this is the beginning of the file
if (dwPhysLen == 0) {
if (memcmp( pbData, "B000FF\x0A", 7 )) {
EdbgOutputDebugString( "EthDown::TFTPD_WRITE::This isn't a .BIN file.\r\n" );
*ppszErrorMsg = "File Is Not .BIN Format";
return 1;
}
// I need to DWORD align the rest of the data so that the DWORD accesses won't cause
// processor exceptions
*cwLength -= 7;
pdwBuffer = (DWORD UNALIGNED *) (pbData + 7); // memmove( pbData, pbData + 7, *cwLength );
dwPhysStart = *pdwBuffer++;
dwOffset=0;
dwPhysLen = *pdwBuffer++;
iBufferPos = 8;
EdbgOutputDebugString("\r\nImage start 0x%X length 0x%X\r\n", dwPhysStart, dwPhysLen );
bNumBytesInDataTail = 0;
BINFileParseState = BIN_PHYSADDR;
dwROMHDRAddr=0;
RomHdr.physfirst=-1;
EdbgOutputDebugString( "FLASH_START_ERASE dwPhysStart %X dwPhysEnd %X\r\n", dwPhysStart, dwPhysStart + dwPhysLen);
fWriteToFlash = IsFlash(dwPhysStart, dwPhysLen);
if (fWriteToFlash) {
EdbgOutputDebugString( "FLASH_START_ERASE Is Flash\r\n" );
dwPhysStart = (dwPhysStart & 0x0FFFFFFFUL) | 0xA0000000UL;
pdwRecStart=pdwRecNext=(LPDWORD)(FLASH_CACHE+dwPhysLen);
// Cleaning of the RAM buffer is not required. The code is present here just for the time being.
#if 0
// Clean the RAM buffer for writing the Flash image.
{
int i;
i = dwPhysStart | FLASH_CACHE;
for(; i < dwPhysLen; i += 4) {
*(volatile unsigned *)i = 0x0;
}
}
#endif 0
}
else {
pdwRecStart=pdwRecNext=(LPDWORD)(dwPhysStart+dwPhysLen-dwOffset);
EdbgOutputDebugString( "FLASH_START_ERASE Not Flash\r\n" );
}
}
// Check to see if this is the last packet and it's empty
else if (*cwLength == 0)
return 0;
// Pull the rest of the 32-bit data word that was started in the last packet
if (bNumBytesInDataTail) {
dwCurDataWord = 0;
for( i = 0; i < 4UL-bNumBytesInDataTail; i++ )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?