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");
953 LOG_MMU("direct store...\n");
954 /* Direct-store segment : absolutely *BUGGY* for now */
956 /* Direct-store implies a 32-bit MMU.
957 * Check the Segment Register's bus unit ID (BUID).
959 sr
= env
->sr
[eaddr
>> 28];
960 if ((sr
& 0x1FF00000) >> 20 == 0x07f) {
961 /* Memory-forced I/O controller interface access */
962 /* If T=1 and BUID=x'07F', the 601 performs a memory access
963 * to SR[28-31] LA[4-31], bypassing all protection mechanisms.
965 ctx
->raddr
= ((sr
& 0xF) << 28) | (eaddr
& 0x0FFFFFFF);
966 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
972 /* Integer load/store : only access allowed */
975 /* No code fetch is allowed in direct-store areas */
978 /* Floating point load/store */
981 /* lwarx, ldarx or srwcx. */
984 /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
985 /* Should make the instruction do no-op.
986 * As it already do no-op, it's quite easy :-)
994 qemu_log("ERROR: instruction should not need "
995 "address translation\n");
998 if ((rw
== 1 || ctx
->key
!= 1) && (rw
== 0 || ctx
->key
!= 0)) {
1009 /* Generic TLB check function for embedded PowerPC implementations */
1010 int ppcemb_tlb_check(CPUState
*env
, ppcemb_tlb_t
*tlb
,
1011 target_phys_addr_t
*raddrp
,
1012 target_ulong address
, uint32_t pid
, int ext
,
1017 /* Check valid flag */
1018 if (!(tlb
->prot
& PAGE_VALID
)) {
1021 mask
= ~(tlb
->size
- 1);
1022 LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx
" PID %u <=> " TARGET_FMT_lx
1023 " " TARGET_FMT_lx
" %u %x\n", __func__
, i
, address
, pid
, tlb
->EPN
,
1024 mask
, (uint32_t)tlb
->PID
, tlb
->prot
);
1026 if (tlb
->PID
!= 0 && tlb
->PID
!= pid
)
1028 /* Check effective address */
1029 if ((address
& mask
) != tlb
->EPN
)
1031 *raddrp
= (tlb
->RPN
& mask
) | (address
& ~mask
);
1032 #if (TARGET_PHYS_ADDR_BITS >= 36)
1034 /* Extend the physical address to 36 bits */
1035 *raddrp
|= (target_phys_addr_t
)(tlb
->RPN
& 0xF) << 32;
1042 /* Generic TLB search function for PowerPC embedded implementations */
1043 int ppcemb_tlb_search (CPUPPCState
*env
, target_ulong address
, uint32_t pid
)
1046 target_phys_addr_t raddr
;
1049 /* Default return value is no match */
1051 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1052 tlb
= &env
->tlb
[i
].tlbe
;
1053 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
, pid
, 0, i
) == 0) {
1062 /* Helpers specific to PowerPC 40x implementations */
1063 static inline void ppc4xx_tlb_invalidate_all(CPUState
*env
)
1068 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1069 tlb
= &env
->tlb
[i
].tlbe
;
1070 tlb
->prot
&= ~PAGE_VALID
;
1075 static inline void ppc4xx_tlb_invalidate_virt(CPUState
*env
,
1076 target_ulong eaddr
, uint32_t pid
)
1078 #if !defined(FLUSH_ALL_TLBS)
1080 target_phys_addr_t raddr
;
1081 target_ulong page
, end
;
1084 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1085 tlb
= &env
->tlb
[i
].tlbe
;
1086 if (ppcemb_tlb_check(env
, tlb
, &raddr
, eaddr
, pid
, 0, i
) == 0) {
1087 end
= tlb
->EPN
+ tlb
->size
;
1088 for (page
= tlb
->EPN
; page
< end
; page
+= TARGET_PAGE_SIZE
)
1089 tlb_flush_page(env
, page
);
1090 tlb
->prot
&= ~PAGE_VALID
;
1095 ppc4xx_tlb_invalidate_all(env
);
1099 static int mmu40x_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1100 target_ulong address
, int rw
, int access_type
)
1103 target_phys_addr_t raddr
;
1104 int i
, ret
, zsel
, zpr
, pr
;
1107 raddr
= (target_phys_addr_t
)-1ULL;
1109 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1110 tlb
= &env
->tlb
[i
].tlbe
;
1111 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
,
1112 env
->spr
[SPR_40x_PID
], 0, i
) < 0)
1114 zsel
= (tlb
->attr
>> 4) & 0xF;
1115 zpr
= (env
->spr
[SPR_40x_ZPR
] >> (30 - (2 * zsel
))) & 0x3;
1116 LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1117 __func__
, i
, zsel
, zpr
, rw
, tlb
->attr
);
1118 /* Check execute enable bit */
1125 /* All accesses granted */
1126 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
1131 /* Raise Zone protection fault. */
1132 env
->spr
[SPR_40x_ESR
] = 1 << 22;
1140 /* Check from TLB entry */
1141 ctx
->prot
= tlb
->prot
;
1142 ret
= check_prot(ctx
->prot
, rw
, access_type
);
1144 env
->spr
[SPR_40x_ESR
] = 0;
1149 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1150 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1155 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1156 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1161 void store_40x_sler (CPUPPCState
*env
, uint32_t val
)
1163 /* XXX: TO BE FIXED */
1164 if (val
!= 0x00000000) {
1165 cpu_abort(env
, "Little-endian regions are not supported by now\n");
1167 env
->spr
[SPR_405_SLER
] = val
;
1170 static inline int mmubooke_check_tlb (CPUState
*env
, ppcemb_tlb_t
*tlb
,
1171 target_phys_addr_t
*raddr
, int *prot
,
1172 target_ulong address
, int rw
,
1173 int access_type
, int i
)
1177 if (ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1178 env
->spr
[SPR_BOOKE_PID
],
1179 !env
->nb_pids
, i
) >= 0) {
1183 if (env
->spr
[SPR_BOOKE_PID1
] &&
1184 ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1185 env
->spr
[SPR_BOOKE_PID1
], 0, i
) >= 0) {
1189 if (env
->spr
[SPR_BOOKE_PID2
] &&
1190 ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1191 env
->spr
[SPR_BOOKE_PID2
], 0, i
) >= 0) {
1195 LOG_SWTLB("%s: TLB entry not found\n", __func__
);
1201 _prot
= tlb
->prot
& 0xF;
1203 _prot
= (tlb
->prot
>> 4) & 0xF;
1206 /* Check the address space */
1207 if (access_type
== ACCESS_CODE
) {
1208 if (msr_ir
!= (tlb
->attr
& 1)) {
1209 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1214 if (_prot
& PAGE_EXEC
) {
1215 LOG_SWTLB("%s: good TLB!\n", __func__
);
1219 LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__
, _prot
);
1222 if (msr_dr
!= (tlb
->attr
& 1)) {
1223 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1228 if ((!rw
&& _prot
& PAGE_READ
) || (rw
&& (_prot
& PAGE_WRITE
))) {
1229 LOG_SWTLB("%s: found TLB!\n", __func__
);
1233 LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__
, _prot
);
1240 static int mmubooke_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1241 target_ulong address
, int rw
,
1245 target_phys_addr_t raddr
;
1249 raddr
= (target_phys_addr_t
)-1ULL;
1250 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1251 tlb
= &env
->tlb
[i
].tlbe
;
1252 ret
= mmubooke_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
, rw
,
1261 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1262 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1265 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1266 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1272 void booke206_flush_tlb(CPUState
*env
, int flags
, const int check_iprot
)
1276 ppc_tlb_t
*tlb
= env
->tlb
;
1278 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1279 if (flags
& (1 << i
)) {
1280 tlb_size
= booke206_tlb_size(env
, i
);
1281 for (j
= 0; j
< tlb_size
; j
++) {
1282 if (!check_iprot
|| !(tlb
[j
].tlbm
.mas1
& MAS1_IPROT
)) {
1283 tlb
[j
].tlbm
.mas1
&= ~MAS1_VALID
;
1287 tlb
+= booke206_tlb_size(env
, i
);
1293 target_phys_addr_t
booke206_tlb_to_page_size(CPUState
*env
, ppcmas_tlb_t
*tlb
)
1296 int tlbn
= booke206_tlbm_to_tlbn(env
, tlb
);
1297 target_phys_addr_t tlbm_size
;
1299 tlbncfg
= env
->spr
[SPR_BOOKE_TLB0CFG
+ tlbn
];
1301 if (tlbncfg
& TLBnCFG_AVAIL
) {
1302 tlbm_size
= (tlb
->mas1
& MAS1_TSIZE_MASK
) >> MAS1_TSIZE_SHIFT
;
1304 tlbm_size
= (tlbncfg
& TLBnCFG_MINSIZE
) >> TLBnCFG_MINSIZE_SHIFT
;
1307 return (1 << (tlbm_size
<< 1)) << 10;
1310 /* TLB check function for MAS based SoftTLBs */
1311 int ppcmas_tlb_check(CPUState
*env
, ppcmas_tlb_t
*tlb
,
1312 target_phys_addr_t
*raddrp
,
1313 target_ulong address
, uint32_t pid
)
1318 /* Check valid flag */
1319 if (!(tlb
->mas1
& MAS1_VALID
)) {
1323 mask
= ~(booke206_tlb_to_page_size(env
, tlb
) - 1);
1324 LOG_SWTLB("%s: TLB ADDR=0x" TARGET_FMT_lx
" PID=0x%x MAS1=0x%x MAS2=0x%"
1325 PRIx64
" mask=0x" TARGET_FMT_lx
" MAS7_3=0x%" PRIx64
" MAS8=%x\n",
1326 __func__
, address
, pid
, tlb
->mas1
, tlb
->mas2
, mask
, tlb
->mas7_3
,
1330 tlb_pid
= (tlb
->mas1
& MAS1_TID_MASK
) >> MAS1_TID_SHIFT
;
1331 if (tlb_pid
!= 0 && tlb_pid
!= pid
) {
1335 /* Check effective address */
1336 if ((address
& mask
) != (tlb
->mas2
& MAS2_EPN_MASK
)) {
1339 *raddrp
= (tlb
->mas7_3
& mask
) | (address
& ~mask
);
1344 static int mmubooke206_check_tlb(CPUState
*env
, ppcmas_tlb_t
*tlb
,
1345 target_phys_addr_t
*raddr
, int *prot
,
1346 target_ulong address
, int rw
,
1352 if (ppcmas_tlb_check(env
, tlb
, raddr
, address
,
1353 env
->spr
[SPR_BOOKE_PID
]) >= 0) {
1357 if (env
->spr
[SPR_BOOKE_PID1
] &&
1358 ppcmas_tlb_check(env
, tlb
, raddr
, address
,
1359 env
->spr
[SPR_BOOKE_PID1
]) >= 0) {
1363 if (env
->spr
[SPR_BOOKE_PID2
] &&
1364 ppcmas_tlb_check(env
, tlb
, raddr
, address
,
1365 env
->spr
[SPR_BOOKE_PID2
]) >= 0) {
1369 LOG_SWTLB("%s: TLB entry not found\n", __func__
);
1375 if (tlb
->mas7_3
& MAS3_UR
) {
1378 if (tlb
->mas7_3
& MAS3_UW
) {
1379 _prot
|= PAGE_WRITE
;
1381 if (tlb
->mas7_3
& MAS3_UX
) {
1385 if (tlb
->mas7_3
& MAS3_SR
) {
1388 if (tlb
->mas7_3
& MAS3_SW
) {
1389 _prot
|= PAGE_WRITE
;
1391 if (tlb
->mas7_3
& MAS3_SX
) {
1396 /* Check the address space and permissions */
1397 if (access_type
== ACCESS_CODE
) {
1398 if (msr_ir
!= ((tlb
->mas1
& MAS1_TS
) >> MAS1_TS_SHIFT
)) {
1399 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1404 if (_prot
& PAGE_EXEC
) {
1405 LOG_SWTLB("%s: good TLB!\n", __func__
);
1409 LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__
, _prot
);
1412 if (msr_dr
!= ((tlb
->mas1
& MAS1_TS
) >> MAS1_TS_SHIFT
)) {
1413 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1418 if ((!rw
&& _prot
& PAGE_READ
) || (rw
&& (_prot
& PAGE_WRITE
))) {
1419 LOG_SWTLB("%s: found TLB!\n", __func__
);
1423 LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__
, _prot
);
1430 static int mmubooke206_get_physical_address(CPUState
*env
, mmu_ctx_t
*ctx
,
1431 target_ulong address
, int rw
,
1435 target_phys_addr_t raddr
;
1439 raddr
= (target_phys_addr_t
)-1ULL;
1441 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1442 int ways
= booke206_tlb_ways(env
, i
);
1444 for (j
= 0; j
< ways
; j
++) {
1445 tlb
= booke206_get_tlbm(env
, i
, address
, j
);
1446 ret
= mmubooke206_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
,
1458 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1459 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1462 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1463 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1469 static inline int check_physical(CPUState
*env
, mmu_ctx_t
*ctx
,
1470 target_ulong eaddr
, int rw
)
1475 ctx
->prot
= PAGE_READ
| PAGE_EXEC
;
1477 switch (env
->mmu_model
) {
1478 case POWERPC_MMU_32B
:
1479 case POWERPC_MMU_601
:
1480 case POWERPC_MMU_SOFT_6xx
:
1481 case POWERPC_MMU_SOFT_74xx
:
1482 case POWERPC_MMU_SOFT_4xx
:
1483 case POWERPC_MMU_REAL
:
1484 case POWERPC_MMU_BOOKE
:
1485 ctx
->prot
|= PAGE_WRITE
;
1487 #if defined(TARGET_PPC64)
1488 case POWERPC_MMU_620
:
1489 case POWERPC_MMU_64B
:
1490 case POWERPC_MMU_2_06
:
1491 /* Real address are 60 bits long */
1492 ctx
->raddr
&= 0x0FFFFFFFFFFFFFFFULL
;
1493 ctx
->prot
|= PAGE_WRITE
;
1496 case POWERPC_MMU_SOFT_4xx_Z
:
1497 if (unlikely(msr_pe
!= 0)) {
1498 /* 403 family add some particular protections,
1499 * using PBL/PBU registers for accesses with no translation.
1502 /* Check PLB validity */
1503 (env
->pb
[0] < env
->pb
[1] &&
1504 /* and address in plb area */
1505 eaddr
>= env
->pb
[0] && eaddr
< env
->pb
[1]) ||
1506 (env
->pb
[2] < env
->pb
[3] &&
1507 eaddr
>= env
->pb
[2] && eaddr
< env
->pb
[3]) ? 1 : 0;
1508 if (in_plb
^ msr_px
) {
1509 /* Access in protected area */
1511 /* Access is not allowed */
1515 /* Read-write access is allowed */
1516 ctx
->prot
|= PAGE_WRITE
;
1520 case POWERPC_MMU_MPC8xx
:
1522 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1524 case POWERPC_MMU_BOOKE206
:
1525 cpu_abort(env
, "BookE 2.06 MMU doesn't have physical real mode\n");
1528 cpu_abort(env
, "Unknown or invalid MMU model\n");
1535 int get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
, target_ulong eaddr
,
1536 int rw
, int access_type
)
1541 qemu_log("%s\n", __func__
);
1543 if ((access_type
== ACCESS_CODE
&& msr_ir
== 0) ||
1544 (access_type
!= ACCESS_CODE
&& msr_dr
== 0)) {
1545 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1546 /* The BookE MMU always performs address translation. The
1547 IS and DS bits only affect the address space. */
1548 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1550 } else if (env
->mmu_model
== POWERPC_MMU_BOOKE206
) {
1551 ret
= mmubooke206_get_physical_address(env
, ctx
, eaddr
, rw
,
1554 /* No address translation. */
1555 ret
= check_physical(env
, ctx
, eaddr
, rw
);
1559 switch (env
->mmu_model
) {
1560 case POWERPC_MMU_32B
:
1561 case POWERPC_MMU_601
:
1562 case POWERPC_MMU_SOFT_6xx
:
1563 case POWERPC_MMU_SOFT_74xx
:
1564 /* Try to find a BAT */
1565 if (env
->nb_BATs
!= 0)
1566 ret
= get_bat(env
, ctx
, eaddr
, rw
, access_type
);
1567 #if defined(TARGET_PPC64)
1568 case POWERPC_MMU_620
:
1569 case POWERPC_MMU_64B
:
1570 case POWERPC_MMU_2_06
:
1573 /* We didn't match any BAT entry or don't have BATs */
1574 ret
= get_segment(env
, ctx
, eaddr
, rw
, access_type
);
1577 case POWERPC_MMU_SOFT_4xx
:
1578 case POWERPC_MMU_SOFT_4xx_Z
:
1579 ret
= mmu40x_get_physical_address(env
, ctx
, eaddr
,
1582 case POWERPC_MMU_BOOKE
:
1583 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1586 case POWERPC_MMU_BOOKE206
:
1587 ret
= mmubooke206_get_physical_address(env
, ctx
, eaddr
, rw
,
1590 case POWERPC_MMU_MPC8xx
:
1592 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1594 case POWERPC_MMU_REAL
:
1595 cpu_abort(env
, "PowerPC in real mode do not do any translation\n");
1598 cpu_abort(env
, "Unknown or invalid MMU model\n");
1603 qemu_log("%s address " TARGET_FMT_lx
" => %d " TARGET_FMT_plx
"\n",
1604 __func__
, eaddr
, ret
, ctx
->raddr
);
1610 target_phys_addr_t
cpu_get_phys_page_debug (CPUState
*env
, target_ulong addr
)
1614 if (unlikely(get_physical_address(env
, &ctx
, addr
, 0, ACCESS_INT
) != 0))
1617 return ctx
.raddr
& TARGET_PAGE_MASK
;
1620 static void booke206_update_mas_tlb_miss(CPUState
*env
, target_ulong address
,
1623 env
->spr
[SPR_BOOKE_MAS0
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TLBSELD_MASK
;
1624 env
->spr
[SPR_BOOKE_MAS1
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TSIZED_MASK
;
1625 env
->spr
[SPR_BOOKE_MAS2
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_WIMGED_MASK
;
1626 env
->spr
[SPR_BOOKE_MAS3
] = 0;
1627 env
->spr
[SPR_BOOKE_MAS6
] = 0;
1628 env
->spr
[SPR_BOOKE_MAS7
] = 0;
1631 if (((rw
== 2) && msr_ir
) || ((rw
!= 2) && msr_dr
)) {
1632 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_TS
;
1633 env
->spr
[SPR_BOOKE_MAS6
] |= MAS6_SAS
;
1636 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_VALID
;
1637 env
->spr
[SPR_BOOKE_MAS2
] |= address
& MAS2_EPN_MASK
;
1639 switch (env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TIDSELD_PIDZ
) {
1640 case MAS4_TIDSELD_PID0
:
1641 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID
] << MAS1_TID_SHIFT
;
1643 case MAS4_TIDSELD_PID1
:
1644 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID1
] << MAS1_TID_SHIFT
;
1646 case MAS4_TIDSELD_PID2
:
1647 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID2
] << MAS1_TID_SHIFT
;
1651 env
->spr
[SPR_BOOKE_MAS6
] |= env
->spr
[SPR_BOOKE_PID
] << 16;
1653 /* next victim logic */
1654 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_ESEL_SHIFT
;
1656 env
->last_way
&= booke206_tlb_ways(env
, 0) - 1;
1657 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_NV_SHIFT
;
1660 /* Perform address translation */
1661 int cpu_ppc_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
1662 int mmu_idx
, int is_softmmu
)
1671 access_type
= ACCESS_CODE
;
1674 access_type
= env
->access_type
;
1676 ret
= get_physical_address(env
, &ctx
, address
, rw
, access_type
);
1678 tlb_set_page(env
, address
& TARGET_PAGE_MASK
,
1679 ctx
.raddr
& TARGET_PAGE_MASK
, ctx
.prot
,
1680 mmu_idx
, TARGET_PAGE_SIZE
);
1682 } else if (ret
< 0) {
1684 if (access_type
== ACCESS_CODE
) {
1687 /* No matches in page tables or TLB */
1688 switch (env
->mmu_model
) {
1689 case POWERPC_MMU_SOFT_6xx
:
1690 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1691 env
->error_code
= 1 << 18;
1692 env
->spr
[SPR_IMISS
] = address
;
1693 env
->spr
[SPR_ICMP
] = 0x80000000 | ctx
.ptem
;
1695 case POWERPC_MMU_SOFT_74xx
:
1696 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1698 case POWERPC_MMU_SOFT_4xx
:
1699 case POWERPC_MMU_SOFT_4xx_Z
:
1700 env
->exception_index
= POWERPC_EXCP_ITLB
;
1701 env
->error_code
= 0;
1702 env
->spr
[SPR_40x_DEAR
] = address
;
1703 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1705 case POWERPC_MMU_32B
:
1706 case POWERPC_MMU_601
:
1707 #if defined(TARGET_PPC64)
1708 case POWERPC_MMU_620
:
1709 case POWERPC_MMU_64B
:
1710 case POWERPC_MMU_2_06
:
1712 env
->exception_index
= POWERPC_EXCP_ISI
;
1713 env
->error_code
= 0x40000000;
1715 case POWERPC_MMU_BOOKE206
:
1716 booke206_update_mas_tlb_miss(env
, address
, rw
);
1718 case POWERPC_MMU_BOOKE
:
1719 env
->exception_index
= POWERPC_EXCP_ITLB
;
1720 env
->error_code
= 0;
1721 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1723 case POWERPC_MMU_MPC8xx
:
1725 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1727 case POWERPC_MMU_REAL
:
1728 cpu_abort(env
, "PowerPC in real mode should never raise "
1729 "any MMU exceptions\n");
1732 cpu_abort(env
, "Unknown or invalid MMU model\n");
1737 /* Access rights violation */
1738 env
->exception_index
= POWERPC_EXCP_ISI
;
1739 env
->error_code
= 0x08000000;
1742 /* No execute protection violation */
1743 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1744 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1745 env
->spr
[SPR_BOOKE_ESR
] = 0x00000000;
1747 env
->exception_index
= POWERPC_EXCP_ISI
;
1748 env
->error_code
= 0x10000000;
1751 /* Direct store exception */
1752 /* No code fetch is allowed in direct-store areas */
1753 env
->exception_index
= POWERPC_EXCP_ISI
;
1754 env
->error_code
= 0x10000000;
1756 #if defined(TARGET_PPC64)
1758 /* No match in segment table */
1759 if (env
->mmu_model
== POWERPC_MMU_620
) {
1760 env
->exception_index
= POWERPC_EXCP_ISI
;
1761 /* XXX: this might be incorrect */
1762 env
->error_code
= 0x40000000;
1764 env
->exception_index
= POWERPC_EXCP_ISEG
;
1765 env
->error_code
= 0;
1773 /* No matches in page tables or TLB */
1774 switch (env
->mmu_model
) {
1775 case POWERPC_MMU_SOFT_6xx
:
1777 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1778 env
->error_code
= 1 << 16;
1780 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1781 env
->error_code
= 0;
1783 env
->spr
[SPR_DMISS
] = address
;
1784 env
->spr
[SPR_DCMP
] = 0x80000000 | ctx
.ptem
;
1786 env
->error_code
|= ctx
.key
<< 19;
1787 env
->spr
[SPR_HASH1
] = env
->htab_base
+
1788 get_pteg_offset(env
, ctx
.hash
[0], HASH_PTE_SIZE_32
);
1789 env
->spr
[SPR_HASH2
] = env
->htab_base
+
1790 get_pteg_offset(env
, ctx
.hash
[1], HASH_PTE_SIZE_32
);
1792 case POWERPC_MMU_SOFT_74xx
:
1794 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1796 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1799 /* Implement LRU algorithm */
1800 env
->error_code
= ctx
.key
<< 19;
1801 env
->spr
[SPR_TLBMISS
] = (address
& ~((target_ulong
)0x3)) |
1802 ((env
->last_way
+ 1) & (env
->nb_ways
- 1));
1803 env
->spr
[SPR_PTEHI
] = 0x80000000 | ctx
.ptem
;
1805 case POWERPC_MMU_SOFT_4xx
:
1806 case POWERPC_MMU_SOFT_4xx_Z
:
1807 env
->exception_index
= POWERPC_EXCP_DTLB
;
1808 env
->error_code
= 0;
1809 env
->spr
[SPR_40x_DEAR
] = address
;
1811 env
->spr
[SPR_40x_ESR
] = 0x00800000;
1813 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1815 case POWERPC_MMU_32B
:
1816 case POWERPC_MMU_601
:
1817 #if defined(TARGET_PPC64)
1818 case POWERPC_MMU_620
:
1819 case POWERPC_MMU_64B
:
1820 case POWERPC_MMU_2_06
:
1822 env
->exception_index
= POWERPC_EXCP_DSI
;
1823 env
->error_code
= 0;
1824 env
->spr
[SPR_DAR
] = address
;
1826 env
->spr
[SPR_DSISR
] = 0x42000000;
1828 env
->spr
[SPR_DSISR
] = 0x40000000;
1830 case POWERPC_MMU_MPC8xx
:
1832 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1834 case POWERPC_MMU_BOOKE206
:
1835 booke206_update_mas_tlb_miss(env
, address
, rw
);
1837 case POWERPC_MMU_BOOKE
:
1838 env
->exception_index
= POWERPC_EXCP_DTLB
;
1839 env
->error_code
= 0;
1840 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1841 env
->spr
[SPR_BOOKE_ESR
] = rw
? 1 << ESR_ST
: 0;
1843 case POWERPC_MMU_REAL
:
1844 cpu_abort(env
, "PowerPC in real mode should never raise "
1845 "any MMU exceptions\n");
1848 cpu_abort(env
, "Unknown or invalid MMU model\n");
1853 /* Access rights violation */
1854 env
->exception_index
= POWERPC_EXCP_DSI
;
1855 env
->error_code
= 0;
1856 if (env
->mmu_model
== POWERPC_MMU_SOFT_4xx
1857 || env
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
) {
1858 env
->spr
[SPR_40x_DEAR
] = address
;
1860 env
->spr
[SPR_40x_ESR
] |= 0x00800000;
1862 } else if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1863 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1864 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1865 env
->spr
[SPR_BOOKE_ESR
] = rw
? 1 << ESR_ST
: 0;
1867 env
->spr
[SPR_DAR
] = address
;
1869 env
->spr
[SPR_DSISR
] = 0x0A000000;
1871 env
->spr
[SPR_DSISR
] = 0x08000000;
1876 /* Direct store exception */
1877 switch (access_type
) {
1879 /* Floating point load/store */
1880 env
->exception_index
= POWERPC_EXCP_ALIGN
;
1881 env
->error_code
= POWERPC_EXCP_ALIGN_FP
;
1882 env
->spr
[SPR_DAR
] = address
;
1885 /* lwarx, ldarx or stwcx. */
1886 env
->exception_index
= POWERPC_EXCP_DSI
;
1887 env
->error_code
= 0;
1888 env
->spr
[SPR_DAR
] = address
;
1890 env
->spr
[SPR_DSISR
] = 0x06000000;
1892 env
->spr
[SPR_DSISR
] = 0x04000000;
1895 /* eciwx or ecowx */
1896 env
->exception_index
= POWERPC_EXCP_DSI
;
1897 env
->error_code
= 0;
1898 env
->spr
[SPR_DAR
] = address
;
1900 env
->spr
[SPR_DSISR
] = 0x06100000;
1902 env
->spr
[SPR_DSISR
] = 0x04100000;
1905 printf("DSI: invalid exception (%d)\n", ret
);
1906 env
->exception_index
= POWERPC_EXCP_PROGRAM
;
1908 POWERPC_EXCP_INVAL
| POWERPC_EXCP_INVAL_INVAL
;
1909 env
->spr
[SPR_DAR
] = address
;
1913 #if defined(TARGET_PPC64)
1915 /* No match in segment table */
1916 if (env
->mmu_model
== POWERPC_MMU_620
) {
1917 env
->exception_index
= POWERPC_EXCP_DSI
;
1918 env
->error_code
= 0;
1919 env
->spr
[SPR_DAR
] = address
;
1920 /* XXX: this might be incorrect */
1922 env
->spr
[SPR_DSISR
] = 0x42000000;
1924 env
->spr
[SPR_DSISR
] = 0x40000000;
1926 env
->exception_index
= POWERPC_EXCP_DSEG
;
1927 env
->error_code
= 0;
1928 env
->spr
[SPR_DAR
] = address
;
1935 printf("%s: set exception to %d %02x\n", __func__
,
1936 env
->exception
, env
->error_code
);
1944 /*****************************************************************************/
1945 /* BATs management */
1946 #if !defined(FLUSH_ALL_TLBS)
1947 static inline void do_invalidate_BAT(CPUPPCState
*env
, target_ulong BATu
,
1950 target_ulong base
, end
, page
;
1952 base
= BATu
& ~0x0001FFFF;
1953 end
= base
+ mask
+ 0x00020000;
1954 LOG_BATS("Flush BAT from " TARGET_FMT_lx
" to " TARGET_FMT_lx
" ("
1955 TARGET_FMT_lx
")\n", base
, end
, mask
);
1956 for (page
= base
; page
!= end
; page
+= TARGET_PAGE_SIZE
)
1957 tlb_flush_page(env
, page
);
1958 LOG_BATS("Flush done\n");
1962 static inline void dump_store_bat(CPUPPCState
*env
, char ID
, int ul
, int nr
,
1965 LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx
" (" TARGET_FMT_lx
")\n", ID
,
1966 nr
, ul
== 0 ? 'u' : 'l', value
, env
->nip
);
1969 void ppc_store_ibatu (CPUPPCState
*env
, int nr
, target_ulong value
)
1973 dump_store_bat(env
, 'I', 0, nr
, value
);
1974 if (env
->IBAT
[0][nr
] != value
) {
1975 mask
= (value
<< 15) & 0x0FFE0000UL
;
1976 #if !defined(FLUSH_ALL_TLBS)
1977 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1979 /* When storing valid upper BAT, mask BEPI and BRPN
1980 * and invalidate all TLBs covered by this BAT
1982 mask
= (value
<< 15) & 0x0FFE0000UL
;
1983 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
1984 (value
& ~0x0001FFFFUL
& ~mask
);
1985 env
->IBAT
[1][nr
] = (env
->IBAT
[1][nr
] & 0x0000007B) |
1986 (env
->IBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
1987 #if !defined(FLUSH_ALL_TLBS)
1988 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
1995 void ppc_store_ibatl (CPUPPCState
*env
, int nr
, target_ulong value
)
1997 dump_store_bat(env
, 'I', 1, nr
, value
);
1998 env
->IBAT
[1][nr
] = value
;
2001 void ppc_store_dbatu (CPUPPCState
*env
, int nr
, target_ulong value
)
2005 dump_store_bat(env
, 'D', 0, nr
, value
);
2006 if (env
->DBAT
[0][nr
] != value
) {
2007 /* When storing valid upper BAT, mask BEPI and BRPN
2008 * and invalidate all TLBs covered by this BAT
2010 mask
= (value
<< 15) & 0x0FFE0000UL
;
2011 #if !defined(FLUSH_ALL_TLBS)
2012 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
2014 mask
= (value
<< 15) & 0x0FFE0000UL
;
2015 env
->DBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
2016 (value
& ~0x0001FFFFUL
& ~mask
);
2017 env
->DBAT
[1][nr
] = (env
->DBAT
[1][nr
] & 0x0000007B) |
2018 (env
->DBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
2019 #if !defined(FLUSH_ALL_TLBS)
2020 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
2027 void ppc_store_dbatl (CPUPPCState
*env
, int nr
, target_ulong value
)
2029 dump_store_bat(env
, 'D', 1, nr
, value
);
2030 env
->DBAT
[1][nr
] = value
;
2033 void ppc_store_ibatu_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
2036 #if defined(FLUSH_ALL_TLBS)
2040 dump_store_bat(env
, 'I', 0, nr
, value
);
2041 if (env
->IBAT
[0][nr
] != value
) {
2042 #if defined(FLUSH_ALL_TLBS)
2045 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
2046 if (env
->IBAT
[1][nr
] & 0x40) {
2047 /* Invalidate BAT only if it is valid */
2048 #if !defined(FLUSH_ALL_TLBS)
2049 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2054 /* When storing valid upper BAT, mask BEPI and BRPN
2055 * and invalidate all TLBs covered by this BAT
2057 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
2058 (value
& ~0x0001FFFFUL
& ~mask
);
2059 env
->DBAT
[0][nr
] = env
->IBAT
[0][nr
];
2060 if (env
->IBAT
[1][nr
] & 0x40) {
2061 #if !defined(FLUSH_ALL_TLBS)
2062 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2067 #if defined(FLUSH_ALL_TLBS)
2074 void ppc_store_ibatl_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
2077 #if defined(FLUSH_ALL_TLBS)
2081 dump_store_bat(env
, 'I', 1, nr
, value
);
2082 if (env
->IBAT
[1][nr
] != value
) {
2083 #if defined(FLUSH_ALL_TLBS)
2086 if (env
->IBAT
[1][nr
] & 0x40) {
2087 #if !defined(FLUSH_ALL_TLBS)
2088 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
2089 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2095 #if !defined(FLUSH_ALL_TLBS)
2096 mask
= (value
<< 17) & 0x0FFE0000UL
;
2097 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2102 env
->IBAT
[1][nr
] = value
;
2103 env
->DBAT
[1][nr
] = value
;
2104 #if defined(FLUSH_ALL_TLBS)
2111 /*****************************************************************************/
2112 /* TLB management */
2113 void ppc_tlb_invalidate_all (CPUPPCState
*env
)
2115 switch (env
->mmu_model
) {
2116 case POWERPC_MMU_SOFT_6xx
:
2117 case POWERPC_MMU_SOFT_74xx
:
2118 ppc6xx_tlb_invalidate_all(env
);
2120 case POWERPC_MMU_SOFT_4xx
:
2121 case POWERPC_MMU_SOFT_4xx_Z
:
2122 ppc4xx_tlb_invalidate_all(env
);
2124 case POWERPC_MMU_REAL
:
2125 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
2127 case POWERPC_MMU_MPC8xx
:
2129 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
2131 case POWERPC_MMU_BOOKE
:
2134 case POWERPC_MMU_BOOKE206
:
2135 booke206_flush_tlb(env
, -1, 0);
2137 case POWERPC_MMU_32B
:
2138 case POWERPC_MMU_601
:
2139 #if defined(TARGET_PPC64)
2140 case POWERPC_MMU_620
:
2141 case POWERPC_MMU_64B
:
2142 case POWERPC_MMU_2_06
:
2143 #endif /* defined(TARGET_PPC64) */
2148 cpu_abort(env
, "Unknown MMU model\n");
2153 void ppc_tlb_invalidate_one (CPUPPCState
*env
, target_ulong addr
)
2155 #if !defined(FLUSH_ALL_TLBS)
2156 addr
&= TARGET_PAGE_MASK
;
2157 switch (env
->mmu_model
) {
2158 case POWERPC_MMU_SOFT_6xx
:
2159 case POWERPC_MMU_SOFT_74xx
:
2160 ppc6xx_tlb_invalidate_virt(env
, addr
, 0);
2161 if (env
->id_tlbs
== 1)
2162 ppc6xx_tlb_invalidate_virt(env
, addr
, 1);
2164 case POWERPC_MMU_SOFT_4xx
:
2165 case POWERPC_MMU_SOFT_4xx_Z
:
2166 ppc4xx_tlb_invalidate_virt(env
, addr
, env
->spr
[SPR_40x_PID
]);
2168 case POWERPC_MMU_REAL
:
2169 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
2171 case POWERPC_MMU_MPC8xx
:
2173 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
2175 case POWERPC_MMU_BOOKE
:
2177 cpu_abort(env
, "BookE MMU model is not implemented\n");
2179 case POWERPC_MMU_BOOKE206
:
2181 cpu_abort(env
, "BookE 2.06 MMU model is not implemented\n");
2183 case POWERPC_MMU_32B
:
2184 case POWERPC_MMU_601
:
2185 /* tlbie invalidate TLBs for all segments */
2186 addr
&= ~((target_ulong
)-1ULL << 28);
2187 /* XXX: this case should be optimized,
2188 * giving a mask to tlb_flush_page
2190 tlb_flush_page(env
, addr
| (0x0 << 28));
2191 tlb_flush_page(env
, addr
| (0x1 << 28));
2192 tlb_flush_page(env
, addr
| (0x2 << 28));
2193 tlb_flush_page(env
, addr
| (0x3 << 28));
2194 tlb_flush_page(env
, addr
| (0x4 << 28));
2195 tlb_flush_page(env
, addr
| (0x5 << 28));
2196 tlb_flush_page(env
, addr
| (0x6 << 28));
2197 tlb_flush_page(env
, addr
| (0x7 << 28));
2198 tlb_flush_page(env
, addr
| (0x8 << 28));
2199 tlb_flush_page(env
, addr
| (0x9 << 28));
2200 tlb_flush_page(env
, addr
| (0xA << 28));
2201 tlb_flush_page(env
, addr
| (0xB << 28));
2202 tlb_flush_page(env
, addr
| (0xC << 28));
2203 tlb_flush_page(env
, addr
| (0xD << 28));
2204 tlb_flush_page(env
, addr
| (0xE << 28));
2205 tlb_flush_page(env
, addr
| (0xF << 28));
2207 #if defined(TARGET_PPC64)
2208 case POWERPC_MMU_620
:
2209 case POWERPC_MMU_64B
:
2210 case POWERPC_MMU_2_06
:
2211 /* tlbie invalidate TLBs for all segments */
2212 /* XXX: given the fact that there are too many segments to invalidate,
2213 * and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
2214 * we just invalidate all TLBs
2218 #endif /* defined(TARGET_PPC64) */
2221 cpu_abort(env
, "Unknown MMU model\n");
2225 ppc_tlb_invalidate_all(env
);
2229 /*****************************************************************************/
2230 /* Special registers manipulation */
2231 #if defined(TARGET_PPC64)
2232 void ppc_store_asr (CPUPPCState
*env
, target_ulong value
)
2234 if (env
->asr
!= value
) {
2241 void ppc_store_sdr1 (CPUPPCState
*env
, target_ulong value
)
2243 LOG_MMU("%s: " TARGET_FMT_lx
"\n", __func__
, value
);
2244 if (env
->spr
[SPR_SDR1
] != value
) {
2245 env
->spr
[SPR_SDR1
] = value
;
2246 #if defined(TARGET_PPC64)
2247 if (env
->mmu_model
& POWERPC_MMU_64
) {
2248 target_ulong htabsize
= value
& SDR_64_HTABSIZE
;
2250 if (htabsize
> 28) {
2251 fprintf(stderr
, "Invalid HTABSIZE 0x" TARGET_FMT_lx
2252 " stored in SDR1\n", htabsize
);
2255 env
->htab_mask
= (1ULL << (htabsize
+ 18)) - 1;
2256 env
->htab_base
= value
& SDR_64_HTABORG
;
2258 #endif /* defined(TARGET_PPC64) */
2260 /* FIXME: Should check for valid HTABMASK values */
2261 env
->htab_mask
= ((value
& SDR_32_HTABMASK
) << 16) | 0xFFFF;
2262 env
->htab_base
= value
& SDR_32_HTABORG
;
2268 #if defined(TARGET_PPC64)
2269 target_ulong
ppc_load_sr (CPUPPCState
*env
, int slb_nr
)
2276 void ppc_store_sr (CPUPPCState
*env
, int srnum
, target_ulong value
)
2278 LOG_MMU("%s: reg=%d " TARGET_FMT_lx
" " TARGET_FMT_lx
"\n", __func__
,
2279 srnum
, value
, env
->sr
[srnum
]);
2280 #if defined(TARGET_PPC64)
2281 if (env
->mmu_model
& POWERPC_MMU_64
) {
2282 uint64_t rb
= 0, rs
= 0;
2285 rb
|= ((uint32_t)srnum
& 0xf) << 28;
2286 /* Set the valid bit */
2289 rb
|= (uint32_t)srnum
;
2292 rs
|= (value
& 0xfffffff) << 12;
2294 rs
|= ((value
>> 27) & 0xf) << 8;
2296 ppc_store_slb(env
, rb
, rs
);
2299 if (env
->sr
[srnum
] != value
) {
2300 env
->sr
[srnum
] = value
;
2301 /* Invalidating 256MB of virtual memory in 4kB pages is way longer than
2302 flusing the whole TLB. */
2303 #if !defined(FLUSH_ALL_TLBS) && 0
2305 target_ulong page
, end
;
2306 /* Invalidate 256 MB of virtual memory */
2307 page
= (16 << 20) * srnum
;
2308 end
= page
+ (16 << 20);
2309 for (; page
!= end
; page
+= TARGET_PAGE_SIZE
)
2310 tlb_flush_page(env
, page
);
2317 #endif /* !defined (CONFIG_USER_ONLY) */
2319 /* GDBstub can read and write MSR... */
2320 void ppc_store_msr (CPUPPCState
*env
, target_ulong value
)
2322 hreg_store_msr(env
, value
, 0);
2325 /*****************************************************************************/
2326 /* Exception processing */
2327 #if defined (CONFIG_USER_ONLY)
2328 void do_interrupt (CPUState
*env
)
2330 env
->exception_index
= POWERPC_EXCP_NONE
;
2331 env
->error_code
= 0;
2334 void ppc_hw_interrupt (CPUState
*env
)
2336 env
->exception_index
= POWERPC_EXCP_NONE
;
2337 env
->error_code
= 0;
2339 #else /* defined (CONFIG_USER_ONLY) */
2340 static inline void dump_syscall(CPUState
*env
)
2342 qemu_log_mask(CPU_LOG_INT
, "syscall r0=%016" PRIx64
" r3=%016" PRIx64
2343 " r4=%016" PRIx64
" r5=%016" PRIx64
" r6=%016" PRIx64
2344 " nip=" TARGET_FMT_lx
"\n",
2345 ppc_dump_gpr(env
, 0), ppc_dump_gpr(env
, 3),
2346 ppc_dump_gpr(env
, 4), ppc_dump_gpr(env
, 5),
2347 ppc_dump_gpr(env
, 6), env
->nip
);
2350 /* Note that this function should be greatly optimized
2351 * when called with a constant excp, from ppc_hw_interrupt
2353 static inline void powerpc_excp(CPUState
*env
, int excp_model
, int excp
)
2355 target_ulong msr
, new_msr
, vector
;
2356 int srr0
, srr1
, asrr0
, asrr1
;
2357 int lpes0
, lpes1
, lev
;
2360 /* XXX: find a suitable condition to enable the hypervisor mode */
2361 lpes0
= (env
->spr
[SPR_LPCR
] >> 1) & 1;
2362 lpes1
= (env
->spr
[SPR_LPCR
] >> 2) & 1;
2364 /* Those values ensure we won't enter the hypervisor mode */
2369 qemu_log_mask(CPU_LOG_INT
, "Raise exception at " TARGET_FMT_lx
2370 " => %08x (%02x)\n", env
->nip
, excp
, env
->error_code
);
2372 /* new srr1 value excluding must-be-zero bits */
2373 msr
= env
->msr
& ~0x783f0000ULL
;
2375 /* new interrupt handler msr */
2376 new_msr
= env
->msr
& ((target_ulong
)1 << MSR_ME
);
2378 /* target registers */
2385 case POWERPC_EXCP_NONE
:
2386 /* Should never happen */
2388 case POWERPC_EXCP_CRITICAL
: /* Critical input */
2389 switch (excp_model
) {
2390 case POWERPC_EXCP_40x
:
2391 srr0
= SPR_40x_SRR2
;
2392 srr1
= SPR_40x_SRR3
;
2394 case POWERPC_EXCP_BOOKE
:
2395 srr0
= SPR_BOOKE_CSRR0
;
2396 srr1
= SPR_BOOKE_CSRR1
;
2398 case POWERPC_EXCP_G2
:
2404 case POWERPC_EXCP_MCHECK
: /* Machine check exception */
2406 /* Machine check exception is not enabled.
2407 * Enter checkstop state.
2409 if (qemu_log_enabled()) {
2410 qemu_log("Machine check while not allowed. "
2411 "Entering checkstop state\n");
2413 fprintf(stderr
, "Machine check while not allowed. "
2414 "Entering checkstop state\n");
2417 env
->interrupt_request
|= CPU_INTERRUPT_EXITTB
;
2420 /* XXX: find a suitable condition to enable the hypervisor mode */
2421 new_msr
|= (target_ulong
)MSR_HVB
;
2424 /* machine check exceptions don't have ME set */
2425 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2427 /* XXX: should also have something loaded in DAR / DSISR */
2428 switch (excp_model
) {
2429 case POWERPC_EXCP_40x
:
2430 srr0
= SPR_40x_SRR2
;
2431 srr1
= SPR_40x_SRR3
;
2433 case POWERPC_EXCP_BOOKE
:
2434 srr0
= SPR_BOOKE_MCSRR0
;
2435 srr1
= SPR_BOOKE_MCSRR1
;
2436 asrr0
= SPR_BOOKE_CSRR0
;
2437 asrr1
= SPR_BOOKE_CSRR1
;
2443 case POWERPC_EXCP_DSI
: /* Data storage exception */
2444 LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx
" DAR=" TARGET_FMT_lx
2445 "\n", env
->spr
[SPR_DSISR
], env
->spr
[SPR_DAR
]);
2447 new_msr
|= (target_ulong
)MSR_HVB
;
2449 case POWERPC_EXCP_ISI
: /* Instruction storage exception */
2450 LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx
", nip=" TARGET_FMT_lx
2451 "\n", msr
, env
->nip
);
2453 new_msr
|= (target_ulong
)MSR_HVB
;
2454 msr
|= env
->error_code
;
2456 case POWERPC_EXCP_EXTERNAL
: /* External input */
2458 new_msr
|= (target_ulong
)MSR_HVB
;
2460 case POWERPC_EXCP_ALIGN
: /* Alignment exception */
2462 new_msr
|= (target_ulong
)MSR_HVB
;
2463 /* XXX: this is false */
2464 /* Get rS/rD and rA from faulting opcode */
2465 env
->spr
[SPR_DSISR
] |= (ldl_code((env
->nip
- 4)) & 0x03FF0000) >> 16;
2467 case POWERPC_EXCP_PROGRAM
: /* Program exception */
2468 switch (env
->error_code
& ~0xF) {
2469 case POWERPC_EXCP_FP
:
2470 if ((msr_fe0
== 0 && msr_fe1
== 0) || msr_fp
== 0) {
2471 LOG_EXCP("Ignore floating point exception\n");
2472 env
->exception_index
= POWERPC_EXCP_NONE
;
2473 env
->error_code
= 0;
2477 new_msr
|= (target_ulong
)MSR_HVB
;
2479 if (msr_fe0
== msr_fe1
)
2483 case POWERPC_EXCP_INVAL
:
2484 LOG_EXCP("Invalid instruction at " TARGET_FMT_lx
"\n", env
->nip
);
2486 new_msr
|= (target_ulong
)MSR_HVB
;
2489 case POWERPC_EXCP_PRIV
:
2491 new_msr
|= (target_ulong
)MSR_HVB
;
2494 case POWERPC_EXCP_TRAP
:
2496 new_msr
|= (target_ulong
)MSR_HVB
;
2500 /* Should never occur */
2501 cpu_abort(env
, "Invalid program exception %d. Aborting\n",
2506 case POWERPC_EXCP_FPU
: /* Floating-point unavailable exception */
2508 new_msr
|= (target_ulong
)MSR_HVB
;
2510 case POWERPC_EXCP_SYSCALL
: /* System call exception */
2512 lev
= env
->error_code
;
2513 if ((lev
== 1) && cpu_ppc_hypercall
) {
2514 cpu_ppc_hypercall(env
);
2517 if (lev
== 1 || (lpes0
== 0 && lpes1
== 0))
2518 new_msr
|= (target_ulong
)MSR_HVB
;
2520 case POWERPC_EXCP_APU
: /* Auxiliary processor unavailable */
2522 case POWERPC_EXCP_DECR
: /* Decrementer exception */
2524 new_msr
|= (target_ulong
)MSR_HVB
;
2526 case POWERPC_EXCP_FIT
: /* Fixed-interval timer interrupt */
2528 LOG_EXCP("FIT exception\n");
2530 case POWERPC_EXCP_WDT
: /* Watchdog timer interrupt */
2531 LOG_EXCP("WDT exception\n");
2532 switch (excp_model
) {
2533 case POWERPC_EXCP_BOOKE
:
2534 srr0
= SPR_BOOKE_CSRR0
;
2535 srr1
= SPR_BOOKE_CSRR1
;
2541 case POWERPC_EXCP_DTLB
: /* Data TLB error */
2543 case POWERPC_EXCP_ITLB
: /* Instruction TLB error */
2545 case POWERPC_EXCP_DEBUG
: /* Debug interrupt */
2546 switch (excp_model
) {
2547 case POWERPC_EXCP_BOOKE
:
2548 srr0
= SPR_BOOKE_DSRR0
;
2549 srr1
= SPR_BOOKE_DSRR1
;
2550 asrr0
= SPR_BOOKE_CSRR0
;
2551 asrr1
= SPR_BOOKE_CSRR1
;
2557 cpu_abort(env
, "Debug exception is not implemented yet !\n");
2559 case POWERPC_EXCP_SPEU
: /* SPE/embedded floating-point unavailable */
2561 case POWERPC_EXCP_EFPDI
: /* Embedded floating-point data interrupt */
2563 cpu_abort(env
, "Embedded floating point data exception "
2564 "is not implemented yet !\n");
2566 case POWERPC_EXCP_EFPRI
: /* Embedded floating-point round interrupt */
2568 cpu_abort(env
, "Embedded floating point round exception "
2569 "is not implemented yet !\n");
2571 case POWERPC_EXCP_EPERFM
: /* Embedded performance monitor interrupt */
2574 "Performance counter exception is not implemented yet !\n");
2576 case POWERPC_EXCP_DOORI
: /* Embedded doorbell interrupt */
2579 "Embedded doorbell interrupt is not implemented yet !\n");
2581 case POWERPC_EXCP_DOORCI
: /* Embedded doorbell critical interrupt */
2582 switch (excp_model
) {
2583 case POWERPC_EXCP_BOOKE
:
2584 srr0
= SPR_BOOKE_CSRR0
;
2585 srr1
= SPR_BOOKE_CSRR1
;
2591 cpu_abort(env
, "Embedded doorbell critical interrupt "
2592 "is not implemented yet !\n");
2594 case POWERPC_EXCP_RESET
: /* System reset exception */
2596 /* indicate that we resumed from power save mode */
2599 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2603 /* XXX: find a suitable condition to enable the hypervisor mode */
2604 new_msr
|= (target_ulong
)MSR_HVB
;
2607 case POWERPC_EXCP_DSEG
: /* Data segment exception */
2609 new_msr
|= (target_ulong
)MSR_HVB
;
2611 case POWERPC_EXCP_ISEG
: /* Instruction segment exception */
2613 new_msr
|= (target_ulong
)MSR_HVB
;
2615 case POWERPC_EXCP_HDECR
: /* Hypervisor decrementer exception */
2618 new_msr
|= (target_ulong
)MSR_HVB
;
2619 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2621 case POWERPC_EXCP_TRACE
: /* Trace exception */
2623 new_msr
|= (target_ulong
)MSR_HVB
;
2625 case POWERPC_EXCP_HDSI
: /* Hypervisor data storage exception */
2628 new_msr
|= (target_ulong
)MSR_HVB
;
2629 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2631 case POWERPC_EXCP_HISI
: /* Hypervisor instruction storage exception */
2634 new_msr
|= (target_ulong
)MSR_HVB
;
2635 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2637 case POWERPC_EXCP_HDSEG
: /* Hypervisor data segment exception */
2640 new_msr
|= (target_ulong
)MSR_HVB
;
2641 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2643 case POWERPC_EXCP_HISEG
: /* Hypervisor instruction segment exception */
2646 new_msr
|= (target_ulong
)MSR_HVB
;
2647 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2649 case POWERPC_EXCP_VPU
: /* Vector unavailable exception */
2651 new_msr
|= (target_ulong
)MSR_HVB
;
2653 case POWERPC_EXCP_PIT
: /* Programmable interval timer interrupt */
2654 LOG_EXCP("PIT exception\n");
2656 case POWERPC_EXCP_IO
: /* IO error exception */
2658 cpu_abort(env
, "601 IO error exception is not implemented yet !\n");
2660 case POWERPC_EXCP_RUNM
: /* Run mode exception */
2662 cpu_abort(env
, "601 run mode exception is not implemented yet !\n");
2664 case POWERPC_EXCP_EMUL
: /* Emulation trap exception */
2666 cpu_abort(env
, "602 emulation trap exception "
2667 "is not implemented yet !\n");
2669 case POWERPC_EXCP_IFTLB
: /* Instruction fetch TLB error */
2670 if (lpes1
== 0) /* XXX: check this */
2671 new_msr
|= (target_ulong
)MSR_HVB
;
2672 switch (excp_model
) {
2673 case POWERPC_EXCP_602
:
2674 case POWERPC_EXCP_603
:
2675 case POWERPC_EXCP_603E
:
2676 case POWERPC_EXCP_G2
:
2678 case POWERPC_EXCP_7x5
:
2680 case POWERPC_EXCP_74xx
:
2683 cpu_abort(env
, "Invalid instruction TLB miss exception\n");
2687 case POWERPC_EXCP_DLTLB
: /* Data load TLB miss */
2688 if (lpes1
== 0) /* XXX: check this */
2689 new_msr
|= (target_ulong
)MSR_HVB
;
2690 switch (excp_model
) {
2691 case POWERPC_EXCP_602
:
2692 case POWERPC_EXCP_603
:
2693 case POWERPC_EXCP_603E
:
2694 case POWERPC_EXCP_G2
:
2696 case POWERPC_EXCP_7x5
:
2698 case POWERPC_EXCP_74xx
:
2701 cpu_abort(env
, "Invalid data load TLB miss exception\n");
2705 case POWERPC_EXCP_DSTLB
: /* Data store TLB miss */
2706 if (lpes1
== 0) /* XXX: check this */
2707 new_msr
|= (target_ulong
)MSR_HVB
;
2708 switch (excp_model
) {
2709 case POWERPC_EXCP_602
:
2710 case POWERPC_EXCP_603
:
2711 case POWERPC_EXCP_603E
:
2712 case POWERPC_EXCP_G2
:
2714 /* Swap temporary saved registers with GPRs */
2715 if (!(new_msr
& ((target_ulong
)1 << MSR_TGPR
))) {
2716 new_msr
|= (target_ulong
)1 << MSR_TGPR
;
2717 hreg_swap_gpr_tgpr(env
);
2720 case POWERPC_EXCP_7x5
:
2722 #if defined (DEBUG_SOFTWARE_TLB)
2723 if (qemu_log_enabled()) {
2725 target_ulong
*miss
, *cmp
;
2727 if (excp
== POWERPC_EXCP_IFTLB
) {
2730 miss
= &env
->spr
[SPR_IMISS
];
2731 cmp
= &env
->spr
[SPR_ICMP
];
2733 if (excp
== POWERPC_EXCP_DLTLB
)
2738 miss
= &env
->spr
[SPR_DMISS
];
2739 cmp
= &env
->spr
[SPR_DCMP
];
2741 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2742 TARGET_FMT_lx
" H1 " TARGET_FMT_lx
" H2 "
2743 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2744 env
->spr
[SPR_HASH1
], env
->spr
[SPR_HASH2
],
2748 msr
|= env
->crf
[0] << 28;
2749 msr
|= env
->error_code
; /* key, D/I, S/L bits */
2750 /* Set way using a LRU mechanism */
2751 msr
|= ((env
->last_way
+ 1) & (env
->nb_ways
- 1)) << 17;
2753 case POWERPC_EXCP_74xx
:
2755 #if defined (DEBUG_SOFTWARE_TLB)
2756 if (qemu_log_enabled()) {
2758 target_ulong
*miss
, *cmp
;
2760 if (excp
== POWERPC_EXCP_IFTLB
) {
2763 miss
= &env
->spr
[SPR_TLBMISS
];
2764 cmp
= &env
->spr
[SPR_PTEHI
];
2766 if (excp
== POWERPC_EXCP_DLTLB
)
2771 miss
= &env
->spr
[SPR_TLBMISS
];
2772 cmp
= &env
->spr
[SPR_PTEHI
];
2774 qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2775 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2779 msr
|= env
->error_code
; /* key bit */
2782 cpu_abort(env
, "Invalid data store TLB miss exception\n");
2786 case POWERPC_EXCP_FPA
: /* Floating-point assist exception */
2788 cpu_abort(env
, "Floating point assist exception "
2789 "is not implemented yet !\n");
2791 case POWERPC_EXCP_DABR
: /* Data address breakpoint */
2793 cpu_abort(env
, "DABR exception is not implemented yet !\n");
2795 case POWERPC_EXCP_IABR
: /* Instruction address breakpoint */
2797 cpu_abort(env
, "IABR exception is not implemented yet !\n");
2799 case POWERPC_EXCP_SMI
: /* System management interrupt */
2801 cpu_abort(env
, "SMI exception is not implemented yet !\n");
2803 case POWERPC_EXCP_THERM
: /* Thermal interrupt */
2805 cpu_abort(env
, "Thermal management exception "
2806 "is not implemented yet !\n");
2808 case POWERPC_EXCP_PERFM
: /* Embedded performance monitor interrupt */
2810 new_msr
|= (target_ulong
)MSR_HVB
;
2813 "Performance counter exception is not implemented yet !\n");
2815 case POWERPC_EXCP_VPUA
: /* Vector assist exception */
2817 cpu_abort(env
, "VPU assist exception is not implemented yet !\n");
2819 case POWERPC_EXCP_SOFTP
: /* Soft patch exception */
2822 "970 soft-patch exception is not implemented yet !\n");
2824 case POWERPC_EXCP_MAINT
: /* Maintenance exception */
2827 "970 maintenance exception is not implemented yet !\n");
2829 case POWERPC_EXCP_MEXTBR
: /* Maskable external breakpoint */
2831 cpu_abort(env
, "Maskable external exception "
2832 "is not implemented yet !\n");
2834 case POWERPC_EXCP_NMEXTBR
: /* Non maskable external breakpoint */
2836 cpu_abort(env
, "Non maskable external exception "
2837 "is not implemented yet !\n");
2841 cpu_abort(env
, "Invalid PowerPC exception %d. Aborting\n", excp
);
2844 /* save current instruction location */
2845 env
->spr
[srr0
] = env
->nip
- 4;
2848 /* save next instruction location */
2849 env
->spr
[srr0
] = env
->nip
;
2853 env
->spr
[srr1
] = msr
;
2854 /* If any alternate SRR register are defined, duplicate saved values */
2856 env
->spr
[asrr0
] = env
->spr
[srr0
];
2858 env
->spr
[asrr1
] = env
->spr
[srr1
];
2859 /* If we disactivated any translation, flush TLBs */
2860 if (new_msr
& ((1 << MSR_IR
) | (1 << MSR_DR
)))
2864 new_msr
|= (target_ulong
)1 << MSR_LE
;
2867 /* Jump to handler */
2868 vector
= env
->excp_vectors
[excp
];
2869 if (vector
== (target_ulong
)-1ULL) {
2870 cpu_abort(env
, "Raised an exception without defined vector %d\n",
2873 vector
|= env
->excp_prefix
;
2874 #if defined(TARGET_PPC64)
2875 if (excp_model
== POWERPC_EXCP_BOOKE
) {
2877 vector
= (uint32_t)vector
;
2879 new_msr
|= (target_ulong
)1 << MSR_CM
;
2882 if (!msr_isf
&& !(env
->mmu_model
& POWERPC_MMU_64
)) {
2883 vector
= (uint32_t)vector
;
2885 new_msr
|= (target_ulong
)1 << MSR_SF
;
2889 /* XXX: we don't use hreg_store_msr here as already have treated
2890 * any special case that could occur. Just store MSR and update hflags
2892 env
->msr
= new_msr
& env
->msr_mask
;
2893 hreg_compute_hflags(env
);
2895 /* Reset exception state */
2896 env
->exception_index
= POWERPC_EXCP_NONE
;
2897 env
->error_code
= 0;
2899 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
2900 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
2901 /* XXX: The BookE changes address space when switching modes,
2902 we should probably implement that as different MMU indexes,
2903 but for the moment we do it the slow way and flush all. */
2908 void do_interrupt (CPUState
*env
)
2910 powerpc_excp(env
, env
->excp_model
, env
->exception_index
);
2913 void ppc_hw_interrupt (CPUPPCState
*env
)
2918 qemu_log_mask(CPU_LOG_INT
, "%s: %p pending %08x req %08x me %d ee %d\n",
2919 __func__
, env
, env
->pending_interrupts
,
2920 env
->interrupt_request
, (int)msr_me
, (int)msr_ee
);
2922 /* External reset */
2923 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_RESET
)) {
2924 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_RESET
);
2925 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_RESET
);
2928 /* Machine check exception */
2929 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_MCK
)) {
2930 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_MCK
);
2931 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_MCHECK
);
2935 /* External debug exception */
2936 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DEBUG
)) {
2937 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DEBUG
);
2938 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DEBUG
);
2943 /* XXX: find a suitable condition to enable the hypervisor mode */
2944 hdice
= env
->spr
[SPR_LPCR
] & 1;
2948 if ((msr_ee
!= 0 || msr_hv
== 0 || msr_pr
!= 0) && hdice
!= 0) {
2949 /* Hypervisor decrementer exception */
2950 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_HDECR
)) {
2951 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_HDECR
);
2952 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_HDECR
);
2957 /* External critical interrupt */
2958 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CEXT
)) {
2959 /* Taking a critical external interrupt does not clear the external
2960 * critical interrupt status
2963 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CEXT
);
2965 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_CRITICAL
);
2970 /* Watchdog timer on embedded PowerPC */
2971 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_WDT
)) {
2972 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_WDT
);
2973 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_WDT
);
2976 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CDOORBELL
)) {
2977 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CDOORBELL
);
2978 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORCI
);
2981 /* Fixed interval timer on embedded PowerPC */
2982 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_FIT
)) {
2983 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_FIT
);
2984 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_FIT
);
2987 /* Programmable interval timer on embedded PowerPC */
2988 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PIT
)) {
2989 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PIT
);
2990 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PIT
);
2993 /* Decrementer exception */
2994 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DECR
)) {
2995 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DECR
);
2996 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DECR
);
2999 /* External interrupt */
3000 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_EXT
)) {
3001 /* Taking an external interrupt does not clear the external
3005 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_EXT
);
3007 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_EXTERNAL
);
3010 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DOORBELL
)) {
3011 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DOORBELL
);
3012 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORI
);
3015 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PERFM
)) {
3016 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PERFM
);
3017 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PERFM
);
3020 /* Thermal interrupt */
3021 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_THERM
)) {
3022 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_THERM
);
3023 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_THERM
);
3028 #endif /* !CONFIG_USER_ONLY */
3030 void cpu_dump_rfi (target_ulong RA
, target_ulong msr
)
3032 qemu_log("Return from exception at " TARGET_FMT_lx
" with flags "
3033 TARGET_FMT_lx
"\n", RA
, msr
);
3036 void cpu_reset(CPUPPCState
*env
)
3040 if (qemu_loglevel_mask(CPU_LOG_RESET
)) {
3041 qemu_log("CPU Reset (CPU %d)\n", env
->cpu_index
);
3042 log_cpu_state(env
, 0);
3045 msr
= (target_ulong
)0;
3047 /* XXX: find a suitable condition to enable the hypervisor mode */
3048 msr
|= (target_ulong
)MSR_HVB
;
3050 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
3051 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
3052 msr
|= (target_ulong
)1 << MSR_EP
;
3053 #if defined (DO_SINGLE_STEP) && 0
3054 /* Single step trace mode */
3055 msr
|= (target_ulong
)1 << MSR_SE
;
3056 msr
|= (target_ulong
)1 << MSR_BE
;
3058 #if defined(CONFIG_USER_ONLY)
3059 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
3060 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
3061 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
3062 msr
|= (target_ulong
)1 << MSR_PR
;
3064 env
->excp_prefix
= env
->hreset_excp_prefix
;
3065 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
3066 if (env
->mmu_model
!= POWERPC_MMU_REAL
)
3067 ppc_tlb_invalidate_all(env
);
3069 env
->msr
= msr
& env
->msr_mask
;
3070 #if defined(TARGET_PPC64)
3071 if (env
->mmu_model
& POWERPC_MMU_64
)
3072 env
->msr
|= (1ULL << MSR_SF
);
3074 hreg_compute_hflags(env
);
3075 env
->reserve_addr
= (target_ulong
)-1ULL;
3076 /* Be sure no exception or interrupt is pending */
3077 env
->pending_interrupts
= 0;
3078 env
->exception_index
= POWERPC_EXCP_NONE
;
3079 env
->error_code
= 0;
3080 /* Flush all TLBs */
3084 CPUPPCState
*cpu_ppc_init (const char *cpu_model
)
3087 const ppc_def_t
*def
;
3089 def
= cpu_ppc_find_by_name(cpu_model
);
3093 env
= qemu_mallocz(sizeof(CPUPPCState
));
3095 ppc_translate_init();
3096 env
->cpu_model_str
= cpu_model
;
3097 cpu_ppc_register_internal(env
, def
);
3099 qemu_init_vcpu(env
);
3104 void cpu_ppc_close (CPUPPCState
*env
)
3106 /* Should also remove all opcode tables... */