2 * PowerPC 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 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/>.
21 #include "helper_regs.h"
29 //#define DEBUG_SOFTWARE_TLB
30 //#define DUMP_PAGE_TABLES
31 //#define DEBUG_EXCEPTIONS
32 //#define FLUSH_ALL_TLBS
35 # define LOG_MMU(...) qemu_log(__VA_ARGS__)
36 # define LOG_MMU_STATE(env) log_cpu_state((env), 0)
38 # define LOG_MMU(...) do { } while (0)
39 # define LOG_MMU_STATE(...) do { } while (0)
43 #ifdef DEBUG_SOFTWARE_TLB
44 # define LOG_SWTLB(...) qemu_log(__VA_ARGS__)
46 # define LOG_SWTLB(...) do { } while (0)
50 # define LOG_BATS(...) qemu_log(__VA_ARGS__)
52 # define LOG_BATS(...) do { } while (0)
56 # define LOG_SLB(...) qemu_log(__VA_ARGS__)
58 # define LOG_SLB(...) do { } while (0)
61 #ifdef DEBUG_EXCEPTIONS
62 # define LOG_EXCP(...) qemu_log(__VA_ARGS__)
64 # define LOG_EXCP(...) do { } while (0)
67 /*****************************************************************************/
68 /* PowerPC Hypercall emulation */
70 void (*cpu_ppc_hypercall
)(CPUPPCState
*);
72 /*****************************************************************************/
73 /* PowerPC MMU emulation */
75 #if defined(CONFIG_USER_ONLY)
76 int cpu_ppc_handle_mmu_fault (CPUPPCState
*env
, target_ulong address
, int rw
,
79 int exception
, error_code
;
82 exception
= POWERPC_EXCP_ISI
;
83 error_code
= 0x40000000;
85 exception
= POWERPC_EXCP_DSI
;
86 error_code
= 0x40000000;
88 error_code
|= 0x02000000;
89 env
->spr
[SPR_DAR
] = address
;
90 env
->spr
[SPR_DSISR
] = error_code
;
92 env
->exception_index
= exception
;
93 env
->error_code
= error_code
;
99 /* Common routines used by software and hardware TLBs emulation */
100 static inline int pte_is_valid(target_ulong pte0
)
102 return pte0
& 0x80000000 ? 1 : 0;
105 static inline void pte_invalidate(target_ulong
*pte0
)
107 *pte0
&= ~0x80000000;
110 #if defined(TARGET_PPC64)
111 static inline int pte64_is_valid(target_ulong pte0
)
113 return pte0
& 0x0000000000000001ULL
? 1 : 0;
116 static inline void pte64_invalidate(target_ulong
*pte0
)
118 *pte0
&= ~0x0000000000000001ULL
;
122 #define PTE_PTEM_MASK 0x7FFFFFBF
123 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
124 #if defined(TARGET_PPC64)
125 #define PTE64_PTEM_MASK 0xFFFFFFFFFFFFFF80ULL
126 #define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F)
129 static inline int pp_check(int key
, int pp
, int nx
)
133 /* Compute access rights */
134 /* When pp is 3/7, the result is undefined. Set it to noaccess */
141 access
|= PAGE_WRITE
;
159 access
= PAGE_READ
| PAGE_WRITE
;
169 static inline int check_prot(int prot
, int rw
, int access_type
)
173 if (access_type
== ACCESS_CODE
) {
174 if (prot
& PAGE_EXEC
)
179 if (prot
& PAGE_WRITE
)
184 if (prot
& PAGE_READ
)
193 static inline int _pte_check(mmu_ctx_t
*ctx
, int is_64b
, target_ulong pte0
,
194 target_ulong pte1
, int h
, int rw
, int type
)
196 target_ulong ptem
, mmask
;
197 int access
, ret
, pteh
, ptev
, pp
;
200 /* Check validity and table match */
201 #if defined(TARGET_PPC64)
203 ptev
= pte64_is_valid(pte0
);
204 pteh
= (pte0
>> 1) & 1;
208 ptev
= pte_is_valid(pte0
);
209 pteh
= (pte0
>> 6) & 1;
211 if (ptev
&& h
== pteh
) {
212 /* Check vsid & api */
213 #if defined(TARGET_PPC64)
215 ptem
= pte0
& PTE64_PTEM_MASK
;
216 mmask
= PTE64_CHECK_MASK
;
217 pp
= (pte1
& 0x00000003) | ((pte1
>> 61) & 0x00000004);
218 ctx
->nx
= (pte1
>> 2) & 1; /* No execute bit */
219 ctx
->nx
|= (pte1
>> 3) & 1; /* Guarded bit */
223 ptem
= pte0
& PTE_PTEM_MASK
;
224 mmask
= PTE_CHECK_MASK
;
225 pp
= pte1
& 0x00000003;
227 if (ptem
== ctx
->ptem
) {
228 if (ctx
->raddr
!= (target_phys_addr_t
)-1ULL) {
229 /* all matches should have equal RPN, WIMG & PP */
230 if ((ctx
->raddr
& mmask
) != (pte1
& mmask
)) {
231 qemu_log("Bad RPN/WIMG/PP\n");
235 /* Compute access rights */
236 access
= pp_check(ctx
->key
, pp
, ctx
->nx
);
237 /* Keep the matching PTE informations */
240 ret
= check_prot(ctx
->prot
, rw
, type
);
243 LOG_MMU("PTE access granted !\n");
245 /* Access right violation */
246 LOG_MMU("PTE access rejected\n");
254 static inline int pte32_check(mmu_ctx_t
*ctx
, target_ulong pte0
,
255 target_ulong pte1
, int h
, int rw
, int type
)
257 return _pte_check(ctx
, 0, pte0
, pte1
, h
, rw
, type
);
260 #if defined(TARGET_PPC64)
261 static inline int pte64_check(mmu_ctx_t
*ctx
, target_ulong pte0
,
262 target_ulong pte1
, int h
, int rw
, int type
)
264 return _pte_check(ctx
, 1, pte0
, pte1
, h
, rw
, type
);
268 static inline int pte_update_flags(mmu_ctx_t
*ctx
, target_ulong
*pte1p
,
273 /* Update page flags */
274 if (!(*pte1p
& 0x00000100)) {
275 /* Update accessed flag */
276 *pte1p
|= 0x00000100;
279 if (!(*pte1p
& 0x00000080)) {
280 if (rw
== 1 && ret
== 0) {
281 /* Update changed flag */
282 *pte1p
|= 0x00000080;
285 /* Force page fault for first write access */
286 ctx
->prot
&= ~PAGE_WRITE
;
293 /* Software driven TLB helpers */
294 static inline int ppc6xx_tlb_getnum(CPUPPCState
*env
, target_ulong eaddr
, int way
,
299 /* Select TLB num in a way from address */
300 nr
= (eaddr
>> TARGET_PAGE_BITS
) & (env
->tlb_per_way
- 1);
302 nr
+= env
->tlb_per_way
* way
;
303 /* 6xx have separate TLBs for instructions and data */
304 if (is_code
&& env
->id_tlbs
== 1)
310 static inline void ppc6xx_tlb_invalidate_all(CPUPPCState
*env
)
315 //LOG_SWTLB("Invalidate all TLBs\n");
316 /* Invalidate all defined software TLB */
318 if (env
->id_tlbs
== 1)
320 for (nr
= 0; nr
< max
; nr
++) {
321 tlb
= &env
->tlb
.tlb6
[nr
];
322 pte_invalidate(&tlb
->pte0
);
327 static inline void __ppc6xx_tlb_invalidate_virt(CPUPPCState
*env
,
329 int is_code
, int match_epn
)
331 #if !defined(FLUSH_ALL_TLBS)
335 /* Invalidate ITLB + DTLB, all ways */
336 for (way
= 0; way
< env
->nb_ways
; way
++) {
337 nr
= ppc6xx_tlb_getnum(env
, eaddr
, way
, is_code
);
338 tlb
= &env
->tlb
.tlb6
[nr
];
339 if (pte_is_valid(tlb
->pte0
) && (match_epn
== 0 || eaddr
== tlb
->EPN
)) {
340 LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx
"\n", nr
,
342 pte_invalidate(&tlb
->pte0
);
343 tlb_flush_page(env
, tlb
->EPN
);
347 /* XXX: PowerPC specification say this is valid as well */
348 ppc6xx_tlb_invalidate_all(env
);
352 static inline void ppc6xx_tlb_invalidate_virt(CPUPPCState
*env
,
353 target_ulong eaddr
, int is_code
)
355 __ppc6xx_tlb_invalidate_virt(env
, eaddr
, is_code
, 0);
358 void ppc6xx_tlb_store (CPUPPCState
*env
, target_ulong EPN
, int way
, int is_code
,
359 target_ulong pte0
, target_ulong pte1
)
364 nr
= ppc6xx_tlb_getnum(env
, EPN
, way
, is_code
);
365 tlb
= &env
->tlb
.tlb6
[nr
];
366 LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx
" PTE0 " TARGET_FMT_lx
367 " PTE1 " TARGET_FMT_lx
"\n", nr
, env
->nb_tlb
, EPN
, pte0
, pte1
);
368 /* Invalidate any pending reference in Qemu for this virtual address */
369 __ppc6xx_tlb_invalidate_virt(env
, EPN
, is_code
, 1);
373 /* Store last way for LRU mechanism */
377 static inline int ppc6xx_tlb_check(CPUPPCState
*env
, mmu_ctx_t
*ctx
,
378 target_ulong eaddr
, int rw
, int access_type
)
385 ret
= -1; /* No TLB found */
386 for (way
= 0; way
< env
->nb_ways
; way
++) {
387 nr
= ppc6xx_tlb_getnum(env
, eaddr
, way
,
388 access_type
== ACCESS_CODE
? 1 : 0);
389 tlb
= &env
->tlb
.tlb6
[nr
];
390 /* This test "emulates" the PTE index match for hardware TLBs */
391 if ((eaddr
& TARGET_PAGE_MASK
) != tlb
->EPN
) {
392 LOG_SWTLB("TLB %d/%d %s [" TARGET_FMT_lx
" " TARGET_FMT_lx
393 "] <> " TARGET_FMT_lx
"\n", nr
, env
->nb_tlb
,
394 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
395 tlb
->EPN
, tlb
->EPN
+ TARGET_PAGE_SIZE
, eaddr
);
398 LOG_SWTLB("TLB %d/%d %s " TARGET_FMT_lx
" <> " TARGET_FMT_lx
" "
399 TARGET_FMT_lx
" %c %c\n", nr
, env
->nb_tlb
,
400 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
401 tlb
->EPN
, eaddr
, tlb
->pte1
,
402 rw
? 'S' : 'L', access_type
== ACCESS_CODE
? 'I' : 'D');
403 switch (pte32_check(ctx
, tlb
->pte0
, tlb
->pte1
, 0, rw
, access_type
)) {
405 /* TLB inconsistency */
408 /* Access violation */
418 /* XXX: we should go on looping to check all TLBs consistency
419 * but we can speed-up the whole thing as the
420 * result would be undefined if TLBs are not consistent.
429 LOG_SWTLB("found TLB at addr " TARGET_FMT_plx
" prot=%01x ret=%d\n",
430 ctx
->raddr
& TARGET_PAGE_MASK
, ctx
->prot
, ret
);
431 /* Update page flags */
432 pte_update_flags(ctx
, &env
->tlb
.tlb6
[best
].pte1
, ret
, rw
);
438 /* Perform BAT hit & translation */
439 static inline void bat_size_prot(CPUPPCState
*env
, target_ulong
*blp
, int *validp
,
440 int *protp
, target_ulong
*BATu
,
446 bl
= (*BATu
& 0x00001FFC) << 15;
449 if (((msr_pr
== 0) && (*BATu
& 0x00000002)) ||
450 ((msr_pr
!= 0) && (*BATu
& 0x00000001))) {
452 pp
= *BATl
& 0x00000003;
454 prot
= PAGE_READ
| PAGE_EXEC
;
464 static inline void bat_601_size_prot(CPUPPCState
*env
, target_ulong
*blp
,
465 int *validp
, int *protp
,
466 target_ulong
*BATu
, target_ulong
*BATl
)
469 int key
, pp
, valid
, prot
;
471 bl
= (*BATl
& 0x0000003F) << 17;
472 LOG_BATS("b %02x ==> bl " TARGET_FMT_lx
" msk " TARGET_FMT_lx
"\n",
473 (uint8_t)(*BATl
& 0x0000003F), bl
, ~bl
);
475 valid
= (*BATl
>> 6) & 1;
477 pp
= *BATu
& 0x00000003;
479 key
= (*BATu
>> 3) & 1;
481 key
= (*BATu
>> 2) & 1;
482 prot
= pp_check(key
, pp
, 0);
489 static inline int get_bat(CPUPPCState
*env
, mmu_ctx_t
*ctx
, target_ulong
virtual,
492 target_ulong
*BATlt
, *BATut
, *BATu
, *BATl
;
493 target_ulong BEPIl
, BEPIu
, bl
;
497 LOG_BATS("%s: %cBAT v " TARGET_FMT_lx
"\n", __func__
,
498 type
== ACCESS_CODE
? 'I' : 'D', virtual);
501 BATlt
= env
->IBAT
[1];
502 BATut
= env
->IBAT
[0];
505 BATlt
= env
->DBAT
[1];
506 BATut
= env
->DBAT
[0];
509 for (i
= 0; i
< env
->nb_BATs
; i
++) {
512 BEPIu
= *BATu
& 0xF0000000;
513 BEPIl
= *BATu
& 0x0FFE0000;
514 if (unlikely(env
->mmu_model
== POWERPC_MMU_601
)) {
515 bat_601_size_prot(env
, &bl
, &valid
, &prot
, BATu
, BATl
);
517 bat_size_prot(env
, &bl
, &valid
, &prot
, BATu
, BATl
);
519 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx
" BATu " TARGET_FMT_lx
520 " BATl " TARGET_FMT_lx
"\n", __func__
,
521 type
== ACCESS_CODE
? 'I' : 'D', i
, virtual, *BATu
, *BATl
);
522 if ((virtual & 0xF0000000) == BEPIu
&&
523 ((virtual & 0x0FFE0000) & ~bl
) == BEPIl
) {
526 /* Get physical address */
527 ctx
->raddr
= (*BATl
& 0xF0000000) |
528 ((virtual & 0x0FFE0000 & bl
) | (*BATl
& 0x0FFE0000)) |
529 (virtual & 0x0001F000);
530 /* Compute access rights */
532 ret
= check_prot(ctx
->prot
, rw
, type
);
534 LOG_BATS("BAT %d match: r " TARGET_FMT_plx
" prot=%c%c\n",
535 i
, ctx
->raddr
, ctx
->prot
& PAGE_READ
? 'R' : '-',
536 ctx
->prot
& PAGE_WRITE
? 'W' : '-');
542 #if defined(DEBUG_BATS)
543 if (qemu_log_enabled()) {
544 LOG_BATS("no BAT match for " TARGET_FMT_lx
":\n", virtual);
545 for (i
= 0; i
< 4; i
++) {
548 BEPIu
= *BATu
& 0xF0000000;
549 BEPIl
= *BATu
& 0x0FFE0000;
550 bl
= (*BATu
& 0x00001FFC) << 15;
551 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx
" BATu " TARGET_FMT_lx
552 " BATl " TARGET_FMT_lx
"\n\t" TARGET_FMT_lx
" "
553 TARGET_FMT_lx
" " TARGET_FMT_lx
"\n",
554 __func__
, type
== ACCESS_CODE
? 'I' : 'D', i
, virtual,
555 *BATu
, *BATl
, BEPIu
, BEPIl
, bl
);
564 static inline target_phys_addr_t
get_pteg_offset(CPUPPCState
*env
,
565 target_phys_addr_t hash
,
568 return (hash
* pte_size
* 8) & env
->htab_mask
;
571 /* PTE table lookup */
572 static inline int _find_pte(CPUPPCState
*env
, mmu_ctx_t
*ctx
, int is_64b
, int h
,
573 int rw
, int type
, int target_page_bits
)
575 target_phys_addr_t pteg_off
;
576 target_ulong pte0
, pte1
;
580 ret
= -1; /* No entry found */
581 pteg_off
= get_pteg_offset(env
, ctx
->hash
[h
],
582 is_64b
? HASH_PTE_SIZE_64
: HASH_PTE_SIZE_32
);
583 for (i
= 0; i
< 8; i
++) {
584 #if defined(TARGET_PPC64)
586 if (env
->external_htab
) {
587 pte0
= ldq_p(env
->external_htab
+ pteg_off
+ (i
* 16));
588 pte1
= ldq_p(env
->external_htab
+ pteg_off
+ (i
* 16) + 8);
590 pte0
= ldq_phys(env
->htab_base
+ pteg_off
+ (i
* 16));
591 pte1
= ldq_phys(env
->htab_base
+ pteg_off
+ (i
* 16) + 8);
594 r
= pte64_check(ctx
, pte0
, pte1
, h
, rw
, type
);
595 LOG_MMU("Load pte from " TARGET_FMT_lx
" => " TARGET_FMT_lx
" "
596 TARGET_FMT_lx
" %d %d %d " TARGET_FMT_lx
"\n",
597 pteg_off
+ (i
* 16), pte0
, pte1
, (int)(pte0
& 1), h
,
598 (int)((pte0
>> 1) & 1), ctx
->ptem
);
602 if (env
->external_htab
) {
603 pte0
= ldl_p(env
->external_htab
+ pteg_off
+ (i
* 8));
604 pte1
= ldl_p(env
->external_htab
+ pteg_off
+ (i
* 8) + 4);
606 pte0
= ldl_phys(env
->htab_base
+ pteg_off
+ (i
* 8));
607 pte1
= ldl_phys(env
->htab_base
+ pteg_off
+ (i
* 8) + 4);
609 r
= pte32_check(ctx
, pte0
, pte1
, h
, rw
, type
);
610 LOG_MMU("Load pte from " TARGET_FMT_lx
" => " TARGET_FMT_lx
" "
611 TARGET_FMT_lx
" %d %d %d " TARGET_FMT_lx
"\n",
612 pteg_off
+ (i
* 8), pte0
, pte1
, (int)(pte0
>> 31), h
,
613 (int)((pte0
>> 6) & 1), ctx
->ptem
);
617 /* PTE inconsistency */
620 /* Access violation */
630 /* XXX: we should go on looping to check all PTEs consistency
631 * but if we can speed-up the whole thing as the
632 * result would be undefined if PTEs are not consistent.
641 LOG_MMU("found PTE at addr " TARGET_FMT_lx
" prot=%01x ret=%d\n",
642 ctx
->raddr
, ctx
->prot
, ret
);
643 /* Update page flags */
645 if (pte_update_flags(ctx
, &pte1
, ret
, rw
) == 1) {
646 #if defined(TARGET_PPC64)
648 if (env
->external_htab
) {
649 stq_p(env
->external_htab
+ pteg_off
+ (good
* 16) + 8,
652 stq_phys_notdirty(env
->htab_base
+ pteg_off
+
653 (good
* 16) + 8, pte1
);
658 if (env
->external_htab
) {
659 stl_p(env
->external_htab
+ pteg_off
+ (good
* 8) + 4,
662 stl_phys_notdirty(env
->htab_base
+ pteg_off
+
663 (good
* 8) + 4, pte1
);
669 /* We have a TLB that saves 4K pages, so let's
670 * split a huge page to 4k chunks */
671 if (target_page_bits
!= TARGET_PAGE_BITS
) {
672 ctx
->raddr
|= (ctx
->eaddr
& ((1 << target_page_bits
) - 1))
678 static inline int find_pte(CPUPPCState
*env
, mmu_ctx_t
*ctx
, int h
, int rw
,
679 int type
, int target_page_bits
)
681 #if defined(TARGET_PPC64)
682 if (env
->mmu_model
& POWERPC_MMU_64
)
683 return _find_pte(env
, ctx
, 1, h
, rw
, type
, target_page_bits
);
686 return _find_pte(env
, ctx
, 0, h
, rw
, type
, target_page_bits
);
689 #if defined(TARGET_PPC64)
690 static inline ppc_slb_t
*slb_lookup(CPUPPCState
*env
, target_ulong eaddr
)
692 uint64_t esid_256M
, esid_1T
;
695 LOG_SLB("%s: eaddr " TARGET_FMT_lx
"\n", __func__
, eaddr
);
697 esid_256M
= (eaddr
& SEGMENT_MASK_256M
) | SLB_ESID_V
;
698 esid_1T
= (eaddr
& SEGMENT_MASK_1T
) | SLB_ESID_V
;
700 for (n
= 0; n
< env
->slb_nr
; n
++) {
701 ppc_slb_t
*slb
= &env
->slb
[n
];
703 LOG_SLB("%s: slot %d %016" PRIx64
" %016"
704 PRIx64
"\n", __func__
, n
, slb
->esid
, slb
->vsid
);
705 /* We check for 1T matches on all MMUs here - if the MMU
706 * doesn't have 1T segment support, we will have prevented 1T
707 * entries from being inserted in the slbmte code. */
708 if (((slb
->esid
== esid_256M
) &&
709 ((slb
->vsid
& SLB_VSID_B
) == SLB_VSID_B_256M
))
710 || ((slb
->esid
== esid_1T
) &&
711 ((slb
->vsid
& SLB_VSID_B
) == SLB_VSID_B_1T
))) {
719 void ppc_slb_invalidate_all (CPUPPCState
*env
)
721 int n
, do_invalidate
;
724 /* XXX: Warning: slbia never invalidates the first segment */
725 for (n
= 1; n
< env
->slb_nr
; n
++) {
726 ppc_slb_t
*slb
= &env
->slb
[n
];
728 if (slb
->esid
& SLB_ESID_V
) {
729 slb
->esid
&= ~SLB_ESID_V
;
730 /* XXX: given the fact that segment size is 256 MB or 1TB,
731 * and we still don't have a tlb_flush_mask(env, n, mask)
732 * in Qemu, we just invalidate all TLBs
741 void ppc_slb_invalidate_one (CPUPPCState
*env
, uint64_t T0
)
745 slb
= slb_lookup(env
, T0
);
750 if (slb
->esid
& SLB_ESID_V
) {
751 slb
->esid
&= ~SLB_ESID_V
;
753 /* XXX: given the fact that segment size is 256 MB or 1TB,
754 * and we still don't have a tlb_flush_mask(env, n, mask)
755 * in Qemu, we just invalidate all TLBs
761 int ppc_store_slb (CPUPPCState
*env
, target_ulong rb
, target_ulong rs
)
763 int slot
= rb
& 0xfff;
764 ppc_slb_t
*slb
= &env
->slb
[slot
];
766 if (rb
& (0x1000 - env
->slb_nr
)) {
767 return -1; /* Reserved bits set or slot too high */
769 if (rs
& (SLB_VSID_B
& ~SLB_VSID_B_1T
)) {
770 return -1; /* Bad segment size */
772 if ((rs
& SLB_VSID_B
) && !(env
->mmu_model
& POWERPC_MMU_1TSEG
)) {
773 return -1; /* 1T segment on MMU that doesn't support it */
776 /* Mask out the slot number as we store the entry */
777 slb
->esid
= rb
& (SLB_ESID_ESID
| SLB_ESID_V
);
780 LOG_SLB("%s: %d " TARGET_FMT_lx
" - " TARGET_FMT_lx
" => %016" PRIx64
781 " %016" PRIx64
"\n", __func__
, slot
, rb
, rs
,
782 slb
->esid
, slb
->vsid
);
787 int ppc_load_slb_esid (CPUPPCState
*env
, target_ulong rb
, target_ulong
*rt
)
789 int slot
= rb
& 0xfff;
790 ppc_slb_t
*slb
= &env
->slb
[slot
];
792 if (slot
>= env
->slb_nr
) {
800 int ppc_load_slb_vsid (CPUPPCState
*env
, target_ulong rb
, target_ulong
*rt
)
802 int slot
= rb
& 0xfff;
803 ppc_slb_t
*slb
= &env
->slb
[slot
];
805 if (slot
>= env
->slb_nr
) {
812 #endif /* defined(TARGET_PPC64) */
814 /* Perform segment based translation */
815 static inline int get_segment(CPUPPCState
*env
, mmu_ctx_t
*ctx
,
816 target_ulong eaddr
, int rw
, int type
)
818 target_phys_addr_t hash
;
820 int ds
, pr
, target_page_bits
;
825 #if defined(TARGET_PPC64)
826 if (env
->mmu_model
& POWERPC_MMU_64
) {
828 target_ulong pageaddr
;
831 LOG_MMU("Check SLBs\n");
832 slb
= slb_lookup(env
, eaddr
);
837 if (slb
->vsid
& SLB_VSID_B
) {
838 vsid
= (slb
->vsid
& SLB_VSID_VSID
) >> SLB_VSID_SHIFT_1T
;
841 vsid
= (slb
->vsid
& SLB_VSID_VSID
) >> SLB_VSID_SHIFT
;
845 target_page_bits
= (slb
->vsid
& SLB_VSID_L
)
846 ? TARGET_PAGE_BITS_16M
: TARGET_PAGE_BITS
;
847 ctx
->key
= !!(pr
? (slb
->vsid
& SLB_VSID_KP
)
848 : (slb
->vsid
& SLB_VSID_KS
));
850 ctx
->nx
= !!(slb
->vsid
& SLB_VSID_N
);
852 pageaddr
= eaddr
& ((1ULL << segment_bits
)
853 - (1ULL << target_page_bits
));
854 if (slb
->vsid
& SLB_VSID_B
) {
855 hash
= vsid
^ (vsid
<< 25) ^ (pageaddr
>> target_page_bits
);
857 hash
= vsid
^ (pageaddr
>> target_page_bits
);
859 /* Only 5 bits of the page index are used in the AVPN */
860 ctx
->ptem
= (slb
->vsid
& SLB_VSID_PTEM
) |
861 ((pageaddr
>> 16) & ((1ULL << segment_bits
) - 0x80));
863 #endif /* defined(TARGET_PPC64) */
865 target_ulong sr
, pgidx
;
867 sr
= env
->sr
[eaddr
>> 28];
868 ctx
->key
= (((sr
& 0x20000000) && (pr
!= 0)) ||
869 ((sr
& 0x40000000) && (pr
== 0))) ? 1 : 0;
870 ds
= sr
& 0x80000000 ? 1 : 0;
871 ctx
->nx
= sr
& 0x10000000 ? 1 : 0;
872 vsid
= sr
& 0x00FFFFFF;
873 target_page_bits
= TARGET_PAGE_BITS
;
874 LOG_MMU("Check segment v=" TARGET_FMT_lx
" %d " TARGET_FMT_lx
" nip="
875 TARGET_FMT_lx
" lr=" TARGET_FMT_lx
876 " ir=%d dr=%d pr=%d %d t=%d\n",
877 eaddr
, (int)(eaddr
>> 28), sr
, env
->nip
, env
->lr
, (int)msr_ir
,
878 (int)msr_dr
, pr
!= 0 ? 1 : 0, rw
, type
);
879 pgidx
= (eaddr
& ~SEGMENT_MASK_256M
) >> target_page_bits
;
881 ctx
->ptem
= (vsid
<< 7) | (pgidx
>> 10);
883 LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx
"\n",
884 ctx
->key
, ds
, ctx
->nx
, vsid
);
887 /* Check if instruction fetch is allowed, if needed */
888 if (type
!= ACCESS_CODE
|| ctx
->nx
== 0) {
889 /* Page address translation */
890 LOG_MMU("htab_base " TARGET_FMT_plx
" htab_mask " TARGET_FMT_plx
891 " hash " TARGET_FMT_plx
"\n",
892 env
->htab_base
, env
->htab_mask
, hash
);
894 ctx
->hash
[1] = ~hash
;
896 /* Initialize real address with an invalid value */
897 ctx
->raddr
= (target_phys_addr_t
)-1ULL;
898 if (unlikely(env
->mmu_model
== POWERPC_MMU_SOFT_6xx
||
899 env
->mmu_model
== POWERPC_MMU_SOFT_74xx
)) {
900 /* Software TLB search */
901 ret
= ppc6xx_tlb_check(env
, ctx
, eaddr
, rw
, type
);
903 LOG_MMU("0 htab=" TARGET_FMT_plx
"/" TARGET_FMT_plx
904 " vsid=" TARGET_FMT_lx
" ptem=" TARGET_FMT_lx
905 " hash=" TARGET_FMT_plx
"\n",
906 env
->htab_base
, env
->htab_mask
, vsid
, ctx
->ptem
,
908 /* Primary table lookup */
909 ret
= find_pte(env
, ctx
, 0, rw
, type
, target_page_bits
);
911 /* Secondary table lookup */
912 if (eaddr
!= 0xEFFFFFFF)
913 LOG_MMU("1 htab=" TARGET_FMT_plx
"/" TARGET_FMT_plx
914 " vsid=" TARGET_FMT_lx
" api=" TARGET_FMT_lx
915 " hash=" TARGET_FMT_plx
"\n", env
->htab_base
,
916 env
->htab_mask
, vsid
, ctx
->ptem
, ctx
->hash
[1]);
917 ret2
= find_pte(env
, ctx
, 1, rw
, type
,
923 #if defined (DUMP_PAGE_TABLES)
924 if (qemu_log_enabled()) {
925 target_phys_addr_t curaddr
;
926 uint32_t a0
, a1
, a2
, a3
;
927 qemu_log("Page table: " TARGET_FMT_plx
" len " TARGET_FMT_plx
928 "\n", sdr
, mask
+ 0x80);
929 for (curaddr
= sdr
; curaddr
< (sdr
+ mask
+ 0x80);
931 a0
= ldl_phys(curaddr
);
932 a1
= ldl_phys(curaddr
+ 4);
933 a2
= ldl_phys(curaddr
+ 8);
934 a3
= ldl_phys(curaddr
+ 12);
935 if (a0
!= 0 || a1
!= 0 || a2
!= 0 || a3
!= 0) {
936 qemu_log(TARGET_FMT_plx
": %08x %08x %08x %08x\n",
937 curaddr
, a0
, a1
, a2
, a3
);
943 LOG_MMU("No access allowed\n");
948 LOG_MMU("direct store...\n");
949 /* Direct-store segment : absolutely *BUGGY* for now */
951 /* Direct-store implies a 32-bit MMU.
952 * Check the Segment Register's bus unit ID (BUID).
954 sr
= env
->sr
[eaddr
>> 28];
955 if ((sr
& 0x1FF00000) >> 20 == 0x07f) {
956 /* Memory-forced I/O controller interface access */
957 /* If T=1 and BUID=x'07F', the 601 performs a memory access
958 * to SR[28-31] LA[4-31], bypassing all protection mechanisms.
960 ctx
->raddr
= ((sr
& 0xF) << 28) | (eaddr
& 0x0FFFFFFF);
961 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
967 /* Integer load/store : only access allowed */
970 /* No code fetch is allowed in direct-store areas */
973 /* Floating point load/store */
976 /* lwarx, ldarx or srwcx. */
979 /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
980 /* Should make the instruction do no-op.
981 * As it already do no-op, it's quite easy :-)
989 qemu_log("ERROR: instruction should not need "
990 "address translation\n");
993 if ((rw
== 1 || ctx
->key
!= 1) && (rw
== 0 || ctx
->key
!= 0)) {
1004 /* Generic TLB check function for embedded PowerPC implementations */
1005 int ppcemb_tlb_check(CPUPPCState
*env
, ppcemb_tlb_t
*tlb
,
1006 target_phys_addr_t
*raddrp
,
1007 target_ulong address
, uint32_t pid
, int ext
,
1012 /* Check valid flag */
1013 if (!(tlb
->prot
& PAGE_VALID
)) {
1016 mask
= ~(tlb
->size
- 1);
1017 LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx
" PID %u <=> " TARGET_FMT_lx
1018 " " TARGET_FMT_lx
" %u %x\n", __func__
, i
, address
, pid
, tlb
->EPN
,
1019 mask
, (uint32_t)tlb
->PID
, tlb
->prot
);
1021 if (tlb
->PID
!= 0 && tlb
->PID
!= pid
)
1023 /* Check effective address */
1024 if ((address
& mask
) != tlb
->EPN
)
1026 *raddrp
= (tlb
->RPN
& mask
) | (address
& ~mask
);
1027 #if (TARGET_PHYS_ADDR_BITS >= 36)
1029 /* Extend the physical address to 36 bits */
1030 *raddrp
|= (target_phys_addr_t
)(tlb
->RPN
& 0xF) << 32;
1037 /* Generic TLB search function for PowerPC embedded implementations */
1038 int ppcemb_tlb_search (CPUPPCState
*env
, target_ulong address
, uint32_t pid
)
1041 target_phys_addr_t raddr
;
1044 /* Default return value is no match */
1046 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1047 tlb
= &env
->tlb
.tlbe
[i
];
1048 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
, pid
, 0, i
) == 0) {
1057 /* Helpers specific to PowerPC 40x implementations */
1058 static inline void ppc4xx_tlb_invalidate_all(CPUPPCState
*env
)
1063 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1064 tlb
= &env
->tlb
.tlbe
[i
];
1065 tlb
->prot
&= ~PAGE_VALID
;
1070 static inline void ppc4xx_tlb_invalidate_virt(CPUPPCState
*env
,
1071 target_ulong eaddr
, uint32_t pid
)
1073 #if !defined(FLUSH_ALL_TLBS)
1075 target_phys_addr_t raddr
;
1076 target_ulong page
, end
;
1079 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1080 tlb
= &env
->tlb
.tlbe
[i
];
1081 if (ppcemb_tlb_check(env
, tlb
, &raddr
, eaddr
, pid
, 0, i
) == 0) {
1082 end
= tlb
->EPN
+ tlb
->size
;
1083 for (page
= tlb
->EPN
; page
< end
; page
+= TARGET_PAGE_SIZE
)
1084 tlb_flush_page(env
, page
);
1085 tlb
->prot
&= ~PAGE_VALID
;
1090 ppc4xx_tlb_invalidate_all(env
);
1094 static int mmu40x_get_physical_address (CPUPPCState
*env
, mmu_ctx_t
*ctx
,
1095 target_ulong address
, int rw
, int access_type
)
1098 target_phys_addr_t raddr
;
1099 int i
, ret
, zsel
, zpr
, pr
;
1102 raddr
= (target_phys_addr_t
)-1ULL;
1104 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1105 tlb
= &env
->tlb
.tlbe
[i
];
1106 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
,
1107 env
->spr
[SPR_40x_PID
], 0, i
) < 0)
1109 zsel
= (tlb
->attr
>> 4) & 0xF;
1110 zpr
= (env
->spr
[SPR_40x_ZPR
] >> (30 - (2 * zsel
))) & 0x3;
1111 LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1112 __func__
, i
, zsel
, zpr
, rw
, tlb
->attr
);
1113 /* Check execute enable bit */
1120 /* All accesses granted */
1121 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
1126 /* Raise Zone protection fault. */
1127 env
->spr
[SPR_40x_ESR
] = 1 << 22;
1135 /* Check from TLB entry */
1136 ctx
->prot
= tlb
->prot
;
1137 ret
= check_prot(ctx
->prot
, rw
, access_type
);
1139 env
->spr
[SPR_40x_ESR
] = 0;
1144 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1145 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1150 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1151 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1156 void store_40x_sler (CPUPPCState
*env
, uint32_t val
)
1158 /* XXX: TO BE FIXED */
1159 if (val
!= 0x00000000) {
1160 cpu_abort(env
, "Little-endian regions are not supported by now\n");
1162 env
->spr
[SPR_405_SLER
] = val
;
1165 static inline int mmubooke_check_tlb (CPUPPCState
*env
, ppcemb_tlb_t
*tlb
,
1166 target_phys_addr_t
*raddr
, int *prot
,
1167 target_ulong address
, int rw
,
1168 int access_type
, int i
)
1172 if (ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1173 env
->spr
[SPR_BOOKE_PID
],
1174 !env
->nb_pids
, i
) >= 0) {
1178 if (env
->spr
[SPR_BOOKE_PID1
] &&
1179 ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1180 env
->spr
[SPR_BOOKE_PID1
], 0, i
) >= 0) {
1184 if (env
->spr
[SPR_BOOKE_PID2
] &&
1185 ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1186 env
->spr
[SPR_BOOKE_PID2
], 0, i
) >= 0) {
1190 LOG_SWTLB("%s: TLB entry not found\n", __func__
);
1196 _prot
= tlb
->prot
& 0xF;
1198 _prot
= (tlb
->prot
>> 4) & 0xF;
1201 /* Check the address space */
1202 if (access_type
== ACCESS_CODE
) {
1203 if (msr_ir
!= (tlb
->attr
& 1)) {
1204 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1209 if (_prot
& PAGE_EXEC
) {
1210 LOG_SWTLB("%s: good TLB!\n", __func__
);
1214 LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__
, _prot
);
1217 if (msr_dr
!= (tlb
->attr
& 1)) {
1218 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1223 if ((!rw
&& _prot
& PAGE_READ
) || (rw
&& (_prot
& PAGE_WRITE
))) {
1224 LOG_SWTLB("%s: found TLB!\n", __func__
);
1228 LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__
, _prot
);
1235 static int mmubooke_get_physical_address (CPUPPCState
*env
, mmu_ctx_t
*ctx
,
1236 target_ulong address
, int rw
,
1240 target_phys_addr_t raddr
;
1244 raddr
= (target_phys_addr_t
)-1ULL;
1245 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1246 tlb
= &env
->tlb
.tlbe
[i
];
1247 ret
= mmubooke_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
, rw
,
1256 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1257 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1260 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1261 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1267 void booke206_flush_tlb(CPUPPCState
*env
, int flags
, const int check_iprot
)
1271 ppcmas_tlb_t
*tlb
= env
->tlb
.tlbm
;
1273 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1274 if (flags
& (1 << i
)) {
1275 tlb_size
= booke206_tlb_size(env
, i
);
1276 for (j
= 0; j
< tlb_size
; j
++) {
1277 if (!check_iprot
|| !(tlb
[j
].mas1
& MAS1_IPROT
)) {
1278 tlb
[j
].mas1
&= ~MAS1_VALID
;
1282 tlb
+= booke206_tlb_size(env
, i
);
1288 target_phys_addr_t
booke206_tlb_to_page_size(CPUPPCState
*env
, ppcmas_tlb_t
*tlb
)
1292 tlbm_size
= (tlb
->mas1
& MAS1_TSIZE_MASK
) >> MAS1_TSIZE_SHIFT
;
1294 return 1024ULL << tlbm_size
;
1297 /* TLB check function for MAS based SoftTLBs */
1298 int ppcmas_tlb_check(CPUPPCState
*env
, ppcmas_tlb_t
*tlb
,
1299 target_phys_addr_t
*raddrp
,
1300 target_ulong address
, uint32_t pid
)
1305 /* Check valid flag */
1306 if (!(tlb
->mas1
& MAS1_VALID
)) {
1310 mask
= ~(booke206_tlb_to_page_size(env
, tlb
) - 1);
1311 LOG_SWTLB("%s: TLB ADDR=0x" TARGET_FMT_lx
" PID=0x%x MAS1=0x%x MAS2=0x%"
1312 PRIx64
" mask=0x" TARGET_FMT_lx
" MAS7_3=0x%" PRIx64
" MAS8=%x\n",
1313 __func__
, address
, pid
, tlb
->mas1
, tlb
->mas2
, mask
, tlb
->mas7_3
,
1317 tlb_pid
= (tlb
->mas1
& MAS1_TID_MASK
) >> MAS1_TID_SHIFT
;
1318 if (tlb_pid
!= 0 && tlb_pid
!= pid
) {
1322 /* Check effective address */
1323 if ((address
& mask
) != (tlb
->mas2
& MAS2_EPN_MASK
)) {
1328 *raddrp
= (tlb
->mas7_3
& mask
) | (address
& ~mask
);
1334 static int mmubooke206_check_tlb(CPUPPCState
*env
, ppcmas_tlb_t
*tlb
,
1335 target_phys_addr_t
*raddr
, int *prot
,
1336 target_ulong address
, int rw
,
1342 if (ppcmas_tlb_check(env
, tlb
, raddr
, address
,
1343 env
->spr
[SPR_BOOKE_PID
]) >= 0) {
1347 if (env
->spr
[SPR_BOOKE_PID1
] &&
1348 ppcmas_tlb_check(env
, tlb
, raddr
, address
,
1349 env
->spr
[SPR_BOOKE_PID1
]) >= 0) {
1353 if (env
->spr
[SPR_BOOKE_PID2
] &&
1354 ppcmas_tlb_check(env
, tlb
, raddr
, address
,
1355 env
->spr
[SPR_BOOKE_PID2
]) >= 0) {
1359 LOG_SWTLB("%s: TLB entry not found\n", __func__
);
1365 if (tlb
->mas7_3
& MAS3_UR
) {
1368 if (tlb
->mas7_3
& MAS3_UW
) {
1369 _prot
|= PAGE_WRITE
;
1371 if (tlb
->mas7_3
& MAS3_UX
) {
1375 if (tlb
->mas7_3
& MAS3_SR
) {
1378 if (tlb
->mas7_3
& MAS3_SW
) {
1379 _prot
|= PAGE_WRITE
;
1381 if (tlb
->mas7_3
& MAS3_SX
) {
1386 /* Check the address space and permissions */
1387 if (access_type
== ACCESS_CODE
) {
1388 if (msr_ir
!= ((tlb
->mas1
& MAS1_TS
) >> MAS1_TS_SHIFT
)) {
1389 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1394 if (_prot
& PAGE_EXEC
) {
1395 LOG_SWTLB("%s: good TLB!\n", __func__
);
1399 LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__
, _prot
);
1402 if (msr_dr
!= ((tlb
->mas1
& MAS1_TS
) >> MAS1_TS_SHIFT
)) {
1403 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1408 if ((!rw
&& _prot
& PAGE_READ
) || (rw
&& (_prot
& PAGE_WRITE
))) {
1409 LOG_SWTLB("%s: found TLB!\n", __func__
);
1413 LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__
, _prot
);
1420 static int mmubooke206_get_physical_address(CPUPPCState
*env
, mmu_ctx_t
*ctx
,
1421 target_ulong address
, int rw
,
1425 target_phys_addr_t raddr
;
1429 raddr
= (target_phys_addr_t
)-1ULL;
1431 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1432 int ways
= booke206_tlb_ways(env
, i
);
1434 for (j
= 0; j
< ways
; j
++) {
1435 tlb
= booke206_get_tlbm(env
, i
, address
, j
);
1439 ret
= mmubooke206_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
,
1451 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1452 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1455 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1456 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1462 static const char *book3e_tsize_to_str
[32] = {
1463 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
1464 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M",
1465 "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G",
1469 static void mmubooke206_dump_one_tlb(FILE *f
, fprintf_function cpu_fprintf
,
1470 CPUPPCState
*env
, int tlbn
, int offset
,
1473 ppcmas_tlb_t
*entry
;
1476 cpu_fprintf(f
, "\nTLB%d:\n", tlbn
);
1477 cpu_fprintf(f
, "Effective Physical Size TID TS SRWX URWX WIMGE U0123\n");
1479 entry
= &env
->tlb
.tlbm
[offset
];
1480 for (i
= 0; i
< tlbsize
; i
++, entry
++) {
1481 target_phys_addr_t ea
, pa
, size
;
1484 if (!(entry
->mas1
& MAS1_VALID
)) {
1488 tsize
= (entry
->mas1
& MAS1_TSIZE_MASK
) >> MAS1_TSIZE_SHIFT
;
1489 size
= 1024ULL << tsize
;
1490 ea
= entry
->mas2
& ~(size
- 1);
1491 pa
= entry
->mas7_3
& ~(size
- 1);
1493 cpu_fprintf(f
, "0x%016" PRIx64
" 0x%016" PRIx64
" %4s %-5u %1u S%c%c%c U%c%c%c %c%c%c%c%c U%c%c%c%c\n",
1494 (uint64_t)ea
, (uint64_t)pa
,
1495 book3e_tsize_to_str
[tsize
],
1496 (entry
->mas1
& MAS1_TID_MASK
) >> MAS1_TID_SHIFT
,
1497 (entry
->mas1
& MAS1_TS
) >> MAS1_TS_SHIFT
,
1498 entry
->mas7_3
& MAS3_SR
? 'R' : '-',
1499 entry
->mas7_3
& MAS3_SW
? 'W' : '-',
1500 entry
->mas7_3
& MAS3_SX
? 'X' : '-',
1501 entry
->mas7_3
& MAS3_UR
? 'R' : '-',
1502 entry
->mas7_3
& MAS3_UW
? 'W' : '-',
1503 entry
->mas7_3
& MAS3_UX
? 'X' : '-',
1504 entry
->mas2
& MAS2_W
? 'W' : '-',
1505 entry
->mas2
& MAS2_I
? 'I' : '-',
1506 entry
->mas2
& MAS2_M
? 'M' : '-',
1507 entry
->mas2
& MAS2_G
? 'G' : '-',
1508 entry
->mas2
& MAS2_E
? 'E' : '-',
1509 entry
->mas7_3
& MAS3_U0
? '0' : '-',
1510 entry
->mas7_3
& MAS3_U1
? '1' : '-',
1511 entry
->mas7_3
& MAS3_U2
? '2' : '-',
1512 entry
->mas7_3
& MAS3_U3
? '3' : '-');
1516 static void mmubooke206_dump_mmu(FILE *f
, fprintf_function cpu_fprintf
,
1522 if (kvm_enabled() && !env
->kvm_sw_tlb
) {
1523 cpu_fprintf(f
, "Cannot access KVM TLB\n");
1527 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1528 int size
= booke206_tlb_size(env
, i
);
1534 mmubooke206_dump_one_tlb(f
, cpu_fprintf
, env
, i
, offset
, size
);
1539 #if defined(TARGET_PPC64)
1540 static void mmubooks_dump_mmu(FILE *f
, fprintf_function cpu_fprintf
,
1544 uint64_t slbe
, slbv
;
1546 cpu_synchronize_state(env
);
1548 cpu_fprintf(f
, "SLB\tESID\t\t\tVSID\n");
1549 for (i
= 0; i
< env
->slb_nr
; i
++) {
1550 slbe
= env
->slb
[i
].esid
;
1551 slbv
= env
->slb
[i
].vsid
;
1552 if (slbe
== 0 && slbv
== 0) {
1555 cpu_fprintf(f
, "%d\t0x%016" PRIx64
"\t0x%016" PRIx64
"\n",
1561 void dump_mmu(FILE *f
, fprintf_function cpu_fprintf
, CPUPPCState
*env
)
1563 switch (env
->mmu_model
) {
1564 case POWERPC_MMU_BOOKE206
:
1565 mmubooke206_dump_mmu(f
, cpu_fprintf
, env
);
1567 #if defined(TARGET_PPC64)
1568 case POWERPC_MMU_64B
:
1569 case POWERPC_MMU_2_06
:
1570 mmubooks_dump_mmu(f
, cpu_fprintf
, env
);
1574 cpu_fprintf(f
, "%s: unimplemented\n", __func__
);
1578 static inline int check_physical(CPUPPCState
*env
, mmu_ctx_t
*ctx
,
1579 target_ulong eaddr
, int rw
)
1584 ctx
->prot
= PAGE_READ
| PAGE_EXEC
;
1586 switch (env
->mmu_model
) {
1587 case POWERPC_MMU_32B
:
1588 case POWERPC_MMU_601
:
1589 case POWERPC_MMU_SOFT_6xx
:
1590 case POWERPC_MMU_SOFT_74xx
:
1591 case POWERPC_MMU_SOFT_4xx
:
1592 case POWERPC_MMU_REAL
:
1593 case POWERPC_MMU_BOOKE
:
1594 ctx
->prot
|= PAGE_WRITE
;
1596 #if defined(TARGET_PPC64)
1597 case POWERPC_MMU_620
:
1598 case POWERPC_MMU_64B
:
1599 case POWERPC_MMU_2_06
:
1600 /* Real address are 60 bits long */
1601 ctx
->raddr
&= 0x0FFFFFFFFFFFFFFFULL
;
1602 ctx
->prot
|= PAGE_WRITE
;
1605 case POWERPC_MMU_SOFT_4xx_Z
:
1606 if (unlikely(msr_pe
!= 0)) {
1607 /* 403 family add some particular protections,
1608 * using PBL/PBU registers for accesses with no translation.
1611 /* Check PLB validity */
1612 (env
->pb
[0] < env
->pb
[1] &&
1613 /* and address in plb area */
1614 eaddr
>= env
->pb
[0] && eaddr
< env
->pb
[1]) ||
1615 (env
->pb
[2] < env
->pb
[3] &&
1616 eaddr
>= env
->pb
[2] && eaddr
< env
->pb
[3]) ? 1 : 0;
1617 if (in_plb
^ msr_px
) {
1618 /* Access in protected area */
1620 /* Access is not allowed */
1624 /* Read-write access is allowed */
1625 ctx
->prot
|= PAGE_WRITE
;
1629 case POWERPC_MMU_MPC8xx
:
1631 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1633 case POWERPC_MMU_BOOKE206
:
1634 cpu_abort(env
, "BookE 2.06 MMU doesn't have physical real mode\n");
1637 cpu_abort(env
, "Unknown or invalid MMU model\n");
1644 int get_physical_address (CPUPPCState
*env
, mmu_ctx_t
*ctx
, target_ulong eaddr
,
1645 int rw
, int access_type
)
1650 qemu_log("%s\n", __func__
);
1652 if ((access_type
== ACCESS_CODE
&& msr_ir
== 0) ||
1653 (access_type
!= ACCESS_CODE
&& msr_dr
== 0)) {
1654 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1655 /* The BookE MMU always performs address translation. The
1656 IS and DS bits only affect the address space. */
1657 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1659 } else if (env
->mmu_model
== POWERPC_MMU_BOOKE206
) {
1660 ret
= mmubooke206_get_physical_address(env
, ctx
, eaddr
, rw
,
1663 /* No address translation. */
1664 ret
= check_physical(env
, ctx
, eaddr
, rw
);
1668 switch (env
->mmu_model
) {
1669 case POWERPC_MMU_32B
:
1670 case POWERPC_MMU_601
:
1671 case POWERPC_MMU_SOFT_6xx
:
1672 case POWERPC_MMU_SOFT_74xx
:
1673 /* Try to find a BAT */
1674 if (env
->nb_BATs
!= 0)
1675 ret
= get_bat(env
, ctx
, eaddr
, rw
, access_type
);
1676 #if defined(TARGET_PPC64)
1677 case POWERPC_MMU_620
:
1678 case POWERPC_MMU_64B
:
1679 case POWERPC_MMU_2_06
:
1682 /* We didn't match any BAT entry or don't have BATs */
1683 ret
= get_segment(env
, ctx
, eaddr
, rw
, access_type
);
1686 case POWERPC_MMU_SOFT_4xx
:
1687 case POWERPC_MMU_SOFT_4xx_Z
:
1688 ret
= mmu40x_get_physical_address(env
, ctx
, eaddr
,
1691 case POWERPC_MMU_BOOKE
:
1692 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1695 case POWERPC_MMU_BOOKE206
:
1696 ret
= mmubooke206_get_physical_address(env
, ctx
, eaddr
, rw
,
1699 case POWERPC_MMU_MPC8xx
:
1701 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1703 case POWERPC_MMU_REAL
:
1704 cpu_abort(env
, "PowerPC in real mode do not do any translation\n");
1707 cpu_abort(env
, "Unknown or invalid MMU model\n");
1712 qemu_log("%s address " TARGET_FMT_lx
" => %d " TARGET_FMT_plx
"\n",
1713 __func__
, eaddr
, ret
, ctx
->raddr
);
1719 target_phys_addr_t
cpu_get_phys_page_debug (CPUPPCState
*env
, target_ulong addr
)
1723 if (unlikely(get_physical_address(env
, &ctx
, addr
, 0, ACCESS_INT
) != 0))
1726 return ctx
.raddr
& TARGET_PAGE_MASK
;
1729 static void booke206_update_mas_tlb_miss(CPUPPCState
*env
, target_ulong address
,
1732 env
->spr
[SPR_BOOKE_MAS0
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TLBSELD_MASK
;
1733 env
->spr
[SPR_BOOKE_MAS1
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TSIZED_MASK
;
1734 env
->spr
[SPR_BOOKE_MAS2
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_WIMGED_MASK
;
1735 env
->spr
[SPR_BOOKE_MAS3
] = 0;
1736 env
->spr
[SPR_BOOKE_MAS6
] = 0;
1737 env
->spr
[SPR_BOOKE_MAS7
] = 0;
1740 if (((rw
== 2) && msr_ir
) || ((rw
!= 2) && msr_dr
)) {
1741 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_TS
;
1742 env
->spr
[SPR_BOOKE_MAS6
] |= MAS6_SAS
;
1745 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_VALID
;
1746 env
->spr
[SPR_BOOKE_MAS2
] |= address
& MAS2_EPN_MASK
;
1748 switch (env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TIDSELD_PIDZ
) {
1749 case MAS4_TIDSELD_PID0
:
1750 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID
] << MAS1_TID_SHIFT
;
1752 case MAS4_TIDSELD_PID1
:
1753 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID1
] << MAS1_TID_SHIFT
;
1755 case MAS4_TIDSELD_PID2
:
1756 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID2
] << MAS1_TID_SHIFT
;
1760 env
->spr
[SPR_BOOKE_MAS6
] |= env
->spr
[SPR_BOOKE_PID
] << 16;
1762 /* next victim logic */
1763 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_ESEL_SHIFT
;
1765 env
->last_way
&= booke206_tlb_ways(env
, 0) - 1;
1766 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_NV_SHIFT
;
1769 /* Perform address translation */
1770 int cpu_ppc_handle_mmu_fault (CPUPPCState
*env
, target_ulong address
, int rw
,
1780 access_type
= ACCESS_CODE
;
1783 access_type
= env
->access_type
;
1785 ret
= get_physical_address(env
, &ctx
, address
, rw
, access_type
);
1787 tlb_set_page(env
, address
& TARGET_PAGE_MASK
,
1788 ctx
.raddr
& TARGET_PAGE_MASK
, ctx
.prot
,
1789 mmu_idx
, TARGET_PAGE_SIZE
);
1791 } else if (ret
< 0) {
1793 if (access_type
== ACCESS_CODE
) {
1796 /* No matches in page tables or TLB */
1797 switch (env
->mmu_model
) {
1798 case POWERPC_MMU_SOFT_6xx
:
1799 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1800 env
->error_code
= 1 << 18;
1801 env
->spr
[SPR_IMISS
] = address
;
1802 env
->spr
[SPR_ICMP
] = 0x80000000 | ctx
.ptem
;
1804 case POWERPC_MMU_SOFT_74xx
:
1805 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1807 case POWERPC_MMU_SOFT_4xx
:
1808 case POWERPC_MMU_SOFT_4xx_Z
:
1809 env
->exception_index
= POWERPC_EXCP_ITLB
;
1810 env
->error_code
= 0;
1811 env
->spr
[SPR_40x_DEAR
] = address
;
1812 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1814 case POWERPC_MMU_32B
:
1815 case POWERPC_MMU_601
:
1816 #if defined(TARGET_PPC64)
1817 case POWERPC_MMU_620
:
1818 case POWERPC_MMU_64B
:
1819 case POWERPC_MMU_2_06
:
1821 env
->exception_index
= POWERPC_EXCP_ISI
;
1822 env
->error_code
= 0x40000000;
1824 case POWERPC_MMU_BOOKE206
:
1825 booke206_update_mas_tlb_miss(env
, address
, rw
);
1827 case POWERPC_MMU_BOOKE
:
1828 env
->exception_index
= POWERPC_EXCP_ITLB
;
1829 env
->error_code
= 0;
1830 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1832 case POWERPC_MMU_MPC8xx
:
1834 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1836 case POWERPC_MMU_REAL
:
1837 cpu_abort(env
, "PowerPC in real mode should never raise "
1838 "any MMU exceptions\n");
1841 cpu_abort(env
, "Unknown or invalid MMU model\n");
1846 /* Access rights violation */
1847 env
->exception_index
= POWERPC_EXCP_ISI
;
1848 env
->error_code
= 0x08000000;
1851 /* No execute protection violation */
1852 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1853 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1854 env
->spr
[SPR_BOOKE_ESR
] = 0x00000000;
1856 env
->exception_index
= POWERPC_EXCP_ISI
;
1857 env
->error_code
= 0x10000000;
1860 /* Direct store exception */
1861 /* No code fetch is allowed in direct-store areas */
1862 env
->exception_index
= POWERPC_EXCP_ISI
;
1863 env
->error_code
= 0x10000000;
1865 #if defined(TARGET_PPC64)
1867 /* No match in segment table */
1868 if (env
->mmu_model
== POWERPC_MMU_620
) {
1869 env
->exception_index
= POWERPC_EXCP_ISI
;
1870 /* XXX: this might be incorrect */
1871 env
->error_code
= 0x40000000;
1873 env
->exception_index
= POWERPC_EXCP_ISEG
;
1874 env
->error_code
= 0;
1882 /* No matches in page tables or TLB */
1883 switch (env
->mmu_model
) {
1884 case POWERPC_MMU_SOFT_6xx
:
1886 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1887 env
->error_code
= 1 << 16;
1889 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1890 env
->error_code
= 0;
1892 env
->spr
[SPR_DMISS
] = address
;
1893 env
->spr
[SPR_DCMP
] = 0x80000000 | ctx
.ptem
;
1895 env
->error_code
|= ctx
.key
<< 19;
1896 env
->spr
[SPR_HASH1
] = env
->htab_base
+
1897 get_pteg_offset(env
, ctx
.hash
[0], HASH_PTE_SIZE_32
);
1898 env
->spr
[SPR_HASH2
] = env
->htab_base
+
1899 get_pteg_offset(env
, ctx
.hash
[1], HASH_PTE_SIZE_32
);
1901 case POWERPC_MMU_SOFT_74xx
:
1903 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1905 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1908 /* Implement LRU algorithm */
1909 env
->error_code
= ctx
.key
<< 19;
1910 env
->spr
[SPR_TLBMISS
] = (address
& ~((target_ulong
)0x3)) |
1911 ((env
->last_way
+ 1) & (env
->nb_ways
- 1));
1912 env
->spr
[SPR_PTEHI
] = 0x80000000 | ctx
.ptem
;
1914 case POWERPC_MMU_SOFT_4xx
:
1915 case POWERPC_MMU_SOFT_4xx_Z
:
1916 env
->exception_index
= POWERPC_EXCP_DTLB
;
1917 env
->error_code
= 0;
1918 env
->spr
[SPR_40x_DEAR
] = address
;
1920 env
->spr
[SPR_40x_ESR
] = 0x00800000;
1922 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1924 case POWERPC_MMU_32B
:
1925 case POWERPC_MMU_601
:
1926 #if defined(TARGET_PPC64)
1927 case POWERPC_MMU_620
:
1928 case POWERPC_MMU_64B
:
1929 case POWERPC_MMU_2_06
:
1931 env
->exception_index
= POWERPC_EXCP_DSI
;
1932 env
->error_code
= 0;
1933 env
->spr
[SPR_DAR
] = address
;
1935 env
->spr
[SPR_DSISR
] = 0x42000000;
1937 env
->spr
[SPR_DSISR
] = 0x40000000;
1939 case POWERPC_MMU_MPC8xx
:
1941 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1943 case POWERPC_MMU_BOOKE206
:
1944 booke206_update_mas_tlb_miss(env
, address
, rw
);
1946 case POWERPC_MMU_BOOKE
:
1947 env
->exception_index
= POWERPC_EXCP_DTLB
;
1948 env
->error_code
= 0;
1949 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1950 env
->spr
[SPR_BOOKE_ESR
] = rw
? ESR_ST
: 0;
1952 case POWERPC_MMU_REAL
:
1953 cpu_abort(env
, "PowerPC in real mode should never raise "
1954 "any MMU exceptions\n");
1957 cpu_abort(env
, "Unknown or invalid MMU model\n");
1962 /* Access rights violation */
1963 env
->exception_index
= POWERPC_EXCP_DSI
;
1964 env
->error_code
= 0;
1965 if (env
->mmu_model
== POWERPC_MMU_SOFT_4xx
1966 || env
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
) {
1967 env
->spr
[SPR_40x_DEAR
] = address
;
1969 env
->spr
[SPR_40x_ESR
] |= 0x00800000;
1971 } else if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1972 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1973 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1974 env
->spr
[SPR_BOOKE_ESR
] = rw
? ESR_ST
: 0;
1976 env
->spr
[SPR_DAR
] = address
;
1978 env
->spr
[SPR_DSISR
] = 0x0A000000;
1980 env
->spr
[SPR_DSISR
] = 0x08000000;
1985 /* Direct store exception */
1986 switch (access_type
) {
1988 /* Floating point load/store */
1989 env
->exception_index
= POWERPC_EXCP_ALIGN
;
1990 env
->error_code
= POWERPC_EXCP_ALIGN_FP
;
1991 env
->spr
[SPR_DAR
] = address
;
1994 /* lwarx, ldarx or stwcx. */
1995 env
->exception_index
= POWERPC_EXCP_DSI
;
1996 env
->error_code
= 0;
1997 env
->spr
[SPR_DAR
] = address
;
1999 env
->spr
[SPR_DSISR
] = 0x06000000;
2001 env
->spr
[SPR_DSISR
] = 0x04000000;
2004 /* eciwx or ecowx */
2005 env
->exception_index
= POWERPC_EXCP_DSI
;
2006 env
->error_code
= 0;
2007 env
->spr
[SPR_DAR
] = address
;
2009 env
->spr
[SPR_DSISR
] = 0x06100000;
2011 env
->spr
[SPR_DSISR
] = 0x04100000;
2014 printf("DSI: invalid exception (%d)\n", ret
);
2015 env
->exception_index
= POWERPC_EXCP_PROGRAM
;
2017 POWERPC_EXCP_INVAL
| POWERPC_EXCP_INVAL_INVAL
;
2018 env
->spr
[SPR_DAR
] = address
;
2022 #if defined(TARGET_PPC64)
2024 /* No match in segment table */
2025 if (env
->mmu_model
== POWERPC_MMU_620
) {
2026 env
->exception_index
= POWERPC_EXCP_DSI
;
2027 env
->error_code
= 0;
2028 env
->spr
[SPR_DAR
] = address
;
2029 /* XXX: this might be incorrect */
2031 env
->spr
[SPR_DSISR
] = 0x42000000;
2033 env
->spr
[SPR_DSISR
] = 0x40000000;
2035 env
->exception_index
= POWERPC_EXCP_DSEG
;
2036 env
->error_code
= 0;
2037 env
->spr
[SPR_DAR
] = address
;
2044 printf("%s: set exception to %d %02x\n", __func__
,
2045 env
->exception
, env
->error_code
);
2053 /*****************************************************************************/
2054 /* BATs management */
2055 #if !defined(FLUSH_ALL_TLBS)
2056 static inline void do_invalidate_BAT(CPUPPCState
*env
, target_ulong BATu
,
2059 target_ulong base
, end
, page
;
2061 base
= BATu
& ~0x0001FFFF;
2062 end
= base
+ mask
+ 0x00020000;
2063 LOG_BATS("Flush BAT from " TARGET_FMT_lx
" to " TARGET_FMT_lx
" ("
2064 TARGET_FMT_lx
")\n", base
, end
, mask
);
2065 for (page
= base
; page
!= end
; page
+= TARGET_PAGE_SIZE
)
2066 tlb_flush_page(env
, page
);
2067 LOG_BATS("Flush done\n");
2071 static inline void dump_store_bat(CPUPPCState
*env
, char ID
, int ul
, int nr
,
2074 LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx
" (" TARGET_FMT_lx
")\n", ID
,
2075 nr
, ul
== 0 ? 'u' : 'l', value
, env
->nip
);
2078 void ppc_store_ibatu (CPUPPCState
*env
, int nr
, target_ulong value
)
2082 dump_store_bat(env
, 'I', 0, nr
, value
);
2083 if (env
->IBAT
[0][nr
] != value
) {
2084 mask
= (value
<< 15) & 0x0FFE0000UL
;
2085 #if !defined(FLUSH_ALL_TLBS)
2086 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2088 /* When storing valid upper BAT, mask BEPI and BRPN
2089 * and invalidate all TLBs covered by this BAT
2091 mask
= (value
<< 15) & 0x0FFE0000UL
;
2092 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
2093 (value
& ~0x0001FFFFUL
& ~mask
);
2094 env
->IBAT
[1][nr
] = (env
->IBAT
[1][nr
] & 0x0000007B) |
2095 (env
->IBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
2096 #if !defined(FLUSH_ALL_TLBS)
2097 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2104 void ppc_store_ibatl (CPUPPCState
*env
, int nr
, target_ulong value
)
2106 dump_store_bat(env
, 'I', 1, nr
, value
);
2107 env
->IBAT
[1][nr
] = value
;
2110 void ppc_store_dbatu (CPUPPCState
*env
, int nr
, target_ulong value
)
2114 dump_store_bat(env
, 'D', 0, nr
, value
);
2115 if (env
->DBAT
[0][nr
] != value
) {
2116 /* When storing valid upper BAT, mask BEPI and BRPN
2117 * and invalidate all TLBs covered by this BAT
2119 mask
= (value
<< 15) & 0x0FFE0000UL
;
2120 #if !defined(FLUSH_ALL_TLBS)
2121 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
2123 mask
= (value
<< 15) & 0x0FFE0000UL
;
2124 env
->DBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
2125 (value
& ~0x0001FFFFUL
& ~mask
);
2126 env
->DBAT
[1][nr
] = (env
->DBAT
[1][nr
] & 0x0000007B) |
2127 (env
->DBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
2128 #if !defined(FLUSH_ALL_TLBS)
2129 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
2136 void ppc_store_dbatl (CPUPPCState
*env
, int nr
, target_ulong value
)
2138 dump_store_bat(env
, 'D', 1, nr
, value
);
2139 env
->DBAT
[1][nr
] = value
;
2142 void ppc_store_ibatu_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
2145 #if defined(FLUSH_ALL_TLBS)
2149 dump_store_bat(env
, 'I', 0, nr
, value
);
2150 if (env
->IBAT
[0][nr
] != value
) {
2151 #if defined(FLUSH_ALL_TLBS)
2154 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
2155 if (env
->IBAT
[1][nr
] & 0x40) {
2156 /* Invalidate BAT only if it is valid */
2157 #if !defined(FLUSH_ALL_TLBS)
2158 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2163 /* When storing valid upper BAT, mask BEPI and BRPN
2164 * and invalidate all TLBs covered by this BAT
2166 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
2167 (value
& ~0x0001FFFFUL
& ~mask
);
2168 env
->DBAT
[0][nr
] = env
->IBAT
[0][nr
];
2169 if (env
->IBAT
[1][nr
] & 0x40) {
2170 #if !defined(FLUSH_ALL_TLBS)
2171 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2176 #if defined(FLUSH_ALL_TLBS)
2183 void ppc_store_ibatl_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
2186 #if defined(FLUSH_ALL_TLBS)
2190 dump_store_bat(env
, 'I', 1, nr
, value
);
2191 if (env
->IBAT
[1][nr
] != value
) {
2192 #if defined(FLUSH_ALL_TLBS)
2195 if (env
->IBAT
[1][nr
] & 0x40) {
2196 #if !defined(FLUSH_ALL_TLBS)
2197 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
2198 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2204 #if !defined(FLUSH_ALL_TLBS)
2205 mask
= (value
<< 17) & 0x0FFE0000UL
;
2206 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2211 env
->IBAT
[1][nr
] = value
;
2212 env
->DBAT
[1][nr
] = value
;
2213 #if defined(FLUSH_ALL_TLBS)
2220 /*****************************************************************************/
2221 /* TLB management */
2222 void ppc_tlb_invalidate_all (CPUPPCState
*env
)
2224 switch (env
->mmu_model
) {
2225 case POWERPC_MMU_SOFT_6xx
:
2226 case POWERPC_MMU_SOFT_74xx
:
2227 ppc6xx_tlb_invalidate_all(env
);
2229 case POWERPC_MMU_SOFT_4xx
:
2230 case POWERPC_MMU_SOFT_4xx_Z
:
2231 ppc4xx_tlb_invalidate_all(env
);
2233 case POWERPC_MMU_REAL
:
2234 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
2236 case POWERPC_MMU_MPC8xx
:
2238 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
2240 case POWERPC_MMU_BOOKE
:
2243 case POWERPC_MMU_BOOKE206
:
2244 booke206_flush_tlb(env
, -1, 0);
2246 case POWERPC_MMU_32B
:
2247 case POWERPC_MMU_601
:
2248 #if defined(TARGET_PPC64)
2249 case POWERPC_MMU_620
:
2250 case POWERPC_MMU_64B
:
2251 case POWERPC_MMU_2_06
:
2252 #endif /* defined(TARGET_PPC64) */
2257 cpu_abort(env
, "Unknown MMU model\n");
2262 void ppc_tlb_invalidate_one (CPUPPCState
*env
, target_ulong addr
)
2264 #if !defined(FLUSH_ALL_TLBS)
2265 addr
&= TARGET_PAGE_MASK
;
2266 switch (env
->mmu_model
) {
2267 case POWERPC_MMU_SOFT_6xx
:
2268 case POWERPC_MMU_SOFT_74xx
:
2269 ppc6xx_tlb_invalidate_virt(env
, addr
, 0);
2270 if (env
->id_tlbs
== 1)
2271 ppc6xx_tlb_invalidate_virt(env
, addr
, 1);
2273 case POWERPC_MMU_SOFT_4xx
:
2274 case POWERPC_MMU_SOFT_4xx_Z
:
2275 ppc4xx_tlb_invalidate_virt(env
, addr
, env
->spr
[SPR_40x_PID
]);
2277 case POWERPC_MMU_REAL
:
2278 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
2280 case POWERPC_MMU_MPC8xx
:
2282 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
2284 case POWERPC_MMU_BOOKE
:
2286 cpu_abort(env
, "BookE MMU model is not implemented\n");
2288 case POWERPC_MMU_BOOKE206
:
2290 cpu_abort(env
, "BookE 2.06 MMU model is not implemented\n");
2292 case POWERPC_MMU_32B
:
2293 case POWERPC_MMU_601
:
2294 /* tlbie invalidate TLBs for all segments */
2295 addr
&= ~((target_ulong
)-1ULL << 28);
2296 /* XXX: this case should be optimized,
2297 * giving a mask to tlb_flush_page
2299 tlb_flush_page(env
, addr
| (0x0 << 28));
2300 tlb_flush_page(env
, addr
| (0x1 << 28));
2301 tlb_flush_page(env
, addr
| (0x2 << 28));
2302 tlb_flush_page(env
, addr
| (0x3 << 28));
2303 tlb_flush_page(env
, addr
| (0x4 << 28));
2304 tlb_flush_page(env
, addr
| (0x5 << 28));
2305 tlb_flush_page(env
, addr
| (0x6 << 28));
2306 tlb_flush_page(env
, addr
| (0x7 << 28));
2307 tlb_flush_page(env
, addr
| (0x8 << 28));
2308 tlb_flush_page(env
, addr
| (0x9 << 28));
2309 tlb_flush_page(env
, addr
| (0xA << 28));
2310 tlb_flush_page(env
, addr
| (0xB << 28));
2311 tlb_flush_page(env
, addr
| (0xC << 28));
2312 tlb_flush_page(env
, addr
| (0xD << 28));
2313 tlb_flush_page(env
, addr
| (0xE << 28));
2314 tlb_flush_page(env
, addr
| (0xF << 28));
2316 #if defined(TARGET_PPC64)
2317 case POWERPC_MMU_620
:
2318 case POWERPC_MMU_64B
:
2319 case POWERPC_MMU_2_06
:
2320 /* tlbie invalidate TLBs for all segments */
2321 /* XXX: given the fact that there are too many segments to invalidate,
2322 * and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
2323 * we just invalidate all TLBs
2327 #endif /* defined(TARGET_PPC64) */
2330 cpu_abort(env
, "Unknown MMU model\n");
2334 ppc_tlb_invalidate_all(env
);
2338 /*****************************************************************************/
2339 /* Special registers manipulation */
2340 #if defined(TARGET_PPC64)
2341 void ppc_store_asr (CPUPPCState
*env
, target_ulong value
)
2343 if (env
->asr
!= value
) {
2350 void ppc_store_sdr1 (CPUPPCState
*env
, target_ulong value
)
2352 LOG_MMU("%s: " TARGET_FMT_lx
"\n", __func__
, value
);
2353 if (env
->spr
[SPR_SDR1
] != value
) {
2354 env
->spr
[SPR_SDR1
] = value
;
2355 #if defined(TARGET_PPC64)
2356 if (env
->mmu_model
& POWERPC_MMU_64
) {
2357 target_ulong htabsize
= value
& SDR_64_HTABSIZE
;
2359 if (htabsize
> 28) {
2360 fprintf(stderr
, "Invalid HTABSIZE 0x" TARGET_FMT_lx
2361 " stored in SDR1\n", htabsize
);
2364 env
->htab_mask
= (1ULL << (htabsize
+ 18)) - 1;
2365 env
->htab_base
= value
& SDR_64_HTABORG
;
2367 #endif /* defined(TARGET_PPC64) */
2369 /* FIXME: Should check for valid HTABMASK values */
2370 env
->htab_mask
= ((value
& SDR_32_HTABMASK
) << 16) | 0xFFFF;
2371 env
->htab_base
= value
& SDR_32_HTABORG
;
2377 #if defined(TARGET_PPC64)
2378 target_ulong
ppc_load_sr (CPUPPCState
*env
, int slb_nr
)
2385 void ppc_store_sr (CPUPPCState
*env
, int srnum
, target_ulong value
)
2387 LOG_MMU("%s: reg=%d " TARGET_FMT_lx
" " TARGET_FMT_lx
"\n", __func__
,
2388 srnum
, value
, env
->sr
[srnum
]);
2389 #if defined(TARGET_PPC64)
2390 if (env
->mmu_model
& POWERPC_MMU_64
) {
2391 uint64_t rb
= 0, rs
= 0;
2394 rb
|= ((uint32_t)srnum
& 0xf) << 28;
2395 /* Set the valid bit */
2398 rb
|= (uint32_t)srnum
;
2401 rs
|= (value
& 0xfffffff) << 12;
2403 rs
|= ((value
>> 27) & 0xf) << 8;
2405 ppc_store_slb(env
, rb
, rs
);
2408 if (env
->sr
[srnum
] != value
) {
2409 env
->sr
[srnum
] = value
;
2410 /* Invalidating 256MB of virtual memory in 4kB pages is way longer than
2411 flusing the whole TLB. */
2412 #if !defined(FLUSH_ALL_TLBS) && 0
2414 target_ulong page
, end
;
2415 /* Invalidate 256 MB of virtual memory */
2416 page
= (16 << 20) * srnum
;
2417 end
= page
+ (16 << 20);
2418 for (; page
!= end
; page
+= TARGET_PAGE_SIZE
)
2419 tlb_flush_page(env
, page
);
2426 #endif /* !defined (CONFIG_USER_ONLY) */
2428 /* GDBstub can read and write MSR... */
2429 void ppc_store_msr (CPUPPCState
*env
, target_ulong value
)
2431 hreg_store_msr(env
, value
, 0);
2434 /*****************************************************************************/
2435 /* Exception processing */
2436 #if defined (CONFIG_USER_ONLY)
2437 void do_interrupt (CPUPPCState
*env
)
2439 env
->exception_index
= POWERPC_EXCP_NONE
;
2440 env
->error_code
= 0;
2443 void ppc_hw_interrupt (CPUPPCState
*env
)
2445 env
->exception_index
= POWERPC_EXCP_NONE
;
2446 env
->error_code
= 0;
2448 #else /* defined (CONFIG_USER_ONLY) */
2449 static inline void dump_syscall(CPUPPCState
*env
)
2451 qemu_log_mask(CPU_LOG_INT
, "syscall r0=%016" PRIx64
" r3=%016" PRIx64
2452 " r4=%016" PRIx64
" r5=%016" PRIx64
" r6=%016" PRIx64
2453 " nip=" TARGET_FMT_lx
"\n",
2454 ppc_dump_gpr(env
, 0), ppc_dump_gpr(env
, 3),
2455 ppc_dump_gpr(env
, 4), ppc_dump_gpr(env
, 5),
2456 ppc_dump_gpr(env
, 6), env
->nip
);
2459 /* Note that this function should be greatly optimized
2460 * when called with a constant excp, from ppc_hw_interrupt
2462 static inline void powerpc_excp(CPUPPCState
*env
, int excp_model
, int excp
)
2464 target_ulong msr
, new_msr
, vector
;
2465 int srr0
, srr1
, asrr0
, asrr1
;
2466 int lpes0
, lpes1
, lev
;
2469 /* XXX: find a suitable condition to enable the hypervisor mode */
2470 lpes0
= (env
->spr
[SPR_LPCR
] >> 1) & 1;
2471 lpes1
= (env
->spr
[SPR_LPCR
] >> 2) & 1;
2473 /* Those values ensure we won't enter the hypervisor mode */
2478 qemu_log_mask(CPU_LOG_INT
, "Raise exception at " TARGET_FMT_lx
2479 " => %08x (%02x)\n", env
->nip
, excp
, env
->error_code
);
2481 /* new srr1 value excluding must-be-zero bits */
2482 msr
= env
->msr
& ~0x783f0000ULL
;
2484 /* new interrupt handler msr */
2485 new_msr
= env
->msr
& ((target_ulong
)1 << MSR_ME
);
2487 /* target registers */
2494 case POWERPC_EXCP_NONE
:
2495 /* Should never happen */
2497 case POWERPC_EXCP_CRITICAL
: /* Critical input */
2498 switch (excp_model
) {
2499 case POWERPC_EXCP_40x
:
2500 srr0
= SPR_40x_SRR2
;
2501 srr1
= SPR_40x_SRR3
;
2503 case POWERPC_EXCP_BOOKE
:
2504 srr0
= SPR_BOOKE_CSRR0
;
2505 srr1
= SPR_BOOKE_CSRR1
;
2507 case POWERPC_EXCP_G2
:
2513 case POWERPC_EXCP_MCHECK
: /* Machine check exception */
2515 /* Machine check exception is not enabled.
2516 * Enter checkstop state.
2518 if (qemu_log_enabled()) {
2519 qemu_log("Machine check while not allowed. "
2520 "Entering checkstop state\n");
2522 fprintf(stderr
, "Machine check while not allowed. "
2523 "Entering checkstop state\n");
2526 env
->interrupt_request
|= CPU_INTERRUPT_EXITTB
;
2529 /* XXX: find a suitable condition to enable the hypervisor mode */
2530 new_msr
|= (target_ulong
)MSR_HVB
;
2533 /* machine check exceptions don't have ME set */
2534 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2536 /* XXX: should also have something loaded in DAR / DSISR */
2537 switch (excp_model
) {
2538 case POWERPC_EXCP_40x
:
2539 srr0
= SPR_40x_SRR2
;
2540 srr1
= SPR_40x_SRR3
;
2542 case POWERPC_EXCP_BOOKE
:
2543 srr0
= SPR_BOOKE_MCSRR0
;
2544 srr1
= SPR_BOOKE_MCSRR1
;
2545 asrr0
= SPR_BOOKE_CSRR0
;
2546 asrr1
= SPR_BOOKE_CSRR1
;
2552 case POWERPC_EXCP_DSI
: /* Data storage exception */
2553 LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx
" DAR=" TARGET_FMT_lx
2554 "\n", env
->spr
[SPR_DSISR
], env
->spr
[SPR_DAR
]);
2556 new_msr
|= (target_ulong
)MSR_HVB
;
2558 case POWERPC_EXCP_ISI
: /* Instruction storage exception */
2559 LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx
", nip=" TARGET_FMT_lx
2560 "\n", msr
, env
->nip
);
2562 new_msr
|= (target_ulong
)MSR_HVB
;
2563 msr
|= env
->error_code
;
2565 case POWERPC_EXCP_EXTERNAL
: /* External input */
2567 new_msr
|= (target_ulong
)MSR_HVB
;
2569 case POWERPC_EXCP_ALIGN
: /* Alignment exception */
2571 new_msr
|= (target_ulong
)MSR_HVB
;
2572 /* XXX: this is false */
2573 /* Get rS/rD and rA from faulting opcode */
2574 env
->spr
[SPR_DSISR
] |= (ldl_code((env
->nip
- 4)) & 0x03FF0000) >> 16;
2576 case POWERPC_EXCP_PROGRAM
: /* Program exception */
2577 switch (env
->error_code
& ~0xF) {
2578 case POWERPC_EXCP_FP
:
2579 if ((msr_fe0
== 0 && msr_fe1
== 0) || msr_fp
== 0) {
2580 LOG_EXCP("Ignore floating point exception\n");
2581 env
->exception_index
= POWERPC_EXCP_NONE
;
2582 env
->error_code
= 0;
2586 new_msr
|= (target_ulong
)MSR_HVB
;
2588 if (msr_fe0
== msr_fe1
)
2592 case POWERPC_EXCP_INVAL
:
2593 LOG_EXCP("Invalid instruction at " TARGET_FMT_lx
"\n", env
->nip
);
2595 new_msr
|= (target_ulong
)MSR_HVB
;
2597 env
->spr
[SPR_BOOKE_ESR
] = ESR_PIL
;
2599 case POWERPC_EXCP_PRIV
:
2601 new_msr
|= (target_ulong
)MSR_HVB
;
2603 env
->spr
[SPR_BOOKE_ESR
] = ESR_PPR
;
2605 case POWERPC_EXCP_TRAP
:
2607 new_msr
|= (target_ulong
)MSR_HVB
;
2609 env
->spr
[SPR_BOOKE_ESR
] = ESR_PTR
;
2612 /* Should never occur */
2613 cpu_abort(env
, "Invalid program exception %d. Aborting\n",
2618 case POWERPC_EXCP_FPU
: /* Floating-point unavailable exception */
2620 new_msr
|= (target_ulong
)MSR_HVB
;
2622 case POWERPC_EXCP_SYSCALL
: /* System call exception */
2624 lev
= env
->error_code
;
2625 if ((lev
== 1) && cpu_ppc_hypercall
) {
2626 cpu_ppc_hypercall(env
);
2629 if (lev
== 1 || (lpes0
== 0 && lpes1
== 0))
2630 new_msr
|= (target_ulong
)MSR_HVB
;
2632 case POWERPC_EXCP_APU
: /* Auxiliary processor unavailable */
2634 case POWERPC_EXCP_DECR
: /* Decrementer exception */
2636 new_msr
|= (target_ulong
)MSR_HVB
;
2638 case POWERPC_EXCP_FIT
: /* Fixed-interval timer interrupt */
2640 LOG_EXCP("FIT exception\n");
2642 case POWERPC_EXCP_WDT
: /* Watchdog timer interrupt */
2643 LOG_EXCP("WDT exception\n");
2644 switch (excp_model
) {
2645 case POWERPC_EXCP_BOOKE
:
2646 srr0
= SPR_BOOKE_CSRR0
;
2647 srr1
= SPR_BOOKE_CSRR1
;
2653 case POWERPC_EXCP_DTLB
: /* Data TLB error */
2655 case POWERPC_EXCP_ITLB
: /* Instruction TLB error */
2657 case POWERPC_EXCP_DEBUG
: /* Debug interrupt */
2658 switch (excp_model
) {
2659 case POWERPC_EXCP_BOOKE
:
2660 srr0
= SPR_BOOKE_DSRR0
;
2661 srr1
= SPR_BOOKE_DSRR1
;
2662 asrr0
= SPR_BOOKE_CSRR0
;
2663 asrr1
= SPR_BOOKE_CSRR1
;
2669 cpu_abort(env
, "Debug exception is not implemented yet !\n");
2671 case POWERPC_EXCP_SPEU
: /* SPE/embedded floating-point unavailable */
2672 env
->spr
[SPR_BOOKE_ESR
] = ESR_SPV
;
2674 case POWERPC_EXCP_EFPDI
: /* Embedded floating-point data interrupt */
2676 cpu_abort(env
, "Embedded floating point data exception "
2677 "is not implemented yet !\n");
2678 env
->spr
[SPR_BOOKE_ESR
] = ESR_SPV
;
2680 case POWERPC_EXCP_EFPRI
: /* Embedded floating-point round interrupt */
2682 cpu_abort(env
, "Embedded floating point round exception "
2683 "is not implemented yet !\n");
2684 env
->spr
[SPR_BOOKE_ESR
] = ESR_SPV
;
2686 case POWERPC_EXCP_EPERFM
: /* Embedded performance monitor interrupt */
2689 "Performance counter exception is not implemented yet !\n");
2691 case POWERPC_EXCP_DOORI
: /* Embedded doorbell interrupt */
2693 case POWERPC_EXCP_DOORCI
: /* Embedded doorbell critical interrupt */
2694 srr0
= SPR_BOOKE_CSRR0
;
2695 srr1
= SPR_BOOKE_CSRR1
;
2697 case POWERPC_EXCP_RESET
: /* System reset exception */
2699 /* indicate that we resumed from power save mode */
2702 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2706 /* XXX: find a suitable condition to enable the hypervisor mode */
2707 new_msr
|= (target_ulong
)MSR_HVB
;
2710 case POWERPC_EXCP_DSEG
: /* Data segment exception */
2712 new_msr
|= (target_ulong
)MSR_HVB
;
2714 case POWERPC_EXCP_ISEG
: /* Instruction segment exception */
2716 new_msr
|= (target_ulong
)MSR_HVB
;
2718 case POWERPC_EXCP_HDECR
: /* Hypervisor decrementer exception */
2721 new_msr
|= (target_ulong
)MSR_HVB
;
2722 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2724 case POWERPC_EXCP_TRACE
: /* Trace exception */
2726 new_msr
|= (target_ulong
)MSR_HVB
;
2728 case POWERPC_EXCP_HDSI
: /* Hypervisor data storage exception */
2731 new_msr
|= (target_ulong
)MSR_HVB
;
2732 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2734 case POWERPC_EXCP_HISI
: /* Hypervisor instruction storage exception */
2737 new_msr
|= (target_ulong
)MSR_HVB
;
2738 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2740 case POWERPC_EXCP_HDSEG
: /* Hypervisor data segment exception */
2743 new_msr
|= (target_ulong
)MSR_HVB
;
2744 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2746 case POWERPC_EXCP_HISEG
: /* Hypervisor instruction segment exception */
2749 new_msr
|= (target_ulong
)MSR_HVB
;
2750 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2752 case POWERPC_EXCP_VPU
: /* Vector unavailable exception */
2754 new_msr
|= (target_ulong
)MSR_HVB
;
2756 case POWERPC_EXCP_PIT
: /* Programmable interval timer interrupt */
2757 LOG_EXCP("PIT exception\n");
2759 case POWERPC_EXCP_IO
: /* IO error exception */
2761 cpu_abort(env
, "601 IO error exception is not implemented yet !\n");
2763 case POWERPC_EXCP_RUNM
: /* Run mode exception */
2765 cpu_abort(env
, "601 run mode exception is not implemented yet !\n");
2767 case POWERPC_EXCP_EMUL
: /* Emulation trap exception */
2769 cpu_abort(env
, "602 emulation trap exception "
2770 "is not implemented yet !\n");
2772 case POWERPC_EXCP_IFTLB
: /* Instruction fetch TLB error */
2773 if (lpes1
== 0) /* XXX: check this */
2774 new_msr
|= (target_ulong
)MSR_HVB
;
2775 switch (excp_model
) {
2776 case POWERPC_EXCP_602
:
2777 case POWERPC_EXCP_603
:
2778 case POWERPC_EXCP_603E
:
2779 case POWERPC_EXCP_G2
:
2781 case POWERPC_EXCP_7x5
:
2783 case POWERPC_EXCP_74xx
:
2786 cpu_abort(env
, "Invalid instruction TLB miss exception\n");
2790 case POWERPC_EXCP_DLTLB
: /* Data load TLB miss */
2791 if (lpes1
== 0) /* XXX: check this */
2792 new_msr
|= (target_ulong
)MSR_HVB
;
2793 switch (excp_model
) {
2794 case POWERPC_EXCP_602
:
2795 case POWERPC_EXCP_603
:
2796 case POWERPC_EXCP_603E
:
2797 case POWERPC_EXCP_G2
:
2799 case POWERPC_EXCP_7x5
:
2801 case POWERPC_EXCP_74xx
:
2804 cpu_abort(env
, "Invalid data load TLB miss exception\n");
2808 case POWERPC_EXCP_DSTLB
: /* Data store TLB miss */
2809 if (lpes1
== 0) /* XXX: check this */
2810 new_msr
|= (target_ulong
)MSR_HVB
;
2811 switch (excp_model
) {
2812 case POWERPC_EXCP_602
:
2813 case POWERPC_EXCP_603
:
2814 case POWERPC_EXCP_603E
:
2815 case POWERPC_EXCP_G2
:
2817 /* Swap temporary saved registers with GPRs */
2818 if (!(new_msr
& ((target_ulong
)1 << MSR_TGPR
))) {
2819 new_msr
|= (target_ulong
)1 << MSR_TGPR
;
2820 hreg_swap_gpr_tgpr(env
);
2823 case POWERPC_EXCP_7x5
:
2825 #if defined (DEBUG_SOFTWARE_TLB)
2826 if (qemu_log_enabled()) {
2828 target_ulong
*miss
, *cmp
;
2830 if (excp
== POWERPC_EXCP_IFTLB
) {
2833 miss
= &env
->spr
[SPR_IMISS
];
2834 cmp
= &env
->spr
[SPR_ICMP
];
2836 if (excp
== POWERPC_EXCP_DLTLB
)
2841 miss
= &env
->spr
[SPR_DMISS
];
2842 cmp
= &env
->spr
[SPR_DCMP
];
2844 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2845 TARGET_FMT_lx
" H1 " TARGET_FMT_lx
" H2 "
2846 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2847 env
->spr
[SPR_HASH1
], env
->spr
[SPR_HASH2
],
2851 msr
|= env
->crf
[0] << 28;
2852 msr
|= env
->error_code
; /* key, D/I, S/L bits */
2853 /* Set way using a LRU mechanism */
2854 msr
|= ((env
->last_way
+ 1) & (env
->nb_ways
- 1)) << 17;
2856 case POWERPC_EXCP_74xx
:
2858 #if defined (DEBUG_SOFTWARE_TLB)
2859 if (qemu_log_enabled()) {
2861 target_ulong
*miss
, *cmp
;
2863 if (excp
== POWERPC_EXCP_IFTLB
) {
2866 miss
= &env
->spr
[SPR_TLBMISS
];
2867 cmp
= &env
->spr
[SPR_PTEHI
];
2869 if (excp
== POWERPC_EXCP_DLTLB
)
2874 miss
= &env
->spr
[SPR_TLBMISS
];
2875 cmp
= &env
->spr
[SPR_PTEHI
];
2877 qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2878 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2882 msr
|= env
->error_code
; /* key bit */
2885 cpu_abort(env
, "Invalid data store TLB miss exception\n");
2889 case POWERPC_EXCP_FPA
: /* Floating-point assist exception */
2891 cpu_abort(env
, "Floating point assist exception "
2892 "is not implemented yet !\n");
2894 case POWERPC_EXCP_DABR
: /* Data address breakpoint */
2896 cpu_abort(env
, "DABR exception is not implemented yet !\n");
2898 case POWERPC_EXCP_IABR
: /* Instruction address breakpoint */
2900 cpu_abort(env
, "IABR exception is not implemented yet !\n");
2902 case POWERPC_EXCP_SMI
: /* System management interrupt */
2904 cpu_abort(env
, "SMI exception is not implemented yet !\n");
2906 case POWERPC_EXCP_THERM
: /* Thermal interrupt */
2908 cpu_abort(env
, "Thermal management exception "
2909 "is not implemented yet !\n");
2911 case POWERPC_EXCP_PERFM
: /* Embedded performance monitor interrupt */
2913 new_msr
|= (target_ulong
)MSR_HVB
;
2916 "Performance counter exception is not implemented yet !\n");
2918 case POWERPC_EXCP_VPUA
: /* Vector assist exception */
2920 cpu_abort(env
, "VPU assist exception is not implemented yet !\n");
2922 case POWERPC_EXCP_SOFTP
: /* Soft patch exception */
2925 "970 soft-patch exception is not implemented yet !\n");
2927 case POWERPC_EXCP_MAINT
: /* Maintenance exception */
2930 "970 maintenance exception is not implemented yet !\n");
2932 case POWERPC_EXCP_MEXTBR
: /* Maskable external breakpoint */
2934 cpu_abort(env
, "Maskable external exception "
2935 "is not implemented yet !\n");
2937 case POWERPC_EXCP_NMEXTBR
: /* Non maskable external breakpoint */
2939 cpu_abort(env
, "Non maskable external exception "
2940 "is not implemented yet !\n");
2944 cpu_abort(env
, "Invalid PowerPC exception %d. Aborting\n", excp
);
2947 /* save current instruction location */
2948 env
->spr
[srr0
] = env
->nip
- 4;
2951 /* save next instruction location */
2952 env
->spr
[srr0
] = env
->nip
;
2956 env
->spr
[srr1
] = msr
;
2957 /* If any alternate SRR register are defined, duplicate saved values */
2959 env
->spr
[asrr0
] = env
->spr
[srr0
];
2961 env
->spr
[asrr1
] = env
->spr
[srr1
];
2962 /* If we disactivated any translation, flush TLBs */
2963 if (new_msr
& ((1 << MSR_IR
) | (1 << MSR_DR
)))
2967 new_msr
|= (target_ulong
)1 << MSR_LE
;
2970 /* Jump to handler */
2971 vector
= env
->excp_vectors
[excp
];
2972 if (vector
== (target_ulong
)-1ULL) {
2973 cpu_abort(env
, "Raised an exception without defined vector %d\n",
2976 vector
|= env
->excp_prefix
;
2977 #if defined(TARGET_PPC64)
2978 if (excp_model
== POWERPC_EXCP_BOOKE
) {
2980 vector
= (uint32_t)vector
;
2982 new_msr
|= (target_ulong
)1 << MSR_CM
;
2985 if (!msr_isf
&& !(env
->mmu_model
& POWERPC_MMU_64
)) {
2986 vector
= (uint32_t)vector
;
2988 new_msr
|= (target_ulong
)1 << MSR_SF
;
2992 /* XXX: we don't use hreg_store_msr here as already have treated
2993 * any special case that could occur. Just store MSR and update hflags
2995 env
->msr
= new_msr
& env
->msr_mask
;
2996 hreg_compute_hflags(env
);
2998 /* Reset exception state */
2999 env
->exception_index
= POWERPC_EXCP_NONE
;
3000 env
->error_code
= 0;
3002 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
3003 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
3004 /* XXX: The BookE changes address space when switching modes,
3005 we should probably implement that as different MMU indexes,
3006 but for the moment we do it the slow way and flush all. */
3011 void do_interrupt (CPUPPCState
*env
)
3013 powerpc_excp(env
, env
->excp_model
, env
->exception_index
);
3016 void ppc_hw_interrupt (CPUPPCState
*env
)
3021 qemu_log_mask(CPU_LOG_INT
, "%s: %p pending %08x req %08x me %d ee %d\n",
3022 __func__
, env
, env
->pending_interrupts
,
3023 env
->interrupt_request
, (int)msr_me
, (int)msr_ee
);
3025 /* External reset */
3026 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_RESET
)) {
3027 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_RESET
);
3028 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_RESET
);
3031 /* Machine check exception */
3032 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_MCK
)) {
3033 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_MCK
);
3034 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_MCHECK
);
3038 /* External debug exception */
3039 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DEBUG
)) {
3040 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DEBUG
);
3041 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DEBUG
);
3046 /* XXX: find a suitable condition to enable the hypervisor mode */
3047 hdice
= env
->spr
[SPR_LPCR
] & 1;
3051 if ((msr_ee
!= 0 || msr_hv
== 0 || msr_pr
!= 0) && hdice
!= 0) {
3052 /* Hypervisor decrementer exception */
3053 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_HDECR
)) {
3054 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_HDECR
);
3055 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_HDECR
);
3060 /* External critical interrupt */
3061 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CEXT
)) {
3062 /* Taking a critical external interrupt does not clear the external
3063 * critical interrupt status
3066 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CEXT
);
3068 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_CRITICAL
);
3073 /* Watchdog timer on embedded PowerPC */
3074 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_WDT
)) {
3075 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_WDT
);
3076 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_WDT
);
3079 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CDOORBELL
)) {
3080 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CDOORBELL
);
3081 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORCI
);
3084 /* Fixed interval timer on embedded PowerPC */
3085 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_FIT
)) {
3086 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_FIT
);
3087 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_FIT
);
3090 /* Programmable interval timer on embedded PowerPC */
3091 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PIT
)) {
3092 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PIT
);
3093 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PIT
);
3096 /* Decrementer exception */
3097 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DECR
)) {
3098 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DECR
);
3099 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DECR
);
3102 /* External interrupt */
3103 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_EXT
)) {
3104 /* Taking an external interrupt does not clear the external
3108 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_EXT
);
3110 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_EXTERNAL
);
3113 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DOORBELL
)) {
3114 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DOORBELL
);
3115 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORI
);
3118 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PERFM
)) {
3119 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PERFM
);
3120 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PERFM
);
3123 /* Thermal interrupt */
3124 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_THERM
)) {
3125 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_THERM
);
3126 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_THERM
);
3131 #endif /* !CONFIG_USER_ONLY */
3133 void cpu_dump_rfi (target_ulong RA
, target_ulong msr
)
3135 qemu_log("Return from exception at " TARGET_FMT_lx
" with flags "
3136 TARGET_FMT_lx
"\n", RA
, msr
);
3139 void cpu_state_reset(CPUPPCState
*env
)
3143 if (qemu_loglevel_mask(CPU_LOG_RESET
)) {
3144 qemu_log("CPU Reset (CPU %d)\n", env
->cpu_index
);
3145 log_cpu_state(env
, 0);
3148 msr
= (target_ulong
)0;
3150 /* XXX: find a suitable condition to enable the hypervisor mode */
3151 msr
|= (target_ulong
)MSR_HVB
;
3153 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
3154 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
3155 msr
|= (target_ulong
)1 << MSR_EP
;
3156 #if defined (DO_SINGLE_STEP) && 0
3157 /* Single step trace mode */
3158 msr
|= (target_ulong
)1 << MSR_SE
;
3159 msr
|= (target_ulong
)1 << MSR_BE
;
3161 #if defined(CONFIG_USER_ONLY)
3162 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
3163 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
3164 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
3165 msr
|= (target_ulong
)1 << MSR_PR
;
3167 env
->excp_prefix
= env
->hreset_excp_prefix
;
3168 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
3169 if (env
->mmu_model
!= POWERPC_MMU_REAL
)
3170 ppc_tlb_invalidate_all(env
);
3172 env
->msr
= msr
& env
->msr_mask
;
3173 #if defined(TARGET_PPC64)
3174 if (env
->mmu_model
& POWERPC_MMU_64
)
3175 env
->msr
|= (1ULL << MSR_SF
);
3177 hreg_compute_hflags(env
);
3178 env
->reserve_addr
= (target_ulong
)-1ULL;
3179 /* Be sure no exception or interrupt is pending */
3180 env
->pending_interrupts
= 0;
3181 env
->exception_index
= POWERPC_EXCP_NONE
;
3182 env
->error_code
= 0;
3183 /* Flush all TLBs */
3187 CPUPPCState
*cpu_ppc_init (const char *cpu_model
)
3190 const ppc_def_t
*def
;
3192 def
= cpu_ppc_find_by_name(cpu_model
);
3196 env
= g_malloc0(sizeof(CPUPPCState
));
3198 if (tcg_enabled()) {
3199 ppc_translate_init();
3201 /* Adjust cpu index for SMT */
3202 #if !defined(CONFIG_USER_ONLY)
3203 if (kvm_enabled()) {
3204 int smt
= kvmppc_smt_threads();
3206 env
->cpu_index
= (env
->cpu_index
/ smp_threads
)*smt
3207 + (env
->cpu_index
% smp_threads
);
3209 #endif /* !CONFIG_USER_ONLY */
3210 env
->cpu_model_str
= cpu_model
;
3211 cpu_ppc_register_internal(env
, def
);
3213 qemu_init_vcpu(env
);
3218 void cpu_ppc_close (CPUPPCState
*env
)
3220 /* Should also remove all opcode tables... */