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_off
+ (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_off
+ (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
"\n", env
->htab_base
,
922 env
->htab_mask
, vsid
, ctx
->ptem
, ctx
->hash
[1]);
923 ret2
= find_pte(env
, ctx
, 1, rw
, type
,
929 #if defined (DUMP_PAGE_TABLES)
930 if (qemu_log_enabled()) {
931 target_phys_addr_t curaddr
;
932 uint32_t a0
, a1
, a2
, a3
;
933 qemu_log("Page table: " TARGET_FMT_plx
" len " TARGET_FMT_plx
934 "\n", sdr
, mask
+ 0x80);
935 for (curaddr
= sdr
; curaddr
< (sdr
+ mask
+ 0x80);
937 a0
= ldl_phys(curaddr
);
938 a1
= ldl_phys(curaddr
+ 4);
939 a2
= ldl_phys(curaddr
+ 8);
940 a3
= ldl_phys(curaddr
+ 12);
941 if (a0
!= 0 || a1
!= 0 || a2
!= 0 || a3
!= 0) {
942 qemu_log(TARGET_FMT_plx
": %08x %08x %08x %08x\n",
943 curaddr
, a0
, a1
, a2
, a3
);
949 LOG_MMU("No access allowed\n");
953 LOG_MMU("direct store...\n");
954 /* Direct-store segment : absolutely *BUGGY* for now */
957 /* Integer load/store : only access allowed */
960 /* No code fetch is allowed in direct-store areas */
963 /* Floating point load/store */
966 /* lwarx, ldarx or srwcx. */
969 /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
970 /* Should make the instruction do no-op.
971 * As it already do no-op, it's quite easy :-)
979 qemu_log("ERROR: instruction should not need "
980 "address translation\n");
983 if ((rw
== 1 || ctx
->key
!= 1) && (rw
== 0 || ctx
->key
!= 0)) {
994 /* Generic TLB check function for embedded PowerPC implementations */
995 int ppcemb_tlb_check(CPUState
*env
, ppcemb_tlb_t
*tlb
,
996 target_phys_addr_t
*raddrp
,
997 target_ulong address
, uint32_t pid
, int ext
,
1002 /* Check valid flag */
1003 if (!(tlb
->prot
& PAGE_VALID
)) {
1006 mask
= ~(tlb
->size
- 1);
1007 LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx
" PID %u <=> " TARGET_FMT_lx
1008 " " TARGET_FMT_lx
" %u %x\n", __func__
, i
, address
, pid
, tlb
->EPN
,
1009 mask
, (uint32_t)tlb
->PID
, tlb
->prot
);
1011 if (tlb
->PID
!= 0 && tlb
->PID
!= pid
)
1013 /* Check effective address */
1014 if ((address
& mask
) != tlb
->EPN
)
1016 *raddrp
= (tlb
->RPN
& mask
) | (address
& ~mask
);
1017 #if (TARGET_PHYS_ADDR_BITS >= 36)
1019 /* Extend the physical address to 36 bits */
1020 *raddrp
|= (target_phys_addr_t
)(tlb
->RPN
& 0xF) << 32;
1027 /* Generic TLB search function for PowerPC embedded implementations */
1028 int ppcemb_tlb_search (CPUPPCState
*env
, target_ulong address
, uint32_t pid
)
1031 target_phys_addr_t raddr
;
1034 /* Default return value is no match */
1036 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1037 tlb
= &env
->tlb
[i
].tlbe
;
1038 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
, pid
, 0, i
) == 0) {
1047 /* Helpers specific to PowerPC 40x implementations */
1048 static inline void ppc4xx_tlb_invalidate_all(CPUState
*env
)
1053 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1054 tlb
= &env
->tlb
[i
].tlbe
;
1055 tlb
->prot
&= ~PAGE_VALID
;
1060 static inline void ppc4xx_tlb_invalidate_virt(CPUState
*env
,
1061 target_ulong eaddr
, uint32_t pid
)
1063 #if !defined(FLUSH_ALL_TLBS)
1065 target_phys_addr_t raddr
;
1066 target_ulong page
, end
;
1069 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1070 tlb
= &env
->tlb
[i
].tlbe
;
1071 if (ppcemb_tlb_check(env
, tlb
, &raddr
, eaddr
, pid
, 0, i
) == 0) {
1072 end
= tlb
->EPN
+ tlb
->size
;
1073 for (page
= tlb
->EPN
; page
< end
; page
+= TARGET_PAGE_SIZE
)
1074 tlb_flush_page(env
, page
);
1075 tlb
->prot
&= ~PAGE_VALID
;
1080 ppc4xx_tlb_invalidate_all(env
);
1084 static int mmu40x_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1085 target_ulong address
, int rw
, int access_type
)
1088 target_phys_addr_t raddr
;
1089 int i
, ret
, zsel
, zpr
, pr
;
1092 raddr
= (target_phys_addr_t
)-1ULL;
1094 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1095 tlb
= &env
->tlb
[i
].tlbe
;
1096 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
,
1097 env
->spr
[SPR_40x_PID
], 0, i
) < 0)
1099 zsel
= (tlb
->attr
>> 4) & 0xF;
1100 zpr
= (env
->spr
[SPR_40x_ZPR
] >> (30 - (2 * zsel
))) & 0x3;
1101 LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1102 __func__
, i
, zsel
, zpr
, rw
, tlb
->attr
);
1103 /* Check execute enable bit */
1110 /* All accesses granted */
1111 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
1116 /* Raise Zone protection fault. */
1117 env
->spr
[SPR_40x_ESR
] = 1 << 22;
1125 /* Check from TLB entry */
1126 ctx
->prot
= tlb
->prot
;
1127 ret
= check_prot(ctx
->prot
, rw
, access_type
);
1129 env
->spr
[SPR_40x_ESR
] = 0;
1134 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1135 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1140 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1141 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1146 void store_40x_sler (CPUPPCState
*env
, uint32_t val
)
1148 /* XXX: TO BE FIXED */
1149 if (val
!= 0x00000000) {
1150 cpu_abort(env
, "Little-endian regions are not supported by now\n");
1152 env
->spr
[SPR_405_SLER
] = val
;
1155 static inline int mmubooke_check_tlb (CPUState
*env
, ppcemb_tlb_t
*tlb
,
1156 target_phys_addr_t
*raddr
, int *prot
,
1157 target_ulong address
, int rw
,
1158 int access_type
, int i
)
1162 if (ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1163 env
->spr
[SPR_BOOKE_PID
],
1164 !env
->nb_pids
, i
) >= 0) {
1168 if (env
->spr
[SPR_BOOKE_PID1
] &&
1169 ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1170 env
->spr
[SPR_BOOKE_PID1
], 0, i
) >= 0) {
1174 if (env
->spr
[SPR_BOOKE_PID2
] &&
1175 ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1176 env
->spr
[SPR_BOOKE_PID2
], 0, i
) >= 0) {
1180 LOG_SWTLB("%s: TLB entry not found\n", __func__
);
1186 _prot
= tlb
->prot
& 0xF;
1188 _prot
= (tlb
->prot
>> 4) & 0xF;
1191 /* Check the address space */
1192 if (access_type
== ACCESS_CODE
) {
1193 if (msr_ir
!= (tlb
->attr
& 1)) {
1194 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1199 if (_prot
& PAGE_EXEC
) {
1200 LOG_SWTLB("%s: good TLB!\n", __func__
);
1204 LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__
, _prot
);
1207 if (msr_dr
!= (tlb
->attr
& 1)) {
1208 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1213 if ((!rw
&& _prot
& PAGE_READ
) || (rw
&& (_prot
& PAGE_WRITE
))) {
1214 LOG_SWTLB("%s: found TLB!\n", __func__
);
1218 LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__
, _prot
);
1225 static int mmubooke_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1226 target_ulong address
, int rw
,
1230 target_phys_addr_t raddr
;
1234 raddr
= (target_phys_addr_t
)-1ULL;
1235 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1236 tlb
= &env
->tlb
[i
].tlbe
;
1237 ret
= mmubooke_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
, rw
,
1246 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1247 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1250 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1251 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1257 void booke206_flush_tlb(CPUState
*env
, int flags
, const int check_iprot
)
1261 ppc_tlb_t
*tlb
= env
->tlb
;
1263 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1264 if (flags
& (1 << i
)) {
1265 tlb_size
= booke206_tlb_size(env
, i
);
1266 for (j
= 0; j
< tlb_size
; j
++) {
1267 if (!check_iprot
|| !(tlb
[j
].tlbe
.attr
& MAS1_IPROT
)) {
1268 tlb
[j
].tlbe
.prot
= 0;
1272 tlb
+= booke206_tlb_size(env
, i
);
1278 static int mmubooke206_get_physical_address(CPUState
*env
, mmu_ctx_t
*ctx
,
1279 target_ulong address
, int rw
,
1283 target_phys_addr_t raddr
;
1287 raddr
= (target_phys_addr_t
)-1ULL;
1289 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1290 int ways
= booke206_tlb_ways(env
, i
);
1292 for (j
= 0; j
< ways
; j
++) {
1293 tlb
= booke206_get_tlbe(env
, i
, address
, j
);
1294 ret
= mmubooke_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
, rw
,
1306 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1307 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1310 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1311 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1317 static inline int check_physical(CPUState
*env
, mmu_ctx_t
*ctx
,
1318 target_ulong eaddr
, int rw
)
1323 ctx
->prot
= PAGE_READ
| PAGE_EXEC
;
1325 switch (env
->mmu_model
) {
1326 case POWERPC_MMU_32B
:
1327 case POWERPC_MMU_601
:
1328 case POWERPC_MMU_SOFT_6xx
:
1329 case POWERPC_MMU_SOFT_74xx
:
1330 case POWERPC_MMU_SOFT_4xx
:
1331 case POWERPC_MMU_REAL
:
1332 case POWERPC_MMU_BOOKE
:
1333 ctx
->prot
|= PAGE_WRITE
;
1335 #if defined(TARGET_PPC64)
1336 case POWERPC_MMU_620
:
1337 case POWERPC_MMU_64B
:
1338 case POWERPC_MMU_2_06
:
1339 /* Real address are 60 bits long */
1340 ctx
->raddr
&= 0x0FFFFFFFFFFFFFFFULL
;
1341 ctx
->prot
|= PAGE_WRITE
;
1344 case POWERPC_MMU_SOFT_4xx_Z
:
1345 if (unlikely(msr_pe
!= 0)) {
1346 /* 403 family add some particular protections,
1347 * using PBL/PBU registers for accesses with no translation.
1350 /* Check PLB validity */
1351 (env
->pb
[0] < env
->pb
[1] &&
1352 /* and address in plb area */
1353 eaddr
>= env
->pb
[0] && eaddr
< env
->pb
[1]) ||
1354 (env
->pb
[2] < env
->pb
[3] &&
1355 eaddr
>= env
->pb
[2] && eaddr
< env
->pb
[3]) ? 1 : 0;
1356 if (in_plb
^ msr_px
) {
1357 /* Access in protected area */
1359 /* Access is not allowed */
1363 /* Read-write access is allowed */
1364 ctx
->prot
|= PAGE_WRITE
;
1368 case POWERPC_MMU_MPC8xx
:
1370 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1372 case POWERPC_MMU_BOOKE206
:
1373 cpu_abort(env
, "BookE 2.06 MMU doesn't have physical real mode\n");
1376 cpu_abort(env
, "Unknown or invalid MMU model\n");
1383 int get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
, target_ulong eaddr
,
1384 int rw
, int access_type
)
1389 qemu_log("%s\n", __func__
);
1391 if ((access_type
== ACCESS_CODE
&& msr_ir
== 0) ||
1392 (access_type
!= ACCESS_CODE
&& msr_dr
== 0)) {
1393 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1394 /* The BookE MMU always performs address translation. The
1395 IS and DS bits only affect the address space. */
1396 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1398 } else if (env
->mmu_model
== POWERPC_MMU_BOOKE206
) {
1399 ret
= mmubooke206_get_physical_address(env
, ctx
, eaddr
, rw
,
1402 /* No address translation. */
1403 ret
= check_physical(env
, ctx
, eaddr
, rw
);
1407 switch (env
->mmu_model
) {
1408 case POWERPC_MMU_32B
:
1409 case POWERPC_MMU_601
:
1410 case POWERPC_MMU_SOFT_6xx
:
1411 case POWERPC_MMU_SOFT_74xx
:
1412 /* Try to find a BAT */
1413 if (env
->nb_BATs
!= 0)
1414 ret
= get_bat(env
, ctx
, eaddr
, rw
, access_type
);
1415 #if defined(TARGET_PPC64)
1416 case POWERPC_MMU_620
:
1417 case POWERPC_MMU_64B
:
1418 case POWERPC_MMU_2_06
:
1421 /* We didn't match any BAT entry or don't have BATs */
1422 ret
= get_segment(env
, ctx
, eaddr
, rw
, access_type
);
1425 case POWERPC_MMU_SOFT_4xx
:
1426 case POWERPC_MMU_SOFT_4xx_Z
:
1427 ret
= mmu40x_get_physical_address(env
, ctx
, eaddr
,
1430 case POWERPC_MMU_BOOKE
:
1431 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1434 case POWERPC_MMU_BOOKE206
:
1435 ret
= mmubooke206_get_physical_address(env
, ctx
, eaddr
, rw
,
1438 case POWERPC_MMU_MPC8xx
:
1440 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1442 case POWERPC_MMU_REAL
:
1443 cpu_abort(env
, "PowerPC in real mode do not do any translation\n");
1446 cpu_abort(env
, "Unknown or invalid MMU model\n");
1451 qemu_log("%s address " TARGET_FMT_lx
" => %d " TARGET_FMT_plx
"\n",
1452 __func__
, eaddr
, ret
, ctx
->raddr
);
1458 target_phys_addr_t
cpu_get_phys_page_debug (CPUState
*env
, target_ulong addr
)
1462 if (unlikely(get_physical_address(env
, &ctx
, addr
, 0, ACCESS_INT
) != 0))
1465 return ctx
.raddr
& TARGET_PAGE_MASK
;
1468 static void booke206_update_mas_tlb_miss(CPUState
*env
, target_ulong address
,
1471 env
->spr
[SPR_BOOKE_MAS0
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TLBSELD_MASK
;
1472 env
->spr
[SPR_BOOKE_MAS1
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TSIZED_MASK
;
1473 env
->spr
[SPR_BOOKE_MAS2
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_WIMGED_MASK
;
1474 env
->spr
[SPR_BOOKE_MAS3
] = 0;
1475 env
->spr
[SPR_BOOKE_MAS6
] = 0;
1476 env
->spr
[SPR_BOOKE_MAS7
] = 0;
1479 if (((rw
== 2) && msr_ir
) || ((rw
!= 2) && msr_dr
)) {
1480 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_TS
;
1481 env
->spr
[SPR_BOOKE_MAS6
] |= MAS6_SAS
;
1484 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_VALID
;
1485 env
->spr
[SPR_BOOKE_MAS2
] |= address
& MAS2_EPN_MASK
;
1487 switch (env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TIDSELD_PIDZ
) {
1488 case MAS4_TIDSELD_PID0
:
1489 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID
] << MAS1_TID_SHIFT
;
1491 case MAS4_TIDSELD_PID1
:
1492 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID1
] << MAS1_TID_SHIFT
;
1494 case MAS4_TIDSELD_PID2
:
1495 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID2
] << MAS1_TID_SHIFT
;
1499 env
->spr
[SPR_BOOKE_MAS6
] |= env
->spr
[SPR_BOOKE_PID
] << 16;
1501 /* next victim logic */
1502 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_ESEL_SHIFT
;
1504 env
->last_way
&= booke206_tlb_ways(env
, 0) - 1;
1505 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_NV_SHIFT
;
1508 /* Perform address translation */
1509 int cpu_ppc_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
1510 int mmu_idx
, int is_softmmu
)
1519 access_type
= ACCESS_CODE
;
1522 access_type
= env
->access_type
;
1524 ret
= get_physical_address(env
, &ctx
, address
, rw
, access_type
);
1526 tlb_set_page(env
, address
& TARGET_PAGE_MASK
,
1527 ctx
.raddr
& TARGET_PAGE_MASK
, ctx
.prot
,
1528 mmu_idx
, TARGET_PAGE_SIZE
);
1530 } else if (ret
< 0) {
1532 if (access_type
== ACCESS_CODE
) {
1535 /* No matches in page tables or TLB */
1536 switch (env
->mmu_model
) {
1537 case POWERPC_MMU_SOFT_6xx
:
1538 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1539 env
->error_code
= 1 << 18;
1540 env
->spr
[SPR_IMISS
] = address
;
1541 env
->spr
[SPR_ICMP
] = 0x80000000 | ctx
.ptem
;
1543 case POWERPC_MMU_SOFT_74xx
:
1544 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1546 case POWERPC_MMU_SOFT_4xx
:
1547 case POWERPC_MMU_SOFT_4xx_Z
:
1548 env
->exception_index
= POWERPC_EXCP_ITLB
;
1549 env
->error_code
= 0;
1550 env
->spr
[SPR_40x_DEAR
] = address
;
1551 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1553 case POWERPC_MMU_32B
:
1554 case POWERPC_MMU_601
:
1555 #if defined(TARGET_PPC64)
1556 case POWERPC_MMU_620
:
1557 case POWERPC_MMU_64B
:
1558 case POWERPC_MMU_2_06
:
1560 env
->exception_index
= POWERPC_EXCP_ISI
;
1561 env
->error_code
= 0x40000000;
1563 case POWERPC_MMU_BOOKE206
:
1564 booke206_update_mas_tlb_miss(env
, address
, rw
);
1566 case POWERPC_MMU_BOOKE
:
1567 env
->exception_index
= POWERPC_EXCP_ITLB
;
1568 env
->error_code
= 0;
1569 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1571 case POWERPC_MMU_MPC8xx
:
1573 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1575 case POWERPC_MMU_REAL
:
1576 cpu_abort(env
, "PowerPC in real mode should never raise "
1577 "any MMU exceptions\n");
1580 cpu_abort(env
, "Unknown or invalid MMU model\n");
1585 /* Access rights violation */
1586 env
->exception_index
= POWERPC_EXCP_ISI
;
1587 env
->error_code
= 0x08000000;
1590 /* No execute protection violation */
1591 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1592 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1593 env
->spr
[SPR_BOOKE_ESR
] = 0x00000000;
1595 env
->exception_index
= POWERPC_EXCP_ISI
;
1596 env
->error_code
= 0x10000000;
1599 /* Direct store exception */
1600 /* No code fetch is allowed in direct-store areas */
1601 env
->exception_index
= POWERPC_EXCP_ISI
;
1602 env
->error_code
= 0x10000000;
1604 #if defined(TARGET_PPC64)
1606 /* No match in segment table */
1607 if (env
->mmu_model
== POWERPC_MMU_620
) {
1608 env
->exception_index
= POWERPC_EXCP_ISI
;
1609 /* XXX: this might be incorrect */
1610 env
->error_code
= 0x40000000;
1612 env
->exception_index
= POWERPC_EXCP_ISEG
;
1613 env
->error_code
= 0;
1621 /* No matches in page tables or TLB */
1622 switch (env
->mmu_model
) {
1623 case POWERPC_MMU_SOFT_6xx
:
1625 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1626 env
->error_code
= 1 << 16;
1628 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1629 env
->error_code
= 0;
1631 env
->spr
[SPR_DMISS
] = address
;
1632 env
->spr
[SPR_DCMP
] = 0x80000000 | ctx
.ptem
;
1634 env
->error_code
|= ctx
.key
<< 19;
1635 env
->spr
[SPR_HASH1
] = env
->htab_base
+
1636 get_pteg_offset(env
, ctx
.hash
[0], HASH_PTE_SIZE_32
);
1637 env
->spr
[SPR_HASH2
] = env
->htab_base
+
1638 get_pteg_offset(env
, ctx
.hash
[1], HASH_PTE_SIZE_32
);
1640 case POWERPC_MMU_SOFT_74xx
:
1642 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1644 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1647 /* Implement LRU algorithm */
1648 env
->error_code
= ctx
.key
<< 19;
1649 env
->spr
[SPR_TLBMISS
] = (address
& ~((target_ulong
)0x3)) |
1650 ((env
->last_way
+ 1) & (env
->nb_ways
- 1));
1651 env
->spr
[SPR_PTEHI
] = 0x80000000 | ctx
.ptem
;
1653 case POWERPC_MMU_SOFT_4xx
:
1654 case POWERPC_MMU_SOFT_4xx_Z
:
1655 env
->exception_index
= POWERPC_EXCP_DTLB
;
1656 env
->error_code
= 0;
1657 env
->spr
[SPR_40x_DEAR
] = address
;
1659 env
->spr
[SPR_40x_ESR
] = 0x00800000;
1661 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1663 case POWERPC_MMU_32B
:
1664 case POWERPC_MMU_601
:
1665 #if defined(TARGET_PPC64)
1666 case POWERPC_MMU_620
:
1667 case POWERPC_MMU_64B
:
1668 case POWERPC_MMU_2_06
:
1670 env
->exception_index
= POWERPC_EXCP_DSI
;
1671 env
->error_code
= 0;
1672 env
->spr
[SPR_DAR
] = address
;
1674 env
->spr
[SPR_DSISR
] = 0x42000000;
1676 env
->spr
[SPR_DSISR
] = 0x40000000;
1678 case POWERPC_MMU_MPC8xx
:
1680 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1682 case POWERPC_MMU_BOOKE206
:
1683 booke206_update_mas_tlb_miss(env
, address
, rw
);
1685 case POWERPC_MMU_BOOKE
:
1686 env
->exception_index
= POWERPC_EXCP_DTLB
;
1687 env
->error_code
= 0;
1688 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1689 env
->spr
[SPR_BOOKE_ESR
] = rw
? 1 << ESR_ST
: 0;
1691 case POWERPC_MMU_REAL
:
1692 cpu_abort(env
, "PowerPC in real mode should never raise "
1693 "any MMU exceptions\n");
1696 cpu_abort(env
, "Unknown or invalid MMU model\n");
1701 /* Access rights violation */
1702 env
->exception_index
= POWERPC_EXCP_DSI
;
1703 env
->error_code
= 0;
1704 if (env
->mmu_model
== POWERPC_MMU_SOFT_4xx
1705 || env
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
) {
1706 env
->spr
[SPR_40x_DEAR
] = address
;
1708 env
->spr
[SPR_40x_ESR
] |= 0x00800000;
1710 } else if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1711 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1712 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1713 env
->spr
[SPR_BOOKE_ESR
] = rw
? 1 << ESR_ST
: 0;
1715 env
->spr
[SPR_DAR
] = address
;
1717 env
->spr
[SPR_DSISR
] = 0x0A000000;
1719 env
->spr
[SPR_DSISR
] = 0x08000000;
1724 /* Direct store exception */
1725 switch (access_type
) {
1727 /* Floating point load/store */
1728 env
->exception_index
= POWERPC_EXCP_ALIGN
;
1729 env
->error_code
= POWERPC_EXCP_ALIGN_FP
;
1730 env
->spr
[SPR_DAR
] = address
;
1733 /* lwarx, ldarx or stwcx. */
1734 env
->exception_index
= POWERPC_EXCP_DSI
;
1735 env
->error_code
= 0;
1736 env
->spr
[SPR_DAR
] = address
;
1738 env
->spr
[SPR_DSISR
] = 0x06000000;
1740 env
->spr
[SPR_DSISR
] = 0x04000000;
1743 /* eciwx or ecowx */
1744 env
->exception_index
= POWERPC_EXCP_DSI
;
1745 env
->error_code
= 0;
1746 env
->spr
[SPR_DAR
] = address
;
1748 env
->spr
[SPR_DSISR
] = 0x06100000;
1750 env
->spr
[SPR_DSISR
] = 0x04100000;
1753 printf("DSI: invalid exception (%d)\n", ret
);
1754 env
->exception_index
= POWERPC_EXCP_PROGRAM
;
1756 POWERPC_EXCP_INVAL
| POWERPC_EXCP_INVAL_INVAL
;
1757 env
->spr
[SPR_DAR
] = address
;
1761 #if defined(TARGET_PPC64)
1763 /* No match in segment table */
1764 if (env
->mmu_model
== POWERPC_MMU_620
) {
1765 env
->exception_index
= POWERPC_EXCP_DSI
;
1766 env
->error_code
= 0;
1767 env
->spr
[SPR_DAR
] = address
;
1768 /* XXX: this might be incorrect */
1770 env
->spr
[SPR_DSISR
] = 0x42000000;
1772 env
->spr
[SPR_DSISR
] = 0x40000000;
1774 env
->exception_index
= POWERPC_EXCP_DSEG
;
1775 env
->error_code
= 0;
1776 env
->spr
[SPR_DAR
] = address
;
1783 printf("%s: set exception to %d %02x\n", __func__
,
1784 env
->exception
, env
->error_code
);
1792 /*****************************************************************************/
1793 /* BATs management */
1794 #if !defined(FLUSH_ALL_TLBS)
1795 static inline void do_invalidate_BAT(CPUPPCState
*env
, target_ulong BATu
,
1798 target_ulong base
, end
, page
;
1800 base
= BATu
& ~0x0001FFFF;
1801 end
= base
+ mask
+ 0x00020000;
1802 LOG_BATS("Flush BAT from " TARGET_FMT_lx
" to " TARGET_FMT_lx
" ("
1803 TARGET_FMT_lx
")\n", base
, end
, mask
);
1804 for (page
= base
; page
!= end
; page
+= TARGET_PAGE_SIZE
)
1805 tlb_flush_page(env
, page
);
1806 LOG_BATS("Flush done\n");
1810 static inline void dump_store_bat(CPUPPCState
*env
, char ID
, int ul
, int nr
,
1813 LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx
" (" TARGET_FMT_lx
")\n", ID
,
1814 nr
, ul
== 0 ? 'u' : 'l', value
, env
->nip
);
1817 void ppc_store_ibatu (CPUPPCState
*env
, int nr
, target_ulong value
)
1821 dump_store_bat(env
, 'I', 0, nr
, value
);
1822 if (env
->IBAT
[0][nr
] != value
) {
1823 mask
= (value
<< 15) & 0x0FFE0000UL
;
1824 #if !defined(FLUSH_ALL_TLBS)
1825 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1827 /* When storing valid upper BAT, mask BEPI and BRPN
1828 * and invalidate all TLBs covered by this BAT
1830 mask
= (value
<< 15) & 0x0FFE0000UL
;
1831 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1832 (value
& ~0x0001FFFFUL
& ~mask
);
1833 env
->IBAT
[1][nr
] = (env
->IBAT
[1][nr
] & 0x0000007B) |
1834 (env
->IBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
1835 #if !defined(FLUSH_ALL_TLBS)
1836 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1843 void ppc_store_ibatl (CPUPPCState
*env
, int nr
, target_ulong value
)
1845 dump_store_bat(env
, 'I', 1, nr
, value
);
1846 env
->IBAT
[1][nr
] = value
;
1849 void ppc_store_dbatu (CPUPPCState
*env
, int nr
, target_ulong value
)
1853 dump_store_bat(env
, 'D', 0, nr
, value
);
1854 if (env
->DBAT
[0][nr
] != value
) {
1855 /* When storing valid upper BAT, mask BEPI and BRPN
1856 * and invalidate all TLBs covered by this BAT
1858 mask
= (value
<< 15) & 0x0FFE0000UL
;
1859 #if !defined(FLUSH_ALL_TLBS)
1860 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
1862 mask
= (value
<< 15) & 0x0FFE0000UL
;
1863 env
->DBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1864 (value
& ~0x0001FFFFUL
& ~mask
);
1865 env
->DBAT
[1][nr
] = (env
->DBAT
[1][nr
] & 0x0000007B) |
1866 (env
->DBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
1867 #if !defined(FLUSH_ALL_TLBS)
1868 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
1875 void ppc_store_dbatl (CPUPPCState
*env
, int nr
, target_ulong value
)
1877 dump_store_bat(env
, 'D', 1, nr
, value
);
1878 env
->DBAT
[1][nr
] = value
;
1881 void ppc_store_ibatu_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
1884 #if defined(FLUSH_ALL_TLBS)
1888 dump_store_bat(env
, 'I', 0, nr
, value
);
1889 if (env
->IBAT
[0][nr
] != value
) {
1890 #if defined(FLUSH_ALL_TLBS)
1893 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
1894 if (env
->IBAT
[1][nr
] & 0x40) {
1895 /* Invalidate BAT only if it is valid */
1896 #if !defined(FLUSH_ALL_TLBS)
1897 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1902 /* When storing valid upper BAT, mask BEPI and BRPN
1903 * and invalidate all TLBs covered by this BAT
1905 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1906 (value
& ~0x0001FFFFUL
& ~mask
);
1907 env
->DBAT
[0][nr
] = env
->IBAT
[0][nr
];
1908 if (env
->IBAT
[1][nr
] & 0x40) {
1909 #if !defined(FLUSH_ALL_TLBS)
1910 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1915 #if defined(FLUSH_ALL_TLBS)
1922 void ppc_store_ibatl_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
1925 #if defined(FLUSH_ALL_TLBS)
1929 dump_store_bat(env
, 'I', 1, nr
, value
);
1930 if (env
->IBAT
[1][nr
] != value
) {
1931 #if defined(FLUSH_ALL_TLBS)
1934 if (env
->IBAT
[1][nr
] & 0x40) {
1935 #if !defined(FLUSH_ALL_TLBS)
1936 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
1937 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1943 #if !defined(FLUSH_ALL_TLBS)
1944 mask
= (value
<< 17) & 0x0FFE0000UL
;
1945 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1950 env
->IBAT
[1][nr
] = value
;
1951 env
->DBAT
[1][nr
] = value
;
1952 #if defined(FLUSH_ALL_TLBS)
1959 /*****************************************************************************/
1960 /* TLB management */
1961 void ppc_tlb_invalidate_all (CPUPPCState
*env
)
1963 switch (env
->mmu_model
) {
1964 case POWERPC_MMU_SOFT_6xx
:
1965 case POWERPC_MMU_SOFT_74xx
:
1966 ppc6xx_tlb_invalidate_all(env
);
1968 case POWERPC_MMU_SOFT_4xx
:
1969 case POWERPC_MMU_SOFT_4xx_Z
:
1970 ppc4xx_tlb_invalidate_all(env
);
1972 case POWERPC_MMU_REAL
:
1973 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
1975 case POWERPC_MMU_MPC8xx
:
1977 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1979 case POWERPC_MMU_BOOKE
:
1982 case POWERPC_MMU_BOOKE206
:
1983 booke206_flush_tlb(env
, -1, 0);
1985 case POWERPC_MMU_32B
:
1986 case POWERPC_MMU_601
:
1987 #if defined(TARGET_PPC64)
1988 case POWERPC_MMU_620
:
1989 case POWERPC_MMU_64B
:
1990 case POWERPC_MMU_2_06
:
1991 #endif /* defined(TARGET_PPC64) */
1996 cpu_abort(env
, "Unknown MMU model\n");
2001 void ppc_tlb_invalidate_one (CPUPPCState
*env
, target_ulong addr
)
2003 #if !defined(FLUSH_ALL_TLBS)
2004 addr
&= TARGET_PAGE_MASK
;
2005 switch (env
->mmu_model
) {
2006 case POWERPC_MMU_SOFT_6xx
:
2007 case POWERPC_MMU_SOFT_74xx
:
2008 ppc6xx_tlb_invalidate_virt(env
, addr
, 0);
2009 if (env
->id_tlbs
== 1)
2010 ppc6xx_tlb_invalidate_virt(env
, addr
, 1);
2012 case POWERPC_MMU_SOFT_4xx
:
2013 case POWERPC_MMU_SOFT_4xx_Z
:
2014 ppc4xx_tlb_invalidate_virt(env
, addr
, env
->spr
[SPR_40x_PID
]);
2016 case POWERPC_MMU_REAL
:
2017 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
2019 case POWERPC_MMU_MPC8xx
:
2021 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
2023 case POWERPC_MMU_BOOKE
:
2025 cpu_abort(env
, "BookE MMU model is not implemented\n");
2027 case POWERPC_MMU_BOOKE206
:
2029 cpu_abort(env
, "BookE 2.06 MMU model is not implemented\n");
2031 case POWERPC_MMU_32B
:
2032 case POWERPC_MMU_601
:
2033 /* tlbie invalidate TLBs for all segments */
2034 addr
&= ~((target_ulong
)-1ULL << 28);
2035 /* XXX: this case should be optimized,
2036 * giving a mask to tlb_flush_page
2038 tlb_flush_page(env
, addr
| (0x0 << 28));
2039 tlb_flush_page(env
, addr
| (0x1 << 28));
2040 tlb_flush_page(env
, addr
| (0x2 << 28));
2041 tlb_flush_page(env
, addr
| (0x3 << 28));
2042 tlb_flush_page(env
, addr
| (0x4 << 28));
2043 tlb_flush_page(env
, addr
| (0x5 << 28));
2044 tlb_flush_page(env
, addr
| (0x6 << 28));
2045 tlb_flush_page(env
, addr
| (0x7 << 28));
2046 tlb_flush_page(env
, addr
| (0x8 << 28));
2047 tlb_flush_page(env
, addr
| (0x9 << 28));
2048 tlb_flush_page(env
, addr
| (0xA << 28));
2049 tlb_flush_page(env
, addr
| (0xB << 28));
2050 tlb_flush_page(env
, addr
| (0xC << 28));
2051 tlb_flush_page(env
, addr
| (0xD << 28));
2052 tlb_flush_page(env
, addr
| (0xE << 28));
2053 tlb_flush_page(env
, addr
| (0xF << 28));
2055 #if defined(TARGET_PPC64)
2056 case POWERPC_MMU_620
:
2057 case POWERPC_MMU_64B
:
2058 case POWERPC_MMU_2_06
:
2059 /* tlbie invalidate TLBs for all segments */
2060 /* XXX: given the fact that there are too many segments to invalidate,
2061 * and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
2062 * we just invalidate all TLBs
2066 #endif /* defined(TARGET_PPC64) */
2069 cpu_abort(env
, "Unknown MMU model\n");
2073 ppc_tlb_invalidate_all(env
);
2077 /*****************************************************************************/
2078 /* Special registers manipulation */
2079 #if defined(TARGET_PPC64)
2080 void ppc_store_asr (CPUPPCState
*env
, target_ulong value
)
2082 if (env
->asr
!= value
) {
2089 void ppc_store_sdr1 (CPUPPCState
*env
, target_ulong value
)
2091 LOG_MMU("%s: " TARGET_FMT_lx
"\n", __func__
, value
);
2092 if (env
->spr
[SPR_SDR1
] != value
) {
2093 env
->spr
[SPR_SDR1
] = value
;
2094 #if defined(TARGET_PPC64)
2095 if (env
->mmu_model
& POWERPC_MMU_64
) {
2096 target_ulong htabsize
= value
& SDR_64_HTABSIZE
;
2098 if (htabsize
> 28) {
2099 fprintf(stderr
, "Invalid HTABSIZE 0x" TARGET_FMT_lx
2100 " stored in SDR1\n", htabsize
);
2103 env
->htab_mask
= (1ULL << (htabsize
+ 18)) - 1;
2104 env
->htab_base
= value
& SDR_64_HTABORG
;
2106 #endif /* defined(TARGET_PPC64) */
2108 /* FIXME: Should check for valid HTABMASK values */
2109 env
->htab_mask
= ((value
& SDR_32_HTABMASK
) << 16) | 0xFFFF;
2110 env
->htab_base
= value
& SDR_32_HTABORG
;
2116 #if defined(TARGET_PPC64)
2117 target_ulong
ppc_load_sr (CPUPPCState
*env
, int slb_nr
)
2124 void ppc_store_sr (CPUPPCState
*env
, int srnum
, target_ulong value
)
2126 LOG_MMU("%s: reg=%d " TARGET_FMT_lx
" " TARGET_FMT_lx
"\n", __func__
,
2127 srnum
, value
, env
->sr
[srnum
]);
2128 #if defined(TARGET_PPC64)
2129 if (env
->mmu_model
& POWERPC_MMU_64
) {
2130 uint64_t rb
= 0, rs
= 0;
2133 rb
|= ((uint32_t)srnum
& 0xf) << 28;
2134 /* Set the valid bit */
2137 rb
|= (uint32_t)srnum
;
2140 rs
|= (value
& 0xfffffff) << 12;
2142 rs
|= ((value
>> 27) & 0xf) << 8;
2144 ppc_store_slb(env
, rb
, rs
);
2147 if (env
->sr
[srnum
] != value
) {
2148 env
->sr
[srnum
] = value
;
2149 /* Invalidating 256MB of virtual memory in 4kB pages is way longer than
2150 flusing the whole TLB. */
2151 #if !defined(FLUSH_ALL_TLBS) && 0
2153 target_ulong page
, end
;
2154 /* Invalidate 256 MB of virtual memory */
2155 page
= (16 << 20) * srnum
;
2156 end
= page
+ (16 << 20);
2157 for (; page
!= end
; page
+= TARGET_PAGE_SIZE
)
2158 tlb_flush_page(env
, page
);
2165 #endif /* !defined (CONFIG_USER_ONLY) */
2167 /* GDBstub can read and write MSR... */
2168 void ppc_store_msr (CPUPPCState
*env
, target_ulong value
)
2170 hreg_store_msr(env
, value
, 0);
2173 /*****************************************************************************/
2174 /* Exception processing */
2175 #if defined (CONFIG_USER_ONLY)
2176 void do_interrupt (CPUState
*env
)
2178 env
->exception_index
= POWERPC_EXCP_NONE
;
2179 env
->error_code
= 0;
2182 void ppc_hw_interrupt (CPUState
*env
)
2184 env
->exception_index
= POWERPC_EXCP_NONE
;
2185 env
->error_code
= 0;
2187 #else /* defined (CONFIG_USER_ONLY) */
2188 static inline void dump_syscall(CPUState
*env
)
2190 qemu_log_mask(CPU_LOG_INT
, "syscall r0=%016" PRIx64
" r3=%016" PRIx64
2191 " r4=%016" PRIx64
" r5=%016" PRIx64
" r6=%016" PRIx64
2192 " nip=" TARGET_FMT_lx
"\n",
2193 ppc_dump_gpr(env
, 0), ppc_dump_gpr(env
, 3),
2194 ppc_dump_gpr(env
, 4), ppc_dump_gpr(env
, 5),
2195 ppc_dump_gpr(env
, 6), env
->nip
);
2198 /* Note that this function should be greatly optimized
2199 * when called with a constant excp, from ppc_hw_interrupt
2201 static inline void powerpc_excp(CPUState
*env
, int excp_model
, int excp
)
2203 target_ulong msr
, new_msr
, vector
;
2204 int srr0
, srr1
, asrr0
, asrr1
;
2205 int lpes0
, lpes1
, lev
;
2208 /* XXX: find a suitable condition to enable the hypervisor mode */
2209 lpes0
= (env
->spr
[SPR_LPCR
] >> 1) & 1;
2210 lpes1
= (env
->spr
[SPR_LPCR
] >> 2) & 1;
2212 /* Those values ensure we won't enter the hypervisor mode */
2217 qemu_log_mask(CPU_LOG_INT
, "Raise exception at " TARGET_FMT_lx
2218 " => %08x (%02x)\n", env
->nip
, excp
, env
->error_code
);
2220 /* new srr1 value excluding must-be-zero bits */
2221 msr
= env
->msr
& ~0x783f0000ULL
;
2223 /* new interrupt handler msr */
2224 new_msr
= env
->msr
& ((target_ulong
)1 << MSR_ME
);
2226 /* target registers */
2233 case POWERPC_EXCP_NONE
:
2234 /* Should never happen */
2236 case POWERPC_EXCP_CRITICAL
: /* Critical input */
2237 switch (excp_model
) {
2238 case POWERPC_EXCP_40x
:
2239 srr0
= SPR_40x_SRR2
;
2240 srr1
= SPR_40x_SRR3
;
2242 case POWERPC_EXCP_BOOKE
:
2243 srr0
= SPR_BOOKE_CSRR0
;
2244 srr1
= SPR_BOOKE_CSRR1
;
2246 case POWERPC_EXCP_G2
:
2252 case POWERPC_EXCP_MCHECK
: /* Machine check exception */
2254 /* Machine check exception is not enabled.
2255 * Enter checkstop state.
2257 if (qemu_log_enabled()) {
2258 qemu_log("Machine check while not allowed. "
2259 "Entering checkstop state\n");
2261 fprintf(stderr
, "Machine check while not allowed. "
2262 "Entering checkstop state\n");
2265 env
->interrupt_request
|= CPU_INTERRUPT_EXITTB
;
2268 /* XXX: find a suitable condition to enable the hypervisor mode */
2269 new_msr
|= (target_ulong
)MSR_HVB
;
2272 /* machine check exceptions don't have ME set */
2273 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2275 /* XXX: should also have something loaded in DAR / DSISR */
2276 switch (excp_model
) {
2277 case POWERPC_EXCP_40x
:
2278 srr0
= SPR_40x_SRR2
;
2279 srr1
= SPR_40x_SRR3
;
2281 case POWERPC_EXCP_BOOKE
:
2282 srr0
= SPR_BOOKE_MCSRR0
;
2283 srr1
= SPR_BOOKE_MCSRR1
;
2284 asrr0
= SPR_BOOKE_CSRR0
;
2285 asrr1
= SPR_BOOKE_CSRR1
;
2291 case POWERPC_EXCP_DSI
: /* Data storage exception */
2292 LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx
" DAR=" TARGET_FMT_lx
2293 "\n", env
->spr
[SPR_DSISR
], env
->spr
[SPR_DAR
]);
2295 new_msr
|= (target_ulong
)MSR_HVB
;
2297 case POWERPC_EXCP_ISI
: /* Instruction storage exception */
2298 LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx
", nip=" TARGET_FMT_lx
2299 "\n", msr
, env
->nip
);
2301 new_msr
|= (target_ulong
)MSR_HVB
;
2302 msr
|= env
->error_code
;
2304 case POWERPC_EXCP_EXTERNAL
: /* External input */
2306 new_msr
|= (target_ulong
)MSR_HVB
;
2308 case POWERPC_EXCP_ALIGN
: /* Alignment exception */
2310 new_msr
|= (target_ulong
)MSR_HVB
;
2311 /* XXX: this is false */
2312 /* Get rS/rD and rA from faulting opcode */
2313 env
->spr
[SPR_DSISR
] |= (ldl_code((env
->nip
- 4)) & 0x03FF0000) >> 16;
2315 case POWERPC_EXCP_PROGRAM
: /* Program exception */
2316 switch (env
->error_code
& ~0xF) {
2317 case POWERPC_EXCP_FP
:
2318 if ((msr_fe0
== 0 && msr_fe1
== 0) || msr_fp
== 0) {
2319 LOG_EXCP("Ignore floating point exception\n");
2320 env
->exception_index
= POWERPC_EXCP_NONE
;
2321 env
->error_code
= 0;
2325 new_msr
|= (target_ulong
)MSR_HVB
;
2327 if (msr_fe0
== msr_fe1
)
2331 case POWERPC_EXCP_INVAL
:
2332 LOG_EXCP("Invalid instruction at " TARGET_FMT_lx
"\n", env
->nip
);
2334 new_msr
|= (target_ulong
)MSR_HVB
;
2337 case POWERPC_EXCP_PRIV
:
2339 new_msr
|= (target_ulong
)MSR_HVB
;
2342 case POWERPC_EXCP_TRAP
:
2344 new_msr
|= (target_ulong
)MSR_HVB
;
2348 /* Should never occur */
2349 cpu_abort(env
, "Invalid program exception %d. Aborting\n",
2354 case POWERPC_EXCP_FPU
: /* Floating-point unavailable exception */
2356 new_msr
|= (target_ulong
)MSR_HVB
;
2358 case POWERPC_EXCP_SYSCALL
: /* System call exception */
2360 lev
= env
->error_code
;
2361 if ((lev
== 1) && cpu_ppc_hypercall
) {
2362 cpu_ppc_hypercall(env
);
2365 if (lev
== 1 || (lpes0
== 0 && lpes1
== 0))
2366 new_msr
|= (target_ulong
)MSR_HVB
;
2368 case POWERPC_EXCP_APU
: /* Auxiliary processor unavailable */
2370 case POWERPC_EXCP_DECR
: /* Decrementer exception */
2372 new_msr
|= (target_ulong
)MSR_HVB
;
2374 case POWERPC_EXCP_FIT
: /* Fixed-interval timer interrupt */
2376 LOG_EXCP("FIT exception\n");
2378 case POWERPC_EXCP_WDT
: /* Watchdog timer interrupt */
2379 LOG_EXCP("WDT exception\n");
2380 switch (excp_model
) {
2381 case POWERPC_EXCP_BOOKE
:
2382 srr0
= SPR_BOOKE_CSRR0
;
2383 srr1
= SPR_BOOKE_CSRR1
;
2389 case POWERPC_EXCP_DTLB
: /* Data TLB error */
2391 case POWERPC_EXCP_ITLB
: /* Instruction TLB error */
2393 case POWERPC_EXCP_DEBUG
: /* Debug interrupt */
2394 switch (excp_model
) {
2395 case POWERPC_EXCP_BOOKE
:
2396 srr0
= SPR_BOOKE_DSRR0
;
2397 srr1
= SPR_BOOKE_DSRR1
;
2398 asrr0
= SPR_BOOKE_CSRR0
;
2399 asrr1
= SPR_BOOKE_CSRR1
;
2405 cpu_abort(env
, "Debug exception is not implemented yet !\n");
2407 case POWERPC_EXCP_SPEU
: /* SPE/embedded floating-point unavailable */
2409 case POWERPC_EXCP_EFPDI
: /* Embedded floating-point data interrupt */
2411 cpu_abort(env
, "Embedded floating point data exception "
2412 "is not implemented yet !\n");
2414 case POWERPC_EXCP_EFPRI
: /* Embedded floating-point round interrupt */
2416 cpu_abort(env
, "Embedded floating point round exception "
2417 "is not implemented yet !\n");
2419 case POWERPC_EXCP_EPERFM
: /* Embedded performance monitor interrupt */
2422 "Performance counter exception is not implemented yet !\n");
2424 case POWERPC_EXCP_DOORI
: /* Embedded doorbell interrupt */
2427 "Embedded doorbell interrupt is not implemented yet !\n");
2429 case POWERPC_EXCP_DOORCI
: /* Embedded doorbell critical interrupt */
2430 switch (excp_model
) {
2431 case POWERPC_EXCP_BOOKE
:
2432 srr0
= SPR_BOOKE_CSRR0
;
2433 srr1
= SPR_BOOKE_CSRR1
;
2439 cpu_abort(env
, "Embedded doorbell critical interrupt "
2440 "is not implemented yet !\n");
2442 case POWERPC_EXCP_RESET
: /* System reset exception */
2444 /* indicate that we resumed from power save mode */
2447 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2451 /* XXX: find a suitable condition to enable the hypervisor mode */
2452 new_msr
|= (target_ulong
)MSR_HVB
;
2455 case POWERPC_EXCP_DSEG
: /* Data segment exception */
2457 new_msr
|= (target_ulong
)MSR_HVB
;
2459 case POWERPC_EXCP_ISEG
: /* Instruction segment exception */
2461 new_msr
|= (target_ulong
)MSR_HVB
;
2463 case POWERPC_EXCP_HDECR
: /* Hypervisor decrementer exception */
2466 new_msr
|= (target_ulong
)MSR_HVB
;
2467 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2469 case POWERPC_EXCP_TRACE
: /* Trace exception */
2471 new_msr
|= (target_ulong
)MSR_HVB
;
2473 case POWERPC_EXCP_HDSI
: /* Hypervisor data storage exception */
2476 new_msr
|= (target_ulong
)MSR_HVB
;
2477 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2479 case POWERPC_EXCP_HISI
: /* Hypervisor instruction storage exception */
2482 new_msr
|= (target_ulong
)MSR_HVB
;
2483 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2485 case POWERPC_EXCP_HDSEG
: /* Hypervisor data segment exception */
2488 new_msr
|= (target_ulong
)MSR_HVB
;
2489 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2491 case POWERPC_EXCP_HISEG
: /* Hypervisor instruction segment exception */
2494 new_msr
|= (target_ulong
)MSR_HVB
;
2495 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2497 case POWERPC_EXCP_VPU
: /* Vector unavailable exception */
2499 new_msr
|= (target_ulong
)MSR_HVB
;
2501 case POWERPC_EXCP_PIT
: /* Programmable interval timer interrupt */
2502 LOG_EXCP("PIT exception\n");
2504 case POWERPC_EXCP_IO
: /* IO error exception */
2506 cpu_abort(env
, "601 IO error exception is not implemented yet !\n");
2508 case POWERPC_EXCP_RUNM
: /* Run mode exception */
2510 cpu_abort(env
, "601 run mode exception is not implemented yet !\n");
2512 case POWERPC_EXCP_EMUL
: /* Emulation trap exception */
2514 cpu_abort(env
, "602 emulation trap exception "
2515 "is not implemented yet !\n");
2517 case POWERPC_EXCP_IFTLB
: /* Instruction fetch TLB error */
2518 if (lpes1
== 0) /* XXX: check this */
2519 new_msr
|= (target_ulong
)MSR_HVB
;
2520 switch (excp_model
) {
2521 case POWERPC_EXCP_602
:
2522 case POWERPC_EXCP_603
:
2523 case POWERPC_EXCP_603E
:
2524 case POWERPC_EXCP_G2
:
2526 case POWERPC_EXCP_7x5
:
2528 case POWERPC_EXCP_74xx
:
2531 cpu_abort(env
, "Invalid instruction TLB miss exception\n");
2535 case POWERPC_EXCP_DLTLB
: /* Data load TLB miss */
2536 if (lpes1
== 0) /* XXX: check this */
2537 new_msr
|= (target_ulong
)MSR_HVB
;
2538 switch (excp_model
) {
2539 case POWERPC_EXCP_602
:
2540 case POWERPC_EXCP_603
:
2541 case POWERPC_EXCP_603E
:
2542 case POWERPC_EXCP_G2
:
2544 case POWERPC_EXCP_7x5
:
2546 case POWERPC_EXCP_74xx
:
2549 cpu_abort(env
, "Invalid data load TLB miss exception\n");
2553 case POWERPC_EXCP_DSTLB
: /* Data store TLB miss */
2554 if (lpes1
== 0) /* XXX: check this */
2555 new_msr
|= (target_ulong
)MSR_HVB
;
2556 switch (excp_model
) {
2557 case POWERPC_EXCP_602
:
2558 case POWERPC_EXCP_603
:
2559 case POWERPC_EXCP_603E
:
2560 case POWERPC_EXCP_G2
:
2562 /* Swap temporary saved registers with GPRs */
2563 if (!(new_msr
& ((target_ulong
)1 << MSR_TGPR
))) {
2564 new_msr
|= (target_ulong
)1 << MSR_TGPR
;
2565 hreg_swap_gpr_tgpr(env
);
2568 case POWERPC_EXCP_7x5
:
2570 #if defined (DEBUG_SOFTWARE_TLB)
2571 if (qemu_log_enabled()) {
2573 target_ulong
*miss
, *cmp
;
2575 if (excp
== POWERPC_EXCP_IFTLB
) {
2578 miss
= &env
->spr
[SPR_IMISS
];
2579 cmp
= &env
->spr
[SPR_ICMP
];
2581 if (excp
== POWERPC_EXCP_DLTLB
)
2586 miss
= &env
->spr
[SPR_DMISS
];
2587 cmp
= &env
->spr
[SPR_DCMP
];
2589 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2590 TARGET_FMT_lx
" H1 " TARGET_FMT_lx
" H2 "
2591 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2592 env
->spr
[SPR_HASH1
], env
->spr
[SPR_HASH2
],
2596 msr
|= env
->crf
[0] << 28;
2597 msr
|= env
->error_code
; /* key, D/I, S/L bits */
2598 /* Set way using a LRU mechanism */
2599 msr
|= ((env
->last_way
+ 1) & (env
->nb_ways
- 1)) << 17;
2601 case POWERPC_EXCP_74xx
:
2603 #if defined (DEBUG_SOFTWARE_TLB)
2604 if (qemu_log_enabled()) {
2606 target_ulong
*miss
, *cmp
;
2608 if (excp
== POWERPC_EXCP_IFTLB
) {
2611 miss
= &env
->spr
[SPR_TLBMISS
];
2612 cmp
= &env
->spr
[SPR_PTEHI
];
2614 if (excp
== POWERPC_EXCP_DLTLB
)
2619 miss
= &env
->spr
[SPR_TLBMISS
];
2620 cmp
= &env
->spr
[SPR_PTEHI
];
2622 qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2623 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2627 msr
|= env
->error_code
; /* key bit */
2630 cpu_abort(env
, "Invalid data store TLB miss exception\n");
2634 case POWERPC_EXCP_FPA
: /* Floating-point assist exception */
2636 cpu_abort(env
, "Floating point assist exception "
2637 "is not implemented yet !\n");
2639 case POWERPC_EXCP_DABR
: /* Data address breakpoint */
2641 cpu_abort(env
, "DABR exception is not implemented yet !\n");
2643 case POWERPC_EXCP_IABR
: /* Instruction address breakpoint */
2645 cpu_abort(env
, "IABR exception is not implemented yet !\n");
2647 case POWERPC_EXCP_SMI
: /* System management interrupt */
2649 cpu_abort(env
, "SMI exception is not implemented yet !\n");
2651 case POWERPC_EXCP_THERM
: /* Thermal interrupt */
2653 cpu_abort(env
, "Thermal management exception "
2654 "is not implemented yet !\n");
2656 case POWERPC_EXCP_PERFM
: /* Embedded performance monitor interrupt */
2658 new_msr
|= (target_ulong
)MSR_HVB
;
2661 "Performance counter exception is not implemented yet !\n");
2663 case POWERPC_EXCP_VPUA
: /* Vector assist exception */
2665 cpu_abort(env
, "VPU assist exception is not implemented yet !\n");
2667 case POWERPC_EXCP_SOFTP
: /* Soft patch exception */
2670 "970 soft-patch exception is not implemented yet !\n");
2672 case POWERPC_EXCP_MAINT
: /* Maintenance exception */
2675 "970 maintenance exception is not implemented yet !\n");
2677 case POWERPC_EXCP_MEXTBR
: /* Maskable external breakpoint */
2679 cpu_abort(env
, "Maskable external exception "
2680 "is not implemented yet !\n");
2682 case POWERPC_EXCP_NMEXTBR
: /* Non maskable external breakpoint */
2684 cpu_abort(env
, "Non maskable external exception "
2685 "is not implemented yet !\n");
2689 cpu_abort(env
, "Invalid PowerPC exception %d. Aborting\n", excp
);
2692 /* save current instruction location */
2693 env
->spr
[srr0
] = env
->nip
- 4;
2696 /* save next instruction location */
2697 env
->spr
[srr0
] = env
->nip
;
2701 env
->spr
[srr1
] = msr
;
2702 /* If any alternate SRR register are defined, duplicate saved values */
2704 env
->spr
[asrr0
] = env
->spr
[srr0
];
2706 env
->spr
[asrr1
] = env
->spr
[srr1
];
2707 /* If we disactivated any translation, flush TLBs */
2708 if (new_msr
& ((1 << MSR_IR
) | (1 << MSR_DR
)))
2712 new_msr
|= (target_ulong
)1 << MSR_LE
;
2715 /* Jump to handler */
2716 vector
= env
->excp_vectors
[excp
];
2717 if (vector
== (target_ulong
)-1ULL) {
2718 cpu_abort(env
, "Raised an exception without defined vector %d\n",
2721 vector
|= env
->excp_prefix
;
2722 #if defined(TARGET_PPC64)
2723 if (excp_model
== POWERPC_EXCP_BOOKE
) {
2725 vector
= (uint32_t)vector
;
2727 new_msr
|= (target_ulong
)1 << MSR_CM
;
2730 if (!msr_isf
&& !(env
->mmu_model
& POWERPC_MMU_64
)) {
2731 vector
= (uint32_t)vector
;
2733 new_msr
|= (target_ulong
)1 << MSR_SF
;
2737 /* XXX: we don't use hreg_store_msr here as already have treated
2738 * any special case that could occur. Just store MSR and update hflags
2740 env
->msr
= new_msr
& env
->msr_mask
;
2741 hreg_compute_hflags(env
);
2743 /* Reset exception state */
2744 env
->exception_index
= POWERPC_EXCP_NONE
;
2745 env
->error_code
= 0;
2747 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
2748 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
2749 /* XXX: The BookE changes address space when switching modes,
2750 we should probably implement that as different MMU indexes,
2751 but for the moment we do it the slow way and flush all. */
2756 void do_interrupt (CPUState
*env
)
2758 powerpc_excp(env
, env
->excp_model
, env
->exception_index
);
2761 void ppc_hw_interrupt (CPUPPCState
*env
)
2766 qemu_log_mask(CPU_LOG_INT
, "%s: %p pending %08x req %08x me %d ee %d\n",
2767 __func__
, env
, env
->pending_interrupts
,
2768 env
->interrupt_request
, (int)msr_me
, (int)msr_ee
);
2770 /* External reset */
2771 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_RESET
)) {
2772 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_RESET
);
2773 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_RESET
);
2776 /* Machine check exception */
2777 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_MCK
)) {
2778 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_MCK
);
2779 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_MCHECK
);
2783 /* External debug exception */
2784 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DEBUG
)) {
2785 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DEBUG
);
2786 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DEBUG
);
2791 /* XXX: find a suitable condition to enable the hypervisor mode */
2792 hdice
= env
->spr
[SPR_LPCR
] & 1;
2796 if ((msr_ee
!= 0 || msr_hv
== 0 || msr_pr
!= 0) && hdice
!= 0) {
2797 /* Hypervisor decrementer exception */
2798 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_HDECR
)) {
2799 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_HDECR
);
2800 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_HDECR
);
2805 /* External critical interrupt */
2806 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CEXT
)) {
2807 /* Taking a critical external interrupt does not clear the external
2808 * critical interrupt status
2811 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CEXT
);
2813 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_CRITICAL
);
2818 /* Watchdog timer on embedded PowerPC */
2819 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_WDT
)) {
2820 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_WDT
);
2821 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_WDT
);
2824 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CDOORBELL
)) {
2825 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CDOORBELL
);
2826 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORCI
);
2829 /* Fixed interval timer on embedded PowerPC */
2830 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_FIT
)) {
2831 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_FIT
);
2832 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_FIT
);
2835 /* Programmable interval timer on embedded PowerPC */
2836 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PIT
)) {
2837 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PIT
);
2838 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PIT
);
2841 /* Decrementer exception */
2842 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DECR
)) {
2843 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DECR
);
2844 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DECR
);
2847 /* External interrupt */
2848 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_EXT
)) {
2849 /* Taking an external interrupt does not clear the external
2853 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_EXT
);
2855 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_EXTERNAL
);
2858 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DOORBELL
)) {
2859 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DOORBELL
);
2860 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORI
);
2863 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PERFM
)) {
2864 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PERFM
);
2865 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PERFM
);
2868 /* Thermal interrupt */
2869 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_THERM
)) {
2870 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_THERM
);
2871 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_THERM
);
2876 #endif /* !CONFIG_USER_ONLY */
2878 void cpu_dump_rfi (target_ulong RA
, target_ulong msr
)
2880 qemu_log("Return from exception at " TARGET_FMT_lx
" with flags "
2881 TARGET_FMT_lx
"\n", RA
, msr
);
2884 void cpu_reset(CPUPPCState
*env
)
2888 if (qemu_loglevel_mask(CPU_LOG_RESET
)) {
2889 qemu_log("CPU Reset (CPU %d)\n", env
->cpu_index
);
2890 log_cpu_state(env
, 0);
2893 msr
= (target_ulong
)0;
2895 /* XXX: find a suitable condition to enable the hypervisor mode */
2896 msr
|= (target_ulong
)MSR_HVB
;
2898 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
2899 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
2900 msr
|= (target_ulong
)1 << MSR_EP
;
2901 #if defined (DO_SINGLE_STEP) && 0
2902 /* Single step trace mode */
2903 msr
|= (target_ulong
)1 << MSR_SE
;
2904 msr
|= (target_ulong
)1 << MSR_BE
;
2906 #if defined(CONFIG_USER_ONLY)
2907 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
2908 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
2909 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
2910 msr
|= (target_ulong
)1 << MSR_PR
;
2912 env
->excp_prefix
= env
->hreset_excp_prefix
;
2913 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
2914 if (env
->mmu_model
!= POWERPC_MMU_REAL
)
2915 ppc_tlb_invalidate_all(env
);
2917 env
->msr
= msr
& env
->msr_mask
;
2918 #if defined(TARGET_PPC64)
2919 if (env
->mmu_model
& POWERPC_MMU_64
)
2920 env
->msr
|= (1ULL << MSR_SF
);
2922 hreg_compute_hflags(env
);
2923 env
->reserve_addr
= (target_ulong
)-1ULL;
2924 /* Be sure no exception or interrupt is pending */
2925 env
->pending_interrupts
= 0;
2926 env
->exception_index
= POWERPC_EXCP_NONE
;
2927 env
->error_code
= 0;
2928 /* Flush all TLBs */
2932 CPUPPCState
*cpu_ppc_init (const char *cpu_model
)
2935 const ppc_def_t
*def
;
2937 def
= cpu_ppc_find_by_name(cpu_model
);
2941 env
= qemu_mallocz(sizeof(CPUPPCState
));
2943 ppc_translate_init();
2944 env
->cpu_model_str
= cpu_model
;
2945 cpu_ppc_register_internal(env
, def
);
2947 qemu_init_vcpu(env
);
2952 void cpu_ppc_close (CPUPPCState
*env
)
2954 /* Should also remove all opcode tables... */