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

Version 6 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 generic changes from v5 -> v6:
- Removed patch v5 32/33 (add GDB scr register)
- Separated CPREG secure support handling to its own commit
- Addressed review feedback
- Added/fixed comments and commit messages

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

Fabian Aggeler (26):
  target-arm: increase arrays of registers R13 & R14
  target-arm: add arm_is_secure() function
  target-arm: make arm_current_el() return EL3
  target-arm: A32: Emulate the SMC instruction
  target-arm: extend async excp masking
  target-arm: add async excp target_el function
  target-arm: add banked register accessors
  target-arm: add CPREG secure state support
  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 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: add secure state bit to CPREG hash
  target-arm: make MAIR0/1 banked

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

 hw/arm/pxa2xx.c            |   8 +-
 target-arm/cpu.c           |  11 +-
 target-arm/cpu.h           | 518 +++++++++++++++++++++++++++----
 target-arm/helper-a64.c    |   6 +-
 target-arm/helper.c        | 742 ++++++++++++++++++++++++++++++++++-----------
 target-arm/internals.h     |   9 +-
 target-arm/machine.c       |   8 +-
 target-arm/op_helper.c     |  21 +-
 target-arm/translate-a64.c |  16 +-
 target-arm/translate.c     |  60 ++--
 target-arm/translate.h     |   5 +-
 11 files changed, 1107 insertions(+), 297 deletions(-)

--
1.8.3.2

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

* [Qemu-devel] [PATCH v6 01/32] target-arm: increase arrays of registers R13 & R14
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-13 12:31   ` Peter Maydell
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 02/32] target-arm: add arm_is_secure() function Greg Bellows
                   ` (30 subsequent siblings)
  31 siblings, 1 reply; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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>
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

==========

v5 -> v6
- Updated vmstate_arm_cpu versioning from 20 to 21
---
 target-arm/cpu.h     | 4 ++--
 target-arm/machine.c | 8 ++++----
 2 files changed, 6 insertions(+), 6 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..f1c903d 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -222,8 +222,8 @@ static int cpu_post_load(void *opaque, int version_id)
 
 const VMStateDescription vmstate_arm_cpu = {
     .name = "cpu",
-    .version_id = 20,
-    .minimum_version_id = 20,
+    .version_id = 21,
+    .minimum_version_id = 21,
     .pre_save = cpu_pre_save,
     .post_load = cpu_post_load,
     .fields = (VMStateField[]) {
@@ -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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 02/32] target-arm: add arm_is_secure() function
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 01/32] target-arm: increase arrays of registers R13 & R14 Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-13 12:41   ` Peter Maydell
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 03/32] target-arm: reject switching to monitor mode Greg Bellows
                   ` (29 subsequent siblings)
  31 siblings, 1 reply; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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>

==========

v5 -> v6
- Broaden CONFIG_USER conditional
- Merge resulting false returns with common comment
- Globally change Aarch# to AArch#
- Replace direct access of env->aarch64 with is_a64()
---
 target-arm/cpu.h | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 81fffd2..4f6db0f 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -753,6 +753,48 @@ static inline int arm_feature(CPUARMState *env, int feature)
     return (env->features & (1ULL << feature)) != 0;
 }
 
+#if !defined(CONFIG_USER_ONLY)
+/* Return true if exception level below EL3 is in secure state */
+static inline bool arm_is_secure_below_el3(CPUARMState *env)
+{
+    if (arm_feature(env, ARM_FEATURE_EL3)) {
+        return !(env->cp15.scr_el3 & SCR_NS);
+    } else {
+        /* If EL2 is not supported then the secure state is implementation
+         * defined, in which case QEMU defaults to non-secure.
+         */
+        return false;
+    }
+}
+
+/* Return true if the processor is in secure state */
+static inline bool arm_is_secure(CPUARMState *env)
+{
+    if (arm_feature(env, ARM_FEATURE_EL3)) {
+        if (is_a64(env) && extract32(env->pstate, 2, 2) == 3) {
+            /* CPU currently in AArch64 state and EL3 */
+            return true;
+        } else if (!is_a64(env) &&
+                (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
+static inline bool arm_is_secure_below_el3(CPUARMState *env)
+{
+    return false;
+}
+
+static inline bool arm_is_secure(CPUARMState *env)
+{
+    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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 03/32] target-arm: reject switching to monitor mode
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 01/32] target-arm: increase arrays of registers R13 & R14 Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 02/32] target-arm: add arm_is_secure() function Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-13 12:58   ` Peter Maydell
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 04/32] target-arm: rename arm_current_pl to arm_current_el Greg Bellows
                   ` (28 subsequent siblings)
  31 siblings, 1 reply; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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

Reject switching to monitor mode 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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 04/32] target-arm: rename arm_current_pl to arm_current_el
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (2 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 03/32] target-arm: reject switching to monitor mode Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-13 13:00   ` Peter Maydell
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 05/32] target-arm: make arm_current_el() return EL3 Greg Bellows
                   ` (27 subsequent siblings)
  31 siblings, 1 reply; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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>

==========

v5 -> v6
- Renamed DisasContext current_pl field to current_el
- Added comment to arm_current_el on handling v7 PL
- Fixed comments referencing PL
---
 target-arm/cpu.h           | 27 +++++++++++++++------------
 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 | 16 ++++++++--------
 target-arm/translate.c     |  4 ++--
 target-arm/translate.h     |  4 ++--
 8 files changed, 50 insertions(+), 47 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 4f6db0f..149f258 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -986,7 +986,10 @@ 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)
+/* Return the current Exception Level (as per ARMv8 note that this differs
+ * from the ARMv7 Privilege Level).
+ */
+static inline int arm_current_el(CPUARMState *env)
 {
     if (env->aarch64) {
         return extract32(env->pstate, 2, 2);
@@ -996,7 +999,7 @@ static inline int arm_current_pl(CPUARMState *env)
         return 0;
     }
     /* We don't currently implement the Virtualization or TrustZone
-     * extensions, so PL2 and PL3 don't exist for us.
+     * extensions, so EL2 and EL3 don't exist for us.
      */
     return 1;
 }
@@ -1159,10 +1162,10 @@ static inline bool cpreg_field_is_64bit(const ARMCPRegInfo *ri)
     return (ri->state == ARM_CP_STATE_AA64) || (ri->type & ARM_CP_64BIT);
 }
 
-static inline bool cp_access_ok(int current_pl,
+static inline bool cp_access_ok(int current_el,
                                 const ARMCPRegInfo *ri, int isread)
 {
-    return (ri->access >> ((current_pl * 2) + isread)) & 1;
+    return (ri->access >> ((current_el * 2) + isread)) & 1;
 }
 
 /**
@@ -1226,7 +1229,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;
@@ -1298,7 +1301,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;
@@ -1311,7 +1314,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;
@@ -1322,10 +1325,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.
@@ -1455,8 +1458,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
@@ -1492,7 +1495,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..b141452 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1226,7 +1226,7 @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
     int op = op1 << 3 | op2;
     switch (op) {
     case 0x05: /* SPSel */
-        if (s->current_pl == 0) {
+        if (s->current_el == 0) {
             unallocated_encoding(s);
             return;
         }
@@ -1323,7 +1323,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
     }
 
     /* Check access permissions */
-    if (!cp_access_ok(s->current_pl, ri, isread)) {
+    if (!cp_access_ok(s->current_el, ri, isread)) {
         unallocated_encoding(s);
         return;
     }
@@ -1362,7 +1362,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
          * guaranteed to be constant by the tb flags.
          */
         tcg_rt = cpu_reg(s, rt);
-        tcg_gen_movi_i64(tcg_rt, s->current_pl << 2);
+        tcg_gen_movi_i64(tcg_rt, s->current_el << 2);
         return;
     case ARM_CP_DC_ZVA:
         /* Writes clear the aligned block of memory which rt points into. */
@@ -1485,7 +1485,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
             gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16));
             break;
         case 2:
-            if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_pl == 0) {
+            if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el == 0) {
                 unallocated_encoding(s);
                 break;
             }
@@ -1498,7 +1498,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
             gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16));
             break;
         case 3:
-            if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->current_pl == 0) {
+            if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->current_el == 0) {
                 unallocated_encoding(s);
                 break;
             }
@@ -1575,7 +1575,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
         tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
         break;
     case 4: /* ERET */
-        if (s->current_pl == 0) {
+        if (s->current_el == 0) {
             unallocated_encoding(s);
             return;
         }
@@ -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_el = arm_current_el(env);
     dc->features = env->features;
 
     /* Single step state. The code-generation logic here is:
@@ -10951,7 +10951,7 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
     dc->ss_active = ARM_TBFLAG_AA64_SS_ACTIVE(tb->flags);
     dc->pstate_ss = ARM_TBFLAG_AA64_PSTATE_SS(tb->flags);
     dc->is_ldex = false;
-    dc->ss_same_el = (arm_debug_target_el(env) == dc->current_pl);
+    dc->ss_same_el = (arm_debug_target_el(env) == dc->current_el);
 
     init_tmp_a64_array(dc);
 
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 8a2994f..617e6a9 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -7041,7 +7041,7 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                             ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
     if (ri) {
         /* Check access permissions */
-        if (!cp_access_ok(s->current_pl, ri, isread)) {
+        if (!cp_access_ok(s->current_el, ri, isread)) {
             return 1;
         }
 
@@ -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_el = arm_current_el(env);
     dc->features = env->features;
 
     /* Single step state. The code-generation logic here is:
diff --git a/target-arm/translate.h b/target-arm/translate.h
index 85c6f9d..2af8f99 100644
--- a/target-arm/translate.h
+++ b/target-arm/translate.h
@@ -29,7 +29,7 @@ typedef struct DisasContext {
      */
     uint32_t svc_imm;
     int aarch64;
-    int current_pl;
+    int current_el;
     GHashTable *cp_regs;
     uint64_t features; /* CPU features bits */
     /* Because unallocated encodings generate different exception syndrome
@@ -68,7 +68,7 @@ static inline int arm_dc_feature(DisasContext *dc, int feature)
 
 static inline int get_mem_index(DisasContext *s)
 {
-    return s->current_pl;
+    return s->current_el;
 }
 
 /* target-specific extra values for is_jmp */
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v6 05/32] target-arm: make arm_current_el() return EL3
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (3 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 04/32] target-arm: rename arm_current_pl to arm_current_el Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-13 13:04   ` Peter Maydell
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 06/32] target-arm: A32: Emulate the SMC instruction Greg Bellows
                   ` (26 subsequent siblings)
  31 siblings, 1 reply; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

From: Fabian Aggeler <aggelerf@ethz.ch>

Make arm_current_el() return EL3 for secure PL1 and monitor mode.
Increase MMU modes since mmu_index is directly infered from arm_
current_el(). 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>

==========

v5 -> v6
- Rework arm_current_el() logic to properly return EL3 for secure PL1 when EL3
  is 32-bit.
- Replace direct access of env->aarch64 with is_a64()
---
 target-arm/cpu.h | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 149f258..ed32b97 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.
@@ -798,11 +798,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
@@ -991,17 +992,27 @@ static inline bool cptype_valid(int cptype)
  */
 static inline int arm_current_el(CPUARMState *env)
 {
-    if (env->aarch64) {
+    if (is_a64(env)) {
         return extract32(env->pstate, 2, 2);
     }
 
-    if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR) {
+    switch (env->uncached_cpsr & 0x1f) {
+    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;
     }
-    /* We don't currently implement the Virtualization or TrustZone
-     * extensions, so EL2 and EL3 don't exist for us.
-     */
-    return 1;
 }
 
 typedef struct ARMCPRegInfo ARMCPRegInfo;
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v6 06/32] target-arm: A32: Emulate the SMC instruction
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (4 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 05/32] target-arm: make arm_current_el() return EL3 Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-13 13:06   ` Peter Maydell
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 07/32] target-arm: extend async excp masking Greg Bellows
                   ` (25 subsequent siblings)
  31 siblings, 1 reply; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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>

==========

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

v4 -> v5
- Merge pre_smc upstream changes and incorporated ss_advance
---
 target-arm/helper.c    | 11 +++++++++++
 target-arm/internals.h |  5 +++++
 target-arm/op_helper.c |  3 +--
 target-arm/translate.c | 39 +++++++++++++++++++++++++++++----------
 4 files changed, 46 insertions(+), 12 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..544fb42 100644
--- a/target-arm/internals.h
+++ b/target-arm/internals.h
@@ -236,6 +236,11 @@ static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_thumb)
         | (is_thumb ? 0 : ARM_EL_IL);
 }
 
