📄 halether.c
字号:
/*
* 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 + -