qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH v2 18/23] target-arm: Convert banked coprocessor


From: Greg Bellows
Subject: Re: [Qemu-devel] [PATCH v2 18/23] target-arm: Convert banked coprocessor registers
Date: Wed, 14 May 2014 14:47:18 -0500




On 13 May 2014 11:16, Fabian Aggeler <address@hidden> wrote:
Use new macro A32_BANKED_REG() for registers which are banked in Aarch32
and not mapped an EL3 register in Aarch64.

Using raw_write and raw_read in .readfn/.writefn to be able to use the
same .readfn/writefn for secure and non-secure instance without case
distinction.

Whenever accessing banked registers using A32_BANKED_REG_GET macro or
A32_MAPPED_EL3_REG_GET for registers which we map to EL3 registers.

Signed-off-by: Sergey Fedorov <address@hidden>
Signed-off-by: Fabian Aggeler <address@hidden>
---
 linux-user/main.c       |   2 +-
 target-arm/cpu.h        |  32 ++++++----
 target-arm/helper-a64.c |   3 +-
 target-arm/helper.c     | 155 ++++++++++++++++++++++++++++++++++--------------
 4 files changed, 132 insertions(+), 60 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index c38fecf..809d731 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -566,7 +566,7 @@ do_kernel_trap(CPUARMState *env)
         end_exclusive();
         break;
     case 0xffff0fe0: /* __kernel_get_tls */