+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(uint32_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..9e38f26 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 617e6a9..60655e1 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_el == 0) {
+                    goto illegal_op;
+                }
+                gen_set_pc_im(s, s->pc - 4);
+                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_el == 0) {
+                        goto illegal_op;
+                    }
+                    gen_set_pc_im(s, s->pc - 4);
+                    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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 07/32] target-arm: extend async excp masking
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (5 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 06/32] target-arm: A32: Emulate the SMC instruction Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 08/32] target-arm: add async excp target_el function Greg Bellows
                   ` (24 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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>

==========

v5 -> v6
- Globally change Aarch# to AArch#
- Fixed comment termination

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

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index ed32b97..6e633cd 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1241,11 +1241,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
@@ -1260,19 +1257,119 @@ 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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 08/32] target-arm: add async excp target_el function
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (6 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 07/32] target-arm: extend async excp masking Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 09/32] target-arm: add banked register accessors Greg Bellows
                   ` (23 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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>

==========

v5 -> v6
- Removed unneeded arm_phys_excp_target_el() function prototype.
- Removed unneeded arm_phys_excp_target_el() USER_ONLY function.
- Fixed up arm_phys_excp_target_el() function definition to be static.
- Globally replace Aarch# with AArch#

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/helper.c | 97 ++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 77 insertions(+), 20 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 7f3f049..9910f72 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3767,6 +3767,80 @@ void switch_mode(CPUARMState *env, int mode)
 }
 
 /*
+ * Determine the target EL for physical exceptions
+ */
+static 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 +3848,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 +3861,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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 09/32] target-arm: add banked register accessors
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (7 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 08/32] target-arm: add async excp target_el function Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 10/32] target-arm: add non-secure Translation Block flag Greg Bellows
                   ` (22 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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>

==========

v5 -> v6
- Converted macro USE_SECURE_REG() into inlince function use_secure_reg()
- Globally replace Aarch# with AArch#

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 | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 6e633cd..9f1613f 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -812,6 +812,46 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
     return arm_feature(env, ARM_FEATURE_AARCH64);
 }
 
+/* Function 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.
+ */
+static inline bool use_secure_reg(CPUARMState *env)
+{
+    bool ret = (arm_feature(env, ARM_FEATURE_EL3) &&
+                !arm_el_is_aa64(env, 3) &&
+                !(env->cp15.scr_el3 & SCR_NS));
+
+    return ret;
+}
+
+/* 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);
 
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v6 10/32] target-arm: add non-secure Translation Block flag
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (8 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 09/32] target-arm: add banked register accessors Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 11/32] target-arm: add CPREG secure state support Greg Bellows
                   ` (21 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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>.

The TBFLAG captures the SCR NS secure state at the time when a TB is created so
the correct bank is accessed on system register accesses.  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>

==========

v5 -> v6
- Removed 64-bit NS TBFLAG macros as they are not needed
- Added comment on DisasContext ns field
- Replaced use of USE_SECURE_REG with use_secure_reg

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       | 7 +++++++
 target-arm/translate.c | 1 +
 target-arm/translate.h | 1 +
 3 files changed, 9 insertions(+)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 9f1613f..59414f3 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1546,6 +1546,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
@@ -1590,6 +1592,8 @@ 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)
 
 static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
@@ -1639,6 +1643,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.c b/target-arm/translate.c
index 60655e1..6217dbb 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 2af8f99..519bcc1 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;        /* Use non-secure CPREG bank on access */
     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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 11/32] target-arm: add CPREG secure state support
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (9 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 10/32] target-arm: add non-secure Translation Block flag Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-17  1:32   ` Edgar E. Iglesias
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 12/32] target-arm: add secure state bit to CPREG hash Greg Bellows
                   ` (20 subsequent siblings)
  31 siblings, 1 reply; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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).

Also added secure state tracking field and flags.  This allows for
identification of the register info secure state.

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

==========

v5 -> v6
- Separate out secure CPREG flags
- Add convenience macro for testing flags
- Removed extraneous newline
- Move add_cpreg_to_hashtable() functionality to a later commit for which it is
  dependent on.
- Added comment explaining fieldoffset padding

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 | 42 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 59414f3..4d8de9e 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -985,6 +985,24 @@ enum {
     ARM_CP_STATE_BOTH = 2,
 };
 
+/* ARM CP register secure state flags.  These flags identify security state
+ * attributes for a given CP register entry.
+ * The existence of both or neither secure and non-secure flags indicates that
+ * the register has both a secure and non-secure hash entry.  A single one of
+ * these flags causes the register to only be hashed for the specified
+ * security state.
+ * Although definitions may have any combination of the S/NS bits, each
+ * registered entry will only have one to identify whether the entry is secure
+ * or non-secure.
+ */
+enum {
+    ARM_CP_SECSTATE_S =   (1 << 0), /* bit[0]: Secure state register */
+    ARM_CP_SECSTATE_NS =  (1 << 1), /* bit[1]: Non-secure state register */
+};
+
+/* Convenience macro for checking for a specific bit */
+#define ARM_CP_SECSTATE_TEST(_ri, _flag) (((_ri)->secure & (_flag)) == (_flag))
+
 /* Return true if cptype is a valid type field. This is used to try to
  * catch errors where the sentinel has been accidentally left off the end
  * of a list of registers.
@@ -1119,6 +1137,8 @@ struct ARMCPRegInfo {
     int type;
     /* Access rights: PL*_[RW] */
     int access;
+    /* Security state: ARM_CP_SECSTATE_* bits/values */
+    int secure;
     /* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
      * this register was defined: can be used to hand data through to the
      * register read/write functions, since they are passed the ARMCPRegInfo*.
@@ -1128,12 +1148,28 @@ 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.
+     *
+     * Extra padding is added to align the default fieldoffset field with the
+     * non-secure bank_fieldoffsets entry.  This is necessary for maintaining
+     * the same storage offset when AArch64 and banked AArch32 are seperately
+     * defined.
+     *
+     * 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
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v6 12/32] target-arm: add secure state bit to CPREG hash
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (10 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 11/32] target-arm: add CPREG secure state support Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 13/32] target-arm: insert AArch32 cpregs twice into hashtable Greg Bellows
                   ` (19 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

Added additional NS-bit to CPREG hash encoding.  Updated hash lookup
locations to specify hash bit currently set to non-secure.

Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

==========

v5 -> v6
- Globally replace Aarch# with AArch#
---
 target-arm/cpu.h       | 25 ++++++++++++++++++++-----
 target-arm/helper.c    |  6 +++---
 target-arm/translate.c | 16 ++++++++++------
 3 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 4d8de9e..8ab3576 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -871,6 +871,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;
@@ -888,9 +889,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 29
+#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 |                                 \
@@ -909,8 +917,15 @@ static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid)
     uint32_t cpregid = kvmid;
     if ((kvmid & CP_REG_ARCH_MASK) == CP_REG_ARM64) {
         cpregid |= CP_REG_AA64_MASK;
-    } else if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
-        cpregid |= (1 << 15);
+    } else {
+        if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
+            cpregid |= (1 << 15);
+        }
+
+        /* KVM is always non-secure so add the NS flag on AArch32 register
+         * entries.
+         */
+         cpregid |= CP_REG_NS_MASK(SCR_NS);
     }
     return cpregid;
 }
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 9910f72..dfdf9d2 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.
@@ -3327,7 +3327,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;
@@ -3477,7 +3477,7 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
                         continue;
                     }
                     add_cpreg_to_hashtable(cpu, r, opaque, state,
-                                           crm, opc1, opc2);
+                                           crm, opc1, opc2, SCR_NS);
                 }
             }
         }
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 6217dbb..442109c 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -712,7 +712,7 @@ static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
 
 /*
  * generate a conditional branch based on ARM condition code cc.
- * This is common between ARM and Aarch64 targets.
+ * This is common between ARM and AArch64 targets.
  */
 void arm_gen_test_cc(int cc, int label)
 {
@@ -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_el, 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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 13/32] target-arm: insert AArch32 cpregs twice into hashtable
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (11 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 12/32] target-arm: add secure state bit to CPREG hash Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 14/32] target-arm: move AArch32 SCR into security reglist Greg Bellows
                   ` (18 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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>

==========

v5 -> v6
- Fixed NS-bit number in the CPREG hash lookup from 27 to 29.
- Switched to dedicated CPREG secure flags.
- Fixed disablement of reset and migration of common 32/64-bit registers.
- Globally replace Aarch# with AArch#

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/helper.c | 90 ++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 75 insertions(+), 15 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index dfdf9d2..f709b4a 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3296,22 +3296,60 @@ 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->secure &= ~(ARM_CP_SECSTATE_S | ARM_CP_SECSTATE_NS);
+        r2->secure |= ARM_CP_SECSTATE_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.
+             * If v7 then we don't need to migrate or reset the AArch32
+             * non-secure bank as this will be handled through the AArch64
+             * view.  In this case the secure bank is not mirrored, so we must
+             * preserve it's reset criteria and allow it to be migrated.
+             *
+             * 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 (r->state == ARM_CP_STATE_BOTH) {
+                if ((arm_feature(&cpu->env, ARM_FEATURE_V8) && r->crn != 13) ||
+                    nsbit) {
+                    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) {
+            /* We assume it is a cp15 register if the .cp field is left unset.
+             */
+            if (r2->cp == 0) {
+                r2->cp = 15;
+            }
+
 #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
@@ -3476,8 +3514,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, SCR_NS);
+                    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->secure & (ARM_CP_SECSTATE_S | ARM_CP_SECSTATE_NS);
+                        if (ARM_CP_SECSTATE_S == s) {
+                            add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                    crm, opc1, opc2, !SCR_NS);
+                        } else if (ARM_CP_SECSTATE_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);
+                    }
                 }
             }
         }
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v6 14/32] target-arm: move AArch32 SCR into security reglist
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (12 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 13/32] target-arm: insert AArch32 cpregs twice into hashtable Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 15/32] target-arm: implement IRQ/FIQ routing to Monitor mode Greg Bellows
                   ` (17 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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 f709b4a..a831b40 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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 15/32] target-arm: implement IRQ/FIQ routing to Monitor mode
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (13 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 14/32] target-arm: move AArch32 SCR into security reglist Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 16/32] target-arm: respect SCR.FW, SCR.AW and SCTLR.NMFI Greg Bellows
                   ` (16 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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 a831b40..760e3f9 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -4211,12 +4211,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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 16/32] target-arm: respect SCR.FW, SCR.AW and SCTLR.NMFI
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (14 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 15/32] target-arm: implement IRQ/FIQ routing to Monitor mode Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 17/32] target-arm: add NSACR register Greg Bellows
                   ` (15 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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 760e3f9..6d0f3ec 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3645,9 +3645,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.
@@ -3659,6 +3656,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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 17/32] target-arm: add NSACR register
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (15 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 16/32] target-arm: respect SCR.FW, SCR.AW and SCTLR.NMFI Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 18/32] target-arm: add SDER definition Greg Bellows
                   ` (14 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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 8ab3576..4d9f6f8 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 6d0f3ec..384af14 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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 18/32] target-arm: add SDER definition
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (16 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 17/32] target-arm: add NSACR register Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 19/32] target-arm: add MVBAR support Greg Bellows
                   ` (13 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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 4d9f6f8..64208bc 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 384af14..d08e4b7 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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 19/32] target-arm: add MVBAR support
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (17 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 18/32] target-arm: add SDER definition Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 20/32] target-arm: add SCTLR_EL3 and make SCTLR banked Greg Bellows
                   ` (12 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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 64208bc..7f314ba 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 d08e4b7..12bf7e4 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
 };
 
@@ -4363,16 +4366,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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 20/32] target-arm: add SCTLR_EL3 and make SCTLR banked
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (18 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 19/32] target-arm: add MVBAR support Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 21/32] target-arm: make CSSELR banked Greg Bellows
                   ` (11 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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>

==========

v5 -> v6
- Changed _el field variants to be array based
- Consolidate SCTLR and SCTLR_EL1 reginfo entries
---
 hw/arm/pxa2xx.c        |  2 +-
 target-arm/cpu.c       |  5 ++--
 target-arm/cpu.h       | 10 ++++++-
 target-arm/helper.c    | 72 +++++++++++++++++++++++++++++---------------------
 target-arm/op_helper.c |  2 +-
 5 files changed, 56 insertions(+), 35 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 edfd586..e192d84 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_el[1] |= 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 7f314ba..5cf58f4 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -178,7 +178,15 @@ 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 _unused_sctlr;
+                uint64_t sctlr_ns;
+                uint64_t hsctlr;
+                uint64_t sctlr_s;
+            };
+            uint64_t sctlr_el[4];
+        };
         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 12bf7e4..25d4240 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_el[1] & 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_el[1] & 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_el[1] & 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_el[3]) },
     { .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_el[1] & SCTLR_UCT)) {
         return CP_ACCESS_TRAP;
     }
     return CP_ACCESS_OK;
