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

📄 halether.c

📁 CIRRUS 公司EP93XX系列CPU的WINCE下的BSP
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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.
//
/*++
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.

Module Name:  
    halether.c
    
Abstract:

    Platform specific code for debug ethernet services (debug messages,
    kernel debugger, text shell (PPSH)).  These functions are all called
    from ethdbg.lib.  They are non-preemptible, and cannot make any system calls.

Functions:


Notes: 

--*/
#include <windows.h>
#include <nkintr.h>
#include <ethdbg.h>
#include <halether.h>
#include <oalintr.h>
#include <kitl.h>
#include <memorymap.h>
#include <drv_glob.h>
#include <debugtimer.h>
#include <cs8950sw.h>
#include <hwdefs.h>
#include <options.h>
#include <eeinfo.h>



#define pDriverGlobals  ((PDRIVER_GLOBALS) DRIVER_GLOBALS_VIRTUAL_MEMORY)
//extern HARP_BOOT_ARGS *pBootArgs;

//
// Function pointers to the support library functions of the currently installed
// debug ethernet controller.
//
PFN_EDBG_INIT                   pfnEDbgInit;
PFN_EDBG_ENABLE_INTS            pfnEDbgEnableInts;
PFN_EDBG_DISABLE_INTS           pfnEDbgDisableInts;
PFN_EDBG_GET_PENDING_INTS       pfnEDbgGetPendingInts;
PFN_EDBG_GET_FRAME              pfnEDbgGetFrame;
PFN_EDBG_SEND_FRAME             pfnEDbgSendFrame;
PFN_EDBG_READ_EEPROM            pfnEDbgReadEEPROM;
PFN_EDBG_WRITE_EEPROM           pfnEDbgWriteEEPROM;
PFN_EDBG_SET_OPTIONS            pfnEDbgSetOptions;
PFN_EDBG_CURRENT_PACKET_FILTER  pfnCurrentPacketFilter;
PFN_EDBG_MULTICAST_LIST         pfnMulticastList;


// Buffer for receiving frames into.  
UCHAR RcvBuf[1500];
extern DWORD EdbgDebugZone;

USHORT wLocalMAC[3];    // Saved copy of the mac address

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

// 
#define MAX_BOOTME_CNT   20
#define BOOTME_INTERVAL  3

#ifdef IMGSHAREETH
BOOL    bNewFilter = FALSE;     //  User mode --> Kernel mode to set new filter.
DWORD   dwFilter;               //  The filter..

BOOL    bNewMulticast = FALSE;  //  User mode --> Kernel mode for new list
DWORD   dwNoOfEntry;
BOOL    ucMultiAddr[8][6];      //  The new list..  
                                //  VMINI assumes 8 multicast list entry..
                                //                          
#endif

DWORD OEMRequestSysIntr(
    DWORD Irq 
    );

extern ULONG gulCS8950KitlUsed;


#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


/* OEMEthInit
 *
 *  Initialization routine - called from EdbgInit() to perform platform specific
 *  HW init.  The CEPC platform uses either an SMC 91C94 Ethernet controller or
 *  an NE2000 compatible adapter (NSC 8390 ethernet controller).
 *
 *  Return Value:
 *    Return TRUE if init is successful, FALSE if error.
 */
