diff options
author | j_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-10-04 00:51:58 +0000 |
---|---|---|
committer | j_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-10-04 00:51:58 +0000 |
commit | d63001d11434fc6bf217255b51f625a75d05fb35 (patch) | |
tree | f9c98fc52c58140c19c77ff12c4089c215a22e76 /target-ppc/translate.c | |
parent | 064034211a65bb602a32ccee18d92109eb2cd656 (diff) |
Make PowerPC cache line size implementation dependant.
Implement dcbz tunable cache line size for PowerPC 970.
Make hardware reset vector implementation dependant.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3321 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-ppc/translate.c')
-rw-r--r-- | target-ppc/translate.c | 185 |
1 files changed, 159 insertions, 26 deletions
diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 5e4b12b03c..77486f3b6a 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -169,6 +169,7 @@ typedef struct DisasContext { #endif ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */ int singlestep_enabled; + int dcache_line_size; } DisasContext; struct opc_handler_t { @@ -482,6 +483,10 @@ enum { PPC_WAIT = 0x0000100000000000ULL, /* New 64 bits extensions (PowerPC 2.0x) */ PPC_64BX = 0x0000200000000000ULL, + /* dcbz instruction with fixed cache line size */ + PPC_CACHE_DCBZ = 0x0000400000000000ULL, + /* dcbz instruction with tunable cache line size */ + PPC_CACHE_DCBZT = 0x0000800000000000ULL, }; /*****************************************************************************/ @@ -3623,51 +3628,178 @@ GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE) } /* dcbz */ -#define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])() +#define op_dcbz(n) (*gen_op_dcbz[n][ctx->mem_idx])() #if defined(CONFIG_USER_ONLY) /* User-mode only */ -static GenOpFunc *gen_op_dcbz[] = { - &gen_op_dcbz_raw, - &gen_op_dcbz_raw, +static GenOpFunc *gen_op_dcbz[4][4] = { + { + &gen_op_dcbz_l32_raw, + &gen_op_dcbz_l32_raw, #if defined(TARGET_PPC64) - &gen_op_dcbz_64_raw, - &gen_op_dcbz_64_raw, + &gen_op_dcbz_l32_64_raw, + &gen_op_dcbz_l32_64_raw, #endif + }, + { + &gen_op_dcbz_l64_raw, + &gen_op_dcbz_l64_raw, +#if defined(TARGET_PPC64) + &gen_op_dcbz_l64_64_raw, + &gen_op_dcbz_l64_64_raw, +#endif + }, + { + &gen_op_dcbz_l128_raw, + &gen_op_dcbz_l128_raw, +#if defined(TARGET_PPC64) + &gen_op_dcbz_l128_64_raw, + &gen_op_dcbz_l128_64_raw, +#endif + }, + { + &gen_op_dcbz_raw, + &gen_op_dcbz_raw, +#if defined(TARGET_PPC64) + &gen_op_dcbz_64_raw, + &gen_op_dcbz_64_raw, +#endif + }, }; #else #if defined(TARGET_PPC64) /* Full system - 64 bits mode */ -static GenOpFunc *gen_op_dcbz[] = { - &gen_op_dcbz_user, - &gen_op_dcbz_user, - &gen_op_dcbz_64_user, - &gen_op_dcbz_64_user, - &gen_op_dcbz_kernel, - &gen_op_dcbz_kernel, - &gen_op_dcbz_64_kernel, - &gen_op_dcbz_64_kernel, +static GenOpFunc *gen_op_dcbz[4][12] = { + { + &gen_op_dcbz_l32_user, + &gen_op_dcbz_l32_user, + &gen_op_dcbz_l32_64_user, + &gen_op_dcbz_l32_64_user, + &gen_op_dcbz_l32_kernel, + &gen_op_dcbz_l32_kernel, + &gen_op_dcbz_l32_64_kernel, + &gen_op_dcbz_l32_64_kernel, +#if defined(TARGET_PPC64H) + &gen_op_dcbz_l32_hypv, + &gen_op_dcbz_l32_hypv, + &gen_op_dcbz_l32_64_hypv, + &gen_op_dcbz_l32_64_hypv, +#endif + }, + { + &gen_op_dcbz_l64_user, + &gen_op_dcbz_l64_user, + &gen_op_dcbz_l64_64_user, + &gen_op_dcbz_l64_64_user, + &gen_op_dcbz_l64_kernel, + &gen_op_dcbz_l64_kernel, + &gen_op_dcbz_l64_64_kernel, + &gen_op_dcbz_l64_64_kernel, #if defined(TARGET_PPC64H) - &gen_op_dcbz_hypv, - &gen_op_dcbz_hypv, - &gen_op_dcbz_64_hypv, - &gen_op_dcbz_64_hypv, + &gen_op_dcbz_l64_hypv, + &gen_op_dcbz_l64_hypv, + &gen_op_dcbz_l64_64_hypv, + &gen_op_dcbz_l64_64_hypv, +#endif + }, + { + &gen_op_dcbz_l128_user, + &gen_op_dcbz_l128_user, + &gen_op_dcbz_l128_64_user, + &gen_op_dcbz_l128_64_user, + &gen_op_dcbz_l128_kernel, + &gen_op_dcbz_l128_kernel, + &gen_op_dcbz_l128_64_kernel, + &gen_op_dcbz_l128_64_kernel, +#if defined(TARGET_PPC64H) + &gen_op_dcbz_l128_hypv, + &gen_op_dcbz_l128_hypv, + &gen_op_dcbz_l128_64_hypv, + &gen_op_dcbz_l128_64_hypv, +#endif + }, + { + &gen_op_dcbz_user, + &gen_op_dcbz_user, + &gen_op_dcbz_64_user, + &gen_op_dcbz_64_user, + &gen_op_dcbz_kernel, + &gen_op_dcbz_kernel, + &gen_op_dcbz_64_kernel, + &gen_op_dcbz_64_kernel, +#if defined(TARGET_PPC64H) + &gen_op_dcbz_hypv, + &gen_op_dcbz_hypv, + &gen_op_dcbz_64_hypv, + &gen_op_dcbz_64_hypv, #endif + }, }; #else /* Full system - 32 bits mode */ -static GenOpFunc *gen_op_dcbz[] = { - &gen_op_dcbz_user, - &gen_op_dcbz_user, - &gen_op_dcbz_kernel, - &gen_op_dcbz_kernel, +static GenOpFunc *gen_op_dcbz[4][4] = { + { + &gen_op_dcbz_l32_user, + &gen_op_dcbz_l32_user, + &gen_op_dcbz_l32_kernel, + &gen_op_dcbz_l32_kernel, + }, + { + &gen_op_dcbz_l64_user, + &gen_op_dcbz_l64_user, + &gen_op_dcbz_l64_kernel, + &gen_op_dcbz_l64_kernel, + }, + { + &gen_op_dcbz_l128_user, + &gen_op_dcbz_l128_user, + &gen_op_dcbz_l128_kernel, + &gen_op_dcbz_l128_kernel, + }, + { + &gen_op_dcbz_user, + &gen_op_dcbz_user, + &gen_op_dcbz_kernel, + &gen_op_dcbz_kernel, + }, }; #endif #endif -GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE) +static inline void handler_dcbz (DisasContext *ctx, int dcache_line_size) +{ + int n; + + switch (dcache_line_size) { + case 32: + n = 0; + break; + case 64: + n = 1; + break; + case 128: + n = 2; + break; + default: + n = 3; + break; + } + op_dcbz(n); +} + +GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ) { gen_addr_reg_index(ctx); - op_dcbz(); + handler_dcbz(ctx, ctx->dcache_line_size); + gen_op_check_reservation(); +} + +GEN_HANDLER(dcbz_970, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT) +{ + gen_addr_reg_index(ctx); + if (ctx->opcode & 0x00200000) + handler_dcbz(ctx, ctx->dcache_line_size); + else + handler_dcbz(ctx, -1); gen_op_check_reservation(); } @@ -6341,6 +6473,7 @@ static inline int gen_intermediate_code_internal (CPUState *env, #else ctx.mem_idx = (supervisor << 1) | msr_le; #endif + ctx.dcache_line_size = env->dcache_line_size; ctx.fpu_enabled = msr_fp; #if defined(TARGET_PPCEMB) ctx.spe_enabled = msr_spe; |