-        env->regs[0] = env->cp15.tpidrro_el0;
+        env->regs[0] = A32_BANKED_CURRENT_REG_GET(env, tpidrro_el0);
         break;
     case 0xffff0f60: /* __kernel_cmpxchg64 */
         arm_kernel_cmpxchg64_helper(env);
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 780c1f5..c20c44a 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -179,7 +179,8 @@ typedef struct CPUARMState {
     /* System control coprocessor (cp15) */
     struct {
         uint32_t c0_cpuid;
-        uint64_t c0_cssel; /* Cache size selection.  */
+        A32_BANKED_REG(uint64_t, c0_cssel); /* Cache size selection
+                                               (banked in Aarch32). */
         uint64_t c1_sys_el1; /* System control register (EL1). */
         uint64_t c1_sys_el3; /* System control register (EL3).  */
         uint64_t c1_coproc; /* Coprocessor access register.  */
@@ -187,22 +188,28 @@ typedef struct CPUARMState {
         uint32_t c1_scr; /* secure config register.  */
         uint32_t c1_sder; /* Secure debug enable register. */
         uint32_t c1_nsacr; /* Non-secure access control register. */
-        uint64_t ttbr0_el1; /* MMU translation table base 0. */
-        uint64_t ttbr1_el1; /* MMU translation table base 1. */
-        uint64_t c2_control; /* MMU translation table base control.  */
+        uint64_t ttbr0_el1;/* MMU translation table base 0. */
+        uint64_t ttbr0_el3;
+        uint64_t ttbr1_el1;/* MMU translation table base 1. */
+        uint64_t ttbr1_el3;
+        A32_BANKED_REG(uint64_t, c2_control);/* MMU translation table base
+                                                control. (banked in Aarch32) */
         uint32_t c2_mask; /* MMU translation table base selection mask.  */
         uint32_t c2_base_mask; /* MMU translation table base 0 mask. */

Should either c2_mask and/or c2_base_mask be "banked" given that the correspond to the value set in c2_control which is banked?
 
         uint32_t c2_data; /* MPU data cachable bits.  */
         uint32_t c2_insn; /* MPU instruction cachable bits.  */
-        uint32_t c3; /* MMU domain access control register
+        A32_BANKED_REG(uint32_t, c3); /* MMU domain access control register
                         MPU write buffer control.  */
         uint32_t pmsav5_data_ap; /* PMSAv5 MPU data access permissions */
         uint32_t pmsav5_insn_ap; /* PMSAv5 MPU insn access permissions */
-        uint32_t ifsr_el2; /* Fault status registers.  */
+        A32_BANKED_REG(uint32_t, ifsr_el2); /* Fault status registers.  */
         uint64_t esr_el1;
+        uint64_t esr_el3;
         uint32_t c6_region[8]; /* MPU base/size registers.  */
         uint64_t far_el1; /* Fault address registers.  */
+        uint64_t far_el3;
         uint64_t par_el1;  /* Translation result. */
+        uint64_t par_el3;
         uint32_t c9_insn; /* Cache lockdown registers.  */
         uint32_t c9_data;
         uint32_t c9_pmcr; /* performance monitor control register */
@@ -212,12 +219,13 @@ typedef struct CPUARMState {
         uint32_t c9_pmuserenr; /* perf monitor user enable */
         uint32_t c9_pminten; /* perf monitor interrupt enables */
         uint64_t mair_el1;
-        uint64_t c12_vbar; /* vector base address register */
-        uint32_t c13_fcse; /* FCSE PID.  */
-        uint64_t contextidr_el1; /* Context ID.  */
-        uint64_t tpidr_el0; /* User RW Thread register.  */
-        uint64_t tpidrro_el0; /* User RO Thread register.  */
-        uint64_t tpidr_el1; /* Privileged Thread register.  */
+        uint64_t c12_vbar_el1; /* vector base address register */
+        uint64_t c12_vbar_el3; /* vector base address register */
+        A32_BANKED_REG(uint32_t, c13_fcse); /* FCSE PID.  */
+        A32_BANKED_REG(uint64_t, contextidr_el1); /* Context ID.  */
+        A32_BANKED_REG(uint64_t, tpidr_el0); /* User RW Thread register.  */
+        A32_BANKED_REG(uint64_t, tpidrro_el0); /* User RO Thread register.  */
+        A32_BANKED_REG(uint64_t, tpidr_el1); /* Privileged Thread register.  */
         uint64_t c14_cntfrq; /* Counter Frequency register */
         uint64_t c14_cntkctl; /* Timer Control register */
         ARMGenericTimer c14_timer[NUM_GTIMERS];
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index bf921cc..765ddf5 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -443,7 +443,8 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
 {
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
-    target_ulong addr = env->cp15.c12_vbar;
+    target_ulong addr = (arm_current_pl(env) == 3) ?
+            env->cp15.c12_vbar_el3 : env->cp15.c12_vbar_el1;
     int i;

     if (arm_current_pl(env) == 0) {
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 757e07b..c76a86b 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -397,10 +397,11 @@ static const ARMCPRegInfo cp_reginfo[] = {
       .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 },
     { .name = "FCSEIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse),
-      .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
+      .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write,
+      .type = ARM_CP_BANKED },
     { .name = "CONTEXTIDR", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
-      .access = PL1_RW,
+      .access = PL1_RW, .type = ARM_CP_BANKED_64BIT,
       .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el1),
       .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
     REGINFO_SENTINEL
@@ -413,7 +414,8 @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
     /* MMU Domain access control / MPU write buffer control */
     { .name = "DACR", .cp = 15,
       .crn = 3, .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
-      .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c3),
+      .access = PL1_RW, .type = ARM_CP_BANKED,
+      .fieldoffset = offsetof(CPUARMState, cp15.c3),
       .resetvalue = 0, .writefn = dacr_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.
@@ -519,9 +521,13 @@ 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,
+      .access = PL1_RW, .type = ARM_CP_NONSECURE,
       .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el1),
       .resetvalue = 0, },
+    { .name = "IFAR(S)", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 2,
+      .access = PL3_RW, .type = ARM_CP_SECURE,
+      .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el3),
+      .resetvalue = 0, },
     /* Watchpoint Fault Address Register : should actually only be present
      * for 1136, 1176, 11MPCore.
      */
@@ -686,7 +692,7 @@ static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
 static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     ARMCPU *cpu = arm_env_get_cpu(env);
-    return cpu->ccsidr[env->cp15.c0_cssel];
+    return cpu->ccsidr[A32_BANKED_REG_GET(env, c0_cssel)];
 }

 static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -786,15 +792,25 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
       .access = PL1_RW, .type = ARM_CP_NO_MIGRATE,
       .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
       .resetvalue = 0, .writefn = pmintenclr_write, },
-    { .name = "VBAR", .state = ARM_CP_STATE_BOTH,
+    { .name = "VBAR_EL1", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .writefn = vbar_write,
-      .fieldoffset = offsetof(CPUARMState, cp15.c12_vbar),
+      .access = PL1_RW, .writefn = vbar_write, .type = ARM_CP_NONSECURE,
+      .fieldoffset = offsetof(CPUARMState, cp15.c12_vbar_el1),
+      .resetvalue = 0 },
+    { .name = "VBAR_EL1(S)",
+      .cp = 15, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
+      .access = PL3_RW, .writefn = vbar_write, .type = ARM_CP_SECURE,
+      .fieldoffset = offsetof(CPUARMState, cp15.c12_vbar_el3),
+      .resetvalue = 0 },
+    { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 4, .opc2 = 5,
+      .access = PL3_RW, .writefn = vbar_write,
+      .fieldoffset = offsetof(CPUARMState, cp15.c12_vbar_el3),
       .resetvalue = 0 },
     { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
       .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_MIGRATE },
-    { .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
+    { .name = "CSSELR", .state = ARM_CP_STATE_BOTH, .type = ARM_CP_BANKED_64BIT,
       .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
       .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c0_cssel),
       .writefn = csselr_write, .resetvalue = 0 },
@@ -871,7 +887,7 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
       .access = PL0_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el0), .resetvalue = 0 },
     { .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2,
-      .access = PL0_RW,
+      .access = PL0_RW, .type = ARM_CP_BANKED_64BIT,
       .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidr_el0),
       .resetfn = arm_cp_reset_ignore },
     { .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64,
@@ -879,12 +895,12 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
       .access = PL0_R|PL1_W,
       .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el0), .resetvalue = 0 },
     { .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3,
-      .access = PL0_R|PL1_W,
+      .access = PL0_R|PL1_W, .type = ARM_CP_BANKED_64BIT,
       .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidrro_el0),
       .resetfn = arm_cp_reset_ignore },
     { .name = "TPIDR_EL1", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 0, .opc2 = 4, .crn = 13, .crm = 0,
-      .access = PL1_RW,
+      .access = PL1_RW, .type = ARM_CP_BANKED_64BIT,
       .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el1), .resetvalue = 0 },
     REGINFO_SENTINEL
 };
