/**************************************************************************** * * SciTech OS Portability Manager Library * * ======================================================================== * * The contents of this file are subject to the SciTech MGL Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.scitechsoft.com/mgl-license.txt * * Software distributed under the License is distributed on an * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc. * * The Initial Developer of the Original Code is SciTech Software, Inc. * All Rights Reserved. * * ======================================================================== * * Language: ANSI C * Environment: any * * Description: Test program to test the PCI library functions. * ****************************************************************************/ #include "pmapi.h" #include "pcilib.h" #include #include #include #include /*------------------------- Global Variables ------------------------------*/ static int NumPCI = -1; static PCIDeviceInfo *PCI; static int *BridgeIndex; static int *DeviceIndex; static int NumBridges; static PCIDeviceInfo *AGPBridge = NULL; static int NumDevices; /*-------------------------- Implementation -------------------------------*/ /**************************************************************************** REMARKS: Enumerates the PCI bus and dumps the PCI configuration information to the log file. ****************************************************************************/ static void EnumeratePCI(void) { int i,index; PCIDeviceInfo *info; printf("Displaying enumeration of PCI bus (%d devices, %d display devices)\n", NumPCI, NumDevices); for (index = 0; index < NumDevices; index++) printf(" Display device %d is PCI device %d\n",index,DeviceIndex[index]); printf("\n"); printf("Bus Slot Fnc DeviceID SubSystem Rev Class IRQ Int Cmd\n"); for (i = 0; i < NumPCI; i++) { printf("%2d %2d %2d %04X:%04X %04X:%04X %02X %02X:%02X %02X %02X %04X ", PCI[i].slot.p.Bus, PCI[i].slot.p.Device, PCI[i].slot.p.Function, PCI[i].VendorID, PCI[i].DeviceID, PCI[i].u.type0.SubSystemVendorID, PCI[i].u.type0.SubSystemID, PCI[i].RevID, PCI[i].BaseClass, PCI[i].SubClass, PCI[i].u.type0.InterruptLine, PCI[i].u.type0.InterruptPin, PCI[i].Command); for (index = 0; index < NumDevices; index++) { if (DeviceIndex[index] == i) break; } if (index < NumDevices) printf("<- %d\n", index); else printf("\n"); } printf("\n"); printf("DeviceID Stat Ifc Cch Lat Hdr BIST\n"); for (i = 0; i < NumPCI; i++) { printf("%04X:%04X %04X %02X %02X %02X %02X %02X ", PCI[i].VendorID, PCI[i].DeviceID, PCI[i].Status, PCI[i].Interface, PCI[i].CacheLineSize, PCI[i].LatencyTimer, PCI[i].HeaderType, PCI[i].BIST); for (index = 0; index < NumDevices; index++) { if (DeviceIndex[index] == i) break; } if (index < NumDevices) printf("<- %d\n", index); else printf("\n"); } printf("\n"); printf("DeviceID Base10h Base14h Base18h Base1Ch Base20h Base24h ROMBase\n"); for (i = 0; i < NumPCI; i++) { printf("%04X:%04X %08lX %08lX %08lX %08lX %08lX %08lX %08lX ", PCI[i].VendorID, PCI[i].DeviceID, PCI[i].u.type0.BaseAddress10, PCI[i].u.type0.BaseAddress14, PCI[i].u.type0.BaseAddress18, PCI[i].u.type0.BaseAddress1C, PCI[i].u.type0.BaseAddress20, PCI[i].u.type0.BaseAddress24, PCI[i].u.type0.ROMBaseAddress); for (index = 0; index < NumDevices; index++) { if (DeviceIndex[index] == i) break; } if (index < NumDevices) printf("<- %d\n", index); else printf("\n"); } printf("\n"); printf("DeviceID BAR10Len BAR14Len BAR18Len BAR1CLen BAR20Len BAR24Len ROMLen\n"); for (i = 0; i < NumPCI; i++) { printf("%04X:%04X %08lX %08lX %08lX %08lX %08lX %08lX %08lX ", PCI[i].VendorID, PCI[i].DeviceID, PCI[i].u.type0.BaseAddress10Len, PCI[i].u.type0.BaseAddress14Len, PCI[i].u.type0.BaseAddress18Len, PCI[i].u.type0.BaseAddress1CLen, PCI[i].u.type0.BaseAddress20Len, PCI[i].u.type0.BaseAddress24Len, PCI[i].u.type0.ROMBaseAddressLen); for (index = 0; index < NumDevices; index++) { if (DeviceIndex[index] == i) break; } if (index < NumDevices) printf("<- %d\n", index); else printf("\n"); } printf("\n"); printf("Displaying enumeration of %d bridge devices\n",NumBridges); printf("\n"); printf("DeviceID P# S# B# IOB IOL MemBase MemLimit PreBase PreLimit Ctrl\n"); for (i = 0; i < NumBridges; i++) { info = (PCIDeviceInfo*)&PCI[BridgeIndex[i]]; printf("%04X:%04X %02X %02X %02X %04X %04X %08X %08X %08X %08X %04X\n", info->VendorID, info->DeviceID, info->u.type1.PrimaryBusNumber, info->u.type1.SecondayBusNumber, info->u.type1.SubordinateBusNumber, ((u16)info->u.type1.IOBase << 8) & 0xF000, info->u.type1.IOLimit ? ((u16)info->u.type1.IOLimit << 8) | 0xFFF : 0, ((u32)info->u.type1.MemoryBase << 16) & 0xFFF00000, info->u.type1.MemoryLimit ? ((u32)info->u.type1.MemoryLimit << 16) | 0xFFFFF : 0, ((u32)info->u.type1.PrefetchableMemoryBase << 16) & 0xFFF00000, info->u.type1.PrefetchableMemoryLimit ? ((u32)info->u.type1.PrefetchableMemoryLimit << 16) | 0xFFFFF : 0, info->u.type1.BridgeControl); } printf("\n"); } /**************************************************************************** RETURNS: Number of display devices found. REMARKS: This function enumerates the number of available display devices on the PCI bus, and returns the number found. ****************************************************************************/ static int PCI_enumerateDevices(void) { int i,j; PCIDeviceInfo *info; /* If this is the first time we have been called, enumerate all */ /* devices on the PCI bus. */ if (NumPCI == -1) { if ((NumPCI = PCI_getNumDevices()) == 0) return -1; PCI = malloc(NumPCI * sizeof(PCI[0])); BridgeIndex = malloc(NumPCI * sizeof(BridgeIndex[0])); DeviceIndex = malloc(NumPCI * sizeof(DeviceIndex[0])); if (!PCI || !BridgeIndex || !DeviceIndex) return -1; for (i = 0; i < NumPCI; i++) PCI[i].dwSize = sizeof(PCI[i]); if (PCI_enumerate(PCI) == 0) return -1; /* Build a list of all PCI bridge devices */ for (i = 0,NumBridges = 0,BridgeIndex[0] = -1; i < NumPCI; i++) { if (PCI[i].BaseClass == PCI_BRIDGE_CLASS) BridgeIndex[NumBridges++] = i; } /* Now build a list of all display class devices */ for (i = 0,NumDevices = 1,DeviceIndex[0] = -1; i < NumPCI; i++) { if (PCI_IS_DISPLAY_CLASS(&PCI[i])) { if ((PCI[i].Command & 0x3) == 0x3) DeviceIndex[0] = i; else DeviceIndex[NumDevices++] = i; if (PCI[i].slot.p.Bus != 0) { /* This device is on a different bus than the primary */ /* PCI bus, so it is probably an AGP device. Find the */ /* AGP bus device that controls that bus so we can */ /* control it. */ for (j = 0; j < NumBridges; j++) { info = (PCIDeviceInfo*)&PCI[BridgeIndex[j]]; if (info->u.type1.SecondayBusNumber == PCI[i].slot.p.Bus) { AGPBridge = info; break; } } } } } /* Enumerate all PCI and bridge devices to standard output */ EnumeratePCI(); } return NumDevices; } int main(void) { /* Enumerate all PCI devices */ PM_init(); if (PCI_enumerateDevices() < 1) { printf("No PCI display devices found!\n"); return -1; } return 0; }