All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs
@ 2014-06-10 23:54 Fabian Aggeler
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 01/32] target-arm: add cpu feature EL3 to CPUs with Security Extensions Fabian Aggeler
                   ` (32 more replies)
  0 siblings, 33 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

Hi,

this is round 3 of the Security Extension patches which started with
the TrustZone patchset by Samsung. Many patches were dropped or 
got separated from this patchset. It shows yet another mechanism of
register banking for EL3 running in Aarch32 mode. This version also
conforms better with the ARM ARMv8. The patches got reordered with 
banking related patches at the end. Most of the registers get converted
separately now.

The whole patchset is based on master with Edgar's patches of
yesterday (v2 target-arm: Parts of the Aarch64 EL2/3 exception model)
applied.

Patch 9,10,11 and 12 are added for some more discussion about Edgar's 
patches which break out masking and target_el. Parts of it could 
probably be added to Edgar's patchset. 

v2 -> v3:
* rebased
* reordered
* changed from ARM_FEATURE_SECURITY_EXTENSIONS to ARM_FEATURE_EL3
* renamed tz_cp_reginfo to security_cp_reginfo
* extended arm_is_secure() with EL3 handling
* rewrote nsacr patch
* removed MMU split for secure/nonsecure world
* removed arm_current_sctlr
* new banking scheme

v2: http://lists.gnu.org/archive/html/qemu-devel/2014-05/msg02522.html

Thanks,
Fabian

Fabian Aggeler (29):
  target-arm: add cpu feature EL3 to CPUs with Security Extensions
  target-arm: move Aarch32 SCR into security reglist
  target-arm: increase arrays of registers R13 & R14
  target-arm: add arm_is_secure() function
  target-arm: make arm_current_pl() return PL3
  target-arm: A32: Emulate the SMC instruction
  target-arm: extend Aarch32 async excp masking
  target-arm: extend Aarch64 SCR.{FIQ|IRQ} handling
  target-arm: add async excp target_el&mode function
  target-arm: use dedicated target_el function
  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 macros to access banked registers
  target-arm: insert Aarch32 cpregs twice into hashtable
  target-arm: arrayfying fieldoffset for banking
  target-arm: add SCTLR_EL3 and make SCTLR banked
  target-arm: make CSSELR banked
  target-arm: add TTBR0_EL3 and make TTBR0/1 banked
  target-arm: add TCR_EL3 and make TTBCR banked
  target-arm: make c2_mask and c2_base_mask banked
  target-arm: make DACR banked
  target-arm: make IFSR banked
  target-arm: make DFSR banked
  target-arm: make IFAR/DFAR banked
  target-arm: make PAR banked
  target-arm: make VBAR banked
  target-arm: make c13 cp regs banked (FCSEIDR,...)

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            |   4 +-
 target-arm/cpu.c           |  11 +-
 target-arm/cpu.h           | 453 +++++++++++++++++++++++++----
 target-arm/helper-a64.c    |  37 ++-
 target-arm/helper.c        | 702 ++++++++++++++++++++++++++++++++++-----------
 target-arm/internals.h     |   5 +
 target-arm/machine.c       |   4 +-
 target-arm/op_helper.c     |   2 +-
 target-arm/translate-a64.c |   1 +
 target-arm/translate.c     |  57 ++--
 target-arm/translate.h     |   1 +
 11 files changed, 1031 insertions(+), 246 deletions(-)

-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v3 01/32] target-arm: add cpu feature EL3 to CPUs with Security Extensions
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 02/32] target-arm: move Aarch32 SCR into security reglist Fabian Aggeler
                   ` (31 subsequent siblings)
  32 siblings, 0 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

Set ARM_FEATURE_EL3 feature for CPUs that implement Security Extensions.

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

diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index cd7a5df..bd581e6 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -550,6 +550,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;
@@ -636,6 +637,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;
@@ -702,6 +704,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).
@@ -768,6 +771,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] 78+ messages in thread

* [Qemu-devel] [PATCH v3 02/32] target-arm: move Aarch32 SCR into security reglist
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 01/32] target-arm: add cpu feature EL3 to CPUs with Security Extensions Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-12 21:55   ` Greg Bellows
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 03/32] target-arm: increase arrays of registers R13 & R14 Fabian Aggeler
                   ` (30 subsequent siblings)
  32 siblings, 1 reply; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

diff --git a/target-arm/helper.c b/target-arm/helper.c
index e157cc2..d8d6637 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -792,9 +792,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 = offsetof(CPUARMState, cp15.c1_scr),
-      .resetvalue = 0, },
     { .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 },
@@ -2216,6 +2213,13 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
+static const ARMCPRegInfo security_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, },
+    REGINFO_SENTINEL
+};
+
 static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                         uint64_t value)
 {
@@ -2479,6 +2483,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
     }
     if (arm_feature(env, ARM_FEATURE_EL3)) {
         define_arm_cp_regs(cpu, v8_el3_cp_reginfo);
+        define_arm_cp_regs(cpu, security_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] 78+ messages in thread

* [Qemu-devel] [PATCH v3 03/32] target-arm: increase arrays of registers R13 & R14
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 01/32] target-arm: add cpu feature EL3 to CPUs with Security Extensions Fabian Aggeler
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 02/32] target-arm: move Aarch32 SCR into security reglist Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-17  8:57   ` Edgar E. Iglesias
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 04/32] target-arm: add arm_is_secure() function Fabian Aggeler
                   ` (29 subsequent siblings)
  32 siblings, 1 reply; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
---
 target-arm/cpu.h     | 4 ++--
 target-arm/machine.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 060664f..903aa01 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 3bcc7cc..5ed495e 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -234,8 +234,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] 78+ messages in thread

* [Qemu-devel] [PATCH v3 04/32] target-arm: add arm_is_secure() function
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (2 preceding siblings ...)
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 03/32] target-arm: increase arrays of registers R13 & R14 Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-11 12:17   ` Sergey Fedorov
  2014-06-17  5:51   ` Edgar E. Iglesias
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 05/32] target-arm: reject switching to monitor mode Fabian Aggeler
                   ` (28 subsequent siblings)
  32 siblings, 2 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

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

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

* [Qemu-devel] [PATCH v3 05/32] target-arm: reject switching to monitor mode
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (3 preceding siblings ...)
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 04/32] target-arm: add arm_is_secure() function Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-12 21:55   ` Greg Bellows
  2014-06-17  5:43   ` Edgar E. Iglesias
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 06/32] target-arm: make arm_current_pl() return PL3 Fabian Aggeler
                   ` (27 subsequent siblings)
  32 siblings, 2 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

...from non-secure state.

Signed-off-by: Sergey Fedorov <s.fedorov@samsung.com>
Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
---
 target-arm/helper.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index d8d6637..ace8d8b 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3049,6 +3049,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] 78+ messages in thread

* [Qemu-devel] [PATCH v3 06/32] target-arm: make arm_current_pl() return PL3
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (4 preceding siblings ...)
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 05/32] target-arm: reject switching to monitor mode Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-17  5:40   ` Edgar E. Iglesias
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 07/32] target-arm: add non-secure Translation Block flag Fabian Aggeler
                   ` (26 subsequent siblings)
  32 siblings, 1 reply; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

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

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index cb0da6b..14007a9 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.
@@ -710,7 +710,6 @@ static inline int arm_feature(CPUARMState *env, int feature)
     return (env->features & (1ULL << feature)) != 0;
 }
 
-
 /* Return true if exception level below EL3 is in secure state */
 static inline bool arm_is_secure_below_el3(CPUARMState *env)
 {
@@ -751,11 +750,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
@@ -947,9 +947,12 @@ static inline int arm_current_pl(CPUARMState *env)
 
     if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR) {
         return 0;
+    } else if (arm_is_secure(env)) {
+        /* Secure PL1 and monitor mode are mapped to PL3 */
+        return 3;
     }
-    /* We don't currently implement the Virtualization or TrustZone
-     * extensions, so PL2 and PL3 don't exist for us.
+    /* We currently do not implement the Virtualization extensions, so PL2 does
+     * not exist for us.
      */
     return 1;
 }
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v3 07/32] target-arm: add non-secure Translation Block flag
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (5 preceding siblings ...)
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 06/32] target-arm: make arm_current_pl() return PL3 Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-17  9:15   ` Edgar E. Iglesias
  2014-06-25  4:15   ` Edgar E. Iglesias
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 08/32] target-arm: A32: Emulate the SMC instruction Fabian Aggeler
                   ` (25 subsequent siblings)
  32 siblings, 2 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

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

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

Signed-off-by: Sergey Fedorov <s.fedorov@samsung.com>
Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
---
 target-arm/cpu.h           | 10 ++++++++++
 target-arm/translate-a64.c |  1 +
 target-arm/translate.c     |  3 +++
 target-arm/translate.h     |  1 +
 4 files changed, 15 insertions(+)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 14007a9..661bfbe 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1275,6 +1275,8 @@ static inline int cpu_mmu_index (CPUARMState *env)
 #define ARM_TBFLAG_BSWAP_CODE_MASK  (1 << ARM_TBFLAG_BSWAP_CODE_SHIFT)
 #define ARM_TBFLAG_CPACR_FPEN_SHIFT 17
 #define ARM_TBFLAG_CPACR_FPEN_MASK  (1 << ARM_TBFLAG_CPACR_FPEN_SHIFT)
+#define ARM_TBFLAG_NS_SHIFT         18
+#define ARM_TBFLAG_NS_MASK          (1 << ARM_TBFLAG_NS_SHIFT)
 
 /* Bit usage when in AArch64 state */
 #define ARM_TBFLAG_AA64_EL_SHIFT    0
@@ -1305,6 +1307,8 @@ static inline int cpu_mmu_index (CPUARMState *env)
     (((F) & ARM_TBFLAG_AA64_EL_MASK) >> ARM_TBFLAG_AA64_EL_SHIFT)
 #define ARM_TBFLAG_AA64_FPEN(F) \
     (((F) & ARM_TBFLAG_AA64_FPEN_MASK) >> ARM_TBFLAG_AA64_FPEN_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)
@@ -1318,6 +1322,9 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
         if (fpen == 3 || (fpen == 1 && arm_current_pl(env) != 0)) {
             *flags |= ARM_TBFLAG_AA64_FPEN_MASK;
         }
+        if (!arm_is_secure(env)) {
+            *flags |= ARM_TBFLAG_NS_MASK;
+        }
     } else {
         int privmode;
         *pc = env->regs[15];
@@ -1334,6 +1341,9 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
         if (privmode) {
             *flags |= ARM_TBFLAG_PRIV_MASK;
         }
+        if (!arm_is_secure(env)) {
+            *flags |= ARM_TBFLAG_NS_MASK;
+        }
         if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
             || arm_el_is_aa64(env, 1)) {
             *flags |= ARM_TBFLAG_VFPEN_MASK;
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 8cb326f..16b706c 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -10878,6 +10878,7 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
     dc->condexec_cond = 0;
 #if !defined(CONFIG_USER_ONLY)
     dc->user = (ARM_TBFLAG_AA64_EL(tb->flags) == 0);
+    dc->ns = ARM_TBFLAG_NS(tb->flags);
 #endif
     dc->cpacr_fpen = ARM_TBFLAG_AA64_FPEN(tb->flags);
     dc->vec_len = 0;
diff --git a/target-arm/translate.c b/target-arm/translate.c
index cf4e767..bf17952 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -53,8 +53,10 @@ static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
 
 #if defined(CONFIG_USER_ONLY)
 #define IS_USER(s) 1
+#define IS_NS(s) 1
 #else
 #define IS_USER(s) (s->user)
+#define IS_NS(s) (s->ns)
 #endif
 
 TCGv_ptr cpu_env;
@@ -10904,6 +10906,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
     dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
 #if !defined(CONFIG_USER_ONLY)
     dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
+    dc->ns = ARM_TBFLAG_NS(tb->flags);
 #endif
     dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags);
     dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
diff --git a/target-arm/translate.h b/target-arm/translate.h
index 31a0104..6e8620a 100644
--- a/target-arm/translate.h
+++ b/target-arm/translate.h
@@ -19,6 +19,7 @@ typedef struct DisasContext {
     int bswap_code;
 #if !defined(CONFIG_USER_ONLY)
     int user;
+    int ns;
 #endif
     bool cpacr_fpen; /* FP enabled via CPACR.FPEN */
     bool vfp_enabled; /* FP enabled via FPSCR.EN */
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v3 08/32] target-arm: A32: Emulate the SMC instruction
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (6 preceding siblings ...)
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 07/32] target-arm: add non-secure Translation Block flag Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 09/32] target-arm: extend Aarch32 async excp masking Fabian Aggeler
                   ` (24 subsequent siblings)
  32 siblings, 0 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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>
---
 target-arm/helper.c    | 11 +++++++++++
 target-arm/internals.h |  5 +++++
 target-arm/translate.c | 35 +++++++++++++++++++++++++----------
 3 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index ace8d8b..5822353 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3588,6 +3588,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.  */
@@ -3606,6 +3612,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);
     env->spsr = cpsr_read(env);
     /* Clear IT bits.  */
diff --git a/target-arm/internals.h b/target-arm/internals.h
index 8815f7c..cda049a 100644
--- a/target-arm/internals.h
+++ b/target-arm/internals.h
@@ -224,6 +224,11 @@ static inline uint32_t syn_aa32_svc(uint16_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(uint16_t imm16)
 {
     return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | imm16;
diff --git a/target-arm/translate.c b/target-arm/translate.c
index bf17952..f657389 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -7840,15 +7840,25 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
         case 7:
         {
             int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
-            /* SMC instruction (op1 == 3)
-               and undefined instructions (op1 == 0 || op1 == 2)
-               will trap */
-            if (op1 != 1) {
+            if (op1 == 1) {
+                /* bkpt */
+                ARCH(5);
+                gen_exception_insn(s, 4, EXCP_BKPT,
+                        syn_aa32_bkpt(imm16, false));
+            } else if (op1 == 3) {
+                /* smi/smc */
+                if (!arm_dc_feature(s, ARM_FEATURE_EL3) ||
+                        s->current_pl == 0) {
+                    goto illegal_op;
+                }
+                tmp = tcg_const_i32(syn_aa32_smc());
+                gen_set_pc_im(s, s->pc);
+                gen_helper_smc(cpu_env, tmp);
+                tcg_temp_free_i32(tmp);
+                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 */
@@ -9679,9 +9689,14 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
 
                 if (insn & (1 << 26)) {
                     /* Secure monitor call (v6Z) */
-                    qemu_log_mask(LOG_UNIMP,
-                                  "arm: unimplemented secure monitor call\n");
-                    goto illegal_op; /* not implemented.  */
+                    if (!arm_dc_feature(s, ARM_FEATURE_EL3) ||
+                            s->current_pl == 0) {
+                        goto illegal_op;
+                    }
+                    tmp = tcg_const_i32(syn_aa32_smc());
+                    gen_set_pc_im(s, s->pc);
+                    gen_helper_smc(cpu_env, tmp);
+                    tcg_temp_free_i32(tmp);
                 } else {
                     op = (insn >> 20) & 7;
                     switch (op) {
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v3 09/32] target-arm: extend Aarch32 async excp masking
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (7 preceding siblings ...)
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 08/32] target-arm: A32: Emulate the SMC instruction Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-17  7:48   ` Edgar E. Iglesias
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 10/32] target-arm: extend Aarch64 SCR.{FIQ|IRQ} handling Fabian Aggeler
                   ` (23 subsequent siblings)
  32 siblings, 1 reply; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
---
 target-arm/cpu.h | 77 ++++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 61 insertions(+), 16 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 661bfbe..f8531aa 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -581,6 +581,8 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
 #define SCR_IRQ       (1U << 1)
 #define SCR_FIQ       (1U << 2)
 #define SCR_EA        (1U << 3)
+#define SCR_FW        (1U << 4)
+#define SCR_AW        (1U << 5)
 #define SCR_SMD       (1U << 7)
 #define SCR_HCE       (1U << 8)
 #define SCR_SIF       (1U << 9)
@@ -1183,30 +1185,73 @@ 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 target_el = arm_excp_target_el(cs, excp_idx);
-    /* FIXME: Use actual secure state.  */
-    bool secure = false;
-    /* Interrupts can only be hypervised and routed to
-     * EL2 if we are in NS EL0/1.
-     */
-    bool irq_can_hyp = !secure && cur_el < 2 && target_el == 2;
+    bool secure = arm_is_secure(env);
+
     bool irq_unmasked = ((IS_M(env) && env->regs[15] < 0xfffffff0)
                           || !(env->daif & PSTATE_I));
 
-    /* Don't take exceptions if they target a lower EL.  */
-    if (cur_el > target_el) {
-        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 (!secure) {
+            if (arm_feature(env, ARM_FEATURE_EL2) &&
+                    (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
+                 */
+                if (cur_el < 2) {
+                    return true;
+                } else if (arm_feature(env, ARM_FEATURE_EL3) &&
+                        (env->cp15.scr_el3 & SCR_FIQ)) {
+                    return true;
+                }
+            }
+            /* 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 (!secure) {
+            if (arm_feature(env, ARM_FEATURE_EL2) &&
+                    (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
+                 */
+                if (cur_el < 2) {
+                    return true;
+                } else if (arm_feature(env, ARM_FEATURE_EL3) &&
+                        (env->cp15.scr_el3 & SCR_IRQ)) {
+                    return true;
+                }
+            }
         }
         return irq_unmasked;
     case EXCP_VFIQ:
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v3 10/32] target-arm: extend Aarch64 SCR.{FIQ|IRQ} handling
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (8 preceding siblings ...)
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 09/32] target-arm: extend Aarch32 async excp masking Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-12 21:55   ` Greg Bellows
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 11/32] target-arm: add async excp target_el&mode function Fabian Aggeler
                   ` (22 subsequent siblings)
  32 siblings, 1 reply; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index f8531aa..b786a5a 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1195,20 +1195,43 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
      * (table G1-18/G1-19) */
     switch (excp_idx) {
     case EXCP_FIQ:
+        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) &&
-                    (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
-                 */
-                if (cur_el < 2) {
-                    return true;
-                } else if (arm_feature(env, ARM_FEATURE_EL3) &&
-                        (env->cp15.scr_el3 & SCR_FIQ)) {
-                    return true;
+            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
@@ -1236,20 +1259,43 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
         }
         return !(env->daif & PSTATE_F);
     case EXCP_IRQ:
+        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) &&
-                    (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
-                 */
-                if (cur_el < 2) {
-                    return true;
-                } else if (arm_feature(env, ARM_FEATURE_EL3) &&
-                        (env->cp15.scr_el3 & SCR_IRQ)) {
-                    return true;
+            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;
                 }
             }
         }
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v3 11/32] target-arm: add async excp target_el&mode function
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (9 preceding siblings ...)
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 10/32] target-arm: extend Aarch64 SCR.{FIQ|IRQ} handling Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-12 21:56   ` Greg Bellows
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 12/32] target-arm: use dedicated target_el function Fabian Aggeler
                   ` (21 subsequent siblings)
  32 siblings, 1 reply; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index b786a5a..52e679f 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -768,6 +768,9 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
 
 void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx);
+inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t *target_mode,
+                                        uint32_t excp_idx, uint32_t cur_el,
+                                        bool secure);
 
 /* Interface between CPU and Interrupt controller.  */
 void armv7m_nvic_set_pending(void *opaque, int irq);
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 5822353..8333b52 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3224,6 +3224,21 @@ uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
     return 0;
 }
 
+inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t *target_mode,
+                                        uint32_t excp_idx, uint32_t cur_el,
+                                        bool secure)
+{
+    switch (excp_idx) {
+    case EXCP_IRQ:
+        *target_mode = ARM_CPU_MODE_IRQ;
+        break;
+    case EXCP_FIQ:
+        *target_mode = ARM_CPU_MODE_FIQ;
+        break;
+    }
+    return 1;
+}
+
 unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
 {
     return 1;
@@ -3285,6 +3300,128 @@ void switch_mode(CPUARMState *env, int mode)
 }
 
 /*
+ * Determine the target EL for physical exceptions
+ */
+inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t *target_mode,
+                                        uint32_t excp_idx, uint32_t cur_el,
+                                        bool secure)
+{
+    CPUARMState *env = cs->env_ptr;
+    uint32_t target_el = 1;
+    uint32_t excp_mode = 0;
+
+    bool scr_routing = 0; /* IRQ, FIQ, EA */
+    bool hcr_routing = 0; /* IMO, FMO, AMO */
+
+    switch (excp_idx) {
+    case EXCP_IRQ:
+        scr_routing = (env->cp15.scr_el3 & SCR_IRQ);
+        hcr_routing = (env->cp15.hcr_el2 & HCR_IMO);
+        excp_mode = ARM_CPU_MODE_IRQ;
+        break;
+    case EXCP_FIQ:
+        scr_routing = (env->cp15.scr_el3 & SCR_FIQ);
+        hcr_routing = (env->cp15.hcr_el2 & HCR_FMO);
+        excp_mode = ARM_CPU_MODE_FIQ;
+    }
+
+    /* If HCR.TGE is set all exceptions that would be routed to EL1 are
+     * routed to EL2 (in non-secure world).
+     */
+    if (arm_feature(env, ARM_FEATURE_EL2) && (env->cp15.hcr_el2 & HCR_TGE)) {
+        hcr_routing = 1;
+    }
+
+    /* Determine target EL according to ARM ARMv8 tables G1-15 and G1-16 */
+    if (arm_el_is_aa64(env, 3)) {
+        /* EL3 in Aarch64 */
+        if (scr_routing) {
+            /* IRQ|FIQ|EA == 1 */
+            target_el = 3;
+        } else {
+            if (hcr_routing) {
+                /* IRQ|FIQ|EA == 0
+                 * IMO|FMO|AMO == 1 */
+                if (secure) {
+                    /* Secure */
+                    target_el = 1;
+                    if (!arm_el_is_aa64(env, 1)) {
+                        /* EL1 using Aarch32 */
+                        *target_mode = ARM_CPU_MODE_ABT;
+                    }
+                } else if (cur_el < 2) {
+                    /* Non-Secure goes to EL2 */
+                    target_el = 2;
+                    if (!arm_el_is_aa64(env, 2)) {
+                        /* EL2 using Aarch32 */
+                        *target_mode = ARM_CPU_MODE_HYP;
+                    }
+                }
+            } else if (env->cp15.scr_el3 & SCR_RW) {
+                /* IRQ|FIQ|EA == 0
+                 * IMO|FMO|AMO == 0
+                 * RW == 1 (Next lower level is Aarch64)
+                 */
+                if (cur_el < 2) {
+                    target_el = 1;
+                } else {
+                    /* Interrupt not taken but remains pending */
+                }
+            } else {
+                /* IRQ|FIQ|EA == 0
+                 * IMO|FMO|AMO == 0
+                 * RW == 0 (Next lower level is Aarch64)
+                 */
+                if (cur_el < 2) {
+                    target_el = 1;
+                    *target_mode = ARM_CPU_MODE_ABT;
+                } else if (cur_el == 2) {
+                    target_el = 2;
+                    *target_mode = ARM_CPU_MODE_HYP;
+                } else {
+                    /* Interrupt not taken but remains pending */
+                }
+            }
+        }
+    } else {
+        /* EL3 in Aarch32 */
+        if (scr_routing) {
+            /* IRQ|FIQ|EA == 1 */
+            target_el = 3;
+            *target_mode = ARM_CPU_MODE_MON;
+        } else {
+            if (hcr_routing) {
+                /* IRQ|FIQ|EA == 0
+                 * IMO|FMO|AMO == 1
+                 */
+                if (secure) {
+                    target_el = 3;
+                    *target_mode = excp_mode;
+                } else {
+                    target_el = 2;
+                    *target_mode = ARM_CPU_MODE_HYP;
+                }
+            } else {
+                /* IRQ|FIQ|EA == 0
+                 * IMO|FMO|AMO == 0
+                 */
+                if (cur_el < 2) {
+                    target_el = 1;
+                    *target_mode = excp_mode;
+                } else if (cur_el == 2) {
+                    target_el = 2;
+                    *target_mode = ARM_CPU_MODE_HYP;
+                } else if (secure) {
+                    target_el = 3;
+                    *target_mode = excp_mode;
+                }
+            }
+        }
+    }
+    return target_el;
+}
+
+/*
  * Determine the target EL for a given exception type.
  */
 unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v3 12/32] target-arm: use dedicated target_el function
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (10 preceding siblings ...)
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 11/32] target-arm: add async excp target_el&mode function Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 13/32] target-arm: implement IRQ/FIQ routing to Monitor mode Fabian Aggeler
                   ` (20 subsequent siblings)
  32 siblings, 0 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
---
 target-arm/helper.c | 24 ++++++------------------
 1 file changed, 6 insertions(+), 18 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 8333b52..b9b458e 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3429,14 +3429,10 @@ unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
     CPUARMState *env = cs->env_ptr;
     unsigned int cur_el = arm_current_pl(env);
     unsigned int target_el = 1;
+    unsigned int target_mode;
     bool route_to_el2 = false;
-    /* FIXME: Use actual secure state.  */
-    bool secure = false;
 
-    if (!env->aarch64) {
-        /* TODO: Add EL2 and 3 exception handling for AArch32.  */
-        return 1;
-    }
+    bool secure = arm_is_secure(env);
 
     if (!secure
         && arm_feature(env, ARM_FEATURE_EL2)
@@ -3458,18 +3454,10 @@ 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;
-
-            if (!secure && (env->cp15.hcr_el2 & hcr_mask)) {
-                target_el = 2;
-            }
-            if (env->cp15.scr_el3 & scr_mask) {
-                target_el = 3;
-            }
-            break;
-        }
+    case EXCP_IRQ:
+        target_el = arm_phys_excp_target_el(cs, &target_mode, 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] 78+ messages in thread

* [Qemu-devel] [PATCH v3 13/32] target-arm: implement IRQ/FIQ routing to Monitor mode
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (11 preceding siblings ...)
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 12/32] target-arm: use dedicated target_el function Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 14/32] target-arm: Respect SCR.FW, SCR.AW and SCTLR.NMFI Fabian Aggeler
                   ` (19 subsequent siblings)
  32 siblings, 0 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

diff --git a/target-arm/helper.c b/target-arm/helper.c
index b9b458e..2fbecfa 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3705,12 +3705,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] 78+ messages in thread

* [Qemu-devel] [PATCH v3 14/32] target-arm: Respect SCR.FW, SCR.AW and SCTLR.NMFI
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (12 preceding siblings ...)
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 13/32] target-arm: implement IRQ/FIQ routing to Monitor mode Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-12 22:43   ` Greg Bellows
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 15/32] target-arm: add NSACR register Fabian Aggeler
                   ` (18 subsequent siblings)
  32 siblings, 1 reply; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

bits when modifying CPSR.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
---
 target-arm/helper.c | 42 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 2fbecfa..f6ff4aa 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3091,9 +3091,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.
@@ -3105,6 +3102,45 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
             switch_mode(env, val & CPSR_M);
         }
     }
+
+    /* In an implementation that does not include Virtualization Extensions
+     * the SCR.FW and SCR.AW bit control whether non-secure software is allowed
+     * to change the CPSR_F and CPSR_A bits respectively.
+     */
+    if ((mask & CPSR_A)
+            && (val & CPSR_A) != (env->uncached_cpsr & CPSR_A)
+            && arm_feature(env, ARM_FEATURE_EL3)
+            && !(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 set\n");
+        mask &= ~CPSR_A;
+    }
+
+    if ((mask & CPSR_F)) {
+        /* Pre ARMv8: 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 (!arm_feature(env, ARM_FEATURE_V8) &&
+            (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;
+        }
+
+        if ((val & CPSR_F) != (env->uncached_cpsr & CPSR_F)
+                && arm_feature(env, ARM_FEATURE_EL3)
+                && !(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 set\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] 78+ messages in thread

* [Qemu-devel] [PATCH v3 15/32] target-arm: add NSACR register
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (13 preceding siblings ...)
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 14/32] target-arm: Respect SCR.FW, SCR.AW and SCTLR.NMFI Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-13 18:27   ` Greg Bellows
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 16/32] target-arm: add SDER definition Fabian Aggeler
                   ` (17 subsequent siblings)
  32 siblings, 1 reply; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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>
---
 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 52e679f..bc9edaa 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -182,6 +182,7 @@ typedef struct CPUARMState {
         uint64_t c1_coproc; /* Coprocessor access register.  */
         uint32_t c1_xscaleauxcr; /* XScale auxiliary control register.  */
         uint32_t c1_scr; /* secure config 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.  */
@@ -593,6 +594,11 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
 #define SCR_RES1_MASK (3U << 4)
 #define SCR_MASK      (0x3fff & ~SCR_RES1_MASK)
 
+#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 f6ff4aa..9671f9f 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -489,7 +489,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);
             }
@@ -501,6 +513,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;
@@ -2184,6 +2197,55 @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
     raw_write(env, ri, value);
 }
 
+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_pl(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,
@@ -2217,6 +2279,10 @@ static const ARMCPRegInfo security_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, },
+    { .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] 78+ messages in thread

