xref: /qemu/target/ppc/mmu_common.c (revision 0e2d7fc817678d8eedd8cae33bb7c191887466c8)
1 /*
2  *  PowerPC MMU, TLB, SLB and BAT emulation helpers for QEMU.
3  *
4  *  Copyright (c) 2003-2007 Jocelyn Mayer
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "qemu/osdep.h"
21 #include "qemu/units.h"
22 #include "cpu.h"
23 #include "sysemu/kvm.h"
24 #include "kvm_ppc.h"
25 #include "mmu-hash64.h"
26 #include "mmu-hash32.h"
27 #include "exec/exec-all.h"
28 #include "exec/page-protection.h"
29 #include "exec/log.h"
30 #include "helper_regs.h"
31 #include "qemu/error-report.h"
32 #include "qemu/qemu-print.h"
33 #include "internal.h"
34 #include "mmu-book3s-v3.h"
35 #include "mmu-radix64.h"
36 #include "mmu-booke.h"
37 
38 /* #define DUMP_PAGE_TABLES */
39 
40 /* Context used internally during MMU translations */
41 typedef struct {
42     hwaddr raddr;      /* Real address             */
43     int prot;          /* Protection bits          */
44     hwaddr hash[2];    /* Pagetable hash values    */
45     target_ulong ptem; /* Virtual segment ID | API */
46     int key;           /* Access key               */
47     int nx;            /* Non-execute area         */
48 } mmu_ctx_t;
49 
50 void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
51 {
52     PowerPCCPU *cpu = env_archcpu(env);
53     qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value);
54     assert(!cpu->env.has_hv_mode || !cpu->vhyp);
55 #if defined(TARGET_PPC64)
56     if (mmu_is_64bit(env->mmu_model)) {
57         target_ulong sdr_mask = SDR_64_HTABORG | SDR_64_HTABSIZE;
58         target_ulong htabsize = value & SDR_64_HTABSIZE;
59 
60         if (value & ~sdr_mask) {
61             qemu_log_mask(LOG_GUEST_ERROR, "Invalid bits 0x"TARGET_FMT_lx
62                      " set in SDR1", value & ~sdr_mask);
63             value &= sdr_mask;
64         }
65         if (htabsize > 28) {
66             qemu_log_mask(LOG_GUEST_ERROR, "Invalid HTABSIZE 0x" TARGET_FMT_lx
67                      " stored in SDR1", htabsize);
68             return;
69         }
70     }
71 #endif /* defined(TARGET_PPC64) */
72     /* FIXME: Should check for valid HTABMASK values in 32-bit case */
73     env->spr[SPR_SDR1] = value;
74 }
75 
76 /*****************************************************************************/
77 /* PowerPC MMU emulation */
78 
79 int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
80                                     int way, int is_code)
81 {
82     int nr;
83 
84     /* Select TLB num in a way from address */
85     nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1);
86     /* Select TLB way */
87     nr += env->tlb_per_way * way;
88     /* 6xx has separate TLBs for instructions and data */
89     if (is_code) {
90         nr += env->nb_tlb;
91     }
92 
93     return nr;
94 }
95 
96 static int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0,
97                                 target_ulong pte1, int pteh,
98                                 MMUAccessType access_type)
99 {
100     /* Check validity and table match */
101     if (!pte_is_valid(pte0) || ((pte0 >> 6) & 1) != pteh ||
102         (pte0 & PTE_PTEM_MASK) != ctx->ptem) {
103         return -1;
104     }
105     /* all matches should have equal RPN, WIMG & PP */
106     if (ctx->raddr != (hwaddr)-1ULL &&
107         (ctx->raddr & PTE_CHECK_MASK) != (pte1 & PTE_CHECK_MASK)) {
108         qemu_log_mask(CPU_LOG_MMU, "Bad RPN/WIMG/PP\n");
109         return -3;
110     }
111     /* Keep the matching PTE information */
112     ctx->raddr = pte1;
113     ctx->prot = ppc_hash32_prot(ctx->key, pte1 & HPTE32_R_PP, ctx->nx);
114     if (check_prot_access_type(ctx->prot, access_type)) {
115         qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n");
116         return 0;
117     } else {
118         qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
119         return -2;
120     }
121 }
122 
123 static int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
124                             int ret, MMUAccessType access_type)
125 {
126     int store = 0;
127 
128     /* Update page flags */
129     if (!(*pte1p & 0x00000100)) {
130         /* Update accessed flag */
131         *pte1p |= 0x00000100;
132         store = 1;
133     }
134     if (!(*pte1p & 0x00000080)) {
135         if (access_type == MMU_DATA_STORE && ret == 0) {
136             /* Update changed flag */
137             *pte1p |= 0x00000080;
138             store = 1;
139         } else {
140             /* Force page fault for first write access */
141             ctx->prot &= ~PAGE_WRITE;
142         }
143     }
144 
145     return store;
146 }
147 
148 /* Software driven TLB helpers */
149 
150 static int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx,
151                             target_ulong eaddr, MMUAccessType access_type)
152 {
153     ppc6xx_tlb_t *tlb;
154     int nr, best, way;
155     int ret;
156 
157     best = -1;
158     ret = -1; /* No TLB found */
159     for (way = 0; way < env->nb_ways; way++) {
160         nr = ppc6xx_tlb_getnum(env, eaddr, way, access_type == MMU_INST_FETCH);
161         tlb = &env->tlb.tlb6[nr];
162         /* This test "emulates" the PTE index match for hardware TLBs */
163         if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) {
164             qemu_log_mask(CPU_LOG_MMU, "TLB %d/%d %s [" TARGET_FMT_lx
165                           " " TARGET_FMT_lx "] <> " TARGET_FMT_lx "\n",
166                           nr, env->nb_tlb,
167                           pte_is_valid(tlb->pte0) ? "valid" : "inval",
168                           tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr);
169             continue;
170         }
171         qemu_log_mask(CPU_LOG_MMU, "TLB %d/%d %s " TARGET_FMT_lx " <> "
172                       TARGET_FMT_lx " " TARGET_FMT_lx " %c %c\n",
173                       nr, env->nb_tlb,
174                       pte_is_valid(tlb->pte0) ? "valid" : "inval",
175                       tlb->EPN, eaddr, tlb->pte1,
176                       access_type == MMU_DATA_STORE ? 'S' : 'L',
177                       access_type == MMU_INST_FETCH ? 'I' : 'D');
178         switch (ppc6xx_tlb_pte_check(ctx, tlb->pte0, tlb->pte1,
179                                      0, access_type)) {
180         case -2:
181             /* Access violation */
182             ret = -2;
183             best = nr;
184             break;
185         case -1: /* No match */
186         case -3: /* TLB inconsistency */
187         default:
188             break;
189         case 0:
190             /* access granted */
191             /*
192              * XXX: we should go on looping to check all TLBs
193              *      consistency but we can speed-up the whole thing as
194              *      the result would be undefined if TLBs are not
195              *      consistent.
196              */
197             ret = 0;
198             best = nr;
199             goto done;
200         }
201     }
202     if (best != -1) {
203 done:
204         qemu_log_mask(CPU_LOG_MMU, "found TLB at addr " HWADDR_FMT_plx
205                       " prot=%01x ret=%d\n",
206                       ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
207         /* Update page flags */
208         pte_update_flags(ctx, &env->tlb.tlb6[best].pte1, ret, access_type);
209     }
210 #if defined(DUMP_PAGE_TABLES)
211     if (qemu_loglevel_mask(CPU_LOG_MMU)) {
212         CPUState *cs = env_cpu(env);
213         hwaddr base = ppc_hash32_hpt_base(env_archcpu(env));
214         hwaddr len = ppc_hash32_hpt_mask(env_archcpu(env)) + 0x80;
215         uint32_t a0, a1, a2, a3;
216 
217         qemu_log("Page table: " HWADDR_FMT_plx " len " HWADDR_FMT_plx "\n",
218                  base, len);
219         for (hwaddr curaddr = base; curaddr < base + len; curaddr += 16) {
220             a0 = ldl_phys(cs->as, curaddr);
221             a1 = ldl_phys(cs->as, curaddr + 4);
222             a2 = ldl_phys(cs->as, curaddr + 8);
223             a3 = ldl_phys(cs->as, curaddr + 12);
224             if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
225                 qemu_log(HWADDR_FMT_plx ": %08x %08x %08x %08x\n",
226                          curaddr, a0, a1, a2, a3);
227             }
228         }
229     }
230 #endif
231     return ret;
232 }
233 
234 /* Perform BAT hit & translation */
235 static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp,
236                                  int *validp, int *protp, target_ulong *BATu,
237                                  target_ulong *BATl)
238 {
239     target_ulong bl;
240     int pp, valid, prot;
241 
242     bl = (*BATu & 0x00001FFC) << 15;
243     valid = 0;
244     prot = 0;
245     if ((!FIELD_EX64(env->msr, MSR, PR) && (*BATu & 0x00000002)) ||
246         (FIELD_EX64(env->msr, MSR, PR) && (*BATu & 0x00000001))) {
247         valid = 1;
248         pp = *BATl & 0x00000003;
249         if (pp != 0) {
250             prot = PAGE_READ | PAGE_EXEC;
251             if (pp == 0x2) {
252                 prot |= PAGE_WRITE;
253             }
254         }
255     }
256     *blp = bl;
257     *validp = valid;
258     *protp = prot;
259 }
260 
261 static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
262                            target_ulong virtual, MMUAccessType access_type)
263 {
264     target_ulong *BATlt, *BATut, *BATu, *BATl;
265     target_ulong BEPIl, BEPIu, bl;
266     int i, valid, prot;
267     int ret = -1;
268     bool ifetch = access_type == MMU_INST_FETCH;
269 
270     qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
271                   ifetch ? 'I' : 'D', virtual);
272     if (ifetch) {
273         BATlt = env->IBAT[1];
274         BATut = env->IBAT[0];
275     } else {
276         BATlt = env->DBAT[1];
277         BATut = env->DBAT[0];
278     }
279     for (i = 0; i < env->nb_BATs; i++) {
280         BATu = &BATut[i];
281         BATl = &BATlt[i];
282         BEPIu = *BATu & 0xF0000000;
283         BEPIl = *BATu & 0x0FFE0000;
284         bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
285         qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT%d v " TARGET_FMT_lx " BATu "
286                       TARGET_FMT_lx " BATl " TARGET_FMT_lx "\n", __func__,
287                       ifetch ? 'I' : 'D', i, virtual, *BATu, *BATl);
288         if ((virtual & 0xF0000000) == BEPIu &&
289             ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
290             /* BAT matches */
291             if (valid != 0) {
292                 /* Get physical address */
293                 ctx->raddr = (*BATl & 0xF0000000) |
294                     ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
295                     (virtual & 0x0001F000);
296                 /* Compute access rights */
297                 ctx->prot = prot;
298                 if (check_prot_access_type(ctx->prot, access_type)) {
299                     qemu_log_mask(CPU_LOG_MMU, "BAT %d match: r " HWADDR_FMT_plx
300                                   " prot=%c%c\n", i, ctx->raddr,
301                                   ctx->prot & PAGE_READ ? 'R' : '-',
302                                   ctx->prot & PAGE_WRITE ? 'W' : '-');
303                     ret = 0;
304                 } else {
305                     ret = -2;
306                 }
307                 break;
308             }
309         }
310     }
311     if (ret < 0) {
312         if (qemu_log_enabled()) {
313             qemu_log_mask(CPU_LOG_MMU, "no BAT match for "
314                           TARGET_FMT_lx ":\n", virtual);
315             for (i = 0; i < 4; i++) {
316                 BATu = &BATut[i];
317                 BATl = &BATlt[i];
318                 BEPIu = *BATu & 0xF0000000;
319                 BEPIl = *BATu & 0x0FFE0000;
320                 bl = (*BATu & 0x00001FFC) << 15;
321                 qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT%d v " TARGET_FMT_lx
322                               " BATu " TARGET_FMT_lx " BATl " TARGET_FMT_lx
323                               "\n\t" TARGET_FMT_lx " " TARGET_FMT_lx " "
324                               TARGET_FMT_lx "\n", __func__, ifetch ? 'I' : 'D',
325                               i, virtual, *BATu, *BATl, BEPIu, BEPIl, bl);
326             }
327         }
328     }
329     /* No hit */
330     return ret;
331 }
332 
333 static int mmu6xx_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
334                                        target_ulong eaddr,
335                                        MMUAccessType access_type, int type)
336 {
337     PowerPCCPU *cpu = env_archcpu(env);
338     hwaddr hash;
339     target_ulong vsid, sr, pgidx;
340     int ds, target_page_bits;
341     bool pr;
342 
343     /* First try to find a BAT entry if there are any */
344     if (env->nb_BATs && get_bat_6xx_tlb(env, ctx, eaddr, access_type) == 0) {
345         return 0;
346     }
347 
348     /* Perform segment based translation when no BATs matched */
349     pr = FIELD_EX64(env->msr, MSR, PR);
350 
351     sr = env->sr[eaddr >> 28];
352     ctx->key = (((sr & 0x20000000) && pr) ||
353                 ((sr & 0x40000000) && !pr)) ? 1 : 0;
354     ds = sr & 0x80000000 ? 1 : 0;
355     ctx->nx = sr & 0x10000000 ? 1 : 0;
356     vsid = sr & 0x00FFFFFF;
357     target_page_bits = TARGET_PAGE_BITS;
358     qemu_log_mask(CPU_LOG_MMU,
359                   "Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx
360                   " nip=" TARGET_FMT_lx " lr=" TARGET_FMT_lx
361                   " ir=%d dr=%d pr=%d %d t=%d\n",
362                   eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr,
363                   (int)FIELD_EX64(env->msr, MSR, IR),
364                   (int)FIELD_EX64(env->msr, MSR, DR), pr ? 1 : 0,
365                   access_type == MMU_DATA_STORE, type);
366     pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits;
367     hash = vsid ^ pgidx;
368     ctx->ptem = (vsid << 7) | (pgidx >> 10);
369 
370     qemu_log_mask(CPU_LOG_MMU, "pte segment: key=%d ds %d nx %d vsid "
371                   TARGET_FMT_lx "\n", ctx->key, ds, ctx->nx, vsid);
372     if (!ds) {
373         /* Check if instruction fetch is allowed, if needed */
374         if (type == ACCESS_CODE && ctx->nx) {
375             qemu_log_mask(CPU_LOG_MMU, "No access allowed\n");
376             return -3;
377         }
378         /* Page address translation */
379         qemu_log_mask(CPU_LOG_MMU, "htab_base " HWADDR_FMT_plx " htab_mask "
380                       HWADDR_FMT_plx " hash " HWADDR_FMT_plx "\n",
381                       ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash);
382         ctx->hash[0] = hash;
383         ctx->hash[1] = ~hash;
384 
385         /* Initialize real address with an invalid value */
386         ctx->raddr = (hwaddr)-1ULL;
387         /* Software TLB search */
388         return ppc6xx_tlb_check(env, ctx, eaddr, access_type);
389     }
390 
391     /* Direct-store segment : absolutely *BUGGY* for now */
392     qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
393     switch (type) {
394     case ACCESS_INT:
395         /* Integer load/store : only access allowed */
396         break;
397     case ACCESS_CODE:
398         /* No code fetch is allowed in direct-store areas */
399         return -4;
400     case ACCESS_FLOAT:
401         /* Floating point load/store */
402         return -4;
403     case ACCESS_RES:
404         /* lwarx, ldarx or srwcx. */
405         return -4;
406     case ACCESS_CACHE:
407         /*
408          * dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi
409          *
410          * Should make the instruction do no-op.  As it already do
411          * no-op, it's quite easy :-)
412          */
413         ctx->raddr = eaddr;
414         return 0;
415     case ACCESS_EXT:
416         /* eciwx or ecowx */
417         return -4;
418     default:
419         qemu_log_mask(CPU_LOG_MMU, "ERROR: instruction should not need address"
420                                    " translation\n");
421         return -4;
422     }
423     if ((access_type == MMU_DATA_STORE || ctx->key != 1) &&
424         (access_type == MMU_DATA_LOAD || ctx->key != 0)) {
425         ctx->raddr = eaddr;
426         return 2;
427     }
428     return -2;
429 }
430 
431 static const char *book3e_tsize_to_str[32] = {
432     "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
433     "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M",
434     "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G",
435     "1T", "2T"
436 };
437 
438 static void mmubooke_dump_mmu(CPUPPCState *env)
439 {
440     ppcemb_tlb_t *entry;
441     int i;
442 
443 #ifdef CONFIG_KVM
444     if (kvm_enabled() && !env->kvm_sw_tlb) {
445         qemu_printf("Cannot access KVM TLB\n");
446         return;
447     }
448 #endif
449 
450     qemu_printf("\nTLB:\n");
451     qemu_printf("Effective          Physical           Size PID   Prot     "
452                 "Attr\n");
453 
454     entry = &env->tlb.tlbe[0];
455     for (i = 0; i < env->nb_tlb; i++, entry++) {
456         hwaddr ea, pa;
457         target_ulong mask;
458         uint64_t size = (uint64_t)entry->size;
459         char size_buf[20];
460 
461         /* Check valid flag */
462         if (!(entry->prot & PAGE_VALID)) {
463             continue;
464         }
465 
466         mask = ~(entry->size - 1);
467         ea = entry->EPN & mask;
468         pa = entry->RPN & mask;
469         /* Extend the physical address to 36 bits */
470         pa |= (hwaddr)(entry->RPN & 0xF) << 32;
471         if (size >= 1 * MiB) {
472             snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "M", size / MiB);
473         } else {
474             snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "k", size / KiB);
475         }
476         qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %s %-5u %08x %08x\n",
477                     (uint64_t)ea, (uint64_t)pa, size_buf, (uint32_t)entry->PID,
478                     entry->prot, entry->attr);
479     }
480 
481 }
482 
483 static void mmubooke206_dump_one_tlb(CPUPPCState *env, int tlbn, int offset,
484                                      int tlbsize)
485 {
486     ppcmas_tlb_t *entry;
487     int i;
488 
489     qemu_printf("\nTLB%d:\n", tlbn);
490     qemu_printf("Effective          Physical           Size TID   TS SRWX"
491                 " URWX WIMGE U0123\n");
492 
493     entry = &env->tlb.tlbm[offset];
494     for (i = 0; i < tlbsize; i++, entry++) {
495         hwaddr ea, pa, size;
496         int tsize;
497 
498         if (!(entry->mas1 & MAS1_VALID)) {
499             continue;
500         }
501 
502         tsize = (entry->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
503         size = 1024ULL << tsize;
504         ea = entry->mas2 & ~(size - 1);
505         pa = entry->mas7_3 & ~(size - 1);
506 
507         qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u  S%c%c%c"
508                     " U%c%c%c %c%c%c%c%c U%c%c%c%c\n",
509                     (uint64_t)ea, (uint64_t)pa,
510                     book3e_tsize_to_str[tsize],
511                     (entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT,
512                     (entry->mas1 & MAS1_TS) >> MAS1_TS_SHIFT,
513                     entry->mas7_3 & MAS3_SR ? 'R' : '-',
514                     entry->mas7_3 & MAS3_SW ? 'W' : '-',
515                     entry->mas7_3 & MAS3_SX ? 'X' : '-',
516                     entry->mas7_3 & MAS3_UR ? 'R' : '-',
517                     entry->mas7_3 & MAS3_UW ? 'W' : '-',
518                     entry->mas7_3 & MAS3_UX ? 'X' : '-',
519                     entry->mas2 & MAS2_W ? 'W' : '-',
520                     entry->mas2 & MAS2_I ? 'I' : '-',
521                     entry->mas2 & MAS2_M ? 'M' : '-',
522                     entry->mas2 & MAS2_G ? 'G' : '-',
523                     entry->mas2 & MAS2_E ? 'E' : '-',
524                     entry->mas7_3 & MAS3_U0 ? '0' : '-',
525                     entry->mas7_3 & MAS3_U1 ? '1' : '-',
526                     entry->mas7_3 & MAS3_U2 ? '2' : '-',
527                     entry->mas7_3 & MAS3_U3 ? '3' : '-');
528     }
529 }
530 
531 static void mmubooke206_dump_mmu(CPUPPCState *env)
532 {
533     int offset = 0;
534     int i;
535 
536 #ifdef CONFIG_KVM
537     if (kvm_enabled() && !env->kvm_sw_tlb) {
538         qemu_printf("Cannot access KVM TLB\n");
539         return;
540     }
541 #endif
542 
543     for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
544         int size = booke206_tlb_size(env, i);
545 
546         if (size == 0) {
547             continue;
548         }
549 
550         mmubooke206_dump_one_tlb(env, i, offset, size);
551         offset += size;
552     }
553 }
554 
555 static void mmu6xx_dump_BATs(CPUPPCState *env, int type)
556 {
557     target_ulong *BATlt, *BATut, *BATu, *BATl;
558     target_ulong BEPIl, BEPIu, bl;
559     int i;
560 
561     switch (type) {
562     case ACCESS_CODE:
563         BATlt = env->IBAT[1];
564         BATut = env->IBAT[0];
565         break;
566     default:
567         BATlt = env->DBAT[1];
568         BATut = env->DBAT[0];
569         break;
570     }
571 
572     for (i = 0; i < env->nb_BATs; i++) {
573         BATu = &BATut[i];
574         BATl = &BATlt[i];
575         BEPIu = *BATu & 0xF0000000;
576         BEPIl = *BATu & 0x0FFE0000;
577         bl = (*BATu & 0x00001FFC) << 15;
578         qemu_printf("%s BAT%d BATu " TARGET_FMT_lx
579                     " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
580                     TARGET_FMT_lx " " TARGET_FMT_lx "\n",
581                     type == ACCESS_CODE ? "code" : "data", i,
582                     *BATu, *BATl, BEPIu, BEPIl, bl);
583     }
584 }
585 
586 static void mmu6xx_dump_mmu(CPUPPCState *env)
587 {
588     PowerPCCPU *cpu = env_archcpu(env);
589     ppc6xx_tlb_t *tlb;
590     target_ulong sr;
591     int type, way, entry, i;
592 
593     qemu_printf("HTAB base = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_base(cpu));
594     qemu_printf("HTAB mask = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_mask(cpu));
595 
596     qemu_printf("\nSegment registers:\n");
597     for (i = 0; i < 32; i++) {
598         sr = env->sr[i];
599         if (sr & 0x80000000) {
600             qemu_printf("%02d T=%d Ks=%d Kp=%d BUID=0x%03x "
601                         "CNTLR_SPEC=0x%05x\n", i,
602                         sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
603                         sr & 0x20000000 ? 1 : 0, (uint32_t)((sr >> 20) & 0x1FF),
604                         (uint32_t)(sr & 0xFFFFF));
605         } else {
606             qemu_printf("%02d T=%d Ks=%d Kp=%d N=%d VSID=0x%06x\n", i,
607                         sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
608                         sr & 0x20000000 ? 1 : 0, sr & 0x10000000 ? 1 : 0,
609                         (uint32_t)(sr & 0x00FFFFFF));
610         }
611     }
612 
613     qemu_printf("\nBATs:\n");
614     mmu6xx_dump_BATs(env, ACCESS_INT);
615     mmu6xx_dump_BATs(env, ACCESS_CODE);
616 
617     qemu_printf("\nTLBs                       [EPN    EPN + SIZE]\n");
618     for (type = 0; type < 2; type++) {
619         for (way = 0; way < env->nb_ways; way++) {
620             for (entry = env->nb_tlb * type + env->tlb_per_way * way;
621                  entry < (env->nb_tlb * type + env->tlb_per_way * (way + 1));
622                  entry++) {
623 
624                 tlb = &env->tlb.tlb6[entry];
625                 qemu_printf("%s TLB %02d/%02d way:%d %s ["
626                             TARGET_FMT_lx " " TARGET_FMT_lx "]\n",
627                             type ? "code" : "data", entry % env->nb_tlb,
628                             env->nb_tlb, way,
629                             pte_is_valid(tlb->pte0) ? "valid" : "inval",
630                             tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE);
631             }
632         }
633     }
634 }
635 
636 void dump_mmu(CPUPPCState *env)
637 {
638     switch (env->mmu_model) {
639     case POWERPC_MMU_BOOKE:
640         mmubooke_dump_mmu(env);
641         break;
642     case POWERPC_MMU_BOOKE206:
643         mmubooke206_dump_mmu(env);
644         break;
645     case POWERPC_MMU_SOFT_6xx:
646         mmu6xx_dump_mmu(env);
647         break;
648 #if defined(TARGET_PPC64)
649     case POWERPC_MMU_64B:
650     case POWERPC_MMU_2_03:
651     case POWERPC_MMU_2_06:
652     case POWERPC_MMU_2_07:
653         dump_slb(env_archcpu(env));
654         break;
655     case POWERPC_MMU_3_00:
656         if (ppc64_v3_radix(env_archcpu(env))) {
657             qemu_log_mask(LOG_UNIMP, "%s: the PPC64 MMU is unsupported\n",
658                           __func__);
659         } else {
660             dump_slb(env_archcpu(env));
661         }
662         break;
663 #endif
664     default:
665         qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__);
666     }
667 }
668 
669 
670 static bool ppc_real_mode_xlate(PowerPCCPU *cpu, vaddr eaddr,
671                                 MMUAccessType access_type,
672                                 hwaddr *raddrp, int *psizep, int *protp)
673 {
674     CPUPPCState *env = &cpu->env;
675 
676     if (access_type == MMU_INST_FETCH ? !FIELD_EX64(env->msr, MSR, IR)
677                                       : !FIELD_EX64(env->msr, MSR, DR)) {
678         *raddrp = eaddr;
679         *protp = PAGE_RWX;
680         *psizep = TARGET_PAGE_BITS;
681         return true;
682     } else if (env->mmu_model == POWERPC_MMU_REAL) {
683         cpu_abort(CPU(cpu), "PowerPC in real mode shold not do translation\n");
684     }
685     return false;
686 }
687 
688 static bool ppc_40x_xlate(PowerPCCPU *cpu, vaddr eaddr,
689                           MMUAccessType access_type,
690                           hwaddr *raddrp, int *psizep, int *protp,
691                           int mmu_idx, bool guest_visible)
692 {
693     CPUState *cs = CPU(cpu);
694     CPUPPCState *env = &cpu->env;
695     int ret;
696 
697     if (ppc_real_mode_xlate(cpu, eaddr, access_type, raddrp, psizep, protp)) {
698         return true;
699     }
700 
701     ret = mmu40x_get_physical_address(env, raddrp, protp, eaddr, access_type);
702     if (ret == 0) {
703         *psizep = TARGET_PAGE_BITS;
704         return true;
705     } else if (!guest_visible) {
706         return false;
707     }
708 
709     log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
710     if (access_type == MMU_INST_FETCH) {
711         switch (ret) {
712         case -1:
713             /* No matches in page tables or TLB */
714             cs->exception_index = POWERPC_EXCP_ITLB;
715             env->error_code = 0;
716             env->spr[SPR_40x_DEAR] = eaddr;
717             env->spr[SPR_40x_ESR] = 0x00000000;
718             break;
719         case -2:
720             /* Access rights violation */
721             cs->exception_index = POWERPC_EXCP_ISI;
722             env->error_code = 0x08000000;
723             break;
724         default:
725             g_assert_not_reached();
726         }
727     } else {
728         switch (ret) {
729         case -1:
730             /* No matches in page tables or TLB */
731             cs->exception_index = POWERPC_EXCP_DTLB;
732             env->error_code = 0;
733             env->spr[SPR_40x_DEAR] = eaddr;
734             if (access_type == MMU_DATA_STORE) {
735                 env->spr[SPR_40x_ESR] = 0x00800000;
736             } else {
737                 env->spr[SPR_40x_ESR] = 0x00000000;
738             }
739             break;
740         case -2:
741             /* Access rights violation */
742             cs->exception_index = POWERPC_EXCP_DSI;
743             env->error_code = 0;
744             env->spr[SPR_40x_DEAR] = eaddr;
745             if (access_type == MMU_DATA_STORE) {
746                 env->spr[SPR_40x_ESR] |= 0x00800000;
747             }
748             break;
749         default:
750             g_assert_not_reached();
751         }
752     }
753     return false;
754 }
755 
756 static bool ppc_6xx_xlate(PowerPCCPU *cpu, vaddr eaddr,
757                           MMUAccessType access_type,
758                           hwaddr *raddrp, int *psizep, int *protp,
759                           int mmu_idx, bool guest_visible)
760 {
761     CPUState *cs = CPU(cpu);
762     CPUPPCState *env = &cpu->env;
763     mmu_ctx_t ctx;
764     int type;
765     int ret;
766 
767     if (ppc_real_mode_xlate(cpu, eaddr, access_type, raddrp, psizep, protp)) {
768         return true;
769     }
770 
771     if (access_type == MMU_INST_FETCH) {
772         /* code access */
773         type = ACCESS_CODE;
774     } else if (guest_visible) {
775         /* data access */
776         type = env->access_type;
777     } else {
778         type = ACCESS_INT;
779     }
780 
781     ctx.prot = 0;
782     ctx.hash[0] = 0;
783     ctx.hash[1] = 0;
784     ret = mmu6xx_get_physical_address(env, &ctx, eaddr, access_type, type);
785     if (ret == 0) {
786         *raddrp = ctx.raddr;
787         *protp = ctx.prot;
788         *psizep = TARGET_PAGE_BITS;
789         return true;
790     } else if (!guest_visible) {
791         return false;
792     }
793 
794     log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
795     if (type == ACCESS_CODE) {
796         switch (ret) {
797         case -1:
798             /* No matches in page tables or TLB */
799             cs->exception_index = POWERPC_EXCP_IFTLB;
800             env->error_code = 1 << 18;
801             env->spr[SPR_IMISS] = eaddr;
802             env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
803             goto tlb_miss;
804         case -2:
805             /* Access rights violation */
806             cs->exception_index = POWERPC_EXCP_ISI;
807             env->error_code = 0x08000000;
808             break;
809         case -3:
810             /* No execute protection violation */
811             cs->exception_index = POWERPC_EXCP_ISI;
812             env->error_code = 0x10000000;
813             break;
814         case -4:
815             /* Direct store exception */
816             /* No code fetch is allowed in direct-store areas */
817             cs->exception_index = POWERPC_EXCP_ISI;
818             env->error_code = 0x10000000;
819             break;
820         }
821     } else {
822         switch (ret) {
823         case -1:
824             /* No matches in page tables or TLB */
825             if (access_type == MMU_DATA_STORE) {
826                 cs->exception_index = POWERPC_EXCP_DSTLB;
827                 env->error_code = 1 << 16;
828             } else {
829                 cs->exception_index = POWERPC_EXCP_DLTLB;
830                 env->error_code = 0;
831             }
832             env->spr[SPR_DMISS] = eaddr;
833             env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
834 tlb_miss:
835             env->error_code |= ctx.key << 19;
836             env->spr[SPR_HASH1] = ppc_hash32_hpt_base(cpu) +
837                                   get_pteg_offset32(cpu, ctx.hash[0]);
838             env->spr[SPR_HASH2] = ppc_hash32_hpt_base(cpu) +
839                                   get_pteg_offset32(cpu, ctx.hash[1]);
840             break;
841         case -2:
842             /* Access rights violation */
843             cs->exception_index = POWERPC_EXCP_DSI;
844             env->error_code = 0;
845             env->spr[SPR_DAR] = eaddr;
846             if (access_type == MMU_DATA_STORE) {
847                 env->spr[SPR_DSISR] = 0x0A000000;
848             } else {
849                 env->spr[SPR_DSISR] = 0x08000000;
850             }
851             break;
852         case -4:
853             /* Direct store exception */
854             switch (type) {
855             case ACCESS_FLOAT:
856                 /* Floating point load/store */
857                 cs->exception_index = POWERPC_EXCP_ALIGN;
858                 env->error_code = POWERPC_EXCP_ALIGN_FP;
859                 env->spr[SPR_DAR] = eaddr;
860                 break;
861             case ACCESS_RES:
862                 /* lwarx, ldarx or stwcx. */
863                 cs->exception_index = POWERPC_EXCP_DSI;
864                 env->error_code = 0;
865                 env->spr[SPR_DAR] = eaddr;
866                 if (access_type == MMU_DATA_STORE) {
867                     env->spr[SPR_DSISR] = 0x06000000;
868                 } else {
869                     env->spr[SPR_DSISR] = 0x04000000;
870                 }
871                 break;
872             case ACCESS_EXT:
873                 /* eciwx or ecowx */
874                 cs->exception_index = POWERPC_EXCP_DSI;
875                 env->error_code = 0;
876                 env->spr[SPR_DAR] = eaddr;
877                 if (access_type == MMU_DATA_STORE) {
878                     env->spr[SPR_DSISR] = 0x06100000;
879                 } else {
880                     env->spr[SPR_DSISR] = 0x04100000;
881                 }
882                 break;
883             default:
884                 printf("DSI: invalid exception (%d)\n", ret);
885                 cs->exception_index = POWERPC_EXCP_PROGRAM;
886                 env->error_code = POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
887                 env->spr[SPR_DAR] = eaddr;
888                 break;
889             }
890             break;
891         }
892     }
893     return false;
894 }
895 
896 /*****************************************************************************/
897 
898 bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
899                       hwaddr *raddrp, int *psizep, int *protp,
900                       int mmu_idx, bool guest_visible)
901 {
902     switch (cpu->env.mmu_model) {
903 #if defined(TARGET_PPC64)
904     case POWERPC_MMU_3_00:
905         if (ppc64_v3_radix(cpu)) {
906             return ppc_radix64_xlate(cpu, eaddr, access_type, raddrp,
907                                      psizep, protp, mmu_idx, guest_visible);
908         }
909         /* fall through */
910     case POWERPC_MMU_64B:
911     case POWERPC_MMU_2_03:
912     case POWERPC_MMU_2_06:
913     case POWERPC_MMU_2_07:
914         return ppc_hash64_xlate(cpu, eaddr, access_type,
915                                 raddrp, psizep, protp, mmu_idx, guest_visible);
916 #endif
917 
918     case POWERPC_MMU_32B:
919         return ppc_hash32_xlate(cpu, eaddr, access_type, raddrp,
920                                psizep, protp, mmu_idx, guest_visible);
921     case POWERPC_MMU_BOOKE:
922     case POWERPC_MMU_BOOKE206:
923         return ppc_booke_xlate(cpu, eaddr, access_type, raddrp,
924                                psizep, protp, mmu_idx, guest_visible);
925     case POWERPC_MMU_SOFT_4xx:
926         return ppc_40x_xlate(cpu, eaddr, access_type, raddrp,
927                              psizep, protp, mmu_idx, guest_visible);
928     case POWERPC_MMU_SOFT_6xx:
929         return ppc_6xx_xlate(cpu, eaddr, access_type, raddrp,
930                              psizep, protp, mmu_idx, guest_visible);
931     case POWERPC_MMU_REAL:
932         return ppc_real_mode_xlate(cpu, eaddr, access_type, raddrp, psizep,
933                                    protp);
934     case POWERPC_MMU_MPC8xx:
935         cpu_abort(env_cpu(&cpu->env), "MPC8xx MMU model is not implemented\n");
936     default:
937         cpu_abort(CPU(cpu), "Unknown or invalid MMU model\n");
938     }
939 }
940 
941 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
942 {
943     PowerPCCPU *cpu = POWERPC_CPU(cs);
944     hwaddr raddr;
945     int s, p;
946 
947     /*
948      * Some MMUs have separate TLBs for code and data. If we only
949      * try an MMU_DATA_LOAD, we may not be able to read instructions
950      * mapped by code TLBs, so we also try a MMU_INST_FETCH.
951      */
952     if (ppc_xlate(cpu, addr, MMU_DATA_LOAD, &raddr, &s, &p,
953                   ppc_env_mmu_index(&cpu->env, false), false) ||
954         ppc_xlate(cpu, addr, MMU_INST_FETCH, &raddr, &s, &p,
955                   ppc_env_mmu_index(&cpu->env, true), false)) {
956         return raddr & TARGET_PAGE_MASK;
957     }
958     return -1;
959 }
960