aboutsummaryrefslogtreecommitdiff
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
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>
-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,