* [Qemu-devel] [PATCH v3 16/32] target-arm: add SDER definition
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (14 preceding siblings ...)
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 15/32] target-arm: add NSACR register Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 17/32] target-arm: add MVBAR support Fabian Aggeler
                   ` (16 subsequent siblings)
  32 siblings, 0 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

Signed-off-by: Sergey Fedorov <s.fedorov@samsung.com>
Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
---
 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 bc9edaa..c76a31c 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -182,6 +182,7 @@ typedef struct CPUARMState {
         uint64_t c1_coproc; /* Coprocessor access register.  */
         uint32_t c1_xscaleauxcr; /* XScale auxiliary control register.  */
         uint32_t c1_scr; /* secure config 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 9671f9f..4bf203e 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2279,6 +2279,9 @@ static const ARMCPRegInfo security_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, },
+    { .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] 78+ messages in thread

* [Qemu-devel] [PATCH v3 17/32] target-arm: add MVBAR support
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (15 preceding siblings ...)
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 16/32] target-arm: add SDER definition Fabian Aggeler
@ 2014-06-10 23:54 ` Fabian Aggeler
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 18/32] target-arm: add macros to access banked registers Fabian Aggeler
                   ` (15 subsequent siblings)
  32 siblings, 0 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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>
---
 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 c76a31c..221b847 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -212,6 +212,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 4bf203e..f9b2374 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2286,6 +2286,9 @@ static const ARMCPRegInfo security_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
 };
 
@@ -3837,16 +3840,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] 78+ messages in thread

* [Qemu-devel] [PATCH v3 18/32] target-arm: add macros to access banked registers
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (16 preceding siblings ...)
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 17/32] target-arm: add MVBAR support Fabian Aggeler
@ 2014-06-10 23:55 ` Fabian Aggeler
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 19/32] target-arm: insert Aarch32 cpregs twice into hashtable Fabian Aggeler
                   ` (14 subsequent siblings)
  32 siblings, 0 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

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

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

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

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

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

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

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

* [Qemu-devel] [PATCH v3 19/32] target-arm: insert Aarch32 cpregs twice into hashtable
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (17 preceding siblings ...)
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 18/32] target-arm: add macros to access banked registers Fabian Aggeler
@ 2014-06-10 23:55 ` Fabian Aggeler
  2014-06-12 19:49   ` Sergey Fedorov
  2014-06-25  5:20   ` Edgar E. Iglesias
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 20/32] target-arm: arrayfying fieldoffset for banking Fabian Aggeler
                   ` (13 subsequent siblings)
  32 siblings, 2 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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>
---
 target-arm/cpu.h       | 14 +++++++++++---
 target-arm/helper.c    | 20 ++++++++++++++++----
 target-arm/translate.c | 19 +++++++++++++------
 3 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 0b8042c..d4eab39 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -831,6 +831,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;
@@ -848,9 +849,16 @@ void armv7m_nvic_complete_irq(void *opaque, int irq);
 #define CP_REG_AA64_SHIFT 28
 #define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
 
-#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2)   \
-    (((cp) << 16) | ((is64) << 15) | ((crn) << 11) |    \
-     ((crm) << 7) | ((opc1) << 3) | (opc2))
+/* To enable banking of coprocessor registers depending on ns-bit we
+ * add a bit to distinguish between secure and non-secure cpregs in the
+ * hashtable.
+ */
+#define CP_REG_NS_SHIFT 27
+#define CP_REG_NS_MASK(nsbit) (nsbit << CP_REG_NS_SHIFT)
+
+#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2, ns)   \
+    (CP_REG_NS_MASK(ns) | ((cp) << 16) | ((is64) << 15) |   \
+     ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
 
 #define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
     (CP_REG_AA64_MASK |                                 \
diff --git a/target-arm/helper.c b/target-arm/helper.c
index f9b2374..610245d 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2883,7 +2883,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.
@@ -2917,7 +2917,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;
@@ -3066,8 +3066,20 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
                     if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
                         continue;
                     }
-                    add_cpreg_to_hashtable(cpu, r, opaque, state,
-                                           crm, opc1, opc2);
+                    if (state == ARM_CP_STATE_AA32) {
+                        /* Under Aarch32 CP registers can be common
+                         * (same for secure and non-secure world) or banked.
+                         */
+                        add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                crm, opc1, opc2, !SCR_NS);
+                        add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                crm, opc1, opc2, SCR_NS);
+                    } else {
+                        /* Aarch64 registers get mapped to non-secure instance
+                         * of Aarch32 */
+                        add_cpreg_to_hashtable(cpu, r, opaque, state,
+                                crm, opc1, opc2, SCR_NS);
+                    }
                 }
             }
         }
diff --git a/target-arm/translate.c b/target-arm/translate.c
index f657389..30d9592 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6968,7 +6968,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
 
 static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 {
-    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
+    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2, ns;
     const ARMCPRegInfo *ri;
 
     cpnum = (insn >> 8) & 0xf;
@@ -7012,8 +7012,11 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
     isread = (insn >> 20) & 1;
     rt = (insn >> 12) & 0xf;
 
+    /* Monitor mode is always treated as secure but cp register reads/writes
+     * can access secure and non-secure instances using SCR.NS bit*/
+    ns = IS_NS(s) ? 1 : !USE_SECURE_REG(env);
     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, ns));
     if (ri) {
         /* Check access permissions */
         if (!cp_access_ok(s->current_pl, ri, isread)) {
@@ -7200,12 +7203,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,
+                      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,
+                      ns ? "non-secure" : "secure");
     }
 
     return 1;
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v3 20/32] target-arm: arrayfying fieldoffset for banking
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (18 preceding siblings ...)
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 19/32] target-arm: insert Aarch32 cpregs twice into hashtable Fabian Aggeler
@ 2014-06-10 23:55 ` Fabian Aggeler
  2014-06-13 20:18   ` Greg Bellows
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 21/32] target-arm: add SCTLR_EL3 and make SCTLR banked Fabian Aggeler
                   ` (12 subsequent siblings)
  32 siblings, 1 reply; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
---
 target-arm/cpu.h    | 16 +++++++++++++---
 target-arm/helper.c | 35 +++++++++++++++++++++++------------
 2 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index d4eab39..7d7782e 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1086,12 +1086,22 @@ struct ARMCPRegInfo {
      * fieldoffset is non-zero, the reset value of the register.
      */
     uint64_t resetvalue;
-    /* Offset of the field in CPUARMState for this register. This is not
-     * needed if either:
+    /* Offsets of the fields (secure/non-secure) in CPUARMState for this
+     * register. The array will be accessed by the ns bit which means the
+     * secure instance has to be at [0] while the non-secure instance must be
+     * at [1]. If a register is not banked .fieldoffset can be used, which maps
+     * to the non-secure bank.
+     * This is not needed if either:
      *  1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
      *  2. both readfn and writefn are specified
      */
-    ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
+    union { /* offsetof(CPUARMState, field) */
+        struct {
+            ptrdiff_t fieldoffset_padding;
+            ptrdiff_t fieldoffset;
+        };
+        ptrdiff_t bank_fieldoffsets[2];
+    };
     /* Function for making any access checks for this register in addition to
      * those specified by the 'access' permissions bits. If NULL, no extra
      * checks required. The access check is performed at runtime, not at
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 610245d..dfaf636 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2891,20 +2891,31 @@ 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.
-         */
-        r2->cp = 15;
-        r2->type |= ARM_CP_NO_MIGRATE;
-        r2->resetfn = arm_cp_reset_ignore;
-#ifdef HOST_WORDS_BIGENDIAN
-        if (r2->fieldoffset) {
-            r2->fieldoffset += sizeof(uint32_t);
+
+    if (state == ARM_CP_STATE_AA32) {
+        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 (r->state == ARM_CP_STATE_BOTH) {
+            /* The AArch32 view of a shared register sees the lower 32 bits
+             * of a 64 bit backing field. It is not migratable as the AArch64
+             * view handles that. AArch64 also handles reset.
+             * We assume it is a cp15 register.
+             */
+            r2->cp = 15;
+            r2->type |= ARM_CP_NO_MIGRATE;
+            r2->resetfn = arm_cp_reset_ignore;
+#ifdef HOST_WORDS_BIGENDIAN
+            if (r2->fieldoffset) {
+                r2->fieldoffset += sizeof(uint32_t);
+            }
 #endif
+        }
     }
     if (state == ARM_CP_STATE_AA64) {
         /* To allow abbreviation of ARMCPRegInfo
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v3 21/32] target-arm: add SCTLR_EL3 and make SCTLR banked
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (19 preceding siblings ...)
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 20/32] target-arm: arrayfying fieldoffset for banking Fabian Aggeler
@ 2014-06-10 23:55 ` Fabian Aggeler
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 22/32] target-arm: make CSSELR banked Fabian Aggeler
                   ` (11 subsequent siblings)
  32 siblings, 0 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
---
 hw/arm/pxa2xx.c        |  2 +-
 target-arm/cpu.c       |  5 ++--
 target-arm/cpu.h       | 13 ++++++++-
 target-arm/helper.c    | 78 +++++++++++++++++++++++++++++---------------------
 target-arm/op_helper.c |  2 +-
 5 files changed, 62 insertions(+), 38 deletions(-)

diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 2d28a11..a74f36f 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 bd581e6..f469715 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -101,7 +101,7 @@ static void arm_cpu_reset(CPUState *s)
 #if defined(CONFIG_USER_ONLY)
         env->pstate = PSTATE_MODE_EL0t;
         /* Userspace expects access to CTL_EL0 and the cache ops */
-        env->cp15.c1_sys |= SCTLR_UCT | SCTLR_UCI;
+        env->cp15.sctlr_el1 |= SCTLR_UCT | SCTLR_UCI;
         /* and to the FP/Neon instructions */
         env->cp15.c1_coproc = deposit64(env->cp15.c1_coproc, 20, 2, 3);
 #else
@@ -147,7 +147,8 @@ static void arm_cpu_reset(CPUState *s)
         }
     }
 
-    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 7d7782e..908ff60 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -178,7 +178,18 @@ typedef struct CPUARMState {
     struct {
         uint32_t c0_cpuid;
         uint64_t c0_cssel; /* Cache size selection.  */
-        uint64_t c1_sys; /* System control register.  */
+        union { /* System control register. */
+            struct {
+                uint64_t sctlr_ns;
+                uint64_t hsctlr;
+                uint64_t sctlr_s;
+            };
+            struct {
+                uint64_t sctlr_el1;
+                uint64_t sctlr_el2;
+                uint64_t sctlr_el3;
+            };
+        };
         uint64_t c1_coproc; /* Coprocessor access register.  */
         uint32_t c1_xscaleauxcr; /* XScale auxiliary control register.  */
         uint32_t c1_scr; /* secure config register.  */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index dfaf636..5655bd8 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1776,7 +1776,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_pl(env) == 0 && !(env->cp15.sctlr_el1 & SCTLR_UMA)) {
         return CP_ACCESS_TRAP;
     }
     return CP_ACCESS_OK;
@@ -1794,7 +1794,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_pl(env) == 0 && !(env->cp15.sctlr_el1 & SCTLR_UCI)) {
         return CP_ACCESS_TRAP;
     }
     return CP_ACCESS_OK;
@@ -1832,7 +1832,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_pl(env) == 0 && !(env->cp15.sctlr_el1 & SCTLR_DZE)) {
         return CP_ACCESS_TRAP;
     }
     return CP_ACCESS_OK;
@@ -1871,6 +1871,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.
@@ -2247,6 +2265,10 @@ static uint64_t nsacr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 }
 
 static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
+    { .name = "SCTLR_EL3", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
+      .access = PL3_RW, .raw_writefn = raw_write, .writefn = sctlr_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el3) },
     { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_MIGRATE,
       .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1,
@@ -2292,30 +2314,12 @@ static const ARMCPRegInfo security_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_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_UCT)) {
+    if (arm_current_pl(env) == 0 && !(env->cp15.sctlr_el1 & SCTLR_UCT)) {
         return CP_ACCESS_TRAP;
     }
     return CP_ACCESS_OK;
@@ -2753,10 +2757,12 @@ void register_cp_regs_for_features(ARMCPU *cpu)
 
     /* Generic registers whose values depend on the implementation */
     {
-        ARMCPRegInfo sctlr = {
-            .name = "SCTLR", .state = ARM_CP_STATE_BOTH,
+        ARMCPRegInfo sctlr_el1 = {
+            .name = "SCTLR_EL1", .state = ARM_CP_STATE_BOTH,
             .opc0 = 3, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
-            .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_sys),
+            .access = PL1_RW,
+            .bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s),
+                                   offsetof(CPUARMState, cp15.sctlr_el1) },
             .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
             .raw_writefn = raw_write,
         };
@@ -2765,9 +2771,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
              * arch/arm/mach-pxa/sleep.S expects two instructions following
              * an MMU enable to execute from cache.  Imitate this behaviour.
              */
-            sctlr.type |= ARM_CP_SUPPRESS_TB_END;
+            sctlr_el1.type |= ARM_CP_SUPPRESS_TB_END;
         }
-        define_one_arm_cp_reg(cpu, &sctlr);
+        define_one_arm_cp_reg(cpu, &sctlr_el1);
     }
 }
 
@@ -3866,7 +3872,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 {
@@ -3892,7 +3898,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;
@@ -3923,7 +3929,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:
@@ -4157,7 +4163,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;
@@ -4488,11 +4495,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;
@@ -4505,7 +4517,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 524dee9..510f68a 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -350,7 +350,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_pl(env) == 0 && !(env->cp15.sctlr_el1 & SCTLR_UMA)) {
         raise_exception(env, EXCP_UDEF);
     }
 
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v3 22/32] target-arm: make CSSELR banked
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (20 preceding siblings ...)
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 21/32] target-arm: add SCTLR_EL3 and make SCTLR banked Fabian Aggeler
@ 2014-06-10 23:55 ` Fabian Aggeler
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 23/32] target-arm: add TTBR0_EL3 and make TTBR0/1 banked Fabian Aggeler
                   ` (10 subsequent siblings)
  32 siblings, 0 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
---
 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 908ff60..6d3deb1 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -177,7 +177,15 @@ typedef struct CPUARMState {
     /* System control coprocessor (cp15) */
     struct {
         uint32_t c0_cpuid;
-        uint64_t c0_cssel; /* Cache size selection.  */
+        union { /* Cache size selection */
+            struct {
+                uint64_t csselr_ns;
+                uint64_t csselr_s;
+            };
+            struct {
+                uint64_t csselr_el1;
+            };
+        };
         union { /* System control register. */
             struct {
                 uint64_t sctlr_ns;
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 5655bd8..69d9612 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -700,7 +700,7 @@ static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
 static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     ARMCPU *cpu = arm_env_get_cpu(env);
-    return cpu->ccsidr[env->cp15.c0_cssel];
+    return cpu->ccsidr[A32_BANKED_REG_GET(env, csselr)];
 }
 
 static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -808,10 +808,11 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
     { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
       .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_MIGRATE },
-    { .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
+    { .name = "CSSELR_EL1", .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 },
+      .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
+                             offsetof(CPUARMState, cp15.csselr_el1) } },
     /* Auxiliary ID register: this actually has an IMPDEF value but for now
      * just RAZ for all cores:
      */
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v3 23/32] target-arm: add TTBR0_EL3 and make TTBR0/1 banked
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (21 preceding siblings ...)
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 22/32] target-arm: make CSSELR banked Fabian Aggeler
@ 2014-06-10 23:55 ` Fabian Aggeler
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 24/32] target-arm: add TCR_EL3 and make TTBCR banked Fabian Aggeler
                   ` (9 subsequent siblings)
  32 siblings, 0 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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>
---
 target-arm/cpu.h    | 21 +++++++++++++++++++--
 target-arm/helper.c | 45 +++++++++++++++++++++++++++++++++++----------
 2 files changed, 54 insertions(+), 12 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 6d3deb1..6890e82 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -203,8 +203,25 @@ typedef struct CPUARMState {
         uint32_t c1_scr; /* secure config register.  */
         uint32_t c1_sder; /* Secure debug enable register. */
         uint32_t c1_nsacr; /* Non-secure access control register. */
-        uint64_t ttbr0_el1; /* MMU translation table base 0. */
-        uint64_t ttbr1_el1; /* MMU translation table base 1. */
+        union { /* MMU translation table base 0. */
+            struct {
+                uint64_t ttbr0_ns;
+                uint64_t ttbr0_s;
+            };
+            struct {
+                uint64_t ttbr0_el1;
+                uint64_t ttbr0_el3;
+            };
+        };
+        union { /* MMU translation table base 1. */
+            struct {
+                uint64_t ttbr1_ns;
+                uint64_t ttbr1_s;
+            };
+            struct {
+                uint64_t ttbr1_el1;
+            };
+        };
         uint64_t c2_control; /* MMU translation table base control.  */
         uint32_t c2_mask; /* MMU translation table base selection mask.  */
         uint32_t c2_base_mask; /* MMU translation table base 0 mask. */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 69d9612..22609ed 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1498,12 +1498,14 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
       .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 },
+      .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
+                             offsetof(CPUARMState, cp15.ttbr0_el1) } },
     { .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 },
+      .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
+                             offsetof(CPUARMState, cp15.ttbr1_el1) } },
     { .name = "TCR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
       .access = PL1_RW, .writefn = vmsa_tcr_el1_write,
@@ -1744,11 +1746,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
 };
@@ -2270,6 +2274,10 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
       .opc0 = 3, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
       .access = PL3_RW, .raw_writefn = raw_write, .writefn = sctlr_write,
       .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el3) },
+    { .name = "TTBR0_EL3", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 6, .opc2 = 0,
+      .access = PL3_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el3) },
     { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_MIGRATE,
       .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1,
@@ -3966,10 +3974,14 @@ static uint32_t get_level1_table_address(CPUARMState *env, uint32_t address)
 {
     uint32_t table;
 
+    /* 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)
-        table = env->cp15.ttbr1_el1 & 0xffffc000;
+        table = A32_BANKED_CURRENT_REG_GET(env, ttbr1) & 0xffffc000;
     else
-        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 table;
@@ -4215,6 +4227,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_pl(env);
 
     if (arm_el_is_aa64(env, 1)) {
         va_size = 64;
@@ -4266,7 +4279,19 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
      * we will always flush the TLB any time the ASID is changed).
      */
     if (ttbr_select == 0) {
-        ttbr = env->cp15.ttbr0_el1;
+        if (arm_el_is_aa64(env, 3)) {
+            switch (cur_el) {
+            case 3:
+                ttbr = env->cp15.ttbr0_el3;
+                break;
+            case 1:
+            case 0:
+            default:
+                ttbr = env->cp15.ttbr0_el1;
+            }
+        } else {
+            ttbr = A32_BANKED_CURRENT_REG_GET(env, ttbr0);
+        }
         epd = extract32(env->cp15.c2_control, 7, 1);
         tsz = t0sz;
 
@@ -4278,7 +4303,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] 78+ messages in thread

* [Qemu-devel] [PATCH v3 24/32] target-arm: add TCR_EL3 and make TTBCR banked
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (22 preceding siblings ...)
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 23/32] target-arm: add TTBR0_EL3 and make TTBR0/1 banked Fabian Aggeler
@ 2014-06-10 23:55 ` Fabian Aggeler
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 25/32] target-arm: make c2_mask and c2_base_mask banked Fabian Aggeler
                   ` (8 subsequent siblings)
  32 siblings, 0 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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>
---
 target-arm/cpu.h    | 11 ++++++++++-
 target-arm/helper.c | 46 ++++++++++++++++++++++++++++++++++------------
 2 files changed, 44 insertions(+), 13 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 6890e82..f26baac 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -222,7 +222,16 @@ typedef struct CPUARMState {
                 uint64_t ttbr1_el1;
             };
         };
-        uint64_t c2_control; /* MMU translation table base control.  */
+        union { /* MMU translation table base control. */
+            struct {
+                uint64_t ttbcr_ns;
+                uint64_t ttbcr_s;
+            };
+            struct {
+                uint64_t tcr_el1;
+                uint64_t tcr_el3;
+            };
+        };
         uint32_t c2_mask; /* MMU translation table base selection mask.  */
         uint32_t c2_base_mask; /* MMU translation table base 0 mask. */
         uint32_t c2_data; /* MPU data cachable bits.  */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 22609ed..85de791 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -312,7 +312,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 & (1U << 31))));
+             && (A32_BANKED_CURRENT_REG_GET(env, ttbcr) & (1U << 31))));
 }
 
 static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
@@ -1510,11 +1510,12 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
       .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
       .access = PL1_RW, .writefn = vmsa_tcr_el1_write,
       .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
-      .fieldoffset = offsetof(CPUARMState, cp15.c2_control) },
+      .fieldoffset = offsetof(CPUARMState, cp15.tcr_el1) },
     { .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
       .access = PL1_RW, .type = ARM_CP_NO_MIGRATE, .writefn = vmsa_ttbcr_write,
       .resetfn = arm_cp_reset_ignore, .raw_writefn = vmsa_ttbcr_raw_write,
-      .fieldoffset = offsetoflow32(CPUARMState, cp15.c2_control) },
+      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.ttbcr_s),
+                             offsetoflow32(CPUARMState, cp15.ttbcr_ns) } },
     /* 64-bit FAR; this entry also gives us the AArch32 DFAR */
     { .name = "FAR_EL1", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
@@ -2278,6 +2279,11 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
       .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 6, .opc2 = 0,
       .access = PL3_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
       .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el3) },
+    { .name = "TCR_EL3", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 6, .opc2 = 2,
+      .access = PL3_RW, .writefn = vmsa_tcr_el1_write,
+      .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.tcr_el3) },
     { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_MIGRATE,
       .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1,
@@ -4228,13 +4234,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_pl(env);
+    uint64_t tcr;
 
-    if (arm_el_is_aa64(env, 1)) {
+    if (arm_el_is_aa64(env, 3)) {
+        switch (cur_el) {
+        case 3:
+            tcr = env->cp15.tcr_el3;
+            break;
+        case 1:
+        case 0:
+        default:
+            tcr = env->cp15.tcr_el1;
+        }
+
+    } else {
+        tcr = A32_BANKED_CURRENT_REG_GET(env, ttbcr);
+    }
+
+    if (arm_el_is_aa64(env, 1) && (cur_el == 0 || cur_el == 1)) {
         va_size = 64;
         if (extract64(address, 55, 1))
-            tbi = extract64(env->cp15.c2_control, 38, 1);
+            tbi = extract64(tcr, 38, 1);
         else
-            tbi = extract64(env->cp15.c2_control, 37, 1);
+            tbi = extract64(tcr, 37, 1);
         tbi *= 8;
     }
 
@@ -4243,12 +4265,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);
@@ -4292,10 +4314,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;
         }
@@ -4304,10 +4326,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;
         }
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v3 25/32] target-arm: make c2_mask and c2_base_mask banked
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (23 preceding siblings ...)
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 24/32] target-arm: add TCR_EL3 and make TTBCR banked Fabian Aggeler
@ 2014-06-10 23:55 ` Fabian Aggeler
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 26/32] target-arm: make DACR banked Fabian Aggeler
                   ` (7 subsequent siblings)
  32 siblings, 0 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index f26baac..09f658b 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -232,8 +232,14 @@ typedef struct CPUARMState {
                 uint64_t tcr_el3;
             };
         };
-        uint32_t c2_mask; /* MMU translation table base selection mask.  */
-        uint32_t c2_base_mask; /* MMU translation table base 0 mask. */
+        struct { /* MMU translation table base selection mask. */
+            uint32_t c2_mask_ns;
+            uint32_t c2_mask_s;
+        };
+        struct { /* MMU translation table base 0 mask. */
+            uint32_t c2_base_mask_ns;
+            uint32_t c2_base_mask_s;
+        };
         uint32_t c2_data; /* MPU data cachable bits.  */
         uint32_t c2_insn; /* MPU instruction cachable bits.  */
         uint32_t c3; /* MMU domain access control register
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 85de791..2c48895 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1435,8 +1435,11 @@ 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);
+
+    A32_BANKED_CURRENT_REG_SET(env, c2_mask,
+            ~(((uint32_t)0xffffffffu) >> maskshift));
+    A32_BANKED_CURRENT_REG_SET(env, c2_base_mask,
+            ~((uint32_t)0x3fffu >> maskshift));
 }
 
 static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -1455,9 +1458,9 @@ 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;
+    A32_BANKED_CURRENT_REG_SET(env, c2_base_mask, 0xffffc000u);
     raw_write(env, ri, 0);
-    env->cp15.c2_mask = 0;
+    A32_BANKED_CURRENT_REG_SET(env, c2_mask, 0);
 }
 
 static void vmsa_tcr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -3984,10 +3987,12 @@ static uint32_t get_level1_table_address(CPUARMState *env, uint32_t address)
      * 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)) {
         table = A32_BANKED_CURRENT_REG_GET(env, ttbr1) & 0xffffc000;
-    else
-        table = A32_BANKED_CURRENT_REG_GET(env, ttbr0) & env->cp15.c2_base_mask;
+    } else {
+        table = A32_BANKED_CURRENT_REG_GET(env, ttbr0) &
+                    A32_BANKED_CURRENT_REG_GET(env, c2_base_mask);
+    }
 
     table |= (address >> 18) & 0x3ffc;
     return table;
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v3 26/32] target-arm: make DACR banked
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (24 preceding siblings ...)
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 25/32] target-arm: make c2_mask and c2_base_mask banked Fabian Aggeler
@ 2014-06-10 23:55 ` Fabian Aggeler
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 27/32] target-arm: make IFSR banked Fabian Aggeler
                   ` (6 subsequent siblings)
  32 siblings, 0 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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>
---
 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 a74f36f..5188187 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -275,7 +275,7 @@ static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
         s->cpu->env.cp15.sctlr_ns = 0;
         s->cpu->env.cp15.c1_coproc = 0;
         s->cpu->env.cp15.ttbr0_el1 = 0;
-        s->cpu->env.cp15.c3 = 0;
+        s->cpu->env.cp15.dacr_ns = 0;
         s->pm_regs[PSSR >> 2] |= 0x8; /* Set STS */
         s->pm_regs[RCSR >> 2] |= 0x8; /* Set GPR */
 
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 09f658b..3457a42 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -242,8 +242,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 2c48895..d50abc4 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -413,8 +413,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.
      */
@@ -2099,10 +2101,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) } },
     /* Dummy implementation of monitor debug system control register:
      * we don't support debug.
      */
@@ -4018,7 +4021,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;
@@ -4126,7 +4129,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] 78+ messages in thread

* [Qemu-devel] [PATCH v3 27/32] target-arm: make IFSR banked
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (25 preceding siblings ...)
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 26/32] target-arm: make DACR banked Fabian Aggeler
@ 2014-06-10 23:55 ` Fabian Aggeler
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 28/32] target-arm: make DFSR banked Fabian Aggeler
                   ` (5 subsequent siblings)
  32 siblings, 0 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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>
---
 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 3457a42..54c51a4 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -257,7 +257,15 @@ typedef struct CPUARMState {
         uint32_t pmsav5_insn_ap; /* PMSAv5 MPU insn access permissions */
         uint64_t hcr_el2; /* Hypervisor configuration register */
         uint32_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 d50abc4..f51498a 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1495,8 +1495,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,
@@ -3835,11 +3836,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] 78+ messages in thread

