Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / perlmod / Midas / 3.32 / lib / site_perl / 5.8.0 / Midas / AttrBlock.pm
CommitLineData
86530b38
AT
1# ========== Copyright Header Begin ==========================================
2#
3# OpenSPARC T2 Processor File: AttrBlock.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{
37 package Midas::AttrBlock;
38 use strict;
39
40 use Midas::Command;
41 use Midas::Error;
42 use Midas::Globals;
43
44 use fields qw(
45 name
46
47 type
48 srcfile
49 srcline
50
51 secobj
52
53 endfile
54 endline
55
56 has_set
57
58 settable
59 );
60
61 our @Settable = qw(name section);
62 our %Settable = map { $_ => 1 } Midas::AttrBlock->settable();
63
64 ##############################################################################
65
66 sub new {
67 my $this = shift;
68 my %args = @_;
69
70 unless (ref $this) {
71 $this = fields::new($this);
72 }
73
74 $this->set_defaults();
75
76 foreach my $key (keys %args) {
77 $this->{$key} = $args{$key};
78 }
79
80 $this->{settable} = \%Settable;
81
82 return $this;
83 }
84
85 ##############################################################################
86
87 sub set_defaults {
88 my $this = shift;
89 $this->{has_set} = {};
90 }
91
92 ##############################################################################
93
94 sub set_end_file_line {
95 my $this = shift;
96 my $endfile = shift;
97 my $endline = shift;
98 $this->{endfile} = $endfile;
99 $this->{endline} = $endline;
100 }
101
102 ##############################################################################
103
104 sub get_end_file_line {
105 my $this = shift;
106 return ($this->{endfile}, $this->{endline});
107 }
108
109 ##############################################################################
110
111 sub clone {
112 my $this = shift;
113
114 my $class = ref $this;
115 my $that = $class->new();
116
117 $that->copy($this);
118 return $that;
119 }
120
121 ##############################################################################
122
123 sub copy {
124 my $this = shift;
125 my $src = shift;
126
127 my @fields = keys %$this;
128
129 my @shallow_refs = qw(Midas::Section);
130
131 # Note this does a shallow copy of elements in arrays and values in hashes.
132 # May need to fix that if this gets more complicated
133
134 foreach my $field (@fields) {
135 if(not ref $src->{$field}) {
136 $this->{$field} = $src->{$field};
137 } else {
138 my $reftype = ref $src->{$field};
139 if($reftype eq 'ARRAY') {
140 $this->{$field} = [ @{$src->{$field}} ];
141 } elsif($reftype eq 'HASH') {
142 $this->{$field} = { %{$src->{$field}} };
143 } elsif(grep /^$reftype$/, @shallow_refs) {
144 $this->{$field} = $src->{$field};
145 } else {
146 $this->{$field} = $src->{$field}->clone();
147 }
148 }
149 }
150
151 }
152
153 ##############################################################################
154
155 sub settable {
156 my $this = shift;
157 return @Settable;
158 }
159
160 ##############################################################################
161
162 sub is_settable {
163 my $this = shift;
164 my $attr = shift;
165
166 $attr = lc $attr;
167 return 1 if exists $this->{settable}{$attr};
168 return;
169 }
170
171 ##############################################################################
172
173 sub set_attr {
174 my $this = shift;
175 my $attr = shift;
176 my $value = shift;
177
178 $this->attr_fatal("Attribute \"$attr\" is not a settable attribute.",
179 M_ILLEGALPARAM) unless $this->is_settable($attr);
180
181 $attr = lc $attr;
182
183 # make "section" a synonym for "name"
184 if ($attr eq 'section') {
185 $attr = 'name';
186 }
187
188 if ($this->{has_set}{$attr}) {
189 $this->attr_fatal("Attribute \"$attr\" is set multiple times.",
190 M_ILLEGALPARAM);
191 }
192
193 $this->{$attr} = $value;
194
195 $this->{has_set}{$attr} = 1;
196
197 return $value;
198 }
199
200 ##############################################################################
201
202 sub sanity_check {
203 my $this = shift;
204 my $message;
205
206 my $fline = $this->get_fline();
207 my @messages;
208 if(not defined $this->{name}) {
209 my $message = '' unless defined $message;
210 $message .= "Block has no \"name\" or \"section\" tag.\n";
211 push @messages, { message => $message, code => M_ATTRSYNTAX }
212 }
213
214 return @messages;
215 }
216
217 ##############################################################################
218
219 sub get_section_name {
220 my $this = shift;
221 return lc $this->{name};
222 }
223
224 ##############################################################################
225
226 sub secobj {
227 my $this = shift;
228 my $obj = shift;
229
230 $this->{secobj} = $obj if defined $obj;
231
232 return $this->{secobj};
233 }
234
235 ##############################################################################
236
237 sub get_fline {
238 my $this = shift;
239 my $fline = "File=$this->{srcfile}, Line=$this->{srcline}";
240 return $fline;
241 }
242
243 ##############################################################################
244
245 sub attr_fatal {
246 my $this = shift;
247 my $message = shift;
248 my $errcode = shift;
249 my $secname = $this->{name};
250 my $fline = $this->get_fline();
251
252 chomp $message;
253 fatal "SECTION '$secname': $message\n At $fline\n", $errcode;
254 }
255
256 ##############################################################################
257
258 sub init_from_args {
259 my $this = shift;
260 my $srcfile = shift;
261 my $srcline = shift;
262 my %args = @_;
263
264 $this->{srcfile} = $srcfile;
265 $this->{srcline} = $srcline;
266
267
268 # Make sure that name => or section => gets set first. That way, if any
269 # later attributes cause an error, at least the error message will
270 # look good.
271 my @attr_names = keys %args;
272 if(exists $args{name}) {
273 my $name = $args{name};
274 delete $args{name};
275 @attr_names = ('name', keys %args);
276 $args{name} = $name;
277 }
278 if(exists $args{section}) {
279 my $section = $args{section};
280 delete $args{section};
281 @attr_names = ('section', keys %args);
282 $args{section} = $section;
283 }
284
285 foreach my $attr (@attr_names) {
286 if ($this->is_settable($attr)) {
287 $this->set_attr($attr, $args{$attr});
288 } else {
289 $this->attr_fatal("No such attribute '$attr'.",M_ILLEGALPARAM);
290 }
291 }
292 }
293
294 ##############################################################################
295}
296
297###############################################################################
298###############################################################################
299
300{
301 package Midas::AttrBlock::LinkAttrs;
302
303 use strict;
304 use Midas::Command;
305 use Midas::Globals;
306 use Midas::Error;
307 use Midas::Segment;
308 use TRELoad 'BitFieldTie';
309
310 use base 'Midas::AttrBlock';
311
312 BEGIN: {
313 require fields;
314 fields->import(Midas::Segment->all_va_names());
315 }
316
317 our @Settable = Midas::Segment->all_va_names();
318 our %Settable = map { $_ => 1 } Midas::AttrBlock::LinkAttrs->settable();
319
320 #############################################################################
321
322 sub new {
323 my $this = shift;
324 my %args = @_;
325
326
327 unless (ref $this) {
328 $this = fields::new($this);
329 }
330
331
332 $this->set_defaults();
333
334 foreach my $key (keys %args) {
335 $this->{$key} = $args{$key};
336 }
337
338 $this->{settable} = \%Settable;
339
340 return $this;
341 }
342
343 #############################################################################
344
345 sub settable {
346 my $this = shift;
347 my @settable = $this->SUPER::settable();
348 push @settable, @Settable;
349 return @settable;
350 }
351
352 #############################################################################
353
354 sub has_segment {
355 my $this = shift;
356 my $segment = shift;
357
358 return 1 if defined $this->{ Midas::Segment->name2va_name($segment) };
359 return;
360 }
361
362 #############################################################################
363
364 sub get_segment_va_bf {
365 my $this = shift;
366 my $segment = shift;
367
368
369 $this->attr_fatal("No segment argument to has_segment.\n", M_CODE)
370 unless defined $segment;
371
372 my $vaname = Midas::Segment->name2va_name($segment);
373
374 return unless defined $this->{$vaname};
375
376 my $va = string2bf($this->{$vaname}, $VASIZE);
377 my $uc = uc $segment;
378 if(not ref $va) {
379 $this->attr_fatal("Cannot interpret $uc \"$this->{$vaname}\":\n$va",
380 M_NOTNUM);
381 }
382
383 return $va;
384 }
385
386 #############################################################################
387
388 sub get_segment_va {
389 my $this = shift;
390 my $segment = shift;
391 my $va_bf = $this->get_segment_va_bf($segment);
392 return unless ref $va_bf;
393 return "0x$va_bf";
394 }
395
396 #############################################################################
397
398 sub defined_segments {
399 my $this = shift;
400 return grep { $this->has_segment($_) } Midas::Segment->all_names();
401 }
402
403 #############################################################################
404
405 sub sanity_check {
406 my $this = shift;
407
408 my @messages = $this->SUPER::sanity_check();
409
410 my $name = $this->get_section_name();
411 my $fline = $this->get_fline();
412
413 my %seg_vas;
414
415 foreach my $segment ($this->defined_segments()) {
416 my $vaname = Midas::Segment->name2va_name($segment);
417 my $va = string2bf($this->{$vaname}, $VASIZE);
418 if (not ref $va) {
419 my $message = "Section '$name' specified ${segment}_va isn't a ".
420 "number:\n".
421 "$va\n at $fline\n";
422 push @messages, { message => $message, code => M_NOTNUM };
423 } else {
424 $seg_vas{$segment} = $va;
425
426 my $dword_offset = $va->extract(2, 0);
427 if ($dword_offset != 0) {
428 my $message = "Section '$name' ${segment}_va 0x$va is not 8-byte ".
429 "aligned.\n at $fline\n";
430 push @messages, { message => $message, code => M_BADALIGN };
431 }
432
433 }
434 }
435
436 my %rev;
437 foreach my $segment (keys %seg_vas) {
438 my $vastring = $seg_vas{$segment};
439
440 if(exists $rev{$vastring}) {
441 my $oldseg = $rev{$vastring};
442
443 my $message = "Section '$name', ${oldseg}_va and ${segment}_va are ".
444 "the same\n at $fline\n";
445 push @messages, { message => $message, code => M_SECSYNTAX };
446 }
447
448 $rev{$vastring} = $segment;
449 }
450
451
452
453 return @messages;
454 }
455
456 #############################################################################
457
458}
459
460###############################################################################
461###############################################################################
462
463{
464 package Midas::AttrBlock::MapAttrs;
465
466 use strict;
467 use Carp;
468 use Midas::Command;
469 use Midas::Globals;
470 use Midas::Error;
471 use Midas::Segment;
472
473 use base 'Midas::AttrBlock';
474 use fields qw(
475 segment
476
477 unique_name
478 compressimage
479
480 tsbnames
481
482 va
483 end_va
484 start_label
485 end_label
486
487 mmutype
488
489 );
490 our @Settable = qw(
491 compressimage
492 va end_va
493 start_label end_label
494 );
495
496 our %Settable = map { $_ => 1} Midas::AttrBlock::MapAttrs->settable();
497
498
499 #############################################################################
500
501 sub new {
502 my $this = shift;
503 my %args = @_;
504
505 unless (ref $this) {
506 $this = fields::new($this);
507 }
508
509 $this->set_defaults();
510
511 foreach my $key (keys %args) {
512 $this->{$key} = $args{$key};
513 }
514
515 $this->{settable} = \%Settable;
516
517 return $this;
518 }
519
520 #############################################################################
521
522 sub set_defaults {
523 my $this = shift;
524 $this->{segment} = Midas::Segment->new(SEG_UNDEF)
525 unless defined $this->{segment};
526 $this->SUPER::set_defaults;
527 $this->{tsbnames} = [];
528 $this->{mmutype} = 'generic' unless defined $this->{mmutype};
529 }
530
531 #############################################################################
532
533 sub settable {
534 my $this = shift;
535 my @settable = $this->SUPER::settable();
536 push @settable, @Settable;
537 return @settable;
538 }
539
540 ##############################################################################
541
542 sub is_settable {
543 my $this = shift;
544 my $attr = shift;
545
546 $attr = lc $attr;
547
548 return 1 if exists $MapAttr_Settable{$attr};
549 return;
550 }
551
552 #############################################################################
553
554 sub get_field_size_hash {
555 my $this = shift;
556 return {};
557 }
558
559 #############################################################################
560
561 sub set_attr {
562 my $this = shift;
563 my $attr = shift;
564 my $value = shift;
565
566 $attr = lc $attr;
567
568 if(exists $STATE->{tsbs}{$attr}) {
569 push @{$this->{tsbnames}}, $attr;
570 $STATE->{tsbs}{$attr}->touch();
571 } else {
572 return $this->SUPER::set_attr($attr, $value);
573 }
574
575 return $value;
576 }
577
578 #############################################################################
579
580 sub get_tsb_list {
581 my $this = shift;
582
583 return [ @{$this->{tsbnames}} ];
584 }
585
586 #############################################################################
587
588 sub is_segment {
589 my $this = shift;
590 my $segment = shift;
591
592 return 1 if $this->{segment}->name() eq $segment;
593 return 0;
594 }
595
596 #############################################################################
597
598 sub get_type {
599 my $this = shift;
600 return $this->{segment}->name();
601 }
602
603 ############################################################################
604
605 sub skip_image {
606 my $this = shift;
607 return 0;
608 }
609
610 ############################################################################
611
612 sub is_mapped {
613 my $this = shift;
614 return 0;
615 }
616
617 #############################################################################
618
619 sub write_to_segment {
620 my $this = shift;
621 my $segment = shift;
622 return 1 if $this->is_segment($segment);
623 return 0;
624 }
625
626 #############################################################################
627
628 sub get_va_bf {
629 my $this = shift;
630
631 if(defined $this->{va}) {
632 return BitFieldTie->new($VASIZE, $this->{va});
633 }
634 return;
635 }
636
637 #############################################################################
638
639 sub get_va {
640 my $this = shift;
641
642 my $bf = $this->get_va_bf();
643 return unless defined $bf;
644 return "0x$bf";
645 }
646
647 ############################################################################
648
649 sub get_pa_bf {
650 my $this = shift;
651 return undef;
652 }
653
654 ############################################################################
655
656 sub get_pa {
657 my $this = shift;
658 my $bf = $this->get_pa_bf();
659 return unless defined $bf;
660 return "0x$bf";
661 }
662
663 ############################################################################
664
665 sub get_ra_bf {
666 my $this = shift;
667 return $this->get_pa_bf();
668 }
669
670 ############################################################################
671
672 sub get_ra {
673 my $this = shift;
674 my $bf = $this->get_ra_bf();
675 return unless defined $bf;
676 return "0x$bf";
677 }
678
679 #############################################################################
680
681 sub unique_name {
682 my $this = shift;
683 my $name = shift;
684
685 $this->{unique_name} = $name if defined $name;
686 return $this->{unique_name};
687 }
688
689 #############################################################################
690
691 sub write_to_goldfinger {
692 my $this = shift;
693 my $segment = shift;
694 my $linkname = shift;
695 my $fh = shift;
696
697
698 my $in_image = ((not $this->skip_image) and
699 $this->write_to_segment($segment)) ? 1 : 0;
700
701 if (not defined $this->{compressimage}) {
702 $this->{compressimage} = 0;
703 }
704 $this->{compressimage} &&= $CONFIG{compress_image};
705
706 my $type = $this->get_type();
707
708 my $name = $this->{name};
709 my $va = $this->get_va();
710 my $ra = $this->get_ra();
711 my $pa = $this->get_pa();
712
713 my $unique_name = $this->unique_name();
714 $fh->print(" BLOCK $unique_name\n");
715 $fh->print(" SECTION_NAME = \"$name\";\n");
716 $fh->print(" SEGMENT_NAME = \"$type\";\n");
717 $fh->print(" LINK_SECTION = \"$linkname\";\n");
718 $fh->print(" SRC_FILE = \"$this->{srcfile}\";\n");
719 $fh->print(" SRC_LINE = $this->{srcline};\n");
720 $fh->print(" COMPRESS = $this->{compressimage};\n");
721 $fh->print(" VA = $va;\n") if defined $va;
722 $fh->print(" RA = $ra;\n") if defined $ra;
723 $fh->print(" PA = $pa;\n") if defined $pa;
724 $fh->print(" IN_IMAGE = $in_image;\n");
725 $fh->print(" END_VA = $this->{end_va};\n")
726 if defined $this->{end_va};
727 $fh->print(" START_LABEL = \"$this->{start_label}\";\n")
728 if defined $this->{start_label};
729 $fh->print(" END_LABEL = \"$this->{end_label}\";\n")
730 if defined $this->{end_label};
731 $this->write_goldfinger_mmu_params($fh);
732
733 $fh->print(" END BLOCK\n");
734 $fh->print("\n");
735
736 }
737
738 #############################################################################
739
740 sub write_goldfinger_mmu_params {
741 my $fh = shift;
742 }
743
744 #############################################################################
745
746}
747
748###############################################################################
749###############################################################################
750
7511;