xref: /qemu/target/ppc/mmu_helper.c (revision f9734d5d)
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/log.h"
29 #include "helper_regs.h"
30 #include "qemu/error-report.h"
31 #include "qemu/main-loop.h"
32 #include "qemu/qemu-print.h"
33 #include "internal.h"
34 #include "mmu-book3s-v3.h"
35 #include "mmu-radix64.h"
36 
37 #ifdef CONFIG_TCG
38 #include "exec/helper-proto.h"
39 #include "exec/cpu_ldst.h"
40 #endif
41 /* #define DEBUG_MMU */
42 /* #define DEBUG_BATS */
43 /* #define DEBUG_SOFTWARE_TLB */
44 /* #define DUMP_PAGE_TABLES */
45 /* #define FLUSH_ALL_TLBS */
46 
47 #ifdef DEBUG_MMU
48 #  define LOG_MMU_STATE(cpu) log_cpu_state_mask(CPU_LOG_MMU, (cpu), 0)
49 #else
50 #  define LOG_MMU_STATE(cpu) do { } while (0)
51 #endif
52 
53 #ifdef DEBUG_SOFTWARE_TLB
54 #  define LOG_SWTLB(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__)
55 #else
56 #  define LOG_SWTLB(...) do { } while (0)
57 #endif
58 
59 #ifdef DEBUG_BATS
60 #  define LOG_BATS(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__)
61 #else
62 #  define LOG_BATS(...) do { } while (0)
63 #endif
64 
65 /*****************************************************************************/
66 /* PowerPC MMU emulation */
67 
68 /* Context used internally during MMU translations */
69 typedef struct mmu_ctx_t mmu_ctx_t;
70 struct mmu_ctx_t {
71     hwaddr raddr;      /* Real address              */
72     hwaddr eaddr;      /* Effective address         */
73     int prot;                      /* Protection bits           */
74     hwaddr hash[2];    /* Pagetable hash values     */
75     target_ulong ptem;             /* Virtual segment ID | API  */
76     int key;                       /* Access key                */
77     int nx;                        /* Non-execute area          */
78 };
79 
80 /* Common routines used by software and hardware TLBs emulation */
81 static inline int pte_is_valid(target_ulong pte0)
82 {
83     return pte0 & 0x80000000 ? 1 : 0;
84 }
85 
86 static inline void pte_invalidate(target_ulong *pte0)
87 {
88     *pte0 &= ~0x80000000;
89 }
90 
91 #define PTE_PTEM_MASK 0x7FFFFFBF
92 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
93 
94 static int pp_check(int key, int pp, int nx)
95 {
96     int access;
97 
98     /* Compute access rights */
99     access = 0;
100     if (key == 0) {
101         switch (pp) {
102         case 0x0:
103         case 0x1:
104         case 0x2:
105             access |= PAGE_WRITE;
106             /* fall through */
107         case 0x3:
108             access |= PAGE_READ;
109             break;
110         }
111     } else {
112         switch (pp) {
113         case 0x0:
114             access = 0;
115             break;
116         case 0x1:
117         case 0x3:
118             access = PAGE_READ;
119             break;
120         case 0x2:
121             access = PAGE_READ | PAGE_WRITE;
122             break;
123         }
124     }
125     if (nx == 0) {
126         access |= PAGE_EXEC;
127     }
128 
129     return access;
130 }
131 
132 static int check_prot(int prot, MMUAccessType access_type)
133 {
134     return prot & prot_for_access_type(access_type) ? 0 : -2;
135 }
136 
137 static int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0,
138                                 target_ulong pte1, int h,
139                                 MMUAccessType access_type)
140 {
141     target_ulong ptem, mmask;
142     int access, ret, pteh, ptev, pp;
143 
144     ret = -1;
145     /* Check validity and table match */
146     ptev = pte_is_valid(pte0);
147     pteh = (pte0 >> 6) & 1;
148     if (ptev && h == pteh) {
149         /* Check vsid & api */
150         ptem = pte0 & PTE_PTEM_MASK;
151         mmask = PTE_CHECK_MASK;
152         pp = pte1 & 0x00000003;
153         if (ptem == ctx->ptem) {
154             if (ctx->raddr != (hwaddr)-1ULL) {
155                 /* all matches should have equal RPN, WIMG & PP */
156                 if ((ctx->raddr & mmask) != (pte1 & mmask)) {
157                     qemu_log_mask(CPU_LOG_MMU, "Bad RPN/WIMG/PP\n");
158                     return -3;
159                 }
160             }
161             /* Compute access rights */
162             access = pp_check(ctx->key, pp, ctx->nx);
163             /* Keep the matching PTE information */
164             ctx->raddr = pte1;
165             ctx->prot = access;
166             ret = check_prot(ctx->prot, access_type);
167             if (ret == 0) {
168                 /* Access granted */
169                 qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n");
170             } else {
171                 /* Access right violation */
172                 qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
173             }
174         }
175     }
176 
177     return ret;
178 }
179 
180 static int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
181                             int ret, MMUAccessType access_type)
182 {
183     int store = 0;
184 
185     /* Update page flags */
186     if (!(*pte1p & 0x00000100)) {
187         /* Update accessed flag */
188         *pte1p |= 0x00000100;
189         store = 1;
190     }
191     if (!(*pte1p & 0x00000080)) {
192         if (access_type == MMU_DATA_STORE && ret == 0) {
193             /* Update changed flag */
194             *pte1p |= 0x00000080;
195             store = 1;
196         } else {
197             /* Force page fault for first write access */
198             ctx->prot &= ~PAGE_WRITE;
199         }
200     }
201 
202     return store;
203 }
204 
205 /* Software driven TLB helpers */
206 static inline int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
207                                     int way, int is_code)
208 {
209     int nr;
210 
211     /* Select TLB num in a way from address */
212     nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1);
213     /* Select TLB way */
214     nr += env->tlb_per_way * way;
215     /* 6xx have separate TLBs for instructions and data */
216     if (is_code && env->id_tlbs == 1) {
217         nr += env->nb_tlb;
218     }
219 
220     return nr;
221 }
222 
223 static inline void ppc6xx_tlb_invalidate_all(CPUPPCState *env)
224 {
225     ppc6xx_tlb_t *tlb;
226     int nr, max;
227 
228     /* LOG_SWTLB("Invalidate all TLBs\n"); */
229     /* Invalidate all defined software TLB */
230     max = env->nb_tlb;
231     if (env->id_tlbs == 1) {
232         max *= 2;
233     }
234     for (nr = 0; nr < max; nr++) {
235         tlb = &env->tlb.tlb6[nr];
236         pte_invalidate(&tlb->pte0);
237     }
238     tlb_flush(env_cpu(env));
239 }
240 
241 static inline void ppc6xx_tlb_invalidate_virt2(CPUPPCState *env,
242                                                target_ulong eaddr,
243                                                int is_code, int match_epn)
244 {
245 #if !defined(FLUSH_ALL_TLBS)
246     CPUState *cs = env_cpu(env);
247     ppc6xx_tlb_t *tlb;
248     int way, nr;
249 
250     /* Invalidate ITLB + DTLB, all ways */
251     for (way = 0; way < env->nb_ways; way++) {
252         nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code);
253         tlb = &env->tlb.tlb6[nr];
254         if (pte_is_valid(tlb->pte0) && (match_epn == 0 || eaddr == tlb->EPN)) {
255             LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx "\n", nr,
256                       env->nb_tlb, eaddr);
257             pte_invalidate(&tlb->pte0);
258             tlb_flush_page(cs, tlb->EPN);
259         }
260     }
261 #else
262     /* XXX: PowerPC specification say this is valid as well */
263     ppc6xx_tlb_invalidate_all(env);
264 #endif
265 }
266 
267 static inline void ppc6xx_tlb_invalidate_virt(CPUPPCState *env,
268                                               target_ulong eaddr, int is_code)
269 {
270     ppc6xx_tlb_invalidate_virt2(env, eaddr, is_code, 0);
271 }
272 
273 #ifdef CONFIG_TCG
274 static void ppc6xx_tlb_store(CPUPPCState *env, target_ulong EPN, int way,
275                              int is_code, target_ulong pte0, target_ulong pte1)
276 {
277     ppc6xx_tlb_t *tlb;
278     int nr;
279 
280     nr = ppc6xx_tlb_getnum(env, EPN, way, is_code);
281     tlb = &env->tlb.tlb6[nr];
282     LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx
283               " PTE1 " TARGET_FMT_lx "\n", nr, env->nb_tlb, EPN, pte0, pte1);
284     /* Invalidate any pending reference in QEMU for this virtual address */
285     ppc6xx_tlb_invalidate_virt2(env, EPN, is_code, 1);
286     tlb->pte0 = pte0;
287     tlb->pte1 = pte1;
288     tlb->EPN = EPN;
289     /* Store last way for LRU mechanism */
290     env->last_way = way;
291 }
292 #endif
293 
294 static int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx,
295                             target_ulong eaddr, MMUAccessType access_type)
296 {
297     ppc6xx_tlb_t *tlb;
298     int nr, best, way;
299     int ret;
300 
301     best = -1;
302     ret = -1; /* No TLB found */
303     for (way = 0; way < env->nb_ways; way++) {
304         nr = ppc6xx_tlb_getnum(env, eaddr, way, access_type == MMU_INST_FETCH);
305         tlb = &env->tlb.tlb6[nr];
306         /* This test "emulates" the PTE index match for hardware TLBs */
307         if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) {
308             LOG_SWTLB("TLB %d/%d %s [" TARGET_FMT_lx " " TARGET_FMT_lx
309                       "] <> " TARGET_FMT_lx "\n", nr, env->nb_tlb,
310                       pte_is_valid(tlb->pte0) ? "valid" : "inval",
311                       tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr);
312             continue;
313         }
314         LOG_SWTLB("TLB %d/%d %s " TARGET_FMT_lx " <> " TARGET_FMT_lx " "
315                   TARGET_FMT_lx " %c %c\n", nr, env->nb_tlb,
316                   pte_is_valid(tlb->pte0) ? "valid" : "inval",
317                   tlb->EPN, eaddr, tlb->pte1,
318                   access_type == MMU_DATA_STORE ? 'S' : 'L',
319                   access_type == MMU_INST_FETCH ? 'I' : 'D');
320         switch (ppc6xx_tlb_pte_check(ctx, tlb->pte0, tlb->pte1,
321                                      0, access_type)) {
322         case -3:
323             /* TLB inconsistency */
324             return -1;
325         case -2:
326             /* Access violation */
327             ret = -2;
328             best = nr;
329             break;
330         case -1:
331         default:
332             /* No match */
333             break;
334         case 0:
335             /* access granted */
336             /*
337              * XXX: we should go on looping to check all TLBs
338              *      consistency but we can speed-up the whole thing as
339              *      the result would be undefined if TLBs are not
340              *      consistent.
341              */
342             ret = 0;
343             best = nr;
344             goto done;
345         }
346     }
347     if (best != -1) {
348     done:
349         LOG_SWTLB("found TLB at addr " TARGET_FMT_plx " prot=%01x ret=%d\n",
350                   ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
351         /* Update page flags */
352         pte_update_flags(ctx, &env->tlb.tlb6[best].pte1, ret, access_type);
353     }
354 
355     return ret;
356 }
357 
358 /* Perform BAT hit & translation */
359 static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp,
360                                  int *validp, int *protp, target_ulong *BATu,
361                                  target_ulong *BATl)
362 {
363     target_ulong bl;
364     int pp, valid, prot;
365 
366     bl = (*BATu & 0x00001FFC) << 15;
367     valid = 0;
368     prot = 0;
369     if (((msr_pr == 0) && (*BATu & 0x00000002)) ||
370         ((msr_pr != 0) && (*BATu & 0x00000001))) {
371         valid = 1;
372         pp = *BATl & 0x00000003;
373         if (pp != 0) {
374             prot = PAGE_READ | PAGE_EXEC;
375             if (pp == 0x2) {
376                 prot |= PAGE_WRITE;
377             }
378         }
379     }
380     *blp = bl;
381     *validp = valid;
382     *protp = prot;
383 }
384 
385 static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
386                            target_ulong virtual, MMUAccessType access_type)
387 {
388     target_ulong *BATlt, *BATut, *BATu, *BATl;
389     target_ulong BEPIl, BEPIu, bl;
390     int i, valid, prot;
391     int ret = -1;
392     bool ifetch = access_type == MMU_INST_FETCH;
393 
394     LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
395              ifetch ? 'I' : 'D', virtual);
396     if (ifetch) {
397         BATlt = env->IBAT[1];
398         BATut = env->IBAT[0];
399     } else {
400         BATlt = env->DBAT[1];
401         BATut = env->DBAT[0];
402     }
403     for (i = 0; i < env->nb_BATs; i++) {
404         BATu = &BATut[i];
405         BATl = &BATlt[i];
406         BEPIu = *BATu & 0xF0000000;
407         BEPIl = *BATu & 0x0FFE0000;
408         bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
409         LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
410                  " BATl " TARGET_FMT_lx "\n", __func__,
411                  ifetch ? 'I' : 'D', i, virtual, *BATu, *BATl);
412         if ((virtual & 0xF0000000) == BEPIu &&
413             ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
414             /* BAT matches */
415             if (valid != 0) {
416                 /* Get physical address */
417                 ctx->raddr = (*BATl & 0xF0000000) |
418                     ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
419                     (virtual & 0x0001F000);
420                 /* Compute access rights */
421                 ctx->prot = prot;
422                 ret = check_prot(ctx->prot, access_type);
423                 if (ret == 0) {
424                     LOG_BATS("BAT %d match: r " TARGET_FMT_plx " prot=%c%c\n",
425                              i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-',
426                              ctx->prot & PAGE_WRITE ? 'W' : '-');
427                 }
428                 break;
429             }
430         }
431     }
432     if (ret < 0) {
433 #if defined(DEBUG_BATS)
434         if (qemu_log_enabled()) {
435             LOG_BATS("no BAT match for " TARGET_FMT_lx ":\n", virtual);
436             for (i = 0; i < 4; i++) {
437                 BATu = &BATut[i];
438                 BATl = &BATlt[i];
439                 BEPIu = *BATu & 0xF0000000;
440                 BEPIl = *BATu & 0x0FFE0000;
441                 bl = (*BATu & 0x00001FFC) << 15;
442                 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
443                          " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
444                          TARGET_FMT_lx " " TARGET_FMT_lx "\n",
445                          __func__, ifetch ? 'I' : 'D', i, virtual,
446                          *BATu, *BATl, BEPIu, BEPIl, bl);
447             }
448         }
449 #endif
450     }
451     /* No hit */
452     return ret;
453 }
454 
455 /* Perform segment based translation */
456 static int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
457                                target_ulong eaddr, MMUAccessType access_type,
458                                int type)
459 {
460     PowerPCCPU *cpu = env_archcpu(env);
461     hwaddr hash;
462     target_ulong vsid;
463     int ds, pr, target_page_bits;
464     int ret;
465     target_ulong sr, pgidx;
466 
467     pr = msr_pr;
468     ctx->eaddr = eaddr;
469 
470     sr = env->sr[eaddr >> 28];
471     ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
472                 ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
473     ds = sr & 0x80000000 ? 1 : 0;
474     ctx->nx = sr & 0x10000000 ? 1 : 0;
475     vsid = sr & 0x00FFFFFF;
476     target_page_bits = TARGET_PAGE_BITS;
477     qemu_log_mask(CPU_LOG_MMU,
478             "Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx
479             " nip=" TARGET_FMT_lx " lr=" TARGET_FMT_lx
480             " ir=%d dr=%d pr=%d %d t=%d\n",
481             eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir,
482             (int)msr_dr, pr != 0 ? 1 : 0, access_type == MMU_DATA_STORE, type);
483     pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits;
484     hash = vsid ^ pgidx;
485     ctx->ptem = (vsid << 7) | (pgidx >> 10);
486 
487     qemu_log_mask(CPU_LOG_MMU,
488             "pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n",
489             ctx->key, ds, ctx->nx, vsid);
490     ret = -1;
491     if (!ds) {
492         /* Check if instruction fetch is allowed, if needed */
493         if (type != ACCESS_CODE || ctx->nx == 0) {
494             /* Page address translation */
495             qemu_log_mask(CPU_LOG_MMU, "htab_base " TARGET_FMT_plx
496                     " htab_mask " TARGET_FMT_plx
497                     " hash " TARGET_FMT_plx "\n",
498                     ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash);
499             ctx->hash[0] = hash;
500             ctx->hash[1] = ~hash;
501 
502             /* Initialize real address with an invalid value */
503             ctx->raddr = (hwaddr)-1ULL;
504             /* Software TLB search */
505             ret = ppc6xx_tlb_check(env, ctx, eaddr, access_type);
506 #if defined(DUMP_PAGE_TABLES)
507             if (qemu_loglevel_mask(CPU_LOG_MMU)) {
508                 CPUState *cs = env_cpu(env);
509                 hwaddr curaddr;
510                 uint32_t a0, a1, a2, a3;
511 
512                 qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx
513                          "\n", ppc_hash32_hpt_base(cpu),
514                          ppc_hash32_hpt_mask(cpu) + 0x80);
515                 for (curaddr = ppc_hash32_hpt_base(cpu);
516                      curaddr < (ppc_hash32_hpt_base(cpu)
517                                 + ppc_hash32_hpt_mask(cpu) + 0x80);
518                      curaddr += 16) {
519                     a0 = ldl_phys(cs->as, curaddr);
520                     a1 = ldl_phys(cs->as, curaddr + 4);
521                     a2 = ldl_phys(cs->as, curaddr + 8);
522                     a3 = ldl_phys(cs->as, curaddr + 12);
523                     if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
524                         qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n",
525                                  curaddr, a0, a1, a2, a3);
526                     }
527                 }
528             }
529 #endif
530         } else {
531             qemu_log_mask(CPU_LOG_MMU, "No access allowed\n");
532             ret = -3;
533         }
534     } else {
535         target_ulong sr;
536 
537         qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
538         /* Direct-store segment : absolutely *BUGGY* for now */
539 
540         /*
541          * Direct-store implies a 32-bit MMU.
542          * Check the Segment Register's bus unit ID (BUID).
543          */
544         sr = env->sr[eaddr >> 28];
545         if ((sr & 0x1FF00000) >> 20 == 0x07f) {
546             /*
547              * Memory-forced I/O controller interface access
548              *
549              * If T=1 and BUID=x'07F', the 601 performs a memory
550              * access to SR[28-31] LA[4-31], bypassing all protection
551              * mechanisms.
552              */
553             ctx->raddr = ((sr & 0xF) << 28) | (eaddr & 0x0FFFFFFF);
554             ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
555             return 0;
556         }
557 
558         switch (type) {
559         case ACCESS_INT:
560             /* Integer load/store : only access allowed */
561             break;
562         case ACCESS_CODE:
563             /* No code fetch is allowed in direct-store areas */
564             return -4;
565         case ACCESS_FLOAT:
566             /* Floating point load/store */
567             return -4;
568         case ACCESS_RES:
569             /* lwarx, ldarx or srwcx. */
570             return -4;
571         case ACCESS_CACHE:
572             /*
573              * dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi
574              *
575              * Should make the instruction do no-op.  As it already do
576              * no-op, it's quite easy :-)
577              */
578             ctx->raddr = eaddr;
579             return 0;
580         case ACCESS_EXT:
581             /* eciwx or ecowx */
582             return -4;
583         default:
584             qemu_log_mask(CPU_LOG_MMU, "ERROR: instruction should not need "
585                           "address translation\n");
586             return -4;
587         }
588         if ((access_type == MMU_DATA_STORE || ctx->key != 1) &&
589             (access_type == MMU_DATA_LOAD || ctx->key != 0)) {
590             ctx->raddr = eaddr;
591             ret = 2;
592         } else {
593             ret = -2;
594         }
595     }
596 
597     return ret;
598 }
599 
600 /* Generic TLB check function for embedded PowerPC implementations */
601 static int ppcemb_tlb_check(CPUPPCState *env, ppcemb_tlb_t *tlb,
602                             hwaddr *raddrp,
603                             target_ulong address, uint32_t pid, int ext,
604                             int i)
605 {
606     target_ulong mask;
607 
608     /* Check valid flag */
609     if (!(tlb->prot & PAGE_VALID)) {
610         return -1;
611     }
612     mask = ~(tlb->size - 1);
613     LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx " PID %u <=> " TARGET_FMT_lx
614               " " TARGET_FMT_lx " %u %x\n", __func__, i, address, pid, tlb->EPN,
615               mask, (uint32_t)tlb->PID, tlb->prot);
616     /* Check PID */
617     if (tlb->PID != 0 && tlb->PID != pid) {
618         return -1;
619     }
620     /* Check effective address */
621     if ((address & mask) != tlb->EPN) {
622         return -1;
623     }
624     *raddrp = (tlb->RPN & mask) | (address & ~mask);
625     if (ext) {
626         /* Extend the physical address to 36 bits */
627         *raddrp |= (uint64_t)(tlb->RPN & 0xF) << 32;
628     }
629 
630     return 0;
631 }
632 
633 #ifdef CONFIG_TCG
634 /* Generic TLB search function for PowerPC embedded implementations */
635 static int ppcemb_tlb_search(CPUPPCState *env, target_ulong address,
636                              uint32_t pid)
637 {
638     ppcemb_tlb_t *tlb;
639     hwaddr raddr;
640     int i, ret;
641 
642     /* Default return value is no match */
643     ret = -1;
644     for (i = 0; i < env->nb_tlb; i++) {
645         tlb = &env->tlb.tlbe[i];
646         if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, 0, i) == 0) {
647             ret = i;
648             break;
649         }
650     }
651 
652     return ret;
653 }
654 #endif
655 
656 /* Helpers specific to PowerPC 40x implementations */
657 static inline void ppc4xx_tlb_invalidate_all(CPUPPCState *env)
658 {
659     ppcemb_tlb_t *tlb;
660     int i;
661 
662     for (i = 0; i < env->nb_tlb; i++) {
663         tlb = &env->tlb.tlbe[i];
664         tlb->prot &= ~PAGE_VALID;
665     }
666     tlb_flush(env_cpu(env));
667 }
668 
669 static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
670                                        target_ulong address,
671                                        MMUAccessType access_type)
672 {
673     ppcemb_tlb_t *tlb;
674     hwaddr raddr;
675     int i, ret, zsel, zpr, pr;
676 
677     ret = -1;
678     raddr = (hwaddr)-1ULL;
679     pr = msr_pr;
680     for (i = 0; i < env->nb_tlb; i++) {
681         tlb = &env->tlb.tlbe[i];
682         if (ppcemb_tlb_check(env, tlb, &raddr, address,
683                              env->spr[SPR_40x_PID], 0, i) < 0) {
684             continue;
685         }
686         zsel = (tlb->attr >> 4) & 0xF;
687         zpr = (env->spr[SPR_40x_ZPR] >> (30 - (2 * zsel))) & 0x3;
688         LOG_SWTLB("%s: TLB %d zsel %d zpr %d ty %d attr %08x\n",
689                     __func__, i, zsel, zpr, access_type, tlb->attr);
690         /* Check execute enable bit */
691         switch (zpr) {
692         case 0x2:
693             if (pr != 0) {
694                 goto check_perms;
695             }
696             /* fall through */
697         case 0x3:
698             /* All accesses granted */
699             ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
700             ret = 0;
701             break;
702         case 0x0:
703             if (pr != 0) {
704                 /* Raise Zone protection fault.  */
705                 env->spr[SPR_40x_ESR] = 1 << 22;
706                 ctx->prot = 0;
707                 ret = -2;
708                 break;
709             }
710             /* fall through */
711         case 0x1:
712         check_perms:
713             /* Check from TLB entry */
714             ctx->prot = tlb->prot;
715             ret = check_prot(ctx->prot, access_type);
716             if (ret == -2) {
717                 env->spr[SPR_40x_ESR] = 0;
718             }
719             break;
720         }
721         if (ret >= 0) {
722             ctx->raddr = raddr;
723             LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
724                       " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
725                       ret);
726             return 0;
727         }
728     }
729     LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
730               " %d %d\n", __func__, address, raddr, ctx->prot, ret);
731 
732     return ret;
733 }
734 
735 void store_40x_sler(CPUPPCState *env, uint32_t val)
736 {
737     /* XXX: TO BE FIXED */
738     if (val != 0x00000000) {
739         cpu_abort(env_cpu(env),
740                   "Little-endian regions are not supported by now\n");
741     }
742     env->spr[SPR_405_SLER] = val;
743 }
744 
745 static int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb,
746                               hwaddr *raddr, int *prot, target_ulong address,
747                               MMUAccessType access_type, int i)
748 {
749     int prot2;
750 
751     if (ppcemb_tlb_check(env, tlb, raddr, address,
752                          env->spr[SPR_BOOKE_PID],
753                          !env->nb_pids, i) >= 0) {
754         goto found_tlb;
755     }
756 
757     if (env->spr[SPR_BOOKE_PID1] &&
758         ppcemb_tlb_check(env, tlb, raddr, address,
759                          env->spr[SPR_BOOKE_PID1], 0, i) >= 0) {
760         goto found_tlb;
761     }
762 
763     if (env->spr[SPR_BOOKE_PID2] &&
764         ppcemb_tlb_check(env, tlb, raddr, address,
765                          env->spr[SPR_BOOKE_PID2], 0, i) >= 0) {
766         goto found_tlb;
767     }
768 
769     LOG_SWTLB("%s: TLB entry not found\n", __func__);
770     return -1;
771 
772 found_tlb:
773 
774     if (msr_pr != 0) {
775         prot2 = tlb->prot & 0xF;
776     } else {
777         prot2 = (tlb->prot >> 4) & 0xF;
778     }
779 
780     /* Check the address space */
781     if ((access_type == MMU_INST_FETCH ? msr_ir : msr_dr) != (tlb->attr & 1)) {
782         LOG_SWTLB("%s: AS doesn't match\n", __func__);
783         return -1;
784     }
785 
786     *prot = prot2;
787     if (prot2 & prot_for_access_type(access_type)) {
788         LOG_SWTLB("%s: good TLB!\n", __func__);
789         return 0;
790     }
791 
792     LOG_SWTLB("%s: no prot match: %x\n", __func__, prot2);
793     return access_type == MMU_INST_FETCH ? -3 : -2;
794 }
795 
796 static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
797                                          target_ulong address,
798                                          MMUAccessType access_type)
799 {
800     ppcemb_tlb_t *tlb;
801     hwaddr raddr;
802     int i, ret;
803 
804     ret = -1;
805     raddr = (hwaddr)-1ULL;
806     for (i = 0; i < env->nb_tlb; i++) {
807         tlb = &env->tlb.tlbe[i];
808         ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address,
809                                  access_type, i);
810         if (ret != -1) {
811             break;
812         }
813     }
814 
815     if (ret >= 0) {
816         ctx->raddr = raddr;
817         LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
818                   " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
819                   ret);
820     } else {
821         LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
822                   " %d %d\n", __func__, address, raddr, ctx->prot, ret);
823     }
824 
825     return ret;
826 }
827 
828 #ifdef CONFIG_TCG
829 static void booke206_flush_tlb(CPUPPCState *env, int flags,
830                                const int check_iprot)
831 {
832     int tlb_size;
833     int i, j;
834     ppcmas_tlb_t *tlb = env->tlb.tlbm;
835 
836     for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
837         if (flags & (1 << i)) {
838             tlb_size = booke206_tlb_size(env, i);
839             for (j = 0; j < tlb_size; j++) {
840                 if (!check_iprot || !(tlb[j].mas1 & MAS1_IPROT)) {
841                     tlb[j].mas1 &= ~MAS1_VALID;
842                 }
843             }
844         }
845         tlb += booke206_tlb_size(env, i);
846     }
847 
848     tlb_flush(env_cpu(env));
849 }
850 #endif
851 
852 static hwaddr booke206_tlb_to_page_size(CPUPPCState *env,
853                                         ppcmas_tlb_t *tlb)
854 {
855     int tlbm_size;
856 
857     tlbm_size = (tlb->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
858 
859     return 1024ULL << tlbm_size;
860 }
861 
862 /* TLB check function for MAS based SoftTLBs */
863 static int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb,
864                             hwaddr *raddrp, target_ulong address,
865                             uint32_t pid)
866 {
867     hwaddr mask;
868     uint32_t tlb_pid;
869 
870     if (!msr_cm) {
871         /* In 32bit mode we can only address 32bit EAs */
872         address = (uint32_t)address;
873     }
874 
875     /* Check valid flag */
876     if (!(tlb->mas1 & MAS1_VALID)) {
877         return -1;
878     }
879 
880     mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
881     LOG_SWTLB("%s: TLB ADDR=0x" TARGET_FMT_lx " PID=0x%x MAS1=0x%x MAS2=0x%"
882               PRIx64 " mask=0x%" HWADDR_PRIx " MAS7_3=0x%" PRIx64 " MAS8=0x%"
883               PRIx32 "\n", __func__, address, pid, tlb->mas1, tlb->mas2, mask,
884               tlb->mas7_3, tlb->mas8);
885 
886     /* Check PID */
887     tlb_pid = (tlb->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT;
888     if (tlb_pid != 0 && tlb_pid != pid) {
889         return -1;
890     }
891 
892     /* Check effective address */
893     if ((address & mask) != (tlb->mas2 & MAS2_EPN_MASK)) {
894         return -1;
895     }
896 
897     if (raddrp) {
898         *raddrp = (tlb->mas7_3 & mask) | (address & ~mask);
899     }
900 
901     return 0;
902 }
903 
904 static bool is_epid_mmu(int mmu_idx)
905 {
906     return mmu_idx == PPC_TLB_EPID_STORE || mmu_idx == PPC_TLB_EPID_LOAD;
907 }
908 
909 static uint32_t mmubooke206_esr(int mmu_idx, MMUAccessType access_type)
910 {
911     uint32_t esr = 0;
912     if (access_type == MMU_DATA_STORE) {
913         esr |= ESR_ST;
914     }
915     if (is_epid_mmu(mmu_idx)) {
916         esr |= ESR_EPID;
917     }
918     return esr;
919 }
920 
921 /*
922  * Get EPID register given the mmu_idx. If this is regular load,
923  * construct the EPID access bits from current processor state
924  *
925  * Get the effective AS and PR bits and the PID. The PID is returned
926  * only if EPID load is requested, otherwise the caller must detect
927  * the correct EPID.  Return true if valid EPID is returned.
928  */
929 static bool mmubooke206_get_as(CPUPPCState *env,
930                                int mmu_idx, uint32_t *epid_out,
931                                bool *as_out, bool *pr_out)
932 {
933     if (is_epid_mmu(mmu_idx)) {
934         uint32_t epidr;
935         if (mmu_idx == PPC_TLB_EPID_STORE) {
936             epidr = env->spr[SPR_BOOKE_EPSC];
937         } else {
938             epidr = env->spr[SPR_BOOKE_EPLC];
939         }
940         *epid_out = (epidr & EPID_EPID) >> EPID_EPID_SHIFT;
941         *as_out = !!(epidr & EPID_EAS);
942         *pr_out = !!(epidr & EPID_EPR);
943         return true;
944     } else {
945         *as_out = msr_ds;
946         *pr_out = msr_pr;
947         return false;
948     }
949 }
950 
951 /* Check if the tlb found by hashing really matches */
952 static int mmubooke206_check_tlb(CPUPPCState *env, ppcmas_tlb_t *tlb,
953                                  hwaddr *raddr, int *prot,
954                                  target_ulong address,
955                                  MMUAccessType access_type, int mmu_idx)
956 {
957     int prot2 = 0;
958     uint32_t epid;
959     bool as, pr;
960     bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr);
961 
962     if (!use_epid) {
963         if (ppcmas_tlb_check(env, tlb, raddr, address,
964                              env->spr[SPR_BOOKE_PID]) >= 0) {
965             goto found_tlb;
966         }
967 
968         if (env->spr[SPR_BOOKE_PID1] &&
969             ppcmas_tlb_check(env, tlb, raddr, address,
970                              env->spr[SPR_BOOKE_PID1]) >= 0) {
971             goto found_tlb;
972         }
973 
974         if (env->spr[SPR_BOOKE_PID2] &&
975             ppcmas_tlb_check(env, tlb, raddr, address,
976                              env->spr[SPR_BOOKE_PID2]) >= 0) {
977             goto found_tlb;
978         }
979     } else {
980         if (ppcmas_tlb_check(env, tlb, raddr, address, epid) >= 0) {
981             goto found_tlb;
982         }
983     }
984 
985     LOG_SWTLB("%s: TLB entry not found\n", __func__);
986     return -1;
987 
988 found_tlb:
989 
990     if (pr) {
991         if (tlb->mas7_3 & MAS3_UR) {
992             prot2 |= PAGE_READ;
993         }
994         if (tlb->mas7_3 & MAS3_UW) {
995             prot2 |= PAGE_WRITE;
996         }
997         if (tlb->mas7_3 & MAS3_UX) {
998             prot2 |= PAGE_EXEC;
999         }
1000     } else {
1001         if (tlb->mas7_3 & MAS3_SR) {
1002             prot2 |= PAGE_READ;
1003         }
1004         if (tlb->mas7_3 & MAS3_SW) {
1005             prot2 |= PAGE_WRITE;
1006         }
1007         if (tlb->mas7_3 & MAS3_SX) {
1008             prot2 |= PAGE_EXEC;
1009         }
1010     }
1011 
1012     /* Check the address space and permissions */
1013     if (access_type == MMU_INST_FETCH) {
1014         /* There is no way to fetch code using epid load */
1015         assert(!use_epid);
1016         as = msr_ir;
1017     }
1018 
1019     if (as != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
1020         LOG_SWTLB("%s: AS doesn't match\n", __func__);
1021         return -1;
1022     }
1023 
1024     *prot = prot2;
1025     if (prot2 & prot_for_access_type(access_type)) {
1026         LOG_SWTLB("%s: good TLB!\n", __func__);
1027         return 0;
1028     }
1029 
1030     LOG_SWTLB("%s: no prot match: %x\n", __func__, prot2);
1031     return access_type == MMU_INST_FETCH ? -3 : -2;
1032 }
1033 
1034 static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
1035                                             target_ulong address,
1036                                             MMUAccessType access_type,
1037                                             int mmu_idx)
1038 {
1039     ppcmas_tlb_t *tlb;
1040     hwaddr raddr;
1041     int i, j, ret;
1042 
1043     ret = -1;
1044     raddr = (hwaddr)-1ULL;
1045 
1046     for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
1047         int ways = booke206_tlb_ways(env, i);
1048 
1049         for (j = 0; j < ways; j++) {
1050             tlb = booke206_get_tlbm(env, i, address, j);
1051             if (!tlb) {
1052                 continue;
1053             }
1054             ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address,
1055                                         access_type, mmu_idx);
1056             if (ret != -1) {
1057                 goto found_tlb;
1058             }
1059         }
1060     }
1061 
1062 found_tlb:
1063 
1064     if (ret >= 0) {
1065         ctx->raddr = raddr;
1066         LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
1067                   " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
1068                   ret);
1069     } else {
1070         LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
1071                   " %d %d\n", __func__, address, raddr, ctx->prot, ret);
1072     }
1073 
1074     return ret;
1075 }
1076 
1077 static const char *book3e_tsize_to_str[32] = {
1078     "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
1079     "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M",
1080     "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G",
1081     "1T", "2T"
1082 };
1083 
1084 static void mmubooke_dump_mmu(CPUPPCState *env)
1085 {
1086     ppcemb_tlb_t *entry;
1087     int i;
1088 
1089     if (kvm_enabled() && !env->kvm_sw_tlb) {
1090         qemu_printf("Cannot access KVM TLB\n");
1091         return;
1092     }
1093 
1094     qemu_printf("\nTLB:\n");
1095     qemu_printf("Effective          Physical           Size PID   Prot     "
1096                 "Attr\n");
1097 
1098     entry = &env->tlb.tlbe[0];
1099     for (i = 0; i < env->nb_tlb; i++, entry++) {
1100         hwaddr ea, pa;
1101         target_ulong mask;
1102         uint64_t size = (uint64_t)entry->size;
1103         char size_buf[20];
1104 
1105         /* Check valid flag */
1106         if (!(entry->prot & PAGE_VALID)) {
1107             continue;
1108         }
1109 
1110         mask = ~(entry->size - 1);
1111         ea = entry->EPN & mask;
1112         pa = entry->RPN & mask;
1113         /* Extend the physical address to 36 bits */
1114         pa |= (hwaddr)(entry->RPN & 0xF) << 32;
1115         if (size >= 1 * MiB) {
1116             snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "M", size / MiB);
1117         } else {
1118             snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "k", size / KiB);
1119         }
1120         qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %s %-5u %08x %08x\n",
1121                     (uint64_t)ea, (uint64_t)pa, size_buf, (uint32_t)entry->PID,
1122                     entry->prot, entry->attr);
1123     }
1124 
1125 }
1126 
1127 static void mmubooke206_dump_one_tlb(CPUPPCState *env, int tlbn, int offset,
1128                                      int tlbsize)
1129 {
1130     ppcmas_tlb_t *entry;
1131     int i;
1132 
1133     qemu_printf("\nTLB%d:\n", tlbn);
1134     qemu_printf("Effective          Physical           Size TID   TS SRWX"
1135                 " URWX WIMGE U0123\n");
1136 
1137     entry = &env->tlb.tlbm[offset];
1138     for (i = 0; i < tlbsize; i++, entry++) {
1139         hwaddr ea, pa, size;
1140         int tsize;
1141 
1142         if (!(entry->mas1 & MAS1_VALID)) {
1143             continue;
1144         }
1145 
1146         tsize = (entry->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
1147         size = 1024ULL << tsize;
1148         ea = entry->mas2 & ~(size - 1);
1149         pa = entry->mas7_3 & ~(size - 1);
1150 
1151         qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u  S%c%c%c"
1152                     "U%c%c%c %c%c%c%c%c U%c%c%c%c\n",
1153                     (uint64_t)ea, (uint64_t)pa,
1154                     book3e_tsize_to_str[tsize],
1155                     (entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT,
1156                     (entry->mas1 & MAS1_TS) >> MAS1_TS_SHIFT,
1157                     entry->mas7_3 & MAS3_SR ? 'R' : '-',
1158                     entry->mas7_3 & MAS3_SW ? 'W' : '-',
1159                     entry->mas7_3 & MAS3_SX ? 'X' : '-',
1160                     entry->mas7_3 & MAS3_UR ? 'R' : '-',
1161                     entry->mas7_3 & MAS3_UW ? 'W' : '-',
1162                     entry->mas7_3 & MAS3_UX ? 'X' : '-',
1163                     entry->mas2 & MAS2_W ? 'W' : '-',
1164                     entry->mas2 & MAS2_I ? 'I' : '-',
1165                     entry->mas2 & MAS2_M ? 'M' : '-',
1166                     entry->mas2 & MAS2_G ? 'G' : '-',
1167                     entry->mas2 & MAS2_E ? 'E' : '-',
1168                     entry->mas7_3 & MAS3_U0 ? '0' : '-',
1169                     entry->mas7_3 & MAS3_U1 ? '1' : '-',
1170                     entry->mas7_3 & MAS3_U2 ? '2' : '-',
1171                     entry->mas7_3 & MAS3_U3 ? '3' : '-');
1172     }
1173 }
1174 
1175 static void mmubooke206_dump_mmu(CPUPPCState *env)
1176 {
1177     int offset = 0;
1178     int i;
1179 
1180     if (kvm_enabled() && !env->kvm_sw_tlb) {
1181         qemu_printf("Cannot access KVM TLB\n");
1182         return;
1183     }
1184 
1185     for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
1186         int size = booke206_tlb_size(env, i);
1187 
1188         if (size == 0) {
1189             continue;
1190         }
1191 
1192         mmubooke206_dump_one_tlb(env, i, offset, size);
1193         offset += size;
1194     }
1195 }
1196 
1197 static void mmu6xx_dump_BATs(CPUPPCState *env, int type)
1198 {
1199     target_ulong *BATlt, *BATut, *BATu, *BATl;
1200     target_ulong BEPIl, BEPIu, bl;
1201     int i;
1202 
1203     switch (type) {
1204     case ACCESS_CODE:
1205         BATlt = env->IBAT[1];
1206         BATut = env->IBAT[0];
1207         break;
1208     default:
1209         BATlt = env->DBAT[1];
1210         BATut = env->DBAT[0];
1211         break;
1212     }
1213 
1214     for (i = 0; i < env->nb_BATs; i++) {
1215         BATu = &BATut[i];
1216         BATl = &BATlt[i];
1217         BEPIu = *BATu & 0xF0000000;
1218         BEPIl = *BATu & 0x0FFE0000;
1219         bl = (*BATu & 0x00001FFC) << 15;
1220         qemu_printf("%s BAT%d BATu " TARGET_FMT_lx
1221                     " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
1222                     TARGET_FMT_lx " " TARGET_FMT_lx "\n",
1223                     type == ACCESS_CODE ? "code" : "data", i,
1224                     *BATu, *BATl, BEPIu, BEPIl, bl);
1225     }
1226 }
1227 
1228 static void mmu6xx_dump_mmu(CPUPPCState *env)
1229 {
1230     PowerPCCPU *cpu = env_archcpu(env);
1231     ppc6xx_tlb_t *tlb;
1232     target_ulong sr;
1233     int type, way, entry, i;
1234 
1235     qemu_printf("HTAB base = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_base(cpu));
1236     qemu_printf("HTAB mask = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_mask(cpu));
1237 
1238     qemu_printf("\nSegment registers:\n");
1239     for (i = 0; i < 32; i++) {
1240         sr = env->sr[i];
1241         if (sr & 0x80000000) {
1242             qemu_printf("%02d T=%d Ks=%d Kp=%d BUID=0x%03x "
1243                         "CNTLR_SPEC=0x%05x\n", i,
1244                         sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
1245                         sr & 0x20000000 ? 1 : 0, (uint32_t)((sr >> 20) & 0x1FF),
1246                         (uint32_t)(sr & 0xFFFFF));
1247         } else {
1248             qemu_printf("%02d T=%d Ks=%d Kp=%d N=%d VSID=0x%06x\n", i,
1249                         sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
1250                         sr & 0x20000000 ? 1 : 0, sr & 0x10000000 ? 1 : 0,
1251                         (uint32_t)(sr & 0x00FFFFFF));
1252         }
1253     }
1254 
1255     qemu_printf("\nBATs:\n");
1256     mmu6xx_dump_BATs(env, ACCESS_INT);
1257     mmu6xx_dump_BATs(env, ACCESS_CODE);
1258 
1259     if (env->id_tlbs != 1) {
1260         qemu_printf("ERROR: 6xx MMU should have separated TLB"
1261                     " for code and data\n");
1262     }
1263 
1264     qemu_printf("\nTLBs                       [EPN    EPN + SIZE]\n");
1265 
1266     for (type = 0; type < 2; type++) {
1267         for (way = 0; way < env->nb_ways; way++) {
1268             for (entry = env->nb_tlb * type + env->tlb_per_way * way;
1269                  entry < (env->nb_tlb * type + env->tlb_per_way * (way + 1));
1270                  entry++) {
1271 
1272                 tlb = &env->tlb.tlb6[entry];
1273                 qemu_printf("%s TLB %02d/%02d way:%d %s ["
1274                             TARGET_FMT_lx " " TARGET_FMT_lx "]\n",
1275                             type ? "code" : "data", entry % env->nb_tlb,
1276                             env->nb_tlb, way,
1277                             pte_is_valid(tlb->pte0) ? "valid" : "inval",
1278                             tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE);
1279             }
1280         }
1281     }
1282 }
1283 
1284 void dump_mmu(CPUPPCState *env)
1285 {
1286     switch (env->mmu_model) {
1287     case POWERPC_MMU_BOOKE:
1288         mmubooke_dump_mmu(env);
1289         break;
1290     case POWERPC_MMU_BOOKE206:
1291         mmubooke206_dump_mmu(env);
1292         break;
1293     case POWERPC_MMU_SOFT_6xx:
1294     case POWERPC_MMU_SOFT_74xx:
1295         mmu6xx_dump_mmu(env);
1296         break;
1297 #if defined(TARGET_PPC64)
1298     case POWERPC_MMU_64B:
1299     case POWERPC_MMU_2_03:
1300     case POWERPC_MMU_2_06:
1301     case POWERPC_MMU_2_07:
1302         dump_slb(env_archcpu(env));
1303         break;
1304     case POWERPC_MMU_3_00:
1305         if (ppc64_v3_radix(env_archcpu(env))) {
1306             qemu_log_mask(LOG_UNIMP, "%s: the PPC64 MMU is unsupported\n",
1307                           __func__);
1308         } else {
1309             dump_slb(env_archcpu(env));
1310         }
1311         break;
1312 #endif
1313     default:
1314         qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__);
1315     }
1316 }
1317 
1318 static int check_physical(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong eaddr,
1319                           MMUAccessType access_type)
1320 {
1321     int in_plb, ret;
1322 
1323     ctx->raddr = eaddr;
1324     ctx->prot = PAGE_READ | PAGE_EXEC;
1325     ret = 0;
1326     switch (env->mmu_model) {
1327     case POWERPC_MMU_SOFT_6xx:
1328     case POWERPC_MMU_SOFT_74xx:
1329     case POWERPC_MMU_SOFT_4xx:
1330     case POWERPC_MMU_REAL:
1331     case POWERPC_MMU_BOOKE:
1332         ctx->prot |= PAGE_WRITE;
1333         break;
1334 
1335     case POWERPC_MMU_SOFT_4xx_Z:
1336         if (unlikely(msr_pe != 0)) {
1337             /*
1338              * 403 family add some particular protections, using
1339              * PBL/PBU registers for accesses with no translation.
1340              */
1341             in_plb =
1342                 /* Check PLB validity */
1343                 (env->pb[0] < env->pb[1] &&
1344                  /* and address in plb area */
1345                  eaddr >= env->pb[0] && eaddr < env->pb[1]) ||
1346                 (env->pb[2] < env->pb[3] &&
1347                  eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0;
1348             if (in_plb ^ msr_px) {
1349                 /* Access in protected area */
1350                 if (access_type == MMU_DATA_STORE) {
1351                     /* Access is not allowed */
1352                     ret = -2;
1353                 }
1354             } else {
1355                 /* Read-write access is allowed */
1356                 ctx->prot |= PAGE_WRITE;
1357             }
1358         }
1359         break;
1360 
1361     default:
1362         /* Caller's checks mean we should never get here for other models */
1363         abort();
1364         return -1;
1365     }
1366 
1367     return ret;
1368 }
1369 
1370 static int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
1371                                      target_ulong eaddr,
1372                                      MMUAccessType access_type, int type,
1373                                      int mmu_idx)
1374 {
1375     int ret = -1;
1376     bool real_mode = (type == ACCESS_CODE && msr_ir == 0)
1377         || (type != ACCESS_CODE && msr_dr == 0);
1378 
1379     switch (env->mmu_model) {
1380     case POWERPC_MMU_SOFT_6xx:
1381     case POWERPC_MMU_SOFT_74xx:
1382         if (real_mode) {
1383             ret = check_physical(env, ctx, eaddr, access_type);
1384         } else {
1385             /* Try to find a BAT */
1386             if (env->nb_BATs != 0) {
1387                 ret = get_bat_6xx_tlb(env, ctx, eaddr, access_type);
1388             }
1389             if (ret < 0) {
1390                 /* We didn't match any BAT entry or don't have BATs */
1391                 ret = get_segment_6xx_tlb(env, ctx, eaddr, access_type, type);
1392             }
1393         }
1394         break;
1395 
1396     case POWERPC_MMU_SOFT_4xx:
1397     case POWERPC_MMU_SOFT_4xx_Z:
1398         if (real_mode) {
1399             ret = check_physical(env, ctx, eaddr, access_type);
1400         } else {
1401             ret = mmu40x_get_physical_address(env, ctx, eaddr, access_type);
1402         }
1403         break;
1404     case POWERPC_MMU_BOOKE:
1405         ret = mmubooke_get_physical_address(env, ctx, eaddr, access_type);
1406         break;
1407     case POWERPC_MMU_BOOKE206:
1408         ret = mmubooke206_get_physical_address(env, ctx, eaddr, access_type,
1409                                                mmu_idx);
1410         break;
1411     case POWERPC_MMU_MPC8xx:
1412         /* XXX: TODO */
1413         cpu_abort(env_cpu(env), "MPC8xx MMU model is not implemented\n");
1414         break;
1415     case POWERPC_MMU_REAL:
1416         if (real_mode) {
1417             ret = check_physical(env, ctx, eaddr, access_type);
1418         } else {
1419             cpu_abort(env_cpu(env),
1420                       "PowerPC in real mode do not do any translation\n");
1421         }
1422         return -1;
1423     default:
1424         cpu_abort(env_cpu(env), "Unknown or invalid MMU model\n");
1425         return -1;
1426     }
1427 
1428     return ret;
1429 }
1430 
1431 #ifdef CONFIG_TCG
1432 static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
1433                                 target_ulong eaddr, MMUAccessType access_type,
1434                                 int type)
1435 {
1436     return get_physical_address_wtlb(env, ctx, eaddr, access_type, type, 0);
1437 }
1438 #endif
1439 
1440 static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
1441                                          MMUAccessType access_type, int mmu_idx)
1442 {
1443     uint32_t epid;
1444     bool as, pr;
1445     uint32_t missed_tid = 0;
1446     bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr);
1447 
1448     if (access_type == MMU_INST_FETCH) {
1449         as = msr_ir;
1450     }
1451     env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK;
1452     env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK;
1453     env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK;
1454     env->spr[SPR_BOOKE_MAS3] = 0;
1455     env->spr[SPR_BOOKE_MAS6] = 0;
1456     env->spr[SPR_BOOKE_MAS7] = 0;
1457 
1458     /* AS */
1459     if (as) {
1460         env->spr[SPR_BOOKE_MAS1] |= MAS1_TS;
1461         env->spr[SPR_BOOKE_MAS6] |= MAS6_SAS;
1462     }
1463 
1464     env->spr[SPR_BOOKE_MAS1] |= MAS1_VALID;
1465     env->spr[SPR_BOOKE_MAS2] |= address & MAS2_EPN_MASK;
1466 
1467     if (!use_epid) {
1468         switch (env->spr[SPR_BOOKE_MAS4] & MAS4_TIDSELD_PIDZ) {
1469         case MAS4_TIDSELD_PID0:
1470             missed_tid = env->spr[SPR_BOOKE_PID];
1471             break;
1472         case MAS4_TIDSELD_PID1:
1473             missed_tid = env->spr[SPR_BOOKE_PID1];
1474             break;
1475         case MAS4_TIDSELD_PID2:
1476             missed_tid = env->spr[SPR_BOOKE_PID2];
1477             break;
1478         }
1479         env->spr[SPR_BOOKE_MAS6] |= env->spr[SPR_BOOKE_PID] << 16;
1480     } else {
1481         missed_tid = epid;
1482         env->spr[SPR_BOOKE_MAS6] |= missed_tid << 16;
1483     }
1484     env->spr[SPR_BOOKE_MAS1] |= (missed_tid << MAS1_TID_SHIFT);
1485 
1486 
1487     /* next victim logic */
1488     env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
1489     env->last_way++;
1490     env->last_way &= booke206_tlb_ways(env, 0) - 1;
1491     env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
1492 }
1493 
1494 /* Perform address translation */
1495 /* TODO: Split this by mmu_model. */
1496 static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
1497                             MMUAccessType access_type,
1498                             hwaddr *raddrp, int *psizep, int *protp,
1499                             int mmu_idx, bool guest_visible)
1500 {
1501     CPUState *cs = CPU(cpu);
1502     CPUPPCState *env = &cpu->env;
1503     mmu_ctx_t ctx;
1504     int type;
1505     int ret;
1506 
1507     if (access_type == MMU_INST_FETCH) {
1508         /* code access */
1509         type = ACCESS_CODE;
1510     } else if (guest_visible) {
1511         /* data access */
1512         type = env->access_type;
1513     } else {
1514         type = ACCESS_INT;
1515     }
1516 
1517     ret = get_physical_address_wtlb(env, &ctx, eaddr, access_type,
1518                                     type, mmu_idx);
1519     if (ret == 0) {
1520         *raddrp = ctx.raddr;
1521         *protp = ctx.prot;
1522         *psizep = TARGET_PAGE_BITS;
1523         return true;
1524     }
1525 
1526     if (guest_visible) {
1527         LOG_MMU_STATE(cs);
1528         if (type == ACCESS_CODE) {
1529             switch (ret) {
1530             case -1:
1531                 /* No matches in page tables or TLB */
1532                 switch (env->mmu_model) {
1533                 case POWERPC_MMU_SOFT_6xx:
1534                     cs->exception_index = POWERPC_EXCP_IFTLB;
1535                     env->error_code = 1 << 18;
1536                     env->spr[SPR_IMISS] = eaddr;
1537                     env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
1538                     goto tlb_miss;
1539                 case POWERPC_MMU_SOFT_74xx:
1540                     cs->exception_index = POWERPC_EXCP_IFTLB;
1541                     goto tlb_miss_74xx;
1542                 case POWERPC_MMU_SOFT_4xx:
1543                 case POWERPC_MMU_SOFT_4xx_Z:
1544                     cs->exception_index = POWERPC_EXCP_ITLB;
1545                     env->error_code = 0;
1546                     env->spr[SPR_40x_DEAR] = eaddr;
1547                     env->spr[SPR_40x_ESR] = 0x00000000;
1548                     break;
1549                 case POWERPC_MMU_BOOKE206:
1550                     booke206_update_mas_tlb_miss(env, eaddr, 2, mmu_idx);
1551                     /* fall through */
1552                 case POWERPC_MMU_BOOKE:
1553                     cs->exception_index = POWERPC_EXCP_ITLB;
1554                     env->error_code = 0;
1555                     env->spr[SPR_BOOKE_DEAR] = eaddr;
1556                     env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, MMU_DATA_LOAD);
1557                     break;
1558                 case POWERPC_MMU_MPC8xx:
1559                     cpu_abort(cs, "MPC8xx MMU model is not implemented\n");
1560                 case POWERPC_MMU_REAL:
1561                     cpu_abort(cs, "PowerPC in real mode should never raise "
1562                               "any MMU exceptions\n");
1563                 default:
1564                     cpu_abort(cs, "Unknown or invalid MMU model\n");
1565                 }
1566                 break;
1567             case -2:
1568                 /* Access rights violation */
1569                 cs->exception_index = POWERPC_EXCP_ISI;
1570                 env->error_code = 0x08000000;
1571                 break;
1572             case -3:
1573                 /* No execute protection violation */
1574                 if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1575                     (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1576                     env->spr[SPR_BOOKE_ESR] = 0x00000000;
1577                 }
1578                 cs->exception_index = POWERPC_EXCP_ISI;
1579                 env->error_code = 0x10000000;
1580                 break;
1581             case -4:
1582                 /* Direct store exception */
1583                 /* No code fetch is allowed in direct-store areas */
1584                 cs->exception_index = POWERPC_EXCP_ISI;
1585                 env->error_code = 0x10000000;
1586                 break;
1587             }
1588         } else {
1589             switch (ret) {
1590             case -1:
1591                 /* No matches in page tables or TLB */
1592                 switch (env->mmu_model) {
1593                 case POWERPC_MMU_SOFT_6xx:
1594                     if (access_type == MMU_DATA_STORE) {
1595                         cs->exception_index = POWERPC_EXCP_DSTLB;
1596                         env->error_code = 1 << 16;
1597                     } else {
1598                         cs->exception_index = POWERPC_EXCP_DLTLB;
1599                         env->error_code = 0;
1600                     }
1601                     env->spr[SPR_DMISS] = eaddr;
1602                     env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
1603                 tlb_miss:
1604                     env->error_code |= ctx.key << 19;
1605                     env->spr[SPR_HASH1] = ppc_hash32_hpt_base(cpu) +
1606                         get_pteg_offset32(cpu, ctx.hash[0]);
1607                     env->spr[SPR_HASH2] = ppc_hash32_hpt_base(cpu) +
1608                         get_pteg_offset32(cpu, ctx.hash[1]);
1609                     break;
1610                 case POWERPC_MMU_SOFT_74xx:
1611                     if (access_type == MMU_DATA_STORE) {
1612                         cs->exception_index = POWERPC_EXCP_DSTLB;
1613                     } else {
1614                         cs->exception_index = POWERPC_EXCP_DLTLB;
1615                     }
1616                 tlb_miss_74xx:
1617                     /* Implement LRU algorithm */
1618                     env->error_code = ctx.key << 19;
1619                     env->spr[SPR_TLBMISS] = (eaddr & ~((target_ulong)0x3)) |
1620                         ((env->last_way + 1) & (env->nb_ways - 1));
1621                     env->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem;
1622                     break;
1623                 case POWERPC_MMU_SOFT_4xx:
1624                 case POWERPC_MMU_SOFT_4xx_Z:
1625                     cs->exception_index = POWERPC_EXCP_DTLB;
1626                     env->error_code = 0;
1627                     env->spr[SPR_40x_DEAR] = eaddr;
1628                     if (access_type == MMU_DATA_STORE) {
1629                         env->spr[SPR_40x_ESR] = 0x00800000;
1630                     } else {
1631                         env->spr[SPR_40x_ESR] = 0x00000000;
1632                     }
1633                     break;
1634                 case POWERPC_MMU_MPC8xx:
1635                     /* XXX: TODO */
1636                     cpu_abort(cs, "MPC8xx MMU model is not implemented\n");
1637                 case POWERPC_MMU_BOOKE206:
1638                     booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
1639                     /* fall through */
1640                 case POWERPC_MMU_BOOKE:
1641                     cs->exception_index = POWERPC_EXCP_DTLB;
1642                     env->error_code = 0;
1643                     env->spr[SPR_BOOKE_DEAR] = eaddr;
1644                     env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1645                     break;
1646                 case POWERPC_MMU_REAL:
1647                     cpu_abort(cs, "PowerPC in real mode should never raise "
1648                               "any MMU exceptions\n");
1649                 default:
1650                     cpu_abort(cs, "Unknown or invalid MMU model\n");
1651                 }
1652                 break;
1653             case -2:
1654                 /* Access rights violation */
1655                 cs->exception_index = POWERPC_EXCP_DSI;
1656                 env->error_code = 0;
1657                 if (env->mmu_model == POWERPC_MMU_SOFT_4xx
1658                     || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) {
1659                     env->spr[SPR_40x_DEAR] = eaddr;
1660                     if (access_type == MMU_DATA_STORE) {
1661                         env->spr[SPR_40x_ESR] |= 0x00800000;
1662                     }
1663                 } else if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1664                            (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1665                     env->spr[SPR_BOOKE_DEAR] = eaddr;
1666                     env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1667                 } else {
1668                     env->spr[SPR_DAR] = eaddr;
1669                     if (access_type == MMU_DATA_STORE) {
1670                         env->spr[SPR_DSISR] = 0x0A000000;
1671                     } else {
1672                         env->spr[SPR_DSISR] = 0x08000000;
1673                     }
1674                 }
1675                 break;
1676             case -4:
1677                 /* Direct store exception */
1678                 switch (type) {
1679                 case ACCESS_FLOAT:
1680                     /* Floating point load/store */
1681                     cs->exception_index = POWERPC_EXCP_ALIGN;
1682                     env->error_code = POWERPC_EXCP_ALIGN_FP;
1683                     env->spr[SPR_DAR] = eaddr;
1684                     break;
1685                 case ACCESS_RES:
1686                     /* lwarx, ldarx or stwcx. */
1687                     cs->exception_index = POWERPC_EXCP_DSI;
1688                     env->error_code = 0;
1689                     env->spr[SPR_DAR] = eaddr;
1690                     if (access_type == MMU_DATA_STORE) {
1691                         env->spr[SPR_DSISR] = 0x06000000;
1692                     } else {
1693                         env->spr[SPR_DSISR] = 0x04000000;
1694                     }
1695                     break;
1696                 case ACCESS_EXT:
1697                     /* eciwx or ecowx */
1698                     cs->exception_index = POWERPC_EXCP_DSI;
1699                     env->error_code = 0;
1700                     env->spr[SPR_DAR] = eaddr;
1701                     if (access_type == MMU_DATA_STORE) {
1702                         env->spr[SPR_DSISR] = 0x06100000;
1703                     } else {
1704                         env->spr[SPR_DSISR] = 0x04100000;
1705                     }
1706                     break;
1707                 default:
1708                     printf("DSI: invalid exception (%d)\n", ret);
1709                     cs->exception_index = POWERPC_EXCP_PROGRAM;
1710                     env->error_code =
1711                         POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
1712                     env->spr[SPR_DAR] = eaddr;
1713                     break;
1714                 }
1715                 break;
1716             }
1717         }
1718     }
1719     return false;
1720 }
1721 
1722 #ifdef CONFIG_TCG
1723 /*****************************************************************************/
1724 /* BATs management */
1725 #if !defined(FLUSH_ALL_TLBS)
1726 static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu,
1727                                      target_ulong mask)
1728 {
1729     CPUState *cs = env_cpu(env);
1730     target_ulong base, end, page;
1731 
1732     base = BATu & ~0x0001FFFF;
1733     end = base + mask + 0x00020000;
1734     if (((end - base) >> TARGET_PAGE_BITS) > 1024) {
1735         /* Flushing 1024 4K pages is slower than a complete flush */
1736         LOG_BATS("Flush all BATs\n");
1737         tlb_flush(cs);
1738         LOG_BATS("Flush done\n");
1739         return;
1740     }
1741     LOG_BATS("Flush BAT from " TARGET_FMT_lx " to " TARGET_FMT_lx " ("
1742              TARGET_FMT_lx ")\n", base, end, mask);
1743     for (page = base; page != end; page += TARGET_PAGE_SIZE) {
1744         tlb_flush_page(cs, page);
1745     }
1746     LOG_BATS("Flush done\n");
1747 }
1748 #endif
1749 
1750 static inline void dump_store_bat(CPUPPCState *env, char ID, int ul, int nr,
1751                                   target_ulong value)
1752 {
1753     LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n", ID,
1754              nr, ul == 0 ? 'u' : 'l', value, env->nip);
1755 }
1756 
1757 void helper_store_ibatu(CPUPPCState *env, uint32_t nr, target_ulong value)
1758 {
1759     target_ulong mask;
1760 
1761     dump_store_bat(env, 'I', 0, nr, value);
1762     if (env->IBAT[0][nr] != value) {
1763         mask = (value << 15) & 0x0FFE0000UL;
1764 #if !defined(FLUSH_ALL_TLBS)
1765         do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1766 #endif
1767         /*
1768          * When storing valid upper BAT, mask BEPI and BRPN and
1769          * invalidate all TLBs covered by this BAT
1770          */
1771         mask = (value << 15) & 0x0FFE0000UL;
1772         env->IBAT[0][nr] = (value & 0x00001FFFUL) |
1773             (value & ~0x0001FFFFUL & ~mask);
1774         env->IBAT[1][nr] = (env->IBAT[1][nr] & 0x0000007B) |
1775             (env->IBAT[1][nr] & ~0x0001FFFF & ~mask);
1776 #if !defined(FLUSH_ALL_TLBS)
1777         do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1778 #else
1779         tlb_flush(env_cpu(env));
1780 #endif
1781     }
1782 }
1783 
1784 void helper_store_ibatl(CPUPPCState *env, uint32_t nr, target_ulong value)
1785 {
1786     dump_store_bat(env, 'I', 1, nr, value);
1787     env->IBAT[1][nr] = value;
1788 }
1789 
1790 void helper_store_dbatu(CPUPPCState *env, uint32_t nr, target_ulong value)
1791 {
1792     target_ulong mask;
1793 
1794     dump_store_bat(env, 'D', 0, nr, value);
1795     if (env->DBAT[0][nr] != value) {
1796         /*
1797          * When storing valid upper BAT, mask BEPI and BRPN and
1798          * invalidate all TLBs covered by this BAT
1799          */
1800         mask = (value << 15) & 0x0FFE0000UL;
1801 #if !defined(FLUSH_ALL_TLBS)
1802         do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1803 #endif
1804         mask = (value << 15) & 0x0FFE0000UL;
1805         env->DBAT[0][nr] = (value & 0x00001FFFUL) |
1806             (value & ~0x0001FFFFUL & ~mask);
1807         env->DBAT[1][nr] = (env->DBAT[1][nr] & 0x0000007B) |
1808             (env->DBAT[1][nr] & ~0x0001FFFF & ~mask);
1809 #if !defined(FLUSH_ALL_TLBS)
1810         do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1811 #else
1812         tlb_flush(env_cpu(env));
1813 #endif
1814     }
1815 }
1816 
1817 void helper_store_dbatl(CPUPPCState *env, uint32_t nr, target_ulong value)
1818 {
1819     dump_store_bat(env, 'D', 1, nr, value);
1820     env->DBAT[1][nr] = value;
1821 }
1822 
1823 void helper_store_601_batu(CPUPPCState *env, uint32_t nr, target_ulong value)
1824 {
1825     target_ulong mask;
1826 #if defined(FLUSH_ALL_TLBS)
1827     int do_inval;
1828 #endif
1829 
1830     dump_store_bat(env, 'I', 0, nr, value);
1831     if (env->IBAT[0][nr] != value) {
1832 #if defined(FLUSH_ALL_TLBS)
1833         do_inval = 0;
1834 #endif
1835         mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
1836         if (env->IBAT[1][nr] & 0x40) {
1837             /* Invalidate BAT only if it is valid */
1838 #if !defined(FLUSH_ALL_TLBS)
1839             do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1840 #else
1841             do_inval = 1;
1842 #endif
1843         }
1844         /*
1845          * When storing valid upper BAT, mask BEPI and BRPN and
1846          * invalidate all TLBs covered by this BAT
1847          */
1848         env->IBAT[0][nr] = (value & 0x00001FFFUL) |
1849             (value & ~0x0001FFFFUL & ~mask);
1850         env->DBAT[0][nr] = env->IBAT[0][nr];
1851         if (env->IBAT[1][nr] & 0x40) {
1852 #if !defined(FLUSH_ALL_TLBS)
1853             do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1854 #else
1855             do_inval = 1;
1856 #endif
1857         }
1858 #if defined(FLUSH_ALL_TLBS)
1859         if (do_inval) {
1860             tlb_flush(env_cpu(env));
1861         }
1862 #endif
1863     }
1864 }
1865 
1866 void helper_store_601_batl(CPUPPCState *env, uint32_t nr, target_ulong value)
1867 {
1868 #if !defined(FLUSH_ALL_TLBS)
1869     target_ulong mask;
1870 #else
1871     int do_inval;
1872 #endif
1873 
1874     dump_store_bat(env, 'I', 1, nr, value);
1875     if (env->IBAT[1][nr] != value) {
1876 #if defined(FLUSH_ALL_TLBS)
1877         do_inval = 0;
1878 #endif
1879         if (env->IBAT[1][nr] & 0x40) {
1880 #if !defined(FLUSH_ALL_TLBS)
1881             mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
1882             do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1883 #else
1884             do_inval = 1;
1885 #endif
1886         }
1887         if (value & 0x40) {
1888 #if !defined(FLUSH_ALL_TLBS)
1889             mask = (value << 17) & 0x0FFE0000UL;
1890             do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1891 #else
1892             do_inval = 1;
1893 #endif
1894         }
1895         env->IBAT[1][nr] = value;
1896         env->DBAT[1][nr] = value;
1897 #if defined(FLUSH_ALL_TLBS)
1898         if (do_inval) {
1899             tlb_flush(env_cpu(env));
1900         }
1901 #endif
1902     }
1903 }
1904 #endif
1905 
1906 #ifdef CONFIG_TCG
1907 /*****************************************************************************/
1908 /* TLB management */
1909 void ppc_tlb_invalidate_all(CPUPPCState *env)
1910 {
1911 #if defined(TARGET_PPC64)
1912     if (mmu_is_64bit(env->mmu_model)) {
1913         env->tlb_need_flush = 0;
1914         tlb_flush(env_cpu(env));
1915     } else
1916 #endif /* defined(TARGET_PPC64) */
1917     switch (env->mmu_model) {
1918     case POWERPC_MMU_SOFT_6xx:
1919     case POWERPC_MMU_SOFT_74xx:
1920         ppc6xx_tlb_invalidate_all(env);
1921         break;
1922     case POWERPC_MMU_SOFT_4xx:
1923     case POWERPC_MMU_SOFT_4xx_Z:
1924         ppc4xx_tlb_invalidate_all(env);
1925         break;
1926     case POWERPC_MMU_REAL:
1927         cpu_abort(env_cpu(env), "No TLB for PowerPC 4xx in real mode\n");
1928         break;
1929     case POWERPC_MMU_MPC8xx:
1930         /* XXX: TODO */
1931         cpu_abort(env_cpu(env), "MPC8xx MMU model is not implemented\n");
1932         break;
1933     case POWERPC_MMU_BOOKE:
1934         tlb_flush(env_cpu(env));
1935         break;
1936     case POWERPC_MMU_BOOKE206:
1937         booke206_flush_tlb(env, -1, 0);
1938         break;
1939     case POWERPC_MMU_32B:
1940     case POWERPC_MMU_601:
1941         env->tlb_need_flush = 0;
1942         tlb_flush(env_cpu(env));
1943         break;
1944     default:
1945         /* XXX: TODO */
1946         cpu_abort(env_cpu(env), "Unknown MMU model %x\n", env->mmu_model);
1947         break;
1948     }
1949 }
1950 #endif
1951 
1952 #ifdef CONFIG_TCG
1953 void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
1954 {
1955 #if !defined(FLUSH_ALL_TLBS)
1956     addr &= TARGET_PAGE_MASK;
1957 #if defined(TARGET_PPC64)
1958     if (mmu_is_64bit(env->mmu_model)) {
1959         /* tlbie invalidate TLBs for all segments */
1960         /*
1961          * XXX: given the fact that there are too many segments to invalidate,
1962          *      and we still don't have a tlb_flush_mask(env, n, mask) in QEMU,
1963          *      we just invalidate all TLBs
1964          */
1965         env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH;
1966     } else
1967 #endif /* defined(TARGET_PPC64) */
1968     switch (env->mmu_model) {
1969     case POWERPC_MMU_SOFT_6xx:
1970     case POWERPC_MMU_SOFT_74xx:
1971         ppc6xx_tlb_invalidate_virt(env, addr, 0);
1972         if (env->id_tlbs == 1) {
1973             ppc6xx_tlb_invalidate_virt(env, addr, 1);
1974         }
1975         break;
1976     case POWERPC_MMU_32B:
1977     case POWERPC_MMU_601:
1978         /*
1979          * Actual CPUs invalidate entire congruence classes based on
1980          * the geometry of their TLBs and some OSes take that into
1981          * account, we just mark the TLB to be flushed later (context
1982          * synchronizing event or sync instruction on 32-bit).
1983          */
1984         env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH;
1985         break;
1986     default:
1987         /* Should never reach here with other MMU models */
1988         assert(0);
1989     }
1990 #else
1991     ppc_tlb_invalidate_all(env);
1992 #endif
1993 }
1994 
1995 /*****************************************************************************/
1996 /* Special registers manipulation */
1997 
1998 /* Segment registers load and store */
1999 target_ulong helper_load_sr(CPUPPCState *env, target_ulong sr_num)
2000 {
2001 #if defined(TARGET_PPC64)
2002     if (mmu_is_64bit(env->mmu_model)) {
2003         /* XXX */
2004         return 0;
2005     }
2006 #endif
2007     return env->sr[sr_num];
2008 }
2009 
2010 void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value)
2011 {
2012     qemu_log_mask(CPU_LOG_MMU,
2013             "%s: reg=%d " TARGET_FMT_lx " " TARGET_FMT_lx "\n", __func__,
2014             (int)srnum, value, env->sr[srnum]);
2015 #if defined(TARGET_PPC64)
2016     if (mmu_is_64bit(env->mmu_model)) {
2017         PowerPCCPU *cpu = env_archcpu(env);
2018         uint64_t esid, vsid;
2019 
2020         /* ESID = srnum */
2021         esid = ((uint64_t)(srnum & 0xf) << 28) | SLB_ESID_V;
2022 
2023         /* VSID = VSID */
2024         vsid = (value & 0xfffffff) << 12;
2025         /* flags = flags */
2026         vsid |= ((value >> 27) & 0xf) << 8;
2027 
2028         ppc_store_slb(cpu, srnum, esid, vsid);
2029     } else
2030 #endif
2031     if (env->sr[srnum] != value) {
2032         env->sr[srnum] = value;
2033         /*
2034          * Invalidating 256MB of virtual memory in 4kB pages is way
2035          * longer than flushing the whole TLB.
2036          */
2037 #if !defined(FLUSH_ALL_TLBS) && 0
2038         {
2039             target_ulong page, end;
2040             /* Invalidate 256 MB of virtual memory */
2041             page = (16 << 20) * srnum;
2042             end = page + (16 << 20);
2043             for (; page != end; page += TARGET_PAGE_SIZE) {
2044                 tlb_flush_page(env_cpu(env), page);
2045             }
2046         }
2047 #else
2048         env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH;
2049 #endif
2050     }
2051 }
2052 
2053 /* TLB management */
2054 void helper_tlbia(CPUPPCState *env)
2055 {
2056     ppc_tlb_invalidate_all(env);
2057 }
2058 
2059 void helper_tlbie(CPUPPCState *env, target_ulong addr)
2060 {
2061     ppc_tlb_invalidate_one(env, addr);
2062 }
2063 
2064 void helper_tlbiva(CPUPPCState *env, target_ulong addr)
2065 {
2066     /* tlbiva instruction only exists on BookE */
2067     assert(env->mmu_model == POWERPC_MMU_BOOKE);
2068     /* XXX: TODO */
2069     cpu_abort(env_cpu(env), "BookE MMU model is not implemented\n");
2070 }
2071 
2072 /* Software driven TLBs management */
2073 /* PowerPC 602/603 software TLB load instructions helpers */
2074 static void do_6xx_tlb(CPUPPCState *env, target_ulong new_EPN, int is_code)
2075 {
2076     target_ulong RPN, CMP, EPN;
2077     int way;
2078 
2079     RPN = env->spr[SPR_RPA];
2080     if (is_code) {
2081         CMP = env->spr[SPR_ICMP];
2082         EPN = env->spr[SPR_IMISS];
2083     } else {
2084         CMP = env->spr[SPR_DCMP];
2085         EPN = env->spr[SPR_DMISS];
2086     }
2087     way = (env->spr[SPR_SRR1] >> 17) & 1;
2088     (void)EPN; /* avoid a compiler warning */
2089     LOG_SWTLB("%s: EPN " TARGET_FMT_lx " " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx
2090               " PTE1 " TARGET_FMT_lx " way %d\n", __func__, new_EPN, EPN, CMP,
2091               RPN, way);
2092     /* Store this TLB */
2093     ppc6xx_tlb_store(env, (uint32_t)(new_EPN & TARGET_PAGE_MASK),
2094                      way, is_code, CMP, RPN);
2095 }
2096 
2097 void helper_6xx_tlbd(CPUPPCState *env, target_ulong EPN)
2098 {
2099     do_6xx_tlb(env, EPN, 0);
2100 }
2101 
2102 void helper_6xx_tlbi(CPUPPCState *env, target_ulong EPN)
2103 {
2104     do_6xx_tlb(env, EPN, 1);
2105 }
2106 
2107 /* PowerPC 74xx software TLB load instructions helpers */
2108 static void do_74xx_tlb(CPUPPCState *env, target_ulong new_EPN, int is_code)
2109 {
2110     target_ulong RPN, CMP, EPN;
2111     int way;
2112 
2113     RPN = env->spr[SPR_PTELO];
2114     CMP = env->spr[SPR_PTEHI];
2115     EPN = env->spr[SPR_TLBMISS] & ~0x3;
2116     way = env->spr[SPR_TLBMISS] & 0x3;
2117     (void)EPN; /* avoid a compiler warning */
2118     LOG_SWTLB("%s: EPN " TARGET_FMT_lx " " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx
2119               " PTE1 " TARGET_FMT_lx " way %d\n", __func__, new_EPN, EPN, CMP,
2120               RPN, way);
2121     /* Store this TLB */
2122     ppc6xx_tlb_store(env, (uint32_t)(new_EPN & TARGET_PAGE_MASK),
2123                      way, is_code, CMP, RPN);
2124 }
2125 
2126 void helper_74xx_tlbd(CPUPPCState *env, target_ulong EPN)
2127 {
2128     do_74xx_tlb(env, EPN, 0);
2129 }
2130 
2131 void helper_74xx_tlbi(CPUPPCState *env, target_ulong EPN)
2132 {
2133     do_74xx_tlb(env, EPN, 1);
2134 }
2135 
2136 /*****************************************************************************/
2137 /* PowerPC 601 specific instructions (POWER bridge) */
2138 
2139 target_ulong helper_rac(CPUPPCState *env, target_ulong addr)
2140 {
2141     mmu_ctx_t ctx;
2142     int nb_BATs;
2143     target_ulong ret = 0;
2144 
2145     /*
2146      * We don't have to generate many instances of this instruction,
2147      * as rac is supervisor only.
2148      *
2149      * XXX: FIX THIS: Pretend we have no BAT
2150      */
2151     nb_BATs = env->nb_BATs;
2152     env->nb_BATs = 0;
2153     if (get_physical_address(env, &ctx, addr, 0, ACCESS_INT) == 0) {
2154         ret = ctx.raddr;
2155     }
2156     env->nb_BATs = nb_BATs;
2157     return ret;
2158 }
2159 
2160 static inline target_ulong booke_tlb_to_page_size(int size)
2161 {
2162     return 1024 << (2 * size);
2163 }
2164 
2165 static inline int booke_page_size_to_tlb(target_ulong page_size)
2166 {
2167     int size;
2168 
2169     switch (page_size) {
2170     case 0x00000400UL:
2171         size = 0x0;
2172         break;
2173     case 0x00001000UL:
2174         size = 0x1;
2175         break;
2176     case 0x00004000UL:
2177         size = 0x2;
2178         break;
2179     case 0x00010000UL:
2180         size = 0x3;
2181         break;
2182     case 0x00040000UL:
2183         size = 0x4;
2184         break;
2185     case 0x00100000UL:
2186         size = 0x5;
2187         break;
2188     case 0x00400000UL:
2189         size = 0x6;
2190         break;
2191     case 0x01000000UL:
2192         size = 0x7;
2193         break;
2194     case 0x04000000UL:
2195         size = 0x8;
2196         break;
2197     case 0x10000000UL:
2198         size = 0x9;
2199         break;
2200     case 0x40000000UL:
2201         size = 0xA;
2202         break;
2203 #if defined(TARGET_PPC64)
2204     case 0x000100000000ULL:
2205         size = 0xB;
2206         break;
2207     case 0x000400000000ULL:
2208         size = 0xC;
2209         break;
2210     case 0x001000000000ULL:
2211         size = 0xD;
2212         break;
2213     case 0x004000000000ULL:
2214         size = 0xE;
2215         break;
2216     case 0x010000000000ULL:
2217         size = 0xF;
2218         break;
2219 #endif
2220     default:
2221         size = -1;
2222         break;
2223     }
2224 
2225     return size;
2226 }
2227 
2228 /* Helpers for 4xx TLB management */
2229 #define PPC4XX_TLB_ENTRY_MASK       0x0000003f  /* Mask for 64 TLB entries */
2230 
2231 #define PPC4XX_TLBHI_V              0x00000040
2232 #define PPC4XX_TLBHI_E              0x00000020
2233 #define PPC4XX_TLBHI_SIZE_MIN       0
2234 #define PPC4XX_TLBHI_SIZE_MAX       7
2235 #define PPC4XX_TLBHI_SIZE_DEFAULT   1
2236 #define PPC4XX_TLBHI_SIZE_SHIFT     7
2237 #define PPC4XX_TLBHI_SIZE_MASK      0x00000007
2238 
2239 #define PPC4XX_TLBLO_EX             0x00000200
2240 #define PPC4XX_TLBLO_WR             0x00000100
2241 #define PPC4XX_TLBLO_ATTR_MASK      0x000000FF
2242 #define PPC4XX_TLBLO_RPN_MASK       0xFFFFFC00
2243 
2244 target_ulong helper_4xx_tlbre_hi(CPUPPCState *env, target_ulong entry)
2245 {
2246     ppcemb_tlb_t *tlb;
2247     target_ulong ret;
2248     int size;
2249 
2250     entry &= PPC4XX_TLB_ENTRY_MASK;
2251     tlb = &env->tlb.tlbe[entry];
2252     ret = tlb->EPN;
2253     if (tlb->prot & PAGE_VALID) {
2254         ret |= PPC4XX_TLBHI_V;
2255     }
2256     size = booke_page_size_to_tlb(tlb->size);
2257     if (size < PPC4XX_TLBHI_SIZE_MIN || size > PPC4XX_TLBHI_SIZE_MAX) {
2258         size = PPC4XX_TLBHI_SIZE_DEFAULT;
2259     }
2260     ret |= size << PPC4XX_TLBHI_SIZE_SHIFT;
2261     env->spr[SPR_40x_PID] = tlb->PID;
2262     return ret;
2263 }
2264 
2265 target_ulong helper_4xx_tlbre_lo(CPUPPCState *env, target_ulong entry)
2266 {
2267     ppcemb_tlb_t *tlb;
2268     target_ulong ret;
2269 
2270     entry &= PPC4XX_TLB_ENTRY_MASK;
2271     tlb = &env->tlb.tlbe[entry];
2272     ret = tlb->RPN;
2273     if (tlb->prot & PAGE_EXEC) {
2274         ret |= PPC4XX_TLBLO_EX;
2275     }
2276     if (tlb->prot & PAGE_WRITE) {
2277         ret |= PPC4XX_TLBLO_WR;
2278     }
2279     return ret;
2280 }
2281 
2282 void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry,
2283                          target_ulong val)
2284 {
2285     CPUState *cs = env_cpu(env);
2286     ppcemb_tlb_t *tlb;
2287     target_ulong page, end;
2288 
2289     LOG_SWTLB("%s entry %d val " TARGET_FMT_lx "\n", __func__, (int)entry,
2290               val);
2291     entry &= PPC4XX_TLB_ENTRY_MASK;
2292     tlb = &env->tlb.tlbe[entry];
2293     /* Invalidate previous TLB (if it's valid) */
2294     if (tlb->prot & PAGE_VALID) {
2295         end = tlb->EPN + tlb->size;
2296         LOG_SWTLB("%s: invalidate old TLB %d start " TARGET_FMT_lx " end "
2297                   TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end);
2298         for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) {
2299             tlb_flush_page(cs, page);
2300         }
2301     }
2302     tlb->size = booke_tlb_to_page_size((val >> PPC4XX_TLBHI_SIZE_SHIFT)
2303                                        & PPC4XX_TLBHI_SIZE_MASK);
2304     /*
2305      * We cannot handle TLB size < TARGET_PAGE_SIZE.
2306      * If this ever occurs, we should implement TARGET_PAGE_BITS_VARY
2307      */
2308     if ((val & PPC4XX_TLBHI_V) && tlb->size < TARGET_PAGE_SIZE) {
2309         cpu_abort(cs, "TLB size " TARGET_FMT_lu " < %u "
2310                   "are not supported (%d)\n"
2311                   "Please implement TARGET_PAGE_BITS_VARY\n",
2312                   tlb->size, TARGET_PAGE_SIZE, (int)((val >> 7) & 0x7));
2313     }
2314     tlb->EPN = val & ~(tlb->size - 1);
2315     if (val & PPC4XX_TLBHI_V) {
2316         tlb->prot |= PAGE_VALID;
2317         if (val & PPC4XX_TLBHI_E) {
2318             /* XXX: TO BE FIXED */
2319             cpu_abort(cs,
2320                       "Little-endian TLB entries are not supported by now\n");
2321         }
2322     } else {
2323         tlb->prot &= ~PAGE_VALID;
2324     }
2325     tlb->PID = env->spr[SPR_40x_PID]; /* PID */
2326     LOG_SWTLB("%s: set up TLB %d RPN " TARGET_FMT_plx " EPN " TARGET_FMT_lx
2327               " size " TARGET_FMT_lx " prot %c%c%c%c PID %d\n", __func__,
2328               (int)entry, tlb->RPN, tlb->EPN, tlb->size,
2329               tlb->prot & PAGE_READ ? 'r' : '-',
2330               tlb->prot & PAGE_WRITE ? 'w' : '-',
2331               tlb->prot & PAGE_EXEC ? 'x' : '-',
2332               tlb->prot & PAGE_VALID ? 'v' : '-', (int)tlb->PID);
2333     /* Invalidate new TLB (if valid) */
2334     if (tlb->prot & PAGE_VALID) {
2335         end = tlb->EPN + tlb->size;
2336         LOG_SWTLB("%s: invalidate TLB %d start " TARGET_FMT_lx " end "
2337                   TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end);
2338         for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) {
2339             tlb_flush_page(cs, page);
2340         }
2341     }
2342 }
2343 
2344 void helper_4xx_tlbwe_lo(CPUPPCState *env, target_ulong entry,
2345                          target_ulong val)
2346 {
2347     ppcemb_tlb_t *tlb;
2348 
2349     LOG_SWTLB("%s entry %i val " TARGET_FMT_lx "\n", __func__, (int)entry,
2350               val);
2351     entry &= PPC4XX_TLB_ENTRY_MASK;
2352     tlb = &env->tlb.tlbe[entry];
2353     tlb->attr = val & PPC4XX_TLBLO_ATTR_MASK;
2354     tlb->RPN = val & PPC4XX_TLBLO_RPN_MASK;
2355     tlb->prot = PAGE_READ;
2356     if (val & PPC4XX_TLBLO_EX) {
2357         tlb->prot |= PAGE_EXEC;
2358     }
2359     if (val & PPC4XX_TLBLO_WR) {
2360         tlb->prot |= PAGE_WRITE;
2361     }
2362     LOG_SWTLB("%s: set up TLB %d RPN " TARGET_FMT_plx " EPN " TARGET_FMT_lx
2363               " size " TARGET_FMT_lx " prot %c%c%c%c PID %d\n", __func__,
2364               (int)entry, tlb->RPN, tlb->EPN, tlb->size,
2365               tlb->prot & PAGE_READ ? 'r' : '-',
2366               tlb->prot & PAGE_WRITE ? 'w' : '-',
2367               tlb->prot & PAGE_EXEC ? 'x' : '-',
2368               tlb->prot & PAGE_VALID ? 'v' : '-', (int)tlb->PID);
2369 }
2370 
2371 target_ulong helper_4xx_tlbsx(CPUPPCState *env, target_ulong address)
2372 {
2373     return ppcemb_tlb_search(env, address, env->spr[SPR_40x_PID]);
2374 }
2375 
2376 /* PowerPC 440 TLB management */
2377 void helper_440_tlbwe(CPUPPCState *env, uint32_t word, target_ulong entry,
2378                       target_ulong value)
2379 {
2380     ppcemb_tlb_t *tlb;
2381     target_ulong EPN, RPN, size;
2382     int do_flush_tlbs;
2383 
2384     LOG_SWTLB("%s word %d entry %d value " TARGET_FMT_lx "\n",
2385               __func__, word, (int)entry, value);
2386     do_flush_tlbs = 0;
2387     entry &= 0x3F;
2388     tlb = &env->tlb.tlbe[entry];
2389     switch (word) {
2390     default:
2391         /* Just here to please gcc */
2392     case 0:
2393         EPN = value & 0xFFFFFC00;
2394         if ((tlb->prot & PAGE_VALID) && EPN != tlb->EPN) {
2395             do_flush_tlbs = 1;
2396         }
2397         tlb->EPN = EPN;
2398         size = booke_tlb_to_page_size((value >> 4) & 0xF);
2399         if ((tlb->prot & PAGE_VALID) && tlb->size < size) {
2400             do_flush_tlbs = 1;
2401         }
2402         tlb->size = size;
2403         tlb->attr &= ~0x1;
2404         tlb->attr |= (value >> 8) & 1;
2405         if (value & 0x200) {
2406             tlb->prot |= PAGE_VALID;
2407         } else {
2408             if (tlb->prot & PAGE_VALID) {
2409                 tlb->prot &= ~PAGE_VALID;
2410                 do_flush_tlbs = 1;
2411             }
2412         }
2413         tlb->PID = env->spr[SPR_440_MMUCR] & 0x000000FF;
2414         if (do_flush_tlbs) {
2415             tlb_flush(env_cpu(env));
2416         }
2417         break;
2418     case 1:
2419         RPN = value & 0xFFFFFC0F;
2420         if ((tlb->prot & PAGE_VALID) && tlb->RPN != RPN) {
2421             tlb_flush(env_cpu(env));
2422         }
2423         tlb->RPN = RPN;
2424         break;
2425     case 2:
2426         tlb->attr = (tlb->attr & 0x1) | (value & 0x0000FF00);
2427         tlb->prot = tlb->prot & PAGE_VALID;
2428         if (value & 0x1) {
2429             tlb->prot |= PAGE_READ << 4;
2430         }
2431         if (value & 0x2) {
2432             tlb->prot |= PAGE_WRITE << 4;
2433         }
2434         if (value & 0x4) {
2435             tlb->prot |= PAGE_EXEC << 4;
2436         }
2437         if (value & 0x8) {
2438             tlb->prot |= PAGE_READ;
2439         }
2440         if (value & 0x10) {
2441             tlb->prot |= PAGE_WRITE;
2442         }
2443         if (value & 0x20) {
2444             tlb->prot |= PAGE_EXEC;
2445         }
2446         break;
2447     }
2448 }
2449 
2450 target_ulong helper_440_tlbre(CPUPPCState *env, uint32_t word,
2451                               target_ulong entry)
2452 {
2453     ppcemb_tlb_t *tlb;
2454     target_ulong ret;
2455     int size;
2456 
2457     entry &= 0x3F;
2458     tlb = &env->tlb.tlbe[entry];
2459     switch (word) {
2460     default:
2461         /* Just here to please gcc */
2462     case 0:
2463         ret = tlb->EPN;
2464         size = booke_page_size_to_tlb(tlb->size);
2465         if (size < 0 || size > 0xF) {
2466             size = 1;
2467         }
2468         ret |= size << 4;
2469         if (tlb->attr & 0x1) {
2470             ret |= 0x100;
2471         }
2472         if (tlb->prot & PAGE_VALID) {
2473             ret |= 0x200;
2474         }
2475         env->spr[SPR_440_MMUCR] &= ~0x000000FF;
2476         env->spr[SPR_440_MMUCR] |= tlb->PID;
2477         break;
2478     case 1:
2479         ret = tlb->RPN;
2480         break;
2481     case 2:
2482         ret = tlb->attr & ~0x1;
2483         if (tlb->prot & (PAGE_READ << 4)) {
2484             ret |= 0x1;
2485         }
2486         if (tlb->prot & (PAGE_WRITE << 4)) {
2487             ret |= 0x2;
2488         }
2489         if (tlb->prot & (PAGE_EXEC << 4)) {
2490             ret |= 0x4;
2491         }
2492         if (tlb->prot & PAGE_READ) {
2493             ret |= 0x8;
2494         }
2495         if (tlb->prot & PAGE_WRITE) {
2496             ret |= 0x10;
2497         }
2498         if (tlb->prot & PAGE_EXEC) {
2499             ret |= 0x20;
2500         }
2501         break;
2502     }
2503     return ret;
2504 }
2505 
2506 target_ulong helper_440_tlbsx(CPUPPCState *env, target_ulong address)
2507 {
2508     return ppcemb_tlb_search(env, address, env->spr[SPR_440_MMUCR] & 0xFF);
2509 }
2510 
2511 /* PowerPC BookE 2.06 TLB management */
2512 
2513 static ppcmas_tlb_t *booke206_cur_tlb(CPUPPCState *env)
2514 {
2515     uint32_t tlbncfg = 0;
2516     int esel = (env->spr[SPR_BOOKE_MAS0] & MAS0_ESEL_MASK) >> MAS0_ESEL_SHIFT;
2517     int ea = (env->spr[SPR_BOOKE_MAS2] & MAS2_EPN_MASK);
2518     int tlb;
2519 
2520     tlb = (env->spr[SPR_BOOKE_MAS0] & MAS0_TLBSEL_MASK) >> MAS0_TLBSEL_SHIFT;
2521     tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlb];
2522 
2523     if ((tlbncfg & TLBnCFG_HES) && (env->spr[SPR_BOOKE_MAS0] & MAS0_HES)) {
2524         cpu_abort(env_cpu(env), "we don't support HES yet\n");
2525     }
2526 
2527     return booke206_get_tlbm(env, tlb, ea, esel);
2528 }
2529 
2530 void helper_booke_setpid(CPUPPCState *env, uint32_t pidn, target_ulong pid)
2531 {
2532     env->spr[pidn] = pid;
2533     /* changing PIDs mean we're in a different address space now */
2534     tlb_flush(env_cpu(env));
2535 }
2536 
2537 void helper_booke_set_eplc(CPUPPCState *env, target_ulong val)
2538 {
2539     env->spr[SPR_BOOKE_EPLC] = val & EPID_MASK;
2540     tlb_flush_by_mmuidx(env_cpu(env), 1 << PPC_TLB_EPID_LOAD);
2541 }
2542 void helper_booke_set_epsc(CPUPPCState *env, target_ulong val)
2543 {
2544     env->spr[SPR_BOOKE_EPSC] = val & EPID_MASK;
2545     tlb_flush_by_mmuidx(env_cpu(env), 1 << PPC_TLB_EPID_STORE);
2546 }
2547 
2548 static inline void flush_page(CPUPPCState *env, ppcmas_tlb_t *tlb)
2549 {
2550     if (booke206_tlb_to_page_size(env, tlb) == TARGET_PAGE_SIZE) {
2551         tlb_flush_page(env_cpu(env), tlb->mas2 & MAS2_EPN_MASK);
2552     } else {
2553         tlb_flush(env_cpu(env));
2554     }
2555 }
2556 
2557 void helper_booke206_tlbwe(CPUPPCState *env)
2558 {
2559     uint32_t tlbncfg, tlbn;
2560     ppcmas_tlb_t *tlb;
2561     uint32_t size_tlb, size_ps;
2562     target_ulong mask;
2563 
2564 
2565     switch (env->spr[SPR_BOOKE_MAS0] & MAS0_WQ_MASK) {
2566     case MAS0_WQ_ALWAYS:
2567         /* good to go, write that entry */
2568         break;
2569     case MAS0_WQ_COND:
2570         /* XXX check if reserved */
2571         if (0) {
2572             return;
2573         }
2574         break;
2575     case MAS0_WQ_CLR_RSRV:
2576         /* XXX clear entry */
2577         return;
2578     default:
2579         /* no idea what to do */
2580         return;
2581     }
2582 
2583     if (((env->spr[SPR_BOOKE_MAS0] & MAS0_ATSEL) == MAS0_ATSEL_LRAT) &&
2584         !msr_gs) {
2585         /* XXX we don't support direct LRAT setting yet */
2586         fprintf(stderr, "cpu: don't support LRAT setting yet\n");
2587         return;
2588     }
2589 
2590     tlbn = (env->spr[SPR_BOOKE_MAS0] & MAS0_TLBSEL_MASK) >> MAS0_TLBSEL_SHIFT;
2591     tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn];
2592 
2593     tlb = booke206_cur_tlb(env);
2594 
2595     if (!tlb) {
2596         raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2597                                POWERPC_EXCP_INVAL |
2598                                POWERPC_EXCP_INVAL_INVAL, GETPC());
2599     }
2600 
2601     /* check that we support the targeted size */
2602     size_tlb = (env->spr[SPR_BOOKE_MAS1] & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
2603     size_ps = booke206_tlbnps(env, tlbn);
2604     if ((env->spr[SPR_BOOKE_MAS1] & MAS1_VALID) && (tlbncfg & TLBnCFG_AVAIL) &&
2605         !(size_ps & (1 << size_tlb))) {
2606         raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
2607                                POWERPC_EXCP_INVAL |
2608                                POWERPC_EXCP_INVAL_INVAL, GETPC());
2609     }
2610 
2611     if (msr_gs) {
2612         cpu_abort(env_cpu(env), "missing HV implementation\n");
2613     }
2614 
2615     if (tlb->mas1 & MAS1_VALID) {
2616         /*
2617          * Invalidate the page in QEMU TLB if it was a valid entry.
2618          *
2619          * In "PowerPC e500 Core Family Reference Manual, Rev. 1",
2620          * Section "12.4.2 TLB Write Entry (tlbwe) Instruction":
2621          * (https://www.nxp.com/docs/en/reference-manual/E500CORERM.pdf)
2622          *
2623          * "Note that when an L2 TLB entry is written, it may be displacing an
2624          * already valid entry in the same L2 TLB location (a victim). If a
2625          * valid L1 TLB entry corresponds to the L2 MMU victim entry, that L1
2626          * TLB entry is automatically invalidated."
2627          */
2628         flush_page(env, tlb);
2629     }
2630 
2631     tlb->mas7_3 = ((uint64_t)env->spr[SPR_BOOKE_MAS7] << 32) |
2632         env->spr[SPR_BOOKE_MAS3];
2633     tlb->mas1 = env->spr[SPR_BOOKE_MAS1];
2634 
2635     if ((env->spr[SPR_MMUCFG] & MMUCFG_MAVN) == MMUCFG_MAVN_V2) {
2636         /* For TLB which has a fixed size TSIZE is ignored with MAV2 */
2637         booke206_fixed_size_tlbn(env, tlbn, tlb);
2638     } else {
2639         if (!(tlbncfg & TLBnCFG_AVAIL)) {
2640             /* force !AVAIL TLB entries to correct page size */
2641             tlb->mas1 &= ~MAS1_TSIZE_MASK;
2642             /* XXX can be configured in MMUCSR0 */
2643             tlb->mas1 |= (tlbncfg & TLBnCFG_MINSIZE) >> 12;
2644         }
2645     }
2646 
2647     /* Make a mask from TLB size to discard invalid bits in EPN field */
2648     mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
2649     /* Add a mask for page attributes */
2650     mask |= MAS2_ACM | MAS2_VLE | MAS2_W | MAS2_I | MAS2_M | MAS2_G | MAS2_E;
2651 
2652     if (!msr_cm) {
2653         /*
2654          * Executing a tlbwe instruction in 32-bit mode will set bits
2655          * 0:31 of the TLB EPN field to zero.
2656          */
2657         mask &= 0xffffffff;
2658     }
2659 
2660     tlb->mas2 = env->spr[SPR_BOOKE_MAS2] & mask;
2661 
2662     if (!(tlbncfg & TLBnCFG_IPROT)) {
2663         /* no IPROT supported by TLB */
2664         tlb->mas1 &= ~MAS1_IPROT;
2665     }
2666 
2667     flush_page(env, tlb);
2668 }
2669 
2670 static inline void booke206_tlb_to_mas(CPUPPCState *env, ppcmas_tlb_t *tlb)
2671 {
2672     int tlbn = booke206_tlbm_to_tlbn(env, tlb);
2673     int way = booke206_tlbm_to_way(env, tlb);
2674 
2675     env->spr[SPR_BOOKE_MAS0] = tlbn << MAS0_TLBSEL_SHIFT;
2676     env->spr[SPR_BOOKE_MAS0] |= way << MAS0_ESEL_SHIFT;
2677     env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
2678 
2679     env->spr[SPR_BOOKE_MAS1] = tlb->mas1;
2680     env->spr[SPR_BOOKE_MAS2] = tlb->mas2;
2681     env->spr[SPR_BOOKE_MAS3] = tlb->mas7_3;
2682     env->spr[SPR_BOOKE_MAS7] = tlb->mas7_3 >> 32;
2683 }
2684 
2685 void helper_booke206_tlbre(CPUPPCState *env)
2686 {
2687     ppcmas_tlb_t *tlb = NULL;
2688 
2689     tlb = booke206_cur_tlb(env);
2690     if (!tlb) {
2691         env->spr[SPR_BOOKE_MAS1] = 0;
2692     } else {
2693         booke206_tlb_to_mas(env, tlb);
2694     }
2695 }
2696 
2697 void helper_booke206_tlbsx(CPUPPCState *env, target_ulong address)
2698 {
2699     ppcmas_tlb_t *tlb = NULL;
2700     int i, j;
2701     hwaddr raddr;
2702     uint32_t spid, sas;
2703 
2704     spid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID_MASK) >> MAS6_SPID_SHIFT;
2705     sas = env->spr[SPR_BOOKE_MAS6] & MAS6_SAS;
2706 
2707     for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
2708         int ways = booke206_tlb_ways(env, i);
2709 
2710         for (j = 0; j < ways; j++) {
2711             tlb = booke206_get_tlbm(env, i, address, j);
2712 
2713             if (!tlb) {
2714                 continue;
2715             }
2716 
2717             if (ppcmas_tlb_check(env, tlb, &raddr, address, spid)) {
2718                 continue;
2719             }
2720 
2721             if (sas != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
2722                 continue;
2723             }
2724 
2725             booke206_tlb_to_mas(env, tlb);
2726             return;
2727         }
2728     }
2729 
2730     /* no entry found, fill with defaults */
2731     env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK;
2732     env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK;
2733     env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK;
2734     env->spr[SPR_BOOKE_MAS3] = 0;
2735     env->spr[SPR_BOOKE_MAS7] = 0;
2736 
2737     if (env->spr[SPR_BOOKE_MAS6] & MAS6_SAS) {
2738         env->spr[SPR_BOOKE_MAS1] |= MAS1_TS;
2739     }
2740 
2741     env->spr[SPR_BOOKE_MAS1] |= (env->spr[SPR_BOOKE_MAS6] >> 16)
2742         << MAS1_TID_SHIFT;
2743 
2744     /* next victim logic */
2745     env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
2746     env->last_way++;
2747     env->last_way &= booke206_tlb_ways(env, 0) - 1;
2748     env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
2749 }
2750 
2751 static inline void booke206_invalidate_ea_tlb(CPUPPCState *env, int tlbn,
2752                                               uint32_t ea)
2753 {
2754     int i;
2755     int ways = booke206_tlb_ways(env, tlbn);
2756     target_ulong mask;
2757 
2758     for (i = 0; i < ways; i++) {
2759         ppcmas_tlb_t *tlb = booke206_get_tlbm(env, tlbn, ea, i);
2760         if (!tlb) {
2761             continue;
2762         }
2763         mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
2764         if (((tlb->mas2 & MAS2_EPN_MASK) == (ea & mask)) &&
2765             !(tlb->mas1 & MAS1_IPROT)) {
2766             tlb->mas1 &= ~MAS1_VALID;
2767         }
2768     }
2769 }
2770 
2771 void helper_booke206_tlbivax(CPUPPCState *env, target_ulong address)
2772 {
2773     CPUState *cs;
2774 
2775     if (address & 0x4) {
2776         /* flush all entries */
2777         if (address & 0x8) {
2778             /* flush all of TLB1 */
2779             booke206_flush_tlb(env, BOOKE206_FLUSH_TLB1, 1);
2780         } else {
2781             /* flush all of TLB0 */
2782             booke206_flush_tlb(env, BOOKE206_FLUSH_TLB0, 0);
2783         }
2784         return;
2785     }
2786 
2787     if (address & 0x8) {
2788         /* flush TLB1 entries */
2789         booke206_invalidate_ea_tlb(env, 1, address);
2790         CPU_FOREACH(cs) {
2791             tlb_flush(cs);
2792         }
2793     } else {
2794         /* flush TLB0 entries */
2795         booke206_invalidate_ea_tlb(env, 0, address);
2796         CPU_FOREACH(cs) {
2797             tlb_flush_page(cs, address & MAS2_EPN_MASK);
2798         }
2799     }
2800 }
2801 
2802 void helper_booke206_tlbilx0(CPUPPCState *env, target_ulong address)
2803 {
2804     /* XXX missing LPID handling */
2805     booke206_flush_tlb(env, -1, 1);
2806 }
2807 
2808 void helper_booke206_tlbilx1(CPUPPCState *env, target_ulong address)
2809 {
2810     int i, j;
2811     int tid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID);
2812     ppcmas_tlb_t *tlb = env->tlb.tlbm;
2813     int tlb_size;
2814 
2815     /* XXX missing LPID handling */
2816     for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
2817         tlb_size = booke206_tlb_size(env, i);
2818         for (j = 0; j < tlb_size; j++) {
2819             if (!(tlb[j].mas1 & MAS1_IPROT) &&
2820                 ((tlb[j].mas1 & MAS1_TID_MASK) == tid)) {
2821                 tlb[j].mas1 &= ~MAS1_VALID;
2822             }
2823         }
2824         tlb += booke206_tlb_size(env, i);
2825     }
2826     tlb_flush(env_cpu(env));
2827 }
2828 
2829 void helper_booke206_tlbilx3(CPUPPCState *env, target_ulong address)
2830 {
2831     int i, j;
2832     ppcmas_tlb_t *tlb;
2833     int tid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID);
2834     int pid = tid >> MAS6_SPID_SHIFT;
2835     int sgs = env->spr[SPR_BOOKE_MAS5] & MAS5_SGS;
2836     int ind = (env->spr[SPR_BOOKE_MAS6] & MAS6_SIND) ? MAS1_IND : 0;
2837     /* XXX check for unsupported isize and raise an invalid opcode then */
2838     int size = env->spr[SPR_BOOKE_MAS6] & MAS6_ISIZE_MASK;
2839     /* XXX implement MAV2 handling */
2840     bool mav2 = false;
2841 
2842     /* XXX missing LPID handling */
2843     /* flush by pid and ea */
2844     for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
2845         int ways = booke206_tlb_ways(env, i);
2846 
2847         for (j = 0; j < ways; j++) {
2848             tlb = booke206_get_tlbm(env, i, address, j);
2849             if (!tlb) {
2850                 continue;
2851             }
2852             if ((ppcmas_tlb_check(env, tlb, NULL, address, pid) != 0) ||
2853                 (tlb->mas1 & MAS1_IPROT) ||
2854                 ((tlb->mas1 & MAS1_IND) != ind) ||
2855                 ((tlb->mas8 & MAS8_TGS) != sgs)) {
2856                 continue;
2857             }
2858             if (mav2 && ((tlb->mas1 & MAS1_TSIZE_MASK) != size)) {
2859                 /* XXX only check when MMUCFG[TWC] || TLBnCFG[HES] */
2860                 continue;
2861             }
2862             /* XXX e500mc doesn't match SAS, but other cores might */
2863             tlb->mas1 &= ~MAS1_VALID;
2864         }
2865     }
2866     tlb_flush(env_cpu(env));
2867 }
2868 
2869 void helper_booke206_tlbflush(CPUPPCState *env, target_ulong type)
2870 {
2871     int flags = 0;
2872 
2873     if (type & 2) {
2874         flags |= BOOKE206_FLUSH_TLB1;
2875     }
2876 
2877     if (type & 4) {
2878         flags |= BOOKE206_FLUSH_TLB0;
2879     }
2880 
2881     booke206_flush_tlb(env, flags, 1);
2882 }
2883 
2884 
2885 void helper_check_tlb_flush_local(CPUPPCState *env)
2886 {
2887     check_tlb_flush(env, false);
2888 }
2889 
2890 void helper_check_tlb_flush_global(CPUPPCState *env)
2891 {
2892     check_tlb_flush(env, true);
2893 }
2894 #endif /* CONFIG_TCG */
2895 
2896 /*****************************************************************************/
2897 
2898 static bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
2899                       hwaddr *raddrp, int *psizep, int *protp,
2900                       int mmu_idx, bool guest_visible)
2901 {
2902     switch (cpu->env.mmu_model) {
2903 #if defined(TARGET_PPC64)
2904     case POWERPC_MMU_3_00:
2905         if (ppc64_v3_radix(cpu)) {
2906             return ppc_radix64_xlate(cpu, eaddr, access_type,
2907                                      raddrp, psizep, protp, mmu_idx, guest_visible);
2908         }
2909         /* fall through */
2910     case POWERPC_MMU_64B:
2911     case POWERPC_MMU_2_03:
2912     case POWERPC_MMU_2_06:
2913     case POWERPC_MMU_2_07:
2914         return ppc_hash64_xlate(cpu, eaddr, access_type,
2915                                 raddrp, psizep, protp, mmu_idx, guest_visible);
2916 #endif
2917 
2918     case POWERPC_MMU_32B:
2919     case POWERPC_MMU_601:
2920         return ppc_hash32_xlate(cpu, eaddr, access_type,
2921                                 raddrp, psizep, protp, mmu_idx, guest_visible);
2922 
2923     default:
2924         return ppc_jumbo_xlate(cpu, eaddr, access_type, raddrp,
2925                                psizep, protp, mmu_idx, guest_visible);
2926     }
2927 }
2928 
2929 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
2930 {
2931     PowerPCCPU *cpu = POWERPC_CPU(cs);
2932     hwaddr raddr;
2933     int s, p;
2934 
2935     /*
2936      * Some MMUs have separate TLBs for code and data. If we only
2937      * try an MMU_DATA_LOAD, we may not be able to read instructions
2938      * mapped by code TLBs, so we also try a MMU_INST_FETCH.
2939      */
2940     if (ppc_xlate(cpu, addr, MMU_DATA_LOAD, &raddr, &s, &p,
2941                   cpu_mmu_index(&cpu->env, false), false) ||
2942         ppc_xlate(cpu, addr, MMU_INST_FETCH, &raddr, &s, &p,
2943                   cpu_mmu_index(&cpu->env, true), false)) {
2944         return raddr & TARGET_PAGE_MASK;
2945     }
2946     return -1;
2947 }
2948 
2949 #ifdef CONFIG_TCG
2950 bool ppc_cpu_tlb_fill(CPUState *cs, vaddr eaddr, int size,
2951                       MMUAccessType access_type, int mmu_idx,
2952                       bool probe, uintptr_t retaddr)
2953 {
2954     PowerPCCPU *cpu = POWERPC_CPU(cs);
2955     hwaddr raddr;
2956     int page_size, prot;
2957 
2958     if (ppc_xlate(cpu, eaddr, access_type, &raddr,
2959                   &page_size, &prot, mmu_idx, !probe)) {
2960         tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
2961                      prot, mmu_idx, 1UL << page_size);
2962         return true;
2963     }
2964     if (probe) {
2965         return false;
2966     }
2967     raise_exception_err_ra(&cpu->env, cs->exception_index,
2968                            cpu->env.error_code, retaddr);
2969 }
2970 #endif
2971