All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework
@ 2014-01-31 15:45 Peter Maydell
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 01/35] target-arm: Fix raw read and write functions on AArch64 registers Peter Maydell
                   ` (36 more replies)
  0 siblings, 37 replies; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

This is version two of a patchset which makes a start on AArch64
system emulation by tackling system registers.

The major changes here since v1 are that I've added a set of
patches which rework the reginfo struct to use a separate accessfn
rather than having readfn and writenfn possibly return EXCP_UDEF.
This was suggested by Peter Crosthwaite in the previous round and
I think it is a big improvement.

For correct syndrome information the next step will be that
the translate.c/translate-a64.c code passes helper_access_check_cp_reg()
a prototype syndrome so it can eventually be used by the exception
entry code; but I'm still working on the syndrome register support
code, and anyway this series is already pretty long.

Review appreciated, especially for the early patches in the
series and for the accessfn refactoring, so I can start to
feed these patches into target-arm.next.

thanks
-- PMM

Peter Maydell (35):
  target-arm: Fix raw read and write functions on AArch64 registers
  target-arm/kvm-consts.h: Define QEMU constants for known KVM CPUs
  target-arm: Define names for SCTLR bits
  target-arm: Restrict check_ap() use of S and R bits to v6 and earlier
  target-arm: Remove unused ARMCPUState sr substruct
  target-arm: Log bad system register accesses with LOG_UNIMP
  target-arm: Add exception level to the AArch64 TB flags
  target-arm: A64: Implement store-exclusive for system mode
  target-arm: A64: Implement MSR (immediate) instructions
  target-arm: Stop underdecoding ARM946 PRBS registers
  target-arm: Split cpreg access checks out from read/write functions
  target-arm: Convert performance monitor reginfo to accesfn
  target-arm: Convert generic timer reginfo to accessfn
  target-arm: Convert miscellaneous reginfo structs to accessfn
  target-arm: Drop success/fail return from cpreg read and write
    functions
  target-arm: Remove unnecessary code now read/write fns can't fail
  target-arm: Remove failure status return from read/write_raw_cp_reg
  target-arm: Fix incorrect type for value argument to write_raw_cp_reg
  target-arm: A64: Make cache ID registers visible to AArch64
  target-arm: Implement AArch64 CurrentEL sysreg
  target-arm: Implement AArch64 MIDR_EL1
  target-arm: Implement AArch64 DAIF system register
  target-arm: Implement AArch64 cache invalidate/clean ops
  target-arm: Implement AArch64 TLB invalidate ops
  target-arm: Implement AArch64 dummy MDSCR_EL1
  target-arm: Implement AArch64 memory attribute registers
  target-arm: Implement AArch64 SCTLR_EL1
  target-arm: Implement AArch64 TCR_EL1
  target-arm: Implement AArch64 VBAR_EL1
  target-arm: Implement AArch64 TTBR*
  target-arm: Implement AArch64 MPIDR
  target-arm: Implement AArch64 generic timers
  target-arm: Implement AArch64 ID and feature registers
  target-arm: Implement AArch64 dummy breakpoint and watchpoint
    registers
  target-arm: Implement AArch64 OSLAR_EL1 sysreg as WI

 hw/arm/pxa2xx.c            |   38 +-
 hw/arm/pxa2xx_pic.c        |   11 +-
 target-arm/cpu-qom.h       |   10 +
 target-arm/cpu.c           |   12 +-
 target-arm/cpu.h           |  153 +++++--
 target-arm/cpu64.c         |    1 +
 target-arm/helper.c        | 1093 +++++++++++++++++++++++++++-----------------
 target-arm/helper.h        |    3 +
 target-arm/kvm-consts.h    |   16 +-
 target-arm/op_helper.c     |   65 ++-
 target-arm/translate-a64.c |  119 ++++-
 target-arm/translate.c     |   28 +-
 12 files changed, 1025 insertions(+), 524 deletions(-)

-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 01/35] target-arm: Fix raw read and write functions on AArch64 registers
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-01-31 15:56   ` Rob Herring
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 02/35] target-arm/kvm-consts.h: Define QEMU constants for known KVM CPUs Peter Maydell
                   ` (35 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

The raw read and write functions were using the ARM_CP_64BIT flag in
ri->type to determine whether to treat the register's state field as
uint32_t or uint64_t; however AArch64 register info structs don't use
that flag. Abstract out the "how big is the field?" test into a
function and fix it to work for AArch64 registers.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.c    | 2 +-
 target-arm/cpu.h    | 8 ++++++++
 target-arm/helper.c | 4 ++--
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 45ad7f0..935269c 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -60,7 +60,7 @@ static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
         return;
     }
 
-    if (ri->type & ARM_CP_64BIT) {
+    if (cpreg_field_is_64bit(ri)) {
         CPREG_FIELD64(&cpu->env, ri) = ri->resetvalue;
     } else {
         CPREG_FIELD32(&cpu->env, ri) = ri->resetvalue;
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 383c582..7ccdbae 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -890,6 +890,14 @@ int arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t *value);
  */
 void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque);
 
+/* Return true if this reginfo struct's field in the cpu state struct
+ * is 64 bits wide.
+ */
+static inline bool cpreg_field_is_64bit(const ARMCPRegInfo *ri)
+{
+    return (ri->state == ARM_CP_STATE_AA64) || (ri->type & ARM_CP_64BIT);
+}
+
 static inline bool cp_access_ok(int current_pl,
                                 const ARMCPRegInfo *ri, int isread)
 {
diff --git a/target-arm/helper.c b/target-arm/helper.c
index ca5b000..e2cccb1 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -110,7 +110,7 @@ static int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
 static int raw_read(CPUARMState *env, const ARMCPRegInfo *ri,
                     uint64_t *value)
 {
-    if (ri->type & ARM_CP_64BIT) {
+    if (cpreg_field_is_64bit(ri)) {
         *value = CPREG_FIELD64(env, ri);
     } else {
         *value = CPREG_FIELD32(env, ri);
@@ -121,7 +121,7 @@ static int raw_read(CPUARMState *env, const ARMCPRegInfo *ri,
 static int raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
                      uint64_t value)
 {
-    if (ri->type & ARM_CP_64BIT) {
+    if (cpreg_field_is_64bit(ri)) {
         CPREG_FIELD64(env, ri) = value;
     } else {
         CPREG_FIELD32(env, ri) = value;
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 02/35] target-arm/kvm-consts.h: Define QEMU constants for known KVM CPUs
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 01/35] target-arm: Fix raw read and write functions on AArch64 registers Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 03/35] target-arm: Define names for SCTLR bits Peter Maydell
                   ` (34 subsequent siblings)
  36 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Extend the set of CPUs for which we provide a QEMU_KVM_ARM_TARGET_*
constant to include all the ones currently supported by the kernel
headers we are using.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/kvm-consts.h | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/target-arm/kvm-consts.h b/target-arm/kvm-consts.h
index 0e7f889..6009a33 100644
--- a/target-arm/kvm-consts.h
+++ b/target-arm/kvm-consts.h
@@ -50,15 +50,29 @@ MISMATCH_CHECK(PSCI_FN_CPU_OFF, KVM_PSCI_FN_CPU_OFF)
 MISMATCH_CHECK(PSCI_FN_CPU_ON, KVM_PSCI_FN_CPU_ON)
 MISMATCH_CHECK(PSCI_FN_MIGRATE, KVM_PSCI_FN_MIGRATE)
 
+/* Note that KVM uses overlapping values for AArch32 and AArch64
+ * target CPU numbers. AArch32 targets:
+ */
 #define QEMU_KVM_ARM_TARGET_CORTEX_A15 0
+#define QEMU_KVM_ARM_TARGET_CORTEX_A7 1
+
+/* AArch64 targets: */
+#define QEMU_KVM_ARM_TARGET_AEM_V8 0
+#define QEMU_KVM_ARM_TARGET_FOUNDATION_V8 1
+#define QEMU_KVM_ARM_TARGET_CORTEX_A57 2
 
 /* There's no kernel define for this: sentinel value which
  * matches no KVM target value for either 64 or 32 bit
  */
 #define QEMU_KVM_ARM_TARGET_NONE UINT_MAX
 
-#ifndef TARGET_AARCH64
+#ifdef TARGET_AARCH64
+MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_AEM_V8, KVM_ARM_TARGET_AEM_V8)
+MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_FOUNDATION_V8, KVM_ARM_TARGET_FOUNDATION_V8)
+MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A57, KVM_ARM_TARGET_CORTEX_A57)
+#else
 MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A15, KVM_ARM_TARGET_CORTEX_A15)
+MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A7, KVM_ARM_TARGET_CORTEX_A7)
 #endif
 
 #define CP_REG_ARM64                   0x6000000000000000ULL
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 03/35] target-arm: Define names for SCTLR bits
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 01/35] target-arm: Fix raw read and write functions on AArch64 registers Peter Maydell
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 02/35] target-arm/kvm-consts.h: Define QEMU constants for known KVM CPUs Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 04/35] target-arm: Restrict check_ap() use of S and R bits to v6 and earlier Peter Maydell
                   ` (33 subsequent siblings)
  36 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

The SCTLR is full of bits for enabling or disabling various things, and so
there are many places in the code which check if certain bits are set.
Define some named constants for the SCTLR bits so these checks are easier
to read.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.c    |  2 +-
 target-arm/cpu.h    | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 target-arm/helper.c | 16 ++++++++--------
 3 files changed, 61 insertions(+), 9 deletions(-)

diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 935269c..3014e86 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -128,7 +128,7 @@ static void arm_cpu_reset(CPUState *s)
         }
     }
 
-    if (env->cp15.c1_sys & (1 << 13)) {
+    if (env->cp15.c1_sys & SCTLR_V) {
             env->regs[15] = 0xFFFF0000;
     }
 
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 7ccdbae..4bad6c0 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -337,6 +337,58 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
                               int mmu_idx);
 #define cpu_handle_mmu_fault cpu_arm_handle_mmu_fault
 
+/* SCTLR bit meanings. Several bits have been reused in newer
+ * versions of the architecture; in that case we define constants
+ * for both old and new bit meanings. Code which tests against those
+ * bits should probably check or otherwise arrange that the CPU
+ * is the architectural version it expects.
+ */
+#define SCTLR_M       (1U << 0)
+#define SCTLR_A       (1U << 1)
+#define SCTLR_C       (1U << 2)
+#define SCTLR_W       (1U << 3) /* up to v6; RAO in v7 */
+#define SCTLR_SA      (1U << 3)
+#define SCTLR_P       (1U << 4) /* up to v5; RAO in v6 and v7 */
+#define SCTLR_SA0     (1U << 4) /* v8 onward, AArch64 only */
+#define SCTLR_D       (1U << 5) /* up to v5; RAO in v6 */
+#define SCTLR_CP15BEN (1U << 5) /* v7 onward */
+#define SCTLR_L       (1U << 6) /* up to v5; RAO in v6 and v7; RAZ in v8 */
+#define SCTLR_B       (1U << 7) /* up to v6; RAZ in v7 */
+#define SCTLR_ITD     (1U << 7) /* v8 onward */
+#define SCTLR_S       (1U << 8) /* up to v6; RAZ in v7 */
+#define SCTLR_SED     (1U << 8) /* v8 onward */
+#define SCTLR_R       (1U << 9) /* up to v6; RAZ in v7 */
+#define SCTLR_UMA     (1U << 9) /* v8 onward, AArch64 only */
+#define SCTLR_F       (1U << 10) /* up to v6 */
+#define SCTLR_SW      (1U << 10) /* v7 onward */
+#define SCTLR_Z       (1U << 11)
+#define SCTLR_I       (1U << 12)
+#define SCTLR_V       (1U << 13)
+#define SCTLR_RR      (1U << 14) /* up to v7 */
+#define SCTLR_DZE     (1U << 14) /* v8 onward, AArch64 only */
+#define SCTLR_L4      (1U << 15) /* up to v6; RAZ in v7 */
+#define SCTLR_UCT     (1U << 15) /* v8 onward, AArch64 only */
+#define SCTLR_DT      (1U << 16) /* up to ??, RAO in v6 and v7 */
+#define SCTLR_nTWI    (1U << 16) /* v8 onward */
+#define SCTLR_HA      (1U << 17)
+#define SCTLR_IT      (1U << 18) /* up to ??, RAO in v6 and v7 */
+#define SCTLR_nTWE    (1U << 18) /* v8 onward */
+#define SCTLR_WXN     (1U << 19)
+#define SCTLR_ST      (1U << 20) /* up to ??, RAZ in v6 */
+#define SCTLR_UWXN    (1U << 20) /* v7 onward */
+#define SCTLR_FI      (1U << 21)
+#define SCTLR_U       (1U << 22)
+#define SCTLR_XP      (1U << 23) /* up to v6; v7 onward RAO */
+#define SCTLR_VE      (1U << 24) /* up to v7 */
+#define SCTLR_E0E     (1U << 24) /* v8 onward, AArch64 only */
+#define SCTLR_EE      (1U << 25)
+#define SCTLR_L2      (1U << 26) /* up to v6, RAZ in v7 */
+#define SCTLR_UCI     (1U << 26) /* v8 onward, AArch64 only */
+#define SCTLR_NMFI    (1U << 27)
+#define SCTLR_TRE     (1U << 28)
+#define SCTLR_AFE     (1U << 29)
+#define SCTLR_TE      (1U << 30)
+
 #define CPSR_M (0x1fU)
 #define CPSR_T (1U << 5)
 #define CPSR_F (1U << 6)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index e2cccb1..d670db8 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2716,7 +2716,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
         return; /* Never happens.  Keep compiler happy.  */
     }
     /* High vectors.  */
-    if (env->cp15.c1_sys & (1 << 13)) {
+    if (env->cp15.c1_sys & SCTLR_V) {
         /* when enabled, base address cannot be remapped.  */
         addr += 0xffff0000;
     } else {
@@ -2739,7 +2739,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 & (1 << 30)) != 0;
+        env->thumb = (env->cp15.c1_sys & SCTLR_TE) != 0;
     }
     env->regs[14] = env->regs[15] + offset;
     env->regs[15] = addr;
@@ -2767,10 +2767,10 @@ static inline int check_ap(CPUARMState *env, int ap, int domain_prot,
   case 0:
       if (access_type == 1)
           return 0;
-      switch ((env->cp15.c1_sys >> 8) & 3) {
-      case 1:
+      switch (env->cp15.c1_sys & (SCTLR_S | SCTLR_R)) {
+      case SCTLR_S:
           return is_user ? 0 : PAGE_READ;
-      case 2:
+      case SCTLR_R:
           return PAGE_READ;
       default:
           return 0;
@@ -2999,7 +2999,7 @@ 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 & (1 << 29)) && (ap & 1) == 0) {
+        if ((env->cp15.c1_sys & SCTLR_AFE) && (ap & 1) == 0) {
             /* Access flag fault.  */
             code = (code == 15) ? 6 : 3;
             goto do_fault;
@@ -3290,7 +3290,7 @@ static inline int get_phys_addr(CPUARMState *env, uint32_t address,
     if (address < 0x02000000)
         address += env->cp15.c13_fcse;
 
-    if ((env->cp15.c1_sys & 1) == 0) {
+    if ((env->cp15.c1_sys & SCTLR_M) == 0) {
         /* MMU/MPU disabled.  */
         *phys_ptr = address;
         *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
@@ -3303,7 +3303,7 @@ static inline int get_phys_addr(CPUARMState *env, uint32_t 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 & (1 << 23)) {
+    } else if (env->cp15.c1_sys & SCTLR_XP) {
         return get_phys_addr_v6(env, address, access_type, is_user, phys_ptr,
                                 prot, page_size);
     } else {
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 04/35] target-arm: Restrict check_ap() use of S and R bits to v6 and earlier
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (2 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 03/35] target-arm: Define names for SCTLR bits Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 05/35] target-arm: Remove unused ARMCPUState sr substruct Peter Maydell
                   ` (32 subsequent siblings)
  36 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

The SCTLR bits S and R (8 and 9) only exist in ARMv6 and earlier.
In ARMv7 these bits RAZ, and in ARMv8 they are reassigned. Guard
the use of them in check_ap() so that we don't get incorrect results
for ARMv8 CPUs.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
 target-arm/helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index d670db8..6f1ec46 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2765,6 +2765,9 @@ static inline int check_ap(CPUARMState *env, int ap, int domain_prot,
 
   switch (ap) {
   case 0:
+      if (arm_feature(env, ARM_FEATURE_V7)) {
+          return 0;
+      }
       if (access_type == 1)
           return 0;
       switch (env->cp15.c1_sys & (SCTLR_S | SCTLR_R)) {
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 05/35] target-arm: Remove unused ARMCPUState sr substruct
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (3 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 04/35] target-arm: Restrict check_ap() use of S and R bits to v6 and earlier Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-05  6:03   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 06/35] target-arm: Log bad system register accesses with LOG_UNIMP Peter Maydell
                   ` (31 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Remove the 'struct sr' from ARMCPUState -- it isn't actually used and is
a hangover from the original separate system register implementation used
by the SuSE linux-user-mode-only AArch64 target.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.h | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 4bad6c0..70cd5a0 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -217,11 +217,6 @@ typedef struct CPUARMState {
         uint32_t c15_power_control; /* power control */
     } cp15;
 
-    /* System registers (AArch64) */
-    struct {
-        uint64_t tpidr_el0;
-    } sr;
-
     struct {
         uint32_t other_sp;
         uint32_t vecbase;
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 06/35] target-arm: Log bad system register accesses with LOG_UNIMP
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (4 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 05/35] target-arm: Remove unused ARMCPUState sr substruct Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 07/35] target-arm: Add exception level to the AArch64 TB flags Peter Maydell
                   ` (30 subsequent siblings)
  36 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Log guest attempts to access unimplemented system registers via
the LOG_UNIMP reporting mechanism (for both the 32 bit and 64 bit
instruction sets). This is particularly useful for debugging
problems where the guest is trying to use a system register that
QEMU doesn't implement.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
 target-arm/translate-a64.c |  7 ++++++-
 target-arm/translate.c     | 13 +++++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index ee768f2..f808998 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1172,7 +1172,12 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
                                                crn, crm, op0, op1, op2));
 
     if (!ri) {
-        /* Unknown register */
+        /* Unknown register; this might be a guest error or a QEMU
+         * unimplemented feature.
+         */
+        qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch64 "
+                      "system register op0:%d op1:%d crn:%d crm:%d op2:%d\n",
+                      isread ? "read" : "write", op0, op1, crn, crm, op2);
         unallocated_encoding(s);
         return;
     }
diff --git a/target-arm/translate.c b/target-arm/translate.c
index e701c0f..45886f9 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6923,6 +6923,19 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
         return 0;
     }
 
+    /* Unknown register; this might be a guest error or a QEMU
+     * unimplemented feature.
+     */
+    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);
+    } 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);
+    }
+
     return 1;
 }
 
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 07/35] target-arm: Add exception level to the AArch64 TB flags
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (5 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 06/35] target-arm: Log bad system register accesses with LOG_UNIMP Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 08/35] target-arm: A64: Implement store-exclusive for system mode Peter Maydell
                   ` (29 subsequent siblings)
  36 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

We already implicitly rely on the exception level being
part of the TB flags for coprocessor access, so actually
include it. (This makes no difference for linux-user mode,
which is always in EL0, but will be needed for correct
operation in system emulation.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.h | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 70cd5a0..385cfcd 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1056,7 +1056,9 @@ static inline int cpu_mmu_index (CPUARMState *env)
 #define ARM_TBFLAG_BSWAP_CODE_SHIFT 16
 #define ARM_TBFLAG_BSWAP_CODE_MASK  (1 << ARM_TBFLAG_BSWAP_CODE_SHIFT)
 
-/* Bit usage when in AArch64 state: currently no bits defined */
+/* Bit usage when in AArch64 state */
+#define ARM_TBFLAG_AA64_EL_SHIFT    0
+#define ARM_TBFLAG_AA64_EL_MASK     (0x3 << ARM_TBFLAG_AA64_EL_SHIFT)
 
 /* some convenience accessor macros */
 #define ARM_TBFLAG_AARCH64_STATE(F) \
@@ -1075,13 +1077,16 @@ static inline int cpu_mmu_index (CPUARMState *env)
     (((F) & ARM_TBFLAG_CONDEXEC_MASK) >> ARM_TBFLAG_CONDEXEC_SHIFT)
 #define ARM_TBFLAG_BSWAP_CODE(F) \
     (((F) & ARM_TBFLAG_BSWAP_CODE_MASK) >> ARM_TBFLAG_BSWAP_CODE_SHIFT)
+#define ARM_TBFLAG_AA64_EL(F) \
+    (((F) & ARM_TBFLAG_AA64_EL_MASK) >> ARM_TBFLAG_AA64_EL_SHIFT)
 
 static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
 {
     if (is_a64(env)) {
         *pc = env->pc;
-        *flags = ARM_TBFLAG_AARCH64_STATE_MASK;
+        *flags = ARM_TBFLAG_AARCH64_STATE_MASK
+            | arm_current_pl(env) << ARM_TBFLAG_AA64_EL_SHIFT;
     } else {
         int privmode;
         *pc = env->regs[15];
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 08/35] target-arm: A64: Implement store-exclusive for system mode
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (6 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 07/35] target-arm: Add exception level to the AArch64 TB flags Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-11 18:43   ` Peter Maydell
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 09/35] target-arm: A64: Implement MSR (immediate) instructions Peter Maydell
                   ` (28 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

System mode store-exclusive use a different code path to usermode ones;
implement this missing code, in a similar way to the 32 bit version.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/translate-a64.c | 68 ++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 62 insertions(+), 6 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index f808998..d938e5e 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1473,12 +1473,68 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
 }
 #else
 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
-                                TCGv_i64 addr, int size, int is_pair)
-{
-    qemu_log_mask(LOG_UNIMP,
-                  "%s:%d: system mode store_exclusive unsupported "
-                  "at pc=%016" PRIx64 "\n",
-                  __FILE__, __LINE__, s->pc - 4);
+                                TCGv_i64 inaddr, int size, int is_pair)
+{
+    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]
+     *     && (!is_pair || env->exclusive_high == [addr + datasize])) {
+     *     [addr] = {Rt};
+     *     if (is_pair) {
+     *         [addr + datasize] = {Rt2};
+     *     }
+     *     {Rd} = 0;
+     * } else {
+     *     {Rd} = 1;
+     * }
+     * env->exclusive_addr = -1;
+     */
+    int fail_label = gen_new_label();
+    int done_label = gen_new_label();
+    TCGv_i64 addr = tcg_temp_local_new_i64();
+    TCGv_i64 tmp;
+
+    /* Copy input into a local temp so it is not trashed when the
+     * basic block ends at the branch insn.
+     */
+    tcg_gen_mov_i64(addr, inaddr);
+    tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
+
+    tmp = tcg_temp_new_i64();
+    tcg_gen_qemu_ld_i64(tmp, addr, get_mem_index(s), MO_TE + size);
+    tcg_gen_brcond_i64(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
+    tcg_temp_free_i64(tmp);
+
+    if (is_pair) {
+        TCGv_i64 addrhi = tcg_temp_new_i64();
+        TCGv_i64 tmphi = tcg_temp_new_i64();
+
+        tcg_gen_addi_i64(addrhi, addr, 1 << size);
+        tcg_gen_qemu_ld_i64(tmphi, addrhi, get_mem_index(s), MO_TE + size);
+        tcg_gen_brcond_i64(TCG_COND_NE, tmphi, cpu_exclusive_high, fail_label);
+
+        tcg_temp_free_i64(tmphi);
+        tcg_temp_free_i64(addrhi);
+    }
+
+    /* We seem to still have the exclusive monitor, so do the store */
+    tcg_gen_qemu_st_i64(cpu_reg(s, rt), addr, get_mem_index(s), MO_TE + size);
+    if (is_pair) {
+        TCGv_i64 addrhi = tcg_temp_new_i64();
+
+        tcg_gen_addi_i64(addrhi, addr, 1 << size);
+        tcg_gen_qemu_st_i64(cpu_reg(s, rt2), addrhi,
+                            get_mem_index(s), MO_TE + size);
+        tcg_temp_free_i64(addrhi);
+    }
+
+    tcg_temp_free_i64(addr);
+
+    tcg_gen_movi_i64(cpu_reg(s, rd), 0);
+    tcg_gen_br(done_label);
+    gen_set_label(fail_label);
+    tcg_gen_movi_i64(cpu_reg(s, rd), 1);
+    gen_set_label(done_label);
+    tcg_gen_movi_i64(cpu_exclusive_addr, -1);
+
 }
 #endif
 
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 09/35] target-arm: A64: Implement MSR (immediate) instructions
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (7 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 08/35] target-arm: A64: Implement store-exclusive for system mode Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-05  6:23   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 10/35] target-arm: Stop underdecoding ARM946 PRBS registers Peter Maydell
                   ` (27 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Implement the MSR (immediate) instructions, which can update the
PSTATE SP and DAIF fields.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.h           |  1 +
 target-arm/helper.h        |  2 ++
 target-arm/op_helper.c     | 25 +++++++++++++++++++++++++
 target-arm/translate-a64.c | 24 +++++++++++++++++++++++-
 4 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 385cfcd..e66d464 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -426,6 +426,7 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
 #define PSTATE_Z (1U << 30)
 #define PSTATE_N (1U << 31)
 #define PSTATE_NZCV (PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V)
+#define PSTATE_DAIF (PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F)
 #define CACHED_PSTATE_BITS (PSTATE_NZCV)
 /* Mode values for AArch64 */
 #define PSTATE_MODE_EL3h 13
diff --git a/target-arm/helper.h b/target-arm/helper.h
index 71b8411..93a27ce 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -62,6 +62,8 @@ DEF_HELPER_2(get_cp_reg, i32, env, ptr)
 DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
 DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
 
+DEF_HELPER_3(msr_i_pstate, void, env, i32, i32)
+
 DEF_HELPER_2(get_r13_banked, i32, env, i32)
 DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
 
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index a918e5b..c812a9f 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -313,6 +313,31 @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
     return value;
 }
 
+void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
+{
+    /* MSR_i to update PSTATE. This is OK from EL0 only if UMA is set.
+     * 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)) {
+        raise_exception(env, EXCP_UDEF);
+    }
+
+    switch (op) {
+    case 0x05: /* SPSel */
+        env->pstate = deposit32(env->pstate, 0, 1, imm);
+        break;
+    case 0x1e: /* DAIFSet */
+        env->pstate |= (imm << 6) & PSTATE_DAIF;
+        break;
+    case 0x1f: /* DAIFClear */
+        env->pstate &= ~((imm << 6) & PSTATE_DAIF);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+}
+
 /* ??? Flag setting arithmetic is awkward because we need to do comparisons.
    The only way to do that in TCG is a conditional branch, which clobbers
    all our temporaries.  For now implement these as helper functions.  */
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index d938e5e..a942609 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1106,7 +1106,29 @@ static void handle_sync(DisasContext *s, uint32_t insn,
 static void handle_msr_i(DisasContext *s, uint32_t insn,
                          unsigned int op1, unsigned int op2, unsigned int crm)
 {
-    unsupported_encoding(s, insn);
+    int op = op1 << 3 | op2;
+    switch (op) {
+    case 0x05: /* SPSel */
+        if (s->current_pl == 0) {
+            unallocated_encoding(s);
+            return;
+        }
+        /* fall through */
+    case 0x1e: /* DAIFSet */
+    case 0x1f: /* DAIFClear */
+    {
+        TCGv_i32 tcg_imm = tcg_const_i32(crm);
+        TCGv_i32 tcg_op = tcg_const_i32(op);
+        gen_helper_msr_i_pstate(cpu_env, tcg_op, tcg_imm);
+        tcg_temp_free_i32(tcg_imm);
+        tcg_temp_free_i32(tcg_op);
+        s->is_jmp = DISAS_UPDATE;
+        break;
+    }
+    default:
+        unallocated_encoding(s);
+        return;
+    }
 }
 
 static void gen_get_nzcv(TCGv_i64 tcg_rt)
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 10/35] target-arm: Stop underdecoding ARM946 PRBS registers
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (8 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 09/35] target-arm: A64: Implement MSR (immediate) instructions Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 11/35] target-arm: Split cpreg access checks out from read/write functions Peter Maydell
                   ` (26 subsequent siblings)
  36 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

The ARM946 has 8 PRBS (protection region base and size) registers.
Currently we implement these with a CP_ANY reginfo; however this
underdecodes (since there are 16 possible values of CRm but only
8 registers) and we catch the invalid values in the read and
write functions. However this causes issues with migration since
we only migrate the first of a wildcard register set, so we only
migrate c6_region[0]. It also makes it awkward to pull reginfo
access checks out into their own function.

Avoid all these problems by just defining separate reginfo structs
for each of the 8 registers; this also lets us avoid having any
read or write functions and will result in more efficient direct
field accesses from generated code.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/helper.c | 47 ++++++++++++++++++++++++-----------------------
 1 file changed, 24 insertions(+), 23 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 6f1ec46..bd78350 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1162,26 +1162,6 @@ static int pmsav5_insn_ap_read(CPUARMState *env, const ARMCPRegInfo *ri,
     return 0;
 }
 
-static int arm946_prbs_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                            uint64_t *value)
-{
-    if (ri->crm >= 8) {
-        return EXCP_UDEF;
-    }
-    *value = env->cp15.c6_region[ri->crm];
-    return 0;
-}
-
-static int arm946_prbs_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                             uint64_t value)
-{
-    if (ri->crm >= 8) {
-        return EXCP_UDEF;
-    }
-    env->cp15.c6_region[ri->crm] = value;
-    return 0;
-}
-
 static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
     { .name = "DATA_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW, .type = ARM_CP_NO_MIGRATE,
@@ -1204,9 +1184,30 @@ static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
       .access = PL1_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.c2_insn), .resetvalue = 0, },
     /* Protection region base and size registers */
-    { .name = "946_PRBS", .cp = 15, .crn = 6, .crm = CP_ANY, .opc1 = 0,
-      .opc2 = CP_ANY, .access = PL1_RW,
-      .readfn = arm946_prbs_read, .writefn = arm946_prbs_write, },
+    { .name = "946_PRBS0", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0,
+      .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.c6_region[0]) },
+    { .name = "946_PRBS1", .cp = 15, .crn = 6, .crm = 1, .opc1 = 0,
+      .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.c6_region[1]) },
+    { .name = "946_PRBS2", .cp = 15, .crn = 6, .crm = 2, .opc1 = 0,
+      .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.c6_region[2]) },
+    { .name = "946_PRBS3", .cp = 15, .crn = 6, .crm = 3, .opc1 = 0,
+      .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.c6_region[3]) },
+    { .name = "946_PRBS4", .cp = 15, .crn = 6, .crm = 4, .opc1 = 0,
+      .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.c6_region[4]) },
+    { .name = "946_PRBS5", .cp = 15, .crn = 6, .crm = 5, .opc1 = 0,
+      .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.c6_region[5]) },
+    { .name = "946_PRBS6", .cp = 15, .crn = 6, .crm = 6, .opc1 = 0,
+      .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.c6_region[6]) },
+    { .name = "946_PRBS7", .cp = 15, .crn = 6, .crm = 7, .opc1 = 0,
+      .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.c6_region[7]) },
     REGINFO_SENTINEL
 };
 
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 11/35] target-arm: Split cpreg access checks out from read/write functions
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (9 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 10/35] target-arm: Stop underdecoding ARM946 PRBS registers Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-09  2:50   ` Peter Crosthwaite
  2014-02-11  6:13   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 12/35] target-arm: Convert performance monitor reginfo to accesfn Peter Maydell
                   ` (25 subsequent siblings)
  36 siblings, 2 replies; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Several of the system registers handled via the ARMCPRegInfo
mechanism have access trap control bits controlling whether the
registers are accessible to lower privilege levels. Replace
the existing mechanism (allowing the read and write functions
to return EXCP_UDEF if access is denied) with a dedicated
"check access rights" function pointer in the ARMCPRegInfo.
This will allow us to simplify some of the register definitions,
which no longer need read/write functions purely to handle
the access checks.

We take the opportunity to define the return value from the
access checking function in a way that allows us to set the
correct exception syndrome information for exceptions taken
to AArch64 (which may need to distinguish access failures due
to a configurable trap or enable from other kinds of access
failure).

This commit defines the new mechanism but does not move any
of the registers across to use it.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.h           | 29 +++++++++++++++++++++++++----
 target-arm/helper.h        |  1 +
 target-arm/op_helper.c     | 18 ++++++++++++++++++
 target-arm/translate-a64.c | 11 +++++++++++
 target-arm/translate.c     | 11 +++++++++++
 5 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index e66d464..30b1a1c 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -812,14 +812,29 @@ static inline int arm_current_pl(CPUARMState *env)
 
 typedef struct ARMCPRegInfo ARMCPRegInfo;
 
-/* Access functions for coprocessor registers. These should return
- * 0 on success, or one of the EXCP_* constants if access should cause
- * an exception (in which case *value is not written).
- */
+typedef enum CPAccessResult {
+    /* Access is permitted */
+    CP_ACCESS_OK = 0,
+    /* Access fails due to a configurable trap or enable which would
+     * result in a categorized exception syndrome giving information about
+     * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
+     * 0xc or 0x18).
+     */
+    CP_ACCESS_TRAP = 1,
+    /* Access fails and results in an exception syndrome 0x0 ("uncategorized").
+     * Note that this is not a catch-all case -- the set of cases which may
+     * result in this failure is specifically defined by the architecture.
+     */
+    CP_ACCESS_TRAP_UNCATEGORIZED = 2,
+} CPAccessResult;
+
+/* Access functions for coprocessor registers. These should always succeed. */
 typedef int CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque,
                      uint64_t *value);
 typedef int CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
                       uint64_t value);
+/* Access permission check functions for coprocessor registers. */
+typedef CPAccessResult CPAccessFn(CPUARMState *env, const ARMCPRegInfo *opaque);
 /* Hook function for register reset */
 typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
 
@@ -873,6 +888,12 @@ struct ARMCPRegInfo {
      *  2. both readfn and writefn are specified
      */
     ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
+    /* 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
+     * translate time.
+     */
+    CPAccessFn *accessfn;
     /* Function for handling reads of this register. If NULL, then reads
      * will be done by loading from the offset into CPUARMState specified
      * by fieldoffset.
diff --git a/target-arm/helper.h b/target-arm/helper.h
index 93a27ce..1d83293 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -57,6 +57,7 @@ DEF_HELPER_1(cpsr_read, i32, env)
 DEF_HELPER_3(v7m_msr, void, env, i32, i32)
 DEF_HELPER_2(v7m_mrs, i32, env, i32)
 
+DEF_HELPER_2(access_check_cp_reg, void, env, ptr)
 DEF_HELPER_3(set_cp_reg, void, env, ptr, i32)
 DEF_HELPER_2(get_cp_reg, i32, env, ptr)
 DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index c812a9f..89b0978 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -273,6 +273,24 @@ void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
     }
 }
 
+void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip)
+{
+    const ARMCPRegInfo *ri = rip;
+    switch (ri->accessfn(env, ri)) {
+    case CP_ACCESS_OK:
+        return;
+    case CP_ACCESS_TRAP:
+    case CP_ACCESS_TRAP_UNCATEGORIZED:
+        /* These cases will eventually need to generate different
+         * syndrome information.
+         */
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    raise_exception(env, EXCP_UDEF);
+}
+
 void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)
 {
     const ARMCPRegInfo *ri = rip;
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index a942609..d90ffd1 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1210,6 +1210,17 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
         return;
     }
 
+    if (ri->accessfn) {
+        /* Emit code to perform further access permissions checks at
+         * runtime; this may result in an exception.
+         */
+        TCGv_ptr tmpptr;
+        gen_a64_set_pc_im(s->pc - 4);
+        tmpptr = tcg_const_ptr(ri);
+        gen_helper_access_check_cp_reg(cpu_env, tmpptr);
+        tcg_temp_free_ptr(tmpptr);
+    }
+
     /* Handle special cases first */
     switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
     case ARM_CP_NOP:
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 45886f9..2713081 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6798,6 +6798,17 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
             return 1;
         }
 
+        if (ri->accessfn) {
+            /* Emit code to perform further access permissions checks at
+             * runtime; this may result in an exception.
+             */
+            TCGv_ptr tmpptr;
+            gen_set_pc_im(s, s->pc);
+            tmpptr = tcg_const_ptr(ri);
+            gen_helper_access_check_cp_reg(cpu_env, tmpptr);
+            tcg_temp_free_ptr(tmpptr);
+        }
+
         /* Handle special cases first */
         switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
         case ARM_CP_NOP:
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 12/35] target-arm: Convert performance monitor reginfo to accesfn
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (10 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 11/35] target-arm: Split cpreg access checks out from read/write functions Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-05  6:59   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 13/35] target-arm: Convert generic timer reginfo to accessfn Peter Maydell
                   ` (24 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Convert the performance monitor reginfo definitions to use
an accessfn rather than returning EXCP_UDEF from read and
write functions. This also allows us to fix a couple of XXX
cases where we weren't imposing the access restrictions on
RAZ/WI or constant registers.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/helper.c | 70 +++++++++++++++++++++--------------------------------
 1 file changed, 28 insertions(+), 42 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index bd78350..9adaeb9 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -485,26 +485,20 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
-
-static int pmreg_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                      uint64_t *value)
+static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    /* Generic performance monitor register read function for where
-     * user access may be allowed by PMUSERENR.
+    /* Perfomance monitor registers user accessibility is controlled
+     * by PMUSERENR.
      */
     if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
