# ========== Copyright Header Begin ==========================================
# OpenSPARC T2 Processor File: Test.pm
# Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
# 4150 Network Circle, Santa Clara, California 95054, U.S.A.
# * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# For the avoidance of doubt, and except that if any non-GPL license
# choice is available it will apply instead, Sun elects to use only
# the General Public License version 2 (GPLv2) at this time for any
# software where a choice of GPL license versions is made
# available with the language indicating that GPLv2 or any later version
# may be used, or where a choice of which version of the GPL is applied is
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# ========== Copyright Header End ============================================
# IMPORTANT: Do not 'use Midas::Test' from anywhere within midas. The
# Test::More module will monkey with midas' exit status, so it won't
# function properly. Test scripts should: use Midas; use Midas::Test;
use TRELoad
'BitFieldTie';
use Midas
::MMU
::TTEFormat
;
our @Test_functions = qw(
check_full_section check_tsb
addr_to_entry new_ttehash
compact_section parse_mem_image
verbose_args dir_args parse_symtab
our @EXPORT = (@Test_functions, '@Test_functions');
###############################################################################
package Midas
::Test
::Memimage
;
use fields
qw( file sections );
my $this = fields
::new
($class);
$this->{file
} = $file if defined $file;
print "MEMIMAGE \"$this->{file}\"\n";
foreach my $sec (sort keys %{$this->{sections
}}) {
print $this->{sections
}{$sec}->tostring();
foreach my $sec (keys %{$this->{sections
}}) {
my $size = $this->{sections
}{$sec}->size();
$num++ if $this->{sections
}{$sec}->nonzero_size() > 0;
foreach my $sec (keys %{$this->{sections
}}) {
my $size = $this->{sections
}{$sec}->size();
$num++ if $this->{sections
}{$sec}->size() > 0;
return $this->{sections
}{$pa} if exists $this->{sections
}{$pa};
my $just_beginning = shift;
my $sec = $this->get_sec_from_pa($pa);
ok
(defined($sec), "Section exists at pa=$pa.");
$sec->check_full_sec($elems, $just_beginning) if defined $sec;
my $sec = $this->get_sec_from_pa($pa);
ok
(defined($sec), "TSB '$tsbname' exists at pa=$pa.");
$sec->check_tsb($entries, $mmutype) if defined $sec;
###############################################################################
package Midas
::Test
::MemimageSection
;
use fields
qw(pa name subsecs);
my $this = fields
::new
($class);
$this->{pa
} = $pa if defined $pa;
foreach my $subsec (keys %{$this->{subsecs
}}) {
$size += $this->{subsecs
}{$subsec}->size();
foreach my $subsec (keys %{$this->{subsecs
}}) {
$size += $this->{subsecs
}{$subsec}->nonzero_size();
$this->{subsecs
}{$subsec->{pa
}} = $subsec;
if($subsec->is_sec_start()) {
$this->{pa
} = $subsec->{pa
};
$this->{name
} = $subsec->{comments
};
$subsec->{secname
} = $this->{name
};
foreach my $subsec (sort keys %{$this->{subsecs
}}) {
if($index >= $this->{subsecs
}{$subsec}{offset_i
} and
$index < ($this->{subsecs
}{$subsec}{offset_i
}+
$this->{subsecs
}{$subsec}->size()))
my $subindex = $index - $this->{subsecs
}{$subsec}{offset_i
};
return $this->{subsecs
}{$subsec}{data
}[$subindex];
my $str = "SECTION \@$this->{pa} $this->{name}\n";
foreach my $subsec (sort keys %{$this->{subsecs
}}) {
$str .= " " . $this->{subsecs
}{$subsec}->tostring();
my $just_beginning = shift;
$just_beginning = 0 unless defined $just_beginning;
my @subsecs = values %{$this->{subsecs
}};
is
(@subsecs, 1, "Section '$this->{name}' has no subsections.");
$subsecs[0]->check_full_subsec($elems, $just_beginning);
my $name = $this->{name
};
my $num_entries = int($this->nonzero_size() / 2);
my $expected_num_entries = @
$entries;
is
($num_entries, $expected_num_entries,
"Check TSB '$name' has '$expected_num_entries' entries.");
foreach my $entry (@
$entries) {
my $tag_index = $entry->{entry
} * 2;
my $data_index = $tag_index + 1;
my $tag = Midas
::Test
::va2tsbtag
($entry->{va
}, $entry->{ttehash
},
my $data = Midas
::Test
::ra2tsbdata
($entry->{ra
}, $entry->{ttehash
},
ok
(defined $this->get_index($tag_index),
"Check there is a tag for entry $entry->{entry}.");
is
($this->get_index($tag_index), $tag,
"Check the value of tag for entry $entry->{entry} is '$tag'.");
ok
(defined $this->get_index($data_index),
"Check there is a data for entry $entry->{entry}.");
is
($this->get_index($data_index), $data,
"Check the value of data for entry $entry->{entry} is '$data'.");
###############################################################################
package Midas
::Test
::MemimageSubsec
;
use fields
qw(pa comments sec secpa data offset_b offset_i secname);
my $this = fields
::new
($class);
$this->{pa
} = $pa if defined $pa;
$this->{comments
} = $comments if defined $comments;
return scalar @
{$this->{data
}};
foreach my $d (@
{$this->{data
}}) {
$nz++ if $d =~ /[1-9a-fA-F]/;
push @
{$this->{data
}}, @
$data;
my $size = $this->size();
my $str = "SUBSEC \@$this->{pa}: $size elements, offset=$this->{offset_b} bytes, $this->{offset_i} index\n";
return 1 if $this->{secpa
} eq $this->{pa
};
my $pa_bf = BitFieldTie
->new(64, $this->{pa
});
my $sec_pa_bf = BitFieldTie
->new(64, $this->{secpa
});
$pa_bf->subtract($sec_pa_bf);
$this->{offset_b
} = $pa_bf->extract(31, 0);
$this->{offset_i
} = ($pa_bf->extract(31, 0) >> 3);
return unless defined $this->{comments
};
if($this->{comments
} =~ /Section\s/ or $this->{comments
} =~ /TSB\s/ or
$this->{comments
} =~ /TSB_LINK\s/) {
$this->{secpa
} = $this->{pa
};
} elsif($this->{comments
} =~ /from compressed 0x([\da-f]+)/) {
$this->calculate_offsets();
my $just_beginning = shift;
$just_beginning = 0 unless defined $just_beginning;
if(not $just_beginning) {
is
($this->size(), $elemsize,
"sec $this->{secname} has $elemsize elements.");
foreach my $elem (@
$elems) {
is
($this->{data
}[$i], $elem,
"Sec $this->{secname}, check element $i.");
###############################################################################
package Midas
::Test
::Symtab
;
my $this = fields
::new
($class);
$this->{entries
}{$entry->{name
}} = $entry;
foreach my $elem (@
$list) {
my ($name, $va, $ra, $pa) = @
$elem;
ok
(exists $this->{entries
}{$name},
"symbol table entry exists for '$name'");
if(exists $this->{entries
}{$name}) {
$this->{entries
}{$name}->check($va, $ra, $pa);
###############################################################################
package Midas
::Test
::SymtabEntry
;
use fields
qw(name va ra pa);
my $this = fields
::new
($class);
$this->{name
} = $name if defined $name;
$this->{va
} = $va if defined $va;
$this->{ra
} = $ra if defined $ra;
$this->{pa
} = $pa if defined $pa;
is
($this->{va
}, $va, "Check VA in symtab for '$this->{name}' is $va");
is
($this->{ra
}, $ra, "Check RA in symtab for '$this->{name}' is $ra");
ok
(! defined $this->{ra
},
"Check RA in symtab for '$this->{name}' is undefined");
is
($this->{pa
}, $pa, "Check PA in symtab for '$this->{name}' is $pa");
###############################################################################
my $fh = IO
::File
->new("<$file");
my $symtab = Midas
::Test
::Symtab
->new();
ok
(defined $fh, "Open symbol.tbl");
return $symtab unless defined $fh;
if(/^(\S+)\s+(\S+)\s+(\S+)(\s+(\S+))/) {
my $entry = Midas
::Test
::SymtabEntry
->new($name, $va, $ra, $pa);
$symtab->add_entry($entry);
###############################################################################
my $fh = IO
::File
->new("<$file");
ok
(defined $fh, "Open mem.image");
return unless defined $fh;
if(/^\s*\@(0[xX])?([\da-fA-F]+)\s*(\/\
/\s*(.*))?/) {
$subsec = Midas
::Test
::MemimageSubsec
->new($pa, $comment);
$subsec->parse_comments();
die "No current subsec!\n" unless defined $subsec;
$subsec->add_data(\
@nums);
my $memimage = Midas
::Test
::Memimage
->new($file);
foreach my $ss (@subsecs) {
if($ss->is_sec_start()) {
my $section = Midas
::Test
::MemimageSection
->new();
$sections{$ss->{secpa
}} = $section;
die "No section for subsection $ss->{pa}\n"
unless exists $sections{$ss->{secpa
}};
$sections{$ss->{secpa
}}->add_subsec($ss);
$memimage->{sections
} = \
%sections;
# $memimage->debug_print();
###############################################################################
$tsbsize = 0 unless defined $tsbsize;
tie
my %va, 'BitFieldTie', 64, $va;
my $hi = 21 + $tsbsize + 3*$pagesize;
my $lo = 13 + 3*$pagesize;
my $entry = $va{"$hi:$lo"};
###############################################################################
# union of all tte attributes for all mmus
tsbtagformat
=> 'tagaccess',
###############################################################################
return $va if $ttehash->{is_link
};
my $format = defined $ttehash->{tsbtagfmt
} ?
$ttehash->{tsbtagfmt
} : 'tagaccess';
my $tag = tte_hash_to_tsb_tag
($mmutype, $format, $ttehash,
$tag = 'XXXXXXXXXXXXXXXX' unless defined $tag;
###############################################################################
return $ra if $ttehash->{is_link
};
$mmutype = 'niagara' unless defined $mmutype;
my $data = tte_hash_to_tsb_data
($mmutype, $ttehash->{tte_fmt
},
$data = 'XXXXXXXXXXXXXXXX' unless defined $data;
###############################################################################
$tofile = 0 unless defined $tofile;
return qw(-v 2 -print_errors);
return qw(-v 0 -noprint_errors);
return qw(-v 2 -print_errors);
###############################################################################
return ('-build_dir', $resultdir, '-dest_dir', $resultdir, '-nocleanup');
###############################################################################