@@ -1263,7 +1279,7 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
              * fault.
              */
         }
-        env->cp15.par_el1 = par64;
+        A32_MAPPED_EL3_REG_SET(env, par, par64);
     } else {
         /* ret is a DFSR/IFSR value for the short descriptor
          * translation table format (with WnR always clear).
@@ -1273,14 +1289,15 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
             /* We do not set any attribute bits in the PAR */
             if (page_size == (1 << 24)
                 && arm_feature(env, ARM_FEATURE_V7)) {
-                env->cp15.par_el1 = (phys_addr & 0xff000000) | 1 << 1;
+                A32_MAPPED_EL3_REG_SET(env, par,
+                        (phys_addr & 0xff000000) | 1 << 1);
             } else {
-                env->cp15.par_el1 = phys_addr & 0xfffff000;
+                A32_MAPPED_EL3_REG_SET(env, par, phys_addr & 0xfffff000);
             }
         } else {
-            env->cp15.par_el1 = ((ret & (1 << 10)) >> 5) |
+            A32_MAPPED_EL3_REG_SET(env, par, ((ret & (1 << 10)) >> 5) |
                 ((ret & (1 << 12)) >> 6) |
-                ((ret & 0xf) << 1) | 1;
+                ((ret & 0xf) << 1) | 1);
         }
     }
 }
