aboutsummaryrefslogtreecommitdiff
path: root/target-ppc/translate.c
diff options
context:
space:
mode:
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-10-04 00:51:58 +0000
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-10-04 00:51:58 +0000
commitd63001d11434fc6bf217255b51f625a75d05fb35 (patch)
treef9c98fc52c58140c19c77ff12c4089c215a22e76 /target-ppc/translate.c
parent064034211a65bb602a32ccee18d92109eb2cd656 (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.c185
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;