-        return EXCP_UDEF;
+        return CP_ACCESS_TRAP;
     }
-    *value = CPREG_FIELD32(env, ri);
-    return 0;
+    return CP_ACCESS_OK;
 }
 
 static int pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                       uint64_t value)
 {
-    if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
-        return EXCP_UDEF;
-    }
     /* only the DP, X, D and E bits are writable */
     env->cp15.c9_pmcr &= ~0x39;
     env->cp15.c9_pmcr |= (value & 0x39);
@@ -514,9 +508,6 @@ static int pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 static int pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
                             uint64_t value)
 {
-    if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
-        return EXCP_UDEF;
-    }
     value &= (1 << 31);
     env->cp15.c9_pmcnten |= value;
     return 0;
@@ -525,9 +516,6 @@ static int pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
 static int pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                             uint64_t value)
 {
-    if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
-        return EXCP_UDEF;
-    }
     value &= (1 << 31);
     env->cp15.c9_pmcnten &= ~value;
     return 0;
@@ -536,9 +524,6 @@ static int pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 static int pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                         uint64_t value)
 {
-    if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
-        return EXCP_UDEF;
-    }
     env->cp15.c9_pmovsr &= ~value;
     return 0;
 }
@@ -546,9 +531,6 @@ static int pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 static int pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
                             uint64_t value)
 {
-    if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
-        return EXCP_UDEF;
-    }
     env->cp15.c9_pmxevtyper = value & 0xff;
     return 0;
 }
@@ -624,37 +606,41 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
     { .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 1,
       .access = PL0_RW, .resetvalue = 0,
       .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
-      .readfn = pmreg_read, .writefn = pmcntenset_write,
-      .raw_readfn = raw_read, .raw_writefn = raw_write },
+      .writefn = pmcntenset_write,
+      .accessfn = pmreg_access,
+      .raw_writefn = raw_write },
     { .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2,
       .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
-      .readfn = pmreg_read, .writefn = pmcntenclr_write,
+      .accessfn = pmreg_access,
+      .writefn = pmcntenclr_write,
       .type = ARM_CP_NO_MIGRATE },
     { .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3,
       .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
-      .readfn = pmreg_read, .writefn = pmovsr_write,
-      .raw_readfn = raw_read, .raw_writefn = raw_write },
-    /* Unimplemented so WI. Strictly speaking write accesses in PL0 should
-     * respect PMUSERENR.
-     */
+      .accessfn = pmreg_access,
+      .writefn = pmovsr_write,
+      .raw_writefn = raw_write },
+    /* Unimplemented so WI. */
     { .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
-      .access = PL0_W, .type = ARM_CP_NOP },
+      .access = PL0_W, .accessfn = pmreg_access, .type = ARM_CP_NOP },
     /* Since we don't implement any events, writing to PMSELR is UNPREDICTABLE.
-     * We choose to RAZ/WI. XXX should respect PMUSERENR.
+     * We choose to RAZ/WI.
      */
     { .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
-      .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
-    /* Unimplemented, RAZ/WI. XXX PMUSERENR */
+      .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0,
+      .accessfn = pmreg_access },
+    /* Unimplemented, RAZ/WI. */
     { .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0,
-      .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+      .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0,
+      .accessfn = pmreg_access },
     { .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1,
       .access = PL0_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.c9_pmxevtyper),
-      .readfn = pmreg_read, .writefn = pmxevtyper_write,
-      .raw_readfn = raw_read, .raw_writefn = raw_write },
-    /* Unimplemented, RAZ/WI. XXX PMUSERENR */
+      .accessfn = pmreg_access, .writefn = pmxevtyper_write,
+      .raw_writefn = raw_write },
+    /* Unimplemented, RAZ/WI. */
     { .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2,
-      .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+      .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0,
+      .accessfn = pmreg_access },
     { .name = "PMUSERENR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 0,
       .access = PL0_R | PL1_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.c9_pmuserenr),
@@ -1708,8 +1694,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
             .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
             .access = PL0_RW, .resetvalue = cpu->midr & 0xff000000,
             .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
-            .readfn = pmreg_read, .writefn = pmcr_write,
-            .raw_readfn = raw_read, .raw_writefn = raw_write,
+            .accessfn = pmreg_access, .writefn = pmcr_write,
+            .raw_writefn = raw_write,
         };
         ARMCPRegInfo clidr = {
             .name = "CLIDR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 13/35] target-arm: Convert generic timer reginfo to accessfn
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (11 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 12/35] target-arm: Convert performance monitor reginfo to accesfn Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-09  3:05   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 14/35] target-arm: Convert miscellaneous reginfo structs " Peter Maydell
                   ` (23 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Convert the reginfo structs for the generic timer registers
to use access functions rather than returning EXCP_UDEF from
their read handlers. In some cases this allows us to remove
a read handler completely.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/helper.c | 122 ++++++++++++++++++++++++++++------------------------
 1 file changed, 66 insertions(+), 56 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 9adaeb9..edff2e7 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -743,6 +743,59 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
 
 #ifndef CONFIG_USER_ONLY
 
+static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    /* CNTFRQ: not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero */
+    if (arm_current_pl(env) == 0 && !extract32(env->cp15.c14_cntkctl, 0, 2)) {
+        return CP_ACCESS_TRAP;
+    }
+    return CP_ACCESS_OK;
+}
+
+static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx)
+{
+    /* CNT[PV]CT: not visible from PL0 if ELO[PV]CTEN is zero */
+    if (arm_current_pl(env) == 0 &&
+        !extract32(env->cp15.c14_cntkctl, timeridx, 1)) {
+        return CP_ACCESS_TRAP;
+    }
+    return CP_ACCESS_OK;
+}
+
+static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx)
+{
+    /* CNT[PV]_CVAL, CNT[PV]_CTL, CNT[PV]_TVAL: not visible from PL0 if
+     * EL0[PV]TEN is zero.
+     */
+    if (arm_current_pl(env) == 0 &&
+        !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
+        return CP_ACCESS_TRAP;
+    }
+    return CP_ACCESS_OK;
+}
+
+static CPAccessResult gt_pct_access(CPUARMState *env,
+                                         const ARMCPRegInfo *ri)
+{
+    return gt_counter_access(env, GTIMER_PHYS);
+}
+
+static CPAccessResult gt_vct_access(CPUARMState *env,
+                                         const ARMCPRegInfo *ri)
+{
+    return gt_counter_access(env, GTIMER_VIRT);
+}
+
+static CPAccessResult gt_ptimer_access(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    return gt_timer_access(env, GTIMER_PHYS);
+}
+
+static CPAccessResult gt_vtimer_access(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    return gt_timer_access(env, GTIMER_VIRT);
+}
+
 static uint64_t gt_get_countervalue(CPUARMState *env)
 {
     return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / GTIMER_SCALE;
@@ -788,17 +841,6 @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
     }
 }
 
-static int gt_cntfrq_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                          uint64_t *value)
-{
-    /* Not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero */
-    if (arm_current_pl(env) == 0 && !extract32(env->cp15.c14_cntkctl, 0, 2)) {
-        return EXCP_UDEF;
-    }
-    *value = env->cp15.c14_cntfrq;
-    return 0;
-}
-
 static void gt_cnt_reset(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     ARMCPU *cpu = arm_env_get_cpu(env);
@@ -810,29 +852,10 @@ static void gt_cnt_reset(CPUARMState *env, const ARMCPRegInfo *ri)
 static int gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri,
                        uint64_t *value)
 {
-    int timeridx = ri->opc1 & 1;
-
-    if (arm_current_pl(env) == 0 &&
-        !extract32(env->cp15.c14_cntkctl, timeridx, 1)) {
-        return EXCP_UDEF;
-    }
     *value = gt_get_countervalue(env);
     return 0;
 }
 
-static int gt_cval_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                        uint64_t *value)
-{
-    int timeridx = ri->opc1 & 1;
-
-    if (arm_current_pl(env) == 0 &&
-        !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
-        return EXCP_UDEF;
-    }
-    *value = env->cp15.c14_timer[timeridx].cval;
-    return 0;
-}
-
 static int gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
                          uint64_t value)
 {
@@ -847,10 +870,6 @@ static int gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
 {
     int timeridx = ri->crm & 1;
 
-    if (arm_current_pl(env) == 0 &&
-        !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
-        return EXCP_UDEF;
-    }
     *value = (uint32_t)(env->cp15.c14_timer[timeridx].cval -
                         gt_get_countervalue(env));
     return 0;
@@ -867,19 +886,6 @@ static int gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
     return 0;
 }
 
-static int gt_ctl_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                       uint64_t *value)
-{
-    int timeridx = ri->crm & 1;
-
-    if (arm_current_pl(env) == 0 &&
-        !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
-        return EXCP_UDEF;
-    }
-    *value = env->cp15.c14_timer[timeridx].ctl;
-    return 0;
-}
-
 static int gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
                         uint64_t value)
 {
@@ -924,7 +930,7 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
       .access = PL1_RW | PL0_R,
       .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
       .resetvalue = (1000 * 1000 * 1000) / GTIMER_SCALE,
-      .readfn = gt_cntfrq_read, .raw_readfn = raw_read,
+      .accessfn = gt_cntfrq_access,
     },
     /* overall control: mostly access permissions */
     { .name = "CNTKCTL", .cp = 15, .crn = 14, .crm = 1, .opc1 = 0, .opc2 = 0,
@@ -937,32 +943,36 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
       .type = ARM_CP_IO, .access = PL1_RW | PL0_R,
       .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
       .resetvalue = 0,
-      .readfn = gt_ctl_read, .writefn = gt_ctl_write,
-      .raw_readfn = raw_read, .raw_writefn = raw_write,
+      .accessfn = gt_ptimer_access,
+      .writefn = gt_ctl_write, .raw_writefn = raw_write,
     },
     { .name = "CNTV_CTL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 1,
       .type = ARM_CP_IO, .access = PL1_RW | PL0_R,
       .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
       .resetvalue = 0,
-      .readfn = gt_ctl_read, .writefn = gt_ctl_write,
-      .raw_readfn = raw_read, .raw_writefn = raw_write,
+      .accessfn = gt_vtimer_access,
+      .writefn = gt_ctl_write, .raw_writefn = raw_write,
     },
     /* TimerValue views: a 32 bit downcounting view of the underlying state */
     { .name = "CNTP_TVAL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 0,
       .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R,
+      .accessfn = gt_ptimer_access,
       .readfn = gt_tval_read, .writefn = gt_tval_write,
     },
     { .name = "CNTV_TVAL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 0,
       .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R,
+      .accessfn = gt_vtimer_access,
       .readfn = gt_tval_read, .writefn = gt_tval_write,
     },
     /* The counter itself */
     { .name = "CNTPCT", .cp = 15, .crm = 14, .opc1 = 0,
       .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE | ARM_CP_IO,
+      .accessfn = gt_pct_access,
       .readfn = gt_cnt_read, .resetfn = gt_cnt_reset,
     },
     { .name = "CNTVCT", .cp = 15, .crm = 14, .opc1 = 1,
       .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE | ARM_CP_IO,
+      .accessfn = gt_vct_access,
       .readfn = gt_cnt_read, .resetfn = gt_cnt_reset,
     },
     /* Comparison value, indicating when the timer goes off */
@@ -971,16 +981,16 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
       .type = ARM_CP_64BIT | ARM_CP_IO,
       .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
       .resetvalue = 0,
-      .readfn = gt_cval_read, .writefn = gt_cval_write,
-      .raw_readfn = raw_read, .raw_writefn = raw_write,
+      .accessfn = gt_ptimer_access,
+      .writefn = gt_cval_write, .raw_writefn = raw_write,
     },
     { .name = "CNTV_CVAL", .cp = 15, .crm = 14, .opc1 = 3,
       .access = PL1_RW | PL0_R,
       .type = ARM_CP_64BIT | ARM_CP_IO,
       .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
       .resetvalue = 0,
-      .readfn = gt_cval_read, .writefn = gt_cval_write,
-      .raw_readfn = raw_read, .raw_writefn = raw_write,
+      .accessfn = gt_vtimer_access,
+      .writefn = gt_cval_write, .raw_writefn = raw_write,
     },
     REGINFO_SENTINEL
 };
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 14/35] target-arm: Convert miscellaneous reginfo structs to accessfn
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (12 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 13/35] target-arm: Convert generic timer reginfo to accessfn Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-09  3:09   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 15/35] target-arm: Drop success/fail return from cpreg read and write functions Peter Maydell
                   ` (22 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Convert the remaining miscellaneous cases of reginfo read/write
functions returning EXCP_UDEF to use an accessfn instead:
TEEHBR, and the ATS address-translation operations.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/helper.c | 44 +++++++++++++++++++-------------------------
 1 file changed, 19 insertions(+), 25 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index edff2e7..664ac92 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -682,27 +682,12 @@ static int teecr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
     return 0;
 }
 
-static int teehbr_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                       uint64_t *value)
+static CPAccessResultg teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    /* This is a helper function because the user access rights
-     * depend on the value of the TEECR.
-     */
     if (arm_current_pl(env) == 0 && (env->teecr & 1)) {
-        return EXCP_UDEF;
-    }
-    *value = env->teehbr;
-    return 0;
-}
-
-static int teehbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                        uint64_t value)
-{
-    if (arm_current_pl(env) == 0 && (env->teecr & 1)) {
-        return EXCP_UDEF;
+        return CP_ACCESS_TRAP;
     }
-    env->teehbr = value;
-    return 0;
+    return CP_ACCESS_OK;
 }
 
 static const ARMCPRegInfo t2ee_cp_reginfo[] = {
@@ -712,8 +697,7 @@ static const ARMCPRegInfo t2ee_cp_reginfo[] = {
       .writefn = teecr_write },
     { .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
       .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr),
-      .resetvalue = 0, .raw_readfn = raw_read, .raw_writefn = raw_write,
-      .readfn = teehbr_read, .writefn = teehbr_write },
+      .accessfn = teehbr_access, .resetvalue = 0 },
     REGINFO_SENTINEL
 };
 
@@ -1031,6 +1015,19 @@ static inline bool extended_addresses_enabled(CPUARMState *env)
         && (env->cp15.c2_control & (1U << 31));
 }
 
+static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    if (ri->opc2 & 4) {
+        /* Other states are only available with TrustZone; in
+         * a non-TZ implementation these registers don't exist
+         * at all, which is an Uncategorized trap. This underdecoding
+         * is safe because the reginfo is NO_MIGRATE.
+         */
+        return CP_ACCESS_TRAP_UNCATEGORIZED;
+    }
+    return CP_ACCESS_OK;
+}
+
 static int ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
 {
     hwaddr phys_addr;
@@ -1039,10 +1036,6 @@ static int ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
     int ret, is_user = ri->opc2 & 2;
     int access_type = ri->opc2 & 1;
 
-    if (ri->opc2 & 4) {
-        /* Other states are only available with TrustZone */
-        return EXCP_UDEF;
-    }
     ret = get_phys_addr(env, value, access_type, is_user,
                         &phys_addr, &prot, &page_size);
     if (extended_addresses_enabled(env)) {
@@ -1095,7 +1088,8 @@ static const ARMCPRegInfo vapa_cp_reginfo[] = {
       .writefn = par_write },
 #ifndef CONFIG_USER_ONLY
     { .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY,
-      .access = PL1_W, .writefn = ats_write, .type = ARM_CP_NO_MIGRATE },
+      .access = PL1_W, .accessfn = ats_access,
+      .writefn = ats_write, .type = ARM_CP_NO_MIGRATE },
 #endif
     REGINFO_SENTINEL
 };
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 15/35] target-arm: Drop success/fail return from cpreg read and write functions
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (13 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 14/35] target-arm: Convert miscellaneous reginfo structs " Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-09  3:27   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 16/35] target-arm: Remove unnecessary code now read/write fns can't fail Peter Maydell
                   ` (21 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

All cpreg read and write functions now return 0, so we can clean up
their prototypes:
 * write functions return void
 * read functions return the value rather than taking a pointer
   to write the value to

This is a fairly mechanical change which makes only the bare
minimum set of changes to the callers of read and write functions.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/pxa2xx.c        |  36 +++----
 hw/arm/pxa2xx_pic.c    |  11 +-
 target-arm/cpu.c       |   6 +-
 target-arm/cpu.h       |  23 ++--
 target-arm/helper.c    | 288 ++++++++++++++++++++-----------------------------
 target-arm/op_helper.c |  24 +----
 6 files changed, 150 insertions(+), 238 deletions(-)

diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 02b7016..bf9416a 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -224,27 +224,24 @@ static const VMStateDescription vmstate_pxa2xx_cm = {
     }
 };
 
-static int pxa2xx_clkcfg_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                              uint64_t *value)
+static uint64_t pxa2xx_clkcfg_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     PXA2xxState *s = (PXA2xxState *)ri->opaque;
-    *value = s->clkcfg;
-    return 0;
+    return s->clkcfg;
 }
 
-static int pxa2xx_clkcfg_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                               uint64_t value)
+static void pxa2xx_clkcfg_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                                uint64_t value)
 {
     PXA2xxState *s = (PXA2xxState *)ri->opaque;
     s->clkcfg = value & 0xf;
     if (value & 2) {
         printf("%s: CPU frequency change attempt\n", __func__);
     }
-    return 0;
 }
 
-static int pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                                uint64_t value)
+static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                                 uint64_t value)
 {
     PXA2xxState *s = (PXA2xxState *)ri->opaque;
     static const char *pwrmode[8] = {
@@ -310,36 +307,29 @@ static int pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
         printf("%s: machine entered %s mode\n", __func__,
                pwrmode[value & 7]);
     }
-
-    return 0;
 }
 
-static int pxa2xx_cppmnc_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                              uint64_t *value)
+static uint64_t pxa2xx_cppmnc_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     PXA2xxState *s = (PXA2xxState *)ri->opaque;
-    *value = s->pmnc;
-    return 0;
+    return s->pmnc;
 }
 
-static int pxa2xx_cppmnc_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                               uint64_t value)
+static void pxa2xx_cppmnc_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                                uint64_t value)
 {
     PXA2xxState *s = (PXA2xxState *)ri->opaque;
     s->pmnc = value;
-    return 0;
 }
 
-static int pxa2xx_cpccnt_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                              uint64_t *value)
+static uint64_t pxa2xx_cpccnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     PXA2xxState *s = (PXA2xxState *)ri->opaque;
     if (s->pmnc & 1) {
-        *value = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+        return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     } else {
-        *value = 0;
+        return 0;
     }
-    return 0;
 }
 
 static const ARMCPRegInfo pxa_cp_reginfo[] = {
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
index 46d337c..345fa4a 100644
--- a/hw/arm/pxa2xx_pic.c
+++ b/hw/arm/pxa2xx_pic.c
@@ -217,20 +217,17 @@ static const int pxa2xx_cp_reg_map[0x10] = {
     [0xa] = ICPR2,
 };
 
-static int pxa2xx_pic_cp_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                              uint64_t *value)
+static uint64_t pxa2xx_pic_cp_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     int offset = pxa2xx_cp_reg_map[ri->crn];
-    *value = pxa2xx_pic_mem_read(ri->opaque, offset, 4);
-    return 0;
+    return pxa2xx_pic_mem_read(ri->opaque, offset, 4);
 }
 
-static int pxa2xx_pic_cp_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                               uint64_t value)
+static void pxa2xx_pic_cp_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                                uint64_t value)
 {
     int offset = pxa2xx_cp_reg_map[ri->crn];
     pxa2xx_pic_mem_write(ri->opaque, offset, value, 4);
-    return 0;
 }
 
 #define REGINFO_FOR_PIC_CP(NAME, CRN) \
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 3014e86..fe18b65 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -681,14 +681,12 @@ static void cortex_a9_initfn(Object *obj)
 }
 
 #ifndef CONFIG_USER_ONLY
-static int a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                           uint64_t *value)
+static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     /* Linux wants the number of processors from here.
      * Might as well set the interrupt-controller bit too.
      */
-    *value = ((smp_cpus - 1) << 24) | (1 << 23);
-    return 0;
+    return ((smp_cpus - 1) << 24) | (1 << 23);
 }
 #endif
 
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 30b1a1c..d1ed423 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -828,11 +828,12 @@ typedef enum CPAccessResult {
     CP_ACCESS_TRAP_UNCATEGORIZED = 2,
 } CPAccessResult;
 
-/* Access functions for coprocessor registers. These should always succeed. */
-typedef int CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque,
-                     uint64_t *value);
-typedef int CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
-                      uint64_t value);
+/* Access functions for coprocessor registers. These cannot fail and
+ * may not raise exceptions.
+ */
+typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque);
+typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
+                       uint64_t value);
 /* Access permission check functions for coprocessor registers. */
 typedef CPAccessResult CPAccessFn(CPUARMState *env, const ARMCPRegInfo *opaque);
 /* Hook function for register reset */
@@ -907,14 +908,14 @@ struct ARMCPRegInfo {
     /* Function for doing a "raw" read; used when we need to copy
      * coprocessor state to the kernel for KVM or out for
      * migration. This only needs to be provided if there is also a
-     * readfn and it makes an access permission check.
+     * readfn and it has side effects (for instance clear-on-read bits).
      */
     CPReadFn *raw_readfn;
     /* Function for doing a "raw" write; used when we need to copy KVM
      * kernel coprocessor state into userspace, or for inbound
      * migration. This only needs to be provided if there is also a
-     * writefn and it makes an access permission check or masks out
-     * "unwritable" bits or has write-one-to-clear or similar behaviour.
+     * writefn and it masks out "unwritable" bits or has write-one-to-clear
+     * or similar behaviour.
      */
     CPWriteFn *raw_writefn;
     /* Function for resetting the register. If NULL, then reset will be done
@@ -949,10 +950,10 @@ static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
 const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp);
 
 /* CPWriteFn that can be used to implement writes-ignored behaviour */
-int arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
-                        uint64_t value);
+void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
+                         uint64_t value);
 /* CPReadFn that can be used for read-as-zero behaviour */
-int arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t *value);
+uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri);
 
 /* CPResetFn that does nothing, for use if no reset is required even
  * if fieldoffset is non zero.
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 664ac92..10aeccc 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -107,26 +107,23 @@ static int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
     }
 }
 
-static int raw_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                    uint64_t *value)
+static uint64_t raw_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     if (cpreg_field_is_64bit(ri)) {
-        *value = CPREG_FIELD64(env, ri);
+        return CPREG_FIELD64(env, ri);
     } else {
-        *value = CPREG_FIELD32(env, ri);
+        return CPREG_FIELD32(env, ri);
     }
-    return 0;
 }
 
-static int raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                     uint64_t value)
+static void raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                      uint64_t value)
 {
     if (cpreg_field_is_64bit(ri)) {
         CPREG_FIELD64(env, ri) = value;
     } else {
         CPREG_FIELD32(env, ri) = value;
     }
-    return 0;
 }
 
 static bool read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -138,11 +135,11 @@ static bool read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
     if (ri->type & ARM_CP_CONST) {
         *v = ri->resetvalue;
     } else if (ri->raw_readfn) {
-        return (ri->raw_readfn(env, ri, v) == 0);
+        *v = ri->raw_readfn(env, ri);
     } else if (ri->readfn) {
-        return (ri->readfn(env, ri, v) == 0);
+        *v = ri->readfn(env, ri);
     } else {
-        raw_read(env, ri, v);
+        *v = raw_read(env, ri);
     }
     return true;
 }
@@ -159,9 +156,9 @@ static bool write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
     if (ri->type & ARM_CP_CONST) {
         return true;
     } else if (ri->raw_writefn) {
-        return (ri->raw_writefn(env, ri, v) == 0);
+        ri->raw_writefn(env, ri, v);
     } else if (ri->writefn) {
-        return (ri->writefn(env, ri, v) == 0);
+        ri->writefn(env, ri, v);
     } else {
         raw_write(env, ri, v);
     }
@@ -309,14 +306,13 @@ void init_cpreg_list(ARMCPU *cpu)
     g_list_free(keys);
 }
 
-static int dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
 {
     env->cp15.c3 = value;
     tlb_flush(env, 1); /* Flush TLB as domain not tracked in TLB */
-    return 0;
 }
 
-static int fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
 {
     if (env->cp15.c13_fcse != value) {
         /* Unlike real hardware the qemu TLB uses virtual addresses,
@@ -325,10 +321,10 @@ static int fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
         tlb_flush(env, 1);
         env->cp15.c13_fcse = value;
     }
-    return 0;
 }
-static int contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                            uint64_t value)
+
+static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                             uint64_t value)
 {
     if (env->cp15.c13_context != value && !arm_feature(env, ARM_FEATURE_MPU)) {
         /* For VMSA (when not using the LPAE long descriptor page table
@@ -338,39 +334,34 @@ static int contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
         tlb_flush(env, 1);
     }
     env->cp15.c13_context = value;
-    return 0;
 }
 
-static int tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                         uint64_t value)
+static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                          uint64_t value)
 {
     /* Invalidate all (TLBIALL) */
     tlb_flush(env, 1);
-    return 0;
 }
 
-static int tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                         uint64_t value)
+static void tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                          uint64_t value)
 {
     /* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */
     tlb_flush_page(env, value & TARGET_PAGE_MASK);
-    return 0;
 }
 
-static int tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                          uint64_t value)
+static void tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                           uint64_t value)
 {
     /* Invalidate by ASID (TLBIASID) */
     tlb_flush(env, value == 0);
-    return 0;
 }
 
-static int tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                          uint64_t value)
+static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                           uint64_t value)
 {
     /* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */
     tlb_flush_page(env, value & TARGET_PAGE_MASK);
-    return 0;
 }
 
 static const ARMCPRegInfo cp_reginfo[] = {
@@ -450,14 +441,14 @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
-static int cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                        uint64_t value)
 {
     if (env->cp15.c1_coproc != value) {
         env->cp15.c1_coproc = value;
         /* ??? Is this safe when called from within a TB?  */
         tb_flush(env);
     }
-    return 0;
 }
 
 static const ARMCPRegInfo v6_cp_reginfo[] = {
@@ -496,89 +487,77 @@ static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri)
     return CP_ACCESS_OK;
 }
 
-static int pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                      uint64_t value)
+static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                       uint64_t value)
 {
     /* only the DP, X, D and E bits are writable */
     env->cp15.c9_pmcr &= ~0x39;
     env->cp15.c9_pmcr |= (value & 0x39);
-    return 0;
 }
 
-static int pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
+static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
                             uint64_t value)
 {
     value &= (1 << 31);
     env->cp15.c9_pmcnten |= value;
-    return 0;
 }
 
-static int pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                            uint64_t value)
+static void pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                             uint64_t value)
 {
     value &= (1 << 31);
     env->cp15.c9_pmcnten &= ~value;
-    return 0;
 }
 
-static int pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                        uint64_t value)
+static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                         uint64_t value)
 {
     env->cp15.c9_pmovsr &= ~value;
-    return 0;
 }
 
-static int pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                            uint64_t value)
+static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                             uint64_t value)
 {
     env->cp15.c9_pmxevtyper = value & 0xff;
-    return 0;
 }
 
-static int pmuserenr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+static void pmuserenr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                             uint64_t value)
 {
     env->cp15.c9_pmuserenr = value & 1;
-    return 0;
 }
 
-static int pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                            uint64_t value)
+static void pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                             uint64_t value)
 {
     /* We have no event counters so only the C bit can be changed */
     value &= (1 << 31);
     env->cp15.c9_pminten |= value;
-    return 0;
 }
 
-static int pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                            uint64_t value)
+static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                             uint64_t value)
 {
     value &= (1 << 31);
     env->cp15.c9_pminten &= ~value;
-    return 0;
 }
 
-static int vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                      uint64_t value)
+static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                       uint64_t value)
 {
     env->cp15.c12_vbar = value & ~0x1Ful;
-    return 0;
 }
 
-static int ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                       uint64_t *value)
+static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     ARMCPU *cpu = arm_env_get_cpu(env);
-    *value = cpu->ccsidr[env->cp15.c0_cssel];
-    return 0;
+    return cpu->ccsidr[env->cp15.c0_cssel];
 }
 
-static int csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                        uint64_t value)
+static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                         uint64_t value)
 {
     env->cp15.c0_cssel = value & 0xf;
-    return 0;
 }
 
 static const ARMCPRegInfo v7_cp_reginfo[] = {
@@ -675,14 +654,14 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
-static int teecr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                        uint64_t value)
 {
     value &= 1;
     env->teecr = value;
-    return 0;
 }
 
-static CPAccessResultg teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri)
+static CPAccessResult teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     if (arm_current_pl(env) == 0 && (env->teecr & 1)) {
         return CP_ACCESS_TRAP;
@@ -833,45 +812,40 @@ static void gt_cnt_reset(CPUARMState *env, const ARMCPRegInfo *ri)
     timer_del(cpu->gt_timer[timeridx]);
 }
 
-static int gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                       uint64_t *value)
+static uint64_t gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    *value = gt_get_countervalue(env);
-    return 0;
+    return gt_get_countervalue(env);
 }
 
-static int gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                         uint64_t value)
+static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                          uint64_t value)
 {
     int timeridx = ri->opc1 & 1;
 
     env->cp15.c14_timer[timeridx].cval = value;
     gt_recalc_timer(arm_env_get_cpu(env), timeridx);
-    return 0;
 }
-static int gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                        uint64_t *value)
+
+static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     int timeridx = ri->crm & 1;
 
-    *value = (uint32_t)(env->cp15.c14_timer[timeridx].cval -
-                        gt_get_countervalue(env));
-    return 0;
+    return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
+                      gt_get_countervalue(env));
 }
 
-static int gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                         uint64_t value)
+static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                          uint64_t value)
 {
     int timeridx = ri->crm & 1;
 
     env->cp15.c14_timer[timeridx].cval = gt_get_countervalue(env) +
         + sextract64(value, 0, 32);
     gt_recalc_timer(arm_env_get_cpu(env), timeridx);
-    return 0;
 }
 
-static int gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                        uint64_t value)
+static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                         uint64_t value)
 {
     ARMCPU *cpu = arm_env_get_cpu(env);
     int timeridx = ri->crm & 1;
@@ -888,7 +862,6 @@ static int gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
         qemu_set_irq(cpu->gt_timer_outputs[timeridx],
                      (oldval & 4) && (value & 2));
     }
-    return 0;
 }
 
 void arm_gt_ptimer_cb(void *opaque)
@@ -990,7 +963,7 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
 
 #endif
 
-static int par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
 {
     if (arm_feature(env, ARM_FEATURE_LPAE)) {
         env->cp15.c7_par = value;
@@ -999,7 +972,6 @@ static int par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
     } else {
         env->cp15.c7_par = value & 0xfffff1ff;
     }
-    return 0;
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -1028,7 +1000,7 @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri)
     return CP_ACCESS_OK;
 }
 
-static int ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
 {
     hwaddr phys_addr;
     target_ulong page_size;
@@ -1077,7 +1049,6 @@ static int ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
         }
         env->cp15.c7_par_hi = 0;
     }
-    return 0;
 }
 #endif
 
@@ -1124,32 +1095,26 @@ static uint32_t extended_mpu_ap_bits(uint32_t val)
     return ret;
 }
 
-static int pmsav5_data_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                                uint64_t value)
+static void pmsav5_data_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                                 uint64_t value)
 {
     env->cp15.c5_data = extended_mpu_ap_bits(value);
-    return 0;
 }
 
-static int pmsav5_data_ap_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                               uint64_t *value)
+static uint64_t pmsav5_data_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    *value = simple_mpu_ap_bits(env->cp15.c5_data);
-    return 0;
+    return simple_mpu_ap_bits(env->cp15.c5_data);
 }
 
-static int pmsav5_insn_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                                uint64_t value)
+static void pmsav5_insn_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                                 uint64_t value)
 {
     env->cp15.c5_insn = extended_mpu_ap_bits(value);
-    return 0;
 }
 
-static int pmsav5_insn_ap_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                               uint64_t *value)
+static uint64_t pmsav5_insn_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    *value = simple_mpu_ap_bits(env->cp15.c5_insn);
-    return 0;
+    return simple_mpu_ap_bits(env->cp15.c5_insn);
 }
 
 static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
@@ -1201,8 +1166,8 @@ static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
-static int vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                                uint64_t value)
+static void vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                                 uint64_t value)
 {
     int maskshift = extract32(value, 0, 3);
 
@@ -1219,11 +1184,10 @@ static int vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
     env->cp15.c2_control = value;
     env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> maskshift);
     env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> maskshift);
-    return 0;
 }
 
-static int vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                            uint64_t value)
+static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                             uint64_t value)
 {
     if (arm_feature(env, ARM_FEATURE_LPAE)) {
         /* With LPAE the TTBCR could result in a change of ASID
@@ -1231,7 +1195,7 @@ static int vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
          */
         tlb_flush(env, 1);
     }
-    return vmsa_ttbcr_raw_write(env, ri, value);
+    vmsa_ttbcr_raw_write(env, ri, value);
 }
 
 static void vmsa_ttbcr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
@@ -1264,40 +1228,36 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
-static int omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                               uint64_t value)
+static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                                uint64_t value)
 {
     env->cp15.c15_ticonfig = value & 0xe7;
     /* The OS_TYPE bit in this register changes the reported CPUID! */
     env->cp15.c0_cpuid = (value & (1 << 5)) ?
         ARM_CPUID_TI915T : ARM_CPUID_TI925T;
-    return 0;
 }
 
-static int omap_threadid_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                               uint64_t value)
+static void omap_threadid_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                                uint64_t value)
 {
     env->cp15.c15_threadid = value & 0xffff;
-    return 0;
 }
 
-static int omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                          uint64_t value)
+static void omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                           uint64_t value)
 {
     /* Wait-for-interrupt (deprecated) */
     cpu_interrupt(CPU(arm_env_get_cpu(env)), CPU_INTERRUPT_HALT);
-    return 0;
 }
 
-static int omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                                 uint64_t value)
+static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                                  uint64_t value)
 {
     /* On OMAP there are registers indicating the max/min index of dcache lines
      * containing a dirty line; cache flush operations have to reset these.
      */
     env->cp15.c15_i_max = 0x000;
     env->cp15.c15_i_min = 0xff0;
-    return 0;
 }
 
 static const ARMCPRegInfo omap_cp_reginfo[] = {
@@ -1339,8 +1299,8 @@ static const ARMCPRegInfo omap_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
-static int xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                             uint64_t value)
+static void xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                              uint64_t value)
 {
     value &= 0x3fff;
     if (env->cp15.c15_cpar != value) {
@@ -1348,7 +1308,6 @@ static int xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri,
         tb_flush(env);
         env->cp15.c15_cpar = value;
     }
-    return 0;
 }
 
 static const ARMCPRegInfo xscale_cp_reginfo[] = {
@@ -1428,8 +1387,7 @@ static const ARMCPRegInfo strongarm_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
-static int mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                      uint64_t *value)
+static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     CPUState *cs = CPU(arm_env_get_cpu(env));
     uint32_t mpidr = cs->cpu_index;
@@ -1444,8 +1402,7 @@ static int mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri,
          * not currently model any of those cores.
          */
     }
-    *value = mpidr;
-    return 0;
+    return mpidr;
 }
 
 static const ARMCPRegInfo mpidr_cp_reginfo[] = {
@@ -1454,17 +1411,16 @@ static const ARMCPRegInfo mpidr_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
-static int par64_read(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t *value)
+static uint64_t par64_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    *value = ((uint64_t)env->cp15.c7_par_hi << 32) | env->cp15.c7_par;
-    return 0;
+    return ((uint64_t)env->cp15.c7_par_hi << 32) | env->cp15.c7_par;
 }
 
-static int par64_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void par64_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                        uint64_t value)
 {
     env->cp15.c7_par_hi = value >> 32;
     env->cp15.c7_par = value;
-    return 0;
 }
 
 static void par64_reset(CPUARMState *env, const ARMCPRegInfo *ri)
@@ -1473,27 +1429,24 @@ static void par64_reset(CPUARMState *env, const ARMCPRegInfo *ri)
     env->cp15.c7_par = 0;
 }
 
-static int ttbr064_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                        uint64_t *value)
+static uint64_t ttbr064_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    *value = ((uint64_t)env->cp15.c2_base0_hi << 32) | env->cp15.c2_base0;
-    return 0;
+    return ((uint64_t)env->cp15.c2_base0_hi << 32) | env->cp15.c2_base0;
 }
 
-static int ttbr064_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                             uint64_t value)
+static void ttbr064_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                              uint64_t value)
 {
     env->cp15.c2_base0_hi = value >> 32;
     env->cp15.c2_base0 = value;
-    return 0;
 }
 
-static int ttbr064_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                         uint64_t value)
+static void ttbr064_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                          uint64_t value)
 {
     /* Writes to the 64 bit format TTBRs may change the ASID */
     tlb_flush(env, 1);
-    return ttbr064_raw_write(env, ri, value);
+    ttbr064_raw_write(env, ri, value);
 }
 
 static void ttbr064_reset(CPUARMState *env, const ARMCPRegInfo *ri)
@@ -1502,19 +1455,16 @@ static void ttbr064_reset(CPUARMState *env, const ARMCPRegInfo *ri)
     env->cp15.c2_base0 = 0;
 }
 
-static int ttbr164_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                        uint64_t *value)
+static uint64_t ttbr164_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    *value = ((uint64_t)env->cp15.c2_base1_hi << 32) | env->cp15.c2_base1;
-    return 0;
+    return ((uint64_t)env->cp15.c2_base1_hi << 32) | env->cp15.c2_base1;
 }
 
-static int ttbr164_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                         uint64_t value)
+static void ttbr164_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                          uint64_t value)
 {
     env->cp15.c2_base1_hi = value >> 32;
     env->cp15.c2_base1 = value;
-    return 0;
 }
 
 static void ttbr164_reset(CPUARMState *env, const ARMCPRegInfo *ri)
@@ -1551,32 +1501,26 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
-static int aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                          uint64_t *value)
+static uint64_t aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    *value = vfp_get_fpcr(env);
-    return 0;
+    return vfp_get_fpcr(env);
 }
 
-static int aa64_fpcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                           uint64_t value)
+static void aa64_fpcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                            uint64_t value)
 {
     vfp_set_fpcr(env, value);
-    return 0;
 }
 
-static int aa64_fpsr_read(CPUARMState *env, const ARMCPRegInfo *ri,
-                          uint64_t *value)
+static uint64_t aa64_fpsr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    *value = vfp_get_fpsr(env);
-    return 0;
+    return vfp_get_fpsr(env);
 }
 
-static int aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                           uint64_t value)
+static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                            uint64_t value)
 {
     vfp_set_fpsr(env, value);
-    return 0;
 }
 
 static const ARMCPRegInfo v8_cp_reginfo[] = {
@@ -1609,13 +1553,13 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
-static int sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
+static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                        uint64_t value)
 {
     env->cp15.c1_sys = value;
     /* ??? Lots of these bits are not implemented.  */
     /* This may enable/disable the MMU, so do a TLB flush.  */
     tlb_flush(env, 1);
-    return 0;
 }
 
 void register_cp_regs_for_features(ARMCPU *cpu)
@@ -2193,17 +2137,15 @@ const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
     return g_hash_table_lookup(cpregs, &encoded_cp);
 }
 
-int arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
-                        uint64_t value)
+void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
+                         uint64_t value)
 {
     /* Helper coprocessor write function for write-ignore registers */
-    return 0;
 }
 
-int arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t *value)
+uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     /* Helper coprocessor write function for read-as-zero registers */
-    *value = 0;
     return 0;
 }
 
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 89b0978..0c1b37a 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -294,41 +294,25 @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip)
 void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)
 {
     const ARMCPRegInfo *ri = rip;
-    int excp = ri->writefn(env, ri, value);
-    if (excp) {
-        raise_exception(env, excp);
-    }
+    ri->writefn(env, ri, value);
 }
 
 uint32_t HELPER(get_cp_reg)(CPUARMState *env, void *rip)
 {
     const ARMCPRegInfo *ri = rip;
-    uint64_t value;
-    int excp = ri->readfn(env, ri, &value);
-    if (excp) {
-        raise_exception(env, excp);
-    }
-    return value;
+    return ri->readfn(env, ri);
 }
 
 void HELPER(set_cp_reg64)(CPUARMState *env, void *rip, uint64_t value)
 {
     const ARMCPRegInfo *ri = rip;
-    int excp = ri->writefn(env, ri, value);
-    if (excp) {
-        raise_exception(env, excp);
-    }
+    ri->writefn(env, ri, value);
 }
 
 uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
 {
     const ARMCPRegInfo *ri = rip;
-    uint64_t value;
-    int excp = ri->readfn(env, ri, &value);
-    if (excp) {
-        raise_exception(env, excp);
-    }
-    return value;
+    return ri->readfn(env, ri);
 }
 
 void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 16/35] target-arm: Remove unnecessary code now read/write fns can't fail
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (14 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 15/35] target-arm: Drop success/fail return from cpreg read and write functions Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-09  3:29   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 17/35] target-arm: Remove failure status return from read/write_raw_cp_reg Peter Maydell
                   ` (20 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Now that cpreg read and write functions can't fail and throw an
exception, we can remove the code from the translator that synchronises
the guest PC in case an exception is thrown.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/translate-a64.c | 2 --
 target-arm/translate.c     | 4 ----
 2 files changed, 6 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index d90ffd1..f437359 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1248,7 +1248,6 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
             tcg_gen_movi_i64(tcg_rt, ri->resetvalue);
         } else if (ri->readfn) {
             TCGv_ptr tmpptr;
-            gen_a64_set_pc_im(s->pc - 4);
             tmpptr = tcg_const_ptr(ri);
             gen_helper_get_cp_reg64(tcg_rt, cpu_env, tmpptr);
             tcg_temp_free_ptr(tmpptr);
@@ -1261,7 +1260,6 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
             return;
         } else if (ri->writefn) {
             TCGv_ptr tmpptr;
-            gen_a64_set_pc_im(s->pc - 4);
             tmpptr = tcg_const_ptr(ri);
             gen_helper_set_cp_reg64(cpu_env, tmpptr, tcg_rt);
             tcg_temp_free_ptr(tmpptr);
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 2713081..8149a3b 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6837,7 +6837,6 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                     tmp64 = tcg_const_i64(ri->resetvalue);
                 } else if (ri->readfn) {
                     TCGv_ptr tmpptr;
-                    gen_set_pc_im(s, s->pc);
                     tmp64 = tcg_temp_new_i64();
                     tmpptr = tcg_const_ptr(ri);
                     gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
@@ -6860,7 +6859,6 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                     tmp = tcg_const_i32(ri->resetvalue);
                 } else if (ri->readfn) {
                     TCGv_ptr tmpptr;
-                    gen_set_pc_im(s, s->pc);
                     tmp = tcg_temp_new_i32();
                     tmpptr = tcg_const_ptr(ri);
                     gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
@@ -6895,7 +6893,6 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                 tcg_temp_free_i32(tmphi);
                 if (ri->writefn) {
                     TCGv_ptr tmpptr = tcg_const_ptr(ri);
-                    gen_set_pc_im(s, s->pc);
                     gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
                     tcg_temp_free_ptr(tmpptr);
                 } else {
@@ -6906,7 +6903,6 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                 if (ri->writefn) {
                     TCGv_i32 tmp;
                     TCGv_ptr tmpptr;
-                    gen_set_pc_im(s, s->pc);
                     tmp = load_reg(s, rt);
                     tmpptr = tcg_const_ptr(ri);
                     gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 17/35] target-arm: Remove failure status return from read/write_raw_cp_reg
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (15 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 16/35] target-arm: Remove unnecessary code now read/write fns can't fail Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-09  3:32   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 18/35] target-arm: Fix incorrect type for value argument to write_raw_cp_reg Peter Maydell
                   ` (19 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

The read_raw_cp_reg and write_raw_cp_reg functions can now never
fail (in fact they should never have failed previously unless
there was a bug in a reginfo that meant no raw accessor was
provided for a might-trap register). This allows us to clean up
their prototypes so the write function returns void and the
read function returns the value read, which in turn lets us
simplify the callers.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/helper.c | 36 ++++++++++++------------------------
 1 file changed, 12 insertions(+), 24 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 10aeccc..577b060 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -126,35 +126,30 @@ static void raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
     }
 }
 
-static bool read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
-                            uint64_t *v)
+static uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    /* Raw read of a coprocessor register (as needed for migration, etc)
-     * return true on success, false if the read is impossible for some reason.
-     */
+    /* Raw read of a coprocessor register (as needed for migration, etc). */
     if (ri->type & ARM_CP_CONST) {
-        *v = ri->resetvalue;
+        return ri->resetvalue;
     } else if (ri->raw_readfn) {
-        *v = ri->raw_readfn(env, ri);
+        return ri->raw_readfn(env, ri);
     } else if (ri->readfn) {
-        *v = ri->readfn(env, ri);
+        return ri->readfn(env, ri);
     } else {
-        *v = raw_read(env, ri);
+        return raw_read(env, ri);
     }
-    return true;
 }
 
-static bool write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
+static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
                              int64_t v)
 {
     /* Raw write of a coprocessor register (as needed for migration, etc).
-     * Return true on success, false if the write is impossible for some reason.
      * Note that constant registers are treated as write-ignored; the
      * caller should check for success by whether a readback gives the
      * value written.
      */
     if (ri->type & ARM_CP_CONST) {
-        return true;
+        return;
     } else if (ri->raw_writefn) {
         ri->raw_writefn(env, ri, v);
     } else if (ri->writefn) {
@@ -162,7 +157,6 @@ static bool write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
     } else {
         raw_write(env, ri, v);
     }
-    return true;
 }
 
 bool write_cpustate_to_list(ARMCPU *cpu)
@@ -174,7 +168,7 @@ bool write_cpustate_to_list(ARMCPU *cpu)
     for (i = 0; i < cpu->cpreg_array_len; i++) {
         uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
         const ARMCPRegInfo *ri;
-        uint64_t v;
+
         ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
         if (!ri) {
             ok = false;
@@ -183,11 +177,7 @@ bool write_cpustate_to_list(ARMCPU *cpu)
         if (ri->type & ARM_CP_NO_MIGRATE) {
             continue;
         }
-        if (!read_raw_cp_reg(&cpu->env, ri, &v)) {
-            ok = false;
-            continue;
-        }
-        cpu->cpreg_values[i] = v;
+        cpu->cpreg_values[i] = read_raw_cp_reg(&cpu->env, ri);
     }
     return ok;
 }
@@ -200,7 +190,6 @@ bool write_list_to_cpustate(ARMCPU *cpu)
     for (i = 0; i < cpu->cpreg_array_len; i++) {
         uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
         uint64_t v = cpu->cpreg_values[i];
-        uint64_t readback;
         const ARMCPRegInfo *ri;
 
         ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
@@ -215,9 +204,8 @@ bool write_list_to_cpustate(ARMCPU *cpu)
          * (to catch read-only registers and partially read-only
          * registers where the incoming migration value doesn't match)
          */
-        if (!write_raw_cp_reg(&cpu->env, ri, v) ||
-            !read_raw_cp_reg(&cpu->env, ri, &readback) ||
-            readback != v) {
+        write_raw_cp_reg(&cpu->env, ri, v);
+        if (read_raw_cp_reg(&cpu->env, ri) != v) {
             ok = false;
         }
     }
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 18/35] target-arm: Fix incorrect type for value argument to write_raw_cp_reg
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (16 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 17/35] target-arm: Remove failure status return from read/write_raw_cp_reg Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-05  7:07   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 19/35] target-arm: A64: Make cache ID registers visible to AArch64 Peter Maydell
                   ` (18 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

The write_raw_cp_reg's value argument should be a uint64_t, since
that's what all its callers hand it and what all the functions it
calls take. A (harmless) typo meant we were accidentally declaring
it as int64_t.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 577b060..06331dd 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -141,7 +141,7 @@ static uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri)
 }
 
 static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
-                             int64_t v)
+                             uint64_t v)
 {
     /* Raw write of a coprocessor register (as needed for migration, etc).
      * Note that constant registers are treated as write-ignored; the
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 19/35] target-arm: A64: Make cache ID registers visible to AArch64
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (17 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 18/35] target-arm: Fix incorrect type for value argument to write_raw_cp_reg Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-07  7:35   ` Hu Tao
  2014-02-09  2:15   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 20/35] target-arm: Implement AArch64 CurrentEL sysreg Peter Maydell
                   ` (17 subsequent siblings)
  36 siblings, 2 replies; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Make the cache ID system registers (CLIDR, CCSELR, CCSIDR, CTR)
visible to AArch64. These are mostly simple 64-bit extensions of the
existing 32 bit system registers and so can share reginfo definitions.
CTR needs to have a split definition, but we can clean up the
temporary user-mode implementation in favour of using the CPU-specified
reset value, and implement the system-mode-required semantics of
restricting its EL0 accessibility if SCTLR.UCT is not set.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.c    |  2 ++
 target-arm/cpu.h    |  2 +-
 target-arm/cpu64.c  |  1 +
 target-arm/helper.c | 31 +++++++++++++++++++++----------
 4 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index fe18b65..8fed098 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -91,6 +91,8 @@ static void arm_cpu_reset(CPUState *s)
         env->aarch64 = 1;
 #if defined(CONFIG_USER_ONLY)
         env->pstate = PSTATE_MODE_EL0t;
+        /* Userspace expects access to CTL_EL0 */
+        env->cp15.c1_sys |= SCTLR_UCT;
 #else
         env->pstate = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F
             | PSTATE_MODE_EL1h;
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index d1ed423..f5b706e 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -166,7 +166,7 @@ typedef struct CPUARMState {
     /* System control coprocessor (cp15) */
     struct {
         uint32_t c0_cpuid;
-        uint32_t c0_cssel; /* Cache size selection.  */
+        uint64_t c0_cssel; /* Cache size selection.  */
         uint32_t c1_sys; /* System control register.  */
         uint32_t c1_coproc; /* Coprocessor access register.  */
         uint32_t c1_xscaleauxcr; /* XScale auxiliary control register.  */
diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c
index a639c2e..8426bf1 100644
--- a/target-arm/cpu64.c
+++ b/target-arm/cpu64.c
@@ -45,6 +45,7 @@ static void aarch64_any_initfn(Object *obj)
     set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
     set_feature(&cpu->env, ARM_FEATURE_V7MP);
     set_feature(&cpu->env, ARM_FEATURE_AARCH64);
+    cpu->ctr = 0x80030003; /* 32 byte I and D cacheline size, VIPT icache */
 }
 #endif
 
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 06331dd..f46dd0f 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -629,9 +629,11 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
     { .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", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 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 },
-    { .name = "CSSELR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
+    { .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
       .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c0_cssel),
       .writefn = csselr_write, .resetvalue = 0 },
     /* Auxiliary ID register: this actually has an IMPDEF value but for now
@@ -1524,13 +1526,6 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
     { .name = "FPSR", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 4,
       .access = PL0_RW, .readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write },
-    /* This claims a 32 byte cacheline size for icache and dcache, VIPT icache.
-     * It will eventually need to have a CPU-specified reset value.
-     */
-    { .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,
-      .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,
-      .access = PL0_R, .type = ARM_CP_CONST,
-      .resetvalue = 0x80030003 },
     /* Prohibit use of DC ZVA. OPTME: implement DC ZVA and allow its use.
      * For system mode the DZP bit here will need to be computed, not constant.
      */
@@ -1550,6 +1545,17 @@ static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
     tlb_flush(env, 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)) {
+        return CP_ACCESS_TRAP;
+    }
+    return CP_ACCESS_OK;
+}
+
 void register_cp_regs_for_features(ARMCPU *cpu)
 {
     /* Register all the coprocessor registers based on feature bits */
@@ -1634,7 +1640,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
             .raw_writefn = raw_write,
         };
         ARMCPRegInfo clidr = {
-            .name = "CLIDR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
+            .name = "CLIDR", .state = ARM_CP_STATE_BOTH,
+            .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
             .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->clidr
         };
         define_one_arm_cp_reg(cpu, &pmcr);
@@ -1713,6 +1720,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
             { .name = "CTR",
               .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1,
               .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
+            { .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,
+              .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,
+              .access = PL0_R, .accessfn = ctr_el0_access,
+              .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
             { .name = "TCMTR",
               .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 2,
               .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 20/35] target-arm: Implement AArch64 CurrentEL sysreg
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (18 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 19/35] target-arm: A64: Make cache ID registers visible to AArch64 Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-09  2:17   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 21/35] target-arm: Implement AArch64 MIDR_EL1 Peter Maydell
                   ` (16 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Implement the CurrentEL sysreg.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.h           | 3 ++-
 target-arm/helper.c        | 3 +++
 target-arm/translate-a64.c | 7 +++++++
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index f5b706e..e0e3736 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -732,7 +732,8 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
 #define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8))
 #define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8))
 #define ARM_CP_NZCV (ARM_CP_SPECIAL | (3 << 8))
-#define ARM_LAST_SPECIAL ARM_CP_NZCV
+#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8))
+#define ARM_LAST_SPECIAL ARM_CP_CURRENTEL
 /* Used only as a terminator for ARMCPRegInfo lists */
 #define ARM_CP_SENTINEL 0xffff
 /* Mask of only the flag bits in a type field */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index f46dd0f..0538f78 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1533,6 +1533,9 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
       .opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0,
       .access = PL0_R, .type = ARM_CP_CONST,
       .resetvalue = 0x10 },
+    { .name = "CURRENTEL", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .opc2 = 2, .crn = 4, .crm = 2,
+      .access = PL1_R, .type = ARM_CP_CURRENTEL },
     REGINFO_SENTINEL
 };
 
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index f437359..fa8d7ac 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1233,6 +1233,13 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
             gen_set_nzcv(tcg_rt);
         }
         return;
+    case ARM_CP_CURRENTEL:
+        /* Reads as current EL value from pstate, which is
+         * guaranteed to be constant by the tb flags.
+         */
+        tcg_rt = cpu_reg(s, rt);
+        tcg_gen_movi_i64(tcg_rt, s->current_pl << 2);
+        return;
     default:
         break;
     }
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 21/35] target-arm: Implement AArch64 MIDR_EL1
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (19 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 20/35] target-arm: Implement AArch64 CurrentEL sysreg Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 22/35] target-arm: Implement AArch64 DAIF system register Peter Maydell
                   ` (15 subsequent siblings)
  36 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Implement the AArch64 view of the MIDR system register
(for AArch64 it is a simple constant, unlike the complicated
mess that TI925 imposes on the 32-bit view).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
 target-arm/helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 0538f78..f67cf5e 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1720,6 +1720,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
               .writefn = arm_cp_write_ignore, .raw_writefn = raw_write,
               .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
               .type = ARM_CP_OVERRIDE },
+            { .name = "MIDR_EL1", .state = ARM_CP_STATE_AA64,
+              .opc0 = 3, .opc1 = 0, .opc2 = 0, .crn = 0, .crm = 0,
+              .access = PL1_R, .resetvalue = cpu->midr, .type = ARM_CP_CONST },
             { .name = "CTR",
               .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1,
               .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 22/35] target-arm: Implement AArch64 DAIF system register
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (20 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 21/35] target-arm: Implement AArch64 MIDR_EL1 Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-09  2:20   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 23/35] target-arm: Implement AArch64 cache invalidate/clean ops Peter Maydell
                   ` (14 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Implement the DAIF system register which is a view of the
DAIF bits in PSTATE.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/helper.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index f67cf5e..82efbfa 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1513,6 +1513,26 @@ static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
     vfp_set_fpsr(env, value);
 }
 
+static CPAccessResult aa64_daif_access(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
+        return CP_ACCESS_TRAP;
+    }
+    return CP_ACCESS_OK;
+}
+
+static uint64_t aa64_daif_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    return pstate_read(env) & PSTATE_DAIF;
+}
+
+static void aa64_daif_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                            uint64_t value)
+{
+    env->pstate &= ~PSTATE_DAIF;
+    env->pstate |= (value & PSTATE_DAIF);
+}
+
 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.
@@ -1520,6 +1540,11 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
     { .name = "NZCV", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 2,
       .access = PL0_RW, .type = ARM_CP_NZCV },
+    { .name = "DAIF", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 2,
+      .access = PL0_RW, .type = ARM_CP_NO_MIGRATE,
+      .readfn = aa64_daif_read, .writefn = aa64_daif_write,
+      .accessfn = aa64_daif_access },
     { .name = "FPCR", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 4,
       .access = PL0_RW, .readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write },
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 23/35] target-arm: Implement AArch64 cache invalidate/clean ops
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (21 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 22/35] target-arm: Implement AArch64 DAIF system register Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-06 11:45   ` Peter Maydell
  2014-02-09  2:22   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 24/35] target-arm: Implement AArch64 TLB invalidate ops Peter Maydell
                   ` (13 subsequent siblings)
  36 siblings, 2 replies; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Implement all the AArch64 cache invalidate and clean ops
(which are all NOPs since QEMU doesn't emulate the cache).
The only remaining unimplemented cache op is DC ZVA.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/helper.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 82efbfa..b9ed707 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1533,6 +1533,18 @@ static void aa64_daif_write(CPUARMState *env, const ARMCPRegInfo *ri,
     env->pstate |= (value & PSTATE_DAIF);
 }
 
+static CPAccessResult aa64_cacheop_access(CPUARMState *env,
+                                          const ARMCPRegInfo *ri)
+{
+    /* 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)) {
+        return CP_ACCESS_TRAP;
+    }
+    return CP_ACCESS_OK;
+}
+
 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.
@@ -1561,6 +1573,41 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
     { .name = "CURRENTEL", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 0, .opc2 = 2, .crn = 4, .crm = 2,
       .access = PL1_R, .type = ARM_CP_CURRENTEL },
+    /* Cache ops: all NOPs since we don't emulate caches */
+    { .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
+      .access = PL1_W, .type = ARM_CP_NOP },
+    { .name = "IC_IALLU", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0,
+      .access = PL1_W, .type = ARM_CP_NOP },
+    { .name = "IC_IVAU", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1,
+      .access = PL0_W, .type = ARM_CP_NOP,
+      .accessfn = aa64_cacheop_access },
+    { .name = "DC_IVAC", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
+      .access = PL1_W, .type = ARM_CP_NOP },
+    { .name = "DC_ISW", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
+      .access = PL1_W, .type = ARM_CP_NOP },
+    { .name = "DC_CVAC", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1,
+      .access = PL0_W, .type = ARM_CP_NOP,
+      .accessfn = aa64_cacheop_access },
+    { .name = "DC_CSW", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
+      .access = PL1_W, .type = ARM_CP_NOP },
+    { .name = "DC_CVAU", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 11, .opc2 = 1,
+      .access = PL0_W, .type = ARM_CP_NOP,
+      .accessfn = aa64_cacheop_access },
+    { .name = "DC_CIVAC", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 1,
+      .access = PL0_W, .type = ARM_CP_NOP,
+      .accessfn = aa64_cacheop_access },
+    { .name = "DC_CISW", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
+      .access = PL1_W, .type = ARM_CP_NOP },
     REGINFO_SENTINEL
 };
 
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 24/35] target-arm: Implement AArch64 TLB invalidate ops
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (22 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 23/35] target-arm: Implement AArch64 cache invalidate/clean ops Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 25/35] target-arm: Implement AArch64 dummy MDSCR_EL1 Peter Maydell
                   ` (12 subsequent siblings)
  36 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Implement the AArch64 TLB invalidate operations. This is
