#!/usr/bin/env perl # Author: Chris Ball # # This script helps to track down problems caused by incorrectly-set # registers. It takes two logfiles containing output of "avivotool # regs all", and we presume that one logfile corresponds to a "working" # setup -- either obtained by using another driver or from a time when # the problem being investigated wasn't happening -- and one corresponds # to the current "broken" state of the card. We compare the logfiles, # and for each line where we are not in compliance with the register # value from the "working" log, we ask the user whether we should # regset that register to its state from the working log. If "-y" # is passed, we regset without asking. In short, it looks like this: # % sudo perl apply-regs-diff.pl workinglog brokenlog # ... # 0000657c was 0ae01d20, is now 13600da0. Write 0ae01d20 [y/n]? # 00006590 was 00000000, is now 00000001. Write 00000000 [y/n]? y # OLD: 0x00006590 (6590) 0x00000001 (1) # NEW: 0x00006590 (6590) 0x00000000 (0) # 00006594 was 00000000, is now 00000101. Write 00000000 [y/n]? y # OLD: 0x00006594 (6594) 0x00000101 (257) # NEW: 0x00006594 (6594) 0x00000000 (0) # 0000659c was 00000002, is now 00000000. Write 00000002 [y/n]? # ... # use strict; use warnings; use Getopt::Std; my %options; getopts('y', \%options); my $yes = 0; $yes = 1 if exists($options{"y"}); # We should have two filename arguments left. die "Usage: $0 [-y] workinglog brokenlog" if (@ARGV != 2); open my $fh, "<", $ARGV[0] or die "Opening $ARGV[0] failed: $!"; my @oldregs = <$fh>; open my $fh2, "<", $ARGV[1] or die "Opening $ARGV[1] failed: $!"; my @newregs = <$fh2>; # If the two register logs have a different number of lines, # we got a different register count. This shouldn't happen. if (@oldregs != @newregs) { die "Different number of registers dumped"; } # Now we can start the comparisons. for (my $i=0; $i<=$#newregs; $i++) { chomp $oldregs[$i]; chomp $newregs[$i]; my ($oldreg, $oldval) = split /\t/, $oldregs[$i]; $oldval =~ m/(.*?) \((.*?)\)/ or die "Regex failed at $i"; my ($oldhex, $olddec) = ($1, $2); my ($newreg, $newval) = split /\t/, $newregs[$i]; $newval =~ m/(.*?) \((.*?)\)/ or die "Regex failed at $i"; my ($newhex, $newdec) = ($1, $2); # print "oldreg is $oldreg and newreg is $newreg\n"; # print "oldval is $oldhex, $olddec and newval is $newhex, $newdec\n"; if ($oldreg ne $newreg) { die "Register order at $i does not match"; } if ($oldval ne $newval) { print "$oldreg was $oldhex, is now $newhex. Write $oldhex [y/n]? "; my $answer; if ($yes == 0) { $answer = ; chomp $answer; } if ($answer eq "y" or $yes == 1) { my $command = "./avivotool regset 0x" . $oldreg . " 0x". $oldhex; # print "command is $command\n"; print `$command 2>&1`; if ($? == -1) { die "Couldn't spawn $command: $!"; } elsif ($? >> 8 != 0) { die "$command returned exit code " . ($? >> 8); } sleep 1; } } }