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/>.
26 #include "helper_regs.h"
27 #include "qemu-common.h"
35 //#define DEBUG_SOFTWARE_TLB
36 //#define DUMP_PAGE_TABLES
37 //#define DEBUG_EXCEPTIONS
38 //#define FLUSH_ALL_TLBS
41 # define LOG_MMU(...) qemu_log(__VA_ARGS__)
42 # define LOG_MMU_STATE(env) log_cpu_state((env), 0)
44 # define LOG_MMU(...) do { } while (0)
45 # define LOG_MMU_STATE(...) do { } while (0)
49 #ifdef DEBUG_SOFTWARE_TLB
50 # define LOG_SWTLB(...) qemu_log(__VA_ARGS__)
52 # define LOG_SWTLB(...) do { } while (0)
56 # define LOG_BATS(...) qemu_log(__VA_ARGS__)
58 # define LOG_BATS(...) do { } while (0)
62 # define LOG_SLB(...) qemu_log(__VA_ARGS__)
64 # define LOG_SLB(...) do { } while (0)
67 #ifdef DEBUG_EXCEPTIONS
68 # define LOG_EXCP(...) qemu_log(__VA_ARGS__)
70 # define LOG_EXCP(...) do { } while (0)
73 /*****************************************************************************/
74 /* PowerPC Hypercall emulation */
76 void (*cpu_ppc_hypercall
)(CPUState
*);
78 /*****************************************************************************/
79 /* PowerPC MMU emulation */
81 #if defined(CONFIG_USER_ONLY)
82 int cpu_ppc_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
85 int exception
, error_code
;
88 exception
= POWERPC_EXCP_ISI
;
89 error_code
= 0x40000000;
91 exception
= POWERPC_EXCP_DSI
;
92 error_code
= 0x40000000;
94 error_code
|= 0x02000000;
95 env
->spr
[SPR_DAR
] = address
;
96 env
->spr
[SPR_DSISR
] = error_code
;
98 env
->exception_index
= exception
;
99 env
->error_code
= error_code
;
105 /* Common routines used by software and hardware TLBs emulation */
106 static inline int pte_is_valid(target_ulong pte0
)
108 return pte0
& 0x80000000 ? 1 : 0;
111 static inline void pte_invalidate(target_ulong
*pte0
)
113 *pte0
&= ~0x80000000;
116 #if defined(TARGET_PPC64)
117 static inline int pte64_is_valid(target_ulong pte0
)
119 return pte0
& 0x0000000000000001ULL
? 1 : 0;
122 static inline void pte64_invalidate(target_ulong
*pte0
)
124 *pte0
&= ~0x0000000000000001ULL
;
128 #define PTE_PTEM_MASK 0x7FFFFFBF
129 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
130 #if defined(TARGET_PPC64)
131 #define PTE64_PTEM_MASK 0xFFFFFFFFFFFFFF80ULL
132 #define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F)
135 static inline int pp_check(int key
, int pp
, int nx
)
139 /* Compute access rights */
140 /* When pp is 3/7, the result is undefined. Set it to noaccess */
147 access
|= PAGE_WRITE
;
165 access
= PAGE_READ
| PAGE_WRITE
;
175 static inline int check_prot(int prot
, int rw
, int access_type
)
179 if (access_type
== ACCESS_CODE
) {
180 if (prot
& PAGE_EXEC
)
185 if (prot
& PAGE_WRITE
)
190 if (prot
& PAGE_READ
)
199 static inline int _pte_check(mmu_ctx_t
*ctx
, int is_64b
, target_ulong pte0
,
200 target_ulong pte1
, int h
, int rw
, int type
)
202 target_ulong ptem
, mmask
;
203 int access
, ret
, pteh
, ptev
, pp
;
206 /* Check validity and table match */
207 #if defined(TARGET_PPC64)
209 ptev
= pte64_is_valid(pte0
);
210 pteh
= (pte0
>> 1) & 1;
214 ptev
= pte_is_valid(pte0
);
215 pteh
= (pte0
>> 6) & 1;
217 if (ptev
&& h
== pteh
) {
218 /* Check vsid & api */
219 #if defined(TARGET_PPC64)
221 ptem
= pte0
& PTE64_PTEM_MASK
;
222 mmask
= PTE64_CHECK_MASK
;
223 pp
= (pte1
& 0x00000003) | ((pte1
>> 61) & 0x00000004);
224 ctx
->nx
= (pte1
>> 2) & 1; /* No execute bit */
225 ctx
->nx
|= (pte1
>> 3) & 1; /* Guarded bit */
229 ptem
= pte0
& PTE_PTEM_MASK
;
230 mmask
= PTE_CHECK_MASK
;
231 pp
= pte1
& 0x00000003;
233 if (ptem
== ctx
->ptem
) {
234 if (ctx
->raddr
!= (target_phys_addr_t
)-1ULL) {
235 /* all matches should have equal RPN, WIMG & PP */
236 if ((ctx
->raddr
& mmask
) != (pte1
& mmask
)) {
237 qemu_log("Bad RPN/WIMG/PP\n");
241 /* Compute access rights */
242 access
= pp_check(ctx
->key
, pp
, ctx
->nx
);
243 /* Keep the matching PTE informations */
246 ret
= check_prot(ctx
->prot
, rw
, type
);
249 LOG_MMU("PTE access granted !\n");
251 /* Access right violation */
252 LOG_MMU("PTE access rejected\n");
260 static inline int pte32_check(mmu_ctx_t
*ctx
, target_ulong pte0
,
261 target_ulong pte1
, int h
, int rw
, int type
)
263 return _pte_check(ctx
, 0, pte0
, pte1
, h
, rw
, type
);
266 #if defined(TARGET_PPC64)
267 static inline int pte64_check(mmu_ctx_t
*ctx
, target_ulong pte0
,
268 target_ulong pte1
, int h
, int rw
, int type
)
270 return _pte_check(ctx
, 1, pte0
, pte1
, h
, rw
, type
);
274 static inline int pte_update_flags(mmu_ctx_t
*ctx
, target_ulong
*pte1p
,
279 /* Update page flags */
280 if (!(*pte1p
& 0x00000100)) {
281 /* Update accessed flag */
282 *pte1p
|= 0x00000100;
285 if (!(*pte1p
& 0x00000080)) {
286 if (rw
== 1 && ret
== 0) {
287 /* Update changed flag */
288 *pte1p
|= 0x00000080;
291 /* Force page fault for first write access */
292 ctx
->prot
&= ~PAGE_WRITE
;
299 /* Software driven TLB helpers */
300 static inline int ppc6xx_tlb_getnum(CPUState
*env
, target_ulong eaddr
, int way
,
305 /* Select TLB num in a way from address */
306 nr
= (eaddr
>> TARGET_PAGE_BITS
) & (env
->tlb_per_way
- 1);
308 nr
+= env
->tlb_per_way
* way
;
309 /* 6xx have separate TLBs for instructions and data */
310 if (is_code
&& env
->id_tlbs
== 1)
316 static inline void ppc6xx_tlb_invalidate_all(CPUState
*env
)
321 //LOG_SWTLB("Invalidate all TLBs\n");
322 /* Invalidate all defined software TLB */
324 if (env
->id_tlbs
== 1)
326 for (nr
= 0; nr
< max
; nr
++) {
327 tlb
= &env
->tlb
.tlb6
[nr
];
328 pte_invalidate(&tlb
->pte0
);
333 static inline void __ppc6xx_tlb_invalidate_virt(CPUState
*env
,
335 int is_code
, int match_epn
)
337 #if !defined(FLUSH_ALL_TLBS)
341 /* Invalidate ITLB + DTLB, all ways */
342 for (way
= 0; way
< env
->nb_ways
; way
++) {
343 nr
= ppc6xx_tlb_getnum(env
, eaddr
, way
, is_code
);
344 tlb
= &env
->tlb
.tlb6
[nr
];
345 if (pte_is_valid(tlb
->pte0
) && (match_epn
== 0 || eaddr
== tlb
->EPN
)) {
346 LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx
"\n", nr
,
348 pte_invalidate(&tlb
->pte0
);
349 tlb_flush_page(env
, tlb
->EPN
);
353 /* XXX: PowerPC specification say this is valid as well */
354 ppc6xx_tlb_invalidate_all(env
);
358 static inline void ppc6xx_tlb_invalidate_virt(CPUState
*env
,
359 target_ulong eaddr
, int is_code
)
361 __ppc6xx_tlb_invalidate_virt(env
, eaddr
, is_code
, 0);
364 void ppc6xx_tlb_store (CPUState
*env
, target_ulong EPN
, int way
, int is_code
,
365 target_ulong pte0
, target_ulong pte1
)
370 nr
= ppc6xx_tlb_getnum(env
, EPN
, way
, is_code
);
371 tlb
= &env
->tlb
.tlb6
[nr
];
372 LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx
" PTE0 " TARGET_FMT_lx
373 " PTE1 " TARGET_FMT_lx
"\n", nr
, env
->nb_tlb
, EPN
, pte0
, pte1
);
374 /* Invalidate any pending reference in Qemu for this virtual address */
375 __ppc6xx_tlb_invalidate_virt(env
, EPN
, is_code
, 1);
379 /* Store last way for LRU mechanism */
383 static inline int ppc6xx_tlb_check(CPUState
*env
, mmu_ctx_t
*ctx
,
384 target_ulong eaddr
, int rw
, int access_type
)
391 ret
= -1; /* No TLB found */
392 for (way
= 0; way
< env
->nb_ways
; way
++) {
393 nr
= ppc6xx_tlb_getnum(env
, eaddr
, way
,
394 access_type
== ACCESS_CODE
? 1 : 0);
395 tlb
= &env
->tlb
.tlb6
[nr
];
396 /* This test "emulates" the PTE index match for hardware TLBs */
397 if ((eaddr
& TARGET_PAGE_MASK
) != tlb
->EPN
) {
398 LOG_SWTLB("TLB %d/%d %s [" TARGET_FMT_lx
" " TARGET_FMT_lx
399 "] <> " TARGET_FMT_lx
"\n", nr
, env
->nb_tlb
,
400 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
401 tlb
->EPN
, tlb
->EPN
+ TARGET_PAGE_SIZE
, eaddr
);
404 LOG_SWTLB("TLB %d/%d %s " TARGET_FMT_lx
" <> " TARGET_FMT_lx
" "
405 TARGET_FMT_lx
" %c %c\n", nr
, env
->nb_tlb
,
406 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
407 tlb
->EPN
, eaddr
, tlb
->pte1
,
408 rw
? 'S' : 'L', access_type
== ACCESS_CODE
? 'I' : 'D');
409 switch (pte32_check(ctx
, tlb
->pte0
, tlb
->pte1
, 0, rw
, access_type
)) {
411 /* TLB inconsistency */
414 /* Access violation */
424 /* XXX: we should go on looping to check all TLBs consistency
425 * but we can speed-up the whole thing as the
426 * result would be undefined if TLBs are not consistent.
435 LOG_SWTLB("found TLB at addr " TARGET_FMT_plx
" prot=%01x ret=%d\n",
436 ctx
->raddr
& TARGET_PAGE_MASK
, ctx
->prot
, ret
);
437 /* Update page flags */
438 pte_update_flags(ctx
, &env
->tlb
.tlb6
[best
].pte1
, ret
, rw
);
444 /* Perform BAT hit & translation */
445 static inline void bat_size_prot(CPUState
*env
, target_ulong
*blp
, int *validp
,
446 int *protp
, target_ulong
*BATu
,
452 bl
= (*BATu
& 0x00001FFC) << 15;
455 if (((msr_pr
== 0) && (*BATu
& 0x00000002)) ||
456 ((msr_pr
!= 0) && (*BATu
& 0x00000001))) {
458 pp
= *BATl
& 0x00000003;
460 prot
= PAGE_READ
| PAGE_EXEC
;
470 static inline void bat_601_size_prot(CPUState
*env
, target_ulong
*blp
,
471 int *validp
, int *protp
,
472 target_ulong
*BATu
, target_ulong
*BATl
)
475 int key
, pp
, valid
, prot
;
477 bl
= (*BATl
& 0x0000003F) << 17;
478 LOG_BATS("b %02x ==> bl " TARGET_FMT_lx
" msk " TARGET_FMT_lx
"\n",
479 (uint8_t)(*BATl
& 0x0000003F), bl
, ~bl
);
481 valid
= (*BATl
>> 6) & 1;
483 pp
= *BATu
& 0x00000003;
485 key
= (*BATu
>> 3) & 1;
487 key
= (*BATu
>> 2) & 1;
488 prot
= pp_check(key
, pp
, 0);
495 static inline int get_bat(CPUState
*env
, mmu_ctx_t
*ctx
, target_ulong
virtual,
498 target_ulong
*BATlt
, *BATut
, *BATu
, *BATl
;
499 target_ulong BEPIl
, BEPIu
, bl
;
503 LOG_BATS("%s: %cBAT v " TARGET_FMT_lx
"\n", __func__
,
504 type
== ACCESS_CODE
? 'I' : 'D', virtual);
507 BATlt
= env
->IBAT
[1];
508 BATut
= env
->IBAT
[0];
511 BATlt
= env
->DBAT
[1];
512 BATut
= env
->DBAT
[0];
515 for (i
= 0; i
< env
->nb_BATs
; i
++) {
518 BEPIu
= *BATu
& 0xF0000000;
519 BEPIl
= *BATu
& 0x0FFE0000;
520 if (unlikely(env
->mmu_model
== POWERPC_MMU_601
)) {
521 bat_601_size_prot(env
, &bl
, &valid
, &prot
, BATu
, BATl
);
523 bat_size_prot(env
, &bl
, &valid
, &prot
, BATu
, BATl
);
525 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx
" BATu " TARGET_FMT_lx
526 " BATl " TARGET_FMT_lx
"\n", __func__
,
527 type
== ACCESS_CODE
? 'I' : 'D', i
, virtual, *BATu
, *BATl
);
528 if ((virtual & 0xF0000000) == BEPIu
&&
529 ((virtual & 0x0FFE0000) & ~bl
) == BEPIl
) {
532 /* Get physical address */
533 ctx
->raddr
= (*BATl
& 0xF0000000) |
534 ((virtual & 0x0FFE0000 & bl
) | (*BATl
& 0x0FFE0000)) |
535 (virtual & 0x0001F000);
536 /* Compute access rights */
538 ret
= check_prot(ctx
->prot
, rw
, type
);
540 LOG_BATS("BAT %d match: r " TARGET_FMT_plx
" prot=%c%c\n",
541 i
, ctx
->raddr
, ctx
->prot
& PAGE_READ
? 'R' : '-',
542 ctx
->prot
& PAGE_WRITE
? 'W' : '-');
548 #if defined(DEBUG_BATS)
549 if (qemu_log_enabled()) {
550 LOG_BATS("no BAT match for " TARGET_FMT_lx
":\n", virtual);
551 for (i
= 0; i
< 4; i
++) {
554 BEPIu
= *BATu
& 0xF0000000;
555 BEPIl
= *BATu
& 0x0FFE0000;
556 bl
= (*BATu
& 0x00001FFC) << 15;
557 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx
" BATu " TARGET_FMT_lx
558 " BATl " TARGET_FMT_lx
"\n\t" TARGET_FMT_lx
" "
559 TARGET_FMT_lx
" " TARGET_FMT_lx
"\n",
560 __func__
, type
== ACCESS_CODE
? 'I' : 'D', i
, virtual,
561 *BATu
, *BATl
, BEPIu
, BEPIl
, bl
);
570 static inline target_phys_addr_t
get_pteg_offset(CPUState
*env
,
571 target_phys_addr_t hash
,
574 return (hash
* pte_size
* 8) & env
->htab_mask
;
577 /* PTE table lookup */
578 static inline int _find_pte(CPUState
*env
, mmu_ctx_t
*ctx
, int is_64b
, int h
,
579 int rw
, int type
, int target_page_bits
)
581 target_phys_addr_t pteg_off
;
582 target_ulong pte0
, pte1
;
586 ret
= -1; /* No entry found */
587 pteg_off
= get_pteg_offset(env
, ctx
->hash
[h
],
588 is_64b
? HASH_PTE_SIZE_64
: HASH_PTE_SIZE_32
);
589 for (i
= 0; i
< 8; i
++) {
590 #if defined(TARGET_PPC64)
592 if (env
->external_htab
) {
593 pte0
= ldq_p(env
->external_htab
+ pteg_off
+ (i
* 16));
594 pte1
= ldq_p(env
->external_htab
+ pteg_off
+ (i
* 16) + 8);
596 pte0
= ldq_phys(env
->htab_base
+ pteg_off
+ (i
* 16));
597 pte1
= ldq_phys(env
->htab_base
+ pteg_off
+ (i
* 16) + 8);
600 /* We have a TLB that saves 4K pages, so let's
601 * split a huge page to 4k chunks */
602 if (target_page_bits
!= TARGET_PAGE_BITS
)
603 pte1
|= (ctx
->eaddr
& (( 1 << target_page_bits
) - 1))
606 r
= pte64_check(ctx
, pte0
, pte1
, h
, rw
, type
);
607 LOG_MMU("Load pte from " TARGET_FMT_lx
" => " TARGET_FMT_lx
" "
608 TARGET_FMT_lx
" %d %d %d " TARGET_FMT_lx
"\n",
609 pteg_off
+ (i
* 16), pte0
, pte1
, (int)(pte0
& 1), h
,
610 (int)((pte0
>> 1) & 1), ctx
->ptem
);
614 if (env
->external_htab
) {
615 pte0
= ldl_p(env
->external_htab
+ pteg_off
+ (i
* 8));
616 pte1
= ldl_p(env
->external_htab
+ pteg_off
+ (i
* 8) + 4);
618 pte0
= ldl_phys(env
->htab_base
+ pteg_off
+ (i
* 8));
619 pte1
= ldl_phys(env
->htab_base
+ pteg_off
+ (i
* 8) + 4);
621 r
= pte32_check(ctx
, pte0
, pte1
, h
, rw
, type
);
622 LOG_MMU("Load pte from " TARGET_FMT_lx
" => " TARGET_FMT_lx
" "
623 TARGET_FMT_lx
" %d %d %d " TARGET_FMT_lx
"\n",
624 pteg_off
+ (i
* 8), pte0
, pte1
, (int)(pte0
>> 31), h
,
625 (int)((pte0
>> 6) & 1), ctx
->ptem
);
629 /* PTE inconsistency */
632 /* Access violation */
642 /* XXX: we should go on looping to check all PTEs consistency
643 * but if we can speed-up the whole thing as the
644 * result would be undefined if PTEs are not consistent.
653 LOG_MMU("found PTE at addr " TARGET_FMT_lx
" prot=%01x ret=%d\n",
654 ctx
->raddr
, ctx
->prot
, ret
);
655 /* Update page flags */
657 if (pte_update_flags(ctx
, &pte1
, ret
, rw
) == 1) {
658 #if defined(TARGET_PPC64)
660 if (env
->external_htab
) {
661 stq_p(env
->external_htab
+ pteg_off
+ (good
* 16) + 8,
664 stq_phys_notdirty(env
->htab_base
+ pteg_off
+
665 (good
* 16) + 8, pte1
);
670 if (env
->external_htab
) {
671 stl_p(env
->external_htab
+ pteg_off
+ (good
* 8) + 4,
674 stl_phys_notdirty(env
->htab_base
+ pteg_off
+
675 (good
* 8) + 4, pte1
);
684 static inline int find_pte(CPUState
*env
, mmu_ctx_t
*ctx
, int h
, int rw
,
685 int type
, int target_page_bits
)
687 #if defined(TARGET_PPC64)
688 if (env
->mmu_model
& POWERPC_MMU_64
)
689 return _find_pte(env
, ctx
, 1, h
, rw
, type
, target_page_bits
);
692 return _find_pte(env
, ctx
, 0, h
, rw
, type
, target_page_bits
);
695 #if defined(TARGET_PPC64)
696 static inline ppc_slb_t
*slb_lookup(CPUPPCState
*env
, target_ulong eaddr
)
698 uint64_t esid_256M
, esid_1T
;
701 LOG_SLB("%s: eaddr " TARGET_FMT_lx
"\n", __func__
, eaddr
);
703 esid_256M
= (eaddr
& SEGMENT_MASK_256M
) | SLB_ESID_V
;
704 esid_1T
= (eaddr
& SEGMENT_MASK_1T
) | SLB_ESID_V
;
706 for (n
= 0; n
< env
->slb_nr
; n
++) {
707 ppc_slb_t
*slb
= &env
->slb
[n
];
709 LOG_SLB("%s: slot %d %016" PRIx64
" %016"
710 PRIx64
"\n", __func__
, n
, slb
->esid
, slb
->vsid
);
711 /* We check for 1T matches on all MMUs here - if the MMU
712 * doesn't have 1T segment support, we will have prevented 1T
713 * entries from being inserted in the slbmte code. */
714 if (((slb
->esid
== esid_256M
) &&
715 ((slb
->vsid
& SLB_VSID_B
) == SLB_VSID_B_256M
))
716 || ((slb
->esid
== esid_1T
) &&
717 ((slb
->vsid
& SLB_VSID_B
) == SLB_VSID_B_1T
))) {
725 void ppc_slb_invalidate_all (CPUPPCState
*env
)
727 int n
, do_invalidate
;
730 /* XXX: Warning: slbia never invalidates the first segment */
731 for (n
= 1; n
< env
->slb_nr
; n
++) {
732 ppc_slb_t
*slb
= &env
->slb
[n
];
734 if (slb
->esid
& SLB_ESID_V
) {
735 slb
->esid
&= ~SLB_ESID_V
;
736 /* XXX: given the fact that segment size is 256 MB or 1TB,
737 * and we still don't have a tlb_flush_mask(env, n, mask)
738 * in Qemu, we just invalidate all TLBs
747 void ppc_slb_invalidate_one (CPUPPCState
*env
, uint64_t T0
)
751 slb
= slb_lookup(env
, T0
);
756 if (slb
->esid
& SLB_ESID_V
) {
757 slb
->esid
&= ~SLB_ESID_V
;
759 /* XXX: given the fact that segment size is 256 MB or 1TB,
760 * and we still don't have a tlb_flush_mask(env, n, mask)
761 * in Qemu, we just invalidate all TLBs
767 int ppc_store_slb (CPUPPCState
*env
, target_ulong rb
, target_ulong rs
)
769 int slot
= rb
& 0xfff;
770 ppc_slb_t
*slb
= &env
->slb
[slot
];
772 if (rb
& (0x1000 - env
->slb_nr
)) {
773 return -1; /* Reserved bits set or slot too high */
775 if (rs
& (SLB_VSID_B
& ~SLB_VSID_B_1T
)) {
776 return -1; /* Bad segment size */
778 if ((rs
& SLB_VSID_B
) && !(env
->mmu_model
& POWERPC_MMU_1TSEG
)) {
779 return -1; /* 1T segment on MMU that doesn't support it */
782 /* Mask out the slot number as we store the entry */
783 slb
->esid
= rb
& (SLB_ESID_ESID
| SLB_ESID_V
);
786 LOG_SLB("%s: %d " TARGET_FMT_lx
" - " TARGET_FMT_lx
" => %016" PRIx64
787 " %016" PRIx64
"\n", __func__
, slot
, rb
, rs
,
788 slb
->esid
, slb
->vsid
);
793 int ppc_load_slb_esid (CPUPPCState
*env
, target_ulong rb
, target_ulong
*rt
)
795 int slot
= rb
& 0xfff;
796 ppc_slb_t
*slb
= &env
->slb
[slot
];
798 if (slot
>= env
->slb_nr
) {
806 int ppc_load_slb_vsid (CPUPPCState
*env
, target_ulong rb
, target_ulong
*rt
)
808 int slot
= rb
& 0xfff;
809 ppc_slb_t
*slb
= &env
->slb
[slot
];
811 if (slot
>= env
->slb_nr
) {
818 #endif /* defined(TARGET_PPC64) */
820 /* Perform segment based translation */
821 static inline int get_segment(CPUState
*env
, mmu_ctx_t
*ctx
,
822 target_ulong eaddr
, int rw
, int type
)
824 target_phys_addr_t hash
;
826 int ds
, pr
, target_page_bits
;
831 #if defined(TARGET_PPC64)
832 if (env
->mmu_model
& POWERPC_MMU_64
) {
834 target_ulong pageaddr
;
837 LOG_MMU("Check SLBs\n");
838 slb
= slb_lookup(env
, eaddr
);
843 if (slb
->vsid
& SLB_VSID_B
) {
844 vsid
= (slb
->vsid
& SLB_VSID_VSID
) >> SLB_VSID_SHIFT_1T
;
847 vsid
= (slb
->vsid
& SLB_VSID_VSID
) >> SLB_VSID_SHIFT
;
851 target_page_bits
= (slb
->vsid
& SLB_VSID_L
)
852 ? TARGET_PAGE_BITS_16M
: TARGET_PAGE_BITS
;
853 ctx
->key
= !!(pr
? (slb
->vsid
& SLB_VSID_KP
)
854 : (slb
->vsid
& SLB_VSID_KS
));
856 ctx
->nx
= !!(slb
->vsid
& SLB_VSID_N
);
858 pageaddr
= eaddr
& ((1ULL << segment_bits
)
859 - (1ULL << target_page_bits
));
860 if (slb
->vsid
& SLB_VSID_B
) {
861 hash
= vsid
^ (vsid
<< 25) ^ (pageaddr
>> target_page_bits
);
863 hash
= vsid
^ (pageaddr
>> target_page_bits
);
865 /* Only 5 bits of the page index are used in the AVPN */
866 ctx
->ptem
= (slb
->vsid
& SLB_VSID_PTEM
) |
867 ((pageaddr
>> 16) & ((1ULL << segment_bits
) - 0x80));
869 #endif /* defined(TARGET_PPC64) */
871 target_ulong sr
, pgidx
;
873 sr
= env
->sr
[eaddr
>> 28];
874 ctx
->key
= (((sr
& 0x20000000) && (pr
!= 0)) ||
875 ((sr
& 0x40000000) && (pr
== 0))) ? 1 : 0;
876 ds
= sr
& 0x80000000 ? 1 : 0;
877 ctx
->nx
= sr
& 0x10000000 ? 1 : 0;
878 vsid
= sr
& 0x00FFFFFF;
879 target_page_bits
= TARGET_PAGE_BITS
;
880 LOG_MMU("Check segment v=" TARGET_FMT_lx
" %d " TARGET_FMT_lx
" nip="
881 TARGET_FMT_lx
" lr=" TARGET_FMT_lx
882 " ir=%d dr=%d pr=%d %d t=%d\n",
883 eaddr
, (int)(eaddr
>> 28), sr
, env
->nip
, env
->lr
, (int)msr_ir
,
884 (int)msr_dr
, pr
!= 0 ? 1 : 0, rw
, type
);
885 pgidx
= (eaddr
& ~SEGMENT_MASK_256M
) >> target_page_bits
;
887 ctx
->ptem
= (vsid
<< 7) | (pgidx
>> 10);
889 LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx
"\n",
890 ctx
->key
, ds
, ctx
->nx
, vsid
);
893 /* Check if instruction fetch is allowed, if needed */
894 if (type
!= ACCESS_CODE
|| ctx
->nx
== 0) {
895 /* Page address translation */
896 LOG_MMU("htab_base " TARGET_FMT_plx
" htab_mask " TARGET_FMT_plx
897 " hash " TARGET_FMT_plx
"\n",
898 env
->htab_base
, env
->htab_mask
, hash
);
900 ctx
->hash
[1] = ~hash
;
902 /* Initialize real address with an invalid value */
903 ctx
->raddr
= (target_phys_addr_t
)-1ULL;
904 if (unlikely(env
->mmu_model
== POWERPC_MMU_SOFT_6xx
||
905 env
->mmu_model
== POWERPC_MMU_SOFT_74xx
)) {
906 /* Software TLB search */
907 ret
= ppc6xx_tlb_check(env
, ctx
, eaddr
, rw
, type
);
909 LOG_MMU("0 htab=" TARGET_FMT_plx
"/" TARGET_FMT_plx
910 " vsid=" TARGET_FMT_lx
" ptem=" TARGET_FMT_lx
911 " hash=" TARGET_FMT_plx
"\n",
912 env
->htab_base
, env
->htab_mask
, vsid
, ctx
->ptem
,
914 /* Primary table lookup */
915 ret
= find_pte(env
, ctx
, 0, rw
, type
, target_page_bits
);
917 /* Secondary table lookup */
918 if (eaddr
!= 0xEFFFFFFF)
919 LOG_MMU("1 htab=" TARGET_FMT_plx
"/" TARGET_FMT_plx
920 " vsid=" TARGET_FMT_lx
" api=" TARGET_FMT_lx
921 " hash=" TARGET_FMT_plx
"\n", env
->htab_base
,
922 env
->htab_mask
, vsid
, ctx
->ptem
, ctx
->hash
[1]);
923 ret2
= find_pte(env
, ctx
, 1, rw
, type
,
929 #if defined (DUMP_PAGE_TABLES)
930 if (qemu_log_enabled()) {
931 target_phys_addr_t curaddr
;
932 uint32_t a0
, a1
, a2
, a3
;
933 qemu_log("Page table: " TARGET_FMT_plx
" len " TARGET_FMT_plx
934 "\n", sdr
, mask
+ 0x80);
935 for (curaddr
= sdr
; curaddr
< (sdr
+ mask
+ 0x80);
937 a0
= ldl_phys(curaddr
);
938 a1
= ldl_phys(curaddr
+ 4);
939 a2
= ldl_phys(curaddr
+ 8);
940 a3
= ldl_phys(curaddr
+ 12);
941 if (a0
!= 0 || a1
!= 0 || a2
!= 0 || a3
!= 0) {
942 qemu_log(TARGET_FMT_plx
": %08x %08x %08x %08x\n",
943 curaddr
, a0
, a1
, a2
, a3
);
949 LOG_MMU("No access allowed\n");
954 LOG_MMU("direct store...\n");
955 /* Direct-store segment : absolutely *BUGGY* for now */
957 /* Direct-store implies a 32-bit MMU.
958 * Check the Segment Register's bus unit ID (BUID).
960 sr
= env
->sr
[eaddr
>> 28];
961 if ((sr
& 0x1FF00000) >> 20 == 0x07f) {
962 /* Memory-forced I/O controller interface access */
963 /* If T=1 and BUID=x'07F', the 601 performs a memory access
964 * to SR[28-31] LA[4-31], bypassing all protection mechanisms.
966 ctx
->raddr
= ((sr
& 0xF) << 28) | (eaddr
& 0x0FFFFFFF);
967 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
973 /* Integer load/store : only access allowed */
976 /* No code fetch is allowed in direct-store areas */
979 /* Floating point load/store */
982 /* lwarx, ldarx or srwcx. */
985 /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
986 /* Should make the instruction do no-op.
987 * As it already do no-op, it's quite easy :-)
995 qemu_log("ERROR: instruction should not need "
996 "address translation\n");
999 if ((rw
== 1 || ctx
->key
!= 1) && (rw
== 0 || ctx
->key
!= 0)) {
1010 /* Generic TLB check function for embedded PowerPC implementations */
1011 int ppcemb_tlb_check(CPUState
*env
, ppcemb_tlb_t
*tlb
,
1012 target_phys_addr_t
*raddrp
,
1013 target_ulong address
, uint32_t pid
, int ext
,
1018 /* Check valid flag */
1019 if (!(tlb
->prot
& PAGE_VALID
)) {
1022 mask
= ~(tlb
->size
- 1);
1023 LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx
" PID %u <=> " TARGET_FMT_lx
1024 " " TARGET_FMT_lx
" %u %x\n", __func__
, i
, address
, pid
, tlb
->EPN
,
1025 mask
, (uint32_t)tlb
->PID
, tlb
->prot
);
1027 if (tlb
->PID
!= 0 && tlb
->PID
!= pid
)
1029 /* Check effective address */
1030 if ((address
& mask
) != tlb
->EPN
)
1032 *raddrp
= (tlb
->RPN
& mask
) | (address
& ~mask
);
1033 #if (TARGET_PHYS_ADDR_BITS >= 36)
1035 /* Extend the physical address to 36 bits */
1036 *raddrp
|= (target_phys_addr_t
)(tlb
->RPN
& 0xF) << 32;
1043 /* Generic TLB search function for PowerPC embedded implementations */
1044 int ppcemb_tlb_search (CPUPPCState
*env
, target_ulong address
, uint32_t pid
)
1047 target_phys_addr_t raddr
;
1050 /* Default return value is no match */
1052 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1053 tlb
= &env
->tlb
.tlbe
[i
];
1054 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
, pid
, 0, i
) == 0) {
1063 /* Helpers specific to PowerPC 40x implementations */
1064 static inline void ppc4xx_tlb_invalidate_all(CPUState
*env
)
1069 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1070 tlb
= &env
->tlb
.tlbe
[i
];
1071 tlb
->prot
&= ~PAGE_VALID
;
1076 static inline void ppc4xx_tlb_invalidate_virt(CPUState
*env
,
1077 target_ulong eaddr
, uint32_t pid
)
1079 #if !defined(FLUSH_ALL_TLBS)
1081 target_phys_addr_t raddr
;
1082 target_ulong page
, end
;
1085 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1086 tlb
= &env
->tlb
.tlbe
[i
];
1087 if (ppcemb_tlb_check(env
, tlb
, &raddr
, eaddr
, pid
, 0, i
) == 0) {
1088 end
= tlb
->EPN
+ tlb
->size
;
1089 for (page
= tlb
->EPN
; page
< end
; page
+= TARGET_PAGE_SIZE
)
1090 tlb_flush_page(env
, page
);
1091 tlb
->prot
&= ~PAGE_VALID
;
1096 ppc4xx_tlb_invalidate_all(env
);
1100 static int mmu40x_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1101 target_ulong address
, int rw
, int access_type
)
1104 target_phys_addr_t raddr
;
1105 int i
, ret
, zsel
, zpr
, pr
;
1108 raddr
= (target_phys_addr_t
)-1ULL;
1110 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1111 tlb
= &env
->tlb
.tlbe
[i
];
1112 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
,
1113 env
->spr
[SPR_40x_PID
], 0, i
) < 0)
1115 zsel
= (tlb
->attr
>> 4) & 0xF;
1116 zpr
= (env
->spr
[SPR_40x_ZPR
] >> (30 - (2 * zsel
))) & 0x3;
1117 LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1118 __func__
, i
, zsel
, zpr
, rw
, tlb
->attr
);
1119 /* Check execute enable bit */
1126 /* All accesses granted */
1127 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
1132 /* Raise Zone protection fault. */
1133 env
->spr
[SPR_40x_ESR
] = 1 << 22;
1141 /* Check from TLB entry */
1142 ctx
->prot
= tlb
->prot
;
1143 ret
= check_prot(ctx
->prot
, rw
, access_type
);
1145 env
->spr
[SPR_40x_ESR
] = 0;
1150 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1151 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1156 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1157 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1162 void store_40x_sler (CPUPPCState
*env
, uint32_t val
)
1164 /* XXX: TO BE FIXED */
1165 if (val
!= 0x00000000) {
1166 cpu_abort(env
, "Little-endian regions are not supported by now\n");
1168 env
->spr
[SPR_405_SLER
] = val
;
1171 static inline int mmubooke_check_tlb (CPUState
*env
, ppcemb_tlb_t
*tlb
,
1172 target_phys_addr_t
*raddr
, int *prot
,
1173 target_ulong address
, int rw
,
1174 int access_type
, int i
)
1178 if (ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1179 env
->spr
[SPR_BOOKE_PID
],
1180 !env
->nb_pids
, i
) >= 0) {
1184 if (env
->spr
[SPR_BOOKE_PID1
] &&
1185 ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1186 env
->spr
[SPR_BOOKE_PID1
], 0, i
) >= 0) {
1190 if (env
->spr
[SPR_BOOKE_PID2
] &&
1191 ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1192 env
->spr
[SPR_BOOKE_PID2
], 0, i
) >= 0) {
1196 LOG_SWTLB("%s: TLB entry not found\n", __func__
);
1202 _prot
= tlb
->prot
& 0xF;
1204 _prot
= (tlb
->prot
>> 4) & 0xF;
1207 /* Check the address space */
1208 if (access_type
== ACCESS_CODE
) {
1209 if (msr_ir
!= (tlb
->attr
& 1)) {
1210 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1215 if (_prot
& PAGE_EXEC
) {
1216 LOG_SWTLB("%s: good TLB!\n", __func__
);
1220 LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__
, _prot
);
1223 if (msr_dr
!= (tlb
->attr
& 1)) {
1224 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1229 if ((!rw
&& _prot
& PAGE_READ
) || (rw
&& (_prot
& PAGE_WRITE
))) {
1230 LOG_SWTLB("%s: found TLB!\n", __func__
);
1234 LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__
, _prot
);
1241 static int mmubooke_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1242 target_ulong address
, int rw
,
1246 target_phys_addr_t raddr
;
1250 raddr
= (target_phys_addr_t
)-1ULL;
1251 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1252 tlb
= &env
->tlb
.tlbe
[i
];
1253 ret
= mmubooke_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
, rw
,
1262 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1263 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1266 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1267 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1273 void booke206_flush_tlb(CPUState
*env
, int flags
, const int check_iprot
)
1277 ppcmas_tlb_t
*tlb
= env
->tlb
.tlbm
;
1279 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1280 if (flags
& (1 << i
)) {
1281 tlb_size
= booke206_tlb_size(env
, i
);
1282 for (j
= 0; j
< tlb_size
; j
++) {
1283 if (!check_iprot
|| !(tlb
[j
].mas1
& MAS1_IPROT
)) {
1284 tlb
[j
].mas1
&= ~MAS1_VALID
;
1288 tlb
+= booke206_tlb_size(env
, i
);
1294 target_phys_addr_t
booke206_tlb_to_page_size(CPUState
*env
, ppcmas_tlb_t
*tlb
)
1297 int tlbn
= booke206_tlbm_to_tlbn(env
, tlb
);
1300 tlbncfg
= env
->spr
[SPR_BOOKE_TLB0CFG
+ tlbn
];
1302 if (tlbncfg
& TLBnCFG_AVAIL
) {
1303 tlbm_size
= (tlb
->mas1
& MAS1_TSIZE_MASK
) >> MAS1_TSIZE_SHIFT
;
1305 tlbm_size
= (tlbncfg
& TLBnCFG_MINSIZE
) >> TLBnCFG_MINSIZE_SHIFT
;
1309 return 1024ULL << tlbm_size
;
1312 /* TLB check function for MAS based SoftTLBs */
1313 int ppcmas_tlb_check(CPUState
*env
, ppcmas_tlb_t
*tlb
,
1314 target_phys_addr_t
*raddrp
,
1315 target_ulong address
, uint32_t pid
)
1320 /* Check valid flag */
1321 if (!(tlb
->mas1
& MAS1_VALID
)) {
1325 mask
= ~(booke206_tlb_to_page_size(env
, tlb
) - 1);
1326 LOG_SWTLB("%s: TLB ADDR=0x" TARGET_FMT_lx
" PID=0x%x MAS1=0x%x MAS2=0x%"
1327 PRIx64
" mask=0x" TARGET_FMT_lx
" MAS7_3=0x%" PRIx64
" MAS8=%x\n",
1328 __func__
, address
, pid
, tlb
->mas1
, tlb
->mas2
, mask
, tlb
->mas7_3
,
1332 tlb_pid
= (tlb
->mas1
& MAS1_TID_MASK
) >> MAS1_TID_SHIFT
;
1333 if (tlb_pid
!= 0 && tlb_pid
!= pid
) {
1337 /* Check effective address */
1338 if ((address
& mask
) != (tlb
->mas2
& MAS2_EPN_MASK
)) {
1341 *raddrp
= (tlb
->mas7_3
& mask
) | (address
& ~mask
);
1346 static int mmubooke206_check_tlb(CPUState
*env
, ppcmas_tlb_t
*tlb
,
1347 target_phys_addr_t
*raddr
, int *prot
,
1348 target_ulong address
, int rw
,
1354 if (ppcmas_tlb_check(env
, tlb
, raddr
, address
,
1355 env
->spr
[SPR_BOOKE_PID
]) >= 0) {
1359 if (env
->spr
[SPR_BOOKE_PID1
] &&
1360 ppcmas_tlb_check(env
, tlb
, raddr
, address
,
1361 env
->spr
[SPR_BOOKE_PID1
]) >= 0) {
1365 if (env
->spr
[SPR_BOOKE_PID2
] &&
1366 ppcmas_tlb_check(env
, tlb
, raddr
, address
,
1367 env
->spr
[SPR_BOOKE_PID2
]) >= 0) {
1371 LOG_SWTLB("%s: TLB entry not found\n", __func__
);
1377 if (tlb
->mas7_3
& MAS3_UR
) {
1380 if (tlb
->mas7_3
& MAS3_UW
) {
1381 _prot
|= PAGE_WRITE
;
1383 if (tlb
->mas7_3
& MAS3_UX
) {
1387 if (tlb
->mas7_3
& MAS3_SR
) {
1390 if (tlb
->mas7_3
& MAS3_SW
) {
1391 _prot
|= PAGE_WRITE
;
1393 if (tlb
->mas7_3
& MAS3_SX
) {
1398 /* Check the address space and permissions */
1399 if (access_type
== ACCESS_CODE
) {
1400 if (msr_ir
!= ((tlb
->mas1
& MAS1_TS
) >> MAS1_TS_SHIFT
)) {
1401 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1406 if (_prot
& PAGE_EXEC
) {
1407 LOG_SWTLB("%s: good TLB!\n", __func__
);
1411 LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__
, _prot
);
1414 if (msr_dr
!= ((tlb
->mas1
& MAS1_TS
) >> MAS1_TS_SHIFT
)) {
1415 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1420 if ((!rw
&& _prot
& PAGE_READ
) || (rw
&& (_prot
& PAGE_WRITE
))) {
1421 LOG_SWTLB("%s: found TLB!\n", __func__
);
1425 LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__
, _prot
);
1432 static int mmubooke206_get_physical_address(CPUState
*env
, mmu_ctx_t
*ctx
,
1433 target_ulong address
, int rw
,
1437 target_phys_addr_t raddr
;
1441 raddr
= (target_phys_addr_t
)-1ULL;
1443 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1444 int ways
= booke206_tlb_ways(env
, i
);
1446 for (j
= 0; j
< ways
; j
++) {
1447 tlb
= booke206_get_tlbm(env
, i
, address
, j
);
1448 ret
= mmubooke206_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
,
1460 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1461 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1464 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1465 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1471 static const char *book3e_tsize_to_str
[32] = {
1472 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
1473 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M",
1474 "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G",
1478 static void mmubooke206_dump_one_tlb(FILE *f
, fprintf_function cpu_fprintf
,
1479 CPUState
*env
, int tlbn
, int offset
,
1482 ppcmas_tlb_t
*entry
;
1485 cpu_fprintf(f
, "\nTLB%d:\n", tlbn
);
1486 cpu_fprintf(f
, "Effective Physical Size TID TS SRWX URWX WIMGE U0123\n");
1488 entry
= &env
->tlb
.tlbm
[offset
];
1489 for (i
= 0; i
< tlbsize
; i
++, entry
++) {
1490 target_phys_addr_t ea
, pa
, size
;
1493 if (!(entry
->mas1
& MAS1_VALID
)) {
1497 tsize
= (entry
->mas1
& MAS1_TSIZE_MASK
) >> MAS1_TSIZE_SHIFT
;
1498 size
= 1024ULL << tsize
;
1499 ea
= entry
->mas2
& ~(size
- 1);
1500 pa
= entry
->mas7_3
& ~(size
- 1);
1502 cpu_fprintf(f
, "0x%016" PRIx64
" 0x%016" PRIx64
" %4s %-5u %1u S%c%c%c U%c%c%c %c%c%c%c%c U%c%c%c%c\n",
1503 (uint64_t)ea
, (uint64_t)pa
,
1504 book3e_tsize_to_str
[tsize
],
1505 (entry
->mas1
& MAS1_TID_MASK
) >> MAS1_TID_SHIFT
,
1506 (entry
->mas1
& MAS1_TS
) >> MAS1_TS_SHIFT
,
1507 entry
->mas7_3
& MAS3_SR
? 'R' : '-',
1508 entry
->mas7_3
& MAS3_SW
? 'W' : '-',
1509 entry
->mas7_3
& MAS3_SX
? 'X' : '-',
1510 entry
->mas7_3
& MAS3_UR
? 'R' : '-',
1511 entry
->mas7_3
& MAS3_UW
? 'W' : '-',
1512 entry
->mas7_3
& MAS3_UX
? 'X' : '-',
1513 entry
->mas2
& MAS2_W
? 'W' : '-',
1514 entry
->mas2
& MAS2_I
? 'I' : '-',
1515 entry
->mas2
& MAS2_M
? 'M' : '-',
1516 entry
->mas2
& MAS2_G
? 'G' : '-',
1517 entry
->mas2
& MAS2_E
? 'E' : '-',
1518 entry
->mas7_3
& MAS3_U0
? '0' : '-',
1519 entry
->mas7_3
& MAS3_U1
? '1' : '-',
1520 entry
->mas7_3
& MAS3_U2
? '2' : '-',
1521 entry
->mas7_3
& MAS3_U3
? '3' : '-');
1525 static void mmubooke206_dump_mmu(FILE *f
, fprintf_function cpu_fprintf
,
1531 if (kvm_enabled() && !env
->kvm_sw_tlb
) {
1532 cpu_fprintf(f
, "Cannot access KVM TLB\n");
1536 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1537 int size
= booke206_tlb_size(env
, i
);
1543 mmubooke206_dump_one_tlb(f
, cpu_fprintf
, env
, i
, offset
, size
);
1548 void dump_mmu(FILE *f
, fprintf_function cpu_fprintf
, CPUState
*env
)
1550 switch (env
->mmu_model
) {
1551 case POWERPC_MMU_BOOKE206
:
1552 mmubooke206_dump_mmu(f
, cpu_fprintf
, env
);
1555 cpu_fprintf(f
, "%s: unimplemented\n", __func__
);
1559 static inline int check_physical(CPUState
*env
, mmu_ctx_t
*ctx
,
1560 target_ulong eaddr
, int rw
)
1565 ctx
->prot
= PAGE_READ
| PAGE_EXEC
;
1567 switch (env
->mmu_model
) {
1568 case POWERPC_MMU_32B
:
1569 case POWERPC_MMU_601
:
1570 case POWERPC_MMU_SOFT_6xx
:
1571 case POWERPC_MMU_SOFT_74xx
:
1572 case POWERPC_MMU_SOFT_4xx
:
1573 case POWERPC_MMU_REAL
:
1574 case POWERPC_MMU_BOOKE
:
1575 ctx
->prot
|= PAGE_WRITE
;
1577 #if defined(TARGET_PPC64)
1578 case POWERPC_MMU_620
:
1579 case POWERPC_MMU_64B
:
1580 case POWERPC_MMU_2_06
:
1581 /* Real address are 60 bits long */
1582 ctx
->raddr
&= 0x0FFFFFFFFFFFFFFFULL
;
1583 ctx
->prot
|= PAGE_WRITE
;
1586 case POWERPC_MMU_SOFT_4xx_Z
:
1587 if (unlikely(msr_pe
!= 0)) {
1588 /* 403 family add some particular protections,
1589 * using PBL/PBU registers for accesses with no translation.
1592 /* Check PLB validity */
1593 (env
->pb
[0] < env
->pb
[1] &&
1594 /* and address in plb area */
1595 eaddr
>= env
->pb
[0] && eaddr
< env
->pb
[1]) ||
1596 (env
->pb
[2] < env
->pb
[3] &&
1597 eaddr
>= env
->pb
[2] && eaddr
< env
->pb
[3]) ? 1 : 0;
1598 if (in_plb
^ msr_px
) {
1599 /* Access in protected area */
1601 /* Access is not allowed */
1605 /* Read-write access is allowed */
1606 ctx
->prot
|= PAGE_WRITE
;
1610 case POWERPC_MMU_MPC8xx
:
1612 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1614 case POWERPC_MMU_BOOKE206
:
1615 cpu_abort(env
, "BookE 2.06 MMU doesn't have physical real mode\n");
1618 cpu_abort(env
, "Unknown or invalid MMU model\n");
1625 int get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
, target_ulong eaddr
,
1626 int rw
, int access_type
)
1631 qemu_log("%s\n", __func__
);
1633 if ((access_type
== ACCESS_CODE
&& msr_ir
== 0) ||
1634 (access_type
!= ACCESS_CODE
&& msr_dr
== 0)) {
1635 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1636 /* The BookE MMU always performs address translation. The
1637 IS and DS bits only affect the address space. */
1638 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1640 } else if (env
->mmu_model
== POWERPC_MMU_BOOKE206
) {
1641 ret
= mmubooke206_get_physical_address(env
, ctx
, eaddr
, rw
,
1644 /* No address translation. */
1645 ret
= check_physical(env
, ctx
, eaddr
, rw
);
1649 switch (env
->mmu_model
) {
1650 case POWERPC_MMU_32B
:
1651 case POWERPC_MMU_601
:
1652 case POWERPC_MMU_SOFT_6xx
:
1653 case POWERPC_MMU_SOFT_74xx
:
1654 /* Try to find a BAT */
1655 if (env
->nb_BATs
!= 0)
1656 ret
= get_bat(env
, ctx
, eaddr
, rw
, access_type
);
1657 #if defined(TARGET_PPC64)
1658 case POWERPC_MMU_620
:
1659 case POWERPC_MMU_64B
:
1660 case POWERPC_MMU_2_06
:
1663 /* We didn't match any BAT entry or don't have BATs */
1664 ret
= get_segment(env
, ctx
, eaddr
, rw
, access_type
);
1667 case POWERPC_MMU_SOFT_4xx
:
1668 case POWERPC_MMU_SOFT_4xx_Z
:
1669 ret
= mmu40x_get_physical_address(env
, ctx
, eaddr
,
1672 case POWERPC_MMU_BOOKE
:
1673 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1676 case POWERPC_MMU_BOOKE206
:
1677 ret
= mmubooke206_get_physical_address(env
, ctx
, eaddr
, rw
,
1680 case POWERPC_MMU_MPC8xx
:
1682 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1684 case POWERPC_MMU_REAL
:
1685 cpu_abort(env
, "PowerPC in real mode do not do any translation\n");
1688 cpu_abort(env
, "Unknown or invalid MMU model\n");
1693 qemu_log("%s address " TARGET_FMT_lx
" => %d " TARGET_FMT_plx
"\n",
1694 __func__
, eaddr
, ret
, ctx
->raddr
);
1700 target_phys_addr_t
cpu_get_phys_page_debug (CPUState
*env
, target_ulong addr
)
1704 if (unlikely(get_physical_address(env
, &ctx
, addr
, 0, ACCESS_INT
) != 0))
1707 return ctx
.raddr
& TARGET_PAGE_MASK
;
1710 static void booke206_update_mas_tlb_miss(CPUState
*env
, target_ulong address
,
1713 env
->spr
[SPR_BOOKE_MAS0
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TLBSELD_MASK
;
1714 env
->spr
[SPR_BOOKE_MAS1
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TSIZED_MASK
;
1715 env
->spr
[SPR_BOOKE_MAS2
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_WIMGED_MASK
;
1716 env
->spr
[SPR_BOOKE_MAS3
] = 0;
1717 env
->spr
[SPR_BOOKE_MAS6
] = 0;
1718 env
->spr
[SPR_BOOKE_MAS7
] = 0;
1721 if (((rw
== 2) && msr_ir
) || ((rw
!= 2) && msr_dr
)) {
1722 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_TS
;
1723 env
->spr
[SPR_BOOKE_MAS6
] |= MAS6_SAS
;
1726 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_VALID
;
1727 env
->spr
[SPR_BOOKE_MAS2
] |= address
& MAS2_EPN_MASK
;
1729 switch (env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TIDSELD_PIDZ
) {
1730 case MAS4_TIDSELD_PID0
:
1731 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID
] << MAS1_TID_SHIFT
;
1733 case MAS4_TIDSELD_PID1
:
1734 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID1
] << MAS1_TID_SHIFT
;
1736 case MAS4_TIDSELD_PID2
:
1737 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID2
] << MAS1_TID_SHIFT
;
1741 env
->spr
[SPR_BOOKE_MAS6
] |= env
->spr
[SPR_BOOKE_PID
] << 16;
1743 /* next victim logic */
1744 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_ESEL_SHIFT
;
1746 env
->last_way
&= booke206_tlb_ways(env
, 0) - 1;
1747 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_NV_SHIFT
;
1750 /* Perform address translation */
1751 int cpu_ppc_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
1761 access_type
= ACCESS_CODE
;
1764 access_type
= env
->access_type
;
1766 ret
= get_physical_address(env
, &ctx
, address
, rw
, access_type
);
1768 tlb_set_page(env
, address
& TARGET_PAGE_MASK
,
1769 ctx
.raddr
& TARGET_PAGE_MASK
, ctx
.prot
,
1770 mmu_idx
, TARGET_PAGE_SIZE
);
1772 } else if (ret
< 0) {
1774 if (access_type
== ACCESS_CODE
) {
1777 /* No matches in page tables or TLB */
1778 switch (env
->mmu_model
) {
1779 case POWERPC_MMU_SOFT_6xx
:
1780 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1781 env
->error_code
= 1 << 18;
1782 env
->spr
[SPR_IMISS
] = address
;
1783 env
->spr
[SPR_ICMP
] = 0x80000000 | ctx
.ptem
;
1785 case POWERPC_MMU_SOFT_74xx
:
1786 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1788 case POWERPC_MMU_SOFT_4xx
:
1789 case POWERPC_MMU_SOFT_4xx_Z
:
1790 env
->exception_index
= POWERPC_EXCP_ITLB
;
1791 env
->error_code
= 0;
1792 env
->spr
[SPR_40x_DEAR
] = address
;
1793 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1795 case POWERPC_MMU_32B
:
1796 case POWERPC_MMU_601
:
1797 #if defined(TARGET_PPC64)
1798 case POWERPC_MMU_620
:
1799 case POWERPC_MMU_64B
:
1800 case POWERPC_MMU_2_06
:
1802 env
->exception_index
= POWERPC_EXCP_ISI
;
1803 env
->error_code
= 0x40000000;
1805 case POWERPC_MMU_BOOKE206
:
1806 booke206_update_mas_tlb_miss(env
, address
, rw
);
1808 case POWERPC_MMU_BOOKE
:
1809 env
->exception_index
= POWERPC_EXCP_ITLB
;
1810 env
->error_code
= 0;
1811 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1813 case POWERPC_MMU_MPC8xx
:
1815 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1817 case POWERPC_MMU_REAL
:
1818 cpu_abort(env
, "PowerPC in real mode should never raise "
1819 "any MMU exceptions\n");
1822 cpu_abort(env
, "Unknown or invalid MMU model\n");
1827 /* Access rights violation */
1828 env
->exception_index
= POWERPC_EXCP_ISI
;
1829 env
->error_code
= 0x08000000;
1832 /* No execute protection violation */
1833 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1834 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1835 env
->spr
[SPR_BOOKE_ESR
] = 0x00000000;
1837 env
->exception_index
= POWERPC_EXCP_ISI
;
1838 env
->error_code
= 0x10000000;
1841 /* Direct store exception */
1842 /* No code fetch is allowed in direct-store areas */
1843 env
->exception_index
= POWERPC_EXCP_ISI
;
1844 env
->error_code
= 0x10000000;
1846 #if defined(TARGET_PPC64)
1848 /* No match in segment table */
1849 if (env
->mmu_model
== POWERPC_MMU_620
) {
1850 env
->exception_index
= POWERPC_EXCP_ISI
;
1851 /* XXX: this might be incorrect */
1852 env
->error_code
= 0x40000000;
1854 env
->exception_index
= POWERPC_EXCP_ISEG
;
1855 env
->error_code
= 0;
1863 /* No matches in page tables or TLB */
1864 switch (env
->mmu_model
) {
1865 case POWERPC_MMU_SOFT_6xx
:
1867 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1868 env
->error_code
= 1 << 16;
1870 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1871 env
->error_code
= 0;
1873 env
->spr
[SPR_DMISS
] = address
;
1874 env
->spr
[SPR_DCMP
] = 0x80000000 | ctx
.ptem
;
1876 env
->error_code
|= ctx
.key
<< 19;
1877 env
->spr
[SPR_HASH1
] = env
->htab_base
+
1878 get_pteg_offset(env
, ctx
.hash
[0], HASH_PTE_SIZE_32
);
1879 env
->spr
[SPR_HASH2
] = env
->htab_base
+
1880 get_pteg_offset(env
, ctx
.hash
[1], HASH_PTE_SIZE_32
);
1882 case POWERPC_MMU_SOFT_74xx
:
1884 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1886 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1889 /* Implement LRU algorithm */
1890 env
->error_code
= ctx
.key
<< 19;
1891 env
->spr
[SPR_TLBMISS
] = (address
& ~((target_ulong
)0x3)) |
1892 ((env
->last_way
+ 1) & (env
->nb_ways
- 1));
1893 env
->spr
[SPR_PTEHI
] = 0x80000000 | ctx
.ptem
;
1895 case POWERPC_MMU_SOFT_4xx
:
1896 case POWERPC_MMU_SOFT_4xx_Z
:
1897 env
->exception_index
= POWERPC_EXCP_DTLB
;
1898 env
->error_code
= 0;
1899 env
->spr
[SPR_40x_DEAR
] = address
;
1901 env
->spr
[SPR_40x_ESR
] = 0x00800000;
1903 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1905 case POWERPC_MMU_32B
:
1906 case POWERPC_MMU_601
:
1907 #if defined(TARGET_PPC64)
1908 case POWERPC_MMU_620
:
1909 case POWERPC_MMU_64B
:
1910 case POWERPC_MMU_2_06
:
1912 env
->exception_index
= POWERPC_EXCP_DSI
;
1913 env
->error_code
= 0;
1914 env
->spr
[SPR_DAR
] = address
;
1916 env
->spr
[SPR_DSISR
] = 0x42000000;
1918 env
->spr
[SPR_DSISR
] = 0x40000000;
1920 case POWERPC_MMU_MPC8xx
:
1922 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1924 case POWERPC_MMU_BOOKE206
:
1925 booke206_update_mas_tlb_miss(env
, address
, rw
);
1927 case POWERPC_MMU_BOOKE
:
1928 env
->exception_index
= POWERPC_EXCP_DTLB
;
1929 env
->error_code
= 0;
1930 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1931 env
->spr
[SPR_BOOKE_ESR
] = rw
? ESR_ST
: 0;
1933 case POWERPC_MMU_REAL
:
1934 cpu_abort(env
, "PowerPC in real mode should never raise "
1935 "any MMU exceptions\n");
1938 cpu_abort(env
, "Unknown or invalid MMU model\n");
1943 /* Access rights violation */
1944 env
->exception_index
= POWERPC_EXCP_DSI
;
1945 env
->error_code
= 0;
1946 if (env
->mmu_model
== POWERPC_MMU_SOFT_4xx
1947 || env
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
) {
1948 env
->spr
[SPR_40x_DEAR
] = address
;
1950 env
->spr
[SPR_40x_ESR
] |= 0x00800000;
1952 } else if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1953 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1954 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1955 env
->spr
[SPR_BOOKE_ESR
] = rw
? ESR_ST
: 0;
1957 env
->spr
[SPR_DAR
] = address
;
1959 env
->spr
[SPR_DSISR
] = 0x0A000000;
1961 env
->spr
[SPR_DSISR
] = 0x08000000;
1966 /* Direct store exception */
1967 switch (access_type
) {
1969 /* Floating point load/store */
1970 env
->exception_index
= POWERPC_EXCP_ALIGN
;
1971 env
->error_code
= POWERPC_EXCP_ALIGN_FP
;
1972 env
->spr
[SPR_DAR
] = address
;
1975 /* lwarx, ldarx or stwcx. */
1976 env
->exception_index
= POWERPC_EXCP_DSI
;
1977 env
->error_code
= 0;
1978 env
->spr
[SPR_DAR
] = address
;
1980 env
->spr
[SPR_DSISR
] = 0x06000000;
1982 env
->spr
[SPR_DSISR
] = 0x04000000;
1985 /* eciwx or ecowx */
1986 env
->exception_index
= POWERPC_EXCP_DSI
;
1987 env
->error_code
= 0;
1988 env
->spr
[SPR_DAR
] = address
;
1990 env
->spr
[SPR_DSISR
] = 0x06100000;
1992 env
->spr
[SPR_DSISR
] = 0x04100000;
1995 printf("DSI: invalid exception (%d)\n", ret
);
1996 env
->exception_index
= POWERPC_EXCP_PROGRAM
;
1998 POWERPC_EXCP_INVAL
| POWERPC_EXCP_INVAL_INVAL
;
1999 env
->spr
[SPR_DAR
] = address
;
2003 #if defined(TARGET_PPC64)
2005 /* No match in segment table */
2006 if (env
->mmu_model
== POWERPC_MMU_620
) {
2007 env
->exception_index
= POWERPC_EXCP_DSI
;
2008 env
->error_code
= 0;
2009 env
->spr
[SPR_DAR
] = address
;
2010 /* XXX: this might be incorrect */
2012 env
->spr
[SPR_DSISR
] = 0x42000000;
2014 env
->spr
[SPR_DSISR
] = 0x40000000;
2016 env
->exception_index
= POWERPC_EXCP_DSEG
;
2017 env
->error_code
= 0;
2018 env
->spr
[SPR_DAR
] = address
;
2025 printf("%s: set exception to %d %02x\n", __func__
,
2026 env
->exception
, env
->error_code
);
2034 /*****************************************************************************/
2035 /* BATs management */
2036 #if !defined(FLUSH_ALL_TLBS)
2037 static inline void do_invalidate_BAT(CPUPPCState
*env
, target_ulong BATu
,
2040 target_ulong base
, end
, page
;
2042 base
= BATu
& ~0x0001FFFF;
2043 end
= base
+ mask
+ 0x00020000;
2044 LOG_BATS("Flush BAT from " TARGET_FMT_lx
" to " TARGET_FMT_lx
" ("
2045 TARGET_FMT_lx
")\n", base
, end
, mask
);
2046 for (page
= base
; page
!= end
; page
+= TARGET_PAGE_SIZE
)
2047 tlb_flush_page(env
, page
);
2048 LOG_BATS("Flush done\n");
2052 static inline void dump_store_bat(CPUPPCState
*env
, char ID
, int ul
, int nr
,
2055 LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx
" (" TARGET_FMT_lx
")\n", ID
,
2056 nr
, ul
== 0 ? 'u' : 'l', value
, env
->nip
);
2059 void ppc_store_ibatu (CPUPPCState
*env
, int nr
, target_ulong value
)
2063 dump_store_bat(env
, 'I', 0, nr
, value
);
2064 if (env
->IBAT
[0][nr
] != value
) {
2065 mask
= (value
<< 15) & 0x0FFE0000UL
;
2066 #if !defined(FLUSH_ALL_TLBS)
2067 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2069 /* When storing valid upper BAT, mask BEPI and BRPN
2070 * and invalidate all TLBs covered by this BAT
2072 mask
= (value
<< 15) & 0x0FFE0000UL
;
2073 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
2074 (value
& ~0x0001FFFFUL
& ~mask
);
2075 env
->IBAT
[1][nr
] = (env
->IBAT
[1][nr
] & 0x0000007B) |
2076 (env
->IBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
2077 #if !defined(FLUSH_ALL_TLBS)
2078 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2085 void ppc_store_ibatl (CPUPPCState
*env
, int nr
, target_ulong value
)
2087 dump_store_bat(env
, 'I', 1, nr
, value
);
2088 env
->IBAT
[1][nr
] = value
;
2091 void ppc_store_dbatu (CPUPPCState
*env
, int nr
, target_ulong value
)
2095 dump_store_bat(env
, 'D', 0, nr
, value
);
2096 if (env
->DBAT
[0][nr
] != value
) {
2097 /* When storing valid upper BAT, mask BEPI and BRPN
2098 * and invalidate all TLBs covered by this BAT
2100 mask
= (value
<< 15) & 0x0FFE0000UL
;
2101 #if !defined(FLUSH_ALL_TLBS)
2102 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
2104 mask
= (value
<< 15) & 0x0FFE0000UL
;
2105 env
->DBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
2106 (value
& ~0x0001FFFFUL
& ~mask
);
2107 env
->DBAT
[1][nr
] = (env
->DBAT
[1][nr
] & 0x0000007B) |
2108 (env
->DBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
2109 #if !defined(FLUSH_ALL_TLBS)
2110 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
2117 void ppc_store_dbatl (CPUPPCState
*env
, int nr
, target_ulong value
)
2119 dump_store_bat(env
, 'D', 1, nr
, value
);
2120 env
->DBAT
[1][nr
] = value
;
2123 void ppc_store_ibatu_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
2126 #if defined(FLUSH_ALL_TLBS)
2130 dump_store_bat(env
, 'I', 0, nr
, value
);
2131 if (env
->IBAT
[0][nr
] != value
) {
2132 #if defined(FLUSH_ALL_TLBS)
2135 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
2136 if (env
->IBAT
[1][nr
] & 0x40) {
2137 /* Invalidate BAT only if it is valid */
2138 #if !defined(FLUSH_ALL_TLBS)
2139 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2144 /* When storing valid upper BAT, mask BEPI and BRPN
2145 * and invalidate all TLBs covered by this BAT
2147 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
2148 (value
& ~0x0001FFFFUL
& ~mask
);
2149 env
->DBAT
[0][nr
] = env
->IBAT
[0][nr
];
2150 if (env
->IBAT
[1][nr
] & 0x40) {
2151 #if !defined(FLUSH_ALL_TLBS)
2152 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2157 #if defined(FLUSH_ALL_TLBS)
2164 void ppc_store_ibatl_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
2167 #if defined(FLUSH_ALL_TLBS)
2171 dump_store_bat(env
, 'I', 1, nr
, value
);
2172 if (env
->IBAT
[1][nr
] != value
) {
2173 #if defined(FLUSH_ALL_TLBS)
2176 if (env
->IBAT
[1][nr
] & 0x40) {
2177 #if !defined(FLUSH_ALL_TLBS)
2178 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
2179 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2185 #if !defined(FLUSH_ALL_TLBS)
2186 mask
= (value
<< 17) & 0x0FFE0000UL
;
2187 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2192 env
->IBAT
[1][nr
] = value
;
2193 env
->DBAT
[1][nr
] = value
;
2194 #if defined(FLUSH_ALL_TLBS)
2201 /*****************************************************************************/
2202 /* TLB management */
2203 void ppc_tlb_invalidate_all (CPUPPCState
*env
)
2205 switch (env
->mmu_model
) {
2206 case POWERPC_MMU_SOFT_6xx
:
2207 case POWERPC_MMU_SOFT_74xx
:
2208 ppc6xx_tlb_invalidate_all(env
);
2210 case POWERPC_MMU_SOFT_4xx
:
2211 case POWERPC_MMU_SOFT_4xx_Z
:
2212 ppc4xx_tlb_invalidate_all(env
);
2214 case POWERPC_MMU_REAL
:
2215 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
2217 case POWERPC_MMU_MPC8xx
:
2219 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
2221 case POWERPC_MMU_BOOKE
:
2224 case POWERPC_MMU_BOOKE206
:
2225 booke206_flush_tlb(env
, -1, 0);
2227 case POWERPC_MMU_32B
:
2228 case POWERPC_MMU_601
:
2229 #if defined(TARGET_PPC64)
2230 case POWERPC_MMU_620
:
2231 case POWERPC_MMU_64B
:
2232 case POWERPC_MMU_2_06
:
2233 #endif /* defined(TARGET_PPC64) */
2238 cpu_abort(env
, "Unknown MMU model\n");
2243 void ppc_tlb_invalidate_one (CPUPPCState
*env
, target_ulong addr
)
2245 #if !defined(FLUSH_ALL_TLBS)
2246 addr
&= TARGET_PAGE_MASK
;
2247 switch (env
->mmu_model
) {
2248 case POWERPC_MMU_SOFT_6xx
:
2249 case POWERPC_MMU_SOFT_74xx
:
2250 ppc6xx_tlb_invalidate_virt(env
, addr
, 0);
2251 if (env
->id_tlbs
== 1)
2252 ppc6xx_tlb_invalidate_virt(env
, addr
, 1);
2254 case POWERPC_MMU_SOFT_4xx
:
2255 case POWERPC_MMU_SOFT_4xx_Z
:
2256 ppc4xx_tlb_invalidate_virt(env
, addr
, env
->spr
[SPR_40x_PID
]);
2258 case POWERPC_MMU_REAL
:
2259 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
2261 case POWERPC_MMU_MPC8xx
:
2263 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
2265 case POWERPC_MMU_BOOKE
:
2267 cpu_abort(env
, "BookE MMU model is not implemented\n");
2269 case POWERPC_MMU_BOOKE206
:
2271 cpu_abort(env
, "BookE 2.06 MMU model is not implemented\n");
2273 case POWERPC_MMU_32B
:
2274 case POWERPC_MMU_601
:
2275 /* tlbie invalidate TLBs for all segments */
2276 addr
&= ~((target_ulong
)-1ULL << 28);
2277 /* XXX: this case should be optimized,
2278 * giving a mask to tlb_flush_page
2280 tlb_flush_page(env
, addr
| (0x0 << 28));
2281 tlb_flush_page(env
, addr
| (0x1 << 28));
2282 tlb_flush_page(env
, addr
| (0x2 << 28));
2283 tlb_flush_page(env
, addr
| (0x3 << 28));
2284 tlb_flush_page(env
, addr
| (0x4 << 28));
2285 tlb_flush_page(env
, addr
| (0x5 << 28));
2286 tlb_flush_page(env
, addr
| (0x6 << 28));
2287 tlb_flush_page(env
, addr
| (0x7 << 28));
2288 tlb_flush_page(env
, addr
| (0x8 << 28));
2289 tlb_flush_page(env
, addr
| (0x9 << 28));
2290 tlb_flush_page(env
, addr
| (0xA << 28));
2291 tlb_flush_page(env
, addr
| (0xB << 28));
2292 tlb_flush_page(env
, addr
| (0xC << 28));
2293 tlb_flush_page(env
, addr
| (0xD << 28));
2294 tlb_flush_page(env
, addr
| (0xE << 28));
2295 tlb_flush_page(env
, addr
| (0xF << 28));
2297 #if defined(TARGET_PPC64)
2298 case POWERPC_MMU_620
:
2299 case POWERPC_MMU_64B
:
2300 case POWERPC_MMU_2_06
:
2301 /* tlbie invalidate TLBs for all segments */
2302 /* XXX: given the fact that there are too many segments to invalidate,
2303 * and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
2304 * we just invalidate all TLBs
2308 #endif /* defined(TARGET_PPC64) */
2311 cpu_abort(env
, "Unknown MMU model\n");
2315 ppc_tlb_invalidate_all(env
);
2319 /*****************************************************************************/
2320 /* Special registers manipulation */
2321 #if defined(TARGET_PPC64)
2322 void ppc_store_asr (CPUPPCState
*env
, target_ulong value
)
2324 if (env
->asr
!= value
) {
2331 void ppc_store_sdr1 (CPUPPCState
*env
, target_ulong value
)
2333 LOG_MMU("%s: " TARGET_FMT_lx
"\n", __func__
, value
);
2334 if (env
->spr
[SPR_SDR1
] != value
) {
2335 env
->spr
[SPR_SDR1
] = value
;
2336 #if defined(TARGET_PPC64)
2337 if (env
->mmu_model
& POWERPC_MMU_64
) {
2338 target_ulong htabsize
= value
& SDR_64_HTABSIZE
;
2340 if (htabsize
> 28) {
2341 fprintf(stderr
, "Invalid HTABSIZE 0x" TARGET_FMT_lx
2342 " stored in SDR1\n", htabsize
);
2345 env
->htab_mask
= (1ULL << (htabsize
+ 18)) - 1;
2346 env
->htab_base
= value
& SDR_64_HTABORG
;
2348 #endif /* defined(TARGET_PPC64) */
2350 /* FIXME: Should check for valid HTABMASK values */
2351 env
->htab_mask
= ((value
& SDR_32_HTABMASK
) << 16) | 0xFFFF;
2352 env
->htab_base
= value
& SDR_32_HTABORG
;
2358 #if defined(TARGET_PPC64)
2359 target_ulong
ppc_load_sr (CPUPPCState
*env
, int slb_nr
)
2366 void ppc_store_sr (CPUPPCState
*env
, int srnum
, target_ulong value
)
2368 LOG_MMU("%s: reg=%d " TARGET_FMT_lx
" " TARGET_FMT_lx
"\n", __func__
,
2369 srnum
, value
, env
->sr
[srnum
]);
2370 #if defined(TARGET_PPC64)
2371 if (env
->mmu_model
& POWERPC_MMU_64
) {
2372 uint64_t rb
= 0, rs
= 0;
2375 rb
|= ((uint32_t)srnum
& 0xf) << 28;
2376 /* Set the valid bit */
2379 rb
|= (uint32_t)srnum
;
2382 rs
|= (value
& 0xfffffff) << 12;
2384 rs
|= ((value
>> 27) & 0xf) << 8;
2386 ppc_store_slb(env
, rb
, rs
);
2389 if (env
->sr
[srnum
] != value
) {
2390 env
->sr
[srnum
] = value
;
2391 /* Invalidating 256MB of virtual memory in 4kB pages is way longer than
2392 flusing the whole TLB. */
2393 #if !defined(FLUSH_ALL_TLBS) && 0
2395 target_ulong page
, end
;
2396 /* Invalidate 256 MB of virtual memory */
2397 page
= (16 << 20) * srnum
;
2398 end
= page
+ (16 << 20);
2399 for (; page
!= end
; page
+= TARGET_PAGE_SIZE
)
2400 tlb_flush_page(env
, page
);
2407 #endif /* !defined (CONFIG_USER_ONLY) */
2409 /* GDBstub can read and write MSR... */
2410 void ppc_store_msr (CPUPPCState
*env
, target_ulong value
)
2412 hreg_store_msr(env
, value
, 0);
2415 /*****************************************************************************/
2416 /* Exception processing */
2417 #if defined (CONFIG_USER_ONLY)
2418 void do_interrupt (CPUState
*env
)
2420 env
->exception_index
= POWERPC_EXCP_NONE
;
2421 env
->error_code
= 0;
2424 void ppc_hw_interrupt (CPUState
*env
)
2426 env
->exception_index
= POWERPC_EXCP_NONE
;
2427 env
->error_code
= 0;
2429 #else /* defined (CONFIG_USER_ONLY) */
2430 static inline void dump_syscall(CPUState
*env
)
2432 qemu_log_mask(CPU_LOG_INT
, "syscall r0=%016" PRIx64
" r3=%016" PRIx64
2433 " r4=%016" PRIx64
" r5=%016" PRIx64
" r6=%016" PRIx64
2434 " nip=" TARGET_FMT_lx
"\n",
2435 ppc_dump_gpr(env
, 0), ppc_dump_gpr(env
, 3),
2436 ppc_dump_gpr(env
, 4), ppc_dump_gpr(env
, 5),
2437 ppc_dump_gpr(env
, 6), env
->nip
);
2440 /* Note that this function should be greatly optimized
2441 * when called with a constant excp, from ppc_hw_interrupt
2443 static inline void powerpc_excp(CPUState
*env
, int excp_model
, int excp
)
2445 target_ulong msr
, new_msr
, vector
;
2446 int srr0
, srr1
, asrr0
, asrr1
;
2447 int lpes0
, lpes1
, lev
;
2450 /* XXX: find a suitable condition to enable the hypervisor mode */
2451 lpes0
= (env
->spr
[SPR_LPCR
] >> 1) & 1;
2452 lpes1
= (env
->spr
[SPR_LPCR
] >> 2) & 1;
2454 /* Those values ensure we won't enter the hypervisor mode */
2459 qemu_log_mask(CPU_LOG_INT
, "Raise exception at " TARGET_FMT_lx
2460 " => %08x (%02x)\n", env
->nip
, excp
, env
->error_code
);
2462 /* new srr1 value excluding must-be-zero bits */
2463 msr
= env
->msr
& ~0x783f0000ULL
;
2465 /* new interrupt handler msr */
2466 new_msr
= env
->msr
& ((target_ulong
)1 << MSR_ME
);
2468 /* target registers */
2475 case POWERPC_EXCP_NONE
:
2476 /* Should never happen */
2478 case POWERPC_EXCP_CRITICAL
: /* Critical input */
2479 switch (excp_model
) {
2480 case POWERPC_EXCP_40x
:
2481 srr0
= SPR_40x_SRR2
;
2482 srr1
= SPR_40x_SRR3
;
2484 case POWERPC_EXCP_BOOKE
:
2485 srr0
= SPR_BOOKE_CSRR0
;
2486 srr1
= SPR_BOOKE_CSRR1
;
2488 case POWERPC_EXCP_G2
:
2494 case POWERPC_EXCP_MCHECK
: /* Machine check exception */
2496 /* Machine check exception is not enabled.
2497 * Enter checkstop state.
2499 if (qemu_log_enabled()) {
2500 qemu_log("Machine check while not allowed. "
2501 "Entering checkstop state\n");
2503 fprintf(stderr
, "Machine check while not allowed. "
2504 "Entering checkstop state\n");
2507 env
->interrupt_request
|= CPU_INTERRUPT_EXITTB
;
2510 /* XXX: find a suitable condition to enable the hypervisor mode */
2511 new_msr
|= (target_ulong
)MSR_HVB
;
2514 /* machine check exceptions don't have ME set */
2515 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2517 /* XXX: should also have something loaded in DAR / DSISR */
2518 switch (excp_model
) {
2519 case POWERPC_EXCP_40x
:
2520 srr0
= SPR_40x_SRR2
;
2521 srr1
= SPR_40x_SRR3
;
2523 case POWERPC_EXCP_BOOKE
:
2524 srr0
= SPR_BOOKE_MCSRR0
;
2525 srr1
= SPR_BOOKE_MCSRR1
;
2526 asrr0
= SPR_BOOKE_CSRR0
;
2527 asrr1
= SPR_BOOKE_CSRR1
;
2533 case POWERPC_EXCP_DSI
: /* Data storage exception */
2534 LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx
" DAR=" TARGET_FMT_lx
2535 "\n", env
->spr
[SPR_DSISR
], env
->spr
[SPR_DAR
]);
2537 new_msr
|= (target_ulong
)MSR_HVB
;
2539 case POWERPC_EXCP_ISI
: /* Instruction storage exception */
2540 LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx
", nip=" TARGET_FMT_lx
2541 "\n", msr
, env
->nip
);
2543 new_msr
|= (target_ulong
)MSR_HVB
;
2544 msr
|= env
->error_code
;
2546 case POWERPC_EXCP_EXTERNAL
: /* External input */
2548 new_msr
|= (target_ulong
)MSR_HVB
;
2550 case POWERPC_EXCP_ALIGN
: /* Alignment exception */
2552 new_msr
|= (target_ulong
)MSR_HVB
;
2553 /* XXX: this is false */
2554 /* Get rS/rD and rA from faulting opcode */
2555 env
->spr
[SPR_DSISR
] |= (ldl_code((env
->nip
- 4)) & 0x03FF0000) >> 16;
2557 case POWERPC_EXCP_PROGRAM
: /* Program exception */
2558 switch (env
->error_code
& ~0xF) {
2559 case POWERPC_EXCP_FP
:
2560 if ((msr_fe0
== 0 && msr_fe1
== 0) || msr_fp
== 0) {
2561 LOG_EXCP("Ignore floating point exception\n");
2562 env
->exception_index
= POWERPC_EXCP_NONE
;
2563 env
->error_code
= 0;
2567 new_msr
|= (target_ulong
)MSR_HVB
;
2569 if (msr_fe0
== msr_fe1
)
2573 case POWERPC_EXCP_INVAL
:
2574 LOG_EXCP("Invalid instruction at " TARGET_FMT_lx
"\n", env
->nip
);
2576 new_msr
|= (target_ulong
)MSR_HVB
;
2578 env
->spr
[SPR_BOOKE_ESR
] = ESR_PIL
;
2580 case POWERPC_EXCP_PRIV
:
2582 new_msr
|= (target_ulong
)MSR_HVB
;
2584 env
->spr
[SPR_BOOKE_ESR
] = ESR_PPR
;
2586 case POWERPC_EXCP_TRAP
:
2588 new_msr
|= (target_ulong
)MSR_HVB
;
2590 env
->spr
[SPR_BOOKE_ESR
] = ESR_PTR
;
2593 /* Should never occur */
2594 cpu_abort(env
, "Invalid program exception %d. Aborting\n",
2599 case POWERPC_EXCP_FPU
: /* Floating-point unavailable exception */
2601 new_msr
|= (target_ulong
)MSR_HVB
;
2603 case POWERPC_EXCP_SYSCALL
: /* System call exception */
2605 lev
= env
->error_code
;
2606 if ((lev
== 1) && cpu_ppc_hypercall
) {
2607 cpu_ppc_hypercall(env
);
2610 if (lev
== 1 || (lpes0
== 0 && lpes1
== 0))
2611 new_msr
|= (target_ulong
)MSR_HVB
;
2613 case POWERPC_EXCP_APU
: /* Auxiliary processor unavailable */
2615 case POWERPC_EXCP_DECR
: /* Decrementer exception */
2617 new_msr
|= (target_ulong
)MSR_HVB
;
2619 case POWERPC_EXCP_FIT
: /* Fixed-interval timer interrupt */
2621 LOG_EXCP("FIT exception\n");
2623 case POWERPC_EXCP_WDT
: /* Watchdog timer interrupt */
2624 LOG_EXCP("WDT exception\n");
2625 switch (excp_model
) {
2626 case POWERPC_EXCP_BOOKE
:
2627 srr0
= SPR_BOOKE_CSRR0
;
2628 srr1
= SPR_BOOKE_CSRR1
;
2634 case POWERPC_EXCP_DTLB
: /* Data TLB error */
2636 case POWERPC_EXCP_ITLB
: /* Instruction TLB error */
2638 case POWERPC_EXCP_DEBUG
: /* Debug interrupt */
2639 switch (excp_model
) {
2640 case POWERPC_EXCP_BOOKE
:
2641 srr0
= SPR_BOOKE_DSRR0
;
2642 srr1
= SPR_BOOKE_DSRR1
;
2643 asrr0
= SPR_BOOKE_CSRR0
;
2644 asrr1
= SPR_BOOKE_CSRR1
;
2650 cpu_abort(env
, "Debug exception is not implemented yet !\n");
2652 case POWERPC_EXCP_SPEU
: /* SPE/embedded floating-point unavailable */
2653 env
->spr
[SPR_BOOKE_ESR
] = ESR_SPV
;
2655 case POWERPC_EXCP_EFPDI
: /* Embedded floating-point data interrupt */
2657 cpu_abort(env
, "Embedded floating point data exception "
2658 "is not implemented yet !\n");
2659 env
->spr
[SPR_BOOKE_ESR
] = ESR_SPV
;
2661 case POWERPC_EXCP_EFPRI
: /* Embedded floating-point round interrupt */
2663 cpu_abort(env
, "Embedded floating point round exception "
2664 "is not implemented yet !\n");
2665 env
->spr
[SPR_BOOKE_ESR
] = ESR_SPV
;
2667 case POWERPC_EXCP_EPERFM
: /* Embedded performance monitor interrupt */
2670 "Performance counter exception is not implemented yet !\n");
2672 case POWERPC_EXCP_DOORI
: /* Embedded doorbell interrupt */
2675 "Embedded doorbell interrupt is not implemented yet !\n");
2677 case POWERPC_EXCP_DOORCI
: /* Embedded doorbell critical interrupt */
2678 switch (excp_model
) {
2679 case POWERPC_EXCP_BOOKE
:
2680 srr0
= SPR_BOOKE_CSRR0
;
2681 srr1
= SPR_BOOKE_CSRR1
;
2687 cpu_abort(env
, "Embedded doorbell critical interrupt "
2688 "is not implemented yet !\n");
2690 case POWERPC_EXCP_RESET
: /* System reset exception */
2692 /* indicate that we resumed from power save mode */
2695 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2699 /* XXX: find a suitable condition to enable the hypervisor mode */
2700 new_msr
|= (target_ulong
)MSR_HVB
;
2703 case POWERPC_EXCP_DSEG
: /* Data segment exception */
2705 new_msr
|= (target_ulong
)MSR_HVB
;
2707 case POWERPC_EXCP_ISEG
: /* Instruction segment exception */
2709 new_msr
|= (target_ulong
)MSR_HVB
;
2711 case POWERPC_EXCP_HDECR
: /* Hypervisor decrementer exception */
2714 new_msr
|= (target_ulong
)MSR_HVB
;
2715 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2717 case POWERPC_EXCP_TRACE
: /* Trace exception */
2719 new_msr
|= (target_ulong
)MSR_HVB
;
2721 case POWERPC_EXCP_HDSI
: /* Hypervisor data storage exception */
2724 new_msr
|= (target_ulong
)MSR_HVB
;
2725 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2727 case POWERPC_EXCP_HISI
: /* Hypervisor instruction storage exception */
2730 new_msr
|= (target_ulong
)MSR_HVB
;
2731 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2733 case POWERPC_EXCP_HDSEG
: /* Hypervisor data segment exception */
2736 new_msr
|= (target_ulong
)MSR_HVB
;
2737 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2739 case POWERPC_EXCP_HISEG
: /* Hypervisor instruction segment exception */
2742 new_msr
|= (target_ulong
)MSR_HVB
;
2743 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2745 case POWERPC_EXCP_VPU
: /* Vector unavailable exception */
2747 new_msr
|= (target_ulong
)MSR_HVB
;
2749 case POWERPC_EXCP_PIT
: /* Programmable interval timer interrupt */
2750 LOG_EXCP("PIT exception\n");
2752 case POWERPC_EXCP_IO
: /* IO error exception */
2754 cpu_abort(env
, "601 IO error exception is not implemented yet !\n");
2756 case POWERPC_EXCP_RUNM
: /* Run mode exception */
2758 cpu_abort(env
, "601 run mode exception is not implemented yet !\n");
2760 case POWERPC_EXCP_EMUL
: /* Emulation trap exception */
2762 cpu_abort(env
, "602 emulation trap exception "
2763 "is not implemented yet !\n");
2765 case POWERPC_EXCP_IFTLB
: /* Instruction fetch TLB error */
2766 if (lpes1
== 0) /* XXX: check this */
2767 new_msr
|= (target_ulong
)MSR_HVB
;
2768 switch (excp_model
) {
2769 case POWERPC_EXCP_602
:
2770 case POWERPC_EXCP_603
:
2771 case POWERPC_EXCP_603E
:
2772 case POWERPC_EXCP_G2
:
2774 case POWERPC_EXCP_7x5
:
2776 case POWERPC_EXCP_74xx
:
2779 cpu_abort(env
, "Invalid instruction TLB miss exception\n");
2783 case POWERPC_EXCP_DLTLB
: /* Data load TLB miss */
2784 if (lpes1
== 0) /* XXX: check this */
2785 new_msr
|= (target_ulong
)MSR_HVB
;
2786 switch (excp_model
) {
2787 case POWERPC_EXCP_602
:
2788 case POWERPC_EXCP_603
:
2789 case POWERPC_EXCP_603E
:
2790 case POWERPC_EXCP_G2
:
2792 case POWERPC_EXCP_7x5
:
2794 case POWERPC_EXCP_74xx
:
2797 cpu_abort(env
, "Invalid data load TLB miss exception\n");
2801 case POWERPC_EXCP_DSTLB
: /* Data store TLB miss */
2802 if (lpes1
== 0) /* XXX: check this */
2803 new_msr
|= (target_ulong
)MSR_HVB
;
2804 switch (excp_model
) {
2805 case POWERPC_EXCP_602
:
2806 case POWERPC_EXCP_603
:
2807 case POWERPC_EXCP_603E
:
2808 case POWERPC_EXCP_G2
:
2810 /* Swap temporary saved registers with GPRs */
2811 if (!(new_msr
& ((target_ulong
)1 << MSR_TGPR
))) {
2812 new_msr
|= (target_ulong
)1 << MSR_TGPR
;
2813 hreg_swap_gpr_tgpr(env
);
2816 case POWERPC_EXCP_7x5
:
2818 #if defined (DEBUG_SOFTWARE_TLB)
2819 if (qemu_log_enabled()) {
2821 target_ulong
*miss
, *cmp
;
2823 if (excp
== POWERPC_EXCP_IFTLB
) {
2826 miss
= &env
->spr
[SPR_IMISS
];
2827 cmp
= &env
->spr
[SPR_ICMP
];
2829 if (excp
== POWERPC_EXCP_DLTLB
)
2834 miss
= &env
->spr
[SPR_DMISS
];
2835 cmp
= &env
->spr
[SPR_DCMP
];
2837 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2838 TARGET_FMT_lx
" H1 " TARGET_FMT_lx
" H2 "
2839 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2840 env
->spr
[SPR_HASH1
], env
->spr
[SPR_HASH2
],
2844 msr
|= env
->crf
[0] << 28;
2845 msr
|= env
->error_code
; /* key, D/I, S/L bits */
2846 /* Set way using a LRU mechanism */
2847 msr
|= ((env
->last_way
+ 1) & (env
->nb_ways
- 1)) << 17;
2849 case POWERPC_EXCP_74xx
:
2851 #if defined (DEBUG_SOFTWARE_TLB)
2852 if (qemu_log_enabled()) {
2854 target_ulong
*miss
, *cmp
;
2856 if (excp
== POWERPC_EXCP_IFTLB
) {
2859 miss
= &env
->spr
[SPR_TLBMISS
];
2860 cmp
= &env
->spr
[SPR_PTEHI
];
2862 if (excp
== POWERPC_EXCP_DLTLB
)
2867 miss
= &env
->spr
[SPR_TLBMISS
];
2868 cmp
= &env
->spr
[SPR_PTEHI
];
2870 qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2871 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2875 msr
|= env
->error_code
; /* key bit */
2878 cpu_abort(env
, "Invalid data store TLB miss exception\n");
2882 case POWERPC_EXCP_FPA
: /* Floating-point assist exception */
2884 cpu_abort(env
, "Floating point assist exception "
2885 "is not implemented yet !\n");
2887 case POWERPC_EXCP_DABR
: /* Data address breakpoint */
2889 cpu_abort(env
, "DABR exception is not implemented yet !\n");
2891 case POWERPC_EXCP_IABR
: /* Instruction address breakpoint */
2893 cpu_abort(env
, "IABR exception is not implemented yet !\n");
2895 case POWERPC_EXCP_SMI
: /* System management interrupt */
2897 cpu_abort(env
, "SMI exception is not implemented yet !\n");
2899 case POWERPC_EXCP_THERM
: /* Thermal interrupt */
2901 cpu_abort(env
, "Thermal management exception "
2902 "is not implemented yet !\n");
2904 case POWERPC_EXCP_PERFM
: /* Embedded performance monitor interrupt */
2906 new_msr
|= (target_ulong
)MSR_HVB
;
2909 "Performance counter exception is not implemented yet !\n");
2911 case POWERPC_EXCP_VPUA
: /* Vector assist exception */
2913 cpu_abort(env
, "VPU assist exception is not implemented yet !\n");
2915 case POWERPC_EXCP_SOFTP
: /* Soft patch exception */
2918 "970 soft-patch exception is not implemented yet !\n");
2920 case POWERPC_EXCP_MAINT
: /* Maintenance exception */
2923 "970 maintenance exception is not implemented yet !\n");
2925 case POWERPC_EXCP_MEXTBR
: /* Maskable external breakpoint */
2927 cpu_abort(env
, "Maskable external exception "
2928 "is not implemented yet !\n");
2930 case POWERPC_EXCP_NMEXTBR
: /* Non maskable external breakpoint */
2932 cpu_abort(env
, "Non maskable external exception "
2933 "is not implemented yet !\n");
2937 cpu_abort(env
, "Invalid PowerPC exception %d. Aborting\n", excp
);
2940 /* save current instruction location */
2941 env
->spr
[srr0
] = env
->nip
- 4;
2944 /* save next instruction location */
2945 env
->spr
[srr0
] = env
->nip
;
2949 env
->spr
[srr1
] = msr
;
2950 /* If any alternate SRR register are defined, duplicate saved values */
2952 env
->spr
[asrr0
] = env
->spr
[srr0
];
2954 env
->spr
[asrr1
] = env
->spr
[srr1
];
2955 /* If we disactivated any translation, flush TLBs */
2956 if (new_msr
& ((1 << MSR_IR
) | (1 << MSR_DR
)))
2960 new_msr
|= (target_ulong
)1 << MSR_LE
;
2963 /* Jump to handler */
2964 vector
= env
->excp_vectors
[excp
];
2965 if (vector
== (target_ulong
)-1ULL) {
2966 cpu_abort(env
, "Raised an exception without defined vector %d\n",
2969 vector
|= env
->excp_prefix
;
2970 #if defined(TARGET_PPC64)
2971 if (excp_model
== POWERPC_EXCP_BOOKE
) {
2973 vector
= (uint32_t)vector
;
2975 new_msr
|= (target_ulong
)1 << MSR_CM
;
2978 if (!msr_isf
&& !(env
->mmu_model
& POWERPC_MMU_64
)) {
2979 vector
= (uint32_t)vector
;
2981 new_msr
|= (target_ulong
)1 << MSR_SF
;
2985 /* XXX: we don't use hreg_store_msr here as already have treated
2986 * any special case that could occur. Just store MSR and update hflags
2988 env
->msr
= new_msr
& env
->msr_mask
;
2989 hreg_compute_hflags(env
);
2991 /* Reset exception state */
2992 env
->exception_index
= POWERPC_EXCP_NONE
;
2993 env
->error_code
= 0;
2995 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
2996 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
2997 /* XXX: The BookE changes address space when switching modes,
2998 we should probably implement that as different MMU indexes,
2999 but for the moment we do it the slow way and flush all. */
3004 void do_interrupt (CPUState
*env
)
3006 powerpc_excp(env
, env
->excp_model
, env
->exception_index
);
3009 void ppc_hw_interrupt (CPUPPCState
*env
)
3014 qemu_log_mask(CPU_LOG_INT
, "%s: %p pending %08x req %08x me %d ee %d\n",
3015 __func__
, env
, env
->pending_interrupts
,
3016 env
->interrupt_request
, (int)msr_me
, (int)msr_ee
);
3018 /* External reset */
3019 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_RESET
)) {
3020 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_RESET
);
3021 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_RESET
);
3024 /* Machine check exception */
3025 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_MCK
)) {
3026 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_MCK
);
3027 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_MCHECK
);
3031 /* External debug exception */
3032 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DEBUG
)) {
3033 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DEBUG
);
3034 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DEBUG
);
3039 /* XXX: find a suitable condition to enable the hypervisor mode */
3040 hdice
= env
->spr
[SPR_LPCR
] & 1;
3044 if ((msr_ee
!= 0 || msr_hv
== 0 || msr_pr
!= 0) && hdice
!= 0) {
3045 /* Hypervisor decrementer exception */
3046 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_HDECR
)) {
3047 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_HDECR
);
3048 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_HDECR
);
3053 /* External critical interrupt */
3054 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CEXT
)) {
3055 /* Taking a critical external interrupt does not clear the external
3056 * critical interrupt status
3059 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CEXT
);
3061 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_CRITICAL
);
3066 /* Watchdog timer on embedded PowerPC */
3067 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_WDT
)) {
3068 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_WDT
);
3069 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_WDT
);
3072 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CDOORBELL
)) {
3073 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CDOORBELL
);
3074 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORCI
);
3077 /* Fixed interval timer on embedded PowerPC */
3078 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_FIT
)) {
3079 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_FIT
);
3080 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_FIT
);
3083 /* Programmable interval timer on embedded PowerPC */
3084 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PIT
)) {
3085 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PIT
);
3086 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PIT
);
3089 /* Decrementer exception */
3090 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DECR
)) {
3091 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DECR
);
3092 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DECR
);
3095 /* External interrupt */
3096 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_EXT
)) {
3097 /* Taking an external interrupt does not clear the external
3101 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_EXT
);
3103 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_EXTERNAL
);
3106 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DOORBELL
)) {
3107 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DOORBELL
);
3108 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORI
);
3111 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PERFM
)) {
3112 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PERFM
);
3113 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PERFM
);
3116 /* Thermal interrupt */
3117 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_THERM
)) {
3118 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_THERM
);
3119 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_THERM
);
3124 #endif /* !CONFIG_USER_ONLY */
3126 void cpu_dump_rfi (target_ulong RA
, target_ulong msr
)
3128 qemu_log("Return from exception at " TARGET_FMT_lx
" with flags "
3129 TARGET_FMT_lx
"\n", RA
, msr
);
3132 void cpu_reset(CPUPPCState
*env
)
3136 if (qemu_loglevel_mask(CPU_LOG_RESET
)) {
3137 qemu_log("CPU Reset (CPU %d)\n", env
->cpu_index
);
3138 log_cpu_state(env
, 0);
3141 msr
= (target_ulong
)0;
3143 /* XXX: find a suitable condition to enable the hypervisor mode */
3144 msr
|= (target_ulong
)MSR_HVB
;
3146 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
3147 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
3148 msr
|= (target_ulong
)1 << MSR_EP
;
3149 #if defined (DO_SINGLE_STEP) && 0
3150 /* Single step trace mode */
3151 msr
|= (target_ulong
)1 << MSR_SE
;
3152 msr
|= (target_ulong
)1 << MSR_BE
;
3154 #if defined(CONFIG_USER_ONLY)
3155 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
3156 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
3157 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
3158 msr
|= (target_ulong
)1 << MSR_PR
;
3160 env
->excp_prefix
= env
->hreset_excp_prefix
;
3161 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
3162 if (env
->mmu_model
!= POWERPC_MMU_REAL
)
3163 ppc_tlb_invalidate_all(env
);
3165 env
->msr
= msr
& env
->msr_mask
;
3166 #if defined(TARGET_PPC64)
3167 if (env
->mmu_model
& POWERPC_MMU_64
)
3168 env
->msr
|= (1ULL << MSR_SF
);
3170 hreg_compute_hflags(env
);
3171 env
->reserve_addr
= (target_ulong
)-1ULL;
3172 /* Be sure no exception or interrupt is pending */
3173 env
->pending_interrupts
= 0;
3174 env
->exception_index
= POWERPC_EXCP_NONE
;
3175 env
->error_code
= 0;
3176 /* Flush all TLBs */
3180 CPUPPCState
*cpu_ppc_init (const char *cpu_model
)
3183 const ppc_def_t
*def
;
3185 def
= cpu_ppc_find_by_name(cpu_model
);
3189 env
= g_malloc0(sizeof(CPUPPCState
));
3191 if (tcg_enabled()) {
3192 ppc_translate_init();
3194 /* Adjust cpu index for SMT */
3195 #if !defined(CONFIG_USER_ONLY)
3196 if (kvm_enabled()) {
3197 int smt
= kvmppc_smt_threads();
3199 env
->cpu_index
= (env
->cpu_index
/ smp_threads
)*smt
3200 + (env
->cpu_index
% smp_threads
);
3202 #endif /* !CONFIG_USER_ONLY */
3203 env
->cpu_model_str
= cpu_model
;
3204 cpu_ppc_register_internal(env
, def
);
3206 qemu_init_vcpu(env
);
3211 void cpu_ppc_close (CPUPPCState
*env
)
3213 /* Should also remove all opcode tables... */