xref: /freebsd/tools/tools/drm/gen-drm_pciids (revision c4e2333c)
1592ffb21SWarner Losh#!/usr/bin/perl
2592ffb21SWarner Losh
3592ffb21SWarner Loshuse strict;
4592ffb21SWarner Loshuse warnings;
5592ffb21SWarner Loshuse utf8;
6592ffb21SWarner Losh
7592ffb21SWarner Loshuse File::Basename;
8592ffb21SWarner Losh
9592ffb21SWarner Loshmy $progname = basename($0);
10592ffb21SWarner Losh
11592ffb21SWarner Loshsub parse_linux_header ($)
12592ffb21SWarner Losh{
13592ffb21SWarner Losh    my ($header) = @_;
14592ffb21SWarner Losh
15592ffb21SWarner Losh    open(my $fh, '<', $header) or die "Can't open Linux header: $!\n";
16592ffb21SWarner Losh
17592ffb21SWarner Losh    my $in_list = 0;
18592ffb21SWarner Losh
19592ffb21SWarner Losh    my %pciids = ();
20592ffb21SWarner Losh
21592ffb21SWarner Losh    my $current_vendor_define;
22592ffb21SWarner Losh
23592ffb21SWarner Losh    while (my $line = <$fh>) {
24592ffb21SWarner Losh        if ($line =~ /^#define +([^ ]+) +/) {
25592ffb21SWarner Losh            $current_vendor_define = $1;
26592ffb21SWarner Losh            $pciids{$current_vendor_define} = {};
27592ffb21SWarner Losh        } elsif ($line =~ /^\t\{0x([0-9a-fA-F]{4}), *0x([0-9a-fA-F]{4}),[^,]+,[^,]+,[^,]+,[^,]+, *([^}]+)\}/) {
28592ffb21SWarner Losh            my $vendor_id = uc($1);
29592ffb21SWarner Losh            my $device_id = uc($2);
30592ffb21SWarner Losh            my $flags     = $3;
31592ffb21SWarner Losh
32592ffb21SWarner Losh            $pciids{$current_vendor_define}{$device_id} = {
33592ffb21SWarner Losh                'vendor_id' => $vendor_id,
34592ffb21SWarner Losh                'flags'     => $flags
35592ffb21SWarner Losh            };
36592ffb21SWarner Losh        }
37592ffb21SWarner Losh    }
38592ffb21SWarner Losh
39592ffb21SWarner Losh    close($fh);
40592ffb21SWarner Losh
41592ffb21SWarner Losh    return %pciids;
42592ffb21SWarner Losh}
43592ffb21SWarner Losh
44592ffb21SWarner Loshsub parse_freebsd_header ($) {
45592ffb21SWarner Losh    my ($header) = @_;
46592ffb21SWarner Losh
47592ffb21SWarner Losh    open(my $fh, '<', $header) or die "Can't open FreeBSD header: $!\n";
48592ffb21SWarner Losh
49592ffb21SWarner Losh    my $in_list = 0;
50592ffb21SWarner Losh
51592ffb21SWarner Losh    my %pciids = ();
52592ffb21SWarner Losh
53592ffb21SWarner Losh    my $current_vendor_define;
54592ffb21SWarner Losh
55592ffb21SWarner Losh    while (my $line = <$fh>) {
56592ffb21SWarner Losh        if ($line =~ /^#define +([^ ]+) +/) {
57592ffb21SWarner Losh            $current_vendor_define = $1;
58592ffb21SWarner Losh            $pciids{$current_vendor_define} = {};
59592ffb21SWarner Losh        } elsif ($line =~ /^\t\{0x([0-9a-fA-F]{4}), *0x([0-9a-fA-F]{4}), *([^,]+), *"([^"]+)"\}/) {
60592ffb21SWarner Losh            my $vendor_id = uc($1);
61592ffb21SWarner Losh            my $device_id = uc($2);
62592ffb21SWarner Losh            my $flags     = $3;
63592ffb21SWarner Losh            my $name      = $4;
64592ffb21SWarner Losh
65592ffb21SWarner Losh            $pciids{$current_vendor_define}{$device_id} = {
66592ffb21SWarner Losh                'vendor_id' => $vendor_id,
67592ffb21SWarner Losh                'flags'     => $flags,
68592ffb21SWarner Losh                'name'      => $name
69592ffb21SWarner Losh            };
70592ffb21SWarner Losh        }
71592ffb21SWarner Losh    }
72592ffb21SWarner Losh
73592ffb21SWarner Losh    close($fh);
74592ffb21SWarner Losh
75592ffb21SWarner Losh    return %pciids;
76592ffb21SWarner Losh}
77592ffb21SWarner Losh
78592ffb21SWarner Loshsub parse_pciids_db ($) {
79592ffb21SWarner Losh    my ($header) = @_;
80592ffb21SWarner Losh
81592ffb21SWarner Losh    open(my $fh, '<', $header) or die "Can't open PCI IDs database: $!\n";
82592ffb21SWarner Losh
83592ffb21SWarner Losh    my %pciids = ();
84592ffb21SWarner Losh
85592ffb21SWarner Losh    my $current_vendor_id;
86592ffb21SWarner Losh
87592ffb21SWarner Losh    while (my $line = <$fh>) {
88592ffb21SWarner Losh        if (!$line || $line =~ /^#/) {
89592ffb21SWarner Losh            next;
90592ffb21SWarner Losh        }
91592ffb21SWarner Losh        if ($line =~ /^([0-9a-fA-F]{4})  (.+)/) {
92592ffb21SWarner Losh            # Vendor ID & name.
93592ffb21SWarner Losh            my $vendor_id   = uc($1);
94592ffb21SWarner Losh            my $vendor_name = $2;
95592ffb21SWarner Losh            $pciids{$vendor_id} = {
96592ffb21SWarner Losh                'name'    => $vendor_name,
97592ffb21SWarner Losh                'devices' => {}
98592ffb21SWarner Losh            };
99592ffb21SWarner Losh
100592ffb21SWarner Losh            $current_vendor_id = $vendor_id;
101592ffb21SWarner Losh        } elsif ($line =~ /^\t([0-9a-fA-F]{4})  (.+)/) {
102592ffb21SWarner Losh            # Device ID & name.
103592ffb21SWarner Losh            my $device_id   = uc($1);
104592ffb21SWarner Losh            my $device_name = $2;
105592ffb21SWarner Losh            $pciids{$current_vendor_id}{'devices'}{$device_id} = $device_name;
106592ffb21SWarner Losh        }
107592ffb21SWarner Losh    }
108592ffb21SWarner Losh
109592ffb21SWarner Losh    close($fh);
110592ffb21SWarner Losh
111592ffb21SWarner Losh    return %pciids;
112592ffb21SWarner Losh}
113592ffb21SWarner Losh
114592ffb21SWarner Loshif (scalar(@ARGV) != 3) {
115592ffb21SWarner Losh    print STDERR "Syntax: $progname <linux_header> <freebsd_header> <pciids_db> [<vendor_define>]\n";
116592ffb21SWarner Losh    exit 1;
117592ffb21SWarner Losh}
118592ffb21SWarner Losh
119592ffb21SWarner Loshmy $linux_header   = $ARGV[0];
120592ffb21SWarner Loshmy $freebsd_header = $ARGV[1];
121592ffb21SWarner Loshmy $pciids_db      = $ARGV[2];
122592ffb21SWarner Loshmy $only_vendor    = $ARGV[3];
123592ffb21SWarner Losh
124592ffb21SWarner Loshmy %linux_pciids   = parse_linux_header($linux_header);
125592ffb21SWarner Loshmy %freebsd_pciids = parse_freebsd_header($freebsd_header);
126592ffb21SWarner Loshmy %pciids_db      = parse_pciids_db($pciids_db);
127592ffb21SWarner Losh
128592ffb21SWarner Loshprint STDERR "Update FreeBSD's PCI IDs:\n";
129592ffb21SWarner Loshforeach my $vendor_define (sort keys(%linux_pciids)) {
130592ffb21SWarner Losh    if ($only_vendor && $vendor_define ne $only_vendor) {
131592ffb21SWarner Losh        print STDERR "(skip unwanted define: $vendor_define)\n";
132592ffb21SWarner Losh        next;
133592ffb21SWarner Losh    } elsif (!$only_vendor && !exists($freebsd_pciids{$vendor_define})) {
134592ffb21SWarner Losh        print STDERR "(skip unsupport define: $vendor_define)\n";
135592ffb21SWarner Losh        next;
136592ffb21SWarner Losh    }
137592ffb21SWarner Losh
138592ffb21SWarner Losh    foreach my $device_id (sort keys(%{$linux_pciids{$vendor_define}})) {
139592ffb21SWarner Losh        my $vendor_id = $linux_pciids{$vendor_define}{$device_id}{'vendor_id'};
140592ffb21SWarner Losh
141592ffb21SWarner Losh        if (exists($freebsd_pciids{$vendor_define}{$device_id})) {
142592ffb21SWarner Losh            print STDERR "  $vendor_define: $vendor_id:$device_id already in header\n";
143592ffb21SWarner Losh            next;
144592ffb21SWarner Losh        }
145592ffb21SWarner Losh
146592ffb21SWarner Losh        my $flags     = $linux_pciids{$vendor_define}{$device_id}{'flags'};
147592ffb21SWarner Losh        my $name      = $pciids_db{$vendor_id}{'devices'}{$device_id} || "Unknown device name";
148592ffb21SWarner Losh        print STDERR "  $vendor_define: $vendor_id:$device_id is missing ($name)\n";
149592ffb21SWarner Losh        $freebsd_pciids{$vendor_define}{$device_id} = {
150592ffb21SWarner Losh            'vendor_id' => $vendor_id,
151592ffb21SWarner Losh            'flags'     => $flags,
152592ffb21SWarner Losh            'name'      => $name
153592ffb21SWarner Losh        };
154592ffb21SWarner Losh    }
155592ffb21SWarner Losh}
156592ffb21SWarner Losh
157592ffb21SWarner Loshprint STDERR "\nWrite FreeBSD header to stdout...\n";
158592ffb21SWarner Loshprint <<"EOF";
159592ffb21SWarner Losh/*
160592ffb21SWarner Losh * Generated by $progname from:
161592ffb21SWarner Losh *   o  previous FreeBSD's drm_pciids.h
162592ffb21SWarner Losh *   o  Linux' drm_pciids.h
163592ffb21SWarner Losh *   o  the PCI ID repository (http://pciids.sourceforge.net/)
164592ffb21SWarner Losh *
165592ffb21SWarner Losh * See tools/tools/drm/$progname.
166592ffb21SWarner Losh */
167592ffb21SWarner LoshEOF
168592ffb21SWarner Loshforeach my $vendor_define (sort keys(%freebsd_pciids)) {
169592ffb21SWarner Losh    print "\n#define $vendor_define \\\n";
170592ffb21SWarner Losh    foreach my $device_id (sort keys(%{$freebsd_pciids{$vendor_define}})) {
171592ffb21SWarner Losh        my $vendor_id = $freebsd_pciids{$vendor_define}{$device_id}{'vendor_id'};
172592ffb21SWarner Losh        my $flags     = $freebsd_pciids{$vendor_define}{$device_id}{'flags'};
173592ffb21SWarner Losh        my $name      = $freebsd_pciids{$vendor_define}{$device_id}{'name'};
174592ffb21SWarner Losh
175592ffb21SWarner Losh        print "\t{0x$vendor_id, 0x$device_id, $flags, \"$name\"}, \\\n";
176592ffb21SWarner Losh    }
177592ffb21SWarner Losh    print "\t{0, 0, 0, NULL}\n";
178592ffb21SWarner Losh}
179