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/>.
28 #include "helper_regs.h"
29 #include "qemu-common.h"
35 //#define DEBUG_SOFTWARE_TLB
36 //#define DUMP_PAGE_TABLES
37 //#define DEBUG_EXCEPTIONS
38 //#define FLUSH_ALL_TLBS
41 # define LOG_MMU(...) qemu_log(__VA_ARGS__)
42 # define LOG_MMU_STATE(env) log_cpu_state((env), 0)
44 # define LOG_MMU(...) do { } while (0)
45 # define LOG_MMU_STATE(...) do { } while (0)
49 #ifdef DEBUG_SOFTWARE_TLB
50 # define LOG_SWTLB(...) qemu_log(__VA_ARGS__)
52 # define LOG_SWTLB(...) do { } while (0)
56 # define LOG_BATS(...) qemu_log(__VA_ARGS__)
58 # define LOG_BATS(...) do { } while (0)
62 # define LOG_SLB(...) qemu_log(__VA_ARGS__)
64 # define LOG_SLB(...) do { } while (0)
67 #ifdef DEBUG_EXCEPTIONS
68 # define LOG_EXCP(...) qemu_log(__VA_ARGS__)
70 # define LOG_EXCP(...) do { } while (0)
73 /*****************************************************************************/
74 /* PowerPC Hypercall emulation */
76 void (*cpu_ppc_hypercall
)(CPUState
*);
78 /*****************************************************************************/
79 /* PowerPC MMU emulation */
81 #if defined(CONFIG_USER_ONLY)
82 int cpu_ppc_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
83 int mmu_idx
, int is_softmmu
)
85 int exception
, error_code
;
88 exception
= POWERPC_EXCP_ISI
;
89 error_code
= 0x40000000;
91 exception
= POWERPC_EXCP_DSI
;
92 error_code
= 0x40000000;
94 error_code
|= 0x02000000;
95 env
->spr
[SPR_DAR
] = address
;
96 env
->spr
[SPR_DSISR
] = error_code
;
98 env
->exception_index
= exception
;
99 env
->error_code
= error_code
;
105 /* Common routines used by software and hardware TLBs emulation */
106 static inline int pte_is_valid(target_ulong pte0
)
108 return pte0
& 0x80000000 ? 1 : 0;
111 static inline void pte_invalidate(target_ulong
*pte0
)
113 *pte0
&= ~0x80000000;
116 #if defined(TARGET_PPC64)
117 static inline int pte64_is_valid(target_ulong pte0
)
119 return pte0
& 0x0000000000000001ULL
? 1 : 0;
122 static inline void pte64_invalidate(target_ulong
*pte0
)
124 *pte0
&= ~0x0000000000000001ULL
;
128 #define PTE_PTEM_MASK 0x7FFFFFBF
129 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
130 #if defined(TARGET_PPC64)
131 #define PTE64_PTEM_MASK 0xFFFFFFFFFFFFFF80ULL
132 #define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F)
135 static inline int pp_check(int key
, int pp
, int nx
)
139 /* Compute access rights */
140 /* When pp is 3/7, the result is undefined. Set it to noaccess */
147 access
|= PAGE_WRITE
;
165 access
= PAGE_READ
| PAGE_WRITE
;
175 static inline int check_prot(int prot
, int rw
, int access_type
)
179 if (access_type
== ACCESS_CODE
) {
180 if (prot
& PAGE_EXEC
)
185 if (prot
& PAGE_WRITE
)
190 if (prot
& PAGE_READ
)
199 static inline int _pte_check(mmu_ctx_t
*ctx
, int is_64b
, target_ulong pte0
,
200 target_ulong pte1
, int h
, int rw
, int type
)
202 target_ulong ptem
, mmask
;
203 int access
, ret
, pteh
, ptev
, pp
;
206 /* Check validity and table match */
207 #if defined(TARGET_PPC64)
209 ptev
= pte64_is_valid(pte0
);
210 pteh
= (pte0
>> 1) & 1;
214 ptev
= pte_is_valid(pte0
);
215 pteh
= (pte0
>> 6) & 1;
217 if (ptev
&& h
== pteh
) {
218 /* Check vsid & api */
219 #if defined(TARGET_PPC64)
221 ptem
= pte0
& PTE64_PTEM_MASK
;
222 mmask
= PTE64_CHECK_MASK
;
223 pp
= (pte1
& 0x00000003) | ((pte1
>> 61) & 0x00000004);
224 ctx
->nx
= (pte1
>> 2) & 1; /* No execute bit */
225 ctx
->nx
|= (pte1
>> 3) & 1; /* Guarded bit */
229 ptem
= pte0
& PTE_PTEM_MASK
;
230 mmask
= PTE_CHECK_MASK
;
231 pp
= pte1
& 0x00000003;
233 if (ptem
== ctx
->ptem
) {
234 if (ctx
->raddr
!= (target_phys_addr_t
)-1ULL) {
235 /* all matches should have equal RPN, WIMG & PP */
236 if ((ctx
->raddr
& mmask
) != (pte1
& mmask
)) {
237 qemu_log("Bad RPN/WIMG/PP\n");
241 /* Compute access rights */
242 access
= pp_check(ctx
->key
, pp
, ctx
->nx
);
243 /* Keep the matching PTE informations */
246 ret
= check_prot(ctx
->prot
, rw
, type
);
249 LOG_MMU("PTE access granted !\n");
251 /* Access right violation */
252 LOG_MMU("PTE access rejected\n");
260 static inline int pte32_check(mmu_ctx_t
*ctx
, target_ulong pte0
,
261 target_ulong pte1
, int h
, int rw
, int type
)
263 return _pte_check(ctx
, 0, pte0
, pte1
, h
, rw
, type
);
266 #if defined(TARGET_PPC64)
267 static inline int pte64_check(mmu_ctx_t
*ctx
, target_ulong pte0
,
268 target_ulong pte1
, int h
, int rw
, int type
)
270 return _pte_check(ctx
, 1, pte0
, pte1
, h
, rw
, type
);
274 static inline int pte_update_flags(mmu_ctx_t
*ctx
, target_ulong
*pte1p
,
279 /* Update page flags */
280 if (!(*pte1p
& 0x00000100)) {
281 /* Update accessed flag */
282 *pte1p
|= 0x00000100;
285 if (!(*pte1p
& 0x00000080)) {
286 if (rw
== 1 && ret
== 0) {
287 /* Update changed flag */
288 *pte1p
|= 0x00000080;
291 /* Force page fault for first write access */
292 ctx
->prot
&= ~PAGE_WRITE
;
299 /* Software driven TLB helpers */
300 static inline int ppc6xx_tlb_getnum(CPUState
*env
, target_ulong eaddr
, int way
,
305 /* Select TLB num in a way from address */
306 nr
= (eaddr
>> TARGET_PAGE_BITS
) & (env
->tlb_per_way
- 1);
308 nr
+= env
->tlb_per_way
* way
;
309 /* 6xx have separate TLBs for instructions and data */
310 if (is_code
&& env
->id_tlbs
== 1)
316 static inline void ppc6xx_tlb_invalidate_all(CPUState
*env
)
321 //LOG_SWTLB("Invalidate all TLBs\n");
322 /* Invalidate all defined software TLB */
324 if (env
->id_tlbs
== 1)
326 for (nr
= 0; nr
< max
; nr
++) {
327 tlb
= &env
->tlb
[nr
].tlb6
;
328 pte_invalidate(&tlb
->pte0
);
333 static inline void __ppc6xx_tlb_invalidate_virt(CPUState
*env
,
335 int is_code
, int match_epn
)
337 #if !defined(FLUSH_ALL_TLBS)
341 /* Invalidate ITLB + DTLB, all ways */
342 for (way
= 0; way
< env
->nb_ways
; way
++) {
343 nr
= ppc6xx_tlb_getnum(env
, eaddr
, way
, is_code
);
344 tlb
= &env
->tlb
[nr
].tlb6
;
345 if (pte_is_valid(tlb
->pte0
) && (match_epn
== 0 || eaddr
== tlb
->EPN
)) {
346 LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx
"\n", nr
,
348 pte_invalidate(&tlb
->pte0
);
349 tlb_flush_page(env
, tlb
->EPN
);
353 /* XXX: PowerPC specification say this is valid as well */
354 ppc6xx_tlb_invalidate_all(env
);
358 static inline void ppc6xx_tlb_invalidate_virt(CPUState
*env
,
359 target_ulong eaddr
, int is_code
)
361 __ppc6xx_tlb_invalidate_virt(env
, eaddr
, is_code
, 0);
364 void ppc6xx_tlb_store (CPUState
*env
, target_ulong EPN
, int way
, int is_code
,
365 target_ulong pte0
, target_ulong pte1
)
370 nr
= ppc6xx_tlb_getnum(env
, EPN
, way
, is_code
);
371 tlb
= &env
->tlb
[nr
].tlb6
;
372 LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx
" PTE0 " TARGET_FMT_lx
373 " PTE1 " TARGET_FMT_lx
"\n", nr
, env
->nb_tlb
, EPN
, pte0
, pte1
);
374 /* Invalidate any pending reference in Qemu for this virtual address */
375 __ppc6xx_tlb_invalidate_virt(env
, EPN
, is_code
, 1);
379 /* Store last way for LRU mechanism */
383 static inline int ppc6xx_tlb_check(CPUState
*env
, mmu_ctx_t
*ctx
,
384 target_ulong eaddr
, int rw
, int access_type
)
391 ret
= -1; /* No TLB found */
392 for (way
= 0; way
< env
->nb_ways
; way
++) {
393 nr
= ppc6xx_tlb_getnum(env
, eaddr
, way
,
394 access_type
== ACCESS_CODE
? 1 : 0);
395 tlb
= &env
->tlb
[nr
].tlb6
;
396 /* This test "emulates" the PTE index match for hardware TLBs */
397 if ((eaddr
& TARGET_PAGE_MASK
) != tlb
->EPN
) {
398 LOG_SWTLB("TLB %d/%d %s [" TARGET_FMT_lx
" " TARGET_FMT_lx
399 "] <> " TARGET_FMT_lx
"\n", nr
, env
->nb_tlb
,
400 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
401 tlb
->EPN
, tlb
->EPN
+ TARGET_PAGE_SIZE
, eaddr
);
404 LOG_SWTLB("TLB %d/%d %s " TARGET_FMT_lx
" <> " TARGET_FMT_lx
" "
405 TARGET_FMT_lx
" %c %c\n", nr
, env
->nb_tlb
,
406 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
407 tlb
->EPN
, eaddr
, tlb
->pte1
,
408 rw
? 'S' : 'L', access_type
== ACCESS_CODE
? 'I' : 'D');
409 switch (pte32_check(ctx
, tlb
->pte0
, tlb
->pte1
, 0, rw
, access_type
)) {
411 /* TLB inconsistency */
414 /* Access violation */
424 /* XXX: we should go on looping to check all TLBs consistency
425 * but we can speed-up the whole thing as the
426 * result would be undefined if TLBs are not consistent.
435 LOG_SWTLB("found TLB at addr " TARGET_FMT_plx
" prot=%01x ret=%d\n",
436 ctx
->raddr
& TARGET_PAGE_MASK
, ctx
->prot
, ret
);
437 /* Update page flags */
438 pte_update_flags(ctx
, &env
->tlb
[best
].tlb6
.pte1
, ret
, rw
);
444 /* Perform BAT hit & translation */
445 static inline void bat_size_prot(CPUState
*env
, target_ulong
*blp
, int *validp
,
446 int *protp
, target_ulong
*BATu
,
452 bl
= (*BATu
& 0x00001FFC) << 15;
455 if (((msr_pr
== 0) && (*BATu
& 0x00000002)) ||
456 ((msr_pr
!= 0) && (*BATu
& 0x00000001))) {
458 pp
= *BATl
& 0x00000003;
460 prot
= PAGE_READ
| PAGE_EXEC
;
470 static inline void bat_601_size_prot(CPUState
*env
, target_ulong
*blp
,
471 int *validp
, int *protp
,
472 target_ulong
*BATu
, target_ulong
*BATl
)
475 int key
, pp
, valid
, prot
;
477 bl
= (*BATl
& 0x0000003F) << 17;
478 LOG_BATS("b %02x ==> bl " TARGET_FMT_lx
" msk " TARGET_FMT_lx
"\n",
479 (uint8_t)(*BATl
& 0x0000003F), bl
, ~bl
);
481 valid
= (*BATl
>> 6) & 1;
483 pp
= *BATu
& 0x00000003;
485 key
= (*BATu
>> 3) & 1;
487 key
= (*BATu
>> 2) & 1;
488 prot
= pp_check(key
, pp
, 0);
495 static inline int get_bat(CPUState
*env
, mmu_ctx_t
*ctx
, target_ulong
virtual,
498 target_ulong
*BATlt
, *BATut
, *BATu
, *BATl
;
499 target_ulong BEPIl
, BEPIu
, bl
;
503 LOG_BATS("%s: %cBAT v " TARGET_FMT_lx
"\n", __func__
,
504 type
== ACCESS_CODE
? 'I' : 'D', virtual);
507 BATlt
= env
->IBAT
[1];
508 BATut
= env
->IBAT
[0];
511 BATlt
= env
->DBAT
[1];
512 BATut
= env
->DBAT
[0];
515 for (i
= 0; i
< env
->nb_BATs
; i
++) {
518 BEPIu
= *BATu
& 0xF0000000;
519 BEPIl
= *BATu
& 0x0FFE0000;
520 if (unlikely(env
->mmu_model
== POWERPC_MMU_601
)) {
521 bat_601_size_prot(env
, &bl
, &valid
, &prot
, BATu
, BATl
);
523 bat_size_prot(env
, &bl
, &valid
, &prot
, BATu
, BATl
);
525 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx
" BATu " TARGET_FMT_lx
526 " BATl " TARGET_FMT_lx
"\n", __func__
,
527 type
== ACCESS_CODE
? 'I' : 'D', i
, virtual, *BATu
, *BATl
);
528 if ((virtual & 0xF0000000) == BEPIu
&&
529 ((virtual & 0x0FFE0000) & ~bl
) == BEPIl
) {
532 /* Get physical address */
533 ctx
->raddr
= (*BATl
& 0xF0000000) |
534 ((virtual & 0x0FFE0000 & bl
) | (*BATl
& 0x0FFE0000)) |
535 (virtual & 0x0001F000);
536 /* Compute access rights */
538 ret
= check_prot(ctx
->prot
, rw
, type
);
540 LOG_BATS("BAT %d match: r " TARGET_FMT_plx
" prot=%c%c\n",
541 i
, ctx
->raddr
, ctx
->prot
& PAGE_READ
? 'R' : '-',
542 ctx
->prot
& PAGE_WRITE
? 'W' : '-');
548 #if defined(DEBUG_BATS)
549 if (qemu_log_enabled()) {
550 LOG_BATS("no BAT match for " TARGET_FMT_lx
":\n", virtual);
551 for (i
= 0; i
< 4; i
++) {
554 BEPIu
= *BATu
& 0xF0000000;
555 BEPIl
= *BATu
& 0x0FFE0000;
556 bl
= (*BATu
& 0x00001FFC) << 15;
557 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx
" BATu " TARGET_FMT_lx
558 " BATl " TARGET_FMT_lx
" \n\t" TARGET_FMT_lx
" "
559 TARGET_FMT_lx
" " TARGET_FMT_lx
"\n",
560 __func__
, type
== ACCESS_CODE
? 'I' : 'D', i
, virtual,
561 *BATu
, *BATl
, BEPIu
, BEPIl
, bl
);
570 static inline target_phys_addr_t
get_pteg_offset(CPUState
*env
,
571 target_phys_addr_t hash
,
574 return (hash
* pte_size
* 8) & env
->htab_mask
;
577 /* PTE table lookup */
578 static inline int _find_pte(CPUState
*env
, mmu_ctx_t
*ctx
, int is_64b
, int h
,
579 int rw
, int type
, int target_page_bits
)
581 target_phys_addr_t pteg_off
;
582 target_ulong pte0
, pte1
;
586 ret
= -1; /* No entry found */
587 pteg_off
= get_pteg_offset(env
, ctx
->hash
[h
],
588 is_64b
? HASH_PTE_SIZE_64
: HASH_PTE_SIZE_32
);
589 for (i
= 0; i
< 8; i
++) {
590 #if defined(TARGET_PPC64)
592 pte0
= ldq_phys(env
->htab_base
+ pteg_off
+ (i
* 16));
593 pte1
= ldq_phys(env
->htab_base
+ pteg_off
+ (i
* 16) + 8);
595 /* We have a TLB that saves 4K pages, so let's
596 * split a huge page to 4k chunks */
597 if (target_page_bits
!= TARGET_PAGE_BITS
)
598 pte1
|= (ctx
->eaddr
& (( 1 << target_page_bits
) - 1))
601 r
= pte64_check(ctx
, pte0
, pte1
, h
, rw
, type
);
602 LOG_MMU("Load pte from " TARGET_FMT_lx
" => " TARGET_FMT_lx
" "
603 TARGET_FMT_lx
" %d %d %d " TARGET_FMT_lx
"\n",
604 pteg_base
+ (i
* 16), pte0
, pte1
, (int)(pte0
& 1), h
,
605 (int)((pte0
>> 1) & 1), ctx
->ptem
);
609 pte0
= ldl_phys(env
->htab_base
+ pteg_off
+ (i
* 8));
610 pte1
= ldl_phys(env
->htab_base
+ pteg_off
+ (i
* 8) + 4);
611 r
= pte32_check(ctx
, pte0
, pte1
, h
, rw
, type
);
612 LOG_MMU("Load pte from " TARGET_FMT_lx
" => " TARGET_FMT_lx
" "
613 TARGET_FMT_lx
" %d %d %d " TARGET_FMT_lx
"\n",
614 pteg_base
+ (i
* 8), pte0
, pte1
, (int)(pte0
>> 31), h
,
615 (int)((pte0
>> 6) & 1), ctx
->ptem
);
619 /* PTE inconsistency */
622 /* Access violation */
632 /* XXX: we should go on looping to check all PTEs consistency
633 * but if we can speed-up the whole thing as the
634 * result would be undefined if PTEs are not consistent.
643 LOG_MMU("found PTE at addr " TARGET_FMT_lx
" prot=%01x ret=%d\n",
644 ctx
->raddr
, ctx
->prot
, ret
);
645 /* Update page flags */
647 if (pte_update_flags(ctx
, &pte1
, ret
, rw
) == 1) {
648 #if defined(TARGET_PPC64)
650 stq_phys_notdirty(env
->htab_base
+ pteg_off
+ (good
* 16) + 8,
655 stl_phys_notdirty(env
->htab_base
+ pteg_off
+ (good
* 8) + 4,
664 static inline int find_pte(CPUState
*env
, mmu_ctx_t
*ctx
, int h
, int rw
,
665 int type
, int target_page_bits
)
667 #if defined(TARGET_PPC64)
668 if (env
->mmu_model
& POWERPC_MMU_64
)
669 return _find_pte(env
, ctx
, 1, h
, rw
, type
, target_page_bits
);
672 return _find_pte(env
, ctx
, 0, h
, rw
, type
, target_page_bits
);
675 #if defined(TARGET_PPC64)
676 static inline ppc_slb_t
*slb_lookup(CPUPPCState
*env
, target_ulong eaddr
)
678 uint64_t esid_256M
, esid_1T
;
681 LOG_SLB("%s: eaddr " TARGET_FMT_lx
"\n", __func__
, eaddr
);
683 esid_256M
= (eaddr
& SEGMENT_MASK_256M
) | SLB_ESID_V
;
684 esid_1T
= (eaddr
& SEGMENT_MASK_1T
) | SLB_ESID_V
;
686 for (n
= 0; n
< env
->slb_nr
; n
++) {
687 ppc_slb_t
*slb
= &env
->slb
[n
];
689 LOG_SLB("%s: slot %d %016" PRIx64
" %016"
690 PRIx64
"\n", __func__
, n
, slb
->esid
, slb
->vsid
);
691 /* We check for 1T matches on all MMUs here - if the MMU
692 * doesn't have 1T segment support, we will have prevented 1T
693 * entries from being inserted in the slbmte code. */
694 if (((slb
->esid
== esid_256M
) &&
695 ((slb
->vsid
& SLB_VSID_B
) == SLB_VSID_B_256M
))
696 || ((slb
->esid
== esid_1T
) &&
697 ((slb
->vsid
& SLB_VSID_B
) == SLB_VSID_B_1T
))) {
705 void ppc_slb_invalidate_all (CPUPPCState
*env
)
707 int n
, do_invalidate
;
710 /* XXX: Warning: slbia never invalidates the first segment */
711 for (n
= 1; n
< env
->slb_nr
; n
++) {
712 ppc_slb_t
*slb
= &env
->slb
[n
];
714 if (slb
->esid
& SLB_ESID_V
) {
715 slb
->esid
&= ~SLB_ESID_V
;
716 /* XXX: given the fact that segment size is 256 MB or 1TB,
717 * and we still don't have a tlb_flush_mask(env, n, mask)
718 * in Qemu, we just invalidate all TLBs
727 void ppc_slb_invalidate_one (CPUPPCState
*env
, uint64_t T0
)
731 slb
= slb_lookup(env
, T0
);
736 if (slb
->esid
& SLB_ESID_V
) {
737 slb
->esid
&= ~SLB_ESID_V
;
739 /* XXX: given the fact that segment size is 256 MB or 1TB,
740 * and we still don't have a tlb_flush_mask(env, n, mask)
741 * in Qemu, we just invalidate all TLBs
747 int ppc_store_slb (CPUPPCState
*env
, target_ulong rb
, target_ulong rs
)
749 int slot
= rb
& 0xfff;
750 ppc_slb_t
*slb
= &env
->slb
[slot
];
752 if (rb
& (0x1000 - env
->slb_nr
)) {
753 return -1; /* Reserved bits set or slot too high */
755 if (rs
& (SLB_VSID_B
& ~SLB_VSID_B_1T
)) {
756 return -1; /* Bad segment size */
758 if ((rs
& SLB_VSID_B
) && !(env
->mmu_model
& POWERPC_MMU_1TSEG
)) {
759 return -1; /* 1T segment on MMU that doesn't support it */
762 /* Mask out the slot number as we store the entry */
763 slb
->esid
= rb
& (SLB_ESID_ESID
| SLB_ESID_V
);
766 LOG_SLB("%s: %d " TARGET_FMT_lx
" - " TARGET_FMT_lx
" => %016" PRIx64
767 " %016" PRIx64
"\n", __func__
, slot
, rb
, rs
,
768 slb
->esid
, slb
->vsid
);
773 int ppc_load_slb_esid (CPUPPCState
*env
, target_ulong rb
, target_ulong
*rt
)
775 int slot
= rb
& 0xfff;
776 ppc_slb_t
*slb
= &env
->slb
[slot
];
778 if (slot
>= env
->slb_nr
) {
786 int ppc_load_slb_vsid (CPUPPCState
*env
, target_ulong rb
, target_ulong
*rt
)
788 int slot
= rb
& 0xfff;
789 ppc_slb_t
*slb
= &env
->slb
[slot
];
791 if (slot
>= env
->slb_nr
) {
798 #endif /* defined(TARGET_PPC64) */
800 /* Perform segment based translation */
801 static inline int get_segment(CPUState
*env
, mmu_ctx_t
*ctx
,
802 target_ulong eaddr
, int rw
, int type
)
804 target_phys_addr_t hash
;
806 int ds
, pr
, target_page_bits
;
811 #if defined(TARGET_PPC64)
812 if (env
->mmu_model
& POWERPC_MMU_64
) {
814 target_ulong pageaddr
;
817 LOG_MMU("Check SLBs\n");
818 slb
= slb_lookup(env
, eaddr
);
823 if (slb
->vsid
& SLB_VSID_B
) {
824 vsid
= (slb
->vsid
& SLB_VSID_VSID
) >> SLB_VSID_SHIFT_1T
;
827 vsid
= (slb
->vsid
& SLB_VSID_VSID
) >> SLB_VSID_SHIFT
;
831 target_page_bits
= (slb
->vsid
& SLB_VSID_L
)
832 ? TARGET_PAGE_BITS_16M
: TARGET_PAGE_BITS
;
833 ctx
->key
= !!(pr
? (slb
->vsid
& SLB_VSID_KP
)
834 : (slb
->vsid
& SLB_VSID_KS
));
836 ctx
->nx
= !!(slb
->vsid
& SLB_VSID_N
);
838 pageaddr
= eaddr
& ((1ULL << segment_bits
)
839 - (1ULL << target_page_bits
));
840 if (slb
->vsid
& SLB_VSID_B
) {
841 hash
= vsid
^ (vsid
<< 25) ^ (pageaddr
>> target_page_bits
);
843 hash
= vsid
^ (pageaddr
>> target_page_bits
);
845 /* Only 5 bits of the page index are used in the AVPN */
846 ctx
->ptem
= (slb
->vsid
& SLB_VSID_PTEM
) |
847 ((pageaddr
>> 16) & ((1ULL << segment_bits
) - 0x80));
849 #endif /* defined(TARGET_PPC64) */
851 target_ulong sr
, pgidx
;
853 sr
= env
->sr
[eaddr
>> 28];
854 ctx
->key
= (((sr
& 0x20000000) && (pr
!= 0)) ||
855 ((sr
& 0x40000000) && (pr
== 0))) ? 1 : 0;
856 ds
= sr
& 0x80000000 ? 1 : 0;
857 ctx
->nx
= sr
& 0x10000000 ? 1 : 0;
858 vsid
= sr
& 0x00FFFFFF;
859 target_page_bits
= TARGET_PAGE_BITS
;
860 LOG_MMU("Check segment v=" TARGET_FMT_lx
" %d " TARGET_FMT_lx
" nip="
861 TARGET_FMT_lx
" lr=" TARGET_FMT_lx
862 " ir=%d dr=%d pr=%d %d t=%d\n",
863 eaddr
, (int)(eaddr
>> 28), sr
, env
->nip
, env
->lr
, (int)msr_ir
,
864 (int)msr_dr
, pr
!= 0 ? 1 : 0, rw
, type
);
865 pgidx
= (eaddr
& ~SEGMENT_MASK_256M
) >> target_page_bits
;
867 ctx
->ptem
= (vsid
<< 7) | (pgidx
>> 10);
869 LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx
"\n",
870 ctx
->key
, ds
, ctx
->nx
, vsid
);
873 /* Check if instruction fetch is allowed, if needed */
874 if (type
!= ACCESS_CODE
|| ctx
->nx
== 0) {
875 /* Page address translation */
876 LOG_MMU("htab_base " TARGET_FMT_plx
" htab_mask " TARGET_FMT_plx
877 " hash " TARGET_FMT_plx
"\n",
878 env
->htab_base
, env
->htab_mask
, hash
);
880 ctx
->hash
[1] = ~hash
;
882 /* Initialize real address with an invalid value */
883 ctx
->raddr
= (target_phys_addr_t
)-1ULL;
884 if (unlikely(env
->mmu_model
== POWERPC_MMU_SOFT_6xx
||
885 env
->mmu_model
== POWERPC_MMU_SOFT_74xx
)) {
886 /* Software TLB search */
887 ret
= ppc6xx_tlb_check(env
, ctx
, eaddr
, rw
, type
);
889 LOG_MMU("0 htab=" TARGET_FMT_plx
"/" TARGET_FMT_plx
890 " vsid=" TARGET_FMT_lx
" ptem=" TARGET_FMT_lx
891 " hash=" TARGET_FMT_plx
"\n",
892 env
->htab_base
, env
->htab_mask
, vsid
, ctx
->ptem
,
894 /* Primary table lookup */
895 ret
= find_pte(env
, ctx
, 0, rw
, type
, target_page_bits
);
897 /* Secondary table lookup */
898 if (eaddr
!= 0xEFFFFFFF)
899 LOG_MMU("1 htab=" TARGET_FMT_plx
"/" TARGET_FMT_plx
900 " vsid=" TARGET_FMT_lx
" api=" TARGET_FMT_lx
901 " hash=" TARGET_FMT_plx
" pg_addr="
902 TARGET_FMT_plx
"\n", env
->htab_base
,
903 env
->htab_mask
, vsid
, ctx
->ptem
, ctx
->hash
[1]);
904 ret2
= find_pte(env
, ctx
, 1, rw
, type
,
910 #if defined (DUMP_PAGE_TABLES)
911 if (qemu_log_enabled()) {
912 target_phys_addr_t curaddr
;
913 uint32_t a0
, a1
, a2
, a3
;
914 qemu_log("Page table: " TARGET_FMT_plx
" len " TARGET_FMT_plx
915 "\n", sdr
, mask
+ 0x80);
916 for (curaddr
= sdr
; curaddr
< (sdr
+ mask
+ 0x80);
918 a0
= ldl_phys(curaddr
);
919 a1
= ldl_phys(curaddr
+ 4);
920 a2
= ldl_phys(curaddr
+ 8);
921 a3
= ldl_phys(curaddr
+ 12);
922 if (a0
!= 0 || a1
!= 0 || a2
!= 0 || a3
!= 0) {
923 qemu_log(TARGET_FMT_plx
": %08x %08x %08x %08x\n",
924 curaddr
, a0
, a1
, a2
, a3
);
930 LOG_MMU("No access allowed\n");
934 LOG_MMU("direct store...\n");
935 /* Direct-store segment : absolutely *BUGGY* for now */
938 /* Integer load/store : only access allowed */
941 /* No code fetch is allowed in direct-store areas */
944 /* Floating point load/store */
947 /* lwarx, ldarx or srwcx. */
950 /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
951 /* Should make the instruction do no-op.
952 * As it already do no-op, it's quite easy :-)
960 qemu_log("ERROR: instruction should not need "
961 "address translation\n");
964 if ((rw
== 1 || ctx
->key
!= 1) && (rw
== 0 || ctx
->key
!= 0)) {
975 /* Generic TLB check function for embedded PowerPC implementations */
976 static inline int ppcemb_tlb_check(CPUState
*env
, ppcemb_tlb_t
*tlb
,
977 target_phys_addr_t
*raddrp
,
978 target_ulong address
, uint32_t pid
, int ext
,
983 /* Check valid flag */
984 if (!(tlb
->prot
& PAGE_VALID
)) {
987 mask
= ~(tlb
->size
- 1);
988 LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx
" PID %u <=> " TARGET_FMT_lx
989 " " TARGET_FMT_lx
" %u\n", __func__
, i
, address
, pid
, tlb
->EPN
,
990 mask
, (uint32_t)tlb
->PID
);
992 if (tlb
->PID
!= 0 && tlb
->PID
!= pid
)
994 /* Check effective address */
995 if ((address
& mask
) != tlb
->EPN
)
997 *raddrp
= (tlb
->RPN
& mask
) | (address
& ~mask
);
998 #if (TARGET_PHYS_ADDR_BITS >= 36)
1000 /* Extend the physical address to 36 bits */
1001 *raddrp
|= (target_phys_addr_t
)(tlb
->RPN
& 0xF) << 32;
1008 /* Generic TLB search function for PowerPC embedded implementations */
1009 int ppcemb_tlb_search (CPUPPCState
*env
, target_ulong address
, uint32_t pid
)
1012 target_phys_addr_t raddr
;
1015 /* Default return value is no match */
1017 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1018 tlb
= &env
->tlb
[i
].tlbe
;
1019 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
, pid
, 0, i
) == 0) {
1028 /* Helpers specific to PowerPC 40x implementations */
1029 static inline void ppc4xx_tlb_invalidate_all(CPUState
*env
)
1034 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1035 tlb
= &env
->tlb
[i
].tlbe
;
1036 tlb
->prot
&= ~PAGE_VALID
;
1041 static inline void ppc4xx_tlb_invalidate_virt(CPUState
*env
,
1042 target_ulong eaddr
, uint32_t pid
)
1044 #if !defined(FLUSH_ALL_TLBS)
1046 target_phys_addr_t raddr
;
1047 target_ulong page
, end
;
1050 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1051 tlb
= &env
->tlb
[i
].tlbe
;
1052 if (ppcemb_tlb_check(env
, tlb
, &raddr
, eaddr
, pid
, 0, i
) == 0) {
1053 end
= tlb
->EPN
+ tlb
->size
;
1054 for (page
= tlb
->EPN
; page
< end
; page
+= TARGET_PAGE_SIZE
)
1055 tlb_flush_page(env
, page
);
1056 tlb
->prot
&= ~PAGE_VALID
;
1061 ppc4xx_tlb_invalidate_all(env
);
1065 static int mmu40x_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1066 target_ulong address
, int rw
, int access_type
)
1069 target_phys_addr_t raddr
;
1070 int i
, ret
, zsel
, zpr
, pr
;
1073 raddr
= (target_phys_addr_t
)-1ULL;
1075 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1076 tlb
= &env
->tlb
[i
].tlbe
;
1077 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
,
1078 env
->spr
[SPR_40x_PID
], 0, i
) < 0)
1080 zsel
= (tlb
->attr
>> 4) & 0xF;
1081 zpr
= (env
->spr
[SPR_40x_ZPR
] >> (30 - (2 * zsel
))) & 0x3;
1082 LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1083 __func__
, i
, zsel
, zpr
, rw
, tlb
->attr
);
1084 /* Check execute enable bit */
1091 /* All accesses granted */
1092 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
1097 /* Raise Zone protection fault. */
1098 env
->spr
[SPR_40x_ESR
] = 1 << 22;
1106 /* Check from TLB entry */
1107 ctx
->prot
= tlb
->prot
;
1108 ret
= check_prot(ctx
->prot
, rw
, access_type
);
1110 env
->spr
[SPR_40x_ESR
] = 0;
1115 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1116 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1121 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1122 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1127 void store_40x_sler (CPUPPCState
*env
, uint32_t val
)
1129 /* XXX: TO BE FIXED */
1130 if (val
!= 0x00000000) {
1131 cpu_abort(env
, "Little-endian regions are not supported by now\n");
1133 env
->spr
[SPR_405_SLER
] = val
;
1136 static int mmubooke_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1137 target_ulong address
, int rw
,
1141 target_phys_addr_t raddr
;
1145 raddr
= (target_phys_addr_t
)-1ULL;
1146 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1147 tlb
= &env
->tlb
[i
].tlbe
;
1148 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
,
1149 env
->spr
[SPR_BOOKE_PID
], 1, i
) < 0)
1152 prot
= tlb
->prot
& 0xF;
1154 prot
= (tlb
->prot
>> 4) & 0xF;
1155 /* Check the address space */
1156 if (access_type
== ACCESS_CODE
) {
1157 if (msr_ir
!= (tlb
->attr
& 1))
1160 if (prot
& PAGE_EXEC
) {
1166 if (msr_dr
!= (tlb
->attr
& 1))
1169 if ((!rw
&& prot
& PAGE_READ
) || (rw
&& (prot
& PAGE_WRITE
))) {
1182 static inline int check_physical(CPUState
*env
, mmu_ctx_t
*ctx
,
1183 target_ulong eaddr
, int rw
)
1188 ctx
->prot
= PAGE_READ
| PAGE_EXEC
;
1190 switch (env
->mmu_model
) {
1191 case POWERPC_MMU_32B
:
1192 case POWERPC_MMU_601
:
1193 case POWERPC_MMU_SOFT_6xx
:
1194 case POWERPC_MMU_SOFT_74xx
:
1195 case POWERPC_MMU_SOFT_4xx
:
1196 case POWERPC_MMU_REAL
:
1197 case POWERPC_MMU_BOOKE
:
1198 ctx
->prot
|= PAGE_WRITE
;
1200 #if defined(TARGET_PPC64)
1201 case POWERPC_MMU_620
:
1202 case POWERPC_MMU_64B
:
1203 case POWERPC_MMU_2_06
:
1204 /* Real address are 60 bits long */
1205 ctx
->raddr
&= 0x0FFFFFFFFFFFFFFFULL
;
1206 ctx
->prot
|= PAGE_WRITE
;
1209 case POWERPC_MMU_SOFT_4xx_Z
:
1210 if (unlikely(msr_pe
!= 0)) {
1211 /* 403 family add some particular protections,
1212 * using PBL/PBU registers for accesses with no translation.
1215 /* Check PLB validity */
1216 (env
->pb
[0] < env
->pb
[1] &&
1217 /* and address in plb area */
1218 eaddr
>= env
->pb
[0] && eaddr
< env
->pb
[1]) ||
1219 (env
->pb
[2] < env
->pb
[3] &&
1220 eaddr
>= env
->pb
[2] && eaddr
< env
->pb
[3]) ? 1 : 0;
1221 if (in_plb
^ msr_px
) {
1222 /* Access in protected area */
1224 /* Access is not allowed */
1228 /* Read-write access is allowed */
1229 ctx
->prot
|= PAGE_WRITE
;
1233 case POWERPC_MMU_MPC8xx
:
1235 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1237 case POWERPC_MMU_BOOKE_FSL
:
1239 cpu_abort(env
, "BookE FSL MMU model not implemented\n");
1242 cpu_abort(env
, "Unknown or invalid MMU model\n");
1249 int get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
, target_ulong eaddr
,
1250 int rw
, int access_type
)
1255 qemu_log("%s\n", __func__
);
1257 if ((access_type
== ACCESS_CODE
&& msr_ir
== 0) ||
1258 (access_type
!= ACCESS_CODE
&& msr_dr
== 0)) {
1259 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1260 /* The BookE MMU always performs address translation. The
1261 IS and DS bits only affect the address space. */
1262 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1265 /* No address translation. */
1266 ret
= check_physical(env
, ctx
, eaddr
, rw
);
1270 switch (env
->mmu_model
) {
1271 case POWERPC_MMU_32B
:
1272 case POWERPC_MMU_601
:
1273 case POWERPC_MMU_SOFT_6xx
:
1274 case POWERPC_MMU_SOFT_74xx
:
1275 /* Try to find a BAT */
1276 if (env
->nb_BATs
!= 0)
1277 ret
= get_bat(env
, ctx
, eaddr
, rw
, access_type
);
1278 #if defined(TARGET_PPC64)
1279 case POWERPC_MMU_620
:
1280 case POWERPC_MMU_64B
:
1281 case POWERPC_MMU_2_06
:
1284 /* We didn't match any BAT entry or don't have BATs */
1285 ret
= get_segment(env
, ctx
, eaddr
, rw
, access_type
);
1288 case POWERPC_MMU_SOFT_4xx
:
1289 case POWERPC_MMU_SOFT_4xx_Z
:
1290 ret
= mmu40x_get_physical_address(env
, ctx
, eaddr
,
1293 case POWERPC_MMU_BOOKE
:
1294 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1297 case POWERPC_MMU_MPC8xx
:
1299 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1301 case POWERPC_MMU_BOOKE_FSL
:
1303 cpu_abort(env
, "BookE FSL MMU model not implemented\n");
1305 case POWERPC_MMU_REAL
:
1306 cpu_abort(env
, "PowerPC in real mode do not do any translation\n");
1309 cpu_abort(env
, "Unknown or invalid MMU model\n");
1314 qemu_log("%s address " TARGET_FMT_lx
" => %d " TARGET_FMT_plx
"\n",
1315 __func__
, eaddr
, ret
, ctx
->raddr
);
1321 target_phys_addr_t
cpu_get_phys_page_debug (CPUState
*env
, target_ulong addr
)
1325 if (unlikely(get_physical_address(env
, &ctx
, addr
, 0, ACCESS_INT
) != 0))
1328 return ctx
.raddr
& TARGET_PAGE_MASK
;
1331 /* Perform address translation */
1332 int cpu_ppc_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
1333 int mmu_idx
, int is_softmmu
)
1342 access_type
= ACCESS_CODE
;
1345 access_type
= env
->access_type
;
1347 ret
= get_physical_address(env
, &ctx
, address
, rw
, access_type
);
1349 tlb_set_page(env
, address
& TARGET_PAGE_MASK
,
1350 ctx
.raddr
& TARGET_PAGE_MASK
, ctx
.prot
,
1351 mmu_idx
, TARGET_PAGE_SIZE
);
1353 } else if (ret
< 0) {
1355 if (access_type
== ACCESS_CODE
) {
1358 /* No matches in page tables or TLB */
1359 switch (env
->mmu_model
) {
1360 case POWERPC_MMU_SOFT_6xx
:
1361 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1362 env
->error_code
= 1 << 18;
1363 env
->spr
[SPR_IMISS
] = address
;
1364 env
->spr
[SPR_ICMP
] = 0x80000000 | ctx
.ptem
;
1366 case POWERPC_MMU_SOFT_74xx
:
1367 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1369 case POWERPC_MMU_SOFT_4xx
:
1370 case POWERPC_MMU_SOFT_4xx_Z
:
1371 env
->exception_index
= POWERPC_EXCP_ITLB
;
1372 env
->error_code
= 0;
1373 env
->spr
[SPR_40x_DEAR
] = address
;
1374 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1376 case POWERPC_MMU_32B
:
1377 case POWERPC_MMU_601
:
1378 #if defined(TARGET_PPC64)
1379 case POWERPC_MMU_620
:
1380 case POWERPC_MMU_64B
:
1381 case POWERPC_MMU_2_06
:
1383 env
->exception_index
= POWERPC_EXCP_ISI
;
1384 env
->error_code
= 0x40000000;
1386 case POWERPC_MMU_BOOKE
:
1387 env
->exception_index
= POWERPC_EXCP_ITLB
;
1388 env
->error_code
= 0;
1389 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1391 case POWERPC_MMU_BOOKE_FSL
:
1393 cpu_abort(env
, "BookE FSL MMU model is not implemented\n");
1395 case POWERPC_MMU_MPC8xx
:
1397 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1399 case POWERPC_MMU_REAL
:
1400 cpu_abort(env
, "PowerPC in real mode should never raise "
1401 "any MMU exceptions\n");
1404 cpu_abort(env
, "Unknown or invalid MMU model\n");
1409 /* Access rights violation */
1410 env
->exception_index
= POWERPC_EXCP_ISI
;
1411 env
->error_code
= 0x08000000;
1414 /* No execute protection violation */
1415 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1416 env
->spr
[SPR_BOOKE_ESR
] = 0x00000000;
1418 env
->exception_index
= POWERPC_EXCP_ISI
;
1419 env
->error_code
= 0x10000000;
1422 /* Direct store exception */
1423 /* No code fetch is allowed in direct-store areas */
1424 env
->exception_index
= POWERPC_EXCP_ISI
;
1425 env
->error_code
= 0x10000000;
1427 #if defined(TARGET_PPC64)
1429 /* No match in segment table */
1430 if (env
->mmu_model
== POWERPC_MMU_620
) {
1431 env
->exception_index
= POWERPC_EXCP_ISI
;
1432 /* XXX: this might be incorrect */
1433 env
->error_code
= 0x40000000;
1435 env
->exception_index
= POWERPC_EXCP_ISEG
;
1436 env
->error_code
= 0;
1444 /* No matches in page tables or TLB */
1445 switch (env
->mmu_model
) {
1446 case POWERPC_MMU_SOFT_6xx
:
1448 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1449 env
->error_code
= 1 << 16;
1451 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1452 env
->error_code
= 0;
1454 env
->spr
[SPR_DMISS
] = address
;
1455 env
->spr
[SPR_DCMP
] = 0x80000000 | ctx
.ptem
;
1457 env
->error_code
|= ctx
.key
<< 19;
1458 env
->spr
[SPR_HASH1
] = env
->htab_base
+
1459 get_pteg_offset(env
, ctx
.hash
[0], HASH_PTE_SIZE_32
);
1460 env
->spr
[SPR_HASH2
] = env
->htab_base
+
1461 get_pteg_offset(env
, ctx
.hash
[1], HASH_PTE_SIZE_32
);
1463 case POWERPC_MMU_SOFT_74xx
:
1465 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1467 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1470 /* Implement LRU algorithm */
1471 env
->error_code
= ctx
.key
<< 19;
1472 env
->spr
[SPR_TLBMISS
] = (address
& ~((target_ulong
)0x3)) |
1473 ((env
->last_way
+ 1) & (env
->nb_ways
- 1));
1474 env
->spr
[SPR_PTEHI
] = 0x80000000 | ctx
.ptem
;
1476 case POWERPC_MMU_SOFT_4xx
:
1477 case POWERPC_MMU_SOFT_4xx_Z
:
1478 env
->exception_index
= POWERPC_EXCP_DTLB
;
1479 env
->error_code
= 0;
1480 env
->spr
[SPR_40x_DEAR
] = address
;
1482 env
->spr
[SPR_40x_ESR
] = 0x00800000;
1484 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1486 case POWERPC_MMU_32B
:
1487 case POWERPC_MMU_601
:
1488 #if defined(TARGET_PPC64)
1489 case POWERPC_MMU_620
:
1490 case POWERPC_MMU_64B
:
1491 case POWERPC_MMU_2_06
:
1493 env
->exception_index
= POWERPC_EXCP_DSI
;
1494 env
->error_code
= 0;
1495 env
->spr
[SPR_DAR
] = address
;
1497 env
->spr
[SPR_DSISR
] = 0x42000000;
1499 env
->spr
[SPR_DSISR
] = 0x40000000;
1501 case POWERPC_MMU_MPC8xx
:
1503 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1505 case POWERPC_MMU_BOOKE
:
1506 env
->exception_index
= POWERPC_EXCP_DTLB
;
1507 env
->error_code
= 0;
1508 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1509 env
->spr
[SPR_BOOKE_ESR
] = rw
? 1 << ESR_ST
: 0;
1511 case POWERPC_MMU_BOOKE_FSL
:
1513 cpu_abort(env
, "BookE FSL MMU model is not implemented\n");
1515 case POWERPC_MMU_REAL
:
1516 cpu_abort(env
, "PowerPC in real mode should never raise "
1517 "any MMU exceptions\n");
1520 cpu_abort(env
, "Unknown or invalid MMU model\n");
1525 /* Access rights violation */
1526 env
->exception_index
= POWERPC_EXCP_DSI
;
1527 env
->error_code
= 0;
1528 if (env
->mmu_model
== POWERPC_MMU_SOFT_4xx
1529 || env
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
) {
1530 env
->spr
[SPR_40x_DEAR
] = address
;
1532 env
->spr
[SPR_40x_ESR
] |= 0x00800000;
1534 } else if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1535 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1536 env
->spr
[SPR_BOOKE_ESR
] = rw
? 1 << ESR_ST
: 0;
1538 env
->spr
[SPR_DAR
] = address
;
1540 env
->spr
[SPR_DSISR
] = 0x0A000000;
1542 env
->spr
[SPR_DSISR
] = 0x08000000;
1547 /* Direct store exception */
1548 switch (access_type
) {
1550 /* Floating point load/store */
1551 env
->exception_index
= POWERPC_EXCP_ALIGN
;
1552 env
->error_code
= POWERPC_EXCP_ALIGN_FP
;
1553 env
->spr
[SPR_DAR
] = address
;
1556 /* lwarx, ldarx or stwcx. */
1557 env
->exception_index
= POWERPC_EXCP_DSI
;
1558 env
->error_code
= 0;
1559 env
->spr
[SPR_DAR
] = address
;
1561 env
->spr
[SPR_DSISR
] = 0x06000000;
1563 env
->spr
[SPR_DSISR
] = 0x04000000;
1566 /* eciwx or ecowx */
1567 env
->exception_index
= POWERPC_EXCP_DSI
;
1568 env
->error_code
= 0;
1569 env
->spr
[SPR_DAR
] = address
;
1571 env
->spr
[SPR_DSISR
] = 0x06100000;
1573 env
->spr
[SPR_DSISR
] = 0x04100000;
1576 printf("DSI: invalid exception (%d)\n", ret
);
1577 env
->exception_index
= POWERPC_EXCP_PROGRAM
;
1579 POWERPC_EXCP_INVAL
| POWERPC_EXCP_INVAL_INVAL
;
1580 env
->spr
[SPR_DAR
] = address
;
1584 #if defined(TARGET_PPC64)
1586 /* No match in segment table */
1587 if (env
->mmu_model
== POWERPC_MMU_620
) {
1588 env
->exception_index
= POWERPC_EXCP_DSI
;
1589 env
->error_code
= 0;
1590 env
->spr
[SPR_DAR
] = address
;
1591 /* XXX: this might be incorrect */
1593 env
->spr
[SPR_DSISR
] = 0x42000000;
1595 env
->spr
[SPR_DSISR
] = 0x40000000;
1597 env
->exception_index
= POWERPC_EXCP_DSEG
;
1598 env
->error_code
= 0;
1599 env
->spr
[SPR_DAR
] = address
;
1606 printf("%s: set exception to %d %02x\n", __func__
,
1607 env
->exception
, env
->error_code
);
1615 /*****************************************************************************/
1616 /* BATs management */
1617 #if !defined(FLUSH_ALL_TLBS)
1618 static inline void do_invalidate_BAT(CPUPPCState
*env
, target_ulong BATu
,
1621 target_ulong base
, end
, page
;
1623 base
= BATu
& ~0x0001FFFF;
1624 end
= base
+ mask
+ 0x00020000;
1625 LOG_BATS("Flush BAT from " TARGET_FMT_lx
" to " TARGET_FMT_lx
" ("
1626 TARGET_FMT_lx
")\n", base
, end
, mask
);
1627 for (page
= base
; page
!= end
; page
+= TARGET_PAGE_SIZE
)
1628 tlb_flush_page(env
, page
);
1629 LOG_BATS("Flush done\n");
1633 static inline void dump_store_bat(CPUPPCState
*env
, char ID
, int ul
, int nr
,
1636 LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx
" (" TARGET_FMT_lx
")\n", ID
,
1637 nr
, ul
== 0 ? 'u' : 'l', value
, env
->nip
);
1640 void ppc_store_ibatu (CPUPPCState
*env
, int nr
, target_ulong value
)
1644 dump_store_bat(env
, 'I', 0, nr
, value
);
1645 if (env
->IBAT
[0][nr
] != value
) {
1646 mask
= (value
<< 15) & 0x0FFE0000UL
;
1647 #if !defined(FLUSH_ALL_TLBS)
1648 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1650 /* When storing valid upper BAT, mask BEPI and BRPN
1651 * and invalidate all TLBs covered by this BAT
1653 mask
= (value
<< 15) & 0x0FFE0000UL
;
1654 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1655 (value
& ~0x0001FFFFUL
& ~mask
);
1656 env
->IBAT
[1][nr
] = (env
->IBAT
[1][nr
] & 0x0000007B) |
1657 (env
->IBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
1658 #if !defined(FLUSH_ALL_TLBS)
1659 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1666 void ppc_store_ibatl (CPUPPCState
*env
, int nr
, target_ulong value
)
1668 dump_store_bat(env
, 'I', 1, nr
, value
);
1669 env
->IBAT
[1][nr
] = value
;
1672 void ppc_store_dbatu (CPUPPCState
*env
, int nr
, target_ulong value
)
1676 dump_store_bat(env
, 'D', 0, nr
, value
);
1677 if (env
->DBAT
[0][nr
] != value
) {
1678 /* When storing valid upper BAT, mask BEPI and BRPN
1679 * and invalidate all TLBs covered by this BAT
1681 mask
= (value
<< 15) & 0x0FFE0000UL
;
1682 #if !defined(FLUSH_ALL_TLBS)
1683 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
1685 mask
= (value
<< 15) & 0x0FFE0000UL
;
1686 env
->DBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1687 (value
& ~0x0001FFFFUL
& ~mask
);
1688 env
->DBAT
[1][nr
] = (env
->DBAT
[1][nr
] & 0x0000007B) |
1689 (env
->DBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
1690 #if !defined(FLUSH_ALL_TLBS)
1691 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
1698 void ppc_store_dbatl (CPUPPCState
*env
, int nr
, target_ulong value
)
1700 dump_store_bat(env
, 'D', 1, nr
, value
);
1701 env
->DBAT
[1][nr
] = value
;
1704 void ppc_store_ibatu_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
1707 #if defined(FLUSH_ALL_TLBS)
1711 dump_store_bat(env
, 'I', 0, nr
, value
);
1712 if (env
->IBAT
[0][nr
] != value
) {
1713 #if defined(FLUSH_ALL_TLBS)
1716 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
1717 if (env
->IBAT
[1][nr
] & 0x40) {
1718 /* Invalidate BAT only if it is valid */
1719 #if !defined(FLUSH_ALL_TLBS)
1720 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1725 /* When storing valid upper BAT, mask BEPI and BRPN
1726 * and invalidate all TLBs covered by this BAT
1728 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1729 (value
& ~0x0001FFFFUL
& ~mask
);
1730 env
->DBAT
[0][nr
] = env
->IBAT
[0][nr
];
1731 if (env
->IBAT
[1][nr
] & 0x40) {
1732 #if !defined(FLUSH_ALL_TLBS)
1733 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1738 #if defined(FLUSH_ALL_TLBS)
1745 void ppc_store_ibatl_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
1748 #if defined(FLUSH_ALL_TLBS)
1752 dump_store_bat(env
, 'I', 1, nr
, value
);
1753 if (env
->IBAT
[1][nr
] != value
) {
1754 #if defined(FLUSH_ALL_TLBS)
1757 if (env
->IBAT
[1][nr
] & 0x40) {
1758 #if !defined(FLUSH_ALL_TLBS)
1759 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
1760 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1766 #if !defined(FLUSH_ALL_TLBS)
1767 mask
= (value
<< 17) & 0x0FFE0000UL
;
1768 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1773 env
->IBAT
[1][nr
] = value
;
1774 env
->DBAT
[1][nr
] = value
;
1775 #if defined(FLUSH_ALL_TLBS)
1782 /*****************************************************************************/
1783 /* TLB management */
1784 void ppc_tlb_invalidate_all (CPUPPCState
*env
)
1786 switch (env
->mmu_model
) {
1787 case POWERPC_MMU_SOFT_6xx
:
1788 case POWERPC_MMU_SOFT_74xx
:
1789 ppc6xx_tlb_invalidate_all(env
);
1791 case POWERPC_MMU_SOFT_4xx
:
1792 case POWERPC_MMU_SOFT_4xx_Z
:
1793 ppc4xx_tlb_invalidate_all(env
);
1795 case POWERPC_MMU_REAL
:
1796 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
1798 case POWERPC_MMU_MPC8xx
:
1800 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1802 case POWERPC_MMU_BOOKE
:
1805 case POWERPC_MMU_BOOKE_FSL
:
1808 cpu_abort(env
, "BookE MMU model is not implemented\n");
1810 case POWERPC_MMU_32B
:
1811 case POWERPC_MMU_601
:
1812 #if defined(TARGET_PPC64)
1813 case POWERPC_MMU_620
:
1814 case POWERPC_MMU_64B
:
1815 case POWERPC_MMU_2_06
:
1816 #endif /* defined(TARGET_PPC64) */
1821 cpu_abort(env
, "Unknown MMU model\n");
1826 void ppc_tlb_invalidate_one (CPUPPCState
*env
, target_ulong addr
)
1828 #if !defined(FLUSH_ALL_TLBS)
1829 addr
&= TARGET_PAGE_MASK
;
1830 switch (env
->mmu_model
) {
1831 case POWERPC_MMU_SOFT_6xx
:
1832 case POWERPC_MMU_SOFT_74xx
:
1833 ppc6xx_tlb_invalidate_virt(env
, addr
, 0);
1834 if (env
->id_tlbs
== 1)
1835 ppc6xx_tlb_invalidate_virt(env
, addr
, 1);
1837 case POWERPC_MMU_SOFT_4xx
:
1838 case POWERPC_MMU_SOFT_4xx_Z
:
1839 ppc4xx_tlb_invalidate_virt(env
, addr
, env
->spr
[SPR_40x_PID
]);
1841 case POWERPC_MMU_REAL
:
1842 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
1844 case POWERPC_MMU_MPC8xx
:
1846 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1848 case POWERPC_MMU_BOOKE
:
1850 cpu_abort(env
, "BookE MMU model is not implemented\n");
1852 case POWERPC_MMU_BOOKE_FSL
:
1854 cpu_abort(env
, "BookE FSL MMU model is not implemented\n");
1856 case POWERPC_MMU_32B
:
1857 case POWERPC_MMU_601
:
1858 /* tlbie invalidate TLBs for all segments */
1859 addr
&= ~((target_ulong
)-1ULL << 28);
1860 /* XXX: this case should be optimized,
1861 * giving a mask to tlb_flush_page
1863 tlb_flush_page(env
, addr
| (0x0 << 28));
1864 tlb_flush_page(env
, addr
| (0x1 << 28));
1865 tlb_flush_page(env
, addr
| (0x2 << 28));
1866 tlb_flush_page(env
, addr
| (0x3 << 28));
1867 tlb_flush_page(env
, addr
| (0x4 << 28));
1868 tlb_flush_page(env
, addr
| (0x5 << 28));
1869 tlb_flush_page(env
, addr
| (0x6 << 28));
1870 tlb_flush_page(env
, addr
| (0x7 << 28));
1871 tlb_flush_page(env
, addr
| (0x8 << 28));
1872 tlb_flush_page(env
, addr
| (0x9 << 28));
1873 tlb_flush_page(env
, addr
| (0xA << 28));
1874 tlb_flush_page(env
, addr
| (0xB << 28));
1875 tlb_flush_page(env
, addr
| (0xC << 28));
1876 tlb_flush_page(env
, addr
| (0xD << 28));
1877 tlb_flush_page(env
, addr
| (0xE << 28));
1878 tlb_flush_page(env
, addr
| (0xF << 28));
1880 #if defined(TARGET_PPC64)
1881 case POWERPC_MMU_620
:
1882 case POWERPC_MMU_64B
:
1883 case POWERPC_MMU_2_06
:
1884 /* tlbie invalidate TLBs for all segments */
1885 /* XXX: given the fact that there are too many segments to invalidate,
1886 * and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
1887 * we just invalidate all TLBs
1891 #endif /* defined(TARGET_PPC64) */
1894 cpu_abort(env
, "Unknown MMU model\n");
1898 ppc_tlb_invalidate_all(env
);
1902 /*****************************************************************************/
1903 /* Special registers manipulation */
1904 #if defined(TARGET_PPC64)
1905 void ppc_store_asr (CPUPPCState
*env
, target_ulong value
)
1907 if (env
->asr
!= value
) {
1914 void ppc_store_sdr1 (CPUPPCState
*env
, target_ulong value
)
1916 LOG_MMU("%s: " TARGET_FMT_lx
"\n", __func__
, value
);
1917 if (env
->spr
[SPR_SDR1
] != value
) {
1918 env
->spr
[SPR_SDR1
] = value
;
1919 #if defined(TARGET_PPC64)
1920 if (env
->mmu_model
& POWERPC_MMU_64
) {
1921 target_ulong htabsize
= value
& SDR_64_HTABSIZE
;
1923 if (htabsize
> 28) {
1924 fprintf(stderr
, "Invalid HTABSIZE 0x" TARGET_FMT_lx
1925 " stored in SDR1\n", htabsize
);
1928 env
->htab_mask
= (1ULL << (htabsize
+ 18)) - 1;
1929 env
->htab_base
= value
& SDR_64_HTABORG
;
1931 #endif /* defined(TARGET_PPC64) */
1933 /* FIXME: Should check for valid HTABMASK values */
1934 env
->htab_mask
= ((value
& SDR_32_HTABMASK
) << 16) | 0xFFFF;
1935 env
->htab_base
= value
& SDR_32_HTABORG
;
1941 #if defined(TARGET_PPC64)
1942 target_ulong
ppc_load_sr (CPUPPCState
*env
, int slb_nr
)
1949 void ppc_store_sr (CPUPPCState
*env
, int srnum
, target_ulong value
)
1951 LOG_MMU("%s: reg=%d " TARGET_FMT_lx
" " TARGET_FMT_lx
"\n", __func__
,
1952 srnum
, value
, env
->sr
[srnum
]);
1953 #if defined(TARGET_PPC64)
1954 if (env
->mmu_model
& POWERPC_MMU_64
) {
1955 uint64_t rb
= 0, rs
= 0;
1958 rb
|= ((uint32_t)srnum
& 0xf) << 28;
1959 /* Set the valid bit */
1962 rb
|= (uint32_t)srnum
;
1965 rs
|= (value
& 0xfffffff) << 12;
1967 rs
|= ((value
>> 27) & 0xf) << 9;
1969 ppc_store_slb(env
, rb
, rs
);
1972 if (env
->sr
[srnum
] != value
) {
1973 env
->sr
[srnum
] = value
;
1974 /* Invalidating 256MB of virtual memory in 4kB pages is way longer than
1975 flusing the whole TLB. */
1976 #if !defined(FLUSH_ALL_TLBS) && 0
1978 target_ulong page
, end
;
1979 /* Invalidate 256 MB of virtual memory */
1980 page
= (16 << 20) * srnum
;
1981 end
= page
+ (16 << 20);
1982 for (; page
!= end
; page
+= TARGET_PAGE_SIZE
)
1983 tlb_flush_page(env
, page
);
1990 #endif /* !defined (CONFIG_USER_ONLY) */
1992 /* GDBstub can read and write MSR... */
1993 void ppc_store_msr (CPUPPCState
*env
, target_ulong value
)
1995 hreg_store_msr(env
, value
, 0);
1998 /*****************************************************************************/
1999 /* Exception processing */
2000 #if defined (CONFIG_USER_ONLY)
2001 void do_interrupt (CPUState
*env
)
2003 env
->exception_index
= POWERPC_EXCP_NONE
;
2004 env
->error_code
= 0;
2007 void ppc_hw_interrupt (CPUState
*env
)
2009 env
->exception_index
= POWERPC_EXCP_NONE
;
2010 env
->error_code
= 0;
2012 #else /* defined (CONFIG_USER_ONLY) */
2013 static inline void dump_syscall(CPUState
*env
)
2015 qemu_log_mask(CPU_LOG_INT
, "syscall r0=%016" PRIx64
" r3=%016" PRIx64
2016 " r4=%016" PRIx64
" r5=%016" PRIx64
" r6=%016" PRIx64
2017 " nip=" TARGET_FMT_lx
"\n",
2018 ppc_dump_gpr(env
, 0), ppc_dump_gpr(env
, 3),
2019 ppc_dump_gpr(env
, 4), ppc_dump_gpr(env
, 5),
2020 ppc_dump_gpr(env
, 6), env
->nip
);
2023 /* Note that this function should be greatly optimized
2024 * when called with a constant excp, from ppc_hw_interrupt
2026 static inline void powerpc_excp(CPUState
*env
, int excp_model
, int excp
)
2028 target_ulong msr
, new_msr
, vector
;
2029 int srr0
, srr1
, asrr0
, asrr1
;
2030 int lpes0
, lpes1
, lev
;
2033 /* XXX: find a suitable condition to enable the hypervisor mode */
2034 lpes0
= (env
->spr
[SPR_LPCR
] >> 1) & 1;
2035 lpes1
= (env
->spr
[SPR_LPCR
] >> 2) & 1;
2037 /* Those values ensure we won't enter the hypervisor mode */
2042 qemu_log_mask(CPU_LOG_INT
, "Raise exception at " TARGET_FMT_lx
2043 " => %08x (%02x)\n", env
->nip
, excp
, env
->error_code
);
2045 /* new srr1 value excluding must-be-zero bits */
2046 msr
= env
->msr
& ~0x783f0000ULL
;
2048 /* new interrupt handler msr */
2049 new_msr
= env
->msr
& ((target_ulong
)1 << MSR_ME
);
2051 /* target registers */
2058 case POWERPC_EXCP_NONE
:
2059 /* Should never happen */
2061 case POWERPC_EXCP_CRITICAL
: /* Critical input */
2062 switch (excp_model
) {
2063 case POWERPC_EXCP_40x
:
2064 srr0
= SPR_40x_SRR2
;
2065 srr1
= SPR_40x_SRR3
;
2067 case POWERPC_EXCP_BOOKE
:
2068 srr0
= SPR_BOOKE_CSRR0
;
2069 srr1
= SPR_BOOKE_CSRR1
;
2071 case POWERPC_EXCP_G2
:
2077 case POWERPC_EXCP_MCHECK
: /* Machine check exception */
2079 /* Machine check exception is not enabled.
2080 * Enter checkstop state.
2082 if (qemu_log_enabled()) {
2083 qemu_log("Machine check while not allowed. "
2084 "Entering checkstop state\n");
2086 fprintf(stderr
, "Machine check while not allowed. "
2087 "Entering checkstop state\n");
2090 env
->interrupt_request
|= CPU_INTERRUPT_EXITTB
;
2093 /* XXX: find a suitable condition to enable the hypervisor mode */
2094 new_msr
|= (target_ulong
)MSR_HVB
;
2097 /* machine check exceptions don't have ME set */
2098 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2100 /* XXX: should also have something loaded in DAR / DSISR */
2101 switch (excp_model
) {
2102 case POWERPC_EXCP_40x
:
2103 srr0
= SPR_40x_SRR2
;
2104 srr1
= SPR_40x_SRR3
;
2106 case POWERPC_EXCP_BOOKE
:
2107 srr0
= SPR_BOOKE_MCSRR0
;
2108 srr1
= SPR_BOOKE_MCSRR1
;
2109 asrr0
= SPR_BOOKE_CSRR0
;
2110 asrr1
= SPR_BOOKE_CSRR1
;
2116 case POWERPC_EXCP_DSI
: /* Data storage exception */
2117 LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx
" DAR=" TARGET_FMT_lx
2118 "\n", env
->spr
[SPR_DSISR
], env
->spr
[SPR_DAR
]);
2120 new_msr
|= (target_ulong
)MSR_HVB
;
2122 case POWERPC_EXCP_ISI
: /* Instruction storage exception */
2123 LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx
", nip=" TARGET_FMT_lx
2124 "\n", msr
, env
->nip
);
2126 new_msr
|= (target_ulong
)MSR_HVB
;
2127 msr
|= env
->error_code
;
2129 case POWERPC_EXCP_EXTERNAL
: /* External input */
2131 new_msr
|= (target_ulong
)MSR_HVB
;
2133 case POWERPC_EXCP_ALIGN
: /* Alignment exception */
2135 new_msr
|= (target_ulong
)MSR_HVB
;
2136 /* XXX: this is false */
2137 /* Get rS/rD and rA from faulting opcode */
2138 env
->spr
[SPR_DSISR
] |= (ldl_code((env
->nip
- 4)) & 0x03FF0000) >> 16;
2140 case POWERPC_EXCP_PROGRAM
: /* Program exception */
2141 switch (env
->error_code
& ~0xF) {
2142 case POWERPC_EXCP_FP
:
2143 if ((msr_fe0
== 0 && msr_fe1
== 0) || msr_fp
== 0) {
2144 LOG_EXCP("Ignore floating point exception\n");
2145 env
->exception_index
= POWERPC_EXCP_NONE
;
2146 env
->error_code
= 0;
2150 new_msr
|= (target_ulong
)MSR_HVB
;
2152 if (msr_fe0
== msr_fe1
)
2156 case POWERPC_EXCP_INVAL
:
2157 LOG_EXCP("Invalid instruction at " TARGET_FMT_lx
"\n", env
->nip
);
2159 new_msr
|= (target_ulong
)MSR_HVB
;
2162 case POWERPC_EXCP_PRIV
:
2164 new_msr
|= (target_ulong
)MSR_HVB
;
2167 case POWERPC_EXCP_TRAP
:
2169 new_msr
|= (target_ulong
)MSR_HVB
;
2173 /* Should never occur */
2174 cpu_abort(env
, "Invalid program exception %d. Aborting\n",
2179 case POWERPC_EXCP_FPU
: /* Floating-point unavailable exception */
2181 new_msr
|= (target_ulong
)MSR_HVB
;
2183 case POWERPC_EXCP_SYSCALL
: /* System call exception */
2185 lev
= env
->error_code
;
2186 if ((lev
== 1) && cpu_ppc_hypercall
) {
2187 cpu_ppc_hypercall(env
);
2190 if (lev
== 1 || (lpes0
== 0 && lpes1
== 0))
2191 new_msr
|= (target_ulong
)MSR_HVB
;
2193 case POWERPC_EXCP_APU
: /* Auxiliary processor unavailable */
2195 case POWERPC_EXCP_DECR
: /* Decrementer exception */
2197 new_msr
|= (target_ulong
)MSR_HVB
;
2199 case POWERPC_EXCP_FIT
: /* Fixed-interval timer interrupt */
2201 LOG_EXCP("FIT exception\n");
2203 case POWERPC_EXCP_WDT
: /* Watchdog timer interrupt */
2204 LOG_EXCP("WDT exception\n");
2205 switch (excp_model
) {
2206 case POWERPC_EXCP_BOOKE
:
2207 srr0
= SPR_BOOKE_CSRR0
;
2208 srr1
= SPR_BOOKE_CSRR1
;
2214 case POWERPC_EXCP_DTLB
: /* Data TLB error */
2216 case POWERPC_EXCP_ITLB
: /* Instruction TLB error */
2218 case POWERPC_EXCP_DEBUG
: /* Debug interrupt */
2219 switch (excp_model
) {
2220 case POWERPC_EXCP_BOOKE
:
2221 srr0
= SPR_BOOKE_DSRR0
;
2222 srr1
= SPR_BOOKE_DSRR1
;
2223 asrr0
= SPR_BOOKE_CSRR0
;
2224 asrr1
= SPR_BOOKE_CSRR1
;
2230 cpu_abort(env
, "Debug exception is not implemented yet !\n");
2232 case POWERPC_EXCP_SPEU
: /* SPE/embedded floating-point unavailable */
2234 case POWERPC_EXCP_EFPDI
: /* Embedded floating-point data interrupt */
2236 cpu_abort(env
, "Embedded floating point data exception "
2237 "is not implemented yet !\n");
2239 case POWERPC_EXCP_EFPRI
: /* Embedded floating-point round interrupt */
2241 cpu_abort(env
, "Embedded floating point round exception "
2242 "is not implemented yet !\n");
2244 case POWERPC_EXCP_EPERFM
: /* Embedded performance monitor interrupt */
2247 "Performance counter exception is not implemented yet !\n");
2249 case POWERPC_EXCP_DOORI
: /* Embedded doorbell interrupt */
2252 "Embedded doorbell interrupt is not implemented yet !\n");
2254 case POWERPC_EXCP_DOORCI
: /* Embedded doorbell critical interrupt */
2255 switch (excp_model
) {
2256 case POWERPC_EXCP_BOOKE
:
2257 srr0
= SPR_BOOKE_CSRR0
;
2258 srr1
= SPR_BOOKE_CSRR1
;
2264 cpu_abort(env
, "Embedded doorbell critical interrupt "
2265 "is not implemented yet !\n");
2267 case POWERPC_EXCP_RESET
: /* System reset exception */
2269 /* indicate that we resumed from power save mode */
2272 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2276 /* XXX: find a suitable condition to enable the hypervisor mode */
2277 new_msr
|= (target_ulong
)MSR_HVB
;
2280 case POWERPC_EXCP_DSEG
: /* Data segment exception */
2282 new_msr
|= (target_ulong
)MSR_HVB
;
2284 case POWERPC_EXCP_ISEG
: /* Instruction segment exception */
2286 new_msr
|= (target_ulong
)MSR_HVB
;
2288 case POWERPC_EXCP_HDECR
: /* Hypervisor decrementer exception */
2291 new_msr
|= (target_ulong
)MSR_HVB
;
2292 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2294 case POWERPC_EXCP_TRACE
: /* Trace exception */
2296 new_msr
|= (target_ulong
)MSR_HVB
;
2298 case POWERPC_EXCP_HDSI
: /* Hypervisor data storage exception */
2301 new_msr
|= (target_ulong
)MSR_HVB
;
2302 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2304 case POWERPC_EXCP_HISI
: /* Hypervisor instruction storage exception */
2307 new_msr
|= (target_ulong
)MSR_HVB
;
2308 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2310 case POWERPC_EXCP_HDSEG
: /* Hypervisor data segment exception */
2313 new_msr
|= (target_ulong
)MSR_HVB
;
2314 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2316 case POWERPC_EXCP_HISEG
: /* Hypervisor instruction segment exception */
2319 new_msr
|= (target_ulong
)MSR_HVB
;
2320 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2322 case POWERPC_EXCP_VPU
: /* Vector unavailable exception */
2324 new_msr
|= (target_ulong
)MSR_HVB
;
2326 case POWERPC_EXCP_PIT
: /* Programmable interval timer interrupt */
2327 LOG_EXCP("PIT exception\n");
2329 case POWERPC_EXCP_IO
: /* IO error exception */
2331 cpu_abort(env
, "601 IO error exception is not implemented yet !\n");
2333 case POWERPC_EXCP_RUNM
: /* Run mode exception */
2335 cpu_abort(env
, "601 run mode exception is not implemented yet !\n");
2337 case POWERPC_EXCP_EMUL
: /* Emulation trap exception */
2339 cpu_abort(env
, "602 emulation trap exception "
2340 "is not implemented yet !\n");
2342 case POWERPC_EXCP_IFTLB
: /* Instruction fetch TLB error */
2343 if (lpes1
== 0) /* XXX: check this */
2344 new_msr
|= (target_ulong
)MSR_HVB
;
2345 switch (excp_model
) {
2346 case POWERPC_EXCP_602
:
2347 case POWERPC_EXCP_603
:
2348 case POWERPC_EXCP_603E
:
2349 case POWERPC_EXCP_G2
:
2351 case POWERPC_EXCP_7x5
:
2353 case POWERPC_EXCP_74xx
:
2356 cpu_abort(env
, "Invalid instruction TLB miss exception\n");
2360 case POWERPC_EXCP_DLTLB
: /* Data load TLB miss */
2361 if (lpes1
== 0) /* XXX: check this */
2362 new_msr
|= (target_ulong
)MSR_HVB
;
2363 switch (excp_model
) {
2364 case POWERPC_EXCP_602
:
2365 case POWERPC_EXCP_603
:
2366 case POWERPC_EXCP_603E
:
2367 case POWERPC_EXCP_G2
:
2369 case POWERPC_EXCP_7x5
:
2371 case POWERPC_EXCP_74xx
:
2374 cpu_abort(env
, "Invalid data load TLB miss exception\n");
2378 case POWERPC_EXCP_DSTLB
: /* Data store TLB miss */
2379 if (lpes1
== 0) /* XXX: check this */
2380 new_msr
|= (target_ulong
)MSR_HVB
;
2381 switch (excp_model
) {
2382 case POWERPC_EXCP_602
:
2383 case POWERPC_EXCP_603
:
2384 case POWERPC_EXCP_603E
:
2385 case POWERPC_EXCP_G2
:
2387 /* Swap temporary saved registers with GPRs */
2388 if (!(new_msr
& ((target_ulong
)1 << MSR_TGPR
))) {
2389 new_msr
|= (target_ulong
)1 << MSR_TGPR
;
2390 hreg_swap_gpr_tgpr(env
);
2393 case POWERPC_EXCP_7x5
:
2395 #if defined (DEBUG_SOFTWARE_TLB)
2396 if (qemu_log_enabled()) {
2398 target_ulong
*miss
, *cmp
;
2400 if (excp
== POWERPC_EXCP_IFTLB
) {
2403 miss
= &env
->spr
[SPR_IMISS
];
2404 cmp
= &env
->spr
[SPR_ICMP
];
2406 if (excp
== POWERPC_EXCP_DLTLB
)
2411 miss
= &env
->spr
[SPR_DMISS
];
2412 cmp
= &env
->spr
[SPR_DCMP
];
2414 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2415 TARGET_FMT_lx
" H1 " TARGET_FMT_lx
" H2 "
2416 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2417 env
->spr
[SPR_HASH1
], env
->spr
[SPR_HASH2
],
2421 msr
|= env
->crf
[0] << 28;
2422 msr
|= env
->error_code
; /* key, D/I, S/L bits */
2423 /* Set way using a LRU mechanism */
2424 msr
|= ((env
->last_way
+ 1) & (env
->nb_ways
- 1)) << 17;
2426 case POWERPC_EXCP_74xx
:
2428 #if defined (DEBUG_SOFTWARE_TLB)
2429 if (qemu_log_enabled()) {
2431 target_ulong
*miss
, *cmp
;
2433 if (excp
== POWERPC_EXCP_IFTLB
) {
2436 miss
= &env
->spr
[SPR_TLBMISS
];
2437 cmp
= &env
->spr
[SPR_PTEHI
];
2439 if (excp
== POWERPC_EXCP_DLTLB
)
2444 miss
= &env
->spr
[SPR_TLBMISS
];
2445 cmp
= &env
->spr
[SPR_PTEHI
];
2447 qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2448 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2452 msr
|= env
->error_code
; /* key bit */
2455 cpu_abort(env
, "Invalid data store TLB miss exception\n");
2459 case POWERPC_EXCP_FPA
: /* Floating-point assist exception */
2461 cpu_abort(env
, "Floating point assist exception "
2462 "is not implemented yet !\n");
2464 case POWERPC_EXCP_DABR
: /* Data address breakpoint */
2466 cpu_abort(env
, "DABR exception is not implemented yet !\n");
2468 case POWERPC_EXCP_IABR
: /* Instruction address breakpoint */
2470 cpu_abort(env
, "IABR exception is not implemented yet !\n");
2472 case POWERPC_EXCP_SMI
: /* System management interrupt */
2474 cpu_abort(env
, "SMI exception is not implemented yet !\n");
2476 case POWERPC_EXCP_THERM
: /* Thermal interrupt */
2478 cpu_abort(env
, "Thermal management exception "
2479 "is not implemented yet !\n");
2481 case POWERPC_EXCP_PERFM
: /* Embedded performance monitor interrupt */
2483 new_msr
|= (target_ulong
)MSR_HVB
;
2486 "Performance counter exception is not implemented yet !\n");
2488 case POWERPC_EXCP_VPUA
: /* Vector assist exception */
2490 cpu_abort(env
, "VPU assist exception is not implemented yet !\n");
2492 case POWERPC_EXCP_SOFTP
: /* Soft patch exception */
2495 "970 soft-patch exception is not implemented yet !\n");
2497 case POWERPC_EXCP_MAINT
: /* Maintenance exception */
2500 "970 maintenance exception is not implemented yet !\n");
2502 case POWERPC_EXCP_MEXTBR
: /* Maskable external breakpoint */
2504 cpu_abort(env
, "Maskable external exception "
2505 "is not implemented yet !\n");
2507 case POWERPC_EXCP_NMEXTBR
: /* Non maskable external breakpoint */
2509 cpu_abort(env
, "Non maskable external exception "
2510 "is not implemented yet !\n");
2514 cpu_abort(env
, "Invalid PowerPC exception %d. Aborting\n", excp
);
2517 /* save current instruction location */
2518 env
->spr
[srr0
] = env
->nip
- 4;
2521 /* save next instruction location */
2522 env
->spr
[srr0
] = env
->nip
;
2526 env
->spr
[srr1
] = msr
;
2527 /* If any alternate SRR register are defined, duplicate saved values */
2529 env
->spr
[asrr0
] = env
->spr
[srr0
];
2531 env
->spr
[asrr1
] = env
->spr
[srr1
];
2532 /* If we disactivated any translation, flush TLBs */
2533 if (new_msr
& ((1 << MSR_IR
) | (1 << MSR_DR
)))
2537 new_msr
|= (target_ulong
)1 << MSR_LE
;
2540 /* Jump to handler */
2541 vector
= env
->excp_vectors
[excp
];
2542 if (vector
== (target_ulong
)-1ULL) {
2543 cpu_abort(env
, "Raised an exception without defined vector %d\n",
2546 vector
|= env
->excp_prefix
;
2547 #if defined(TARGET_PPC64)
2548 if (excp_model
== POWERPC_EXCP_BOOKE
) {
2550 vector
= (uint32_t)vector
;
2552 new_msr
|= (target_ulong
)1 << MSR_CM
;
2555 if (!msr_isf
&& !(env
->mmu_model
& POWERPC_MMU_64
)) {
2556 vector
= (uint32_t)vector
;
2558 new_msr
|= (target_ulong
)1 << MSR_SF
;
2562 /* XXX: we don't use hreg_store_msr here as already have treated
2563 * any special case that could occur. Just store MSR and update hflags
2565 env
->msr
= new_msr
& env
->msr_mask
;
2566 hreg_compute_hflags(env
);
2568 /* Reset exception state */
2569 env
->exception_index
= POWERPC_EXCP_NONE
;
2570 env
->error_code
= 0;
2572 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
2573 /* XXX: The BookE changes address space when switching modes,
2574 we should probably implement that as different MMU indexes,
2575 but for the moment we do it the slow way and flush all. */
2580 void do_interrupt (CPUState
*env
)
2582 powerpc_excp(env
, env
->excp_model
, env
->exception_index
);
2585 void ppc_hw_interrupt (CPUPPCState
*env
)
2590 qemu_log_mask(CPU_LOG_INT
, "%s: %p pending %08x req %08x me %d ee %d\n",
2591 __func__
, env
, env
->pending_interrupts
,
2592 env
->interrupt_request
, (int)msr_me
, (int)msr_ee
);
2594 /* External reset */
2595 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_RESET
)) {
2596 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_RESET
);
2597 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_RESET
);
2600 /* Machine check exception */
2601 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_MCK
)) {
2602 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_MCK
);
2603 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_MCHECK
);
2607 /* External debug exception */
2608 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DEBUG
)) {
2609 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DEBUG
);
2610 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DEBUG
);
2615 /* XXX: find a suitable condition to enable the hypervisor mode */
2616 hdice
= env
->spr
[SPR_LPCR
] & 1;
2620 if ((msr_ee
!= 0 || msr_hv
== 0 || msr_pr
!= 0) && hdice
!= 0) {
2621 /* Hypervisor decrementer exception */
2622 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_HDECR
)) {
2623 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_HDECR
);
2624 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_HDECR
);
2629 /* External critical interrupt */
2630 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CEXT
)) {
2631 /* Taking a critical external interrupt does not clear the external
2632 * critical interrupt status
2635 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CEXT
);
2637 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_CRITICAL
);
2642 /* Watchdog timer on embedded PowerPC */
2643 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_WDT
)) {
2644 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_WDT
);
2645 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_WDT
);
2648 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CDOORBELL
)) {
2649 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CDOORBELL
);
2650 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORCI
);
2653 /* Fixed interval timer on embedded PowerPC */
2654 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_FIT
)) {
2655 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_FIT
);
2656 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_FIT
);
2659 /* Programmable interval timer on embedded PowerPC */
2660 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PIT
)) {
2661 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PIT
);
2662 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PIT
);
2665 /* Decrementer exception */
2666 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DECR
)) {
2667 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DECR
);
2668 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DECR
);
2671 /* External interrupt */
2672 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_EXT
)) {
2673 /* Taking an external interrupt does not clear the external
2677 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_EXT
);
2679 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_EXTERNAL
);
2682 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DOORBELL
)) {
2683 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DOORBELL
);
2684 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORI
);
2687 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PERFM
)) {
2688 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PERFM
);
2689 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PERFM
);
2692 /* Thermal interrupt */
2693 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_THERM
)) {
2694 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_THERM
);
2695 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_THERM
);
2700 #endif /* !CONFIG_USER_ONLY */
2702 void cpu_dump_rfi (target_ulong RA
, target_ulong msr
)
2704 qemu_log("Return from exception at " TARGET_FMT_lx
" with flags "
2705 TARGET_FMT_lx
"\n", RA
, msr
);
2708 void cpu_reset(CPUPPCState
*env
)
2712 if (qemu_loglevel_mask(CPU_LOG_RESET
)) {
2713 qemu_log("CPU Reset (CPU %d)\n", env
->cpu_index
);
2714 log_cpu_state(env
, 0);
2717 msr
= (target_ulong
)0;
2719 /* XXX: find a suitable condition to enable the hypervisor mode */
2720 msr
|= (target_ulong
)MSR_HVB
;
2722 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
2723 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
2724 msr
|= (target_ulong
)1 << MSR_EP
;
2725 #if defined (DO_SINGLE_STEP) && 0
2726 /* Single step trace mode */
2727 msr
|= (target_ulong
)1 << MSR_SE
;
2728 msr
|= (target_ulong
)1 << MSR_BE
;
2730 #if defined(CONFIG_USER_ONLY)
2731 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
2732 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
2733 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
2734 msr
|= (target_ulong
)1 << MSR_PR
;
2736 env
->excp_prefix
= env
->hreset_excp_prefix
;
2737 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
2738 if (env
->mmu_model
!= POWERPC_MMU_REAL
)
2739 ppc_tlb_invalidate_all(env
);
2741 env
->msr
= msr
& env
->msr_mask
;
2742 #if defined(TARGET_PPC64)
2743 if (env
->mmu_model
& POWERPC_MMU_64
)
2744 env
->msr
|= (1ULL << MSR_SF
);
2746 hreg_compute_hflags(env
);
2747 env
->reserve_addr
= (target_ulong
)-1ULL;
2748 /* Be sure no exception or interrupt is pending */
2749 env
->pending_interrupts
= 0;
2750 env
->exception_index
= POWERPC_EXCP_NONE
;
2751 env
->error_code
= 0;
2752 /* Flush all TLBs */
2756 CPUPPCState
*cpu_ppc_init (const char *cpu_model
)
2759 const ppc_def_t
*def
;
2761 def
= cpu_ppc_find_by_name(cpu_model
);
2765 env
= qemu_mallocz(sizeof(CPUPPCState
));
2767 ppc_translate_init();
2768 env
->cpu_model_str
= cpu_model
;
2769 cpu_ppc_register_internal(env
, def
);
2771 qemu_init_vcpu(env
);
2776 void cpu_ppc_close (CPUPPCState
*env
)
2778 /* Should also remove all opcode tables... */