diff options
Diffstat (limited to 'target-cris')
-rw-r--r-- | target-cris/helper.c | 393 |
1 files changed, 196 insertions, 197 deletions
diff --git a/target-cris/helper.c b/target-cris/helper.c index 6e75e9819e..de04143da8 100644 --- a/target-cris/helper.c +++ b/target-cris/helper.c @@ -36,19 +36,19 @@ #if defined(CONFIG_USER_ONLY) -void do_interrupt (CPUCRISState *env) +void do_interrupt(CPUCRISState *env) { - env->exception_index = -1; - env->pregs[PR_ERP] = env->pc; + env->exception_index = -1; + env->pregs[PR_ERP] = env->pc; } int cpu_cris_handle_mmu_fault(CPUCRISState * env, target_ulong address, int rw, int mmu_idx) { - env->exception_index = 0xaa; - env->pregs[PR_EDA] = address; - cpu_dump_state(env, stderr, fprintf, 0); - return 1; + env->exception_index = 0xaa; + env->pregs[PR_EDA] = address; + cpu_dump_state(env, stderr, fprintf, 0); + return 1; } #else /* !CONFIG_USER_ONLY */ @@ -56,211 +56,210 @@ int cpu_cris_handle_mmu_fault(CPUCRISState * env, target_ulong address, int rw, static void cris_shift_ccs(CPUCRISState *env) { - uint32_t ccs; - /* Apply the ccs shift. */ - ccs = env->pregs[PR_CCS]; - ccs = ((ccs & 0xc0000000) | ((ccs << 12) >> 2)) & ~0x3ff; - env->pregs[PR_CCS] = ccs; + uint32_t ccs; + /* Apply the ccs shift. */ + ccs = env->pregs[PR_CCS]; + ccs = ((ccs & 0xc0000000) | ((ccs << 12) >> 2)) & ~0x3ff; + env->pregs[PR_CCS] = ccs; } -int cpu_cris_handle_mmu_fault (CPUCRISState *env, target_ulong address, int rw, - int mmu_idx) +int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw, + int mmu_idx) { - struct cris_mmu_result res; - int prot, miss; - int r = -1; - target_ulong phy; - - D(printf ("%s addr=%x pc=%x rw=%x\n", __func__, address, env->pc, rw)); - miss = cris_mmu_translate(&res, env, address & TARGET_PAGE_MASK, - rw, mmu_idx, 0); - if (miss) - { - if (env->exception_index == EXCP_BUSFAULT) - cpu_abort(env, - "CRIS: Illegal recursive bus fault." - "addr=%x rw=%d\n", - address, rw); - - env->pregs[PR_EDA] = address; - env->exception_index = EXCP_BUSFAULT; - env->fault_vector = res.bf_vec; - r = 1; - } - else - { - /* - * Mask off the cache selection bit. The ETRAX busses do not - * see the top bit. - */ - phy = res.phy & ~0x80000000; - prot = res.prot; - tlb_set_page(env, address & TARGET_PAGE_MASK, phy, - prot, mmu_idx, TARGET_PAGE_SIZE); - r = 0; - } - if (r > 0) - D_LOG("%s returns %d irqreq=%x addr=%x phy=%x vec=%x pc=%x\n", - __func__, r, env->interrupt_request, address, res.phy, - res.bf_vec, env->pc); - return r; + struct cris_mmu_result res; + int prot, miss; + int r = -1; + target_ulong phy; + + D(printf("%s addr=%x pc=%x rw=%x\n", __func__, address, env->pc, rw)); + miss = cris_mmu_translate(&res, env, address & TARGET_PAGE_MASK, + rw, mmu_idx, 0); + if (miss) { + if (env->exception_index == EXCP_BUSFAULT) { + cpu_abort(env, + "CRIS: Illegal recursive bus fault." + "addr=%x rw=%d\n", + address, rw); + } + + env->pregs[PR_EDA] = address; + env->exception_index = EXCP_BUSFAULT; + env->fault_vector = res.bf_vec; + r = 1; + } else { + /* + * Mask off the cache selection bit. The ETRAX busses do not + * see the top bit. + */ + phy = res.phy & ~0x80000000; + prot = res.prot; + tlb_set_page(env, address & TARGET_PAGE_MASK, phy, + prot, mmu_idx, TARGET_PAGE_SIZE); + r = 0; + } + if (r > 0) { + D_LOG("%s returns %d irqreq=%x addr=%x phy=%x vec=%x pc=%x\n", + __func__, r, env->interrupt_request, address, res.phy, + res.bf_vec, env->pc); + } + return r; } static void do_interruptv10(CPUCRISState *env) { - int ex_vec = -1; - - D_LOG( "exception index=%d interrupt_req=%d\n", - env->exception_index, - env->interrupt_request); - - assert(!(env->pregs[PR_CCS] & PFIX_FLAG)); - switch (env->exception_index) - { - case EXCP_BREAK: - /* These exceptions are genereated by the core itself. - ERP should point to the insn following the brk. */ - ex_vec = env->trap_vector; - env->pregs[PRV10_BRP] = env->pc; - break; - - case EXCP_NMI: - /* NMI is hardwired to vector zero. */ - ex_vec = 0; - env->pregs[PR_CCS] &= ~M_FLAG_V10; - env->pregs[PRV10_BRP] = env->pc; - break; - - case EXCP_BUSFAULT: - cpu_abort(env, "Unhandled busfault"); - break; - - default: - /* The interrupt controller gives us the vector. */ - ex_vec = env->interrupt_vector; - /* Normal interrupts are taken between - TB's. env->pc is valid here. */ - env->pregs[PR_ERP] = env->pc; - break; - } - - if (env->pregs[PR_CCS] & U_FLAG) { - /* Swap stack pointers. */ - env->pregs[PR_USP] = env->regs[R_SP]; - env->regs[R_SP] = env->ksp; - } - - /* Now that we are in kernel mode, load the handlers address. */ - env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4); - env->locked_irq = 1; - env->pregs[PR_CCS] |= F_FLAG_V10; /* set F. */ - - qemu_log_mask(CPU_LOG_INT, "%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n", - __func__, env->pc, ex_vec, - env->pregs[PR_CCS], - env->pregs[PR_PID], - env->pregs[PR_ERP]); + int ex_vec = -1; + + D_LOG("exception index=%d interrupt_req=%d\n", + env->exception_index, + env->interrupt_request); + + assert(!(env->pregs[PR_CCS] & PFIX_FLAG)); + switch (env->exception_index) { + case EXCP_BREAK: + /* These exceptions are genereated by the core itself. + ERP should point to the insn following the brk. */ + ex_vec = env->trap_vector; + env->pregs[PRV10_BRP] = env->pc; + break; + + case EXCP_NMI: + /* NMI is hardwired to vector zero. */ + ex_vec = 0; + env->pregs[PR_CCS] &= ~M_FLAG_V10; + env->pregs[PRV10_BRP] = env->pc; + break; + + case EXCP_BUSFAULT: + cpu_abort(env, "Unhandled busfault"); + break; + + default: + /* The interrupt controller gives us the vector. */ + ex_vec = env->interrupt_vector; + /* Normal interrupts are taken between + TB's. env->pc is valid here. */ + env->pregs[PR_ERP] = env->pc; + break; + } + + if (env->pregs[PR_CCS] & U_FLAG) { + /* Swap stack pointers. */ + env->pregs[PR_USP] = env->regs[R_SP]; + env->regs[R_SP] = env->ksp; + } + + /* Now that we are in kernel mode, load the handlers address. */ + env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4); + env->locked_irq = 1; + env->pregs[PR_CCS] |= F_FLAG_V10; /* set F. */ + + qemu_log_mask(CPU_LOG_INT, "%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n", + __func__, env->pc, ex_vec, + env->pregs[PR_CCS], + env->pregs[PR_PID], + env->pregs[PR_ERP]); } void do_interrupt(CPUCRISState *env) { - int ex_vec = -1; - - if (env->pregs[PR_VR] < 32) - return do_interruptv10(env); - - D_LOG( "exception index=%d interrupt_req=%d\n", - env->exception_index, - env->interrupt_request); - - switch (env->exception_index) - { - case EXCP_BREAK: - /* These exceptions are genereated by the core itself. - ERP should point to the insn following the brk. */ - ex_vec = env->trap_vector; - env->pregs[PR_ERP] = env->pc; - break; - - case EXCP_NMI: - /* NMI is hardwired to vector zero. */ - ex_vec = 0; - env->pregs[PR_CCS] &= ~M_FLAG_V32; - env->pregs[PR_NRP] = env->pc; - break; - - case EXCP_BUSFAULT: - ex_vec = env->fault_vector; - env->pregs[PR_ERP] = env->pc; - break; - - default: - /* The interrupt controller gives us the vector. */ - ex_vec = env->interrupt_vector; - /* Normal interrupts are taken between - TB's. env->pc is valid here. */ - env->pregs[PR_ERP] = env->pc; - break; - } - - /* Fill in the IDX field. */ - env->pregs[PR_EXS] = (ex_vec & 0xff) << 8; - - if (env->dslot) { - D_LOG("excp isr=%x PC=%x ds=%d SP=%x" - " ERP=%x pid=%x ccs=%x cc=%d %x\n", - ex_vec, env->pc, env->dslot, - env->regs[R_SP], - env->pregs[PR_ERP], env->pregs[PR_PID], - env->pregs[PR_CCS], - env->cc_op, env->cc_mask); - /* We loose the btarget, btaken state here so rexec the - branch. */ - env->pregs[PR_ERP] -= env->dslot; - /* Exception starts with dslot cleared. */ - env->dslot = 0; - } + int ex_vec = -1; + + if (env->pregs[PR_VR] < 32) { + return do_interruptv10(env); + } + + D_LOG("exception index=%d interrupt_req=%d\n", + env->exception_index, + env->interrupt_request); + + switch (env->exception_index) { + case EXCP_BREAK: + /* These exceptions are genereated by the core itself. + ERP should point to the insn following the brk. */ + ex_vec = env->trap_vector; + env->pregs[PR_ERP] = env->pc; + break; + + case EXCP_NMI: + /* NMI is hardwired to vector zero. */ + ex_vec = 0; + env->pregs[PR_CCS] &= ~M_FLAG_V32; + env->pregs[PR_NRP] = env->pc; + break; + + case EXCP_BUSFAULT: + ex_vec = env->fault_vector; + env->pregs[PR_ERP] = env->pc; + break; + + default: + /* The interrupt controller gives us the vector. */ + ex_vec = env->interrupt_vector; + /* Normal interrupts are taken between + TB's. env->pc is valid here. */ + env->pregs[PR_ERP] = env->pc; + break; + } + + /* Fill in the IDX field. */ + env->pregs[PR_EXS] = (ex_vec & 0xff) << 8; + + if (env->dslot) { + D_LOG("excp isr=%x PC=%x ds=%d SP=%x" + " ERP=%x pid=%x ccs=%x cc=%d %x\n", + ex_vec, env->pc, env->dslot, + env->regs[R_SP], + env->pregs[PR_ERP], env->pregs[PR_PID], + env->pregs[PR_CCS], + env->cc_op, env->cc_mask); + /* We loose the btarget, btaken state here so rexec the + branch. */ + env->pregs[PR_ERP] -= env->dslot; + /* Exception starts with dslot cleared. */ + env->dslot = 0; + } - if (env->pregs[PR_CCS] & U_FLAG) { - /* Swap stack pointers. */ - env->pregs[PR_USP] = env->regs[R_SP]; - env->regs[R_SP] = env->ksp; - } - - /* Apply the CRIS CCS shift. Clears U if set. */ - cris_shift_ccs(env); - - /* Now that we are in kernel mode, load the handlers address. - This load may not fault, real hw leaves that behaviour as - undefined. */ - env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4); - - /* Clear the excption_index to avoid spurios hw_aborts for recursive - bus faults. */ - env->exception_index = -1; - - D_LOG("%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n", - __func__, env->pc, ex_vec, - env->pregs[PR_CCS], - env->pregs[PR_PID], - env->pregs[PR_ERP]); + if (env->pregs[PR_CCS] & U_FLAG) { + /* Swap stack pointers. */ + env->pregs[PR_USP] = env->regs[R_SP]; + env->regs[R_SP] = env->ksp; + } + + /* Apply the CRIS CCS shift. Clears U if set. */ + cris_shift_ccs(env); + + /* Now that we are in kernel mode, load the handlers address. + This load may not fault, real hw leaves that behaviour as + undefined. */ + env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4); + + /* Clear the excption_index to avoid spurios hw_aborts for recursive + bus faults. */ + env->exception_index = -1; + + D_LOG("%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n", + __func__, env->pc, ex_vec, + env->pregs[PR_CCS], + env->pregs[PR_PID], + env->pregs[PR_ERP]); } hwaddr cpu_get_phys_page_debug(CPUCRISState * env, target_ulong addr) { - uint32_t phy = addr; - struct cris_mmu_result res; - int miss; - - miss = cris_mmu_translate(&res, env, addr, 0, 0, 1); - /* If D TLB misses, try I TLB. */ - if (miss) { - miss = cris_mmu_translate(&res, env, addr, 2, 0, 1); - } - - if (!miss) - phy = res.phy; - D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy)); - return phy; + uint32_t phy = addr; + struct cris_mmu_result res; + int miss; + + miss = cris_mmu_translate(&res, env, addr, 0, 0, 1); + /* If D TLB misses, try I TLB. */ + if (miss) { + miss = cris_mmu_translate(&res, env, addr, 2, 0, 1); + } + + if (!miss) { + phy = res.phy; + } + D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy)); + return phy; } #endif |