Commit 28de16da38f20b3fe76fa80d10561c3a998342e2

Authored by edgar_igl
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
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);
... ...