@@ -3244,8 +3248,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
     {
         ARMCPRegInfo sctlr = {
             .name = "SCTLR", .state = ARM_CP_STATE_BOTH,
-            .opc0 = 3, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
-            .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_sys),
+            .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
+            .access = PL1_RW,
+            .bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s),
+                                   offsetof(CPUARMState, cp15.sctlr_ns) },
             .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
             .raw_writefn = raw_write,
         };
@@ -4369,7 +4375,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 {
@@ -4399,7 +4405,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;
@@ -4430,7 +4436,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:
@@ -4679,7 +4685,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;
@@ -5010,11 +5017,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;
@@ -5027,7 +5039,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 9e38f26..6a093d6 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_el[1] & SCTLR_UMA)) {
         raise_exception(env, EXCP_UDEF);
     }
 
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v6 21/32] target-arm: make CSSELR banked
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (19 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 20/32] target-arm: add SCTLR_EL3 and make SCTLR banked Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 22/32] target-arm: add TTBR0_EL3 and make TTBR0/1 banked Greg Bellows
                   ` (10 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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>

==========

v5 -> v6
- Changed _el field variants to be array based
- Switch to use distinct CPREG secure flags.
- Merged CSSELR and CSSELR_EL1 reginfo entries

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 | 16 ++++++++++++----
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 5cf58f4..a8c299c 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 _unused_csselr0;
+                uint64_t csselr_ns;
+                uint64_t _unused_csselr1;
+                uint64_t csselr_s;
+            };
+            uint64_t csselr_el[4];
+        };
         union { /* System control register. */
             struct {
                 uint64_t _unused_sctlr;
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 25d4240..55d961e 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,
+                                 ARM_CP_SECSTATE_TEST(ri, ARM_CP_SECSTATE_S));
+
+    return cpu->ccsidr[index];
 }
 
 static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -915,9 +922,10 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
       .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 },
+      .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_ns) } },
     /* Auxiliary ID register: this actually has an IMPDEF value but for now
      * just RAZ for all cores:
      */
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v6 22/32] target-arm: add TTBR0_EL3 and make TTBR0/1 banked
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (20 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 21/32] target-arm: make CSSELR banked Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 23/32] target-arm: add TCR_EL3 and make TTBCR banked Greg Bellows
                   ` (9 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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>

==========

v5 -> v6
- Changed _el field variants to be array based
- Merged TTBR# and TTBR#_EL1 reginfo entries
- Globally replace Aarch# with AArch#
---
 hw/arm/pxa2xx.c     |  4 ++--
 target-arm/cpu.h    | 20 ++++++++++++++++++--
 target-arm/helper.c | 54 +++++++++++++++++++++++++++++++++++++++--------------
 3 files changed, 60 insertions(+), 18 deletions(-)

diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 0114597..13261d0 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -274,7 +274,7 @@ static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
         s->cpu->env.daif = PSTATE_A | PSTATE_F | PSTATE_I;
         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.ttbr0_el[1] = 0;
         s->cpu->env.cp15.c3 = 0;
         s->pm_regs[PSSR >> 2] |= 0x8; /* Set STS */
         s->pm_regs[RCSR >> 2] |= 0x8; /* Set GPR */
@@ -2046,7 +2046,7 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
     }
     if (!revision)
         revision = "pxa270";
-    
+
     s->cpu = cpu_arm_init(revision);
     if (s->cpu == NULL) {
         fprintf(stderr, "Unable to find CPU definition\n");
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index a8c299c..40e6a1d 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -199,8 +199,24 @@ 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 _unused_ttbr0_0;
+                uint64_t ttbr0_ns;
+                uint64_t _unused_ttbr0_1;
+                uint64_t ttbr0_s;
+            };
+            uint64_t ttbr0_el[4];
+        };
+        union { /* MMU translation table base 1. */
+            struct {
+                uint64_t _unused_ttbr1_0;
+                uint64_t ttbr1_ns;
+                uint64_t _unused_ttbr1_1;
+                uint64_t ttbr1_s;
+            };
+            uint64_t ttbr1_el[4];
+        };
         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 55d961e..f3cbdc2 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1658,14 +1658,16 @@ 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,
-      .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,
-      .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 },
+    { .name = "TTBR0", .state = ARM_CP_STATE_BOTH,
+      .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 = "TTBR1", .state = ARM_CP_STATE_BOTH,
+      .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_ns) } },
     { .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 +1898,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
 };
@@ -2403,6 +2407,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_el[3]) },
+    { .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_el[3]) },
     { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_MIGRATE,
       .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1,
@@ -4479,18 +4487,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;
@@ -4744,6 +4757,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;
@@ -4795,7 +4809,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_el[3];
+                break;
+            case 1:
+            case 0:
+            default:
+                ttbr = env->cp15.ttbr0_el[1];
+            }
+        } else {
+            ttbr = A32_BANKED_CURRENT_REG_GET(env, ttbr0);
+        }
         epd = extract32(env->cp15.c2_control, 7, 1);
         tsz = t0sz;
 
@@ -4807,7 +4833,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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 23/32] target-arm: add TCR_EL3 and make TTBCR banked
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (21 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 22/32] target-arm: add TTBR0_EL3 and make TTBR0/1 banked Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 24/32] target-arm: make c2_mask and c2_base_mask banked Greg Bellows
                   ` (8 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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>

==========

v5 -> v6
- Changed _el field variants to be array based

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    | 48 +++++++++++++++++++++++++++++++++++-------------
 target-arm/internals.h |  2 +-
 3 files changed, 45 insertions(+), 15 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 40e6a1d..dea93d8 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -217,7 +217,15 @@ typedef struct CPUARMState {
             };
             uint64_t ttbr1_el[4];
         };
-        uint64_t c2_control; /* MMU translation table base control.  */
+        union { /* MMU translation table base control. */
+            struct {
+                uint64_t _unused_ttbcr_0;
+                uint64_t ttbcr_ns;
+                uint64_t _unused_ttbcr_1;
+                uint64_t ttbcr_s;
+            };
+            uint64_t 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 f3cbdc2..f50ad02 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1672,11 +1672,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_el[1]) },
     { .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,
@@ -2411,6 +2412,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_el[3]) },
+    { .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_el[3]) },
     { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_MIGRATE,
       .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1,
@@ -4492,13 +4498,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;
         }
@@ -4758,13 +4764,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_el[3];
+            break;
+        case 1:
+        case 0:
+        default:
+            tcr = env->cp15.tcr_el[1];
+        }
+
+    } 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;
     }
 
@@ -4773,12 +4795,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);
@@ -4822,10 +4844,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;
         }
@@ -4834,10 +4856,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 544fb42..400138a 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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 24/32] target-arm: make c2_mask and c2_base_mask banked
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (22 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 23/32] target-arm: add TCR_EL3 and make TTBCR banked Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 25/32] target-arm: make DACR banked Greg Bellows
                   ` (7 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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>

==========

v5 -> v6
- Switch to use distinct CPREG secure flags

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 dea93d8..7379e28 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -226,8 +226,14 @@ typedef struct CPUARMState {
             };
             uint64_t tcr_el[4];
         };
-        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 f50ad02..bfefcc7 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,
+                       ARM_CP_SECSTATE_TEST(ri, ARM_CP_SECSTATE_S),
+                       ~(((uint32_t)0xffffffffu) >> maskshift));
+    A32_BANKED_REG_SET(env, c2_base_mask,
+                       ARM_CP_SECSTATE_TEST(ri, ARM_CP_SECSTATE_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,
+                       ARM_CP_SECSTATE_TEST(ri, ARM_CP_SECSTATE_S),
+                       0xffffc000u);
+    A32_BANKED_REG_SET(env, c2_mask,
+                       ARM_CP_SECSTATE_TEST(ri, ARM_CP_SECSTATE_S), 0);
     raw_write(env, ri, 0);
-    env->cp15.c2_mask = 0;
 }
 
 static void vmsa_tcr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -4497,7 +4509,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;
@@ -4509,7 +4521,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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 25/32] target-arm: make DACR banked
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (23 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 24/32] target-arm: make c2_mask and c2_base_mask banked Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 26/32] target-arm: make IFSR banked Greg Bellows
                   ` (6 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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 13261d0..51d9fe8 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_el[1] = 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 7379e28..315f98c 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -236,8 +236,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 bfefcc7..4db90ef 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.
      */
@@ -2269,10 +2271,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,
@@ -4551,7 +4554,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;
@@ -4663,7 +4666,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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 26/32] target-arm: make IFSR banked
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (24 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 25/32] target-arm: make DACR banked Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 27/32] target-arm: make DFSR banked Greg Bellows
                   ` (5 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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 315f98c..adb51d3 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -251,7 +251,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 4db90ef..af6b371 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,
@@ -4354,11 +4355,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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 27/32] target-arm: make DFSR banked
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (25 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 26/32] target-arm: make IFSR banked Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 28/32] target-arm: make IFAR/DFAR banked Greg Bellows
                   ` (4 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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 adb51d3..66206f9 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -260,7 +260,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 af6b371..9fdbbbf 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,
@@ -4366,11 +4367,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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 28/32] target-arm: make IFAR/DFAR banked
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (26 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 27/32] target-arm: make DFSR banked Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 29/32] target-arm: make PAR banked Greg Bellows
                   ` (3 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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 e192d84..8ba72ed 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 66206f9..3240777 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -270,7 +270,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 9fdbbbf..9f0fb93 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.
@@ -1694,11 +1695,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
 };
 
