⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ether.c

📁 WinCE5.0BSP for Renesas SH7770
💻 C
字号:
//
//  Copyright(C) Renesas Technology Corp. 2005. All rights reserved.
//
//  Ethernet Boot Loader for ITS-DS7
//
//  FILE      : ether.c
//  CREATED   : 2005.08.01
//  MODIFIED  : 
//  AUTHOR    : Renesas Technology Corp.
//  HARDWARE  : RENESAS ITS-DS7
//  HISTORY   : 
//              2005.08.01
//              - Created release code.
//                (based on EBOOT for ASPEN for WCE5.0)

//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft 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.
//
//------------------------------------------------------------------------------
//
//  Module: ether.c
//
//  This module provides the interface to the ethernet transport.
//
//------------------------------------------------------------------------------

// Include Files 
#include "boot.h"
#include <ethdbg.h>
#include <pehdr.h>
#include <romldr.h>
#include <oemfw.h>
#include "shx.h"
#include "platform.h"
#include "drv_glob.h"
#include "loader.h"
#include "rev.h"
 
// External Functions

extern  BOOL    ReadEEPROMData  ( DWORD *pdwIP, DWORD *pdwSubnetMask);
extern  BOOL    UpdateEEPROMData( DWORD  dwIP,  DWORD   dwSubnetMask);
extern  void    JumpToOS        ( DWORD dwLaunchAddr );
extern  BOOL    AskUser         ( EDBG_ADDR *pMyAddr, LPDWORD pdwSubnetMask );
extern  void    SpinForever     ( VOID );

// External Variables 
extern BOOL gbStoreSDRAMImageToFlash;
extern BOOL gbJumpToFlash;
extern BOOL gbGotIP;

// Global Variables 

// Defines 

#define pDriverGlobals ((PDRIVER_GLOBALS) DRIVER_GLOBALS_PHYSICAL_MEMORY_START)

#define EDBG_CPUID                  EDBG_CPU_SH4        // CPU Id for Eshell

#define LAST_LAUNCH_ADDR_VALID      (0xBADBEEF6)

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

// Types
 
// Local Variables 
 
// Local Functions 

// function to ask user for IP/subnetMask

static EDBG_ADDR MyAddr;        // IP address
static DWORD dwSubnetMask;      // subnet mask
static BOOL fNoWait;            // wait for desktop?

//------------------------------------------------------------------------------
//  Function:  EthInit
//
//  Initialize ethernet interface.
//

BOOL EthInit( void )
{
    EdbgOutputDebugString( "+EthInit\r\n" );

    EdbgOutputDebugString( "INFO: SMC base : 0x%X\r\n", PF_ETHER_BASE);

    if( !SMCInit( (BYTE *) PF_ETHER_BASE, 1, MyAddr.wMAC) )
    {
        EdbgOutputDebugString("ERROR: SMC Ethernet init failed, attempting parallel download...\n");

        pDriverGlobals->eth.etherFlags|=EDBG_FL_CLEANBOOT;
        pDriverGlobals->eth.EbootMagicNum = ~EBOOT_MAGIC_NUM;
        return( FALSE );
    }

#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);

		WRITE_REGISTER_USHORT(PF_ETHER_BASE + (0x0E * 1),0x3301);
		WRITE_REGISTER_USHORT(PF_ETHER_BASE + (0x04 * 1),MyAddr.wMAC[0]);
		WRITE_REGISTER_USHORT(PF_ETHER_BASE + (0x06 * 1),MyAddr.wMAC[1]);
		WRITE_REGISTER_USHORT(PF_ETHER_BASE + (0x08 * 1),MyAddr.wMAC[2]);

		MyAddr.wMAC[0] = READ_REGISTER_USHORT(PF_ETHER_BASE + (0x04 * 1));
		MyAddr.wMAC[1] = READ_REGISTER_USHORT(PF_ETHER_BASE + (0x06 * 1));
		MyAddr.wMAC[2] = READ_REGISTER_USHORT(PF_ETHER_BASE + (0x08 * 1));

        EdbgOutputDebugString("SMC Ethernet Address: %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);
	}
#endif

    // Make sure MAC address has been programmed

    if( !MyAddr.wMAC[0] && !MyAddr.wMAC[1] && !MyAddr.wMAC[2] )
    {
        EdbgOutputDebugString( "ERROR: Invalid MAC address.\r\n" );
        return( FALSE );
    }

    // Read IP info in EEPROMs

    EdbgOutputDebugString( "INFO: ReadEEPROMData...\r\n");

    if( !ReadEEPROMData( &MyAddr.dwIP, &dwSubnetMask ) )
    {
        EdbgOutputDebugString(" ERROR: EthInit: ReadEEPROMData failed\r\n" );
        return( FALSE );
    }
    EdbgOutputDebugString("INFO: EEPROM IpAddr %s ", inet_ntoa( MyAddr.dwIP ) );
    EdbgOutputDebugString("netmask %s\r\n", inet_ntoa( dwSubnetMask) );

    // Save our address in driver globals
    memcpy(&pDriverGlobals->eth.PlatformAddr,&MyAddr,sizeof(MyAddr));
    pDriverGlobals->eth.SubnetMask = dwSubnetMask;

    // Indicate status

    EdbgOutputDebugString( "-EthInit(rc=1)\r\n" );
    return( TRUE );
}

