Commit 28de16da38f20b3fe76fa80d10561c3a998342e2
1 parent
4a6b819c
CRIS: Improve ASID related TLB flushes.
* Speedup and correct ASID (PID) related TLB flushes. * Use 64bit tcg load/stores to emulate movem. * Remove unused helpers and other minor cleanups. Signed-off-by: Edgar E. Iglesias <edgar@axis.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5302 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
36 additions
and
37 deletions
target-cris/helper.h
@@ -3,10 +3,8 @@ | @@ -3,10 +3,8 @@ | ||
3 | void TCG_HELPER_PROTO helper_raise_exception(uint32_t index); | 3 | void TCG_HELPER_PROTO helper_raise_exception(uint32_t index); |
4 | void TCG_HELPER_PROTO helper_tlb_flush_pid(uint32_t pid); | 4 | void TCG_HELPER_PROTO helper_tlb_flush_pid(uint32_t pid); |
5 | void TCG_HELPER_PROTO helper_dump(uint32_t a0, uint32_t a1, uint32_t a2); | 5 | void TCG_HELPER_PROTO helper_dump(uint32_t a0, uint32_t a1, uint32_t a2); |
6 | -void TCG_HELPER_PROTO helper_dummy(void); | ||
7 | void TCG_HELPER_PROTO helper_rfe(void); | 6 | void TCG_HELPER_PROTO helper_rfe(void); |
8 | void TCG_HELPER_PROTO helper_rfn(void); | 7 | void TCG_HELPER_PROTO helper_rfn(void); |
9 | -void TCG_HELPER_PROTO helper_store(uint32_t a0); | ||
10 | 8 | ||
11 | void TCG_HELPER_PROTO helper_movl_sreg_reg (uint32_t sreg, uint32_t reg); | 9 | void TCG_HELPER_PROTO helper_movl_sreg_reg (uint32_t sreg, uint32_t reg); |
12 | void TCG_HELPER_PROTO helper_movl_reg_sreg (uint32_t reg, uint32_t sreg); | 10 | void TCG_HELPER_PROTO helper_movl_reg_sreg (uint32_t reg, uint32_t sreg); |
target-cris/mmu.c
@@ -140,7 +140,7 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, | @@ -140,7 +140,7 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, | ||
140 | 140 | ||
141 | r_cause = env->sregs[SFR_R_MM_CAUSE]; | 141 | r_cause = env->sregs[SFR_R_MM_CAUSE]; |
142 | r_cfg = env->sregs[SFR_RW_MM_CFG]; | 142 | r_cfg = env->sregs[SFR_RW_MM_CFG]; |
143 | - pid = env->pregs[PR_PID]; | 143 | + pid = env->pregs[PR_PID] & 0xff; |
144 | 144 | ||
145 | switch (rw) { | 145 | switch (rw) { |
146 | case 2: rwcause = CRIS_MMU_ERR_EXEC; mmu = 0; break; | 146 | case 2: rwcause = CRIS_MMU_ERR_EXEC; mmu = 0; break; |
@@ -270,7 +270,7 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, | @@ -270,7 +270,7 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, | ||
270 | /* Update RW_MM_CAUSE. */ | 270 | /* Update RW_MM_CAUSE. */ |
271 | set_field(&r_cause, rwcause, 8, 2); | 271 | set_field(&r_cause, rwcause, 8, 2); |
272 | set_field(&r_cause, vpage, 13, 19); | 272 | set_field(&r_cause, vpage, 13, 19); |
273 | - set_field(&r_cause, env->pregs[PR_PID], 0, 8); | 273 | + set_field(&r_cause, pid, 0, 8); |
274 | env->sregs[SFR_R_MM_CAUSE] = r_cause; | 274 | env->sregs[SFR_R_MM_CAUSE] = r_cause; |
275 | D(printf("refill vaddr=%x pc=%x\n", vaddr, env->pc)); | 275 | D(printf("refill vaddr=%x pc=%x\n", vaddr, env->pc)); |
276 | } | 276 | } |
@@ -280,7 +280,7 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, | @@ -280,7 +280,7 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, | ||
280 | __func__, rw, match, env->pc, | 280 | __func__, rw, match, env->pc, |
281 | vaddr, vpage, | 281 | vaddr, vpage, |
282 | tlb_vpn, tlb_pfn, tlb_pid, | 282 | tlb_vpn, tlb_pfn, tlb_pid, |
283 | - env->pregs[PR_PID], | 283 | + pid, |
284 | r_cause, | 284 | r_cause, |
285 | env->sregs[SFR_RW_MM_TLB_SEL], | 285 | env->sregs[SFR_RW_MM_TLB_SEL], |
286 | env->regs[R_SP], env->pregs[PR_USP], env->ksp)); | 286 | env->regs[R_SP], env->pregs[PR_USP], env->ksp)); |
@@ -315,7 +315,7 @@ void cris_mmu_flush_pid(CPUState *env, uint32_t pid) | @@ -315,7 +315,7 @@ void cris_mmu_flush_pid(CPUState *env, uint32_t pid) | ||
315 | 315 | ||
316 | /* Kernel protected areas need to be flushed | 316 | /* Kernel protected areas need to be flushed |
317 | as well. */ | 317 | as well. */ |
318 | - if (tlb_v && !tlb_g) { | 318 | + if (tlb_v && !tlb_g && (tlb_pid == pid || tlb_k)) { |
319 | vaddr = tlb_vpn << TARGET_PAGE_BITS; | 319 | vaddr = tlb_vpn << TARGET_PAGE_BITS; |
320 | D(fprintf(logfile, | 320 | D(fprintf(logfile, |
321 | "flush pid=%x vaddr=%x\n", | 321 | "flush pid=%x vaddr=%x\n", |
target-cris/op_helper.c
@@ -91,7 +91,9 @@ void helper_raise_exception(uint32_t index) | @@ -91,7 +91,9 @@ void helper_raise_exception(uint32_t index) | ||
91 | void helper_tlb_flush_pid(uint32_t pid) | 91 | void helper_tlb_flush_pid(uint32_t pid) |
92 | { | 92 | { |
93 | #if !defined(CONFIG_USER_ONLY) | 93 | #if !defined(CONFIG_USER_ONLY) |
94 | - cris_mmu_flush_pid(env, pid); | 94 | + pid &= 0xff; |
95 | + if (pid != (env->pregs[PR_PID] & 0xff)) | ||
96 | + cris_mmu_flush_pid(env, env->pregs[PR_PID]); | ||
95 | #endif | 97 | #endif |
96 | } | 98 | } |
97 | 99 | ||
@@ -100,11 +102,6 @@ void helper_dump(uint32_t a0, uint32_t a1, uint32_t a2) | @@ -100,11 +102,6 @@ void helper_dump(uint32_t a0, uint32_t a1, uint32_t a2) | ||
100 | (fprintf(logfile, "%s: a0=%x a1=%x\n", __func__, a0, a1)); | 102 | (fprintf(logfile, "%s: a0=%x a1=%x\n", __func__, a0, a1)); |
101 | } | 103 | } |
102 | 104 | ||
103 | -void helper_dummy(void) | ||
104 | -{ | ||
105 | - | ||
106 | -} | ||
107 | - | ||
108 | /* Used by the tlb decoder. */ | 105 | /* Used by the tlb decoder. */ |
109 | #define EXTRACT_FIELD(src, start, end) \ | 106 | #define EXTRACT_FIELD(src, start, end) \ |
110 | (((src) >> start) & ((1 << (end - start + 1)) - 1)) | 107 | (((src) >> start) & ((1 << (end - start + 1)) - 1)) |
@@ -239,15 +236,6 @@ void helper_rfn(void) | @@ -239,15 +236,6 @@ void helper_rfn(void) | ||
239 | env->pregs[PR_CCS] |= M_FLAG; | 236 | env->pregs[PR_CCS] |= M_FLAG; |
240 | } | 237 | } |
241 | 238 | ||
242 | -void helper_store(uint32_t a0) | ||
243 | -{ | ||
244 | - if (env->pregs[PR_CCS] & P_FLAG ) | ||
245 | - { | ||
246 | - cpu_abort(env, "cond_store_failed! pc=%x a0=%x\n", | ||
247 | - env->pc, a0); | ||
248 | - } | ||
249 | -} | ||
250 | - | ||
251 | void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, | 239 | void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, |
252 | int is_asi) | 240 | int is_asi) |
253 | { | 241 | { |
target-cris/translate.c
@@ -216,11 +216,11 @@ static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn) | @@ -216,11 +216,11 @@ static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn) | ||
216 | else if (r == PR_SRS) | 216 | else if (r == PR_SRS) |
217 | tcg_gen_andi_tl(cpu_PR[r], tn, 3); | 217 | tcg_gen_andi_tl(cpu_PR[r], tn, 3); |
218 | else { | 218 | else { |
219 | - tcg_gen_mov_tl(cpu_PR[r], tn); | ||
220 | if (r == PR_PID) | 219 | if (r == PR_PID) |
221 | tcg_gen_helper_0_1(helper_tlb_flush_pid, tn); | 220 | tcg_gen_helper_0_1(helper_tlb_flush_pid, tn); |
222 | else if (r == PR_CCS) | 221 | else if (r == PR_CCS) |
223 | dc->cpustate_changed = 1; | 222 | dc->cpustate_changed = 1; |
223 | + tcg_gen_mov_tl(cpu_PR[r], tn); | ||
224 | } | 224 | } |
225 | } | 225 | } |
226 | 226 | ||
@@ -1223,9 +1223,12 @@ void gen_load(DisasContext *dc, TCGv dst, TCGv addr, | @@ -1223,9 +1223,12 @@ void gen_load(DisasContext *dc, TCGv dst, TCGv addr, | ||
1223 | else | 1223 | else |
1224 | tcg_gen_qemu_ld16u(dst, addr, mem_index); | 1224 | tcg_gen_qemu_ld16u(dst, addr, mem_index); |
1225 | } | 1225 | } |
1226 | - else { | 1226 | + else if (size == 4) { |
1227 | tcg_gen_qemu_ld32u(dst, addr, mem_index); | 1227 | tcg_gen_qemu_ld32u(dst, addr, mem_index); |
1228 | } | 1228 | } |
1229 | + else if (size == 8) { | ||
1230 | + tcg_gen_qemu_ld64(dst, addr, mem_index); | ||
1231 | + } | ||
1229 | } | 1232 | } |
1230 | 1233 | ||
1231 | void gen_store (DisasContext *dc, TCGv addr, TCGv val, | 1234 | void gen_store (DisasContext *dc, TCGv addr, TCGv val, |
@@ -1248,7 +1251,6 @@ void gen_store (DisasContext *dc, TCGv addr, TCGv val, | @@ -1248,7 +1251,6 @@ void gen_store (DisasContext *dc, TCGv addr, TCGv val, | ||
1248 | return; | 1251 | return; |
1249 | } | 1252 | } |
1250 | 1253 | ||
1251 | - /* Remember, operands are flipped. CRIS has reversed order. */ | ||
1252 | if (size == 1) | 1254 | if (size == 1) |
1253 | tcg_gen_qemu_st8(val, addr, mem_index); | 1255 | tcg_gen_qemu_st8(val, addr, mem_index); |
1254 | else if (size == 2) | 1256 | else if (size == 2) |
@@ -2548,27 +2550,38 @@ static unsigned int dec_movem_mr(DisasContext *dc) | @@ -2548,27 +2550,38 @@ static unsigned int dec_movem_mr(DisasContext *dc) | ||
2548 | { | 2550 | { |
2549 | TCGv tmp[16]; | 2551 | TCGv tmp[16]; |
2550 | int i; | 2552 | int i; |
2553 | + int nr = dc->op2 + 1; | ||
2551 | 2554 | ||
2552 | DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1, | 2555 | DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1, |
2553 | dc->postinc ? "+]" : "]", dc->op2)); | 2556 | dc->postinc ? "+]" : "]", dc->op2)); |
2554 | 2557 | ||
2555 | - /* fetch the address into T0 and T1. */ | 2558 | + /* There are probably better ways of doing this. */ |
2556 | cris_flush_cc_state(dc); | 2559 | cris_flush_cc_state(dc); |
2557 | - for (i = 0; i <= dc->op2; i++) { | ||
2558 | - tmp[i] = tcg_temp_new(TCG_TYPE_TL); | ||
2559 | - /* Perform the load onto regnum i. Always dword wide. */ | ||
2560 | - tcg_gen_addi_tl(cpu_T[0], cpu_R[dc->op1], i * 4); | 2560 | + for (i = 0; i < (nr >> 1); i++) { |
2561 | + tmp[i] = tcg_temp_new(TCG_TYPE_I64); | ||
2562 | + tcg_gen_addi_tl(cpu_T[0], cpu_R[dc->op1], i * 8); | ||
2563 | + gen_load(dc, tmp[i], cpu_T[0], 8, 0); | ||
2564 | + } | ||
2565 | + if (nr & 1) { | ||
2566 | + tmp[i] = tcg_temp_new(TCG_TYPE_I32); | ||
2567 | + tcg_gen_addi_tl(cpu_T[0], cpu_R[dc->op1], i * 8); | ||
2561 | gen_load(dc, tmp[i], cpu_T[0], 4, 0); | 2568 | gen_load(dc, tmp[i], cpu_T[0], 4, 0); |
2562 | } | 2569 | } |
2563 | 2570 | ||
2564 | - for (i = 0; i <= dc->op2; i++) { | ||
2565 | - tcg_gen_mov_tl(cpu_R[i], tmp[i]); | 2571 | + for (i = 0; i < (nr >> 1); i++) { |
2572 | + tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]); | ||
2573 | + tcg_gen_shri_i64(tmp[i], tmp[i], 32); | ||
2574 | + tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]); | ||
2575 | + tcg_temp_free(tmp[i]); | ||
2576 | + } | ||
2577 | + if (nr & 1) { | ||
2578 | + tcg_gen_mov_tl(cpu_R[dc->op2], tmp[i]); | ||
2566 | tcg_temp_free(tmp[i]); | 2579 | tcg_temp_free(tmp[i]); |
2567 | } | 2580 | } |
2568 | 2581 | ||
2569 | /* writeback the updated pointer value. */ | 2582 | /* writeback the updated pointer value. */ |
2570 | if (dc->postinc) | 2583 | if (dc->postinc) |
2571 | - tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], i * 4); | 2584 | + tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4); |
2572 | 2585 | ||
2573 | /* gen_load might want to evaluate the previous insns flags. */ | 2586 | /* gen_load might want to evaluate the previous insns flags. */ |
2574 | cris_cc_mask(dc, 0); | 2587 | cris_cc_mask(dc, 0); |
@@ -2948,6 +2961,9 @@ cris_decoder(DisasContext *dc) | @@ -2948,6 +2961,9 @@ cris_decoder(DisasContext *dc) | ||
2948 | unsigned int insn_len = 2; | 2961 | unsigned int insn_len = 2; |
2949 | int i; | 2962 | int i; |
2950 | 2963 | ||
2964 | + if (unlikely(loglevel & CPU_LOG_TB_OP)) | ||
2965 | + tcg_gen_debug_insn_start(dc->pc); | ||
2966 | + | ||
2951 | /* Load a halfword onto the instruction register. */ | 2967 | /* Load a halfword onto the instruction register. */ |
2952 | dc->ir = lduw_code(dc->pc); | 2968 | dc->ir = lduw_code(dc->pc); |
2953 | 2969 | ||
@@ -3131,9 +3147,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, | @@ -3131,9 +3147,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, | ||
3131 | if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) | 3147 | if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) |
3132 | gen_io_start(); | 3148 | gen_io_start(); |
3133 | dc->clear_x = 1; | 3149 | dc->clear_x = 1; |
3134 | - if (unlikely(loglevel & CPU_LOG_TB_OP)) | ||
3135 | - tcg_gen_debug_insn_start(dc->pc); | ||
3136 | - insn_len = cris_decoder(dc); | 3150 | + |
3151 | + insn_len = cris_decoder(dc); | ||
3137 | dc->ppc = dc->pc; | 3152 | dc->ppc = dc->pc; |
3138 | dc->pc += insn_len; | 3153 | dc->pc += insn_len; |
3139 | if (dc->clear_x) | 3154 | if (dc->clear_x) |
@@ -3357,9 +3372,7 @@ CPUCRISState *cpu_cris_init (const char *cpu_model) | @@ -3357,9 +3372,7 @@ CPUCRISState *cpu_cris_init (const char *cpu_model) | ||
3357 | } | 3372 | } |
3358 | 3373 | ||
3359 | TCG_HELPER(helper_raise_exception); | 3374 | TCG_HELPER(helper_raise_exception); |
3360 | - TCG_HELPER(helper_store); | ||
3361 | TCG_HELPER(helper_dump); | 3375 | TCG_HELPER(helper_dump); |
3362 | - TCG_HELPER(helper_dummy); | ||
3363 | 3376 | ||
3364 | TCG_HELPER(helper_tlb_flush_pid); | 3377 | TCG_HELPER(helper_tlb_flush_pid); |
3365 | TCG_HELPER(helper_movl_sreg_reg); | 3378 | TCG_HELPER(helper_movl_sreg_reg); |