symbian-qemu-0.9.1-12/qemu-symbian-svp/target-ppc/helper.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  *  PowerPC emulation helpers for qemu.
       
     3  *
       
     4  *  Copyright (c) 2003-2007 Jocelyn Mayer
       
     5  *
       
     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.
       
    10  *
       
    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.
       
    15  *
       
    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
       
    19  */
       
    20 #include <stdarg.h>
       
    21 #include <stdlib.h>
       
    22 #include <stdio.h>
       
    23 #include <string.h>
       
    24 #include <inttypes.h>
       
    25 #include <signal.h>
       
    26 #include <assert.h>
       
    27 
       
    28 #include "cpu.h"
       
    29 #include "exec-all.h"
       
    30 #include "helper_regs.h"
       
    31 #include "qemu-common.h"
       
    32 #include "kvm.h"
       
    33 
       
    34 //#define DEBUG_MMU
       
    35 //#define DEBUG_BATS
       
    36 //#define DEBUG_SLB
       
    37 //#define DEBUG_SOFTWARE_TLB
       
    38 //#define DUMP_PAGE_TABLES
       
    39 //#define DEBUG_EXCEPTIONS
       
    40 //#define FLUSH_ALL_TLBS
       
    41 
       
    42 /*****************************************************************************/
       
    43 /* PowerPC MMU emulation */
       
    44 
       
    45 #if defined(CONFIG_USER_ONLY)
       
    46 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
       
    47                               int mmu_idx, int is_softmmu)
       
    48 {
       
    49     int exception, error_code;
       
    50 
       
    51     if (rw == 2) {
       
    52         exception = POWERPC_EXCP_ISI;
       
    53         error_code = 0x40000000;
       
    54     } else {
       
    55         exception = POWERPC_EXCP_DSI;
       
    56         error_code = 0x40000000;
       
    57         if (rw)
       
    58             error_code |= 0x02000000;
       
    59         env->spr[SPR_DAR] = address;
       
    60         env->spr[SPR_DSISR] = error_code;
       
    61     }
       
    62     env->exception_index = exception;
       
    63     env->error_code = error_code;
       
    64 
       
    65     return 1;
       
    66 }
       
    67 
       
    68 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
       
    69 {
       
    70     return addr;
       
    71 }
       
    72 
       
    73 #else
       
    74 /* Common routines used by software and hardware TLBs emulation */
       
    75 static always_inline int pte_is_valid (target_ulong pte0)
       
    76 {
       
    77     return pte0 & 0x80000000 ? 1 : 0;
       
    78 }
       
    79 
       
    80 static always_inline void pte_invalidate (target_ulong *pte0)
       
    81 {
       
    82     *pte0 &= ~0x80000000;
       
    83 }
       
    84 
       
    85 #if defined(TARGET_PPC64)
       
    86 static always_inline int pte64_is_valid (target_ulong pte0)
       
    87 {
       
    88     return pte0 & 0x0000000000000001ULL ? 1 : 0;
       
    89 }
       
    90 
       
    91 static always_inline void pte64_invalidate (target_ulong *pte0)
       
    92 {
       
    93     *pte0 &= ~0x0000000000000001ULL;
       
    94 }
       
    95 #endif
       
    96 
       
    97 #define PTE_PTEM_MASK 0x7FFFFFBF
       
    98 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
       
    99 #if defined(TARGET_PPC64)
       
   100 #define PTE64_PTEM_MASK 0xFFFFFFFFFFFFFF80ULL
       
   101 #define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F)
       
   102 #endif
       
   103 
       
   104 static always_inline int pp_check (int key, int pp, int nx)
       
   105 {
       
   106     int access;
       
   107 
       
   108     /* Compute access rights */
       
   109     /* When pp is 3/7, the result is undefined. Set it to noaccess */
       
   110     access = 0;
       
   111     if (key == 0) {
       
   112         switch (pp) {
       
   113         case 0x0:
       
   114         case 0x1:
       
   115         case 0x2:
       
   116             access |= PAGE_WRITE;
       
   117             /* No break here */
       
   118         case 0x3:
       
   119         case 0x6:
       
   120             access |= PAGE_READ;
       
   121             break;
       
   122         }
       
   123     } else {
       
   124         switch (pp) {
       
   125         case 0x0:
       
   126         case 0x6:
       
   127             access = 0;
       
   128             break;
       
   129         case 0x1:
       
   130         case 0x3:
       
   131             access = PAGE_READ;
       
   132             break;
       
   133         case 0x2:
       
   134             access = PAGE_READ | PAGE_WRITE;
       
   135             break;
       
   136         }
       
   137     }
       
   138     if (nx == 0)
       
   139         access |= PAGE_EXEC;
       
   140 
       
   141     return access;
       
   142 }
       
   143 
       
   144 static always_inline int check_prot (int prot, int rw, int access_type)
       
   145 {
       
   146     int ret;
       
   147 
       
   148     if (access_type == ACCESS_CODE) {
       
   149         if (prot & PAGE_EXEC)
       
   150             ret = 0;
       
   151         else
       
   152             ret = -2;
       
   153     } else if (rw) {
       
   154         if (prot & PAGE_WRITE)
       
   155             ret = 0;
       
   156         else
       
   157             ret = -2;
       
   158     } else {
       
   159         if (prot & PAGE_READ)
       
   160             ret = 0;
       
   161         else
       
   162             ret = -2;
       
   163     }
       
   164 
       
   165     return ret;
       
   166 }
       
   167 
       
   168 static always_inline int _pte_check (mmu_ctx_t *ctx, int is_64b,
       
   169                                      target_ulong pte0, target_ulong pte1,
       
   170                                      int h, int rw, int type)
       
   171 {
       
   172     target_ulong ptem, mmask;
       
   173     int access, ret, pteh, ptev, pp;
       
   174 
       
   175     access = 0;
       
   176     ret = -1;
       
   177     /* Check validity and table match */
       
   178 #if defined(TARGET_PPC64)
       
   179     if (is_64b) {
       
   180         ptev = pte64_is_valid(pte0);
       
   181         pteh = (pte0 >> 1) & 1;
       
   182     } else
       
   183 #endif
       
   184     {
       
   185         ptev = pte_is_valid(pte0);
       
   186         pteh = (pte0 >> 6) & 1;
       
   187     }
       
   188     if (ptev && h == pteh) {
       
   189         /* Check vsid & api */
       
   190 #if defined(TARGET_PPC64)
       
   191         if (is_64b) {
       
   192             ptem = pte0 & PTE64_PTEM_MASK;
       
   193             mmask = PTE64_CHECK_MASK;
       
   194             pp = (pte1 & 0x00000003) | ((pte1 >> 61) & 0x00000004);
       
   195             ctx->nx |= (pte1 >> 2) & 1; /* No execute bit */
       
   196             ctx->nx |= (pte1 >> 3) & 1; /* Guarded bit    */
       
   197         } else
       
   198 #endif
       
   199         {
       
   200             ptem = pte0 & PTE_PTEM_MASK;
       
   201             mmask = PTE_CHECK_MASK;
       
   202             pp = pte1 & 0x00000003;
       
   203         }
       
   204         if (ptem == ctx->ptem) {
       
   205             if (ctx->raddr != (target_phys_addr_t)-1ULL) {
       
   206                 /* all matches should have equal RPN, WIMG & PP */
       
   207                 if ((ctx->raddr & mmask) != (pte1 & mmask)) {
       
   208                     if (loglevel != 0)
       
   209                         fprintf(logfile, "Bad RPN/WIMG/PP\n");
       
   210                     return -3;
       
   211                 }
       
   212             }
       
   213             /* Compute access rights */
       
   214             access = pp_check(ctx->key, pp, ctx->nx);
       
   215             /* Keep the matching PTE informations */
       
   216             ctx->raddr = pte1;
       
   217             ctx->prot = access;
       
   218             ret = check_prot(ctx->prot, rw, type);
       
   219             if (ret == 0) {
       
   220                 /* Access granted */
       
   221 #if defined (DEBUG_MMU)
       
   222                 if (loglevel != 0)
       
   223                     fprintf(logfile, "PTE access granted !\n");
       
   224 #endif
       
   225             } else {
       
   226                 /* Access right violation */
       
   227 #if defined (DEBUG_MMU)
       
   228                 if (loglevel != 0)
       
   229                     fprintf(logfile, "PTE access rejected\n");
       
   230 #endif
       
   231             }
       
   232         }
       
   233     }
       
   234 
       
   235     return ret;
       
   236 }
       
   237 
       
   238 static always_inline int pte32_check (mmu_ctx_t *ctx,
       
   239                                       target_ulong pte0, target_ulong pte1,
       
   240                                       int h, int rw, int type)
       
   241 {
       
   242     return _pte_check(ctx, 0, pte0, pte1, h, rw, type);
       
   243 }
       
   244 
       
   245 #if defined(TARGET_PPC64)
       
   246 static always_inline int pte64_check (mmu_ctx_t *ctx,
       
   247                                       target_ulong pte0, target_ulong pte1,
       
   248                                       int h, int rw, int type)
       
   249 {
       
   250     return _pte_check(ctx, 1, pte0, pte1, h, rw, type);
       
   251 }
       
   252 #endif
       
   253 
       
   254 static always_inline int pte_update_flags (mmu_ctx_t *ctx, target_ulong *pte1p,
       
   255                                            int ret, int rw)
       
   256 {
       
   257     int store = 0;
       
   258 
       
   259     /* Update page flags */
       
   260     if (!(*pte1p & 0x00000100)) {
       
   261         /* Update accessed flag */
       
   262         *pte1p |= 0x00000100;
       
   263         store = 1;
       
   264     }
       
   265     if (!(*pte1p & 0x00000080)) {
       
   266         if (rw == 1 && ret == 0) {
       
   267             /* Update changed flag */
       
   268             *pte1p |= 0x00000080;
       
   269             store = 1;
       
   270         } else {
       
   271             /* Force page fault for first write access */
       
   272             ctx->prot &= ~PAGE_WRITE;
       
   273         }
       
   274     }
       
   275 
       
   276     return store;
       
   277 }
       
   278 
       
   279 /* Software driven TLB helpers */
       
   280 static always_inline int ppc6xx_tlb_getnum (CPUState *env, target_ulong eaddr,
       
   281                                             int way, int is_code)
       
   282 {
       
   283     int nr;
       
   284 
       
   285     /* Select TLB num in a way from address */
       
   286     nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1);
       
   287     /* Select TLB way */
       
   288     nr += env->tlb_per_way * way;
       
   289     /* 6xx have separate TLBs for instructions and data */
       
   290     if (is_code && env->id_tlbs == 1)
       
   291         nr += env->nb_tlb;
       
   292 
       
   293     return nr;
       
   294 }
       
   295 
       
   296 static always_inline void ppc6xx_tlb_invalidate_all (CPUState *env)
       
   297 {
       
   298     ppc6xx_tlb_t *tlb;
       
   299     int nr, max;
       
   300 
       
   301 #if defined (DEBUG_SOFTWARE_TLB) && 0
       
   302     if (loglevel != 0) {
       
   303         fprintf(logfile, "Invalidate all TLBs\n");
       
   304     }
       
   305 #endif
       
   306     /* Invalidate all defined software TLB */
       
   307     max = env->nb_tlb;
       
   308     if (env->id_tlbs == 1)
       
   309         max *= 2;
       
   310     for (nr = 0; nr < max; nr++) {
       
   311         tlb = &env->tlb[nr].tlb6;
       
   312         pte_invalidate(&tlb->pte0);
       
   313     }
       
   314     tlb_flush(env, 1);
       
   315 }
       
   316 
       
   317 static always_inline void __ppc6xx_tlb_invalidate_virt (CPUState *env,
       
   318                                                         target_ulong eaddr,
       
   319                                                         int is_code,
       
   320                                                         int match_epn)
       
   321 {
       
   322 #if !defined(FLUSH_ALL_TLBS)
       
   323     ppc6xx_tlb_t *tlb;
       
   324     int way, nr;
       
   325 
       
   326     /* Invalidate ITLB + DTLB, all ways */
       
   327     for (way = 0; way < env->nb_ways; way++) {
       
   328         nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code);
       
   329         tlb = &env->tlb[nr].tlb6;
       
   330         if (pte_is_valid(tlb->pte0) && (match_epn == 0 || eaddr == tlb->EPN)) {
       
   331 #if defined (DEBUG_SOFTWARE_TLB)
       
   332             if (loglevel != 0) {
       
   333                 fprintf(logfile, "TLB invalidate %d/%d " ADDRX "\n",
       
   334                         nr, env->nb_tlb, eaddr);
       
   335             }
       
   336 #endif
       
   337             pte_invalidate(&tlb->pte0);
       
   338             tlb_flush_page(env, tlb->EPN);
       
   339         }
       
   340     }
       
   341 #else
       
   342     /* XXX: PowerPC specification say this is valid as well */
       
   343     ppc6xx_tlb_invalidate_all(env);
       
   344 #endif
       
   345 }
       
   346 
       
   347 static always_inline void ppc6xx_tlb_invalidate_virt (CPUState *env,
       
   348                                                       target_ulong eaddr,
       
   349                                                       int is_code)
       
   350 {
       
   351     __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0);
       
   352 }
       
   353 
       
   354 void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
       
   355                        target_ulong pte0, target_ulong pte1)
       
   356 {
       
   357     ppc6xx_tlb_t *tlb;
       
   358     int nr;
       
   359 
       
   360     nr = ppc6xx_tlb_getnum(env, EPN, way, is_code);
       
   361     tlb = &env->tlb[nr].tlb6;
       
   362 #if defined (DEBUG_SOFTWARE_TLB)
       
   363     if (loglevel != 0) {
       
   364         fprintf(logfile, "Set TLB %d/%d EPN " ADDRX " PTE0 " ADDRX
       
   365                 " PTE1 " ADDRX "\n", nr, env->nb_tlb, EPN, pte0, pte1);
       
   366     }
       
   367 #endif
       
   368     /* Invalidate any pending reference in Qemu for this virtual address */
       
   369     __ppc6xx_tlb_invalidate_virt(env, EPN, is_code, 1);
       
   370     tlb->pte0 = pte0;
       
   371     tlb->pte1 = pte1;
       
   372     tlb->EPN = EPN;
       
   373     /* Store last way for LRU mechanism */
       
   374     env->last_way = way;
       
   375 }
       
   376 
       
   377 static always_inline int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx,
       
   378                                            target_ulong eaddr, int rw,
       
   379                                            int access_type)
       
   380 {
       
   381     ppc6xx_tlb_t *tlb;
       
   382     int nr, best, way;
       
   383     int ret;
       
   384 
       
   385     best = -1;
       
   386     ret = -1; /* No TLB found */
       
   387     for (way = 0; way < env->nb_ways; way++) {
       
   388         nr = ppc6xx_tlb_getnum(env, eaddr, way,
       
   389                                access_type == ACCESS_CODE ? 1 : 0);
       
   390         tlb = &env->tlb[nr].tlb6;
       
   391         /* This test "emulates" the PTE index match for hardware TLBs */
       
   392         if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) {
       
   393 #if defined (DEBUG_SOFTWARE_TLB)
       
   394             if (loglevel != 0) {
       
   395                 fprintf(logfile, "TLB %d/%d %s [" ADDRX " " ADDRX
       
   396                         "] <> " ADDRX "\n",
       
   397                         nr, env->nb_tlb,
       
   398                         pte_is_valid(tlb->pte0) ? "valid" : "inval",
       
   399                         tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr);
       
   400             }
       
   401 #endif
       
   402             continue;
       
   403         }
       
   404 #if defined (DEBUG_SOFTWARE_TLB)
       
   405         if (loglevel != 0) {
       
   406             fprintf(logfile, "TLB %d/%d %s " ADDRX " <> " ADDRX " " ADDRX
       
   407                     " %c %c\n",
       
   408                     nr, env->nb_tlb,
       
   409                     pte_is_valid(tlb->pte0) ? "valid" : "inval",
       
   410                     tlb->EPN, eaddr, tlb->pte1,
       
   411                     rw ? 'S' : 'L', access_type == ACCESS_CODE ? 'I' : 'D');
       
   412         }
       
   413 #endif
       
   414         switch (pte32_check(ctx, tlb->pte0, tlb->pte1, 0, rw, access_type)) {
       
   415         case -3:
       
   416             /* TLB inconsistency */
       
   417             return -1;
       
   418         case -2:
       
   419             /* Access violation */
       
   420             ret = -2;
       
   421             best = nr;
       
   422             break;
       
   423         case -1:
       
   424         default:
       
   425             /* No match */
       
   426             break;
       
   427         case 0:
       
   428             /* access granted */
       
   429             /* XXX: we should go on looping to check all TLBs consistency
       
   430              *      but we can speed-up the whole thing as the
       
   431              *      result would be undefined if TLBs are not consistent.
       
   432              */
       
   433             ret = 0;
       
   434             best = nr;
       
   435             goto done;
       
   436         }
       
   437     }
       
   438     if (best != -1) {
       
   439     done:
       
   440 #if defined (DEBUG_SOFTWARE_TLB)
       
   441         if (loglevel != 0) {
       
   442             fprintf(logfile, "found TLB at addr " PADDRX " prot=%01x ret=%d\n",
       
   443                     ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
       
   444         }
       
   445 #endif
       
   446         /* Update page flags */
       
   447         pte_update_flags(ctx, &env->tlb[best].tlb6.pte1, ret, rw);
       
   448     }
       
   449 
       
   450     return ret;
       
   451 }
       
   452 
       
   453 /* Perform BAT hit & translation */
       
   454 static always_inline void bat_size_prot (CPUState *env, target_ulong *blp,
       
   455                                          int *validp, int *protp,
       
   456                                          target_ulong *BATu, target_ulong *BATl)
       
   457 {
       
   458     target_ulong bl;
       
   459     int pp, valid, prot;
       
   460 
       
   461     bl = (*BATu & 0x00001FFC) << 15;
       
   462     valid = 0;
       
   463     prot = 0;
       
   464     if (((msr_pr == 0) && (*BATu & 0x00000002)) ||
       
   465         ((msr_pr != 0) && (*BATu & 0x00000001))) {
       
   466         valid = 1;
       
   467         pp = *BATl & 0x00000003;
       
   468         if (pp != 0) {
       
   469             prot = PAGE_READ | PAGE_EXEC;
       
   470             if (pp == 0x2)
       
   471                 prot |= PAGE_WRITE;
       
   472         }
       
   473     }
       
   474     *blp = bl;
       
   475     *validp = valid;
       
   476     *protp = prot;
       
   477 }
       
   478 
       
   479 static always_inline void bat_601_size_prot (CPUState *env,target_ulong *blp,
       
   480                                              int *validp, int *protp,
       
   481                                              target_ulong *BATu,
       
   482                                              target_ulong *BATl)
       
   483 {
       
   484     target_ulong bl;
       
   485     int key, pp, valid, prot;
       
   486 
       
   487     bl = (*BATl & 0x0000003F) << 17;
       
   488 #if defined (DEBUG_BATS)
       
   489     if (loglevel != 0) {
       
   490         fprintf(logfile, "b %02x ==> bl " ADDRX " msk " ADDRX "\n",
       
   491                 (uint8_t)(*BATl & 0x0000003F), bl, ~bl);
       
   492     }
       
   493 #endif
       
   494     prot = 0;
       
   495     valid = (*BATl >> 6) & 1;
       
   496     if (valid) {
       
   497         pp = *BATu & 0x00000003;
       
   498         if (msr_pr == 0)
       
   499             key = (*BATu >> 3) & 1;
       
   500         else
       
   501             key = (*BATu >> 2) & 1;
       
   502         prot = pp_check(key, pp, 0);
       
   503     }
       
   504     *blp = bl;
       
   505     *validp = valid;
       
   506     *protp = prot;
       
   507 }
       
   508 
       
   509 static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
       
   510                                   target_ulong virtual, int rw, int type)
       
   511 {
       
   512     target_ulong *BATlt, *BATut, *BATu, *BATl;
       
   513     target_ulong base, BEPIl, BEPIu, bl;
       
   514     int i, valid, prot;
       
   515     int ret = -1;
       
   516 
       
   517 #if defined (DEBUG_BATS)
       
   518     if (loglevel != 0) {
       
   519         fprintf(logfile, "%s: %cBAT v " ADDRX "\n", __func__,
       
   520                 type == ACCESS_CODE ? 'I' : 'D', virtual);
       
   521     }
       
   522 #endif
       
   523     switch (type) {
       
   524     case ACCESS_CODE:
       
   525         BATlt = env->IBAT[1];
       
   526         BATut = env->IBAT[0];
       
   527         break;
       
   528     default:
       
   529         BATlt = env->DBAT[1];
       
   530         BATut = env->DBAT[0];
       
   531         break;
       
   532     }
       
   533     base = virtual & 0xFFFC0000;
       
   534     for (i = 0; i < env->nb_BATs; i++) {
       
   535         BATu = &BATut[i];
       
   536         BATl = &BATlt[i];
       
   537         BEPIu = *BATu & 0xF0000000;
       
   538         BEPIl = *BATu & 0x0FFE0000;
       
   539         if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
       
   540             bat_601_size_prot(env, &bl, &valid, &prot, BATu, BATl);
       
   541         } else {
       
   542             bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
       
   543         }
       
   544 #if defined (DEBUG_BATS)
       
   545         if (loglevel != 0) {
       
   546             fprintf(logfile, "%s: %cBAT%d v " ADDRX " BATu " ADDRX
       
   547                     " BATl " ADDRX "\n", __func__,
       
   548                     type == ACCESS_CODE ? 'I' : 'D', i, virtual, *BATu, *BATl);
       
   549         }
       
   550 #endif
       
   551         if ((virtual & 0xF0000000) == BEPIu &&
       
   552             ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
       
   553             /* BAT matches */
       
   554             if (valid != 0) {
       
   555                 /* Get physical address */
       
   556                 ctx->raddr = (*BATl & 0xF0000000) |
       
   557                     ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
       
   558                     (virtual & 0x0001F000);
       
   559                 /* Compute access rights */
       
   560                 ctx->prot = prot;
       
   561                 ret = check_prot(ctx->prot, rw, type);
       
   562 #if defined (DEBUG_BATS)
       
   563                 if (ret == 0 && loglevel != 0) {
       
   564                     fprintf(logfile, "BAT %d match: r " PADDRX " prot=%c%c\n",
       
   565                             i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-',
       
   566                             ctx->prot & PAGE_WRITE ? 'W' : '-');
       
   567                 }
       
   568 #endif
       
   569                 break;
       
   570             }
       
   571         }
       
   572     }
       
   573     if (ret < 0) {
       
   574 #if defined (DEBUG_BATS)
       
   575         if (loglevel != 0) {
       
   576             fprintf(logfile, "no BAT match for " ADDRX ":\n", virtual);
       
   577             for (i = 0; i < 4; i++) {
       
   578                 BATu = &BATut[i];
       
   579                 BATl = &BATlt[i];
       
   580                 BEPIu = *BATu & 0xF0000000;
       
   581                 BEPIl = *BATu & 0x0FFE0000;
       
   582                 bl = (*BATu & 0x00001FFC) << 15;
       
   583                 fprintf(logfile, "%s: %cBAT%d v " ADDRX " BATu " ADDRX
       
   584                         " BATl " ADDRX " \n\t" ADDRX " " ADDRX " " ADDRX "\n",
       
   585                         __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,
       
   586                         *BATu, *BATl, BEPIu, BEPIl, bl);
       
   587             }
       
   588         }
       
   589 #endif
       
   590     }
       
   591 
       
   592     /* No hit */
       
   593     return ret;
       
   594 }
       
   595 
       
   596 /* PTE table lookup */
       
   597 static always_inline int _find_pte (mmu_ctx_t *ctx, int is_64b, int h,
       
   598                                     int rw, int type)
       
   599 {
       
   600     target_ulong base, pte0, pte1;
       
   601     int i, good = -1;
       
   602     int ret, r;
       
   603 
       
   604     ret = -1; /* No entry found */
       
   605     base = ctx->pg_addr[h];
       
   606     for (i = 0; i < 8; i++) {
       
   607 #if defined(TARGET_PPC64)
       
   608         if (is_64b) {
       
   609             pte0 = ldq_phys(base + (i * 16));
       
   610             pte1 =  ldq_phys(base + (i * 16) + 8);
       
   611             r = pte64_check(ctx, pte0, pte1, h, rw, type);
       
   612 #if defined (DEBUG_MMU)
       
   613             if (loglevel != 0) {
       
   614                 fprintf(logfile, "Load pte from " ADDRX " => " ADDRX " " ADDRX
       
   615                         " %d %d %d " ADDRX "\n",
       
   616                         base + (i * 16), pte0, pte1,
       
   617                         (int)(pte0 & 1), h, (int)((pte0 >> 1) & 1),
       
   618                         ctx->ptem);
       
   619             }
       
   620 #endif
       
   621         } else
       
   622 #endif
       
   623         {
       
   624             pte0 = ldl_phys(base + (i * 8));
       
   625             pte1 =  ldl_phys(base + (i * 8) + 4);
       
   626             r = pte32_check(ctx, pte0, pte1, h, rw, type);
       
   627 #if defined (DEBUG_MMU)
       
   628             if (loglevel != 0) {
       
   629                 fprintf(logfile, "Load pte from " ADDRX " => " ADDRX " " ADDRX
       
   630                         " %d %d %d " ADDRX "\n",
       
   631                         base + (i * 8), pte0, pte1,
       
   632                         (int)(pte0 >> 31), h, (int)((pte0 >> 6) & 1),
       
   633                         ctx->ptem);
       
   634             }
       
   635 #endif
       
   636         }
       
   637         switch (r) {
       
   638         case -3:
       
   639             /* PTE inconsistency */
       
   640             return -1;
       
   641         case -2:
       
   642             /* Access violation */
       
   643             ret = -2;
       
   644             good = i;
       
   645             break;
       
   646         case -1:
       
   647         default:
       
   648             /* No PTE match */
       
   649             break;
       
   650         case 0:
       
   651             /* access granted */
       
   652             /* XXX: we should go on looping to check all PTEs consistency
       
   653              *      but if we can speed-up the whole thing as the
       
   654              *      result would be undefined if PTEs are not consistent.
       
   655              */
       
   656             ret = 0;
       
   657             good = i;
       
   658             goto done;
       
   659         }
       
   660     }
       
   661     if (good != -1) {
       
   662     done:
       
   663 #if defined (DEBUG_MMU)
       
   664         if (loglevel != 0) {
       
   665             fprintf(logfile, "found PTE at addr " PADDRX " prot=%01x ret=%d\n",
       
   666                     ctx->raddr, ctx->prot, ret);
       
   667         }
       
   668 #endif
       
   669         /* Update page flags */
       
   670         pte1 = ctx->raddr;
       
   671         if (pte_update_flags(ctx, &pte1, ret, rw) == 1) {
       
   672 #if defined(TARGET_PPC64)
       
   673             if (is_64b) {
       
   674                 stq_phys_notdirty(base + (good * 16) + 8, pte1);
       
   675             } else
       
   676 #endif
       
   677             {
       
   678                 stl_phys_notdirty(base + (good * 8) + 4, pte1);
       
   679             }
       
   680         }
       
   681     }
       
   682 
       
   683     return ret;
       
   684 }
       
   685 
       
   686 static always_inline int find_pte32 (mmu_ctx_t *ctx, int h, int rw, int type)
       
   687 {
       
   688     return _find_pte(ctx, 0, h, rw, type);
       
   689 }
       
   690 
       
   691 #if defined(TARGET_PPC64)
       
   692 static always_inline int find_pte64 (mmu_ctx_t *ctx, int h, int rw, int type)
       
   693 {
       
   694     return _find_pte(ctx, 1, h, rw, type);
       
   695 }
       
   696 #endif
       
   697 
       
   698 static always_inline int find_pte (CPUState *env, mmu_ctx_t *ctx,
       
   699                                    int h, int rw, int type)
       
   700 {
       
   701 #if defined(TARGET_PPC64)
       
   702     if (env->mmu_model & POWERPC_MMU_64)
       
   703         return find_pte64(ctx, h, rw, type);
       
   704 #endif
       
   705 
       
   706     return find_pte32(ctx, h, rw, type);
       
   707 }
       
   708 
       
   709 #if defined(TARGET_PPC64)
       
   710 static always_inline int slb_is_valid (uint64_t slb64)
       
   711 {
       
   712     return slb64 & 0x0000000008000000ULL ? 1 : 0;
       
   713 }
       
   714 
       
   715 static always_inline void slb_invalidate (uint64_t *slb64)
       
   716 {
       
   717     *slb64 &= ~0x0000000008000000ULL;
       
   718 }
       
   719 
       
   720 static always_inline int slb_lookup (CPUPPCState *env, target_ulong eaddr,
       
   721                                      target_ulong *vsid,
       
   722                                      target_ulong *page_mask, int *attr)
       
   723 {
       
   724     target_phys_addr_t sr_base;
       
   725     target_ulong mask;
       
   726     uint64_t tmp64;
       
   727     uint32_t tmp;
       
   728     int n, ret;
       
   729 
       
   730     ret = -5;
       
   731     sr_base = env->spr[SPR_ASR];
       
   732 #if defined(DEBUG_SLB)
       
   733     if (loglevel != 0) {
       
   734         fprintf(logfile, "%s: eaddr " ADDRX " base " PADDRX "\n",
       
   735                 __func__, eaddr, sr_base);
       
   736     }
       
   737 #endif
       
   738     mask = 0x0000000000000000ULL; /* Avoid gcc warning */
       
   739     for (n = 0; n < env->slb_nr; n++) {
       
   740         tmp64 = ldq_phys(sr_base);
       
   741         tmp = ldl_phys(sr_base + 8);
       
   742 #if defined(DEBUG_SLB)
       
   743         if (loglevel != 0) {
       
   744             fprintf(logfile, "%s: seg %d " PADDRX " %016" PRIx64 " %08"
       
   745                     PRIx32 "\n", __func__, n, sr_base, tmp64, tmp);
       
   746         }
       
   747 #endif
       
   748         if (slb_is_valid(tmp64)) {
       
   749             /* SLB entry is valid */
       
   750             switch (tmp64 & 0x0000000006000000ULL) {
       
   751             case 0x0000000000000000ULL:
       
   752                 /* 256 MB segment */
       
   753                 mask = 0xFFFFFFFFF0000000ULL;
       
   754                 break;
       
   755             case 0x0000000002000000ULL:
       
   756                 /* 1 TB segment */
       
   757                 mask = 0xFFFF000000000000ULL;
       
   758                 break;
       
   759             case 0x0000000004000000ULL:
       
   760             case 0x0000000006000000ULL:
       
   761                 /* Reserved => segment is invalid */
       
   762                 continue;
       
   763             }
       
   764             if ((eaddr & mask) == (tmp64 & mask)) {
       
   765                 /* SLB match */
       
   766                 *vsid = ((tmp64 << 24) | (tmp >> 8)) & 0x0003FFFFFFFFFFFFULL;
       
   767                 *page_mask = ~mask;
       
   768                 *attr = tmp & 0xFF;
       
   769                 ret = n;
       
   770                 break;
       
   771             }
       
   772         }
       
   773         sr_base += 12;
       
   774     }
       
   775 
       
   776     return ret;
       
   777 }
       
   778 
       
   779 void ppc_slb_invalidate_all (CPUPPCState *env)
       
   780 {
       
   781     target_phys_addr_t sr_base;
       
   782     uint64_t tmp64;
       
   783     int n, do_invalidate;
       
   784 
       
   785     do_invalidate = 0;
       
   786     sr_base = env->spr[SPR_ASR];
       
   787     /* XXX: Warning: slbia never invalidates the first segment */
       
   788     for (n = 1; n < env->slb_nr; n++) {
       
   789         tmp64 = ldq_phys(sr_base);
       
   790         if (slb_is_valid(tmp64)) {
       
   791             slb_invalidate(&tmp64);
       
   792             stq_phys(sr_base, tmp64);
       
   793             /* XXX: given the fact that segment size is 256 MB or 1TB,
       
   794              *      and we still don't have a tlb_flush_mask(env, n, mask)
       
   795              *      in Qemu, we just invalidate all TLBs
       
   796              */
       
   797             do_invalidate = 1;
       
   798         }
       
   799         sr_base += 12;
       
   800     }
       
   801     if (do_invalidate)
       
   802         tlb_flush(env, 1);
       
   803 }
       
   804 
       
   805 void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
       
   806 {
       
   807     target_phys_addr_t sr_base;
       
   808     target_ulong vsid, page_mask;
       
   809     uint64_t tmp64;
       
   810     int attr;
       
   811     int n;
       
   812 
       
   813     n = slb_lookup(env, T0, &vsid, &page_mask, &attr);
       
   814     if (n >= 0) {
       
   815         sr_base = env->spr[SPR_ASR];
       
   816         sr_base += 12 * n;
       
   817         tmp64 = ldq_phys(sr_base);
       
   818         if (slb_is_valid(tmp64)) {
       
   819             slb_invalidate(&tmp64);
       
   820             stq_phys(sr_base, tmp64);
       
   821             /* XXX: given the fact that segment size is 256 MB or 1TB,
       
   822              *      and we still don't have a tlb_flush_mask(env, n, mask)
       
   823              *      in Qemu, we just invalidate all TLBs
       
   824              */
       
   825             tlb_flush(env, 1);
       
   826         }
       
   827     }
       
   828 }
       
   829 
       
   830 target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr)
       
   831 {
       
   832     target_phys_addr_t sr_base;
       
   833     target_ulong rt;
       
   834     uint64_t tmp64;
       
   835     uint32_t tmp;
       
   836 
       
   837     sr_base = env->spr[SPR_ASR];
       
   838     sr_base += 12 * slb_nr;
       
   839     tmp64 = ldq_phys(sr_base);
       
   840     tmp = ldl_phys(sr_base + 8);
       
   841     if (tmp64 & 0x0000000008000000ULL) {
       
   842         /* SLB entry is valid */
       
   843         /* Copy SLB bits 62:88 to Rt 37:63 (VSID 23:49) */
       
   844         rt = tmp >> 8;             /* 65:88 => 40:63 */
       
   845         rt |= (tmp64 & 0x7) << 24; /* 62:64 => 37:39 */
       
   846         /* Copy SLB bits 89:92 to Rt 33:36 (KsKpNL) */
       
   847         rt |= ((tmp >> 4) & 0xF) << 27;
       
   848     } else {
       
   849         rt = 0;
       
   850     }
       
   851 #if defined(DEBUG_SLB)
       
   852     if (loglevel != 0) {
       
   853         fprintf(logfile, "%s: " PADDRX " %016" PRIx64 " %08" PRIx32 " => %d "
       
   854                 ADDRX "\n", __func__, sr_base, tmp64, tmp, slb_nr, rt);
       
   855     }
       
   856 #endif
       
   857 
       
   858     return rt;
       
   859 }
       
   860 
       
   861 void ppc_store_slb (CPUPPCState *env, int slb_nr, target_ulong rs)
       
   862 {
       
   863     target_phys_addr_t sr_base;
       
   864     uint64_t tmp64;
       
   865     uint32_t tmp;
       
   866 
       
   867     sr_base = env->spr[SPR_ASR];
       
   868     sr_base += 12 * slb_nr;
       
   869     /* Copy Rs bits 37:63 to SLB 62:88 */
       
   870     tmp = rs << 8;
       
   871     tmp64 = (rs >> 24) & 0x7;
       
   872     /* Copy Rs bits 33:36 to SLB 89:92 */
       
   873     tmp |= ((rs >> 27) & 0xF) << 4;
       
   874     /* Set the valid bit */
       
   875     tmp64 |= 1 << 27;
       
   876     /* Set ESID */
       
   877     tmp64 |= (uint32_t)slb_nr << 28;
       
   878 #if defined(DEBUG_SLB)
       
   879     if (loglevel != 0) {
       
   880         fprintf(logfile, "%s: %d " ADDRX " => " PADDRX " %016" PRIx64
       
   881                 " %08" PRIx32 "\n", __func__,
       
   882                 slb_nr, rs, sr_base, tmp64, tmp);
       
   883     }
       
   884 #endif
       
   885     /* Write SLB entry to memory */
       
   886     stq_phys(sr_base, tmp64);
       
   887     stl_phys(sr_base + 8, tmp);
       
   888 }
       
   889 #endif /* defined(TARGET_PPC64) */
       
   890 
       
   891 /* Perform segment based translation */
       
   892 static always_inline target_phys_addr_t get_pgaddr (target_phys_addr_t sdr1,
       
   893                                                     int sdr_sh,
       
   894                                                     target_phys_addr_t hash,
       
   895                                                     target_phys_addr_t mask)
       
   896 {
       
   897     return (sdr1 & ((target_phys_addr_t)(-1ULL) << sdr_sh)) | (hash & mask);
       
   898 }
       
   899 
       
   900 static always_inline int get_segment (CPUState *env, mmu_ctx_t *ctx,
       
   901                                       target_ulong eaddr, int rw, int type)
       
   902 {
       
   903     target_phys_addr_t sdr, hash, mask, sdr_mask, htab_mask;
       
   904     target_ulong sr, vsid, vsid_mask, pgidx, page_mask;
       
   905 #if defined(TARGET_PPC64)
       
   906     int attr;
       
   907 #endif
       
   908     int ds, vsid_sh, sdr_sh, pr;
       
   909     int ret, ret2;
       
   910 
       
   911     pr = msr_pr;
       
   912 #if defined(TARGET_PPC64)
       
   913     if (env->mmu_model & POWERPC_MMU_64) {
       
   914 #if defined (DEBUG_MMU)
       
   915         if (loglevel != 0) {
       
   916             fprintf(logfile, "Check SLBs\n");
       
   917         }
       
   918 #endif
       
   919         ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr);
       
   920         if (ret < 0)
       
   921             return ret;
       
   922         ctx->key = ((attr & 0x40) && (pr != 0)) ||
       
   923             ((attr & 0x80) && (pr == 0)) ? 1 : 0;
       
   924         ds = 0;
       
   925         ctx->nx = attr & 0x20 ? 1 : 0;
       
   926         vsid_mask = 0x00003FFFFFFFFF80ULL;
       
   927         vsid_sh = 7;
       
   928         sdr_sh = 18;
       
   929         sdr_mask = 0x3FF80;
       
   930     } else
       
   931 #endif /* defined(TARGET_PPC64) */
       
   932     {
       
   933         sr = env->sr[eaddr >> 28];
       
   934         page_mask = 0x0FFFFFFF;
       
   935         ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
       
   936                     ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
       
   937         ds = sr & 0x80000000 ? 1 : 0;
       
   938         ctx->nx = sr & 0x10000000 ? 1 : 0;
       
   939         vsid = sr & 0x00FFFFFF;
       
   940         vsid_mask = 0x01FFFFC0;
       
   941         vsid_sh = 6;
       
   942         sdr_sh = 16;
       
   943         sdr_mask = 0xFFC0;
       
   944 #if defined (DEBUG_MMU)
       
   945         if (loglevel != 0) {
       
   946             fprintf(logfile, "Check segment v=" ADDRX " %d " ADDRX
       
   947                     " nip=" ADDRX " lr=" ADDRX " ir=%d dr=%d pr=%d %d t=%d\n",
       
   948                     eaddr, (int)(eaddr >> 28), sr, env->nip,
       
   949                     env->lr, (int)msr_ir, (int)msr_dr, pr != 0 ? 1 : 0,
       
   950                     rw, type);
       
   951         }
       
   952 #endif
       
   953     }
       
   954 #if defined (DEBUG_MMU)
       
   955     if (loglevel != 0) {
       
   956         fprintf(logfile, "pte segment: key=%d ds %d nx %d vsid " ADDRX "\n",
       
   957                 ctx->key, ds, ctx->nx, vsid);
       
   958     }
       
   959 #endif
       
   960     ret = -1;
       
   961     if (!ds) {
       
   962         /* Check if instruction fetch is allowed, if needed */
       
   963         if (type != ACCESS_CODE || ctx->nx == 0) {
       
   964             /* Page address translation */
       
   965             /* Primary table address */
       
   966             sdr = env->sdr1;
       
   967             pgidx = (eaddr & page_mask) >> TARGET_PAGE_BITS;
       
   968 #if defined(TARGET_PPC64)
       
   969             if (env->mmu_model & POWERPC_MMU_64) {
       
   970                 htab_mask = 0x0FFFFFFF >> (28 - (sdr & 0x1F));
       
   971                 /* XXX: this is false for 1 TB segments */
       
   972                 hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
       
   973             } else
       
   974 #endif
       
   975             {
       
   976                 htab_mask = sdr & 0x000001FF;
       
   977                 hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
       
   978             }
       
   979             mask = (htab_mask << sdr_sh) | sdr_mask;
       
   980 #if defined (DEBUG_MMU)
       
   981             if (loglevel != 0) {
       
   982                 fprintf(logfile, "sdr " PADDRX " sh %d hash " PADDRX
       
   983                         " mask " PADDRX " " ADDRX "\n",
       
   984                         sdr, sdr_sh, hash, mask, page_mask);
       
   985             }
       
   986 #endif
       
   987             ctx->pg_addr[0] = get_pgaddr(sdr, sdr_sh, hash, mask);
       
   988             /* Secondary table address */
       
   989             hash = (~hash) & vsid_mask;
       
   990 #if defined (DEBUG_MMU)
       
   991             if (loglevel != 0) {
       
   992                 fprintf(logfile, "sdr " PADDRX " sh %d hash " PADDRX
       
   993                         " mask " PADDRX "\n",
       
   994                         sdr, sdr_sh, hash, mask);
       
   995             }
       
   996 #endif
       
   997             ctx->pg_addr[1] = get_pgaddr(sdr, sdr_sh, hash, mask);
       
   998 #if defined(TARGET_PPC64)
       
   999             if (env->mmu_model & POWERPC_MMU_64) {
       
  1000                 /* Only 5 bits of the page index are used in the AVPN */
       
  1001                 ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80);
       
  1002             } else
       
  1003 #endif
       
  1004             {
       
  1005                 ctx->ptem = (vsid << 7) | (pgidx >> 10);
       
  1006             }
       
  1007             /* Initialize real address with an invalid value */
       
  1008             ctx->raddr = (target_phys_addr_t)-1ULL;
       
  1009             if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx ||
       
  1010                          env->mmu_model == POWERPC_MMU_SOFT_74xx)) {
       
  1011                 /* Software TLB search */
       
  1012                 ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
       
  1013             } else {
       
  1014 #if defined (DEBUG_MMU)
       
  1015                 if (loglevel != 0) {
       
  1016                     fprintf(logfile, "0 sdr1=" PADDRX " vsid=" ADDRX " "
       
  1017                             "api=" ADDRX " hash=" PADDRX
       
  1018                             " pg_addr=" PADDRX "\n",
       
  1019                             sdr, vsid, pgidx, hash, ctx->pg_addr[0]);
       
  1020                 }
       
  1021 #endif
       
  1022                 /* Primary table lookup */
       
  1023                 ret = find_pte(env, ctx, 0, rw, type);
       
  1024                 if (ret < 0) {
       
  1025                     /* Secondary table lookup */
       
  1026 #if defined (DEBUG_MMU)
       
  1027                     if (eaddr != 0xEFFFFFFF && loglevel != 0) {
       
  1028                         fprintf(logfile, "1 sdr1=" PADDRX " vsid=" ADDRX " "
       
  1029                                 "api=" ADDRX " hash=" PADDRX
       
  1030                                 " pg_addr=" PADDRX "\n",
       
  1031                                 sdr, vsid, pgidx, hash, ctx->pg_addr[1]);
       
  1032                     }
       
  1033 #endif
       
  1034                     ret2 = find_pte(env, ctx, 1, rw, type);
       
  1035                     if (ret2 != -1)
       
  1036                         ret = ret2;
       
  1037                 }
       
  1038             }
       
  1039 #if defined (DUMP_PAGE_TABLES)
       
  1040             if (loglevel != 0) {
       
  1041                 target_phys_addr_t curaddr;
       
  1042                 uint32_t a0, a1, a2, a3;
       
  1043                 fprintf(logfile, "Page table: " PADDRX " len " PADDRX "\n",
       
  1044                         sdr, mask + 0x80);
       
  1045                 for (curaddr = sdr; curaddr < (sdr + mask + 0x80);
       
  1046                      curaddr += 16) {
       
  1047                     a0 = ldl_phys(curaddr);
       
  1048                     a1 = ldl_phys(curaddr + 4);
       
  1049                     a2 = ldl_phys(curaddr + 8);
       
  1050                     a3 = ldl_phys(curaddr + 12);
       
  1051                     if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
       
  1052                         fprintf(logfile, PADDRX ": %08x %08x %08x %08x\n",
       
  1053                                 curaddr, a0, a1, a2, a3);
       
  1054                     }
       
  1055                 }
       
  1056             }
       
  1057 #endif
       
  1058         } else {
       
  1059 #if defined (DEBUG_MMU)
       
  1060             if (loglevel != 0)
       
  1061                 fprintf(logfile, "No access allowed\n");
       
  1062 #endif
       
  1063             ret = -3;
       
  1064         }
       
  1065     } else {
       
  1066 #if defined (DEBUG_MMU)
       
  1067         if (loglevel != 0)
       
  1068             fprintf(logfile, "direct store...\n");
       
  1069 #endif
       
  1070         /* Direct-store segment : absolutely *BUGGY* for now */
       
  1071         switch (type) {
       
  1072         case ACCESS_INT:
       
  1073             /* Integer load/store : only access allowed */
       
  1074             break;
       
  1075         case ACCESS_CODE:
       
  1076             /* No code fetch is allowed in direct-store areas */
       
  1077             return -4;
       
  1078         case ACCESS_FLOAT:
       
  1079             /* Floating point load/store */
       
  1080             return -4;
       
  1081         case ACCESS_RES:
       
  1082             /* lwarx, ldarx or srwcx. */
       
  1083             return -4;
       
  1084         case ACCESS_CACHE:
       
  1085             /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
       
  1086             /* Should make the instruction do no-op.
       
  1087              * As it already do no-op, it's quite easy :-)
       
  1088              */
       
  1089             ctx->raddr = eaddr;
       
  1090             return 0;
       
  1091         case ACCESS_EXT:
       
  1092             /* eciwx or ecowx */
       
  1093             return -4;
       
  1094         default:
       
  1095             if (logfile) {
       
  1096                 fprintf(logfile, "ERROR: instruction should not need "
       
  1097                         "address translation\n");
       
  1098             }
       
  1099             return -4;
       
  1100         }
       
  1101         if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) {
       
  1102             ctx->raddr = eaddr;
       
  1103             ret = 2;
       
  1104         } else {
       
  1105             ret = -2;
       
  1106         }
       
  1107     }
       
  1108 
       
  1109     return ret;
       
  1110 }
       
  1111 
       
  1112 /* Generic TLB check function for embedded PowerPC implementations */
       
  1113 static always_inline int ppcemb_tlb_check (CPUState *env, ppcemb_tlb_t *tlb,
       
  1114                                            target_phys_addr_t *raddrp,
       
  1115                                            target_ulong address,
       
  1116                                            uint32_t pid, int ext, int i)
       
  1117 {
       
  1118     target_ulong mask;
       
  1119 
       
  1120     /* Check valid flag */
       
  1121     if (!(tlb->prot & PAGE_VALID)) {
       
  1122         if (loglevel != 0)
       
  1123             fprintf(logfile, "%s: TLB %d not valid\n", __func__, i);
       
  1124         return -1;
       
  1125     }
       
  1126     mask = ~(tlb->size - 1);
       
  1127 #if defined (DEBUG_SOFTWARE_TLB)
       
  1128     if (loglevel != 0) {
       
  1129         fprintf(logfile, "%s: TLB %d address " ADDRX " PID %u <=> " ADDRX
       
  1130                 " " ADDRX " %u\n",
       
  1131                 __func__, i, address, pid, tlb->EPN, mask, (uint32_t)tlb->PID);
       
  1132     }
       
  1133 #endif
       
  1134     /* Check PID */
       
  1135     if (tlb->PID != 0 && tlb->PID != pid)
       
  1136         return -1;
       
  1137     /* Check effective address */
       
  1138     if ((address & mask) != tlb->EPN)
       
  1139         return -1;
       
  1140     *raddrp = (tlb->RPN & mask) | (address & ~mask);
       
  1141 #if (TARGET_PHYS_ADDR_BITS >= 36)
       
  1142     if (ext) {
       
  1143         /* Extend the physical address to 36 bits */
       
  1144         *raddrp |= (target_phys_addr_t)(tlb->RPN & 0xF) << 32;
       
  1145     }
       
  1146 #endif
       
  1147 
       
  1148     return 0;
       
  1149 }
       
  1150 
       
  1151 /* Generic TLB search function for PowerPC embedded implementations */
       
  1152 int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid)
       
  1153 {
       
  1154     ppcemb_tlb_t *tlb;
       
  1155     target_phys_addr_t raddr;
       
  1156     int i, ret;
       
  1157 
       
  1158     /* Default return value is no match */
       
  1159     ret = -1;
       
  1160     for (i = 0; i < env->nb_tlb; i++) {
       
  1161         tlb = &env->tlb[i].tlbe;
       
  1162         if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, 0, i) == 0) {
       
  1163             ret = i;
       
  1164             break;
       
  1165         }
       
  1166     }
       
  1167 
       
  1168     return ret;
       
  1169 }
       
  1170 
       
  1171 /* Helpers specific to PowerPC 40x implementations */
       
  1172 static always_inline void ppc4xx_tlb_invalidate_all (CPUState *env)
       
  1173 {
       
  1174     ppcemb_tlb_t *tlb;
       
  1175     int i;
       
  1176 
       
  1177     for (i = 0; i < env->nb_tlb; i++) {
       
  1178         tlb = &env->tlb[i].tlbe;
       
  1179         tlb->prot &= ~PAGE_VALID;
       
  1180     }
       
  1181     tlb_flush(env, 1);
       
  1182 }
       
  1183 
       
  1184 static always_inline void ppc4xx_tlb_invalidate_virt (CPUState *env,
       
  1185                                                       target_ulong eaddr,
       
  1186                                                       uint32_t pid)
       
  1187 {
       
  1188 #if !defined(FLUSH_ALL_TLBS)
       
  1189     ppcemb_tlb_t *tlb;
       
  1190     target_phys_addr_t raddr;
       
  1191     target_ulong page, end;
       
  1192     int i;
       
  1193 
       
  1194     for (i = 0; i < env->nb_tlb; i++) {
       
  1195         tlb = &env->tlb[i].tlbe;
       
  1196         if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) {
       
  1197             end = tlb->EPN + tlb->size;
       
  1198             for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
       
  1199                 tlb_flush_page(env, page);
       
  1200             tlb->prot &= ~PAGE_VALID;
       
  1201             break;
       
  1202         }
       
  1203     }
       
  1204 #else
       
  1205     ppc4xx_tlb_invalidate_all(env);
       
  1206 #endif
       
  1207 }
       
  1208 
       
  1209 static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
       
  1210                                  target_ulong address, int rw, int access_type)
       
  1211 {
       
  1212     ppcemb_tlb_t *tlb;
       
  1213     target_phys_addr_t raddr;
       
  1214     int i, ret, zsel, zpr, pr;
       
  1215 
       
  1216     ret = -1;
       
  1217     raddr = (target_phys_addr_t)-1ULL;
       
  1218     pr = msr_pr;
       
  1219     for (i = 0; i < env->nb_tlb; i++) {
       
  1220         tlb = &env->tlb[i].tlbe;
       
  1221         if (ppcemb_tlb_check(env, tlb, &raddr, address,
       
  1222                              env->spr[SPR_40x_PID], 0, i) < 0)
       
  1223             continue;
       
  1224         zsel = (tlb->attr >> 4) & 0xF;
       
  1225         zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3;
       
  1226 #if defined (DEBUG_SOFTWARE_TLB)
       
  1227         if (loglevel != 0) {
       
  1228             fprintf(logfile, "%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
       
  1229                     __func__, i, zsel, zpr, rw, tlb->attr);
       
  1230         }
       
  1231 #endif
       
  1232         /* Check execute enable bit */
       
  1233         switch (zpr) {
       
  1234         case 0x2:
       
  1235             if (pr != 0)
       
  1236                 goto check_perms;
       
  1237             /* No break here */
       
  1238         case 0x3:
       
  1239             /* All accesses granted */
       
  1240             ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
       
  1241             ret = 0;
       
  1242             break;
       
  1243         case 0x0:
       
  1244             if (pr != 0) {
       
  1245                 ctx->prot = 0;
       
  1246                 ret = -2;
       
  1247                 break;
       
  1248             }
       
  1249             /* No break here */
       
  1250         case 0x1:
       
  1251         check_perms:
       
  1252             /* Check from TLB entry */
       
  1253             /* XXX: there is a problem here or in the TLB fill code... */
       
  1254             ctx->prot = tlb->prot;
       
  1255             ctx->prot |= PAGE_EXEC;
       
  1256             ret = check_prot(ctx->prot, rw, access_type);
       
  1257             break;
       
  1258         }
       
  1259         if (ret >= 0) {
       
  1260             ctx->raddr = raddr;
       
  1261 #if defined (DEBUG_SOFTWARE_TLB)
       
  1262             if (loglevel != 0) {
       
  1263                 fprintf(logfile, "%s: access granted " ADDRX " => " PADDRX
       
  1264                         " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
       
  1265                         ret);
       
  1266             }
       
  1267 #endif
       
  1268             return 0;
       
  1269         }
       
  1270     }
       
  1271 #if defined (DEBUG_SOFTWARE_TLB)
       
  1272     if (loglevel != 0) {
       
  1273         fprintf(logfile, "%s: access refused " ADDRX " => " PADDRX
       
  1274                 " %d %d\n", __func__, address, raddr, ctx->prot,
       
  1275                 ret);
       
  1276     }
       
  1277 #endif
       
  1278 
       
  1279     return ret;
       
  1280 }
       
  1281 
       
  1282 void store_40x_sler (CPUPPCState *env, uint32_t val)
       
  1283 {
       
  1284     /* XXX: TO BE FIXED */
       
  1285     if (val != 0x00000000) {
       
  1286         cpu_abort(env, "Little-endian regions are not supported by now\n");
       
  1287     }
       
  1288     env->spr[SPR_405_SLER] = val;
       
  1289 }
       
  1290 
       
  1291 static int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
       
  1292                                           target_ulong address, int rw,
       
  1293                                           int access_type)
       
  1294 {
       
  1295     ppcemb_tlb_t *tlb;
       
  1296     target_phys_addr_t raddr;
       
  1297     int i, prot, ret;
       
  1298 
       
  1299     ret = -1;
       
  1300     raddr = (target_phys_addr_t)-1ULL;
       
  1301     for (i = 0; i < env->nb_tlb; i++) {
       
  1302         tlb = &env->tlb[i].tlbe;
       
  1303         if (ppcemb_tlb_check(env, tlb, &raddr, address,
       
  1304                              env->spr[SPR_BOOKE_PID], 1, i) < 0)
       
  1305             continue;
       
  1306         if (msr_pr != 0)
       
  1307             prot = tlb->prot & 0xF;
       
  1308         else
       
  1309             prot = (tlb->prot >> 4) & 0xF;
       
  1310         /* Check the address space */
       
  1311         if (access_type == ACCESS_CODE) {
       
  1312             if (msr_ir != (tlb->attr & 1))
       
  1313                 continue;
       
  1314             ctx->prot = prot;
       
  1315             if (prot & PAGE_EXEC) {
       
  1316                 ret = 0;
       
  1317                 break;
       
  1318             }
       
  1319             ret = -3;
       
  1320         } else {
       
  1321             if (msr_dr != (tlb->attr & 1))
       
  1322                 continue;
       
  1323             ctx->prot = prot;
       
  1324             if ((!rw && prot & PAGE_READ) || (rw && (prot & PAGE_WRITE))) {
       
  1325                 ret = 0;
       
  1326                 break;
       
  1327             }
       
  1328             ret = -2;
       
  1329         }
       
  1330     }
       
  1331     if (ret >= 0)
       
  1332         ctx->raddr = raddr;
       
  1333 
       
  1334     return ret;
       
  1335 }
       
  1336 
       
  1337 static always_inline int check_physical (CPUState *env, mmu_ctx_t *ctx,
       
  1338                                          target_ulong eaddr, int rw)
       
  1339 {
       
  1340     int in_plb, ret;
       
  1341 
       
  1342     ctx->raddr = eaddr;
       
  1343     ctx->prot = PAGE_READ | PAGE_EXEC;
       
  1344     ret = 0;
       
  1345     switch (env->mmu_model) {
       
  1346     case POWERPC_MMU_32B:
       
  1347     case POWERPC_MMU_601:
       
  1348     case POWERPC_MMU_SOFT_6xx:
       
  1349     case POWERPC_MMU_SOFT_74xx:
       
  1350     case POWERPC_MMU_SOFT_4xx:
       
  1351     case POWERPC_MMU_REAL:
       
  1352     case POWERPC_MMU_BOOKE:
       
  1353         ctx->prot |= PAGE_WRITE;
       
  1354         break;
       
  1355 #if defined(TARGET_PPC64)
       
  1356     case POWERPC_MMU_620:
       
  1357     case POWERPC_MMU_64B:
       
  1358         /* Real address are 60 bits long */
       
  1359         ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL;
       
  1360         ctx->prot |= PAGE_WRITE;
       
  1361         break;
       
  1362 #endif
       
  1363     case POWERPC_MMU_SOFT_4xx_Z:
       
  1364         if (unlikely(msr_pe != 0)) {
       
  1365             /* 403 family add some particular protections,
       
  1366              * using PBL/PBU registers for accesses with no translation.
       
  1367              */
       
  1368             in_plb =
       
  1369                 /* Check PLB validity */
       
  1370                 (env->pb[0] < env->pb[1] &&
       
  1371                  /* and address in plb area */
       
  1372                  eaddr >= env->pb[0] && eaddr < env->pb[1]) ||
       
  1373                 (env->pb[2] < env->pb[3] &&
       
  1374                  eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0;
       
  1375             if (in_plb ^ msr_px) {
       
  1376                 /* Access in protected area */
       
  1377                 if (rw == 1) {
       
  1378                     /* Access is not allowed */
       
  1379                     ret = -2;
       
  1380                 }
       
  1381             } else {
       
  1382                 /* Read-write access is allowed */
       
  1383                 ctx->prot |= PAGE_WRITE;
       
  1384             }
       
  1385         }
       
  1386         break;
       
  1387     case POWERPC_MMU_MPC8xx:
       
  1388         /* XXX: TODO */
       
  1389         cpu_abort(env, "MPC8xx MMU model is not implemented\n");
       
  1390         break;
       
  1391     case POWERPC_MMU_BOOKE_FSL:
       
  1392         /* XXX: TODO */
       
  1393         cpu_abort(env, "BookE FSL MMU model not implemented\n");
       
  1394         break;
       
  1395     default:
       
  1396         cpu_abort(env, "Unknown or invalid MMU model\n");
       
  1397         return -1;
       
  1398     }
       
  1399 
       
  1400     return ret;
       
  1401 }
       
  1402 
       
  1403 int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
       
  1404                           int rw, int access_type)
       
  1405 {
       
  1406     int ret;
       
  1407 
       
  1408 #if 0
       
  1409     if (loglevel != 0) {
       
  1410         fprintf(logfile, "%s\n", __func__);
       
  1411     }
       
  1412 #endif
       
  1413     if ((access_type == ACCESS_CODE && msr_ir == 0) ||
       
  1414         (access_type != ACCESS_CODE && msr_dr == 0)) {
       
  1415         /* No address translation */
       
  1416         ret = check_physical(env, ctx, eaddr, rw);
       
  1417     } else {
       
  1418         ret = -1;
       
  1419         switch (env->mmu_model) {
       
  1420         case POWERPC_MMU_32B:
       
  1421         case POWERPC_MMU_601:
       
  1422         case POWERPC_MMU_SOFT_6xx:
       
  1423         case POWERPC_MMU_SOFT_74xx:
       
  1424 #if defined(TARGET_PPC64)
       
  1425         case POWERPC_MMU_620:
       
  1426         case POWERPC_MMU_64B:
       
  1427 #endif
       
  1428             /* Try to find a BAT */
       
  1429             if (env->nb_BATs != 0)
       
  1430                 ret = get_bat(env, ctx, eaddr, rw, access_type);
       
  1431             if (ret < 0) {
       
  1432                 /* We didn't match any BAT entry or don't have BATs */
       
  1433                 ret = get_segment(env, ctx, eaddr, rw, access_type);
       
  1434             }
       
  1435             break;
       
  1436         case POWERPC_MMU_SOFT_4xx:
       
  1437         case POWERPC_MMU_SOFT_4xx_Z:
       
  1438             ret = mmu40x_get_physical_address(env, ctx, eaddr,
       
  1439                                               rw, access_type);
       
  1440             break;
       
  1441         case POWERPC_MMU_BOOKE:
       
  1442             ret = mmubooke_get_physical_address(env, ctx, eaddr,
       
  1443                                                 rw, access_type);
       
  1444             break;
       
  1445         case POWERPC_MMU_MPC8xx:
       
  1446             /* XXX: TODO */
       
  1447             cpu_abort(env, "MPC8xx MMU model is not implemented\n");
       
  1448             break;
       
  1449         case POWERPC_MMU_BOOKE_FSL:
       
  1450             /* XXX: TODO */
       
  1451             cpu_abort(env, "BookE FSL MMU model not implemented\n");
       
  1452             return -1;
       
  1453         case POWERPC_MMU_REAL:
       
  1454             cpu_abort(env, "PowerPC in real mode do not do any translation\n");
       
  1455             return -1;
       
  1456         default:
       
  1457             cpu_abort(env, "Unknown or invalid MMU model\n");
       
  1458             return -1;
       
  1459         }
       
  1460     }
       
  1461 #if 0
       
  1462     if (loglevel != 0) {
       
  1463         fprintf(logfile, "%s address " ADDRX " => %d " PADDRX "\n",
       
  1464                 __func__, eaddr, ret, ctx->raddr);
       
  1465     }
       
  1466 #endif
       
  1467 
       
  1468     return ret;
       
  1469 }
       
  1470 
       
  1471 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
       
  1472 {
       
  1473     mmu_ctx_t ctx;
       
  1474 
       
  1475     if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0))
       
  1476         return -1;
       
  1477 
       
  1478     return ctx.raddr & TARGET_PAGE_MASK;
       
  1479 }
       
  1480 
       
  1481 /* Perform address translation */
       
  1482 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
       
  1483                               int mmu_idx, int is_softmmu)
       
  1484 {
       
  1485     mmu_ctx_t ctx;
       
  1486     int access_type;
       
  1487     int ret = 0;
       
  1488 
       
  1489     if (rw == 2) {
       
  1490         /* code access */
       
  1491         rw = 0;
       
  1492         access_type = ACCESS_CODE;
       
  1493     } else {
       
  1494         /* data access */
       
  1495         access_type = env->access_type;
       
  1496     }
       
  1497     ret = get_physical_address(env, &ctx, address, rw, access_type);
       
  1498     if (ret == 0) {
       
  1499         ret = tlb_set_page_exec(env, address & TARGET_PAGE_MASK,
       
  1500                                 ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
       
  1501                                 mmu_idx, is_softmmu);
       
  1502     } else if (ret < 0) {
       
  1503 #if defined (DEBUG_MMU)
       
  1504         if (loglevel != 0)
       
  1505             cpu_dump_state(env, logfile, fprintf, 0);
       
  1506 #endif
       
  1507         if (access_type == ACCESS_CODE) {
       
  1508             switch (ret) {
       
  1509             case -1:
       
  1510                 /* No matches in page tables or TLB */
       
  1511                 switch (env->mmu_model) {
       
  1512                 case POWERPC_MMU_SOFT_6xx:
       
  1513                     env->exception_index = POWERPC_EXCP_IFTLB;
       
  1514                     env->error_code = 1 << 18;
       
  1515                     env->spr[SPR_IMISS] = address;
       
  1516                     env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
       
  1517                     goto tlb_miss;
       
  1518                 case POWERPC_MMU_SOFT_74xx:
       
  1519                     env->exception_index = POWERPC_EXCP_IFTLB;
       
  1520                     goto tlb_miss_74xx;
       
  1521                 case POWERPC_MMU_SOFT_4xx:
       
  1522                 case POWERPC_MMU_SOFT_4xx_Z:
       
  1523                     env->exception_index = POWERPC_EXCP_ITLB;
       
  1524                     env->error_code = 0;
       
  1525                     env->spr[SPR_40x_DEAR] = address;
       
  1526                     env->spr[SPR_40x_ESR] = 0x00000000;
       
  1527                     break;
       
  1528                 case POWERPC_MMU_32B:
       
  1529                 case POWERPC_MMU_601:
       
  1530 #if defined(TARGET_PPC64)
       
  1531                 case POWERPC_MMU_620:
       
  1532                 case POWERPC_MMU_64B:
       
  1533 #endif
       
  1534                     env->exception_index = POWERPC_EXCP_ISI;
       
  1535                     env->error_code = 0x40000000;
       
  1536                     break;
       
  1537                 case POWERPC_MMU_BOOKE:
       
  1538                     /* XXX: TODO */
       
  1539                     cpu_abort(env, "BookE MMU model is not implemented\n");
       
  1540                     return -1;
       
  1541                 case POWERPC_MMU_BOOKE_FSL:
       
  1542                     /* XXX: TODO */
       
  1543                     cpu_abort(env, "BookE FSL MMU model is not implemented\n");
       
  1544                     return -1;
       
  1545                 case POWERPC_MMU_MPC8xx:
       
  1546                     /* XXX: TODO */
       
  1547                     cpu_abort(env, "MPC8xx MMU model is not implemented\n");
       
  1548                     break;
       
  1549                 case POWERPC_MMU_REAL:
       
  1550                     cpu_abort(env, "PowerPC in real mode should never raise "
       
  1551                               "any MMU exceptions\n");
       
  1552                     return -1;
       
  1553                 default:
       
  1554                     cpu_abort(env, "Unknown or invalid MMU model\n");
       
  1555                     return -1;
       
  1556                 }
       
  1557                 break;
       
  1558             case -2:
       
  1559                 /* Access rights violation */
       
  1560                 env->exception_index = POWERPC_EXCP_ISI;
       
  1561                 env->error_code = 0x08000000;
       
  1562                 break;
       
  1563             case -3:
       
  1564                 /* No execute protection violation */
       
  1565                 env->exception_index = POWERPC_EXCP_ISI;
       
  1566                 env->error_code = 0x10000000;
       
  1567                 break;
       
  1568             case -4:
       
  1569                 /* Direct store exception */
       
  1570                 /* No code fetch is allowed in direct-store areas */
       
  1571                 env->exception_index = POWERPC_EXCP_ISI;
       
  1572                 env->error_code = 0x10000000;
       
  1573                 break;
       
  1574 #if defined(TARGET_PPC64)
       
  1575             case -5:
       
  1576                 /* No match in segment table */
       
  1577                 if (env->mmu_model == POWERPC_MMU_620) {
       
  1578                     env->exception_index = POWERPC_EXCP_ISI;
       
  1579                     /* XXX: this might be incorrect */
       
  1580                     env->error_code = 0x40000000;
       
  1581                 } else {
       
  1582                     env->exception_index = POWERPC_EXCP_ISEG;
       
  1583                     env->error_code = 0;
       
  1584                 }
       
  1585                 break;
       
  1586 #endif
       
  1587             }
       
  1588         } else {
       
  1589             switch (ret) {
       
  1590             case -1:
       
  1591                 /* No matches in page tables or TLB */
       
  1592                 switch (env->mmu_model) {
       
  1593                 case POWERPC_MMU_SOFT_6xx:
       
  1594                     if (rw == 1) {
       
  1595                         env->exception_index = POWERPC_EXCP_DSTLB;
       
  1596                         env->error_code = 1 << 16;
       
  1597                     } else {
       
  1598                         env->exception_index = POWERPC_EXCP_DLTLB;
       
  1599                         env->error_code = 0;
       
  1600                     }
       
  1601                     env->spr[SPR_DMISS] = address;
       
  1602                     env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
       
  1603                 tlb_miss:
       
  1604                     env->error_code |= ctx.key << 19;
       
  1605                     env->spr[SPR_HASH1] = ctx.pg_addr[0];
       
  1606                     env->spr[SPR_HASH2] = ctx.pg_addr[1];
       
  1607                     break;
       
  1608                 case POWERPC_MMU_SOFT_74xx:
       
  1609                     if (rw == 1) {
       
  1610                         env->exception_index = POWERPC_EXCP_DSTLB;
       
  1611                     } else {
       
  1612                         env->exception_index = POWERPC_EXCP_DLTLB;
       
  1613                     }
       
  1614                 tlb_miss_74xx:
       
  1615                     /* Implement LRU algorithm */
       
  1616                     env->error_code = ctx.key << 19;
       
  1617                     env->spr[SPR_TLBMISS] = (address & ~((target_ulong)0x3)) |
       
  1618                         ((env->last_way + 1) & (env->nb_ways - 1));
       
  1619                     env->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem;
       
  1620                     break;
       
  1621                 case POWERPC_MMU_SOFT_4xx:
       
  1622                 case POWERPC_MMU_SOFT_4xx_Z:
       
  1623                     env->exception_index = POWERPC_EXCP_DTLB;
       
  1624                     env->error_code = 0;
       
  1625                     env->spr[SPR_40x_DEAR] = address;
       
  1626                     if (rw)
       
  1627                         env->spr[SPR_40x_ESR] = 0x00800000;
       
  1628                     else
       
  1629                         env->spr[SPR_40x_ESR] = 0x00000000;
       
  1630                     break;
       
  1631                 case POWERPC_MMU_32B:
       
  1632                 case POWERPC_MMU_601:
       
  1633 #if defined(TARGET_PPC64)
       
  1634                 case POWERPC_MMU_620:
       
  1635                 case POWERPC_MMU_64B:
       
  1636 #endif
       
  1637                     env->exception_index = POWERPC_EXCP_DSI;
       
  1638                     env->error_code = 0;
       
  1639                     env->spr[SPR_DAR] = address;
       
  1640                     if (rw == 1)
       
  1641                         env->spr[SPR_DSISR] = 0x42000000;
       
  1642                     else
       
  1643                         env->spr[SPR_DSISR] = 0x40000000;
       
  1644                     break;
       
  1645                 case POWERPC_MMU_MPC8xx:
       
  1646                     /* XXX: TODO */
       
  1647                     cpu_abort(env, "MPC8xx MMU model is not implemented\n");
       
  1648                     break;
       
  1649                 case POWERPC_MMU_BOOKE:
       
  1650                     /* XXX: TODO */
       
  1651                     cpu_abort(env, "BookE MMU model is not implemented\n");
       
  1652                     return -1;
       
  1653                 case POWERPC_MMU_BOOKE_FSL:
       
  1654                     /* XXX: TODO */
       
  1655                     cpu_abort(env, "BookE FSL MMU model is not implemented\n");
       
  1656                     return -1;
       
  1657                 case POWERPC_MMU_REAL:
       
  1658                     cpu_abort(env, "PowerPC in real mode should never raise "
       
  1659                               "any MMU exceptions\n");
       
  1660                     return -1;
       
  1661                 default:
       
  1662                     cpu_abort(env, "Unknown or invalid MMU model\n");
       
  1663                     return -1;
       
  1664                 }
       
  1665                 break;
       
  1666             case -2:
       
  1667                 /* Access rights violation */
       
  1668                 env->exception_index = POWERPC_EXCP_DSI;
       
  1669                 env->error_code = 0;
       
  1670                 env->spr[SPR_DAR] = address;
       
  1671                 if (rw == 1)
       
  1672                     env->spr[SPR_DSISR] = 0x0A000000;
       
  1673                 else
       
  1674                     env->spr[SPR_DSISR] = 0x08000000;
       
  1675                 break;
       
  1676             case -4:
       
  1677                 /* Direct store exception */
       
  1678                 switch (access_type) {
       
  1679                 case ACCESS_FLOAT:
       
  1680                     /* Floating point load/store */
       
  1681                     env->exception_index = POWERPC_EXCP_ALIGN;
       
  1682                     env->error_code = POWERPC_EXCP_ALIGN_FP;
       
  1683                     env->spr[SPR_DAR] = address;
       
  1684                     break;
       
  1685                 case ACCESS_RES:
       
  1686                     /* lwarx, ldarx or stwcx. */
       
  1687                     env->exception_index = POWERPC_EXCP_DSI;
       
  1688                     env->error_code = 0;
       
  1689                     env->spr[SPR_DAR] = address;
       
  1690                     if (rw == 1)
       
  1691                         env->spr[SPR_DSISR] = 0x06000000;
       
  1692                     else
       
  1693                         env->spr[SPR_DSISR] = 0x04000000;
       
  1694                     break;
       
  1695                 case ACCESS_EXT:
       
  1696                     /* eciwx or ecowx */
       
  1697                     env->exception_index = POWERPC_EXCP_DSI;
       
  1698                     env->error_code = 0;
       
  1699                     env->spr[SPR_DAR] = address;
       
  1700                     if (rw == 1)
       
  1701                         env->spr[SPR_DSISR] = 0x06100000;
       
  1702                     else
       
  1703                         env->spr[SPR_DSISR] = 0x04100000;
       
  1704                     break;
       
  1705                 default:
       
  1706                     printf("DSI: invalid exception (%d)\n", ret);
       
  1707                     env->exception_index = POWERPC_EXCP_PROGRAM;
       
  1708                     env->error_code =
       
  1709                         POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
       
  1710                     env->spr[SPR_DAR] = address;
       
  1711                     break;
       
  1712                 }
       
  1713                 break;
       
  1714 #if defined(TARGET_PPC64)
       
  1715             case -5:
       
  1716                 /* No match in segment table */
       
  1717                 if (env->mmu_model == POWERPC_MMU_620) {
       
  1718                     env->exception_index = POWERPC_EXCP_DSI;
       
  1719                     env->error_code = 0;
       
  1720                     env->spr[SPR_DAR] = address;
       
  1721                     /* XXX: this might be incorrect */
       
  1722                     if (rw == 1)
       
  1723                         env->spr[SPR_DSISR] = 0x42000000;
       
  1724                     else
       
  1725                         env->spr[SPR_DSISR] = 0x40000000;
       
  1726                 } else {
       
  1727                     env->exception_index = POWERPC_EXCP_DSEG;
       
  1728                     env->error_code = 0;
       
  1729                     env->spr[SPR_DAR] = address;
       
  1730                 }
       
  1731                 break;
       
  1732 #endif
       
  1733             }
       
  1734         }
       
  1735 #if 0
       
  1736         printf("%s: set exception to %d %02x\n", __func__,
       
  1737                env->exception, env->error_code);
       
  1738 #endif
       
  1739         ret = 1;
       
  1740     }
       
  1741 
       
  1742     return ret;
       
  1743 }
       
  1744 
       
  1745 /*****************************************************************************/
       
  1746 /* BATs management */
       
  1747 #if !defined(FLUSH_ALL_TLBS)
       
  1748 static always_inline void do_invalidate_BAT (CPUPPCState *env,
       
  1749                                              target_ulong BATu,
       
  1750                                              target_ulong mask)
       
  1751 {
       
  1752     target_ulong base, end, page;
       
  1753 
       
  1754     base = BATu & ~0x0001FFFF;
       
  1755     end = base + mask + 0x00020000;
       
  1756 #if defined (DEBUG_BATS)
       
  1757     if (loglevel != 0) {
       
  1758         fprintf(logfile, "Flush BAT from " ADDRX " to " ADDRX " (" ADDRX ")\n",
       
  1759                 base, end, mask);
       
  1760     }
       
  1761 #endif
       
  1762     for (page = base; page != end; page += TARGET_PAGE_SIZE)
       
  1763         tlb_flush_page(env, page);
       
  1764 #if defined (DEBUG_BATS)
       
  1765     if (loglevel != 0)
       
  1766         fprintf(logfile, "Flush done\n");
       
  1767 #endif
       
  1768 }
       
  1769 #endif
       
  1770 
       
  1771 static always_inline void dump_store_bat (CPUPPCState *env, char ID,
       
  1772                                           int ul, int nr, target_ulong value)
       
  1773 {
       
  1774 #if defined (DEBUG_BATS)
       
  1775     if (loglevel != 0) {
       
  1776         fprintf(logfile, "Set %cBAT%d%c to " ADDRX " (" ADDRX ")\n",
       
  1777                 ID, nr, ul == 0 ? 'u' : 'l', value, env->nip);
       
  1778     }
       
  1779 #endif
       
  1780 }
       
  1781 
       
  1782 void ppc_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
       
  1783 {
       
  1784     target_ulong mask;
       
  1785 
       
  1786     dump_store_bat(env, 'I', 0, nr, value);
       
  1787     if (env->IBAT[0][nr] != value) {
       
  1788         mask = (value << 15) & 0x0FFE0000UL;
       
  1789 #if !defined(FLUSH_ALL_TLBS)
       
  1790         do_invalidate_BAT(env, env->IBAT[0][nr], mask);
       
  1791 #endif
       
  1792         /* When storing valid upper BAT, mask BEPI and BRPN
       
  1793          * and invalidate all TLBs covered by this BAT
       
  1794          */
       
  1795         mask = (value << 15) & 0x0FFE0000UL;
       
  1796         env->IBAT[0][nr] = (value & 0x00001FFFUL) |
       
  1797             (value & ~0x0001FFFFUL & ~mask);
       
  1798         env->IBAT[1][nr] = (env->IBAT[1][nr] & 0x0000007B) |
       
  1799             (env->IBAT[1][nr] & ~0x0001FFFF & ~mask);
       
  1800 #if !defined(FLUSH_ALL_TLBS)
       
  1801         do_invalidate_BAT(env, env->IBAT[0][nr], mask);
       
  1802 #else
       
  1803         tlb_flush(env, 1);
       
  1804 #endif
       
  1805     }
       
  1806 }
       
  1807 
       
  1808 void ppc_store_ibatl (CPUPPCState *env, int nr, target_ulong value)
       
  1809 {
       
  1810     dump_store_bat(env, 'I', 1, nr, value);
       
  1811     env->IBAT[1][nr] = value;
       
  1812 }
       
  1813 
       
  1814 void ppc_store_dbatu (CPUPPCState *env, int nr, target_ulong value)
       
  1815 {
       
  1816     target_ulong mask;
       
  1817 
       
  1818     dump_store_bat(env, 'D', 0, nr, value);
       
  1819     if (env->DBAT[0][nr] != value) {
       
  1820         /* When storing valid upper BAT, mask BEPI and BRPN
       
  1821          * and invalidate all TLBs covered by this BAT
       
  1822          */
       
  1823         mask = (value << 15) & 0x0FFE0000UL;
       
  1824 #if !defined(FLUSH_ALL_TLBS)
       
  1825         do_invalidate_BAT(env, env->DBAT[0][nr], mask);
       
  1826 #endif
       
  1827         mask = (value << 15) & 0x0FFE0000UL;
       
  1828         env->DBAT[0][nr] = (value & 0x00001FFFUL) |
       
  1829             (value & ~0x0001FFFFUL & ~mask);
       
  1830         env->DBAT[1][nr] = (env->DBAT[1][nr] & 0x0000007B) |
       
  1831             (env->DBAT[1][nr] & ~0x0001FFFF & ~mask);
       
  1832 #if !defined(FLUSH_ALL_TLBS)
       
  1833         do_invalidate_BAT(env, env->DBAT[0][nr], mask);
       
  1834 #else
       
  1835         tlb_flush(env, 1);
       
  1836 #endif
       
  1837     }
       
  1838 }
       
  1839 
       
  1840 void ppc_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
       
  1841 {
       
  1842     dump_store_bat(env, 'D', 1, nr, value);
       
  1843     env->DBAT[1][nr] = value;
       
  1844 }
       
  1845 
       
  1846 void ppc_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value)
       
  1847 {
       
  1848     target_ulong mask;
       
  1849     int do_inval;
       
  1850 
       
  1851     dump_store_bat(env, 'I', 0, nr, value);
       
  1852     if (env->IBAT[0][nr] != value) {
       
  1853         do_inval = 0;
       
  1854         mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
       
  1855         if (env->IBAT[1][nr] & 0x40) {
       
  1856             /* Invalidate BAT only if it is valid */
       
  1857 #if !defined(FLUSH_ALL_TLBS)
       
  1858             do_invalidate_BAT(env, env->IBAT[0][nr], mask);
       
  1859 #else
       
  1860             do_inval = 1;
       
  1861 #endif
       
  1862         }
       
  1863         /* When storing valid upper BAT, mask BEPI and BRPN
       
  1864          * and invalidate all TLBs covered by this BAT
       
  1865          */
       
  1866         env->IBAT[0][nr] = (value & 0x00001FFFUL) |
       
  1867             (value & ~0x0001FFFFUL & ~mask);
       
  1868         env->DBAT[0][nr] = env->IBAT[0][nr];
       
  1869         if (env->IBAT[1][nr] & 0x40) {
       
  1870 #if !defined(FLUSH_ALL_TLBS)
       
  1871             do_invalidate_BAT(env, env->IBAT[0][nr], mask);
       
  1872 #else
       
  1873             do_inval = 1;
       
  1874 #endif
       
  1875         }
       
  1876 #if defined(FLUSH_ALL_TLBS)
       
  1877         if (do_inval)
       
  1878             tlb_flush(env, 1);
       
  1879 #endif
       
  1880     }
       
  1881 }
       
  1882 
       
  1883 void ppc_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value)
       
  1884 {
       
  1885     target_ulong mask;
       
  1886     int do_inval;
       
  1887 
       
  1888     dump_store_bat(env, 'I', 1, nr, value);
       
  1889     if (env->IBAT[1][nr] != value) {
       
  1890         do_inval = 0;
       
  1891         if (env->IBAT[1][nr] & 0x40) {
       
  1892 #if !defined(FLUSH_ALL_TLBS)
       
  1893             mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
       
  1894             do_invalidate_BAT(env, env->IBAT[0][nr], mask);
       
  1895 #else
       
  1896             do_inval = 1;
       
  1897 #endif
       
  1898         }
       
  1899         if (value & 0x40) {
       
  1900 #if !defined(FLUSH_ALL_TLBS)
       
  1901             mask = (value << 17) & 0x0FFE0000UL;
       
  1902             do_invalidate_BAT(env, env->IBAT[0][nr], mask);
       
  1903 #else
       
  1904             do_inval = 1;
       
  1905 #endif
       
  1906         }
       
  1907         env->IBAT[1][nr] = value;
       
  1908         env->DBAT[1][nr] = value;
       
  1909 #if defined(FLUSH_ALL_TLBS)
       
  1910         if (do_inval)
       
  1911             tlb_flush(env, 1);
       
  1912 #endif
       
  1913     }
       
  1914 }
       
  1915 
       
  1916 /*****************************************************************************/
       
  1917 /* TLB management */
       
  1918 void ppc_tlb_invalidate_all (CPUPPCState *env)
       
  1919 {
       
  1920     switch (env->mmu_model) {
       
  1921     case POWERPC_MMU_SOFT_6xx:
       
  1922     case POWERPC_MMU_SOFT_74xx:
       
  1923         ppc6xx_tlb_invalidate_all(env);
       
  1924         break;
       
  1925     case POWERPC_MMU_SOFT_4xx:
       
  1926     case POWERPC_MMU_SOFT_4xx_Z:
       
  1927         ppc4xx_tlb_invalidate_all(env);
       
  1928         break;
       
  1929     case POWERPC_MMU_REAL:
       
  1930         cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
       
  1931         break;
       
  1932     case POWERPC_MMU_MPC8xx:
       
  1933         /* XXX: TODO */
       
  1934         cpu_abort(env, "MPC8xx MMU model is not implemented\n");
       
  1935         break;
       
  1936     case POWERPC_MMU_BOOKE:
       
  1937         /* XXX: TODO */
       
  1938         cpu_abort(env, "BookE MMU model is not implemented\n");
       
  1939         break;
       
  1940     case POWERPC_MMU_BOOKE_FSL:
       
  1941         /* XXX: TODO */
       
  1942         cpu_abort(env, "BookE MMU model is not implemented\n");
       
  1943         break;
       
  1944     case POWERPC_MMU_32B:
       
  1945     case POWERPC_MMU_601:
       
  1946 #if defined(TARGET_PPC64)
       
  1947     case POWERPC_MMU_620:
       
  1948     case POWERPC_MMU_64B:
       
  1949 #endif /* defined(TARGET_PPC64) */
       
  1950         tlb_flush(env, 1);
       
  1951         break;
       
  1952     default:
       
  1953         /* XXX: TODO */
       
  1954         cpu_abort(env, "Unknown MMU model\n");
       
  1955         break;
       
  1956     }
       
  1957 }
       
  1958 
       
  1959 void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
       
  1960 {
       
  1961 #if !defined(FLUSH_ALL_TLBS)
       
  1962     addr &= TARGET_PAGE_MASK;
       
  1963     switch (env->mmu_model) {
       
  1964     case POWERPC_MMU_SOFT_6xx:
       
  1965     case POWERPC_MMU_SOFT_74xx:
       
  1966         ppc6xx_tlb_invalidate_virt(env, addr, 0);
       
  1967         if (env->id_tlbs == 1)
       
  1968             ppc6xx_tlb_invalidate_virt(env, addr, 1);
       
  1969         break;
       
  1970     case POWERPC_MMU_SOFT_4xx:
       
  1971     case POWERPC_MMU_SOFT_4xx_Z:
       
  1972         ppc4xx_tlb_invalidate_virt(env, addr, env->spr[SPR_40x_PID]);
       
  1973         break;
       
  1974     case POWERPC_MMU_REAL:
       
  1975         cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
       
  1976         break;
       
  1977     case POWERPC_MMU_MPC8xx:
       
  1978         /* XXX: TODO */
       
  1979         cpu_abort(env, "MPC8xx MMU model is not implemented\n");
       
  1980         break;
       
  1981     case POWERPC_MMU_BOOKE:
       
  1982         /* XXX: TODO */
       
  1983         cpu_abort(env, "BookE MMU model is not implemented\n");
       
  1984         break;
       
  1985     case POWERPC_MMU_BOOKE_FSL:
       
  1986         /* XXX: TODO */
       
  1987         cpu_abort(env, "BookE FSL MMU model is not implemented\n");
       
  1988         break;
       
  1989     case POWERPC_MMU_32B:
       
  1990     case POWERPC_MMU_601:
       
  1991         /* tlbie invalidate TLBs for all segments */
       
  1992         addr &= ~((target_ulong)-1ULL << 28);
       
  1993         /* XXX: this case should be optimized,
       
  1994          * giving a mask to tlb_flush_page
       
  1995          */
       
  1996         tlb_flush_page(env, addr | (0x0 << 28));
       
  1997         tlb_flush_page(env, addr | (0x1 << 28));
       
  1998         tlb_flush_page(env, addr | (0x2 << 28));
       
  1999         tlb_flush_page(env, addr | (0x3 << 28));
       
  2000         tlb_flush_page(env, addr | (0x4 << 28));
       
  2001         tlb_flush_page(env, addr | (0x5 << 28));
       
  2002         tlb_flush_page(env, addr | (0x6 << 28));
       
  2003         tlb_flush_page(env, addr | (0x7 << 28));
       
  2004         tlb_flush_page(env, addr | (0x8 << 28));
       
  2005         tlb_flush_page(env, addr | (0x9 << 28));
       
  2006         tlb_flush_page(env, addr | (0xA << 28));
       
  2007         tlb_flush_page(env, addr | (0xB << 28));
       
  2008         tlb_flush_page(env, addr | (0xC << 28));
       
  2009         tlb_flush_page(env, addr | (0xD << 28));
       
  2010         tlb_flush_page(env, addr | (0xE << 28));
       
  2011         tlb_flush_page(env, addr | (0xF << 28));
       
  2012         break;
       
  2013 #if defined(TARGET_PPC64)
       
  2014     case POWERPC_MMU_620:
       
  2015     case POWERPC_MMU_64B:
       
  2016         /* tlbie invalidate TLBs for all segments */
       
  2017         /* XXX: given the fact that there are too many segments to invalidate,
       
  2018          *      and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
       
  2019          *      we just invalidate all TLBs
       
  2020          */
       
  2021         tlb_flush(env, 1);
       
  2022         break;
       
  2023 #endif /* defined(TARGET_PPC64) */
       
  2024     default:
       
  2025         /* XXX: TODO */
       
  2026         cpu_abort(env, "Unknown MMU model\n");
       
  2027         break;
       
  2028     }
       
  2029 #else
       
  2030     ppc_tlb_invalidate_all(env);
       
  2031 #endif
       
  2032 }
       
  2033 
       
  2034 /*****************************************************************************/
       
  2035 /* Special registers manipulation */
       
  2036 #if defined(TARGET_PPC64)
       
  2037 void ppc_store_asr (CPUPPCState *env, target_ulong value)
       
  2038 {
       
  2039     if (env->asr != value) {
       
  2040         env->asr = value;
       
  2041         tlb_flush(env, 1);
       
  2042     }
       
  2043 }
       
  2044 #endif
       
  2045 
       
  2046 void ppc_store_sdr1 (CPUPPCState *env, target_ulong value)
       
  2047 {
       
  2048 #if defined (DEBUG_MMU)
       
  2049     if (loglevel != 0) {
       
  2050         fprintf(logfile, "%s: " ADDRX "\n", __func__, value);
       
  2051     }
       
  2052 #endif
       
  2053     if (env->sdr1 != value) {
       
  2054         /* XXX: for PowerPC 64, should check that the HTABSIZE value
       
  2055          *      is <= 28
       
  2056          */
       
  2057         env->sdr1 = value;
       
  2058         tlb_flush(env, 1);
       
  2059     }
       
  2060 }
       
  2061 
       
  2062 void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value)
       
  2063 {
       
  2064 #if defined (DEBUG_MMU)
       
  2065     if (loglevel != 0) {
       
  2066         fprintf(logfile, "%s: reg=%d " ADDRX " " ADDRX "\n",
       
  2067                 __func__, srnum, value, env->sr[srnum]);
       
  2068     }
       
  2069 #endif
       
  2070     if (env->sr[srnum] != value) {
       
  2071         env->sr[srnum] = value;
       
  2072 #if !defined(FLUSH_ALL_TLBS) && 0
       
  2073         {
       
  2074             target_ulong page, end;
       
  2075             /* Invalidate 256 MB of virtual memory */
       
  2076             page = (16 << 20) * srnum;
       
  2077             end = page + (16 << 20);
       
  2078             for (; page != end; page += TARGET_PAGE_SIZE)
       
  2079                 tlb_flush_page(env, page);
       
  2080         }
       
  2081 #else
       
  2082         tlb_flush(env, 1);
       
  2083 #endif
       
  2084     }
       
  2085 }
       
  2086 #endif /* !defined (CONFIG_USER_ONLY) */
       
  2087 
       
  2088 /* GDBstub can read and write MSR... */
       
  2089 void ppc_store_msr (CPUPPCState *env, target_ulong value)
       
  2090 {
       
  2091     hreg_store_msr(env, value, 0);
       
  2092 }
       
  2093 
       
  2094 /*****************************************************************************/
       
  2095 /* Exception processing */
       
  2096 #if defined (CONFIG_USER_ONLY)
       
  2097 void do_interrupt (CPUState *env)
       
  2098 {
       
  2099     env->exception_index = POWERPC_EXCP_NONE;
       
  2100     env->error_code = 0;
       
  2101 }
       
  2102 
       
  2103 void ppc_hw_interrupt (CPUState *env)
       
  2104 {
       
  2105     env->exception_index = POWERPC_EXCP_NONE;
       
  2106     env->error_code = 0;
       
  2107 }
       
  2108 #else /* defined (CONFIG_USER_ONLY) */
       
  2109 static always_inline void dump_syscall (CPUState *env)
       
  2110 {
       
  2111     fprintf(logfile, "syscall r0=" REGX " r3=" REGX " r4=" REGX
       
  2112             " r5=" REGX " r6=" REGX " nip=" ADDRX "\n",
       
  2113             ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3), ppc_dump_gpr(env, 4),
       
  2114             ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6), env->nip);
       
  2115 }
       
  2116 
       
  2117 extern int semihosting_enabled;
       
  2118 
       
  2119 /* Note that this function should be greatly optimized
       
  2120  * when called with a constant excp, from ppc_hw_interrupt
       
  2121  */
       
  2122 static always_inline void powerpc_excp (CPUState *env,
       
  2123                                         int excp_model, int excp)
       
  2124 {
       
  2125     target_ulong msr, new_msr, vector;
       
  2126     int srr0, srr1, asrr0, asrr1;
       
  2127     int lpes0, lpes1, lev;
       
  2128 
       
  2129     if (0) {
       
  2130         /* XXX: find a suitable condition to enable the hypervisor mode */
       
  2131         lpes0 = (env->spr[SPR_LPCR] >> 1) & 1;
       
  2132         lpes1 = (env->spr[SPR_LPCR] >> 2) & 1;
       
  2133     } else {
       
  2134         /* Those values ensure we won't enter the hypervisor mode */
       
  2135         lpes0 = 0;
       
  2136         lpes1 = 1;
       
  2137     }
       
  2138 
       
  2139     if (loglevel & CPU_LOG_INT) {
       
  2140         fprintf(logfile, "Raise exception at " ADDRX " => %08x (%02x)\n",
       
  2141                 env->nip, excp, env->error_code);
       
  2142     }
       
  2143     msr = env->msr;
       
  2144     new_msr = msr;
       
  2145     srr0 = SPR_SRR0;
       
  2146     srr1 = SPR_SRR1;
       
  2147     asrr0 = -1;
       
  2148     asrr1 = -1;
       
  2149     msr &= ~((target_ulong)0x783F0000);
       
  2150     switch (excp) {
       
  2151     case POWERPC_EXCP_NONE:
       
  2152         /* Should never happen */
       
  2153         return;
       
  2154     case POWERPC_EXCP_CRITICAL:    /* Critical input                         */
       
  2155         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
       
  2156         switch (excp_model) {
       
  2157         case POWERPC_EXCP_40x:
       
  2158             srr0 = SPR_40x_SRR2;
       
  2159             srr1 = SPR_40x_SRR3;
       
  2160             break;
       
  2161         case POWERPC_EXCP_BOOKE:
       
  2162             srr0 = SPR_BOOKE_CSRR0;
       
  2163             srr1 = SPR_BOOKE_CSRR1;
       
  2164             break;
       
  2165         case POWERPC_EXCP_G2:
       
  2166             break;
       
  2167         default:
       
  2168             goto excp_invalid;
       
  2169         }
       
  2170         goto store_next;
       
  2171     case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */
       
  2172         if (msr_me == 0) {
       
  2173             /* Machine check exception is not enabled.
       
  2174              * Enter checkstop state.
       
  2175              */
       
  2176             if (loglevel != 0) {
       
  2177                 fprintf(logfile, "Machine check while not allowed. "
       
  2178                         "Entering checkstop state\n");
       
  2179             } else {
       
  2180                 fprintf(stderr, "Machine check while not allowed. "
       
  2181                         "Entering checkstop state\n");
       
  2182             }
       
  2183             env->halted = 1;
       
  2184             env->interrupt_request |= CPU_INTERRUPT_EXITTB;
       
  2185         }
       
  2186         new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2187         new_msr &= ~((target_ulong)1 << MSR_ME);
       
  2188         if (0) {
       
  2189             /* XXX: find a suitable condition to enable the hypervisor mode */
       
  2190             new_msr |= (target_ulong)MSR_HVB;
       
  2191         }
       
  2192         /* XXX: should also have something loaded in DAR / DSISR */
       
  2193         switch (excp_model) {
       
  2194         case POWERPC_EXCP_40x:
       
  2195             srr0 = SPR_40x_SRR2;
       
  2196             srr1 = SPR_40x_SRR3;
       
  2197             break;
       
  2198         case POWERPC_EXCP_BOOKE:
       
  2199             srr0 = SPR_BOOKE_MCSRR0;
       
  2200             srr1 = SPR_BOOKE_MCSRR1;
       
  2201             asrr0 = SPR_BOOKE_CSRR0;
       
  2202             asrr1 = SPR_BOOKE_CSRR1;
       
  2203             break;
       
  2204         default:
       
  2205             break;
       
  2206         }
       
  2207         goto store_next;
       
  2208     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
       
  2209 #if defined (DEBUG_EXCEPTIONS)
       
  2210         if (loglevel != 0) {
       
  2211             fprintf(logfile, "DSI exception: DSISR=" ADDRX" DAR=" ADDRX "\n",
       
  2212                     env->spr[SPR_DSISR], env->spr[SPR_DAR]);
       
  2213         }
       
  2214 #endif
       
  2215         new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2216         if (lpes1 == 0)
       
  2217             new_msr |= (target_ulong)MSR_HVB;
       
  2218         goto store_next;
       
  2219     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
       
  2220 #if defined (DEBUG_EXCEPTIONS)
       
  2221         if (loglevel != 0) {
       
  2222             fprintf(logfile, "ISI exception: msr=" ADDRX ", nip=" ADDRX "\n",
       
  2223                     msr, env->nip);
       
  2224         }
       
  2225 #endif
       
  2226         new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2227         if (lpes1 == 0)
       
  2228             new_msr |= (target_ulong)MSR_HVB;
       
  2229         msr |= env->error_code;
       
  2230         goto store_next;
       
  2231     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
       
  2232         new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2233         if (lpes0 == 1)
       
  2234             new_msr |= (target_ulong)MSR_HVB;
       
  2235         goto store_next;
       
  2236     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
       
  2237         new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2238         if (lpes1 == 0)
       
  2239             new_msr |= (target_ulong)MSR_HVB;
       
  2240         /* XXX: this is false */
       
  2241         /* Get rS/rD and rA from faulting opcode */
       
  2242         env->spr[SPR_DSISR] |= (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
       
  2243         goto store_current;
       
  2244     case POWERPC_EXCP_PROGRAM:   /* Program exception                        */
       
  2245         switch (env->error_code & ~0xF) {
       
  2246         case POWERPC_EXCP_FP:
       
  2247             if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
       
  2248 #if defined (DEBUG_EXCEPTIONS)
       
  2249                 if (loglevel != 0) {
       
  2250                     fprintf(logfile, "Ignore floating point exception\n");
       
  2251                 }
       
  2252 #endif
       
  2253                 env->exception_index = POWERPC_EXCP_NONE;
       
  2254                 env->error_code = 0;
       
  2255                 return;
       
  2256             }
       
  2257             new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2258             if (lpes1 == 0)
       
  2259                 new_msr |= (target_ulong)MSR_HVB;
       
  2260             msr |= 0x00100000;
       
  2261             if (msr_fe0 == msr_fe1)
       
  2262                 goto store_next;
       
  2263             msr |= 0x00010000;
       
  2264             break;
       
  2265         case POWERPC_EXCP_INVAL:
       
  2266 #if defined (DEBUG_EXCEPTIONS)
       
  2267             if (loglevel != 0) {
       
  2268                 fprintf(logfile, "Invalid instruction at " ADDRX "\n",
       
  2269                         env->nip);
       
  2270             }
       
  2271 #endif
       
  2272             new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2273             if (lpes1 == 0)
       
  2274                 new_msr |= (target_ulong)MSR_HVB;
       
  2275             msr |= 0x00080000;
       
  2276             break;
       
  2277         case POWERPC_EXCP_PRIV:
       
  2278             new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2279             if (lpes1 == 0)
       
  2280                 new_msr |= (target_ulong)MSR_HVB;
       
  2281             msr |= 0x00040000;
       
  2282             break;
       
  2283         case POWERPC_EXCP_TRAP:
       
  2284             new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2285             if (lpes1 == 0)
       
  2286                 new_msr |= (target_ulong)MSR_HVB;
       
  2287             msr |= 0x00020000;
       
  2288             break;
       
  2289         default:
       
  2290             /* Should never occur */
       
  2291             cpu_abort(env, "Invalid program exception %d. Aborting\n",
       
  2292                       env->error_code);
       
  2293             break;
       
  2294         }
       
  2295         goto store_current;
       
  2296     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
       
  2297         new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2298         if (lpes1 == 0)
       
  2299             new_msr |= (target_ulong)MSR_HVB;
       
  2300         goto store_current;
       
  2301     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
       
  2302         /* Semihosted syscall mode.  */
       
  2303         if (semihosting_enabled) {
       
  2304             do_ppc_semihosting(env);
       
  2305             env->exception_index = POWERPC_EXCP_NONE;
       
  2306             env->error_code = 0;
       
  2307             return;
       
  2308         }
       
  2309         /* NOTE: this is a temporary hack to support graphics OSI
       
  2310            calls from the MOL driver */
       
  2311         /* XXX: To be removed */
       
  2312         if (env->gpr[3] == 0x113724fa && env->gpr[4] == 0x77810f9b &&
       
  2313             env->osi_call) {
       
  2314             if (env->osi_call(env) != 0) {
       
  2315                 env->exception_index = POWERPC_EXCP_NONE;
       
  2316                 env->error_code = 0;
       
  2317                 return;
       
  2318             }
       
  2319         }
       
  2320         if (loglevel & CPU_LOG_INT) {
       
  2321             dump_syscall(env);
       
  2322         }
       
  2323         new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2324         lev = env->error_code;
       
  2325         if (lev == 1 || (lpes0 == 0 && lpes1 == 0))
       
  2326             new_msr |= (target_ulong)MSR_HVB;
       
  2327         goto store_next;
       
  2328     case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
       
  2329         new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2330         goto store_current;
       
  2331     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
       
  2332         new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2333         if (lpes1 == 0)
       
  2334             new_msr |= (target_ulong)MSR_HVB;
       
  2335         goto store_next;
       
  2336     case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
       
  2337         /* FIT on 4xx */
       
  2338 #if defined (DEBUG_EXCEPTIONS)
       
  2339         if (loglevel != 0)
       
  2340             fprintf(logfile, "FIT exception\n");
       
  2341 #endif
       
  2342         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
       
  2343         goto store_next;
       
  2344     case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */
       
  2345 #if defined (DEBUG_EXCEPTIONS)
       
  2346         if (loglevel != 0)
       
  2347             fprintf(logfile, "WDT exception\n");
       
  2348 #endif
       
  2349         switch (excp_model) {
       
  2350         case POWERPC_EXCP_BOOKE:
       
  2351             srr0 = SPR_BOOKE_CSRR0;
       
  2352             srr1 = SPR_BOOKE_CSRR1;
       
  2353             break;
       
  2354         default:
       
  2355             break;
       
  2356         }
       
  2357         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
       
  2358         goto store_next;
       
  2359     case POWERPC_EXCP_DTLB:      /* Data TLB error                           */
       
  2360         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
       
  2361         goto store_next;
       
  2362     case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */
       
  2363         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
       
  2364         goto store_next;
       
  2365     case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */
       
  2366         switch (excp_model) {
       
  2367         case POWERPC_EXCP_BOOKE:
       
  2368             srr0 = SPR_BOOKE_DSRR0;
       
  2369             srr1 = SPR_BOOKE_DSRR1;
       
  2370             asrr0 = SPR_BOOKE_CSRR0;
       
  2371             asrr1 = SPR_BOOKE_CSRR1;
       
  2372             break;
       
  2373         default:
       
  2374             break;
       
  2375         }
       
  2376         /* XXX: TODO */
       
  2377         cpu_abort(env, "Debug exception is not implemented yet !\n");
       
  2378         goto store_next;
       
  2379     case POWERPC_EXCP_SPEU:      /* SPE/embedded floating-point unavailable  */
       
  2380         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
       
  2381         goto store_current;
       
  2382     case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */
       
  2383         /* XXX: TODO */
       
  2384         cpu_abort(env, "Embedded floating point data exception "
       
  2385                   "is not implemented yet !\n");
       
  2386         goto store_next;
       
  2387     case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */
       
  2388         /* XXX: TODO */
       
  2389         cpu_abort(env, "Embedded floating point round exception "
       
  2390                   "is not implemented yet !\n");
       
  2391         goto store_next;
       
  2392     case POWERPC_EXCP_EPERFM:    /* Embedded performance monitor interrupt   */
       
  2393         new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2394         /* XXX: TODO */
       
  2395         cpu_abort(env,
       
  2396                   "Performance counter exception is not implemented yet !\n");
       
  2397         goto store_next;
       
  2398     case POWERPC_EXCP_DOORI:     /* Embedded doorbell interrupt              */
       
  2399         /* XXX: TODO */
       
  2400         cpu_abort(env,
       
  2401                   "Embedded doorbell interrupt is not implemented yet !\n");
       
  2402         goto store_next;
       
  2403     case POWERPC_EXCP_DOORCI:    /* Embedded doorbell critical interrupt     */
       
  2404         switch (excp_model) {
       
  2405         case POWERPC_EXCP_BOOKE:
       
  2406             srr0 = SPR_BOOKE_CSRR0;
       
  2407             srr1 = SPR_BOOKE_CSRR1;
       
  2408             break;
       
  2409         default:
       
  2410             break;
       
  2411         }
       
  2412         /* XXX: TODO */
       
  2413         cpu_abort(env, "Embedded doorbell critical interrupt "
       
  2414                   "is not implemented yet !\n");
       
  2415         goto store_next;
       
  2416     case POWERPC_EXCP_RESET:     /* System reset exception                   */
       
  2417         new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2418         if (0) {
       
  2419             /* XXX: find a suitable condition to enable the hypervisor mode */
       
  2420             new_msr |= (target_ulong)MSR_HVB;
       
  2421         }
       
  2422         goto store_next;
       
  2423     case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
       
  2424         new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2425         if (lpes1 == 0)
       
  2426             new_msr |= (target_ulong)MSR_HVB;
       
  2427         goto store_next;
       
  2428     case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
       
  2429         new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2430         if (lpes1 == 0)
       
  2431             new_msr |= (target_ulong)MSR_HVB;
       
  2432         goto store_next;
       
  2433     case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
       
  2434         srr0 = SPR_HSRR0;
       
  2435         srr1 = SPR_HSRR1;
       
  2436         new_msr |= (target_ulong)MSR_HVB;
       
  2437         goto store_next;
       
  2438     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
       
  2439         new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2440         if (lpes1 == 0)
       
  2441             new_msr |= (target_ulong)MSR_HVB;
       
  2442         goto store_next;
       
  2443     case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
       
  2444         srr0 = SPR_HSRR0;
       
  2445         srr1 = SPR_HSRR1;
       
  2446         new_msr |= (target_ulong)MSR_HVB;
       
  2447         goto store_next;
       
  2448     case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */
       
  2449         srr0 = SPR_HSRR0;
       
  2450         srr1 = SPR_HSRR1;
       
  2451         new_msr |= (target_ulong)MSR_HVB;
       
  2452         goto store_next;
       
  2453     case POWERPC_EXCP_HDSEG:     /* Hypervisor data segment exception        */
       
  2454         srr0 = SPR_HSRR0;
       
  2455         srr1 = SPR_HSRR1;
       
  2456         new_msr |= (target_ulong)MSR_HVB;
       
  2457         goto store_next;
       
  2458     case POWERPC_EXCP_HISEG:     /* Hypervisor instruction segment exception */
       
  2459         srr0 = SPR_HSRR0;
       
  2460         srr1 = SPR_HSRR1;
       
  2461         new_msr |= (target_ulong)MSR_HVB;
       
  2462         goto store_next;
       
  2463     case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
       
  2464         new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2465         if (lpes1 == 0)
       
  2466             new_msr |= (target_ulong)MSR_HVB;
       
  2467         goto store_current;
       
  2468     case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
       
  2469 #if defined (DEBUG_EXCEPTIONS)
       
  2470         if (loglevel != 0)
       
  2471             fprintf(logfile, "PIT exception\n");
       
  2472 #endif
       
  2473         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
       
  2474         goto store_next;
       
  2475     case POWERPC_EXCP_IO:        /* IO error exception                       */
       
  2476         /* XXX: TODO */
       
  2477         cpu_abort(env, "601 IO error exception is not implemented yet !\n");
       
  2478         goto store_next;
       
  2479     case POWERPC_EXCP_RUNM:      /* Run mode exception                       */
       
  2480         /* XXX: TODO */
       
  2481         cpu_abort(env, "601 run mode exception is not implemented yet !\n");
       
  2482         goto store_next;
       
  2483     case POWERPC_EXCP_EMUL:      /* Emulation trap exception                 */
       
  2484         /* XXX: TODO */
       
  2485         cpu_abort(env, "602 emulation trap exception "
       
  2486                   "is not implemented yet !\n");
       
  2487         goto store_next;
       
  2488     case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
       
  2489         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
       
  2490         if (lpes1 == 0) /* XXX: check this */
       
  2491             new_msr |= (target_ulong)MSR_HVB;
       
  2492         switch (excp_model) {
       
  2493         case POWERPC_EXCP_602:
       
  2494         case POWERPC_EXCP_603:
       
  2495         case POWERPC_EXCP_603E:
       
  2496         case POWERPC_EXCP_G2:
       
  2497             goto tlb_miss_tgpr;
       
  2498         case POWERPC_EXCP_7x5:
       
  2499             goto tlb_miss;
       
  2500         case POWERPC_EXCP_74xx:
       
  2501             goto tlb_miss_74xx;
       
  2502         default:
       
  2503             cpu_abort(env, "Invalid instruction TLB miss exception\n");
       
  2504             break;
       
  2505         }
       
  2506         break;
       
  2507     case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
       
  2508         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
       
  2509         if (lpes1 == 0) /* XXX: check this */
       
  2510             new_msr |= (target_ulong)MSR_HVB;
       
  2511         switch (excp_model) {
       
  2512         case POWERPC_EXCP_602:
       
  2513         case POWERPC_EXCP_603:
       
  2514         case POWERPC_EXCP_603E:
       
  2515         case POWERPC_EXCP_G2:
       
  2516             goto tlb_miss_tgpr;
       
  2517         case POWERPC_EXCP_7x5:
       
  2518             goto tlb_miss;
       
  2519         case POWERPC_EXCP_74xx:
       
  2520             goto tlb_miss_74xx;
       
  2521         default:
       
  2522             cpu_abort(env, "Invalid data load TLB miss exception\n");
       
  2523             break;
       
  2524         }
       
  2525         break;
       
  2526     case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
       
  2527         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
       
  2528         if (lpes1 == 0) /* XXX: check this */
       
  2529             new_msr |= (target_ulong)MSR_HVB;
       
  2530         switch (excp_model) {
       
  2531         case POWERPC_EXCP_602:
       
  2532         case POWERPC_EXCP_603:
       
  2533         case POWERPC_EXCP_603E:
       
  2534         case POWERPC_EXCP_G2:
       
  2535         tlb_miss_tgpr:
       
  2536             /* Swap temporary saved registers with GPRs */
       
  2537             if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
       
  2538                 new_msr |= (target_ulong)1 << MSR_TGPR;
       
  2539                 hreg_swap_gpr_tgpr(env);
       
  2540             }
       
  2541             goto tlb_miss;
       
  2542         case POWERPC_EXCP_7x5:
       
  2543         tlb_miss:
       
  2544 #if defined (DEBUG_SOFTWARE_TLB)
       
  2545             if (loglevel != 0) {
       
  2546                 const unsigned char *es;
       
  2547                 target_ulong *miss, *cmp;
       
  2548                 int en;
       
  2549                 if (excp == POWERPC_EXCP_IFTLB) {
       
  2550                     es = "I";
       
  2551                     en = 'I';
       
  2552                     miss = &env->spr[SPR_IMISS];
       
  2553                     cmp = &env->spr[SPR_ICMP];
       
  2554                 } else {
       
  2555                     if (excp == POWERPC_EXCP_DLTLB)
       
  2556                         es = "DL";
       
  2557                     else
       
  2558                         es = "DS";
       
  2559                     en = 'D';
       
  2560                     miss = &env->spr[SPR_DMISS];
       
  2561                     cmp = &env->spr[SPR_DCMP];
       
  2562                 }
       
  2563                 fprintf(logfile, "6xx %sTLB miss: %cM " ADDRX " %cC " ADDRX
       
  2564                         " H1 " ADDRX " H2 " ADDRX " %08x\n",
       
  2565                         es, en, *miss, en, *cmp,
       
  2566                         env->spr[SPR_HASH1], env->spr[SPR_HASH2],
       
  2567                         env->error_code);
       
  2568             }
       
  2569 #endif
       
  2570             msr |= env->crf[0] << 28;
       
  2571             msr |= env->error_code; /* key, D/I, S/L bits */
       
  2572             /* Set way using a LRU mechanism */
       
  2573             msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
       
  2574             break;
       
  2575         case POWERPC_EXCP_74xx:
       
  2576         tlb_miss_74xx:
       
  2577 #if defined (DEBUG_SOFTWARE_TLB)
       
  2578             if (loglevel != 0) {
       
  2579                 const unsigned char *es;
       
  2580                 target_ulong *miss, *cmp;
       
  2581                 int en;
       
  2582                 if (excp == POWERPC_EXCP_IFTLB) {
       
  2583                     es = "I";
       
  2584                     en = 'I';
       
  2585                     miss = &env->spr[SPR_TLBMISS];
       
  2586                     cmp = &env->spr[SPR_PTEHI];
       
  2587                 } else {
       
  2588                     if (excp == POWERPC_EXCP_DLTLB)
       
  2589                         es = "DL";
       
  2590                     else
       
  2591                         es = "DS";
       
  2592                     en = 'D';
       
  2593                     miss = &env->spr[SPR_TLBMISS];
       
  2594                     cmp = &env->spr[SPR_PTEHI];
       
  2595                 }
       
  2596                 fprintf(logfile, "74xx %sTLB miss: %cM " ADDRX " %cC " ADDRX
       
  2597                         " %08x\n",
       
  2598                         es, en, *miss, en, *cmp, env->error_code);
       
  2599             }
       
  2600 #endif
       
  2601             msr |= env->error_code; /* key bit */
       
  2602             break;
       
  2603         default:
       
  2604             cpu_abort(env, "Invalid data store TLB miss exception\n");
       
  2605             break;
       
  2606         }
       
  2607         goto store_next;
       
  2608     case POWERPC_EXCP_FPA:       /* Floating-point assist exception          */
       
  2609         /* XXX: TODO */
       
  2610         cpu_abort(env, "Floating point assist exception "
       
  2611                   "is not implemented yet !\n");
       
  2612         goto store_next;
       
  2613     case POWERPC_EXCP_DABR:      /* Data address breakpoint                  */
       
  2614         /* XXX: TODO */
       
  2615         cpu_abort(env, "DABR exception is not implemented yet !\n");
       
  2616         goto store_next;
       
  2617     case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
       
  2618         /* XXX: TODO */
       
  2619         cpu_abort(env, "IABR exception is not implemented yet !\n");
       
  2620         goto store_next;
       
  2621     case POWERPC_EXCP_SMI:       /* System management interrupt              */
       
  2622         /* XXX: TODO */
       
  2623         cpu_abort(env, "SMI exception is not implemented yet !\n");
       
  2624         goto store_next;
       
  2625     case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
       
  2626         /* XXX: TODO */
       
  2627         cpu_abort(env, "Thermal management exception "
       
  2628                   "is not implemented yet !\n");
       
  2629         goto store_next;
       
  2630     case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
       
  2631         new_msr &= ~((target_ulong)1 << MSR_RI);
       
  2632         if (lpes1 == 0)
       
  2633             new_msr |= (target_ulong)MSR_HVB;
       
  2634         /* XXX: TODO */
       
  2635         cpu_abort(env,
       
  2636                   "Performance counter exception is not implemented yet !\n");
       
  2637         goto store_next;
       
  2638     case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
       
  2639         /* XXX: TODO */
       
  2640         cpu_abort(env, "VPU assist exception is not implemented yet !\n");
       
  2641         goto store_next;
       
  2642     case POWERPC_EXCP_SOFTP:     /* Soft patch exception                     */
       
  2643         /* XXX: TODO */
       
  2644         cpu_abort(env,
       
  2645                   "970 soft-patch exception is not implemented yet !\n");
       
  2646         goto store_next;
       
  2647     case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */
       
  2648         /* XXX: TODO */
       
  2649         cpu_abort(env,
       
  2650                   "970 maintenance exception is not implemented yet !\n");
       
  2651         goto store_next;
       
  2652     case POWERPC_EXCP_MEXTBR:    /* Maskable external breakpoint             */
       
  2653         /* XXX: TODO */
       
  2654         cpu_abort(env, "Maskable external exception "
       
  2655                   "is not implemented yet !\n");
       
  2656         goto store_next;
       
  2657     case POWERPC_EXCP_NMEXTBR:   /* Non maskable external breakpoint         */
       
  2658         /* XXX: TODO */
       
  2659         cpu_abort(env, "Non maskable external exception "
       
  2660                   "is not implemented yet !\n");
       
  2661         goto store_next;
       
  2662     default:
       
  2663     excp_invalid:
       
  2664         cpu_abort(env, "Invalid PowerPC exception %d. Aborting\n", excp);
       
  2665         break;
       
  2666     store_current:
       
  2667         /* save current instruction location */
       
  2668         env->spr[srr0] = env->nip - 4;
       
  2669         break;
       
  2670     store_next:
       
  2671         /* save next instruction location */
       
  2672         env->spr[srr0] = env->nip;
       
  2673         break;
       
  2674     }
       
  2675     /* Save MSR */
       
  2676     env->spr[srr1] = msr;
       
  2677     /* If any alternate SRR register are defined, duplicate saved values */
       
  2678     if (asrr0 != -1)
       
  2679         env->spr[asrr0] = env->spr[srr0];
       
  2680     if (asrr1 != -1)
       
  2681         env->spr[asrr1] = env->spr[srr1];
       
  2682     /* If we disactivated any translation, flush TLBs */
       
  2683     if (new_msr & ((1 << MSR_IR) | (1 << MSR_DR)))
       
  2684         tlb_flush(env, 1);
       
  2685     /* reload MSR with correct bits */
       
  2686     new_msr &= ~((target_ulong)1 << MSR_EE);
       
  2687     new_msr &= ~((target_ulong)1 << MSR_PR);
       
  2688     new_msr &= ~((target_ulong)1 << MSR_FP);
       
  2689     new_msr &= ~((target_ulong)1 << MSR_FE0);
       
  2690     new_msr &= ~((target_ulong)1 << MSR_SE);
       
  2691     new_msr &= ~((target_ulong)1 << MSR_BE);
       
  2692     new_msr &= ~((target_ulong)1 << MSR_FE1);
       
  2693     new_msr &= ~((target_ulong)1 << MSR_IR);
       
  2694     new_msr &= ~((target_ulong)1 << MSR_DR);
       
  2695 #if 0 /* Fix this: not on all targets */
       
  2696     new_msr &= ~((target_ulong)1 << MSR_PMM);
       
  2697 #endif
       
  2698     new_msr &= ~((target_ulong)1 << MSR_LE);
       
  2699     if (msr_ile)
       
  2700         new_msr |= (target_ulong)1 << MSR_LE;
       
  2701     else
       
  2702         new_msr &= ~((target_ulong)1 << MSR_LE);
       
  2703     /* Jump to handler */
       
  2704     vector = env->excp_vectors[excp];
       
  2705     if (vector == (target_ulong)-1ULL) {
       
  2706         cpu_abort(env, "Raised an exception without defined vector %d\n",
       
  2707                   excp);
       
  2708     }
       
  2709     vector |= env->excp_prefix;
       
  2710 #if defined(TARGET_PPC64)
       
  2711     if (excp_model == POWERPC_EXCP_BOOKE) {
       
  2712         if (!msr_icm) {
       
  2713             new_msr &= ~((target_ulong)1 << MSR_CM);
       
  2714             vector = (uint32_t)vector;
       
  2715         } else {
       
  2716             new_msr |= (target_ulong)1 << MSR_CM;
       
  2717         }
       
  2718     } else {
       
  2719         if (!msr_isf) {
       
  2720             new_msr &= ~((target_ulong)1 << MSR_SF);
       
  2721             vector = (uint32_t)vector;
       
  2722         } else {
       
  2723             new_msr |= (target_ulong)1 << MSR_SF;
       
  2724         }
       
  2725     }
       
  2726 #endif
       
  2727     /* XXX: we don't use hreg_store_msr here as already have treated
       
  2728      *      any special case that could occur. Just store MSR and update hflags
       
  2729      */
       
  2730     env->msr = new_msr & env->msr_mask;
       
  2731     hreg_compute_hflags(env);
       
  2732     env->nip = vector;
       
  2733     /* Reset exception state */
       
  2734     env->exception_index = POWERPC_EXCP_NONE;
       
  2735     env->error_code = 0;
       
  2736 }
       
  2737 
       
  2738 void do_interrupt (CPUState *env)
       
  2739 {
       
  2740     powerpc_excp(env, env->excp_model, env->exception_index);
       
  2741 }
       
  2742 
       
  2743 void ppc_hw_interrupt (CPUPPCState *env)
       
  2744 {
       
  2745     int hdice;
       
  2746 
       
  2747 #if 0
       
  2748     if (loglevel & CPU_LOG_INT) {
       
  2749         fprintf(logfile, "%s: %p pending %08x req %08x me %d ee %d\n",
       
  2750                 __func__, env, env->pending_interrupts,
       
  2751                 env->interrupt_request, (int)msr_me, (int)msr_ee);
       
  2752     }
       
  2753 #endif
       
  2754     /* External reset */
       
  2755     if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
       
  2756         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
       
  2757         powerpc_excp(env, env->excp_model, POWERPC_EXCP_RESET);
       
  2758         return;
       
  2759     }
       
  2760     /* Machine check exception */
       
  2761     if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
       
  2762         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
       
  2763         powerpc_excp(env, env->excp_model, POWERPC_EXCP_MCHECK);
       
  2764         return;
       
  2765     }
       
  2766 #if 0 /* TODO */
       
  2767     /* External debug exception */
       
  2768     if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
       
  2769         env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
       
  2770         powerpc_excp(env, env->excp_model, POWERPC_EXCP_DEBUG);
       
  2771         return;
       
  2772     }
       
  2773 #endif
       
  2774     if (0) {
       
  2775         /* XXX: find a suitable condition to enable the hypervisor mode */
       
  2776         hdice = env->spr[SPR_LPCR] & 1;
       
  2777     } else {
       
  2778         hdice = 0;
       
  2779     }
       
  2780     if ((msr_ee != 0 || msr_hv == 0 || msr_pr != 0) && hdice != 0) {
       
  2781         /* Hypervisor decrementer exception */
       
  2782         if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
       
  2783             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
       
  2784             powerpc_excp(env, env->excp_model, POWERPC_EXCP_HDECR);
       
  2785             return;
       
  2786         }
       
  2787     }
       
  2788     if (msr_ce != 0) {
       
  2789         /* External critical interrupt */
       
  2790         if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
       
  2791             /* Taking a critical external interrupt does not clear the external
       
  2792              * critical interrupt status
       
  2793              */
       
  2794 #if 0
       
  2795             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CEXT);
       
  2796 #endif
       
  2797             powerpc_excp(env, env->excp_model, POWERPC_EXCP_CRITICAL);
       
  2798             return;
       
  2799         }
       
  2800     }
       
  2801     if (msr_ee != 0) {
       
  2802         /* Watchdog timer on embedded PowerPC */
       
  2803         if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
       
  2804             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
       
  2805             powerpc_excp(env, env->excp_model, POWERPC_EXCP_WDT);
       
  2806             return;
       
  2807         }
       
  2808         if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
       
  2809             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
       
  2810             powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORCI);
       
  2811             return;
       
  2812         }
       
  2813         /* Fixed interval timer on embedded PowerPC */
       
  2814         if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
       
  2815             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
       
  2816             powerpc_excp(env, env->excp_model, POWERPC_EXCP_FIT);
       
  2817             return;
       
  2818         }
       
  2819         /* Programmable interval timer on embedded PowerPC */
       
  2820         if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
       
  2821             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
       
  2822             powerpc_excp(env, env->excp_model, POWERPC_EXCP_PIT);
       
  2823             return;
       
  2824         }
       
  2825         /* Decrementer exception */
       
  2826         if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
       
  2827             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
       
  2828             powerpc_excp(env, env->excp_model, POWERPC_EXCP_DECR);
       
  2829             return;
       
  2830         }
       
  2831         /* External interrupt */
       
  2832         if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
       
  2833             /* Taking an external interrupt does not clear the external
       
  2834              * interrupt status
       
  2835              */
       
  2836 #if 0
       
  2837             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
       
  2838 #endif
       
  2839             powerpc_excp(env, env->excp_model, POWERPC_EXCP_EXTERNAL);
       
  2840             return;
       
  2841         }
       
  2842         if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
       
  2843             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
       
  2844             powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORI);
       
  2845             return;
       
  2846         }
       
  2847         if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
       
  2848             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
       
  2849             powerpc_excp(env, env->excp_model, POWERPC_EXCP_PERFM);
       
  2850             return;
       
  2851         }
       
  2852         /* Thermal interrupt */
       
  2853         if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
       
  2854             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
       
  2855             powerpc_excp(env, env->excp_model, POWERPC_EXCP_THERM);
       
  2856             return;
       
  2857         }
       
  2858     }
       
  2859 }
       
  2860 #endif /* !CONFIG_USER_ONLY */
       
  2861 
       
  2862 void cpu_dump_rfi (target_ulong RA, target_ulong msr)
       
  2863 {
       
  2864     FILE *f;
       
  2865 
       
  2866     if (logfile) {
       
  2867         f = logfile;
       
  2868     } else {
       
  2869         f = stdout;
       
  2870         return;
       
  2871     }
       
  2872     fprintf(f, "Return from exception at " ADDRX " with flags " ADDRX "\n",
       
  2873             RA, msr);
       
  2874 }
       
  2875 
       
  2876 void cpu_ppc_reset (void *opaque)
       
  2877 {
       
  2878     CPUPPCState *env;
       
  2879     target_ulong msr;
       
  2880 
       
  2881     env = opaque;
       
  2882     msr = (target_ulong)0;
       
  2883     if (0) {
       
  2884         /* XXX: find a suitable condition to enable the hypervisor mode */
       
  2885         msr |= (target_ulong)MSR_HVB;
       
  2886     }
       
  2887     msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
       
  2888     msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
       
  2889     msr |= (target_ulong)1 << MSR_EP;
       
  2890 #if defined (DO_SINGLE_STEP) && 0
       
  2891     /* Single step trace mode */
       
  2892     msr |= (target_ulong)1 << MSR_SE;
       
  2893     msr |= (target_ulong)1 << MSR_BE;
       
  2894 #endif
       
  2895 #if defined(CONFIG_USER_ONLY)
       
  2896     /* Initialize MSR with appropriate instruction capabilities.  */
       
  2897     if (env->msr_mask & ((target_ulong)1 << MSR_FP))
       
  2898         msr |= (target_ulong)1 << MSR_FP;
       
  2899     if (env->msr_mask & ((target_ulong)1 << MSR_VR))
       
  2900         msr |= (target_ulong)1 << MSR_VR;
       
  2901     if (env->msr_mask & ((target_ulong)1 << MSR_SPE))
       
  2902         msr |= (target_ulong)1 << MSR_SPE;
       
  2903     msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
       
  2904     msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
       
  2905     msr |= (target_ulong)1 << MSR_PR;
       
  2906     env->msr = msr & env->msr_mask;
       
  2907 #else
       
  2908     env->nip = env->hreset_vector | env->excp_prefix;
       
  2909     if (env->mmu_model != POWERPC_MMU_REAL)
       
  2910         ppc_tlb_invalidate_all(env);
       
  2911 #endif
       
  2912     hreg_compute_hflags(env);
       
  2913     env->reserve = (target_ulong)-1ULL;
       
  2914     /* Be sure no exception or interrupt is pending */
       
  2915     env->pending_interrupts = 0;
       
  2916     env->exception_index = POWERPC_EXCP_NONE;
       
  2917     env->error_code = 0;
       
  2918     /* Flush all TLBs */
       
  2919     tlb_flush(env, 1);
       
  2920 }
       
  2921 
       
  2922 CPUPPCState *cpu_ppc_init (const char *cpu_model)
       
  2923 {
       
  2924     CPUPPCState *env;
       
  2925     const ppc_def_t *def;
       
  2926 
       
  2927     def = cpu_ppc_find_by_name(cpu_model);
       
  2928     if (!def)
       
  2929         return NULL;
       
  2930 
       
  2931     env = qemu_mallocz(sizeof(CPUPPCState));
       
  2932     if (!env)
       
  2933         return NULL;
       
  2934     cpu_exec_init(env);
       
  2935     ppc_translate_init();
       
  2936     env->cpu_model_str = cpu_model;
       
  2937     cpu_ppc_register_internal(env, def);
       
  2938     cpu_ppc_reset(env);
       
  2939 
       
  2940     if (kvm_enabled())
       
  2941         kvm_init_vcpu(env);
       
  2942 
       
  2943     return env;
       
  2944 }
       
  2945 
       
  2946 void cpu_ppc_close (CPUPPCState *env)
       
  2947 {
       
  2948     /* Should also remove all opcode tables... */
       
  2949     qemu_free(env);
       
  2950 }