@@ -1288,9 +1305,13 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)

 static const ARMCPRegInfo vapa_cp_reginfo[] = {
     { .name = "PAR", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .resetvalue = 0,
+      .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_NONSECURE,
       .fieldoffset = offsetoflow32(CPUARMState, cp15.par_el1),
       .writefn = par_write },
+    { .name = "PAR(S)", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0, 
+      .access = PL3_RW, .resetvalue = 0, .type = ARM_CP_SECURE,
+      .fieldoffset = offsetoflow32(CPUARMState, cp15.par_el3),
+      .writefn = par_write },
 #ifndef CONFIG_USER_ONLY
     { .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY,
       .access = PL1_W, .accessfn = ats_access,
@@ -1476,23 +1497,39 @@ static void vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,

 static const ARMCPRegInfo vmsa_cp_reginfo[] = {
     { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .type = ARM_CP_NO_MIGRATE,
+      .access = PL1_RW, .type = ARM_CP_NO_MIGRATE | ARM_CP_NONSECURE,
       .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el1),
       .resetfn = arm_cp_reset_ignore, },
+    { .name = "DFSR(S)", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
+      .access = PL3_RW, .type = ARM_CP_SECURE, .resetvalue = 0,
+      .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el3) },
     { .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.ifsr_el2), .resetvalue = 0, },
     { .name = "ESR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.esr_el1), .resetvalue = 0, },
+    { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64, .crn = 5, .crm = 2,
+      .opc0 = 3, .opc1 = 6, .opc2 = 0, .access = PL3_RW, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.esr_el3) },
     { .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),
+      .access = PL1_RW, .type = ARM_CP_NONSECURE,
+      .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el1),
+      .writefn = vmsa_ttbr_write, .resetvalue = 0 },
+    { .name = "TTBR0(S)", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
+      .access = PL3_RW, .type = ARM_CP_SECURE,
+      .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el3),
       .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),
+      .access = PL1_RW, .type = ARM_CP_NONSECURE,
+      .fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el1),
+      .writefn = vmsa_ttbr_write, .resetvalue = 0 },
+    { .name = "TTBR1(S)", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1,
+      .access = PL3_RW, .type = ARM_CP_SECURE,
+      .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el3),
       .writefn = vmsa_ttbr_write, .resetvalue = 0 },
     { .name = "TCR_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
@@ -1500,14 +1537,18 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
       .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,
+      .access = PL1_RW, .type = ARM_CP_NO_MIGRATE | ARM_CP_BANKED_64BIT,
+      .writefn = vmsa_ttbcr_write, .resetfn = arm_cp_reset_ignore,
+      .raw_writefn = vmsa_ttbcr_raw_write,
       .fieldoffset = offsetoflow32(CPUARMState, cp15.c2_control) },
     /* 64-bit FAR; this entry also gives us the AArch32 DFAR */
-    { .name = "FAR_EL1", .state = ARM_CP_STATE_BOTH,
+    { .name = "FAR_EL1", .state = ARM_CP_STATE_BOTH, .type = ARM_CP_NONSECURE,
       .opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el1),
       .resetvalue = 0, },
+    { .name = "DFAR(S)", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
+      .access = PL3_RW,  .type = ARM_CP_SECURE, .resetvalue = 0,
+      .fieldoffset = offsetof(CPUARMState, cp15.far_el3)},
     REGINFO_SENTINEL
 };

@@ -1545,9 +1586,15 @@ static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,

 static const ARMCPRegInfo omap_cp_reginfo[] = {
     { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY,
-      .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_OVERRIDE,
+      .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW,
+      .type = ARM_CP_OVERRIDE | ARM_CP_NONSECURE,
       .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el1),
       .resetvalue = 0, },