//------------------------------------------------------------------------------
//  Function:  EthPreDownload
//
//  
//

DWORD EthPreDownload( void )
{
    BOOL    fGotJumpImg = FALSE;
    DWORD   DHCPLeaseTime = 0;
    DWORD   *pDHCPLeaseTime = &DHCPLeaseTime;

    EdbgOutputDebugString( "+EthPreDownload\r\n" );

    // Polarity is reversed, so this is actually testing the "Off" position

    if( gbJumpToFlash )
    {
        EdbgOutputDebugString( "INFO: Switch 1 on, jumping to flash image...\r\n");
        fNoWait = TRUE;

        return BL_JUMP;
    }

    EdbgOutputDebugString("Using device name: %s%d\n", BSP_DEVICE_PREFIX, ((MyAddr.wMAC[2] & 0x00FF) << 8) | MyAddr.wMAC[2] >> 8);

    // If DIP switch SW2-2 is ON, use already IP address.
	if (gbGotIP) {	// ON
		if (dwSubnetMask) { 
			EdbgOutputDebugString("Switch SW2-2 is ON, use existing IP address.\r\n");
			//bGotIP = TRUE;
		} else {
			EdbgOutputDebugString("Switch SW2-2 is ON, but NOT exist IP address. Enter new IP address.\r\n");
			gbGotIP = FALSE;
		}
	}
	if(gbGotIP){
		// already read EEPROM from static IP(EthInit)
        pDHCPLeaseTime = NULL;          // pDHCPLeaseTime is overloaded - NULL indicates static IP
        pDriverGlobals->eth.EdbgFlags = EDBG_FLAGS_STATIC_IP;
	}
	else{
	    // Ask user if static IP is desired

	    if( AskUser( &MyAddr, &dwSubnetMask) )
	    {
	        pDHCPLeaseTime = NULL;          // pDHCPLeaseTime is overloaded - NULL indicates static IP
	        pDriverGlobals->eth.EdbgFlags = EDBG_FLAGS_STATIC_IP;
	    }
	}

    // Initialize TFTP transport

    if( !EbootInitEtherTransport( &MyAddr, 
                                  &dwSubnetMask, 
                                  &fGotJumpImg, 
                                  pDHCPLeaseTime,
                                  EBOOT_VERSION_MAJOR, 
                                  EBOOT_VERSION_MINOR, 
                                  BSP_DEVICE_PREFIX, 
                                  NULL, 
                                  EDBG_CPUID, 
                                  0) )
    {
        return( BL_ERROR );
    }

    // update DHCP lease time

    pDriverGlobals->eth.DHCPLeaseTime = DHCPLeaseTime;

    return( fGotJumpImg? BL_JUMP : BL_DOWNLOAD );
}

