CRIS: Emulate NMIs.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4719 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
edgar_igl 2008-06-09 23:18:06 +00:00
parent 5bf8f1aba1
commit 1b1a38b0aa
3 changed files with 28 additions and 16 deletions

View File

@ -501,7 +501,15 @@ int cpu_exec(CPUState *env1)
next_tb = 0; next_tb = 0;
} }
#elif defined(TARGET_CRIS) #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); do_interrupt(env);
next_tb = 0; next_tb = 0;
} }

View File

@ -29,12 +29,11 @@
#define ELF_MACHINE EM_CRIS #define ELF_MACHINE EM_CRIS
#define EXCP_MMU_EXEC 0 #define EXCP_NMI 1
#define EXCP_MMU_READ 1 #define EXCP_GURU 2
#define EXCP_MMU_WRITE 2 #define EXCP_BUSFAULT 3
#define EXCP_MMU_FLUSH 3 #define EXCP_IRQ 4
#define EXCP_MMU_FAULT 4 #define EXCP_BREAK 5
#define EXCP_BREAK 16 /* trap. */
/* Register aliases. R0 - R15 */ /* Register aliases. R0 - R15 */
#define R_FP 8 #define R_FP 8
@ -54,11 +53,14 @@
#define PR_EBP 9 #define PR_EBP 9
#define PR_ERP 10 #define PR_ERP 10
#define PR_SRP 11 #define PR_SRP 11
#define PR_NRP 12
#define PR_CCS 13 #define PR_CCS 13
#define PR_USP 14 #define PR_USP 14
#define PR_SPC 15 #define PR_SPC 15
/* CPU flags. */ /* CPU flags. */
#define Q_FLAG 0x80000000
#define M_FLAG 0x40000000
#define S_FLAG 0x200 #define S_FLAG 0x200
#define R_FLAG 0x100 #define R_FLAG 0x100
#define P_FLAG 0x80 #define P_FLAG 0x80
@ -154,7 +156,6 @@ typedef struct CPUCRISState {
uint32_t lo; uint32_t lo;
} tlbsets[2][4][16]; } tlbsets[2][4][16];
int features;
int user_mode_only; int user_mode_only;
CPU_COMMON CPU_COMMON

View File

@ -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); miss = cris_mmu_translate(&res, env, address, rw, mmu_idx);
if (miss) if (miss)
{ {
if (env->exception_index == EXCP_MMU_FAULT) if (env->exception_index == EXCP_BUSFAULT)
cpu_abort(env, cpu_abort(env,
"CRIS: Illegal recursive bus fault." "CRIS: Illegal recursive bus fault."
"addr=%x rw=%d\n", "addr=%x rw=%d\n",
address, rw); address, rw);
env->exception_index = EXCP_MMU_FAULT; env->exception_index = EXCP_BUSFAULT;
env->fault_vector = res.bf_vec; env->fault_vector = res.bf_vec;
r = 1; r = 1;
} }
@ -120,17 +120,20 @@ void do_interrupt(CPUState *env)
env->pregs[PR_ERP] = env->pc + 2; env->pregs[PR_ERP] = env->pc + 2;
break; 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; ex_vec = env->fault_vector;
env->pregs[PR_ERP] = env->pc; env->pregs[PR_ERP] = env->pc;
break; break;
default: default:
/* Is the core accepting interrupts? */ /* The interrupt controller gives us the vector. */
if (!(env->pregs[PR_CCS] & I_FLAG))
return;
/* The interrupt controller gives us the
vector. */
ex_vec = env->interrupt_vector; ex_vec = env->interrupt_vector;
/* Normal interrupts are taken between /* Normal interrupts are taken between
TB's. env->pc is valid here. */ TB's. env->pc is valid here. */