]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - tools/tools/drm/gen-drm_pciids
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / tools / tools / drm / gen-drm_pciids
1 #!/usr/bin/perl
2 # $FreeBSD$
3
4 use strict;
5 use warnings;
6 use utf8;
7
8 use File::Basename;
9
10 my $progname = basename($0);
11
12 sub parse_linux_header ($)
13 {
14     my ($header) = @_;
15
16     open(my $fh, '<', $header) or die "Can't open Linux header: $!\n";
17
18     my $in_list = 0;
19
20     my %pciids = ();
21
22     my $current_vendor_define;
23
24     while (my $line = <$fh>) {
25         if ($line =~ /^#define +([^ ]+) +/) {
26             $current_vendor_define = $1;
27             $pciids{$current_vendor_define} = {};
28         } elsif ($line =~ /^\t\{0x([0-9a-fA-F]{4}), *0x([0-9a-fA-F]{4}),[^,]+,[^,]+,[^,]+,[^,]+, *([^}]+)\}/) {
29             my $vendor_id = uc($1);
30             my $device_id = uc($2);
31             my $flags     = $3;
32
33             $pciids{$current_vendor_define}{$device_id} = {
34                 'vendor_id' => $vendor_id,
35                 'flags'     => $flags
36             };
37         }
38     }
39
40     close($fh);
41
42     return %pciids;
43 }
44
45 sub parse_freebsd_header ($) {
46     my ($header) = @_;
47
48     open(my $fh, '<', $header) or die "Can't open FreeBSD header: $!\n";
49
50     my $in_list = 0;
51
52     my %pciids = ();
53
54     my $current_vendor_define;
55
56     while (my $line = <$fh>) {
57         if ($line =~ /^#define +([^ ]+) +/) {
58             $current_vendor_define = $1;
59             $pciids{$current_vendor_define} = {};
60         } elsif ($line =~ /^\t\{0x([0-9a-fA-F]{4}), *0x([0-9a-fA-F]{4}), *([^,]+), *"([^"]+)"\}/) {
61             my $vendor_id = uc($1);
62             my $device_id = uc($2);
63             my $flags     = $3;
64             my $name      = $4;
65
66             $pciids{$current_vendor_define}{$device_id} = {
67                 'vendor_id' => $vendor_id,
68                 'flags'     => $flags,
69                 'name'      => $name
70             };
71         }
72     }
73
74     close($fh);
75
76     return %pciids;
77 }
78
79 sub parse_pciids_db ($) {
80     my ($header) = @_;
81
82     open(my $fh, '<', $header) or die "Can't open PCI IDs database: $!\n";
83
84     my %pciids = ();
85
86     my $current_vendor_id;
87
88     while (my $line = <$fh>) {
89         if (!$line || $line =~ /^#/) {
90             next;
91         }
92         if ($line =~ /^([0-9a-fA-F]{4})  (.+)/) {
93             # Vendor ID & name.
94             my $vendor_id   = uc($1);
95             my $vendor_name = $2;
96             $pciids{$vendor_id} = {
97                 'name'    => $vendor_name,
98                 'devices' => {}
99             };
100
101             $current_vendor_id = $vendor_id;
102         } elsif ($line =~ /^\t([0-9a-fA-F]{4})  (.+)/) {
103             # Device ID & name.
104             my $device_id   = uc($1);
105             my $device_name = $2;
106             $pciids{$current_vendor_id}{'devices'}{$device_id} = $device_name;
107         }
108     }
109
110     close($fh);
111
112     return %pciids;
113 }
114
115 if (scalar(@ARGV) != 3) {
116     print STDERR "Syntax: $progname <linux_header> <freebsd_header> <pciids_db> [<vendor_define>]\n";
117     exit 1;
118 }
119
120 my $linux_header   = $ARGV[0];
121 my $freebsd_header = $ARGV[1];
122 my $pciids_db      = $ARGV[2];
123 my $only_vendor    = $ARGV[3];
124
125 my %linux_pciids   = parse_linux_header($linux_header);
126 my %freebsd_pciids = parse_freebsd_header($freebsd_header);
127 my %pciids_db      = parse_pciids_db($pciids_db);
128
129 print STDERR "Update FreeBSD's PCI IDs:\n";
130 foreach my $vendor_define (sort keys(%linux_pciids)) {
131     if ($only_vendor && $vendor_define ne $only_vendor) {
132         print STDERR "(skip unwanted define: $vendor_define)\n";
133         next;
134     } elsif (!$only_vendor && !exists($freebsd_pciids{$vendor_define})) {
135         print STDERR "(skip unsupport define: $vendor_define)\n";
136         next;
137     }
138
139     foreach my $device_id (sort keys(%{$linux_pciids{$vendor_define}})) {
140         my $vendor_id = $linux_pciids{$vendor_define}{$device_id}{'vendor_id'};
141
142         if (exists($freebsd_pciids{$vendor_define}{$device_id})) {
143             print STDERR "  $vendor_define: $vendor_id:$device_id already in header\n";
144             next;
145         }
146
147         my $flags     = $linux_pciids{$vendor_define}{$device_id}{'flags'};
148         my $name      = $pciids_db{$vendor_id}{'devices'}{$device_id} || "Unknown device name";
149         print STDERR "  $vendor_define: $vendor_id:$device_id is missing ($name)\n";
150         $freebsd_pciids{$vendor_define}{$device_id} = {
151             'vendor_id' => $vendor_id,
152             'flags'     => $flags,
153             'name'      => $name
154         };
155     }
156 }
157
158 print STDERR "\nWrite FreeBSD header to stdout...\n";
159 print <<"EOF";
160 /*
161  * \$FreeBSD\$
162  */
163
164 /*
165  * Generated by $progname from:
166  *   o  previous FreeBSD's drm_pciids.h
167  *   o  Linux' drm_pciids.h
168  *   o  the PCI ID repository (http://pciids.sourceforge.net/)
169  *
170  * See tools/tools/drm/$progname.
171  */
172 EOF
173 foreach my $vendor_define (sort keys(%freebsd_pciids)) {
174     print "\n#define $vendor_define \\\n";
175     foreach my $device_id (sort keys(%{$freebsd_pciids{$vendor_define}})) {
176         my $vendor_id = $freebsd_pciids{$vendor_define}{$device_id}{'vendor_id'};
177         my $flags     = $freebsd_pciids{$vendor_define}{$device_id}{'flags'};
178         my $name      = $freebsd_pciids{$vendor_define}{$device_id}{'name'};
179
180         print "\t{0x$vendor_id, 0x$device_id, $flags, \"$name\"}, \\\n";
181     }
182     print "\t{0, 0, 0, NULL}\n";
183 }