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