the full set of TLBI ops defined for a CPU which doesn't
implement EL2 or EL3.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/helper.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index b9ed707..0dcb5b1 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1545,6 +1545,30 @@ static CPAccessResult aa64_cacheop_access(CPUARMState *env,
     return CP_ACCESS_OK;
 }
 
+static void tlbi_aa64_va_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                               uint64_t value)
+{
+    /* Invalidate by VA (AArch64 version) */
+    uint64_t pageaddr = value << 12;
+    tlb_flush_page(env, pageaddr);
+}
+
+static void tlbi_aa64_vaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                                uint64_t value)
+{
+    /* Invalidate by VA, all ASIDs (AArch64 version) */
+    uint64_t pageaddr = value << 12;
+    tlb_flush_page(env, pageaddr);
+}
+
+static void tlbi_aa64_asid_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                                 uint64_t value)
+{
+    /* Invalidate by ASID (AArch64 version) */
+    int asid = extract64(value, 48, 16);
+    tlb_flush(env, asid == 0);
+}
+
 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.
@@ -1608,6 +1632,55 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
     { .name = "DC_CISW", .state = ARM_CP_STATE_AA64,
       .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
       .access = PL1_W, .type = ARM_CP_NOP },
+    /* TLBI operations */
+    { .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 3, .opc2 = 0,
+      .access = PL1_W, .type = ARM_CP_NO_MIGRATE,
+      .writefn = tlbiall_write },
+    { .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 3, .opc2 = 1,
+      .access = PL1_W, .type = ARM_CP_NO_MIGRATE,
+      .writefn = tlbi_aa64_va_write },
+    { .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 3, .opc2 = 2,
+      .access = PL1_W, .type = ARM_CP_NO_MIGRATE,
+      .writefn = tlbi_aa64_asid_write },
+    { .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 3, .opc2 = 3,
+      .access = PL1_W, .type = ARM_CP_NO_MIGRATE,
+      .writefn = tlbi_aa64_vaa_write },
+    { .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 3, .opc2 = 5,
+      .access = PL1_W, .type = ARM_CP_NO_MIGRATE,
+      .writefn = tlbi_aa64_va_write },
+    { .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 3, .opc2 = 7,
+      .access = PL1_W, .type = ARM_CP_NO_MIGRATE,
+      .writefn = tlbi_aa64_vaa_write },
+    { .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 7, .opc2 = 0,
+      .access = PL1_W, .type = ARM_CP_NO_MIGRATE,
+      .writefn = tlbiall_write },
+    { .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 7, .opc2 = 1,
+      .access = PL1_W, .type = ARM_CP_NO_MIGRATE,
+      .writefn = tlbi_aa64_va_write },
+    { .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 7, .opc2 = 2,
+      .access = PL1_W, .type = ARM_CP_NO_MIGRATE,
+      .writefn = tlbi_aa64_asid_write },
+    { .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 7, .opc2 = 3,
+      .access = PL1_W, .type = ARM_CP_NO_MIGRATE,
+      .writefn = tlbi_aa64_vaa_write },
+    { .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 7, .opc2 = 5,
+      .access = PL1_W, .type = ARM_CP_NO_MIGRATE,
+      .writefn = tlbi_aa64_va_write },
+    { .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 7, .opc2 = 7,
+      .access = PL1_W, .type = ARM_CP_NO_MIGRATE,
+      .writefn = tlbi_aa64_vaa_write },
     REGINFO_SENTINEL
 };
 
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 25/35] target-arm: Implement AArch64 dummy MDSCR_EL1
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (23 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 24/35] target-arm: Implement AArch64 TLB invalidate ops Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-09  2:27   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 26/35] target-arm: Implement AArch64 memory attribute registers Peter Maydell
                   ` (11 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

We don't support letting the guest do debug, but Linux prods the
monitor debug system control register anyway, so implement a dummy
RAZ/WI version.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/helper.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 0dcb5b1..b0d28ca 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1681,6 +1681,12 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
       .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 7, .opc2 = 7,
       .access = PL1_W, .type = ARM_CP_NO_MIGRATE,
       .writefn = tlbi_aa64_vaa_write },
+    /* Dummy implementation of monitor debug system control register:
+     * we don't support debug.
+     */
+    { .name = "MDSCR_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
+      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
     REGINFO_SENTINEL
 };
 
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 26/35] target-arm: Implement AArch64 memory attribute registers
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (24 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 25/35] target-arm: Implement AArch64 dummy MDSCR_EL1 Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-09  2:31   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 27/35] target-arm: Implement AArch64 SCTLR_EL1 Peter Maydell
                   ` (10 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Implement the AArch64 memory attribute registers. Since QEMU doesn't
model caches it does not need to care about memory attributes at all,
and we can simply make these read-as-written.

We did not previously implement the AArch32 versions of the MAIR
registers, which went unnoticed because of the overbroad TLB_LOCKDOWN
reginfo definition; provide them now to keep the 64<->32 register
relationship clear.

We already provided AMAIR registers for 32 bit as simple RAZ/WI;
extend that to provide a 64 bit RAZ/WI AMAIR_EL1.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.h    |  3 +++
 target-arm/helper.c | 24 +++++++++++++++++++++++-
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index e0e3736..a08c02b 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -74,8 +74,10 @@
  */
 #ifdef HOST_WORDS_BIGENDIAN
 #define offsetoflow32(S, M) (offsetof(S, M) + sizeof(uint32_t))
+#define offsetofhigh32(S, M) offsetof(S, M)
 #else
 #define offsetoflow32(S, M) offsetof(S, M)
+#define offsetofhigh32(S, M) (offsetof(S, M) + sizeof(uint32_t))
 #endif
 
 /* Meanings of the ARMCPU object's two inbound GPIO lines */
@@ -197,6 +199,7 @@ typedef struct CPUARMState {
         uint32_t c9_pmxevtyper; /* perf monitor event type */
         uint32_t c9_pmuserenr; /* perf monitor user enable */
         uint32_t c9_pminten; /* perf monitor interrupt enables */
+        uint64_t mair_el1;
         uint32_t c12_vbar; /* vector base address register */
         uint32_t c13_fcse; /* FCSE PID.  */
         uint32_t c13_context; /* Context ID.  */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index b0d28ca..32bface 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -641,6 +641,26 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
      */
     { .name = "AIDR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 7,
       .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
+    /* MAIR can just read-as-written because we don't implement caches
+     * and so don't need to care about memory attributes.
+     */
+    { .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
+      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el1),
+      .resetvalue = 0 },
+    /* For non-long-descriptor page tables these are PRRR and NMRR;
+     * regardless they still act as reads-as-written for QEMU.
+     * The override is necessary because of the overly-broad TLB_LOCKDOWN
+     * definition.
+     */
+    { .name = "MAIR0", .state = ARM_CP_STATE_AA32, .type = ARM_CP_OVERRIDE,
+      .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0, .access = PL1_RW,
+      .fieldoffset = offsetoflow32(CPUARMState, cp15.mair_el1),
+      .resetfn = arm_cp_reset_ignore },
+    { .name = "MAIR1", .state = ARM_CP_STATE_AA32, .type = ARM_CP_OVERRIDE,
+      .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1, .access = PL1_RW,
+      .fieldoffset = offsetofhigh32(CPUARMState, cp15.mair_el1),
+      .resetfn = arm_cp_reset_ignore },
     REGINFO_SENTINEL
 };
 
@@ -1467,9 +1487,11 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
     /* NOP AMAIR0/1: the override is because these clash with the rather
      * broadly specified TLB_LOCKDOWN entry in the generic cp_reginfo.
      */
-    { .name = "AMAIR0", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0,
+    { .name = "AMAIR0", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_OVERRIDE,
       .resetvalue = 0 },
+    /* AMAIR1 is mapped to AMAIR_EL1[63:32] */
     { .name = "AMAIR1", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 1,
       .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_OVERRIDE,
       .resetvalue = 0 },
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 27/35] target-arm: Implement AArch64 SCTLR_EL1
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (25 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 26/35] target-arm: Implement AArch64 memory attribute registers Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-09  2:32   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 28/35] target-arm: Implement AArch64 TCR_EL1 Peter Maydell
                   ` (9 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Implement the AArch64 view of the system control register SCTLR_EL1.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.h    | 2 +-
 target-arm/helper.c | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index a08c02b..1fb9675 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -169,7 +169,7 @@ typedef struct CPUARMState {
     struct {
         uint32_t c0_cpuid;
         uint64_t c0_cssel; /* Cache size selection.  */
-        uint32_t c1_sys; /* System control register.  */
+        uint64_t c1_sys; /* System control register.  */
         uint32_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 32bface..7f466d6 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1973,7 +1973,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
     /* Generic registers whose values depend on the implementation */
     {
         ARMCPRegInfo sctlr = {
-            .name = "SCTLR", .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
+            .name = "SCTLR", .state = ARM_CP_STATE_BOTH,
+            .opc0 = 3, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
             .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_sys),
             .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
             .raw_writefn = raw_write,
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 28/35] target-arm: Implement AArch64 TCR_EL1
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (26 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 27/35] target-arm: Implement AArch64 SCTLR_EL1 Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-09  2:35   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 29/35] target-arm: Implement AArch64 VBAR_EL1 Peter Maydell
                   ` (8 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Implement the AArch64 TCR_EL1, which is the 64 bit view of
the AArch32 TTBCR. (The uses of the bits in the register are
completely different, but in any given situation the CPU will
always interpret them one way or the other. In fact for QEMU EL1
is always 64 bit, but we share the state field because this
is the correct mapping to permit a future implementation of EL2.)
We also make the AArch64 view the 'master' as far as migration
and reset is concerned.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.h    |  2 +-
 target-arm/helper.c | 19 ++++++++++++++++---
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 1fb9675..38f8eed 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -177,7 +177,7 @@ typedef struct CPUARMState {
         uint32_t c2_base0_hi; /* MMU translation table base 0, high 32 bits */
         uint32_t c2_base1; /* MMU translation table base 0.  */
         uint32_t c2_base1_hi; /* MMU translation table base 1, high 32 bits */
-        uint32_t c2_control; /* MMU translation table base control.  */
+        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. */
         uint32_t c2_data; /* MPU data cachable bits.  */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 7f466d6..b527fe3 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1215,6 +1215,14 @@ static void vmsa_ttbcr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
     env->cp15.c2_mask = 0;
 }
 
+static void vmsa_tcr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                               uint64_t value)
+{
+    /* For AArch64 the A1 bit could result in a change of ASID, so TLB flush. */
+    tlb_flush(env, 1);
+    env->cp15.c2_control = value;
+}
+
 static const ARMCPRegInfo vmsa_cp_reginfo[] = {
     { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW,
@@ -1228,10 +1236,15 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
     { .name = "TTBR1", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1,
       .access = PL1_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.c2_base1), .resetvalue = 0, },
-    { .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
-      .access = PL1_RW, .writefn = vmsa_ttbcr_write,
-      .resetfn = vmsa_ttbcr_reset, .raw_writefn = vmsa_ttbcr_raw_write,
+    { .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,
+      .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
       .fieldoffset = offsetof(CPUARMState, cp15.c2_control) },
+    { .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) },
     { .name = "DFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c6_data),
       .resetvalue = 0, },
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 29/35] target-arm: Implement AArch64 VBAR_EL1
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (27 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 28/35] target-arm: Implement AArch64 TCR_EL1 Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 30/35] target-arm: Implement AArch64 TTBR* Peter Maydell
                   ` (7 subsequent siblings)
  36 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Implement the A64 view of the VBAR system register.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
 target-arm/cpu.h    | 2 +-
 target-arm/helper.c | 9 ++++++++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 38f8eed..270e51e 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -200,7 +200,7 @@ typedef struct CPUARMState {
         uint32_t c9_pmuserenr; /* perf monitor user enable */
         uint32_t c9_pminten; /* perf monitor interrupt enables */
         uint64_t mair_el1;
-        uint32_t c12_vbar; /* vector base address register */
+        uint64_t c12_vbar; /* vector base address register */
         uint32_t c13_fcse; /* FCSE PID.  */
         uint32_t c13_context; /* Context ID.  */
         uint64_t tpidr_el0; /* User RW Thread register.  */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index b527fe3..0dcd5de 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -533,6 +533,12 @@ static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
                        uint64_t value)
 {
+    /* Note that even though the AArch64 view of this register has bits
+     * [10:0] all RES0 we can only mask the bottom 5, to comply with the
+     * architectural requirements for bits which are RES0 only in some
+     * contexts. (ARMv8 would permit us to do no masking at all, but ARMv7
+     * requires the bottom five bits to be RAZ/WI because they're UNK/SBZP.)
+     */
     env->cp15.c12_vbar = value & ~0x1Ful;
 }
 
@@ -622,7 +628,8 @@ 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", .cp = 15, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
+    { .name = "VBAR", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW, .writefn = vbar_write,
       .fieldoffset = offsetof(CPUARMState, cp15.c12_vbar),
       .resetvalue = 0 },
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 30/35] target-arm: Implement AArch64 TTBR*
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (28 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 29/35] target-arm: Implement AArch64 VBAR_EL1 Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-09  2:38   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 31/35] target-arm: Implement AArch64 MPIDR Peter Maydell
                   ` (6 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Implement the AArch64 TTBR* registers. For v7 these were already 64 bits
to handle LPAE, but implemented as two separate uint32_t fields.
Combine them into a single uint64_t which can be used for all purposes.
Since this requires touching every use, take the opportunity to rename
the field to the architectural name.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/pxa2xx.c     |  2 +-
 target-arm/cpu.h    |  6 ++--
 target-arm/helper.c | 89 ++++++++++++++++++-----------------------------------
 3 files changed, 33 insertions(+), 64 deletions(-)

diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index bf9416a..88f0988 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -276,7 +276,7 @@ static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
             ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
         s->cpu->env.cp15.c1_sys = 0;
         s->cpu->env.cp15.c1_coproc = 0;
-        s->cpu->env.cp15.c2_base0 = 0;
+        s->cpu->env.cp15.ttbr0_el1 = 0;
         s->cpu->env.cp15.c3 = 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 270e51e..3151329 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -173,10 +173,8 @@ typedef struct CPUARMState {
         uint32_t c1_coproc; /* Coprocessor access register.  */
         uint32_t c1_xscaleauxcr; /* XScale auxiliary control register.  */
         uint32_t c1_scr; /* secure config register.  */
-        uint32_t c2_base0; /* MMU translation table base 0.  */
-        uint32_t c2_base0_hi; /* MMU translation table base 0, high 32 bits */
-        uint32_t c2_base1; /* MMU translation table base 0.  */
-        uint32_t c2_base1_hi; /* MMU translation table base 1, high 32 bits */
+        uint64_t ttbr0_el1; /* MMU translation table base 0. */
+        uint32_t ttbr1_el1; /* MMU translation table base 1. */
         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 0dcd5de..a23b40d 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1230,6 +1230,18 @@ static void vmsa_tcr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
     env->cp15.c2_control = value;
 }
 
+static void vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                            uint64_t value)
+{
+    /* 64 bit accesses to the TTBRs can change the ASID and so we
+     * must flush the TLB.
+     */
+    if (cpreg_field_is_64bit(ri)) {
+        tlb_flush(env, 1);
+    }
+    raw_write(env, ri, value);
+}
+
 static const ARMCPRegInfo vmsa_cp_reginfo[] = {
     { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW,
@@ -1237,12 +1249,14 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
     { .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
       .access = PL1_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.c5_insn), .resetvalue = 0, },
-    { .name = "TTBR0", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW,
-      .fieldoffset = offsetof(CPUARMState, cp15.c2_base0), .resetvalue = 0, },
-    { .name = "TTBR1", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1,
-      .access = PL1_RW,
-      .fieldoffset = offsetof(CPUARMState, cp15.c2_base1), .resetvalue = 0, },
+    { .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
+      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el1),
+      .writefn = vmsa_ttbr_write, .resetvalue = 0 },
+    { .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1,
+      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el1),
+      .writefn = vmsa_ttbr_write, .resetvalue = 0 },
     { .name = "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,
@@ -1459,50 +1473,6 @@ static void par64_reset(CPUARMState *env, const ARMCPRegInfo *ri)
     env->cp15.c7_par = 0;
 }
 
