package Midas
::MMU
::SunSectionAttrs
;
use Midas
::MMU
::TTEFormat
;
use TRELoad
'BitFieldTie';
use base
qw(Midas::AttrBlock::MapAttrs);
tsbonly notsb uninitialized
# Hard-code MMU type because 'use fields' directive needs
# to happen at compile-time
keys %{ get_union_tte_field_hash
('ultra2') }
tsbonly notsb uninitialized
our %Settable = map {$_ => 1} Midas
::MMU
::SunSectionAttrs
->settable();
###############################################################################
$this = fields
::new
($this);
$this->{settable
} = \
%Settable;
foreach my $key (keys %args) {
$this->{$key} = $args{$key};
###############################################################################
$this->SUPER::set_defaults
();
$this->{bypass
} = 0 unless defined $this->{bypass
};
$this->{tsbonly
} = 0 unless defined $this->{tsbonly
};
$this->{notsb
} = 0 unless defined $this->{notsb
};
$this->{uninitialized
} = 0 unless defined $this->{uninitialized
};
$this->{tte_size
} = 0 unless defined $this->{tte_size
};
###############################################################################
sub get_field_size_hash
{
my $sizes = $this->SUPER::get_field_size_hash
();
foreach my $field (keys %FieldSizes) {
$sizes->{$field} = $FieldSizes{$field};
###############################################################################
my @messages = $this->SUPER::sanity_check
();
my $name = $this->get_section_name();
my $fline = $this->get_fline();
if($this->{uninitialized
} && $this->{tsbonly
}) {
my $message = "Section '$name' redundantly specifies both tsbonly and ".
"uninitialized.\n at $fline\n";
push @messages, { message
=> $message, code
=> M_ATTRSYNTAX
};
###############################################################################
my @settable = $this->SUPER::settable
();
push @settable, @Settable;
###############################################################################
return 1 if $this->{tsbonly
} || $this->{uninitialized
};
###############################################################################
if (exists $MapAttr_FieldMax{$lcattr}) {
my $width = $MapAttr_FieldWidth{$lcattr};
$this->attr_fatal("Attribute \"$attr\" set to non-numeric value: ".
unless $val =~ /^\s*(0[xX])?[\da-fA-F]+\s*$/;
my $val_bf = string2bf
($val, 64);
$this->attr_fatal("Value \"$val\" is not a ${width}-bit hex number:\n".
my $range_bf = $MapAttr_FieldMax{$lcattr};
if($val_bf->ucompare($range_bf) >= 0) {
$this->attr_fatal("Value \"$val\" is out of range for ".
"${width}-bit field '$attr'.", M_OUTOFRANGE
);
$val = $val_bf->extract($width-1, 0);
$this->SUPER::set_attr
($attr => $val);
###############################################################################
###############################################################################
my $force_ctx_zero = shift;
$this->attr_fatal("Getting tag for unmapped section.\n", M_CODE
)
unless $this->is_mapped();
my $tag = tte_hash_to_tsb_tag
($this->{mmutype
},
$CONFIG{tsbtagfmt
}, $this,
fatal
"Combination of MMU type $this->{mmutype} and TSB tag format ".
"$CONFIG{tsbtagfmt}\n is not legal\n", M_ATTRSYNTAX
unless defined $tag;
###############################################################################
###############################################################################
return unless $this->is_mapped();
return unless exists $this->{pa
} and defined $this->{pa
};
my $pa = string2bf
($this->{pa
}, $PASIZE);
$this->attr_fatal("Cannot interpret PA \"$this->{pa}\":\n$pa\n", M_NOTNUM
);
###############################################################################
return 1 unless $this->{bypass
};
###############################################################################
my $ttefmt = $tsb->get_ttefmt();
$this->attr_fatal("Getting data for unmapped section.\n", M_CODE
)
unless $this->is_mapped();
$this->attr_fatal("Trying to generate TTE data in illegal format ".
"'$ttefmt'\n", M_ATTRSYNTAX
) unless
is_good_format_for_mmu
($this->{mmutype
}, $ttefmt);
my $data = tte_hash_to_tsb_data
($this->{mmutype
},
fatal
"Combination of MMU type $this->{mmutype} and TTE format $ttefmt ".
" is not legal\n", M_ATTRSYNTAX
unless defined $data;
##############################################################################
sub write_goldfinger_mmu_params
{
my $tsblist = $this->get_tsb_list();
print $ofh " no_end_range_check = 1;\n" if $this->{uninitialized
};
print $ofh " PA_EQ_VA;\n" if not $this->is_mapped();
print $ofh " RA_EQ_VA;\n" if $this->{bypass
};
my ($tag_bit_hi, $tag_bit_lo) = $this->get_tag_addr_bits();
my ($tte_tag_bit_hi, $tte_tag_bit_lo) = $this->get_tte_tag_addr_bits();
my ($data_bit_hi, $data_bit_lo) = $this->get_data_addr_bits();
foreach my $tsbname (@
$tsblist) {
my $tsb = $STATE->{tsbs
}{$tsbname};
my $data = $this->get_data($tsb);
if(defined $this->{tte_size_ptr
}) {
$sizeptr = $this->{tte_size_ptr
};
} elsif(defined $tsb->page_size()) {
$sizeptr = $tsb->page_size();
$sizeptr = $this->{tte_size
};
my $pagesize = 8192 * (8 ** $sizeptr);
my $size3 = 3 * $sizeptr;
my $va_ind_hi = 21+$size3;
my $va_ind_lo = 13+$size3;
my $force_ctx_zero = $tsb->is_force_ctx_zero();
my $tag = $this->get_tag($force_ctx_zero);
print $ofh " BLOCK_TSB $tsbname\n";
print $ofh " page_size = $pagesize;\n";
print $ofh " va_index_bits = $va_ind_hi : $va_ind_lo;\n";
print $ofh " tag_addr_bits = $tag_bit_hi : $tag_bit_lo;\n";
print $ofh " tte_tag_addr_bits = $tte_tag_bit_hi : $tte_tag_bit_lo;\n";
print $ofh " data_addr_bits = $data_bit_hi : $data_bit_lo;\n";
print $ofh " tag_base = 0x$tag;\n";
print $ofh " data_base = 0x$data;\n";
print $ofh " END BLOCK_TSB\n";
###############################################################################
if($CONFIG{tsbtagfmt
} eq 'tagtarget') {
##############################################################################
sub get_tte_tag_addr_bits
{
if($CONFIG{tsbtagfmt
} eq 'tagtarget') {
###############################################################################
###############################################################################
package Midas
::MMU
::SunHyperAttrs
;
use base
qw(Midas::MMU::SunSectionAttrs);
use fields
qw(ra hypervisor );
our @Settable = (qw(ra hypervisor));
our %Settable = map { $_ => 1} Midas
::MMU
::SunHyperAttrs
->settable();
############################################################################
$this = fields
::new
($this);
$this->{settable
} = \
%Settable;
foreach my $key (keys %args) {
$this->{$key} = $args{$key};
############################################################################
$this->SUPER::set_defaults
();
$this->{hypervisor
} = 0 unless defined $this->{hypervisor
};
#############################################################################
my @settable = $this->SUPER::settable
();
push @settable, @Settable;
#############################################################################
sub get_field_size_hash
{
my $sizes = $this->SUPER::get_field_size_hash
();
foreach my $field (keys %FieldSizes) {
$sizes->{$field} = $FieldSizes{$field};
############################################################################
return unless $this->is_mapped();
return unless exists $this->{ra
} and defined $this->{ra
};
my $ra = BitFieldTie
->new($RASIZE, $this->{ra
});
$this->attr_fatal("Cannot interpret RA \"$this->{ra}\":\n$ra",
############################################################################
my @messages = $this->SUPER::sanity_check
();
my $name = $this->get_section_name();
my $fline = $this->get_fline();
if($this->{hypervisor
}) {
if(defined $this->{ra
}) {
my $message = "Section '$name' hypervisor block has RA defined\n".
push @messages, { message
=> $message, code
=> M_ATTRSYNTAX
};
if(defined $this->{pa
}) {
my $message = "Section '$name' hypervisor block has PA defined\n".
push @messages, { message
=> $message, code
=> M_ATTRSYNTAX
};
my $message = "Section '$name' hypervisor block has bypass defined\n".
push @messages, { message
=> $message, code
=> M_ATTRSYNTAX
};
my @settable = keys %MapAttr_Settable;
foreach my $settable (@settable) {
if(($settable =~ /^tte/ or $settable =~ /^tsb/ )
and $this->{has_set
}{$settable})
my $message = "Section '$name' hypervisor block sets tte attr ".
push @messages, { message
=> $message, code
=> M_ATTRSYNTAX
};
if(not $CONFIG{allow_illegal_page_sizes
}) {
if(not grep /^$this->{tte_size}$/, $this->legal_page_bits()) {
my $message = "Section '$name' has illegal page size bits ".
"Not allowed unles -allow_illegal_page_sizses is used\n".
push @messages, { message
=> $message, code
=> M_ILLEGALPARAM
};
if(defined $this->{tte_size_ptr
}) {
if(not grep /^$this->{tte_size_ptr}$/, $this->legal_page_bits()) {
my $message = "Section '$name' has illegal page size ptr bits ".
"'$this->{tte_size_ptr}'\n".
"Not allowed unles -allow_illegal_page_sizses is used\n".
push @messages, { message
=> $message, code
=> M_ILLEGALPARAM
};
if(not defined $this->{pa
} and not $this->skip_image()) {
my $message = "Section '$name' non-hv block has no PA defined\n".
push @messages, { message
=> $message, code
=> M_ATTRSYNTAX
};
if(not $this->{bypass
} and not defined $this->{ra
} and
my $message = "Section '$name' is not bypass or hypervisor and\n".
"does not define RA.\n at $fline\n";
push @messages, { message
=> $message, code
=> M_ATTRSYNTAX
};
if($this->{bypass
} and defined $this->{ra
}) {
my $message = "Section '$name' defines both bypass and RA.\n".
push @messages, { message
=> $message, code
=> M_ATTRSYNTAX
};
my $num_tsbs = @
{ $this->{tsbnames
} };
if(not $num_tsbs and not $this->{notsb
}) {
my $message = "Section '$name' non-hv block defines no TSBs\n".
push @messages, { message
=> $message, code
=> M_ATTRSYNTAX
};
if($num_tsbs and $this->{notsb
}) {
my $message = "Section '$name' defined $num_tsbs TSB(s) and notsb\n".
push @messages, { message
=> $message, code
=> M_ATTRSYNTAX
};
if(defined $this->{va
}) {
my $va_bf = string2bf
($this->{va
}, $VASIZE);
my $message = "Section '$name' VA is not a number:\n$va_bf\n".
push @messages, { message
=> $message, code
=> M_NOTNUM
};
if(defined $this->{ra
}) {
my $ra_bf = string2bf
($this->{ra
}, $RASIZE);
my $message = "Section '$name' RA is not a number:\n$ra_bf.\n".
push @messages, { message
=> $message, code
=> M_NOTNUM
};
if(defined $this->{pa
}) {
my $pa_bf = string2bf
($this->{pa
}, $PASIZE);
my $message = "Section '$name' PA is not a number:\n$pa_bf.\n".
push @messages, { message
=> $message, code
=> M_NOTNUM
};
###########################################################################
return 1 unless $this->{hypervisor
};
###########################################################################
###############################################################################
###############################################################################