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,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);