qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC PATCH 16/21] target-arm: convert appropriate coprocess


From: Sergey Fedorov
Subject: [Qemu-devel] [RFC PATCH 16/21] target-arm: convert appropriate coprocessor registers to banked type
Date: Tue, 03 Dec 2013 12:48:50 +0400

Define appropriate coprocessor registers with banked type. The register
state fields are defined with BANKED_CP_REG() macro.

Banked coprocessor registers with a special behaviour is adjusted to
correctly use its active or banked non-secure state.

Signed-off-by: Sergey Fedorov <address@hidden>
---
 target-arm/cpu.c    |    2 +-
 target-arm/cpu.h    |   62 +++++++++++++++++---------
 target-arm/helper.c |  120 +++++++++++++++++++++++++++++----------------------
 3 files changed, 111 insertions(+), 73 deletions(-)

diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 4607ca8..3bb3deb 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -356,7 +356,7 @@ static void arm1026_initfn(Object *obj)
         /* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */
         ARMCPRegInfo ifar = {
             .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
-            .access = PL1_RW,
+            .access = PL1_RW, .type = ARM_CP_BANKED,
             .fieldoffset = offsetof(CPUARMState, cp15.c6_insn),
             .resetvalue = 0
         };
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index fe3a646..b4500b4 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -84,6 +84,26 @@ typedef uint32_t ARMReadCPFunc(void *opaque, int cp_info,
         type banked_##name[2]; \
     }
 