@@ -4357,8 +4361,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;
@@ -4368,8 +4371,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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 29/32] target-arm: make PAR banked
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (27 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 28/32] target-arm: make IFAR/DFAR banked Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 30/32] target-arm: make c13 cp regs banked (FCSEIDR, ...) Greg Bellows
                   ` (2 subsequent siblings)
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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>

==========

v5 -> v6
- Changed _el field variants to be array based
- Merged VBAR and VBAR_EL1 reginfo entries

v3 -> v4
- Fix par union/structure definition
---
 target-arm/cpu.h    | 20 ++++++++++++++++++--
 target-arm/helper.c | 33 ++++++++++++++++++---------------
 2 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 3240777..4804ff1 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -288,7 +288,15 @@ typedef struct CPUARMState {
             };
             uint64_t far_el[4];
         };
-        uint64_t par_el1;  /* Translation result. */
+        union { /* Translation result. */
+            struct {
+                uint64_t _unused_par_0;
+                uint64_t par_ns;
+                uint64_t _unused_par_1;
+                uint64_t par_s;
+            };
+            uint64_t par_el[4];
+        };
         uint32_t c9_insn; /* Cache lockdown registers.  */
         uint32_t c9_data;
         uint64_t c9_pmcr; /* performance monitor control register */
@@ -298,7 +306,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 9f0fb93..1e211c4 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 },
@@ -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,
@@ -1915,8 +1917,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),
@@ -4425,7 +4428,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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 30/32] target-arm: make c13 cp regs banked (FCSEIDR, ...)
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (28 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 29/32] target-arm: make PAR banked Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-15  3:17   ` Edgar E. Iglesias
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 31/32] target-arm: make MAIR0/1 banked Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 32/32] target-arm: add cpu feature EL3 to CPUs with Security Extensions Greg Bellows
  31 siblings, 1 reply; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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>

==========

v5 -> v6
- Changed _el field variants to be array based
- Rework data layout for correct aliasing
- Merged CONTEXTIDR and CONTEXTIDR_EL1 reginfo entries

v3 -> v4
- Fix tpidrprw mapping
---
 target-arm/cpu.h       | 35 ++++++++++++++++++++++++++++++-----
 target-arm/helper.c    | 37 ++++++++++++++++++++++---------------
 target-arm/op_helper.c |  2 +-
 3 files changed, 53 insertions(+), 21 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 4804ff1..e8ede63 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -316,11 +316,36 @@ 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 fcseidr_ns;
+            uint32_t fcseidr_s;
+        };
+        union { /* Context ID. */
+            struct {
+                uint64_t _unused_contextidr;
+                uint64_t contextidr_ns;
+                uint64_t contextidr_s;
+            };
+            uint64_t contextidr_el[2];
+        };
+        union { /* User RW Thread register. */
+            struct {
+                uint64_t tpidrurw_ns;
+                uint64_t tpidrprw_ns;
+                uint64_t htpidr;
+                uint64_t _tpidr_el3;
+            };
+            uint64_t tpidr_el[4];
+        };
+        /* The secure banks of these registers don't map anywhere */
+        uint64_t tpidrurw_s;
+        uint64_t tpidrprw_s;
+        uint64_t tpidruro_s;
+
+        union { /* User RO Thread register. */
+            uint64_t tpidruro_ns;
+            uint64_t tpidrro_el[1];
+        };
         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 1e211c4..d05eb4d 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.fcseidr_s),
+                             offsetof(CPUARMState, cp15.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,
+      .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
 };
@@ -1038,23 +1041,27 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
     { .name = "TPIDR_EL0", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 3, .opc2 = 2, .crn = 13, .crm = 0,
       .access = PL0_RW,
-      .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el0), .resetvalue = 0 },
+      .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[0]), .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 },
+      .access = PL0_R|PL1_W, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el[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 },
+      .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[1]), .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
 };
 
@@ -5102,7 +5109,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, fcseidr);
 
     if ((sctlr & SCTLR_M) == 0) {
         /* MMU/MPU disabled.  */
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 6a093d6..7383d79 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -556,7 +556,7 @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
      * short descriptor format (in which case it holds both PROCID and ASID),
      * since we don't implement the optional v7 context ID masking.
      */
-    contextidr = extract64(env->cp15.contextidr_el1, 0, 32);
+    contextidr = extract64(env->cp15.contextidr_el[1], 0, 32);
 
     switch (bt) {
     case 3: /* linked context ID match */
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v6 31/32] target-arm: make MAIR0/1 banked
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (29 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 30/32] target-arm: make c13 cp regs banked (FCSEIDR, ...) Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 32/32] target-arm: add cpu feature EL3 to CPUs with Security Extensions Greg Bellows
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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

Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

==========

v5 -> v6
- Changed _el field variants to be array based
---
 target-arm/cpu.h    | 12 +++++++++++-
 target-arm/helper.c |  8 +++++---
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index e8ede63..73b445a 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -305,7 +305,17 @@ typedef struct CPUARMState {
         uint32_t c9_pmxevtyper; /* perf monitor event type */
         uint32_t c9_pmuserenr; /* perf monitor user enable */
         uint32_t c9_pminten; /* perf monitor interrupt enables */
-        uint64_t mair_el1;
+        union { /* Memory attribute redirection */
+            struct {
+                uint64_t _unused_mair_0;
+                uint32_t mair0_ns;
+                uint32_t mair1_ns;
+                uint64_t _unused_mair_1;
+                uint32_t mair0_s;
+                uint32_t mair1_s;
+            };
+            uint64_t mair_el[4];
+        };
         union { /* vector base address register */
             struct {
                 uint64_t _unused_vbar;
diff --git a/target-arm/helper.c b/target-arm/helper.c
index d05eb4d..136a232 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -952,7 +952,7 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
      */
     { .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el1),
+      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]),
       .resetvalue = 0 },
     /* For non-long-descriptor page tables these are PRRR and NMRR;
      * regardless they still act as reads-as-written for QEMU.
@@ -961,11 +961,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 = { offsetof(CPUARMState, cp15.mair0_s),
+                             offsetof(CPUARMState, cp15.mair0_ns) },
       .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 = { offsetof(CPUARMState, cp15.mair1_s),
+                             offsetof(CPUARMState, cp15.mair1_ns) },
       .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] 50+ messages in thread

* [Qemu-devel] [PATCH v6 32/32] target-arm: add cpu feature EL3 to CPUs with Security Extensions
  2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
                   ` (30 preceding siblings ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 31/32] target-arm: make MAIR0/1 banked Greg Bellows
@ 2014-10-10 16:03 ` Greg Bellows
  31 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-10 16:03 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, serge.fdrv, edgar.iglesias, aggelerf

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 8ba72ed..fa12602 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] 50+ messages in thread

* Re: [Qemu-devel] [PATCH v6 01/32] target-arm: increase arrays of registers R13 & R14
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 01/32] target-arm: increase arrays of registers R13 & R14 Greg Bellows
@ 2014-10-13 12:31   ` Peter Maydell
  0 siblings, 0 replies; 50+ messages in thread
From: Peter Maydell @ 2014-10-13 12:31 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 10 October 2014 18:03, 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>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>

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

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v6 02/32] target-arm: add arm_is_secure() function
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 02/32] target-arm: add arm_is_secure() function Greg Bellows
@ 2014-10-13 12:41   ` Peter Maydell
  0 siblings, 0 replies; 50+ messages in thread
From: Peter Maydell @ 2014-10-13 12:41 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 10 October 2014 18:03, 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>
>
> ==========
>
> v5 -> v6
> - Broaden CONFIG_USER conditional
> - Merge resulting false returns with common comment
> - Globally change Aarch# to AArch#
> - Replace direct access of env->aarch64 with is_a64()
> ---
>  target-arm/cpu.h | 42 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 42 insertions(+)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 81fffd2..4f6db0f 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -753,6 +753,48 @@ static inline int arm_feature(CPUARMState *env, int feature)
>      return (env->features & (1ULL << feature)) != 0;
>  }
>
> +#if !defined(CONFIG_USER_ONLY)
> +/* Return true if exception level below EL3 is in secure state */

This is still missing the clarifying comment I was hoping for.

Make this:

/* Return true if exception levels below EL3 are in secure state,
 * or would be following an exception return to that level.
 * Unlike arm_is_secure() (which is alvays a question about the
 * _current_ state of the CPU) this doesn't care about the current
 * EL or mode.
 */

and then you can add my reviewed-by tag.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v6 03/32] target-arm: reject switching to monitor mode
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 03/32] target-arm: reject switching to monitor mode Greg Bellows
@ 2014-10-13 12:58   ` Peter Maydell
  0 siblings, 0 replies; 50+ messages in thread
From: Peter Maydell @ 2014-10-13 12:58 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 10 October 2014 18:03, Greg Bellows <greg.bellows@linaro.org> wrote:
> From: Sergey Fedorov <s.fedorov@samsung.com>
>
> Reject switching to monitor mode 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(+)

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

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v6 04/32] target-arm: rename arm_current_pl to arm_current_el
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 04/32] target-arm: rename arm_current_pl to arm_current_el Greg Bellows
@ 2014-10-13 13:00   ` Peter Maydell
  0 siblings, 0 replies; 50+ messages in thread
From: Peter Maydell @ 2014-10-13 13:00 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 10 October 2014 18:03, 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>
>
> ==========
>
> v5 -> v6
> - Renamed DisasContext current_pl field to current_el
> - Added comment to arm_current_el on handling v7 PL
> - Fixed comments referencing PL
> ---
>  target-arm/cpu.h           | 27 +++++++++++++++------------
>  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 | 16 ++++++++--------
>  target-arm/translate.c     |  4 ++--
>  target-arm/translate.h     |  4 ++--
>  8 files changed, 50 insertions(+), 47 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 4f6db0f..149f258 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -986,7 +986,10 @@ 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)
> +/* Return the current Exception Level (as per ARMv8 note that this differs

Needs a semicolon between "ARMv8" and "note".

> + * from the ARMv7 Privilege Level).
> + */
> +static inline int arm_current_el(CPUARMState *env)

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

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v6 05/32] target-arm: make arm_current_el() return EL3
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 05/32] target-arm: make arm_current_el() return EL3 Greg Bellows
@ 2014-10-13 13:04   ` Peter Maydell
  0 siblings, 0 replies; 50+ messages in thread
From: Peter Maydell @ 2014-10-13 13:04 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 10 October 2014 18:03, Greg Bellows <greg.bellows@linaro.org> wrote:
> From: Fabian Aggeler <aggelerf@ethz.ch>
>
> Make arm_current_el() return EL3 for secure PL1 and monitor mode.
> Increase MMU modes since mmu_index is directly infered from arm_

"inferred"

> current_el(). Changes assertion in arm_el_is_aa64() to allow EL3.

"Change"

>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
>
> ==========
>
> v5 -> v6
> - Rework arm_current_el() logic to properly return EL3 for secure PL1 when EL3
>   is 32-bit.
> - Replace direct access of env->aarch64 with is_a64()
> ---
>  target-arm/cpu.h | 29 ++++++++++++++++++++---------
>  1 file changed, 20 insertions(+), 9 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 149f258..ed32b97 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.
> @@ -798,11 +798,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
> @@ -991,17 +992,27 @@ static inline bool cptype_valid(int cptype)
>   */
>  static inline int arm_current_el(CPUARMState *env)
>  {
> -    if (env->aarch64) {
> +    if (is_a64(env)) {
>          return extract32(env->pstate, 2, 2);
>      }
>
> -    if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR) {
> +    switch (env->uncached_cpsr & 0x1f) {

Use CPSR_M, not a raw 0x1f, please.

> +    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;

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

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v6 06/32] target-arm: A32: Emulate the SMC instruction
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 06/32] target-arm: A32: Emulate the SMC instruction Greg Bellows
@ 2014-10-13 13:06   ` Peter Maydell
  2014-10-13 13:13     ` Greg Bellows
  0 siblings, 1 reply; 50+ messages in thread
From: Peter Maydell @ 2014-10-13 13:06 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

On 10 October 2014 18:03, 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>
>
> ==========
>
> v5 -> v6
> - Fixed PC offsetting for presmc
> - Removed extraneous semi-colon
> - Fixed merge issue
>
> v4 -> v5
> - Merge pre_smc upstream changes and incorporated ss_advance
> ---
>  target-arm/helper.c    | 11 +++++++++++
>  target-arm/internals.h |  5 +++++
>  target-arm/op_helper.c |  3 +--
>  target-arm/translate.c | 39 +++++++++++++++++++++++++++++----------
>  4 files changed, 46 insertions(+), 12 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..544fb42 100644
> --- a/target-arm/internals.h
> +++ b/target-arm/internals.h
> @@ -236,6 +236,11 @@ static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_thumb)
>          | (is_thumb ? 0 : ARM_EL_IL);
>  }
>
> +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(uint32_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..9e38f26 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 617e6a9..60655e1 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_el == 0) {
> +                    goto illegal_op;
> +                }
> +                gen_set_pc_im(s, s->pc - 4);
> +                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;

This is wrong; you should be basing this series on top of my PSCI
series which will get you a correct implementation of the translate.c
changes for SMC for A32/T32. (You'll still need the do_interrupt
changes.)

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v6 06/32] target-arm: A32: Emulate the SMC instruction
  2014-10-13 13:06   ` Peter Maydell
