If EL3 is in Aarch32 state certain cp registers are banked (secure and
non-secure instance). When reading or writing to coprocessor registers
the following macros can be used. If the CPU is in monitor mode SCR.NS
bit determines which instance is going to be accessed.

- USE_SECURE_REG(env): to determine which instance to use, depends on
                       SCR.NS bit
- A32_BANKED_REG_GET(env, regname): get value of banked register
- A32_BANKED_REG_SET(env, regname): set value of banked register

When accessing banked registers otherwise use s/ns field depending
on whether CPU is in secure state (monitor mode or ns-bit clear).

- A32_BANKED_CURRENT_REG_GET(env, regname)
- A32_BANKED_CURRENT_REG_SET(env, regname)

If EL3 is operating in Aarch64 state coprocessor registers are not
banked anymore. The macros use the non-secure instance (_ns) in this
case, which is architecturally mapped to the Aarch64 EL register.

Signed-off-by: Sergey Fedorov <s.fedo...@samsung.com>
Signed-off-by: Fabian Aggeler <aggel...@ethz.ch>
---
 target-arm/cpu.h | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 221b847..0b8042c 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -774,6 +774,41 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
     return arm_feature(env, ARM_FEATURE_AARCH64);
 }
 
+/* When EL3 is operating in Aarch32 state, the NS-bit determines
+ * whether the secure instance of a cp-register should be used. */
+#define USE_SECURE_REG(env) ( \
+                        arm_feature(env, ARM_FEATURE_EL3) && \
+                        !arm_el_is_aa64(env, 3) && \
+                        !((env)->cp15.scr_el3 & SCR_NS))
+
+#define A32_BANKED_REG_GET(env, regname) \
+    ((USE_SECURE_REG(env)) ? \
+            (env)->cp15.regname##_s : \
+            (env)->cp15.regname##_ns)
+
+#define A32_BANKED_REG_SET(env, regname, val) \
+        do { \
+            if (USE_SECURE_REG(env)) { \
+                (env)->cp15.regname##_s = (val); \
+            } else { \
+                (env)->cp15.regname##_ns = (val); \
+            } \
+        } while (0)
+
+#define A32_BANKED_CURRENT_REG_GET(env, regname) \
+    ((!arm_el_is_aa64(env, 3) && arm_is_secure(env)) ? \
+            (env)->cp15.regname##_s : \
+            (env)->cp15.regname##_ns)
+
+#define A32_BANKED_CURRENT_REG_SET(env, regname, val) \
+        do { \
+            if (!arm_el_is_aa64(env, 3) && arm_is_secure(env)) { \
+                (env)->cp15.regname##_s = (val); \
+            } else { \
+                (env)->cp15.regname##_ns = (val); \
+            } \
+        } while (0)
+
 void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx);
 inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t *target_mode,
-- 
1.8.3.2


Reply via email to