📄 ether.c
字号:
pBootArgs->EdbgAddr.dwIP = gLoaderVars.nIPAddr;
MyAddr.dwIP = gLoaderVars.nIPAddr;
dwSubnetMask = gLoaderVars.nSubnetMask;
pDHCPLeaseTime = NULL; // Skip DHCP
pBootArgs->EdbgFlags |= EDBG_FLAGS_STATIC_IP;
RETAILMSG(1, (TEXT("Using static IP address: %s\r\n"),inet_ntoa(pBootArgs->EdbgAddr.dwIP)));
}
else
{
pBootArgs->EdbgAddr.dwIP = 0;
MyAddr.dwIP = 0;
}
// initialize TFTP transport
if (!EbootInitEtherTransport (&MyAddr, &dwSubnetMask, &fGotJumpImg, pDHCPLeaseTime,
BLDR_VERSION_MAJOR, BLDR_VERSION_MINOR, PLATFORM_STRING, szDeviceName, EDBG_CPU_i486, dwBootFlags)) {
return BL_ERROR;
}
// update BOOTARG with the info we got so far
memcpy(&pBootArgs->EdbgAddr,&MyAddr,sizeof(MyAddr));
pBootArgs->ucLoaderFlags = LDRFL_USE_EDBG | LDRFL_ADDR_VALID | LDRFL_JUMPIMG;
pBootArgs->DHCPLeaseTime = DHCPLeaseTime;
return fGotJumpImg? BL_JUMP : BL_DOWNLOAD;
}
BOOL OEMEthReadData(DWORD cbData, LPBYTE pbData)
{
return EbootEtherReadData (cbData, pbData);
}
BOOL
OEMEthGetFrame(
BYTE *pData, // OUT - Receives frame data
UINT16 *pwLength) // IN - Length of Rx buffer
// OUT - Number of bytes received
{
return(pfnEDbgGetFrame(pData, pwLength));
}
BOOL
OEMEthSendFrame(
BYTE *pData, // IN - Data buffer
DWORD dwLength) // IN - Length of buffer
{
int retries = 0;
// Let's be persistant here
while (retries++ < 4) {
if (!pfnEDbgSendFrame(pData, dwLength))
return TRUE;
else
RETAILMSG(1, (TEXT("ERROR: OEMEthSendFrame failure, retry %u\n"), retries));
}
return(FALSE);
}
DWORD
OEMEthGetSecs()
{
return(OEMGetSecs());
}
VOID
OEMEthLaunch(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr, const ROMHDR *pRomHdr)
{
EDBG_OS_CONFIG_DATA *pCfgData;
EDBG_ADDR EshellHostAddr;
memset (&EshellHostAddr, 0, sizeof (EshellHostAddr));
// wait for the jump command from eshell unless user specify jump directly
RETAILMSG(1, (TEXT("Download successful! Jumping to image at %Xh...\r\n"), dwLaunchAddr));
if (!(pCfgData = EbootWaitForHostConnect (&MyAddr, &EshellHostAddr))) {
RETAILMSG(1, (TEXT("EbootWaitForHostConenct failed, spin forever\r\n")));
SpinForever ();
}
// update service information
if (pCfgData->Flags & EDBG_FL_DBGMSG)
{
RETAILMSG(1, (TEXT("Enabling debug messages over Ethernet, IP: %s, port:%u\n"), inet_ntoa(pCfgData->DbgMsgIPAddr),ntohs(pCfgData->DbgMsgPort)));
memcpy(&pBootArgs->DbgHostAddr.wMAC,&EshellHostAddr.wMAC,6);
pBootArgs->DbgHostAddr.dwIP = pCfgData->DbgMsgIPAddr;
pBootArgs->DbgHostAddr.wPort = pCfgData->DbgMsgPort;
}
if (pCfgData->Flags & EDBG_FL_PPSH)
{
RETAILMSG(1, (TEXT("Enabling CESH over Ethernet, IP: %s, port:%u\n"), inet_ntoa(pCfgData->PpshIPAddr),ntohs(pCfgData->PpshPort)));
memcpy(&pBootArgs->CeshHostAddr.wMAC,&EshellHostAddr.wMAC,6);
pBootArgs->CeshHostAddr.dwIP = pCfgData->PpshIPAddr;
pBootArgs->CeshHostAddr.wPort = pCfgData->PpshPort;
}
if (pCfgData->Flags & EDBG_FL_KDBG)
{
RETAILMSG(1, (TEXT("Enabling KDBG over Ethernet, IP: %s, port:%u\n"), inet_ntoa(pCfgData->KdbgIPAddr),ntohs(pCfgData->KdbgPort)));
memcpy(&pBootArgs->KdbgHostAddr.wMAC,&EshellHostAddr.wMAC,6);
pBootArgs->KdbgHostAddr.dwIP = pCfgData->KdbgIPAddr;
pBootArgs->KdbgHostAddr.wPort = pCfgData->KdbgPort;
}
pBootArgs->ucEshellFlags = pCfgData->Flags;
pBootArgs->dwEBootFlag = BOOTARG_SIG;
memcpy (&pBootArgs->EshellHostAddr, &EshellHostAddr, sizeof(EDBG_ADDR));
//
// If we have been configured by the host to clear RAM, do so now.
// The RAM addresses are hard coded and must match those in the
// config.bib file for the image. Note that the stack and the driver
// globals memory are not in this range, and this will not hang if we
// run off the end of the memory actually present.
//
if (pBootArgs->ucEshellFlags & EDBG_FL_CLEANBOOT) {
// Clear here if needed.
}
((PFN_LAUNCH)(dwLaunchAddr))();
// Should never be reached...
SpinForever();
}
DWORD
FindPCINetCard(BYTE bIRQ)
{
PCI_SLOT_NUMBER slotNumber;
PCI_COMMON_CONFIG pciConfig;
int bus, device, function;
int length;
DWORD dwBaseAddr = 0;
DEBUGMSG(ZONE_INFO, (TEXT("Searching for PCI NetCard @ IRQ %d...\r\n"), bIRQ));
for (bus = 0; bus < PCI_MAX_BUS; bus++) {
for (device = 0; device < PCI_MAX_DEVICES; device++) {
slotNumber.u.bits.DeviceNumber = device;
for (function = 0; function < PCI_MAX_FUNCTION; function++) {
slotNumber.u.bits.FunctionNumber = function;
length = PCIGetBusDataByOffset(bus, slotNumber.u.AsULONG,
&pciConfig, 0, sizeof(pciConfig) -
sizeof(pciConfig.DeviceSpecific));
if (length == 0 || pciConfig.VendorID == 0xFFFF)
break;
if ((pciConfig.BaseClass == PCI_CLASS_NETWORK_CTLR) &&
(pciConfig.SubClass == PCI_SUBCLASS_NET_ETHERNET_CTLR)) {
if (pciConfig.u.type0.InterruptLine == bIRQ) {
//
// It's an ethernet controller with the matching IRQ
// setting. The InterruptLine register must have been
// set by the PnP BIOS.
//
dwBaseAddr = pciConfig.u.type0.BaseAddresses[0] & 0xFFFC;
DEBUGMSG(ZONE_INFO, (TEXT("Found PCI Net card @ 0x%X, IRQ%d\r\n"), dwBaseAddr, bIRQ));
break;
}
}
if (function == 0 && !(pciConfig.HeaderType & 0x80))
break;
}
if (dwBaseAddr || length == 0)
break;
}
if (dwBaseAddr || (length == 0 && device == 0))
break;
}
if (dwBaseAddr == 0) {
RETAILMSG(1, (TEXT("No PCI NetCard found @ IRQ %d...\r\n"), bIRQ));
}
return (dwBaseAddr);
}
BOOL InitNIC(void)
{
PCI_SLOT_NUMBER slotNumber;
PCI_COMMON_CONFIG pciConfig;
int bus, device, function;
int length;
BOOL bFoundIt;
bFoundIt = FALSE;
DEBUGMSG(ZONE_INFO, (TEXT("Initializing PCI NetCard...\r\n")));
for (bus = 0; bus < PCI_MAX_BUS; bus++) {
for (device = 0; device < PCI_MAX_DEVICES; device++) {
slotNumber.u.bits.DeviceNumber = device;
for (function = 0; function < PCI_MAX_FUNCTION; function++) {
slotNumber.u.bits.FunctionNumber = function;
length = PCIGetBusDataByOffset(bus, slotNumber.u.AsULONG,
&pciConfig, 0, sizeof(pciConfig) -
sizeof(pciConfig.DeviceSpecific));
if (length == 0 || pciConfig.VendorID == 0xFFFF)
break;
if ((pciConfig.BaseClass == PCI_CLASS_NETWORK_CTLR) &&
(pciConfig.SubClass == PCI_SUBCLASS_NET_ETHERNET_CTLR)) {
bFoundIt = TRUE;
break;
}
if (function == 0 && !(pciConfig.HeaderType & 0x80))
break;
}
if (bFoundIt || length == 0)
break;
}
if (bFoundIt || (length == 0 && device == 0))
break;
}
if (!bFoundIt) {
RETAILMSG(1, (TEXT("Error : Didn't find PCI Ethernet Controller (using ISA?)\r\n")));
return FALSE;
}
//
// Allow I/O and MMIO and assign an interrupt number.
//
pciConfig.Command |= 3;
pciConfig.u.type0.InterruptLine = DEBUG_ETHER_IRQ;
length = PCISetBusDataByOffset(bus, slotNumber.u.AsULONG,
&pciConfig, 0, sizeof(pciConfig) -
sizeof(pciConfig.DeviceSpecific));
return(TRUE);
}
// Stub LED display routine - called by NE2000 ethdbg driver.
VOID SC_WriteDebugLED(WORD wIndex, DWORD dwPattern)
{
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -