Commit 36f696517b1723d627b79aa924bac7c678de01b0
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
Showing
6 changed files
with
83 additions
and
55 deletions
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 | ... | ... |