+/* Whether a co-processor access instruction should use a banked Non-secure
+ * copy of a register instead of active one */
+#define USE_NS_REG(env) ( \
+        unlikely( \
+            ((env)->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON && \
+            ((env)->cp15.c1_scr & 1/*NS*/)))
+/* Get a banked CP15 register in co-processor access instruction handler */
+#define BANKED_CP15_REG_GET(env, regname) \
+    (!USE_NS_REG(env) ? (env)->cp15.regname : \
+     (env)->cp15.banked_##regname[1])
+/* Set a banked CP15 register in co-processor access instruction handler */
+#define BANKED_CP15_REG_SET(env, regname, val) \
+    do { \
+        if (!USE_NS_REG(env)) { \
+            (env)->cp15.regname = (val); \
+        } else { \
+            (env)->cp15.banked_##regname[1] = (val); \
+        } \
+    } while (0)
+
 struct arm_boot_info;
 
 #define NB_MMU_MODES 4
@@ -156,31 +176,31 @@ typedef struct CPUARMState {
     /* System control coprocessor (cp15) */
     struct {
         uint32_t c0_cpuid;
-        uint32_t c0_cssel; /* Cache size selection.  */
-        uint32_t c1_sys; /* System control register.  */
+        BANKED_CP_REG(uint32_t, c0_cssel); /* Cache size selection.  */
+        BANKED_CP_REG(uint32_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.  */
         uint32_t c1_sder; /* Secure debug enable register. */
         uint32_t c1_nsacr; /* Non-secure access control 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 */
-        uint32_t c2_control; /* MMU translation table base control.  */
+        BANKED_CP_REG(uint32_t, c2_base0); /* MMU translation table base 0.  */
+        BANKED_CP_REG(uint32_t, c2_base0_hi); /* MMU translation table base 0, 
high 32 bits */
+        BANKED_CP_REG(uint32_t, c2_base1); /* MMU translation table base 0.  */
+        BANKED_CP_REG(uint32_t, c2_base1_hi); /* MMU translation table base 1, 
high 32 bits */
+        BANKED_CP_REG(uint32_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.  */
         uint32_t c2_insn; /* MPU instruction cachable bits.  */
-        uint32_t c3; /* MMU domain access control register
-                        MPU write buffer control.  */
-        uint32_t c5_insn; /* Fault status registers.  */
-        uint32_t c5_data;
+        BANKED_CP_REG(uint32_t, c3); /* MMU domain access control register
+                                        MPU write buffer control.  */
+        BANKED_CP_REG(uint32_t, c5_insn); /* Fault status registers.  */
+        BANKED_CP_REG(uint32_t, c5_data);
         uint32_t c6_region[8]; /* MPU base/size registers.  */
-        uint32_t c6_insn; /* Fault address registers.  */
-        uint32_t c6_data;
-        uint32_t c7_par;  /* Translation result. */
-        uint32_t c7_par_hi;  /* Translation result, high 32 bits */
+        BANKED_CP_REG(uint32_t, c6_insn); /* Fault address registers.  */
+        BANKED_CP_REG(uint32_t, c6_data);
+        BANKED_CP_REG(uint32_t, c7_par);  /* Translation result. */
+        BANKED_CP_REG(uint32_t, c7_par_hi);  /* Translation result, high 32 
bits */
         uint32_t c9_insn; /* Cache lockdown registers.  */
         uint32_t c9_data;
         uint32_t c9_pmcr; /* performance monitor control register */
@@ -189,12 +209,12 @@ 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 */
-        uint32_t c12_vbar; /* vector base address register */
-        uint32_t c13_fcse; /* FCSE PID.  */
-        uint32_t c13_context; /* Context ID.  */
-        uint32_t c13_tls1; /* User RW Thread register.  */
-        uint32_t c13_tls2; /* User RO Thread register.  */
-        uint32_t c13_tls3; /* Privileged Thread register.  */
+        BANKED_CP_REG(uint32_t, c12_vbar); /* vector base address register */
+        BANKED_CP_REG(uint32_t, c13_fcse); /* FCSE PID.  */
+        BANKED_CP_REG(uint32_t, c13_context); /* Context ID.  */
+        BANKED_CP_REG(uint32_t, c13_tls1); /* User RW Thread register.  */
+        BANKED_CP_REG(uint32_t, c13_tls2); /* User RO Thread register.  */
+        BANKED_CP_REG(uint32_t, c13_tls3); /* Privileged Thread register.  */
         uint32_t c14_cntfrq; /* Counter Frequency register */
         uint32_t c14_cntkctl; /* Timer Control register */
         ARMGenericTimer c14_timer[NUM_GTIMERS];
diff --git a/target-arm/helper.c b/target-arm/helper.c
index c145cfe..9442e08 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -277,33 +277,34 @@ void init_cpreg_list(ARMCPU *cpu)
 
 static int dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
 {
-    env->cp15.c3 = value;
+    BANKED_CP15_REG_SET(env, 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)
 {
-    if (env->cp15.c13_fcse != value) {
+    if (BANKED_CP15_REG_GET(env, c13_fcse) != value) {
         /* Unlike real hardware the qemu TLB uses virtual addresses,
          * not modified virtual addresses, so this causes a TLB flush.
          */
         tlb_flush(env, 1);
-        env->cp15.c13_fcse = value;
+        BANKED_CP15_REG_SET(env, c13_fcse, value);
     }
     return 0;
 }
 static int contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                             uint64_t value)
 {
-    if (env->cp15.c13_context != value && !arm_feature(env, ARM_FEATURE_MPU)) {
+    if (BANKED_CP15_REG_GET(env, c13_context) != value &&
+            !arm_feature(env, ARM_FEATURE_MPU)) {
         /* For VMSA (when not using the LPAE long descriptor page table
          * format) this register includes the ASID, so do a TLB flush.
          * For PMSA it is purely a process ID and no action is needed.
          */
         tlb_flush(env, 1);
     }
-    env->cp15.c13_context = value;
+    BANKED_CP15_REG_SET(env, c13_context, value);
     return 0;
 }
 
@@ -349,13 +350,16 @@ static const ARMCPRegInfo cp_reginfo[] = {
     /* MMU Domain access control / MPU write buffer control */
     { .name = "DACR", .cp = 15,
       .crn = 3, .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c3),
+      .access = PL1_RW, .type = ARM_CP_BANKED,
+      .fieldoffset = offsetof(CPUARMState, cp15.c3),
       .resetvalue = 0, .writefn = dacr_write, .raw_writefn = raw_write, },
     { .name = "FCSEIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse),
+      .access = PL1_RW, .type = ARM_CP_BANKED,
+      .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse),
       .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
     { .name = "CONTEXTIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 
1,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse),
+      .access = PL1_RW, .type = ARM_CP_BANKED,
+      .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse),
       .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, 
},
     /* ??? This covers not just the impdef TLB lockdown registers but also
      * some v7VMSA registers relating to TEX remap, so it is overly broad.
@@ -455,7 +459,8 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
     { .name = "DMB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 5,
       .access = PL0_W, .type = ARM_CP_NOP },
     { .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 2,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c6_insn),
+      .access = PL1_RW, .type = ARM_CP_BANKED,
+      .fieldoffset = offsetof(CPUARMState, cp15.c6_insn),
       .resetvalue = 0, },
     /* Watchpoint Fault Address Register : should actually only be present
      * for 1136, 1176, 11MPCore.
@@ -564,7 +569,7 @@ static int ccsidr_read(CPUARMState *env, const ARMCPRegInfo 
*ri,
                        uint64_t *value)
 {
     ARMCPU *cpu = arm_env_get_cpu(env);
-    *value = cpu->ccsidr[env->cp15.c0_cssel];
+    *value = cpu->ccsidr[BANKED_CP15_REG_GET(env, c0_cssel)];
     return 0;
 }
 
@@ -648,7 +653,8 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
     { .name = "CCSIDR", .cp = 15, .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,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c0_cssel),
+      .access = PL1_RW, .type = ARM_CP_BANKED,
+      .fieldoffset = offsetof(CPUARMState, cp15.c0_cssel),
       .writefn = csselr_write, .resetvalue = 0 },
     /* Auxiliary ID register: this actually has an IMPDEF value but for now
      * just RAZ for all cores:
@@ -702,15 +708,15 @@ static const ARMCPRegInfo t2ee_cp_reginfo[] = {
 
 static const ARMCPRegInfo v6k_cp_reginfo[] = {
     { .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2,
-      .access = PL0_RW,
+      .access = PL0_RW, .type = ARM_CP_BANKED,
       .fieldoffset = offsetof(CPUARMState, cp15.c13_tls1),
       .resetvalue = 0 },
     { .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3,
-      .access = PL0_R|PL1_W,
+      .access = PL0_R|PL1_W, .type = ARM_CP_BANKED,
       .fieldoffset = offsetof(CPUARMState, cp15.c13_tls2),
       .resetvalue = 0 },
     { .name = "TPIDRPRW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 4,
-      .access = PL1_RW,
+      .access = PL1_RW, .type = ARM_CP_BANKED,
       .fieldoffset = offsetof(CPUARMState, cp15.c13_tls3),
       .resetvalue = 0 },
     REGINFO_SENTINEL
@@ -974,11 +980,11 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
 static int par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
 {
     if (arm_feature(env, ARM_FEATURE_LPAE)) {
-        env->cp15.c7_par = value;
+        BANKED_CP15_REG_SET(env, c7_par, value);
     } else if (arm_feature(env, ARM_FEATURE_V7)) {
-        env->cp15.c7_par = value & 0xfffff6ff;
+        BANKED_CP15_REG_SET(env, c7_par, value & 0xfffff6ff);
     } else {
-        env->cp15.c7_par = value & 0xfffff1ff;
+        BANKED_CP15_REG_SET(env, c7_par, value & 0xfffff1ff);
     }
     return 0;
 }
@@ -1027,8 +1033,8 @@ static int ats_write(CPUARMState *env, const ARMCPRegInfo 
*ri, uint64_t value)
              * fault.
              */
         }
-        env->cp15.c7_par = par64;
-        env->cp15.c7_par_hi = par64 >> 32;
+        BANKED_CP15_REG_SET(env, c7_par, par64);
+        BANKED_CP15_REG_SET(env, c7_par_hi, par64 >> 32);
     } else {
         /* ret is a DFSR/IFSR value for the short descriptor
          * translation table format (with WnR always clear).
@@ -1038,16 +1044,17 @@ static int ats_write(CPUARMState *env, const 
ARMCPRegInfo *ri, uint64_t value)
             /* We do not set any attribute bits in the PAR */
             if (page_size == (1 << 24)
                 && arm_feature(env, ARM_FEATURE_V7)) {
-                env->cp15.c7_par = (phys_addr & 0xff000000) | 1 << 1;
+                BANKED_CP15_REG_SET(env, c7_par,
+                        (phys_addr & 0xff000000) | 1 << 1);
             } else {
-                env->cp15.c7_par = phys_addr & 0xfffff000;
+                BANKED_CP15_REG_SET(env, c7_par, phys_addr & 0xfffff000);
             }
         } else {
-            env->cp15.c7_par = ((ret & (10 << 1)) >> 5) |
+            BANKED_CP15_REG_SET(env, c7_par, ((ret & (10 << 1)) >> 5) |
                 ((ret & (12 << 1)) >> 6) |
-                ((ret & 0xf) << 1) | 1;
+                ((ret & 0xf) << 1) | 1);
         }
-        env->cp15.c7_par_hi = 0;
+        BANKED_CP15_REG_SET(env, c7_par_hi, 0);
     }
     return 0;
 }
@@ -1055,7 +1062,7 @@ static int ats_write(CPUARMState *env, const ARMCPRegInfo 
*ri, uint64_t value)
 
 static const ARMCPRegInfo vapa_cp_reginfo[] = {
     { .name = "PAR", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .resetvalue = 0,
+      .access = PL1_RW, .type = ARM_CP_BANKED, .resetvalue = 0,
       .fieldoffset = offsetof(CPUARMState, cp15.c7_par),
       .writefn = par_write },
 #ifndef CONFIG_USER_ONLY
@@ -1145,18 +1152,18 @@ static int arm946_prbs_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 
 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,
+      .access = PL1_RW, .type = ARM_CP_NO_MIGRATE | ARM_CP_BANKED,
       .fieldoffset = offsetof(CPUARMState, cp15.c5_data), .resetvalue = 0,
       .readfn = pmsav5_data_ap_read, .writefn = pmsav5_data_ap_write, },
     { .name = "INSN_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
-      .access = PL1_RW, .type = ARM_CP_NO_MIGRATE,
+      .access = PL1_RW, .type = ARM_CP_NO_MIGRATE | ARM_CP_BANKED,
       .fieldoffset = offsetof(CPUARMState, cp15.c5_insn), .resetvalue = 0,
       .readfn = pmsav5_insn_ap_read, .writefn = pmsav5_insn_ap_write, },
     { .name = "DATA_EXT_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 
2,
-      .access = PL1_RW,
+      .access = PL1_RW, .type = ARM_CP_BANKED,
       .fieldoffset = offsetof(CPUARMState, cp15.c5_data), .resetvalue = 0, },
     { .name = "INSN_EXT_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 
3,
-      .access = PL1_RW,
+      .access = PL1_RW, .type = ARM_CP_BANKED,
       .fieldoffset = offsetof(CPUARMState, cp15.c5_insn), .resetvalue = 0, },
     { .name = "DCACHE_CFG", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW,
@@ -1188,9 +1195,11 @@ static int vmsa_ttbcr_raw_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
      * for long-descriptor tables the TTBCR fields are used differently
      * and the c2_mask and c2_base_mask values are meaningless.
      */
-    env->cp15.c2_control = value;
-    env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> maskshift);
-    env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> maskshift);
+    BANKED_CP15_REG_SET(env, c2_control, value);
+    if (!USE_NS_REG(env)) {
+            env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> maskshift);
+            env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> maskshift);
+    }
     return 0;
 }
 
