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,21 +1884,6 @@ void OPPROTO op_td (void) | ||
1884 | } | 1884 | } |
1885 | #endif | 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 | #if !defined(CONFIG_USER_ONLY) | 1887 | #if !defined(CONFIG_USER_ONLY) |
1903 | /* tlbia */ | 1888 | /* tlbia */ |
1904 | PPC_OP(tlbia) | 1889 | PPC_OP(tlbia) |
target-ppc/op_helper.c
@@ -808,35 +808,6 @@ void do_td (int flags) | @@ -808,35 +808,6 @@ void do_td (int flags) | ||
808 | } | 808 | } |
809 | #endif | 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 | /* PowerPC 601 specific instructions (POWER bridge) */ | 812 | /* PowerPC 601 specific instructions (POWER bridge) */ |
842 | void do_POWER_abso (void) | 813 | void do_POWER_abso (void) |
target-ppc/op_helper.h
@@ -29,6 +29,7 @@ void glue(do_lmw, MEMSUFFIX) (int dst); | @@ -29,6 +29,7 @@ void glue(do_lmw, MEMSUFFIX) (int dst); | ||
29 | void glue(do_lmw_le, MEMSUFFIX) (int dst); | 29 | void glue(do_lmw_le, MEMSUFFIX) (int dst); |
30 | void glue(do_stmw, MEMSUFFIX) (int src); | 30 | void glue(do_stmw, MEMSUFFIX) (int src); |
31 | void glue(do_stmw_le, MEMSUFFIX) (int src); | 31 | void glue(do_stmw_le, MEMSUFFIX) (int src); |
32 | +void glue(do_icbi, MEMSUFFIX) (void); | ||
32 | void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb); | 33 | void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb); |
33 | void glue(do_POWER2_lfq, MEMSUFFIX) (void); | 34 | void glue(do_POWER2_lfq, MEMSUFFIX) (void); |
34 | void glue(do_POWER2_lfq_le, MEMSUFFIX) (void); | 35 | void glue(do_POWER2_lfq_le, MEMSUFFIX) (void); |
@@ -44,6 +45,7 @@ void glue(do_lmw_64, MEMSUFFIX) (int dst); | @@ -44,6 +45,7 @@ void glue(do_lmw_64, MEMSUFFIX) (int dst); | ||
44 | void glue(do_lmw_le_64, MEMSUFFIX) (int dst); | 45 | void glue(do_lmw_le_64, MEMSUFFIX) (int dst); |
45 | void glue(do_stmw_64, MEMSUFFIX) (int src); | 46 | void glue(do_stmw_64, MEMSUFFIX) (int src); |
46 | void glue(do_stmw_le_64, MEMSUFFIX) (int src); | 47 | void glue(do_stmw_le_64, MEMSUFFIX) (int src); |
48 | +void glue(do_icbi_64, MEMSUFFIX) (void); | ||
47 | #endif | 49 | #endif |
48 | 50 | ||
49 | #else | 51 | #else |
@@ -102,11 +104,6 @@ void do_tw (int flags); | @@ -102,11 +104,6 @@ void do_tw (int flags); | ||
102 | #if defined(TARGET_PPC64) | 104 | #if defined(TARGET_PPC64) |
103 | void do_td (int flags); | 105 | void do_td (int flags); |
104 | #endif | 106 | #endif |
105 | -void do_icbi (void); | ||
106 | -#if defined(TARGET_PPC64) | ||
107 | -void do_icbi_64 (void); | ||
108 | -#endif | ||
109 | - | ||
110 | #if !defined(CONFIG_USER_ONLY) | 107 | #if !defined(CONFIG_USER_ONLY) |
111 | void do_rfi (void); | 108 | void do_rfi (void); |
112 | #if defined(TARGET_PPC64) | 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,6 +242,35 @@ void glue(do_stsw_le_64, MEMSUFFIX) (int src) | ||
242 | } | 242 | } |
243 | #endif | 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 | /* PPC 601 specific instructions (POWER bridge) */ | 274 | /* PPC 601 specific instructions (POWER bridge) */ |
246 | // XXX: to be tested | 275 | // XXX: to be tested |
247 | void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb) | 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,6 +730,21 @@ void OPPROTO glue(op_dcbz_64, MEMSUFFIX) (void) | ||
730 | } | 730 | } |
731 | #endif | 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 | /* External access */ | 748 | /* External access */ |
734 | void OPPROTO glue(op_eciwx, MEMSUFFIX) (void) | 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,17 +3069,48 @@ GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE) | ||
3069 | } | 3069 | } |
3070 | 3070 | ||
3071 | /* icbi */ | 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 | GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE) | 3108 | GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE) |
3073 | { | 3109 | { |
3074 | /* NIP cannot be restored if the memory exception comes from an helper */ | 3110 | /* NIP cannot be restored if the memory exception comes from an helper */ |
3075 | gen_update_nip(ctx, ctx->nip - 4); | 3111 | gen_update_nip(ctx, ctx->nip - 4); |
3076 | gen_addr_reg_index(ctx); | 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 | RET_STOP(ctx); | 3114 | RET_STOP(ctx); |
3084 | } | 3115 | } |
3085 | 3116 |