package Midas
::MMU
::TTEFormat
;
use TRELoad
'BitFieldTie';
# BEGIN block, because these need to be defined when other modules
# call get_union_tte_field hash inside a 'use fields' clause.
CONTEXT
=> { hi
=>60, lo
=>48 },
VA
=> { hi
=>41, lo
=> 0, src
=>'63:22' },
VA
=> { hi
=>63, lo
=>13, src
=>'63:13' },
CONTEXT
=> { hi
=>12, lo
=> 0 },
CONTEXT
=> { hi
=>60, lo
=>48 },
VA
=> { hi
=>41, lo
=> 0, src
=>'63:22' },
VA
=> { hi
=>63, lo
=>13, src
=>'63:13' },
CONTEXT
=> { hi
=>12, lo
=> 0 },
CONTEXT
=> { hi
=>60, lo
=>48 },
VA
=> { hi
=>41, lo
=> 0, src
=>'63:22' },
VA
=> { hi
=>63, lo
=>13, src
=>'63:13' },
CONTEXT
=> { hi
=>12, lo
=> 0 },
CONTEXT
=> { hi
=>60, lo
=>48 },
VA
=> { hi
=>41, lo
=> 0, src
=>'63:22' },
VA
=> { hi
=>63, lo
=>13, src
=>'63:13' },
CONTEXT
=> { hi
=>12, lo
=> 0 },
tie
my %tsb_data_ultra2_sun4u, 'Tie::IxHash';
tie
my %tsb_data_niagara_sun4u, 'Tie::IxHash';
tie
my %tsb_data_niagara_sun4v, 'Tie::IxHash';
tie
my %tsb_data_niagara2_sun4u, 'Tie::IxHash';
tie
my %tsb_data_niagara2_sun4v, 'Tie::IxHash';
tie
my %tsb_data_rock_sun4v, 'Tie::IxHash';
V
=> { hi
=>63, lo
=>63, default => 1, descr
=> "Valid bit, default=1" },
SIZE
=> { hi
=>62, lo
=>61, descr
=> "Encoded page size"},
NFO
=> { hi
=>60, lo
=>60, descr
=> "Non-Faulting Only" },
IE
=> { hi
=>59, lo
=>59, descr
=> "Invert Endianness" },
SOFT2
=> { hi
=>58, lo
=>50, descr
=> "Software usable"},
DIAG
=> { hi
=>49, lo
=>41, descr
=> "Diagnostic"},
PA
=> { hi
=>40, lo
=>13, src
=>'40:13', descr
=> "Physical Address"},
SOFT
=> { hi
=>12, lo
=> 7, descr
=> "Software usable" },
L
=> { hi
=> 6, lo
=> 6, descr
=> "Lock"},
descr
=> "Cacheable in phys. indexed cache"},
descr
=> "Cacheable in virt. indexed cache"},
E
=> { hi
=> 3, lo
=> 3, descr
=> "Side-effect"},
P
=> { hi
=> 2, lo
=> 2, descr
=> "Priviliged"},
W
=> { hi
=> 1, lo
=> 1, descr
=> "Writeable"},
G
=> { hi
=> 0, lo
=> 0, descr
=> "Global" },
%tsb_data_niagara_sun4u =
V
=> { hi
=>63, lo
=>63, default => 1, descr
=> "Valid bit, default=1"},
SZL
=> { hi
=>62, lo
=>61, name
=>'SIZE', src
=>'1:0',
descr
=> "Low bits of encoded page size" },
NFO
=> { hi
=>60, lo
=>60, descr
=> "Non-Faulting Only"},
IE
=> { hi
=>59, lo
=>59, descr
=> "Invert Endianness"},
SOFT2
=> { hi
=>58, lo
=>49, descr
=> "Software usable"},
SZH
=> { hi
=>48, lo
=>48, name
=>'SIZE', src
=>'2',
descr
=> "High bit of encoded page size" },
DIAG
=> { hi
=>47, lo
=>40, descr
=> "Diagnostic"},
PA
=> { hi
=>39, lo
=>13, src
=>'39:13', descr
=> "Physical Address"},
SOFT
=> { hi
=>12, lo
=> 8, descr
=> "Software usable"},
RSVD0
=> { hi
=> 7, lo
=> 7, descr
=> "Reserved"},
L
=> { hi
=> 6, lo
=> 6, descr
=> "Lock" },
descr
=> "Cacheable in phys. indexed cache"},
descr
=> "Cacheable in virt. indexed cache"},
E
=> { hi
=> 3, lo
=> 3, descr
=> "Side-effect"},
P
=> { hi
=> 2, lo
=> 2, descr
=> "Priviliged" },
W
=> { hi
=> 1, lo
=> 1, descr
=> "Writeable" },
RSVD1
=> { hi
=> 0, lo
=> 0, aliases
=>['G'], descr
=> "Reserved" },
%tsb_data_niagara_sun4v =
V
=> { hi
=>63, lo
=>63, default => 1, descr
=> "Valid bit, default=1"},
NFO
=> { hi
=>62, lo
=>62, descr
=> "Non-Faulting Only" },
L
=> { hi
=>61, lo
=>61, descr
=> "Lock" },
SOFT
=> { hi
=>60, lo
=>40, descr
=> "Software usable"},
PA
=> { hi
=>39, lo
=>13, src
=>'39:13', descr
=> "Physical Address"},
IE
=> { hi
=>12, lo
=>12, descr
=> "Invert Endianness"},
E
=> { hi
=>11, lo
=>11, descr
=> "Side-effect"},
descr
=> "Cacheable in phys. indexed cache"},
descr
=> "Cacheable in virt. indexed cache"},
P
=> { hi
=> 8, lo
=> 8, descr
=> "Priviliged" },
RSVD0
=> { hi
=> 7, lo
=> 7, descr
=> "Reserved" },
W
=> { hi
=> 6, lo
=> 6, descr
=> "Writeable" },
SW1
=> { hi
=> 5, lo
=> 5, descr
=> "Software usable" },
SW0
=> { hi
=> 4, lo
=> 4, descr
=> "Software usable" },
RSVD1
=> { hi
=> 3, lo
=> 3, descr
=> "Reserved" },
SIZE
=> { hi
=> 2, lo
=> 0, descr
=> "Encoded page size" },
%tsb_data_niagara2_sun4u =
V
=> { hi
=>63, lo
=>63, default => 1, descr
=> "Valid bit, default=1"},
SZL
=> { hi
=>62, lo
=>61, name
=>'SIZE', src
=>'1:0',
descr
=> "Low bits of encoded page size" },
NFO
=> { hi
=>60, lo
=>60, descr
=> "Non-Faulting Only"},
IE
=> { hi
=>59, lo
=>59, descr
=> "Invert Endianness"},
SOFT2
=> { hi
=>58, lo
=>49, descr
=> "Software usable"},
SZH
=> { hi
=>48, lo
=>48, name
=>'SIZE', src
=>'2',
descr
=> "High bit of encoded page size" },
DIAG
=> { hi
=>47, lo
=>40, descr
=> "Diagnostic" },
PA
=> { hi
=>39, lo
=>13, src
=>'39:13', descr
=> "Physical Address"},
SOFT
=> { hi
=>12, lo
=> 8, descr
=> "Software usable"},
EP
=> { hi
=> 7, lo
=> 7, aliases
=>['X'],
descr
=> "Executable (also TTE_X)"},
L
=> { hi
=> 6, lo
=> 6, descr
=> "Lock" },
descr
=> "Cacheable in phys. indexed cache"},
descr
=> "Cacheable in virt. indexed cache"},
E
=> { hi
=> 3, lo
=> 3, descr
=> "Side-effect"},
P
=> { hi
=> 2, lo
=> 2, descr
=> "Priviliged" },
W
=> { hi
=> 1, lo
=> 1, descr
=> "Writeable" },
RSVD1
=> { hi
=> 0, lo
=> 0, aliases
=>['G'], descr
=> "Reserved" },
%tsb_data_niagara2_sun4v =
V
=> { hi
=>63, lo
=>63, default => 1, descr
=> "Valid bit, default=1"},
NFO
=> { hi
=>62, lo
=>62, descr
=> "Non-Faulting Only" },
L
=> { hi
=>61, lo
=>61, descr
=> "Lock"},
SOFT
=> { hi
=>60, lo
=>40, descr
=> "Software usable"},
PA
=> { hi
=>39, lo
=>13, src
=>'39:13', descr
=> "Physical Address"},
IE
=> { hi
=>12, lo
=>12, descr
=> "Invert Endianness"},
E
=> { hi
=>11, lo
=>11, descr
=> "Side-effect"},
descr
=> "Cacheable in phys. indexed cache"},
descr
=> "Cacheable in virt. indexed cache"},
P
=> { hi
=> 8, lo
=> 8, descr
=> "Priviliged"},
EP
=> { hi
=> 7, lo
=> 7, aliases
=>['X'],
descr
=> "Executable (also TTE_X)"},
W
=> { hi
=> 6, lo
=> 6, descr
=> "Writeable" },
SW1
=> { hi
=> 5, lo
=> 5, descr
=> "Software usable"},
SW0
=> { hi
=> 4, lo
=> 4, descr
=> "Software usable"},
RSVD1
=> { hi
=> 3, lo
=> 3, descr
=> "Reserved" },
SIZE
=> { hi
=> 2, lo
=> 0, descr
=> "Encoded page size"},
V
=> { hi
=>63, lo
=>63, default => 1, descr
=> "Valid bit, default=1"},
NFO
=> { hi
=>62, lo
=>62, descr
=> "Non-Faulting Only" },
SW1
=> { hi
=>61, lo
=>47, descr
=> "Software usable"},
PA
=> { hi
=>46, lo
=>13, src
=>'46:13', descr
=> "Physical Address"},
IE
=> { hi
=>12, lo
=>12, descr
=> "Invert Endianness" },
E
=> { hi
=>11, lo
=>11, descr
=> "Side-effect"},
descr
=> "Cacheable in phys. indexed cache"},
descr
=> "Cacheable in virt. indexed cache"},
P
=> { hi
=> 8, lo
=> 8, descr
=> "Priviliged" },
X
=> { hi
=> 7, lo
=> 7, aliases
=>['EP'],
descr
=> "Executable (also TTE_EP)" },
W
=> { hi
=> 6, lo
=> 6, descr
=> "Writeable" },
R
=> { hi
=> 5, lo
=> 5, descr
=> "Readable" },
SW0
=> { hi
=> 4, lo
=> 4, descr
=> "Software usable"},
RSVD0
=> { hi
=> 3, lo
=> 3, descr
=> "Reserved"},
SIZE
=> { hi
=> 2, lo
=> 0, descr
=> "Encoded page size" },
sun4u
=> \
%tsb_data_ultra2_sun4u,
sun4u
=> \
%tsb_data_niagara_sun4u,
sun4v
=> \
%tsb_data_niagara_sun4v,
sun4u
=> \
%tsb_data_niagara2_sun4u,
sun4v
=> \
%tsb_data_niagara2_sun4v,
sun4v
=> \
%tsb_data_rock_sun4v,
##############################################################################
foreach my $field (keys %{$TSB_DATA_FORMAT{$mmu_type}{$ttefmt}}) {
my $descr = $TSB_DATA_FORMAT{$mmu_type}{$ttefmt}{$field};
my $size = $descr->{hi
} - $descr->{lo
} + 1;
my $name = (exists $descr->{name
}) ?
$descr->{name
} : $field;
push @names, @
{ $descr->{aliases
} } if exists $descr->{aliases
};
my $tte_n = lc('tte_' . $n);
$fields{$tte_n} = 0 unless exists $fields{$tte_n};
$fields{$tte_n} += $size;
foreach my $field (keys %{$TSB_TAG_FORMAT{$mmu_type}{$tsbtagfmt}}) {
my $descr = $TSB_TAG_FORMAT{$mmu_type}{$tsbtagfmt}{$field};
my $size = $descr->{hi
} - $descr->{lo
} + 1;
my $name = (exists $descr->{name
}) ?
$descr->{name
} : $field;
push @names, @
{ $descr->{aliases
} } if exists $descr->{aliases
};
my $tte_n = lc('tte_' . $n);
$fields{$tte_n} = 0 unless exists $fields{$tte_n};
$fields{$tte_n} += $size;
delete $fields{tte_va
} if exists $fields{tte_va
};
delete $fields{tte_ra
} if exists $fields{tte_ra
};
delete $fields{tte_pa
} if exists $fields{tte_pa
};
##############################################################################
sub get_union_tte_field_hash
{
foreach my $ttefmt (keys %{ $TSB_DATA_FORMAT{$mmu_type} }) {
foreach my $tsbtagfmt (keys %{ $TSB_TAG_FORMAT{$mmu_type} } ) {
my $fieldHash = get_tte_field_hash
($mmu_type, $ttefmt, $tsbtagfmt);
foreach my $field (keys %$fieldHash) {
$fields{$field} = 0 unless defined $fields{$field};
$fields{$field} = ($fields{$field} > $fieldHash->{$field}) ?
$fields{$field} : $fieldHash->{$field};
##############################################################################
sub tte_hash_to_tsb_data
{
$addr = '0' unless defined $addr;
my $pa = BitFieldTie
->new(64, $addr);
my $data = BitFieldTie
->new(64, 0);
my $size = (exists $ttehash->{tte_size
}) ?
BitFieldTie
->new(64, $ttehash->{tte_size
}) : undef;
tie
my %data, 'BitFieldTie', $data;
tie
my %pa, 'BitFieldTie', $pa;
tie
my %size, 'BitFieldTie', $size;
foreach my $field (keys %{ $TSB_DATA_FORMAT{$mmutype}{$ttefmt} }) {
my $descr = $TSB_DATA_FORMAT{$mmutype}{$ttefmt}{$field};
my $name = (exists $descr->{name
}) ?
$descr->{name
} : $field;
push @names, @
{ $descr->{aliases
} } if exists $descr->{aliases
};
my $def_value = (defined $descr->{default}) ?
$descr->{default} : 0;
if($name eq 'PA' or $name eq 'SIZE') {
my $bits = (exists $descr->{src
}) ?
$descr->{src
} : '31:0';
if($bits =~ /^(\d+):(\d+)$/) {
my ($hi, $lo) = ($1, $2);
my $dist = $hi - $lo + 1;
my $descr_mid_hi = $descr->{hi
} - 31;
my $descr_mid_lo = $descr_mid_hi - 1;
$data{"$descr->{hi}:$descr_mid_hi"} =
$data{"${descr_mid_lo}:$descr->{lo}"} =
} elsif($name eq 'SIZE') {
my $tte_n = lc('tte_' . $n);
if(exists $ttehash->{$tte_n}) {
$value ||= $ttehash->{$tte_n};
$value = $def_value unless $found;
$data{"$descr->{hi}" . ':' . "$descr->{lo}"} = $value
return $data->stringify();
##############################################################################
sub tte_hash_to_tsb_tag
{
my $force_ctx_zero = shift;
$addr = '0' unless defined $addr;
$force_ctx_zero = 0 unless defined $force_ctx_zero;
my $va = BitFieldTie
->new(64, $addr);
my $tag = BitFieldTie
->new(64, 0);
tie
my %tag, 'BitFieldTie', $tag;
tie
my %va, 'BitFieldTie', $va;
foreach my $field (keys %{ $TSB_TAG_FORMAT{$mmutype}{$tsbtagfmt} }) {
my $descr = $TSB_TAG_FORMAT{$mmutype}{$tsbtagfmt}{$field};
my $name = (exists $descr->{name
}) ?
$descr->{name
} : $field;
push @names, @
{ $descr->{aliases
} } if exists $descr->{aliases
};
my $value = (defined $descr->{default}) ?
$descr->{default} : 0;
my $bits = (exists $descr->{src
}) ?
$descr->{src
} : '31:0';
if($bits =~ /(\d+)\:(\d+)/) {
my ($bitsHi, $bitsLo) = ($1, $2);
my $bitsCut = $bitsHi-31;
$tag{"${hi}:${cut}"} = $va{"${bitsHi}:${bitsCut}"};
$tag{"${cut}:${lo}"} = $va{"${bitsCut}:${bitsLo}"};
$tag{"${hi}:${lo}"} = $va{$bits};
my $tte_n = lc('tte_' . $n);
if(exists $ttehash->{$tte_n}) {
$value ||= $ttehash->{$tte_n};
if($tte_n eq 'tte_context' and $force_ctx_zero) {
$tag{"$descr->{hi}" . ':' . "$descr->{lo}"} = $value;
return $tag->stringify();
##############################################################################
tie
my %parsed, 'Tie::IxHash';
my $data = BitFieldTie
->new(64, $tte_data);
tie
my %data, 'BitFieldTie', $data;
my $types = $TSB_DATA_FORMAT{$mmutype}{$ttefmt};
foreach my $field (sort { $types->{$b}{hi
} <=> $types->{$a}{hi
}}
my $descr = $types->{$field};
my $value = $data{"$descr->{hi}" . ':' . "$descr->{lo}"};
my $name = (exists $descr->{name
}) ?
$descr->{name
} : $field;
$parsed{$name} = 0 unless defined $parsed{$name};
if(exists $descr->{src
}) {
my $v = BitFieldTie
->new(64, 0);
tie
my %v, 'BitFieldTie', $v;
$v{$descr->{src
}} = $value;
$value = $v->extract(31,0);
$parsed{$name} |= $value;
##############################################################################
sub is_good_format_for_mmu
{
return 1 if exists $TSB_DATA_FORMAT{$mmutype}{$ttefmt};
##############################################################################