-static uint64_t ttbr064_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    return ((uint64_t)env->cp15.c2_base0_hi << 32) | env->cp15.c2_base0;
-}
-
-static void ttbr064_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                              uint64_t value)
-{
-    env->cp15.c2_base0_hi = value >> 32;
-    env->cp15.c2_base0 = value;
-}
-
-static void ttbr064_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                          uint64_t value)
-{
-    /* Writes to the 64 bit format TTBRs may change the ASID */
-    tlb_flush(env, 1);
-    ttbr064_raw_write(env, ri, value);
-}
-
-static void ttbr064_reset(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    env->cp15.c2_base0_hi = 0;
-    env->cp15.c2_base0 = 0;
-}
-
-static uint64_t ttbr164_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    return ((uint64_t)env->cp15.c2_base1_hi << 32) | env->cp15.c2_base1;
-}
-
-static void ttbr164_write(CPUARMState *env, const ARMCPRegInfo *ri,
-                          uint64_t value)
-{
-    env->cp15.c2_base1_hi = value >> 32;
-    env->cp15.c2_base1 = value;
-}
-
-static void ttbr164_reset(CPUARMState *env, const ARMCPRegInfo *ri)
-{
-    env->cp15.c2_base1_hi = 0;
-    env->cp15.c2_base1 = 0;
-}
-
 static const ARMCPRegInfo lpae_cp_reginfo[] = {
     /* NOP AMAIR0/1: the override is because these clash with the rather
      * broadly specified TLB_LOCKDOWN entry in the generic cp_reginfo.
@@ -1524,12 +1494,13 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
       .access = PL1_RW, .type = ARM_CP_64BIT,
       .readfn = par64_read, .writefn = par64_write, .resetfn = par64_reset },
     { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0,
-      .access = PL1_RW, .type = ARM_CP_64BIT, .readfn = ttbr064_read,
-      .writefn = ttbr064_write, .raw_writefn = ttbr064_raw_write,
-      .resetfn = ttbr064_reset },
+      .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE,
+      .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el1),
+      .writefn = vmsa_ttbr_write, .resetfn = arm_cp_reset_ignore },
     { .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1,
-      .access = PL1_RW, .type = ARM_CP_64BIT, .readfn = ttbr164_read,
-      .writefn = ttbr164_write, .resetfn = ttbr164_reset },
+      .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE,
+      .fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el1),
+      .writefn = vmsa_ttbr_write, .resetfn = arm_cp_reset_ignore },
     REGINFO_SENTINEL
 };
 
@@ -2939,9 +2910,9 @@ static uint32_t get_level1_table_address(CPUARMState *env, uint32_t address)
     uint32_t table;
 
     if (address & env->cp15.c2_mask)
-        table = env->cp15.c2_base1 & 0xffffc000;
+        table = env->cp15.ttbr1_el1 & 0xffffc000;
     else
-        table = env->cp15.c2_base0 & env->cp15.c2_base_mask;
+        table = env->cp15.ttbr0_el1 & env->cp15.c2_base_mask;
 
     table |= (address >> 18) & 0x3ffc;
     return table;
@@ -3214,11 +3185,11 @@ static int get_phys_addr_lpae(CPUARMState *env, uint32_t address,
      * we will always flush the TLB any time the ASID is changed).
      */
     if (ttbr_select == 0) {
-        ttbr = ((uint64_t)env->cp15.c2_base0_hi << 32) | env->cp15.c2_base0;
+        ttbr = env->cp15.ttbr0_el1;
         epd = extract32(env->cp15.c2_control, 7, 1);
         tsz = t0sz;
     } else {
-        ttbr = ((uint64_t)env->cp15.c2_base1_hi << 32) | env->cp15.c2_base1;
+        ttbr = env->cp15.ttbr1_el1;
         epd = extract32(env->cp15.c2_control, 23, 1);
         tsz = t1sz;
     }
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 31/35] target-arm: Implement AArch64 MPIDR
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (29 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 30/35] target-arm: Implement AArch64 TTBR* Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 32/35] target-arm: Implement AArch64 generic timers Peter Maydell
                   ` (5 subsequent siblings)
  36 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Implement the AArch64 MPIDR system register.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
 target-arm/helper.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index a23b40d..d943963 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1435,7 +1435,8 @@ static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     CPUState *cs = CPU(arm_env_get_cpu(env));
     uint32_t mpidr = cs->cpu_index;
-    /* We don't support setting cluster ID ([8..11])
+    /* We don't support setting cluster ID ([8..11]) (known as Aff1
+     * in later ARM ARM versions), or any of the higher affinity level fields,
      * so these bits always RAZ.
      */
     if (arm_feature(env, ARM_FEATURE_V7MP)) {
@@ -1450,7 +1451,8 @@ static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 }
 
 static const ARMCPRegInfo mpidr_cp_reginfo[] = {
-    { .name = "MPIDR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5,
+    { .name = "MPIDR", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5,
       .access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_MIGRATE },
     REGINFO_SENTINEL
 };
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 32/35] target-arm: Implement AArch64 generic timers
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (30 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 31/35] target-arm: Implement AArch64 MPIDR Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 33/35] target-arm: Implement AArch64 ID and feature registers Peter Maydell
                   ` (4 subsequent siblings)
  36 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Implement the AArch64 view of the generic timer system registers.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.h    |  6 ++---
 target-arm/helper.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 72 insertions(+), 10 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 3151329..24a8e93 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -104,7 +104,7 @@ struct arm_boot_info;
 /* CPU state for each instance of a generic timer (in cp15 c14) */
 typedef struct ARMGenericTimer {
     uint64_t cval; /* Timer CompareValue register */
-    uint32_t ctl; /* Timer Control register */
+    uint64_t ctl; /* Timer Control register */
 } ARMGenericTimer;
 
 #define GTIMER_PHYS 0
@@ -204,8 +204,8 @@ typedef struct CPUARMState {
         uint64_t tpidr_el0; /* User RW Thread register.  */
         uint64_t tpidrro_el0; /* User RO Thread register.  */
         uint64_t tpidr_el1; /* Privileged Thread register.  */
-        uint32_t c14_cntfrq; /* Counter Frequency register */
-        uint32_t c14_cntkctl; /* Timer Control register */
+        uint64_t c14_cntfrq; /* Counter Frequency register */
+        uint64_t c14_cntkctl; /* Timer Control register */
         ARMGenericTimer c14_timer[NUM_GTIMERS];
         uint32_t c15_cpar; /* XScale Coprocessor Access Register */
         uint32_t c15_ticonfig; /* TI925T configuration byte.  */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index d943963..e7d8e7c 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -901,19 +901,36 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
      * Our reset value matches the fixed frequency we implement the timer at.
      */
     { .name = "CNTFRQ", .cp = 15, .crn = 14, .crm = 0, .opc1 = 0, .opc2 = 0,
+      .access = PL1_RW | PL0_R, .type = ARM_CP_NO_MIGRATE,
+      .fieldoffset = offsetoflow32(CPUARMState, cp15.c14_cntfrq),
+      .resetfn = arm_cp_reset_ignore,
+      .accessfn = gt_cntfrq_access,
+    },
+    { .name = "CNTFRQ_EL0", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0,
       .access = PL1_RW | PL0_R,
       .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
       .resetvalue = (1000 * 1000 * 1000) / GTIMER_SCALE,
       .accessfn = gt_cntfrq_access,
     },
     /* overall control: mostly access permissions */
-    { .name = "CNTKCTL", .cp = 15, .crn = 14, .crm = 1, .opc1 = 0, .opc2 = 0,
+    { .name = "CNTKCTL", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 0, .crn = 14, .crm = 1, .opc2 = 0,
       .access = PL1_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.c14_cntkctl),
       .resetvalue = 0,
     },
     /* per-timer control */
     { .name = "CNTP_CTL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 1,
+      .type = ARM_CP_IO | ARM_CP_NO_MIGRATE, .access = PL1_RW | PL0_R,
+      .fieldoffset = offsetoflow32(CPUARMState,
+                                   cp15.c14_timer[GTIMER_PHYS].ctl),
+      .resetfn = arm_cp_reset_ignore,
+      .accessfn = gt_ptimer_access,
+      .writefn = gt_ctl_write, .raw_writefn = raw_write,
+    },
+    { .name = "CNTP_CTL_EL0", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 1,
       .type = ARM_CP_IO, .access = PL1_RW | PL0_R,
       .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
       .resetvalue = 0,
@@ -921,6 +938,15 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
       .writefn = gt_ctl_write, .raw_writefn = raw_write,
     },
     { .name = "CNTV_CTL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 1,
+      .type = ARM_CP_IO | ARM_CP_NO_MIGRATE, .access = PL1_RW | PL0_R,
+      .fieldoffset = offsetoflow32(CPUARMState,
+                                   cp15.c14_timer[GTIMER_VIRT].ctl),
+      .resetfn = arm_cp_reset_ignore,
+      .accessfn = gt_vtimer_access,
+      .writefn = gt_ctl_write, .raw_writefn = raw_write,
+    },
+    { .name = "CNTV_CTL_EL0", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 1,
       .type = ARM_CP_IO, .access = PL1_RW | PL0_R,
       .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
       .resetvalue = 0,
@@ -933,37 +959,73 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
       .accessfn = gt_ptimer_access,
       .readfn = gt_tval_read, .writefn = gt_tval_write,
     },
+    { .name = "CNTP_TVAL_EL0", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 0,
+      .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R,
+      .readfn = gt_tval_read, .writefn = gt_tval_write,
+    },
     { .name = "CNTV_TVAL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 0,
       .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R,
       .accessfn = gt_vtimer_access,
       .readfn = gt_tval_read, .writefn = gt_tval_write,
     },
+    { .name = "CNTV_TVAL_EL0", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 0,
+      .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R,
+      .readfn = gt_tval_read, .writefn = gt_tval_write,
+    },
     /* The counter itself */
     { .name = "CNTPCT", .cp = 15, .crm = 14, .opc1 = 0,
       .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE | ARM_CP_IO,
       .accessfn = gt_pct_access,
+      .readfn = gt_cnt_read, .resetfn = arm_cp_reset_ignore,
+    },
+    { .name = "CNTPCT_EL0", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 1,
+      .access = PL0_R, .type = ARM_CP_NO_MIGRATE | ARM_CP_IO,
+      .accessfn = gt_pct_access,
       .readfn = gt_cnt_read, .resetfn = gt_cnt_reset,
     },
     { .name = "CNTVCT", .cp = 15, .crm = 14, .opc1 = 1,
       .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE | ARM_CP_IO,
       .accessfn = gt_vct_access,
+      .readfn = gt_cnt_read, .resetfn = arm_cp_reset_ignore,
+    },
+    { .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2,
+      .access = PL0_R, .type = ARM_CP_NO_MIGRATE | ARM_CP_IO,
+      .accessfn = gt_vct_access,
       .readfn = gt_cnt_read, .resetfn = gt_cnt_reset,
     },
     /* Comparison value, indicating when the timer goes off */
     { .name = "CNTP_CVAL", .cp = 15, .crm = 14, .opc1 = 2,
       .access = PL1_RW | PL0_R,
-      .type = ARM_CP_64BIT | ARM_CP_IO,
+      .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_MIGRATE,
       .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
-      .resetvalue = 0,
-      .accessfn = gt_ptimer_access,
+      .accessfn = gt_ptimer_access, .resetfn = arm_cp_reset_ignore,
+      .writefn = gt_cval_write, .raw_writefn = raw_write,
+    },
+    { .name = "CNTP_CVAL_EL0", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 2,
+      .access = PL1_RW | PL0_R,
+      .type = ARM_CP_IO,
+      .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
+      .resetvalue = 0, .accessfn = gt_vtimer_access,
       .writefn = gt_cval_write, .raw_writefn = raw_write,
     },
     { .name = "CNTV_CVAL", .cp = 15, .crm = 14, .opc1 = 3,
       .access = PL1_RW | PL0_R,
-      .type = ARM_CP_64BIT | ARM_CP_IO,
+      .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_MIGRATE,
       .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
-      .resetvalue = 0,
-      .accessfn = gt_vtimer_access,
+      .accessfn = gt_vtimer_access, .resetfn = arm_cp_reset_ignore,
+      .writefn = gt_cval_write, .raw_writefn = raw_write,
+    },
+    { .name = "CNTV_CVAL_EL0", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 2,
+      .access = PL1_RW | PL0_R,
+      .type = ARM_CP_IO,
+      .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
+      .resetvalue = 0, .accessfn = gt_vtimer_access,
       .writefn = gt_cval_write, .raw_writefn = raw_write,
     },
     REGINFO_SENTINEL
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 33/35] target-arm: Implement AArch64 ID and feature registers
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (31 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 32/35] target-arm: Implement AArch64 generic timers Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-09  2:42   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 34/35] target-arm: Implement AArch64 dummy breakpoint and watchpoint registers Peter Maydell
                   ` (3 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Implement the AArch64-specific ID and feature registers. Although
many of these are currently not used by the architecture (and so
always zero for all implementations), we define the full set of
fields in the ARMCPU struct for symmetry.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu-qom.h | 10 ++++++++++
 target-arm/helper.c  | 45 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index afbd422..00234e1 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -132,6 +132,16 @@ typedef struct ARMCPU {
     uint32_t id_isar3;
     uint32_t id_isar4;
     uint32_t id_isar5;
+    uint64_t id_aa64pfr0;
+    uint64_t id_aa64pfr1;
+    uint64_t id_aa64dfr0;
+    uint64_t id_aa64dfr1;
+    uint64_t id_aa64afr0;
+    uint64_t id_aa64afr1;
+    uint64_t id_aa64isar0;
+    uint64_t id_aa64isar1;
+    uint64_t id_aa64mmfr0;
+    uint64_t id_aa64mmfr1;
     uint32_t clidr;
     /* The elements of this array are the CCSIDR values for each cache,
      * in the order L1DCache, L1ICache, L2DCache, L2ICache, etc.
diff --git a/target-arm/helper.c b/target-arm/helper.c
index e7d8e7c..eb37e7e 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1882,6 +1882,51 @@ void register_cp_regs_for_features(ARMCPU *cpu)
         define_arm_cp_regs(cpu, not_v7_cp_reginfo);
     }
     if (arm_feature(env, ARM_FEATURE_V8)) {
+        /* AArch64 ID registers, which all have impdef reset values */
+        ARMCPRegInfo v8_idregs[] = {
+            { .name = "ID_AA64PFR0_EL1", .state = ARM_CP_STATE_AA64,
+              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 0,
+              .access = PL1_R, .type = ARM_CP_CONST,
+              .resetvalue = cpu->id_aa64pfr0 },
+            { .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64,
+              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1,
+              .access = PL1_R, .type = ARM_CP_CONST,
+              .resetvalue = cpu->id_aa64pfr1},
+            { .name = "ID_AA64DFR0_EL1", .state = ARM_CP_STATE_AA64,
+              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
+              .access = PL1_R, .type = ARM_CP_CONST,
+              .resetvalue = cpu->id_aa64dfr0 },
+            { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64,
+              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
+              .access = PL1_R, .type = ARM_CP_CONST,
+              .resetvalue = cpu->id_aa64dfr1 },
+            { .name = "ID_AA64AFR0_EL1", .state = ARM_CP_STATE_AA64,
+              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 4,
+              .access = PL1_R, .type = ARM_CP_CONST,
+              .resetvalue = cpu->id_aa64afr0 },
+            { .name = "ID_AA64AFR1_EL1", .state = ARM_CP_STATE_AA64,
+              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 5,
+              .access = PL1_R, .type = ARM_CP_CONST,
+              .resetvalue = cpu->id_aa64afr1 },
+            { .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64,
+              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0,
+              .access = PL1_R, .type = ARM_CP_CONST,
+              .resetvalue = cpu->id_aa64isar0 },
+            { .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64,
+              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1,
+              .access = PL1_R, .type = ARM_CP_CONST,
+              .resetvalue = cpu->id_aa64isar1 },
+            { .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64,
+              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
+              .access = PL1_R, .type = ARM_CP_CONST,
+              .resetvalue = cpu->id_aa64mmfr0 },
+            { .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64,
+              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1,
+              .access = PL1_R, .type = ARM_CP_CONST,
+              .resetvalue = cpu->id_aa64mmfr1 },
+            REGINFO_SENTINEL
+        };
+        define_arm_cp_regs(cpu, v8_idregs);
         define_arm_cp_regs(cpu, v8_cp_reginfo);
     }
     if (arm_feature(env, ARM_FEATURE_MPU)) {
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 34/35] target-arm: Implement AArch64 dummy breakpoint and watchpoint registers
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (32 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 33/35] target-arm: Implement AArch64 ID and feature registers Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-09  2:44   ` Peter Crosthwaite
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 35/35] target-arm: Implement AArch64 OSLAR_EL1 sysreg as WI Peter Maydell
                   ` (2 subsequent siblings)
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

In AArch64 the breakpoint and watchpoint registers are mandatory, so the
kernel always accesses them on bootup. Implement dummy versions, which
read as written but have no actual effect.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.h    |  4 ++++
 target-arm/helper.c | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 24a8e93..267d5ae 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -216,6 +216,10 @@ typedef struct CPUARMState {
         uint32_t c15_diagnostic; /* diagnostic register */
         uint32_t c15_power_diagnostic;
         uint32_t c15_power_control; /* power control */
+        uint64_t dbgbvr[16]; /* breakpoint value registers */
+        uint64_t dbgbcr[16]; /* breakpoint control registers */
+        uint64_t dbgwvr[16]; /* watchpoint value registers */
+        uint64_t dbgwcr[16]; /* watchpoint control registers */
     } cp15;
 
     struct {
diff --git a/target-arm/helper.c b/target-arm/helper.c
index eb37e7e..1621030 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1787,6 +1787,37 @@ static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri)
     return CP_ACCESS_OK;
 }
 
+static void define_aarch64_debug_regs(ARMCPU *cpu)
+{
+    /* Define breakpoint and watchpoint registers. These do nothing
+     * but read as written, for now.
+     */
+    int i;
+
+    for (i = 0; i < 16; i++) {
+        ARMCPRegInfo dbgregs[] = {
+            { .name = "DBGBVR", .state = ARM_CP_STATE_AA64,
+              .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
+              .access = PL1_RW,
+              .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]) },
+            { .name = "DBGBCR", .state = ARM_CP_STATE_AA64,
+              .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
+              .access = PL1_RW,
+              .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]) },
+            { .name = "DBGWVR", .state = ARM_CP_STATE_AA64,
+              .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
+              .access = PL1_RW,
+              .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]) },
+            { .name = "DBGWCR", .state = ARM_CP_STATE_AA64,
+              .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,
+              .access = PL1_RW,
+              .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]) },
+               REGINFO_SENTINEL
+        };
+        define_arm_cp_regs(cpu, dbgregs);
+    }
+}
+
 void register_cp_regs_for_features(ARMCPU *cpu)
 {
     /* Register all the coprocessor registers based on feature bits */
@@ -1928,6 +1959,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
         };
         define_arm_cp_regs(cpu, v8_idregs);
         define_arm_cp_regs(cpu, v8_cp_reginfo);
+        define_aarch64_debug_regs(cpu);
     }
     if (arm_feature(env, ARM_FEATURE_MPU)) {
         /* These are the MPU registers prior to PMSAv6. Any new
-- 
1.8.5

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

* [Qemu-devel] [PATCH v2 35/35] target-arm: Implement AArch64 OSLAR_EL1 sysreg as WI
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (33 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 34/35] target-arm: Implement AArch64 dummy breakpoint and watchpoint registers Peter Maydell
@ 2014-01-31 15:45 ` Peter Maydell
  2014-02-09  2:44   ` Peter Crosthwaite
  2014-02-11  6:11 ` [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Crosthwaite
  2014-02-11 17:12 ` Peter Maydell
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 15:45 UTC (permalink / raw)
  To: qemu-devel
  Cc: Rob Herring, Peter Crosthwaite, patches, Michael Matz,
	Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

Define a dummy version of the AArch64 OSLAR_EL1 system register
which just ignores writes. Linux will always write to this (it
is the OS lock used for debugging), but we don't support debug.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/helper.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 1621030..43a4f31 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1764,6 +1764,10 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
     { .name = "MDSCR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
       .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+    /* We define a dummy WI OSLAR_EL1, because Linux writes to it. */
+    { .name = "OSLAR_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4,
+      .access = PL1_W, .type = ARM_CP_NOP },
     REGINFO_SENTINEL
 };
 
-- 
1.8.5

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

* Re: [Qemu-devel] [PATCH v2 01/35] target-arm: Fix raw read and write functions on AArch64 registers
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 01/35] target-arm: Fix raw read and write functions on AArch64 registers Peter Maydell
@ 2014-01-31 15:56   ` Rob Herring
  2014-01-31 16:06     ` Peter Maydell
  0 siblings, 1 reply; 83+ messages in thread
From: Rob Herring @ 2014-01-31 15:56 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Peter Crosthwaite, patches, Michael Matz, Alexander Graf,
	qemu-devel, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

On 31 January 2014 09:45, Peter Maydell <peter.maydell@linaro.org> wrote:
> The raw read and write functions were using the ARM_CP_64BIT flag in
> ri->type to determine whether to treat the register's state field as
> uint32_t or uint64_t; however AArch64 register info structs don't use
> that flag. Abstract out the "how big is the field?" test into a
> function and fix it to work for AArch64 registers.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target-arm/cpu.c    | 2 +-
>  target-arm/cpu.h    | 8 ++++++++
>  target-arm/helper.c | 4 ++--
>  3 files changed, 11 insertions(+), 3 deletions(-)
>
> diff --git a/target-arm/cpu.c b/target-arm/cpu.c
> index 45ad7f0..935269c 100644
> --- a/target-arm/cpu.c
> +++ b/target-arm/cpu.c
> @@ -60,7 +60,7 @@ static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
>          return;
>      }
>
> -    if (ri->type & ARM_CP_64BIT) {
> +    if (cpreg_field_is_64bit(ri)) {
>          CPREG_FIELD64(&cpu->env, ri) = ri->resetvalue;
>      } else {
>          CPREG_FIELD32(&cpu->env, ri) = ri->resetvalue;
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 383c582..7ccdbae 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -890,6 +890,14 @@ int arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t *value);
>   */
>  void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque);
>
> +/* Return true if this reginfo struct's field in the cpu state struct
> + * is 64 bits wide.
> + */
> +static inline bool cpreg_field_is_64bit(const ARMCPRegInfo *ri)
> +{
> +    return (ri->state == ARM_CP_STATE_AA64) || (ri->type & ARM_CP_64BIT);

Won't this fail when state is ARM_CP_STATE_BOTH? That was what I found
in testing as TTBR writes were not causing a tlb_flush.

Rob

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

* Re: [Qemu-devel] [PATCH v2 01/35] target-arm: Fix raw read and write functions on AArch64 registers
  2014-01-31 15:56   ` Rob Herring
@ 2014-01-31 16:06     ` Peter Maydell
  2014-01-31 16:38       ` Peter Maydell
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 16:06 UTC (permalink / raw)
  To: Rob Herring
  Cc: Peter Crosthwaite, Patch Tracking, Michael Matz, Alexander Graf,
	QEMU Developers, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

On 31 January 2014 15:56, Rob Herring <rob.herring@linaro.org> wrote:
> On 31 January 2014 09:45, Peter Maydell <peter.maydell@linaro.org> wrote:
>> The raw read and write functions were using the ARM_CP_64BIT flag in
>> ri->type to determine whether to treat the register's state field as
>> uint32_t or uint64_t; however AArch64 register info structs don't use
>> that flag. Abstract out the "how big is the field?" test into a
>> function and fix it to work for AArch64 registers.

>> +/* Return true if this reginfo struct's field in the cpu state struct
>> + * is 64 bits wide.
>> + */
>> +static inline bool cpreg_field_is_64bit(const ARMCPRegInfo *ri)
>> +{
>> +    return (ri->state == ARM_CP_STATE_AA64) || (ri->type & ARM_CP_64BIT);
>
> Won't this fail when state is ARM_CP_STATE_BOTH? That was what I found
> in testing as TTBR writes were not causing a tlb_flush.

Hmm. You're right that this won't work as it stands.
We could either fix this condition or we could make the code
that puts reginfo structs into the hashtable fix the state
so that the reginfo for the AArch64 register said _AA64
and the one for AArch32 said _AA32.

(And/or we could make that code force ARM_CP_64BIT for the AArch64
entry, but I felt it would be a bit confusing having that be
present on none of the structs in the source code but on all
of them at runtime.)

Anybody got a preference? If not I think I'll take the
path of least resistance and change this condition to

  /* Only AArch32-only non-64-bit registers have a 32 bit
   * backing field.
   */
  return (ri->state != ARM_CP_STATE_AA32) || (ri->type & ARM_CP_64BIT);

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 01/35] target-arm: Fix raw read and write functions on AArch64 registers
  2014-01-31 16:06     ` Peter Maydell
@ 2014-01-31 16:38       ` Peter Maydell
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-01-31 16:38 UTC (permalink / raw)
  To: Rob Herring
  Cc: Peter Crosthwaite, Patch Tracking, Michael Matz, Alexander Graf,
	QEMU Developers, Claudio Fontana, Dirk Mueller, Will Newton,
	Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

On 31 January 2014 16:06, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 31 January 2014 15:56, Rob Herring <rob.herring@linaro.org> wrote:
>> On 31 January 2014 09:45, Peter Maydell <peter.maydell@linaro.org> wrote:
>>> +/* Return true if this reginfo struct's field in the cpu state struct
>>> + * is 64 bits wide.
>>> + */
>>> +static inline bool cpreg_field_is_64bit(const ARMCPRegInfo *ri)
>>> +{
>>> +    return (ri->state == ARM_CP_STATE_AA64) || (ri->type & ARM_CP_64BIT);
>>
>> Won't this fail when state is ARM_CP_STATE_BOTH? That was what I found
>> in testing as TTBR writes were not causing a tlb_flush.
>
> Hmm. You're right that this won't work as it stands.
> We could either fix this condition or we could make the code
> that puts reginfo structs into the hashtable fix the state
> so that the reginfo for the AArch64 register said _AA64
> and the one for AArch32 said _AA32.
>
> (And/or we could make that code force ARM_CP_64BIT for the AArch64
> entry, but I felt it would be a bit confusing having that be
> present on none of the structs in the source code but on all
> of them at runtime.)
>
> Anybody got a preference?

On further thought, this has to be done by making the reginfo
structs in the hashtable different for the AArch32 and AArch64
views of the register. What the function is attempting to
determine is "is the view of the register corresponding to
this reginfo 32 or 64 bits wide?" (in the 32 bit case it
could well be that the field is stored in half of a uint64_t,
but still raw accesses to the field should be doing 32 bit
loads/stores, not 64 bit). So we must do something to the
copies of a STATE_BOTH reginfo as we feed them into the hash
table so that they are distinct. Changing the ri->state seems
most sensible.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 05/35] target-arm: Remove unused ARMCPUState sr substruct
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 05/35] target-arm: Remove unused ARMCPUState sr substruct Peter Maydell
@ 2014-02-05  6:03   ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-05  6:03 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Remove the 'struct sr' from ARMCPUState -- it isn't actually used and is
> a hangover from the original separate system register implementation used
> by the SuSE linux-user-mode-only AArch64 target.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  target-arm/cpu.h | 5 -----
>  1 file changed, 5 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 4bad6c0..70cd5a0 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -217,11 +217,6 @@ typedef struct CPUARMState {
>          uint32_t c15_power_control; /* power control */
>      } cp15;
>
> -    /* System registers (AArch64) */
> -    struct {
> -        uint64_t tpidr_el0;
> -    } sr;
> -
>      struct {
>          uint32_t other_sp;
>          uint32_t vecbase;
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 09/35] target-arm: A64: Implement MSR (immediate) instructions
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 09/35] target-arm: A64: Implement MSR (immediate) instructions Peter Maydell
@ 2014-02-05  6:23   ` Peter Crosthwaite
  2014-02-05 10:55     ` Peter Maydell
  2014-02-14 16:41     ` Peter Maydell
  0 siblings, 2 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-05  6:23 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Implement the MSR (immediate) instructions, which can update the
> PSTATE SP and DAIF fields.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target-arm/cpu.h           |  1 +
>  target-arm/helper.h        |  2 ++
>  target-arm/op_helper.c     | 25 +++++++++++++++++++++++++
>  target-arm/translate-a64.c | 24 +++++++++++++++++++++++-
>  4 files changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 385cfcd..e66d464 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -426,6 +426,7 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
>  #define PSTATE_Z (1U << 30)
>  #define PSTATE_N (1U << 31)
>  #define PSTATE_NZCV (PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V)
> +#define PSTATE_DAIF (PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F)
>  #define CACHED_PSTATE_BITS (PSTATE_NZCV)
>  /* Mode values for AArch64 */
>  #define PSTATE_MODE_EL3h 13
> diff --git a/target-arm/helper.h b/target-arm/helper.h
> index 71b8411..93a27ce 100644
> --- a/target-arm/helper.h
> +++ b/target-arm/helper.h
> @@ -62,6 +62,8 @@ DEF_HELPER_2(get_cp_reg, i32, env, ptr)
>  DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
>  DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
>
> +DEF_HELPER_3(msr_i_pstate, void, env, i32, i32)
> +
>  DEF_HELPER_2(get_r13_banked, i32, env, i32)
>  DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
>
> diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
> index a918e5b..c812a9f 100644
> --- a/target-arm/op_helper.c
> +++ b/target-arm/op_helper.c
> @@ -313,6 +313,31 @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
>      return value;
>  }
>
> +void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
> +{
> +    /* MSR_i to update PSTATE. This is OK from EL0 only if UMA is set.
> +     * 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)) {
> +        raise_exception(env, EXCP_UDEF);
> +    }
> +
> +    switch (op) {
> +    case 0x05: /* SPSel */
> +        env->pstate = deposit32(env->pstate, 0, 1, imm);

"0","1" hardcoded constants are a bit unfriendly. I guess the current
macro set doesnt define _SHIFT and _WIDTH definitions, should they be
added?

FWIW, I have this macro in my tree which makes short work of defining
mask, shift and width constants as a one liner:

/* Define SHIFT, LENGTH and MASK constants for a field within a register */

#define FIELD(reg, field, length, shift) \
enum { reg ## _ ## field ## _SHIFT = (shift)}; \
enum { reg ## _ ## field ## _LENGTH = (length)}; \
enum { reg ## _ ## field ## _MASK = (((1ULL << (length)) - 1) \
                                          << (shift)) };

Usage would be something like FIELD(PSTATE, SPSEL, 1, 0)

> +        break;
> +    case 0x1e: /* DAIFSet */
> +        env->pstate |= (imm << 6) & PSTATE_DAIF;
> +        break;
> +    case 0x1f: /* DAIFClear */
> +        env->pstate &= ~((imm << 6) & PSTATE_DAIF);

I wonder whether deposit should be extended with and/or (with
existing) versions to allow for consistency in places like this. In
SPSel we get the nice deposit based implementation but with the logic
function change here were are stuck with open codedness. Set and
clearing and fields should be common enough tree wide to warrant it
perhaps.

Regards,
Peter

> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
> +}
> +
>  /* ??? Flag setting arithmetic is awkward because we need to do comparisons.
>     The only way to do that in TCG is a conditional branch, which clobbers
>     all our temporaries.  For now implement these as helper functions.  */
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index d938e5e..a942609 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -1106,7 +1106,29 @@ static void handle_sync(DisasContext *s, uint32_t insn,
>  static void handle_msr_i(DisasContext *s, uint32_t insn,
>                           unsigned int op1, unsigned int op2, unsigned int crm)
>  {
> -    unsupported_encoding(s, insn);
> +    int op = op1 << 3 | op2;
> +    switch (op) {
> +    case 0x05: /* SPSel */
> +        if (s->current_pl == 0) {
> +            unallocated_encoding(s);
> +            return;
> +        }
> +        /* fall through */
> +    case 0x1e: /* DAIFSet */
> +    case 0x1f: /* DAIFClear */
> +    {
> +        TCGv_i32 tcg_imm = tcg_const_i32(crm);
> +        TCGv_i32 tcg_op = tcg_const_i32(op);
> +        gen_helper_msr_i_pstate(cpu_env, tcg_op, tcg_imm);
> +        tcg_temp_free_i32(tcg_imm);
> +        tcg_temp_free_i32(tcg_op);
> +        s->is_jmp = DISAS_UPDATE;
> +        break;
> +    }
> +    default:
> +        unallocated_encoding(s);
> +        return;
> +    }
>  }
>
>  static void gen_get_nzcv(TCGv_i64 tcg_rt)
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 12/35] target-arm: Convert performance monitor reginfo to accesfn
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 12/35] target-arm: Convert performance monitor reginfo to accesfn Peter Maydell
@ 2014-02-05  6:59   ` Peter Crosthwaite
  2014-02-05 11:01     ` Peter Maydell
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-05  6:59 UTC (permalink / raw)
  To: Peter Maydell, Alistair Francis
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

cc Alistair, this may conflict with his timer work.

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Convert the performance monitor reginfo definitions to use
> an accessfn rather than returning EXCP_UDEF from read and
> write functions. This also allows us to fix a couple of XXX
> cases where we weren't imposing the access restrictions on
> RAZ/WI or constant registers.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target-arm/helper.c | 70 +++++++++++++++++++++--------------------------------
>  1 file changed, 28 insertions(+), 42 deletions(-)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index bd78350..9adaeb9 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -485,26 +485,20 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
>      REGINFO_SENTINEL
>  };
>
> -
> -static int pmreg_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                      uint64_t *value)
> +static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
> -    /* Generic performance monitor register read function for where
> -     * user access may be allowed by PMUSERENR.
> +    /* Perfomance monitor registers user accessibility is controlled
> +     * by PMUSERENR.
>       */
>      if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
> -        return EXCP_UDEF;
> +        return CP_ACCESS_TRAP;
>      }
> -    *value = CPREG_FIELD32(env, ri);
> -    return 0;
> +    return CP_ACCESS_OK;
>  }
>
>  static int pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
>                        uint64_t value)
>  {
> -    if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
> -        return EXCP_UDEF;
> -    }
>      /* only the DP, X, D and E bits are writable */
>      env->cp15.c9_pmcr &= ~0x39;
>      env->cp15.c9_pmcr |= (value & 0x39);
> @@ -514,9 +508,6 @@ static int pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
>  static int pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
>                              uint64_t value)
>  {
> -    if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
> -        return EXCP_UDEF;
> -    }
>      value &= (1 << 31);
>      env->cp15.c9_pmcnten |= value;
>      return 0;
> @@ -525,9 +516,6 @@ static int pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
>  static int pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
>                              uint64_t value)
>  {
> -    if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
> -        return EXCP_UDEF;
> -    }
>      value &= (1 << 31);
>      env->cp15.c9_pmcnten &= ~value;
>      return 0;
> @@ -536,9 +524,6 @@ static int pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
>  static int pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
>                          uint64_t value)
>  {
> -    if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
> -        return EXCP_UDEF;
> -    }
>      env->cp15.c9_pmovsr &= ~value;
>      return 0;
>  }
> @@ -546,9 +531,6 @@ static int pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
>  static int pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
>                              uint64_t value)
>  {
> -    if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
> -        return EXCP_UDEF;
> -    }
>      env->cp15.c9_pmxevtyper = value & 0xff;
>      return 0;
>  }
> @@ -624,37 +606,41 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
>      { .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 1,
>        .access = PL0_RW, .resetvalue = 0,
>        .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
> -      .readfn = pmreg_read, .writefn = pmcntenset_write,
> -      .raw_readfn = raw_read, .raw_writefn = raw_write },
> +      .writefn = pmcntenset_write,
> +      .accessfn = pmreg_access,
> +      .raw_writefn = raw_write },

A nit but,

You're field ordering scheme is inconsistent, here you go, write ->
access -> raw_write ....

>      { .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2,
>        .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
> -      .readfn = pmreg_read, .writefn = pmcntenclr_write,
> +      .accessfn = pmreg_access,
> +      .writefn = pmcntenclr_write,
>        .type = ARM_CP_NO_MIGRATE },
>      { .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3,
>        .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
> -      .readfn = pmreg_read, .writefn = pmovsr_write,
> -      .raw_readfn = raw_read, .raw_writefn = raw_write },
> -    /* Unimplemented so WI. Strictly speaking write accesses in PL0 should
> -     * respect PMUSERENR.
> -     */
> +      .accessfn = pmreg_access,
> +      .writefn = pmovsr_write,
> +      .raw_writefn = raw_write },

... and this is access -> write -> raw_write. Is there a prescribed
order to keep new (or gradually refactored) code consistent?

Regards,
Peter

> +    /* Unimplemented so WI. */
>      { .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
> -      .access = PL0_W, .type = ARM_CP_NOP },
> +      .access = PL0_W, .accessfn = pmreg_access, .type = ARM_CP_NOP },
>      /* Since we don't implement any events, writing to PMSELR is UNPREDICTABLE.
> -     * We choose to RAZ/WI. XXX should respect PMUSERENR.
> +     * We choose to RAZ/WI.
>       */
>      { .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
> -      .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
> -    /* Unimplemented, RAZ/WI. XXX PMUSERENR */
> +      .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0,
> +      .accessfn = pmreg_access },
> +    /* Unimplemented, RAZ/WI. */
>      { .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0,
> -      .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
> +      .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0,
> +      .accessfn = pmreg_access },
>      { .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1,
>        .access = PL0_RW,
>        .fieldoffset = offsetof(CPUARMState, cp15.c9_pmxevtyper),
> -      .readfn = pmreg_read, .writefn = pmxevtyper_write,
> -      .raw_readfn = raw_read, .raw_writefn = raw_write },
> -    /* Unimplemented, RAZ/WI. XXX PMUSERENR */
> +      .accessfn = pmreg_access, .writefn = pmxevtyper_write,
> +      .raw_writefn = raw_write },
> +    /* Unimplemented, RAZ/WI. */
>      { .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2,
> -      .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
> +      .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0,
> +      .accessfn = pmreg_access },
>      { .name = "PMUSERENR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 0,
>        .access = PL0_R | PL1_RW,
>        .fieldoffset = offsetof(CPUARMState, cp15.c9_pmuserenr),
> @@ -1708,8 +1694,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>              .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
>              .access = PL0_RW, .resetvalue = cpu->midr & 0xff000000,
>              .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
> -            .readfn = pmreg_read, .writefn = pmcr_write,
> -            .raw_readfn = raw_read, .raw_writefn = raw_write,
> +            .accessfn = pmreg_access, .writefn = pmcr_write,
> +            .raw_writefn = raw_write,
>          };
>          ARMCPRegInfo clidr = {
>              .name = "CLIDR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 18/35] target-arm: Fix incorrect type for value argument to write_raw_cp_reg
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 18/35] target-arm: Fix incorrect type for value argument to write_raw_cp_reg Peter Maydell
@ 2014-02-05  7:07   ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-05  7:07 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> The write_raw_cp_reg's value argument should be a uint64_t, since
> that's what all its callers hand it and what all the functions it
> calls take. A (harmless) typo meant we were accidentally declaring
> it as int64_t.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  target-arm/helper.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 577b060..06331dd 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -141,7 +141,7 @@ static uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri)
>  }
>
>  static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
> -                             int64_t v)
> +                             uint64_t v)
>  {
>      /* Raw write of a coprocessor register (as needed for migration, etc).
>       * Note that constant registers are treated as write-ignored; the
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 09/35] target-arm: A64: Implement MSR (immediate) instructions
  2014-02-05  6:23   ` Peter Crosthwaite
