1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "qemu/osdep.h"
21#include "cpu.h"
22#include "exec/exec-all.h"
23#include "qemu/qemu-print.h"
24#include "trace.h"
25
26
27
28#if defined(CONFIG_USER_ONLY)
29
30bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
31 MMUAccessType access_type, int mmu_idx,
32 bool probe, uintptr_t retaddr)
33{
34 SPARCCPU *cpu = SPARC_CPU(cs);
35 CPUSPARCState *env = &cpu->env;
36
37 if (access_type == MMU_INST_FETCH) {
38 cs->exception_index = TT_TFAULT;
39 } else {
40 cs->exception_index = TT_DFAULT;
41#ifdef TARGET_SPARC64
42 env->dmmu.mmuregs[4] = address;
43#else
44 env->mmuregs[4] = address;
45#endif
46 }
47 cpu_loop_exit_restore(cs, retaddr);
48}
49
50#else
51
52#ifndef TARGET_SPARC64
53
54
55
56static const int access_table[8][8] = {
57 { 0, 0, 0, 0, 8, 0, 12, 12 },
58 { 0, 0, 0, 0, 8, 0, 0, 0 },
59 { 8, 8, 0, 0, 0, 8, 12, 12 },
60 { 8, 8, 0, 0, 0, 8, 0, 0 },
61 { 8, 0, 8, 0, 8, 8, 12, 12 },
62 { 8, 0, 8, 0, 8, 0, 8, 0 },
63 { 8, 8, 8, 0, 8, 8, 12, 12 },
64 { 8, 8, 8, 0, 8, 8, 8, 0 }
65};
66
67static const int perm_table[2][8] = {
68 {
69 PAGE_READ,
70 PAGE_READ | PAGE_WRITE,
71 PAGE_READ | PAGE_EXEC,
72 PAGE_READ | PAGE_WRITE | PAGE_EXEC,
73 PAGE_EXEC,
74 PAGE_READ | PAGE_WRITE,
75 PAGE_READ | PAGE_EXEC,
76 PAGE_READ | PAGE_WRITE | PAGE_EXEC
77 },
78 {
79 PAGE_READ,
80 PAGE_READ | PAGE_WRITE,
81 PAGE_READ | PAGE_EXEC,
82 PAGE_READ | PAGE_WRITE | PAGE_EXEC,
83 PAGE_EXEC,
84 PAGE_READ,
85 0,
86 0,
87 }
88};
89
90static int get_physical_address(CPUSPARCState *env, hwaddr *physical,
91 int *prot, int *access_index,
92 target_ulong address, int rw, int mmu_idx,
93 target_ulong *page_size)
94{
95 int access_perms = 0;
96 hwaddr pde_ptr;
97 uint32_t pde;
98 int error_code = 0, is_dirty, is_user;
99 unsigned long page_offset;
100 CPUState *cs = env_cpu(env);
101
102 is_user = mmu_idx == MMU_USER_IDX;
103
104 if (mmu_idx == MMU_PHYS_IDX) {
105 *page_size = TARGET_PAGE_SIZE;
106
107 if (rw == 2 && (env->mmuregs[0] & env->def.mmu_bm)) {
108 *physical = env->prom_addr | (address & 0x7ffffULL);
109 *prot = PAGE_READ | PAGE_EXEC;
110 return 0;
111 }
112 *physical = address;
113 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
114 return 0;
115 }
116
117 *access_index = ((rw & 1) << 2) | (rw & 2) | (is_user ? 0 : 1);
118 *physical = 0xffffffffffff0000ULL;
119
120
121
122 pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
123 pde = ldl_phys(cs->as, pde_ptr);
124
125
126 switch (pde & PTE_ENTRYTYPE_MASK) {
127 default:
128 case 0:
129 return 1 << 2;
130 case 2:
131 case 3:
132 return 4 << 2;
133 case 1:
134 pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
135 pde = ldl_phys(cs->as, pde_ptr);
136
137 switch (pde & PTE_ENTRYTYPE_MASK) {
138 default:
139 case 0:
140 return (1 << 8) | (1 << 2);
141 case 3:
142 return (1 << 8) | (4 << 2);
143 case 1:
144 pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
145 pde = ldl_phys(cs->as, pde_ptr);
146
147 switch (pde & PTE_ENTRYTYPE_MASK) {
148 default:
149 case 0:
150 return (2 << 8) | (1 << 2);
151 case 3:
152 return (2 << 8) | (4 << 2);
153 case 1:
154 pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
155 pde = ldl_phys(cs->as, pde_ptr);
156
157 switch (pde & PTE_ENTRYTYPE_MASK) {
158 default:
159 case 0:
160 return (3 << 8) | (1 << 2);
161 case 1:
162 case 3:
163 return (3 << 8) | (4 << 2);
164 case 2:
165 page_offset = 0;
166 }
167 *page_size = TARGET_PAGE_SIZE;
168 break;
169 case 2:
170 page_offset = address & 0x3f000;
171 *page_size = 0x40000;
172 }
173 break;
174 case 2:
175 page_offset = address & 0xfff000;
176 *page_size = 0x1000000;
177 }
178 }
179
180
181 access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
182 error_code = access_table[*access_index][access_perms];
183 if (error_code && !((env->mmuregs[0] & MMU_NF) && is_user)) {
184 return error_code;
185 }
186
187
188 is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
189 if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
190 pde |= PG_ACCESSED_MASK;
191 if (is_dirty) {
192 pde |= PG_MODIFIED_MASK;
193 }
194 stl_phys_notdirty(cs->as, pde_ptr, pde);
195 }
196
197
198 *prot = perm_table[is_user][access_perms];
199 if (!(pde & PG_MODIFIED_MASK)) {
200
201
202 *prot &= ~PAGE_WRITE;
203 }
204
205
206
207 *physical = ((hwaddr)(pde & PTE_ADDR_MASK) << 4) + page_offset;
208 return error_code;
209}
210
211
212bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
213 MMUAccessType access_type, int mmu_idx,
214 bool probe, uintptr_t retaddr)
215{
216 SPARCCPU *cpu = SPARC_CPU(cs);
217 CPUSPARCState *env = &cpu->env;
218 hwaddr paddr;
219 target_ulong vaddr;
220 target_ulong page_size;
221 int error_code = 0, prot, access_index;
222
223
224
225
226
227
228
229 assert(!probe);
230
231 address &= TARGET_PAGE_MASK;
232 error_code = get_physical_address(env, &paddr, &prot, &access_index,
233 address, access_type,
234 mmu_idx, &page_size);
235 vaddr = address;
236 if (likely(error_code == 0)) {
237 qemu_log_mask(CPU_LOG_MMU,
238 "Translate at %" VADDR_PRIx " -> "
239 TARGET_FMT_plx ", vaddr " TARGET_FMT_lx "\n",
240 address, paddr, vaddr);
241 tlb_set_page(cs, vaddr, paddr, prot, mmu_idx, page_size);
242 return true;
243 }
244
245 if (env->mmuregs[3]) {
246 env->mmuregs[3] = 1;
247 }
248 env->mmuregs[3] |= (access_index << 5) | error_code | 2;
249 env->mmuregs[4] = address;
250
251 if ((env->mmuregs[0] & MMU_NF) || env->psret == 0) {
252
253
254
255
256 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
257 tlb_set_page(cs, vaddr, paddr, prot, mmu_idx, TARGET_PAGE_SIZE);
258 return true;
259 } else {
260 if (access_type == MMU_INST_FETCH) {
261 cs->exception_index = TT_TFAULT;
262 } else {
263 cs->exception_index = TT_DFAULT;
264 }
265 cpu_loop_exit_restore(cs, retaddr);
266 }
267}
268
269target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev)
270{
271 CPUState *cs = env_cpu(env);
272 hwaddr pde_ptr;
273 uint32_t pde;
274
275
276 pde_ptr = (hwaddr)(env->mmuregs[1] << 4) +
277 (env->mmuregs[2] << 2);
278 pde = ldl_phys(cs->as, pde_ptr);
279
280 switch (pde & PTE_ENTRYTYPE_MASK) {
281 default:
282 case 0:
283 case 2:
284 case 3:
285 return 0;
286 case 1:
287 if (mmulev == 3) {
288 return pde;
289 }
290 pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
291 pde = ldl_phys(cs->as, pde_ptr);
292
293 switch (pde & PTE_ENTRYTYPE_MASK) {
294 default:
295 case 0:
296 case 3:
297 return 0;
298 case 2:
299 return pde;
300 case 1:
301 if (mmulev == 2) {
302 return pde;
303 }
304 pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
305 pde = ldl_phys(cs->as, pde_ptr);
306
307 switch (pde & PTE_ENTRYTYPE_MASK) {
308 default:
309 case 0:
310 case 3:
311 return 0;
312 case 2:
313 return pde;
314 case 1:
315 if (mmulev == 1) {
316 return pde;
317 }
318 pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
319 pde = ldl_phys(cs->as, pde_ptr);
320
321 switch (pde & PTE_ENTRYTYPE_MASK) {
322 default:
323 case 0:
324 case 1:
325 case 3:
326 return 0;
327 case 2:
328 return pde;
329 }
330 }
331 }
332 }
333 return 0;
334}
335
336void dump_mmu(CPUSPARCState *env)
337{
338 CPUState *cs = env_cpu(env);
339 target_ulong va, va1, va2;
340 unsigned int n, m, o;
341 hwaddr pde_ptr, pa;
342 uint32_t pde;
343
344 pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
345 pde = ldl_phys(cs->as, pde_ptr);
346 qemu_printf("Root ptr: " TARGET_FMT_plx ", ctx: %d\n",
347 (hwaddr)env->mmuregs[1] << 4, env->mmuregs[2]);
348 for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
349 pde = mmu_probe(env, va, 2);
350 if (pde) {
351 pa = cpu_get_phys_page_debug(cs, va);
352 qemu_printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
353 " PDE: " TARGET_FMT_lx "\n", va, pa, pde);
354 for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
355 pde = mmu_probe(env, va1, 1);
356 if (pde) {
357 pa = cpu_get_phys_page_debug(cs, va1);
358 qemu_printf(" VA: " TARGET_FMT_lx ", PA: "
359 TARGET_FMT_plx " PDE: " TARGET_FMT_lx "\n",
360 va1, pa, pde);
361 for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
362 pde = mmu_probe(env, va2, 0);
363 if (pde) {
364 pa = cpu_get_phys_page_debug(cs, va2);
365 qemu_printf(" VA: " TARGET_FMT_lx ", PA: "
366 TARGET_FMT_plx " PTE: "
367 TARGET_FMT_lx "\n",
368 va2, pa, pde);
369 }
370 }
371 }
372 }
373 }
374 }
375}
376
377
378
379
380
381int sparc_cpu_memory_rw_debug(CPUState *cs, vaddr address,
382 uint8_t *buf, int len, bool is_write)
383{
384 SPARCCPU *cpu = SPARC_CPU(cs);
385 CPUSPARCState *env = &cpu->env;
386 target_ulong addr = address;
387 int i;
388 int len1;
389 int cwp = env->cwp;
390
391 if (!is_write) {
392 for (i = 0; i < env->nwindows; i++) {
393 int off;
394 target_ulong fp = env->regbase[cwp * 16 + 22];
395
396
397 if (fp == 0) {
398 break;
399 }
400
401 cwp = cpu_cwp_inc(env, cwp + 1);
402
403
404 if (env->wim & (1 << cwp)) {
405 break;
406 }
407
408
409 if (addr + len < fp) {
410 break;
411 }
412
413
414 if (addr > fp + 64) {
415 continue;
416 }
417
418
419 if (addr < fp) {
420 len1 = fp - addr;
421 if (cpu_memory_rw_debug(cs, addr, buf, len1, is_write) != 0) {
422 return -1;
423 }
424 addr += len1;
425 len -= len1;
426 buf += len1;
427 }
428
429
430
431
432 off = addr - fp;
433 len1 = 64 - off;
434
435 if (len1 > len) {
436 len1 = len;
437 }
438
439 for (; len1; len1--) {
440 int reg = cwp * 16 + 8 + (off >> 2);
441 union {
442 uint32_t v;
443 uint8_t c[4];
444 } u;
445 u.v = cpu_to_be32(env->regbase[reg]);
446 *buf++ = u.c[off & 3];
447 addr++;
448 len--;
449 off++;
450 }
451
452 if (len == 0) {
453 return 0;
454 }
455 }
456 }
457 return cpu_memory_rw_debug(cs, addr, buf, len, is_write);
458}
459
460#else
461
462
463static inline hwaddr ultrasparc_truncate_physical(uint64_t x)
464{
465 return x & 0x1ffffffffffULL;
466}
467
468
469
470
471
472
473
474
475static inline int ultrasparc_tag_match(SparcTLBEntry *tlb,
476 uint64_t address, uint64_t context,
477 hwaddr *physical)
478{
479 uint64_t mask = -(8192ULL << 3 * TTE_PGSIZE(tlb->tte));
480
481
482 if (TTE_IS_VALID(tlb->tte) &&
483 (TTE_IS_GLOBAL(tlb->tte) || tlb_compare_context(tlb, context))
484 && compare_masked(address, tlb->tag, mask)) {
485
486 *physical = ((tlb->tte & mask) | (address & ~mask)) & 0x1ffffffe000ULL;
487 return 1;
488 }
489
490 return 0;
491}
492
493static int get_physical_address_data(CPUSPARCState *env,
494 hwaddr *physical, int *prot,
495 target_ulong address, int rw, int mmu_idx)
496{
497 CPUState *cs = env_cpu(env);
498 unsigned int i;
499 uint64_t context;
500 uint64_t sfsr = 0;
501 bool is_user = false;
502
503 switch (mmu_idx) {
504 case MMU_PHYS_IDX:
505 g_assert_not_reached();
506 case MMU_USER_IDX:
507 is_user = true;
508
509 case MMU_KERNEL_IDX:
510 context = env->dmmu.mmu_primary_context & 0x1fff;
511 sfsr |= SFSR_CT_PRIMARY;
512 break;
513 case MMU_USER_SECONDARY_IDX:
514 is_user = true;
515
516 case MMU_KERNEL_SECONDARY_IDX:
517 context = env->dmmu.mmu_secondary_context & 0x1fff;
518 sfsr |= SFSR_CT_SECONDARY;
519 break;
520 case MMU_NUCLEUS_IDX:
521 sfsr |= SFSR_CT_NUCLEUS;
522
523 default:
524 context = 0;
525 break;
526 }
527
528 if (rw == 1) {
529 sfsr |= SFSR_WRITE_BIT;
530 } else if (rw == 4) {
531 sfsr |= SFSR_NF_BIT;
532 }
533
534 for (i = 0; i < 64; i++) {
535
536 if (ultrasparc_tag_match(&env->dtlb[i], address, context, physical)) {
537 int do_fault = 0;
538
539
540
541 if (TTE_IS_PRIV(env->dtlb[i].tte) && is_user) {
542 do_fault = 1;
543 sfsr |= SFSR_FT_PRIV_BIT;
544 trace_mmu_helper_dfault(address, context, mmu_idx, env->tl);
545 }
546 if (rw == 4) {
547 if (TTE_IS_SIDEEFFECT(env->dtlb[i].tte)) {
548 do_fault = 1;
549 sfsr |= SFSR_FT_NF_E_BIT;
550 }
551 } else {
552 if (TTE_IS_NFO(env->dtlb[i].tte)) {
553 do_fault = 1;
554 sfsr |= SFSR_FT_NFO_BIT;
555 }
556 }
557
558 if (do_fault) {
559
560 cs->exception_index = TT_DFAULT;
561 } else if (!TTE_IS_W_OK(env->dtlb[i].tte) && (rw == 1)) {
562 do_fault = 1;
563 cs->exception_index = TT_DPROT;
564
565 trace_mmu_helper_dprot(address, context, mmu_idx, env->tl);
566 }
567
568 if (!do_fault) {
569 *prot = PAGE_READ;
570 if (TTE_IS_W_OK(env->dtlb[i].tte)) {
571 *prot |= PAGE_WRITE;
572 }
573
574 TTE_SET_USED(env->dtlb[i].tte);
575
576 return 0;
577 }
578
579 if (env->dmmu.sfsr & SFSR_VALID_BIT) {
580 sfsr |= SFSR_OW_BIT;
581
582 }
583
584 if (env->pstate & PS_PRIV) {
585 sfsr |= SFSR_PR_BIT;
586 }
587
588
589 env->dmmu.sfsr = sfsr | SFSR_VALID_BIT;
590
591 env->dmmu.sfar = address;
592
593 env->dmmu.tag_access = (address & ~0x1fffULL) | context;
594
595 return 1;
596 }
597 }
598
599 trace_mmu_helper_dmiss(address, context);
600
601
602
603
604
605
606 env->dmmu.tag_access = (address & ~0x1fffULL) | context;
607 cs->exception_index = TT_DMISS;
608 return 1;
609}
610
611static int get_physical_address_code(CPUSPARCState *env,
612 hwaddr *physical, int *prot,
613 target_ulong address, int mmu_idx)
614{
615 CPUState *cs = env_cpu(env);
616 unsigned int i;
617 uint64_t context;
618 bool is_user = false;
619
620 switch (mmu_idx) {
621 case MMU_PHYS_IDX:
622 case MMU_USER_SECONDARY_IDX:
623 case MMU_KERNEL_SECONDARY_IDX:
624 g_assert_not_reached();
625 case MMU_USER_IDX:
626 is_user = true;
627
628 case MMU_KERNEL_IDX:
629 context = env->dmmu.mmu_primary_context & 0x1fff;
630 break;
631 default:
632 context = 0;
633 break;
634 }
635
636 if (env->tl == 0) {
637
638 context = env->dmmu.mmu_primary_context & 0x1fff;
639 } else {
640
641 context = 0;
642 }
643
644 for (i = 0; i < 64; i++) {
645
646 if (ultrasparc_tag_match(&env->itlb[i],
647 address, context, physical)) {
648
649 if (TTE_IS_PRIV(env->itlb[i].tte) && is_user) {
650
651 if (env->immu.sfsr & SFSR_VALID_BIT) {
652 env->immu.sfsr = SFSR_OW_BIT;
653
654 } else {
655 env->immu.sfsr = 0;
656 }
657 if (env->pstate & PS_PRIV) {
658 env->immu.sfsr |= SFSR_PR_BIT;
659 }
660 if (env->tl > 0) {
661 env->immu.sfsr |= SFSR_CT_NUCLEUS;
662 }
663
664
665 env->immu.sfsr |= SFSR_FT_PRIV_BIT | SFSR_VALID_BIT;
666 cs->exception_index = TT_TFAULT;
667
668 env->immu.tag_access = (address & ~0x1fffULL) | context;
669
670 trace_mmu_helper_tfault(address, context);
671
672 return 1;
673 }
674 *prot = PAGE_EXEC;
675 TTE_SET_USED(env->itlb[i].tte);
676 return 0;
677 }
678 }
679
680 trace_mmu_helper_tmiss(address, context);
681
682
683 env->immu.tag_access = (address & ~0x1fffULL) | context;
684 cs->exception_index = TT_TMISS;
685 return 1;
686}
687
688static int get_physical_address(CPUSPARCState *env, hwaddr *physical,
689 int *prot, int *access_index,
690 target_ulong address, int rw, int mmu_idx,
691 target_ulong *page_size)
692{
693
694
695 *page_size = TARGET_PAGE_SIZE;
696
697
698 if (env->tl > 0 && mmu_idx != MMU_NUCLEUS_IDX) {
699 if (rw == 2) {
700 trace_mmu_helper_get_phys_addr_code(env->tl, mmu_idx,
701 env->dmmu.mmu_primary_context,
702 env->dmmu.mmu_secondary_context,
703 address);
704 } else {
705 trace_mmu_helper_get_phys_addr_data(env->tl, mmu_idx,
706 env->dmmu.mmu_primary_context,
707 env->dmmu.mmu_secondary_context,
708 address);
709 }
710 }
711
712 if (mmu_idx == MMU_PHYS_IDX) {
713 *physical = ultrasparc_truncate_physical(address);
714 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
715 return 0;
716 }
717
718 if (rw == 2) {
719 return get_physical_address_code(env, physical, prot, address,
720 mmu_idx);
721 } else {
722 return get_physical_address_data(env, physical, prot, address, rw,
723 mmu_idx);
724 }
725}
726
727
728bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
729 MMUAccessType access_type, int mmu_idx,
730 bool probe, uintptr_t retaddr)
731{
732 SPARCCPU *cpu = SPARC_CPU(cs);
733 CPUSPARCState *env = &cpu->env;
734 target_ulong vaddr;
735 hwaddr paddr;
736 target_ulong page_size;
737 int error_code = 0, prot, access_index;
738
739 address &= TARGET_PAGE_MASK;
740 error_code = get_physical_address(env, &paddr, &prot, &access_index,
741 address, access_type,
742 mmu_idx, &page_size);
743 if (likely(error_code == 0)) {
744 vaddr = address;
745
746 trace_mmu_helper_mmu_fault(address, paddr, mmu_idx, env->tl,
747 env->dmmu.mmu_primary_context,
748 env->dmmu.mmu_secondary_context);
749
750 tlb_set_page(cs, vaddr, paddr, prot, mmu_idx, page_size);
751 return true;
752 }
753 if (probe) {
754 return false;
755 }
756 cpu_loop_exit_restore(cs, retaddr);
757}
758
759void dump_mmu(CPUSPARCState *env)
760{
761 unsigned int i;
762 const char *mask;
763
764 qemu_printf("MMU contexts: Primary: %" PRId64 ", Secondary: %"
765 PRId64 "\n",
766 env->dmmu.mmu_primary_context,
767 env->dmmu.mmu_secondary_context);
768 qemu_printf("DMMU Tag Access: %" PRIx64 ", TSB Tag Target: %" PRIx64
769 "\n", env->dmmu.tag_access, env->dmmu.tsb_tag_target);
770 if ((env->lsu & DMMU_E) == 0) {
771 qemu_printf("DMMU disabled\n");
772 } else {
773 qemu_printf("DMMU dump\n");
774 for (i = 0; i < 64; i++) {
775 switch (TTE_PGSIZE(env->dtlb[i].tte)) {
776 default:
777 case 0x0:
778 mask = " 8k";
779 break;
780 case 0x1:
781 mask = " 64k";
782 break;
783 case 0x2:
784 mask = "512k";
785 break;
786 case 0x3:
787 mask = " 4M";
788 break;
789 }
790 if (TTE_IS_VALID(env->dtlb[i].tte)) {
791 qemu_printf("[%02u] VA: %" PRIx64 ", PA: %llx"
792 ", %s, %s, %s, %s, ctx %" PRId64 " %s\n",
793 i,
794 env->dtlb[i].tag & (uint64_t)~0x1fffULL,
795 TTE_PA(env->dtlb[i].tte),
796 mask,
797 TTE_IS_PRIV(env->dtlb[i].tte) ? "priv" : "user",
798 TTE_IS_W_OK(env->dtlb[i].tte) ? "RW" : "RO",
799 TTE_IS_LOCKED(env->dtlb[i].tte) ?
800 "locked" : "unlocked",
801 env->dtlb[i].tag & (uint64_t)0x1fffULL,
802 TTE_IS_GLOBAL(env->dtlb[i].tte) ?
803 "global" : "local");
804 }
805 }
806 }
807 if ((env->lsu & IMMU_E) == 0) {
808 qemu_printf("IMMU disabled\n");
809 } else {
810 qemu_printf("IMMU dump\n");
811 for (i = 0; i < 64; i++) {
812 switch (TTE_PGSIZE(env->itlb[i].tte)) {
813 default:
814 case 0x0:
815 mask = " 8k";
816 break;
817 case 0x1:
818 mask = " 64k";
819 break;
820 case 0x2:
821 mask = "512k";
822 break;
823 case 0x3:
824 mask = " 4M";
825 break;
826 }
827 if (TTE_IS_VALID(env->itlb[i].tte)) {
828 qemu_printf("[%02u] VA: %" PRIx64 ", PA: %llx"
829 ", %s, %s, %s, ctx %" PRId64 " %s\n",
830 i,
831 env->itlb[i].tag & (uint64_t)~0x1fffULL,
832 TTE_PA(env->itlb[i].tte),
833 mask,
834 TTE_IS_PRIV(env->itlb[i].tte) ? "priv" : "user",
835 TTE_IS_LOCKED(env->itlb[i].tte) ?
836 "locked" : "unlocked",
837 env->itlb[i].tag & (uint64_t)0x1fffULL,
838 TTE_IS_GLOBAL(env->itlb[i].tte) ?
839 "global" : "local");
840 }
841 }
842 }
843}
844
845#endif
846
847static int cpu_sparc_get_phys_page(CPUSPARCState *env, hwaddr *phys,
848 target_ulong addr, int rw, int mmu_idx)
849{
850 target_ulong page_size;
851 int prot, access_index;
852
853 return get_physical_address(env, phys, &prot, &access_index, addr, rw,
854 mmu_idx, &page_size);
855}
856
857#if defined(TARGET_SPARC64)
858hwaddr cpu_get_phys_page_nofault(CPUSPARCState *env, target_ulong addr,
859 int mmu_idx)
860{
861 hwaddr phys_addr;
862
863 if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 4, mmu_idx) != 0) {
864 return -1;
865 }
866 return phys_addr;
867}
868#endif
869
870hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
871{
872 SPARCCPU *cpu = SPARC_CPU(cs);
873 CPUSPARCState *env = &cpu->env;
874 hwaddr phys_addr;
875 int mmu_idx = cpu_mmu_index(env, false);
876
877 if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 2, mmu_idx) != 0) {
878 if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 0, mmu_idx) != 0) {
879 return -1;
880 }
881 }
882 return phys_addr;
883}
884#endif
885