Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / perl-5.8.0 / lib / site_perl / 5.8.0 / Midas_samy / MMU / SunSectionAttrs.pm
CommitLineData
86530b38
AT
1# -*- perl -*-
2
3package Midas::MMU::SunSectionAttrs;
4
5use strict;
6
7use Midas::Command;
8use Midas::AttrBlock;
9use Midas::Globals;
10use Midas::Error;
11
12use Midas::MMU::TTEFormat;
13
14use TRELoad 'BitFieldTie';
15
16use base qw(Midas::AttrBlock::MapAttrs);
17
18use fields (
19 qw(
20 pa bypass
21 tsbonly notsb uninitialized
22
23 tte_size_ptr
24
25 ),
26 (
27 # Hard-code MMU type because 'use fields' directive needs
28 # to happen at compile-time
29 keys %{ get_union_tte_field_hash('ultra2') }
30 )
31 );
32
33
34our @Settable = (
35 qw(
36 pa bypass
37 tsbonly notsb uninitialized
38
39 tte_size_ptr
40 ),
41 );
42
43our %Settable = map {$_ => 1} Midas::MMU::SunSectionAttrs->settable();
44
45our %FieldSizes =
46 (
47 tsbonly => 1,
48 notsb => 1,
49 bypass => 1,
50 uninitialized => 1,
51 tte_size_ptr => 3,
52 );
53
54###############################################################################
55
56sub new {
57 my $this = shift;
58 my %args = @_;
59
60 unless (ref $this) {
61 $this = fields::new($this);
62 }
63
64 $this->SUPER::new();
65
66 $this->{settable} = \%Settable;
67 foreach my $key (keys %args) {
68 $this->{$key} = $args{$key};
69 }
70
71 return $this;
72}
73
74###############################################################################
75
76sub set_defaults {
77 my $this = shift;
78
79 $this->SUPER::set_defaults();
80
81 $this->{bypass} = 0 unless defined $this->{bypass};
82 $this->{tsbonly} = 0 unless defined $this->{tsbonly};
83 $this->{notsb} = 0 unless defined $this->{notsb};
84 $this->{uninitialized} = 0 unless defined $this->{uninitialized};
85
86 $this->{tte_size} = 0 unless defined $this->{tte_size};
87}
88
89###############################################################################
90
91sub get_field_size_hash {
92 my $this = shift;
93
94 my $sizes = $this->SUPER::get_field_size_hash();
95
96 foreach my $field (keys %FieldSizes) {
97 $sizes->{$field} = $FieldSizes{$field};
98 }
99
100 return $sizes;
101}
102
103###############################################################################
104
105sub sanity_check {
106 my $this = shift;
107
108 my @messages = $this->SUPER::sanity_check();
109
110 my $name = $this->get_section_name();
111 my $fline = $this->get_fline();
112
113 if($this->{uninitialized} && $this->{tsbonly}) {
114 my $message = "Section '$name' redundantly specifies both tsbonly and ".
115 "uninitialized.\n at $fline\n";
116 push @messages, { message => $message, code => M_ATTRSYNTAX };
117 }
118
119 return @messages;
120}
121
122
123###############################################################################
124
125sub settable {
126 my $this = shift;
127 my @settable = $this->SUPER::settable();
128 push @settable, @Settable;
129 return @settable;
130}
131
132###############################################################################
133
134sub skip_image {
135 my $this = shift;
136 return 1 if $this->{tsbonly} || $this->{uninitialized};
137 return 0;
138}
139
140###############################################################################
141
142sub set_attr {
143 my $this = shift;
144 my $attr = shift;
145 my $val = shift;
146
147 my $lcattr = lc $attr;
148 if (exists $MapAttr_FieldMax{$lcattr}) {
149
150 my $width = $MapAttr_FieldWidth{$lcattr};
151 $this->attr_fatal("Attribute \"$attr\" set to non-numeric value: ".
152 "\"$val\"\n", M_NOTNUM)
153 unless $val =~ /^\s*(0[xX])?[\da-fA-F]+\s*$/;
154
155 my $val_bf = string2bf($val, 64);
156 if(not ref $val_bf) {
157 $this->attr_fatal("Value \"$val\" is not a ${width}-bit hex number:\n".
158 "$val_bf",
159 M_NOTNUM);
160 }
161
162 my $range_bf = $MapAttr_FieldMax{$lcattr};
163
164 if($val_bf->ucompare($range_bf) >= 0) {
165 $this->attr_fatal("Value \"$val\" is out of range for ".
166 "${width}-bit field '$attr'.", M_OUTOFRANGE);
167 }
168
169 $val = $val_bf->extract($width-1, 0);
170 }
171 $this->SUPER::set_attr($attr => $val);
172}
173
174###############################################################################
175
176sub get_data_addr_bits {
177 my $this = shift;
178 return (39, 13);
179}
180
181###############################################################################
182
183sub get_tag {
184 my $this = shift;
185 my $force_ctx_zero = shift;
186
187 $this->attr_fatal("Getting tag for unmapped section.\n", M_CODE)
188 unless $this->is_mapped();
189
190 my $addr = '0';
191 my $tag = tte_hash_to_tsb_tag($this->{mmutype},
192 $CONFIG{tsbtagfmt}, $this,
193 $addr, $force_ctx_zero);
194 fatal "Combination of MMU type $this->{mmutype} and TSB tag format ".
195 "$CONFIG{tsbtagfmt}\n is not legal\n", M_ATTRSYNTAX unless defined $tag;
196 return $tag;
197
198}
199
200###############################################################################
201
202sub legal_page_bits {
203 my $this = shift;
204 return (0 .. 7);
205}
206
207###############################################################################
208
209sub get_pa_bf {
210 my $this = shift;
211
212 return unless $this->is_mapped();
213 return unless exists $this->{pa} and defined $this->{pa};
214
215 my $pa = string2bf($this->{pa}, $PASIZE);
216 if(not ref $pa) {
217 $this->attr_fatal("Cannot interpret PA \"$this->{pa}\":\n$pa\n", M_NOTNUM);
218 }
219 return $pa;
220}
221
222###############################################################################
223
224sub is_mapped {
225 my $this = shift;
226 return 1 unless $this->{bypass};
227 return;
228}
229
230###############################################################################
231
232sub get_data {
233 my $this = shift;
234 my $tsb = shift;
235
236 my $ttefmt = $tsb->get_ttefmt();
237
238 $this->attr_fatal("Getting data for unmapped section.\n", M_CODE)
239 unless $this->is_mapped();
240
241 $this->attr_fatal("Trying to generate TTE data in illegal format ".
242 "'$ttefmt'\n", M_ATTRSYNTAX) unless
243 is_good_format_for_mmu($this->{mmutype}, $ttefmt);
244
245
246
247 my $addr = 0;
248 my $data = tte_hash_to_tsb_data($this->{mmutype},
249 $ttefmt, $this, $addr);
250
251 fatal "Combination of MMU type $this->{mmutype} and TTE format $ttefmt ".
252 " is not legal\n", M_ATTRSYNTAX unless defined $data;
253 return $data;
254}
255
256##############################################################################
257
258sub write_goldfinger_mmu_params {
259 my $this = shift;
260 my $ofh = shift;
261
262 my $tsblist = $this->get_tsb_list();
263
264 print $ofh " no_end_range_check = 1;\n" if $this->{uninitialized};
265
266 print $ofh " PA_EQ_VA;\n" if not $this->is_mapped();
267 print $ofh " RA_EQ_VA;\n" if $this->{bypass};
268
269 if(@$tsblist) {
270
271
272 my ($tag_bit_hi, $tag_bit_lo) = $this->get_tag_addr_bits();
273 my ($tte_tag_bit_hi, $tte_tag_bit_lo) = $this->get_tte_tag_addr_bits();
274 my ($data_bit_hi, $data_bit_lo) = $this->get_data_addr_bits();
275
276 foreach my $tsbname (@$tsblist) {
277 my $tsb = $STATE->{tsbs}{$tsbname};
278 my $data = $this->get_data($tsb);
279
280 my $sizeptr;
281
282 if(defined $this->{tte_size_ptr}) {
283 $sizeptr = $this->{tte_size_ptr};
284 } elsif(defined $tsb->page_size()) {
285 $sizeptr = $tsb->page_size();
286 } else {
287 $sizeptr = $this->{tte_size};
288 }
289
290 my $pagesize = 8192 * (8 ** $sizeptr);
291 my $size3 = 3 * $sizeptr;
292 my $va_ind_hi = 21+$size3;
293 my $va_ind_lo = 13+$size3;
294
295
296 my $force_ctx_zero = $tsb->is_force_ctx_zero();
297 my $tag = $this->get_tag($force_ctx_zero);
298
299 print $ofh " BLOCK_TSB $tsbname\n";
300
301 print $ofh " page_size = $pagesize;\n";
302 print $ofh " va_index_bits = $va_ind_hi : $va_ind_lo;\n";
303 print $ofh " tag_addr_bits = $tag_bit_hi : $tag_bit_lo;\n";
304 print $ofh " tte_tag_addr_bits = $tte_tag_bit_hi : $tte_tag_bit_lo;\n";
305 print $ofh " data_addr_bits = $data_bit_hi : $data_bit_lo;\n";
306 print $ofh " tag_base = 0x$tag;\n";
307 print $ofh " data_base = 0x$data;\n";
308 print $ofh " END BLOCK_TSB\n";
309 }
310
311 }
312}
313
314
315###############################################################################
316
317sub get_tag_addr_bits {
318 my $this = shift;
319 if($CONFIG{tsbtagfmt} eq 'tagtarget') {
320 return (41, 0);
321 } else {
322 return (63, 13);
323 }
324}
325
326##############################################################################
327
328sub get_tte_tag_addr_bits {
329 my $this = shift;
330 if($CONFIG{tsbtagfmt} eq 'tagtarget') {
331 return (63, 22);
332 } else {
333 return (63, 13);
334 }
335}
336
337###############################################################################
338###############################################################################
339
340{
341 package Midas::MMU::SunHyperAttrs;
342
343 use Midas::Globals;
344 use Midas::Error;
345 use Midas::Command;
346
347 use base qw(Midas::MMU::SunSectionAttrs);
348 use fields qw(ra hypervisor );
349
350
351 our @Settable = (qw(ra hypervisor));
352 our %Settable = map { $_ => 1} Midas::MMU::SunHyperAttrs->settable();
353 our %FieldSizes =
354 (
355 hypervisor => 1,
356 );
357
358 ############################################################################
359
360 sub new {
361 my $this = shift;
362 my %args = @_;
363
364 unless (ref $this) {
365 $this = fields::new($this);
366 }
367
368 $this->{settable} = \%Settable;
369 foreach my $key (keys %args) {
370 $this->{$key} = $args{$key};
371 }
372
373 return $this;
374 }
375
376 ############################################################################
377
378 sub set_defaults {
379 my $this = shift;
380
381 $this->SUPER::set_defaults();
382
383 $this->{hypervisor} = 0 unless defined $this->{hypervisor};
384
385 }
386
387 #############################################################################
388
389 sub settable {
390 my $this = shift;
391 my @settable = $this->SUPER::settable();
392 push @settable, @Settable;
393 return @settable;
394 }
395
396 #############################################################################
397
398 sub get_field_size_hash {
399 my $this = shift;
400 my $sizes = $this->SUPER::get_field_size_hash();
401
402 foreach my $field (keys %FieldSizes) {
403 $sizes->{$field} = $FieldSizes{$field};
404 }
405 return $sizes;
406 }
407
408 ############################################################################
409
410
411 sub get_ra_bf {
412 my $this = shift;
413
414 return unless $this->is_mapped();
415 return unless exists $this->{ra} and defined $this->{ra};
416 my $ra = BitFieldTie->new($RASIZE, $this->{ra});
417 if(not ref $ra) {
418 $this->attr_fatal("Cannot interpret RA \"$this->{ra}\":\n$ra",
419 M_NOTNUM);
420 }
421 return $ra;
422 }
423
424 ############################################################################
425
426 sub sanity_check {
427 my $this = shift;
428
429 my @messages = $this->SUPER::sanity_check();
430
431 my $name = $this->get_section_name();
432 my $fline = $this->get_fline();
433
434 if($this->{hypervisor}) {
435 if(defined $this->{ra}) {
436 my $message = "Section '$name' hypervisor block has RA defined\n".
437 " at $fline\n";
438 push @messages, { message => $message, code => M_ATTRSYNTAX };
439 }
440 if(defined $this->{pa}) {
441 my $message = "Section '$name' hypervisor block has PA defined\n".
442 " at $fline\n";
443 push @messages, { message => $message, code => M_ATTRSYNTAX };
444 }
445 if($this->{bypass}) {
446 my $message = "Section '$name' hypervisor block has bypass defined\n".
447 " at $fline\n";
448 push @messages, { message => $message, code => M_ATTRSYNTAX };
449 }
450
451 my @settable = keys %MapAttr_Settable;
452
453 foreach my $settable (@settable) {
454 if(($settable =~ /^tte/ or $settable =~ /^tsb/ )
455 and $this->{has_set}{$settable})
456 {
457 my $message = "Section '$name' hypervisor block sets tte attr ".
458 "\"$settable\"\n".
459 " at $fline\n";
460 push @messages, { message => $message, code => M_ATTRSYNTAX };
461 }
462 }
463 } else {
464 if(not $CONFIG{allow_illegal_page_sizes}) {
465 if(not grep /^$this->{tte_size}$/, $this->legal_page_bits()) {
466 my $message = "Section '$name' has illegal page size bits ".
467 "'$this->{tte_size}'\n".
468 "Not allowed unles -allow_illegal_page_sizses is used\n".
469 " at $fline\n";
470 push @messages, { message => $message, code => M_ILLEGALPARAM };
471 }
472
473 if(defined $this->{tte_size_ptr}) {
474 if(not grep /^$this->{tte_size_ptr}$/, $this->legal_page_bits()) {
475 my $message = "Section '$name' has illegal page size ptr bits ".
476 "'$this->{tte_size_ptr}'\n".
477 "Not allowed unles -allow_illegal_page_sizses is used\n".
478 " at $fline\n";
479 push @messages, { message => $message, code => M_ILLEGALPARAM };
480 }
481 }
482
483 }
484
485
486 if(not defined $this->{pa} and not $this->skip_image()) {
487 my $message = "Section '$name' non-hv block has no PA defined\n".
488 " at $fline\n";
489 push @messages, { message => $message, code => M_ATTRSYNTAX };
490 }
491 if(not $this->{bypass} and not defined $this->{ra} and
492 not $this->{notsb})
493 {
494 my $message = "Section '$name' is not bypass or hypervisor and\n".
495 "does not define RA.\n at $fline\n";
496 push @messages, { message => $message, code => M_ATTRSYNTAX };
497 }
498 if($this->{bypass} and defined $this->{ra}) {
499 my $message = "Section '$name' defines both bypass and RA.\n".
500 " at $fline\n";
501 push @messages, { message => $message, code => M_ATTRSYNTAX };
502 }
503
504 my $num_tsbs = @{ $this->{tsbnames} };
505 if(not $num_tsbs and not $this->{notsb}) {
506 my $message = "Section '$name' non-hv block defines no TSBs\n".
507 " at $fline\n";
508 push @messages, { message => $message, code => M_ATTRSYNTAX };
509 }
510 if($num_tsbs and $this->{notsb}) {
511 my $message = "Section '$name' defined $num_tsbs TSB(s) and notsb\n".
512 " at $fline\n";
513 push @messages, { message => $message, code => M_ATTRSYNTAX };
514 }
515
516 if(defined $this->{va}) {
517 my $va_bf = string2bf($this->{va}, $VASIZE);
518 if(not ref $va_bf) {
519 my $message = "Section '$name' VA is not a number:\n$va_bf\n".
520 " at $fline\n";
521 push @messages, { message => $message, code => M_NOTNUM };
522 } else {
523 }
524 }
525 if(defined $this->{ra}) {
526 my $ra_bf = string2bf($this->{ra}, $RASIZE);
527 if(not ref $ra_bf) {
528 my $message = "Section '$name' RA is not a number:\n$ra_bf.\n".
529 " at $fline\n";
530 push @messages, { message => $message, code => M_NOTNUM };
531 } else {
532 }
533 }
534 if(defined $this->{pa}) {
535 my $pa_bf = string2bf($this->{pa}, $PASIZE);
536 if(not ref $pa_bf) {
537 my $message = "Section '$name' PA is not a number:\n$pa_bf.\n".
538 " at $fline\n";
539 push @messages, { message => $message, code => M_NOTNUM };
540 } else {
541 }
542 }
543
544 }
545
546
547 return @messages;
548 }
549
550 ###########################################################################
551
552 sub is_mapped {
553 my $this = shift;
554 return 1 unless $this->{hypervisor};
555 return;
556 }
557
558 ###########################################################################
559
560
561}
562
563
564###############################################################################
565###############################################################################
5661;