📄 ether.c
字号:
//
// 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.
//
#include <windows.h>
#include <halether.h>
#include <s2440.h>
#include "loader.h"
#include <drv_glob.h>
#define FROM_BCD(n) ((((n) >> 4) * 10) + ((n) & 0xf))
#define TO_BCD(n) ((((n) / 10) << 4) | ((n) % 10))
extern PDRIVER_GLOBALS pDriverGlobals;
//
// 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;
BOOL CS8900DBG_Init(PBYTE iobase, DWORD membase, USHORT MacAddr[3]);
UINT16 CS8900DBG_GetFrame(PBYTE pbData, UINT16 *pwLength);
UINT16 CS8900DBG_SendFrame(PBYTE pbData, DWORD dwLength);
/*
@func BOOL | InitEthDevice | Initializes the Ethernet device to be used for download.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL InitEthDevice(PBOOT_CFG pBootCfg)
{
USHORT wMAC[3];
PBYTE pBaseIOAddress = NULL;
DWORD dwMultiplier = 0;
// Boot CS8900.
//
if (!pBaseIOAddress)
{
// Use the MAC address programmed into flash by the user.
//
memcpy(wMAC, pBootCfg->EdbgAddr.wMAC, 6);
pfnEDbgInit = CS8900DBG_Init;
pfnEDbgGetFrame = CS8900DBG_GetFrame;
pfnEDbgSendFrame = CS8900DBG_SendFrame;
pBaseIOAddress = (PBYTE)CS8900DBG_IOBASE;
dwMultiplier = CS8900DBG_MEMBASE;
memcpy(pDriverGlobals->eth.TargetAddr.wMAC, pBootCfg->EdbgAddr.wMAC, 6);
pDriverGlobals->misc.EbootDevice = (UCHAR)DOWNLOAD_DEVICE_CS8900;
}
// Initialize the built-in Ethenet controller.
//
if (!pfnEDbgInit((PBYTE)pBaseIOAddress, dwMultiplier, wMAC))
{
EdbgOutputDebugString("ERROR: InitEthDevice: Failed to initialize Ethernet controller.\r\n");
return(FALSE);
}
// Make sure MAC address has been programmed.
//
if (!wMAC[0] && !wMAC[1] && !wMAC[2])
{
EdbgOutputDebugString("ERROR: InitEthDevice: Invalid MAC address read from NIC.\r\n");
return(FALSE);
}
memcpy(&pDriverGlobals->eth.TargetAddr.wMAC, &wMAC, (3 * sizeof(USHORT)));
return(TRUE);
}
/*
@func BOOL | OEMGetRealTime | Returns the current wall-clock time from the RTC.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
static BOOL OEMGetRealTime(LPSYSTEMTIME lpst)
{
volatile RTCreg *s2440RTC = (RTCreg *)RTC_BASE;
do
{
lpst->wYear = FROM_BCD(s2440RTC->rBCDYEAR) + 2000 ;
lpst->wMonth = FROM_BCD(s2440RTC->rBCDMON & 0x1f);
lpst->wDay = FROM_BCD(s2440RTC->rBCDDAY & 0x3f);
lpst->wDayOfWeek = (s2440RTC->rBCDDATE - 1);
lpst->wHour = FROM_BCD(s2440RTC->rBCDHOUR & 0x3f);
lpst->wMinute = FROM_BCD(s2440RTC->rBCDMIN & 0x7f);
lpst->wSecond = FROM_BCD(s2440RTC->rBCDSEC & 0x7f);
lpst->wMilliseconds = 0;
}
while(!(lpst->wSecond));
return(TRUE);
}
/*
@func DWORD | OEMEthGetSecs | Returns a free-running seconds count.
@rdesc Number of elapsed seconds since last roll-over.
@comm
@xref
*/
DWORD OEMEthGetSecs(void)
{
SYSTEMTIME sTime;
OEMGetRealTime(&sTime);
return((60UL * (60UL * (24UL * (31UL * sTime.wMonth + sTime.wDay) + sTime.wHour) + sTime.wMinute)) + sTime.wSecond);
}
/*
@func BOOL | OEMEthGetFrame | Reads data from the Ethernet device.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL OEMEthGetFrame(PUCHAR pData, PUSHORT pwLength)
{
return pfnEDbgGetFrame(pData, pwLength);
}
/*
@func BOOL | OEMEthSendFrame | Writes data to an Ethernet device.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL OEMEthSendFrame(PUCHAR pData, DWORD dwLength)
{
BYTE Retries = 0;
while(Retries++ < 4)
{
if (!pfnEDbgSendFrame(pData, dwLength))
return(TRUE);
EdbgOutputDebugString("INFO: OEMEthSendFrame: retrying send (%u)\r\n", Retries);
}
return(FALSE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -