diff options
author | edgar_igl <edgar_igl@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-06-09 23:18:06 +0000 |
---|---|---|
committer | edgar_igl <edgar_igl@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-06-09 23:18:06 +0000 |
commit | 1b1a38b0aaf3a24b9b8162d8aef9e700a42f8d43 (patch) | |
tree | 1492c8dbf290afdd5fe16fb1437729671ef287ec | |
parent | 5bf8f1aba1ab727713edf4084e7bc841dd1e6732 (diff) |
CRIS: Emulate NMIs.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4719 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r-- | cpu-exec.c | 10 | ||||
-rw-r--r-- | target-cris/cpu.h | 15 | ||||
-rw-r--r-- | target-cris/helper.c | 19 |
3 files changed, 28 insertions, 16 deletions
diff --git a/cpu-exec.c b/cpu-exec.c index 3a1ff4e07..b8c208b41 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -501,7 +501,15 @@ int cpu_exec(CPUState *env1) next_tb = 0; } #elif defined(TARGET_CRIS) - if (interrupt_request & CPU_INTERRUPT_HARD) { + if (interrupt_request & CPU_INTERRUPT_HARD + && (env->pregs[PR_CCS] & I_FLAG)) { + env->exception_index = EXCP_IRQ; + do_interrupt(env); + next_tb = 0; + } + if (interrupt_request & CPU_INTERRUPT_NMI + && (env->pregs[PR_CCS] & M_FLAG)) { + env->exception_index = EXCP_NMI; do_interrupt(env); next_tb = 0; } diff --git a/target-cris/cpu.h b/target-cris/cpu.h index a4f016f12..447e780b2 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -29,12 +29,11 @@ #define ELF_MACHINE EM_CRIS -#define EXCP_MMU_EXEC 0 -#define EXCP_MMU_READ 1 -#define EXCP_MMU_WRITE 2 -#define EXCP_MMU_FLUSH 3 -#define EXCP_MMU_FAULT 4 -#define EXCP_BREAK 16 /* trap. */ +#define EXCP_NMI 1 +#define EXCP_GURU 2 +#define EXCP_BUSFAULT 3 +#define EXCP_IRQ 4 +#define EXCP_BREAK 5 /* Register aliases. R0 - R15 */ #define R_FP 8 @@ -54,11 +53,14 @@ #define PR_EBP 9 #define PR_ERP 10 #define PR_SRP 11 +#define PR_NRP 12 #define PR_CCS 13 #define PR_USP 14 #define PR_SPC 15 /* CPU flags. */ +#define Q_FLAG 0x80000000 +#define M_FLAG 0x40000000 #define S_FLAG 0x200 #define R_FLAG 0x100 #define P_FLAG 0x80 @@ -154,7 +156,6 @@ typedef struct CPUCRISState { uint32_t lo; } tlbsets[2][4][16]; - int features; int user_mode_only; CPU_COMMON diff --git a/target-cris/helper.c b/target-cris/helper.c index c16a58a3b..a29e55c05 100644 --- a/target-cris/helper.c +++ b/target-cris/helper.c @@ -78,13 +78,13 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, miss = cris_mmu_translate(&res, env, address, rw, mmu_idx); if (miss) { - if (env->exception_index == EXCP_MMU_FAULT) + if (env->exception_index == EXCP_BUSFAULT) cpu_abort(env, "CRIS: Illegal recursive bus fault." "addr=%x rw=%d\n", address, rw); - env->exception_index = EXCP_MMU_FAULT; + env->exception_index = EXCP_BUSFAULT; env->fault_vector = res.bf_vec; r = 1; } @@ -120,17 +120,20 @@ void do_interrupt(CPUState *env) env->pregs[PR_ERP] = env->pc + 2; break; - case EXCP_MMU_FAULT: + case EXCP_NMI: + /* NMI is hardwired to vector zero. */ + ex_vec = 0; + env->pregs[PR_CCS] &= ~M_FLAG; + env->pregs[PR_NRP] = env->pc; + break; + + case EXCP_BUSFAULT: ex_vec = env->fault_vector; env->pregs[PR_ERP] = env->pc; break; default: - /* Is the core accepting interrupts? */ - if (!(env->pregs[PR_CCS] & I_FLAG)) - return; - /* The interrupt controller gives us the - vector. */ + /* The interrupt controller gives us the vector. */ ex_vec = env->interrupt_vector; /* Normal interrupts are taken between TB's. env->pc is valid here. */ |