summaryrefslogtreecommitdiff
path: root/hw/xfree86/scanpci/pciid2c.pl
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xfree86/scanpci/pciid2c.pl')
-rw-r--r--hw/xfree86/scanpci/pciid2c.pl362
1 files changed, 362 insertions, 0 deletions
diff --git a/hw/xfree86/scanpci/pciid2c.pl b/hw/xfree86/scanpci/pciid2c.pl
new file mode 100644
index 000000000..a43bc5be6
--- /dev/null
+++ b/hw/xfree86/scanpci/pciid2c.pl
@@ -0,0 +1,362 @@
+#!/usr/bin/perl
+
+# Automatically generate the data structures for PCI vendor/device lists
+# from the pci.ids file.
+#
+# It should be run as:
+#
+# perl pciid2c.pl ../common/xf86PciInfo.h < pci.ids > xf86PciIds.h
+#
+#
+# Copyright © 2002 by The XFree86 Project, Inc.
+#
+# Author: David Dawes
+#
+# $XFree86: xc/programs/Xserver/hw/xfree86/scanpci/pciid2c.pl,v 1.2 2002/12/23 16:45:19 tsi Exp $
+#
+
+if (@ARGV[0]) {
+ $infofile = @ARGV[0];
+}
+
+#
+# The basic pci.ids format is:
+# - Vendor lines start with four (lower case) hex digits
+# - Device lines start with one tab followed by four hex digits
+# - Subsystem lines start with two tabs followed by two sets of four
+# hex digits.
+# - Class overrides for devices start with two tabs followed by a "C",
+# followed by four hex digits with the class/subclass value.
+# - Class lines start with a "C".
+# - Comment lines start with a '#'.
+# - Blank lines are ignored.
+#
+# We allow for extra lines to be appended to modify existing entries or
+# add new ones. To add/modify Device entries without modifying the
+# Vendor name, a special vendor name of '"' is used (mnemonic: "ditto").
+# Similarly for adding subsystem names without modifying (or adding)
+# a corresponding device entry. To rename an existing entry, simply
+# provide the new name. To remove an existing entry, use the special
+# name '-'.
+#
+
+while (<STDIN>) {
+ # Process data lines
+ if (/^([0-9a-f]{4})\s+(.*)/) {
+ $vendor = $1;
+ if ($2 eq '-') {
+ delete($vendors{$vendor});
+ } elsif ($2 ne '"') {
+ $vendors{$vendor} = $2;
+ # Remove " characters
+ $vendors{$vendor} =~ s/"//g;
+ # Remove multiple "?" sequences to avoid trigraphs
+ $vendors{$vendor} =~ s/\?+/\?/g;
+ }
+ } elsif (/^\t([0-9a-f]{4})\s+(.*)/) {
+ $device = $1;
+ if ($2 eq '-') {
+ delete($devices{$vendor}{$device});
+ } elsif ($2 ne '"') {
+ $devices{$vendor}{$device} = $2;
+ # Remove " characters
+ $devices{$vendor}{$device} =~ s/"//g;
+ # Remove multiple "?" sequences to avoid trigraphs
+ $devices{$vendor}{$device} =~ s/\?+/\?/g;
+ }
+ } elsif (/^\t\t([0-9a-f]{4})\s+([0-9a-f]{4})\s+(.*)/) {
+ $v = $1;
+ $s = $2;
+ if ($3 eq '-') {
+ delete($subsystems{$v}{$s});
+ delete($devsubsystems{$vendor}{$device}{"$v-$s"});
+ } elsif ($3 ne '"') {
+ if ($subsystems{$v}{$s}) {
+ #print STDERR "Duplicate subsytem: $v, $s, \"$subsystems{$v}{$s}\", \"$3\"\n";
+ }
+ $subsystems{$v}{$s} = $3;
+ # Remove " characters
+ $subsystems{$v}{$s} =~ s/"//g;
+ # Remove multiple "?" sequences to avoid trigraphs
+ $subsystems{$v}{$s} =~ s/\?+/\?/g;
+ $devsubsystems{$vendor}{$device}{"$v-$s"} = $subsystems{$v}{$s};
+ }
+ } elsif (/^\t\tC\s+([0-9a-f]{4})/) {
+ $classes{$vendor}{$device} = $1;
+ }
+ # Ignore all other lines.
+}
+
+# Find which vendors are "video" vendors.
+if ($infofile) {
+ open(INFO, "<$infofile") || die "Can't open $infofile";
+ while (<INFO>) {
+ if (/^#define\s+PCI_VENDOR_.*0x([0-9a-fA-F]{4})/) {
+ $vendor = $1;
+ $vendor =~ tr/A-F/a-f/;
+ $video{$vendor} = 1;
+ }
+ }
+}
+
+#
+# This layout is quite different from that used in the old xf86PciInfo.h
+# file. One main difference is that the list is initialised at runtime.
+# It's currently a flat list. This could be improved.
+#
+
+# Print out header information.
+
+$proj = "XFree86";
+print "/* \$$proj\$ */
+
+/*
+ * THIS FILE IS AUTOMATICALLY GENERATED -- DO NOT EDIT
+ *
+ * It is generated by pciid2c.pl using data from the following files:
+ *
+ * ../etc/pci.ids
+ * ../etc/extrapci.ids
+ * ../common/xf86PciInfo.h
+ */
+
+/*
+ * Copyright © 2002 by the XFree86 Project, Inc.
+ *
+ * The pci.ids file and the data it contains are from the Linux PCI ID's
+ * Project (http://pciids.sf.net/). It is maintained by Martin Mares
+ * <mj\@ucw.cz> and other volunteers. The pci.ids file contains no
+ * copyright notice.
+ */
+
+#include \"xf86PciInfo.h\"
+#ifndef NULL
+#define NULL (void *)0
+#endif
+
+";
+
+# The following #ifdefs are used:
+# - INIT_SUBSYS_INFO -- initialise subsystem data
+# - INIT_VENDOR_SUBSYS_INFO -- initialise a vendor<->subsystem table.
+# - VENDOR_INCLUDE_NONVIDEO -- include data for non-video vendors.
+
+# Define static variables with all of the strings.
+
+foreach $vendor (sort keys %vendors) {
+ if ($infofile && !$video{$vendor}) {
+ print "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
+ }
+ print "static const char pci_vendor_${vendor}[] = \"$vendors{$vendor}\";\n";
+ foreach $device (sort keys %{$devices{$vendor}}) {
+ print "static const char pci_device_${vendor}_${device}[] = " .
+ "\"$devices{$vendor}{$device}\";\n";
+ foreach $subsys (sort keys %{$devsubsystems{$vendor}{$device}}) {
+ $s = $subsys;
+ ($v) = split /-/, $s;
+ if ($infofile && !$video{$vendor} && $video{$v}) {
+ print "#endif\n";
+ }
+ $s =~ s/-/_/;
+ print "#ifdef INIT_SUBSYS_INFO\n";
+ print "static const char pci_subsys_${vendor}_${device}_${s}[] = " .
+ "\"$devsubsystems{$vendor}{$device}{$subsys}\";\n";
+ print "#endif\n";
+ if ($infofile && !$video{$vendor} && $video{$v}) {
+ print "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
+ }
+ }
+ }
+ if ($infofile && !$video{$vendor}) {
+ print "#endif\n";
+ }
+}
+
+
+# Pre-initialise the table structures (from the inner to the outer).
+
+# First, the subsys structures.
+
+print "#ifdef INIT_SUBSYS_INFO\n";
+foreach $vendor (sort keys %vendors) {
+ if ($infofile && !$video{$vendor}) {
+ $pre = "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
+ } else {
+ undef($pre);
+ undef($post);
+ }
+ foreach $device (sort keys %{$devices{$vendor}}) {
+ foreach $subsys (sort keys %{$devsubsystems{$vendor}{$device}}) {
+ $s = $subsys;
+ $s =~ tr/-/_/;
+ ($vid, $sid) = split /_/, $s;
+ if ($pre) {
+ print $pre;
+ undef($pre);
+ $post = "#endif\n";
+ }
+ if ($infofile && !$video{$vendor} && $video{$vid}) {
+ print "#endif\n";
+ }
+ print "static const pciSubsystemInfo " .
+ "pci_ss_info_${vendor}_${device}_$s =\n";
+ print "\t{0x$vid, 0x$sid, pci_subsys_${vendor}_${device}_$s, 0};\n";
+ print "#undef pci_ss_info_$s\n";
+ print "#define pci_ss_info_$s pci_ss_info_${vendor}_${device}_$s\n";
+ if ($infofile && !$video{$vendor} && $video{$vid}) {
+ print "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
+ }
+ }
+ }
+ if ($post) {
+ print $post;
+ undef($post);
+ }
+}
+
+# Next, the list of per vendor+device subsystem arrays
+
+foreach $vendor (sort keys %vendors) {
+ if ($infofile && !$video{$vendor}) {
+ $pre = "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
+ } else {
+ undef($pre);
+ undef($post);
+ }
+ foreach $device (sort keys %{$devices{$vendor}}) {
+ if (scalar(keys %{$devsubsystems{$vendor}{$device}}) > 0) {
+ if ($pre) {
+ print $pre;
+ undef($pre);
+ $post = "#endif\n";
+ }
+ print "static const pciSubsystemInfo *pci_ss_list_${vendor}_${device}[] = {\n";
+ foreach $sub (sort keys %{$devsubsystems{$vendor}{$device}}) {
+ $sub =~ s/-/_/;
+ print "\t&pci_ss_info_${vendor}_${device}_${sub},\n";
+ }
+ print "\tNULL\n};\n";
+ } else {
+ print "#define pci_ss_list_${vendor}_${device} NULL\n";
+ }
+ }
+ if ($post) {
+ print $post;
+ undef($post);
+ }
+}
+
+# Next, the list of per vendor subsystem arrays
+
+print "#ifdef INIT_VENDOR_SUBSYS_INFO\n";
+foreach $vendor (sort keys %vendors) {
+ if (scalar(keys %{$subsystems{$vendor}}) > 0) {
+ if ($infofile && !$video{$vendor}) {
+ print "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
+ }
+ print "static const pciSubsystemInfo *pci_ss_list_${vendor}[] = {\n";
+ foreach $sub (sort keys %{$subsystems{$vendor}}) {
+ print "\t&pci_ss_info_${vendor}_${sub},\n";
+ }
+ print "\tNULL\n};\n";
+ if ($infofile && !$video{$vendor}) {
+ print "#endif\n";
+ }
+ } else {
+ print "#define pci_ss_list_${vendor} NULL\n";
+ }
+}
+print "#endif /* INIT_VENDOR_SUBSYS_INFO */\n";
+print "#endif /* INIT_SUBSYS_INFO */\n";
+
+# Next the device structures
+
+foreach $vendor (sort keys %vendors) {
+ if ($infofile && !$video{$vendor}) {
+ $pre = "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
+ } else {
+ undef($pre);
+ undef($post);
+ }
+ foreach $device (sort keys %{$devices{$vendor}}) {
+ if ($pre) {
+ print $pre;
+ undef($pre);
+ $post = "#endif\n";
+ }
+ if ($classes{$vendor}{$device}) {
+ $class = "0x$classes{$vendor}{$device}";
+ } else {
+ $class = "0";
+ }
+ print "static const pciDeviceInfo " .
+ "pci_dev_info_${vendor}_${device} = {\n";
+ print "\t0x$device, pci_device_${vendor}_${device},\n";
+ print "#ifdef INIT_SUBSYS_INFO\n";
+ print "\tpci_ss_list_${vendor}_${device},\n";
+ print "#else\n";
+ print "\tNULL,\n";
+ print "#endif\n";
+ print "\t$class\n};\n";
+ }
+ if ($post) {
+ print $post;
+ undef($post);
+ }
+}
+
+# Next, the list of per vendor device arrays
+
+foreach $vendor (sort keys %vendors) {
+ if (scalar(keys %{$devices{$vendor}}) > 0) {
+ if ($infofile && !$video{$vendor}) {
+ print "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
+ }
+ print "static const pciDeviceInfo *pci_dev_list_${vendor}[] = {\n";
+ foreach $device (sort keys %{$devices{$vendor}}) {
+ print "\t&pci_dev_info_${vendor}_${device},\n";
+ }
+ print "\tNULL\n};\n";
+ if ($infofile && !$video{$vendor}) {
+ print "#endif\n";
+ }
+ } else {
+ print "#define pci_dev_list_${vendor} NULL\n";
+ }
+}
+
+# Next, the main vendor list
+
+print "
+static const pciVendorInfo pciVendorInfoList[] = {
+";
+
+foreach $vendor (sort keys %vendors) {
+ if ($infofile && !$video{$vendor}) {
+ print "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
+ }
+ print "\t{0x$vendor, pci_vendor_$vendor, pci_dev_list_$vendor},\n";
+ if ($infofile && !$video{$vendor}) {
+ print "#endif\n";
+ }
+}
+print "\t{0x0000, NULL, NULL}\n};\n";
+
+# Finally, the main vendor/subsystem list
+
+print "
+#if defined(INIT_VENDOR_SUBSYS_INFO) && defined(INIT_SUBSYS_INFO)
+static const pciVendorSubsysInfo pciVendorSubsysInfoList[] = {
+";
+
+foreach $vendor (sort keys %vendors) {
+ if ($infofile && !$video{$vendor}) {
+ print "#ifdef VENDOR_INCLUDE_NONVIDEO\n";
+ }
+ print "\t{0x$vendor, pci_vendor_$vendor, pci_ss_list_$vendor},\n";
+ if ($infofile && !$video{$vendor}) {
+ print "#endif\n";
+ }
+}
+print "\t{0x0000, NULL, NULL}\n};\n";
+print "#endif\n";