Full implementation of PowerPC 64 MMU, just missing support for 1 TB
memory segments. Remove the PowerPC 64 "bridge" MMU model and implement segment registers emulation using SLB entries instead. Make SLB area size implementation dependant. Improve TLB & SLB search debug traces. Temporary hack to make PowerPC 970 boot from ROM instead of RAM. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3335 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									5bfb56b264
								
							
						
					
					
						commit
						12de9a396a
					
				| @ -105,10 +105,8 @@ enum { | ||||
|     /* BookE FSL MMU model                                     */ | ||||
|     POWERPC_MMU_BOOKE_FSL, | ||||
| #if defined(TARGET_PPC64) | ||||
|     /* Standard 64 bits PowerPC MMU                            */ | ||||
|     /* 64 bits PowerPC MMU                                     */ | ||||
|     POWERPC_MMU_64B, | ||||
|     /* 64 bits "bridge" PowerPC MMU                            */ | ||||
|     POWERPC_MMU_64BRIDGE, | ||||
| #endif /* defined(TARGET_PPC64) */ | ||||
| }; | ||||
| 
 | ||||
| @ -514,6 +512,8 @@ struct CPUPPCState { | ||||
|     ppc_tlb_t *tlb;  /* TLB is optional. Allocate them only if needed        */ | ||||
|     /* 403 dedicated access protection registers */ | ||||
|     target_ulong pb[4]; | ||||
|     /* PowerPC 64 SLB area */ | ||||
|     int slb_nr; | ||||
| 
 | ||||
|     int dcache_line_size; | ||||
|     int icache_line_size; | ||||
| @ -606,10 +606,14 @@ void do_store_sdr1 (CPUPPCState *env, target_ulong value); | ||||
| #if defined(TARGET_PPC64) | ||||
| target_ulong ppc_load_asr (CPUPPCState *env); | ||||
| void ppc_store_asr (CPUPPCState *env, target_ulong value); | ||||
| #endif | ||||
| target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr); | ||||
| void ppc_store_slb (CPUPPCState *env, int slb_nr, target_ulong rs); | ||||
| #endif /* defined(TARGET_PPC64) */ | ||||
| #if 0 // Unused
 | ||||
