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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 //#define DEBUG_SOFTWARE_TLB
34 //#define DEBUG_EXCEPTIONS
35 //#define FLUSH_ALL_TLBS
37 /*****************************************************************************/
38 /* PowerPC MMU emulation */
40 #if defined(CONFIG_USER_ONLY)
41 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
42 int is_user, int is_softmmu)
44 int exception, error_code;
53 error_code |= 0x02000000;
54 env->spr[SPR_DAR] = address;
55 env->spr[SPR_DSISR] = error_code;
57 env->exception_index = exception;
58 env->error_code = error_code;
63 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
69 /* Common routines used by software and hardware TLBs emulation */
70 static inline int pte_is_valid (target_ulong pte0)
72 return pte0 & 0x80000000 ? 1 : 0;
75 static inline void pte_invalidate (target_ulong *pte0)
80 #define PTE_PTEM_MASK 0x7FFFFFBF
81 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
83 static int pte_check (mmu_ctx_t *ctx,
84 target_ulong pte0, target_ulong pte1, int h, int rw)
90 /* Check validity and table match */
91 if (pte_is_valid(pte0) && (h == ((pte0 >> 6) & 1))) {
92 /* Check vsid & api */
93 if ((pte0 & PTE_PTEM_MASK) == ctx->ptem) {
94 if (ctx->raddr != (target_ulong)-1) {
95 /* all matches should have equal RPN, WIMG & PP */
96 if ((ctx->raddr & PTE_CHECK_MASK) != (pte1 & PTE_CHECK_MASK)) {
98 fprintf(logfile, "Bad RPN/WIMG/PP\n");
102 /* Compute access rights */
105 if ((pte1 & 0x00000003) != 0x3)
106 access |= PAGE_WRITE;
108 switch (pte1 & 0x00000003) {
117 access = PAGE_READ | PAGE_WRITE;
121 /* Keep the matching PTE informations */
124 if ((rw == 0 && (access & PAGE_READ)) ||
125 (rw == 1 && (access & PAGE_WRITE))) {
127 #if defined (DEBUG_MMU)
129 fprintf(logfile, "PTE access granted !\n");
133 /* Access right violation */
134 #if defined (DEBUG_MMU)
136 fprintf(logfile, "PTE access rejected\n");
146 static int pte_update_flags (mmu_ctx_t *ctx, target_ulong *pte1p,
151 /* Update page flags */
152 if (!(*pte1p & 0x00000100)) {
153 /* Update accessed flag */
154 *pte1p |= 0x00000100;
157 if (!(*pte1p & 0x00000080)) {
158 if (rw == 1 && ret == 0) {
159 /* Update changed flag */
160 *pte1p |= 0x00000080;
163 /* Force page fault for first write access */
164 ctx->prot &= ~PAGE_WRITE;
171 /* Software driven TLB helpers */
172 static int ppc6xx_tlb_getnum (CPUState *env, target_ulong eaddr,
173 int way, int is_code)
177 /* Select TLB num in a way from address */
178 nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1);
180 nr += env->tlb_per_way * way;
181 /* 6xx have separate TLBs for instructions and data */
182 if (is_code && env->id_tlbs == 1)
188 void ppc6xx_tlb_invalidate_all (CPUState *env)
193 #if defined (DEBUG_SOFTWARE_TLB) && 0
195 fprintf(logfile, "Invalidate all TLBs\n");
198 /* Invalidate all defined software TLB */
200 if (env->id_tlbs == 1)
202 for (nr = 0; nr < max; nr++) {
203 tlb = &env->tlb[nr].tlb6;
204 #if !defined(FLUSH_ALL_TLBS)
205 tlb_flush_page(env, tlb->EPN);
207 pte_invalidate(&tlb->pte0);
209 #if defined(FLUSH_ALL_TLBS)
214 static inline void __ppc6xx_tlb_invalidate_virt (CPUState *env,
216 int is_code, int match_epn)
218 #if !defined(FLUSH_ALL_TLBS)
222 /* Invalidate ITLB + DTLB, all ways */
223 for (way = 0; way < env->nb_ways; way++) {
224 nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code);
225 tlb = &env->tlb[nr].tlb6;
226 if (pte_is_valid(tlb->pte0) && (match_epn == 0 || eaddr == tlb->EPN)) {
227 #if defined (DEBUG_SOFTWARE_TLB)
229 fprintf(logfile, "TLB invalidate %d/%d " ADDRX "\n",
230 nr, env->nb_tlb, eaddr);
233 pte_invalidate(&tlb->pte0);
234 tlb_flush_page(env, tlb->EPN);
238 /* XXX: PowerPC specification say this is valid as well */
239 ppc6xx_tlb_invalidate_all(env);
243 void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
246 __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0);
249 void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
250 target_ulong pte0, target_ulong pte1)
255 nr = ppc6xx_tlb_getnum(env, EPN, way, is_code);
256 tlb = &env->tlb[nr].tlb6;
257 #if defined (DEBUG_SOFTWARE_TLB)
259 fprintf(logfile, "Set TLB %d/%d EPN " ADDRX " PTE0 " ADDRX
260 " PTE1 " ADDRX "\n", nr, env->nb_tlb, EPN, pte0, pte1);
263 /* Invalidate any pending reference in Qemu for this virtual address */
264 __ppc6xx_tlb_invalidate_virt(env, EPN, is_code, 1);
268 /* Store last way for LRU mechanism */
272 static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx,
273 target_ulong eaddr, int rw, int access_type)
280 ret = -1; /* No TLB found */
281 for (way = 0; way < env->nb_ways; way++) {
282 nr = ppc6xx_tlb_getnum(env, eaddr, way,
283 access_type == ACCESS_CODE ? 1 : 0);
284 tlb = &env->tlb[nr].tlb6;
285 /* This test "emulates" the PTE index match for hardware TLBs */
286 if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) {
287 #if defined (DEBUG_SOFTWARE_TLB)
289 fprintf(logfile, "TLB %d/%d %s [" ADDRX " " ADDRX
292 pte_is_valid(tlb->pte0) ? "valid" : "inval",
293 tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr);
298 #if defined (DEBUG_SOFTWARE_TLB)
300 fprintf(logfile, "TLB %d/%d %s " ADDRX " <> " ADDRX " " ADDRX
303 pte_is_valid(tlb->pte0) ? "valid" : "inval",
304 tlb->EPN, eaddr, tlb->pte1,
305 rw ? 'S' : 'L', access_type == ACCESS_CODE ? 'I' : 'D');
308 switch (pte_check(ctx, tlb->pte0, tlb->pte1, 0, rw)) {
310 /* TLB inconsistency */
313 /* Access violation */
323 /* XXX: we should go on looping to check all TLBs consistency
324 * but we can speed-up the whole thing as the
325 * result would be undefined if TLBs are not consistent.
334 #if defined (DEBUG_SOFTWARE_TLB)
336 fprintf(logfile, "found TLB at addr 0x%08lx prot=0x%01x ret=%d\n",
337 ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
340 /* Update page flags */
341 pte_update_flags(ctx, &env->tlb[best].tlb6.pte1, ret, rw);
347 /* Perform BAT hit & translation */
348 static int get_bat (CPUState *env, mmu_ctx_t *ctx,
349 target_ulong virtual, int rw, int type)
351 target_ulong *BATlt, *BATut, *BATu, *BATl;
352 target_ulong base, BEPIl, BEPIu, bl;
356 #if defined (DEBUG_BATS)
358 fprintf(logfile, "%s: %cBAT v 0x" ADDRX "\n", __func__,
359 type == ACCESS_CODE ? 'I' : 'D', virtual);
364 BATlt = env->IBAT[1];
365 BATut = env->IBAT[0];
368 BATlt = env->DBAT[1];
369 BATut = env->DBAT[0];
372 #if defined (DEBUG_BATS)
374 fprintf(logfile, "%s...: %cBAT v 0x" ADDRX "\n", __func__,
375 type == ACCESS_CODE ? 'I' : 'D', virtual);
378 base = virtual & 0xFFFC0000;
379 for (i = 0; i < 4; i++) {
382 BEPIu = *BATu & 0xF0000000;
383 BEPIl = *BATu & 0x0FFE0000;
384 bl = (*BATu & 0x00001FFC) << 15;
385 #if defined (DEBUG_BATS)
387 fprintf(logfile, "%s: %cBAT%d v 0x" ADDRX " BATu 0x" ADDRX
388 " BATl 0x" ADDRX "\n",
389 __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,
393 if ((virtual & 0xF0000000) == BEPIu &&
394 ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
396 if ((msr_pr == 0 && (*BATu & 0x00000002)) ||
397 (msr_pr == 1 && (*BATu & 0x00000001))) {
398 /* Get physical address */
399 ctx->raddr = (*BATl & 0xF0000000) |
400 ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
401 (virtual & 0x0001F000);
402 if (*BATl & 0x00000001)
403 ctx->prot = PAGE_READ;
404 if (*BATl & 0x00000002)
405 ctx->prot = PAGE_WRITE | PAGE_READ;
406 #if defined (DEBUG_BATS)
408 fprintf(logfile, "BAT %d match: r 0x" PADDRX
410 i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-',
411 ctx->prot & PAGE_WRITE ? 'W' : '-');
420 #if defined (DEBUG_BATS)
422 fprintf(logfile, "no BAT match for 0x" ADDRX ":\n", virtual);
423 for (i = 0; i < 4; i++) {
426 BEPIu = *BATu & 0xF0000000;
427 BEPIl = *BATu & 0x0FFE0000;
428 bl = (*BATu & 0x00001FFC) << 15;
429 fprintf(logfile, "%s: %cBAT%d v 0x" ADDRX " BATu 0x" ADDRX
430 " BATl 0x" ADDRX " \n\t"
431 "0x" ADDRX " 0x" ADDRX " 0x" ADDRX "\n",
432 __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,
433 *BATu, *BATl, BEPIu, BEPIl, bl);
442 /* PTE table lookup */
443 static int find_pte (mmu_ctx_t *ctx, int h, int rw)
445 target_ulong base, pte0, pte1;
449 ret = -1; /* No entry found */
450 base = ctx->pg_addr[h];
451 for (i = 0; i < 8; i++) {
452 pte0 = ldl_phys(base + (i * 8));
453 pte1 = ldl_phys(base + (i * 8) + 4);
454 #if defined (DEBUG_MMU)
456 fprintf(logfile, "Load pte from 0x" ADDRX " => 0x" ADDRX
457 " 0x" ADDRX " %d %d %d 0x" ADDRX "\n",
458 base + (i * 8), pte0, pte1,
459 pte0 >> 31, h, (pte0 >> 6) & 1, ctx->ptem);
462 switch (pte_check(ctx, pte0, pte1, h, rw)) {
464 /* PTE inconsistency */
467 /* Access violation */
477 /* XXX: we should go on looping to check all PTEs consistency
478 * but if we can speed-up the whole thing as the
479 * result would be undefined if PTEs are not consistent.
488 #if defined (DEBUG_MMU)
490 fprintf(logfile, "found PTE at addr 0x" PADDRX " prot=0x%01x "
492 ctx->raddr, ctx->prot, ret);
495 /* Update page flags */
497 if (pte_update_flags(ctx, &pte1, ret, rw) == 1)
498 stl_phys_notdirty(base + (good * 8) + 4, pte1);
504 static inline target_phys_addr_t get_pgaddr (target_phys_addr_t sdr1,
505 target_phys_addr_t hash,
506 target_phys_addr_t mask)
508 return (sdr1 & 0xFFFF0000) | (hash & mask);
511 /* Perform segment based translation */
512 static int get_segment (CPUState *env, mmu_ctx_t *ctx,
513 target_ulong eaddr, int rw, int type)
515 target_phys_addr_t sdr, hash, mask;
516 target_ulong sr, vsid, pgidx;
519 sr = env->sr[eaddr >> 28];
520 #if defined (DEBUG_MMU)
522 fprintf(logfile, "Check segment v=0x" ADDRX " %d 0x" ADDRX " nip=0x"
523 ADDRX " lr=0x" ADDRX " ir=%d dr=%d pr=%d %d t=%d\n",
524 eaddr, eaddr >> 28, sr, env->nip,
525 env->lr, msr_ir, msr_dr, msr_pr, rw, type);
528 ctx->key = (((sr & 0x20000000) && msr_pr == 1) ||
529 ((sr & 0x40000000) && msr_pr == 0)) ? 1 : 0;
530 if ((sr & 0x80000000) == 0) {
531 #if defined (DEBUG_MMU)
533 fprintf(logfile, "pte segment: key=%d n=0x" ADDRX "\n",
534 ctx->key, sr & 0x10000000);
536 /* Check if instruction fetch is allowed, if needed */
537 if (type != ACCESS_CODE || (sr & 0x10000000) == 0) {
538 /* Page address translation */
539 pgidx = (eaddr >> TARGET_PAGE_BITS) & 0xFFFF;
540 vsid = sr & 0x00FFFFFF;
541 hash = ((vsid ^ pgidx) & 0x0007FFFF) << 6;
542 /* Primary table address */
544 mask = ((sdr & 0x000001FF) << 16) | 0xFFC0;
545 ctx->pg_addr[0] = get_pgaddr(sdr, hash, mask);
546 /* Secondary table address */
547 hash = (~hash) & 0x01FFFFC0;
548 ctx->pg_addr[1] = get_pgaddr(sdr, hash, mask);
549 ctx->ptem = (vsid << 7) | (pgidx >> 10);
550 /* Initialize real address with an invalid value */
551 ctx->raddr = (target_ulong)-1;
552 if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
553 /* Software TLB search */
554 ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
556 #if defined (DEBUG_MMU)
558 fprintf(logfile, "0 sdr1=0x" PADDRX " vsid=0x%06x "
559 "api=0x%04x hash=0x%07x pg_addr=0x" PADDRX "\n",
560 sdr, (uint32_t)vsid, (uint32_t)pgidx,
561 (uint32_t)hash, ctx->pg_addr[0]);
564 /* Primary table lookup */
565 ret = find_pte(ctx, 0, rw);
567 /* Secondary table lookup */
568 #if defined (DEBUG_MMU)
569 if (eaddr != 0xEFFFFFFF && loglevel != 0) {
571 "1 sdr1=0x" PADDRX " vsid=0x%06x api=0x%04x "
572 "hash=0x%05x pg_addr=0x" PADDRX "\n",
573 sdr, (uint32_t)vsid, (uint32_t)pgidx,
574 (uint32_t)hash, ctx->pg_addr[1]);
577 ret2 = find_pte(ctx, 1, rw);
583 #if defined (DEBUG_MMU)
585 fprintf(logfile, "No access allowed\n");
590 #if defined (DEBUG_MMU)
592 fprintf(logfile, "direct store...\n");
594 /* Direct-store segment : absolutely *BUGGY* for now */
597 /* Integer load/store : only access allowed */
600 /* No code fetch is allowed in direct-store areas */
603 /* Floating point load/store */
606 /* lwarx, ldarx or srwcx. */
609 /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
610 /* Should make the instruction do no-op.
611 * As it already do no-op, it's quite easy :-)
620 fprintf(logfile, "ERROR: instruction should not need "
621 "address translation\n");
625 if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) {
636 /* Generic TLB check function for embedded PowerPC implementations */
637 static int ppcemb_tlb_check (CPUState *env, ppcemb_tlb_t *tlb,
638 target_phys_addr_t *raddrp,
639 target_ulong address,
640 uint32_t pid, int ext, int i)
644 /* Check valid flag */
645 if (!(tlb->prot & PAGE_VALID)) {
647 fprintf(logfile, "%s: TLB %d not valid\n", __func__, i);
650 mask = ~(tlb->size - 1);
652 fprintf(logfile, "%s: TLB %d address " ADDRX " PID %d <=> "
653 ADDRX " " ADDRX " %d\n",
654 __func__, i, address, pid, tlb->EPN, mask, (int)tlb->PID);
657 if (tlb->PID != 0 && tlb->PID != pid)
659 /* Check effective address */
660 if ((address & mask) != tlb->EPN)
662 *raddrp = (tlb->RPN & mask) | (address & ~mask);
664 /* Extend the physical address to 36 bits */
665 *raddrp |= (target_phys_addr_t)(tlb->RPN & 0xF) << 32;
671 /* Generic TLB search function for PowerPC embedded implementations */
672 int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid)
675 target_phys_addr_t raddr;
678 /* Default return value is no match */
680 for (i = 0; i < 64; i++) {
681 tlb = &env->tlb[i].tlbe;
682 if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, 0, i) == 0) {
691 /* Helpers specific to PowerPC 40x implementations */
692 void ppc4xx_tlb_invalidate_all (CPUState *env)
697 for (i = 0; i < env->nb_tlb; i++) {
698 tlb = &env->tlb[i].tlbe;
699 if (tlb->prot & PAGE_VALID) {
700 #if 0 // XXX: TLB have variable sizes then we flush all Qemu TLB.
701 end = tlb->EPN + tlb->size;
702 for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
703 tlb_flush_page(env, page);
705 tlb->prot &= ~PAGE_VALID;
711 int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
712 target_ulong address, int rw, int access_type)
715 target_phys_addr_t raddr;
716 int i, ret, zsel, zpr;
720 for (i = 0; i < env->nb_tlb; i++) {
721 tlb = &env->tlb[i].tlbe;
722 if (ppcemb_tlb_check(env, tlb, &raddr, address,
723 env->spr[SPR_40x_PID], 0, i) < 0)
725 zsel = (tlb->attr >> 4) & 0xF;
726 zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3;
728 fprintf(logfile, "%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
729 __func__, i, zsel, zpr, rw, tlb->attr);
731 if (access_type == ACCESS_CODE) {
732 /* Check execute enable bit */
736 goto check_exec_perm;
747 /* Check from TLB entry */
748 if (!(tlb->prot & PAGE_EXEC)) {
751 if (tlb->prot & PAGE_WRITE) {
752 ctx->prot = PAGE_READ | PAGE_WRITE;
754 ctx->prot = PAGE_READ;
761 /* All accesses granted */
762 ctx->prot = PAGE_READ | PAGE_WRITE;
781 /* Check from TLB entry */
782 /* Check write protection bit */
783 if (tlb->prot & PAGE_WRITE) {
784 ctx->prot = PAGE_READ | PAGE_WRITE;
787 ctx->prot = PAGE_READ;
796 /* All accesses granted */
797 ctx->prot = PAGE_READ | PAGE_WRITE;
805 fprintf(logfile, "%s: access granted " ADDRX " => " REGX
806 " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
813 fprintf(logfile, "%s: access refused " ADDRX " => " REGX
814 " %d %d\n", __func__, address, raddr, ctx->prot,
821 void store_40x_sler (CPUPPCState *env, uint32_t val)
823 /* XXX: TO BE FIXED */
824 if (val != 0x00000000) {
825 cpu_abort(env, "Little-endian regions are not supported by now\n");
827 env->spr[SPR_405_SLER] = val;
830 static int check_physical (CPUState *env, mmu_ctx_t *ctx,
831 target_ulong eaddr, int rw)
836 ctx->prot = PAGE_READ;
838 if (unlikely(msr_pe != 0 && PPC_MMU(env) == PPC_FLAGS_MMU_403)) {
839 /* 403 family add some particular protections,
840 * using PBL/PBU registers for accesses with no translation.
843 /* Check PLB validity */
844 (env->pb[0] < env->pb[1] &&
845 /* and address in plb area */
846 eaddr >= env->pb[0] && eaddr < env->pb[1]) ||
847 (env->pb[2] < env->pb[3] &&
848 eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0;
849 if (in_plb ^ msr_px) {
850 /* Access in protected area */
852 /* Access is not allowed */
856 /* Read-write access is allowed */
857 ctx->prot |= PAGE_WRITE;
860 ctx->prot |= PAGE_WRITE;
866 int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
867 int rw, int access_type, int check_BATs)
872 fprintf(logfile, "%s\n", __func__);
875 if ((access_type == ACCESS_CODE && msr_ir == 0) ||
876 (access_type != ACCESS_CODE && msr_dr == 0)) {
877 /* No address translation */
878 ret = check_physical(env, ctx, eaddr, rw);
881 switch (PPC_MMU(env)) {
882 case PPC_FLAGS_MMU_32B:
883 case PPC_FLAGS_MMU_SOFT_6xx:
884 /* Try to find a BAT */
886 ret = get_bat(env, ctx, eaddr, rw, access_type);
888 #if defined(TARGET_PPC64)
889 case PPC_FLAGS_MMU_64B:
890 case PPC_FLAGS_MMU_64BRIDGE:
893 /* We didn't match any BAT entry or don't have BATs */
894 ret = get_segment(env, ctx, eaddr, rw, access_type);
897 case PPC_FLAGS_MMU_SOFT_4xx:
898 case PPC_FLAGS_MMU_403:
899 ret = mmu40x_get_physical_address(env, ctx, eaddr,
902 case PPC_FLAGS_MMU_601:
904 cpu_abort(env, "601 MMU model not implemented\n");
906 case PPC_FLAGS_MMU_BOOKE:
908 cpu_abort(env, "BookeE MMU model not implemented\n");
910 case PPC_FLAGS_MMU_BOOKE_FSL:
912 cpu_abort(env, "BookE FSL MMU model not implemented\n");
915 cpu_abort(env, "Unknown or invalid MMU model\n");
921 fprintf(logfile, "%s address " ADDRX " => %d " PADDRX "\n",
922 __func__, eaddr, ret, ctx->raddr);
929 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
933 if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT, 1) != 0))
936 return ctx.raddr & TARGET_PAGE_MASK;
939 /* Perform address translation */
940 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
941 int is_user, int is_softmmu)
944 int exception = 0, error_code = 0;
951 access_type = ACCESS_CODE;
954 /* XXX: put correct access by using cpu_restore_state()
956 access_type = ACCESS_INT;
957 // access_type = env->access_type;
959 ret = get_physical_address(env, &ctx, address, rw, access_type, 1);
961 ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
962 ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
963 is_user, is_softmmu);
964 } else if (ret < 0) {
965 #if defined (DEBUG_MMU)
967 cpu_dump_state(env, logfile, fprintf, 0);
969 if (access_type == ACCESS_CODE) {
970 exception = EXCP_ISI;
973 /* No matches in page tables or TLB */
974 switch (PPC_MMU(env)) {
975 case PPC_FLAGS_MMU_SOFT_6xx:
976 exception = EXCP_I_TLBMISS;
977 env->spr[SPR_IMISS] = address;
978 env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
979 error_code = 1 << 18;
981 case PPC_FLAGS_MMU_SOFT_4xx:
982 case PPC_FLAGS_MMU_403:
983 exception = EXCP_40x_ITLBMISS;
985 env->spr[SPR_40x_DEAR] = address;
986 env->spr[SPR_40x_ESR] = 0x00000000;
988 case PPC_FLAGS_MMU_32B:
989 error_code = 0x40000000;
991 #if defined(TARGET_PPC64)
992 case PPC_FLAGS_MMU_64B:
994 cpu_abort(env, "MMU model not implemented\n");
996 case PPC_FLAGS_MMU_64BRIDGE:
998 cpu_abort(env, "MMU model not implemented\n");
1001 case PPC_FLAGS_MMU_601:
1003 cpu_abort(env, "MMU model not implemented\n");
1005 case PPC_FLAGS_MMU_BOOKE:
1007 cpu_abort(env, "MMU model not implemented\n");
1009 case PPC_FLAGS_MMU_BOOKE_FSL:
1011 cpu_abort(env, "MMU model not implemented\n");
1014 cpu_abort(env, "Unknown or invalid MMU model\n");
1019 /* Access rights violation */
1020 error_code = 0x08000000;
1023 /* No execute protection violation */
1024 error_code = 0x10000000;
1027 /* Direct store exception */
1028 /* No code fetch is allowed in direct-store areas */
1029 error_code = 0x10000000;
1032 /* No match in segment table */
1033 exception = EXCP_ISEG;
1038 exception = EXCP_DSI;
1041 /* No matches in page tables or TLB */
1042 switch (PPC_MMU(env)) {
1043 case PPC_FLAGS_MMU_SOFT_6xx:
1045 exception = EXCP_DS_TLBMISS;
1046 error_code = 1 << 16;
1048 exception = EXCP_DL_TLBMISS;
1051 env->spr[SPR_DMISS] = address;
1052 env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
1054 error_code |= ctx.key << 19;
1055 env->spr[SPR_HASH1] = ctx.pg_addr[0];
1056 env->spr[SPR_HASH2] = ctx.pg_addr[1];
1057 /* Do not alter DAR nor DSISR */
1059 case PPC_FLAGS_MMU_SOFT_4xx:
1060 case PPC_FLAGS_MMU_403:
1061 exception = EXCP_40x_DTLBMISS;
1063 env->spr[SPR_40x_DEAR] = address;
1065 env->spr[SPR_40x_ESR] = 0x00800000;
1067 env->spr[SPR_40x_ESR] = 0x00000000;
1069 case PPC_FLAGS_MMU_32B:
1070 error_code = 0x40000000;
1072 #if defined(TARGET_PPC64)
1073 case PPC_FLAGS_MMU_64B:
1075 cpu_abort(env, "MMU model not implemented\n");
1077 case PPC_FLAGS_MMU_64BRIDGE:
1079 cpu_abort(env, "MMU model not implemented\n");
1082 case PPC_FLAGS_MMU_601:
1084 cpu_abort(env, "MMU model not implemented\n");
1086 case PPC_FLAGS_MMU_BOOKE:
1088 cpu_abort(env, "MMU model not implemented\n");
1090 case PPC_FLAGS_MMU_BOOKE_FSL:
1092 cpu_abort(env, "MMU model not implemented\n");
1095 cpu_abort(env, "Unknown or invalid MMU model\n");
1100 /* Access rights violation */
1101 error_code = 0x08000000;
1104 /* Direct store exception */
1105 switch (access_type) {
1107 /* Floating point load/store */
1108 exception = EXCP_ALIGN;
1109 error_code = EXCP_ALIGN_FP;
1112 /* lwarx, ldarx or srwcx. */
1113 error_code = 0x04000000;
1116 /* eciwx or ecowx */
1117 error_code = 0x04100000;
1120 printf("DSI: invalid exception (%d)\n", ret);
1121 exception = EXCP_PROGRAM;
1122 error_code = EXCP_INVAL | EXCP_INVAL_INVAL;
1127 /* No match in segment table */
1128 exception = EXCP_DSEG;
1132 if (exception == EXCP_DSI && rw == 1)
1133 error_code |= 0x02000000;
1134 /* Store fault address */
1135 env->spr[SPR_DAR] = address;
1136 env->spr[SPR_DSISR] = error_code;
1140 printf("%s: set exception to %d %02x\n",
1141 __func__, exception, error_code);
1143 env->exception_index = exception;
1144 env->error_code = error_code;
1151 /*****************************************************************************/
1152 /* BATs management */
1153 #if !defined(FLUSH_ALL_TLBS)
1154 static inline void do_invalidate_BAT (CPUPPCState *env,
1155 target_ulong BATu, target_ulong mask)
1157 target_ulong base, end, page;
1159 base = BATu & ~0x0001FFFF;
1160 end = base + mask + 0x00020000;
1161 #if defined (DEBUG_BATS)
1162 if (loglevel != 0) {
1163 fprintf(logfile, "Flush BAT from " ADDRX " to " ADDRX " (" ADDRX ")\n",
1167 for (page = base; page != end; page += TARGET_PAGE_SIZE)
1168 tlb_flush_page(env, page);
1169 #if defined (DEBUG_BATS)
1171 fprintf(logfile, "Flush done\n");
1176 static inline void dump_store_bat (CPUPPCState *env, char ID, int ul, int nr,
1179 #if defined (DEBUG_BATS)
1180 if (loglevel != 0) {
1181 fprintf(logfile, "Set %cBAT%d%c to 0x" ADDRX " (0x" ADDRX ")\n",
1182 ID, nr, ul == 0 ? 'u' : 'l', value, env->nip);
1187 target_ulong do_load_ibatu (CPUPPCState *env, int nr)
1189 return env->IBAT[0][nr];
1192 target_ulong do_load_ibatl (CPUPPCState *env, int nr)
1194 return env->IBAT[1][nr];
1197 void do_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
1201 dump_store_bat(env, 'I', 0, nr, value);
1202 if (env->IBAT[0][nr] != value) {
1203 mask = (value << 15) & 0x0FFE0000UL;
1204 #if !defined(FLUSH_ALL_TLBS)
1205 do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1207 /* When storing valid upper BAT, mask BEPI and BRPN
1208 * and invalidate all TLBs covered by this BAT
1210 mask = (value << 15) & 0x0FFE0000UL;
1211 env->IBAT[0][nr] = (value & 0x00001FFFUL) |
1212 (value & ~0x0001FFFFUL & ~mask);
1213 env->IBAT[1][nr] = (env->IBAT[1][nr] & 0x0000007B) |
1214 (env->IBAT[1][nr] & ~0x0001FFFF & ~mask);
1215 #if !defined(FLUSH_ALL_TLBS)
1216 do_invalidate_BAT(env, env->IBAT[0][nr], mask);
1223 void do_store_ibatl (CPUPPCState *env, int nr, target_ulong value)
1225 dump_store_bat(env, 'I', 1, nr, value);
1226 env->IBAT[1][nr] = value;
1229 target_ulong do_load_dbatu (CPUPPCState *env, int nr)
1231 return env->DBAT[0][nr];
1234 target_ulong do_load_dbatl (CPUPPCState *env, int nr)
1236 return env->DBAT[1][nr];
1239 void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value)
1243 dump_store_bat(env, 'D', 0, nr, value);
1244 if (env->DBAT[0][nr] != value) {
1245 /* When storing valid upper BAT, mask BEPI and BRPN
1246 * and invalidate all TLBs covered by this BAT
1248 mask = (value << 15) & 0x0FFE0000UL;
1249 #if !defined(FLUSH_ALL_TLBS)
1250 do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1252 mask = (value << 15) & 0x0FFE0000UL;
1253 env->DBAT[0][nr] = (value & 0x00001FFFUL) |
1254 (value & ~0x0001FFFFUL & ~mask);
1255 env->DBAT[1][nr] = (env->DBAT[1][nr] & 0x0000007B) |
1256 (env->DBAT[1][nr] & ~0x0001FFFF & ~mask);
1257 #if !defined(FLUSH_ALL_TLBS)
1258 do_invalidate_BAT(env, env->DBAT[0][nr], mask);
1265 void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
1267 dump_store_bat(env, 'D', 1, nr, value);
1268 env->DBAT[1][nr] = value;
1272 /*****************************************************************************/
1273 /* TLB management */
1274 void ppc_tlb_invalidate_all (CPUPPCState *env)
1276 if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
1277 ppc6xx_tlb_invalidate_all(env);
1278 } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
1279 ppc4xx_tlb_invalidate_all(env);
1285 /*****************************************************************************/
1286 /* Special registers manipulation */
1287 #if defined(TARGET_PPC64)
1288 target_ulong ppc_load_asr (CPUPPCState *env)
1293 void ppc_store_asr (CPUPPCState *env, target_ulong value)
1295 if (env->asr != value) {
1302 target_ulong do_load_sdr1 (CPUPPCState *env)
1307 void do_store_sdr1 (CPUPPCState *env, target_ulong value)
1309 #if defined (DEBUG_MMU)
1310 if (loglevel != 0) {
1311 fprintf(logfile, "%s: 0x" ADDRX "\n", __func__, value);
1314 if (env->sdr1 != value) {
1320 target_ulong do_load_sr (CPUPPCState *env, int srnum)
1322 return env->sr[srnum];
1325 void do_store_sr (CPUPPCState *env, int srnum, target_ulong value)
1327 #if defined (DEBUG_MMU)
1328 if (loglevel != 0) {
1329 fprintf(logfile, "%s: reg=%d 0x" ADDRX " " ADDRX "\n",
1330 __func__, srnum, value, env->sr[srnum]);
1333 if (env->sr[srnum] != value) {
1334 env->sr[srnum] = value;
1335 #if !defined(FLUSH_ALL_TLBS) && 0
1337 target_ulong page, end;
1338 /* Invalidate 256 MB of virtual memory */
1339 page = (16 << 20) * srnum;
1340 end = page + (16 << 20);
1341 for (; page != end; page += TARGET_PAGE_SIZE)
1342 tlb_flush_page(env, page);
1349 #endif /* !defined (CONFIG_USER_ONLY) */
1351 uint32_t ppc_load_xer (CPUPPCState *env)
1353 return (xer_so << XER_SO) |
1354 (xer_ov << XER_OV) |
1355 (xer_ca << XER_CA) |
1356 (xer_bc << XER_BC) |
1357 (xer_cmp << XER_CMP);
1360 void ppc_store_xer (CPUPPCState *env, uint32_t value)
1362 xer_so = (value >> XER_SO) & 0x01;
1363 xer_ov = (value >> XER_OV) & 0x01;
1364 xer_ca = (value >> XER_CA) & 0x01;
1365 xer_cmp = (value >> XER_CMP) & 0xFF;
1366 xer_bc = (value >> XER_BC) & 0x7F;
1369 /* Swap temporary saved registers with GPRs */
1370 static inline void swap_gpr_tgpr (CPUPPCState *env)
1375 env->gpr[0] = env->tgpr[0];
1378 env->gpr[1] = env->tgpr[1];
1381 env->gpr[2] = env->tgpr[2];
1384 env->gpr[3] = env->tgpr[3];
1388 /* GDBstub can read and write MSR... */
1389 target_ulong do_load_msr (CPUPPCState *env)
1392 #if defined (TARGET_PPC64)
1393 ((target_ulong)msr_sf << MSR_SF) |
1394 ((target_ulong)msr_isf << MSR_ISF) |
1395 ((target_ulong)msr_hv << MSR_HV) |
1397 ((target_ulong)msr_ucle << MSR_UCLE) |
1398 ((target_ulong)msr_vr << MSR_VR) | /* VR / SPE */
1399 ((target_ulong)msr_ap << MSR_AP) |
1400 ((target_ulong)msr_sa << MSR_SA) |
1401 ((target_ulong)msr_key << MSR_KEY) |
1402 ((target_ulong)msr_pow << MSR_POW) | /* POW / WE */
1403 ((target_ulong)msr_tlb << MSR_TLB) | /* TLB / TGPE / CE */
1404 ((target_ulong)msr_ile << MSR_ILE) |
1405 ((target_ulong)msr_ee << MSR_EE) |
1406 ((target_ulong)msr_pr << MSR_PR) |
1407 ((target_ulong)msr_fp << MSR_FP) |
1408 ((target_ulong)msr_me << MSR_ME) |
1409 ((target_ulong)msr_fe0 << MSR_FE0) |
1410 ((target_ulong)msr_se << MSR_SE) | /* SE / DWE / UBLE */
1411 ((target_ulong)msr_be << MSR_BE) | /* BE / DE */
1412 ((target_ulong)msr_fe1 << MSR_FE1) |
1413 ((target_ulong)msr_al << MSR_AL) |
1414 ((target_ulong)msr_ip << MSR_IP) |
1415 ((target_ulong)msr_ir << MSR_IR) | /* IR / IS */
1416 ((target_ulong)msr_dr << MSR_DR) | /* DR / DS */
1417 ((target_ulong)msr_pe << MSR_PE) | /* PE / EP */
1418 ((target_ulong)msr_px << MSR_PX) | /* PX / PMM */
1419 ((target_ulong)msr_ri << MSR_RI) |
1420 ((target_ulong)msr_le << MSR_LE);
1423 void do_store_msr (CPUPPCState *env, target_ulong value)
1427 value &= env->msr_mask;
1428 if (((value >> MSR_IR) & 1) != msr_ir ||
1429 ((value >> MSR_DR) & 1) != msr_dr) {
1430 /* Flush all tlb when changing translation mode */
1432 env->interrupt_request |= CPU_INTERRUPT_EXITTB;
1435 if (loglevel != 0) {
1436 fprintf(logfile, "%s: T0 %08lx\n", __func__, value);
1439 switch (PPC_EXCP(env)) {
1440 case PPC_FLAGS_EXCP_602:
1441 case PPC_FLAGS_EXCP_603:
1442 if (((value >> MSR_TGPR) & 1) != msr_tgpr) {
1443 /* Swap temporary saved registers with GPRs */
1450 #if defined (TARGET_PPC64)
1451 msr_sf = (value >> MSR_SF) & 1;
1452 msr_isf = (value >> MSR_ISF) & 1;
1453 msr_hv = (value >> MSR_HV) & 1;
1455 msr_ucle = (value >> MSR_UCLE) & 1;
1456 msr_vr = (value >> MSR_VR) & 1; /* VR / SPE */
1457 msr_ap = (value >> MSR_AP) & 1;
1458 msr_sa = (value >> MSR_SA) & 1;
1459 msr_key = (value >> MSR_KEY) & 1;
1460 msr_pow = (value >> MSR_POW) & 1; /* POW / WE */
1461 msr_tlb = (value >> MSR_TLB) & 1; /* TLB / TGPR / CE */
1462 msr_ile = (value >> MSR_ILE) & 1;
1463 msr_ee = (value >> MSR_EE) & 1;
1464 msr_pr = (value >> MSR_PR) & 1;
1465 msr_fp = (value >> MSR_FP) & 1;
1466 msr_me = (value >> MSR_ME) & 1;
1467 msr_fe0 = (value >> MSR_FE0) & 1;
1468 msr_se = (value >> MSR_SE) & 1; /* SE / DWE / UBLE */
1469 msr_be = (value >> MSR_BE) & 1; /* BE / DE */
1470 msr_fe1 = (value >> MSR_FE1) & 1;
1471 msr_al = (value >> MSR_AL) & 1;
1472 msr_ip = (value >> MSR_IP) & 1;
1473 msr_ir = (value >> MSR_IR) & 1; /* IR / IS */
1474 msr_dr = (value >> MSR_DR) & 1; /* DR / DS */
1475 msr_pe = (value >> MSR_PE) & 1; /* PE / EP */
1476 msr_px = (value >> MSR_PX) & 1; /* PX / PMM */
1477 msr_ri = (value >> MSR_RI) & 1;
1478 msr_le = (value >> MSR_LE) & 1;
1479 do_compute_hflags(env);
1482 switch (PPC_EXCP(env)) {
1483 case PPC_FLAGS_EXCP_603:
1484 /* Don't handle SLEEP mode: we should disable all clocks...
1485 * No dynamic power-management.
1487 if (msr_pow == 1 && (env->spr[SPR_HID0] & 0x00C00000) != 0)
1490 case PPC_FLAGS_EXCP_604:
1494 case PPC_FLAGS_EXCP_7x0:
1495 if (msr_pow == 1 && (env->spr[SPR_HID0] & 0x00E00000) != 0)
1502 if (likely(!env->halted)) {
1503 /* power save: exit cpu loop */
1505 env->exception_index = EXCP_HLT;
1511 #if defined(TARGET_PPC64)
1512 void ppc_store_msr_32 (CPUPPCState *env, uint32_t value)
1515 (do_load_msr(env) & ~0xFFFFFFFFULL) | (value & 0xFFFFFFFF));
1519 void do_compute_hflags (CPUPPCState *env)
1521 /* Compute current hflags */
1522 env->hflags = (msr_cm << MSR_CM) | (msr_vr << MSR_VR) |
1523 (msr_ap << MSR_AP) | (msr_sa << MSR_SA) | (msr_pr << MSR_PR) |
1524 (msr_fp << MSR_FP) | (msr_fe0 << MSR_FE0) | (msr_se << MSR_SE) |
1525 (msr_be << MSR_BE) | (msr_fe1 << MSR_FE1) | (msr_le << MSR_LE);
1526 #if defined (TARGET_PPC64)
1527 /* No care here: PowerPC 64 MSR_SF means the same as MSR_CM for BookE */
1528 env->hflags |= (msr_sf << (MSR_SF - 32)) | (msr_hv << (MSR_HV - 32));
1532 /*****************************************************************************/
1533 /* Exception processing */
1534 #if defined (CONFIG_USER_ONLY)
1535 void do_interrupt (CPUState *env)
1537 env->exception_index = -1;
1540 void ppc_hw_interrupt (CPUState *env)
1542 env->exception_index = -1;
1544 #else /* defined (CONFIG_USER_ONLY) */
1545 static void dump_syscall (CPUState *env)
1547 fprintf(logfile, "syscall r0=0x" REGX " r3=0x" REGX " r4=0x" REGX
1548 " r5=0x" REGX " r6=0x" REGX " nip=0x" ADDRX "\n",
1549 env->gpr[0], env->gpr[3], env->gpr[4],
1550 env->gpr[5], env->gpr[6], env->nip);
1553 void do_interrupt (CPUState *env)
1555 target_ulong msr, *srr_0, *srr_1, *asrr_0, *asrr_1;
1558 excp = env->exception_index;
1559 msr = do_load_msr(env);
1560 /* The default is to use SRR0 & SRR1 to save the exception context */
1561 srr_0 = &env->spr[SPR_SRR0];
1562 srr_1 = &env->spr[SPR_SRR1];
1565 #if defined (DEBUG_EXCEPTIONS)
1566 if ((excp == EXCP_PROGRAM || excp == EXCP_DSI) && msr_pr == 1) {
1567 if (loglevel != 0) {
1569 "Raise exception at 0x" ADDRX " => 0x%08x (%02x)\n",
1570 env->nip, excp, env->error_code);
1571 cpu_dump_state(env, logfile, fprintf, 0);
1575 if (loglevel & CPU_LOG_INT) {
1576 fprintf(logfile, "Raise exception at 0x" ADDRX " => 0x%08x (%02x)\n",
1577 env->nip, excp, env->error_code);
1581 /* Generate informations in save/restore registers */
1583 /* Generic PowerPC exceptions */
1584 case EXCP_RESET: /* 0x0100 */
1585 switch (PPC_EXCP(env)) {
1586 case PPC_FLAGS_EXCP_40x:
1587 srr_0 = &env->spr[SPR_40x_SRR2];
1588 srr_1 = &env->spr[SPR_40x_SRR3];
1590 case PPC_FLAGS_EXCP_BOOKE:
1592 srr_0 = &env->spr[SPR_BOOKE_CSRR0];
1593 srr_1 = &env->spr[SPR_BOOKE_CSRR1];
1602 case EXCP_MACHINE_CHECK: /* 0x0200 */
1603 switch (PPC_EXCP(env)) {
1604 case PPC_FLAGS_EXCP_40x:
1605 srr_0 = &env->spr[SPR_40x_SRR2];
1606 srr_1 = &env->spr[SPR_40x_SRR3];
1608 case PPC_FLAGS_EXCP_BOOKE:
1610 srr_0 = &env->spr[SPR_BOOKE_MCSRR0];
1611 srr_1 = &env->spr[SPR_BOOKE_MCSRR1];
1612 asrr_0 = &env->spr[SPR_BOOKE_CSRR0];
1613 asrr_1 = &env->spr[SPR_BOOKE_CSRR1];
1621 case EXCP_DSI: /* 0x0300 */
1622 /* Store exception cause */
1623 /* data location address has been stored
1624 * when the fault has been detected
1628 #if defined (DEBUG_EXCEPTIONS)
1629 if (loglevel != 0) {
1630 fprintf(logfile, "DSI exception: DSISR=0x" ADDRX" DAR=0x" ADDRX
1631 "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
1635 case EXCP_ISI: /* 0x0400 */
1636 /* Store exception cause */
1639 msr |= env->error_code;
1640 #if defined (DEBUG_EXCEPTIONS)
1641 if (loglevel != 0) {
1642 fprintf(logfile, "ISI exception: msr=0x" ADDRX ", nip=0x" ADDRX
1643 "\n", msr, env->nip);
1647 case EXCP_EXTERNAL: /* 0x0500 */
1650 case EXCP_ALIGN: /* 0x0600 */
1651 if (likely(PPC_EXCP(env) != PPC_FLAGS_EXCP_601)) {
1652 /* Store exception cause */
1654 /* Get rS/rD and rA from faulting opcode */
1655 env->spr[SPR_DSISR] |=
1656 (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
1657 /* data location address has been stored
1658 * when the fault has been detected
1661 /* IO error exception on PowerPC 601 */
1664 "601 IO error exception is not implemented yet !\n");
1667 case EXCP_PROGRAM: /* 0x0700 */
1670 switch (env->error_code & ~0xF) {
1672 if (msr_fe0 == 0 && msr_fe1 == 0) {
1673 #if defined (DEBUG_EXCEPTIONS)
1674 if (loglevel != 0) {
1675 fprintf(logfile, "Ignore floating point exception\n");
1682 env->fpscr[7] |= 0x8;
1683 /* Finally, update FEX */
1684 if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) &
1685 ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3)))
1686 env->fpscr[7] |= 0x4;
1689 #if defined (DEBUG_EXCEPTIONS)
1690 if (loglevel != 0) {
1691 fprintf(logfile, "Invalid instruction at 0x" ADDRX "\n",
1705 /* Should never occur */
1710 case EXCP_NO_FP: /* 0x0800 */
1716 case EXCP_SYSCALL: /* 0x0C00 */
1718 /* NOTE: this is a temporary hack to support graphics OSI
1719 calls from the MOL driver */
1720 if (env->gpr[3] == 0x113724fa && env->gpr[4] == 0x77810f9b &&
1722 if (env->osi_call(env) != 0)
1725 if (loglevel & CPU_LOG_INT) {
1729 case EXCP_TRACE: /* 0x0D00 */
1731 case EXCP_PERF: /* 0x0F00 */
1734 "Performance counter exception is not implemented yet !\n");
1736 /* 32 bits PowerPC specific exceptions */
1737 case EXCP_FP_ASSIST: /* 0x0E00 */
1739 cpu_abort(env, "Floating point assist exception "
1740 "is not implemented yet !\n");
1742 /* 64 bits PowerPC exceptions */
1743 case EXCP_DSEG: /* 0x0380 */
1745 cpu_abort(env, "Data segment exception is not implemented yet !\n");
1747 case EXCP_ISEG: /* 0x0480 */
1750 "Instruction segment exception is not implemented yet !\n");
1752 case EXCP_HDECR: /* 0x0980 */
1754 cpu_abort(env, "Hypervisor decrementer exception is not implemented "
1757 /* Implementation specific exceptions */
1759 if (likely(env->spr[SPR_PVR] == CPU_PPC_G2 ||
1760 env->spr[SPR_PVR] == CPU_PPC_G2LE)) {
1761 /* Critical interrupt on G2 */
1763 cpu_abort(env, "G2 critical interrupt is not implemented yet !\n");
1766 cpu_abort(env, "Invalid exception 0x0A00 !\n");
1771 switch (PPC_EXCP(env)) {
1772 case PPC_FLAGS_EXCP_40x:
1773 /* APU unavailable on 405 */
1776 "APU unavailable exception is not implemented yet !\n");
1778 case PPC_FLAGS_EXCP_74xx:
1779 /* Altivec unavailable */
1781 cpu_abort(env, "Altivec unavailable exception "
1782 "is not implemented yet !\n");
1785 cpu_abort(env, "Invalid exception 0x0F20 !\n");
1791 switch (PPC_EXCP(env)) {
1792 case PPC_FLAGS_EXCP_40x:
1795 #if defined (DEBUG_EXCEPTIONS)
1797 fprintf(logfile, "PIT exception\n");
1800 case PPC_FLAGS_EXCP_602:
1801 case PPC_FLAGS_EXCP_603:
1802 /* ITLBMISS on 602/603 */
1804 case PPC_FLAGS_EXCP_7x5:
1805 /* ITLBMISS on 745/755 */
1808 cpu_abort(env, "Invalid exception 0x1000 !\n");
1814 switch (PPC_EXCP(env)) {
1815 case PPC_FLAGS_EXCP_40x:
1818 #if defined (DEBUG_EXCEPTIONS)
1820 fprintf(logfile, "FIT exception\n");
1824 cpu_abort(env, "Invalid exception 0x1010 !\n");
1830 switch (PPC_EXCP(env)) {
1831 case PPC_FLAGS_EXCP_40x:
1832 /* Watchdog on 4xx */
1834 #if defined (DEBUG_EXCEPTIONS)
1836 fprintf(logfile, "WDT exception\n");
1839 case PPC_FLAGS_EXCP_BOOKE:
1840 srr_0 = &env->spr[SPR_BOOKE_CSRR0];
1841 srr_1 = &env->spr[SPR_BOOKE_CSRR1];
1844 cpu_abort(env, "Invalid exception 0x1020 !\n");
1850 switch (PPC_EXCP(env)) {
1851 case PPC_FLAGS_EXCP_40x:
1852 /* DTLBMISS on 4xx */
1855 case PPC_FLAGS_EXCP_602:
1856 case PPC_FLAGS_EXCP_603:
1857 /* DLTLBMISS on 602/603 */
1859 case PPC_FLAGS_EXCP_7x5:
1860 /* DLTLBMISS on 745/755 */
1863 cpu_abort(env, "Invalid exception 0x1100 !\n");
1869 switch (PPC_EXCP(env)) {
1870 case PPC_FLAGS_EXCP_40x:
1871 /* ITLBMISS on 4xx */
1874 case PPC_FLAGS_EXCP_602:
1875 case PPC_FLAGS_EXCP_603:
1876 /* DSTLBMISS on 602/603 */
1878 /* Swap temporary saved registers with GPRs */
1881 #if defined (DEBUG_SOFTWARE_TLB)
1882 if (loglevel != 0) {
1883 const unsigned char *es;
1884 target_ulong *miss, *cmp;
1886 if (excp == 0x1000) {
1889 miss = &env->spr[SPR_IMISS];
1890 cmp = &env->spr[SPR_ICMP];
1897 miss = &env->spr[SPR_DMISS];
1898 cmp = &env->spr[SPR_DCMP];
1900 fprintf(logfile, "6xx %sTLB miss: %cM " ADDRX " %cC " ADDRX
1901 " H1 " ADDRX " H2 " ADDRX " %08x\n",
1902 es, en, *miss, en, *cmp,
1903 env->spr[SPR_HASH1], env->spr[SPR_HASH2],
1908 case PPC_FLAGS_EXCP_7x5:
1909 /* DSTLBMISS on 745/755 */
1912 msr |= env->crf[0] << 28;
1913 msr |= env->error_code; /* key, D/I, S/L bits */
1914 /* Set way using a LRU mechanism */
1915 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
1918 cpu_abort(env, "Invalid exception 0x1200 !\n");
1923 switch (PPC_EXCP(env)) {
1924 case PPC_FLAGS_EXCP_601:
1925 case PPC_FLAGS_EXCP_602:
1926 case PPC_FLAGS_EXCP_603:
1927 case PPC_FLAGS_EXCP_604:
1928 case PPC_FLAGS_EXCP_7x0:
1929 case PPC_FLAGS_EXCP_7x5:
1930 /* IABR on 6xx/7xx */
1932 cpu_abort(env, "IABR exception is not implemented yet !\n");
1935 cpu_abort(env, "Invalid exception 0x1300 !\n");
1940 switch (PPC_EXCP(env)) {
1941 case PPC_FLAGS_EXCP_601:
1942 case PPC_FLAGS_EXCP_602:
1943 case PPC_FLAGS_EXCP_603:
1944 case PPC_FLAGS_EXCP_604:
1945 case PPC_FLAGS_EXCP_7x0:
1946 case PPC_FLAGS_EXCP_7x5:
1947 /* SMI on 6xx/7xx */
1949 cpu_abort(env, "SMI exception is not implemented yet !\n");
1952 cpu_abort(env, "Invalid exception 0x1400 !\n");
1957 switch (PPC_EXCP(env)) {
1958 case PPC_FLAGS_EXCP_602:
1959 /* Watchdog on 602 */
1962 "602 watchdog exception is not implemented yet !\n");
1964 case PPC_FLAGS_EXCP_970:
1965 /* Soft patch exception on 970 */
1968 "970 soft-patch exception is not implemented yet !\n");
1970 case PPC_FLAGS_EXCP_74xx:
1971 /* VPU assist on 74xx */
1973 cpu_abort(env, "VPU assist exception is not implemented yet !\n");
1976 cpu_abort(env, "Invalid exception 0x1500 !\n");
1981 switch (PPC_EXCP(env)) {
1982 case PPC_FLAGS_EXCP_602:
1983 /* Emulation trap on 602 */
1985 cpu_abort(env, "602 emulation trap exception "
1986 "is not implemented yet !\n");
1988 case PPC_FLAGS_EXCP_970:
1989 /* Maintenance exception on 970 */
1992 "970 maintenance exception is not implemented yet !\n");
1995 cpu_abort(env, "Invalid exception 0x1600 !\n");
2000 switch (PPC_EXCP(env)) {
2001 case PPC_FLAGS_EXCP_7x0:
2002 case PPC_FLAGS_EXCP_7x5:
2003 /* Thermal management interrupt on G3 */
2005 cpu_abort(env, "G3 thermal management exception "
2006 "is not implemented yet !\n");
2008 case PPC_FLAGS_EXCP_970:
2009 /* VPU assist on 970 */
2012 "970 VPU assist exception is not implemented yet !\n");
2015 cpu_abort(env, "Invalid exception 0x1700 !\n");
2020 switch (PPC_EXCP(env)) {
2021 case PPC_FLAGS_EXCP_970:
2022 /* Thermal exception on 970 */
2024 cpu_abort(env, "970 thermal management exception "
2025 "is not implemented yet !\n");
2028 cpu_abort(env, "Invalid exception 0x1800 !\n");
2033 switch (PPC_EXCP(env)) {
2034 case PPC_FLAGS_EXCP_40x:
2037 cpu_abort(env, "40x debug exception is not implemented yet !\n");
2039 case PPC_FLAGS_EXCP_601:
2040 /* Run mode exception on 601 */
2043 "601 run mode exception is not implemented yet !\n");
2045 case PPC_FLAGS_EXCP_BOOKE:
2046 srr_0 = &env->spr[SPR_BOOKE_CSRR0];
2047 srr_1 = &env->spr[SPR_BOOKE_CSRR1];
2050 cpu_abort(env, "Invalid exception 0x1800 !\n");
2054 /* Other exceptions */
2055 /* Qemu internal exceptions:
2056 * we should never come here with those values: abort execution
2059 cpu_abort(env, "Invalid exception: code %d (%04x)\n", excp, excp);
2062 /* save current instruction location */
2063 *srr_0 = env->nip - 4;
2066 /* save next instruction location */
2076 /* If we disactivated any translation, flush TLBs */
2077 if (msr_ir || msr_dr) {
2080 /* reload MSR with correct bits */
2092 if (PPC_EXCP(env) == PPC_FLAGS_EXCP_BOOKE) {
2094 if (idx == -1 || (idx >= 16 && idx < 32)) {
2095 cpu_abort(env, "Invalid exception index for excp %d %08x idx %d\n",
2098 #if defined(TARGET_PPC64)
2100 env->nip = (uint64_t)env->spr[SPR_BOOKE_IVPR];
2103 env->nip = (uint32_t)env->spr[SPR_BOOKE_IVPR];
2105 env->nip |= env->spr[SPR_BOOKE_IVOR0 + idx];
2107 env->nip |= env->spr[SPR_BOOKE_IVOR32 + idx - 32];
2112 do_compute_hflags(env);
2113 /* Jump to handler */
2114 env->exception_index = EXCP_NONE;
2117 void ppc_hw_interrupt (CPUPPCState *env)
2122 if (loglevel & CPU_LOG_INT) {
2123 fprintf(logfile, "%s: %p pending %08x req %08x me %d ee %d\n",
2124 __func__, env, env->pending_interrupts,
2125 env->interrupt_request, msr_me, msr_ee);
2129 if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
2130 /* External reset / critical input */
2131 /* XXX: critical input should be handled another way.
2132 * This code is not correct !
2134 env->exception_index = EXCP_RESET;
2135 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
2138 if (raised == 0 && msr_me != 0) {
2139 /* Machine check exception */
2140 if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
2141 env->exception_index = EXCP_MACHINE_CHECK;
2142 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
2146 if (raised == 0 && msr_ee != 0) {
2147 #if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
2148 /* Hypervisor decrementer exception */
2149 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
2150 env->exception_index = EXCP_HDECR;
2151 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
2155 /* Decrementer exception */
2156 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
2157 env->exception_index = EXCP_DECR;
2158 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
2160 /* Programmable interval timer on embedded PowerPC */
2161 } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
2162 env->exception_index = EXCP_40x_PIT;
2163 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
2165 /* Fixed interval timer on embedded PowerPC */
2166 } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
2167 env->exception_index = EXCP_40x_FIT;
2168 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
2170 /* Watchdog timer on embedded PowerPC */
2171 } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
2172 env->exception_index = EXCP_40x_WATCHDOG;
2173 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
2175 /* External interrupt */
2176 } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
2177 env->exception_index = EXCP_EXTERNAL;
2178 /* Taking an external interrupt does not clear the external
2182 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
2186 /* Thermal interrupt */
2187 } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
2188 env->exception_index = EXCP_970_THRM;
2189 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
2194 /* External debug exception */
2195 } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
2196 env->exception_index = EXCP_xxx;
2197 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
2202 env->error_code = 0;
2206 #endif /* !CONFIG_USER_ONLY */
2208 void cpu_dump_EA (target_ulong EA)
2218 fprintf(f, "Memory access at address " ADDRX "\n", EA);
2221 void cpu_dump_rfi (target_ulong RA, target_ulong msr)
2231 fprintf(f, "Return from exception at " ADDRX " with flags " ADDRX "\n",
2235 void cpu_ppc_reset (void *opaque)
2240 #if defined (DO_SINGLE_STEP) && 0
2241 /* Single step trace mode */
2245 msr_fp = 1; /* Allow floating point exceptions */
2246 msr_me = 1; /* Allow machine check exceptions */
2247 #if defined(TARGET_PPC64)
2248 msr_sf = 0; /* Boot in 32 bits mode */
2251 #if defined(CONFIG_USER_ONLY)
2255 env->nip = 0xFFFFFFFC;
2256 ppc_tlb_invalidate_all(env);
2258 do_compute_hflags(env);
2262 CPUPPCState *cpu_ppc_init (void)
2266 env = qemu_mallocz(sizeof(CPUPPCState));
2275 void cpu_ppc_close (CPUPPCState *env)
2277 /* Should also remove all opcode tables... */