123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- #!/usr/bin/perl -w
- #
- # Helper program to generate Makefile rules into file Rom from table in
- # file NIC
- #
- # GPL, Ken Yap 2001, with major contributions by Klaus Espenlaub
- # Revised 2002
- #
-
- use strict;
-
- use bytes;
-
- use File::Basename;
-
- use vars qw($familyfile $nic @families $curfam %drivers %pcient %isaent %isalist %buildent $arch @srcs);
-
- sub __gendep ($$$)
- {
- my ($file, $deps, $driver_dep) = @_;
- foreach my $source (@$deps) {
- my $inc;
- my @collect_dep = ();
- $inc = "arch/$arch/include/$source" unless ! -e "arch/$arch/include/$source";
- $inc = "include/$source" unless ! -e "include/$source";
- $inc = dirname($file) . "/$source" unless ! -e dirname($file) . "/$source";
- unless (defined($inc)) {
- print STDERR "$source from $file not found (shouldn't happen)\n";
- next;
- };
- next if (exists ${$driver_dep}{$inc});
- ${$driver_dep}{$inc} = $inc;
- # Warn about failure to open, then skip, rather than soldiering on with the read
- unless (open(INFILE, "$inc")) {
- print STDERR "$inc: $! (shouldn't happen)\n";
- next;
- };
- while (<INFILE>) {
- chomp($_);
- # This code is not very smart: no C comments or CPP conditionals processing is
- # done. This may cause unexpected (or incorrect) additional dependencies.
- # However, ignoring the CPP conditionals is in some sense correct: we need to
- # figure out a superset of all the headers for the driver source.
- next unless (s/^\s*#include\s*"([^"]*)".*$/$1/);
- # Ignore system includes, like the ones in osdep.h
- next if ($_ =~ m:^/:);
- # Ignore "special" includes, like .buildserial.h
- next if /^\./;
- push(@collect_dep, $_);
- }
- close(INFILE);
- if (@collect_dep) {
- &__gendep($inc, \@collect_dep, $driver_dep);
- }
- }
- }
-
- sub gendep ($) {
- my ($driver) = @_;
-
- # Automatically generate the dependencies for the driver sources.
- my %driver_dep = ();
- __gendep( "", [ $driver ], \%driver_dep);
- return sort values %driver_dep
- }
-
- # Make sure that every rom name exists only once.
- # make will warn if it finds duplicate rules, but it is better to stop
- sub checkduplicate (\%$$) {
- my ($anyent, $curfam, $romname) = @_;
- foreach my $family (@families) {
- if (exists($$anyent{$family})) {
- my $aref = $$anyent{$family};
- foreach my $entry (@$aref) {
- if ($entry->[0] eq $romname) {
- print STDERR "\nROM name $romname defined twice. Please correct.\n";
- exit 1;
- }
- }
- }
- }
- }
-
- sub genroms($) {
- my ($driver) = @_;
-
- # Automatically discover the ROMS this driver can produce.
- unless (open(INFILE, "$driver")) {
- print STDERR "$driver: %! (shouldn't happen)\n";
- next;
- };
- while (<INFILE>) {
- chomp($_);
- if ($_ =~ m/^\s*PCI_ROM\(\s*0x([0-9A-Fa-f]*)\s*,\s*0x([0-9A-Fa-f]*)\s*,\s*"([^"]*)"\s*,\s*"([^"]*)"\)/) {
-
- # We store a list of PCI IDs and comments for each PC target
- my ($vendor_id, $device_id, $rom, $comment) = (hex($1), hex($2), $3, $4);
- my $ids = sprintf("0x%04x,0x%04x", $vendor_id, $device_id);
- checkduplicate(%pcient, $curfam, $rom);
- push(@{$pcient{$curfam}}, [$rom, $ids, $comment]);
- }
- elsif($_ =~ m/^\s*ISA_ROM\(\s*"([^"]*)"\s*,\s*"([^"]*)"\)/) {
- my ($rom, $comment) = ($1, $2);
- # We store the base driver file for each ISA target
- $isalist{$rom} = $curfam;
- $buildent{$rom} = 1;
- checkduplicate(%isaent, $curfam, $rom);
- push(@{$isaent{$curfam}}, [$rom, $comment]);
- }
- elsif($_ =~ m/^\s*PCI_ROM/ or $_ =~ m/^\s*ISA_ROM/) {
- # Complain since we cannot parse this. Of course it would be nicer if we could parse...
- print STDERR "\nFound incomplete PCI_ROM or ISA_ROM macro in file $driver.\n";
- print STDERR "ROM macros spanning more than one line are not supported,\n";
- print STDERR "please adjust $driver accordingly.\n\n\n";
- exit 1;
- }
- }
- }
-
- sub addfam ($) {
- my ($family) = @_;
-
- push(@families, $family);
- # We store the list of dependencies in the hash for each family
- my @deps = &gendep("$family.c");
- $drivers{$family} = join(' ', @deps);
- $pcient{$family} = [];
- genroms("$family.c");
- }
-
- sub addrom ($) {
- my ($rom, $ids, $comment) = split(' ', $_[0], 3);
-
- # defaults if missing
- $ids = '-' unless ($ids);
- $comment = $rom unless ($comment);
- if ($ids ne '-') {
- # We store a list of PCI IDs and comments for each PCI target
- checkduplicate(%pcient, $curfam, $rom);
- push(@{$pcient{$curfam}}, [$rom, $ids, $comment]);
- } else {
- # We store the base driver file for each ISA target
- $isalist{$rom} = $curfam;
- $buildent{$rom} = 1;
- checkduplicate(%isaent, $curfam, $rom);
- push(@{$isaent{$curfam}}, [$rom, $comment]);
- }
- }
-
- # Return true if this driver is ISA only
- sub isaonly ($) {
- my $aref = $pcient{$_[0]};
-
- return ($#$aref < 0);
- }
-
- $#ARGV >= 1 or die "Usage: $0 Families bin/NIC arch sources...\n";
- $familyfile = shift(@ARGV);
- $nic = shift(@ARGV);
- $arch = shift(@ARGV);
- @srcs = @ARGV;
- open FAM, "<$familyfile" or die "Could not open $familyfile: $!\n";
-
- $curfam = '';
- while ( <FAM> ) {
- chomp($_);
- next if (/^\s*(#.*)?$/);
- my ($keyword) = split(' ', $_ , 2);
- if ($keyword eq 'family') {
- my ($keyword, $driver) = split(' ', $_, 2);
- $curfam = '';
- if (! -e "$driver.c") {
- print STDERR "Driver file $driver.c not found, skipping...\n";
- next;
- }
- if ($driver =~ "^arch" && $driver !~ "^arch/$arch") {
- # This warning just makes noise for most compilations.
- # print STDERR "Driver file $driver.c not for arch $arch, skipping...\n";
- next;
- }
- &addfam($curfam = $driver);
- } else {
- # skip until we have a valid family
- next if ($curfam eq '');
- &addrom($_);
- }
- }
- close FAM;
-
- open(N,">$nic") or die "$nic: $!\n";
- print N <<EOF;
- # This is an automatically generated file, do not edit
- # It does not affect anything in the build, it's only for rom-o-matic
-
- EOF
- foreach my $family (@families) {
- print N "family\t$family\n";
- if (exists($pcient{$family})) {
- my $aref = $pcient{$family};
- foreach my $entry (@$aref) {
- my $rom = $entry->[0];
- my $ids = $entry->[1];
- my $comment = $entry->[2];
- print N "$rom\t$ids\t$comment\n";
- }
- }
- if (exists($isaent{$family})) {
- my $aref = $isaent{$family};
- foreach my $entry (@$aref) {
- my $rom = $entry->[0];
- my $comment = $entry->[1];
- print N "$rom\t-\t$comment\n";
- }
- }
- print N "\n";
- }
- close(N);
-
- # Generate the normal source dependencies
- print "# Core object file dependencies\n";
- foreach my $source (@srcs) {
- next if ($source !~ '[.][cS]$');
- my @deps = &gendep($source);
- my $obj = $source;
- $obj =~ s/^.*?([^\/]+)\.[cS]/bin\/$1.o/;
- foreach my $dep (@deps) {
- print "$obj: $dep\n";
- }
- print("\n");
- }
-
- # Generate the assignments to DOBJS and BINS
- print "# Driver object files and ROM image files\n";
- print "DOBJS\t:=\n";
- print "PCIOBJS\t:=\n";
-
- print "# Target formats\n";
- print "EB_ISOS\t:=\n";
- print "EB_LISOS\t:=\n";
- print "EB_COMS\t:=\n";
- print "EB_EXES\t:=\n";
- print "EB_LILOS\t:=\n";
- print "EB_ZLILOS\t:=\n";
- print "EB_PXES\t:=\n";
- print "EB_ZPXES\t:=\n";
- print "EB_DSKS\t:=\n";
- print "EB_ZDSKS\t:=\n";
- print "EB_ELFS\t:=\n";
- print "EB_ZELFS\t:=\n";
- print "EB_LMELFS\t:=\n";
- print "EB_ZLMELFS\t:=\n";
- print "EB_ELFDS\t:=\n";
- print "EB_ZELFDS\t:=\n";
- print "EB_LMELFDS\t:=\n";
- print "EB_ZLMELFDS\t:=\n";
-
- foreach my $pci (sort keys %pcient) {
- my $img = basename($pci);
-
- print "DOBJS\t+= \$(BIN)/$img.o\n";
- print "PCIOBJS\t+= \$(BIN)/$img.o\n" unless isaonly($pci);
-
- # Output targets
- print "EB_LILOS\t+= \$(BIN)/$img.lilo \nEB_ZLILOS\t+= \$(BIN)/$img.zlilo\n";
- print "EB_PXES\t+= \$(BIN)/$img.pxe \nEB_ZPXES\t+= \$(BIN)/$img.zpxe\n";
- print "EB_DSKS\t+= \$(BIN)/$img.dsk \nEB_ZDSKS\t+= \$(BIN)/$img.zdsk\n";
- print "EB_ELFS\t+= \$(BIN)/$img.elf \nEB_ZELFS\t+= \$(BIN)/$img.zelf\n";
- print "EB_LMELFS\t+= \$(BIN)/$img.lmelf \nEB_ZLMELFS\t+= \$(BIN)/$img.zlmelf\n";
- print "EB_ELFDS\t+= \$(BIN)/$img.elfd \nEB_ZELFDS\t+= \$(BIN)/$img.zelfd\n";
- print "EB_LMELFDS\t+= \$(BIN)/$img.lmelfd \nEB_ZLMELFDS\t+= \$(BIN)/$img.zlmelfd\n";
- print "EB_BIMAGES\t+= \$(BIN)/$img.bImage \nEB_BZIMAGES\t+= \$(BIN)/$img.bzImage\n";
- print "EB_ISOS\t+= \$(BIN)/$img.iso\n";
- print "EB_LISOS\t+= \$(BIN)/$img.liso\n";
- print "EB_COMS\t+= \$(BIN)/$img.com\n";
- print "EB_EXES\t+= \$(BIN)/$img.exe\n";
- }
-
- foreach my $img (sort keys %buildent) {
-
- print "DOBJS\t+= \$(BIN)/$img.o\n";
-
- # Output targets
- print "EB_LILOS\t+= \$(BIN)/$img.lilo \nEB_ZLILOS\t+= \$(BIN)/$img.zlilo\n";
- print "EB_PXES\t+= \$(BIN)/$img.pxe \nEB_ZPXES\t+= \$(BIN)/$img.zpxe\n";
- print "EB_DSKS\t+= \$(BIN)/$img.dsk \nEB_ZDSKS\t+= \$(BIN)/$img.zdsk\n";
- print "EB_ELFS\t+= \$(BIN)/$img.elf \nEB_ZELFS\t+= \$(BIN)/$img.zelf\n";
- print "EB_LMELFS\t+= \$(BIN)/$img.lmelf \nEB_ZLMELFS\t+= \$(BIN)/$img.zlmelf\n";
- print "EB_ELFDS\t+= \$(BIN)/$img.elfd \nEB_ZELFDS\t+= \$(BIN)/$img.zelfd\n";
- print "EB_LMELFDS\t+= \$(BIN)/$img.lmelfd \nEB_ZLMELFDS\t+= \$(BIN)/$img.zlmelfd\n";
- print "EB_BIMAGES\t+= \$(BIN)/$img.bImage \nEB_BZIMAGE\t+= \$(BIN)/$img.bzImage\n";
- print "EB_ISOS\t+= \$(BIN)/$img.iso\n";
- print "EB_LISOS\t+= \$(BIN)/$img.liso\n";
- print "EB_COMS\t+= \$(BIN)/$img.com\n";
- print "EB_EXES\t+= \$(BIN)/$img.exe\n";
- }
-
- print "ROMS\t:=\n";
- foreach my $family (sort keys %pcient) {
- my $aref = $pcient{$family};
- foreach my $entry (@$aref) {
- my $rom = $entry->[0];
- print "ROMS\t+= \$(BIN)/$rom.rom \$(BIN)/$rom.zrom\n";
- }
- }
- foreach my $isa (sort keys %isalist) {
- print "ROMS\t+= \$(BIN)/$isa.rom \$(BIN)/$isa.zrom\n";
- }
-
- # Generate the *.o rules
- print "\n# Rules to build the driver object files\n";
- foreach my $pci (sort keys %drivers) {
- # For ISA the rule for .o will generated later
- next if isaonly($pci);
- # PCI drivers are compiled only once for all ROMs
- (my $macro = basename($pci)) =~ tr/\-/_/;
- my $obj = basename($pci);
- my $deps = $drivers{$pci};
- print <<EOF;
-
- \$(BIN)/$obj.o: $pci.c \$(MAKEDEPS) $deps
- \$(CC) \$(CFLAGS) \$(\U$macro\EFLAGS) -o \$@ -c \$<
-
- \$(BIN)/$obj--%.o: \$(BIN)/%.o \$(BIN)/$obj.o \$(MAKEDEPS)
- \$(LD) -r \$(BIN)/$obj.o \$< -o \$@
-
- EOF
- }
-
- # Do the ISA entries
- foreach my $isa (sort keys %isalist) {
- (my $macro = $isa) =~ tr/\-/_/;
- my $base = $isalist{$isa};
- my $deps = $drivers{$base};
- print <<EOF;
- \$(BIN)/$isa.o: $base.c \$(MAKEDEPS) $deps
- \$(CC) \$(CFLAGS) \$(\U$macro\EFLAGS) -o \$@ -c \$<
-
- \$(BIN)/$isa--%.o: \$(BIN)/%.o \$(BIN)/$isa.o \$(MAKEDEPS)
- \$(LD) -r \$(BIN)/$isa.o \$< -o \$@
- EOF
- }
-
- # Generate the Rom rules
- print "# Rules to build the ROM files\n";
- foreach my $family (sort keys %pcient) {
- next if isaonly($family);
- my $img = basename($family);
- print <<EOF;
- ROMTYPE_$img = PCI
- EOF
- my $aref = $pcient{$family};
- foreach my $entry (@$aref) {
- my ($rom, $ids, $comment) = @$entry;
- next if ($ids eq '-');
- print <<EOF;
- ROMTYPE_$rom = PCI
- MAKEROM_ID_$rom = -p $ids
-
- EOF
- next if($rom eq $img);
- print <<EOF;
- \$(BIN)/$rom\%rom: \$(BIN)/$img\%rom
- cat \$< > \$@
- \$(MAKEROM) \$(MAKEROM_FLAGS) \$(MAKEROM_\$(ROMCARD)) \$(MAKEROM_ID_\$(ROMCARD)) -i\$(IDENT) \$@
-
- EOF
- }
- }
-
- # ISA ROMs are prepared from the matching code images
- # Think this can probably be removed, but not sure
- foreach my $isa (sort keys %isalist) {
- print <<EOF;
- EOF
- }
|