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/>.
27 #include "helper_regs.h"
28 #include "qemu-common.h"
34 //#define DEBUG_SOFTWARE_TLB
35 //#define DUMP_PAGE_TABLES
36 //#define DEBUG_EXCEPTIONS
37 //#define FLUSH_ALL_TLBS
40 # define LOG_MMU(...) qemu_log(__VA_ARGS__)
41 # define LOG_MMU_STATE(env) log_cpu_state((env), 0)
43 # define LOG_MMU(...) do { } while (0)
44 # define LOG_MMU_STATE(...) do { } while (0)
48 #ifdef DEBUG_SOFTWARE_TLB
49 # define LOG_SWTLB(...) qemu_log(__VA_ARGS__)
51 # define LOG_SWTLB(...) do { } while (0)
55 # define LOG_BATS(...) qemu_log(__VA_ARGS__)
57 # define LOG_BATS(...) do { } while (0)
61 # define LOG_SLB(...) qemu_log(__VA_ARGS__)
63 # define LOG_SLB(...) do { } while (0)
66 #ifdef DEBUG_EXCEPTIONS
67 # define LOG_EXCP(...) qemu_log(__VA_ARGS__)
69 # define LOG_EXCP(...) do { } while (0)
72 /*****************************************************************************/
73 /* PowerPC Hypercall emulation */
75 void (*cpu_ppc_hypercall
)(CPUState
*);
77 /*****************************************************************************/
78 /* PowerPC MMU emulation */
80 #if defined(CONFIG_USER_ONLY)
81 int cpu_ppc_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
82 int mmu_idx
, int is_softmmu
)
84 int exception
, error_code
;
87 exception
= POWERPC_EXCP_ISI
;
88 error_code
= 0x40000000;
90 exception
= POWERPC_EXCP_DSI
;
91 error_code
= 0x40000000;
93 error_code
|= 0x02000000;
94 env
->spr
[SPR_DAR
] = address
;
95 env
->spr
[SPR_DSISR
] = error_code
;
97 env
->exception_index
= exception
;
98 env
->error_code
= error_code
;
104 /* Common routines used by software and hardware TLBs emulation */
105 static inline int pte_is_valid(target_ulong pte0
)
107 return pte0
& 0x80000000 ? 1 : 0;
110 static inline void pte_invalidate(target_ulong
*pte0
)
112 *pte0
&= ~0x80000000;
115 #if defined(TARGET_PPC64)
116 static inline int pte64_is_valid(target_ulong pte0
)
118 return pte0
& 0x0000000000000001ULL
? 1 : 0;
121 static inline void pte64_invalidate(target_ulong
*pte0
)
123 *pte0
&= ~0x0000000000000001ULL
;
127 #define PTE_PTEM_MASK 0x7FFFFFBF
128 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
129 #if defined(TARGET_PPC64)
130 #define PTE64_PTEM_MASK 0xFFFFFFFFFFFFFF80ULL
131 #define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F)
134 static inline int pp_check(int key
, int pp
, int nx
)
138 /* Compute access rights */
139 /* When pp is 3/7, the result is undefined. Set it to noaccess */
146 access
|= PAGE_WRITE
;
164 access
= PAGE_READ
| PAGE_WRITE
;
174 static inline int check_prot(int prot
, int rw
, int access_type
)
178 if (access_type
== ACCESS_CODE
) {
179 if (prot
& PAGE_EXEC
)
184 if (prot
& PAGE_WRITE
)
189 if (prot
& PAGE_READ
)
198 static inline int _pte_check(mmu_ctx_t
*ctx
, int is_64b
, target_ulong pte0
,
199 target_ulong pte1
, int h
, int rw
, int type
)
201 target_ulong ptem
, mmask
;
202 int access
, ret
, pteh
, ptev
, pp
;
205 /* Check validity and table match */
206 #if defined(TARGET_PPC64)
208 ptev
= pte64_is_valid(pte0
);
209 pteh
= (pte0
>> 1) & 1;
213 ptev
= pte_is_valid(pte0
);
214 pteh
= (pte0
>> 6) & 1;
216 if (ptev
&& h
== pteh
) {
217 /* Check vsid & api */
218 #if defined(TARGET_PPC64)
220 ptem
= pte0
& PTE64_PTEM_MASK
;
221 mmask
= PTE64_CHECK_MASK
;
222 pp
= (pte1
& 0x00000003) | ((pte1
>> 61) & 0x00000004);
223 ctx
->nx
= (pte1
>> 2) & 1; /* No execute bit */
224 ctx
->nx
|= (pte1
>> 3) & 1; /* Guarded bit */
228 ptem
= pte0
& PTE_PTEM_MASK
;
229 mmask
= PTE_CHECK_MASK
;
230 pp
= pte1
& 0x00000003;
232 if (ptem
== ctx
->ptem
) {
233 if (ctx
->raddr
!= (target_phys_addr_t
)-1ULL) {
234 /* all matches should have equal RPN, WIMG & PP */
235 if ((ctx
->raddr
& mmask
) != (pte1
& mmask
)) {
236 qemu_log("Bad RPN/WIMG/PP\n");
240 /* Compute access rights */
241 access
= pp_check(ctx
->key
, pp
, ctx
->nx
);
242 /* Keep the matching PTE informations */
245 ret
= check_prot(ctx
->prot
, rw
, type
);
248 LOG_MMU("PTE access granted !\n");
250 /* Access right violation */
251 LOG_MMU("PTE access rejected\n");
259 static inline int pte32_check(mmu_ctx_t
*ctx
, target_ulong pte0
,
260 target_ulong pte1
, int h
, int rw
, int type
)
262 return _pte_check(ctx
, 0, pte0
, pte1
, h
, rw
, type
);
265 #if defined(TARGET_PPC64)
266 static inline int pte64_check(mmu_ctx_t
*ctx
, target_ulong pte0
,
267 target_ulong pte1
, int h
, int rw
, int type
)
269 return _pte_check(ctx
, 1, pte0
, pte1
, h
, rw
, type
);
273 static inline int pte_update_flags(mmu_ctx_t
*ctx
, target_ulong
*pte1p
,
278 /* Update page flags */
279 if (!(*pte1p
& 0x00000100)) {
280 /* Update accessed flag */
281 *pte1p
|= 0x00000100;
284 if (!(*pte1p
& 0x00000080)) {
285 if (rw
== 1 && ret
== 0) {
286 /* Update changed flag */
287 *pte1p
|= 0x00000080;
290 /* Force page fault for first write access */
291 ctx
->prot
&= ~PAGE_WRITE
;
298 /* Software driven TLB helpers */
299 static inline int ppc6xx_tlb_getnum(CPUState
*env
, target_ulong eaddr
, int way
,
304 /* Select TLB num in a way from address */
305 nr
= (eaddr
>> TARGET_PAGE_BITS
) & (env
->tlb_per_way
- 1);
307 nr
+= env
->tlb_per_way
* way
;
308 /* 6xx have separate TLBs for instructions and data */
309 if (is_code
&& env
->id_tlbs
== 1)
315 static inline void ppc6xx_tlb_invalidate_all(CPUState
*env
)
320 //LOG_SWTLB("Invalidate all TLBs\n");
321 /* Invalidate all defined software TLB */
323 if (env
->id_tlbs
== 1)
325 for (nr
= 0; nr
< max
; nr
++) {
326 tlb
= &env
->tlb
[nr
].tlb6
;
327 pte_invalidate(&tlb
->pte0
);
332 static inline void __ppc6xx_tlb_invalidate_virt(CPUState
*env
,
334 int is_code
, int match_epn
)
336 #if !defined(FLUSH_ALL_TLBS)
340 /* Invalidate ITLB + DTLB, all ways */
341 for (way
= 0; way
< env
->nb_ways
; way
++) {
342 nr
= ppc6xx_tlb_getnum(env
, eaddr
, way
, is_code
);
343 tlb
= &env
->tlb
[nr
].tlb6
;
344 if (pte_is_valid(tlb
->pte0
) && (match_epn
== 0 || eaddr
== tlb
->EPN
)) {
345 LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx
"\n", nr
,
347 pte_invalidate(&tlb
->pte0
);
348 tlb_flush_page(env
, tlb
->EPN
);
352 /* XXX: PowerPC specification say this is valid as well */
353 ppc6xx_tlb_invalidate_all(env
);
357 static inline void ppc6xx_tlb_invalidate_virt(CPUState
*env
,
358 target_ulong eaddr
, int is_code
)
360 __ppc6xx_tlb_invalidate_virt(env
, eaddr
, is_code
, 0);
363 void ppc6xx_tlb_store (CPUState
*env
, target_ulong EPN
, int way
, int is_code
,
364 target_ulong pte0
, target_ulong pte1
)
369 nr
= ppc6xx_tlb_getnum(env
, EPN
, way
, is_code
);
370 tlb
= &env
->tlb
[nr
].tlb6
;
371 LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx
" PTE0 " TARGET_FMT_lx
372 " PTE1 " TARGET_FMT_lx
"\n", nr
, env
->nb_tlb
, EPN
, pte0
, pte1
);
373 /* Invalidate any pending reference in Qemu for this virtual address */
374 __ppc6xx_tlb_invalidate_virt(env
, EPN
, is_code
, 1);
378 /* Store last way for LRU mechanism */
382 static inline int ppc6xx_tlb_check(CPUState
*env
, mmu_ctx_t
*ctx
,
383 target_ulong eaddr
, int rw
, int access_type
)
390 ret
= -1; /* No TLB found */
391 for (way
= 0; way
< env
->nb_ways
; way
++) {
392 nr
= ppc6xx_tlb_getnum(env
, eaddr
, way
,
393 access_type
== ACCESS_CODE
? 1 : 0);
394 tlb
= &env
->tlb
[nr
].tlb6
;
395 /* This test "emulates" the PTE index match for hardware TLBs */
396 if ((eaddr
& TARGET_PAGE_MASK
) != tlb
->EPN
) {
397 LOG_SWTLB("TLB %d/%d %s [" TARGET_FMT_lx
" " TARGET_FMT_lx
398 "] <> " TARGET_FMT_lx
"\n", nr
, env
->nb_tlb
,
399 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
400 tlb
->EPN
, tlb
->EPN
+ TARGET_PAGE_SIZE
, eaddr
);
403 LOG_SWTLB("TLB %d/%d %s " TARGET_FMT_lx
" <> " TARGET_FMT_lx
" "
404 TARGET_FMT_lx
" %c %c\n", nr
, env
->nb_tlb
,
405 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
406 tlb
->EPN
, eaddr
, tlb
->pte1
,
407 rw
? 'S' : 'L', access_type
== ACCESS_CODE
? 'I' : 'D');
408 switch (pte32_check(ctx
, tlb
->pte0
, tlb
->pte1
, 0, rw
, access_type
)) {
410 /* TLB inconsistency */
413 /* Access violation */
423 /* XXX: we should go on looping to check all TLBs consistency
424 * but we can speed-up the whole thing as the
425 * result would be undefined if TLBs are not consistent.
434 LOG_SWTLB("found TLB at addr " TARGET_FMT_plx
" prot=%01x ret=%d\n",
435 ctx
->raddr
& TARGET_PAGE_MASK
, ctx
->prot
, ret
);
436 /* Update page flags */
437 pte_update_flags(ctx
, &env
->tlb
[best
].tlb6
.pte1
, ret
, rw
);
443 /* Perform BAT hit & translation */
444 static inline void bat_size_prot(CPUState
*env
, target_ulong
*blp
, int *validp
,
445 int *protp
, target_ulong
*BATu
,
451 bl
= (*BATu
& 0x00001FFC) << 15;
454 if (((msr_pr
== 0) && (*BATu
& 0x00000002)) ||
455 ((msr_pr
!= 0) && (*BATu
& 0x00000001))) {
457 pp
= *BATl
& 0x00000003;
459 prot
= PAGE_READ
| PAGE_EXEC
;
469 static inline void bat_601_size_prot(CPUState
*env
, target_ulong
*blp
,
470 int *validp
, int *protp
,
471 target_ulong
*BATu
, target_ulong
*BATl
)
474 int key
, pp
, valid
, prot
;
476 bl
= (*BATl
& 0x0000003F) << 17;
477 LOG_BATS("b %02x ==> bl " TARGET_FMT_lx
" msk " TARGET_FMT_lx
"\n",
478 (uint8_t)(*BATl
& 0x0000003F), bl
, ~bl
);
480 valid
= (*BATl
>> 6) & 1;
482 pp
= *BATu
& 0x00000003;
484 key
= (*BATu
>> 3) & 1;
486 key
= (*BATu
>> 2) & 1;
487 prot
= pp_check(key
, pp
, 0);
494 static inline int get_bat(CPUState
*env
, mmu_ctx_t
*ctx
, target_ulong
virtual,
497 target_ulong
*BATlt
, *BATut
, *BATu
, *BATl
;
498 target_ulong BEPIl
, BEPIu
, bl
;
502 LOG_BATS("%s: %cBAT v " TARGET_FMT_lx
"\n", __func__
,
503 type
== ACCESS_CODE
? 'I' : 'D', virtual);
506 BATlt
= env
->IBAT
[1];
507 BATut
= env
->IBAT
[0];
510 BATlt
= env
->DBAT
[1];
511 BATut
= env
->DBAT
[0];
514 for (i
= 0; i
< env
->nb_BATs
; i
++) {
517 BEPIu
= *BATu
& 0xF0000000;
518 BEPIl
= *BATu
& 0x0FFE0000;
519 if (unlikely(env
->mmu_model
== POWERPC_MMU_601
)) {
520 bat_601_size_prot(env
, &bl
, &valid
, &prot
, BATu
, BATl
);
522 bat_size_prot(env
, &bl
, &valid
, &prot
, BATu
, BATl
);
524 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx
" BATu " TARGET_FMT_lx
525 " BATl " TARGET_FMT_lx
"\n", __func__
,
526 type
== ACCESS_CODE
? 'I' : 'D', i
, virtual, *BATu
, *BATl
);
527 if ((virtual & 0xF0000000) == BEPIu
&&
528 ((virtual & 0x0FFE0000) & ~bl
) == BEPIl
) {
531 /* Get physical address */
532 ctx
->raddr
= (*BATl
& 0xF0000000) |
533 ((virtual & 0x0FFE0000 & bl
) | (*BATl
& 0x0FFE0000)) |
534 (virtual & 0x0001F000);
535 /* Compute access rights */
537 ret
= check_prot(ctx
->prot
, rw
, type
);
539 LOG_BATS("BAT %d match: r " TARGET_FMT_plx
" prot=%c%c\n",
540 i
, ctx
->raddr
, ctx
->prot
& PAGE_READ
? 'R' : '-',
541 ctx
->prot
& PAGE_WRITE
? 'W' : '-');
547 #if defined(DEBUG_BATS)
548 if (qemu_log_enabled()) {
549 LOG_BATS("no BAT match for " TARGET_FMT_lx
":\n", virtual);
550 for (i
= 0; i
< 4; i
++) {
553 BEPIu
= *BATu
& 0xF0000000;
554 BEPIl
= *BATu
& 0x0FFE0000;
555 bl
= (*BATu
& 0x00001FFC) << 15;
556 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx
" BATu " TARGET_FMT_lx
557 " BATl " TARGET_FMT_lx
" \n\t" TARGET_FMT_lx
" "
558 TARGET_FMT_lx
" " TARGET_FMT_lx
"\n",
559 __func__
, type
== ACCESS_CODE
? 'I' : 'D', i
, virtual,
560 *BATu
, *BATl
, BEPIu
, BEPIl
, bl
);
569 static inline target_phys_addr_t
get_pteg_offset(CPUState
*env
,
570 target_phys_addr_t hash
,
573 return (hash
* pte_size
* 8) & env
->htab_mask
;
576 /* PTE table lookup */
577 static inline int _find_pte(CPUState
*env
, mmu_ctx_t
*ctx
, int is_64b
, int h
,
578 int rw
, int type
, int target_page_bits
)
580 target_phys_addr_t pteg_off
;
581 target_ulong pte0
, pte1
;
585 ret
= -1; /* No entry found */
586 pteg_off
= get_pteg_offset(env
, ctx
->hash
[h
],
587 is_64b
? HASH_PTE_SIZE_64
: HASH_PTE_SIZE_32
);
588 for (i
= 0; i
< 8; i
++) {
589 #if defined(TARGET_PPC64)
591 if (env
->external_htab
) {
592 pte0
= ldq_p(env
->external_htab
+ pteg_off
+ (i
* 16));
593 pte1
= ldq_p(env
->external_htab
+ pteg_off
+ (i
* 16) + 8);
595 pte0
= ldq_phys(env
->htab_base
+ pteg_off
+ (i
* 16));
596 pte1
= ldq_phys(env
->htab_base
+ pteg_off
+ (i
* 16) + 8);
599 /* We have a TLB that saves 4K pages, so let's
600 * split a huge page to 4k chunks */
601 if (target_page_bits
!= TARGET_PAGE_BITS
)
602 pte1
|= (ctx
->eaddr
& (( 1 << target_page_bits
) - 1))
605 r
= pte64_check(ctx
, pte0
, pte1
, h
, rw
, type
);
606 LOG_MMU("Load pte from " TARGET_FMT_lx
" => " TARGET_FMT_lx
" "
607 TARGET_FMT_lx
" %d %d %d " TARGET_FMT_lx
"\n",
608 pteg_off
+ (i
* 16), pte0
, pte1
, (int)(pte0
& 1), h
,
609 (int)((pte0
>> 1) & 1), ctx
->ptem
);
613 if (env
->external_htab
) {
614 pte0
= ldl_p(env
->external_htab
+ pteg_off
+ (i
* 8));
615 pte1
= ldl_p(env
->external_htab
+ pteg_off
+ (i
* 8) + 4);
617 pte0
= ldl_phys(env
->htab_base
+ pteg_off
+ (i
* 8));
618 pte1
= ldl_phys(env
->htab_base
+ pteg_off
+ (i
* 8) + 4);
620 r
= pte32_check(ctx
, pte0
, pte1
, h
, rw
, type
);
621 LOG_MMU("Load pte from " TARGET_FMT_lx
" => " TARGET_FMT_lx
" "
622 TARGET_FMT_lx
" %d %d %d " TARGET_FMT_lx
"\n",
623 pteg_off
+ (i
* 8), pte0
, pte1
, (int)(pte0
>> 31), h
,
624 (int)((pte0
>> 6) & 1), ctx
->ptem
);
628 /* PTE inconsistency */
631 /* Access violation */
641 /* XXX: we should go on looping to check all PTEs consistency
642 * but if we can speed-up the whole thing as the
643 * result would be undefined if PTEs are not consistent.
652 LOG_MMU("found PTE at addr " TARGET_FMT_lx
" prot=%01x ret=%d\n",
653 ctx
->raddr
, ctx
->prot
, ret
);
654 /* Update page flags */
656 if (pte_update_flags(ctx
, &pte1
, ret
, rw
) == 1) {
657 #if defined(TARGET_PPC64)
659 if (env
->external_htab
) {
660 stq_p(env
->external_htab
+ pteg_off
+ (good
* 16) + 8,
663 stq_phys_notdirty(env
->htab_base
+ pteg_off
+
664 (good
* 16) + 8, pte1
);
669 if (env
->external_htab
) {
670 stl_p(env
->external_htab
+ pteg_off
+ (good
* 8) + 4,
673 stl_phys_notdirty(env
->htab_base
+ pteg_off
+
674 (good
* 8) + 4, pte1
);
683 static inline int find_pte(CPUState
*env
, mmu_ctx_t
*ctx
, int h
, int rw
,
684 int type
, int target_page_bits
)
686 #if defined(TARGET_PPC64)
687 if (env
->mmu_model
& POWERPC_MMU_64
)
688 return _find_pte(env
, ctx
, 1, h
, rw
, type
, target_page_bits
);
691 return _find_pte(env
, ctx
, 0, h
, rw
, type
, target_page_bits
);
694 #if defined(TARGET_PPC64)
695 static inline ppc_slb_t
*slb_lookup(CPUPPCState
*env
, target_ulong eaddr
)
697 uint64_t esid_256M
, esid_1T
;
700 LOG_SLB("%s: eaddr " TARGET_FMT_lx
"\n", __func__
, eaddr
);
702 esid_256M
= (eaddr
& SEGMENT_MASK_256M
) | SLB_ESID_V
;
703 esid_1T
= (eaddr
& SEGMENT_MASK_1T
) | SLB_ESID_V
;
705 for (n
= 0; n
< env
->slb_nr
; n
++) {
706 ppc_slb_t
*slb
= &env
->slb
[n
];
708 LOG_SLB("%s: slot %d %016" PRIx64
" %016"
709 PRIx64
"\n", __func__
, n
, slb
->esid
, slb
->vsid
);
710 /* We check for 1T matches on all MMUs here - if the MMU
711 * doesn't have 1T segment support, we will have prevented 1T
712 * entries from being inserted in the slbmte code. */
713 if (((slb
->esid
== esid_256M
) &&
714 ((slb
->vsid
& SLB_VSID_B
) == SLB_VSID_B_256M
))
715 || ((slb
->esid
== esid_1T
) &&
716 ((slb
->vsid
& SLB_VSID_B
) == SLB_VSID_B_1T
))) {
724 void ppc_slb_invalidate_all (CPUPPCState
*env
)
726 int n
, do_invalidate
;
729 /* XXX: Warning: slbia never invalidates the first segment */
730 for (n
= 1; n
< env
->slb_nr
; n
++) {
731 ppc_slb_t
*slb
= &env
->slb
[n
];
733 if (slb
->esid
& SLB_ESID_V
) {
734 slb
->esid
&= ~SLB_ESID_V
;
735 /* XXX: given the fact that segment size is 256 MB or 1TB,
736 * and we still don't have a tlb_flush_mask(env, n, mask)
737 * in Qemu, we just invalidate all TLBs
746 void ppc_slb_invalidate_one (CPUPPCState
*env
, uint64_t T0
)
750 slb
= slb_lookup(env
, T0
);
755 if (slb
->esid
& SLB_ESID_V
) {
756 slb
->esid
&= ~SLB_ESID_V
;
758 /* XXX: given the fact that segment size is 256 MB or 1TB,
759 * and we still don't have a tlb_flush_mask(env, n, mask)
760 * in Qemu, we just invalidate all TLBs
766 int ppc_store_slb (CPUPPCState
*env
, target_ulong rb
, target_ulong rs
)
768 int slot
= rb
& 0xfff;
769 ppc_slb_t
*slb
= &env
->slb
[slot
];
771 if (rb
& (0x1000 - env
->slb_nr
)) {
772 return -1; /* Reserved bits set or slot too high */
774 if (rs
& (SLB_VSID_B
& ~SLB_VSID_B_1T
)) {
775 return -1; /* Bad segment size */
777 if ((rs
& SLB_VSID_B
) && !(env
->mmu_model
& POWERPC_MMU_1TSEG
)) {
778 return -1; /* 1T segment on MMU that doesn't support it */
781 /* Mask out the slot number as we store the entry */
782 slb
->esid
= rb
& (SLB_ESID_ESID
| SLB_ESID_V
);
785 LOG_SLB("%s: %d " TARGET_FMT_lx
" - " TARGET_FMT_lx
" => %016" PRIx64
786 " %016" PRIx64
"\n", __func__
, slot
, rb
, rs
,
787 slb
->esid
, slb
->vsid
);
792 int ppc_load_slb_esid (CPUPPCState
*env
, target_ulong rb
, target_ulong
*rt
)
794 int slot
= rb
& 0xfff;
795 ppc_slb_t
*slb
= &env
->slb
[slot
];
797 if (slot
>= env
->slb_nr
) {
805 int ppc_load_slb_vsid (CPUPPCState
*env
, target_ulong rb
, target_ulong
*rt
)
807 int slot
= rb
& 0xfff;
808 ppc_slb_t
*slb
= &env
->slb
[slot
];
810 if (slot
>= env
->slb_nr
) {
817 #endif /* defined(TARGET_PPC64) */
819 /* Perform segment based translation */
820 static inline int get_segment(CPUState
*env
, mmu_ctx_t
*ctx
,
821 target_ulong eaddr
, int rw
, int type
)
823 target_phys_addr_t hash
;
825 int ds
, pr
, target_page_bits
;
830 #if defined(TARGET_PPC64)
831 if (env
->mmu_model
& POWERPC_MMU_64
) {
833 target_ulong pageaddr
;
836 LOG_MMU("Check SLBs\n");
837 slb
= slb_lookup(env
, eaddr
);
842 if (slb
->vsid
& SLB_VSID_B
) {
843 vsid
= (slb
->vsid
& SLB_VSID_VSID
) >> SLB_VSID_SHIFT_1T
;
846 vsid
= (slb
->vsid
& SLB_VSID_VSID
) >> SLB_VSID_SHIFT
;
850 target_page_bits
= (slb
->vsid
& SLB_VSID_L
)
851 ? TARGET_PAGE_BITS_16M
: TARGET_PAGE_BITS
;
852 ctx
->key
= !!(pr
? (slb
->vsid
& SLB_VSID_KP
)
853 : (slb
->vsid
& SLB_VSID_KS
));
855 ctx
->nx
= !!(slb
->vsid
& SLB_VSID_N
);
857 pageaddr
= eaddr
& ((1ULL << segment_bits
)
858 - (1ULL << target_page_bits
));
859 if (slb
->vsid
& SLB_VSID_B
) {
860 hash
= vsid
^ (vsid
<< 25) ^ (pageaddr
>> target_page_bits
);
862 hash
= vsid
^ (pageaddr
>> target_page_bits
);
864 /* Only 5 bits of the page index are used in the AVPN */
865 ctx
->ptem
= (slb
->vsid
& SLB_VSID_PTEM
) |
866 ((pageaddr
>> 16) & ((1ULL << segment_bits
) - 0x80));
868 #endif /* defined(TARGET_PPC64) */
870 target_ulong sr
, pgidx
;
872 sr
= env
->sr
[eaddr
>> 28];
873 ctx
->key
= (((sr
& 0x20000000) && (pr
!= 0)) ||
874 ((sr
& 0x40000000) && (pr
== 0))) ? 1 : 0;
875 ds
= sr
& 0x80000000 ? 1 : 0;
876 ctx
->nx
= sr
& 0x10000000 ? 1 : 0;
877 vsid
= sr
& 0x00FFFFFF;
878 target_page_bits
= TARGET_PAGE_BITS
;
879 LOG_MMU("Check segment v=" TARGET_FMT_lx
" %d " TARGET_FMT_lx
" nip="
880 TARGET_FMT_lx
" lr=" TARGET_FMT_lx
881 " ir=%d dr=%d pr=%d %d t=%d\n",
882 eaddr
, (int)(eaddr
>> 28), sr
, env
->nip
, env
->lr
, (int)msr_ir
,
883 (int)msr_dr
, pr
!= 0 ? 1 : 0, rw
, type
);
884 pgidx
= (eaddr
& ~SEGMENT_MASK_256M
) >> target_page_bits
;
886 ctx
->ptem
= (vsid
<< 7) | (pgidx
>> 10);
888 LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx
"\n",
889 ctx
->key
, ds
, ctx
->nx
, vsid
);
892 /* Check if instruction fetch is allowed, if needed */
893 if (type
!= ACCESS_CODE
|| ctx
->nx
== 0) {
894 /* Page address translation */
895 LOG_MMU("htab_base " TARGET_FMT_plx
" htab_mask " TARGET_FMT_plx
896 " hash " TARGET_FMT_plx
"\n",
897 env
->htab_base
, env
->htab_mask
, hash
);
899 ctx
->hash
[1] = ~hash
;
901 /* Initialize real address with an invalid value */
902 ctx
->raddr
= (target_phys_addr_t
)-1ULL;
903 if (unlikely(env
->mmu_model
== POWERPC_MMU_SOFT_6xx
||
904 env
->mmu_model
== POWERPC_MMU_SOFT_74xx
)) {
905 /* Software TLB search */
906 ret
= ppc6xx_tlb_check(env
, ctx
, eaddr
, rw
, type
);
908 LOG_MMU("0 htab=" TARGET_FMT_plx
"/" TARGET_FMT_plx
909 " vsid=" TARGET_FMT_lx
" ptem=" TARGET_FMT_lx
910 " hash=" TARGET_FMT_plx
"\n",
911 env
->htab_base
, env
->htab_mask
, vsid
, ctx
->ptem
,
913 /* Primary table lookup */
914 ret
= find_pte(env
, ctx
, 0, rw
, type
, target_page_bits
);
916 /* Secondary table lookup */
917 if (eaddr
!= 0xEFFFFFFF)
918 LOG_MMU("1 htab=" TARGET_FMT_plx
"/" TARGET_FMT_plx
919 " vsid=" TARGET_FMT_lx
" api=" TARGET_FMT_lx
920 " hash=" TARGET_FMT_plx
"\n", env
->htab_base
,
921 env
->htab_mask
, vsid
, ctx
->ptem
, ctx
->hash
[1]);
922 ret2
= find_pte(env
, ctx
, 1, rw
, type
,
928 #if defined (DUMP_PAGE_TABLES)
929 if (qemu_log_enabled()) {
930 target_phys_addr_t curaddr
;
931 uint32_t a0
, a1
, a2
, a3
;
932 qemu_log("Page table: " TARGET_FMT_plx
" len " TARGET_FMT_plx
933 "\n", sdr
, mask
+ 0x80);
934 for (curaddr
= sdr
; curaddr
< (sdr
+ mask
+ 0x80);
936 a0
= ldl_phys(curaddr
);
937 a1
= ldl_phys(curaddr
+ 4);
938 a2
= ldl_phys(curaddr
+ 8);
939 a3
= ldl_phys(curaddr
+ 12);
940 if (a0
!= 0 || a1
!= 0 || a2
!= 0 || a3
!= 0) {
941 qemu_log(TARGET_FMT_plx
": %08x %08x %08x %08x\n",
942 curaddr
, a0
, a1
, a2
, a3
);
948 LOG_MMU("No access allowed\n");
952 LOG_MMU("direct store...\n");
953 /* Direct-store segment : absolutely *BUGGY* for now */
956 /* Integer load/store : only access allowed */
959 /* No code fetch is allowed in direct-store areas */
962 /* Floating point load/store */
965 /* lwarx, ldarx or srwcx. */
968 /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
969 /* Should make the instruction do no-op.
970 * As it already do no-op, it's quite easy :-)
978 qemu_log("ERROR: instruction should not need "
979 "address translation\n");
982 if ((rw
== 1 || ctx
->key
!= 1) && (rw
== 0 || ctx
->key
!= 0)) {
993 /* Generic TLB check function for embedded PowerPC implementations */
994 int ppcemb_tlb_check(CPUState
*env
, ppcemb_tlb_t
*tlb
,
995 target_phys_addr_t
*raddrp
,
996 target_ulong address
, uint32_t pid
, int ext
,
1001 /* Check valid flag */
1002 if (!(tlb
->prot
& PAGE_VALID
)) {
1005 mask
= ~(tlb
->size
- 1);
1006 LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx
" PID %u <=> " TARGET_FMT_lx
1007 " " TARGET_FMT_lx
" %u %x\n", __func__
, i
, address
, pid
, tlb
->EPN
,
1008 mask
, (uint32_t)tlb
->PID
, tlb
->prot
);
1010 if (tlb
->PID
!= 0 && tlb
->PID
!= pid
)
1012 /* Check effective address */
1013 if ((address
& mask
) != tlb
->EPN
)
1015 *raddrp
= (tlb
->RPN
& mask
) | (address
& ~mask
);
1016 #if (TARGET_PHYS_ADDR_BITS >= 36)
1018 /* Extend the physical address to 36 bits */
1019 *raddrp
|= (target_phys_addr_t
)(tlb
->RPN
& 0xF) << 32;
1026 /* Generic TLB search function for PowerPC embedded implementations */
1027 int ppcemb_tlb_search (CPUPPCState
*env
, target_ulong address
, uint32_t pid
)
1030 target_phys_addr_t raddr
;
1033 /* Default return value is no match */
1035 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1036 tlb
= &env
->tlb
[i
].tlbe
;
1037 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
, pid
, 0, i
) == 0) {
1046 /* Helpers specific to PowerPC 40x implementations */
1047 static inline void ppc4xx_tlb_invalidate_all(CPUState
*env
)
1052 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1053 tlb
= &env
->tlb
[i
].tlbe
;
1054 tlb
->prot
&= ~PAGE_VALID
;
1059 static inline void ppc4xx_tlb_invalidate_virt(CPUState
*env
,
1060 target_ulong eaddr
, uint32_t pid
)
1062 #if !defined(FLUSH_ALL_TLBS)
1064 target_phys_addr_t raddr
;
1065 target_ulong page
, end
;
1068 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1069 tlb
= &env
->tlb
[i
].tlbe
;
1070 if (ppcemb_tlb_check(env
, tlb
, &raddr
, eaddr
, pid
, 0, i
) == 0) {
1071 end
= tlb
->EPN
+ tlb
->size
;
1072 for (page
= tlb
->EPN
; page
< end
; page
+= TARGET_PAGE_SIZE
)
1073 tlb_flush_page(env
, page
);
1074 tlb
->prot
&= ~PAGE_VALID
;
1079 ppc4xx_tlb_invalidate_all(env
);
1083 static int mmu40x_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1084 target_ulong address
, int rw
, int access_type
)
1087 target_phys_addr_t raddr
;
1088 int i
, ret
, zsel
, zpr
, pr
;
1091 raddr
= (target_phys_addr_t
)-1ULL;
1093 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1094 tlb
= &env
->tlb
[i
].tlbe
;
1095 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
,
1096 env
->spr
[SPR_40x_PID
], 0, i
) < 0)
1098 zsel
= (tlb
->attr
>> 4) & 0xF;
1099 zpr
= (env
->spr
[SPR_40x_ZPR
] >> (30 - (2 * zsel
))) & 0x3;
1100 LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1101 __func__
, i
, zsel
, zpr
, rw
, tlb
->attr
);
1102 /* Check execute enable bit */
1109 /* All accesses granted */
1110 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
1115 /* Raise Zone protection fault. */
1116 env
->spr
[SPR_40x_ESR
] = 1 << 22;
1124 /* Check from TLB entry */
1125 ctx
->prot
= tlb
->prot
;
1126 ret
= check_prot(ctx
->prot
, rw
, access_type
);
1128 env
->spr
[SPR_40x_ESR
] = 0;
1133 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1134 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1139 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1140 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1145 void store_40x_sler (CPUPPCState
*env
, uint32_t val
)
1147 /* XXX: TO BE FIXED */
1148 if (val
!= 0x00000000) {
1149 cpu_abort(env
, "Little-endian regions are not supported by now\n");
1151 env
->spr
[SPR_405_SLER
] = val
;
1154 static inline int mmubooke_check_tlb (CPUState
*env
, ppcemb_tlb_t
*tlb
,
1155 target_phys_addr_t
*raddr
, int *prot
,
1156 target_ulong address
, int rw
,
1157 int access_type
, int i
)
1161 if (ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1162 env
->spr
[SPR_BOOKE_PID
],
1163 !env
->nb_pids
, i
) >= 0) {
1167 if (env
->spr
[SPR_BOOKE_PID1
] &&
1168 ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1169 env
->spr
[SPR_BOOKE_PID1
], 0, i
) >= 0) {
1173 if (env
->spr
[SPR_BOOKE_PID2
] &&
1174 ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1175 env
->spr
[SPR_BOOKE_PID2
], 0, i
) >= 0) {
1179 LOG_SWTLB("%s: TLB entry not found\n", __func__
);
1185 _prot
= tlb
->prot
& 0xF;
1187 _prot
= (tlb
->prot
>> 4) & 0xF;
1190 /* Check the address space */
1191 if (access_type
== ACCESS_CODE
) {
1192 if (msr_ir
!= (tlb
->attr
& 1)) {
1193 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1198 if (_prot
& PAGE_EXEC
) {
1199 LOG_SWTLB("%s: good TLB!\n", __func__
);
1203 LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__
, _prot
);
1206 if (msr_dr
!= (tlb
->attr
& 1)) {
1207 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1212 if ((!rw
&& _prot
& PAGE_READ
) || (rw
&& (_prot
& PAGE_WRITE
))) {
1213 LOG_SWTLB("%s: found TLB!\n", __func__
);
1217 LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__
, _prot
);
1224 static int mmubooke_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1225 target_ulong address
, int rw
,
1229 target_phys_addr_t raddr
;
1233 raddr
= (target_phys_addr_t
)-1ULL;
1234 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1235 tlb
= &env
->tlb
[i
].tlbe
;
1236 ret
= mmubooke_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
, rw
,
1245 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1246 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1249 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1250 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1256 void booke206_flush_tlb(CPUState
*env
, int flags
, const int check_iprot
)
1260 ppc_tlb_t
*tlb
= env
->tlb
;
1262 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1263 if (flags
& (1 << i
)) {
1264 tlb_size
= booke206_tlb_size(env
, i
);
1265 for (j
= 0; j
< tlb_size
; j
++) {
1266 if (!check_iprot
|| !(tlb
[j
].tlbe
.attr
& MAS1_IPROT
)) {
1267 tlb
[j
].tlbe
.prot
= 0;
1271 tlb
+= booke206_tlb_size(env
, i
);
1277 static int mmubooke206_get_physical_address(CPUState
*env
, mmu_ctx_t
*ctx
,
1278 target_ulong address
, int rw
,
1282 target_phys_addr_t raddr
;
1286 raddr
= (target_phys_addr_t
)-1ULL;
1288 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1289 int ways
= booke206_tlb_ways(env
, i
);
1291 for (j
= 0; j
< ways
; j
++) {
1292 tlb
= booke206_get_tlbe(env
, i
, address
, j
);
1293 ret
= mmubooke_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
, rw
,
1305 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1306 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1309 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1310 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1316 static inline int check_physical(CPUState
*env
, mmu_ctx_t
*ctx
,
1317 target_ulong eaddr
, int rw
)
1322 ctx
->prot
= PAGE_READ
| PAGE_EXEC
;
1324 switch (env
->mmu_model
) {
1325 case POWERPC_MMU_32B
:
1326 case POWERPC_MMU_601
:
1327 case POWERPC_MMU_SOFT_6xx
:
1328 case POWERPC_MMU_SOFT_74xx
:
1329 case POWERPC_MMU_SOFT_4xx
:
1330 case POWERPC_MMU_REAL
:
1331 case POWERPC_MMU_BOOKE
:
1332 ctx
->prot
|= PAGE_WRITE
;
1334 #if defined(TARGET_PPC64)
1335 case POWERPC_MMU_620
:
1336 case POWERPC_MMU_64B
:
1337 case POWERPC_MMU_2_06
:
1338 /* Real address are 60 bits long */
1339 ctx
->raddr
&= 0x0FFFFFFFFFFFFFFFULL
;
1340 ctx
->prot
|= PAGE_WRITE
;
1343 case POWERPC_MMU_SOFT_4xx_Z
:
1344 if (unlikely(msr_pe
!= 0)) {
1345 /* 403 family add some particular protections,
1346 * using PBL/PBU registers for accesses with no translation.
1349 /* Check PLB validity */
1350 (env
->pb
[0] < env
->pb
[1] &&
1351 /* and address in plb area */
1352 eaddr
>= env
->pb
[0] && eaddr
< env
->pb
[1]) ||
1353 (env
->pb
[2] < env
->pb
[3] &&
1354 eaddr
>= env
->pb
[2] && eaddr
< env
->pb
[3]) ? 1 : 0;
1355 if (in_plb
^ msr_px
) {
1356 /* Access in protected area */
1358 /* Access is not allowed */
1362 /* Read-write access is allowed */
1363 ctx
->prot
|= PAGE_WRITE
;
1367 case POWERPC_MMU_MPC8xx
:
1369 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1371 case POWERPC_MMU_BOOKE206
:
1372 cpu_abort(env
, "BookE 2.06 MMU doesn't have physical real mode\n");
1375 cpu_abort(env
, "Unknown or invalid MMU model\n");
1382 int get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
, target_ulong eaddr
,
1383 int rw
, int access_type
)
1388 qemu_log("%s\n", __func__
);
1390 if ((access_type
== ACCESS_CODE
&& msr_ir
== 0) ||
1391 (access_type
!= ACCESS_CODE
&& msr_dr
== 0)) {
1392 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1393 /* The BookE MMU always performs address translation. The
1394 IS and DS bits only affect the address space. */
1395 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1397 } else if (env
->mmu_model
== POWERPC_MMU_BOOKE206
) {
1398 ret
= mmubooke206_get_physical_address(env
, ctx
, eaddr
, rw
,
1401 /* No address translation. */
1402 ret
= check_physical(env
, ctx
, eaddr
, rw
);
1406 switch (env
->mmu_model
) {
1407 case POWERPC_MMU_32B
:
1408 case POWERPC_MMU_601
:
1409 case POWERPC_MMU_SOFT_6xx
:
1410 case POWERPC_MMU_SOFT_74xx
:
1411 /* Try to find a BAT */
1412 if (env
->nb_BATs
!= 0)
1413 ret
= get_bat(env
, ctx
, eaddr
, rw
, access_type
);
1414 #if defined(TARGET_PPC64)
1415 case POWERPC_MMU_620
:
1416 case POWERPC_MMU_64B
:
1417 case POWERPC_MMU_2_06
:
1420 /* We didn't match any BAT entry or don't have BATs */
1421 ret
= get_segment(env
, ctx
, eaddr
, rw
, access_type
);
1424 case POWERPC_MMU_SOFT_4xx
:
1425 case POWERPC_MMU_SOFT_4xx_Z
:
1426 ret
= mmu40x_get_physical_address(env
, ctx
, eaddr
,
1429 case POWERPC_MMU_BOOKE
:
1430 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1433 case POWERPC_MMU_BOOKE206
:
1434 ret
= mmubooke206_get_physical_address(env
, ctx
, eaddr
, rw
,
1437 case POWERPC_MMU_MPC8xx
:
1439 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1441 case POWERPC_MMU_REAL
:
1442 cpu_abort(env
, "PowerPC in real mode do not do any translation\n");
1445 cpu_abort(env
, "Unknown or invalid MMU model\n");
1450 qemu_log("%s address " TARGET_FMT_lx
" => %d " TARGET_FMT_plx
"\n",
1451 __func__
, eaddr
, ret
, ctx
->raddr
);
1457 target_phys_addr_t
cpu_get_phys_page_debug (CPUState
*env
, target_ulong addr
)
1461 if (unlikely(get_physical_address(env
, &ctx
, addr
, 0, ACCESS_INT
) != 0))
1464 return ctx
.raddr
& TARGET_PAGE_MASK
;
1467 static void booke206_update_mas_tlb_miss(CPUState
*env
, target_ulong address
,
1470 env
->spr
[SPR_BOOKE_MAS0
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TLBSELD_MASK
;
1471 env
->spr
[SPR_BOOKE_MAS1
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TSIZED_MASK
;
1472 env
->spr
[SPR_BOOKE_MAS2
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_WIMGED_MASK
;
1473 env
->spr
[SPR_BOOKE_MAS3
] = 0;
1474 env
->spr
[SPR_BOOKE_MAS6
] = 0;
1475 env
->spr
[SPR_BOOKE_MAS7
] = 0;
1478 if (((rw
== 2) && msr_ir
) || ((rw
!= 2) && msr_dr
)) {
1479 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_TS
;
1480 env
->spr
[SPR_BOOKE_MAS6
] |= MAS6_SAS
;
1483 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_VALID
;
1484 env
->spr
[SPR_BOOKE_MAS2
] |= address
& MAS2_EPN_MASK
;
1486 switch (env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TIDSELD_PIDZ
) {
1487 case MAS4_TIDSELD_PID0
:
1488 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID
] << MAS1_TID_SHIFT
;
1490 case MAS4_TIDSELD_PID1
:
1491 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID1
] << MAS1_TID_SHIFT
;
1493 case MAS4_TIDSELD_PID2
:
1494 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID2
] << MAS1_TID_SHIFT
;
1498 env
->spr
[SPR_BOOKE_MAS6
] |= env
->spr
[SPR_BOOKE_PID
] << 16;
1500 /* next victim logic */
1501 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_ESEL_SHIFT
;
1503 env
->last_way
&= booke206_tlb_ways(env
, 0) - 1;
1504 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_NV_SHIFT
;
1507 /* Perform address translation */
1508 int cpu_ppc_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
1509 int mmu_idx
, int is_softmmu
)
1518 access_type
= ACCESS_CODE
;
1521 access_type
= env
->access_type
;
1523 ret
= get_physical_address(env
, &ctx
, address
, rw
, access_type
);
1525 tlb_set_page(env
, address
& TARGET_PAGE_MASK
,
1526 ctx
.raddr
& TARGET_PAGE_MASK
, ctx
.prot
,
1527 mmu_idx
, TARGET_PAGE_SIZE
);
1529 } else if (ret
< 0) {
1531 if (access_type
== ACCESS_CODE
) {
1534 /* No matches in page tables or TLB */
1535 switch (env
->mmu_model
) {
1536 case POWERPC_MMU_SOFT_6xx
:
1537 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1538 env
->error_code
= 1 << 18;
1539 env
->spr
[SPR_IMISS
] = address
;
1540 env
->spr
[SPR_ICMP
] = 0x80000000 | ctx
.ptem
;
1542 case POWERPC_MMU_SOFT_74xx
:
1543 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1545 case POWERPC_MMU_SOFT_4xx
:
1546 case POWERPC_MMU_SOFT_4xx_Z
:
1547 env
->exception_index
= POWERPC_EXCP_ITLB
;
1548 env
->error_code
= 0;
1549 env
->spr
[SPR_40x_DEAR
] = address
;
1550 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1552 case POWERPC_MMU_32B
:
1553 case POWERPC_MMU_601
:
1554 #if defined(TARGET_PPC64)
1555 case POWERPC_MMU_620
:
1556 case POWERPC_MMU_64B
:
1557 case POWERPC_MMU_2_06
:
1559 env
->exception_index
= POWERPC_EXCP_ISI
;
1560 env
->error_code
= 0x40000000;
1562 case POWERPC_MMU_BOOKE206
:
1563 booke206_update_mas_tlb_miss(env
, address
, rw
);
1565 case POWERPC_MMU_BOOKE
:
1566 env
->exception_index
= POWERPC_EXCP_ITLB
;
1567 env
->error_code
= 0;
1568 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1570 case POWERPC_MMU_MPC8xx
:
1572 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1574 case POWERPC_MMU_REAL
:
1575 cpu_abort(env
, "PowerPC in real mode should never raise "
1576 "any MMU exceptions\n");
1579 cpu_abort(env
, "Unknown or invalid MMU model\n");
1584 /* Access rights violation */
1585 env
->exception_index
= POWERPC_EXCP_ISI
;
1586 env
->error_code
= 0x08000000;
1589 /* No execute protection violation */
1590 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1591 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1592 env
->spr
[SPR_BOOKE_ESR
] = 0x00000000;
1594 env
->exception_index
= POWERPC_EXCP_ISI
;
1595 env
->error_code
= 0x10000000;
1598 /* Direct store exception */
1599 /* No code fetch is allowed in direct-store areas */
1600 env
->exception_index
= POWERPC_EXCP_ISI
;
1601 env
->error_code
= 0x10000000;
1603 #if defined(TARGET_PPC64)
1605 /* No match in segment table */
1606 if (env
->mmu_model
== POWERPC_MMU_620
) {
1607 env
->exception_index
= POWERPC_EXCP_ISI
;
1608 /* XXX: this might be incorrect */
1609 env
->error_code
= 0x40000000;
1611 env
->exception_index
= POWERPC_EXCP_ISEG
;
1612 env
->error_code
= 0;
1620 /* No matches in page tables or TLB */
1621 switch (env
->mmu_model
) {
1622 case POWERPC_MMU_SOFT_6xx
:
1624 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1625 env
->error_code
= 1 << 16;
1627 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1628 env
->error_code
= 0;
1630 env
->spr
[SPR_DMISS
] = address
;
1631 env
->spr
[SPR_DCMP
] = 0x80000000 | ctx
.ptem
;
1633 env
->error_code
|= ctx
.key
<< 19;
1634 env
->spr
[SPR_HASH1
] = env
->htab_base
+
1635 get_pteg_offset(env
, ctx
.hash
[0], HASH_PTE_SIZE_32
);
1636 env
->spr
[SPR_HASH2
] = env
->htab_base
+
1637 get_pteg_offset(env
, ctx
.hash
[1], HASH_PTE_SIZE_32
);
1639 case POWERPC_MMU_SOFT_74xx
:
1641 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1643 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1646 /* Implement LRU algorithm */
1647 env
->error_code
= ctx
.key
<< 19;
1648 env
->spr
[SPR_TLBMISS
] = (address
& ~((target_ulong
)0x3)) |
1649 ((env
->last_way
+ 1) & (env
->nb_ways
- 1));
1650 env
->spr
[SPR_PTEHI
] = 0x80000000 | ctx
.ptem
;
1652 case POWERPC_MMU_SOFT_4xx
:
1653 case POWERPC_MMU_SOFT_4xx_Z
:
1654 env
->exception_index
= POWERPC_EXCP_DTLB
;
1655 env
->error_code
= 0;
1656 env
->spr
[SPR_40x_DEAR
] = address
;
1658 env
->spr
[SPR_40x_ESR
] = 0x00800000;
1660 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1662 case POWERPC_MMU_32B
:
1663 case POWERPC_MMU_601
:
1664 #if defined(TARGET_PPC64)
1665 case POWERPC_MMU_620
:
1666 case POWERPC_MMU_64B
:
1667 case POWERPC_MMU_2_06
:
1669 env
->exception_index
= POWERPC_EXCP_DSI
;
1670 env
->error_code
= 0;
1671 env
->spr
[SPR_DAR
] = address
;
1673 env
->spr
[SPR_DSISR
] = 0x42000000;
1675 env
->spr
[SPR_DSISR
] = 0x40000000;
1677 case POWERPC_MMU_MPC8xx
:
1679 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1681 case POWERPC_MMU_BOOKE206
:
1682 booke206_update_mas_tlb_miss(env
, address
, rw
);
1684 case POWERPC_MMU_BOOKE
:
1685 env
->exception_index
= POWERPC_EXCP_DTLB
;
1686 env
->error_code
= 0;
1687 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1688 env
->spr
[SPR_BOOKE_ESR
] = rw
? 1 << ESR_ST
: 0;
1690 case POWERPC_MMU_REAL
:
1691 cpu_abort(env
, "PowerPC in real mode should never raise "
1692 "any MMU exceptions\n");
1695 cpu_abort(env
, "Unknown or invalid MMU model\n");
1700 /* Access rights violation */
1701 env
->exception_index
= POWERPC_EXCP_DSI
;
1702 env
->error_code
= 0;
1703 if (env
->mmu_model
== POWERPC_MMU_SOFT_4xx
1704 || env
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
) {
1705 env
->spr
[SPR_40x_DEAR
] = address
;
1707 env
->spr
[SPR_40x_ESR
] |= 0x00800000;
1709 } else if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1710 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1711 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1712 env
->spr
[SPR_BOOKE_ESR
] = rw
? 1 << ESR_ST
: 0;
1714 env
->spr
[SPR_DAR
] = address
;
1716 env
->spr
[SPR_DSISR
] = 0x0A000000;
1718 env
->spr
[SPR_DSISR
] = 0x08000000;
1723 /* Direct store exception */
1724 switch (access_type
) {
1726 /* Floating point load/store */
1727 env
->exception_index
= POWERPC_EXCP_ALIGN
;
1728 env
->error_code
= POWERPC_EXCP_ALIGN_FP
;
1729 env
->spr
[SPR_DAR
] = address
;
1732 /* lwarx, ldarx or stwcx. */
1733 env
->exception_index
= POWERPC_EXCP_DSI
;
1734 env
->error_code
= 0;
1735 env
->spr
[SPR_DAR
] = address
;
1737 env
->spr
[SPR_DSISR
] = 0x06000000;
1739 env
->spr
[SPR_DSISR
] = 0x04000000;
1742 /* eciwx or ecowx */
1743 env
->exception_index
= POWERPC_EXCP_DSI
;
1744 env
->error_code
= 0;
1745 env
->spr
[SPR_DAR
] = address
;
1747 env
->spr
[SPR_DSISR
] = 0x06100000;
1749 env
->spr
[SPR_DSISR
] = 0x04100000;
1752 printf("DSI: invalid exception (%d)\n", ret
);
1753 env
->exception_index
= POWERPC_EXCP_PROGRAM
;
1755 POWERPC_EXCP_INVAL
| POWERPC_EXCP_INVAL_INVAL
;
1756 env
->spr
[SPR_DAR
] = address
;
1760 #if defined(TARGET_PPC64)
1762 /* No match in segment table */
1763 if (env
->mmu_model
== POWERPC_MMU_620
) {
1764 env
->exception_index
= POWERPC_EXCP_DSI
;
1765 env
->error_code
= 0;
1766 env
->spr
[SPR_DAR
] = address
;
1767 /* XXX: this might be incorrect */
1769 env
->spr
[SPR_DSISR
] = 0x42000000;
1771 env
->spr
[SPR_DSISR
] = 0x40000000;
1773 env
->exception_index
= POWERPC_EXCP_DSEG
;
1774 env
->error_code
= 0;
1775 env
->spr
[SPR_DAR
] = address
;
1782 printf("%s: set exception to %d %02x\n", __func__
,
1783 env
->exception
, env
->error_code
);
1791 /*****************************************************************************/
1792 /* BATs management */
1793 #if !defined(FLUSH_ALL_TLBS)
1794 static inline void do_invalidate_BAT(CPUPPCState
*env
, target_ulong BATu
,
1797 target_ulong base
, end
, page
;
1799 base
= BATu
& ~0x0001FFFF;
1800 end
= base
+ mask
+ 0x00020000;
1801 LOG_BATS("Flush BAT from " TARGET_FMT_lx
" to " TARGET_FMT_lx
" ("
1802 TARGET_FMT_lx
")\n", base
, end
, mask
);
1803 for (page
= base
; page
!= end
; page
+= TARGET_PAGE_SIZE
)
1804 tlb_flush_page(env
, page
);
1805 LOG_BATS("Flush done\n");
1809 static inline void dump_store_bat(CPUPPCState
*env
, char ID
, int ul
, int nr
,
1812 LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx
" (" TARGET_FMT_lx
")\n", ID
,
1813 nr
, ul
== 0 ? 'u' : 'l', value
, env
->nip
);
1816 void ppc_store_ibatu (CPUPPCState
*env
, int nr
, target_ulong value
)
1820 dump_store_bat(env
, 'I', 0, nr
, value
);
1821 if (env
->IBAT
[0][nr
] != value
) {
1822 mask
= (value
<< 15) & 0x0FFE0000UL
;
1823 #if !defined(FLUSH_ALL_TLBS)
1824 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1826 /* When storing valid upper BAT, mask BEPI and BRPN
1827 * and invalidate all TLBs covered by this BAT
1829 mask
= (value
<< 15) & 0x0FFE0000UL
;
1830 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1831 (value
& ~0x0001FFFFUL
& ~mask
);
1832 env
->IBAT
[1][nr
] = (env
->IBAT
[1][nr
] & 0x0000007B) |
1833 (env
->IBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
1834 #if !defined(FLUSH_ALL_TLBS)
1835 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1842 void ppc_store_ibatl (CPUPPCState
*env
, int nr
, target_ulong value
)
1844 dump_store_bat(env
, 'I', 1, nr
, value
);
1845 env
->IBAT
[1][nr
] = value
;
1848 void ppc_store_dbatu (CPUPPCState
*env
, int nr
, target_ulong value
)
1852 dump_store_bat(env
, 'D', 0, nr
, value
);
1853 if (env
->DBAT
[0][nr
] != value
) {
1854 /* When storing valid upper BAT, mask BEPI and BRPN
1855 * and invalidate all TLBs covered by this BAT
1857 mask
= (value
<< 15) & 0x0FFE0000UL
;
1858 #if !defined(FLUSH_ALL_TLBS)
1859 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
1861 mask
= (value
<< 15) & 0x0FFE0000UL
;
1862 env
->DBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1863 (value
& ~0x0001FFFFUL
& ~mask
);
1864 env
->DBAT
[1][nr
] = (env
->DBAT
[1][nr
] & 0x0000007B) |
1865 (env
->DBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
1866 #if !defined(FLUSH_ALL_TLBS)
1867 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
1874 void ppc_store_dbatl (CPUPPCState
*env
, int nr
, target_ulong value
)
1876 dump_store_bat(env
, 'D', 1, nr
, value
);
1877 env
->DBAT
[1][nr
] = value
;
1880 void ppc_store_ibatu_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
1883 #if defined(FLUSH_ALL_TLBS)
1887 dump_store_bat(env
, 'I', 0, nr
, value
);
1888 if (env
->IBAT
[0][nr
] != value
) {
1889 #if defined(FLUSH_ALL_TLBS)
1892 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
1893 if (env
->IBAT
[1][nr
] & 0x40) {
1894 /* Invalidate BAT only if it is valid */
1895 #if !defined(FLUSH_ALL_TLBS)
1896 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1901 /* When storing valid upper BAT, mask BEPI and BRPN
1902 * and invalidate all TLBs covered by this BAT
1904 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1905 (value
& ~0x0001FFFFUL
& ~mask
);
1906 env
->DBAT
[0][nr
] = env
->IBAT
[0][nr
];
1907 if (env
->IBAT
[1][nr
] & 0x40) {
1908 #if !defined(FLUSH_ALL_TLBS)
1909 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1914 #if defined(FLUSH_ALL_TLBS)
1921 void ppc_store_ibatl_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
1924 #if defined(FLUSH_ALL_TLBS)
1928 dump_store_bat(env
, 'I', 1, nr
, value
);
1929 if (env
->IBAT
[1][nr
] != value
) {
1930 #if defined(FLUSH_ALL_TLBS)
1933 if (env
->IBAT
[1][nr
] & 0x40) {
1934 #if !defined(FLUSH_ALL_TLBS)
1935 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
1936 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1942 #if !defined(FLUSH_ALL_TLBS)
1943 mask
= (value
<< 17) & 0x0FFE0000UL
;
1944 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1949 env
->IBAT
[1][nr
] = value
;
1950 env
->DBAT
[1][nr
] = value
;
1951 #if defined(FLUSH_ALL_TLBS)
1958 /*****************************************************************************/
1959 /* TLB management */
1960 void ppc_tlb_invalidate_all (CPUPPCState
*env
)
1962 switch (env
->mmu_model
) {
1963 case POWERPC_MMU_SOFT_6xx
:
1964 case POWERPC_MMU_SOFT_74xx
:
1965 ppc6xx_tlb_invalidate_all(env
);
1967 case POWERPC_MMU_SOFT_4xx
:
1968 case POWERPC_MMU_SOFT_4xx_Z
:
1969 ppc4xx_tlb_invalidate_all(env
);
1971 case POWERPC_MMU_REAL
:
1972 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
1974 case POWERPC_MMU_MPC8xx
:
1976 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1978 case POWERPC_MMU_BOOKE
:
1981 case POWERPC_MMU_BOOKE206
:
1982 booke206_flush_tlb(env
, -1, 0);
1984 case POWERPC_MMU_32B
:
1985 case POWERPC_MMU_601
:
1986 #if defined(TARGET_PPC64)
1987 case POWERPC_MMU_620
:
1988 case POWERPC_MMU_64B
:
1989 case POWERPC_MMU_2_06
:
1990 #endif /* defined(TARGET_PPC64) */
1995 cpu_abort(env
, "Unknown MMU model\n");
2000 void ppc_tlb_invalidate_one (CPUPPCState
*env
, target_ulong addr
)
2002 #if !defined(FLUSH_ALL_TLBS)
2003 addr
&= TARGET_PAGE_MASK
;
2004 switch (env
->mmu_model
) {
2005 case POWERPC_MMU_SOFT_6xx
:
2006 case POWERPC_MMU_SOFT_74xx
:
2007 ppc6xx_tlb_invalidate_virt(env
, addr
, 0);
2008 if (env
->id_tlbs
== 1)
2009 ppc6xx_tlb_invalidate_virt(env
, addr
, 1);
2011 case POWERPC_MMU_SOFT_4xx
:
2012 case POWERPC_MMU_SOFT_4xx_Z
:
2013 ppc4xx_tlb_invalidate_virt(env
, addr
, env
->spr
[SPR_40x_PID
]);
2015 case POWERPC_MMU_REAL
:
2016 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
2018 case POWERPC_MMU_MPC8xx
:
2020 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
2022 case POWERPC_MMU_BOOKE
:
2024 cpu_abort(env
, "BookE MMU model is not implemented\n");
2026 case POWERPC_MMU_BOOKE206
:
2028 cpu_abort(env
, "BookE 2.06 MMU model is not implemented\n");
2030 case POWERPC_MMU_32B
:
2031 case POWERPC_MMU_601
:
2032 /* tlbie invalidate TLBs for all segments */
2033 addr
&= ~((target_ulong
)-1ULL << 28);
2034 /* XXX: this case should be optimized,
2035 * giving a mask to tlb_flush_page
2037 tlb_flush_page(env
, addr
| (0x0 << 28));
2038 tlb_flush_page(env
, addr
| (0x1 << 28));
2039 tlb_flush_page(env
, addr
| (0x2 << 28));
2040 tlb_flush_page(env
, addr
| (0x3 << 28));
2041 tlb_flush_page(env
, addr
| (0x4 << 28));
2042 tlb_flush_page(env
, addr
| (0x5 << 28));
2043 tlb_flush_page(env
, addr
| (0x6 << 28));
2044 tlb_flush_page(env
, addr
| (0x7 << 28));
2045 tlb_flush_page(env
, addr
| (0x8 << 28));
2046 tlb_flush_page(env
, addr
| (0x9 << 28));
2047 tlb_flush_page(env
, addr
| (0xA << 28));
2048 tlb_flush_page(env
, addr
| (0xB << 28));
2049 tlb_flush_page(env
, addr
| (0xC << 28));
2050 tlb_flush_page(env
, addr
| (0xD << 28));
2051 tlb_flush_page(env
, addr
| (0xE << 28));
2052 tlb_flush_page(env
, addr
| (0xF << 28));
2054 #if defined(TARGET_PPC64)
2055 case POWERPC_MMU_620
:
2056 case POWERPC_MMU_64B
:
2057 case POWERPC_MMU_2_06
:
2058 /* tlbie invalidate TLBs for all segments */
2059 /* XXX: given the fact that there are too many segments to invalidate,
2060 * and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
2061 * we just invalidate all TLBs
2065 #endif /* defined(TARGET_PPC64) */
2068 cpu_abort(env
, "Unknown MMU model\n");
2072 ppc_tlb_invalidate_all(env
);
2076 /*****************************************************************************/
2077 /* Special registers manipulation */
2078 #if defined(TARGET_PPC64)
2079 void ppc_store_asr (CPUPPCState
*env
, target_ulong value
)
2081 if (env
->asr
!= value
) {
2088 void ppc_store_sdr1 (CPUPPCState
*env
, target_ulong value
)
2090 LOG_MMU("%s: " TARGET_FMT_lx
"\n", __func__
, value
);
2091 if (env
->spr
[SPR_SDR1
] != value
) {
2092 env
->spr
[SPR_SDR1
] = value
;
2093 #if defined(TARGET_PPC64)
2094 if (env
->mmu_model
& POWERPC_MMU_64
) {
2095 target_ulong htabsize
= value
& SDR_64_HTABSIZE
;
2097 if (htabsize
> 28) {
2098 fprintf(stderr
, "Invalid HTABSIZE 0x" TARGET_FMT_lx
2099 " stored in SDR1\n", htabsize
);
2102 env
->htab_mask
= (1ULL << (htabsize
+ 18)) - 1;
2103 env
->htab_base
= value
& SDR_64_HTABORG
;
2105 #endif /* defined(TARGET_PPC64) */
2107 /* FIXME: Should check for valid HTABMASK values */
2108 env
->htab_mask
= ((value
& SDR_32_HTABMASK
) << 16) | 0xFFFF;
2109 env
->htab_base
= value
& SDR_32_HTABORG
;
2115 #if defined(TARGET_PPC64)
2116 target_ulong
ppc_load_sr (CPUPPCState
*env
, int slb_nr
)
2123 void ppc_store_sr (CPUPPCState
*env
, int srnum
, target_ulong value
)
2125 LOG_MMU("%s: reg=%d " TARGET_FMT_lx
" " TARGET_FMT_lx
"\n", __func__
,
2126 srnum
, value
, env
->sr
[srnum
]);
2127 #if defined(TARGET_PPC64)
2128 if (env
->mmu_model
& POWERPC_MMU_64
) {
2129 uint64_t rb
= 0, rs
= 0;
2132 rb
|= ((uint32_t)srnum
& 0xf) << 28;
2133 /* Set the valid bit */
2136 rb
|= (uint32_t)srnum
;
2139 rs
|= (value
& 0xfffffff) << 12;
2141 rs
|= ((value
>> 27) & 0xf) << 8;
2143 ppc_store_slb(env
, rb
, rs
);
2146 if (env
->sr
[srnum
] != value
) {
2147 env
->sr
[srnum
] = value
;
2148 /* Invalidating 256MB of virtual memory in 4kB pages is way longer than
2149 flusing the whole TLB. */
2150 #if !defined(FLUSH_ALL_TLBS) && 0
2152 target_ulong page
, end
;
2153 /* Invalidate 256 MB of virtual memory */
2154 page
= (16 << 20) * srnum
;
2155 end
= page
+ (16 << 20);
2156 for (; page
!= end
; page
+= TARGET_PAGE_SIZE
)
2157 tlb_flush_page(env
, page
);
2164 #endif /* !defined (CONFIG_USER_ONLY) */
2166 /* GDBstub can read and write MSR... */
2167 void ppc_store_msr (CPUPPCState
*env
, target_ulong value
)
2169 hreg_store_msr(env
, value
, 0);
2172 /*****************************************************************************/
2173 /* Exception processing */
2174 #if defined (CONFIG_USER_ONLY)
2175 void do_interrupt (CPUState
*env
)
2177 env
->exception_index
= POWERPC_EXCP_NONE
;
2178 env
->error_code
= 0;
2181 void ppc_hw_interrupt (CPUState
*env
)
2183 env
->exception_index
= POWERPC_EXCP_NONE
;
2184 env
->error_code
= 0;
2186 #else /* defined (CONFIG_USER_ONLY) */
2187 static inline void dump_syscall(CPUState
*env
)
2189 qemu_log_mask(CPU_LOG_INT
, "syscall r0=%016" PRIx64
" r3=%016" PRIx64
2190 " r4=%016" PRIx64
" r5=%016" PRIx64
" r6=%016" PRIx64
2191 " nip=" TARGET_FMT_lx
"\n",
2192 ppc_dump_gpr(env
, 0), ppc_dump_gpr(env
, 3),
2193 ppc_dump_gpr(env
, 4), ppc_dump_gpr(env
, 5),
2194 ppc_dump_gpr(env
, 6), env
->nip
);
2197 /* Note that this function should be greatly optimized
2198 * when called with a constant excp, from ppc_hw_interrupt
2200 static inline void powerpc_excp(CPUState
*env
, int excp_model
, int excp
)
2202 target_ulong msr
, new_msr
, vector
;
2203 int srr0
, srr1
, asrr0
, asrr1
;
2204 int lpes0
, lpes1
, lev
;
2207 /* XXX: find a suitable condition to enable the hypervisor mode */
2208 lpes0
= (env
->spr
[SPR_LPCR
] >> 1) & 1;
2209 lpes1
= (env
->spr
[SPR_LPCR
] >> 2) & 1;
2211 /* Those values ensure we won't enter the hypervisor mode */
2216 qemu_log_mask(CPU_LOG_INT
, "Raise exception at " TARGET_FMT_lx
2217 " => %08x (%02x)\n", env
->nip
, excp
, env
->error_code
);
2219 /* new srr1 value excluding must-be-zero bits */
2220 msr
= env
->msr
& ~0x783f0000ULL
;
2222 /* new interrupt handler msr */
2223 new_msr
= env
->msr
& ((target_ulong
)1 << MSR_ME
);
2225 /* target registers */
2232 case POWERPC_EXCP_NONE
:
2233 /* Should never happen */
2235 case POWERPC_EXCP_CRITICAL
: /* Critical input */
2236 switch (excp_model
) {
2237 case POWERPC_EXCP_40x
:
2238 srr0
= SPR_40x_SRR2
;
2239 srr1
= SPR_40x_SRR3
;
2241 case POWERPC_EXCP_BOOKE
:
2242 srr0
= SPR_BOOKE_CSRR0
;
2243 srr1
= SPR_BOOKE_CSRR1
;
2245 case POWERPC_EXCP_G2
:
2251 case POWERPC_EXCP_MCHECK
: /* Machine check exception */
2253 /* Machine check exception is not enabled.
2254 * Enter checkstop state.
2256 if (qemu_log_enabled()) {
2257 qemu_log("Machine check while not allowed. "
2258 "Entering checkstop state\n");
2260 fprintf(stderr
, "Machine check while not allowed. "
2261 "Entering checkstop state\n");
2264 env
->interrupt_request
|= CPU_INTERRUPT_EXITTB
;
2267 /* XXX: find a suitable condition to enable the hypervisor mode */
2268 new_msr
|= (target_ulong
)MSR_HVB
;
2271 /* machine check exceptions don't have ME set */
2272 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2274 /* XXX: should also have something loaded in DAR / DSISR */
2275 switch (excp_model
) {
2276 case POWERPC_EXCP_40x
:
2277 srr0
= SPR_40x_SRR2
;
2278 srr1
= SPR_40x_SRR3
;
2280 case POWERPC_EXCP_BOOKE
:
2281 srr0
= SPR_BOOKE_MCSRR0
;
2282 srr1
= SPR_BOOKE_MCSRR1
;
2283 asrr0
= SPR_BOOKE_CSRR0
;
2284 asrr1
= SPR_BOOKE_CSRR1
;
2290 case POWERPC_EXCP_DSI
: /* Data storage exception */
2291 LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx
" DAR=" TARGET_FMT_lx
2292 "\n", env
->spr
[SPR_DSISR
], env
->spr
[SPR_DAR
]);
2294 new_msr
|= (target_ulong
)MSR_HVB
;
2296 case POWERPC_EXCP_ISI
: /* Instruction storage exception */
2297 LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx
", nip=" TARGET_FMT_lx
2298 "\n", msr
, env
->nip
);
2300 new_msr
|= (target_ulong
)MSR_HVB
;
2301 msr
|= env
->error_code
;
2303 case POWERPC_EXCP_EXTERNAL
: /* External input */
2305 new_msr
|= (target_ulong
)MSR_HVB
;
2307 case POWERPC_EXCP_ALIGN
: /* Alignment exception */
2309 new_msr
|= (target_ulong
)MSR_HVB
;
2310 /* XXX: this is false */
2311 /* Get rS/rD and rA from faulting opcode */
2312 env
->spr
[SPR_DSISR
] |= (ldl_code((env
->nip
- 4)) & 0x03FF0000) >> 16;
2314 case POWERPC_EXCP_PROGRAM
: /* Program exception */
2315 switch (env
->error_code
& ~0xF) {
2316 case POWERPC_EXCP_FP
:
2317 if ((msr_fe0
== 0 && msr_fe1
== 0) || msr_fp
== 0) {
2318 LOG_EXCP("Ignore floating point exception\n");
2319 env
->exception_index
= POWERPC_EXCP_NONE
;
2320 env
->error_code
= 0;
2324 new_msr
|= (target_ulong
)MSR_HVB
;
2326 if (msr_fe0
== msr_fe1
)
2330 case POWERPC_EXCP_INVAL
:
2331 LOG_EXCP("Invalid instruction at " TARGET_FMT_lx
"\n", env
->nip
);
2333 new_msr
|= (target_ulong
)MSR_HVB
;
2336 case POWERPC_EXCP_PRIV
:
2338 new_msr
|= (target_ulong
)MSR_HVB
;
2341 case POWERPC_EXCP_TRAP
:
2343 new_msr
|= (target_ulong
)MSR_HVB
;
2347 /* Should never occur */
2348 cpu_abort(env
, "Invalid program exception %d. Aborting\n",
2353 case POWERPC_EXCP_FPU
: /* Floating-point unavailable exception */
2355 new_msr
|= (target_ulong
)MSR_HVB
;
2357 case POWERPC_EXCP_SYSCALL
: /* System call exception */
2359 lev
= env
->error_code
;
2360 if ((lev
== 1) && cpu_ppc_hypercall
) {
2361 cpu_ppc_hypercall(env
);
2364 if (lev
== 1 || (lpes0
== 0 && lpes1
== 0))
2365 new_msr
|= (target_ulong
)MSR_HVB
;
2367 case POWERPC_EXCP_APU
: /* Auxiliary processor unavailable */
2369 case POWERPC_EXCP_DECR
: /* Decrementer exception */
2371 new_msr
|= (target_ulong
)MSR_HVB
;
2373 case POWERPC_EXCP_FIT
: /* Fixed-interval timer interrupt */
2375 LOG_EXCP("FIT exception\n");
2377 case POWERPC_EXCP_WDT
: /* Watchdog timer interrupt */
2378 LOG_EXCP("WDT exception\n");
2379 switch (excp_model
) {
2380 case POWERPC_EXCP_BOOKE
:
2381 srr0
= SPR_BOOKE_CSRR0
;
2382 srr1
= SPR_BOOKE_CSRR1
;
2388 case POWERPC_EXCP_DTLB
: /* Data TLB error */
2390 case POWERPC_EXCP_ITLB
: /* Instruction TLB error */
2392 case POWERPC_EXCP_DEBUG
: /* Debug interrupt */
2393 switch (excp_model
) {
2394 case POWERPC_EXCP_BOOKE
:
2395 srr0
= SPR_BOOKE_DSRR0
;
2396 srr1
= SPR_BOOKE_DSRR1
;
2397 asrr0
= SPR_BOOKE_CSRR0
;
2398 asrr1
= SPR_BOOKE_CSRR1
;
2404 cpu_abort(env
, "Debug exception is not implemented yet !\n");
2406 case POWERPC_EXCP_SPEU
: /* SPE/embedded floating-point unavailable */
2408 case POWERPC_EXCP_EFPDI
: /* Embedded floating-point data interrupt */
2410 cpu_abort(env
, "Embedded floating point data exception "
2411 "is not implemented yet !\n");
2413 case POWERPC_EXCP_EFPRI
: /* Embedded floating-point round interrupt */
2415 cpu_abort(env
, "Embedded floating point round exception "
2416 "is not implemented yet !\n");
2418 case POWERPC_EXCP_EPERFM
: /* Embedded performance monitor interrupt */
2421 "Performance counter exception is not implemented yet !\n");
2423 case POWERPC_EXCP_DOORI
: /* Embedded doorbell interrupt */
2426 "Embedded doorbell interrupt is not implemented yet !\n");
2428 case POWERPC_EXCP_DOORCI
: /* Embedded doorbell critical interrupt */
2429 switch (excp_model
) {
2430 case POWERPC_EXCP_BOOKE
:
2431 srr0
= SPR_BOOKE_CSRR0
;
2432 srr1
= SPR_BOOKE_CSRR1
;
2438 cpu_abort(env
, "Embedded doorbell critical interrupt "
2439 "is not implemented yet !\n");
2441 case POWERPC_EXCP_RESET
: /* System reset exception */
2443 /* indicate that we resumed from power save mode */
2446 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2450 /* XXX: find a suitable condition to enable the hypervisor mode */
2451 new_msr
|= (target_ulong
)MSR_HVB
;
2454 case POWERPC_EXCP_DSEG
: /* Data segment exception */
2456 new_msr
|= (target_ulong
)MSR_HVB
;
2458 case POWERPC_EXCP_ISEG
: /* Instruction segment exception */
2460 new_msr
|= (target_ulong
)MSR_HVB
;
2462 case POWERPC_EXCP_HDECR
: /* Hypervisor decrementer exception */
2465 new_msr
|= (target_ulong
)MSR_HVB
;
2466 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2468 case POWERPC_EXCP_TRACE
: /* Trace exception */
2470 new_msr
|= (target_ulong
)MSR_HVB
;
2472 case POWERPC_EXCP_HDSI
: /* Hypervisor data storage exception */
2475 new_msr
|= (target_ulong
)MSR_HVB
;
2476 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2478 case POWERPC_EXCP_HISI
: /* Hypervisor instruction storage exception */
2481 new_msr
|= (target_ulong
)MSR_HVB
;
2482 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2484 case POWERPC_EXCP_HDSEG
: /* Hypervisor data segment exception */
2487 new_msr
|= (target_ulong
)MSR_HVB
;
2488 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2490 case POWERPC_EXCP_HISEG
: /* Hypervisor instruction segment exception */
2493 new_msr
|= (target_ulong
)MSR_HVB
;
2494 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2496 case POWERPC_EXCP_VPU
: /* Vector unavailable exception */
2498 new_msr
|= (target_ulong
)MSR_HVB
;
2500 case POWERPC_EXCP_PIT
: /* Programmable interval timer interrupt */
2501 LOG_EXCP("PIT exception\n");
2503 case POWERPC_EXCP_IO
: /* IO error exception */
2505 cpu_abort(env
, "601 IO error exception is not implemented yet !\n");
2507 case POWERPC_EXCP_RUNM
: /* Run mode exception */
2509 cpu_abort(env
, "601 run mode exception is not implemented yet !\n");
2511 case POWERPC_EXCP_EMUL
: /* Emulation trap exception */
2513 cpu_abort(env
, "602 emulation trap exception "
2514 "is not implemented yet !\n");
2516 case POWERPC_EXCP_IFTLB
: /* Instruction fetch TLB error */
2517 if (lpes1
== 0) /* XXX: check this */
2518 new_msr
|= (target_ulong
)MSR_HVB
;
2519 switch (excp_model
) {
2520 case POWERPC_EXCP_602
:
2521 case POWERPC_EXCP_603
:
2522 case POWERPC_EXCP_603E
:
2523 case POWERPC_EXCP_G2
:
2525 case POWERPC_EXCP_7x5
:
2527 case POWERPC_EXCP_74xx
:
2530 cpu_abort(env
, "Invalid instruction TLB miss exception\n");
2534 case POWERPC_EXCP_DLTLB
: /* Data load TLB miss */
2535 if (lpes1
== 0) /* XXX: check this */
2536 new_msr
|= (target_ulong
)MSR_HVB
;
2537 switch (excp_model
) {
2538 case POWERPC_EXCP_602
:
2539 case POWERPC_EXCP_603
:
2540 case POWERPC_EXCP_603E
:
2541 case POWERPC_EXCP_G2
:
2543 case POWERPC_EXCP_7x5
:
2545 case POWERPC_EXCP_74xx
:
2548 cpu_abort(env
, "Invalid data load TLB miss exception\n");
2552 case POWERPC_EXCP_DSTLB
: /* Data store TLB miss */
2553 if (lpes1
== 0) /* XXX: check this */
2554 new_msr
|= (target_ulong
)MSR_HVB
;
2555 switch (excp_model
) {
2556 case POWERPC_EXCP_602
:
2557 case POWERPC_EXCP_603
:
2558 case POWERPC_EXCP_603E
:
2559 case POWERPC_EXCP_G2
:
2561 /* Swap temporary saved registers with GPRs */
2562 if (!(new_msr
& ((target_ulong
)1 << MSR_TGPR
))) {
2563 new_msr
|= (target_ulong
)1 << MSR_TGPR
;
2564 hreg_swap_gpr_tgpr(env
);
2567 case POWERPC_EXCP_7x5
:
2569 #if defined (DEBUG_SOFTWARE_TLB)
2570 if (qemu_log_enabled()) {
2572 target_ulong
*miss
, *cmp
;
2574 if (excp
== POWERPC_EXCP_IFTLB
) {
2577 miss
= &env
->spr
[SPR_IMISS
];
2578 cmp
= &env
->spr
[SPR_ICMP
];
2580 if (excp
== POWERPC_EXCP_DLTLB
)
2585 miss
= &env
->spr
[SPR_DMISS
];
2586 cmp
= &env
->spr
[SPR_DCMP
];
2588 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2589 TARGET_FMT_lx
" H1 " TARGET_FMT_lx
" H2 "
2590 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2591 env
->spr
[SPR_HASH1
], env
->spr
[SPR_HASH2
],
2595 msr
|= env
->crf
[0] << 28;
2596 msr
|= env
->error_code
; /* key, D/I, S/L bits */
2597 /* Set way using a LRU mechanism */
2598 msr
|= ((env
->last_way
+ 1) & (env
->nb_ways
- 1)) << 17;
2600 case POWERPC_EXCP_74xx
:
2602 #if defined (DEBUG_SOFTWARE_TLB)
2603 if (qemu_log_enabled()) {
2605 target_ulong
*miss
, *cmp
;
2607 if (excp
== POWERPC_EXCP_IFTLB
) {
2610 miss
= &env
->spr
[SPR_TLBMISS
];
2611 cmp
= &env
->spr
[SPR_PTEHI
];
2613 if (excp
== POWERPC_EXCP_DLTLB
)
2618 miss
= &env
->spr
[SPR_TLBMISS
];
2619 cmp
= &env
->spr
[SPR_PTEHI
];
2621 qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2622 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2626 msr
|= env
->error_code
; /* key bit */
2629 cpu_abort(env
, "Invalid data store TLB miss exception\n");
2633 case POWERPC_EXCP_FPA
: /* Floating-point assist exception */
2635 cpu_abort(env
, "Floating point assist exception "
2636 "is not implemented yet !\n");
2638 case POWERPC_EXCP_DABR
: /* Data address breakpoint */
2640 cpu_abort(env
, "DABR exception is not implemented yet !\n");
2642 case POWERPC_EXCP_IABR
: /* Instruction address breakpoint */
2644 cpu_abort(env
, "IABR exception is not implemented yet !\n");
2646 case POWERPC_EXCP_SMI
: /* System management interrupt */
2648 cpu_abort(env
, "SMI exception is not implemented yet !\n");
2650 case POWERPC_EXCP_THERM
: /* Thermal interrupt */
2652 cpu_abort(env
, "Thermal management exception "
2653 "is not implemented yet !\n");
2655 case POWERPC_EXCP_PERFM
: /* Embedded performance monitor interrupt */
2657 new_msr
|= (target_ulong
)MSR_HVB
;
2660 "Performance counter exception is not implemented yet !\n");
2662 case POWERPC_EXCP_VPUA
: /* Vector assist exception */
2664 cpu_abort(env
, "VPU assist exception is not implemented yet !\n");
2666 case POWERPC_EXCP_SOFTP
: /* Soft patch exception */
2669 "970 soft-patch exception is not implemented yet !\n");
2671 case POWERPC_EXCP_MAINT
: /* Maintenance exception */
2674 "970 maintenance exception is not implemented yet !\n");
2676 case POWERPC_EXCP_MEXTBR
: /* Maskable external breakpoint */
2678 cpu_abort(env
, "Maskable external exception "
2679 "is not implemented yet !\n");
2681 case POWERPC_EXCP_NMEXTBR
: /* Non maskable external breakpoint */
2683 cpu_abort(env
, "Non maskable external exception "
2684 "is not implemented yet !\n");
2688 cpu_abort(env
, "Invalid PowerPC exception %d. Aborting\n", excp
);
2691 /* save current instruction location */
2692 env
->spr
[srr0
] = env
->nip
- 4;
2695 /* save next instruction location */
2696 env
->spr
[srr0
] = env
->nip
;
2700 env
->spr
[srr1
] = msr
;
2701 /* If any alternate SRR register are defined, duplicate saved values */
2703 env
->spr
[asrr0
] = env
->spr
[srr0
];
2705 env
->spr
[asrr1
] = env
->spr
[srr1
];
2706 /* If we disactivated any translation, flush TLBs */
2707 if (new_msr
& ((1 << MSR_IR
) | (1 << MSR_DR
)))
2711 new_msr
|= (target_ulong
)1 << MSR_LE
;
2714 /* Jump to handler */
2715 vector
= env
->excp_vectors
[excp
];
2716 if (vector
== (target_ulong
)-1ULL) {
2717 cpu_abort(env
, "Raised an exception without defined vector %d\n",
2720 vector
|= env
->excp_prefix
;
2721 #if defined(TARGET_PPC64)
2722 if (excp_model
== POWERPC_EXCP_BOOKE
) {
2724 vector
= (uint32_t)vector
;
2726 new_msr
|= (target_ulong
)1 << MSR_CM
;
2729 if (!msr_isf
&& !(env
->mmu_model
& POWERPC_MMU_64
)) {
2730 vector
= (uint32_t)vector
;
2732 new_msr
|= (target_ulong
)1 << MSR_SF
;
2736 /* XXX: we don't use hreg_store_msr here as already have treated
2737 * any special case that could occur. Just store MSR and update hflags
2739 env
->msr
= new_msr
& env
->msr_mask
;
2740 hreg_compute_hflags(env
);
2742 /* Reset exception state */
2743 env
->exception_index
= POWERPC_EXCP_NONE
;
2744 env
->error_code
= 0;
2746 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
2747 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
2748 /* XXX: The BookE changes address space when switching modes,
2749 we should probably implement that as different MMU indexes,
2750 but for the moment we do it the slow way and flush all. */
2755 void do_interrupt (CPUState
*env
)
2757 powerpc_excp(env
, env
->excp_model
, env
->exception_index
);
2760 void ppc_hw_interrupt (CPUPPCState
*env
)
2765 qemu_log_mask(CPU_LOG_INT
, "%s: %p pending %08x req %08x me %d ee %d\n",
2766 __func__
, env
, env
->pending_interrupts
,
2767 env
->interrupt_request
, (int)msr_me
, (int)msr_ee
);
2769 /* External reset */
2770 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_RESET
)) {
2771 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_RESET
);
2772 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_RESET
);
2775 /* Machine check exception */
2776 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_MCK
)) {
2777 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_MCK
);
2778 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_MCHECK
);
2782 /* External debug exception */
2783 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DEBUG
)) {
2784 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DEBUG
);
2785 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DEBUG
);
2790 /* XXX: find a suitable condition to enable the hypervisor mode */
2791 hdice
= env
->spr
[SPR_LPCR
] & 1;
2795 if ((msr_ee
!= 0 || msr_hv
== 0 || msr_pr
!= 0) && hdice
!= 0) {
2796 /* Hypervisor decrementer exception */
2797 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_HDECR
)) {
2798 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_HDECR
);
2799 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_HDECR
);
2804 /* External critical interrupt */
2805 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CEXT
)) {
2806 /* Taking a critical external interrupt does not clear the external
2807 * critical interrupt status
2810 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CEXT
);
2812 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_CRITICAL
);
2817 /* Watchdog timer on embedded PowerPC */
2818 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_WDT
)) {
2819 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_WDT
);
2820 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_WDT
);
2823 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CDOORBELL
)) {
2824 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CDOORBELL
);
2825 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORCI
);
2828 /* Fixed interval timer on embedded PowerPC */
2829 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_FIT
)) {
2830 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_FIT
);
2831 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_FIT
);
2834 /* Programmable interval timer on embedded PowerPC */
2835 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PIT
)) {
2836 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PIT
);
2837 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PIT
);
2840 /* Decrementer exception */
2841 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DECR
)) {
2842 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DECR
);
2843 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DECR
);
2846 /* External interrupt */
2847 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_EXT
)) {
2848 /* Taking an external interrupt does not clear the external
2852 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_EXT
);
2854 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_EXTERNAL
);
2857 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DOORBELL
)) {
2858 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DOORBELL
);
2859 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORI
);
2862 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PERFM
)) {
2863 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PERFM
);
2864 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PERFM
);
2867 /* Thermal interrupt */
2868 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_THERM
)) {
2869 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_THERM
);
2870 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_THERM
);
2875 #endif /* !CONFIG_USER_ONLY */
2877 void cpu_dump_rfi (target_ulong RA
, target_ulong msr
)
2879 qemu_log("Return from exception at " TARGET_FMT_lx
" with flags "
2880 TARGET_FMT_lx
"\n", RA
, msr
);
2883 void cpu_reset(CPUPPCState
*env
)
2887 if (qemu_loglevel_mask(CPU_LOG_RESET
)) {
2888 qemu_log("CPU Reset (CPU %d)\n", env
->cpu_index
);
2889 log_cpu_state(env
, 0);
2892 msr
= (target_ulong
)0;
2894 /* XXX: find a suitable condition to enable the hypervisor mode */
2895 msr
|= (target_ulong
)MSR_HVB
;
2897 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
2898 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
2899 msr
|= (target_ulong
)1 << MSR_EP
;
2900 #if defined (DO_SINGLE_STEP) && 0
2901 /* Single step trace mode */
2902 msr
|= (target_ulong
)1 << MSR_SE
;
2903 msr
|= (target_ulong
)1 << MSR_BE
;
2905 #if defined(CONFIG_USER_ONLY)
2906 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
2907 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
2908 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
2909 msr
|= (target_ulong
)1 << MSR_PR
;
2911 env
->excp_prefix
= env
->hreset_excp_prefix
;
2912 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
2913 if (env
->mmu_model
!= POWERPC_MMU_REAL
)
2914 ppc_tlb_invalidate_all(env
);
2916 env
->msr
= msr
& env
->msr_mask
;
2917 #if defined(TARGET_PPC64)
2918 if (env
->mmu_model
& POWERPC_MMU_64
)
2919 env
->msr
|= (1ULL << MSR_SF
);
2921 hreg_compute_hflags(env
);
2922 env
->reserve_addr
= (target_ulong
)-1ULL;
2923 /* Be sure no exception or interrupt is pending */
2924 env
->pending_interrupts
= 0;
2925 env
->exception_index
= POWERPC_EXCP_NONE
;
2926 env
->error_code
= 0;
2927 /* Flush all TLBs */
2931 CPUPPCState
*cpu_ppc_init (const char *cpu_model
)
2934 const ppc_def_t
*def
;
2936 def
= cpu_ppc_find_by_name(cpu_model
);
2940 env
= qemu_mallocz(sizeof(CPUPPCState
));
2942 ppc_translate_init();
2943 env
->cpu_model_str
= cpu_model
;
2944 cpu_ppc_register_internal(env
, def
);
2946 qemu_init_vcpu(env
);
2951 void cpu_ppc_close (CPUPPCState
*env
)
2953 /* Should also remove all opcode tables... */