@ 2014-10-13 13:13     ` Greg Bellows
  2014-10-13 13:36       ` Peter Maydell
  0 siblings, 1 reply; 50+ messages in thread
From: Greg Bellows @ 2014-10-13 13:13 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Sergey Fedorov, QEMU Developers, Fabian Aggeler, Edgar E. Iglesias

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

I realize that, but I don't believe your changes were available yet and
still sounded to be a bit in flux, so I was waiting to merge.

As I mentioned previously, I had already merged on top of your initial
changes.

I'll recommit with your changes.

Greg

On 13 October 2014 08:06, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 10 October 2014 18:03, 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>
> >
> > ==========
> >
> > v5 -> v6
> > - Fixed PC offsetting for presmc
> > - Removed extraneous semi-colon
> > - Fixed merge issue
> >
> > v4 -> v5
> > - Merge pre_smc upstream changes and incorporated ss_advance
> > ---
> >  target-arm/helper.c    | 11 +++++++++++
> >  target-arm/internals.h |  5 +++++
> >  target-arm/op_helper.c |  3 +--
> >  target-arm/translate.c | 39 +++++++++++++++++++++++++++++----------
> >  4 files changed, 46 insertions(+), 12 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..544fb42 100644
> > --- a/target-arm/internals.h
> > +++ b/target-arm/internals.h
> > @@ -236,6 +236,11 @@ static inline uint32_t syn_aa32_svc(uint32_t imm16,
> bool is_thumb)
> >          | (is_thumb ? 0 : ARM_EL_IL);
> >  }
> >
> > +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(uint32_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..9e38f26 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 617e6a9..60655e1 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_el == 0) {
> > +                    goto illegal_op;
> > +                }
> > +                gen_set_pc_im(s, s->pc - 4);
> > +                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;
>
> This is wrong; you should be basing this series on top of my PSCI
> series which will get you a correct implementation of the translate.c
> changes for SMC for A32/T32. (You'll still need the do_interrupt
> changes.)
>
> thanks
> -- PMM
>

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

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

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

On 13 October 2014 15:13, Greg Bellows <greg.bellows@linaro.org> wrote:
> I realize that, but I don't believe your changes were available yet and
> still sounded to be a bit in flux, so I was waiting to merge.
>
> As I mentioned previously, I had already merged on top of your initial
> changes.

Ah. I thought when you said you'd merged your series on top of mine
that you'd merged it on top of the relevant patches...


> I'll recommit with your changes.

Thanks.

I'm going to finish reviewing the rest of this series, since
the later patches are basically independent of this. I may
be a day or two though as the next few require deeper thought
than the minor nits in the first half dozen patches. So you
don't need to push out a v7 just yet.

-- PMM

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

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

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

I reapplied my changes on top of your v5 with the latest backing.  It
basically scraps most of my changes on this patch for yours, except for
some slight updates here and there.

I'll continue to make any v7 updates on your v5 set.

Greg

On 13 October 2014 08:36, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 13 October 2014 15:13, Greg Bellows <greg.bellows@linaro.org> wrote:
> > I realize that, but I don't believe your changes were available yet and
> > still sounded to be a bit in flux, so I was waiting to merge.
> >
> > As I mentioned previously, I had already merged on top of your initial
> > changes.
>
> Ah. I thought when you said you'd merged your series on top of mine
> that you'd merged it on top of the relevant patches...
>
>
> > I'll recommit with your changes.
>
> Thanks.
>
> I'm going to finish reviewing the rest of this series, since
> the later patches are basically independent of this. I may
> be a day or two though as the next few require deeper thought
> than the minor nits in the first half dozen patches. So you
> don't need to push out a v7 just yet.
>
> -- PMM
>

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

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

* Re: [Qemu-devel] [PATCH v6 30/32] target-arm: make c13 cp regs banked (FCSEIDR, ...)
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 30/32] target-arm: make c13 cp regs banked (FCSEIDR, ...) Greg Bellows
@ 2014-10-15  3:17   ` Edgar E. Iglesias
  2014-10-16 18:20     ` Greg Bellows
  0 siblings, 1 reply; 50+ messages in thread
From: Edgar E. Iglesias @ 2014-10-15  3:17 UTC (permalink / raw)
  To: Greg Bellows; +Cc: peter.maydell, qemu-devel, aggelerf, serge.fdrv

On Fri, Oct 10, 2014 at 11:03:41AM -0500, Greg Bellows 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>

Hi Greg,

When changing tpidr_el into an array, I think we need to
update linux-user/ usages as well.

Cheers,
Edgar


> 
> ==========
> 
> v5 -> v6
> - Changed _el field variants to be array based
> - Rework data layout for correct aliasing
> - Merged CONTEXTIDR and CONTEXTIDR_EL1 reginfo entries
> 
> v3 -> v4
> - Fix tpidrprw mapping
> ---
>  target-arm/cpu.h       | 35 ++++++++++++++++++++++++++++++-----
>  target-arm/helper.c    | 37 ++++++++++++++++++++++---------------
>  target-arm/op_helper.c |  2 +-
>  3 files changed, 53 insertions(+), 21 deletions(-)
> 
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 4804ff1..e8ede63 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -316,11 +316,36 @@ 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 fcseidr_ns;
> +            uint32_t fcseidr_s;
> +        };
> +        union { /* Context ID. */
> +            struct {
> +                uint64_t _unused_contextidr;
> +                uint64_t contextidr_ns;
> +                uint64_t contextidr_s;
> +            };
> +            uint64_t contextidr_el[2];
> +        };
> +        union { /* User RW Thread register. */
> +            struct {
> +                uint64_t tpidrurw_ns;
> +                uint64_t tpidrprw_ns;
> +                uint64_t htpidr;
> +                uint64_t _tpidr_el3;
> +            };
> +            uint64_t tpidr_el[4];
> +        };
> +        /* The secure banks of these registers don't map anywhere */
> +        uint64_t tpidrurw_s;
> +        uint64_t tpidrprw_s;
> +        uint64_t tpidruro_s;
> +
> +        union { /* User RO Thread register. */
> +            uint64_t tpidruro_ns;
> +            uint64_t tpidrro_el[1];
> +        };
>          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 1e211c4..d05eb4d 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.fcseidr_s),
> +                             offsetof(CPUARMState, cp15.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,
> +      .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
>  };
> @@ -1038,23 +1041,27 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
>      { .name = "TPIDR_EL0", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .opc1 = 3, .opc2 = 2, .crn = 13, .crm = 0,
>        .access = PL0_RW,
> -      .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el0), .resetvalue = 0 },
> +      .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[0]), .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 },
> +      .access = PL0_R|PL1_W, .resetvalue = 0,
> +      .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el[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 },
> +      .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[1]), .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
>  };
>  
> @@ -5102,7 +5109,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, fcseidr);
>  
>      if ((sctlr & SCTLR_M) == 0) {
>          /* MMU/MPU disabled.  */
> diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
> index 6a093d6..7383d79 100644
> --- a/target-arm/op_helper.c
> +++ b/target-arm/op_helper.c
> @@ -556,7 +556,7 @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
>       * short descriptor format (in which case it holds both PROCID and ASID),
>       * since we don't implement the optional v7 context ID masking.
>       */
> -    contextidr = extract64(env->cp15.contextidr_el1, 0, 32);
> +    contextidr = extract64(env->cp15.contextidr_el[1], 0, 32);
>  
>      switch (bt) {
>      case 3: /* linked context ID match */
> -- 
> 1.8.3.2
> 

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

* Re: [Qemu-devel] [PATCH v6 30/32] target-arm: make c13 cp regs banked (FCSEIDR, ...)
  2014-10-15  3:17   ` Edgar E. Iglesias
@ 2014-10-16 18:20     ` Greg Bellows
  0 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-16 18:20 UTC (permalink / raw)
  To: Edgar E. Iglesias
  Cc: Peter Maydell, QEMU Developers, Fabian Aggeler, Sergey Fedorov

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

Yes, good catch.  Not sure why it did not come up in my search.

Will fix in v7.

Greg

On 14 October 2014 22:17, Edgar E. Iglesias <edgar.iglesias@gmail.com>
wrote:

> On Fri, Oct 10, 2014 at 11:03:41AM -0500, Greg Bellows 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>
>
> Hi Greg,
>
> When changing tpidr_el into an array, I think we need to
> update linux-user/ usages as well.
>
> Cheers,
> Edgar
>
>
> >
> > ==========
> >
> > v5 -> v6
> > - Changed _el field variants to be array based
> > - Rework data layout for correct aliasing
> > - Merged CONTEXTIDR and CONTEXTIDR_EL1 reginfo entries
> >
> > v3 -> v4
> > - Fix tpidrprw mapping
> > ---
> >  target-arm/cpu.h       | 35 ++++++++++++++++++++++++++++++-----
> >  target-arm/helper.c    | 37 ++++++++++++++++++++++---------------
> >  target-arm/op_helper.c |  2 +-
> >  3 files changed, 53 insertions(+), 21 deletions(-)
> >
> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > index 4804ff1..e8ede63 100644
> > --- a/target-arm/cpu.h
> > +++ b/target-arm/cpu.h
> > @@ -316,11 +316,36 @@ 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 fcseidr_ns;
> > +            uint32_t fcseidr_s;
> > +        };
> > +        union { /* Context ID. */
> > +            struct {
> > +                uint64_t _unused_contextidr;
> > +                uint64_t contextidr_ns;
> > +                uint64_t contextidr_s;
> > +            };
> > +            uint64_t contextidr_el[2];
> > +        };
> > +        union { /* User RW Thread register. */
> > +            struct {
> > +                uint64_t tpidrurw_ns;
> > +                uint64_t tpidrprw_ns;
> > +                uint64_t htpidr;
> > +                uint64_t _tpidr_el3;
> > +            };
> > +            uint64_t tpidr_el[4];
> > +        };
> > +        /* The secure banks of these registers don't map anywhere */
> > +        uint64_t tpidrurw_s;
> > +        uint64_t tpidrprw_s;
> > +        uint64_t tpidruro_s;
> > +
> > +        union { /* User RO Thread register. */
> > +            uint64_t tpidruro_ns;
> > +            uint64_t tpidrro_el[1];
> > +        };
> >          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 1e211c4..d05eb4d 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.fcseidr_s),
> > +                             offsetof(CPUARMState, cp15.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,
> > +      .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
> >  };
> > @@ -1038,23 +1041,27 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
> >      { .name = "TPIDR_EL0", .state = ARM_CP_STATE_AA64,
> >        .opc0 = 3, .opc1 = 3, .opc2 = 2, .crn = 13, .crm = 0,
> >        .access = PL0_RW,
> > -      .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el0), .resetvalue
> = 0 },
> > +      .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[0]),
> .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 },
> > +      .access = PL0_R|PL1_W, .resetvalue = 0,
> > +      .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el[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 },
> > +      .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[1]),
> .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
> >  };
> >
> > @@ -5102,7 +5109,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, fcseidr);
> >
> >      if ((sctlr & SCTLR_M) == 0) {
> >          /* MMU/MPU disabled.  */
> > diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
> > index 6a093d6..7383d79 100644
> > --- a/target-arm/op_helper.c
> > +++ b/target-arm/op_helper.c
> > @@ -556,7 +556,7 @@ static bool linked_bp_matches(ARMCPU *cpu, int lbn)
> >       * short descriptor format (in which case it holds both PROCID and
> ASID),
> >       * since we don't implement the optional v7 context ID masking.
> >       */
> > -    contextidr = extract64(env->cp15.contextidr_el1, 0, 32);
> > +    contextidr = extract64(env->cp15.contextidr_el[1], 0, 32);
> >
> >      switch (bt) {
> >      case 3: /* linked context ID match */
> > --
> > 1.8.3.2
> >
>

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

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

* Re: [Qemu-devel] [PATCH v6 11/32] target-arm: add CPREG secure state support
  2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 11/32] target-arm: add CPREG secure state support Greg Bellows
@ 2014-10-17  1:32   ` Edgar E. Iglesias
  2014-10-17 13:37     ` Greg Bellows
  0 siblings, 1 reply; 50+ messages in thread
From: Edgar E. Iglesias @ 2014-10-17  1:32 UTC (permalink / raw)
  To: Greg Bellows; +Cc: peter.maydell, qemu-devel, aggelerf, serge.fdrv

On Fri, Oct 10, 2014 at 11:03:22AM -0500, Greg Bellows 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).