| target_ulong do_load_sr (CPUPPCState *env, int srnum); | ||||
| void do_store_sr (CPUPPCState *env, int srnum, target_ulong value); | ||||
| #endif | ||||
| void do_store_sr (CPUPPCState *env, int srnum, target_ulong value); | ||||
| #endif /* !defined(CONFIG_USER_ONLY) */ | ||||
| target_ulong ppc_load_xer (CPUPPCState *env); | ||||
| void ppc_store_xer (CPUPPCState *env, target_ulong value); | ||||
| target_ulong do_load_msr (CPUPPCState *env); | ||||
|  | ||||
| @ -501,21 +501,31 @@ static inline int _find_pte (mmu_ctx_t *ctx, int is_64b, int h, int rw) | ||||
|             pte0 = ldq_phys(base + (i * 16)); | ||||
|             pte1 =  ldq_phys(base + (i * 16) + 8); | ||||
|             r = pte64_check(ctx, pte0, pte1, h, rw); | ||||
| #if defined (DEBUG_MMU) | ||||
|             if (loglevel != 0) { | ||||
|                 fprintf(logfile, "Load pte from 0x" ADDRX " => 0x" ADDRX | ||||
|                         " 0x" ADDRX " %d %d %d 0x" ADDRX "\n", | ||||
|                         base + (i * 16), pte0, pte1, | ||||
|                         (int)(pte0 & 1), h, (int)((pte0 >> 1) & 1), | ||||
|                         ctx->ptem); | ||||
|             } | ||||
| #endif | ||||
|         } else | ||||
| #endif | ||||
|         { | ||||
|             pte0 = ldl_phys(base + (i * 8)); | ||||
|             pte1 =  ldl_phys(base + (i * 8) + 4); | ||||
|             r = pte32_check(ctx, pte0, pte1, h, rw); | ||||
|         } | ||||
| #if defined (DEBUG_MMU) | ||||
|         if (loglevel != 0) { | ||||
|             fprintf(logfile, "Load pte from 0x" ADDRX " => 0x" ADDRX | ||||
|                     " 0x" ADDRX " %d %d %d 0x" ADDRX "\n", | ||||
|                     base + (i * 8), pte0, pte1, | ||||
|                     (int)(pte0 >> 31), h, (int)((pte0 >> 6) & 1), ctx->ptem); | ||||
|         } | ||||
|             if (loglevel != 0) { | ||||
|                 fprintf(logfile, "Load pte from 0x" ADDRX " => 0x" ADDRX | ||||
|                         " 0x" ADDRX " %d %d %d 0x" ADDRX "\n", | ||||
|                         base + (i * 8), pte0, pte1, | ||||
|                         (int)(pte0 >> 31), h, (int)((pte0 >> 6) & 1), | ||||
|                         ctx->ptem); | ||||
|             } | ||||
| #endif | ||||
|         } | ||||
|         switch (r) { | ||||
|         case -3: | ||||
|             /* PTE inconsistency */ | ||||
| @ -581,24 +591,15 @@ static int find_pte64 (mmu_ctx_t *ctx, int h, int rw) | ||||
| static inline int find_pte (CPUState *env, mmu_ctx_t *ctx, int h, int rw) | ||||
| { | ||||
| #if defined(TARGET_PPC64) | ||||
|     if (env->mmu_model == POWERPC_MMU_64B || | ||||
|         env->mmu_model == POWERPC_MMU_64BRIDGE) | ||||
|     if (env->mmu_model == POWERPC_MMU_64B) | ||||
|         return find_pte64(ctx, h, rw); | ||||
| #endif | ||||
| 
 | ||||
|     return find_pte32(ctx, h, rw); | ||||
| } | ||||
| 
 | ||||
| static inline target_phys_addr_t get_pgaddr (target_phys_addr_t sdr1, | ||||
|                                              int sdr_sh, | ||||
|                                              target_phys_addr_t hash, | ||||
|                                              target_phys_addr_t mask) | ||||
| { | ||||
|     return (sdr1 & ((target_ulong)(-1ULL) << sdr_sh)) | (hash & mask); | ||||
| } | ||||
| 
 | ||||
| #if defined(TARGET_PPC64) | ||||
| static int slb_lookup (CPUState *env, target_ulong eaddr, | ||||
| static int slb_lookup (CPUPPCState *env, target_ulong eaddr, | ||||
|                        target_ulong *vsid, target_ulong *page_mask, int *attr) | ||||
| { | ||||
|     target_phys_addr_t sr_base; | ||||
| @ -610,14 +611,23 @@ static int slb_lookup (CPUState *env, target_ulong eaddr, | ||||
| 
 | ||||
|     ret = -5; | ||||
|     sr_base = env->spr[SPR_ASR]; | ||||
|     mask = 0x0000000000000000ULL; /* Avoid gcc warning */ | ||||
| #if 0 /* XXX: Fix this */
 | ||||
|     slb_nr = env->slb_nr; | ||||
| #else | ||||
|     slb_nr = 32; | ||||
| #if defined(DEBUG_SLB) | ||||
|     if (loglevel != 0) { | ||||
|         fprintf(logfile, "%s: eaddr " ADDRX " base " PADDRX "\n", | ||||
|                 __func__, eaddr, sr_base); | ||||
|     } | ||||
| #endif | ||||
|     mask = 0x0000000000000000ULL; /* Avoid gcc warning */ | ||||
|     slb_nr = env->slb_nr; | ||||
|     for (n = 0; n < slb_nr; n++) { | ||||
|         tmp64 = ldq_phys(sr_base); | ||||
|         tmp = ldl_phys(sr_base + 8); | ||||
| #if defined(DEBUG_SLB) | ||||
|         if (loglevel != 0) { | ||||
|         fprintf(logfile, "%s: seg %d " PADDRX " %016" PRIx64 " %08" PRIx32 "\n", | ||||
|                 __func__, n, sr_base, tmp64, tmp); | ||||
|         } | ||||
| #endif | ||||
|         if (tmp64 & 0x0000000008000000ULL) { | ||||
|             /* SLB entry is valid */ | ||||
|             switch (tmp64 & 0x0000000006000000ULL) { | ||||
| @ -636,7 +646,6 @@ static int slb_lookup (CPUState *env, target_ulong eaddr, | ||||
|             } | ||||
|             if ((eaddr & mask) == (tmp64 & mask)) { | ||||
|                 /* SLB match */ | ||||
|                 tmp = ldl_phys(sr_base + 8); | ||||
|                 *vsid = ((tmp64 << 24) | (tmp >> 8)) & 0x0003FFFFFFFFFFFFULL; | ||||
|                 *page_mask = ~mask; | ||||
|                 *attr = tmp & 0xFF; | ||||
| @ -649,13 +658,80 @@ static int slb_lookup (CPUState *env, target_ulong eaddr, | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr) | ||||
| { | ||||
|     target_phys_addr_t sr_base; | ||||
|     target_ulong rt; | ||||
|     uint64_t tmp64; | ||||
|     uint32_t tmp; | ||||
| 
 | ||||
|     sr_base = env->spr[SPR_ASR]; | ||||
|     sr_base += 12 * slb_nr; | ||||
|     tmp64 = ldq_phys(sr_base); | ||||
|     tmp = ldl_phys(sr_base + 8); | ||||
|     if (tmp64 & 0x0000000008000000ULL) { | ||||
|         /* SLB entry is valid */ | ||||
|         /* Copy SLB bits 62:88 to Rt 37:63 (VSID 23:49) */ | ||||
|         rt = tmp >> 8;             /* 65:88 => 40:63 */ | ||||
|         rt |= (tmp64 & 0x7) << 24; /* 62:64 => 37:39 */ | ||||
|         /* Copy SLB bits 89:92 to Rt 33:36 (KsKpNL) */ | ||||
|         rt |= ((tmp >> 4) & 0xF) << 27; | ||||
|     } else { | ||||
|         rt = 0; | ||||
|     } | ||||
| #if defined(DEBUG_SLB) | ||||
|     if (loglevel != 0) { | ||||
|         fprintf(logfile, "%s: " PADDRX " %016" PRIx64 " %08" PRIx32 " => %d " | ||||
|                 ADDRX "\n", __func__, sr_base, tmp64, tmp, slb_nr, rt); | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     return rt; | ||||
| } | ||||
| 
 | ||||
| void ppc_store_slb (CPUPPCState *env, int slb_nr, target_ulong rs) | ||||
| { | ||||
|     target_phys_addr_t sr_base; | ||||
|     uint64_t tmp64; | ||||
|     uint32_t tmp; | ||||
| 
 | ||||
|     sr_base = env->spr[SPR_ASR]; | ||||
|     sr_base += 12 * slb_nr; | ||||
|     /* Copy Rs bits 37:63 to SLB 62:88 */ | ||||
|     tmp = rs << 8; | ||||
|     tmp64 = (rs >> 24) & 0x7; | ||||
|     /* Copy Rs bits 33:36 to SLB 89:92 */ | ||||
|     tmp |= ((rs >> 27) & 0xF) << 4; | ||||
|     /* Set the valid bit */ | ||||
|     tmp64 |= 1 << 27; | ||||
|     /* Set ESID */ | ||||
|     tmp64 |= (uint32_t)slb_nr << 28; | ||||
| #if defined(DEBUG_SLB) | ||||
|     if (loglevel != 0) { | ||||
|         fprintf(logfile, "%s: %d " ADDRX " => " PADDRX " %016" PRIx64 " %08" | ||||
|                 PRIx32 "\n", __func__, slb_nr, rs, sr_base, tmp64, tmp); | ||||
|     } | ||||
| #endif | ||||
|     /* Write SLB entry to memory */ | ||||
|     stq_phys(sr_base, tmp64); | ||||
|     stl_phys(sr_base + 8, tmp); | ||||
| } | ||||
| #endif /* defined(TARGET_PPC64) */ | ||||
| 
 | ||||
| /* Perform segment based translation */ | ||||
| static inline target_phys_addr_t get_pgaddr (target_phys_addr_t sdr1, | ||||
|                                              int sdr_sh, | ||||
|                                              target_phys_addr_t hash, | ||||
|                                              target_phys_addr_t mask) | ||||
| { | ||||
|     return (sdr1 & ((target_ulong)(-1ULL) << sdr_sh)) | (hash & mask); | ||||
| } | ||||
| 
 | ||||
| static int get_segment (CPUState *env, mmu_ctx_t *ctx, | ||||
|                         target_ulong eaddr, int rw, int type) | ||||
| { | ||||
|     target_phys_addr_t sdr, hash, mask, sdr_mask; | ||||
|     target_phys_addr_t sdr, hash, mask, sdr_mask, htab_mask; | ||||
|     target_ulong sr, vsid, vsid_mask, pgidx, page_mask; | ||||
| #if defined(TARGET_PPC64) | ||||
|     int attr; | ||||
| @ -664,8 +740,12 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx, | ||||
|     int ret, ret2; | ||||
| 
 | ||||
| #if defined(TARGET_PPC64) | ||||
|     if (env->mmu_model == POWERPC_MMU_64B || | ||||
|         env->mmu_model == POWERPC_MMU_64BRIDGE) { | ||||
|     if (env->mmu_model == POWERPC_MMU_64B) { | ||||
| #if defined (DEBUG_MMU) | ||||
|         if (loglevel != 0) { | ||||
|             fprintf(logfile, "Check SLBs\n"); | ||||
|         } | ||||
| #endif | ||||
|         ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr); | ||||
|         if (ret < 0) | ||||
|             return ret; | ||||
| @ -699,29 +779,53 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx, | ||||
|                     eaddr, (int)(eaddr >> 28), sr, env->nip, | ||||
|                     env->lr, msr_ir, msr_dr, msr_pr, rw, type); | ||||
|         } | ||||
|         if (!ds && loglevel != 0) { | ||||
|             fprintf(logfile, "pte segment: key=%d n=0x" ADDRX "\n", | ||||
|                     ctx->key, sr & 0x10000000); | ||||
|         } | ||||
| #endif | ||||
|     } | ||||
| #if defined (DEBUG_MMU) | ||||
|     if (loglevel != 0) { | ||||
|         fprintf(logfile, "pte segment: key=%d ds %d nx %d vsid " ADDRX "\n", | ||||
|                 ctx->key, ds, nx, vsid); | ||||
|     } | ||||
| #endif | ||||
|     ret = -1; | ||||
|     if (!ds) { | ||||
|         /* Check if instruction fetch is allowed, if needed */ | ||||
|         if (type != ACCESS_CODE || nx == 0) { | ||||
|             /* Page address translation */ | ||||
|             pgidx = (eaddr & page_mask) >> TARGET_PAGE_BITS; | ||||
|             hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask; | ||||
|             /* Primary table address */ | ||||
|             sdr = env->sdr1; | ||||
|             mask = ((sdr & 0x000001FF) << sdr_sh) | sdr_mask; | ||||
|             pgidx = (eaddr & page_mask) >> TARGET_PAGE_BITS; | ||||
| #if defined(TARGET_PPC64) | ||||
|             if (env->mmu_model == POWERPC_MMU_64B) { | ||||
|                 htab_mask = 0x0FFFFFFF >> (28 - (sdr & 0x1F)); | ||||
|                 /* XXX: this is false for 1 TB segments */ | ||||
|                 hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask; | ||||
|             } else | ||||
| #endif | ||||
|             { | ||||
|                 htab_mask = sdr & 0x000001FF; | ||||
|                 hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask; | ||||
|             } | ||||
|             mask = (htab_mask << sdr_sh) | sdr_mask; | ||||
| #if defined (DEBUG_MMU) | ||||
|             if (loglevel != 0) { | ||||
|                 fprintf(logfile, "sdr " PADDRX " sh %d hash " PADDRX " mask " | ||||
|                         PADDRX " " ADDRX "\n", sdr, sdr_sh, hash, mask, | ||||
|                         page_mask); | ||||
|             } | ||||
| #endif | ||||
|             ctx->pg_addr[0] = get_pgaddr(sdr, sdr_sh, hash, mask); | ||||
|             /* Secondary table address */ | ||||
|             hash = (~hash) & vsid_mask; | ||||
| #if defined (DEBUG_MMU) | ||||
|             if (loglevel != 0) { | ||||
|                 fprintf(logfile, "sdr " PADDRX " sh %d hash " PADDRX " mask " | ||||
|                         PADDRX "\n", sdr, sdr_sh, hash, mask); | ||||
|             } | ||||
| #endif | ||||
|             ctx->pg_addr[1] = get_pgaddr(sdr, sdr_sh, hash, mask); | ||||
| #if defined(TARGET_PPC64) | ||||
|             if (env->mmu_model == POWERPC_MMU_64B || | ||||
|                 env->mmu_model == POWERPC_MMU_64BRIDGE) { | ||||
|             if (env->mmu_model == POWERPC_MMU_64B) { | ||||
|                 /* Only 5 bits of the page index are used in the AVPN */ | ||||
|                 ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80); | ||||
|             } else | ||||
| @ -762,6 +866,27 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx, | ||||
|                         ret = ret2; | ||||
|                 } | ||||
|             } | ||||
| #if defined (DEBUG_MMU) | ||||
|                     if (loglevel != 0) { | ||||
|                         target_phys_addr_t curaddr; | ||||
|                         uint32_t a0, a1, a2, a3; | ||||
|                         fprintf(logfile, | ||||
|                                 "Page table: " PADDRX " len " PADDRX "\n", | ||||
|                                 sdr, mask + 0x80); | ||||
|                         for (curaddr = sdr; curaddr < (sdr + mask + 0x80); | ||||
|                              curaddr += 16) { | ||||
|                             a0 = ldl_phys(curaddr); | ||||
|                             a1 = ldl_phys(curaddr + 4); | ||||
|                             a2 = ldl_phys(curaddr + 8); | ||||
|                             a3 = ldl_phys(curaddr + 12); | ||||
|                             if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) { | ||||
|                                 fprintf(logfile, | ||||
|                                         PADDRX ": %08x %08x %08x %08x\n", | ||||
|                                         curaddr, a0, a1, a2, a3); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
| #endif | ||||
|         } else { | ||||
| #if defined (DEBUG_MMU) | ||||
|             if (loglevel != 0) | ||||
| @ -1103,7 +1228,6 @@ static int check_physical (CPUState *env, mmu_ctx_t *ctx, | ||||
|         break; | ||||
| #if defined(TARGET_PPC64) | ||||
|     case POWERPC_MMU_64B: | ||||
|     case POWERPC_MMU_64BRIDGE: | ||||
|         /* Real address are 60 bits long */ | ||||
|         ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL; | ||||
|         ctx->prot |= PAGE_WRITE; | ||||
| @ -1170,7 +1294,6 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, | ||||
|             /* No break here */ | ||||
| #if defined(TARGET_PPC64) | ||||
|         case POWERPC_MMU_64B: | ||||
|         case POWERPC_MMU_64BRIDGE: | ||||
| #endif | ||||
|             if (ret < 0) { | ||||
|                 /* We didn't match any BAT entry or don't have BATs */ | ||||
| @ -1275,7 +1398,6 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | ||||
|                 case POWERPC_MMU_32B: | ||||
| #if defined(TARGET_PPC64) | ||||
|                 case POWERPC_MMU_64B: | ||||
|                 case POWERPC_MMU_64BRIDGE: | ||||
| #endif | ||||
|                     env->exception_index = POWERPC_EXCP_ISI; | ||||
|                     env->error_code = 0x40000000; | ||||
| @ -1371,7 +1493,6 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | ||||
|                 case POWERPC_MMU_32B: | ||||
| #if defined(TARGET_PPC64) | ||||
|                 case POWERPC_MMU_64B: | ||||
|                 case POWERPC_MMU_64BRIDGE: | ||||
| #endif | ||||
|                     env->exception_index = POWERPC_EXCP_DSI; | ||||
|                     env->error_code = 0; | ||||
| @ -1622,13 +1743,12 @@ void ppc_tlb_invalidate_all (CPUPPCState *env) | ||||
|     case POWERPC_MMU_32B: | ||||
| #if defined(TARGET_PPC64) | ||||
|     case POWERPC_MMU_64B: | ||||
|     case POWERPC_MMU_64BRIDGE: | ||||
| #endif /* defined(TARGET_PPC64) */ | ||||
|         tlb_flush(env, 1); | ||||
|         break; | ||||
|     default: | ||||
|         /* XXX: TODO */ | ||||
|         cpu_abort(env, "Unknown MMU model %d\n", env->mmu_model); | ||||
|         cpu_abort(env, "Unknown MMU model\n"); | ||||
|         break; | ||||
|     } | ||||
| } | ||||
| @ -1688,7 +1808,6 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr) | ||||
|         break; | ||||
| #if defined(TARGET_PPC64) | ||||
|     case POWERPC_MMU_64B: | ||||
|     case POWERPC_MMU_64BRIDGE: | ||||
|         /* tlbie invalidate TLBs for all segments */ | ||||
|         /* XXX: given the fact that there are too many segments to invalidate,
 | ||||
|          *      and we still don't have a tlb_flush_mask(env, n, mask) in Qemu, | ||||
| @ -1699,7 +1818,7 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr) | ||||
| #endif /* defined(TARGET_PPC64) */ | ||||
|     default: | ||||
|         /* XXX: TODO */ | ||||
|         cpu_abort(env, "Unknown MMU model 2\n"); | ||||
|         cpu_abort(env, "Unknown MMU model\n"); | ||||
|         break; | ||||
|     } | ||||
| #else | ||||
| @ -1752,15 +1871,20 @@ void do_store_sdr1 (CPUPPCState *env, target_ulong value) | ||||
|     } | ||||
| #endif | ||||
|     if (env->sdr1 != value) { | ||||
|         /* XXX: for PowerPC 64, should check that the HTABSIZE value
 | ||||
|          *      is <= 28 | ||||
|          */ | ||||
|         env->sdr1 = value; | ||||
|         tlb_flush(env, 1); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #if 0 // Unused
 | ||||
| target_ulong do_load_sr (CPUPPCState *env, int srnum) | ||||
| { | ||||
|     return env->sr[srnum]; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| void do_store_sr (CPUPPCState *env, int srnum, target_ulong value) | ||||
| { | ||||
|  | ||||
| @ -317,6 +317,20 @@ void OPPROTO op_store_sr (void) | ||||
|     RETURN(); | ||||
| } | ||||
| 
 | ||||
| #if defined(TARGET_PPC64) | ||||
| void OPPROTO op_load_slb (void) | ||||
| { | ||||
|     T0 = ppc_load_slb(env, T1); | ||||
|     RETURN(); | ||||
| } | ||||
| 
 | ||||
| void OPPROTO op_store_slb (void) | ||||
| { | ||||
|     ppc_store_slb(env, T1, T0); | ||||
|     RETURN(); | ||||
| } | ||||
| #endif /* defined(TARGET_PPC64) */ | ||||
| 
 | ||||
| void OPPROTO op_load_sdr1 (void) | ||||
| { | ||||
|     T0 = env->sdr1; | ||||
|  | ||||
| @ -385,107 +385,107 @@ static inline target_ulong MASK (uint32_t start, uint32_t end) | ||||
| /* PowerPC Instructions types definitions                                    */ | ||||
| enum { | ||||
|     PPC_NONE          = 0x0000000000000000ULL, | ||||
|     /* integer operations instructions                  */ | ||||
|     /* flow control instructions                        */ | ||||
|     /* virtual memory instructions                      */ | ||||
|     /* ld/st with reservation instructions              */ | ||||
|     /* cache control instructions                       */ | ||||
|     /* spr/msr access instructions                      */ | ||||
|     /* PowerPC base instructions set                                         */ | ||||
|     PPC_INSNS_BASE    = 0x0000000000000001ULL, | ||||
|     /* integer operations instructions                                       */ | ||||
| #define PPC_INTEGER PPC_INSNS_BASE | ||||
|     /* flow control instructions                                             */ | ||||
| #define PPC_FLOW    PPC_INSNS_BASE | ||||
|     /* virtual memory instructions                                           */ | ||||
| #define PPC_MEM     PPC_INSNS_BASE | ||||
|     /* ld/st with reservation instructions                                   */ | ||||
| #define PPC_RES     PPC_INSNS_BASE | ||||
|     /* cache control instructions                                            */ | ||||
| #define PPC_CACHE   PPC_INSNS_BASE | ||||
|     /* spr/msr access instructions                                           */ | ||||
| #define PPC_MISC    PPC_INSNS_BASE | ||||
|     /* Optional floating point instructions             */ | ||||
|     /* Optional floating point instructions                                  */ | ||||
|     PPC_FLOAT         = 0x0000000000000002ULL, | ||||
|     PPC_FLOAT_FSQRT   = 0x0000000000000004ULL, | ||||
|     PPC_FLOAT_FRES    = 0x0000000000000008ULL, | ||||
|     PPC_FLOAT_FRSQRTE = 0x0000000000000010ULL, | ||||
|     PPC_FLOAT_FSEL    = 0x0000000000000020ULL, | ||||
|     PPC_FLOAT_STFIWX  = 0x0000000000000040ULL, | ||||
|     /* external control instructions                    */ | ||||
|     /* external control instructions                                         */ | ||||
|     PPC_EXTERN        = 0x0000000000000080ULL, | ||||
|     /* segment register access instructions             */ | ||||
|     /* segment register access instructions                                  */ | ||||
|     PPC_SEGMENT       = 0x0000000000000100ULL, | ||||
|     /* Optional cache control instruction               */ | ||||
|     /* Optional cache control instruction                                    */ | ||||
|     PPC_CACHE_DCBA    = 0x0000000000000200ULL, | ||||
|     /* Optional memory control instructions             */ | ||||
|     /* Optional memory control instructions                                  */ | ||||
|     PPC_MEM_TLBIA     = 0x0000000000000400ULL, | ||||
|     PPC_MEM_TLBIE     = 0x0000000000000800ULL, | ||||
|     PPC_MEM_TLBSYNC   = 0x0000000000001000ULL, | ||||
|     /* eieio & sync                                     */ | ||||
|     /* eieio & sync                                                          */ | ||||
|     PPC_MEM_SYNC      = 0x0000000000002000ULL, | ||||
|     /* PowerPC 6xx TLB management instructions          */ | ||||
|     /* PowerPC 6xx TLB management instructions                               */ | ||||
|     PPC_6xx_TLB       = 0x0000000000004000ULL, | ||||
|     /* Altivec support                                  */ | ||||
|     /* Altivec support                                                       */ | ||||
|     PPC_ALTIVEC       = 0x0000000000008000ULL, | ||||
|     /* Time base mftb instruction                       */ | ||||
|     /* Time base mftb instruction                                            */ | ||||
|     PPC_MFTB          = 0x0000000000010000ULL, | ||||
|     /* Embedded PowerPC dedicated instructions          */ | ||||
|     /* Embedded PowerPC dedicated instructions                               */ | ||||
|     PPC_EMB_COMMON    = 0x0000000000020000ULL, | ||||
|     /* PowerPC 40x exception model                      */ | ||||
|     /* PowerPC 40x exception model                                           */ | ||||
|     PPC_40x_EXCP      = 0x0000000000040000ULL, | ||||
|     /* PowerPC 40x TLB management instructions          */ | ||||
|     /* PowerPC 40x TLB management instructions                               */ | ||||
|     PPC_40x_TLB       = 0x0000000000080000ULL, | ||||
|     /* PowerPC 405 Mac instructions                     */ | ||||
|     /* PowerPC 405 Mac instructions                                          */ | ||||
|     PPC_405_MAC       = 0x0000000000100000ULL, | ||||
|     /* PowerPC 440 specific instructions                */ | ||||
|     /* PowerPC 440 specific instructions                                     */ | ||||
|     PPC_440_SPEC      = 0x0000000000200000ULL, | ||||
|     /* Power-to-PowerPC bridge (601)                    */ | ||||
|     /* Power-to-PowerPC bridge (601)                                         */ | ||||
|     PPC_POWER_BR      = 0x0000000000400000ULL, | ||||
|     /* PowerPC 602 specific */ | ||||
|     /* PowerPC 602 specific                                                  */ | ||||
|     PPC_602_SPEC      = 0x0000000000800000ULL, | ||||
|     /* Deprecated instructions                          */ | ||||
|     /* Original POWER instruction set                   */ | ||||
|     /* Deprecated instructions                                               */ | ||||
|     /* Original POWER instruction set                                        */ | ||||
|     PPC_POWER         = 0x0000000001000000ULL, | ||||
|     /* POWER2 instruction set extension                 */ | ||||
|     /* POWER2 instruction set extension                                      */ | ||||
|     PPC_POWER2        = 0x0000000002000000ULL, | ||||
|     /* Power RTC support */ | ||||
|     /* Power RTC support                                                     */ | ||||
|     PPC_POWER_RTC     = 0x0000000004000000ULL, | ||||
|     /* 64 bits PowerPC instructions                     */ | ||||
|     /* 64 bits PowerPC instruction set                  */ | ||||
|     /* 64 bits PowerPC instruction set                                       */ | ||||
|     PPC_64B           = 0x0000000008000000ULL, | ||||
|     /* 64 bits hypervisor extensions                    */ | ||||
|     /* 64 bits hypervisor extensions                                         */ | ||||
|     PPC_64H           = 0x0000000010000000ULL, | ||||
|     /* 64 bits PowerPC "bridge" features                */ | ||||
|     PPC_64_BRIDGE     = 0x0000000020000000ULL, | ||||
|     /* BookE (embedded) PowerPC specification           */ | ||||
|     /* segment register access instructions for PowerPC 64 "bridge"          */ | ||||
|     PPC_SEGMENT_64B   = 0x0000000020000000ULL, | ||||
|     /* BookE (embedded) PowerPC specification                                */ | ||||
|     PPC_BOOKE         = 0x0000000040000000ULL, | ||||
|     /* eieio                                            */ | ||||
|     /* eieio                                                                 */ | ||||
|     PPC_MEM_EIEIO     = 0x0000000080000000ULL, | ||||
|     /* e500 vector instructions                         */ | ||||
|     /* e500 vector instructions                                              */ | ||||
|     PPC_E500_VECTOR   = 0x0000000100000000ULL, | ||||
|     /* PowerPC 4xx dedicated instructions               */ | ||||
|     /* PowerPC 4xx dedicated instructions                                    */ | ||||
|     PPC_4xx_COMMON    = 0x0000000200000000ULL, | ||||
|     /* PowerPC 2.03 specification extensions            */ | ||||
|     /* PowerPC 2.03 specification extensions                                 */ | ||||
|     PPC_203           = 0x0000000400000000ULL, | ||||
|     /* PowerPC 2.03 SPE extension                       */ | ||||
|     /* PowerPC 2.03 SPE extension                                            */ | ||||
|     PPC_SPE           = 0x0000000800000000ULL, | ||||
|     /* PowerPC 2.03 SPE floating-point extension        */ | ||||
|     /* PowerPC 2.03 SPE floating-point extension                             */ | ||||
|     PPC_SPEFPU        = 0x0000001000000000ULL, | ||||
|     /* SLB management                                   */ | ||||
|     /* SLB management                                                        */ | ||||
|     PPC_SLBI          = 0x0000002000000000ULL, | ||||
|     /* PowerPC 40x ibct instructions                    */ | ||||
|     /* PowerPC 40x ibct instructions                                         */ | ||||
|     PPC_40x_ICBT      = 0x0000004000000000ULL, | ||||
|     /* PowerPC 74xx TLB management instructions         */ | ||||
|     /* PowerPC 74xx TLB management instructions                              */ | ||||
|     PPC_74xx_TLB      = 0x0000008000000000ULL, | ||||
|     /* More BookE (embedded) instructions...            */ | ||||
|     /* More BookE (embedded) instructions...                                 */ | ||||
|     PPC_BOOKE_EXT     = 0x0000010000000000ULL, | ||||
|     /* rfmci is not implemented in all BookE PowerPC    */ | ||||
|     /* rfmci is not implemented in all BookE PowerPC                         */ | ||||
|     PPC_RFMCI         = 0x0000020000000000ULL, | ||||
|     /* user-mode DCR access, implemented in PowerPC 460 */ | ||||
|     /* user-mode DCR access, implemented in PowerPC 460                      */ | ||||
|     PPC_DCRUX         = 0x0000040000000000ULL, | ||||
|     /* New floating-point extensions (PowerPC 2.0x)     */ | ||||
|     /* New floating-point extensions (PowerPC 2.0x)                          */ | ||||
|     PPC_FLOAT_EXT     = 0x0000080000000000ULL, | ||||
|     /* New wait instruction (PowerPC 2.0x)              */ | ||||
|     /* New wait instruction (PowerPC 2.0x)                                   */ | ||||
|     PPC_WAIT          = 0x0000100000000000ULL, | ||||
|     /* New 64 bits extensions (PowerPC 2.0x)            */ | ||||
|     /* New 64 bits extensions (PowerPC 2.0x)                                 */ | ||||
|     PPC_64BX          = 0x0000200000000000ULL, | ||||
|     /* dcbz instruction with fixed cache line size      */ | ||||
|     /* dcbz instruction with fixed cache line size                           */ | ||||
|     PPC_CACHE_DCBZ    = 0x0000400000000000ULL, | ||||
|     /* dcbz instruction with tunable cache line size    */ | ||||
|     /* dcbz instruction with tunable cache line size                         */ | ||||
|     PPC_CACHE_DCBZT   = 0x0000800000000000ULL, | ||||
| }; | ||||
| 
 | ||||
| @ -3931,6 +3931,75 @@ GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT) | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| #if defined(TARGET_PPC64) | ||||
| /* Specific implementation for PowerPC 64 "bridge" emulation using SLB */ | ||||
| /* mfsr */ | ||||
| GEN_HANDLER(mfsr_64b, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B) | ||||
| { | ||||
| #if defined(CONFIG_USER_ONLY) | ||||
|     GEN_EXCP_PRIVREG(ctx); | ||||
| #else | ||||
|     if (unlikely(!ctx->supervisor)) { | ||||
|         GEN_EXCP_PRIVREG(ctx); | ||||
|         return; | ||||
|     } | ||||
|     gen_op_set_T1(SR(ctx->opcode)); | ||||
|     gen_op_load_slb(); | ||||
|     gen_op_store_T0_gpr(rD(ctx->opcode)); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /* mfsrin */ | ||||
| GEN_HANDLER(mfsrin_64b, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT_64B) | ||||
| { | ||||
| #if defined(CONFIG_USER_ONLY) | ||||
|     GEN_EXCP_PRIVREG(ctx); | ||||
| #else | ||||
|     if (unlikely(!ctx->supervisor)) { | ||||
|         GEN_EXCP_PRIVREG(ctx); | ||||
|         return; | ||||
|     } | ||||
|     gen_op_load_gpr_T1(rB(ctx->opcode)); | ||||
|     gen_op_srli_T1(28); | ||||
|     gen_op_load_slb(); | ||||
|     gen_op_store_T0_gpr(rD(ctx->opcode)); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /* mtsr */ | ||||
| GEN_HANDLER(mtsr_64b, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B) | ||||
| { | ||||
| #if defined(CONFIG_USER_ONLY) | ||||
|     GEN_EXCP_PRIVREG(ctx); | ||||
| #else | ||||
|     if (unlikely(!ctx->supervisor)) { | ||||
|         GEN_EXCP_PRIVREG(ctx); | ||||
|         return; | ||||
|     } | ||||
|     gen_op_load_gpr_T0(rS(ctx->opcode)); | ||||
|     gen_op_set_T1(SR(ctx->opcode)); | ||||
|     gen_op_store_slb(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /* mtsrin */ | ||||
| GEN_HANDLER(mtsrin_64b, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT_64B) | ||||
| { | ||||
| #if defined(CONFIG_USER_ONLY) | ||||
|     GEN_EXCP_PRIVREG(ctx); | ||||
| #else | ||||
|     if (unlikely(!ctx->supervisor)) { | ||||
|         GEN_EXCP_PRIVREG(ctx); | ||||
|         return; | ||||
|     } | ||||
|     gen_op_load_gpr_T0(rS(ctx->opcode)); | ||||
|     gen_op_load_gpr_T1(rB(ctx->opcode)); | ||||
|     gen_op_srli_T1(28); | ||||
|     gen_op_store_slb(); | ||||
| #endif | ||||
| } | ||||
| #endif /* defined(TARGET_PPC64) */ | ||||
| 
 | ||||
| /***                      Lookaside buffer management                      ***/ | ||||
| /* Optional & supervisor only: */ | ||||
| /* tlbia */ | ||||
|  | ||||
| @ -3095,12 +3095,13 @@ static void init_proc_e500 (CPUPPCState *env) | ||||
| /* Non-embedded PowerPC                                                      */ | ||||
| /* Base instructions set for all 6xx/7xx/74xx/970 PowerPC                    */ | ||||
| #define POWERPC_INSNS_6xx    (PPC_INSNS_BASE | PPC_FLOAT | PPC_MEM_SYNC |     \ | ||||
|                               PPC_MEM_EIEIO | PPC_SEGMENT | PPC_MEM_TLBIE) | ||||
|                               PPC_MEM_EIEIO | PPC_MEM_TLBIE) | ||||
| /* Instructions common to all 6xx/7xx/74xx/970 PowerPC except 601 & 602      */ | ||||
| #define POWERPC_INSNS_WORKS  (POWERPC_INSNS_6xx | PPC_FLOAT_FSQRT |           \ | ||||
|                               PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE |            \ | ||||
|                               PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX |             \ | ||||
|                               PPC_MEM_TLBSYNC | PPC_CACHE_DCBZ | PPC_MFTB) | ||||
|                               PPC_MEM_TLBSYNC | PPC_CACHE_DCBZ | PPC_MFTB |   \ | ||||
|                               PPC_SEGMENT) | ||||
| 
 | ||||
| /* POWER : same as 601, without mfmsr, mfsr                                  */ | ||||
| #if defined(TODO) | ||||
| @ -3111,7 +3112,7 @@ static void init_proc_e500 (CPUPPCState *env) | ||||
| 
 | ||||
| /* PowerPC 601                                                               */ | ||||
| #define POWERPC_INSNS_601    (POWERPC_INSNS_6xx | PPC_CACHE_DCBZ |            \ | ||||
|                               PPC_EXTERN | PPC_POWER_BR) | ||||
|                               PPC_SEGMENT | PPC_EXTERN | PPC_POWER_BR) | ||||
| #define POWERPC_MSRM_601     (0x000000000000FE70ULL) | ||||
| //#define POWERPC_MMU_601      (POWERPC_MMU_601)
 | ||||
| //#define POWERPC_EXCP_601     (POWERPC_EXCP_601)
 | ||||
| @ -3164,7 +3165,7 @@ static void init_proc_601 (CPUPPCState *env) | ||||
|                               PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE |            \ | ||||
|                               PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX |             \ | ||||
|                               PPC_6xx_TLB | PPC_MEM_TLBSYNC | PPC_CACHE_DCBZ |\ | ||||
|                               PPC_602_SPEC) | ||||
|                               PPC_SEGMENT | PPC_602_SPEC) | ||||
| #define POWERPC_MSRM_602     (0x000000000033FF73ULL) | ||||
| #define POWERPC_MMU_602      (POWERPC_MMU_SOFT_6xx) | ||||
| //#define POWERPC_EXCP_602     (POWERPC_EXCP_602)
 | ||||
| @ -3942,15 +3943,15 @@ static void init_proc_7455 (CPUPPCState *env) | ||||
| 
 | ||||
| #if defined (TARGET_PPC64) | ||||
| #define POWERPC_INSNS_WORK64  (POWERPC_INSNS_6xx | PPC_FLOAT_FSQRT |          \ | ||||
|                               PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE |            \ | ||||
|                               PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX |             \ | ||||
|                               PPC_MEM_TLBSYNC | PPC_CACHE_DCBZT | PPC_MFTB) | ||||
|                                PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE |           \ | ||||
|                                PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX |            \ | ||||
|                                PPC_MEM_TLBSYNC | PPC_CACHE_DCBZT | PPC_MFTB) | ||||
| /* PowerPC 970                                                               */ | ||||
| #define POWERPC_INSNS_970    (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT |        \ | ||||
|                               PPC_64B | PPC_ALTIVEC |                         \ | ||||
|                               PPC_64_BRIDGE | PPC_SLBI) | ||||
|                               PPC_SEGMENT_64B | PPC_SLBI) | ||||
| #define POWERPC_MSRM_970     (0x900000000204FF36ULL) | ||||
| #define POWERPC_MMU_970      (POWERPC_MMU_64BRIDGE) | ||||
| #define POWERPC_MMU_970      (POWERPC_MMU_64B) | ||||
| //#define POWERPC_EXCP_970     (POWERPC_EXCP_970)
 | ||||
| #define POWERPC_INPUT_970    (PPC_FLAGS_INPUT_970) | ||||
| #define POWERPC_BFDM_970     (bfd_mach_ppc64) | ||||
| @ -3990,9 +3991,24 @@ static void init_proc_970 (CPUPPCState *env) | ||||
|     /* Memory management */ | ||||
|     /* XXX: not correct */ | ||||
|     gen_low_BATs(env); | ||||
| #if 0 // TODO
 | ||||
|     env->slb_nr = 32; | ||||
|     /* XXX : not implemented */ | ||||
|     spr_register(env, SPR_MMUCFG, "MMUCFG", | ||||
|                  SPR_NOACCESS, SPR_NOACCESS, | ||||
|                  &spr_read_generic, SPR_NOACCESS, | ||||
|                  0x00000000); /* TOFIX */ | ||||
|     /* XXX : not implemented */ | ||||
|     spr_register(env, SPR_MMUCSR0, "MMUCSR0", | ||||
|                  SPR_NOACCESS, SPR_NOACCESS, | ||||
|                  &spr_read_generic, &spr_write_generic, | ||||
|                  0x00000000); /* TOFIX */ | ||||
|     spr_register(env, SPR_HIOR, "SPR_HIOR", | ||||
|                  SPR_NOACCESS, SPR_NOACCESS, | ||||
|                  &spr_read_generic, &spr_write_generic, | ||||
|                  0xFFF00000); /* XXX: This is a hack */ | ||||
| #if !defined(CONFIG_USER_ONLY) | ||||
|     env->excp_prefix = 0xFFF00000; | ||||
| #endif | ||||
|     env->slb_nr = 32; | ||||
|     init_excp_970(env); | ||||
|     env->dcache_line_size = 128; | ||||
|     env->icache_line_size = 128; | ||||
| @ -4003,9 +4019,9 @@ static void init_proc_970 (CPUPPCState *env) | ||||
| /* PowerPC 970FX (aka G5)                                                    */ | ||||
| #define POWERPC_INSNS_970FX  (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT |        \ | ||||
|                               PPC_64B | PPC_ALTIVEC |                         \ | ||||
|                               PPC_64_BRIDGE | PPC_SLBI) | ||||
|                               PPC_SEGMENT_64B | PPC_SLBI) | ||||
| #define POWERPC_MSRM_970FX   (0x800000000204FF36ULL) | ||||
| #define POWERPC_MMU_970FX    (POWERPC_MMU_64BRIDGE) | ||||
| #define POWERPC_MMU_970FX    (POWERPC_MMU_64B) | ||||
| #define POWERPC_EXCP_970FX   (POWERPC_EXCP_970) | ||||
| #define POWERPC_INPUT_970FX  (PPC_FLAGS_INPUT_970) | ||||
| #define POWERPC_BFDM_970FX   (bfd_mach_ppc64) | ||||
| @ -4045,9 +4061,24 @@ static void init_proc_970FX (CPUPPCState *env) | ||||
|     /* Memory management */ | ||||
|     /* XXX: not correct */ | ||||
|     gen_low_BATs(env); | ||||
| #if 0 // TODO
 | ||||