* [Qemu-devel] [PATCH v3 28/32] target-arm: make DFSR banked
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (26 preceding siblings ...)
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 27/32] target-arm: make IFSR banked Fabian Aggeler
@ 2014-06-10 23:55 ` Fabian Aggeler
  2014-06-13 22:06   ` Greg Bellows
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 29/32] target-arm: make IFAR/DFAR banked Fabian Aggeler
                   ` (4 subsequent siblings)
  32 siblings, 1 reply; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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>
---
 target-arm/cpu.h        | 13 ++++++++++++-
 target-arm/helper-a64.c | 17 ++++++++++++++---
 target-arm/helper.c     | 15 ++++++++-------
 3 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 54c51a4..71782cf 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -266,7 +266,18 @@ typedef struct CPUARMState {
                 uint32_t ifsr32_el2;
             };
         };
-        uint64_t esr_el[4];
+        union {
+            struct {
+                uint64_t dfsr_ns;
+                uint64_t hsr;
+                uint64_t dfsr_s;
+            };
+            struct {
+                uint64_t esr_el1;
+                uint64_t esr_el2;
+                uint64_t esr_el3;
+            };
+        };
         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-a64.c b/target-arm/helper-a64.c
index d7522b6..dbbf012 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -447,6 +447,18 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
     target_ulong addr = env->cp15.vbar_el[new_el];
     unsigned int new_mode = aarch64_pstate_mode(new_el, true);
     int i;
+    uint64_t *target_esr;
+    switch (new_el) {
+    case 3:
+        target_esr = &env->cp15.esr_el3;
+        break;
+    case 2:
+        target_esr = &env->cp15.esr_el2;
+        break;
+    case 1:
+        target_esr = &env->cp15.esr_el1;
+        break;
+    }
 
     if (arm_current_pl(env) < new_el) {
         if (env->aarch64) {
@@ -477,8 +489,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
     case EXCP_SWI:
     case EXCP_HVC:
     case EXCP_SMC:
-        env->cp15.esr_el[new_el] = env->exception.syndrome;
-        break;
+        *target_esr = env->exception.syndrome;
     case EXCP_IRQ:
     case EXCP_VIRQ:
         addr += 0x80;
@@ -498,7 +509,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
     } else {
         env->banked_spsr[0] = cpsr_read(env);
         if (!env->thumb) {
-            env->cp15.esr_el[new_el] |= 1 << 25;
+            *target_esr |= 1 << 25;
         }
         env->elr_el[new_el] = env->regs[15];
 
diff --git a/target-arm/helper.c b/target-arm/helper.c
index f51498a..793985e 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1492,7 +1492,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,
@@ -1501,7 +1502,7 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
     { .name = "ESR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW,
-      .fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue = 0, },
+      .fieldoffset = offsetof(CPUARMState, cp15.esr_el1), .resetvalue = 0, },
     { .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
@@ -1565,7 +1566,7 @@ static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
 static const ARMCPRegInfo omap_cp_reginfo[] = {
     { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY,
       .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_OVERRIDE,
-      .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]),
+      .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el1),
       .resetvalue = 0, },
     { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW, .type = ARM_CP_NOP },
@@ -2187,7 +2188,7 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
     { .name = "ESR_EL2", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_MIGRATE,
       .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
-      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[2]) },
+      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el2) },
     { .name = "FAR_EL2", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
       .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[2]) },
@@ -2299,7 +2300,7 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
     { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_MIGRATE,
       .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 2, .opc2 = 0,
-      .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[3]) },
+      .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el3) },
     { .name = "FAR_EL3", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 0,
       .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[3]) },
@@ -3847,11 +3848,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] 78+ messages in thread

* [Qemu-devel] [PATCH v3 29/32] target-arm: make IFAR/DFAR banked
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (27 preceding siblings ...)
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 28/32] target-arm: make DFSR banked Fabian Aggeler
@ 2014-06-10 23:55 ` Fabian Aggeler
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 30/32] target-arm: make PAR banked Fabian Aggeler
                   ` (3 subsequent siblings)
  32 siblings, 0 replies; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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>

Conflicts:
	target-arm/helper.c
---
 target-arm/cpu.c        |  2 +-
 target-arm/cpu.h        | 21 ++++++++++++++++++++-
 target-arm/helper-a64.c | 14 ++++++++++++--
 target-arm/helper.c     | 25 ++++++++++++++-----------
 4 files changed, 47 insertions(+), 15 deletions(-)

diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index f469715..6be35ed 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -463,7 +463,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 = offsetofhigh32(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 71782cf..7f5124c 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -279,7 +279,26 @@ typedef struct CPUARMState {
             };
         };
         uint32_t c6_region[8]; /* MPU base/size registers.  */
-        uint64_t far_el[4]; /* Fault address registers.  */
+        union { /* Fault address registers. */
+            struct {
+#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
+            };
+            struct {
+                uint64_t far_el1;
+                uint64_t far_el2;
+            };
+        };
+        uint64_t far_el3;
         uint64_t par_el1;  /* Translation result. */
         uint32_t c9_insn; /* Cache lockdown registers.  */
         uint32_t c9_data;
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index dbbf012..1fc0d3c 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -481,9 +481,19 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
     switch (cs->exception_index) {
     case EXCP_PREFETCH_ABORT:
     case EXCP_DATA_ABORT:
-        env->cp15.far_el[new_el] = env->exception.vaddress;
+        switch (new_el) {
+        case 3:
+            env->cp15.far_el3 = env->exception.vaddress;
+            break;
+        case 2:
+            env->cp15.far_el2 = env->exception.vaddress;
+            break;
+        case 1:
+            env->cp15.far_el1 = env->exception.vaddress;
+            break;
+        }
         qemu_log_mask(CPU_LOG_INT, "...with FAR 0x%" PRIx64 "\n",
-                      env->cp15.far_el[new_el]);
+                      env->exception.vaddress);
     case EXCP_BKPT:
     case EXCP_UDEF:
     case EXCP_SWI:
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 793985e..47bf7a7 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -536,7 +536,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.
@@ -1523,11 +1524,15 @@ 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_el1),
+    },
     REGINFO_SENTINEL
 };
 
@@ -2191,7 +2196,7 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
       .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el2) },
     { .name = "FAR_EL2", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
-      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[2]) },
+      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el2) },
     { .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_MIGRATE,
       .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
@@ -2303,7 +2308,7 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
       .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el3) },
     { .name = "FAR_EL3", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 0,
-      .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[3]) },
+      .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el3) },
     { .name = "SPSR_EL3", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_MIGRATE,
       .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 0,
@@ -3838,8 +3843,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;
@@ -3849,8 +3853,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] 78+ messages in thread

* [Qemu-devel] [PATCH v3 30/32] target-arm: make PAR banked
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (28 preceding siblings ...)
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 29/32] target-arm: make IFAR/DFAR banked Fabian Aggeler
@ 2014-06-10 23:55 ` Fabian Aggeler
  2014-06-13 22:49   ` Greg Bellows
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 31/32] target-arm: make VBAR banked Fabian Aggeler
                   ` (2 subsequent siblings)
  32 siblings, 1 reply; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 7f5124c..048ede9 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -299,7 +299,15 @@ typedef struct CPUARMState {
             };
         };
         uint64_t far_el3;
-        uint64_t par_el1;  /* Translation result. */
+        struct { /* Translation result. */
+            union {
+                uint64_t par_ns;
+                uint64_t par_s;
+            };
+            union {
+                uint64_t par_el1;
+            };
+        };
         uint32_t c9_insn; /* Cache lockdown registers.  */
         uint32_t c9_data;
         uint32_t c9_pmcr; /* performance monitor control register */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 47bf7a7..c3195bd 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1281,7 +1281,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).
@@ -1291,14 +1291,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);
         }
     }
 }
@@ -1306,9 +1308,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,
@@ -1755,8 +1757,9 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
     { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0,
       .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
     { .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0,
-      .access = PL1_RW, .type = ARM_CP_64BIT,
-      .fieldoffset = offsetof(CPUARMState, cp15.par_el1), .resetvalue = 0 },
+      .access = PL1_RW, .type = ARM_CP_64BIT, .resetvalue = 0,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.par_s),
+                             offsetof(CPUARMState, cp15.par_ns)} },
     { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0,
       .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE,
       .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
-- 
1.8.3.2

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

* [Qemu-devel] [PATCH v3 31/32] target-arm: make VBAR banked
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (29 preceding siblings ...)
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 30/32] target-arm: make PAR banked Fabian Aggeler
@ 2014-06-10 23:55 ` Fabian Aggeler
  2014-06-13 22:43   ` Greg Bellows
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 32/32] target-arm: make c13 cp regs banked (FCSEIDR, ...) Fabian Aggeler
  2014-06-11  1:31 ` [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Edgar E. Iglesias
  32 siblings, 1 reply; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
---
 target-arm/cpu.h        | 12 +++++++++++-
 target-arm/helper-a64.c |  6 +++++-
 target-arm/helper.c     | 14 +++++++-------
 3 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 048ede9..c7d606e 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -317,7 +317,17 @@ 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 */
+        struct { /* vector base address register */
+            union {
+                uint64_t vbar_ns;
+                uint64_t vbar_s;
+            };
+            union {
+                uint64_t vbar_el1;
+                uint64_t vbar_el3;
+            };
+        };
+        uint64_t vbar_el2;
         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-a64.c b/target-arm/helper-a64.c
index 1fc0d3c..a66ec94 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -444,19 +444,23 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
     unsigned int new_el = arm_excp_target_el(cs, cs->exception_index);
-    target_ulong addr = env->cp15.vbar_el[new_el];
+    target_ulong addr = 0;
     unsigned int new_mode = aarch64_pstate_mode(new_el, true);
     int i;
     uint64_t *target_esr;
+
     switch (new_el) {
     case 3:
         target_esr = &env->cp15.esr_el3;
+        addr = env->cp15.vbar_el3;
         break;
     case 2:
         target_esr = &env->cp15.esr_el2;
+        addr = env->cp15.vbar_el2;
         break;
     case 1:
         target_esr = &env->cp15.esr_el1;
+        addr = env->cp15.vbar_el1;
         break;
     }
 
diff --git a/target-arm/helper.c b/target-arm/helper.c
index c3195bd..2d085aa 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -803,11 +803,11 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
       .access = PL1_RW, .type = ARM_CP_NO_MIGRATE,
       .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
       .resetvalue = 0, .writefn = pmintenclr_write, },
-    { .name = "VBAR", .state = ARM_CP_STATE_BOTH,
+    { .name = "VBAR_EL1", .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 },
@@ -2207,7 +2207,7 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
     { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
       .access = PL2_RW, .writefn = vbar_write,
-      .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[2]),
+      .fieldoffset = offsetof(CPUARMState, cp15.vbar_el2),
       .resetvalue = 0 },
     REGINFO_SENTINEL
 };
@@ -2319,7 +2319,7 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
     { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 0,
       .access = PL3_RW, .writefn = vbar_write,
-      .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[3]),
+      .fieldoffset = offsetof(CPUARMState, cp15.vbar_el3),
       .resetvalue = 0 },
     { .name = "SCR_EL3", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
@@ -3910,7 +3910,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] 78+ messages in thread

* [Qemu-devel] [PATCH v3 32/32] target-arm: make c13 cp regs banked (FCSEIDR, ...)
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (30 preceding siblings ...)
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 31/32] target-arm: make VBAR banked Fabian Aggeler
@ 2014-06-10 23:55 ` Fabian Aggeler
  2014-06-23 21:40   ` Greg Bellows
  2014-06-11  1:31 ` [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Edgar E. Iglesias
  32 siblings, 1 reply; 78+ messages in thread
From: Fabian Aggeler @ 2014-06-10 23:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, peter.crosthwaite, greg.bellows, serge.fdrv,
	edgar.iglesias, christoffer.dall

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

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c7d606e..13fa966 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -329,11 +329,46 @@ typedef struct CPUARMState {
         };
         uint64_t vbar_el2;
         uint64_t mvbar; /* (monitor) vector base address register */
-        uint32_t c13_fcse; /* FCSE PID.  */
-        uint64_t contextidr_el1; /* Context ID.  */
-        uint64_t tpidr_el0; /* User RW Thread register.  */
-        uint64_t tpidrro_el0; /* User RO Thread register.  */
-        uint64_t tpidr_el1; /* Privileged Thread register.  */
+        struct { /* FCSE PID. */
+            uint32_t c13_fcseidr_ns;
+            uint32_t c13_fcseidr_s;
+        };
+        union { /* Context ID. */
+            struct {
+                uint64_t contextidr_ns;
+                uint64_t contextidr_s;
+            };
+            struct {
+                uint64_t contextidr_el1;
+            };
+        };
+        union { /* User RW Thread register. */
+            struct {
+                uint64_t tpidrurw_ns;
+                uint64_t tpidrurw_s;
+            };
+            struct {
+                uint64_t tpidr_el0;
+            };
+        };
+        union { /* User RO Thread register. */
+            struct {
+                uint64_t tpidruro_ns;
+                uint64_t tpidruro_s;
+            };
+            struct {
+                uint64_t tpidrro_el0;
+            };
+        };
+        union { /* Privileged Thread register. */
+            struct {
+                uint64_t tpidrprw_ns;
+                uint64_t tpidrprw_s;
+            };
+            struct {
+                uint64_t tpidr_el1;
+            };
+        };
         uint64_t c14_cntfrq; /* Counter Frequency register */
         uint64_t c14_cntkctl; /* Timer Control register */
         ARMGenericTimer c14_timer[NUM_GTIMERS];
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 2d085aa..aebcc62 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -396,12 +396,15 @@ static const ARMCPRegInfo cp_reginfo[] = {
     { .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
       .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 },
     { .name = "FCSEIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse),
+      .access = PL1_RW,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.c13_fcseidr_s),
+                             offsetof(CPUARMState, cp15.c13_fcseidr_ns) },
       .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
     { .name = "CONTEXTIDR", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
       .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
 };
@@ -889,21 +892,25 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
       .access = PL0_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el0), .resetvalue = 0 },
     { .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2,
-      .access = PL0_RW,
-      .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidr_el0),
-      .resetfn = arm_cp_reset_ignore },
+      .access = PL0_RW, .resetfn = arm_cp_reset_ignore,
+      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrurw_s),
+                             offsetoflow32(CPUARMState, cp15.tpidrurw_ns) } },
     { .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0,
       .access = PL0_R|PL1_W,
       .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el0), .resetvalue = 0 },
     { .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3,
-      .access = PL0_R|PL1_W,
-      .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidrro_el0),
-      .resetfn = arm_cp_reset_ignore },
-    { .name = "TPIDR_EL1", .state = ARM_CP_STATE_BOTH,
+      .access = PL0_R|PL1_W, .resetfn = arm_cp_reset_ignore,
+      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s),
+                             offsetoflow32(CPUARMState, cp15.tpidruro_ns) } },
+    { .name = "TPIDR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 0, .opc2 = 4, .crn = 13, .crm = 0,
       .access = PL1_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el1), .resetvalue = 0 },
+    { .name = "TPIDRPRW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 4,
+      .access = PL1_RW, .resetfn = arm_cp_reset_ignore,
+      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s),
+                             offsetoflow32(CPUARMState, cp15.tpidruro_ns) } },
     REGINFO_SENTINEL
 };
 
@@ -4566,7 +4573,7 @@ static inline int get_phys_addr(CPUARMState *env, target_ulong address,
 
     /* Fast Context Switch Extension.  */
     if (address < 0x02000000)
-        address += env->cp15.c13_fcse;
+        address += A32_BANKED_CURRENT_REG_GET(env, c13_fcseidr);
 
     if ((sctlr & SCTLR_M) == 0) {
         /* MMU/MPU disabled.  */
-- 
1.8.3.2

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

* Re: [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs
  2014-06-10 23:54 [Qemu-devel] [PATCH v3 00/32] target-arm: add Security Extensions for CPUs Fabian Aggeler
                   ` (31 preceding siblings ...)
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 32/32] target-arm: make c13 cp regs banked (FCSEIDR, ...) Fabian Aggeler
@ 2014-06-11  1:31 ` Edgar E. Iglesias
  32 siblings, 0 replies; 78+ messages in thread
From: Edgar E. Iglesias @ 2014-06-11  1:31 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: peter.maydell, peter.crosthwaite, qemu-devel, greg.bellows,
	serge.fdrv, christoffer.dall

On Wed, Jun 11, 2014 at 01:54:42AM +0200, Fabian Aggeler wrote:
> Hi,
> 
> this is round 3 of the Security Extension patches which started with
> the TrustZone patchset by Samsung. Many patches were dropped or 
> got separated from this patchset. It shows yet another mechanism of
> register banking for EL3 running in Aarch32 mode. This version also
> conforms better with the ARM ARMv8. The patches got reordered with 
> banking related patches at the end. Most of the registers get converted
> separately now.
> 
> The whole patchset is based on master with Edgar's patches of
> yesterday (v2 target-arm: Parts of the Aarch64 EL2/3 exception model)
> applied.
> 
> Patch 9,10,11 and 12 are added for some more discussion about Edgar's 
> patches which break out masking and target_el. Parts of it could 
> probably be added to Edgar's patchset.


Good to see this series Fabian,

I'll be on the road for a couple of days but will review this more
closely early next week.

Thanks,
Edgar


> 
> v2 -> v3:
> * rebased
> * reordered
> * changed from ARM_FEATURE_SECURITY_EXTENSIONS to ARM_FEATURE_EL3
> * renamed tz_cp_reginfo to security_cp_reginfo
> * extended arm_is_secure() with EL3 handling
> * rewrote nsacr patch
> * removed MMU split for secure/nonsecure world
> * removed arm_current_sctlr
> * new banking scheme
> 
> v2: http://lists.gnu.org/archive/html/qemu-devel/2014-05/msg02522.html
> 
> Thanks,
> Fabian
> 
> Fabian Aggeler (29):
>   target-arm: add cpu feature EL3 to CPUs with Security Extensions
>   target-arm: move Aarch32 SCR into security reglist
>   target-arm: increase arrays of registers R13 & R14
>   target-arm: add arm_is_secure() function
>   target-arm: make arm_current_pl() return PL3
>   target-arm: A32: Emulate the SMC instruction
>   target-arm: extend Aarch32 async excp masking
>   target-arm: extend Aarch64 SCR.{FIQ|IRQ} handling
>   target-arm: add async excp target_el&mode function
>   target-arm: use dedicated target_el function
>   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 macros to access banked registers
>   target-arm: insert Aarch32 cpregs twice into hashtable
>   target-arm: arrayfying fieldoffset for banking
>   target-arm: add SCTLR_EL3 and make SCTLR banked
>   target-arm: make CSSELR banked
>   target-arm: add TTBR0_EL3 and make TTBR0/1 banked
>   target-arm: add TCR_EL3 and make TTBCR banked
>   target-arm: make c2_mask and c2_base_mask banked
>   target-arm: make DACR banked
>   target-arm: make IFSR banked
>   target-arm: make DFSR banked
>   target-arm: make IFAR/DFAR banked
>   target-arm: make PAR banked
>   target-arm: make VBAR banked
>   target-arm: make c13 cp regs banked (FCSEIDR,...)
> 
> 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            |   4 +-
>  target-arm/cpu.c           |  11 +-
>  target-arm/cpu.h           | 453 +++++++++++++++++++++++++----
>  target-arm/helper-a64.c    |  37 ++-
>  target-arm/helper.c        | 702 ++++++++++++++++++++++++++++++++++-----------
>  target-arm/internals.h     |   5 +
>  target-arm/machine.c       |   4 +-
>  target-arm/op_helper.c     |   2 +-
>  target-arm/translate-a64.c |   1 +
>  target-arm/translate.c     |  57 ++--
>  target-arm/translate.h     |   1 +
>  11 files changed, 1031 insertions(+), 246 deletions(-)
> 
> -- 
> 1.8.3.2
> 

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

* Re: [Qemu-devel] [PATCH v3 04/32] target-arm: add arm_is_secure() function
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 04/32] target-arm: add arm_is_secure() function Fabian Aggeler
@ 2014-06-11 12:17   ` Sergey Fedorov
  2014-06-12 16:26     ` Greg Bellows
  2014-06-17  5:51   ` Edgar E. Iglesias
  1 sibling, 1 reply; 78+ messages in thread
From: Sergey Fedorov @ 2014-06-11 12:17 UTC (permalink / raw)
  To: Fabian Aggeler, qemu-devel
  Cc: edgar.iglesias, peter.crosthwaite, greg.bellows,
	christoffer.dall, peter.maydell

On 11.06.2014 03:54, Fabian Aggeler wrote:
> 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>
> ---
>  target-arm/cpu.h | 38 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 903aa01..cb0da6b 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -710,6 +710,44 @@ static inline int arm_feature(CPUARMState *env, int feature)
>      return (env->features & (1ULL << feature)) != 0;
>  }
>  
> +
> +/* Return true if exception level below EL3 is in secure state */
> +static inline bool arm_is_secure_below_el3(CPUARMState *env)
> +{
> +#if !defined(CONFIG_USER_ONLY)
> +    if (arm_feature(env, ARM_FEATURE_EL3)) {
> +        return !(env->cp15.scr_el3 & SCR_NS);
> +    } else if (arm_feature(env, ARM_FEATURE_EL2)) {
> +        return false;
> +    } else {
> +        /* IMPDEF: QEMU defaults to non-secure */
> +        return false;
> +    }
> +#else
> +    return false;
> +#endif
> +}
> +
> +/* Return true if the processor is in secure state */
> +static inline bool arm_is_secure(CPUARMState *env)
> +{
> +#if !defined(CONFIG_USER_ONLY)
> +    if (arm_feature(env, ARM_FEATURE_EL3)) {
> +        if (env->aarch64 && extract32(env->pstate, 2, 2) == 3) {
> +            /* CPU currently in Aarch64 state and EL3 */
> +            return true;
> +        } else if (!env->aarch64 &&
> +                (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
> +            /* CPU currently in Aarch32 state and monitor mode */
> +            return true;
> +        }

Hi Fabian,

Why don't use arm_current_pl() from patch 6 to determine EL here?

Best regards,
Sergey

> +    }
> +    return arm_is_secure_below_el3(env);
> +#else
> +    return false;
> +#endif
> +}
> +
>  /* Return true if the specified exception level is running in AArch64 state. */
>  static inline bool arm_el_is_aa64(CPUARMState *env, int el)
>  {

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

* Re: [Qemu-devel] [PATCH v3 04/32] target-arm: add arm_is_secure() function
  2014-06-11 12:17   ` Sergey Fedorov
@ 2014-06-12 16:26     ` Greg Bellows
  2014-06-12 17:26       ` Sergey Fedorov
  0 siblings, 1 reply; 78+ messages in thread
From: Greg Bellows @ 2014-06-12 16:26 UTC (permalink / raw)
  To: Sergey Fedorov
  Cc: Peter Maydell, Peter Crosthwaite, Fabian Aggeler,
	QEMU Developers, Edgar E. Iglesias, Christoffer Dall

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

Hi Sergey,

I think I am missing your point.  In patch 6 arm_current_pl calls
arm_is_secure.  Can you elaborate?

Greg


On 11 June 2014 07:17, Sergey Fedorov <serge.fdrv@gmail.com> wrote:

> On 11.06.2014 03:54, Fabian Aggeler wrote:
> > 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>
> > ---
> >  target-arm/cpu.h | 38 ++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 38 insertions(+)
> >
> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > index 903aa01..cb0da6b 100644
> > --- a/target-arm/cpu.h
> > +++ b/target-arm/cpu.h
> > @@ -710,6 +710,44 @@ static inline int arm_feature(CPUARMState *env, int
> feature)
> >      return (env->features & (1ULL << feature)) != 0;
> >  }
> >
> > +
> > +/* Return true if exception level below EL3 is in secure state */
> > +static inline bool arm_is_secure_below_el3(CPUARMState *env)
> > +{
> > +#if !defined(CONFIG_USER_ONLY)
> > +    if (arm_feature(env, ARM_FEATURE_EL3)) {
> > +        return !(env->cp15.scr_el3 & SCR_NS);
> > +    } else if (arm_feature(env, ARM_FEATURE_EL2)) {
> > +        return false;
> > +    } else {
> > +        /* IMPDEF: QEMU defaults to non-secure */
> > +        return false;
> > +    }
> > +#else
> > +    return false;
> > +#endif
> > +}
> > +
> > +/* Return true if the processor is in secure state */
> > +static inline bool arm_is_secure(CPUARMState *env)
> > +{
> > +#if !defined(CONFIG_USER_ONLY)
> > +    if (arm_feature(env, ARM_FEATURE_EL3)) {
> > +        if (env->aarch64 && extract32(env->pstate, 2, 2) == 3) {
> > +            /* CPU currently in Aarch64 state and EL3 */
> > +            return true;
> > +        } else if (!env->aarch64 &&
> > +                (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
> > +            /* CPU currently in Aarch32 state and monitor mode */
> > +            return true;
> > +        }
>
> Hi Fabian,
>
> Why don't use arm_current_pl() from patch 6 to determine EL here?
>
> Best regards,
> Sergey
>
> > +    }
> > +    return arm_is_secure_below_el3(env);
> > +#else
> > +    return false;
> > +#endif
> > +}
> > +
> >  /* Return true if the specified exception level is running in AArch64
> state. */
> >  static inline bool arm_el_is_aa64(CPUARMState *env, int el)
> >  {
>
>

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

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

* Re: [Qemu-devel] [PATCH v3 04/32] target-arm: add arm_is_secure() function
  2014-06-12 16:26     ` Greg Bellows
@ 2014-06-12 17:26       ` Sergey Fedorov
  2014-06-12 18:35         ` Greg Bellows
  0 siblings, 1 reply; 78+ messages in thread
From: Sergey Fedorov @ 2014-06-12 17:26 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Peter Maydell, Peter Crosthwaite, Fabian Aggeler,
	QEMU Developers, Edgar E. Iglesias, Christoffer Dall

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

Hi Greg,

I'm sorry, I wasn't thoughtful enough and missed that.
I would just suggest to combine that functions since they have a common
part, i.e.:

    if (arm_feature(env, ARM_FEATURE_EL3)) {
        ...

What do you think?

// Sergey

12.06.2014 20:26, Greg Bellows пишет:
> Hi Sergey,
>
> I think I am missing your point.  In patch 6 arm_current_pl calls
> arm_is_secure.  Can you elaborate?
>
> Greg
>
>
> On 11 June 2014 07:17, Sergey Fedorov <serge.fdrv@gmail.com
> <mailto:serge.fdrv@gmail.com>> wrote:
>
>     On 11.06.2014 03:54, Fabian Aggeler wrote:
>     > 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
>     <mailto:s.fedorov@samsung.com>>
>     > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch
>     <mailto:aggelerf@ethz.ch>>
>     > ---
>     >  target-arm/cpu.h | 38 ++++++++++++++++++++++++++++++++++++++
>     >  1 file changed, 38 insertions(+)
>     >
>     > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
>     > index 903aa01..cb0da6b 100644
>     > --- a/target-arm/cpu.h
>     > +++ b/target-arm/cpu.h
>     > @@ -710,6 +710,44 @@ static inline int arm_feature(CPUARMState
>     *env, int feature)
>     >      return (env->features & (1ULL << feature)) != 0;
>     >  }
>     >
>     > +
>     > +/* Return true if exception level below EL3 is in secure state */
>     > +static inline bool arm_is_secure_below_el3(CPUARMState *env)
>     > +{
>     > +#if !defined(CONFIG_USER_ONLY)
>     > +    if (arm_feature(env, ARM_FEATURE_EL3)) {
>     > +        return !(env->cp15.scr_el3 & SCR_NS);
>     > +    } else if (arm_feature(env, ARM_FEATURE_EL2)) {
>     > +        return false;
>     > +    } else {
>     > +        /* IMPDEF: QEMU defaults to non-secure */
>     > +        return false;
>     > +    }
>     > +#else
>     > +    return false;
>     > +#endif
>     > +}
>     > +
>     > +/* Return true if the processor is in secure state */
>     > +static inline bool arm_is_secure(CPUARMState *env)
>     > +{
>     > +#if !defined(CONFIG_USER_ONLY)
>     > +    if (arm_feature(env, ARM_FEATURE_EL3)) {
>     > +        if (env->aarch64 && extract32(env->pstate, 2, 2) == 3) {
>     > +            /* CPU currently in Aarch64 state and EL3 */
>     > +            return true;
>     > +        } else if (!env->aarch64 &&
>     > +                (env->uncached_cpsr & CPSR_M) ==
>     ARM_CPU_MODE_MON) {
>     > +            /* CPU currently in Aarch32 state and monitor mode */
>     > +            return true;
>     > +        }
>
>     Hi Fabian,
>
>     Why don't use arm_current_pl() from patch 6 to determine EL here?
>
>     Best regards,
>     Sergey
>
>     > +    }
>     > +    return arm_is_secure_below_el3(env);
>     > +#else
>     > +    return false;
>     > +#endif
>     > +}
>     > +
>     >  /* Return true if the specified exception level is running in
>     AArch64 state. */
>     >  static inline bool arm_el_is_aa64(CPUARMState *env, int el)
>     >  {
>
>


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

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

* Re: [Qemu-devel] [PATCH v3 04/32] target-arm: add arm_is_secure() function
  2014-06-12 17:26       ` Sergey Fedorov
@ 2014-06-12 18:35         ` Greg Bellows
  2014-06-12 19:09           ` Sergey Fedorov
  0 siblings, 1 reply; 78+ messages in thread
From: Greg Bellows @ 2014-06-12 18:35 UTC (permalink / raw)
  To: Sergey Fedorov
  Cc: Peter Maydell, Peter Crosthwaite, Fabian Aggeler,
	QEMU Developers, Edgar E. Iglesias, Christoffer Dall

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

To make sure I understand, you are proposing that we simply use the return
from arm_current_pl of 3 to indicate isSecure?

Fabian's code closely follows the v8 spec pseudo code.  I believe the case
that would be omitted if we let a return of 3 mean "secure" is the case
where we are in EL0/1 with SCR.NS=0.

So, the to functions are not quite identical.  In the case of
arm_current_pl, it returns the PL regardless of the SCR.NS bit.  In the
case of arm_is_secure, the secure state takes into consideration both the
PL and the SCR.NS setting.


On 12 June 2014 12:26, Sergey Fedorov <serge.fdrv@gmail.com> wrote:

>  Hi Greg,
>
> I'm sorry, I wasn't thoughtful enough and missed that.
> I would just suggest to combine that functions since they have a common
> part, i.e.:
>
>     if (arm_feature(env, ARM_FEATURE_EL3)) {
>         ...
>
> What do you think?
>
> // Sergey
>
> 12.06.2014 20:26, Greg Bellows пишет:
>
>  Hi Sergey,
>
>  I think I am missing your point.  In patch 6 arm_current_pl calls
> arm_is_secure.  Can you elaborate?
>
>  Greg
>
>
>  On 11 June 2014 07:17, Sergey Fedorov <serge.fdrv@gmail.com> wrote:
>
>>  On 11.06.2014 03:54, Fabian Aggeler wrote:
>> > 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>
>> > ---
>> >  target-arm/cpu.h | 38 ++++++++++++++++++++++++++++++++++++++
>> >  1 file changed, 38 insertions(+)
>> >
>> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
>> > index 903aa01..cb0da6b 100644
>> > --- a/target-arm/cpu.h
>> > +++ b/target-arm/cpu.h
>> > @@ -710,6 +710,44 @@ static inline int arm_feature(CPUARMState *env,
>> int feature)
>> >      return (env->features & (1ULL << feature)) != 0;
>> >  }
>> >
>> > +
>> > +/* Return true if exception level below EL3 is in secure state */
>> > +static inline bool arm_is_secure_below_el3(CPUARMState *env)
>> > +{
>> > +#if !defined(CONFIG_USER_ONLY)
>> > +    if (arm_feature(env, ARM_FEATURE_EL3)) {
>> > +        return !(env->cp15.scr_el3 & SCR_NS);
>> > +    } else if (arm_feature(env, ARM_FEATURE_EL2)) {
>> > +        return false;
>> > +    } else {
>> > +        /* IMPDEF: QEMU defaults to non-secure */
>> > +        return false;
>> > +    }
>> > +#else
>> > +    return false;
>> > +#endif
>> > +}
>> > +
>> > +/* Return true if the processor is in secure state */
>> > +static inline bool arm_is_secure(CPUARMState *env)
>> > +{
>> > +#if !defined(CONFIG_USER_ONLY)
>> > +    if (arm_feature(env, ARM_FEATURE_EL3)) {
>> > +        if (env->aarch64 && extract32(env->pstate, 2, 2) == 3) {
>> > +            /* CPU currently in Aarch64 state and EL3 */
>> > +            return true;
>> > +        } else if (!env->aarch64 &&
>> > +                (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
>> > +            /* CPU currently in Aarch32 state and monitor mode */
>> > +            return true;
>> > +        }
>>
>>  Hi Fabian,
>>
>> Why don't use arm_current_pl() from patch 6 to determine EL here?
>>
>> Best regards,
>> Sergey
>>
>> > +    }
>> > +    return arm_is_secure_below_el3(env);
>> > +#else
>> > +    return false;
>> > +#endif
>> > +}
>> > +
>> >  /* Return true if the specified exception level is running in AArch64
>> state. */
>> >  static inline bool arm_el_is_aa64(CPUARMState *env, int el)
>> >  {
>>
>>
>
>

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

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

* Re: [Qemu-devel] [PATCH v3 04/32] target-arm: add arm_is_secure() function
  2014-06-12 18:35         ` Greg Bellows
@ 2014-06-12 19:09           ` Sergey Fedorov
  0 siblings, 0 replies; 78+ messages in thread
From: Sergey Fedorov @ 2014-06-12 19:09 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Peter Maydell, Peter Crosthwaite, Fabian Aggeler,
	QEMU Developers, Edgar E. Iglesias, Christoffer Dall

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

I suggested to combine arm_is_secure() and arm_is_secure_below_el3().
Since the code follows the v8 pseudo code my suggestion is really not a
good idea. So I apologize twice for wasting your time :)

// Sergey

12.06.2014 22:35, Greg Bellows wrote:
> To make sure I understand, you are proposing that we simply use the
> return from arm_current_pl of 3 to indicate isSecure?
>
> Fabian's code closely follows the v8 spec pseudo code.  I believe the
> case that would be omitted if we let a return of 3 mean "secure" is
> the case where we are in EL0/1 with SCR.NS=0.
>
> So, the to functions are not quite identical.  In the case of
> arm_current_pl, it returns the PL regardless of the SCR.NS bit.  In
> the case of arm_is_secure, the secure state takes into consideration
> both the PL and the SCR.NS setting.
>
>
> On 12 June 2014 12:26, Sergey Fedorov <serge.fdrv@gmail.com
> <mailto:serge.fdrv@gmail.com>> wrote:
>
>     Hi Greg,
>
>     I'm sorry, I wasn't thoughtful enough and missed that.
>     I would just suggest to combine that functions since they have a
>     common part, i.e.:
>
>         if (arm_feature(env, ARM_FEATURE_EL3)) {
>             ...
>
>     What do you think?
>
>     // Sergey
>
>     12.06.2014 20:26, Greg Bellows пишет:
>
>>     Hi Sergey,
>>
>>     I think I am missing your point.  In patch 6 arm_current_pl calls
>>     arm_is_secure.  Can you elaborate?
>>
>>     Greg
>>
>>
>>     On 11 June 2014 07:17, Sergey Fedorov <serge.fdrv@gmail.com
>>     <mailto:serge.fdrv@gmail.com>> wrote:
>>
>>         On 11.06.2014 03:54, Fabian Aggeler wrote:
>>         > 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
>>         <mailto:s.fedorov@samsung.com>>
>>         > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch
>>         <mailto:aggelerf@ethz.ch>>
>>         > ---
>>         >  target-arm/cpu.h | 38 ++++++++++++++++++++++++++++++++++++++
>>         >  1 file changed, 38 insertions(+)
>>         >
>>         > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
>>         > index 903aa01..cb0da6b 100644
>>         > --- a/target-arm/cpu.h
>>         > +++ b/target-arm/cpu.h
>>         > @@ -710,6 +710,44 @@ static inline int
>>         arm_feature(CPUARMState *env, int feature)
>>         >      return (env->features & (1ULL << feature)) != 0;
>>         >  }
>>         >
>>         > +
>>         > +/* Return true if exception level below EL3 is in secure
>>         state */
>>         > +static inline bool arm_is_secure_below_el3(CPUARMState *env)
>>         > +{
>>         > +#if !defined(CONFIG_USER_ONLY)
>>         > +    if (arm_feature(env, ARM_FEATURE_EL3)) {
>>         > +        return !(env->cp15.scr_el3 & SCR_NS);
>>         > +    } else if (arm_feature(env, ARM_FEATURE_EL2)) {
>>         > +        return false;
>>         > +    } else {
>>         > +        /* IMPDEF: QEMU defaults to non-secure */
>>         > +        return false;
>>         > +    }
>>         > +#else
>>         > +    return false;
>>         > +#endif
>>         > +}
>>         > +
>>         > +/* Return true if the processor is in secure state */
>>         > +static inline bool arm_is_secure(CPUARMState *env)
>>         > +{
>>         > +#if !defined(CONFIG_USER_ONLY)
>>         > +    if (arm_feature(env, ARM_FEATURE_EL3)) {
>>         > +        if (env->aarch64 && extract32(env->pstate, 2, 2)
>>         == 3) {
>>         > +            /* CPU currently in Aarch64 state and EL3 */
>>         > +            return true;
>>         > +        } else if (!env->aarch64 &&
>>         > +                (env->uncached_cpsr & CPSR_M) ==
>>         ARM_CPU_MODE_MON) {
>>         > +            /* CPU currently in Aarch32 state and monitor
>>         mode */
>>         > +            return true;
>>         > +        }
>>
>>         Hi Fabian,
>>
>>         Why don't use arm_current_pl() from patch 6 to determine EL here?
>>
>>         Best regards,
>>         Sergey
>>
>>         > +    }
>>         > +    return arm_is_secure_below_el3(env);
>>         > +#else
>>         > +    return false;
>>         > +#endif
>>         > +}
>>         > +
>>         >  /* Return true if the specified exception level is running
>>         in AArch64 state. */
>>         >  static inline bool arm_el_is_aa64(CPUARMState *env, int el)
>>         >  {
>>
>>
>
>


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

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

* Re: [Qemu-devel] [PATCH v3 19/32] target-arm: insert Aarch32 cpregs twice into hashtable
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 19/32] target-arm: insert Aarch32 cpregs twice into hashtable Fabian Aggeler
@ 2014-06-12 19:49   ` Sergey Fedorov
  2014-06-25  5:20   ` Edgar E. Iglesias
  1 sibling, 0 replies; 78+ messages in thread
From: Sergey Fedorov @ 2014-06-12 19:49 UTC (permalink / raw)
  To: Fabian Aggeler, qemu-devel
  Cc: edgar.iglesias, peter.crosthwaite, greg.bellows,
	christoffer.dall, peter.maydell

Hi Fabian,

11.06.2014 03:55, Fabian Aggeler wrote:
> 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>
> ---
>  target-arm/cpu.h       | 14 +++++++++++---
>  target-arm/helper.c    | 20 ++++++++++++++++----
>  target-arm/translate.c | 19 +++++++++++++------
>  3 files changed, 40 insertions(+), 13 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 0b8042c..d4eab39 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -831,6 +831,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;
> @@ -848,9 +849,16 @@ void armv7m_nvic_complete_irq(void *opaque, int irq);
>  #define CP_REG_AA64_SHIFT 28
>  #define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
>  
> -#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2)   \
> -    (((cp) << 16) | ((is64) << 15) | ((crn) << 11) |    \
> -     ((crm) << 7) | ((opc1) << 3) | (opc2))
> +/* To enable banking of coprocessor registers depending on ns-bit we
> + * add a bit to distinguish between secure and non-secure cpregs in the
> + * hashtable.
> + */
> +#define CP_REG_NS_SHIFT 27
> +#define CP_REG_NS_MASK(nsbit) (nsbit << CP_REG_NS_SHIFT)
> +
> +#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2, ns)   \
> +    (CP_REG_NS_MASK(ns) | ((cp) << 16) | ((is64) << 15) |   \
> +     ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
>  
>  #define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
>      (CP_REG_AA64_MASK |                                 \
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index f9b2374..610245d 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -2883,7 +2883,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.
> @@ -2917,7 +2917,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;
> @@ -3066,8 +3066,20 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
>                      if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
>                          continue;
>                      }
> -                    add_cpreg_to_hashtable(cpu, r, opaque, state,
> -                                           crm, opc1, opc2);
> +                    if (state == ARM_CP_STATE_AA32) {
> +                        /* Under Aarch32 CP registers can be common
> +                         * (same for secure and non-secure world) or banked.
> +                         */
> +                        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);

You may need to make one of the reginfos of type ARM_CP_NO_MIGRATE if
you add non-banked register here twice.

> +                    } else {
> +                        /* Aarch64 registers get mapped to non-secure instance
> +                         * of Aarch32 */
> +                        add_cpreg_to_hashtable(cpu, r, opaque, state,
> +                                crm, opc1, opc2, SCR_NS);
> +                    }
>                  }
>              }
>          }
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index f657389..30d9592 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -6968,7 +6968,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
>  
>  static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
>  {
> -    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
> +    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2, ns;
>      const ARMCPRegInfo *ri;
>  
>      cpnum = (insn >> 8) & 0xf;
> @@ -7012,8 +7012,11 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
>      isread = (insn >> 20) & 1;
>      rt = (insn >> 12) & 0xf;
>  
> +    /* Monitor mode is always treated as secure but cp register reads/writes
> +     * can access secure and non-secure instances using SCR.NS bit*/
> +    ns = IS_NS(s) ? 1 : !USE_SECURE_REG(env);
>      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, ns));
>      if (ri) {
>          /* Check access permissions */
>          if (!cp_access_ok(s->current_pl, ri, isread)) {
> @@ -7200,12 +7203,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,
> +                      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,
> +                      ns ? "non-secure" : "secure");
>      }
>  
>      return 1;

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

