These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / target-sparc / mmu_helper.c
1 /*
2  *  Sparc MMU helpers
3  *
4  *  Copyright (c) 2003-2005 Fabrice Bellard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "qemu/osdep.h"
21 #include "cpu.h"
22 #include "trace.h"
23 #include "exec/address-spaces.h"
24
25 /* Sparc MMU emulation */
26
27 #if defined(CONFIG_USER_ONLY)
28
29 int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
30                                int mmu_idx)
31 {
32     if (rw & 2) {
33         cs->exception_index = TT_TFAULT;
34     } else {
35         cs->exception_index = TT_DFAULT;
36     }
37     return 1;
38 }
39
40 #else
41
42 #ifndef TARGET_SPARC64
43 /*
44  * Sparc V8 Reference MMU (SRMMU)
45  */
46 static const int access_table[8][8] = {
47     { 0, 0, 0, 0, 8, 0, 12, 12 },
48     { 0, 0, 0, 0, 8, 0, 0, 0 },
49     { 8, 8, 0, 0, 0, 8, 12, 12 },
50     { 8, 8, 0, 0, 0, 8, 0, 0 },
51     { 8, 0, 8, 0, 8, 8, 12, 12 },
52     { 8, 0, 8, 0, 8, 0, 8, 0 },
53     { 8, 8, 8, 0, 8, 8, 12, 12 },
54     { 8, 8, 8, 0, 8, 8, 8, 0 }
55 };
56
57 static const int perm_table[2][8] = {
58     {
59         PAGE_READ,
60         PAGE_READ | PAGE_WRITE,
61         PAGE_READ | PAGE_EXEC,
62         PAGE_READ | PAGE_WRITE | PAGE_EXEC,
63         PAGE_EXEC,
64         PAGE_READ | PAGE_WRITE,
65         PAGE_READ | PAGE_EXEC,
66         PAGE_READ | PAGE_WRITE | PAGE_EXEC
67     },
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,
75         0,
76         0,
77     }
78 };
79
80 static int get_physical_address(CPUSPARCState *env, hwaddr *physical,
81                                 int *prot, int *access_index,
82                                 target_ulong address, int rw, int mmu_idx,
83                                 target_ulong *page_size)
84 {
85     int access_perms = 0;
86     hwaddr pde_ptr;
87     uint32_t pde;
88     int error_code = 0, is_dirty, is_user;
89     unsigned long page_offset;
90     CPUState *cs = CPU(sparc_env_get_cpu(env));
91
92     is_user = mmu_idx == MMU_USER_IDX;
93
94     if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
95         *page_size = TARGET_PAGE_SIZE;
96         /* Boot mode: instruction fetches are taken from PROM */
97         if (rw == 2 && (env->mmuregs[0] & env->def->mmu_bm)) {
98             *physical = env->prom_addr | (address & 0x7ffffULL);
99             *prot = PAGE_READ | PAGE_EXEC;
100             return 0;
101         }
102         *physical = address;
103         *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
104         return 0;
105     }
106
107     *access_index = ((rw & 1) << 2) | (rw & 2) | (is_user ? 0 : 1);
108     *physical = 0xffffffffffff0000ULL;
109
110     /* SPARC reference MMU table walk: Context table->L1->L2->PTE */
111     /* Context base + context number */
112     pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
113     pde = ldl_phys(cs->as, pde_ptr);
114
115     /* Ctx pde */
116     switch (pde & PTE_ENTRYTYPE_MASK) {
117     default:
118     case 0: /* Invalid */
119         return 1 << 2;
120     case 2: /* L0 PTE, maybe should not happen? */
121     case 3: /* Reserved */
122         return 4 << 2;
123     case 1: /* L0 PDE */
124         pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
125         pde = ldl_phys(cs->as, pde_ptr);
126
127         switch (pde & PTE_ENTRYTYPE_MASK) {
128         default:
129         case 0: /* Invalid */
130             return (1 << 8) | (1 << 2);
131         case 3: /* Reserved */
132             return (1 << 8) | (4 << 2);
133         case 1: /* L1 PDE */
134             pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
135             pde = ldl_phys(cs->as, pde_ptr);
136
137             switch (pde & PTE_ENTRYTYPE_MASK) {
138             default:
139             case 0: /* Invalid */
140                 return (2 << 8) | (1 << 2);
141             case 3: /* Reserved */
142                 return (2 << 8) | (4 << 2);
143             case 1: /* L2 PDE */
144                 pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
145                 pde = ldl_phys(cs->as, pde_ptr);
146
147                 switch (pde & PTE_ENTRYTYPE_MASK) {
148                 default:
149                 case 0: /* Invalid */
150                     return (3 << 8) | (1 << 2);
151                 case 1: /* PDE, should not happen */
152                 case 3: /* Reserved */
153                     return (3 << 8) | (4 << 2);
154                 case 2: /* L3 PTE */
155                     page_offset = 0;
156                 }
157                 *page_size = TARGET_PAGE_SIZE;
158                 break;
159             case 2: /* L2 PTE */
160                 page_offset = address & 0x3f000;
161                 *page_size = 0x40000;
162             }
163             break;
164         case 2: /* L1 PTE */
165             page_offset = address & 0xfff000;
166             *page_size = 0x1000000;
167         }
168     }
169
170     /* check access */
171     access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
172     error_code = access_table[*access_index][access_perms];
173     if (error_code && !((env->mmuregs[0] & MMU_NF) && is_user)) {
174         return error_code;
175     }
176
177     /* update page modified and dirty bits */
178     is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
179     if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
180         pde |= PG_ACCESSED_MASK;
181         if (is_dirty) {
182             pde |= PG_MODIFIED_MASK;
183         }
184         stl_phys_notdirty(cs->as, pde_ptr, pde);
185     }
186
187     /* the page can be put in the TLB */
188     *prot = perm_table[is_user][access_perms];
189     if (!(pde & PG_MODIFIED_MASK)) {
190         /* only set write access if already dirty... otherwise wait
191            for dirty access */
192         *prot &= ~PAGE_WRITE;
193     }
194
195     /* Even if large ptes, we map only one 4KB page in the cache to
196        avoid filling it too fast */
197     *physical = ((hwaddr)(pde & PTE_ADDR_MASK) << 4) + page_offset;
198     return error_code;
199 }
200
201 /* Perform address translation */
202 int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
203                                int mmu_idx)
204 {
205     SPARCCPU *cpu = SPARC_CPU(cs);
206     CPUSPARCState *env = &cpu->env;
207     hwaddr paddr;
208     target_ulong vaddr;
209     target_ulong page_size;
210     int error_code = 0, prot, access_index;
211
212     address &= TARGET_PAGE_MASK;
213     error_code = get_physical_address(env, &paddr, &prot, &access_index,
214                                       address, rw, mmu_idx, &page_size);
215     vaddr = address;
216     if (error_code == 0) {
217         qemu_log_mask(CPU_LOG_MMU,
218                 "Translate at %" VADDR_PRIx " -> " TARGET_FMT_plx ", vaddr "
219                 TARGET_FMT_lx "\n", address, paddr, vaddr);
220         tlb_set_page(cs, vaddr, paddr, prot, mmu_idx, page_size);
221         return 0;
222     }
223
224     if (env->mmuregs[3]) { /* Fault status register */
225         env->mmuregs[3] = 1; /* overflow (not read before another fault) */
226     }
227     env->mmuregs[3] |= (access_index << 5) | error_code | 2;
228     env->mmuregs[4] = address; /* Fault address register */
229
230     if ((env->mmuregs[0] & MMU_NF) || env->psret == 0)  {
231         /* No fault mode: if a mapping is available, just override
232            permissions. If no mapping is available, redirect accesses to
233            neverland. Fake/overridden mappings will be flushed when
234            switching to normal mode. */
235         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
236         tlb_set_page(cs, vaddr, paddr, prot, mmu_idx, TARGET_PAGE_SIZE);
237         return 0;
238     } else {
239         if (rw & 2) {
240             cs->exception_index = TT_TFAULT;
241         } else {
242             cs->exception_index = TT_DFAULT;
243         }
244         return 1;
245     }
246 }
247
248 target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev)
249 {
250     CPUState *cs = CPU(sparc_env_get_cpu(env));
251     hwaddr pde_ptr;
252     uint32_t pde;
253
254     /* Context base + context number */
255     pde_ptr = (hwaddr)(env->mmuregs[1] << 4) +
256         (env->mmuregs[2] << 2);
257     pde = ldl_phys(cs->as, pde_ptr);
258
259     switch (pde & PTE_ENTRYTYPE_MASK) {
260     default:
261     case 0: /* Invalid */
262     case 2: /* PTE, maybe should not happen? */
263     case 3: /* Reserved */
264         return 0;
265     case 1: /* L1 PDE */
266         if (mmulev == 3) {
267             return pde;
268         }
269         pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
270         pde = ldl_phys(cs->as, pde_ptr);
271
272         switch (pde & PTE_ENTRYTYPE_MASK) {
273         default:
274         case 0: /* Invalid */
275         case 3: /* Reserved */
276             return 0;
277         case 2: /* L1 PTE */
278             return pde;
279         case 1: /* L2 PDE */
280             if (mmulev == 2) {
281                 return pde;
282             }
283             pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
284             pde = ldl_phys(cs->as, pde_ptr);
285
286             switch (pde & PTE_ENTRYTYPE_MASK) {
287             default:
288             case 0: /* Invalid */
289             case 3: /* Reserved */
290                 return 0;
291             case 2: /* L2 PTE */
292                 return pde;
293             case 1: /* L3 PDE */
294                 if (mmulev == 1) {
295                     return pde;
296                 }
297                 pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
298                 pde = ldl_phys(cs->as, pde_ptr);
299
300                 switch (pde & PTE_ENTRYTYPE_MASK) {
301                 default:
302                 case 0: /* Invalid */
303                 case 1: /* PDE, should not happen */
304                 case 3: /* Reserved */
305                     return 0;
306                 case 2: /* L3 PTE */
307                     return pde;
308                 }
309             }
310         }
311     }
312     return 0;
313 }
314
315 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env)
316 {
317     CPUState *cs = CPU(sparc_env_get_cpu(env));
318     target_ulong va, va1, va2;
319     unsigned int n, m, o;
320     hwaddr pde_ptr, pa;
321     uint32_t pde;
322
323     pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
324     pde = ldl_phys(cs->as, pde_ptr);
325     (*cpu_fprintf)(f, "Root ptr: " TARGET_FMT_plx ", ctx: %d\n",
326                    (hwaddr)env->mmuregs[1] << 4, env->mmuregs[2]);
327     for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
328         pde = mmu_probe(env, va, 2);
329         if (pde) {
330             pa = cpu_get_phys_page_debug(cs, va);
331             (*cpu_fprintf)(f, "VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
332                            " PDE: " TARGET_FMT_lx "\n", va, pa, pde);
333             for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
334                 pde = mmu_probe(env, va1, 1);
335                 if (pde) {
336                     pa = cpu_get_phys_page_debug(cs, va1);
337                     (*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: "
338                                    TARGET_FMT_plx " PDE: " TARGET_FMT_lx "\n",
339                                    va1, pa, pde);
340                     for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
341                         pde = mmu_probe(env, va2, 0);
342                         if (pde) {
343                             pa = cpu_get_phys_page_debug(cs, va2);
344                             (*cpu_fprintf)(f, "  VA: " TARGET_FMT_lx ", PA: "
345                                            TARGET_FMT_plx " PTE: "
346                                            TARGET_FMT_lx "\n",
347                                            va2, pa, pde);
348                         }
349                     }
350                 }
351             }
352         }
353     }
354 }
355
356 /* Gdb expects all registers windows to be flushed in ram. This function handles
357  * reads (and only reads) in stack frames as if windows were flushed. We assume
358  * that the sparc ABI is followed.
359  */
360 int sparc_cpu_memory_rw_debug(CPUState *cs, vaddr address,
361                               uint8_t *buf, int len, bool is_write)
362 {
363     SPARCCPU *cpu = SPARC_CPU(cs);
364     CPUSPARCState *env = &cpu->env;
365     target_ulong addr = address;
366     int i;
367     int len1;
368     int cwp = env->cwp;
369
370     if (!is_write) {
371         for (i = 0; i < env->nwindows; i++) {
372             int off;
373             target_ulong fp = env->regbase[cwp * 16 + 22];
374
375             /* Assume fp == 0 means end of frame.  */
376             if (fp == 0) {
377                 break;
378             }
379
380             cwp = cpu_cwp_inc(env, cwp + 1);
381
382             /* Invalid window ? */
383             if (env->wim & (1 << cwp)) {
384                 break;
385             }
386
387             /* According to the ABI, the stack is growing downward.  */
388             if (addr + len < fp) {
389                 break;
390             }
391
392             /* Not in this frame.  */
393             if (addr > fp + 64) {
394                 continue;
395             }
396
397             /* Handle access before this window.  */
398             if (addr < fp) {
399                 len1 = fp - addr;
400                 if (cpu_memory_rw_debug(cs, addr, buf, len1, is_write) != 0) {
401                     return -1;
402                 }
403                 addr += len1;
404                 len -= len1;
405                 buf += len1;
406             }
407
408             /* Access byte per byte to registers. Not very efficient but speed
409              * is not critical.
410              */
411             off = addr - fp;
412             len1 = 64 - off;
413
414             if (len1 > len) {
415                 len1 = len;
416             }
417
418             for (; len1; len1--) {
419                 int reg = cwp * 16 + 8 + (off >> 2);
420                 union {
421                     uint32_t v;
422                     uint8_t c[4];
423                 } u;
424                 u.v = cpu_to_be32(env->regbase[reg]);
425                 *buf++ = u.c[off & 3];
426                 addr++;
427                 len--;
428                 off++;
429             }
430
431             if (len == 0) {
432                 return 0;
433             }
434         }
435     }
436     return cpu_memory_rw_debug(cs, addr, buf, len, is_write);
437 }
438
439 #else /* !TARGET_SPARC64 */
440
441 /* 41 bit physical address space */
442 static inline hwaddr ultrasparc_truncate_physical(uint64_t x)
443 {
444     return x & 0x1ffffffffffULL;
445 }
446
447 /*
448  * UltraSparc IIi I/DMMUs
449  */
450
451 /* Returns true if TTE tag is valid and matches virtual address value
452    in context requires virtual address mask value calculated from TTE
453    entry size */
454 static inline int ultrasparc_tag_match(SparcTLBEntry *tlb,
455                                        uint64_t address, uint64_t context,
456                                        hwaddr *physical)
457 {
458     uint64_t mask;
459
460     switch (TTE_PGSIZE(tlb->tte)) {
461     default:
462     case 0x0: /* 8k */
463         mask = 0xffffffffffffe000ULL;
464         break;
465     case 0x1: /* 64k */
466         mask = 0xffffffffffff0000ULL;
467         break;
468     case 0x2: /* 512k */
469         mask = 0xfffffffffff80000ULL;
470         break;
471     case 0x3: /* 4M */
472         mask = 0xffffffffffc00000ULL;
473         break;
474     }
475
476     /* valid, context match, virtual address match? */
477     if (TTE_IS_VALID(tlb->tte) &&
478         (TTE_IS_GLOBAL(tlb->tte) || tlb_compare_context(tlb, context))
479         && compare_masked(address, tlb->tag, mask)) {
480         /* decode physical address */
481         *physical = ((tlb->tte & mask) | (address & ~mask)) & 0x1ffffffe000ULL;
482         return 1;
483     }
484
485     return 0;
486 }
487
488 static int get_physical_address_data(CPUSPARCState *env,
489                                      hwaddr *physical, int *prot,
490                                      target_ulong address, int rw, int mmu_idx)
491 {
492     CPUState *cs = CPU(sparc_env_get_cpu(env));
493     unsigned int i;
494     uint64_t context;
495     uint64_t sfsr = 0;
496
497     int is_user = (mmu_idx == MMU_USER_IDX ||
498                    mmu_idx == MMU_USER_SECONDARY_IDX);
499
500     if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
501         *physical = ultrasparc_truncate_physical(address);
502         *prot = PAGE_READ | PAGE_WRITE;
503         return 0;
504     }
505
506     switch (mmu_idx) {
507     case MMU_USER_IDX:
508     case MMU_KERNEL_IDX:
509         context = env->dmmu.mmu_primary_context & 0x1fff;
510         sfsr |= SFSR_CT_PRIMARY;
511         break;
512     case MMU_USER_SECONDARY_IDX:
513     case MMU_KERNEL_SECONDARY_IDX:
514         context = env->dmmu.mmu_secondary_context & 0x1fff;
515         sfsr |= SFSR_CT_SECONDARY;
516         break;
517     case MMU_NUCLEUS_IDX:
518         sfsr |= SFSR_CT_NUCLEUS;
519         /* FALLTHRU */
520     default:
521         context = 0;
522         break;
523     }
524
525     if (rw == 1) {
526         sfsr |= SFSR_WRITE_BIT;
527     } else if (rw == 4) {
528         sfsr |= SFSR_NF_BIT;
529     }
530
531     for (i = 0; i < 64; i++) {
532         /* ctx match, vaddr match, valid? */
533         if (ultrasparc_tag_match(&env->dtlb[i], address, context, physical)) {
534             int do_fault = 0;
535
536             /* access ok? */
537             /* multiple bits in SFSR.FT may be set on TT_DFAULT */
538             if (TTE_IS_PRIV(env->dtlb[i].tte) && is_user) {
539                 do_fault = 1;
540                 sfsr |= SFSR_FT_PRIV_BIT; /* privilege violation */
541                 trace_mmu_helper_dfault(address, context, mmu_idx, env->tl);
542             }
543             if (rw == 4) {
544                 if (TTE_IS_SIDEEFFECT(env->dtlb[i].tte)) {
545                     do_fault = 1;
546                     sfsr |= SFSR_FT_NF_E_BIT;
547                 }
548             } else {
549                 if (TTE_IS_NFO(env->dtlb[i].tte)) {
550                     do_fault = 1;
551                     sfsr |= SFSR_FT_NFO_BIT;
552                 }
553             }
554
555             if (do_fault) {
556                 /* faults above are reported with TT_DFAULT. */
557                 cs->exception_index = TT_DFAULT;
558             } else if (!TTE_IS_W_OK(env->dtlb[i].tte) && (rw == 1)) {
559                 do_fault = 1;
560                 cs->exception_index = TT_DPROT;
561
562                 trace_mmu_helper_dprot(address, context, mmu_idx, env->tl);
563             }
564
565             if (!do_fault) {
566                 *prot = PAGE_READ;
567                 if (TTE_IS_W_OK(env->dtlb[i].tte)) {
568                     *prot |= PAGE_WRITE;
569                 }
570
571                 TTE_SET_USED(env->dtlb[i].tte);
572
573                 return 0;
574             }
575
576             if (env->dmmu.sfsr & SFSR_VALID_BIT) { /* Fault status register */
577                 sfsr |= SFSR_OW_BIT; /* overflow (not read before
578                                         another fault) */
579             }
580
581             if (env->pstate & PS_PRIV) {
582                 sfsr |= SFSR_PR_BIT;
583             }
584
585             /* FIXME: ASI field in SFSR must be set */
586             env->dmmu.sfsr = sfsr | SFSR_VALID_BIT;
587
588             env->dmmu.sfar = address; /* Fault address register */
589
590             env->dmmu.tag_access = (address & ~0x1fffULL) | context;
591
592             return 1;
593         }
594     }
595
596     trace_mmu_helper_dmiss(address, context);
597
598     /*
599      * On MMU misses:
600      * - UltraSPARC IIi: SFSR and SFAR unmodified
601      * - JPS1: SFAR updated and some fields of SFSR updated
602      */
603     env->dmmu.tag_access = (address & ~0x1fffULL) | context;
604     cs->exception_index = TT_DMISS;
605     return 1;
606 }
607
608 static int get_physical_address_code(CPUSPARCState *env,
609                                      hwaddr *physical, int *prot,
610                                      target_ulong address, int mmu_idx)
611 {
612     CPUState *cs = CPU(sparc_env_get_cpu(env));
613     unsigned int i;
614     uint64_t context;
615
616     int is_user = (mmu_idx == MMU_USER_IDX ||
617                    mmu_idx == MMU_USER_SECONDARY_IDX);
618
619     if ((env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0) {
620         /* IMMU disabled */
621         *physical = ultrasparc_truncate_physical(address);
622         *prot = PAGE_EXEC;
623         return 0;
624     }
625
626     if (env->tl == 0) {
627         /* PRIMARY context */
628         context = env->dmmu.mmu_primary_context & 0x1fff;
629     } else {
630         /* NUCLEUS context */
631         context = 0;
632     }
633
634     for (i = 0; i < 64; i++) {
635         /* ctx match, vaddr match, valid? */
636         if (ultrasparc_tag_match(&env->itlb[i],
637                                  address, context, physical)) {
638             /* access ok? */
639             if (TTE_IS_PRIV(env->itlb[i].tte) && is_user) {
640                 /* Fault status register */
641                 if (env->immu.sfsr & SFSR_VALID_BIT) {
642                     env->immu.sfsr = SFSR_OW_BIT; /* overflow (not read before
643                                                      another fault) */
644                 } else {
645                     env->immu.sfsr = 0;
646                 }
647                 if (env->pstate & PS_PRIV) {
648                     env->immu.sfsr |= SFSR_PR_BIT;
649                 }
650                 if (env->tl > 0) {
651                     env->immu.sfsr |= SFSR_CT_NUCLEUS;
652                 }
653
654                 /* FIXME: ASI field in SFSR must be set */
655                 env->immu.sfsr |= SFSR_FT_PRIV_BIT | SFSR_VALID_BIT;
656                 cs->exception_index = TT_TFAULT;
657
658                 env->immu.tag_access = (address & ~0x1fffULL) | context;
659
660                 trace_mmu_helper_tfault(address, context);
661
662                 return 1;
663             }
664             *prot = PAGE_EXEC;
665             TTE_SET_USED(env->itlb[i].tte);
666             return 0;
667         }
668     }
669
670     trace_mmu_helper_tmiss(address, context);
671
672     /* Context is stored in DMMU (dmmuregs[1]) also for IMMU */
673     env->immu.tag_access = (address & ~0x1fffULL) | context;
674     cs->exception_index = TT_TMISS;
675     return 1;
676 }
677
678 static int get_physical_address(CPUSPARCState *env, hwaddr *physical,
679                                 int *prot, int *access_index,
680                                 target_ulong address, int rw, int mmu_idx,
681                                 target_ulong *page_size)
682 {
683     /* ??? We treat everything as a small page, then explicitly flush
684        everything when an entry is evicted.  */
685     *page_size = TARGET_PAGE_SIZE;
686
687     /* safety net to catch wrong softmmu index use from dynamic code */
688     if (env->tl > 0 && mmu_idx != MMU_NUCLEUS_IDX) {
689         if (rw == 2) {
690             trace_mmu_helper_get_phys_addr_code(env->tl, mmu_idx,
691                                                 env->dmmu.mmu_primary_context,
692                                                 env->dmmu.mmu_secondary_context,
693                                                 address);
694         } else {
695             trace_mmu_helper_get_phys_addr_data(env->tl, mmu_idx,
696                                                 env->dmmu.mmu_primary_context,
697                                                 env->dmmu.mmu_secondary_context,
698                                                 address);
699         }
700     }
701
702     if (rw == 2) {
703         return get_physical_address_code(env, physical, prot, address,
704                                          mmu_idx);
705     } else {
706         return get_physical_address_data(env, physical, prot, address, rw,
707                                          mmu_idx);
708     }
709 }
710
711 /* Perform address translation */
712 int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
713                                int mmu_idx)
714 {
715     SPARCCPU *cpu = SPARC_CPU(cs);
716     CPUSPARCState *env = &cpu->env;
717     target_ulong vaddr;
718     hwaddr paddr;
719     target_ulong page_size;
720     int error_code = 0, prot, access_index;
721
722     address &= TARGET_PAGE_MASK;
723     error_code = get_physical_address(env, &paddr, &prot, &access_index,
724                                       address, rw, mmu_idx, &page_size);
725     if (error_code == 0) {
726         vaddr = address;
727
728         trace_mmu_helper_mmu_fault(address, paddr, mmu_idx, env->tl,
729                                    env->dmmu.mmu_primary_context,
730                                    env->dmmu.mmu_secondary_context);
731
732         tlb_set_page(cs, vaddr, paddr, prot, mmu_idx, page_size);
733         return 0;
734     }
735     /* XXX */
736     return 1;
737 }
738
739 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env)
740 {
741     unsigned int i;
742     const char *mask;
743
744     (*cpu_fprintf)(f, "MMU contexts: Primary: %" PRId64 ", Secondary: %"
745                    PRId64 "\n",
746                    env->dmmu.mmu_primary_context,
747                    env->dmmu.mmu_secondary_context);
748     if ((env->lsu & DMMU_E) == 0) {
749         (*cpu_fprintf)(f, "DMMU disabled\n");
750     } else {
751         (*cpu_fprintf)(f, "DMMU dump\n");
752         for (i = 0; i < 64; i++) {
753             switch (TTE_PGSIZE(env->dtlb[i].tte)) {
754             default:
755             case 0x0:
756                 mask = "  8k";
757                 break;
758             case 0x1:
759                 mask = " 64k";
760                 break;
761             case 0x2:
762                 mask = "512k";
763                 break;
764             case 0x3:
765                 mask = "  4M";
766                 break;
767             }
768             if (TTE_IS_VALID(env->dtlb[i].tte)) {
769                 (*cpu_fprintf)(f, "[%02u] VA: %" PRIx64 ", PA: %llx"
770                                ", %s, %s, %s, %s, ctx %" PRId64 " %s\n",
771                                i,
772                                env->dtlb[i].tag & (uint64_t)~0x1fffULL,
773                                TTE_PA(env->dtlb[i].tte),
774                                mask,
775                                TTE_IS_PRIV(env->dtlb[i].tte) ? "priv" : "user",
776                                TTE_IS_W_OK(env->dtlb[i].tte) ? "RW" : "RO",
777                                TTE_IS_LOCKED(env->dtlb[i].tte) ?
778                                "locked" : "unlocked",
779                                env->dtlb[i].tag & (uint64_t)0x1fffULL,
780                                TTE_IS_GLOBAL(env->dtlb[i].tte) ?
781                                "global" : "local");
782             }
783         }
784     }
785     if ((env->lsu & IMMU_E) == 0) {
786         (*cpu_fprintf)(f, "IMMU disabled\n");
787     } else {
788         (*cpu_fprintf)(f, "IMMU dump\n");
789         for (i = 0; i < 64; i++) {
790             switch (TTE_PGSIZE(env->itlb[i].tte)) {
791             default:
792             case 0x0:
793                 mask = "  8k";
794                 break;
795             case 0x1:
796                 mask = " 64k";
797                 break;
798             case 0x2:
799                 mask = "512k";
800                 break;
801             case 0x3:
802                 mask = "  4M";
803                 break;
804             }
805             if (TTE_IS_VALID(env->itlb[i].tte)) {
806                 (*cpu_fprintf)(f, "[%02u] VA: %" PRIx64 ", PA: %llx"
807                                ", %s, %s, %s, ctx %" PRId64 " %s\n",
808                                i,
809                                env->itlb[i].tag & (uint64_t)~0x1fffULL,
810                                TTE_PA(env->itlb[i].tte),
811                                mask,
812                                TTE_IS_PRIV(env->itlb[i].tte) ? "priv" : "user",
813                                TTE_IS_LOCKED(env->itlb[i].tte) ?
814                                "locked" : "unlocked",
815                                env->itlb[i].tag & (uint64_t)0x1fffULL,
816                                TTE_IS_GLOBAL(env->itlb[i].tte) ?
817                                "global" : "local");
818             }
819         }
820     }
821 }
822
823 #endif /* TARGET_SPARC64 */
824
825 static int cpu_sparc_get_phys_page(CPUSPARCState *env, hwaddr *phys,
826                                    target_ulong addr, int rw, int mmu_idx)
827 {
828     target_ulong page_size;
829     int prot, access_index;
830
831     return get_physical_address(env, phys, &prot, &access_index, addr, rw,
832                                 mmu_idx, &page_size);
833 }
834
835 #if defined(TARGET_SPARC64)
836 hwaddr cpu_get_phys_page_nofault(CPUSPARCState *env, target_ulong addr,
837                                            int mmu_idx)
838 {
839     hwaddr phys_addr;
840
841     if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 4, mmu_idx) != 0) {
842         return -1;
843     }
844     return phys_addr;
845 }
846 #endif
847
848 hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
849 {
850     SPARCCPU *cpu = SPARC_CPU(cs);
851     CPUSPARCState *env = &cpu->env;
852     hwaddr phys_addr;
853     int mmu_idx = cpu_mmu_index(env, false);
854     MemoryRegionSection section;
855
856     if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 2, mmu_idx) != 0) {
857         if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 0, mmu_idx) != 0) {
858             return -1;
859         }
860     }
861     section = memory_region_find(get_system_memory(), phys_addr, 1);
862     memory_region_unref(section.mr);
863     if (!int128_nz(section.size)) {
864         return -1;
865     }
866     return phys_addr;
867 }
868 #endif