|     env->slb_nr = 32; | ||||
|     /* XXX : not implemented */ | ||||
|     spr_register(env, SPR_MMUCFG, "MMUCFG", | ||||
|                  SPR_NOACCESS, SPR_NOACCESS, | ||||
|                  &spr_read_generic, SPR_NOACCESS, | ||||
|                  0x00000000); /* TOFIX */ | ||||
|     /* XXX : not implemented */ | ||||
|     spr_register(env, SPR_MMUCSR0, "MMUCSR0", | ||||
|                  SPR_NOACCESS, SPR_NOACCESS, | ||||
|                  &spr_read_generic, &spr_write_generic, | ||||
|                  0x00000000); /* TOFIX */ | ||||
|     spr_register(env, SPR_HIOR, "SPR_HIOR", | ||||
|                  SPR_NOACCESS, SPR_NOACCESS, | ||||
|                  &spr_read_generic, &spr_write_generic, | ||||
|                  0xFFF00000); /* XXX: This is a hack */ | ||||
| #if !defined(CONFIG_USER_ONLY) | ||||
|     env->excp_prefix = 0xFFF00000; | ||||
| #endif | ||||
|     env->slb_nr = 32; | ||||
|     init_excp_970(env); | ||||
|     env->dcache_line_size = 128; | ||||
|     env->icache_line_size = 128; | ||||
| @ -4058,9 +4089,9 @@ static void init_proc_970FX (CPUPPCState *env) | ||||
| /* PowerPC 970 GX                                                            */ | ||||
| #define POWERPC_INSNS_970GX  (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT |        \ | ||||
|                               PPC_64B | PPC_ALTIVEC |                         \ | ||||
|                               PPC_64_BRIDGE | PPC_SLBI) | ||||
|                               PPC_SEGMENT_64B | PPC_SLBI) | ||||
| #define POWERPC_MSRM_970GX   (0x800000000204FF36ULL) | ||||
| #define POWERPC_MMU_970GX    (POWERPC_MMU_64BRIDGE) | ||||
| #define POWERPC_MMU_970GX    (POWERPC_MMU_64B) | ||||
| #define POWERPC_EXCP_970GX   (POWERPC_EXCP_970) | ||||
| #define POWERPC_INPUT_970GX  (PPC_FLAGS_INPUT_970) | ||||
| #define POWERPC_BFDM_970GX   (bfd_mach_ppc64) | ||||
| @ -4100,9 +4131,24 @@ static void init_proc_970GX (CPUPPCState *env) | ||||
|     /* Memory management */ | ||||
|     /* XXX: not correct */ | ||||
|     gen_low_BATs(env); | ||||
| #if 0 // TODO
 | ||||
