aboutsummaryrefslogtreecommitdiff
path: root/target-openrisc/interrupt.c
diff options
context:
space:
mode:
authorJia Liu <proljc@gmail.com>2012-07-20 15:50:41 +0800
committerBlue Swirl <blauwirbel@gmail.com>2012-07-27 21:12:57 +0000
commitb6a71ef7e01bcac7aeb47d8de4082704fbc6479c (patch)
tree3ae466a65ec1083a2575b5d3cbb92139e9b98742 /target-openrisc/interrupt.c
parent726fe04572093504e7bf4ea56e0b2de559063787 (diff)
downloadqemu-b6a71ef7e01bcac7aeb47d8de4082704fbc6479c.zip
qemu-b6a71ef7e01bcac7aeb47d8de4082704fbc6479c.tar.gz
qemu-b6a71ef7e01bcac7aeb47d8de4082704fbc6479c.tar.bz2
target-or32: Add interrupt support
Add OpenRISC interrupt support. Signed-off-by: Jia Liu <proljc@gmail.com> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'target-openrisc/interrupt.c')
-rw-r--r--target-openrisc/interrupt.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/target-openrisc/interrupt.c b/target-openrisc/interrupt.c
index 7a9ee0b..642da7d 100644
--- a/target-openrisc/interrupt.c
+++ b/target-openrisc/interrupt.c
@@ -27,4 +27,48 @@
void do_interrupt(CPUOpenRISCState *env)
{
+#ifndef CONFIG_USER_ONLY
+ if (env->flags & D_FLAG) { /* Delay Slot insn */
+ 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;
+ }
+ }
+
+ /* For machine-state changed between user-mode and supervisor mode,
+ we need flush TLB when we enter&exit EXCP. */
+ tlb_flush(env, 1);
+
+ env->esr = env->sr;
+ env->sr &= ~SR_DME;
+ env->sr &= ~SR_IME;
+ env->sr |= SR_SM;
+ env->sr &= ~SR_IEE;
+ env->sr &= ~SR_TEE;
+ env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
+ env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;
+
+ if (env->exception_index > 0 && env->exception_index < EXCP_NR) {
+ env->pc = (env->exception_index << 8);
+ } else {
+ cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
+ }
+#endif
+
+ env->exception_index = -1;
}