BOOL
OEMEthInit(EDBG_ADAPTER *pAdapter)
{
    PULONG      pulEthernetBase;
    BOOL        bTemp;

    DEBUGMSG(1, (TEXT("+OEMEthInit\r\n")));

    //
    // Store info from bootargs in the adapter object.
    //
    pAdapter->Addr.dwIP     = pDriverGlobals->eth.EdbgAddr.dwIP;
    //pAdapter->Addr          = pDriverGlobals->eth.EdbgAddr;
    pAdapter->DHCPLeaseTime = pDriverGlobals->eth.DHCPLeaseTime;
    pAdapter->EdbgFlags     = pDriverGlobals->eth.EdbgFlags;
    //uiActiveNicNumber       = pDriverGlobals->eth.EdbgHardwareType;

    //
    // Some parameters included in boot args for future use, make sure these aren't set
    //
    switch(pDriverGlobals->eth.EdbgHardwareType)
    {
#if 0
    case EDBG_ADAPTER_SMC9000:
        pfnEDbgInit           = SMCInit;
        pfnEDbgEnableInts     = SMCEnableInts;     
        pfnEDbgDisableInts    = SMCDisableInts;    
        pfnEDbgGetPendingInts = SMCGetPendingInterrupts; 
        pfnEDbgGetFrame       = SMCGetFrame;       
        pfnEDbgSendFrame      = SMCSendFrame;      
        pfnEDbgReadEEPROM     = SMCReadEEPROM;     
        pfnEDbgWriteEEPROM    = SMCWriteEEPROM;
        pfnEDbgSetOptions     = SMCSetOptions;
        pfnCurrentPacketFilter= NULL;
        pfnMulticastList      = NULL;
        pulEthernetBase       = (ULONG *)0x12345678;

        EdbgOutputDebugString("INFO: EDBG using SMC9000 controller.\r\n");
        break;
#endif // 0

    //
    // Ethernet base needs to be passed in from eboot.
    // TODO
    //
    case EDBG_ADAPTER_NE2000:
        pfnEDbgInit           = NE2000Init;
        pfnEDbgEnableInts     = NE2000EnableInts;     
        pfnEDbgDisableInts    = NE2000DisableInts;    
        pfnEDbgGetPendingInts = NE2000GetPendingInts; 
        pfnEDbgGetFrame       = NE2000GetFrame;       
        pfnEDbgSendFrame      = NE2000SendFrame;      
        pfnEDbgReadEEPROM     = NE2000ReadEEPROM;     
        pfnEDbgWriteEEPROM    = NE2000WriteEEPROM;    
        pfnEDbgSetOptions     = NE2000SetOptions;
        pfnCurrentPacketFilter= Ne2000CurrentPacketFilter;
        pfnMulticastList      = NE2000MulticastList;
        pulEthernetBase       = (ULONG *)(PCMCIACARD_IO + 0x320);

        //
        // TODO - Change the interrupt later.
        //
        pAdapter->SysIntrVal  = KITL_SYSINTR_NOINTR;
        EdbgOutputDebugString("INFO: EDBG using NE2000 controller.\r\n");
        break;

    //
    // Put in the CS8950 ethernet routines.
    //
    case EDBG_ADAPTER_CS8950:
        pfnEDbgInit           = CS8950Init;
        pfnEDbgEnableInts     = CS8950EnableInts;     
        pfnEDbgDisableInts    = CS8950DisableInts;    
        pfnEDbgGetPendingInts = CS8950GetPendingInterrupts; 
        pfnEDbgGetFrame       = CS8950GetFrame;       
        pfnEDbgSendFrame      = CS8950SendFrame;      
        pfnEDbgReadEEPROM     = CS8950ReadEEPROM;     
        pfnEDbgWriteEEPROM    = CS8950WriteEEPROM;    
        pfnEDbgSetOptions     = NULL;
        pfnCurrentPacketFilter= NULL; //CS8950CurrentPacketFilter;
        pfnMulticastList      = NULL; // CS8950MulticastList;
        pulEthernetBase       = (ULONG *)ETHERNET_BASE;
        pAdapter->SysIntrVal  = SYSINTR_ETHER;
        gulCS8950KitlUsed     = TRUE;


        //
        // CS8950 DMA's to SDRAM.  Need to give the library a physical and virtual
        // address to uncached memory.
        //
        bTemp = CS8950DMAInit
        (
            CS8950_PHYSICAL_MEMORY, 
            CS8950_VIRTUAL_MEMORY, 
            CS8950_MEMORY_SIZE
        );

        if(!bTemp)
        {
            EdbgOutputDebugString("ERROR: Failed to Initialize CS8950 DMA buffer.\r\n");
            return FALSE;
        }


        //
        // We need to do this since the board does not have a MAC address.
        // Lets use the same mac address as eboot.
        //
        CS8950WriteEEPROM(0, pDriverGlobals->eth.EdbgAddr.wMAC[0]);
        CS8950WriteEEPROM(1, pDriverGlobals->eth.EdbgAddr.wMAC[1]);
        CS8950WriteEEPROM(2, pDriverGlobals->eth.EdbgAddr.wMAC[2]);
        EdbgOutputDebugString("INFO: EDBG using Internal EP931x controller.\r\n");
        break;
    default:

        EdbgOutputDebugString
        (
            "Unsupported debug Ethernet parameters - adapter: %u\n",
             pDriverGlobals->eth.EdbgHardwareType
        );
        return (FALSE);
    }

    //
    // Initialize the ethernet device.
    //
    //
    if (!pfnEDbgInit((BYTE *) pulEthernetBase,1,pAdapter->Addr.wMAC) )
    {
        return (FALSE);
    }

    //
    // Check the MAC address - this can be invalid if the switches are set wrong.
    //
    if ( !pAdapter->Addr.wMAC[0] && !pAdapter->Addr.wMAC[1] && !pAdapter->Addr.wMAC[2] ) 
    {
        EdbgOutputDebugString
        (
            "Invalid Ethernet address read from the debug ethernet controller, check switch settings\n"
        );
        return (FALSE);
    }

    //
    // Save out local mac address.
    //
    memcpy ((char *)wLocalMAC, pAdapter->Addr.wMAC, sizeof(wLocalMAC));
    
    EdbgOutputDebugString("Debug Ethernet card initialized, MAC Address:%B:%B:%B:%B:%B:%B\r\n",
                          pAdapter->Addr.wMAC[0] & 0x00FF, pAdapter->Addr.wMAC[0] >> 8,
                          pAdapter->Addr.wMAC[1] & 0x00FF, pAdapter->Addr.wMAC[1] >> 8,
                          pAdapter->Addr.wMAC[2] & 0x00FF, pAdapter->Addr.wMAC[2] >> 8  );

#ifdef IMGSHAREETH 
    VBridgeInit();
    VBridgeKSetLocalMacAddress((char *)wLocalMAC);
#endif



    // Enable filtering of broadcast packets (all except ARP packets) to reduce 
    // overhead.  We still have to take an interrupt, but the driver can 
    // quickly determine whether a packet may be discarded without having to 
    // copy all the data from the chip.   Note that we cannot turn this option 
    // on until DHCP is done processing, since some DHCP servers return 
    // responses in broadcast frames.

#ifndef IMGSHAREETH
    if (pAdapter->Addr.dwIP)
        pfnEDbgSetOptions(OPT_BROADCAST_FILTERING);
#endif

    DEBUGMSG(1, (TEXT("-OEMEthInit\r\n")));

    return (TRUE);
}