* Re: [Qemu-devel] [PATCH v3 02/32] target-arm: move Aarch32 SCR into security reglist
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 02/32] target-arm: move Aarch32 SCR into security reglist Fabian Aggeler
@ 2014-06-12 21:55   ` Greg Bellows
  2014-06-17  7:22     ` Aggeler  Fabian
  0 siblings, 1 reply; 78+ messages in thread
From: Greg Bellows @ 2014-06-12 21:55 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall

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

Conflict with Edgar's changes around the name of the security register
group v8_el3_cp_reginfo vs. security_cp_reginfo.

Given that there is a difference between the v7 regs and their v8
equivalents such as encoding, I propose we create 2 separate groups, but
map them to the same storage where applicable.  This somewhat follows on
the SCR mapping discussion.


On 10 June 2014 18:54, Fabian Aggeler <aggelerf@ethz.ch> wrote:

> 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>
> ---
>  target-arm/helper.c | 11 ++++++++---
>  1 file changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index e157cc2..d8d6637 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -792,9 +792,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 = offsetof(CPUARMState, cp15.c1_scr),
> -      .resetvalue = 0, },
>      { .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 },
> @@ -2216,6 +2213,13 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
>      REGINFO_SENTINEL
>  };
>
> +static const ARMCPRegInfo security_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, },
> +    REGINFO_SENTINEL
> +};
> +
>  static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
>                          uint64_t value)
>  {
> @@ -2479,6 +2483,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>      }
>      if (arm_feature(env, ARM_FEATURE_EL3)) {
>          define_arm_cp_regs(cpu, v8_el3_cp_reginfo);
> +        define_arm_cp_regs(cpu, security_cp_reginfo);
>      }
>      if (arm_feature(env, ARM_FEATURE_MPU)) {
>          /* These are the MPU registers prior to PMSAv6. Any new
> --
> 1.8.3.2
>
>

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

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

* Re: [Qemu-devel] [PATCH v3 05/32] target-arm: reject switching to monitor mode
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 05/32] target-arm: reject switching to monitor mode Fabian Aggeler
@ 2014-06-12 21:55   ` Greg Bellows
  2014-06-24 12:19     ` Aggeler  Fabian
  2014-06-17  5:43   ` Edgar E. Iglesias
  1 sibling, 1 reply; 78+ messages in thread
From: Greg Bellows @ 2014-06-12 21:55 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall

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

Missing case where it is UNPREDICTABLE to enter FIQ mode from non-secure
state if NSACR.RFR is 1.


On 10 June 2014 18:54, Fabian Aggeler <aggelerf@ethz.ch> wrote:

> From: Sergey Fedorov <s.fedorov@samsung.com>
>
> ...from non-secure state.
>
> Signed-off-by: Sergey Fedorov <s.fedorov@samsung.com>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> ---
>  target-arm/helper.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index d8d6637..ace8d8b 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -3049,6 +3049,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
>
>

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

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

* Re: [Qemu-devel] [PATCH v3 10/32] target-arm: extend Aarch64 SCR.{FIQ|IRQ} handling
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 10/32] target-arm: extend Aarch64 SCR.{FIQ|IRQ} handling Fabian Aggeler
@ 2014-06-12 21:55   ` Greg Bellows
  0 siblings, 0 replies; 78+ messages in thread
From: Greg Bellows @ 2014-06-12 21:55 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall

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

This should be squashed with 9/32.


On 10 June 2014 18:54, Fabian Aggeler <aggelerf@ethz.ch> wrote:

> 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>
> ---
>  target-arm/cpu.h | 98
> +++++++++++++++++++++++++++++++++++++++++---------------
>  1 file changed, 72 insertions(+), 26 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index f8531aa..b786a5a 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -1195,20 +1195,43 @@ static inline bool arm_excp_unmasked(CPUState *cs,
> unsigned int excp_idx)
>       * (table G1-18/G1-19) */
>      switch (excp_idx) {
>      case EXCP_FIQ:
> +        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) &&
> -                    (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
> -                 */
> -                if (cur_el < 2) {
> -                    return true;
> -                } else if (arm_feature(env, ARM_FEATURE_EL3) &&
> -                        (env->cp15.scr_el3 & SCR_FIQ)) {
> -                    return true;
> +            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
> @@ -1236,20 +1259,43 @@ static inline bool arm_excp_unmasked(CPUState *cs,
> unsigned int excp_idx)
>          }
>          return !(env->daif & PSTATE_F);
>      case EXCP_IRQ:
> +        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) &&
> -                    (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
> -                 */
> -                if (cur_el < 2) {
> -                    return true;
> -                } else if (arm_feature(env, ARM_FEATURE_EL3) &&
> -                        (env->cp15.scr_el3 & SCR_IRQ)) {
> -                    return true;
> +            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;
>                  }
>              }
>          }
> --
> 1.8.3.2
>
>

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

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

* Re: [Qemu-devel] [PATCH v3 11/32] target-arm: add async excp target_el&mode function
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 11/32] target-arm: add async excp target_el&mode function Fabian Aggeler
@ 2014-06-12 21:56   ` Greg Bellows
  2014-06-17  7:29     ` Aggeler  Fabian
  0 siblings, 1 reply; 78+ messages in thread
From: Greg Bellows @ 2014-06-12 21:56 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall

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

On 10 June 2014 18:54, Fabian Aggeler <aggelerf@ethz.ch> wrote:

> 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>
> ---
>  target-arm/cpu.h    |   3 ++
>  target-arm/helper.c | 137
> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 140 insertions(+)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index b786a5a..52e679f 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -768,6 +768,9 @@ static inline bool arm_el_is_aa64(CPUARMState *env,
> int el)
>
>  void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf);
>  unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx);
> +inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t
> *target_mode,
> +                                        uint32_t excp_idx, uint32_t
> cur_el,
> +                                        bool secure);
>
>  /* Interface between CPU and Interrupt controller.  */
>  void armv7m_nvic_set_pending(void *opaque, int irq);
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 5822353..8333b52 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -3224,6 +3224,21 @@ uint32_t HELPER(get_r13_banked)(CPUARMState *env,
> uint32_t mode)
>      return 0;
>  }
>
> +inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t
> *target_mode,
> +                                        uint32_t excp_idx, uint32_t
> cur_el,
> +                                        bool secure)
> +{
> +    switch (excp_idx) {
> +    case EXCP_IRQ:
> +        *target_mode = ARM_CPU_MODE_IRQ;
> +        break;
> +    case EXCP_FIQ:
> +        *target_mode = ARM_CPU_MODE_FIQ;
> +        break;
> +    }
> +    return 1;
> +}
> +
>  unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
>  {
>      return 1;
> @@ -3285,6 +3300,128 @@ void switch_mode(CPUARMState *env, int mode)
>  }
>
>  /*
> + * Determine the target EL for physical exceptions
> + */
> +inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t
> *target_mode,
> +                                        uint32_t excp_idx, uint32_t
> cur_el,
> +                                        bool secure)
> +{
> +    CPUARMState *env = cs->env_ptr;
> +    uint32_t target_el = 1;
> +    uint32_t excp_mode = 0;
> +
> +    bool scr_routing = 0; /* IRQ, FIQ, EA */
> +    bool hcr_routing = 0; /* IMO, FMO, AMO */
> +
> +    switch (excp_idx) {
> +    case EXCP_IRQ:
> +        scr_routing = (env->cp15.scr_el3 & SCR_IRQ);
> +        hcr_routing = (env->cp15.hcr_el2 & HCR_IMO);
> +        excp_mode = ARM_CPU_MODE_IRQ;
> +        break;
> +    case EXCP_FIQ:
> +        scr_routing = (env->cp15.scr_el3 & SCR_FIQ);
> +        hcr_routing = (env->cp15.hcr_el2 & HCR_FMO);
> +        excp_mode = ARM_CPU_MODE_FIQ;
> +    }
> +
> +    /* If HCR.TGE is set all exceptions that would be routed to EL1 are
> +     * routed to EL2 (in non-secure world).
> +     */
> +    if (arm_feature(env, ARM_FEATURE_EL2) && (env->cp15.hcr_el2 &
> HCR_TGE)) {
> +        hcr_routing = 1;
> +    }
> +
> +    /* Determine target EL according to ARM ARMv8 tables G1-15 and G1-16
> */
> +    if (arm_el_is_aa64(env, 3)) {
> +        /* EL3 in Aarch64 */
> +        if (scr_routing) {
> +            /* IRQ|FIQ|EA == 1 */
> +            target_el = 3;
> +        } else {
> +            if (hcr_routing) {
> +                /* IRQ|FIQ|EA == 0
> +                 * IMO|FMO|AMO == 1 */
> +                if (secure) {
> +                    /* Secure */
> +                    target_el = 1;
> +                    if (!arm_el_is_aa64(env, 1)) {
> +                        /* EL1 using Aarch32 */
> +                        *target_mode = ARM_CPU_MODE_ABT;
> +                    }
> +                } else if (cur_el < 2) {
> +                    /* Non-Secure goes to EL2 */
> +                    target_el = 2;
> +                    if (!arm_el_is_aa64(env, 2)) {
> +                        /* EL2 using Aarch32 */
> +                        *target_mode = ARM_CPU_MODE_HYP;
> +                    }
> +                }
> +            } else if (env->cp15.scr_el3 & SCR_RW) {
> +                /* IRQ|FIQ|EA == 0
> +                 * IMO|FMO|AMO == 0
> +                 * RW == 1 (Next lower level is Aarch64)
> +                 */
> +                if (cur_el < 2) {
> +                    target_el = 1;
> +                } else {
> +                    /* Interrupt not taken but remains pending */
> +                }
> +            } else {
> +                /* IRQ|FIQ|EA == 0
> +                 * IMO|FMO|AMO == 0
> +                 * RW == 0 (Next lower level is Aarch64)
> +                 */
> +                if (cur_el < 2) {
> +                    target_el = 1;
> +                    *target_mode = ARM_CPU_MODE_ABT;
>

According to the aforementioned tables, the target mode should be
excp_mode, not always abort.


> +                } else if (cur_el == 2) {
> +                    target_el = 2;
> +                    *target_mode = ARM_CPU_MODE_HYP;
> +                } else {
> +                    /* Interrupt not taken but remains pending */
> +                }
> +            }
> +        }
> +    } else {
> +        /* EL3 in Aarch32 */
> +        if (scr_routing) {
> +            /* IRQ|FIQ|EA == 1 */
> +            target_el = 3;
> +            *target_mode = ARM_CPU_MODE_MON;
> +        } else {
> +            if (hcr_routing) {
> +                /* IRQ|FIQ|EA == 0
> +                 * IMO|FMO|AMO == 1
> +                 */
> +                if (secure) {
> +                    target_el = 3;
> +                    *target_mode = excp_mode;
> +                } else {
> +                    target_el = 2;
> +                    *target_mode = ARM_CPU_MODE_HYP;
> +                }
> +            } else {
> +                /* IRQ|FIQ|EA == 0
> +                 * IMO|FMO|AMO == 0
> +                 */
> +                if (cur_el < 2) {
> +                    target_el = 1;
> +                    *target_mode = excp_mode;
> +                } else if (cur_el == 2) {
> +                    target_el = 2;
> +                    *target_mode = ARM_CPU_MODE_HYP;
> +                } else if (secure) {
> +                    target_el = 3;
> +                    *target_mode = excp_mode;
> +                }
> +            }
> +        }
> +    }
> +    return target_el;
> +}
> +
> +/*
>   * Determine the target EL for a given exception type.
>   */
>  unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
> --
> 1.8.3.2
>
>

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

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

* Re: [Qemu-devel] [PATCH v3 14/32] target-arm: Respect SCR.FW, SCR.AW and SCTLR.NMFI
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 14/32] target-arm: Respect SCR.FW, SCR.AW and SCTLR.NMFI Fabian Aggeler
@ 2014-06-12 22:43   ` Greg Bellows
  2014-06-17  7:36     ` Aggeler  Fabian
  0 siblings, 1 reply; 78+ messages in thread
From: Greg Bellows @ 2014-06-12 22:43 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall

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

On 10 June 2014 18:54, Fabian Aggeler <aggelerf@ethz.ch> wrote:

> bits when modifying CPSR.
>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> ---
>  target-arm/helper.c | 42 +++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 39 insertions(+), 3 deletions(-)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 2fbecfa..f6ff4aa 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -3091,9 +3091,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.
> @@ -3105,6 +3102,45 @@ void cpsr_write(CPUARMState *env, uint32_t val,
> uint32_t mask)
>              switch_mode(env, val & CPSR_M);
>          }
>      }
> +
> +    /* In an implementation that does not include Virtualization
> Extensions
> +     * the SCR.FW and SCR.AW bit control whether non-secure software is
> allowed
> +     * to change the CPSR_F and CPSR_A bits respectively.
> +     */
> +    if ((mask & CPSR_A)
> +            && (val & CPSR_A) != (env->uncached_cpsr & CPSR_A)
> +            && arm_feature(env, ARM_FEATURE_EL3)
> +            && !(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 set\n");
> +        mask &= ~CPSR_A;
>

Ignoring the write appears to only be valid in the case of ARMv7 (actually
says "early implementations of v7") but not v8.  This is noted in the ARMv8
spec in the section "Effects of EL3 and EL2 on the CPSR.{A, F} bits".
 According to this passage, the AW/FW bits only block the corresponding
bits being updated when the SPSR is copied to the CPSR.  It sounds like
they are distinguishing between this copy and a raw write.


> +    }
> +
> +    if ((mask & CPSR_F)) {
> +        /* Pre ARMv8: 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 (!arm_feature(env, ARM_FEATURE_V8) &&
> +            (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;
> +        }
> +
> +        if ((val & CPSR_F) != (env->uncached_cpsr & CPSR_F)
> +                && arm_feature(env, ARM_FEATURE_EL3)
> +                && !(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 set\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
>
>

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

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

* Re: [Qemu-devel] [PATCH v3 15/32] target-arm: add NSACR register
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 15/32] target-arm: add NSACR register Fabian Aggeler
@ 2014-06-13 18:27   ` Greg Bellows
  2014-06-17  7:41     ` Aggeler  Fabian
  0 siblings, 1 reply; 78+ messages in thread
From: Greg Bellows @ 2014-06-13 18:27 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall

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

On 10 June 2014 18:54, Fabian Aggeler <aggelerf@ethz.ch> wrote:

> 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>
> ---
>  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 52e679f..bc9edaa 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -182,6 +182,7 @@ typedef struct CPUARMState {
>          uint64_t c1_coproc; /* Coprocessor access register.  */
>          uint32_t c1_xscaleauxcr; /* XScale auxiliary control register.  */
>          uint32_t c1_scr; /* secure config 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.  */
> @@ -593,6 +594,11 @@ static inline void xpsr_write(CPUARMState *env,
> uint32_t val, uint32_t mask)
>  #define SCR_RES1_MASK (3U << 4)
>  #define SCR_MASK      (0x3fff & ~SCR_RES1_MASK)
>
> +#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 f6ff4aa..9671f9f 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -489,7 +489,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);
>              }
> @@ -501,6 +513,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;
> @@ -2184,6 +2197,55 @@ static void scr_write(CPUARMState *env, const
> ARMCPRegInfo *ri, uint64_t value)
>      raw_write(env, ri, value);
>  }
>
> +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_pl(env) != 3)) {
> +            ret = 0x0000C00;
> +        }
>

It appears we are missing a case where 0xc00 is returned because we check
for the non-existence of EL3.

+    }
> +    return ret;
> +}
> +
>

The ARMv8 spec suggests that if EL3 is aarch64 that a read or write of this
register occurs from secure EL1 when aarch32 it is trapped as an exception
to EL3.  Is this omitted?


