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