Hi Greg,

I gave the series a try through my auto-tester and it fails on this
patch with gcc-4.4:
$ gcc-4.4 --version
gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7

We might need to pass additional options to gcc for the
anonymous structs/unions or use a different approach.

Cheers,
Edgar



> 
> Also added secure state tracking field and flags.  This allows for
> identification of the register info secure state.
> 
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> 
> ==========
> 
> v5 -> v6
> - Separate out secure CPREG flags
> - Add convenience macro for testing flags
> - Removed extraneous newline
> - Move add_cpreg_to_hashtable() functionality to a later commit for which it is
>   dependent on.
> - Added comment explaining fieldoffset padding
> 
> 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 | 42 +++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 39 insertions(+), 3 deletions(-)
> 
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 59414f3..4d8de9e 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -985,6 +985,24 @@ enum {
>      ARM_CP_STATE_BOTH = 2,
>  };
>  
> +/* ARM CP register secure state flags.  These flags identify security state
> + * attributes for a given CP register entry.
> + * The existence of both or neither secure and non-secure flags indicates that
> + * the register has both a secure and non-secure hash entry.  A single one of
> + * these flags causes the register to only be hashed for the specified
> + * security state.
> + * Although definitions may have any combination of the S/NS bits, each
> + * registered entry will only have one to identify whether the entry is secure
> + * or non-secure.
> + */
> +enum {
> +    ARM_CP_SECSTATE_S =   (1 << 0), /* bit[0]: Secure state register */
> +    ARM_CP_SECSTATE_NS =  (1 << 1), /* bit[1]: Non-secure state register */
> +};
> +
> +/* Convenience macro for checking for a specific bit */
> +#define ARM_CP_SECSTATE_TEST(_ri, _flag) (((_ri)->secure & (_flag)) == (_flag))
> +
>  /* Return true if cptype is a valid type field. This is used to try to
>   * catch errors where the sentinel has been accidentally left off the end
>   * of a list of registers.
> @@ -1119,6 +1137,8 @@ struct ARMCPRegInfo {
>      int type;
>      /* Access rights: PL*_[RW] */
>      int access;
> +    /* Security state: ARM_CP_SECSTATE_* bits/values */
> +    int secure;
>      /* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
>       * this register was defined: can be used to hand data through to the
>       * register read/write functions, since they are passed the ARMCPRegInfo*.
> @@ -1128,12 +1148,28 @@ 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.
> +     *
> +     * Extra padding is added to align the default fieldoffset field with the
> +     * non-secure bank_fieldoffsets entry.  This is necessary for maintaining
> +     * the same storage offset when AArch64 and banked AArch32 are seperately
> +     * defined.
> +     *
> +     * 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
> -- 
> 1.8.3.2
> 

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

* Re: [Qemu-devel] [PATCH v6 11/32] target-arm: add CPREG secure state support
  2014-10-17  1:32   ` Edgar E. Iglesias
@ 2014-10-17 13:37     ` Greg Bellows
  2014-10-17 15:20       ` Greg Bellows
  0 siblings, 1 reply; 50+ messages in thread
From: Greg Bellows @ 2014-10-17 13:37 UTC (permalink / raw)
  To: Edgar E. Iglesias
  Cc: Peter Maydell, QEMU Developers, Fabian Aggeler, Sergey Fedorov

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

Hmmm, I had not encountered this as I am using a new compiler which is
presumeably using -std=c11.   Here is what I am using:

> gcc --version
gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1

A quick search on gcc 4.4 shows that a different flag may be
needed (-fms-extensions). There is also a special flag for 4.6 apparently.

One question I have is how old of a toolchain do we support?  Peter?

In the meantime, I'll try and reproduce on my end and try the additional
flags.

Thanks for pointing this out.

Greg

On 16 October 2014 20:32, Edgar E. Iglesias <edgar.iglesias@gmail.com>
wrote:

> On Fri, Oct 10, 2014 at 11:03:22AM -0500, Greg Bellows 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).
>
> Hi Greg,
>
> I gave the series a try through my auto-tester and it fails on this
> patch with gcc-4.4:
> $ gcc-4.4 --version
> gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7
>
> We might need to pass additional options to gcc for the
> anonymous structs/unions or use a different approach.
>
> Cheers,
> Edgar
>
>
>
> >
> > Also added secure state tracking field and flags.  This allows for
> > identification of the register info secure state.
> >
> > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> >
> > ==========
> >
> > v5 -> v6
> > - Separate out secure CPREG flags
> > - Add convenience macro for testing flags
> > - Removed extraneous newline
> > - Move add_cpreg_to_hashtable() functionality to a later commit for
> which it is
> >   dependent on.
> > - Added comment explaining fieldoffset padding
> >
> > 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 | 42 +++++++++++++++++++++++++++++++++++++++---
> >  1 file changed, 39 insertions(+), 3 deletions(-)
> >
> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > index 59414f3..4d8de9e 100644
> > --- a/target-arm/cpu.h
> > +++ b/target-arm/cpu.h
> > @@ -985,6 +985,24 @@ enum {
> >      ARM_CP_STATE_BOTH = 2,
> >  };
> >
> > +/* ARM CP register secure state flags.  These flags identify security
> state
> > + * attributes for a given CP register entry.
> > + * The existence of both or neither secure and non-secure flags
> indicates that
> > + * the register has both a secure and non-secure hash entry.  A single
> one of
> > + * these flags causes the register to only be hashed for the specified
> > + * security state.
> > + * Although definitions may have any combination of the S/NS bits, each
> > + * registered entry will only have one to identify whether the entry is
> secure
> > + * or non-secure.
> > + */
> > +enum {
> > +    ARM_CP_SECSTATE_S =   (1 << 0), /* bit[0]: Secure state register */
> > +    ARM_CP_SECSTATE_NS =  (1 << 1), /* bit[1]: Non-secure state
> register */
> > +};
> > +
> > +/* Convenience macro for checking for a specific bit */
> > +#define ARM_CP_SECSTATE_TEST(_ri, _flag) (((_ri)->secure & (_flag)) ==
> (_flag))
> > +
> >  /* Return true if cptype is a valid type field. This is used to try to
> >   * catch errors where the sentinel has been accidentally left off the
> end
> >   * of a list of registers.
> > @@ -1119,6 +1137,8 @@ struct ARMCPRegInfo {
> >      int type;
> >      /* Access rights: PL*_[RW] */
> >      int access;
> > +    /* Security state: ARM_CP_SECSTATE_* bits/values */
> > +    int secure;
> >      /* The opaque pointer passed to define_arm_cp_regs_with_opaque()
> when
> >       * this register was defined: can be used to hand data through to
> the
> >       * register read/write functions, since they are passed the
> ARMCPRegInfo*.
> > @@ -1128,12 +1148,28 @@ 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.
> > +     *
> > +     * Extra padding is added to align the default fieldoffset field
> with the
> > +     * non-secure bank_fieldoffsets entry.  This is necessary for
> maintaining
> > +     * the same storage offset when AArch64 and banked AArch32 are
> seperately
> > +     * defined.
> > +     *
> > +     * 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
> > --
> > 1.8.3.2
> >
>

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

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

* Re: [Qemu-devel] [PATCH v6 11/32] target-arm: add CPREG secure state support
  2014-10-17 13:37     ` Greg Bellows
@ 2014-10-17 15:20       ` Greg Bellows
  2014-10-17 15:27         ` Laurent Desnogues
  2014-10-17 19:12         ` Greg Bellows
  0 siblings, 2 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-17 15:20 UTC (permalink / raw)
  To: Edgar E. Iglesias
  Cc: Peter Maydell, QEMU Developers, Fabian Aggeler, Sergey Fedorov

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

So, I believe I reproduced the issue with gcc-4.4.  4.6 and 4.7 appear to
work fine.  I tried adding the "-fms-extensions" flag through configure's
"--extra-cflags" but it dow not appear to work.  Not sure if this is a
configure/make issue or if anonymous unions/structs are still disallowed.

I'll look into other options in case we deem it important to support older
compilers.

Greg

On 17 October 2014 08:37, Greg Bellows <greg.bellows@linaro.org> wrote:

> Hmmm, I had not encountered this as I am using a new compiler which is
> presumeably using -std=c11.   Here is what I am using:
>
> > gcc --version
> gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
>
> A quick search on gcc 4.4 shows that a different flag may be
> needed (-fms-extensions). There is also a special flag for 4.6 apparently.
>
> One question I have is how old of a toolchain do we support?  Peter?
>
> In the meantime, I'll try and reproduce on my end and try the additional
> flags.
>
> Thanks for pointing this out.
>
> Greg
>
> On 16 October 2014 20:32, Edgar E. Iglesias <edgar.iglesias@gmail.com>
> wrote:
>
>> On Fri, Oct 10, 2014 at 11:03:22AM -0500, Greg Bellows 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).
>>
>> Hi Greg,
>>
>> I gave the series a try through my auto-tester and it fails on this
>> patch with gcc-4.4:
>> $ gcc-4.4 --version
>> gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7
>>
>> We might need to pass additional options to gcc for the
>> anonymous structs/unions or use a different approach.
>>
>> Cheers,
>> Edgar
>>
>>
>>
>> >
>> > Also added secure state tracking field and flags.  This allows for
>> > identification of the register info secure state.
>> >
>> > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
>> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
>> >
>> > ==========
>> >
>> > v5 -> v6
>> > - Separate out secure CPREG flags
>> > - Add convenience macro for testing flags
>> > - Removed extraneous newline
>> > - Move add_cpreg_to_hashtable() functionality to a later commit for
>> which it is
>> >   dependent on.
>> > - Added comment explaining fieldoffset padding
>> >
>> > 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 | 42 +++++++++++++++++++++++++++++++++++++++---
>> >  1 file changed, 39 insertions(+), 3 deletions(-)
>> >
>> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
>> > index 59414f3..4d8de9e 100644
>> > --- a/target-arm/cpu.h
>> > +++ b/target-arm/cpu.h
>> > @@ -985,6 +985,24 @@ enum {
>> >      ARM_CP_STATE_BOTH = 2,
>> >  };
>> >
>> > +/* ARM CP register secure state flags.  These flags identify security
>> state
>> > + * attributes for a given CP register entry.
>> > + * The existence of both or neither secure and non-secure flags
>> indicates that
>> > + * the register has both a secure and non-secure hash entry.  A single
>> one of
>> > + * these flags causes the register to only be hashed for the specified
>> > + * security state.
>> > + * Although definitions may have any combination of the S/NS bits, each
>> > + * registered entry will only have one to identify whether the entry
>> is secure
>> > + * or non-secure.
>> > + */
>> > +enum {
>> > +    ARM_CP_SECSTATE_S =   (1 << 0), /* bit[0]: Secure state register */
>> > +    ARM_CP_SECSTATE_NS =  (1 << 1), /* bit[1]: Non-secure state
>> register */
>> > +};
>> > +
>> > +/* Convenience macro for checking for a specific bit */
>> > +#define ARM_CP_SECSTATE_TEST(_ri, _flag) (((_ri)->secure & (_flag)) ==
>> (_flag))
>> > +
>> >  /* Return true if cptype is a valid type field. This is used to try to
>> >   * catch errors where the sentinel has been accidentally left off the
>> end
>> >   * of a list of registers.
>> > @@ -1119,6 +1137,8 @@ struct ARMCPRegInfo {
>> >      int type;
>> >      /* Access rights: PL*_[RW] */
>> >      int access;
>> > +    /* Security state: ARM_CP_SECSTATE_* bits/values */
>> > +    int secure;
>> >      /* The opaque pointer passed to define_arm_cp_regs_with_opaque()
>> when
>> >       * this register was defined: can be used to hand data through to
>> the
>> >       * register read/write functions, since they are passed the
>> ARMCPRegInfo*.
>> > @@ -1128,12 +1148,28 @@ 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.
>> > +     *
>> > +     * Extra padding is added to align the default fieldoffset field
>> with the
>> > +     * non-secure bank_fieldoffsets entry.  This is necessary for
>> maintaining
>> > +     * the same storage offset when AArch64 and banked AArch32 are
>> seperately
>> > +     * defined.
>> > +     *
>> > +     * 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
>> > --
>> > 1.8.3.2
>> >
>>
>
>

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

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

* Re: [Qemu-devel] [PATCH v6 11/32] target-arm: add CPREG secure state support
  2014-10-17 15:20       ` Greg Bellows
@ 2014-10-17 15:27         ` Laurent Desnogues
  2014-10-17 15:30           ` Greg Bellows
  2014-10-17 19:12         ` Greg Bellows
  1 sibling, 1 reply; 50+ messages in thread
From: Laurent Desnogues @ 2014-10-17 15:27 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Edgar E. Iglesias, Sergey Fedorov, QEMU Developers,
	Fabian Aggeler, Peter Maydell

On Fri, Oct 17, 2014 at 5:20 PM, Greg Bellows <greg.bellows@linaro.org> wrote:
> So, I believe I reproduced the issue with gcc-4.4.  4.6 and 4.7 appear to
> work fine.  I tried adding the "-fms-extensions" flag through configure's
> "--extra-cflags" but it dow not appear to work.  Not sure if this is a
> configure/make issue or if anonymous unions/structs are still disallowed.
>
> I'll look into other options in case we deem it important to support older
> compilers.

gcc 4.4 is what comes with RHEL6/CentOS 6 so IMHO it should be
supported.


Laurent

> Greg
>
> On 17 October 2014 08:37, Greg Bellows <greg.bellows@linaro.org> wrote:
>>
>> Hmmm, I had not encountered this as I am using a new compiler which is
>> presumeably using -std=c11.   Here is what I am using:
>>
>> > gcc --version
>> gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
>>
>> A quick search on gcc 4.4 shows that a different flag may be needed
>> (-fms-extensions). There is also a special flag for 4.6 apparently.
>>
>> One question I have is how old of a toolchain do we support?  Peter?
>>
>> In the meantime, I'll try and reproduce on my end and try the additional
>> flags.
>>
>> Thanks for pointing this out.
>>
>> Greg
>>
>> On 16 October 2014 20:32, Edgar E. Iglesias <edgar.iglesias@gmail.com>
>> wrote:
>>>
>>> On Fri, Oct 10, 2014 at 11:03:22AM -0500, Greg Bellows 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).
>>>
>>> Hi Greg,
>>>
>>> I gave the series a try through my auto-tester and it fails on this
>>> patch with gcc-4.4:
>>> $ gcc-4.4 --version
>>> gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7
>>>
>>> We might need to pass additional options to gcc for the
>>> anonymous structs/unions or use a different approach.
>>>
>>> Cheers,
>>> Edgar
>>>
>>>
>>>
>>> >
>>> > Also added secure state tracking field and flags.  This allows for
>>> > identification of the register info secure state.
>>> >
>>> > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
>>> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
>>> >
>>> > ==========
>>> >
>>> > v5 -> v6
>>> > - Separate out secure CPREG flags
>>> > - Add convenience macro for testing flags
>>> > - Removed extraneous newline
>>> > - Move add_cpreg_to_hashtable() functionality to a later commit for
>>> > which it is
>>> >   dependent on.
>>> > - Added comment explaining fieldoffset padding
>>> >
>>> > 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 | 42 +++++++++++++++++++++++++++++++++++++++---
>>> >  1 file changed, 39 insertions(+), 3 deletions(-)
>>> >
>>> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
>>> > index 59414f3..4d8de9e 100644
>>> > --- a/target-arm/cpu.h
>>> > +++ b/target-arm/cpu.h
>>> > @@ -985,6 +985,24 @@ enum {
>>> >      ARM_CP_STATE_BOTH = 2,
>>> >  };
>>> >
>>> > +/* ARM CP register secure state flags.  These flags identify security
>>> > state
>>> > + * attributes for a given CP register entry.
>>> > + * The existence of both or neither secure and non-secure flags
>>> > indicates that
>>> > + * the register has both a secure and non-secure hash entry.  A single
>>> > one of
>>> > + * these flags causes the register to only be hashed for the specified
>>> > + * security state.
>>> > + * Although definitions may have any combination of the S/NS bits,
>>> > each
>>> > + * registered entry will only have one to identify whether the entry
>>> > is secure
>>> > + * or non-secure.
>>> > + */
>>> > +enum {
>>> > +    ARM_CP_SECSTATE_S =   (1 << 0), /* bit[0]: Secure state register
>>> > */
>>> > +    ARM_CP_SECSTATE_NS =  (1 << 1), /* bit[1]: Non-secure state
>>> > register */
>>> > +};
>>> > +
>>> > +/* Convenience macro for checking for a specific bit */
>>> > +#define ARM_CP_SECSTATE_TEST(_ri, _flag) (((_ri)->secure & (_flag)) ==
>>> > (_flag))
>>> > +
>>> >  /* Return true if cptype is a valid type field. This is used to try to
>>> >   * catch errors where the sentinel has been accidentally left off the
>>> > end
>>> >   * of a list of registers.
>>> > @@ -1119,6 +1137,8 @@ struct ARMCPRegInfo {
>>> >      int type;
>>> >      /* Access rights: PL*_[RW] */
>>> >      int access;
>>> > +    /* Security state: ARM_CP_SECSTATE_* bits/values */
>>> > +    int secure;
>>> >      /* The opaque pointer passed to define_arm_cp_regs_with_opaque()
>>> > when
>>> >       * this register was defined: can be used to hand data through to
>>> > the
>>> >       * register read/write functions, since they are passed the
>>> > ARMCPRegInfo*.
>>> > @@ -1128,12 +1148,28 @@ 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.
>>> > +     *
>>> > +     * Extra padding is added to align the default fieldoffset field
>>> > with the
>>> > +     * non-secure bank_fieldoffsets entry.  This is necessary for
>>> > maintaining
>>> > +     * the same storage offset when AArch64 and banked AArch32 are
>>> > seperately
>>> > +     * defined.
>>> > +     *
>>> > +     * 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
>>> > --
>>> > 1.8.3.2
>>> >
>>
>>
>

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

* Re: [Qemu-devel] [PATCH v6 11/32] target-arm: add CPREG secure state support
  2014-10-17 15:27         ` Laurent Desnogues
@ 2014-10-17 15:30           ` Greg Bellows
  0 siblings, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-17 15:30 UTC (permalink / raw)
  To: Laurent Desnogues
  Cc: Peter Maydell, Sergey Fedorov, QEMU Developers, Fabian Aggeler,
	Edgar E. Iglesias

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

Good to know.  Thanks Laurent.
On Oct 17, 2014 10:27 AM, "Laurent Desnogues" <laurent.desnogues@gmail.com>
wrote:

> On Fri, Oct 17, 2014 at 5:20 PM, Greg Bellows <greg.bellows@linaro.org>
> wrote:
> > So, I believe I reproduced the issue with gcc-4.4.  4.6 and 4.7 appear to
> > work fine.  I tried adding the "-fms-extensions" flag through configure's
> > "--extra-cflags" but it dow not appear to work.  Not sure if this is a
> > configure/make issue or if anonymous unions/structs are still disallowed.
> >
> > I'll look into other options in case we deem it important to support
> older
> > compilers.
>
> gcc 4.4 is what comes with RHEL6/CentOS 6 so IMHO it should be
> supported.
>
>
> Laurent
>
> > Greg
> >
> > On 17 October 2014 08:37, Greg Bellows <greg.bellows@linaro.org> wrote:
> >>
> >> Hmmm, I had not encountered this as I am using a new compiler which is
> >> presumeably using -std=c11.   Here is what I am using:
> >>
> >> > gcc --version
> >> gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
> >>
> >> A quick search on gcc 4.4 shows that a different flag may be needed
> >> (-fms-extensions). There is also a special flag for 4.6 apparently.
> >>
> >> One question I have is how old of a toolchain do we support?  Peter?
> >>
> >> In the meantime, I'll try and reproduce on my end and try the additional
> >> flags.
> >>
> >> Thanks for pointing this out.
> >>
> >> Greg
> >>
> >> On 16 October 2014 20:32, Edgar E. Iglesias <edgar.iglesias@gmail.com>
> >> wrote:
> >>>
> >>> On Fri, Oct 10, 2014 at 11:03:22AM -0500, Greg Bellows 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).
> >>>
> >>> Hi Greg,
> >>>
> >>> I gave the series a try through my auto-tester and it fails on this
> >>> patch with gcc-4.4:
> >>> $ gcc-4.4 --version
> >>> gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7
> >>>
> >>> We might need to pass additional options to gcc for the
> >>> anonymous structs/unions or use a different approach.
> >>>
> >>> Cheers,
> >>> Edgar
> >>>
> >>>
> >>>
> >>> >
> >>> > Also added secure state tracking field and flags.  This allows for
> >>> > identification of the register info secure state.
> >>> >
> >>> > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> >>> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
> >>> >
> >>> > ==========
> >>> >
> >>> > v5 -> v6
> >>> > - Separate out secure CPREG flags
> >>> > - Add convenience macro for testing flags
> >>> > - Removed extraneous newline
> >>> > - Move add_cpreg_to_hashtable() functionality to a later commit for
> >>> > which it is
> >>> >   dependent on.
> >>> > - Added comment explaining fieldoffset padding
> >>> >
> >>> > 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 | 42 +++++++++++++++++++++++++++++++++++++++---
> >>> >  1 file changed, 39 insertions(+), 3 deletions(-)
> >>> >
> >>> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> >>> > index 59414f3..4d8de9e 100644
> >>> > --- a/target-arm/cpu.h
> >>> > +++ b/target-arm/cpu.h
> >>> > @@ -985,6 +985,24 @@ enum {
> >>> >      ARM_CP_STATE_BOTH = 2,
> >>> >  };
> >>> >
> >>> > +/* ARM CP register secure state flags.  These flags identify
> security
> >>> > state
> >>> > + * attributes for a given CP register entry.
> >>> > + * The existence of both or neither secure and non-secure flags
> >>> > indicates that
> >>> > + * the register has both a secure and non-secure hash entry.  A
> single
> >>> > one of
> >>> > + * these flags causes the register to only be hashed for the
> specified
> >>> > + * security state.
> >>> > + * Although definitions may have any combination of the S/NS bits,
> >>> > each
> >>> > + * registered entry will only have one to identify whether the entry
> >>> > is secure
> >>> > + * or non-secure.
> >>> > + */
> >>> > +enum {
> >>> > +    ARM_CP_SECSTATE_S =   (1 << 0), /* bit[0]: Secure state register
> >>> > */
> >>> > +    ARM_CP_SECSTATE_NS =  (1 << 1), /* bit[1]: Non-secure state
> >>> > register */
> >>> > +};
> >>> > +
> >>> > +/* Convenience macro for checking for a specific bit */
> >>> > +#define ARM_CP_SECSTATE_TEST(_ri, _flag) (((_ri)->secure & (_flag))
> ==
> >>> > (_flag))
> >>> > +
> >>> >  /* Return true if cptype is a valid type field. This is used to try
> to
> >>> >   * catch errors where the sentinel has been accidentally left off
> the
> >>> > end
> >>> >   * of a list of registers.
> >>> > @@ -1119,6 +1137,8 @@ struct ARMCPRegInfo {
> >>> >      int type;
> >>> >      /* Access rights: PL*_[RW] */
> >>> >      int access;
> >>> > +    /* Security state: ARM_CP_SECSTATE_* bits/values */
> >>> > +    int secure;
> >>> >      /* The opaque pointer passed to define_arm_cp_regs_with_opaque()
> >>> > when
> >>> >       * this register was defined: can be used to hand data through
> to
> >>> > the
> >>> >       * register read/write functions, since they are passed the
> >>> > ARMCPRegInfo*.
> >>> > @@ -1128,12 +1148,28 @@ 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.
> >>> > +     *
> >>> > +     * Extra padding is added to align the default fieldoffset field
> >>> > with the
> >>> > +     * non-secure bank_fieldoffsets entry.  This is necessary for
> >>> > maintaining
> >>> > +     * the same storage offset when AArch64 and banked AArch32 are
> >>> > seperately
> >>> > +     * defined.
> >>> > +     *
> >>> > +     * 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
> >>> > --
> >>> > 1.8.3.2
> >>> >
> >>
> >>
> >
>

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

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

* Re: [Qemu-devel] [PATCH v6 11/32] target-arm: add CPREG secure state support
  2014-10-17 15:20       ` Greg Bellows
  2014-10-17 15:27         ` Laurent Desnogues
@ 2014-10-17 19:12         ` Greg Bellows
  1 sibling, 0 replies; 50+ messages in thread
From: Greg Bellows @ 2014-10-17 19:12 UTC (permalink / raw)
  To: Edgar E. Iglesias
  Cc: Peter Maydell, QEMU Developers, Fabian Aggeler, Sergey Fedorov

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

I fixed the issue by adding naming and a couple of macros for short-cutting
the name.  Interestingly and somewhat baffling, the only fields that needed
the fix were the bank_fieldoffsets and fieldoffsets.  It appears to be
related to static initialization using these fields as all the CP15
anonymous unions/structs don't throw errors.

Greg

On 17 October 2014 10:20, Greg Bellows <greg.bellows@linaro.org> wrote:

> So, I believe I reproduced the issue with gcc-4.4.  4.6 and 4.7 appear to
> work fine.  I tried adding the "-fms-extensions" flag through configure's
> "--extra-cflags" but it dow not appear to work.  Not sure if this is a
> configure/make issue or if anonymous unions/structs are still disallowed.
>
> I'll look into other options in case we deem it important to support older
> compilers.
>
> Greg
>
> On 17 October 2014 08:37, Greg Bellows <greg.bellows@linaro.org> wrote:
>
>> Hmmm, I had not encountered this as I am using a new compiler which is
>> presumeably using -std=c11.   Here is what I am using:
>>
>> > gcc --version
>> gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
>>
>> A quick search on gcc 4.4 shows that a different flag may be
>> needed (-fms-extensions). There is also a special flag for 4.6 apparently.
>>
>> One question I have is how old of a toolchain do we support?  Peter?
>>
>> In the meantime, I'll try and reproduce on my end and try the additional
>> flags.
>>
>> Thanks for pointing this out.
>>
>> Greg
>>
>> On 16 October 2014 20:32, Edgar E. Iglesias <edgar.iglesias@gmail.com>
>> wrote:
>>
>>> On Fri, Oct 10, 2014 at 11:03:22AM -0500, Greg Bellows 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).
>>>
>>> Hi Greg,
>>>
>>> I gave the series a try through my auto-tester and it fails on this
>>> patch with gcc-4.4:
>>> $ gcc-4.4 --version
>>> gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7
>>>
>>> We might need to pass additional options to gcc for the
>>> anonymous structs/unions or use a different approach.
>>>
>>> Cheers,
>>> Edgar
>>>
>>>
>>>
>>> >
>>> > Also added secure state tracking field and flags.  This allows for
>>> > identification of the register info secure state.
>>> >
>>> > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
>>> > Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
>>> >
>>> > ==========
>>> >
>>> > v5 -> v6
>>> > - Separate out secure CPREG flags
>>> > - Add convenience macro for testing flags
>>> > - Removed extraneous newline
>>> > - Move add_cpreg_to_hashtable() functionality to a later commit for
>>> which it is
>>> >   dependent on.
>>> > - Added comment explaining fieldoffset padding
>>> >
>>> > 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 | 42 +++++++++++++++++++++++++++++++++++++++---
>>> >  1 file changed, 39 insertions(+), 3 deletions(-)
>>> >
>>> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
>>> > index 59414f3..4d8de9e 100644
>>> > --- a/target-arm/cpu.h
>>> > +++ b/target-arm/cpu.h
>>> > @@ -985,6 +985,24 @@ enum {
>>> >      ARM_CP_STATE_BOTH = 2,
>>> >  };
>>> >
>>> > +/* ARM CP register secure state flags.  These flags identify security
>>> state
>>> > + * attributes for a given CP register entry.
>>> > + * The existence of both or neither secure and non-secure flags
>>> indicates that
>>> > + * the register has both a secure and non-secure hash entry.  A
>>> single one of
>>> > + * these flags causes the register to only be hashed for the specified
>>> > + * security state.
>>> > + * Although definitions may have any combination of the S/NS bits,
>>> each
>>> > + * registered entry will only have one to identify whether the entry
>>> is secure
>>> > + * or non-secure.
>>> > + */
>>> > +enum {
>>> > +    ARM_CP_SECSTATE_S =   (1 << 0), /* bit[0]: Secure state register
>>> */
>>> > +    ARM_CP_SECSTATE_NS =  (1 << 1), /* bit[1]: Non-secure state
>>> register */
>>> > +};
>>> > +
>>> > +/* Convenience macro for checking for a specific bit */
>>> > +#define ARM_CP_SECSTATE_TEST(_ri, _flag) (((_ri)->secure & (_flag))
>>> == (_flag))
>>> > +
>>> >  /* Return true if cptype is a valid type field. This is used to try to
>>> >   * catch errors where the sentinel has been accidentally left off the
>>> end
>>> >   * of a list of registers.
>>> > @@ -1119,6 +1137,8 @@ struct ARMCPRegInfo {
>>> >      int type;
>>> >      /* Access rights: PL*_[RW] */
>>> >      int access;
>>> > +    /* Security state: ARM_CP_SECSTATE_* bits/values */
>>> > +    int secure;
>>> >      /* The opaque pointer passed to define_arm_cp_regs_with_opaque()
>>> when
>>> >       * this register was defined: can be used to hand data through to
>>> the
>>> >       * register read/write functions, since they are passed the
>>> ARMCPRegInfo*.
>>> > @@ -1128,12 +1148,28 @@ 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.
>>> > +     *
>>> > +     * Extra padding is added to align the default fieldoffset field
>>> with the
>>> > +     * non-secure bank_fieldoffsets entry.  This is necessary for
>>> maintaining
>>> > +     * the same storage offset when AArch64 and banked AArch32 are
>>> seperately
>>> > +     * defined.
>>> > +     *
>>> > +     * 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
>>> > --
>>> > 1.8.3.2
>>> >
>>>
>>
>>
>

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

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

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

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-10 16:03 [Qemu-devel] [PATCH v6 00/32] target-arm: add Security Extensions for CPUs Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 01/32] target-arm: increase arrays of registers R13 & R14 Greg Bellows
2014-10-13 12:31   ` Peter Maydell
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 02/32] target-arm: add arm_is_secure() function Greg Bellows
2014-10-13 12:41   ` Peter Maydell
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 03/32] target-arm: reject switching to monitor mode Greg Bellows
2014-10-13 12:58   ` Peter Maydell
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 04/32] target-arm: rename arm_current_pl to arm_current_el Greg Bellows
2014-10-13 13:00   ` Peter Maydell
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 05/32] target-arm: make arm_current_el() return EL3 Greg Bellows
2014-10-13 13:04   ` Peter Maydell
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 06/32] target-arm: A32: Emulate the SMC instruction Greg Bellows
2014-10-13 13:06   ` Peter Maydell
2014-10-13 13:13     ` Greg Bellows
2014-10-13 13:36       ` Peter Maydell
2014-10-13 13:56         ` Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 07/32] target-arm: extend async excp masking Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 08/32] target-arm: add async excp target_el function Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 09/32] target-arm: add banked register accessors Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 10/32] target-arm: add non-secure Translation Block flag Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 11/32] target-arm: add CPREG secure state support Greg Bellows
2014-10-17  1:32   ` Edgar E. Iglesias
2014-10-17 13:37     ` Greg Bellows
2014-10-17 15:20       ` Greg Bellows
2014-10-17 15:27         ` Laurent Desnogues
2014-10-17 15:30           ` Greg Bellows
2014-10-17 19:12         ` Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 12/32] target-arm: add secure state bit to CPREG hash Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 13/32] target-arm: insert AArch32 cpregs twice into hashtable Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 14/32] target-arm: move AArch32 SCR into security reglist Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 15/32] target-arm: implement IRQ/FIQ routing to Monitor mode Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 16/32] target-arm: respect SCR.FW, SCR.AW and SCTLR.NMFI Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 17/32] target-arm: add NSACR register Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 18/32] target-arm: add SDER definition Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 19/32] target-arm: add MVBAR support Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 20/32] target-arm: add SCTLR_EL3 and make SCTLR banked Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 21/32] target-arm: make CSSELR banked Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 22/32] target-arm: add TTBR0_EL3 and make TTBR0/1 banked Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 23/32] target-arm: add TCR_EL3 and make TTBCR banked Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 24/32] target-arm: make c2_mask and c2_base_mask banked Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 25/32] target-arm: make DACR banked Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 26/32] target-arm: make IFSR banked Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 27/32] target-arm: make DFSR banked Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 28/32] target-arm: make IFAR/DFAR banked Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 29/32] target-arm: make PAR banked Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 30/32] target-arm: make c13 cp regs banked (FCSEIDR, ...) Greg Bellows
2014-10-15  3:17   ` Edgar E. Iglesias
2014-10-16 18:20     ` Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 31/32] target-arm: make MAIR0/1 banked Greg Bellows
2014-10-10 16:03 ` [Qemu-devel] [PATCH v6 32/32] target-arm: add cpu feature EL3 to CPUs with Security Extensions Greg Bellows

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.