diff options
author | j_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-03-18 08:47:10 +0000 |
---|---|---|
committer | j_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-03-18 08:47:10 +0000 |
commit | 36f696517b1723d627b79aa924bac7c678de01b0 (patch) | |
tree | ea0063b4b3fdd86185f8e73885316f07b6c0dbe1 /target-ppc | |
parent | 33d68b5f00011c8101aec93ba1bb2b470e35151d (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.c | 15 | ||||
-rw-r--r-- | target-ppc/op_helper.c | 29 | ||||
-rw-r--r-- | target-ppc/op_helper.h | 7 | ||||
-rw-r--r-- | target-ppc/op_helper_mem.h | 29 | ||||
-rw-r--r-- | target-ppc/op_mem.h | 15 | ||||
-rw-r--r-- | target-ppc/translate.c | 43 |
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); } |