@ 2014-02-05 10:55     ` Peter Maydell
  2014-02-14 16:41     ` Peter Maydell
  1 sibling, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-02-05 10:55 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On 5 February 2014 06:23, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> Implement the MSR (immediate) instructions, which can update the
>> PSTATE SP and DAIF fields.
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> ---
>>  target-arm/cpu.h           |  1 +
>>  target-arm/helper.h        |  2 ++
>>  target-arm/op_helper.c     | 25 +++++++++++++++++++++++++
>>  target-arm/translate-a64.c | 24 +++++++++++++++++++++++-
>>  4 files changed, 51 insertions(+), 1 deletion(-)
>>
>> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
>> index 385cfcd..e66d464 100644
>> --- a/target-arm/cpu.h
>> +++ b/target-arm/cpu.h
>> @@ -426,6 +426,7 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
>>  #define PSTATE_Z (1U << 30)
>>  #define PSTATE_N (1U << 31)
>>  #define PSTATE_NZCV (PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V)
>> +#define PSTATE_DAIF (PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F)
>>  #define CACHED_PSTATE_BITS (PSTATE_NZCV)
>>  /* Mode values for AArch64 */
>>  #define PSTATE_MODE_EL3h 13
>> diff --git a/target-arm/helper.h b/target-arm/helper.h
>> index 71b8411..93a27ce 100644
>> --- a/target-arm/helper.h
>> +++ b/target-arm/helper.h
>> @@ -62,6 +62,8 @@ DEF_HELPER_2(get_cp_reg, i32, env, ptr)
>>  DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
>>  DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
>>
>> +DEF_HELPER_3(msr_i_pstate, void, env, i32, i32)
>> +
>>  DEF_HELPER_2(get_r13_banked, i32, env, i32)
>>  DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
>>
>> diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
>> index a918e5b..c812a9f 100644
>> --- a/target-arm/op_helper.c
>> +++ b/target-arm/op_helper.c
>> @@ -313,6 +313,31 @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
>>      return value;
>>  }
>>
>> +void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
>> +{
>> +    /* MSR_i to update PSTATE. This is OK from EL0 only if UMA is set.
>> +     * 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)) {
>> +        raise_exception(env, EXCP_UDEF);
>> +    }
>> +
>> +    switch (op) {
>> +    case 0x05: /* SPSel */
>> +        env->pstate = deposit32(env->pstate, 0, 1, imm);
>
> "0","1" hardcoded constants are a bit unfriendly. I guess the current
> macro set doesnt define _SHIFT and _WIDTH definitions, should they be
> added?
>
> FWIW, I have this macro in my tree which makes short work of defining
> mask, shift and width constants as a one liner:
>
> /* Define SHIFT, LENGTH and MASK constants for a field within a register */
>
> #define FIELD(reg, field, length, shift) \
> enum { reg ## _ ## field ## _SHIFT = (shift)}; \
> enum { reg ## _ ## field ## _LENGTH = (length)}; \
> enum { reg ## _ ## field ## _MASK = (((1ULL << (length)) - 1) \
>                                           << (shift)) };
>
> Usage would be something like FIELD(PSTATE, SPSEL, 1, 0)

Hmm. I guess we could use some more consistent structure in
defining bit macros. (reg, field, start, len) would be a better
argument order though, to match the extract and deposit fns.

>> +        break;
>> +    case 0x1e: /* DAIFSet */
>> +        env->pstate |= (imm << 6) & PSTATE_DAIF;
>> +        break;
>> +    case 0x1f: /* DAIFClear */
>> +        env->pstate &= ~((imm << 6) & PSTATE_DAIF);
>
> I wonder whether deposit should be extended with and/or (with
> existing) versions to allow for consistency in places like this. In
> SPSel we get the nice deposit based implementation but with the logic
> function change here were are stuck with open codedness. Set and
> clearing and fields should be common enough tree wide to warrant it
> perhaps.

I dunno. Deposit is a function mostly because "clear old
field to zeroes then insert new value" is complicated enough
that it's easy to miscode it. Plain force-set and force-clear
I think is simple enough (and not all that common) that I'm
happy to opencode it.

One point I need to think about a little more with the DAIF
bits is whether we should be keeping them in one place for
AArch32 and AArch64 -- at the moment an AArch32 core's
IF bits are in cpsr. Having them in one location would make
the cpu-exec.c code a bit simpler.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 12/35] target-arm: Convert performance monitor reginfo to accesfn
  2014-02-05  6:59   ` Peter Crosthwaite
@ 2014-02-05 11:01     ` Peter Maydell
  2014-02-06  0:05       ` Alistair Francis
  2014-02-09  2:59       ` Peter Crosthwaite
  0 siblings, 2 replies; 83+ messages in thread
From: Peter Maydell @ 2014-02-05 11:01 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alistair Francis,
	Alex Bennée, kvmarm, Christoffer Dall, Richard Henderson

On 5 February 2014 06:59, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> cc Alistair, this may conflict with his timer work.
>
> On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> @@ -624,37 +606,41 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
>>      { .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 1,
>>        .access = PL0_RW, .resetvalue = 0,
>>        .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
>> -      .readfn = pmreg_read, .writefn = pmcntenset_write,
>> -      .raw_readfn = raw_read, .raw_writefn = raw_write },
>> +      .writefn = pmcntenset_write,
>> +      .accessfn = pmreg_access,
>> +      .raw_writefn = raw_write },
>
> A nit but,
>
> You're field ordering scheme is inconsistent, here you go, write ->
> access -> raw_write ....
>
>>      { .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2,
>>        .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
>> -      .readfn = pmreg_read, .writefn = pmcntenclr_write,
>> +      .accessfn = pmreg_access,
>> +      .writefn = pmcntenclr_write,
>>        .type = ARM_CP_NO_MIGRATE },
>>      { .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3,
>>        .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
>> -      .readfn = pmreg_read, .writefn = pmovsr_write,
>> -      .raw_readfn = raw_read, .raw_writefn = raw_write },
>> -    /* Unimplemented so WI. Strictly speaking write accesses in PL0 should
>> -     * respect PMUSERENR.
>> -     */
>> +      .accessfn = pmreg_access,
>> +      .writefn = pmovsr_write,
>> +      .raw_writefn = raw_write },
>
> ... and this is access -> write -> raw_write. Is there a prescribed
> order to keep new (or gradually refactored) code consistent?

No, I've just been going for "whatever looks like it fits reasonably
neatly onto not too many lines and is a fairly minimal change to existing
structs", mostly. The thing I have been trying to be consistent with is
the order for crn/crm/opc1/opc2 fields, which for new registers I've been
making be op0/op1/crn/crm/op2, because that's the order the ARM ARM
seems to have settled on. Unfortunately a lot of our existing definitions
are crn/crm/op1/op2, because at the time there was variance in the
ARM docs and that order seemed sensible to me.

For the other fields, I think "name first; type/state/encoding second;
access related fields; read and write accessors; reset stuff" is probably
not a bad order. But the nice thing about having named fields is it
doesn't actually matter what order things go in.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 12/35] target-arm: Convert performance monitor reginfo to accesfn
  2014-02-05 11:01     ` Peter Maydell
@ 2014-02-06  0:05       ` Alistair Francis
  2014-02-09  2:59       ` Peter Crosthwaite
  1 sibling, 0 replies; 83+ messages in thread
From: Alistair Francis @ 2014-02-06  0:05 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Peter Crosthwaite, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Laurent Desnogues,
	Alistair Francis, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

On Wed, Feb 5, 2014 at 9:01 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 5 February 2014 06:59, Peter Crosthwaite
> <peter.crosthwaite@xilinx.com> wrote:
>> cc Alistair, this may conflict with his timer work.

It seems fine to me. None of Peter's code changes conflict with mine,
except for adding the ".accessfn = pmreg_access," to the PMCCNTR
register. My patch never implemented the return EXCP_UDEF; so no
action is needed there

>>
>> On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>> @@ -624,37 +606,41 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
>>>      { .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 1,
>>>        .access = PL0_RW, .resetvalue = 0,
>>>        .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
>>> -      .readfn = pmreg_read, .writefn = pmcntenset_write,
>>> -      .raw_readfn = raw_read, .raw_writefn = raw_write },
>>> +      .writefn = pmcntenset_write,
>>> +      .accessfn = pmreg_access,
>>> +      .raw_writefn = raw_write },
>>
>> A nit but,
>>
>> You're field ordering scheme is inconsistent, here you go, write ->
>> access -> raw_write ....
>>
>>>      { .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2,
>>>        .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
>>> -      .readfn = pmreg_read, .writefn = pmcntenclr_write,
>>> +      .accessfn = pmreg_access,
>>> +      .writefn = pmcntenclr_write,
>>>        .type = ARM_CP_NO_MIGRATE },
>>>      { .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3,
>>>        .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
>>> -      .readfn = pmreg_read, .writefn = pmovsr_write,
>>> -      .raw_readfn = raw_read, .raw_writefn = raw_write },
>>> -    /* Unimplemented so WI. Strictly speaking write accesses in PL0 should
>>> -     * respect PMUSERENR.
>>> -     */
>>> +      .accessfn = pmreg_access,
>>> +      .writefn = pmovsr_write,
>>> +      .raw_writefn = raw_write },
>>
>> ... and this is access -> write -> raw_write. Is there a prescribed
>> order to keep new (or gradually refactored) code consistent?
>
> No, I've just been going for "whatever looks like it fits reasonably
> neatly onto not too many lines and is a fairly minimal change to existing
> structs", mostly. The thing I have been trying to be consistent with is
> the order for crn/crm/opc1/opc2 fields, which for new registers I've been
> making be op0/op1/crn/crm/op2, because that's the order the ARM ARM
> seems to have settled on. Unfortunately a lot of our existing definitions
> are crn/crm/op1/op2, because at the time there was variance in the
> ARM docs and that order seemed sensible to me.
>
> For the other fields, I think "name first; type/state/encoding second;
> access related fields; read and write accessors; reset stuff" is probably
> not a bad order. But the nice thing about having named fields is it
> doesn't actually matter what order things go in.
>
> thanks
> -- PMM
>

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

* Re: [Qemu-devel] [PATCH v2 23/35] target-arm: Implement AArch64 cache invalidate/clean ops
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 23/35] target-arm: Implement AArch64 cache invalidate/clean ops Peter Maydell
@ 2014-02-06 11:45   ` Peter Maydell
  2014-02-09  2:22   ` Peter Crosthwaite
  1 sibling, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-02-06 11:45 UTC (permalink / raw)
  To: QEMU Developers
  Cc: Rob Herring, Peter Crosthwaite, Laurent Desnogues,
	Patch Tracking, Michael Matz, Alexander Graf, Claudio Fontana,
	Dirk Mueller, Will Newton, Alex Bennée, kvmarm,
	Christoffer Dall, Richard Henderson

On 31 January 2014 15:45, Peter Maydell <peter.maydell@linaro.org> wrote:
> Implement all the AArch64 cache invalidate and clean ops
> (which are all NOPs since QEMU doesn't emulate the cache).
> The only remaining unimplemented cache op is DC ZVA.

Alex pointed out to me on IRC that since userspace can
use these operations we really need them for linux-user
mode. I'd appreciate review on the various bits of this
patchset that are dependencies for getting this into
master before 2.0 freeze (whenever that is)...

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 19/35] target-arm: A64: Make cache ID registers visible to AArch64
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 19/35] target-arm: A64: Make cache ID registers visible to AArch64 Peter Maydell
@ 2014-02-07  7:35   ` Hu Tao
  2014-02-07 10:27     ` Peter Maydell
  2014-02-09  2:15   ` Peter Crosthwaite
  1 sibling, 1 reply; 83+ messages in thread
From: Hu Tao @ 2014-02-07  7:35 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Peter Crosthwaite, Laurent Desnogues, patches,
	Michael Matz, qemu-devel, Claudio Fontana, Dirk Mueller,
	Will Newton, kvmarm, Richard Henderson

On Fri, Jan 31, 2014 at 03:45:27PM +0000, Peter Maydell wrote:
> Make the cache ID system registers (CLIDR, CCSELR, CCSIDR, CTR)

s/CCSELR/CSSELR/

> visible to AArch64. These are mostly simple 64-bit extensions of the
> existing 32 bit system registers and so can share reginfo definitions.

According to the document(ARM DDI 0487A.a), some AArch64 system
registers are 32-bit, for example CCSIDR_EL1 is 32-bit. But System_Put()
and System_Get() writes/reads 64-bit values, which makes me confused.

> CTR needs to have a split definition, but we can clean up the
> temporary user-mode implementation in favour of using the CPU-specified
> reset value, and implement the system-mode-required semantics of
> restricting its EL0 accessibility if SCTLR.UCT is not set.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target-arm/cpu.c    |  2 ++
>  target-arm/cpu.h    |  2 +-
>  target-arm/cpu64.c  |  1 +
>  target-arm/helper.c | 31 +++++++++++++++++++++----------
>  4 files changed, 25 insertions(+), 11 deletions(-)
> 
> diff --git a/target-arm/cpu.c b/target-arm/cpu.c
> index fe18b65..8fed098 100644
> --- a/target-arm/cpu.c
> +++ b/target-arm/cpu.c
> @@ -91,6 +91,8 @@ static void arm_cpu_reset(CPUState *s)
>          env->aarch64 = 1;
>  #if defined(CONFIG_USER_ONLY)
>          env->pstate = PSTATE_MODE_EL0t;
> +        /* Userspace expects access to CTL_EL0 */
> +        env->cp15.c1_sys |= SCTLR_UCT;
>  #else
>          env->pstate = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F
>              | PSTATE_MODE_EL1h;
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index d1ed423..f5b706e 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -166,7 +166,7 @@ typedef struct CPUARMState {
>      /* System control coprocessor (cp15) */
>      struct {
>          uint32_t c0_cpuid;
> -        uint32_t c0_cssel; /* Cache size selection.  */
> +        uint64_t c0_cssel; /* Cache size selection.  */

I see all backing fields for AArch64 system registers are converted to
uint64_t, why not convert ARMCPU.ccsidr which backs CCSIDR?

-- 
Regards,
Hu Tao

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

* Re: [Qemu-devel] [PATCH v2 19/35] target-arm: A64: Make cache ID registers visible to AArch64
  2014-02-07  7:35   ` Hu Tao
@ 2014-02-07 10:27     ` Peter Maydell
  2014-02-11  8:38       ` Hu Tao
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-02-07 10:27 UTC (permalink / raw)
  To: Hu Tao
  Cc: Rob Herring, Peter Crosthwaite, Laurent Desnogues,
	Patch Tracking, Michael Matz, QEMU Developers, Claudio Fontana,
	Dirk Mueller, Will Newton, kvmarm, Richard Henderson

On 7 February 2014 07:35, Hu Tao <hutao@cn.fujitsu.com> wrote:
> On Fri, Jan 31, 2014 at 03:45:27PM +0000, Peter Maydell wrote:
>> Make the cache ID system registers (CLIDR, CCSELR, CCSIDR, CTR)
>
> s/CCSELR/CSSELR/
>
>> visible to AArch64. These are mostly simple 64-bit extensions of the
>> existing 32 bit system registers and so can share reginfo definitions.
>
> According to the document(ARM DDI 0487A.a), some AArch64 system
> registers are 32-bit, for example CCSIDR_EL1 is 32-bit. But System_Put()
> and System_Get() writes/reads 64-bit values, which makes me confused.

We've been round this issue before. The documentation
uses "32-bit" as a shorthand for "64 bit but the top
32 bits are RES0". There is no way in AArch64 to do a
32 bit read or write of a system register -- the only
instructions are MSR/MRS, which are always 64 bits.
Similarly, the KVM kernel API exposes all registers as
64 bits wide.

We could in theory have a mechanism that allowed a
64 bit system register access to be backed by a 32 bit
field value, but it's simpler not to.

>> CTR needs to have a split definition, but we can clean up the
>> temporary user-mode implementation in favour of using the CPU-specified
>> reset value, and implement the system-mode-required semantics of
>> restricting its EL0 accessibility if SCTLR.UCT is not set.
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> ---
>>  target-arm/cpu.c    |  2 ++
>>  target-arm/cpu.h    |  2 +-
>>  target-arm/cpu64.c  |  1 +
>>  target-arm/helper.c | 31 +++++++++++++++++++++----------
>>  4 files changed, 25 insertions(+), 11 deletions(-)
>>
>> diff --git a/target-arm/cpu.c b/target-arm/cpu.c
>> index fe18b65..8fed098 100644
>> --- a/target-arm/cpu.c
>> +++ b/target-arm/cpu.c
>> @@ -91,6 +91,8 @@ static void arm_cpu_reset(CPUState *s)
>>          env->aarch64 = 1;
>>  #if defined(CONFIG_USER_ONLY)
>>          env->pstate = PSTATE_MODE_EL0t;
>> +        /* Userspace expects access to CTL_EL0 */
>> +        env->cp15.c1_sys |= SCTLR_UCT;
>>  #else
>>          env->pstate = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F
>>              | PSTATE_MODE_EL1h;
>> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
>> index d1ed423..f5b706e 100644
>> --- a/target-arm/cpu.h
>> +++ b/target-arm/cpu.h
>> @@ -166,7 +166,7 @@ typedef struct CPUARMState {
>>      /* System control coprocessor (cp15) */
>>      struct {
>>          uint32_t c0_cpuid;
>> -        uint32_t c0_cssel; /* Cache size selection.  */
>> +        uint64_t c0_cssel; /* Cache size selection.  */
>
> I see all backing fields for AArch64 system registers are converted to
> uint64_t, why not convert ARMCPU.ccsidr which backs CCSIDR?

It's not directly accessed via a .fieldoffset() entry,
so there's no requirement for it to be 64 bits wide.
I've also generally left the ARMCPU values which are
just constants to be used in ".resetvalue =" specifications
alone. It's only the cases where a struct field is the
backing storage for the register that need widening.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 19/35] target-arm: A64: Make cache ID registers visible to AArch64
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 19/35] target-arm: A64: Make cache ID registers visible to AArch64 Peter Maydell
  2014-02-07  7:35   ` Hu Tao
@ 2014-02-09  2:15   ` Peter Crosthwaite
  2014-02-09 11:52     ` Peter Maydell
  1 sibling, 1 reply; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  2:15 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Make the cache ID system registers (CLIDR, CCSELR, CCSIDR, CTR)
> visible to AArch64. These are mostly simple 64-bit extensions of the
> existing 32 bit system registers and so can share reginfo definitions.
> CTR needs to have a split definition, but we can clean up the
> temporary user-mode implementation in favour of using the CPU-specified
> reset value, and implement the system-mode-required semantics of
> restricting its EL0 accessibility if SCTLR.UCT is not set.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target-arm/cpu.c    |  2 ++
>  target-arm/cpu.h    |  2 +-
>  target-arm/cpu64.c  |  1 +
>  target-arm/helper.c | 31 +++++++++++++++++++++----------
>  4 files changed, 25 insertions(+), 11 deletions(-)
>
> diff --git a/target-arm/cpu.c b/target-arm/cpu.c
> index fe18b65..8fed098 100644
> --- a/target-arm/cpu.c
> +++ b/target-arm/cpu.c
> @@ -91,6 +91,8 @@ static void arm_cpu_reset(CPUState *s)
>          env->aarch64 = 1;
>  #if defined(CONFIG_USER_ONLY)
>          env->pstate = PSTATE_MODE_EL0t;
> +        /* Userspace expects access to CTL_EL0 */
> +        env->cp15.c1_sys |= SCTLR_UCT;
>  #else
>          env->pstate = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F
>              | PSTATE_MODE_EL1h;
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index d1ed423..f5b706e 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -166,7 +166,7 @@ typedef struct CPUARMState {
>      /* System control coprocessor (cp15) */
>      struct {
>          uint32_t c0_cpuid;
> -        uint32_t c0_cssel; /* Cache size selection.  */
> +        uint64_t c0_cssel; /* Cache size selection.  */
>          uint32_t c1_sys; /* System control register.  */
>          uint32_t c1_coproc; /* Coprocessor access register.  */
>          uint32_t c1_xscaleauxcr; /* XScale auxiliary control register.  */
> diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c
> index a639c2e..8426bf1 100644
> --- a/target-arm/cpu64.c
> +++ b/target-arm/cpu64.c
> @@ -45,6 +45,7 @@ static void aarch64_any_initfn(Object *obj)
>      set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
>      set_feature(&cpu->env, ARM_FEATURE_V7MP);
>      set_feature(&cpu->env, ARM_FEATURE_AARCH64);
> +    cpu->ctr = 0x80030003; /* 32 byte I and D cacheline size, VIPT icache */
>  }
>  #endif
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 06331dd..f46dd0f 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -629,9 +629,11 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
>      { .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", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
> +    { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
> +      .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,

Why is the .cp field lost in the conversion to STATE_BOTH?

Regards,
Peter

>        .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_MIGRATE },
> -    { .name = "CSSELR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
> +    { .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
> +      .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
>        .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c0_cssel),
>        .writefn = csselr_write, .resetvalue = 0 },
>      /* Auxiliary ID register: this actually has an IMPDEF value but for now
> @@ -1524,13 +1526,6 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
>      { .name = "FPSR", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 4,
>        .access = PL0_RW, .readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write },
> -    /* This claims a 32 byte cacheline size for icache and dcache, VIPT icache.
> -     * It will eventually need to have a CPU-specified reset value.
> -     */
> -    { .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,
> -      .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,
> -      .access = PL0_R, .type = ARM_CP_CONST,
> -      .resetvalue = 0x80030003 },
>      /* Prohibit use of DC ZVA. OPTME: implement DC ZVA and allow its use.
>       * For system mode the DZP bit here will need to be computed, not constant.
>       */
> @@ -1550,6 +1545,17 @@ static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
>      tlb_flush(env, 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)) {
> +        return CP_ACCESS_TRAP;
> +    }
> +    return CP_ACCESS_OK;
> +}
> +
>  void register_cp_regs_for_features(ARMCPU *cpu)
>  {
>      /* Register all the coprocessor registers based on feature bits */
> @@ -1634,7 +1640,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>              .raw_writefn = raw_write,
>          };
>          ARMCPRegInfo clidr = {
> -            .name = "CLIDR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
> +            .name = "CLIDR", .state = ARM_CP_STATE_BOTH,
> +            .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
>              .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->clidr
>          };
>          define_one_arm_cp_reg(cpu, &pmcr);
> @@ -1713,6 +1720,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>              { .name = "CTR",
>                .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1,
>                .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
> +            { .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,
> +              .access = PL0_R, .accessfn = ctr_el0_access,
> +              .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
>              { .name = "TCMTR",
>                .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 2,
>                .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 20/35] target-arm: Implement AArch64 CurrentEL sysreg
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 20/35] target-arm: Implement AArch64 CurrentEL sysreg Peter Maydell
@ 2014-02-09  2:17   ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  2:17 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Implement the CurrentEL sysreg.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  target-arm/cpu.h           | 3 ++-
>  target-arm/helper.c        | 3 +++
>  target-arm/translate-a64.c | 7 +++++++
>  3 files changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index f5b706e..e0e3736 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -732,7 +732,8 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
>  #define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8))
>  #define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8))
>  #define ARM_CP_NZCV (ARM_CP_SPECIAL | (3 << 8))
> -#define ARM_LAST_SPECIAL ARM_CP_NZCV
> +#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8))
> +#define ARM_LAST_SPECIAL ARM_CP_CURRENTEL
>  /* Used only as a terminator for ARMCPRegInfo lists */
>  #define ARM_CP_SENTINEL 0xffff
>  /* Mask of only the flag bits in a type field */
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index f46dd0f..0538f78 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1533,6 +1533,9 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
>        .opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0,
>        .access = PL0_R, .type = ARM_CP_CONST,
>        .resetvalue = 0x10 },
> +    { .name = "CURRENTEL", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 3, .opc1 = 0, .opc2 = 2, .crn = 4, .crm = 2,
> +      .access = PL1_R, .type = ARM_CP_CURRENTEL },
>      REGINFO_SENTINEL
>  };
>
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index f437359..fa8d7ac 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -1233,6 +1233,13 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
>              gen_set_nzcv(tcg_rt);
>          }
>          return;
> +    case ARM_CP_CURRENTEL:
> +        /* Reads as current EL value from pstate, which is
> +         * guaranteed to be constant by the tb flags.
> +         */
> +        tcg_rt = cpu_reg(s, rt);
> +        tcg_gen_movi_i64(tcg_rt, s->current_pl << 2);
> +        return;
>      default:
>          break;
>      }
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 22/35] target-arm: Implement AArch64 DAIF system register
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 22/35] target-arm: Implement AArch64 DAIF system register Peter Maydell
@ 2014-02-09  2:20   ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  2:20 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Implement the DAIF system register which is a view of the
> DAIF bits in PSTATE.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  target-arm/helper.c | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index f67cf5e..82efbfa 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1513,6 +1513,26 @@ static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
>      vfp_set_fpsr(env, value);
>  }
>
> +static CPAccessResult aa64_daif_access(CPUARMState *env, const ARMCPRegInfo *ri)
> +{
> +    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
> +        return CP_ACCESS_TRAP;
> +    }
> +    return CP_ACCESS_OK;
> +}
> +
> +static uint64_t aa64_daif_read(CPUARMState *env, const ARMCPRegInfo *ri)
> +{
> +    return pstate_read(env) & PSTATE_DAIF;
> +}
> +
> +static void aa64_daif_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                            uint64_t value)
> +{
> +    env->pstate &= ~PSTATE_DAIF;
> +    env->pstate |= (value & PSTATE_DAIF);
> +}
> +
>  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.
> @@ -1520,6 +1540,11 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
>      { .name = "NZCV", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 2,
>        .access = PL0_RW, .type = ARM_CP_NZCV },
> +    { .name = "DAIF", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 2,
> +      .access = PL0_RW, .type = ARM_CP_NO_MIGRATE,
> +      .readfn = aa64_daif_read, .writefn = aa64_daif_write,
> +      .accessfn = aa64_daif_access },
>      { .name = "FPCR", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 4,
>        .access = PL0_RW, .readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write },
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 23/35] target-arm: Implement AArch64 cache invalidate/clean ops
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 23/35] target-arm: Implement AArch64 cache invalidate/clean ops Peter Maydell
  2014-02-06 11:45   ` Peter Maydell
@ 2014-02-09  2:22   ` Peter Crosthwaite
  1 sibling, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  2:22 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Implement all the AArch64 cache invalidate and clean ops
