target/ppc: initialize 'val' union in kvm_get_one_spr()
[qemu.git] / target / ppc / mmu_common.c
blobe9c5b14c0f4893a6c5f7005a31825eb031de956e
1 /*
2 * PowerPC MMU, TLB, SLB and BAT emulation helpers for QEMU.
4 * Copyright (c) 2003-2007 Jocelyn Mayer
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.
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.
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/>.
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"
37 /* #define DUMP_PAGE_TABLES */
39 void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
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;
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;
54 if (htabsize > 28) {
55 qemu_log_mask(LOG_GUEST_ERROR, "Invalid HTABSIZE 0x" TARGET_FMT_lx
56 " stored in SDR1", htabsize);
57 return;
60 #endif /* defined(TARGET_PPC64) */
61 /* FIXME: Should check for valid HTABMASK values in 32-bit case */
62 env->spr[SPR_SDR1] = value;
65 /*****************************************************************************/
66 /* PowerPC MMU emulation */
68 static int pp_check(int key, int pp, int nx)
70 int access;
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;
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;
99 if (nx == 0) {
100 access |= PAGE_EXEC;
103 return access;
106 static int check_prot(int prot, MMUAccessType access_type)
108 return prot & prot_for_access_type(access_type) ? 0 : -2;
111 int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
112 int way, int is_code)
114 int nr;
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;
125 return nr;
128 static int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0,
129 target_ulong pte1, int h,
130 MMUAccessType access_type)
132 target_ulong ptem, mmask;
133 int access, ret, pteh, ptev, pp;
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;
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");
168 return ret;
171 static int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
172 int ret, MMUAccessType access_type)
174 int store = 0;
176 /* Update page flags */
177 if (!(*pte1p & 0x00000100)) {
178 /* Update accessed flag */
179 *pte1p |= 0x00000100;
180 store = 1;
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;
193 return store;
196 /* Software driven TLB helpers */
198 static int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx,
199 target_ulong eaddr, MMUAccessType access_type)
201 ppc6xx_tlb_t *tlb;
202 int nr, best, way;
203 int ret;
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;
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 */
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.
248 ret = 0;
249 best = nr;
250 goto done;
253 if (best != -1) {
254 done:
255 qemu_log_mask(CPU_LOG_MMU, "found TLB at addr " TARGET_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);
262 return ret;
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)
270 target_ulong bl;
271 int pp, valid, prot;
273 bl = (*BATu & 0x00001FFC) << 15;
274 valid = 0;
275 prot = 0;
276 if (((msr_pr == 0) && (*BATu & 0x00000002)) ||
277 ((msr_pr != 0) && (*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;
287 *blp = bl;
288 *validp = valid;
289 *protp = prot;
292 static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
293 target_ulong virtual, MMUAccessType access_type)
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;
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];
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 " TARGET_FMT_plx
332 " prot=%c%c\n", i, ctx->raddr,
333 ctx->prot & PAGE_READ ? 'R' : '-',
334 ctx->prot & PAGE_WRITE ? 'W' : '-');
336 break;
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);
359 /* No hit */
360 return ret;
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)
368 PowerPCCPU *cpu = env_archcpu(env);
369 hwaddr hash;
370 target_ulong vsid;
371 int ds, pr, target_page_bits;
372 int ret;
373 target_ulong sr, pgidx;
375 pr = msr_pr;
376 ctx->eaddr = eaddr;
378 sr = env->sr[eaddr >> 28];
379 ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
380 ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
381 ds = sr & 0x80000000 ? 1 : 0;
382 ctx->nx = sr & 0x10000000 ? 1 : 0;
383 vsid = sr & 0x00FFFFFF;
384 target_page_bits = TARGET_PAGE_BITS;
385 qemu_log_mask(CPU_LOG_MMU,
386 "Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx
387 " nip=" TARGET_FMT_lx " lr=" TARGET_FMT_lx
388 " ir=%d dr=%d pr=%d %d t=%d\n",
389 eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir,
390 (int)msr_dr, pr != 0 ? 1 : 0,
391 access_type == MMU_DATA_STORE, type);
392 pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits;
393 hash = vsid ^ pgidx;
394 ctx->ptem = (vsid << 7) | (pgidx >> 10);
396 qemu_log_mask(CPU_LOG_MMU,
397 "pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n",
398 ctx->key, ds, ctx->nx, vsid);
399 ret = -1;
400 if (!ds) {
401 /* Check if instruction fetch is allowed, if needed */
402 if (type != ACCESS_CODE || ctx->nx == 0) {
403 /* Page address translation */
404 qemu_log_mask(CPU_LOG_MMU, "htab_base " TARGET_FMT_plx
405 " htab_mask " TARGET_FMT_plx
406 " hash " TARGET_FMT_plx "\n",
407 ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash);
408 ctx->hash[0] = hash;
409 ctx->hash[1] = ~hash;
411 /* Initialize real address with an invalid value */
412 ctx->raddr = (hwaddr)-1ULL;
413 /* Software TLB search */
414 ret = ppc6xx_tlb_check(env, ctx, eaddr, access_type);
415 #if defined(DUMP_PAGE_TABLES)
416 if (qemu_loglevel_mask(CPU_LOG_MMU)) {
417 CPUState *cs = env_cpu(env);
418 hwaddr curaddr;
419 uint32_t a0, a1, a2, a3;
421 qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx
422 "\n", ppc_hash32_hpt_base(cpu),
423 ppc_hash32_hpt_mask(cpu) + 0x80);
424 for (curaddr = ppc_hash32_hpt_base(cpu);
425 curaddr < (ppc_hash32_hpt_base(cpu)
426 + ppc_hash32_hpt_mask(cpu) + 0x80);
427 curaddr += 16) {
428 a0 = ldl_phys(cs->as, curaddr);
429 a1 = ldl_phys(cs->as, curaddr + 4);
430 a2 = ldl_phys(cs->as, curaddr + 8);
431 a3 = ldl_phys(cs->as, curaddr + 12);
432 if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
433 qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n",
434 curaddr, a0, a1, a2, a3);
438 #endif
439 } else {
440 qemu_log_mask(CPU_LOG_MMU, "No access allowed\n");
441 ret = -3;
443 } else {
444 qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
445 /* Direct-store segment : absolutely *BUGGY* for now */
447 switch (type) {
448 case ACCESS_INT:
449 /* Integer load/store : only access allowed */
450 break;
451 case ACCESS_CODE:
452 /* No code fetch is allowed in direct-store areas */
453 return -4;
454 case ACCESS_FLOAT:
455 /* Floating point load/store */
456 return -4;
457 case ACCESS_RES:
458 /* lwarx, ldarx or srwcx. */
459 return -4;
460 case ACCESS_CACHE:
462 * dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi
464 * Should make the instruction do no-op. As it already do
465 * no-op, it's quite easy :-)
467 ctx->raddr = eaddr;
468 return 0;
469 case ACCESS_EXT:
470 /* eciwx or ecowx */
471 return -4;
472 default:
473 qemu_log_mask(CPU_LOG_MMU, "ERROR: instruction should not need "
474 "address translation\n");
475 return -4;
477 if ((access_type == MMU_DATA_STORE || ctx->key != 1) &&
478 (access_type == MMU_DATA_LOAD || ctx->key != 0)) {
479 ctx->raddr = eaddr;
480 ret = 2;
481 } else {
482 ret = -2;
486 return ret;
489 /* Generic TLB check function for embedded PowerPC implementations */
490 int ppcemb_tlb_check(CPUPPCState *env, ppcemb_tlb_t *tlb,
491 hwaddr *raddrp,
492 target_ulong address, uint32_t pid, int ext,
493 int i)
495 target_ulong mask;
497 /* Check valid flag */
498 if (!(tlb->prot & PAGE_VALID)) {
499 return -1;
501 mask = ~(tlb->size - 1);
502 qemu_log_mask(CPU_LOG_MMU, "%s: TLB %d address " TARGET_FMT_lx
503 " PID %u <=> " TARGET_FMT_lx " " TARGET_FMT_lx " %u %x\n",
504 __func__, i, address, pid, tlb->EPN,
505 mask, (uint32_t)tlb->PID, tlb->prot);
506 /* Check PID */
507 if (tlb->PID != 0 && tlb->PID != pid) {
508 return -1;
510 /* Check effective address */
511 if ((address & mask) != tlb->EPN) {
512 return -1;
514 *raddrp = (tlb->RPN & mask) | (address & ~mask);
515 if (ext) {
516 /* Extend the physical address to 36 bits */
517 *raddrp |= (uint64_t)(tlb->RPN & 0xF) << 32;
520 return 0;
523 static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
524 target_ulong address,
525 MMUAccessType access_type)
527 ppcemb_tlb_t *tlb;
528 hwaddr raddr;
529 int i, ret, zsel, zpr, pr;
531 ret = -1;
532 raddr = (hwaddr)-1ULL;
533 pr = msr_pr;
534 for (i = 0; i < env->nb_tlb; i++) {
535 tlb = &env->tlb.tlbe[i];
536 if (ppcemb_tlb_check(env, tlb, &raddr, address,
537 env->spr[SPR_40x_PID], 0, i) < 0) {
538 continue;
540 zsel = (tlb->attr >> 4) & 0xF;
541 zpr = (env->spr[SPR_40x_ZPR] >> (30 - (2 * zsel))) & 0x3;
542 qemu_log_mask(CPU_LOG_MMU,
543 "%s: TLB %d zsel %d zpr %d ty %d attr %08x\n",
544 __func__, i, zsel, zpr, access_type, tlb->attr);
545 /* Check execute enable bit */
546 switch (zpr) {
547 case 0x2:
548 if (pr != 0) {
549 goto check_perms;
551 /* fall through */
552 case 0x3:
553 /* All accesses granted */
554 ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
555 ret = 0;
556 break;
557 case 0x0:
558 if (pr != 0) {
559 /* Raise Zone protection fault. */
560 env->spr[SPR_40x_ESR] = 1 << 22;
561 ctx->prot = 0;
562 ret = -2;
563 break;
565 /* fall through */
566 case 0x1:
567 check_perms:
568 /* Check from TLB entry */
569 ctx->prot = tlb->prot;
570 ret = check_prot(ctx->prot, access_type);
571 if (ret == -2) {
572 env->spr[SPR_40x_ESR] = 0;
574 break;
576 if (ret >= 0) {
577 ctx->raddr = raddr;
578 qemu_log_mask(CPU_LOG_MMU, "%s: access granted " TARGET_FMT_lx
579 " => " TARGET_FMT_plx
580 " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
581 ret);
582 return 0;
585 qemu_log_mask(CPU_LOG_MMU, "%s: access refused " TARGET_FMT_lx
586 " => " TARGET_FMT_plx
587 " %d %d\n", __func__, address, raddr, ctx->prot, ret);
589 return ret;
592 static int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb,
593 hwaddr *raddr, int *prot, target_ulong address,
594 MMUAccessType access_type, int i)
596 int prot2;
598 if (ppcemb_tlb_check(env, tlb, raddr, address,
599 env->spr[SPR_BOOKE_PID],
600 !env->nb_pids, i) >= 0) {
601 goto found_tlb;
604 if (env->spr[SPR_BOOKE_PID1] &&
605 ppcemb_tlb_check(env, tlb, raddr, address,
606 env->spr[SPR_BOOKE_PID1], 0, i) >= 0) {
607 goto found_tlb;
610 if (env->spr[SPR_BOOKE_PID2] &&
611 ppcemb_tlb_check(env, tlb, raddr, address,
612 env->spr[SPR_BOOKE_PID2], 0, i) >= 0) {
613 goto found_tlb;
616 qemu_log_mask(CPU_LOG_MMU, "%s: TLB entry not found\n", __func__);
617 return -1;
619 found_tlb:
621 if (msr_pr != 0) {
622 prot2 = tlb->prot & 0xF;
623 } else {
624 prot2 = (tlb->prot >> 4) & 0xF;
627 /* Check the address space */
628 if ((access_type == MMU_INST_FETCH ? msr_ir : msr_dr) != (tlb->attr & 1)) {
629 qemu_log_mask(CPU_LOG_MMU, "%s: AS doesn't match\n", __func__);
630 return -1;
633 *prot = prot2;
634 if (prot2 & prot_for_access_type(access_type)) {
635 qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
636 return 0;
639 qemu_log_mask(CPU_LOG_MMU, "%s: no prot match: %x\n", __func__, prot2);
640 return access_type == MMU_INST_FETCH ? -3 : -2;
643 static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
644 target_ulong address,
645 MMUAccessType access_type)
647 ppcemb_tlb_t *tlb;
648 hwaddr raddr;
649 int i, ret;
651 ret = -1;
652 raddr = (hwaddr)-1ULL;
653 for (i = 0; i < env->nb_tlb; i++) {
654 tlb = &env->tlb.tlbe[i];
655 ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address,
656 access_type, i);
657 if (ret != -1) {
658 break;
662 if (ret >= 0) {
663 ctx->raddr = raddr;
664 qemu_log_mask(CPU_LOG_MMU, "%s: access granted " TARGET_FMT_lx
665 " => " TARGET_FMT_plx " %d %d\n", __func__,
666 address, ctx->raddr, ctx->prot, ret);
667 } else {
668 qemu_log_mask(CPU_LOG_MMU, "%s: access refused " TARGET_FMT_lx
669 " => " TARGET_FMT_plx " %d %d\n", __func__,
670 address, raddr, ctx->prot, ret);
673 return ret;
676 hwaddr booke206_tlb_to_page_size(CPUPPCState *env,
677 ppcmas_tlb_t *tlb)
679 int tlbm_size;
681 tlbm_size = (tlb->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
683 return 1024ULL << tlbm_size;
686 /* TLB check function for MAS based SoftTLBs */
687 int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb,
688 hwaddr *raddrp, target_ulong address,
689 uint32_t pid)
691 hwaddr mask;
692 uint32_t tlb_pid;
694 if (!msr_cm) {
695 /* In 32bit mode we can only address 32bit EAs */
696 address = (uint32_t)address;
699 /* Check valid flag */
700 if (!(tlb->mas1 & MAS1_VALID)) {
701 return -1;
704 mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
705 qemu_log_mask(CPU_LOG_MMU, "%s: TLB ADDR=0x" TARGET_FMT_lx
706 " PID=0x%x MAS1=0x%x MAS2=0x%" PRIx64 " mask=0x%"
707 HWADDR_PRIx " MAS7_3=0x%" PRIx64 " MAS8=0x%" PRIx32 "\n",
708 __func__, address, pid, tlb->mas1, tlb->mas2, mask,
709 tlb->mas7_3, tlb->mas8);
711 /* Check PID */
712 tlb_pid = (tlb->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT;
713 if (tlb_pid != 0 && tlb_pid != pid) {
714 return -1;
717 /* Check effective address */
718 if ((address & mask) != (tlb->mas2 & MAS2_EPN_MASK)) {
719 return -1;
722 if (raddrp) {
723 *raddrp = (tlb->mas7_3 & mask) | (address & ~mask);
726 return 0;
729 static bool is_epid_mmu(int mmu_idx)
731 return mmu_idx == PPC_TLB_EPID_STORE || mmu_idx == PPC_TLB_EPID_LOAD;
734 static uint32_t mmubooke206_esr(int mmu_idx, MMUAccessType access_type)
736 uint32_t esr = 0;
737 if (access_type == MMU_DATA_STORE) {
738 esr |= ESR_ST;
740 if (is_epid_mmu(mmu_idx)) {
741 esr |= ESR_EPID;
743 return esr;
747 * Get EPID register given the mmu_idx. If this is regular load,
748 * construct the EPID access bits from current processor state
750 * Get the effective AS and PR bits and the PID. The PID is returned
751 * only if EPID load is requested, otherwise the caller must detect
752 * the correct EPID. Return true if valid EPID is returned.
754 static bool mmubooke206_get_as(CPUPPCState *env,
755 int mmu_idx, uint32_t *epid_out,
756 bool *as_out, bool *pr_out)
758 if (is_epid_mmu(mmu_idx)) {
759 uint32_t epidr;
760 if (mmu_idx == PPC_TLB_EPID_STORE) {
761 epidr = env->spr[SPR_BOOKE_EPSC];
762 } else {
763 epidr = env->spr[SPR_BOOKE_EPLC];
765 *epid_out = (epidr & EPID_EPID) >> EPID_EPID_SHIFT;
766 *as_out = !!(epidr & EPID_EAS);
767 *pr_out = !!(epidr & EPID_EPR);
768 return true;
769 } else {
770 *as_out = msr_ds;
771 *pr_out = msr_pr;
772 return false;
776 /* Check if the tlb found by hashing really matches */
777 static int mmubooke206_check_tlb(CPUPPCState *env, ppcmas_tlb_t *tlb,
778 hwaddr *raddr, int *prot,
779 target_ulong address,
780 MMUAccessType access_type, int mmu_idx)
782 int prot2 = 0;
783 uint32_t epid;
784 bool as, pr;
785 bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr);
787 if (!use_epid) {
788 if (ppcmas_tlb_check(env, tlb, raddr, address,
789 env->spr[SPR_BOOKE_PID]) >= 0) {
790 goto found_tlb;
793 if (env->spr[SPR_BOOKE_PID1] &&
794 ppcmas_tlb_check(env, tlb, raddr, address,
795 env->spr[SPR_BOOKE_PID1]) >= 0) {
796 goto found_tlb;
799 if (env->spr[SPR_BOOKE_PID2] &&
800 ppcmas_tlb_check(env, tlb, raddr, address,
801 env->spr[SPR_BOOKE_PID2]) >= 0) {
802 goto found_tlb;
804 } else {
805 if (ppcmas_tlb_check(env, tlb, raddr, address, epid) >= 0) {
806 goto found_tlb;
810 qemu_log_mask(CPU_LOG_MMU, "%s: TLB entry not found\n", __func__);
811 return -1;
813 found_tlb:
815 if (pr) {
816 if (tlb->mas7_3 & MAS3_UR) {
817 prot2 |= PAGE_READ;
819 if (tlb->mas7_3 & MAS3_UW) {
820 prot2 |= PAGE_WRITE;
822 if (tlb->mas7_3 & MAS3_UX) {
823 prot2 |= PAGE_EXEC;
825 } else {
826 if (tlb->mas7_3 & MAS3_SR) {
827 prot2 |= PAGE_READ;
829 if (tlb->mas7_3 & MAS3_SW) {
830 prot2 |= PAGE_WRITE;
832 if (tlb->mas7_3 & MAS3_SX) {
833 prot2 |= PAGE_EXEC;
837 /* Check the address space and permissions */
838 if (access_type == MMU_INST_FETCH) {
839 /* There is no way to fetch code using epid load */
840 assert(!use_epid);
841 as = msr_ir;
844 if (as != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
845 qemu_log_mask(CPU_LOG_MMU, "%s: AS doesn't match\n", __func__);
846 return -1;
849 *prot = prot2;
850 if (prot2 & prot_for_access_type(access_type)) {
851 qemu_log_mask(CPU_LOG_MMU, "%s: good TLB!\n", __func__);
852 return 0;
855 qemu_log_mask(CPU_LOG_MMU, "%s: no prot match: %x\n", __func__, prot2);
856 return access_type == MMU_INST_FETCH ? -3 : -2;
859 static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
860 target_ulong address,
861 MMUAccessType access_type,
862 int mmu_idx)
864 ppcmas_tlb_t *tlb;
865 hwaddr raddr;
866 int i, j, ret;
868 ret = -1;
869 raddr = (hwaddr)-1ULL;
871 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
872 int ways = booke206_tlb_ways(env, i);
874 for (j = 0; j < ways; j++) {
875 tlb = booke206_get_tlbm(env, i, address, j);
876 if (!tlb) {
877 continue;
879 ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address,
880 access_type, mmu_idx);
881 if (ret != -1) {
882 goto found_tlb;
887 found_tlb:
889 if (ret >= 0) {
890 ctx->raddr = raddr;
891 qemu_log_mask(CPU_LOG_MMU, "%s: access granted " TARGET_FMT_lx
892 " => " TARGET_FMT_plx " %d %d\n", __func__, address,
893 ctx->raddr, ctx->prot, ret);
894 } else {
895 qemu_log_mask(CPU_LOG_MMU, "%s: access refused " TARGET_FMT_lx
896 " => " TARGET_FMT_plx " %d %d\n", __func__, address,
897 raddr, ctx->prot, ret);
900 return ret;
903 static const char *book3e_tsize_to_str[32] = {
904 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
905 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M",
906 "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G",
907 "1T", "2T"
910 static void mmubooke_dump_mmu(CPUPPCState *env)
912 ppcemb_tlb_t *entry;
913 int i;
915 if (kvm_enabled() && !env->kvm_sw_tlb) {
916 qemu_printf("Cannot access KVM TLB\n");
917 return;
920 qemu_printf("\nTLB:\n");
921 qemu_printf("Effective Physical Size PID Prot "
922 "Attr\n");
924 entry = &env->tlb.tlbe[0];
925 for (i = 0; i < env->nb_tlb; i++, entry++) {
926 hwaddr ea, pa;
927 target_ulong mask;
928 uint64_t size = (uint64_t)entry->size;
929 char size_buf[20];
931 /* Check valid flag */
932 if (!(entry->prot & PAGE_VALID)) {
933 continue;
936 mask = ~(entry->size - 1);
937 ea = entry->EPN & mask;
938 pa = entry->RPN & mask;
939 /* Extend the physical address to 36 bits */
940 pa |= (hwaddr)(entry->RPN & 0xF) << 32;
941 if (size >= 1 * MiB) {
942 snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "M", size / MiB);
943 } else {
944 snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "k", size / KiB);
946 qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %s %-5u %08x %08x\n",
947 (uint64_t)ea, (uint64_t)pa, size_buf, (uint32_t)entry->PID,
948 entry->prot, entry->attr);
953 static void mmubooke206_dump_one_tlb(CPUPPCState *env, int tlbn, int offset,
954 int tlbsize)
956 ppcmas_tlb_t *entry;
957 int i;
959 qemu_printf("\nTLB%d:\n", tlbn);
960 qemu_printf("Effective Physical Size TID TS SRWX"
961 " URWX WIMGE U0123\n");
963 entry = &env->tlb.tlbm[offset];
964 for (i = 0; i < tlbsize; i++, entry++) {
965 hwaddr ea, pa, size;
966 int tsize;
968 if (!(entry->mas1 & MAS1_VALID)) {
969 continue;
972 tsize = (entry->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
973 size = 1024ULL << tsize;
974 ea = entry->mas2 & ~(size - 1);
975 pa = entry->mas7_3 & ~(size - 1);
977 qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u S%c%c%c"
978 "U%c%c%c %c%c%c%c%c U%c%c%c%c\n",
979 (uint64_t)ea, (uint64_t)pa,
980 book3e_tsize_to_str[tsize],
981 (entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT,
982 (entry->mas1 & MAS1_TS) >> MAS1_TS_SHIFT,
983 entry->mas7_3 & MAS3_SR ? 'R' : '-',
984 entry->mas7_3 & MAS3_SW ? 'W' : '-',
985 entry->mas7_3 & MAS3_SX ? 'X' : '-',
986 entry->mas7_3 & MAS3_UR ? 'R' : '-',
987 entry->mas7_3 & MAS3_UW ? 'W' : '-',
988 entry->mas7_3 & MAS3_UX ? 'X' : '-',
989 entry->mas2 & MAS2_W ? 'W' : '-',
990 entry->mas2 & MAS2_I ? 'I' : '-',
991 entry->mas2 & MAS2_M ? 'M' : '-',
992 entry->mas2 & MAS2_G ? 'G' : '-',
993 entry->mas2 & MAS2_E ? 'E' : '-',
994 entry->mas7_3 & MAS3_U0 ? '0' : '-',
995 entry->mas7_3 & MAS3_U1 ? '1' : '-',
996 entry->mas7_3 & MAS3_U2 ? '2' : '-',
997 entry->mas7_3 & MAS3_U3 ? '3' : '-');
1001 static void mmubooke206_dump_mmu(CPUPPCState *env)
1003 int offset = 0;
1004 int i;
1006 if (kvm_enabled() && !env->kvm_sw_tlb) {
1007 qemu_printf("Cannot access KVM TLB\n");
1008 return;
1011 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
1012 int size = booke206_tlb_size(env, i);
1014 if (size == 0) {
1015 continue;
1018 mmubooke206_dump_one_tlb(env, i, offset, size);
1019 offset += size;
1023 static void mmu6xx_dump_BATs(CPUPPCState *env, int type)
1025 target_ulong *BATlt, *BATut, *BATu, *BATl;
1026 target_ulong BEPIl, BEPIu, bl;
1027 int i;
1029 switch (type) {
1030 case ACCESS_CODE:
1031 BATlt = env->IBAT[1];
1032 BATut = env->IBAT[0];
1033 break;
1034 default:
1035 BATlt = env->DBAT[1];
1036 BATut = env->DBAT[0];
1037 break;
1040 for (i = 0; i < env->nb_BATs; i++) {
1041 BATu = &BATut[i];
1042 BATl = &BATlt[i];
1043 BEPIu = *BATu & 0xF0000000;
1044 BEPIl = *BATu & 0x0FFE0000;
1045 bl = (*BATu & 0x00001FFC) << 15;
1046 qemu_printf("%s BAT%d BATu " TARGET_FMT_lx
1047 " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
1048 TARGET_FMT_lx " " TARGET_FMT_lx "\n",
1049 type == ACCESS_CODE ? "code" : "data", i,
1050 *BATu, *BATl, BEPIu, BEPIl, bl);
1054 static void mmu6xx_dump_mmu(CPUPPCState *env)
1056 PowerPCCPU *cpu = env_archcpu(env);
1057 ppc6xx_tlb_t *tlb;
1058 target_ulong sr;
1059 int type, way, entry, i;
1061 qemu_printf("HTAB base = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_base(cpu));
1062 qemu_printf("HTAB mask = 0x%"HWADDR_PRIx"\n", ppc_hash32_hpt_mask(cpu));
1064 qemu_printf("\nSegment registers:\n");
1065 for (i = 0; i < 32; i++) {
1066 sr = env->sr[i];
1067 if (sr & 0x80000000) {
1068 qemu_printf("%02d T=%d Ks=%d Kp=%d BUID=0x%03x "
1069 "CNTLR_SPEC=0x%05x\n", i,
1070 sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
1071 sr & 0x20000000 ? 1 : 0, (uint32_t)((sr >> 20) & 0x1FF),
1072 (uint32_t)(sr & 0xFFFFF));
1073 } else {
1074 qemu_printf("%02d T=%d Ks=%d Kp=%d N=%d VSID=0x%06x\n", i,
1075 sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
1076 sr & 0x20000000 ? 1 : 0, sr & 0x10000000 ? 1 : 0,
1077 (uint32_t)(sr & 0x00FFFFFF));
1081 qemu_printf("\nBATs:\n");
1082 mmu6xx_dump_BATs(env, ACCESS_INT);
1083 mmu6xx_dump_BATs(env, ACCESS_CODE);
1085 if (env->id_tlbs != 1) {
1086 qemu_printf("ERROR: 6xx MMU should have separated TLB"
1087 " for code and data\n");
1090 qemu_printf("\nTLBs [EPN EPN + SIZE]\n");
1092 for (type = 0; type < 2; type++) {
1093 for (way = 0; way < env->nb_ways; way++) {
1094 for (entry = env->nb_tlb * type + env->tlb_per_way * way;
1095 entry < (env->nb_tlb * type + env->tlb_per_way * (way + 1));
1096 entry++) {
1098 tlb = &env->tlb.tlb6[entry];
1099 qemu_printf("%s TLB %02d/%02d way:%d %s ["
1100 TARGET_FMT_lx " " TARGET_FMT_lx "]\n",
1101 type ? "code" : "data", entry % env->nb_tlb,
1102 env->nb_tlb, way,
1103 pte_is_valid(tlb->pte0) ? "valid" : "inval",
1104 tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE);
1110 void dump_mmu(CPUPPCState *env)
1112 switch (env->mmu_model) {
1113 case POWERPC_MMU_BOOKE:
1114 mmubooke_dump_mmu(env);
1115 break;
1116 case POWERPC_MMU_BOOKE206:
1117 mmubooke206_dump_mmu(env);
1118 break;
1119 case POWERPC_MMU_SOFT_6xx:
1120 mmu6xx_dump_mmu(env);
1121 break;
1122 #if defined(TARGET_PPC64)
1123 case POWERPC_MMU_64B:
1124 case POWERPC_MMU_2_03:
1125 case POWERPC_MMU_2_06:
1126 case POWERPC_MMU_2_07:
1127 dump_slb(env_archcpu(env));
1128 break;
1129 case POWERPC_MMU_3_00:
1130 if (ppc64_v3_radix(env_archcpu(env))) {
1131 qemu_log_mask(LOG_UNIMP, "%s: the PPC64 MMU is unsupported\n",
1132 __func__);
1133 } else {
1134 dump_slb(env_archcpu(env));
1136 break;
1137 #endif
1138 default:
1139 qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__);
1143 static int check_physical(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong eaddr,
1144 MMUAccessType access_type)
1146 ctx->raddr = eaddr;
1147 ctx->prot = PAGE_READ | PAGE_EXEC;
1149 switch (env->mmu_model) {
1150 case POWERPC_MMU_SOFT_6xx:
1151 case POWERPC_MMU_SOFT_4xx:
1152 case POWERPC_MMU_REAL:
1153 case POWERPC_MMU_BOOKE:
1154 ctx->prot |= PAGE_WRITE;
1155 break;
1157 default:
1158 /* Caller's checks mean we should never get here for other models */
1159 g_assert_not_reached();
1162 return 0;
1165 int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
1166 target_ulong eaddr,
1167 MMUAccessType access_type, int type,
1168 int mmu_idx)
1170 int ret = -1;
1171 bool real_mode = (type == ACCESS_CODE && msr_ir == 0)
1172 || (type != ACCESS_CODE && msr_dr == 0);
1174 switch (env->mmu_model) {
1175 case POWERPC_MMU_SOFT_6xx:
1176 if (real_mode) {
1177 ret = check_physical(env, ctx, eaddr, access_type);
1178 } else {
1179 /* Try to find a BAT */
1180 if (env->nb_BATs != 0) {
1181 ret = get_bat_6xx_tlb(env, ctx, eaddr, access_type);
1183 if (ret < 0) {
1184 /* We didn't match any BAT entry or don't have BATs */
1185 ret = get_segment_6xx_tlb(env, ctx, eaddr, access_type, type);
1188 break;
1190 case POWERPC_MMU_SOFT_4xx:
1191 if (real_mode) {
1192 ret = check_physical(env, ctx, eaddr, access_type);
1193 } else {
1194 ret = mmu40x_get_physical_address(env, ctx, eaddr, access_type);
1196 break;
1197 case POWERPC_MMU_BOOKE:
1198 ret = mmubooke_get_physical_address(env, ctx, eaddr, access_type);
1199 break;
1200 case POWERPC_MMU_BOOKE206:
1201 ret = mmubooke206_get_physical_address(env, ctx, eaddr, access_type,
1202 mmu_idx);
1203 break;
1204 case POWERPC_MMU_MPC8xx:
1205 /* XXX: TODO */
1206 cpu_abort(env_cpu(env), "MPC8xx MMU model is not implemented\n");
1207 break;
1208 case POWERPC_MMU_REAL:
1209 if (real_mode) {
1210 ret = check_physical(env, ctx, eaddr, access_type);
1211 } else {
1212 cpu_abort(env_cpu(env),
1213 "PowerPC in real mode do not do any translation\n");
1215 return -1;
1216 default:
1217 cpu_abort(env_cpu(env), "Unknown or invalid MMU model\n");
1218 return -1;
1221 return ret;
1224 static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
1225 MMUAccessType access_type, int mmu_idx)
1227 uint32_t epid;
1228 bool as, pr;
1229 uint32_t missed_tid = 0;
1230 bool use_epid = mmubooke206_get_as(env, mmu_idx, &epid, &as, &pr);
1232 if (access_type == MMU_INST_FETCH) {
1233 as = msr_ir;
1235 env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK;
1236 env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK;
1237 env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK;
1238 env->spr[SPR_BOOKE_MAS3] = 0;
1239 env->spr[SPR_BOOKE_MAS6] = 0;
1240 env->spr[SPR_BOOKE_MAS7] = 0;
1242 /* AS */
1243 if (as) {
1244 env->spr[SPR_BOOKE_MAS1] |= MAS1_TS;
1245 env->spr[SPR_BOOKE_MAS6] |= MAS6_SAS;
1248 env->spr[SPR_BOOKE_MAS1] |= MAS1_VALID;
1249 env->spr[SPR_BOOKE_MAS2] |= address & MAS2_EPN_MASK;
1251 if (!use_epid) {
1252 switch (env->spr[SPR_BOOKE_MAS4] & MAS4_TIDSELD_PIDZ) {
1253 case MAS4_TIDSELD_PID0:
1254 missed_tid = env->spr[SPR_BOOKE_PID];
1255 break;
1256 case MAS4_TIDSELD_PID1:
1257 missed_tid = env->spr[SPR_BOOKE_PID1];
1258 break;
1259 case MAS4_TIDSELD_PID2:
1260 missed_tid = env->spr[SPR_BOOKE_PID2];
1261 break;
1263 env->spr[SPR_BOOKE_MAS6] |= env->spr[SPR_BOOKE_PID] << 16;
1264 } else {
1265 missed_tid = epid;
1266 env->spr[SPR_BOOKE_MAS6] |= missed_tid << 16;
1268 env->spr[SPR_BOOKE_MAS1] |= (missed_tid << MAS1_TID_SHIFT);
1271 /* next victim logic */
1272 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
1273 env->last_way++;
1274 env->last_way &= booke206_tlb_ways(env, 0) - 1;
1275 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
1278 /* Perform address translation */
1279 /* TODO: Split this by mmu_model. */
1280 static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
1281 MMUAccessType access_type,
1282 hwaddr *raddrp, int *psizep, int *protp,
1283 int mmu_idx, bool guest_visible)
1285 CPUState *cs = CPU(cpu);
1286 CPUPPCState *env = &cpu->env;
1287 mmu_ctx_t ctx;
1288 int type;
1289 int ret;
1291 if (access_type == MMU_INST_FETCH) {
1292 /* code access */
1293 type = ACCESS_CODE;
1294 } else if (guest_visible) {
1295 /* data access */
1296 type = env->access_type;
1297 } else {
1298 type = ACCESS_INT;
1301 ret = get_physical_address_wtlb(env, &ctx, eaddr, access_type,
1302 type, mmu_idx);
1303 if (ret == 0) {
1304 *raddrp = ctx.raddr;
1305 *protp = ctx.prot;
1306 *psizep = TARGET_PAGE_BITS;
1307 return true;
1310 if (guest_visible) {
1311 log_cpu_state_mask(CPU_LOG_MMU, cs, 0);
1312 if (type == ACCESS_CODE) {
1313 switch (ret) {
1314 case -1:
1315 /* No matches in page tables or TLB */
1316 switch (env->mmu_model) {
1317 case POWERPC_MMU_SOFT_6xx:
1318 cs->exception_index = POWERPC_EXCP_IFTLB;
1319 env->error_code = 1 << 18;
1320 env->spr[SPR_IMISS] = eaddr;
1321 env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
1322 goto tlb_miss;
1323 case POWERPC_MMU_SOFT_4xx:
1324 cs->exception_index = POWERPC_EXCP_ITLB;
1325 env->error_code = 0;
1326 env->spr[SPR_40x_DEAR] = eaddr;
1327 env->spr[SPR_40x_ESR] = 0x00000000;
1328 break;
1329 case POWERPC_MMU_BOOKE206:
1330 booke206_update_mas_tlb_miss(env, eaddr, 2, mmu_idx);
1331 /* fall through */
1332 case POWERPC_MMU_BOOKE:
1333 cs->exception_index = POWERPC_EXCP_ITLB;
1334 env->error_code = 0;
1335 env->spr[SPR_BOOKE_DEAR] = eaddr;
1336 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, MMU_DATA_LOAD);
1337 break;
1338 case POWERPC_MMU_MPC8xx:
1339 cpu_abort(cs, "MPC8xx MMU model is not implemented\n");
1340 case POWERPC_MMU_REAL:
1341 cpu_abort(cs, "PowerPC in real mode should never raise "
1342 "any MMU exceptions\n");
1343 default:
1344 cpu_abort(cs, "Unknown or invalid MMU model\n");
1346 break;
1347 case -2:
1348 /* Access rights violation */
1349 cs->exception_index = POWERPC_EXCP_ISI;
1350 if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1351 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1352 env->error_code = 0;
1353 } else {
1354 env->error_code = 0x08000000;
1356 break;
1357 case -3:
1358 /* No execute protection violation */
1359 if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1360 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1361 env->spr[SPR_BOOKE_ESR] = 0x00000000;
1362 env->error_code = 0;
1363 } else {
1364 env->error_code = 0x10000000;
1366 cs->exception_index = POWERPC_EXCP_ISI;
1367 break;
1368 case -4:
1369 /* Direct store exception */
1370 /* No code fetch is allowed in direct-store areas */
1371 cs->exception_index = POWERPC_EXCP_ISI;
1372 if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1373 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1374 env->error_code = 0;
1375 } else {
1376 env->error_code = 0x10000000;
1378 break;
1380 } else {
1381 switch (ret) {
1382 case -1:
1383 /* No matches in page tables or TLB */
1384 switch (env->mmu_model) {
1385 case POWERPC_MMU_SOFT_6xx:
1386 if (access_type == MMU_DATA_STORE) {
1387 cs->exception_index = POWERPC_EXCP_DSTLB;
1388 env->error_code = 1 << 16;
1389 } else {
1390 cs->exception_index = POWERPC_EXCP_DLTLB;
1391 env->error_code = 0;
1393 env->spr[SPR_DMISS] = eaddr;
1394 env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
1395 tlb_miss:
1396 env->error_code |= ctx.key << 19;
1397 env->spr[SPR_HASH1] = ppc_hash32_hpt_base(cpu) +
1398 get_pteg_offset32(cpu, ctx.hash[0]);
1399 env->spr[SPR_HASH2] = ppc_hash32_hpt_base(cpu) +
1400 get_pteg_offset32(cpu, ctx.hash[1]);
1401 break;
1402 case POWERPC_MMU_SOFT_4xx:
1403 cs->exception_index = POWERPC_EXCP_DTLB;
1404 env->error_code = 0;
1405 env->spr[SPR_40x_DEAR] = eaddr;
1406 if (access_type == MMU_DATA_STORE) {
1407 env->spr[SPR_40x_ESR] = 0x00800000;
1408 } else {
1409 env->spr[SPR_40x_ESR] = 0x00000000;
1411 break;
1412 case POWERPC_MMU_MPC8xx:
1413 /* XXX: TODO */
1414 cpu_abort(cs, "MPC8xx MMU model is not implemented\n");
1415 case POWERPC_MMU_BOOKE206:
1416 booke206_update_mas_tlb_miss(env, eaddr, access_type, mmu_idx);
1417 /* fall through */
1418 case POWERPC_MMU_BOOKE:
1419 cs->exception_index = POWERPC_EXCP_DTLB;
1420 env->error_code = 0;
1421 env->spr[SPR_BOOKE_DEAR] = eaddr;
1422 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1423 break;
1424 case POWERPC_MMU_REAL:
1425 cpu_abort(cs, "PowerPC in real mode should never raise "
1426 "any MMU exceptions\n");
1427 default:
1428 cpu_abort(cs, "Unknown or invalid MMU model\n");
1430 break;
1431 case -2:
1432 /* Access rights violation */
1433 cs->exception_index = POWERPC_EXCP_DSI;
1434 env->error_code = 0;
1435 if (env->mmu_model == POWERPC_MMU_SOFT_4xx) {
1436 env->spr[SPR_40x_DEAR] = eaddr;
1437 if (access_type == MMU_DATA_STORE) {
1438 env->spr[SPR_40x_ESR] |= 0x00800000;
1440 } else if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1441 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1442 env->spr[SPR_BOOKE_DEAR] = eaddr;
1443 env->spr[SPR_BOOKE_ESR] = mmubooke206_esr(mmu_idx, access_type);
1444 } else {
1445 env->spr[SPR_DAR] = eaddr;
1446 if (access_type == MMU_DATA_STORE) {
1447 env->spr[SPR_DSISR] = 0x0A000000;
1448 } else {
1449 env->spr[SPR_DSISR] = 0x08000000;
1452 break;
1453 case -4:
1454 /* Direct store exception */
1455 switch (type) {
1456 case ACCESS_FLOAT:
1457 /* Floating point load/store */
1458 cs->exception_index = POWERPC_EXCP_ALIGN;
1459 env->error_code = POWERPC_EXCP_ALIGN_FP;
1460 env->spr[SPR_DAR] = eaddr;
1461 break;
1462 case ACCESS_RES:
1463 /* lwarx, ldarx or stwcx. */
1464 cs->exception_index = POWERPC_EXCP_DSI;
1465 env->error_code = 0;
1466 env->spr[SPR_DAR] = eaddr;
1467 if (access_type == MMU_DATA_STORE) {
1468 env->spr[SPR_DSISR] = 0x06000000;
1469 } else {
1470 env->spr[SPR_DSISR] = 0x04000000;
1472 break;
1473 case ACCESS_EXT:
1474 /* eciwx or ecowx */
1475 cs->exception_index = POWERPC_EXCP_DSI;
1476 env->error_code = 0;
1477 env->spr[SPR_DAR] = eaddr;
1478 if (access_type == MMU_DATA_STORE) {
1479 env->spr[SPR_DSISR] = 0x06100000;
1480 } else {
1481 env->spr[SPR_DSISR] = 0x04100000;
1483 break;
1484 default:
1485 printf("DSI: invalid exception (%d)\n", ret);
1486 cs->exception_index = POWERPC_EXCP_PROGRAM;
1487 env->error_code =
1488 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
1489 env->spr[SPR_DAR] = eaddr;
1490 break;
1492 break;
1496 return false;
1499 /*****************************************************************************/
1501 bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
1502 hwaddr *raddrp, int *psizep, int *protp,
1503 int mmu_idx, bool guest_visible)
1505 switch (cpu->env.mmu_model) {
1506 #if defined(TARGET_PPC64)
1507 case POWERPC_MMU_3_00:
1508 if (ppc64_v3_radix(cpu)) {
1509 return ppc_radix64_xlate(cpu, eaddr, access_type, raddrp,
1510 psizep, protp, mmu_idx, guest_visible);
1512 /* fall through */
1513 case POWERPC_MMU_64B:
1514 case POWERPC_MMU_2_03:
1515 case POWERPC_MMU_2_06:
1516 case POWERPC_MMU_2_07:
1517 return ppc_hash64_xlate(cpu, eaddr, access_type,
1518 raddrp, psizep, protp, mmu_idx, guest_visible);
1519 #endif
1521 case POWERPC_MMU_32B:
1522 return ppc_hash32_xlate(cpu, eaddr, access_type, raddrp,
1523 psizep, protp, mmu_idx, guest_visible);
1525 default:
1526 return ppc_jumbo_xlate(cpu, eaddr, access_type, raddrp,
1527 psizep, protp, mmu_idx, guest_visible);
1531 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
1533 PowerPCCPU *cpu = POWERPC_CPU(cs);
1534 hwaddr raddr;
1535 int s, p;
1538 * Some MMUs have separate TLBs for code and data. If we only
1539 * try an MMU_DATA_LOAD, we may not be able to read instructions
1540 * mapped by code TLBs, so we also try a MMU_INST_FETCH.
1542 if (ppc_xlate(cpu, addr, MMU_DATA_LOAD, &raddr, &s, &p,
1543 cpu_mmu_index(&cpu->env, false), false) ||
1544 ppc_xlate(cpu, addr, MMU_INST_FETCH, &raddr, &s, &p,
1545 cpu_mmu_index(&cpu->env, true), false)) {
1546 return raddr & TARGET_PAGE_MASK;
1548 return -1;