提交 da52a4df 编写于 作者: Y Yongbok Kim 提交者: Leon Alrae

target-mips: fix offset calculation for Interrupts

Correct computation of vector offsets for EXCP_EXT_INTERRUPT.
For instance, if Cause.IV is 0 the vector offset should be 0x180.

Simplify the finding vector number logic for the Vectored Interrupts.
Signed-off-by: NYongbok Kim <yongbok.kim@imgtec.com>
Reviewed-by: NLeon Alrae <leon.alrae@imgtec.com>
[leon.alrae@imgtec.com: cosmetic changes]
Signed-off-by: NLeon Alrae <leon.alrae@imgtec.com>
上级 8bcbb834
...@@ -565,34 +565,30 @@ void mips_cpu_do_interrupt(CPUState *cs) ...@@ -565,34 +565,30 @@ void mips_cpu_do_interrupt(CPUState *cs)
break; break;
case EXCP_EXT_INTERRUPT: case EXCP_EXT_INTERRUPT:
cause = 0; cause = 0;
if (env->CP0_Cause & (1 << CP0Ca_IV)) if (env->CP0_Cause & (1 << CP0Ca_IV)) {
offset = 0x200; uint32_t spacing = (env->CP0_IntCtl >> CP0IntCtl_VS) & 0x1f;
if (env->CP0_Config3 & ((1 << CP0C3_VInt) | (1 << CP0C3_VEIC))) { if ((env->CP0_Status & (1 << CP0St_BEV)) || spacing == 0) {
/* Vectored Interrupts. */ offset = 0x200;
unsigned int spacing; } else {
unsigned int vector; uint32_t vector = 0;
unsigned int pending = (env->CP0_Cause & CP0Ca_IP_mask) >> 8; uint32_t pending = (env->CP0_Cause & CP0Ca_IP_mask) >> CP0Ca_IP;
pending &= env->CP0_Status >> 8; if (env->CP0_Config3 & (1 << CP0C3_VEIC)) {
/* Compute the Vector Spacing. */ /* For VEIC mode, the external interrupt controller feeds
spacing = (env->CP0_IntCtl >> CP0IntCtl_VS) & ((1 << 6) - 1); * the vector through the CP0Cause IP lines. */
spacing <<= 5; vector = pending;
} else {
if (env->CP0_Config3 & (1 << CP0C3_VInt)) { /* Vectored Interrupts
/* For VInt mode, the MIPS computes the vector internally. */ * Mask with Status.IM7-IM0 to get enabled interrupts. */
for (vector = 7; vector > 0; vector--) { pending &= (env->CP0_Status >> CP0St_IM) & 0xff;
if (pending & (1 << vector)) { /* Find the highest-priority interrupt. */
/* Found it. */ while (pending >>= 1) {
break; vector++;
} }
} }
} else { offset = 0x200 + (vector * (spacing << 5));
/* For VEIC mode, the external interrupt controller feeds the
vector through the CP0Cause IP lines. */
vector = pending;
} }
offset = 0x200 + vector * spacing;
} }
goto set_EPC; goto set_EPC;
case EXCP_LTLBL: case EXCP_LTLBL:
......
...@@ -1432,7 +1432,6 @@ void helper_mttc0_status(CPUMIPSState *env, target_ulong arg1) ...@@ -1432,7 +1432,6 @@ void helper_mttc0_status(CPUMIPSState *env, target_ulong arg1)
void helper_mtc0_intctl(CPUMIPSState *env, target_ulong arg1) void helper_mtc0_intctl(CPUMIPSState *env, target_ulong arg1)
{ {
/* vectored interrupts not implemented, no performance counters. */
env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000003e0) | (arg1 & 0x000003e0); env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000003e0) | (arg1 & 0x000003e0);
} }
...@@ -1473,7 +1472,6 @@ target_ulong helper_mftc0_ebase(CPUMIPSState *env) ...@@ -1473,7 +1472,6 @@ target_ulong helper_mftc0_ebase(CPUMIPSState *env)
void helper_mtc0_ebase(CPUMIPSState *env, target_ulong arg1) void helper_mtc0_ebase(CPUMIPSState *env, target_ulong arg1)
{ {
/* vectored interrupts not implemented */
env->CP0_EBase = (env->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000); env->CP0_EBase = (env->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册