+    { .name = "DFSR(S)", .cp = 15, .crn = 5, .crm = CP_ANY,
+      .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL3_RW,
+      .type = ARM_CP_OVERRIDE | ARM_CP_SECURE,
+      .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el3),
+      .resetvalue = 0, },
     { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
       .access = PL1_RW, .type = ARM_CP_NOP },
     { .name = "TICONFIG", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0,
@@ -1730,7 +1777,13 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
     { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0,
       .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
     { .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0,
-      .access = PL1_RW, .type = ARM_CP_64BIT,
+      .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NONSECURE,
+      .fieldoffset = offsetof(CPUARMState, cp15.par_el1), .resetvalue = 0 },
+    { .name = "PAR(S)", .cp = 15, .crm = 7, .opc1 = 0,
+      .access = PL3_RW, .type = ARM_CP_64BIT | ARM_CP_SECURE,
+      .fieldoffset = offsetof(CPUARMState, cp15.par_el3), .resetvalue = 0 },
+    { .name = "PAR_EL1", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .crn = 7, .crm = 4, .opc2 = 0, .access = PL1_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.par_el1), .resetvalue = 0 },
     { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0,
       .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE,
@@ -2131,6 +2184,10 @@ static const ARMCPRegInfo tz_cp_reginfo[] = {
     { .name = "SCR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0,
       .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_scr),
       .resetvalue = 0, },
+    { .name = "SCR_EL3", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .crn = 6, .crm = 1, .opc1 = 0, .opc2 = 0,
+      .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_scr),
+      .resetvalue = 0 },
     { .name = "SDER", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 1,
       .access = PL3_RW, .resetvalue = 0,
       .fieldoffset = offsetof(CPUARMState, cp15.c1_sder) },
@@ -3469,22 +3526,25 @@ void arm_cpu_do_interrupt(CPUState *cs)
         env->exception.fsr = 2;
         /* Fall through to prefetch abort.  */
     case EXCP_PREFETCH_ABORT:
-        env->cp15.ifsr_el2 = env->exception.fsr;
-        env->cp15.far_el1 = deposit64(env->cp15.far_el1, 32, 32,
-                                      env->exception.vaddress);
+        A32_BANKED_CURRENT_REG_SET(env, ifsr_el2, env->exception.fsr);
+        A32_MAPPED_EL3_CURRENT_REG_SET(env, far,
+                deposit64(A32_MAPPED_EL3_CURRENT_REG_GET(env, far), 32, 32,
+                                      env->exception.vaddress));
         qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n",
-                      env->cp15.ifsr_el2, (uint32_t)env->exception.vaddress);
+                      A32_BANKED_CURRENT_REG_GET(env, ifsr_el2),
+                      (uint32_t)env->exception.vaddress);
         new_mode = ARM_CPU_MODE_ABT;
         addr = 0x0c;
         mask = CPSR_A | CPSR_I;
         offset = 4;
         break;
     case EXCP_DATA_ABORT:
-        env->cp15.esr_el1 = env->exception.fsr;
-        env->cp15.far_el1 = deposit64(env->cp15.far_el1, 0, 32,
-                                      env->exception.vaddress);
+        A32_MAPPED_EL3_CURRENT_REG_SET(env, esr, env->exception.fsr);
+        A32_MAPPED_EL3_CURRENT_REG_SET(env, far,
+                deposit64(A32_MAPPED_EL3_CURRENT_REG_GET(env, far), 0, 32,
+                                      env->exception.vaddress));
         qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n",
-                      (uint32_t)env->cp15.esr_el1,
+                      (uint32_t)A32_MAPPED_EL3_CURRENT_REG_GET(env, esr),
                       (uint32_t)env->exception.vaddress);
         new_mode = ARM_CPU_MODE_ABT;
         addr = 0x10;
@@ -3521,7 +3581,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
          * and is never in monitor mode this feature is always active.
          * Note: only bits 31:5 are valid.
          */
