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