aboutsummaryrefslogtreecommitdiff
path: root/target-ppc
diff options
context:
space:
mode:
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-03-18 08:47:10 +0000
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-03-18 08:47:10 +0000
commit36f696517b1723d627b79aa924bac7c678de01b0 (patch)
treeea0063b4b3fdd86185f8e73885316f07b6c0dbe1 /target-ppc
parent33d68b5f00011c8101aec93ba1bb2b470e35151d (diff)
As icbi is not a priviledge instruction and is treated as a load by the MMU
it needs to be implemented for every MMU translation mode. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2492 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-ppc')
-rw-r--r--target-ppc/op.c15
-rw-r--r--target-ppc/op_helper.c29
-rw-r--r--target-ppc/op_helper.h7
-rw-r--r--target-ppc/op_helper_mem.h29
-rw-r--r--target-ppc/op_mem.h15
-rw-r--r--target-ppc/translate.c43
6 files changed, 83 insertions, 55 deletions
diff --git a/target-ppc/op.c b/target-ppc/op.c
index be922c6ada..9531595bec 100644
--- a/target-ppc/op.c
+++ b/target-ppc/op.c
@@ -1884,21 +1884,6 @@ void OPPROTO op_td (void)
}
#endif
-/* Instruction cache block invalidate */
-void OPPROTO op_icbi (void)
-{
- do_icbi();
- RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_icbi_64 (void)
-{
- do_icbi_64();
- RETURN();
-}
-#endif
-
#if !defined(CONFIG_USER_ONLY)
/* tlbia */
PPC_OP(tlbia)
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 7bc59332df..7ef06b20b0 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -808,35 +808,6 @@ void do_td (int flags)
}
#endif
-/* Instruction cache invalidation helper */
-void do_icbi (void)
-{
- uint32_t tmp;
- /* Invalidate one cache line :
- * PowerPC specification says this is to be treated like a load
- * (not a fetch) by the MMU. To be sure it will be so,
- * do the load "by hand".
- */
- tmp = ldl_kernel((uint32_t)T0);
- T0 &= ~(ICACHE_LINE_SIZE - 1);
- tb_invalidate_page_range((uint32_t)T0, (uint32_t)(T0 + ICACHE_LINE_SIZE));
-}
-
-#if defined(TARGET_PPC64)
-void do_icbi_64 (void)
-{
- uint64_t tmp;
- /* Invalidate one cache line :
- * PowerPC specification says this is to be treated like a load
- * (not a fetch) by the MMU. To be sure it will be so,
- * do the load "by hand".
- */
- tmp = ldq_kernel((uint64_t)T0);
- T0 &= ~(ICACHE_LINE_SIZE - 1);
- tb_invalidate_page_range((uint64_t)T0, (uint64_t)(T0 + ICACHE_LINE_SIZE));
-}
-#endif
-
/*****************************************************************************/
/* PowerPC 601 specific instructions (POWER bridge) */
void do_POWER_abso (void)
diff --git a/target-ppc/op_helper.h b/target-ppc/op_helper.h
index 13ed7ab927..6eaceb30ed 100644
--- a/target-ppc/op_helper.h
+++ b/target-ppc/op_helper.h
@@ -29,6 +29,7 @@ void glue(do_lmw, MEMSUFFIX) (int dst);
void glue(do_lmw_le, MEMSUFFIX) (int dst);
void glue(do_stmw, MEMSUFFIX) (int src);
void glue(do_stmw_le, MEMSUFFIX) (int src);
+void glue(do_icbi, MEMSUFFIX) (void);
void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb);
void glue(do_POWER2_lfq, MEMSUFFIX) (void);
void glue(do_POWER2_lfq_le, MEMSUFFIX) (void);
@@ -44,6 +45,7 @@ void glue(do_lmw_64, MEMSUFFIX) (int dst);
void glue(do_lmw_le_64, MEMSUFFIX) (int dst);
void glue(do_stmw_64, MEMSUFFIX) (int src);
void glue(do_stmw_le_64, MEMSUFFIX) (int src);
+void glue(do_icbi_64, MEMSUFFIX) (void);
#endif
#else
@@ -102,11 +104,6 @@ void do_tw (int flags);
#if defined(TARGET_PPC64)
void do_td (int flags);
#endif
-void do_icbi (void);
-#if defined(TARGET_PPC64)
-void do_icbi_64 (void);
-#endif
-
#if !defined(CONFIG_USER_ONLY)
void do_rfi (void);
#if defined(TARGET_PPC64)
diff --git a/target-ppc/op_helper_mem.h b/target-ppc/op_helper_mem.h
index ccee7142ed..49ec1c42f4 100644
--- a/target-ppc/op_helper_mem.h
+++ b/target-ppc/op_helper_mem.h
@@ -242,6 +242,35 @@ void glue(do_stsw_le_64, MEMSUFFIX) (int src)
}
#endif
+/* Instruction cache invalidation helper */
+void glue(do_icbi, MEMSUFFIX) (void)
+{
+ uint32_t tmp;
+ /* Invalidate one cache line :
+ * PowerPC specification says this is to be treated like a load
+ * (not a fetch) by the MMU. To be sure it will be so,
+ * do the load "by hand".
+ */
+ tmp = glue(ldl, MEMSUFFIX)((uint32_t)T0);
+ T0 &= ~(ICACHE_LINE_SIZE - 1);
+ tb_invalidate_page_range((uint32_t)T0, (uint32_t)(T0 + ICACHE_LINE_SIZE));
+}
+
+#if defined(TARGET_PPC64)
+void glue(do_icbi_64, MEMSUFFIX) (void)
+{
+ uint64_t tmp;
+ /* Invalidate one cache line :
+ * PowerPC specification says this is to be treated like a load
+ * (not a fetch) by the MMU. To be sure it will be so,
+ * do the load "by hand".
+ */
+ tmp = glue(ldq, MEMSUFFIX)((uint64_t)T0);
+ T0 &= ~(ICACHE_LINE_SIZE - 1);
+ tb_invalidate_page_range((uint64_t)T0, (uint64_t)(T0 + ICACHE_LINE_SIZE));
+}
+#endif
+
/* PPC 601 specific instructions (POWER bridge) */
// XXX: to be tested
void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb)
diff --git a/target-ppc/op_mem.h b/target-ppc/op_mem.h
index 8aa799f651..f5a8c4b64f 100644
--- a/target-ppc/op_mem.h
+++ b/target-ppc/op_mem.h
@@ -730,6 +730,21 @@ void OPPROTO glue(op_dcbz_64, MEMSUFFIX) (void)
}
#endif
+/* Instruction cache block invalidate */
+void OPPROTO glue(op_icbi, MEMSUFFIX) (void)
+{
+ glue(do_icbi, MEMSUFFIX)();
+ RETURN();
+}
+
+#if defined(TARGET_PPC64)
+void OPPROTO glue(op_icbi_64, MEMSUFFIX) (void)
+{
+ glue(do_icbi_64, MEMSUFFIX)();
+ RETURN();
+}
+#endif
+
/* External access */
void OPPROTO glue(op_eciwx, MEMSUFFIX) (void)
{
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index e5c281293a..82919a5875 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3069,17 +3069,48 @@ GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
}
/* icbi */
+#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
+#if defined(TARGET_PPC64)
+#if defined(CONFIG_USER_ONLY)
+static GenOpFunc *gen_op_icbi[] = {
+ &gen_op_icbi_raw,
+ &gen_op_icbi_raw,
+ &gen_op_icbi_64_raw,
+ &gen_op_icbi_64_raw,
+};
+#else
+static GenOpFunc *gen_op_icbi[] = {
+ &gen_op_icbi_user,
+ &gen_op_icbi_user,
+ &gen_op_icbi_kernel,
+ &gen_op_icbi_kernel,
+ &gen_op_icbi_64_user,
+ &gen_op_icbi_64_user,
+ &gen_op_icbi_64_kernel,
+ &gen_op_icbi_64_kernel,
+};
+#endif
+#else
+#if defined(CONFIG_USER_ONLY)
+static GenOpFunc *gen_op_icbi[] = {
+ &gen_op_icbi_raw,
+ &gen_op_icbi_raw,
+};
+#else
+static GenOpFunc *gen_op_icbi[] = {
+ &gen_op_icbi_user,
+ &gen_op_icbi_user,
+ &gen_op_icbi_kernel,
+ &gen_op_icbi_kernel,
+};
+#endif
+#endif
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
{
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
gen_addr_reg_index(ctx);
-#if defined(TARGET_PPC64)
- if (ctx->sf_mode)
- gen_op_icbi_64();
- else
-#endif
- gen_op_icbi();
+ op_icbi();
RET_STOP(ctx);
}