blob: be275e1a0411765f3d95b2c310c42c17fdb5b06c [file] [log] [blame]
/****************************************************************************
*
* 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;
}