qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [5302] CRIS: Improve ASID related TLB flushes.


From: Edgar E. Iglesias
Subject: [Qemu-devel] [5302] CRIS: Improve ASID related TLB flushes.
Date: Mon, 22 Sep 2008 20:51:28 +0000

Revision: 5302
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5302
Author:   edgar_igl
Date:     2008-09-22 20:51:28 +0000 (Mon, 22 Sep 2008)

Log Message:
-----------
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 <address@hidden>

Modified Paths:
--------------
    trunk/target-cris/helper.h
    trunk/target-cris/mmu.c
    trunk/target-cris/op_helper.c
    trunk/target-cris/translate.c

Modified: trunk/target-cris/helper.h
===================================================================
--- trunk/target-cris/helper.h  2008-09-22 20:41:57 UTC (rev 5301)
+++ trunk/target-cris/helper.h  2008-09-22 20:51:28 UTC (rev 5302)
@@ -3,10 +3,8 @@
 void TCG_HELPER_PROTO helper_raise_exception(uint32_t index);
 void TCG_HELPER_PROTO helper_tlb_flush_pid(uint32_t pid);
 void TCG_HELPER_PROTO helper_dump(uint32_t a0, uint32_t a1, uint32_t a2);
-void TCG_HELPER_PROTO helper_dummy(void);
 void TCG_HELPER_PROTO helper_rfe(void);
 void TCG_HELPER_PROTO helper_rfn(void);
-void TCG_HELPER_PROTO helper_store(uint32_t a0);
 
 void TCG_HELPER_PROTO helper_movl_sreg_reg (uint32_t sreg, uint32_t reg);
 void TCG_HELPER_PROTO helper_movl_reg_sreg (uint32_t reg, uint32_t sreg);

Modified: trunk/target-cris/mmu.c
===================================================================
--- trunk/target-cris/mmu.c     2008-09-22 20:41:57 UTC (rev 5301)
+++ trunk/target-cris/mmu.c     2008-09-22 20:51:28 UTC (rev 5302)
@@ -140,7 +140,7 @@
 
        r_cause = env->sregs[SFR_R_MM_CAUSE];
        r_cfg = env->sregs[SFR_RW_MM_CFG];
-       pid = env->pregs[PR_PID];
+       pid = env->pregs[PR_PID] & 0xff;
 
        switch (rw) {
                case 2: rwcause = CRIS_MMU_ERR_EXEC; mmu = 0; break;
@@ -270,7 +270,7 @@
                /* Update RW_MM_CAUSE.  */
                set_field(&r_cause, rwcause, 8, 2);
                set_field(&r_cause, vpage, 13, 19);
-               set_field(&r_cause, env->pregs[PR_PID], 0, 8);
+               set_field(&r_cause, pid, 0, 8);
                env->sregs[SFR_R_MM_CAUSE] = r_cause;
                D(printf("refill vaddr=%x pc=%x\n", vaddr, env->pc));
        }
@@ -280,7 +280,7 @@
                  __func__, rw, match, env->pc,
                  vaddr, vpage,
                  tlb_vpn, tlb_pfn, tlb_pid, 
-                 env->pregs[PR_PID],
+                 pid,
                  r_cause,
                  env->sregs[SFR_RW_MM_TLB_SEL],
                  env->regs[R_SP], env->pregs[PR_USP], env->ksp));
@@ -315,7 +315,7 @@
 
                                /* Kernel protected areas need to be flushed
                                   as well.  */
-                               if (tlb_v && !tlb_g) {
+                               if (tlb_v && !tlb_g && (tlb_pid == pid || 
tlb_k)) {
                                        vaddr = tlb_vpn << TARGET_PAGE_BITS;
                                        D(fprintf(logfile,
                                                  "flush pid=%x vaddr=%x\n", 

Modified: trunk/target-cris/op_helper.c
===================================================================
--- trunk/target-cris/op_helper.c       2008-09-22 20:41:57 UTC (rev 5301)
+++ trunk/target-cris/op_helper.c       2008-09-22 20:51:28 UTC (rev 5302)
@@ -91,7 +91,9 @@
 void helper_tlb_flush_pid(uint32_t pid)
 {
 #if !defined(CONFIG_USER_ONLY)
-       cris_mmu_flush_pid(env, pid);
+       pid &= 0xff;
+       if (pid != (env->pregs[PR_PID] & 0xff))
+               cris_mmu_flush_pid(env, env->pregs[PR_PID]);
 #endif
 }
 
@@ -100,11 +102,6 @@
        (fprintf(logfile, "%s: a0=%x a1=%x\n", __func__, a0, a1)); 
 }
 
-void helper_dummy(void)
-{
-
-}
-
 /* Used by the tlb decoder.  */
 #define EXTRACT_FIELD(src, start, end) \
            (((src) >> start) & ((1 << (end - start + 1)) - 1))
@@ -239,15 +236,6 @@
     env->pregs[PR_CCS] |= M_FLAG;
 }
 
-void helper_store(uint32_t a0)
-{
-       if (env->pregs[PR_CCS] & P_FLAG )
-       {
-               cpu_abort(env, "cond_store_failed! pc=%x a0=%x\n",
-                         env->pc, a0);
-       }
-}
-
 void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
                           int is_asi)
 {

Modified: trunk/target-cris/translate.c
===================================================================
--- trunk/target-cris/translate.c       2008-09-22 20:41:57 UTC (rev 5301)
+++ trunk/target-cris/translate.c       2008-09-22 20:51:28 UTC (rev 5302)
@@ -216,11 +216,11 @@
        else if (r == PR_SRS)
                tcg_gen_andi_tl(cpu_PR[r], tn, 3);
        else {
-               tcg_gen_mov_tl(cpu_PR[r], tn);
                if (r == PR_PID) 
                        tcg_gen_helper_0_1(helper_tlb_flush_pid, tn);
                else if (r == PR_CCS)
                        dc->cpustate_changed = 1;
+               tcg_gen_mov_tl(cpu_PR[r], tn);
        }
 }
 
@@ -1223,9 +1223,12 @@
                else
                        tcg_gen_qemu_ld16u(dst, addr, mem_index);
        }