> (which are all NOPs since QEMU doesn't emulate the cache).
> The only remaining unimplemented cache op is DC ZVA.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  target-arm/helper.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 82efbfa..b9ed707 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1533,6 +1533,18 @@ static void aa64_daif_write(CPUARMState *env, const ARMCPRegInfo *ri,
>      env->pstate |= (value & PSTATE_DAIF);
>  }
>
> +static CPAccessResult aa64_cacheop_access(CPUARMState *env,
> +                                          const ARMCPRegInfo *ri)
> +{
> +    /* 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)) {
> +        return CP_ACCESS_TRAP;
> +    }
> +    return CP_ACCESS_OK;
> +}
> +
>  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.
> @@ -1561,6 +1573,41 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
>      { .name = "CURRENTEL", .state = ARM_CP_STATE_AA64,
>        .opc0 = 3, .opc1 = 0, .opc2 = 2, .crn = 4, .crm = 2,
>        .access = PL1_R, .type = ARM_CP_CURRENTEL },
> +    /* Cache ops: all NOPs since we don't emulate caches */
> +    { .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
> +      .access = PL1_W, .type = ARM_CP_NOP },
> +    { .name = "IC_IALLU", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0,
> +      .access = PL1_W, .type = ARM_CP_NOP },
> +    { .name = "IC_IVAU", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1,
> +      .access = PL0_W, .type = ARM_CP_NOP,
> +      .accessfn = aa64_cacheop_access },
> +    { .name = "DC_IVAC", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
> +      .access = PL1_W, .type = ARM_CP_NOP },
> +    { .name = "DC_ISW", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
> +      .access = PL1_W, .type = ARM_CP_NOP },
> +    { .name = "DC_CVAC", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1,
> +      .access = PL0_W, .type = ARM_CP_NOP,
> +      .accessfn = aa64_cacheop_access },
> +    { .name = "DC_CSW", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
> +      .access = PL1_W, .type = ARM_CP_NOP },
> +    { .name = "DC_CVAU", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 11, .opc2 = 1,
> +      .access = PL0_W, .type = ARM_CP_NOP,
> +      .accessfn = aa64_cacheop_access },
> +    { .name = "DC_CIVAC", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 1,
> +      .access = PL0_W, .type = ARM_CP_NOP,
> +      .accessfn = aa64_cacheop_access },
> +    { .name = "DC_CISW", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
> +      .access = PL1_W, .type = ARM_CP_NOP },
>      REGINFO_SENTINEL
>  };
>
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 25/35] target-arm: Implement AArch64 dummy MDSCR_EL1
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 25/35] target-arm: Implement AArch64 dummy MDSCR_EL1 Peter Maydell
@ 2014-02-09  2:27   ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  2:27 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> We don't support letting the guest do debug, but Linux prods the
> monitor debug system control register anyway, so implement a dummy
> RAZ/WI version.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  target-arm/helper.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 0dcb5b1..b0d28ca 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1681,6 +1681,12 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
>        .opc0 = 1, .opc2 = 0, .crn = 8, .crm = 7, .opc2 = 7,
>        .access = PL1_W, .type = ARM_CP_NO_MIGRATE,
>        .writefn = tlbi_aa64_vaa_write },
> +    /* Dummy implementation of monitor debug system control register:
> +     * we don't support debug.
> +     */
> +    { .name = "MDSCR_EL1", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
> +      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
>      REGINFO_SENTINEL
>  };
>
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 26/35] target-arm: Implement AArch64 memory attribute registers
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 26/35] target-arm: Implement AArch64 memory attribute registers Peter Maydell
@ 2014-02-09  2:31   ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  2:31 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Implement the AArch64 memory attribute registers. Since QEMU doesn't
> model caches it does not need to care about memory attributes at all,
> and we can simply make these read-as-written.
>
> We did not previously implement the AArch32 versions of the MAIR
> registers, which went unnoticed because of the overbroad TLB_LOCKDOWN
> reginfo definition; provide them now to keep the 64<->32 register
> relationship clear.
>
> We already provided AMAIR registers for 32 bit as simple RAZ/WI;
> extend that to provide a 64 bit RAZ/WI AMAIR_EL1.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  target-arm/cpu.h    |  3 +++
>  target-arm/helper.c | 24 +++++++++++++++++++++++-
>  2 files changed, 26 insertions(+), 1 deletion(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index e0e3736..a08c02b 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -74,8 +74,10 @@
>   */
>  #ifdef HOST_WORDS_BIGENDIAN
>  #define offsetoflow32(S, M) (offsetof(S, M) + sizeof(uint32_t))
> +#define offsetofhigh32(S, M) offsetof(S, M)
>  #else
>  #define offsetoflow32(S, M) offsetof(S, M)
> +#define offsetofhigh32(S, M) (offsetof(S, M) + sizeof(uint32_t))
>  #endif
>
>  /* Meanings of the ARMCPU object's two inbound GPIO lines */
> @@ -197,6 +199,7 @@ typedef struct CPUARMState {
>          uint32_t c9_pmxevtyper; /* perf monitor event type */
>          uint32_t c9_pmuserenr; /* perf monitor user enable */
>          uint32_t c9_pminten; /* perf monitor interrupt enables */
> +        uint64_t mair_el1;
>          uint32_t c12_vbar; /* vector base address register */
>          uint32_t c13_fcse; /* FCSE PID.  */
>          uint32_t c13_context; /* Context ID.  */
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index b0d28ca..32bface 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -641,6 +641,26 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
>       */
>      { .name = "AIDR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 7,
>        .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
> +    /* MAIR can just read-as-written because we don't implement caches
> +     * and so don't need to care about memory attributes.
> +     */
> +    { .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
> +      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el1),
> +      .resetvalue = 0 },
> +    /* For non-long-descriptor page tables these are PRRR and NMRR;
> +     * regardless they still act as reads-as-written for QEMU.
> +     * The override is necessary because of the overly-broad TLB_LOCKDOWN
> +     * definition.
> +     */
> +    { .name = "MAIR0", .state = ARM_CP_STATE_AA32, .type = ARM_CP_OVERRIDE,
> +      .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0, .access = PL1_RW,
> +      .fieldoffset = offsetoflow32(CPUARMState, cp15.mair_el1),
> +      .resetfn = arm_cp_reset_ignore },
> +    { .name = "MAIR1", .state = ARM_CP_STATE_AA32, .type = ARM_CP_OVERRIDE,
> +      .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1, .access = PL1_RW,
> +      .fieldoffset = offsetofhigh32(CPUARMState, cp15.mair_el1),
> +      .resetfn = arm_cp_reset_ignore },
>      REGINFO_SENTINEL
>  };
>
> @@ -1467,9 +1487,11 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
>      /* NOP AMAIR0/1: the override is because these clash with the rather
>       * broadly specified TLB_LOCKDOWN entry in the generic cp_reginfo.
>       */
> -    { .name = "AMAIR0", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0,
> +    { .name = "AMAIR0", .state = ARM_CP_STATE_BOTH,
> +      .opc0 = 3, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0,
>        .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_OVERRIDE,
>        .resetvalue = 0 },
> +    /* AMAIR1 is mapped to AMAIR_EL1[63:32] */
>      { .name = "AMAIR1", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 1,
>        .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_OVERRIDE,
>        .resetvalue = 0 },
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 27/35] target-arm: Implement AArch64 SCTLR_EL1
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 27/35] target-arm: Implement AArch64 SCTLR_EL1 Peter Maydell
@ 2014-02-09  2:32   ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  2:32 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Implement the AArch64 view of the system control register SCTLR_EL1.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  target-arm/cpu.h    | 2 +-
>  target-arm/helper.c | 3 ++-
>  2 files changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index a08c02b..1fb9675 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -169,7 +169,7 @@ typedef struct CPUARMState {
>      struct {
>          uint32_t c0_cpuid;
>          uint64_t c0_cssel; /* Cache size selection.  */
> -        uint32_t c1_sys; /* System control register.  */
> +        uint64_t c1_sys; /* System control register.  */
>          uint32_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 32bface..7f466d6 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1973,7 +1973,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>      /* Generic registers whose values depend on the implementation */
>      {
>          ARMCPRegInfo sctlr = {
> -            .name = "SCTLR", .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
> +            .name = "SCTLR", .state = ARM_CP_STATE_BOTH,
> +            .opc0 = 3, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
>              .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_sys),
>              .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
>              .raw_writefn = raw_write,
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 28/35] target-arm: Implement AArch64 TCR_EL1
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 28/35] target-arm: Implement AArch64 TCR_EL1 Peter Maydell
@ 2014-02-09  2:35   ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  2:35 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Implement the AArch64 TCR_EL1, which is the 64 bit view of
> the AArch32 TTBCR. (The uses of the bits in the register are
> completely different, but in any given situation the CPU will
> always interpret them one way or the other. In fact for QEMU EL1
> is always 64 bit, but we share the state field because this
> is the correct mapping to permit a future implementation of EL2.)
> We also make the AArch64 view the 'master' as far as migration
> and reset is concerned.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  target-arm/cpu.h    |  2 +-
>  target-arm/helper.c | 19 ++++++++++++++++---
>  2 files changed, 17 insertions(+), 4 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 1fb9675..38f8eed 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -177,7 +177,7 @@ typedef struct CPUARMState {
>          uint32_t c2_base0_hi; /* MMU translation table base 0, high 32 bits */
>          uint32_t c2_base1; /* MMU translation table base 0.  */
>          uint32_t c2_base1_hi; /* MMU translation table base 1, high 32 bits */
> -        uint32_t c2_control; /* MMU translation table base control.  */
> +        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. */
>          uint32_t c2_data; /* MPU data cachable bits.  */
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 7f466d6..b527fe3 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1215,6 +1215,14 @@ static void vmsa_ttbcr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
>      env->cp15.c2_mask = 0;
>  }
>
> +static void vmsa_tcr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                               uint64_t value)
> +{
> +    /* For AArch64 the A1 bit could result in a change of ASID, so TLB flush. */
> +    tlb_flush(env, 1);
> +    env->cp15.c2_control = value;
> +}
> +
>  static const ARMCPRegInfo vmsa_cp_reginfo[] = {
>      { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
>        .access = PL1_RW,
> @@ -1228,10 +1236,15 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
>      { .name = "TTBR1", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1,
>        .access = PL1_RW,
>        .fieldoffset = offsetof(CPUARMState, cp15.c2_base1), .resetvalue = 0, },
> -    { .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
> -      .access = PL1_RW, .writefn = vmsa_ttbcr_write,
> -      .resetfn = vmsa_ttbcr_reset, .raw_writefn = vmsa_ttbcr_raw_write,
> +    { .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,
> +      .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
>        .fieldoffset = offsetof(CPUARMState, cp15.c2_control) },
> +    { .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) },
>      { .name = "DFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
>        .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c6_data),
>        .resetvalue = 0, },
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 30/35] target-arm: Implement AArch64 TTBR*
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 30/35] target-arm: Implement AArch64 TTBR* Peter Maydell
@ 2014-02-09  2:38   ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  2:38 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Implement the AArch64 TTBR* registers. For v7 these were already 64 bits
> to handle LPAE, but implemented as two separate uint32_t fields.
> Combine them into a single uint64_t which can be used for all purposes.
> Since this requires touching every use, take the opportunity to rename
> the field to the architectural name.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  hw/arm/pxa2xx.c     |  2 +-
>  target-arm/cpu.h    |  6 ++--
>  target-arm/helper.c | 89 ++++++++++++++++++-----------------------------------
>  3 files changed, 33 insertions(+), 64 deletions(-)
>
> diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
> index bf9416a..88f0988 100644
> --- a/hw/arm/pxa2xx.c
> +++ b/hw/arm/pxa2xx.c
> @@ -276,7 +276,7 @@ static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
>              ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
>          s->cpu->env.cp15.c1_sys = 0;
>          s->cpu->env.cp15.c1_coproc = 0;
> -        s->cpu->env.cp15.c2_base0 = 0;
> +        s->cpu->env.cp15.ttbr0_el1 = 0;
>          s->cpu->env.cp15.c3 = 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 270e51e..3151329 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -173,10 +173,8 @@ typedef struct CPUARMState {
>          uint32_t c1_coproc; /* Coprocessor access register.  */
>          uint32_t c1_xscaleauxcr; /* XScale auxiliary control register.  */
>          uint32_t c1_scr; /* secure config register.  */
> -        uint32_t c2_base0; /* MMU translation table base 0.  */
> -        uint32_t c2_base0_hi; /* MMU translation table base 0, high 32 bits */
> -        uint32_t c2_base1; /* MMU translation table base 0.  */
> -        uint32_t c2_base1_hi; /* MMU translation table base 1, high 32 bits */
> +        uint64_t ttbr0_el1; /* MMU translation table base 0. */
> +        uint32_t ttbr1_el1; /* MMU translation table base 1. */
>          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 0dcd5de..a23b40d 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1230,6 +1230,18 @@ static void vmsa_tcr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
>      env->cp15.c2_control = value;
>  }
>
> +static void vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                            uint64_t value)
> +{
> +    /* 64 bit accesses to the TTBRs can change the ASID and so we
> +     * must flush the TLB.
> +     */
> +    if (cpreg_field_is_64bit(ri)) {
> +        tlb_flush(env, 1);
> +    }
> +    raw_write(env, ri, value);
> +}
> +
>  static const ARMCPRegInfo vmsa_cp_reginfo[] = {
>      { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
>        .access = PL1_RW,
> @@ -1237,12 +1249,14 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
>      { .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
>        .access = PL1_RW,
>        .fieldoffset = offsetof(CPUARMState, cp15.c5_insn), .resetvalue = 0, },
> -    { .name = "TTBR0", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
> -      .access = PL1_RW,
> -      .fieldoffset = offsetof(CPUARMState, cp15.c2_base0), .resetvalue = 0, },
> -    { .name = "TTBR1", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1,
> -      .access = PL1_RW,
> -      .fieldoffset = offsetof(CPUARMState, cp15.c2_base1), .resetvalue = 0, },
> +    { .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
> +      .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
> +      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el1),
> +      .writefn = vmsa_ttbr_write, .resetvalue = 0 },
> +    { .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
> +      .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1,
> +      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el1),
> +      .writefn = vmsa_ttbr_write, .resetvalue = 0 },
>      { .name = "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,
> @@ -1459,50 +1473,6 @@ static void par64_reset(CPUARMState *env, const ARMCPRegInfo *ri)
>      env->cp15.c7_par = 0;
>  }
>
> -static uint64_t ttbr064_read(CPUARMState *env, const ARMCPRegInfo *ri)
> -{
> -    return ((uint64_t)env->cp15.c2_base0_hi << 32) | env->cp15.c2_base0;
> -}
> -
> -static void ttbr064_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                              uint64_t value)
> -{
> -    env->cp15.c2_base0_hi = value >> 32;
> -    env->cp15.c2_base0 = value;
> -}
> -
> -static void ttbr064_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                          uint64_t value)
> -{
> -    /* Writes to the 64 bit format TTBRs may change the ASID */
> -    tlb_flush(env, 1);
> -    ttbr064_raw_write(env, ri, value);
> -}
> -
> -static void ttbr064_reset(CPUARMState *env, const ARMCPRegInfo *ri)
> -{
> -    env->cp15.c2_base0_hi = 0;
> -    env->cp15.c2_base0 = 0;
> -}
> -
> -static uint64_t ttbr164_read(CPUARMState *env, const ARMCPRegInfo *ri)
> -{
> -    return ((uint64_t)env->cp15.c2_base1_hi << 32) | env->cp15.c2_base1;
> -}
> -
> -static void ttbr164_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                          uint64_t value)
> -{
> -    env->cp15.c2_base1_hi = value >> 32;
> -    env->cp15.c2_base1 = value;
> -}
> -
> -static void ttbr164_reset(CPUARMState *env, const ARMCPRegInfo *ri)
> -{
> -    env->cp15.c2_base1_hi = 0;
> -    env->cp15.c2_base1 = 0;
> -}
> -
>  static const ARMCPRegInfo lpae_cp_reginfo[] = {
>      /* NOP AMAIR0/1: the override is because these clash with the rather
>       * broadly specified TLB_LOCKDOWN entry in the generic cp_reginfo.
> @@ -1524,12 +1494,13 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
>        .access = PL1_RW, .type = ARM_CP_64BIT,
>        .readfn = par64_read, .writefn = par64_write, .resetfn = par64_reset },
>      { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0,
> -      .access = PL1_RW, .type = ARM_CP_64BIT, .readfn = ttbr064_read,
> -      .writefn = ttbr064_write, .raw_writefn = ttbr064_raw_write,
> -      .resetfn = ttbr064_reset },
> +      .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE,
> +      .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el1),
> +      .writefn = vmsa_ttbr_write, .resetfn = arm_cp_reset_ignore },
>      { .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1,
> -      .access = PL1_RW, .type = ARM_CP_64BIT, .readfn = ttbr164_read,
> -      .writefn = ttbr164_write, .resetfn = ttbr164_reset },
> +      .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE,
> +      .fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el1),
> +      .writefn = vmsa_ttbr_write, .resetfn = arm_cp_reset_ignore },
>      REGINFO_SENTINEL
>  };
>
> @@ -2939,9 +2910,9 @@ static uint32_t get_level1_table_address(CPUARMState *env, uint32_t address)
>      uint32_t table;
>
>      if (address & env->cp15.c2_mask)
> -        table = env->cp15.c2_base1 & 0xffffc000;
> +        table = env->cp15.ttbr1_el1 & 0xffffc000;
>      else
> -        table = env->cp15.c2_base0 & env->cp15.c2_base_mask;
> +        table = env->cp15.ttbr0_el1 & env->cp15.c2_base_mask;
>
>      table |= (address >> 18) & 0x3ffc;
>      return table;
> @@ -3214,11 +3185,11 @@ static int get_phys_addr_lpae(CPUARMState *env, uint32_t address,
>       * we will always flush the TLB any time the ASID is changed).
>       */
>      if (ttbr_select == 0) {
> -        ttbr = ((uint64_t)env->cp15.c2_base0_hi << 32) | env->cp15.c2_base0;
> +        ttbr = env->cp15.ttbr0_el1;
>          epd = extract32(env->cp15.c2_control, 7, 1);
>          tsz = t0sz;
>      } else {
> -        ttbr = ((uint64_t)env->cp15.c2_base1_hi << 32) | env->cp15.c2_base1;
> +        ttbr = env->cp15.ttbr1_el1;
>          epd = extract32(env->cp15.c2_control, 23, 1);
>          tsz = t1sz;
>      }
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 33/35] target-arm: Implement AArch64 ID and feature registers
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 33/35] target-arm: Implement AArch64 ID and feature registers Peter Maydell
@ 2014-02-09  2:42   ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  2:42 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Implement the AArch64-specific ID and feature registers. Although
> many of these are currently not used by the architecture (and so
> always zero for all implementations), we define the full set of
> fields in the ARMCPU struct for symmetry.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  target-arm/cpu-qom.h | 10 ++++++++++
>  target-arm/helper.c  | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 55 insertions(+)
>
> diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
> index afbd422..00234e1 100644
> --- a/target-arm/cpu-qom.h
> +++ b/target-arm/cpu-qom.h
> @@ -132,6 +132,16 @@ typedef struct ARMCPU {
>      uint32_t id_isar3;
>      uint32_t id_isar4;
>      uint32_t id_isar5;
> +    uint64_t id_aa64pfr0;
> +    uint64_t id_aa64pfr1;
> +    uint64_t id_aa64dfr0;
> +    uint64_t id_aa64dfr1;
> +    uint64_t id_aa64afr0;
> +    uint64_t id_aa64afr1;
> +    uint64_t id_aa64isar0;
> +    uint64_t id_aa64isar1;
> +    uint64_t id_aa64mmfr0;
> +    uint64_t id_aa64mmfr1;
>      uint32_t clidr;
>      /* The elements of this array are the CCSIDR values for each cache,
>       * in the order L1DCache, L1ICache, L2DCache, L2ICache, etc.
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index e7d8e7c..eb37e7e 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1882,6 +1882,51 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>          define_arm_cp_regs(cpu, not_v7_cp_reginfo);
>      }
>      if (arm_feature(env, ARM_FEATURE_V8)) {
> +        /* AArch64 ID registers, which all have impdef reset values */
> +        ARMCPRegInfo v8_idregs[] = {
> +            { .name = "ID_AA64PFR0_EL1", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 0,
> +              .access = PL1_R, .type = ARM_CP_CONST,
> +              .resetvalue = cpu->id_aa64pfr0 },
> +            { .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1,
> +              .access = PL1_R, .type = ARM_CP_CONST,
> +              .resetvalue = cpu->id_aa64pfr1},
> +            { .name = "ID_AA64DFR0_EL1", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
> +              .access = PL1_R, .type = ARM_CP_CONST,
> +              .resetvalue = cpu->id_aa64dfr0 },
> +            { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
> +              .access = PL1_R, .type = ARM_CP_CONST,
> +              .resetvalue = cpu->id_aa64dfr1 },
> +            { .name = "ID_AA64AFR0_EL1", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 4,
> +              .access = PL1_R, .type = ARM_CP_CONST,
> +              .resetvalue = cpu->id_aa64afr0 },
> +            { .name = "ID_AA64AFR1_EL1", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 5,
> +              .access = PL1_R, .type = ARM_CP_CONST,
> +              .resetvalue = cpu->id_aa64afr1 },
> +            { .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0,
> +              .access = PL1_R, .type = ARM_CP_CONST,
> +              .resetvalue = cpu->id_aa64isar0 },
> +            { .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1,
> +              .access = PL1_R, .type = ARM_CP_CONST,
> +              .resetvalue = cpu->id_aa64isar1 },
> +            { .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
> +              .access = PL1_R, .type = ARM_CP_CONST,
> +              .resetvalue = cpu->id_aa64mmfr0 },
> +            { .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1,
> +              .access = PL1_R, .type = ARM_CP_CONST,
> +              .resetvalue = cpu->id_aa64mmfr1 },
> +            REGINFO_SENTINEL
> +        };
> +        define_arm_cp_regs(cpu, v8_idregs);
>          define_arm_cp_regs(cpu, v8_cp_reginfo);
>      }
>      if (arm_feature(env, ARM_FEATURE_MPU)) {
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 34/35] target-arm: Implement AArch64 dummy breakpoint and watchpoint registers
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 34/35] target-arm: Implement AArch64 dummy breakpoint and watchpoint registers Peter Maydell
@ 2014-02-09  2:44   ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  2:44 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> In AArch64 the breakpoint and watchpoint registers are mandatory, so the
> kernel always accesses them on bootup. Implement dummy versions, which
> read as written but have no actual effect.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  target-arm/cpu.h    |  4 ++++
>  target-arm/helper.c | 32 ++++++++++++++++++++++++++++++++
>  2 files changed, 36 insertions(+)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 24a8e93..267d5ae 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -216,6 +216,10 @@ typedef struct CPUARMState {
>          uint32_t c15_diagnostic; /* diagnostic register */
>          uint32_t c15_power_diagnostic;
>          uint32_t c15_power_control; /* power control */
> +        uint64_t dbgbvr[16]; /* breakpoint value registers */
> +        uint64_t dbgbcr[16]; /* breakpoint control registers */
> +        uint64_t dbgwvr[16]; /* watchpoint value registers */
> +        uint64_t dbgwcr[16]; /* watchpoint control registers */
>      } cp15;
>
>      struct {
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index eb37e7e..1621030 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1787,6 +1787,37 @@ static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri)
>      return CP_ACCESS_OK;
>  }
>
> +static void define_aarch64_debug_regs(ARMCPU *cpu)
> +{
> +    /* Define breakpoint and watchpoint registers. These do nothing
> +     * but read as written, for now.
> +     */
> +    int i;
> +
> +    for (i = 0; i < 16; i++) {
> +        ARMCPRegInfo dbgregs[] = {
> +            { .name = "DBGBVR", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
> +              .access = PL1_RW,
> +              .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]) },
> +            { .name = "DBGBCR", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
> +              .access = PL1_RW,
> +              .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]) },
> +            { .name = "DBGWVR", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
> +              .access = PL1_RW,
> +              .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]) },
> +            { .name = "DBGWCR", .state = ARM_CP_STATE_AA64,
> +              .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,
> +              .access = PL1_RW,
> +              .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]) },
> +               REGINFO_SENTINEL
> +        };
> +        define_arm_cp_regs(cpu, dbgregs);
> +    }
> +}
> +
>  void register_cp_regs_for_features(ARMCPU *cpu)
>  {
>      /* Register all the coprocessor registers based on feature bits */
> @@ -1928,6 +1959,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>          };
>          define_arm_cp_regs(cpu, v8_idregs);
>          define_arm_cp_regs(cpu, v8_cp_reginfo);
> +        define_aarch64_debug_regs(cpu);
>      }
>      if (arm_feature(env, ARM_FEATURE_MPU)) {
>          /* These are the MPU registers prior to PMSAv6. Any new
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 35/35] target-arm: Implement AArch64 OSLAR_EL1 sysreg as WI
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 35/35] target-arm: Implement AArch64 OSLAR_EL1 sysreg as WI Peter Maydell
@ 2014-02-09  2:44   ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  2:44 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Define a dummy version of the AArch64 OSLAR_EL1 system register
> which just ignores writes. Linux will always write to this (it
> is the OS lock used for debugging), but we don't support debug.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  target-arm/helper.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 1621030..43a4f31 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1764,6 +1764,10 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
>      { .name = "MDSCR_EL1", .state = ARM_CP_STATE_AA64,
>        .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
>        .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
> +    /* We define a dummy WI OSLAR_EL1, because Linux writes to it. */
> +    { .name = "OSLAR_EL1", .state = ARM_CP_STATE_AA64,
> +      .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4,
> +      .access = PL1_W, .type = ARM_CP_NOP },
>      REGINFO_SENTINEL
>  };
>
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 11/35] target-arm: Split cpreg access checks out from read/write functions
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 11/35] target-arm: Split cpreg access checks out from read/write functions Peter Maydell
@ 2014-02-09  2:50   ` Peter Crosthwaite
  2014-02-09 12:02     ` Peter Maydell
  2014-02-11  6:13   ` Peter Crosthwaite
  1 sibling, 1 reply; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  2:50 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Several of the system registers handled via the ARMCPRegInfo
> mechanism have access trap control bits controlling whether the
> registers are accessible to lower privilege levels. Replace
> the existing mechanism (allowing the read and write functions
> to return EXCP_UDEF if access is denied) with a dedicated
> "check access rights" function pointer in the ARMCPRegInfo.
> This will allow us to simplify some of the register definitions,
> which no longer need read/write functions purely to handle
> the access checks.
>
> We take the opportunity to define the return value from the
> access checking function in a way that allows us to set the
> correct exception syndrome information for exceptions taken
> to AArch64 (which may need to distinguish access failures due
> to a configurable trap or enable from other kinds of access
> failure).
>
> This commit defines the new mechanism but does not move any
> of the registers across to use it.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target-arm/cpu.h           | 29 +++++++++++++++++++++++++----
>  target-arm/helper.h        |  1 +
>  target-arm/op_helper.c     | 18 ++++++++++++++++++
>  target-arm/translate-a64.c | 11 +++++++++++
>  target-arm/translate.c     | 11 +++++++++++
>  5 files changed, 66 insertions(+), 4 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index e66d464..30b1a1c 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -812,14 +812,29 @@ static inline int arm_current_pl(CPUARMState *env)
>
>  typedef struct ARMCPRegInfo ARMCPRegInfo;
>
> -/* Access functions for coprocessor registers. These should return
> - * 0 on success, or one of the EXCP_* constants if access should cause
> - * an exception (in which case *value is not written).
> - */
> +typedef enum CPAccessResult {
> +    /* Access is permitted */
> +    CP_ACCESS_OK = 0,
> +    /* Access fails due to a configurable trap or enable which would
> +     * result in a categorized exception syndrome giving information about
> +     * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
> +     * 0xc or 0x18).
> +     */
> +    CP_ACCESS_TRAP = 1,
> +    /* Access fails and results in an exception syndrome 0x0 ("uncategorized").
> +     * Note that this is not a catch-all case -- the set of cases which may
> +     * result in this failure is specifically defined by the architecture.
> +     */
> +    CP_ACCESS_TRAP_UNCATEGORIZED = 2,

Hi Peter,

So its not obvious to me just yet why these two types or traps needs
separate encoding on this level. From your commentary, the two
different types of traps are mutually exclusive and identifyable by
the syndrome information. I.E _TRAP is syndrome != 0 and _TRAP_UNCAT
is syndrome == 0. Cant the access checkers return boolean if is_trap
then the syndrome can be used to make this distinction?

Regards,
Peter

> +} CPAccessResult;
> +
> +/* Access functions for coprocessor registers. These should always succeed. */
>  typedef int CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque,
>                       uint64_t *value);
>  typedef int CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
>                        uint64_t value);
> +/* Access permission check functions for coprocessor registers. */
> +typedef CPAccessResult CPAccessFn(CPUARMState *env, const ARMCPRegInfo *opaque);
>  /* Hook function for register reset */
>  typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
>
> @@ -873,6 +888,12 @@ struct ARMCPRegInfo {
>       *  2. both readfn and writefn are specified
>       */
>      ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
> +    /* 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
> +     * translate time.
> +     */
> +    CPAccessFn *accessfn;
>      /* Function for handling reads of this register. If NULL, then reads
>       * will be done by loading from the offset into CPUARMState specified
>       * by fieldoffset.
> diff --git a/target-arm/helper.h b/target-arm/helper.h
> index 93a27ce..1d83293 100644
> --- a/target-arm/helper.h
> +++ b/target-arm/helper.h
> @@ -57,6 +57,7 @@ DEF_HELPER_1(cpsr_read, i32, env)
>  DEF_HELPER_3(v7m_msr, void, env, i32, i32)
>  DEF_HELPER_2(v7m_mrs, i32, env, i32)
>
> +DEF_HELPER_2(access_check_cp_reg, void, env, ptr)
>  DEF_HELPER_3(set_cp_reg, void, env, ptr, i32)
>  DEF_HELPER_2(get_cp_reg, i32, env, ptr)
>  DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
> diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
> index c812a9f..89b0978 100644
> --- a/target-arm/op_helper.c
> +++ b/target-arm/op_helper.c
> @@ -273,6 +273,24 @@ void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
>      }
>  }
>
> +void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip)
> +{
> +    const ARMCPRegInfo *ri = rip;
> +    switch (ri->accessfn(env, ri)) {
> +    case CP_ACCESS_OK:
> +        return;
> +    case CP_ACCESS_TRAP:
> +    case CP_ACCESS_TRAP_UNCATEGORIZED:
> +        /* These cases will eventually need to generate different
> +         * syndrome information.
> +         */
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
> +    raise_exception(env, EXCP_UDEF);
> +}
> +
>  void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)
>  {
>      const ARMCPRegInfo *ri = rip;
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index a942609..d90ffd1 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -1210,6 +1210,17 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
>          return;
>      }
>
> +    if (ri->accessfn) {
> +        /* Emit code to perform further access permissions checks at
> +         * runtime; this may result in an exception.
> +         */
> +        TCGv_ptr tmpptr;
> +        gen_a64_set_pc_im(s->pc - 4);
> +        tmpptr = tcg_const_ptr(ri);
> +        gen_helper_access_check_cp_reg(cpu_env, tmpptr);
> +        tcg_temp_free_ptr(tmpptr);
> +    }
> +
>      /* Handle special cases first */
>      switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
>      case ARM_CP_NOP:
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index 45886f9..2713081 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -6798,6 +6798,17 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
>              return 1;
>          }
>
> +        if (ri->accessfn) {
> +            /* Emit code to perform further access permissions checks at
> +             * runtime; this may result in an exception.
> +             */
> +            TCGv_ptr tmpptr;
> +            gen_set_pc_im(s, s->pc);
> +            tmpptr = tcg_const_ptr(ri);
> +            gen_helper_access_check_cp_reg(cpu_env, tmpptr);
> +            tcg_temp_free_ptr(tmpptr);
> +        }
> +
>          /* Handle special cases first */
>          switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
>          case ARM_CP_NOP:
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 12/35] target-arm: Convert performance monitor reginfo to accesfn
  2014-02-05 11:01     ` Peter Maydell
  2014-02-06  0:05       ` Alistair Francis
@ 2014-02-09  2:59       ` Peter Crosthwaite
  2014-02-09 12:04         ` Peter Maydell
  1 sibling, 1 reply; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  2:59 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Patch Tracking, Michael Matz,
	qemu-devel@nongnu.org Developers, Alexander Graf,
	Claudio Fontana, Dirk Mueller, Will Newton, Laurent Desnogues,
	Alistair Francis, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

On Wed, Feb 5, 2014 at 9:01 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 5 February 2014 06:59, Peter Crosthwaite
> <peter.crosthwaite@xilinx.com> wrote:
>> cc Alistair, this may conflict with his timer work.
>>
>> On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>> @@ -624,37 +606,41 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
>>>      { .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 1,
>>>        .access = PL0_RW, .resetvalue = 0,
>>>        .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
>>> -      .readfn = pmreg_read, .writefn = pmcntenset_write,
>>> -      .raw_readfn = raw_read, .raw_writefn = raw_write },
>>> +      .writefn = pmcntenset_write,
>>> +      .accessfn = pmreg_access,
>>> +      .raw_writefn = raw_write },
>>
>> A nit but,
>>
>> You're field ordering scheme is inconsistent, here you go, write ->
>> access -> raw_write ....
>>
>>>      { .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2,
>>>        .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
>>> -      .readfn = pmreg_read, .writefn = pmcntenclr_write,
>>> +      .accessfn = pmreg_access,
>>> +      .writefn = pmcntenclr_write,
>>>        .type = ARM_CP_NO_MIGRATE },
>>>      { .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3,
>>>        .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
>>> -      .readfn = pmreg_read, .writefn = pmovsr_write,
>>> -      .raw_readfn = raw_read, .raw_writefn = raw_write },
>>> -    /* Unimplemented so WI. Strictly speaking write accesses in PL0 should
>>> -     * respect PMUSERENR.
>>> -     */
>>> +      .accessfn = pmreg_access,
>>> +      .writefn = pmovsr_write,
>>> +      .raw_writefn = raw_write },
>>
>> ... and this is access -> write -> raw_write. Is there a prescribed
>> order to keep new (or gradually refactored) code consistent?
>
> No, I've just been going for "whatever looks like it fits reasonably
> neatly onto not too many lines and is a fairly minimal change to existing
> structs", mostly.

I agree that we should minimise diff. Existing code trumps any new
rules we come up with here. But I picked on this one because its
inconsistent just within the new changes.

The thing I have been trying to be consistent with is
> the order for crn/crm/opc1/opc2 fields, which for new registers I've been
> making be op0/op1/crn/crm/op2, because that's the order the ARM ARM
> seems to have settled on. Unfortunately a lot of our existing definitions
> are crn/crm/op1/op2, because at the time there was variance in the
> ARM docs and that order seemed sensible to me.
>
> For the other fields, I think "name first; type/state/encoding second;
> access related fields; read and write accessors; reset stuff" is probably
> not a bad order.

Agreed. With diff-correction based on this scheme:

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

 But the nice thing about having named fields is it
> doesn't actually matter what order things go in.
>

But for similar entries its much more readable if they are self-consistent.

Regards,
Peter

> thanks
> -- PMM
>

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

* Re: [Qemu-devel] [PATCH v2 13/35] target-arm: Convert generic timer reginfo to accessfn
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 13/35] target-arm: Convert generic timer reginfo to accessfn Peter Maydell
@ 2014-02-09  3:05   ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  3:05 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Convert the reginfo structs for the generic timer registers
> to use access functions rather than returning EXCP_UDEF from
> their read handlers. In some cases this allows us to remove
> a read handler completely.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  target-arm/helper.c | 122 ++++++++++++++++++++++++++++------------------------
>  1 file changed, 66 insertions(+), 56 deletions(-)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 9adaeb9..edff2e7 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -743,6 +743,59 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
>
>  #ifndef CONFIG_USER_ONLY
>
> +static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri)
> +{
> +    /* CNTFRQ: not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero */
> +    if (arm_current_pl(env) == 0 && !extract32(env->cp15.c14_cntkctl, 0, 2)) {
> +        return CP_ACCESS_TRAP;
> +    }
> +    return CP_ACCESS_OK;
> +}
> +
> +static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx)
> +{
> +    /* CNT[PV]CT: not visible from PL0 if ELO[PV]CTEN is zero */
> +    if (arm_current_pl(env) == 0 &&
> +        !extract32(env->cp15.c14_cntkctl, timeridx, 1)) {
> +        return CP_ACCESS_TRAP;
> +    }
> +    return CP_ACCESS_OK;
> +}
> +
> +static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx)
> +{
> +    /* CNT[PV]_CVAL, CNT[PV]_CTL, CNT[PV]_TVAL: not visible from PL0 if
> +     * EL0[PV]TEN is zero.
> +     */
> +    if (arm_current_pl(env) == 0 &&
> +        !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
> +        return CP_ACCESS_TRAP;
> +    }
> +    return CP_ACCESS_OK;
> +}
> +
> +static CPAccessResult gt_pct_access(CPUARMState *env,
> +                                         const ARMCPRegInfo *ri)
> +{
> +    return gt_counter_access(env, GTIMER_PHYS);
> +}
> +
> +static CPAccessResult gt_vct_access(CPUARMState *env,
> +                                         const ARMCPRegInfo *ri)
> +{
> +    return gt_counter_access(env, GTIMER_VIRT);
> +}
> +
> +static CPAccessResult gt_ptimer_access(CPUARMState *env, const ARMCPRegInfo *ri)
> +{
> +    return gt_timer_access(env, GTIMER_PHYS);
> +}
> +
> +static CPAccessResult gt_vtimer_access(CPUARMState *env, const ARMCPRegInfo *ri)
> +{
> +    return gt_timer_access(env, GTIMER_VIRT);
> +}
> +
>  static uint64_t gt_get_countervalue(CPUARMState *env)
>  {
>      return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / GTIMER_SCALE;
> @@ -788,17 +841,6 @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
>      }
>  }
>
> -static int gt_cntfrq_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                          uint64_t *value)
> -{
> -    /* Not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero */
> -    if (arm_current_pl(env) == 0 && !extract32(env->cp15.c14_cntkctl, 0, 2)) {
> -        return EXCP_UDEF;
> -    }
> -    *value = env->cp15.c14_cntfrq;
> -    return 0;
> -}
> -
>  static void gt_cnt_reset(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
>      ARMCPU *cpu = arm_env_get_cpu(env);
> @@ -810,29 +852,10 @@ static void gt_cnt_reset(CPUARMState *env, const ARMCPRegInfo *ri)
>  static int gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri,
>                         uint64_t *value)
>  {
> -    int timeridx = ri->opc1 & 1;
> -
> -    if (arm_current_pl(env) == 0 &&
> -        !extract32(env->cp15.c14_cntkctl, timeridx, 1)) {
> -        return EXCP_UDEF;
> -    }
>      *value = gt_get_countervalue(env);
>      return 0;
>  }
>
> -static int gt_cval_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                        uint64_t *value)
> -{
> -    int timeridx = ri->opc1 & 1;
> -
> -    if (arm_current_pl(env) == 0 &&
> -        !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
> -        return EXCP_UDEF;
> -    }
> -    *value = env->cp15.c14_timer[timeridx].cval;
> -    return 0;
> -}
> -
>  static int gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
>                           uint64_t value)
>  {
> @@ -847,10 +870,6 @@ static int gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
>  {
>      int timeridx = ri->crm & 1;
>
> -    if (arm_current_pl(env) == 0 &&
> -        !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
> -        return EXCP_UDEF;
> -    }
>      *value = (uint32_t)(env->cp15.c14_timer[timeridx].cval -
>                          gt_get_countervalue(env));
>      return 0;
> @@ -867,19 +886,6 @@ static int gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
>      return 0;
>  }
>
> -static int gt_ctl_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                       uint64_t *value)
> -{
> -    int timeridx = ri->crm & 1;
> -
> -    if (arm_current_pl(env) == 0 &&
> -        !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
> -        return EXCP_UDEF;
> -    }
> -    *value = env->cp15.c14_timer[timeridx].ctl;
> -    return 0;
> -}
> -
>  static int gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
>                          uint64_t value)
>  {
> @@ -924,7 +930,7 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
>        .access = PL1_RW | PL0_R,
>        .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
>        .resetvalue = (1000 * 1000 * 1000) / GTIMER_SCALE,
> -      .readfn = gt_cntfrq_read, .raw_readfn = raw_read,
> +      .accessfn = gt_cntfrq_access,
>      },
>      /* overall control: mostly access permissions */
>      { .name = "CNTKCTL", .cp = 15, .crn = 14, .crm = 1, .opc1 = 0, .opc2 = 0,
> @@ -937,32 +943,36 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
>        .type = ARM_CP_IO, .access = PL1_RW | PL0_R,
>        .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
>        .resetvalue = 0,
> -      .readfn = gt_ctl_read, .writefn = gt_ctl_write,
> -      .raw_readfn = raw_read, .raw_writefn = raw_write,
> +      .accessfn = gt_ptimer_access,
> +      .writefn = gt_ctl_write, .raw_writefn = raw_write,
>      },
>      { .name = "CNTV_CTL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 1,
>        .type = ARM_CP_IO, .access = PL1_RW | PL0_R,
>        .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
>        .resetvalue = 0,
> -      .readfn = gt_ctl_read, .writefn = gt_ctl_write,
> -      .raw_readfn = raw_read, .raw_writefn = raw_write,
> +      .accessfn = gt_vtimer_access,
> +      .writefn = gt_ctl_write, .raw_writefn = raw_write,
>      },
>      /* TimerValue views: a 32 bit downcounting view of the underlying state */
>      { .name = "CNTP_TVAL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 0,
>        .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R,
> +      .accessfn = gt_ptimer_access,
>        .readfn = gt_tval_read, .writefn = gt_tval_write,
>      },
>      { .name = "CNTV_TVAL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 0,
>        .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R,
> +      .accessfn = gt_vtimer_access,
>        .readfn = gt_tval_read, .writefn = gt_tval_write,
>      },
>      /* The counter itself */
>      { .name = "CNTPCT", .cp = 15, .crm = 14, .opc1 = 0,
>        .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE | ARM_CP_IO,
> +      .accessfn = gt_pct_access,
>        .readfn = gt_cnt_read, .resetfn = gt_cnt_reset,
>      },
>      { .name = "CNTVCT", .cp = 15, .crm = 14, .opc1 = 1,
>        .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE | ARM_CP_IO,
> +      .accessfn = gt_vct_access,
>        .readfn = gt_cnt_read, .resetfn = gt_cnt_reset,
>      },
>      /* Comparison value, indicating when the timer goes off */
> @@ -971,16 +981,16 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
>        .type = ARM_CP_64BIT | ARM_CP_IO,
>        .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
>        .resetvalue = 0,
> -      .readfn = gt_cval_read, .writefn = gt_cval_write,
> -      .raw_readfn = raw_read, .raw_writefn = raw_write,
> +      .accessfn = gt_ptimer_access,
> +      .writefn = gt_cval_write, .raw_writefn = raw_write,
>      },
>      { .name = "CNTV_CVAL", .cp = 15, .crm = 14, .opc1 = 3,
>        .access = PL1_RW | PL0_R,
>        .type = ARM_CP_64BIT | ARM_CP_IO,
>        .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
>        .resetvalue = 0,
> -      .readfn = gt_cval_read, .writefn = gt_cval_write,
> -      .raw_readfn = raw_read, .raw_writefn = raw_write,
> +      .accessfn = gt_vtimer_access,
> +      .writefn = gt_cval_write, .raw_writefn = raw_write,
>      },
>      REGINFO_SENTINEL
>  };
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 14/35] target-arm: Convert miscellaneous reginfo structs to accessfn
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 14/35] target-arm: Convert miscellaneous reginfo structs " Peter Maydell
@ 2014-02-09  3:09   ` Peter Crosthwaite
  2014-02-09 12:09     ` Peter Maydell
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  3:09 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Convert the remaining miscellaneous cases of reginfo read/write
> functions returning EXCP_UDEF to use an accessfn instead:
> TEEHBR, and the ATS address-translation operations.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target-arm/helper.c | 44 +++++++++++++++++++-------------------------
>  1 file changed, 19 insertions(+), 25 deletions(-)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index edff2e7..664ac92 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -682,27 +682,12 @@ static int teecr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
>      return 0;
>  }
>
> -static int teehbr_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                       uint64_t *value)
> +static CPAccessResultg teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
> -    /* This is a helper function because the user access rights
> -     * depend on the value of the TEECR.
> -     */
>      if (arm_current_pl(env) == 0 && (env->teecr & 1)) {
> -        return EXCP_UDEF;
> -    }
> -    *value = env->teehbr;
> -    return 0;
> -}
> -
> -static int teehbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                        uint64_t value)
> -{
> -    if (arm_current_pl(env) == 0 && (env->teecr & 1)) {
> -        return EXCP_UDEF;
> +        return CP_ACCESS_TRAP;
>      }
> -    env->teehbr = value;
> -    return 0;
> +    return CP_ACCESS_OK;
>  }
>
>  static const ARMCPRegInfo t2ee_cp_reginfo[] = {
> @@ -712,8 +697,7 @@ static const ARMCPRegInfo t2ee_cp_reginfo[] = {
>        .writefn = teecr_write },
>      { .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
>        .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr),
> -      .resetvalue = 0, .raw_readfn = raw_read, .raw_writefn = raw_write,
> -      .readfn = teehbr_read, .writefn = teehbr_write },
> +      .accessfn = teehbr_access, .resetvalue = 0 },
>      REGINFO_SENTINEL
>  };
>
> @@ -1031,6 +1015,19 @@ static inline bool extended_addresses_enabled(CPUARMState *env)
>          && (env->cp15.c2_control & (1U << 31));
>  }
>
> +static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri)
> +{
> +    if (ri->opc2 & 4) {
> +        /* Other states are only available with TrustZone; in

A nit, but following earlier discussions there in no mention of
"TrustZone" in ARM ARM. Should this be "security extensions"?

Regards,
Peter

> +         * a non-TZ implementation these registers don't exist
> +         * at all, which is an Uncategorized trap. This underdecoding
> +         * is safe because the reginfo is NO_MIGRATE.
> +         */
> +        return CP_ACCESS_TRAP_UNCATEGORIZED;
> +    }
> +    return CP_ACCESS_OK;
> +}
> +
>  static int ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
>  {
>      hwaddr phys_addr;
> @@ -1039,10 +1036,6 @@ static int ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
>      int ret, is_user = ri->opc2 & 2;
>      int access_type = ri->opc2 & 1;
>
> -    if (ri->opc2 & 4) {
> -        /* Other states are only available with TrustZone */
> -        return EXCP_UDEF;
> -    }
>      ret = get_phys_addr(env, value, access_type, is_user,
>                          &phys_addr, &prot, &page_size);
>      if (extended_addresses_enabled(env)) {
> @@ -1095,7 +1088,8 @@ static const ARMCPRegInfo vapa_cp_reginfo[] = {
>        .writefn = par_write },
>  #ifndef CONFIG_USER_ONLY
>      { .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY,
> -      .access = PL1_W, .writefn = ats_write, .type = ARM_CP_NO_MIGRATE },
> +      .access = PL1_W, .accessfn = ats_access,
> +      .writefn = ats_write, .type = ARM_CP_NO_MIGRATE },
>  #endif
>      REGINFO_SENTINEL
>  };
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 15/35] target-arm: Drop success/fail return from cpreg read and write functions
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 15/35] target-arm: Drop success/fail return from cpreg read and write functions Peter Maydell
@ 2014-02-09  3:27   ` Peter Crosthwaite
  2014-02-09 12:15     ` Peter Maydell
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  3:27 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> All cpreg read and write functions now return 0, so we can clean up
> their prototypes:
>  * write functions return void
>  * read functions return the value rather than taking a pointer
>    to write the value to
>
> This is a fairly mechanical change which makes only the bare
> minimum set of changes to the callers of read and write functions.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/arm/pxa2xx.c        |  36 +++----
>  hw/arm/pxa2xx_pic.c    |  11 +-
>  target-arm/cpu.c       |   6 +-
>  target-arm/cpu.h       |  23 ++--
>  target-arm/helper.c    | 288 ++++++++++++++++++++-----------------------------
>  target-arm/op_helper.c |  24 +----
>  6 files changed, 150 insertions(+), 238 deletions(-)
>
> diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
> index 02b7016..bf9416a 100644
> --- a/hw/arm/pxa2xx.c
> +++ b/hw/arm/pxa2xx.c
> @@ -224,27 +224,24 @@ static const VMStateDescription vmstate_pxa2xx_cm = {
>      }
>  };
>
> -static int pxa2xx_clkcfg_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                              uint64_t *value)
> +static uint64_t pxa2xx_clkcfg_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
>      PXA2xxState *s = (PXA2xxState *)ri->opaque;
> -    *value = s->clkcfg;
> -    return 0;
> +    return s->clkcfg;
>  }
>
> -static int pxa2xx_clkcfg_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                               uint64_t value)
> +static void pxa2xx_clkcfg_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                                uint64_t value)
>  {
>      PXA2xxState *s = (PXA2xxState *)ri->opaque;
>      s->clkcfg = value & 0xf;
>      if (value & 2) {
>          printf("%s: CPU frequency change attempt\n", __func__);
>      }
> -    return 0;
>  }
>
> -static int pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                                uint64_t value)
> +static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                                 uint64_t value)
>  {
>      PXA2xxState *s = (PXA2xxState *)ri->opaque;
>      static const char *pwrmode[8] = {
> @@ -310,36 +307,29 @@ static int pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
>          printf("%s: machine entered %s mode\n", __func__,
>                 pwrmode[value & 7]);
>      }
> -
> -    return 0;
>  }
>
> -static int pxa2xx_cppmnc_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                              uint64_t *value)
> +static uint64_t pxa2xx_cppmnc_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
>      PXA2xxState *s = (PXA2xxState *)ri->opaque;
> -    *value = s->pmnc;
> -    return 0;
> +    return s->pmnc;
>  }
>
> -static int pxa2xx_cppmnc_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                               uint64_t value)
> +static void pxa2xx_cppmnc_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                                uint64_t value)
>  {
>      PXA2xxState *s = (PXA2xxState *)ri->opaque;
>      s->pmnc = value;
> -    return 0;
>  }
>
> -static int pxa2xx_cpccnt_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                              uint64_t *value)
> +static uint64_t pxa2xx_cpccnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
>      PXA2xxState *s = (PXA2xxState *)ri->opaque;
>      if (s->pmnc & 1) {
> -        *value = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> +        return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>      } else {
> -        *value = 0;
> +        return 0;
>      }
> -    return 0;
>  }
>
>  static const ARMCPRegInfo pxa_cp_reginfo[] = {
> diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
> index 46d337c..345fa4a 100644
> --- a/hw/arm/pxa2xx_pic.c
> +++ b/hw/arm/pxa2xx_pic.c
> @@ -217,20 +217,17 @@ static const int pxa2xx_cp_reg_map[0x10] = {
>      [0xa] = ICPR2,
>  };
>
> -static int pxa2xx_pic_cp_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                              uint64_t *value)
> +static uint64_t pxa2xx_pic_cp_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
>      int offset = pxa2xx_cp_reg_map[ri->crn];
> -    *value = pxa2xx_pic_mem_read(ri->opaque, offset, 4);
> -    return 0;
> +    return pxa2xx_pic_mem_read(ri->opaque, offset, 4);
>  }
>
> -static int pxa2xx_pic_cp_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                               uint64_t value)
> +static void pxa2xx_pic_cp_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                                uint64_t value)
>  {
>      int offset = pxa2xx_cp_reg_map[ri->crn];
>      pxa2xx_pic_mem_write(ri->opaque, offset, value, 4);
> -    return 0;
>  }
>
>  #define REGINFO_FOR_PIC_CP(NAME, CRN) \
> diff --git a/target-arm/cpu.c b/target-arm/cpu.c
> index 3014e86..fe18b65 100644
> --- a/target-arm/cpu.c
> +++ b/target-arm/cpu.c
> @@ -681,14 +681,12 @@ static void cortex_a9_initfn(Object *obj)
>  }
>
>  #ifndef CONFIG_USER_ONLY
> -static int a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                           uint64_t *value)
> +static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
>      /* Linux wants the number of processors from here.
>       * Might as well set the interrupt-controller bit too.
>       */
> -    *value = ((smp_cpus - 1) << 24) | (1 << 23);
> -    return 0;
> +    return ((smp_cpus - 1) << 24) | (1 << 23);
>  }
>  #endif
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 30b1a1c..d1ed423 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -828,11 +828,12 @@ typedef enum CPAccessResult {
>      CP_ACCESS_TRAP_UNCATEGORIZED = 2,
>  } CPAccessResult;
>
> -/* Access functions for coprocessor registers. These should always succeed. */
> -typedef int CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque,
> -                     uint64_t *value);
> -typedef int CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
> -                      uint64_t value);
> +/* Access functions for coprocessor registers. These cannot fail and
> + * may not raise exceptions.

Is this based on an assumption that the only possible reason for an
exception is access violation? This series quite validly obsoletes the
need for exception-via-return-path, but my understanding is that CP
accessor functions are able to implement any form of side affects. If
an exception is thus generated from the side effects of a CP access
then thats fair game - it just happens via the already existing
mechanisms for generating an exception from helper context. Long story
short, I think you can just drop second sentence from this comment.

> + */
> +typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque);
> +typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
> +                       uint64_t value);
>  /* Access permission check functions for coprocessor registers. */
>  typedef CPAccessResult CPAccessFn(CPUARMState *env, const ARMCPRegInfo *opaque);
>  /* Hook function for register reset */
> @@ -907,14 +908,14 @@ struct ARMCPRegInfo {
>      /* Function for doing a "raw" read; used when we need to copy
>       * coprocessor state to the kernel for KVM or out for
>       * migration. This only needs to be provided if there is also a
> -     * readfn and it makes an access permission check.
> +     * readfn and it has side effects (for instance clear-on-read bits).
>       */
>      CPReadFn *raw_readfn;
>      /* Function for doing a "raw" write; used when we need to copy KVM
>       * kernel coprocessor state into userspace, or for inbound
>       * migration. This only needs to be provided if there is also a
> -     * writefn and it makes an access permission check or masks out
> -     * "unwritable" bits or has write-one-to-clear or similar behaviour.
> +     * writefn and it masks out "unwritable" bits or has write-one-to-clear
> +     * or similar behaviour.
>       */
>      CPWriteFn *raw_writefn;
>      /* Function for resetting the register. If NULL, then reset will be done
> @@ -949,10 +950,10 @@ static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
>  const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp);
>
>  /* CPWriteFn that can be used to implement writes-ignored behaviour */
> -int arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
> -                        uint64_t value);
> +void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
> +                         uint64_t value);
>  /* CPReadFn that can be used for read-as-zero behaviour */
> -int arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t *value);
> +uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri);
>
>  /* CPResetFn that does nothing, for use if no reset is required even
>   * if fieldoffset is non zero.
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 664ac92..10aeccc 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -107,26 +107,23 @@ static int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
>      }
>  }
>
> -static int raw_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                    uint64_t *value)
> +static uint64_t raw_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
>      if (cpreg_field_is_64bit(ri)) {
> -        *value = CPREG_FIELD64(env, ri);
> +        return CPREG_FIELD64(env, ri);
>      } else {
> -        *value = CPREG_FIELD32(env, ri);
> +        return CPREG_FIELD32(env, ri);
>      }
> -    return 0;
>  }
>
> -static int raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                     uint64_t value)
> +static void raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                      uint64_t value)
>  {
>      if (cpreg_field_is_64bit(ri)) {
>          CPREG_FIELD64(env, ri) = value;
>      } else {
>          CPREG_FIELD32(env, ri) = value;
>      }
> -    return 0;
>  }
>
>  static bool read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
> @@ -138,11 +135,11 @@ static bool read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
>      if (ri->type & ARM_CP_CONST) {
>          *v = ri->resetvalue;
>      } else if (ri->raw_readfn) {
> -        return (ri->raw_readfn(env, ri, v) == 0);
> +        *v = ri->raw_readfn(env, ri);
>      } else if (ri->readfn) {
> -        return (ri->readfn(env, ri, v) == 0);
> +        *v = ri->readfn(env, ri);
>      } else {
> -        raw_read(env, ri, v);
> +        *v = raw_read(env, ri);
>      }
>      return true;
>  }
> @@ -159,9 +156,9 @@ static bool write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
>      if (ri->type & ARM_CP_CONST) {
>          return true;
>      } else if (ri->raw_writefn) {
> -        return (ri->raw_writefn(env, ri, v) == 0);
> +        ri->raw_writefn(env, ri, v);
>      } else if (ri->writefn) {
> -        return (ri->writefn(env, ri, v) == 0);
> +        ri->writefn(env, ri, v);
>      } else {
>          raw_write(env, ri, v);
>      }
> @@ -309,14 +306,13 @@ void init_cpreg_list(ARMCPU *cpu)
>      g_list_free(keys);
>  }
>
> -static int dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
> +static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
>  {
>      env->cp15.c3 = value;
>      tlb_flush(env, 1); /* Flush TLB as domain not tracked in TLB */
> -    return 0;
>  }
>
> -static int fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
> +static void fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
>  {
>      if (env->cp15.c13_fcse != value) {
>          /* Unlike real hardware the qemu TLB uses virtual addresses,
> @@ -325,10 +321,10 @@ static int fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
>          tlb_flush(env, 1);
>          env->cp15.c13_fcse = value;
>      }
> -    return 0;
>  }
> -static int contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                            uint64_t value)
> +
> +static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                             uint64_t value)
>  {
>      if (env->cp15.c13_context != value && !arm_feature(env, ARM_FEATURE_MPU)) {
>          /* For VMSA (when not using the LPAE long descriptor page table
> @@ -338,39 +334,34 @@ static int contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
>          tlb_flush(env, 1);
>      }
>      env->cp15.c13_context = value;
> -    return 0;
>  }
>
> -static int tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                         uint64_t value)
> +static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                          uint64_t value)
>  {
>      /* Invalidate all (TLBIALL) */
>      tlb_flush(env, 1);
> -    return 0;
>  }
>
> -static int tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                         uint64_t value)
> +static void tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                          uint64_t value)
>  {
>      /* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */
>      tlb_flush_page(env, value & TARGET_PAGE_MASK);
> -    return 0;
>  }
>
> -static int tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                          uint64_t value)
> +static void tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                           uint64_t value)
>  {
>      /* Invalidate by ASID (TLBIASID) */
>      tlb_flush(env, value == 0);
> -    return 0;
>  }
>
> -static int tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                          uint64_t value)
> +static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                           uint64_t value)
>  {
>      /* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */
>      tlb_flush_page(env, value & TARGET_PAGE_MASK);
> -    return 0;
>  }
>
>  static const ARMCPRegInfo cp_reginfo[] = {
> @@ -450,14 +441,14 @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = {
>      REGINFO_SENTINEL
>  };
>
> -static int cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
> +static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                        uint64_t value)
>  {
>      if (env->cp15.c1_coproc != value) {
>          env->cp15.c1_coproc = value;
>          /* ??? Is this safe when called from within a TB?  */
>          tb_flush(env);
>      }
> -    return 0;
>  }
>
>  static const ARMCPRegInfo v6_cp_reginfo[] = {
> @@ -496,89 +487,77 @@ static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri)
>      return CP_ACCESS_OK;
>  }
>
> -static int pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                      uint64_t value)
> +static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                       uint64_t value)
>  {
>      /* only the DP, X, D and E bits are writable */
>      env->cp15.c9_pmcr &= ~0x39;
>      env->cp15.c9_pmcr |= (value & 0x39);
> -    return 0;
>  }
>
> -static int pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
>                              uint64_t value)
>  {
>      value &= (1 << 31);
>      env->cp15.c9_pmcnten |= value;
> -    return 0;
>  }
>
> -static int pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                            uint64_t value)
> +static void pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                             uint64_t value)
>  {
>      value &= (1 << 31);
>      env->cp15.c9_pmcnten &= ~value;
> -    return 0;
>  }
>
> -static int pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                        uint64_t value)
> +static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                         uint64_t value)
>  {
>      env->cp15.c9_pmovsr &= ~value;
> -    return 0;
>  }
>
> -static int pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                            uint64_t value)
> +static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                             uint64_t value)
>  {
>      env->cp15.c9_pmxevtyper = value & 0xff;
> -    return 0;
>  }
>
> -static int pmuserenr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +static void pmuserenr_write(CPUARMState *env, const ARMCPRegInfo *ri,
>                              uint64_t value)
>  {
>      env->cp15.c9_pmuserenr = value & 1;
> -    return 0;
>  }
>
> -static int pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                            uint64_t value)
> +static void pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                             uint64_t value)
>  {
>      /* We have no event counters so only the C bit can be changed */
>      value &= (1 << 31);
>      env->cp15.c9_pminten |= value;
> -    return 0;
>  }
>
> -static int pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                            uint64_t value)
> +static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                             uint64_t value)
>  {
>      value &= (1 << 31);
>      env->cp15.c9_pminten &= ~value;
> -    return 0;
>  }
>
> -static int vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                      uint64_t value)
> +static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                       uint64_t value)
>  {
>      env->cp15.c12_vbar = value & ~0x1Ful;
> -    return 0;
>  }
>
> -static int ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                       uint64_t *value)
> +static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
>      ARMCPU *cpu = arm_env_get_cpu(env);
> -    *value = cpu->ccsidr[env->cp15.c0_cssel];
> -    return 0;
> +    return cpu->ccsidr[env->cp15.c0_cssel];
>  }
>
> -static int csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                        uint64_t value)
> +static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                         uint64_t value)
>  {
>      env->cp15.c0_cssel = value & 0xf;
> -    return 0;
>  }
>
>  static const ARMCPRegInfo v7_cp_reginfo[] = {
> @@ -675,14 +654,14 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
>      REGINFO_SENTINEL
>  };
>
> -static int teecr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
> +static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                        uint64_t value)
>  {
>      value &= 1;
>      env->teecr = value;
> -    return 0;
>  }
>
> -static CPAccessResultg teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri)
> +static CPAccessResult teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
>      if (arm_current_pl(env) == 0 && (env->teecr & 1)) {
>          return CP_ACCESS_TRAP;
> @@ -833,45 +812,40 @@ static void gt_cnt_reset(CPUARMState *env, const ARMCPRegInfo *ri)
>      timer_del(cpu->gt_timer[timeridx]);
>  }
>
> -static int gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                       uint64_t *value)
> +static uint64_t gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
> -    *value = gt_get_countervalue(env);
> -    return 0;
> +    return gt_get_countervalue(env);
>  }
>
> -static int gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                         uint64_t value)
> +static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                          uint64_t value)
>  {
>      int timeridx = ri->opc1 & 1;
>
>      env->cp15.c14_timer[timeridx].cval = value;
>      gt_recalc_timer(arm_env_get_cpu(env), timeridx);
> -    return 0;
>  }
> -static int gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                        uint64_t *value)
> +
> +static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
>      int timeridx = ri->crm & 1;
>
> -    *value = (uint32_t)(env->cp15.c14_timer[timeridx].cval -
> -                        gt_get_countervalue(env));
> -    return 0;
> +    return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
> +                      gt_get_countervalue(env));
>  }
>
> -static int gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                         uint64_t value)
> +static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                          uint64_t value)
>  {
>      int timeridx = ri->crm & 1;
>
>      env->cp15.c14_timer[timeridx].cval = gt_get_countervalue(env) +
>          + sextract64(value, 0, 32);
>      gt_recalc_timer(arm_env_get_cpu(env), timeridx);
> -    return 0;
>  }
>
> -static int gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                        uint64_t value)
> +static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                         uint64_t value)
>  {
>      ARMCPU *cpu = arm_env_get_cpu(env);
>      int timeridx = ri->crm & 1;
> @@ -888,7 +862,6 @@ static int gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
>          qemu_set_irq(cpu->gt_timer_outputs[timeridx],
>                       (oldval & 4) && (value & 2));
>      }
> -    return 0;
>  }
>
>  void arm_gt_ptimer_cb(void *opaque)
> @@ -990,7 +963,7 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
>
>  #endif
>
> -static int par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
> +static void par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
>  {
>      if (arm_feature(env, ARM_FEATURE_LPAE)) {
>          env->cp15.c7_par = value;
> @@ -999,7 +972,6 @@ static int par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
>      } else {
>          env->cp15.c7_par = value & 0xfffff1ff;
>      }
> -    return 0;
>  }
>
>  #ifndef CONFIG_USER_ONLY
> @@ -1028,7 +1000,7 @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri)
>      return CP_ACCESS_OK;
>  }
>
> -static int ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
> +static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
>  {
>      hwaddr phys_addr;
>      target_ulong page_size;
> @@ -1077,7 +1049,6 @@ static int ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
>          }
>          env->cp15.c7_par_hi = 0;
>      }
> -    return 0;
>  }
>  #endif
>
> @@ -1124,32 +1095,26 @@ static uint32_t extended_mpu_ap_bits(uint32_t val)
>      return ret;
>  }
>
> -static int pmsav5_data_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                                uint64_t value)
> +static void pmsav5_data_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                                 uint64_t value)
>  {
>      env->cp15.c5_data = extended_mpu_ap_bits(value);
> -    return 0;
>  }
>
> -static int pmsav5_data_ap_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                               uint64_t *value)
> +static uint64_t pmsav5_data_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
> -    *value = simple_mpu_ap_bits(env->cp15.c5_data);
> -    return 0;
> +    return simple_mpu_ap_bits(env->cp15.c5_data);
>  }
>
> -static int pmsav5_insn_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                                uint64_t value)
> +static void pmsav5_insn_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                                 uint64_t value)
>  {
>      env->cp15.c5_insn = extended_mpu_ap_bits(value);
> -    return 0;
>  }
>
> -static int pmsav5_insn_ap_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                               uint64_t *value)
> +static uint64_t pmsav5_insn_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
> -    *value = simple_mpu_ap_bits(env->cp15.c5_insn);
> -    return 0;
> +    return simple_mpu_ap_bits(env->cp15.c5_insn);
>  }
>
>  static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
> @@ -1201,8 +1166,8 @@ static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
>      REGINFO_SENTINEL
>  };
>
> -static int vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                                uint64_t value)
> +static void vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                                 uint64_t value)
>  {
>      int maskshift = extract32(value, 0, 3);
>
> @@ -1219,11 +1184,10 @@ static int vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
>      env->cp15.c2_control = value;
>      env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> maskshift);
>      env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> maskshift);
> -    return 0;
>  }
>
> -static int vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                            uint64_t value)
> +static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                             uint64_t value)
>  {
>      if (arm_feature(env, ARM_FEATURE_LPAE)) {
>          /* With LPAE the TTBCR could result in a change of ASID
> @@ -1231,7 +1195,7 @@ static int vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
>           */
>          tlb_flush(env, 1);
>      }
> -    return vmsa_ttbcr_raw_write(env, ri, value);
> +    vmsa_ttbcr_raw_write(env, ri, value);
>  }
>
>  static void vmsa_ttbcr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
> @@ -1264,40 +1228,36 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
>      REGINFO_SENTINEL
>  };
>
> -static int omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                               uint64_t value)
> +static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                                uint64_t value)
>  {
>      env->cp15.c15_ticonfig = value & 0xe7;
>      /* The OS_TYPE bit in this register changes the reported CPUID! */
>      env->cp15.c0_cpuid = (value & (1 << 5)) ?
>          ARM_CPUID_TI915T : ARM_CPUID_TI925T;
> -    return 0;
>  }
>
> -static int omap_threadid_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                               uint64_t value)
> +static void omap_threadid_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                                uint64_t value)
>  {
>      env->cp15.c15_threadid = value & 0xffff;
> -    return 0;
>  }
>
> -static int omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                          uint64_t value)
> +static void omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                           uint64_t value)
>  {
>      /* Wait-for-interrupt (deprecated) */
>      cpu_interrupt(CPU(arm_env_get_cpu(env)), CPU_INTERRUPT_HALT);
> -    return 0;
>  }
>
> -static int omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                                 uint64_t value)
> +static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                                  uint64_t value)
>  {
>      /* On OMAP there are registers indicating the max/min index of dcache lines
>       * containing a dirty line; cache flush operations have to reset these.
>       */
>      env->cp15.c15_i_max = 0x000;
>      env->cp15.c15_i_min = 0xff0;
> -    return 0;
>  }
>
>  static const ARMCPRegInfo omap_cp_reginfo[] = {
> @@ -1339,8 +1299,8 @@ static const ARMCPRegInfo omap_cp_reginfo[] = {
>      REGINFO_SENTINEL
>  };
>
> -static int xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                             uint64_t value)
> +static void xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                              uint64_t value)
>  {
>      value &= 0x3fff;
>      if (env->cp15.c15_cpar != value) {
> @@ -1348,7 +1308,6 @@ static int xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri,
>          tb_flush(env);
>          env->cp15.c15_cpar = value;
>      }
> -    return 0;
>  }
>
>  static const ARMCPRegInfo xscale_cp_reginfo[] = {
> @@ -1428,8 +1387,7 @@ static const ARMCPRegInfo strongarm_cp_reginfo[] = {
>      REGINFO_SENTINEL
>  };
>
> -static int mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                      uint64_t *value)
> +static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
>      CPUState *cs = CPU(arm_env_get_cpu(env));
>      uint32_t mpidr = cs->cpu_index;
> @@ -1444,8 +1402,7 @@ static int mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri,
>           * not currently model any of those cores.
>           */
>      }
> -    *value = mpidr;
> -    return 0;
> +    return mpidr;
>  }
>
>  static const ARMCPRegInfo mpidr_cp_reginfo[] = {
> @@ -1454,17 +1411,16 @@ static const ARMCPRegInfo mpidr_cp_reginfo[] = {
>      REGINFO_SENTINEL
>  };
>
> -static int par64_read(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t *value)
> +static uint64_t par64_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
> -    *value = ((uint64_t)env->cp15.c7_par_hi << 32) | env->cp15.c7_par;
> -    return 0;
> +    return ((uint64_t)env->cp15.c7_par_hi << 32) | env->cp15.c7_par;
>  }
>
> -static int par64_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
> +static void par64_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                        uint64_t value)
>  {
>      env->cp15.c7_par_hi = value >> 32;
>      env->cp15.c7_par = value;
> -    return 0;
>  }
>
>  static void par64_reset(CPUARMState *env, const ARMCPRegInfo *ri)
> @@ -1473,27 +1429,24 @@ static void par64_reset(CPUARMState *env, const ARMCPRegInfo *ri)
>      env->cp15.c7_par = 0;
>  }
>
> -static int ttbr064_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                        uint64_t *value)
> +static uint64_t ttbr064_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
> -    *value = ((uint64_t)env->cp15.c2_base0_hi << 32) | env->cp15.c2_base0;
> -    return 0;
> +    return ((uint64_t)env->cp15.c2_base0_hi << 32) | env->cp15.c2_base0;
>  }
>
> -static int ttbr064_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                             uint64_t value)
> +static void ttbr064_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                              uint64_t value)
>  {
>      env->cp15.c2_base0_hi = value >> 32;
>      env->cp15.c2_base0 = value;
> -    return 0;
>  }
>
> -static int ttbr064_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                         uint64_t value)
> +static void ttbr064_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                          uint64_t value)
>  {
>      /* Writes to the 64 bit format TTBRs may change the ASID */
>      tlb_flush(env, 1);
> -    return ttbr064_raw_write(env, ri, value);
> +    ttbr064_raw_write(env, ri, value);
>  }
>
>  static void ttbr064_reset(CPUARMState *env, const ARMCPRegInfo *ri)
> @@ -1502,19 +1455,16 @@ static void ttbr064_reset(CPUARMState *env, const ARMCPRegInfo *ri)
>      env->cp15.c2_base0 = 0;
>  }
>
> -static int ttbr164_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                        uint64_t *value)
> +static uint64_t ttbr164_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
> -    *value = ((uint64_t)env->cp15.c2_base1_hi << 32) | env->cp15.c2_base1;
> -    return 0;
> +    return ((uint64_t)env->cp15.c2_base1_hi << 32) | env->cp15.c2_base1;
>  }
>
> -static int ttbr164_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                         uint64_t value)
> +static void ttbr164_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                          uint64_t value)
>  {
>      env->cp15.c2_base1_hi = value >> 32;
>      env->cp15.c2_base1 = value;
> -    return 0;
>  }
>
>  static void ttbr164_reset(CPUARMState *env, const ARMCPRegInfo *ri)
> @@ -1551,32 +1501,26 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
>      REGINFO_SENTINEL
>  };
>
> -static int aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                          uint64_t *value)
> +static uint64_t aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
> -    *value = vfp_get_fpcr(env);
> -    return 0;
> +    return vfp_get_fpcr(env);
>  }
>
> -static int aa64_fpcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                           uint64_t value)
> +static void aa64_fpcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                            uint64_t value)
>  {
>      vfp_set_fpcr(env, value);
> -    return 0;
>  }
>
> -static int aa64_fpsr_read(CPUARMState *env, const ARMCPRegInfo *ri,
> -                          uint64_t *value)
> +static uint64_t aa64_fpsr_read(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
> -    *value = vfp_get_fpsr(env);
> -    return 0;
> +    return vfp_get_fpsr(env);
>  }
>
> -static int aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> -                           uint64_t value)
> +static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                            uint64_t value)
>  {
>      vfp_set_fpsr(env, value);
> -    return 0;
>  }
>
>  static const ARMCPRegInfo v8_cp_reginfo[] = {
> @@ -1609,13 +1553,13 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
>      REGINFO_SENTINEL
>  };
>
> -static int sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
> +static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> +                        uint64_t value)
>  {
>      env->cp15.c1_sys = value;
>      /* ??? Lots of these bits are not implemented.  */
>      /* This may enable/disable the MMU, so do a TLB flush.  */
>      tlb_flush(env, 1);
> -    return 0;
>  }
>
>  void register_cp_regs_for_features(ARMCPU *cpu)
> @@ -2193,17 +2137,15 @@ const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
>      return g_hash_table_lookup(cpregs, &encoded_cp);
>  }
>
> -int arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
> -                        uint64_t value)
> +void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
> +                         uint64_t value)
>  {
>      /* Helper coprocessor write function for write-ignore registers */
> -    return 0;
>  }
>
> -int arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t *value)
> +uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
>      /* Helper coprocessor write function for read-as-zero registers */
> -    *value = 0;
>      return 0;
>  }
>
> diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
> index 89b0978..0c1b37a 100644
> --- a/target-arm/op_helper.c
> +++ b/target-arm/op_helper.c
> @@ -294,41 +294,25 @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip)
>  void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)
>  {
>      const ARMCPRegInfo *ri = rip;
> -    int excp = ri->writefn(env, ri, value);
> -    if (excp) {
> -        raise_exception(env, excp);
> -    }
> +    ri->writefn(env, ri, value);
>  }
>
>  uint32_t HELPER(get_cp_reg)(CPUARMState *env, void *rip)
>  {
>      const ARMCPRegInfo *ri = rip;
> -    uint64_t value;
> -    int excp = ri->readfn(env, ri, &value);
> -    if (excp) {
> -        raise_exception(env, excp);
> -    }
> -    return value;

Should ideally be a blank line here, but ..

> +    return ri->readfn(env, ri);

... you could just drop the single use variable completely with:

return ri->readfn(env, (const ARMCPRegInfo *)rip);

>  }
>
>  void HELPER(set_cp_reg64)(CPUARMState *env, void *rip, uint64_t value)
>  {
>      const ARMCPRegInfo *ri = rip;
> -    int excp = ri->writefn(env, ri, value);
> -    if (excp) {
> -        raise_exception(env, excp);
> -    }
> +    ri->writefn(env, ri, value);

Same.

>  }
>
>  uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
>  {
>      const ARMCPRegInfo *ri = rip;
> -    uint64_t value;
> -    int excp = ri->readfn(env, ri, &value);
> -    if (excp) {
> -        raise_exception(env, excp);
> -    }
> -    return value;
> +    return ri->readfn(env, ri);

Same. With fixes,

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

Regards,
Peter

>  }
>
>  void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 16/35] target-arm: Remove unnecessary code now read/write fns can't fail
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 16/35] target-arm: Remove unnecessary code now read/write fns can't fail Peter Maydell
@ 2014-02-09  3:29   ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  3:29 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Now that cpreg read and write functions can't fail and throw an
> exception, we can remove the code from the translator that synchronises
> the guest PC in case an exception is thrown.
>

Based on my comment last patch, this may be overly restrictive. You
are setting something of a developer trap for anyone that wants to
throw an exception for CPReg accesses for non-access reasons.

Regards,
Peter

> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target-arm/translate-a64.c | 2 --
>  target-arm/translate.c     | 4 ----
>  2 files changed, 6 deletions(-)
>
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index d90ffd1..f437359 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -1248,7 +1248,6 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
>              tcg_gen_movi_i64(tcg_rt, ri->resetvalue);
>          } else if (ri->readfn) {
>              TCGv_ptr tmpptr;
> -            gen_a64_set_pc_im(s->pc - 4);
>              tmpptr = tcg_const_ptr(ri);
>              gen_helper_get_cp_reg64(tcg_rt, cpu_env, tmpptr);
>              tcg_temp_free_ptr(tmpptr);
> @@ -1261,7 +1260,6 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
>              return;
>          } else if (ri->writefn) {
>              TCGv_ptr tmpptr;
> -            gen_a64_set_pc_im(s->pc - 4);
>              tmpptr = tcg_const_ptr(ri);
>              gen_helper_set_cp_reg64(cpu_env, tmpptr, tcg_rt);
>              tcg_temp_free_ptr(tmpptr);
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index 2713081..8149a3b 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -6837,7 +6837,6 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
>                      tmp64 = tcg_const_i64(ri->resetvalue);
>                  } else if (ri->readfn) {
>                      TCGv_ptr tmpptr;
> -                    gen_set_pc_im(s, s->pc);
>                      tmp64 = tcg_temp_new_i64();
>                      tmpptr = tcg_const_ptr(ri);
>                      gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
> @@ -6860,7 +6859,6 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
>                      tmp = tcg_const_i32(ri->resetvalue);
>                  } else if (ri->readfn) {
>                      TCGv_ptr tmpptr;
> -                    gen_set_pc_im(s, s->pc);
>                      tmp = tcg_temp_new_i32();
>                      tmpptr = tcg_const_ptr(ri);
>                      gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
> @@ -6895,7 +6893,6 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
>                  tcg_temp_free_i32(tmphi);
>                  if (ri->writefn) {
>                      TCGv_ptr tmpptr = tcg_const_ptr(ri);
> -                    gen_set_pc_im(s, s->pc);
>                      gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
>                      tcg_temp_free_ptr(tmpptr);
>                  } else {
> @@ -6906,7 +6903,6 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
>                  if (ri->writefn) {
>                      TCGv_i32 tmp;
>                      TCGv_ptr tmpptr;
> -                    gen_set_pc_im(s, s->pc);
>                      tmp = load_reg(s, rt);
>                      tmpptr = tcg_const_ptr(ri);
>                      gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 17/35] target-arm: Remove failure status return from read/write_raw_cp_reg
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 17/35] target-arm: Remove failure status return from read/write_raw_cp_reg Peter Maydell
@ 2014-02-09  3:32   ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09  3:32 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> The read_raw_cp_reg and write_raw_cp_reg functions can now never
> fail (in fact they should never have failed previously unless
> there was a bug in a reginfo that meant no raw accessor was
> provided for a might-trap register). This allows us to clean up
> their prototypes so the write function returns void and the
> read function returns the value read, which in turn lets us
> simplify the callers.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  target-arm/helper.c | 36 ++++++++++++------------------------
>  1 file changed, 12 insertions(+), 24 deletions(-)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 10aeccc..577b060 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -126,35 +126,30 @@ static void raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
>      }
>  }
>
> -static bool read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
> -                            uint64_t *v)
> +static uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri)
>  {
> -    /* Raw read of a coprocessor register (as needed for migration, etc)
> -     * return true on success, false if the read is impossible for some reason.
> -     */
> +    /* Raw read of a coprocessor register (as needed for migration, etc). */
>      if (ri->type & ARM_CP_CONST) {
> -        *v = ri->resetvalue;
> +        return ri->resetvalue;
>      } else if (ri->raw_readfn) {
> -        *v = ri->raw_readfn(env, ri);
> +        return ri->raw_readfn(env, ri);
>      } else if (ri->readfn) {
> -        *v = ri->readfn(env, ri);
> +        return ri->readfn(env, ri);
>      } else {
> -        *v = raw_read(env, ri);
> +        return raw_read(env, ri);
>      }
> -    return true;
>  }
>
> -static bool write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
> +static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
>                               int64_t v)
>  {
>      /* Raw write of a coprocessor register (as needed for migration, etc).
> -     * Return true on success, false if the write is impossible for some reason.
>       * Note that constant registers are treated as write-ignored; the
>       * caller should check for success by whether a readback gives the
>       * value written.
>       */
>      if (ri->type & ARM_CP_CONST) {
> -        return true;
> +        return;
>      } else if (ri->raw_writefn) {
>          ri->raw_writefn(env, ri, v);
>      } else if (ri->writefn) {
> @@ -162,7 +157,6 @@ static bool write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
>      } else {
>          raw_write(env, ri, v);
>      }
> -    return true;
>  }
>
>  bool write_cpustate_to_list(ARMCPU *cpu)
> @@ -174,7 +168,7 @@ bool write_cpustate_to_list(ARMCPU *cpu)
>      for (i = 0; i < cpu->cpreg_array_len; i++) {
>          uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
>          const ARMCPRegInfo *ri;
> -        uint64_t v;
> +
>          ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
>          if (!ri) {
>              ok = false;
> @@ -183,11 +177,7 @@ bool write_cpustate_to_list(ARMCPU *cpu)
>          if (ri->type & ARM_CP_NO_MIGRATE) {
>              continue;
>          }
> -        if (!read_raw_cp_reg(&cpu->env, ri, &v)) {
> -            ok = false;
> -            continue;
> -        }
> -        cpu->cpreg_values[i] = v;
> +        cpu->cpreg_values[i] = read_raw_cp_reg(&cpu->env, ri);
>      }
>      return ok;
>  }
> @@ -200,7 +190,6 @@ bool write_list_to_cpustate(ARMCPU *cpu)
>      for (i = 0; i < cpu->cpreg_array_len; i++) {
>          uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
>          uint64_t v = cpu->cpreg_values[i];
> -        uint64_t readback;
>          const ARMCPRegInfo *ri;
>
>          ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
> @@ -215,9 +204,8 @@ bool write_list_to_cpustate(ARMCPU *cpu)
>           * (to catch read-only registers and partially read-only
>           * registers where the incoming migration value doesn't match)
>           */
> -        if (!write_raw_cp_reg(&cpu->env, ri, v) ||
> -            !read_raw_cp_reg(&cpu->env, ri, &readback) ||
> -            readback != v) {
> +        write_raw_cp_reg(&cpu->env, ri, v);
> +        if (read_raw_cp_reg(&cpu->env, ri) != v) {
>              ok = false;
>          }
>      }
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 19/35] target-arm: A64: Make cache ID registers visible to AArch64
  2014-02-09  2:15   ` Peter Crosthwaite
