Microsoft KB Archive/252670

= FIX: CEPC Ethernet Boot Loader (Eboot.bin) Appears to Halt During PCI Bus Enumeration =

Article ID: 252670

Article Last Modified on 12/26/2003

-

APPLIES TO


 * Microsoft Windows CE Platform Builder 2.12

-



This article was previously published under Q252670



SYMPTOMS
On a Windows CE PC-based (CEPC) hardware platform, the Ethernet boot loader (Eboot.bin) scans for devices on the Peripheral Component Interconnect (PCI) bus and presents a comprehensive inventory of the devices found. However, certain hardware implementations cause Eboot.bin to appear to stop responding (halt or hang) during this scanning process.



CAUSE
Certain host-PCI hardware bridge implementations (a comprehensive list of such devices has not been developed) demonstrate a bus address aliasing problem whereby they respond positively to queries with devices that actually reside on a lower-numbered bus. This problem is apparent when you scan bus numbers greater than some hardware-assumed maximum number. The result is a slow-down of the PCI bus enumeration process. Because phantom devices are being found, the enumeration process takes a long time (giving the appearance that the system has halted). Also, detecting phantom devices on these buses can cause other side effects.



RESOLUTION
The solution to the problem is to modify the Pciconfig.c file to first establish a maximum PCI bus number present in the system. The Pciconfig.c file does this by scanning PCI bus 0 (zero) for the highest sub-bus number. Once the PCI enumeration loop finishes scanning this highest-numbered bus, the process ends.

Included below is the entire contents of the Pciconfig.c file for the Windows CE Platform Builder version 2.12 Eboot.bin file. Make a backup copy of the existing Pciconfig.c file on your computer (Wince212\Platform\Cepc\Eboot\Pciconfig.c), replace the contents of the original with what follows, and then rebuild the Eboot.bin image: //-- // // 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-1999  Microsoft Corporation // //--
 * 1) include 
 * 2) include 
 * 3) include 
 * 4) include 
 * 5) include 


 * 1) include "eboot.h"
 * 2) include "ethdown.h"
 * 3) include 
 * 4) include 
 * 5) include 


 * 1) undef TEXT
 * 2) define TEXT
 * 3) define NKDbgPrintfW   EdbgOutputDebugString

const LPSTR BaseClass[] = { TEXT("PRE_20"), TEXT("MASS_STORAGE_CTLR"), TEXT("NETWORK_CTLR"), TEXT("DISPLAY_CTLR"), TEXT("MULTIMEDIA_DEV"), TEXT("MEMORY_CTLR"), TEXT("BRIDGE_DEV"), TEXT("SIMPLE_COMMS_CTLR"), TEXT("BASE_SYSTEM_DEV"), TEXT("INPUT_DEV"), TEXT("DOCKING_STATION"), TEXT("PROCESSOR"), TEXT("SERIAL_BUS_CTLR") };

//-- //-- VOID PrintConfig(   int bus,    int device,    int function,    PPCI_COMMON_CONFIG pCfg    ) {   DWORD i;

RETAILMSG(1, (TEXT("========================================================\r\n"))); RETAILMSG(1, (TEXT(" Bus, Device, Function = %d, %d, %d\r\n"), bus, device, function)); RETAILMSG(1, (TEXT(" Vendor ID, Device ID = 0x%H, 0x%H\r\n"), pCfg->VendorID, pCfg->DeviceID)); RETAILMSG(1, (TEXT(" Base Class, Subclass = %d, %d => %s\r\n"), pCfg->BaseClass, pCfg->SubClass, BaseClass[pCfg->BaseClass]));

if ((pCfg->HeaderType & 0x7F) == PCI_DEVICE_TYPE) {

RETAILMSG(1, (TEXT(" Interrupt            = %d\r\n"), pCfg->u.type0.InterruptLine)); for (i = 0; i < PCI_TYPE0_ADDRESSES; i++) { if (pCfg->u.type0.BaseAddresses[i]) { if (pCfg->u.type0.BaseAddresses[i] & 1) { RETAILMSG(1, (TEXT(" BaseAddress[%d]       = 0x%x (I/O)\r\n"), i, pCfg->u.type0.BaseAddresses[i] & 0xFFFFFFFC)); } else { RETAILMSG(1, (TEXT(" BaseAddress[%d]       = 0x%x (Memory)\r\n"), i, pCfg->u.type0.BaseAddresses[i] & 0xFFFFFFE0)); }           }        }    } }

//-- //-- BYTE GetMaxBusNumber {   PCI_SLOT_NUMBER     slotNumber; PCI_COMMON_CONFIG  pciConfig; int                bus, device, function; int                length; BYTE               bMaxBus = 0;

//    // Scan bus 0 for bridges. They'll tell us the number of buses. //    bus = 0; 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));

if (length == 0 || pciConfig.VendorID == 0xFFFF) break;

if (pciConfig.BaseClass == PCI_CLASS_BRIDGE_DEV && pciConfig.SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI) { if (pciConfig.u.type1.SubordinateBusNumber > bMaxBus) { bMaxBus = pciConfig.u.type1.SubordinateBusNumber; }           }

if (function == 0 && !(pciConfig.HeaderType & 0x80)) break; }       if (length == 0) break; }

return bMaxBus; }

//-- //--
 * 1) define IGNOREBRIDGES 1    // Set to 0 to print out basic bridge info.

BOOL PrintPCIConfig {   PCI_SLOT_NUMBER     slotNumber; PCI_COMMON_CONFIG  pciConfig; int                bus, device, function; int                length; int                maxbus;

maxbus = (int) GetMaxBusNumber;

RETAILMSG(1, (TEXT("PCI Device Configurations (%d PCI bus(es) present)...\r\n"), maxbus + 1));

for (bus = 0; bus <= maxbus; 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));

if (length == 0 || pciConfig.VendorID == 0xFFFF) break;

if (pciConfig.BaseClass == 6) // Ignore bridges break;
 * 1) if IGNOREBRIDGES
 * 1) endif

PrintConfig(bus, device, function, &pciConfig); if (function == 0 && !(pciConfig.HeaderType & 0x80)) break; }           if (length == 0) break; }

if (length == 0 && device == 0) break; }

RETAILMSG(1, (TEXT("========================================================\r\n"))); return TRUE; }



STATUS
Microsoft has confirmed that this is a problem in the Microsoft products that are listed at the beginning of this article.

Additional query words: eboot PCI scan enumeration hang bootloader quit

Keywords: kbbug kbfix kboswince212fix kbetk212fix KB252670

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.