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"
33 //#define DEBUG_SOFTWARE_TLB
34 //#define DUMP_PAGE_TABLES
35 //#define DEBUG_EXCEPTIONS
36 //#define FLUSH_ALL_TLBS
39 # define LOG_MMU(...) qemu_log(__VA_ARGS__)
40 # define LOG_MMU_STATE(env) log_cpu_state((env), 0)
42 # define LOG_MMU(...) do { } while (0)
43 # define LOG_MMU_STATE(...) do { } while (0)
47 #ifdef DEBUG_SOFTWARE_TLB
48 # define LOG_SWTLB(...) qemu_log(__VA_ARGS__)
50 # define LOG_SWTLB(...) do { } while (0)
54 # define LOG_BATS(...) qemu_log(__VA_ARGS__)
56 # define LOG_BATS(...) do { } while (0)
60 # define LOG_SLB(...) qemu_log(__VA_ARGS__)
62 # define LOG_SLB(...) do { } while (0)
65 #ifdef DEBUG_EXCEPTIONS
66 # define LOG_EXCP(...) qemu_log(__VA_ARGS__)
68 # define LOG_EXCP(...) do { } while (0)
71 /*****************************************************************************/
72 /* PowerPC Hypercall emulation */
74 void (*cpu_ppc_hypercall
)(CPUState
*);
76 /*****************************************************************************/
77 /* PowerPC MMU emulation */
79 #if defined(CONFIG_USER_ONLY)
80 int cpu_ppc_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
83 int exception
, error_code
;
86 exception
= POWERPC_EXCP_ISI
;
87 error_code
= 0x40000000;
89 exception
= POWERPC_EXCP_DSI
;
90 error_code
= 0x40000000;
92 error_code
|= 0x02000000;
93 env
->spr
[SPR_DAR
] = address
;
94 env
->spr
[SPR_DSISR
] = error_code
;
96 env
->exception_index
= exception
;
97 env
->error_code
= error_code
;
103 /* Common routines used by software and hardware TLBs emulation */
104 static inline int pte_is_valid(target_ulong pte0
)
106 return pte0
& 0x80000000 ? 1 : 0;
109 static inline void pte_invalidate(target_ulong
*pte0
)
111 *pte0
&= ~0x80000000;
114 #if defined(TARGET_PPC64)
115 static inline int pte64_is_valid(target_ulong pte0
)
117 return pte0
& 0x0000000000000001ULL
? 1 : 0;
120 static inline void pte64_invalidate(target_ulong
*pte0
)
122 *pte0
&= ~0x0000000000000001ULL
;
126 #define PTE_PTEM_MASK 0x7FFFFFBF
127 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
128 #if defined(TARGET_PPC64)
129 #define PTE64_PTEM_MASK 0xFFFFFFFFFFFFFF80ULL
130 #define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F)
133 static inline int pp_check(int key
, int pp
, int nx
)
137 /* Compute access rights */
138 /* When pp is 3/7, the result is undefined. Set it to noaccess */
145 access
|= PAGE_WRITE
;
163 access
= PAGE_READ
| PAGE_WRITE
;
173 static inline int check_prot(int prot
, int rw
, int access_type
)
177 if (access_type
== ACCESS_CODE
) {
178 if (prot
& PAGE_EXEC
)
183 if (prot
& PAGE_WRITE
)
188 if (prot
& PAGE_READ
)
197 static inline int _pte_check(mmu_ctx_t
*ctx
, int is_64b
, target_ulong pte0
,
198 target_ulong pte1
, int h
, int rw
, int type
)
200 target_ulong ptem
, mmask
;
201 int access
, ret
, pteh
, ptev
, pp
;
204 /* Check validity and table match */
205 #if defined(TARGET_PPC64)
207 ptev
= pte64_is_valid(pte0
);
208 pteh
= (pte0
>> 1) & 1;
212 ptev
= pte_is_valid(pte0
);
213 pteh
= (pte0
>> 6) & 1;
215 if (ptev
&& h
== pteh
) {
216 /* Check vsid & api */
217 #if defined(TARGET_PPC64)
219 ptem
= pte0
& PTE64_PTEM_MASK
;
220 mmask
= PTE64_CHECK_MASK
;
221 pp
= (pte1
& 0x00000003) | ((pte1
>> 61) & 0x00000004);
222 ctx
->nx
= (pte1
>> 2) & 1; /* No execute bit */
223 ctx
->nx
|= (pte1
>> 3) & 1; /* Guarded bit */
227 ptem
= pte0
& PTE_PTEM_MASK
;
228 mmask
= PTE_CHECK_MASK
;
229 pp
= pte1
& 0x00000003;
231 if (ptem
== ctx
->ptem
) {
232 if (ctx
->raddr
!= (target_phys_addr_t
)-1ULL) {
233 /* all matches should have equal RPN, WIMG & PP */
234 if ((ctx
->raddr
& mmask
) != (pte1
& mmask
)) {
235 qemu_log("Bad RPN/WIMG/PP\n");
239 /* Compute access rights */
240 access
= pp_check(ctx
->key
, pp
, ctx
->nx
);
241 /* Keep the matching PTE informations */
244 ret
= check_prot(ctx
->prot
, rw
, type
);
247 LOG_MMU("PTE access granted !\n");
249 /* Access right violation */
250 LOG_MMU("PTE access rejected\n");
258 static inline int pte32_check(mmu_ctx_t
*ctx
, target_ulong pte0
,
259 target_ulong pte1
, int h
, int rw
, int type
)
261 return _pte_check(ctx
, 0, pte0
, pte1
, h
, rw
, type
);
264 #if defined(TARGET_PPC64)
265 static inline int pte64_check(mmu_ctx_t
*ctx
, target_ulong pte0
,
266 target_ulong pte1
, int h
, int rw
, int type
)
268 return _pte_check(ctx
, 1, pte0
, pte1
, h
, rw
, type
);
272 static inline int pte_update_flags(mmu_ctx_t
*ctx
, target_ulong
*pte1p
,
277 /* Update page flags */
278 if (!(*pte1p
& 0x00000100)) {
279 /* Update accessed flag */
280 *pte1p
|= 0x00000100;
283 if (!(*pte1p
& 0x00000080)) {
284 if (rw
== 1 && ret
== 0) {
285 /* Update changed flag */
286 *pte1p
|= 0x00000080;
289 /* Force page fault for first write access */
290 ctx
->prot
&= ~PAGE_WRITE
;
297 /* Software driven TLB helpers */
298 static inline int ppc6xx_tlb_getnum(CPUState
*env
, target_ulong eaddr
, int way
,
303 /* Select TLB num in a way from address */
304 nr
= (eaddr
>> TARGET_PAGE_BITS
) & (env
->tlb_per_way
- 1);
306 nr
+= env
->tlb_per_way
* way
;
307 /* 6xx have separate TLBs for instructions and data */
308 if (is_code
&& env
->id_tlbs
== 1)
314 static inline void ppc6xx_tlb_invalidate_all(CPUState
*env
)
319 //LOG_SWTLB("Invalidate all TLBs\n");
320 /* Invalidate all defined software TLB */
322 if (env
->id_tlbs
== 1)
324 for (nr
= 0; nr
< max
; nr
++) {
325 tlb
= &env
->tlb
.tlb6
[nr
];
326 pte_invalidate(&tlb
->pte0
);
331 static inline void __ppc6xx_tlb_invalidate_virt(CPUState
*env
,
333 int is_code
, int match_epn
)
335 #if !defined(FLUSH_ALL_TLBS)
339 /* Invalidate ITLB + DTLB, all ways */
340 for (way
= 0; way
< env
->nb_ways
; way
++) {
341 nr
= ppc6xx_tlb_getnum(env
, eaddr
, way
, is_code
);
342 tlb
= &env
->tlb
.tlb6
[nr
];
343 if (pte_is_valid(tlb
->pte0
) && (match_epn
== 0 || eaddr
== tlb
->EPN
)) {
344 LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx
"\n", nr
,
346 pte_invalidate(&tlb
->pte0
);
347 tlb_flush_page(env
, tlb
->EPN
);
351 /* XXX: PowerPC specification say this is valid as well */
352 ppc6xx_tlb_invalidate_all(env
);
356 static inline void ppc6xx_tlb_invalidate_virt(CPUState
*env
,
357 target_ulong eaddr
, int is_code
)
359 __ppc6xx_tlb_invalidate_virt(env
, eaddr
, is_code
, 0);
362 void ppc6xx_tlb_store (CPUState
*env
, target_ulong EPN
, int way
, int is_code
,
363 target_ulong pte0
, target_ulong pte1
)
368 nr
= ppc6xx_tlb_getnum(env
, EPN
, way
, is_code
);
369 tlb
= &env
->tlb
.tlb6
[nr
];
370 LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx
" PTE0 " TARGET_FMT_lx
371 " PTE1 " TARGET_FMT_lx
"\n", nr
, env
->nb_tlb
, EPN
, pte0
, pte1
);
372 /* Invalidate any pending reference in Qemu for this virtual address */
373 __ppc6xx_tlb_invalidate_virt(env
, EPN
, is_code
, 1);
377 /* Store last way for LRU mechanism */
381 static inline int ppc6xx_tlb_check(CPUState
*env
, mmu_ctx_t
*ctx
,
382 target_ulong eaddr
, int rw
, int access_type
)
389 ret
= -1; /* No TLB found */
390 for (way
= 0; way
< env
->nb_ways
; way
++) {
391 nr
= ppc6xx_tlb_getnum(env
, eaddr
, way
,
392 access_type
== ACCESS_CODE
? 1 : 0);
393 tlb
= &env
->tlb
.tlb6
[nr
];
394 /* This test "emulates" the PTE index match for hardware TLBs */
395 if ((eaddr
& TARGET_PAGE_MASK
) != tlb
->EPN
) {
396 LOG_SWTLB("TLB %d/%d %s [" TARGET_FMT_lx
" " TARGET_FMT_lx
397 "] <> " TARGET_FMT_lx
"\n", nr
, env
->nb_tlb
,
398 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
399 tlb
->EPN
, tlb
->EPN
+ TARGET_PAGE_SIZE
, eaddr
);
402 LOG_SWTLB("TLB %d/%d %s " TARGET_FMT_lx
" <> " TARGET_FMT_lx
" "
403 TARGET_FMT_lx
" %c %c\n", nr
, env
->nb_tlb
,
404 pte_is_valid(tlb
->pte0
) ? "valid" : "inval",
405 tlb
->EPN
, eaddr
, tlb
->pte1
,
406 rw
? 'S' : 'L', access_type
== ACCESS_CODE
? 'I' : 'D');
407 switch (pte32_check(ctx
, tlb
->pte0
, tlb
->pte1
, 0, rw
, access_type
)) {
409 /* TLB inconsistency */
412 /* Access violation */
422 /* XXX: we should go on looping to check all TLBs consistency
423 * but we can speed-up the whole thing as the
424 * result would be undefined if TLBs are not consistent.
433 LOG_SWTLB("found TLB at addr " TARGET_FMT_plx
" prot=%01x ret=%d\n",
434 ctx
->raddr
& TARGET_PAGE_MASK
, ctx
->prot
, ret
);
435 /* Update page flags */
436 pte_update_flags(ctx
, &env
->tlb
.tlb6
[best
].pte1
, ret
, rw
);
442 /* Perform BAT hit & translation */
443 static inline void bat_size_prot(CPUState
*env
, target_ulong
*blp
, int *validp
,
444 int *protp
, target_ulong
*BATu
,
450 bl
= (*BATu
& 0x00001FFC) << 15;
453 if (((msr_pr
== 0) && (*BATu
& 0x00000002)) ||
454 ((msr_pr
!= 0) && (*BATu
& 0x00000001))) {
456 pp
= *BATl
& 0x00000003;
458 prot
= PAGE_READ
| PAGE_EXEC
;
468 static inline void bat_601_size_prot(CPUState
*env
, target_ulong
*blp
,
469 int *validp
, int *protp
,
470 target_ulong
*BATu
, target_ulong
*BATl
)
473 int key
, pp
, valid
, prot
;
475 bl
= (*BATl
& 0x0000003F) << 17;
476 LOG_BATS("b %02x ==> bl " TARGET_FMT_lx
" msk " TARGET_FMT_lx
"\n",
477 (uint8_t)(*BATl
& 0x0000003F), bl
, ~bl
);
479 valid
= (*BATl
>> 6) & 1;
481 pp
= *BATu
& 0x00000003;
483 key
= (*BATu
>> 3) & 1;
485 key
= (*BATu
>> 2) & 1;
486 prot
= pp_check(key
, pp
, 0);
493 static inline int get_bat(CPUState
*env
, mmu_ctx_t
*ctx
, target_ulong
virtual,
496 target_ulong
*BATlt
, *BATut
, *BATu
, *BATl
;
497 target_ulong BEPIl
, BEPIu
, bl
;
501 LOG_BATS("%s: %cBAT v " TARGET_FMT_lx
"\n", __func__
,
502 type
== ACCESS_CODE
? 'I' : 'D', virtual);
505 BATlt
= env
->IBAT
[1];
506 BATut
= env
->IBAT
[0];
509 BATlt
= env
->DBAT
[1];
510 BATut
= env
->DBAT
[0];
513 for (i
= 0; i
< env
->nb_BATs
; i
++) {
516 BEPIu
= *BATu
& 0xF0000000;
517 BEPIl
= *BATu
& 0x0FFE0000;
518 if (unlikely(env
->mmu_model
== POWERPC_MMU_601
)) {
519 bat_601_size_prot(env
, &bl
, &valid
, &prot
, BATu
, BATl
);
521 bat_size_prot(env
, &bl
, &valid
, &prot
, BATu
, BATl
);
523 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx
" BATu " TARGET_FMT_lx
524 " BATl " TARGET_FMT_lx
"\n", __func__
,
525 type
== ACCESS_CODE
? 'I' : 'D', i
, virtual, *BATu
, *BATl
);
526 if ((virtual & 0xF0000000) == BEPIu
&&
527 ((virtual & 0x0FFE0000) & ~bl
) == BEPIl
) {
530 /* Get physical address */
531 ctx
->raddr
= (*BATl
& 0xF0000000) |
532 ((virtual & 0x0FFE0000 & bl
) | (*BATl
& 0x0FFE0000)) |
533 (virtual & 0x0001F000);
534 /* Compute access rights */
536 ret
= check_prot(ctx
->prot
, rw
, type
);
538 LOG_BATS("BAT %d match: r " TARGET_FMT_plx
" prot=%c%c\n",
539 i
, ctx
->raddr
, ctx
->prot
& PAGE_READ
? 'R' : '-',
540 ctx
->prot
& PAGE_WRITE
? 'W' : '-');
546 #if defined(DEBUG_BATS)
547 if (qemu_log_enabled()) {
548 LOG_BATS("no BAT match for " TARGET_FMT_lx
":\n", virtual);
549 for (i
= 0; i
< 4; i
++) {
552 BEPIu
= *BATu
& 0xF0000000;
553 BEPIl
= *BATu
& 0x0FFE0000;
554 bl
= (*BATu
& 0x00001FFC) << 15;
555 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx
" BATu " TARGET_FMT_lx
556 " BATl " TARGET_FMT_lx
"\n\t" TARGET_FMT_lx
" "
557 TARGET_FMT_lx
" " TARGET_FMT_lx
"\n",
558 __func__
, type
== ACCESS_CODE
? 'I' : 'D', i
, virtual,
559 *BATu
, *BATl
, BEPIu
, BEPIl
, bl
);
568 static inline target_phys_addr_t
get_pteg_offset(CPUState
*env
,
569 target_phys_addr_t hash
,
572 return (hash
* pte_size
* 8) & env
->htab_mask
;
575 /* PTE table lookup */
576 static inline int _find_pte(CPUState
*env
, mmu_ctx_t
*ctx
, int is_64b
, int h
,
577 int rw
, int type
, int target_page_bits
)
579 target_phys_addr_t pteg_off
;
580 target_ulong pte0
, pte1
;
584 ret
= -1; /* No entry found */
585 pteg_off
= get_pteg_offset(env
, ctx
->hash
[h
],
586 is_64b
? HASH_PTE_SIZE_64
: HASH_PTE_SIZE_32
);
587 for (i
= 0; i
< 8; i
++) {
588 #if defined(TARGET_PPC64)
590 if (env
->external_htab
) {
591 pte0
= ldq_p(env
->external_htab
+ pteg_off
+ (i
* 16));
592 pte1
= ldq_p(env
->external_htab
+ pteg_off
+ (i
* 16) + 8);
594 pte0
= ldq_phys(env
->htab_base
+ pteg_off
+ (i
* 16));
595 pte1
= ldq_phys(env
->htab_base
+ pteg_off
+ (i
* 16) + 8);
598 /* We have a TLB that saves 4K pages, so let's
599 * split a huge page to 4k chunks */
600 if (target_page_bits
!= TARGET_PAGE_BITS
)
601 pte1
|= (ctx
->eaddr
& (( 1 << target_page_bits
) - 1))
604 r
= pte64_check(ctx
, pte0
, pte1
, h
, rw
, type
);
605 LOG_MMU("Load pte from " TARGET_FMT_lx
" => " TARGET_FMT_lx
" "
606 TARGET_FMT_lx
" %d %d %d " TARGET_FMT_lx
"\n",
607 pteg_off
+ (i
* 16), pte0
, pte1
, (int)(pte0
& 1), h
,
608 (int)((pte0
>> 1) & 1), ctx
->ptem
);
612 if (env
->external_htab
) {
613 pte0
= ldl_p(env
->external_htab
+ pteg_off
+ (i
* 8));
614 pte1
= ldl_p(env
->external_htab
+ pteg_off
+ (i
* 8) + 4);
616 pte0
= ldl_phys(env
->htab_base
+ pteg_off
+ (i
* 8));
617 pte1
= ldl_phys(env
->htab_base
+ pteg_off
+ (i
* 8) + 4);
619 r
= pte32_check(ctx
, pte0
, pte1
, h
, rw
, type
);
620 LOG_MMU("Load pte from " TARGET_FMT_lx
" => " TARGET_FMT_lx
" "
621 TARGET_FMT_lx
" %d %d %d " TARGET_FMT_lx
"\n",
622 pteg_off
+ (i
* 8), pte0
, pte1
, (int)(pte0
>> 31), h
,
623 (int)((pte0
>> 6) & 1), ctx
->ptem
);
627 /* PTE inconsistency */
630 /* Access violation */
640 /* XXX: we should go on looping to check all PTEs consistency
641 * but if we can speed-up the whole thing as the
642 * result would be undefined if PTEs are not consistent.
651 LOG_MMU("found PTE at addr " TARGET_FMT_lx
" prot=%01x ret=%d\n",
652 ctx
->raddr
, ctx
->prot
, ret
);
653 /* Update page flags */
655 if (pte_update_flags(ctx
, &pte1
, ret
, rw
) == 1) {
656 #if defined(TARGET_PPC64)
658 if (env
->external_htab
) {
659 stq_p(env
->external_htab
+ pteg_off
+ (good
* 16) + 8,
662 stq_phys_notdirty(env
->htab_base
+ pteg_off
+
663 (good
* 16) + 8, pte1
);
668 if (env
->external_htab
) {
669 stl_p(env
->external_htab
+ pteg_off
+ (good
* 8) + 4,
672 stl_phys_notdirty(env
->htab_base
+ pteg_off
+
673 (good
* 8) + 4, pte1
);
682 static inline int find_pte(CPUState
*env
, mmu_ctx_t
*ctx
, int h
, int rw
,
683 int type
, int target_page_bits
)
685 #if defined(TARGET_PPC64)
686 if (env
->mmu_model
& POWERPC_MMU_64
)
687 return _find_pte(env
, ctx
, 1, h
, rw
, type
, target_page_bits
);
690 return _find_pte(env
, ctx
, 0, h
, rw
, type
, target_page_bits
);
693 #if defined(TARGET_PPC64)
694 static inline ppc_slb_t
*slb_lookup(CPUPPCState
*env
, target_ulong eaddr
)
696 uint64_t esid_256M
, esid_1T
;
699 LOG_SLB("%s: eaddr " TARGET_FMT_lx
"\n", __func__
, eaddr
);
701 esid_256M
= (eaddr
& SEGMENT_MASK_256M
) | SLB_ESID_V
;
702 esid_1T
= (eaddr
& SEGMENT_MASK_1T
) | SLB_ESID_V
;
704 for (n
= 0; n
< env
->slb_nr
; n
++) {
705 ppc_slb_t
*slb
= &env
->slb
[n
];
707 LOG_SLB("%s: slot %d %016" PRIx64
" %016"
708 PRIx64
"\n", __func__
, n
, slb
->esid
, slb
->vsid
);
709 /* We check for 1T matches on all MMUs here - if the MMU
710 * doesn't have 1T segment support, we will have prevented 1T
711 * entries from being inserted in the slbmte code. */
712 if (((slb
->esid
== esid_256M
) &&
713 ((slb
->vsid
& SLB_VSID_B
) == SLB_VSID_B_256M
))
714 || ((slb
->esid
== esid_1T
) &&
715 ((slb
->vsid
& SLB_VSID_B
) == SLB_VSID_B_1T
))) {
723 void ppc_slb_invalidate_all (CPUPPCState
*env
)
725 int n
, do_invalidate
;
728 /* XXX: Warning: slbia never invalidates the first segment */
729 for (n
= 1; n
< env
->slb_nr
; n
++) {
730 ppc_slb_t
*slb
= &env
->slb
[n
];
732 if (slb
->esid
& SLB_ESID_V
) {
733 slb
->esid
&= ~SLB_ESID_V
;
734 /* XXX: given the fact that segment size is 256 MB or 1TB,
735 * and we still don't have a tlb_flush_mask(env, n, mask)
736 * in Qemu, we just invalidate all TLBs
745 void ppc_slb_invalidate_one (CPUPPCState
*env
, uint64_t T0
)
749 slb
= slb_lookup(env
, T0
);
754 if (slb
->esid
& SLB_ESID_V
) {
755 slb
->esid
&= ~SLB_ESID_V
;
757 /* XXX: given the fact that segment size is 256 MB or 1TB,
758 * and we still don't have a tlb_flush_mask(env, n, mask)
759 * in Qemu, we just invalidate all TLBs
765 int ppc_store_slb (CPUPPCState
*env
, target_ulong rb
, target_ulong rs
)
767 int slot
= rb
& 0xfff;
768 ppc_slb_t
*slb
= &env
->slb
[slot
];
770 if (rb
& (0x1000 - env
->slb_nr
)) {
771 return -1; /* Reserved bits set or slot too high */
773 if (rs
& (SLB_VSID_B
& ~SLB_VSID_B_1T
)) {
774 return -1; /* Bad segment size */
776 if ((rs
& SLB_VSID_B
) && !(env
->mmu_model
& POWERPC_MMU_1TSEG
)) {
777 return -1; /* 1T segment on MMU that doesn't support it */
780 /* Mask out the slot number as we store the entry */
781 slb
->esid
= rb
& (SLB_ESID_ESID
| SLB_ESID_V
);
784 LOG_SLB("%s: %d " TARGET_FMT_lx
" - " TARGET_FMT_lx
" => %016" PRIx64
785 " %016" PRIx64
"\n", __func__
, slot
, rb
, rs
,
786 slb
->esid
, slb
->vsid
);
791 int ppc_load_slb_esid (CPUPPCState
*env
, target_ulong rb
, target_ulong
*rt
)
793 int slot
= rb
& 0xfff;
794 ppc_slb_t
*slb
= &env
->slb
[slot
];
796 if (slot
>= env
->slb_nr
) {
804 int ppc_load_slb_vsid (CPUPPCState
*env
, target_ulong rb
, target_ulong
*rt
)
806 int slot
= rb
& 0xfff;
807 ppc_slb_t
*slb
= &env
->slb
[slot
];
809 if (slot
>= env
->slb_nr
) {
816 #endif /* defined(TARGET_PPC64) */
818 /* Perform segment based translation */
819 static inline int get_segment(CPUState
*env
, mmu_ctx_t
*ctx
,
820 target_ulong eaddr
, int rw
, int type
)
822 target_phys_addr_t hash
;
824 int ds
, pr
, target_page_bits
;
829 #if defined(TARGET_PPC64)
830 if (env
->mmu_model
& POWERPC_MMU_64
) {
832 target_ulong pageaddr
;
835 LOG_MMU("Check SLBs\n");
836 slb
= slb_lookup(env
, eaddr
);
841 if (slb
->vsid
& SLB_VSID_B
) {
842 vsid
= (slb
->vsid
& SLB_VSID_VSID
) >> SLB_VSID_SHIFT_1T
;
845 vsid
= (slb
->vsid
& SLB_VSID_VSID
) >> SLB_VSID_SHIFT
;
849 target_page_bits
= (slb
->vsid
& SLB_VSID_L
)
850 ? TARGET_PAGE_BITS_16M
: TARGET_PAGE_BITS
;
851 ctx
->key
= !!(pr
? (slb
->vsid
& SLB_VSID_KP
)
852 : (slb
->vsid
& SLB_VSID_KS
));
854 ctx
->nx
= !!(slb
->vsid
& SLB_VSID_N
);
856 pageaddr
= eaddr
& ((1ULL << segment_bits
)
857 - (1ULL << target_page_bits
));
858 if (slb
->vsid
& SLB_VSID_B
) {
859 hash
= vsid
^ (vsid
<< 25) ^ (pageaddr
>> target_page_bits
);
861 hash
= vsid
^ (pageaddr
>> target_page_bits
);
863 /* Only 5 bits of the page index are used in the AVPN */
864 ctx
->ptem
= (slb
->vsid
& SLB_VSID_PTEM
) |
865 ((pageaddr
>> 16) & ((1ULL << segment_bits
) - 0x80));
867 #endif /* defined(TARGET_PPC64) */
869 target_ulong sr
, pgidx
;
871 sr
= env
->sr
[eaddr
>> 28];
872 ctx
->key
= (((sr
& 0x20000000) && (pr
!= 0)) ||
873 ((sr
& 0x40000000) && (pr
== 0))) ? 1 : 0;
874 ds
= sr
& 0x80000000 ? 1 : 0;
875 ctx
->nx
= sr
& 0x10000000 ? 1 : 0;
876 vsid
= sr
& 0x00FFFFFF;
877 target_page_bits
= TARGET_PAGE_BITS
;
878 LOG_MMU("Check segment v=" TARGET_FMT_lx
" %d " TARGET_FMT_lx
" nip="
879 TARGET_FMT_lx
" lr=" TARGET_FMT_lx
880 " ir=%d dr=%d pr=%d %d t=%d\n",
881 eaddr
, (int)(eaddr
>> 28), sr
, env
->nip
, env
->lr
, (int)msr_ir
,
882 (int)msr_dr
, pr
!= 0 ? 1 : 0, rw
, type
);
883 pgidx
= (eaddr
& ~SEGMENT_MASK_256M
) >> target_page_bits
;
885 ctx
->ptem
= (vsid
<< 7) | (pgidx
>> 10);
887 LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx
"\n",
888 ctx
->key
, ds
, ctx
->nx
, vsid
);
891 /* Check if instruction fetch is allowed, if needed */
892 if (type
!= ACCESS_CODE
|| ctx
->nx
== 0) {
893 /* Page address translation */
894 LOG_MMU("htab_base " TARGET_FMT_plx
" htab_mask " TARGET_FMT_plx
895 " hash " TARGET_FMT_plx
"\n",
896 env
->htab_base
, env
->htab_mask
, hash
);
898 ctx
->hash
[1] = ~hash
;
900 /* Initialize real address with an invalid value */
901 ctx
->raddr
= (target_phys_addr_t
)-1ULL;
902 if (unlikely(env
->mmu_model
== POWERPC_MMU_SOFT_6xx
||
903 env
->mmu_model
== POWERPC_MMU_SOFT_74xx
)) {
904 /* Software TLB search */
905 ret
= ppc6xx_tlb_check(env
, ctx
, eaddr
, rw
, type
);
907 LOG_MMU("0 htab=" TARGET_FMT_plx
"/" TARGET_FMT_plx
908 " vsid=" TARGET_FMT_lx
" ptem=" TARGET_FMT_lx
909 " hash=" TARGET_FMT_plx
"\n",
910 env
->htab_base
, env
->htab_mask
, vsid
, ctx
->ptem
,
912 /* Primary table lookup */
913 ret
= find_pte(env
, ctx
, 0, rw
, type
, target_page_bits
);
915 /* Secondary table lookup */
916 if (eaddr
!= 0xEFFFFFFF)
917 LOG_MMU("1 htab=" TARGET_FMT_plx
"/" TARGET_FMT_plx
918 " vsid=" TARGET_FMT_lx
" api=" TARGET_FMT_lx
919 " hash=" TARGET_FMT_plx
"\n", env
->htab_base
,
920 env
->htab_mask
, vsid
, ctx
->ptem
, ctx
->hash
[1]);
921 ret2
= find_pte(env
, ctx
, 1, rw
, type
,
927 #if defined (DUMP_PAGE_TABLES)
928 if (qemu_log_enabled()) {
929 target_phys_addr_t curaddr
;
930 uint32_t a0
, a1
, a2
, a3
;
931 qemu_log("Page table: " TARGET_FMT_plx
" len " TARGET_FMT_plx
932 "\n", sdr
, mask
+ 0x80);
933 for (curaddr
= sdr
; curaddr
< (sdr
+ mask
+ 0x80);
935 a0
= ldl_phys(curaddr
);
936 a1
= ldl_phys(curaddr
+ 4);
937 a2
= ldl_phys(curaddr
+ 8);
938 a3
= ldl_phys(curaddr
+ 12);
939 if (a0
!= 0 || a1
!= 0 || a2
!= 0 || a3
!= 0) {
940 qemu_log(TARGET_FMT_plx
": %08x %08x %08x %08x\n",
941 curaddr
, a0
, a1
, a2
, a3
);
947 LOG_MMU("No access allowed\n");
952 LOG_MMU("direct store...\n");
953 /* Direct-store segment : absolutely *BUGGY* for now */
955 /* Direct-store implies a 32-bit MMU.
956 * Check the Segment Register's bus unit ID (BUID).
958 sr
= env
->sr
[eaddr
>> 28];
959 if ((sr
& 0x1FF00000) >> 20 == 0x07f) {
960 /* Memory-forced I/O controller interface access */
961 /* If T=1 and BUID=x'07F', the 601 performs a memory access
962 * to SR[28-31] LA[4-31], bypassing all protection mechanisms.
964 ctx
->raddr
= ((sr
& 0xF) << 28) | (eaddr
& 0x0FFFFFFF);
965 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
971 /* Integer load/store : only access allowed */
974 /* No code fetch is allowed in direct-store areas */
977 /* Floating point load/store */
980 /* lwarx, ldarx or srwcx. */
983 /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
984 /* Should make the instruction do no-op.
985 * As it already do no-op, it's quite easy :-)
993 qemu_log("ERROR: instruction should not need "
994 "address translation\n");
997 if ((rw
== 1 || ctx
->key
!= 1) && (rw
== 0 || ctx
->key
!= 0)) {
1008 /* Generic TLB check function for embedded PowerPC implementations */
1009 int ppcemb_tlb_check(CPUState
*env
, ppcemb_tlb_t
*tlb
,
1010 target_phys_addr_t
*raddrp
,
1011 target_ulong address
, uint32_t pid
, int ext
,
1016 /* Check valid flag */
1017 if (!(tlb
->prot
& PAGE_VALID
)) {
1020 mask
= ~(tlb
->size
- 1);
1021 LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx
" PID %u <=> " TARGET_FMT_lx
1022 " " TARGET_FMT_lx
" %u %x\n", __func__
, i
, address
, pid
, tlb
->EPN
,
1023 mask
, (uint32_t)tlb
->PID
, tlb
->prot
);
1025 if (tlb
->PID
!= 0 && tlb
->PID
!= pid
)
1027 /* Check effective address */
1028 if ((address
& mask
) != tlb
->EPN
)
1030 *raddrp
= (tlb
->RPN
& mask
) | (address
& ~mask
);
1031 #if (TARGET_PHYS_ADDR_BITS >= 36)
1033 /* Extend the physical address to 36 bits */
1034 *raddrp
|= (target_phys_addr_t
)(tlb
->RPN
& 0xF) << 32;
1041 /* Generic TLB search function for PowerPC embedded implementations */
1042 int ppcemb_tlb_search (CPUPPCState
*env
, target_ulong address
, uint32_t pid
)
1045 target_phys_addr_t raddr
;
1048 /* Default return value is no match */
1050 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1051 tlb
= &env
->tlb
.tlbe
[i
];
1052 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
, pid
, 0, i
) == 0) {
1061 /* Helpers specific to PowerPC 40x implementations */
1062 static inline void ppc4xx_tlb_invalidate_all(CPUState
*env
)
1067 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1068 tlb
= &env
->tlb
.tlbe
[i
];
1069 tlb
->prot
&= ~PAGE_VALID
;
1074 static inline void ppc4xx_tlb_invalidate_virt(CPUState
*env
,
1075 target_ulong eaddr
, uint32_t pid
)
1077 #if !defined(FLUSH_ALL_TLBS)
1079 target_phys_addr_t raddr
;
1080 target_ulong page
, end
;
1083 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1084 tlb
= &env
->tlb
.tlbe
[i
];
1085 if (ppcemb_tlb_check(env
, tlb
, &raddr
, eaddr
, pid
, 0, i
) == 0) {
1086 end
= tlb
->EPN
+ tlb
->size
;
1087 for (page
= tlb
->EPN
; page
< end
; page
+= TARGET_PAGE_SIZE
)
1088 tlb_flush_page(env
, page
);
1089 tlb
->prot
&= ~PAGE_VALID
;
1094 ppc4xx_tlb_invalidate_all(env
);
1098 static int mmu40x_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1099 target_ulong address
, int rw
, int access_type
)
1102 target_phys_addr_t raddr
;
1103 int i
, ret
, zsel
, zpr
, pr
;
1106 raddr
= (target_phys_addr_t
)-1ULL;
1108 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1109 tlb
= &env
->tlb
.tlbe
[i
];
1110 if (ppcemb_tlb_check(env
, tlb
, &raddr
, address
,
1111 env
->spr
[SPR_40x_PID
], 0, i
) < 0)
1113 zsel
= (tlb
->attr
>> 4) & 0xF;
1114 zpr
= (env
->spr
[SPR_40x_ZPR
] >> (30 - (2 * zsel
))) & 0x3;
1115 LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1116 __func__
, i
, zsel
, zpr
, rw
, tlb
->attr
);
1117 /* Check execute enable bit */
1124 /* All accesses granted */
1125 ctx
->prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
1130 /* Raise Zone protection fault. */
1131 env
->spr
[SPR_40x_ESR
] = 1 << 22;
1139 /* Check from TLB entry */
1140 ctx
->prot
= tlb
->prot
;
1141 ret
= check_prot(ctx
->prot
, rw
, access_type
);
1143 env
->spr
[SPR_40x_ESR
] = 0;
1148 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1149 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1154 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1155 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1160 void store_40x_sler (CPUPPCState
*env
, uint32_t val
)
1162 /* XXX: TO BE FIXED */
1163 if (val
!= 0x00000000) {
1164 cpu_abort(env
, "Little-endian regions are not supported by now\n");
1166 env
->spr
[SPR_405_SLER
] = val
;
1169 static inline int mmubooke_check_tlb (CPUState
*env
, ppcemb_tlb_t
*tlb
,
1170 target_phys_addr_t
*raddr
, int *prot
,
1171 target_ulong address
, int rw
,
1172 int access_type
, int i
)
1176 if (ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1177 env
->spr
[SPR_BOOKE_PID
],
1178 !env
->nb_pids
, i
) >= 0) {
1182 if (env
->spr
[SPR_BOOKE_PID1
] &&
1183 ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1184 env
->spr
[SPR_BOOKE_PID1
], 0, i
) >= 0) {
1188 if (env
->spr
[SPR_BOOKE_PID2
] &&
1189 ppcemb_tlb_check(env
, tlb
, raddr
, address
,
1190 env
->spr
[SPR_BOOKE_PID2
], 0, i
) >= 0) {
1194 LOG_SWTLB("%s: TLB entry not found\n", __func__
);
1200 _prot
= tlb
->prot
& 0xF;
1202 _prot
= (tlb
->prot
>> 4) & 0xF;
1205 /* Check the address space */
1206 if (access_type
== ACCESS_CODE
) {
1207 if (msr_ir
!= (tlb
->attr
& 1)) {
1208 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1213 if (_prot
& PAGE_EXEC
) {
1214 LOG_SWTLB("%s: good TLB!\n", __func__
);
1218 LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__
, _prot
);
1221 if (msr_dr
!= (tlb
->attr
& 1)) {
1222 LOG_SWTLB("%s: AS doesn't match\n", __func__
);
1227 if ((!rw
&& _prot
& PAGE_READ
) || (rw
&& (_prot
& PAGE_WRITE
))) {
1228 LOG_SWTLB("%s: found TLB!\n", __func__
);
1232 LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__
, _prot
);
1239 static int mmubooke_get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
,
1240 target_ulong address
, int rw
,
1244 target_phys_addr_t raddr
;
1248 raddr
= (target_phys_addr_t
)-1ULL;
1249 for (i
= 0; i
< env
->nb_tlb
; i
++) {
1250 tlb
= &env
->tlb
.tlbe
[i
];
1251 ret
= mmubooke_check_tlb(env
, tlb
, &raddr
, &ctx
->prot
, address
, rw
,
1260 LOG_SWTLB("%s: access granted " TARGET_FMT_lx
" => " TARGET_FMT_plx
1261 " %d %d\n", __func__
, address
, ctx
->raddr
, ctx
->prot
,
1264 LOG_SWTLB("%s: access refused " TARGET_FMT_lx
" => " TARGET_FMT_plx
1265 " %d %d\n", __func__
, address
, raddr
, ctx
->prot
, ret
);
1271 void booke206_flush_tlb(CPUState
*env
, int flags
, const int check_iprot
)
1275 ppcmas_tlb_t
*tlb
= env
->tlb
.tlbm
;
1277 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1278 if (flags
& (1 << i
)) {
1279 tlb_size
= booke206_tlb_size(env
, i
);
1280 for (j
= 0; j
< tlb_size
; j
++) {
1281 if (!check_iprot
|| !(tlb
[j
].mas1
& MAS1_IPROT
)) {
1282 tlb
[j
].mas1
&= ~MAS1_VALID
;
1286 tlb
+= booke206_tlb_size(env
, i
);
1292 target_phys_addr_t
booke206_tlb_to_page_size(CPUState
*env
, ppcmas_tlb_t
*tlb
)
1295 int tlbn
= booke206_tlbm_to_tlbn(env
, tlb
);
1298 tlbncfg
= env
->spr
[SPR_BOOKE_TLB0CFG
+ tlbn
];
1300 if (tlbncfg
& TLBnCFG_AVAIL
) {
1301 tlbm_size
= (tlb
->mas1
& MAS1_TSIZE_MASK
) >> MAS1_TSIZE_SHIFT
;
1303 tlbm_size
= (tlbncfg
& TLBnCFG_MINSIZE
) >> TLBnCFG_MINSIZE_SHIFT
;
1307 return 1024ULL << tlbm_size
;
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 const char *book3e_tsize_to_str
[32] = {
1470 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
1471 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M",
1472 "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G",
1476 static void mmubooke206_dump_one_tlb(FILE *f
, fprintf_function cpu_fprintf
,
1477 CPUState
*env
, int tlbn
, int offset
,
1480 ppcmas_tlb_t
*entry
;
1483 cpu_fprintf(f
, "\nTLB%d:\n", tlbn
);
1484 cpu_fprintf(f
, "Effective Physical Size TID TS SRWX URWX WIMGE U0123\n");
1486 entry
= &env
->tlb
.tlbm
[offset
];
1487 for (i
= 0; i
< tlbsize
; i
++, entry
++) {
1488 target_phys_addr_t ea
, pa
, size
;
1491 if (!(entry
->mas1
& MAS1_VALID
)) {
1495 tsize
= (entry
->mas1
& MAS1_TSIZE_MASK
) >> MAS1_TSIZE_SHIFT
;
1496 size
= 1024ULL << tsize
;
1497 ea
= entry
->mas2
& ~(size
- 1);
1498 pa
= entry
->mas7_3
& ~(size
- 1);
1500 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",
1501 (uint64_t)ea
, (uint64_t)pa
,
1502 book3e_tsize_to_str
[tsize
],
1503 (entry
->mas1
& MAS1_TID_MASK
) >> MAS1_TID_SHIFT
,
1504 (entry
->mas1
& MAS1_TS
) >> MAS1_TS_SHIFT
,
1505 entry
->mas7_3
& MAS3_SR
? 'R' : '-',
1506 entry
->mas7_3
& MAS3_SW
? 'W' : '-',
1507 entry
->mas7_3
& MAS3_SX
? 'X' : '-',
1508 entry
->mas7_3
& MAS3_UR
? 'R' : '-',
1509 entry
->mas7_3
& MAS3_UW
? 'W' : '-',
1510 entry
->mas7_3
& MAS3_UX
? 'X' : '-',
1511 entry
->mas2
& MAS2_W
? 'W' : '-',
1512 entry
->mas2
& MAS2_I
? 'I' : '-',
1513 entry
->mas2
& MAS2_M
? 'M' : '-',
1514 entry
->mas2
& MAS2_G
? 'G' : '-',
1515 entry
->mas2
& MAS2_E
? 'E' : '-',
1516 entry
->mas7_3
& MAS3_U0
? '0' : '-',
1517 entry
->mas7_3
& MAS3_U1
? '1' : '-',
1518 entry
->mas7_3
& MAS3_U2
? '2' : '-',
1519 entry
->mas7_3
& MAS3_U3
? '3' : '-');
1523 static void mmubooke206_dump_mmu(FILE *f
, fprintf_function cpu_fprintf
,
1529 if (kvm_enabled() && !env
->kvm_sw_tlb
) {
1530 cpu_fprintf(f
, "Cannot access KVM TLB\n");
1534 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
1535 int size
= booke206_tlb_size(env
, i
);
1541 mmubooke206_dump_one_tlb(f
, cpu_fprintf
, env
, i
, offset
, size
);
1546 void dump_mmu(FILE *f
, fprintf_function cpu_fprintf
, CPUState
*env
)
1548 switch (env
->mmu_model
) {
1549 case POWERPC_MMU_BOOKE206
:
1550 mmubooke206_dump_mmu(f
, cpu_fprintf
, env
);
1553 cpu_fprintf(f
, "%s: unimplemented\n", __func__
);
1557 static inline int check_physical(CPUState
*env
, mmu_ctx_t
*ctx
,
1558 target_ulong eaddr
, int rw
)
1563 ctx
->prot
= PAGE_READ
| PAGE_EXEC
;
1565 switch (env
->mmu_model
) {
1566 case POWERPC_MMU_32B
:
1567 case POWERPC_MMU_601
:
1568 case POWERPC_MMU_SOFT_6xx
:
1569 case POWERPC_MMU_SOFT_74xx
:
1570 case POWERPC_MMU_SOFT_4xx
:
1571 case POWERPC_MMU_REAL
:
1572 case POWERPC_MMU_BOOKE
:
1573 ctx
->prot
|= PAGE_WRITE
;
1575 #if defined(TARGET_PPC64)
1576 case POWERPC_MMU_620
:
1577 case POWERPC_MMU_64B
:
1578 case POWERPC_MMU_2_06
:
1579 /* Real address are 60 bits long */
1580 ctx
->raddr
&= 0x0FFFFFFFFFFFFFFFULL
;
1581 ctx
->prot
|= PAGE_WRITE
;
1584 case POWERPC_MMU_SOFT_4xx_Z
:
1585 if (unlikely(msr_pe
!= 0)) {
1586 /* 403 family add some particular protections,
1587 * using PBL/PBU registers for accesses with no translation.
1590 /* Check PLB validity */
1591 (env
->pb
[0] < env
->pb
[1] &&
1592 /* and address in plb area */
1593 eaddr
>= env
->pb
[0] && eaddr
< env
->pb
[1]) ||
1594 (env
->pb
[2] < env
->pb
[3] &&
1595 eaddr
>= env
->pb
[2] && eaddr
< env
->pb
[3]) ? 1 : 0;
1596 if (in_plb
^ msr_px
) {
1597 /* Access in protected area */
1599 /* Access is not allowed */
1603 /* Read-write access is allowed */
1604 ctx
->prot
|= PAGE_WRITE
;
1608 case POWERPC_MMU_MPC8xx
:
1610 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1612 case POWERPC_MMU_BOOKE206
:
1613 cpu_abort(env
, "BookE 2.06 MMU doesn't have physical real mode\n");
1616 cpu_abort(env
, "Unknown or invalid MMU model\n");
1623 int get_physical_address (CPUState
*env
, mmu_ctx_t
*ctx
, target_ulong eaddr
,
1624 int rw
, int access_type
)
1629 qemu_log("%s\n", __func__
);
1631 if ((access_type
== ACCESS_CODE
&& msr_ir
== 0) ||
1632 (access_type
!= ACCESS_CODE
&& msr_dr
== 0)) {
1633 if (env
->mmu_model
== POWERPC_MMU_BOOKE
) {
1634 /* The BookE MMU always performs address translation. The
1635 IS and DS bits only affect the address space. */
1636 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1638 } else if (env
->mmu_model
== POWERPC_MMU_BOOKE206
) {
1639 ret
= mmubooke206_get_physical_address(env
, ctx
, eaddr
, rw
,
1642 /* No address translation. */
1643 ret
= check_physical(env
, ctx
, eaddr
, rw
);
1647 switch (env
->mmu_model
) {
1648 case POWERPC_MMU_32B
:
1649 case POWERPC_MMU_601
:
1650 case POWERPC_MMU_SOFT_6xx
:
1651 case POWERPC_MMU_SOFT_74xx
:
1652 /* Try to find a BAT */
1653 if (env
->nb_BATs
!= 0)
1654 ret
= get_bat(env
, ctx
, eaddr
, rw
, access_type
);
1655 #if defined(TARGET_PPC64)
1656 case POWERPC_MMU_620
:
1657 case POWERPC_MMU_64B
:
1658 case POWERPC_MMU_2_06
:
1661 /* We didn't match any BAT entry or don't have BATs */
1662 ret
= get_segment(env
, ctx
, eaddr
, rw
, access_type
);
1665 case POWERPC_MMU_SOFT_4xx
:
1666 case POWERPC_MMU_SOFT_4xx_Z
:
1667 ret
= mmu40x_get_physical_address(env
, ctx
, eaddr
,
1670 case POWERPC_MMU_BOOKE
:
1671 ret
= mmubooke_get_physical_address(env
, ctx
, eaddr
,
1674 case POWERPC_MMU_BOOKE206
:
1675 ret
= mmubooke206_get_physical_address(env
, ctx
, eaddr
, rw
,
1678 case POWERPC_MMU_MPC8xx
:
1680 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1682 case POWERPC_MMU_REAL
:
1683 cpu_abort(env
, "PowerPC in real mode do not do any translation\n");
1686 cpu_abort(env
, "Unknown or invalid MMU model\n");
1691 qemu_log("%s address " TARGET_FMT_lx
" => %d " TARGET_FMT_plx
"\n",
1692 __func__
, eaddr
, ret
, ctx
->raddr
);
1698 target_phys_addr_t
cpu_get_phys_page_debug (CPUState
*env
, target_ulong addr
)
1702 if (unlikely(get_physical_address(env
, &ctx
, addr
, 0, ACCESS_INT
) != 0))
1705 return ctx
.raddr
& TARGET_PAGE_MASK
;
1708 static void booke206_update_mas_tlb_miss(CPUState
*env
, target_ulong address
,
1711 env
->spr
[SPR_BOOKE_MAS0
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TLBSELD_MASK
;
1712 env
->spr
[SPR_BOOKE_MAS1
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TSIZED_MASK
;
1713 env
->spr
[SPR_BOOKE_MAS2
] = env
->spr
[SPR_BOOKE_MAS4
] & MAS4_WIMGED_MASK
;
1714 env
->spr
[SPR_BOOKE_MAS3
] = 0;
1715 env
->spr
[SPR_BOOKE_MAS6
] = 0;
1716 env
->spr
[SPR_BOOKE_MAS7
] = 0;
1719 if (((rw
== 2) && msr_ir
) || ((rw
!= 2) && msr_dr
)) {
1720 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_TS
;
1721 env
->spr
[SPR_BOOKE_MAS6
] |= MAS6_SAS
;
1724 env
->spr
[SPR_BOOKE_MAS1
] |= MAS1_VALID
;
1725 env
->spr
[SPR_BOOKE_MAS2
] |= address
& MAS2_EPN_MASK
;
1727 switch (env
->spr
[SPR_BOOKE_MAS4
] & MAS4_TIDSELD_PIDZ
) {
1728 case MAS4_TIDSELD_PID0
:
1729 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID
] << MAS1_TID_SHIFT
;
1731 case MAS4_TIDSELD_PID1
:
1732 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID1
] << MAS1_TID_SHIFT
;
1734 case MAS4_TIDSELD_PID2
:
1735 env
->spr
[SPR_BOOKE_MAS1
] |= env
->spr
[SPR_BOOKE_PID2
] << MAS1_TID_SHIFT
;
1739 env
->spr
[SPR_BOOKE_MAS6
] |= env
->spr
[SPR_BOOKE_PID
] << 16;
1741 /* next victim logic */
1742 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_ESEL_SHIFT
;
1744 env
->last_way
&= booke206_tlb_ways(env
, 0) - 1;
1745 env
->spr
[SPR_BOOKE_MAS0
] |= env
->last_way
<< MAS0_NV_SHIFT
;
1748 /* Perform address translation */
1749 int cpu_ppc_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
1759 access_type
= ACCESS_CODE
;
1762 access_type
= env
->access_type
;
1764 ret
= get_physical_address(env
, &ctx
, address
, rw
, access_type
);
1766 tlb_set_page(env
, address
& TARGET_PAGE_MASK
,
1767 ctx
.raddr
& TARGET_PAGE_MASK
, ctx
.prot
,
1768 mmu_idx
, TARGET_PAGE_SIZE
);
1770 } else if (ret
< 0) {
1772 if (access_type
== ACCESS_CODE
) {
1775 /* No matches in page tables or TLB */
1776 switch (env
->mmu_model
) {
1777 case POWERPC_MMU_SOFT_6xx
:
1778 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1779 env
->error_code
= 1 << 18;
1780 env
->spr
[SPR_IMISS
] = address
;
1781 env
->spr
[SPR_ICMP
] = 0x80000000 | ctx
.ptem
;
1783 case POWERPC_MMU_SOFT_74xx
:
1784 env
->exception_index
= POWERPC_EXCP_IFTLB
;
1786 case POWERPC_MMU_SOFT_4xx
:
1787 case POWERPC_MMU_SOFT_4xx_Z
:
1788 env
->exception_index
= POWERPC_EXCP_ITLB
;
1789 env
->error_code
= 0;
1790 env
->spr
[SPR_40x_DEAR
] = address
;
1791 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1793 case POWERPC_MMU_32B
:
1794 case POWERPC_MMU_601
:
1795 #if defined(TARGET_PPC64)
1796 case POWERPC_MMU_620
:
1797 case POWERPC_MMU_64B
:
1798 case POWERPC_MMU_2_06
:
1800 env
->exception_index
= POWERPC_EXCP_ISI
;
1801 env
->error_code
= 0x40000000;
1803 case POWERPC_MMU_BOOKE206
:
1804 booke206_update_mas_tlb_miss(env
, address
, rw
);
1806 case POWERPC_MMU_BOOKE
:
1807 env
->exception_index
= POWERPC_EXCP_ITLB
;
1808 env
->error_code
= 0;
1809 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1811 case POWERPC_MMU_MPC8xx
:
1813 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1815 case POWERPC_MMU_REAL
:
1816 cpu_abort(env
, "PowerPC in real mode should never raise "
1817 "any MMU exceptions\n");
1820 cpu_abort(env
, "Unknown or invalid MMU model\n");
1825 /* Access rights violation */
1826 env
->exception_index
= POWERPC_EXCP_ISI
;
1827 env
->error_code
= 0x08000000;
1830 /* No execute protection violation */
1831 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1832 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1833 env
->spr
[SPR_BOOKE_ESR
] = 0x00000000;
1835 env
->exception_index
= POWERPC_EXCP_ISI
;
1836 env
->error_code
= 0x10000000;
1839 /* Direct store exception */
1840 /* No code fetch is allowed in direct-store areas */
1841 env
->exception_index
= POWERPC_EXCP_ISI
;
1842 env
->error_code
= 0x10000000;
1844 #if defined(TARGET_PPC64)
1846 /* No match in segment table */
1847 if (env
->mmu_model
== POWERPC_MMU_620
) {
1848 env
->exception_index
= POWERPC_EXCP_ISI
;
1849 /* XXX: this might be incorrect */
1850 env
->error_code
= 0x40000000;
1852 env
->exception_index
= POWERPC_EXCP_ISEG
;
1853 env
->error_code
= 0;
1861 /* No matches in page tables or TLB */
1862 switch (env
->mmu_model
) {
1863 case POWERPC_MMU_SOFT_6xx
:
1865 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1866 env
->error_code
= 1 << 16;
1868 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1869 env
->error_code
= 0;
1871 env
->spr
[SPR_DMISS
] = address
;
1872 env
->spr
[SPR_DCMP
] = 0x80000000 | ctx
.ptem
;
1874 env
->error_code
|= ctx
.key
<< 19;
1875 env
->spr
[SPR_HASH1
] = env
->htab_base
+
1876 get_pteg_offset(env
, ctx
.hash
[0], HASH_PTE_SIZE_32
);
1877 env
->spr
[SPR_HASH2
] = env
->htab_base
+
1878 get_pteg_offset(env
, ctx
.hash
[1], HASH_PTE_SIZE_32
);
1880 case POWERPC_MMU_SOFT_74xx
:
1882 env
->exception_index
= POWERPC_EXCP_DSTLB
;
1884 env
->exception_index
= POWERPC_EXCP_DLTLB
;
1887 /* Implement LRU algorithm */
1888 env
->error_code
= ctx
.key
<< 19;
1889 env
->spr
[SPR_TLBMISS
] = (address
& ~((target_ulong
)0x3)) |
1890 ((env
->last_way
+ 1) & (env
->nb_ways
- 1));
1891 env
->spr
[SPR_PTEHI
] = 0x80000000 | ctx
.ptem
;
1893 case POWERPC_MMU_SOFT_4xx
:
1894 case POWERPC_MMU_SOFT_4xx_Z
:
1895 env
->exception_index
= POWERPC_EXCP_DTLB
;
1896 env
->error_code
= 0;
1897 env
->spr
[SPR_40x_DEAR
] = address
;
1899 env
->spr
[SPR_40x_ESR
] = 0x00800000;
1901 env
->spr
[SPR_40x_ESR
] = 0x00000000;
1903 case POWERPC_MMU_32B
:
1904 case POWERPC_MMU_601
:
1905 #if defined(TARGET_PPC64)
1906 case POWERPC_MMU_620
:
1907 case POWERPC_MMU_64B
:
1908 case POWERPC_MMU_2_06
:
1910 env
->exception_index
= POWERPC_EXCP_DSI
;
1911 env
->error_code
= 0;
1912 env
->spr
[SPR_DAR
] = address
;
1914 env
->spr
[SPR_DSISR
] = 0x42000000;
1916 env
->spr
[SPR_DSISR
] = 0x40000000;
1918 case POWERPC_MMU_MPC8xx
:
1920 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
1922 case POWERPC_MMU_BOOKE206
:
1923 booke206_update_mas_tlb_miss(env
, address
, rw
);
1925 case POWERPC_MMU_BOOKE
:
1926 env
->exception_index
= POWERPC_EXCP_DTLB
;
1927 env
->error_code
= 0;
1928 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1929 env
->spr
[SPR_BOOKE_ESR
] = rw
? ESR_ST
: 0;
1931 case POWERPC_MMU_REAL
:
1932 cpu_abort(env
, "PowerPC in real mode should never raise "
1933 "any MMU exceptions\n");
1936 cpu_abort(env
, "Unknown or invalid MMU model\n");
1941 /* Access rights violation */
1942 env
->exception_index
= POWERPC_EXCP_DSI
;
1943 env
->error_code
= 0;
1944 if (env
->mmu_model
== POWERPC_MMU_SOFT_4xx
1945 || env
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
) {
1946 env
->spr
[SPR_40x_DEAR
] = address
;
1948 env
->spr
[SPR_40x_ESR
] |= 0x00800000;
1950 } else if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
1951 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
1952 env
->spr
[SPR_BOOKE_DEAR
] = address
;
1953 env
->spr
[SPR_BOOKE_ESR
] = rw
? ESR_ST
: 0;
1955 env
->spr
[SPR_DAR
] = address
;
1957 env
->spr
[SPR_DSISR
] = 0x0A000000;
1959 env
->spr
[SPR_DSISR
] = 0x08000000;
1964 /* Direct store exception */
1965 switch (access_type
) {
1967 /* Floating point load/store */
1968 env
->exception_index
= POWERPC_EXCP_ALIGN
;
1969 env
->error_code
= POWERPC_EXCP_ALIGN_FP
;
1970 env
->spr
[SPR_DAR
] = address
;
1973 /* lwarx, ldarx or stwcx. */
1974 env
->exception_index
= POWERPC_EXCP_DSI
;
1975 env
->error_code
= 0;
1976 env
->spr
[SPR_DAR
] = address
;
1978 env
->spr
[SPR_DSISR
] = 0x06000000;
1980 env
->spr
[SPR_DSISR
] = 0x04000000;
1983 /* eciwx or ecowx */
1984 env
->exception_index
= POWERPC_EXCP_DSI
;
1985 env
->error_code
= 0;
1986 env
->spr
[SPR_DAR
] = address
;
1988 env
->spr
[SPR_DSISR
] = 0x06100000;
1990 env
->spr
[SPR_DSISR
] = 0x04100000;
1993 printf("DSI: invalid exception (%d)\n", ret
);
1994 env
->exception_index
= POWERPC_EXCP_PROGRAM
;
1996 POWERPC_EXCP_INVAL
| POWERPC_EXCP_INVAL_INVAL
;
1997 env
->spr
[SPR_DAR
] = address
;
2001 #if defined(TARGET_PPC64)
2003 /* No match in segment table */
2004 if (env
->mmu_model
== POWERPC_MMU_620
) {
2005 env
->exception_index
= POWERPC_EXCP_DSI
;
2006 env
->error_code
= 0;
2007 env
->spr
[SPR_DAR
] = address
;
2008 /* XXX: this might be incorrect */
2010 env
->spr
[SPR_DSISR
] = 0x42000000;
2012 env
->spr
[SPR_DSISR
] = 0x40000000;
2014 env
->exception_index
= POWERPC_EXCP_DSEG
;
2015 env
->error_code
= 0;
2016 env
->spr
[SPR_DAR
] = address
;
2023 printf("%s: set exception to %d %02x\n", __func__
,
2024 env
->exception
, env
->error_code
);
2032 /*****************************************************************************/
2033 /* BATs management */
2034 #if !defined(FLUSH_ALL_TLBS)
2035 static inline void do_invalidate_BAT(CPUPPCState
*env
, target_ulong BATu
,
2038 target_ulong base
, end
, page
;
2040 base
= BATu
& ~0x0001FFFF;
2041 end
= base
+ mask
+ 0x00020000;
2042 LOG_BATS("Flush BAT from " TARGET_FMT_lx
" to " TARGET_FMT_lx
" ("
2043 TARGET_FMT_lx
")\n", base
, end
, mask
);
2044 for (page
= base
; page
!= end
; page
+= TARGET_PAGE_SIZE
)
2045 tlb_flush_page(env
, page
);
2046 LOG_BATS("Flush done\n");
2050 static inline void dump_store_bat(CPUPPCState
*env
, char ID
, int ul
, int nr
,
2053 LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx
" (" TARGET_FMT_lx
")\n", ID
,
2054 nr
, ul
== 0 ? 'u' : 'l', value
, env
->nip
);
2057 void ppc_store_ibatu (CPUPPCState
*env
, int nr
, target_ulong value
)
2061 dump_store_bat(env
, 'I', 0, nr
, value
);
2062 if (env
->IBAT
[0][nr
] != value
) {
2063 mask
= (value
<< 15) & 0x0FFE0000UL
;
2064 #if !defined(FLUSH_ALL_TLBS)
2065 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2067 /* When storing valid upper BAT, mask BEPI and BRPN
2068 * and invalidate all TLBs covered by this BAT
2070 mask
= (value
<< 15) & 0x0FFE0000UL
;
2071 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
2072 (value
& ~0x0001FFFFUL
& ~mask
);
2073 env
->IBAT
[1][nr
] = (env
->IBAT
[1][nr
] & 0x0000007B) |
2074 (env
->IBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
2075 #if !defined(FLUSH_ALL_TLBS)
2076 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2083 void ppc_store_ibatl (CPUPPCState
*env
, int nr
, target_ulong value
)
2085 dump_store_bat(env
, 'I', 1, nr
, value
);
2086 env
->IBAT
[1][nr
] = value
;
2089 void ppc_store_dbatu (CPUPPCState
*env
, int nr
, target_ulong value
)
2093 dump_store_bat(env
, 'D', 0, nr
, value
);
2094 if (env
->DBAT
[0][nr
] != value
) {
2095 /* When storing valid upper BAT, mask BEPI and BRPN
2096 * and invalidate all TLBs covered by this BAT
2098 mask
= (value
<< 15) & 0x0FFE0000UL
;
2099 #if !defined(FLUSH_ALL_TLBS)
2100 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
2102 mask
= (value
<< 15) & 0x0FFE0000UL
;
2103 env
->DBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
2104 (value
& ~0x0001FFFFUL
& ~mask
);
2105 env
->DBAT
[1][nr
] = (env
->DBAT
[1][nr
] & 0x0000007B) |
2106 (env
->DBAT
[1][nr
] & ~0x0001FFFF & ~mask
);
2107 #if !defined(FLUSH_ALL_TLBS)
2108 do_invalidate_BAT(env
, env
->DBAT
[0][nr
], mask
);
2115 void ppc_store_dbatl (CPUPPCState
*env
, int nr
, target_ulong value
)
2117 dump_store_bat(env
, 'D', 1, nr
, value
);
2118 env
->DBAT
[1][nr
] = value
;
2121 void ppc_store_ibatu_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
2124 #if defined(FLUSH_ALL_TLBS)
2128 dump_store_bat(env
, 'I', 0, nr
, value
);
2129 if (env
->IBAT
[0][nr
] != value
) {
2130 #if defined(FLUSH_ALL_TLBS)
2133 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
2134 if (env
->IBAT
[1][nr
] & 0x40) {
2135 /* Invalidate BAT only if it is valid */
2136 #if !defined(FLUSH_ALL_TLBS)
2137 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2142 /* When storing valid upper BAT, mask BEPI and BRPN
2143 * and invalidate all TLBs covered by this BAT
2145 env
->IBAT
[0][nr
] = (value
& 0x00001FFFUL
) |
2146 (value
& ~0x0001FFFFUL
& ~mask
);
2147 env
->DBAT
[0][nr
] = env
->IBAT
[0][nr
];
2148 if (env
->IBAT
[1][nr
] & 0x40) {
2149 #if !defined(FLUSH_ALL_TLBS)
2150 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2155 #if defined(FLUSH_ALL_TLBS)
2162 void ppc_store_ibatl_601 (CPUPPCState
*env
, int nr
, target_ulong value
)
2165 #if defined(FLUSH_ALL_TLBS)
2169 dump_store_bat(env
, 'I', 1, nr
, value
);
2170 if (env
->IBAT
[1][nr
] != value
) {
2171 #if defined(FLUSH_ALL_TLBS)
2174 if (env
->IBAT
[1][nr
] & 0x40) {
2175 #if !defined(FLUSH_ALL_TLBS)
2176 mask
= (env
->IBAT
[1][nr
] << 17) & 0x0FFE0000UL
;
2177 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2183 #if !defined(FLUSH_ALL_TLBS)
2184 mask
= (value
<< 17) & 0x0FFE0000UL
;
2185 do_invalidate_BAT(env
, env
->IBAT
[0][nr
], mask
);
2190 env
->IBAT
[1][nr
] = value
;
2191 env
->DBAT
[1][nr
] = value
;
2192 #if defined(FLUSH_ALL_TLBS)
2199 /*****************************************************************************/
2200 /* TLB management */
2201 void ppc_tlb_invalidate_all (CPUPPCState
*env
)
2203 switch (env
->mmu_model
) {
2204 case POWERPC_MMU_SOFT_6xx
:
2205 case POWERPC_MMU_SOFT_74xx
:
2206 ppc6xx_tlb_invalidate_all(env
);
2208 case POWERPC_MMU_SOFT_4xx
:
2209 case POWERPC_MMU_SOFT_4xx_Z
:
2210 ppc4xx_tlb_invalidate_all(env
);
2212 case POWERPC_MMU_REAL
:
2213 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
2215 case POWERPC_MMU_MPC8xx
:
2217 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
2219 case POWERPC_MMU_BOOKE
:
2222 case POWERPC_MMU_BOOKE206
:
2223 booke206_flush_tlb(env
, -1, 0);
2225 case POWERPC_MMU_32B
:
2226 case POWERPC_MMU_601
:
2227 #if defined(TARGET_PPC64)
2228 case POWERPC_MMU_620
:
2229 case POWERPC_MMU_64B
:
2230 case POWERPC_MMU_2_06
:
2231 #endif /* defined(TARGET_PPC64) */
2236 cpu_abort(env
, "Unknown MMU model\n");
2241 void ppc_tlb_invalidate_one (CPUPPCState
*env
, target_ulong addr
)
2243 #if !defined(FLUSH_ALL_TLBS)
2244 addr
&= TARGET_PAGE_MASK
;
2245 switch (env
->mmu_model
) {
2246 case POWERPC_MMU_SOFT_6xx
:
2247 case POWERPC_MMU_SOFT_74xx
:
2248 ppc6xx_tlb_invalidate_virt(env
, addr
, 0);
2249 if (env
->id_tlbs
== 1)
2250 ppc6xx_tlb_invalidate_virt(env
, addr
, 1);
2252 case POWERPC_MMU_SOFT_4xx
:
2253 case POWERPC_MMU_SOFT_4xx_Z
:
2254 ppc4xx_tlb_invalidate_virt(env
, addr
, env
->spr
[SPR_40x_PID
]);
2256 case POWERPC_MMU_REAL
:
2257 cpu_abort(env
, "No TLB for PowerPC 4xx in real mode\n");
2259 case POWERPC_MMU_MPC8xx
:
2261 cpu_abort(env
, "MPC8xx MMU model is not implemented\n");
2263 case POWERPC_MMU_BOOKE
:
2265 cpu_abort(env
, "BookE MMU model is not implemented\n");
2267 case POWERPC_MMU_BOOKE206
:
2269 cpu_abort(env
, "BookE 2.06 MMU model is not implemented\n");
2271 case POWERPC_MMU_32B
:
2272 case POWERPC_MMU_601
:
2273 /* tlbie invalidate TLBs for all segments */
2274 addr
&= ~((target_ulong
)-1ULL << 28);
2275 /* XXX: this case should be optimized,
2276 * giving a mask to tlb_flush_page
2278 tlb_flush_page(env
, addr
| (0x0 << 28));
2279 tlb_flush_page(env
, addr
| (0x1 << 28));
2280 tlb_flush_page(env
, addr
| (0x2 << 28));
2281 tlb_flush_page(env
, addr
| (0x3 << 28));
2282 tlb_flush_page(env
, addr
| (0x4 << 28));
2283 tlb_flush_page(env
, addr
| (0x5 << 28));
2284 tlb_flush_page(env
, addr
| (0x6 << 28));
2285 tlb_flush_page(env
, addr
| (0x7 << 28));
2286 tlb_flush_page(env
, addr
| (0x8 << 28));
2287 tlb_flush_page(env
, addr
| (0x9 << 28));
2288 tlb_flush_page(env
, addr
| (0xA << 28));
2289 tlb_flush_page(env
, addr
| (0xB << 28));
2290 tlb_flush_page(env
, addr
| (0xC << 28));
2291 tlb_flush_page(env
, addr
| (0xD << 28));
2292 tlb_flush_page(env
, addr
| (0xE << 28));
2293 tlb_flush_page(env
, addr
| (0xF << 28));
2295 #if defined(TARGET_PPC64)
2296 case POWERPC_MMU_620
:
2297 case POWERPC_MMU_64B
:
2298 case POWERPC_MMU_2_06
:
2299 /* tlbie invalidate TLBs for all segments */
2300 /* XXX: given the fact that there are too many segments to invalidate,
2301 * and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
2302 * we just invalidate all TLBs
2306 #endif /* defined(TARGET_PPC64) */
2309 cpu_abort(env
, "Unknown MMU model\n");
2313 ppc_tlb_invalidate_all(env
);
2317 /*****************************************************************************/
2318 /* Special registers manipulation */
2319 #if defined(TARGET_PPC64)
2320 void ppc_store_asr (CPUPPCState
*env
, target_ulong value
)
2322 if (env
->asr
!= value
) {
2329 void ppc_store_sdr1 (CPUPPCState
*env
, target_ulong value
)
2331 LOG_MMU("%s: " TARGET_FMT_lx
"\n", __func__
, value
);
2332 if (env
->spr
[SPR_SDR1
] != value
) {
2333 env
->spr
[SPR_SDR1
] = value
;
2334 #if defined(TARGET_PPC64)
2335 if (env
->mmu_model
& POWERPC_MMU_64
) {
2336 target_ulong htabsize
= value
& SDR_64_HTABSIZE
;
2338 if (htabsize
> 28) {
2339 fprintf(stderr
, "Invalid HTABSIZE 0x" TARGET_FMT_lx
2340 " stored in SDR1\n", htabsize
);
2343 env
->htab_mask
= (1ULL << (htabsize
+ 18)) - 1;
2344 env
->htab_base
= value
& SDR_64_HTABORG
;
2346 #endif /* defined(TARGET_PPC64) */
2348 /* FIXME: Should check for valid HTABMASK values */
2349 env
->htab_mask
= ((value
& SDR_32_HTABMASK
) << 16) | 0xFFFF;
2350 env
->htab_base
= value
& SDR_32_HTABORG
;
2356 #if defined(TARGET_PPC64)
2357 target_ulong
ppc_load_sr (CPUPPCState
*env
, int slb_nr
)
2364 void ppc_store_sr (CPUPPCState
*env
, int srnum
, target_ulong value
)
2366 LOG_MMU("%s: reg=%d " TARGET_FMT_lx
" " TARGET_FMT_lx
"\n", __func__
,
2367 srnum
, value
, env
->sr
[srnum
]);
2368 #if defined(TARGET_PPC64)
2369 if (env
->mmu_model
& POWERPC_MMU_64
) {
2370 uint64_t rb
= 0, rs
= 0;
2373 rb
|= ((uint32_t)srnum
& 0xf) << 28;
2374 /* Set the valid bit */
2377 rb
|= (uint32_t)srnum
;
2380 rs
|= (value
& 0xfffffff) << 12;
2382 rs
|= ((value
>> 27) & 0xf) << 8;
2384 ppc_store_slb(env
, rb
, rs
);
2387 if (env
->sr
[srnum
] != value
) {
2388 env
->sr
[srnum
] = value
;
2389 /* Invalidating 256MB of virtual memory in 4kB pages is way longer than
2390 flusing the whole TLB. */
2391 #if !defined(FLUSH_ALL_TLBS) && 0
2393 target_ulong page
, end
;
2394 /* Invalidate 256 MB of virtual memory */
2395 page
= (16 << 20) * srnum
;
2396 end
= page
+ (16 << 20);
2397 for (; page
!= end
; page
+= TARGET_PAGE_SIZE
)
2398 tlb_flush_page(env
, page
);
2405 #endif /* !defined (CONFIG_USER_ONLY) */
2407 /* GDBstub can read and write MSR... */
2408 void ppc_store_msr (CPUPPCState
*env
, target_ulong value
)
2410 hreg_store_msr(env
, value
, 0);
2413 /*****************************************************************************/
2414 /* Exception processing */
2415 #if defined (CONFIG_USER_ONLY)
2416 void do_interrupt (CPUState
*env
)
2418 env
->exception_index
= POWERPC_EXCP_NONE
;
2419 env
->error_code
= 0;
2422 void ppc_hw_interrupt (CPUState
*env
)
2424 env
->exception_index
= POWERPC_EXCP_NONE
;
2425 env
->error_code
= 0;
2427 #else /* defined (CONFIG_USER_ONLY) */
2428 static inline void dump_syscall(CPUState
*env
)
2430 qemu_log_mask(CPU_LOG_INT
, "syscall r0=%016" PRIx64
" r3=%016" PRIx64
2431 " r4=%016" PRIx64
" r5=%016" PRIx64
" r6=%016" PRIx64
2432 " nip=" TARGET_FMT_lx
"\n",
2433 ppc_dump_gpr(env
, 0), ppc_dump_gpr(env
, 3),
2434 ppc_dump_gpr(env
, 4), ppc_dump_gpr(env
, 5),
2435 ppc_dump_gpr(env
, 6), env
->nip
);
2438 /* Note that this function should be greatly optimized
2439 * when called with a constant excp, from ppc_hw_interrupt
2441 static inline void powerpc_excp(CPUState
*env
, int excp_model
, int excp
)
2443 target_ulong msr
, new_msr
, vector
;
2444 int srr0
, srr1
, asrr0
, asrr1
;
2445 int lpes0
, lpes1
, lev
;
2448 /* XXX: find a suitable condition to enable the hypervisor mode */
2449 lpes0
= (env
->spr
[SPR_LPCR
] >> 1) & 1;
2450 lpes1
= (env
->spr
[SPR_LPCR
] >> 2) & 1;
2452 /* Those values ensure we won't enter the hypervisor mode */
2457 qemu_log_mask(CPU_LOG_INT
, "Raise exception at " TARGET_FMT_lx
2458 " => %08x (%02x)\n", env
->nip
, excp
, env
->error_code
);
2460 /* new srr1 value excluding must-be-zero bits */
2461 msr
= env
->msr
& ~0x783f0000ULL
;
2463 /* new interrupt handler msr */
2464 new_msr
= env
->msr
& ((target_ulong
)1 << MSR_ME
);
2466 /* target registers */
2473 case POWERPC_EXCP_NONE
:
2474 /* Should never happen */
2476 case POWERPC_EXCP_CRITICAL
: /* Critical input */
2477 switch (excp_model
) {
2478 case POWERPC_EXCP_40x
:
2479 srr0
= SPR_40x_SRR2
;
2480 srr1
= SPR_40x_SRR3
;
2482 case POWERPC_EXCP_BOOKE
:
2483 srr0
= SPR_BOOKE_CSRR0
;
2484 srr1
= SPR_BOOKE_CSRR1
;
2486 case POWERPC_EXCP_G2
:
2492 case POWERPC_EXCP_MCHECK
: /* Machine check exception */
2494 /* Machine check exception is not enabled.
2495 * Enter checkstop state.
2497 if (qemu_log_enabled()) {
2498 qemu_log("Machine check while not allowed. "
2499 "Entering checkstop state\n");
2501 fprintf(stderr
, "Machine check while not allowed. "
2502 "Entering checkstop state\n");
2505 env
->interrupt_request
|= CPU_INTERRUPT_EXITTB
;
2508 /* XXX: find a suitable condition to enable the hypervisor mode */
2509 new_msr
|= (target_ulong
)MSR_HVB
;
2512 /* machine check exceptions don't have ME set */
2513 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2515 /* XXX: should also have something loaded in DAR / DSISR */
2516 switch (excp_model
) {
2517 case POWERPC_EXCP_40x
:
2518 srr0
= SPR_40x_SRR2
;
2519 srr1
= SPR_40x_SRR3
;
2521 case POWERPC_EXCP_BOOKE
:
2522 srr0
= SPR_BOOKE_MCSRR0
;
2523 srr1
= SPR_BOOKE_MCSRR1
;
2524 asrr0
= SPR_BOOKE_CSRR0
;
2525 asrr1
= SPR_BOOKE_CSRR1
;
2531 case POWERPC_EXCP_DSI
: /* Data storage exception */
2532 LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx
" DAR=" TARGET_FMT_lx
2533 "\n", env
->spr
[SPR_DSISR
], env
->spr
[SPR_DAR
]);
2535 new_msr
|= (target_ulong
)MSR_HVB
;
2537 case POWERPC_EXCP_ISI
: /* Instruction storage exception */
2538 LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx
", nip=" TARGET_FMT_lx
2539 "\n", msr
, env
->nip
);
2541 new_msr
|= (target_ulong
)MSR_HVB
;
2542 msr
|= env
->error_code
;
2544 case POWERPC_EXCP_EXTERNAL
: /* External input */
2546 new_msr
|= (target_ulong
)MSR_HVB
;
2548 case POWERPC_EXCP_ALIGN
: /* Alignment exception */
2550 new_msr
|= (target_ulong
)MSR_HVB
;
2551 /* XXX: this is false */
2552 /* Get rS/rD and rA from faulting opcode */
2553 env
->spr
[SPR_DSISR
] |= (ldl_code((env
->nip
- 4)) & 0x03FF0000) >> 16;
2555 case POWERPC_EXCP_PROGRAM
: /* Program exception */
2556 switch (env
->error_code
& ~0xF) {
2557 case POWERPC_EXCP_FP
:
2558 if ((msr_fe0
== 0 && msr_fe1
== 0) || msr_fp
== 0) {
2559 LOG_EXCP("Ignore floating point exception\n");
2560 env
->exception_index
= POWERPC_EXCP_NONE
;
2561 env
->error_code
= 0;
2565 new_msr
|= (target_ulong
)MSR_HVB
;
2567 if (msr_fe0
== msr_fe1
)
2571 case POWERPC_EXCP_INVAL
:
2572 LOG_EXCP("Invalid instruction at " TARGET_FMT_lx
"\n", env
->nip
);
2574 new_msr
|= (target_ulong
)MSR_HVB
;
2576 env
->spr
[SPR_BOOKE_ESR
] = ESR_PIL
;
2578 case POWERPC_EXCP_PRIV
:
2580 new_msr
|= (target_ulong
)MSR_HVB
;
2582 env
->spr
[SPR_BOOKE_ESR
] = ESR_PPR
;
2584 case POWERPC_EXCP_TRAP
:
2586 new_msr
|= (target_ulong
)MSR_HVB
;
2588 env
->spr
[SPR_BOOKE_ESR
] = ESR_PTR
;
2591 /* Should never occur */
2592 cpu_abort(env
, "Invalid program exception %d. Aborting\n",
2597 case POWERPC_EXCP_FPU
: /* Floating-point unavailable exception */
2599 new_msr
|= (target_ulong
)MSR_HVB
;
2601 case POWERPC_EXCP_SYSCALL
: /* System call exception */
2603 lev
= env
->error_code
;
2604 if ((lev
== 1) && cpu_ppc_hypercall
) {
2605 cpu_ppc_hypercall(env
);
2608 if (lev
== 1 || (lpes0
== 0 && lpes1
== 0))
2609 new_msr
|= (target_ulong
)MSR_HVB
;
2611 case POWERPC_EXCP_APU
: /* Auxiliary processor unavailable */
2613 case POWERPC_EXCP_DECR
: /* Decrementer exception */
2615 new_msr
|= (target_ulong
)MSR_HVB
;
2617 case POWERPC_EXCP_FIT
: /* Fixed-interval timer interrupt */
2619 LOG_EXCP("FIT exception\n");
2621 case POWERPC_EXCP_WDT
: /* Watchdog timer interrupt */
2622 LOG_EXCP("WDT exception\n");
2623 switch (excp_model
) {
2624 case POWERPC_EXCP_BOOKE
:
2625 srr0
= SPR_BOOKE_CSRR0
;
2626 srr1
= SPR_BOOKE_CSRR1
;
2632 case POWERPC_EXCP_DTLB
: /* Data TLB error */
2634 case POWERPC_EXCP_ITLB
: /* Instruction TLB error */
2636 case POWERPC_EXCP_DEBUG
: /* Debug interrupt */
2637 switch (excp_model
) {
2638 case POWERPC_EXCP_BOOKE
:
2639 srr0
= SPR_BOOKE_DSRR0
;
2640 srr1
= SPR_BOOKE_DSRR1
;
2641 asrr0
= SPR_BOOKE_CSRR0
;
2642 asrr1
= SPR_BOOKE_CSRR1
;
2648 cpu_abort(env
, "Debug exception is not implemented yet !\n");
2650 case POWERPC_EXCP_SPEU
: /* SPE/embedded floating-point unavailable */
2651 env
->spr
[SPR_BOOKE_ESR
] = ESR_SPV
;
2653 case POWERPC_EXCP_EFPDI
: /* Embedded floating-point data interrupt */
2655 cpu_abort(env
, "Embedded floating point data exception "
2656 "is not implemented yet !\n");
2657 env
->spr
[SPR_BOOKE_ESR
] = ESR_SPV
;
2659 case POWERPC_EXCP_EFPRI
: /* Embedded floating-point round interrupt */
2661 cpu_abort(env
, "Embedded floating point round exception "
2662 "is not implemented yet !\n");
2663 env
->spr
[SPR_BOOKE_ESR
] = ESR_SPV
;
2665 case POWERPC_EXCP_EPERFM
: /* Embedded performance monitor interrupt */
2668 "Performance counter exception is not implemented yet !\n");
2670 case POWERPC_EXCP_DOORI
: /* Embedded doorbell interrupt */
2673 "Embedded doorbell interrupt is not implemented yet !\n");
2675 case POWERPC_EXCP_DOORCI
: /* Embedded doorbell critical interrupt */
2676 switch (excp_model
) {
2677 case POWERPC_EXCP_BOOKE
:
2678 srr0
= SPR_BOOKE_CSRR0
;
2679 srr1
= SPR_BOOKE_CSRR1
;
2685 cpu_abort(env
, "Embedded doorbell critical interrupt "
2686 "is not implemented yet !\n");
2688 case POWERPC_EXCP_RESET
: /* System reset exception */
2690 /* indicate that we resumed from power save mode */
2693 new_msr
&= ~((target_ulong
)1 << MSR_ME
);
2697 /* XXX: find a suitable condition to enable the hypervisor mode */
2698 new_msr
|= (target_ulong
)MSR_HVB
;
2701 case POWERPC_EXCP_DSEG
: /* Data segment exception */
2703 new_msr
|= (target_ulong
)MSR_HVB
;
2705 case POWERPC_EXCP_ISEG
: /* Instruction segment exception */
2707 new_msr
|= (target_ulong
)MSR_HVB
;
2709 case POWERPC_EXCP_HDECR
: /* Hypervisor decrementer exception */
2712 new_msr
|= (target_ulong
)MSR_HVB
;
2713 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2715 case POWERPC_EXCP_TRACE
: /* Trace exception */
2717 new_msr
|= (target_ulong
)MSR_HVB
;
2719 case POWERPC_EXCP_HDSI
: /* Hypervisor data storage exception */
2722 new_msr
|= (target_ulong
)MSR_HVB
;
2723 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2725 case POWERPC_EXCP_HISI
: /* Hypervisor instruction storage exception */
2728 new_msr
|= (target_ulong
)MSR_HVB
;
2729 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2731 case POWERPC_EXCP_HDSEG
: /* Hypervisor data segment exception */
2734 new_msr
|= (target_ulong
)MSR_HVB
;
2735 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2737 case POWERPC_EXCP_HISEG
: /* Hypervisor instruction segment exception */
2740 new_msr
|= (target_ulong
)MSR_HVB
;
2741 new_msr
|= env
->msr
& ((target_ulong
)1 << MSR_RI
);
2743 case POWERPC_EXCP_VPU
: /* Vector unavailable exception */
2745 new_msr
|= (target_ulong
)MSR_HVB
;
2747 case POWERPC_EXCP_PIT
: /* Programmable interval timer interrupt */
2748 LOG_EXCP("PIT exception\n");
2750 case POWERPC_EXCP_IO
: /* IO error exception */
2752 cpu_abort(env
, "601 IO error exception is not implemented yet !\n");
2754 case POWERPC_EXCP_RUNM
: /* Run mode exception */
2756 cpu_abort(env
, "601 run mode exception is not implemented yet !\n");
2758 case POWERPC_EXCP_EMUL
: /* Emulation trap exception */
2760 cpu_abort(env
, "602 emulation trap exception "
2761 "is not implemented yet !\n");
2763 case POWERPC_EXCP_IFTLB
: /* Instruction fetch TLB error */
2764 if (lpes1
== 0) /* XXX: check this */
2765 new_msr
|= (target_ulong
)MSR_HVB
;
2766 switch (excp_model
) {
2767 case POWERPC_EXCP_602
:
2768 case POWERPC_EXCP_603
:
2769 case POWERPC_EXCP_603E
:
2770 case POWERPC_EXCP_G2
:
2772 case POWERPC_EXCP_7x5
:
2774 case POWERPC_EXCP_74xx
:
2777 cpu_abort(env
, "Invalid instruction TLB miss exception\n");
2781 case POWERPC_EXCP_DLTLB
: /* Data load TLB miss */
2782 if (lpes1
== 0) /* XXX: check this */
2783 new_msr
|= (target_ulong
)MSR_HVB
;
2784 switch (excp_model
) {
2785 case POWERPC_EXCP_602
:
2786 case POWERPC_EXCP_603
:
2787 case POWERPC_EXCP_603E
:
2788 case POWERPC_EXCP_G2
:
2790 case POWERPC_EXCP_7x5
:
2792 case POWERPC_EXCP_74xx
:
2795 cpu_abort(env
, "Invalid data load TLB miss exception\n");
2799 case POWERPC_EXCP_DSTLB
: /* Data store TLB miss */
2800 if (lpes1
== 0) /* XXX: check this */
2801 new_msr
|= (target_ulong
)MSR_HVB
;
2802 switch (excp_model
) {
2803 case POWERPC_EXCP_602
:
2804 case POWERPC_EXCP_603
:
2805 case POWERPC_EXCP_603E
:
2806 case POWERPC_EXCP_G2
:
2808 /* Swap temporary saved registers with GPRs */
2809 if (!(new_msr
& ((target_ulong
)1 << MSR_TGPR
))) {
2810 new_msr
|= (target_ulong
)1 << MSR_TGPR
;
2811 hreg_swap_gpr_tgpr(env
);
2814 case POWERPC_EXCP_7x5
:
2816 #if defined (DEBUG_SOFTWARE_TLB)
2817 if (qemu_log_enabled()) {
2819 target_ulong
*miss
, *cmp
;
2821 if (excp
== POWERPC_EXCP_IFTLB
) {
2824 miss
= &env
->spr
[SPR_IMISS
];
2825 cmp
= &env
->spr
[SPR_ICMP
];
2827 if (excp
== POWERPC_EXCP_DLTLB
)
2832 miss
= &env
->spr
[SPR_DMISS
];
2833 cmp
= &env
->spr
[SPR_DCMP
];
2835 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2836 TARGET_FMT_lx
" H1 " TARGET_FMT_lx
" H2 "
2837 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2838 env
->spr
[SPR_HASH1
], env
->spr
[SPR_HASH2
],
2842 msr
|= env
->crf
[0] << 28;
2843 msr
|= env
->error_code
; /* key, D/I, S/L bits */
2844 /* Set way using a LRU mechanism */
2845 msr
|= ((env
->last_way
+ 1) & (env
->nb_ways
- 1)) << 17;
2847 case POWERPC_EXCP_74xx
:
2849 #if defined (DEBUG_SOFTWARE_TLB)
2850 if (qemu_log_enabled()) {
2852 target_ulong
*miss
, *cmp
;
2854 if (excp
== POWERPC_EXCP_IFTLB
) {
2857 miss
= &env
->spr
[SPR_TLBMISS
];
2858 cmp
= &env
->spr
[SPR_PTEHI
];
2860 if (excp
== POWERPC_EXCP_DLTLB
)
2865 miss
= &env
->spr
[SPR_TLBMISS
];
2866 cmp
= &env
->spr
[SPR_PTEHI
];
2868 qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx
" %cC "
2869 TARGET_FMT_lx
" %08x\n", es
, en
, *miss
, en
, *cmp
,
2873 msr
|= env
->error_code
; /* key bit */
2876 cpu_abort(env
, "Invalid data store TLB miss exception\n");
2880 case POWERPC_EXCP_FPA
: /* Floating-point assist exception */
2882 cpu_abort(env
, "Floating point assist exception "
2883 "is not implemented yet !\n");
2885 case POWERPC_EXCP_DABR
: /* Data address breakpoint */
2887 cpu_abort(env
, "DABR exception is not implemented yet !\n");
2889 case POWERPC_EXCP_IABR
: /* Instruction address breakpoint */
2891 cpu_abort(env
, "IABR exception is not implemented yet !\n");
2893 case POWERPC_EXCP_SMI
: /* System management interrupt */
2895 cpu_abort(env
, "SMI exception is not implemented yet !\n");
2897 case POWERPC_EXCP_THERM
: /* Thermal interrupt */
2899 cpu_abort(env
, "Thermal management exception "
2900 "is not implemented yet !\n");
2902 case POWERPC_EXCP_PERFM
: /* Embedded performance monitor interrupt */
2904 new_msr
|= (target_ulong
)MSR_HVB
;
2907 "Performance counter exception is not implemented yet !\n");
2909 case POWERPC_EXCP_VPUA
: /* Vector assist exception */
2911 cpu_abort(env
, "VPU assist exception is not implemented yet !\n");
2913 case POWERPC_EXCP_SOFTP
: /* Soft patch exception */
2916 "970 soft-patch exception is not implemented yet !\n");
2918 case POWERPC_EXCP_MAINT
: /* Maintenance exception */
2921 "970 maintenance exception is not implemented yet !\n");
2923 case POWERPC_EXCP_MEXTBR
: /* Maskable external breakpoint */
2925 cpu_abort(env
, "Maskable external exception "
2926 "is not implemented yet !\n");
2928 case POWERPC_EXCP_NMEXTBR
: /* Non maskable external breakpoint */
2930 cpu_abort(env
, "Non maskable external exception "
2931 "is not implemented yet !\n");
2935 cpu_abort(env
, "Invalid PowerPC exception %d. Aborting\n", excp
);
2938 /* save current instruction location */
2939 env
->spr
[srr0
] = env
->nip
- 4;
2942 /* save next instruction location */
2943 env
->spr
[srr0
] = env
->nip
;
2947 env
->spr
[srr1
] = msr
;
2948 /* If any alternate SRR register are defined, duplicate saved values */
2950 env
->spr
[asrr0
] = env
->spr
[srr0
];
2952 env
->spr
[asrr1
] = env
->spr
[srr1
];
2953 /* If we disactivated any translation, flush TLBs */
2954 if (new_msr
& ((1 << MSR_IR
) | (1 << MSR_DR
)))
2958 new_msr
|= (target_ulong
)1 << MSR_LE
;
2961 /* Jump to handler */
2962 vector
= env
->excp_vectors
[excp
];
2963 if (vector
== (target_ulong
)-1ULL) {
2964 cpu_abort(env
, "Raised an exception without defined vector %d\n",
2967 vector
|= env
->excp_prefix
;
2968 #if defined(TARGET_PPC64)
2969 if (excp_model
== POWERPC_EXCP_BOOKE
) {
2971 vector
= (uint32_t)vector
;
2973 new_msr
|= (target_ulong
)1 << MSR_CM
;
2976 if (!msr_isf
&& !(env
->mmu_model
& POWERPC_MMU_64
)) {
2977 vector
= (uint32_t)vector
;
2979 new_msr
|= (target_ulong
)1 << MSR_SF
;
2983 /* XXX: we don't use hreg_store_msr here as already have treated
2984 * any special case that could occur. Just store MSR and update hflags
2986 env
->msr
= new_msr
& env
->msr_mask
;
2987 hreg_compute_hflags(env
);
2989 /* Reset exception state */
2990 env
->exception_index
= POWERPC_EXCP_NONE
;
2991 env
->error_code
= 0;
2993 if ((env
->mmu_model
== POWERPC_MMU_BOOKE
) ||
2994 (env
->mmu_model
== POWERPC_MMU_BOOKE206
)) {
2995 /* XXX: The BookE changes address space when switching modes,
2996 we should probably implement that as different MMU indexes,
2997 but for the moment we do it the slow way and flush all. */
3002 void do_interrupt (CPUState
*env
)
3004 powerpc_excp(env
, env
->excp_model
, env
->exception_index
);
3007 void ppc_hw_interrupt (CPUPPCState
*env
)
3012 qemu_log_mask(CPU_LOG_INT
, "%s: %p pending %08x req %08x me %d ee %d\n",
3013 __func__
, env
, env
->pending_interrupts
,
3014 env
->interrupt_request
, (int)msr_me
, (int)msr_ee
);
3016 /* External reset */
3017 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_RESET
)) {
3018 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_RESET
);
3019 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_RESET
);
3022 /* Machine check exception */
3023 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_MCK
)) {
3024 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_MCK
);
3025 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_MCHECK
);
3029 /* External debug exception */
3030 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DEBUG
)) {
3031 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DEBUG
);
3032 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DEBUG
);
3037 /* XXX: find a suitable condition to enable the hypervisor mode */
3038 hdice
= env
->spr
[SPR_LPCR
] & 1;
3042 if ((msr_ee
!= 0 || msr_hv
== 0 || msr_pr
!= 0) && hdice
!= 0) {
3043 /* Hypervisor decrementer exception */
3044 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_HDECR
)) {
3045 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_HDECR
);
3046 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_HDECR
);
3051 /* External critical interrupt */
3052 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CEXT
)) {
3053 /* Taking a critical external interrupt does not clear the external
3054 * critical interrupt status
3057 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CEXT
);
3059 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_CRITICAL
);
3064 /* Watchdog timer on embedded PowerPC */
3065 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_WDT
)) {
3066 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_WDT
);
3067 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_WDT
);
3070 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_CDOORBELL
)) {
3071 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_CDOORBELL
);
3072 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORCI
);
3075 /* Fixed interval timer on embedded PowerPC */
3076 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_FIT
)) {
3077 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_FIT
);
3078 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_FIT
);
3081 /* Programmable interval timer on embedded PowerPC */
3082 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PIT
)) {
3083 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PIT
);
3084 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PIT
);
3087 /* Decrementer exception */
3088 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DECR
)) {
3089 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DECR
);
3090 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DECR
);
3093 /* External interrupt */
3094 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_EXT
)) {
3095 /* Taking an external interrupt does not clear the external
3099 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_EXT
);
3101 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_EXTERNAL
);
3104 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_DOORBELL
)) {
3105 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_DOORBELL
);
3106 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_DOORI
);
3109 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_PERFM
)) {
3110 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_PERFM
);
3111 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_PERFM
);
3114 /* Thermal interrupt */
3115 if (env
->pending_interrupts
& (1 << PPC_INTERRUPT_THERM
)) {
3116 env
->pending_interrupts
&= ~(1 << PPC_INTERRUPT_THERM
);
3117 powerpc_excp(env
, env
->excp_model
, POWERPC_EXCP_THERM
);
3122 #endif /* !CONFIG_USER_ONLY */
3124 void cpu_dump_rfi (target_ulong RA
, target_ulong msr
)
3126 qemu_log("Return from exception at " TARGET_FMT_lx
" with flags "
3127 TARGET_FMT_lx
"\n", RA
, msr
);
3130 void cpu_reset(CPUPPCState
*env
)
3134 if (qemu_loglevel_mask(CPU_LOG_RESET
)) {
3135 qemu_log("CPU Reset (CPU %d)\n", env
->cpu_index
);
3136 log_cpu_state(env
, 0);
3139 msr
= (target_ulong
)0;
3141 /* XXX: find a suitable condition to enable the hypervisor mode */
3142 msr
|= (target_ulong
)MSR_HVB
;
3144 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
3145 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
3146 msr
|= (target_ulong
)1 << MSR_EP
;
3147 #if defined (DO_SINGLE_STEP) && 0
3148 /* Single step trace mode */
3149 msr
|= (target_ulong
)1 << MSR_SE
;
3150 msr
|= (target_ulong
)1 << MSR_BE
;
3152 #if defined(CONFIG_USER_ONLY)
3153 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
3154 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
3155 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
3156 msr
|= (target_ulong
)1 << MSR_PR
;
3158 env
->excp_prefix
= env
->hreset_excp_prefix
;
3159 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
3160 if (env
->mmu_model
!= POWERPC_MMU_REAL
)
3161 ppc_tlb_invalidate_all(env
);
3163 env
->msr
= msr
& env
->msr_mask
;
3164 #if defined(TARGET_PPC64)
3165 if (env
->mmu_model
& POWERPC_MMU_64
)
3166 env
->msr
|= (1ULL << MSR_SF
);
3168 hreg_compute_hflags(env
);
3169 env
->reserve_addr
= (target_ulong
)-1ULL;
3170 /* Be sure no exception or interrupt is pending */
3171 env
->pending_interrupts
= 0;
3172 env
->exception_index
= POWERPC_EXCP_NONE
;
3173 env
->error_code
= 0;
3174 /* Flush all TLBs */
3178 CPUPPCState
*cpu_ppc_init (const char *cpu_model
)
3181 const ppc_def_t
*def
;
3183 def
= cpu_ppc_find_by_name(cpu_model
);
3187 env
= g_malloc0(sizeof(CPUPPCState
));
3189 if (tcg_enabled()) {
3190 ppc_translate_init();
3192 env
->cpu_model_str
= cpu_model
;
3193 cpu_ppc_register_internal(env
, def
);
3195 qemu_init_vcpu(env
);
3200 void cpu_ppc_close (CPUPPCState
*env
)
3202 /* Should also remove all opcode tables... */