//------------------------------------------------------------------------------
//  Function:  EthLaunch
//
//  
//
void EthLaunch( DWORD dwImageStart, 
                DWORD dwImageLength, 
                DWORD dwLaunchAddr, 
                const ROMHDR *pRomHdr )
{
    EDBG_OS_CONFIG_DATA *pCfgData = NULL;    
    EDBG_ADDR EshellHostAddr;

    EdbgOutputDebugString("+EthLaunch( 0x%x, 0x%x, 0x%x, 0x%x )\r\n",
        dwImageStart, dwImageLength, dwLaunchAddr, pRomHdr );

    // Wait for the jump command from PB unless user specify jump directly

    if( !fNoWait )
    {
        EdbgOutputDebugString ("Download successful! Jumping to image at %Xh...\r\n", dwLaunchAddr);

        if( !(pCfgData = EbootWaitForHostConnect( &MyAddr, &EshellHostAddr )) )
        {
            EdbgOutputDebugString ("ERROR: EthLaunch: EbootWaitForHostConenct failed\r\n");
            SpinForever();

            // Should never get here. Also cleans up a prefast error...
            return;
        }

        // Update service information

        if( pCfgData->Flags & EDBG_FL_DBGMSG )
        {
            EdbgOutputDebugString("Enabling debug messages over Ethernet, IP: %s, port:%u\n",
                                  inet_ntoa(pCfgData->DbgMsgIPAddr),ntohs(pCfgData->DbgMsgPort));
            memcpy(&pDriverGlobals->eth.DbgHostAddr.wMAC,&EshellHostAddr.wMAC,6);
            pDriverGlobals->eth.DbgHostAddr.dwIP  = pCfgData->DbgMsgIPAddr;
            pDriverGlobals->eth.DbgHostAddr.wPort = pCfgData->DbgMsgPort;
        }

        if( pCfgData->Flags & EDBG_FL_PPSH )
        {
            EdbgOutputDebugString("Enabling CESH over Ethernet,           IP: %s, port:%u\n",
                                  inet_ntoa(pCfgData->PpshIPAddr),ntohs(pCfgData->PpshPort));
            memcpy(&pDriverGlobals->eth.PpshHostAddr.wMAC,&EshellHostAddr.wMAC,6);
            pDriverGlobals->eth.PpshHostAddr.dwIP  = pCfgData->PpshIPAddr;
            pDriverGlobals->eth.PpshHostAddr.wPort = pCfgData->PpshPort;
        }

        if( pCfgData->Flags & EDBG_FL_KDBG )
        {
            EdbgOutputDebugString("Enabling KDBG over Ethernet,           IP: %s, port:%u\n",
                                  inet_ntoa(pCfgData->KdbgIPAddr),ntohs(pCfgData->KdbgPort));
            memcpy(&pDriverGlobals->eth.KdbgHostAddr.wMAC,&EshellHostAddr.wMAC,6);
            pDriverGlobals->eth.KdbgHostAddr.dwIP  = pCfgData->KdbgIPAddr;
            pDriverGlobals->eth.KdbgHostAddr.wPort = pCfgData->KdbgPort;
        }
        pDriverGlobals->eth.etherFlags = pCfgData->Flags;
        memcpy( &pDriverGlobals->eth.DownloadHostAddr,&EshellHostAddr,sizeof(EDBG_ADDR) );
    }

    // Update address info, in driver globals, and in EEPROM if necessary

    pDriverGlobals->eth.EbootMagicNum = EBOOT_MAGIC_NUM;
    if(pCfgData) pDriverGlobals->eth.KitlTransport = pCfgData->KitlTransport;
    memcpy( &pDriverGlobals->eth.PlatformAddr, &MyAddr, sizeof(MyAddr) );
    pDriverGlobals->eth.SubnetMask = dwSubnetMask;

    // Update EEPROM IP/subnet information

    UpdateEEPROMData( MyAddr.dwIP, dwSubnetMask );

    if( dwLaunchAddr == 0 )
    {
        if( pDriverGlobals->dwLastLaunchAddrValid == LAST_LAUNCH_ADDR_VALID )
        {
            EdbgOutputDebugString("Using previous launch address\n");
            dwLaunchAddr = pDriverGlobals->dwLastLaunchAddr;
        }
        else
        {
            if( pRomHdr && pRomHdr->physfirst != -1 )
            {
                dwLaunchAddr= pRomHdr->physfirst;
            }
            else
            {
				dwLaunchAddr = FLASH_IMAGE_START_CACHED;   // Default launch address
            }
        }
    }
    else
    {
        pDriverGlobals->dwLastLaunchAddrValid = LAST_LAUNCH_ADDR_VALID;
        pDriverGlobals->dwLastLaunchAddr=dwLaunchAddr;
    }

    EdbgOutputDebugString("\r\nJumping to existing image at %Xh...\r\n",dwLaunchAddr);

    // Launch the OS - never returns

    JumpToOS( dwLaunchAddr );
    SpinForever();
}

//------------------------------------------------------------------------------
//  Function: OEMEthGetFrame
//
//  Receives a buffer from NIC driver. Returns TRUE if frame 
//  has been received, FALSE if not.
//

BOOL OEMEthGetFrame( BYTE *pData, UINT16 *pwLength )     
{
    return( SMCGetFrame(pData, pwLength) );
}

//------------------------------------------------------------------------------
//  Function: OEMEthSendFrame
//
//  Send Ethernet frame. Returns TRUE if frame successfully 
//  sent, FALSE otherwise.
//

BOOL OEMEthSendFrame( BYTE *pData, DWORD dwLength )
{
    int retries = 0;

    // Let's be persistant here

    while( retries++ < 4 )
    {
        if( !SMCSendFrame(pData, dwLength) )
        {
            return TRUE;
        }
        else
        {
            EdbgOutputDebugString("ERROR: OEMEthSendFrame: Failed - retries %u\n",retries);
        }
    }
    return FALSE;
}

//------------------------------------------------------------------------------
//  Function: OEMEthGetSecs
//
//  Return a count of seconds from some arbitrary time (the absolute value 
//  is not important, so long as it increments appropriately).
//

DWORD OEMEthGetSecs( void ) 
{
    SYSTEMTIME st;

    OEMGetRealTime( &st );
    return((60UL * (60UL * (24UL * (31UL * st.wMonth + st.wDay) + st.wHour) + st.wMinute)) + st.wSecond);
}

⌨️ 快捷键说明

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