Commit 36f696517b1723d627b79aa924bac7c678de01b0

Authored by j_mayer
1 parent 33d68b5f

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
target-ppc/op.c
... ... @@ -1884,21 +1884,6 @@ void OPPROTO op_td (void)
1884 1884 }
1885 1885 #endif
1886 1886  
1887   -/* Instruction cache block invalidate */
1888   -void OPPROTO op_icbi (void)
1889   -{
1890   - do_icbi();
1891   - RETURN();
1892   -}
1893   -
1894   -#if defined(TARGET_PPC64)
1895   -void OPPROTO op_icbi_64 (void)
1896   -{
1897   - do_icbi_64();
1898   - RETURN();
1899   -}
1900   -#endif
1901   -
1902 1887 #if !defined(CONFIG_USER_ONLY)
1903 1888 /* tlbia */
1904 1889 PPC_OP(tlbia)
... ...
target-ppc/op_helper.c
... ... @@ -808,35 +808,6 @@ void do_td (int flags)
808 808 }
809 809 #endif
810 810  
811   -/* Instruction cache invalidation helper */
812   -void do_icbi (void)
813   -{
814   - uint32_t tmp;
815   - /* Invalidate one cache line :
816   - * PowerPC specification says this is to be treated like a load
817   - * (not a fetch) by the MMU. To be sure it will be so,
818   - * do the load "by hand".
819   - */
820   - tmp = ldl_kernel((uint32_t)T0);
821   - T0 &= ~(ICACHE_LINE_SIZE - 1);
822   - tb_invalidate_page_range((uint32_t)T0, (uint32_t)(T0 + ICACHE_LINE_SIZE));
823   -}
824   -
825   -#if defined(TARGET_PPC64)
826   -void do_icbi_64 (void)
827   -{
828   - uint64_t tmp;
829   - /* Invalidate one cache line :
830   - * PowerPC specification says this is to be treated like a load
831   - * (not a fetch) by the MMU. To be sure it will be so,
832   - * do the load "by hand".
833   - */
834   - tmp = ldq_kernel((uint64_t)T0);
835   - T0 &= ~(ICACHE_LINE_SIZE - 1);
836   - tb_invalidate_page_range((uint64_t)T0, (uint64_t)(T0 + ICACHE_LINE_SIZE));
837   -}
838   -#endif
839   -
840 811 /*****************************************************************************/
841 812 /* PowerPC 601 specific instructions (POWER bridge) */
842 813 void do_POWER_abso (void)
... ...
target-ppc/op_helper.h
... ... @@ -29,6 +29,7 @@ void glue(do_lmw, MEMSUFFIX) (int dst);
29 29 void glue(do_lmw_le, MEMSUFFIX) (int dst);
30 30 void glue(do_stmw, MEMSUFFIX) (int src);
31 31 void glue(do_stmw_le, MEMSUFFIX) (int src);
  32 +void glue(do_icbi, MEMSUFFIX) (void);
32 33 void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb);
33 34 void glue(do_POWER2_lfq, MEMSUFFIX) (void);
34 35 void glue(do_POWER2_lfq_le, MEMSUFFIX) (void);
... ... @@ -44,6 +45,7 @@ void glue(do_lmw_64, MEMSUFFIX) (int dst);
44 45 void glue(do_lmw_le_64, MEMSUFFIX) (int dst);
45 46 void glue(do_stmw_64, MEMSUFFIX) (int src);
46 47 void glue(do_stmw_le_64, MEMSUFFIX) (int src);
  48 +void glue(do_icbi_64, MEMSUFFIX) (void);