@@ -1215,23 +1224,24 @@ static void vmsa_ttbcr_reset(CPUARMState *env, const 
ARMCPRegInfo *ri)
 
 static const ARMCPRegInfo vmsa_cp_reginfo[] = {
     { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW,
+      .access = PL1_RW, .type = ARM_CP_BANKED,
       .fieldoffset = offsetof(CPUARMState, cp15.c5_data), .resetvalue = 0, },
     { .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
-      .access = PL1_RW,
+      .access = PL1_RW, .type = ARM_CP_BANKED,
       .fieldoffset = offsetof(CPUARMState, cp15.c5_insn), .resetvalue = 0, },
     { .name = "TTBR0", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW,
+      .access = PL1_RW, .type = ARM_CP_BANKED,
       .fieldoffset = offsetof(CPUARMState, cp15.c2_base0), .resetvalue = 0, },
     { .name = "TTBR1", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1,
-      .access = PL1_RW,
+      .access = PL1_RW, .type = ARM_CP_BANKED,
       .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,
+      .access = PL1_RW, .type = ARM_CP_BANKED, .writefn = vmsa_ttbcr_write,
       .resetfn = vmsa_ttbcr_reset, .raw_writefn = vmsa_ttbcr_raw_write,
       .fieldoffset = offsetof(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),
+      .access = PL1_RW, .type = ARM_CP_BANKED,
+      .fieldoffset = offsetof(CPUARMState, cp15.c6_data),
       .resetvalue = 0, },
     REGINFO_SENTINEL
 };