-       else {
+       else if (size == 4) {
                tcg_gen_qemu_ld32u(dst, addr, mem_index);
        }
+       else if (size == 8) {
+               tcg_gen_qemu_ld64(dst, addr, mem_index);
+       }
 }
 
 void gen_store (DisasContext *dc, TCGv addr, TCGv val,
@@ -1248,7 +1251,6 @@
                return;
        }
 
-       /* Remember, operands are flipped. CRIS has reversed order.  */
        if (size == 1)
                tcg_gen_qemu_st8(val, addr, mem_index);
        else if (size == 2)
@@ -2548,27 +2550,38 @@
 {
        TCGv tmp[16];
        int i;
+       int nr = dc->op2 + 1;
 
        DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1,
                    dc->postinc ? "+]" : "]", dc->op2));
 
-       /* fetch the address into T0 and T1.  */
+       /* There are probably better ways of doing this.  */
        cris_flush_cc_state(dc);
-       for (i = 0; i <= dc->op2; i++) {
-               tmp[i] = tcg_temp_new(TCG_TYPE_TL);
-               /* Perform the load onto regnum i. Always dword wide.  */
-               tcg_gen_addi_tl(cpu_T[0], cpu_R[dc->op1], i * 4);
+       for (i = 0; i < (nr >> 1); i++) {
+               tmp[i] = tcg_temp_new(TCG_TYPE_I64);
+               tcg_gen_addi_tl(cpu_T[0], cpu_R[dc->op1], i * 8);
+               gen_load(dc, tmp[i], cpu_T[0], 8, 0);
+       }
+       if (nr & 1) {
+               tmp[i] = tcg_temp_new(TCG_TYPE_I32);
+               tcg_gen_addi_tl(cpu_T[0], cpu_R[dc->op1], i * 8);
                gen_load(dc, tmp[i], cpu_T[0], 4, 0);
        }
 
-       for (i = 0; i <= dc->op2; i++) {
-               tcg_gen_mov_tl(cpu_R[i], tmp[i]);
+       for (i = 0; i < (nr >> 1); i++) {
+               tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]);
+               tcg_gen_shri_i64(tmp[i], tmp[i], 32);
+               tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
                tcg_temp_free(tmp[i]);
        }
+       if (nr & 1) {
+               tcg_gen_mov_tl(cpu_R[dc->op2], tmp[i]);
+               tcg_temp_free(tmp[i]);
+       }
 
        /* writeback the updated pointer value.  */
        if (dc->postinc)
-               tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], i * 4);
+               tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);
 
        /* gen_load might want to evaluate the previous insns flags.  */
        cris_cc_mask(dc, 0);
@@ -2948,6 +2961,9 @@
        unsigned int insn_len = 2;
        int i;
 
+       if (unlikely(loglevel & CPU_LOG_TB_OP))
+               tcg_gen_debug_insn_start(dc->pc);
+
        /* Load a halfword onto the instruction register.  */
        dc->ir = lduw_code(dc->pc);
 
@@ -3131,9 +3147,8 @@
                 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
                     gen_io_start();
                dc->clear_x = 1;
-               if (unlikely(loglevel & CPU_LOG_TB_OP))
-                       tcg_gen_debug_insn_start(dc->pc);
-               insn_len = cris_decoder(dc);
+
+               insn_len = cris_decoder(dc);            
                dc->ppc = dc->pc;
                dc->pc += insn_len;
                if (dc->clear_x)
@@ -3357,9 +3372,7 @@
        }
 
        TCG_HELPER(helper_raise_exception);
-       TCG_HELPER(helper_store);
        TCG_HELPER(helper_dump);
-       TCG_HELPER(helper_dummy);
 
        TCG_HELPER(helper_tlb_flush_pid);
        TCG_HELPER(helper_movl_sreg_reg);






reply via email to

[Prev in Thread] Current Thread [Next in Thread]