aboutsummaryrefslogtreecommitdiff
path: root/target-openrisc/interrupt.c
diff options
context:
space:
mode:
authorSebastian Macke <sebastian@macke.de>2013-10-22 02:12:40 +0200
committerJia Liu <proljc@gmail.com>2013-11-20 21:45:42 +0800
commitae52bd96ceaea36c486d8ffeb798e160f31d3be8 (patch)
treebdbb70343d10e424f52e494930b0fa7aefdccd60 /target-openrisc/interrupt.c
parent04359e6bb7f2841031aae645a770583f9c5df3cd (diff)
target-openrisc: Correct wrong epcr register in interrupt handler
This patch corrects several misbehaviors during an interrupt process. Most of the time the pc is already correct and therefore no special treatment of the exceptions is necessary. Tested by checking crashing programs which otherwise work in or1ksim. Signed-off-by: Sebastian Macke <sebastian@macke.de> Reviewed-by: Jia Liu <proljc@gmail.com> Signed-off-by: Jia Liu <proljc@gmail.com>
Diffstat (limited to 'target-openrisc/interrupt.c')
-rw-r--r--target-openrisc/interrupt.c25
1 files changed, 7 insertions, 18 deletions
diff --git a/target-openrisc/interrupt.c b/target-openrisc/interrupt.c
index 16ef4b3e79..2153e7ea7e 100644
--- a/target-openrisc/interrupt.c
+++ b/target-openrisc/interrupt.c
@@ -30,26 +30,15 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
OpenRISCCPU *cpu = OPENRISC_CPU(cs);
CPUOpenRISCState *env = &cpu->env;
#ifndef CONFIG_USER_ONLY
- if (env->flags & D_FLAG) { /* Delay Slot insn */
+
+ env->epcr = env->pc;
+ if (env->flags & D_FLAG) {
env->flags &= ~D_FLAG;
env->sr |= SR_DSX;
- if (env->exception_index == EXCP_TICK ||
- env->exception_index == EXCP_INT ||
- env->exception_index == EXCP_SYSCALL ||
- env->exception_index == EXCP_FPE) {
- env->epcr = env->jmp_pc;
- } else {
- env->epcr = env->pc - 4;
- }
- } else {
- if (env->exception_index == EXCP_TICK ||
- env->exception_index == EXCP_INT ||
- env->exception_index == EXCP_SYSCALL ||
- env->exception_index == EXCP_FPE) {
- env->epcr = env->npc;
- } else {
- env->epcr = env->pc;
- }
+ env->epcr -= 4;
+ }
+ if (env->exception_index == EXCP_SYSCALL) {
+ env->epcr += 4;
}
/* For machine-state changed between user-mode and supervisor mode,