📄 main.c
字号:
/*++
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.
Copyright (c) 1995, 1996, 1997, 1998 Microsoft Corporation
--*/
/*
** INTEL CONFIDENTIAL
** Copyright 2000-2003 Intel Corporation All Rights Reserved.
**
** The source code contained or described herein and all documents
** related to the source code (Material) are owned by Intel Corporation
** or its suppliers or licensors. Title to the Material remains with
** Intel Corporation or its suppliers and licensors. The Material contains
** trade secrets and proprietary and confidential information of Intel
** or its suppliers and licensors. The Material is protected by worldwide
** copyright and trade secret laws and treaty provisions. No part of the
** Material may be used, copied, reproduced, modified, published, uploaded,
** posted, transmitted, distributed, or disclosed in any way without Intel抯
** prior express written permission.
** No license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise. Any license under such intellectual property rights
** must be express and approved by Intel in writing.
*/
/*
Module Name:
main.c
Abstract:
Ethernet boot loader main module. This file contains the C main
for the boot loader.
The Windows CE boot loader is the code that is executed on a Windows CE
development system at power-on reset and loads the Windows CE
operating system.
*/
#include <windows.h>
#include <ethdbg.h>
#include "halether.h"
#include <nkintr.h>
#include <pehdr.h>
#include <romldr.h>
#include "ethdown.h"
#include "xllp_defs.h"
//#include "xllp_serialization.h"
//#include "xllp_lcd.h"
#include "xllp_ethernet.h"
#include "xllp_memctrl.h" //hzh
#define BOOT_LOADER // To avoid including debug ethernet support
#include "..\..\kernel\hal\debug.c"
// The EBOOTCFG structure holds a variety of configuration parameters.
// When adding new parameters, make sure that the size of the structure in bytes is
// an integral number of DWORDS. Pad the structure if necessary.
typedef struct
{
DWORD autoDownloadImage;
DWORD IP;
DWORD subnetMask;
DWORD numBootMe;
DWORD delay;
DWORD DHCPEnable;
DWORD bootDeviceOrder;
DWORD dwPhysStart;
DWORD dwPhysLen;
DWORD dwLaunchAddr;
DWORD bWriteBINToFlash;
DWORD ConfigMagicNumber;
DWORD CRC;
DRIVER_GLOBALS DriverGlobals;
} EBOOTCFG;
// Flash type constants
#define J3 1
#define K3 2
#define K18 3
#define L18 4
#define L30 5
// File type constants
#define BIN_FILE_TYPE 1
#define NB0_FILE_TYPE 2
#define BOOTLOADER 4
#define NKBIN 8
#define FLASHTARGET 16
#define SDRAMEXE 32
// State machine contants
#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
#define NONE -1
#ifdef MMXIP_MEMMAP
#define RAM_IMAGE_START 0x96CB8000
#else
#define RAM_IMAGE_START 0x800B8000
#endif
#define FLASH_CFG_START (BOOT_FLASH_BASE_U_VIRTUAL+0x00040000)
#define FLASH_BIN_START (BOOT_FLASH_BASE_U_VIRTUAL+0x00080000)
#define EbootCFGMagicNumber 0x11232000
#define DEVICE_PCMCIA_S0 0
#define DEVICE_PCMCIA_S1 1
#define DEVICE_SMSC 2
#define BOOTME_INTERVAL 3 // Interval between BOOTMEs in seconds
#define MAX_BOOTME_CNT 25
// 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 "XSC1BD"
// CPU Id for Eshell
#define EDBG_CPUID EDBG_CPU_TYPE_ARM
#define EBOOT_VERSION_MAJOR 1
#define EBOOT_VERSION_MINOR 0
#define pDriverGlobals ((PDRIVER_GLOBALS) DRIVER_GLOBALS_PHYSICAL_MEMORY_START)
// Function prototypes
extern void Launch(unsigned int uAddr);
extern void Launch2(unsigned int uAddr);
extern msWait(unsigned msVal);
extern DWORD VerifyCheckSum(void);
extern int InitSpecifiedEthDevice(EDBG_ADDR *MyAddr, UINT EthDevice);
extern void InitClock(void);
extern void ClearPromiscuousIP( void );
void KernelRelocate(ROMHDR *const pTOC);
int StoreEBootCFG(EBOOTCFG *EBootCFG);
int LoadEBootCFG(EBOOTCFG *EBootCFG);
void ResetFactoryDefaultCFG(EBOOTCFG *EBootCFG);
void SetIP(EBOOTCFG *pEbootCFG);
void SetMask(EBOOTCFG *pEbootCFG);
void SetBootMe(EBOOTCFG *pEbootCFG);
void SetDelay(EBOOTCFG *pEbootCFG);
int LoadFlashImage(DWORD dwPhysStart, DWORD dwPhysLen, DWORD dwLaunchAddr, EBOOTCFG *pEbootCFG);
int DetectFlashDevice(void);
void EraseFlashImage(void);
XLLP_UINT32_T XllpEthernetGetEEPROMMACAddress(P_XLLP_UINT16_T macAddressP);
XLLP_UINT32_T XllpEthernetStoreEEPROMMACAddress(P_XLLP_UINT16_T macAddressP);
void XllpEthernetGetMACAddress(P_XLLP_UINT16_T macAddressP);
void XllpEthernetStoreMACAddress(P_XLLP_UINT16_T macAddressP);
void init_crc32();
unsigned long crc32(unsigned char *buf, int len);
void SetSMSCMACAddress();
void CvtMAC(USHORT MacAddr[3], char *pszDottedD );
//extern XLLP_STATUS_T XllpLCDInit(P_XLLP_LCD_T pXllpLCD);
//void TestLCD();
//void vline(int x1, int y1, int y2, __int16 c);
//void line(int ox1, int oy1, int ox2, int oy2, __int16 c);
//void hline(int x1, int y1, int x2,__int16 c);
//void ClearFrameBuffer();
// Global variables
extern DWORD dwPhysStart; // image physical starting address
extern DWORD dwPhysLen; // image physical length
extern DWORD fileType;
extern DWORD v_PacketNum;
extern DWORD dwLaunchAddr;
extern DWORD dwOffset;
extern int offset;
//
// Function pointers to the support library functions of the currently installed debug ethernet controller.
//
extern PFN_EDBG_INIT pfnEDbgInit;
extern PFN_EDBG_ENABLE_INTS pfnEDbgEnableInts;
extern PFN_EDBG_DISABLE_INTS pfnEDbgDisableInts;
extern PFN_EDBG_GET_PENDING_INTS pfnEDbgGetPendingInts;
extern PFN_EDBG_GET_FRAME pfnEDbgGetFrame;
extern PFN_EDBG_SEND_FRAME pfnEDbgSendFrame;
extern PFN_EDBG_READ_EEPROM pfnEDbgReadEEPROM;
extern PFN_EDBG_WRITE_EEPROM pfnEDbgWriteEEPROM;
extern PFN_EDBG_SET_OPTIONS pfnEDbgSetOptions;
const unsigned char NKSignon[] = {
"\nMicrosoft Windows CE Ethernet Bootloader built "
__DATE__ " " __TIME__ "\n"
"Copyright (c) 2002 Microsoft Corporation\n"
"Portions copyright (c) 2002 Intel Corporation\n"};
ROMHDR RomHdr; // ROM Table of Contents
static BYTE FrameBuffer[ETHER_MTU];
ROMHDR * volatile const pTOC = (ROMHDR *)-1; // Gets replaced by RomLoader with real address
BOOL CFGChanged=FALSE;
BOOL bLinkEstablished = FALSE;
DWORD EdbgDebugZone;
DWORD CurMSec;
int flashType;
//
// Move all writeable data sections into RAM
//
// Relocate the kernel
void KernelRelocate(ROMHDR *const pTOC)
{
ULONG loop;
COPYentry *cptr;
if (pTOC == (ROMHDR *const) 0xffffffff)
{
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);
}
}
void main(void)
{
EDBG_ADDR MyAddr;
DWORD dwSubnetMask;
DWORD dwStartTime;
DWORD dwCurrTime;
DWORD dwPrevTime;
DWORD selection;
DWORD delay;
BOOL fGotJumpimg = FALSE, fGotIP = FALSE;
DWORD dwIPState = IPSTATE_NONE;
EDBG_ADDR EshellHostAddr = {0,0,0};
EDBG_OS_CONFIG_DATA *pCfgData;
DWORD dwNextBootme=0; // Time of next bootme
UCHAR BootmeCnt=0; // # of bootmes sent so far
int DHCPRetry=0;
DWORD DHCPLeaseTime;
DWORD EdbgFlags = 0;
UINT ethernet_device;
LPDWORD lpdwToc; // toc pointer
int i,j;
SYSTEMTIME st;
SYSTEMTIME defst = {1998,1,0,1,12,0,0,0};
EBOOTCFG EbootCFG;
EBOOTCFG *pEbootCFG;
// This table describes the boot order for a given configuration
int bootOrder[] = {DEVICE_SMSC,DEVICE_PCMCIA_S0,DEVICE_PCMCIA_S1, //pEbootCFG->bootDeviceOrder = 0
DEVICE_SMSC,DEVICE_PCMCIA_S1,DEVICE_PCMCIA_S0, //pEbootCFG->bootDeviceOrder = 1
DEVICE_PCMCIA_S0,DEVICE_PCMCIA_S1,DEVICE_SMSC, //pEbootCFG->bootDeviceOrder = 2
DEVICE_PCMCIA_S0,DEVICE_SMSC,DEVICE_PCMCIA_S1, //pEbootCFG->bootDeviceOrder = 3
DEVICE_PCMCIA_S1,DEVICE_SMSC,DEVICE_PCMCIA_S0, //pEbootCFG->bootDeviceOrder = 4
DEVICE_PCMCIA_S1,DEVICE_PCMCIA_S0,DEVICE_SMSC}; //pEbootCFG->bootDeviceOrder = 5
int x,y,z;
volatile BLR_REGS *BLR = (BLR_REGS *)FPGA_REGS_BASE_U_VIRTUAL;
volatile XLLP_GPIO_T *p_GPIORegs = (XLLP_GPIO_T *)GPIO_BASE_U_VIRTUAL;
//===hzh
volatile XLLP_MEMORY_CONTROL_REGISTER_T *p_MemCtrl= (XLLP_MEMORY_CONTROL_REGISTER_T *)MEMC_BASE_U_VIRTUAL;
//===
/* Copy kernel data to RAM & zero out BSS */
KernelRelocate(pTOC);
OEMInitDebugSerial();
EdbgOutputDebugString(NKSignon);
//===hzh
p_MemCtrl->MSC0 &= 0xffff;
p_MemCtrl->MSC0 |= 0x9469<<16;
p_MemCtrl->MSC1 = 0xB8C9B8DC;
p_MemCtrl->MSC2 = 0xFFF99134;
//EdbgOutputDebugString("MSC0 0x%x, MSC1 0x%x, MSC2 0x%x\n", p_MemCtrl->MSC0, p_MemCtrl->MSC1, p_MemCtrl->MSC2);
//===
flashType = DetectFlashDevice();
switch (flashType)
{
case J3:
EdbgOutputDebugString("Flash type J3\r\n");
break;
case K3:
EdbgOutputDebugString("Flash type K3\r\n");
break;
case K18:
EdbgOutputDebugString("Flash type K18\r\n");
break;
case L18:
EdbgOutputDebugString("Flash type L18\r\n");
break;
case L30:
EdbgOutputDebugString("Flash type L30\r\n");
break;
default:
EdbgOutputDebugString("Flash type unknown.\r\n");
break;
}
// Configure the MUX for PCMCIA
BLR->misc_wr &= ~0x200;
BLR->hex_led = 0;
memset((LPVOID)&RomHdr,-1,sizeof(ROMHDR));
memset((LPVOID)pDriverGlobals,0,sizeof(DRIVER_GLOBALS));
InitClock();
OEMGetRealTime(&st);
pEbootCFG = &EbootCFG;
LoadEBootCFG(pEbootCFG);
MyAddr.dwIP = pEbootCFG->IP;
dwSubnetMask = pEbootCFG->subnetMask;
delay = pEbootCFG->delay;
memcpy(pDriverGlobals, &pEbootCFG->DriverGlobals, sizeof(DRIVER_GLOBALS));
if (pEbootCFG->autoDownloadImage)
{
EdbgOutputDebugString ( "Press [ENTER] to download now or [SPACE] to cancel.\r\n");
EdbgOutputDebugString ( "\r\nInitiating image download in %d seconds. ", delay--);
}
else
{
EdbgOutputDebugString ( "Press [ENTER] to launch image stored in flash or [SPACE] to cancel.\r\n");
EdbgOutputDebugString ( "\r\nInitiating image launch in %d seconds. ", delay--);
}
dwStartTime = OEMEthGetSecs();
dwPrevTime = dwStartTime;
dwCurrTime = dwStartTime;
selection = 0;
while ((dwCurrTime - dwStartTime) < pEbootCFG->delay)
{
selection = OEMReadDebugByte();
if ((selection == 0x20) || (selection == 0x0d))
break;
dwCurrTime = OEMEthGetSecs();
if (dwCurrTime > dwPrevTime)
{
// 1 Second has elapsed
// Update the countdown timer
dwPrevTime = dwCurrTime;
if (delay < 9)
i = 11;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -