xref: /qemu/target/ppc/mmu_common.c (revision ba91e5d0276607fd6f862b498603f94c16ec0e07)
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, hwaddr *raddr,
638                                          int *prot, target_ulong address,
639                                          MMUAccessType access_type)
640 {
641     ppcemb_tlb_t *tlb;
642     int i, ret = -1;
643 
644     for (i = 0; i < env->nb_tlb; i++) {
645         tlb = &env->tlb.tlbe[i];
646         ret = mmubooke_check_tlb(env, tlb, raddr, prot, address,
647                                  access_type, i);
648         if (ret != -1) {
649             break;
650         }
651     }
652     qemu_log_mask(CPU_LOG_MMU,
653                   "%s: access %s " TARGET_FMT_lx " => " HWADDR_FMT_plx
654                   " %d %d\n", __func__, ret < 0 ? "refused" : "granted",
655                   address, ret < 0 ? -1 : *raddr, ret == -1 ? 0 : *prot, ret);
656     return ret;
657 }
658 
659 hwaddr booke206_tlb_to_page_size(CPUPPCState *env, ppcmas_tlb_t *tlb)
660 {
661     int tlbm_size;
662 
663     tlbm_size = (tlb->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
664 
665     return 1024ULL << tlbm_size;
666 }
667 
668 /* TLB check function for MAS based SoftTLBs */
669 int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb, hwaddr *raddrp,
670                      target_ulong address, uint32_t pid)
671 {
672     hwaddr mask;
673     uint32_t tlb_pid;
674 
675     if (!FIELD_EX64(env->msr, MSR, CM)) {
676         /* In 32bit mode we can only address 32bit EAs */
677         address = (uint32_t)address;
678     }
679 
680     /* Check valid flag */
681     if (!(tlb->mas1 & MAS1_VALID)) {
682         return -1;
683     }
684 
685     mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
686     qemu_log_mask(CPU_LOG_MMU, "%s: TLB ADDR=0x" TARGET_FMT_lx
687                   " PID=0x%x MAS1=0x%x MAS2=0x%" PRIx64 " mask=0x%"
688                   HWADDR_PRIx " MAS7_3=0x%" PRIx64 " MAS8=0x%" PRIx32 "\n",
689                   __func__, address, pid, tlb->mas1, tlb->mas2, mask,
690                   tlb->mas7_3, tlb->mas8);
691 
692     /* Check PID */
693     tlb_pid = (tlb->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT;
694     if (tlb_pid != 0 && tlb_pid != pid) {
695         return -1;
696     }
697 
698     /* Check effective address */
699     if ((address & mask) != (tlb->mas2 & MAS2_EPN_MASK)) {
700         return -1;
701     }
702 
703     if (raddrp) {
704         *raddrp = (tlb->mas7_3 & mask) | (address & ~mask);
705     }
706 
707     return 0;
708 }
709 
710 static bool is_epid_mmu(int mmu_idx)
711 {
712     return mmu_idx == PPC_TLB_EPID_STORE || mmu_idx == PPC_TLB_EPID_LOAD;
713 }
714 
715 static uint32_t mmubooke206_esr(int mmu_idx, MMUAccessType access_type)
716 {
717     uint32_t esr = 0;
718     if (access_type == MMU_DATA_STORE) {
719         esr |= ESR_ST;
720     }
721     if (is_epid_mmu(mmu_idx)) {
722         esr |= ESR_EPID;
723     }
724     return esr;
725 }
726 
727 /*
728  * Get EPID register given the mmu_idx. If this is regular load,
729  * construct the EPID access bits from current processor state
730  *
731  * Get the effective AS and PR bits and the PID. The PID is returned
732  * only if EPID load is requested, otherwise the caller must detect
733  * the correct EPID.  Return true if valid EPID is returned.
734  */
735 static bool mmubooke206_get_as(CPUPPCState *env,
736                                int mmu_idx, uint32_t *epid_out,
737                                bool *as_out, bool *pr_out)
738 {
739     if (is_epid_mmu(mmu_idx)) {
740         uint32_t epidr;
741         if (mmu_idx == PPC_TLB_EPID_STORE) {
742             epidr = env->spr[SPR_BOOKE_EPSC];
743         } else {
744             epidr = env->spr[SPR_BOOKE_EPLC];
745         }
746         *epid_out = (epidr & EPID_EPID) >> EPID_EPID_SHIFT;
747         *as_out = !!(epidr & EPID_EAS);
748         *pr_out = !!(epidr & EPID_EPR);
749         return true;
750     } else {
751         *as_out = FIELD_EX64(env->msr, MSR, DS);
752         *pr_out = FIELD_EX64(env->msr, MSR, PR);
753         return false;
754     }
755 }
756 
757 /* Check if the tlb found by hashing really matches */
758 static int mmubooke206_check_tlb(CPUPPCState *env, ppcmas_tlb_t *tlb,
759                                  hwaddr *raddr, int *prot,
760                                  target_ulong address,
761                                  MMUAccessType access_type, int mmu_idx)
762 {
763     uint32_t epid;
764     bool as, pr;
765     bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr);
766 
767     if (!use_epid) {
768         if (ppcmas_tlb_check(env, tlb, raddr, address,
769                              env->spr[SPR_BOOKE_PID]) >= 0) {
770             goto found_tlb;
771         }
772 
773         if (env->spr[SPR_BOOKE_PID1] &&
774             ppcmas_tlb_check(env, tlb, raddr, address,
775                              env->spr[SPR_BOOKE_PID1]) >= 0) {
776             goto found_tlb;
777         }
778 
779         if (env->spr[SPR_BOOKE_PID2] &&
780             ppcmas_tlb_check(env, tlb, raddr, address,
781                              env->spr[SPR_BOOKE_PID2]) >= 0) {
782             goto found_tlb;
783         }
784     } else {
785         if (ppcmas_tlb_check(env, tlb, raddr, address, epid) >= 0) {
786             goto found_tlb;
787         }
788     }
789 
790     qemu_log_mask(CPU_LOG_MMU, "%s: No TLB entry found for effective address "
791                   "0x" TARGET_FMT_lx "\n", __func__, address);
792     return -1;
793 
794 found_tlb:
795 
796     /* Check the address space and permissions */
797     if (access_type == MMU_INST_FETCH) {
798         /* There is no way to fetch code using epid load */
799         assert(!use_epid);
800         as = FIELD_EX64(env->msr, MSR, IR);
801     }
802 
803     if (as != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
804         qemu_log_mask(CPU_LOG_MMU, "%s: AS doesn't match\n", __func__);
805         return -1;
806     }
807 
808     *prot = 0;
809     if (pr) {
810         if (tlb->mas7_3 & MAS3_UR) {
811             *prot |= PAGE_READ;
812         }
813         if (tlb->mas7_3 & MAS3_UW) {
814             *prot |= PAGE_WRITE;
815         }
816         if (tlb->mas7_3 & MAS3_UX) {
817             *prot |= PAGE_EXEC;
818         }
819     } else {
820         if (tlb->mas7_3 & MAS3_SR) {
821             *prot |= PAGE_READ;
822         }
823         if (tlb->mas7_3 & MAS3_SW) {
824             *prot |= PAGE_WRITE;
825         }
826         if (tlb->mas7_3 & MAS3_SX) {
827             *prot |= PAGE_EXEC;
828         }
829     }
830     if (*prot & prot_for_access_type(access_type)) {
831         qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
832         return 0;
833     }
834 
835     qemu_log_mask(CPU_LOG_MMU, "%s: no prot match: %x\n", __func__, *prot);
836     return access_type == MMU_INST_FETCH ? -3 : -2;
837 }
838 
839 static int mmubooke206_get_physical_address(CPUPPCState *env, hwaddr *raddr,
840                                             int *prot, target_ulong address,
841                                             MMUAccessType access_type,
842                                             int mmu_idx)
843 {
844     ppcmas_tlb_t *tlb;
845     int i, j, ret = -1;
846 
847     for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
848         int ways = booke206_tlb_ways(env, i);
849         for (j = 0; j < ways; j++) {
850             tlb = booke206_get_tlbm(env, i, address, j);
851             if (!tlb) {
852                 continue;
853             }
854             ret = mmubooke206_check_tlb(env, tlb, raddr, prot, address,
855                                         access_type, mmu_idx);
856             if (ret != -1) {
857                 goto found_tlb;
858             }
859         }
860     }
861 
862 found_tlb:
863 
864     qemu_log_mask(CPU_LOG_MMU, "%s: access %s " TARGET_FMT_lx " => "
865                   HWADDR_FMT_plx " %d %d\n", __func__,
866                   ret < 0 ? "refused" : "granted", address,
867                   ret < 0 ? -1 : *raddr, ret == -1 ? 0 : *prot, ret);
868     return ret;
869 }
870 
871 static const char *book3e_tsize_to_str[32] = {
872     "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
873     "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M",
874     "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G",
875     "1T", "2T"
876 };
877 
878 static void mmubooke_dump_mmu(CPUPPCState *env)
879 {
880     ppcemb_tlb_t *entry;
881     int i;
882 
883 #ifdef CONFIG_KVM
884     if (kvm_enabled() && !env->kvm_sw_tlb) {
885         qemu_printf("Cannot access KVM TLB\n");
886         return;
887     }
888 #endif
889 
890     qemu_printf("\nTLB:\n");
891     qemu_printf("Effective          Physical           Size PID   Prot     "
892                 "Attr\n");
893 
894     entry = &env->tlb.tlbe[0];
895     for (i = 0; i < env->nb_tlb; i++, entry++) {
896         hwaddr ea, pa;
897         target_ulong mask;
898         uint64_t size = (uint64_t)entry->size;
899         char size_buf[20];
900 
901         /* Check valid flag */
902         if (!(entry->prot & PAGE_VALID)) {
903             continue;
904         }
905 
906         mask = ~(entry->size - 1);
907         ea = entry->EPN & mask;
908         pa = entry->RPN & mask;
909         /* Extend the physical address to 36 bits */
910         pa |= (hwaddr)(entry->RPN & 0xF) << 32;
911         if (size >= 1 * MiB) {
912             snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "M", size / MiB);
913         } else {
914             snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "k", size / KiB);
915         }
916         qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %s %-5u %08x %08x\n",
917                     (uint64_t)ea, (uint64_t)pa, size_buf, (uint32_t)entry->PID,
918                     entry->prot, entry->attr);
919     }
920 
921 }
922 
923 static void mmubooke206_dump_one_tlb(CPUPPCState *env, int tlbn, int offset,
924                                      int tlbsize)
925 {
926     ppcmas_tlb_t *entry;
927     int i;
928 
929     qemu_printf("\nTLB%d:\n", tlbn);
930     qemu_printf("Effective          Physical           Size TID   TS SRWX"
931                 " URWX WIMGE U0123\n");
932 
933     entry = &env->tlb.tlbm[offset];
934     for (i = 0; i < tlbsize; i++, entry++) {
935         hwaddr ea, pa, size;
936         int tsize;
937 
938         if (!(entry->mas1 & MAS1_VALID)) {
939             continue;
940         }
941 
942         tsize = (entry->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
943         size = 1024ULL << tsize;
944         ea = entry->mas2 & ~(size - 1);
945         pa = entry->mas7_3 & ~(size - 1);
946 
947         qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u  S%c%c%c"
948                     " U%c%c%c %c%c%c%c%c U%c%c%c%c\n",
949                     (uint64_t)ea, (uint64_t)pa,
950                     book3e_tsize_to_str[tsize],
951                     (entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT,
952                     (entry->mas1 & MAS1_TS) >> MAS1_TS_SHIFT,
953                     entry->mas7_3 & MAS3_SR ? 'R' : '-',
954                     entry->mas7_3 & MAS3_SW ? 'W' : '-',
955                     entry->mas7_3 & MAS3_SX ? 'X' : '-',
956                     entry->mas7_3 & MAS3_UR ? 'R' : '-',
957                     entry->mas7_3 & MAS3_UW ? 'W' : '-',
958                     entry->mas7_3 & MAS3_UX ? 'X' : '-',
959                     entry->mas2 & MAS2_W ? 'W' : '-',
960                     entry->mas2 & MAS2_I ? 'I' : '-',
961                     entry->mas2 & MAS2_M ? 'M' : '-',
962                     entry->mas2 & MAS2_G ? 'G' : '-',
963                     entry->mas2 & MAS2_E ? 'E' : '-',
964                     entry->mas7_3 & MAS3_U0 ? '0' : '-',
965                     entry->mas7_3 & MAS3_U1 ? '1' : '-',
966                     entry->mas7_3 & MAS3_U2 ? '2' : '-',
967                     entry->mas7_3 & MAS3_U3 ? '3' : '-');
968     }
969 }
970 
971 static void mmubooke206_dump_mmu(CPUPPCState *env)
972 {
973     int offset = 0;
974     int i;
975 
976 #ifdef CONFIG_KVM
977     if (kvm_enabled() && !env->kvm_sw_tlb) {
978         qemu_printf("Cannot access KVM TLB\n");
979         return;
980     }
981 #endif
982 
983     for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
984         int size = booke206_tlb_size(env, i);
985 
986         if (size == 0) {
987             continue;
988         }
989 
990         mmubooke206_dump_one_tlb(env, i, offset, size);
991         offset += size;
992     }
993 }
994 
995 static void mmu6xx_dump_BATs(CPUPPCState *env, int type)
996 {
997     target_ulong *BATlt, *BATut, *BATu, *BATl;
998     target_ulong BEPIl, BEPIu, bl;
999     int i;
1000 
1001     switch (type) {
1002     case ACCESS_CODE:
1003         BATlt = env->IBAT[1];
1004         BATut = env->IBAT[0];
1005         break;
1006     default:
1007         BATlt = env->DBAT[1];
1008         BATut = env->DBAT[0];
1009         break;
1010     }
1011 
1012     for (i = 0; i < env->nb_BATs; i++) {
1013         BATu = &BATut[i];
1014         BATl = &BATlt[i];
1015         BEPIu = *BATu & 0xF0000000;
1016         BEPIl = *BATu & 0x0FFE0000;
1017         bl = (*BATu & 0x00001FFC) << 15;
1018         qemu_printf("%s BAT%d BATu " TARGET_FMT_lx
1019                     " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
1020                     TARGET_FMT_lx " " TARGET_FMT_lx "\n",
1021                     type == ACCESS_CODE ? "code" : "data", i,
1022                     *BATu, *BATl, BEPIu, BEPIl, bl);
1023     }
1024 }
1025 
1026 static void mmu6xx_dump_mmu(CPUPPCState *env)
1027 {
1028     PowerPCCPU *cpu = env_archcpu(env);
1029     ppc6xx_tlb_t *tlb;
1030     target_ulong sr;
1031     int type, way, entry, i;
1032 
1033     qemu_printf("HTAB base = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_base(cpu));
1034     qemu_printf("HTAB mask = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_mask(cpu));
1035 
1036     qemu_printf("\nSegment registers:\n");
1037     for (i = 0; i < 32; i++) {
1038         sr = env->sr[i];
1039         if (sr & 0x80000000) {
1040             qemu_printf("%02d T=%d Ks=%d Kp=%d BUID=0x%03x "
1041                         "CNTLR_SPEC=0x%05x\n", i,
1042                         sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
1043                         sr & 0x20000000 ? 1 : 0, (uint32_t)((sr >> 20) & 0x1FF),
1044                         (uint32_t)(sr & 0xFFFFF));
1045         } else {
1046             qemu_printf("%02d T=%d Ks=%d Kp=%d N=%d VSID=0x%06x\n", i,
1047                         sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
1048                         sr & 0x20000000 ? 1 : 0, sr & 0x10000000 ? 1 : 0,
1049                         (uint32_t)(sr & 0x00FFFFFF));
1050         }
1051     }
1052 
1053     qemu_printf("\nBATs:\n");
1054     mmu6xx_dump_BATs(env, ACCESS_INT);
1055     mmu6xx_dump_BATs(env, ACCESS_CODE);
1056 
1057     if (env->id_tlbs != 1) {
1058         qemu_printf("ERROR: 6xx MMU should have separated TLB"
1059                     " for code and data\n");
1060     }
1061 
1062     qemu_printf("\nTLBs                       [EPN    EPN + SIZE]\n");
1063 
1064     for (type = 0; type < 2; type++) {
1065         for (way = 0; way < env->nb_ways; way++) {
1066             for (entry = env->nb_tlb * type + env->tlb_per_way * way;
1067                  entry < (env->nb_tlb * type + env->tlb_per_way * (way + 1));
1068                  entry++) {
1069 
1070                 tlb = &env->tlb.tlb6[entry];
1071                 qemu_printf("%s TLB %02d/%02d way:%d %s ["
1072                             TARGET_FMT_lx " " TARGET_FMT_lx "]\n",
1073                             type ? "code" : "data", entry % env->nb_tlb,
1074                             env->nb_tlb, way,
1075                             pte_is_valid(tlb->pte0) ? "valid" : "inval",
1076                             tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE);
1077             }
1078         }
1079     }
1080 }
1081 
1082 void dump_mmu(CPUPPCState *env)
1083 {
1084     switch (env->mmu_model) {
1085     case POWERPC_MMU_BOOKE:
1086         mmubooke_dump_mmu(env);
1087         break;
1088     case POWERPC_MMU_BOOKE206:
1089         mmubooke206_dump_mmu(env);
1090         break;
1091     case POWERPC_MMU_SOFT_6xx:
1092         mmu6xx_dump_mmu(env);
1093         break;
1094 #if defined(TARGET_PPC64)
1095     case POWERPC_MMU_64B:
1096     case POWERPC_MMU_2_03:
1097     case POWERPC_MMU_2_06:
1098     case POWERPC_MMU_2_07:
1099         dump_slb(env_archcpu(env));
1100         break;
1101     case POWERPC_MMU_3_00:
1102         if (ppc64_v3_radix(env_archcpu(env))) {
1103             qemu_log_mask(LOG_UNIMP, "%s: the PPC64 MMU is unsupported\n",
1104                           __func__);
1105         } else {
1106             dump_slb(env_archcpu(env));
1107         }
1108         break;
1109 #endif
1110     default:
1111         qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__);
1112     }
1113 }
1114 
1115 int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
1116                                      target_ulong eaddr,
1117                                      MMUAccessType access_type, int type,
1118                                      int mmu_idx)
1119 {
1120     bool real_mode = (type == ACCESS_CODE) ? !FIELD_EX64(env->msr, MSR, IR)
1121                                            : !FIELD_EX64(env->msr, MSR, DR);
1122     if (real_mode) {
1123         ctx->raddr = eaddr;
1124         ctx->prot = PAGE_RWX;
1125         return 0;
1126     }
1127 
1128     switch (env->mmu_model) {
1129     case POWERPC_MMU_SOFT_6xx:
1130         return mmu6xx_get_physical_address(env, ctx, eaddr, access_type, type);
1131     case POWERPC_MMU_SOFT_4xx:
1132         return mmu40x_get_physical_address(env, &ctx->raddr, &ctx->prot, eaddr,
1133                                            access_type);
1134     case POWERPC_MMU_REAL:
1135         cpu_abort(env_cpu(env),
1136                   "PowerPC in real mode do not do any translation\n");
1137     default:
1138         cpu_abort(env_cpu(env), "Unknown or invalid MMU model\n");
1139     }
1140 }
1141 
1142 static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
1143                                          MMUAccessType access_type, int mmu_idx)
1144 {
1145     uint32_t epid;
1146     bool as, pr;
1147     uint32_t missed_tid = 0;
1148     bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr);
1149 
1150     if (access_type == MMU_INST_FETCH) {
1151         as = FIELD_EX64(env->msr, MSR, IR);
1152     }
1153     env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK;
1154     env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK;
1155     env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK;
1156     env->spr[SPR_BOOKE_MAS3] = 0;
1157     env->spr[SPR_BOOKE_MAS6] = 0;
1158     env->spr[SPR_BOOKE_MAS7] = 0;
1159 
1160     /* AS */
1161     if (as) {
1162         env->spr[SPR_BOOKE_MAS1] |= MAS1_TS;
1163         env->spr[SPR_BOOKE_MAS6] |= MAS6_SAS;
1164     }
1165 
1166     env->spr[SPR_BOOKE_MAS1] |= MAS1_VALID;
1167     env->spr[SPR_BOOKE_MAS2] |= address & MAS2_EPN_MASK;
1168 
1169     if (!use_epid) {
1170         switch (env->spr[SPR_BOOKE_MAS4] & MAS4_TIDSELD_PIDZ) {
1171         case MAS4_TIDSELD_PID0:
1172             missed_tid = env->spr[SPR_BOOKE_PID];
1173             break;
1174         case MAS4_TIDSELD_PID1:
1175             missed_tid = env->spr[SPR_BOOKE_PID1];
1176             break;
1177         case MAS4_TIDSELD_PID2:
1178             missed_tid = env->spr[SPR_BOOKE_PID2];
1179             break;
1180         }
1181         env->spr[SPR_BOOKE_MAS6] |= env->spr[SPR_BOOKE_PID] << 16;
1182     } else {
1183         missed_tid = epid;
1184         env->spr[SPR_BOOKE_MAS6] |= missed_tid << 16;
1185     }
1186     env->spr[SPR_BOOKE_MAS1] |= (missed_tid << MAS1_TID_SHIFT);
1187 
1188 
1189     /* next victim logic */
1190     env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
1191     env->last_way++;
1192     env->last_way &= booke206_tlb_ways(env, 0) - 1;
1193     env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
1194 }
1195 
1196 static bool ppc_booke_xlate(PowerPCCPU *cpu, vaddr eaddr,
1197                             MMUAccessType access_type,
1198                             hwaddr *raddrp, int *psizep, int *protp,
1199                             int mmu_idx, bool guest_visible)
1200 {
1201     CPUState *cs = CPU(cpu);
1202     CPUPPCState *env = &cpu->env;
1203     hwaddr raddr;
1204     int prot, ret;
1205 
1206     if (env->mmu_model == POWERPC_MMU_BOOKE206) {
1207         ret = mmubooke206_get_physical_address(env, &raddr, &prot, eaddr,
1208                                                access_type, mmu_idx);
1209     } else {
1210         ret = mmubooke_get_physical_address(env, &raddr, &prot, eaddr,
1211                                             access_type);
1212     }
1213     if (ret == 0) {
1214         *raddrp = raddr;
1215         *protp = prot;
1216         *psizep = TARGET_PAGE_BITS;
1217         return true;
1218     } else if (!guest_visible) {
1219         return false;
1220     }
1221 
1222     log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
1223     if (access_type == MMU_INST_FETCH) {
1224         switch (ret) {
1225         case -1:
1226             /* No matches in page tables or TLB */
1227             switch (env->mmu_model) {
1228             case POWERPC_MMU_BOOKE206:
1229                 booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
1230                 /* fall through */
1231             case POWERPC_MMU_BOOKE:
1232                 cs->exception_index = POWERPC_EXCP_ITLB;
1233                 env->error_code = 0;
1234                 env->spr[SPR_BOOKE_DEAR] = eaddr;
1235                 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1236                 break;
1237             default:
1238                 g_assert_not_reached();
1239             }
1240             break;
1241         case -2:
1242             /* Access rights violation */
1243             cs->exception_index = POWERPC_EXCP_ISI;
1244             env->error_code = 0;
1245             break;
1246         case -3:
1247             /* No execute protection violation */
1248             cs->exception_index = POWERPC_EXCP_ISI;
1249             env->spr[SPR_BOOKE_ESR] = 0;
1250             env->error_code = 0;
1251             break;
1252         }
1253     } else {
1254         switch (ret) {
1255         case -1:
1256             /* No matches in page tables or TLB */
1257             switch (env->mmu_model) {
1258             case POWERPC_MMU_BOOKE206:
1259                 booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
1260                 /* fall through */
1261             case POWERPC_MMU_BOOKE:
1262                 cs->exception_index = POWERPC_EXCP_DTLB;
1263                 env->error_code = 0;
1264                 env->spr[SPR_BOOKE_DEAR] = eaddr;
1265                 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1266                 break;
1267             default:
1268                 g_assert_not_reached();
1269             }
1270             break;
1271         case -2:
1272             /* Access rights violation */
1273             cs->exception_index = POWERPC_EXCP_DSI;
1274             env->error_code = 0;
1275             env->spr[SPR_BOOKE_DEAR] = eaddr;
1276             env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1277             break;
1278         }
1279     }
1280     return false;
1281 }
1282 
1283 /* Perform address translation */
1284 /* TODO: Split this by mmu_model. */
1285 static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
1286                             MMUAccessType access_type,
1287                             hwaddr *raddrp, int *psizep, int *protp,
1288                             int mmu_idx, bool guest_visible)
1289 {
1290     CPUState *cs = CPU(cpu);
1291     CPUPPCState *env = &cpu->env;
1292     mmu_ctx_t ctx;
1293     int type;
1294     int ret;
1295 
1296     if (access_type == MMU_INST_FETCH) {
1297         /* code access */
1298         type = ACCESS_CODE;
1299     } else if (guest_visible) {
1300         /* data access */
1301         type = env->access_type;
1302     } else {
1303         type = ACCESS_INT;
1304     }
1305 
1306     ret = get_physical_address_wtlb(env, &ctx, eaddr, access_type,
1307                                     type, mmu_idx);
1308     if (ret == 0) {
1309         *raddrp = ctx.raddr;
1310         *protp = ctx.prot;
1311         *psizep = TARGET_PAGE_BITS;
1312         return true;
1313     } else if (!guest_visible) {
1314         return false;
1315     }
1316 
1317     log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
1318     if (type == ACCESS_CODE) {
1319         switch (ret) {
1320         case -1:
1321             /* No matches in page tables or TLB */
1322             switch (env->mmu_model) {
1323             case POWERPC_MMU_SOFT_6xx:
1324                 cs->exception_index = POWERPC_EXCP_IFTLB;
1325                 env->error_code = 1 << 18;
1326                 env->spr[SPR_IMISS] = eaddr;
1327                 env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
1328                 goto tlb_miss;
1329             case POWERPC_MMU_SOFT_4xx:
1330                 cs->exception_index = POWERPC_EXCP_ITLB;
1331                 env->error_code = 0;
1332                 env->spr[SPR_40x_DEAR] = eaddr;
1333                 env->spr[SPR_40x_ESR] = 0x00000000;
1334                 break;
1335             case POWERPC_MMU_REAL:
1336                 cpu_abort(cs, "PowerPC in real mode should never raise "
1337                               "any MMU exceptions\n");
1338             default:
1339                 cpu_abort(cs, "Unknown or invalid MMU model\n");
1340             }
1341             break;
1342         case -2:
1343             /* Access rights violation */
1344             cs->exception_index = POWERPC_EXCP_ISI;
1345             env->error_code = 0x08000000;
1346             break;
1347         case -3:
1348             /* No execute protection violation */
1349             cs->exception_index = POWERPC_EXCP_ISI;
1350             env->error_code = 0x10000000;
1351             break;
1352         case -4:
1353             /* Direct store exception */
1354             /* No code fetch is allowed in direct-store areas */
1355             cs->exception_index = POWERPC_EXCP_ISI;
1356             env->error_code = 0x10000000;
1357             break;
1358         }
1359     } else {
1360         switch (ret) {
1361         case -1:
1362             /* No matches in page tables or TLB */
1363             switch (env->mmu_model) {
1364             case POWERPC_MMU_SOFT_6xx:
1365                 if (access_type == MMU_DATA_STORE) {
1366                     cs->exception_index = POWERPC_EXCP_DSTLB;
1367                     env->error_code = 1 << 16;
1368                 } else {
1369                     cs->exception_index = POWERPC_EXCP_DLTLB;
1370                     env->error_code = 0;
1371                 }
1372                 env->spr[SPR_DMISS] = eaddr;
1373                 env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
1374             tlb_miss:
1375                 env->error_code |= ctx.key << 19;
1376                 env->spr[SPR_HASH1] = ppc_hash32_hpt_base(cpu) +
1377                   get_pteg_offset32(cpu, ctx.hash[0]);
1378                 env->spr[SPR_HASH2] = ppc_hash32_hpt_base(cpu) +
1379                   get_pteg_offset32(cpu, ctx.hash[1]);
1380                 break;
1381             case POWERPC_MMU_SOFT_4xx:
1382                 cs->exception_index = POWERPC_EXCP_DTLB;
1383                 env->error_code = 0;
1384                 env->spr[SPR_40x_DEAR] = eaddr;
1385                 if (access_type == MMU_DATA_STORE) {
1386                     env->spr[SPR_40x_ESR] = 0x00800000;
1387                 } else {
1388                     env->spr[SPR_40x_ESR] = 0x00000000;
1389                 }
1390                 break;
1391             case POWERPC_MMU_REAL:
1392                 cpu_abort(cs, "PowerPC in real mode should never raise "
1393                               "any MMU exceptions\n");
1394             default:
1395                 cpu_abort(cs, "Unknown or invalid MMU model\n");
1396             }
1397             break;
1398         case -2:
1399             /* Access rights violation */
1400             cs->exception_index = POWERPC_EXCP_DSI;
1401             env->error_code = 0;
1402             if (env->mmu_model == POWERPC_MMU_SOFT_4xx) {
1403                 env->spr[SPR_40x_DEAR] = eaddr;
1404                 if (access_type == MMU_DATA_STORE) {
1405                     env->spr[SPR_40x_ESR] |= 0x00800000;
1406                 }
1407             } else {
1408                 env->spr[SPR_DAR] = eaddr;
1409                 if (access_type == MMU_DATA_STORE) {
1410                     env->spr[SPR_DSISR] = 0x0A000000;
1411                 } else {
1412                     env->spr[SPR_DSISR] = 0x08000000;
1413                 }
1414             }
1415             break;
1416         case -4:
1417             /* Direct store exception */
1418             switch (type) {
1419             case ACCESS_FLOAT:
1420                 /* Floating point load/store */
1421                 cs->exception_index = POWERPC_EXCP_ALIGN;
1422                 env->error_code = POWERPC_EXCP_ALIGN_FP;
1423                 env->spr[SPR_DAR] = eaddr;
1424                 break;
1425             case ACCESS_RES:
1426                 /* lwarx, ldarx or stwcx. */
1427                 cs->exception_index = POWERPC_EXCP_DSI;
1428                 env->error_code = 0;
1429                 env->spr[SPR_DAR] = eaddr;
1430                 if (access_type == MMU_DATA_STORE) {
1431                     env->spr[SPR_DSISR] = 0x06000000;
1432                 } else {
1433                     env->spr[SPR_DSISR] = 0x04000000;
1434                 }
1435                 break;
1436             case ACCESS_EXT:
1437                 /* eciwx or ecowx */
1438                 cs->exception_index = POWERPC_EXCP_DSI;
1439                 env->error_code = 0;
1440                 env->spr[SPR_DAR] = eaddr;
1441                 if (access_type == MMU_DATA_STORE) {
1442                     env->spr[SPR_DSISR] = 0x06100000;
1443                 } else {
1444                     env->spr[SPR_DSISR] = 0x04100000;
1445                 }
1446                 break;
1447             default:
1448                 printf("DSI: invalid exception (%d)\n", ret);
1449                 cs->exception_index = POWERPC_EXCP_PROGRAM;
1450                 env->error_code = POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
1451                 env->spr[SPR_DAR] = eaddr;
1452                 break;
1453             }
1454             break;
1455         }
1456     }
1457     return false;
1458 }
1459 
1460 /*****************************************************************************/
1461 
1462 bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
1463                       hwaddr *raddrp, int *psizep, int *protp,
1464                       int mmu_idx, bool guest_visible)
1465 {
1466     switch (cpu->env.mmu_model) {
1467 #if defined(TARGET_PPC64)
1468     case POWERPC_MMU_3_00:
1469         if (ppc64_v3_radix(cpu)) {
1470             return ppc_radix64_xlate(cpu, eaddr, access_type, raddrp,
1471                                      psizep, protp, mmu_idx, guest_visible);
1472         }
1473         /* fall through */
1474     case POWERPC_MMU_64B:
1475     case POWERPC_MMU_2_03:
1476     case POWERPC_MMU_2_06:
1477     case POWERPC_MMU_2_07:
1478         return ppc_hash64_xlate(cpu, eaddr, access_type,
1479                                 raddrp, psizep, protp, mmu_idx, guest_visible);
1480 #endif
1481 
1482     case POWERPC_MMU_32B:
1483         return ppc_hash32_xlate(cpu, eaddr, access_type, raddrp,
1484                                psizep, protp, mmu_idx, guest_visible);
1485     case POWERPC_MMU_BOOKE:
1486     case POWERPC_MMU_BOOKE206:
1487         return ppc_booke_xlate(cpu, eaddr, access_type, raddrp,
1488                                psizep, protp, mmu_idx, guest_visible);
1489     case POWERPC_MMU_MPC8xx:
1490         cpu_abort(env_cpu(&cpu->env), "MPC8xx MMU model is not implemented\n");
1491     default:
1492         return ppc_jumbo_xlate(cpu, eaddr, access_type, raddrp,
1493                                psizep, protp, mmu_idx, guest_visible);
1494     }
1495 }
1496 
1497 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
1498 {
1499     PowerPCCPU *cpu = POWERPC_CPU(cs);
1500     hwaddr raddr;
1501     int s, p;
1502 
1503     /*
1504      * Some MMUs have separate TLBs for code and data. If we only
1505      * try an MMU_DATA_LOAD, we may not be able to read instructions
1506      * mapped by code TLBs, so we also try a MMU_INST_FETCH.
1507      */
1508     if (ppc_xlate(cpu, addr, MMU_DATA_LOAD, &raddr, &s, &p,
1509                   ppc_env_mmu_index(&cpu->env, false), false) ||
1510         ppc_xlate(cpu, addr, MMU_INST_FETCH, &raddr, &s, &p,
1511                   ppc_env_mmu_index(&cpu->env, true), false)) {
1512         return raddr & TARGET_PAGE_MASK;
1513     }
1514     return -1;
1515 }
1516