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