2 * PowerPC emulation helpers for qemu.
4 * Copyright (c) 2003-2007 Jocelyn Mayer
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
27 #include "helper_regs.h"
28 #include "qemu-common.h"
34 //#define DEBUG_SOFTWARE_TLB
35 //#define DUMP_PAGE_TABLES
36 //#define DEBUG_EXCEPTIONS
37 //#define FLUSH_ALL_TLBS
40 # define LOG_MMU(...) qemu_log(__VA_ARGS__)
41 # define LOG_MMU_STATE(env) log_cpu_state((env), 0)
43 # define LOG_MMU(...) do { } while (0)
44 # define LOG_MMU_STATE(...) do { } while (0)
48 #ifdef DEBUG_SOFTWARE_TLB
49 # define LOG_SWTLB(...) qemu_log(__VA_ARGS__)
51 # define LOG_SWTLB(...) do { } while (0)
55 # define LOG_BATS(...) qemu_log(__VA_ARGS__)
57 # define LOG_BATS(...) do { } while (0)
61 # define LOG_SLB(...) qemu_log(__VA_ARGS__)
63 # define LOG_SLB(...) do { } while (0)
66 #ifdef DEBUG_EXCEPTIONS
67 # define LOG_EXCP(...) qemu_log(__VA_ARGS__)
69 # define LOG_EXCP(...) do { } while (0)
72 /*****************************************************************************/
73 /* PowerPC Hypercall emulation */
75 void (*cpu_ppc_hypercall)(CPUState *);
77 /*****************************************************************************/
78 /* PowerPC MMU emulation */
80 #if defined(CONFIG_USER_ONLY)
81 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
82 int mmu_idx, int is_softmmu)
84 int exception, error_code;
87 exception = POWERPC_EXCP_ISI;
88 error_code = 0x40000000;
90 exception = POWERPC_EXCP_DSI;
91 error_code = 0x40000000;
93 error_code |= 0x02000000;
94 env->spr[SPR_DAR] = address;
95 env->spr[SPR_DSISR] = error_code;
97 env->exception_index = exception;
98 env->error_code = error_code;
104 /* Common routines used by software and hardware TLBs emulation */
105 static inline int pte_is_valid(target_ulong pte0)
107 return pte0 & 0x80000000 ? 1 : 0;
110 static inline void pte_invalidate(target_ulong *pte0)
112 *pte0 &= ~0x80000000;
115 #if defined(TARGET_PPC64)
116 static inline int pte64_is_valid(target_ulong pte0)
118 return pte0 & 0x0000000000000001ULL ? 1 : 0;
121 static inline void pte64_invalidate(target_ulong *pte0)
123 *pte0 &= ~0x0000000000000001ULL;
127 #define PTE_PTEM_MASK 0x7FFFFFBF
128 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
129 #if defined(TARGET_PPC64)
130 #define PTE64_PTEM_MASK 0xFFFFFFFFFFFFFF80ULL
131 #define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F)
134 static inline int pp_check(int key, int pp, int nx)
138 /* Compute access rights */
139 /* When pp is 3/7, the result is undefined. Set it to noaccess */
146 access |= PAGE_WRITE;
164 access = PAGE_READ | PAGE_WRITE;
174 static inline int check_prot(int prot, int rw, int access_type)
178 if (access_type == ACCESS_CODE) {
179 if (prot & PAGE_EXEC)
184 if (prot & PAGE_WRITE)
189 if (prot & PAGE_READ)
198 static inline int _pte_check(mmu_ctx_t *ctx, int is_64b, target_ulong pte0,
199 target_ulong pte1, int h, int rw, int type)
201 target_ulong ptem, mmask;
202 int access, ret, pteh, ptev, pp;
205 /* Check validity and table match */
206 #if defined(TARGET_PPC64)
208 ptev = pte64_is_valid(pte0);
209 pteh = (pte0 >> 1) & 1;
213 ptev = pte_is_valid(pte0);
214 pteh = (pte0 >> 6) & 1;
216 if (ptev && h == pteh) {
217 /* Check vsid & api */
218 #if defined(TARGET_PPC64)
220 ptem = pte0 & PTE64_PTEM_MASK;
221 mmask = PTE64_CHECK_MASK;
222 pp = (pte1 & 0x00000003) | ((pte1 >> 61) & 0x00000004);
223 ctx->nx = (pte1 >> 2) & 1; /* No execute bit */
224 ctx->nx |= (pte1 >> 3) & 1; /* Guarded bit */
228 ptem = pte0 & PTE_PTEM_MASK;
229 mmask = PTE_CHECK_MASK;
230 pp = pte1 & 0x00000003;
232 if (ptem == ctx->ptem) {
233 if (ctx->raddr != (target_phys_addr_t)-1ULL) {
234 /* all matches should have equal RPN, WIMG & PP */
235 if ((ctx->raddr & mmask) != (pte1 & mmask)) {
236 qemu_log("Bad RPN/WIMG/PP\n");
240 /* Compute access rights */
241 access = pp_check(ctx->key, pp, ctx->nx);
242 /* Keep the matching PTE informations */
245 ret = check_prot(ctx->prot, rw, type);
248 LOG_MMU("PTE access granted !\n");
250 /* Access right violation */
251 LOG_MMU("PTE access rejected\n");
259 static inline int pte32_check(mmu_ctx_t *ctx, target_ulong pte0,
260 target_ulong pte1, int h, int rw, int type)
262 return _pte_check(ctx, 0, pte0, pte1, h, rw, type);
265 #if defined(TARGET_PPC64)
266 static inline int pte64_check(mmu_ctx_t *ctx, target_ulong pte0,
267 target_ulong pte1, int h, int rw, int type)
269 return _pte_check(ctx, 1, pte0, pte1, h, rw, type);
273 static inline int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
278 /* Update page flags */
279 if (!(*pte1p & 0x00000100)) {
280 /* Update accessed flag */
281 *pte1p |= 0x00000100;
284 if (!(*pte1p & 0x00000080)) {
285 if (rw == 1 && ret == 0) {
286 /* Update changed flag */
287 *pte1p |= 0x00000080;
290 /* Force page fault for first write access */
291 ctx->prot &= ~PAGE_WRITE;
298 /* Software driven TLB helpers */
299 static inline int ppc6xx_tlb_getnum(CPUState *env, target_ulong eaddr, int way,
304 /* Select TLB num in a way from address */
305 nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1);
307 nr += env->tlb_per_way * way;
308 /* 6xx have separate TLBs for instructions and data */
309 if (is_code && env->id_tlbs == 1)
315 static inline void ppc6xx_tlb_invalidate_all(CPUState *env)
320 //LOG_SWTLB("Invalidate all TLBs\n");
321 /* Invalidate all defined software TLB */
323 if (env->id_tlbs == 1)
325 for (nr = 0; nr < max; nr++) {
326 tlb = &env->tlb[nr].tlb6;
327 pte_invalidate(&tlb->pte0);
332 static inline void __ppc6xx_tlb_invalidate_virt(CPUState *env,
334 int is_code, int match_epn)
336 #if !defined(FLUSH_ALL_TLBS)
340 /* Invalidate ITLB + DTLB, all ways */
341 for (way = 0; way < env->nb_ways; way++) {
342 nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code);
343 tlb = &env->tlb[nr].tlb6;
344 if (pte_is_valid(tlb->pte0) && (match_epn == 0 || eaddr == tlb->EPN)) {
345 LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx "\n", nr,
347 pte_invalidate(&tlb->pte0);
348 tlb_flush_page(env, tlb->EPN);
352 /* XXX: PowerPC specification say this is valid as well */
353 ppc6xx_tlb_invalidate_all(env);
357 static inline void ppc6xx_tlb_invalidate_virt(CPUState *env,
358 target_ulong eaddr, int is_code)
360 __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0);
363 void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
364 target_ulong pte0, target_ulong pte1)
369 nr = ppc6xx_tlb_getnum(env, EPN, way, is_code);
370 tlb = &env->tlb[nr].tlb6;
371 LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx
372 " PTE1 " TARGET_FMT_lx "\n", nr, env->nb_tlb, EPN, pte0, pte1);
373 /* Invalidate any pending reference in Qemu for this virtual address */
374 __ppc6xx_tlb_invalidate_virt(env, EPN, is_code, 1);
378 /* Store last way for LRU mechanism */
382 static inline int ppc6xx_tlb_check(CPUState *env, mmu_ctx_t *ctx,
383 target_ulong eaddr, int rw, int access_type)
390 ret = -1; /* No TLB found */
391 for (way = 0; way < env->nb_ways; way++) {
392 nr = ppc6xx_tlb_getnum(env, eaddr, way,
393 access_type == ACCESS_CODE ? 1 : 0);
394 tlb = &env->tlb[nr].tlb6;
395 /* This test "emulates" the PTE index match for hardware TLBs */
396 if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) {
397 LOG_SWTLB("TLB %d/%d %s [" TARGET_FMT_lx " " TARGET_FMT_lx
398 "] <> " TARGET_FMT_lx "\n", nr, env->nb_tlb,
399 pte_is_valid(tlb->pte0) ? "valid" : "inval",
400 tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr);
403 LOG_SWTLB("TLB %d/%d %s " TARGET_FMT_lx " <> " TARGET_FMT_lx " "
404 TARGET_FMT_lx " %c %c\n", nr, env->nb_tlb,
405 pte_is_valid(tlb->pte0) ? "valid" : "inval",
406 tlb->EPN, eaddr, tlb->pte1,
407 rw ? 'S' : 'L', access_type == ACCESS_CODE ? 'I' : 'D');
408 switch (pte32_check(ctx, tlb->pte0, tlb->pte1, 0, rw, access_type)) {
410 /* TLB inconsistency */
413 /* Access violation */
423 /* XXX: we should go on looping to check all TLBs consistency
424 * but we can speed-up the whole thing as the
425 * result would be undefined if TLBs are not consistent.
434 LOG_SWTLB("found TLB at addr " TARGET_FMT_plx " prot=%01x ret=%d\n",
435 ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
436 /* Update page flags */
437 pte_update_flags(ctx, &env->tlb[best].tlb6.pte1, ret, rw);
443 /* Perform BAT hit & translation */
444 static inline void bat_size_prot(CPUState *env, target_ulong *blp, int *validp,
445 int *protp, target_ulong *BATu,
451 bl = (*BATu & 0x00001FFC) << 15;
454 if (((msr_pr == 0) && (*BATu & 0x00000002)) ||
455 ((msr_pr != 0) && (*BATu & 0x00000001))) {
457 pp = *BATl & 0x00000003;
459 prot = PAGE_READ | PAGE_EXEC;
469 static inline void bat_601_size_prot(CPUState *env, target_ulong *blp,
470 int *validp, int *protp,
471 target_ulong *BATu, target_ulong *BATl)
474 int key, pp, valid, prot;
476 bl = (*BATl & 0x0000003F) << 17;
477 LOG_BATS("b %02x ==> bl " TARGET_FMT_lx " msk " TARGET_FMT_lx "\n",
478 (uint8_t)(*BATl & 0x0000003F), bl, ~bl);
480 valid = (*BATl >> 6) & 1;
482 pp = *BATu & 0x00000003;
484 key = (*BATu >> 3) & 1;
486 key = (*BATu >> 2) & 1;
487 prot = pp_check(key, pp, 0);
494 static inline int get_bat(CPUState *env, mmu_ctx_t *ctx, target_ulong virtual,
497 target_ulong *BATlt, *BATut, *BATu, *BATl;
498 target_ulong BEPIl, BEPIu, bl;
502 LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
503 type == ACCESS_CODE ? 'I' : 'D', virtual);
506 BATlt = env->IBAT[1];
507 BATut = env->IBAT[0];
510 BATlt = env->DBAT[1];
511 BATut = env->DBAT[0];
514 for (i = 0; i < env->nb_BATs; i++) {
517 BEPIu = *BATu & 0xF0000000;
518 BEPIl = *BATu & 0x0FFE0000;
519 if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
520 bat_601_size_prot(env, &bl, &valid, &prot, BATu, BATl);
522 bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
524 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
525 " BATl " TARGET_FMT_lx "\n", __func__,
526 type == ACCESS_CODE ? 'I' : 'D', i, virtual, *BATu, *BATl);
527 if ((virtual & 0xF0000000) == BEPIu &&
528 ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
531 /* Get physical address */
532 ctx->raddr = (*BATl & 0xF0000000) |
533 ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
534 (virtual & 0x0001F000);
535 /* Compute access rights */
537 ret = check_prot(ctx->prot, rw, type);
539 LOG_BATS("BAT %d match: r " TARGET_FMT_plx " prot=%c%c\n",
540 i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-',
541 ctx->prot & PAGE_WRITE ? 'W' : '-');
547 #if defined(DEBUG_BATS)
548 if (qemu_log_enabled()) {
549 LOG_BATS("no BAT match for " TARGET_FMT_lx ":\n", virtual);
550 for (i = 0; i < 4; i++) {
553 BEPIu = *BATu & 0xF0000000;
554 BEPIl = *BATu & 0x0FFE0000;
555 bl = (*BATu & 0x00001FFC) << 15;
556 LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
557 " BATl " TARGET_FMT_lx " \n\t" TARGET_FMT_lx " "
558 TARGET_FMT_lx " " TARGET_FMT_lx "\n",
559 __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,
560 *BATu, *BATl, BEPIu, BEPIl, bl);
569 static inline target_phys_addr_t get_pteg_offset(CPUState *env,
570 target_phys_addr_t hash,
573 return (hash * pte_size * 8) & env->htab_mask;
576 /* PTE table lookup */
577 static inline int _find_pte(CPUState *env, mmu_ctx_t *ctx, int is_64b, int h,
578 int rw, int type, int target_page_bits)
580 target_phys_addr_t pteg_off;
581 target_ulong pte0, pte1;
585 ret = -1; /* No entry found */
586 pteg_off = get_pteg_offset(env, ctx->hash[h],
587 is_64b ? HASH_PTE_SIZE_64 : HASH_PTE_SIZE_32);
588 for (i = 0; i < 8; i++) {
589 #if defined(TARGET_PPC64)
591 if (env->external_htab) {
592 pte0 = ldq_p(env->external_htab + pteg_off + (i * 16));
593 pte1 = ldq_p(env->external_htab + pteg_off + (i * 16) + 8);
595 pte0 = ldq_phys(env->htab_base + pteg_off + (i * 16));
596 pte1 = ldq_phys(env->htab_base + pteg_off + (i * 16) + 8);
599 /* We have a TLB that saves 4K pages, so let's
600 * split a huge page to 4k chunks */
601 if (target_page_bits != TARGET_PAGE_BITS)
602 pte1 |= (ctx->eaddr & (( 1 << target_page_bits ) - 1))
605 r = pte64_check(ctx, pte0, pte1, h, rw, type);
606 LOG_MMU("Load pte from " TARGET_FMT_lx " => " TARGET_FMT_lx " "
607 TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
608 pteg_off + (i * 16), pte0, pte1, (int)(pte0 & 1), h,
609 (int)((pte0 >> 1) & 1), ctx->ptem);
613 if (env->external_htab) {
614 pte0 = ldl_p(env->external_htab + pteg_off + (i * 8));
615 pte1 = ldl_p(env->external_htab + pteg_off + (i * 8) + 4);
617 pte0 = ldl_phys(env->htab_base + pteg_off + (i * 8));
618 pte1 = ldl_phys(env->htab_base + pteg_off + (i * 8) + 4);
620 r = pte32_check(ctx, pte0, pte1, h, rw, type);
621 LOG_MMU("Load pte from " TARGET_FMT_lx " => " TARGET_FMT_lx " "
622 TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
623 pteg_off + (i * 8), pte0, pte1, (int)(pte0 >> 31), h,
624 (int)((pte0 >> 6) & 1), ctx->ptem);
628 /* PTE inconsistency */
631 /* Access violation */
641 /* XXX: we should go on looping to check all PTEs consistency
642 * but if we can speed-up the whole thing as the
643 * result would be undefined if PTEs are not consistent.
652 LOG_MMU("found PTE at addr " TARGET_FMT_lx " prot=%01x ret=%d\n",
653 ctx->raddr, ctx->prot, ret);
654 /* Update page flags */
656 if (pte_update_flags(ctx, &pte1, ret, rw) == 1) {
657 #if defined(TARGET_PPC64)
659 if (env->external_htab) {
660 stq_p(env->external_htab + pteg_off + (good * 16) + 8,
663 stq_phys_notdirty(env->htab_base + pteg_off +
664 (good * 16) + 8, pte1);
669 if (env->external_htab) {
670 stl_p(env->external_htab + pteg_off + (good * 8) + 4,
673 stl_phys_notdirty(env->htab_base + pteg_off +
674 (good * 8) + 4, pte1);
683 static inline int find_pte(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
684 int type, int target_page_bits)
686 #if defined(TARGET_PPC64)
687 if (env->mmu_model & POWERPC_MMU_64)
688 return _find_pte(env, ctx, 1, h, rw, type, target_page_bits);
691 return _find_pte(env, ctx, 0, h, rw, type, target_page_bits);
694 #if defined(TARGET_PPC64)
695 static inline ppc_slb_t *slb_lookup(CPUPPCState *env, target_ulong eaddr)
697 uint64_t esid_256M, esid_1T;
700 LOG_SLB("%s: eaddr " TARGET_FMT_lx "\n", __func__, eaddr);
702 esid_256M = (eaddr & SEGMENT_MASK_256M) | SLB_ESID_V;
703 esid_1T = (eaddr & SEGMENT_MASK_1T) | SLB_ESID_V;
705 for (n = 0; n < env->slb_nr; n++) {
706 ppc_slb_t *slb = &env->slb[n];
708 LOG_SLB("%s: slot %d %016" PRIx64 " %016"
709 PRIx64 "\n", __func__, n, slb->esid, slb->vsid);
710 /* We check for 1T matches on all MMUs here - if the MMU
711 * doesn't have 1T segment support, we will have prevented 1T
712 * entries from being inserted in the slbmte code. */
713 if (((slb->esid == esid_256M) &&
714 ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_256M))
715 || ((slb->esid == esid_1T) &&
716 ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_1T))) {
724 void ppc_slb_invalidate_all (CPUPPCState *env)
726 int n, do_invalidate;
729 /* XXX: Warning: slbia never invalidates the first segment */
730 for (n = 1; n < env->slb_nr; n++) {
731 ppc_slb_t *slb = &env->slb[n];
733 if (slb->esid & SLB_ESID_V) {
734 slb->esid &= ~SLB_ESID_V;
735 /* XXX: given the fact that segment size is 256 MB or 1TB,
736 * and we still don't have a tlb_flush_mask(env, n, mask)
737 * in Qemu, we just invalidate all TLBs
746 void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
750 slb = slb_lookup(env, T0);
755 if (slb->esid & SLB_ESID_V) {
756 slb->esid &= ~SLB_ESID_V;
758 /* XXX: given the fact that segment size is 256 MB or 1TB,
759 * and we still don't have a tlb_flush_mask(env, n, mask)
760 * in Qemu, we just invalidate all TLBs
766 int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs)
768 int slot = rb & 0xfff;
769 ppc_slb_t *slb = &env->slb[slot];
771 if (rb & (0x1000 - env->slb_nr)) {
772 return -1; /* Reserved bits set or slot too high */
774 if (rs & (SLB_VSID_B & ~SLB_VSID_B_1T)) {
775 return -1; /* Bad segment size */
777 if ((rs & SLB_VSID_B) && !(env->mmu_model & POWERPC_MMU_1TSEG)) {
778 return -1; /* 1T segment on MMU that doesn't support it */
781 /* Mask out the slot number as we store the entry */
782 slb->esid = rb & (SLB_ESID_ESID | SLB_ESID_V);
785 LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64
786 " %016" PRIx64 "\n", __func__, slot, rb, rs,
787 slb->esid, slb->vsid);
792 int ppc_load_slb_esid (CPUPPCState *env, target_ulong rb, target_ulong *rt)
794 int slot = rb & 0xfff;
795 ppc_slb_t *slb = &env->slb[slot];
797 if (slot >= env->slb_nr) {
805 int ppc_load_slb_vsid (CPUPPCState *env, target_ulong rb, target_ulong *rt)
807 int slot = rb & 0xfff;
808 ppc_slb_t *slb = &env->slb[slot];
810 if (slot >= env->slb_nr) {
817 #endif /* defined(TARGET_PPC64) */
819 /* Perform segment based translation */
820 static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
821 target_ulong eaddr, int rw, int type)
823 target_phys_addr_t hash;
825 int ds, pr, target_page_bits;
830 #if defined(TARGET_PPC64)
831 if (env->mmu_model & POWERPC_MMU_64) {
833 target_ulong pageaddr;
836 LOG_MMU("Check SLBs\n");
837 slb = slb_lookup(env, eaddr);
842 if (slb->vsid & SLB_VSID_B) {
843 vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT_1T;
846 vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
850 target_page_bits = (slb->vsid & SLB_VSID_L)
851 ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
852 ctx->key = !!(pr ? (slb->vsid & SLB_VSID_KP)
853 : (slb->vsid & SLB_VSID_KS));
855 ctx->nx = !!(slb->vsid & SLB_VSID_N);
857 pageaddr = eaddr & ((1ULL << segment_bits)
858 - (1ULL << target_page_bits));
859 if (slb->vsid & SLB_VSID_B) {
860 hash = vsid ^ (vsid << 25) ^ (pageaddr >> target_page_bits);
862 hash = vsid ^ (pageaddr >> target_page_bits);
864 /* Only 5 bits of the page index are used in the AVPN */
865 ctx->ptem = (slb->vsid & SLB_VSID_PTEM) |
866 ((pageaddr >> 16) & ((1ULL << segment_bits) - 0x80));
868 #endif /* defined(TARGET_PPC64) */
870 target_ulong sr, pgidx;
872 sr = env->sr[eaddr >> 28];
873 ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
874 ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
875 ds = sr & 0x80000000 ? 1 : 0;
876 ctx->nx = sr & 0x10000000 ? 1 : 0;
877 vsid = sr & 0x00FFFFFF;
878 target_page_bits = TARGET_PAGE_BITS;
879 LOG_MMU("Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx " nip="
880 TARGET_FMT_lx " lr=" TARGET_FMT_lx
881 " ir=%d dr=%d pr=%d %d t=%d\n",
882 eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir,
883 (int)msr_dr, pr != 0 ? 1 : 0, rw, type);
884 pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits;
886 ctx->ptem = (vsid << 7) | (pgidx >> 10);
888 LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n",
889 ctx->key, ds, ctx->nx, vsid);
892 /* Check if instruction fetch is allowed, if needed */
893 if (type != ACCESS_CODE || ctx->nx == 0) {
894 /* Page address translation */
895 LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
896 " hash " TARGET_FMT_plx "\n",
897 env->htab_base, env->htab_mask, hash);
899 ctx->hash[1] = ~hash;
901 /* Initialize real address with an invalid value */
902 ctx->raddr = (target_phys_addr_t)-1ULL;
903 if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx ||
904 env->mmu_model == POWERPC_MMU_SOFT_74xx)) {
905 /* Software TLB search */
906 ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
908 LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
909 " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
910 " hash=" TARGET_FMT_plx "\n",
911 env->htab_base, env->htab_mask, vsid, ctx->ptem,
913 /* Primary table lookup */
914 ret = find_pte(env, ctx, 0, rw, type, target_page_bits);
916 /* Secondary table lookup */
917 if (eaddr != 0xEFFFFFFF)
918 LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
919 " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
920 " hash=" TARGET_FMT_plx "\n", env->htab_base,
921 env->htab_mask, vsid, ctx->ptem, ctx->hash[1]);
922 ret2 = find_pte(env, ctx, 1, rw, type,
928 #if defined (DUMP_PAGE_TABLES)
929 if (qemu_log_enabled()) {
930 target_phys_addr_t curaddr;
931 uint32_t a0, a1, a2, a3;
932 qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx
933 "\n", sdr, mask + 0x80);
934 for (curaddr = sdr; curaddr < (sdr + mask + 0x80);
936 a0 = ldl_phys(curaddr);
937 a1 = ldl_phys(curaddr + 4);
938 a2 = ldl_phys(curaddr + 8);
939 a3 = ldl_phys(curaddr + 12);
940 if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
941 qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n",
942 curaddr, a0, a1, a2, a3);
948 LOG_MMU("No access allowed\n");
953 LOG_MMU("direct store...\n");
954 /* Direct-store segment : absolutely *BUGGY* for now */
956 /* Direct-store implies a 32-bit MMU.
957 * Check the Segment Register's bus unit ID (BUID).
959 sr = env->sr[eaddr >> 28];
960 if ((sr & 0x1FF00000) >> 20 == 0x07f) {
961 /* Memory-forced I/O controller interface access */
962 /* If T=1 and BUID=x'07F', the 601 performs a memory access
963 * to SR[28-31] LA[4-31], bypassing all protection mechanisms.
965 ctx->raddr = ((sr & 0xF) << 28) | (eaddr & 0x0FFFFFFF);
966 ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
972 /* Integer load/store : only access allowed */
975 /* No code fetch is allowed in direct-store areas */
978 /* Floating point load/store */
981 /* lwarx, ldarx or srwcx. */
984 /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
985 /* Should make the instruction do no-op.
986 * As it already do no-op, it's quite easy :-)
994 qemu_log("ERROR: instruction should not need "
995 "address translation\n");
998 if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) {
1009 /* Generic TLB check function for embedded PowerPC implementations */
1010 int ppcemb_tlb_check(CPUState *env, ppcemb_tlb_t *tlb,
1011 target_phys_addr_t *raddrp,
1012 target_ulong address, uint32_t pid, int ext,
1017 /* Check valid flag */
1018 if (!(tlb->prot & PAGE_VALID)) {
1021 mask = ~(tlb->size - 1);
1022 LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx " PID %u <=> " TARGET_FMT_lx
1023 " " TARGET_FMT_lx " %u %x\n", __func__, i, address, pid, tlb->EPN,
1024 mask, (uint32_t)tlb->PID, tlb->prot);
1026 if (tlb->PID != 0 && tlb->PID != pid)
1028 /* Check effective address */
1029 if ((address & mask) != tlb->EPN)
1031 *raddrp = (tlb->RPN & mask) | (address & ~mask);
1032 #if (TARGET_PHYS_ADDR_BITS >= 36)
1034 /* Extend the physical address to 36 bits */
1035 *raddrp |= (target_phys_addr_t)(tlb->RPN & 0xF) << 32;
1042 /* Generic TLB search function for PowerPC embedded implementations */
1043 int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid)
1046 target_phys_addr_t raddr;
1049 /* Default return value is no match */
1051 for (i = 0; i < env->nb_tlb; i++) {
1052 tlb = &env->tlb[i].tlbe;
1053 if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, 0, i) == 0) {
1062 /* Helpers specific to PowerPC 40x implementations */
1063 static inline void ppc4xx_tlb_invalidate_all(CPUState *env)
1068 for (i = 0; i < env->nb_tlb; i++) {
1069 tlb = &env->tlb[i].tlbe;
1070 tlb->prot &= ~PAGE_VALID;
1075 static inline void ppc4xx_tlb_invalidate_virt(CPUState *env,
1076 target_ulong eaddr, uint32_t pid)
1078 #if !defined(FLUSH_ALL_TLBS)
1080 target_phys_addr_t raddr;
1081 target_ulong page, end;
1084 for (i = 0; i < env->nb_tlb; i++) {
1085 tlb = &env->tlb[i].tlbe;
1086 if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) {
1087 end = tlb->EPN + tlb->size;
1088 for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
1089 tlb_flush_page(env, page);
1090 tlb->prot &= ~PAGE_VALID;
1095 ppc4xx_tlb_invalidate_all(env);
1099 static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1100 target_ulong address, int rw, int access_type)
1103 target_phys_addr_t raddr;
1104 int i, ret, zsel, zpr, pr;
1107 raddr = (target_phys_addr_t)-1ULL;
1109 for (i = 0; i < env->nb_tlb; i++) {
1110 tlb = &env->tlb[i].tlbe;
1111 if (ppcemb_tlb_check(env, tlb, &raddr, address,
1112 env->spr[SPR_40x_PID], 0, i) < 0)
1114 zsel = (tlb->attr >> 4) & 0xF;
1115 zpr = (env->spr[SPR_40x_ZPR] >> (30 - (2 * zsel))) & 0x3;
1116 LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
1117 __func__, i, zsel, zpr, rw, tlb->attr);
1118 /* Check execute enable bit */
1125 /* All accesses granted */
1126 ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
1131 /* Raise Zone protection fault. */
1132 env->spr[SPR_40x_ESR] = 1 << 22;
1140 /* Check from TLB entry */
1141 ctx->prot = tlb->prot;
1142 ret = check_prot(ctx->prot, rw, access_type);
1144 env->spr[SPR_40x_ESR] = 0;
1149 LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
1150 " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
1155 LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
1156 " %d %d\n", __func__, address, raddr, ctx->prot, ret);
1161 void store_40x_sler (CPUPPCState *env, uint32_t val)
1163 /* XXX: TO BE FIXED */
1164 if (val != 0x00000000) {
1165 cpu_abort(env, "Little-endian regions are not supported by now\n");
1167 env->spr[SPR_405_SLER] = val;
1170 static inline int mmubooke_check_tlb (CPUState *env, ppcemb_tlb_t *tlb,
1171 target_phys_addr_t *raddr, int *prot,
1172 target_ulong address, int rw,
1173 int access_type, int i)
1177 if (ppcemb_tlb_check(env, tlb, raddr, address,
1178 env->spr[SPR_BOOKE_PID],
1179 !env->nb_pids, i) >= 0) {
1183 if (env->spr[SPR_BOOKE_PID1] &&
1184 ppcemb_tlb_check(env, tlb, raddr, address,
1185 env->spr[SPR_BOOKE_PID1], 0, i) >= 0) {
1189 if (env->spr[SPR_BOOKE_PID2] &&
1190 ppcemb_tlb_check(env, tlb, raddr, address,
1191 env->spr[SPR_BOOKE_PID2], 0, i) >= 0) {
1195 LOG_SWTLB("%s: TLB entry not found\n", __func__);
1201 _prot = tlb->prot & 0xF;
1203 _prot = (tlb->prot >> 4) & 0xF;
1206 /* Check the address space */
1207 if (access_type == ACCESS_CODE) {
1208 if (msr_ir != (tlb->attr & 1)) {
1209 LOG_SWTLB("%s: AS doesn't match\n", __func__);
1214 if (_prot & PAGE_EXEC) {
1215 LOG_SWTLB("%s: good TLB!\n", __func__);
1219 LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, _prot);
1222 if (msr_dr != (tlb->attr & 1)) {
1223 LOG_SWTLB("%s: AS doesn't match\n", __func__);
1228 if ((!rw && _prot & PAGE_READ) || (rw && (_prot & PAGE_WRITE))) {
1229 LOG_SWTLB("%s: found TLB!\n", __func__);
1233 LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, _prot);
1240 static int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1241 target_ulong address, int rw,
1245 target_phys_addr_t raddr;
1249 raddr = (target_phys_addr_t)-1ULL;
1250 for (i = 0; i < env->nb_tlb; i++) {
1251 tlb = &env->tlb[i].tlbe;
1252 ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address, rw,
1261 LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
1262 " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
1265 LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
1266 " %d %d\n", __func__, address, raddr, ctx->prot, ret);
1272 void booke206_flush_tlb(CPUState *env, int flags, const int check_iprot)
1276 ppc_tlb_t *tlb = env->tlb;
1278 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
1279 if (flags & (1 << i)) {
1280 tlb_size = booke206_tlb_size(env, i);
1281 for (j = 0; j < tlb_size; j++) {
1282 if (!check_iprot || !(tlb[j].tlbe.attr & MAS1_IPROT)) {
1283 tlb[j].tlbe.prot = 0;
1287 tlb += booke206_tlb_size(env, i);
1293 static int mmubooke206_get_physical_address(CPUState *env, mmu_ctx_t *ctx,
1294 target_ulong address, int rw,
1298 target_phys_addr_t raddr;
1302 raddr = (target_phys_addr_t)-1ULL;
1304 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
1305 int ways = booke206_tlb_ways(env, i);
1307 for (j = 0; j < ways; j++) {
1308 tlb = booke206_get_tlbe(env, i, address, j);
1309 ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address, rw,
1321 LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
1322 " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
1325 LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
1326 " %d %d\n", __func__, address, raddr, ctx->prot, ret);
1332 static inline int check_physical(CPUState *env, mmu_ctx_t *ctx,
1333 target_ulong eaddr, int rw)
1338 ctx->prot = PAGE_READ | PAGE_EXEC;
1340 switch (env->mmu_model) {
1341 case POWERPC_MMU_32B:
1342 case POWERPC_MMU_601:
1343 case POWERPC_MMU_SOFT_6xx:
1344 case POWERPC_MMU_SOFT_74xx:
1345 case POWERPC_MMU_SOFT_4xx:
1346 case POWERPC_MMU_REAL:
1347 case POWERPC_MMU_BOOKE:
1348 ctx->prot |= PAGE_WRITE;
1350 #if defined(TARGET_PPC64)
1351 case POWERPC_MMU_620:
1352 case POWERPC_MMU_64B:
1353 case POWERPC_MMU_2_06:
1354 /* Real address are 60 bits long */
1355 ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL;
1356 ctx->prot |= PAGE_WRITE;
1359 case POWERPC_MMU_SOFT_4xx_Z:
1360 if (unlikely(msr_pe != 0)) {
1361 /* 403 family add some particular protections,
1362 * using PBL/PBU registers for accesses with no translation.
1365 /* Check PLB validity */
1366 (env->pb[0] < env->pb[1] &&
1367 /* and address in plb area */
1368 eaddr >= env->pb[0] && eaddr < env->pb[1]) ||
1369 (env->pb[2] < env->pb[3] &&
1370 eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0;
1371 if (in_plb ^ msr_px) {
1372 /* Access in protected area */
1374 /* Access is not allowed */
1378 /* Read-write access is allowed */
1379 ctx->prot |= PAGE_WRITE;
1383 case POWERPC_MMU_MPC8xx:
1385 cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1387 case POWERPC_MMU_BOOKE206:
1388 cpu_abort(env, "BookE 2.06 MMU doesn't have physical real mode\n");
1391 cpu_abort(env, "Unknown or invalid MMU model\n");
1398 int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
1399 int rw, int access_type)
1404 qemu_log("%s\n", __func__);
1406 if ((access_type == ACCESS_CODE && msr_ir == 0) ||
1407 (access_type != ACCESS_CODE && msr_dr == 0)) {
1408 if (env->mmu_model == POWERPC_MMU_BOOKE) {
1409 /* The BookE MMU always performs address translation. The
1410 IS and DS bits only affect the address space. */
1411 ret = mmubooke_get_physical_address(env, ctx, eaddr,
1413 } else if (env->mmu_model == POWERPC_MMU_BOOKE206) {
1414 ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw,
1417 /* No address translation. */
1418 ret = check_physical(env, ctx, eaddr, rw);
1422 switch (env->mmu_model) {
1423 case POWERPC_MMU_32B:
1424 case POWERPC_MMU_601:
1425 case POWERPC_MMU_SOFT_6xx:
1426 case POWERPC_MMU_SOFT_74xx:
1427 /* Try to find a BAT */
1428 if (env->nb_BATs != 0)
1429 ret = get_bat(env, ctx, eaddr, rw, access_type);
1430 #if defined(TARGET_PPC64)
1431 case POWERPC_MMU_620:
1432 case POWERPC_MMU_64B:
1433 case POWERPC_MMU_2_06:
1436 /* We didn't match any BAT entry or don't have BATs */
1437 ret = get_segment(env, ctx, eaddr, rw, access_type);
1440 case POWERPC_MMU_SOFT_4xx:
1441 case POWERPC_MMU_SOFT_4xx_Z:
1442 ret = mmu40x_get_physical_address(env, ctx, eaddr,
1445 case POWERPC_MMU_BOOKE:
1446 ret = mmubooke_get_physical_address(env, ctx, eaddr,
1449 case POWERPC_MMU_BOOKE206:
1450 ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw,
1453 case POWERPC_MMU_MPC8xx:
1455 cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1457 case POWERPC_MMU_REAL:
1458 cpu_abort(env, "PowerPC in real mode do not do any translation\n");
1461 cpu_abort(env, "Unknown or invalid MMU model\n");
1466 qemu_log("%s address " TARGET_FMT_lx " => %d " TARGET_FMT_plx "\n",
1467 __func__, eaddr, ret, ctx->raddr);
1473 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
1477 if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0))
1480 return ctx.raddr & TARGET_PAGE_MASK;
1483 static void booke206_update_mas_tlb_miss(CPUState *env, target_ulong address,
1486 env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK;
1487 env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK;
1488 env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK;
1489 env->spr[SPR_BOOKE_MAS3] = 0;
1490 env->spr[SPR_BOOKE_MAS6] = 0;
1491 env->spr[SPR_BOOKE_MAS7] = 0;
1494 if (((rw == 2) && msr_ir) || ((rw != 2) && msr_dr)) {
1495 env->spr[SPR_BOOKE_MAS1] |= MAS1_TS;
1496 env->spr[SPR_BOOKE_MAS6] |= MAS6_SAS;
1499 env->spr[SPR_BOOKE_MAS1] |= MAS1_VALID;
1500 env->spr[SPR_BOOKE_MAS2] |= address & MAS2_EPN_MASK;
1502 switch (env->spr[SPR_BOOKE_MAS4] & MAS4_TIDSELD_PIDZ) {
1503 case MAS4_TIDSELD_PID0:
1504 env->spr[SPR_BOOKE_MAS1] |= env->spr[SPR_BOOKE_PID] << MAS1_TID_SHIFT;
1506 case MAS4_TIDSELD_PID1:
1507 env->spr[SPR_BOOKE_MAS1] |= env->spr[SPR_BOOKE_PID1] << MAS1_TID_SHIFT;
1509 case MAS4_TIDSELD_PID2:
1510 env->spr[SPR_BOOKE_MAS1] |= env->spr[SPR_BOOKE_PID2] << MAS1_TID_SHIFT;
1514 env->spr[SPR_BOOKE_MAS6] |= env->spr[SPR_BOOKE_PID] << 16;
1516 /* next victim logic */
1517 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
1519 env->last_way &= booke206_tlb_ways(env, 0) - 1;
1520 env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
1523 /* Perform address translation */
1524 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1525 int mmu_idx, int is_softmmu)
1534 access_type = ACCESS_CODE;
1537 access_type = env->access_type;
1539 ret = get_physical_address(env, &ctx, address, rw, access_type);
1541 tlb_set_page(env, address & TARGET_PAGE_MASK,
1542 ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
1543 mmu_idx, TARGET_PAGE_SIZE);
1545 } else if (ret < 0) {
1547 if (access_type == ACCESS_CODE) {
1550 /* No matches in page tables or TLB */
1551 switch (env->mmu_model) {
1552 case POWERPC_MMU_SOFT_6xx:
1553 env->exception_index = POWERPC_EXCP_IFTLB;
1554 env->error_code = 1 << 18;
1555 env->spr[SPR_IMISS] = address;
1556 env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
1558 case POWERPC_MMU_SOFT_74xx:
1559 env->exception_index = POWERPC_EXCP_IFTLB;
1561 case POWERPC_MMU_SOFT_4xx:
1562 case POWERPC_MMU_SOFT_4xx_Z:
1563 env->exception_index = POWERPC_EXCP_ITLB;
1564 env->error_code = 0;
1565 env->spr[SPR_40x_DEAR] = address;
1566 env->spr[SPR_40x_ESR] = 0x00000000;
1568 case POWERPC_MMU_32B:
1569 case POWERPC_MMU_601:
1570 #if defined(TARGET_PPC64)
1571 case POWERPC_MMU_620:
1572 case POWERPC_MMU_64B:
1573 case POWERPC_MMU_2_06:
1575 env->exception_index = POWERPC_EXCP_ISI;
1576 env->error_code = 0x40000000;
1578 case POWERPC_MMU_BOOKE206:
1579 booke206_update_mas_tlb_miss(env, address, rw);
1581 case POWERPC_MMU_BOOKE:
1582 env->exception_index = POWERPC_EXCP_ITLB;
1583 env->error_code = 0;
1584 env->spr[SPR_BOOKE_DEAR] = address;
1586 case POWERPC_MMU_MPC8xx:
1588 cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1590 case POWERPC_MMU_REAL:
1591 cpu_abort(env, "PowerPC in real mode should never raise "
1592 "any MMU exceptions\n");
1595 cpu_abort(env, "Unknown or invalid MMU model\n");
1600 /* Access rights violation */
1601 env->exception_index = POWERPC_EXCP_ISI;
1602 env->error_code = 0x08000000;
1605 /* No execute protection violation */
1606 if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1607 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1608 env->spr[SPR_BOOKE_ESR] = 0x00000000;
1610 env->exception_index = POWERPC_EXCP_ISI;
1611 env->error_code = 0x10000000;
1614 /* Direct store exception */
1615 /* No code fetch is allowed in direct-store areas */
1616 env->exception_index = POWERPC_EXCP_ISI;
1617 env->error_code = 0x10000000;
1619 #if defined(TARGET_PPC64)
1621 /* No match in segment table */
1622 if (env->mmu_model == POWERPC_MMU_620) {
1623 env->exception_index = POWERPC_EXCP_ISI;
1624 /* XXX: this might be incorrect */
1625 env->error_code = 0x40000000;
1627 env->exception_index = POWERPC_EXCP_ISEG;
1628 env->error_code = 0;
1636 /* No matches in page tables or TLB */
1637 switch (env->mmu_model) {
1638 case POWERPC_MMU_SOFT_6xx:
1640 env->exception_index = POWERPC_EXCP_DSTLB;
1641 env->error_code = 1 << 16;
1643 env->exception_index = POWERPC_EXCP_DLTLB;
1644 env->error_code = 0;
1646 env->spr[SPR_DMISS] = address;
1647 env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
1649 env->error_code |= ctx.key << 19;
1650 env->spr[SPR_HASH1] = env->htab_base +
1651 get_pteg_offset(env, ctx.hash[0], HASH_PTE_SIZE_32);
1652 env->spr[SPR_HASH2] = env->htab_base +
1653 get_pteg_offset(env, ctx.hash[1], HASH_PTE_SIZE_32);
1655 case POWERPC_MMU_SOFT_74xx:
1657 env->exception_index = POWERPC_EXCP_DSTLB;
1659 env->exception_index = POWERPC_EXCP_DLTLB;
1662 /* Implement LRU algorithm */
1663 env->error_code = ctx.key << 19;
1664 env->spr[SPR_TLBMISS] = (address & ~((target_ulong)0x3)) |
1665 ((env->last_way + 1) & (env->nb_ways - 1));
1666 env->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem;
1668 case POWERPC_MMU_SOFT_4xx:
1669 case POWERPC_MMU_SOFT_4xx_Z:
1670 env->exception_index = POWERPC_EXCP_DTLB;
1671 env->error_code = 0;
1672 env->spr[SPR_40x_DEAR] = address;
1674 env->spr[SPR_40x_ESR] = 0x00800000;
1676 env->spr[SPR_40x_ESR] = 0x00000000;
1678 case POWERPC_MMU_32B:
1679 case POWERPC_MMU_601:
1680 #if defined(TARGET_PPC64)
1681 case POWERPC_MMU_620:
1682 case POWERPC_MMU_64B:
1683 case POWERPC_MMU_2_06:
1685 env->exception_index = POWERPC_EXCP_DSI;
1686 env->error_code = 0;
1687 env->spr[SPR_DAR] = address;
1689 env->spr[SPR_DSISR] = 0x42000000;
1691 env->spr[SPR_DSISR] = 0x40000000;
1693 case POWERPC_MMU_MPC8xx:
1695 cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1697 case POWERPC_MMU_BOOKE206:
1698 booke206_update_mas_tlb_miss(env, address, rw);
1700 case POWERPC_MMU_BOOKE:
1701 env->exception_index = POWERPC_EXCP_DTLB;
1702 env->error_code = 0;
1703 env->spr[SPR_BOOKE_DEAR] = address;
1704 env->spr[SPR_BOOKE_ESR] = rw ? 1 << ESR_ST : 0;
1706 case POWERPC_MMU_REAL:
1707 cpu_abort(env, "PowerPC in real mode should never raise "
1708 "any MMU exceptions\n");
1711 cpu_abort(env, "Unknown or invalid MMU model\n");
1716 /* Access rights violation */
1717 env->exception_index = POWERPC_EXCP_DSI;
1718 env->error_code = 0;
1719 if (env->mmu_model == POWERPC_MMU_SOFT_4xx
1720 || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) {
1721 env->spr[SPR_40x_DEAR] = address;
1723 env->spr[SPR_40x_ESR] |= 0x00800000;
1725 } else if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
1726 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
1727 env->spr[SPR_BOOKE_DEAR] = address;
1728 env->spr[SPR_BOOKE_ESR] = rw ? 1 << ESR_ST : 0;
1730 env->spr[SPR_DAR] = address;
1732 env->spr[SPR_DSISR] = 0x0A000000;
1734 env->spr[SPR_DSISR] = 0x08000000;
1739 /* Direct store exception */
1740 switch (access_type) {
1742 /* Floating point load/store */
1743 env->exception_index = POWERPC_EXCP_ALIGN;
1744 env->error_code = POWERPC_EXCP_ALIGN_FP;
1745 env->spr[SPR_DAR] = address;
1748 /* lwarx, ldarx or stwcx. */
1749 env->exception_index = POWERPC_EXCP_DSI;
1750 env->error_code = 0;
1751 env->spr[SPR_DAR] = address;
1753 env->spr[SPR_DSISR] = 0x06000000;
1755 env->spr[SPR_DSISR] = 0x04000000;
1758 /* eciwx or ecowx */
1759 env->exception_index = POWERPC_EXCP_DSI;
1760 env->error_code = 0;
1761 env->spr[SPR_DAR] = address;
1763 env->spr[SPR_DSISR] = 0x06100000;
1765 env->spr[SPR_DSISR] = 0x04100000;
1768 printf("DSI: invalid exception (%d)\n", ret);
1769 env->exception_index = POWERPC_EXCP_PROGRAM;
1771 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
1772 env->spr[SPR_DAR] = address;
1776 #if defined(TARGET_PPC64)
1778 /* No match in segment table */
1779 if (env->mmu_model == POWERPC_MMU_620) {
1780 env->exception_index = POWERPC_EXCP_DSI;
1781 env->error_code = 0;
1782 env->spr[SPR_DAR] = address;
1783 /* XXX: this might be incorrect */
1785 env->spr[SPR_DSISR] = 0x42000000;
1787 env->spr[SPR_DSISR] = 0x40000000;
1789 env->exception_index = POWERPC_EXCP_DSEG;
1790 env->error_code = 0;
1791 env->spr[SPR_DAR] = address;
1798 printf("%s: set exception to %d %02x\n", __func__,
1799 env->exception, env->error_code);
1807 /*****************************************************************************/
1808 /* BATs management */
1809 #if !defined(FLUSH_ALL_TLBS)
1810 static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu,
1813 target_ulong base, end, page;
1815 base = BATu & ~0x0001FFFF;
1816 end = base + mask + 0x00020000;
1817 LOG_BATS("Flush BAT from " TARGET_FMT_lx " to " TARGET_FMT_lx " ("
1818 TARGET_FMT_lx ")\n", base, end, mask);
1819 for (page = base; page != end; page += TARGET_PAGE_SIZE)
1820 tlb_flush_page(env, page);
1821 LOG_BATS("Flush done\n");
1825 static inline void dump_store_bat(CPUPPCState *env, char ID, int ul, int nr,
1828 LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n", ID,
1829 nr, ul == 0 ? 'u' : 'l', value, env->nip);
1832 void ppc_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
1836 dump_store_bat(env, 'I', 0, nr, value);
1837 if (env->IBAT[0][nr] != value) {
1838 mask = (value << 15) & 0x0FFE0000UL;
1839 #if !defined(FLUSH_ALL_TLBS)
1840 do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1842 /* When storing valid upper BAT, mask BEPI and BRPN
1843 * and invalidate all TLBs covered by this BAT
1845 mask = (value << 15) & 0x0FFE0000UL;
1846 env->IBAT[0][nr] = (value & 0x00001FFFUL) |
1847 (value & ~0x0001FFFFUL & ~mask);
1848 env->IBAT[1][nr] = (env->IBAT[1][nr] & 0x0000007B) |
1849 (env->IBAT[1][nr] & ~0x0001FFFF & ~mask);
1850 #if !defined(FLUSH_ALL_TLBS)
1851 do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1858 void ppc_store_ibatl (CPUPPCState *env, int nr, target_ulong value)
1860 dump_store_bat(env, 'I', 1, nr, value);
1861 env->IBAT[1][nr] = value;
1864 void ppc_store_dbatu (CPUPPCState *env, int nr, target_ulong value)
1868 dump_store_bat(env, 'D', 0, nr, value);
1869 if (env->DBAT[0][nr] != value) {
1870 /* When storing valid upper BAT, mask BEPI and BRPN
1871 * and invalidate all TLBs covered by this BAT
1873 mask = (value << 15) & 0x0FFE0000UL;
1874 #if !defined(FLUSH_ALL_TLBS)
1875 do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1877 mask = (value << 15) & 0x0FFE0000UL;
1878 env->DBAT[0][nr] = (value & 0x00001FFFUL) |
1879 (value & ~0x0001FFFFUL & ~mask);
1880 env->DBAT[1][nr] = (env->DBAT[1][nr] & 0x0000007B) |
1881 (env->DBAT[1][nr] & ~0x0001FFFF & ~mask);
1882 #if !defined(FLUSH_ALL_TLBS)
1883 do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1890 void ppc_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
1892 dump_store_bat(env, 'D', 1, nr, value);
1893 env->DBAT[1][nr] = value;
1896 void ppc_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value)
1899 #if defined(FLUSH_ALL_TLBS)
1903 dump_store_bat(env, 'I', 0, nr, value);
1904 if (env->IBAT[0][nr] != value) {
1905 #if defined(FLUSH_ALL_TLBS)
1908 mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
1909 if (env->IBAT[1][nr] & 0x40) {
1910 /* Invalidate BAT only if it is valid */
1911 #if !defined(FLUSH_ALL_TLBS)
1912 do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1917 /* When storing valid upper BAT, mask BEPI and BRPN
1918 * and invalidate all TLBs covered by this BAT
1920 env->IBAT[0][nr] = (value & 0x00001FFFUL) |
1921 (value & ~0x0001FFFFUL & ~mask);
1922 env->DBAT[0][nr] = env->IBAT[0][nr];
1923 if (env->IBAT[1][nr] & 0x40) {
1924 #if !defined(FLUSH_ALL_TLBS)
1925 do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1930 #if defined(FLUSH_ALL_TLBS)
1937 void ppc_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value)
1940 #if defined(FLUSH_ALL_TLBS)
1944 dump_store_bat(env, 'I', 1, nr, value);
1945 if (env->IBAT[1][nr] != value) {
1946 #if defined(FLUSH_ALL_TLBS)
1949 if (env->IBAT[1][nr] & 0x40) {
1950 #if !defined(FLUSH_ALL_TLBS)
1951 mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
1952 do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1958 #if !defined(FLUSH_ALL_TLBS)
1959 mask = (value << 17) & 0x0FFE0000UL;
1960 do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1965 env->IBAT[1][nr] = value;
1966 env->DBAT[1][nr] = value;
1967 #if defined(FLUSH_ALL_TLBS)
1974 /*****************************************************************************/
1975 /* TLB management */
1976 void ppc_tlb_invalidate_all (CPUPPCState *env)
1978 switch (env->mmu_model) {
1979 case POWERPC_MMU_SOFT_6xx:
1980 case POWERPC_MMU_SOFT_74xx:
1981 ppc6xx_tlb_invalidate_all(env);
1983 case POWERPC_MMU_SOFT_4xx:
1984 case POWERPC_MMU_SOFT_4xx_Z:
1985 ppc4xx_tlb_invalidate_all(env);
1987 case POWERPC_MMU_REAL:
1988 cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
1990 case POWERPC_MMU_MPC8xx:
1992 cpu_abort(env, "MPC8xx MMU model is not implemented\n");
1994 case POWERPC_MMU_BOOKE:
1997 case POWERPC_MMU_BOOKE206:
1998 booke206_flush_tlb(env, -1, 0);
2000 case POWERPC_MMU_32B:
2001 case POWERPC_MMU_601:
2002 #if defined(TARGET_PPC64)
2003 case POWERPC_MMU_620:
2004 case POWERPC_MMU_64B:
2005 case POWERPC_MMU_2_06:
2006 #endif /* defined(TARGET_PPC64) */
2011 cpu_abort(env, "Unknown MMU model\n");
2016 void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
2018 #if !defined(FLUSH_ALL_TLBS)
2019 addr &= TARGET_PAGE_MASK;
2020 switch (env->mmu_model) {
2021 case POWERPC_MMU_SOFT_6xx:
2022 case POWERPC_MMU_SOFT_74xx:
2023 ppc6xx_tlb_invalidate_virt(env, addr, 0);
2024 if (env->id_tlbs == 1)
2025 ppc6xx_tlb_invalidate_virt(env, addr, 1);
2027 case POWERPC_MMU_SOFT_4xx:
2028 case POWERPC_MMU_SOFT_4xx_Z:
2029 ppc4xx_tlb_invalidate_virt(env, addr, env->spr[SPR_40x_PID]);
2031 case POWERPC_MMU_REAL:
2032 cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
2034 case POWERPC_MMU_MPC8xx:
2036 cpu_abort(env, "MPC8xx MMU model is not implemented\n");
2038 case POWERPC_MMU_BOOKE:
2040 cpu_abort(env, "BookE MMU model is not implemented\n");
2042 case POWERPC_MMU_BOOKE206:
2044 cpu_abort(env, "BookE 2.06 MMU model is not implemented\n");
2046 case POWERPC_MMU_32B:
2047 case POWERPC_MMU_601:
2048 /* tlbie invalidate TLBs for all segments */
2049 addr &= ~((target_ulong)-1ULL << 28);
2050 /* XXX: this case should be optimized,
2051 * giving a mask to tlb_flush_page
2053 tlb_flush_page(env, addr | (0x0 << 28));
2054 tlb_flush_page(env, addr | (0x1 << 28));
2055 tlb_flush_page(env, addr | (0x2 << 28));
2056 tlb_flush_page(env, addr | (0x3 << 28));
2057 tlb_flush_page(env, addr | (0x4 << 28));
2058 tlb_flush_page(env, addr | (0x5 << 28));
2059 tlb_flush_page(env, addr | (0x6 << 28));
2060 tlb_flush_page(env, addr | (0x7 << 28));
2061 tlb_flush_page(env, addr | (0x8 << 28));
2062 tlb_flush_page(env, addr | (0x9 << 28));
2063 tlb_flush_page(env, addr | (0xA << 28));
2064 tlb_flush_page(env, addr | (0xB << 28));
2065 tlb_flush_page(env, addr | (0xC << 28));
2066 tlb_flush_page(env, addr | (0xD << 28));
2067 tlb_flush_page(env, addr | (0xE << 28));
2068 tlb_flush_page(env, addr | (0xF << 28));
2070 #if defined(TARGET_PPC64)
2071 case POWERPC_MMU_620:
2072 case POWERPC_MMU_64B:
2073 case POWERPC_MMU_2_06:
2074 /* tlbie invalidate TLBs for all segments */
2075 /* XXX: given the fact that there are too many segments to invalidate,
2076 * and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
2077 * we just invalidate all TLBs
2081 #endif /* defined(TARGET_PPC64) */
2084 cpu_abort(env, "Unknown MMU model\n");
2088 ppc_tlb_invalidate_all(env);
2092 /*****************************************************************************/
2093 /* Special registers manipulation */
2094 #if defined(TARGET_PPC64)
2095 void ppc_store_asr (CPUPPCState *env, target_ulong value)
2097 if (env->asr != value) {
2104 void ppc_store_sdr1 (CPUPPCState *env, target_ulong value)
2106 LOG_MMU("%s: " TARGET_FMT_lx "\n", __func__, value);
2107 if (env->spr[SPR_SDR1] != value) {
2108 env->spr[SPR_SDR1] = value;
2109 #if defined(TARGET_PPC64)
2110 if (env->mmu_model & POWERPC_MMU_64) {
2111 target_ulong htabsize = value & SDR_64_HTABSIZE;
2113 if (htabsize > 28) {
2114 fprintf(stderr, "Invalid HTABSIZE 0x" TARGET_FMT_lx
2115 " stored in SDR1\n", htabsize);
2118 env->htab_mask = (1ULL << (htabsize + 18)) - 1;
2119 env->htab_base = value & SDR_64_HTABORG;
2121 #endif /* defined(TARGET_PPC64) */
2123 /* FIXME: Should check for valid HTABMASK values */
2124 env->htab_mask = ((value & SDR_32_HTABMASK) << 16) | 0xFFFF;
2125 env->htab_base = value & SDR_32_HTABORG;
2131 #if defined(TARGET_PPC64)
2132 target_ulong ppc_load_sr (CPUPPCState *env, int slb_nr)
2139 void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value)
2141 LOG_MMU("%s: reg=%d " TARGET_FMT_lx " " TARGET_FMT_lx "\n", __func__,
2142 srnum, value, env->sr[srnum]);
2143 #if defined(TARGET_PPC64)
2144 if (env->mmu_model & POWERPC_MMU_64) {
2145 uint64_t rb = 0, rs = 0;
2148 rb |= ((uint32_t)srnum & 0xf) << 28;
2149 /* Set the valid bit */
2152 rb |= (uint32_t)srnum;
2155 rs |= (value & 0xfffffff) << 12;
2157 rs |= ((value >> 27) & 0xf) << 8;
2159 ppc_store_slb(env, rb, rs);
2162 if (env->sr[srnum] != value) {
2163 env->sr[srnum] = value;
2164 /* Invalidating 256MB of virtual memory in 4kB pages is way longer than
2165 flusing the whole TLB. */
2166 #if !defined(FLUSH_ALL_TLBS) && 0
2168 target_ulong page, end;
2169 /* Invalidate 256 MB of virtual memory */
2170 page = (16 << 20) * srnum;
2171 end = page + (16 << 20);
2172 for (; page != end; page += TARGET_PAGE_SIZE)
2173 tlb_flush_page(env, page);
2180 #endif /* !defined (CONFIG_USER_ONLY) */
2182 /* GDBstub can read and write MSR... */
2183 void ppc_store_msr (CPUPPCState *env, target_ulong value)
2185 hreg_store_msr(env, value, 0);
2188 /*****************************************************************************/
2189 /* Exception processing */
2190 #if defined (CONFIG_USER_ONLY)
2191 void do_interrupt (CPUState *env)
2193 env->exception_index = POWERPC_EXCP_NONE;
2194 env->error_code = 0;
2197 void ppc_hw_interrupt (CPUState *env)
2199 env->exception_index = POWERPC_EXCP_NONE;
2200 env->error_code = 0;
2202 #else /* defined (CONFIG_USER_ONLY) */
2203 static inline void dump_syscall(CPUState *env)
2205 qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 " r3=%016" PRIx64
2206 " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
2207 " nip=" TARGET_FMT_lx "\n",
2208 ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
2209 ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
2210 ppc_dump_gpr(env, 6), env->nip);
2213 /* Note that this function should be greatly optimized
2214 * when called with a constant excp, from ppc_hw_interrupt
2216 static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
2218 target_ulong msr, new_msr, vector;
2219 int srr0, srr1, asrr0, asrr1;
2220 int lpes0, lpes1, lev;
2223 /* XXX: find a suitable condition to enable the hypervisor mode */
2224 lpes0 = (env->spr[SPR_LPCR] >> 1) & 1;
2225 lpes1 = (env->spr[SPR_LPCR] >> 2) & 1;
2227 /* Those values ensure we won't enter the hypervisor mode */
2232 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
2233 " => %08x (%02x)\n", env->nip, excp, env->error_code);
2235 /* new srr1 value excluding must-be-zero bits */
2236 msr = env->msr & ~0x783f0000ULL;
2238 /* new interrupt handler msr */
2239 new_msr = env->msr & ((target_ulong)1 << MSR_ME);
2241 /* target registers */
2248 case POWERPC_EXCP_NONE:
2249 /* Should never happen */
2251 case POWERPC_EXCP_CRITICAL: /* Critical input */
2252 switch (excp_model) {
2253 case POWERPC_EXCP_40x:
2254 srr0 = SPR_40x_SRR2;
2255 srr1 = SPR_40x_SRR3;
2257 case POWERPC_EXCP_BOOKE:
2258 srr0 = SPR_BOOKE_CSRR0;
2259 srr1 = SPR_BOOKE_CSRR1;
2261 case POWERPC_EXCP_G2:
2267 case POWERPC_EXCP_MCHECK: /* Machine check exception */
2269 /* Machine check exception is not enabled.
2270 * Enter checkstop state.
2272 if (qemu_log_enabled()) {
2273 qemu_log("Machine check while not allowed. "
2274 "Entering checkstop state\n");
2276 fprintf(stderr, "Machine check while not allowed. "
2277 "Entering checkstop state\n");
2280 env->interrupt_request |= CPU_INTERRUPT_EXITTB;
2283 /* XXX: find a suitable condition to enable the hypervisor mode */
2284 new_msr |= (target_ulong)MSR_HVB;
2287 /* machine check exceptions don't have ME set */
2288 new_msr &= ~((target_ulong)1 << MSR_ME);
2290 /* XXX: should also have something loaded in DAR / DSISR */
2291 switch (excp_model) {
2292 case POWERPC_EXCP_40x:
2293 srr0 = SPR_40x_SRR2;
2294 srr1 = SPR_40x_SRR3;
2296 case POWERPC_EXCP_BOOKE:
2297 srr0 = SPR_BOOKE_MCSRR0;
2298 srr1 = SPR_BOOKE_MCSRR1;
2299 asrr0 = SPR_BOOKE_CSRR0;
2300 asrr1 = SPR_BOOKE_CSRR1;
2306 case POWERPC_EXCP_DSI: /* Data storage exception */
2307 LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx
2308 "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
2310 new_msr |= (target_ulong)MSR_HVB;
2312 case POWERPC_EXCP_ISI: /* Instruction storage exception */
2313 LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx
2314 "\n", msr, env->nip);
2316 new_msr |= (target_ulong)MSR_HVB;
2317 msr |= env->error_code;
2319 case POWERPC_EXCP_EXTERNAL: /* External input */
2321 new_msr |= (target_ulong)MSR_HVB;
2323 case POWERPC_EXCP_ALIGN: /* Alignment exception */
2325 new_msr |= (target_ulong)MSR_HVB;
2326 /* XXX: this is false */
2327 /* Get rS/rD and rA from faulting opcode */
2328 env->spr[SPR_DSISR] |= (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
2330 case POWERPC_EXCP_PROGRAM: /* Program exception */
2331 switch (env->error_code & ~0xF) {
2332 case POWERPC_EXCP_FP:
2333 if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
2334 LOG_EXCP("Ignore floating point exception\n");
2335 env->exception_index = POWERPC_EXCP_NONE;
2336 env->error_code = 0;
2340 new_msr |= (target_ulong)MSR_HVB;
2342 if (msr_fe0 == msr_fe1)
2346 case POWERPC_EXCP_INVAL:
2347 LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);
2349 new_msr |= (target_ulong)MSR_HVB;
2352 case POWERPC_EXCP_PRIV:
2354 new_msr |= (target_ulong)MSR_HVB;
2357 case POWERPC_EXCP_TRAP:
2359 new_msr |= (target_ulong)MSR_HVB;
2363 /* Should never occur */
2364 cpu_abort(env, "Invalid program exception %d. Aborting\n",
2369 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
2371 new_msr |= (target_ulong)MSR_HVB;
2373 case POWERPC_EXCP_SYSCALL: /* System call exception */
2375 lev = env->error_code;
2376 if ((lev == 1) && cpu_ppc_hypercall) {
2377 cpu_ppc_hypercall(env);
2380 if (lev == 1 || (lpes0 == 0 && lpes1 == 0))
2381 new_msr |= (target_ulong)MSR_HVB;
2383 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
2385 case POWERPC_EXCP_DECR: /* Decrementer exception */
2387 new_msr |= (target_ulong)MSR_HVB;
2389 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
2391 LOG_EXCP("FIT exception\n");
2393 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
2394 LOG_EXCP("WDT exception\n");
2395 switch (excp_model) {
2396 case POWERPC_EXCP_BOOKE:
2397 srr0 = SPR_BOOKE_CSRR0;
2398 srr1 = SPR_BOOKE_CSRR1;
2404 case POWERPC_EXCP_DTLB: /* Data TLB error */
2406 case POWERPC_EXCP_ITLB: /* Instruction TLB error */
2408 case POWERPC_EXCP_DEBUG: /* Debug interrupt */
2409 switch (excp_model) {
2410 case POWERPC_EXCP_BOOKE:
2411 srr0 = SPR_BOOKE_DSRR0;
2412 srr1 = SPR_BOOKE_DSRR1;
2413 asrr0 = SPR_BOOKE_CSRR0;
2414 asrr1 = SPR_BOOKE_CSRR1;
2420 cpu_abort(env, "Debug exception is not implemented yet !\n");
2422 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable */
2424 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */
2426 cpu_abort(env, "Embedded floating point data exception "
2427 "is not implemented yet !\n");
2429 case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */
2431 cpu_abort(env, "Embedded floating point round exception "
2432 "is not implemented yet !\n");
2434 case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */
2437 "Performance counter exception is not implemented yet !\n");
2439 case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */
2442 "Embedded doorbell interrupt is not implemented yet !\n");
2444 case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */
2445 switch (excp_model) {
2446 case POWERPC_EXCP_BOOKE:
2447 srr0 = SPR_BOOKE_CSRR0;
2448 srr1 = SPR_BOOKE_CSRR1;
2454 cpu_abort(env, "Embedded doorbell critical interrupt "
2455 "is not implemented yet !\n");
2457 case POWERPC_EXCP_RESET: /* System reset exception */
2459 /* indicate that we resumed from power save mode */
2462 new_msr &= ~((target_ulong)1 << MSR_ME);
2466 /* XXX: find a suitable condition to enable the hypervisor mode */
2467 new_msr |= (target_ulong)MSR_HVB;
2470 case POWERPC_EXCP_DSEG: /* Data segment exception */
2472 new_msr |= (target_ulong)MSR_HVB;
2474 case POWERPC_EXCP_ISEG: /* Instruction segment exception */
2476 new_msr |= (target_ulong)MSR_HVB;
2478 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
2481 new_msr |= (target_ulong)MSR_HVB;
2482 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2484 case POWERPC_EXCP_TRACE: /* Trace exception */
2486 new_msr |= (target_ulong)MSR_HVB;
2488 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
2491 new_msr |= (target_ulong)MSR_HVB;
2492 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2494 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */
2497 new_msr |= (target_ulong)MSR_HVB;
2498 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2500 case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
2503 new_msr |= (target_ulong)MSR_HVB;
2504 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2506 case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */
2509 new_msr |= (target_ulong)MSR_HVB;
2510 new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
2512 case POWERPC_EXCP_VPU: /* Vector unavailable exception */
2514 new_msr |= (target_ulong)MSR_HVB;
2516 case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */
2517 LOG_EXCP("PIT exception\n");
2519 case POWERPC_EXCP_IO: /* IO error exception */
2521 cpu_abort(env, "601 IO error exception is not implemented yet !\n");
2523 case POWERPC_EXCP_RUNM: /* Run mode exception */
2525 cpu_abort(env, "601 run mode exception is not implemented yet !\n");
2527 case POWERPC_EXCP_EMUL: /* Emulation trap exception */
2529 cpu_abort(env, "602 emulation trap exception "
2530 "is not implemented yet !\n");
2532 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
2533 if (lpes1 == 0) /* XXX: check this */
2534 new_msr |= (target_ulong)MSR_HVB;
2535 switch (excp_model) {
2536 case POWERPC_EXCP_602:
2537 case POWERPC_EXCP_603:
2538 case POWERPC_EXCP_603E:
2539 case POWERPC_EXCP_G2:
2541 case POWERPC_EXCP_7x5:
2543 case POWERPC_EXCP_74xx:
2546 cpu_abort(env, "Invalid instruction TLB miss exception\n");
2550 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
2551 if (lpes1 == 0) /* XXX: check this */
2552 new_msr |= (target_ulong)MSR_HVB;
2553 switch (excp_model) {
2554 case POWERPC_EXCP_602:
2555 case POWERPC_EXCP_603:
2556 case POWERPC_EXCP_603E:
2557 case POWERPC_EXCP_G2:
2559 case POWERPC_EXCP_7x5:
2561 case POWERPC_EXCP_74xx:
2564 cpu_abort(env, "Invalid data load TLB miss exception\n");
2568 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
2569 if (lpes1 == 0) /* XXX: check this */
2570 new_msr |= (target_ulong)MSR_HVB;
2571 switch (excp_model) {
2572 case POWERPC_EXCP_602:
2573 case POWERPC_EXCP_603:
2574 case POWERPC_EXCP_603E:
2575 case POWERPC_EXCP_G2:
2577 /* Swap temporary saved registers with GPRs */
2578 if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
2579 new_msr |= (target_ulong)1 << MSR_TGPR;
2580 hreg_swap_gpr_tgpr(env);
2583 case POWERPC_EXCP_7x5:
2585 #if defined (DEBUG_SOFTWARE_TLB)
2586 if (qemu_log_enabled()) {
2588 target_ulong *miss, *cmp;
2590 if (excp == POWERPC_EXCP_IFTLB) {
2593 miss = &env->spr[SPR_IMISS];
2594 cmp = &env->spr[SPR_ICMP];
2596 if (excp == POWERPC_EXCP_DLTLB)
2601 miss = &env->spr[SPR_DMISS];
2602 cmp = &env->spr[SPR_DCMP];
2604 qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
2605 TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "
2606 TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
2607 env->spr[SPR_HASH1], env->spr[SPR_HASH2],
2611 msr |= env->crf[0] << 28;
2612 msr |= env->error_code; /* key, D/I, S/L bits */
2613 /* Set way using a LRU mechanism */
2614 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
2616 case POWERPC_EXCP_74xx:
2618 #if defined (DEBUG_SOFTWARE_TLB)
2619 if (qemu_log_enabled()) {
2621 target_ulong *miss, *cmp;
2623 if (excp == POWERPC_EXCP_IFTLB) {
2626 miss = &env->spr[SPR_TLBMISS];
2627 cmp = &env->spr[SPR_PTEHI];
2629 if (excp == POWERPC_EXCP_DLTLB)
2634 miss = &env->spr[SPR_TLBMISS];
2635 cmp = &env->spr[SPR_PTEHI];
2637 qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
2638 TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
2642 msr |= env->error_code; /* key bit */
2645 cpu_abort(env, "Invalid data store TLB miss exception\n");
2649 case POWERPC_EXCP_FPA: /* Floating-point assist exception */
2651 cpu_abort(env, "Floating point assist exception "
2652 "is not implemented yet !\n");
2654 case POWERPC_EXCP_DABR: /* Data address breakpoint */
2656 cpu_abort(env, "DABR exception is not implemented yet !\n");
2658 case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
2660 cpu_abort(env, "IABR exception is not implemented yet !\n");
2662 case POWERPC_EXCP_SMI: /* System management interrupt */
2664 cpu_abort(env, "SMI exception is not implemented yet !\n");
2666 case POWERPC_EXCP_THERM: /* Thermal interrupt */
2668 cpu_abort(env, "Thermal management exception "
2669 "is not implemented yet !\n");
2671 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */
2673 new_msr |= (target_ulong)MSR_HVB;
2676 "Performance counter exception is not implemented yet !\n");
2678 case POWERPC_EXCP_VPUA: /* Vector assist exception */
2680 cpu_abort(env, "VPU assist exception is not implemented yet !\n");
2682 case POWERPC_EXCP_SOFTP: /* Soft patch exception */
2685 "970 soft-patch exception is not implemented yet !\n");
2687 case POWERPC_EXCP_MAINT: /* Maintenance exception */
2690 "970 maintenance exception is not implemented yet !\n");
2692 case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */
2694 cpu_abort(env, "Maskable external exception "
2695 "is not implemented yet !\n");
2697 case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */
2699 cpu_abort(env, "Non maskable external exception "
2700 "is not implemented yet !\n");
2704 cpu_abort(env, "Invalid PowerPC exception %d. Aborting\n", excp);
2707 /* save current instruction location */
2708 env->spr[srr0] = env->nip - 4;
2711 /* save next instruction location */
2712 env->spr[srr0] = env->nip;
2716 env->spr[srr1] = msr;
2717 /* If any alternate SRR register are defined, duplicate saved values */
2719 env->spr[asrr0] = env->spr[srr0];
2721 env->spr[asrr1] = env->spr[srr1];
2722 /* If we disactivated any translation, flush TLBs */
2723 if (new_msr & ((1 << MSR_IR) | (1 << MSR_DR)))
2727 new_msr |= (target_ulong)1 << MSR_LE;
2730 /* Jump to handler */
2731 vector = env->excp_vectors[excp];
2732 if (vector == (target_ulong)-1ULL) {
2733 cpu_abort(env, "Raised an exception without defined vector %d\n",
2736 vector |= env->excp_prefix;
2737 #if defined(TARGET_PPC64)
2738 if (excp_model == POWERPC_EXCP_BOOKE) {
2740 vector = (uint32_t)vector;
2742 new_msr |= (target_ulong)1 << MSR_CM;
2745 if (!msr_isf && !(env->mmu_model & POWERPC_MMU_64)) {
2746 vector = (uint32_t)vector;
2748 new_msr |= (target_ulong)1 << MSR_SF;
2752 /* XXX: we don't use hreg_store_msr here as already have treated
2753 * any special case that could occur. Just store MSR and update hflags
2755 env->msr = new_msr & env->msr_mask;
2756 hreg_compute_hflags(env);
2758 /* Reset exception state */
2759 env->exception_index = POWERPC_EXCP_NONE;
2760 env->error_code = 0;
2762 if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
2763 (env->mmu_model == POWERPC_MMU_BOOKE206)) {
2764 /* XXX: The BookE changes address space when switching modes,
2765 we should probably implement that as different MMU indexes,
2766 but for the moment we do it the slow way and flush all. */
2771 void do_interrupt (CPUState *env)
2773 powerpc_excp(env, env->excp_model, env->exception_index);
2776 void ppc_hw_interrupt (CPUPPCState *env)
2781 qemu_log_mask(CPU_LOG_INT, "%s: %p pending %08x req %08x me %d ee %d\n",
2782 __func__, env, env->pending_interrupts,
2783 env->interrupt_request, (int)msr_me, (int)msr_ee);
2785 /* External reset */
2786 if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
2787 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
2788 powerpc_excp(env, env->excp_model, POWERPC_EXCP_RESET);
2791 /* Machine check exception */
2792 if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
2793 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
2794 powerpc_excp(env, env->excp_model, POWERPC_EXCP_MCHECK);
2798 /* External debug exception */
2799 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
2800 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
2801 powerpc_excp(env, env->excp_model, POWERPC_EXCP_DEBUG);
2806 /* XXX: find a suitable condition to enable the hypervisor mode */
2807 hdice = env->spr[SPR_LPCR] & 1;
2811 if ((msr_ee != 0 || msr_hv == 0 || msr_pr != 0) && hdice != 0) {
2812 /* Hypervisor decrementer exception */
2813 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
2814 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
2815 powerpc_excp(env, env->excp_model, POWERPC_EXCP_HDECR);
2820 /* External critical interrupt */
2821 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
2822 /* Taking a critical external interrupt does not clear the external
2823 * critical interrupt status
2826 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CEXT);
2828 powerpc_excp(env, env->excp_model, POWERPC_EXCP_CRITICAL);
2833 /* Watchdog timer on embedded PowerPC */
2834 if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
2835 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
2836 powerpc_excp(env, env->excp_model, POWERPC_EXCP_WDT);
2839 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
2840 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
2841 powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORCI);
2844 /* Fixed interval timer on embedded PowerPC */
2845 if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
2846 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
2847 powerpc_excp(env, env->excp_model, POWERPC_EXCP_FIT);
2850 /* Programmable interval timer on embedded PowerPC */
2851 if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
2852 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
2853 powerpc_excp(env, env->excp_model, POWERPC_EXCP_PIT);
2856 /* Decrementer exception */
2857 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
2858 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
2859 powerpc_excp(env, env->excp_model, POWERPC_EXCP_DECR);
2862 /* External interrupt */
2863 if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
2864 /* Taking an external interrupt does not clear the external
2868 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
2870 powerpc_excp(env, env->excp_model, POWERPC_EXCP_EXTERNAL);
2873 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
2874 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
2875 powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORI);
2878 if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
2879 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
2880 powerpc_excp(env, env->excp_model, POWERPC_EXCP_PERFM);
2883 /* Thermal interrupt */
2884 if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
2885 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
2886 powerpc_excp(env, env->excp_model, POWERPC_EXCP_THERM);
2891 #endif /* !CONFIG_USER_ONLY */
2893 void cpu_dump_rfi (target_ulong RA, target_ulong msr)
2895 qemu_log("Return from exception at " TARGET_FMT_lx " with flags "
2896 TARGET_FMT_lx "\n", RA, msr);
2899 void cpu_reset(CPUPPCState *env)
2903 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
2904 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
2905 log_cpu_state(env, 0);
2908 msr = (target_ulong)0;
2910 /* XXX: find a suitable condition to enable the hypervisor mode */
2911 msr |= (target_ulong)MSR_HVB;
2913 msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
2914 msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
2915 msr |= (target_ulong)1 << MSR_EP;
2916 #if defined (DO_SINGLE_STEP) && 0
2917 /* Single step trace mode */
2918 msr |= (target_ulong)1 << MSR_SE;
2919 msr |= (target_ulong)1 << MSR_BE;
2921 #if defined(CONFIG_USER_ONLY)
2922 msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
2923 msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
2924 msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
2925 msr |= (target_ulong)1 << MSR_PR;
2927 env->excp_prefix = env->hreset_excp_prefix;
2928 env->nip = env->hreset_vector | env->excp_prefix;
2929 if (env->mmu_model != POWERPC_MMU_REAL)
2930 ppc_tlb_invalidate_all(env);
2932 env->msr = msr & env->msr_mask;
2933 #if defined(TARGET_PPC64)
2934 if (env->mmu_model & POWERPC_MMU_64)
2935 env->msr |= (1ULL << MSR_SF);
2937 hreg_compute_hflags(env);
2938 env->reserve_addr = (target_ulong)-1ULL;
2939 /* Be sure no exception or interrupt is pending */
2940 env->pending_interrupts = 0;
2941 env->exception_index = POWERPC_EXCP_NONE;
2942 env->error_code = 0;
2943 /* Flush all TLBs */
2947 CPUPPCState *cpu_ppc_init (const char *cpu_model)
2950 const ppc_def_t *def;
2952 def = cpu_ppc_find_by_name(cpu_model);
2956 env = qemu_mallocz(sizeof(CPUPPCState));
2958 ppc_translate_init();
2959 env->cpu_model_str = cpu_model;
2960 cpu_ppc_register_internal(env, def);
2962 qemu_init_vcpu(env);
2967 void cpu_ppc_close (CPUPPCState *env)
2969 /* Should also remove all opcode tables... */