📄 ether.c
字号:
/*++
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-2000 Microsoft Corporation
Module Name: ether.c
Abstract: Boot loader ethernet download support functions.
Functions:
Notes:
--*/
#include <windows.h>
#include <ethdbg.h>
#include <nkintr.h>
#include <halether.h>
#include <ceddk.h>
#include <pc.h>
#include "bootarg.h"
#include "bldr.h"
#include "pci.h"
DWORD EdbgDebugZone = 0;
// Preprocessor definitions.
//
#define EDBG_ADAPTER_RTL8139 2
#define PLATFORM_STRING "CEPC"
// Type definitions.
//
typedef BOOL (*PFN_EDBG_INIT_DMABUF)(DWORD dwStartAddress, DWORD dwSize);
typedef struct vendorid // NIC vendor ID.
{
DWORD dwUpperMAC; // first 3 bytes of ethernet address.
char *szAbbrev; // Vendor name abbreviation.
} VENDORID;
// External variables.
//
extern BOOT_ARGS *pBootArgs;
LOADER_VARS gLoaderVars;
// Function prototypes.
//
DWORD FindPCINetCard(BYTE bIRQ);
BOOL InitNIC(void);
// Global variables.
//
EDBG_ADDR MyAddr; // CEPC address
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
//{0x00900B, "RT" } // RealTek
};
#define NUM_VENDORIDS (sizeof(VendorIds)/sizeof(VENDORID))
//
// Function pointers to the support library functions of the currently
// installed debug ethernet controller.
//
PFN_EDBG_INIT pfnEDbgInit;
PFN_EDBG_INIT_DMABUF pfnEDbgInitDMA;
PFN_EDBG_GET_FRAME pfnEDbgGetFrame;
PFN_EDBG_SEND_FRAME pfnEDbgSendFrame;
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;
}
static 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);
}
BOOL
OEMEthPlatformInit(VOID)
{
// Find and assign predetermined ILR value.
InitNIC();
if (pBootArgs->dwEdbgBaseAddr == 0) {
//
// The user can specify a ZERO base address and we'll try to find
// the PCI net card that matched the IRQ (set by the BIOS)
//
pBootArgs->dwEdbgBaseAddr = FindPCINetCard(pBootArgs->ucEdbgIRQ);
if (pBootArgs->dwEdbgBaseAddr == 0) {
RETAILMSG(1, (TEXT("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\r\n")));
RETAILMSG(1, (TEXT("---------------------------------------------\r\n")));
RETAILMSG(1, (TEXT(" Failed to locate the Ethernet board!\r\n")));
RETAILMSG(1, (TEXT(" A base I/O address of ZERO was specified, but\r\n")));
RETAILMSG(1, (TEXT(" no PCI Ethernet Card was found at IRQ %d.\r\n"), pBootArgs->ucEdbgIRQ));
RETAILMSG(1, (TEXT("---------------------------------------------\r\n")));
RETAILMSG(1, (TEXT("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n")));
SpinForever();
}
}
// Assign controller-specific callbacks.
switch (pBootArgs->ucEdbgAdapterType)
{
case EDBG_ADAPTER_SMC9000:
pfnEDbgInit = SMCInit;
pfnEDbgGetFrame = SMCGetFrame;
pfnEDbgSendFrame = SMCSendFrame;
break;
case EDBG_ADAPTER_NE2000:
pfnEDbgInit = NE2000Init;
pfnEDbgGetFrame = NE2000GetFrame;
pfnEDbgSendFrame = NE2000SendFrame;
break;
case EDBG_ADAPTER_RTL8139:
case EDBG_ADAPTER_OEM:
pfnEDbgInitDMA = RTL8139InitDMABuffer;
pfnEDbgInit = RTL8139Init;
pfnEDbgGetFrame = RTL8139GetFrame;
pfnEDbgSendFrame = RTL8139SendFrame;
if (!pfnEDbgInitDMA(ETHDMA_BUFF_BASE, ETHDMA_BUFF_SIZE))
RETAILMSG(1, (TEXT("ERROR: Enet buffer init failed.\r\n")));
break;
default:
RETAILMSG(1, (TEXT("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\r\n")));
RETAILMSG(1, (TEXT("---------------------------------------------\r\n")));
RETAILMSG(1, (TEXT(" Unsupported Ethernet Adapter %u\r\n"), pBootArgs->ucEdbgAdapterType));
RETAILMSG(1, (TEXT(" Please use :\r\n")));
RETAILMSG(1, (TEXT(" %2d : SMC9000\r\n"), EDBG_ADAPTER_SMC9000));
RETAILMSG(1, (TEXT(" %2d : NE2000 (or compatible)\r\n"), EDBG_ADAPTER_NE2000));
RETAILMSG(1, (TEXT(" %2d : RTL8139\r\n"), EDBG_ADAPTER_RTL8139));
RETAILMSG(1, (TEXT("---------------------------------------------\r\n")));
RETAILMSG(1, (TEXT("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n")));
return FALSE;
}
// call driver specific initialization
if (!pfnEDbgInit( (BYTE *) pBootArgs->dwEdbgBaseAddr, 1, MyAddr.wMAC)) {
RETAILMSG(1, (TEXT("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\r\n")));
RETAILMSG(1, (TEXT("---------------------------------------------\r\n")));
RETAILMSG(1, (TEXT(" Failed to initialize Ethernet board!\r\n")));
RETAILMSG(1, (TEXT(" Please check that the Ethernet card is\r\n")));
RETAILMSG(1, (TEXT(" properly installed and configured.\r\n")));
RETAILMSG(1, (TEXT("---------------------------------------------\r\n")));
RETAILMSG(1, (TEXT("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n")));
return FALSE;
}
RETAILMSG(1, (TEXT("Returned MAC 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));
return(TRUE);
}
DWORD OEMEthPreDownload(VOID)
{
DWORD dwSubnetMask, dwBootFlags = 0;
DWORD DHCPLeaseTime = DEFAULT_DHCP_LEASE, *pDHCPLeaseTime = &DHCPLeaseTime;
char szDeviceName[EDBG_MAX_DEV_NAMELEN];
BOOL fGotJumpImg = FALSE;
// check if this is a cold boot. Force download if so.
if (BOOTARG_SIG != pBootArgs->dwEBootFlag) {
dwBootFlags = EDBG_BOOTFLAG_FORCE_DOWNLOAD;
}
// Create device name based on Ethernet address
CreateDeviceName(&MyAddr, szDeviceName);
RETAILMSG(1, (TEXT("Using device name: %s\n"), szDeviceName));
// Check CMOS settings - have preset IP and subnet and want to use static?
if (!gLoaderVars.nUseDHCP && gLoaderVars.nIPAddr && gLoaderVars.nSubnetMask)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -