summaryrefslogtreecommitdiffstats
path: root/src/util/disrom.pl
diff options
context:
space:
mode:
authorMichael Brown2005-03-08 19:53:11 +0100
committerMichael Brown2005-03-08 19:53:11 +0100
commit3d6123e69ab879c72ff489afc5bf93ef0b7a94ce (patch)
tree9f3277569153a550fa8d81ebd61bd88f266eb8da /src/util/disrom.pl
downloadipxe-3d6123e69ab879c72ff489afc5bf93ef0b7a94ce.tar.gz
ipxe-3d6123e69ab879c72ff489afc5bf93ef0b7a94ce.tar.xz
ipxe-3d6123e69ab879c72ff489afc5bf93ef0b7a94ce.zip
Initial revision
Diffstat (limited to 'src/util/disrom.pl')
-rwxr-xr-xsrc/util/disrom.pl114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/util/disrom.pl b/src/util/disrom.pl
new file mode 100755
index 00000000..64128698
--- /dev/null
+++ b/src/util/disrom.pl
@@ -0,0 +1,114 @@
+#!/usr/bin/perl -w
+#
+# Program to display key information about a boot ROM
+# including PCI and PnP structures
+#
+# GPL, Ken Yap 2001
+#
+
+use bytes;
+
+sub getid ($)
+{
+ my ($offset) = @_;
+
+ return '' if ($offset == 0 or $offset > $len);
+ my ($string) = unpack('Z32', substr($data, $offset, 32));
+ return ($string);
+}
+
+sub dispci
+{
+ my ($pcidata) = substr($data, $pci, 0x18);
+ my ($dummy, $vendorid, $deviceid, $vpd, $pcilen, $pcirev,
+ $class1, $class2, $class3, $imglen, $coderev, $codetype,
+ $indicator) = unpack('a4v4C4v2C2', $pcidata);
+ $imglen *= 512;
+ my $vendorstr = sprintf('%#04x', $vendorid);
+ my $devicestr = sprintf('%#04x', $deviceid);
+ my $coderevstr = sprintf('%#04x', $coderev);
+ print <<EOF;
+PCI structure:
+
+Vital product data: $vpd
+Vendor ID: $vendorstr
+Device ID: $devicestr
+Device base type: $class1
+Device sub type: $class2
+Device interface type: $class3
+Image length: $imglen
+Code revision: $coderevstr
+Code type: $codetype
+Indicator: $indicator
+
+EOF
+}
+
+sub dispnp
+{
+ my ($pnpdata) = substr($data, $pnp, 0x20);
+ my ($dummy1, $pnprev, $pnplen, $nextpnp, $dummy2,
+ $pnpcsum, $deviceid, $mfrid, $productid,
+ $class1, $class2, $class3, $indicator,
+ $bcv, $dv, $bev, $dummy, $sri) = unpack('a4C2vC2a4v2C4v5', $pnpdata);
+ print <<EOF;
+PnP structure:
+
+EOF
+ print 'Vendor: ', &getid($mfrid), "\n";
+ print 'Device: ', &getid($productid), "\n";
+ my $indicatorstr = sprintf('%#02x', $indicator);
+ my $bcvstr = sprintf('%#04x', $bcv);
+ my $dvstr = sprintf('%#04x', $dv);
+ my $bevstr = sprintf('%#04x', $bev);
+ my $sristr = sprintf('%#04x', $sri);
+ my $checksum = unpack('%8C*', $pnpdata);
+ print <<EOF;
+Device base type: $class1
+Device sub type: $class2
+Device interface type: $class3
+Device indicator: $indicatorstr
+Boot connection vector: $bcvstr
+Disconnect vector: $dvstr
+Bootstrap entry vector: $bevstr
+Static resource information vector: $sristr
+Checksum: $checksum
+
+EOF
+}
+
+sub pcipnp
+{
+ ($pci, $pnp) = unpack('v2', substr($data, 0x18, 4));
+ if ($pci >= $len or $pnp >= $len) {
+ print "$file: Not a PCI PnP ROM image\n";
+ return;
+ }
+ if (substr($data, $pci, 4) ne 'PCIR' or substr($data, $pnp, 4) ne '$PnP') {
+ print "$file: No PCI and PNP structures, not a PCI PNP ROM image\n";
+ return;
+ }
+ &dispci();
+ &dispnp();
+}
+
+$file = $#ARGV >= 0 ? $ARGV[0] : '-';
+open(F, "$file") or die "$file: $!\n";
+binmode(F);
+# Handle up to 64kB ROM images
+$len = read(F, $data, 64*1024);
+close(F);
+defined($len) or die "$file: $!\n";
+substr($data, 0, 2) eq "\x55\xAA" or die "$file: Not a boot ROM image\n";
+my ($codelen) = unpack('C', substr($data, 2, 1));
+$codelen *= 512;
+if ($codelen < $len) {
+ my $pad = $len - $codelen;
+ print "Image is $codelen bytes and has $pad bytes of padding following\n";
+ $data = substr($data, 0, $codelen);
+} elsif ($codelen > $len) {
+ print "Image should be $codelen bytes but is truncated to $len bytes\n";}
+&pcipnp();
+($csum) = unpack('%8C*', $data);
+print "ROM checksum: $csum \n";
+exit(0);