@@ -1274,7 +1284,8 @@ static int omap_cachemaint_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 
 static const ARMCPRegInfo omap_cp_reginfo[] = {
     { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY,
-      .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = 
ARM_CP_OVERRIDE,
+      .opc1 = CP_ANY, .opc2 = CP_ANY,
+      .access = PL1_RW, .type = ARM_CP_OVERRIDE | ARM_CP_BANKED,
       .fieldoffset = offsetof(CPUARMState, cp15.c5_data), .resetvalue = 0, },
     { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW, .type = ARM_CP_NOP },
@@ -1427,14 +1438,16 @@ static const ARMCPRegInfo mpidr_cp_reginfo[] = {
 
 static int par64_read(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t 
*value)
 {
-    *value = ((uint64_t)env->cp15.c7_par_hi << 32) | env->cp15.c7_par;
+    *value = BANKED_CP15_REG_GET(env, c7_par_hi);
+    *value <<= 32;
+    *value |= BANKED_CP15_REG_GET(env, c7_par);
     return 0;
 }
 
 static int par64_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t 
value)
 {
-    env->cp15.c7_par_hi = value >> 32;
-    env->cp15.c7_par = value;
+    BANKED_CP15_REG_SET(env, c7_par_hi, value >> 32);
+    BANKED_CP15_REG_SET(env, c7_par, value);
     return 0;
 }
 
@@ -1447,15 +1460,17 @@ static void par64_reset(CPUARMState *env, const 
ARMCPRegInfo *ri)
 static int ttbr064_read(CPUARMState *env, const ARMCPRegInfo *ri,
                         uint64_t *value)
 {
-    *value = ((uint64_t)env->cp15.c2_base0_hi << 32) | env->cp15.c2_base0;
+    *value = BANKED_CP15_REG_GET(env, c2_base0_hi);
+    *value <<= 32;
+    *value |= BANKED_CP15_REG_GET(env, c2_base0);
     return 0;
 }
 
 static int ttbr064_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
                              uint64_t value)
 {
-    env->cp15.c2_base0_hi = value >> 32;
-    env->cp15.c2_base0 = value;
+    BANKED_CP15_REG_SET(env, c2_base0_hi, value >> 32);
+    BANKED_CP15_REG_SET(env, c2_base0, value);
     return 0;
 }
 
