You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

genrules.pl 11KB

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