main.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 856 行 · 第 1/3 页

C
856
字号
/*

  Copyright(c) 1998,1999 SIC/Hitachi,Ltd.

	Module Name:

		main.c

	Revision History:

		26th April		1999		Released
		29th June		1999		Modified default launch address 
		12th October	1999		Fixed minor bug

*/

#include <windows.h>
#include <ethdbg.h>
#include <nkintr.h>
#include <pehdr.h>
#include <romldr.h>
#include <oemfw.h>

#include "shx.h"
#include "platform.h"
#include "drv_glob.h"

//#include "loader.h"
#include "ethdown.h"
#include "rev.h"

#if 1
#define MACADDR0 0x0000
#define MACADDR1 0x0000
#define MACADDR2 0x0000
#else
/* 00:00:E1:0C:50:FF */
#define MACADDR0 0x0000
#define MACADDR1 0xE101
#define MACADDR2 0x0042
#endif


#define pDriverGlobals ((PDRIVER_GLOBALS) DRIVER_GLOBALS_PHYSICAL_MEMORY_START)

#define PF_ETHER_BASE ETHERNET_BASE

// Constants that control operation of bootloader. All times in seconds
#define BOOTME_INTERVAL	   3    // Interval between BOOTMEs
#define MAX_BOOTME_CNT	   10   // Max number of BOOTMEs sent

// Well known DHCP ports for use with UDP
#define DHCP_SERVER_PORT 0x4300
#define DHCP_CLIENT_PORT 0x4400

// Name of platform and base for device name in Eshell
#define PLATFORM_STRING  "ASPEN"

// CPU Id for Eshell
#define EDBG_CPUID EDBG_CPU_SH4

const unsigned char NKSignon[] = {
    "\nMicrosoft Windows CE Ethernet Bootloader built "
        __DATE__ " " __TIME__ "\n"
	" Copyright(c) 1998,1999 SIC/Hitachi,Ltd. \n"};

ROMHDR RomHdr;							// ROM Table of Contents 

BOOL ReadEEPROMData(DWORD *pdwIP, DWORD *pdwSubnetMask);
BOOL UpdateEEPROMData(DWORD dwIP, DWORD dwSubnetMask);

static BYTE FrameBuffer[ETHER_MTU];

extern DWORD dwLaunchAddr;
extern DWORD VerifyCheckSum(void);

// We save the address of the last launch in this var, and use a magic value to
// verify that the contents are valid.
DWORD dwLastLaunchAddr;
#define LAST_LAUNCH_ADDR_VALID 0xBADBEEF6
DWORD dwLastLaunchAddrValid;

// For blinking LEDS
static WORD wDiscreteLedCount;

// Can be used to turn on debug zones in eboot.lib and smc9000.lib functions
DWORD EdbgDebugZone;

typedef volatile unsigned int *VPDWORD;

extern DWORD dwOffset;

#if (SH_PLATFORM != PLATFORM_ASPEN)
ROMHDR *const pTOC = (ROMHDR *)-1;     // Gets replaced by RomLoader with real address
void KernelRelocate(ROMHDR *const pTOC);
int ParallelDownloadImage(void);
#endif (SH_PLATFORM != PLATFORM_ASPEN)

typedef volatile unsigned int *VPDWORD;
extern unsigned int ulRamBufStart;				// starting address of available RAM
extern unsigned int ulRamBufEnd;				// ending address of available RAM


//#ifndef R3000
//void memset(char * dest, int c, unsigned int count);
//void memcpy(char * dest, char * src, unsigned int count);
//#endif

unsigned int vAddr;

static unsigned int iTest=0x12345678;

