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 /* XXX: there is a problem here or in the TLB fill code... */
1176 ctx
->prot
= tlb
->prot
;
1177 ctx
->prot
|= PAGE_EXEC
;
1178 ret
= check_prot(ctx
->prot
, rw
, access_type
);
1180 env
->spr
[SPR_40x_ESR
] = 0;
1185 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1186 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1191 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1192 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1197 void store_40x_sler (CPUPPCState
*env
, uint32_t val
)
1199 /* XXX: TO BE FIXED */
1200 if (val
!= 0x00000000) {
1201 cpu_abort(env
, "Little-endian regions are not supported by now\n");
1203 env
->spr
[SPR_405_SLER
] = val
;
1206 static int mmubooke_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1207 target_ulong address
, int rw
,
1211 target_phys_addr_t raddr
;
1215 raddr
= (target_phys_addr_t
)-1ULL;
1216 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1217 tlb
= &env
->tlb
[i
].tlbe
;
1218 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
,
1219 env
->spr
[SPR_BOOKE_PID
], 1, i
) < 0)
1222 prot
= tlb
->prot
& 0xF;
1224 prot
= (tlb
->prot
>> 4) & 0xF;
1225 /* Check the address space */
1226 if (access_type
== ACCESS_CODE
) {
1227 if (msr_ir
!= (tlb
->attr
& 1))
1230 if (prot
& PAGE_EXEC
) {
1236 if (msr_dr
!= (tlb
->attr
& 1))
1239 if ((!rw
&& prot
& PAGE_READ
) || (rw
&& (prot
& PAGE_WRITE
))) {
1252 static inline int check_physical(CPUState
*env
, mmu_ctx_t
*ctx
,
1253 target_ulong eaddr
, int rw
)
1258 ctx
->prot
= PAGE_READ
| PAGE_EXEC
;
1260 switch (env
->mmu_model
) {
1261 case POWERPC_MMU_32B
:
1262 case POWERPC_MMU_601
:
1263 case POWERPC_MMU_SOFT_6xx
:
1264 case POWERPC_MMU_SOFT_74xx
:
1265 case POWERPC_MMU_SOFT_4xx
:
1266 case POWERPC_MMU_REAL
:
1267 case POWERPC_MMU_BOOKE
:
1268 ctx
->prot
|= PAGE_WRITE
;
1270 #if defined(TARGET_PPC64)
1271 case POWERPC_MMU_620
:
1272 case POWERPC_MMU_64B
:
1273 /* Real address are 60 bits long */
1274 ctx
->raddr
&= 0x0FFFFFFFFFFFFFFFULL
;
1275 ctx
->prot
|= PAGE_WRITE
;
1278 case POWERPC_MMU_SOFT_4xx_Z
:
1279 if (unlikely(msr_pe
!= 0)) {
1280 /* 403 family add some particular protections,
1281 * using PBL/PBU registers for accesses with no translation.
1284 /* Check PLB validity */
1285 (env
->pb
[0] < env
->pb
[1] &&
1286 /* and address in plb area */
1287 eaddr
>= env
->pb
[0] && eaddr
< env
->pb
[1]) ||
1288 (env
->pb
[2] < env
->pb
[3] &&
1289 eaddr
>= env
->pb
[2] && eaddr
< env
->pb
[3]) ? 1 : 0;
1290 if (in_plb
^ msr_px
) {
1291 /* Access in protected area */
1293 /* Access is not allowed */
1297 /* Read-write access is allowed */
1298 ctx
->prot
|= PAGE_WRITE
;
1302 case POWERPC_MMU_MPC8xx
:
1304 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1306 case POWERPC_MMU_BOOKE_FSL
:
1308 cpu_abort(env
, "BookE FSL MMU model not implemented\n");
1311 cpu_abort(env
, "Unknown or invalid MMU model\n");
1318 int get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
, target_ulong eaddr
,
1319 int rw
, int access_type
)
1324 qemu_log("%s\n", __func__
);
1326 if ((access_type
== ACCESS_CODE
&& msr_ir
== 0) ||
1327 (access_type
!= ACCESS_CODE
&& msr_dr
== 0)) {
1328 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1329 /* The BookE MMU always performs address translation. The
1330 IS and DS bits only affect the address space. */
1331 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1334 /* No address translation. */
1335 ret
= check_physical(env
, ctx
, eaddr
, rw
);
1339 switch (env
->mmu_model
) {
1340 case POWERPC_MMU_32B
:
1341 case POWERPC_MMU_601
:
1342 case POWERPC_MMU_SOFT_6xx
:
1343 case POWERPC_MMU_SOFT_74xx
:
1344 /* Try to find a BAT */
1345 if (env
->nb_BATs
!= 0)
1346 ret
= get_bat(env
, ctx
, eaddr
, rw
, access_type
);
1347 #if defined(TARGET_PPC64)
1348 case POWERPC_MMU_620
:
1349 case POWERPC_MMU_64B
:
1352 /* We didn't match any BAT entry or don't have BATs */
1353 ret
= get_segment(env
, ctx
, eaddr
, rw
, access_type
);
1356 case POWERPC_MMU_SOFT_4xx
:
1357 case POWERPC_MMU_SOFT_4xx_Z
:
1358 ret
= mmu40x_get_physical_address(env
, ctx
, eaddr
,
1361 case POWERPC_MMU_BOOKE
:
1362 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1365 case POWERPC_MMU_MPC8xx
:
1367 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1369 case POWERPC_MMU_BOOKE_FSL
:
1371 cpu_abort(env
, "BookE FSL MMU model not implemented\n");
1373 case POWERPC_MMU_REAL
:
1374 cpu_abort(env
, "PowerPC in real mode do not do any translation\n");
1377 cpu_abort(env
, "Unknown or invalid MMU model\n");
1382 qemu_log("%s address " TARGET_FMT_lx
" => %d " TARGET_FMT_plx
"\n",
1383 __func__
, eaddr
, ret
, ctx
->raddr
);
1389 target_phys_addr_t
cpu_get_phys_page_debug (CPUState
*env
, target_ulong addr
)
1393 if (unlikely(get_physical_address(env
, &ctx
, addr
, 0, ACCESS_INT
) != 0))
1396 return ctx
.raddr
& TARGET_PAGE_MASK
;
1399 /* Perform address translation */
1400 int cpu_ppc_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
1401 int mmu_idx
, int is_softmmu
)
1410 access_type
= ACCESS_CODE
;
1413 access_type
= env
->access_type
;
1415 ret
= get_physical_address(env
, &ctx
, address
, rw
, access_type
);
1417 tlb_set_page(env
, address
& TARGET_PAGE_MASK
,
1418 ctx
.raddr
& TARGET_PAGE_MASK
, ctx
.prot
,
1419 mmu_idx
, TARGET_PAGE_SIZE
);
1421 } else if (ret
< 0) {
1423 if (access_type
== ACCESS_CODE
) {
1426 /* No matches in page tables or TLB */
1427 switch (env
->mmu_model
) {
1428 case POWERPC_MMU_SOFT_6xx
:
1429 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1430 env
->error_code
= 1 << 18;
1431 env
->spr
[SPR_IMISS
] = address
;
1432 env
->spr
[SPR_ICMP
] = 0x80000000 | ctx
.ptem
;
1434 case POWERPC_MMU_SOFT_74xx
:
1435 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1437 case POWERPC_MMU_SOFT_4xx
:
1438 case POWERPC_MMU_SOFT_4xx_Z
:
1439 env
->exception_index
= POWERPC_EXCP_ITLB
;
1440 env
->error_code
= 0;
1441 env
->spr
[SPR_40x_DEAR
] = address
;
1442 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1444 case POWERPC_MMU_32B
:
1445 case POWERPC_MMU_601
:
1446 #if defined(TARGET_PPC64)
1447 case POWERPC_MMU_620
:
1448 case POWERPC_MMU_64B
:
1450 env
->exception_index
= POWERPC_EXCP_ISI
;
1451 env
->error_code
= 0x40000000;
1453 case POWERPC_MMU_BOOKE
:
1454 env
->exception_index
= POWERPC_EXCP_ITLB
;
1455 env
->error_code
= 0;
1456 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1458 case POWERPC_MMU_BOOKE_FSL
:
1460 cpu_abort(env
, "BookE FSL MMU model is not implemented\n");
1462 case POWERPC_MMU_MPC8xx
:
1464 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1466 case POWERPC_MMU_REAL
:
1467 cpu_abort(env
, "PowerPC in real mode should never raise "
1468 "any MMU exceptions\n");
1471 cpu_abort(env
, "Unknown or invalid MMU model\n");
1476 /* Access rights violation */
1477 env
->exception_index
= POWERPC_EXCP_ISI
;
1478 env
->error_code
= 0x08000000;
1481 /* No execute protection violation */
1482 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1483 env
->spr
[SPR_BOOKE_ESR
] = 0x00000000;
1485 env
->exception_index
= POWERPC_EXCP_ISI
;
1486 env
->error_code
= 0x10000000;
1489 /* Direct store exception */
1490 /* No code fetch is allowed in direct-store areas */
1491 env
->exception_index
= POWERPC_EXCP_ISI
;
1492 env
->error_code
= 0x10000000;
1494 #if defined(TARGET_PPC64)
1496 /* No match in segment table */
1497 if (env
->mmu_model
== POWERPC_MMU_620
) {
1498 env
->exception_index
= POWERPC_EXCP_ISI
;
1499 /* XXX: this might be incorrect */
1500 env
->error_code
= 0x40000000;
1502 env
->exception_index
= POWERPC_EXCP_ISEG
;
1503 env
->error_code
= 0;
1511 /* No matches in page tables or TLB */
1512 switch (env
->mmu_model
) {
1513 case POWERPC_MMU_SOFT_6xx
:
1515 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1516 env
->error_code
= 1 << 16;
1518 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1519 env
->error_code
= 0;
1521 env
->spr
[SPR_DMISS
] = address
;
1522 env
->spr
[SPR_DCMP
] = 0x80000000 | ctx
.ptem
;
1524 env
->error_code
|= ctx
.key
<< 19;
1525 env
->spr
[SPR_HASH1
] = ctx
.pg_addr
[0];
1526 env
->spr
[SPR_HASH2
] = ctx
.pg_addr
[1];
1528 case POWERPC_MMU_SOFT_74xx
:
1530 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1532 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1535 /* Implement LRU algorithm */
1536 env
->error_code
= ctx
.key
<< 19;
1537 env
->spr
[SPR_TLBMISS
] = (address
& ~((target_ulong
)0x3)) |
1538 ((env
->last_way
+ 1) & (env
->nb_ways
- 1));
1539 env
->spr
[SPR_PTEHI
] = 0x80000000 | ctx
.ptem
;
1541 case POWERPC_MMU_SOFT_4xx
:
1542 case POWERPC_MMU_SOFT_4xx_Z
:
1543 env
->exception_index
= POWERPC_EXCP_DTLB
;
1544 env
->error_code
= 0;
1545 env
->spr
[SPR_40x_DEAR
] = address
;
1547 env
->spr
[SPR_40x_ESR
] = 0x00800000;
1549 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1551 case POWERPC_MMU_32B
:
1552 case POWERPC_MMU_601
:
1553 #if defined(TARGET_PPC64)
1554 case POWERPC_MMU_620
:
1555 case POWERPC_MMU_64B
:
1557 env
->exception_index
= POWERPC_EXCP_DSI
;
1558 env
->error_code
= 0;
1559 env
->spr
[SPR_DAR
] = address
;
1561 env
->spr
[SPR_DSISR
] = 0x42000000;
1563 env
->spr
[SPR_DSISR
] = 0x40000000;
1565 case POWERPC_MMU_MPC8xx
:
1567 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1569 case POWERPC_MMU_BOOKE
:
1570 env
->exception_index
= POWERPC_EXCP_DTLB
;
1571 env
->error_code
= 0;
1572 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1573 env
->spr
[SPR_BOOKE_ESR
] = rw
? 1 << ESR_ST
: 0;
1575 case POWERPC_MMU_BOOKE_FSL
:
1577 cpu_abort(env
, "BookE FSL MMU model is not implemented\n");
1579 case POWERPC_MMU_REAL
:
1580 cpu_abort(env
, "PowerPC in real mode should never raise "
1581 "any MMU exceptions\n");
1584 cpu_abort(env
, "Unknown or invalid MMU model\n");
1589 /* Access rights violation */
1590 env
->exception_index
= POWERPC_EXCP_DSI
;
1591 env
->error_code
= 0;
1592 if (env
->mmu_model
== POWERPC_MMU_SOFT_4xx
1593 || env
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
) {
1594 env
->spr
[SPR_40x_DEAR
] = address
;
1596 env
->spr
[SPR_40x_ESR
] |= 0x00800000;
1598 } else if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1599 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1600 env
->spr
[SPR_BOOKE_ESR
] = rw
? 1 << ESR_ST
: 0;
1602 env
->spr
[SPR_DAR
] = address
;
1604 env
->spr
[SPR_DSISR
] = 0x0A000000;
1606 env
->spr
[SPR_DSISR
] = 0x08000000;
1611 /* Direct store exception */
1612 switch (access_type
) {
1614 /* Floating point load/store */
1615 env
->exception_index
= POWERPC_EXCP_ALIGN
;
1616 env
->error_code
= POWERPC_EXCP_ALIGN_FP
;
1617 env
->spr
[SPR_DAR
] = address
;
1620 /* lwarx, ldarx or stwcx. */
1621 env
->exception_index
= POWERPC_EXCP_DSI
;
1622 env
->error_code
= 0;
1623 env
->spr
[SPR_DAR
] = address
;
1625 env
->spr
[SPR_DSISR
] = 0x06000000;
1627 env
->spr
[SPR_DSISR
] = 0x04000000;
1630 /* eciwx or ecowx */
1631 env
->exception_index
= POWERPC_EXCP_DSI
;
1632 env
->error_code
= 0;
1633 env
->spr
[SPR_DAR
] = address
;
1635 env
->spr
[SPR_DSISR
] = 0x06100000;
1637 env
->spr
[SPR_DSISR
] = 0x04100000;
1640 printf("DSI: invalid exception (%d)\n", ret
);
1641 env
->exception_index
= POWERPC_EXCP_PROGRAM
;
1643 POWERPC_EXCP_INVAL
| POWERPC_EXCP_INVAL_INVAL
;
1644 env
->spr
[SPR_DAR
] = address
;
1648 #if defined(TARGET_PPC64)
1650 /* No match in segment table */
1651 if (env
->mmu_model
== POWERPC_MMU_620
) {
1652 env
->exception_index
= POWERPC_EXCP_DSI
;
1653 env
->error_code
= 0;
1654 env
->spr
[SPR_DAR
] = address
;
1655 /* XXX: this might be incorrect */
1657 env
->spr
[SPR_DSISR
] = 0x42000000;
1659 env
->spr
[SPR_DSISR
] = 0x40000000;
1661 env
->exception_index
= POWERPC_EXCP_DSEG
;
1662 env
->error_code
= 0;
1663 env
->spr
[SPR_DAR
] = address
;
1670 printf("%s: set exception to %d %02x\n", __func__
,
1671 env
->exception
, env
->error_code
);
1679 /*****************************************************************************/
1680 /* BATs management */
1681 #if !defined(FLUSH_ALL_TLBS)
1682 static inline void do_invalidate_BAT(CPUPPCState
*env
, target_ulong BATu
,
1685 target_ulong base
, end
, page
;
1687 base
= BATu
& ~0x0001FFFF;
1688 end
= base
+ mask
+ 0x00020000;
1689 LOG_BATS("Flush BAT from " TARGET_FMT_lx
" to " TARGET_FMT_lx
" ("
1690 TARGET_FMT_lx
")\n", base
, end
, mask
);
1691 for (page
= base
; page
!= end
; page
+= TARGET_PAGE_SIZE
)
1692 tlb_flush_page(env
, page
);
1693 LOG_BATS("Flush done\n");
1697 static inline void dump_store_bat(CPUPPCState
*env
, char ID
, int ul
, int nr
,
1700 LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx
" (" TARGET_FMT_lx
")\n", ID
,
1701 nr
, ul
== 0 ? 'u' : 'l', value
, env
->nip
);
1704 void ppc_store_ibatu (CPUPPCState
*env
, int nr
, target_ulong value
)
1708 dump_store_bat(env
, 'I', 0, nr
, value
);
1709 if (env
->IBAT
[0][nr
] != value
) {
1710 mask
= (value
<< 15) & 0x0FFE0000UL
;
1711 #if !defined(FLUSH_ALL_TLBS)
1712 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1714 /* When storing valid upper BAT, mask BEPI and BRPN
1715 * and invalidate all TLBs covered by this BAT
1717 mask
= (value
<< 15) & 0x0FFE0000UL
;
1718 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1719 (value
& ~0x0001FFFFUL
& ~mask
);
1720 env
->IBAT
[1][nr
] = (env
->IBAT
[1][nr
] & 0x0000007B) |
1721 (env
->IBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
1722 #if !defined(FLUSH_ALL_TLBS)
1723 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1730 void ppc_store_ibatl (CPUPPCState
*env
, int nr
, target_ulong value
)
1732 dump_store_bat(env
, 'I', 1, nr
, value
);
1733 env
->IBAT
[1][nr
] = value
;
1736 void ppc_store_dbatu (CPUPPCState
*env
, int nr
, target_ulong value
)
1740 dump_store_bat(env
, 'D', 0, nr
, value
);
1741 if (env
->DBAT
[0][nr
] != value
) {
1742 /* When storing valid upper BAT, mask BEPI and BRPN
1743 * and invalidate all TLBs covered by this BAT
1745 mask
= (value
<< 15) & 0x0FFE0000UL
;
1746 #if !defined(FLUSH_ALL_TLBS)
1747 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
1749 mask
= (value
<< 15) & 0x0FFE0000UL
;
1750 env
->DBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1751 (value
& ~0x0001FFFFUL
& ~mask
);
1752 env
->DBAT
[1][nr
] = (env
->DBAT
[1][nr
] & 0x0000007B) |
1753 (env
->DBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
1754 #if !defined(FLUSH_ALL_TLBS)
1755 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
1762 void ppc_store_dbatl (CPUPPCState
*env
, int nr
, target_ulong value
)
1764 dump_store_bat(env
, 'D', 1, nr
, value
);
1765 env
->DBAT
[1][nr
] = value
;
1768 void ppc_store_ibatu_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
1771 #if defined(FLUSH_ALL_TLBS)
1775 dump_store_bat(env
, 'I', 0, nr
, value
);
1776 if (env
->IBAT
[0][nr
] != value
) {
1777 #if defined(FLUSH_ALL_TLBS)
1780 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
1781 if (env
->IBAT
[1][nr
] & 0x40) {
1782 /* Invalidate BAT only if it is valid */
1783 #if !defined(FLUSH_ALL_TLBS)
1784 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1789 /* When storing valid upper BAT, mask BEPI and BRPN
1790 * and invalidate all TLBs covered by this BAT
1792 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1793 (value
& ~0x0001FFFFUL
& ~mask
);
1794 env
->DBAT
[0][nr
] = env
->IBAT
[0][nr
];
1795 if (env
->IBAT
[1][nr
] & 0x40) {
1796 #if !defined(FLUSH_ALL_TLBS)
1797 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1802 #if defined(FLUSH_ALL_TLBS)
1809 void ppc_store_ibatl_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
1812 #if defined(FLUSH_ALL_TLBS)
1816 dump_store_bat(env
, 'I', 1, nr
, value
);
1817 if (env
->IBAT
[1][nr
] != value
) {
1818 #if defined(FLUSH_ALL_TLBS)
1821 if (env
->IBAT
[1][nr
] & 0x40) {
1822 #if !defined(FLUSH_ALL_TLBS)
1823 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
1824 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1830 #if !defined(FLUSH_ALL_TLBS)
1831 mask
= (value
<< 17) & 0x0FFE0000UL
;
1832 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1837 env
->IBAT
[1][nr
] = value
;
1838 env
->DBAT
[1][nr
] = value
;
1839 #if defined(FLUSH_ALL_TLBS)
1846 /*****************************************************************************/
1847 /* TLB management */
1848 void ppc_tlb_invalidate_all (CPUPPCState
*env
)
1850 switch (env
->mmu_model
) {
1851 case POWERPC_MMU_SOFT_6xx
:
1852 case POWERPC_MMU_SOFT_74xx
:
1853 ppc6xx_tlb_invalidate_all(env
);
1855 case POWERPC_MMU_SOFT_4xx
:
1856 case POWERPC_MMU_SOFT_4xx_Z
:
1857 ppc4xx_tlb_invalidate_all(env
);
1859 case POWERPC_MMU_REAL
:
1860 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
1862 case POWERPC_MMU_MPC8xx
:
1864 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1866 case POWERPC_MMU_BOOKE
:
1869 case POWERPC_MMU_BOOKE_FSL
:
1872 cpu_abort(env
, "BookE MMU model is not implemented\n");
1874 case POWERPC_MMU_32B
:
1875 case POWERPC_MMU_601
:
1876 #if defined(TARGET_PPC64)
1877 case POWERPC_MMU_620
:
1878 case POWERPC_MMU_64B
:
1879 #endif /* defined(TARGET_PPC64) */
1884 cpu_abort(env
, "Unknown MMU model\n");
1889 void ppc_tlb_invalidate_one (CPUPPCState
*env
, target_ulong addr
)
1891 #if !defined(FLUSH_ALL_TLBS)
1892 addr
&= TARGET_PAGE_MASK
;
1893 switch (env
->mmu_model
) {
1894 case POWERPC_MMU_SOFT_6xx
:
1895 case POWERPC_MMU_SOFT_74xx
:
1896 ppc6xx_tlb_invalidate_virt(env
, addr
, 0);
1897 if (env
->id_tlbs
== 1)
1898 ppc6xx_tlb_invalidate_virt(env
, addr
, 1);
1900 case POWERPC_MMU_SOFT_4xx
:
1901 case POWERPC_MMU_SOFT_4xx_Z
:
1902 ppc4xx_tlb_invalidate_virt(env
, addr
, env
->spr
[SPR_40x_PID
]);
1904 case POWERPC_MMU_REAL
:
1905 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
1907 case POWERPC_MMU_MPC8xx
:
1909 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1911 case POWERPC_MMU_BOOKE
:
1913 cpu_abort(env
, "BookE MMU model is not implemented\n");
1915 case POWERPC_MMU_BOOKE_FSL
:
1917 cpu_abort(env
, "BookE FSL MMU model is not implemented\n");
1919 case POWERPC_MMU_32B
:
1920 case POWERPC_MMU_601
:
1921 /* tlbie invalidate TLBs for all segments */
1922 addr
&= ~((target_ulong
)-1ULL << 28);
1923 /* XXX: this case should be optimized,
1924 * giving a mask to tlb_flush_page
1926 tlb_flush_page(env
, addr
| (0x0 << 28));
1927 tlb_flush_page(env
, addr
| (0x1 << 28));
1928 tlb_flush_page(env
, addr
| (0x2 << 28));
1929 tlb_flush_page(env
, addr
| (0x3 << 28));
1930 tlb_flush_page(env
, addr
| (0x4 << 28));
1931 tlb_flush_page(env
, addr
| (0x5 << 28));
1932 tlb_flush_page(env
, addr
| (0x6 << 28));
1933 tlb_flush_page(env
, addr
| (0x7 << 28));
1934 tlb_flush_page(env
, addr
| (0x8 << 28));
1935 tlb_flush_page(env
, addr
| (0x9 << 28));
1936 tlb_flush_page(env
, addr
| (0xA << 28));
1937 tlb_flush_page(env
, addr
| (0xB << 28));
1938 tlb_flush_page(env
, addr
| (0xC << 28));
1939 tlb_flush_page(env
, addr
| (0xD << 28));
1940 tlb_flush_page(env
, addr
| (0xE << 28));
1941 tlb_flush_page(env
, addr
| (0xF << 28));
1943 #if defined(TARGET_PPC64)
1944 case POWERPC_MMU_620
:
1945 case POWERPC_MMU_64B
:
1946 /* tlbie invalidate TLBs for all segments */
1947 /* XXX: given the fact that there are too many segments to invalidate,
1948 * and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
1949 * we just invalidate all TLBs
1953 #endif /* defined(TARGET_PPC64) */
1956 cpu_abort(env
, "Unknown MMU model\n");
1960 ppc_tlb_invalidate_all(env
);
1964 /*****************************************************************************/
1965 /* Special registers manipulation */
1966 #if defined(TARGET_PPC64)
1967 void ppc_store_asr (CPUPPCState
*env
, target_ulong value
)
1969 if (env
->asr
!= value
) {
1976 void ppc_store_sdr1 (CPUPPCState
*env
, target_ulong value
)
1978 LOG_MMU("%s: " TARGET_FMT_lx
"\n", __func__
, value
);
1979 if (env
->sdr1
!= value
) {
1980 /* XXX: for PowerPC 64, should check that the HTABSIZE value
1988 #if defined(TARGET_PPC64)
1989 target_ulong
ppc_load_sr (CPUPPCState
*env
, int slb_nr
)
1996 void ppc_store_sr (CPUPPCState
*env
, int srnum
, target_ulong value
)
1998 LOG_MMU("%s: reg=%d " TARGET_FMT_lx
" " TARGET_FMT_lx
"\n", __func__
,
1999 srnum
, value
, env
->sr
[srnum
]);
2000 #if defined(TARGET_PPC64)
2001 if (env
->mmu_model
& POWERPC_MMU_64
) {
2002 uint64_t rb
= 0, rs
= 0;
2005 rb
|= ((uint32_t)srnum
& 0xf) << 28;
2006 /* Set the valid bit */
2009 rb
|= (uint32_t)srnum
;
2012 rs
|= (value
& 0xfffffff) << 12;
2014 rs
|= ((value
>> 27) & 0xf) << 9;
2016 ppc_store_slb(env
, rb
, rs
);
2019 if (env
->sr
[srnum
] != value
) {
2020 env
->sr
[srnum
] = value
;
2021 /* Invalidating 256MB of virtual memory in 4kB pages is way longer than
2022 flusing the whole TLB. */
2023 #if !defined(FLUSH_ALL_TLBS) && 0
2025 target_ulong page
, end
;
2026 /* Invalidate 256 MB of virtual memory */
2027 page
= (16 << 20) * srnum
;
2028 end
= page
+ (16 << 20);
2029 for (; page
!= end
; page
+= TARGET_PAGE_SIZE
)
2030 tlb_flush_page(env
, page
);
2037 #endif /* !defined (CONFIG_USER_ONLY) */
2039 /* GDBstub can read and write MSR... */
2040 void ppc_store_msr (CPUPPCState
*env
, target_ulong value
)
2042 hreg_store_msr(env
, value
, 0);
2045 /*****************************************************************************/
2046 /* Exception processing */
2047 #if defined (CONFIG_USER_ONLY)
2048 void do_interrupt (CPUState
*env
)
2050 env
->exception_index
= POWERPC_EXCP_NONE
;
2051 env
->error_code
= 0;
2054 void ppc_hw_interrupt (CPUState
*env
)
2056 env
->exception_index
= POWERPC_EXCP_NONE
;
2057 env
->error_code
= 0;
2059 #else /* defined (CONFIG_USER_ONLY) */
2060 static inline void dump_syscall(CPUState
*env
)
2062 qemu_log_mask(CPU_LOG_INT
, "syscall r0=%016" PRIx64
" r3=%016" PRIx64
2063 " r4=%016" PRIx64
" r5=%016" PRIx64
" r6=%016" PRIx64
2064 " nip=" TARGET_FMT_lx
"\n",
2065 ppc_dump_gpr(env
, 0), ppc_dump_gpr(env
, 3),
2066 ppc_dump_gpr(env
, 4), ppc_dump_gpr(env
, 5),
2067 ppc_dump_gpr(env
, 6), env
->nip
);
2070 /* Note that this function should be greatly optimized
2071 * when called with a constant excp, from ppc_hw_interrupt
2073 static inline void powerpc_excp(CPUState
*env
, int excp_model
, int excp
)
2075 target_ulong msr
, new_msr
, vector
;
2076 int srr0
, srr1
, asrr0
, asrr1
;
2077 int lpes0
, lpes1
, lev
;
2080 /* XXX: find a suitable condition to enable the hypervisor mode */
2081 lpes0
= (env
->spr
[SPR_LPCR
] >> 1) & 1;
2082 lpes1
= (env
->spr
[SPR_LPCR
] >> 2) & 1;
2084 /* Those values ensure we won't enter the hypervisor mode */
2089 qemu_log_mask(CPU_LOG_INT
, "Raise exception at " TARGET_FMT_lx
2090 " => %08x (%02x)\n", env
->nip
, excp
, env
->error_code
);
2092 /* new srr1 value excluding must-be-zero bits */
2093 msr
= env
->msr
& ~0x783f0000ULL
;
2095 /* new interrupt handler msr */
2096 new_msr
= env
->msr
& ((target_ulong
)1 << MSR_ME
);
2098 /* target registers */
2105 case POWERPC_EXCP_NONE
:
2106 /* Should never happen */
2108 case POWERPC_EXCP_CRITICAL
: /* Critical input */
2109 switch (excp_model
) {
2110 case POWERPC_EXCP_40x
:
2111 srr0
= SPR_40x_SRR2
;
2112 srr1
= SPR_40x_SRR3
;
2114 case POWERPC_EXCP_BOOKE
:
2115 srr0
= SPR_BOOKE_CSRR0
;
2116 srr1
= SPR_BOOKE_CSRR1
;
2118 case POWERPC_EXCP_G2
:
2124 case POWERPC_EXCP_MCHECK
: /* Machine check exception */
2126 /* Machine check exception is not enabled.
2127 * Enter checkstop state.
2129 if (qemu_log_enabled()) {
2130 qemu_log("Machine check while not allowed. "
2131 "Entering checkstop state\n");
2133 fprintf(stderr
, "Machine check while not allowed. "
2134 "Entering checkstop state\n");
2137 env
->interrupt_request
|= CPU_INTERRUPT_EXITTB
;
2140 /* XXX: find a suitable condition to enable the hypervisor mode */
2141 new_msr
|= (target_ulong
)MSR_HVB
;
2144 /* machine check exceptions don't have ME set */
2145 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2147 /* XXX: should also have something loaded in DAR / DSISR */
2148 switch (excp_model
) {
2149 case POWERPC_EXCP_40x
:
2150 srr0
= SPR_40x_SRR2
;
2151 srr1
= SPR_40x_SRR3
;
2153 case POWERPC_EXCP_BOOKE
:
2154 srr0
= SPR_BOOKE_MCSRR0
;
2155 srr1
= SPR_BOOKE_MCSRR1
;
2156 asrr0
= SPR_BOOKE_CSRR0
;
2157 asrr1
= SPR_BOOKE_CSRR1
;
2163 case POWERPC_EXCP_DSI
: /* Data storage exception */
2164 LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx
" DAR=" TARGET_FMT_lx
2165 "\n", env
->spr
[SPR_DSISR
], env
->spr
[SPR_DAR
]);
2167 new_msr
|= (target_ulong
)MSR_HVB
;
2169 case POWERPC_EXCP_ISI
: /* Instruction storage exception */
2170 LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx
", nip=" TARGET_FMT_lx
2171 "\n", msr
, env
->nip
);
2173 new_msr
|= (target_ulong
)MSR_HVB
;
2174 msr
|= env
->error_code
;
2176 case POWERPC_EXCP_EXTERNAL
: /* External input */
2178 new_msr
|= (target_ulong
)MSR_HVB
;
2180 case POWERPC_EXCP_ALIGN
: /* Alignment exception */
2182 new_msr
|= (target_ulong
)MSR_HVB
;
2183 /* XXX: this is false */
2184 /* Get rS/rD and rA from faulting opcode */
2185 env
->spr
[SPR_DSISR
] |= (ldl_code((env
->nip
- 4)) & 0x03FF0000) >> 16;
2187 case POWERPC_EXCP_PROGRAM
: /* Program exception */
2188 switch (env
->error_code
& ~0xF) {
2189 case POWERPC_EXCP_FP
:
2190 if ((msr_fe0
== 0 && msr_fe1
== 0) || msr_fp
== 0) {
2191 LOG_EXCP("Ignore floating point exception\n");
2192 env
->exception_index
= POWERPC_EXCP_NONE
;
2193 env
->error_code
= 0;
2197 new_msr
|= (target_ulong
)MSR_HVB
;
2199 if (msr_fe0
== msr_fe1
)
2203 case POWERPC_EXCP_INVAL
:
2204 LOG_EXCP("Invalid instruction at " TARGET_FMT_lx
"\n", env
->nip
);
2206 new_msr
|= (target_ulong
)MSR_HVB
;
2209 case POWERPC_EXCP_PRIV
:
2211 new_msr
|= (target_ulong
)MSR_HVB
;
2214 case POWERPC_EXCP_TRAP
:
2216 new_msr
|= (target_ulong
)MSR_HVB
;
2220 /* Should never occur */
2221 cpu_abort(env
, "Invalid program exception %d. Aborting\n",
2226 case POWERPC_EXCP_FPU
: /* Floating-point unavailable exception */
2228 new_msr
|= (target_ulong
)MSR_HVB
;
2230 case POWERPC_EXCP_SYSCALL
: /* System call exception */
2231 /* NOTE: this is a temporary hack to support graphics OSI
2232 calls from the MOL driver */
2233 /* XXX: To be removed */
2234 if (env
->gpr
[3] == 0x113724fa && env
->gpr
[4] == 0x77810f9b &&
2236 if (env
->osi_call(env
) != 0) {
2237 env
->exception_index
= POWERPC_EXCP_NONE
;
2238 env
->error_code
= 0;
2243 lev
= env
->error_code
;
2244 if (lev
== 1 || (lpes0
== 0 && lpes1
== 0))
2245 new_msr
|= (target_ulong
)MSR_HVB
;
2247 case POWERPC_EXCP_APU
: /* Auxiliary processor unavailable */
2249 case POWERPC_EXCP_DECR
: /* Decrementer exception */
2251 new_msr
|= (target_ulong
)MSR_HVB
;
2253 case POWERPC_EXCP_FIT
: /* Fixed-interval timer interrupt */
2255 LOG_EXCP("FIT exception\n");
2257 case POWERPC_EXCP_WDT
: /* Watchdog timer interrupt */
2258 LOG_EXCP("WDT exception\n");
2259 switch (excp_model
) {
2260 case POWERPC_EXCP_BOOKE
:
2261 srr0
= SPR_BOOKE_CSRR0
;
2262 srr1
= SPR_BOOKE_CSRR1
;
2268 case POWERPC_EXCP_DTLB
: /* Data TLB error */
2270 case POWERPC_EXCP_ITLB
: /* Instruction TLB error */
2272 case POWERPC_EXCP_DEBUG
: /* Debug interrupt */
2273 switch (excp_model
) {
2274 case POWERPC_EXCP_BOOKE
:
2275 srr0
= SPR_BOOKE_DSRR0
;
2276 srr1
= SPR_BOOKE_DSRR1
;
2277 asrr0
= SPR_BOOKE_CSRR0
;
2278 asrr1
= SPR_BOOKE_CSRR1
;
2284 cpu_abort(env
, "Debug exception is not implemented yet !\n");
2286 case POWERPC_EXCP_SPEU
: /* SPE/embedded floating-point unavailable */
2288 case POWERPC_EXCP_EFPDI
: /* Embedded floating-point data interrupt */
2290 cpu_abort(env
, "Embedded floating point data exception "
2291 "is not implemented yet !\n");
2293 case POWERPC_EXCP_EFPRI
: /* Embedded floating-point round interrupt */
2295 cpu_abort(env
, "Embedded floating point round exception "
2296 "is not implemented yet !\n");
2298 case POWERPC_EXCP_EPERFM
: /* Embedded performance monitor interrupt */
2301 "Performance counter exception is not implemented yet !\n");
2303 case POWERPC_EXCP_DOORI
: /* Embedded doorbell interrupt */
2306 "Embedded doorbell interrupt is not implemented yet !\n");
2308 case POWERPC_EXCP_DOORCI
: /* Embedded doorbell critical interrupt */
2309 switch (excp_model
) {
2310 case POWERPC_EXCP_BOOKE
:
2311 srr0
= SPR_BOOKE_CSRR0
;
2312 srr1
= SPR_BOOKE_CSRR1
;
2318 cpu_abort(env
, "Embedded doorbell critical interrupt "
2319 "is not implemented yet !\n");
2321 case POWERPC_EXCP_RESET
: /* System reset exception */
2323 /* indicate that we resumed from power save mode */
2326 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2330 /* XXX: find a suitable condition to enable the hypervisor mode */
2331 new_msr
|= (target_ulong
)MSR_HVB
;
2334 case POWERPC_EXCP_DSEG
: /* Data segment exception */
2336 new_msr
|= (target_ulong
)MSR_HVB
;
2338 case POWERPC_EXCP_ISEG
: /* Instruction segment exception */
2340 new_msr
|= (target_ulong
)MSR_HVB
;
2342 case POWERPC_EXCP_HDECR
: /* Hypervisor decrementer exception */
2345 new_msr
|= (target_ulong
)MSR_HVB
;
2346 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2348 case POWERPC_EXCP_TRACE
: /* Trace exception */
2350 new_msr
|= (target_ulong
)MSR_HVB
;
2352 case POWERPC_EXCP_HDSI
: /* Hypervisor data storage exception */
2355 new_msr
|= (target_ulong
)MSR_HVB
;
2356 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2358 case POWERPC_EXCP_HISI
: /* Hypervisor instruction storage exception */
2361 new_msr
|= (target_ulong
)MSR_HVB
;
2362 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2364 case POWERPC_EXCP_HDSEG
: /* Hypervisor data segment exception */
2367 new_msr
|= (target_ulong
)MSR_HVB
;
2368 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2370 case POWERPC_EXCP_HISEG
: /* Hypervisor instruction segment exception */
2373 new_msr
|= (target_ulong
)MSR_HVB
;
2374 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2376 case POWERPC_EXCP_VPU
: /* Vector unavailable exception */
2378 new_msr
|= (target_ulong
)MSR_HVB
;
2380 case POWERPC_EXCP_PIT
: /* Programmable interval timer interrupt */
2381 LOG_EXCP("PIT exception\n");
2383 case POWERPC_EXCP_IO
: /* IO error exception */
2385 cpu_abort(env
, "601 IO error exception is not implemented yet !\n");
2387 case POWERPC_EXCP_RUNM
: /* Run mode exception */
2389 cpu_abort(env
, "601 run mode exception is not implemented yet !\n");
2391 case POWERPC_EXCP_EMUL
: /* Emulation trap exception */
2393 cpu_abort(env
, "602 emulation trap exception "
2394 "is not implemented yet !\n");
2396 case POWERPC_EXCP_IFTLB
: /* Instruction fetch TLB error */
2397 if (lpes1
== 0) /* XXX: check this */
2398 new_msr
|= (target_ulong
)MSR_HVB
;
2399 switch (excp_model
) {
2400 case POWERPC_EXCP_602
:
2401 case POWERPC_EXCP_603
:
2402 case POWERPC_EXCP_603E
:
2403 case POWERPC_EXCP_G2
:
2405 case POWERPC_EXCP_7x5
:
2407 case POWERPC_EXCP_74xx
:
2410 cpu_abort(env
, "Invalid instruction TLB miss exception\n");
2414 case POWERPC_EXCP_DLTLB
: /* Data load TLB miss */
2415 if (lpes1
== 0) /* XXX: check this */
2416 new_msr
|= (target_ulong
)MSR_HVB
;
2417 switch (excp_model
) {
2418 case POWERPC_EXCP_602
:
2419 case POWERPC_EXCP_603
:
2420 case POWERPC_EXCP_603E
:
2421 case POWERPC_EXCP_G2
:
2423 case POWERPC_EXCP_7x5
:
2425 case POWERPC_EXCP_74xx
:
2428 cpu_abort(env
, "Invalid data load TLB miss exception\n");
2432 case POWERPC_EXCP_DSTLB
: /* Data store TLB miss */
2433 if (lpes1
== 0) /* XXX: check this */
2434 new_msr
|= (target_ulong
)MSR_HVB
;
2435 switch (excp_model
) {
2436 case POWERPC_EXCP_602
:
2437 case POWERPC_EXCP_603
:
2438 case POWERPC_EXCP_603E
:
2439 case POWERPC_EXCP_G2
:
2441 /* Swap temporary saved registers with GPRs */
2442 if (!(new_msr
& ((target_ulong
)1 << MSR_TGPR
))) {
2443 new_msr
|= (target_ulong
)1 << MSR_TGPR
;
2444 hreg_swap_gpr_tgpr(env
);
2447 case POWERPC_EXCP_7x5
:
2449 #if defined (DEBUG_SOFTWARE_TLB)
2450 if (qemu_log_enabled()) {
2452 target_ulong
*miss
, *cmp
;
2454 if (excp
== POWERPC_EXCP_IFTLB
) {
2457 miss
= &env
->spr
[SPR_IMISS
];
2458 cmp
= &env
->spr
[SPR_ICMP
];
2460 if (excp
== POWERPC_EXCP_DLTLB
)
2465 miss
= &env
->spr
[SPR_DMISS
];
2466 cmp
= &env
->spr
[SPR_DCMP
];
2468 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2469 TARGET_FMT_lx
" H1 " TARGET_FMT_lx
" H2 "
2470 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2471 env
->spr
[SPR_HASH1
], env
->spr
[SPR_HASH2
],
2475 msr
|= env
->crf
[0] << 28;
2476 msr
|= env
->error_code
; /* key, D/I, S/L bits */
2477 /* Set way using a LRU mechanism */
2478 msr
|= ((env
->last_way
+ 1) & (env
->nb_ways
- 1)) << 17;
2480 case POWERPC_EXCP_74xx
:
2482 #if defined (DEBUG_SOFTWARE_TLB)
2483 if (qemu_log_enabled()) {
2485 target_ulong
*miss
, *cmp
;
2487 if (excp
== POWERPC_EXCP_IFTLB
) {
2490 miss
= &env
->spr
[SPR_TLBMISS
];
2491 cmp
= &env
->spr
[SPR_PTEHI
];
2493 if (excp
== POWERPC_EXCP_DLTLB
)
2498 miss
= &env
->spr
[SPR_TLBMISS
];
2499 cmp
= &env
->spr
[SPR_PTEHI
];
2501 qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2502 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2506 msr
|= env
->error_code
; /* key bit */
2509 cpu_abort(env
, "Invalid data store TLB miss exception\n");
2513 case POWERPC_EXCP_FPA
: /* Floating-point assist exception */
2515 cpu_abort(env
, "Floating point assist exception "
2516 "is not implemented yet !\n");
2518 case POWERPC_EXCP_DABR
: /* Data address breakpoint */
2520 cpu_abort(env
, "DABR exception is not implemented yet !\n");
2522 case POWERPC_EXCP_IABR
: /* Instruction address breakpoint */
2524 cpu_abort(env
, "IABR exception is not implemented yet !\n");
2526 case POWERPC_EXCP_SMI
: /* System management interrupt */
2528 cpu_abort(env
, "SMI exception is not implemented yet !\n");
2530 case POWERPC_EXCP_THERM
: /* Thermal interrupt */
2532 cpu_abort(env
, "Thermal management exception "
2533 "is not implemented yet !\n");
2535 case POWERPC_EXCP_PERFM
: /* Embedded performance monitor interrupt */
2537 new_msr
|= (target_ulong
)MSR_HVB
;
2540 "Performance counter exception is not implemented yet !\n");
2542 case POWERPC_EXCP_VPUA
: /* Vector assist exception */
2544 cpu_abort(env
, "VPU assist exception is not implemented yet !\n");
2546 case POWERPC_EXCP_SOFTP
: /* Soft patch exception */
2549 "970 soft-patch exception is not implemented yet !\n");
2551 case POWERPC_EXCP_MAINT
: /* Maintenance exception */
2554 "970 maintenance exception is not implemented yet !\n");
2556 case POWERPC_EXCP_MEXTBR
: /* Maskable external breakpoint */
2558 cpu_abort(env
, "Maskable external exception "
2559 "is not implemented yet !\n");
2561 case POWERPC_EXCP_NMEXTBR
: /* Non maskable external breakpoint */
2563 cpu_abort(env
, "Non maskable external exception "
2564 "is not implemented yet !\n");
2568 cpu_abort(env
, "Invalid PowerPC exception %d. Aborting\n", excp
);
2571 /* save current instruction location */
2572 env
->spr
[srr0
] = env
->nip
- 4;
2575 /* save next instruction location */
2576 env
->spr
[srr0
] = env
->nip
;
2580 env
->spr
[srr1
] = msr
;
2581 /* If any alternate SRR register are defined, duplicate saved values */
2583 env
->spr
[asrr0
] = env
->spr
[srr0
];
2585 env
->spr
[asrr1
] = env
->spr
[srr1
];
2586 /* If we disactivated any translation, flush TLBs */
2587 if (new_msr
& ((1 << MSR_IR
) | (1 << MSR_DR
)))
2591 new_msr
|= (target_ulong
)1 << MSR_LE
;
2594 /* Jump to handler */
2595 vector
= env
->excp_vectors
[excp
];
2596 if (vector
== (target_ulong
)-1ULL) {
2597 cpu_abort(env
, "Raised an exception without defined vector %d\n",
2600 vector
|= env
->excp_prefix
;
2601 #if defined(TARGET_PPC64)
2602 if (excp_model
== POWERPC_EXCP_BOOKE
) {
2604 vector
= (uint32_t)vector
;
2606 new_msr
|= (target_ulong
)1 << MSR_CM
;
2609 if (!msr_isf
&& !(env
->mmu_model
& POWERPC_MMU_64
)) {
2610 vector
= (uint32_t)vector
;
2612 new_msr
|= (target_ulong
)1 << MSR_SF
;
2616 /* XXX: we don't use hreg_store_msr here as already have treated
2617 * any special case that could occur. Just store MSR and update hflags
2619 env
->msr
= new_msr
& env
->msr_mask
;
2620 hreg_compute_hflags(env
);
2622 /* Reset exception state */
2623 env
->exception_index
= POWERPC_EXCP_NONE
;
2624 env
->error_code
= 0;
2626 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
2627 /* XXX: The BookE changes address space when switching modes,
2628 we should probably implement that as different MMU indexes,
2629 but for the moment we do it the slow way and flush all. */
2634 void do_interrupt (CPUState
*env
)
2636 powerpc_excp(env
, env
->excp_model
, env
->exception_index
);
2639 void ppc_hw_interrupt (CPUPPCState
*env
)
2644 qemu_log_mask(CPU_LOG_INT
, "%s: %p pending %08x req %08x me %d ee %d\n",
2645 __func__
, env
, env
->pending_interrupts
,
2646 env
->interrupt_request
, (int)msr_me
, (int)msr_ee
);
2648 /* External reset */
2649 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_RESET
)) {
2650 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_RESET
);
2651 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_RESET
);
2654 /* Machine check exception */
2655 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_MCK
)) {
2656 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_MCK
);
2657 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_MCHECK
);
2661 /* External debug exception */
2662 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DEBUG
)) {
2663 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DEBUG
);
2664 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DEBUG
);
2669 /* XXX: find a suitable condition to enable the hypervisor mode */
2670 hdice
= env
->spr
[SPR_LPCR
] & 1;
2674 if ((msr_ee
!= 0 || msr_hv
== 0 || msr_pr
!= 0) && hdice
!= 0) {
2675 /* Hypervisor decrementer exception */
2676 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_HDECR
)) {
2677 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_HDECR
);
2678 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_HDECR
);
2683 /* External critical interrupt */
2684 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CEXT
)) {
2685 /* Taking a critical external interrupt does not clear the external
2686 * critical interrupt status
2689 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CEXT
);
2691 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_CRITICAL
);
2696 /* Watchdog timer on embedded PowerPC */
2697 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_WDT
)) {
2698 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_WDT
);
2699 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_WDT
);
2702 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CDOORBELL
)) {
2703 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CDOORBELL
);
2704 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORCI
);
2707 /* Fixed interval timer on embedded PowerPC */
2708 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_FIT
)) {
2709 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_FIT
);
2710 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_FIT
);
2713 /* Programmable interval timer on embedded PowerPC */
2714 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PIT
)) {
2715 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PIT
);
2716 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PIT
);
2719 /* Decrementer exception */
2720 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DECR
)) {
2721 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DECR
);
2722 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DECR
);
2725 /* External interrupt */
2726 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_EXT
)) {
2727 /* Taking an external interrupt does not clear the external
2731 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_EXT
);
2733 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_EXTERNAL
);
2736 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DOORBELL
)) {
2737 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DOORBELL
);
2738 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORI
);
2741 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PERFM
)) {
2742 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PERFM
);
2743 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PERFM
);
2746 /* Thermal interrupt */
2747 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_THERM
)) {
2748 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_THERM
);
2749 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_THERM
);
2754 #endif /* !CONFIG_USER_ONLY */
2756 void cpu_dump_rfi (target_ulong RA
, target_ulong msr
)
2758 qemu_log("Return from exception at " TARGET_FMT_lx
" with flags "
2759 TARGET_FMT_lx
"\n", RA
, msr
);
2762 void cpu_reset(CPUPPCState
*env
)
2766 if (qemu_loglevel_mask(CPU_LOG_RESET
)) {
2767 qemu_log("CPU Reset (CPU %d)\n", env
->cpu_index
);
2768 log_cpu_state(env
, 0);
2771 msr
= (target_ulong
)0;
2773 /* XXX: find a suitable condition to enable the hypervisor mode */
2774 msr
|= (target_ulong
)MSR_HVB
;
2776 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
2777 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
2778 msr
|= (target_ulong
)1 << MSR_EP
;
2779 #if defined (DO_SINGLE_STEP) && 0
2780 /* Single step trace mode */
2781 msr
|= (target_ulong
)1 << MSR_SE
;
2782 msr
|= (target_ulong
)1 << MSR_BE
;
2784 #if defined(CONFIG_USER_ONLY)
2785 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
2786 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
2787 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
2788 msr
|= (target_ulong
)1 << MSR_PR
;
2790 env
->excp_prefix
= env
->hreset_excp_prefix
;
2791 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
2792 if (env
->mmu_model
!= POWERPC_MMU_REAL
)
2793 ppc_tlb_invalidate_all(env
);
2795 env
->msr
= msr
& env
->msr_mask
;
2796 #if defined(TARGET_PPC64)
2797 if (env
->mmu_model
& POWERPC_MMU_64
)
2798 env
->msr
|= (1ULL << MSR_SF
);
2800 hreg_compute_hflags(env
);
2801 env
->reserve_addr
= (target_ulong
)-1ULL;
2802 /* Be sure no exception or interrupt is pending */
2803 env
->pending_interrupts
= 0;
2804 env
->exception_index
= POWERPC_EXCP_NONE
;
2805 env
->error_code
= 0;
2806 /* Flush all TLBs */
2810 CPUPPCState
*cpu_ppc_init (const char *cpu_model
)
2813 const ppc_def_t
*def
;
2815 def
= cpu_ppc_find_by_name(cpu_model
);
2819 env
= qemu_mallocz(sizeof(CPUPPCState
));
2821 ppc_translate_init();
2822 env
->cpu_model_str
= cpu_model
;
2823 cpu_ppc_register_internal(env
, def
);
2825 qemu_init_vcpu(env
);
2830 void cpu_ppc_close (CPUPPCState
*env
)
2832 /* Should also remove all opcode tables... */