//---------------------------------------------------------------------- // stolen from John's pci detect program //---------------------------------------------------------------------- void cmdScan(void) { FxU32 deviceNumber; FxBool firstDeviceDetected = FXFALSE; FxU32 deviceID = 0; FxU32 vendorID = 0; FxU32 baseAddress0 = 0; FxU32 command = 0; FxU32 classCode = 0; if (!pciOpen()) { fprintf(stderr, pciGetErrorString()); exit(100); } for ( deviceNumber = 0; deviceNumber < MAX_PCI_DEVICES; deviceNumber++ ) { if ( pciDeviceExists( deviceNumber ) ) { if ( !firstDeviceDetected ) { puts( "bus slot vendId devId baseAddr0 cmd description" ); puts( "--- ---- ------ ------ ---------- ------ -----------" ); firstDeviceDetected = FXTRUE; } pciGetConfigData( PCI_DEVICE_ID, deviceNumber, &deviceID ); pciGetConfigData( PCI_VENDOR_ID, deviceNumber, &vendorID ); pciGetConfigData( PCI_BASE_ADDRESS_0, deviceNumber, &baseAddress0 ); pciGetConfigData( PCI_COMMAND, deviceNumber, &command ); pciGetConfigData( PCI_CLASS_CODE, deviceNumber, &classCode ); printf( " %.02d %.02d 0x%.04lx 0x%.04lx 0x%.08x 0x%.04x %.8s:%.25s\n", deviceNumber>>5, deviceNumber&0x1f, vendorID, deviceID, baseAddress0, command, pciGetVendorName( (FxU16)vendorID ), pciGetClassName( classCode, deviceID ) ); } } }
/*------------------------------------------------------------------- Function: initEnumHardware Date: 10/9 Implementor(s): jdt Library: init Description: Calls a user supplied function on an initialized InitDeviceInfo structure for each device in the system. Calls a user supplied callback repeatedly for each device in the system. The callback can stop the enumeration cycle by return a value of FXTRUE. Arguments: cb - callback function of type INitHWEnumCallback which is called on an initialzied InitDeviceInfo structure Return: none -------------------------------------------------------------------*/ void initEnumHardware( InitHWEnumCallback *cb ) { FxU32 busLocation; FxU32 device; if ( !libInitialized ) { /* When initializing the Library snoop out all 3Dfx devices and fill a static data structure with pertinant data. */ numDevicesInSystem = 0; numSst1s = 0; if ( !pciOpen() ) return; for( busLocation = 0; busLocation < MAX_PCI_DEVICES; busLocation++ ) { if ( pciDeviceExists( busLocation ) ) { FxU32 vId, dId; pciGetConfigData( PCI_VENDOR_ID, busLocation, &vId ); pciGetConfigData( PCI_DEVICE_ID, busLocation, &dId ); GDBG_INFO((80, "initEnumHardware: Vendor: 0x%x Device: 0x%x\n", vId, dId)); #if defined( SST1 ) if ( (vId == TDFXVID) && (dId == SST1DID) ) { /* Detect SST1 */ FxU32 *base; sst1DeviceInfoStruct info; /* Scanline interleave must be two boards back to back if there is a second board in the system, and the previous board was SLI, then this is the slave */ if ( numDevicesInSystem > 0 ) { if ( hwInfo[numDevicesInSystem-1].hwClass==INIT_VOODOO && hwInfo[numDevicesInSystem-1].hwDep.vgInfo.sliDetect ) { hwInfo[numDevicesInSystem-1].hwDep.vgInfo.slaveBaseAddr = (FxU32)sst1InitMapBoard( numSst1s ); hwInfo[numDevicesInSystem-1].regs.hwDep.VGRegDesc.slavePtr = (FxU32*)hwInfo[numDevicesInSystem-1].hwDep.vgInfo.slaveBaseAddr; numSst1s++; continue; } } hwInfo[numDevicesInSystem].vendorID = (FxU16) vId; hwInfo[numDevicesInSystem].deviceID = (FxU16) dId; hwInfo[numDevicesInSystem].devNumber = numDevicesInSystem; hwInfo[numDevicesInSystem].hwClass = INIT_VOODOO; /* On SST-1 We Have to Initialize the Registers to Discover the configuration of the board */ #if 0 base = sst1InitMapBoard( numSst1s ); sst1InitRegisters( base ); #else base = (FxU32*)initMapBoard(numSst1s); #endif sst1InitGetDeviceInfo( base, &info ); hwInfo[numDevicesInSystem].hwDep.vgInfo.vgBaseAddr = (FxU32) base; hwInfo[numDevicesInSystem].hwDep.vgInfo.pfxRev = info.fbiRevision; hwInfo[numDevicesInSystem].hwDep.vgInfo.pfxRam = info.fbiMemSize; hwInfo[numDevicesInSystem].hwDep.vgInfo.nTFX = info.numberTmus; hwInfo[numDevicesInSystem].hwDep.vgInfo.tfxRev = info.tmuRevision; hwInfo[numDevicesInSystem].hwDep.vgInfo.tfxRam = info.tmuMemSize[0]; hwInfo[numDevicesInSystem].hwDep.vgInfo.sliDetect = info.sstSliDetect; hwInfo[numDevicesInSystem].hwDep.vgInfo.slaveBaseAddr = 0; hwInfo[numDevicesInSystem].regs.hwDep.VGRegDesc.baseAddress = base; hwInfo[numDevicesInSystem].regs.hwDep.VGRegDesc.slavePtr = 0; numSst1s++; numDevicesInSystem++; } #elif defined(SST96) #define IS_CHIP(name) (vId == name##VID && dId == name##DID) if (IS_CHIP(AT3D) || IS_CHIP(MCRX)) { if (IS_CHIP(MCRX)) { /* In the case of Macronix, look for 3d4/3f[2] == 1, as they set that bit when we're attached. */ FxU8 regVal; _outp(0x3d4, 0x3f); regVal = _inp(0x3d5); if (!(regVal & (1 << 2))) /* we're not there */ continue; } hwInfo[numDevicesInSystem].vendorID = (FxU16) vId; hwInfo[numDevicesInSystem].deviceID = (FxU16) dId; hwInfo[numDevicesInSystem].devNumber = numDevicesInSystem; hwInfo[numDevicesInSystem].hwClass = INIT_VG96; /* SST-96 initialization also retrieves board configuration info */ #if 0 init96MapBoard(&hwInfo[numDevicesInSystem].regs, &hwInfo[numDevicesInSystem].hwDep.vg96Info, (FxU16) vId, (FxU16) dId); #else initMapBoard(numDevicesInSystem); #endif hwInfo[numDevicesInSystem].hwDep.vg96Info.vgaBaseAddr = (FxU32)hwInfo[numDevicesInSystem].regs.hwDep.VG96RegDesc.partnerRegPtr; hwInfo[numDevicesInSystem].hwDep.vg96Info.vg96BaseAddr = (FxU32)hwInfo[numDevicesInSystem].regs.hwDep.VG96RegDesc.baseAddress; numDevicesInSystem++; } #else # error "Do hardware enumeration for this chip!" #endif } } /* Sanity Check for SLI detection */ for( device = 0; device < numDevicesInSystem; device++ ) { if ( hwInfo[device].hwClass == INIT_VOODOO && hwInfo[device].hwDep.vgInfo.sliDetect && hwInfo[device].hwDep.vgInfo.slaveBaseAddr == 0 ) { hwInfo[device].hwDep.vgInfo.sliDetect = FXFALSE; } } /* Initialize all drivers */ vgDriverInit( &contexts[INIT_VOODOO] ); vg96DriverInit( &contexts[INIT_VG96] ); /* Mark the library as initialized */ libInitialized = FXTRUE; } if ( cb ) { for( device = 0; device < numDevicesInSystem; device++ ) { cb( &hwInfo[device] ); } } return; } /* initEnumHardware */