@ 2014-02-09 11:52     ` Peter Maydell
  2014-02-09 21:01       ` Peter Crosthwaite
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-02-09 11:52 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On 9 February 2014 02:15, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> -    { .name = "CCSIDR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
>> +    { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
>> +      .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
>
> Why is the .cp field lost in the conversion to STATE_BOTH?

Because 64 bit sysregs don't have a concept of coprocessor. STATE_BOTH
means "this is a 64 bit sysreg with a cp15 encoding in the obvious place".
Anything other than cp15 needs split definitions anyway, so if we required
the .cp to be specified it would always be '.cp = 15'. Essentially this is
attempting to keep the length of cpreg definitions down by abbreviating
parts where there isn't actually any choice.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 11/35] target-arm: Split cpreg access checks out from read/write functions
  2014-02-09  2:50   ` Peter Crosthwaite
@ 2014-02-09 12:02     ` Peter Maydell
  2014-02-11  6:13       ` Peter Crosthwaite
  0 siblings, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-02-09 12:02 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On 9 February 2014 02:50, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> +typedef enum CPAccessResult {
>> +    /* Access is permitted */
>> +    CP_ACCESS_OK = 0,
>> +    /* Access fails due to a configurable trap or enable which would
>> +     * result in a categorized exception syndrome giving information about
>> +     * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
>> +     * 0xc or 0x18).
>> +     */
>> +    CP_ACCESS_TRAP = 1,
>> +    /* Access fails and results in an exception syndrome 0x0 ("uncategorized").
>> +     * Note that this is not a catch-all case -- the set of cases which may
>> +     * result in this failure is specifically defined by the architecture.
>> +     */
>> +    CP_ACCESS_TRAP_UNCATEGORIZED = 2,
>
> Hi Peter,
>
> So its not obvious to me just yet why these two types or traps needs
> separate encoding on this level. From your commentary, the two
> different types of traps are mutually exclusive and identifyable by
> the syndrome information. I.E _TRAP is syndrome != 0 and _TRAP_UNCAT
> is syndrome == 0. Cant the access checkers return boolean if is_trap
> then the syndrome can be used to make this distinction?

No, because the access checker is the thing that tells us what the
syndrome register is supposed to be. That is, the caller of the access
functions will do something like:

     ret = ri->accessfn(env, ri);
     switch (ret) {
          case CP_ACCESS_OK:
                 return;
          case CP_ACCESS_TRAP:
                 env->exception.syndrome = syn_cp_trap(stuff);
                 break;
          case CP_ACCESS_TRAP_UNCATEGORIZED:
                 env->exception_syndrome = syn_uncategorized();
                 break;
     }
     raise_exception(EXCP_UDEF);

(This code is in the syndrome work I have which sits on top of this
patchset; it's pretty nearly ready to post but I have a few odds and
ends to tie off first.)

The actual value of the syndrome register depends on a pile
of stuff that includes various fields from the instruction, so we
don't want to burden the access checkers with actually setting
or returning us a syndrome value. (Also the syndrome encoding
covers the whole uint32_t space so it's not possible to return
"syndrome or some value meaning no exception", which makes
that an awkward API choice anyway.) So we just have the checker
tell us "OK, or this set of syndromes, or that set?" and we can calculate
the syndrome from just that three-way bit of information.

The phrasing of the comments above is supposed to help somebody
implementing a cpreg know what they should be returning : the
ARM ARM docs will let them know which kind of syndrome category
the access failure is, which in turn indicates which CP_ value to
return to cause QEMU to generate the syndrome information that
is required.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 12/35] target-arm: Convert performance monitor reginfo to accesfn
  2014-02-09  2:59       ` Peter Crosthwaite
@ 2014-02-09 12:04         ` Peter Maydell
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-02-09 12:04 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Rob Herring, Patch Tracking, Michael Matz,
	qemu-devel@nongnu.org Developers, Alexander Graf,
	Claudio Fontana, Dirk Mueller, Will Newton, Laurent Desnogues,
	Alistair Francis, Alex Bennée, kvmarm, Christoffer Dall,
	Richard Henderson

On 9 February 2014 02:59, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:

> Agreed. With diff-correction based on this scheme:
>
> Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
>
>  But the nice thing about having named fields is it
>> doesn't actually matter what order things go in.
>>
>
> But for similar entries its much more readable if they are self-consistent.

Yes; this patch in particular was rather inconsistent and I
have fixed it.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 14/35] target-arm: Convert miscellaneous reginfo structs to accessfn
  2014-02-09  3:09   ` Peter Crosthwaite
@ 2014-02-09 12:09     ` Peter Maydell
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-02-09 12:09 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On 9 February 2014 03:09, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>
>> +static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri)
>> +{
>> +    if (ri->opc2 & 4) {
>> +        /* Other states are only available with TrustZone; in
>
> A nit, but following earlier discussions there in no mention of
> "TrustZone" in ARM ARM. Should this be "security extensions"?

This is just a movement of an existing comment:

>> -    if (ri->opc2 & 4) {
>> -        /* Other states are only available with TrustZone */
>> -        return EXCP_UDEF;
>> -    }

I'm not going to go through changing all the references to "Neon"
to "AdvSIMD" either...

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 15/35] target-arm: Drop success/fail return from cpreg read and write functions
  2014-02-09  3:27   ` Peter Crosthwaite
@ 2014-02-09 12:15     ` Peter Maydell
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-02-09 12:15 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On 9 February 2014 03:27, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> -/* Access functions for coprocessor registers. These should always succeed. */
>> -typedef int CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque,
>> -                     uint64_t *value);
>> -typedef int CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
>> -                      uint64_t value);
>> +/* Access functions for coprocessor registers. These cannot fail and
>> + * may not raise exceptions.
>
> Is this based on an assumption that the only possible reason for an
> exception is access violation? This series quite validly obsoletes the
> need for exception-via-return-path, but my understanding is that CP
> accessor functions are able to implement any form of side affects. If
> an exception is thus generated from the side effects of a CP access
> then thats fair game - it just happens via the already existing
> mechanisms for generating an exception from helper context. Long story
> short, I think you can just drop second sentence from this comment.

It's based on the fact that the translate.c code no longer supports
calling raise_exception() from within a read/write function -- if you
try it the PC will be wrong because we haven't synchronised it
before calling the helper function. You're right that in theory a
coprocessor access could raise an arbitrary exception, but if
anybody needs that they'll need to add the support (probably by
adding an extra ARM_CP_ flag for "can raise exceptions" so we
don't take the hit of synchronising PC except in the odd case
where it's necessary.) In practice I think it is unlikely that there
will be any such situation which couldn't be handled by a suitable
accessfn.

>>  uint32_t HELPER(get_cp_reg)(CPUARMState *env, void *rip)
>>  {
>>      const ARMCPRegInfo *ri = rip;
>> -    uint64_t value;
>> -    int excp = ri->readfn(env, ri, &value);
>> -    if (excp) {
>> -        raise_exception(env, excp);
>> -    }
>> -    return value;
>
> Should ideally be a blank line here, but ..
>
>> +    return ri->readfn(env, ri);
>
> ... you could just drop the single use variable completely with:
>
> return ri->readfn(env, (const ARMCPRegInfo *)rip);

I dislike casts like that. I'll put in the blank line if you like.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 19/35] target-arm: A64: Make cache ID registers visible to AArch64
  2014-02-09 11:52     ` Peter Maydell
@ 2014-02-09 21:01       ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-09 21:01 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Patch Tracking, Michael Matz,
	qemu-devel@nongnu.org Developers, Alexander Graf,
	Claudio Fontana, Dirk Mueller, Will Newton, Laurent Desnogues,
	Alex Bennée, kvmarm, Christoffer Dall, Richard Henderson

On Sun, Feb 9, 2014 at 9:52 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 9 February 2014 02:15, Peter Crosthwaite
> <peter.crosthwaite@xilinx.com> wrote:
>> On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>> -    { .name = "CCSIDR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
>>> +    { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
>>> +      .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
>>
>> Why is the .cp field lost in the conversion to STATE_BOTH?
>
> Because 64 bit sysregs don't have a concept of coprocessor. STATE_BOTH
> means "this is a 64 bit sysreg with a cp15 encoding in the obvious place".
> Anything other than cp15 needs split definitions anyway, so if we required
> the .cp to be specified it would always be '.cp = 15'. Essentially this is
> attempting to keep the length of cpreg definitions down by abbreviating
> parts where there isn't actually any choice.
>

Thanks,

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> thanks
> -- PMM
>

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

* Re: [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (34 preceding siblings ...)
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 35/35] target-arm: Implement AArch64 OSLAR_EL1 sysreg as WI Peter Maydell
@ 2014-02-11  6:11 ` Peter Crosthwaite
  2014-02-11  9:05   ` Peter Maydell
  2014-02-11 17:12 ` Peter Maydell
  36 siblings, 1 reply; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-11  6:11 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> This is version two of a patchset which makes a start on AArch64
> system emulation by tackling system registers.
>
> The major changes here since v1 are that I've added a set of
> patches which rework the reginfo struct to use a separate accessfn
> rather than having readfn and writenfn possibly return EXCP_UDEF.
> This was suggested by Peter Crosthwaite in the previous round and
> I think it is a big improvement.
>
> For correct syndrome information the next step will be that
> the translate.c/translate-a64.c code passes helper_access_check_cp_reg()
> a prototype syndrome so it can eventually be used by the exception
> entry code; but I'm still working on the syndrome register support
> code, and anyway this series is already pretty long.
>
> Review appreciated, especially for the early patches in the
> series and for the accessfn refactoring, so I can start to
> feed these patches into target-arm.next.
>

Hi Peter,

Im finished with my review of this one, all outstanding
comments/queries are addressed so for any patches w/o my RB already:

acked-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

Still not a huge fan of pulling out the exception capability from the
helper context CP regs accessors but it's not worth arguing over TBH.

Regards,
peter

> thanks
> -- PMM
>
> Peter Maydell (35):
>   target-arm: Fix raw read and write functions on AArch64 registers
>   target-arm/kvm-consts.h: Define QEMU constants for known KVM CPUs
>   target-arm: Define names for SCTLR bits
>   target-arm: Restrict check_ap() use of S and R bits to v6 and earlier
>   target-arm: Remove unused ARMCPUState sr substruct
>   target-arm: Log bad system register accesses with LOG_UNIMP
>   target-arm: Add exception level to the AArch64 TB flags
>   target-arm: A64: Implement store-exclusive for system mode
>   target-arm: A64: Implement MSR (immediate) instructions
>   target-arm: Stop underdecoding ARM946 PRBS registers
>   target-arm: Split cpreg access checks out from read/write functions
>   target-arm: Convert performance monitor reginfo to accesfn
>   target-arm: Convert generic timer reginfo to accessfn
>   target-arm: Convert miscellaneous reginfo structs to accessfn
>   target-arm: Drop success/fail return from cpreg read and write
>     functions
>   target-arm: Remove unnecessary code now read/write fns can't fail
>   target-arm: Remove failure status return from read/write_raw_cp_reg
>   target-arm: Fix incorrect type for value argument to write_raw_cp_reg
>   target-arm: A64: Make cache ID registers visible to AArch64
>   target-arm: Implement AArch64 CurrentEL sysreg
>   target-arm: Implement AArch64 MIDR_EL1
>   target-arm: Implement AArch64 DAIF system register
>   target-arm: Implement AArch64 cache invalidate/clean ops
>   target-arm: Implement AArch64 TLB invalidate ops
>   target-arm: Implement AArch64 dummy MDSCR_EL1
>   target-arm: Implement AArch64 memory attribute registers
>   target-arm: Implement AArch64 SCTLR_EL1
>   target-arm: Implement AArch64 TCR_EL1
>   target-arm: Implement AArch64 VBAR_EL1
>   target-arm: Implement AArch64 TTBR*
>   target-arm: Implement AArch64 MPIDR
>   target-arm: Implement AArch64 generic timers
>   target-arm: Implement AArch64 ID and feature registers
>   target-arm: Implement AArch64 dummy breakpoint and watchpoint
>     registers
>   target-arm: Implement AArch64 OSLAR_EL1 sysreg as WI
>
>  hw/arm/pxa2xx.c            |   38 +-
>  hw/arm/pxa2xx_pic.c        |   11 +-
>  target-arm/cpu-qom.h       |   10 +
>  target-arm/cpu.c           |   12 +-
>  target-arm/cpu.h           |  153 +++++--
>  target-arm/cpu64.c         |    1 +
>  target-arm/helper.c        | 1093 +++++++++++++++++++++++++++-----------------
>  target-arm/helper.h        |    3 +
>  target-arm/kvm-consts.h    |   16 +-
>  target-arm/op_helper.c     |   65 ++-
>  target-arm/translate-a64.c |  119 ++++-
>  target-arm/translate.c     |   28 +-
>  12 files changed, 1025 insertions(+), 524 deletions(-)
>
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 11/35] target-arm: Split cpreg access checks out from read/write functions
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 11/35] target-arm: Split cpreg access checks out from read/write functions Peter Maydell
  2014-02-09  2:50   ` Peter Crosthwaite
@ 2014-02-11  6:13   ` Peter Crosthwaite
  1 sibling, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-11  6:13 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Several of the system registers handled via the ARMCPRegInfo
> mechanism have access trap control bits controlling whether the
> registers are accessible to lower privilege levels. Replace
> the existing mechanism (allowing the read and write functions
> to return EXCP_UDEF if access is denied) with a dedicated
> "check access rights" function pointer in the ARMCPRegInfo.
> This will allow us to simplify some of the register definitions,
> which no longer need read/write functions purely to handle
> the access checks.
>
> We take the opportunity to define the return value from the
> access checking function in a way that allows us to set the
> correct exception syndrome information for exceptions taken
> to AArch64 (which may need to distinguish access failures due
> to a configurable trap or enable from other kinds of access
> failure).
>
> This commit defines the new mechanism but does not move any
> of the registers across to use it.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  target-arm/cpu.h           | 29 +++++++++++++++++++++++++----
>  target-arm/helper.h        |  1 +
>  target-arm/op_helper.c     | 18 ++++++++++++++++++
>  target-arm/translate-a64.c | 11 +++++++++++
>  target-arm/translate.c     | 11 +++++++++++
>  5 files changed, 66 insertions(+), 4 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index e66d464..30b1a1c 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -812,14 +812,29 @@ static inline int arm_current_pl(CPUARMState *env)
>
>  typedef struct ARMCPRegInfo ARMCPRegInfo;
>
> -/* Access functions for coprocessor registers. These should return
> - * 0 on success, or one of the EXCP_* constants if access should cause
> - * an exception (in which case *value is not written).
> - */
> +typedef enum CPAccessResult {
> +    /* Access is permitted */
> +    CP_ACCESS_OK = 0,
> +    /* Access fails due to a configurable trap or enable which would
> +     * result in a categorized exception syndrome giving information about
> +     * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
> +     * 0xc or 0x18).
> +     */
> +    CP_ACCESS_TRAP = 1,
> +    /* Access fails and results in an exception syndrome 0x0 ("uncategorized").
> +     * Note that this is not a catch-all case -- the set of cases which may
> +     * result in this failure is specifically defined by the architecture.
> +     */
> +    CP_ACCESS_TRAP_UNCATEGORIZED = 2,
> +} CPAccessResult;
> +
> +/* Access functions for coprocessor registers. These should always succeed. */
>  typedef int CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque,
>                       uint64_t *value);
>  typedef int CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
>                        uint64_t value);
> +/* Access permission check functions for coprocessor registers. */
> +typedef CPAccessResult CPAccessFn(CPUARMState *env, const ARMCPRegInfo *opaque);
>  /* Hook function for register reset */
>  typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
>
> @@ -873,6 +888,12 @@ struct ARMCPRegInfo {
>       *  2. both readfn and writefn are specified
>       */
>      ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
> +    /* 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
> +     * translate time.
> +     */
> +    CPAccessFn *accessfn;
>      /* Function for handling reads of this register. If NULL, then reads
>       * will be done by loading from the offset into CPUARMState specified
>       * by fieldoffset.
> diff --git a/target-arm/helper.h b/target-arm/helper.h
> index 93a27ce..1d83293 100644
> --- a/target-arm/helper.h
> +++ b/target-arm/helper.h
> @@ -57,6 +57,7 @@ DEF_HELPER_1(cpsr_read, i32, env)
>  DEF_HELPER_3(v7m_msr, void, env, i32, i32)
>  DEF_HELPER_2(v7m_mrs, i32, env, i32)
>
> +DEF_HELPER_2(access_check_cp_reg, void, env, ptr)
>  DEF_HELPER_3(set_cp_reg, void, env, ptr, i32)
>  DEF_HELPER_2(get_cp_reg, i32, env, ptr)
>  DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
> diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
> index c812a9f..89b0978 100644
> --- a/target-arm/op_helper.c
> +++ b/target-arm/op_helper.c
> @@ -273,6 +273,24 @@ void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
>      }
>  }
>
> +void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip)
> +{
> +    const ARMCPRegInfo *ri = rip;
> +    switch (ri->accessfn(env, ri)) {
> +    case CP_ACCESS_OK:
> +        return;
> +    case CP_ACCESS_TRAP:
> +    case CP_ACCESS_TRAP_UNCATEGORIZED:
> +        /* These cases will eventually need to generate different
> +         * syndrome information.
> +         */
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
> +    raise_exception(env, EXCP_UDEF);
> +}
> +
>  void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)
>  {
>      const ARMCPRegInfo *ri = rip;
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index a942609..d90ffd1 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -1210,6 +1210,17 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
>          return;
>      }
>
> +    if (ri->accessfn) {
> +        /* Emit code to perform further access permissions checks at
> +         * runtime; this may result in an exception.
> +         */
> +        TCGv_ptr tmpptr;
> +        gen_a64_set_pc_im(s->pc - 4);
> +        tmpptr = tcg_const_ptr(ri);
> +        gen_helper_access_check_cp_reg(cpu_env, tmpptr);
> +        tcg_temp_free_ptr(tmpptr);
> +    }
> +
>      /* Handle special cases first */
>      switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
>      case ARM_CP_NOP:
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index 45886f9..2713081 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -6798,6 +6798,17 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
>              return 1;
>          }
>
> +        if (ri->accessfn) {
> +            /* Emit code to perform further access permissions checks at
> +             * runtime; this may result in an exception.
> +             */
> +            TCGv_ptr tmpptr;
> +            gen_set_pc_im(s, s->pc);
> +            tmpptr = tcg_const_ptr(ri);
> +            gen_helper_access_check_cp_reg(cpu_env, tmpptr);
> +            tcg_temp_free_ptr(tmpptr);
> +        }
> +
>          /* Handle special cases first */
>          switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
>          case ARM_CP_NOP:
> --
> 1.8.5
>
>

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

* Re: [Qemu-devel] [PATCH v2 11/35] target-arm: Split cpreg access checks out from read/write functions
  2014-02-09 12:02     ` Peter Maydell
@ 2014-02-11  6:13       ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-11  6:13 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Patch Tracking, Michael Matz,
	qemu-devel@nongnu.org Developers, Alexander Graf,
	Claudio Fontana, Dirk Mueller, Will Newton, Laurent Desnogues,
	Alex Bennée, kvmarm, Christoffer Dall, Richard Henderson

On Sun, Feb 9, 2014 at 10:02 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 9 February 2014 02:50, Peter Crosthwaite
> <peter.crosthwaite@xilinx.com> wrote:
>> On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>> +typedef enum CPAccessResult {
>>> +    /* Access is permitted */
>>> +    CP_ACCESS_OK = 0,
>>> +    /* Access fails due to a configurable trap or enable which would
>>> +     * result in a categorized exception syndrome giving information about
>>> +     * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
>>> +     * 0xc or 0x18).
>>> +     */
>>> +    CP_ACCESS_TRAP = 1,
>>> +    /* Access fails and results in an exception syndrome 0x0 ("uncategorized").
>>> +     * Note that this is not a catch-all case -- the set of cases which may
>>> +     * result in this failure is specifically defined by the architecture.
>>> +     */
>>> +    CP_ACCESS_TRAP_UNCATEGORIZED = 2,
>>
>> Hi Peter,
>>
>> So its not obvious to me just yet why these two types or traps needs
>> separate encoding on this level. From your commentary, the two
>> different types of traps are mutually exclusive and identifyable by
>> the syndrome information. I.E _TRAP is syndrome != 0 and _TRAP_UNCAT
>> is syndrome == 0. Cant the access checkers return boolean if is_trap
>> then the syndrome can be used to make this distinction?
>
> No, because the access checker is the thing that tells us what the
> syndrome register is supposed to be. That is, the caller of the access
> functions will do something like:
>
>      ret = ri->accessfn(env, ri);
>      switch (ret) {
>           case CP_ACCESS_OK:
>                  return;
>           case CP_ACCESS_TRAP:
>                  env->exception.syndrome = syn_cp_trap(stuff);
>                  break;
>           case CP_ACCESS_TRAP_UNCATEGORIZED:
>                  env->exception_syndrome = syn_uncategorized();
>                  break;
>      }
>      raise_exception(EXCP_UDEF);
>
> (This code is in the syndrome work I have which sits on top of this
> patchset; it's pretty nearly ready to post but I have a few odds and
> ends to tie off first.)
>
> The actual value of the syndrome register depends on a pile
> of stuff that includes various fields from the instruction, so we
> don't want to burden the access checkers with actually setting
> or returning us a syndrome value. (Also the syndrome encoding
> covers the whole uint32_t space so it's not possible to return
> "syndrome or some value meaning no exception", which makes
> that an awkward API choice anyway.) So we just have the checker
> tell us "OK, or this set of syndromes, or that set?" and we can calculate
> the syndrome from just that three-way bit of information.
>
> The phrasing of the comments above is supposed to help somebody
> implementing a cpreg know what they should be returning : the
> ARM ARM docs will let them know which kind of syndrome category
> the access failure is, which in turn indicates which CP_ value to
> return to cause QEMU to generate the syndrome information that
> is required.
>

Thanks for the clarification. I was assuming that checkers were going
to do syndromes.

Regards,
Peter

> thanks
> -- PMM
>

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

* Re: [Qemu-devel] [PATCH v2 19/35] target-arm: A64: Make cache ID registers visible to AArch64
  2014-02-07 10:27     ` Peter Maydell
@ 2014-02-11  8:38       ` Hu Tao
  0 siblings, 0 replies; 83+ messages in thread
From: Hu Tao @ 2014-02-11  8:38 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Peter Crosthwaite, Laurent Desnogues,
	Patch Tracking, Michael Matz, QEMU Developers, Claudio Fontana,
	Dirk Mueller, Will Newton, kvmarm, Richard Henderson

On Fri, Feb 07, 2014 at 10:27:35AM +0000, Peter Maydell wrote:
> On 7 February 2014 07:35, Hu Tao <hutao@cn.fujitsu.com> wrote:
> > On Fri, Jan 31, 2014 at 03:45:27PM +0000, Peter Maydell wrote:
> >> Make the cache ID system registers (CLIDR, CCSELR, CCSIDR, CTR)
> >
> > s/CCSELR/CSSELR/
> >
> >> visible to AArch64. These are mostly simple 64-bit extensions of the
> >> existing 32 bit system registers and so can share reginfo definitions.
> >
> > According to the document(ARM DDI 0487A.a), some AArch64 system
> > registers are 32-bit, for example CCSIDR_EL1 is 32-bit. But System_Put()
> > and System_Get() writes/reads 64-bit values, which makes me confused.
> 
> We've been round this issue before. The documentation
> uses "32-bit" as a shorthand for "64 bit but the top
> 32 bits are RES0". There is no way in AArch64 to do a
> 32 bit read or write of a system register -- the only
> instructions are MSR/MRS, which are always 64 bits.
> Similarly, the KVM kernel API exposes all registers as
> 64 bits wide.

Thanks for the explanation!

-- 
Regards,
Hu Tao

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

* Re: [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework
  2014-02-11  6:11 ` [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Crosthwaite
@ 2014-02-11  9:05   ` Peter Maydell
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-02-11  9:05 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On 11 February 2014 06:11, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> Im finished with my review of this one, all outstanding
> comments/queries are addressed so for any patches w/o my RB already:
>
> acked-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

Thanks. I'll put some of the reviewed patches into target-arm.next,
respin with fixes for various things and see if any of the syndrome
stuff is ready to tack onto the end for v2.

> Still not a huge fan of pulling out the exception capability from the
> helper context CP regs accessors but it's not worth arguing over TBH.

If we do find we ever need it in the future then it's a trivial 10
line patch to add the support back in, so we're not preventing
the possibility forever.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework
  2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
                   ` (35 preceding siblings ...)
  2014-02-11  6:11 ` [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Crosthwaite
@ 2014-02-11 17:12 ` Peter Maydell
  36 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-02-11 17:12 UTC (permalink / raw)
  To: QEMU Developers
  Cc: Rob Herring, Peter Crosthwaite, Laurent Desnogues,
	Patch Tracking, Michael Matz, Claudio Fontana, Dirk Mueller,
	Will Newton, kvmarm, Richard Henderson

On 31 January 2014 15:45, Peter Maydell <peter.maydell@linaro.org> wrote:
> Review appreciated, especially for the early patches in the
> series and for the accessfn refactoring, so I can start to
> feed these patches into target-arm.next.

OK, I'm going to put a bunch of the groundwork/cpreg API
refactoring patches into target-arm.next. Specifically:

> Peter Maydell (35):
>   target-arm: Fix raw read and write functions on AArch64 registers

This patch was broken and needs a respin

>   target-arm/kvm-consts.h: Define QEMU constants for known KVM CPUs
>   target-arm: Define names for SCTLR bits
>   target-arm: Restrict check_ap() use of S and R bits to v6 and earlier
>   target-arm: Remove unused ARMCPUState sr substruct
>   target-arm: Log bad system register accesses with LOG_UNIMP

these were fine and got review (mostly) -- will put in target-arm.next

>   target-arm: Add exception level to the AArch64 TB flags
>   target-arm: A64: Implement store-exclusive for system mode
>   target-arm: A64: Implement MSR (immediate) instructions

will skip these for now (either unreviewed or have issues)

>   target-arm: Stop underdecoding ARM946 PRBS registers
>   target-arm: Split cpreg access checks out from read/write functions
>   target-arm: Convert performance monitor reginfo to accesfn
>   target-arm: Convert generic timer reginfo to accessfn
>   target-arm: Convert miscellaneous reginfo structs to accessfn
>   target-arm: Drop success/fail return from cpreg read and write
>     functions
>   target-arm: Remove unnecessary code now read/write fns can't fail
>   target-arm: Remove failure status return from read/write_raw_cp_reg
>   target-arm: Fix incorrect type for value argument to write_raw_cp_reg

these were all reviewed so will go into target-arm.next

>   target-arm: A64: Make cache ID registers visible to AArch64
>   target-arm: Implement AArch64 CurrentEL sysreg
>   target-arm: Implement AArch64 MIDR_EL1
>   target-arm: Implement AArch64 DAIF system register
>   target-arm: Implement AArch64 cache invalidate/clean ops
>   target-arm: Implement AArch64 TLB invalidate ops
>   target-arm: Implement AArch64 dummy MDSCR_EL1
>   target-arm: Implement AArch64 memory attribute registers
>   target-arm: Implement AArch64 SCTLR_EL1
>   target-arm: Implement AArch64 TCR_EL1
>   target-arm: Implement AArch64 VBAR_EL1
>   target-arm: Implement AArch64 TTBR*
>   target-arm: Implement AArch64 MPIDR
>   target-arm: Implement AArch64 generic timers
>   target-arm: Implement AArch64 ID and feature registers
>   target-arm: Implement AArch64 dummy breakpoint and watchpoint
>     registers
>   target-arm: Implement AArch64 OSLAR_EL1 sysreg as WI

These were mostly fine (some review issues to be addressed)
but they depend on a fixed version of that patch at the
top of the stack so won't put them in for now; will retransmit
in a v2 series.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 08/35] target-arm: A64: Implement store-exclusive for system mode
  2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 08/35] target-arm: A64: Implement store-exclusive for system mode Peter Maydell
@ 2014-02-11 18:43   ` Peter Maydell
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Maydell @ 2014-02-11 18:43 UTC (permalink / raw)
  To: QEMU Developers
  Cc: Rob Herring, Peter Crosthwaite, Laurent Desnogues,
	Patch Tracking, Michael Matz, Claudio Fontana, Dirk Mueller,
	Will Newton, kvmarm, Richard Henderson

On 31 January 2014 15:45, Peter Maydell <peter.maydell@linaro.org> wrote:
> System mode store-exclusive use a different code path to usermode ones;
> implement this missing code, in a similar way to the 32 bit version.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

I just got a reviewed-by from rth on IRC for this patch
and so I'm going to add it to target-arm.next.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 09/35] target-arm: A64: Implement MSR (immediate) instructions
  2014-02-05  6:23   ` Peter Crosthwaite
  2014-02-05 10:55     ` Peter Maydell
@ 2014-02-14 16:41     ` Peter Maydell
  2014-02-14 23:07       ` Peter Crosthwaite
  1 sibling, 1 reply; 83+ messages in thread
From: Peter Maydell @ 2014-02-14 16:41 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Rob Herring, Laurent Desnogues, Patch Tracking, Michael Matz,
	Alexander Graf, qemu-devel@nongnu.org Developers,
	Claudio Fontana, Dirk Mueller, Will Newton, Alex Bennée,
	kvmarm, Christoffer Dall, Richard Henderson

On 5 February 2014 06:23, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> +    switch (op) {
>> +    case 0x05: /* SPSel */
>> +        env->pstate = deposit32(env->pstate, 0, 1, imm);
>
> "0","1" hardcoded constants are a bit unfriendly. I guess the current
> macro set doesnt define _SHIFT and _WIDTH definitions, should they be
> added?
>
> FWIW, I have this macro in my tree which makes short work of defining
> mask, shift and width constants as a one liner:
>
> /* Define SHIFT, LENGTH and MASK constants for a field within a register */
>
> #define FIELD(reg, field, length, shift) \
> enum { reg ## _ ## field ## _SHIFT = (shift)}; \
> enum { reg ## _ ## field ## _LENGTH = (length)}; \
> enum { reg ## _ ## field ## _MASK = (((1ULL << (length)) - 1) \
>                                           << (shift)) };
>
> Usage would be something like FIELD(PSTATE, SPSEL, 1, 0)

So, I kind of like this, but I'm a bit reluctant to tie up
this patchset in "add a new generic facility to bitops.h",
and current handling for pstate/cpsr has a lot of hardcoded
constants for bit positions. Is it OK if we do this as a
separate cleanup, or do you feel strongly we should bite
the bullet and do it as part of this series?

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 09/35] target-arm: A64: Implement MSR (immediate) instructions
  2014-02-14 16:41     ` Peter Maydell
@ 2014-02-14 23:07       ` Peter Crosthwaite
  0 siblings, 0 replies; 83+ messages in thread
From: Peter Crosthwaite @ 2014-02-14 23:07 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Rob Herring, Patch Tracking, Michael Matz,
	qemu-devel@nongnu.org Developers, Alexander Graf,
	Claudio Fontana, Dirk Mueller, Will Newton, Laurent Desnogues,
	Alex Bennée, kvmarm, Christoffer Dall, Richard Henderson

On Sat, Feb 15, 2014 at 2:41 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 5 February 2014 06:23, Peter Crosthwaite
> <peter.crosthwaite@xilinx.com> wrote:
>> On Sat, Feb 1, 2014 at 1:45 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>> +    switch (op) {
>>> +    case 0x05: /* SPSel */
>>> +        env->pstate = deposit32(env->pstate, 0, 1, imm);
>>
>> "0","1" hardcoded constants are a bit unfriendly. I guess the current
>> macro set doesnt define _SHIFT and _WIDTH definitions, should they be
>> added?
>>
>> FWIW, I have this macro in my tree which makes short work of defining
>> mask, shift and width constants as a one liner:
>>
>> /* Define SHIFT, LENGTH and MASK constants for a field within a register */
>>
>> #define FIELD(reg, field, length, shift) \
>> enum { reg ## _ ## field ## _SHIFT = (shift)}; \
>> enum { reg ## _ ## field ## _LENGTH = (length)}; \
>> enum { reg ## _ ## field ## _MASK = (((1ULL << (length)) - 1) \
>>                                           << (shift)) };
>>
>> Usage would be something like FIELD(PSTATE, SPSEL, 1, 0)
>
> So, I kind of like this, but I'm a bit reluctant to tie up
> this patchset in "add a new generic facility to bitops.h",
> and current handling for pstate/cpsr has a lot of hardcoded
> constants for bit positions. Is it OK if we do this as a
> separate cleanup, or do you feel strongly we should bite
> the bullet and do it as part of this series?
>

No I think its follow up.

Regards,
Peter

> thanks
> -- PMM
>

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

end of thread, other threads:[~2014-02-14 23:08 UTC | newest]

Thread overview: 83+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-31 15:45 [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 01/35] target-arm: Fix raw read and write functions on AArch64 registers Peter Maydell
2014-01-31 15:56   ` Rob Herring
2014-01-31 16:06     ` Peter Maydell
2014-01-31 16:38       ` Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 02/35] target-arm/kvm-consts.h: Define QEMU constants for known KVM CPUs Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 03/35] target-arm: Define names for SCTLR bits Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 04/35] target-arm: Restrict check_ap() use of S and R bits to v6 and earlier Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 05/35] target-arm: Remove unused ARMCPUState sr substruct Peter Maydell
2014-02-05  6:03   ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 06/35] target-arm: Log bad system register accesses with LOG_UNIMP Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 07/35] target-arm: Add exception level to the AArch64 TB flags Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 08/35] target-arm: A64: Implement store-exclusive for system mode Peter Maydell
2014-02-11 18:43   ` Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 09/35] target-arm: A64: Implement MSR (immediate) instructions Peter Maydell
2014-02-05  6:23   ` Peter Crosthwaite
2014-02-05 10:55     ` Peter Maydell
2014-02-14 16:41     ` Peter Maydell
2014-02-14 23:07       ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 10/35] target-arm: Stop underdecoding ARM946 PRBS registers Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 11/35] target-arm: Split cpreg access checks out from read/write functions Peter Maydell
2014-02-09  2:50   ` Peter Crosthwaite
2014-02-09 12:02     ` Peter Maydell
2014-02-11  6:13       ` Peter Crosthwaite
2014-02-11  6:13   ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 12/35] target-arm: Convert performance monitor reginfo to accesfn Peter Maydell
2014-02-05  6:59   ` Peter Crosthwaite
2014-02-05 11:01     ` Peter Maydell
2014-02-06  0:05       ` Alistair Francis
2014-02-09  2:59       ` Peter Crosthwaite
2014-02-09 12:04         ` Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 13/35] target-arm: Convert generic timer reginfo to accessfn Peter Maydell
2014-02-09  3:05   ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 14/35] target-arm: Convert miscellaneous reginfo structs " Peter Maydell
2014-02-09  3:09   ` Peter Crosthwaite
2014-02-09 12:09     ` Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 15/35] target-arm: Drop success/fail return from cpreg read and write functions Peter Maydell
2014-02-09  3:27   ` Peter Crosthwaite
2014-02-09 12:15     ` Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 16/35] target-arm: Remove unnecessary code now read/write fns can't fail Peter Maydell
2014-02-09  3:29   ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 17/35] target-arm: Remove failure status return from read/write_raw_cp_reg Peter Maydell
2014-02-09  3:32   ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 18/35] target-arm: Fix incorrect type for value argument to write_raw_cp_reg Peter Maydell
2014-02-05  7:07   ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 19/35] target-arm: A64: Make cache ID registers visible to AArch64 Peter Maydell
2014-02-07  7:35   ` Hu Tao
2014-02-07 10:27     ` Peter Maydell
2014-02-11  8:38       ` Hu Tao
2014-02-09  2:15   ` Peter Crosthwaite
2014-02-09 11:52     ` Peter Maydell
2014-02-09 21:01       ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 20/35] target-arm: Implement AArch64 CurrentEL sysreg Peter Maydell
2014-02-09  2:17   ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 21/35] target-arm: Implement AArch64 MIDR_EL1 Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 22/35] target-arm: Implement AArch64 DAIF system register Peter Maydell
2014-02-09  2:20   ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 23/35] target-arm: Implement AArch64 cache invalidate/clean ops Peter Maydell
2014-02-06 11:45   ` Peter Maydell
2014-02-09  2:22   ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 24/35] target-arm: Implement AArch64 TLB invalidate ops Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 25/35] target-arm: Implement AArch64 dummy MDSCR_EL1 Peter Maydell
2014-02-09  2:27   ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 26/35] target-arm: Implement AArch64 memory attribute registers Peter Maydell
2014-02-09  2:31   ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 27/35] target-arm: Implement AArch64 SCTLR_EL1 Peter Maydell
2014-02-09  2:32   ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 28/35] target-arm: Implement AArch64 TCR_EL1 Peter Maydell
2014-02-09  2:35   ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 29/35] target-arm: Implement AArch64 VBAR_EL1 Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 30/35] target-arm: Implement AArch64 TTBR* Peter Maydell
2014-02-09  2:38   ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 31/35] target-arm: Implement AArch64 MPIDR Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 32/35] target-arm: Implement AArch64 generic timers Peter Maydell
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 33/35] target-arm: Implement AArch64 ID and feature registers Peter Maydell
2014-02-09  2:42   ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 34/35] target-arm: Implement AArch64 dummy breakpoint and watchpoint registers Peter Maydell
2014-02-09  2:44   ` Peter Crosthwaite
2014-01-31 15:45 ` [Qemu-devel] [PATCH v2 35/35] target-arm: Implement AArch64 OSLAR_EL1 sysreg as WI Peter Maydell
2014-02-09  2:44   ` Peter Crosthwaite
2014-02-11  6:11 ` [Qemu-devel] [PATCH v2 00/35] AArch64 system mode: system register rework Peter Crosthwaite
2014-02-11  9:05   ` Peter Maydell
2014-02-11 17:12 ` Peter Maydell

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