提交 add78955 编写于 作者: J j_mayer

PowerPC 620 MMU do not have the same exact behavior as standard

  64 bits PowerPC ones.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3706 c046a42c-6fe2-441c-8c8c-71466251a162
上级 5b8105fa
......@@ -93,30 +93,33 @@ typedef uint32_t ppc_gpr_t;
/* MMU model */
typedef enum powerpc_mmu_t powerpc_mmu_t;
enum powerpc_mmu_t {
POWERPC_MMU_UNKNOWN = 0,
POWERPC_MMU_UNKNOWN = 0x00000000,
/* Standard 32 bits PowerPC MMU */
POWERPC_MMU_32B,
POWERPC_MMU_32B = 0x00000001,
/* PowerPC 6xx MMU with software TLB */
POWERPC_MMU_SOFT_6xx,
POWERPC_MMU_SOFT_6xx = 0x00000002,
/* PowerPC 74xx MMU with software TLB */
POWERPC_MMU_SOFT_74xx,
POWERPC_MMU_SOFT_74xx = 0x00000003,
/* PowerPC 4xx MMU with software TLB */
POWERPC_MMU_SOFT_4xx,
POWERPC_MMU_SOFT_4xx = 0x00000004,
/* PowerPC 4xx MMU with software TLB and zones protections */
POWERPC_MMU_SOFT_4xx_Z,
POWERPC_MMU_SOFT_4xx_Z = 0x00000005,
/* PowerPC MMU in real mode only */
POWERPC_MMU_REAL,
POWERPC_MMU_REAL = 0x00000006,
/* Freescale MPC8xx MMU model */
POWERPC_MMU_MPC8xx,
POWERPC_MMU_MPC8xx = 0x00000007,
/* BookE MMU model */
POWERPC_MMU_BOOKE,
POWERPC_MMU_BOOKE = 0x00000008,
/* BookE FSL MMU model */
POWERPC_MMU_BOOKE_FSL,
POWERPC_MMU_BOOKE_FSL = 0x00000009,
/* PowerPC 601 MMU model (specific BATs format) */
POWERPC_MMU_601,
POWERPC_MMU_601 = 0x0000000A,
#if defined(TARGET_PPC64)
#define POWERPC_MMU_64 0x00010000
/* 64 bits PowerPC MMU */
POWERPC_MMU_64B,
POWERPC_MMU_64B = POWERPC_MMU_64 | 0x00000001,
/* 620 variant (no segment exceptions) */
POWERPC_MMU_620 = POWERPC_MMU_64 | 0x00000002,
#endif /* defined(TARGET_PPC64) */
};
......
......@@ -706,7 +706,7 @@ static always_inline int find_pte (CPUState *env, mmu_ctx_t *ctx,
int h, int rw, int type)
{
#if defined(TARGET_PPC64)
if (env->mmu_model == POWERPC_MMU_64B)
if (env->mmu_model & POWERPC_MMU_64)
return find_pte64(ctx, h, rw, type);
#endif
......@@ -916,7 +916,7 @@ static always_inline int get_segment (CPUState *env, mmu_ctx_t *ctx,
pr = msr_pr;
#if defined(TARGET_PPC64)
if (env->mmu_model == POWERPC_MMU_64B) {
if (env->mmu_model & POWERPC_MMU_64) {
#if defined (DEBUG_MMU)
if (loglevel != 0) {
fprintf(logfile, "Check SLBs\n");
......@@ -973,7 +973,7 @@ static always_inline int get_segment (CPUState *env, mmu_ctx_t *ctx,
sdr = env->sdr1;
pgidx = (eaddr & page_mask) >> TARGET_PAGE_BITS;
#if defined(TARGET_PPC64)
if (env->mmu_model == POWERPC_MMU_64B) {
if (env->mmu_model & POWERPC_MMU_64) {
htab_mask = 0x0FFFFFFF >> (28 - (sdr & 0x1F));
/* XXX: this is false for 1 TB segments */
hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
......@@ -1002,7 +1002,7 @@ static always_inline int get_segment (CPUState *env, mmu_ctx_t *ctx,
#endif
ctx->pg_addr[1] = get_pgaddr(sdr, sdr_sh, hash, mask);
#if defined(TARGET_PPC64)
if (env->mmu_model == POWERPC_MMU_64B) {
if (env->mmu_model & POWERPC_MMU_64) {
/* Only 5 bits of the page index are used in the AVPN */
ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80);
} else
......@@ -1362,6 +1362,7 @@ static always_inline int check_physical (CPUState *env, mmu_ctx_t *ctx,
ctx->prot |= PAGE_WRITE;
break;
#if defined(TARGET_PPC64)
case POWERPC_MMU_620:
case POWERPC_MMU_64B:
/* Real address are 60 bits long */
ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL;
......@@ -1430,6 +1431,7 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
case POWERPC_MMU_SOFT_6xx:
case POWERPC_MMU_SOFT_74xx:
#if defined(TARGET_PPC64)
case POWERPC_MMU_620:
case POWERPC_MMU_64B:
#endif
/* Try to find a BAT */
......@@ -1538,6 +1540,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
case POWERPC_MMU_32B:
case POWERPC_MMU_601:
#if defined(TARGET_PPC64)
case POWERPC_MMU_620:
case POWERPC_MMU_64B:
#endif
env->exception_index = POWERPC_EXCP_ISI;
......@@ -1583,8 +1586,14 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
#if defined(TARGET_PPC64)
case -5:
/* No match in segment table */
env->exception_index = POWERPC_EXCP_ISEG;
env->error_code = 0;
if (env->mmu_model == POWERPC_MMU_620) {
env->exception_index = POWERPC_EXCP_ISI;
/* XXX: this might be incorrect */
env->error_code = 0x40000000;
} else {
env->exception_index = POWERPC_EXCP_ISEG;
env->error_code = 0;
}
break;
#endif
}
......@@ -1634,6 +1643,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
case POWERPC_MMU_32B:
case POWERPC_MMU_601:
#if defined(TARGET_PPC64)
case POWERPC_MMU_620:
case POWERPC_MMU_64B:
#endif
env->exception_index = POWERPC_EXCP_DSI;
......@@ -1716,9 +1726,20 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
#if defined(TARGET_PPC64)
case -5:
/* No match in segment table */
env->exception_index = POWERPC_EXCP_DSEG;
env->error_code = 0;
env->spr[SPR_DAR] = address;
if (env->mmu_model == POWERPC_MMU_620) {
env->exception_index = POWERPC_EXCP_DSI;
env->error_code = 0;
env->spr[SPR_DAR] = address;
/* XXX: this might be incorrect */
if (rw == 1)
env->spr[SPR_DSISR] = 0x42000000;
else
env->spr[SPR_DSISR] = 0x40000000;
} else {
env->exception_index = POWERPC_EXCP_DSEG;
env->error_code = 0;
env->spr[SPR_DAR] = address;
}
break;
#endif
}
......@@ -1955,6 +1976,7 @@ void ppc_tlb_invalidate_all (CPUPPCState *env)
case POWERPC_MMU_32B:
case POWERPC_MMU_601:
#if defined(TARGET_PPC64)
case POWERPC_MMU_620:
case POWERPC_MMU_64B:
#endif /* defined(TARGET_PPC64) */
tlb_flush(env, 1);
......@@ -2021,6 +2043,7 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
tlb_flush_page(env, addr | (0xF << 28));
break;
#if defined(TARGET_PPC64)
case POWERPC_MMU_620:
case POWERPC_MMU_64B:
/* tlbie invalidate TLBs for all segments */
/* XXX: given the fact that there are too many segments to invalidate,
......
......@@ -5237,13 +5237,13 @@ static void init_proc_970MP (CPUPPCState *env)
/* PowerPC 620 */
#define POWERPC_INSNS_620 (POWERPC_INSNS_WORKS | PPC_FLOAT_FSQRT | \
PPC_64B | PPC_SLBI)
#define POWERPC_MSRM_620 (0x800000000005FF73ULL)
#define POWERPC_MMU_620 (POWERPC_MMU_64B)
#define POWERPC_MSRM_620 (0x800000000005FF77ULL)
//#define POWERPC_MMU_620 (POWERPC_MMU_620)
#define POWERPC_EXCP_620 (POWERPC_EXCP_970)
#define POWERPC_INPUT_620 (PPC_FLAGS_INPUT_6xx)
#define POWERPC_BFDM_620 (bfd_mach_ppc64)
#define POWERPC_FLAG_620 (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \
POWERPC_FLAG_BUS_CLK)
POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK)
#define check_pow_620 check_pow_nocheck /* Check this */
__attribute__ (( unused ))
......@@ -8313,6 +8313,9 @@ int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def)
case POWERPC_MMU_64B:
mmu_model = "PowerPC 64";
break;
case POWERPC_MMU_620:
mmu_model = "PowerPC 620";
break;
#endif
default:
mmu_model = "Unknown or invalid";
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册