CRIS: Segmented addressing only for kernel mode.
authorEdgar E. Iglesias <edgar.iglesias@gmail.com>
Sat, 10 Oct 2009 15:34:27 +0000 (17:34 +0200)
committerEdgar E. Iglesias <edgar.iglesias@gmail.com>
Sat, 10 Oct 2009 15:34:27 +0000 (17:34 +0200)
Segmented translation through the CRIS MMU is only done for
accesses in kernel mode. In user-mode, all accesses are treated
as paged regardless of the mode config in RW_MM_CFG.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
target-cris/helper.c
target-cris/mmu.c

index a12ac10ee00151b82667207daa10ea59c8fae082..ff4f2fe1da57c1aa06d7191f62a5cd9de69323bd 100644 (file)
@@ -172,8 +172,6 @@ void do_interrupt(CPUState *env)
                env->dslot = 0;
        }
        
-       env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4);
-
        if (env->pregs[PR_CCS] & U_FLAG) {
                /* Swap stack pointers.  */
                env->pregs[PR_USP] = env->regs[R_SP];
@@ -182,6 +180,10 @@ void do_interrupt(CPUState *env)
 
        /* Apply the CRIS CCS shift. Clears U if set.  */
        cris_shift_ccs(env);
+
+       /* Now that we are in kernel mode, load the handlers address.  */
+       env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4);
+
        D_LOG("%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n", 
                   __func__, env->pc, ex_vec, 
                   env->pregs[PR_CCS],
index bc5b7105d1af62e307d3d3fd2c7c290004903625..b6892bbbf29d38eb3765d7a6f5fc0b1d60078703 100644 (file)
@@ -345,7 +345,7 @@ int cris_mmu_translate(struct cris_mmu_result *res,
        }
 
        seg = vaddr >> 28;
-       if (cris_mmu_segmented_addr(seg, env->sregs[SFR_RW_MM_CFG]))
+       if (!is_user && cris_mmu_segmented_addr(seg, env->sregs[SFR_RW_MM_CFG]))
        {
                uint32_t base;