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.

romcheck.pl 1.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use warnings;
  4. use constant DEVICES => "/proc/bus/pci/devices";
  5. open my $fh, DEVICES
  6. or die "Could not open ".DEVICES.": $!";
  7. while ( ( my $line = <$fh> ) ) {
  8. # Parse line from /proc/bus/pci/devices
  9. chomp $line;
  10. ( my $bus, my $devfn, my $vendor, my $device, my $irq, my $bars, my $lengths,
  11. my $driver )
  12. = ( $line =~ /^ ([0-9a-f]{2}) ([0-9a-f]{2}) \s+
  13. ([0-9a-f]{4}) ([0-9a-f]{4}) \s+ ([0-9a-f]+) \s+
  14. ((?:[0-9a-f]+\s+){7}) ((?:[0-9a-f]+\s+){7})
  15. (.+)?$/x )
  16. or die "Invalid line \"".$line."\"\n";
  17. ( $bus, $devfn, $vendor, $device, $irq ) =
  18. map { hex ( $_ ) } ( $bus, $devfn, $vendor, $device, $irq );
  19. my $dev = ( $devfn >> 3 );
  20. my $fn = ( $devfn & 0x7 );
  21. $bars = [ map { hex ( $_ ) } split ( /\s+/, $bars ) ];
  22. $lengths = [ map { hex ( $_ ) } split ( /\s+/, $lengths ) ];
  23. # Calculate expansion ROM BAR presence and length
  24. my $rom_length = $lengths->[6];
  25. # Look for a BAR that could support a .mrom
  26. my $mrom_ok;
  27. if ( $rom_length ) {
  28. for ( my $bar = 0 ; $bar < 7 ; $bar++ ) {
  29. # Skip I/O BARs
  30. next if $bars->[$bar] & 0x01;
  31. # Skip low half of 64-bit BARs
  32. $bar++ if $bars->[$bar] & 0x04;
  33. # Skip 64-bit BARs with high dword set
  34. next if $bars->[$bar] >> 32;
  35. # Skip BARs smaller than the expansion ROM BAR
  36. next if $lengths->[$bar] < $rom_length;
  37. # This BAR is usable!
  38. $mrom_ok = 1;
  39. last;
  40. }
  41. }
  42. printf "%02x:%02x.%x (%04x:%04x)", $bus, $dev, $fn, $vendor, $device;
  43. printf " supports a %dkB .rom", ( $rom_length / 1024 ) if $rom_length;
  44. printf " or .mrom" if $mrom_ok;
  45. printf "\n";
  46. }