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