>  static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
>      { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
>        .type = ARM_CP_NO_MIGRATE,
> @@ -2217,6 +2279,10 @@ static const ARMCPRegInfo security_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, },
> +    { .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
>
>

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

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

* Re: [Qemu-devel] [PATCH v3 20/32] target-arm: arrayfying fieldoffset for banking
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 20/32] target-arm: arrayfying fieldoffset for banking Fabian Aggeler
@ 2014-06-13 20:18   ` Greg Bellows
  0 siblings, 0 replies; 78+ messages in thread
From: Greg Bellows @ 2014-06-13 20:18 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall

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

On 10 June 2014 18:55, Fabian Aggeler <aggelerf@ethz.ch> wrote:

> Prepare ARMCPRegInfo to support specifying two fieldoffsets per
> register definition. This will allow us to keep one register
> definition for banked registers (different offsets for secure/
> non-secure world).
>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> ---
>  target-arm/cpu.h    | 16 +++++++++++++---
>  target-arm/helper.c | 35 +++++++++++++++++++++++------------
>  2 files changed, 36 insertions(+), 15 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index d4eab39..7d7782e 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -1086,12 +1086,22 @@ struct ARMCPRegInfo {
>       * fieldoffset is non-zero, the reset value of the register.
>       */
>      uint64_t resetvalue;
> -    /* Offset of the field in CPUARMState for this register. This is not
> -     * needed if either:
> +    /* Offsets of the fields (secure/non-secure) in CPUARMState for this
> +     * register. The array will be accessed by the ns bit which means the
> +     * secure instance has to be at [0] while the non-secure instance
> must be
> +     * at [1]. If a register is not banked .fieldoffset can be used,
> which maps
> +     * to the non-secure bank.
> +     * This is not needed if either:
>       *  1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
>       *  2. both readfn and writefn are specified
>       */
> -    ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
> +    union { /* offsetof(CPUARMState, field) */
> +        struct {
> +            ptrdiff_t fieldoffset_padding;
> +            ptrdiff_t fieldoffset;
> +        };
> +        ptrdiff_t bank_fieldoffsets[2];
> +    };
>      /* Function for making any access checks for this register in
> addition to
>       * those specified by the 'access' permissions bits. If NULL, no extra
>       * checks required. The access check is performed at runtime, not at
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 610245d..dfaf636 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -2891,20 +2891,31 @@ 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.
> -         */
> -        r2->cp = 15;
> -        r2->type |= ARM_CP_NO_MIGRATE;
> -        r2->resetfn = arm_cp_reset_ignore;
> -#ifdef HOST_WORDS_BIGENDIAN
> -        if (r2->fieldoffset) {
> -            r2->fieldoffset += sizeof(uint32_t);
> +
> +    if (state == ARM_CP_STATE_AA32) {
> +        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];
>

This is somewhat convoluted as sometimes we will be overwriting one of the
bank offsets and other times not.  Would it be better to not unionize the
fieldoffset and the bank offsets and allow this update to be made while
keeping the incoming bank values?


>          }
> +
> +        if (r->state == ARM_CP_STATE_BOTH) {
> +            /* The AArch32 view of a shared register sees the lower 32
> bits
> +             * of a 64 bit backing field. It is not migratable as the
> AArch64
> +             * view handles that. AArch64 also handles reset.
> +             * We assume it is a cp15 register.
> +             */
> +            r2->cp = 15;
> +            r2->type |= ARM_CP_NO_MIGRATE;
> +            r2->resetfn = arm_cp_reset_ignore;
> +#ifdef HOST_WORDS_BIGENDIAN
> +            if (r2->fieldoffset) {
> +                r2->fieldoffset += sizeof(uint32_t);
> +            }
>  #endif
> +        }
>      }
>      if (state == ARM_CP_STATE_AA64) {
>          /* To allow abbreviation of ARMCPRegInfo
> --
> 1.8.3.2
>
>

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

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

* Re: [Qemu-devel] [PATCH v3 28/32] target-arm: make DFSR banked
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 28/32] target-arm: make DFSR banked Fabian Aggeler
@ 2014-06-13 22:06   ` Greg Bellows
  2014-06-17  6:12     ` Edgar E. Iglesias
  0 siblings, 1 reply; 78+ messages in thread
From: Greg Bellows @ 2014-06-13 22:06 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall

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

I just wanted to point out that the change from array-notation to hard-code
numbers in the names undoes Edgar's EL2/EL3 changes.  I prefer this way
over the array notation.


On 10 June 2014 18:55, Fabian Aggeler <aggelerf@ethz.ch> wrote:

> 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>
> ---
>  target-arm/cpu.h        | 13 ++++++++++++-
>  target-arm/helper-a64.c | 17 ++++++++++++++---
>  target-arm/helper.c     | 15 ++++++++-------
>  3 files changed, 34 insertions(+), 11 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 54c51a4..71782cf 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -266,7 +266,18 @@ typedef struct CPUARMState {
>                  uint32_t ifsr32_el2;
>              };
>          };
> -        uint64_t esr_el[4];
> +        union {
> +            struct {
> +                uint64_t dfsr_ns;
> +                uint64_t hsr;
> +                uint64_t dfsr_s;
> +            };
> +            struct {
> +                uint64_t esr_el1;
> +                uint64_t esr_el2;
> +                uint64_t esr_el3;
> +            };
> +        };
>          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-a64.c b/target-arm/helper-a64.c
> index d7522b6..dbbf012 100644
> --- a/target-arm/helper-a64.c
> +++ b/target-arm/helper-a64.c
> @@ -447,6 +447,18 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
>      target_ulong addr = env->cp15.vbar_el[new_el];
>      unsigned int new_mode = aarch64_pstate_mode(new_el, true);
>      int i;
> +    uint64_t *target_esr;
> +    switch (new_el) {
> +    case 3:
> +        target_esr = &env->cp15.esr_el3;
> +        break;
> +    case 2:
> +        target_esr = &env->cp15.esr_el2;
> +        break;
> +    case 1:
> +        target_esr = &env->cp15.esr_el1;
> +        break;
> +    }
>
>      if (arm_current_pl(env) < new_el) {
>          if (env->aarch64) {
> @@ -477,8 +489,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
>      case EXCP_SWI:
>      case EXCP_HVC:
>      case EXCP_SMC:
> -        env->cp15.esr_el[new_el] = env->exception.syndrome;
> -        break;
> +        *target_esr = env->exception.syndrome;
>      case EXCP_IRQ:
>      case EXCP_VIRQ:
>          addr += 0x80;
> @@ -498,7 +509,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
>      } else {
>          env->banked_spsr[0] = cpsr_read(env);
>          if (!env->thumb) {
> -            env->cp15.esr_el[new_el] |= 1 << 25;
> +            *target_esr |= 1 << 25;
>          }
>          env->elr_el[new_el] = env->regs[15];
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index f51498a..793985e 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1492,7 +1492,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,
> @@ -1501,7 +1502,7 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
>      { .name = "ESR_EL1", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
>        .access = PL1_RW,
> -      .fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue =
> 0, },
> +      .fieldoffset = offsetof(CPUARMState, cp15.esr_el1), .resetvalue =
> 0, },
>      { .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
>        .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
>        .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
> @@ -1565,7 +1566,7 @@ static void omap_cachemaint_write(CPUARMState *env,
> const ARMCPRegInfo *ri,
>  static const ARMCPRegInfo omap_cp_reginfo[] = {
>      { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY,
>        .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type =
> ARM_CP_OVERRIDE,
> -      .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]),
> +      .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el1),
>        .resetvalue = 0, },
>      { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
>        .access = PL1_RW, .type = ARM_CP_NOP },
> @@ -2187,7 +2188,7 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
>      { .name = "ESR_EL2", .state = ARM_CP_STATE_AA64,
>        .type = ARM_CP_NO_MIGRATE,
>        .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
> -      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState,
> cp15.esr_el[2]) },
> +      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState,
> cp15.esr_el2) },
>      { .name = "FAR_EL2", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
>        .access = PL2_RW, .fieldoffset = offsetof(CPUARMState,
> cp15.far_el[2]) },
> @@ -2299,7 +2300,7 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
>      { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64,
>        .type = ARM_CP_NO_MIGRATE,
>        .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 2, .opc2 = 0,
> -      .access = PL3_RW, .fieldoffset = offsetof(CPUARMState,
> cp15.esr_el[3]) },
> +      .access = PL3_RW, .fieldoffset = offsetof(CPUARMState,
> cp15.esr_el3) },
>      { .name = "FAR_EL3", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 0,
>        .access = PL3_RW, .fieldoffset = offsetof(CPUARMState,
> cp15.far_el[3]) },
> @@ -3847,11 +3848,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
>
>

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

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

* Re: [Qemu-devel] [PATCH v3 31/32] target-arm: make VBAR banked
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 31/32] target-arm: make VBAR banked Fabian Aggeler
@ 2014-06-13 22:43   ` Greg Bellows
  2014-06-17  7:17     ` Aggeler  Fabian
  0 siblings, 1 reply; 78+ messages in thread
From: Greg Bellows @ 2014-06-13 22:43 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall

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

On 10 June 2014 18:55, Fabian Aggeler <aggelerf@ethz.ch> wrote:

> When EL3 is running in Aarch32 (or ARMv7 with Security Extensions)
> VBAR has a secure and a non-secure instance, which are mapped to
> VBAR_EL1 and VBAR_EL3.
>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> ---
>  target-arm/cpu.h        | 12 +++++++++++-
>  target-arm/helper-a64.c |  6 +++++-
>  target-arm/helper.c     | 14 +++++++-------
>  3 files changed, 23 insertions(+), 9 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 048ede9..c7d606e 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -317,7 +317,17 @@ 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 */
> +        struct { /* vector base address register */
> +            union {
> +                uint64_t vbar_ns;
> +                uint64_t vbar_s;
> +            };
> +            union {
> +                uint64_t vbar_el1;
> +                uint64_t vbar_el3;
> +            };
> +        };
> +        uint64_t vbar_el2;
>

This is broken.  I think the intent is a union of 2 structs rather than a
struct of two unions.  Plus, vbar_el2 should be added in and hvbar made a
union of it.

union {
    struct {
        uint64_t vbar_ns;
        uint64_t hvbar;
        uint64_t vbar_s;
    };
    struct {
        uint64_t vbar_el1;
        uint64_t vbar_el2;
        uint64_t vbar_el3;
    };
};

>          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-a64.c b/target-arm/helper-a64.c
> index 1fc0d3c..a66ec94 100644
> --- a/target-arm/helper-a64.c
> +++ b/target-arm/helper-a64.c
> @@ -444,19 +444,23 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
>      ARMCPU *cpu = ARM_CPU(cs);
>      CPUARMState *env = &cpu->env;
>      unsigned int new_el = arm_excp_target_el(cs, cs->exception_index);
> -    target_ulong addr = env->cp15.vbar_el[new_el];
> +    target_ulong addr = 0;
>      unsigned int new_mode = aarch64_pstate_mode(new_el, true);
>      int i;
>      uint64_t *target_esr;
> +
>      switch (new_el) {
>      case 3:
>          target_esr = &env->cp15.esr_el3;
> +        addr = env->cp15.vbar_el3;
>          break;
>      case 2:
>          target_esr = &env->cp15.esr_el2;
> +        addr = env->cp15.vbar_el2;
>          break;
>      case 1:
>          target_esr = &env->cp15.esr_el1;
> +        addr = env->cp15.vbar_el1;
>          break;
>      }
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index c3195bd..2d085aa 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -803,11 +803,11 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
>        .access = PL1_RW, .type = ARM_CP_NO_MIGRATE,
>        .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
>        .resetvalue = 0, .writefn = pmintenclr_write, },
> -    { .name = "VBAR", .state = ARM_CP_STATE_BOTH,
> +    { .name = "VBAR_EL1", .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) } },
>

In the cases where we are registering banked registers, it may be clearer
to keep the v7 name such as VBAR, because a banked VBAR_EL1 is counter
intuitive.


>      { .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 },
> @@ -2207,7 +2207,7 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
>      { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
>        .access = PL2_RW, .writefn = vbar_write,
> -      .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[2]),
> +      .fieldoffset = offsetof(CPUARMState, cp15.vbar_el2),
>        .resetvalue = 0 },
>      REGINFO_SENTINEL
>  };
> @@ -2319,7 +2319,7 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
>      { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 0,
>        .access = PL3_RW, .writefn = vbar_write,
> -      .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[3]),
> +      .fieldoffset = offsetof(CPUARMState, cp15.vbar_el3),
>        .resetvalue = 0 },
>      { .name = "SCR_EL3", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
> @@ -3910,7 +3910,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
>
>

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

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

* Re: [Qemu-devel] [PATCH v3 30/32] target-arm: make PAR banked
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 30/32] target-arm: make PAR banked Fabian Aggeler
@ 2014-06-13 22:49   ` Greg Bellows
  2014-06-17  7:15     ` Aggeler  Fabian
  0 siblings, 1 reply; 78+ messages in thread
From: Greg Bellows @ 2014-06-13 22:49 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall

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

On 10 June 2014 18:55, Fabian Aggeler <aggelerf@ethz.ch> wrote:

> 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>
> ---
>  target-arm/cpu.h    | 10 +++++++++-
>  target-arm/helper.c | 25 ++++++++++++++-----------
>  2 files changed, 23 insertions(+), 12 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 7f5124c..048ede9 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -299,7 +299,15 @@ typedef struct CPUARMState {
>              };
>          };
>          uint64_t far_el3;
> -        uint64_t par_el1;  /* Translation result. */
> +        struct { /* Translation result. */
> +            union {
> +                uint64_t par_ns;
> +                uint64_t par_s;
> +            };
> +            union {
> +                uint64_t par_el1;
> +            };
> +        };
>

This is broken.  This should be a union of structs rather than a struct of
unions.  Should instead be.

union {
    struct {
        uint64_t par_ns;
        uint64_t par_s;
    };
    struct {
        uint64_t par_el1;
    };
};

         uint32_t c9_insn; /* Cache lockdown registers.  */
>          uint32_t c9_data;
>          uint32_t c9_pmcr; /* performance monitor control register */
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 47bf7a7..c3195bd 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1281,7 +1281,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).
> @@ -1291,14 +1291,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);
>          }
>      }
>  }
> @@ -1306,9 +1308,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,
> @@ -1755,8 +1757,9 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
>      { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0,
>        .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0
> },
>      { .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0,
> -      .access = PL1_RW, .type = ARM_CP_64BIT,
> -      .fieldoffset = offsetof(CPUARMState, cp15.par_el1), .resetvalue = 0
> },
> +      .access = PL1_RW, .type = ARM_CP_64BIT, .resetvalue = 0,
> +      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.par_s),
> +                             offsetof(CPUARMState, cp15.par_ns)} },
>      { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0,
>        .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE,
>        .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
> --
> 1.8.3.2
>
>

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

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

* Re: [Qemu-devel] [PATCH v3 06/32] target-arm: make arm_current_pl() return PL3
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 06/32] target-arm: make arm_current_pl() return PL3 Fabian Aggeler
@ 2014-06-17  5:40   ` Edgar E. Iglesias
  2014-06-17  7:12     ` Aggeler  Fabian
  0 siblings, 1 reply; 78+ messages in thread
From: Edgar E. Iglesias @ 2014-06-17  5:40 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: peter.maydell, peter.crosthwaite, qemu-devel, greg.bellows,
	serge.fdrv, christoffer.dall

On Wed, Jun 11, 2014 at 01:54:48AM +0200, Fabian Aggeler wrote:
> Make arm_current_pl() return PL3 for secure PL1 and monitor mode.
> Increase MMU modes since mmu_index is directly infered from arm_
> current_pl(). Changes assertion in arm_el_is_aa64() to allow EL3.
> 
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> ---
>  target-arm/cpu.h | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index cb0da6b..14007a9 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

I guess this was unintentional here?


>  
>  /* We currently assume float and double are IEEE single and double
>     precision respectively.
> @@ -710,7 +710,6 @@ static inline int arm_feature(CPUARMState *env, int feature)
>      return (env->features & (1ULL << feature)) != 0;
>  }
>  
> -

This too.


>  /* Return true if exception level below EL3 is in secure state */
>  static inline bool arm_is_secure_below_el3(CPUARMState *env)
>  {
> @@ -751,11 +750,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
> @@ -947,9 +947,12 @@ static inline int arm_current_pl(CPUARMState *env)
>  
>      if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR) {
>          return 0;
> +    } else if (arm_is_secure(env)) {
> +        /* Secure PL1 and monitor mode are mapped to PL3 */
> +        return 3;
>      }
> -    /* We don't currently implement the Virtualization or TrustZone
> -     * extensions, so PL2 and PL3 don't exist for us.
> +    /* We currently do not implement the Virtualization extensions, so PL2 does
> +     * not exist for us.
>       */
>      return 1;
>  }
> -- 
> 1.8.3.2
> 

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

* Re: [Qemu-devel] [PATCH v3 05/32] target-arm: reject switching to monitor mode
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 05/32] target-arm: reject switching to monitor mode Fabian Aggeler
  2014-06-12 21:55   ` Greg Bellows
@ 2014-06-17  5:43   ` Edgar E. Iglesias
  1 sibling, 0 replies; 78+ messages in thread
From: Edgar E. Iglesias @ 2014-06-17  5:43 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: peter.maydell, peter.crosthwaite, qemu-devel, greg.bellows,
	serge.fdrv, christoffer.dall

On Wed, Jun 11, 2014 at 01:54:47AM +0200, Fabian Aggeler wrote:
> From: Sergey Fedorov <s.fedorov@samsung.com>
> 
> ...from non-secure state.
>

Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>


> Signed-off-by: Sergey Fedorov <s.fedorov@samsung.com>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> ---
>  target-arm/helper.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index d8d6637..ace8d8b 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -3049,6 +3049,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	[flat|nested] 78+ messages in thread

* Re: [Qemu-devel] [PATCH v3 04/32] target-arm: add arm_is_secure() function
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 04/32] target-arm: add arm_is_secure() function Fabian Aggeler
  2014-06-11 12:17   ` Sergey Fedorov
@ 2014-06-17  5:51   ` Edgar E. Iglesias
  1 sibling, 0 replies; 78+ messages in thread
From: Edgar E. Iglesias @ 2014-06-17  5:51 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: peter.maydell, peter.crosthwaite, qemu-devel, greg.bellows,
	serge.fdrv, christoffer.dall

On Wed, Jun 11, 2014 at 01:54:46AM +0200, Fabian Aggeler wrote:
> 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>
> ---
>  target-arm/cpu.h | 38 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)
> 
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 903aa01..cb0da6b 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -710,6 +710,44 @@ static inline int arm_feature(CPUARMState *env, int feature)
>      return (env->features & (1ULL << feature)) != 0;
>  }
>  
> +
> +/* Return true if exception level below EL3 is in secure state */
> +static inline bool arm_is_secure_below_el3(CPUARMState *env)
> +{
> +#if !defined(CONFIG_USER_ONLY)
> +    if (arm_feature(env, ARM_FEATURE_EL3)) {
> +        return !(env->cp15.scr_el3 & SCR_NS);
> +    } else if (arm_feature(env, ARM_FEATURE_EL2)) {
> +        return false;
> +    } else {
> +        /* IMPDEF: QEMU defaults to non-secure */
> +        return false;
> +    }
> +#else
> +    return false;
> +#endif
> +}

IIUC arm_is_secure_below_el3() will remain unused for defined(CONFIG_USER_ONLY).
Maybe we should just #if !defined(CONFIG_USER_ONLY) the entire function.

Otherwise the logic looks good to me.

Cheers,
Edgar


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

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

* Re: [Qemu-devel] [PATCH v3 28/32] target-arm: make DFSR banked
  2014-06-13 22:06   ` Greg Bellows
@ 2014-06-17  6:12     ` Edgar E. Iglesias
  2014-06-23 16:53       ` Greg Bellows
  2014-06-24 11:05       ` Aggeler  Fabian
  0 siblings, 2 replies; 78+ messages in thread
From: Edgar E. Iglesias @ 2014-06-17  6:12 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Peter Maydell, Peter Crosthwaite, Fabian Aggeler,
	QEMU Developers, Sergey Fedorov, Christoffer Dall

On Fri, Jun 13, 2014 at 05:06:15PM -0500, Greg Bellows wrote:
> I just wanted to point out that the change from array-notation to hard-code
> numbers in the names undoes Edgar's EL2/EL3 changes.  I prefer this way
> over the array notation.

Hi,

This was discussed briefly here
http://lists.gnu.org/archive/html/qemu-devel/2014-05/msg03561.html

IMO, for some regs the array version doesn't make sense but for regs
that need to be indexed by EL it does. Just look at what this patch
results in for aarch64_cpu_do_interrupt(). AArch64 has a simpler/cleaner
architecture in this respect, IMO we should keep the
AArch64 simple and clean and take the banking pain in the AArch32 port.


> 
> 
> On 10 June 2014 18:55, Fabian Aggeler <aggelerf@ethz.ch> wrote:
> 
> > 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>
> > ---
> >  target-arm/cpu.h        | 13 ++++++++++++-
> >  target-arm/helper-a64.c | 17 ++++++++++++++---
> >  target-arm/helper.c     | 15 ++++++++-------
> >  3 files changed, 34 insertions(+), 11 deletions(-)
> >
> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > index 54c51a4..71782cf 100644
> > --- a/target-arm/cpu.h
> > +++ b/target-arm/cpu.h
> > @@ -266,7 +266,18 @@ typedef struct CPUARMState {
> >                  uint32_t ifsr32_el2;
> >              };
> >          };
> > -        uint64_t esr_el[4];
> > +        union {
> > +            struct {
> > +                uint64_t dfsr_ns;
> > +                uint64_t hsr;
> > +                uint64_t dfsr_s;
> > +            };
> > +            struct {
> > +                uint64_t esr_el1;
> > +                uint64_t esr_el2;
> > +                uint64_t esr_el3;
> > +            };
> > +        };

I'd prefer:

-        uint64_t esr_el[4];
+        union {
+            struct {
+                uint64_t dummy 
+                uint64_t dfsr_ns;
+                uint64_t hsr;
+                uint64_t dfsr_s;
+            };
+            struct {
+                uint64_t esr_el[4];
+            };
+        };

And avoid the whole target_esr pointer thing in aarch64_cpu_do_interrupt().

Cheers,
Edgar


> >          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-a64.c b/target-arm/helper-a64.c
> > index d7522b6..dbbf012 100644
> > --- a/target-arm/helper-a64.c
> > +++ b/target-arm/helper-a64.c
> > @@ -447,6 +447,18 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
> >      target_ulong addr = env->cp15.vbar_el[new_el];
> >      unsigned int new_mode = aarch64_pstate_mode(new_el, true);
> >      int i;
> > +    uint64_t *target_esr;
> > +    switch (new_el) {
> > +    case 3:
> > +        target_esr = &env->cp15.esr_el3;
> > +        break;
> > +    case 2:
> > +        target_esr = &env->cp15.esr_el2;
> > +        break;
> > +    case 1:
> > +        target_esr = &env->cp15.esr_el1;
> > +        break;
> > +    }
> >
> >      if (arm_current_pl(env) < new_el) {
> >          if (env->aarch64) {
> > @@ -477,8 +489,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
> >      case EXCP_SWI:
> >      case EXCP_HVC:
> >      case EXCP_SMC:
> > -        env->cp15.esr_el[new_el] = env->exception.syndrome;
> > -        break;
> > +        *target_esr = env->exception.syndrome;
> >      case EXCP_IRQ:
> >      case EXCP_VIRQ:
> >          addr += 0x80;
> > @@ -498,7 +509,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
> >      } else {
> >          env->banked_spsr[0] = cpsr_read(env);
> >          if (!env->thumb) {
> > -            env->cp15.esr_el[new_el] |= 1 << 25;
> > +            *target_esr |= 1 << 25;
> >          }
> >          env->elr_el[new_el] = env->regs[15];
> >
> > diff --git a/target-arm/helper.c b/target-arm/helper.c
> > index f51498a..793985e 100644
> > --- a/target-arm/helper.c
> > +++ b/target-arm/helper.c
> > @@ -1492,7 +1492,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,
> > @@ -1501,7 +1502,7 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
> >      { .name = "ESR_EL1", .state = ARM_CP_STATE_AA64,
> >        .opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
> >        .access = PL1_RW,
> > -      .fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue =
> > 0, },
> > +      .fieldoffset = offsetof(CPUARMState, cp15.esr_el1), .resetvalue =
> > 0, },
> >      { .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
> >        .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
> >        .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
> > @@ -1565,7 +1566,7 @@ static void omap_cachemaint_write(CPUARMState *env,
> > const ARMCPRegInfo *ri,
> >  static const ARMCPRegInfo omap_cp_reginfo[] = {
> >      { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY,
> >        .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type =
> > ARM_CP_OVERRIDE,
> > -      .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]),
> > +      .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el1),
> >        .resetvalue = 0, },
> >      { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
> >        .access = PL1_RW, .type = ARM_CP_NOP },
> > @@ -2187,7 +2188,7 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
> >      { .name = "ESR_EL2", .state = ARM_CP_STATE_AA64,
> >        .type = ARM_CP_NO_MIGRATE,
> >        .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
> > -      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState,
> > cp15.esr_el[2]) },
> > +      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState,
> > cp15.esr_el2) },
> >      { .name = "FAR_EL2", .state = ARM_CP_STATE_AA64,
> >        .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
> >        .access = PL2_RW, .fieldoffset = offsetof(CPUARMState,
> > cp15.far_el[2]) },
> > @@ -2299,7 +2300,7 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
> >      { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64,
> >        .type = ARM_CP_NO_MIGRATE,
> >        .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 2, .opc2 = 0,
> > -      .access = PL3_RW, .fieldoffset = offsetof(CPUARMState,
> > cp15.esr_el[3]) },
> > +      .access = PL3_RW, .fieldoffset = offsetof(CPUARMState,
> > cp15.esr_el3) },
> >      { .name = "FAR_EL3", .state = ARM_CP_STATE_AA64,
> >        .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 0,
> >        .access = PL3_RW, .fieldoffset = offsetof(CPUARMState,
> > cp15.far_el[3]) },
> > @@ -3847,11 +3848,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	[flat|nested] 78+ messages in thread

* Re: [Qemu-devel] [PATCH v3 06/32] target-arm: make arm_current_pl() return PL3
  2014-06-17  7:12     ` Aggeler  Fabian
@ 2014-06-17  7:07       ` Edgar E. Iglesias
  0 siblings, 0 replies; 78+ messages in thread
From: Edgar E. Iglesias @ 2014-06-17  7:07 UTC (permalink / raw)
  To: Aggeler Fabian
  Cc: Peter Maydell, peter.crosthwaite,
	qemu-devel@nongnu.org Developers, Greg Bellows, Sergey Fedorov,
	Christoffer Dall

On Tue, Jun 17, 2014 at 07:12:19AM +0000, Aggeler  Fabian wrote:
> 
> On 17 Jun 2014, at 07:40, Edgar E. Iglesias <edgar.iglesias@gmail.com> wrote:
> 
> > On Wed, Jun 11, 2014 at 01:54:48AM +0200, Fabian Aggeler wrote:
> >> Make arm_current_pl() return PL3 for secure PL1 and monitor mode.
> >> Increase MMU modes since mmu_index is directly infered from arm_
> >> current_pl(). Changes assertion in arm_el_is_aa64() to allow EL3.
> >> 
> >> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> >> ---
> >> target-arm/cpu.h | 15 +++++++++------
> >> 1 file changed, 9 insertions(+), 6 deletions(-)
> >> 
> >> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> >> index cb0da6b..14007a9 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
> > 
> > I guess this was unintentional here?
> 
> Not really. Well, it was first in a separate commit but I squashed it. We need to increase
> the number of MMU_MODES to 4 because arm_current_pl() now returns 3 for monitor
> mode and secure PL1 (Aarch32) and EL3 (Aarch64), which is directly used as mmu_index
> since your last patchset. Is my reasoning wrong?


Aha I see. Nah I think you are correct, I was just surprised that it wasn't
a separate patch.

Thanks,
Edgar


> 
> 
> > 
> > 
> >> 
> >> /* We currently assume float and double are IEEE single and double
> >>    precision respectively.
> >> @@ -710,7 +710,6 @@ static inline int arm_feature(CPUARMState *env, int feature)
> >>     return (env->features & (1ULL << feature)) != 0;
> >> }
> >> 
> >> -
> > 
> > This too.
> > 
> > 
> >> /* Return true if exception level below EL3 is in secure state */
> >> static inline bool arm_is_secure_below_el3(CPUARMState *env)
> >> {
> >> @@ -751,11 +750,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
> >> @@ -947,9 +947,12 @@ static inline int arm_current_pl(CPUARMState *env)
> >> 
> >>     if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR) {
> >>         return 0;
> >> +    } else if (arm_is_secure(env)) {
> >> +        /* Secure PL1 and monitor mode are mapped to PL3 */
> >> +        return 3;
> >>     }
> >> -    /* We don't currently implement the Virtualization or TrustZone
> >> -     * extensions, so PL2 and PL3 don't exist for us.
> >> +    /* We currently do not implement the Virtualization extensions, so PL2 does
> >> +     * not exist for us.
> >>      */
> >>     return 1;
> >> }
> >> -- 
> >> 1.8.3.2
> 

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

* Re: [Qemu-devel] [PATCH v3 06/32] target-arm: make arm_current_pl() return PL3
  2014-06-17  5:40   ` Edgar E. Iglesias
@ 2014-06-17  7:12     ` Aggeler  Fabian
  2014-06-17  7:07       ` Edgar E. Iglesias
  0 siblings, 1 reply; 78+ messages in thread
From: Aggeler  Fabian @ 2014-06-17  7:12 UTC (permalink / raw)
  To: Edgar E. Iglesias
  Cc: Peter Maydell, peter.crosthwaite,
	qemu-devel@nongnu.org Developers, Greg Bellows, Sergey Fedorov,
	Christoffer Dall


On 17 Jun 2014, at 07:40, Edgar E. Iglesias <edgar.iglesias@gmail.com> wrote:

> On Wed, Jun 11, 2014 at 01:54:48AM +0200, Fabian Aggeler wrote:
>> Make arm_current_pl() return PL3 for secure PL1 and monitor mode.
>> Increase MMU modes since mmu_index is directly infered from arm_
>> current_pl(). Changes assertion in arm_el_is_aa64() to allow EL3.
>> 
>> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
>> ---
>> target-arm/cpu.h | 15 +++++++++------
>> 1 file changed, 9 insertions(+), 6 deletions(-)
>> 
>> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
>> index cb0da6b..14007a9 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
> 
> I guess this was unintentional here?

