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 | 3 | void TCG_HELPER_PROTO helper_raise_exception(uint32_t index); |
4 | 4 | void TCG_HELPER_PROTO helper_tlb_flush_pid(uint32_t pid); |
5 | 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 | 6 | void TCG_HELPER_PROTO helper_rfe(void); |
8 | 7 | void TCG_HELPER_PROTO helper_rfn(void); |
9 | -void TCG_HELPER_PROTO helper_store(uint32_t a0); | |
10 | 8 | |
11 | 9 | void TCG_HELPER_PROTO helper_movl_sreg_reg (uint32_t sreg, uint32_t reg); |
12 | 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 | 140 | |
141 | 141 | r_cause = env->sregs[SFR_R_MM_CAUSE]; |
142 | 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 | 145 | switch (rw) { |
146 | 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 | 270 | /* Update RW_MM_CAUSE. */ |
271 | 271 | set_field(&r_cause, rwcause, 8, 2); |
272 | 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 | 274 | env->sregs[SFR_R_MM_CAUSE] = r_cause; |
275 | 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 | 280 | __func__, rw, match, env->pc, |
281 | 281 | vaddr, vpage, |
282 | 282 | tlb_vpn, tlb_pfn, tlb_pid, |
283 | - env->pregs[PR_PID], | |
283 | + pid, | |
284 | 284 | r_cause, |
285 | 285 | env->sregs[SFR_RW_MM_TLB_SEL], |
286 | 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 | 315 | |
316 | 316 | /* Kernel protected areas need to be flushed |
317 | 317 | as well. */ |
318 | - if (tlb_v && !tlb_g) { | |
318 | + if (tlb_v && !tlb_g && (tlb_pid == pid || tlb_k)) { | |
319 | 319 | vaddr = tlb_vpn << TARGET_PAGE_BITS; |
320 | 320 | D(fprintf(logfile, |
321 | 321 | "flush pid=%x vaddr=%x\n", | ... | ... |
target-cris/op_helper.c
... | ... | @@ -91,7 +91,9 @@ void helper_raise_exception(uint32_t index) |
91 | 91 | void helper_tlb_flush_pid(uint32_t pid) |
92 | 92 | { |
93 | 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 | 97 | #endif |
96 | 98 | } |
97 | 99 | |
... | ... | @@ -100,11 +102,6 @@ void helper_dump(uint32_t a0, uint32_t a1, uint32_t a2) |
100 | 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 | 105 | /* Used by the tlb decoder. */ |
109 | 106 | #define EXTRACT_FIELD(src, start, end) \ |
110 | 107 | (((src) >> start) & ((1 << (end - start + 1)) - 1)) |
... | ... | @@ -239,15 +236,6 @@ void helper_rfn(void) |
239 | 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 | 239 | void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, |
252 | 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 | 216 | else if (r == PR_SRS) |
217 | 217 | tcg_gen_andi_tl(cpu_PR[r], tn, 3); |
218 | 218 | else { |
219 | - tcg_gen_mov_tl(cpu_PR[r], tn); | |
220 | 219 | if (r == PR_PID) |
221 | 220 | tcg_gen_helper_0_1(helper_tlb_flush_pid, tn); |
222 | 221 | else if (r == PR_CCS) |
223 | 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 | 1223 | else |
1224 | 1224 | tcg_gen_qemu_ld16u(dst, addr, mem_index); |
1225 | 1225 | } |
1226 | - else { | |
1226 | + else if (size == 4) { | |
1227 | 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 | 1234 | void gen_store (DisasContext *dc, TCGv addr, TCGv val, |
... | ... | @@ -1248,7 +1251,6 @@ void gen_store (DisasContext *dc, TCGv addr, TCGv val, |
1248 | 1251 | return; |
1249 | 1252 | } |
1250 | 1253 | |
1251 | - /* Remember, operands are flipped. CRIS has reversed order. */ | |
1252 | 1254 | if (size == 1) |
1253 | 1255 | tcg_gen_qemu_st8(val, addr, mem_index); |
1254 | 1256 | else if (size == 2) |
... | ... | @@ -2548,27 +2550,38 @@ static unsigned int dec_movem_mr(DisasContext *dc) |
2548 | 2550 | { |
2549 | 2551 | TCGv tmp[16]; |
2550 | 2552 | int i; |
2553 | + int nr = dc->op2 + 1; | |
2551 | 2554 | |
2552 | 2555 | DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1, |
2553 | 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 | 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 | 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 | 2579 | tcg_temp_free(tmp[i]); |
2567 | 2580 | } |
2568 | 2581 | |
2569 | 2582 | /* writeback the updated pointer value. */ |
2570 | 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 | 2586 | /* gen_load might want to evaluate the previous insns flags. */ |
2574 | 2587 | cris_cc_mask(dc, 0); |
... | ... | @@ -2948,6 +2961,9 @@ cris_decoder(DisasContext *dc) |
2948 | 2961 | unsigned int insn_len = 2; |
2949 | 2962 | int i; |
2950 | 2963 | |
2964 | + if (unlikely(loglevel & CPU_LOG_TB_OP)) | |
2965 | + tcg_gen_debug_insn_start(dc->pc); | |
2966 | + | |
2951 | 2967 | /* Load a halfword onto the instruction register. */ |
2952 | 2968 | dc->ir = lduw_code(dc->pc); |
2953 | 2969 | |
... | ... | @@ -3131,9 +3147,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, |
3131 | 3147 | if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) |
3132 | 3148 | gen_io_start(); |
3133 | 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 | 3152 | dc->ppc = dc->pc; |
3138 | 3153 | dc->pc += insn_len; |
3139 | 3154 | if (dc->clear_x) |
... | ... | @@ -3357,9 +3372,7 @@ CPUCRISState *cpu_cris_init (const char *cpu_model) |
3357 | 3372 | } |
3358 | 3373 | |
3359 | 3374 | TCG_HELPER(helper_raise_exception); |
3360 | - TCG_HELPER(helper_store); | |
3361 | 3375 | TCG_HELPER(helper_dump); |
3362 | - TCG_HELPER(helper_dummy); | |
3363 | 3376 | |
3364 | 3377 | TCG_HELPER(helper_tlb_flush_pid); |
3365 | 3378 | TCG_HELPER(helper_movl_sreg_reg); | ... | ... |