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

📄 halether.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*   The content of this file or document is CONFIDENTIAL and PROPRIETARY
*   to Jade Technologies Co., Ltd.  It is subjected to the terms of a
*   License Agreement between Licensee and Jade Technologies Co., Ltd.
*   restricting among other things, the use, reproduction, distribution
*   and transfer.  Each of the embodiments, including this information 
*   and any derivative work shall retain this copyright notice.
* 
*   Copyright (c) 2004 - 2005 Jade Technologies Co., Ltd. 
*   All rights reserved.
 * ----------------------------------------------------------------
 * File:     halether.c,v
 * Revision: 1.0
 * ----------------------------------------------------------------
 * $
 *
 * 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.
 *
 */
#include <windows.h>
#include <nkintr.h>
#include <ethdbg.h>
#include <halether.h>
#include <drv_glob.h>
#include <platform.h>
#include <oalintr.h>
#include <kitl.h>

#include <pl031.h>  // RTC

#define pDriverGlobals  ((PDRIVER_GLOBALS) DRIVER_GLOBALS_PHYSICAL_MEMORY_START)
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;


extern DWORD EdbgDebugZone;

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

typedef struct vendorid {
    DWORD dwUpperMAC; // first 3 bytes of ethernet address
    char  *szAbbrev;
} VENDORID;

static const VENDORID VendorIds[] = {
    {0x00006E, "AE" }, // Artisoft
    {0x000094, "AS" }, // ASANTE
    {0x0000E8, "AC" }, // Accton Technology
    {0x004005, "LS" }, // LinkSys
    {0x004033, "AD" }, // Addtron Technology
    {0x004092, "ASP"}, // ASP Computer Products
    {0x00800F, "SMC"}, // SMC
    {0x008048, "CPX"}, // Compex
    {0x0080AD, "CN" }, // CNET Technologies
    {0x0080C8, "DL" }, // D-Link
    {0x00A0D2, "AT" }, // Allied TeleSyn
    {0x00C00D, "ALR"}, // Advanced Logic Research
    {0x00C06D, "BR" }, // Boca Research
    {0x00C0DF, "GE" }, // Kye International GENIUS GE2000 series
    {0x00C0F0, "KS" }, // Kingston
    {0x4854E8, "WB" }  // WinBond Electronics Corp
};

#define NUM_VENDORIDS (sizeof(VendorIds)/sizeof(VENDORID))

#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

static void
itoa10( int n, char s[] )
{
    int i = 0; 

    // Get absolute value of number
    unsigned int val = (unsigned int)((n < 0) ? -n : n);

    // Extract digits in reverse order
    do {
        s[i++] = (val % 10) + '0';
    } while (val /= 10);

    // Add sign if number negative
    if (n < 0) s[i++] = '-';

    s[i--] = '\0';

    // Reverse string
    for (n = 0; n < i; n++, i--) {
        char swap = s[n];
        s[n] = s[i];
        s[i] = swap;
    }
}

static DWORD
UpperDWFromMAC(EDBG_ADDR * pAddr)
{
    DWORD ret;

    //
    // The WORDs in wMAC field are in net order, so we need to do some
    // serious shifting around.
    // A hex ethernet address of 12 34 56 78 9a bc is stored in wMAC array as
    // wMAC[0] = 3412, wMAC[1] = 7856, wMAC[2] = bc9a.
    // The 4 byte return value should look like 0x00123456
    //
    ret = (pAddr->wMAC[0] & 0x00ff) << 16;
    ret |= pAddr->wMAC[0] & 0xff00;
    ret |= pAddr->wMAC[1] & 0x00ff;
    return ret;
}

void
CreateDeviceName(EDBG_ADDR *pMyAddr, char *szBuf)
{
    int i;
    DWORD dwUpperMAC = UpperDWFromMAC(pMyAddr);

    strcpy(szBuf,PLATFORM_STRING);
    szBuf += strlen(szBuf);

    for (i=0;i<NUM_VENDORIDS;i++) {
        if (dwUpperMAC == VendorIds[i].dwUpperMAC) {
            strcat(szBuf,VendorIds[i].szAbbrev);
            szBuf += strlen(szBuf);
            break;
        }
    }
    itoa10(((pMyAddr->wMAC[2]>>8) | ((pMyAddr->wMAC[2] & 0x00ff) << 8)), szBuf);
}