Not really. Well, it was first in a separate commit but I squashed it. We need to increase
the number of MMU_MODES to 4 because arm_current_pl() now returns 3 for monitor
mode and secure PL1 (Aarch32) and EL3 (Aarch64), which is directly used as mmu_index
since your last patchset. Is my reasoning wrong? 


> 
> 
>> 
>> /* We currently assume float and double are IEEE single and double
>>    precision respectively.
>> @@ -710,7 +710,6 @@ static inline int arm_feature(CPUARMState *env, int feature)
>>     return (env->features & (1ULL << feature)) != 0;
>> }
>> 
>> -
> 
> This too.
> 
> 
>> /* Return true if exception level below EL3 is in secure state */
>> static inline bool arm_is_secure_below_el3(CPUARMState *env)
>> {
>> @@ -751,11 +750,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
>> @@ -947,9 +947,12 @@ static inline int arm_current_pl(CPUARMState *env)
>> 
>>     if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR) {
>>         return 0;
>> +    } else if (arm_is_secure(env)) {
>> +        /* Secure PL1 and monitor mode are mapped to PL3 */
>> +        return 3;
>>     }
>> -    /* We don't currently implement the Virtualization or TrustZone
>> -     * extensions, so PL2 and PL3 don't exist for us.
>> +    /* We currently do not implement the Virtualization extensions, so PL2 does
>> +     * not exist for us.
>>      */
>>     return 1;
>> }
>> -- 
>> 1.8.3.2

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

* Re: [Qemu-devel] [PATCH v3 30/32] target-arm: make PAR banked
  2014-06-13 22:49   ` Greg Bellows
@ 2014-06-17  7:15     ` Aggeler  Fabian
  0 siblings, 0 replies; 78+ messages in thread
From: Aggeler  Fabian @ 2014-06-17  7:15 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall


On 14 Jun 2014, at 00:49, Greg Bellows <greg.bellows@linaro.org<mailto:greg.bellows@linaro.org>> wrote:




On 10 June 2014 18:55, Fabian Aggeler <aggelerf@ethz.ch<mailto:aggelerf@ethz.ch>> wrote:
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<mailto:aggelerf@ethz.ch>>
---
 target-arm/cpu.h    | 10 +++++++++-
 target-arm/helper.c | 25 ++++++++++++++-----------
 2 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 7f5124c..048ede9 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -299,7 +299,15 @@ typedef struct CPUARMState {
             };
         };
         uint64_t far_el3;
-        uint64_t par_el1;  /* Translation result. */
+        struct { /* Translation result. */
+            union {
+                uint64_t par_ns;
+                uint64_t par_s;
+            };
+            union {
+                uint64_t par_el1;
+            };
+        };

This is broken.  This should be a union of structs rather than a struct of unions.  Should instead be.

union {
    struct {
        uint64_t par_ns;
        uint64_t par_s;
    };
    struct {
        uint64_t par_el1;
    };
};


Right, that should have been the other way round, like you said.

         uint32_t c9_insn; /* Cache lockdown registers.  */
         uint32_t c9_data;
         uint32_t c9_pmcr; /* performance monitor control register */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 47bf7a7..c3195bd 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1281,7 +1281,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).
@@ -1291,14 +1291,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);
         }
     }
 }
@@ -1306,9 +1308,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,
@@ -1755,8 +1757,9 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
     { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0,
       .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
     { .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0,
-      .access = PL1_RW, .type = ARM_CP_64BIT,
-      .fieldoffset = offsetof(CPUARMState, cp15.par_el1), .resetvalue = 0 },
+      .access = PL1_RW, .type = ARM_CP_64BIT, .resetvalue = 0,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.par_s),
+                             offsetof(CPUARMState, cp15.par_ns)} },
     { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0,
       .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE,
       .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
--
1.8.3.2

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

* Re: [Qemu-devel] [PATCH v3 31/32] target-arm: make VBAR banked
  2014-06-13 22:43   ` Greg Bellows
@ 2014-06-17  7:17     ` Aggeler  Fabian
  0 siblings, 0 replies; 78+ messages in thread
From: Aggeler  Fabian @ 2014-06-17  7:17 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall


On 14 Jun 2014, at 00:43, Greg Bellows <greg.bellows@linaro.org<mailto:greg.bellows@linaro.org>> wrote:




On 10 June 2014 18:55, Fabian Aggeler <aggelerf@ethz.ch<mailto:aggelerf@ethz.ch>> wrote:
When EL3 is running in Aarch32 (or ARMv7 with Security Extensions)
VBAR has a secure and a non-secure instance, which are mapped to
VBAR_EL1 and VBAR_EL3.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch<mailto:aggelerf@ethz.ch>>
---
 target-arm/cpu.h        | 12 +++++++++++-
 target-arm/helper-a64.c |  6 +++++-
 target-arm/helper.c     | 14 +++++++-------
 3 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 048ede9..c7d606e 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -317,7 +317,17 @@ 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 */
+        struct { /* vector base address register */
+            union {
+                uint64_t vbar_ns;
+                uint64_t vbar_s;
+            };
+            union {
+                uint64_t vbar_el1;
+                uint64_t vbar_el3;
+            };
+        };
+        uint64_t vbar_el2;

This is broken.  I think the intent is a union of 2 structs rather than a struct of two unions.  Plus, vbar_el2 should be added in and hvbar made a union of it.

union {
    struct {
        uint64_t vbar_ns;
        uint64_t hvbar;
        uint64_t vbar_s;
    };
    struct {
        uint64_t vbar_el1;
        uint64_t vbar_el2;
        uint64_t vbar_el3;
    };
};

Indeed. I left out the hvbar mapping to avoid introducing Virtualization Extension changes in
this patchset but I guess it makes sense since we are touching it anyways.

         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-a64.c b/target-arm/helper-a64.c
index 1fc0d3c..a66ec94 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -444,19 +444,23 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
     unsigned int new_el = arm_excp_target_el(cs, cs->exception_index);
-    target_ulong addr = env->cp15.vbar_el[new_el];
+    target_ulong addr = 0;
     unsigned int new_mode = aarch64_pstate_mode(new_el, true);
     int i;
     uint64_t *target_esr;
+
     switch (new_el) {
     case 3:
         target_esr = &env->cp15.esr_el3;
+        addr = env->cp15.vbar_el3;
         break;
     case 2:
         target_esr = &env->cp15.esr_el2;
+        addr = env->cp15.vbar_el2;
         break;
     case 1:
         target_esr = &env->cp15.esr_el1;
+        addr = env->cp15.vbar_el1;
         break;
     }

diff --git a/target-arm/helper.c b/target-arm/helper.c
index c3195bd..2d085aa 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -803,11 +803,11 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
       .access = PL1_RW, .type = ARM_CP_NO_MIGRATE,
       .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
       .resetvalue = 0, .writefn = pmintenclr_write, },
-    { .name = "VBAR", .state = ARM_CP_STATE_BOTH,
+    { .name = "VBAR_EL1", .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) } },

In the cases where we are registering banked registers, it may be clearer to keep the v7 name such as VBAR, because a banked VBAR_EL1 is counter intuitive.

     { .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 },
@@ -2207,7 +2207,7 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
     { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
       .access = PL2_RW, .writefn = vbar_write,
-      .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[2]),
+      .fieldoffset = offsetof(CPUARMState, cp15.vbar_el2),
       .resetvalue = 0 },
     REGINFO_SENTINEL
 };
@@ -2319,7 +2319,7 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
     { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 0,
       .access = PL3_RW, .writefn = vbar_write,
-      .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[3]),
+      .fieldoffset = offsetof(CPUARMState, cp15.vbar_el3),
       .resetvalue = 0 },
     { .name = "SCR_EL3", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
@@ -3910,7 +3910,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] 78+ messages in thread

* Re: [Qemu-devel] [PATCH v3 02/32] target-arm: move Aarch32 SCR into security reglist
  2014-06-12 21:55   ` Greg Bellows
@ 2014-06-17  7:22     ` Aggeler  Fabian
  0 siblings, 0 replies; 78+ messages in thread
From: Aggeler  Fabian @ 2014-06-17  7:22 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall


On 12 Jun 2014, at 23:55, Greg Bellows <greg.bellows@linaro.org<mailto:greg.bellows@linaro.org>> wrote:

Conflict with Edgar's changes around the name of the security register group v8_el3_cp_reginfo vs. security_cp_reginfo.

Given that there is a difference between the v7 regs and their v8 equivalents such as encoding, I propose we create 2 separate groups, but map them to the same storage where applicable.  This somewhat follows on the SCR mapping discussion.

That’s actually what I was trying to do here. I separated Aarch32 Security Extension registers into a separate group.
They do map to the same storage already in this patch. I guess we could rename the group to v8_el3_a32_cp_reginfo
or something like this. What do you think?



On 10 June 2014 18:54, Fabian Aggeler <aggelerf@ethz.ch<mailto:aggelerf@ethz.ch>> wrote:
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<mailto:s.fedorov@samsung.com>>
Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch<mailto:aggelerf@ethz.ch>>
---
 target-arm/helper.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index e157cc2..d8d6637 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -792,9 +792,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 = offsetof(CPUARMState, cp15.c1_scr),
-      .resetvalue = 0, },
     { .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 },
@@ -2216,6 +2213,13 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
     REGINFO_SENTINEL
 };

+static const ARMCPRegInfo security_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, },
+    REGINFO_SENTINEL
+};
+
 static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                         uint64_t value)
 {
@@ -2479,6 +2483,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
     }
     if (arm_feature(env, ARM_FEATURE_EL3)) {
         define_arm_cp_regs(cpu, v8_el3_cp_reginfo);
+        define_arm_cp_regs(cpu, security_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] 78+ messages in thread

* Re: [Qemu-devel] [PATCH v3 11/32] target-arm: add async excp target_el&mode function
  2014-06-12 21:56   ` Greg Bellows
@ 2014-06-17  7:29     ` Aggeler  Fabian
  0 siblings, 0 replies; 78+ messages in thread
From: Aggeler  Fabian @ 2014-06-17  7:29 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall


On 12 Jun 2014, at 23:56, Greg Bellows <greg.bellows@linaro.org<mailto:greg.bellows@linaro.org>> wrote:




On 10 June 2014 18:54, Fabian Aggeler <aggelerf@ethz.ch<mailto:aggelerf@ethz.ch>> wrote:
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<mailto:aggelerf@ethz.ch>>
---
 target-arm/cpu.h    |   3 ++
 target-arm/helper.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 140 insertions(+)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index b786a5a..52e679f 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -768,6 +768,9 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)

 void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx);
+inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t *target_mode,
+                                        uint32_t excp_idx, uint32_t cur_el,
+                                        bool secure);

 /* Interface between CPU and Interrupt controller.  */
 void armv7m_nvic_set_pending(void *opaque, int irq);
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 5822353..8333b52 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3224,6 +3224,21 @@ uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
     return 0;
 }

+inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t *target_mode,
+                                        uint32_t excp_idx, uint32_t cur_el,
+                                        bool secure)
+{
+    switch (excp_idx) {
+    case EXCP_IRQ:
+        *target_mode = ARM_CPU_MODE_IRQ;
+        break;
+    case EXCP_FIQ:
+        *target_mode = ARM_CPU_MODE_FIQ;
+        break;
+    }
+    return 1;
+}
+
 unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
 {
     return 1;
@@ -3285,6 +3300,128 @@ void switch_mode(CPUARMState *env, int mode)
 }

 /*
+ * Determine the target EL for physical exceptions
+ */
+inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t *target_mode,
+                                        uint32_t excp_idx, uint32_t cur_el,
+                                        bool secure)
+{
+    CPUARMState *env = cs->env_ptr;
+    uint32_t target_el = 1;
+    uint32_t excp_mode = 0;
+
+    bool scr_routing = 0; /* IRQ, FIQ, EA */
+    bool hcr_routing = 0; /* IMO, FMO, AMO */
+
+    switch (excp_idx) {
+    case EXCP_IRQ:
+        scr_routing = (env->cp15.scr_el3 & SCR_IRQ);
+        hcr_routing = (env->cp15.hcr_el2 & HCR_IMO);
+        excp_mode = ARM_CPU_MODE_IRQ;
+        break;
+    case EXCP_FIQ:
+        scr_routing = (env->cp15.scr_el3 & SCR_FIQ);
+        hcr_routing = (env->cp15.hcr_el2 & HCR_FMO);
+        excp_mode = ARM_CPU_MODE_FIQ;
+    }
+
+    /* If HCR.TGE is set all exceptions that would be routed to EL1 are
+     * routed to EL2 (in non-secure world).
+     */
+    if (arm_feature(env, ARM_FEATURE_EL2) && (env->cp15.hcr_el2 & HCR_TGE)) {
+        hcr_routing = 1;
+    }
+
+    /* Determine target EL according to ARM ARMv8 tables G1-15 and G1-16 */
+    if (arm_el_is_aa64(env, 3)) {
+        /* EL3 in Aarch64 */
+        if (scr_routing) {
+            /* IRQ|FIQ|EA == 1 */
+            target_el = 3;
+        } else {
+            if (hcr_routing) {
+                /* IRQ|FIQ|EA == 0
+                 * IMO|FMO|AMO == 1 */
+                if (secure) {
+                    /* Secure */
+                    target_el = 1;
+                    if (!arm_el_is_aa64(env, 1)) {
+                        /* EL1 using Aarch32 */
+                        *target_mode = ARM_CPU_MODE_ABT;
+                    }
+                } else if (cur_el < 2) {
+                    /* Non-Secure goes to EL2 */
+                    target_el = 2;
+                    if (!arm_el_is_aa64(env, 2)) {
+                        /* EL2 using Aarch32 */
+                        *target_mode = ARM_CPU_MODE_HYP;
+                    }
+                }
+            } else if (env->cp15.scr_el3 & SCR_RW) {
+                /* IRQ|FIQ|EA == 0
+                 * IMO|FMO|AMO == 0
+                 * RW == 1 (Next lower level is Aarch64)
+                 */
+                if (cur_el < 2) {
+                    target_el = 1;
+                } else {
+                    /* Interrupt not taken but remains pending */
+                }
+            } else {
+                /* IRQ|FIQ|EA == 0
+                 * IMO|FMO|AMO == 0
+                 * RW == 0 (Next lower level is Aarch64)
+                 */
+                if (cur_el < 2) {
+                    target_el = 1;
+                    *target_mode = ARM_CPU_MODE_ABT;

According to the aforementioned tables, the target mode should be excp_mode, not always abort.

True, this is wrong and should be excp_mode, as you said.


+                } else if (cur_el == 2) {
+                    target_el = 2;
+                    *target_mode = ARM_CPU_MODE_HYP;
+                } else {
+                    /* Interrupt not taken but remains pending */
+                }
+            }
+        }
+    } else {
+        /* EL3 in Aarch32 */
+        if (scr_routing) {
+            /* IRQ|FIQ|EA == 1 */
+            target_el = 3;
+            *target_mode = ARM_CPU_MODE_MON;
+        } else {
+            if (hcr_routing) {
+                /* IRQ|FIQ|EA == 0
+                 * IMO|FMO|AMO == 1
+                 */
+                if (secure) {
+                    target_el = 3;
+                    *target_mode = excp_mode;
+                } else {
+                    target_el = 2;
+                    *target_mode = ARM_CPU_MODE_HYP;
+                }
+            } else {
+                /* IRQ|FIQ|EA == 0
+                 * IMO|FMO|AMO == 0
+                 */
+                if (cur_el < 2) {
+                    target_el = 1;
+                    *target_mode = excp_mode;
+                } else if (cur_el == 2) {
+                    target_el = 2;
+                    *target_mode = ARM_CPU_MODE_HYP;
+                } else if (secure) {
+                    target_el = 3;
+                    *target_mode = excp_mode;
+                }
+            }
+        }
+    }
+    return target_el;
+}
+
+/*
  * Determine the target EL for a given exception type.
  */
 unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
--
1.8.3.2

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

* Re: [Qemu-devel] [PATCH v3 14/32] target-arm: Respect SCR.FW, SCR.AW and SCTLR.NMFI
  2014-06-12 22:43   ` Greg Bellows
@ 2014-06-17  7:36     ` Aggeler  Fabian
  0 siblings, 0 replies; 78+ messages in thread
From: Aggeler  Fabian @ 2014-06-17  7:36 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall


On 13 Jun 2014, at 00:43, Greg Bellows <greg.bellows@linaro.org<mailto:greg.bellows@linaro.org>> wrote:




On 10 June 2014 18:54, Fabian Aggeler <aggelerf@ethz.ch<mailto:aggelerf@ethz.ch>> wrote:
bits when modifying CPSR.

Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch<mailto:aggelerf@ethz.ch>>
---
 target-arm/helper.c | 42 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 2fbecfa..f6ff4aa 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3091,9 +3091,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.
@@ -3105,6 +3102,45 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
             switch_mode(env, val & CPSR_M);
         }
     }
+
+    /* In an implementation that does not include Virtualization Extensions
+     * the SCR.FW and SCR.AW<http://scr.aw/> bit control whether non-secure software is allowed
+     * to change the CPSR_F and CPSR_A bits respectively.
+     */
+    if ((mask & CPSR_A)
+            && (val & CPSR_A) != (env->uncached_cpsr & CPSR_A)
+            && arm_feature(env, ARM_FEATURE_EL3)
+            && !(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<http://scr.aw/> bit set\n");
+        mask &= ~CPSR_A;

Ignoring the write appears to only be valid in the case of ARMv7 (actually says "early implementations of v7") but not v8.  This is noted in the ARMv8 spec in the section "Effects of EL3 and EL2 on the CPSR.{A, F} bits".  According to this passage, the AW/FW bits only block the corresponding bits being updated when the SPSR is copied to the CPSR.  It sounds like they are distinguishing between this copy and a raw write.

Yes, I missed that bit. Adding a !arm_feature(env, ARM_FEATURE_V8) condition should help
in that case. And then do the check as well when copying SPSR to CPSR.


+    }
+
+    if ((mask & CPSR_F)) {
+        /* Pre ARMv8: 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 (!arm_feature(env, ARM_FEATURE_V8) &&
+            (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;
+        }
+
+        if ((val & CPSR_F) != (env->uncached_cpsr & CPSR_F)
+                && arm_feature(env, ARM_FEATURE_EL3)
+                && !(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 set\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] 78+ messages in thread

* Re: [Qemu-devel] [PATCH v3 15/32] target-arm: add NSACR register
  2014-06-13 18:27   ` Greg Bellows
@ 2014-06-17  7:41     ` Aggeler  Fabian
  2014-06-24 15:37       ` Greg Bellows
  0 siblings, 1 reply; 78+ messages in thread
From: Aggeler  Fabian @ 2014-06-17  7:41 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall


On 13 Jun 2014, at 20:27, Greg Bellows <greg.bellows@linaro.org<mailto:greg.bellows@linaro.org>> wrote:




On 10 June 2014 18:54, Fabian Aggeler <aggelerf@ethz.ch<mailto:aggelerf@ethz.ch>> wrote:
Implements NSACR register with corresponding read/write functions
for ARMv7 and ARMv8.

Signed-off-by: Sergey Fedorov <s.fedorov@samsung.com<mailto:s.fedorov@samsung.com>>
Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch<mailto:aggelerf@ethz.ch>>
---
 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 52e679f..bc9edaa 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -182,6 +182,7 @@ typedef struct CPUARMState {
         uint64_t c1_coproc; /* Coprocessor access register.  */
         uint32_t c1_xscaleauxcr; /* XScale auxiliary control register.  */
         uint32_t c1_scr; /* secure config 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.  */
@@ -593,6 +594,11 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
 #define SCR_RES1_MASK (3U << 4)
 #define SCR_MASK      (0x3fff & ~SCR_RES1_MASK)

+#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 f6ff4aa..9671f9f 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -489,7 +489,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);
             }
@@ -501,6 +513,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;
@@ -2184,6 +2197,55 @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
     raw_write(env, ri, value);
 }

+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_pl(env) != 3)) {
+            ret = 0x0000C00;
+        }

It appears we are missing a case where 0xc00 is returned because we check for the non-existence of EL3.

Right, this case is missing.


+    }
+    return ret;
+}
+

The ARMv8 spec suggests that if EL3 is aarch64 that a read or write of this register occurs from secure EL1 when aarch32 it is trapped as an exception to EL3.  Is this omitted?

It seems I skipped that line when reading the ARMv8 spec. Should be added of course.


 static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
     { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_NO_MIGRATE,
@@ -2217,6 +2279,10 @@ static const ARMCPRegInfo security_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, },
+    { .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] 78+ messages in thread

* Re: [Qemu-devel] [PATCH v3 09/32] target-arm: extend Aarch32 async excp masking
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 09/32] target-arm: extend Aarch32 async excp masking Fabian Aggeler
@ 2014-06-17  7:48   ` Edgar E. Iglesias
  0 siblings, 0 replies; 78+ messages in thread
From: Edgar E. Iglesias @ 2014-06-17  7:48 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: peter.maydell, peter.crosthwaite, qemu-devel, greg.bellows,
	serge.fdrv, christoffer.dall

On Wed, Jun 11, 2014 at 01:54:51AM +0200, Fabian Aggeler wrote:
> This patch extends arm_excp_unmasked() according to ARM ARMv7 and
> ARM ARMv8 (all EL running in Aarch32) and adds comments.

Hi Fabian,

I think this and the following patch generally look good. I haven't
checked all the details yet though. A few minor comments here.



> 
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> ---
>  target-arm/cpu.h | 77 ++++++++++++++++++++++++++++++++++++++++++++------------
>  1 file changed, 61 insertions(+), 16 deletions(-)
> 
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 661bfbe..f8531aa 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -581,6 +581,8 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
>  #define SCR_IRQ       (1U << 1)
>  #define SCR_FIQ       (1U << 2)
>  #define SCR_EA        (1U << 3)
> +#define SCR_FW        (1U << 4)
> +#define SCR_AW        (1U << 5)
>  #define SCR_SMD       (1U << 7)
>  #define SCR_HCE       (1U << 8)
>  #define SCR_SIF       (1U << 9)
> @@ -1183,30 +1185,73 @@ 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 target_el = arm_excp_target_el(cs, excp_idx);
> -    /* FIXME: Use actual secure state.  */
> -    bool secure = false;
> -    /* Interrupts can only be hypervised and routed to
> -     * EL2 if we are in NS EL0/1.
> -     */
> -    bool irq_can_hyp = !secure && cur_el < 2 && target_el == 2;
> +    bool secure = arm_is_secure(env);
> +
>      bool irq_unmasked = ((IS_M(env) && env->regs[15] < 0xfffffff0)
>                            || !(env->daif & PSTATE_I));
>  
> -    /* Don't take exceptions if they target a lower EL.  */
> -    if (cur_el > target_el) {
> -        return false;
> -    }

If you remove this, it needs to be replaced with something equivalent
for VFIQ/VIRQ.


> -
> +    /* 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 (!secure) {
> +            if (arm_feature(env, ARM_FEATURE_EL2) &&
> +                    (env->cp15.hcr_el2 & HCR_FMO)) {

I think some of this logic will be simpler to read if you can for positive
flag testing assume that hcr_el2 is zero when el2 is unavailable. Same
for scr_el3 positive flag testing.

> +                /* 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
> +                 */
> +                if (cur_el < 2) {
> +                    return true;
> +                } else if (arm_feature(env, ARM_FEATURE_EL3) &&
> +                        (env->cp15.scr_el3 & SCR_FIQ)) {
> +                    return true;
> +                }
> +            }
> +            /* 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 (!secure) {
> +            if (arm_feature(env, ARM_FEATURE_EL2) &&
> +                    (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
> +                 */
> +                if (cur_el < 2) {
> +                    return true;
> +                } else if (arm_feature(env, ARM_FEATURE_EL3) &&
> +                        (env->cp15.scr_el3 & SCR_IRQ)) {
> +                    return true;
> +                }
> +            }
>          }
>          return irq_unmasked;
>      case EXCP_VFIQ:
> -- 
> 1.8.3.2
> 

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

* Re: [Qemu-devel] [PATCH v3 03/32] target-arm: increase arrays of registers R13 & R14
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 03/32] target-arm: increase arrays of registers R13 & R14 Fabian Aggeler
@ 2014-06-17  8:57   ` Edgar E. Iglesias
  0 siblings, 0 replies; 78+ messages in thread
From: Edgar E. Iglesias @ 2014-06-17  8:57 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: peter.maydell, peter.crosthwaite, qemu-devel, greg.bellows,
	serge.fdrv, christoffer.dall

On Wed, Jun 11, 2014 at 01:54:45AM +0200, Fabian Aggeler wrote:
> Increasing banked_r13 and banked_r14 to store LR_mon and SP_mon (bank
> index 7).

Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>

> 
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> ---
>  target-arm/cpu.h     | 4 ++--
>  target-arm/machine.c | 4 ++--
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 060664f..903aa01 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 3bcc7cc..5ed495e 100644
> --- a/target-arm/machine.c
> +++ b/target-arm/machine.c
> @@ -234,8 +234,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	[flat|nested] 78+ messages in thread

* Re: [Qemu-devel] [PATCH v3 07/32] target-arm: add non-secure Translation Block flag
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 07/32] target-arm: add non-secure Translation Block flag Fabian Aggeler
@ 2014-06-17  9:15   ` Edgar E. Iglesias
  2014-06-17 10:07     ` Sergey Fedorov
  2014-06-25  4:15   ` Edgar E. Iglesias
  1 sibling, 1 reply; 78+ messages in thread
From: Edgar E. Iglesias @ 2014-06-17  9:15 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: peter.maydell, peter.crosthwaite, qemu-devel, greg.bellows,
	serge.fdrv, christoffer.dall

On Wed, Jun 11, 2014 at 01:54:49AM +0200, Fabian Aggeler wrote:
> From: Sergey Fedorov <s.fedorov@samsung.com>
> 
> This patch is based on idea found in patch at
> git://github.com/jowinter/qemu-trustzone.git
> f3d955c6c0ed8c46bc0eb10b634201032a651dd2 by
> Johannes Winter <johannes.winter@iaik.tugraz.at>.
> 
> This flag prevents QEMU from executing TCG code generated for other CPU
> security state. It also allows to generate different TCG code depending on
> CPU secure state.

Hi, I think the patch looks OK but I'm unsure if it brings any benefits
unless we add separate TLBs for S and NS.

I noticed that TTBR0 gets banked in the series, but are changes to
SCR.NS flushing the TLBs? I might have missed that from the patches.
You'll need it unless we add separate S/NS TLBs.

Considering that changes to SCR.NS will flush the TLBs, the
use of a per TB ns flag is limited, unless I am missing something...

Cheers,
Edgar


> 
> Signed-off-by: Sergey Fedorov <s.fedorov@samsung.com>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> ---
>  target-arm/cpu.h           | 10 ++++++++++
>  target-arm/translate-a64.c |  1 +
>  target-arm/translate.c     |  3 +++
>  target-arm/translate.h     |  1 +
>  4 files changed, 15 insertions(+)
> 
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 14007a9..661bfbe 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -1275,6 +1275,8 @@ static inline int cpu_mmu_index (CPUARMState *env)
>  #define ARM_TBFLAG_BSWAP_CODE_MASK  (1 << ARM_TBFLAG_BSWAP_CODE_SHIFT)
>  #define ARM_TBFLAG_CPACR_FPEN_SHIFT 17
>  #define ARM_TBFLAG_CPACR_FPEN_MASK  (1 << ARM_TBFLAG_CPACR_FPEN_SHIFT)
> +#define ARM_TBFLAG_NS_SHIFT         18
> +#define ARM_TBFLAG_NS_MASK          (1 << ARM_TBFLAG_NS_SHIFT)
>  
>  /* Bit usage when in AArch64 state */
>  #define ARM_TBFLAG_AA64_EL_SHIFT    0
> @@ -1305,6 +1307,8 @@ static inline int cpu_mmu_index (CPUARMState *env)
>      (((F) & ARM_TBFLAG_AA64_EL_MASK) >> ARM_TBFLAG_AA64_EL_SHIFT)
>  #define ARM_TBFLAG_AA64_FPEN(F) \
>      (((F) & ARM_TBFLAG_AA64_FPEN_MASK) >> ARM_TBFLAG_AA64_FPEN_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)
> @@ -1318,6 +1322,9 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
>          if (fpen == 3 || (fpen == 1 && arm_current_pl(env) != 0)) {
>              *flags |= ARM_TBFLAG_AA64_FPEN_MASK;
>          }
> +        if (!arm_is_secure(env)) {
> +            *flags |= ARM_TBFLAG_NS_MASK;
> +        }
>      } else {
>          int privmode;
>          *pc = env->regs[15];
> @@ -1334,6 +1341,9 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
>          if (privmode) {
>              *flags |= ARM_TBFLAG_PRIV_MASK;
>          }
> +        if (!arm_is_secure(env)) {
> +            *flags |= ARM_TBFLAG_NS_MASK;
> +        }
>          if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
>              || arm_el_is_aa64(env, 1)) {
>              *flags |= ARM_TBFLAG_VFPEN_MASK;
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index 8cb326f..16b706c 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -10878,6 +10878,7 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
>      dc->condexec_cond = 0;
>  #if !defined(CONFIG_USER_ONLY)
>      dc->user = (ARM_TBFLAG_AA64_EL(tb->flags) == 0);
> +    dc->ns = ARM_TBFLAG_NS(tb->flags);
>  #endif
>      dc->cpacr_fpen = ARM_TBFLAG_AA64_FPEN(tb->flags);
>      dc->vec_len = 0;
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index cf4e767..bf17952 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -53,8 +53,10 @@ static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
>  
>  #if defined(CONFIG_USER_ONLY)
>  #define IS_USER(s) 1
> +#define IS_NS(s) 1
>  #else
>  #define IS_USER(s) (s->user)
> +#define IS_NS(s) (s->ns)
>  #endif
>  
>  TCGv_ptr cpu_env;
> @@ -10904,6 +10906,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
>      dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
>  #if !defined(CONFIG_USER_ONLY)
>      dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
> +    dc->ns = ARM_TBFLAG_NS(tb->flags);
>  #endif
>      dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags);
>      dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
> diff --git a/target-arm/translate.h b/target-arm/translate.h
> index 31a0104..6e8620a 100644
> --- a/target-arm/translate.h
> +++ b/target-arm/translate.h
> @@ -19,6 +19,7 @@ typedef struct DisasContext {
>      int bswap_code;
>  #if !defined(CONFIG_USER_ONLY)
>      int user;
> +    int ns;
>  #endif
>      bool cpacr_fpen; /* FP enabled via CPACR.FPEN */
>      bool vfp_enabled; /* FP enabled via FPSCR.EN */
> -- 
> 1.8.3.2
> 

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

* Re: [Qemu-devel] [PATCH v3 07/32] target-arm: add non-secure Translation Block flag
  2014-06-17  9:15   ` Edgar E. Iglesias