/* OEMEthEnableInts
 *
 *  Turn on HW interrupts.  Return TRUE if interrupts supported, or FALSE
 *  to run in polling mode for all clients.
 */
void
OEMEthEnableInts()
{

    if(pfnEDbgEnableInts)
    {
        pfnEDbgEnableInts();
    }
}

/* OEMEthDisableInts
 *
 *  Disable HW interrupts.
 */
void
OEMEthDisableInts()
{
    if(pfnEDbgDisableInts)
    {
        pfnEDbgDisableInts();
    }
}

#ifdef IMGSHAREETH

/* ProcessVMiniSend()
 *
 *      This routine drains the pending VMINI TX.
 * 
 */

void
ProcessVMiniSend(void)
{
    PBYTE   pVMiniData;
    DWORD   dwVMiniDataLength;

    ////////////////////////////////////////////////////////////////////////////
    //  Handle the filter if we need to..
    //
    if (bNewFilter && pfnCurrentPacketFilter)
    {
        bNewFilter = FALSE;     
        pfnCurrentPacketFilter(dwFilter);
    }       

    //
    //  Handle new multicast list..
    //  
    
    if (bNewMulticast && pfnMulticastList)
    {
        bNewMulticast = FALSE;
        pfnMulticastList(
            (PUCHAR)ucMultiAddr,
            dwNoOfEntry);
    }

    ////////////////////////////////////////////////////////////////////////////
    //  Consume all the client packets.
    //
    while (VBridgeKGetOneTxBuffer(&pVMiniData, &dwVMiniDataLength) == TRUE)
    {
        pfnEDbgSendFrame (pVMiniData, dwVMiniDataLength);
        VBridgeKGetOneTxBufferComplete(pVMiniData);
    } 

}   //  ProcessVMiniSend()

#endif

/* OEMEthISR
 *
 *    ISR routine, called by EDBG IST when Ethernet controller interrupts. Also
 *    called in polling mode, to check for received data.
 *
 * Return Value:
 *    Return bitmask indicating which interrupts are pending.  Currently, the ones
 *    that EDBG cares about are the following (others should be handled internally):
 *       INTR_TYPE_RX   -- Receive interrupt. IST will call into GetFrame to read data.
 */
DWORD
OEMEthISR()
{
    DWORD dwReturnValue = 0;

    EdbgOutputDebugString("X");

#ifdef IMGSHAREETH
    ProcessVMiniSend();
#endif
    if(pfnEDbgGetPendingInts)
    {
        dwReturnValue = pfnEDbgGetPendingInts();
    }

    return dwReturnValue;    
}

/* OEMEthGetFrame
 *
 *   Check to see if a frame has been received, and if so copy to buffer. An optimization
 *   which may be performed in the Ethernet driver is to filter out all received broadcast

⌨️ 快捷键说明

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