47 49 #endif
48 50  
49 51 #else
... ... @@ -102,11 +104,6 @@ void do_tw (int flags);
102 104 #if defined(TARGET_PPC64)
103 105 void do_td (int flags);
104 106 #endif
105   -void do_icbi (void);
106   -#if defined(TARGET_PPC64)
107   -void do_icbi_64 (void);
108   -#endif
109   -
110 107 #if !defined(CONFIG_USER_ONLY)
111 108 void do_rfi (void);
112 109 #if defined(TARGET_PPC64)
... ...
target-ppc/op_helper_mem.h
... ... @@ -242,6 +242,35 @@ void glue(do_stsw_le_64, MEMSUFFIX) (int src)
242 242 }
243 243 #endif
244 244  
  245 +/* Instruction cache invalidation helper */
  246 +void glue(do_icbi, MEMSUFFIX) (void)
  247 +{
  248 + uint32_t tmp;
  249 + /* Invalidate one cache line :
  250 + * PowerPC specification says this is to be treated like a load
  251 + * (not a fetch) by the MMU. To be sure it will be so,
  252 + * do the load "by hand".
  253 + */
  254 + tmp = glue(ldl, MEMSUFFIX)((uint32_t)T0);
  255 + T0 &= ~(ICACHE_LINE_SIZE - 1);
  256 + tb_invalidate_page_range((uint32_t)T0, (uint32_t)(T0 + ICACHE_LINE_SIZE));
  257 +}
  258 +
  259 +#if defined(TARGET_PPC64)
  260 +void glue(do_icbi_64, MEMSUFFIX) (void)
  261 +{
  262 + uint64_t tmp;
  263 + /* Invalidate one cache line :
  264 + * PowerPC specification says this is to be treated like a load
  265 + * (not a fetch) by the MMU. To be sure it will be so,
  266 + * do the load "by hand".
  267 + */
  268 + tmp = glue(ldq, MEMSUFFIX)((uint64_t)T0);
  269 + T0 &= ~(ICACHE_LINE_SIZE - 1);
  270 + tb_invalidate_page_range((uint64_t)T0, (uint64_t)(T0 + ICACHE_LINE_SIZE));
  271 +}
  272 +#endif
  273 +
245 274 /* PPC 601 specific instructions (POWER bridge) */
246 275 // XXX: to be tested
247 276 void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb)
... ...
target-ppc/op_mem.h
... ... @@ -730,6 +730,21 @@ void OPPROTO glue(op_dcbz_64, MEMSUFFIX) (void)
730 730 }
731 731 #endif
732 732  
  733 +/* Instruction cache block invalidate */
  734 +void OPPROTO glue(op_icbi, MEMSUFFIX) (void)
  735 +{
  736 + glue(do_icbi, MEMSUFFIX)();
  737 + RETURN();
  738 +}
  739 +
  740 +#if defined(TARGET_PPC64)
  741 +void OPPROTO glue(op_icbi_64, MEMSUFFIX) (void)
  742 +{
  743 + glue(do_icbi_64, MEMSUFFIX)();
  744 + RETURN();
  745 +}
  746 +#endif
  747 +
733 748 /* External access */
734 749 void OPPROTO glue(op_eciwx, MEMSUFFIX) (void)
735 750 {
... ...
target-ppc/translate.c
... ... @@ -3069,17 +3069,48 @@ GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
3069 3069 }
3070 3070  
3071 3071 /* icbi */
  3072 +#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
  3073 +#if defined(TARGET_PPC64)
  3074 +#if defined(CONFIG_USER_ONLY)
  3075 +static GenOpFunc *gen_op_icbi[] = {
  3076 + &gen_op_icbi_raw,
  3077 + &gen_op_icbi_raw,
  3078 + &gen_op_icbi_64_raw,
  3079 + &gen_op_icbi_64_raw,
  3080 +};
  3081 +#else
  3082 +static GenOpFunc *gen_op_icbi[] = {
  3083 + &gen_op_icbi_user,
  3084 + &gen_op_icbi_user,
  3085 + &gen_op_icbi_kernel,
  3086 + &gen_op_icbi_kernel,
  3087 + &gen_op_icbi_64_user,
  3088 + &gen_op_icbi_64_user,
  3089 + &gen_op_icbi_64_kernel,
  3090 + &gen_op_icbi_64_kernel,
  3091 +};
  3092 +#endif
  3093 +#else
  3094 +#if defined(CONFIG_USER_ONLY)
  3095 +static GenOpFunc *gen_op_icbi[] = {
  3096 + &gen_op_icbi_raw,
  3097 + &gen_op_icbi_raw,
  3098 +};
  3099 +#else
  3100 +static GenOpFunc *gen_op_icbi[] = {
  3101 + &gen_op_icbi_user,
  3102 + &gen_op_icbi_user,
  3103 + &gen_op_icbi_kernel,
  3104 + &gen_op_icbi_kernel,
  3105 +};
  3106 +#endif
  3107 +#endif
3072 3108 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
3073 3109 {
3074 3110 /* NIP cannot be restored if the memory exception comes from an helper */
3075 3111 gen_update_nip(ctx, ctx->nip - 4);
3076 3112 gen_addr_reg_index(ctx);
3077   -#if defined(TARGET_PPC64)
3078   - if (ctx->sf_mode)
3079   - gen_op_icbi_64();
3080   - else
3081   -#endif
3082   - gen_op_icbi();
  3113 + op_icbi();
3083 3114 RET_STOP(ctx);
3084 3115 }
3085 3116  
... ...