@ 2014-06-17 10:07     ` Sergey Fedorov
  2014-06-19  5:30       ` Edgar E. Iglesias
  0 siblings, 1 reply; 78+ messages in thread
From: Sergey Fedorov @ 2014-06-17 10:07 UTC (permalink / raw)
  To: Edgar E. Iglesias, Fabian Aggeler
  Cc: peter.maydell, peter.crosthwaite, qemu-devel, christoffer.dall,
	greg.bellows

On 17.06.2014 13:15, Edgar E. Iglesias wrote:
> Hi, I think the patch looks OK but I'm unsure if it brings any benefits
> unless we add separate TLBs for S and NS.
>
> I noticed that TTBR0 gets banked in the series, but are changes to
> SCR.NS flushing the TLBs? I might have missed that from the patches.
> You'll need it unless we add separate S/NS TLBs.
>
> Considering that changes to SCR.NS will flush the TLBs, the
> use of a per TB ns flag is limited, unless I am missing something...

Hi Edgar,

This seems to be used in patch 19/32.

// Sergey

>
> Cheers,
> Edgar

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

* Re: [Qemu-devel] [PATCH v3 07/32] target-arm: add non-secure Translation Block flag
  2014-06-17 10:07     ` Sergey Fedorov
@ 2014-06-19  5:30       ` Edgar E. Iglesias
  0 siblings, 0 replies; 78+ messages in thread
From: Edgar E. Iglesias @ 2014-06-19  5:30 UTC (permalink / raw)
  To: Sergey Fedorov
  Cc: peter.maydell, peter.crosthwaite, Fabian Aggeler, qemu-devel,
	greg.bellows, christoffer.dall

On Tue, Jun 17, 2014 at 02:07:11PM +0400, Sergey Fedorov wrote:
> On 17.06.2014 13:15, Edgar E. Iglesias wrote:
> > Hi, I think the patch looks OK but I'm unsure if it brings any benefits
> > unless we add separate TLBs for S and NS.
> >
> > I noticed that TTBR0 gets banked in the series, but are changes to
> > SCR.NS flushing the TLBs? I might have missed that from the patches.
> > You'll need it unless we add separate S/NS TLBs.
> >
> > Considering that changes to SCR.NS will flush the TLBs, the
> > use of a per TB ns flag is limited, unless I am missing something...
> 
> Hi Edgar,
> 
> This seems to be used in patch 19/32.

Yes, I actually meant limited use as in having the NS flag in translation
time brings limited performance win or none.

But looking more carefuly, the way we handle cp regs requires the ns bit
at translation time to support direct loads of cpregs (without calling
out to tcg helpers). That is probably enough to motivate the tb flag.

Cheers,
Edgar

> 
> // Sergey
> 
> >
> > Cheers,
> > Edgar
> 

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

* Re: [Qemu-devel] [PATCH v3 28/32] target-arm: make DFSR banked
  2014-06-17  6:12     ` Edgar E. Iglesias
@ 2014-06-23 16:53       ` Greg Bellows
  2014-06-24 11:05       ` Aggeler  Fabian
  1 sibling, 0 replies; 78+ messages in thread
From: Greg Bellows @ 2014-06-23 16:53 UTC (permalink / raw)
  To: Edgar E. Iglesias
  Cc: Peter Maydell, Peter Crosthwaite, Fabian Aggeler,
	QEMU Developers, Sergey Fedorov, Christoffer Dall

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

I agree, if we are going to allow for EL-based array indexing then the
indices should correspond to the actual EL for clarity.

I am fine with the above compromise.


On 17 June 2014 01:12, Edgar E. Iglesias <edgar.iglesias@gmail.com> wrote:

> On Fri, Jun 13, 2014 at 05:06:15PM -0500, Greg Bellows wrote:
> > I just wanted to point out that the change from array-notation to
> hard-code
> > numbers in the names undoes Edgar's EL2/EL3 changes.  I prefer this way
> > over the array notation.
>
> Hi,
>
> This was discussed briefly here
> http://lists.gnu.org/archive/html/qemu-devel/2014-05/msg03561.html
>
> IMO, for some regs the array version doesn't make sense but for regs
> that need to be indexed by EL it does. Just look at what this patch
> results in for aarch64_cpu_do_interrupt(). AArch64 has a simpler/cleaner
> architecture in this respect, IMO we should keep the
> AArch64 simple and clean and take the banking pain in the AArch32 port.
>
>
> >
> >
> > On 10 June 2014 18:55, Fabian Aggeler <aggelerf@ethz.ch> wrote:
> >
> > > 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>
> > > ---
> > >  target-arm/cpu.h        | 13 ++++++++++++-
> > >  target-arm/helper-a64.c | 17 ++++++++++++++---
> > >  target-arm/helper.c     | 15 ++++++++-------
> > >  3 files changed, 34 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > > index 54c51a4..71782cf 100644
> > > --- a/target-arm/cpu.h
> > > +++ b/target-arm/cpu.h
> > > @@ -266,7 +266,18 @@ typedef struct CPUARMState {
> > >                  uint32_t ifsr32_el2;
> > >              };
> > >          };
> > > -        uint64_t esr_el[4];
> > > +        union {
> > > +            struct {
> > > +                uint64_t dfsr_ns;
> > > +                uint64_t hsr;
> > > +                uint64_t dfsr_s;
> > > +            };
> > > +            struct {
> > > +                uint64_t esr_el1;
> > > +                uint64_t esr_el2;
> > > +                uint64_t esr_el3;
> > > +            };
> > > +        };
>
> I'd prefer:
>
> -        uint64_t esr_el[4];
> +        union {
> +            struct {
> +                uint64_t dummy
> +                uint64_t dfsr_ns;
> +                uint64_t hsr;
> +                uint64_t dfsr_s;
> +            };
> +            struct {
> +                uint64_t esr_el[4];
> +            };
> +        };
>
> And avoid the whole target_esr pointer thing in aarch64_cpu_do_interrupt().
>
> Cheers,
> Edgar
>
>
> > >          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-a64.c b/target-arm/helper-a64.c
> > > index d7522b6..dbbf012 100644
> > > --- a/target-arm/helper-a64.c
> > > +++ b/target-arm/helper-a64.c
> > > @@ -447,6 +447,18 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
> > >      target_ulong addr = env->cp15.vbar_el[new_el];
> > >      unsigned int new_mode = aarch64_pstate_mode(new_el, true);
> > >      int i;
> > > +    uint64_t *target_esr;
> > > +    switch (new_el) {
> > > +    case 3:
> > > +        target_esr = &env->cp15.esr_el3;
> > > +        break;
> > > +    case 2:
> > > +        target_esr = &env->cp15.esr_el2;
> > > +        break;
> > > +    case 1:
> > > +        target_esr = &env->cp15.esr_el1;
> > > +        break;
> > > +    }
> > >
> > >      if (arm_current_pl(env) < new_el) {
> > >          if (env->aarch64) {
> > > @@ -477,8 +489,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
> > >      case EXCP_SWI:
> > >      case EXCP_HVC:
> > >      case EXCP_SMC:
> > > -        env->cp15.esr_el[new_el] = env->exception.syndrome;
> > > -        break;
> > > +        *target_esr = env->exception.syndrome;
> > >      case EXCP_IRQ:
> > >      case EXCP_VIRQ:
> > >          addr += 0x80;
> > > @@ -498,7 +509,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
> > >      } else {
> > >          env->banked_spsr[0] = cpsr_read(env);
> > >          if (!env->thumb) {
> > > -            env->cp15.esr_el[new_el] |= 1 << 25;
> > > +            *target_esr |= 1 << 25;
> > >          }
> > >          env->elr_el[new_el] = env->regs[15];
> > >
> > > diff --git a/target-arm/helper.c b/target-arm/helper.c
> > > index f51498a..793985e 100644
> > > --- a/target-arm/helper.c
> > > +++ b/target-arm/helper.c
> > > @@ -1492,7 +1492,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,
> > > @@ -1501,7 +1502,7 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
> > >      { .name = "ESR_EL1", .state = ARM_CP_STATE_AA64,
> > >        .opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
> > >        .access = PL1_RW,
> > > -      .fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]),
> .resetvalue =
> > > 0, },
> > > +      .fieldoffset = offsetof(CPUARMState, cp15.esr_el1), .resetvalue
> =
> > > 0, },
> > >      { .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
> > >        .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
> > >        .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
> > > @@ -1565,7 +1566,7 @@ static void omap_cachemaint_write(CPUARMState
> *env,
> > > const ARMCPRegInfo *ri,
> > >  static const ARMCPRegInfo omap_cp_reginfo[] = {
> > >      { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY,
> > >        .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type =
> > > ARM_CP_OVERRIDE,
> > > -      .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]),
> > > +      .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el1),
> > >        .resetvalue = 0, },
> > >      { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
> > >        .access = PL1_RW, .type = ARM_CP_NOP },
> > > @@ -2187,7 +2188,7 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
> > >      { .name = "ESR_EL2", .state = ARM_CP_STATE_AA64,
> > >        .type = ARM_CP_NO_MIGRATE,
> > >        .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
> > > -      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState,
> > > cp15.esr_el[2]) },
> > > +      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState,
> > > cp15.esr_el2) },
> > >      { .name = "FAR_EL2", .state = ARM_CP_STATE_AA64,
> > >        .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
> > >        .access = PL2_RW, .fieldoffset = offsetof(CPUARMState,
> > > cp15.far_el[2]) },
> > > @@ -2299,7 +2300,7 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
> > >      { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64,
> > >        .type = ARM_CP_NO_MIGRATE,
> > >        .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 2, .opc2 = 0,
> > > -      .access = PL3_RW, .fieldoffset = offsetof(CPUARMState,
> > > cp15.esr_el[3]) },
> > > +      .access = PL3_RW, .fieldoffset = offsetof(CPUARMState,
> > > cp15.esr_el3) },
> > >      { .name = "FAR_EL3", .state = ARM_CP_STATE_AA64,
> > >        .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 0,
> > >        .access = PL3_RW, .fieldoffset = offsetof(CPUARMState,
> > > cp15.far_el[3]) },
> > > @@ -3847,11 +3848,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
> > >
> > >
>

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

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

* Re: [Qemu-devel] [PATCH v3 32/32] target-arm: make c13 cp regs banked (FCSEIDR, ...)
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 32/32] target-arm: make c13 cp regs banked (FCSEIDR, ...) Fabian Aggeler
@ 2014-06-23 21:40   ` Greg Bellows
  2014-06-24 11:08     ` Aggeler  Fabian
  0 siblings, 1 reply; 78+ messages in thread
From: Greg Bellows @ 2014-06-23 21:40 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall

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

On 10 June 2014 18:55, Fabian Aggeler <aggelerf@ethz.ch> wrote:

> 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>
> ---
>  target-arm/cpu.h    | 45 ++++++++++++++++++++++++++++++++++++++++-----
>  target-arm/helper.c | 27 +++++++++++++++++----------
>  2 files changed, 57 insertions(+), 15 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index c7d606e..13fa966 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -329,11 +329,46 @@ typedef struct CPUARMState {
>          };
>          uint64_t vbar_el2;
>          uint64_t mvbar; /* (monitor) vector base address register */
> -        uint32_t c13_fcse; /* FCSE PID.  */
> -        uint64_t contextidr_el1; /* Context ID.  */
> -        uint64_t tpidr_el0; /* User RW Thread register.  */
> -        uint64_t tpidrro_el0; /* User RO Thread register.  */
> -        uint64_t tpidr_el1; /* Privileged Thread register.  */
> +        struct { /* FCSE PID. */
> +            uint32_t c13_fcseidr_ns;
> +            uint32_t c13_fcseidr_s;
> +        };
> +        union { /* Context ID. */
> +            struct {
> +                uint64_t contextidr_ns;
> +                uint64_t contextidr_s;
> +            };
> +            struct {
> +                uint64_t contextidr_el1;
> +            };
> +        };
> +        union { /* User RW Thread register. */
> +            struct {
> +                uint64_t tpidrurw_ns;
> +                uint64_t tpidrurw_s;
> +            };
> +            struct {
> +                uint64_t tpidr_el0;
> +            };
> +        };
> +        union { /* User RO Thread register. */
> +            struct {
> +                uint64_t tpidruro_ns;
> +                uint64_t tpidruro_s;
> +            };
> +            struct {
> +                uint64_t tpidrro_el0;
> +            };
> +        };
> +        union { /* Privileged Thread register. */
> +            struct {
> +                uint64_t tpidrprw_ns;
> +                uint64_t tpidrprw_s;
> +            };
> +            struct {
> +                uint64_t tpidr_el1;
> +            };
> +        };
>          uint64_t c14_cntfrq; /* Counter Frequency register */
>          uint64_t c14_cntkctl; /* Timer Control register */
>          ARMGenericTimer c14_timer[NUM_GTIMERS];
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 2d085aa..aebcc62 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -396,12 +396,15 @@ static const ARMCPRegInfo cp_reginfo[] = {
>      { .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 =
> 0,
>        .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 },
>      { .name = "FCSEIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2
> = 0,
> -      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState,
> cp15.c13_fcse),
> +      .access = PL1_RW,
> +      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.c13_fcseidr_s),
> +                             offsetof(CPUARMState, cp15.c13_fcseidr_ns) },
>        .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
>      { .name = "CONTEXTIDR", .state = ARM_CP_STATE_BOTH,
>        .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
>        .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
>  };
> @@ -889,21 +892,25 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
>        .access = PL0_RW,
>        .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el0), .resetvalue =
> 0 },
>      { .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2
> = 2,
> -      .access = PL0_RW,
> -      .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidr_el0),
> -      .resetfn = arm_cp_reset_ignore },
> +      .access = PL0_RW, .resetfn = arm_cp_reset_ignore,
> +      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrurw_s),
> +                             offsetoflow32(CPUARMState, cp15.tpidrurw_ns)
> } },
>      { .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0,
>        .access = PL0_R|PL1_W,
>        .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el0), .resetvalue
> = 0 },
>      { .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2
> = 3,
> -      .access = PL0_R|PL1_W,
> -      .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidrro_el0),
> -      .resetfn = arm_cp_reset_ignore },
> -    { .name = "TPIDR_EL1", .state = ARM_CP_STATE_BOTH,
> +      .access = PL0_R|PL1_W, .resetfn = arm_cp_reset_ignore,
> +      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s),
> +                             offsetoflow32(CPUARMState, cp15.tpidruro_ns)
> } },
> +    { .name = "TPIDR_EL1", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .opc1 = 0, .opc2 = 4, .crn = 13, .crm = 0,
>        .access = PL1_RW,
>        .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el1), .resetvalue =
> 0 },
> +    { .name = "TPIDRPRW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2
> = 4,
> +      .access = PL1_RW, .resetfn = arm_cp_reset_ignore,
> +      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s),
> +                             offsetoflow32(CPUARMState, cp15.tpidruro_ns)
> } },
>

Just discovered that TPIDRPRW is mapped to the wrong storage (tpidruro).
 Should be mapped to tpidrprw.


>      REGINFO_SENTINEL
>  };
>
> @@ -4566,7 +4573,7 @@ static inline int get_phys_addr(CPUARMState *env,
> target_ulong address,
>
>      /* Fast Context Switch Extension.  */
>      if (address < 0x02000000)
> -        address += env->cp15.c13_fcse;
> +        address += A32_BANKED_CURRENT_REG_GET(env, c13_fcseidr);
>
>      if ((sctlr & SCTLR_M) == 0) {
>          /* MMU/MPU disabled.  */
> --
> 1.8.3.2
>
>

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

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

* Re: [Qemu-devel] [PATCH v3 28/32] target-arm: make DFSR banked
  2014-06-17  6:12     ` Edgar E. Iglesias
  2014-06-23 16:53       ` Greg Bellows
@ 2014-06-24 11:05       ` Aggeler  Fabian
  1 sibling, 0 replies; 78+ messages in thread
From: Aggeler  Fabian @ 2014-06-24 11:05 UTC (permalink / raw)
  To: Edgar E. Iglesias
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers, Greg Bellows,
	Sergey Fedorov, Christoffer Dall


On 17 Jun 2014, at 08:12, Edgar E. Iglesias <edgar.iglesias@gmail.com> wrote:

> On Fri, Jun 13, 2014 at 05:06:15PM -0500, Greg Bellows wrote:
>> I just wanted to point out that the change from array-notation to hard-code
>> numbers in the names undoes Edgar's EL2/EL3 changes.  I prefer this way
>> over the array notation.
> 
> Hi,
> 
> This was discussed briefly here
> http://lists.gnu.org/archive/html/qemu-devel/2014-05/msg03561.html
> 
> IMO, for some regs the array version doesn't make sense but for regs
> that need to be indexed by EL it does. Just look at what this patch
> results in for aarch64_cpu_do_interrupt(). AArch64 has a simpler/cleaner
> architecture in this respect, IMO we should keep the
> AArch64 simple and clean and take the banking pain in the AArch32 port.
> 

You’re right. I didn’t like the outcome of this change either. 

Since we can combine the advantages of both concepts in this compromise I
also vote for changing it to your proposed solution.

>> 
>> 
>> On 10 June 2014 18:55, Fabian Aggeler <aggelerf@ethz.ch> wrote:
>> 
>>> 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>
>>> ---
>>> target-arm/cpu.h        | 13 ++++++++++++-
>>> target-arm/helper-a64.c | 17 ++++++++++++++---
>>> target-arm/helper.c     | 15 ++++++++-------
>>> 3 files changed, 34 insertions(+), 11 deletions(-)
>>> 
>>> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
>>> index 54c51a4..71782cf 100644
>>> --- a/target-arm/cpu.h
>>> +++ b/target-arm/cpu.h
>>> @@ -266,7 +266,18 @@ typedef struct CPUARMState {
>>>                 uint32_t ifsr32_el2;
>>>             };
>>>         };
>>> -        uint64_t esr_el[4];
>>> +        union {
>>> +            struct {
>>> +                uint64_t dfsr_ns;
>>> +                uint64_t hsr;
>>> +                uint64_t dfsr_s;
>>> +            };
>>> +            struct {
>>> +                uint64_t esr_el1;
>>> +                uint64_t esr_el2;
>>> +                uint64_t esr_el3;
>>> +            };
>>> +        };
> 
> I'd prefer:
> 
> -        uint64_t esr_el[4];
> +        union {
> +            struct {
> +                uint64_t dummy 
> +                uint64_t dfsr_ns;
> +                uint64_t hsr;
> +                uint64_t dfsr_s;
> +            };
> +            struct {
> +                uint64_t esr_el[4];
> +            };
> +        };
> 
> And avoid the whole target_esr pointer thing in aarch64_cpu_do_interrupt().
> 
> Cheers,
> Edgar
> 
> 
>>>         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-a64.c b/target-arm/helper-a64.c
>>> index d7522b6..dbbf012 100644
>>> --- a/target-arm/helper-a64.c
>>> +++ b/target-arm/helper-a64.c
>>> @@ -447,6 +447,18 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
>>>     target_ulong addr = env->cp15.vbar_el[new_el];
>>>     unsigned int new_mode = aarch64_pstate_mode(new_el, true);
>>>     int i;
>>> +    uint64_t *target_esr;
>>> +    switch (new_el) {
>>> +    case 3:
>>> +        target_esr = &env->cp15.esr_el3;
>>> +        break;
>>> +    case 2:
>>> +        target_esr = &env->cp15.esr_el2;
>>> +        break;
>>> +    case 1:
>>> +        target_esr = &env->cp15.esr_el1;
>>> +        break;
>>> +    }
>>> 
>>>     if (arm_current_pl(env) < new_el) {
>>>         if (env->aarch64) {
>>> @@ -477,8 +489,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
>>>     case EXCP_SWI:
>>>     case EXCP_HVC:
>>>     case EXCP_SMC:
>>> -        env->cp15.esr_el[new_el] = env->exception.syndrome;
>>> -        break;
>>> +        *target_esr = env->exception.syndrome;
>>>     case EXCP_IRQ:
>>>     case EXCP_VIRQ:
>>>         addr += 0x80;
>>> @@ -498,7 +509,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
>>>     } else {
>>>         env->banked_spsr[0] = cpsr_read(env);
>>>         if (!env->thumb) {
>>> -            env->cp15.esr_el[new_el] |= 1 << 25;
>>> +            *target_esr |= 1 << 25;
>>>         }
>>>         env->elr_el[new_el] = env->regs[15];
>>> 
>>> diff --git a/target-arm/helper.c b/target-arm/helper.c
>>> index f51498a..793985e 100644
>>> --- a/target-arm/helper.c
>>> +++ b/target-arm/helper.c
>>> @@ -1492,7 +1492,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,
>>> @@ -1501,7 +1502,7 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
>>>     { .name = "ESR_EL1", .state = ARM_CP_STATE_AA64,
>>>       .opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
>>>       .access = PL1_RW,
>>> -      .fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue =
>>> 0, },
>>> +      .fieldoffset = offsetof(CPUARMState, cp15.esr_el1), .resetvalue =
>>> 0, },
>>>     { .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
>>>       .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
>>>       .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
>>> @@ -1565,7 +1566,7 @@ static void omap_cachemaint_write(CPUARMState *env,
>>> const ARMCPRegInfo *ri,
>>> static const ARMCPRegInfo omap_cp_reginfo[] = {
>>>     { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY,
>>>       .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type =
>>> ARM_CP_OVERRIDE,
>>> -      .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]),
>>> +      .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el1),
>>>       .resetvalue = 0, },
>>>     { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
>>>       .access = PL1_RW, .type = ARM_CP_NOP },
>>> @@ -2187,7 +2188,7 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = {
>>>     { .name = "ESR_EL2", .state = ARM_CP_STATE_AA64,
>>>       .type = ARM_CP_NO_MIGRATE,
>>>       .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
>>> -      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState,
>>> cp15.esr_el[2]) },
>>> +      .access = PL2_RW, .fieldoffset = offsetof(CPUARMState,
>>> cp15.esr_el2) },
>>>     { .name = "FAR_EL2", .state = ARM_CP_STATE_AA64,
>>>       .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
>>>       .access = PL2_RW, .fieldoffset = offsetof(CPUARMState,
>>> cp15.far_el[2]) },
>>> @@ -2299,7 +2300,7 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
>>>     { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64,
>>>       .type = ARM_CP_NO_MIGRATE,
>>>       .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 2, .opc2 = 0,
>>> -      .access = PL3_RW, .fieldoffset = offsetof(CPUARMState,
>>> cp15.esr_el[3]) },
>>> +      .access = PL3_RW, .fieldoffset = offsetof(CPUARMState,
>>> cp15.esr_el3) },
>>>     { .name = "FAR_EL3", .state = ARM_CP_STATE_AA64,
>>>       .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 0,
>>>       .access = PL3_RW, .fieldoffset = offsetof(CPUARMState,
>>> cp15.far_el[3]) },
>>> @@ -3847,11 +3848,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	[flat|nested] 78+ messages in thread

* Re: [Qemu-devel] [PATCH v3 32/32] target-arm: make c13 cp regs banked (FCSEIDR, ...)
  2014-06-23 21:40   ` Greg Bellows
@ 2014-06-24 11:08     ` Aggeler  Fabian
  0 siblings, 0 replies; 78+ messages in thread
From: Aggeler  Fabian @ 2014-06-24 11:08 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall


On 23 Jun 2014, at 23:40, Greg Bellows <greg.bellows@linaro.org<mailto:greg.bellows@linaro.org>> wrote:




On 10 June 2014 18:55, Fabian Aggeler <aggelerf@ethz.ch<mailto:aggelerf@ethz.ch>> wrote:
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<mailto:aggelerf@ethz.ch>>
---
 target-arm/cpu.h    | 45 ++++++++++++++++++++++++++++++++++++++++-----
 target-arm/helper.c | 27 +++++++++++++++++----------
 2 files changed, 57 insertions(+), 15 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c7d606e..13fa966 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -329,11 +329,46 @@ typedef struct CPUARMState {
         };
         uint64_t vbar_el2;
         uint64_t mvbar; /* (monitor) vector base address register */
-        uint32_t c13_fcse; /* FCSE PID.  */
-        uint64_t contextidr_el1; /* Context ID.  */
-        uint64_t tpidr_el0; /* User RW Thread register.  */
-        uint64_t tpidrro_el0; /* User RO Thread register.  */
-        uint64_t tpidr_el1; /* Privileged Thread register.  */
+        struct { /* FCSE PID. */
+            uint32_t c13_fcseidr_ns;
+            uint32_t c13_fcseidr_s;
+        };
+        union { /* Context ID. */
+            struct {
+                uint64_t contextidr_ns;
+                uint64_t contextidr_s;
+            };
+            struct {
+                uint64_t contextidr_el1;
+            };
+        };
+        union { /* User RW Thread register. */
+            struct {
+                uint64_t tpidrurw_ns;
+                uint64_t tpidrurw_s;
+            };
+            struct {
+                uint64_t tpidr_el0;
+            };
+        };
+        union { /* User RO Thread register. */
+            struct {
+                uint64_t tpidruro_ns;
+                uint64_t tpidruro_s;
+            };
+            struct {
+                uint64_t tpidrro_el0;
+            };
+        };
+        union { /* Privileged Thread register. */
+            struct {
+                uint64_t tpidrprw_ns;
+                uint64_t tpidrprw_s;
+            };
+            struct {
+                uint64_t tpidr_el1;
+            };
+        };
         uint64_t c14_cntfrq; /* Counter Frequency register */
         uint64_t c14_cntkctl; /* Timer Control register */
         ARMGenericTimer c14_timer[NUM_GTIMERS];
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 2d085aa..aebcc62 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -396,12 +396,15 @@ static const ARMCPRegInfo cp_reginfo[] = {
     { .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
       .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 },
     { .name = "FCSEIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse),
+      .access = PL1_RW,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.c13_fcseidr_s),
+                             offsetof(CPUARMState, cp15.c13_fcseidr_ns) },
       .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
     { .name = "CONTEXTIDR", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
       .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
 };
@@ -889,21 +892,25 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
       .access = PL0_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el0), .resetvalue = 0 },
     { .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2,
-      .access = PL0_RW,
-      .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidr_el0),
-      .resetfn = arm_cp_reset_ignore },
+      .access = PL0_RW, .resetfn = arm_cp_reset_ignore,
+      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrurw_s),
+                             offsetoflow32(CPUARMState, cp15.tpidrurw_ns) } },
     { .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0,
       .access = PL0_R|PL1_W,
       .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el0), .resetvalue = 0 },
     { .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3,
-      .access = PL0_R|PL1_W,
-      .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidrro_el0),
-      .resetfn = arm_cp_reset_ignore },
-    { .name = "TPIDR_EL1", .state = ARM_CP_STATE_BOTH,
+      .access = PL0_R|PL1_W, .resetfn = arm_cp_reset_ignore,
+      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s),
+                             offsetoflow32(CPUARMState, cp15.tpidruro_ns) } },
+    { .name = "TPIDR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 0, .opc2 = 4, .crn = 13, .crm = 0,
       .access = PL1_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el1), .resetvalue = 0 },
