diff mbox

[v7,06/32] target-arm: A32: Emulate the SMC instruction

Message ID 1413910544-20150-7-git-send-email-greg.bellows@linaro.org
State New
Headers show

Commit Message

Greg Bellows Oct. 21, 2014, 4:55 p.m. UTC
From: Fabian Aggeler <aggelerf@ethz.ch>

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>

Comments

Peter Maydell Oct. 23, 2014, 2:06 p.m. UTC | #1
On 21 October 2014 17:55, Greg Bellows <greg.bellows@linaro.org> wrote:
> From: Fabian Aggeler <aggelerf@ethz.ch>
>
> 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>
>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM
diff mbox

Patch

==========

v5 -> v6
- Fixed PC offsetting for presmc
- Removed extraneous semi-colon
- Fixed merge issue

v4 -> v5
- Merge pre_smc upstream changes and incorporated ss_advance

Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
---
 target-arm/helper.c    | 11 +++++++++++
 target-arm/op_helper.c |  3 +--
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 033b18f..38d9f7b 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.
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 6cc3387..62012c3 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -429,8 +429,7 @@  void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
 {
     ARMCPU *cpu = arm_env_get_cpu(env);
     int cur_el = arm_current_el(env);
-    /* FIXME: Use real secure state.  */
-    bool secure = false;
+    bool secure = arm_is_secure(env);
     bool smd = env->cp15.scr_el3 & SCR_SMD;
     /* On ARMv8 AArch32, SMD only applies to NS state.
      * On ARMv7 SMD only applies to NS state and only if EL2 is available.