@@ -1476,15 +1491,17 @@ static void ttbr064_reset(CPUARMState *env, const 
ARMCPRegInfo *ri)
 static int ttbr164_read(CPUARMState *env, const ARMCPRegInfo *ri,
                         uint64_t *value)
 {
-    *value = ((uint64_t)env->cp15.c2_base1_hi << 32) | env->cp15.c2_base1;
+    *value = BANKED_CP15_REG_GET(env, c2_base1_hi);
+    *value <<= 32;
+    *value |= BANKED_CP15_REG_GET(env, c2_base1);
     return 0;
 }
 
 static int ttbr164_write(CPUARMState *env, const ARMCPRegInfo *ri,
                          uint64_t value)
 {
-    env->cp15.c2_base1_hi = value >> 32;
-    env->cp15.c2_base1 = value;
+    BANKED_CP15_REG_SET(env, c2_base1_hi, value >> 32);
+    BANKED_CP15_REG_SET(env, c2_base1, value);
     return 0;
 }
 
@@ -1528,7 +1545,7 @@ static int sctlr_write(CPUARMState *env, const 
ARMCPRegInfo *ri, uint64_t value)
         value = value | 0x00c50078; /* This bits are RAO/WI */
     }
 
-    env->cp15.c1_sys = value;
+    BANKED_CP15_REG_SET(env, 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);
@@ -1557,7 +1574,7 @@ static const ARMCPRegInfo tz_cp_reginfo[] = {
       .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_scr),
       .resetvalue = 0 },
     { .name = "VBAR", .cp = 15, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .writefn = vbar_write,
+      .access = PL1_RW, .type = ARM_CP_BANKED, .writefn = vbar_write,
       .fieldoffset = offsetof(CPUARMState, cp15.c12_vbar),
       .resetvalue = 0 },
     { .name = "SDER", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 1,
@@ -1795,7 +1812,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
     {
         ARMCPRegInfo sctlr = {
             .name = "SCTLR", .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 
0,
-            .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, 
cp15.c1_sys),
+            .access = PL1_RW, .type = ARM_CP_BANKED,
+            .fieldoffset = offsetof(CPUARMState, cp15.c1_sys),
             .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
             .raw_writefn = raw_write,
         };
-- 
1.7.9.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]