#if (SH_PLATFORM != PLATFORM_ASPEN)
//
// Move all writeable data sections into RAM
//
// Relocate the kernel
void KernelRelocate(ROMHDR *const pTOC)
{
	ULONG loop;
	COPYentry *cptr;
	if (pTOC == (ROMHDR *const) 0xffffffff) {
	    WRITE_REGISTER_ULONG(LED_ALPHA,0xc0dedead);
		while (1) ; // spin forever!
	}
	// This is where the data sections become valid... don't read globals until after this
	for (loop = 0; loop < pTOC->ulCopyEntries; loop++) {
		cptr = (COPYentry *)(pTOC->ulCopyOffset + loop*sizeof(COPYentry));
		if (cptr->ulCopyLen)
			memcpy((LPVOID)cptr->ulDest,(LPVOID)cptr->ulSource,cptr->ulCopyLen);
		if (cptr->ulCopyLen != cptr->ulDestLen)
			memset((LPVOID)(cptr->ulDest+cptr->ulCopyLen),0,cptr->ulDestLen-cptr->ulCopyLen);
	}
}
#endif (SH_PLATFORM != PLATFORM_ASPEN)

#define IPSTATE_NONE    0
#define IPSTATE_GOTIP   1
#define IPSTATE_ARP     2
#define IPSTATE_ARPED   3
#define IPSTATE_RETRY   4

#define MAX_DHCP_RETRY  3


