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 / TTEFormat.pm
CommitLineData
86530b38
AT
1# ========== Copyright Header Begin ==========================================
2#
3# OpenSPARC T2 Processor File: TTEFormat.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::TTEFormat;
38use strict;
39
40use TRELoad 'BitFieldTie';
41use Tie::IxHash;
42
43require Exporter;
44
45our @ISA = qw(Exporter);
46our @EXPORT = qw(
47 get_tte_field_hash
48 get_union_tte_field_hash
49 tte_hash_to_tsb_data
50 tte_hash_to_tsb_tag
51 parse_tsb_data
52 is_good_format_for_mmu
53
54 %TSB_TAG_FORMAT
55 %TSB_DATA_FORMAT
56 );
57
58our %TSB_TAG_FORMAT;
59our %TSB_DATA_FORMAT;
60
61# BEGIN block, because these need to be defined when other modules
62# call get_union_tte_field hash inside a 'use fields' clause.
63BEGIN {
64
65 our %TSB_TAG_FORMAT =
66 (
67 ultra2 =>
68 {
69 tagtarget =>
70 {
71 G => { hi=>63, lo=>63 },
72 CONTEXT => { hi=>60, lo=>48 },
73 VA => { hi=>41, lo=> 0, src=>'63:22' },
74 },
75 tagaccess =>
76 {
77 VA => { hi=>63, lo=>13, src=>'63:13' },
78 CONTEXT => { hi=>12, lo=> 0 },
79 },
80 },
81
82 niagara =>
83 {
84 tagtarget =>
85 {
86 CONTEXT => { hi=>60, lo=>48 },
87 VA => { hi=>41, lo=> 0, src=>'63:22' },
88 },
89 tagaccess =>
90 {
91 VA => { hi=>63, lo=>13, src=>'63:13' },
92 CONTEXT => { hi=>12, lo=> 0 },
93 },
94 },
95
96 niagara2 =>
97 {
98 tagtarget =>
99 {
100 CONTEXT => { hi=>60, lo=>48 },
101 VA => { hi=>41, lo=> 0, src=>'63:22' },
102 },
103 tagaccess =>
104 {
105 VA => { hi=>63, lo=>13, src=>'63:13' },
106 CONTEXT => { hi=>12, lo=> 0 },
107 },
108 },
109 X =>
110 {
111 tagtarget =>
112 {
113 CONTEXT => { hi=>60, lo=>48 },
114 VA => { hi=>41, lo=> 0, src=>'63:22' },
115 },
116 tagaccess =>
117 {
118 VA => { hi=>63, lo=>13, src=>'63:13' },
119 CONTEXT => { hi=>12, lo=> 0 },
120 },
121 },
122
123
124 );
125
126 tie my %tsb_data_ultra2_sun4u, 'Tie::IxHash';
127 tie my %tsb_data_niagara_sun4u, 'Tie::IxHash';
128 tie my %tsb_data_niagara_sun4v, 'Tie::IxHash';
129 tie my %tsb_data_niagara2_sun4u, 'Tie::IxHash';
130 tie my %tsb_data_niagara2_sun4v, 'Tie::IxHash';
131 tie my %tsb_data_X_sun4v, 'Tie::IxHash';
132
133 %tsb_data_ultra2_sun4u =
134 (
135 V => { hi=>63, lo=>63, default => 1, descr => "Valid bit, default=1" },
136 SIZE => { hi=>62, lo=>61, descr => "Encoded page size"},
137 NFO => { hi=>60, lo=>60, descr => "Non-Faulting Only" },
138 IE => { hi=>59, lo=>59, descr => "Invert Endianness" },
139 SOFT2=> { hi=>58, lo=>50, descr => "Software usable"},
140 DIAG => { hi=>49, lo=>41, descr => "Diagnostic"},
141 PA => { hi=>40, lo=>13, src=>'40:13', descr => "Physical Address"},
142 SOFT => { hi=>12, lo=> 7, descr => "Software usable" },
143 L => { hi=> 6, lo=> 6, descr => "Lock"},
144 CP => { hi=> 5, lo=> 5,
145 descr => "Cacheable in phys. indexed cache"},
146 CV => { hi=> 4, lo=> 4,
147 descr => "Cacheable in virt. indexed cache"},
148 E => { hi=> 3, lo=> 3, descr => "Side-effect"},
149 P => { hi=> 2, lo=> 2, descr => "Priviliged"},
150 W => { hi=> 1, lo=> 1, descr => "Writeable"},
151 G => { hi=> 0, lo=> 0, descr => "Global" },
152 );
153
154 %tsb_data_niagara_sun4u =
155 (
156 V => { hi=>63, lo=>63, default => 1, descr => "Valid bit, default=1"},
157 SZL => { hi=>62, lo=>61, name=>'SIZE', src=>'1:0',
158 descr => "Low bits of encoded page size" },
159 NFO => { hi=>60, lo=>60, descr => "Non-Faulting Only"},
160 IE => { hi=>59, lo=>59, descr => "Invert Endianness"},
161 SOFT2=> { hi=>58, lo=>49, descr => "Software usable"},
162 SZH => { hi=>48, lo=>48, name=>'SIZE', src=>'2',
163 descr => "High bit of encoded page size" },
164 DIAG => { hi=>47, lo=>40, descr => "Diagnostic"},
165 PA => { hi=>39, lo=>13, src=>'39:13', descr => "Physical Address"},
166 SOFT => { hi=>12, lo=> 8, descr => "Software usable"},
167 RSVD0=> { hi=> 7, lo=> 7, descr => "Reserved"},
168 L => { hi=> 6, lo=> 6, descr => "Lock" },
169 CP => { hi=> 5, lo=> 5,
170 descr => "Cacheable in phys. indexed cache"},
171 CV => { hi=> 4, lo=> 4,
172 descr => "Cacheable in virt. indexed cache"},
173 E => { hi=> 3, lo=> 3, descr => "Side-effect"},
174 P => { hi=> 2, lo=> 2, descr => "Priviliged" },
175 W => { hi=> 1, lo=> 1, descr => "Writeable" },
176 RSVD1=> { hi=> 0, lo=> 0, aliases=>['G'], descr => "Reserved" },
177 );
178
179 %tsb_data_niagara_sun4v =
180 (
181 V => { hi=>63, lo=>63, default => 1, descr => "Valid bit, default=1"},
182 NFO => { hi=>62, lo=>62, descr => "Non-Faulting Only" },
183 L => { hi=>61, lo=>61, descr => "Lock" },
184 SOFT => { hi=>60, lo=>40, descr => "Software usable"},
185 PA => { hi=>39, lo=>13, src=>'39:13', descr => "Physical Address"},
186 IE => { hi=>12, lo=>12, descr => "Invert Endianness"},
187 E => { hi=>11, lo=>11, descr => "Side-effect"},
188 CP => { hi=>10, lo=>10,
189 descr => "Cacheable in phys. indexed cache"},
190 CV => { hi=> 9, lo=> 9,
191 descr => "Cacheable in virt. indexed cache"},
192 P => { hi=> 8, lo=> 8, descr => "Priviliged" },
193 RSVD0=> { hi=> 7, lo=> 7, descr => "Reserved" },
194 W => { hi=> 6, lo=> 6, descr => "Writeable" },
195 SW1 => { hi=> 5, lo=> 5, descr => "Software usable" },
196 SW0 => { hi=> 4, lo=> 4, descr => "Software usable" },
197 RSVD1=> { hi=> 3, lo=> 3, descr => "Reserved" },
198 SIZE => { hi=> 2, lo=> 0, descr => "Encoded page size" },
199 );
200
201 %tsb_data_niagara2_sun4u =
202 (
203 V => { hi=>63, lo=>63, default => 1, descr => "Valid bit, default=1"},
204 SZL => { hi=>62, lo=>61, name=>'SIZE', src=>'1:0',
205 descr => "Low bits of encoded page size" },
206 NFO => { hi=>60, lo=>60, descr => "Non-Faulting Only"},
207 IE => { hi=>59, lo=>59, descr => "Invert Endianness"},
208 SOFT2=> { hi=>58, lo=>49, descr => "Software usable"},
209 SZH => { hi=>48, lo=>48, name=>'SIZE', src=>'2',
210 descr => "High bit of encoded page size" },
211 DIAG => { hi=>47, lo=>40, descr => "Diagnostic" },
212 PA => { hi=>39, lo=>13, src=>'39:13', descr => "Physical Address"},
213 SOFT => { hi=>12, lo=> 8, descr => "Software usable"},
214 EP => { hi=> 7, lo=> 7, aliases=>['X'],
215 descr => "Executable (also TTE_X)"},
216 L => { hi=> 6, lo=> 6, descr => "Lock" },
217 CP => { hi=> 5, lo=> 5,
218 descr => "Cacheable in phys. indexed cache"},
219 CV => { hi=> 4, lo=> 4,
220 descr => "Cacheable in virt. indexed cache"},
221 E => { hi=> 3, lo=> 3, descr => "Side-effect"},
222 P => { hi=> 2, lo=> 2, descr => "Priviliged" },
223 W => { hi=> 1, lo=> 1, descr => "Writeable" },
224 RSVD1=> { hi=> 0, lo=> 0, aliases=>['G'], descr => "Reserved" },
225 );
226
227 %tsb_data_niagara2_sun4v =
228 (
229 V => { hi=>63, lo=>63, default => 1, descr => "Valid bit, default=1"},
230 NFO => { hi=>62, lo=>62, descr => "Non-Faulting Only" },
231 L => { hi=>61, lo=>61, descr => "Lock"},
232 SOFT => { hi=>60, lo=>40, descr => "Software usable"},
233 PA => { hi=>39, lo=>13, src=>'39:13', descr => "Physical Address"},
234 IE => { hi=>12, lo=>12, descr => "Invert Endianness"},
235 E => { hi=>11, lo=>11, descr => "Side-effect"},
236 CP => { hi=>10, lo=>10,
237 descr => "Cacheable in phys. indexed cache"},
238 CV => { hi=> 9, lo=> 9,
239 descr => "Cacheable in virt. indexed cache"},
240 P => { hi=> 8, lo=> 8, descr => "Priviliged"},
241 EP => { hi=> 7, lo=> 7, aliases=>['X'],
242 descr => "Executable (also TTE_X)"},
243 W => { hi=> 6, lo=> 6, descr => "Writeable" },
244 SW1 => { hi=> 5, lo=> 5, descr => "Software usable"},
245 SW0 => { hi=> 4, lo=> 4, descr => "Software usable"},
246 RSVD1=> { hi=> 3, lo=> 3, descr => "Reserved" },
247 SIZE => { hi=> 2, lo=> 0, descr => "Encoded page size"},
248 );
249
250 %tsb_data_X_sun4v =
251 (
252 V => { hi=>63, lo=>63, default => 1, descr => "Valid bit, default=1"},
253 NFO => { hi=>62, lo=>62, descr => "Non-Faulting Only" },
254 SW1 => { hi=>61, lo=>47, descr => "Software usable"},
255 PA => { hi=>46, lo=>13, src=>'46:13', descr => "Physical Address"},
256 IE => { hi=>12, lo=>12, descr => "Invert Endianness" },
257 E => { hi=>11, lo=>11, descr => "Side-effect"},
258 CP => { hi=>10, lo=>10,
259 descr => "Cacheable in phys. indexed cache"},
260 CV => { hi=> 9, lo=> 9,
261 descr => "Cacheable in virt. indexed cache"},
262 P => { hi=> 8, lo=> 8, descr => "Priviliged" },
263 X => { hi=> 7, lo=> 7, aliases=>['EP'],
264 descr => "Executable (also TTE_EP)" },
265 W => { hi=> 6, lo=> 6, descr => "Writeable" },
266 R => { hi=> 5, lo=> 5, descr => "Readable" },
267 SW0 => { hi=> 4, lo=> 4, descr => "Software usable"},
268 RSVD0=> { hi=> 3, lo=> 3, descr => "Reserved"},
269 SIZE => { hi=> 2, lo=> 0, descr => "Encoded page size" },
270 );
271
272 our %TSB_DATA_FORMAT =
273 (
274
275 ultra2 => {
276 sun4u => \%tsb_data_ultra2_sun4u,
277 },
278 niagara => {
279 sun4u => \%tsb_data_niagara_sun4u,
280 sun4v => \%tsb_data_niagara_sun4v,
281 },
282
283 niagara2 => {
284 sun4u => \%tsb_data_niagara2_sun4u,
285 sun4v => \%tsb_data_niagara2_sun4v,
286 },
287
288
289 X => {
290 sun4v => \%tsb_data_X_sun4v,
291 },
292
293 );
294}
295
296##############################################################################
297
298sub get_tte_field_hash {
299 my $mmu_type = shift;
300 my $ttefmt = shift;
301 my $tsbtagfmt = shift;
302
303 my %fields;
304 foreach my $field (keys %{$TSB_DATA_FORMAT{$mmu_type}{$ttefmt}}) {
305 my $descr = $TSB_DATA_FORMAT{$mmu_type}{$ttefmt}{$field};
306 my $size = $descr->{hi} - $descr->{lo} + 1;
307 my $name = (exists $descr->{name}) ? $descr->{name} : $field;
308
309 my @names = ($name);
310 push @names, @{ $descr->{aliases} } if exists $descr->{aliases};
311
312 foreach my $n (@names) {
313 my $tte_n = lc('tte_' . $n);
314
315 $fields{$tte_n} = 0 unless exists $fields{$tte_n};
316 $fields{$tte_n} += $size;
317 }
318 }
319
320 foreach my $field (keys %{$TSB_TAG_FORMAT{$mmu_type}{$tsbtagfmt}}) {
321 my $descr = $TSB_TAG_FORMAT{$mmu_type}{$tsbtagfmt}{$field};
322 my $size = $descr->{hi} - $descr->{lo} + 1;
323 my $name = (exists $descr->{name}) ? $descr->{name} : $field;
324
325 my @names = ($name);
326 push @names, @{ $descr->{aliases} } if exists $descr->{aliases};
327
328 foreach my $n (@names) {
329 my $tte_n = lc('tte_' . $n);
330
331 $fields{$tte_n} = 0 unless exists $fields{$tte_n};
332 if($tte_n eq 'tte_g') {
333 $fields{$tte_n} = $size;
334 } else {
335 $fields{$tte_n} += $size;
336 }
337 }
338 }
339
340 delete $fields{tte_va} if exists $fields{tte_va};
341 delete $fields{tte_ra} if exists $fields{tte_ra};
342 delete $fields{tte_pa} if exists $fields{tte_pa};
343
344
345 return \%fields;
346}
347
348##############################################################################
349
350sub get_union_tte_field_hash {
351 my $mmu_type = shift;
352
353 my %fields;
354 foreach my $ttefmt (keys %{ $TSB_DATA_FORMAT{$mmu_type} }) {
355 foreach my $tsbtagfmt (keys %{ $TSB_TAG_FORMAT{$mmu_type} } ) {
356 my $fieldHash = get_tte_field_hash($mmu_type, $ttefmt, $tsbtagfmt);
357 foreach my $field (keys %$fieldHash) {
358 $fields{$field} = 0 unless defined $fields{$field};
359 $fields{$field} = ($fields{$field} > $fieldHash->{$field}) ?
360 $fields{$field} : $fieldHash->{$field};
361 }
362 }
363 }
364
365 return \%fields;
366}
367
368##############################################################################
369
370sub tte_hash_to_tsb_data {
371 my $mmutype = shift;
372 my $ttefmt = shift;
373 my $ttehash = shift;
374 my $addr = shift;
375
376 $addr = '0' unless defined $addr;
377
378 my $pa = BitFieldTie->new(64, $addr);
379 my $data = BitFieldTie->new(64, 0);
380 my $size = (exists $ttehash->{tte_size}) ?
381 BitFieldTie->new(64, $ttehash->{tte_size}) : undef;
382
383 tie my %data, 'BitFieldTie', $data;
384 tie my %pa, 'BitFieldTie', $pa;
385 tie my %size, 'BitFieldTie', $size;
386
387 foreach my $field (keys %{ $TSB_DATA_FORMAT{$mmutype}{$ttefmt} }) {
388 my $descr = $TSB_DATA_FORMAT{$mmutype}{$ttefmt}{$field};
389 my $name = (exists $descr->{name}) ? $descr->{name} : $field;
390
391 my @names = ($name);
392 push @names, @{ $descr->{aliases} } if exists $descr->{aliases};
393
394 my $def_value = (defined $descr->{default}) ? $descr->{default} : 0;
395 my $value;
396 my $set_already = 0;
397 if($name eq 'PA' or $name eq 'SIZE') {
398 my $bits = (exists $descr->{src}) ? $descr->{src} : '31:0';
399 if($name eq 'PA') {
400 if($bits =~ /^(\d+):(\d+)$/) {
401 my ($hi, $lo) = ($1, $2);
402 my $dist = $hi - $lo + 1;
403 if($dist > 32) {
404 my $mid_hi = $hi-31;
405 my $mid_lo = $mid_hi-1;
406
407 my $descr_mid_hi = $descr->{hi} - 31;
408 my $descr_mid_lo = $descr_mid_hi - 1;
409
410 $data{"$descr->{hi}:$descr_mid_hi"} =
411 $pa{"${hi}:$mid_hi"};
412
413 $data{"${descr_mid_lo}:$descr->{lo}"} =
414 $pa{"${mid_lo}:$lo"};
415
416 $set_already = 1;
417 } else {
418 $value = $pa{$bits};
419 }
420 } else {
421 $value = $pa{$bits};
422 }
423 } elsif($name eq 'SIZE') {
424 $value = $size{$bits};
425 }
426 } else {
427 my $found = 0;
428 foreach my $n (@names) {
429 my $tte_n = lc('tte_' . $n);
430 if(exists $ttehash->{$tte_n}) {
431 $value ||= $ttehash->{$tte_n};
432 $found = 1;
433 }
434 }
435 $value = $def_value unless $found;
436 }
437
438 $data{"$descr->{hi}" . ':' . "$descr->{lo}"} = $value
439 unless $set_already;
440
441 }
442 return $data->stringify();
443}
444
445##############################################################################
446
447sub tte_hash_to_tsb_tag {
448 my $mmutype = shift;
449 my $tsbtagfmt = shift;
450 my $ttehash = shift;
451 my $addr = shift;
452 my $force_ctx_zero = shift;
453
454 $addr = '0' unless defined $addr;
455 $force_ctx_zero = 0 unless defined $force_ctx_zero;
456
457 my $va = BitFieldTie->new(64, $addr);
458 my $tag = BitFieldTie->new(64, 0);
459
460 tie my %tag, 'BitFieldTie', $tag;
461 tie my %va, 'BitFieldTie', $va;
462
463 foreach my $field (keys %{ $TSB_TAG_FORMAT{$mmutype}{$tsbtagfmt} }) {
464 my $descr = $TSB_TAG_FORMAT{$mmutype}{$tsbtagfmt}{$field};
465 my $name = (exists $descr->{name}) ? $descr->{name} : $field;
466
467 my @names = ($name);
468 push @names, @{ $descr->{aliases} } if exists $descr->{aliases};
469
470 my $value = (defined $descr->{default}) ? $descr->{default} : 0;
471 if( $name eq 'VA') {
472 my $bits = (exists $descr->{src}) ? $descr->{src} : '31:0';
473
474 my $hi = $descr->{hi};
475 my $lo = $descr->{lo};
476 my $dist = ($hi-$lo+1);
477 if($dist >= 32) {
478 my $cut = $hi-31;
479 if($bits =~ /(\d+)\:(\d+)/) {
480 my ($bitsHi, $bitsLo) = ($1, $2);
481 my $bitsCut = $bitsHi-31;
482 $tag{"${hi}:${cut}"} = $va{"${bitsHi}:${bitsCut}"};
483 $cut--; $bitsCut--;
484 $tag{"${cut}:${lo}"} = $va{"${bitsCut}:${bitsLo}"};
485 }
486 } else {
487 $tag{"${hi}:${lo}"} = $va{$bits};
488 }
489
490
491 } else {
492 foreach my $n (@names) {
493 my $tte_n = lc('tte_' . $n);
494 if(exists $ttehash->{$tte_n}) {
495 $value ||= $ttehash->{$tte_n};
496 }
497 if($tte_n eq 'tte_context' and $force_ctx_zero) {
498 $value = 0;
499 }
500 }
501
502 $tag{"$descr->{hi}" . ':' . "$descr->{lo}"} = $value;
503 }
504
505
506 }
507 return $tag->stringify();
508}
509
510##############################################################################
511
512sub parse_tsb_data {
513 my $mmutype = shift;
514 my $ttefmt = shift;
515 my $tte_data = shift;
516
517 tie my %parsed, 'Tie::IxHash';
518
519 my $data = BitFieldTie->new(64, $tte_data);
520 tie my %data, 'BitFieldTie', $data;
521
522 my $types = $TSB_DATA_FORMAT{$mmutype}{$ttefmt};
523 foreach my $field (sort { $types->{$b}{hi} <=> $types->{$a}{hi}}
524 keys %$types)
525 {
526 my $descr = $types->{$field};
527 my $value = $data{"$descr->{hi}" . ':' . "$descr->{lo}"};
528 my $name = (exists $descr->{name}) ? $descr->{name} : $field;
529
530 $parsed{$name} = 0 unless defined $parsed{$name};
531 if(exists $descr->{src}) {
532 my $v = BitFieldTie->new(64, 0);
533 tie my %v, 'BitFieldTie', $v;
534 $v{$descr->{src}} = $value;
535 $value = $v->extract(31,0);
536 }
537 $parsed{$name} |= $value;
538
539 }
540
541 return \%parsed;
542}
543
544##############################################################################
545
546sub is_good_format_for_mmu {
547 my $mmutype = shift;
548 my $ttefmt = shift;
549 return 1 if exists $TSB_DATA_FORMAT{$mmutype}{$ttefmt};
550 return;
551}
552
553##############################################################################
5541;