xref: /qemu/target/ppc/mmu_common.c (revision 5cc867a679d4b5032284d30d22dad8e81195e60d)
1 /*
2  *  PowerPC MMU, TLB, SLB and BAT emulation helpers for QEMU.
3  *
4  *  Copyright (c) 2003-2007 Jocelyn Mayer
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.1 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 "qemu/units.h"
22 #include "cpu.h"
23 #include "sysemu/kvm.h"
24 #include "kvm_ppc.h"
25 #include "mmu-hash64.h"
26 #include "mmu-hash32.h"
27 #include "exec/exec-all.h"
28 #include "exec/page-protection.h"
29 #include "exec/log.h"
30 #include "helper_regs.h"
31 #include "qemu/error-report.h"
32 #include "qemu/qemu-print.h"
33 #include "internal.h"
34 #include "mmu-book3s-v3.h"
35 #include "mmu-radix64.h"
36 
37 /* #define DUMP_PAGE_TABLES */
38 
39 void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
40 {
41     PowerPCCPU *cpu = env_archcpu(env);
42     qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value);
43     assert(!cpu->env.has_hv_mode || !cpu->vhyp);
44 #if defined(TARGET_PPC64)
45     if (mmu_is_64bit(env->mmu_model)) {
46         target_ulong sdr_mask = SDR_64_HTABORG | SDR_64_HTABSIZE;
47         target_ulong htabsize = value & SDR_64_HTABSIZE;
48 
49         if (value & ~sdr_mask) {
50             qemu_log_mask(LOG_GUEST_ERROR, "Invalid bits 0x"TARGET_FMT_lx
51                      " set in SDR1", value & ~sdr_mask);
52             value &= sdr_mask;
53         }
54         if (htabsize > 28) {
55             qemu_log_mask(LOG_GUEST_ERROR, "Invalid HTABSIZE 0x" TARGET_FMT_lx
56                      " stored in SDR1", htabsize);
57             return;
58         }
59     }
60 #endif /* defined(TARGET_PPC64) */
61     /* FIXME: Should check for valid HTABMASK values in 32-bit case */
62     env->spr[SPR_SDR1] = value;
63 }
64 
65 /*****************************************************************************/
66 /* PowerPC MMU emulation */
67 
68 static int pp_check(int key, int pp, int nx)
69 {
70     int access;
71 
72     /* Compute access rights */
73     access = 0;
74     if (key == 0) {
75         switch (pp) {
76         case 0x0:
77         case 0x1:
78         case 0x2:
79             access |= PAGE_WRITE;
80             /* fall through */
81         case 0x3:
82             access |= PAGE_READ;
83             break;
84         }
85     } else {
86         switch (pp) {
87         case 0x0:
88             access = 0;
89             break;
90         case 0x1:
91         case 0x3:
92             access = PAGE_READ;
93             break;
94         case 0x2:
95             access = PAGE_READ | PAGE_WRITE;
96             break;
97         }
98     }
99     if (nx == 0) {
100         access |= PAGE_EXEC;
101     }
102 
103     return access;
104 }
105 
106 static int check_prot(int prot, MMUAccessType access_type)
107 {
108     return prot & prot_for_access_type(access_type) ? 0 : -2;
109 }
110 
111 int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
112                                     int way, int is_code)
113 {
114     int nr;
115 
116     /* Select TLB num in a way from address */
117     nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1);
118     /* Select TLB way */
119     nr += env->tlb_per_way * way;
120     /* 6xx have separate TLBs for instructions and data */
121     if (is_code && env->id_tlbs == 1) {
122         nr += env->nb_tlb;
123     }
124 
125     return nr;
126 }
127 
128 static int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0,
129                                 target_ulong pte1, int h,
130                                 MMUAccessType access_type)
131 {
132     target_ulong ptem, mmask;
133     int access, ret, pteh, ptev, pp;
134 
135     ret = -1;
136     /* Check validity and table match */
137     ptev = pte_is_valid(pte0);
138     pteh = (pte0 >> 6) & 1;
139     if (ptev && h == pteh) {
140         /* Check vsid & api */
141         ptem = pte0 & PTE_PTEM_MASK;
142         mmask = PTE_CHECK_MASK;
143         pp = pte1 & 0x00000003;
144         if (ptem == ctx->ptem) {
145             if (ctx->raddr != (hwaddr)-1ULL) {
146                 /* all matches should have equal RPN, WIMG & PP */
147                 if ((ctx->raddr & mmask) != (pte1 & mmask)) {
148                     qemu_log_mask(CPU_LOG_MMU, "Bad RPN/WIMG/PP\n");
149                     return -3;
150                 }
151             }
152             /* Compute access rights */
153             access = pp_check(ctx->key, pp, ctx->nx);
154             /* Keep the matching PTE information */
155             ctx->raddr = pte1;
156             ctx->prot = access;
157             ret = check_prot(ctx->prot, access_type);
158             if (ret == 0) {
159                 /* Access granted */
160                 qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n");
161             } else {
162                 /* Access right violation */
163                 qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
164             }
165         }
166     }
167 
168     return ret;
169 }
170 
171 static int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
172                             int ret, MMUAccessType access_type)
173 {
174     int store = 0;
175 
176     /* Update page flags */
177     if (!(*pte1p & 0x00000100)) {
178         /* Update accessed flag */
179         *pte1p |= 0x00000100;
180         store = 1;
181     }
182     if (!(*pte1p & 0x00000080)) {
183         if (access_type == MMU_DATA_STORE && ret == 0) {
184             /* Update changed flag */
185             *pte1p |= 0x00000080;
186             store = 1;
187         } else {
188             /* Force page fault for first write access */
189             ctx->prot &= ~PAGE_WRITE;
190         }
191     }
192 
193     return store;
194 }
195 
196 /* Software driven TLB helpers */
197 
198 static int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx,
199                             target_ulong eaddr, MMUAccessType access_type)
200 {
201     ppc6xx_tlb_t *tlb;
202     int nr, best, way;
203     int ret;
204 
205     best = -1;
206     ret = -1; /* No TLB found */
207     for (way = 0; way < env->nb_ways; way++) {
208         nr = ppc6xx_tlb_getnum(env, eaddr, way, access_type == MMU_INST_FETCH);
209         tlb = &env->tlb.tlb6[nr];
210         /* This test "emulates" the PTE index match for hardware TLBs */
211         if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) {
212             qemu_log_mask(CPU_LOG_MMU, "TLB %d/%d %s [" TARGET_FMT_lx
213                           " " TARGET_FMT_lx "] <> " TARGET_FMT_lx "\n",
214                           nr, env->nb_tlb,
215                           pte_is_valid(tlb->pte0) ? "valid" : "inval",
216                           tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr);
217             continue;
218         }
219         qemu_log_mask(CPU_LOG_MMU, "TLB %d/%d %s " TARGET_FMT_lx " <> "
220                       TARGET_FMT_lx " " TARGET_FMT_lx " %c %c\n",
221                       nr, env->nb_tlb,
222                       pte_is_valid(tlb->pte0) ? "valid" : "inval",
223                       tlb->EPN, eaddr, tlb->pte1,
224                       access_type == MMU_DATA_STORE ? 'S' : 'L',
225                       access_type == MMU_INST_FETCH ? 'I' : 'D');
226         switch (ppc6xx_tlb_pte_check(ctx, tlb->pte0, tlb->pte1,
227                                      0, access_type)) {
228         case -2:
229             /* Access violation */
230             ret = -2;
231             best = nr;
232             break;
233         case -1: /* No match */
234         case -3: /* TLB inconsistency */
235         default:
236             break;
237         case 0:
238             /* access granted */
239             /*
240              * XXX: we should go on looping to check all TLBs
241              *      consistency but we can speed-up the whole thing as
242              *      the result would be undefined if TLBs are not
243              *      consistent.
244              */
245             ret = 0;
246             best = nr;
247             goto done;
248         }
249     }
250     if (best != -1) {
251 done:
252         qemu_log_mask(CPU_LOG_MMU, "found TLB at addr " HWADDR_FMT_plx
253                       " prot=%01x ret=%d\n",
254                       ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
255         /* Update page flags */
256         pte_update_flags(ctx, &env->tlb.tlb6[best].pte1, ret, access_type);
257     }
258 #if defined(DUMP_PAGE_TABLES)
259     if (qemu_loglevel_mask(CPU_LOG_MMU)) {
260         CPUState *cs = env_cpu(env);
261         hwaddr base = ppc_hash32_hpt_base(env_archcpu(env));
262         hwaddr len = ppc_hash32_hpt_mask(env_archcpu(env)) + 0x80;
263         uint32_t a0, a1, a2, a3;
264 
265         qemu_log("Page table: " HWADDR_FMT_plx " len " HWADDR_FMT_plx "\n",
266                  base, len);
267         for (hwaddr curaddr = base; curaddr < base + len; curaddr += 16) {
268             a0 = ldl_phys(cs->as, curaddr);
269             a1 = ldl_phys(cs->as, curaddr + 4);
270             a2 = ldl_phys(cs->as, curaddr + 8);
271             a3 = ldl_phys(cs->as, curaddr + 12);
272             if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
273                 qemu_log(HWADDR_FMT_plx ": %08x %08x %08x %08x\n",
274                          curaddr, a0, a1, a2, a3);
275             }
276         }
277     }
278 #endif
279     return ret;
280 }
281 
282 /* Perform BAT hit & translation */
283 static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp,
284                                  int *validp, int *protp, target_ulong *BATu,
285                                  target_ulong *BATl)
286 {
287     target_ulong bl;
288     int pp, valid, prot;
289 
290     bl = (*BATu & 0x00001FFC) << 15;
291     valid = 0;
292     prot = 0;
293     if ((!FIELD_EX64(env->msr, MSR, PR) && (*BATu & 0x00000002)) ||
294         (FIELD_EX64(env->msr, MSR, PR) && (*BATu & 0x00000001))) {
295         valid = 1;
296         pp = *BATl & 0x00000003;
297         if (pp != 0) {
298             prot = PAGE_READ | PAGE_EXEC;
299             if (pp == 0x2) {
300                 prot |= PAGE_WRITE;
301             }
302         }
303     }
304     *blp = bl;
305     *validp = valid;
306     *protp = prot;
307 }
308 
309 static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
310                            target_ulong virtual, MMUAccessType access_type)
311 {
312     target_ulong *BATlt, *BATut, *BATu, *BATl;
313     target_ulong BEPIl, BEPIu, bl;
314     int i, valid, prot;
315     int ret = -1;
316     bool ifetch = access_type == MMU_INST_FETCH;
317 
318     qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
319                   ifetch ? 'I' : 'D', virtual);
320     if (ifetch) {
321         BATlt = env->IBAT[1];
322         BATut = env->IBAT[0];
323     } else {
324         BATlt = env->DBAT[1];
325         BATut = env->DBAT[0];
326     }
327     for (i = 0; i < env->nb_BATs; i++) {
328         BATu = &BATut[i];
329         BATl = &BATlt[i];
330         BEPIu = *BATu & 0xF0000000;
331         BEPIl = *BATu & 0x0FFE0000;
332         bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
333         qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT%d v " TARGET_FMT_lx " BATu "
334                       TARGET_FMT_lx " BATl " TARGET_FMT_lx "\n", __func__,
335                       ifetch ? 'I' : 'D', i, virtual, *BATu, *BATl);
336         if ((virtual & 0xF0000000) == BEPIu &&
337             ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
338             /* BAT matches */
339             if (valid != 0) {
340                 /* Get physical address */
341                 ctx->raddr = (*BATl & 0xF0000000) |
342                     ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
343                     (virtual & 0x0001F000);
344                 /* Compute access rights */
345                 ctx->prot = prot;
346                 ret = check_prot(ctx->prot, access_type);
347                 if (ret == 0) {
348                     qemu_log_mask(CPU_LOG_MMU, "BAT %d match: r " HWADDR_FMT_plx
349                                   " prot=%c%c\n", i, ctx->raddr,
350                                   ctx->prot & PAGE_READ ? 'R' : '-',
351                                   ctx->prot & PAGE_WRITE ? 'W' : '-');
352                 }
353                 break;
354             }
355         }
356     }
357     if (ret < 0) {
358         if (qemu_log_enabled()) {
359             qemu_log_mask(CPU_LOG_MMU, "no BAT match for "
360                           TARGET_FMT_lx ":\n", virtual);
361             for (i = 0; i < 4; i++) {
362                 BATu = &BATut[i];
363                 BATl = &BATlt[i];
364                 BEPIu = *BATu & 0xF0000000;
365                 BEPIl = *BATu & 0x0FFE0000;
366                 bl = (*BATu & 0x00001FFC) << 15;
367                 qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT%d v " TARGET_FMT_lx
368                               " BATu " TARGET_FMT_lx " BATl " TARGET_FMT_lx
369                               "\n\t" TARGET_FMT_lx " " TARGET_FMT_lx " "
370                               TARGET_FMT_lx "\n", __func__, ifetch ? 'I' : 'D',
371                               i, virtual, *BATu, *BATl, BEPIu, BEPIl, bl);
372             }
373         }
374     }
375     /* No hit */
376     return ret;
377 }
378 
379 static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
380                                        target_ulong eaddr,
381                                        MMUAccessType access_type, int type)
382 {
383     PowerPCCPU *cpu = env_archcpu(env);
384     hwaddr hash;
385     target_ulong vsid, sr, pgidx;
386     int ds, target_page_bits;
387     bool pr;
388 
389     /* First try to find a BAT entry if there are any */
390     if (env->nb_BATs && get_bat_6xx_tlb(env, ctx, eaddr, access_type) == 0) {
391         return 0;
392     }
393 
394     /* Perform segment based translation when no BATs matched */
395     pr = FIELD_EX64(env->msr, MSR, PR);
396     ctx->eaddr = eaddr;
397 
398     sr = env->sr[eaddr >> 28];
399     ctx->key = (((sr & 0x20000000) && pr) ||
400                 ((sr & 0x40000000) && !pr)) ? 1 : 0;
401     ds = sr & 0x80000000 ? 1 : 0;
402     ctx->nx = sr & 0x10000000 ? 1 : 0;
403     vsid = sr & 0x00FFFFFF;
404     target_page_bits = TARGET_PAGE_BITS;
405     qemu_log_mask(CPU_LOG_MMU,
406                   "Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx
407                   " nip=" TARGET_FMT_lx " lr=" TARGET_FMT_lx
408                   " ir=%d dr=%d pr=%d %d t=%d\n",
409                   eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr,
410                   (int)FIELD_EX64(env->msr, MSR, IR),
411                   (int)FIELD_EX64(env->msr, MSR, DR), pr ? 1 : 0,
412                   access_type == MMU_DATA_STORE, type);
413     pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits;
414     hash = vsid ^ pgidx;
415     ctx->ptem = (vsid << 7) | (pgidx >> 10);
416 
417     qemu_log_mask(CPU_LOG_MMU, "pte segment: key=%d ds %d nx %d vsid "
418                   TARGET_FMT_lx "\n", ctx->key, ds, ctx->nx, vsid);
419     if (!ds) {
420         /* Check if instruction fetch is allowed, if needed */
421         if (type == ACCESS_CODE && ctx->nx) {
422             qemu_log_mask(CPU_LOG_MMU, "No access allowed\n");
423             return -3;
424         }
425         /* Page address translation */
426         qemu_log_mask(CPU_LOG_MMU, "htab_base " HWADDR_FMT_plx " htab_mask "
427                       HWADDR_FMT_plx " hash " HWADDR_FMT_plx "\n",
428                       ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash);
429         ctx->hash[0] = hash;
430         ctx->hash[1] = ~hash;
431 
432         /* Initialize real address with an invalid value */
433         ctx->raddr = (hwaddr)-1ULL;
434         /* Software TLB search */
435         return ppc6xx_tlb_check(env, ctx, eaddr, access_type);
436     }
437 
438     /* Direct-store segment : absolutely *BUGGY* for now */
439     qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
440     switch (type) {
441     case ACCESS_INT:
442         /* Integer load/store : only access allowed */
443         break;
444     case ACCESS_CODE:
445         /* No code fetch is allowed in direct-store areas */
446         return -4;
447     case ACCESS_FLOAT:
448         /* Floating point load/store */
449         return -4;
450     case ACCESS_RES:
451         /* lwarx, ldarx or srwcx. */
452         return -4;
453     case ACCESS_CACHE:
454         /*
455          * dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi
456          *
457          * Should make the instruction do no-op.  As it already do
458          * no-op, it's quite easy :-)
459          */
460         ctx->raddr = eaddr;
461         return 0;
462     case ACCESS_EXT:
463         /* eciwx or ecowx */
464         return -4;
465     default:
466         qemu_log_mask(CPU_LOG_MMU, "ERROR: instruction should not need address"
467                                    " translation\n");
468         return -4;
469     }
470     if ((access_type == MMU_DATA_STORE || ctx->key != 1) &&
471         (access_type == MMU_DATA_LOAD || ctx->key != 0)) {
472         ctx->raddr = eaddr;
473         return 2;
474     }
475     return -2;
476 }
477 
478 /* Generic TLB check function for embedded PowerPC implementations */
479 static bool ppcemb_tlb_check(CPUPPCState *env, ppcemb_tlb_t *tlb,
480                              hwaddr *raddrp,
481                              target_ulong address, uint32_t pid, int i)
482 {
483     target_ulong mask;
484 
485     /* Check valid flag */
486     if (!(tlb->prot & PAGE_VALID)) {
487         return false;
488     }
489     mask = ~(tlb->size - 1);
490     qemu_log_mask(CPU_LOG_MMU, "%s: TLB %d address " TARGET_FMT_lx
491                   " PID %u <=> " TARGET_FMT_lx " " TARGET_FMT_lx " %u %x\n",
492                   __func__, i, address, pid, tlb->EPN,
493                   mask, (uint32_t)tlb->PID, tlb->prot);
494     /* Check PID */
495     if (tlb->PID != 0 && tlb->PID != pid) {
496         return false;
497     }
498     /* Check effective address */
499     if ((address & mask) != tlb->EPN) {
500         return false;
501     }
502     *raddrp = (tlb->RPN & mask) | (address & ~mask);
503     return true;
504 }
505 
506 /* Generic TLB search function for PowerPC embedded implementations */
507 int ppcemb_tlb_search(CPUPPCState *env, target_ulong address, uint32_t pid)
508 {
509     ppcemb_tlb_t *tlb;
510     hwaddr raddr;
511     int i;
512 
513     for (i = 0; i < env->nb_tlb; i++) {
514         tlb = &env->tlb.tlbe[i];
515         if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, i)) {
516             return i;
517         }
518     }
519     return -1;
520 }
521 
522 static int mmu40x_get_physical_address(CPUPPCState *env, hwaddr *raddr,
523                                        int *prot, target_ulong address,
524                                        MMUAccessType access_type)
525 {
526     ppcemb_tlb_t *tlb;
527     int i, ret, zsel, zpr, pr;
528 
529     ret = -1;
530     pr = FIELD_EX64(env->msr, MSR, PR);
531     for (i = 0; i < env->nb_tlb; i++) {
532         tlb = &env->tlb.tlbe[i];
533         if (!ppcemb_tlb_check(env, tlb, raddr, address,
534                               env->spr[SPR_40x_PID], i)) {
535             continue;
536         }
537         zsel = (tlb->attr >> 4) & 0xF;
538         zpr = (env->spr[SPR_40x_ZPR] >> (30 - (2 * zsel))) & 0x3;
539         qemu_log_mask(CPU_LOG_MMU,
540                       "%s: TLB %d zsel %d zpr %d ty %d attr %08x\n",
541                       __func__, i, zsel, zpr, access_type, tlb->attr);
542         /* Check execute enable bit */
543         switch (zpr) {
544         case 0x2:
545             if (pr != 0) {
546                 goto check_perms;
547             }
548             /* fall through */
549         case 0x3:
550             /* All accesses granted */
551             *prot = PAGE_RWX;
552             ret = 0;
553             break;
554 
555         case 0x0:
556             if (pr != 0) {
557                 /* Raise Zone protection fault.  */
558                 env->spr[SPR_40x_ESR] = 1 << 22;
559                 *prot = 0;
560                 ret = -2;
561                 break;
562             }
563             /* fall through */
564         case 0x1:
565 check_perms:
566             /* Check from TLB entry */
567             *prot = tlb->prot;
568             ret = check_prot(*prot, access_type);
569             if (ret == -2) {
570                 env->spr[SPR_40x_ESR] = 0;
571             }
572             break;
573         }
574     }
575     qemu_log_mask(CPU_LOG_MMU, "%s: access %s " TARGET_FMT_lx " => "
576                   HWADDR_FMT_plx " %d %d\n",  __func__,
577                   ret < 0 ? "refused" : "granted", address,
578                   ret < 0 ? 0 : *raddr, *prot, ret);
579 
580     return ret;
581 }
582 
583 static bool mmubooke_check_pid(CPUPPCState *env, ppcemb_tlb_t *tlb,
584                                hwaddr *raddr, target_ulong addr, int i)
585 {
586     if (ppcemb_tlb_check(env, tlb, raddr, addr, env->spr[SPR_BOOKE_PID], i)) {
587         if (!env->nb_pids) {
588             /* Extend the physical address to 36 bits */
589             *raddr |= (uint64_t)(tlb->RPN & 0xF) << 32;
590         }
591         return true;
592     } else if (!env->nb_pids) {
593         return false;
594     }
595     if (env->spr[SPR_BOOKE_PID1] &&
596         ppcemb_tlb_check(env, tlb, raddr, addr, env->spr[SPR_BOOKE_PID1], i)) {
597         return true;
598     }
599     if (env->spr[SPR_BOOKE_PID2] &&
600         ppcemb_tlb_check(env, tlb, raddr, addr, env->spr[SPR_BOOKE_PID2], i)) {
601         return true;
602     }
603     return false;
604 }
605 
606 static int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb,
607                               hwaddr *raddr, int *prot, target_ulong address,
608                               MMUAccessType access_type, int i)
609 {
610     if (!mmubooke_check_pid(env, tlb, raddr, address, i)) {
611         qemu_log_mask(CPU_LOG_MMU, "%s: TLB entry not found\n", __func__);
612         return -1;
613     }
614 
615     /* Check the address space */
616     if ((access_type == MMU_INST_FETCH ?
617         FIELD_EX64(env->msr, MSR, IR) :
618         FIELD_EX64(env->msr, MSR, DR)) != (tlb->attr & 1)) {
619         qemu_log_mask(CPU_LOG_MMU, "%s: AS doesn't match\n", __func__);
620         return -1;
621     }
622 
623     if (FIELD_EX64(env->msr, MSR, PR)) {
624         *prot = tlb->prot & 0xF;
625     } else {
626         *prot = (tlb->prot >> 4) & 0xF;
627     }
628     if (*prot & prot_for_access_type(access_type)) {
629         qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
630         return 0;
631     }
632 
633     qemu_log_mask(CPU_LOG_MMU, "%s: no prot match: %x\n", __func__, *prot);
634     return access_type == MMU_INST_FETCH ? -3 : -2;
635 }
636 
637 static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
638                                          target_ulong address,
639                                          MMUAccessType access_type)
640 {
641     ppcemb_tlb_t *tlb;
642     hwaddr raddr;
643     int i, ret;
644 
645     ret = -1;
646     raddr = (hwaddr)-1ULL;
647     for (i = 0; i < env->nb_tlb; i++) {
648         tlb = &env->tlb.tlbe[i];
649         ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address,
650                                  access_type, i);
651         if (ret != -1) {
652             break;
653         }
654     }
655 
656     if (ret >= 0) {
657         ctx->raddr = raddr;
658         qemu_log_mask(CPU_LOG_MMU, "%s: access granted " TARGET_FMT_lx
659                       " => " HWADDR_FMT_plx " %d %d\n", __func__,
660                       address, ctx->raddr, ctx->prot, ret);
661     } else {
662          qemu_log_mask(CPU_LOG_MMU, "%s: access refused " TARGET_FMT_lx
663                        " => " HWADDR_FMT_plx " %d %d\n", __func__,
664                        address, raddr, ctx->prot, ret);
665     }
666 
667     return ret;
668 }
669 
670 hwaddr booke206_tlb_to_page_size(CPUPPCState *env, ppcmas_tlb_t *tlb)
671 {
672     int tlbm_size;
673 
674     tlbm_size = (tlb->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
675 
676     return 1024ULL << tlbm_size;
677 }
678 
679 /* TLB check function for MAS based SoftTLBs */
680 int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb, hwaddr *raddrp,
681                      target_ulong address, uint32_t pid)
682 {
683     hwaddr mask;
684     uint32_t tlb_pid;
685 
686     if (!FIELD_EX64(env->msr, MSR, CM)) {
687         /* In 32bit mode we can only address 32bit EAs */
688         address = (uint32_t)address;
689     }
690 
691     /* Check valid flag */
692     if (!(tlb->mas1 & MAS1_VALID)) {
693         return -1;
694     }
695 
696     mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
697     qemu_log_mask(CPU_LOG_MMU, "%s: TLB ADDR=0x" TARGET_FMT_lx
698                   " PID=0x%x MAS1=0x%x MAS2=0x%" PRIx64 " mask=0x%"
699                   HWADDR_PRIx " MAS7_3=0x%" PRIx64 " MAS8=0x%" PRIx32 "\n",
700                   __func__, address, pid, tlb->mas1, tlb->mas2, mask,
701                   tlb->mas7_3, tlb->mas8);
702 
703     /* Check PID */
704     tlb_pid = (tlb->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT;
705     if (tlb_pid != 0 && tlb_pid != pid) {
706         return -1;
707     }
708 
709     /* Check effective address */
710     if ((address & mask) != (tlb->mas2 & MAS2_EPN_MASK)) {
711         return -1;
712     }
713 
714     if (raddrp) {
715         *raddrp = (tlb->mas7_3 & mask) | (address & ~mask);
716     }
717 
718     return 0;
719 }
720 
721 static bool is_epid_mmu(int mmu_idx)
722 {
723     return mmu_idx == PPC_TLB_EPID_STORE || mmu_idx == PPC_TLB_EPID_LOAD;
724 }
725 
726 static uint32_t mmubooke206_esr(int mmu_idx, MMUAccessType access_type)
727 {
728     uint32_t esr = 0;
729     if (access_type == MMU_DATA_STORE) {
730         esr |= ESR_ST;
731     }
732     if (is_epid_mmu(mmu_idx)) {
733         esr |= ESR_EPID;
734     }
735     return esr;
736 }
737 
738 /*
739  * Get EPID register given the mmu_idx. If this is regular load,
740  * construct the EPID access bits from current processor state
741  *
742  * Get the effective AS and PR bits and the PID. The PID is returned
743  * only if EPID load is requested, otherwise the caller must detect
744  * the correct EPID.  Return true if valid EPID is returned.
745  */
746 static bool mmubooke206_get_as(CPUPPCState *env,
747                                int mmu_idx, uint32_t *epid_out,
748                                bool *as_out, bool *pr_out)
749 {
750     if (is_epid_mmu(mmu_idx)) {
751         uint32_t epidr;
752         if (mmu_idx == PPC_TLB_EPID_STORE) {
753             epidr = env->spr[SPR_BOOKE_EPSC];
754         } else {
755             epidr = env->spr[SPR_BOOKE_EPLC];
756         }
757         *epid_out = (epidr & EPID_EPID) >> EPID_EPID_SHIFT;
758         *as_out = !!(epidr & EPID_EAS);
759         *pr_out = !!(epidr & EPID_EPR);
760         return true;
761     } else {
762         *as_out = FIELD_EX64(env->msr, MSR, DS);
763         *pr_out = FIELD_EX64(env->msr, MSR, PR);
764         return false;
765     }
766 }
767 
768 /* Check if the tlb found by hashing really matches */
769 static int mmubooke206_check_tlb(CPUPPCState *env, ppcmas_tlb_t *tlb,
770                                  hwaddr *raddr, int *prot,
771                                  target_ulong address,
772                                  MMUAccessType access_type, int mmu_idx)
773 {
774     uint32_t epid;
775     bool as, pr;
776     bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr);
777 
778     if (!use_epid) {
779         if (ppcmas_tlb_check(env, tlb, raddr, address,
780                              env->spr[SPR_BOOKE_PID]) >= 0) {
781             goto found_tlb;
782         }
783 
784         if (env->spr[SPR_BOOKE_PID1] &&
785             ppcmas_tlb_check(env, tlb, raddr, address,
786                              env->spr[SPR_BOOKE_PID1]) >= 0) {
787             goto found_tlb;
788         }
789 
790         if (env->spr[SPR_BOOKE_PID2] &&
791             ppcmas_tlb_check(env, tlb, raddr, address,
792                              env->spr[SPR_BOOKE_PID2]) >= 0) {
793             goto found_tlb;
794         }
795     } else {
796         if (ppcmas_tlb_check(env, tlb, raddr, address, epid) >= 0) {
797             goto found_tlb;
798         }
799     }
800 
801     qemu_log_mask(CPU_LOG_MMU, "%s: No TLB entry found for effective address "
802                   "0x" TARGET_FMT_lx "\n", __func__, address);
803     return -1;
804 
805 found_tlb:
806 
807     /* Check the address space and permissions */
808     if (access_type == MMU_INST_FETCH) {
809         /* There is no way to fetch code using epid load */
810         assert(!use_epid);
811         as = FIELD_EX64(env->msr, MSR, IR);
812     }
813 
814     if (as != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
815         qemu_log_mask(CPU_LOG_MMU, "%s: AS doesn't match\n", __func__);
816         return -1;
817     }
818 
819     *prot = 0;
820     if (pr) {
821         if (tlb->mas7_3 & MAS3_UR) {
822             *prot |= PAGE_READ;
823         }
824         if (tlb->mas7_3 & MAS3_UW) {
825             *prot |= PAGE_WRITE;
826         }
827         if (tlb->mas7_3 & MAS3_UX) {
828             *prot |= PAGE_EXEC;
829         }
830     } else {
831         if (tlb->mas7_3 & MAS3_SR) {
832             *prot |= PAGE_READ;
833         }
834         if (tlb->mas7_3 & MAS3_SW) {
835             *prot |= PAGE_WRITE;
836         }
837         if (tlb->mas7_3 & MAS3_SX) {
838             *prot |= PAGE_EXEC;
839         }
840     }
841     if (*prot & prot_for_access_type(access_type)) {
842         qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
843         return 0;
844     }
845 
846     qemu_log_mask(CPU_LOG_MMU, "%s: no prot match: %x\n", __func__, *prot);
847     return access_type == MMU_INST_FETCH ? -3 : -2;
848 }
849 
850 static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
851                                             target_ulong address,
852                                             MMUAccessType access_type,
853                                             int mmu_idx)
854 {
855     ppcmas_tlb_t *tlb;
856     hwaddr raddr;
857     int i, j, ret;
858 
859     ret = -1;
860     raddr = (hwaddr)-1ULL;
861 
862     for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
863         int ways = booke206_tlb_ways(env, i);
864 
865         for (j = 0; j < ways; j++) {
866             tlb = booke206_get_tlbm(env, i, address, j);
867             if (!tlb) {
868                 continue;
869             }
870             ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address,
871                                         access_type, mmu_idx);
872             if (ret != -1) {
873                 goto found_tlb;
874             }
875         }
876     }
877 
878 found_tlb:
879 
880     if (ret >= 0) {
881         ctx->raddr = raddr;
882          qemu_log_mask(CPU_LOG_MMU, "%s: access granted " TARGET_FMT_lx
883                        " => " HWADDR_FMT_plx " %d %d\n", __func__, address,
884                        ctx->raddr, ctx->prot, ret);
885     } else {
886          qemu_log_mask(CPU_LOG_MMU, "%s: access refused " TARGET_FMT_lx
887                        " => " HWADDR_FMT_plx " %d %d\n", __func__, address,
888                        raddr, ctx->prot, ret);
889     }
890 
891     return ret;
892 }
893 
894 static const char *book3e_tsize_to_str[32] = {
895     "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
896     "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M",
897     "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G",
898     "1T", "2T"
899 };
900 
901 static void mmubooke_dump_mmu(CPUPPCState *env)
902 {
903     ppcemb_tlb_t *entry;
904     int i;
905 
906 #ifdef CONFIG_KVM
907     if (kvm_enabled() && !env->kvm_sw_tlb) {
908         qemu_printf("Cannot access KVM TLB\n");
909         return;
910     }
911 #endif
912 
913     qemu_printf("\nTLB:\n");
914     qemu_printf("Effective          Physical           Size PID   Prot     "
915                 "Attr\n");
916 
917     entry = &env->tlb.tlbe[0];
918     for (i = 0; i < env->nb_tlb; i++, entry++) {
919         hwaddr ea, pa;
920         target_ulong mask;
921         uint64_t size = (uint64_t)entry->size;
922         char size_buf[20];
923 
924         /* Check valid flag */
925         if (!(entry->prot & PAGE_VALID)) {
926             continue;
927         }
928 
929         mask = ~(entry->size - 1);
930         ea = entry->EPN & mask;
931         pa = entry->RPN & mask;
932         /* Extend the physical address to 36 bits */
933         pa |= (hwaddr)(entry->RPN & 0xF) << 32;
934         if (size >= 1 * MiB) {
935             snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "M", size / MiB);
936         } else {
937             snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "k", size / KiB);
938         }
939         qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %s %-5u %08x %08x\n",
940                     (uint64_t)ea, (uint64_t)pa, size_buf, (uint32_t)entry->PID,
941                     entry->prot, entry->attr);
942     }
943 
944 }
945 
946 static void mmubooke206_dump_one_tlb(CPUPPCState *env, int tlbn, int offset,
947                                      int tlbsize)
948 {
949     ppcmas_tlb_t *entry;
950     int i;
951 
952     qemu_printf("\nTLB%d:\n", tlbn);
953     qemu_printf("Effective          Physical           Size TID   TS SRWX"
954                 " URWX WIMGE U0123\n");
955 
956     entry = &env->tlb.tlbm[offset];
957     for (i = 0; i < tlbsize; i++, entry++) {
958         hwaddr ea, pa, size;
959         int tsize;
960 
961         if (!(entry->mas1 & MAS1_VALID)) {
962             continue;
963         }
964 
965         tsize = (entry->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
966         size = 1024ULL << tsize;
967         ea = entry->mas2 & ~(size - 1);
968         pa = entry->mas7_3 & ~(size - 1);
969 
970         qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u  S%c%c%c"
971                     " U%c%c%c %c%c%c%c%c U%c%c%c%c\n",
972                     (uint64_t)ea, (uint64_t)pa,
973                     book3e_tsize_to_str[tsize],
974                     (entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT,
975                     (entry->mas1 & MAS1_TS) >> MAS1_TS_SHIFT,
976                     entry->mas7_3 & MAS3_SR ? 'R' : '-',
977                     entry->mas7_3 & MAS3_SW ? 'W' : '-',
978                     entry->mas7_3 & MAS3_SX ? 'X' : '-',
979                     entry->mas7_3 & MAS3_UR ? 'R' : '-',
980                     entry->mas7_3 & MAS3_UW ? 'W' : '-',
981                     entry->mas7_3 & MAS3_UX ? 'X' : '-',
982                     entry->mas2 & MAS2_W ? 'W' : '-',
983                     entry->mas2 & MAS2_I ? 'I' : '-',
984                     entry->mas2 & MAS2_M ? 'M' : '-',
985                     entry->mas2 & MAS2_G ? 'G' : '-',
986                     entry->mas2 & MAS2_E ? 'E' : '-',
987                     entry->mas7_3 & MAS3_U0 ? '0' : '-',
988                     entry->mas7_3 & MAS3_U1 ? '1' : '-',
989                     entry->mas7_3 & MAS3_U2 ? '2' : '-',
990                     entry->mas7_3 & MAS3_U3 ? '3' : '-');
991     }
992 }
993 
994 static void mmubooke206_dump_mmu(CPUPPCState *env)
995 {
996     int offset = 0;
997     int i;
998 
999 #ifdef CONFIG_KVM
1000     if (kvm_enabled() && !env->kvm_sw_tlb) {
1001         qemu_printf("Cannot access KVM TLB\n");
1002         return;
1003     }
1004 #endif
1005 
1006     for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
1007         int size = booke206_tlb_size(env, i);
1008 
1009         if (size == 0) {
1010             continue;
1011         }
1012 
1013         mmubooke206_dump_one_tlb(env, i, offset, size);
1014         offset += size;
1015     }
1016 }
1017 
1018 static void mmu6xx_dump_BATs(CPUPPCState *env, int type)
1019 {
1020     target_ulong *BATlt, *BATut, *BATu, *BATl;
1021     target_ulong BEPIl, BEPIu, bl;
1022     int i;
1023 
1024     switch (type) {
1025     case ACCESS_CODE:
1026         BATlt = env->IBAT[1];
1027         BATut = env->IBAT[0];
1028         break;
1029     default:
1030         BATlt = env->DBAT[1];
1031         BATut = env->DBAT[0];
1032         break;
1033     }
1034 
1035     for (i = 0; i < env->nb_BATs; i++) {
1036         BATu = &BATut[i];
1037         BATl = &BATlt[i];
1038         BEPIu = *BATu & 0xF0000000;
1039         BEPIl = *BATu & 0x0FFE0000;
1040         bl = (*BATu & 0x00001FFC) << 15;
1041         qemu_printf("%s BAT%d BATu " TARGET_FMT_lx
1042                     " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
1043                     TARGET_FMT_lx " " TARGET_FMT_lx "\n",
1044                     type == ACCESS_CODE ? "code" : "data", i,
1045                     *BATu, *BATl, BEPIu, BEPIl, bl);
1046     }
1047 }
1048 
1049 static void mmu6xx_dump_mmu(CPUPPCState *env)
1050 {
1051     PowerPCCPU *cpu = env_archcpu(env);
1052     ppc6xx_tlb_t *tlb;
1053     target_ulong sr;
1054     int type, way, entry, i;
1055 
1056     qemu_printf("HTAB base = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_base(cpu));
1057     qemu_printf("HTAB mask = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_mask(cpu));
1058 
1059     qemu_printf("\nSegment registers:\n");
1060     for (i = 0; i < 32; i++) {
1061         sr = env->sr[i];
1062         if (sr & 0x80000000) {
1063             qemu_printf("%02d T=%d Ks=%d Kp=%d BUID=0x%03x "
1064                         "CNTLR_SPEC=0x%05x\n", i,
1065                         sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
1066                         sr & 0x20000000 ? 1 : 0, (uint32_t)((sr >> 20) & 0x1FF),
1067                         (uint32_t)(sr & 0xFFFFF));
1068         } else {
1069             qemu_printf("%02d T=%d Ks=%d Kp=%d N=%d VSID=0x%06x\n", i,
1070                         sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
1071                         sr & 0x20000000 ? 1 : 0, sr & 0x10000000 ? 1 : 0,
1072                         (uint32_t)(sr & 0x00FFFFFF));
1073         }
1074     }
1075 
1076     qemu_printf("\nBATs:\n");
1077     mmu6xx_dump_BATs(env, ACCESS_INT);
1078     mmu6xx_dump_BATs(env, ACCESS_CODE);
1079 
1080     if (env->id_tlbs != 1) {
1081         qemu_printf("ERROR: 6xx MMU should have separated TLB"
1082                     " for code and data\n");
1083     }
1084 
1085     qemu_printf("\nTLBs                       [EPN    EPN + SIZE]\n");
1086 
1087     for (type = 0; type < 2; type++) {
1088         for (way = 0; way < env->nb_ways; way++) {
1089             for (entry = env->nb_tlb * type + env->tlb_per_way * way;
1090                  entry < (env->nb_tlb * type + env->tlb_per_way * (way + 1));
1091                  entry++) {
1092 
1093                 tlb = &env->tlb.tlb6[entry];
1094                 qemu_printf("%s TLB %02d/%02d way:%d %s ["
1095                             TARGET_FMT_lx " " TARGET_FMT_lx "]\n",
1096                             type ? "code" : "data", entry % env->nb_tlb,
1097                             env->nb_tlb, way,
1098                             pte_is_valid(tlb->pte0) ? "valid" : "inval",
1099                             tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE);
1100             }
1101         }
1102     }
1103 }
1104 
1105 void dump_mmu(CPUPPCState *env)
1106 {
1107     switch (env->mmu_model) {
1108     case POWERPC_MMU_BOOKE:
1109         mmubooke_dump_mmu(env);
1110         break;
1111     case POWERPC_MMU_BOOKE206:
1112         mmubooke206_dump_mmu(env);
1113         break;
1114     case POWERPC_MMU_SOFT_6xx:
1115         mmu6xx_dump_mmu(env);
1116         break;
1117 #if defined(TARGET_PPC64)
1118     case POWERPC_MMU_64B:
1119     case POWERPC_MMU_2_03:
1120     case POWERPC_MMU_2_06:
1121     case POWERPC_MMU_2_07:
1122         dump_slb(env_archcpu(env));
1123         break;
1124     case POWERPC_MMU_3_00:
1125         if (ppc64_v3_radix(env_archcpu(env))) {
1126             qemu_log_mask(LOG_UNIMP, "%s: the PPC64 MMU is unsupported\n",
1127                           __func__);
1128         } else {
1129             dump_slb(env_archcpu(env));
1130         }
1131         break;
1132 #endif
1133     default:
1134         qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__);
1135     }
1136 }
1137 
1138 int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
1139                                      target_ulong eaddr,
1140                                      MMUAccessType access_type, int type,
1141                                      int mmu_idx)
1142 {
1143     bool real_mode;
1144 
1145     if (env->mmu_model == POWERPC_MMU_BOOKE) {
1146         return mmubooke_get_physical_address(env, ctx, eaddr, access_type);
1147     } else if (env->mmu_model == POWERPC_MMU_BOOKE206) {
1148         return mmubooke206_get_physical_address(env, ctx, eaddr, access_type,
1149                                                 mmu_idx);
1150     }
1151 
1152     real_mode = (type == ACCESS_CODE) ? !FIELD_EX64(env->msr, MSR, IR)
1153                                       : !FIELD_EX64(env->msr, MSR, DR);
1154     if (real_mode && (env->mmu_model == POWERPC_MMU_SOFT_6xx ||
1155                       env->mmu_model == POWERPC_MMU_SOFT_4xx ||
1156                       env->mmu_model == POWERPC_MMU_REAL)) {
1157         ctx->raddr = eaddr;
1158         ctx->prot = PAGE_RWX;
1159         return 0;
1160     }
1161 
1162     switch (env->mmu_model) {
1163     case POWERPC_MMU_SOFT_6xx:
1164         return mmu6xx_get_physical_address(env, ctx, eaddr, access_type, type);
1165     case POWERPC_MMU_SOFT_4xx:
1166         return mmu40x_get_physical_address(env, &ctx->raddr, &ctx->prot, eaddr,
1167                                            access_type);
1168     case POWERPC_MMU_REAL:
1169         cpu_abort(env_cpu(env),
1170                   "PowerPC in real mode do not do any translation\n");
1171     default:
1172         cpu_abort(env_cpu(env), "Unknown or invalid MMU model\n");
1173     }
1174 }
1175 
1176 static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
1177                                          MMUAccessType access_type, int mmu_idx)
1178 {
1179     uint32_t epid;
1180     bool as, pr;
1181     uint32_t missed_tid = 0;
1182     bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr);
1183 
1184     if (access_type == MMU_INST_FETCH) {
1185         as = FIELD_EX64(env->msr, MSR, IR);
1186     }
1187     env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK;
1188     env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK;
1189     env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK;
1190     env->spr[SPR_BOOKE_MAS3] = 0;
1191     env->spr[SPR_BOOKE_MAS6] = 0;
1192     env->spr[SPR_BOOKE_MAS7] = 0;
1193 
1194     /* AS */
1195     if (as) {
1196         env->spr[SPR_BOOKE_MAS1] |= MAS1_TS;
1197         env->spr[SPR_BOOKE_MAS6] |= MAS6_SAS;
1198     }
1199 
1200     env->spr[SPR_BOOKE_MAS1] |= MAS1_VALID;
1201     env->spr[SPR_BOOKE_MAS2] |= address & MAS2_EPN_MASK;
1202 
1203     if (!use_epid) {
1204         switch (env->spr[SPR_BOOKE_MAS4] & MAS4_TIDSELD_PIDZ) {
1205         case MAS4_TIDSELD_PID0:
1206             missed_tid = env->spr[SPR_BOOKE_PID];
1207             break;
1208         case MAS4_TIDSELD_PID1:
1209             missed_tid = env->spr[SPR_BOOKE_PID1];
1210             break;
1211         case MAS4_TIDSELD_PID2:
1212             missed_tid = env->spr[SPR_BOOKE_PID2];
1213             break;
1214         }
1215         env->spr[SPR_BOOKE_MAS6] |= env->spr[SPR_BOOKE_PID] << 16;
1216     } else {
1217         missed_tid = epid;
1218         env->spr[SPR_BOOKE_MAS6] |= missed_tid << 16;
1219     }
1220     env->spr[SPR_BOOKE_MAS1] |= (missed_tid << MAS1_TID_SHIFT);
1221 
1222 
1223     /* next victim logic */
1224     env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
1225     env->last_way++;
1226     env->last_way &= booke206_tlb_ways(env, 0) - 1;
1227     env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
1228 }
1229 
1230 /* Perform address translation */
1231 /* TODO: Split this by mmu_model. */
1232 static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
1233                             MMUAccessType access_type,
1234                             hwaddr *raddrp, int *psizep, int *protp,
1235                             int mmu_idx, bool guest_visible)
1236 {
1237     CPUState *cs = CPU(cpu);
1238     CPUPPCState *env = &cpu->env;
1239     mmu_ctx_t ctx;
1240     int type;
1241     int ret;
1242 
1243     if (access_type == MMU_INST_FETCH) {
1244         /* code access */
1245         type = ACCESS_CODE;
1246     } else if (guest_visible) {
1247         /* data access */
1248         type = env->access_type;
1249     } else {
1250         type = ACCESS_INT;
1251     }
1252 
1253     ret = get_physical_address_wtlb(env, &ctx, eaddr, access_type,
1254                                     type, mmu_idx);
1255     if (ret == 0) {
1256         *raddrp = ctx.raddr;
1257         *protp = ctx.prot;
1258         *psizep = TARGET_PAGE_BITS;
1259         return true;
1260     } else if (!guest_visible) {
1261         return false;
1262     }
1263 
1264     log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
1265     if (type == ACCESS_CODE) {
1266         switch (ret) {
1267         case -1:
1268             /* No matches in page tables or TLB */
1269             switch (env->mmu_model) {
1270             case POWERPC_MMU_SOFT_6xx:
1271                 cs->exception_index = POWERPC_EXCP_IFTLB;
1272                 env->error_code = 1 << 18;
1273                 env->spr[SPR_IMISS] = eaddr;
1274                 env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
1275                 goto tlb_miss;
1276             case POWERPC_MMU_SOFT_4xx:
1277                 cs->exception_index = POWERPC_EXCP_ITLB;
1278                 env->error_code = 0;
1279                 env->spr[SPR_40x_DEAR] = eaddr;
1280                 env->spr[SPR_40x_ESR] = 0x00000000;
1281                 break;
1282             case POWERPC_MMU_BOOKE206:
1283                 booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
1284                 /* fall through */
1285             case POWERPC_MMU_BOOKE:
1286                 cs->exception_index = POWERPC_EXCP_ITLB;
1287                 env->error_code = 0;
1288                 env->spr[SPR_BOOKE_DEAR] = eaddr;
1289                 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1290                 break;
1291             case POWERPC_MMU_REAL:
1292                 cpu_abort(cs, "PowerPC in real mode should never raise "
1293                               "any MMU exceptions\n");
1294             default:
1295                 cpu_abort(cs, "Unknown or invalid MMU model\n");
1296             }
1297             break;
1298         case -2:
1299             /* Access rights violation */
1300             cs->exception_index = POWERPC_EXCP_ISI;
1301             if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1302                 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1303                 env->error_code = 0;
1304             } else {
1305                 env->error_code = 0x08000000;
1306             }
1307             break;
1308         case -3:
1309             /* No execute protection violation */
1310             if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1311                 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1312                 env->spr[SPR_BOOKE_ESR] = 0x00000000;
1313                 env->error_code = 0;
1314             } else {
1315                 env->error_code = 0x10000000;
1316             }
1317             cs->exception_index = POWERPC_EXCP_ISI;
1318             break;
1319         case -4:
1320             /* Direct store exception */
1321             /* No code fetch is allowed in direct-store areas */
1322             cs->exception_index = POWERPC_EXCP_ISI;
1323             if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1324                 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1325                 env->error_code = 0;
1326             } else {
1327                 env->error_code = 0x10000000;
1328             }
1329             break;
1330         }
1331     } else {
1332         switch (ret) {
1333         case -1:
1334             /* No matches in page tables or TLB */
1335             switch (env->mmu_model) {
1336             case POWERPC_MMU_SOFT_6xx:
1337                 if (access_type == MMU_DATA_STORE) {
1338                     cs->exception_index = POWERPC_EXCP_DSTLB;
1339                     env->error_code = 1 << 16;
1340                 } else {
1341                     cs->exception_index = POWERPC_EXCP_DLTLB;
1342                     env->error_code = 0;
1343                 }
1344                 env->spr[SPR_DMISS] = eaddr;
1345                 env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
1346             tlb_miss:
1347                 env->error_code |= ctx.key << 19;
1348                 env->spr[SPR_HASH1] = ppc_hash32_hpt_base(cpu) +
1349                   get_pteg_offset32(cpu, ctx.hash[0]);
1350                 env->spr[SPR_HASH2] = ppc_hash32_hpt_base(cpu) +
1351                   get_pteg_offset32(cpu, ctx.hash[1]);
1352                 break;
1353             case POWERPC_MMU_SOFT_4xx:
1354                 cs->exception_index = POWERPC_EXCP_DTLB;
1355                 env->error_code = 0;
1356                 env->spr[SPR_40x_DEAR] = eaddr;
1357                 if (access_type == MMU_DATA_STORE) {
1358                     env->spr[SPR_40x_ESR] = 0x00800000;
1359                 } else {
1360                     env->spr[SPR_40x_ESR] = 0x00000000;
1361                 }
1362                 break;
1363             case POWERPC_MMU_BOOKE206:
1364                 booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
1365                 /* fall through */
1366             case POWERPC_MMU_BOOKE:
1367                 cs->exception_index = POWERPC_EXCP_DTLB;
1368                 env->error_code = 0;
1369                 env->spr[SPR_BOOKE_DEAR] = eaddr;
1370                 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1371                 break;
1372             case POWERPC_MMU_REAL:
1373                 cpu_abort(cs, "PowerPC in real mode should never raise "
1374                               "any MMU exceptions\n");
1375             default:
1376                 cpu_abort(cs, "Unknown or invalid MMU model\n");
1377             }
1378             break;
1379         case -2:
1380             /* Access rights violation */
1381             cs->exception_index = POWERPC_EXCP_DSI;
1382             env->error_code = 0;
1383             if (env->mmu_model == POWERPC_MMU_SOFT_4xx) {
1384                 env->spr[SPR_40x_DEAR] = eaddr;
1385                 if (access_type == MMU_DATA_STORE) {
1386                     env->spr[SPR_40x_ESR] |= 0x00800000;
1387                 }
1388             } else if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1389                        (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1390                 env->spr[SPR_BOOKE_DEAR] = eaddr;
1391                 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1392             } else {
1393                 env->spr[SPR_DAR] = eaddr;
1394                 if (access_type == MMU_DATA_STORE) {
1395                     env->spr[SPR_DSISR] = 0x0A000000;
1396                 } else {
1397                     env->spr[SPR_DSISR] = 0x08000000;
1398                 }
1399             }
1400             break;
1401         case -4:
1402             /* Direct store exception */
1403             switch (type) {
1404             case ACCESS_FLOAT:
1405                 /* Floating point load/store */
1406                 cs->exception_index = POWERPC_EXCP_ALIGN;
1407                 env->error_code = POWERPC_EXCP_ALIGN_FP;
1408                 env->spr[SPR_DAR] = eaddr;
1409                 break;
1410             case ACCESS_RES:
1411                 /* lwarx, ldarx or stwcx. */
1412                 cs->exception_index = POWERPC_EXCP_DSI;
1413                 env->error_code = 0;
1414                 env->spr[SPR_DAR] = eaddr;
1415                 if (access_type == MMU_DATA_STORE) {
1416                     env->spr[SPR_DSISR] = 0x06000000;
1417                 } else {
1418                     env->spr[SPR_DSISR] = 0x04000000;
1419                 }
1420                 break;
1421             case ACCESS_EXT:
1422                 /* eciwx or ecowx */
1423                 cs->exception_index = POWERPC_EXCP_DSI;
1424                 env->error_code = 0;
1425                 env->spr[SPR_DAR] = eaddr;
1426                 if (access_type == MMU_DATA_STORE) {
1427                     env->spr[SPR_DSISR] = 0x06100000;
1428                 } else {
1429                     env->spr[SPR_DSISR] = 0x04100000;
1430                 }
1431                 break;
1432             default:
1433                 printf("DSI: invalid exception (%d)\n", ret);
1434                 cs->exception_index = POWERPC_EXCP_PROGRAM;
1435                 env->error_code = POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
1436                 env->spr[SPR_DAR] = eaddr;
1437                 break;
1438             }
1439             break;
1440         }
1441     }
1442     return false;
1443 }
1444 
1445 /*****************************************************************************/
1446 
1447 bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
1448                       hwaddr *raddrp, int *psizep, int *protp,
1449                       int mmu_idx, bool guest_visible)
1450 {
1451     switch (cpu->env.mmu_model) {
1452 #if defined(TARGET_PPC64)
1453     case POWERPC_MMU_3_00:
1454         if (ppc64_v3_radix(cpu)) {
1455             return ppc_radix64_xlate(cpu, eaddr, access_type, raddrp,
1456                                      psizep, protp, mmu_idx, guest_visible);
1457         }
1458         /* fall through */
1459     case POWERPC_MMU_64B:
1460     case POWERPC_MMU_2_03:
1461     case POWERPC_MMU_2_06:
1462     case POWERPC_MMU_2_07:
1463         return ppc_hash64_xlate(cpu, eaddr, access_type,
1464                                 raddrp, psizep, protp, mmu_idx, guest_visible);
1465 #endif
1466 
1467     case POWERPC_MMU_32B:
1468         return ppc_hash32_xlate(cpu, eaddr, access_type, raddrp,
1469                                psizep, protp, mmu_idx, guest_visible);
1470     case POWERPC_MMU_MPC8xx:
1471         cpu_abort(env_cpu(&cpu->env), "MPC8xx MMU model is not implemented\n");
1472     default:
1473         return ppc_jumbo_xlate(cpu, eaddr, access_type, raddrp,
1474                                psizep, protp, mmu_idx, guest_visible);
1475     }
1476 }
1477 
1478 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
1479 {
1480     PowerPCCPU *cpu = POWERPC_CPU(cs);
1481     hwaddr raddr;
1482     int s, p;
1483 
1484     /*
1485      * Some MMUs have separate TLBs for code and data. If we only
1486      * try an MMU_DATA_LOAD, we may not be able to read instructions
1487      * mapped by code TLBs, so we also try a MMU_INST_FETCH.
1488      */
1489     if (ppc_xlate(cpu, addr, MMU_DATA_LOAD, &raddr, &s, &p,
1490                   ppc_env_mmu_index(&cpu->env, false), false) ||
1491         ppc_xlate(cpu, addr, MMU_INST_FETCH, &raddr, &s, &p,
1492                   ppc_env_mmu_index(&cpu->env, true), false)) {
1493         return raddr & TARGET_PAGE_MASK;
1494     }
1495     return -1;
1496 }
1497