|     env->slb_nr = 32; | ||||
|     /* XXX : not implemented */ | ||||
|     spr_register(env, SPR_MMUCFG, "MMUCFG", | ||||
|                  SPR_NOACCESS, SPR_NOACCESS, | ||||
|                  &spr_read_generic, SPR_NOACCESS, | ||||
|                  0x00000000); /* TOFIX */ | ||||
|     /* XXX : not implemented */ | ||||
|     spr_register(env, SPR_MMUCSR0, "MMUCSR0", | ||||
|                  SPR_NOACCESS, SPR_NOACCESS, | ||||
|                  &spr_read_generic, &spr_write_generic, | ||||
|                  0x00000000); /* TOFIX */ | ||||
|     spr_register(env, SPR_HIOR, "SPR_HIOR", | ||||
|                  SPR_NOACCESS, SPR_NOACCESS, | ||||
|                  &spr_read_generic, &spr_write_generic, | ||||
|                  0xFFF00000); /* XXX: This is a hack */ | ||||
| #if !defined(CONFIG_USER_ONLY) | ||||
|     env->excp_prefix = 0xFFF00000; | ||||
| #endif | ||||
|     env->slb_nr = 32; | ||||
|     init_excp_970(env); | ||||
|     env->dcache_line_size = 128; | ||||
|     env->icache_line_size = 128; | ||||
| @ -6010,9 +6056,6 @@ int cpu_ppc_register (CPUPPCState *env, ppc_def_t *def) | ||||
|         case POWERPC_MMU_64B: | ||||
|             mmu_model = "PowerPC 64"; | ||||
|             break; | ||||
|         case POWERPC_MMU_64BRIDGE: | ||||
|             mmu_model = "PowerPC 64 bridge"; | ||||
|             break; | ||||
| #endif | ||||
|         default: | ||||
|             mmu_model = "Unknown or invalid"; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 j_mayer
						j_mayer