/* OEMEthInit
 *
 *  Initialization routine - called from EdbgInit() to perform platform specific
 *  specific HW init.  The Z228 Development Board platform uses an SMSC91C111 Ethernet 
 *  controller
 *
 *  Return Value:
 *    Return TRUE if init is successful, FALSE if error.
 */
BOOL
OEMEthInit(EDBG_ADAPTER *pAdapter)
{

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

    // Some parameters included in boot args for future use, make sure these aren't set
    switch (pBootArgs->ucEdbgAdapterType) {

    case EDBG_ADAPTER_OEM:
        pfnEDbgInit           = SMCInit;
        pfnEDbgEnableInts     = SMCEnableInts;     
        pfnEDbgDisableInts    = SMCDisableInts;    
        pfnEDbgGetPendingInts = SMCGetPendingInterrupts; 
        pfnEDbgGetFrame       = SMCGetFrame;       
        pfnEDbgSendFrame      = SMCSendFrame;      
        pfnEDbgReadEEPROM     = NULL;     
        pfnEDbgWriteEEPROM    = NULL;    
        pfnEDbgSetOptions     = NULL;
        pfnCurrentPacketFilter= SMCCurrentPacketFilter;
        pfnMulticastList      = SMCMulticastList;
        EdbgOutputDebugString("INFO: EDBG using Smc9000 controller.\r\n");
        break;

    default:

        EdbgOutputDebugString("Unsupported debug Ethernet parameters - adapter: %u, IRQ:%u\n",
                              pBootArgs->ucEdbgAdapterType, pBootArgs->ucEdbgIRQ);
        return (FALSE);
    }
        EdbgOutputDebugString("+pfnEDbgInit\n");


    if (!pfnEDbgInit((BYTE *) (VA_EDBG_BASE),1,pAdapter->Addr.wMAC) )
    {
        EdbgOutputDebugString("pfnEDbgInit error\n");

        return (FALSE);
    }

        EdbgOutputDebugString("-pfnEDbgInit\n");
		
// eboot writes MAC address into FLASH 0xC40C00018; KITL read the MAC from this address

//		pAdapter->Addr.wMAC[0] = *(PUSHORT)0x8BEE0000 ;
//		pAdapter->Addr.wMAC[1] = *(PUSHORT)0x8BEE0004 ;
//		pAdapter->Addr.wMAC[2] = *(PUSHORT)0x8BEE0008 ;

		pAdapter->Addr.wMAC[0] = (*(USHORT *)0x800C0018)&0xFFFF;
	    	pAdapter->Addr.wMAC[1] = (USHORT)(((*(ULONG *)0x800C0018)>>16)&0xFFFF);
	    	pAdapter->Addr.wMAC[2] = (*(USHORT *)0x800C001C)&0xFFFF;
		
    // Check the MAC address

    if ( !pAdapter->Addr.wMAC[0] && !pAdapter->Addr.wMAC[1] && !pAdapter->Addr.wMAC[2] ) {
        EdbgOutputDebugString("Invalid Ethernet address read from the debug ethernet controller\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

    // Fill in our SYSINTR value for the EDBG subsystem. Since we have limited IRQ
    // resources, just run in polled mode unless otherwise configured.
    if ( pBootArgs->ucEdbgIRQ )
    {
     //   pAdapter->SysIntrVal = OEMRequestSysIntr(pBootArgs->ucEdbgIRQ);
     	  pAdapter->SysIntrVal = SYSINTR_EDBG;
        RETAILMSG(1, (TEXT("INFO: Ethdbg IRQ = 0x%x  SYSINTR = 0x%x\r\n"), pBootArgs->ucEdbgIRQ, pAdapter->SysIntrVal));

    }
    else
    
    {
        pAdapter->SysIntrVal = KITL_SYSINTR_NOINTR;
    }

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

    // 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()
{
    pfnEDbgEnableInts();
}


/* OEMEthDisableInts
 *
 *  Disable HW interrupts.
 */
void
OEMEthDisableInts()
{
    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()
{

#ifdef IMGSHAREETH
    ProcessVMiniSend();
#endif

    return (pfnEDbgGetPendingInts());    
}

⌨️ 快捷键说明

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