halether.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 848 行 · 第 1/2 页
C
848 行
/*++
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 Microsoft Corporation
Module Name:
halether.c
Abstract:
Platform specific code for debug ethernet services (debug messages,
kernel debugger, text shell (CESH)). These functions are all called
from ethdbg.lib. They are non-preemptible, and cannot make any system calls.
Functions:
Notes:
--*/
// FOR MIPS ONLY.
// Not sure yet ethernet support for SH4
#ifdef MIPS
#include <windows.h>
#include <nkintr.h>
#include <oalintr.h>
#include <alt_def.h>
#include "ethernet.h"
#include <oalio.h>
#include <eglobal.h>
#include <vrc5074.h>
// Needed for the Cedar BSP since halether.h can't be updated.
//
BOOL DEC21140InitDMABuffer(DWORD dwStartAddress, DWORD dwSize);
BOOL DEC21140SetMACAddress(USHORT MacAddr[3]);
// No Vmini support in Cedar.
#undef IMGSHAREETH
#ifdef IMGSHAREETH
BOOL bNewFilter = FALSE; // User mode --> Kernel mode to set new filter.
DWORD dwFilter; // The filter..
PFN_EDBG_CURRENT_PACKET_FILTER pfnCurrentPacketFilter;
PFN_EDBG_MULTICAST_LIST pfnMulticastList;
#endif // IMGSHAREETH.
/////////////////////////////////////////////////////////////////////////////////
// Depending on which NIC deteceted, we'll update this table accordingly...
//
typedef struct _NIC_FTBL
{
BOOL (*NIC_Init) (BYTE *pbBaseAddress, ULONG dwMemOffset, USHORT MacAddr[3]);
void (*NIC_EnableInts) (void);
void (*NIC_DisableInts) (void);
DWORD (*NIC_GetPendingInts) (void);
UINT16 (*NIC_GetFrame) (BYTE *pbData, UINT16 *pwLength);
UINT16 (*NIC_OtherGetFrame) (BYTE *pbData, UINT16 *pwLength);
UINT16 (*NIC_SendFrame) (BYTE *pbData, DWORD dwLength);
BOOL (*NIC_InitDMABuffer) (DWORD dwStartAddress, DWORD dwSize);
DWORD (*NIC_QueryBufferSize) (void);
DWORD (*NIC_QueryDescriptorSize) (void);
} NIC_FTBL, *PNIC_FTBL;
NIC_FTBL DEC21140FTbl =
{
DEC21140Init,
DEC21140EnableInts,
NULL,
DEC21140GetPendingInts,
NULL,
DEC21140GetFrame,
DEC21140SendFrame,
DEC21140InitDMABuffer,
DEC21140QueryBufferSize,
DEC21140QueryDescriptorSize
};
NIC_FTBL NE2000FTbl =
{
NE2000Init,
NE2000EnableInts,
NE2000DisableInts,
NE2000GetPendingInts,
NE2000GetFrame,
NULL,
NE2000SendFrame,
NULL, // NE2000 Does not need these functions...
NULL,
NULL
};
PNIC_FTBL NIC_FTbl;
BOOL bDecChip = FALSE;
/////////////////////////////////////////////////////////////////////////////////
// WARNING --- WARNING --- WARNING ---
// Still one peculiarity unresolved.
// If EdbgOutputDebugString() is called early during the startup, it will cause the
// whole system to freeze.
// Investigation shows that it's frozen in the OEMWriteDebugByte() where it
// loops forever waiting for "tx holding register empty" in the UART.
//
// Hence all reference to EdbgOutputDebugString() in NE2000.c and hal are redirected
// to local EdbgOutputDebugString which will simply use OutputDebugString() instead
// of checking whether or not it should pump to ethernet (which is what actually
// done in ethdbg.lib). [Note that if the ethdbg itself uses the function, we
// can't prevent it from here...]
//
// So here we go...
// ALL EdbgOutputDebugString() WILL GO OUT SERIAL !!!
// The target audience will just be those that trouble shooting the HAL, and NE2000
// library. No one else should be affected.
//
//
static void vOutputFormatString(const UCHAR *sz, va_list vl);
void
localEdbgOutputDebugString(const char *sz, ...)
{
;
// Do nothing !!!
}
void
localDEBUGMSG (const char *sz, ...)
{
;
// Do nothing !!!
}
USHORT wLocalMAC[3]; // Global, so that oemioctl handling for IOCTL_HAL_GET_UUID can
// return our MAC address as a form of unique ID
// NOTE: This function only works if i is greater than 0.
// It's only used in this file and we know that
// we never call it with anything less or equal 0.
// It must be modified if you need to extended to
// work on generic integer.
static void
itoa10(
int i,
char * a
)
{
char * p = a;
int c = 0;
int n = i;
char swap;
//
// Build the ascii string in reverse digit order
//
while (n) {
*p = (char)(n % 10) + '0';
n /= 10;
p++;
c++;
}
*p = 0;
c--;
//
// Reverse the string in place to correct order
//
for (n = 0; n < c; n++, c--) {
swap = a[n];
a[n] = a[c];
a[c] = 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)
{
DWORD dwUpperMAC = UpperDWFromMAC(pMyAddr);
strcpy(szBuf,PLATFORM_STRING);
szBuf += strlen(szBuf);
itoa10(((pMyAddr->wMAC[2]>>8) | ((pMyAddr->wMAC[2] & 0x00ff) << 8)), szBuf);
}
#ifdef IMGSHAREETH
void
ProcessVMiniSend(void)
{
PBYTE pVMiniData;
DWORD dwVMiniDataLength;
////////////////////////////////////////////////////////////////////////////
// Handle the filter if we need to..
//
if (bNewFilter && pfnCurrentPacketFilter)
{
bNewFilter = FALSE;
pfnCurrentPacketFilter(dwFilter);
}
////////////////////////////////////////////////////////////////////////////
// Consume all the client packets.
//
while (VBridgeKGetOneTxBuffer(&pVMiniData, &dwVMiniDataLength) == TRUE)
{
NIC_FTbl->NIC_SendFrame(pVMiniData, dwVMiniDataLength);
VBridgeKGetOneTxBufferComplete(pVMiniData);
}
} // ProcessVMiniSend()
#endif // IMGSHAREETH.
/////////////////////////////////////////////////////////////////////////////////
// OEMEthInit
//
// Initialization routine - called from EdbgInit() to perform platform specific
// HW init.
// Return Value:
// Return TRUE if init is successful, FALSE if error.
#define NIC_DESCRIPTORS_HEAD 0xA3BE0000
#define NIC_BUFFER_SIZE 0x00200000
BOOL
OEMEthInit(
EDBG_ADAPTER *pAdapter) // OUT - Pointer to adapter info structure. Filled
// in with address and SYSINTR info.
{
EDBG_ADDR MyAddr; // Device's IP and MAC addresses.
DWORD EtherCardIoAddress = 0; // I/O Address of Ether 16 NIC.
DWORD EtherCardIrq = 0;
DWORD dwMemOffset = 0;
DWORD dwIP = 0;
PDEVICE_NETWORK_INFO pLocalDeviceNetworkInfo = NULL;
////////////////////////////////////////////////////////////////////////////
// Initialize Ether Card.
// Boston (DDB5476) supports DEC21140 for EDBG.
//
EtherCardIoAddress = pDriverGlobals->EtherIoAddr | KSEG1_BASE | PCI_IO_BASE;
EtherCardIrq = pDriverGlobals->EtherIntrNumber & CLEAN_UP;
////////////////////////////////////////////////////////////////////////////
// Use IRQ to determine which chip to talk to...
//
dwMemOffset = 0;
if ((pDriverGlobals->EtherIntrNumber & ~CLEAN_UP) == DEC21140_DEBUG)
{
bDecChip = TRUE;
NIC_FTbl = &DEC21140FTbl;
// Get the MAC address for Boston (it's stored in system flash).
//
pLocalDeviceNetworkInfo =
(PDEVICE_NETWORK_INFO) DEVICE_NETWORK_INFO_LOCATION;
if (pLocalDeviceNetworkInfo->dwSignature == VALID_INFO_SIGNATURE &&
pLocalDeviceNetworkInfo->dwMACSignature == VALID_MAC_ADDRESS)
{
MyAddr.wMAC[0] = pLocalDeviceNetworkInfo->wMAC[0];
MyAddr.wMAC[1] = pLocalDeviceNetworkInfo->wMAC[1];
MyAddr.wMAC[2] = pLocalDeviceNetworkInfo->wMAC[2];
dwIP = pLocalDeviceNetworkInfo->dwIP;
// Call into the DEC21140 driver and give it the MAC (it'll need it
// to set up perfect filtering).
DEC21140SetMACAddress(MyAddr.wMAC);
}
else
{
EdbgOutputDebugString ("ERROR: No MAC address assigned to the DEC21140...\r\n");
return(FALSE);
}
// Initialize the NIC DMA buffer.
//
if (!NIC_FTbl->NIC_InitDMABuffer(NIC_DESCRIPTORS_HEAD, NIC_BUFFER_SIZE))
{
EdbgOutputDebugString ("ERROR: Failed to initialize NIC DMA buffer. .\r\n");
return(FALSE);
}
// Initialize the NIC. Note we're passing NULL for the MAC address.
// This signals the public DEC21140 driver not to look for the MAC
// itself, since it doesn't know how to find it on Boston.
//
if (!(NIC_FTbl->NIC_Init((PBYTE)EtherCardIoAddress, 0, NULL)))
{
EdbgOutputDebugString ("ERROR: Failed to initialize NIC...\r\n");
return(FALSE);
}
}
else if ((pDriverGlobals->EtherIntrNumber & ~CLEAN_UP) == NE2000_DEBUG)
{
bDecChip = FALSE;
NIC_FTbl = &NE2000FTbl;
if (!(NIC_FTbl->NIC_Init((PBYTE)EtherCardIoAddress, 0, MyAddr.wMAC)))
{
EdbgOutputDebugString ("ERROR: Failed to initialize NE2000 NIC...\r\n");
return(FALSE);
}
}
// Here we simply update the pAdapter.
//
pAdapter->Addr.wMAC[0] = MyAddr.wMAC[0];
pAdapter->Addr.wMAC[1] = MyAddr.wMAC[1];
pAdapter->Addr.wMAC[2] = MyAddr.wMAC[2];
pAdapter->Addr.dwIP = dwIP;
pAdapter->Addr.wPort = 0;
// Save out local mac address.
//
memcpy( (char *)wLocalMAC, pAdapter->Addr.wMAC, sizeof(wLocalMAC) );
// Use Vmini to share ethernet port, since there's only one on-board NIC.
#ifdef IMGSHAREETH
VBridgeInit();
VBridgeKSetLocalMacAddress((char *)wLocalMAC);
#endif // IMGSHAREETH.
// Store DHCP lease and EDBG flag information.
//
pAdapter->DHCPLeaseTime = pDriverGlobals->DHCPLeaseTime;
pAdapter->EdbgFlags = 0;
// Hardcode the EDBG Ethernet controller interrupt.
//
pAdapter->SysIntrVal = SYSINTR_ETHER;
return(TRUE);
}
/////////////////////////////////////////////////////////////////////////////////
// OEMEthEnableInts
// Turn on HW interrupts.
void
OEMEthEnableInts()
{
NIC_FTbl->NIC_EnableInts();
}
/////////////////////////////////////////////////////////////////////////////////
// OEMEthEnableInts
// Disable HW interrupts
void
OEMEthDisableInts()
{
NIC_FTbl->NIC_DisableInts();
}
////////////////////////////////////////////////////////////////////////////////
// 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()
{
// Vmini.
#ifdef IMGSHAREETH
ProcessVMiniSend();
#endif // IMGSHAREETH.
return NIC_FTbl->NIC_GetPendingInts();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?