| /**************************************************************************** |
| * |
| * 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 <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <stdarg.h> |
| |
| /*------------------------- 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; |
| } |