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"
23 #include "sysemu/kvm.h"
25 #include "mmu-hash64.h"
26 #include "mmu-hash32.h"
27 #include "exec/exec-all.h"
29 #include "helper_regs.h"
30 #include "qemu/error-report.h"
31 #include "qemu/main-loop.h"
32 #include "qemu/qemu-print.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
);
55 qemu_log_mask(LOG_GUEST_ERROR
, "Invalid HTABSIZE 0x" TARGET_FMT_lx
56 " stored in SDR1", htabsize
);
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
)
72 /* Compute access rights */
95 access
= PAGE_READ
| PAGE_WRITE
;
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
)
116 /* Select TLB num in a way from address */
117 nr
= (eaddr
>> TARGET_PAGE_BITS
) & (env
->tlb_per_way
- 1);
119 nr
+= env
->tlb_per_way
* way
;
120 /* 6xx have separate TLBs for instructions and data */
121 if (is_code
&& env
->id_tlbs
== 1) {
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
;
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");
152 /* Compute access rights */
153 access
= pp_check(ctx
->key
, pp
, ctx
->nx
);
154 /* Keep the matching PTE information */
157 ret
= check_prot(ctx
->prot
, access_type
);
160 qemu_log_mask(CPU_LOG_MMU
, "PTE access granted !\n");
162 /* Access right violation */
163 qemu_log_mask(CPU_LOG_MMU
, "PTE access rejected\n");
171 static int pte_update_flags(mmu_ctx_t
*ctx
, target_ulong
*pte1p
,
172 int ret
, MMUAccessType access_type
)
176 /* Update page flags */
177 if (!(*pte1p
& 0x00000100)) {
178 /* Update accessed flag */
179 *pte1p
|= 0x00000100;
182 if (!(*pte1p
& 0x00000080)) {
183 if (access_type
== MMU_DATA_STORE
&& ret
== 0) {
184 /* Update changed flag */
185 *pte1p
|= 0x00000080;
188 /* Force page fault for first write access */
189 ctx
->prot
&= ~PAGE_WRITE
;
196 /* Software driven TLB helpers */
198 static int ppc6xx_tlb_check(CPUPPCState
*env
, mmu_ctx_t
*ctx
,
199 target_ulong eaddr
, MMUAccessType access_type
)
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",
215 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
216 tlb
->EPN
, tlb
->EPN
+ TARGET_PAGE_SIZE
, eaddr
);
219 qemu_log_mask(CPU_LOG_MMU
, "TLB %d/%d %s " TARGET_FMT_lx
" <> "
220 TARGET_FMT_lx
" " TARGET_FMT_lx
" %c %c\n",
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
,
229 /* TLB inconsistency */
232 /* Access violation */
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
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
);
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
,
273 bl
= (*BATu
& 0x00001FFC) << 15;
276 if (((msr_pr
== 0) && (*BATu
& 0x00000002)) ||
277 ((msr_pr
!= 0) && (*BATu
& 0x00000001))) {
279 pp
= *BATl
& 0x00000003;
281 prot
= PAGE_READ
| PAGE_EXEC
;
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
;
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);
304 BATlt
= env
->IBAT
[1];
305 BATut
= env
->IBAT
[0];
307 BATlt
= env
->DBAT
[1];
308 BATut
= env
->DBAT
[0];
310 for (i
= 0; i
< env
->nb_BATs
; 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
) {
323 /* Get physical address */
324 ctx
->raddr
= (*BATl
& 0xF0000000) |
325 ((virtual & 0x0FFE0000 & bl
) | (*BATl
& 0x0FFE0000)) |
326 (virtual & 0x0001F000);
327 /* Compute access rights */
329 ret
= check_prot(ctx
->prot
, access_type
);
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' : '-');
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
++) {
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
);
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
,
368 PowerPCCPU
*cpu
= env_archcpu(env
);
371 int ds
, pr
, target_page_bits
;
373 target_ulong sr
, pgidx
;
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
;
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
);
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
);
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
);
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);
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
);
440 qemu_log_mask(CPU_LOG_MMU
, "No access allowed\n");
446 qemu_log_mask(CPU_LOG_MMU
, "direct store...\n");
447 /* Direct-store segment : absolutely *BUGGY* for now */
450 * Direct-store implies a 32-bit MMU.
451 * Check the Segment Register's bus unit ID (BUID).
453 sr
= env
->sr
[eaddr
>> 28];
454 if ((sr
& 0x1FF00000) >> 20 == 0x07f) {
456 * Memory-forced I/O controller interface access
458 * If T=1 and BUID=x'07F', the 601 performs a memory
459 * access to SR[28-31] LA[4-31], bypassing all protection
462 ctx
->raddr
= ((sr
& 0xF) << 28) | (eaddr
& 0x0FFFFFFF);
463 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
469 /* Integer load/store : only access allowed */
472 /* No code fetch is allowed in direct-store areas */
475 /* Floating point load/store */
478 /* lwarx, ldarx or srwcx. */
482 * dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi
484 * Should make the instruction do no-op. As it already do
485 * no-op, it's quite easy :-)
493 qemu_log_mask(CPU_LOG_MMU
, "ERROR: instruction should not need "
494 "address translation\n");
497 if ((access_type
== MMU_DATA_STORE
|| ctx
->key
!= 1) &&
498 (access_type
== MMU_DATA_LOAD
|| ctx
->key
!= 0)) {
509 /* Generic TLB check function for embedded PowerPC implementations */
510 int ppcemb_tlb_check(CPUPPCState
*env
, ppcemb_tlb_t
*tlb
,
512 target_ulong address
, uint32_t pid
, int ext
,
517 /* Check valid flag */
518 if (!(tlb
->prot
& PAGE_VALID
)) {
521 mask
= ~(tlb
->size
- 1);
522 qemu_log_mask(CPU_LOG_MMU
, "%s: TLB %d address " TARGET_FMT_lx
523 " PID %u <=> " TARGET_FMT_lx
" " TARGET_FMT_lx
" %u %x\n",
524 __func__
, i
, address
, pid
, tlb
->EPN
,
525 mask
, (uint32_t)tlb
->PID
, tlb
->prot
);
527 if (tlb
->PID
!= 0 && tlb
->PID
!= pid
) {
530 /* Check effective address */
531 if ((address
& mask
) != tlb
->EPN
) {
534 *raddrp
= (tlb
->RPN
& mask
) | (address
& ~mask
);
536 /* Extend the physical address to 36 bits */
537 *raddrp
|= (uint64_t)(tlb
->RPN
& 0xF) << 32;
543 static int mmu40x_get_physical_address(CPUPPCState
*env
, mmu_ctx_t
*ctx
,
544 target_ulong address
,
545 MMUAccessType access_type
)
549 int i
, ret
, zsel
, zpr
, pr
;
552 raddr
= (hwaddr
)-1ULL;
554 for (i
= 0; i
< env
->nb_tlb
; i
++) {
555 tlb
= &env
->tlb
.tlbe
[i
];
556 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
,
557 env
->spr
[SPR_40x_PID
], 0, i
) < 0) {
560 zsel
= (tlb
->attr
>> 4) & 0xF;
561 zpr
= (env
->spr
[SPR_40x_ZPR
] >> (30 - (2 * zsel
))) & 0x3;
562 qemu_log_mask(CPU_LOG_MMU
,
563 "%s: TLB %d zsel %d zpr %d ty %d attr %08x\n",
564 __func__
, i
, zsel
, zpr
, access_type
, tlb
->attr
);
565 /* Check execute enable bit */
573 /* All accesses granted */
574 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
579 /* Raise Zone protection fault. */
580 env
->spr
[SPR_40x_ESR
] = 1 << 22;
588 /* Check from TLB entry */
589 ctx
->prot
= tlb
->prot
;
590 ret
= check_prot(ctx
->prot
, access_type
);
592 env
->spr
[SPR_40x_ESR
] = 0;
598 qemu_log_mask(CPU_LOG_MMU
, "%s: access granted " TARGET_FMT_lx
599 " => " TARGET_FMT_plx
600 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
605 qemu_log_mask(CPU_LOG_MMU
, "%s: access refused " TARGET_FMT_lx
606 " => " TARGET_FMT_plx
607 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
612 static int mmubooke_check_tlb(CPUPPCState
*env
, ppcemb_tlb_t
*tlb
,
613 hwaddr
*raddr
, int *prot
, target_ulong address
,
614 MMUAccessType access_type
, int i
)
618 if (ppcemb_tlb_check(env
, tlb
, raddr
, address
,
619 env
->spr
[SPR_BOOKE_PID
],
620 !env
->nb_pids
, i
) >= 0) {
624 if (env
->spr
[SPR_BOOKE_PID1
] &&
625 ppcemb_tlb_check(env
, tlb
, raddr
, address
,
626 env
->spr
[SPR_BOOKE_PID1
], 0, i
) >= 0) {
630 if (env
->spr
[SPR_BOOKE_PID2
] &&
631 ppcemb_tlb_check(env
, tlb
, raddr
, address
,
632 env
->spr
[SPR_BOOKE_PID2
], 0, i
) >= 0) {
636 qemu_log_mask(CPU_LOG_MMU
, "%s: TLB entry not found\n", __func__
);
642 prot2
= tlb
->prot
& 0xF;
644 prot2
= (tlb
->prot
>> 4) & 0xF;
647 /* Check the address space */
648 if ((access_type
== MMU_INST_FETCH
? msr_ir
: msr_dr
) != (tlb
->attr
& 1)) {
649 qemu_log_mask(CPU_LOG_MMU
, "%s: AS doesn't match\n", __func__
);
654 if (prot2
& prot_for_access_type(access_type
)) {
655 qemu_log_mask(CPU_LOG_MMU
, "%s: good TLB!\n", __func__
);
659 qemu_log_mask(CPU_LOG_MMU
, "%s: no prot match: %x\n", __func__
, prot2
);
660 return access_type
== MMU_INST_FETCH
? -3 : -2;
663 static int mmubooke_get_physical_address(CPUPPCState
*env
, mmu_ctx_t
*ctx
,
664 target_ulong address
,
665 MMUAccessType access_type
)
672 raddr
= (hwaddr
)-1ULL;
673 for (i
= 0; i
< env
->nb_tlb
; i
++) {
674 tlb
= &env
->tlb
.tlbe
[i
];
675 ret
= mmubooke_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
,
684 qemu_log_mask(CPU_LOG_MMU
, "%s: access granted " TARGET_FMT_lx
685 " => " TARGET_FMT_plx
" %d %d\n", __func__
,
686 address
, ctx
->raddr
, ctx
->prot
, ret
);
688 qemu_log_mask(CPU_LOG_MMU
, "%s: access refused " TARGET_FMT_lx
689 " => " TARGET_FMT_plx
" %d %d\n", __func__
,
690 address
, raddr
, ctx
->prot
, ret
);
696 hwaddr
booke206_tlb_to_page_size(CPUPPCState
*env
,
701 tlbm_size
= (tlb
->mas1
& MAS1_TSIZE_MASK
) >> MAS1_TSIZE_SHIFT
;
703 return 1024ULL << tlbm_size
;
706 /* TLB check function for MAS based SoftTLBs */
707 int ppcmas_tlb_check(CPUPPCState
*env
, ppcmas_tlb_t
*tlb
,
708 hwaddr
*raddrp
, target_ulong address
,
715 /* In 32bit mode we can only address 32bit EAs */
716 address
= (uint32_t)address
;
719 /* Check valid flag */
720 if (!(tlb
->mas1
& MAS1_VALID
)) {
724 mask
= ~(booke206_tlb_to_page_size(env
, tlb
) - 1);
725 qemu_log_mask(CPU_LOG_MMU
, "%s: TLB ADDR=0x" TARGET_FMT_lx
726 " PID=0x%x MAS1=0x%x MAS2=0x%" PRIx64
" mask=0x%"
727 HWADDR_PRIx
" MAS7_3=0x%" PRIx64
" MAS8=0x%" PRIx32
"\n",
728 __func__
, address
, pid
, tlb
->mas1
, tlb
->mas2
, mask
,
729 tlb
->mas7_3
, tlb
->mas8
);
732 tlb_pid
= (tlb
->mas1
& MAS1_TID_MASK
) >> MAS1_TID_SHIFT
;
733 if (tlb_pid
!= 0 && tlb_pid
!= pid
) {
737 /* Check effective address */
738 if ((address
& mask
) != (tlb
->mas2
& MAS2_EPN_MASK
)) {
743 *raddrp
= (tlb
->mas7_3
& mask
) | (address
& ~mask
);
749 static bool is_epid_mmu(int mmu_idx
)
751 return mmu_idx
== PPC_TLB_EPID_STORE
|| mmu_idx
== PPC_TLB_EPID_LOAD
;
754 static uint32_t mmubooke206_esr(int mmu_idx
, MMUAccessType access_type
)
757 if (access_type
== MMU_DATA_STORE
) {
760 if (is_epid_mmu(mmu_idx
)) {
767 * Get EPID register given the mmu_idx. If this is regular load,
768 * construct the EPID access bits from current processor state
770 * Get the effective AS and PR bits and the PID. The PID is returned
771 * only if EPID load is requested, otherwise the caller must detect
772 * the correct EPID. Return true if valid EPID is returned.
774 static bool mmubooke206_get_as(CPUPPCState
*env
,
775 int mmu_idx
, uint32_t *epid_out
,
776 bool *as_out
, bool *pr_out
)
778 if (is_epid_mmu(mmu_idx
)) {
780 if (mmu_idx
== PPC_TLB_EPID_STORE
) {
781 epidr
= env
->spr
[SPR_BOOKE_EPSC
];
783 epidr
= env
->spr
[SPR_BOOKE_EPLC
];
785 *epid_out
= (epidr
& EPID_EPID
) >> EPID_EPID_SHIFT
;
786 *as_out
= !!(epidr
& EPID_EAS
);
787 *pr_out
= !!(epidr
& EPID_EPR
);
796 /* Check if the tlb found by hashing really matches */
797 static int mmubooke206_check_tlb(CPUPPCState
*env
, ppcmas_tlb_t
*tlb
,
798 hwaddr
*raddr
, int *prot
,
799 target_ulong address
,
800 MMUAccessType access_type
, int mmu_idx
)
805 bool use_epid
= mmubooke206_get_as(env
, mmu_idx
, &epid
, &as
, &pr
);
808 if (ppcmas_tlb_check(env
, tlb
, raddr
, address
,
809 env
->spr
[SPR_BOOKE_PID
]) >= 0) {
813 if (env
->spr
[SPR_BOOKE_PID1
] &&
814 ppcmas_tlb_check(env
, tlb
, raddr
, address
,
815 env
->spr
[SPR_BOOKE_PID1
]) >= 0) {
819 if (env
->spr
[SPR_BOOKE_PID2
] &&
820 ppcmas_tlb_check(env
, tlb
, raddr
, address
,
821 env
->spr
[SPR_BOOKE_PID2
]) >= 0) {
825 if (ppcmas_tlb_check(env
, tlb
, raddr
, address
, epid
) >= 0) {
830 qemu_log_mask(CPU_LOG_MMU
, "%s: TLB entry not found\n", __func__
);
836 if (tlb
->mas7_3
& MAS3_UR
) {
839 if (tlb
->mas7_3
& MAS3_UW
) {
842 if (tlb
->mas7_3
& MAS3_UX
) {
846 if (tlb
->mas7_3
& MAS3_SR
) {
849 if (tlb
->mas7_3
& MAS3_SW
) {
852 if (tlb
->mas7_3
& MAS3_SX
) {
857 /* Check the address space and permissions */
858 if (access_type
== MMU_INST_FETCH
) {
859 /* There is no way to fetch code using epid load */
864 if (as
!= ((tlb
->mas1
& MAS1_TS
) >> MAS1_TS_SHIFT
)) {
865 qemu_log_mask(CPU_LOG_MMU
, "%s: AS doesn't match\n", __func__
);
870 if (prot2
& prot_for_access_type(access_type
)) {
871 qemu_log_mask(CPU_LOG_MMU
, "%s: good TLB!\n", __func__
);
875 qemu_log_mask(CPU_LOG_MMU
, "%s: no prot match: %x\n", __func__
, prot2
);
876 return access_type
== MMU_INST_FETCH
? -3 : -2;
879 static int mmubooke206_get_physical_address(CPUPPCState
*env
, mmu_ctx_t
*ctx
,
880 target_ulong address
,
881 MMUAccessType access_type
,
889 raddr
= (hwaddr
)-1ULL;
891 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
892 int ways
= booke206_tlb_ways(env
, i
);
894 for (j
= 0; j
< ways
; j
++) {
895 tlb
= booke206_get_tlbm(env
, i
, address
, j
);
899 ret
= mmubooke206_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
,
900 access_type
, mmu_idx
);
911 qemu_log_mask(CPU_LOG_MMU
, "%s: access granted " TARGET_FMT_lx
912 " => " TARGET_FMT_plx
" %d %d\n", __func__
, address
,
913 ctx
->raddr
, ctx
->prot
, ret
);
915 qemu_log_mask(CPU_LOG_MMU
, "%s: access refused " TARGET_FMT_lx
916 " => " TARGET_FMT_plx
" %d %d\n", __func__
, address
,
917 raddr
, ctx
->prot
, ret
);
923 static const char *book3e_tsize_to_str
[32] = {
924 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
925 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M",
926 "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G",
930 static void mmubooke_dump_mmu(CPUPPCState
*env
)
935 if (kvm_enabled() && !env
->kvm_sw_tlb
) {
936 qemu_printf("Cannot access KVM TLB\n");
940 qemu_printf("\nTLB:\n");
941 qemu_printf("Effective Physical Size PID Prot "
944 entry
= &env
->tlb
.tlbe
[0];
945 for (i
= 0; i
< env
->nb_tlb
; i
++, entry
++) {
948 uint64_t size
= (uint64_t)entry
->size
;
951 /* Check valid flag */
952 if (!(entry
->prot
& PAGE_VALID
)) {
956 mask
= ~(entry
->size
- 1);
957 ea
= entry
->EPN
& mask
;
958 pa
= entry
->RPN
& mask
;
959 /* Extend the physical address to 36 bits */
960 pa
|= (hwaddr
)(entry
->RPN
& 0xF) << 32;
961 if (size
>= 1 * MiB
) {
962 snprintf(size_buf
, sizeof(size_buf
), "%3" PRId64
"M", size
/ MiB
);
964 snprintf(size_buf
, sizeof(size_buf
), "%3" PRId64
"k", size
/ KiB
);
966 qemu_printf("0x%016" PRIx64
" 0x%016" PRIx64
" %s %-5u %08x %08x\n",
967 (uint64_t)ea
, (uint64_t)pa
, size_buf
, (uint32_t)entry
->PID
,
968 entry
->prot
, entry
->attr
);
973 static void mmubooke206_dump_one_tlb(CPUPPCState
*env
, int tlbn
, int offset
,
979 qemu_printf("\nTLB%d:\n", tlbn
);
980 qemu_printf("Effective Physical Size TID TS SRWX"
981 " URWX WIMGE U0123\n");
983 entry
= &env
->tlb
.tlbm
[offset
];
984 for (i
= 0; i
< tlbsize
; i
++, entry
++) {
988 if (!(entry
->mas1
& MAS1_VALID
)) {
992 tsize
= (entry
->mas1
& MAS1_TSIZE_MASK
) >> MAS1_TSIZE_SHIFT
;
993 size
= 1024ULL << tsize
;
994 ea
= entry
->mas2
& ~(size
- 1);
995 pa
= entry
->mas7_3
& ~(size
- 1);
997 qemu_printf("0x%016" PRIx64
" 0x%016" PRIx64
" %4s %-5u %1u S%c%c%c"
998 "U%c%c%c %c%c%c%c%c U%c%c%c%c\n",
999 (uint64_t)ea
, (uint64_t)pa
,
1000 book3e_tsize_to_str
[tsize
],
1001 (entry
->mas1
& MAS1_TID_MASK
) >> MAS1_TID_SHIFT
,
1002 (entry
->mas1
& MAS1_TS
) >> MAS1_TS_SHIFT
,
1003 entry
->mas7_3
& MAS3_SR
? 'R' : '-',
1004 entry
->mas7_3
& MAS3_SW
? 'W' : '-',
1005 entry
->mas7_3
& MAS3_SX
? 'X' : '-',
1006 entry
->mas7_3
& MAS3_UR
? 'R' : '-',
1007 entry
->mas7_3
& MAS3_UW
? 'W' : '-',
1008 entry
->mas7_3
& MAS3_UX
? 'X' : '-',
1009 entry
->mas2
& MAS2_W
? 'W' : '-',
1010 entry
->mas2
& MAS2_I
? 'I' : '-',
1011 entry
->mas2
& MAS2_M
? 'M' : '-',
1012 entry
->mas2
& MAS2_G
? 'G' : '-',
1013 entry
->mas2
& MAS2_E
? 'E' : '-',
1014 entry
->mas7_3
& MAS3_U0
? '0' : '-',
1015 entry
->mas7_3
& MAS3_U1
? '1' : '-',
1016 entry
->mas7_3
& MAS3_U2
? '2' : '-',
1017 entry
->mas7_3
& MAS3_U3
? '3' : '-');
1021 static void mmubooke206_dump_mmu(CPUPPCState
*env
)
1026 if (kvm_enabled() && !env
->kvm_sw_tlb
) {
1027 qemu_printf("Cannot access KVM TLB\n");
1031 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1032 int size
= booke206_tlb_size(env
, i
);
1038 mmubooke206_dump_one_tlb(env
, i
, offset
, size
);
1043 static void mmu6xx_dump_BATs(CPUPPCState
*env
, int type
)
1045 target_ulong
*BATlt
, *BATut
, *BATu
, *BATl
;
1046 target_ulong BEPIl
, BEPIu
, bl
;
1051 BATlt
= env
->IBAT
[1];
1052 BATut
= env
->IBAT
[0];
1055 BATlt
= env
->DBAT
[1];
1056 BATut
= env
->DBAT
[0];
1060 for (i
= 0; i
< env
->nb_BATs
; i
++) {
1063 BEPIu
= *BATu
& 0xF0000000;
1064 BEPIl
= *BATu
& 0x0FFE0000;
1065 bl
= (*BATu
& 0x00001FFC) << 15;
1066 qemu_printf("%s BAT%d BATu " TARGET_FMT_lx
1067 " BATl " TARGET_FMT_lx
"\n\t" TARGET_FMT_lx
" "
1068 TARGET_FMT_lx
" " TARGET_FMT_lx
"\n",
1069 type
== ACCESS_CODE
? "code" : "data", i
,
1070 *BATu
, *BATl
, BEPIu
, BEPIl
, bl
);
1074 static void mmu6xx_dump_mmu(CPUPPCState
*env
)
1076 PowerPCCPU
*cpu
= env_archcpu(env
);
1079 int type
, way
, entry
, i
;
1081 qemu_printf("HTAB base = 0x%"HWADDR_PRIx
"\n", ppc_hash32_hpt_base(cpu
));
1082 qemu_printf("HTAB mask = 0x%"HWADDR_PRIx
"\n", ppc_hash32_hpt_mask(cpu
));
1084 qemu_printf("\nSegment registers:\n");
1085 for (i
= 0; i
< 32; i
++) {
1087 if (sr
& 0x80000000) {
1088 qemu_printf("%02d T=%d Ks=%d Kp=%d BUID=0x%03x "
1089 "CNTLR_SPEC=0x%05x\n", i
,
1090 sr
& 0x80000000 ? 1 : 0, sr
& 0x40000000 ? 1 : 0,
1091 sr
& 0x20000000 ? 1 : 0, (uint32_t)((sr
>> 20) & 0x1FF),
1092 (uint32_t)(sr
& 0xFFFFF));
1094 qemu_printf("%02d T=%d Ks=%d Kp=%d N=%d VSID=0x%06x\n", i
,
1095 sr
& 0x80000000 ? 1 : 0, sr
& 0x40000000 ? 1 : 0,
1096 sr
& 0x20000000 ? 1 : 0, sr
& 0x10000000 ? 1 : 0,
1097 (uint32_t)(sr
& 0x00FFFFFF));
1101 qemu_printf("\nBATs:\n");
1102 mmu6xx_dump_BATs(env
, ACCESS_INT
);
1103 mmu6xx_dump_BATs(env
, ACCESS_CODE
);
1105 if (env
->id_tlbs
!= 1) {
1106 qemu_printf("ERROR: 6xx MMU should have separated TLB"
1107 " for code and data\n");
1110 qemu_printf("\nTLBs [EPN EPN + SIZE]\n");
1112 for (type
= 0; type
< 2; type
++) {
1113 for (way
= 0; way
< env
->nb_ways
; way
++) {
1114 for (entry
= env
->nb_tlb
* type
+ env
->tlb_per_way
* way
;
1115 entry
< (env
->nb_tlb
* type
+ env
->tlb_per_way
* (way
+ 1));
1118 tlb
= &env
->tlb
.tlb6
[entry
];
1119 qemu_printf("%s TLB %02d/%02d way:%d %s ["
1120 TARGET_FMT_lx
" " TARGET_FMT_lx
"]\n",
1121 type
? "code" : "data", entry
% env
->nb_tlb
,
1123 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
1124 tlb
->EPN
, tlb
->EPN
+ TARGET_PAGE_SIZE
);
1130 void dump_mmu(CPUPPCState
*env
)
1132 switch (env
->mmu_model
) {
1133 case POWERPC_MMU_BOOKE
:
1134 mmubooke_dump_mmu(env
);
1136 case POWERPC_MMU_BOOKE206
:
1137 mmubooke206_dump_mmu(env
);
1139 case POWERPC_MMU_SOFT_6xx
:
1140 mmu6xx_dump_mmu(env
);
1142 #if defined(TARGET_PPC64)
1143 case POWERPC_MMU_64B
:
1144 case POWERPC_MMU_2_03
:
1145 case POWERPC_MMU_2_06
:
1146 case POWERPC_MMU_2_07
:
1147 dump_slb(env_archcpu(env
));
1149 case POWERPC_MMU_3_00
:
1150 if (ppc64_v3_radix(env_archcpu(env
))) {
1151 qemu_log_mask(LOG_UNIMP
, "%s: the PPC64 MMU is unsupported\n",
1154 dump_slb(env_archcpu(env
));
1159 qemu_log_mask(LOG_UNIMP
, "%s: unimplemented\n", __func__
);
1163 static int check_physical(CPUPPCState
*env
, mmu_ctx_t
*ctx
, target_ulong eaddr
,
1164 MMUAccessType access_type
)
1167 ctx
->prot
= PAGE_READ
| PAGE_EXEC
;
1169 switch (env
->mmu_model
) {
1170 case POWERPC_MMU_SOFT_6xx
:
1171 case POWERPC_MMU_SOFT_4xx
:
1172 case POWERPC_MMU_REAL
:
1173 case POWERPC_MMU_BOOKE
:
1174 ctx
->prot
|= PAGE_WRITE
;
1178 /* Caller's checks mean we should never get here for other models */
1179 g_assert_not_reached();
1185 int get_physical_address_wtlb(CPUPPCState
*env
, mmu_ctx_t
*ctx
,
1187 MMUAccessType access_type
, int type
,
1191 bool real_mode
= (type
== ACCESS_CODE
&& msr_ir
== 0)
1192 || (type
!= ACCESS_CODE
&& msr_dr
== 0);
1194 switch (env
->mmu_model
) {
1195 case POWERPC_MMU_SOFT_6xx
:
1197 ret
= check_physical(env
, ctx
, eaddr
, access_type
);
1199 /* Try to find a BAT */
1200 if (env
->nb_BATs
!= 0) {
1201 ret
= get_bat_6xx_tlb(env
, ctx
, eaddr
, access_type
);
1204 /* We didn't match any BAT entry or don't have BATs */
1205 ret
= get_segment_6xx_tlb(env
, ctx
, eaddr
, access_type
, type
);
1210 case POWERPC_MMU_SOFT_4xx
:
1212 ret
= check_physical(env
, ctx
, eaddr
, access_type
);
1214 ret
= mmu40x_get_physical_address(env
, ctx
, eaddr
, access_type
);
1217 case POWERPC_MMU_BOOKE
:
1218 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
, access_type
);
1220 case POWERPC_MMU_BOOKE206
:
1221 ret
= mmubooke206_get_physical_address(env
, ctx
, eaddr
, access_type
,
1224 case POWERPC_MMU_MPC8xx
:
1226 cpu_abort(env_cpu(env
), "MPC8xx MMU model is not implemented\n");
1228 case POWERPC_MMU_REAL
:
1230 ret
= check_physical(env
, ctx
, eaddr
, access_type
);
1232 cpu_abort(env_cpu(env
),
1233 "PowerPC in real mode do not do any translation\n");
1237 cpu_abort(env_cpu(env
), "Unknown or invalid MMU model\n");
1244 static void booke206_update_mas_tlb_miss(CPUPPCState
*env
, target_ulong address
,
1245 MMUAccessType access_type
, int mmu_idx
)
1249 uint32_t missed_tid
= 0;
1250 bool use_epid
= mmubooke206_get_as(env
, mmu_idx
, &epid
, &as
, &pr
);
1252 if (access_type
== MMU_INST_FETCH
) {
1255 env
->spr
[SPR_BOOKE_MAS0
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TLBSELD_MASK
;
1256 env
->spr
[SPR_BOOKE_MAS1
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TSIZED_MASK
;
1257 env
->spr
[SPR_BOOKE_MAS2
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_WIMGED_MASK
;
1258 env
->spr
[SPR_BOOKE_MAS3
] = 0;
1259 env
->spr
[SPR_BOOKE_MAS6
] = 0;
1260 env
->spr
[SPR_BOOKE_MAS7
] = 0;
1264 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_TS
;
1265 env
->spr
[SPR_BOOKE_MAS6
] |= MAS6_SAS
;
1268 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_VALID
;
1269 env
->spr
[SPR_BOOKE_MAS2
] |= address
& MAS2_EPN_MASK
;
1272 switch (env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TIDSELD_PIDZ
) {
1273 case MAS4_TIDSELD_PID0
:
1274 missed_tid
= env
->spr
[SPR_BOOKE_PID
];
1276 case MAS4_TIDSELD_PID1
:
1277 missed_tid
= env
->spr
[SPR_BOOKE_PID1
];
1279 case MAS4_TIDSELD_PID2
:
1280 missed_tid
= env
->spr
[SPR_BOOKE_PID2
];
1283 env
->spr
[SPR_BOOKE_MAS6
] |= env
->spr
[SPR_BOOKE_PID
] << 16;
1286 env
->spr
[SPR_BOOKE_MAS6
] |= missed_tid
<< 16;
1288 env
->spr
[SPR_BOOKE_MAS1
] |= (missed_tid
<< MAS1_TID_SHIFT
);
1291 /* next victim logic */
1292 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_ESEL_SHIFT
;
1294 env
->last_way
&= booke206_tlb_ways(env
, 0) - 1;
1295 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_NV_SHIFT
;
1298 /* Perform address translation */
1299 /* TODO: Split this by mmu_model. */
1300 static bool ppc_jumbo_xlate(PowerPCCPU
*cpu
, vaddr eaddr
,
1301 MMUAccessType access_type
,
1302 hwaddr
*raddrp
, int *psizep
, int *protp
,
1303 int mmu_idx
, bool guest_visible
)
1305 CPUState
*cs
= CPU(cpu
);
1306 CPUPPCState
*env
= &cpu
->env
;
1311 if (access_type
== MMU_INST_FETCH
) {
1314 } else if (guest_visible
) {
1316 type
= env
->access_type
;
1321 ret
= get_physical_address_wtlb(env
, &ctx
, eaddr
, access_type
,
1324 *raddrp
= ctx
.raddr
;
1326 *psizep
= TARGET_PAGE_BITS
;
1330 if (guest_visible
) {
1331 log_cpu_state_mask(CPU_LOG_MMU
, cs
, 0);
1332 if (type
== ACCESS_CODE
) {
1335 /* No matches in page tables or TLB */
1336 switch (env
->mmu_model
) {
1337 case POWERPC_MMU_SOFT_6xx
:
1338 cs
->exception_index
= POWERPC_EXCP_IFTLB
;
1339 env
->error_code
= 1 << 18;
1340 env
->spr
[SPR_IMISS
] = eaddr
;
1341 env
->spr
[SPR_ICMP
] = 0x80000000 | ctx
.ptem
;
1343 case POWERPC_MMU_SOFT_4xx
:
1344 cs
->exception_index
= POWERPC_EXCP_ITLB
;
1345 env
->error_code
= 0;
1346 env
->spr
[SPR_40x_DEAR
] = eaddr
;
1347 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1349 case POWERPC_MMU_BOOKE206
:
1350 booke206_update_mas_tlb_miss(env
, eaddr
, 2, mmu_idx
);
1352 case POWERPC_MMU_BOOKE
:
1353 cs
->exception_index
= POWERPC_EXCP_ITLB
;
1354 env
->error_code
= 0;
1355 env
->spr
[SPR_BOOKE_DEAR
] = eaddr
;
1356 env
->spr
[SPR_BOOKE_ESR
] = mmubooke206_esr(mmu_idx
, MMU_DATA_LOAD
);
1358 case POWERPC_MMU_MPC8xx
:
1359 cpu_abort(cs
, "MPC8xx MMU model is not implemented\n");
1360 case POWERPC_MMU_REAL
:
1361 cpu_abort(cs
, "PowerPC in real mode should never raise "
1362 "any MMU exceptions\n");
1364 cpu_abort(cs
, "Unknown or invalid MMU model\n");
1368 /* Access rights violation */
1369 cs
->exception_index
= POWERPC_EXCP_ISI
;
1370 env
->error_code
= 0x08000000;
1373 /* No execute protection violation */
1374 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1375 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1376 env
->spr
[SPR_BOOKE_ESR
] = 0x00000000;
1378 cs
->exception_index
= POWERPC_EXCP_ISI
;
1379 env
->error_code
= 0x10000000;
1382 /* Direct store exception */
1383 /* No code fetch is allowed in direct-store areas */
1384 cs
->exception_index
= POWERPC_EXCP_ISI
;
1385 env
->error_code
= 0x10000000;
1391 /* No matches in page tables or TLB */
1392 switch (env
->mmu_model
) {
1393 case POWERPC_MMU_SOFT_6xx
:
1394 if (access_type
== MMU_DATA_STORE
) {
1395 cs
->exception_index
= POWERPC_EXCP_DSTLB
;
1396 env
->error_code
= 1 << 16;
1398 cs
->exception_index
= POWERPC_EXCP_DLTLB
;
1399 env
->error_code
= 0;
1401 env
->spr
[SPR_DMISS
] = eaddr
;
1402 env
->spr
[SPR_DCMP
] = 0x80000000 | ctx
.ptem
;
1404 env
->error_code
|= ctx
.key
<< 19;
1405 env
->spr
[SPR_HASH1
] = ppc_hash32_hpt_base(cpu
) +
1406 get_pteg_offset32(cpu
, ctx
.hash
[0]);
1407 env
->spr
[SPR_HASH2
] = ppc_hash32_hpt_base(cpu
) +
1408 get_pteg_offset32(cpu
, ctx
.hash
[1]);
1410 case POWERPC_MMU_SOFT_4xx
:
1411 cs
->exception_index
= POWERPC_EXCP_DTLB
;
1412 env
->error_code
= 0;
1413 env
->spr
[SPR_40x_DEAR
] = eaddr
;
1414 if (access_type
== MMU_DATA_STORE
) {
1415 env
->spr
[SPR_40x_ESR
] = 0x00800000;
1417 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1420 case POWERPC_MMU_MPC8xx
:
1422 cpu_abort(cs
, "MPC8xx MMU model is not implemented\n");
1423 case POWERPC_MMU_BOOKE206
:
1424 booke206_update_mas_tlb_miss(env
, eaddr
, access_type
, mmu_idx
);
1426 case POWERPC_MMU_BOOKE
:
1427 cs
->exception_index
= POWERPC_EXCP_DTLB
;
1428 env
->error_code
= 0;
1429 env
->spr
[SPR_BOOKE_DEAR
] = eaddr
;
1430 env
->spr
[SPR_BOOKE_ESR
] = mmubooke206_esr(mmu_idx
, access_type
);
1432 case POWERPC_MMU_REAL
:
1433 cpu_abort(cs
, "PowerPC in real mode should never raise "
1434 "any MMU exceptions\n");
1436 cpu_abort(cs
, "Unknown or invalid MMU model\n");
1440 /* Access rights violation */
1441 cs
->exception_index
= POWERPC_EXCP_DSI
;
1442 env
->error_code
= 0;
1443 if (env
->mmu_model
== POWERPC_MMU_SOFT_4xx
) {
1444 env
->spr
[SPR_40x_DEAR
] = eaddr
;
1445 if (access_type
== MMU_DATA_STORE
) {
1446 env
->spr
[SPR_40x_ESR
] |= 0x00800000;
1448 } else if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1449 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1450 env
->spr
[SPR_BOOKE_DEAR
] = eaddr
;
1451 env
->spr
[SPR_BOOKE_ESR
] = mmubooke206_esr(mmu_idx
, access_type
);
1453 env
->spr
[SPR_DAR
] = eaddr
;
1454 if (access_type
== MMU_DATA_STORE
) {
1455 env
->spr
[SPR_DSISR
] = 0x0A000000;
1457 env
->spr
[SPR_DSISR
] = 0x08000000;
1462 /* Direct store exception */
1465 /* Floating point load/store */
1466 cs
->exception_index
= POWERPC_EXCP_ALIGN
;
1467 env
->error_code
= POWERPC_EXCP_ALIGN_FP
;
1468 env
->spr
[SPR_DAR
] = eaddr
;
1471 /* lwarx, ldarx or stwcx. */
1472 cs
->exception_index
= POWERPC_EXCP_DSI
;
1473 env
->error_code
= 0;
1474 env
->spr
[SPR_DAR
] = eaddr
;
1475 if (access_type
== MMU_DATA_STORE
) {
1476 env
->spr
[SPR_DSISR
] = 0x06000000;
1478 env
->spr
[SPR_DSISR
] = 0x04000000;
1482 /* eciwx or ecowx */
1483 cs
->exception_index
= POWERPC_EXCP_DSI
;
1484 env
->error_code
= 0;
1485 env
->spr
[SPR_DAR
] = eaddr
;
1486 if (access_type
== MMU_DATA_STORE
) {
1487 env
->spr
[SPR_DSISR
] = 0x06100000;
1489 env
->spr
[SPR_DSISR
] = 0x04100000;
1493 printf("DSI: invalid exception (%d)\n", ret
);
1494 cs
->exception_index
= POWERPC_EXCP_PROGRAM
;
1496 POWERPC_EXCP_INVAL
| POWERPC_EXCP_INVAL_INVAL
;
1497 env
->spr
[SPR_DAR
] = eaddr
;
1507 /*****************************************************************************/
1509 bool ppc_xlate(PowerPCCPU
*cpu
, vaddr eaddr
, MMUAccessType access_type
,
1510 hwaddr
*raddrp
, int *psizep
, int *protp
,
1511 int mmu_idx
, bool guest_visible
)
1513 switch (cpu
->env
.mmu_model
) {
1514 #if defined(TARGET_PPC64)
1515 case POWERPC_MMU_3_00
:
1516 if (ppc64_v3_radix(cpu
)) {
1517 return ppc_radix64_xlate(cpu
, eaddr
, access_type
, raddrp
,
1518 psizep
, protp
, mmu_idx
, guest_visible
);
1521 case POWERPC_MMU_64B
:
1522 case POWERPC_MMU_2_03
:
1523 case POWERPC_MMU_2_06
:
1524 case POWERPC_MMU_2_07
:
1525 return ppc_hash64_xlate(cpu
, eaddr
, access_type
,
1526 raddrp
, psizep
, protp
, mmu_idx
, guest_visible
);
1529 case POWERPC_MMU_32B
:
1530 case POWERPC_MMU_601
:
1531 return ppc_hash32_xlate(cpu
, eaddr
, access_type
, raddrp
,
1532 psizep
, protp
, mmu_idx
, guest_visible
);
1535 return ppc_jumbo_xlate(cpu
, eaddr
, access_type
, raddrp
,
1536 psizep
, protp
, mmu_idx
, guest_visible
);
1540 hwaddr
ppc_cpu_get_phys_page_debug(CPUState
*cs
, vaddr addr
)
1542 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
1547 * Some MMUs have separate TLBs for code and data. If we only
1548 * try an MMU_DATA_LOAD, we may not be able to read instructions
1549 * mapped by code TLBs, so we also try a MMU_INST_FETCH.
1551 if (ppc_xlate(cpu
, addr
, MMU_DATA_LOAD
, &raddr
, &s
, &p
,
1552 cpu_mmu_index(&cpu
->env
, false), false) ||
1553 ppc_xlate(cpu
, addr
, MMU_INST_FETCH
, &raddr
, &s
, &p
,
1554 cpu_mmu_index(&cpu
->env
, true), false)) {
1555 return raddr
& TARGET_PAGE_MASK
;