+    { .name = "TPIDRPRW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 4,
+      .access = PL1_RW, .resetfn = arm_cp_reset_ignore,
+      .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s),
+                             offsetoflow32(CPUARMState, cp15.tpidruro_ns) } },

Just discovered that TPIDRPRW is mapped to the wrong storage (tpidruro).  Should be mapped to tpidrprw.

Indeed, should be tpidrprw_s/ns. Good catch!


     REGINFO_SENTINEL
 };

@@ -4566,7 +4573,7 @@ static inline int get_phys_addr(CPUARMState *env, target_ulong address,

     /* Fast Context Switch Extension.  */
     if (address < 0x02000000)
-        address += env->cp15.c13_fcse;
+        address += A32_BANKED_CURRENT_REG_GET(env, c13_fcseidr);

     if ((sctlr & SCTLR_M) == 0) {
         /* MMU/MPU disabled.  */
--
1.8.3.2

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

* Re: [Qemu-devel] [PATCH v3 05/32] target-arm: reject switching to monitor mode
  2014-06-12 21:55   ` Greg Bellows
@ 2014-06-24 12:19     ` Aggeler  Fabian
  2014-06-24 13:43       ` Greg Bellows
  0 siblings, 1 reply; 78+ messages in thread
From: Aggeler  Fabian @ 2014-06-24 12:19 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall

Hm…yes, this case is missing, but it is only missing for ARMv7 as this bit is RES0 in ARMv8. Even in ARMv7 it is IMPDEF whether
this bit is supported. And since ARMv7 mentions, that this bit is deprecated from the introduction of Virtualization Extensions
I did not care to add this special case.

On 12 Jun 2014, at 23:55, Greg Bellows <greg.bellows@linaro.org<mailto:greg.bellows@linaro.org>> wrote:

Missing case where it is UNPREDICTABLE to enter FIQ mode from non-secure state if NSACR.RFR is 1.


On 10 June 2014 18:54, Fabian Aggeler <aggelerf@ethz.ch<mailto:aggelerf@ethz.ch>> wrote:
From: Sergey Fedorov <s.fedorov@samsung.com<mailto:s.fedorov@samsung.com>>

...from non-secure state.

Signed-off-by: Sergey Fedorov <s.fedorov@samsung.com<mailto:s.fedorov@samsung.com>>
Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch<mailto:aggelerf@ethz.ch>>
---
 target-arm/helper.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index d8d6637..ace8d8b 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3049,6 +3049,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] 78+ messages in thread

* Re: [Qemu-devel] [PATCH v3 05/32] target-arm: reject switching to monitor mode
  2014-06-24 12:19     ` Aggeler  Fabian
@ 2014-06-24 13:43       ` Greg Bellows
  0 siblings, 0 replies; 78+ messages in thread
From: Greg Bellows @ 2014-06-24 13:43 UTC (permalink / raw)
  To: Aggeler Fabian
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall

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

Thanks.

I wont bother making a change to your patchset for this and will revisit
after things are upstream if a change is needed.

Greg


On 24 June 2014 07:19, Aggeler Fabian <aggelerf@student.ethz.ch> wrote:

> Hm…yes, this case is missing, but it is only missing for ARMv7 as this bit
> is RES0 in ARMv8. Even in ARMv7 it is IMPDEF whether
> this bit is supported. And since ARMv7 mentions, that this bit is
> deprecated from the introduction of Virtualization Extensions
> I did not care to add this special case.
>
> On 12 Jun 2014, at 23:55, Greg Bellows <greg.bellows@linaro.org<mailto:
> greg.bellows@linaro.org>> wrote:
>
> Missing case where it is UNPREDICTABLE to enter FIQ mode from non-secure
> state if NSACR.RFR is 1.
>
>
> On 10 June 2014 18:54, Fabian Aggeler <aggelerf@ethz.ch<mailto:
> aggelerf@ethz.ch>> wrote:
> From: Sergey Fedorov <s.fedorov@samsung.com<mailto:s.fedorov@samsung.com>>
>
> ...from non-secure state.
>
> Signed-off-by: Sergey Fedorov <s.fedorov@samsung.com<mailto:
> s.fedorov@samsung.com>>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch<mailto:aggelerf@ethz.ch>>
> ---
>  target-arm/helper.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index d8d6637..ace8d8b 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -3049,6 +3049,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
>
>
>
>

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

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

* Re: [Qemu-devel] [PATCH v3 15/32] target-arm: add NSACR register
  2014-06-17  7:41     ` Aggeler  Fabian
@ 2014-06-24 15:37       ` Greg Bellows
  0 siblings, 0 replies; 78+ messages in thread
From: Greg Bellows @ 2014-06-24 15:37 UTC (permalink / raw)
  To: Aggeler Fabian
  Cc: Peter Maydell, Peter Crosthwaite, QEMU Developers,
	Sergey Fedorov, Edgar E. Iglesias, Christoffer Dall

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

On 17 June 2014 02:41, Aggeler Fabian <aggelerf@student.ethz.ch> wrote:

>
> On 13 Jun 2014, at 20:27, Greg Bellows <greg.bellows@linaro.org<mailto:
> greg.bellows@linaro.org>> wrote:
>
>
>
>
> On 10 June 2014 18:54, Fabian Aggeler <aggelerf@ethz.ch<mailto:
> aggelerf@ethz.ch>> wrote:
> Implements NSACR register with corresponding read/write functions
> for ARMv7 and ARMv8.
>
> Signed-off-by: Sergey Fedorov <s.fedorov@samsung.com<mailto:
> s.fedorov@samsung.com>>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch<mailto:aggelerf@ethz.ch>>
> ---
>  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 52e679f..bc9edaa 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -182,6 +182,7 @@ typedef struct CPUARMState {
>          uint64_t c1_coproc; /* Coprocessor access register.  */
>          uint32_t c1_xscaleauxcr; /* XScale auxiliary control register.  */
>          uint32_t c1_scr; /* secure config 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.  */
> @@ -593,6 +594,11 @@ static inline void xpsr_write(CPUARMState *env,
> uint32_t val, uint32_t mask)
>  #define SCR_RES1_MASK (3U << 4)
>  #define SCR_MASK      (0x3fff & ~SCR_RES1_MASK)
>
> +#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 f6ff4aa..9671f9f 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -489,7 +489,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);
>              }
> @@ -501,6 +513,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;
> @@ -2184,6 +2197,55 @@ static void scr_write(CPUARMState *env, const
> ARMCPRegInfo *ri, uint64_t value)
>      raw_write(env, ri, value);
>  }
>
> +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_pl(env) != 3)) {
> +            ret = 0x0000C00;
> +        }
>
> It appears we are missing a case where 0xc00 is returned because we check
> for the non-existence of EL3.
>
> Right, this case is missing.
>
>
Not sure what I was thinking at the time but the case I thought was missing
is covered.


>
> +    }
> +    return ret;
> +}
> +
>
> The ARMv8 spec suggests that if EL3 is aarch64 that a read or write of
> this register occurs from secure EL1 when aarch32 it is trapped as an
> exception to EL3.  Is this omitted?
>
> It seems I skipped that line when reading the ARMv8 spec. Should be added
> of course.
>
>
I will add this as a separate commit because it is only a v8 concern.


>
>  static const ARMCPRegInfo v8_el3_cp_reginfo[] = {
>      { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
>        .type = ARM_CP_NO_MIGRATE,
> @@ -2217,6 +2279,10 @@ static const ARMCPRegInfo security_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, },
> +    { .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
>
>
>
>

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

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

* Re: [Qemu-devel] [PATCH v3 07/32] target-arm: add non-secure Translation Block flag
  2014-06-10 23:54 ` [Qemu-devel] [PATCH v3 07/32] target-arm: add non-secure Translation Block flag Fabian Aggeler
  2014-06-17  9:15   ` Edgar E. Iglesias
@ 2014-06-25  4:15   ` Edgar E. Iglesias
  1 sibling, 0 replies; 78+ messages in thread
From: Edgar E. Iglesias @ 2014-06-25  4:15 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: peter.maydell, peter.crosthwaite, qemu-devel, greg.bellows,
	serge.fdrv, christoffer.dall

On Wed, Jun 11, 2014 at 01:54:49AM +0200, Fabian Aggeler wrote:
> From: Sergey Fedorov <s.fedorov@samsung.com>
> 
> This patch is based on idea found in patch at
> git://github.com/jowinter/qemu-trustzone.git
> f3d955c6c0ed8c46bc0eb10b634201032a651dd2 by
> Johannes Winter <johannes.winter@iaik.tugraz.at>.
> 
> This flag prevents QEMU from executing TCG code generated for other CPU
> security state. It also allows to generate different TCG code depending on
> CPU secure state.
>


Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>

 
> Signed-off-by: Sergey Fedorov <s.fedorov@samsung.com>
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> ---
>  target-arm/cpu.h           | 10 ++++++++++
>  target-arm/translate-a64.c |  1 +
>  target-arm/translate.c     |  3 +++
>  target-arm/translate.h     |  1 +
>  4 files changed, 15 insertions(+)
> 
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 14007a9..661bfbe 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -1275,6 +1275,8 @@ static inline int cpu_mmu_index (CPUARMState *env)
>  #define ARM_TBFLAG_BSWAP_CODE_MASK  (1 << ARM_TBFLAG_BSWAP_CODE_SHIFT)
>  #define ARM_TBFLAG_CPACR_FPEN_SHIFT 17
>  #define ARM_TBFLAG_CPACR_FPEN_MASK  (1 << ARM_TBFLAG_CPACR_FPEN_SHIFT)
> +#define ARM_TBFLAG_NS_SHIFT         18
> +#define ARM_TBFLAG_NS_MASK          (1 << ARM_TBFLAG_NS_SHIFT)
>  
>  /* Bit usage when in AArch64 state */
>  #define ARM_TBFLAG_AA64_EL_SHIFT    0
> @@ -1305,6 +1307,8 @@ static inline int cpu_mmu_index (CPUARMState *env)
>      (((F) & ARM_TBFLAG_AA64_EL_MASK) >> ARM_TBFLAG_AA64_EL_SHIFT)
>  #define ARM_TBFLAG_AA64_FPEN(F) \
>      (((F) & ARM_TBFLAG_AA64_FPEN_MASK) >> ARM_TBFLAG_AA64_FPEN_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)
> @@ -1318,6 +1322,9 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
>          if (fpen == 3 || (fpen == 1 && arm_current_pl(env) != 0)) {
>              *flags |= ARM_TBFLAG_AA64_FPEN_MASK;
>          }
> +        if (!arm_is_secure(env)) {
> +            *flags |= ARM_TBFLAG_NS_MASK;
> +        }
>      } else {
>          int privmode;
>          *pc = env->regs[15];
> @@ -1334,6 +1341,9 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
>          if (privmode) {
>              *flags |= ARM_TBFLAG_PRIV_MASK;
>          }
> +        if (!arm_is_secure(env)) {
> +            *flags |= ARM_TBFLAG_NS_MASK;
> +        }
>          if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
>              || arm_el_is_aa64(env, 1)) {
>              *flags |= ARM_TBFLAG_VFPEN_MASK;
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index 8cb326f..16b706c 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -10878,6 +10878,7 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
>      dc->condexec_cond = 0;
>  #if !defined(CONFIG_USER_ONLY)
>      dc->user = (ARM_TBFLAG_AA64_EL(tb->flags) == 0);
> +    dc->ns = ARM_TBFLAG_NS(tb->flags);
>  #endif
>      dc->cpacr_fpen = ARM_TBFLAG_AA64_FPEN(tb->flags);
>      dc->vec_len = 0;
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index cf4e767..bf17952 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -53,8 +53,10 @@ static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
>  
>  #if defined(CONFIG_USER_ONLY)
>  #define IS_USER(s) 1
> +#define IS_NS(s) 1
>  #else
>  #define IS_USER(s) (s->user)
> +#define IS_NS(s) (s->ns)
>  #endif
>  
>  TCGv_ptr cpu_env;
> @@ -10904,6 +10906,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
>      dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
>  #if !defined(CONFIG_USER_ONLY)
>      dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
> +    dc->ns = ARM_TBFLAG_NS(tb->flags);
>  #endif
>      dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags);
>      dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
> diff --git a/target-arm/translate.h b/target-arm/translate.h
> index 31a0104..6e8620a 100644
> --- a/target-arm/translate.h
> +++ b/target-arm/translate.h
> @@ -19,6 +19,7 @@ typedef struct DisasContext {
>      int bswap_code;
>  #if !defined(CONFIG_USER_ONLY)
>      int user;
> +    int ns;
>  #endif
>      bool cpacr_fpen; /* FP enabled via CPACR.FPEN */
>      bool vfp_enabled; /* FP enabled via FPSCR.EN */
> -- 
> 1.8.3.2
> 

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

* Re: [Qemu-devel] [PATCH v3 19/32] target-arm: insert Aarch32 cpregs twice into hashtable
  2014-06-10 23:55 ` [Qemu-devel] [PATCH v3 19/32] target-arm: insert Aarch32 cpregs twice into hashtable Fabian Aggeler
  2014-06-12 19:49   ` Sergey Fedorov
@ 2014-06-25  5:20   ` Edgar E. Iglesias
  2014-06-25 13:50     ` Greg Bellows
  1 sibling, 1 reply; 78+ messages in thread
From: Edgar E. Iglesias @ 2014-06-25  5:20 UTC (permalink / raw)
  To: Fabian Aggeler
  Cc: peter.maydell, peter.crosthwaite, qemu-devel, greg.bellows,
	serge.fdrv, christoffer.dall

On Wed, Jun 11, 2014 at 01:55:01AM +0200, Fabian Aggeler wrote:
> Prepare for cp register banking by inserting every cp register twice,
> once for secure world and once for non-secure world.

Hi,

A question regarding the migration issue that Sergey raised.
Do we need to do anything about it or can we live with multiple
migrations of the same reg? I guess we could somehow encode
an array of "migratable" flags or maybe auto eliminate the dups
while migrating or registering the regs.

Except for the migration question, I think your approach here
looks good.

Thanks,
Edgar


> 
> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> ---
>  target-arm/cpu.h       | 14 +++++++++++---
>  target-arm/helper.c    | 20 ++++++++++++++++----
>  target-arm/translate.c | 19 +++++++++++++------
>  3 files changed, 40 insertions(+), 13 deletions(-)
> 
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 0b8042c..d4eab39 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -831,6 +831,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;
> @@ -848,9 +849,16 @@ void armv7m_nvic_complete_irq(void *opaque, int irq);
>  #define CP_REG_AA64_SHIFT 28
>  #define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
>  
> -#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2)   \
> -    (((cp) << 16) | ((is64) << 15) | ((crn) << 11) |    \
> -     ((crm) << 7) | ((opc1) << 3) | (opc2))
> +/* To enable banking of coprocessor registers depending on ns-bit we
> + * add a bit to distinguish between secure and non-secure cpregs in the
> + * hashtable.
> + */
> +#define CP_REG_NS_SHIFT 27
> +#define CP_REG_NS_MASK(nsbit) (nsbit << CP_REG_NS_SHIFT)
> +
> +#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2, ns)   \
> +    (CP_REG_NS_MASK(ns) | ((cp) << 16) | ((is64) << 15) |   \
> +     ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
>  
>  #define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
>      (CP_REG_AA64_MASK |                                 \
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index f9b2374..610245d 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -2883,7 +2883,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.
> @@ -2917,7 +2917,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;
> @@ -3066,8 +3066,20 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
>                      if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
>                          continue;
>                      }
> -                    add_cpreg_to_hashtable(cpu, r, opaque, state,
> -                                           crm, opc1, opc2);
> +                    if (state == ARM_CP_STATE_AA32) {
> +                        /* Under Aarch32 CP registers can be common
> +                         * (same for secure and non-secure world) or banked.
> +                         */
> +                        add_cpreg_to_hashtable(cpu, r, opaque, state,
> +                                crm, opc1, opc2, !SCR_NS);
> +                        add_cpreg_to_hashtable(cpu, r, opaque, state,
> +                                crm, opc1, opc2, SCR_NS);
> +                    } else {
> +                        /* Aarch64 registers get mapped to non-secure instance
> +                         * of Aarch32 */
> +                        add_cpreg_to_hashtable(cpu, r, opaque, state,
> +                                crm, opc1, opc2, SCR_NS);
> +                    }
>                  }
>              }
>          }
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index f657389..30d9592 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -6968,7 +6968,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
>  
>  static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
>  {
> -    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
> +    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2, ns;
>      const ARMCPRegInfo *ri;
>  
>      cpnum = (insn >> 8) & 0xf;
> @@ -7012,8 +7012,11 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
>      isread = (insn >> 20) & 1;
>      rt = (insn >> 12) & 0xf;
>  
> +    /* Monitor mode is always treated as secure but cp register reads/writes
> +     * can access secure and non-secure instances using SCR.NS bit*/
> +    ns = IS_NS(s) ? 1 : !USE_SECURE_REG(env);
>      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, ns));
>      if (ri) {
>          /* Check access permissions */
>          if (!cp_access_ok(s->current_pl, ri, isread)) {
> @@ -7200,12 +7203,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,
> +                      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,
> +                      ns ? "non-secure" : "secure");
>      }
>  
>      return 1;
> -- 
> 1.8.3.2
> 

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

* Re: [Qemu-devel] [PATCH v3 19/32] target-arm: insert Aarch32 cpregs twice into hashtable
  2014-06-25  5:20   ` Edgar E. Iglesias
@ 2014-06-25 13:50     ` Greg Bellows
  2014-06-26  3:56       ` Edgar E. Iglesias
  0 siblings, 1 reply; 78+ messages in thread
From: Greg Bellows @ 2014-06-25 13:50 UTC (permalink / raw)
  To: Edgar E. Iglesias
  Cc: Peter Maydell, Peter Crosthwaite, Fabian Aggeler,
	QEMU Developers, Sergey Fedorov, Christoffer Dall

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

I am going to add a patch to the series to handle migration.


On 25 June 2014 00:20, Edgar E. Iglesias <edgar.iglesias@gmail.com> wrote:

> On Wed, Jun 11, 2014 at 01:55:01AM +0200, Fabian Aggeler wrote:
> > Prepare for cp register banking by inserting every cp register twice,
> > once for secure world and once for non-secure world.
>
> Hi,
>
> A question regarding the migration issue that Sergey raised.
> Do we need to do anything about it or can we live with multiple
> migrations of the same reg? I guess we could somehow encode
> an array of "migratable" flags or maybe auto eliminate the dups
> while migrating or registering the regs.
>
> Except for the migration question, I think your approach here
> looks good.
>
> Thanks,
> Edgar
>
>
> >
> > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> > ---
> >  target-arm/cpu.h       | 14 +++++++++++---
> >  target-arm/helper.c    | 20 ++++++++++++++++----
> >  target-arm/translate.c | 19 +++++++++++++------
> >  3 files changed, 40 insertions(+), 13 deletions(-)
> >
> > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > index 0b8042c..d4eab39 100644
> > --- a/target-arm/cpu.h
> > +++ b/target-arm/cpu.h
> > @@ -831,6 +831,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;
> > @@ -848,9 +849,16 @@ void armv7m_nvic_complete_irq(void *opaque, int
> irq);
> >  #define CP_REG_AA64_SHIFT 28
> >  #define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
> >
> > -#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2)   \
> > -    (((cp) << 16) | ((is64) << 15) | ((crn) << 11) |    \
> > -     ((crm) << 7) | ((opc1) << 3) | (opc2))
> > +/* To enable banking of coprocessor registers depending on ns-bit we
> > + * add a bit to distinguish between secure and non-secure cpregs in the
> > + * hashtable.
> > + */
> > +#define CP_REG_NS_SHIFT 27
> > +#define CP_REG_NS_MASK(nsbit) (nsbit << CP_REG_NS_SHIFT)
> > +
> > +#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2, ns)   \
> > +    (CP_REG_NS_MASK(ns) | ((cp) << 16) | ((is64) << 15) |   \
> > +     ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
> >
> >  #define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
> >      (CP_REG_AA64_MASK |                                 \
> > diff --git a/target-arm/helper.c b/target-arm/helper.c
> > index f9b2374..610245d 100644
> > --- a/target-arm/helper.c
> > +++ b/target-arm/helper.c
> > @@ -2883,7 +2883,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.
> > @@ -2917,7 +2917,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;
> > @@ -3066,8 +3066,20 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU
> *cpu,
> >                      if (r->state != state && r->state !=
> ARM_CP_STATE_BOTH) {
> >                          continue;
> >                      }
> > -                    add_cpreg_to_hashtable(cpu, r, opaque, state,
> > -                                           crm, opc1, opc2);
> > +                    if (state == ARM_CP_STATE_AA32) {
> > +                        /* Under Aarch32 CP registers can be common
> > +                         * (same for secure and non-secure world) or
> banked.
> > +                         */
> > +                        add_cpreg_to_hashtable(cpu, r, opaque, state,
> > +                                crm, opc1, opc2, !SCR_NS);
> > +                        add_cpreg_to_hashtable(cpu, r, opaque, state,
> > +                                crm, opc1, opc2, SCR_NS);
> > +                    } else {
> > +                        /* Aarch64 registers get mapped to non-secure
> instance
> > +                         * of Aarch32 */
> > +                        add_cpreg_to_hashtable(cpu, r, opaque, state,
> > +                                crm, opc1, opc2, SCR_NS);
> > +                    }
> >                  }
> >              }
> >          }
> > diff --git a/target-arm/translate.c b/target-arm/translate.c
> > index f657389..30d9592 100644
> > --- a/target-arm/translate.c
> > +++ b/target-arm/translate.c
> > @@ -6968,7 +6968,7 @@ static int disas_neon_data_insn(CPUARMState * env,
> DisasContext *s, uint32_t ins
> >
> >  static int disas_coproc_insn(CPUARMState * env, DisasContext *s,
> uint32_t insn)
> >  {
> > -    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
> > +    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2, ns;
> >      const ARMCPRegInfo *ri;
> >
> >      cpnum = (insn >> 8) & 0xf;
> > @@ -7012,8 +7012,11 @@ static int disas_coproc_insn(CPUARMState * env,
> DisasContext *s, uint32_t insn)
> >      isread = (insn >> 20) & 1;
> >      rt = (insn >> 12) & 0xf;
> >
> > +    /* Monitor mode is always treated as secure but cp register
> reads/writes
> > +     * can access secure and non-secure instances using SCR.NS bit*/
> > +    ns = IS_NS(s) ? 1 : !USE_SECURE_REG(env);
> >      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, ns));
> >      if (ri) {
> >          /* Check access permissions */
> >          if (!cp_access_ok(s->current_pl, ri, isread)) {
> > @@ -7200,12 +7203,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,
> > +                      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,
> > +                      ns ? "non-secure" : "secure");
> >      }
> >
> >      return 1;
> > --
> > 1.8.3.2
> >
>

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

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

* Re: [Qemu-devel] [PATCH v3 19/32] target-arm: insert Aarch32 cpregs twice into hashtable
  2014-06-25 13:50     ` Greg Bellows
@ 2014-06-26  3:56       ` Edgar E. Iglesias
  0 siblings, 0 replies; 78+ messages in thread
From: Edgar E. Iglesias @ 2014-06-26  3:56 UTC (permalink / raw)
  To: Greg Bellows
  Cc: Peter Maydell, Peter Crosthwaite, Fabian Aggeler,
	QEMU Developers, Sergey Fedorov, Christoffer Dall

On Wed, Jun 25, 2014 at 08:50:12AM -0500, Greg Bellows wrote:
> I am going to add a patch to the series to handle migration.

Great, thanks Greg.

Cheers

> 
> 
> On 25 June 2014 00:20, Edgar E. Iglesias <edgar.iglesias@gmail.com> wrote:
> 
> > On Wed, Jun 11, 2014 at 01:55:01AM +0200, Fabian Aggeler wrote:
> > > Prepare for cp register banking by inserting every cp register twice,
> > > once for secure world and once for non-secure world.
> >
> > Hi,
> >
> > A question regarding the migration issue that Sergey raised.
> > Do we need to do anything about it or can we live with multiple
> > migrations of the same reg? I guess we could somehow encode
> > an array of "migratable" flags or maybe auto eliminate the dups
> > while migrating or registering the regs.
> >
> > Except for the migration question, I think your approach here
> > looks good.
> >
> > Thanks,
> > Edgar
> >
> >
> > >
> > > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
> > > ---
> > >  target-arm/cpu.h       | 14 +++++++++++---
> > >  target-arm/helper.c    | 20 ++++++++++++++++----
> > >  target-arm/translate.c | 19 +++++++++++++------
> > >  3 files changed, 40 insertions(+), 13 deletions(-)
> > >
> > > diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> > > index 0b8042c..d4eab39 100644
> > > --- a/target-arm/cpu.h
> > > +++ b/target-arm/cpu.h
> > > @@ -831,6 +831,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;
> > > @@ -848,9 +849,16 @@ void armv7m_nvic_complete_irq(void *opaque, int
> > irq);
> > >  #define CP_REG_AA64_SHIFT 28
> > >  #define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
> > >
> > > -#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2)   \
> > > -    (((cp) << 16) | ((is64) << 15) | ((crn) << 11) |    \
> > > -     ((crm) << 7) | ((opc1) << 3) | (opc2))
> > > +/* To enable banking of coprocessor registers depending on ns-bit we
> > > + * add a bit to distinguish between secure and non-secure cpregs in the
> > > + * hashtable.
> > > + */
> > > +#define CP_REG_NS_SHIFT 27
> > > +#define CP_REG_NS_MASK(nsbit) (nsbit << CP_REG_NS_SHIFT)
> > > +
> > > +#define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2, ns)   \
> > > +    (CP_REG_NS_MASK(ns) | ((cp) << 16) | ((is64) << 15) |   \
> > > +     ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
> > >
> > >  #define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
> > >      (CP_REG_AA64_MASK |                                 \
> > > diff --git a/target-arm/helper.c b/target-arm/helper.c
> > > index f9b2374..610245d 100644
> > > --- a/target-arm/helper.c
> > > +++ b/target-arm/helper.c
> > > @@ -2883,7 +2883,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.
> > > @@ -2917,7 +2917,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;
> > > @@ -3066,8 +3066,20 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU
> > *cpu,
> > >                      if (r->state != state && r->state !=
> > ARM_CP_STATE_BOTH) {
> > >                          continue;
> > >                      }
> > > -                    add_cpreg_to_hashtable(cpu, r, opaque, state,
> > > -                                           crm, opc1, opc2);
> > > +                    if (state == ARM_CP_STATE_AA32) {
> > > +                        /* Under Aarch32 CP registers can be common
> > > +                         * (same for secure and non-secure world) or
> > banked.
> > > +                         */
> > > +                        add_cpreg_to_hashtable(cpu, r, opaque, state,
> > > +                                crm, opc1, opc2, !SCR_NS);
> > > +                        add_cpreg_to_hashtable(cpu, r, opaque, state,
> > > +                                crm, opc1, opc2, SCR_NS);
> > > +                    } else {
> > > +                        /* Aarch64 registers get mapped to non-secure
> > instance
> > > +                         * of Aarch32 */
> > > +                        add_cpreg_to_hashtable(cpu, r, opaque, state,
> > > +                                crm, opc1, opc2, SCR_NS);
> > > +                    }
> > >                  }
> > >              }
> > >          }
> > > diff --git a/target-arm/translate.c b/target-arm/translate.c
> > > index f657389..30d9592 100644
> > > --- a/target-arm/translate.c
> > > +++ b/target-arm/translate.c
> > > @@ -6968,7 +6968,7 @@ static int disas_neon_data_insn(CPUARMState * env,
> > DisasContext *s, uint32_t ins
> > >
> > >  static int disas_coproc_insn(CPUARMState * env, DisasContext *s,
> > uint32_t insn)
> > >  {
> > > -    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
> > > +    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2, ns;
> > >      const ARMCPRegInfo *ri;
> > >
> > >      cpnum = (insn >> 8) & 0xf;
> > > @@ -7012,8 +7012,11 @@ static int disas_coproc_insn(CPUARMState * env,
> > DisasContext *s, uint32_t insn)
> > >      isread = (insn >> 20) & 1;
> > >      rt = (insn >> 12) & 0xf;
> > >
> > > +    /* Monitor mode is always treated as secure but cp register
> > reads/writes
> > > +     * can access secure and non-secure instances using SCR.NS bit*/
> > > +    ns = IS_NS(s) ? 1 : !USE_SECURE_REG(env);
> > >      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, ns));
> > >      if (ri) {
> > >          /* Check access permissions */
> > >          if (!cp_access_ok(s->current_pl, ri, isread)) {
> > > @@ -7200,12 +7203,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,
> > > +                      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,
> > > +                      ns ? "non-secure" : "secure");
> > >      }
> > >
> > >      return 1;
> > > --
> > > 1.8.3.2
> > >
> >

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

end of thread, other threads:[~2014-06-26  3:57 UTC | newest]

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

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.