www.pudn.com > S2410_eboot.rar > 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#include #include #include "loader.h" #include #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 *s2410RTC = (RTCreg *)RTC_BASE; do { lpst->wYear = FROM_BCD(s2410RTC->rBCDYEAR) + 2000 ; lpst->wMonth = FROM_BCD(s2410RTC->rBCDMON & 0x1f); lpst->wDay = FROM_BCD(s2410RTC->rBCDDAY & 0x3f); lpst->wDayOfWeek = (s2410RTC->rBCDDATE - 1); lpst->wHour = FROM_BCD(s2410RTC->rBCDHOUR & 0x3f); lpst->wMinute = FROM_BCD(s2410RTC->rBCDMIN & 0x7f); lpst->wSecond = FROM_BCD(s2410RTC->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); }