summaryrefslogtreecommitdiff
path: root/target-arm/helper.c
diff options
context:
space:
mode:
authorFabian Aggeler <aggelerf@ethz.ch>2014-10-24 12:19:15 +0100
committerPeter Maydell <peter.maydell@linaro.org>2014-10-24 12:19:15 +0100
commitdbe9d1636787dd226d3f9a61c07fbc27e0db5bbf (patch)
treeb6b5a36edb72357b0df274483371a824bc7df3a8 /target-arm/helper.c
parent592125f83a8034deaa26f840cde5909f26429c4a (diff)
downloadqemu-dbe9d1636787dd226d3f9a61c07fbc27e0db5bbf.zip
target-arm: A32: Emulate the SMC instruction
Implements SMC instruction in AArch32 using the A32 syndrome. When executing SMC instruction from monitor CPU mode SCR.NS bit is reset. Signed-off-by: Sergey Fedorov <s.fedorov@samsung.com> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch> Signed-off-by: Greg Bellows <greg.bellows@linaro.org> Message-id: 1413910544-20150-7-git-send-email-greg.bellows@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-arm/helper.c')
-rw-r--r--target-arm/helper.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c
index c2b3539da6..c47487a0af 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -4091,6 +4091,12 @@ void arm_cpu_do_interrupt(CPUState *cs)
mask = CPSR_A | CPSR_I | CPSR_F;
offset = 4;
break;
+ case EXCP_SMC:
+ new_mode = ARM_CPU_MODE_MON;
+ addr = 0x08;
+ mask = CPSR_A | CPSR_I | CPSR_F;
+ offset = 0;
+ break;
default:
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
return; /* Never happens. Keep compiler happy. */
@@ -4109,6 +4115,11 @@ void arm_cpu_do_interrupt(CPUState *cs)
*/
addr += env->cp15.vbar_el[1];
}
+
+ if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
+ env->cp15.scr_el3 &= ~SCR_NS;
+ }
+
switch_mode (env, new_mode);
/* For exceptions taken to AArch32 we must clear the SS bit in both
* PSTATE and in the old-state value we save to SPSR_<mode>, so zero it now.