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 ppc_slb_t
*slb_get_entry(CPUPPCState
*env
, int nr
)
677 ppc_slb_t
*retval
= &env
->slb
[nr
];
679 #if 0 // XXX implement bridge mode?
680 if (env
->spr
[SPR_ASR
] & 1) {
681 target_phys_addr_t sr_base
;
683 sr_base
= env
->spr
[SPR_ASR
] & 0xfffffffffffff000;
684 sr_base
+= (12 * nr
);
686 retval
->tmp64
= ldq_phys(sr_base
);
687 retval
->tmp
= ldl_phys(sr_base
+ 8);
694 static void slb_set_entry(CPUPPCState
*env
, int nr
, ppc_slb_t
*slb
)
696 ppc_slb_t
*entry
= &env
->slb
[nr
];
701 entry
->tmp64
= slb
->tmp64
;
702 entry
->tmp
= slb
->tmp
;
705 static inline int slb_is_valid(ppc_slb_t
*slb
)
707 return (int)(slb
->tmp64
& 0x0000000008000000ULL
);
710 static inline void slb_invalidate(ppc_slb_t
*slb
)
712 slb
->tmp64
&= ~0x0000000008000000ULL
;
715 static inline int slb_lookup(CPUPPCState
*env
, target_ulong eaddr
,
716 target_ulong
*vsid
, target_ulong
*page_mask
,
717 int *attr
, int *target_page_bits
)
723 LOG_SLB("%s: eaddr " TARGET_FMT_lx
"\n", __func__
, eaddr
);
724 mask
= 0x0000000000000000ULL
; /* Avoid gcc warning */
725 for (n
= 0; n
< env
->slb_nr
; n
++) {
726 ppc_slb_t
*slb
= slb_get_entry(env
, n
);
728 LOG_SLB("%s: seg %d %016" PRIx64
" %08"
729 PRIx32
"\n", __func__
, n
, slb
->tmp64
, slb
->tmp
);
730 if (slb_is_valid(slb
)) {
731 /* SLB entry is valid */
732 mask
= 0xFFFFFFFFF0000000ULL
;
733 if (slb
->tmp
& 0x8) {
735 if (target_page_bits
)
736 *target_page_bits
= 24;
739 if (target_page_bits
)
740 *target_page_bits
= TARGET_PAGE_BITS
;
742 if ((eaddr
& mask
) == (slb
->tmp64
& mask
)) {
744 *vsid
= ((slb
->tmp64
<< 24) | (slb
->tmp
>> 8)) & 0x0003FFFFFFFFFFFFULL
;
746 *attr
= slb
->tmp
& 0xFF;
756 void ppc_slb_invalidate_all (CPUPPCState
*env
)
758 int n
, do_invalidate
;
761 /* XXX: Warning: slbia never invalidates the first segment */
762 for (n
= 1; n
< env
->slb_nr
; n
++) {
763 ppc_slb_t
*slb
= slb_get_entry(env
, n
);
765 if (slb_is_valid(slb
)) {
767 slb_set_entry(env
, n
, slb
);
768 /* XXX: given the fact that segment size is 256 MB or 1TB,
769 * and we still don't have a tlb_flush_mask(env, n, mask)
770 * in Qemu, we just invalidate all TLBs
779 void ppc_slb_invalidate_one (CPUPPCState
*env
, uint64_t T0
)
781 target_ulong vsid
, page_mask
;
785 n
= slb_lookup(env
, T0
, &vsid
, &page_mask
, &attr
, NULL
);
787 ppc_slb_t
*slb
= slb_get_entry(env
, n
);
789 if (slb_is_valid(slb
)) {
791 slb_set_entry(env
, n
, slb
);
792 /* XXX: given the fact that segment size is 256 MB or 1TB,
793 * and we still don't have a tlb_flush_mask(env, n, mask)
794 * in Qemu, we just invalidate all TLBs
801 target_ulong
ppc_load_slb (CPUPPCState
*env
, int slb_nr
)
804 ppc_slb_t
*slb
= slb_get_entry(env
, slb_nr
);
806 if (slb_is_valid(slb
)) {
807 /* SLB entry is valid */
808 /* Copy SLB bits 62:88 to Rt 37:63 (VSID 23:49) */
809 rt
= slb
->tmp
>> 8; /* 65:88 => 40:63 */
810 rt
|= (slb
->tmp64
& 0x7) << 24; /* 62:64 => 37:39 */
811 /* Copy SLB bits 89:92 to Rt 33:36 (KsKpNL) */
812 rt
|= ((slb
->tmp
>> 4) & 0xF) << 27;
816 LOG_SLB("%s: %016" PRIx64
" %08" PRIx32
" => %d "
817 TARGET_FMT_lx
"\n", __func__
, slb
->tmp64
, slb
->tmp
, slb_nr
, rt
);
822 void ppc_store_slb (CPUPPCState
*env
, target_ulong rb
, target_ulong rs
)
828 int flags
, valid
, slb_nr
;
831 flags
= ((rs
>> 8) & 0xf);
834 valid
= (rb
& (1 << 27));
837 slb
= slb_get_entry(env
, slb_nr
);
838 slb
->tmp64
= (esid
<< 28) | valid
| (vsid
>> 24);
839 slb
->tmp
= (vsid
<< 8) | (flags
<< 3);
841 LOG_SLB("%s: %d " TARGET_FMT_lx
" - " TARGET_FMT_lx
" => %016" PRIx64
842 " %08" PRIx32
"\n", __func__
, slb_nr
, rb
, rs
, slb
->tmp64
,
845 slb_set_entry(env
, slb_nr
, slb
);
847 #endif /* defined(TARGET_PPC64) */
849 /* Perform segment based translation */
850 static inline target_phys_addr_t
get_pgaddr(target_phys_addr_t sdr1
,
852 target_phys_addr_t hash
,
853 target_phys_addr_t mask
)
855 return (sdr1
& ((target_phys_addr_t
)(-1ULL) << sdr_sh
)) | (hash
& mask
);
858 static inline int get_segment(CPUState
*env
, mmu_ctx_t
*ctx
,
859 target_ulong eaddr
, int rw
, int type
)
861 target_phys_addr_t sdr
, hash
, mask
, sdr_mask
, htab_mask
;
862 target_ulong sr
, vsid
, vsid_mask
, pgidx
, page_mask
;
863 #if defined(TARGET_PPC64)
866 int ds
, vsid_sh
, sdr_sh
, pr
, target_page_bits
;
870 #if defined(TARGET_PPC64)
871 if (env
->mmu_model
& POWERPC_MMU_64
) {
872 LOG_MMU("Check SLBs\n");
873 ret
= slb_lookup(env
, eaddr
, &vsid
, &page_mask
, &attr
,
877 ctx
->key
= ((attr
& 0x40) && (pr
!= 0)) ||
878 ((attr
& 0x80) && (pr
== 0)) ? 1 : 0;
880 ctx
->nx
= attr
& 0x10 ? 1 : 0;
882 vsid_mask
= 0x00003FFFFFFFFF80ULL
;
887 #endif /* defined(TARGET_PPC64) */
889 sr
= env
->sr
[eaddr
>> 28];
890 page_mask
= 0x0FFFFFFF;
891 ctx
->key
= (((sr
& 0x20000000) && (pr
!= 0)) ||
892 ((sr
& 0x40000000) && (pr
== 0))) ? 1 : 0;
893 ds
= sr
& 0x80000000 ? 1 : 0;
894 ctx
->nx
= sr
& 0x10000000 ? 1 : 0;
895 vsid
= sr
& 0x00FFFFFF;
896 vsid_mask
= 0x01FFFFC0;
900 target_page_bits
= TARGET_PAGE_BITS
;
901 LOG_MMU("Check segment v=" TARGET_FMT_lx
" %d " TARGET_FMT_lx
" nip="
902 TARGET_FMT_lx
" lr=" TARGET_FMT_lx
903 " ir=%d dr=%d pr=%d %d t=%d\n",
904 eaddr
, (int)(eaddr
>> 28), sr
, env
->nip
, env
->lr
, (int)msr_ir
,
905 (int)msr_dr
, pr
!= 0 ? 1 : 0, rw
, type
);
907 LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx
"\n",
908 ctx
->key
, ds
, ctx
->nx
, vsid
);
911 /* Check if instruction fetch is allowed, if needed */
912 if (type
!= ACCESS_CODE
|| ctx
->nx
== 0) {
913 /* Page address translation */
914 /* Primary table address */
916 pgidx
= (eaddr
& page_mask
) >> target_page_bits
;
917 #if defined(TARGET_PPC64)
918 if (env
->mmu_model
& POWERPC_MMU_64
) {
919 htab_mask
= 0x0FFFFFFF >> (28 - (sdr
& 0x1F));
920 /* XXX: this is false for 1 TB segments */
921 hash
= ((vsid
^ pgidx
) << vsid_sh
) & vsid_mask
;
925 htab_mask
= sdr
& 0x000001FF;
926 hash
= ((vsid
^ pgidx
) << vsid_sh
) & vsid_mask
;
928 mask
= (htab_mask
<< sdr_sh
) | sdr_mask
;
929 LOG_MMU("sdr " TARGET_FMT_plx
" sh %d hash " TARGET_FMT_plx
930 " mask " TARGET_FMT_plx
" " TARGET_FMT_lx
"\n",
931 sdr
, sdr_sh
, hash
, mask
, page_mask
);
932 ctx
->pg_addr
[0] = get_pgaddr(sdr
, sdr_sh
, hash
, mask
);
933 /* Secondary table address */
934 hash
= (~hash
) & vsid_mask
;
935 LOG_MMU("sdr " TARGET_FMT_plx
" sh %d hash " TARGET_FMT_plx
936 " mask " TARGET_FMT_plx
"\n", sdr
, sdr_sh
, hash
, mask
);
937 ctx
->pg_addr
[1] = get_pgaddr(sdr
, sdr_sh
, hash
, mask
);
938 #if defined(TARGET_PPC64)
939 if (env
->mmu_model
& POWERPC_MMU_64
) {
940 /* Only 5 bits of the page index are used in the AVPN */
941 if (target_page_bits
> 23) {
942 ctx
->ptem
= (vsid
<< 12) |
943 ((pgidx
<< (target_page_bits
- 16)) & 0xF80);
945 ctx
->ptem
= (vsid
<< 12) | ((pgidx
>> 4) & 0x0F80);
950 ctx
->ptem
= (vsid
<< 7) | (pgidx
>> 10);
952 /* Initialize real address with an invalid value */
953 ctx
->raddr
= (target_phys_addr_t
)-1ULL;
954 if (unlikely(env
->mmu_model
== POWERPC_MMU_SOFT_6xx
||
955 env
->mmu_model
== POWERPC_MMU_SOFT_74xx
)) {
956 /* Software TLB search */
957 ret
= ppc6xx_tlb_check(env
, ctx
, eaddr
, rw
, type
);
959 LOG_MMU("0 sdr1=" TARGET_FMT_plx
" vsid=" TARGET_FMT_lx
" "
960 "api=" TARGET_FMT_lx
" hash=" TARGET_FMT_plx
961 " pg_addr=" TARGET_FMT_plx
"\n",
962 sdr
, vsid
, pgidx
, hash
, ctx
->pg_addr
[0]);
963 /* Primary table lookup */
964 ret
= find_pte(env
, ctx
, 0, rw
, type
, target_page_bits
);
966 /* Secondary table lookup */
967 if (eaddr
!= 0xEFFFFFFF)
968 LOG_MMU("1 sdr1=" TARGET_FMT_plx
" vsid=" TARGET_FMT_lx
" "
969 "api=" TARGET_FMT_lx
" hash=" TARGET_FMT_plx
970 " pg_addr=" TARGET_FMT_plx
"\n", sdr
, vsid
,
971 pgidx
, hash
, ctx
->pg_addr
[1]);
972 ret2
= find_pte(env
, ctx
, 1, rw
, type
,
978 #if defined (DUMP_PAGE_TABLES)
979 if (qemu_log_enabled()) {
980 target_phys_addr_t curaddr
;
981 uint32_t a0
, a1
, a2
, a3
;
982 qemu_log("Page table: " TARGET_FMT_plx
" len " TARGET_FMT_plx
983 "\n", sdr
, mask
+ 0x80);
984 for (curaddr
= sdr
; curaddr
< (sdr
+ mask
+ 0x80);
986 a0
= ldl_phys(curaddr
);
987 a1
= ldl_phys(curaddr
+ 4);
988 a2
= ldl_phys(curaddr
+ 8);
989 a3
= ldl_phys(curaddr
+ 12);
990 if (a0
!= 0 || a1
!= 0 || a2
!= 0 || a3
!= 0) {
991 qemu_log(TARGET_FMT_plx
": %08x %08x %08x %08x\n",
992 curaddr
, a0
, a1
, a2
, a3
);
998 LOG_MMU("No access allowed\n");
1002 LOG_MMU("direct store...\n");
1003 /* Direct-store segment : absolutely *BUGGY* for now */
1006 /* Integer load/store : only access allowed */
1009 /* No code fetch is allowed in direct-store areas */
1012 /* Floating point load/store */
1015 /* lwarx, ldarx or srwcx. */
1018 /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
1019 /* Should make the instruction do no-op.
1020 * As it already do no-op, it's quite easy :-)
1025 /* eciwx or ecowx */
1028 qemu_log("ERROR: instruction should not need "
1029 "address translation\n");
1032 if ((rw
== 1 || ctx
->key
!= 1) && (rw
== 0 || ctx
->key
!= 0)) {
1043 /* Generic TLB check function for embedded PowerPC implementations */
1044 static inline int ppcemb_tlb_check(CPUState
*env
, ppcemb_tlb_t
*tlb
,
1045 target_phys_addr_t
*raddrp
,
1046 target_ulong address
, uint32_t pid
, int ext
,
1051 /* Check valid flag */
1052 if (!(tlb
->prot
& PAGE_VALID
)) {
1055 mask
= ~(tlb
->size
- 1);
1056 LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx
" PID %u <=> " TARGET_FMT_lx
1057 " " TARGET_FMT_lx
" %u\n", __func__
, i
, address
, pid
, tlb
->EPN
,
1058 mask
, (uint32_t)tlb
->PID
);
1060 if (tlb
->PID
!= 0 && tlb
->PID
!= pid
)
1062 /* Check effective address */
1063 if ((address
& mask
) != tlb
->EPN
)
1065 *raddrp
= (tlb
->RPN
& mask
) | (address
& ~mask
);
1066 #if (TARGET_PHYS_ADDR_BITS >= 36)
1068 /* Extend the physical address to 36 bits */
1069 *raddrp
|= (target_phys_addr_t
)(tlb
->RPN
& 0xF) << 32;
1076 /* Generic TLB search function for PowerPC embedded implementations */
1077 int ppcemb_tlb_search (CPUPPCState
*env
, target_ulong address
, uint32_t pid
)
1080 target_phys_addr_t raddr
;
1083 /* Default return value is no match */
1085 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1086 tlb
= &env
->tlb
[i
].tlbe
;
1087 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
, pid
, 0, i
) == 0) {
1096 /* Helpers specific to PowerPC 40x implementations */
1097 static inline void ppc4xx_tlb_invalidate_all(CPUState
*env
)
1102 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1103 tlb
= &env
->tlb
[i
].tlbe
;
1104 tlb
->prot
&= ~PAGE_VALID
;
1109 static inline void ppc4xx_tlb_invalidate_virt(CPUState
*env
,
1110 target_ulong eaddr
, uint32_t pid
)
1112 #if !defined(FLUSH_ALL_TLBS)
1114 target_phys_addr_t raddr
;
1115 target_ulong page
, end
;
1118 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1119 tlb
= &env
->tlb
[i
].tlbe
;
1120 if (ppcemb_tlb_check(env
, tlb
, &raddr
, eaddr
, pid
, 0, i
) == 0) {
1121 end
= tlb
->EPN
+ tlb
->size
;
1122 for (page
= tlb
->EPN
; page
< end
; page
+= TARGET_PAGE_SIZE
)
1123 tlb_flush_page(env
, page
);
1124 tlb
->prot
&= ~PAGE_VALID
;
1129 ppc4xx_tlb_invalidate_all(env
);
1133 static int mmu40x_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1134 target_ulong address
, int rw
, int access_type
)
1137 target_phys_addr_t raddr
;
1138 int i
, ret
, zsel
, zpr
, pr
;
1141 raddr
= (target_phys_addr_t
)-1ULL;
1143 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1144 tlb
= &env
->tlb
[i
].tlbe
;
1145 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
,
1146 env
->spr
[SPR_40x_PID
], 0, i
) < 0)
1148 zsel
= (tlb
->attr
>> 4) & 0xF;
1149 zpr
= (env
->spr
[SPR_40x_ZPR
] >> (30 - (2 * zsel
))) & 0x3;
1150 LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1151 __func__
, i
, zsel
, zpr
, rw
, tlb
->attr
);
1152 /* Check execute enable bit */
1159 /* All accesses granted */
1160 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
1165 /* Raise Zone protection fault. */
1166 env
->spr
[SPR_40x_ESR
] = 1 << 22;
1174 /* Check from TLB entry */
1175 ctx
->prot
= tlb
->prot
;
1176 ret
= check_prot(ctx
->prot
, rw
, access_type
);
1178 env
->spr
[SPR_40x_ESR
] = 0;
1183 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1184 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1189 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1190 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1195 void store_40x_sler (CPUPPCState
*env
, uint32_t val
)
1197 /* XXX: TO BE FIXED */
1198 if (val
!= 0x00000000) {
1199 cpu_abort(env
, "Little-endian regions are not supported by now\n");
1201 env
->spr
[SPR_405_SLER
] = val
;
1204 static int mmubooke_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1205 target_ulong address
, int rw
,
1209 target_phys_addr_t raddr
;
1213 raddr
= (target_phys_addr_t
)-1ULL;
1214 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1215 tlb
= &env
->tlb
[i
].tlbe
;
1216 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
,
1217 env
->spr
[SPR_BOOKE_PID
], 1, i
) < 0)
1220 prot
= tlb
->prot
& 0xF;
1222 prot
= (tlb
->prot
>> 4) & 0xF;
1223 /* Check the address space */
1224 if (access_type
== ACCESS_CODE
) {
1225 if (msr_ir
!= (tlb
->attr
& 1))
1228 if (prot
& PAGE_EXEC
) {
1234 if (msr_dr
!= (tlb
->attr
& 1))
1237 if ((!rw
&& prot
& PAGE_READ
) || (rw
&& (prot
& PAGE_WRITE
))) {
1250 static inline int check_physical(CPUState
*env
, mmu_ctx_t
*ctx
,
1251 target_ulong eaddr
, int rw
)
1256 ctx
->prot
= PAGE_READ
| PAGE_EXEC
;
1258 switch (env
->mmu_model
) {
1259 case POWERPC_MMU_32B
:
1260 case POWERPC_MMU_601
:
1261 case POWERPC_MMU_SOFT_6xx
:
1262 case POWERPC_MMU_SOFT_74xx
:
1263 case POWERPC_MMU_SOFT_4xx
:
1264 case POWERPC_MMU_REAL
:
1265 case POWERPC_MMU_BOOKE
:
1266 ctx
->prot
|= PAGE_WRITE
;
1268 #if defined(TARGET_PPC64)
1269 case POWERPC_MMU_620
:
1270 case POWERPC_MMU_64B
:
1271 /* Real address are 60 bits long */
1272 ctx
->raddr
&= 0x0FFFFFFFFFFFFFFFULL
;
1273 ctx
->prot
|= PAGE_WRITE
;
1276 case POWERPC_MMU_SOFT_4xx_Z
:
1277 if (unlikely(msr_pe
!= 0)) {
1278 /* 403 family add some particular protections,
1279 * using PBL/PBU registers for accesses with no translation.
1282 /* Check PLB validity */
1283 (env
->pb
[0] < env
->pb
[1] &&
1284 /* and address in plb area */
1285 eaddr
>= env
->pb
[0] && eaddr
< env
->pb
[1]) ||
1286 (env
->pb
[2] < env
->pb
[3] &&
1287 eaddr
>= env
->pb
[2] && eaddr
< env
->pb
[3]) ? 1 : 0;
1288 if (in_plb
^ msr_px
) {
1289 /* Access in protected area */
1291 /* Access is not allowed */
1295 /* Read-write access is allowed */
1296 ctx
->prot
|= PAGE_WRITE
;
1300 case POWERPC_MMU_MPC8xx
:
1302 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1304 case POWERPC_MMU_BOOKE_FSL
:
1306 cpu_abort(env
, "BookE FSL MMU model not implemented\n");
1309 cpu_abort(env
, "Unknown or invalid MMU model\n");
1316 int get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
, target_ulong eaddr
,
1317 int rw
, int access_type
)
1322 qemu_log("%s\n", __func__
);
1324 if ((access_type
== ACCESS_CODE
&& msr_ir
== 0) ||
1325 (access_type
!= ACCESS_CODE
&& msr_dr
== 0)) {
1326 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1327 /* The BookE MMU always performs address translation. The
1328 IS and DS bits only affect the address space. */
1329 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1332 /* No address translation. */
1333 ret
= check_physical(env
, ctx
, eaddr
, rw
);
1337 switch (env
->mmu_model
) {
1338 case POWERPC_MMU_32B
:
1339 case POWERPC_MMU_601
:
1340 case POWERPC_MMU_SOFT_6xx
:
1341 case POWERPC_MMU_SOFT_74xx
:
1342 /* Try to find a BAT */
1343 if (env
->nb_BATs
!= 0)
1344 ret
= get_bat(env
, ctx
, eaddr
, rw
, access_type
);
1345 #if defined(TARGET_PPC64)
1346 case POWERPC_MMU_620
:
1347 case POWERPC_MMU_64B
:
1350 /* We didn't match any BAT entry or don't have BATs */
1351 ret
= get_segment(env
, ctx
, eaddr
, rw
, access_type
);
1354 case POWERPC_MMU_SOFT_4xx
:
1355 case POWERPC_MMU_SOFT_4xx_Z
:
1356 ret
= mmu40x_get_physical_address(env
, ctx
, eaddr
,
1359 case POWERPC_MMU_BOOKE
:
1360 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1363 case POWERPC_MMU_MPC8xx
:
1365 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1367 case POWERPC_MMU_BOOKE_FSL
:
1369 cpu_abort(env
, "BookE FSL MMU model not implemented\n");
1371 case POWERPC_MMU_REAL
:
1372 cpu_abort(env
, "PowerPC in real mode do not do any translation\n");
1375 cpu_abort(env
, "Unknown or invalid MMU model\n");
1380 qemu_log("%s address " TARGET_FMT_lx
" => %d " TARGET_FMT_plx
"\n",
1381 __func__
, eaddr
, ret
, ctx
->raddr
);
1387 target_phys_addr_t
cpu_get_phys_page_debug (CPUState
*env
, target_ulong addr
)
1391 if (unlikely(get_physical_address(env
, &ctx
, addr
, 0, ACCESS_INT
) != 0))
1394 return ctx
.raddr
& TARGET_PAGE_MASK
;
1397 /* Perform address translation */
1398 int cpu_ppc_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
1399 int mmu_idx
, int is_softmmu
)
1408 access_type
= ACCESS_CODE
;
1411 access_type
= env
->access_type
;
1413 ret
= get_physical_address(env
, &ctx
, address
, rw
, access_type
);
1415 tlb_set_page(env
, address
& TARGET_PAGE_MASK
,
1416 ctx
.raddr
& TARGET_PAGE_MASK
, ctx
.prot
,
1417 mmu_idx
, TARGET_PAGE_SIZE
);
1419 } else if (ret
< 0) {
1421 if (access_type
== ACCESS_CODE
) {
1424 /* No matches in page tables or TLB */
1425 switch (env
->mmu_model
) {
1426 case POWERPC_MMU_SOFT_6xx
:
1427 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1428 env
->error_code
= 1 << 18;
1429 env
->spr
[SPR_IMISS
] = address
;
1430 env
->spr
[SPR_ICMP
] = 0x80000000 | ctx
.ptem
;
1432 case POWERPC_MMU_SOFT_74xx
:
1433 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1435 case POWERPC_MMU_SOFT_4xx
:
1436 case POWERPC_MMU_SOFT_4xx_Z
:
1437 env
->exception_index
= POWERPC_EXCP_ITLB
;
1438 env
->error_code
= 0;
1439 env
->spr
[SPR_40x_DEAR
] = address
;
1440 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1442 case POWERPC_MMU_32B
:
1443 case POWERPC_MMU_601
:
1444 #if defined(TARGET_PPC64)
1445 case POWERPC_MMU_620
:
1446 case POWERPC_MMU_64B
:
1448 env
->exception_index
= POWERPC_EXCP_ISI
;
1449 env
->error_code
= 0x40000000;
1451 case POWERPC_MMU_BOOKE
:
1452 env
->exception_index
= POWERPC_EXCP_ITLB
;
1453 env
->error_code
= 0;
1454 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1456 case POWERPC_MMU_BOOKE_FSL
:
1458 cpu_abort(env
, "BookE FSL MMU model is not implemented\n");
1460 case POWERPC_MMU_MPC8xx
:
1462 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1464 case POWERPC_MMU_REAL
:
1465 cpu_abort(env
, "PowerPC in real mode should never raise "
1466 "any MMU exceptions\n");
1469 cpu_abort(env
, "Unknown or invalid MMU model\n");
1474 /* Access rights violation */
1475 env
->exception_index
= POWERPC_EXCP_ISI
;
1476 env
->error_code
= 0x08000000;
1479 /* No execute protection violation */
1480 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1481 env
->spr
[SPR_BOOKE_ESR
] = 0x00000000;
1483 env
->exception_index
= POWERPC_EXCP_ISI
;
1484 env
->error_code
= 0x10000000;
1487 /* Direct store exception */
1488 /* No code fetch is allowed in direct-store areas */
1489 env
->exception_index
= POWERPC_EXCP_ISI
;
1490 env
->error_code
= 0x10000000;
1492 #if defined(TARGET_PPC64)
1494 /* No match in segment table */
1495 if (env
->mmu_model
== POWERPC_MMU_620
) {
1496 env
->exception_index
= POWERPC_EXCP_ISI
;
1497 /* XXX: this might be incorrect */
1498 env
->error_code
= 0x40000000;
1500 env
->exception_index
= POWERPC_EXCP_ISEG
;
1501 env
->error_code
= 0;
1509 /* No matches in page tables or TLB */
1510 switch (env
->mmu_model
) {
1511 case POWERPC_MMU_SOFT_6xx
:
1513 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1514 env
->error_code
= 1 << 16;
1516 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1517 env
->error_code
= 0;
1519 env
->spr
[SPR_DMISS
] = address
;
1520 env
->spr
[SPR_DCMP
] = 0x80000000 | ctx
.ptem
;
1522 env
->error_code
|= ctx
.key
<< 19;
1523 env
->spr
[SPR_HASH1
] = ctx
.pg_addr
[0];
1524 env
->spr
[SPR_HASH2
] = ctx
.pg_addr
[1];
1526 case POWERPC_MMU_SOFT_74xx
:
1528 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1530 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1533 /* Implement LRU algorithm */
1534 env
->error_code
= ctx
.key
<< 19;
1535 env
->spr
[SPR_TLBMISS
] = (address
& ~((target_ulong
)0x3)) |
1536 ((env
->last_way
+ 1) & (env
->nb_ways
- 1));
1537 env
->spr
[SPR_PTEHI
] = 0x80000000 | ctx
.ptem
;
1539 case POWERPC_MMU_SOFT_4xx
:
1540 case POWERPC_MMU_SOFT_4xx_Z
:
1541 env
->exception_index
= POWERPC_EXCP_DTLB
;
1542 env
->error_code
= 0;
1543 env
->spr
[SPR_40x_DEAR
] = address
;
1545 env
->spr
[SPR_40x_ESR
] = 0x00800000;
1547 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1549 case POWERPC_MMU_32B
:
1550 case POWERPC_MMU_601
:
1551 #if defined(TARGET_PPC64)
1552 case POWERPC_MMU_620
:
1553 case POWERPC_MMU_64B
:
1555 env
->exception_index
= POWERPC_EXCP_DSI
;
1556 env
->error_code
= 0;
1557 env
->spr
[SPR_DAR
] = address
;
1559 env
->spr
[SPR_DSISR
] = 0x42000000;
1561 env
->spr
[SPR_DSISR
] = 0x40000000;
1563 case POWERPC_MMU_MPC8xx
:
1565 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1567 case POWERPC_MMU_BOOKE
:
1568 env
->exception_index
= POWERPC_EXCP_DTLB
;
1569 env
->error_code
= 0;
1570 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1571 env
->spr
[SPR_BOOKE_ESR
] = rw
? 1 << ESR_ST
: 0;
1573 case POWERPC_MMU_BOOKE_FSL
:
1575 cpu_abort(env
, "BookE FSL MMU model is not implemented\n");
1577 case POWERPC_MMU_REAL
:
1578 cpu_abort(env
, "PowerPC in real mode should never raise "
1579 "any MMU exceptions\n");
1582 cpu_abort(env
, "Unknown or invalid MMU model\n");
1587 /* Access rights violation */
1588 env
->exception_index
= POWERPC_EXCP_DSI
;
1589 env
->error_code
= 0;
1590 if (env
->mmu_model
== POWERPC_MMU_SOFT_4xx
1591 || env
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
) {
1592 env
->spr
[SPR_40x_DEAR
] = address
;
1594 env
->spr
[SPR_40x_ESR
] |= 0x00800000;
1596 } else if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1597 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1598 env
->spr
[SPR_BOOKE_ESR
] = rw
? 1 << ESR_ST
: 0;
1600 env
->spr
[SPR_DAR
] = address
;
1602 env
->spr
[SPR_DSISR
] = 0x0A000000;
1604 env
->spr
[SPR_DSISR
] = 0x08000000;
1609 /* Direct store exception */
1610 switch (access_type
) {
1612 /* Floating point load/store */
1613 env
->exception_index
= POWERPC_EXCP_ALIGN
;
1614 env
->error_code
= POWERPC_EXCP_ALIGN_FP
;
1615 env
->spr
[SPR_DAR
] = address
;
1618 /* lwarx, ldarx or stwcx. */
1619 env
->exception_index
= POWERPC_EXCP_DSI
;
1620 env
->error_code
= 0;
1621 env
->spr
[SPR_DAR
] = address
;
1623 env
->spr
[SPR_DSISR
] = 0x06000000;
1625 env
->spr
[SPR_DSISR
] = 0x04000000;
1628 /* eciwx or ecowx */
1629 env
->exception_index
= POWERPC_EXCP_DSI
;
1630 env
->error_code
= 0;
1631 env
->spr
[SPR_DAR
] = address
;
1633 env
->spr
[SPR_DSISR
] = 0x06100000;
1635 env
->spr
[SPR_DSISR
] = 0x04100000;
1638 printf("DSI: invalid exception (%d)\n", ret
);
1639 env
->exception_index
= POWERPC_EXCP_PROGRAM
;
1641 POWERPC_EXCP_INVAL
| POWERPC_EXCP_INVAL_INVAL
;
1642 env
->spr
[SPR_DAR
] = address
;
1646 #if defined(TARGET_PPC64)
1648 /* No match in segment table */
1649 if (env
->mmu_model
== POWERPC_MMU_620
) {
1650 env
->exception_index
= POWERPC_EXCP_DSI
;
1651 env
->error_code
= 0;
1652 env
->spr
[SPR_DAR
] = address
;
1653 /* XXX: this might be incorrect */
1655 env
->spr
[SPR_DSISR
] = 0x42000000;
1657 env
->spr
[SPR_DSISR
] = 0x40000000;
1659 env
->exception_index
= POWERPC_EXCP_DSEG
;
1660 env
->error_code
= 0;
1661 env
->spr
[SPR_DAR
] = address
;
1668 printf("%s: set exception to %d %02x\n", __func__
,
1669 env
->exception
, env
->error_code
);
1677 /*****************************************************************************/
1678 /* BATs management */
1679 #if !defined(FLUSH_ALL_TLBS)
1680 static inline void do_invalidate_BAT(CPUPPCState
*env
, target_ulong BATu
,
1683 target_ulong base
, end
, page
;
1685 base
= BATu
& ~0x0001FFFF;
1686 end
= base
+ mask
+ 0x00020000;
1687 LOG_BATS("Flush BAT from " TARGET_FMT_lx
" to " TARGET_FMT_lx
" ("
1688 TARGET_FMT_lx
")\n", base
, end
, mask
);
1689 for (page
= base
; page
!= end
; page
+= TARGET_PAGE_SIZE
)
1690 tlb_flush_page(env
, page
);
1691 LOG_BATS("Flush done\n");
1695 static inline void dump_store_bat(CPUPPCState
*env
, char ID
, int ul
, int nr
,
1698 LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx
" (" TARGET_FMT_lx
")\n", ID
,
1699 nr
, ul
== 0 ? 'u' : 'l', value
, env
->nip
);
1702 void ppc_store_ibatu (CPUPPCState
*env
, int nr
, target_ulong value
)
1706 dump_store_bat(env
, 'I', 0, nr
, value
);
1707 if (env
->IBAT
[0][nr
] != value
) {
1708 mask
= (value
<< 15) & 0x0FFE0000UL
;
1709 #if !defined(FLUSH_ALL_TLBS)
1710 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1712 /* When storing valid upper BAT, mask BEPI and BRPN
1713 * and invalidate all TLBs covered by this BAT
1715 mask
= (value
<< 15) & 0x0FFE0000UL
;
1716 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1717 (value
& ~0x0001FFFFUL
& ~mask
);
1718 env
->IBAT
[1][nr
] = (env
->IBAT
[1][nr
] & 0x0000007B) |
1719 (env
->IBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
1720 #if !defined(FLUSH_ALL_TLBS)
1721 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1728 void ppc_store_ibatl (CPUPPCState
*env
, int nr
, target_ulong value
)
1730 dump_store_bat(env
, 'I', 1, nr
, value
);
1731 env
->IBAT
[1][nr
] = value
;
1734 void ppc_store_dbatu (CPUPPCState
*env
, int nr
, target_ulong value
)
1738 dump_store_bat(env
, 'D', 0, nr
, value
);
1739 if (env
->DBAT
[0][nr
] != value
) {
1740 /* When storing valid upper BAT, mask BEPI and BRPN
1741 * and invalidate all TLBs covered by this BAT
1743 mask
= (value
<< 15) & 0x0FFE0000UL
;
1744 #if !defined(FLUSH_ALL_TLBS)
1745 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
1747 mask
= (value
<< 15) & 0x0FFE0000UL
;
1748 env
->DBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1749 (value
& ~0x0001FFFFUL
& ~mask
);
1750 env
->DBAT
[1][nr
] = (env
->DBAT
[1][nr
] & 0x0000007B) |
1751 (env
->DBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
1752 #if !defined(FLUSH_ALL_TLBS)
1753 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
1760 void ppc_store_dbatl (CPUPPCState
*env
, int nr
, target_ulong value
)
1762 dump_store_bat(env
, 'D', 1, nr
, value
);
1763 env
->DBAT
[1][nr
] = value
;
1766 void ppc_store_ibatu_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
1769 #if defined(FLUSH_ALL_TLBS)
1773 dump_store_bat(env
, 'I', 0, nr
, value
);
1774 if (env
->IBAT
[0][nr
] != value
) {
1775 #if defined(FLUSH_ALL_TLBS)
1778 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
1779 if (env
->IBAT
[1][nr
] & 0x40) {
1780 /* Invalidate BAT only if it is valid */
1781 #if !defined(FLUSH_ALL_TLBS)
1782 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1787 /* When storing valid upper BAT, mask BEPI and BRPN
1788 * and invalidate all TLBs covered by this BAT
1790 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1791 (value
& ~0x0001FFFFUL
& ~mask
);
1792 env
->DBAT
[0][nr
] = env
->IBAT
[0][nr
];
1793 if (env
->IBAT
[1][nr
] & 0x40) {
1794 #if !defined(FLUSH_ALL_TLBS)
1795 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1800 #if defined(FLUSH_ALL_TLBS)
1807 void ppc_store_ibatl_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
1810 #if defined(FLUSH_ALL_TLBS)
1814 dump_store_bat(env
, 'I', 1, nr
, value
);
1815 if (env
->IBAT
[1][nr
] != value
) {
1816 #if defined(FLUSH_ALL_TLBS)
1819 if (env
->IBAT
[1][nr
] & 0x40) {
1820 #if !defined(FLUSH_ALL_TLBS)
1821 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
1822 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1828 #if !defined(FLUSH_ALL_TLBS)
1829 mask
= (value
<< 17) & 0x0FFE0000UL
;
1830 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1835 env
->IBAT
[1][nr
] = value
;
1836 env
->DBAT
[1][nr
] = value
;
1837 #if defined(FLUSH_ALL_TLBS)
1844 /*****************************************************************************/
1845 /* TLB management */
1846 void ppc_tlb_invalidate_all (CPUPPCState
*env
)
1848 switch (env
->mmu_model
) {
1849 case POWERPC_MMU_SOFT_6xx
:
1850 case POWERPC_MMU_SOFT_74xx
:
1851 ppc6xx_tlb_invalidate_all(env
);
1853 case POWERPC_MMU_SOFT_4xx
:
1854 case POWERPC_MMU_SOFT_4xx_Z
:
1855 ppc4xx_tlb_invalidate_all(env
);
1857 case POWERPC_MMU_REAL
:
1858 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
1860 case POWERPC_MMU_MPC8xx
:
1862 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1864 case POWERPC_MMU_BOOKE
:
1867 case POWERPC_MMU_BOOKE_FSL
:
1870 cpu_abort(env
, "BookE MMU model is not implemented\n");
1872 case POWERPC_MMU_32B
:
1873 case POWERPC_MMU_601
:
1874 #if defined(TARGET_PPC64)
1875 case POWERPC_MMU_620
:
1876 case POWERPC_MMU_64B
:
1877 #endif /* defined(TARGET_PPC64) */
1882 cpu_abort(env
, "Unknown MMU model\n");
1887 void ppc_tlb_invalidate_one (CPUPPCState
*env
, target_ulong addr
)
1889 #if !defined(FLUSH_ALL_TLBS)
1890 addr
&= TARGET_PAGE_MASK
;
1891 switch (env
->mmu_model
) {
1892 case POWERPC_MMU_SOFT_6xx
:
1893 case POWERPC_MMU_SOFT_74xx
:
1894 ppc6xx_tlb_invalidate_virt(env
, addr
, 0);
1895 if (env
->id_tlbs
== 1)
1896 ppc6xx_tlb_invalidate_virt(env
, addr
, 1);
1898 case POWERPC_MMU_SOFT_4xx
:
1899 case POWERPC_MMU_SOFT_4xx_Z
:
1900 ppc4xx_tlb_invalidate_virt(env
, addr
, env
->spr
[SPR_40x_PID
]);
1902 case POWERPC_MMU_REAL
:
1903 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
1905 case POWERPC_MMU_MPC8xx
:
1907 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1909 case POWERPC_MMU_BOOKE
:
1911 cpu_abort(env
, "BookE MMU model is not implemented\n");
1913 case POWERPC_MMU_BOOKE_FSL
:
1915 cpu_abort(env
, "BookE FSL MMU model is not implemented\n");
1917 case POWERPC_MMU_32B
:
1918 case POWERPC_MMU_601
:
1919 /* tlbie invalidate TLBs for all segments */
1920 addr
&= ~((target_ulong
)-1ULL << 28);
1921 /* XXX: this case should be optimized,
1922 * giving a mask to tlb_flush_page
1924 tlb_flush_page(env
, addr
| (0x0 << 28));
1925 tlb_flush_page(env
, addr
| (0x1 << 28));
1926 tlb_flush_page(env
, addr
| (0x2 << 28));
1927 tlb_flush_page(env
, addr
| (0x3 << 28));
1928 tlb_flush_page(env
, addr
| (0x4 << 28));
1929 tlb_flush_page(env
, addr
| (0x5 << 28));
1930 tlb_flush_page(env
, addr
| (0x6 << 28));
1931 tlb_flush_page(env
, addr
| (0x7 << 28));
1932 tlb_flush_page(env
, addr
| (0x8 << 28));
1933 tlb_flush_page(env
, addr
| (0x9 << 28));
1934 tlb_flush_page(env
, addr
| (0xA << 28));
1935 tlb_flush_page(env
, addr
| (0xB << 28));
1936 tlb_flush_page(env
, addr
| (0xC << 28));
1937 tlb_flush_page(env
, addr
| (0xD << 28));
1938 tlb_flush_page(env
, addr
| (0xE << 28));
1939 tlb_flush_page(env
, addr
| (0xF << 28));
1941 #if defined(TARGET_PPC64)
1942 case POWERPC_MMU_620
:
1943 case POWERPC_MMU_64B
:
1944 /* tlbie invalidate TLBs for all segments */
1945 /* XXX: given the fact that there are too many segments to invalidate,
1946 * and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
1947 * we just invalidate all TLBs
1951 #endif /* defined(TARGET_PPC64) */
1954 cpu_abort(env
, "Unknown MMU model\n");
1958 ppc_tlb_invalidate_all(env
);
1962 /*****************************************************************************/
1963 /* Special registers manipulation */
1964 #if defined(TARGET_PPC64)
1965 void ppc_store_asr (CPUPPCState
*env
, target_ulong value
)
1967 if (env
->asr
!= value
) {
1974 void ppc_store_sdr1 (CPUPPCState
*env
, target_ulong value
)
1976 LOG_MMU("%s: " TARGET_FMT_lx
"\n", __func__
, value
);
1977 if (env
->sdr1
!= value
) {
1978 /* XXX: for PowerPC 64, should check that the HTABSIZE value
1986 #if defined(TARGET_PPC64)
1987 target_ulong
ppc_load_sr (CPUPPCState
*env
, int slb_nr
)
1994 void ppc_store_sr (CPUPPCState
*env
, int srnum
, target_ulong value
)
1996 LOG_MMU("%s: reg=%d " TARGET_FMT_lx
" " TARGET_FMT_lx
"\n", __func__
,
1997 srnum
, value
, env
->sr
[srnum
]);
1998 #if defined(TARGET_PPC64)
1999 if (env
->mmu_model
& POWERPC_MMU_64
) {
2000 uint64_t rb
= 0, rs
= 0;
2003 rb
|= ((uint32_t)srnum
& 0xf) << 28;
2004 /* Set the valid bit */
2007 rb
|= (uint32_t)srnum
;
2010 rs
|= (value
& 0xfffffff) << 12;
2012 rs
|= ((value
>> 27) & 0xf) << 9;
2014 ppc_store_slb(env
, rb
, rs
);
2017 if (env
->sr
[srnum
] != value
) {
2018 env
->sr
[srnum
] = value
;
2019 /* Invalidating 256MB of virtual memory in 4kB pages is way longer than
2020 flusing the whole TLB. */
2021 #if !defined(FLUSH_ALL_TLBS) && 0
2023 target_ulong page
, end
;
2024 /* Invalidate 256 MB of virtual memory */
2025 page
= (16 << 20) * srnum
;
2026 end
= page
+ (16 << 20);
2027 for (; page
!= end
; page
+= TARGET_PAGE_SIZE
)
2028 tlb_flush_page(env
, page
);
2035 #endif /* !defined (CONFIG_USER_ONLY) */
2037 /* GDBstub can read and write MSR... */
2038 void ppc_store_msr (CPUPPCState
*env
, target_ulong value
)
2040 hreg_store_msr(env
, value
, 0);
2043 /*****************************************************************************/
2044 /* Exception processing */
2045 #if defined (CONFIG_USER_ONLY)
2046 void do_interrupt (CPUState
*env
)
2048 env
->exception_index
= POWERPC_EXCP_NONE
;
2049 env
->error_code
= 0;
2052 void ppc_hw_interrupt (CPUState
*env
)
2054 env
->exception_index
= POWERPC_EXCP_NONE
;
2055 env
->error_code
= 0;
2057 #else /* defined (CONFIG_USER_ONLY) */
2058 static inline void dump_syscall(CPUState
*env
)
2060 qemu_log_mask(CPU_LOG_INT
, "syscall r0=%016" PRIx64
" r3=%016" PRIx64
2061 " r4=%016" PRIx64
" r5=%016" PRIx64
" r6=%016" PRIx64
2062 " nip=" TARGET_FMT_lx
"\n",
2063 ppc_dump_gpr(env
, 0), ppc_dump_gpr(env
, 3),
2064 ppc_dump_gpr(env
, 4), ppc_dump_gpr(env
, 5),
2065 ppc_dump_gpr(env
, 6), env
->nip
);
2068 /* Note that this function should be greatly optimized
2069 * when called with a constant excp, from ppc_hw_interrupt
2071 static inline void powerpc_excp(CPUState
*env
, int excp_model
, int excp
)
2073 target_ulong msr
, new_msr
, vector
;
2074 int srr0
, srr1
, asrr0
, asrr1
;
2075 int lpes0
, lpes1
, lev
;
2078 /* XXX: find a suitable condition to enable the hypervisor mode */
2079 lpes0
= (env
->spr
[SPR_LPCR
] >> 1) & 1;
2080 lpes1
= (env
->spr
[SPR_LPCR
] >> 2) & 1;
2082 /* Those values ensure we won't enter the hypervisor mode */
2087 qemu_log_mask(CPU_LOG_INT
, "Raise exception at " TARGET_FMT_lx
2088 " => %08x (%02x)\n", env
->nip
, excp
, env
->error_code
);
2090 /* new srr1 value excluding must-be-zero bits */
2091 msr
= env
->msr
& ~0x783f0000ULL
;
2093 /* new interrupt handler msr */
2094 new_msr
= env
->msr
& ((target_ulong
)1 << MSR_ME
);
2096 /* target registers */
2103 case POWERPC_EXCP_NONE
:
2104 /* Should never happen */
2106 case POWERPC_EXCP_CRITICAL
: /* Critical input */
2107 switch (excp_model
) {
2108 case POWERPC_EXCP_40x
:
2109 srr0
= SPR_40x_SRR2
;
2110 srr1
= SPR_40x_SRR3
;
2112 case POWERPC_EXCP_BOOKE
:
2113 srr0
= SPR_BOOKE_CSRR0
;
2114 srr1
= SPR_BOOKE_CSRR1
;
2116 case POWERPC_EXCP_G2
:
2122 case POWERPC_EXCP_MCHECK
: /* Machine check exception */
2124 /* Machine check exception is not enabled.
2125 * Enter checkstop state.
2127 if (qemu_log_enabled()) {
2128 qemu_log("Machine check while not allowed. "
2129 "Entering checkstop state\n");
2131 fprintf(stderr
, "Machine check while not allowed. "
2132 "Entering checkstop state\n");
2135 env
->interrupt_request
|= CPU_INTERRUPT_EXITTB
;
2138 /* XXX: find a suitable condition to enable the hypervisor mode */
2139 new_msr
|= (target_ulong
)MSR_HVB
;
2142 /* machine check exceptions don't have ME set */
2143 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2145 /* XXX: should also have something loaded in DAR / DSISR */
2146 switch (excp_model
) {
2147 case POWERPC_EXCP_40x
:
2148 srr0
= SPR_40x_SRR2
;
2149 srr1
= SPR_40x_SRR3
;
2151 case POWERPC_EXCP_BOOKE
:
2152 srr0
= SPR_BOOKE_MCSRR0
;
2153 srr1
= SPR_BOOKE_MCSRR1
;
2154 asrr0
= SPR_BOOKE_CSRR0
;
2155 asrr1
= SPR_BOOKE_CSRR1
;
2161 case POWERPC_EXCP_DSI
: /* Data storage exception */
2162 LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx
" DAR=" TARGET_FMT_lx
2163 "\n", env
->spr
[SPR_DSISR
], env
->spr
[SPR_DAR
]);
2165 new_msr
|= (target_ulong
)MSR_HVB
;
2167 case POWERPC_EXCP_ISI
: /* Instruction storage exception */
2168 LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx
", nip=" TARGET_FMT_lx
2169 "\n", msr
, env
->nip
);
2171 new_msr
|= (target_ulong
)MSR_HVB
;
2172 msr
|= env
->error_code
;
2174 case POWERPC_EXCP_EXTERNAL
: /* External input */
2176 new_msr
|= (target_ulong
)MSR_HVB
;
2178 case POWERPC_EXCP_ALIGN
: /* Alignment exception */
2180 new_msr
|= (target_ulong
)MSR_HVB
;
2181 /* XXX: this is false */
2182 /* Get rS/rD and rA from faulting opcode */
2183 env
->spr
[SPR_DSISR
] |= (ldl_code((env
->nip
- 4)) & 0x03FF0000) >> 16;
2185 case POWERPC_EXCP_PROGRAM
: /* Program exception */
2186 switch (env
->error_code
& ~0xF) {
2187 case POWERPC_EXCP_FP
:
2188 if ((msr_fe0
== 0 && msr_fe1
== 0) || msr_fp
== 0) {
2189 LOG_EXCP("Ignore floating point exception\n");
2190 env
->exception_index
= POWERPC_EXCP_NONE
;
2191 env
->error_code
= 0;
2195 new_msr
|= (target_ulong
)MSR_HVB
;
2197 if (msr_fe0
== msr_fe1
)
2201 case POWERPC_EXCP_INVAL
:
2202 LOG_EXCP("Invalid instruction at " TARGET_FMT_lx
"\n", env
->nip
);
2204 new_msr
|= (target_ulong
)MSR_HVB
;
2207 case POWERPC_EXCP_PRIV
:
2209 new_msr
|= (target_ulong
)MSR_HVB
;
2212 case POWERPC_EXCP_TRAP
:
2214 new_msr
|= (target_ulong
)MSR_HVB
;
2218 /* Should never occur */
2219 cpu_abort(env
, "Invalid program exception %d. Aborting\n",
2224 case POWERPC_EXCP_FPU
: /* Floating-point unavailable exception */
2226 new_msr
|= (target_ulong
)MSR_HVB
;
2228 case POWERPC_EXCP_SYSCALL
: /* System call exception */
2229 /* NOTE: this is a temporary hack to support graphics OSI
2230 calls from the MOL driver */
2231 /* XXX: To be removed */
2232 if (env
->gpr
[3] == 0x113724fa && env
->gpr
[4] == 0x77810f9b &&
2234 if (env
->osi_call(env
) != 0) {
2235 env
->exception_index
= POWERPC_EXCP_NONE
;
2236 env
->error_code
= 0;
2241 lev
= env
->error_code
;
2242 if (lev
== 1 || (lpes0
== 0 && lpes1
== 0))
2243 new_msr
|= (target_ulong
)MSR_HVB
;
2245 case POWERPC_EXCP_APU
: /* Auxiliary processor unavailable */
2247 case POWERPC_EXCP_DECR
: /* Decrementer exception */
2249 new_msr
|= (target_ulong
)MSR_HVB
;
2251 case POWERPC_EXCP_FIT
: /* Fixed-interval timer interrupt */
2253 LOG_EXCP("FIT exception\n");
2255 case POWERPC_EXCP_WDT
: /* Watchdog timer interrupt */
2256 LOG_EXCP("WDT exception\n");
2257 switch (excp_model
) {
2258 case POWERPC_EXCP_BOOKE
:
2259 srr0
= SPR_BOOKE_CSRR0
;
2260 srr1
= SPR_BOOKE_CSRR1
;
2266 case POWERPC_EXCP_DTLB
: /* Data TLB error */
2268 case POWERPC_EXCP_ITLB
: /* Instruction TLB error */
2270 case POWERPC_EXCP_DEBUG
: /* Debug interrupt */
2271 switch (excp_model
) {
2272 case POWERPC_EXCP_BOOKE
:
2273 srr0
= SPR_BOOKE_DSRR0
;
2274 srr1
= SPR_BOOKE_DSRR1
;
2275 asrr0
= SPR_BOOKE_CSRR0
;
2276 asrr1
= SPR_BOOKE_CSRR1
;
2282 cpu_abort(env
, "Debug exception is not implemented yet !\n");
2284 case POWERPC_EXCP_SPEU
: /* SPE/embedded floating-point unavailable */
2286 case POWERPC_EXCP_EFPDI
: /* Embedded floating-point data interrupt */
2288 cpu_abort(env
, "Embedded floating point data exception "
2289 "is not implemented yet !\n");
2291 case POWERPC_EXCP_EFPRI
: /* Embedded floating-point round interrupt */
2293 cpu_abort(env
, "Embedded floating point round exception "
2294 "is not implemented yet !\n");
2296 case POWERPC_EXCP_EPERFM
: /* Embedded performance monitor interrupt */
2299 "Performance counter exception is not implemented yet !\n");
2301 case POWERPC_EXCP_DOORI
: /* Embedded doorbell interrupt */
2304 "Embedded doorbell interrupt is not implemented yet !\n");
2306 case POWERPC_EXCP_DOORCI
: /* Embedded doorbell critical interrupt */
2307 switch (excp_model
) {
2308 case POWERPC_EXCP_BOOKE
:
2309 srr0
= SPR_BOOKE_CSRR0
;
2310 srr1
= SPR_BOOKE_CSRR1
;
2316 cpu_abort(env
, "Embedded doorbell critical interrupt "
2317 "is not implemented yet !\n");
2319 case POWERPC_EXCP_RESET
: /* System reset exception */
2321 /* indicate that we resumed from power save mode */
2324 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2328 /* XXX: find a suitable condition to enable the hypervisor mode */
2329 new_msr
|= (target_ulong
)MSR_HVB
;
2332 case POWERPC_EXCP_DSEG
: /* Data segment exception */
2334 new_msr
|= (target_ulong
)MSR_HVB
;
2336 case POWERPC_EXCP_ISEG
: /* Instruction segment exception */
2338 new_msr
|= (target_ulong
)MSR_HVB
;
2340 case POWERPC_EXCP_HDECR
: /* Hypervisor decrementer exception */
2343 new_msr
|= (target_ulong
)MSR_HVB
;
2344 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2346 case POWERPC_EXCP_TRACE
: /* Trace exception */
2348 new_msr
|= (target_ulong
)MSR_HVB
;
2350 case POWERPC_EXCP_HDSI
: /* Hypervisor data storage exception */
2353 new_msr
|= (target_ulong
)MSR_HVB
;
2354 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2356 case POWERPC_EXCP_HISI
: /* Hypervisor instruction storage exception */
2359 new_msr
|= (target_ulong
)MSR_HVB
;
2360 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2362 case POWERPC_EXCP_HDSEG
: /* Hypervisor data segment exception */
2365 new_msr
|= (target_ulong
)MSR_HVB
;
2366 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2368 case POWERPC_EXCP_HISEG
: /* Hypervisor instruction segment exception */
2371 new_msr
|= (target_ulong
)MSR_HVB
;
2372 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2374 case POWERPC_EXCP_VPU
: /* Vector unavailable exception */
2376 new_msr
|= (target_ulong
)MSR_HVB
;
2378 case POWERPC_EXCP_PIT
: /* Programmable interval timer interrupt */
2379 LOG_EXCP("PIT exception\n");
2381 case POWERPC_EXCP_IO
: /* IO error exception */
2383 cpu_abort(env
, "601 IO error exception is not implemented yet !\n");
2385 case POWERPC_EXCP_RUNM
: /* Run mode exception */
2387 cpu_abort(env
, "601 run mode exception is not implemented yet !\n");
2389 case POWERPC_EXCP_EMUL
: /* Emulation trap exception */
2391 cpu_abort(env
, "602 emulation trap exception "
2392 "is not implemented yet !\n");
2394 case POWERPC_EXCP_IFTLB
: /* Instruction fetch TLB error */
2395 if (lpes1
== 0) /* XXX: check this */
2396 new_msr
|= (target_ulong
)MSR_HVB
;
2397 switch (excp_model
) {
2398 case POWERPC_EXCP_602
:
2399 case POWERPC_EXCP_603
:
2400 case POWERPC_EXCP_603E
:
2401 case POWERPC_EXCP_G2
:
2403 case POWERPC_EXCP_7x5
:
2405 case POWERPC_EXCP_74xx
:
2408 cpu_abort(env
, "Invalid instruction TLB miss exception\n");
2412 case POWERPC_EXCP_DLTLB
: /* Data load TLB miss */
2413 if (lpes1
== 0) /* XXX: check this */
2414 new_msr
|= (target_ulong
)MSR_HVB
;
2415 switch (excp_model
) {
2416 case POWERPC_EXCP_602
:
2417 case POWERPC_EXCP_603
:
2418 case POWERPC_EXCP_603E
:
2419 case POWERPC_EXCP_G2
:
2421 case POWERPC_EXCP_7x5
:
2423 case POWERPC_EXCP_74xx
:
2426 cpu_abort(env
, "Invalid data load TLB miss exception\n");
2430 case POWERPC_EXCP_DSTLB
: /* Data store TLB miss */
2431 if (lpes1
== 0) /* XXX: check this */
2432 new_msr
|= (target_ulong
)MSR_HVB
;
2433 switch (excp_model
) {
2434 case POWERPC_EXCP_602
:
2435 case POWERPC_EXCP_603
:
2436 case POWERPC_EXCP_603E
:
2437 case POWERPC_EXCP_G2
:
2439 /* Swap temporary saved registers with GPRs */
2440 if (!(new_msr
& ((target_ulong
)1 << MSR_TGPR
))) {
2441 new_msr
|= (target_ulong
)1 << MSR_TGPR
;
2442 hreg_swap_gpr_tgpr(env
);
2445 case POWERPC_EXCP_7x5
:
2447 #if defined (DEBUG_SOFTWARE_TLB)
2448 if (qemu_log_enabled()) {
2450 target_ulong
*miss
, *cmp
;
2452 if (excp
== POWERPC_EXCP_IFTLB
) {
2455 miss
= &env
->spr
[SPR_IMISS
];
2456 cmp
= &env
->spr
[SPR_ICMP
];
2458 if (excp
== POWERPC_EXCP_DLTLB
)
2463 miss
= &env
->spr
[SPR_DMISS
];
2464 cmp
= &env
->spr
[SPR_DCMP
];
2466 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2467 TARGET_FMT_lx
" H1 " TARGET_FMT_lx
" H2 "
2468 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2469 env
->spr
[SPR_HASH1
], env
->spr
[SPR_HASH2
],
2473 msr
|= env
->crf
[0] << 28;
2474 msr
|= env
->error_code
; /* key, D/I, S/L bits */
2475 /* Set way using a LRU mechanism */
2476 msr
|= ((env
->last_way
+ 1) & (env
->nb_ways
- 1)) << 17;
2478 case POWERPC_EXCP_74xx
:
2480 #if defined (DEBUG_SOFTWARE_TLB)
2481 if (qemu_log_enabled()) {
2483 target_ulong
*miss
, *cmp
;
2485 if (excp
== POWERPC_EXCP_IFTLB
) {
2488 miss
= &env
->spr
[SPR_TLBMISS
];
2489 cmp
= &env
->spr
[SPR_PTEHI
];
2491 if (excp
== POWERPC_EXCP_DLTLB
)
2496 miss
= &env
->spr
[SPR_TLBMISS
];
2497 cmp
= &env
->spr
[SPR_PTEHI
];
2499 qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2500 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2504 msr
|= env
->error_code
; /* key bit */
2507 cpu_abort(env
, "Invalid data store TLB miss exception\n");
2511 case POWERPC_EXCP_FPA
: /* Floating-point assist exception */
2513 cpu_abort(env
, "Floating point assist exception "
2514 "is not implemented yet !\n");
2516 case POWERPC_EXCP_DABR
: /* Data address breakpoint */
2518 cpu_abort(env
, "DABR exception is not implemented yet !\n");
2520 case POWERPC_EXCP_IABR
: /* Instruction address breakpoint */
2522 cpu_abort(env
, "IABR exception is not implemented yet !\n");
2524 case POWERPC_EXCP_SMI
: /* System management interrupt */
2526 cpu_abort(env
, "SMI exception is not implemented yet !\n");
2528 case POWERPC_EXCP_THERM
: /* Thermal interrupt */
2530 cpu_abort(env
, "Thermal management exception "
2531 "is not implemented yet !\n");
2533 case POWERPC_EXCP_PERFM
: /* Embedded performance monitor interrupt */
2535 new_msr
|= (target_ulong
)MSR_HVB
;
2538 "Performance counter exception is not implemented yet !\n");
2540 case POWERPC_EXCP_VPUA
: /* Vector assist exception */
2542 cpu_abort(env
, "VPU assist exception is not implemented yet !\n");
2544 case POWERPC_EXCP_SOFTP
: /* Soft patch exception */
2547 "970 soft-patch exception is not implemented yet !\n");
2549 case POWERPC_EXCP_MAINT
: /* Maintenance exception */
2552 "970 maintenance exception is not implemented yet !\n");
2554 case POWERPC_EXCP_MEXTBR
: /* Maskable external breakpoint */
2556 cpu_abort(env
, "Maskable external exception "
2557 "is not implemented yet !\n");
2559 case POWERPC_EXCP_NMEXTBR
: /* Non maskable external breakpoint */
2561 cpu_abort(env
, "Non maskable external exception "
2562 "is not implemented yet !\n");
2566 cpu_abort(env
, "Invalid PowerPC exception %d. Aborting\n", excp
);
2569 /* save current instruction location */
2570 env
->spr
[srr0
] = env
->nip
- 4;
2573 /* save next instruction location */
2574 env
->spr
[srr0
] = env
->nip
;
2578 env
->spr
[srr1
] = msr
;
2579 /* If any alternate SRR register are defined, duplicate saved values */
2581 env
->spr
[asrr0
] = env
->spr
[srr0
];
2583 env
->spr
[asrr1
] = env
->spr
[srr1
];
2584 /* If we disactivated any translation, flush TLBs */
2585 if (new_msr
& ((1 << MSR_IR
) | (1 << MSR_DR
)))
2589 new_msr
|= (target_ulong
)1 << MSR_LE
;
2592 /* Jump to handler */
2593 vector
= env
->excp_vectors
[excp
];
2594 if (vector
== (target_ulong
)-1ULL) {
2595 cpu_abort(env
, "Raised an exception without defined vector %d\n",
2598 vector
|= env
->excp_prefix
;
2599 #if defined(TARGET_PPC64)
2600 if (excp_model
== POWERPC_EXCP_BOOKE
) {
2602 vector
= (uint32_t)vector
;
2604 new_msr
|= (target_ulong
)1 << MSR_CM
;
2607 if (!msr_isf
&& !(env
->mmu_model
& POWERPC_MMU_64
)) {
2608 vector
= (uint32_t)vector
;
2610 new_msr
|= (target_ulong
)1 << MSR_SF
;
2614 /* XXX: we don't use hreg_store_msr here as already have treated
2615 * any special case that could occur. Just store MSR and update hflags
2617 env
->msr
= new_msr
& env
->msr_mask
;
2618 hreg_compute_hflags(env
);
2620 /* Reset exception state */
2621 env
->exception_index
= POWERPC_EXCP_NONE
;
2622 env
->error_code
= 0;
2624 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
2625 /* XXX: The BookE changes address space when switching modes,
2626 we should probably implement that as different MMU indexes,
2627 but for the moment we do it the slow way and flush all. */
2632 void do_interrupt (CPUState
*env
)
2634 powerpc_excp(env
, env
->excp_model
, env
->exception_index
);
2637 void ppc_hw_interrupt (CPUPPCState
*env
)
2642 qemu_log_mask(CPU_LOG_INT
, "%s: %p pending %08x req %08x me %d ee %d\n",
2643 __func__
, env
, env
->pending_interrupts
,
2644 env
->interrupt_request
, (int)msr_me
, (int)msr_ee
);
2646 /* External reset */
2647 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_RESET
)) {
2648 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_RESET
);
2649 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_RESET
);
2652 /* Machine check exception */
2653 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_MCK
)) {
2654 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_MCK
);
2655 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_MCHECK
);
2659 /* External debug exception */
2660 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DEBUG
)) {
2661 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DEBUG
);
2662 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DEBUG
);
2667 /* XXX: find a suitable condition to enable the hypervisor mode */
2668 hdice
= env
->spr
[SPR_LPCR
] & 1;
2672 if ((msr_ee
!= 0 || msr_hv
== 0 || msr_pr
!= 0) && hdice
!= 0) {
2673 /* Hypervisor decrementer exception */
2674 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_HDECR
)) {
2675 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_HDECR
);
2676 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_HDECR
);
2681 /* External critical interrupt */
2682 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CEXT
)) {
2683 /* Taking a critical external interrupt does not clear the external
2684 * critical interrupt status
2687 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CEXT
);
2689 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_CRITICAL
);
2694 /* Watchdog timer on embedded PowerPC */
2695 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_WDT
)) {
2696 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_WDT
);
2697 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_WDT
);
2700 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CDOORBELL
)) {
2701 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CDOORBELL
);
2702 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORCI
);
2705 /* Fixed interval timer on embedded PowerPC */
2706 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_FIT
)) {
2707 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_FIT
);
2708 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_FIT
);
2711 /* Programmable interval timer on embedded PowerPC */
2712 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PIT
)) {
2713 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PIT
);
2714 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PIT
);
2717 /* Decrementer exception */
2718 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DECR
)) {
2719 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DECR
);
2720 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DECR
);
2723 /* External interrupt */
2724 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_EXT
)) {
2725 /* Taking an external interrupt does not clear the external
2729 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_EXT
);
2731 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_EXTERNAL
);
2734 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DOORBELL
)) {
2735 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DOORBELL
);
2736 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORI
);
2739 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PERFM
)) {
2740 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PERFM
);
2741 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PERFM
);
2744 /* Thermal interrupt */
2745 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_THERM
)) {
2746 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_THERM
);
2747 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_THERM
);
2752 #endif /* !CONFIG_USER_ONLY */
2754 void cpu_dump_rfi (target_ulong RA
, target_ulong msr
)
2756 qemu_log("Return from exception at " TARGET_FMT_lx
" with flags "
2757 TARGET_FMT_lx
"\n", RA
, msr
);
2760 void cpu_reset(CPUPPCState
*env
)
2764 if (qemu_loglevel_mask(CPU_LOG_RESET
)) {
2765 qemu_log("CPU Reset (CPU %d)\n", env
->cpu_index
);
2766 log_cpu_state(env
, 0);
2769 msr
= (target_ulong
)0;
2771 /* XXX: find a suitable condition to enable the hypervisor mode */
2772 msr
|= (target_ulong
)MSR_HVB
;
2774 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
2775 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
2776 msr
|= (target_ulong
)1 << MSR_EP
;
2777 #if defined (DO_SINGLE_STEP) && 0
2778 /* Single step trace mode */
2779 msr
|= (target_ulong
)1 << MSR_SE
;
2780 msr
|= (target_ulong
)1 << MSR_BE
;
2782 #if defined(CONFIG_USER_ONLY)
2783 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
2784 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
2785 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
2786 msr
|= (target_ulong
)1 << MSR_PR
;
2788 env
->excp_prefix
= env
->hreset_excp_prefix
;
2789 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
2790 if (env
->mmu_model
!= POWERPC_MMU_REAL
)
2791 ppc_tlb_invalidate_all(env
);
2793 env
->msr
= msr
& env
->msr_mask
;
2794 #if defined(TARGET_PPC64)
2795 if (env
->mmu_model
& POWERPC_MMU_64
)
2796 env
->msr
|= (1ULL << MSR_SF
);
2798 hreg_compute_hflags(env
);
2799 env
->reserve_addr
= (target_ulong
)-1ULL;
2800 /* Be sure no exception or interrupt is pending */
2801 env
->pending_interrupts
= 0;
2802 env
->exception_index
= POWERPC_EXCP_NONE
;
2803 env
->error_code
= 0;
2804 /* Flush all TLBs */
2808 CPUPPCState
*cpu_ppc_init (const char *cpu_model
)
2811 const ppc_def_t
*def
;
2813 def
= cpu_ppc_find_by_name(cpu_model
);
2817 env
= qemu_mallocz(sizeof(CPUPPCState
));
2819 ppc_translate_init();
2820 env
->cpu_model_str
= cpu_model
;
2821 cpu_ppc_register_internal(env
, def
);
2823 qemu_init_vcpu(env
);
2828 void cpu_ppc_close (CPUPPCState
*env
)
2830 /* Should also remove all opcode tables... */