/* Copyright 2000 by Egbert Eich * Copyright 1995 by Robin Cutshaw * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the names of the above listed copyright holder(s) * not be used in advertising or publicity pertaining to distribution of * the software without specific, written prior permission. The above listed * copyright holder(s) make(s) no representations about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. * * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ /* $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.81 2001/01/06 20:19:12 tsi Exp $ */ #include "X.h" #include "os.h" #include "xf86.h" #include "xf86Priv.h" #include "xf86_OSproc.h" #include "xf86Pci.h" #include "xf86ScanPci.h" #include "xf86PciInfo.h" #include "dummylib.h" #include #include #ifdef __linux__ /* to get getopt on Linux */ #ifndef __USE_POSIX2 #define __USE_POSIX2 #endif #endif #include #if defined(ISC) || defined(Lynx) extern char *optarg; extern int optind, opterr; #endif pciVideoPtr *xf86PciVideoInfo = NULL; void usage(void); void identify_card(pciConfigPtr pcr, int verbose); void print_default_class(pciConfigPtr pcr); void print_bridge_pci_class(pciConfigPtr pcr); void print_bridge_class(pciConfigPtr pcr); void print_mach64(pciConfigPtr pcr); void print_i128(pciConfigPtr pcr); void print_pcibridge(pciConfigPtr pcr); typedef struct { unsigned int Vendor; struct { int DeviceID; void(*func)(pciConfigPtr); } Device[MAX_DEV_PER_VENDOR]; } pciVendorDevFuncInfo; pciVendorDevFuncInfo vendorDeviceFuncInfo[] = { { 0x1002, { { 0x4354, print_mach64 }, { 0x4358, print_mach64 }, { 0x4554, print_mach64 }, { 0x4742, print_mach64 }, { 0x4744, print_mach64 }, { 0x4749, print_mach64 }, { 0x474C, print_mach64 }, { 0x474D, print_mach64 }, { 0x474E, print_mach64 }, { 0x474F, print_mach64 }, { 0x4750, print_mach64 }, { 0x4751, print_mach64 }, { 0x4752, print_mach64 }, { 0x4753, print_mach64 }, { 0x4754, print_mach64 }, { 0x4755, print_mach64 }, { 0x4756, print_mach64 }, { 0x4757, print_mach64 }, { 0x4758, print_mach64 }, { 0x475A, print_mach64 }, { 0x4C42, print_mach64 }, { 0x4C44, print_mach64 }, { 0x4C47, print_mach64 }, { 0x4C49, print_mach64 }, { 0x4C4D, print_mach64 }, { 0x4C4E, print_mach64 }, { 0x4C50, print_mach64 }, { 0x4C52, print_mach64 }, { 0x4C53, print_mach64 }, { 0x5654, print_mach64 }, { 0x5655, print_mach64 }, { 0x5656, print_mach64 }, { 0x0000, NULL } } }, { 0x105D, { { 0x2309, print_i128 }, { 0x2339, print_i128 }, { 0x493D, print_i128 }, { 0x5348, print_i128 }, { 0x0000, NULL } } }, { 0x1011, { { 0x0001, print_pcibridge}, { 0x0000, NULL } } }, { 0x0000, { { 0x0000, NULL } } } }; void usage(void) { printf("Usage: scanpci [-v12OfV]\n"); printf(" -v print config space\n"); printf(" -1 config type 1\n"); printf(" -2 config type 2\n"); printf(" -O use OS config support\n"); printf(" -f force config type\n"); printf(" -V set message verbosity level\n"); } int main(int argc, char *argv[]) { pciConfigPtr *pcrpp = NULL; int Verbose = 0; int i = 0; int force = 0; char c; xf86Info.pciFlags = PCIProbe1; while ((c = getopt(argc, argv, "?v12OfV:")) != -1) switch(c) { case 'v': Verbose = 1; break; case '1': xf86Info.pciFlags = PCIProbe1; break; case '2': xf86Info.pciFlags = PCIProbe2; break; case 'O': xf86Info.pciFlags = PCIOsConfig; break; case 'f': force = 1; break; case 'V': xf86Verbose = atoi(optarg); break; case '?': default: usage(); exit (1); break; } if (force) switch (xf86Info.pciFlags) { case PCIProbe1: xf86Info.pciFlags = PCIForceConfig1; break; case PCIProbe2: xf86Info.pciFlags = PCIForceConfig2; break; default: break; } xf86EnableIO(); pcrpp = xf86scanpci(0); xf86DisableIO(); if (!pcrpp) { printf("No PCI devices found\n"); exit (1); } while (pcrpp[i]) identify_card(pcrpp[i++],Verbose); exit(0); } void identify_card(pciConfigPtr pcr, int verbose) { int i, j; int foundit = 0; int foundvendor = 0; SymTabRec *pvnd; pciVendorDeviceInfo *pvd; pciVendorDevFuncInfo *vdf = vendorDeviceFuncInfo; pciVendorCardInfo *pvc; xf86SetupScanPci(&pvnd,&pvd,&pvc); printf("\npci bus 0x%x cardnum 0x%02x function 0x%04x: vendor 0x%04x device 0x%04x\n", pcr->busnum, pcr->devnum, pcr->funcnum, pcr->pci_vendor, pcr->pci_device); for (i = 0; pvnd[i].name; i++) { if (pvnd[i].token == pcr->pci_vendor) { printf(" %s ", pvnd[i].name); break; } } for (i = 0; pvd[i].VendorID && pvd[i].VendorID != pcr->pci_vendor; i++) ; if (pvd[i].VendorID) { for (j = 0; pvd[i].Device[j].DeviceName; j++) { if (pvd[i].Device[j].DeviceID == pcr->pci_device) { printf("%s", pvd[i].Device[j].DeviceName); foundit = 1; break; } } } if (!foundit) printf(" Device unknown\n"); else { printf("\n"); if (verbose) { for (i = 0; vdf[i].Vendor; i++) { if (vdf[i].Vendor == pcr->pci_vendor) { for (j = 0; vdf[i].Device[j].DeviceID; j++) { if (vdf[i].Device[j].DeviceID == pcr->pci_device) { vdf[i].Device[j].func(pcr); return; } } break; } } } } if (verbose && !(pcr->pci_header_type & 0x7f) && (pcr->pci_subsys_vendor != 0 || pcr->pci_subsys_card != 0)) { foundit = 0; foundvendor = 0; printf(" CardVendor 0x%04x card 0x%04x", pcr->pci_subsys_vendor, pcr->pci_subsys_card); for (i = 0; pvnd[i].name; i++) { if (pvnd[i].token == pcr->pci_subsys_vendor) { printf(" (%s", pvnd[i].name); foundvendor = 1; break; } } for (i = 0; pvc[i].VendorID && pvc[i].VendorID != pcr->pci_subsys_vendor; i++) ; if (pvc[i].VendorID) { for (j = 0; pvc[i].Device[j].CardName; j++) { if (pvc[i].Device[j].SubsystemID == pcr->pci_subsys_card) { printf(" %s)", pvc[i].Device[j].CardName); foundit = 1; break; } } } if (!foundit) { if (!foundvendor) printf(" ("); else printf(", "); printf("Card unknown)"); } printf("\n"); } if (verbose) { if (pcr->pci_status_command) printf(" STATUS 0x%04x COMMAND 0x%04x\n", pcr->pci_status, pcr->pci_command); if (pcr->pci_class_revision) printf(" CLASS 0x%02x 0x%02x 0x%02x REVISION 0x%02x\n", pcr->pci_base_class, pcr->pci_sub_class, pcr->pci_prog_if, pcr->pci_rev_id); switch (pcr->pci_base_class) { case PCI_CLASS_BRIDGE: switch (pcr->pci_sub_class) { case PCI_SUBCLASS_BRIDGE_PCI: print_bridge_pci_class(pcr); break; default: print_bridge_class(pcr); break; } break; default: print_default_class(pcr); break; } } } void print_default_class(pciConfigPtr pcr) { if (pcr->pci_bist_header_latency_cache) printf(" BIST 0x%02x HEADER 0x%02x LATENCY 0x%02x CACHE 0x%02x\n", pcr->pci_bist, pcr->pci_header_type, pcr->pci_latency_timer, pcr->pci_cache_line_size); if (pcr->pci_base0) printf(" BASE0 0x%08x addr 0x%08x %s%s%s\n", (int)pcr->pci_base0,(int)(pcr->pci_base0 & (pcr->pci_base0 & 0x1 ? 0xFFFFFFFC : 0xFFFFFFF0)), pcr->pci_base0 & 0x1 ? "I/O" : "MEM", ((pcr->pci_base0 & 0x9) == 0x8) ? " PREFETCHABLE" :"", ((pcr->pci_base0 & 0x7) == 0x4) ? " 64BIT" : ""); if (pcr->pci_base1) printf(" BASE1 0x%08x addr 0x%08x %s%s%s\n", (int)pcr->pci_base1, (int)(pcr->pci_base1 & (pcr->pci_base1 & 0x1 ? 0xFFFFFFFC : 0xFFFFFFF0)), pcr->pci_base1 & 0x1 ? "I/O" : "MEM", ((pcr->pci_base1 & 0x9) == 0x8) ? " PREFETCHABLE" :"", ((pcr->pci_base1 & 0x7) == 0x4) ? " 64BIT" : ""); if (pcr->pci_base2) printf(" BASE2 0x%08x addr 0x%08x %s%s%s\n", (int)pcr->pci_base2, (int)(pcr->pci_base2 & (pcr->pci_base2 & 0x1 ? 0xFFFFFFFC : 0xFFFFFFF0)), pcr->pci_base2 & 0x1 ? "I/O" : "MEM", ((pcr->pci_base2 & 0x9) == 0x8) ? " PREFETCHABLE" :"", ((pcr->pci_base2 & 0x7) == 0x4) ? " 64BIT" : ""); if (pcr->pci_base3) printf(" BASE3 0x%08x addr 0x%08x %s%s%s\n", (int)pcr->pci_base3, (int)(pcr->pci_base3 & (pcr->pci_base3 & 0x1 ? 0xFFFFFFFC : 0xFFFFFFF0)), pcr->pci_base3 & 0x1 ? "I/O" : "MEM", ((pcr->pci_base3 & 0x9) == 0x8) ? " PREFETCHABLE" :"", ((pcr->pci_base3 & 0x7) == 0x4) ? " 64BIT" : ""); if (pcr->pci_base4) printf(" BASE4 0x%08x addr 0x%08x %s%s%s\n", (int)pcr->pci_base4, (int)(pcr->pci_base4 & (pcr->pci_base4 & 0x1 ? 0xFFFFFFFC : 0xFFFFFFF0)), pcr->pci_base4 & 0x1 ? "I/O" : "MEM", ((pcr->pci_base4 & 0x9) == 0x8) ? " PREFETCHABLE" :"", ((pcr->pci_base4 & 0x7) == 0x4) ? " 64BIT" : ""); if (pcr->pci_base5) printf(" BASE5 0x%08x addr 0x%08x %s%s%s\n", (int)pcr->pci_base5, (int)(pcr->pci_base5 & (pcr->pci_base5 & 0x1 ? 0xFFFFFFFC : 0xFFFFFFF0)), pcr->pci_base5 & 0x1 ? "I/O" : "MEM", ((pcr->pci_base5 & 0x9) == 0x8) ? " PREFETCHABLE" :"", ((pcr->pci_base5 & 0x7) == 0x4) ? " 64BIT" : ""); if (pcr->pci_baserom) printf(" BASEROM 0x%08x addr 0x%08x %sdecode-enabled\n", (int)pcr->pci_baserom, (int)(pcr->pci_baserom & 0xFFFF8000), pcr->pci_baserom & 0x1 ? "" : "not-"); if (pcr->pci_max_min_ipin_iline) printf(" MAX_LAT 0x%02x MIN_GNT 0x%02x INT_PIN 0x%02x INT_LINE 0x%02x\n", pcr->pci_max_lat, pcr->pci_min_gnt, pcr->pci_int_pin, pcr->pci_int_line); if (pcr->pci_user_config) printf(" BYTE_0 0x%02x BYTE_1 0x%02x BYTE_2 0x%02x BYTE_3 0x%02x\n", (int)pcr->pci_user_config_0, (int)pcr->pci_user_config_1, (int)pcr->pci_user_config_2, (int)pcr->pci_user_config_3); } #define PCI_B_FAST_B_B 0x80 #define PCI_B_SB_RESET 0x40 #define PCI_B_M_ABORT 0x20 #define PCI_B_VGA_EN 0x08 #define PCI_B_ISA_EN 0x04 #define PCI_B_P_ERR 0x01 void print_bridge_pci_class(pciConfigPtr pcr) { if (pcr->pci_bist_header_latency_cache) printf(" HEADER 0x%02x LATENCY 0x%02x\n", pcr->pci_header_type, pcr->pci_latency_timer); printf(" PRIBUS 0x%02x SECBUS 0x%02x SUBBUS 0x%02x SECLT 0x%02x\n", pcr->pci_primary_bus_number, pcr->pci_secondary_bus_number, pcr->pci_subordinate_bus_number, pcr->pci_secondary_latency_timer); printf(" IOBASE 0x%02x IOLIM 0x%02x SECSTATUS 0x%04x\n", pcr->pci_io_base << 8, (pcr->pci_io_limit << 8) | 0xfff, pcr->pci_secondary_status); printf(" NOPREFETCH_MEMBASE 0x%08x MEMLIM 0x%08x\n", pcr->pci_mem_base << 16, (pcr->pci_mem_limit << 16) | 0xfffff); printf(" PREFETCH_MEMBASE 0x%08x MEMLIM 0x%08x\n", pcr->pci_prefetch_mem_base << 16, (pcr->pci_prefetch_mem_limit << 16) | 0xfffff); printf(" %sFAST_B2B %sSEC_BUS_RST %sM_ABRT %sVGA_EN %sISA_EN" " %sPERR_EN\n", (pcr->pci_bridge_control & PCI_B_FAST_B_B) ? "" : "NO_", (pcr->pci_bridge_control & PCI_B_SB_RESET) ? "" : "NO_", (pcr->pci_bridge_control & PCI_B_M_ABORT) ? "" : "NO_", (pcr->pci_bridge_control & PCI_B_VGA_EN) ? "" : "NO_", (pcr->pci_bridge_control & PCI_B_ISA_EN) ? "" : "NO_", (pcr->pci_bridge_control & PCI_B_P_ERR) ? "" : "NO_"); } void print_bridge_class(pciConfigPtr pcr) { if (pcr->pci_bist_header_latency_cache) printf(" HEADER 0x%02x LATENCY 0x%02x\n", pcr->pci_header_type, pcr->pci_latency_timer); } void print_mach64(pciConfigPtr pcr) { CARD32 sparse_io = 0; printf(" CardVendor 0x%04x card 0x%04x\n", pcr->pci_subsys_vendor, pcr->pci_subsys_card); if (pcr->pci_status_command) printf(" STATUS 0x%04x COMMAND 0x%04x\n", pcr->pci_status, pcr->pci_command); if (pcr->pci_class_revision) printf(" CLASS 0x%02x 0x%02x 0x%02x REVISION 0x%02x\n", pcr->pci_base_class, pcr->pci_sub_class, pcr->pci_prog_if, pcr->pci_rev_id); if (pcr->pci_bist_header_latency_cache) printf(" BIST 0x%02x HEADER 0x%02x LATENCY 0x%02x CACHE 0x%02x\n", pcr->pci_bist, pcr->pci_header_type, pcr->pci_latency_timer, pcr->pci_cache_line_size); if (pcr->pci_base0) printf(" APBASE 0x%08x addr 0x%08x\n", (int)pcr->pci_base0, (int)(pcr->pci_base0 & (pcr->pci_base0 & 0x1 ? 0xFFFFFFFC : 0xFFFFFFF0))); if (pcr->pci_base1) printf(" BLOCKIO 0x%08x addr 0x%08x\n", (int)pcr->pci_base1, (int)(pcr->pci_base1 & (pcr->pci_base1 & 0x1 ? 0xFFFFFFFC : 0xFFFFFFF0))); if (pcr->pci_base2) printf(" REGBASE 0x%08x addr 0x%08x\n", (int)pcr->pci_base2, (int)(pcr->pci_base2 & (pcr->pci_base2 & 0x1 ? 0xFFFFFFFC : 0xFFFFFFF0))); if (pcr->pci_baserom) printf(" BASEROM 0x%08x addr 0x%08x %sdecode-enabled\n", (int)pcr->pci_baserom, (int)(pcr->pci_baserom & 0xFFFF8000), pcr->pci_baserom & 0x1 ? "" : "not-"); if (pcr->pci_max_min_ipin_iline) printf(" MAX_LAT 0x%02x MIN_GNT 0x%02x INT_PIN 0x%02x INT_LINE 0x%02x\n", pcr->pci_max_lat, pcr->pci_min_gnt, pcr->pci_int_pin, pcr->pci_int_line); switch (pcr->pci_user_config_0 & 0x03) { case 0: sparse_io = 0x2ec; break; case 1: sparse_io = 0x1cc; break; case 2: sparse_io = 0x1c8; break; } printf(" SPARSEIO 0x%03x %s IO enabled %sable 0x46E8\n", (int)sparse_io, pcr->pci_user_config_0 & 0x04 ? "Block" : "Sparse", pcr->pci_user_config_0 & 0x08 ? "Dis" : "En"); } void print_i128(pciConfigPtr pcr) { printf(" CardVendor 0x%04x card 0x%04x\n", pcr->pci_subsys_vendor, pcr->pci_subsys_card); if (pcr->pci_status_command) printf(" STATUS 0x%04x COMMAND 0x%04x\n", pcr->pci_status, pcr->pci_command); if (pcr->pci_class_revision) printf(" CLASS 0x%02x 0x%02x 0x%02x REVISION 0x%02x\n", pcr->pci_base_class, pcr->pci_sub_class, pcr->pci_prog_if, pcr->pci_rev_id); if (pcr->pci_bist_header_latency_cache) printf(" BIST 0x%02x HEADER 0x%02x LATENCY 0x%02x CACHE 0x%02x\n", pcr->pci_bist, pcr->pci_header_type, pcr->pci_latency_timer, pcr->pci_cache_line_size); printf(" MW0_AD 0x%08x addr 0x%08x %spre-fetchable\n", (int)pcr->pci_base0, (int)(pcr->pci_base0 & 0xFFC00000), pcr->pci_base0 & 0x8 ? "" : "not-"); printf(" MW1_AD 0x%08x addr 0x%08x %spre-fetchable\n", (int)pcr->pci_base1, (int)(pcr->pci_base1 & 0xFFC00000), pcr->pci_base1 & 0x8 ? "" : "not-"); printf(" XYW_AD(A) 0x%08x addr 0x%08x\n", (int)pcr->pci_base2, (int)(pcr->pci_base2 & 0xFFC00000)); printf(" XYW_AD(B) 0x%08x addr 0x%08x\n", (int)pcr->pci_base3, (int)(pcr->pci_base3 & 0xFFC00000)); printf(" RBASE_G 0x%08x addr 0x%08x\n", (int)pcr->pci_base4, (int)(pcr->pci_base4 & 0xFFFF0000)); printf(" IO 0x%08x addr 0x%08x\n", (int)pcr->pci_base5, (int)(pcr->pci_base5 & 0xFFFFFF00)); printf(" RBASE_E 0x%08x addr 0x%08x %sdecode-enabled\n", (int)pcr->pci_baserom, (int)(pcr->pci_baserom & 0xFFFF8000), pcr->pci_baserom & 0x1 ? "" : "not-"); if (pcr->pci_max_min_ipin_iline) printf(" MAX_LAT 0x%02x MIN_GNT 0x%02x INT_PIN 0x%02x INT_LINE 0x%02x\n", pcr->pci_max_lat, pcr->pci_min_gnt, pcr->pci_int_pin, pcr->pci_int_line); } void print_pcibridge(pciConfigPtr pcr) { if (pcr->pci_status_command) printf(" STATUS 0x%04x COMMAND 0x%04x\n", pcr->pci_status, pcr->pci_command); if (pcr->pci_class_revision) printf(" CLASS 0x%02x 0x%02x 0x%02x REVISION 0x%02x\n", pcr->pci_base_class, pcr->pci_sub_class, pcr->pci_prog_if, pcr->pci_rev_id); if (pcr->pci_bist_header_latency_cache) printf(" BIST 0x%02x HEADER 0x%02x LATENCY 0x%02x CACHE 0x%02x\n", pcr->pci_bist, pcr->pci_header_type, pcr->pci_latency_timer, pcr->pci_cache_line_size); printf(" PRIBUS 0x%02x SECBUS 0x%02x SUBBUS 0x%02x SECLT 0x%02x\n", pcr->pci_primary_bus_number, pcr->pci_secondary_bus_number, pcr->pci_subordinate_bus_number, pcr->pci_secondary_latency_timer); printf(" IOBASE 0x%02x IOLIM 0x%02x SECSTATUS 0x%04x\n", pcr->pci_io_base << 8, (pcr->pci_io_limit << 8) | 0xfff, pcr->pci_secondary_status); printf(" NOPREFETCH_MEMBASE 0x%08x MEMLIM 0x%08x\n", pcr->pci_mem_base << 16, (pcr->pci_mem_limit << 16) | 0xfffff); printf(" PREFETCH_MEMBASE 0x%08x MEMLIM 0x%08x\n", pcr->pci_prefetch_mem_base << 16, (pcr->pci_prefetch_mem_limit << 16) | 0xfffff); printf(" RBASE_E 0x%08x addr 0x%08x %sdecode-enabled\n", (int)pcr->pci_baserom, (int)(pcr->pci_baserom & 0xFFFF8000), pcr->pci_baserom & 0x1 ? "" : "not-"); if (pcr->pci_max_min_ipin_iline) printf(" MAX_LAT 0x%02x MIN_GNT 0x%02x INT_PIN 0x%02x INT_LINE 0x%02x\n", pcr->pci_max_lat, pcr->pci_min_gnt, pcr->pci_int_pin, pcr->pci_int_line); } #include "xf86getpagesize.c"