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 + -
显示快捷键?