2 * PowerPC emulation helpers for qemu.
4 * Copyright (c) 2003-2007 Jocelyn Mayer
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
28 #include "helper_regs.h"
29 #include "qemu-common.h"
35 //#define DEBUG_SOFTWARE_TLB
36 //#define DUMP_PAGE_TABLES
37 //#define DEBUG_EXCEPTIONS
38 //#define FLUSH_ALL_TLBS
41 # define LOG_MMU(...) qemu_log(__VA_ARGS__)
42 # define LOG_MMU_STATE(env) log_cpu_state((env), 0)
44 # define LOG_MMU(...) do { } while (0)
45 # define LOG_MMU_STATE(...) do { } while (0)
49 #ifdef DEBUG_SOFTWARE_TLB
50 # define LOG_SWTLB(...) qemu_log(__VA_ARGS__)
52 # define LOG_SWTLB(...) do { } while (0)
56 # define LOG_BATS(...) qemu_log(__VA_ARGS__)
58 # define LOG_BATS(...) do { } while (0)
62 # define LOG_SLB(...) qemu_log(__VA_ARGS__)
64 # define LOG_SLB(...) do { } while (0)
67 #ifdef DEBUG_EXCEPTIONS
68 # define LOG_EXCP(...) qemu_log(__VA_ARGS__)
70 # define LOG_EXCP(...) do { } while (0)
73 /*****************************************************************************/
74 /* PowerPC Hypercall emulation */
76 void (*cpu_ppc_hypercall
)(CPUState
*);
78 /*****************************************************************************/
79 /* PowerPC MMU emulation */
81 #if defined(CONFIG_USER_ONLY)
82 int cpu_ppc_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
83 int mmu_idx
, int is_softmmu
)
85 int exception
, error_code
;
88 exception
= POWERPC_EXCP_ISI
;
89 error_code
= 0x40000000;
91 exception
= POWERPC_EXCP_DSI
;
92 error_code
= 0x40000000;
94 error_code
|= 0x02000000;
95 env
->spr
[SPR_DAR
] = address
;
96 env
->spr
[SPR_DSISR
] = error_code
;
98 env
->exception_index
= exception
;
99 env
->error_code
= error_code
;
105 /* Common routines used by software and hardware TLBs emulation */
106 static inline int pte_is_valid(target_ulong pte0
)
108 return pte0
& 0x80000000 ? 1 : 0;
111 static inline void pte_invalidate(target_ulong
*pte0
)
113 *pte0
&= ~0x80000000;
116 #if defined(TARGET_PPC64)
117 static inline int pte64_is_valid(target_ulong pte0
)
119 return pte0
& 0x0000000000000001ULL
? 1 : 0;
122 static inline void pte64_invalidate(target_ulong
*pte0
)
124 *pte0
&= ~0x0000000000000001ULL
;
128 #define PTE_PTEM_MASK 0x7FFFFFBF
129 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
130 #if defined(TARGET_PPC64)
131 #define PTE64_PTEM_MASK 0xFFFFFFFFFFFFFF80ULL
132 #define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F)
135 static inline int pp_check(int key
, int pp
, int nx
)
139 /* Compute access rights */
140 /* When pp is 3/7, the result is undefined. Set it to noaccess */
147 access
|= PAGE_WRITE
;
165 access
= PAGE_READ
| PAGE_WRITE
;
175 static inline int check_prot(int prot
, int rw
, int access_type
)
179 if (access_type
== ACCESS_CODE
) {
180 if (prot
& PAGE_EXEC
)
185 if (prot
& PAGE_WRITE
)
190 if (prot
& PAGE_READ
)
199 static inline int _pte_check(mmu_ctx_t
*ctx
, int is_64b
, target_ulong pte0
,
200 target_ulong pte1
, int h
, int rw
, int type
)
202 target_ulong ptem
, mmask
;
203 int access
, ret
, pteh
, ptev
, pp
;
206 /* Check validity and table match */
207 #if defined(TARGET_PPC64)
209 ptev
= pte64_is_valid(pte0
);
210 pteh
= (pte0
>> 1) & 1;
214 ptev
= pte_is_valid(pte0
);
215 pteh
= (pte0
>> 6) & 1;
217 if (ptev
&& h
== pteh
) {
218 /* Check vsid & api */
219 #if defined(TARGET_PPC64)
221 ptem
= pte0
& PTE64_PTEM_MASK
;
222 mmask
= PTE64_CHECK_MASK
;
223 pp
= (pte1
& 0x00000003) | ((pte1
>> 61) & 0x00000004);
224 ctx
->nx
= (pte1
>> 2) & 1; /* No execute bit */
225 ctx
->nx
|= (pte1
>> 3) & 1; /* Guarded bit */
229 ptem
= pte0
& PTE_PTEM_MASK
;
230 mmask
= PTE_CHECK_MASK
;
231 pp
= pte1
& 0x00000003;
233 if (ptem
== ctx
->ptem
) {
234 if (ctx
->raddr
!= (target_phys_addr_t
)-1ULL) {
235 /* all matches should have equal RPN, WIMG & PP */
236 if ((ctx
->raddr
& mmask
) != (pte1
& mmask
)) {
237 qemu_log("Bad RPN/WIMG/PP\n");
241 /* Compute access rights */
242 access
= pp_check(ctx
->key
, pp
, ctx
->nx
);
243 /* Keep the matching PTE informations */
246 ret
= check_prot(ctx
->prot
, rw
, type
);
249 LOG_MMU("PTE access granted !\n");
251 /* Access right violation */
252 LOG_MMU("PTE access rejected\n");
260 static inline int pte32_check(mmu_ctx_t
*ctx
, target_ulong pte0
,
261 target_ulong pte1
, int h
, int rw
, int type
)
263 return _pte_check(ctx
, 0, pte0
, pte1
, h
, rw
, type
);
266 #if defined(TARGET_PPC64)
267 static inline int pte64_check(mmu_ctx_t
*ctx
, target_ulong pte0
,
268 target_ulong pte1
, int h
, int rw
, int type
)
270 return _pte_check(ctx
, 1, pte0
, pte1
, h
, rw
, type
);
274 static inline int pte_update_flags(mmu_ctx_t
*ctx
, target_ulong
*pte1p
,
279 /* Update page flags */
280 if (!(*pte1p
& 0x00000100)) {
281 /* Update accessed flag */
282 *pte1p
|= 0x00000100;
285 if (!(*pte1p
& 0x00000080)) {
286 if (rw
== 1 && ret
== 0) {
287 /* Update changed flag */
288 *pte1p
|= 0x00000080;
291 /* Force page fault for first write access */
292 ctx
->prot
&= ~PAGE_WRITE
;
299 /* Software driven TLB helpers */
300 static inline int ppc6xx_tlb_getnum(CPUState
*env
, target_ulong eaddr
, int way
,
305 /* Select TLB num in a way from address */
306 nr
= (eaddr
>> TARGET_PAGE_BITS
) & (env
->tlb_per_way
- 1);
308 nr
+= env
->tlb_per_way
* way
;
309 /* 6xx have separate TLBs for instructions and data */
310 if (is_code
&& env
->id_tlbs
== 1)
316 static inline void ppc6xx_tlb_invalidate_all(CPUState
*env
)
321 //LOG_SWTLB("Invalidate all TLBs\n");
322 /* Invalidate all defined software TLB */
324 if (env
->id_tlbs
== 1)
326 for (nr
= 0; nr
< max
; nr
++) {
327 tlb
= &env
->tlb
[nr
].tlb6
;
328 pte_invalidate(&tlb
->pte0
);
333 static inline void __ppc6xx_tlb_invalidate_virt(CPUState
*env
,
335 int is_code
, int match_epn
)
337 #if !defined(FLUSH_ALL_TLBS)
341 /* Invalidate ITLB + DTLB, all ways */
342 for (way
= 0; way
< env
->nb_ways
; way
++) {
343 nr
= ppc6xx_tlb_getnum(env
, eaddr
, way
, is_code
);
344 tlb
= &env
->tlb
[nr
].tlb6
;
345 if (pte_is_valid(tlb
->pte0
) && (match_epn
== 0 || eaddr
== tlb
->EPN
)) {
346 LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx
"\n", nr
,
348 pte_invalidate(&tlb
->pte0
);
349 tlb_flush_page(env
, tlb
->EPN
);
353 /* XXX: PowerPC specification say this is valid as well */
354 ppc6xx_tlb_invalidate_all(env
);
358 static inline void ppc6xx_tlb_invalidate_virt(CPUState
*env
,
359 target_ulong eaddr
, int is_code
)
361 __ppc6xx_tlb_invalidate_virt(env
, eaddr
, is_code
, 0);
364 void ppc6xx_tlb_store (CPUState
*env
, target_ulong EPN
, int way
, int is_code
,
365 target_ulong pte0
, target_ulong pte1
)
370 nr
= ppc6xx_tlb_getnum(env
, EPN
, way
, is_code
);
371 tlb
= &env
->tlb
[nr
].tlb6
;
372 LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx
" PTE0 " TARGET_FMT_lx
373 " PTE1 " TARGET_FMT_lx
"\n", nr
, env
->nb_tlb
, EPN
, pte0
, pte1
);
374 /* Invalidate any pending reference in Qemu for this virtual address */
375 __ppc6xx_tlb_invalidate_virt(env
, EPN
, is_code
, 1);
379 /* Store last way for LRU mechanism */
383 static inline int ppc6xx_tlb_check(CPUState
*env
, mmu_ctx_t
*ctx
,
384 target_ulong eaddr
, int rw
, int access_type
)
391 ret
= -1; /* No TLB found */
392 for (way
= 0; way
< env
->nb_ways
; way
++) {
393 nr
= ppc6xx_tlb_getnum(env
, eaddr
, way
,
394 access_type
== ACCESS_CODE
? 1 : 0);
395 tlb
= &env
->tlb
[nr
].tlb6
;
396 /* This test "emulates" the PTE index match for hardware TLBs */
397 if ((eaddr
& TARGET_PAGE_MASK
) != tlb
->EPN
) {
398 LOG_SWTLB("TLB %d/%d %s [" TARGET_FMT_lx
" " TARGET_FMT_lx
399 "] <> " TARGET_FMT_lx
"\n", nr
, env
->nb_tlb
,
400 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
401 tlb
->EPN
, tlb
->EPN
+ TARGET_PAGE_SIZE
, eaddr
);
404 LOG_SWTLB("TLB %d/%d %s " TARGET_FMT_lx
" <> " TARGET_FMT_lx
" "
405 TARGET_FMT_lx
" %c %c\n", nr
, env
->nb_tlb
,
406 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
407 tlb
->EPN
, eaddr
, tlb
->pte1
,
408 rw
? 'S' : 'L', access_type
== ACCESS_CODE
? 'I' : 'D');
409 switch (pte32_check(ctx
, tlb
->pte0
, tlb
->pte1
, 0, rw
, access_type
)) {
411 /* TLB inconsistency */
414 /* Access violation */
424 /* XXX: we should go on looping to check all TLBs consistency
425 * but we can speed-up the whole thing as the
426 * result would be undefined if TLBs are not consistent.
435 LOG_SWTLB("found TLB at addr " TARGET_FMT_plx
" prot=%01x ret=%d\n",
436 ctx
->raddr
& TARGET_PAGE_MASK
, ctx
->prot
, ret
);
437 /* Update page flags */
438 pte_update_flags(ctx
, &env
->tlb
[best
].tlb6
.pte1
, ret
, rw
);
444 /* Perform BAT hit & translation */
445 static inline void bat_size_prot(CPUState
*env
, target_ulong
*blp
, int *validp
,
446 int *protp
, target_ulong
*BATu
,
452 bl
= (*BATu
& 0x00001FFC) << 15;
455 if (((msr_pr
== 0) && (*BATu
& 0x00000002)) ||
456 ((msr_pr
!= 0) && (*BATu
& 0x00000001))) {
458 pp
= *BATl
& 0x00000003;
460 prot
= PAGE_READ
| PAGE_EXEC
;
470 static inline void bat_601_size_prot(CPUState
*env
, target_ulong
*blp
,
471 int *validp
, int *protp
,
472 target_ulong
*BATu
, target_ulong
*BATl
)
475 int key
, pp
, valid
, prot
;
477 bl
= (*BATl
& 0x0000003F) << 17;
478 LOG_BATS("b %02x ==> bl " TARGET_FMT_lx
" msk " TARGET_FMT_lx
"\n",
479 (uint8_t)(*BATl
& 0x0000003F), bl
, ~bl
);
481 valid
= (*BATl
>> 6) & 1;
483 pp
= *BATu
& 0x00000003;
485 key
= (*BATu
>> 3) & 1;
487 key
= (*BATu
>> 2) & 1;
488 prot
= pp_check(key
, pp
, 0);
495 static inline int get_bat(CPUState
*env
, mmu_ctx_t
*ctx
, target_ulong
virtual,
498 target_ulong
*BATlt
, *BATut
, *BATu
, *BATl
;
499 target_ulong BEPIl
, BEPIu
, bl
;
503 LOG_BATS("%s: %cBAT v " TARGET_FMT_lx
"\n", __func__
,
504 type
== ACCESS_CODE
? 'I' : 'D', virtual);
507 BATlt
= env
->IBAT
[1];
508 BATut
= env
->IBAT
[0];
511 BATlt
= env
->DBAT
[1];
512 BATut
= env
->DBAT
[0];
515 for (i
= 0; i
< env
->nb_BATs
; i
++) {
518 BEPIu
= *BATu
& 0xF0000000;
519 BEPIl
= *BATu
& 0x0FFE0000;
520 if (unlikely(env
->mmu_model
== POWERPC_MMU_601
)) {
521 bat_601_size_prot(env
, &bl
, &valid
, &prot
, BATu
, BATl
);
523 bat_size_prot(env
, &bl
, &valid
, &prot
, BATu
, BATl
);
525 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx
" BATu " TARGET_FMT_lx
526 " BATl " TARGET_FMT_lx
"\n", __func__
,
527 type
== ACCESS_CODE
? 'I' : 'D', i
, virtual, *BATu
, *BATl
);
528 if ((virtual & 0xF0000000) == BEPIu
&&
529 ((virtual & 0x0FFE0000) & ~bl
) == BEPIl
) {
532 /* Get physical address */
533 ctx
->raddr
= (*BATl
& 0xF0000000) |
534 ((virtual & 0x0FFE0000 & bl
) | (*BATl
& 0x0FFE0000)) |
535 (virtual & 0x0001F000);
536 /* Compute access rights */
538 ret
= check_prot(ctx
->prot
, rw
, type
);
540 LOG_BATS("BAT %d match: r " TARGET_FMT_plx
" prot=%c%c\n",
541 i
, ctx
->raddr
, ctx
->prot
& PAGE_READ
? 'R' : '-',
542 ctx
->prot
& PAGE_WRITE
? 'W' : '-');
548 #if defined(DEBUG_BATS)
549 if (qemu_log_enabled()) {
550 LOG_BATS("no BAT match for " TARGET_FMT_lx
":\n", virtual);
551 for (i
= 0; i
< 4; i
++) {
554 BEPIu
= *BATu
& 0xF0000000;
555 BEPIl
= *BATu
& 0x0FFE0000;
556 bl
= (*BATu
& 0x00001FFC) << 15;
557 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx
" BATu " TARGET_FMT_lx
558 " BATl " TARGET_FMT_lx
" \n\t" TARGET_FMT_lx
" "
559 TARGET_FMT_lx
" " TARGET_FMT_lx
"\n",
560 __func__
, type
== ACCESS_CODE
? 'I' : 'D', i
, virtual,
561 *BATu
, *BATl
, BEPIu
, BEPIl
, bl
);
570 static inline target_phys_addr_t
get_pteg_offset(CPUState
*env
,
571 target_phys_addr_t hash
,
574 return (hash
* pte_size
* 8) & env
->htab_mask
;
577 /* PTE table lookup */
578 static inline int _find_pte(CPUState
*env
, mmu_ctx_t
*ctx
, int is_64b
, int h
,
579 int rw
, int type
, int target_page_bits
)
581 target_phys_addr_t pteg_off
;
582 target_ulong pte0
, pte1
;
586 ret
= -1; /* No entry found */
587 pteg_off
= get_pteg_offset(env
, ctx
->hash
[h
],
588 is_64b
? HASH_PTE_SIZE_64
: HASH_PTE_SIZE_32
);
589 for (i
= 0; i
< 8; i
++) {
590 #if defined(TARGET_PPC64)
592 if (env
->external_htab
) {
593 pte0
= ldq_p(env
->external_htab
+ pteg_off
+ (i
* 16));
594 pte1
= ldq_p(env
->external_htab
+ pteg_off
+ (i
* 16) + 8);
596 pte0
= ldq_phys(env
->htab_base
+ pteg_off
+ (i
* 16));
597 pte1
= ldq_phys(env
->htab_base
+ pteg_off
+ (i
* 16) + 8);
600 /* We have a TLB that saves 4K pages, so let's
601 * split a huge page to 4k chunks */
602 if (target_page_bits
!= TARGET_PAGE_BITS
)
603 pte1
|= (ctx
->eaddr
& (( 1 << target_page_bits
) - 1))
606 r
= pte64_check(ctx
, pte0
, pte1
, h
, rw
, type
);
607 LOG_MMU("Load pte from " TARGET_FMT_lx
" => " TARGET_FMT_lx
" "
608 TARGET_FMT_lx
" %d %d %d " TARGET_FMT_lx
"\n",
609 pteg_base
+ (i
* 16), pte0
, pte1
, (int)(pte0
& 1), h
,
610 (int)((pte0
>> 1) & 1), ctx
->ptem
);
614 if (env
->external_htab
) {
615 pte0
= ldl_p(env
->external_htab
+ pteg_off
+ (i
* 8));
616 pte1
= ldl_p(env
->external_htab
+ pteg_off
+ (i
* 8) + 4);
618 pte0
= ldl_phys(env
->htab_base
+ pteg_off
+ (i
* 8));
619 pte1
= ldl_phys(env
->htab_base
+ pteg_off
+ (i
* 8) + 4);
621 r
= pte32_check(ctx
, pte0
, pte1
, h
, rw
, type
);
622 LOG_MMU("Load pte from " TARGET_FMT_lx
" => " TARGET_FMT_lx
" "
623 TARGET_FMT_lx
" %d %d %d " TARGET_FMT_lx
"\n",
624 pteg_base
+ (i
* 8), pte0
, pte1
, (int)(pte0
>> 31), h
,
625 (int)((pte0
>> 6) & 1), ctx
->ptem
);
629 /* PTE inconsistency */
632 /* Access violation */
642 /* XXX: we should go on looping to check all PTEs consistency
643 * but if we can speed-up the whole thing as the
644 * result would be undefined if PTEs are not consistent.
653 LOG_MMU("found PTE at addr " TARGET_FMT_lx
" prot=%01x ret=%d\n",
654 ctx
->raddr
, ctx
->prot
, ret
);
655 /* Update page flags */
657 if (pte_update_flags(ctx
, &pte1
, ret
, rw
) == 1) {
658 #if defined(TARGET_PPC64)
660 if (env
->external_htab
) {
661 stq_p(env
->external_htab
+ pteg_off
+ (good
* 16) + 8,
664 stq_phys_notdirty(env
->htab_base
+ pteg_off
+
665 (good
* 16) + 8, pte1
);
670 if (env
->external_htab
) {
671 stl_p(env
->external_htab
+ pteg_off
+ (good
* 8) + 4,
674 stl_phys_notdirty(env
->htab_base
+ pteg_off
+
675 (good
* 8) + 4, pte1
);
684 static inline int find_pte(CPUState
*env
, mmu_ctx_t
*ctx
, int h
, int rw
,
685 int type
, int target_page_bits
)
687 #if defined(TARGET_PPC64)
688 if (env
->mmu_model
& POWERPC_MMU_64
)
689 return _find_pte(env
, ctx
, 1, h
, rw
, type
, target_page_bits
);
692 return _find_pte(env
, ctx
, 0, h
, rw
, type
, target_page_bits
);
695 #if defined(TARGET_PPC64)
696 static inline ppc_slb_t
*slb_lookup(CPUPPCState
*env
, target_ulong eaddr
)
698 uint64_t esid_256M
, esid_1T
;
701 LOG_SLB("%s: eaddr " TARGET_FMT_lx
"\n", __func__
, eaddr
);
703 esid_256M
= (eaddr
& SEGMENT_MASK_256M
) | SLB_ESID_V
;
704 esid_1T
= (eaddr
& SEGMENT_MASK_1T
) | SLB_ESID_V
;
706 for (n
= 0; n
< env
->slb_nr
; n
++) {
707 ppc_slb_t
*slb
= &env
->slb
[n
];
709 LOG_SLB("%s: slot %d %016" PRIx64
" %016"
710 PRIx64
"\n", __func__
, n
, slb
->esid
, slb
->vsid
);
711 /* We check for 1T matches on all MMUs here - if the MMU
712 * doesn't have 1T segment support, we will have prevented 1T
713 * entries from being inserted in the slbmte code. */
714 if (((slb
->esid
== esid_256M
) &&
715 ((slb
->vsid
& SLB_VSID_B
) == SLB_VSID_B_256M
))
716 || ((slb
->esid
== esid_1T
) &&
717 ((slb
->vsid
& SLB_VSID_B
) == SLB_VSID_B_1T
))) {
725 void ppc_slb_invalidate_all (CPUPPCState
*env
)
727 int n
, do_invalidate
;
730 /* XXX: Warning: slbia never invalidates the first segment */
731 for (n
= 1; n
< env
->slb_nr
; n
++) {
732 ppc_slb_t
*slb
= &env
->slb
[n
];
734 if (slb
->esid
& SLB_ESID_V
) {
735 slb
->esid
&= ~SLB_ESID_V
;
736 /* XXX: given the fact that segment size is 256 MB or 1TB,
737 * and we still don't have a tlb_flush_mask(env, n, mask)
738 * in Qemu, we just invalidate all TLBs
747 void ppc_slb_invalidate_one (CPUPPCState
*env
, uint64_t T0
)
751 slb
= slb_lookup(env
, T0
);
756 if (slb
->esid
& SLB_ESID_V
) {
757 slb
->esid
&= ~SLB_ESID_V
;
759 /* XXX: given the fact that segment size is 256 MB or 1TB,
760 * and we still don't have a tlb_flush_mask(env, n, mask)
761 * in Qemu, we just invalidate all TLBs
767 int ppc_store_slb (CPUPPCState
*env
, target_ulong rb
, target_ulong rs
)
769 int slot
= rb
& 0xfff;
770 ppc_slb_t
*slb
= &env
->slb
[slot
];
772 if (rb
& (0x1000 - env
->slb_nr
)) {
773 return -1; /* Reserved bits set or slot too high */
775 if (rs
& (SLB_VSID_B
& ~SLB_VSID_B_1T
)) {
776 return -1; /* Bad segment size */
778 if ((rs
& SLB_VSID_B
) && !(env
->mmu_model
& POWERPC_MMU_1TSEG
)) {
779 return -1; /* 1T segment on MMU that doesn't support it */
782 /* Mask out the slot number as we store the entry */
783 slb
->esid
= rb
& (SLB_ESID_ESID
| SLB_ESID_V
);
786 LOG_SLB("%s: %d " TARGET_FMT_lx
" - " TARGET_FMT_lx
" => %016" PRIx64
787 " %016" PRIx64
"\n", __func__
, slot
, rb
, rs
,
788 slb
->esid
, slb
->vsid
);
793 int ppc_load_slb_esid (CPUPPCState
*env
, target_ulong rb
, target_ulong
*rt
)
795 int slot
= rb
& 0xfff;
796 ppc_slb_t
*slb
= &env
->slb
[slot
];
798 if (slot
>= env
->slb_nr
) {
806 int ppc_load_slb_vsid (CPUPPCState
*env
, target_ulong rb
, target_ulong
*rt
)
808 int slot
= rb
& 0xfff;
809 ppc_slb_t
*slb
= &env
->slb
[slot
];
811 if (slot
>= env
->slb_nr
) {
818 #endif /* defined(TARGET_PPC64) */
820 /* Perform segment based translation */
821 static inline int get_segment(CPUState
*env
, mmu_ctx_t
*ctx
,
822 target_ulong eaddr
, int rw
, int type
)
824 target_phys_addr_t hash
;
826 int ds
, pr
, target_page_bits
;
831 #if defined(TARGET_PPC64)
832 if (env
->mmu_model
& POWERPC_MMU_64
) {
834 target_ulong pageaddr
;
837 LOG_MMU("Check SLBs\n");
838 slb
= slb_lookup(env
, eaddr
);
843 if (slb
->vsid
& SLB_VSID_B
) {
844 vsid
= (slb
->vsid
& SLB_VSID_VSID
) >> SLB_VSID_SHIFT_1T
;
847 vsid
= (slb
->vsid
& SLB_VSID_VSID
) >> SLB_VSID_SHIFT
;
851 target_page_bits
= (slb
->vsid
& SLB_VSID_L
)
852 ? TARGET_PAGE_BITS_16M
: TARGET_PAGE_BITS
;
853 ctx
->key
= !!(pr
? (slb
->vsid
& SLB_VSID_KP
)
854 : (slb
->vsid
& SLB_VSID_KS
));
856 ctx
->nx
= !!(slb
->vsid
& SLB_VSID_N
);
858 pageaddr
= eaddr
& ((1ULL << segment_bits
)
859 - (1ULL << target_page_bits
));
860 if (slb
->vsid
& SLB_VSID_B
) {
861 hash
= vsid
^ (vsid
<< 25) ^ (pageaddr
>> target_page_bits
);
863 hash
= vsid
^ (pageaddr
>> target_page_bits
);
865 /* Only 5 bits of the page index are used in the AVPN */
866 ctx
->ptem
= (slb
->vsid
& SLB_VSID_PTEM
) |
867 ((pageaddr
>> 16) & ((1ULL << segment_bits
) - 0x80));
869 #endif /* defined(TARGET_PPC64) */
871 target_ulong sr
, pgidx
;
873 sr
= env
->sr
[eaddr
>> 28];
874 ctx
->key
= (((sr
& 0x20000000) && (pr
!= 0)) ||
875 ((sr
& 0x40000000) && (pr
== 0))) ? 1 : 0;
876 ds
= sr
& 0x80000000 ? 1 : 0;
877 ctx
->nx
= sr
& 0x10000000 ? 1 : 0;
878 vsid
= sr
& 0x00FFFFFF;
879 target_page_bits
= TARGET_PAGE_BITS
;
880 LOG_MMU("Check segment v=" TARGET_FMT_lx
" %d " TARGET_FMT_lx
" nip="
881 TARGET_FMT_lx
" lr=" TARGET_FMT_lx
882 " ir=%d dr=%d pr=%d %d t=%d\n",
883 eaddr
, (int)(eaddr
>> 28), sr
, env
->nip
, env
->lr
, (int)msr_ir
,
884 (int)msr_dr
, pr
!= 0 ? 1 : 0, rw
, type
);
885 pgidx
= (eaddr
& ~SEGMENT_MASK_256M
) >> target_page_bits
;
887 ctx
->ptem
= (vsid
<< 7) | (pgidx
>> 10);
889 LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx
"\n",
890 ctx
->key
, ds
, ctx
->nx
, vsid
);
893 /* Check if instruction fetch is allowed, if needed */
894 if (type
!= ACCESS_CODE
|| ctx
->nx
== 0) {
895 /* Page address translation */
896 LOG_MMU("htab_base " TARGET_FMT_plx
" htab_mask " TARGET_FMT_plx
897 " hash " TARGET_FMT_plx
"\n",
898 env
->htab_base
, env
->htab_mask
, hash
);
900 ctx
->hash
[1] = ~hash
;
902 /* Initialize real address with an invalid value */
903 ctx
->raddr
= (target_phys_addr_t
)-1ULL;
904 if (unlikely(env
->mmu_model
== POWERPC_MMU_SOFT_6xx
||
905 env
->mmu_model
== POWERPC_MMU_SOFT_74xx
)) {
906 /* Software TLB search */
907 ret
= ppc6xx_tlb_check(env
, ctx
, eaddr
, rw
, type
);
909 LOG_MMU("0 htab=" TARGET_FMT_plx
"/" TARGET_FMT_plx
910 " vsid=" TARGET_FMT_lx
" ptem=" TARGET_FMT_lx
911 " hash=" TARGET_FMT_plx
"\n",
912 env
->htab_base
, env
->htab_mask
, vsid
, ctx
->ptem
,
914 /* Primary table lookup */
915 ret
= find_pte(env
, ctx
, 0, rw
, type
, target_page_bits
);
917 /* Secondary table lookup */
918 if (eaddr
!= 0xEFFFFFFF)
919 LOG_MMU("1 htab=" TARGET_FMT_plx
"/" TARGET_FMT_plx
920 " vsid=" TARGET_FMT_lx
" api=" TARGET_FMT_lx
921 " hash=" TARGET_FMT_plx
" pg_addr="
922 TARGET_FMT_plx
"\n", env
->htab_base
,
923 env
->htab_mask
, vsid
, ctx
->ptem
, ctx
->hash
[1]);
924 ret2
= find_pte(env
, ctx
, 1, rw
, type
,
930 #if defined (DUMP_PAGE_TABLES)
931 if (qemu_log_enabled()) {
932 target_phys_addr_t curaddr
;
933 uint32_t a0
, a1
, a2
, a3
;
934 qemu_log("Page table: " TARGET_FMT_plx
" len " TARGET_FMT_plx
935 "\n", sdr
, mask
+ 0x80);
936 for (curaddr
= sdr
; curaddr
< (sdr
+ mask
+ 0x80);
938 a0
= ldl_phys(curaddr
);
939 a1
= ldl_phys(curaddr
+ 4);
940 a2
= ldl_phys(curaddr
+ 8);
941 a3
= ldl_phys(curaddr
+ 12);
942 if (a0
!= 0 || a1
!= 0 || a2
!= 0 || a3
!= 0) {
943 qemu_log(TARGET_FMT_plx
": %08x %08x %08x %08x\n",
944 curaddr
, a0
, a1
, a2
, a3
);
950 LOG_MMU("No access allowed\n");
954 LOG_MMU("direct store...\n");
955 /* Direct-store segment : absolutely *BUGGY* for now */
958 /* Integer load/store : only access allowed */
961 /* No code fetch is allowed in direct-store areas */
964 /* Floating point load/store */
967 /* lwarx, ldarx or srwcx. */
970 /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
971 /* Should make the instruction do no-op.
972 * As it already do no-op, it's quite easy :-)
980 qemu_log("ERROR: instruction should not need "
981 "address translation\n");
984 if ((rw
== 1 || ctx
->key
!= 1) && (rw
== 0 || ctx
->key
!= 0)) {
995 /* Generic TLB check function for embedded PowerPC implementations */
996 int ppcemb_tlb_check(CPUState
*env
, ppcemb_tlb_t
*tlb
,
997 target_phys_addr_t
*raddrp
,
998 target_ulong address
, uint32_t pid
, int ext
,
1003 /* Check valid flag */
1004 if (!(tlb
->prot
& PAGE_VALID
)) {
1007 mask
= ~(tlb
->size
- 1);
1008 LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx
" PID %u <=> " TARGET_FMT_lx
1009 " " TARGET_FMT_lx
" %u %x\n", __func__
, i
, address
, pid
, tlb
->EPN
,
1010 mask
, (uint32_t)tlb
->PID
, tlb
->prot
);
1012 if (tlb
->PID
!= 0 && tlb
->PID
!= pid
)
1014 /* Check effective address */
1015 if ((address
& mask
) != tlb
->EPN
)
1017 *raddrp
= (tlb
->RPN
& mask
) | (address
& ~mask
);
1018 #if (TARGET_PHYS_ADDR_BITS >= 36)
1020 /* Extend the physical address to 36 bits */
1021 *raddrp
|= (target_phys_addr_t
)(tlb
->RPN
& 0xF) << 32;
1028 /* Generic TLB search function for PowerPC embedded implementations */
1029 int ppcemb_tlb_search (CPUPPCState
*env
, target_ulong address
, uint32_t pid
)
1032 target_phys_addr_t raddr
;
1035 /* Default return value is no match */
1037 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1038 tlb
= &env
->tlb
[i
].tlbe
;
1039 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
, pid
, 0, i
) == 0) {
1048 /* Helpers specific to PowerPC 40x implementations */
1049 static inline void ppc4xx_tlb_invalidate_all(CPUState
*env
)
1054 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1055 tlb
= &env
->tlb
[i
].tlbe
;
1056 tlb
->prot
&= ~PAGE_VALID
;
1061 static inline void ppc4xx_tlb_invalidate_virt(CPUState
*env
,
1062 target_ulong eaddr
, uint32_t pid
)
1064 #if !defined(FLUSH_ALL_TLBS)
1066 target_phys_addr_t raddr
;
1067 target_ulong page
, end
;
1070 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1071 tlb
= &env
->tlb
[i
].tlbe
;
1072 if (ppcemb_tlb_check(env
, tlb
, &raddr
, eaddr
, pid
, 0, i
) == 0) {
1073 end
= tlb
->EPN
+ tlb
->size
;
1074 for (page
= tlb
->EPN
; page
< end
; page
+= TARGET_PAGE_SIZE
)
1075 tlb_flush_page(env
, page
);
1076 tlb
->prot
&= ~PAGE_VALID
;
1081 ppc4xx_tlb_invalidate_all(env
);
1085 static int mmu40x_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1086 target_ulong address
, int rw
, int access_type
)
1089 target_phys_addr_t raddr
;
1090 int i
, ret
, zsel
, zpr
, pr
;
1093 raddr
= (target_phys_addr_t
)-1ULL;
1095 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1096 tlb
= &env
->tlb
[i
].tlbe
;
1097 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
,
1098 env
->spr
[SPR_40x_PID
], 0, i
) < 0)
1100 zsel
= (tlb
->attr
>> 4) & 0xF;
1101 zpr
= (env
->spr
[SPR_40x_ZPR
] >> (30 - (2 * zsel
))) & 0x3;
1102 LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1103 __func__
, i
, zsel
, zpr
, rw
, tlb
->attr
);
1104 /* Check execute enable bit */
1111 /* All accesses granted */
1112 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
1117 /* Raise Zone protection fault. */
1118 env
->spr
[SPR_40x_ESR
] = 1 << 22;
1126 /* Check from TLB entry */
1127 ctx
->prot
= tlb
->prot
;
1128 ret
= check_prot(ctx
->prot
, rw
, access_type
);
1130 env
->spr
[SPR_40x_ESR
] = 0;
1135 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1136 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1141 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1142 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1147 void store_40x_sler (CPUPPCState
*env
, uint32_t val
)
1149 /* XXX: TO BE FIXED */
1150 if (val
!= 0x00000000) {
1151 cpu_abort(env
, "Little-endian regions are not supported by now\n");
1153 env
->spr
[SPR_405_SLER
] = val
;
1156 static inline int mmubooke_check_tlb (CPUState
*env
, ppcemb_tlb_t
*tlb
,
1157 target_phys_addr_t
*raddr
, int *prot
,
1158 target_ulong address
, int rw
,
1159 int access_type
, int i
)
1163 if (ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1164 env
->spr
[SPR_BOOKE_PID
],
1165 !env
->nb_pids
, i
) >= 0) {
1169 if (env
->spr
[SPR_BOOKE_PID1
] &&
1170 ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1171 env
->spr
[SPR_BOOKE_PID1
], 0, i
) >= 0) {
1175 if (env
->spr
[SPR_BOOKE_PID2
] &&
1176 ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1177 env
->spr
[SPR_BOOKE_PID2
], 0, i
) >= 0) {
1181 LOG_SWTLB("%s: TLB entry not found\n", __func__
);
1187 _prot
= tlb
->prot
& 0xF;
1189 _prot
= (tlb
->prot
>> 4) & 0xF;
1192 /* Check the address space */
1193 if (access_type
== ACCESS_CODE
) {
1194 if (msr_ir
!= (tlb
->attr
& 1)) {
1195 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1200 if (_prot
& PAGE_EXEC
) {
1201 LOG_SWTLB("%s: good TLB!\n", __func__
);
1205 LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__
, _prot
);
1208 if (msr_dr
!= (tlb
->attr
& 1)) {
1209 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1214 if ((!rw
&& _prot
& PAGE_READ
) || (rw
&& (_prot
& PAGE_WRITE
))) {
1215 LOG_SWTLB("%s: found TLB!\n", __func__
);
1219 LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__
, _prot
);
1226 static int mmubooke_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1227 target_ulong address
, int rw
,
1231 target_phys_addr_t raddr
;
1235 raddr
= (target_phys_addr_t
)-1ULL;
1236 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1237 tlb
= &env
->tlb
[i
].tlbe
;
1238 ret
= mmubooke_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
, rw
,
1247 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1248 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1251 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1252 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1258 void booke206_flush_tlb(CPUState
*env
, int flags
, const int check_iprot
)
1262 ppc_tlb_t
*tlb
= env
->tlb
;
1264 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1265 if (flags
& (1 << i
)) {
1266 tlb_size
= booke206_tlb_size(env
, i
);
1267 for (j
= 0; j
< tlb_size
; j
++) {
1268 if (!check_iprot
|| !(tlb
[j
].tlbe
.attr
& MAS1_IPROT
)) {
1269 tlb
[j
].tlbe
.prot
= 0;
1273 tlb
+= booke206_tlb_size(env
, i
);
1279 static int mmubooke206_get_physical_address(CPUState
*env
, mmu_ctx_t
*ctx
,
1280 target_ulong address
, int rw
,
1284 target_phys_addr_t raddr
;
1288 raddr
= (target_phys_addr_t
)-1ULL;
1290 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1291 int ways
= booke206_tlb_ways(env
, i
);
1293 for (j
= 0; j
< ways
; j
++) {
1294 tlb
= booke206_get_tlbe(env
, i
, address
, j
);
1295 ret
= mmubooke_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
, rw
,
1307 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1308 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1311 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1312 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1318 static inline int check_physical(CPUState
*env
, mmu_ctx_t
*ctx
,
1319 target_ulong eaddr
, int rw
)
1324 ctx
->prot
= PAGE_READ
| PAGE_EXEC
;
1326 switch (env
->mmu_model
) {
1327 case POWERPC_MMU_32B
:
1328 case POWERPC_MMU_601
:
1329 case POWERPC_MMU_SOFT_6xx
:
1330 case POWERPC_MMU_SOFT_74xx
:
1331 case POWERPC_MMU_SOFT_4xx
:
1332 case POWERPC_MMU_REAL
:
1333 case POWERPC_MMU_BOOKE
:
1334 ctx
->prot
|= PAGE_WRITE
;
1336 #if defined(TARGET_PPC64)
1337 case POWERPC_MMU_620
:
1338 case POWERPC_MMU_64B
:
1339 case POWERPC_MMU_2_06
:
1340 /* Real address are 60 bits long */
1341 ctx
->raddr
&= 0x0FFFFFFFFFFFFFFFULL
;
1342 ctx
->prot
|= PAGE_WRITE
;
1345 case POWERPC_MMU_SOFT_4xx_Z
:
1346 if (unlikely(msr_pe
!= 0)) {
1347 /* 403 family add some particular protections,
1348 * using PBL/PBU registers for accesses with no translation.
1351 /* Check PLB validity */
1352 (env
->pb
[0] < env
->pb
[1] &&
1353 /* and address in plb area */
1354 eaddr
>= env
->pb
[0] && eaddr
< env
->pb
[1]) ||
1355 (env
->pb
[2] < env
->pb
[3] &&
1356 eaddr
>= env
->pb
[2] && eaddr
< env
->pb
[3]) ? 1 : 0;
1357 if (in_plb
^ msr_px
) {
1358 /* Access in protected area */
1360 /* Access is not allowed */
1364 /* Read-write access is allowed */
1365 ctx
->prot
|= PAGE_WRITE
;
1369 case POWERPC_MMU_MPC8xx
:
1371 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1373 case POWERPC_MMU_BOOKE206
:
1374 cpu_abort(env
, "BookE 2.06 MMU doesn't have physical real mode\n");
1377 cpu_abort(env
, "Unknown or invalid MMU model\n");
1384 int get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
, target_ulong eaddr
,
1385 int rw
, int access_type
)
1390 qemu_log("%s\n", __func__
);
1392 if ((access_type
== ACCESS_CODE
&& msr_ir
== 0) ||
1393 (access_type
!= ACCESS_CODE
&& msr_dr
== 0)) {
1394 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1395 /* The BookE MMU always performs address translation. The
1396 IS and DS bits only affect the address space. */
1397 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1399 } else if (env
->mmu_model
== POWERPC_MMU_BOOKE206
) {
1400 ret
= mmubooke206_get_physical_address(env
, ctx
, eaddr
, rw
,
1403 /* No address translation. */
1404 ret
= check_physical(env
, ctx
, eaddr
, rw
);
1408 switch (env
->mmu_model
) {
1409 case POWERPC_MMU_32B
:
1410 case POWERPC_MMU_601
:
1411 case POWERPC_MMU_SOFT_6xx
:
1412 case POWERPC_MMU_SOFT_74xx
:
1413 /* Try to find a BAT */
1414 if (env
->nb_BATs
!= 0)
1415 ret
= get_bat(env
, ctx
, eaddr
, rw
, access_type
);
1416 #if defined(TARGET_PPC64)
1417 case POWERPC_MMU_620
:
1418 case POWERPC_MMU_64B
:
1419 case POWERPC_MMU_2_06
:
1422 /* We didn't match any BAT entry or don't have BATs */
1423 ret
= get_segment(env
, ctx
, eaddr
, rw
, access_type
);
1426 case POWERPC_MMU_SOFT_4xx
:
1427 case POWERPC_MMU_SOFT_4xx_Z
:
1428 ret
= mmu40x_get_physical_address(env
, ctx
, eaddr
,
1431 case POWERPC_MMU_BOOKE
:
1432 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1435 case POWERPC_MMU_BOOKE206
:
1436 ret
= mmubooke206_get_physical_address(env
, ctx
, eaddr
, rw
,
1439 case POWERPC_MMU_MPC8xx
:
1441 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1443 case POWERPC_MMU_REAL
:
1444 cpu_abort(env
, "PowerPC in real mode do not do any translation\n");
1447 cpu_abort(env
, "Unknown or invalid MMU model\n");
1452 qemu_log("%s address " TARGET_FMT_lx
" => %d " TARGET_FMT_plx
"\n",
1453 __func__
, eaddr
, ret
, ctx
->raddr
);
1459 target_phys_addr_t
cpu_get_phys_page_debug (CPUState
*env
, target_ulong addr
)
1463 if (unlikely(get_physical_address(env
, &ctx
, addr
, 0, ACCESS_INT
) != 0))
1466 return ctx
.raddr
& TARGET_PAGE_MASK
;
1469 static void booke206_update_mas_tlb_miss(CPUState
*env
, target_ulong address
,
1472 env
->spr
[SPR_BOOKE_MAS0
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TLBSELD_MASK
;
1473 env
->spr
[SPR_BOOKE_MAS1
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TSIZED_MASK
;
1474 env
->spr
[SPR_BOOKE_MAS2
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_WIMGED_MASK
;
1475 env
->spr
[SPR_BOOKE_MAS3
] = 0;
1476 env
->spr
[SPR_BOOKE_MAS6
] = 0;
1477 env
->spr
[SPR_BOOKE_MAS7
] = 0;
1480 if (((rw
== 2) && msr_ir
) || ((rw
!= 2) && msr_dr
)) {
1481 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_TS
;
1482 env
->spr
[SPR_BOOKE_MAS6
] |= MAS6_SAS
;
1485 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_VALID
;
1486 env
->spr
[SPR_BOOKE_MAS2
] |= address
& MAS2_EPN_MASK
;
1488 switch (env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TIDSELD_PIDZ
) {
1489 case MAS4_TIDSELD_PID0
:
1490 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID
] << MAS1_TID_SHIFT
;
1492 case MAS4_TIDSELD_PID1
:
1493 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID1
] << MAS1_TID_SHIFT
;
1495 case MAS4_TIDSELD_PID2
:
1496 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID2
] << MAS1_TID_SHIFT
;
1500 env
->spr
[SPR_BOOKE_MAS6
] |= env
->spr
[SPR_BOOKE_PID
] << 16;
1502 /* next victim logic */
1503 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_ESEL_SHIFT
;
1505 env
->last_way
&= booke206_tlb_ways(env
, 0) - 1;
1506 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_NV_SHIFT
;
1509 /* Perform address translation */
1510 int cpu_ppc_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
1511 int mmu_idx
, int is_softmmu
)
1520 access_type
= ACCESS_CODE
;
1523 access_type
= env
->access_type
;
1525 ret
= get_physical_address(env
, &ctx
, address
, rw
, access_type
);
1527 tlb_set_page(env
, address
& TARGET_PAGE_MASK
,
1528 ctx
.raddr
& TARGET_PAGE_MASK
, ctx
.prot
,
1529 mmu_idx
, TARGET_PAGE_SIZE
);
1531 } else if (ret
< 0) {
1533 if (access_type
== ACCESS_CODE
) {
1536 /* No matches in page tables or TLB */
1537 switch (env
->mmu_model
) {
1538 case POWERPC_MMU_SOFT_6xx
:
1539 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1540 env
->error_code
= 1 << 18;
1541 env
->spr
[SPR_IMISS
] = address
;
1542 env
->spr
[SPR_ICMP
] = 0x80000000 | ctx
.ptem
;
1544 case POWERPC_MMU_SOFT_74xx
:
1545 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1547 case POWERPC_MMU_SOFT_4xx
:
1548 case POWERPC_MMU_SOFT_4xx_Z
:
1549 env
->exception_index
= POWERPC_EXCP_ITLB
;
1550 env
->error_code
= 0;
1551 env
->spr
[SPR_40x_DEAR
] = address
;
1552 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1554 case POWERPC_MMU_32B
:
1555 case POWERPC_MMU_601
:
1556 #if defined(TARGET_PPC64)
1557 case POWERPC_MMU_620
:
1558 case POWERPC_MMU_64B
:
1559 case POWERPC_MMU_2_06
:
1561 env
->exception_index
= POWERPC_EXCP_ISI
;
1562 env
->error_code
= 0x40000000;
1564 case POWERPC_MMU_BOOKE206
:
1565 booke206_update_mas_tlb_miss(env
, address
, rw
);
1567 case POWERPC_MMU_BOOKE
:
1568 env
->exception_index
= POWERPC_EXCP_ITLB
;
1569 env
->error_code
= 0;
1570 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1572 case POWERPC_MMU_MPC8xx
:
1574 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1576 case POWERPC_MMU_REAL
:
1577 cpu_abort(env
, "PowerPC in real mode should never raise "
1578 "any MMU exceptions\n");
1581 cpu_abort(env
, "Unknown or invalid MMU model\n");
1586 /* Access rights violation */
1587 env
->exception_index
= POWERPC_EXCP_ISI
;
1588 env
->error_code
= 0x08000000;
1591 /* No execute protection violation */
1592 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1593 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1594 env
->spr
[SPR_BOOKE_ESR
] = 0x00000000;
1596 env
->exception_index
= POWERPC_EXCP_ISI
;
1597 env
->error_code
= 0x10000000;
1600 /* Direct store exception */
1601 /* No code fetch is allowed in direct-store areas */
1602 env
->exception_index
= POWERPC_EXCP_ISI
;
1603 env
->error_code
= 0x10000000;
1605 #if defined(TARGET_PPC64)
1607 /* No match in segment table */
1608 if (env
->mmu_model
== POWERPC_MMU_620
) {
1609 env
->exception_index
= POWERPC_EXCP_ISI
;
1610 /* XXX: this might be incorrect */
1611 env
->error_code
= 0x40000000;
1613 env
->exception_index
= POWERPC_EXCP_ISEG
;
1614 env
->error_code
= 0;
1622 /* No matches in page tables or TLB */
1623 switch (env
->mmu_model
) {
1624 case POWERPC_MMU_SOFT_6xx
:
1626 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1627 env
->error_code
= 1 << 16;
1629 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1630 env
->error_code
= 0;
1632 env
->spr
[SPR_DMISS
] = address
;
1633 env
->spr
[SPR_DCMP
] = 0x80000000 | ctx
.ptem
;
1635 env
->error_code
|= ctx
.key
<< 19;
1636 env
->spr
[SPR_HASH1
] = env
->htab_base
+
1637 get_pteg_offset(env
, ctx
.hash
[0], HASH_PTE_SIZE_32
);
1638 env
->spr
[SPR_HASH2
] = env
->htab_base
+
1639 get_pteg_offset(env
, ctx
.hash
[1], HASH_PTE_SIZE_32
);
1641 case POWERPC_MMU_SOFT_74xx
:
1643 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1645 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1648 /* Implement LRU algorithm */
1649 env
->error_code
= ctx
.key
<< 19;
1650 env
->spr
[SPR_TLBMISS
] = (address
& ~((target_ulong
)0x3)) |
1651 ((env
->last_way
+ 1) & (env
->nb_ways
- 1));
1652 env
->spr
[SPR_PTEHI
] = 0x80000000 | ctx
.ptem
;
1654 case POWERPC_MMU_SOFT_4xx
:
1655 case POWERPC_MMU_SOFT_4xx_Z
:
1656 env
->exception_index
= POWERPC_EXCP_DTLB
;
1657 env
->error_code
= 0;
1658 env
->spr
[SPR_40x_DEAR
] = address
;
1660 env
->spr
[SPR_40x_ESR
] = 0x00800000;
1662 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1664 case POWERPC_MMU_32B
:
1665 case POWERPC_MMU_601
:
1666 #if defined(TARGET_PPC64)
1667 case POWERPC_MMU_620
:
1668 case POWERPC_MMU_64B
:
1669 case POWERPC_MMU_2_06
:
1671 env
->exception_index
= POWERPC_EXCP_DSI
;
1672 env
->error_code
= 0;
1673 env
->spr
[SPR_DAR
] = address
;
1675 env
->spr
[SPR_DSISR
] = 0x42000000;
1677 env
->spr
[SPR_DSISR
] = 0x40000000;
1679 case POWERPC_MMU_MPC8xx
:
1681 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1683 case POWERPC_MMU_BOOKE206
:
1684 booke206_update_mas_tlb_miss(env
, address
, rw
);
1686 case POWERPC_MMU_BOOKE
:
1687 env
->exception_index
= POWERPC_EXCP_DTLB
;
1688 env
->error_code
= 0;
1689 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1690 env
->spr
[SPR_BOOKE_ESR
] = rw
? 1 << ESR_ST
: 0;
1692 case POWERPC_MMU_REAL
:
1693 cpu_abort(env
, "PowerPC in real mode should never raise "
1694 "any MMU exceptions\n");
1697 cpu_abort(env
, "Unknown or invalid MMU model\n");
1702 /* Access rights violation */
1703 env
->exception_index
= POWERPC_EXCP_DSI
;
1704 env
->error_code
= 0;
1705 if (env
->mmu_model
== POWERPC_MMU_SOFT_4xx
1706 || env
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
) {
1707 env
->spr
[SPR_40x_DEAR
] = address
;
1709 env
->spr
[SPR_40x_ESR
] |= 0x00800000;
1711 } else if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1712 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1713 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1714 env
->spr
[SPR_BOOKE_ESR
] = rw
? 1 << ESR_ST
: 0;
1716 env
->spr
[SPR_DAR
] = address
;
1718 env
->spr
[SPR_DSISR
] = 0x0A000000;
1720 env
->spr
[SPR_DSISR
] = 0x08000000;
1725 /* Direct store exception */
1726 switch (access_type
) {
1728 /* Floating point load/store */
1729 env
->exception_index
= POWERPC_EXCP_ALIGN
;
1730 env
->error_code
= POWERPC_EXCP_ALIGN_FP
;
1731 env
->spr
[SPR_DAR
] = address
;
1734 /* lwarx, ldarx or stwcx. */
1735 env
->exception_index
= POWERPC_EXCP_DSI
;
1736 env
->error_code
= 0;
1737 env
->spr
[SPR_DAR
] = address
;
1739 env
->spr
[SPR_DSISR
] = 0x06000000;
1741 env
->spr
[SPR_DSISR
] = 0x04000000;
1744 /* eciwx or ecowx */
1745 env
->exception_index
= POWERPC_EXCP_DSI
;
1746 env
->error_code
= 0;
1747 env
->spr
[SPR_DAR
] = address
;
1749 env
->spr
[SPR_DSISR
] = 0x06100000;
1751 env
->spr
[SPR_DSISR
] = 0x04100000;
1754 printf("DSI: invalid exception (%d)\n", ret
);
1755 env
->exception_index
= POWERPC_EXCP_PROGRAM
;
1757 POWERPC_EXCP_INVAL
| POWERPC_EXCP_INVAL_INVAL
;
1758 env
->spr
[SPR_DAR
] = address
;
1762 #if defined(TARGET_PPC64)
1764 /* No match in segment table */
1765 if (env
->mmu_model
== POWERPC_MMU_620
) {
1766 env
->exception_index
= POWERPC_EXCP_DSI
;
1767 env
->error_code
= 0;
1768 env
->spr
[SPR_DAR
] = address
;
1769 /* XXX: this might be incorrect */
1771 env
->spr
[SPR_DSISR
] = 0x42000000;
1773 env
->spr
[SPR_DSISR
] = 0x40000000;
1775 env
->exception_index
= POWERPC_EXCP_DSEG
;
1776 env
->error_code
= 0;
1777 env
->spr
[SPR_DAR
] = address
;
1784 printf("%s: set exception to %d %02x\n", __func__
,
1785 env
->exception
, env
->error_code
);
1793 /*****************************************************************************/
1794 /* BATs management */
1795 #if !defined(FLUSH_ALL_TLBS)
1796 static inline void do_invalidate_BAT(CPUPPCState
*env
, target_ulong BATu
,
1799 target_ulong base
, end
, page
;
1801 base
= BATu
& ~0x0001FFFF;
1802 end
= base
+ mask
+ 0x00020000;
1803 LOG_BATS("Flush BAT from " TARGET_FMT_lx
" to " TARGET_FMT_lx
" ("
1804 TARGET_FMT_lx
")\n", base
, end
, mask
);
1805 for (page
= base
; page
!= end
; page
+= TARGET_PAGE_SIZE
)
1806 tlb_flush_page(env
, page
);
1807 LOG_BATS("Flush done\n");
1811 static inline void dump_store_bat(CPUPPCState
*env
, char ID
, int ul
, int nr
,
1814 LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx
" (" TARGET_FMT_lx
")\n", ID
,
1815 nr
, ul
== 0 ? 'u' : 'l', value
, env
->nip
);
1818 void ppc_store_ibatu (CPUPPCState
*env
, int nr
, target_ulong value
)
1822 dump_store_bat(env
, 'I', 0, nr
, value
);
1823 if (env
->IBAT
[0][nr
] != value
) {
1824 mask
= (value
<< 15) & 0x0FFE0000UL
;
1825 #if !defined(FLUSH_ALL_TLBS)
1826 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1828 /* When storing valid upper BAT, mask BEPI and BRPN
1829 * and invalidate all TLBs covered by this BAT
1831 mask
= (value
<< 15) & 0x0FFE0000UL
;
1832 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1833 (value
& ~0x0001FFFFUL
& ~mask
);
1834 env
->IBAT
[1][nr
] = (env
->IBAT
[1][nr
] & 0x0000007B) |
1835 (env
->IBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
1836 #if !defined(FLUSH_ALL_TLBS)
1837 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1844 void ppc_store_ibatl (CPUPPCState
*env
, int nr
, target_ulong value
)
1846 dump_store_bat(env
, 'I', 1, nr
, value
);
1847 env
->IBAT
[1][nr
] = value
;
1850 void ppc_store_dbatu (CPUPPCState
*env
, int nr
, target_ulong value
)
1854 dump_store_bat(env
, 'D', 0, nr
, value
);
1855 if (env
->DBAT
[0][nr
] != value
) {
1856 /* When storing valid upper BAT, mask BEPI and BRPN
1857 * and invalidate all TLBs covered by this BAT
1859 mask
= (value
<< 15) & 0x0FFE0000UL
;
1860 #if !defined(FLUSH_ALL_TLBS)
1861 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
1863 mask
= (value
<< 15) & 0x0FFE0000UL
;
1864 env
->DBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1865 (value
& ~0x0001FFFFUL
& ~mask
);
1866 env
->DBAT
[1][nr
] = (env
->DBAT
[1][nr
] & 0x0000007B) |
1867 (env
->DBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
1868 #if !defined(FLUSH_ALL_TLBS)
1869 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
1876 void ppc_store_dbatl (CPUPPCState
*env
, int nr
, target_ulong value
)
1878 dump_store_bat(env
, 'D', 1, nr
, value
);
1879 env
->DBAT
[1][nr
] = value
;
1882 void ppc_store_ibatu_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
1885 #if defined(FLUSH_ALL_TLBS)
1889 dump_store_bat(env
, 'I', 0, nr
, value
);
1890 if (env
->IBAT
[0][nr
] != value
) {
1891 #if defined(FLUSH_ALL_TLBS)
1894 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
1895 if (env
->IBAT
[1][nr
] & 0x40) {
1896 /* Invalidate BAT only if it is valid */
1897 #if !defined(FLUSH_ALL_TLBS)
1898 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1903 /* When storing valid upper BAT, mask BEPI and BRPN
1904 * and invalidate all TLBs covered by this BAT
1906 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1907 (value
& ~0x0001FFFFUL
& ~mask
);
1908 env
->DBAT
[0][nr
] = env
->IBAT
[0][nr
];
1909 if (env
->IBAT
[1][nr
] & 0x40) {
1910 #if !defined(FLUSH_ALL_TLBS)
1911 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1916 #if defined(FLUSH_ALL_TLBS)
1923 void ppc_store_ibatl_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
1926 #if defined(FLUSH_ALL_TLBS)
1930 dump_store_bat(env
, 'I', 1, nr
, value
);
1931 if (env
->IBAT
[1][nr
] != value
) {
1932 #if defined(FLUSH_ALL_TLBS)
1935 if (env
->IBAT
[1][nr
] & 0x40) {
1936 #if !defined(FLUSH_ALL_TLBS)
1937 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
1938 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1944 #if !defined(FLUSH_ALL_TLBS)
1945 mask
= (value
<< 17) & 0x0FFE0000UL
;
1946 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1951 env
->IBAT
[1][nr
] = value
;
1952 env
->DBAT
[1][nr
] = value
;
1953 #if defined(FLUSH_ALL_TLBS)
1960 /*****************************************************************************/
1961 /* TLB management */
1962 void ppc_tlb_invalidate_all (CPUPPCState
*env
)
1964 switch (env
->mmu_model
) {
1965 case POWERPC_MMU_SOFT_6xx
:
1966 case POWERPC_MMU_SOFT_74xx
:
1967 ppc6xx_tlb_invalidate_all(env
);
1969 case POWERPC_MMU_SOFT_4xx
:
1970 case POWERPC_MMU_SOFT_4xx_Z
:
1971 ppc4xx_tlb_invalidate_all(env
);
1973 case POWERPC_MMU_REAL
:
1974 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
1976 case POWERPC_MMU_MPC8xx
:
1978 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1980 case POWERPC_MMU_BOOKE
:
1983 case POWERPC_MMU_BOOKE206
:
1984 booke206_flush_tlb(env
, -1, 0);
1986 case POWERPC_MMU_32B
:
1987 case POWERPC_MMU_601
:
1988 #if defined(TARGET_PPC64)
1989 case POWERPC_MMU_620
:
1990 case POWERPC_MMU_64B
:
1991 case POWERPC_MMU_2_06
:
1992 #endif /* defined(TARGET_PPC64) */
1997 cpu_abort(env
, "Unknown MMU model\n");
2002 void ppc_tlb_invalidate_one (CPUPPCState
*env
, target_ulong addr
)
2004 #if !defined(FLUSH_ALL_TLBS)
2005 addr
&= TARGET_PAGE_MASK
;
2006 switch (env
->mmu_model
) {
2007 case POWERPC_MMU_SOFT_6xx
:
2008 case POWERPC_MMU_SOFT_74xx
:
2009 ppc6xx_tlb_invalidate_virt(env
, addr
, 0);
2010 if (env
->id_tlbs
== 1)
2011 ppc6xx_tlb_invalidate_virt(env
, addr
, 1);
2013 case POWERPC_MMU_SOFT_4xx
:
2014 case POWERPC_MMU_SOFT_4xx_Z
:
2015 ppc4xx_tlb_invalidate_virt(env
, addr
, env
->spr
[SPR_40x_PID
]);
2017 case POWERPC_MMU_REAL
:
2018 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
2020 case POWERPC_MMU_MPC8xx
:
2022 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
2024 case POWERPC_MMU_BOOKE
:
2026 cpu_abort(env
, "BookE MMU model is not implemented\n");
2028 case POWERPC_MMU_BOOKE206
:
2030 cpu_abort(env
, "BookE 2.06 MMU model is not implemented\n");
2032 case POWERPC_MMU_32B
:
2033 case POWERPC_MMU_601
:
2034 /* tlbie invalidate TLBs for all segments */
2035 addr
&= ~((target_ulong
)-1ULL << 28);
2036 /* XXX: this case should be optimized,
2037 * giving a mask to tlb_flush_page
2039 tlb_flush_page(env
, addr
| (0x0 << 28));
2040 tlb_flush_page(env
, addr
| (0x1 << 28));
2041 tlb_flush_page(env
, addr
| (0x2 << 28));
2042 tlb_flush_page(env
, addr
| (0x3 << 28));
2043 tlb_flush_page(env
, addr
| (0x4 << 28));
2044 tlb_flush_page(env
, addr
| (0x5 << 28));
2045 tlb_flush_page(env
, addr
| (0x6 << 28));
2046 tlb_flush_page(env
, addr
| (0x7 << 28));
2047 tlb_flush_page(env
, addr
| (0x8 << 28));
2048 tlb_flush_page(env
, addr
| (0x9 << 28));
2049 tlb_flush_page(env
, addr
| (0xA << 28));
2050 tlb_flush_page(env
, addr
| (0xB << 28));
2051 tlb_flush_page(env
, addr
| (0xC << 28));
2052 tlb_flush_page(env
, addr
| (0xD << 28));
2053 tlb_flush_page(env
, addr
| (0xE << 28));
2054 tlb_flush_page(env
, addr
| (0xF << 28));
2056 #if defined(TARGET_PPC64)
2057 case POWERPC_MMU_620
:
2058 case POWERPC_MMU_64B
:
2059 case POWERPC_MMU_2_06
:
2060 /* tlbie invalidate TLBs for all segments */
2061 /* XXX: given the fact that there are too many segments to invalidate,
2062 * and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
2063 * we just invalidate all TLBs
2067 #endif /* defined(TARGET_PPC64) */
2070 cpu_abort(env
, "Unknown MMU model\n");
2074 ppc_tlb_invalidate_all(env
);
2078 /*****************************************************************************/
2079 /* Special registers manipulation */
2080 #if defined(TARGET_PPC64)
2081 void ppc_store_asr (CPUPPCState
*env
, target_ulong value
)
2083 if (env
->asr
!= value
) {
2090 void ppc_store_sdr1 (CPUPPCState
*env
, target_ulong value
)
2092 LOG_MMU("%s: " TARGET_FMT_lx
"\n", __func__
, value
);
2093 if (env
->spr
[SPR_SDR1
] != value
) {
2094 env
->spr
[SPR_SDR1
] = value
;
2095 #if defined(TARGET_PPC64)
2096 if (env
->mmu_model
& POWERPC_MMU_64
) {
2097 target_ulong htabsize
= value
& SDR_64_HTABSIZE
;
2099 if (htabsize
> 28) {
2100 fprintf(stderr
, "Invalid HTABSIZE 0x" TARGET_FMT_lx
2101 " stored in SDR1\n", htabsize
);
2104 env
->htab_mask
= (1ULL << (htabsize
+ 18)) - 1;
2105 env
->htab_base
= value
& SDR_64_HTABORG
;
2107 #endif /* defined(TARGET_PPC64) */
2109 /* FIXME: Should check for valid HTABMASK values */
2110 env
->htab_mask
= ((value
& SDR_32_HTABMASK
) << 16) | 0xFFFF;
2111 env
->htab_base
= value
& SDR_32_HTABORG
;
2117 #if defined(TARGET_PPC64)
2118 target_ulong
ppc_load_sr (CPUPPCState
*env
, int slb_nr
)
2125 void ppc_store_sr (CPUPPCState
*env
, int srnum
, target_ulong value
)
2127 LOG_MMU("%s: reg=%d " TARGET_FMT_lx
" " TARGET_FMT_lx
"\n", __func__
,
2128 srnum
, value
, env
->sr
[srnum
]);
2129 #if defined(TARGET_PPC64)
2130 if (env
->mmu_model
& POWERPC_MMU_64
) {
2131 uint64_t rb
= 0, rs
= 0;
2134 rb
|= ((uint32_t)srnum
& 0xf) << 28;
2135 /* Set the valid bit */
2138 rb
|= (uint32_t)srnum
;
2141 rs
|= (value
& 0xfffffff) << 12;
2143 rs
|= ((value
>> 27) & 0xf) << 9;
2145 ppc_store_slb(env
, rb
, rs
);
2148 if (env
->sr
[srnum
] != value
) {
2149 env
->sr
[srnum
] = value
;
2150 /* Invalidating 256MB of virtual memory in 4kB pages is way longer than
2151 flusing the whole TLB. */
2152 #if !defined(FLUSH_ALL_TLBS) && 0
2154 target_ulong page
, end
;
2155 /* Invalidate 256 MB of virtual memory */
2156 page
= (16 << 20) * srnum
;
2157 end
= page
+ (16 << 20);
2158 for (; page
!= end
; page
+= TARGET_PAGE_SIZE
)
2159 tlb_flush_page(env
, page
);
2166 #endif /* !defined (CONFIG_USER_ONLY) */
2168 /* GDBstub can read and write MSR... */
2169 void ppc_store_msr (CPUPPCState
*env
, target_ulong value
)
2171 hreg_store_msr(env
, value
, 0);
2174 /*****************************************************************************/
2175 /* Exception processing */
2176 #if defined (CONFIG_USER_ONLY)
2177 void do_interrupt (CPUState
*env
)
2179 env
->exception_index
= POWERPC_EXCP_NONE
;
2180 env
->error_code
= 0;
2183 void ppc_hw_interrupt (CPUState
*env
)
2185 env
->exception_index
= POWERPC_EXCP_NONE
;
2186 env
->error_code
= 0;
2188 #else /* defined (CONFIG_USER_ONLY) */
2189 static inline void dump_syscall(CPUState
*env
)
2191 qemu_log_mask(CPU_LOG_INT
, "syscall r0=%016" PRIx64
" r3=%016" PRIx64
2192 " r4=%016" PRIx64
" r5=%016" PRIx64
" r6=%016" PRIx64
2193 " nip=" TARGET_FMT_lx
"\n",
2194 ppc_dump_gpr(env
, 0), ppc_dump_gpr(env
, 3),
2195 ppc_dump_gpr(env
, 4), ppc_dump_gpr(env
, 5),
2196 ppc_dump_gpr(env
, 6), env
->nip
);
2199 /* Note that this function should be greatly optimized
2200 * when called with a constant excp, from ppc_hw_interrupt
2202 static inline void powerpc_excp(CPUState
*env
, int excp_model
, int excp
)
2204 target_ulong msr
, new_msr
, vector
;
2205 int srr0
, srr1
, asrr0
, asrr1
;
2206 int lpes0
, lpes1
, lev
;
2209 /* XXX: find a suitable condition to enable the hypervisor mode */
2210 lpes0
= (env
->spr
[SPR_LPCR
] >> 1) & 1;
2211 lpes1
= (env
->spr
[SPR_LPCR
] >> 2) & 1;
2213 /* Those values ensure we won't enter the hypervisor mode */
2218 qemu_log_mask(CPU_LOG_INT
, "Raise exception at " TARGET_FMT_lx
2219 " => %08x (%02x)\n", env
->nip
, excp
, env
->error_code
);
2221 /* new srr1 value excluding must-be-zero bits */
2222 msr
= env
->msr
& ~0x783f0000ULL
;
2224 /* new interrupt handler msr */
2225 new_msr
= env
->msr
& ((target_ulong
)1 << MSR_ME
);
2227 /* target registers */
2234 case POWERPC_EXCP_NONE
:
2235 /* Should never happen */
2237 case POWERPC_EXCP_CRITICAL
: /* Critical input */
2238 switch (excp_model
) {
2239 case POWERPC_EXCP_40x
:
2240 srr0
= SPR_40x_SRR2
;
2241 srr1
= SPR_40x_SRR3
;
2243 case POWERPC_EXCP_BOOKE
:
2244 srr0
= SPR_BOOKE_CSRR0
;
2245 srr1
= SPR_BOOKE_CSRR1
;
2247 case POWERPC_EXCP_G2
:
2253 case POWERPC_EXCP_MCHECK
: /* Machine check exception */
2255 /* Machine check exception is not enabled.
2256 * Enter checkstop state.
2258 if (qemu_log_enabled()) {
2259 qemu_log("Machine check while not allowed. "
2260 "Entering checkstop state\n");
2262 fprintf(stderr
, "Machine check while not allowed. "
2263 "Entering checkstop state\n");
2266 env
->interrupt_request
|= CPU_INTERRUPT_EXITTB
;
2269 /* XXX: find a suitable condition to enable the hypervisor mode */
2270 new_msr
|= (target_ulong
)MSR_HVB
;
2273 /* machine check exceptions don't have ME set */
2274 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2276 /* XXX: should also have something loaded in DAR / DSISR */
2277 switch (excp_model
) {
2278 case POWERPC_EXCP_40x
:
2279 srr0
= SPR_40x_SRR2
;
2280 srr1
= SPR_40x_SRR3
;
2282 case POWERPC_EXCP_BOOKE
:
2283 srr0
= SPR_BOOKE_MCSRR0
;
2284 srr1
= SPR_BOOKE_MCSRR1
;
2285 asrr0
= SPR_BOOKE_CSRR0
;
2286 asrr1
= SPR_BOOKE_CSRR1
;
2292 case POWERPC_EXCP_DSI
: /* Data storage exception */
2293 LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx
" DAR=" TARGET_FMT_lx
2294 "\n", env
->spr
[SPR_DSISR
], env
->spr
[SPR_DAR
]);
2296 new_msr
|= (target_ulong
)MSR_HVB
;
2298 case POWERPC_EXCP_ISI
: /* Instruction storage exception */
2299 LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx
", nip=" TARGET_FMT_lx
2300 "\n", msr
, env
->nip
);
2302 new_msr
|= (target_ulong
)MSR_HVB
;
2303 msr
|= env
->error_code
;
2305 case POWERPC_EXCP_EXTERNAL
: /* External input */
2307 new_msr
|= (target_ulong
)MSR_HVB
;
2309 case POWERPC_EXCP_ALIGN
: /* Alignment exception */
2311 new_msr
|= (target_ulong
)MSR_HVB
;
2312 /* XXX: this is false */
2313 /* Get rS/rD and rA from faulting opcode */
2314 env
->spr
[SPR_DSISR
] |= (ldl_code((env
->nip
- 4)) & 0x03FF0000) >> 16;
2316 case POWERPC_EXCP_PROGRAM
: /* Program exception */
2317 switch (env
->error_code
& ~0xF) {
2318 case POWERPC_EXCP_FP
:
2319 if ((msr_fe0
== 0 && msr_fe1
== 0) || msr_fp
== 0) {
2320 LOG_EXCP("Ignore floating point exception\n");
2321 env
->exception_index
= POWERPC_EXCP_NONE
;
2322 env
->error_code
= 0;
2326 new_msr
|= (target_ulong
)MSR_HVB
;
2328 if (msr_fe0
== msr_fe1
)
2332 case POWERPC_EXCP_INVAL
:
2333 LOG_EXCP("Invalid instruction at " TARGET_FMT_lx
"\n", env
->nip
);
2335 new_msr
|= (target_ulong
)MSR_HVB
;
2338 case POWERPC_EXCP_PRIV
:
2340 new_msr
|= (target_ulong
)MSR_HVB
;
2343 case POWERPC_EXCP_TRAP
:
2345 new_msr
|= (target_ulong
)MSR_HVB
;
2349 /* Should never occur */
2350 cpu_abort(env
, "Invalid program exception %d. Aborting\n",
2355 case POWERPC_EXCP_FPU
: /* Floating-point unavailable exception */
2357 new_msr
|= (target_ulong
)MSR_HVB
;
2359 case POWERPC_EXCP_SYSCALL
: /* System call exception */
2361 lev
= env
->error_code
;
2362 if ((lev
== 1) && cpu_ppc_hypercall
) {
2363 cpu_ppc_hypercall(env
);
2366 if (lev
== 1 || (lpes0
== 0 && lpes1
== 0))
2367 new_msr
|= (target_ulong
)MSR_HVB
;
2369 case POWERPC_EXCP_APU
: /* Auxiliary processor unavailable */
2371 case POWERPC_EXCP_DECR
: /* Decrementer exception */
2373 new_msr
|= (target_ulong
)MSR_HVB
;
2375 case POWERPC_EXCP_FIT
: /* Fixed-interval timer interrupt */
2377 LOG_EXCP("FIT exception\n");
2379 case POWERPC_EXCP_WDT
: /* Watchdog timer interrupt */
2380 LOG_EXCP("WDT exception\n");
2381 switch (excp_model
) {
2382 case POWERPC_EXCP_BOOKE
:
2383 srr0
= SPR_BOOKE_CSRR0
;
2384 srr1
= SPR_BOOKE_CSRR1
;
2390 case POWERPC_EXCP_DTLB
: /* Data TLB error */
2392 case POWERPC_EXCP_ITLB
: /* Instruction TLB error */
2394 case POWERPC_EXCP_DEBUG
: /* Debug interrupt */
2395 switch (excp_model
) {
2396 case POWERPC_EXCP_BOOKE
:
2397 srr0
= SPR_BOOKE_DSRR0
;
2398 srr1
= SPR_BOOKE_DSRR1
;
2399 asrr0
= SPR_BOOKE_CSRR0
;
2400 asrr1
= SPR_BOOKE_CSRR1
;
2406 cpu_abort(env
, "Debug exception is not implemented yet !\n");
2408 case POWERPC_EXCP_SPEU
: /* SPE/embedded floating-point unavailable */
2410 case POWERPC_EXCP_EFPDI
: /* Embedded floating-point data interrupt */
2412 cpu_abort(env
, "Embedded floating point data exception "
2413 "is not implemented yet !\n");
2415 case POWERPC_EXCP_EFPRI
: /* Embedded floating-point round interrupt */
2417 cpu_abort(env
, "Embedded floating point round exception "
2418 "is not implemented yet !\n");
2420 case POWERPC_EXCP_EPERFM
: /* Embedded performance monitor interrupt */
2423 "Performance counter exception is not implemented yet !\n");
2425 case POWERPC_EXCP_DOORI
: /* Embedded doorbell interrupt */
2428 "Embedded doorbell interrupt is not implemented yet !\n");
2430 case POWERPC_EXCP_DOORCI
: /* Embedded doorbell critical interrupt */
2431 switch (excp_model
) {
2432 case POWERPC_EXCP_BOOKE
:
2433 srr0
= SPR_BOOKE_CSRR0
;
2434 srr1
= SPR_BOOKE_CSRR1
;
2440 cpu_abort(env
, "Embedded doorbell critical interrupt "
2441 "is not implemented yet !\n");
2443 case POWERPC_EXCP_RESET
: /* System reset exception */
2445 /* indicate that we resumed from power save mode */
2448 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2452 /* XXX: find a suitable condition to enable the hypervisor mode */
2453 new_msr
|= (target_ulong
)MSR_HVB
;
2456 case POWERPC_EXCP_DSEG
: /* Data segment exception */
2458 new_msr
|= (target_ulong
)MSR_HVB
;
2460 case POWERPC_EXCP_ISEG
: /* Instruction segment exception */
2462 new_msr
|= (target_ulong
)MSR_HVB
;
2464 case POWERPC_EXCP_HDECR
: /* Hypervisor decrementer exception */
2467 new_msr
|= (target_ulong
)MSR_HVB
;
2468 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2470 case POWERPC_EXCP_TRACE
: /* Trace exception */
2472 new_msr
|= (target_ulong
)MSR_HVB
;
2474 case POWERPC_EXCP_HDSI
: /* Hypervisor data storage exception */
2477 new_msr
|= (target_ulong
)MSR_HVB
;
2478 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2480 case POWERPC_EXCP_HISI
: /* Hypervisor instruction storage exception */
2483 new_msr
|= (target_ulong
)MSR_HVB
;
2484 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2486 case POWERPC_EXCP_HDSEG
: /* Hypervisor data segment exception */
2489 new_msr
|= (target_ulong
)MSR_HVB
;
2490 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2492 case POWERPC_EXCP_HISEG
: /* Hypervisor instruction segment exception */
2495 new_msr
|= (target_ulong
)MSR_HVB
;
2496 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2498 case POWERPC_EXCP_VPU
: /* Vector unavailable exception */
2500 new_msr
|= (target_ulong
)MSR_HVB
;
2502 case POWERPC_EXCP_PIT
: /* Programmable interval timer interrupt */
2503 LOG_EXCP("PIT exception\n");
2505 case POWERPC_EXCP_IO
: /* IO error exception */
2507 cpu_abort(env
, "601 IO error exception is not implemented yet !\n");
2509 case POWERPC_EXCP_RUNM
: /* Run mode exception */
2511 cpu_abort(env
, "601 run mode exception is not implemented yet !\n");
2513 case POWERPC_EXCP_EMUL
: /* Emulation trap exception */
2515 cpu_abort(env
, "602 emulation trap exception "
2516 "is not implemented yet !\n");
2518 case POWERPC_EXCP_IFTLB
: /* Instruction fetch TLB error */
2519 if (lpes1
== 0) /* XXX: check this */
2520 new_msr
|= (target_ulong
)MSR_HVB
;
2521 switch (excp_model
) {
2522 case POWERPC_EXCP_602
:
2523 case POWERPC_EXCP_603
:
2524 case POWERPC_EXCP_603E
:
2525 case POWERPC_EXCP_G2
:
2527 case POWERPC_EXCP_7x5
:
2529 case POWERPC_EXCP_74xx
:
2532 cpu_abort(env
, "Invalid instruction TLB miss exception\n");
2536 case POWERPC_EXCP_DLTLB
: /* Data load TLB miss */
2537 if (lpes1
== 0) /* XXX: check this */
2538 new_msr
|= (target_ulong
)MSR_HVB
;
2539 switch (excp_model
) {
2540 case POWERPC_EXCP_602
:
2541 case POWERPC_EXCP_603
:
2542 case POWERPC_EXCP_603E
:
2543 case POWERPC_EXCP_G2
:
2545 case POWERPC_EXCP_7x5
:
2547 case POWERPC_EXCP_74xx
:
2550 cpu_abort(env
, "Invalid data load TLB miss exception\n");
2554 case POWERPC_EXCP_DSTLB
: /* Data store TLB miss */
2555 if (lpes1
== 0) /* XXX: check this */
2556 new_msr
|= (target_ulong
)MSR_HVB
;
2557 switch (excp_model
) {
2558 case POWERPC_EXCP_602
:
2559 case POWERPC_EXCP_603
:
2560 case POWERPC_EXCP_603E
:
2561 case POWERPC_EXCP_G2
:
2563 /* Swap temporary saved registers with GPRs */
2564 if (!(new_msr
& ((target_ulong
)1 << MSR_TGPR
))) {
2565 new_msr
|= (target_ulong
)1 << MSR_TGPR
;
2566 hreg_swap_gpr_tgpr(env
);
2569 case POWERPC_EXCP_7x5
:
2571 #if defined (DEBUG_SOFTWARE_TLB)
2572 if (qemu_log_enabled()) {
2574 target_ulong
*miss
, *cmp
;
2576 if (excp
== POWERPC_EXCP_IFTLB
) {
2579 miss
= &env
->spr
[SPR_IMISS
];
2580 cmp
= &env
->spr
[SPR_ICMP
];
2582 if (excp
== POWERPC_EXCP_DLTLB
)
2587 miss
= &env
->spr
[SPR_DMISS
];
2588 cmp
= &env
->spr
[SPR_DCMP
];
2590 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2591 TARGET_FMT_lx
" H1 " TARGET_FMT_lx
" H2 "
2592 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2593 env
->spr
[SPR_HASH1
], env
->spr
[SPR_HASH2
],
2597 msr
|= env
->crf
[0] << 28;
2598 msr
|= env
->error_code
; /* key, D/I, S/L bits */
2599 /* Set way using a LRU mechanism */
2600 msr
|= ((env
->last_way
+ 1) & (env
->nb_ways
- 1)) << 17;
2602 case POWERPC_EXCP_74xx
:
2604 #if defined (DEBUG_SOFTWARE_TLB)
2605 if (qemu_log_enabled()) {
2607 target_ulong
*miss
, *cmp
;
2609 if (excp
== POWERPC_EXCP_IFTLB
) {
2612 miss
= &env
->spr
[SPR_TLBMISS
];
2613 cmp
= &env
->spr
[SPR_PTEHI
];
2615 if (excp
== POWERPC_EXCP_DLTLB
)
2620 miss
= &env
->spr
[SPR_TLBMISS
];
2621 cmp
= &env
->spr
[SPR_PTEHI
];
2623 qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2624 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2628 msr
|= env
->error_code
; /* key bit */
2631 cpu_abort(env
, "Invalid data store TLB miss exception\n");
2635 case POWERPC_EXCP_FPA
: /* Floating-point assist exception */
2637 cpu_abort(env
, "Floating point assist exception "
2638 "is not implemented yet !\n");
2640 case POWERPC_EXCP_DABR
: /* Data address breakpoint */
2642 cpu_abort(env
, "DABR exception is not implemented yet !\n");
2644 case POWERPC_EXCP_IABR
: /* Instruction address breakpoint */
2646 cpu_abort(env
, "IABR exception is not implemented yet !\n");
2648 case POWERPC_EXCP_SMI
: /* System management interrupt */
2650 cpu_abort(env
, "SMI exception is not implemented yet !\n");
2652 case POWERPC_EXCP_THERM
: /* Thermal interrupt */
2654 cpu_abort(env
, "Thermal management exception "
2655 "is not implemented yet !\n");
2657 case POWERPC_EXCP_PERFM
: /* Embedded performance monitor interrupt */
2659 new_msr
|= (target_ulong
)MSR_HVB
;
2662 "Performance counter exception is not implemented yet !\n");
2664 case POWERPC_EXCP_VPUA
: /* Vector assist exception */
2666 cpu_abort(env
, "VPU assist exception is not implemented yet !\n");
2668 case POWERPC_EXCP_SOFTP
: /* Soft patch exception */
2671 "970 soft-patch exception is not implemented yet !\n");
2673 case POWERPC_EXCP_MAINT
: /* Maintenance exception */
2676 "970 maintenance exception is not implemented yet !\n");
2678 case POWERPC_EXCP_MEXTBR
: /* Maskable external breakpoint */
2680 cpu_abort(env
, "Maskable external exception "
2681 "is not implemented yet !\n");
2683 case POWERPC_EXCP_NMEXTBR
: /* Non maskable external breakpoint */
2685 cpu_abort(env
, "Non maskable external exception "
2686 "is not implemented yet !\n");
2690 cpu_abort(env
, "Invalid PowerPC exception %d. Aborting\n", excp
);
2693 /* save current instruction location */
2694 env
->spr
[srr0
] = env
->nip
- 4;
2697 /* save next instruction location */
2698 env
->spr
[srr0
] = env
->nip
;
2702 env
->spr
[srr1
] = msr
;
2703 /* If any alternate SRR register are defined, duplicate saved values */
2705 env
->spr
[asrr0
] = env
->spr
[srr0
];
2707 env
->spr
[asrr1
] = env
->spr
[srr1
];
2708 /* If we disactivated any translation, flush TLBs */
2709 if (new_msr
& ((1 << MSR_IR
) | (1 << MSR_DR
)))
2713 new_msr
|= (target_ulong
)1 << MSR_LE
;
2716 /* Jump to handler */
2717 vector
= env
->excp_vectors
[excp
];
2718 if (vector
== (target_ulong
)-1ULL) {
2719 cpu_abort(env
, "Raised an exception without defined vector %d\n",
2722 vector
|= env
->excp_prefix
;
2723 #if defined(TARGET_PPC64)
2724 if (excp_model
== POWERPC_EXCP_BOOKE
) {
2726 vector
= (uint32_t)vector
;
2728 new_msr
|= (target_ulong
)1 << MSR_CM
;
2731 if (!msr_isf
&& !(env
->mmu_model
& POWERPC_MMU_64
)) {
2732 vector
= (uint32_t)vector
;
2734 new_msr
|= (target_ulong
)1 << MSR_SF
;
2738 /* XXX: we don't use hreg_store_msr here as already have treated
2739 * any special case that could occur. Just store MSR and update hflags
2741 env
->msr
= new_msr
& env
->msr_mask
;
2742 hreg_compute_hflags(env
);
2744 /* Reset exception state */
2745 env
->exception_index
= POWERPC_EXCP_NONE
;
2746 env
->error_code
= 0;
2748 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
2749 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
2750 /* XXX: The BookE changes address space when switching modes,
2751 we should probably implement that as different MMU indexes,
2752 but for the moment we do it the slow way and flush all. */
2757 void do_interrupt (CPUState
*env
)
2759 powerpc_excp(env
, env
->excp_model
, env
->exception_index
);
2762 void ppc_hw_interrupt (CPUPPCState
*env
)
2767 qemu_log_mask(CPU_LOG_INT
, "%s: %p pending %08x req %08x me %d ee %d\n",
2768 __func__
, env
, env
->pending_interrupts
,
2769 env
->interrupt_request
, (int)msr_me
, (int)msr_ee
);
2771 /* External reset */
2772 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_RESET
)) {
2773 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_RESET
);
2774 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_RESET
);
2777 /* Machine check exception */
2778 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_MCK
)) {
2779 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_MCK
);
2780 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_MCHECK
);
2784 /* External debug exception */
2785 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DEBUG
)) {
2786 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DEBUG
);
2787 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DEBUG
);
2792 /* XXX: find a suitable condition to enable the hypervisor mode */
2793 hdice
= env
->spr
[SPR_LPCR
] & 1;
2797 if ((msr_ee
!= 0 || msr_hv
== 0 || msr_pr
!= 0) && hdice
!= 0) {
2798 /* Hypervisor decrementer exception */
2799 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_HDECR
)) {
2800 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_HDECR
);
2801 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_HDECR
);
2806 /* External critical interrupt */
2807 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CEXT
)) {
2808 /* Taking a critical external interrupt does not clear the external
2809 * critical interrupt status
2812 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CEXT
);
2814 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_CRITICAL
);
2819 /* Watchdog timer on embedded PowerPC */
2820 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_WDT
)) {
2821 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_WDT
);
2822 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_WDT
);
2825 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CDOORBELL
)) {
2826 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CDOORBELL
);
2827 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORCI
);
2830 /* Fixed interval timer on embedded PowerPC */
2831 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_FIT
)) {
2832 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_FIT
);
2833 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_FIT
);
2836 /* Programmable interval timer on embedded PowerPC */
2837 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PIT
)) {
2838 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PIT
);
2839 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PIT
);
2842 /* Decrementer exception */
2843 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DECR
)) {
2844 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DECR
);
2845 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DECR
);
2848 /* External interrupt */
2849 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_EXT
)) {
2850 /* Taking an external interrupt does not clear the external
2854 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_EXT
);
2856 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_EXTERNAL
);
2859 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DOORBELL
)) {
2860 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DOORBELL
);
2861 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORI
);
2864 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PERFM
)) {
2865 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PERFM
);
2866 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PERFM
);
2869 /* Thermal interrupt */
2870 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_THERM
)) {
2871 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_THERM
);
2872 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_THERM
);
2877 #endif /* !CONFIG_USER_ONLY */
2879 void cpu_dump_rfi (target_ulong RA
, target_ulong msr
)
2881 qemu_log("Return from exception at " TARGET_FMT_lx
" with flags "
2882 TARGET_FMT_lx
"\n", RA
, msr
);
2885 void cpu_reset(CPUPPCState
*env
)
2889 if (qemu_loglevel_mask(CPU_LOG_RESET
)) {
2890 qemu_log("CPU Reset (CPU %d)\n", env
->cpu_index
);
2891 log_cpu_state(env
, 0);
2894 msr
= (target_ulong
)0;
2896 /* XXX: find a suitable condition to enable the hypervisor mode */
2897 msr
|= (target_ulong
)MSR_HVB
;
2899 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
2900 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
2901 msr
|= (target_ulong
)1 << MSR_EP
;
2902 #if defined (DO_SINGLE_STEP) && 0
2903 /* Single step trace mode */
2904 msr
|= (target_ulong
)1 << MSR_SE
;
2905 msr
|= (target_ulong
)1 << MSR_BE
;
2907 #if defined(CONFIG_USER_ONLY)
2908 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
2909 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
2910 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
2911 msr
|= (target_ulong
)1 << MSR_PR
;
2913 env
->excp_prefix
= env
->hreset_excp_prefix
;
2914 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
2915 if (env
->mmu_model
!= POWERPC_MMU_REAL
)
2916 ppc_tlb_invalidate_all(env
);
2918 env
->msr
= msr
& env
->msr_mask
;
2919 #if defined(TARGET_PPC64)
2920 if (env
->mmu_model
& POWERPC_MMU_64
)
2921 env
->msr
|= (1ULL << MSR_SF
);
2923 hreg_compute_hflags(env
);
2924 env
->reserve_addr
= (target_ulong
)-1ULL;
2925 /* Be sure no exception or interrupt is pending */
2926 env
->pending_interrupts
= 0;
2927 env
->exception_index
= POWERPC_EXCP_NONE
;
2928 env
->error_code
= 0;
2929 /* Flush all TLBs */
2933 CPUPPCState
*cpu_ppc_init (const char *cpu_model
)
2936 const ppc_def_t
*def
;
2938 def
= cpu_ppc_find_by_name(cpu_model
);
2942 env
= qemu_mallocz(sizeof(CPUPPCState
));
2944 ppc_translate_init();
2945 env
->cpu_model_str
= cpu_model
;
2946 cpu_ppc_register_internal(env
, def
);
2948 qemu_init_vcpu(env
);
2953 void cpu_ppc_close (CPUPPCState
*env
)
2955 /* Should also remove all opcode tables... */