int
Command_Ether(int dummy)
{
	EDBG_ADDR MyAddr;
	DWORD dwSubnetMask;
	DWORD dwStartTime;
	WORD wDIPs;
	BOOL  fGotJumpimg = FALSE, fGotIP = FALSE;
    DWORD dwIPState = IPSTATE_NONE;
    EDBG_ADDR EshellHostAddr = {0,0,0};
    EDBG_OS_CONFIG_DATA *pCfgData;    
	char *pszErrorMsg;
	DWORD dwNextBootme=0; // Time of next bootme
	UCHAR BootmeCnt=0;	  // # of bootmes sent so far
	SYSTEMTIME st;
	SYSTEMTIME defst = {1998,1,0,1,12,0,0,0};
    int DHCPRetry=0;
    DWORD DHCPLeaseTime;
    DWORD EdbgFlags = 0;

	LPDWORD	lpdwToc;	  // toc pointer

#if (SH_PLATFORM != PLATFORM_ASPEN)
	WRITE_REGISTER_ULONG(LED_ALPHA,0xCE2EB002);

    /* Copy kernel data to RAM & zero out BSS */
	KernelRelocate(pTOC);
	OEMInitDebugSerial();
#endif (SH_PLATFORM != PLATFORM_ASPEN)

	// Enable cache to speed up the download process.
	// We found around 30 % time advantage in using cache for 
	// complete download + write to Flash.
	enable_cache();

    EdbgOutputDebugString(NKSignon);
    EdbgOutputDebugString("Stack=%Xh\r\n",&MyAddr);
	// init RomHdr
	memset((LPVOID)&RomHdr,-1,sizeof(ROMHDR));
    // Initialize driver globals area, so kernel knows we are present
    memset((LPVOID)&pDriverGlobals->eth,0,DBG_ETH_GLOBALS_SIZE);
	pDriverGlobals->eth.EbootMagicNum = EBOOT_MAGIC_NUM;

	EdbgOutputDebugString("Set pDriverGlobals (0x%x) to 0x%x\n", 
					&pDriverGlobals->eth.EbootMagicNum, pDriverGlobals->eth.EbootMagicNum);

	{
		USHORT	wFRQCR,wBCR2;
		ULONG	lBCR1,lWCR1,lWCR2,lWCR3;
			
		wFRQCR = READ_REGISTER_USHORT(CPG_FRQCR);
		lBCR1  = READ_REGISTER_ULONG (BSC_REGBASE+BSC_BCR1_OFFSET);
		wBCR2  = READ_REGISTER_USHORT(BSC_REGBASE+BSC_BCR2_OFFSET);
		lWCR1  = READ_REGISTER_ULONG (BSC_REGBASE+BSC_WCR1_OFFSET);
		lWCR2  = READ_REGISTER_ULONG (BSC_REGBASE+BSC_WCR2_OFFSET);
		lWCR3  = READ_REGISTER_ULONG (BSC_REGBASE+BSC_WCR3_OFFSET);
		EdbgOutputDebugString("FRQCR:0x%x\r\n", wFRQCR);
		EdbgOutputDebugString("BCR1:0x%x\tBCR2:0x%x\r\n", lBCR1, wBCR2);
		EdbgOutputDebugString("WCR1:0x%x\tWCR2:0x%x\tWCR3:0x%x\r\n", lWCR1, lWCR2, lWCR3);
	}

#if (SH_PLATFORM != PLATFORM_ASPEN)
	//
	// At this time, the CPU has been initialized
	//
	if (!PowerOnSelfTest()) {
        EdbgOutputDebugString("!Failed Power On Self test!\n");
        goto FatalError;
    }
#endif (SH_PLATFORM != PLATFORM_ASPEN)

    // Check real time clock, initialize if necessary (used for polling in net routines)
	OEMGetRealTime(&st);
	if ((st.wYear < 1601) ||
		(st.wMonth < 1) ||
		(st.wMonth > 12) ||
		(st.wDay < 1) ||
		(st.wDay > 31) ||
		(st.wHour > 23) ||
		(st.wMinute > 59) ||
		(st.wSecond > 59) ||
		(st.wMilliseconds > 999)) {

        EdbgOutputDebugString("Invalid time returned from OEMGetRealTime: Year: %u, Month: %u, Day: %u, Hour: %u, Minute: %u, second: %u\n",
                           st.wYear, st.wMonth,st.wDay, st.wHour, st.wMinute,st.wSecond);
        EdbgOutputDebugString("Resetting real time clock to default date\n");
		OEMSetRealTime(&defst);
    }
	else
		OEMSetRealTime(&st);

    // First, reset the 91C94. Do this before we print the banner so there is
    // a little time for the HW to settle.
/*** delete for S1
    WRITE_REGISTER_USHORT( SMC_HARD_RESET_REG, 1 );
    WRITE_REGISTER_USHORT( SMC_HARD_RESET_REG, 0 );
***/

/*
	{
		int	loop;
	    EdbgOutputDebugString("Testing OEMEthGetSecs");
		for (loop=0; loop<10; loop++) {
			dwStartTime=OEMEthGetSecs();
			while (OEMEthGetSecs() == dwStartTime) ;
		    EdbgOutputDebugString(".");
		}
	    EdbgOutputDebugString("\r\n");
	}
*/

    // SMCInit will time out and return error if the debug Ethernet board is not present.
    // Otherwise, the HW will be initialized and our address will be filled in (read
    // from the on chip serial EEPROM).

    if (!SMCInit( (BYTE *) PF_ETHER_BASE, 1, MyAddr.wMAC)) {
        EdbgOutputDebugString("Failed to initialize SMC Ethernet board. Returning to monitor...\n");

#if (SH_PLATFORM != PLATFORM_ASPEN)
		pDriverGlobals->eth.etherFlags|=EDBG_FL_CLEANBOOT;
		pDriverGlobals->eth.EbootMagicNum = ~EBOOT_MAGIC_NUM;
		ParallelDownloadImage();
        goto DoLaunch2;
#endif (SH_PLATFORM != PLATFORM_ASPEN)

		return 1;
    }

#if (MACADDR0 || MACADDR1 || MACADDR2)
	/* Serial EEPROM emulation */
	{
		EdbgOutputDebugString("Set Ethernet Address\r\n");

		MyAddr.wMAC[0] = ((MACADDR0 << 8) & 0xFF00) | ((MACADDR0 >> 8) & 0x00FF);
		MyAddr.wMAC[1] = ((MACADDR1 << 8) & 0xFF00) | ((MACADDR1 >> 8) & 0x00FF);
		MyAddr.wMAC[2] = ((MACADDR2 << 8) & 0xFF00) | ((MACADDR2 >> 8) & 0x00FF);

        EdbgOutputDebugString("We Set SMC Ethernet Address to: %B:%B:%B:%B:%B:%B\r\n",
                               MyAddr.wMAC[0] & 0x00FF, MyAddr.wMAC[0] >> 8,
                               MyAddr.wMAC[1] & 0x00FF, MyAddr.wMAC[1] >> 8,
                               MyAddr.wMAC[2] & 0x00FF, MyAddr.wMAC[2] >> 8);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?