-        addr += env->cp15.c12_vbar;
+        addr += A32_MAPPED_EL3_CURRENT_REG_GET(env, c12_vbar);
     }
     switch_mode (env, new_mode);
     env->spsr = cpsr_read(env);
@@ -3601,9 +3661,10 @@ static uint32_t get_level1_table_address(CPUARMState *env, uint32_t address)
     uint32_t table;

     if (address & env->cp15.c2_mask)
-        table = env->cp15.ttbr1_el1 & 0xffffc000;
+        table = A32_MAPPED_EL3_CURRENT_REG_GET(env, ttbr1) & 0xffffc000;
     else
-        table = env->cp15.ttbr0_el1 & env->cp15.c2_base_mask;
+        table =
+           A32_MAPPED_EL3_CURRENT_REG_GET(env, ttbr0) & env->cp15.c2_base_mask;

     table |= (address >> 18) & 0x3ffc;
     return table;
@@ -3737,7 +3798,7 @@ static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type,
         /* Page or Section.  */
         domain = (desc >> 5) & 0x0f;
     }
-    domain_prot = (env->cp15.c3 >> (domain * 2)) & 3;
+    domain_prot = (A32_BANKED_CURRENT_REG_GET(env, c3) >> (domain * 2)) & 3;
     if (domain_prot == 0 || domain_prot == 2) {
         if (type != 1) {
             code = 9; /* Section domain fault.  */
@@ -3863,12 +3924,14 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
      * This is a Non-secure PL0/1 stage 1 translation, so controlled by
      * TTBCR/TTBR0/TTBR1 in accordance with ARM ARM DDI0406C table B-32:
      */
-    uint32_t t0sz = extract32(env->cp15.c2_control, 0, 6);
+    uint32_t t0sz = extract32(
+            A32_BANKED_CURRENT_REG_GET(env, c2_control), 0, 6);
     if (arm_el_is_aa64(env, 1)) {
         t0sz = MIN(t0sz, 39);
         t0sz = MAX(t0sz, 16);
     }
-    uint32_t t1sz = extract32(env->cp15.c2_control, 16, 6);
+    uint32_t t1sz = extract32(
+            A32_BANKED_CURRENT_REG_GET(env, c2_control), 16, 6);
     if (arm_el_is_aa64(env, 1)) {
         t1sz = MIN(t1sz, 39);
         t1sz = MAX(t1sz, 16);
@@ -3899,8 +3962,8 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
      * we will always flush the TLB any time the ASID is changed).
      */
     if (ttbr_select == 0) {
-        ttbr = env->cp15.ttbr0_el1;
-        epd = extract32(env->cp15.c2_control, 7, 1);
+        ttbr = A32_MAPPED_EL3_CURRENT_REG_GET(env, ttbr0);
+        epd = extract32(A32_BANKED_CURRENT_REG_GET(env, c2_control), 7, 1);
         tsz = t0sz;

         tg = extract32(env->cp15.c2_control, 14, 2);
@@ -3911,8 +3974,8 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
             granule_sz = 11;
         }
     } else {
-        ttbr = env->cp15.ttbr1_el1;
-        epd = extract32(env->cp15.c2_control, 23, 1);
+        ttbr = A32_MAPPED_EL3_CURRENT_REG_GET(env, ttbr1);
+        epd = extract32(A32_BANKED_CURRENT_REG_GET(env, c2_control), 23, 1);
         tsz = t1sz;

         tg = extract32(env->cp15.c2_control, 30, 2);
@@ -4132,7 +4195,7 @@ static inline int get_phys_addr(CPUARMState *env, target_ulong address,
 {
     /* Fast Context Switch Extension.  */
     if (address < 0x02000000)
-        address += env->cp15.c13_fcse;
+        address += A32_BANKED_CURRENT_REG_GET(env, c13_fcse);

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




reply via email to

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