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/qemu-print.h"
33 #include "mmu-book3s-v3.h"
34 #include "mmu-radix64.h"
36 /* #define DUMP_PAGE_TABLES */
38 void ppc_store_sdr1(CPUPPCState
*env
, target_ulong value
)
40 PowerPCCPU
*cpu
= env_archcpu(env
);
41 qemu_log_mask(CPU_LOG_MMU
, "%s: " TARGET_FMT_lx
"\n", __func__
, value
);
42 assert(!cpu
->env
.has_hv_mode
|| !cpu
->vhyp
);
43 #if defined(TARGET_PPC64)
44 if (mmu_is_64bit(env
->mmu_model
)) {
45 target_ulong sdr_mask
= SDR_64_HTABORG
| SDR_64_HTABSIZE
;
46 target_ulong htabsize
= value
& SDR_64_HTABSIZE
;
48 if (value
& ~sdr_mask
) {
49 qemu_log_mask(LOG_GUEST_ERROR
, "Invalid bits 0x"TARGET_FMT_lx
50 " set in SDR1", value
& ~sdr_mask
);
54 qemu_log_mask(LOG_GUEST_ERROR
, "Invalid HTABSIZE 0x" TARGET_FMT_lx
55 " stored in SDR1", htabsize
);
59 #endif /* defined(TARGET_PPC64) */
60 /* FIXME: Should check for valid HTABMASK values in 32-bit case */
61 env
->spr
[SPR_SDR1
] = value
;
64 /*****************************************************************************/
65 /* PowerPC MMU emulation */
67 static int pp_check(int key
, int pp
, int nx
)
71 /* Compute access rights */
94 access
= PAGE_READ
| PAGE_WRITE
;
105 static int check_prot(int prot
, MMUAccessType access_type
)
107 return prot
& prot_for_access_type(access_type
) ? 0 : -2;
110 int ppc6xx_tlb_getnum(CPUPPCState
*env
, target_ulong eaddr
,
111 int way
, int is_code
)
115 /* Select TLB num in a way from address */
116 nr
= (eaddr
>> TARGET_PAGE_BITS
) & (env
->tlb_per_way
- 1);
118 nr
+= env
->tlb_per_way
* way
;
119 /* 6xx have separate TLBs for instructions and data */
120 if (is_code
&& env
->id_tlbs
== 1) {
127 static int ppc6xx_tlb_pte_check(mmu_ctx_t
*ctx
, target_ulong pte0
,
128 target_ulong pte1
, int h
,
129 MMUAccessType access_type
)
131 target_ulong ptem
, mmask
;
132 int access
, ret
, pteh
, ptev
, pp
;
135 /* Check validity and table match */
136 ptev
= pte_is_valid(pte0
);
137 pteh
= (pte0
>> 6) & 1;
138 if (ptev
&& h
== pteh
) {
139 /* Check vsid & api */
140 ptem
= pte0
& PTE_PTEM_MASK
;
141 mmask
= PTE_CHECK_MASK
;
142 pp
= pte1
& 0x00000003;
143 if (ptem
== ctx
->ptem
) {
144 if (ctx
->raddr
!= (hwaddr
)-1ULL) {
145 /* all matches should have equal RPN, WIMG & PP */
146 if ((ctx
->raddr
& mmask
) != (pte1
& mmask
)) {
147 qemu_log_mask(CPU_LOG_MMU
, "Bad RPN/WIMG/PP\n");
151 /* Compute access rights */
152 access
= pp_check(ctx
->key
, pp
, ctx
->nx
);
153 /* Keep the matching PTE information */
156 ret
= check_prot(ctx
->prot
, access_type
);
159 qemu_log_mask(CPU_LOG_MMU
, "PTE access granted !\n");
161 /* Access right violation */
162 qemu_log_mask(CPU_LOG_MMU
, "PTE access rejected\n");
170 static int pte_update_flags(mmu_ctx_t
*ctx
, target_ulong
*pte1p
,
171 int ret
, MMUAccessType access_type
)
175 /* Update page flags */
176 if (!(*pte1p
& 0x00000100)) {
177 /* Update accessed flag */
178 *pte1p
|= 0x00000100;
181 if (!(*pte1p
& 0x00000080)) {
182 if (access_type
== MMU_DATA_STORE
&& ret
== 0) {
183 /* Update changed flag */
184 *pte1p
|= 0x00000080;
187 /* Force page fault for first write access */
188 ctx
->prot
&= ~PAGE_WRITE
;
195 /* Software driven TLB helpers */
197 static int ppc6xx_tlb_check(CPUPPCState
*env
, mmu_ctx_t
*ctx
,
198 target_ulong eaddr
, MMUAccessType access_type
)
205 ret
= -1; /* No TLB found */
206 for (way
= 0; way
< env
->nb_ways
; way
++) {
207 nr
= ppc6xx_tlb_getnum(env
, eaddr
, way
, access_type
== MMU_INST_FETCH
);
208 tlb
= &env
->tlb
.tlb6
[nr
];
209 /* This test "emulates" the PTE index match for hardware TLBs */
210 if ((eaddr
& TARGET_PAGE_MASK
) != tlb
->EPN
) {
211 qemu_log_mask(CPU_LOG_MMU
, "TLB %d/%d %s [" TARGET_FMT_lx
212 " " TARGET_FMT_lx
"] <> " TARGET_FMT_lx
"\n",
214 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
215 tlb
->EPN
, tlb
->EPN
+ TARGET_PAGE_SIZE
, eaddr
);
218 qemu_log_mask(CPU_LOG_MMU
, "TLB %d/%d %s " TARGET_FMT_lx
" <> "
219 TARGET_FMT_lx
" " TARGET_FMT_lx
" %c %c\n",
221 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
222 tlb
->EPN
, eaddr
, tlb
->pte1
,
223 access_type
== MMU_DATA_STORE
? 'S' : 'L',
224 access_type
== MMU_INST_FETCH
? 'I' : 'D');
225 switch (ppc6xx_tlb_pte_check(ctx
, tlb
->pte0
, tlb
->pte1
,
228 /* TLB inconsistency */
231 /* Access violation */
242 * XXX: we should go on looping to check all TLBs
243 * consistency but we can speed-up the whole thing as
244 * the result would be undefined if TLBs are not
254 qemu_log_mask(CPU_LOG_MMU
, "found TLB at addr " HWADDR_FMT_plx
255 " prot=%01x ret=%d\n",
256 ctx
->raddr
& TARGET_PAGE_MASK
, ctx
->prot
, ret
);
257 /* Update page flags */
258 pte_update_flags(ctx
, &env
->tlb
.tlb6
[best
].pte1
, ret
, access_type
);
264 /* Perform BAT hit & translation */
265 static inline void bat_size_prot(CPUPPCState
*env
, target_ulong
*blp
,
266 int *validp
, int *protp
, target_ulong
*BATu
,
272 bl
= (*BATu
& 0x00001FFC) << 15;
275 if ((!FIELD_EX64(env
->msr
, MSR
, PR
) && (*BATu
& 0x00000002)) ||
276 (FIELD_EX64(env
->msr
, MSR
, PR
) && (*BATu
& 0x00000001))) {
278 pp
= *BATl
& 0x00000003;
280 prot
= PAGE_READ
| PAGE_EXEC
;
291 static int get_bat_6xx_tlb(CPUPPCState
*env
, mmu_ctx_t
*ctx
,
292 target_ulong
virtual, MMUAccessType access_type
)
294 target_ulong
*BATlt
, *BATut
, *BATu
, *BATl
;
295 target_ulong BEPIl
, BEPIu
, bl
;
298 bool ifetch
= access_type
== MMU_INST_FETCH
;
300 qemu_log_mask(CPU_LOG_MMU
, "%s: %cBAT v " TARGET_FMT_lx
"\n", __func__
,
301 ifetch
? 'I' : 'D', virtual);
303 BATlt
= env
->IBAT
[1];
304 BATut
= env
->IBAT
[0];
306 BATlt
= env
->DBAT
[1];
307 BATut
= env
->DBAT
[0];
309 for (i
= 0; i
< env
->nb_BATs
; i
++) {
312 BEPIu
= *BATu
& 0xF0000000;
313 BEPIl
= *BATu
& 0x0FFE0000;
314 bat_size_prot(env
, &bl
, &valid
, &prot
, BATu
, BATl
);
315 qemu_log_mask(CPU_LOG_MMU
, "%s: %cBAT%d v " TARGET_FMT_lx
" BATu "
316 TARGET_FMT_lx
" BATl " TARGET_FMT_lx
"\n", __func__
,
317 ifetch
? 'I' : 'D', i
, virtual, *BATu
, *BATl
);
318 if ((virtual & 0xF0000000) == BEPIu
&&
319 ((virtual & 0x0FFE0000) & ~bl
) == BEPIl
) {
322 /* Get physical address */
323 ctx
->raddr
= (*BATl
& 0xF0000000) |
324 ((virtual & 0x0FFE0000 & bl
) | (*BATl
& 0x0FFE0000)) |
325 (virtual & 0x0001F000);
326 /* Compute access rights */
328 ret
= check_prot(ctx
->prot
, access_type
);
330 qemu_log_mask(CPU_LOG_MMU
, "BAT %d match: r " HWADDR_FMT_plx
331 " prot=%c%c\n", i
, ctx
->raddr
,
332 ctx
->prot
& PAGE_READ
? 'R' : '-',
333 ctx
->prot
& PAGE_WRITE
? 'W' : '-');
340 if (qemu_log_enabled()) {
341 qemu_log_mask(CPU_LOG_MMU
, "no BAT match for "
342 TARGET_FMT_lx
":\n", virtual);
343 for (i
= 0; i
< 4; i
++) {
346 BEPIu
= *BATu
& 0xF0000000;
347 BEPIl
= *BATu
& 0x0FFE0000;
348 bl
= (*BATu
& 0x00001FFC) << 15;
349 qemu_log_mask(CPU_LOG_MMU
, "%s: %cBAT%d v "
350 TARGET_FMT_lx
" BATu " TARGET_FMT_lx
351 " BATl " TARGET_FMT_lx
"\n\t" TARGET_FMT_lx
" "
352 TARGET_FMT_lx
" " TARGET_FMT_lx
"\n",
353 __func__
, ifetch
? 'I' : 'D', i
, virtual,
354 *BATu
, *BATl
, BEPIu
, BEPIl
, bl
);
362 /* Perform segment based translation */
363 static int get_segment_6xx_tlb(CPUPPCState
*env
, mmu_ctx_t
*ctx
,
364 target_ulong eaddr
, MMUAccessType access_type
,
367 PowerPCCPU
*cpu
= env_archcpu(env
);
370 int ds
, target_page_bits
;
373 target_ulong sr
, pgidx
;
375 pr
= FIELD_EX64(env
->msr
, MSR
, PR
);
378 sr
= env
->sr
[eaddr
>> 28];
379 ctx
->key
= (((sr
& 0x20000000) && pr
) ||
380 ((sr
& 0x40000000) && !pr
)) ? 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
,
390 (int)FIELD_EX64(env
->msr
, MSR
, IR
),
391 (int)FIELD_EX64(env
->msr
, MSR
, DR
), pr
? 1 : 0,
392 access_type
== MMU_DATA_STORE
, type
);
393 pgidx
= (eaddr
& ~SEGMENT_MASK_256M
) >> target_page_bits
;
395 ctx
->ptem
= (vsid
<< 7) | (pgidx
>> 10);
397 qemu_log_mask(CPU_LOG_MMU
,
398 "pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx
"\n",
399 ctx
->key
, ds
, ctx
->nx
, vsid
);
402 /* Check if instruction fetch is allowed, if needed */
403 if (type
!= ACCESS_CODE
|| ctx
->nx
== 0) {
404 /* Page address translation */
405 qemu_log_mask(CPU_LOG_MMU
, "htab_base " HWADDR_FMT_plx
406 " htab_mask " HWADDR_FMT_plx
407 " hash " HWADDR_FMT_plx
"\n",
408 ppc_hash32_hpt_base(cpu
), ppc_hash32_hpt_mask(cpu
), hash
);
410 ctx
->hash
[1] = ~hash
;
412 /* Initialize real address with an invalid value */
413 ctx
->raddr
= (hwaddr
)-1ULL;
414 /* Software TLB search */
415 ret
= ppc6xx_tlb_check(env
, ctx
, eaddr
, access_type
);
416 #if defined(DUMP_PAGE_TABLES)
417 if (qemu_loglevel_mask(CPU_LOG_MMU
)) {
418 CPUState
*cs
= env_cpu(env
);
420 uint32_t a0
, a1
, a2
, a3
;
422 qemu_log("Page table: " HWADDR_FMT_plx
" len " HWADDR_FMT_plx
423 "\n", ppc_hash32_hpt_base(cpu
),
424 ppc_hash32_hpt_mask(cpu
) + 0x80);
425 for (curaddr
= ppc_hash32_hpt_base(cpu
);
426 curaddr
< (ppc_hash32_hpt_base(cpu
)
427 + ppc_hash32_hpt_mask(cpu
) + 0x80);
429 a0
= ldl_phys(cs
->as
, curaddr
);
430 a1
= ldl_phys(cs
->as
, curaddr
+ 4);
431 a2
= ldl_phys(cs
->as
, curaddr
+ 8);
432 a3
= ldl_phys(cs
->as
, curaddr
+ 12);
433 if (a0
!= 0 || a1
!= 0 || a2
!= 0 || a3
!= 0) {
434 qemu_log(HWADDR_FMT_plx
": %08x %08x %08x %08x\n",
435 curaddr
, a0
, a1
, a2
, a3
);
441 qemu_log_mask(CPU_LOG_MMU
, "No access allowed\n");
445 qemu_log_mask(CPU_LOG_MMU
, "direct store...\n");
446 /* Direct-store segment : absolutely *BUGGY* for now */
450 /* Integer load/store : only access allowed */
453 /* No code fetch is allowed in direct-store areas */
456 /* Floating point load/store */
459 /* lwarx, ldarx or srwcx. */
463 * dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi
465 * Should make the instruction do no-op. As it already do
466 * no-op, it's quite easy :-)
474 qemu_log_mask(CPU_LOG_MMU
, "ERROR: instruction should not need "
475 "address translation\n");
478 if ((access_type
== MMU_DATA_STORE
|| ctx
->key
!= 1) &&
479 (access_type
== MMU_DATA_LOAD
|| ctx
->key
!= 0)) {
490 /* Generic TLB check function for embedded PowerPC implementations */
491 static bool ppcemb_tlb_check(CPUPPCState
*env
, ppcemb_tlb_t
*tlb
,
493 target_ulong address
, uint32_t pid
, int i
)
497 /* Check valid flag */
498 if (!(tlb
->prot
& PAGE_VALID
)) {
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
);
507 if (tlb
->PID
!= 0 && tlb
->PID
!= pid
) {
510 /* Check effective address */
511 if ((address
& mask
) != tlb
->EPN
) {
514 *raddrp
= (tlb
->RPN
& mask
) | (address
& ~mask
);
518 /* Generic TLB search function for PowerPC embedded implementations */
519 int ppcemb_tlb_search(CPUPPCState
*env
, target_ulong address
, uint32_t pid
)
525 for (i
= 0; i
< env
->nb_tlb
; i
++) {
526 tlb
= &env
->tlb
.tlbe
[i
];
527 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
, pid
, i
)) {
534 static int mmu40x_get_physical_address(CPUPPCState
*env
, mmu_ctx_t
*ctx
,
535 target_ulong address
,
536 MMUAccessType access_type
)
540 int i
, ret
, zsel
, zpr
, pr
;
543 raddr
= (hwaddr
)-1ULL;
544 pr
= FIELD_EX64(env
->msr
, MSR
, PR
);
545 for (i
= 0; i
< env
->nb_tlb
; i
++) {
546 tlb
= &env
->tlb
.tlbe
[i
];
547 if (!ppcemb_tlb_check(env
, tlb
, &raddr
, address
,
548 env
->spr
[SPR_40x_PID
], i
)) {
551 zsel
= (tlb
->attr
>> 4) & 0xF;
552 zpr
= (env
->spr
[SPR_40x_ZPR
] >> (30 - (2 * zsel
))) & 0x3;
553 qemu_log_mask(CPU_LOG_MMU
,
554 "%s: TLB %d zsel %d zpr %d ty %d attr %08x\n",
555 __func__
, i
, zsel
, zpr
, access_type
, tlb
->attr
);
556 /* Check execute enable bit */
564 /* All accesses granted */
565 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
570 /* Raise Zone protection fault. */
571 env
->spr
[SPR_40x_ESR
] = 1 << 22;
579 /* Check from TLB entry */
580 ctx
->prot
= tlb
->prot
;
581 ret
= check_prot(ctx
->prot
, access_type
);
583 env
->spr
[SPR_40x_ESR
] = 0;
589 qemu_log_mask(CPU_LOG_MMU
, "%s: access granted " TARGET_FMT_lx
590 " => " HWADDR_FMT_plx
591 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
596 qemu_log_mask(CPU_LOG_MMU
, "%s: access refused " TARGET_FMT_lx
597 " => " HWADDR_FMT_plx
598 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
603 static bool mmubooke_check_pid(CPUPPCState
*env
, ppcemb_tlb_t
*tlb
,
604 hwaddr
*raddr
, target_ulong addr
, int i
)
606 if (ppcemb_tlb_check(env
, tlb
, raddr
, addr
, env
->spr
[SPR_BOOKE_PID
], i
)) {
608 /* Extend the physical address to 36 bits */
609 *raddr
|= (uint64_t)(tlb
->RPN
& 0xF) << 32;
612 } else if (!env
->nb_pids
) {
615 if (env
->spr
[SPR_BOOKE_PID1
] &&
616 ppcemb_tlb_check(env
, tlb
, raddr
, addr
, env
->spr
[SPR_BOOKE_PID1
], i
)) {
619 if (env
->spr
[SPR_BOOKE_PID2
] &&
620 ppcemb_tlb_check(env
, tlb
, raddr
, addr
, env
->spr
[SPR_BOOKE_PID2
], i
)) {
626 static int mmubooke_check_tlb(CPUPPCState
*env
, ppcemb_tlb_t
*tlb
,
627 hwaddr
*raddr
, int *prot
, target_ulong address
,
628 MMUAccessType access_type
, int i
)
632 if (!mmubooke_check_pid(env
, tlb
, raddr
, address
, i
)) {
633 qemu_log_mask(CPU_LOG_MMU
, "%s: TLB entry not found\n", __func__
);
637 if (FIELD_EX64(env
->msr
, MSR
, PR
)) {
638 prot2
= tlb
->prot
& 0xF;
640 prot2
= (tlb
->prot
>> 4) & 0xF;
643 /* Check the address space */
644 if ((access_type
== MMU_INST_FETCH
?
645 FIELD_EX64(env
->msr
, MSR
, IR
) :
646 FIELD_EX64(env
->msr
, MSR
, DR
)) != (tlb
->attr
& 1)) {
647 qemu_log_mask(CPU_LOG_MMU
, "%s: AS doesn't match\n", __func__
);
652 if (prot2
& prot_for_access_type(access_type
)) {
653 qemu_log_mask(CPU_LOG_MMU
, "%s: good TLB!\n", __func__
);
657 qemu_log_mask(CPU_LOG_MMU
, "%s: no prot match: %x\n", __func__
, prot2
);
658 return access_type
== MMU_INST_FETCH
? -3 : -2;
661 static int mmubooke_get_physical_address(CPUPPCState
*env
, mmu_ctx_t
*ctx
,
662 target_ulong address
,
663 MMUAccessType access_type
)
670 raddr
= (hwaddr
)-1ULL;
671 for (i
= 0; i
< env
->nb_tlb
; i
++) {
672 tlb
= &env
->tlb
.tlbe
[i
];
673 ret
= mmubooke_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
,
682 qemu_log_mask(CPU_LOG_MMU
, "%s: access granted " TARGET_FMT_lx
683 " => " HWADDR_FMT_plx
" %d %d\n", __func__
,
684 address
, ctx
->raddr
, ctx
->prot
, ret
);
686 qemu_log_mask(CPU_LOG_MMU
, "%s: access refused " TARGET_FMT_lx
687 " => " HWADDR_FMT_plx
" %d %d\n", __func__
,
688 address
, raddr
, ctx
->prot
, ret
);
694 hwaddr
booke206_tlb_to_page_size(CPUPPCState
*env
, ppcmas_tlb_t
*tlb
)
698 tlbm_size
= (tlb
->mas1
& MAS1_TSIZE_MASK
) >> MAS1_TSIZE_SHIFT
;
700 return 1024ULL << tlbm_size
;
703 /* TLB check function for MAS based SoftTLBs */
704 int ppcmas_tlb_check(CPUPPCState
*env
, ppcmas_tlb_t
*tlb
, hwaddr
*raddrp
,
705 target_ulong address
, uint32_t pid
)
710 if (!FIELD_EX64(env
->msr
, MSR
, CM
)) {
711 /* In 32bit mode we can only address 32bit EAs */
712 address
= (uint32_t)address
;
715 /* Check valid flag */
716 if (!(tlb
->mas1
& MAS1_VALID
)) {
720 mask
= ~(booke206_tlb_to_page_size(env
, tlb
) - 1);
721 qemu_log_mask(CPU_LOG_MMU
, "%s: TLB ADDR=0x" TARGET_FMT_lx
722 " PID=0x%x MAS1=0x%x MAS2=0x%" PRIx64
" mask=0x%"
723 HWADDR_PRIx
" MAS7_3=0x%" PRIx64
" MAS8=0x%" PRIx32
"\n",
724 __func__
, address
, pid
, tlb
->mas1
, tlb
->mas2
, mask
,
725 tlb
->mas7_3
, tlb
->mas8
);
728 tlb_pid
= (tlb
->mas1
& MAS1_TID_MASK
) >> MAS1_TID_SHIFT
;
729 if (tlb_pid
!= 0 && tlb_pid
!= pid
) {
733 /* Check effective address */
734 if ((address
& mask
) != (tlb
->mas2
& MAS2_EPN_MASK
)) {
739 *raddrp
= (tlb
->mas7_3
& mask
) | (address
& ~mask
);
745 static bool is_epid_mmu(int mmu_idx
)
747 return mmu_idx
== PPC_TLB_EPID_STORE
|| mmu_idx
== PPC_TLB_EPID_LOAD
;
750 static uint32_t mmubooke206_esr(int mmu_idx
, MMUAccessType access_type
)
753 if (access_type
== MMU_DATA_STORE
) {
756 if (is_epid_mmu(mmu_idx
)) {
763 * Get EPID register given the mmu_idx. If this is regular load,
764 * construct the EPID access bits from current processor state
766 * Get the effective AS and PR bits and the PID. The PID is returned
767 * only if EPID load is requested, otherwise the caller must detect
768 * the correct EPID. Return true if valid EPID is returned.
770 static bool mmubooke206_get_as(CPUPPCState
*env
,
771 int mmu_idx
, uint32_t *epid_out
,
772 bool *as_out
, bool *pr_out
)
774 if (is_epid_mmu(mmu_idx
)) {
776 if (mmu_idx
== PPC_TLB_EPID_STORE
) {
777 epidr
= env
->spr
[SPR_BOOKE_EPSC
];
779 epidr
= env
->spr
[SPR_BOOKE_EPLC
];
781 *epid_out
= (epidr
& EPID_EPID
) >> EPID_EPID_SHIFT
;
782 *as_out
= !!(epidr
& EPID_EAS
);
783 *pr_out
= !!(epidr
& EPID_EPR
);
786 *as_out
= FIELD_EX64(env
->msr
, MSR
, DS
);
787 *pr_out
= FIELD_EX64(env
->msr
, MSR
, PR
);
792 /* Check if the tlb found by hashing really matches */
793 static int mmubooke206_check_tlb(CPUPPCState
*env
, ppcmas_tlb_t
*tlb
,
794 hwaddr
*raddr
, int *prot
,
795 target_ulong address
,
796 MMUAccessType access_type
, int mmu_idx
)
801 bool use_epid
= mmubooke206_get_as(env
, mmu_idx
, &epid
, &as
, &pr
);
804 if (ppcmas_tlb_check(env
, tlb
, raddr
, address
,
805 env
->spr
[SPR_BOOKE_PID
]) >= 0) {
809 if (env
->spr
[SPR_BOOKE_PID1
] &&
810 ppcmas_tlb_check(env
, tlb
, raddr
, address
,
811 env
->spr
[SPR_BOOKE_PID1
]) >= 0) {
815 if (env
->spr
[SPR_BOOKE_PID2
] &&
816 ppcmas_tlb_check(env
, tlb
, raddr
, address
,
817 env
->spr
[SPR_BOOKE_PID2
]) >= 0) {
821 if (ppcmas_tlb_check(env
, tlb
, raddr
, address
, epid
) >= 0) {
826 qemu_log_mask(CPU_LOG_MMU
, "%s: No TLB entry found for effective address "
827 "0x" TARGET_FMT_lx
"\n", __func__
, address
);
833 if (tlb
->mas7_3
& MAS3_UR
) {
836 if (tlb
->mas7_3
& MAS3_UW
) {
839 if (tlb
->mas7_3
& MAS3_UX
) {
843 if (tlb
->mas7_3
& MAS3_SR
) {
846 if (tlb
->mas7_3
& MAS3_SW
) {
849 if (tlb
->mas7_3
& MAS3_SX
) {
854 /* Check the address space and permissions */
855 if (access_type
== MMU_INST_FETCH
) {
856 /* There is no way to fetch code using epid load */
858 as
= FIELD_EX64(env
->msr
, MSR
, IR
);
861 if (as
!= ((tlb
->mas1
& MAS1_TS
) >> MAS1_TS_SHIFT
)) {
862 qemu_log_mask(CPU_LOG_MMU
, "%s: AS doesn't match\n", __func__
);
867 if (prot2
& prot_for_access_type(access_type
)) {
868 qemu_log_mask(CPU_LOG_MMU
, "%s: good TLB!\n", __func__
);
872 qemu_log_mask(CPU_LOG_MMU
, "%s: no prot match: %x\n", __func__
, prot2
);
873 return access_type
== MMU_INST_FETCH
? -3 : -2;
876 static int mmubooke206_get_physical_address(CPUPPCState
*env
, mmu_ctx_t
*ctx
,
877 target_ulong address
,
878 MMUAccessType access_type
,
886 raddr
= (hwaddr
)-1ULL;
888 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
889 int ways
= booke206_tlb_ways(env
, i
);
891 for (j
= 0; j
< ways
; j
++) {
892 tlb
= booke206_get_tlbm(env
, i
, address
, j
);
896 ret
= mmubooke206_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
,
897 access_type
, mmu_idx
);
908 qemu_log_mask(CPU_LOG_MMU
, "%s: access granted " TARGET_FMT_lx
909 " => " HWADDR_FMT_plx
" %d %d\n", __func__
, address
,
910 ctx
->raddr
, ctx
->prot
, ret
);
912 qemu_log_mask(CPU_LOG_MMU
, "%s: access refused " TARGET_FMT_lx
913 " => " HWADDR_FMT_plx
" %d %d\n", __func__
, address
,
914 raddr
, ctx
->prot
, ret
);
920 static const char *book3e_tsize_to_str
[32] = {
921 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
922 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M",
923 "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G",
927 static void mmubooke_dump_mmu(CPUPPCState
*env
)
933 if (kvm_enabled() && !env
->kvm_sw_tlb
) {
934 qemu_printf("Cannot access KVM TLB\n");
939 qemu_printf("\nTLB:\n");
940 qemu_printf("Effective Physical Size PID Prot "
943 entry
= &env
->tlb
.tlbe
[0];
944 for (i
= 0; i
< env
->nb_tlb
; i
++, entry
++) {
947 uint64_t size
= (uint64_t)entry
->size
;
950 /* Check valid flag */
951 if (!(entry
->prot
& PAGE_VALID
)) {
955 mask
= ~(entry
->size
- 1);
956 ea
= entry
->EPN
& mask
;
957 pa
= entry
->RPN
& mask
;
958 /* Extend the physical address to 36 bits */
959 pa
|= (hwaddr
)(entry
->RPN
& 0xF) << 32;
960 if (size
>= 1 * MiB
) {
961 snprintf(size_buf
, sizeof(size_buf
), "%3" PRId64
"M", size
/ MiB
);
963 snprintf(size_buf
, sizeof(size_buf
), "%3" PRId64
"k", size
/ KiB
);
965 qemu_printf("0x%016" PRIx64
" 0x%016" PRIx64
" %s %-5u %08x %08x\n",
966 (uint64_t)ea
, (uint64_t)pa
, size_buf
, (uint32_t)entry
->PID
,
967 entry
->prot
, entry
->attr
);
972 static void mmubooke206_dump_one_tlb(CPUPPCState
*env
, int tlbn
, int offset
,
978 qemu_printf("\nTLB%d:\n", tlbn
);
979 qemu_printf("Effective Physical Size TID TS SRWX"
980 " URWX WIMGE U0123\n");
982 entry
= &env
->tlb
.tlbm
[offset
];
983 for (i
= 0; i
< tlbsize
; i
++, entry
++) {
987 if (!(entry
->mas1
& MAS1_VALID
)) {
991 tsize
= (entry
->mas1
& MAS1_TSIZE_MASK
) >> MAS1_TSIZE_SHIFT
;
992 size
= 1024ULL << tsize
;
993 ea
= entry
->mas2
& ~(size
- 1);
994 pa
= entry
->mas7_3
& ~(size
- 1);
996 qemu_printf("0x%016" PRIx64
" 0x%016" PRIx64
" %4s %-5u %1u S%c%c%c"
997 " U%c%c%c %c%c%c%c%c U%c%c%c%c\n",
998 (uint64_t)ea
, (uint64_t)pa
,
999 book3e_tsize_to_str
[tsize
],
1000 (entry
->mas1
& MAS1_TID_MASK
) >> MAS1_TID_SHIFT
,
1001 (entry
->mas1
& MAS1_TS
) >> MAS1_TS_SHIFT
,
1002 entry
->mas7_3
& MAS3_SR
? 'R' : '-',
1003 entry
->mas7_3
& MAS3_SW
? 'W' : '-',
1004 entry
->mas7_3
& MAS3_SX
? 'X' : '-',
1005 entry
->mas7_3
& MAS3_UR
? 'R' : '-',
1006 entry
->mas7_3
& MAS3_UW
? 'W' : '-',
1007 entry
->mas7_3
& MAS3_UX
? 'X' : '-',
1008 entry
->mas2
& MAS2_W
? 'W' : '-',
1009 entry
->mas2
& MAS2_I
? 'I' : '-',
1010 entry
->mas2
& MAS2_M
? 'M' : '-',
1011 entry
->mas2
& MAS2_G
? 'G' : '-',
1012 entry
->mas2
& MAS2_E
? 'E' : '-',
1013 entry
->mas7_3
& MAS3_U0
? '0' : '-',
1014 entry
->mas7_3
& MAS3_U1
? '1' : '-',
1015 entry
->mas7_3
& MAS3_U2
? '2' : '-',
1016 entry
->mas7_3
& MAS3_U3
? '3' : '-');
1020 static void mmubooke206_dump_mmu(CPUPPCState
*env
)
1026 if (kvm_enabled() && !env
->kvm_sw_tlb
) {
1027 qemu_printf("Cannot access KVM TLB\n");
1032 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1033 int size
= booke206_tlb_size(env
, i
);
1039 mmubooke206_dump_one_tlb(env
, i
, offset
, size
);
1044 static void mmu6xx_dump_BATs(CPUPPCState
*env
, int type
)
1046 target_ulong
*BATlt
, *BATut
, *BATu
, *BATl
;
1047 target_ulong BEPIl
, BEPIu
, bl
;
1052 BATlt
= env
->IBAT
[1];
1053 BATut
= env
->IBAT
[0];
1056 BATlt
= env
->DBAT
[1];
1057 BATut
= env
->DBAT
[0];
1061 for (i
= 0; i
< env
->nb_BATs
; i
++) {
1064 BEPIu
= *BATu
& 0xF0000000;
1065 BEPIl
= *BATu
& 0x0FFE0000;
1066 bl
= (*BATu
& 0x00001FFC) << 15;
1067 qemu_printf("%s BAT%d BATu " TARGET_FMT_lx
1068 " BATl " TARGET_FMT_lx
"\n\t" TARGET_FMT_lx
" "
1069 TARGET_FMT_lx
" " TARGET_FMT_lx
"\n",
1070 type
== ACCESS_CODE
? "code" : "data", i
,
1071 *BATu
, *BATl
, BEPIu
, BEPIl
, bl
);
1075 static void mmu6xx_dump_mmu(CPUPPCState
*env
)
1077 PowerPCCPU
*cpu
= env_archcpu(env
);
1080 int type
, way
, entry
, i
;
1082 qemu_printf("HTAB base = 0x%"HWADDR_PRIx
"\n", ppc_hash32_hpt_base(cpu
));
1083 qemu_printf("HTAB mask = 0x%"HWADDR_PRIx
"\n", ppc_hash32_hpt_mask(cpu
));
1085 qemu_printf("\nSegment registers:\n");
1086 for (i
= 0; i
< 32; i
++) {
1088 if (sr
& 0x80000000) {
1089 qemu_printf("%02d T=%d Ks=%d Kp=%d BUID=0x%03x "
1090 "CNTLR_SPEC=0x%05x\n", i
,
1091 sr
& 0x80000000 ? 1 : 0, sr
& 0x40000000 ? 1 : 0,
1092 sr
& 0x20000000 ? 1 : 0, (uint32_t)((sr
>> 20) & 0x1FF),
1093 (uint32_t)(sr
& 0xFFFFF));
1095 qemu_printf("%02d T=%d Ks=%d Kp=%d N=%d VSID=0x%06x\n", i
,
1096 sr
& 0x80000000 ? 1 : 0, sr
& 0x40000000 ? 1 : 0,
1097 sr
& 0x20000000 ? 1 : 0, sr
& 0x10000000 ? 1 : 0,
1098 (uint32_t)(sr
& 0x00FFFFFF));
1102 qemu_printf("\nBATs:\n");
1103 mmu6xx_dump_BATs(env
, ACCESS_INT
);
1104 mmu6xx_dump_BATs(env
, ACCESS_CODE
);
1106 if (env
->id_tlbs
!= 1) {
1107 qemu_printf("ERROR: 6xx MMU should have separated TLB"
1108 " for code and data\n");
1111 qemu_printf("\nTLBs [EPN EPN + SIZE]\n");
1113 for (type
= 0; type
< 2; type
++) {
1114 for (way
= 0; way
< env
->nb_ways
; way
++) {
1115 for (entry
= env
->nb_tlb
* type
+ env
->tlb_per_way
* way
;
1116 entry
< (env
->nb_tlb
* type
+ env
->tlb_per_way
* (way
+ 1));
1119 tlb
= &env
->tlb
.tlb6
[entry
];
1120 qemu_printf("%s TLB %02d/%02d way:%d %s ["
1121 TARGET_FMT_lx
" " TARGET_FMT_lx
"]\n",
1122 type
? "code" : "data", entry
% env
->nb_tlb
,
1124 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
1125 tlb
->EPN
, tlb
->EPN
+ TARGET_PAGE_SIZE
);
1131 void dump_mmu(CPUPPCState
*env
)
1133 switch (env
->mmu_model
) {
1134 case POWERPC_MMU_BOOKE
:
1135 mmubooke_dump_mmu(env
);
1137 case POWERPC_MMU_BOOKE206
:
1138 mmubooke206_dump_mmu(env
);
1140 case POWERPC_MMU_SOFT_6xx
:
1141 mmu6xx_dump_mmu(env
);
1143 #if defined(TARGET_PPC64)
1144 case POWERPC_MMU_64B
:
1145 case POWERPC_MMU_2_03
:
1146 case POWERPC_MMU_2_06
:
1147 case POWERPC_MMU_2_07
:
1148 dump_slb(env_archcpu(env
));
1150 case POWERPC_MMU_3_00
:
1151 if (ppc64_v3_radix(env_archcpu(env
))) {
1152 qemu_log_mask(LOG_UNIMP
, "%s: the PPC64 MMU is unsupported\n",
1155 dump_slb(env_archcpu(env
));
1160 qemu_log_mask(LOG_UNIMP
, "%s: unimplemented\n", __func__
);
1164 static int check_physical(CPUPPCState
*env
, mmu_ctx_t
*ctx
, target_ulong eaddr
,
1165 MMUAccessType access_type
)
1168 ctx
->prot
= PAGE_READ
| PAGE_EXEC
;
1170 switch (env
->mmu_model
) {
1171 case POWERPC_MMU_SOFT_6xx
:
1172 case POWERPC_MMU_SOFT_4xx
:
1173 case POWERPC_MMU_REAL
:
1174 case POWERPC_MMU_BOOKE
:
1175 ctx
->prot
|= PAGE_WRITE
;
1179 /* Caller's checks mean we should never get here for other models */
1180 g_assert_not_reached();
1186 int get_physical_address_wtlb(CPUPPCState
*env
, mmu_ctx_t
*ctx
,
1188 MMUAccessType access_type
, int type
,
1192 bool real_mode
= (type
== ACCESS_CODE
&& !FIELD_EX64(env
->msr
, MSR
, IR
)) ||
1193 (type
!= ACCESS_CODE
&& !FIELD_EX64(env
->msr
, MSR
, DR
));
1195 switch (env
->mmu_model
) {
1196 case POWERPC_MMU_SOFT_6xx
:
1198 ret
= check_physical(env
, ctx
, eaddr
, access_type
);
1200 /* Try to find a BAT */
1201 if (env
->nb_BATs
!= 0) {
1202 ret
= get_bat_6xx_tlb(env
, ctx
, eaddr
, access_type
);
1205 /* We didn't match any BAT entry or don't have BATs */
1206 ret
= get_segment_6xx_tlb(env
, ctx
, eaddr
, access_type
, type
);
1211 case POWERPC_MMU_SOFT_4xx
:
1213 ret
= check_physical(env
, ctx
, eaddr
, access_type
);
1215 ret
= mmu40x_get_physical_address(env
, ctx
, eaddr
, access_type
);
1218 case POWERPC_MMU_BOOKE
:
1219 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
, access_type
);
1221 case POWERPC_MMU_BOOKE206
:
1222 ret
= mmubooke206_get_physical_address(env
, ctx
, eaddr
, access_type
,
1225 case POWERPC_MMU_MPC8xx
:
1227 cpu_abort(env_cpu(env
), "MPC8xx MMU model is not implemented\n");
1229 case POWERPC_MMU_REAL
:
1231 ret
= check_physical(env
, ctx
, eaddr
, access_type
);
1233 cpu_abort(env_cpu(env
),
1234 "PowerPC in real mode do not do any translation\n");
1238 cpu_abort(env_cpu(env
), "Unknown or invalid MMU model\n");
1245 static void booke206_update_mas_tlb_miss(CPUPPCState
*env
, target_ulong address
,
1246 MMUAccessType access_type
, int mmu_idx
)
1250 uint32_t missed_tid
= 0;
1251 bool use_epid
= mmubooke206_get_as(env
, mmu_idx
, &epid
, &as
, &pr
);
1253 if (access_type
== MMU_INST_FETCH
) {
1254 as
= FIELD_EX64(env
->msr
, MSR
, IR
);
1256 env
->spr
[SPR_BOOKE_MAS0
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TLBSELD_MASK
;
1257 env
->spr
[SPR_BOOKE_MAS1
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TSIZED_MASK
;
1258 env
->spr
[SPR_BOOKE_MAS2
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_WIMGED_MASK
;
1259 env
->spr
[SPR_BOOKE_MAS3
] = 0;
1260 env
->spr
[SPR_BOOKE_MAS6
] = 0;
1261 env
->spr
[SPR_BOOKE_MAS7
] = 0;
1265 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_TS
;
1266 env
->spr
[SPR_BOOKE_MAS6
] |= MAS6_SAS
;
1269 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_VALID
;
1270 env
->spr
[SPR_BOOKE_MAS2
] |= address
& MAS2_EPN_MASK
;
1273 switch (env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TIDSELD_PIDZ
) {
1274 case MAS4_TIDSELD_PID0
:
1275 missed_tid
= env
->spr
[SPR_BOOKE_PID
];
1277 case MAS4_TIDSELD_PID1
:
1278 missed_tid
= env
->spr
[SPR_BOOKE_PID1
];
1280 case MAS4_TIDSELD_PID2
:
1281 missed_tid
= env
->spr
[SPR_BOOKE_PID2
];
1284 env
->spr
[SPR_BOOKE_MAS6
] |= env
->spr
[SPR_BOOKE_PID
] << 16;
1287 env
->spr
[SPR_BOOKE_MAS6
] |= missed_tid
<< 16;
1289 env
->spr
[SPR_BOOKE_MAS1
] |= (missed_tid
<< MAS1_TID_SHIFT
);
1292 /* next victim logic */
1293 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_ESEL_SHIFT
;
1295 env
->last_way
&= booke206_tlb_ways(env
, 0) - 1;
1296 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_NV_SHIFT
;
1299 /* Perform address translation */
1300 /* TODO: Split this by mmu_model. */
1301 static bool ppc_jumbo_xlate(PowerPCCPU
*cpu
, vaddr eaddr
,
1302 MMUAccessType access_type
,
1303 hwaddr
*raddrp
, int *psizep
, int *protp
,
1304 int mmu_idx
, bool guest_visible
)
1306 CPUState
*cs
= CPU(cpu
);
1307 CPUPPCState
*env
= &cpu
->env
;
1312 if (access_type
== MMU_INST_FETCH
) {
1315 } else if (guest_visible
) {
1317 type
= env
->access_type
;
1322 ret
= get_physical_address_wtlb(env
, &ctx
, eaddr
, access_type
,
1325 *raddrp
= ctx
.raddr
;
1327 *psizep
= TARGET_PAGE_BITS
;
1331 if (guest_visible
) {
1332 log_cpu_state_mask(CPU_LOG_MMU
, cs
, 0);
1333 if (type
== ACCESS_CODE
) {
1336 /* No matches in page tables or TLB */
1337 switch (env
->mmu_model
) {
1338 case POWERPC_MMU_SOFT_6xx
:
1339 cs
->exception_index
= POWERPC_EXCP_IFTLB
;
1340 env
->error_code
= 1 << 18;
1341 env
->spr
[SPR_IMISS
] = eaddr
;
1342 env
->spr
[SPR_ICMP
] = 0x80000000 | ctx
.ptem
;
1344 case POWERPC_MMU_SOFT_4xx
:
1345 cs
->exception_index
= POWERPC_EXCP_ITLB
;
1346 env
->error_code
= 0;
1347 env
->spr
[SPR_40x_DEAR
] = eaddr
;
1348 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1350 case POWERPC_MMU_BOOKE206
:
1351 booke206_update_mas_tlb_miss(env
, eaddr
, 2, mmu_idx
);
1353 case POWERPC_MMU_BOOKE
:
1354 cs
->exception_index
= POWERPC_EXCP_ITLB
;
1355 env
->error_code
= 0;
1356 env
->spr
[SPR_BOOKE_DEAR
] = eaddr
;
1357 env
->spr
[SPR_BOOKE_ESR
] = mmubooke206_esr(mmu_idx
, MMU_DATA_LOAD
);
1359 case POWERPC_MMU_MPC8xx
:
1360 cpu_abort(cs
, "MPC8xx MMU model is not implemented\n");
1361 case POWERPC_MMU_REAL
:
1362 cpu_abort(cs
, "PowerPC in real mode should never raise "
1363 "any MMU exceptions\n");
1365 cpu_abort(cs
, "Unknown or invalid MMU model\n");
1369 /* Access rights violation */
1370 cs
->exception_index
= POWERPC_EXCP_ISI
;
1371 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1372 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1373 env
->error_code
= 0;
1375 env
->error_code
= 0x08000000;
1379 /* No execute protection violation */
1380 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1381 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1382 env
->spr
[SPR_BOOKE_ESR
] = 0x00000000;
1383 env
->error_code
= 0;
1385 env
->error_code
= 0x10000000;
1387 cs
->exception_index
= POWERPC_EXCP_ISI
;
1390 /* Direct store exception */
1391 /* No code fetch is allowed in direct-store areas */
1392 cs
->exception_index
= POWERPC_EXCP_ISI
;
1393 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1394 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1395 env
->error_code
= 0;
1397 env
->error_code
= 0x10000000;
1404 /* No matches in page tables or TLB */
1405 switch (env
->mmu_model
) {
1406 case POWERPC_MMU_SOFT_6xx
:
1407 if (access_type
== MMU_DATA_STORE
) {
1408 cs
->exception_index
= POWERPC_EXCP_DSTLB
;
1409 env
->error_code
= 1 << 16;
1411 cs
->exception_index
= POWERPC_EXCP_DLTLB
;
1412 env
->error_code
= 0;
1414 env
->spr
[SPR_DMISS
] = eaddr
;
1415 env
->spr
[SPR_DCMP
] = 0x80000000 | ctx
.ptem
;
1417 env
->error_code
|= ctx
.key
<< 19;
1418 env
->spr
[SPR_HASH1
] = ppc_hash32_hpt_base(cpu
) +
1419 get_pteg_offset32(cpu
, ctx
.hash
[0]);
1420 env
->spr
[SPR_HASH2
] = ppc_hash32_hpt_base(cpu
) +
1421 get_pteg_offset32(cpu
, ctx
.hash
[1]);
1423 case POWERPC_MMU_SOFT_4xx
:
1424 cs
->exception_index
= POWERPC_EXCP_DTLB
;
1425 env
->error_code
= 0;
1426 env
->spr
[SPR_40x_DEAR
] = eaddr
;
1427 if (access_type
== MMU_DATA_STORE
) {
1428 env
->spr
[SPR_40x_ESR
] = 0x00800000;
1430 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1433 case POWERPC_MMU_MPC8xx
:
1435 cpu_abort(cs
, "MPC8xx MMU model is not implemented\n");
1436 case POWERPC_MMU_BOOKE206
:
1437 booke206_update_mas_tlb_miss(env
, eaddr
, access_type
, mmu_idx
);
1439 case POWERPC_MMU_BOOKE
:
1440 cs
->exception_index
= POWERPC_EXCP_DTLB
;
1441 env
->error_code
= 0;
1442 env
->spr
[SPR_BOOKE_DEAR
] = eaddr
;
1443 env
->spr
[SPR_BOOKE_ESR
] = mmubooke206_esr(mmu_idx
, access_type
);
1445 case POWERPC_MMU_REAL
:
1446 cpu_abort(cs
, "PowerPC in real mode should never raise "
1447 "any MMU exceptions\n");
1449 cpu_abort(cs
, "Unknown or invalid MMU model\n");
1453 /* Access rights violation */
1454 cs
->exception_index
= POWERPC_EXCP_DSI
;
1455 env
->error_code
= 0;
1456 if (env
->mmu_model
== POWERPC_MMU_SOFT_4xx
) {
1457 env
->spr
[SPR_40x_DEAR
] = eaddr
;
1458 if (access_type
== MMU_DATA_STORE
) {
1459 env
->spr
[SPR_40x_ESR
] |= 0x00800000;
1461 } else if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1462 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1463 env
->spr
[SPR_BOOKE_DEAR
] = eaddr
;
1464 env
->spr
[SPR_BOOKE_ESR
] = mmubooke206_esr(mmu_idx
, access_type
);
1466 env
->spr
[SPR_DAR
] = eaddr
;
1467 if (access_type
== MMU_DATA_STORE
) {
1468 env
->spr
[SPR_DSISR
] = 0x0A000000;
1470 env
->spr
[SPR_DSISR
] = 0x08000000;
1475 /* Direct store exception */
1478 /* Floating point load/store */
1479 cs
->exception_index
= POWERPC_EXCP_ALIGN
;
1480 env
->error_code
= POWERPC_EXCP_ALIGN_FP
;
1481 env
->spr
[SPR_DAR
] = eaddr
;
1484 /* lwarx, ldarx or stwcx. */
1485 cs
->exception_index
= POWERPC_EXCP_DSI
;
1486 env
->error_code
= 0;
1487 env
->spr
[SPR_DAR
] = eaddr
;
1488 if (access_type
== MMU_DATA_STORE
) {
1489 env
->spr
[SPR_DSISR
] = 0x06000000;
1491 env
->spr
[SPR_DSISR
] = 0x04000000;
1495 /* eciwx or ecowx */
1496 cs
->exception_index
= POWERPC_EXCP_DSI
;
1497 env
->error_code
= 0;
1498 env
->spr
[SPR_DAR
] = eaddr
;
1499 if (access_type
== MMU_DATA_STORE
) {
1500 env
->spr
[SPR_DSISR
] = 0x06100000;
1502 env
->spr
[SPR_DSISR
] = 0x04100000;
1506 printf("DSI: invalid exception (%d)\n", ret
);
1507 cs
->exception_index
= POWERPC_EXCP_PROGRAM
;
1509 POWERPC_EXCP_INVAL
| POWERPC_EXCP_INVAL_INVAL
;
1510 env
->spr
[SPR_DAR
] = eaddr
;
1520 /*****************************************************************************/
1522 bool ppc_xlate(PowerPCCPU
*cpu
, vaddr eaddr
, MMUAccessType access_type
,
1523 hwaddr
*raddrp
, int *psizep
, int *protp
,
1524 int mmu_idx
, bool guest_visible
)
1526 switch (cpu
->env
.mmu_model
) {
1527 #if defined(TARGET_PPC64)
1528 case POWERPC_MMU_3_00
:
1529 if (ppc64_v3_radix(cpu
)) {
1530 return ppc_radix64_xlate(cpu
, eaddr
, access_type
, raddrp
,
1531 psizep
, protp
, mmu_idx
, guest_visible
);
1534 case POWERPC_MMU_64B
:
1535 case POWERPC_MMU_2_03
:
1536 case POWERPC_MMU_2_06
:
1537 case POWERPC_MMU_2_07
:
1538 return ppc_hash64_xlate(cpu
, eaddr
, access_type
,
1539 raddrp
, psizep
, protp
, mmu_idx
, guest_visible
);
1542 case POWERPC_MMU_32B
:
1543 return ppc_hash32_xlate(cpu
, eaddr
, access_type
, raddrp
,
1544 psizep
, protp
, mmu_idx
, guest_visible
);
1547 return ppc_jumbo_xlate(cpu
, eaddr
, access_type
, raddrp
,
1548 psizep
, protp
, mmu_idx
, guest_visible
);
1552 hwaddr
ppc_cpu_get_phys_page_debug(CPUState
*cs
, vaddr addr
)
1554 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
1559 * Some MMUs have separate TLBs for code and data. If we only
1560 * try an MMU_DATA_LOAD, we may not be able to read instructions
1561 * mapped by code TLBs, so we also try a MMU_INST_FETCH.
1563 if (ppc_xlate(cpu
, addr
, MMU_DATA_LOAD
, &raddr
, &s
, &p
,
1564 ppc_env_mmu_index(&cpu
->env
, false), false) ||
1565 ppc_xlate(cpu
, addr
, MMU_INST_FETCH
, &raddr
, &s
, &p
,
1566 ppc_env_mmu_index(&cpu
->env
, true), false)) {
1567 return raddr
& TARGET_PAGE_MASK
;