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)
74 /*****************************************************************************/
75 /* PowerPC MMU emulation */
77 #if defined(CONFIG_USER_ONLY)
78 int cpu_ppc_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
79 int mmu_idx
, int is_softmmu
)
81 int exception
, error_code
;
84 exception
= POWERPC_EXCP_ISI
;
85 error_code
= 0x40000000;
87 exception
= POWERPC_EXCP_DSI
;
88 error_code
= 0x40000000;
90 error_code
|= 0x02000000;
91 env
->spr
[SPR_DAR
] = address
;
92 env
->spr
[SPR_DSISR
] = error_code
;
94 env
->exception_index
= exception
;
95 env
->error_code
= error_code
;
101 /* Common routines used by software and hardware TLBs emulation */
102 static inline int pte_is_valid(target_ulong pte0
)
104 return pte0
& 0x80000000 ? 1 : 0;
107 static inline void pte_invalidate(target_ulong
*pte0
)
109 *pte0
&= ~0x80000000;
112 #if defined(TARGET_PPC64)
113 static inline int pte64_is_valid(target_ulong pte0
)
115 return pte0
& 0x0000000000000001ULL
? 1 : 0;
118 static inline void pte64_invalidate(target_ulong
*pte0
)
120 *pte0
&= ~0x0000000000000001ULL
;
124 #define PTE_PTEM_MASK 0x7FFFFFBF
125 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
126 #if defined(TARGET_PPC64)
127 #define PTE64_PTEM_MASK 0xFFFFFFFFFFFFFF80ULL
128 #define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F)
131 static inline int pp_check(int key
, int pp
, int nx
)
135 /* Compute access rights */
136 /* When pp is 3/7, the result is undefined. Set it to noaccess */
143 access
|= PAGE_WRITE
;
161 access
= PAGE_READ
| PAGE_WRITE
;
171 static inline int check_prot(int prot
, int rw
, int access_type
)
175 if (access_type
== ACCESS_CODE
) {
176 if (prot
& PAGE_EXEC
)
181 if (prot
& PAGE_WRITE
)
186 if (prot
& PAGE_READ
)
195 static inline int _pte_check(mmu_ctx_t
*ctx
, int is_64b
, target_ulong pte0
,
196 target_ulong pte1
, int h
, int rw
, int type
)
198 target_ulong ptem
, mmask
;
199 int access
, ret
, pteh
, ptev
, pp
;
202 /* Check validity and table match */
203 #if defined(TARGET_PPC64)
205 ptev
= pte64_is_valid(pte0
);
206 pteh
= (pte0
>> 1) & 1;
210 ptev
= pte_is_valid(pte0
);
211 pteh
= (pte0
>> 6) & 1;
213 if (ptev
&& h
== pteh
) {
214 /* Check vsid & api */
215 #if defined(TARGET_PPC64)
217 ptem
= pte0
& PTE64_PTEM_MASK
;
218 mmask
= PTE64_CHECK_MASK
;
219 pp
= (pte1
& 0x00000003) | ((pte1
>> 61) & 0x00000004);
220 ctx
->nx
= (pte1
>> 2) & 1; /* No execute bit */
221 ctx
->nx
|= (pte1
>> 3) & 1; /* Guarded bit */
225 ptem
= pte0
& PTE_PTEM_MASK
;
226 mmask
= PTE_CHECK_MASK
;
227 pp
= pte1
& 0x00000003;
229 if (ptem
== ctx
->ptem
) {
230 if (ctx
->raddr
!= (target_phys_addr_t
)-1ULL) {
231 /* all matches should have equal RPN, WIMG & PP */
232 if ((ctx
->raddr
& mmask
) != (pte1
& mmask
)) {
233 qemu_log("Bad RPN/WIMG/PP\n");
237 /* Compute access rights */
238 access
= pp_check(ctx
->key
, pp
, ctx
->nx
);
239 /* Keep the matching PTE informations */
242 ret
= check_prot(ctx
->prot
, rw
, type
);
245 LOG_MMU("PTE access granted !\n");
247 /* Access right violation */
248 LOG_MMU("PTE access rejected\n");
256 static inline int pte32_check(mmu_ctx_t
*ctx
, target_ulong pte0
,
257 target_ulong pte1
, int h
, int rw
, int type
)
259 return _pte_check(ctx
, 0, pte0
, pte1
, h
, rw
, type
);
262 #if defined(TARGET_PPC64)
263 static inline int pte64_check(mmu_ctx_t
*ctx
, target_ulong pte0
,
264 target_ulong pte1
, int h
, int rw
, int type
)
266 return _pte_check(ctx
, 1, pte0
, pte1
, h
, rw
, type
);
270 static inline int pte_update_flags(mmu_ctx_t
*ctx
, target_ulong
*pte1p
,
275 /* Update page flags */
276 if (!(*pte1p
& 0x00000100)) {
277 /* Update accessed flag */
278 *pte1p
|= 0x00000100;
281 if (!(*pte1p
& 0x00000080)) {
282 if (rw
== 1 && ret
== 0) {
283 /* Update changed flag */
284 *pte1p
|= 0x00000080;
287 /* Force page fault for first write access */
288 ctx
->prot
&= ~PAGE_WRITE
;
295 /* Software driven TLB helpers */
296 static inline int ppc6xx_tlb_getnum(CPUState
*env
, target_ulong eaddr
, int way
,
301 /* Select TLB num in a way from address */
302 nr
= (eaddr
>> TARGET_PAGE_BITS
) & (env
->tlb_per_way
- 1);
304 nr
+= env
->tlb_per_way
* way
;
305 /* 6xx have separate TLBs for instructions and data */
306 if (is_code
&& env
->id_tlbs
== 1)
312 static inline void ppc6xx_tlb_invalidate_all(CPUState
*env
)
317 //LOG_SWTLB("Invalidate all TLBs\n");
318 /* Invalidate all defined software TLB */
320 if (env
->id_tlbs
== 1)
322 for (nr
= 0; nr
< max
; nr
++) {
323 tlb
= &env
->tlb
[nr
].tlb6
;
324 pte_invalidate(&tlb
->pte0
);
329 static inline void __ppc6xx_tlb_invalidate_virt(CPUState
*env
,
331 int is_code
, int match_epn
)
333 #if !defined(FLUSH_ALL_TLBS)
337 /* Invalidate ITLB + DTLB, all ways */
338 for (way
= 0; way
< env
->nb_ways
; way
++) {
339 nr
= ppc6xx_tlb_getnum(env
, eaddr
, way
, is_code
);
340 tlb
= &env
->tlb
[nr
].tlb6
;
341 if (pte_is_valid(tlb
->pte0
) && (match_epn
== 0 || eaddr
== tlb
->EPN
)) {
342 LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx
"\n", nr
,
344 pte_invalidate(&tlb
->pte0
);
345 tlb_flush_page(env
, tlb
->EPN
);
349 /* XXX: PowerPC specification say this is valid as well */
350 ppc6xx_tlb_invalidate_all(env
);
354 static inline void ppc6xx_tlb_invalidate_virt(CPUState
*env
,
355 target_ulong eaddr
, int is_code
)
357 __ppc6xx_tlb_invalidate_virt(env
, eaddr
, is_code
, 0);
360 void ppc6xx_tlb_store (CPUState
*env
, target_ulong EPN
, int way
, int is_code
,
361 target_ulong pte0
, target_ulong pte1
)
366 nr
= ppc6xx_tlb_getnum(env
, EPN
, way
, is_code
);
367 tlb
= &env
->tlb
[nr
].tlb6
;
368 LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx
" PTE0 " TARGET_FMT_lx
369 " PTE1 " TARGET_FMT_lx
"\n", nr
, env
->nb_tlb
, EPN
, pte0
, pte1
);
370 /* Invalidate any pending reference in Qemu for this virtual address */
371 __ppc6xx_tlb_invalidate_virt(env
, EPN
, is_code
, 1);
375 /* Store last way for LRU mechanism */
379 static inline int ppc6xx_tlb_check(CPUState
*env
, mmu_ctx_t
*ctx
,
380 target_ulong eaddr
, int rw
, int access_type
)
387 ret
= -1; /* No TLB found */
388 for (way
= 0; way
< env
->nb_ways
; way
++) {
389 nr
= ppc6xx_tlb_getnum(env
, eaddr
, way
,
390 access_type
== ACCESS_CODE
? 1 : 0);
391 tlb
= &env
->tlb
[nr
].tlb6
;
392 /* This test "emulates" the PTE index match for hardware TLBs */
393 if ((eaddr
& TARGET_PAGE_MASK
) != tlb
->EPN
) {
394 LOG_SWTLB("TLB %d/%d %s [" TARGET_FMT_lx
" " TARGET_FMT_lx
395 "] <> " TARGET_FMT_lx
"\n", nr
, env
->nb_tlb
,
396 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
397 tlb
->EPN
, tlb
->EPN
+ TARGET_PAGE_SIZE
, eaddr
);
400 LOG_SWTLB("TLB %d/%d %s " TARGET_FMT_lx
" <> " TARGET_FMT_lx
" "
401 TARGET_FMT_lx
" %c %c\n", nr
, env
->nb_tlb
,
402 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
403 tlb
->EPN
, eaddr
, tlb
->pte1
,
404 rw
? 'S' : 'L', access_type
== ACCESS_CODE
? 'I' : 'D');
405 switch (pte32_check(ctx
, tlb
->pte0
, tlb
->pte1
, 0, rw
, access_type
)) {
407 /* TLB inconsistency */
410 /* Access violation */
420 /* XXX: we should go on looping to check all TLBs consistency
421 * but we can speed-up the whole thing as the
422 * result would be undefined if TLBs are not consistent.
431 LOG_SWTLB("found TLB at addr " TARGET_FMT_plx
" prot=%01x ret=%d\n",
432 ctx
->raddr
& TARGET_PAGE_MASK
, ctx
->prot
, ret
);
433 /* Update page flags */
434 pte_update_flags(ctx
, &env
->tlb
[best
].tlb6
.pte1
, ret
, rw
);
440 /* Perform BAT hit & translation */
441 static inline void bat_size_prot(CPUState
*env
, target_ulong
*blp
, int *validp
,
442 int *protp
, target_ulong
*BATu
,
448 bl
= (*BATu
& 0x00001FFC) << 15;
451 if (((msr_pr
== 0) && (*BATu
& 0x00000002)) ||
452 ((msr_pr
!= 0) && (*BATu
& 0x00000001))) {
454 pp
= *BATl
& 0x00000003;
456 prot
= PAGE_READ
| PAGE_EXEC
;
466 static inline void bat_601_size_prot(CPUState
*env
, target_ulong
*blp
,
467 int *validp
, int *protp
,
468 target_ulong
*BATu
, target_ulong
*BATl
)
471 int key
, pp
, valid
, prot
;
473 bl
= (*BATl
& 0x0000003F) << 17;
474 LOG_BATS("b %02x ==> bl " TARGET_FMT_lx
" msk " TARGET_FMT_lx
"\n",
475 (uint8_t)(*BATl
& 0x0000003F), bl
, ~bl
);
477 valid
= (*BATl
>> 6) & 1;
479 pp
= *BATu
& 0x00000003;
481 key
= (*BATu
>> 3) & 1;
483 key
= (*BATu
>> 2) & 1;
484 prot
= pp_check(key
, pp
, 0);
491 static inline int get_bat(CPUState
*env
, mmu_ctx_t
*ctx
, target_ulong
virtual,
494 target_ulong
*BATlt
, *BATut
, *BATu
, *BATl
;
495 target_ulong BEPIl
, BEPIu
, bl
;
499 LOG_BATS("%s: %cBAT v " TARGET_FMT_lx
"\n", __func__
,
500 type
== ACCESS_CODE
? 'I' : 'D', virtual);
503 BATlt
= env
->IBAT
[1];
504 BATut
= env
->IBAT
[0];
507 BATlt
= env
->DBAT
[1];
508 BATut
= env
->DBAT
[0];
511 for (i
= 0; i
< env
->nb_BATs
; i
++) {
514 BEPIu
= *BATu
& 0xF0000000;
515 BEPIl
= *BATu
& 0x0FFE0000;
516 if (unlikely(env
->mmu_model
== POWERPC_MMU_601
)) {
517 bat_601_size_prot(env
, &bl
, &valid
, &prot
, BATu
, BATl
);
519 bat_size_prot(env
, &bl
, &valid
, &prot
, BATu
, BATl
);
521 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx
" BATu " TARGET_FMT_lx
522 " BATl " TARGET_FMT_lx
"\n", __func__
,
523 type
== ACCESS_CODE
? 'I' : 'D', i
, virtual, *BATu
, *BATl
);
524 if ((virtual & 0xF0000000) == BEPIu
&&
525 ((virtual & 0x0FFE0000) & ~bl
) == BEPIl
) {
528 /* Get physical address */
529 ctx
->raddr
= (*BATl
& 0xF0000000) |
530 ((virtual & 0x0FFE0000 & bl
) | (*BATl
& 0x0FFE0000)) |
531 (virtual & 0x0001F000);
532 /* Compute access rights */
534 ret
= check_prot(ctx
->prot
, rw
, type
);
536 LOG_BATS("BAT %d match: r " TARGET_FMT_plx
" prot=%c%c\n",
537 i
, ctx
->raddr
, ctx
->prot
& PAGE_READ
? 'R' : '-',
538 ctx
->prot
& PAGE_WRITE
? 'W' : '-');
544 #if defined(DEBUG_BATS)
545 if (qemu_log_enabled()) {
546 LOG_BATS("no BAT match for " TARGET_FMT_lx
":\n", virtual);
547 for (i
= 0; i
< 4; i
++) {
550 BEPIu
= *BATu
& 0xF0000000;
551 BEPIl
= *BATu
& 0x0FFE0000;
552 bl
= (*BATu
& 0x00001FFC) << 15;
553 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx
" BATu " TARGET_FMT_lx
554 " BATl " TARGET_FMT_lx
" \n\t" TARGET_FMT_lx
" "
555 TARGET_FMT_lx
" " TARGET_FMT_lx
"\n",
556 __func__
, type
== ACCESS_CODE
? 'I' : 'D', i
, virtual,
557 *BATu
, *BATl
, BEPIu
, BEPIl
, bl
);
566 /* PTE table lookup */
567 static inline int _find_pte(mmu_ctx_t
*ctx
, int is_64b
, int h
, int rw
,
568 int type
, int target_page_bits
)
570 target_ulong base
, pte0
, pte1
;
574 ret
= -1; /* No entry found */
575 base
= ctx
->pg_addr
[h
];
576 for (i
= 0; i
< 8; i
++) {
577 #if defined(TARGET_PPC64)
579 pte0
= ldq_phys(base
+ (i
* 16));
580 pte1
= ldq_phys(base
+ (i
* 16) + 8);
582 /* We have a TLB that saves 4K pages, so let's
583 * split a huge page to 4k chunks */
584 if (target_page_bits
!= TARGET_PAGE_BITS
)
585 pte1
|= (ctx
->eaddr
& (( 1 << target_page_bits
) - 1))
588 r
= pte64_check(ctx
, pte0
, pte1
, h
, rw
, type
);
589 LOG_MMU("Load pte from " TARGET_FMT_lx
" => " TARGET_FMT_lx
" "
590 TARGET_FMT_lx
" %d %d %d " TARGET_FMT_lx
"\n",
591 base
+ (i
* 16), pte0
, pte1
, (int)(pte0
& 1), h
,
592 (int)((pte0
>> 1) & 1), ctx
->ptem
);
596 pte0
= ldl_phys(base
+ (i
* 8));
597 pte1
= ldl_phys(base
+ (i
* 8) + 4);
598 r
= pte32_check(ctx
, pte0
, pte1
, h
, rw
, type
);
599 LOG_MMU("Load pte from " TARGET_FMT_lx
" => " TARGET_FMT_lx
" "
600 TARGET_FMT_lx
" %d %d %d " TARGET_FMT_lx
"\n",
601 base
+ (i
* 8), pte0
, pte1
, (int)(pte0
>> 31), h
,
602 (int)((pte0
>> 6) & 1), ctx
->ptem
);
606 /* PTE inconsistency */
609 /* Access violation */
619 /* XXX: we should go on looping to check all PTEs consistency
620 * but if we can speed-up the whole thing as the
621 * result would be undefined if PTEs are not consistent.
630 LOG_MMU("found PTE at addr " TARGET_FMT_lx
" prot=%01x ret=%d\n",
631 ctx
->raddr
, ctx
->prot
, ret
);
632 /* Update page flags */
634 if (pte_update_flags(ctx
, &pte1
, ret
, rw
) == 1) {
635 #if defined(TARGET_PPC64)
637 stq_phys_notdirty(base
+ (good
* 16) + 8, pte1
);
641 stl_phys_notdirty(base
+ (good
* 8) + 4, pte1
);
649 static inline int find_pte32(mmu_ctx_t
*ctx
, int h
, int rw
, int type
,
650 int target_page_bits
)
652 return _find_pte(ctx
, 0, h
, rw
, type
, target_page_bits
);
655 #if defined(TARGET_PPC64)
656 static inline int find_pte64(mmu_ctx_t
*ctx
, int h
, int rw
, int type
,
657 int target_page_bits
)
659 return _find_pte(ctx
, 1, h
, rw
, type
, target_page_bits
);
663 static inline int find_pte(CPUState
*env
, mmu_ctx_t
*ctx
, int h
, int rw
,
664 int type
, int target_page_bits
)
666 #if defined(TARGET_PPC64)
667 if (env
->mmu_model
& POWERPC_MMU_64
)
668 return find_pte64(ctx
, h
, rw
, type
, target_page_bits
);
671 return find_pte32(ctx
, h
, rw
, type
, target_page_bits
);
674 #if defined(TARGET_PPC64)
675 static inline int slb_lookup(CPUPPCState
*env
, target_ulong eaddr
,
676 target_ulong
*vsid
, target_ulong
*page_mask
,
677 int *attr
, int *target_page_bits
)
682 LOG_SLB("%s: eaddr " TARGET_FMT_lx
"\n", __func__
, eaddr
);
684 esid
= (eaddr
& SEGMENT_MASK_256M
) | 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 if (slb
->esid
== esid
) {
692 *vsid
= (slb
->vsid
& SLB_VSID_VSID
) >> SLB_VSID_SHIFT
;
693 *page_mask
= ~SEGMENT_MASK_256M
;
694 *attr
= slb
->vsid
& SLB_VSID_ATTR
;
695 if (target_page_bits
) {
696 *target_page_bits
= (slb
->vsid
& SLB_VSID_L
)
697 ? TARGET_PAGE_BITS_16M
707 void ppc_slb_invalidate_all (CPUPPCState
*env
)
709 int n
, do_invalidate
;
712 /* XXX: Warning: slbia never invalidates the first segment */
713 for (n
= 1; n
< env
->slb_nr
; n
++) {
714 ppc_slb_t
*slb
= &env
->slb
[n
];
716 if (slb
->esid
& SLB_ESID_V
) {
717 slb
->esid
&= ~SLB_ESID_V
;
718 /* XXX: given the fact that segment size is 256 MB or 1TB,
719 * and we still don't have a tlb_flush_mask(env, n, mask)
720 * in Qemu, we just invalidate all TLBs
729 void ppc_slb_invalidate_one (CPUPPCState
*env
, uint64_t T0
)
731 target_ulong vsid
, page_mask
;
736 n
= slb_lookup(env
, T0
, &vsid
, &page_mask
, &attr
, NULL
);
743 if (slb
->esid
& SLB_ESID_V
) {
744 slb
->esid
&= ~SLB_ESID_V
;
746 /* XXX: given the fact that segment size is 256 MB or 1TB,
747 * and we still don't have a tlb_flush_mask(env, n, mask)
748 * in Qemu, we just invalidate all TLBs
754 int ppc_store_slb (CPUPPCState
*env
, target_ulong rb
, target_ulong rs
)
756 int slot
= rb
& 0xfff;
757 uint64_t esid
= rb
& ~0xfff;
758 ppc_slb_t
*slb
= &env
->slb
[slot
];
760 if (slot
>= env
->slb_nr
) {
767 LOG_SLB("%s: %d " TARGET_FMT_lx
" - " TARGET_FMT_lx
" => %016" PRIx64
768 " %016" PRIx64
"\n", __func__
, slot
, rb
, rs
,
769 slb
->esid
, slb
->vsid
);
773 #endif /* defined(TARGET_PPC64) */
775 /* Perform segment based translation */
776 static inline target_phys_addr_t
get_pgaddr(target_phys_addr_t sdr1
,
778 target_phys_addr_t hash
,
779 target_phys_addr_t mask
)
781 return (sdr1
& ((target_phys_addr_t
)(-1ULL) << sdr_sh
)) | (hash
& mask
);
784 static inline int get_segment(CPUState
*env
, mmu_ctx_t
*ctx
,
785 target_ulong eaddr
, int rw
, int type
)
787 target_phys_addr_t sdr
, hash
, mask
, sdr_mask
, htab_mask
;
788 target_ulong sr
, vsid
, vsid_mask
, pgidx
, page_mask
;
789 int ds
, vsid_sh
, sdr_sh
, pr
, target_page_bits
;
793 #if defined(TARGET_PPC64)
794 if (env
->mmu_model
& POWERPC_MMU_64
) {
797 LOG_MMU("Check SLBs\n");
798 ret
= slb_lookup(env
, eaddr
, &vsid
, &page_mask
, &attr
,
802 ctx
->key
= !!(pr
? (attr
& SLB_VSID_KP
) : (attr
& SLB_VSID_KS
));
804 ctx
->nx
= !!(attr
& SLB_VSID_N
);
806 vsid_mask
= 0x00003FFFFFFFFF80ULL
;
811 #endif /* defined(TARGET_PPC64) */
813 sr
= env
->sr
[eaddr
>> 28];
814 page_mask
= 0x0FFFFFFF;
815 ctx
->key
= (((sr
& 0x20000000) && (pr
!= 0)) ||
816 ((sr
& 0x40000000) && (pr
== 0))) ? 1 : 0;
817 ds
= sr
& 0x80000000 ? 1 : 0;
818 ctx
->nx
= sr
& 0x10000000 ? 1 : 0;
819 vsid
= sr
& 0x00FFFFFF;
820 vsid_mask
= 0x01FFFFC0;
824 target_page_bits
= TARGET_PAGE_BITS
;
825 LOG_MMU("Check segment v=" TARGET_FMT_lx
" %d " TARGET_FMT_lx
" nip="
826 TARGET_FMT_lx
" lr=" TARGET_FMT_lx
827 " ir=%d dr=%d pr=%d %d t=%d\n",
828 eaddr
, (int)(eaddr
>> 28), sr
, env
->nip
, env
->lr
, (int)msr_ir
,
829 (int)msr_dr
, pr
!= 0 ? 1 : 0, rw
, type
);
831 LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx
"\n",
832 ctx
->key
, ds
, ctx
->nx
, vsid
);
835 /* Check if instruction fetch is allowed, if needed */
836 if (type
!= ACCESS_CODE
|| ctx
->nx
== 0) {
837 /* Page address translation */
838 /* Primary table address */
840 pgidx
= (eaddr
& page_mask
) >> target_page_bits
;
841 #if defined(TARGET_PPC64)
842 if (env
->mmu_model
& POWERPC_MMU_64
) {
843 htab_mask
= 0x0FFFFFFF >> (28 - (sdr
& 0x1F));
844 /* XXX: this is false for 1 TB segments */
845 hash
= ((vsid
^ pgidx
) << vsid_sh
) & vsid_mask
;
849 htab_mask
= sdr
& 0x000001FF;
850 hash
= ((vsid
^ pgidx
) << vsid_sh
) & vsid_mask
;
852 mask
= (htab_mask
<< sdr_sh
) | sdr_mask
;
853 LOG_MMU("sdr " TARGET_FMT_plx
" sh %d hash " TARGET_FMT_plx
854 " mask " TARGET_FMT_plx
" " TARGET_FMT_lx
"\n",
855 sdr
, sdr_sh
, hash
, mask
, page_mask
);
856 ctx
->pg_addr
[0] = get_pgaddr(sdr
, sdr_sh
, hash
, mask
);
857 /* Secondary table address */
858 hash
= (~hash
) & vsid_mask
;
859 LOG_MMU("sdr " TARGET_FMT_plx
" sh %d hash " TARGET_FMT_plx
860 " mask " TARGET_FMT_plx
"\n", sdr
, sdr_sh
, hash
, mask
);
861 ctx
->pg_addr
[1] = get_pgaddr(sdr
, sdr_sh
, hash
, mask
);
862 #if defined(TARGET_PPC64)
863 if (env
->mmu_model
& POWERPC_MMU_64
) {
864 /* Only 5 bits of the page index are used in the AVPN */
865 if (target_page_bits
> 23) {
866 ctx
->ptem
= (vsid
<< 12) |
867 ((pgidx
<< (target_page_bits
- 16)) & 0xF80);
869 ctx
->ptem
= (vsid
<< 12) | ((pgidx
>> 4) & 0x0F80);
874 ctx
->ptem
= (vsid
<< 7) | (pgidx
>> 10);
876 /* Initialize real address with an invalid value */
877 ctx
->raddr
= (target_phys_addr_t
)-1ULL;
878 if (unlikely(env
->mmu_model
== POWERPC_MMU_SOFT_6xx
||
879 env
->mmu_model
== POWERPC_MMU_SOFT_74xx
)) {
880 /* Software TLB search */
881 ret
= ppc6xx_tlb_check(env
, ctx
, eaddr
, rw
, type
);
883 LOG_MMU("0 sdr1=" TARGET_FMT_plx
" vsid=" TARGET_FMT_lx
" "
884 "api=" TARGET_FMT_lx
" hash=" TARGET_FMT_plx
885 " pg_addr=" TARGET_FMT_plx
"\n",
886 sdr
, vsid
, pgidx
, hash
, ctx
->pg_addr
[0]);
887 /* Primary table lookup */
888 ret
= find_pte(env
, ctx
, 0, rw
, type
, target_page_bits
);
890 /* Secondary table lookup */
891 if (eaddr
!= 0xEFFFFFFF)
892 LOG_MMU("1 sdr1=" TARGET_FMT_plx
" vsid=" TARGET_FMT_lx
" "
893 "api=" TARGET_FMT_lx
" hash=" TARGET_FMT_plx
894 " pg_addr=" TARGET_FMT_plx
"\n", sdr
, vsid
,
895 pgidx
, hash
, ctx
->pg_addr
[1]);
896 ret2
= find_pte(env
, ctx
, 1, rw
, type
,
902 #if defined (DUMP_PAGE_TABLES)
903 if (qemu_log_enabled()) {
904 target_phys_addr_t curaddr
;
905 uint32_t a0
, a1
, a2
, a3
;
906 qemu_log("Page table: " TARGET_FMT_plx
" len " TARGET_FMT_plx
907 "\n", sdr
, mask
+ 0x80);
908 for (curaddr
= sdr
; curaddr
< (sdr
+ mask
+ 0x80);
910 a0
= ldl_phys(curaddr
);
911 a1
= ldl_phys(curaddr
+ 4);
912 a2
= ldl_phys(curaddr
+ 8);
913 a3
= ldl_phys(curaddr
+ 12);
914 if (a0
!= 0 || a1
!= 0 || a2
!= 0 || a3
!= 0) {
915 qemu_log(TARGET_FMT_plx
": %08x %08x %08x %08x\n",
916 curaddr
, a0
, a1
, a2
, a3
);
922 LOG_MMU("No access allowed\n");
926 LOG_MMU("direct store...\n");
927 /* Direct-store segment : absolutely *BUGGY* for now */
930 /* Integer load/store : only access allowed */
933 /* No code fetch is allowed in direct-store areas */
936 /* Floating point load/store */
939 /* lwarx, ldarx or srwcx. */
942 /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
943 /* Should make the instruction do no-op.
944 * As it already do no-op, it's quite easy :-)
952 qemu_log("ERROR: instruction should not need "
953 "address translation\n");
956 if ((rw
== 1 || ctx
->key
!= 1) && (rw
== 0 || ctx
->key
!= 0)) {
967 /* Generic TLB check function for embedded PowerPC implementations */
968 static inline int ppcemb_tlb_check(CPUState
*env
, ppcemb_tlb_t
*tlb
,
969 target_phys_addr_t
*raddrp
,
970 target_ulong address
, uint32_t pid
, int ext
,
975 /* Check valid flag */
976 if (!(tlb
->prot
& PAGE_VALID
)) {
979 mask
= ~(tlb
->size
- 1);
980 LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx
" PID %u <=> " TARGET_FMT_lx
981 " " TARGET_FMT_lx
" %u\n", __func__
, i
, address
, pid
, tlb
->EPN
,
982 mask
, (uint32_t)tlb
->PID
);
984 if (tlb
->PID
!= 0 && tlb
->PID
!= pid
)
986 /* Check effective address */
987 if ((address
& mask
) != tlb
->EPN
)
989 *raddrp
= (tlb
->RPN
& mask
) | (address
& ~mask
);
990 #if (TARGET_PHYS_ADDR_BITS >= 36)
992 /* Extend the physical address to 36 bits */
993 *raddrp
|= (target_phys_addr_t
)(tlb
->RPN
& 0xF) << 32;
1000 /* Generic TLB search function for PowerPC embedded implementations */
1001 int ppcemb_tlb_search (CPUPPCState
*env
, target_ulong address
, uint32_t pid
)
1004 target_phys_addr_t raddr
;
1007 /* Default return value is no match */
1009 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1010 tlb
= &env
->tlb
[i
].tlbe
;
1011 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
, pid
, 0, i
) == 0) {
1020 /* Helpers specific to PowerPC 40x implementations */
1021 static inline void ppc4xx_tlb_invalidate_all(CPUState
*env
)
1026 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1027 tlb
= &env
->tlb
[i
].tlbe
;
1028 tlb
->prot
&= ~PAGE_VALID
;
1033 static inline void ppc4xx_tlb_invalidate_virt(CPUState
*env
,
1034 target_ulong eaddr
, uint32_t pid
)
1036 #if !defined(FLUSH_ALL_TLBS)
1038 target_phys_addr_t raddr
;
1039 target_ulong page
, end
;
1042 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1043 tlb
= &env
->tlb
[i
].tlbe
;
1044 if (ppcemb_tlb_check(env
, tlb
, &raddr
, eaddr
, pid
, 0, i
) == 0) {
1045 end
= tlb
->EPN
+ tlb
->size
;
1046 for (page
= tlb
->EPN
; page
< end
; page
+= TARGET_PAGE_SIZE
)
1047 tlb_flush_page(env
, page
);
1048 tlb
->prot
&= ~PAGE_VALID
;
1053 ppc4xx_tlb_invalidate_all(env
);
1057 static int mmu40x_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1058 target_ulong address
, int rw
, int access_type
)
1061 target_phys_addr_t raddr
;
1062 int i
, ret
, zsel
, zpr
, pr
;
1065 raddr
= (target_phys_addr_t
)-1ULL;
1067 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1068 tlb
= &env
->tlb
[i
].tlbe
;
1069 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
,
1070 env
->spr
[SPR_40x_PID
], 0, i
) < 0)
1072 zsel
= (tlb
->attr
>> 4) & 0xF;
1073 zpr
= (env
->spr
[SPR_40x_ZPR
] >> (30 - (2 * zsel
))) & 0x3;
1074 LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1075 __func__
, i
, zsel
, zpr
, rw
, tlb
->attr
);
1076 /* Check execute enable bit */
1083 /* All accesses granted */
1084 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
1089 /* Raise Zone protection fault. */
1090 env
->spr
[SPR_40x_ESR
] = 1 << 22;
1098 /* Check from TLB entry */
1099 ctx
->prot
= tlb
->prot
;
1100 ret
= check_prot(ctx
->prot
, rw
, access_type
);
1102 env
->spr
[SPR_40x_ESR
] = 0;
1107 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1108 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1113 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1114 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1119 void store_40x_sler (CPUPPCState
*env
, uint32_t val
)
1121 /* XXX: TO BE FIXED */
1122 if (val
!= 0x00000000) {
1123 cpu_abort(env
, "Little-endian regions are not supported by now\n");
1125 env
->spr
[SPR_405_SLER
] = val
;
1128 static int mmubooke_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1129 target_ulong address
, int rw
,
1133 target_phys_addr_t raddr
;
1137 raddr
= (target_phys_addr_t
)-1ULL;
1138 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1139 tlb
= &env
->tlb
[i
].tlbe
;
1140 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
,
1141 env
->spr
[SPR_BOOKE_PID
], 1, i
) < 0)
1144 prot
= tlb
->prot
& 0xF;
1146 prot
= (tlb
->prot
>> 4) & 0xF;
1147 /* Check the address space */
1148 if (access_type
== ACCESS_CODE
) {
1149 if (msr_ir
!= (tlb
->attr
& 1))
1152 if (prot
& PAGE_EXEC
) {
1158 if (msr_dr
!= (tlb
->attr
& 1))
1161 if ((!rw
&& prot
& PAGE_READ
) || (rw
&& (prot
& PAGE_WRITE
))) {
1174 static inline int check_physical(CPUState
*env
, mmu_ctx_t
*ctx
,
1175 target_ulong eaddr
, int rw
)
1180 ctx
->prot
= PAGE_READ
| PAGE_EXEC
;
1182 switch (env
->mmu_model
) {
1183 case POWERPC_MMU_32B
:
1184 case POWERPC_MMU_601
:
1185 case POWERPC_MMU_SOFT_6xx
:
1186 case POWERPC_MMU_SOFT_74xx
:
1187 case POWERPC_MMU_SOFT_4xx
:
1188 case POWERPC_MMU_REAL
:
1189 case POWERPC_MMU_BOOKE
:
1190 ctx
->prot
|= PAGE_WRITE
;
1192 #if defined(TARGET_PPC64)
1193 case POWERPC_MMU_620
:
1194 case POWERPC_MMU_64B
:
1195 /* Real address are 60 bits long */
1196 ctx
->raddr
&= 0x0FFFFFFFFFFFFFFFULL
;
1197 ctx
->prot
|= PAGE_WRITE
;
1200 case POWERPC_MMU_SOFT_4xx_Z
:
1201 if (unlikely(msr_pe
!= 0)) {
1202 /* 403 family add some particular protections,
1203 * using PBL/PBU registers for accesses with no translation.
1206 /* Check PLB validity */
1207 (env
->pb
[0] < env
->pb
[1] &&
1208 /* and address in plb area */
1209 eaddr
>= env
->pb
[0] && eaddr
< env
->pb
[1]) ||
1210 (env
->pb
[2] < env
->pb
[3] &&
1211 eaddr
>= env
->pb
[2] && eaddr
< env
->pb
[3]) ? 1 : 0;
1212 if (in_plb
^ msr_px
) {
1213 /* Access in protected area */
1215 /* Access is not allowed */
1219 /* Read-write access is allowed */
1220 ctx
->prot
|= PAGE_WRITE
;
1224 case POWERPC_MMU_MPC8xx
:
1226 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1228 case POWERPC_MMU_BOOKE_FSL
:
1230 cpu_abort(env
, "BookE FSL MMU model not implemented\n");
1233 cpu_abort(env
, "Unknown or invalid MMU model\n");
1240 int get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
, target_ulong eaddr
,
1241 int rw
, int access_type
)
1246 qemu_log("%s\n", __func__
);
1248 if ((access_type
== ACCESS_CODE
&& msr_ir
== 0) ||
1249 (access_type
!= ACCESS_CODE
&& msr_dr
== 0)) {
1250 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1251 /* The BookE MMU always performs address translation. The
1252 IS and DS bits only affect the address space. */
1253 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1256 /* No address translation. */
1257 ret
= check_physical(env
, ctx
, eaddr
, rw
);
1261 switch (env
->mmu_model
) {
1262 case POWERPC_MMU_32B
:
1263 case POWERPC_MMU_601
:
1264 case POWERPC_MMU_SOFT_6xx
:
1265 case POWERPC_MMU_SOFT_74xx
:
1266 /* Try to find a BAT */
1267 if (env
->nb_BATs
!= 0)
1268 ret
= get_bat(env
, ctx
, eaddr
, rw
, access_type
);
1269 #if defined(TARGET_PPC64)
1270 case POWERPC_MMU_620
:
1271 case POWERPC_MMU_64B
:
1274 /* We didn't match any BAT entry or don't have BATs */
1275 ret
= get_segment(env
, ctx
, eaddr
, rw
, access_type
);
1278 case POWERPC_MMU_SOFT_4xx
:
1279 case POWERPC_MMU_SOFT_4xx_Z
:
1280 ret
= mmu40x_get_physical_address(env
, ctx
, eaddr
,
1283 case POWERPC_MMU_BOOKE
:
1284 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1287 case POWERPC_MMU_MPC8xx
:
1289 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1291 case POWERPC_MMU_BOOKE_FSL
:
1293 cpu_abort(env
, "BookE FSL MMU model not implemented\n");
1295 case POWERPC_MMU_REAL
:
1296 cpu_abort(env
, "PowerPC in real mode do not do any translation\n");
1299 cpu_abort(env
, "Unknown or invalid MMU model\n");
1304 qemu_log("%s address " TARGET_FMT_lx
" => %d " TARGET_FMT_plx
"\n",
1305 __func__
, eaddr
, ret
, ctx
->raddr
);
1311 target_phys_addr_t
cpu_get_phys_page_debug (CPUState
*env
, target_ulong addr
)
1315 if (unlikely(get_physical_address(env
, &ctx
, addr
, 0, ACCESS_INT
) != 0))
1318 return ctx
.raddr
& TARGET_PAGE_MASK
;
1321 /* Perform address translation */
1322 int cpu_ppc_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
1323 int mmu_idx
, int is_softmmu
)
1332 access_type
= ACCESS_CODE
;
1335 access_type
= env
->access_type
;
1337 ret
= get_physical_address(env
, &ctx
, address
, rw
, access_type
);
1339 tlb_set_page(env
, address
& TARGET_PAGE_MASK
,
1340 ctx
.raddr
& TARGET_PAGE_MASK
, ctx
.prot
,
1341 mmu_idx
, TARGET_PAGE_SIZE
);
1343 } else if (ret
< 0) {
1345 if (access_type
== ACCESS_CODE
) {
1348 /* No matches in page tables or TLB */
1349 switch (env
->mmu_model
) {
1350 case POWERPC_MMU_SOFT_6xx
:
1351 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1352 env
->error_code
= 1 << 18;
1353 env
->spr
[SPR_IMISS
] = address
;
1354 env
->spr
[SPR_ICMP
] = 0x80000000 | ctx
.ptem
;
1356 case POWERPC_MMU_SOFT_74xx
:
1357 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1359 case POWERPC_MMU_SOFT_4xx
:
1360 case POWERPC_MMU_SOFT_4xx_Z
:
1361 env
->exception_index
= POWERPC_EXCP_ITLB
;
1362 env
->error_code
= 0;
1363 env
->spr
[SPR_40x_DEAR
] = address
;
1364 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1366 case POWERPC_MMU_32B
:
1367 case POWERPC_MMU_601
:
1368 #if defined(TARGET_PPC64)
1369 case POWERPC_MMU_620
:
1370 case POWERPC_MMU_64B
:
1372 env
->exception_index
= POWERPC_EXCP_ISI
;
1373 env
->error_code
= 0x40000000;
1375 case POWERPC_MMU_BOOKE
:
1376 env
->exception_index
= POWERPC_EXCP_ITLB
;
1377 env
->error_code
= 0;
1378 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1380 case POWERPC_MMU_BOOKE_FSL
:
1382 cpu_abort(env
, "BookE FSL MMU model is not implemented\n");
1384 case POWERPC_MMU_MPC8xx
:
1386 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1388 case POWERPC_MMU_REAL
:
1389 cpu_abort(env
, "PowerPC in real mode should never raise "
1390 "any MMU exceptions\n");
1393 cpu_abort(env
, "Unknown or invalid MMU model\n");
1398 /* Access rights violation */
1399 env
->exception_index
= POWERPC_EXCP_ISI
;
1400 env
->error_code
= 0x08000000;
1403 /* No execute protection violation */
1404 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1405 env
->spr
[SPR_BOOKE_ESR
] = 0x00000000;
1407 env
->exception_index
= POWERPC_EXCP_ISI
;
1408 env
->error_code
= 0x10000000;
1411 /* Direct store exception */
1412 /* No code fetch is allowed in direct-store areas */
1413 env
->exception_index
= POWERPC_EXCP_ISI
;
1414 env
->error_code
= 0x10000000;
1416 #if defined(TARGET_PPC64)
1418 /* No match in segment table */
1419 if (env
->mmu_model
== POWERPC_MMU_620
) {
1420 env
->exception_index
= POWERPC_EXCP_ISI
;
1421 /* XXX: this might be incorrect */
1422 env
->error_code
= 0x40000000;
1424 env
->exception_index
= POWERPC_EXCP_ISEG
;
1425 env
->error_code
= 0;
1433 /* No matches in page tables or TLB */
1434 switch (env
->mmu_model
) {
1435 case POWERPC_MMU_SOFT_6xx
:
1437 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1438 env
->error_code
= 1 << 16;
1440 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1441 env
->error_code
= 0;
1443 env
->spr
[SPR_DMISS
] = address
;
1444 env
->spr
[SPR_DCMP
] = 0x80000000 | ctx
.ptem
;
1446 env
->error_code
|= ctx
.key
<< 19;
1447 env
->spr
[SPR_HASH1
] = ctx
.pg_addr
[0];
1448 env
->spr
[SPR_HASH2
] = ctx
.pg_addr
[1];
1450 case POWERPC_MMU_SOFT_74xx
:
1452 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1454 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1457 /* Implement LRU algorithm */
1458 env
->error_code
= ctx
.key
<< 19;
1459 env
->spr
[SPR_TLBMISS
] = (address
& ~((target_ulong
)0x3)) |
1460 ((env
->last_way
+ 1) & (env
->nb_ways
- 1));
1461 env
->spr
[SPR_PTEHI
] = 0x80000000 | ctx
.ptem
;
1463 case POWERPC_MMU_SOFT_4xx
:
1464 case POWERPC_MMU_SOFT_4xx_Z
:
1465 env
->exception_index
= POWERPC_EXCP_DTLB
;
1466 env
->error_code
= 0;
1467 env
->spr
[SPR_40x_DEAR
] = address
;
1469 env
->spr
[SPR_40x_ESR
] = 0x00800000;
1471 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1473 case POWERPC_MMU_32B
:
1474 case POWERPC_MMU_601
:
1475 #if defined(TARGET_PPC64)
1476 case POWERPC_MMU_620
:
1477 case POWERPC_MMU_64B
:
1479 env
->exception_index
= POWERPC_EXCP_DSI
;
1480 env
->error_code
= 0;
1481 env
->spr
[SPR_DAR
] = address
;
1483 env
->spr
[SPR_DSISR
] = 0x42000000;
1485 env
->spr
[SPR_DSISR
] = 0x40000000;
1487 case POWERPC_MMU_MPC8xx
:
1489 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1491 case POWERPC_MMU_BOOKE
:
1492 env
->exception_index
= POWERPC_EXCP_DTLB
;
1493 env
->error_code
= 0;
1494 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1495 env
->spr
[SPR_BOOKE_ESR
] = rw
? 1 << ESR_ST
: 0;
1497 case POWERPC_MMU_BOOKE_FSL
:
1499 cpu_abort(env
, "BookE FSL MMU model is not implemented\n");
1501 case POWERPC_MMU_REAL
:
1502 cpu_abort(env
, "PowerPC in real mode should never raise "
1503 "any MMU exceptions\n");
1506 cpu_abort(env
, "Unknown or invalid MMU model\n");
1511 /* Access rights violation */
1512 env
->exception_index
= POWERPC_EXCP_DSI
;
1513 env
->error_code
= 0;
1514 if (env
->mmu_model
== POWERPC_MMU_SOFT_4xx
1515 || env
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
) {
1516 env
->spr
[SPR_40x_DEAR
] = address
;
1518 env
->spr
[SPR_40x_ESR
] |= 0x00800000;
1520 } else if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1521 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1522 env
->spr
[SPR_BOOKE_ESR
] = rw
? 1 << ESR_ST
: 0;
1524 env
->spr
[SPR_DAR
] = address
;
1526 env
->spr
[SPR_DSISR
] = 0x0A000000;
1528 env
->spr
[SPR_DSISR
] = 0x08000000;
1533 /* Direct store exception */
1534 switch (access_type
) {
1536 /* Floating point load/store */
1537 env
->exception_index
= POWERPC_EXCP_ALIGN
;
1538 env
->error_code
= POWERPC_EXCP_ALIGN_FP
;
1539 env
->spr
[SPR_DAR
] = address
;
1542 /* lwarx, ldarx or stwcx. */
1543 env
->exception_index
= POWERPC_EXCP_DSI
;
1544 env
->error_code
= 0;
1545 env
->spr
[SPR_DAR
] = address
;
1547 env
->spr
[SPR_DSISR
] = 0x06000000;
1549 env
->spr
[SPR_DSISR
] = 0x04000000;
1552 /* eciwx or ecowx */
1553 env
->exception_index
= POWERPC_EXCP_DSI
;
1554 env
->error_code
= 0;
1555 env
->spr
[SPR_DAR
] = address
;
1557 env
->spr
[SPR_DSISR
] = 0x06100000;
1559 env
->spr
[SPR_DSISR
] = 0x04100000;
1562 printf("DSI: invalid exception (%d)\n", ret
);
1563 env
->exception_index
= POWERPC_EXCP_PROGRAM
;
1565 POWERPC_EXCP_INVAL
| POWERPC_EXCP_INVAL_INVAL
;
1566 env
->spr
[SPR_DAR
] = address
;
1570 #if defined(TARGET_PPC64)
1572 /* No match in segment table */
1573 if (env
->mmu_model
== POWERPC_MMU_620
) {
1574 env
->exception_index
= POWERPC_EXCP_DSI
;
1575 env
->error_code
= 0;
1576 env
->spr
[SPR_DAR
] = address
;
1577 /* XXX: this might be incorrect */
1579 env
->spr
[SPR_DSISR
] = 0x42000000;
1581 env
->spr
[SPR_DSISR
] = 0x40000000;
1583 env
->exception_index
= POWERPC_EXCP_DSEG
;
1584 env
->error_code
= 0;
1585 env
->spr
[SPR_DAR
] = address
;
1592 printf("%s: set exception to %d %02x\n", __func__
,
1593 env
->exception
, env
->error_code
);
1601 /*****************************************************************************/
1602 /* BATs management */
1603 #if !defined(FLUSH_ALL_TLBS)
1604 static inline void do_invalidate_BAT(CPUPPCState
*env
, target_ulong BATu
,
1607 target_ulong base
, end
, page
;
1609 base
= BATu
& ~0x0001FFFF;
1610 end
= base
+ mask
+ 0x00020000;
1611 LOG_BATS("Flush BAT from " TARGET_FMT_lx
" to " TARGET_FMT_lx
" ("
1612 TARGET_FMT_lx
")\n", base
, end
, mask
);
1613 for (page
= base
; page
!= end
; page
+= TARGET_PAGE_SIZE
)
1614 tlb_flush_page(env
, page
);
1615 LOG_BATS("Flush done\n");
1619 static inline void dump_store_bat(CPUPPCState
*env
, char ID
, int ul
, int nr
,
1622 LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx
" (" TARGET_FMT_lx
")\n", ID
,
1623 nr
, ul
== 0 ? 'u' : 'l', value
, env
->nip
);
1626 void ppc_store_ibatu (CPUPPCState
*env
, int nr
, target_ulong value
)
1630 dump_store_bat(env
, 'I', 0, nr
, value
);
1631 if (env
->IBAT
[0][nr
] != value
) {
1632 mask
= (value
<< 15) & 0x0FFE0000UL
;
1633 #if !defined(FLUSH_ALL_TLBS)
1634 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1636 /* When storing valid upper BAT, mask BEPI and BRPN
1637 * and invalidate all TLBs covered by this BAT
1639 mask
= (value
<< 15) & 0x0FFE0000UL
;
1640 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1641 (value
& ~0x0001FFFFUL
& ~mask
);
1642 env
->IBAT
[1][nr
] = (env
->IBAT
[1][nr
] & 0x0000007B) |
1643 (env
->IBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
1644 #if !defined(FLUSH_ALL_TLBS)
1645 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1652 void ppc_store_ibatl (CPUPPCState
*env
, int nr
, target_ulong value
)
1654 dump_store_bat(env
, 'I', 1, nr
, value
);
1655 env
->IBAT
[1][nr
] = value
;
1658 void ppc_store_dbatu (CPUPPCState
*env
, int nr
, target_ulong value
)
1662 dump_store_bat(env
, 'D', 0, nr
, value
);
1663 if (env
->DBAT
[0][nr
] != value
) {
1664 /* When storing valid upper BAT, mask BEPI and BRPN
1665 * and invalidate all TLBs covered by this BAT
1667 mask
= (value
<< 15) & 0x0FFE0000UL
;
1668 #if !defined(FLUSH_ALL_TLBS)
1669 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
1671 mask
= (value
<< 15) & 0x0FFE0000UL
;
1672 env
->DBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1673 (value
& ~0x0001FFFFUL
& ~mask
);
1674 env
->DBAT
[1][nr
] = (env
->DBAT
[1][nr
] & 0x0000007B) |
1675 (env
->DBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
1676 #if !defined(FLUSH_ALL_TLBS)
1677 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
1684 void ppc_store_dbatl (CPUPPCState
*env
, int nr
, target_ulong value
)
1686 dump_store_bat(env
, 'D', 1, nr
, value
);
1687 env
->DBAT
[1][nr
] = value
;
1690 void ppc_store_ibatu_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
1693 #if defined(FLUSH_ALL_TLBS)
1697 dump_store_bat(env
, 'I', 0, nr
, value
);
1698 if (env
->IBAT
[0][nr
] != value
) {
1699 #if defined(FLUSH_ALL_TLBS)
1702 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
1703 if (env
->IBAT
[1][nr
] & 0x40) {
1704 /* Invalidate BAT only if it is valid */
1705 #if !defined(FLUSH_ALL_TLBS)
1706 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1711 /* When storing valid upper BAT, mask BEPI and BRPN
1712 * and invalidate all TLBs covered by this BAT
1714 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1715 (value
& ~0x0001FFFFUL
& ~mask
);
1716 env
->DBAT
[0][nr
] = env
->IBAT
[0][nr
];
1717 if (env
->IBAT
[1][nr
] & 0x40) {
1718 #if !defined(FLUSH_ALL_TLBS)
1719 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1724 #if defined(FLUSH_ALL_TLBS)
1731 void ppc_store_ibatl_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
1734 #if defined(FLUSH_ALL_TLBS)
1738 dump_store_bat(env
, 'I', 1, nr
, value
);
1739 if (env
->IBAT
[1][nr
] != value
) {
1740 #if defined(FLUSH_ALL_TLBS)
1743 if (env
->IBAT
[1][nr
] & 0x40) {
1744 #if !defined(FLUSH_ALL_TLBS)
1745 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
1746 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1752 #if !defined(FLUSH_ALL_TLBS)
1753 mask
= (value
<< 17) & 0x0FFE0000UL
;
1754 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1759 env
->IBAT
[1][nr
] = value
;
1760 env
->DBAT
[1][nr
] = value
;
1761 #if defined(FLUSH_ALL_TLBS)
1768 /*****************************************************************************/
1769 /* TLB management */
1770 void ppc_tlb_invalidate_all (CPUPPCState
*env
)
1772 switch (env
->mmu_model
) {
1773 case POWERPC_MMU_SOFT_6xx
:
1774 case POWERPC_MMU_SOFT_74xx
:
1775 ppc6xx_tlb_invalidate_all(env
);
1777 case POWERPC_MMU_SOFT_4xx
:
1778 case POWERPC_MMU_SOFT_4xx_Z
:
1779 ppc4xx_tlb_invalidate_all(env
);
1781 case POWERPC_MMU_REAL
:
1782 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
1784 case POWERPC_MMU_MPC8xx
:
1786 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1788 case POWERPC_MMU_BOOKE
:
1791 case POWERPC_MMU_BOOKE_FSL
:
1794 cpu_abort(env
, "BookE MMU model is not implemented\n");
1796 case POWERPC_MMU_32B
:
1797 case POWERPC_MMU_601
:
1798 #if defined(TARGET_PPC64)
1799 case POWERPC_MMU_620
:
1800 case POWERPC_MMU_64B
:
1801 #endif /* defined(TARGET_PPC64) */
1806 cpu_abort(env
, "Unknown MMU model\n");
1811 void ppc_tlb_invalidate_one (CPUPPCState
*env
, target_ulong addr
)
1813 #if !defined(FLUSH_ALL_TLBS)
1814 addr
&= TARGET_PAGE_MASK
;
1815 switch (env
->mmu_model
) {
1816 case POWERPC_MMU_SOFT_6xx
:
1817 case POWERPC_MMU_SOFT_74xx
:
1818 ppc6xx_tlb_invalidate_virt(env
, addr
, 0);
1819 if (env
->id_tlbs
== 1)
1820 ppc6xx_tlb_invalidate_virt(env
, addr
, 1);
1822 case POWERPC_MMU_SOFT_4xx
:
1823 case POWERPC_MMU_SOFT_4xx_Z
:
1824 ppc4xx_tlb_invalidate_virt(env
, addr
, env
->spr
[SPR_40x_PID
]);
1826 case POWERPC_MMU_REAL
:
1827 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
1829 case POWERPC_MMU_MPC8xx
:
1831 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1833 case POWERPC_MMU_BOOKE
:
1835 cpu_abort(env
, "BookE MMU model is not implemented\n");
1837 case POWERPC_MMU_BOOKE_FSL
:
1839 cpu_abort(env
, "BookE FSL MMU model is not implemented\n");
1841 case POWERPC_MMU_32B
:
1842 case POWERPC_MMU_601
:
1843 /* tlbie invalidate TLBs for all segments */
1844 addr
&= ~((target_ulong
)-1ULL << 28);
1845 /* XXX: this case should be optimized,
1846 * giving a mask to tlb_flush_page
1848 tlb_flush_page(env
, addr
| (0x0 << 28));
1849 tlb_flush_page(env
, addr
| (0x1 << 28));
1850 tlb_flush_page(env
, addr
| (0x2 << 28));
1851 tlb_flush_page(env
, addr
| (0x3 << 28));
1852 tlb_flush_page(env
, addr
| (0x4 << 28));
1853 tlb_flush_page(env
, addr
| (0x5 << 28));
1854 tlb_flush_page(env
, addr
| (0x6 << 28));
1855 tlb_flush_page(env
, addr
| (0x7 << 28));
1856 tlb_flush_page(env
, addr
| (0x8 << 28));
1857 tlb_flush_page(env
, addr
| (0x9 << 28));
1858 tlb_flush_page(env
, addr
| (0xA << 28));
1859 tlb_flush_page(env
, addr
| (0xB << 28));
1860 tlb_flush_page(env
, addr
| (0xC << 28));
1861 tlb_flush_page(env
, addr
| (0xD << 28));
1862 tlb_flush_page(env
, addr
| (0xE << 28));
1863 tlb_flush_page(env
, addr
| (0xF << 28));
1865 #if defined(TARGET_PPC64)
1866 case POWERPC_MMU_620
:
1867 case POWERPC_MMU_64B
:
1868 /* tlbie invalidate TLBs for all segments */
1869 /* XXX: given the fact that there are too many segments to invalidate,
1870 * and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
1871 * we just invalidate all TLBs
1875 #endif /* defined(TARGET_PPC64) */
1878 cpu_abort(env
, "Unknown MMU model\n");
1882 ppc_tlb_invalidate_all(env
);
1886 /*****************************************************************************/
1887 /* Special registers manipulation */
1888 #if defined(TARGET_PPC64)
1889 void ppc_store_asr (CPUPPCState
*env
, target_ulong value
)
1891 if (env
->asr
!= value
) {
1898 void ppc_store_sdr1 (CPUPPCState
*env
, target_ulong value
)
1900 LOG_MMU("%s: " TARGET_FMT_lx
"\n", __func__
, value
);
1901 if (env
->sdr1
!= value
) {
1902 /* XXX: for PowerPC 64, should check that the HTABSIZE value
1910 #if defined(TARGET_PPC64)
1911 target_ulong
ppc_load_sr (CPUPPCState
*env
, int slb_nr
)
1918 void ppc_store_sr (CPUPPCState
*env
, int srnum
, target_ulong value
)
1920 LOG_MMU("%s: reg=%d " TARGET_FMT_lx
" " TARGET_FMT_lx
"\n", __func__
,
1921 srnum
, value
, env
->sr
[srnum
]);
1922 #if defined(TARGET_PPC64)
1923 if (env
->mmu_model
& POWERPC_MMU_64
) {
1924 uint64_t rb
= 0, rs
= 0;
1927 rb
|= ((uint32_t)srnum
& 0xf) << 28;
1928 /* Set the valid bit */
1931 rb
|= (uint32_t)srnum
;
1934 rs
|= (value
& 0xfffffff) << 12;
1936 rs
|= ((value
>> 27) & 0xf) << 9;
1938 ppc_store_slb(env
, rb
, rs
);
1941 if (env
->sr
[srnum
] != value
) {
1942 env
->sr
[srnum
] = value
;
1943 /* Invalidating 256MB of virtual memory in 4kB pages is way longer than
1944 flusing the whole TLB. */
1945 #if !defined(FLUSH_ALL_TLBS) && 0
1947 target_ulong page
, end
;
1948 /* Invalidate 256 MB of virtual memory */
1949 page
= (16 << 20) * srnum
;
1950 end
= page
+ (16 << 20);
1951 for (; page
!= end
; page
+= TARGET_PAGE_SIZE
)
1952 tlb_flush_page(env
, page
);
1959 #endif /* !defined (CONFIG_USER_ONLY) */
1961 /* GDBstub can read and write MSR... */
1962 void ppc_store_msr (CPUPPCState
*env
, target_ulong value
)
1964 hreg_store_msr(env
, value
, 0);
1967 /*****************************************************************************/
1968 /* Exception processing */
1969 #if defined (CONFIG_USER_ONLY)
1970 void do_interrupt (CPUState
*env
)
1972 env
->exception_index
= POWERPC_EXCP_NONE
;
1973 env
->error_code
= 0;
1976 void ppc_hw_interrupt (CPUState
*env
)
1978 env
->exception_index
= POWERPC_EXCP_NONE
;
1979 env
->error_code
= 0;
1981 #else /* defined (CONFIG_USER_ONLY) */
1982 static inline void dump_syscall(CPUState
*env
)
1984 qemu_log_mask(CPU_LOG_INT
, "syscall r0=%016" PRIx64
" r3=%016" PRIx64
1985 " r4=%016" PRIx64
" r5=%016" PRIx64
" r6=%016" PRIx64
1986 " nip=" TARGET_FMT_lx
"\n",
1987 ppc_dump_gpr(env
, 0), ppc_dump_gpr(env
, 3),
1988 ppc_dump_gpr(env
, 4), ppc_dump_gpr(env
, 5),
1989 ppc_dump_gpr(env
, 6), env
->nip
);
1992 /* Note that this function should be greatly optimized
1993 * when called with a constant excp, from ppc_hw_interrupt
1995 static inline void powerpc_excp(CPUState
*env
, int excp_model
, int excp
)
1997 target_ulong msr
, new_msr
, vector
;
1998 int srr0
, srr1
, asrr0
, asrr1
;
1999 int lpes0
, lpes1
, lev
;
2002 /* XXX: find a suitable condition to enable the hypervisor mode */
2003 lpes0
= (env
->spr
[SPR_LPCR
] >> 1) & 1;
2004 lpes1
= (env
->spr
[SPR_LPCR
] >> 2) & 1;
2006 /* Those values ensure we won't enter the hypervisor mode */
2011 qemu_log_mask(CPU_LOG_INT
, "Raise exception at " TARGET_FMT_lx
2012 " => %08x (%02x)\n", env
->nip
, excp
, env
->error_code
);
2014 /* new srr1 value excluding must-be-zero bits */
2015 msr
= env
->msr
& ~0x783f0000ULL
;
2017 /* new interrupt handler msr */
2018 new_msr
= env
->msr
& ((target_ulong
)1 << MSR_ME
);
2020 /* target registers */
2027 case POWERPC_EXCP_NONE
:
2028 /* Should never happen */
2030 case POWERPC_EXCP_CRITICAL
: /* Critical input */
2031 switch (excp_model
) {
2032 case POWERPC_EXCP_40x
:
2033 srr0
= SPR_40x_SRR2
;
2034 srr1
= SPR_40x_SRR3
;
2036 case POWERPC_EXCP_BOOKE
:
2037 srr0
= SPR_BOOKE_CSRR0
;
2038 srr1
= SPR_BOOKE_CSRR1
;
2040 case POWERPC_EXCP_G2
:
2046 case POWERPC_EXCP_MCHECK
: /* Machine check exception */
2048 /* Machine check exception is not enabled.
2049 * Enter checkstop state.
2051 if (qemu_log_enabled()) {
2052 qemu_log("Machine check while not allowed. "
2053 "Entering checkstop state\n");
2055 fprintf(stderr
, "Machine check while not allowed. "
2056 "Entering checkstop state\n");
2059 env
->interrupt_request
|= CPU_INTERRUPT_EXITTB
;
2062 /* XXX: find a suitable condition to enable the hypervisor mode */
2063 new_msr
|= (target_ulong
)MSR_HVB
;
2066 /* machine check exceptions don't have ME set */
2067 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2069 /* XXX: should also have something loaded in DAR / DSISR */
2070 switch (excp_model
) {
2071 case POWERPC_EXCP_40x
:
2072 srr0
= SPR_40x_SRR2
;
2073 srr1
= SPR_40x_SRR3
;
2075 case POWERPC_EXCP_BOOKE
:
2076 srr0
= SPR_BOOKE_MCSRR0
;
2077 srr1
= SPR_BOOKE_MCSRR1
;
2078 asrr0
= SPR_BOOKE_CSRR0
;
2079 asrr1
= SPR_BOOKE_CSRR1
;
2085 case POWERPC_EXCP_DSI
: /* Data storage exception */
2086 LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx
" DAR=" TARGET_FMT_lx
2087 "\n", env
->spr
[SPR_DSISR
], env
->spr
[SPR_DAR
]);
2089 new_msr
|= (target_ulong
)MSR_HVB
;
2091 case POWERPC_EXCP_ISI
: /* Instruction storage exception */
2092 LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx
", nip=" TARGET_FMT_lx
2093 "\n", msr
, env
->nip
);
2095 new_msr
|= (target_ulong
)MSR_HVB
;
2096 msr
|= env
->error_code
;
2098 case POWERPC_EXCP_EXTERNAL
: /* External input */
2100 new_msr
|= (target_ulong
)MSR_HVB
;
2102 case POWERPC_EXCP_ALIGN
: /* Alignment exception */
2104 new_msr
|= (target_ulong
)MSR_HVB
;
2105 /* XXX: this is false */
2106 /* Get rS/rD and rA from faulting opcode */
2107 env
->spr
[SPR_DSISR
] |= (ldl_code((env
->nip
- 4)) & 0x03FF0000) >> 16;
2109 case POWERPC_EXCP_PROGRAM
: /* Program exception */
2110 switch (env
->error_code
& ~0xF) {
2111 case POWERPC_EXCP_FP
:
2112 if ((msr_fe0
== 0 && msr_fe1
== 0) || msr_fp
== 0) {
2113 LOG_EXCP("Ignore floating point exception\n");
2114 env
->exception_index
= POWERPC_EXCP_NONE
;
2115 env
->error_code
= 0;
2119 new_msr
|= (target_ulong
)MSR_HVB
;
2121 if (msr_fe0
== msr_fe1
)
2125 case POWERPC_EXCP_INVAL
:
2126 LOG_EXCP("Invalid instruction at " TARGET_FMT_lx
"\n", env
->nip
);
2128 new_msr
|= (target_ulong
)MSR_HVB
;
2131 case POWERPC_EXCP_PRIV
:
2133 new_msr
|= (target_ulong
)MSR_HVB
;
2136 case POWERPC_EXCP_TRAP
:
2138 new_msr
|= (target_ulong
)MSR_HVB
;
2142 /* Should never occur */
2143 cpu_abort(env
, "Invalid program exception %d. Aborting\n",
2148 case POWERPC_EXCP_FPU
: /* Floating-point unavailable exception */
2150 new_msr
|= (target_ulong
)MSR_HVB
;
2152 case POWERPC_EXCP_SYSCALL
: /* System call exception */
2154 lev
= env
->error_code
;
2155 if (lev
== 1 || (lpes0
== 0 && lpes1
== 0))
2156 new_msr
|= (target_ulong
)MSR_HVB
;
2158 case POWERPC_EXCP_APU
: /* Auxiliary processor unavailable */
2160 case POWERPC_EXCP_DECR
: /* Decrementer exception */
2162 new_msr
|= (target_ulong
)MSR_HVB
;
2164 case POWERPC_EXCP_FIT
: /* Fixed-interval timer interrupt */
2166 LOG_EXCP("FIT exception\n");
2168 case POWERPC_EXCP_WDT
: /* Watchdog timer interrupt */
2169 LOG_EXCP("WDT exception\n");
2170 switch (excp_model
) {
2171 case POWERPC_EXCP_BOOKE
:
2172 srr0
= SPR_BOOKE_CSRR0
;
2173 srr1
= SPR_BOOKE_CSRR1
;
2179 case POWERPC_EXCP_DTLB
: /* Data TLB error */
2181 case POWERPC_EXCP_ITLB
: /* Instruction TLB error */
2183 case POWERPC_EXCP_DEBUG
: /* Debug interrupt */
2184 switch (excp_model
) {
2185 case POWERPC_EXCP_BOOKE
:
2186 srr0
= SPR_BOOKE_DSRR0
;
2187 srr1
= SPR_BOOKE_DSRR1
;
2188 asrr0
= SPR_BOOKE_CSRR0
;
2189 asrr1
= SPR_BOOKE_CSRR1
;
2195 cpu_abort(env
, "Debug exception is not implemented yet !\n");
2197 case POWERPC_EXCP_SPEU
: /* SPE/embedded floating-point unavailable */
2199 case POWERPC_EXCP_EFPDI
: /* Embedded floating-point data interrupt */
2201 cpu_abort(env
, "Embedded floating point data exception "
2202 "is not implemented yet !\n");
2204 case POWERPC_EXCP_EFPRI
: /* Embedded floating-point round interrupt */
2206 cpu_abort(env
, "Embedded floating point round exception "
2207 "is not implemented yet !\n");
2209 case POWERPC_EXCP_EPERFM
: /* Embedded performance monitor interrupt */
2212 "Performance counter exception is not implemented yet !\n");
2214 case POWERPC_EXCP_DOORI
: /* Embedded doorbell interrupt */
2217 "Embedded doorbell interrupt is not implemented yet !\n");
2219 case POWERPC_EXCP_DOORCI
: /* Embedded doorbell critical interrupt */
2220 switch (excp_model
) {
2221 case POWERPC_EXCP_BOOKE
:
2222 srr0
= SPR_BOOKE_CSRR0
;
2223 srr1
= SPR_BOOKE_CSRR1
;
2229 cpu_abort(env
, "Embedded doorbell critical interrupt "
2230 "is not implemented yet !\n");
2232 case POWERPC_EXCP_RESET
: /* System reset exception */
2234 /* indicate that we resumed from power save mode */
2237 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2241 /* XXX: find a suitable condition to enable the hypervisor mode */
2242 new_msr
|= (target_ulong
)MSR_HVB
;
2245 case POWERPC_EXCP_DSEG
: /* Data segment exception */
2247 new_msr
|= (target_ulong
)MSR_HVB
;
2249 case POWERPC_EXCP_ISEG
: /* Instruction segment exception */
2251 new_msr
|= (target_ulong
)MSR_HVB
;
2253 case POWERPC_EXCP_HDECR
: /* Hypervisor decrementer exception */
2256 new_msr
|= (target_ulong
)MSR_HVB
;
2257 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2259 case POWERPC_EXCP_TRACE
: /* Trace exception */
2261 new_msr
|= (target_ulong
)MSR_HVB
;
2263 case POWERPC_EXCP_HDSI
: /* Hypervisor data storage exception */
2266 new_msr
|= (target_ulong
)MSR_HVB
;
2267 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2269 case POWERPC_EXCP_HISI
: /* Hypervisor instruction storage exception */
2272 new_msr
|= (target_ulong
)MSR_HVB
;
2273 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2275 case POWERPC_EXCP_HDSEG
: /* Hypervisor data segment exception */
2278 new_msr
|= (target_ulong
)MSR_HVB
;
2279 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2281 case POWERPC_EXCP_HISEG
: /* Hypervisor instruction segment exception */
2284 new_msr
|= (target_ulong
)MSR_HVB
;
2285 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2287 case POWERPC_EXCP_VPU
: /* Vector unavailable exception */
2289 new_msr
|= (target_ulong
)MSR_HVB
;
2291 case POWERPC_EXCP_PIT
: /* Programmable interval timer interrupt */
2292 LOG_EXCP("PIT exception\n");
2294 case POWERPC_EXCP_IO
: /* IO error exception */
2296 cpu_abort(env
, "601 IO error exception is not implemented yet !\n");
2298 case POWERPC_EXCP_RUNM
: /* Run mode exception */
2300 cpu_abort(env
, "601 run mode exception is not implemented yet !\n");
2302 case POWERPC_EXCP_EMUL
: /* Emulation trap exception */
2304 cpu_abort(env
, "602 emulation trap exception "
2305 "is not implemented yet !\n");
2307 case POWERPC_EXCP_IFTLB
: /* Instruction fetch TLB error */
2308 if (lpes1
== 0) /* XXX: check this */
2309 new_msr
|= (target_ulong
)MSR_HVB
;
2310 switch (excp_model
) {
2311 case POWERPC_EXCP_602
:
2312 case POWERPC_EXCP_603
:
2313 case POWERPC_EXCP_603E
:
2314 case POWERPC_EXCP_G2
:
2316 case POWERPC_EXCP_7x5
:
2318 case POWERPC_EXCP_74xx
:
2321 cpu_abort(env
, "Invalid instruction TLB miss exception\n");
2325 case POWERPC_EXCP_DLTLB
: /* Data load TLB miss */
2326 if (lpes1
== 0) /* XXX: check this */
2327 new_msr
|= (target_ulong
)MSR_HVB
;
2328 switch (excp_model
) {
2329 case POWERPC_EXCP_602
:
2330 case POWERPC_EXCP_603
:
2331 case POWERPC_EXCP_603E
:
2332 case POWERPC_EXCP_G2
:
2334 case POWERPC_EXCP_7x5
:
2336 case POWERPC_EXCP_74xx
:
2339 cpu_abort(env
, "Invalid data load TLB miss exception\n");
2343 case POWERPC_EXCP_DSTLB
: /* Data store TLB miss */
2344 if (lpes1
== 0) /* XXX: check this */
2345 new_msr
|= (target_ulong
)MSR_HVB
;
2346 switch (excp_model
) {
2347 case POWERPC_EXCP_602
:
2348 case POWERPC_EXCP_603
:
2349 case POWERPC_EXCP_603E
:
2350 case POWERPC_EXCP_G2
:
2352 /* Swap temporary saved registers with GPRs */
2353 if (!(new_msr
& ((target_ulong
)1 << MSR_TGPR
))) {
2354 new_msr
|= (target_ulong
)1 << MSR_TGPR
;
2355 hreg_swap_gpr_tgpr(env
);
2358 case POWERPC_EXCP_7x5
:
2360 #if defined (DEBUG_SOFTWARE_TLB)
2361 if (qemu_log_enabled()) {
2363 target_ulong
*miss
, *cmp
;
2365 if (excp
== POWERPC_EXCP_IFTLB
) {
2368 miss
= &env
->spr
[SPR_IMISS
];
2369 cmp
= &env
->spr
[SPR_ICMP
];
2371 if (excp
== POWERPC_EXCP_DLTLB
)
2376 miss
= &env
->spr
[SPR_DMISS
];
2377 cmp
= &env
->spr
[SPR_DCMP
];
2379 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2380 TARGET_FMT_lx
" H1 " TARGET_FMT_lx
" H2 "
2381 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2382 env
->spr
[SPR_HASH1
], env
->spr
[SPR_HASH2
],
2386 msr
|= env
->crf
[0] << 28;
2387 msr
|= env
->error_code
; /* key, D/I, S/L bits */
2388 /* Set way using a LRU mechanism */
2389 msr
|= ((env
->last_way
+ 1) & (env
->nb_ways
- 1)) << 17;
2391 case POWERPC_EXCP_74xx
:
2393 #if defined (DEBUG_SOFTWARE_TLB)
2394 if (qemu_log_enabled()) {
2396 target_ulong
*miss
, *cmp
;
2398 if (excp
== POWERPC_EXCP_IFTLB
) {
2401 miss
= &env
->spr
[SPR_TLBMISS
];
2402 cmp
= &env
->spr
[SPR_PTEHI
];
2404 if (excp
== POWERPC_EXCP_DLTLB
)
2409 miss
= &env
->spr
[SPR_TLBMISS
];
2410 cmp
= &env
->spr
[SPR_PTEHI
];
2412 qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2413 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2417 msr
|= env
->error_code
; /* key bit */
2420 cpu_abort(env
, "Invalid data store TLB miss exception\n");
2424 case POWERPC_EXCP_FPA
: /* Floating-point assist exception */
2426 cpu_abort(env
, "Floating point assist exception "
2427 "is not implemented yet !\n");
2429 case POWERPC_EXCP_DABR
: /* Data address breakpoint */
2431 cpu_abort(env
, "DABR exception is not implemented yet !\n");
2433 case POWERPC_EXCP_IABR
: /* Instruction address breakpoint */
2435 cpu_abort(env
, "IABR exception is not implemented yet !\n");
2437 case POWERPC_EXCP_SMI
: /* System management interrupt */
2439 cpu_abort(env
, "SMI exception is not implemented yet !\n");
2441 case POWERPC_EXCP_THERM
: /* Thermal interrupt */
2443 cpu_abort(env
, "Thermal management exception "
2444 "is not implemented yet !\n");
2446 case POWERPC_EXCP_PERFM
: /* Embedded performance monitor interrupt */
2448 new_msr
|= (target_ulong
)MSR_HVB
;
2451 "Performance counter exception is not implemented yet !\n");
2453 case POWERPC_EXCP_VPUA
: /* Vector assist exception */
2455 cpu_abort(env
, "VPU assist exception is not implemented yet !\n");
2457 case POWERPC_EXCP_SOFTP
: /* Soft patch exception */
2460 "970 soft-patch exception is not implemented yet !\n");
2462 case POWERPC_EXCP_MAINT
: /* Maintenance exception */
2465 "970 maintenance exception is not implemented yet !\n");
2467 case POWERPC_EXCP_MEXTBR
: /* Maskable external breakpoint */
2469 cpu_abort(env
, "Maskable external exception "
2470 "is not implemented yet !\n");
2472 case POWERPC_EXCP_NMEXTBR
: /* Non maskable external breakpoint */
2474 cpu_abort(env
, "Non maskable external exception "
2475 "is not implemented yet !\n");
2479 cpu_abort(env
, "Invalid PowerPC exception %d. Aborting\n", excp
);
2482 /* save current instruction location */
2483 env
->spr
[srr0
] = env
->nip
- 4;
2486 /* save next instruction location */
2487 env
->spr
[srr0
] = env
->nip
;
2491 env
->spr
[srr1
] = msr
;
2492 /* If any alternate SRR register are defined, duplicate saved values */
2494 env
->spr
[asrr0
] = env
->spr
[srr0
];
2496 env
->spr
[asrr1
] = env
->spr
[srr1
];
2497 /* If we disactivated any translation, flush TLBs */
2498 if (new_msr
& ((1 << MSR_IR
) | (1 << MSR_DR
)))
2502 new_msr
|= (target_ulong
)1 << MSR_LE
;
2505 /* Jump to handler */
2506 vector
= env
->excp_vectors
[excp
];
2507 if (vector
== (target_ulong
)-1ULL) {
2508 cpu_abort(env
, "Raised an exception without defined vector %d\n",
2511 vector
|= env
->excp_prefix
;
2512 #if defined(TARGET_PPC64)
2513 if (excp_model
== POWERPC_EXCP_BOOKE
) {
2515 vector
= (uint32_t)vector
;
2517 new_msr
|= (target_ulong
)1 << MSR_CM
;
2520 if (!msr_isf
&& !(env
->mmu_model
& POWERPC_MMU_64
)) {
2521 vector
= (uint32_t)vector
;
2523 new_msr
|= (target_ulong
)1 << MSR_SF
;
2527 /* XXX: we don't use hreg_store_msr here as already have treated
2528 * any special case that could occur. Just store MSR and update hflags
2530 env
->msr
= new_msr
& env
->msr_mask
;
2531 hreg_compute_hflags(env
);
2533 /* Reset exception state */
2534 env
->exception_index
= POWERPC_EXCP_NONE
;
2535 env
->error_code
= 0;
2537 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
2538 /* XXX: The BookE changes address space when switching modes,
2539 we should probably implement that as different MMU indexes,
2540 but for the moment we do it the slow way and flush all. */
2545 void do_interrupt (CPUState
*env
)
2547 powerpc_excp(env
, env
->excp_model
, env
->exception_index
);
2550 void ppc_hw_interrupt (CPUPPCState
*env
)
2555 qemu_log_mask(CPU_LOG_INT
, "%s: %p pending %08x req %08x me %d ee %d\n",
2556 __func__
, env
, env
->pending_interrupts
,
2557 env
->interrupt_request
, (int)msr_me
, (int)msr_ee
);
2559 /* External reset */
2560 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_RESET
)) {
2561 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_RESET
);
2562 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_RESET
);
2565 /* Machine check exception */
2566 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_MCK
)) {
2567 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_MCK
);
2568 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_MCHECK
);
2572 /* External debug exception */
2573 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DEBUG
)) {
2574 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DEBUG
);
2575 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DEBUG
);
2580 /* XXX: find a suitable condition to enable the hypervisor mode */
2581 hdice
= env
->spr
[SPR_LPCR
] & 1;
2585 if ((msr_ee
!= 0 || msr_hv
== 0 || msr_pr
!= 0) && hdice
!= 0) {
2586 /* Hypervisor decrementer exception */
2587 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_HDECR
)) {
2588 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_HDECR
);
2589 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_HDECR
);
2594 /* External critical interrupt */
2595 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CEXT
)) {
2596 /* Taking a critical external interrupt does not clear the external
2597 * critical interrupt status
2600 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CEXT
);
2602 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_CRITICAL
);
2607 /* Watchdog timer on embedded PowerPC */
2608 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_WDT
)) {
2609 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_WDT
);
2610 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_WDT
);
2613 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CDOORBELL
)) {
2614 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CDOORBELL
);
2615 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORCI
);
2618 /* Fixed interval timer on embedded PowerPC */
2619 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_FIT
)) {
2620 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_FIT
);
2621 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_FIT
);
2624 /* Programmable interval timer on embedded PowerPC */
2625 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PIT
)) {
2626 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PIT
);
2627 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PIT
);
2630 /* Decrementer exception */
2631 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DECR
)) {
2632 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DECR
);
2633 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DECR
);
2636 /* External interrupt */
2637 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_EXT
)) {
2638 /* Taking an external interrupt does not clear the external
2642 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_EXT
);
2644 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_EXTERNAL
);
2647 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DOORBELL
)) {
2648 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DOORBELL
);
2649 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORI
);
2652 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PERFM
)) {
2653 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PERFM
);
2654 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PERFM
);
2657 /* Thermal interrupt */
2658 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_THERM
)) {
2659 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_THERM
);
2660 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_THERM
);
2665 #endif /* !CONFIG_USER_ONLY */
2667 void cpu_dump_rfi (target_ulong RA
, target_ulong msr
)
2669 qemu_log("Return from exception at " TARGET_FMT_lx
" with flags "
2670 TARGET_FMT_lx
"\n", RA
, msr
);
2673 void cpu_reset(CPUPPCState
*env
)
2677 if (qemu_loglevel_mask(CPU_LOG_RESET
)) {
2678 qemu_log("CPU Reset (CPU %d)\n", env
->cpu_index
);
2679 log_cpu_state(env
, 0);
2682 msr
= (target_ulong
)0;
2684 /* XXX: find a suitable condition to enable the hypervisor mode */
2685 msr
|= (target_ulong
)MSR_HVB
;
2687 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
2688 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
2689 msr
|= (target_ulong
)1 << MSR_EP
;
2690 #if defined (DO_SINGLE_STEP) && 0
2691 /* Single step trace mode */
2692 msr
|= (target_ulong
)1 << MSR_SE
;
2693 msr
|= (target_ulong
)1 << MSR_BE
;
2695 #if defined(CONFIG_USER_ONLY)
2696 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
2697 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
2698 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
2699 msr
|= (target_ulong
)1 << MSR_PR
;
2701 env
->excp_prefix
= env
->hreset_excp_prefix
;
2702 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
2703 if (env
->mmu_model
!= POWERPC_MMU_REAL
)
2704 ppc_tlb_invalidate_all(env
);
2706 env
->msr
= msr
& env
->msr_mask
;
2707 #if defined(TARGET_PPC64)
2708 if (env
->mmu_model
& POWERPC_MMU_64
)
2709 env
->msr
|= (1ULL << MSR_SF
);
2711 hreg_compute_hflags(env
);
2712 env
->reserve_addr
= (target_ulong
)-1ULL;
2713 /* Be sure no exception or interrupt is pending */
2714 env
->pending_interrupts
= 0;
2715 env
->exception_index
= POWERPC_EXCP_NONE
;
2716 env
->error_code
= 0;
2717 /* Flush all TLBs */
2721 CPUPPCState
*cpu_ppc_init (const char *cpu_model
)
2724 const ppc_def_t
*def
;
2726 def
= cpu_ppc_find_by_name(cpu_model
);
2730 env
= qemu_mallocz(sizeof(CPUPPCState
));
2732 ppc_translate_init();
2733 env
->cpu_model_str
= cpu_model
;
2734 cpu_ppc_register_internal(env
, def
);
2736 qemu_init_vcpu(env
);
2741 void cpu_ppc_close (CPUPPCState
*env
)
2743 /* Should also remove all opcode tables... */