run_tests.pl 5.46 KB
#!/usr/bin/perl
#

# run script from directory bbboot/test

use Getopt::Std;

# this constant must match the output physical address
# used by the boot code TRACE macro
$trace_addr = "0x046e0000";

getopts("t:d:sh");
if ($opt_h == 1){
    print "usage:\n    ";
    print "run_tests.pl -t <test_input_file> -d <test_output_dir> [-h -s]\n";
    print "where if -s is present, the make in directory bbboot \n";
    print "is skipped. Option -h prints this message.\n";
    exit(0);
}
if ($opt_t eq ""){
    print "test input file arg required (use -h for usage)\n";
    exit(1);
}
if ($opt_d eq ""){
    print "test output dir arg required (use -h for usage)\n";
    exit(1);
}
$test_out_subdir = $opt_d;
$test_in_file = $opt_t;

$test_dir = `pwd`;
chop($test_dir);

$sim_dir = "../../../../../hw/chip/vsim";
$sim_dir_data = "$sim_dir/tests";
$sim_brom_fname = "$sim_dir_data/brom.dat";
$sim_nand_fname = "$sim_dir/External_File.txt";
$sim_vram_fname = "$sim_dir_data/v2.dat";
$sim_mdio_fname = "$sim_dir_data/mdio.dat";

$local_rom_fname = "../rom.sim";

# directory where input test data is stored (mdio.dat type files)
$test_data_subdir = "testdata";

# filenames for generated test params and log
$nand_base_fname = "psk.nand";
$vram_base_fname = "vram2.sim";
$log_base_fname = "test.log";

# base command to run cpu simulator
$run_cpu = "sim.cpu +vcs+lic+wait +cbus_mon +cpu_mon";

# if test output directory does not exist, create
if (!(-d "$test_out_subdir")) {
    print "creating test output directory $test_out_subdir\n";
    mkdir("$test_out_subdir") || 
	die "Failed to create directory $test_out_subdir\n";
}

# rebuild boot code and psk_tool
if ($opt_s != 1) {
    chdir("../");
    system("make clean > $test_dir/$test_out_subdir/$log_base_fname 2>&1")
	&& die "FATAL ERROR: make failed in bbboot directory.\n";
    system("make >> $test_dir/$test_out_subdir/$log_base_fname 2>&1")
	&& die "FATAL ERROR: make failed in bbboot directory.\n";
    chdir("psk");
    system("make clean >> $test_dir/$test_out_subdir/$log_base_fname 2>&1")
	&& die "FATAL ERROR: make failed in psk directory.\n";
    system("make >> $test_dir/$test_out_subdir/$log_base_fname 2>&1")
	&& die "FATAL ERROR: make failed in psk directory.\n";
    chdir("$test_dir");
}


$count = 0;

# parse and run tests in input test description file
$parsing_test = 0;
open(testfile, "$test_in_file") || die "Cannot open test file.\n";
while ($line = <testfile>) {
    if ($line =~ /^\#/) {
	#print $line;
    }
    elsif ($line =~ /test name/) {
	%test_input = (); # initialize to nulls
	do process_param($test_input{'name'}, $line);

	# set output filenames
	$nand_fname = "$nand_base_fname$count";
	$vram_fname = "$vram_base_fname$count";
	$log_fname = "$log_base_fname$count";

	print "Processing test: $test_input{'name'} \n";
	print "  log file: $log_fname\n";
    }
    elsif ($line =~ /psk params/) {
	do process_param($test_input{'psk'}, $line);
    }
    elsif ($line =~ /simulator start params/) {
	do process_param($test_input{'sim'}, $line);
    }
    elsif ($line =~ /module state file/) {
	do process_param($test_input{'mod'}, $line);
    }
    elsif ($line =~ /external check/) {
	do process_param($test_input{'ext'}, $line);	
    }
    elsif ($line =~ /expected result/) {
	do process_param($test_input{'expect'}, $line);

	# run the test

	chdir("../psk");
	system("./psk_tool -f $test_dir/$test_out_subdir/$nand_fname -v "
	       . "$test_dir/$test_out_subdir/$vram_fname "
	       . "$test_input{'psk'} psk.sim > " 
	       . "$test_dir/$test_out_subdir/$log_fname")
		&& die "FATAL ERROR: psk_tool failed to complete.\n";
	chdir("$test_dir");
	system("cp -f $local_rom_fname $sim_brom_fname");
	system("cp -f $test_out_subdir/$nand_fname $sim_nand_fname");
	system("cp -f $test_out_subdir/$vram_fname $sim_vram_fname");
	system("cp -f $test_data_subdir/$test_input{'mod'} "
	       . "$sim_mdio_fname");
	chdir("$sim_dir");
	system("$run_cpu $test_input{'sim'} >> "
	       . "$test_dir/$test_out_subdir/$log_fname 2>&1");
	chdir("$test_dir");
	$result = do log_parse("$test_out_subdir/$log_fname","$trace_addr");

	if ($test_input{'ext'} ne "") {
	    $ext_result = system("$test_input{'ext'} " .
				 "$test_out_subdir/$log_fname $trace_addr");
	    $ext_result /= 256;
	    print "external log parsing: returned $ext_result\n";
	}

	if (($result eq $test_input{'expect'}) && 
	    ( ($ext_result == 0) || ($test_input{'ext'} eq "")) ) {
	    print "$test_input{'name'} ($result): PASS \n";
	}
	else {
	    print "regular log parsing: returned $result, "
		. "expected $test_input{'expect'}\n";
	    print "$test_input{'name'}: FAIL\n";
	}

	$count = $count + 1;
    }
}
close(testfile);


# args:
#  $_[0] = output param
#  $_[1] = input line
sub process_param {
    ($junk, $_[0]) = split(/:/, $_[1]);
    while ($_[0] =~ /^ /) {
	$_[0] =~ s/^ //;
    }
    if ($_[0] =~ /\n/) {
	chop($_[0]);
    }
}


# args:
#  $_[0] = log filename to parse
#  $_[1] = address TRACE macro writes to
# return:
#  string holding status of test
sub log_parse {
    local $checkline = 0;
    local $retval;
    local $line;

    $retval = "unknown";

    open(logfile, "$_[0]") || die "Cannot open log file.\n";
    while ($line = <logfile>) {
	if ($line =~ /$_[1]/) {
	    $checkline = 1;
	}
	elsif ($checkline == 1){
	    if ($line =~ /0xbaad0000/){
		$retval = "fatal";
		last;
	    }
	    elsif ($line =~ /0xec010000/){
		$retval = "exception";
		last;
	    }
	    elsif ($line =~ /0xaaaa0000/){
		$retval = "success";
	    }
	    $checkline = 0;
	}
    }
    close(logfile);

    return $retval;
}