All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs
@ 2014-09-30 21:49 Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 01/33] target-arm: increase arrays of registers R13 & R14 Greg Bellows
                   ` (33 more replies)
  0 siblings, 34 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

Version 5 of the ARM processor security extension (TrustZone) support.
This patchset includes changes to support the processor security extensions
on ARMv7 aarch32 with hooks for later enabling v8 aarch64/32.

Summary of changes from v4 -> v5:
- Renamed arm_current_pl to arm_current_el
- Added banked MAIR support
- Added gdb SCR register
- Bugfixes and clean-up
- Reordered patches so infrastructure happens before use.

More detailed change history included on a per-patch basis.

Fabian Aggeler (27):
  target-arm: increase arrays of registers R13 & R14
  target-arm: add arm_is_secure() function
  target-arm: make arm_current_pl() return PL3
  target-arm: A32: Emulate the SMC instruction
  target-arm: extend async excp masking
  target-arm: add async excp target_el function
  target-arm: add macros to access banked registers
  target-arm: arrayfying fieldoffset for banking
  target-arm: insert Aarch32 cpregs twice into hashtable
  target-arm: move Aarch32 SCR into security reglist
  target-arm: implement IRQ/FIQ routing to Monitor mode
  target-arm: Respect SCR.FW, SCR.AW and SCTLR.NMFI
  target-arm: add NSACR register
  target-arm: add MVBAR support
  target-arm: add SCTLR_EL3 and make SCTLR banked
  target-arm: make CSSELR banked
  target-arm: add TTBR0_EL3 and make TTBR0/1 banked
  target-arm: add TCR_EL3 and make TTBCR banked
  target-arm: make c2_mask and c2_base_mask banked
  target-arm: make DACR banked
  target-arm: make IFSR banked
  target-arm: make DFSR banked
  target-arm: make IFAR/DFAR banked
  target-arm: make PAR banked
  target-arm: make VBAR banked
  target-arm: make c13 cp regs banked (FCSEIDR, ...)
  target-arm: add cpu feature EL3 to CPUs with Security Extensions

Greg Bellows (3):
  target-arm: rename arm_current_pl to arm_current_el
  target-arm: make MAIR0/1 banked
  target-arm: add GDB scr register

Sergey Fedorov (3):
  target-arm: reject switching to monitor mode
  target-arm: add non-secure Translation Block flag
  target-arm: add SDER definition

 gdb-xml/arm-core.xml       |   1 +
 hw/arm/pxa2xx.c            |   4 +-
 target-arm/cpu.c           |  13 +-
 target-arm/cpu.h           | 471 +++++++++++++++++++++++----
 target-arm/gdbstub.c       |   3 +
 target-arm/helper-a64.c    |   6 +-
 target-arm/helper.c        | 772 ++++++++++++++++++++++++++++++++++-----------
 target-arm/internals.h     |  11 +-
 target-arm/machine.c       |   4 +-
 target-arm/op_helper.c     |  19 +-
 target-arm/translate-a64.c |   3 +-
 target-arm/translate.c     |  56 +++-
 target-arm/translate.h     |   1 +
 13 files changed, 1092 insertions(+), 272 deletions(-)

--
1.8.3.2

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 01/33] target-arm: increase arrays of registers R13 & R14
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-10-06 14:48   ` Peter Maydell
  2014-10-06 19:21   ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function Greg Bellows
                   ` (32 subsequent siblings)
  33 siblings, 2 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

Increasing banked_r13 and banked_r14 to store LR_mon and SP_mon (bank
index 7).

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
---
 target-arm/cpu.h     | 4 ++--
 target-arm/machine.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 65a3417..81fffd2 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -153,8 +153,8 @@ typedef struct CPUARMState {
 
     /* Banked registers.  */
     uint64_t banked_spsr[8];
-    uint32_t banked_r13[6];
-    uint32_t banked_r14[6];
+    uint32_t banked_r13[8];
+    uint32_t banked_r14[8];
 
     /* These hold r8-r12.  */
     uint32_t usr_regs[5];
diff --git a/target-arm/machine.c b/target-arm/machine.c
index ddb7d05..7e69127 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -238,8 +238,8 @@ const VMStateDescription vmstate_arm_cpu = {
         },
         VMSTATE_UINT32(env.spsr, ARMCPU),
         VMSTATE_UINT64_ARRAY(env.banked_spsr, ARMCPU, 8),
-        VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 6),
-        VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 6),
+        VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 8),
+        VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 8),
         VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5),
         VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5),
         VMSTATE_UINT64_ARRAY(env.elr_el, ARMCPU, 4),
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 01/33] target-arm: increase arrays of registers R13 & R14 Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 22:50   ` Edgar E. Iglesias
  2014-10-06 14:56   ` Peter Maydell
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 03/33] target-arm: reject switching to monitor mode Greg Bellows
                   ` (31 subsequent siblings)
  33 siblings, 2 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Sergey Fedorov, Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

arm_is_secure() function allows to determine CPU security state
if the CPU implements Security Extensions/EL3.
arm_is_secure_below_el3() returns true if CPU is in secure state
below EL3.

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>
---
 target-arm/cpu.h | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 81fffd2..10afef0 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -753,6 +753,44 @@ static inline int arm_feature(CPUARMState *env, int feature)
     return (env->features & (1ULL << feature)) != 0;
 }
 
+
+/* Return true if exception level below EL3 is in secure state */
+static inline bool arm_is_secure_below_el3(CPUARMState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+    if (arm_feature(env, ARM_FEATURE_EL3)) {
+        return !(env->cp15.scr_el3 & SCR_NS);
+    } else if (arm_feature(env, ARM_FEATURE_EL2)) {
+        return false;
+    } else {
+        /* IMPDEF: QEMU defaults to non-secure */
+        return false;
+    }
+#else
+    return false;
+#endif
+}
+
+/* Return true if the processor is in secure state */
+static inline bool arm_is_secure(CPUARMState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+    if (arm_feature(env, ARM_FEATURE_EL3)) {
+        if (env->aarch64 && extract32(env->pstate, 2, 2) == 3) {
+            /* CPU currently in Aarch64 state and EL3 */
+            return true;
+        } else if (!env->aarch64 &&
+                (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
+            /* CPU currently in Aarch32 state and monitor mode */
+            return true;
+        }
+    }
+    return arm_is_secure_below_el3(env);
+#else
+    return false;
+#endif
+}
+
 /* Return true if the specified exception level is running in AArch64 state. */
 static inline bool arm_el_is_aa64(CPUARMState *env, int el)
 {
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 03/33] target-arm: reject switching to monitor mode
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 01/33] target-arm: increase arrays of registers R13 & R14 Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-10-06 15:02   ` Peter Maydell
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 04/33] target-arm: rename arm_current_pl to arm_current_el Greg Bellows
                   ` (30 subsequent siblings)
  33 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Sergey Fedorov, Greg Bellows

From: Sergey Fedorov <s.fedorov@samsung.com>

...from non-secure state.

Signed-off-by: Sergey Fedorov <s.fedorov@samsung.com>
Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
---
 target-arm/helper.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 2669e15..d6e3b52 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3531,6 +3531,8 @@ static int bad_mode_switch(CPUARMState *env, int mode)
     case ARM_CPU_MODE_IRQ:
     case ARM_CPU_MODE_FIQ:
         return 0;
+    case ARM_CPU_MODE_MON:
+        return !arm_is_secure(env);
     default:
         return 1;
     }
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 04/33] target-arm: rename arm_current_pl to arm_current_el
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (2 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 03/33] target-arm: reject switching to monitor mode Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 22:56   ` Edgar E. Iglesias
  2014-10-06 15:10   ` Peter Maydell
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 05/33] target-arm: make arm_current_pl() return PL3 Greg Bellows
                   ` (29 subsequent siblings)
  33 siblings, 2 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

Renamed the arm_current_pl CPU function to more accurately represent that it
returns the ARMv8 EL rather than ARMv7 PL.

Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
---
 target-arm/cpu.h           | 18 +++++++++---------
 target-arm/helper-a64.c    |  6 +++---
 target-arm/helper.c        | 22 +++++++++++-----------
 target-arm/internals.h     |  2 +-
 target-arm/op_helper.c     | 16 ++++++++--------
 target-arm/translate-a64.c |  2 +-
 target-arm/translate.c     |  2 +-
 7 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 10afef0..101d139 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -982,7 +982,7 @@ static inline bool cptype_valid(int cptype)
 #define PL1_RW (PL1_R | PL1_W)
 #define PL0_RW (PL0_R | PL0_W)
 
-static inline int arm_current_pl(CPUARMState *env)
+static inline int arm_current_el(CPUARMState *env)
 {
     if (env->aarch64) {
         return extract32(env->pstate, 2, 2);
@@ -1222,7 +1222,7 @@ bool write_cpustate_to_list(ARMCPU *cpu);
 static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
 {
     CPUARMState *env = cs->env_ptr;
-    unsigned int cur_el = arm_current_pl(env);
+    unsigned int cur_el = arm_current_el(env);
     unsigned int target_el = arm_excp_target_el(cs, excp_idx);
     /* FIXME: Use actual secure state.  */
     bool secure = false;
@@ -1294,7 +1294,7 @@ static inline CPUARMState *cpu_init(const char *cpu_model)
 #define MMU_USER_IDX 0
 static inline int cpu_mmu_index (CPUARMState *env)
 {
-    return arm_current_pl(env);
+    return arm_current_el(env);
 }
 
 /* Return the Exception Level targeted by debug exceptions;
@@ -1307,7 +1307,7 @@ static inline int arm_debug_target_el(CPUARMState *env)
 
 static inline bool aa64_generate_debug_exceptions(CPUARMState *env)
 {
-    if (arm_current_pl(env) == arm_debug_target_el(env)) {
+    if (arm_current_el(env) == arm_debug_target_el(env)) {
         if ((extract32(env->cp15.mdscr_el1, 13, 1) == 0)
             || (env->daif & PSTATE_D)) {
             return false;
@@ -1318,10 +1318,10 @@ static inline bool aa64_generate_debug_exceptions(CPUARMState *env)
 
 static inline bool aa32_generate_debug_exceptions(CPUARMState *env)
 {
-    if (arm_current_pl(env) == 0 && arm_el_is_aa64(env, 1)) {
+    if (arm_current_el(env) == 0 && arm_el_is_aa64(env, 1)) {
         return aa64_generate_debug_exceptions(env);
     }
-    return arm_current_pl(env) != 2;
+    return arm_current_el(env) != 2;
 }
 
 /* Return true if debugging exceptions are currently enabled.
@@ -1451,8 +1451,8 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
     if (is_a64(env)) {
         *pc = env->pc;
         *flags = ARM_TBFLAG_AARCH64_STATE_MASK
-            | (arm_current_pl(env) << ARM_TBFLAG_AA64_EL_SHIFT);
-        if (fpen == 3 || (fpen == 1 && arm_current_pl(env) != 0)) {
+            | (arm_current_el(env) << ARM_TBFLAG_AA64_EL_SHIFT);
+        if (fpen == 3 || (fpen == 1 && arm_current_el(env) != 0)) {
             *flags |= ARM_TBFLAG_AA64_FPEN_MASK;
         }
         /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
@@ -1488,7 +1488,7 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
             || arm_el_is_aa64(env, 1)) {
             *flags |= ARM_TBFLAG_VFPEN_MASK;
         }
-        if (fpen == 3 || (fpen == 1 && arm_current_pl(env) != 0)) {
+        if (fpen == 3 || (fpen == 1 && arm_current_el(env) != 0)) {
             *flags |= ARM_TBFLAG_CPACR_FPEN_MASK;
         }
         /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index 8228e29..173f116 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -448,7 +448,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
     unsigned int new_mode = aarch64_pstate_mode(new_el, true);
     int i;
 
-    if (arm_current_pl(env) < new_el) {
+    if (arm_current_el(env) < new_el) {
         if (env->aarch64) {
             addr += 0x400;
         } else {
@@ -459,7 +459,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
     }
 
     arm_log_exception(cs->exception_index);
-    qemu_log_mask(CPU_LOG_INT, "...from EL%d\n", arm_current_pl(env));
+    qemu_log_mask(CPU_LOG_INT, "...from EL%d\n", arm_current_el(env));
     if (qemu_loglevel_mask(CPU_LOG_INT)
         && !excp_is_internal(cs->exception_index)) {
         qemu_log_mask(CPU_LOG_INT, "...with ESR 0x%" PRIx32 "\n",
@@ -495,7 +495,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
 
     if (is_a64(env)) {
         env->banked_spsr[aarch64_banked_spsr_index(new_el)] = pstate_read(env);
-        aarch64_save_sp(env, arm_current_pl(env));
+        aarch64_save_sp(env, arm_current_el(env));
         env->elr_el[new_el] = env->pc;
     } else {
         env->banked_spsr[0] = cpsr_read(env);
diff --git a/target-arm/helper.c b/target-arm/helper.c
index d6e3b52..2381e6f 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -571,7 +571,7 @@ static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri)
     /* Performance monitor registers user accessibility is controlled
      * by PMUSERENR.
      */
-    if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
+    if (arm_current_el(env) == 0 && !env->cp15.c9_pmuserenr) {
         return CP_ACCESS_TRAP;
     }
     return CP_ACCESS_OK;
@@ -996,7 +996,7 @@ static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 
 static CPAccessResult teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    if (arm_current_pl(env) == 0 && (env->teecr & 1)) {
+    if (arm_current_el(env) == 0 && (env->teecr & 1)) {
         return CP_ACCESS_TRAP;
     }
     return CP_ACCESS_OK;
@@ -1042,7 +1042,7 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
 static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     /* CNTFRQ: not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero */
-    if (arm_current_pl(env) == 0 && !extract32(env->cp15.c14_cntkctl, 0, 2)) {
+    if (arm_current_el(env) == 0 && !extract32(env->cp15.c14_cntkctl, 0, 2)) {
         return CP_ACCESS_TRAP;
     }
     return CP_ACCESS_OK;
@@ -1051,7 +1051,7 @@ static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri)
 static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx)
 {
     /* CNT[PV]CT: not visible from PL0 if ELO[PV]CTEN is zero */
-    if (arm_current_pl(env) == 0 &&
+    if (arm_current_el(env) == 0 &&
         !extract32(env->cp15.c14_cntkctl, timeridx, 1)) {
         return CP_ACCESS_TRAP;
     }
@@ -1063,7 +1063,7 @@ static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx)
     /* CNT[PV]_CVAL, CNT[PV]_CTL, CNT[PV]_TVAL: not visible from PL0 if
      * EL0[PV]TEN is zero.
      */
-    if (arm_current_pl(env) == 0 &&
+    if (arm_current_el(env) == 0 &&
         !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
         return CP_ACCESS_TRAP;
     }
@@ -1911,7 +1911,7 @@ static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 
 static CPAccessResult aa64_daif_access(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
+    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
         return CP_ACCESS_TRAP;
     }
     return CP_ACCESS_OK;
@@ -1929,7 +1929,7 @@ static CPAccessResult aa64_cacheop_access(CPUARMState *env,
     /* Cache invalidate/clean: NOP, but EL0 must UNDEF unless
      * SCTLR_EL1.UCI is set.
      */
-    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCI)) {
+    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCI)) {
         return CP_ACCESS_TRAP;
     }
     return CP_ACCESS_OK;
@@ -2006,7 +2006,7 @@ static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri)
     /* We don't implement EL2, so the only control on DC ZVA is the
      * bit in the SCTLR which can prohibit access for EL0.
      */
-    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_DZE)) {
+    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_DZE)) {
         return CP_ACCESS_TRAP;
     }
     return CP_ACCESS_OK;
@@ -2366,7 +2366,7 @@ static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri)
     /* Only accessible in EL0 if SCTLR.UCT is set (and only in AArch64,
      * but the AArch32 CTR has its own reginfo struct)
      */
-    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCT)) {
+    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCT)) {
         return CP_ACCESS_TRAP;
     }
     return CP_ACCESS_OK;
@@ -3773,7 +3773,7 @@ unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
 {
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
-    unsigned int cur_el = arm_current_pl(env);
+    unsigned int cur_el = arm_current_el(env);
     unsigned int target_el;
     /* FIXME: Use actual secure state.  */
     bool secure = false;
@@ -4769,7 +4769,7 @@ int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
     int prot;
     int ret, is_user;
     uint32_t syn;
-    bool same_el = (arm_current_pl(env) != 0);
+    bool same_el = (arm_current_el(env) != 0);
 
     is_user = mmu_idx == MMU_USER_IDX;
     ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot,
diff --git a/target-arm/internals.h b/target-arm/internals.h
index b7547bb..fd69a83 100644
--- a/target-arm/internals.h
+++ b/target-arm/internals.h
@@ -130,7 +130,7 @@ static inline void aarch64_restore_sp(CPUARMState *env, int el)
 
 static inline void update_spsel(CPUARMState *env, uint32_t imm)
 {
-    unsigned int cur_el = arm_current_pl(env);
+    unsigned int cur_el = arm_current_el(env);
     /* Update PSTATE SPSel bit; this requires us to update the
      * working stack pointer in xregs[31].
      */
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 03ac92a..0809d63 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -361,7 +361,7 @@ void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
      * Note that SPSel is never OK from EL0; we rely on handle_msr_i()
      * to catch that case at translate time.
      */
-    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
+    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
         raise_exception(env, EXCP_UDEF);
     }
 
@@ -387,7 +387,7 @@ void HELPER(clear_pstate_ss)(CPUARMState *env)
 
 void HELPER(pre_hvc)(CPUARMState *env)
 {
-    int cur_el = arm_current_pl(env);
+    int cur_el = arm_current_el(env);
     /* FIXME: Use actual secure state.  */
     bool secure = false;
     bool undef;
@@ -418,7 +418,7 @@ void HELPER(pre_hvc)(CPUARMState *env)
 
 void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
 {
-    int cur_el = arm_current_pl(env);
+    int cur_el = arm_current_el(env);
     /* FIXME: Use real secure state.  */
     bool secure = false;
     bool smd = env->cp15.scr_el3 & SCR_SMD;
@@ -444,7 +444,7 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
 
 void HELPER(exception_return)(CPUARMState *env)
 {
-    int cur_el = arm_current_pl(env);
+    int cur_el = arm_current_el(env);
     unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
     uint32_t spsr = env->banked_spsr[spsr_idx];
     int new_el, i;
@@ -561,7 +561,7 @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
 
     switch (bt) {
     case 3: /* linked context ID match */
-        if (arm_current_pl(env) > 1) {
+        if (arm_current_el(env) > 1) {
             /* Context matches never fire in EL2 or (AArch64) EL3 */
             return false;
         }
@@ -641,7 +641,7 @@ static bool bp_wp_matches(ARMCPU *cpu, int n, bool is_wp)
      * rely on this behaviour currently.
      * For breakpoints we do want to use the current CPU state.
      */
-    switch (arm_current_pl(env)) {
+    switch (arm_current_el(env)) {
     case 3:
     case 2:
         if (!hmc) {
@@ -728,7 +728,7 @@ void arm_debug_excp_handler(CPUState *cs)
             cs->watchpoint_hit = NULL;
             if (check_watchpoints(cpu)) {
                 bool wnr = (wp_hit->flags & BP_WATCHPOINT_HIT_WRITE) != 0;
-                bool same_el = arm_debug_target_el(env) == arm_current_pl(env);
+                bool same_el = arm_debug_target_el(env) == arm_current_el(env);
 
                 env->exception.syndrome = syn_watchpoint(same_el, 0, wnr);
                 if (extended_addresses_enabled(env)) {
@@ -744,7 +744,7 @@ void arm_debug_excp_handler(CPUState *cs)
         }
     } else {
         if (check_breakpoints(cpu)) {
-            bool same_el = (arm_debug_target_el(env) == arm_current_pl(env));
+            bool same_el = (arm_debug_target_el(env) == arm_current_el(env));
             env->exception.syndrome = syn_breakpoint(same_el);
             if (extended_addresses_enabled(env)) {
                 env->exception.fsr = (1 << 9) | 0x22;
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 35ae3ea..f53dc0f 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -10930,7 +10930,7 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
     dc->vec_len = 0;
     dc->vec_stride = 0;
     dc->cp_regs = cpu->cp_regs;
-    dc->current_pl = arm_current_pl(env);
+    dc->current_pl = arm_current_el(env);
     dc->features = env->features;
 
     /* Single step state. The code-generation logic here is:
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 8a2994f..f6404be 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -10945,7 +10945,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
     dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
     dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
     dc->cp_regs = cpu->cp_regs;
-    dc->current_pl = arm_current_pl(env);
+    dc->current_pl = arm_current_el(env);
     dc->features = env->features;
 
     /* Single step state. The code-generation logic here is:
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 05/33] target-arm: make arm_current_pl() return PL3
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (3 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 04/33] target-arm: rename arm_current_pl to arm_current_el Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-10-01  1:23   ` Sergey Fedorov
  2014-10-06 15:34   ` Peter Maydell
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 06/33] target-arm: A32: Emulate the SMC instruction Greg Bellows
                   ` (28 subsequent siblings)
  33 siblings, 2 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

Make arm_current_pl() return PL3 for secure PL1 and monitor mode.
Increase MMU modes since mmu_index is directly infered from arm_
current_pl(). Changes assertion in arm_el_is_aa64() to allow EL3.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
---
 target-arm/cpu.h | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 101d139..c000716 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -100,7 +100,7 @@ typedef uint32_t ARMReadCPFunc(void *opaque, int cp_info,
 
 struct arm_boot_info;
 
-#define NB_MMU_MODES 2
+#define NB_MMU_MODES 4
 
 /* We currently assume float and double are IEEE single and double
    precision respectively.
@@ -753,7 +753,6 @@ static inline int arm_feature(CPUARMState *env, int feature)
     return (env->features & (1ULL << feature)) != 0;
 }
 
-
 /* Return true if exception level below EL3 is in secure state */
 static inline bool arm_is_secure_below_el3(CPUARMState *env)
 {
@@ -794,11 +793,12 @@ static inline bool arm_is_secure(CPUARMState *env)
 /* Return true if the specified exception level is running in AArch64 state. */
 static inline bool arm_el_is_aa64(CPUARMState *env, int el)
 {
-    /* We don't currently support EL2 or EL3, and this isn't valid for EL0
+    /* We don't currently support EL2, and this isn't valid for EL0
      * (if we're in EL0, is_a64() is what you want, and if we're not in EL0
      * then the state of EL0 isn't well defined.)
      */
-    assert(el == 1);
+    assert(el == 1 || el == 3);
+
     /* AArch64-capable CPUs always run with EL1 in AArch64 mode. This
      * is a QEMU-imposed simplification which we may wish to change later.
      * If we in future support EL2 and/or EL3, then the state of lower
@@ -990,9 +990,12 @@ static inline int arm_current_el(CPUARMState *env)
 
     if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR) {
         return 0;
+    } else if (arm_is_secure(env)) {
+        /* Secure PL1 and monitor mode are mapped to PL3 */
+        return 3;
     }
-    /* We don't currently implement the Virtualization or TrustZone
-     * extensions, so PL2 and PL3 don't exist for us.
+    /* We currently do not implement the Virtualization extensions, so PL2 does
+     * not exist for us.
      */
     return 1;
 }
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 06/33] target-arm: A32: Emulate the SMC instruction
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (4 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 05/33] target-arm: make arm_current_pl() return PL3 Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-10-06 15:46   ` Peter Maydell
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 07/33] target-arm: extend async excp masking Greg Bellows
                   ` (27 subsequent siblings)
  33 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Sergey Fedorov, Greg Bellows

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>

----------
v4 -> v5
- Merge pre_smc upstream changes and incorporated ss_advance
---
 target-arm/helper.c    | 11 +++++++++++
 target-arm/internals.h |  7 ++++++-
 target-arm/op_helper.c |  3 +--
 target-arm/translate.c | 39 +++++++++++++++++++++++++++++----------
 4 files changed, 47 insertions(+), 13 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 2381e6f..7f3f049 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -4090,6 +4090,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.  */
@@ -4108,6 +4114,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/internals.h b/target-arm/internals.h
index fd69a83..43a2e7d 100644
--- a/target-arm/internals.h
+++ b/target-arm/internals.h
@@ -236,7 +236,12 @@ static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_thumb)
         | (is_thumb ? 0 : ARM_EL_IL);
 }
 
-static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
+static inline uint32_t syn_aa32_smc(void)
+{
+    return (EC_AA32_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL;
+}
+
+static inline uint32_t syn_aa64_bkpt(uint16_t imm16)
 {
     return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
 }
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 0809d63..8ed8ee9 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -419,8 +419,7 @@ void HELPER(pre_hvc)(CPUARMState *env)
 void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
 {
     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.
diff --git a/target-arm/translate.c b/target-arm/translate.c
index f6404be..3f3ddfb 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -7872,15 +7872,27 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
         case 7:
         {
             int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
-            /* SMC instruction (op1 == 3)
-               and undefined instructions (op1 == 0 || op1 == 2)
-               will trap */
-            if (op1 != 1) {
+            if (op1 == 1) {
+                /* bkpt */
+                ARCH(5);
+                gen_exception_insn(s, 4, EXCP_BKPT,
+                        syn_aa32_bkpt(imm16, false));
+            } else if (op1 == 3) {
+                /* smi/smc */
+                if (!arm_dc_feature(s, ARM_FEATURE_EL3) ||
+                        s->current_pl == 0) {
+                    goto illegal_op;
+                }
+                gen_set_pc_im(s, s->pc);
+                tmp = tcg_const_i32(syn_aa32_smc());
+                gen_helper_pre_smc(cpu_env, tmp);
+                tcg_temp_free_i32(tmp);
+                gen_ss_advance(s);
+                gen_exception_insn(s, 0, EXCP_SMC, syn_aa32_smc());
+                break;
+            } else {
                 goto illegal_op;
             }
-            /* bkpt */
-            ARCH(5);
-            gen_exception_insn(s, 4, EXCP_BKPT, syn_aa32_bkpt(imm16, false));
             break;
         }
         case 0x8: /* signed multiply */
@@ -9711,9 +9723,16 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
 
                 if (insn & (1 << 26)) {
                     /* Secure monitor call (v6Z) */
-                    qemu_log_mask(LOG_UNIMP,
-                                  "arm: unimplemented secure monitor call\n");
-                    goto illegal_op; /* not implemented.  */
+                    if (!arm_dc_feature(s, ARM_FEATURE_EL3) ||
+                            s->current_pl == 0) {
+                        goto illegal_op;
+                    }
+                    gen_set_pc_im(s, s->pc);
+                    tmp = tcg_const_i32(syn_aa32_smc());
+                    gen_helper_pre_smc(cpu_env, tmp);
+                    tcg_temp_free_i32(tmp);
+                    gen_ss_advance(s);
+                    gen_exception_insn(s, 0, EXCP_SMC, syn_aa32_smc());
                 } else {
                     op = (insn >> 20) & 7;
                     switch (op) {
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 07/33] target-arm: extend async excp masking
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (5 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 06/33] target-arm: A32: Emulate the SMC instruction Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-10-06 15:53   ` Peter Maydell
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 08/33] target-arm: add async excp target_el function Greg Bellows
                   ` (26 subsequent siblings)
  33 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

This patch extends arm_excp_unmasked() according to ARM ARMv7 and
ARM ARMv8 (all EL running in Aarch32) and adds comments.

If EL3 is using Aarch64 IRQ/FIQ masking is ignored in
all exception levels other than EL3 if SCR.{FIQ|IRQ} is
set to 1 (routed to EL3).

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

----------
v4 -> v5
- Merge with v4 patch 10
---
 target-arm/cpu.h | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 106 insertions(+), 10 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c000716..30f57fd 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1226,11 +1226,8 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
 {
     CPUARMState *env = cs->env_ptr;
     unsigned int cur_el = arm_current_el(env);
-    unsigned int target_el = arm_excp_target_el(cs, excp_idx);
-    /* FIXME: Use actual secure state.  */
-    bool secure = false;
-    /* If in EL1/0, Physical IRQ routing to EL2 only happens from NS state.  */
-    bool irq_can_hyp = !secure && cur_el < 2 && target_el == 2;
+    bool secure = arm_is_secure(env);
+
     /* ARMv7-M interrupt return works by loading a magic value
      * into the PC.  On real hardware the load causes the
      * return to occur.  The qemu implementation performs the
@@ -1245,19 +1242,118 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
                         && (!IS_M(env) || env->regs[15] < 0xfffffff0);
 
     /* Don't take exceptions if they target a lower EL.  */
-    if (cur_el > target_el) {
+    if (cur_el > arm_excp_target_el(cs, excp_idx)) {
         return false;
     }
 
+    /* ARM ARMv7 B1.8.6  Asynchronous exception masking (table B1-12/B1-13)
+     * ARM ARMv8 G1.11.3 Asynchronous exception masking controls
+     * (table G1-18/G1-19) */
     switch (excp_idx) {
     case EXCP_FIQ:
-        if (irq_can_hyp && (env->cp15.hcr_el2 & HCR_FMO)) {
-            return true;
+        if (arm_feature(env, ARM_FEATURE_EL3) && arm_el_is_aa64(env, 3)) {
+            /* If EL3 is using Aarch64 and FIQs are routed to EL3 masking is
+             * ignored in all exception levels except EL3.
+             */
+            if ((env->cp15.scr_el3 & SCR_FIQ) && cur_el < 3) {
+                return true;
+            }
+            /* If we are in EL3 but FIQs are not routed to EL3 the exception
+             * is not taken but remains pending.
+             */
+            if (!(env->cp15.scr_el3 & SCR_FIQ) && cur_el == 3) {
+                return false;
+            }
+        }
+        if (!secure) {
+            if (arm_feature(env, ARM_FEATURE_EL2)) {
+                if (env->cp15.hcr_el2 & HCR_FMO) {
+                    /* CPSR.F/PSTATE.F ignored if
+                     *  - exception is taken from Non-secure state
+                     *  - HCR.FMO == 1
+                     *  - either:  - not in Hyp mode
+                     *             - SCR.FIQ routes exception to monitor mode
+                     *               (EL3 in Aarch32)
+                     */
+                    if (cur_el < 2) {
+                        return true;
+                    } else if (arm_feature(env, ARM_FEATURE_EL3) &&
+                            (env->cp15.scr_el3 & SCR_FIQ) &&
+                            !arm_el_is_aa64(env, 3)) {
+                        return true;
+                    }
+                } else if (arm_el_is_aa64(env, 3) &&
+                          (env->cp15.scr_el3 & SCR_RW) &&
+                          cur_el == 2) {
+                    /* FIQs not routed to EL2 but currently in EL2 (A64).
+                     * Exception is not taken but remains pending. */
+                    return false;
+                }
+            }
+            /* In ARMv7 only applies if both Security Extensions (EL3) and
+             * Hypervirtualization Extensions (EL2) implemented, while
+             * for ARMv8 it applies also if only EL3 implemented.
+             */
+            if (arm_feature(env, ARM_FEATURE_EL3) &&
+                    (arm_feature(env, ARM_FEATURE_EL2) ||
+                            arm_feature(env, ARM_FEATURE_V8))) {
+                /* CPSR.F/PSTATE.F ignored if
+                 * - exception is taken from Non-secure state
+                 * - SCR.FIQ routes exception to monitor mode
+                 * - SCR.FW bit is set to 0
+                 * - HCR.FMO == 0 (if EL2 implemented)
+                 */
+                if ((env->cp15.scr_el3 & SCR_FIQ) &&
+                        !(env->cp15.scr_el3 & SCR_FW)) {
+                    if (!arm_feature(env, ARM_FEATURE_EL2)) {
+                        return true;
+                    } else if (!(env->cp15.hcr_el2 & HCR_FMO)) {
+                        return true;
+                    }
+                }
+            }
         }
         return !(env->daif & PSTATE_F);
     case EXCP_IRQ:
-        if (irq_can_hyp && (env->cp15.hcr_el2 & HCR_IMO)) {
-            return true;
+        if (arm_feature(env, ARM_FEATURE_EL3) && arm_el_is_aa64(env, 3)) {
+            /* If EL3 is using Aarch64 and IRQs are routed to EL3 masking is
+             * ignored in all exception levels except EL3.
+             */
+            if ((env->cp15.scr_el3 & SCR_IRQ) && cur_el < 3) {
+                return true;
+            }
+            /* If we are in EL3 but IRQ s are not routed to EL3 the exception
+             * is not taken but remains pending.
+             */
+            if (!(env->cp15.scr_el3 & SCR_IRQ) && cur_el == 3) {
+                return false;
+            }
+        }
+        if (!secure) {
+            if (arm_feature(env, ARM_FEATURE_EL2)) {
+                if (env->cp15.hcr_el2 & HCR_IMO) {
+                    /* CPSR.I/PSTATE.I ignored if
+                     *  - exception is taken from Non-secure state
+                     *  - HCR.IMO == 1
+                     *  - either:  - not in Hyp mode
+                     *             - SCR.IRQ routes exception to monitor mode
+                     *                (EL3 in Aarch32)
+                     */
+                    if (cur_el < 2) {
+                        return true;
+                    } else if (arm_feature(env, ARM_FEATURE_EL3) &&
+                            (env->cp15.scr_el3 & SCR_IRQ) &&
+                            !arm_el_is_aa64(env, 3)) {
+                        return true;
+                    }
+                } else if (arm_el_is_aa64(env, 3) &&
+                          (env->cp15.scr_el3 & SCR_RW) &&
+                          cur_el == 2) {
+                    /* IRQs not routed to EL2 but currently in EL2 (A64).
+                     * Exception is not taken but remains pending. */
+                    return false;
+                }
+            }
         }
         return irq_unmasked;
     case EXCP_VFIQ:
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 08/33] target-arm: add async excp target_el function
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (6 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 07/33] target-arm: extend async excp masking Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-10-06 16:02   ` Peter Maydell
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 09/33] target-arm: add macros to access banked registers Greg Bellows
                   ` (25 subsequent siblings)
  33 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

Adds a dedicated function for IRQ and FIQ exceptions to determine
target_el and mode (Aarch32) according to tables in ARM ARMv8 and
ARM ARM v7.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

----------
v4 -> v5
- Simplify target EL function including removal of mode which was unused
- Merged with patch that plugs in the use of the function

v3 -> v4
- Fixed arm_phys_excp_target_el() 0/0/0 case to return excp_mode when EL<2
  rather than ABORT.
---
 target-arm/cpu.h    |   2 +
 target-arm/helper.c | 103 ++++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 85 insertions(+), 20 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 30f57fd..601f8fe 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -809,6 +809,8 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
 
 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 excp_idx,
+                                        uint32_t cur_el, bool secure);
 
 /* Interface between CPU and Interrupt controller.  */
 void armv7m_nvic_set_pending(void *opaque, int irq);
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 7f3f049..a10f459 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3706,6 +3706,12 @@ uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
     return 0;
 }
 
+inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
+                                        uint32_t cur_el, bool secure)
+{
+    return 1;
+}
+
 unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
 {
     return 1;
@@ -3767,6 +3773,80 @@ void switch_mode(CPUARMState *env, int mode)
 }
 
 /*
+ * Determine the target EL for physical exceptions
+ */
+inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
+                                        uint32_t cur_el, bool secure)
+{
+    CPUARMState *env = cs->env_ptr;
+    uint32_t target_el = 1;
+
+    /* There is no SCR or HCR routing unless the respective EL3 and EL2
+     * extensions are supported.  This initial setting affects whether any
+     * other conditions matter.
+     */
+    bool scr_routing = arm_feature(env, ARM_FEATURE_EL3); /* IRQ, FIQ, EA */
+    bool hcr_routing = arm_feature(env, ARM_FEATURE_EL2); /* IMO, FMO, AMO */
+
+    /* Fast-path if EL2 and EL3 are not enabled */
+    if (!scr_routing && !hcr_routing) {
+        return target_el;
+    }
+
+    switch (excp_idx) {
+    case EXCP_IRQ:
+        scr_routing &= ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ);
+        hcr_routing &= ((env->cp15.hcr_el2 & HCR_IMO) == HCR_IMO);
+        break;
+    case EXCP_FIQ:
+        scr_routing &= ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ);
+        hcr_routing &= ((env->cp15.hcr_el2 & HCR_FMO) == HCR_FMO);
+    }
+
+    /* If SCR routing is enabled we always go to EL3 regardless of EL3
+     * execution state
+     */
+    if (scr_routing) {
+        /* IRQ|FIQ|EA == 1 */
+        return 3;
+    }
+
+    /* If HCR.TGE is set all exceptions that would be routed to EL1 are
+     * routed to EL2 (in non-secure world).
+     */
+    hcr_routing &= (env->cp15.hcr_el2 & HCR_TGE) == HCR_TGE;
+
+    /* Determine target EL according to ARM ARMv8 tables G1-15 and G1-16 */
+    if (arm_el_is_aa64(env, 3)) {
+        /* EL3 in Aarch64 */
+        if (!secure) {
+            /* If non-secure, we may route to EL2 depending on other state.
+             * If we are coming from the secure world then we always route to
+             * EL1.
+             */
+            if (hcr_routing ||
+                (cur_el == 2 && !(env->cp15.scr_el3 & SCR_RW))) {
+                /* If HCR.FMO/IMO is set or we already in EL2 and it is not
+                 * configured to be AArch64 then route to EL2.
+                 */
+                target_el = 2;
+            }
+        }
+    } else {
+        /* EL3 in Aarch32 */
+        if (secure) {
+            /* If coming from secure always route to EL3 */
+            target_el = 3;
+        } else if (hcr_routing || cur_el == 2) {
+            /* If HCR.FMO/IMO is set or we are already EL2 then route to EL2 */
+            target_el = 2;
+        }
+    }
+
+    return target_el;
+}
+
+/*
  * Determine the target EL for a given exception type.
  */
 unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
@@ -3774,14 +3854,8 @@ unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
     unsigned int cur_el = arm_current_el(env);
-    unsigned int target_el;
-    /* FIXME: Use actual secure state.  */
-    bool secure = false;
-
-    if (!env->aarch64) {
-        /* TODO: Add EL2 and 3 exception handling for AArch32.  */
-        return 1;
-    }
+    unsigned int target_el = 1;
+    bool secure = arm_is_secure(env);
 
     switch (excp_idx) {
     case EXCP_HVC:
@@ -3793,19 +3867,8 @@ unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
         break;
     case EXCP_FIQ:
     case EXCP_IRQ:
-    {
-        const uint64_t hcr_mask = excp_idx == EXCP_FIQ ? HCR_FMO : HCR_IMO;
-        const uint32_t scr_mask = excp_idx == EXCP_FIQ ? SCR_FIQ : SCR_IRQ;
-
-        target_el = 1;
-        if (!secure && (env->cp15.hcr_el2 & hcr_mask)) {
-            target_el = 2;
-        }
-        if (env->cp15.scr_el3 & scr_mask) {
-            target_el = 3;
-        }
+        target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure);
         break;
-    }
     case EXCP_VIRQ:
     case EXCP_VFIQ:
         target_el = 1;
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 09/33] target-arm: add macros to access banked registers
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (7 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 08/33] target-arm: add async excp target_el function Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-10-06 16:09   ` Peter Maydell
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 10/33] target-arm: add non-secure Translation Block flag Greg Bellows
                   ` (24 subsequent siblings)
  33 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Sergey Fedorov, Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

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.

- A32_BANKED macros are used for choosing the banked register based on provided
  input security argument.  This macro is used to choose the bank during
  translation of MRC/MCR instructions that are dependent on something other
  than the current secure state.
- A32_BANKED_CURRENT macros are used for choosing the banked register based on
  current secure state.  This is NOT to be used for choosing the bank used
  during translation as it breaks monitor mode.

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.fedorov@samsung.com>
Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

----------
v4 -> v5
- Cleaned-up macros to try and alleviate misuse.  Made A32_BANKED macros take
  secure arg indicator rather than relying on USE_SECURE_REG.  Incorporated the
  A32_BANKED macros into the A32_BANKED_CURRENT.  CURRENT is now the only one
  that automatically chooses based on current secure state.
---
 target-arm/cpu.h | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 601f8fe..c58fdf5 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -807,6 +807,42 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
     return arm_feature(env, ARM_FEATURE_AARCH64);
 }
 
+/* Macro for determing whether to use the secure or non-secure bank of a CP
+ * register.  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))
+
+/* Macros for accessing a specified CP register bank */
+#define A32_BANKED_REG_GET(_env, _regname, _secure)    \
+    ((_secure) ? (_env)->cp15._regname##_s : (_env)->cp15._regname##_ns)
+
+#define A32_BANKED_REG_SET(_env, _regname, _secure, _val)   \
+    do {                                                \
+        if (_secure) {                                   \
+            (_env)->cp15._regname##_s = (_val);            \
+        } else {                                        \
+            (_env)->cp15._regname##_ns = (_val);           \
+        }                                               \
+    } while (0)
+
+/* Macros for automatically accessing a specific CP register bank depending on
+ * the current secure state of the system.  These macros are not intended for
+ * supporting instruction translation reads/writes as these are dependent
+ * solely on the SCR.NS bit and not the mode.
+ */
+#define A32_BANKED_CURRENT_REG_GET(_env, _regname)        \
+    A32_BANKED_REG_GET((_env), _regname,                \
+                       ((!arm_el_is_aa64((_env), 3) && arm_is_secure(_env))))
+
+#define A32_BANKED_CURRENT_REG_SET(_env, _regname, _val)                       \
+    A32_BANKED_REG_SET((_env), _regname,                                    \
+                       ((!arm_el_is_aa64((_env), 3) && arm_is_secure(_env))),  \
+                       (_val))
+
 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 excp_idx,
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 10/33] target-arm: add non-secure Translation Block flag
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (8 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 09/33] target-arm: add macros to access banked registers Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-10-06 16:13   ` Peter Maydell
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 11/33] target-arm: arrayfying fieldoffset for banking Greg Bellows
                   ` (23 subsequent siblings)
  33 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Sergey Fedorov, Greg Bellows

From: Sergey Fedorov <s.fedorov@samsung.com>

This patch is based on idea found in patch at
git://github.com/jowinter/qemu-trustzone.git
f3d955c6c0ed8c46bc0eb10b634201032a651dd2 by
Johannes Winter <johannes.winter@iaik.tugraz.at>.

This flag prevents QEMU from executing TCG code generated for other CPU
security state. It also allows to generate different TCG code depending on
CPU secure state.

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>

----------
v4 -> v5
- Merge changes
- Fixed issue where TB secure state flag was incorrectly being set based on
  secure state rather than NS setting.  This caused an issue where monitor mode
  MRC/MCR accesses were always secure rather than being based on NS bit
  setting.
- Added separate 64/32 TB secure state flags
- Unconditionalized the setting of the DC ns bit
- Removed IS_NS macro and replaced with direct usage.
---
 target-arm/cpu.h           | 14 ++++++++++++++
 target-arm/translate-a64.c |  1 +
 target-arm/translate.c     |  1 +
 target-arm/translate.h     |  1 +
 4 files changed, 17 insertions(+)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c58fdf5..1700676 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1528,6 +1528,8 @@ static inline bool arm_singlestep_active(CPUARMState *env)
  */
 #define ARM_TBFLAG_XSCALE_CPAR_SHIFT 20
 #define ARM_TBFLAG_XSCALE_CPAR_MASK (3 << ARM_TBFLAG_XSCALE_CPAR_SHIFT)
+#define ARM_TBFLAG_NS_SHIFT         22
+#define ARM_TBFLAG_NS_MASK          (1 << ARM_TBFLAG_NS_SHIFT)
 
 /* Bit usage when in AArch64 state */
 #define ARM_TBFLAG_AA64_EL_SHIFT    0
@@ -1538,6 +1540,8 @@ static inline bool arm_singlestep_active(CPUARMState *env)
 #define ARM_TBFLAG_AA64_SS_ACTIVE_MASK (1 << ARM_TBFLAG_AA64_SS_ACTIVE_SHIFT)
 #define ARM_TBFLAG_AA64_PSTATE_SS_SHIFT 4
 #define ARM_TBFLAG_AA64_PSTATE_SS_MASK (1 << ARM_TBFLAG_AA64_PSTATE_SS_SHIFT)
+#define ARM_TBFLAG_AA64_NS_SHIFT    5
+#define ARM_TBFLAG_AA64_NS_MASK     (1 << ARM_TBFLAG_AA64_NS_SHIFT)
 
 /* some convenience accessor macros */
 #define ARM_TBFLAG_AARCH64_STATE(F) \
@@ -1572,6 +1576,10 @@ static inline bool arm_singlestep_active(CPUARMState *env)
     (((F) & ARM_TBFLAG_AA64_SS_ACTIVE_MASK) >> ARM_TBFLAG_AA64_SS_ACTIVE_SHIFT)
 #define ARM_TBFLAG_AA64_PSTATE_SS(F) \
     (((F) & ARM_TBFLAG_AA64_PSTATE_SS_MASK) >> ARM_TBFLAG_AA64_PSTATE_SS_SHIFT)
+#define ARM_TBFLAG_NS(F) \
+    (((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT)
+#define ARM_TBFLAG_AA64_NS(F) \
+    (((F) & ARM_TBFLAG_AA64_NS_MASK) >> ARM_TBFLAG_AA64_NS_SHIFT)
 
 static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
@@ -1605,6 +1613,9 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
                 *flags |= ARM_TBFLAG_AA64_PSTATE_SS_MASK;
             }
         }
+        if (!(USE_SECURE_REG(env))) {
+            *flags |= ARM_TBFLAG_AA64_NS_MASK;
+        }
     } else {
         int privmode;
         *pc = env->regs[15];
@@ -1621,6 +1632,9 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
         if (privmode) {
             *flags |= ARM_TBFLAG_PRIV_MASK;
         }
+        if (!(USE_SECURE_REG(env))) {
+            *flags |= ARM_TBFLAG_NS_MASK;
+        }
         if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
             || arm_el_is_aa64(env, 1)) {
             *flags |= ARM_TBFLAG_VFPEN_MASK;
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index f53dc0f..dfc8c58 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -10926,6 +10926,7 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
 #if !defined(CONFIG_USER_ONLY)
     dc->user = (ARM_TBFLAG_AA64_EL(tb->flags) == 0);
 #endif
+    dc->ns = ARM_TBFLAG_AA64_NS(tb->flags);
     dc->cpacr_fpen = ARM_TBFLAG_AA64_FPEN(tb->flags);
     dc->vec_len = 0;
     dc->vec_stride = 0;
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 3f3ddfb..5e1d677 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -10958,6 +10958,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
 #if !defined(CONFIG_USER_ONLY)
     dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
 #endif
+    dc->ns = ARM_TBFLAG_NS(tb->flags);
     dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags);
     dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
     dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
diff --git a/target-arm/translate.h b/target-arm/translate.h
index 85c6f9d..4f9892b 100644
--- a/target-arm/translate.h
+++ b/target-arm/translate.h
@@ -20,6 +20,7 @@ typedef struct DisasContext {
 #if !defined(CONFIG_USER_ONLY)
     int user;
 #endif
+    bool ns;
     bool cpacr_fpen; /* FP enabled via CPACR.FPEN */
     bool vfp_enabled; /* FP enabled via FPSCR.EN */
     int vec_len;
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 11/33] target-arm: arrayfying fieldoffset for banking
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (9 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 10/33] target-arm: add non-secure Translation Block flag Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-10-06 16:19   ` Peter Maydell
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 12/33] target-arm: insert Aarch32 cpregs twice into hashtable Greg Bellows
                   ` (22 subsequent siblings)
  33 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

Prepare ARMCPRegInfo to support specifying two fieldoffsets per
register definition. This will allow us to keep one register
definition for banked registers (different offsets for secure/
non-secure world).

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

----------
v4 -> v5
- Added ARM CP register secure and non-secure bank flags
- Added setting of secure and non-secure flags furing registration
---
 target-arm/cpu.h    | 23 +++++++++++++++-----
 target-arm/helper.c | 60 +++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 65 insertions(+), 18 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 1700676..9681d45 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -958,10 +958,12 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
 #define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8))
 #define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | (5 << 8))
 #define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
+#define ARM_CP_BANK_S   (1 << 16)
+#define ARM_CP_BANK_NS  (2 << 16)
 /* Used only as a terminator for ARMCPRegInfo lists */
-#define ARM_CP_SENTINEL 0xffff
+#define ARM_CP_SENTINEL 0xffffff
 /* Mask of only the flag bits in a type field */
-#define ARM_CP_FLAG_MASK 0x7f
+#define ARM_CP_FLAG_MASK 0x3007f
 
 /* Valid values for ARMCPRegInfo state field, indicating which of
  * the AArch32 and AArch64 execution states this register is visible in.
@@ -1096,6 +1098,7 @@ struct ARMCPRegInfo {
     uint8_t opc0;
     uint8_t opc1;
     uint8_t opc2;
+
     /* Execution state in which this register is visible: ARM_CP_STATE_* */
     int state;
     /* Register type: ARM_CP_* bits/values */
@@ -1111,12 +1114,22 @@ struct ARMCPRegInfo {
      * fieldoffset is non-zero, the reset value of the register.
      */
     uint64_t resetvalue;
-    /* Offset of the field in CPUARMState for this register. This is not
-     * needed if either:
+    /* Offsets of the fields (secure/non-secure) in CPUARMState for this
+     * register. The array will be accessed by the ns bit which means the
+     * secure instance has to be at [0] while the non-secure instance must be
+     * at [1]. If a register is not banked .fieldoffset can be used, which maps
+     * to the non-secure bank.
+     * This is not needed if either:
      *  1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
      *  2. both readfn and writefn are specified
      */
-    ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
+    union { /* offsetof(CPUARMState, field) */
+        struct {
+            ptrdiff_t fieldoffset_padding;
+            ptrdiff_t fieldoffset;
+        };
+        ptrdiff_t bank_fieldoffsets[2];
+    };
     /* Function for making any access checks for this register in addition to
      * those specified by the 'access' permissions bits. If NULL, no extra
      * checks required. The access check is performed at runtime, not at
diff --git a/target-arm/helper.c b/target-arm/helper.c
index a10f459..ab38b68 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3296,22 +3296,56 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
     uint32_t *key = g_new(uint32_t, 1);
     ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
     int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
-    if (r->state == ARM_CP_STATE_BOTH && state == ARM_CP_STATE_AA32) {
-        /* The AArch32 view of a shared register sees the lower 32 bits
-         * of a 64 bit backing field. It is not migratable as the AArch64
-         * view handles that. AArch64 also handles reset.
-         * We assume it is a cp15 register if the .cp field is left unset.
-         */
-        if (r2->cp == 0) {
-            r2->cp = 15;
+
+    if (state == ARM_CP_STATE_AA32) {
+        /* Clear the secure state flags and set based on incoming nsbit */
+        r2->type &= ~(ARM_CP_BANK_S | ARM_CP_BANK_NS);
+        r2->type |= ARM_CP_BANK_S << nsbit;
+
+        if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
+            /* Register is banked (using both entries in array).
+             * Overwriting fieldoffset as the array was only used to define
+             * banked registers but later only fieldoffset is used.
+             */
+            r2->fieldoffset = r->bank_fieldoffsets[nsbit];
+
+            /* If V8 is enabled then we don't need to migrate or reset the
+             * AArch32 version of the banked registers as this will be handled
+             * through the AArch64 view.
+             * The exception to the above is cpregs with a crn of 13
+             * (specifically FCSEIDR and CONTEXTIDR) in which case there may
+             * not be an AArch64 equivalent for one or either bank so migration
+             * and reset must be preserved.
+             */
+            if (arm_feature(&cpu->env, ARM_FEATURE_V8) && r->crn != 13) {
+                r2->type |= ARM_CP_NO_MIGRATE;
+                r2->resetfn = arm_cp_reset_ignore;
+            }
+        } else if (!nsbit) {
+            /* The register is not banked so we only want to allow migration of
+             * the non-secure instance.
+             */
+            r2->type |= ARM_CP_NO_MIGRATE;
+            r2->resetfn = arm_cp_reset_ignore;
         }
-        r2->type |= ARM_CP_NO_MIGRATE;
-        r2->resetfn = arm_cp_reset_ignore;
+
+        if (r->state == ARM_CP_STATE_BOTH) {
+            /* The AArch32 view of a shared register sees the lower 32 bits
+             * of a 64 bit backing field. It is not migratable as the AArch64
+             * view handles that. AArch64 also handles reset.
+             * We assume it is a cp15 register if the .cp field is left unset.
+             */
+            if (r2->cp == 0) {
+                r2->cp = 15;
+            }
+            r2->type |= ARM_CP_NO_MIGRATE;
+            r2->resetfn = arm_cp_reset_ignore;
 #ifdef HOST_WORDS_BIGENDIAN
-        if (r2->fieldoffset) {
-            r2->fieldoffset += sizeof(uint32_t);
-        }
+            if (r2->fieldoffset) {
+                r2->fieldoffset += sizeof(uint32_t);
+            }
 #endif
+        }
     }
     if (state == ARM_CP_STATE_AA64) {
         /* To allow abbreviation of ARMCPRegInfo
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 12/33] target-arm: insert Aarch32 cpregs twice into hashtable
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (10 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 11/33] target-arm: arrayfying fieldoffset for banking Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-10-06 16:25   ` Peter Maydell
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 13/33] target-arm: move Aarch32 SCR into security reglist Greg Bellows
                   ` (21 subsequent siblings)
  33 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

Prepare for cp register banking by inserting every cp register twice,
once for secure world and once for non-secure world.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

----------
v4 -> v5
- Added use of ARM CP secure/non-secure bank flags during register processing
  in define_one_arm_cp_reg_with_opaque().  We now only register the specified
  bank if only one flag is specified, otherwise we register both a secure and
  non-secure instance.
---
 target-arm/cpu.h       | 14 +++++++++++---
 target-arm/helper.c    | 30 ++++++++++++++++++++++++++----
 target-arm/translate.c | 14 +++++++++-----
 3 files changed, 46 insertions(+), 12 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 9681d45..220571c 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -864,6 +864,7 @@ void armv7m_nvic_complete_irq(void *opaque, int irq);
  *  Crn, Crm, opc1, opc2 fields
  *  32 or 64 bit register (ie is it accessed via MRC/MCR
  *    or via MRRC/MCRR?)
+ *  non-secure/secure bank (Aarch32 only)
  * We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field.
  * (In this case crn and opc2 should be zero.)
  * For AArch64, there is no 32/64 bit size distinction;
@@ -881,9 +882,16 @@ void armv7m_nvic_complete_irq(void *opaque, int irq);
 #define CP_REG_AA64_SHIFT 28
 #define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
 
-#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2)   \
-    (((cp) << 16) | ((is64) << 15) | ((crn) << 11) |    \
-     ((crm) << 7) | ((opc1) << 3) | (opc2))
+/* To enable banking of coprocessor registers depending on ns-bit we
+ * add a bit to distinguish between secure and non-secure cpregs in the
+ * hashtable.
+ */
+#define CP_REG_NS_SHIFT 27
+#define CP_REG_NS_MASK(nsbit) (nsbit << CP_REG_NS_SHIFT)
+
+#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2, ns)   \
+    (CP_REG_NS_MASK(ns) | ((cp) << 16) | ((is64) << 15) |   \
+     ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
 
 #define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
     (CP_REG_AA64_MASK |                                 \
diff --git a/target-arm/helper.c b/target-arm/helper.c
index ab38b68..a0f53dd 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3288,7 +3288,7 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
 
 static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
                                    void *opaque, int state,
-                                   int crm, int opc1, int opc2)
+                                   int crm, int opc1, int opc2, int nsbit)
 {
     /* Private utility function for define_one_arm_cp_reg_with_opaque():
      * add a single reginfo struct to the hash table.
@@ -3361,7 +3361,7 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
         *key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
                                   r2->opc0, opc1, opc2);
     } else {
-        *key = ENCODE_CP_REG(r2->cp, is64, r2->crn, crm, opc1, opc2);
+        *key = ENCODE_CP_REG(r2->cp, is64, r2->crn, crm, opc1, opc2, nsbit);
     }
     if (opaque) {
         r2->opaque = opaque;
@@ -3510,8 +3510,30 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
                     if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
                         continue;
                     }
-                    add_cpreg_to_hashtable(cpu, r, opaque, state,
-                                           crm, opc1, opc2);
+                    if (state == ARM_CP_STATE_AA32) {
+                        /* Under Aarch32 CP registers can be common
+                         * (same for secure and non-secure world) or banked.
+                         */
+                        uint32_t s =
+                                r->type & (ARM_CP_BANK_S | ARM_CP_BANK_NS);
+                        if (ARM_CP_BANK_S == s) {
+                            add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                    crm, opc1, opc2, !SCR_NS);
+                        } else if (ARM_CP_BANK_NS == s) {
+                            add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                    crm, opc1, opc2, SCR_NS);
+                        } else {
+                            add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                    crm, opc1, opc2, !SCR_NS);
+                            add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                    crm, opc1, opc2, SCR_NS);
+                        }
+                    } else {
+                        /* Aarch64 registers get mapped to non-secure instance
+                         * of Aarch32 */
+                        add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                crm, opc1, opc2, SCR_NS);
+                    }
                 }
             }
         }
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 5e1d677..7720ed8 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -7038,7 +7038,7 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
     rt = (insn >> 12) & 0xf;
 
     ri = get_arm_cp_reginfo(s->cp_regs,
-                            ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
+            ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2, s->ns));
     if (ri) {
         /* Check access permissions */
         if (!cp_access_ok(s->current_pl, ri, isread)) {
@@ -7228,12 +7228,16 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
      */
     if (is64) {
         qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
-                      "64 bit system register cp:%d opc1: %d crm:%d\n",
-                      isread ? "read" : "write", cpnum, opc1, crm);
+                      "64 bit system register cp:%d opc1: %d crm:%d "
+                      "(%s)\n",
+                      isread ? "read" : "write", cpnum, opc1, crm,
+                      s->ns ? "non-secure" : "secure");
     } else {
         qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
-                      "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
-                      isread ? "read" : "write", cpnum, opc1, crn, crm, opc2);
+                      "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
+                      "(%s)\n",
+                      isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
+                      s->ns ? "non-secure" : "secure");
     }
 
     return 1;
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 13/33] target-arm: move Aarch32 SCR into security reglist
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (11 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 12/33] target-arm: insert Aarch32 cpregs twice into hashtable Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 14/33] target-arm: implement IRQ/FIQ routing to Monitor mode Greg Bellows
                   ` (20 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Sergey Fedorov, Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

Define a new ARM CP register info list for the ARMv7 Security Extension
feature. Register that list only for ARM cores with Security Extension/EL3
support. Moving Aarch32 SCR into Security Extension register group.

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>

------------------
v4 -> v5
- Added reset value on SCR_EL3
- Squashed SCR Migration fix (previously patch 33)
  This patch adds code to mark duplicate CP register registrations as
  NO_MIGRATE to avoid duplicate migrations.

v3 -> v4
- Renamed security_cp_reginfo to v7_el3_cp_reginfo
- Conditionalized define on whether v7 or v8 were enabled

Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
---
 target-arm/helper.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index a0f53dd..cb2eb3c 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -898,9 +898,6 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
       .access = PL1_RW, .writefn = vbar_write,
       .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[1]),
       .resetvalue = 0 },
-    { .name = "SCR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3),
-      .resetvalue = 0, .writefn = scr_write },
     { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
       .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_MIGRATE },
@@ -2335,11 +2332,21 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
       .access = PL3_RW, .writefn = vbar_write,
       .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[3]),
       .resetvalue = 0 },
-    { .name = "SCR_EL3", .state = ARM_CP_STATE_AA64,
-      .type = ARM_CP_NO_MIGRATE,
+      /* SCR will always be registered for v7, but not necessarily for v8, so
+       * this entry is marked to allow migration to be handled by the v7
+       * registration instance.
+       */
+    { .name = "SCR_EL3", .state = ARM_CP_STATE_AA64, .type = ARM_CP_NO_MIGRATE,
       .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
       .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
-      .writefn = scr_write },
+      .resetvalue = 0, .writefn = scr_write },
+    REGINFO_SENTINEL
+};
+
+static const ARMCPRegInfo v7_el3_cp_reginfo[] = {
+    { .name = "SCR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0,
+      .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
+      .resetvalue = 0, .writefn = scr_write},
     REGINFO_SENTINEL
 };
 
@@ -2960,7 +2967,12 @@ void register_cp_regs_for_features(ARMCPU *cpu)
         }
     }
     if (arm_feature(env, ARM_FEATURE_EL3)) {
-        define_arm_cp_regs(cpu, v8_el3_cp_reginfo);
+        if (arm_feature(env, ARM_FEATURE_V8)) {
+            define_arm_cp_regs(cpu, v8_el3_cp_reginfo);
+        }
+        if (arm_feature(env, ARM_FEATURE_V7)) {
+            define_arm_cp_regs(cpu, v7_el3_cp_reginfo);
+        }
     }
     if (arm_feature(env, ARM_FEATURE_MPU)) {
         /* These are the MPU registers prior to PMSAv6. Any new
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 14/33] target-arm: implement IRQ/FIQ routing to Monitor mode
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (12 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 13/33] target-arm: move Aarch32 SCR into security reglist Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 15/33] target-arm: Respect SCR.FW, SCR.AW and SCTLR.NMFI Greg Bellows
                   ` (19 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Sergey Fedorov, Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

SCR.{IRQ/FIQ} bits allow to route IRQ/FIQ exceptions to monitor CPU
mode. When taking IRQ exception to monitor mode FIQ exception is
additionally masked.

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>
---
 target-arm/helper.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index cb2eb3c..8cc94ce 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -4213,12 +4213,21 @@ void arm_cpu_do_interrupt(CPUState *cs)
         /* Disable IRQ and imprecise data aborts.  */
         mask = CPSR_A | CPSR_I;
         offset = 4;
+        if (env->cp15.scr_el3 & SCR_IRQ) {
+            /* IRQ routed to monitor mode */
+            new_mode = ARM_CPU_MODE_MON;
+            mask |= CPSR_F;
+        }
         break;
     case EXCP_FIQ:
         new_mode = ARM_CPU_MODE_FIQ;
         addr = 0x1c;
         /* Disable FIQ, IRQ and imprecise data aborts.  */
         mask = CPSR_A | CPSR_I | CPSR_F;
+        if (env->cp15.scr_el3 & SCR_FIQ) {
+            /* FIQ routed to monitor mode */
+            new_mode = ARM_CPU_MODE_MON;
+        }
         offset = 4;
         break;
     case EXCP_SMC:
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 15/33] target-arm: Respect SCR.FW, SCR.AW and SCTLR.NMFI
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (13 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 14/33] target-arm: implement IRQ/FIQ routing to Monitor mode Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 16/33] target-arm: add NSACR register Greg Bellows
                   ` (18 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

bits when modifying CPSR.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

---------------
v3 -> v4
- Fixed up conditions for ignoring CPSR.A/F updates by isolating to v7 and
  checking for the existence of EL3 and non-existence of EL2.
---
 target-arm/helper.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 59 insertions(+), 3 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 8cc94ce..f897848 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3641,9 +3641,6 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
         env->GE = (val >> 16) & 0xf;
     }
 
-    env->daif &= ~(CPSR_AIF & mask);
-    env->daif |= val & CPSR_AIF & mask;
-
     if ((env->uncached_cpsr ^ val) & mask & CPSR_M) {
         if (bad_mode_switch(env, val & CPSR_M)) {
             /* Attempt to switch to an invalid mode: this is UNPREDICTABLE.
@@ -3655,6 +3652,65 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
             switch_mode(env, val & CPSR_M);
         }
     }
+
+    /* In a V7 implementation that incldoes the security extensions but does
+     * not include Virtualization Extensions the SCR.FW and SCR.AW bits control
+     * whether non-secure software is allowed to change the CPSR_F and CPSR_A
+     * bits respectively.
+     *
+     * In a V8 implementation, it is permitted for privileged software to
+     * change the CPSR A/F bits regardless of the SCR.AW/FW bits.  However,
+     * when the SPSR is copied to the CPSR, the SCR.AW/FW bits control whether
+     * the CPSR.A/F bits are copied.
+     */
+    if (!arm_feature(env, ARM_FEATURE_V8)) {
+        if ((mask & CPSR_A) &&
+            (val & CPSR_A) != (env->uncached_cpsr & CPSR_A) &&
+            arm_feature(env, ARM_FEATURE_EL3) &&
+            !arm_feature(env, ARM_FEATURE_EL2) &&
+            !(env->cp15.scr_el3 & SCR_AW) && !arm_is_secure(env)) {
+            qemu_log_mask(LOG_GUEST_ERROR,
+                          "Ignoring attempt to switch CPSR_A flag from "
+                          "non-secure world with SCR.AW bit clear\n");
+            mask &= ~CPSR_A;
+        }
+
+        if ((mask & CPSR_F) &&
+            (val & CPSR_F) != (env->uncached_cpsr & CPSR_F)) {
+            /*
+             * The existence of the security extension (EL3) and the
+             * non-existence of the virtualization extension affects whether
+             * the CPSR.F bit can be modified.
+             */
+            if (arm_feature(env, ARM_FEATURE_EL3) &&
+                !arm_feature(env, ARM_FEATURE_EL2)) {
+                /* CPSR.F cannot be changed in nonsecure with SCR.FW clear */
+                if (!(env->cp15.scr_el3 & SCR_FW) && !arm_is_secure(env)) {
+                    qemu_log_mask(LOG_GUEST_ERROR,
+                                  "Ignoring attempt to switch CPSR_F flag from "
+                                  "non-secure world with SCR.FW bit clear\n");
+                    mask &= ~CPSR_F;
+                }
+
+                /* Check whether non-maskable FIQ (NMFI) support is enabled.
+                 * If this bit is set software is not allowed to mask
+                 * FIQs, but is allowed to set CPSR_F to 0.
+                 */
+                if ((A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_NMFI) &&
+                    (val & CPSR_F)) {
+                    qemu_log_mask(LOG_GUEST_ERROR,
+                                  "Ignoring attempt to enable CPSR_F flag "
+                                  "(non-maskable FIQ [NMFI] support "
+                                  "enabled)\n");
+                    mask &= ~CPSR_F;
+                }
+            }
+        }
+    }
+
+    env->daif &= ~(CPSR_AIF & mask);
+    env->daif |= val & CPSR_AIF & mask;
+
     mask &= ~CACHED_CPSR_BITS;
     env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
 }
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 16/33] target-arm: add NSACR register
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (14 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 15/33] target-arm: Respect SCR.FW, SCR.AW and SCTLR.NMFI Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 17/33] target-arm: add SDER definition Greg Bellows
                   ` (17 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Sergey Fedorov, Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

Implements NSACR register with corresponding read/write functions
for ARMv7 and ARMv8.

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>

----------
v4 -> v5
- Changed to use renamed arm_current_el()
---
 target-arm/cpu.h    |  6 +++++
 target-arm/helper.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 220571c..5be258b 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -181,6 +181,7 @@ typedef struct CPUARMState {
         uint64_t c1_sys; /* System control register.  */
         uint64_t c1_coproc; /* Coprocessor access register.  */
         uint32_t c1_xscaleauxcr; /* XScale auxiliary control register.  */
+        uint32_t c1_nsacr; /* Non-secure access control register. */
         uint64_t ttbr0_el1; /* MMU translation table base 0. */
         uint64_t ttbr1_el1; /* MMU translation table base 1. */
         uint64_t c2_control; /* MMU translation table base control.  */
@@ -634,6 +635,11 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
 #define SCR_AARCH32_MASK      (0x3fff & ~(SCR_RW | SCR_ST))
 #define SCR_AARCH64_MASK      (0x3fff & ~SCR_NET)
 
+#define NSACR_NSTRCDIS (1U << 20)
+#define NSACR_RFR      (1U << 19)
+#define NSACR_NSASEDIS (1U << 15)
+#define NSACR_NSD32DIS (1U << 14)
+
 /* Return the current FPSCR value.  */
 uint32_t vfp_get_fpscr(CPUARMState *env);
 void vfp_set_fpscr(CPUARMState *env, uint32_t val);
diff --git a/target-arm/helper.c b/target-arm/helper.c
index f897848..0c3663a 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -520,7 +520,19 @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
             /* VFP coprocessor: cp10 & cp11 [23:20] */
             mask |= (1 << 31) | (1 << 30) | (0xf << 20);
 
-            if (!arm_feature(env, ARM_FEATURE_NEON)) {
+            if (arm_feature(env, ARM_FEATURE_NEON)) {
+                /* NSACR can disable non-secure writes to
+                 * ASEDIS [31] or D32DIS [30]
+                 */
+                if (arm_feature(env, ARM_FEATURE_EL3) && !arm_is_secure(env)) {
+                    if ((env->cp15.c1_nsacr & NSACR_NSASEDIS)) {
+                        mask &= ~(1 << 31);
+                    }
+                    if ((env->cp15.c1_nsacr & NSACR_NSD32DIS)) {
+                        mask &= ~(1 << 30);
+                    }
+                }
+            } else {
                 /* ASEDIS [31] bit is RAO/WI */
                 value |= (1 << 31);
             }
@@ -532,6 +544,7 @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                     !arm_feature(env, ARM_FEATURE_VFP3)) {
                 /* D32DIS [30] is RAO/WI if D16-31 are not implemented. */
                 value |= (1 << 30);
+                mask |= (1 << 30);
             }
         }
         value &= mask;
@@ -2310,6 +2323,55 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
+static void nsacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                      uint64_t value)
+{
+    uint32_t mask = 0;
+
+    /* Pre ARMv8 some bits are RAO or UNK/SBZP */
+    if (!arm_feature(env, ARM_FEATURE_V8)) {
+
+        if (arm_feature(env, ARM_FEATURE_VFP)) {
+            mask |= NSACR_NSASEDIS | NSACR_NSD32DIS;
+
+            if (!arm_feature(env, ARM_FEATURE_NEON)) {
+                /* NSASEDIS are RAO/WI */
+                value |= NSACR_NSASEDIS;
+            }
+
+            /* VFPv3 and upwards with NEON implement 32 double precision
+             * registers (D0-D31).
+             */
+            if (!arm_feature(env, ARM_FEATURE_NEON) ||
+                    !arm_feature(env, ARM_FEATURE_VFP3)) {
+                /* NSD32DIS is RAO/WI if D16-31 are not implemented. */
+                value |= NSACR_NSD32DIS;
+            }
+        }
+
+        /* cpn bits [13:0] */
+        mask = 0x3fff;
+
+        value &= mask;
+    }
+
+    raw_write(env, ri, value);
+}
+
+static uint64_t nsacr_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    uint64_t ret = raw_read(env, ri);
+
+    if (arm_feature(env, ARM_FEATURE_V8)) {
+        if (!arm_feature(env, ARM_FEATURE_EL3) || (
+                arm_el_is_aa64(env, 3) && !is_a64(env) &&
+                arm_current_el(env) != 3)) {
+            ret = 0x0000C00;
+        }
+    }
+    return ret;
+}
+
 static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
     { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_MIGRATE,
@@ -2347,6 +2409,10 @@ static const ARMCPRegInfo v7_el3_cp_reginfo[] = {
     { .name = "SCR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0,
       .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
       .resetvalue = 0, .writefn = scr_write},
+    { .name = "NSACR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 2,
+      .access = PL3_RW | PL1_R, .resetvalue = 0,
+      .writefn = nsacr_write, .readfn = nsacr_read,
+      .fieldoffset = offsetof(CPUARMState, cp15.c1_nsacr) },
     REGINFO_SENTINEL
 };
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 17/33] target-arm: add SDER definition
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (15 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 16/33] target-arm: add NSACR register Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 18/33] target-arm: add MVBAR support Greg Bellows
                   ` (16 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Sergey Fedorov, Greg Bellows

From: Sergey Fedorov <s.fedorov@samsung.com>

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>
---
 target-arm/cpu.h    | 1 +
 target-arm/helper.c | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 5be258b..f7148d1 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -181,6 +181,7 @@ typedef struct CPUARMState {
         uint64_t c1_sys; /* System control register.  */
         uint64_t c1_coproc; /* Coprocessor access register.  */
         uint32_t c1_xscaleauxcr; /* XScale auxiliary control register.  */
+        uint32_t c1_sder; /* Secure debug enable register. */
         uint32_t c1_nsacr; /* Non-secure access control register. */
         uint64_t ttbr0_el1; /* MMU translation table base 0. */
         uint64_t ttbr1_el1; /* MMU translation table base 1. */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 0c3663a..778c21c 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2409,6 +2409,9 @@ static const ARMCPRegInfo v7_el3_cp_reginfo[] = {
     { .name = "SCR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0,
       .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
       .resetvalue = 0, .writefn = scr_write},
+    { .name = "SDER", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 1,
+      .access = PL3_RW, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.c1_sder) },
     { .name = "NSACR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 2,
       .access = PL3_RW | PL1_R, .resetvalue = 0,
       .writefn = nsacr_write, .readfn = nsacr_read,
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 18/33] target-arm: add MVBAR support
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (16 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 17/33] target-arm: add SDER definition Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 19/33] target-arm: add SCTLR_EL3 and make SCTLR banked Greg Bellows
                   ` (15 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Sergey Fedorov, Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

Use MVBAR register as exception vector base address for
exceptions taken to CPU monitor mode.

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>
---
 target-arm/cpu.h    |  1 +
 target-arm/helper.c | 15 +++++++++------
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index f7148d1..1b6ce8a 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -211,6 +211,7 @@ typedef struct CPUARMState {
         uint32_t c9_pminten; /* perf monitor interrupt enables */
         uint64_t mair_el1;
         uint64_t vbar_el[4]; /* vector base address register */
+        uint64_t mvbar; /* (monitor) vector base address register */
         uint32_t c13_fcse; /* FCSE PID.  */
         uint64_t contextidr_el1; /* Context ID.  */
         uint64_t tpidr_el0; /* User RW Thread register.  */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 778c21c..4ad55d5 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2416,6 +2416,9 @@ static const ARMCPRegInfo v7_el3_cp_reginfo[] = {
       .access = PL3_RW | PL1_R, .resetvalue = 0,
       .writefn = nsacr_write, .readfn = nsacr_read,
       .fieldoffset = offsetof(CPUARMState, cp15.c1_nsacr) },
+    { .name = "MVBAR", .cp = 15, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 1,
+      .access = PL3_RW, .writefn = vbar_write, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.mvbar) },
     REGINFO_SENTINEL
 };
 
@@ -4365,16 +4368,16 @@ void arm_cpu_do_interrupt(CPUState *cs)
         cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
         return; /* Never happens.  Keep compiler happy.  */
     }
-    /* High vectors.  */
-    if (env->cp15.c1_sys & SCTLR_V) {
-        /* when enabled, base address cannot be remapped.  */
+
+    if (new_mode == ARM_CPU_MODE_MON) {
+        addr += env->cp15.mvbar;
+    } else if (env->cp15.c1_sys & SCTLR_V) {
+        /* High vectors. When enabled, base address cannot be remapped. */
         addr += 0xffff0000;
     } else {
         /* ARM v7 architectures provide a vector base address register to remap
          * the interrupt vector table.
-         * This register is only followed in non-monitor mode, and has a secure
-         * and un-secure copy. Since the cpu is always in a un-secure operation
-         * and is never in monitor mode this feature is always active.
+         * This register is only followed in non-monitor mode, and is banked.
          * Note: only bits 31:5 are valid.
          */
         addr += env->cp15.vbar_el[1];
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 19/33] target-arm: add SCTLR_EL3 and make SCTLR banked
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (17 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 18/33] target-arm: add MVBAR support Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 20/33] target-arm: make CSSELR banked Greg Bellows
                   ` (14 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

Implements SCTLR_EL3 and uses secure/non-secure instance when
needed.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
---
 hw/arm/pxa2xx.c        |  2 +-
 target-arm/cpu.c       |  5 +--
 target-arm/cpu.h       | 13 +++++++-
 target-arm/helper.c    | 85 ++++++++++++++++++++++++++++++++------------------
 target-arm/op_helper.c |  2 +-
 5 files changed, 71 insertions(+), 36 deletions(-)

diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 7d306fb..0114597 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -272,7 +272,7 @@ static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
     case 3:
         s->cpu->env.uncached_cpsr = ARM_CPU_MODE_SVC;
         s->cpu->env.daif = PSTATE_A | PSTATE_F | PSTATE_I;
-        s->cpu->env.cp15.c1_sys = 0;
+        s->cpu->env.cp15.sctlr_ns = 0;
         s->cpu->env.cp15.c1_coproc = 0;
         s->cpu->env.cp15.ttbr0_el1 = 0;
         s->cpu->env.cp15.c3 = 0;
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 8ab6d95..ee69489 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -103,7 +103,7 @@ static void arm_cpu_reset(CPUState *s)
 #if defined(CONFIG_USER_ONLY)
         env->pstate = PSTATE_MODE_EL0t;
         /* Userspace expects access to CTL_EL0 and the cache ops */
-        env->cp15.c1_sys |= SCTLR_UCT | SCTLR_UCI;
+        env->cp15.sctlr_el1 |= SCTLR_UCT | SCTLR_UCI;
         /* and to the FP/Neon instructions */
         env->cp15.c1_coproc = deposit64(env->cp15.c1_coproc, 20, 2, 3);
 #else
@@ -161,7 +161,8 @@ static void arm_cpu_reset(CPUState *s)
         env->thumb = initial_pc & 1;
     }
 
-    if (env->cp15.c1_sys & SCTLR_V) {
+    if (!arm_feature(env, ARM_FEATURE_V8)
+            && (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V)) {
         env->regs[15] = 0xFFFF0000;
     }
 
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 1b6ce8a..44d7098 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -178,7 +178,18 @@ typedef struct CPUARMState {
     struct {
         uint32_t c0_cpuid;
         uint64_t c0_cssel; /* Cache size selection.  */
-        uint64_t c1_sys; /* System control register.  */
+        union { /* System control register. */
+            struct {
+                uint64_t sctlr_ns;
+                uint64_t hsctlr;
+                uint64_t sctlr_s;
+            };
+            struct {
+                uint64_t sctlr_el1;
+                uint64_t sctlr_el2;
+                uint64_t sctlr_el3;
+            };
+        };
         uint64_t c1_coproc; /* Coprocessor access register.  */
         uint32_t c1_xscaleauxcr; /* XScale auxiliary control register.  */
         uint32_t c1_sder; /* Secure debug enable register. */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 4ad55d5..7d26acc 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1921,7 +1921,7 @@ static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 
 static CPAccessResult aa64_daif_access(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
+    if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el1 & SCTLR_UMA)) {
         return CP_ACCESS_TRAP;
     }
     return CP_ACCESS_OK;
@@ -1939,7 +1939,7 @@ static CPAccessResult aa64_cacheop_access(CPUARMState *env,
     /* Cache invalidate/clean: NOP, but EL0 must UNDEF unless
      * SCTLR_EL1.UCI is set.
      */
-    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCI)) {
+    if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el1 & SCTLR_UCI)) {
         return CP_ACCESS_TRAP;
     }
     return CP_ACCESS_OK;
@@ -2016,7 +2016,7 @@ static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri)
     /* We don't implement EL2, so the only control on DC ZVA is the
      * bit in the SCTLR which can prohibit access for EL0.
      */
-    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_DZE)) {
+    if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el1 & SCTLR_DZE)) {
         return CP_ACCESS_TRAP;
     }
     return CP_ACCESS_OK;
@@ -2055,6 +2055,24 @@ static void spsel_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
     update_spsel(env, val);
 }
 
+static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                        uint64_t value)
+{
+    ARMCPU *cpu = arm_env_get_cpu(env);
+
+    if (raw_read(env, ri) == value) {
+        /* Skip the TLB flush if nothing actually changed; Linux likes
+         * to do a lot of pointless SCTLR writes.
+         */
+        return;
+    }
+
+    raw_write(env, ri, value);
+    /* ??? Lots of these bits are not implemented.  */
+    /* This may enable/disable the MMU, so do a TLB flush.  */
+    tlb_flush(CPU(cpu), 1);
+}
+
 static const ARMCPRegInfo v8_cp_reginfo[] = {
     /* Minimal set of EL0-visible registers. This will need to be expanded
      * significantly for system emulation of AArch64 CPUs.
@@ -2373,6 +2391,10 @@ static uint64_t nsacr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 }
 
 static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
+    { .name = "SCTLR_EL3", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
+      .access = PL3_RW, .raw_writefn = raw_write, .writefn = sctlr_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el3) },
     { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_MIGRATE,
       .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1,
@@ -2422,30 +2444,12 @@ static const ARMCPRegInfo v7_el3_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
-static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                        uint64_t value)
-{
-    ARMCPU *cpu = arm_env_get_cpu(env);
-
-    if (raw_read(env, ri) == value) {
-        /* Skip the TLB flush if nothing actually changed; Linux likes
-         * to do a lot of pointless SCTLR writes.
-         */
-        return;
-    }
-
-    raw_write(env, ri, value);
-    /* ??? Lots of these bits are not implemented.  */
-    /* This may enable/disable the MMU, so do a TLB flush.  */
-    tlb_flush(CPU(cpu), 1);
-}
-
 static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     /* Only accessible in EL0 if SCTLR.UCT is set (and only in AArch64,
      * but the AArch32 CTR has its own reginfo struct)
      */
-    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCT)) {
+    if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el1 & SCTLR_UCT)) {
         return CP_ACCESS_TRAP;
     }
     return CP_ACCESS_OK;
@@ -3242,10 +3246,21 @@ void register_cp_regs_for_features(ARMCPU *cpu)
 
     /* Generic registers whose values depend on the implementation */
     {
-        ARMCPRegInfo sctlr = {
-            .name = "SCTLR", .state = ARM_CP_STATE_BOTH,
+        ARMCPRegInfo sctlr_el1 = {
+            .name = "SCTLR_EL1", .state = ARM_CP_STATE_AA64,
             .opc0 = 3, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
-            .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_sys),
+            .access = PL1_RW,
+            .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el1),
+            .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
+            .raw_writefn = raw_write,
+        };
+
+        ARMCPRegInfo sctlr = {
+            .name = "SCTLR",
+            .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
+            .access = PL1_RW,
+            .bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s),
+                                   offsetof(CPUARMState, cp15.sctlr_el1) },
             .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
             .raw_writefn = raw_write,
         };
@@ -3254,9 +3269,11 @@ void register_cp_regs_for_features(ARMCPU *cpu)
              * arch/arm/mach-pxa/sleep.S expects two instructions following
              * an MMU enable to execute from cache.  Imitate this behaviour.
              */
+            sctlr_el1.type |= ARM_CP_SUPPRESS_TB_END;
             sctlr.type |= ARM_CP_SUPPRESS_TB_END;
         }
         define_one_arm_cp_reg(cpu, &sctlr);
+        define_one_arm_cp_reg(cpu, &sctlr_el1);
     }
 }
 
@@ -4371,7 +4388,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
 
     if (new_mode == ARM_CPU_MODE_MON) {
         addr += env->cp15.mvbar;
-    } else if (env->cp15.c1_sys & SCTLR_V) {
+    } else if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) {
         /* High vectors. When enabled, base address cannot be remapped. */
         addr += 0xffff0000;
     } else {
@@ -4401,7 +4418,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
     /* this is a lie, as the was no c1_sys on V4T/V5, but who cares
      * and we should just guard the thumb mode on V4 */
     if (arm_feature(env, ARM_FEATURE_V4T)) {
-        env->thumb = (env->cp15.c1_sys & SCTLR_TE) != 0;
+        env->thumb = (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_TE) != 0;
     }
     env->regs[14] = env->regs[15] + offset;
     env->regs[15] = addr;
@@ -4432,7 +4449,7 @@ static inline int check_ap(CPUARMState *env, int ap, int domain_prot,
       }
       if (access_type == 1)
           return 0;
-      switch (env->cp15.c1_sys & (SCTLR_S | SCTLR_R)) {
+      switch (A32_BANKED_CURRENT_REG_GET(env, sctlr) & (SCTLR_S | SCTLR_R)) {
       case SCTLR_S:
           return is_user ? 0 : PAGE_READ;
       case SCTLR_R:
@@ -4681,7 +4698,8 @@ static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type,
             goto do_fault;
 
         /* The simplified model uses AP[0] as an access control bit.  */
-        if ((env->cp15.c1_sys & SCTLR_AFE) && (ap & 1) == 0) {
+        if ((A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_AFE)
+                && (ap & 1) == 0) {
             /* Access flag fault.  */
             code = (code == 15) ? 6 : 3;
             goto do_fault;
@@ -5012,11 +5030,16 @@ static inline int get_phys_addr(CPUARMState *env, target_ulong address,
                                 hwaddr *phys_ptr, int *prot,
                                 target_ulong *page_size)
 {
+    /* This is not entirely correct as get_phys_addr() can also be called
+     * from ats_write() for an address translation of a specific regime.
+     */
+    uint32_t sctlr = A32_BANKED_CURRENT_REG_GET(env, sctlr);
+
     /* Fast Context Switch Extension.  */
     if (address < 0x02000000)
         address += env->cp15.c13_fcse;
 
-    if ((env->cp15.c1_sys & SCTLR_M) == 0) {
+    if ((sctlr & SCTLR_M) == 0) {
         /* MMU/MPU disabled.  */
         *phys_ptr = address;
         *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
@@ -5029,7 +5052,7 @@ static inline int get_phys_addr(CPUARMState *env, target_ulong address,
     } else if (extended_addresses_enabled(env)) {
         return get_phys_addr_lpae(env, address, access_type, is_user, phys_ptr,
                                   prot, page_size);
-    } else if (env->cp15.c1_sys & SCTLR_XP) {
+    } else if (sctlr & SCTLR_XP) {
         return get_phys_addr_v6(env, address, access_type, is_user, phys_ptr,
                                 prot, page_size);
     } else {
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 8ed8ee9..fe93526 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -361,7 +361,7 @@ void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
      * Note that SPSel is never OK from EL0; we rely on handle_msr_i()
      * to catch that case at translate time.
      */
-    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
+    if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el1 & SCTLR_UMA)) {
         raise_exception(env, EXCP_UDEF);
     }
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 20/33] target-arm: make CSSELR banked
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (18 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 19/33] target-arm: add SCTLR_EL3 and make SCTLR banked Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 21/33] target-arm: add TTBR0_EL3 and make TTBR0/1 banked Greg Bellows
                   ` (13 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

Rename CSSELR (cache size selection register) and add secure
instance (Aarch32).

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

----------
v4 -> v5
- Changed to use the CCSIDR cpreg bank flag to select the csselr bank instead
  of the  A32_BANKED macro.  This more accurately uses the secure state bank
  matching the CCSIDR.
---
 target-arm/cpu.h    | 10 +++++++++-
 target-arm/helper.c | 22 +++++++++++++++++-----
 2 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 44d7098..332a2cb 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -177,7 +177,15 @@ typedef struct CPUARMState {
     /* System control coprocessor (cp15) */
     struct {
         uint32_t c0_cpuid;
-        uint64_t c0_cssel; /* Cache size selection.  */
+        union { /* Cache size selection */
+            struct {
+                uint64_t csselr_ns;
+                uint64_t csselr_s;
+            };
+            struct {
+                uint64_t csselr_el1;
+            };
+        };
         union { /* System control register. */
             struct {
                 uint64_t sctlr_ns;
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 7d26acc..90f5352 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -789,7 +789,14 @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
 static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     ARMCPU *cpu = arm_env_get_cpu(env);
-    return cpu->ccsidr[env->cp15.c0_cssel];
+
+    /* Acquire the CSSELR index from the bank corresponding to the CCSIDR
+     * bank
+     */
+    uint32_t index = A32_BANKED_REG_GET(env, csselr,
+                                 (ri->type & ARM_CP_BANK_S) == ARM_CP_BANK_S);
+
+    return cpu->ccsidr[index];
 }
 
 static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -914,10 +921,11 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
     { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
       .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_MIGRATE },
-    { .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c0_cssel),
-      .writefn = csselr_write, .resetvalue = 0 },
+    { .name = "CSSELR", 
+      .cp = 15, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
+      .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
+                             offsetof(CPUARMState, cp15.csselr_el1) } },
     /* Auxiliary ID register: this actually has an IMPDEF value but for now
      * just RAZ for all cores:
      */
@@ -2270,6 +2278,10 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
       .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 0,
       .type = ARM_CP_NO_MIGRATE,
       .access = PL1_RW, .readfn = spsel_read, .writefn = spsel_write },
+    { .name = "CSSELR_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
+      .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.csselr_el1) },
     REGINFO_SENTINEL
 };
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 21/33] target-arm: add TTBR0_EL3 and make TTBR0/1 banked
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (19 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 20/33] target-arm: make CSSELR banked Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 22/33] target-arm: add TCR_EL3 and make TTBCR banked Greg Bellows
                   ` (12 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

Add TTBR0 and maps secure/non-secure instance of ttbr0 and ttbr1
accordingly (translation table base register).

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
---
 target-arm/cpu.h    | 21 +++++++++++++++++--
 target-arm/helper.c | 58 +++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 64 insertions(+), 15 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 332a2cb..c99158e 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -202,8 +202,25 @@ typedef struct CPUARMState {
         uint32_t c1_xscaleauxcr; /* XScale auxiliary control register.  */
         uint32_t c1_sder; /* Secure debug enable register. */
         uint32_t c1_nsacr; /* Non-secure access control register. */
-        uint64_t ttbr0_el1; /* MMU translation table base 0. */
-        uint64_t ttbr1_el1; /* MMU translation table base 1. */
+        union { /* MMU translation table base 0. */
+            struct {
+                uint64_t ttbr0_ns;
+                uint64_t ttbr0_s;
+            };
+            struct {
+                uint64_t ttbr0_el1;
+                uint64_t ttbr0_el3;
+            };
+        };
+        union { /* MMU translation table base 1. */
+            struct {
+                uint64_t ttbr1_ns;
+                uint64_t ttbr1_s;
+            };
+            struct {
+                uint64_t ttbr1_el1;
+            };
+        };
         uint64_t c2_control; /* MMU translation table base control.  */
         uint32_t c2_mask; /* MMU translation table base selection mask.  */
         uint32_t c2_base_mask; /* MMU translation table base 0 mask. */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 90f5352..2a6a129 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -921,7 +921,7 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
     { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
       .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_MIGRATE },
-    { .name = "CSSELR", 
+    { .name = "CSSELR",
       .cp = 15, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
       .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0,
       .bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
@@ -1658,14 +1658,22 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
       .opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue = 0, },
-    { .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
+    { .name = "TTBR0", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
+      .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
+                             offsetof(CPUARMState, cp15.ttbr0_ns) } },
+    { .name = "TTBR0_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el1),
-      .writefn = vmsa_ttbr_write, .resetvalue = 0 },
-    { .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
+      .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el1) },
+    { .name = "TTBR1", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1,
+      .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
+                             offsetof(CPUARMState, cp15.ttbr1_el1) } },
+    { .name = "TTBR1_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el1),
-      .writefn = vmsa_ttbr_write, .resetvalue = 0 },
+      .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el1) },
     { .name = "TCR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
       .access = PL1_RW, .writefn = vmsa_tcr_el1_write,
@@ -1896,11 +1904,13 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
       .fieldoffset = offsetof(CPUARMState, cp15.par_el1), .resetvalue = 0 },
     { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0,
       .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE,
-      .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el1),
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
+                             offsetof(CPUARMState, cp15.ttbr0_ns) },
       .writefn = vmsa_ttbr_write, .resetfn = arm_cp_reset_ignore },
     { .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1,
       .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE,
-      .fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el1),
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
+                             offsetof(CPUARMState, cp15.ttbr1_ns) },
       .writefn = vmsa_ttbr_write, .resetfn = arm_cp_reset_ignore },
     REGINFO_SENTINEL
 };
@@ -2407,6 +2417,10 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
       .opc0 = 3, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
       .access = PL3_RW, .raw_writefn = raw_write, .writefn = sctlr_write,
       .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el3) },
+    { .name = "TTBR0_EL3", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 6, .opc2 = 0,
+      .access = PL3_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el3) },
     { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_MIGRATE,
       .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1,
@@ -4496,18 +4510,23 @@ static inline int check_ap(CPUARMState *env, int ap, int domain_prot,
 static bool get_level1_table_address(CPUARMState *env, uint32_t *table,
                                          uint32_t address)
 {
+    /* We only get here if EL1 is running in Aarch32. If EL3 is running in
+     * Aarch32 there is a secure and non-secure instance of the translation
+     * table registers.
+     */
     if (address & env->cp15.c2_mask) {
         if ((env->cp15.c2_control & TTBCR_PD1)) {
             /* Translation table walk disabled for TTBR1 */
             return false;
         }
-        *table = env->cp15.ttbr1_el1 & 0xffffc000;
+        *table = A32_BANKED_CURRENT_REG_GET(env, ttbr1) & 0xffffc000;
     } else {
         if ((env->cp15.c2_control & TTBCR_PD0)) {
             /* Translation table walk disabled for TTBR0 */
             return false;
         }
-        *table = env->cp15.ttbr0_el1 & env->cp15.c2_base_mask;
+        *table = A32_BANKED_CURRENT_REG_GET(env, ttbr0) &
+                 env->cp15.c2_base_mask;
     }
     *table |= (address >> 18) & 0x3ffc;
     return true;
@@ -4761,6 +4780,7 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
     int32_t granule_sz = 9;
     int32_t va_size = 32;
     int32_t tbi = 0;
+    uint32_t cur_el = arm_current_el(env);
 
     if (arm_el_is_aa64(env, 1)) {
         va_size = 64;
@@ -4812,7 +4832,19 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
      * we will always flush the TLB any time the ASID is changed).
      */
     if (ttbr_select == 0) {
-        ttbr = env->cp15.ttbr0_el1;
+        if (arm_el_is_aa64(env, 3)) {
+            switch (cur_el) {
+            case 3:
+                ttbr = env->cp15.ttbr0_el3;
+                break;
+            case 1:
+            case 0:
+            default:
+                ttbr = env->cp15.ttbr0_el1;
+            }
+        } else {
+            ttbr = A32_BANKED_CURRENT_REG_GET(env, ttbr0);
+        }
         epd = extract32(env->cp15.c2_control, 7, 1);
         tsz = t0sz;
 
@@ -4824,7 +4856,7 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
             granule_sz = 11;
         }
     } else {
-        ttbr = env->cp15.ttbr1_el1;
+        ttbr = A32_BANKED_CURRENT_REG_GET(env, ttbr1);
         epd = extract32(env->cp15.c2_control, 23, 1);
         tsz = t1sz;
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 22/33] target-arm: add TCR_EL3 and make TTBCR banked
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (20 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 21/33] target-arm: add TTBR0_EL3 and make TTBR0/1 banked Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 23:18   ` Edgar E. Iglesias
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 23/33] target-arm: make c2_mask and c2_base_mask banked Greg Bellows
                   ` (11 subsequent siblings)
  33 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

Adds TCR_EL3 system register and makes existing TTBCR banked. Adjust
translation functions to use TCR/TTBCR instance depending on CPU state.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

----------
v4 -> v5
- Changed c2_mask updates to use the TTBCR cpreg bank flag for selcting the
  secure bank instead of the A32_BANKED_CURRENT macro.  This more accurately
  chooses the correct bank matching that of the TTBCR being accessed.
---
 target-arm/cpu.h       | 11 ++++++++++-
 target-arm/helper.c    | 48 +++++++++++++++++++++++++++++++++++-------------
 target-arm/internals.h |  2 +-
 3 files changed, 46 insertions(+), 15 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c99158e..477c219 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -221,7 +221,16 @@ typedef struct CPUARMState {
                 uint64_t ttbr1_el1;
             };
         };
-        uint64_t c2_control; /* MMU translation table base control.  */
+        union { /* MMU translation table base control. */
+            struct {
+                uint64_t ttbcr_ns;
+                uint64_t ttbcr_s;
+            };
+            struct {
+                uint64_t tcr_el1;
+                uint64_t tcr_el3;
+            };
+        };
         uint32_t c2_mask; /* MMU translation table base selection mask.  */
         uint32_t c2_base_mask; /* MMU translation table base 0 mask. */
         uint32_t c2_data; /* MPU data cachable bits.  */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 2a6a129..bdb76e0 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1678,11 +1678,12 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
       .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
       .access = PL1_RW, .writefn = vmsa_tcr_el1_write,
       .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
-      .fieldoffset = offsetof(CPUARMState, cp15.c2_control) },
+      .fieldoffset = offsetof(CPUARMState, cp15.tcr_el1) },
     { .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
       .access = PL1_RW, .type = ARM_CP_NO_MIGRATE, .writefn = vmsa_ttbcr_write,
       .resetfn = arm_cp_reset_ignore, .raw_writefn = vmsa_ttbcr_raw_write,
-      .fieldoffset = offsetoflow32(CPUARMState, cp15.c2_control) },
+      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.ttbcr_s),
+                             offsetoflow32(CPUARMState, cp15.ttbcr_ns) } },
     /* 64-bit FAR; this entry also gives us the AArch32 DFAR */
     { .name = "FAR_EL1", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
@@ -2421,6 +2422,11 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
       .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 6, .opc2 = 0,
       .access = PL3_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
       .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el3) },
+    { .name = "TCR_EL3", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 6, .opc2 = 2,
+      .access = PL3_RW, .writefn = vmsa_tcr_el1_write,
+      .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.tcr_el3) },
     { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_MIGRATE,
       .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1,
@@ -4515,13 +4521,13 @@ static bool get_level1_table_address(CPUARMState *env, uint32_t *table,
      * table registers.
      */
     if (address & env->cp15.c2_mask) {
-        if ((env->cp15.c2_control & TTBCR_PD1)) {
+        if (A32_BANKED_CURRENT_REG_GET(env, ttbcr) & TTBCR_PD1) {
             /* Translation table walk disabled for TTBR1 */
             return false;
         }
         *table = A32_BANKED_CURRENT_REG_GET(env, ttbr1) & 0xffffc000;
     } else {
-        if ((env->cp15.c2_control & TTBCR_PD0)) {
+        if (A32_BANKED_CURRENT_REG_GET(env, ttbcr) & TTBCR_PD0) {
             /* Translation table walk disabled for TTBR0 */
             return false;
         }
@@ -4781,13 +4787,29 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
     int32_t va_size = 32;
     int32_t tbi = 0;
     uint32_t cur_el = arm_current_el(env);
+    uint64_t tcr;
 
-    if (arm_el_is_aa64(env, 1)) {
+    if (arm_el_is_aa64(env, 3)) {
+        switch (cur_el) {
+        case 3:
+            tcr = env->cp15.tcr_el3;
+            break;
+        case 1:
+        case 0:
+        default:
+            tcr = env->cp15.tcr_el1;
+        }
+
+    } else {
+        tcr = A32_BANKED_CURRENT_REG_GET(env, ttbcr);
+    }
+
+    if (arm_el_is_aa64(env, 1) && (cur_el == 0 || cur_el == 1)) {
         va_size = 64;
         if (extract64(address, 55, 1))
-            tbi = extract64(env->cp15.c2_control, 38, 1);
+            tbi = extract64(tcr, 38, 1);
         else
-            tbi = extract64(env->cp15.c2_control, 37, 1);
+            tbi = extract64(tcr, 37, 1);
         tbi *= 8;
     }
 
@@ -4796,12 +4818,12 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
      * This is a Non-secure PL0/1 stage 1 translation, so controlled by
      * TTBCR/TTBR0/TTBR1 in accordance with ARM ARM DDI0406C table B-32:
      */
-    uint32_t t0sz = extract32(env->cp15.c2_control, 0, 6);
+    uint32_t t0sz = extract32(tcr, 0, 6);
     if (arm_el_is_aa64(env, 1)) {
         t0sz = MIN(t0sz, 39);
         t0sz = MAX(t0sz, 16);
     }
-    uint32_t t1sz = extract32(env->cp15.c2_control, 16, 6);
+    uint32_t t1sz = extract32(tcr, 16, 6);
     if (arm_el_is_aa64(env, 1)) {
         t1sz = MIN(t1sz, 39);
         t1sz = MAX(t1sz, 16);
@@ -4845,10 +4867,10 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
         } else {
             ttbr = A32_BANKED_CURRENT_REG_GET(env, ttbr0);
         }
-        epd = extract32(env->cp15.c2_control, 7, 1);
+        epd = extract32(tcr, 7, 1);
         tsz = t0sz;
 
-        tg = extract32(env->cp15.c2_control, 14, 2);
+        tg = extract32(tcr, 14, 2);
         if (tg == 1) { /* 64KB pages */
             granule_sz = 13;
         }
@@ -4857,10 +4879,10 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
         }
     } else {
         ttbr = A32_BANKED_CURRENT_REG_GET(env, ttbr1);
-        epd = extract32(env->cp15.c2_control, 23, 1);
+        epd = extract32(tcr, 23, 1);
         tsz = t1sz;
 
-        tg = extract32(env->cp15.c2_control, 30, 2);
+        tg = extract32(tcr, 30, 2);
         if (tg == 3)  { /* 64KB pages */
             granule_sz = 13;
         }
diff --git a/target-arm/internals.h b/target-arm/internals.h
index 43a2e7d..dba7766 100644
--- a/target-arm/internals.h
+++ b/target-arm/internals.h
@@ -155,7 +155,7 @@ static inline bool extended_addresses_enabled(CPUARMState *env)
 {
     return arm_el_is_aa64(env, 1)
         || ((arm_feature(env, ARM_FEATURE_LPAE)
-             && (env->cp15.c2_control & TTBCR_EAE)));
+             && (A32_BANKED_CURRENT_REG_GET(env, ttbcr) & TTBCR_EAE)));
 }
 
 /* Valid Syndrome Register EC field values */
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 23/33] target-arm: make c2_mask and c2_base_mask banked
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (21 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 22/33] target-arm: add TCR_EL3 and make TTBCR banked Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 24/33] target-arm: make DACR banked Greg Bellows
                   ` (10 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

Since TTBCR is banked we will bank c2_mask and c2_base_mask too. This
avoids recalculating them on switches from secure to non-secure world.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

----------
v4 -> v5
- Changed c2_mask updates to use the TTBCR cpreg bank flag for selcting the
  secure bank instead of the A32_BANKED_CURRENT macro.  This more accurately
  chooses the correct bank matching that of the TTBCR being accessed.
---
 target-arm/cpu.h    | 10 ++++++++--
 target-arm/helper.c | 24 ++++++++++++++++++------
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 477c219..54bce55 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -231,8 +231,14 @@ typedef struct CPUARMState {
                 uint64_t tcr_el3;
             };
         };
-        uint32_t c2_mask; /* MMU translation table base selection mask.  */
-        uint32_t c2_base_mask; /* MMU translation table base 0 mask. */
+        struct { /* MMU translation table base selection mask. */
+            uint32_t c2_mask_ns;
+            uint32_t c2_mask_s;
+        };
+        struct { /* MMU translation table base 0 mask. */
+            uint32_t c2_base_mask_ns;
+            uint32_t c2_base_mask_s;
+        };
         uint32_t c2_data; /* MPU data cachable bits.  */
         uint32_t c2_insn; /* MPU instruction cachable bits.  */
         uint32_t c3; /* MMU domain access control register
diff --git a/target-arm/helper.c b/target-arm/helper.c
index bdb76e0..a77ab95 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1597,8 +1597,14 @@ static void vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
      * and the c2_mask and c2_base_mask values are meaningless.
      */
     raw_write(env, ri, value);
-    env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> maskshift);
-    env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> maskshift);
+
+    /* Update the masks corresponding to the the TTBCR bank being written */
+    A32_BANKED_REG_SET(env, c2_mask,
+                       ((ri->type & ARM_CP_BANK_S) == ARM_CP_BANK_S),
+                       ~(((uint32_t)0xffffffffu) >> maskshift));
+    A32_BANKED_REG_SET(env, c2_base_mask,
+                       ((ri->type & ARM_CP_BANK_S) == ARM_CP_BANK_S),
+                       ~((uint32_t)0x3fffu >> maskshift));
 }
 
 static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -1617,9 +1623,15 @@ static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 
 static void vmsa_ttbcr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    env->cp15.c2_base_mask = 0xffffc000u;
+    /* Rest both the TTBCR as well as the masks corresponding to the bank of
+     * the TTBCR being reset.
+     */
+    A32_BANKED_REG_SET(env, c2_base_mask,
+                       ((ri->type & ARM_CP_BANK_S) == ARM_CP_BANK_S),
+                       0xffffc000u);
+    A32_BANKED_REG_SET(env, c2_mask,
+                       ((ri->type & ARM_CP_BANK_S) == ARM_CP_BANK_S), 0);
     raw_write(env, ri, 0);
-    env->cp15.c2_mask = 0;
 }
 
 static void vmsa_tcr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -4520,7 +4532,7 @@ static bool get_level1_table_address(CPUARMState *env, uint32_t *table,
      * Aarch32 there is a secure and non-secure instance of the translation
      * table registers.
      */
-    if (address & env->cp15.c2_mask) {
+    if (address & A32_BANKED_CURRENT_REG_GET(env, c2_mask)) {
         if (A32_BANKED_CURRENT_REG_GET(env, ttbcr) & TTBCR_PD1) {
             /* Translation table walk disabled for TTBR1 */
             return false;
@@ -4532,7 +4544,7 @@ static bool get_level1_table_address(CPUARMState *env, uint32_t *table,
             return false;
         }
         *table = A32_BANKED_CURRENT_REG_GET(env, ttbr0) &
-                 env->cp15.c2_base_mask;
+                 A32_BANKED_CURRENT_REG_GET(env, c2_base_mask);
     }
     *table |= (address >> 18) & 0x3ffc;
     return true;
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 24/33] target-arm: make DACR banked
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (22 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 23/33] target-arm: make c2_mask and c2_base_mask banked Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 25/33] target-arm: make IFSR banked Greg Bellows
                   ` (9 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

When EL3 is running in Aarch32 (or ARMv7 with Security Extensions)
DACR has a secure and a non-secure instance.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
---
 hw/arm/pxa2xx.c     |  2 +-
 target-arm/cpu.h    | 13 +++++++++++--
 target-arm/helper.c | 19 +++++++++++--------
 3 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 0114597..fe8aa44 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -275,7 +275,7 @@ static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
         s->cpu->env.cp15.sctlr_ns = 0;
         s->cpu->env.cp15.c1_coproc = 0;
         s->cpu->env.cp15.ttbr0_el1 = 0;
-        s->cpu->env.cp15.c3 = 0;
+        s->cpu->env.cp15.dacr_ns = 0;
         s->pm_regs[PSSR >> 2] |= 0x8; /* Set STS */
         s->pm_regs[RCSR >> 2] |= 0x8; /* Set GPR */
 
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 54bce55..3661e85 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -241,8 +241,17 @@ typedef struct CPUARMState {
         };
         uint32_t c2_data; /* MPU data cachable bits.  */
         uint32_t c2_insn; /* MPU instruction cachable bits.  */
-        uint32_t c3; /* MMU domain access control register
-                        MPU write buffer control.  */
+        union { /* MMU domain access control register
+                 * MPU write buffer control.
+                 */
+            struct {
+                uint32_t dacr_ns;
+                uint32_t dacr_s;
+            };
+            struct {
+                uint32_t dacr32_el2;
+            };
+        };
         uint32_t pmsav5_data_ap; /* PMSAv5 MPU data access permissions */
         uint32_t pmsav5_insn_ap; /* PMSAv5 MPU insn access permissions */
         uint64_t hcr_el2; /* Hypervisor configuration register */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index a77ab95..c2d44d2 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -437,8 +437,10 @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
     /* MMU Domain access control / MPU write buffer control */
     { .name = "DACR", .cp = 15,
       .crn = 3, .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c3),
-      .resetvalue = 0, .writefn = dacr_write, .raw_writefn = raw_write, },
+      .access = PL1_RW, .resetvalue = 0,
+      .writefn = dacr_write, .raw_writefn = raw_write,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.dacr_s),
+                             offsetof(CPUARMState, cp15.dacr_ns) } },
     /* ??? This covers not just the impdef TLB lockdown registers but also
      * some v7VMSA registers relating to TEX remap, so it is overly broad.
      */
@@ -2275,10 +2277,11 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
     { .name = "DCCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
       .type = ARM_CP_NOP, .access = PL1_W },
     /* MMU Domain access control / MPU write buffer control */
-    { .name = "DACR", .cp = 15,
-      .opc1 = 0, .crn = 3, .crm = 0, .opc2 = 0,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c3),
-      .resetvalue = 0, .writefn = dacr_write, .raw_writefn = raw_write, },
+    { .name = "DACR", .cp = 15, .opc1 = 0, .crn = 3, .crm = 0, .opc2 = 0,
+      .access = PL1_RW, .resetvalue = 0,
+      .writefn = dacr_write, .raw_writefn = raw_write,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.dacr_s),
+                             offsetof(CPUARMState, cp15.dacr_ns) } },
     { .name = "ELR_EL1", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_MIGRATE,
       .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 1,
@@ -4574,7 +4577,7 @@ static int get_phys_addr_v5(CPUARMState *env, uint32_t address, int access_type,
     desc = ldl_phys(cs->as, table);
     type = (desc & 3);
     domain = (desc >> 5) & 0x0f;
-    domain_prot = (env->cp15.c3 >> (domain * 2)) & 3;
+    domain_prot = (A32_BANKED_CURRENT_REG_GET(env, dacr) >> (domain * 2)) & 3;
     if (type == 0) {
         /* Section translation fault.  */
         code = 5;
@@ -4686,7 +4689,7 @@ static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type,
         /* Page or Section.  */
         domain = (desc >> 5) & 0x0f;
     }
-    domain_prot = (env->cp15.c3 >> (domain * 2)) & 3;
+    domain_prot = (A32_BANKED_CURRENT_REG_GET(env, dacr) >> (domain * 2)) & 3;
     if (domain_prot == 0 || domain_prot == 2) {
         if (type != 1) {
             code = 9; /* Section domain fault.  */
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 25/33] target-arm: make IFSR banked
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (23 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 24/33] target-arm: make DACR banked Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 26/33] target-arm: make DFSR banked Greg Bellows
                   ` (8 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

When EL3 is running in Aarch32 (or ARMv7 with Security Extensions)
IFSR has a secure and a non-secure instance.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
---
 target-arm/cpu.h    | 10 +++++++++-
 target-arm/helper.c |  9 +++++----
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 3661e85..5f9edc5 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -256,7 +256,15 @@ typedef struct CPUARMState {
         uint32_t pmsav5_insn_ap; /* PMSAv5 MPU insn access permissions */
         uint64_t hcr_el2; /* Hypervisor configuration register */
         uint64_t scr_el3; /* Secure configuration register.  */
-        uint32_t ifsr_el2; /* Fault status registers.  */
+        union { /* Fault status registers.  */
+            struct {
+                uint32_t ifsr_ns;
+                uint32_t ifsr_s;
+            };
+            struct {
+                uint32_t ifsr32_el2;
+            };
+        };
         uint64_t esr_el[4];
         uint32_t c6_region[8]; /* MPU base/size registers.  */
         uint64_t far_el[4]; /* Fault address registers.  */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index c2d44d2..a083566 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1666,8 +1666,9 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
       .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]),
       .resetfn = arm_cp_reset_ignore, },
     { .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
-      .access = PL1_RW,
-      .fieldoffset = offsetof(CPUARMState, cp15.ifsr_el2), .resetvalue = 0, },
+      .access = PL1_RW, .resetvalue = 0,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ifsr_s),
+                             offsetof(CPUARMState, cp15.ifsr_ns) } },
     { .name = "ESR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW,
@@ -4377,11 +4378,11 @@ void arm_cpu_do_interrupt(CPUState *cs)
         env->exception.fsr = 2;
         /* Fall through to prefetch abort.  */
     case EXCP_PREFETCH_ABORT:
-        env->cp15.ifsr_el2 = env->exception.fsr;
+        A32_BANKED_CURRENT_REG_SET(env, ifsr, env->exception.fsr);
         env->cp15.far_el[1] = deposit64(env->cp15.far_el[1], 32, 32,
                                         env->exception.vaddress);
         qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n",
-                      env->cp15.ifsr_el2, (uint32_t)env->exception.vaddress);
+                      env->exception.fsr, (uint32_t)env->exception.vaddress);
         new_mode = ARM_CPU_MODE_ABT;
         addr = 0x0c;
         mask = CPSR_A | CPSR_I;
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 26/33] target-arm: make DFSR banked
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (24 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 25/33] target-arm: make IFSR banked Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 27/33] target-arm: make IFAR/DFAR banked Greg Bellows
                   ` (7 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

When EL3 is running in Aarch32 (or ARMv7 with Security Extensions)
DFSR has a secure and a non-secure instance.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

---------------
v3 -> v4
- Reverted esr/dfsr back to array-based notation as a union with v7 naming.
---
 target-arm/cpu.h    | 10 +++++++++-
 target-arm/helper.c |  7 ++++---
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 5f9edc5..8e10e18 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -265,7 +265,15 @@ typedef struct CPUARMState {
                 uint32_t ifsr32_el2;
             };
         };
-        uint64_t esr_el[4];
+        union {
+            struct {
+                uint64_t _unused_dfsr;
+                uint64_t dfsr_ns;
+                uint64_t hsr;
+                uint64_t dfsr_s;
+            };
+            uint64_t esr_el[4];
+        };
         uint32_t c6_region[8]; /* MPU base/size registers.  */
         uint64_t far_el[4]; /* Fault address registers.  */
         uint64_t par_el1;  /* Translation result. */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index a083566..85c7cc8 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1663,7 +1663,8 @@ static void vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 static const ARMCPRegInfo vmsa_cp_reginfo[] = {
     { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW, .type = ARM_CP_NO_MIGRATE,
-      .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]),
+      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dfsr_s),
+                             offsetoflow32(CPUARMState, cp15.dfsr_ns) },
       .resetfn = arm_cp_reset_ignore, },
     { .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
       .access = PL1_RW, .resetvalue = 0,
@@ -4389,11 +4390,11 @@ void arm_cpu_do_interrupt(CPUState *cs)
         offset = 4;
         break;
     case EXCP_DATA_ABORT:
-        env->cp15.esr_el[1] = env->exception.fsr;
+        A32_BANKED_CURRENT_REG_SET(env, dfsr, env->exception.fsr);
         env->cp15.far_el[1] = deposit64(env->cp15.far_el[1], 0, 32,
                                         env->exception.vaddress);
         qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n",
-                      (uint32_t)env->cp15.esr_el[1],
+                      env->exception.fsr,
                       (uint32_t)env->exception.vaddress);
         new_mode = ARM_CPU_MODE_ABT;
         addr = 0x10;
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 27/33] target-arm: make IFAR/DFAR banked
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (25 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 26/33] target-arm: make DFSR banked Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 28/33] target-arm: make PAR banked Greg Bellows
                   ` (6 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

When EL3 is running in Aarch32 (or ARMv7 with Security Extensions)
IFAR and DFAR have a secure and a non-secure instance.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

-----------------
v3 -> v4
- Revert to array-based notation of far_el in combination with v7 naming
---
 target-arm/cpu.c    |  2 +-
 target-arm/cpu.h    | 19 ++++++++++++++++++-
 target-arm/helper.c | 20 +++++++++++---------
 3 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index ee69489..2a5c333 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -513,7 +513,7 @@ static void arm1026_initfn(Object *obj)
         ARMCPRegInfo ifar = {
             .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
             .access = PL1_RW,
-            .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el[1]),
+            .fieldoffset = offsetof(CPUARMState, cp15.ifar_ns),
             .resetvalue = 0
         };
         define_one_arm_cp_reg(cpu, &ifar);
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 8e10e18..0f70245 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -275,7 +275,24 @@ typedef struct CPUARMState {
             uint64_t esr_el[4];
         };
         uint32_t c6_region[8]; /* MPU base/size registers.  */
-        uint64_t far_el[4]; /* Fault address registers.  */
+        union { /* Fault address registers. */
+            struct {
+                uint64_t _unused_far0;
+#ifdef HOST_WORDS_BIGENDIAN
+                uint32_t ifar_ns;
+                uint32_t dfar_ns;
+                uint32_t ifar_s;
+                uint32_t dfar_s;
+#else
+                uint32_t dfar_ns;
+                uint32_t ifar_ns;
+                uint32_t dfar_s;
+                uint32_t ifar_s;
+#endif
+                uint64_t _unused_far3;;
+            };
+            uint64_t far_el[4];
+        };
         uint64_t par_el1;  /* Translation result. */
         uint32_t c9_insn; /* Cache lockdown registers.  */
         uint32_t c9_data;
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 85c7cc8..e29f340 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -567,7 +567,8 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
       .access = PL0_W, .type = ARM_CP_NOP },
     { .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 2,
       .access = PL1_RW,
-      .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el[1]),
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ifar_s),
+                             offsetof(CPUARMState, cp15.ifar_ns) },
       .resetvalue = 0, },
     /* Watchpoint Fault Address Register : should actually only be present
      * for 1136, 1176, 11MPCore.
@@ -1700,11 +1701,14 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
       .resetfn = arm_cp_reset_ignore, .raw_writefn = vmsa_ttbcr_raw_write,
       .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.ttbcr_s),
                              offsetoflow32(CPUARMState, cp15.ttbcr_ns) } },
-    /* 64-bit FAR; this entry also gives us the AArch32 DFAR */
-    { .name = "FAR_EL1", .state = ARM_CP_STATE_BOTH,
+    { .name = "DFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
+      .access = PL1_RW, .resetvalue = 0,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.dfar_s),
+                             offsetof(CPUARMState, cp15.dfar_ns) } },
+    { .name = "FAR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
-      .resetvalue = 0, },
+      .access = PL1_RW, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.far_el[1]) },
     REGINFO_SENTINEL
 };
 
@@ -4380,8 +4384,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
         /* Fall through to prefetch abort.  */
     case EXCP_PREFETCH_ABORT:
         A32_BANKED_CURRENT_REG_SET(env, ifsr, env->exception.fsr);
-        env->cp15.far_el[1] = deposit64(env->cp15.far_el[1], 32, 32,
-                                        env->exception.vaddress);
+        A32_BANKED_CURRENT_REG_SET(env, ifar, env->exception.vaddress);
         qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n",
                       env->exception.fsr, (uint32_t)env->exception.vaddress);
         new_mode = ARM_CPU_MODE_ABT;
@@ -4391,8 +4394,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
         break;
     case EXCP_DATA_ABORT:
         A32_BANKED_CURRENT_REG_SET(env, dfsr, env->exception.fsr);
-        env->cp15.far_el[1] = deposit64(env->cp15.far_el[1], 0, 32,
-                                        env->exception.vaddress);
+        A32_BANKED_CURRENT_REG_SET(env, dfar, env->exception.vaddress);
         qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n",
                       env->exception.fsr,
                       (uint32_t)env->exception.vaddress);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 28/33] target-arm: make PAR banked
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (26 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 27/33] target-arm: make IFAR/DFAR banked Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 29/33] target-arm: make VBAR banked Greg Bellows
                   ` (5 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

When EL3 is running in Aarch32 (or ARMv7 with Security Extensions)
PAR has a secure and a non-secure instance.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

-------------
v3 -> v4
- Fix par union/structure definition
---
 target-arm/cpu.h    | 10 +++++++++-
 target-arm/helper.c | 25 ++++++++++++++-----------
 2 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 0f70245..4b70530 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -293,7 +293,15 @@ typedef struct CPUARMState {
             };
             uint64_t far_el[4];
         };
-        uint64_t par_el1;  /* Translation result. */
+        union { /* Translation result. */
+            struct {
+                uint64_t par_ns;
+                uint64_t par_s;
+            };
+            struct {
+                uint64_t par_el1;
+            };
+        };
         uint32_t c9_insn; /* Cache lockdown registers.  */
         uint32_t c9_data;
         uint64_t c9_pmcr; /* performance monitor control register */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index e29f340..2b0918f 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1432,7 +1432,7 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
              * fault.
              */
         }
-        env->cp15.par_el1 = par64;
+        A32_BANKED_CURRENT_REG_SET(env, par, par64);
     } else {
         /* ret is a DFSR/IFSR value for the short descriptor
          * translation table format (with WnR always clear).
@@ -1442,14 +1442,16 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
             /* We do not set any attribute bits in the PAR */
             if (page_size == (1 << 24)
                 && arm_feature(env, ARM_FEATURE_V7)) {
-                env->cp15.par_el1 = (phys_addr & 0xff000000) | 1 << 1;
+                A32_BANKED_CURRENT_REG_SET(env, par,
+                        (phys_addr & 0xff000000) | 1 << 1);
             } else {
-                env->cp15.par_el1 = phys_addr & 0xfffff000;
+                A32_BANKED_CURRENT_REG_SET(env, par, phys_addr & 0xfffff000);
             }
         } else {
-            env->cp15.par_el1 = ((ret & (1 << 10)) >> 5) |
-                ((ret & (1 << 12)) >> 6) |
-                ((ret & 0xf) << 1) | 1;
+            A32_BANKED_CURRENT_REG_SET(env, par,
+                    ((ret & (1 << 10)) >> 5) |
+                    ((ret & (1 << 12)) >> 6) |
+                    ((ret & 0xf) << 1) | 1);
         }
     }
 }
@@ -1457,9 +1459,9 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
 
 static const ARMCPRegInfo vapa_cp_reginfo[] = {
     { .name = "PAR", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .resetvalue = 0,
-      .fieldoffset = offsetoflow32(CPUARMState, cp15.par_el1),
-      .writefn = par_write },
+      .access = PL1_RW, .resetvalue = 0, .writefn = par_write,
+      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.par_s),
+                             offsetoflow32(CPUARMState, cp15.par_ns) } },
 #ifndef CONFIG_USER_ONLY
     { .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY,
       .access = PL1_W, .accessfn = ats_access,
@@ -1921,8 +1923,9 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
       .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_OVERRIDE,
       .resetvalue = 0 },
     { .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0,
-      .access = PL1_RW, .type = ARM_CP_64BIT,
-      .fieldoffset = offsetof(CPUARMState, cp15.par_el1), .resetvalue = 0 },
+      .access = PL1_RW, .type = ARM_CP_64BIT, .resetvalue = 0,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.par_s),
+                             offsetof(CPUARMState, cp15.par_ns)} },
     { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0,
       .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE,
       .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 29/33] target-arm: make VBAR banked
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (27 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 28/33] target-arm: make PAR banked Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 30/33] target-arm: make MAIR0/1 banked Greg Bellows
                   ` (4 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

When EL3 is running in Aarch32 (or ARMv7 with Security Extensions)
VBAR has a secure and a non-secure instance, which are mapped to
VBAR_EL1 and VBAR_EL3.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

----------------
v3 -> v4
- Fix vbar union/structure definition
- Revert back to array-based vbar definition combined with v7 naming
---
 target-arm/cpu.h    | 10 +++++++++-
 target-arm/helper.c | 13 +++++++++----
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 4b70530..1fa9e0d 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -311,7 +311,15 @@ typedef struct CPUARMState {
         uint32_t c9_pmuserenr; /* perf monitor user enable */
         uint32_t c9_pminten; /* perf monitor interrupt enables */
         uint64_t mair_el1;
-        uint64_t vbar_el[4]; /* vector base address register */
+        union { /* vector base address register */
+            struct {
+                uint64_t _unused_vbar;
+                uint64_t vbar_ns;
+                uint64_t hvbar;
+                uint64_t vbar_s;
+            };
+            uint64_t vbar_el[4];
+        };
         uint64_t mvbar; /* (monitor) vector base address register */
         uint32_t c13_fcse; /* FCSE PID.  */
         uint64_t contextidr_el1; /* Context ID.  */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 2b0918f..8543813 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -918,9 +918,9 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
       .resetvalue = 0, .writefn = pmintenclr_write, },
     { .name = "VBAR", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .writefn = vbar_write,
-      .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[1]),
-      .resetvalue = 0 },
+      .access = PL1_RW, .writefn = vbar_write, .resetvalue = 0,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
+                             offsetof(CPUARMState, cp15.vbar_ns) } },
     { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
       .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_MIGRATE },
@@ -2313,6 +2313,11 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
       .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 0,
       .type = ARM_CP_NO_MIGRATE,
       .access = PL1_RW, .readfn = spsel_read, .writefn = spsel_write },
+    { .name = "VBAR_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 0,
+      .access = PL1_RW, .writefn = vbar_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[1]),
+      .resetvalue = 0 },
     { .name = "CSSELR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
       .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0,
@@ -4451,7 +4456,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
          * This register is only followed in non-monitor mode, and is banked.
          * Note: only bits 31:5 are valid.
          */
-        addr += env->cp15.vbar_el[1];
+        addr += A32_BANKED_CURRENT_REG_GET(env, vbar);
     }
 
     if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 30/33] target-arm: make MAIR0/1 banked
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (28 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 29/33] target-arm: make VBAR banked Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 31/33] target-arm: make c13 cp regs banked (FCSEIDR, ...) Greg Bellows
                   ` (3 subsequent siblings)
  33 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

Added CP register info entries for the ARMv7 MAIR0/1 secure banks.

Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
---
 target-arm/cpu.h    | 1 +
 target-arm/helper.c | 6 ++++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 1fa9e0d..7a8eaef 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -311,6 +311,7 @@ typedef struct CPUARMState {
         uint32_t c9_pmuserenr; /* perf monitor user enable */
         uint32_t c9_pminten; /* perf monitor interrupt enables */
         uint64_t mair_el1;
+        uint64_t mair_el3;
         union { /* vector base address register */
             struct {
                 uint64_t _unused_vbar;
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 8543813..e91a019 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -958,11 +958,13 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
      */
     { .name = "MAIR0", .state = ARM_CP_STATE_AA32, .type = ARM_CP_OVERRIDE,
       .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0, .access = PL1_RW,
-      .fieldoffset = offsetoflow32(CPUARMState, cp15.mair_el1),
+      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.mair_el3),
+                             offsetoflow32(CPUARMState, cp15.mair_el1) },
       .resetfn = arm_cp_reset_ignore },
     { .name = "MAIR1", .state = ARM_CP_STATE_AA32, .type = ARM_CP_OVERRIDE,
       .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1, .access = PL1_RW,
-      .fieldoffset = offsetofhigh32(CPUARMState, cp15.mair_el1),
+      .bank_fieldoffsets = { offsetofhigh32(CPUARMState, cp15.mair_el3),
+                             offsetofhigh32(CPUARMState, cp15.mair_el1) },
       .resetfn = arm_cp_reset_ignore },
     { .name = "ISR_EL1", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 0,
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 31/33] target-arm: make c13 cp regs banked (FCSEIDR, ...)
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (29 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 30/33] target-arm: make MAIR0/1 banked Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-10-01 14:30   ` Greg Bellows
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 32/33] target-arm: add GDB scr register Greg Bellows
                   ` (2 subsequent siblings)
  33 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

When EL3 is running in Aarch32 (or ARMv7 with Security Extensions)
FCSEIDR, CONTEXTIDR, TPIDRURW, TPIDRURO and TPIDRPRW have a secure
and a non-secure instance.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

--------------
v3 -> v4
- Fix tpidrprw mapping
---
 target-arm/cpu.h    | 45 ++++++++++++++++++++++++++++++++++++++++-----
 target-arm/helper.c | 36 ++++++++++++++++++++++++------------
 2 files changed, 64 insertions(+), 17 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 7a8eaef..7d27c69 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -322,11 +322,46 @@ typedef struct CPUARMState {
             uint64_t vbar_el[4];
         };
         uint64_t mvbar; /* (monitor) vector base address register */
-        uint32_t c13_fcse; /* FCSE PID.  */
-        uint64_t contextidr_el1; /* Context ID.  */
-        uint64_t tpidr_el0; /* User RW Thread register.  */
-        uint64_t tpidrro_el0; /* User RO Thread register.  */
-        uint64_t tpidr_el1; /* Privileged Thread register.  */
+        struct { /* FCSE PID. */
+            uint32_t c13_fcseidr_ns;
+            uint32_t c13_fcseidr_s;
+        };
+        union { /* Context ID. */
+            struct {
+                uint64_t contextidr_ns;
+                uint64_t contextidr_s;
+            };
+            struct {
+                uint64_t contextidr_el1;
+            };
+        };
+        union { /* User RW Thread register. */
+            struct {
+                uint64_t tpidrurw_ns;
+                uint64_t tpidrurw_s;
+            };
+            struct {
+                uint64_t tpidr_el0;
+            };
+        };
+        union { /* User RO Thread register. */
+            struct {
+                uint64_t tpidruro_ns;
+                uint64_t tpidruro_s;
+            };
+            struct {
+                uint64_t tpidrro_el0;
+            };
+        };
+        union { /* Privileged Thread register. */
+            struct {
+                uint64_t tpidrprw_ns;
+                uint64_t tpidrprw_s;
+            };
+            struct {
+                uint64_t tpidr_el1;
+            };
+        };
         uint64_t c14_cntfrq; /* Counter Frequency register */
         uint64_t c14_cntkctl; /* Timer Control register */
         ARMGenericTimer c14_timer[NUM_GTIMERS];
diff --git a/target-arm/helper.c b/target-arm/helper.c
index e91a019..8d9563f 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -420,12 +420,15 @@ static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
 
 static const ARMCPRegInfo cp_reginfo[] = {
     { .name = "FCSEIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse),
+      .access = PL1_RW,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.c13_fcseidr_s),
+                             offsetof(CPUARMState, cp15.c13_fcseidr_ns) },
       .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
-    { .name = "CONTEXTIDR", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
+    { .name = "CONTEXTIDR",
+      .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
       .access = PL1_RW,
-      .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el1),
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.contextidr_s),
+                             offsetof(CPUARMState, cp15.contextidr_ns) },
       .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
     REGINFO_SENTINEL
 };
@@ -1042,21 +1045,25 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
       .access = PL0_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el0), .resetvalue = 0 },
     { .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2,
-      .access = PL0_RW,
-      .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidr_el0),
-      .resetfn = arm_cp_reset_ignore },
+      .access = PL0_RW, .resetvalue = 0,
+      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrurw_s),
+                             offsetoflow32(CPUARMState, cp15.tpidrurw_ns) } },
     { .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0,
       .access = PL0_R|PL1_W,
       .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el0), .resetvalue = 0 },
     { .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3,
-      .access = PL0_R|PL1_W,
-      .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidrro_el0),
-      .resetfn = arm_cp_reset_ignore },
-    { .name = "TPIDR_EL1", .state = ARM_CP_STATE_BOTH,
+      .access = PL0_R|PL1_W, .resetvalue = 0,
+      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s),
+                             offsetoflow32(CPUARMState, cp15.tpidruro_ns) } },
+    { .name = "TPIDR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 0, .opc2 = 4, .crn = 13, .crm = 0,
       .access = PL1_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el1), .resetvalue = 0 },
+    { .name = "TPIDRPRW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 4,
+      .access = PL1_RW, .resetvalue = 0,
+      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrprw_s),
+                             offsetoflow32(CPUARMState, cp15.tpidrprw_ns) } },
     REGINFO_SENTINEL
 };
 
@@ -2324,6 +2331,11 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
       .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
       .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0,
       .fieldoffset = offsetof(CPUARMState, cp15.csselr_el1) },
+    { .name = "CONTEXTIDR_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
+      .access = PL1_RW,
+      .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el1),
+      .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write },
     REGINFO_SENTINEL
 };
 
@@ -5132,7 +5144,7 @@ static inline int get_phys_addr(CPUARMState *env, target_ulong address,
 
     /* Fast Context Switch Extension.  */
     if (address < 0x02000000)
-        address += env->cp15.c13_fcse;
+        address += A32_BANKED_CURRENT_REG_GET(env, c13_fcseidr);
 
     if ((sctlr & SCTLR_M) == 0) {
         /* MMU/MPU disabled.  */
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 32/33] target-arm: add GDB scr register
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (30 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 31/33] target-arm: make c13 cp regs banked (FCSEIDR, ...) Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-10-06 16:27   ` Peter Maydell
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 33/33] target-arm: add cpu feature EL3 to CPUs with Security Extensions Greg Bellows
  2014-10-06 16:32 ` [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Peter Maydell
  33 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

Added the ability to print the scr register like can be done with the cpsr.

Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
---
 gdb-xml/arm-core.xml | 1 +
 target-arm/cpu.c     | 2 +-
 target-arm/cpu.h     | 2 ++
 target-arm/gdbstub.c | 3 +++
 target-arm/helper.c  | 5 +++++
 5 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/gdb-xml/arm-core.xml b/gdb-xml/arm-core.xml
index 6012f34..b63b998 100644
--- a/gdb-xml/arm-core.xml
+++ b/gdb-xml/arm-core.xml
@@ -28,4 +28,5 @@
        the FPA registers historically were placed between the PC
        and the CPSR in the "g" packet.  -->
   <reg name="cpsr" bitsize="32" regnum="25"/>
+  <reg name="scr" bitsize="32" regnum="26"/>
 </feature>
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 2a5c333..ea2169b 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -1116,7 +1116,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_phys_page_debug = arm_cpu_get_phys_page_debug;
     cc->vmsd = &vmstate_arm_cpu;
 #endif
-    cc->gdb_num_core_regs = 26;
+    cc->gdb_num_core_regs = 27;
     cc->gdb_core_xml_file = "arm-core.xml";
     cc->debug_excp_handler = arm_debug_excp_handler;
 }
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 7d27c69..8059d8a 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -689,6 +689,8 @@ static inline void pstate_write(CPUARMState *env, uint32_t val)
 
 /* Return the current CPSR value.  */
 uint32_t cpsr_read(CPUARMState *env);
+/* Return the current SCR value.  */
+uint32_t scr_read(CPUARMState *env);
 /* Set the CPSR.  Note that some bits of mask must be all-set or all-clear.  */
 void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask);
 
diff --git a/target-arm/gdbstub.c b/target-arm/gdbstub.c
index 1c34396..9fbe979 100644
--- a/target-arm/gdbstub.c
+++ b/target-arm/gdbstub.c
@@ -54,6 +54,9 @@ int arm_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
     case 25:
         /* CPSR */
         return gdb_get_reg32(mem_buf, cpsr_read(env));
+    case 26:
+        /* SCR */
+        return gdb_get_reg32(mem_buf, scr_read(env));
     }
     /* Unknown register.  */
     return 0;
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 8d9563f..a721db1 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2407,6 +2407,11 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
+uint32_t scr_read(CPUARMState *env)
+{
+    return env->cp15.scr_el3;
+}
+
 static void nsacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                       uint64_t value)
 {
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [Qemu-devel] [PATCH v5 33/33] target-arm: add cpu feature EL3 to CPUs with Security Extensions
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (31 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 32/33] target-arm: add GDB scr register Greg Bellows
@ 2014-09-30 21:49 ` Greg Bellows
  2014-10-06 16:28   ` Peter Maydell
  2014-10-06 16:32 ` [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Peter Maydell
  33 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-09-30 21:49 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf
  Cc: Greg Bellows

From: Fabian Aggeler <aggelerf@ethz.ch>

Set ARM_FEATURE_EL3 feature for CPUs that implement Security Extensions.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
---
 target-arm/cpu.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index ea2169b..2a0eeb3 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -601,6 +601,7 @@ static void arm1176_initfn(Object *obj)
     set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
     set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
     set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
+    set_feature(&cpu->env, ARM_FEATURE_EL3);
     cpu->midr = 0x410fb767;
     cpu->reset_fpsid = 0x410120b5;
     cpu->mvfr0 = 0x11111111;
@@ -687,6 +688,7 @@ static void cortex_a8_initfn(Object *obj)
     set_feature(&cpu->env, ARM_FEATURE_NEON);
     set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
     set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
+    set_feature(&cpu->env, ARM_FEATURE_EL3);
     cpu->midr = 0x410fc080;
     cpu->reset_fpsid = 0x410330c0;
     cpu->mvfr0 = 0x11110222;
@@ -754,6 +756,7 @@ static void cortex_a9_initfn(Object *obj)
     set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
     set_feature(&cpu->env, ARM_FEATURE_NEON);
     set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
+    set_feature(&cpu->env, ARM_FEATURE_EL3);
     /* Note that A9 supports the MP extensions even for
      * A9UP and single-core A9MP (which are both different
      * and valid configurations; we don't model A9UP).
@@ -821,6 +824,7 @@ static void cortex_a15_initfn(Object *obj)
     set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
     set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
     set_feature(&cpu->env, ARM_FEATURE_LPAE);
+    set_feature(&cpu->env, ARM_FEATURE_EL3);
     cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
     cpu->midr = 0x412fc0f1;
     cpu->reset_fpsid = 0x410430f0;
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function Greg Bellows
@ 2014-09-30 22:50   ` Edgar E. Iglesias
  2014-10-01 12:53     ` Greg Bellows
  2014-10-06 14:56   ` Peter Maydell
  1 sibling, 1 reply; 83+ messages in thread
From: Edgar E. Iglesias @ 2014-09-30 22:50 UTC (permalink / raw)
  To: Greg Bellows
  Cc: peter.maydell, Sergey Fedorov, qemu-devel, aggelerf, serge.fdrv

On Tue, Sep 30, 2014 at 04:49:14PM -0500, Greg Bellows wrote:
> From: Fabian Aggeler <aggelerf@ethz.ch>
> 
> arm_is_secure() function allows to determine CPU security state
> if the CPU implements Security Extensions/EL3.
> arm_is_secure_below_el3() returns true if CPU is in secure state
> below EL3.

Hi Greg,

> 
> 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>
> ---
>  target-arm/cpu.h | 38 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)
> 
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 81fffd2..10afef0 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -753,6 +753,44 @@ static inline int arm_feature(CPUARMState *env, int feature)
>      return (env->features & (1ULL << feature)) != 0;
>  }
>  
> +
> +/* Return true if exception level below EL3 is in secure state */
> +static inline bool arm_is_secure_below_el3(CPUARMState *env)
> +{
> +#if !defined(CONFIG_USER_ONLY)
> +    if (arm_feature(env, ARM_FEATURE_EL3)) {
> +        return !(env->cp15.scr_el3 & SCR_NS);
> +    } else if (arm_feature(env, ARM_FEATURE_EL2)) {
> +        return false;
> +    } else {
> +        /* IMPDEF: QEMU defaults to non-secure */
> +        return false;
> +    }
> +#else
> +    return false;
> +#endif
> +}

arm_is_secure_below_el3() is never called from CONFIG_USER_ONLY
code so maybe we could ifdef around the entire function
for readability?

Or maybe even around both functions and provide a separate
static inline bool arm_is_secure(CPUARMState *env)
{
    return false;
}
for the user_only case.

Cheers,
Edgar


> +
> +/* Return true if the processor is in secure state */
> +static inline bool arm_is_secure(CPUARMState *env)
> +{
> +#if !defined(CONFIG_USER_ONLY)
> +    if (arm_feature(env, ARM_FEATURE_EL3)) {
> +        if (env->aarch64 && extract32(env->pstate, 2, 2) == 3) {
> +            /* CPU currently in Aarch64 state and EL3 */
> +            return true;
> +        } else if (!env->aarch64 &&
> +                (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
> +            /* CPU currently in Aarch32 state and monitor mode */
> +            return true;
> +        }
> +    }
> +    return arm_is_secure_below_el3(env);
> +#else
> +    return false;
> +#endif
> +}
> +
>  /* Return true if the specified exception level is running in AArch64 state. */
>  static inline bool arm_el_is_aa64(CPUARMState *env, int el)
>  {
> -- 
> 1.8.3.2
> 

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 04/33] target-arm: rename arm_current_pl to arm_current_el
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 04/33] target-arm: rename arm_current_pl to arm_current_el Greg Bellows
@ 2014-09-30 22:56   ` Edgar E. Iglesias
  2014-10-01 12:54     ` Greg Bellows
  2014-10-06 15:10   ` Peter Maydell
  1 sibling, 1 reply; 83+ messages in thread
From: Edgar E. Iglesias @ 2014-09-30 22:56 UTC (permalink / raw)
  To: Greg Bellows; +Cc: peter.maydell, qemu-devel, aggelerf, serge.fdrv

On Tue, Sep 30, 2014 at 04:49:16PM -0500, Greg Bellows wrote:
> Renamed the arm_current_pl CPU function to more accurately represent that it
> returns the ARMv8 EL rather than ARMv7 PL.
> 
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> ---
>  target-arm/cpu.h           | 18 +++++++++---------
>  target-arm/helper-a64.c    |  6 +++---
>  target-arm/helper.c        | 22 +++++++++++-----------
>  target-arm/internals.h     |  2 +-
>  target-arm/op_helper.c     | 16 ++++++++--------
>  target-arm/translate-a64.c |  2 +-
>  target-arm/translate.c     |  2 +-
>  7 files changed, 34 insertions(+), 34 deletions(-)
> 
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 10afef0..101d139 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -982,7 +982,7 @@ static inline bool cptype_valid(int cptype)
>  #define PL1_RW (PL1_R | PL1_W)
>  #define PL0_RW (PL0_R | PL0_W)
>  
> -static inline int arm_current_pl(CPUARMState *env)
> +static inline int arm_current_el(CPUARMState *env)
>  {
>      if (env->aarch64) {
>          return extract32(env->pstate, 2, 2);
> @@ -1222,7 +1222,7 @@ bool write_cpustate_to_list(ARMCPU *cpu);
>  static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
>  {
>      CPUARMState *env = cs->env_ptr;
> -    unsigned int cur_el = arm_current_pl(env);
> +    unsigned int cur_el = arm_current_el(env);
>      unsigned int target_el = arm_excp_target_el(cs, excp_idx);
>      /* FIXME: Use actual secure state.  */
>      bool secure = false;
> @@ -1294,7 +1294,7 @@ static inline CPUARMState *cpu_init(const char *cpu_model)
>  #define MMU_USER_IDX 0
>  static inline int cpu_mmu_index (CPUARMState *env)
>  {
> -    return arm_current_pl(env);
> +    return arm_current_el(env);
>  }
>  
>  /* Return the Exception Level targeted by debug exceptions;
> @@ -1307,7 +1307,7 @@ static inline int arm_debug_target_el(CPUARMState *env)
>  
>  static inline bool aa64_generate_debug_exceptions(CPUARMState *env)
>  {
> -    if (arm_current_pl(env) == arm_debug_target_el(env)) {
> +    if (arm_current_el(env) == arm_debug_target_el(env)) {
>          if ((extract32(env->cp15.mdscr_el1, 13, 1) == 0)
>              || (env->daif & PSTATE_D)) {
>              return false;
> @@ -1318,10 +1318,10 @@ static inline bool aa64_generate_debug_exceptions(CPUARMState *env)
>  
>  static inline bool aa32_generate_debug_exceptions(CPUARMState *env)
>  {
> -    if (arm_current_pl(env) == 0 && arm_el_is_aa64(env, 1)) {
> +    if (arm_current_el(env) == 0 && arm_el_is_aa64(env, 1)) {
>          return aa64_generate_debug_exceptions(env);
>      }
> -    return arm_current_pl(env) != 2;
> +    return arm_current_el(env) != 2;
>  }
>  
>  /* Return true if debugging exceptions are currently enabled.
> @@ -1451,8 +1451,8 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
>      if (is_a64(env)) {
>          *pc = env->pc;
>          *flags = ARM_TBFLAG_AARCH64_STATE_MASK
> -            | (arm_current_pl(env) << ARM_TBFLAG_AA64_EL_SHIFT);
> -        if (fpen == 3 || (fpen == 1 && arm_current_pl(env) != 0)) {
> +            | (arm_current_el(env) << ARM_TBFLAG_AA64_EL_SHIFT);
> +        if (fpen == 3 || (fpen == 1 && arm_current_el(env) != 0)) {
>              *flags |= ARM_TBFLAG_AA64_FPEN_MASK;
>          }
>          /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
> @@ -1488,7 +1488,7 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
>              || arm_el_is_aa64(env, 1)) {
>              *flags |= ARM_TBFLAG_VFPEN_MASK;
>          }
> -        if (fpen == 3 || (fpen == 1 && arm_current_pl(env) != 0)) {
> +        if (fpen == 3 || (fpen == 1 && arm_current_el(env) != 0)) {
>              *flags |= ARM_TBFLAG_CPACR_FPEN_MASK;
>          }
>          /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
> diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
> index 8228e29..173f116 100644
> --- a/target-arm/helper-a64.c
> +++ b/target-arm/helper-a64.c
> @@ -448,7 +448,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
>      unsigned int new_mode = aarch64_pstate_mode(new_el, true);
>      int i;
>  
> -    if (arm_current_pl(env) < new_el) {
> +    if (arm_current_el(env) < new_el) {
>          if (env->aarch64) {
>              addr += 0x400;
>          } else {
> @@ -459,7 +459,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
>      }
>  
>      arm_log_exception(cs->exception_index);
> -    qemu_log_mask(CPU_LOG_INT, "...from EL%d\n", arm_current_pl(env));
> +    qemu_log_mask(CPU_LOG_INT, "...from EL%d\n", arm_current_el(env));
>      if (qemu_loglevel_mask(CPU_LOG_INT)
>          && !excp_is_internal(cs->exception_index)) {
>          qemu_log_mask(CPU_LOG_INT, "...with ESR 0x%" PRIx32 "\n",
> @@ -495,7 +495,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
>  
>      if (is_a64(env)) {
>          env->banked_spsr[aarch64_banked_spsr_index(new_el)] = pstate_read(env);
> -        aarch64_save_sp(env, arm_current_pl(env));
> +        aarch64_save_sp(env, arm_current_el(env));
>          env->elr_el[new_el] = env->pc;
>      } else {
>          env->banked_spsr[0] = cpsr_read(env);
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index d6e3b52..2381e6f 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -571,7 +571,7 @@ static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri)
>      /* Performance monitor registers user accessibility is controlled
>       * by PMUSERENR.
>       */
> -    if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
> +    if (arm_current_el(env) == 0 && !env->cp15.c9_pmuserenr) {
>          return CP_ACCESS_TRAP;
>      }
>      return CP_ACCESS_OK;
> @@ -996,7 +996,7 @@ static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
>  
>  static CPAccessResult teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
> -    if (arm_current_pl(env) == 0 && (env->teecr & 1)) {
> +    if (arm_current_el(env) == 0 && (env->teecr & 1)) {
>          return CP_ACCESS_TRAP;
>      }
>      return CP_ACCESS_OK;
> @@ -1042,7 +1042,7 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
>  static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
>      /* CNTFRQ: not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero */
> -    if (arm_current_pl(env) == 0 && !extract32(env->cp15.c14_cntkctl, 0, 2)) {
> +    if (arm_current_el(env) == 0 && !extract32(env->cp15.c14_cntkctl, 0, 2)) {
>          return CP_ACCESS_TRAP;
>      }
>      return CP_ACCESS_OK;
> @@ -1051,7 +1051,7 @@ static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri)
>  static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx)
>  {
>      /* CNT[PV]CT: not visible from PL0 if ELO[PV]CTEN is zero */
> -    if (arm_current_pl(env) == 0 &&
> +    if (arm_current_el(env) == 0 &&
>          !extract32(env->cp15.c14_cntkctl, timeridx, 1)) {
>          return CP_ACCESS_TRAP;
>      }
> @@ -1063,7 +1063,7 @@ static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx)
>      /* CNT[PV]_CVAL, CNT[PV]_CTL, CNT[PV]_TVAL: not visible from PL0 if
>       * EL0[PV]TEN is zero.
>       */
> -    if (arm_current_pl(env) == 0 &&
> +    if (arm_current_el(env) == 0 &&
>          !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
>          return CP_ACCESS_TRAP;
>      }
> @@ -1911,7 +1911,7 @@ static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
>  
>  static CPAccessResult aa64_daif_access(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
> -    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
> +    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
>          return CP_ACCESS_TRAP;
>      }
>      return CP_ACCESS_OK;
> @@ -1929,7 +1929,7 @@ static CPAccessResult aa64_cacheop_access(CPUARMState *env,
>      /* Cache invalidate/clean: NOP, but EL0 must UNDEF unless
>       * SCTLR_EL1.UCI is set.
>       */
> -    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCI)) {
> +    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCI)) {
>          return CP_ACCESS_TRAP;
>      }
>      return CP_ACCESS_OK;
> @@ -2006,7 +2006,7 @@ static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri)
>      /* We don't implement EL2, so the only control on DC ZVA is the
>       * bit in the SCTLR which can prohibit access for EL0.
>       */
> -    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_DZE)) {
> +    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_DZE)) {
>          return CP_ACCESS_TRAP;
>      }
>      return CP_ACCESS_OK;
> @@ -2366,7 +2366,7 @@ static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri)
>      /* Only accessible in EL0 if SCTLR.UCT is set (and only in AArch64,
>       * but the AArch32 CTR has its own reginfo struct)
>       */
> -    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCT)) {
> +    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCT)) {
>          return CP_ACCESS_TRAP;
>      }
>      return CP_ACCESS_OK;
> @@ -3773,7 +3773,7 @@ unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
>  {
>      ARMCPU *cpu = ARM_CPU(cs);
>      CPUARMState *env = &cpu->env;
> -    unsigned int cur_el = arm_current_pl(env);
> +    unsigned int cur_el = arm_current_el(env);
>      unsigned int target_el;
>      /* FIXME: Use actual secure state.  */
>      bool secure = false;
> @@ -4769,7 +4769,7 @@ int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
>      int prot;
>      int ret, is_user;
>      uint32_t syn;
> -    bool same_el = (arm_current_pl(env) != 0);
> +    bool same_el = (arm_current_el(env) != 0);
>  
>      is_user = mmu_idx == MMU_USER_IDX;
>      ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot,
> diff --git a/target-arm/internals.h b/target-arm/internals.h
> index b7547bb..fd69a83 100644
> --- a/target-arm/internals.h
> +++ b/target-arm/internals.h
> @@ -130,7 +130,7 @@ static inline void aarch64_restore_sp(CPUARMState *env, int el)
>  
>  static inline void update_spsel(CPUARMState *env, uint32_t imm)
>  {
> -    unsigned int cur_el = arm_current_pl(env);
> +    unsigned int cur_el = arm_current_el(env);
>      /* Update PSTATE SPSel bit; this requires us to update the
>       * working stack pointer in xregs[31].
>       */
> diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
> index 03ac92a..0809d63 100644
> --- a/target-arm/op_helper.c
> +++ b/target-arm/op_helper.c
> @@ -361,7 +361,7 @@ void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
>       * Note that SPSel is never OK from EL0; we rely on handle_msr_i()
>       * to catch that case at translate time.
>       */
> -    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
> +    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
>          raise_exception(env, EXCP_UDEF);
>      }
>  
> @@ -387,7 +387,7 @@ void HELPER(clear_pstate_ss)(CPUARMState *env)
>  
>  void HELPER(pre_hvc)(CPUARMState *env)
>  {
> -    int cur_el = arm_current_pl(env);
> +    int cur_el = arm_current_el(env);
>      /* FIXME: Use actual secure state.  */
>      bool secure = false;
>      bool undef;
> @@ -418,7 +418,7 @@ void HELPER(pre_hvc)(CPUARMState *env)
>  
>  void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
>  {
> -    int cur_el = arm_current_pl(env);
> +    int cur_el = arm_current_el(env);
>      /* FIXME: Use real secure state.  */
>      bool secure = false;
>      bool smd = env->cp15.scr_el3 & SCR_SMD;
> @@ -444,7 +444,7 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
>  
>  void HELPER(exception_return)(CPUARMState *env)
>  {
> -    int cur_el = arm_current_pl(env);
> +    int cur_el = arm_current_el(env);
>      unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
>      uint32_t spsr = env->banked_spsr[spsr_idx];
>      int new_el, i;
> @@ -561,7 +561,7 @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
>  
>      switch (bt) {
>      case 3: /* linked context ID match */
> -        if (arm_current_pl(env) > 1) {
> +        if (arm_current_el(env) > 1) {
>              /* Context matches never fire in EL2 or (AArch64) EL3 */
>              return false;
>          }
> @@ -641,7 +641,7 @@ static bool bp_wp_matches(ARMCPU *cpu, int n, bool is_wp)
>       * rely on this behaviour currently.
>       * For breakpoints we do want to use the current CPU state.
>       */
> -    switch (arm_current_pl(env)) {
> +    switch (arm_current_el(env)) {
>      case 3:
>      case 2:
>          if (!hmc) {
> @@ -728,7 +728,7 @@ void arm_debug_excp_handler(CPUState *cs)
>              cs->watchpoint_hit = NULL;
>              if (check_watchpoints(cpu)) {
>                  bool wnr = (wp_hit->flags & BP_WATCHPOINT_HIT_WRITE) != 0;
> -                bool same_el = arm_debug_target_el(env) == arm_current_pl(env);
> +                bool same_el = arm_debug_target_el(env) == arm_current_el(env);
>  
>                  env->exception.syndrome = syn_watchpoint(same_el, 0, wnr);
>                  if (extended_addresses_enabled(env)) {
> @@ -744,7 +744,7 @@ void arm_debug_excp_handler(CPUState *cs)
>          }
>      } else {
>          if (check_breakpoints(cpu)) {
> -            bool same_el = (arm_debug_target_el(env) == arm_current_pl(env));
> +            bool same_el = (arm_debug_target_el(env) == arm_current_el(env));
>              env->exception.syndrome = syn_breakpoint(same_el);
>              if (extended_addresses_enabled(env)) {
>                  env->exception.fsr = (1 << 9) | 0x22;
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index 35ae3ea..f53dc0f 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -10930,7 +10930,7 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
>      dc->vec_len = 0;
>      dc->vec_stride = 0;
>      dc->cp_regs = cpu->cp_regs;
> -    dc->current_pl = arm_current_pl(env);
> +    dc->current_pl = arm_current_el(env);
>      dc->features = env->features;
>  
>      /* Single step state. The code-generation logic here is:
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index 8a2994f..f6404be 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -10945,7 +10945,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
>      dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
>      dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
>      dc->cp_regs = cpu->cp_regs;
> -    dc->current_pl = arm_current_pl(env);
> +    dc->current_pl = arm_current_el(env);

Should we rename dc->current_pl aswell?
This might turn into a patch that is hard to maintain while the series
gets reviewed. Maybe this change to be done earlier and hopefully get
merged early to avoid some pain on your side....

Cheers,
Edgar

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 22/33] target-arm: add TCR_EL3 and make TTBCR banked
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 22/33] target-arm: add TCR_EL3 and make TTBCR banked Greg Bellows
@ 2014-09-30 23:18   ` Edgar E. Iglesias
  2014-10-01 13:05     ` Greg Bellows
  0 siblings, 1 reply; 83+ messages in thread
From: Edgar E. Iglesias @ 2014-09-30 23:18 UTC (permalink / raw)
  To: Greg Bellows; +Cc: peter.maydell, qemu-devel, aggelerf, serge.fdrv

On Tue, Sep 30, 2014 at 04:49:34PM -0500, Greg Bellows wrote:
> From: Fabian Aggeler <aggelerf@ethz.ch>
> 
> Adds TCR_EL3 system register and makes existing TTBCR banked. Adjust
> translation functions to use TCR/TTBCR instance depending on CPU state.
> 
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> 
> ----------
> v4 -> v5
> - Changed c2_mask updates to use the TTBCR cpreg bank flag for selcting the
>   secure bank instead of the A32_BANKED_CURRENT macro.  This more accurately
>   chooses the correct bank matching that of the TTBCR being accessed.
> ---
>  target-arm/cpu.h       | 11 ++++++++++-
>  target-arm/helper.c    | 48 +++++++++++++++++++++++++++++++++++-------------
>  target-arm/internals.h |  2 +-
>  3 files changed, 46 insertions(+), 15 deletions(-)
> 
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index c99158e..477c219 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -221,7 +221,16 @@ typedef struct CPUARMState {
>                  uint64_t ttbr1_el1;
>              };
>          };
> -        uint64_t c2_control; /* MMU translation table base control.  */
> +        union { /* MMU translation table base control. */
> +            struct {
> +                uint64_t ttbcr_ns;
> +                uint64_t ttbcr_s;
> +            };
> +            struct {
> +                uint64_t tcr_el1;
> +                uint64_t tcr_el3;
> +            };
> +        };

I was hoping that the aarch64 regs would be arrays (e.g tcr_el[4])...





>          uint32_t c2_mask; /* MMU translation table base selection mask.  */
>          uint32_t c2_base_mask; /* MMU translation table base 0 mask. */
>          uint32_t c2_data; /* MPU data cachable bits.  */
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 2a6a129..bdb76e0 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1678,11 +1678,12 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
>        .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
>        .access = PL1_RW, .writefn = vmsa_tcr_el1_write,
>        .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
> -      .fieldoffset = offsetof(CPUARMState, cp15.c2_control) },
> +      .fieldoffset = offsetof(CPUARMState, cp15.tcr_el1) },
>      { .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
>        .access = PL1_RW, .type = ARM_CP_NO_MIGRATE, .writefn = vmsa_ttbcr_write,
>        .resetfn = arm_cp_reset_ignore, .raw_writefn = vmsa_ttbcr_raw_write,
> -      .fieldoffset = offsetoflow32(CPUARMState, cp15.c2_control) },
> +      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.ttbcr_s),
> +                             offsetoflow32(CPUARMState, cp15.ttbcr_ns) } },
>      /* 64-bit FAR; this entry also gives us the AArch32 DFAR */
>      { .name = "FAR_EL1", .state = ARM_CP_STATE_BOTH,
>        .opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
> @@ -2421,6 +2422,11 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
>        .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 6, .opc2 = 0,
>        .access = PL3_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
>        .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el3) },
> +    { .name = "TCR_EL3", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 6, .opc2 = 2,
> +      .access = PL3_RW, .writefn = vmsa_tcr_el1_write,
> +      .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
> +      .fieldoffset = offsetof(CPUARMState, cp15.tcr_el3) },
>      { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
>        .type = ARM_CP_NO_MIGRATE,
>        .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1,
> @@ -4515,13 +4521,13 @@ static bool get_level1_table_address(CPUARMState *env, uint32_t *table,
>       * table registers.
>       */
>      if (address & env->cp15.c2_mask) {
> -        if ((env->cp15.c2_control & TTBCR_PD1)) {
> +        if (A32_BANKED_CURRENT_REG_GET(env, ttbcr) & TTBCR_PD1) {
>              /* Translation table walk disabled for TTBR1 */
>              return false;
>          }
>          *table = A32_BANKED_CURRENT_REG_GET(env, ttbr1) & 0xffffc000;
>      } else {
> -        if ((env->cp15.c2_control & TTBCR_PD0)) {
> +        if (A32_BANKED_CURRENT_REG_GET(env, ttbcr) & TTBCR_PD0) {
>              /* Translation table walk disabled for TTBR0 */
>              return false;
>          }
> @@ -4781,13 +4787,29 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
>      int32_t va_size = 32;
>      int32_t tbi = 0;
>      uint32_t cur_el = arm_current_el(env);
> +    uint64_t tcr;
>  
> -    if (arm_el_is_aa64(env, 1)) {
> +    if (arm_el_is_aa64(env, 3)) {
> +        switch (cur_el) {
> +        case 3:
> +            tcr = env->cp15.tcr_el3;
> +            break;
> +        case 1:
> +        case 0:
> +        default:
> +            tcr = env->cp15.tcr_el1;
> +        }
> +
> +    } else {
> +        tcr = A32_BANKED_CURRENT_REG_GET(env, ttbcr);
> +    }
> +
> +    if (arm_el_is_aa64(env, 1) && (cur_el == 0 || cur_el == 1)) {
>          va_size = 64;
>          if (extract64(address, 55, 1))
> -            tbi = extract64(env->cp15.c2_control, 38, 1);
> +            tbi = extract64(tcr, 38, 1);
>          else
> -            tbi = extract64(env->cp15.c2_control, 37, 1);
> +            tbi = extract64(tcr, 37, 1);
>          tbi *= 8;
>      }
>  
> @@ -4796,12 +4818,12 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
>       * This is a Non-secure PL0/1 stage 1 translation, so controlled by
>       * TTBCR/TTBR0/TTBR1 in accordance with ARM ARM DDI0406C table B-32:
>       */
> -    uint32_t t0sz = extract32(env->cp15.c2_control, 0, 6);
> +    uint32_t t0sz = extract32(tcr, 0, 6);
>      if (arm_el_is_aa64(env, 1)) {
>          t0sz = MIN(t0sz, 39);
>          t0sz = MAX(t0sz, 16);
>      }
> -    uint32_t t1sz = extract32(env->cp15.c2_control, 16, 6);
> +    uint32_t t1sz = extract32(tcr, 16, 6);
>      if (arm_el_is_aa64(env, 1)) {
>          t1sz = MIN(t1sz, 39);
>          t1sz = MAX(t1sz, 16);
> @@ -4845,10 +4867,10 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
>          } else {
>              ttbr = A32_BANKED_CURRENT_REG_GET(env, ttbr0);
>          }
> -        epd = extract32(env->cp15.c2_control, 7, 1);
> +        epd = extract32(tcr, 7, 1);
>          tsz = t0sz;
>  
> -        tg = extract32(env->cp15.c2_control, 14, 2);
> +        tg = extract32(tcr, 14, 2);
>          if (tg == 1) { /* 64KB pages */
>              granule_sz = 13;
>          }
> @@ -4857,10 +4879,10 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
>          }
>      } else {
>          ttbr = A32_BANKED_CURRENT_REG_GET(env, ttbr1);
> -        epd = extract32(env->cp15.c2_control, 23, 1);
> +        epd = extract32(tcr, 23, 1);
>          tsz = t1sz;
>  
> -        tg = extract32(env->cp15.c2_control, 30, 2);
> +        tg = extract32(tcr, 30, 2);
>          if (tg == 3)  { /* 64KB pages */
>              granule_sz = 13;
>          }
> diff --git a/target-arm/internals.h b/target-arm/internals.h
> index 43a2e7d..dba7766 100644
> --- a/target-arm/internals.h
> +++ b/target-arm/internals.h
> @@ -155,7 +155,7 @@ static inline bool extended_addresses_enabled(CPUARMState *env)
>  {
>      return arm_el_is_aa64(env, 1)
>          || ((arm_feature(env, ARM_FEATURE_LPAE)
> -             && (env->cp15.c2_control & TTBCR_EAE)));
> +             && (A32_BANKED_CURRENT_REG_GET(env, ttbcr) & TTBCR_EAE)));
>  }
>  
>  /* Valid Syndrome Register EC field values */
> -- 
> 1.8.3.2
> 

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 05/33] target-arm: make arm_current_pl() return PL3
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 05/33] target-arm: make arm_current_pl() return PL3 Greg Bellows
@ 2014-10-01  1:23   ` Sergey Fedorov
  2014-10-01 14:31     ` Greg Bellows
  2014-10-06 15:34   ` Peter Maydell
  1 sibling, 1 reply; 83+ messages in thread
From: Sergey Fedorov @ 2014-10-01  1:23 UTC (permalink / raw)
  To: Greg Bellows, qemu-devel, peter.maydell, edgar.iglesias, aggelerf

On 30.09.2014 14:49, Greg Bellows wrote:
> From: Fabian Aggeler <aggelerf@ethz.ch>
>
> Make arm_current_pl() return PL3 for secure PL1 and monitor mode.
> Increase MMU modes since mmu_index is directly infered from arm_
> current_pl(). Changes assertion in arm_el_is_aa64() to allow EL3.

arm_current_pl() is renamed in previous patch :)

>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function
  2014-09-30 22:50   ` Edgar E. Iglesias
@ 2014-10-01 12:53     ` Greg Bellows
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-10-01 12:53 UTC (permalink / raw)
  To: Edgar E. Iglesias
  Cc: Peter Maydell, Sergey Fedorov, QEMU Developers, Fabian Aggeler,
	Sergey Fedorov

[-- Attachment #1: Type: text/plain, Size: 2842 bytes --]

Yeah, that would be cleaner, I'll fix it in the next version.

On 30 September 2014 17:50, Edgar E. Iglesias <edgar.iglesias@gmail.com>
wrote:

> On Tue, Sep 30, 2014 at 04:49:14PM -0500, Greg Bellows wrote:
> > From: Fabian Aggeler <aggelerf@ethz.ch>
> >
> > arm_is_secure() function allows to determine CPU security state
> > if the CPU implements Security Extensions/EL3.
> > arm_is_secure_below_el3() returns true if CPU is in secure state
> > below EL3.
>
> Hi Greg,
>
> >
> > 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>
> > ---
> >  target-arm/cpu.h | 38 ++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 38 insertions(+)
> >
> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > index 81fffd2..10afef0 100644
> > --- a/target-arm/cpu.h
> > +++ b/target-arm/cpu.h
> > @@ -753,6 +753,44 @@ static inline int arm_feature(CPUARMState *env, int
> feature)
> >      return (env->features & (1ULL << feature)) != 0;
> >  }
> >
> > +
> > +/* Return true if exception level below EL3 is in secure state */
> > +static inline bool arm_is_secure_below_el3(CPUARMState *env)
> > +{
> > +#if !defined(CONFIG_USER_ONLY)
> > +    if (arm_feature(env, ARM_FEATURE_EL3)) {
> > +        return !(env->cp15.scr_el3 & SCR_NS);
> > +    } else if (arm_feature(env, ARM_FEATURE_EL2)) {
> > +        return false;
> > +    } else {
> > +        /* IMPDEF: QEMU defaults to non-secure */
> > +        return false;
> > +    }
> > +#else
> > +    return false;
> > +#endif
> > +}
>
> arm_is_secure_below_el3() is never called from CONFIG_USER_ONLY
> code so maybe we could ifdef around the entire function
> for readability?
>
> Or maybe even around both functions and provide a separate
> static inline bool arm_is_secure(CPUARMState *env)
> {
>     return false;
> }
> for the user_only case.
>
> Cheers,
> Edgar
>
>
> > +
> > +/* Return true if the processor is in secure state */
> > +static inline bool arm_is_secure(CPUARMState *env)
> > +{
> > +#if !defined(CONFIG_USER_ONLY)
> > +    if (arm_feature(env, ARM_FEATURE_EL3)) {
> > +        if (env->aarch64 && extract32(env->pstate, 2, 2) == 3) {
> > +            /* CPU currently in Aarch64 state and EL3 */
> > +            return true;
> > +        } else if (!env->aarch64 &&
> > +                (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
> > +            /* CPU currently in Aarch32 state and monitor mode */
> > +            return true;
> > +        }
> > +    }
> > +    return arm_is_secure_below_el3(env);
> > +#else
> > +    return false;
> > +#endif
> > +}
> > +
> >  /* Return true if the specified exception level is running in AArch64
> state. */
> >  static inline bool arm_el_is_aa64(CPUARMState *env, int el)
> >  {
> > --
> > 1.8.3.2
> >
>

[-- Attachment #2: Type: text/html, Size: 4034 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 04/33] target-arm: rename arm_current_pl to arm_current_el
  2014-09-30 22:56   ` Edgar E. Iglesias
@ 2014-10-01 12:54     ` Greg Bellows
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-10-01 12:54 UTC (permalink / raw)
  To: Edgar E. Iglesias
  Cc: Peter Maydell, QEMU Developers, Fabian Aggeler, Sergey Fedorov

[-- Attachment #1: Type: text/plain, Size: 15817 bytes --]

Yes.  Done for next version.

On 30 September 2014 17:56, Edgar E. Iglesias <edgar.iglesias@gmail.com>
wrote:

> On Tue, Sep 30, 2014 at 04:49:16PM -0500, Greg Bellows wrote:
> > Renamed the arm_current_pl CPU function to more accurately represent
> that it
> > returns the ARMv8 EL rather than ARMv7 PL.
> >
> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> > ---
> >  target-arm/cpu.h           | 18 +++++++++---------
> >  target-arm/helper-a64.c    |  6 +++---
> >  target-arm/helper.c        | 22 +++++++++++-----------
> >  target-arm/internals.h     |  2 +-
> >  target-arm/op_helper.c     | 16 ++++++++--------
> >  target-arm/translate-a64.c |  2 +-
> >  target-arm/translate.c     |  2 +-
> >  7 files changed, 34 insertions(+), 34 deletions(-)
> >
> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > index 10afef0..101d139 100644
> > --- a/target-arm/cpu.h
> > +++ b/target-arm/cpu.h
> > @@ -982,7 +982,7 @@ static inline bool cptype_valid(int cptype)
> >  #define PL1_RW (PL1_R | PL1_W)
> >  #define PL0_RW (PL0_R | PL0_W)
> >
> > -static inline int arm_current_pl(CPUARMState *env)
> > +static inline int arm_current_el(CPUARMState *env)
> >  {
> >      if (env->aarch64) {
> >          return extract32(env->pstate, 2, 2);
> > @@ -1222,7 +1222,7 @@ bool write_cpustate_to_list(ARMCPU *cpu);
> >  static inline bool arm_excp_unmasked(CPUState *cs, unsigned int
> excp_idx)
> >  {
> >      CPUARMState *env = cs->env_ptr;
> > -    unsigned int cur_el = arm_current_pl(env);
> > +    unsigned int cur_el = arm_current_el(env);
> >      unsigned int target_el = arm_excp_target_el(cs, excp_idx);
> >      /* FIXME: Use actual secure state.  */
> >      bool secure = false;
> > @@ -1294,7 +1294,7 @@ static inline CPUARMState *cpu_init(const char
> *cpu_model)
> >  #define MMU_USER_IDX 0
> >  static inline int cpu_mmu_index (CPUARMState *env)
> >  {
> > -    return arm_current_pl(env);
> > +    return arm_current_el(env);
> >  }
> >
> >  /* Return the Exception Level targeted by debug exceptions;
> > @@ -1307,7 +1307,7 @@ static inline int arm_debug_target_el(CPUARMState
> *env)
> >
> >  static inline bool aa64_generate_debug_exceptions(CPUARMState *env)
> >  {
> > -    if (arm_current_pl(env) == arm_debug_target_el(env)) {
> > +    if (arm_current_el(env) == arm_debug_target_el(env)) {
> >          if ((extract32(env->cp15.mdscr_el1, 13, 1) == 0)
> >              || (env->daif & PSTATE_D)) {
> >              return false;
> > @@ -1318,10 +1318,10 @@ static inline bool
> aa64_generate_debug_exceptions(CPUARMState *env)
> >
> >  static inline bool aa32_generate_debug_exceptions(CPUARMState *env)
> >  {
> > -    if (arm_current_pl(env) == 0 && arm_el_is_aa64(env, 1)) {
> > +    if (arm_current_el(env) == 0 && arm_el_is_aa64(env, 1)) {
> >          return aa64_generate_debug_exceptions(env);
> >      }
> > -    return arm_current_pl(env) != 2;
> > +    return arm_current_el(env) != 2;
> >  }
> >
> >  /* Return true if debugging exceptions are currently enabled.
> > @@ -1451,8 +1451,8 @@ static inline void
> cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
> >      if (is_a64(env)) {
> >          *pc = env->pc;
> >          *flags = ARM_TBFLAG_AARCH64_STATE_MASK
> > -            | (arm_current_pl(env) << ARM_TBFLAG_AA64_EL_SHIFT);
> > -        if (fpen == 3 || (fpen == 1 && arm_current_pl(env) != 0)) {
> > +            | (arm_current_el(env) << ARM_TBFLAG_AA64_EL_SHIFT);
> > +        if (fpen == 3 || (fpen == 1 && arm_current_el(env) != 0)) {
> >              *flags |= ARM_TBFLAG_AA64_FPEN_MASK;
> >          }
> >          /* The SS_ACTIVE and PSTATE_SS bits correspond to the state
> machine
> > @@ -1488,7 +1488,7 @@ static inline void
> cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
> >              || arm_el_is_aa64(env, 1)) {
> >              *flags |= ARM_TBFLAG_VFPEN_MASK;
> >          }
> > -        if (fpen == 3 || (fpen == 1 && arm_current_pl(env) != 0)) {
> > +        if (fpen == 3 || (fpen == 1 && arm_current_el(env) != 0)) {
> >              *flags |= ARM_TBFLAG_CPACR_FPEN_MASK;
> >          }
> >          /* The SS_ACTIVE and PSTATE_SS bits correspond to the state
> machine
> > diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
> > index 8228e29..173f116 100644
> > --- a/target-arm/helper-a64.c
> > +++ b/target-arm/helper-a64.c
> > @@ -448,7 +448,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
> >      unsigned int new_mode = aarch64_pstate_mode(new_el, true);
> >      int i;
> >
> > -    if (arm_current_pl(env) < new_el) {
> > +    if (arm_current_el(env) < new_el) {
> >          if (env->aarch64) {
> >              addr += 0x400;
> >          } else {
> > @@ -459,7 +459,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
> >      }
> >
> >      arm_log_exception(cs->exception_index);
> > -    qemu_log_mask(CPU_LOG_INT, "...from EL%d\n", arm_current_pl(env));
> > +    qemu_log_mask(CPU_LOG_INT, "...from EL%d\n", arm_current_el(env));
> >      if (qemu_loglevel_mask(CPU_LOG_INT)
> >          && !excp_is_internal(cs->exception_index)) {
> >          qemu_log_mask(CPU_LOG_INT, "...with ESR 0x%" PRIx32 "\n",
> > @@ -495,7 +495,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
> >
> >      if (is_a64(env)) {
> >          env->banked_spsr[aarch64_banked_spsr_index(new_el)] =
> pstate_read(env);
> > -        aarch64_save_sp(env, arm_current_pl(env));
> > +        aarch64_save_sp(env, arm_current_el(env));
> >          env->elr_el[new_el] = env->pc;
> >      } else {
> >          env->banked_spsr[0] = cpsr_read(env);
> > diff --git a/target-arm/helper.c b/target-arm/helper.c
> > index d6e3b52..2381e6f 100644
> > --- a/target-arm/helper.c
> > +++ b/target-arm/helper.c
> > @@ -571,7 +571,7 @@ static CPAccessResult pmreg_access(CPUARMState *env,
> const ARMCPRegInfo *ri)
> >      /* Performance monitor registers user accessibility is controlled
> >       * by PMUSERENR.
> >       */
> > -    if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
> > +    if (arm_current_el(env) == 0 && !env->cp15.c9_pmuserenr) {
> >          return CP_ACCESS_TRAP;
> >      }
> >      return CP_ACCESS_OK;
> > @@ -996,7 +996,7 @@ static void teecr_write(CPUARMState *env, const
> ARMCPRegInfo *ri,
> >
> >  static CPAccessResult teehbr_access(CPUARMState *env, const
> ARMCPRegInfo *ri)
> >  {
> > -    if (arm_current_pl(env) == 0 && (env->teecr & 1)) {
> > +    if (arm_current_el(env) == 0 && (env->teecr & 1)) {
> >          return CP_ACCESS_TRAP;
> >      }
> >      return CP_ACCESS_OK;
> > @@ -1042,7 +1042,7 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
> >  static CPAccessResult gt_cntfrq_access(CPUARMState *env, const
> ARMCPRegInfo *ri)
> >  {
> >      /* CNTFRQ: not visible from PL0 if both PL0PCTEN and PL0VCTEN are
> zero */
> > -    if (arm_current_pl(env) == 0 && !extract32(env->cp15.c14_cntkctl,
> 0, 2)) {
> > +    if (arm_current_el(env) == 0 && !extract32(env->cp15.c14_cntkctl,
> 0, 2)) {
> >          return CP_ACCESS_TRAP;
> >      }
> >      return CP_ACCESS_OK;
> > @@ -1051,7 +1051,7 @@ static CPAccessResult gt_cntfrq_access(CPUARMState
> *env, const ARMCPRegInfo *ri)
> >  static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx)
> >  {
> >      /* CNT[PV]CT: not visible from PL0 if ELO[PV]CTEN is zero */
> > -    if (arm_current_pl(env) == 0 &&
> > +    if (arm_current_el(env) == 0 &&
> >          !extract32(env->cp15.c14_cntkctl, timeridx, 1)) {
> >          return CP_ACCESS_TRAP;
> >      }
> > @@ -1063,7 +1063,7 @@ static CPAccessResult gt_timer_access(CPUARMState
> *env, int timeridx)
> >      /* CNT[PV]_CVAL, CNT[PV]_CTL, CNT[PV]_TVAL: not visible from PL0 if
> >       * EL0[PV]TEN is zero.
> >       */
> > -    if (arm_current_pl(env) == 0 &&
> > +    if (arm_current_el(env) == 0 &&
> >          !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
> >          return CP_ACCESS_TRAP;
> >      }
> > @@ -1911,7 +1911,7 @@ static void aa64_fpsr_write(CPUARMState *env,
> const ARMCPRegInfo *ri,
> >
> >  static CPAccessResult aa64_daif_access(CPUARMState *env, const
> ARMCPRegInfo *ri)
> >  {
> > -    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
> > +    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
> >          return CP_ACCESS_TRAP;
> >      }
> >      return CP_ACCESS_OK;
> > @@ -1929,7 +1929,7 @@ static CPAccessResult
> aa64_cacheop_access(CPUARMState *env,
> >      /* Cache invalidate/clean: NOP, but EL0 must UNDEF unless
> >       * SCTLR_EL1.UCI is set.
> >       */
> > -    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCI)) {
> > +    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCI)) {
> >          return CP_ACCESS_TRAP;
> >      }
> >      return CP_ACCESS_OK;
> > @@ -2006,7 +2006,7 @@ static CPAccessResult aa64_zva_access(CPUARMState
> *env, const ARMCPRegInfo *ri)
> >      /* We don't implement EL2, so the only control on DC ZVA is the
> >       * bit in the SCTLR which can prohibit access for EL0.
> >       */
> > -    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_DZE)) {
> > +    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_DZE)) {
> >          return CP_ACCESS_TRAP;
> >      }
> >      return CP_ACCESS_OK;
> > @@ -2366,7 +2366,7 @@ static CPAccessResult ctr_el0_access(CPUARMState
> *env, const ARMCPRegInfo *ri)
> >      /* Only accessible in EL0 if SCTLR.UCT is set (and only in AArch64,
> >       * but the AArch32 CTR has its own reginfo struct)
> >       */
> > -    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCT)) {
> > +    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCT)) {
> >          return CP_ACCESS_TRAP;
> >      }
> >      return CP_ACCESS_OK;
> > @@ -3773,7 +3773,7 @@ unsigned int arm_excp_target_el(CPUState *cs,
> unsigned int excp_idx)
> >  {
> >      ARMCPU *cpu = ARM_CPU(cs);
> >      CPUARMState *env = &cpu->env;
> > -    unsigned int cur_el = arm_current_pl(env);
> > +    unsigned int cur_el = arm_current_el(env);
> >      unsigned int target_el;
> >      /* FIXME: Use actual secure state.  */
> >      bool secure = false;
> > @@ -4769,7 +4769,7 @@ int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr
> address,
> >      int prot;
> >      int ret, is_user;
> >      uint32_t syn;
> > -    bool same_el = (arm_current_pl(env) != 0);
> > +    bool same_el = (arm_current_el(env) != 0);
> >
> >      is_user = mmu_idx == MMU_USER_IDX;
> >      ret = get_phys_addr(env, address, access_type, is_user, &phys_addr,
> &prot,
> > diff --git a/target-arm/internals.h b/target-arm/internals.h
> > index b7547bb..fd69a83 100644
> > --- a/target-arm/internals.h
> > +++ b/target-arm/internals.h
> > @@ -130,7 +130,7 @@ static inline void aarch64_restore_sp(CPUARMState
> *env, int el)
> >
> >  static inline void update_spsel(CPUARMState *env, uint32_t imm)
> >  {
> > -    unsigned int cur_el = arm_current_pl(env);
> > +    unsigned int cur_el = arm_current_el(env);
> >      /* Update PSTATE SPSel bit; this requires us to update the
> >       * working stack pointer in xregs[31].
> >       */
> > diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
> > index 03ac92a..0809d63 100644
> > --- a/target-arm/op_helper.c
> > +++ b/target-arm/op_helper.c
> > @@ -361,7 +361,7 @@ void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t
> op, uint32_t imm)
> >       * Note that SPSel is never OK from EL0; we rely on handle_msr_i()
> >       * to catch that case at translate time.
> >       */
> > -    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
> > +    if (arm_current_el(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
> >          raise_exception(env, EXCP_UDEF);
> >      }
> >
> > @@ -387,7 +387,7 @@ void HELPER(clear_pstate_ss)(CPUARMState *env)
> >
> >  void HELPER(pre_hvc)(CPUARMState *env)
> >  {
> > -    int cur_el = arm_current_pl(env);
> > +    int cur_el = arm_current_el(env);
> >      /* FIXME: Use actual secure state.  */
> >      bool secure = false;
> >      bool undef;
> > @@ -418,7 +418,7 @@ void HELPER(pre_hvc)(CPUARMState *env)
> >
> >  void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
> >  {
> > -    int cur_el = arm_current_pl(env);
> > +    int cur_el = arm_current_el(env);
> >      /* FIXME: Use real secure state.  */
> >      bool secure = false;
> >      bool smd = env->cp15.scr_el3 & SCR_SMD;
> > @@ -444,7 +444,7 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t
> syndrome)
> >
> >  void HELPER(exception_return)(CPUARMState *env)
> >  {
> > -    int cur_el = arm_current_pl(env);
> > +    int cur_el = arm_current_el(env);
> >      unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
> >      uint32_t spsr = env->banked_spsr[spsr_idx];
> >      int new_el, i;
> > @@ -561,7 +561,7 @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
> >
> >      switch (bt) {
> >      case 3: /* linked context ID match */
> > -        if (arm_current_pl(env) > 1) {
> > +        if (arm_current_el(env) > 1) {
> >              /* Context matches never fire in EL2 or (AArch64) EL3 */
> >              return false;
> >          }
> > @@ -641,7 +641,7 @@ static bool bp_wp_matches(ARMCPU *cpu, int n, bool
> is_wp)
> >       * rely on this behaviour currently.
> >       * For breakpoints we do want to use the current CPU state.
> >       */
> > -    switch (arm_current_pl(env)) {
> > +    switch (arm_current_el(env)) {
> >      case 3:
> >      case 2:
> >          if (!hmc) {
> > @@ -728,7 +728,7 @@ void arm_debug_excp_handler(CPUState *cs)
> >              cs->watchpoint_hit = NULL;
> >              if (check_watchpoints(cpu)) {
> >                  bool wnr = (wp_hit->flags & BP_WATCHPOINT_HIT_WRITE) !=
> 0;
> > -                bool same_el = arm_debug_target_el(env) ==
> arm_current_pl(env);
> > +                bool same_el = arm_debug_target_el(env) ==
> arm_current_el(env);
> >
> >                  env->exception.syndrome = syn_watchpoint(same_el, 0,
> wnr);
> >                  if (extended_addresses_enabled(env)) {
> > @@ -744,7 +744,7 @@ void arm_debug_excp_handler(CPUState *cs)
> >          }
> >      } else {
> >          if (check_breakpoints(cpu)) {
> > -            bool same_el = (arm_debug_target_el(env) ==
> arm_current_pl(env));
> > +            bool same_el = (arm_debug_target_el(env) ==
> arm_current_el(env));
> >              env->exception.syndrome = syn_breakpoint(same_el);
> >              if (extended_addresses_enabled(env)) {
> >                  env->exception.fsr = (1 << 9) | 0x22;
> > diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> > index 35ae3ea..f53dc0f 100644
> > --- a/target-arm/translate-a64.c
> > +++ b/target-arm/translate-a64.c
> > @@ -10930,7 +10930,7 @@ void gen_intermediate_code_internal_a64(ARMCPU
> *cpu,
> >      dc->vec_len = 0;
> >      dc->vec_stride = 0;
> >      dc->cp_regs = cpu->cp_regs;
> > -    dc->current_pl = arm_current_pl(env);
> > +    dc->current_pl = arm_current_el(env);
> >      dc->features = env->features;
> >
> >      /* Single step state. The code-generation logic here is:
> > diff --git a/target-arm/translate.c b/target-arm/translate.c
> > index 8a2994f..f6404be 100644
> > --- a/target-arm/translate.c
> > +++ b/target-arm/translate.c
> > @@ -10945,7 +10945,7 @@ static inline void
> gen_intermediate_code_internal(ARMCPU *cpu,
> >      dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
> >      dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
> >      dc->cp_regs = cpu->cp_regs;
> > -    dc->current_pl = arm_current_pl(env);
> > +    dc->current_pl = arm_current_el(env);
>
> Should we rename dc->current_pl aswell?
> This might turn into a patch that is hard to maintain while the series
> gets reviewed. Maybe this change to be done earlier and hopefully get
> merged early to avoid some pain on your side....
>
> Cheers,
> Edgar
>
>

[-- Attachment #2: Type: text/html, Size: 19520 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 22/33] target-arm: add TCR_EL3 and make TTBCR banked
  2014-09-30 23:18   ` Edgar E. Iglesias
@ 2014-10-01 13:05     ` Greg Bellows
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-10-01 13:05 UTC (permalink / raw)
  To: Edgar E. Iglesias
  Cc: Peter Maydell, QEMU Developers, Fabian Aggeler, Sergey Fedorov

[-- Attachment #1: Type: text/plain, Size: 8291 bytes --]

Thanks Edgar.

I'm okay with array notation (I think we agreed to that) as long as we are
okay with the extra padding which should be minor.

I will update the few fields that can and should be arrays.

Greg

On 30 September 2014 18:18, Edgar E. Iglesias <edgar.iglesias@gmail.com>
wrote:

> On Tue, Sep 30, 2014 at 04:49:34PM -0500, Greg Bellows wrote:
> > From: Fabian Aggeler <aggelerf@ethz.ch>
> >
> > Adds TCR_EL3 system register and makes existing TTBCR banked. Adjust
> > translation functions to use TCR/TTBCR instance depending on CPU state.
> >
> > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> >
> > ----------
> > v4 -> v5
> > - Changed c2_mask updates to use the TTBCR cpreg bank flag for selcting
> the
> >   secure bank instead of the A32_BANKED_CURRENT macro.  This more
> accurately
> >   chooses the correct bank matching that of the TTBCR being accessed.
> > ---
> >  target-arm/cpu.h       | 11 ++++++++++-
> >  target-arm/helper.c    | 48
> +++++++++++++++++++++++++++++++++++-------------
> >  target-arm/internals.h |  2 +-
> >  3 files changed, 46 insertions(+), 15 deletions(-)
> >
> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > index c99158e..477c219 100644
> > --- a/target-arm/cpu.h
> > +++ b/target-arm/cpu.h
> > @@ -221,7 +221,16 @@ typedef struct CPUARMState {
> >                  uint64_t ttbr1_el1;
> >              };
> >          };
> > -        uint64_t c2_control; /* MMU translation table base control.  */
> > +        union { /* MMU translation table base control. */
> > +            struct {
> > +                uint64_t ttbcr_ns;
> > +                uint64_t ttbcr_s;
> > +            };
> > +            struct {
> > +                uint64_t tcr_el1;
> > +                uint64_t tcr_el3;
> > +            };
> > +        };
>
> I was hoping that the aarch64 regs would be arrays (e.g tcr_el[4])...
>
>
>
>
>
> >          uint32_t c2_mask; /* MMU translation table base selection
> mask.  */
> >          uint32_t c2_base_mask; /* MMU translation table base 0 mask. */
> >          uint32_t c2_data; /* MPU data cachable bits.  */
> > diff --git a/target-arm/helper.c b/target-arm/helper.c
> > index 2a6a129..bdb76e0 100644
> > --- a/target-arm/helper.c
> > +++ b/target-arm/helper.c
> > @@ -1678,11 +1678,12 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
> >        .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
> >        .access = PL1_RW, .writefn = vmsa_tcr_el1_write,
> >        .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
> > -      .fieldoffset = offsetof(CPUARMState, cp15.c2_control) },
> > +      .fieldoffset = offsetof(CPUARMState, cp15.tcr_el1) },
> >      { .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 =
> 2,
> >        .access = PL1_RW, .type = ARM_CP_NO_MIGRATE, .writefn =
> vmsa_ttbcr_write,
> >        .resetfn = arm_cp_reset_ignore, .raw_writefn =
> vmsa_ttbcr_raw_write,
> > -      .fieldoffset = offsetoflow32(CPUARMState, cp15.c2_control) },
> > +      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.ttbcr_s),
> > +                             offsetoflow32(CPUARMState, cp15.ttbcr_ns)
> } },
> >      /* 64-bit FAR; this entry also gives us the AArch32 DFAR */
> >      { .name = "FAR_EL1", .state = ARM_CP_STATE_BOTH,
> >        .opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
> > @@ -2421,6 +2422,11 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
> >        .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 6, .opc2 = 0,
> >        .access = PL3_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
> >        .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el3) },
> > +    { .name = "TCR_EL3", .state = ARM_CP_STATE_AA64,
> > +      .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 6, .opc2 = 2,
> > +      .access = PL3_RW, .writefn = vmsa_tcr_el1_write,
> > +      .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
> > +      .fieldoffset = offsetof(CPUARMState, cp15.tcr_el3) },
> >      { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
> >        .type = ARM_CP_NO_MIGRATE,
> >        .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1,
> > @@ -4515,13 +4521,13 @@ static bool get_level1_table_address(CPUARMState
> *env, uint32_t *table,
> >       * table registers.
> >       */
> >      if (address & env->cp15.c2_mask) {
> > -        if ((env->cp15.c2_control & TTBCR_PD1)) {
> > +        if (A32_BANKED_CURRENT_REG_GET(env, ttbcr) & TTBCR_PD1) {
> >              /* Translation table walk disabled for TTBR1 */
> >              return false;
> >          }
> >          *table = A32_BANKED_CURRENT_REG_GET(env, ttbr1) & 0xffffc000;
> >      } else {
> > -        if ((env->cp15.c2_control & TTBCR_PD0)) {
> > +        if (A32_BANKED_CURRENT_REG_GET(env, ttbcr) & TTBCR_PD0) {
> >              /* Translation table walk disabled for TTBR0 */
> >              return false;
> >          }
> > @@ -4781,13 +4787,29 @@ static int get_phys_addr_lpae(CPUARMState *env,
> target_ulong address,
> >      int32_t va_size = 32;
> >      int32_t tbi = 0;
> >      uint32_t cur_el = arm_current_el(env);
> > +    uint64_t tcr;
> >
> > -    if (arm_el_is_aa64(env, 1)) {
> > +    if (arm_el_is_aa64(env, 3)) {
> > +        switch (cur_el) {
> > +        case 3:
> > +            tcr = env->cp15.tcr_el3;
> > +            break;
> > +        case 1:
> > +        case 0:
> > +        default:
> > +            tcr = env->cp15.tcr_el1;
> > +        }
> > +
> > +    } else {
> > +        tcr = A32_BANKED_CURRENT_REG_GET(env, ttbcr);
> > +    }
> > +
> > +    if (arm_el_is_aa64(env, 1) && (cur_el == 0 || cur_el == 1)) {
> >          va_size = 64;
> >          if (extract64(address, 55, 1))
> > -            tbi = extract64(env->cp15.c2_control, 38, 1);
> > +            tbi = extract64(tcr, 38, 1);
> >          else
> > -            tbi = extract64(env->cp15.c2_control, 37, 1);
> > +            tbi = extract64(tcr, 37, 1);
> >          tbi *= 8;
> >      }
> >
> > @@ -4796,12 +4818,12 @@ static int get_phys_addr_lpae(CPUARMState *env,
> target_ulong address,
> >       * This is a Non-secure PL0/1 stage 1 translation, so controlled by
> >       * TTBCR/TTBR0/TTBR1 in accordance with ARM ARM DDI0406C table B-32:
> >       */
> > -    uint32_t t0sz = extract32(env->cp15.c2_control, 0, 6);
> > +    uint32_t t0sz = extract32(tcr, 0, 6);
> >      if (arm_el_is_aa64(env, 1)) {
> >          t0sz = MIN(t0sz, 39);
> >          t0sz = MAX(t0sz, 16);
> >      }
> > -    uint32_t t1sz = extract32(env->cp15.c2_control, 16, 6);
> > +    uint32_t t1sz = extract32(tcr, 16, 6);
> >      if (arm_el_is_aa64(env, 1)) {
> >          t1sz = MIN(t1sz, 39);
> >          t1sz = MAX(t1sz, 16);
> > @@ -4845,10 +4867,10 @@ static int get_phys_addr_lpae(CPUARMState *env,
> target_ulong address,
> >          } else {
> >              ttbr = A32_BANKED_CURRENT_REG_GET(env, ttbr0);
> >          }
> > -        epd = extract32(env->cp15.c2_control, 7, 1);
> > +        epd = extract32(tcr, 7, 1);
> >          tsz = t0sz;
> >
> > -        tg = extract32(env->cp15.c2_control, 14, 2);
> > +        tg = extract32(tcr, 14, 2);
> >          if (tg == 1) { /* 64KB pages */
> >              granule_sz = 13;
> >          }
> > @@ -4857,10 +4879,10 @@ static int get_phys_addr_lpae(CPUARMState *env,
> target_ulong address,
> >          }
> >      } else {
> >          ttbr = A32_BANKED_CURRENT_REG_GET(env, ttbr1);
> > -        epd = extract32(env->cp15.c2_control, 23, 1);
> > +        epd = extract32(tcr, 23, 1);
> >          tsz = t1sz;
> >
> > -        tg = extract32(env->cp15.c2_control, 30, 2);
> > +        tg = extract32(tcr, 30, 2);
> >          if (tg == 3)  { /* 64KB pages */
> >              granule_sz = 13;
> >          }
> > diff --git a/target-arm/internals.h b/target-arm/internals.h
> > index 43a2e7d..dba7766 100644
> > --- a/target-arm/internals.h
> > +++ b/target-arm/internals.h
> > @@ -155,7 +155,7 @@ static inline bool
> extended_addresses_enabled(CPUARMState *env)
> >  {
> >      return arm_el_is_aa64(env, 1)
> >          || ((arm_feature(env, ARM_FEATURE_LPAE)
> > -             && (env->cp15.c2_control & TTBCR_EAE)));
> > +             && (A32_BANKED_CURRENT_REG_GET(env, ttbcr) & TTBCR_EAE)));
> >  }
> >
> >  /* Valid Syndrome Register EC field values */
> > --
> > 1.8.3.2
> >
>

[-- Attachment #2: Type: text/html, Size: 10701 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 31/33] target-arm: make c13 cp regs banked (FCSEIDR, ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 31/33] target-arm: make c13 cp regs banked (FCSEIDR, ...) Greg Bellows
@ 2014-10-01 14:30   ` Greg Bellows
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-10-01 14:30 UTC (permalink / raw)
  To: QEMU Developers, Peter Maydell, Sergey Fedorov,
	Edgar E. Iglesias, Fabian Aggeler
  Cc: Greg Bellows

[-- Attachment #1: Type: text/plain, Size: 6940 bytes --]

I have fixed-up some of the bank definitions and names so they more
accurately match the ARMv8 mappings.  In next version.

On 30 September 2014 16:49, Greg Bellows <greg.bellows@linaro.org> wrote:

> From: Fabian Aggeler <aggelerf@ethz.ch>
>
> When EL3 is running in Aarch32 (or ARMv7 with Security Extensions)
> FCSEIDR, CONTEXTIDR, TPIDRURW, TPIDRURO and TPIDRPRW have a secure
> and a non-secure instance.
>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
>
> --------------
> v3 -> v4
> - Fix tpidrprw mapping
> ---
>  target-arm/cpu.h    | 45 ++++++++++++++++++++++++++++++++++++++++-----
>  target-arm/helper.c | 36 ++++++++++++++++++++++++------------
>  2 files changed, 64 insertions(+), 17 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 7a8eaef..7d27c69 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -322,11 +322,46 @@ typedef struct CPUARMState {
>              uint64_t vbar_el[4];
>          };
>          uint64_t mvbar; /* (monitor) vector base address register */
> -        uint32_t c13_fcse; /* FCSE PID.  */
> -        uint64_t contextidr_el1; /* Context ID.  */
> -        uint64_t tpidr_el0; /* User RW Thread register.  */
> -        uint64_t tpidrro_el0; /* User RO Thread register.  */
> -        uint64_t tpidr_el1; /* Privileged Thread register.  */
> +        struct { /* FCSE PID. */
> +            uint32_t c13_fcseidr_ns;
> +            uint32_t c13_fcseidr_s;
> +        };
> +        union { /* Context ID. */
> +            struct {
> +                uint64_t contextidr_ns;
> +                uint64_t contextidr_s;
> +            };
> +            struct {
> +                uint64_t contextidr_el1;
> +            };
> +        };
> +        union { /* User RW Thread register. */
> +            struct {
> +                uint64_t tpidrurw_ns;
> +                uint64_t tpidrurw_s;
> +            };
> +            struct {
> +                uint64_t tpidr_el0;
> +            };
> +        };
> +        union { /* User RO Thread register. */
> +            struct {
> +                uint64_t tpidruro_ns;
> +                uint64_t tpidruro_s;
> +            };
> +            struct {
> +                uint64_t tpidrro_el0;
> +            };
> +        };
> +        union { /* Privileged Thread register. */
> +            struct {
> +                uint64_t tpidrprw_ns;
> +                uint64_t tpidrprw_s;
> +            };
> +            struct {
> +                uint64_t tpidr_el1;
> +            };
> +        };
>          uint64_t c14_cntfrq; /* Counter Frequency register */
>          uint64_t c14_cntkctl; /* Timer Control register */
>          ARMGenericTimer c14_timer[NUM_GTIMERS];
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index e91a019..8d9563f 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -420,12 +420,15 @@ static void tlbimvaa_is_write(CPUARMState *env,
> const ARMCPRegInfo *ri,
>
>  static const ARMCPRegInfo cp_reginfo[] = {
>      { .name = "FCSEIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2
> = 0,
> -      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState,
> cp15.c13_fcse),
> +      .access = PL1_RW,
> +      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.c13_fcseidr_s),
> +                             offsetof(CPUARMState, cp15.c13_fcseidr_ns) },
>        .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
> -    { .name = "CONTEXTIDR", .state = ARM_CP_STATE_BOTH,
> -      .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
> +    { .name = "CONTEXTIDR",
> +      .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
>        .access = PL1_RW,
> -      .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el1),
> +      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.contextidr_s),
> +                             offsetof(CPUARMState, cp15.contextidr_ns) },
>        .resetvalue = 0, .writefn = contextidr_write, .raw_writefn =
> raw_write, },
>      REGINFO_SENTINEL
>  };
> @@ -1042,21 +1045,25 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
>        .access = PL0_RW,
>        .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el0), .resetvalue =
> 0 },
>      { .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2
> = 2,
> -      .access = PL0_RW,
> -      .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidr_el0),
> -      .resetfn = arm_cp_reset_ignore },
> +      .access = PL0_RW, .resetvalue = 0,
> +      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrurw_s),
> +                             offsetoflow32(CPUARMState, cp15.tpidrurw_ns)
> } },
>      { .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0,
>        .access = PL0_R|PL1_W,
>        .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el0), .resetvalue
> = 0 },
>      { .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2
> = 3,
> -      .access = PL0_R|PL1_W,
> -      .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidrro_el0),
> -      .resetfn = arm_cp_reset_ignore },
> -    { .name = "TPIDR_EL1", .state = ARM_CP_STATE_BOTH,
> +      .access = PL0_R|PL1_W, .resetvalue = 0,
> +      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s),
> +                             offsetoflow32(CPUARMState, cp15.tpidruro_ns)
> } },
> +    { .name = "TPIDR_EL1", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .opc1 = 0, .opc2 = 4, .crn = 13, .crm = 0,
>        .access = PL1_RW,
>        .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el1), .resetvalue =
> 0 },
> +    { .name = "TPIDRPRW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2
> = 4,
> +      .access = PL1_RW, .resetvalue = 0,
> +      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrprw_s),
> +                             offsetoflow32(CPUARMState, cp15.tpidrprw_ns)
> } },
>      REGINFO_SENTINEL
>  };
>
> @@ -2324,6 +2331,11 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
>        .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
>        .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0,
>        .fieldoffset = offsetof(CPUARMState, cp15.csselr_el1) },
> +    { .name = "CONTEXTIDR_EL1", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
> +      .access = PL1_RW,
> +      .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el1),
> +      .resetvalue = 0, .writefn = contextidr_write, .raw_writefn =
> raw_write },
>      REGINFO_SENTINEL
>  };
>
> @@ -5132,7 +5144,7 @@ static inline int get_phys_addr(CPUARMState *env,
> target_ulong address,
>
>      /* Fast Context Switch Extension.  */
>      if (address < 0x02000000)
> -        address += env->cp15.c13_fcse;
> +        address += A32_BANKED_CURRENT_REG_GET(env, c13_fcseidr);
>
>      if ((sctlr & SCTLR_M) == 0) {
>          /* MMU/MPU disabled.  */
> --
> 1.8.3.2
>
>

[-- Attachment #2: Type: text/html, Size: 8555 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 05/33] target-arm: make arm_current_pl() return PL3
  2014-10-01  1:23   ` Sergey Fedorov
@ 2014-10-01 14:31     ` Greg Bellows
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-10-01 14:31 UTC (permalink / raw)
  To: Sergey Fedorov
  Cc: Peter Maydell, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

[-- Attachment #1: Type: text/plain, Size: 590 bytes --]

Yes, good catch.  Fixed in next version.

On 30 September 2014 20:23, Sergey Fedorov <serge.fdrv@gmail.com> wrote:

> On 30.09.2014 14:49, Greg Bellows wrote:
> > From: Fabian Aggeler <aggelerf@ethz.ch>
> >
> > Make arm_current_pl() return PL3 for secure PL1 and monitor mode.
> > Increase MMU modes since mmu_index is directly infered from arm_
> > current_pl(). Changes assertion in arm_el_is_aa64() to allow EL3.
>
> arm_current_pl() is renamed in previous patch :)
>
> >
> > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
>
>

[-- Attachment #2: Type: text/html, Size: 1159 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 01/33] target-arm: increase arrays of registers R13 & R14
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 01/33] target-arm: increase arrays of registers R13 & R14 Greg Bellows
@ 2014-10-06 14:48   ` Peter Maydell
  2014-10-06 19:21   ` Greg Bellows
  1 sibling, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 14:48 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> From: Fabian Aggeler <aggelerf@ethz.ch>
>
> Increasing banked_r13 and banked_r14 to store LR_mon and SP_mon (bank
> index 7).
>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> ---
>  target-arm/cpu.h     | 4 ++--
>  target-arm/machine.c | 4 ++--
>  2 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 65a3417..81fffd2 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -153,8 +153,8 @@ typedef struct CPUARMState {
>
>      /* Banked registers.  */
>      uint64_t banked_spsr[8];
> -    uint32_t banked_r13[6];
> -    uint32_t banked_r14[6];
> +    uint32_t banked_r13[8];
> +    uint32_t banked_r14[8];
>
>      /* These hold r8-r12.  */
>      uint32_t usr_regs[5];
> diff --git a/target-arm/machine.c b/target-arm/machine.c
> index ddb7d05..7e69127 100644
> --- a/target-arm/machine.c
> +++ b/target-arm/machine.c
> @@ -238,8 +238,8 @@ const VMStateDescription vmstate_arm_cpu = {
>          },
>          VMSTATE_UINT32(env.spsr, ARMCPU),
>          VMSTATE_UINT64_ARRAY(env.banked_spsr, ARMCPU, 8),
> -        VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 6),
> -        VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 6),
> +        VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 8),
> +        VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 8),
>          VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5),
>          VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5),
>          VMSTATE_UINT64_ARRAY(env.elr_el, ARMCPU, 4),

You need to bump the vmstate version fields if
you change fields like this.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function Greg Bellows
  2014-09-30 22:50   ` Edgar E. Iglesias
@ 2014-10-06 14:56   ` Peter Maydell
  2014-10-06 17:57     ` Sergey Fedorov
  2014-10-06 19:45     ` Greg Bellows
  1 sibling, 2 replies; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 14:56 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, Sergey Fedorov, QEMU Developers, Fabian Aggeler,
	Edgar E. Iglesias

On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> From: Fabian Aggeler <aggelerf@ethz.ch>
>
> arm_is_secure() function allows to determine CPU security state
> if the CPU implements Security Extensions/EL3.
> arm_is_secure_below_el3() returns true if CPU is in secure state
> below EL3.
>
> 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>
> ---
>  target-arm/cpu.h | 38 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 81fffd2..10afef0 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -753,6 +753,44 @@ static inline int arm_feature(CPUARMState *env, int feature)
>      return (env->features & (1ULL << feature)) != 0;
>  }
>
> +
> +/* Return true if exception level below EL3 is in secure state */
> +static inline bool arm_is_secure_below_el3(CPUARMState *env)
> +{
> +#if !defined(CONFIG_USER_ONLY)
> +    if (arm_feature(env, ARM_FEATURE_EL3)) {
> +        return !(env->cp15.scr_el3 & SCR_NS);
> +    } else if (arm_feature(env, ARM_FEATURE_EL2)) {
> +        return false;
> +    } else {
> +        /* IMPDEF: QEMU defaults to non-secure */
> +        return false;

I would be happy to fold both these identical 'return false'
cases together and have a comment that it's only IMPDEF
if EL2 isn't implemented.

> +    }
> +#else
> +    return false;
> +#endif
> +}
> +
> +/* Return true if the processor is in secure state */
> +static inline bool arm_is_secure(CPUARMState *env)
> +{
> +#if !defined(CONFIG_USER_ONLY)
> +    if (arm_feature(env, ARM_FEATURE_EL3)) {
> +        if (env->aarch64 && extract32(env->pstate, 2, 2) == 3) {
> +            /* CPU currently in Aarch64 state and EL3 */

Nit: "AArch64" with two capital 'A's (here and elsewhere).

> +            return true;
> +        } else if (!env->aarch64 &&
> +                (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
> +            /* CPU currently in Aarch32 state and monitor mode */
> +            return true;
> +        }
> +    }
> +    return arm_is_secure_below_el3(env);
> +#else
> +    return false;
> +#endif
> +}

I checked your git tree and we don't actually use
arm_is_secure_below_el3() anywhere except in
arm_is_secure(), do we? That suggests to me we should
just fold the two functions together.

Can these functions live in internals.h rather than cpu.h?
(The difference is that internals.h is restricted to only
target-arm/ code whereas cpu.h is auto-included for a much
wider set of files.)

thanks
-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/33] target-arm: reject switching to monitor mode
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 03/33] target-arm: reject switching to monitor mode Greg Bellows
@ 2014-10-06 15:02   ` Peter Maydell
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 15:02 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> From: Sergey Fedorov <s.fedorov@samsung.com>
>
> ...from non-secure state.
>
> Signed-off-by: Sergey Fedorov <s.fedorov@samsung.com>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

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

though as a style nit I would prefer the commit to
read:

===
Subject: target-arm: reject switching to monitor mode if NS

Reject switching to monitor mode from non-secure state.
===

since the oneline summary should stand on its own.

PS: please drop Sergey's now-bouncing Samsung address
from the CC list when you send v6 of this series :-)


> ---
>  target-arm/helper.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 2669e15..d6e3b52 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -3531,6 +3531,8 @@ static int bad_mode_switch(CPUARMState *env, int mode)
>      case ARM_CPU_MODE_IRQ:
>      case ARM_CPU_MODE_FIQ:
>          return 0;
> +    case ARM_CPU_MODE_MON:
> +        return !arm_is_secure(env);
>      default:
>          return 1;
>      }
> --
> 1.8.3.2

thanks
-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 04/33] target-arm: rename arm_current_pl to arm_current_el
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 04/33] target-arm: rename arm_current_pl to arm_current_el Greg Bellows
  2014-09-30 22:56   ` Edgar E. Iglesias
@ 2014-10-06 15:10   ` Peter Maydell
  2014-10-06 19:55     ` Greg Bellows
  1 sibling, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 15:10 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> Renamed the arm_current_pl CPU function to more accurately represent that it
> returns the ARMv8 EL rather than ARMv7 PL.
>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> ---
>  target-arm/cpu.h           | 18 +++++++++---------
>  target-arm/helper-a64.c    |  6 +++---
>  target-arm/helper.c        | 22 +++++++++++-----------
>  target-arm/internals.h     |  2 +-
>  target-arm/op_helper.c     | 16 ++++++++--------
>  target-arm/translate-a64.c |  2 +-
>  target-arm/translate.c     |  2 +-
>  7 files changed, 34 insertions(+), 34 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 10afef0..101d139 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -982,7 +982,7 @@ static inline bool cptype_valid(int cptype)
>  #define PL1_RW (PL1_R | PL1_W)
>  #define PL0_RW (PL0_R | PL0_W)
>
> -static inline int arm_current_pl(CPUARMState *env)
> +static inline int arm_current_el(CPUARMState *env)

I suggest we add a brief comment before the function:
/* Return the current Exception Level (as per ARMv8;
 * note that this differs from the ARMv7 Privilege Level).
 */

You should also fix the "PL2" and "PL3" references in
the comments to read "EL2" and "EL3".

thanks
-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 05/33] target-arm: make arm_current_pl() return PL3
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 05/33] target-arm: make arm_current_pl() return PL3 Greg Bellows
  2014-10-01  1:23   ` Sergey Fedorov
@ 2014-10-06 15:34   ` Peter Maydell
  2014-10-06 20:53     ` Greg Bellows
  1 sibling, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 15:34 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> From: Fabian Aggeler <aggelerf@ethz.ch>
>
> Make arm_current_pl() return PL3 for secure PL1 and monitor mode.
> Increase MMU modes since mmu_index is directly infered from arm_
> current_pl(). Changes assertion in arm_el_is_aa64() to allow EL3.
>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> ---
>  target-arm/cpu.h | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 101d139..c000716 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -100,7 +100,7 @@ typedef uint32_t ARMReadCPFunc(void *opaque, int cp_info,
>
>  struct arm_boot_info;
>
> -#define NB_MMU_MODES 2
> +#define NB_MMU_MODES 4
>
>  /* We currently assume float and double are IEEE single and double
>     precision respectively.
> @@ -753,7 +753,6 @@ static inline int arm_feature(CPUARMState *env, int feature)
>      return (env->features & (1ULL << feature)) != 0;
>  }
>
> -

Stray whitespace change.

>  /* Return true if exception level below EL3 is in secure state */
>  static inline bool arm_is_secure_below_el3(CPUARMState *env)
>  {
> @@ -794,11 +793,12 @@ static inline bool arm_is_secure(CPUARMState *env)
>  /* Return true if the specified exception level is running in AArch64 state. */
>  static inline bool arm_el_is_aa64(CPUARMState *env, int el)
>  {
> -    /* We don't currently support EL2 or EL3, and this isn't valid for EL0
> +    /* We don't currently support EL2, and this isn't valid for EL0
>       * (if we're in EL0, is_a64() is what you want, and if we're not in EL0
>       * then the state of EL0 isn't well defined.)
>       */
> -    assert(el == 1);
> +    assert(el == 1 || el == 3);
> +
>      /* AArch64-capable CPUs always run with EL1 in AArch64 mode. This
>       * is a QEMU-imposed simplification which we may wish to change later.
>       * If we in future support EL2 and/or EL3, then the state of lower

> @@ -990,9 +990,12 @@ static inline int arm_current_el(CPUARMState *env)
>
>      if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR) {
>          return 0;
> +    } else if (arm_is_secure(env)) {
> +        /* Secure PL1 and monitor mode are mapped to PL3 */
> +        return 3;

This isn't correct. Secure privileged !Mon AArch32 modes are only
EL3 if EL3 is AArch32. If EL3 is AArch64 then the !Mon AArch32
modes are EL1.

>      }
> -    /* We don't currently implement the Virtualization or TrustZone
> -     * extensions, so PL2 and PL3 don't exist for us.
> +    /* We currently do not implement the Virtualization extensions, so PL2 does
> +     * not exist for us.
>       */
>      return 1;

Now that we've added the complications for handling secure mode,
we might as well also have the trivial code for Hyp too. So
that means the function looks something like:

    if (env->aarch64) {
        return extract32(env->pstate, 2, 2);
    }

    switch (env->uncached_cpsr & CPSR_M) {
    case ARM_CPU_MODE_USR:
        return 0;
    case ARM_CPU_MODE_HYP:
        return 2;
    case ARM_CPU_MODE_MON:
        return 3;
    default:
        if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
            /* If EL3 is 32-bit then all secure privileged modes run in EL3 */
            return 3;
        }
        return 1;
    }

thanks
-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 06/33] target-arm: A32: Emulate the SMC instruction
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 06/33] target-arm: A32: Emulate the SMC instruction Greg Bellows
@ 2014-10-06 15:46   ` Peter Maydell
  2014-10-07  1:56     ` Greg Bellows
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 15:46 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, Sergey Fedorov, QEMU Developers, Fabian Aggeler,
	Edgar E. Iglesias

On 30 September 2014 22:49, 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>
>
> ----------
> v4 -> v5
> - Merge pre_smc upstream changes and incorporated ss_advance
> ---
>  target-arm/helper.c    | 11 +++++++++++
>  target-arm/internals.h |  7 ++++++-
>  target-arm/op_helper.c |  3 +--
>  target-arm/translate.c | 39 +++++++++++++++++++++++++++++----------
>  4 files changed, 47 insertions(+), 13 deletions(-)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 2381e6f..7f3f049 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -4090,6 +4090,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.  */
> @@ -4108,6 +4114,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/internals.h b/target-arm/internals.h
> index fd69a83..43a2e7d 100644
> --- a/target-arm/internals.h
> +++ b/target-arm/internals.h
> @@ -236,7 +236,12 @@ static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_thumb)
>          | (is_thumb ? 0 : ARM_EL_IL);
>  }
>
> -static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
> +static inline uint32_t syn_aa32_smc(void)
> +{
> +    return (EC_AA32_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL;
> +}
> +
> +static inline uint32_t syn_aa64_bkpt(uint16_t imm16)

Bogus change (probably introduced by accident in a merge
conflict fixup).

>  {
>      return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
>  }
> diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
> index 0809d63..8ed8ee9 100644
> --- a/target-arm/op_helper.c
> +++ b/target-arm/op_helper.c
> @@ -419,8 +419,7 @@ void HELPER(pre_hvc)(CPUARMState *env)
>  void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
>  {
>      int cur_el = arm_current_el(env);
> -    /* FIXME: Use real secure state.  */
> -    bool secure = false;
> +    bool secure = arm_is_secure(env);;

Doubled semicolon.

>      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.
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index f6404be..3f3ddfb 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -7872,15 +7872,27 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
>          case 7:
>          {
>              int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
> -            /* SMC instruction (op1 == 3)
> -               and undefined instructions (op1 == 0 || op1 == 2)
> -               will trap */
> -            if (op1 != 1) {
> +            if (op1 == 1) {
> +                /* bkpt */
> +                ARCH(5);
> +                gen_exception_insn(s, 4, EXCP_BKPT,
> +                        syn_aa32_bkpt(imm16, false));
> +            } else if (op1 == 3) {
> +                /* smi/smc */
> +                if (!arm_dc_feature(s, ARM_FEATURE_EL3) ||
> +                        s->current_pl == 0) {
> +                    goto illegal_op;
> +                }
> +                gen_set_pc_im(s, s->pc);

This should be s->pc - 4, because if the pre_smc helper throws
an UNDEF exception you want the PC to point to the SMC insn,
not the insn after. (If the SMC executes as an SMC then the
PC for the EXCP_SMC will be correct because of the 0 offset
passed to gen_exception_insn below.)

> +                tmp = tcg_const_i32(syn_aa32_smc());
> +                gen_helper_pre_smc(cpu_env, tmp);
> +                tcg_temp_free_i32(tmp);
> +                gen_ss_advance(s);
> +                gen_exception_insn(s, 0, EXCP_SMC, syn_aa32_smc());
> +                break;
> +            } else {
>                  goto illegal_op;
>              }

That said, I have a feeling we might want to put the SMC
handling into the end-of-loop processing for A32/T32,
the same way we do SVC. Ard has a patch onlist which does
that, though it is on my todo list to try to fix because
it has its own issues...

-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 07/33] target-arm: extend async excp masking
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 07/33] target-arm: extend async excp masking Greg Bellows
@ 2014-10-06 15:53   ` Peter Maydell
  2014-10-07  3:16     ` Greg Bellows
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 15:53 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> From: Fabian Aggeler <aggelerf@ethz.ch>
>
> This patch extends arm_excp_unmasked() according to ARM ARMv7 and
> ARM ARMv8 (all EL running in Aarch32) and adds comments.

"AA" (just do a search and replace through the whole patchset,
please.)

>
> If EL3 is using Aarch64 IRQ/FIQ masking is ignored in
> all exception levels other than EL3 if SCR.{FIQ|IRQ} is
> set to 1 (routed to EL3).
>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
>
> ----------
> v4 -> v5
> - Merge with v4 patch 10
> ---
>  target-arm/cpu.h | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 106 insertions(+), 10 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index c000716..30f57fd 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -1226,11 +1226,8 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
>  {
>      CPUARMState *env = cs->env_ptr;
>      unsigned int cur_el = arm_current_el(env);
> -    unsigned int target_el = arm_excp_target_el(cs, excp_idx);
> -    /* FIXME: Use actual secure state.  */
> -    bool secure = false;
> -    /* If in EL1/0, Physical IRQ routing to EL2 only happens from NS state.  */
> -    bool irq_can_hyp = !secure && cur_el < 2 && target_el == 2;
> +    bool secure = arm_is_secure(env);
> +
>      /* ARMv7-M interrupt return works by loading a magic value
>       * into the PC.  On real hardware the load causes the
>       * return to occur.  The qemu implementation performs the
> @@ -1245,19 +1242,118 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
>                          && (!IS_M(env) || env->regs[15] < 0xfffffff0);
>
>      /* Don't take exceptions if they target a lower EL.  */
> -    if (cur_el > target_el) {
> +    if (cur_el > arm_excp_target_el(cs, excp_idx)) {
>          return false;
>      }
>
> +    /* ARM ARMv7 B1.8.6  Asynchronous exception masking (table B1-12/B1-13)
> +     * ARM ARMv8 G1.11.3 Asynchronous exception masking controls
> +     * (table G1-18/G1-19) */

"*/" goes on its own line.

>      switch (excp_idx) {
>      case EXCP_FIQ:
> -        if (irq_can_hyp && (env->cp15.hcr_el2 & HCR_FMO)) {
> -            return true;
> +        if (arm_feature(env, ARM_FEATURE_EL3) && arm_el_is_aa64(env, 3)) {
> +            /* If EL3 is using Aarch64 and FIQs are routed to EL3 masking is
> +             * ignored in all exception levels except EL3.
> +             */
> +            if ((env->cp15.scr_el3 & SCR_FIQ) && cur_el < 3) {
> +                return true;
> +            }
> +            /* If we are in EL3 but FIQs are not routed to EL3 the exception
> +             * is not taken but remains pending.
> +             */
> +            if (!(env->cp15.scr_el3 & SCR_FIQ) && cur_el == 3) {
> +                return false;
> +            }
> +        }

This is all kind of confusing. What is the division of work
between this function and arm_phys_excp_target_el(),
conceptually? Why isn't "we're in EL3 but FIQs aren't going
to EL3" handled by the "cur_el > arm_excp_target_el()" check
above, for instance?

thanks
-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 08/33] target-arm: add async excp target_el function
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 08/33] target-arm: add async excp target_el function Greg Bellows
@ 2014-10-06 16:02   ` Peter Maydell
  2014-10-07  3:52     ` Greg Bellows
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 16:02 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> From: Fabian Aggeler <aggelerf@ethz.ch>
>
> Adds a dedicated function for IRQ and FIQ exceptions to determine
> target_el and mode (Aarch32) according to tables in ARM ARMv8 and
> ARM ARM v7.
>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
>
> ----------
> v4 -> v5
> - Simplify target EL function including removal of mode which was unused
> - Merged with patch that plugs in the use of the function
>
> v3 -> v4
> - Fixed arm_phys_excp_target_el() 0/0/0 case to return excp_mode when EL<2
>   rather than ABORT.
> ---
>  target-arm/cpu.h    |   2 +
>  target-arm/helper.c | 103 ++++++++++++++++++++++++++++++++++++++++++----------
>  2 files changed, 85 insertions(+), 20 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 30f57fd..601f8fe 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -809,6 +809,8 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
>
>  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 excp_idx,
> +                                        uint32_t cur_el, bool secure);

This is only used in helper.c which is also the place where it
is defined, so why are we making it a global function with
a prototype here rather than having it be 'static'?

>
>  /* Interface between CPU and Interrupt controller.  */
>  void armv7m_nvic_set_pending(void *opaque, int irq);
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 7f3f049..a10f459 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -3706,6 +3706,12 @@ uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
>      return 0;
>  }
>
> +inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
> +                                        uint32_t cur_el, bool secure)
> +{
> +    return 1;
> +}
> +

This version is never used, so I think it can be deleted?

>  unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
>  {
>      return 1;
> @@ -3767,6 +3773,80 @@ void switch_mode(CPUARMState *env, int mode)
>  }
>
>  /*
> + * Determine the target EL for physical exceptions

What's a "physical exception" ?

> + */
> +inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
> +                                        uint32_t cur_el, bool secure)
> +{
> +    CPUARMState *env = cs->env_ptr;
> +    uint32_t target_el = 1;
> +
> +    /* There is no SCR or HCR routing unless the respective EL3 and EL2
> +     * extensions are supported.  This initial setting affects whether any
> +     * other conditions matter.
> +     */
> +    bool scr_routing = arm_feature(env, ARM_FEATURE_EL3); /* IRQ, FIQ, EA */
> +    bool hcr_routing = arm_feature(env, ARM_FEATURE_EL2); /* IMO, FMO, AMO */
> +
> +    /* Fast-path if EL2 and EL3 are not enabled */
> +    if (!scr_routing && !hcr_routing) {
> +        return target_el;
> +    }
> +
> +    switch (excp_idx) {
> +    case EXCP_IRQ:
> +        scr_routing &= ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ);
> +        hcr_routing &= ((env->cp15.hcr_el2 & HCR_IMO) == HCR_IMO);
> +        break;
> +    case EXCP_FIQ:
> +        scr_routing &= ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ);
> +        hcr_routing &= ((env->cp15.hcr_el2 & HCR_FMO) == HCR_FMO);
> +    }
> +
> +    /* If SCR routing is enabled we always go to EL3 regardless of EL3
> +     * execution state
> +     */
> +    if (scr_routing) {
> +        /* IRQ|FIQ|EA == 1 */
> +        return 3;
> +    }
> +
> +    /* If HCR.TGE is set all exceptions that would be routed to EL1 are
> +     * routed to EL2 (in non-secure world).
> +     */
> +    hcr_routing &= (env->cp15.hcr_el2 & HCR_TGE) == HCR_TGE;
> +
> +    /* Determine target EL according to ARM ARMv8 tables G1-15 and G1-16 */
> +    if (arm_el_is_aa64(env, 3)) {
> +        /* EL3 in Aarch64 */
> +        if (!secure) {
> +            /* If non-secure, we may route to EL2 depending on other state.
> +             * If we are coming from the secure world then we always route to
> +             * EL1.
> +             */
> +            if (hcr_routing ||
> +                (cur_el == 2 && !(env->cp15.scr_el3 & SCR_RW))) {
> +                /* If HCR.FMO/IMO is set or we already in EL2 and it is not
> +                 * configured to be AArch64 then route to EL2.
> +                 */
> +                target_el = 2;
> +            }
> +        }
> +    } else {
> +        /* EL3 in Aarch32 */
> +        if (secure) {
> +            /* If coming from secure always route to EL3 */
> +            target_el = 3;
> +        } else if (hcr_routing || cur_el == 2) {
> +            /* If HCR.FMO/IMO is set or we are already EL2 then route to EL2 */
> +            target_el = 2;
> +        }
> +    }
> +
> +    return target_el;
> +}
> +
> +/*
>   * Determine the target EL for a given exception type.
>   */
>  unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
> @@ -3774,14 +3854,8 @@ unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
>      ARMCPU *cpu = ARM_CPU(cs);
>      CPUARMState *env = &cpu->env;
>      unsigned int cur_el = arm_current_el(env);
> -    unsigned int target_el;
> -    /* FIXME: Use actual secure state.  */
> -    bool secure = false;
> -
> -    if (!env->aarch64) {
> -        /* TODO: Add EL2 and 3 exception handling for AArch32.  */
> -        return 1;
> -    }
> +    unsigned int target_el = 1;
> +    bool secure = arm_is_secure(env);
>
>      switch (excp_idx) {
>      case EXCP_HVC:
> @@ -3793,19 +3867,8 @@ unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
>          break;
>      case EXCP_FIQ:
>      case EXCP_IRQ:
> -    {
> -        const uint64_t hcr_mask = excp_idx == EXCP_FIQ ? HCR_FMO : HCR_IMO;
> -        const uint32_t scr_mask = excp_idx == EXCP_FIQ ? SCR_FIQ : SCR_IRQ;
> -
> -        target_el = 1;
> -        if (!secure && (env->cp15.hcr_el2 & hcr_mask)) {
> -            target_el = 2;
> -        }
> -        if (env->cp15.scr_el3 & scr_mask) {
> -            target_el = 3;
> -        }
> +        target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure);
>          break;
> -    }
>      case EXCP_VIRQ:
>      case EXCP_VFIQ:
>          target_el = 1;
> --
> 1.8.3.2
>


thanks
-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 09/33] target-arm: add macros to access banked registers
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 09/33] target-arm: add macros to access banked registers Greg Bellows
@ 2014-10-06 16:09   ` Peter Maydell
  2014-10-07  4:02     ` Greg Bellows
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 16:09 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, Sergey Fedorov, QEMU Developers, Fabian Aggeler,
	Edgar E. Iglesias

On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> From: Fabian Aggeler <aggelerf@ethz.ch>
>
> 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.
>
> - A32_BANKED macros are used for choosing the banked register based on provided
>   input security argument.  This macro is used to choose the bank during
>   translation of MRC/MCR instructions that are dependent on something other
>   than the current secure state.
> - A32_BANKED_CURRENT macros are used for choosing the banked register based on
>   current secure state.  This is NOT to be used for choosing the bank used
>   during translation as it breaks monitor mode.
>
> 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.fedorov@samsung.com>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
>
> ----------
> v4 -> v5
> - Cleaned-up macros to try and alleviate misuse.  Made A32_BANKED macros take
>   secure arg indicator rather than relying on USE_SECURE_REG.  Incorporated the
>   A32_BANKED macros into the A32_BANKED_CURRENT.  CURRENT is now the only one
>   that automatically chooses based on current secure state.
> ---
>  target-arm/cpu.h | 36 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 601f8fe..c58fdf5 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -807,6 +807,42 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
>      return arm_feature(env, ARM_FEATURE_AARCH64);
>  }
>
> +/* Macro for determing whether to use the secure or non-secure bank of a CP
> + * register.  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))

Better to use an inline function for this rather than a macro,
I think.

> +
> +/* Macros for accessing a specified CP register bank */
> +#define A32_BANKED_REG_GET(_env, _regname, _secure)    \
> +    ((_secure) ? (_env)->cp15._regname##_s : (_env)->cp15._regname##_ns)
> +
> +#define A32_BANKED_REG_SET(_env, _regname, _secure, _val)   \
> +    do {                                                \
> +        if (_secure) {                                   \
> +            (_env)->cp15._regname##_s = (_val);            \
> +        } else {                                        \
> +            (_env)->cp15._regname##_ns = (_val);           \
> +        }                                               \
> +    } while (0)
> +
> +/* Macros for automatically accessing a specific CP register bank depending on
> + * the current secure state of the system.  These macros are not intended for
> + * supporting instruction translation reads/writes as these are dependent
> + * solely on the SCR.NS bit and not the mode.
> + */
> +#define A32_BANKED_CURRENT_REG_GET(_env, _regname)        \
> +    A32_BANKED_REG_GET((_env), _regname,                \
> +                       ((!arm_el_is_aa64((_env), 3) && arm_is_secure(_env))))
> +
> +#define A32_BANKED_CURRENT_REG_SET(_env, _regname, _val)                       \
> +    A32_BANKED_REG_SET((_env), _regname,                                    \
> +                       ((!arm_el_is_aa64((_env), 3) && arm_is_secure(_env))),  \
> +                       (_val))
> +

...though these all have to be macros because of the regname handling.

(Do we use "!arm_el_is_aa64((env), 3) && arm_is_secure(env)"
often enough to make it worth a utility function? I can't
think of a good name though, so maybe not...)

thanks
-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 10/33] target-arm: add non-secure Translation Block flag
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 10/33] target-arm: add non-secure Translation Block flag Greg Bellows
@ 2014-10-06 16:13   ` Peter Maydell
  2014-10-06 18:10     ` Sergey Fedorov
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 16:13 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, Sergey Fedorov, QEMU Developers, Fabian Aggeler,
	Edgar E. Iglesias

On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> From: Sergey Fedorov <s.fedorov@samsung.com>
>
> This patch is based on idea found in patch at
> git://github.com/jowinter/qemu-trustzone.git
> f3d955c6c0ed8c46bc0eb10b634201032a651dd2 by
> Johannes Winter <johannes.winter@iaik.tugraz.at>.
>
> This flag prevents QEMU from executing TCG code generated for other CPU
> security state. It also allows to generate different TCG code depending on
> CPU secure state.

This doesn't quite seem to line up with the code:
the commit message says the flag is for the CPU's
current security state, but the code is using the
"which register bank" setting.

> 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>
>
> ----------
> v4 -> v5
> - Merge changes
> - Fixed issue where TB secure state flag was incorrectly being set based on
>   secure state rather than NS setting.  This caused an issue where monitor mode
>   MRC/MCR accesses were always secure rather than being based on NS bit
>   setting.
> - Added separate 64/32 TB secure state flags
> - Unconditionalized the setting of the DC ns bit
> - Removed IS_NS macro and replaced with direct usage.
> ---
>  target-arm/cpu.h           | 14 ++++++++++++++
>  target-arm/translate-a64.c |  1 +
>  target-arm/translate.c     |  1 +
>  target-arm/translate.h     |  1 +
>  4 files changed, 17 insertions(+)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index c58fdf5..1700676 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -1528,6 +1528,8 @@ static inline bool arm_singlestep_active(CPUARMState *env)
>   */
>  #define ARM_TBFLAG_XSCALE_CPAR_SHIFT 20
>  #define ARM_TBFLAG_XSCALE_CPAR_MASK (3 << ARM_TBFLAG_XSCALE_CPAR_SHIFT)
> +#define ARM_TBFLAG_NS_SHIFT         22
> +#define ARM_TBFLAG_NS_MASK          (1 << ARM_TBFLAG_NS_SHIFT)
>
>  /* Bit usage when in AArch64 state */
>  #define ARM_TBFLAG_AA64_EL_SHIFT    0
> @@ -1538,6 +1540,8 @@ static inline bool arm_singlestep_active(CPUARMState *env)
>  #define ARM_TBFLAG_AA64_SS_ACTIVE_MASK (1 << ARM_TBFLAG_AA64_SS_ACTIVE_SHIFT)
>  #define ARM_TBFLAG_AA64_PSTATE_SS_SHIFT 4
>  #define ARM_TBFLAG_AA64_PSTATE_SS_MASK (1 << ARM_TBFLAG_AA64_PSTATE_SS_SHIFT)
> +#define ARM_TBFLAG_AA64_NS_SHIFT    5
> +#define ARM_TBFLAG_AA64_NS_MASK     (1 << ARM_TBFLAG_AA64_NS_SHIFT)
>
>  /* some convenience accessor macros */
>  #define ARM_TBFLAG_AARCH64_STATE(F) \
> @@ -1572,6 +1576,10 @@ static inline bool arm_singlestep_active(CPUARMState *env)
>      (((F) & ARM_TBFLAG_AA64_SS_ACTIVE_MASK) >> ARM_TBFLAG_AA64_SS_ACTIVE_SHIFT)
>  #define ARM_TBFLAG_AA64_PSTATE_SS(F) \
>      (((F) & ARM_TBFLAG_AA64_PSTATE_SS_MASK) >> ARM_TBFLAG_AA64_PSTATE_SS_SHIFT)
> +#define ARM_TBFLAG_NS(F) \
> +    (((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT)
> +#define ARM_TBFLAG_AA64_NS(F) \
> +    (((F) & ARM_TBFLAG_AA64_NS_MASK) >> ARM_TBFLAG_AA64_NS_SHIFT)
>
>  static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
>                                          target_ulong *cs_base, int *flags)
> @@ -1605,6 +1613,9 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
>                  *flags |= ARM_TBFLAG_AA64_PSTATE_SS_MASK;
>              }
>          }
> +        if (!(USE_SECURE_REG(env))) {
> +            *flags |= ARM_TBFLAG_AA64_NS_MASK;
> +        }

What's this for? If we're in AArch64 mode then we know that
EL3 (if it exists) must also be AArch64, and so USE_SECURE_REG
always returns false...

>      } else {
>          int privmode;
>          *pc = env->regs[15];
> @@ -1621,6 +1632,9 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
>          if (privmode) {
>              *flags |= ARM_TBFLAG_PRIV_MASK;
>          }
> +        if (!(USE_SECURE_REG(env))) {
> +            *flags |= ARM_TBFLAG_NS_MASK;
> +        }
>          if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
>              || arm_el_is_aa64(env, 1)) {
>              *flags |= ARM_TBFLAG_VFPEN_MASK;
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index f53dc0f..dfc8c58 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -10926,6 +10926,7 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
>  #if !defined(CONFIG_USER_ONLY)
>      dc->user = (ARM_TBFLAG_AA64_EL(tb->flags) == 0);
>  #endif
> +    dc->ns = ARM_TBFLAG_AA64_NS(tb->flags);
>      dc->cpacr_fpen = ARM_TBFLAG_AA64_FPEN(tb->flags);
>      dc->vec_len = 0;
>      dc->vec_stride = 0;
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index 3f3ddfb..5e1d677 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -10958,6 +10958,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
>  #if !defined(CONFIG_USER_ONLY)
>      dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
>  #endif
> +    dc->ns = ARM_TBFLAG_NS(tb->flags);
>      dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags);
>      dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
>      dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
> diff --git a/target-arm/translate.h b/target-arm/translate.h
> index 85c6f9d..4f9892b 100644
> --- a/target-arm/translate.h
> +++ b/target-arm/translate.h
> @@ -20,6 +20,7 @@ typedef struct DisasContext {
>  #if !defined(CONFIG_USER_ONLY)
>      int user;
>  #endif
> +    bool ns;

This could use a brief comment explaining what it indicates.

>      bool cpacr_fpen; /* FP enabled via CPACR.FPEN */
>      bool vfp_enabled; /* FP enabled via FPSCR.EN */
>      int vec_len;
> --
> 1.8.3.2

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 11/33] target-arm: arrayfying fieldoffset for banking
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 11/33] target-arm: arrayfying fieldoffset for banking Greg Bellows
@ 2014-10-06 16:19   ` Peter Maydell
  2014-10-07  5:06     ` Greg Bellows
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 16:19 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> From: Fabian Aggeler <aggelerf@ethz.ch>
>
> Prepare ARMCPRegInfo to support specifying two fieldoffsets per
> register definition. This will allow us to keep one register
> definition for banked registers (different offsets for secure/
> non-secure world).
>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
>
> ----------
> v4 -> v5
> - Added ARM CP register secure and non-secure bank flags
> - Added setting of secure and non-secure flags furing registration
> ---
>  target-arm/cpu.h    | 23 +++++++++++++++-----
>  target-arm/helper.c | 60 +++++++++++++++++++++++++++++++++++++++++------------
>  2 files changed, 65 insertions(+), 18 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 1700676..9681d45 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -958,10 +958,12 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
>  #define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8))
>  #define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | (5 << 8))
>  #define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
> +#define ARM_CP_BANK_S   (1 << 16)
> +#define ARM_CP_BANK_NS  (2 << 16)

I thought we were going to put these flags into a reginfo->secure
field? Mixing them into the 'type' bits seems unnecessarily
confusing to me.

>  /* Used only as a terminator for ARMCPRegInfo lists */
> -#define ARM_CP_SENTINEL 0xffff
> +#define ARM_CP_SENTINEL 0xffffff
>  /* Mask of only the flag bits in a type field */
> -#define ARM_CP_FLAG_MASK 0x7f
> +#define ARM_CP_FLAG_MASK 0x3007f
>
>  /* Valid values for ARMCPRegInfo state field, indicating which of
>   * the AArch32 and AArch64 execution states this register is visible in.
> @@ -1096,6 +1098,7 @@ struct ARMCPRegInfo {
>      uint8_t opc0;
>      uint8_t opc1;
>      uint8_t opc2;
> +

Stray whitespace change.

>      /* Execution state in which this register is visible: ARM_CP_STATE_* */
>      int state;
>      /* Register type: ARM_CP_* bits/values */
> @@ -1111,12 +1114,22 @@ struct ARMCPRegInfo {
>       * fieldoffset is non-zero, the reset value of the register.
>       */
>      uint64_t resetvalue;
> -    /* Offset of the field in CPUARMState for this register. This is not
> -     * needed if either:
> +    /* Offsets of the fields (secure/non-secure) in CPUARMState for this
> +     * register. The array will be accessed by the ns bit which means the
> +     * secure instance has to be at [0] while the non-secure instance must be
> +     * at [1]. If a register is not banked .fieldoffset can be used, which maps
> +     * to the non-secure bank.
> +     * This is not needed if either:
>       *  1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
>       *  2. both readfn and writefn are specified
>       */
> -    ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
> +    union { /* offsetof(CPUARMState, field) */
> +        struct {
> +            ptrdiff_t fieldoffset_padding;
> +            ptrdiff_t fieldoffset;

...why is the padding field first? Given that we always write
fieldoffset when we put the banked versions into the hash table
I don't think it should matter, should it?

> +        };
> +        ptrdiff_t bank_fieldoffsets[2];
> +    };
>      /* Function for making any access checks for this register in addition to
>       * those specified by the 'access' permissions bits. If NULL, no extra
>       * checks required. The access check is performed at runtime, not at
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index a10f459..ab38b68 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -3296,22 +3296,56 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
>      uint32_t *key = g_new(uint32_t, 1);
>      ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
>      int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
> -    if (r->state == ARM_CP_STATE_BOTH && state == ARM_CP_STATE_AA32) {
> -        /* The AArch32 view of a shared register sees the lower 32 bits
> -         * of a 64 bit backing field. It is not migratable as the AArch64
> -         * view handles that. AArch64 also handles reset.
> -         * We assume it is a cp15 register if the .cp field is left unset.
> -         */
> -        if (r2->cp == 0) {
> -            r2->cp = 15;
> +
> +    if (state == ARM_CP_STATE_AA32) {
> +        /* Clear the secure state flags and set based on incoming nsbit */
> +        r2->type &= ~(ARM_CP_BANK_S | ARM_CP_BANK_NS);
> +        r2->type |= ARM_CP_BANK_S << nsbit;
> +
> +        if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
> +            /* Register is banked (using both entries in array).
> +             * Overwriting fieldoffset as the array was only used to define
> +             * banked registers but later only fieldoffset is used.
> +             */
> +            r2->fieldoffset = r->bank_fieldoffsets[nsbit];
> +
> +            /* If V8 is enabled then we don't need to migrate or reset the
> +             * AArch32 version of the banked registers as this will be handled
> +             * through the AArch64 view.
> +             * The exception to the above is cpregs with a crn of 13
> +             * (specifically FCSEIDR and CONTEXTIDR) in which case there may
> +             * not be an AArch64 equivalent for one or either bank so migration
> +             * and reset must be preserved.
> +             */
> +            if (arm_feature(&cpu->env, ARM_FEATURE_V8) && r->crn != 13) {
> +                r2->type |= ARM_CP_NO_MIGRATE;
> +                r2->resetfn = arm_cp_reset_ignore;
> +            }
> +        } else if (!nsbit) {
> +            /* The register is not banked so we only want to allow migration of
> +             * the non-secure instance.
> +             */
> +            r2->type |= ARM_CP_NO_MIGRATE;
> +            r2->resetfn = arm_cp_reset_ignore;
>          }
> -        r2->type |= ARM_CP_NO_MIGRATE;
> -        r2->resetfn = arm_cp_reset_ignore;
> +
> +        if (r->state == ARM_CP_STATE_BOTH) {
> +            /* The AArch32 view of a shared register sees the lower 32 bits
> +             * of a 64 bit backing field. It is not migratable as the AArch64
> +             * view handles that. AArch64 also handles reset.
> +             * We assume it is a cp15 register if the .cp field is left unset.
> +             */
> +            if (r2->cp == 0) {
> +                r2->cp = 15;
> +            }
> +            r2->type |= ARM_CP_NO_MIGRATE;
> +            r2->resetfn = arm_cp_reset_ignore;
>  #ifdef HOST_WORDS_BIGENDIAN
> -        if (r2->fieldoffset) {
> -            r2->fieldoffset += sizeof(uint32_t);
> -        }
> +            if (r2->fieldoffset) {
> +                r2->fieldoffset += sizeof(uint32_t);
> +            }
>  #endif
> +        }
>      }
>      if (state == ARM_CP_STATE_AA64) {
>          /* To allow abbreviation of ARMCPRegInfo
> --
> 1.8.3.2
>


thanks
-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 12/33] target-arm: insert Aarch32 cpregs twice into hashtable
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 12/33] target-arm: insert Aarch32 cpregs twice into hashtable Greg Bellows
@ 2014-10-06 16:25   ` Peter Maydell
  2014-10-07  5:31     ` Greg Bellows
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 16:25 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> From: Fabian Aggeler <aggelerf@ethz.ch>
>
> Prepare for cp register banking by inserting every cp register twice,
> once for secure world and once for non-secure world.
>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
>
> ----------
> v4 -> v5
> - Added use of ARM CP secure/non-secure bank flags during register processing
>   in define_one_arm_cp_reg_with_opaque().  We now only register the specified
>   bank if only one flag is specified, otherwise we register both a secure and
>   non-secure instance.
> ---
>  target-arm/cpu.h       | 14 +++++++++++---
>  target-arm/helper.c    | 30 ++++++++++++++++++++++++++----
>  target-arm/translate.c | 14 +++++++++-----
>  3 files changed, 46 insertions(+), 12 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 9681d45..220571c 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -864,6 +864,7 @@ void armv7m_nvic_complete_irq(void *opaque, int irq);
>   *  Crn, Crm, opc1, opc2 fields
>   *  32 or 64 bit register (ie is it accessed via MRC/MCR
>   *    or via MRRC/MCRR?)
> + *  non-secure/secure bank (Aarch32 only)

...so if this is an AArch64 register is the bit in the hash
table key set or clear?

>   * We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field.
>   * (In this case crn and opc2 should be zero.)
>   * For AArch64, there is no 32/64 bit size distinction;
> @@ -881,9 +882,16 @@ void armv7m_nvic_complete_irq(void *opaque, int irq);
>  #define CP_REG_AA64_SHIFT 28
>  #define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
>
> -#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2)   \
> -    (((cp) << 16) | ((is64) << 15) | ((crn) << 11) |    \
> -     ((crm) << 7) | ((opc1) << 3) | (opc2))
> +/* To enable banking of coprocessor registers depending on ns-bit we
> + * add a bit to distinguish between secure and non-secure cpregs in the
> + * hashtable.
> + */
> +#define CP_REG_NS_SHIFT 27
> +#define CP_REG_NS_MASK(nsbit) (nsbit << CP_REG_NS_SHIFT)

Bit 27 is already used, as part of the COPROC field.
There's a reason the AA64 bit is 28...

> +
> +#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2, ns)   \
> +    (CP_REG_NS_MASK(ns) | ((cp) << 16) | ((is64) << 15) |   \
> +     ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))

Doesn't this break KVM's accessing of the hashtable?
You probably need to make kvm_to_cpreg_id OR in the NS
bit as appropriate, and cpreg_to_kvm_id mask it out, since
if we're using KVM then we're always non-secure.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 32/33] target-arm: add GDB scr register
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 32/33] target-arm: add GDB scr register Greg Bellows
@ 2014-10-06 16:27   ` Peter Maydell
  2014-10-07  5:09     ` Greg Bellows
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 16:27 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> Added the ability to print the scr register like can be done with the cpsr.
>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

Not sure you can just arbitrarily add new core registers
if gdb isn't expecting them, and in any case if we want
to do this we should probably do it via some more generic
mechanism than manually adding registers one at a time.
I recommend you just drop this patch for now.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 33/33] target-arm: add cpu feature EL3 to CPUs with Security Extensions
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 33/33] target-arm: add cpu feature EL3 to CPUs with Security Extensions Greg Bellows
@ 2014-10-06 16:28   ` Peter Maydell
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 16:28 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> From: Fabian Aggeler <aggelerf@ethz.ch>
>
> Set ARM_FEATURE_EL3 feature for CPUs that implement Security Extensions.
>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

(as we've discussed, but just as a note for the wider audience:)
This is the patch we can't commit til we've thought through
possible back-compatibility breakage a bit more carefully.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs
  2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (32 preceding siblings ...)
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 33/33] target-arm: add cpu feature EL3 to CPUs with Security Extensions Greg Bellows
@ 2014-10-06 16:32 ` Peter Maydell
  33 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 16:32 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> Version 5 of the ARM processor security extension (TrustZone) support.
> This patchset includes changes to support the processor security extensions
> on ARMv7 aarch32 with hooks for later enabling v8 aarch64/32.

Thanks. I've reviewed the first dozen or so patches, and
I think at that point the later patches start to need enough
changes based on review comments on the first ones that it's
not worth reviewing them at the moment. If you could respin
and send out a v6 with the comments so far addressed that
would be great.

We're into soft freeze at this point, so my intention with
these patches is to commit as many of the preliminary ones
as we can get definitely reviewed over the next week or so,
since they don't actually change behaviour for the existing
CPUs. After that the freeze starts to get solid enough that
anything remaining we'll just have to do review on so it's
ready to commit when we finish the 2.2 release in early
December, I'm afraid.

-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function
  2014-10-06 14:56   ` Peter Maydell
@ 2014-10-06 17:57     ` Sergey Fedorov
  2014-10-06 18:01       ` Peter Maydell
  2014-10-06 19:45     ` Greg Bellows
  1 sibling, 1 reply; 83+ messages in thread
From: Sergey Fedorov @ 2014-10-06 17:57 UTC (permalink / raw)
  To: Peter Maydell, Greg Bellows
  Cc: Edgar E. Iglesias, Sergey Fedorov, QEMU Developers, Fabian Aggeler

On 06.10.2014 07:56, Peter Maydell wrote:
> On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
>> From: Fabian Aggeler <aggelerf@ethz.ch>
>>
>> arm_is_secure() function allows to determine CPU security state
>> if the CPU implements Security Extensions/EL3.
>> arm_is_secure_below_el3() returns true if CPU is in secure state
>> below EL3.
>>
>> 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>
>> ---
>>  target-arm/cpu.h | 38 ++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 38 insertions(+)
>>
>> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
>> index 81fffd2..10afef0 100644
>> --- a/target-arm/cpu.h
>> +++ b/target-arm/cpu.h
>> @@ -753,6 +753,44 @@ static inline int arm_feature(CPUARMState *env, int feature)
>>      return (env->features & (1ULL << feature)) != 0;
>>  }
>>
>> +
>> +/* Return true if exception level below EL3 is in secure state */
>> +static inline bool arm_is_secure_below_el3(CPUARMState *env)
>> +{
>> +#if !defined(CONFIG_USER_ONLY)
>> +    if (arm_feature(env, ARM_FEATURE_EL3)) {
>> +        return !(env->cp15.scr_el3 & SCR_NS);
>> +    } else if (arm_feature(env, ARM_FEATURE_EL2)) {
>> +        return false;
>> +    } else {
>> +        /* IMPDEF: QEMU defaults to non-secure */
>> +        return false;
> I would be happy to fold both these identical 'return false'
> cases together and have a comment that it's only IMPDEF
> if EL2 isn't implemented.
>
>> +    }
>> +#else
>> +    return false;
>> +#endif
>> +}
>> +
>> +/* Return true if the processor is in secure state */
>> +static inline bool arm_is_secure(CPUARMState *env)
>> +{
>> +#if !defined(CONFIG_USER_ONLY)
>> +    if (arm_feature(env, ARM_FEATURE_EL3)) {
>> +        if (env->aarch64 && extract32(env->pstate, 2, 2) == 3) {
>> +            /* CPU currently in Aarch64 state and EL3 */
> Nit: "AArch64" with two capital 'A's (here and elsewhere).
>
>> +            return true;
>> +        } else if (!env->aarch64 &&
>> +                (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
>> +            /* CPU currently in Aarch32 state and monitor mode */
>> +            return true;
>> +        }
>> +    }
>> +    return arm_is_secure_below_el3(env);
>> +#else
>> +    return false;
>> +#endif
>> +}
> I checked your git tree and we don't actually use
> arm_is_secure_below_el3() anywhere except in
> arm_is_secure(), do we? That suggests to me we should
> just fold the two functions together.
>
> Can these functions live in internals.h rather than cpu.h?
> (The difference is that internals.h is restricted to only
> target-arm/ code whereas cpu.h is auto-included for a much
> wider set of files.)

Probably arm_is_secure() would be used by ARM GIC emulation until there
is no better way to determine memory transaction NS tag.

>
> thanks
> -- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function
  2014-10-06 17:57     ` Sergey Fedorov
@ 2014-10-06 18:01       ` Peter Maydell
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 18:01 UTC (permalink / raw)
  To: Sergey Fedorov
  Cc: Edgar E. Iglesias, Sergey Fedorov, QEMU Developers,
	Fabian Aggeler, Greg Bellows

On 6 October 2014 18:57, Sergey Fedorov <serge.fdrv@gmail.com> wrote:
> On 06.10.2014 07:56, Peter Maydell wrote:
>> Can these functions live in internals.h rather than cpu.h?
>> (The difference is that internals.h is restricted to only
>> target-arm/ code whereas cpu.h is auto-included for a much
>> wider set of files.)
>
> Probably arm_is_secure() would be used by ARM GIC emulation until there
> is no better way to determine memory transaction NS tag.

We could have the GIC code temporarily include
internals.h, which would be a nice big red flag that
it was doing things the wrong way :-)

-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 10/33] target-arm: add non-secure Translation Block flag
  2014-10-06 16:13   ` Peter Maydell
@ 2014-10-06 18:10     ` Sergey Fedorov
  2014-10-07  4:21       ` Greg Bellows
  0 siblings, 1 reply; 83+ messages in thread
From: Sergey Fedorov @ 2014-10-06 18:10 UTC (permalink / raw)
  To: Peter Maydell, Greg Bellows
  Cc: Edgar E. Iglesias, Sergey Fedorov, QEMU Developers, Fabian Aggeler

On 06.10.2014 09:13, Peter Maydell wrote:
> On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
>> From: Sergey Fedorov <s.fedorov@samsung.com>
>>
>> This patch is based on idea found in patch at
>> git://github.com/jowinter/qemu-trustzone.git
>> f3d955c6c0ed8c46bc0eb10b634201032a651dd2 by
>> Johannes Winter <johannes.winter@iaik.tugraz.at>.
>>
>> This flag prevents QEMU from executing TCG code generated for other CPU
>> security state. It also allows to generate different TCG code depending on
>> CPU secure state.
> This doesn't quite seem to line up with the code:
> the commit message says the flag is for the CPU's
> current security state, but the code is using the
> "which register bank" setting.

Right, the original patch used "!arm_is_secure(env)" as a condition for
setting this flag. But that was changed at some point without correcting
commit message.

>
>> 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>
>>
>> ----------
>> v4 -> v5
>> - Merge changes
>> - Fixed issue where TB secure state flag was incorrectly being set based on
>>   secure state rather than NS setting.  This caused an issue where monitor mode
>>   MRC/MCR accesses were always secure rather than being based on NS bit
>>   setting.
>> - Added separate 64/32 TB secure state flags
>> - Unconditionalized the setting of the DC ns bit
>> - Removed IS_NS macro and replaced with direct usage.
>> ---
>>  target-arm/cpu.h           | 14 ++++++++++++++
>>  target-arm/translate-a64.c |  1 +
>>  target-arm/translate.c     |  1 +
>>  target-arm/translate.h     |  1 +
>>  4 files changed, 17 insertions(+)
>>
>> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
>> index c58fdf5..1700676 100644
>> --- a/target-arm/cpu.h
>> +++ b/target-arm/cpu.h
>> @@ -1528,6 +1528,8 @@ static inline bool arm_singlestep_active(CPUARMState *env)
>>   */
>>  #define ARM_TBFLAG_XSCALE_CPAR_SHIFT 20
>>  #define ARM_TBFLAG_XSCALE_CPAR_MASK (3 << ARM_TBFLAG_XSCALE_CPAR_SHIFT)
>> +#define ARM_TBFLAG_NS_SHIFT         22
>> +#define ARM_TBFLAG_NS_MASK          (1 << ARM_TBFLAG_NS_SHIFT)
>>
>>  /* Bit usage when in AArch64 state */
>>  #define ARM_TBFLAG_AA64_EL_SHIFT    0
>> @@ -1538,6 +1540,8 @@ static inline bool arm_singlestep_active(CPUARMState *env)
>>  #define ARM_TBFLAG_AA64_SS_ACTIVE_MASK (1 << ARM_TBFLAG_AA64_SS_ACTIVE_SHIFT)
>>  #define ARM_TBFLAG_AA64_PSTATE_SS_SHIFT 4
>>  #define ARM_TBFLAG_AA64_PSTATE_SS_MASK (1 << ARM_TBFLAG_AA64_PSTATE_SS_SHIFT)
>> +#define ARM_TBFLAG_AA64_NS_SHIFT    5
>> +#define ARM_TBFLAG_AA64_NS_MASK     (1 << ARM_TBFLAG_AA64_NS_SHIFT)
>>
>>  /* some convenience accessor macros */
>>  #define ARM_TBFLAG_AARCH64_STATE(F) \
>> @@ -1572,6 +1576,10 @@ static inline bool arm_singlestep_active(CPUARMState *env)
>>      (((F) & ARM_TBFLAG_AA64_SS_ACTIVE_MASK) >> ARM_TBFLAG_AA64_SS_ACTIVE_SHIFT)
>>  #define ARM_TBFLAG_AA64_PSTATE_SS(F) \
>>      (((F) & ARM_TBFLAG_AA64_PSTATE_SS_MASK) >> ARM_TBFLAG_AA64_PSTATE_SS_SHIFT)
>> +#define ARM_TBFLAG_NS(F) \
>> +    (((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT)
>> +#define ARM_TBFLAG_AA64_NS(F) \
>> +    (((F) & ARM_TBFLAG_AA64_NS_MASK) >> ARM_TBFLAG_AA64_NS_SHIFT)
>>
>>  static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
>>                                          target_ulong *cs_base, int *flags)
>> @@ -1605,6 +1613,9 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
>>                  *flags |= ARM_TBFLAG_AA64_PSTATE_SS_MASK;
>>              }
>>          }
>> +        if (!(USE_SECURE_REG(env))) {
>> +            *flags |= ARM_TBFLAG_AA64_NS_MASK;
>> +        }
> What's this for? If we're in AArch64 mode then we know that
> EL3 (if it exists) must also be AArch64, and so USE_SECURE_REG
> always returns false...
>
>>      } else {
>>          int privmode;
>>          *pc = env->regs[15];
>> @@ -1621,6 +1632,9 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
>>          if (privmode) {
>>              *flags |= ARM_TBFLAG_PRIV_MASK;
>>          }
>> +        if (!(USE_SECURE_REG(env))) {
>> +            *flags |= ARM_TBFLAG_NS_MASK;
>> +        }
>>          if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
>>              || arm_el_is_aa64(env, 1)) {
>>              *flags |= ARM_TBFLAG_VFPEN_MASK;
>> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
>> index f53dc0f..dfc8c58 100644
>> --- a/target-arm/translate-a64.c
>> +++ b/target-arm/translate-a64.c
>> @@ -10926,6 +10926,7 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
>>  #if !defined(CONFIG_USER_ONLY)
>>      dc->user = (ARM_TBFLAG_AA64_EL(tb->flags) == 0);
>>  #endif
>> +    dc->ns = ARM_TBFLAG_AA64_NS(tb->flags);
>>      dc->cpacr_fpen = ARM_TBFLAG_AA64_FPEN(tb->flags);
>>      dc->vec_len = 0;
>>      dc->vec_stride = 0;
>> diff --git a/target-arm/translate.c b/target-arm/translate.c
>> index 3f3ddfb..5e1d677 100644
>> --- a/target-arm/translate.c
>> +++ b/target-arm/translate.c
>> @@ -10958,6 +10958,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
>>  #if !defined(CONFIG_USER_ONLY)
>>      dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
>>  #endif
>> +    dc->ns = ARM_TBFLAG_NS(tb->flags);
>>      dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags);
>>      dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
>>      dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
>> diff --git a/target-arm/translate.h b/target-arm/translate.h
>> index 85c6f9d..4f9892b 100644
>> --- a/target-arm/translate.h
>> +++ b/target-arm/translate.h
>> @@ -20,6 +20,7 @@ typedef struct DisasContext {
>>  #if !defined(CONFIG_USER_ONLY)
>>      int user;
>>  #endif
>> +    bool ns;
> This could use a brief comment explaining what it indicates.
>
>>      bool cpacr_fpen; /* FP enabled via CPACR.FPEN */
>>      bool vfp_enabled; /* FP enabled via FPSCR.EN */
>>      int vec_len;
>> --
>> 1.8.3.2

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 01/33] target-arm: increase arrays of registers R13 & R14
  2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 01/33] target-arm: increase arrays of registers R13 & R14 Greg Bellows
  2014-10-06 14:48   ` Peter Maydell
@ 2014-10-06 19:21   ` Greg Bellows
  1 sibling, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-10-06 19:21 UTC (permalink / raw)
  To: QEMU Developers, Peter Maydell, Sergey Fedorov,
	Edgar E. Iglesias, Fabian Aggeler
  Cc: Greg Bellows

[-- Attachment #1: Type: text/plain, Size: 1718 bytes --]

Fixed in v6.

On 30 September 2014 16:49, Greg Bellows <greg.bellows@linaro.org> wrote:

> From: Fabian Aggeler <aggelerf@ethz.ch>
>
> Increasing banked_r13 and banked_r14 to store LR_mon and SP_mon (bank
> index 7).
>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> ---
>  target-arm/cpu.h     | 4 ++--
>  target-arm/machine.c | 4 ++--
>  2 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 65a3417..81fffd2 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -153,8 +153,8 @@ typedef struct CPUARMState {
>
>      /* Banked registers.  */
>      uint64_t banked_spsr[8];
> -    uint32_t banked_r13[6];
> -    uint32_t banked_r14[6];
> +    uint32_t banked_r13[8];
> +    uint32_t banked_r14[8];
>
>      /* These hold r8-r12.  */
>      uint32_t usr_regs[5];
> diff --git a/target-arm/machine.c b/target-arm/machine.c
> index ddb7d05..7e69127 100644
> --- a/target-arm/machine.c
> +++ b/target-arm/machine.c
> @@ -238,8 +238,8 @@ const VMStateDescription vmstate_arm_cpu = {
>          },
>          VMSTATE_UINT32(env.spsr, ARMCPU),
>          VMSTATE_UINT64_ARRAY(env.banked_spsr, ARMCPU, 8),
> -        VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 6),
> -        VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 6),
> +        VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 8),
> +        VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 8),
>          VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5),
>          VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5),
>          VMSTATE_UINT64_ARRAY(env.elr_el, ARMCPU, 4),
> --
> 1.8.3.2
>
>

[-- Attachment #2: Type: text/html, Size: 2481 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function
  2014-10-06 14:56   ` Peter Maydell
  2014-10-06 17:57     ` Sergey Fedorov
@ 2014-10-06 19:45     ` Greg Bellows
  2014-10-06 20:07       ` Peter Maydell
  1 sibling, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-10-06 19:45 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Sergey Fedorov, Sergey Fedorov, QEMU Developers, Fabian Aggeler,
	Edgar E. Iglesias

[-- Attachment #1: Type: text/plain, Size: 3399 bytes --]

On 6 October 2014 09:56, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> > From: Fabian Aggeler <aggelerf@ethz.ch>
> >
> > arm_is_secure() function allows to determine CPU security state
> > if the CPU implements Security Extensions/EL3.
> > arm_is_secure_below_el3() returns true if CPU is in secure state
> > below EL3.
> >
> > 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>
> > ---
> >  target-arm/cpu.h | 38 ++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 38 insertions(+)
> >
> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > index 81fffd2..10afef0 100644
> > --- a/target-arm/cpu.h
> > +++ b/target-arm/cpu.h
> > @@ -753,6 +753,44 @@ static inline int arm_feature(CPUARMState *env, int
> feature)
> >      return (env->features & (1ULL << feature)) != 0;
> >  }
> >
> > +
> > +/* Return true if exception level below EL3 is in secure state */
> > +static inline bool arm_is_secure_below_el3(CPUARMState *env)
> > +{
> > +#if !defined(CONFIG_USER_ONLY)
> > +    if (arm_feature(env, ARM_FEATURE_EL3)) {
> > +        return !(env->cp15.scr_el3 & SCR_NS);
> > +    } else if (arm_feature(env, ARM_FEATURE_EL2)) {
> > +        return false;
> > +    } else {
> > +        /* IMPDEF: QEMU defaults to non-secure */
> > +        return false;
>
> I would be happy to fold both these identical 'return false'
> cases together and have a comment that it's only IMPDEF
> if EL2 isn't implemented.
>

Yes, this makes sense.  Fixed in v6.


>
> > +    }
> > +#else
> > +    return false;
> > +#endif
> > +}
> > +
> > +/* Return true if the processor is in secure state */
> > +static inline bool arm_is_secure(CPUARMState *env)
> > +{
> > +#if !defined(CONFIG_USER_ONLY)
> > +    if (arm_feature(env, ARM_FEATURE_EL3)) {
> > +        if (env->aarch64 && extract32(env->pstate, 2, 2) == 3) {
> > +            /* CPU currently in Aarch64 state and EL3 */
>
> Nit: "AArch64" with two capital 'A's (here and elsewhere).
>
> > +            return true;
> > +        } else if (!env->aarch64 &&
> > +                (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
> > +            /* CPU currently in Aarch32 state and monitor mode */
> > +            return true;
> > +        }
> > +    }
> > +    return arm_is_secure_below_el3(env);
> > +#else
> > +    return false;
> > +#endif
> > +}
>
> I checked your git tree and we don't actually use
> arm_is_secure_below_el3() anywhere except in
> arm_is_secure(), do we? That suggests to me we should
> just fold the two functions together.
>

This is true and I contemplated this myself.  The reason I did not fold
them together is because they match what is defined in the ARM v8 ARM and
the below_el3 pseudo-function is actually used elsewhere in the spec
separate from isSecure().  Honestly, I can go whichever way, so given the
above what is your preference?


>
> Can these functions live in internals.h rather than cpu.h?
> (The difference is that internals.h is restricted to only
> target-arm/ code whereas cpu.h is auto-included for a much
> wider set of files.)
>

I can move the code, but how does it differ from the likes of arm_feature()
or arm_el_is_aa64()?  They seem to serve the same utility purpose.


>
> thanks
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 5080 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 04/33] target-arm: rename arm_current_pl to arm_current_el
  2014-10-06 15:10   ` Peter Maydell
@ 2014-10-06 19:55     ` Greg Bellows
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-10-06 19:55 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

[-- Attachment #1: Type: text/plain, Size: 1484 bytes --]

On 6 October 2014 10:10, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> > Renamed the arm_current_pl CPU function to more accurately represent
> that it
> > returns the ARMv8 EL rather than ARMv7 PL.
>

Comment added in v6.


> >
> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> > ---
> >  target-arm/cpu.h           | 18 +++++++++---------
> >  target-arm/helper-a64.c    |  6 +++---
> >  target-arm/helper.c        | 22 +++++++++++-----------
> >  target-arm/internals.h     |  2 +-
> >  target-arm/op_helper.c     | 16 ++++++++--------
> >  target-arm/translate-a64.c |  2 +-
> >  target-arm/translate.c     |  2 +-
> >  7 files changed, 34 insertions(+), 34 deletions(-)
> >
> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > index 10afef0..101d139 100644
> > --- a/target-arm/cpu.h
> > +++ b/target-arm/cpu.h
> > @@ -982,7 +982,7 @@ static inline bool cptype_valid(int cptype)
> >  #define PL1_RW (PL1_R | PL1_W)
> >  #define PL0_RW (PL0_R | PL0_W)
> >
> > -static inline int arm_current_pl(CPUARMState *env)
> > +static inline int arm_current_el(CPUARMState *env)
>
> I suggest we add a brief comment before the function:
> /* Return the current Exception Level (as per ARMv8;
>  * note that this differs from the ARMv7 Privilege Level).
>  */
>
> You should also fix the "PL2" and "PL3" references in
> the comments to read "EL2" and "EL3".
>
>
Fixed in v6.


> thanks
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 2488 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function
  2014-10-06 19:45     ` Greg Bellows
@ 2014-10-06 20:07       ` Peter Maydell
  2014-10-06 20:47         ` Greg Bellows
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 20:07 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, Sergey Fedorov, QEMU Developers, Fabian Aggeler,
	Edgar E. Iglesias

On 6 October 2014 20:45, Greg Bellows <greg.bellows@linaro.org> wrote:
> On 6 October 2014 09:56, Peter Maydell <peter.maydell@linaro.org> wrote:
>> I checked your git tree and we don't actually use
>> arm_is_secure_below_el3() anywhere except in
>> arm_is_secure(), do we? That suggests to me we should
>> just fold the two functions together.
>
>
> This is true and I contemplated this myself.  The reason I did not fold them
> together is because they match what is defined in the ARM v8 ARM and the
> below_el3 pseudo-function is actually used elsewhere in the spec separate
> from isSecure().  Honestly, I can go whichever way, so given the above what
> is your preference?

Ah, my search through the ARM ARM didn't find the pseudocode
function first time around. I was also a bit confused by
the comment on the function, which you have as:
/* Return true if exception level below EL3 is in secure state */

which implies that it's just "arm_is_secure() but it only
works if you're not in EL3", whereas the ARM ARM says:

//  Return TRUE if an Exception level below EL3 is in Secure state
//  or would be following an exception return to that level.
//  Differs from IsSecure in that it ignores the current EL or Mode
//  in considering security state.

which makes it clearer why it might be useful and why
it's not the same as arm_is_secure(). So yes, we should
retain the two separate functions, but we should improve
the comment describing what arm_is_secure_below_el3() does.

You should use is_a64() rather than directly looking at
env->aarch64, incidentally.

>> Can these functions live in internals.h rather than cpu.h?
>> (The difference is that internals.h is restricted to only
>> target-arm/ code whereas cpu.h is auto-included for a much
>> wider set of files.)
>
>
> I can move the code, but how does it differ from the likes of arm_feature()
> or arm_el_is_aa64()?  They seem to serve the same utility purpose.

Many functions in cpu.h are there simply because they were
written before we added internals.h (ie for legacy reasons).
I'd prefer not to add to the set of functions in the wrong
place, though.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function
  2014-10-06 20:07       ` Peter Maydell
@ 2014-10-06 20:47         ` Greg Bellows
  2014-10-06 21:07           ` Peter Maydell
  0 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-10-06 20:47 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Sergey Fedorov, Sergey Fedorov, QEMU Developers, Fabian Aggeler,
	Edgar E. Iglesias

[-- Attachment #1: Type: text/plain, Size: 2559 bytes --]

On 6 October 2014 15:07, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 6 October 2014 20:45, Greg Bellows <greg.bellows@linaro.org> wrote:
> > On 6 October 2014 09:56, Peter Maydell <peter.maydell@linaro.org> wrote:
> >> I checked your git tree and we don't actually use
> >> arm_is_secure_below_el3() anywhere except in
> >> arm_is_secure(), do we? That suggests to me we should
> >> just fold the two functions together.
> >
> >
> > This is true and I contemplated this myself.  The reason I did not fold
> them
> > together is because they match what is defined in the ARM v8 ARM and the
> > below_el3 pseudo-function is actually used elsewhere in the spec separate
> > from isSecure().  Honestly, I can go whichever way, so given the above
> what
> > is your preference?
>
> Ah, my search through the ARM ARM didn't find the pseudocode
> function first time around. I was also a bit confused by
> the comment on the function, which you have as:
> /* Return true if exception level below EL3 is in secure state */
>
> which implies that it's just "arm_is_secure() but it only
> works if you're not in EL3", whereas the ARM ARM says:
>
> //  Return TRUE if an Exception level below EL3 is in Secure state
> //  or would be following an exception return to that level.
> //  Differs from IsSecure in that it ignores the current EL or Mode
> //  in considering security state.
>
> which makes it clearer why it might be useful and why
> it's not the same as arm_is_secure(). So yes, we should
> retain the two separate functions, but we should improve
> the comment describing what arm_is_secure_below_el3() does.
>
>
Comments added in v6.


> You should use is_a64() rather than directly looking at
> env->aarch64, incidentally.
>

Since I am touching arm_current_el(), should I go ahead and fix it to use
is_a64() as well?


>
> >> Can these functions live in internals.h rather than cpu.h?
> >> (The difference is that internals.h is restricted to only
> >> target-arm/ code whereas cpu.h is auto-included for a much
> >> wider set of files.)
> >
> >
> > I can move the code, but how does it differ from the likes of
> arm_feature()
> > or arm_el_is_aa64()?  They seem to serve the same utility purpose.
>
> Many functions in cpu.h are there simply because they were
> written before we added internals.h (ie for legacy reasons).
> I'd prefer not to add to the set of functions in the wrong
> place, though.
>
>
I'll move in v6.  Should I also go ahead and move arm_current_el() to
internals.h as well since I am touching it?


> thanks
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 3787 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 05/33] target-arm: make arm_current_pl() return PL3
  2014-10-06 15:34   ` Peter Maydell
@ 2014-10-06 20:53     ` Greg Bellows
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-10-06 20:53 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

[-- Attachment #1: Type: text/plain, Size: 3876 bytes --]

On 6 October 2014 10:34, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> > From: Fabian Aggeler <aggelerf@ethz.ch>
> >
> > Make arm_current_pl() return PL3 for secure PL1 and monitor mode.
> > Increase MMU modes since mmu_index is directly infered from arm_
> > current_pl(). Changes assertion in arm_el_is_aa64() to allow EL3.
> >
> > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> > ---
> >  target-arm/cpu.h | 15 +++++++++------
> >  1 file changed, 9 insertions(+), 6 deletions(-)
> >
> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > index 101d139..c000716 100644
> > --- a/target-arm/cpu.h
> > +++ b/target-arm/cpu.h
> > @@ -100,7 +100,7 @@ typedef uint32_t ARMReadCPFunc(void *opaque, int
> cp_info,
> >
> >  struct arm_boot_info;
> >
> > -#define NB_MMU_MODES 2
> > +#define NB_MMU_MODES 4
> >
> >  /* We currently assume float and double are IEEE single and double
> >     precision respectively.
> > @@ -753,7 +753,6 @@ static inline int arm_feature(CPUARMState *env, int
> feature)
> >      return (env->features & (1ULL << feature)) != 0;
> >  }
> >
> > -
>
> Stray whitespace change.
>

Fixed in early commit where an additional blank line was inadvertently
added.


>
> >  /* Return true if exception level below EL3 is in secure state */
> >  static inline bool arm_is_secure_below_el3(CPUARMState *env)
> >  {
> > @@ -794,11 +793,12 @@ static inline bool arm_is_secure(CPUARMState *env)
> >  /* Return true if the specified exception level is running in AArch64
> state. */
> >  static inline bool arm_el_is_aa64(CPUARMState *env, int el)
> >  {
> > -    /* We don't currently support EL2 or EL3, and this isn't valid for
> EL0
> > +    /* We don't currently support EL2, and this isn't valid for EL0
> >       * (if we're in EL0, is_a64() is what you want, and if we're not in
> EL0
> >       * then the state of EL0 isn't well defined.)
> >       */
> > -    assert(el == 1);
> > +    assert(el == 1 || el == 3);
> > +
> >      /* AArch64-capable CPUs always run with EL1 in AArch64 mode. This
> >       * is a QEMU-imposed simplification which we may wish to change
> later.
> >       * If we in future support EL2 and/or EL3, then the state of lower
>
> > @@ -990,9 +990,12 @@ static inline int arm_current_el(CPUARMState *env)
> >
> >      if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR) {
> >          return 0;
> > +    } else if (arm_is_secure(env)) {
> > +        /* Secure PL1 and monitor mode are mapped to PL3 */
> > +        return 3;
>
> This isn't correct. Secure privileged !Mon AArch32 modes are only
> EL3 if EL3 is AArch32. If EL3 is AArch64 then the !Mon AArch32
> modes are EL1.
>

Yes, this was on my list of updates based on our discussion and I missed
it.  Fixed in v6 as prescribed.


>
> >      }
> > -    /* We don't currently implement the Virtualization or TrustZone
> > -     * extensions, so PL2 and PL3 don't exist for us.
> > +    /* We currently do not implement the Virtualization extensions, so
> PL2 does
> > +     * not exist for us.
> >       */
> >      return 1;
>
> Now that we've added the complications for handling secure mode,
> we might as well also have the trivial code for Hyp too. So
> that means the function looks something like:
>
>     if (env->aarch64) {
>         return extract32(env->pstate, 2, 2);
>     }
>
>     switch (env->uncached_cpsr & CPSR_M) {
>     case ARM_CPU_MODE_USR:
>         return 0;
>     case ARM_CPU_MODE_HYP:
>         return 2;
>     case ARM_CPU_MODE_MON:
>         return 3;
>     default:
>         if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
>             /* If EL3 is 32-bit then all secure privileged modes run in
> EL3 */
>             return 3;
>         }
>         return 1;
>     }
>
> thanks
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 5432 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function
  2014-10-06 20:47         ` Greg Bellows
@ 2014-10-06 21:07           ` Peter Maydell
  2014-10-08 19:33             ` Greg Bellows
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-10-06 21:07 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, Sergey Fedorov, QEMU Developers, Fabian Aggeler,
	Edgar E. Iglesias

On 6 October 2014 21:47, Greg Bellows <greg.bellows@linaro.org> wrote:
>
>
> On 6 October 2014 15:07, Peter Maydell <peter.maydell@linaro.org> wrote:
>> You should use is_a64() rather than directly looking at
>> env->aarch64, incidentally.
>
>
> Since I am touching arm_current_el(), should I go ahead and fix it to use
> is_a64() as well?

Optional.

> I'll move in v6.  Should I also go ahead and move arm_current_el() to
> internals.h as well since I am touching it?

No. Let's try to keep the scope of this patchset under control.

-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 06/33] target-arm: A32: Emulate the SMC instruction
  2014-10-06 15:46   ` Peter Maydell
@ 2014-10-07  1:56     ` Greg Bellows
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-10-07  1:56 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Sergey Fedorov, Sergey Fedorov, QEMU Developers, Fabian Aggeler,
	Edgar E. Iglesias

[-- Attachment #1: Type: text/plain, Size: 5667 bytes --]

On 6 October 2014 10:46, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 30 September 2014 22:49, 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>
> >
> > ----------
> > v4 -> v5
> > - Merge pre_smc upstream changes and incorporated ss_advance
> > ---
> >  target-arm/helper.c    | 11 +++++++++++
> >  target-arm/internals.h |  7 ++++++-
> >  target-arm/op_helper.c |  3 +--
> >  target-arm/translate.c | 39 +++++++++++++++++++++++++++++----------
> >  4 files changed, 47 insertions(+), 13 deletions(-)
> >
> > diff --git a/target-arm/helper.c b/target-arm/helper.c
> > index 2381e6f..7f3f049 100644
> > --- a/target-arm/helper.c
> > +++ b/target-arm/helper.c
> > @@ -4090,6 +4090,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.  */
> > @@ -4108,6 +4114,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/internals.h b/target-arm/internals.h
> > index fd69a83..43a2e7d 100644
> > --- a/target-arm/internals.h
> > +++ b/target-arm/internals.h
> > @@ -236,7 +236,12 @@ static inline uint32_t syn_aa32_svc(uint32_t imm16,
> bool is_thumb)
> >          | (is_thumb ? 0 : ARM_EL_IL);
> >  }
> >
> > -static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
> > +static inline uint32_t syn_aa32_smc(void)
> > +{
> > +    return (EC_AA32_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL;
> > +}
> > +
> > +static inline uint32_t syn_aa64_bkpt(uint16_t imm16)
>
> Bogus change (probably introduced by accident in a merge
> conflict fixup).
>

Fixed in v6.


>
> >  {
> >      return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 &
> 0xffff);
> >  }
> > diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
> > index 0809d63..8ed8ee9 100644
> > --- a/target-arm/op_helper.c
> > +++ b/target-arm/op_helper.c
> > @@ -419,8 +419,7 @@ void HELPER(pre_hvc)(CPUARMState *env)
> >  void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
> >  {
> >      int cur_el = arm_current_el(env);
> > -    /* FIXME: Use real secure state.  */
> > -    bool secure = false;
> > +    bool secure = arm_is_secure(env);;
>
> Doubled semicolon.
>

Fixed in v6


>
> >      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.
> > diff --git a/target-arm/translate.c b/target-arm/translate.c
> > index f6404be..3f3ddfb 100644
> > --- a/target-arm/translate.c
> > +++ b/target-arm/translate.c
> > @@ -7872,15 +7872,27 @@ static void disas_arm_insn(CPUARMState * env,
> DisasContext *s)
> >          case 7:
> >          {
> >              int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12)
> << 4);
> > -            /* SMC instruction (op1 == 3)
> > -               and undefined instructions (op1 == 0 || op1 == 2)
> > -               will trap */
> > -            if (op1 != 1) {
> > +            if (op1 == 1) {
> > +                /* bkpt */
> > +                ARCH(5);
> > +                gen_exception_insn(s, 4, EXCP_BKPT,
> > +                        syn_aa32_bkpt(imm16, false));
> > +            } else if (op1 == 3) {
> > +                /* smi/smc */
> > +                if (!arm_dc_feature(s, ARM_FEATURE_EL3) ||
> > +                        s->current_pl == 0) {
> > +                    goto illegal_op;
> > +                }
> > +                gen_set_pc_im(s, s->pc);
>
> This should be s->pc - 4, because if the pre_smc helper throws
> an UNDEF exception you want the PC to point to the SMC insn,
> not the insn after. (If the SMC executes as an SMC then the
> PC for the EXCP_SMC will be correct because of the 0 offset
> passed to gen_exception_insn below.)
>

Fixed in v6


>
> > +                tmp = tcg_const_i32(syn_aa32_smc());
> > +                gen_helper_pre_smc(cpu_env, tmp);
> > +                tcg_temp_free_i32(tmp);
> > +                gen_ss_advance(s);
> > +                gen_exception_insn(s, 0, EXCP_SMC, syn_aa32_smc());
> > +                break;
> > +            } else {
> >                  goto illegal_op;
> >              }
>
> That said, I have a feeling we might want to put the SMC
> handling into the end-of-loop processing for A32/T32,
> the same way we do SVC. Ard has a patch onlist which does
> that, though it is on my todo list to try to fix because
> it has its own issues...
>

I'll leave it as-is for now because it appears to work.  In the meantime,
I'll hunt for Ard's patch... unless you have a pointer and can save me the
trouble.


>
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 8100 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 07/33] target-arm: extend async excp masking
  2014-10-06 15:53   ` Peter Maydell
@ 2014-10-07  3:16     ` Greg Bellows
  2014-10-07  7:03       ` Peter Maydell
  0 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-10-07  3:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

[-- Attachment #1: Type: text/plain, Size: 3862 bytes --]

On 6 October 2014 10:53, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> > From: Fabian Aggeler <aggelerf@ethz.ch>
> >
> > This patch extends arm_excp_unmasked() according to ARM ARMv7 and
> > ARM ARMv8 (all EL running in Aarch32) and adds comments.
>
> "AA" (just do a search and replace through the whole patchset,
> please.)
>
> >
> > If EL3 is using Aarch64 IRQ/FIQ masking is ignored in
> > all exception levels other than EL3 if SCR.{FIQ|IRQ} is
> > set to 1 (routed to EL3).
> >
> > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> >
> > ----------
> > v4 -> v5
> > - Merge with v4 patch 10
> > ---
> >  target-arm/cpu.h | 116
> ++++++++++++++++++++++++++++++++++++++++++++++++++-----
> >  1 file changed, 106 insertions(+), 10 deletions(-)
> >
> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > index c000716..30f57fd 100644
> > --- a/target-arm/cpu.h
> > +++ b/target-arm/cpu.h
> > @@ -1226,11 +1226,8 @@ static inline bool arm_excp_unmasked(CPUState
> *cs, unsigned int excp_idx)
> >  {
> >      CPUARMState *env = cs->env_ptr;
> >      unsigned int cur_el = arm_current_el(env);
> > -    unsigned int target_el = arm_excp_target_el(cs, excp_idx);
> > -    /* FIXME: Use actual secure state.  */
> > -    bool secure = false;
> > -    /* If in EL1/0, Physical IRQ routing to EL2 only happens from NS
> state.  */
> > -    bool irq_can_hyp = !secure && cur_el < 2 && target_el == 2;
> > +    bool secure = arm_is_secure(env);
> > +
> >      /* ARMv7-M interrupt return works by loading a magic value
> >       * into the PC.  On real hardware the load causes the
> >       * return to occur.  The qemu implementation performs the
> > @@ -1245,19 +1242,118 @@ static inline bool arm_excp_unmasked(CPUState
> *cs, unsigned int excp_idx)
> >                          && (!IS_M(env) || env->regs[15] < 0xfffffff0);
> >
> >      /* Don't take exceptions if they target a lower EL.  */
> > -    if (cur_el > target_el) {
> > +    if (cur_el > arm_excp_target_el(cs, excp_idx)) {
> >          return false;
> >      }
> >
> > +    /* ARM ARMv7 B1.8.6  Asynchronous exception masking (table
> B1-12/B1-13)
> > +     * ARM ARMv8 G1.11.3 Asynchronous exception masking controls
> > +     * (table G1-18/G1-19) */
>
> "*/" goes on its own line.
>
>
Fixed in v6


> >      switch (excp_idx) {
> >      case EXCP_FIQ:
> > -        if (irq_can_hyp && (env->cp15.hcr_el2 & HCR_FMO)) {
> > -            return true;
> > +        if (arm_feature(env, ARM_FEATURE_EL3) && arm_el_is_aa64(env,
> 3)) {
> > +            /* If EL3 is using Aarch64 and FIQs are routed to EL3
> masking is
> > +             * ignored in all exception levels except EL3.
> > +             */
> > +            if ((env->cp15.scr_el3 & SCR_FIQ) && cur_el < 3) {
> > +                return true;
> > +            }
> > +            /* If we are in EL3 but FIQs are not routed to EL3 the
> exception
> > +             * is not taken but remains pending.
> > +             */
> > +            if (!(env->cp15.scr_el3 & SCR_FIQ) && cur_el == 3) {
> > +                return false;
> > +            }
> > +        }
>
> This is all kind of confusing. What is the division of work
> between this function and arm_phys_excp_target_el(),
> conceptually? Why isn't "we're in EL3 but FIQs aren't going
> to EL3" handled by the "cur_el > arm_excp_target_el()" check
> above, for instance?
>

I inherited the code, so I can't speak entirely to the motivation.  I'm
guessing that the code closely follows the ARM spec for masking.  Certainly
the code could be divided differently, but functionally it works so I saw
no need to change it.  I can certainly adjust the two functions if you
would prefer to isolate the routing/target function.


> thanks
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 5728 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 08/33] target-arm: add async excp target_el function
  2014-10-06 16:02   ` Peter Maydell
@ 2014-10-07  3:52     ` Greg Bellows
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-10-07  3:52 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

[-- Attachment #1: Type: text/plain, Size: 7251 bytes --]

On 6 October 2014 11:02, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> > From: Fabian Aggeler <aggelerf@ethz.ch>
> >
> > Adds a dedicated function for IRQ and FIQ exceptions to determine
> > target_el and mode (Aarch32) according to tables in ARM ARMv8 and
> > ARM ARM v7.
> >
> > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> >
> > ----------
> > v4 -> v5
> > - Simplify target EL function including removal of mode which was unused
> > - Merged with patch that plugs in the use of the function
> >
> > v3 -> v4
> > - Fixed arm_phys_excp_target_el() 0/0/0 case to return excp_mode when
> EL<2
> >   rather than ABORT.
> > ---
> >  target-arm/cpu.h    |   2 +
> >  target-arm/helper.c | 103
> ++++++++++++++++++++++++++++++++++++++++++----------
> >  2 files changed, 85 insertions(+), 20 deletions(-)
> >
> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > index 30f57fd..601f8fe 100644
> > --- a/target-arm/cpu.h
> > +++ b/target-arm/cpu.h
> > @@ -809,6 +809,8 @@ static inline bool arm_el_is_aa64(CPUARMState *env,
> int el)
> >
> >  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 excp_idx,
> > +                                        uint32_t cur_el, bool secure);
>
> This is only used in helper.c which is also the place where it
> is defined, so why are we making it a global function with
> a prototype here rather than having it be 'static'?
>
>
Removed from v6 and made static local to helper.c.


> >
> >  /* Interface between CPU and Interrupt controller.  */
> >  void armv7m_nvic_set_pending(void *opaque, int irq);
> > diff --git a/target-arm/helper.c b/target-arm/helper.c
> > index 7f3f049..a10f459 100644
> > --- a/target-arm/helper.c
> > +++ b/target-arm/helper.c
> > @@ -3706,6 +3706,12 @@ uint32_t HELPER(get_r13_banked)(CPUARMState *env,
> uint32_t mode)
> >      return 0;
> >  }
> >
> > +inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
> > +                                        uint32_t cur_el, bool secure)
> > +{
> > +    return 1;
> > +}
> > +
>
> This version is never used, so I think it can be deleted?
>
>
Yep, removed from v6.


It is actually called from


> >  unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
> >  {
> >      return 1;
> > @@ -3767,6 +3773,80 @@ void switch_mode(CPUARMState *env, int mode)
> >  }
> >
> >  /*
> > + * Determine the target EL for physical exceptions
>
> What's a "physical exception" ?
>

I am guessing that this was taken from the ARM spec which refers to
"physical exceptions" as the resulting actual exception type that virtual
exceptions correspond to.


> > + */
> > +inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
> > +                                        uint32_t cur_el, bool secure)
> > +{
> > +    CPUARMState *env = cs->env_ptr;
> > +    uint32_t target_el = 1;
> > +
> > +    /* There is no SCR or HCR routing unless the respective EL3 and EL2
> > +     * extensions are supported.  This initial setting affects whether
> any
> > +     * other conditions matter.
> > +     */
> > +    bool scr_routing = arm_feature(env, ARM_FEATURE_EL3); /* IRQ, FIQ,
> EA */
> > +    bool hcr_routing = arm_feature(env, ARM_FEATURE_EL2); /* IMO, FMO,
> AMO */
> > +
> > +    /* Fast-path if EL2 and EL3 are not enabled */
> > +    if (!scr_routing && !hcr_routing) {
> > +        return target_el;
> > +    }
> > +
> > +    switch (excp_idx) {
> > +    case EXCP_IRQ:
> > +        scr_routing &= ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ);
> > +        hcr_routing &= ((env->cp15.hcr_el2 & HCR_IMO) == HCR_IMO);
> > +        break;
> > +    case EXCP_FIQ:
> > +        scr_routing &= ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ);
> > +        hcr_routing &= ((env->cp15.hcr_el2 & HCR_FMO) == HCR_FMO);
> > +    }
> > +
> > +    /* If SCR routing is enabled we always go to EL3 regardless of EL3
> > +     * execution state
> > +     */
> > +    if (scr_routing) {
> > +        /* IRQ|FIQ|EA == 1 */
> > +        return 3;
> > +    }
> > +
> > +    /* If HCR.TGE is set all exceptions that would be routed to EL1 are
> > +     * routed to EL2 (in non-secure world).
> > +     */
> > +    hcr_routing &= (env->cp15.hcr_el2 & HCR_TGE) == HCR_TGE;
> > +
> > +    /* Determine target EL according to ARM ARMv8 tables G1-15 and
> G1-16 */
> > +    if (arm_el_is_aa64(env, 3)) {
> > +        /* EL3 in Aarch64 */
> > +        if (!secure) {
> > +            /* If non-secure, we may route to EL2 depending on other
> state.
> > +             * If we are coming from the secure world then we always
> route to
> > +             * EL1.
> > +             */
> > +            if (hcr_routing ||
> > +                (cur_el == 2 && !(env->cp15.scr_el3 & SCR_RW))) {
> > +                /* If HCR.FMO/IMO is set or we already in EL2 and it is
> not
> > +                 * configured to be AArch64 then route to EL2.
> > +                 */
> > +                target_el = 2;
> > +            }
> > +        }
> > +    } else {
> > +        /* EL3 in Aarch32 */
> > +        if (secure) {
> > +            /* If coming from secure always route to EL3 */
> > +            target_el = 3;
> > +        } else if (hcr_routing || cur_el == 2) {
> > +            /* If HCR.FMO/IMO is set or we are already EL2 then route
> to EL2 */
> > +            target_el = 2;
> > +        }
> > +    }
> > +
> > +    return target_el;
> > +}
> > +
> > +/*
> >   * Determine the target EL for a given exception type.
> >   */
> >  unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
> > @@ -3774,14 +3854,8 @@ unsigned int arm_excp_target_el(CPUState *cs,
> unsigned int excp_idx)
> >      ARMCPU *cpu = ARM_CPU(cs);
> >      CPUARMState *env = &cpu->env;
> >      unsigned int cur_el = arm_current_el(env);
> > -    unsigned int target_el;
> > -    /* FIXME: Use actual secure state.  */
> > -    bool secure = false;
> > -
> > -    if (!env->aarch64) {
> > -        /* TODO: Add EL2 and 3 exception handling for AArch32.  */
> > -        return 1;
> > -    }
> > +    unsigned int target_el = 1;
> > +    bool secure = arm_is_secure(env);
> >
> >      switch (excp_idx) {
> >      case EXCP_HVC:
> > @@ -3793,19 +3867,8 @@ unsigned int arm_excp_target_el(CPUState *cs,
> unsigned int excp_idx)
> >          break;
> >      case EXCP_FIQ:
> >      case EXCP_IRQ:
> > -    {
> > -        const uint64_t hcr_mask = excp_idx == EXCP_FIQ ? HCR_FMO :
> HCR_IMO;
> > -        const uint32_t scr_mask = excp_idx == EXCP_FIQ ? SCR_FIQ :
> SCR_IRQ;
> > -
> > -        target_el = 1;
> > -        if (!secure && (env->cp15.hcr_el2 & hcr_mask)) {
> > -            target_el = 2;
> > -        }
> > -        if (env->cp15.scr_el3 & scr_mask) {
> > -            target_el = 3;
> > -        }
> > +        target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el,
> secure);
> >          break;
> > -    }
> >      case EXCP_VIRQ:
> >      case EXCP_VFIQ:
> >          target_el = 1;
> > --
> > 1.8.3.2
> >
>
>
> thanks
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 10060 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 09/33] target-arm: add macros to access banked registers
  2014-10-06 16:09   ` Peter Maydell
@ 2014-10-07  4:02     ` Greg Bellows
  2014-10-07  6:54       ` Peter Maydell
  0 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-10-07  4:02 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Sergey Fedorov, Sergey Fedorov, QEMU Developers, Fabian Aggeler,
	Edgar E. Iglesias

[-- Attachment #1: Type: text/plain, Size: 4614 bytes --]

Right, we need the macros to do string concatenation so they have to be
macros.  That combination occurs 3 times from a quick look.  I agree that
it may be cumbersome to try and invent a name.

Anything to do on this?

On 6 October 2014 11:09, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> > From: Fabian Aggeler <aggelerf@ethz.ch>
> >
> > 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.
> >
> > - A32_BANKED macros are used for choosing the banked register based on
> provided
> >   input security argument.  This macro is used to choose the bank during
> >   translation of MRC/MCR instructions that are dependent on something
> other
> >   than the current secure state.
> > - A32_BANKED_CURRENT macros are used for choosing the banked register
> based on
> >   current secure state.  This is NOT to be used for choosing the bank
> used
> >   during translation as it breaks monitor mode.
> >
> > 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.fedorov@samsung.com>
> > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> >
> > ----------
> > v4 -> v5
> > - Cleaned-up macros to try and alleviate misuse.  Made A32_BANKED macros
> take
> >   secure arg indicator rather than relying on USE_SECURE_REG.
> Incorporated the
> >   A32_BANKED macros into the A32_BANKED_CURRENT.  CURRENT is now the
> only one
> >   that automatically chooses based on current secure state.
> > ---
> >  target-arm/cpu.h | 36 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 36 insertions(+)
> >
> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > index 601f8fe..c58fdf5 100644
> > --- a/target-arm/cpu.h
> > +++ b/target-arm/cpu.h
> > @@ -807,6 +807,42 @@ static inline bool arm_el_is_aa64(CPUARMState *env,
> int el)
> >      return arm_feature(env, ARM_FEATURE_AARCH64);
> >  }
> >
> > +/* Macro for determing whether to use the secure or non-secure bank of
> a CP
> > + * register.  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))
>
> Better to use an inline function for this rather than a macro,
> I think.
>
> > +
> > +/* Macros for accessing a specified CP register bank */
> > +#define A32_BANKED_REG_GET(_env, _regname, _secure)    \
> > +    ((_secure) ? (_env)->cp15._regname##_s : (_env)->cp15._regname##_ns)
> > +
> > +#define A32_BANKED_REG_SET(_env, _regname, _secure, _val)   \
> > +    do {                                                \
> > +        if (_secure) {                                   \
> > +            (_env)->cp15._regname##_s = (_val);            \
> > +        } else {                                        \
> > +            (_env)->cp15._regname##_ns = (_val);           \
> > +        }                                               \
> > +    } while (0)
> > +
> > +/* Macros for automatically accessing a specific CP register bank
> depending on
> > + * the current secure state of the system.  These macros are not
> intended for
> > + * supporting instruction translation reads/writes as these are
> dependent
> > + * solely on the SCR.NS bit and not the mode.
> > + */
> > +#define A32_BANKED_CURRENT_REG_GET(_env, _regname)        \
> > +    A32_BANKED_REG_GET((_env), _regname,                \
> > +                       ((!arm_el_is_aa64((_env), 3) &&
> arm_is_secure(_env))))
> > +
> > +#define A32_BANKED_CURRENT_REG_SET(_env, _regname, _val)
>        \
> > +    A32_BANKED_REG_SET((_env), _regname,
>     \
> > +                       ((!arm_el_is_aa64((_env), 3) &&
> arm_is_secure(_env))),  \
> > +                       (_val))
> > +
>
> ...though these all have to be macros because of the regname handling.
>
> (Do we use "!arm_el_is_aa64((env), 3) && arm_is_secure(env)"
> often enough to make it worth a utility function? I can't
> think of a good name though, so maybe not...)
>
> thanks
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 6156 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 10/33] target-arm: add non-secure Translation Block flag
  2014-10-06 18:10     ` Sergey Fedorov
@ 2014-10-07  4:21       ` Greg Bellows
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-10-07  4:21 UTC (permalink / raw)
  To: Sergey Fedorov
  Cc: Peter Maydell, Sergey Fedorov, QEMU Developers, Fabian Aggeler,
	Edgar E. Iglesias

[-- Attachment #1: Type: text/plain, Size: 6781 bytes --]

On 6 October 2014 13:10, Sergey Fedorov <serge.fdrv@gmail.com> wrote:

> On 06.10.2014 09:13, Peter Maydell wrote:
> > On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org>
> wrote:
> >> From: Sergey Fedorov <s.fedorov@samsung.com>
> >>
> >> This patch is based on idea found in patch at
> >> git://github.com/jowinter/qemu-trustzone.git
> >> f3d955c6c0ed8c46bc0eb10b634201032a651dd2 by
> >> Johannes Winter <johannes.winter@iaik.tugraz.at>.
> >>
> >> This flag prevents QEMU from executing TCG code generated for other CPU
> >> security state. It also allows to generate different TCG code depending
> on
> >> CPU secure state.
> > This doesn't quite seem to line up with the code:
> > the commit message says the flag is for the CPU's
> > current security state, but the code is using the
> > "which register bank" setting.
>
> Right, the original patch used "!arm_is_secure(env)" as a condition for
> setting this flag. But that was changed at some point without correcting
> commit message.
>
>
Yeah, that was my bad.  This had to be fixed as code generated for monitor
mode would always use secure banks.

Comment fixed in v6.


> >
> >> 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>
> >>
> >> ----------
> >> v4 -> v5
> >> - Merge changes
> >> - Fixed issue where TB secure state flag was incorrectly being set
> based on
> >>   secure state rather than NS setting.  This caused an issue where
> monitor mode
> >>   MRC/MCR accesses were always secure rather than being based on NS bit
> >>   setting.
> >> - Added separate 64/32 TB secure state flags
> >> - Unconditionalized the setting of the DC ns bit
> >> - Removed IS_NS macro and replaced with direct usage.
> >> ---
> >>  target-arm/cpu.h           | 14 ++++++++++++++
> >>  target-arm/translate-a64.c |  1 +
> >>  target-arm/translate.c     |  1 +
> >>  target-arm/translate.h     |  1 +
> >>  4 files changed, 17 insertions(+)
> >>
> >> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> >> index c58fdf5..1700676 100644
> >> --- a/target-arm/cpu.h
> >> +++ b/target-arm/cpu.h
> >> @@ -1528,6 +1528,8 @@ static inline bool
> arm_singlestep_active(CPUARMState *env)
> >>   */
> >>  #define ARM_TBFLAG_XSCALE_CPAR_SHIFT 20
> >>  #define ARM_TBFLAG_XSCALE_CPAR_MASK (3 << ARM_TBFLAG_XSCALE_CPAR_SHIFT)
> >> +#define ARM_TBFLAG_NS_SHIFT         22
> >> +#define ARM_TBFLAG_NS_MASK          (1 << ARM_TBFLAG_NS_SHIFT)
> >>
> >>  /* Bit usage when in AArch64 state */
> >>  #define ARM_TBFLAG_AA64_EL_SHIFT    0
> >> @@ -1538,6 +1540,8 @@ static inline bool
> arm_singlestep_active(CPUARMState *env)
> >>  #define ARM_TBFLAG_AA64_SS_ACTIVE_MASK (1 <<
> ARM_TBFLAG_AA64_SS_ACTIVE_SHIFT)
> >>  #define ARM_TBFLAG_AA64_PSTATE_SS_SHIFT 4
> >>  #define ARM_TBFLAG_AA64_PSTATE_SS_MASK (1 <<
> ARM_TBFLAG_AA64_PSTATE_SS_SHIFT)
> >> +#define ARM_TBFLAG_AA64_NS_SHIFT    5
> >> +#define ARM_TBFLAG_AA64_NS_MASK     (1 << ARM_TBFLAG_AA64_NS_SHIFT)
> >>
> >>  /* some convenience accessor macros */
> >>  #define ARM_TBFLAG_AARCH64_STATE(F) \
> >> @@ -1572,6 +1576,10 @@ static inline bool
> arm_singlestep_active(CPUARMState *env)
> >>      (((F) & ARM_TBFLAG_AA64_SS_ACTIVE_MASK) >>
> ARM_TBFLAG_AA64_SS_ACTIVE_SHIFT)
> >>  #define ARM_TBFLAG_AA64_PSTATE_SS(F) \
> >>      (((F) & ARM_TBFLAG_AA64_PSTATE_SS_MASK) >>
> ARM_TBFLAG_AA64_PSTATE_SS_SHIFT)
> >> +#define ARM_TBFLAG_NS(F) \
> >> +    (((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT)
> >> +#define ARM_TBFLAG_AA64_NS(F) \
> >> +    (((F) & ARM_TBFLAG_AA64_NS_MASK) >> ARM_TBFLAG_AA64_NS_SHIFT)
> >>
> >>  static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong
> *pc,
> >>                                          target_ulong *cs_base, int
> *flags)
> >> @@ -1605,6 +1613,9 @@ static inline void
> cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
> >>                  *flags |= ARM_TBFLAG_AA64_PSTATE_SS_MASK;
> >>              }
> >>          }
> >> +        if (!(USE_SECURE_REG(env))) {
> >> +            *flags |= ARM_TBFLAG_AA64_NS_MASK;
> >> +        }
> > What's this for? If we're in AArch64 mode then we know that
> > EL3 (if it exists) must also be AArch64, and so USE_SECURE_REG
> > always returns false...
>

True, this was a leftover change from when it was a call to
arm_is_secure(), which also was likely unneeded..  Plus if we are AA64 then
we don't care about banks, so we can probably just remove the 64-bit
macros.

Removed from v6


> >
> >>      } else {
> >>          int privmode;
> >>          *pc = env->regs[15];
> >> @@ -1621,6 +1632,9 @@ static inline void
> cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
> >>          if (privmode) {
> >>              *flags |= ARM_TBFLAG_PRIV_MASK;
> >>          }
> >> +        if (!(USE_SECURE_REG(env))) {
> >> +            *flags |= ARM_TBFLAG_NS_MASK;
> >> +        }
> >>          if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
> >>              || arm_el_is_aa64(env, 1)) {
> >>              *flags |= ARM_TBFLAG_VFPEN_MASK;
> >> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> >> index f53dc0f..dfc8c58 100644
> >> --- a/target-arm/translate-a64.c
> >> +++ b/target-arm/translate-a64.c
> >> @@ -10926,6 +10926,7 @@ void gen_intermediate_code_internal_a64(ARMCPU
> *cpu,
> >>  #if !defined(CONFIG_USER_ONLY)
> >>      dc->user = (ARM_TBFLAG_AA64_EL(tb->flags) == 0);
> >>  #endif
> >> +    dc->ns = ARM_TBFLAG_AA64_NS(tb->flags);
> >>      dc->cpacr_fpen = ARM_TBFLAG_AA64_FPEN(tb->flags);
> >>      dc->vec_len = 0;
> >>      dc->vec_stride = 0;
> >> diff --git a/target-arm/translate.c b/target-arm/translate.c
> >> index 3f3ddfb..5e1d677 100644
> >> --- a/target-arm/translate.c
> >> +++ b/target-arm/translate.c
> >> @@ -10958,6 +10958,7 @@ static inline void
> gen_intermediate_code_internal(ARMCPU *cpu,
> >>  #if !defined(CONFIG_USER_ONLY)
> >>      dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
> >>  #endif
> >> +    dc->ns = ARM_TBFLAG_NS(tb->flags);
> >>      dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags);
> >>      dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
> >>      dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
> >> diff --git a/target-arm/translate.h b/target-arm/translate.h
> >> index 85c6f9d..4f9892b 100644
> >> --- a/target-arm/translate.h
> >> +++ b/target-arm/translate.h
> >> @@ -20,6 +20,7 @@ typedef struct DisasContext {
> >>  #if !defined(CONFIG_USER_ONLY)
> >>      int user;
> >>  #endif
> >> +    bool ns;
> > This could use a brief comment explaining what it indicates.
>

Commented added in v6


> >
> >>      bool cpacr_fpen; /* FP enabled via CPACR.FPEN */
> >>      bool vfp_enabled; /* FP enabled via FPSCR.EN */
> >>      int vec_len;
> >> --
> >> 1.8.3.2
>
>

[-- Attachment #2: Type: text/html, Size: 9954 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 11/33] target-arm: arrayfying fieldoffset for banking
  2014-10-06 16:19   ` Peter Maydell
@ 2014-10-07  5:06     ` Greg Bellows
  2014-10-07  7:12       ` Peter Maydell
  0 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-10-07  5:06 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

[-- Attachment #1: Type: text/plain, Size: 8055 bytes --]

On 6 October 2014 11:19, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> > From: Fabian Aggeler <aggelerf@ethz.ch>
> >
> > Prepare ARMCPRegInfo to support specifying two fieldoffsets per
> > register definition. This will allow us to keep one register
> > definition for banked registers (different offsets for secure/
> > non-secure world).
> >
> > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> >
> > ----------
> > v4 -> v5
> > - Added ARM CP register secure and non-secure bank flags
> > - Added setting of secure and non-secure flags furing registration
> > ---
> >  target-arm/cpu.h    | 23 +++++++++++++++-----
> >  target-arm/helper.c | 60
> +++++++++++++++++++++++++++++++++++++++++------------
> >  2 files changed, 65 insertions(+), 18 deletions(-)
> >
> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > index 1700676..9681d45 100644
> > --- a/target-arm/cpu.h
> > +++ b/target-arm/cpu.h
> > @@ -958,10 +958,12 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t
> cpregid)
> >  #define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8))
> >  #define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | (5 << 8))
> >  #define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
> > +#define ARM_CP_BANK_S   (1 << 16)
> > +#define ARM_CP_BANK_NS  (2 << 16)
>
> I thought we were going to put these flags into a reginfo->secure
> field? Mixing them into the 'type' bits seems unnecessarily
> confusing to me.
>

Hmmm... that's not how I interpreted our discussion.  We discussed having
BANK_ flags which I figured we were talking about the existing flags.  So,
you are thinking that the "secure" field becomes a separate flags, so we
would have 2 flags fields.  Not sure that is any less confusing, maybe more
because then you have to worry about the flags being put in the right place.


>
> >  /* Used only as a terminator for ARMCPRegInfo lists */
> > -#define ARM_CP_SENTINEL 0xffff
> > +#define ARM_CP_SENTINEL 0xffffff
> >  /* Mask of only the flag bits in a type field */
> > -#define ARM_CP_FLAG_MASK 0x7f
> > +#define ARM_CP_FLAG_MASK 0x3007f
> >
> >  /* Valid values for ARMCPRegInfo state field, indicating which of
> >   * the AArch32 and AArch64 execution states this register is visible in.
> > @@ -1096,6 +1098,7 @@ struct ARMCPRegInfo {
> >      uint8_t opc0;
> >      uint8_t opc1;
> >      uint8_t opc2;
> > +
>
> Stray whitespace change.
>

Fixed in v6


>
> >      /* Execution state in which this register is visible:
> ARM_CP_STATE_* */
> >      int state;
> >      /* Register type: ARM_CP_* bits/values */
> > @@ -1111,12 +1114,22 @@ struct ARMCPRegInfo {
> >       * fieldoffset is non-zero, the reset value of the register.
> >       */
> >      uint64_t resetvalue;
> > -    /* Offset of the field in CPUARMState for this register. This is not
> > -     * needed if either:
> > +    /* Offsets of the fields (secure/non-secure) in CPUARMState for this
> > +     * register. The array will be accessed by the ns bit which means
> the
> > +     * secure instance has to be at [0] while the non-secure instance
> must be
> > +     * at [1]. If a register is not banked .fieldoffset can be used,
> which maps
> > +     * to the non-secure bank.
> > +     * This is not needed if either:
> >       *  1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
> >       *  2. both readfn and writefn are specified
> >       */
> > -    ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
> > +    union { /* offsetof(CPUARMState, field) */
> > +        struct {
> > +            ptrdiff_t fieldoffset_padding;
> > +            ptrdiff_t fieldoffset;
>
> ...why is the padding field first? Given that we always write
> fieldoffset when we put the banked versions into the hash table
> I don't think it should matter, should it?
>

The padding aligns the existing fieldoffset with the non-secure bank.  For
correctness, I added the padding to truly align the default fieldoffset
with the non-secure bank.  I don't think it matters otherwise.

>
> > +        };
> > +        ptrdiff_t bank_fieldoffsets[2];
> > +    };
> >      /* Function for making any access checks for this register in
> addition to
> >       * those specified by the 'access' permissions bits. If NULL, no
> extra
> >       * checks required. The access check is performed at runtime, not at
> > diff --git a/target-arm/helper.c b/target-arm/helper.c
> > index a10f459..ab38b68 100644
> > --- a/target-arm/helper.c
> > +++ b/target-arm/helper.c
> > @@ -3296,22 +3296,56 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu,
> const ARMCPRegInfo *r,
> >      uint32_t *key = g_new(uint32_t, 1);
> >      ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
> >      int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
> > -    if (r->state == ARM_CP_STATE_BOTH && state == ARM_CP_STATE_AA32) {
> > -        /* The AArch32 view of a shared register sees the lower 32 bits
> > -         * of a 64 bit backing field. It is not migratable as the
> AArch64
> > -         * view handles that. AArch64 also handles reset.
> > -         * We assume it is a cp15 register if the .cp field is left
> unset.
> > -         */
> > -        if (r2->cp == 0) {
> > -            r2->cp = 15;
> > +
> > +    if (state == ARM_CP_STATE_AA32) {
> > +        /* Clear the secure state flags and set based on incoming nsbit
> */
> > +        r2->type &= ~(ARM_CP_BANK_S | ARM_CP_BANK_NS);
> > +        r2->type |= ARM_CP_BANK_S << nsbit;
> > +
> > +        if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
> > +            /* Register is banked (using both entries in array).
> > +             * Overwriting fieldoffset as the array was only used to
> define
> > +             * banked registers but later only fieldoffset is used.
> > +             */
> > +            r2->fieldoffset = r->bank_fieldoffsets[nsbit];
> > +
> > +            /* If V8 is enabled then we don't need to migrate or reset
> the
> > +             * AArch32 version of the banked registers as this will be
> handled
> > +             * through the AArch64 view.
> > +             * The exception to the above is cpregs with a crn of 13
> > +             * (specifically FCSEIDR and CONTEXTIDR) in which case
> there may
> > +             * not be an AArch64 equivalent for one or either bank so
> migration
> > +             * and reset must be preserved.
> > +             */
> > +            if (arm_feature(&cpu->env, ARM_FEATURE_V8) && r->crn != 13)
> {
> > +                r2->type |= ARM_CP_NO_MIGRATE;
> > +                r2->resetfn = arm_cp_reset_ignore;
> > +            }
> > +        } else if (!nsbit) {
> > +            /* The register is not banked so we only want to allow
> migration of
> > +             * the non-secure instance.
> > +             */
> > +            r2->type |= ARM_CP_NO_MIGRATE;
> > +            r2->resetfn = arm_cp_reset_ignore;
> >          }
> > -        r2->type |= ARM_CP_NO_MIGRATE;
> > -        r2->resetfn = arm_cp_reset_ignore;
> > +
> > +        if (r->state == ARM_CP_STATE_BOTH) {
> > +            /* The AArch32 view of a shared register sees the lower 32
> bits
> > +             * of a 64 bit backing field. It is not migratable as the
> AArch64
> > +             * view handles that. AArch64 also handles reset.
> > +             * We assume it is a cp15 register if the .cp field is left
> unset.
> > +             */
> > +            if (r2->cp == 0) {
> > +                r2->cp = 15;
> > +            }
> > +            r2->type |= ARM_CP_NO_MIGRATE;
> > +            r2->resetfn = arm_cp_reset_ignore;
> >  #ifdef HOST_WORDS_BIGENDIAN
> > -        if (r2->fieldoffset) {
> > -            r2->fieldoffset += sizeof(uint32_t);
> > -        }
> > +            if (r2->fieldoffset) {
> > +                r2->fieldoffset += sizeof(uint32_t);
> > +            }
> >  #endif
> > +        }
> >      }
> >      if (state == ARM_CP_STATE_AA64) {
> >          /* To allow abbreviation of ARMCPRegInfo
> > --
> > 1.8.3.2
> >
>
>
> thanks
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 10690 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 32/33] target-arm: add GDB scr register
  2014-10-06 16:27   ` Peter Maydell
@ 2014-10-07  5:09     ` Greg Bellows
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-10-07  5:09 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

[-- Attachment #1: Type: text/plain, Size: 616 bytes --]

Dropped in v6

On 6 October 2014 11:27, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> > Added the ability to print the scr register like can be done with the
> cpsr.
> >
> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
>
> Not sure you can just arbitrarily add new core registers
> if gdb isn't expecting them, and in any case if we want
> to do this we should probably do it via some more generic
> mechanism than manually adding registers one at a time.
> I recommend you just drop this patch for now.
>
> thanks
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 1089 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 12/33] target-arm: insert Aarch32 cpregs twice into hashtable
  2014-10-06 16:25   ` Peter Maydell
@ 2014-10-07  5:31     ` Greg Bellows
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-10-07  5:31 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

[-- Attachment #1: Type: text/plain, Size: 3120 bytes --]

On 6 October 2014 11:25, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
> > From: Fabian Aggeler <aggelerf@ethz.ch>
> >
> > Prepare for cp register banking by inserting every cp register twice,
> > once for secure world and once for non-secure world.
> >
> > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> >
> > ----------
> > v4 -> v5
> > - Added use of ARM CP secure/non-secure bank flags during register
> processing
> >   in define_one_arm_cp_reg_with_opaque().  We now only register the
> specified
> >   bank if only one flag is specified, otherwise we register both a
> secure and
> >   non-secure instance.
> > ---
> >  target-arm/cpu.h       | 14 +++++++++++---
> >  target-arm/helper.c    | 30 ++++++++++++++++++++++++++----
> >  target-arm/translate.c | 14 +++++++++-----
> >  3 files changed, 46 insertions(+), 12 deletions(-)
> >
> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > index 9681d45..220571c 100644
> > --- a/target-arm/cpu.h
> > +++ b/target-arm/cpu.h
> > @@ -864,6 +864,7 @@ void armv7m_nvic_complete_irq(void *opaque, int irq);
> >   *  Crn, Crm, opc1, opc2 fields
> >   *  32 or 64 bit register (ie is it accessed via MRC/MCR
> >   *    or via MRRC/MCRR?)
> > + *  non-secure/secure bank (Aarch32 only)
>
> ...so if this is an AArch64 register is the bit in the hash
> table key set or clear?
>

The 64-bit hash does not include a S/NS bit, so it defaults to 0.  I'll add
some additional comments to v6.


>
> >   * We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field.
> >   * (In this case crn and opc2 should be zero.)
> >   * For AArch64, there is no 32/64 bit size distinction;
> > @@ -881,9 +882,16 @@ void armv7m_nvic_complete_irq(void *opaque, int
> irq);
> >  #define CP_REG_AA64_SHIFT 28
> >  #define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
> >
> > -#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2)   \
> > -    (((cp) << 16) | ((is64) << 15) | ((crn) << 11) |    \
> > -     ((crm) << 7) | ((opc1) << 3) | (opc2))
> > +/* To enable banking of coprocessor registers depending on ns-bit we
> > + * add a bit to distinguish between secure and non-secure cpregs in the
> > + * hashtable.
> > + */
> > +#define CP_REG_NS_SHIFT 27
> > +#define CP_REG_NS_MASK(nsbit) (nsbit << CP_REG_NS_SHIFT)
>
> Bit 27 is already used, as part of the COPROC field.
> There's a reason the AA64 bit is 28...
>

Yes, good catch.  I think I originally had it as bit 31. but went with what
Fabian had.  I will bump it up for v6.


>
> > +
> > +#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2, ns)   \
> > +    (CP_REG_NS_MASK(ns) | ((cp) << 16) | ((is64) << 15) |   \
> > +     ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
>
> Doesn't this break KVM's accessing of the hashtable?
> You probably need to make kvm_to_cpreg_id OR in the NS
> bit as appropriate, and cpreg_to_kvm_id mask it out, since
> if we're using KVM then we're always non-secure.
>
> Not sure if it breaks KVM, I'll have to look into it.


> thanks
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 4658 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 09/33] target-arm: add macros to access banked registers
  2014-10-07  4:02     ` Greg Bellows
@ 2014-10-07  6:54       ` Peter Maydell
  2014-10-07 17:49         ` Greg Bellows
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-10-07  6:54 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, Sergey Fedorov, QEMU Developers, Fabian Aggeler,
	Edgar E. Iglesias

On 7 October 2014 05:02, Greg Bellows <greg.bellows@linaro.org> wrote:
> Right, we need the macros to do string concatenation so they have to be
> macros.  That combination occurs 3 times from a quick look.  I agree that it
> may be cumbersome to try and invent a name.
>
> Anything to do on this?

Make USE_SECURE_REG into an inline function (with a
decapitalised name), leave the rest.

-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 07/33] target-arm: extend async excp masking
  2014-10-07  3:16     ` Greg Bellows
@ 2014-10-07  7:03       ` Peter Maydell
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-10-07  7:03 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 7 October 2014 04:16, Greg Bellows <greg.bellows@linaro.org> wrote:
>
>
> On 6 October 2014 10:53, Peter Maydell <peter.maydell@linaro.org> wrote:

>> >      switch (excp_idx) {
>> >      case EXCP_FIQ:
>> > -        if (irq_can_hyp && (env->cp15.hcr_el2 & HCR_FMO)) {
>> > -            return true;
>> > +        if (arm_feature(env, ARM_FEATURE_EL3) && arm_el_is_aa64(env,
>> > 3)) {
>> > +            /* If EL3 is using Aarch64 and FIQs are routed to EL3
>> > masking is
>> > +             * ignored in all exception levels except EL3.
>> > +             */
>> > +            if ((env->cp15.scr_el3 & SCR_FIQ) && cur_el < 3) {
>> > +                return true;
>> > +            }
>> > +            /* If we are in EL3 but FIQs are not routed to EL3 the
>> > exception
>> > +             * is not taken but remains pending.
>> > +             */
>> > +            if (!(env->cp15.scr_el3 & SCR_FIQ) && cur_el == 3) {
>> > +                return false;
>> > +            }
>> > +        }
>>
>> This is all kind of confusing. What is the division of work
>> between this function and arm_phys_excp_target_el(),
>> conceptually? Why isn't "we're in EL3 but FIQs aren't going
>> to EL3" handled by the "cur_el > arm_excp_target_el()" check
>> above, for instance?
>
>
> I inherited the code, so I can't speak entirely to the motivation.  I'm
> guessing that the code closely follows the ARM spec for masking.  Certainly
> the code could be divided differently, but functionally it works so I saw no
> need to change it.  I can certainly adjust the two functions if you would
> prefer to isolate the routing/target function.

My point is really that it's hard to review if it's not
clear how the functions fit together and why code is in
one place and not another. I'm not asking for changes to
the code so much as better explication of why it is the way
it is. I guess I need to sit down with the ARM ARM and work
through whether it's putting things in the right place, then.

-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 11/33] target-arm: arrayfying fieldoffset for banking
  2014-10-07  5:06     ` Greg Bellows
@ 2014-10-07  7:12       ` Peter Maydell
  2014-10-07 21:50         ` Greg Bellows
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-10-07  7:12 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 7 October 2014 06:06, Greg Bellows <greg.bellows@linaro.org> wrote:
>
>
> On 6 October 2014 11:19, Peter Maydell <peter.maydell@linaro.org> wrote:
>>
>> On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org> wrote:
>> > From: Fabian Aggeler <aggelerf@ethz.ch>
>> >
>> > Prepare ARMCPRegInfo to support specifying two fieldoffsets per
>> > register definition. This will allow us to keep one register
>> > definition for banked registers (different offsets for secure/
>> > non-secure world).
>> >
>> > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
>> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
>> >
>> > ----------
>> > v4 -> v5
>> > - Added ARM CP register secure and non-secure bank flags
>> > - Added setting of secure and non-secure flags furing registration
>> > ---
>> >  target-arm/cpu.h    | 23 +++++++++++++++-----
>> >  target-arm/helper.c | 60
>> > +++++++++++++++++++++++++++++++++++++++++------------
>> >  2 files changed, 65 insertions(+), 18 deletions(-)
>> >
>> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
>> > index 1700676..9681d45 100644
>> > --- a/target-arm/cpu.h
>> > +++ b/target-arm/cpu.h
>> > @@ -958,10 +958,12 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t
>> > cpregid)
>> >  #define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8))
>> >  #define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | (5 << 8))
>> >  #define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
>> > +#define ARM_CP_BANK_S   (1 << 16)
>> > +#define ARM_CP_BANK_NS  (2 << 16)
>>
>> I thought we were going to put these flags into a reginfo->secure
>> field? Mixing them into the 'type' bits seems unnecessarily
>> confusing to me.
>
>
> Hmmm... that's not how I interpreted our discussion.  We discussed having
> BANK_ flags which I figured we were talking about the existing flags.  So,
> you are thinking that the "secure" field becomes a separate flags, so we
> would have 2 flags fields.  Not sure that is any less confusing, maybe more
> because then you have to worry about the flags being put in the right place.

Sorry for any confusion. My intention was that the previous
'secure' field which just had a 1/0 value should have flags
in it instead. Note that we don't have a generic "flags" field;
we have a "type" field which indicates properties of how the
register itself behaves (unrelated to what encodings and
states it is visible from), we have a "state" field which has
the flags for whether it is visible from AArch32 or AArch64
or both, and we have an "access" field which has flags for
whether it is readable or writable from various exception
levels. I think having a separate "secure" field is easier
to understand and fits into that approach.



>> > -    ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
>> > +    union { /* offsetof(CPUARMState, field) */
>> > +        struct {
>> > +            ptrdiff_t fieldoffset_padding;
>> > +            ptrdiff_t fieldoffset;
>>
>> ...why is the padding field first? Given that we always write
>> fieldoffset when we put the banked versions into the hash table
>> I don't think it should matter, should it?
>
>
> The padding aligns the existing fieldoffset with the non-secure bank.  For
> correctness, I added the padding to truly align the default fieldoffset with
> the non-secure bank.  I don't think it matters otherwise.

But do we ever write to "fieldoffset" and then read from
"bank_fieldoffsets[1]" (or vice versa)? If we don't then it's
not necessary for correctness at all... (If we do do that, where
does it happen?)

thanks
-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 09/33] target-arm: add macros to access banked registers
  2014-10-07  6:54       ` Peter Maydell
@ 2014-10-07 17:49         ` Greg Bellows
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-10-07 17:49 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Sergey Fedorov, Sergey Fedorov, QEMU Developers, Fabian Aggeler,
	Edgar E. Iglesias

[-- Attachment #1: Type: text/plain, Size: 511 bytes --]

Converted in v6

On 7 October 2014 01:54, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 7 October 2014 05:02, Greg Bellows <greg.bellows@linaro.org> wrote:
> > Right, we need the macros to do string concatenation so they have to be
> > macros.  That combination occurs 3 times from a quick look.  I agree
> that it
> > may be cumbersome to try and invent a name.
> >
> > Anything to do on this?
>
> Make USE_SECURE_REG into an inline function (with a
> decapitalised name), leave the rest.
>
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 931 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 11/33] target-arm: arrayfying fieldoffset for banking
  2014-10-07  7:12       ` Peter Maydell
@ 2014-10-07 21:50         ` Greg Bellows
  2014-10-07 22:38           ` Peter Maydell
  0 siblings, 1 reply; 83+ messages in thread
From: Greg Bellows @ 2014-10-07 21:50 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

[-- Attachment #1: Type: text/plain, Size: 4304 bytes --]

On 7 October 2014 02:12, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 7 October 2014 06:06, Greg Bellows <greg.bellows@linaro.org> wrote:
> >
> >
> > On 6 October 2014 11:19, Peter Maydell <peter.maydell@linaro.org> wrote:
> >>
> >> On 30 September 2014 22:49, Greg Bellows <greg.bellows@linaro.org>
> wrote:
> >> > From: Fabian Aggeler <aggelerf@ethz.ch>
> >> >
> >> > Prepare ARMCPRegInfo to support specifying two fieldoffsets per
> >> > register definition. This will allow us to keep one register
> >> > definition for banked registers (different offsets for secure/
> >> > non-secure world).
> >> >
> >> > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> >> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> >> >
> >> > ----------
> >> > v4 -> v5
> >> > - Added ARM CP register secure and non-secure bank flags
> >> > - Added setting of secure and non-secure flags furing registration
> >> > ---
> >> >  target-arm/cpu.h    | 23 +++++++++++++++-----
> >> >  target-arm/helper.c | 60
> >> > +++++++++++++++++++++++++++++++++++++++++------------
> >> >  2 files changed, 65 insertions(+), 18 deletions(-)
> >> >
> >> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> >> > index 1700676..9681d45 100644
> >> > --- a/target-arm/cpu.h
> >> > +++ b/target-arm/cpu.h
> >> > @@ -958,10 +958,12 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t
> >> > cpregid)
> >> >  #define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8))
> >> >  #define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | (5 << 8))
> >> >  #define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
> >> > +#define ARM_CP_BANK_S   (1 << 16)
> >> > +#define ARM_CP_BANK_NS  (2 << 16)
> >>
> >> I thought we were going to put these flags into a reginfo->secure
> >> field? Mixing them into the 'type' bits seems unnecessarily
> >> confusing to me.
> >
> >
> > Hmmm... that's not how I interpreted our discussion.  We discussed having
> > BANK_ flags which I figured we were talking about the existing flags.
> So,
> > you are thinking that the "secure" field becomes a separate flags, so we
> > would have 2 flags fields.  Not sure that is any less confusing, maybe
> more
> > because then you have to worry about the flags being put in the right
> place.
>
> Sorry for any confusion. My intention was that the previous
> 'secure' field which just had a 1/0 value should have flags
> in it instead. Note that we don't have a generic "flags" field;
> we have a "type" field which indicates properties of how the
> register itself behaves (unrelated to what encodings and
> states it is visible from), we have a "state" field which has
> the flags for whether it is visible from AArch32 or AArch64
> or both, and we have an "access" field which has flags for
> whether it is readable or writable from various exception
> levels. I think having a separate "secure" field is easier
> to understand and fits into that approach.
>
>
Fixed in v6 by separating out the security flags and adding a secure field.


>
>
> >> > -    ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
> >> > +    union { /* offsetof(CPUARMState, field) */
> >> > +        struct {
> >> > +            ptrdiff_t fieldoffset_padding;
> >> > +            ptrdiff_t fieldoffset;
> >>
> >> ...why is the padding field first? Given that we always write
> >> fieldoffset when we put the banked versions into the hash table
> >> I don't think it should matter, should it?
> >
> >
> > The padding aligns the existing fieldoffset with the non-secure bank.
> For
> > correctness, I added the padding to truly align the default fieldoffset
> with
> > the non-secure bank.  I don't think it matters otherwise.
>
> But do we ever write to "fieldoffset" and then read from
> "bank_fieldoffsets[1]" (or vice versa)? If we don't then it's
> not necessary for correctness at all... (If we do do that, where
> does it happen?)
>
>
In short, No.  The only time we use bank_fieldoffset is during registration
and that is to fixup fieldoffset to contain the correct bank offset.
Otherwise, we always use fieldoffset when determining the register offset.

I'm still trying to wrap my head around it, but I believe there are cases
where we use a different register set depending on whether a given EL is 32
or 64-bit.  I need to spend a bit more time working through the scenarios.


> thanks
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 6190 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 11/33] target-arm: arrayfying fieldoffset for banking
  2014-10-07 21:50         ` Greg Bellows
@ 2014-10-07 22:38           ` Peter Maydell
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-10-07 22:38 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 7 October 2014 22:50, Greg Bellows <greg.bellows@linaro.org> wrote:
> I'm still trying to wrap my head around it, but I believe there are
> cases where we use a different register set depending on whether a
> given EL is 32 or 64-bit.

Well, if an EL is 64-bit then it sees (effectively) a totally
different register set anyway. We merge together the STATE_AA64
and STATE_AA32 reginfo structures in the sourcecode[*], but the
process of populating the hashtable effectively creates two
disjoint sets of register info, one for STATE_AA32 and one for
STATE_AA64. The 64-bit registers may have the same underlying
state as one or more 32-bit registers (which the ARM ARM refers
to as the registers being "architecturally mapped" to each other,
and which we typically implement by pointing the fieldoffsets to
the same underlying uint64_t), but they're not strictly speaking
the same registers.

[*] This merging is purely for convenience and to avoid having
to write out multiple near-identical reginfo definitions: it's
always possible to write out a non-merged equivalent pair of
reginfo fields. Similarly it's always going to be possible to
write out separate (STATE_AA64, STATE_AA32 BANK_S, STATE_AA32 BANK_NS)
versions, we just want to be able to collapse them together
into one reginfo most of the time.

The other thing to watch out for is differences in what
secure-SVC/etc code sees depending on whether EL3 is 32 bit
or 64 bit. For instance, if EL3 is 32 bit then the SCTLR is banked,
and all the non-secure privileged modes execute at EL1 and
see SCTLR(NS), while the secure privileged modes execute at
EL3 and see SCTLR(S). However if EL3 is 64 bit then the SCTLR
is not banked, and both secure and non-secure 32 bit
privileged modes execute at EL1 and see SCTLR(NS). (It's the
responsibility of a 64-bit EL3 monitor to swap the contents of the
EL1 registers when it switches between Secure and Nonsecure OSes.)
But the USE_SECURE_REG() macro handles this correctly, so we should
be good there.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function
  2014-10-06 21:07           ` Peter Maydell
@ 2014-10-08 19:33             ` Greg Bellows
  0 siblings, 0 replies; 83+ messages in thread
From: Greg Bellows @ 2014-10-08 19:33 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Sergey Fedorov, Sergey Fedorov, QEMU Developers, Fabian Aggeler,
	Edgar E. Iglesias

[-- Attachment #1: Type: text/plain, Size: 760 bytes --]

Unfortunately, the arm_is_secure*() functions cannot be moved either as
they are used within cpu.h.

Greg

On 6 October 2014 16:07, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 6 October 2014 21:47, Greg Bellows <greg.bellows@linaro.org> wrote:
> >
> >
> > On 6 October 2014 15:07, Peter Maydell <peter.maydell@linaro.org> wrote:
> >> You should use is_a64() rather than directly looking at
> >> env->aarch64, incidentally.
> >
> >
> > Since I am touching arm_current_el(), should I go ahead and fix it to use
> > is_a64() as well?
>
> Optional.
>
> > I'll move in v6.  Should I also go ahead and move arm_current_el() to
> > internals.h as well since I am touching it?
>
> No. Let's try to keep the scope of this patchset under control.
>
> -- PMM
>

[-- Attachment #2: Type: text/html, Size: 1362 bytes --]

^ permalink raw reply	[flat|nested] 83+ messages in thread

end of thread, other threads:[~2014-10-08 19:33 UTC | newest]

Thread overview: 83+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-30 21:49 [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 01/33] target-arm: increase arrays of registers R13 & R14 Greg Bellows
2014-10-06 14:48   ` Peter Maydell
2014-10-06 19:21   ` Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function Greg Bellows
2014-09-30 22:50   ` Edgar E. Iglesias
2014-10-01 12:53     ` Greg Bellows
2014-10-06 14:56   ` Peter Maydell
2014-10-06 17:57     ` Sergey Fedorov
2014-10-06 18:01       ` Peter Maydell
2014-10-06 19:45     ` Greg Bellows
2014-10-06 20:07       ` Peter Maydell
2014-10-06 20:47         ` Greg Bellows
2014-10-06 21:07           ` Peter Maydell
2014-10-08 19:33             ` Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 03/33] target-arm: reject switching to monitor mode Greg Bellows
2014-10-06 15:02   ` Peter Maydell
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 04/33] target-arm: rename arm_current_pl to arm_current_el Greg Bellows
2014-09-30 22:56   ` Edgar E. Iglesias
2014-10-01 12:54     ` Greg Bellows
2014-10-06 15:10   ` Peter Maydell
2014-10-06 19:55     ` Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 05/33] target-arm: make arm_current_pl() return PL3 Greg Bellows
2014-10-01  1:23   ` Sergey Fedorov
2014-10-01 14:31     ` Greg Bellows
2014-10-06 15:34   ` Peter Maydell
2014-10-06 20:53     ` Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 06/33] target-arm: A32: Emulate the SMC instruction Greg Bellows
2014-10-06 15:46   ` Peter Maydell
2014-10-07  1:56     ` Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 07/33] target-arm: extend async excp masking Greg Bellows
2014-10-06 15:53   ` Peter Maydell
2014-10-07  3:16     ` Greg Bellows
2014-10-07  7:03       ` Peter Maydell
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 08/33] target-arm: add async excp target_el function Greg Bellows
2014-10-06 16:02   ` Peter Maydell
2014-10-07  3:52     ` Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 09/33] target-arm: add macros to access banked registers Greg Bellows
2014-10-06 16:09   ` Peter Maydell
2014-10-07  4:02     ` Greg Bellows
2014-10-07  6:54       ` Peter Maydell
2014-10-07 17:49         ` Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 10/33] target-arm: add non-secure Translation Block flag Greg Bellows
2014-10-06 16:13   ` Peter Maydell
2014-10-06 18:10     ` Sergey Fedorov
2014-10-07  4:21       ` Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 11/33] target-arm: arrayfying fieldoffset for banking Greg Bellows
2014-10-06 16:19   ` Peter Maydell
2014-10-07  5:06     ` Greg Bellows
2014-10-07  7:12       ` Peter Maydell
2014-10-07 21:50         ` Greg Bellows
2014-10-07 22:38           ` Peter Maydell
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 12/33] target-arm: insert Aarch32 cpregs twice into hashtable Greg Bellows
2014-10-06 16:25   ` Peter Maydell
2014-10-07  5:31     ` Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 13/33] target-arm: move Aarch32 SCR into security reglist Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 14/33] target-arm: implement IRQ/FIQ routing to Monitor mode Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 15/33] target-arm: Respect SCR.FW, SCR.AW and SCTLR.NMFI Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 16/33] target-arm: add NSACR register Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 17/33] target-arm: add SDER definition Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 18/33] target-arm: add MVBAR support Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 19/33] target-arm: add SCTLR_EL3 and make SCTLR banked Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 20/33] target-arm: make CSSELR banked Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 21/33] target-arm: add TTBR0_EL3 and make TTBR0/1 banked Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 22/33] target-arm: add TCR_EL3 and make TTBCR banked Greg Bellows
2014-09-30 23:18   ` Edgar E. Iglesias
2014-10-01 13:05     ` Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 23/33] target-arm: make c2_mask and c2_base_mask banked Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 24/33] target-arm: make DACR banked Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 25/33] target-arm: make IFSR banked Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 26/33] target-arm: make DFSR banked Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 27/33] target-arm: make IFAR/DFAR banked Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 28/33] target-arm: make PAR banked Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 29/33] target-arm: make VBAR banked Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 30/33] target-arm: make MAIR0/1 banked Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 31/33] target-arm: make c13 cp regs banked (FCSEIDR, ...) Greg Bellows
2014-10-01 14:30   ` Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 32/33] target-arm: add GDB scr register Greg Bellows
2014-10-06 16:27   ` Peter Maydell
2014-10-07  5:09     ` Greg Bellows
2014-09-30 21:49 ` [Qemu-devel] [PATCH v5 33/33] target-arm: add cpu feature EL3 to CPUs with Security Extensions Greg Bellows
2014-10-06 16:28   ` Peter Maydell
2014-10-06 16:32 ` [Qemu-devel] [PATCH v5 00/33] target-arm: add Security Extensions for CPUs Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.