1 | #!/usr/bin/perl -w
|
---|
2 | #
|
---|
3 | # Helper program to generate Makefile rules into file Rom from table in
|
---|
4 | # file NIC
|
---|
5 | #
|
---|
6 | # GPL, Ken Yap 2001, with major contributions by Klaus Espenlaub
|
---|
7 | # Revised 2002
|
---|
8 | #
|
---|
9 |
|
---|
10 | use strict;
|
---|
11 |
|
---|
12 | use bytes;
|
---|
13 |
|
---|
14 | use File::Basename;
|
---|
15 |
|
---|
16 | use vars qw($familyfile $nic @families $curfam %drivers %pcient %isaent %isalist %buildent $arch @srcs);
|
---|
17 |
|
---|
18 | sub __gendep ($$$)
|
---|
19 | {
|
---|
20 | my ($file, $deps, $driver_dep) = @_;
|
---|
21 | foreach my $source (@$deps) {
|
---|
22 | my $inc;
|
---|
23 | my @collect_dep = ();
|
---|
24 | $inc = "arch/$arch/include/$source" unless ! -e "arch/$arch/include/$source";
|
---|
25 | $inc = "include/$source" unless ! -e "include/$source";
|
---|
26 | $inc = dirname($file) . "/$source" unless ! -e dirname($file) . "/$source";
|
---|
27 | unless (defined($inc)) {
|
---|
28 | print STDERR "$source from $file not found (shouldn't happen)\n";
|
---|
29 | next;
|
---|
30 | };
|
---|
31 | next if (exists ${$driver_dep}{$inc});
|
---|
32 | ${$driver_dep}{$inc} = $inc;
|
---|
33 | # Warn about failure to open, then skip, rather than soldiering on with the read
|
---|
34 | unless (open(INFILE, "$inc")) {
|
---|
35 | print STDERR "$inc: $! (shouldn't happen)\n";
|
---|
36 | next;
|
---|
37 | };
|
---|
38 | while (<INFILE>) {
|
---|
39 | chomp($_);
|
---|
40 | # This code is not very smart: no C comments or CPP conditionals processing is
|
---|
41 | # done. This may cause unexpected (or incorrect) additional dependencies.
|
---|
42 | # However, ignoring the CPP conditionals is in some sense correct: we need to
|
---|
43 | # figure out a superset of all the headers for the driver source.
|
---|
44 | next unless (s/^\s*#include\s*"([^"]*)".*$/$1/);
|
---|
45 | # Ignore system includes, like the ones in osdep.h
|
---|
46 | next if ($_ =~ m:^/:);
|
---|
47 | # Ignore "special" includes, like .buildserial.h
|
---|
48 | next if /^\./;
|
---|
49 | push(@collect_dep, $_);
|
---|
50 | }
|
---|
51 | close(INFILE);
|
---|
52 | if (@collect_dep) {
|
---|
53 | &__gendep($inc, \@collect_dep, $driver_dep);
|
---|
54 | }
|
---|
55 | }
|
---|
56 | }
|
---|
57 |
|
---|
58 | sub gendep ($) {
|
---|
59 | my ($driver) = @_;
|
---|
60 |
|
---|
61 | # Automatically generate the dependencies for the driver sources.
|
---|
62 | my %driver_dep = ();
|
---|
63 | __gendep( "", [ $driver ], \%driver_dep);
|
---|
64 | return sort values %driver_dep
|
---|
65 | }
|
---|
66 |
|
---|
67 | # Make sure that every rom name exists only once.
|
---|
68 | # make will warn if it finds duplicate rules, but it is better to stop
|
---|
69 | sub checkduplicate (\%$$) {
|
---|
70 | my ($anyent, $curfam, $romname) = @_;
|
---|
71 | foreach my $family (@families) {
|
---|
72 | if (exists($$anyent{$family})) {
|
---|
73 | my $aref = $$anyent{$family};
|
---|
74 | foreach my $entry (@$aref) {
|
---|
75 | if ($entry->[0] eq $romname) {
|
---|
76 | print STDERR "\nROM name $romname defined twice. Please correct.\n";
|
---|
77 | exit 1;
|
---|
78 | }
|
---|
79 | }
|
---|
80 | }
|
---|
81 | }
|
---|
82 | }
|
---|
83 |
|
---|
84 | sub genroms($) {
|
---|
85 | my ($driver) = @_;
|
---|
86 |
|
---|
87 | # Automatically discover the ROMS this driver can produce.
|
---|
88 | unless (open(INFILE, "$driver")) {
|
---|
89 | print STDERR "$driver: %! (shouldn't happen)\n";
|
---|
90 | next;
|
---|
91 | };
|
---|
92 | while (<INFILE>) {
|
---|
93 | chomp($_);
|
---|
94 | if ($_ =~ m/^\s*PCI_ROM\(\s*0x([0-9A-Fa-f]*)\s*,\s*0x([0-9A-Fa-f]*)\s*,\s*"([^"]*)"\s*,\s*"([^"]*)"\)/) {
|
---|
95 |
|
---|
96 | # We store a list of PCI IDs and comments for each PC target
|
---|
97 | my ($vendor_id, $device_id, $rom, $comment) = (hex($1), hex($2), $3, $4);
|
---|
98 | my $ids = sprintf("0x%04x,0x%04x", $vendor_id, $device_id);
|
---|
99 | checkduplicate(%pcient, $curfam, $rom);
|
---|
100 | push(@{$pcient{$curfam}}, [$rom, $ids, $comment]);
|
---|
101 | }
|
---|
102 | elsif($_ =~ m/^\s*ISA_ROM\(\s*"([^"]*)"\s*,\s*"([^"]*)"\)/) {
|
---|
103 | my ($rom, $comment) = ($1, $2);
|
---|
104 | # We store the base driver file for each ISA target
|
---|
105 | $isalist{$rom} = $curfam;
|
---|
106 | $buildent{$rom} = 1;
|
---|
107 | checkduplicate(%isaent, $curfam, $rom);
|
---|
108 | push(@{$isaent{$curfam}}, [$rom, $comment]);
|
---|
109 | }
|
---|
110 | elsif($_ =~ m/^\s*PCI_ROM/ or $_ =~ m/^\s*ISA_ROM/) {
|
---|
111 | # Complain since we cannot parse this. Of course it would be nicer if we could parse...
|
---|
112 | print STDERR "\nFound incomplete PCI_ROM or ISA_ROM macro in file $driver.\n";
|
---|
113 | print STDERR "ROM macros spanning more than one line are not supported,\n";
|
---|
114 | print STDERR "please adjust $driver accordingly.\n\n\n";
|
---|
115 | exit 1;
|
---|
116 | }
|
---|
117 | }
|
---|
118 | }
|
---|
119 |
|
---|
120 | sub addfam ($) {
|
---|
121 | my ($family) = @_;
|
---|
122 |
|
---|
123 | push(@families, $family);
|
---|
124 | # We store the list of dependencies in the hash for each family
|
---|
125 | my @deps = &gendep("$family.c");
|
---|
126 | $drivers{$family} = join(' ', @deps);
|
---|
127 | $pcient{$family} = [];
|
---|
128 | genroms("$family.c");
|
---|
129 | }
|
---|
130 |
|
---|
131 | sub addrom ($) {
|
---|
132 | my ($rom, $ids, $comment) = split(' ', $_[0], 3);
|
---|
133 |
|
---|
134 | # defaults if missing
|
---|
135 | $ids = '-' unless ($ids);
|
---|
136 | $comment = $rom unless ($comment);
|
---|
137 | if ($ids ne '-') {
|
---|
138 | # We store a list of PCI IDs and comments for each PCI target
|
---|
139 | checkduplicate(%pcient, $curfam, $rom);
|
---|
140 | push(@{$pcient{$curfam}}, [$rom, $ids, $comment]);
|
---|
141 | } else {
|
---|
142 | # We store the base driver file for each ISA target
|
---|
143 | $isalist{$rom} = $curfam;
|
---|
144 | $buildent{$rom} = 1;
|
---|
145 | checkduplicate(%isaent, $curfam, $rom);
|
---|
146 | push(@{$isaent{$curfam}}, [$rom, $comment]);
|
---|
147 | }
|
---|
148 | }
|
---|
149 |
|
---|
150 | # Return true if this driver is ISA only
|
---|
151 | sub isaonly ($) {
|
---|
152 | my $aref = $pcient{$_[0]};
|
---|
153 |
|
---|
154 | return ($#$aref < 0);
|
---|
155 | }
|
---|
156 |
|
---|
157 | $#ARGV >= 1 or die "Usage: $0 Families bin/NIC arch sources...\n";
|
---|
158 | $familyfile = shift(@ARGV);
|
---|
159 | $nic = shift(@ARGV);
|
---|
160 | $arch = shift(@ARGV);
|
---|
161 | @srcs = @ARGV;
|
---|
162 | open FAM, "<$familyfile" or die "Could not open $familyfile: $!\n";
|
---|
163 |
|
---|
164 | $curfam = '';
|
---|
165 | while ( <FAM> ) {
|
---|
166 | chomp($_);
|
---|
167 | next if (/^\s*(#.*)?$/);
|
---|
168 | my ($keyword) = split(' ', $_ , 2);
|
---|
169 | if ($keyword eq 'family') {
|
---|
170 | my ($keyword, $driver) = split(' ', $_, 2);
|
---|
171 | $curfam = '';
|
---|
172 | if (! -e "$driver.c") {
|
---|
173 | print STDERR "Driver file $driver.c not found, skipping...\n";
|
---|
174 | next;
|
---|
175 | }
|
---|
176 | if ($driver =~ "^arch" && $driver !~ "^arch/$arch") {
|
---|
177 | # This warning just makes noise for most compilations.
|
---|
178 | # print STDERR "Driver file $driver.c not for arch $arch, skipping...\n";
|
---|
179 | next;
|
---|
180 | }
|
---|
181 | &addfam($curfam = $driver);
|
---|
182 | } else {
|
---|
183 | # skip until we have a valid family
|
---|
184 | next if ($curfam eq '');
|
---|
185 | &addrom($_);
|
---|
186 | }
|
---|
187 | }
|
---|
188 | close FAM;
|
---|
189 |
|
---|
190 | open(N,">$nic") or die "$nic: $!\n";
|
---|
191 | print N <<EOF;
|
---|
192 | # This is an automatically generated file, do not edit
|
---|
193 | # It does not affect anything in the build, it's only for rom-o-matic
|
---|
194 |
|
---|
195 | EOF
|
---|
196 | foreach my $family (@families) {
|
---|
197 | print N "family\t$family\n";
|
---|
198 | if (exists($pcient{$family})) {
|
---|
199 | my $aref = $pcient{$family};
|
---|
200 | foreach my $entry (@$aref) {
|
---|
201 | my $rom = $entry->[0];
|
---|
202 | my $ids = $entry->[1];
|
---|
203 | my $comment = $entry->[2];
|
---|
204 | print N "$rom\t$ids\t$comment\n";
|
---|
205 | }
|
---|
206 | }
|
---|
207 | if (exists($isaent{$family})) {
|
---|
208 | my $aref = $isaent{$family};
|
---|
209 | foreach my $entry (@$aref) {
|
---|
210 | my $rom = $entry->[0];
|
---|
211 | my $comment = $entry->[1];
|
---|
212 | print N "$rom\t-\t$comment\n";
|
---|
213 | }
|
---|
214 | }
|
---|
215 | print N "\n";
|
---|
216 | }
|
---|
217 | close(N);
|
---|
218 |
|
---|
219 | # Generate the normal source dependencies
|
---|
220 | print "# Core object file dependencies\n";
|
---|
221 | foreach my $source (@srcs) {
|
---|
222 | next if ($source !~ '[.][cS]$');
|
---|
223 | my @deps = &gendep($source);
|
---|
224 | my $obj = $source;
|
---|
225 | $obj =~ s/^.*?([^\/]+)\.[cS]/bin\/$1.o/;
|
---|
226 | foreach my $dep (@deps) {
|
---|
227 | print "$obj: $dep\n";
|
---|
228 | }
|
---|
229 | print("\n");
|
---|
230 | }
|
---|
231 |
|
---|
232 | # Generate the assignments to DOBJS and BINS
|
---|
233 | print "# Driver object files and ROM image files\n";
|
---|
234 | print "DOBJS\t:=\n";
|
---|
235 | print "PCIOBJS\t:=\n";
|
---|
236 |
|
---|
237 | print "# Target formats\n";
|
---|
238 | print "EB_ISOS\t:=\n";
|
---|
239 | print "EB_LISOS\t:=\n";
|
---|
240 | print "EB_COMS\t:=\n";
|
---|
241 | print "EB_EXES\t:=\n";
|
---|
242 | print "EB_LILOS\t:=\n";
|
---|
243 | print "EB_ZLILOS\t:=\n";
|
---|
244 | print "EB_PXES\t:=\n";
|
---|
245 | print "EB_ZPXES\t:=\n";
|
---|
246 | print "EB_DSKS\t:=\n";
|
---|
247 | print "EB_ZDSKS\t:=\n";
|
---|
248 | print "EB_HDS\t:=\n";
|
---|
249 | print "EB_ZHDS\t:=\n";
|
---|
250 | print "EB_ELFS\t:=\n";
|
---|
251 | print "EB_ZELFS\t:=\n";
|
---|
252 | print "EB_LMELFS\t:=\n";
|
---|
253 | print "EB_ZLMELFS\t:=\n";
|
---|
254 | print "EB_ELFDS\t:=\n";
|
---|
255 | print "EB_ZELFDS\t:=\n";
|
---|
256 | print "EB_LMELFDS\t:=\n";
|
---|
257 | print "EB_ZLMELFDS\t:=\n";
|
---|
258 |
|
---|
259 | foreach my $pci (sort keys %pcient) {
|
---|
260 | my $img = basename($pci);
|
---|
261 |
|
---|
262 | print "DOBJS\t+= \$(BIN)/$img.o\n";
|
---|
263 | print "PCIOBJS\t+= \$(BIN)/$img.o\n" unless isaonly($pci);
|
---|
264 |
|
---|
265 | # Output targets
|
---|
266 | print "EB_LILOS\t+= \$(BIN)/$img.lilo \nEB_ZLILOS\t+= \$(BIN)/$img.zlilo\n";
|
---|
267 | print "EB_PXES\t+= \$(BIN)/$img.pxe \nEB_ZPXES\t+= \$(BIN)/$img.zpxe\n";
|
---|
268 | print "EB_DSKS\t+= \$(BIN)/$img.dsk \nEB_ZDSKS\t+= \$(BIN)/$img.zdsk\n";
|
---|
269 | print "EB_HDS\t+= \$(BIN)/$img.hd \nEB_ZHDS\t+= \$(BIN)/$img.zhd\n";
|
---|
270 | print "EB_ELFS\t+= \$(BIN)/$img.elf \nEB_ZELFS\t+= \$(BIN)/$img.zelf\n";
|
---|
271 | print "EB_LMELFS\t+= \$(BIN)/$img.lmelf \nEB_ZLMELFS\t+= \$(BIN)/$img.zlmelf\n";
|
---|
272 | print "EB_ELFDS\t+= \$(BIN)/$img.elfd \nEB_ZELFDS\t+= \$(BIN)/$img.zelfd\n";
|
---|
273 | print "EB_LMELFDS\t+= \$(BIN)/$img.lmelfd \nEB_ZLMELFDS\t+= \$(BIN)/$img.zlmelfd\n";
|
---|
274 | print "EB_BIMAGES\t+= \$(BIN)/$img.bImage \nEB_BZIMAGES\t+= \$(BIN)/$img.bzImage\n";
|
---|
275 | print "EB_ISOS\t+= \$(BIN)/$img.iso\n";
|
---|
276 | print "EB_LISOS\t+= \$(BIN)/$img.liso\n";
|
---|
277 | print "EB_COMS\t+= \$(BIN)/$img.com\n";
|
---|
278 | print "EB_EXES\t+= \$(BIN)/$img.exe\n";
|
---|
279 | }
|
---|
280 |
|
---|
281 | foreach my $img (sort keys %buildent) {
|
---|
282 |
|
---|
283 | print "DOBJS\t+= \$(BIN)/$img.o\n";
|
---|
284 |
|
---|
285 | # Output targets
|
---|
286 | print "EB_LILOS\t+= \$(BIN)/$img.lilo \nEB_ZLILOS\t+= \$(BIN)/$img.zlilo\n";
|
---|
287 | print "EB_PXES\t+= \$(BIN)/$img.pxe \nEB_ZPXES\t+= \$(BIN)/$img.zpxe\n";
|
---|
288 | print "EB_DSKS\t+= \$(BIN)/$img.dsk \nEB_ZDSKS\t+= \$(BIN)/$img.zdsk\n";
|
---|
289 | print "EB_HDS\t+= \$(BIN)/$img.hd \nEB_ZHDS\t+= \$(BIN)/$img.zhd\n";
|
---|
290 | print "EB_ELFS\t+= \$(BIN)/$img.elf \nEB_ZELFS\t+= \$(BIN)/$img.zelf\n";
|
---|
291 | print "EB_LMELFS\t+= \$(BIN)/$img.lmelf \nEB_ZLMELFS\t+= \$(BIN)/$img.zlmelf\n";
|
---|
292 | print "EB_ELFDS\t+= \$(BIN)/$img.elfd \nEB_ZELFDS\t+= \$(BIN)/$img.zelfd\n";
|
---|
293 | print "EB_LMELFDS\t+= \$(BIN)/$img.lmelfd \nEB_ZLMELFDS\t+= \$(BIN)/$img.zlmelfd\n";
|
---|
294 | print "EB_BIMAGES\t+= \$(BIN)/$img.bImage \nEB_BZIMAGE\t+= \$(BIN)/$img.bzImage\n";
|
---|
295 | print "EB_ISOS\t+= \$(BIN)/$img.iso\n";
|
---|
296 | print "EB_LISOS\t+= \$(BIN)/$img.liso\n";
|
---|
297 | print "EB_COMS\t+= \$(BIN)/$img.com\n";
|
---|
298 | print "EB_EXES\t+= \$(BIN)/$img.exe\n";
|
---|
299 | }
|
---|
300 |
|
---|
301 | print "ROMS\t:=\n";
|
---|
302 | foreach my $family (sort keys %pcient) {
|
---|
303 | my $aref = $pcient{$family};
|
---|
304 | foreach my $entry (@$aref) {
|
---|
305 | my $rom = $entry->[0];
|
---|
306 | print "ROMS\t+= \$(BIN)/$rom.rom \$(BIN)/$rom.zrom\n";
|
---|
307 | }
|
---|
308 | }
|
---|
309 | foreach my $isa (sort keys %isalist) {
|
---|
310 | print "ROMS\t+= \$(BIN)/$isa.rom \$(BIN)/$isa.zrom\n";
|
---|
311 | }
|
---|
312 |
|
---|
313 | # Generate the *.o rules
|
---|
314 | print "\n# Rules to build the driver object files\n";
|
---|
315 | foreach my $pci (sort keys %drivers) {
|
---|
316 | # For ISA the rule for .o will generated later
|
---|
317 | next if isaonly($pci);
|
---|
318 | # PCI drivers are compiled only once for all ROMs
|
---|
319 | (my $macro = basename($pci)) =~ tr/\-/_/;
|
---|
320 | my $obj = basename($pci);
|
---|
321 | my $deps = $drivers{$pci};
|
---|
322 | print <<EOF;
|
---|
323 |
|
---|
324 | \$(BIN)/$obj.o: $pci.c \$(MAKEDEPS) $deps
|
---|
325 | \$(CC) \$(CFLAGS) \$(\U$macro\EFLAGS) -o \$@ -c \$<
|
---|
326 |
|
---|
327 | \$(BIN)/$obj--%.o: \$(BIN)/%.o \$(BIN)/$obj.o \$(MAKEDEPS)
|
---|
328 | \$(LD) \$(LDFLAGS) -r \$(BIN)/$obj.o \$< -o \$@
|
---|
329 |
|
---|
330 | EOF
|
---|
331 | }
|
---|
332 |
|
---|
333 | # Do the ISA entries
|
---|
334 | foreach my $isa (sort keys %isalist) {
|
---|
335 | (my $macro = $isa) =~ tr/\-/_/;
|
---|
336 | my $base = $isalist{$isa};
|
---|
337 | my $deps = $drivers{$base};
|
---|
338 | print <<EOF;
|
---|
339 | \$(BIN)/$isa.o: $base.c \$(MAKEDEPS) $deps
|
---|
340 | \$(CC) \$(CFLAGS) \$(\U$macro\EFLAGS) -o \$@ -c \$<
|
---|
341 |
|
---|
342 | \$(BIN)/$isa--%.o: \$(BIN)/%.o \$(BIN)/$isa.o \$(MAKEDEPS)
|
---|
343 | \$(LD) \$(LDFLAGS) -r \$(BIN)/$isa.o \$< -o \$@
|
---|
344 | EOF
|
---|
345 | }
|
---|
346 |
|
---|
347 | # Generate the Rom rules
|
---|
348 | print "# Rules to build the ROM files\n";
|
---|
349 | foreach my $family (sort keys %pcient) {
|
---|
350 | next if isaonly($family);
|
---|
351 | my $img = basename($family);
|
---|
352 | print <<EOF;
|
---|
353 | ROMTYPE_$img = PCI
|
---|
354 | EOF
|
---|
355 | my $aref = $pcient{$family};
|
---|
356 | foreach my $entry (@$aref) {
|
---|
357 | my ($rom, $ids, $comment) = @$entry;
|
---|
358 | next if ($ids eq '-');
|
---|
359 | print <<EOF;
|
---|
360 | ROMTYPE_$rom = PCI
|
---|
361 | MAKEROM_ID_$rom = -p $ids
|
---|
362 |
|
---|
363 | EOF
|
---|
364 | next if($rom eq $img);
|
---|
365 | print <<EOF;
|
---|
366 | \$(BIN)/$rom\%rom: \$(BIN)/$img\%rom
|
---|
367 | cat \$< > \$@
|
---|
368 | \$(MAKEROM) \$(MAKEROM_FLAGS) \$(MAKEROM_\$(ROMCARD)) \$(MAKEROM_ID_\$(ROMCARD)) -i\$(IDENT) \$@
|
---|
369 |
|
---|
370 | EOF
|
---|
371 | }
|
---|
372 | }
|
---|
373 |
|
---|
374 | # ISA ROMs are prepared from the matching code images
|
---|
375 | # Think this can probably be removed, but not sure
|
---|
376 | foreach my $isa (sort keys %isalist) {
|
---|
377 | print <<EOF;
|
---|
378 | EOF
|
---|
379 | }
|
---|
380 |
|
---|