Skip to contentSkip to conversation

Add support for 64bit ARM system registers

PATCH In review Alexey Starikovskiy 3 participants 9 messages Mar 15, 2012

lore
Share & tools
lore
#0 lore raw

PATCH v4 1/3 Add support for 64bit ARM system registers

---
 target-arm/cpu.h     |   10 ++++------
 target-arm/helper.c  |   14 +++++++-------
 target-arm/machine.c |   16 ++++++----------
 3 files changed, 17 insertions(+), 23 deletions(-)
target-arm/cpu.h +4 -6
index 26c114b..a0cdde3 100644
@@ -117,11 +117,9 @@ 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_base1; /* MMU translation table base 1.  */
+        uint64_t c2_base0; /* MMU translation table base 0.  */
+        uint64_t c2_base1; /* MMU translation table base 1.  */
         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
@@ -131,7 +129,7 @@ typedef struct CPUARMState {
         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. */
+        uint64_t c7_par;  /* Translation result. */
         uint32_t c9_insn; /* Cache lockdown registers.  */
         uint32_t c9_data;
         uint32_t c9_pmcr; /* performance monitor control register */
@@ -455,7 +453,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
 #define cpu_signal_handler cpu_arm_signal_handler
 #define cpu_list arm_cpu_list
 
-#define CPU_SAVE_VERSION 6
+#define CPU_SAVE_VERSION 7
 
 /* MMU modes definitions */
 #define MMU_MODE0_SUFFIX _kernel
target-arm/helper.c +7 -7
index 8a08db8..2e61861 100644
@@ -325,7 +325,6 @@ void cpu_state_reset(CPUARMState *env)
         }
     }
     env->vfp.xregs[ARM_VFP_FPEXC] = 0;
-    env->cp15.c2_base_mask = 0xffffc000u;
     /* v7 performance monitor control register: same implementor
      * field as main ID register, and we implement no event counters.
      */
@@ -1050,12 +1049,15 @@ static inline int check_ap(CPUARMState *env, int ap, int domain_prot,
 static uint32_t get_level1_table_address(CPUARMState *env, uint32_t address)
 {
     uint32_t table;
+    int t0size = env->cp15.c2_control & 0x7;
+    uint32_t mask = ~(((uint32_t)0xffffffffu) >> t0size);
 
-    if (address & env->cp15.c2_mask)
+    if (address & mask) {
         table = env->cp15.c2_base1 & 0xffffc000;
-    else
-        table = env->cp15.c2_base0 & env->cp15.c2_base_mask;
-
+    } else {
+        mask = ~((uint32_t)0x3fffu >> t0size);
+        table = env->cp15.c2_base0 & mask;
+    }
     table |= (address >> 18) & 0x3ffc;
     return table;
 }
@@ -1531,8 +1533,6 @@ void HELPER(set_cp15)(CPUARMState *env, uint32_t insn, uint32_t val)
 	    case 2:
                 val &= 7;
                 env->cp15.c2_control = val;
-		env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> val);
-                env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> val);
 		break;
 	    default:
 		goto bad_reg;
target-arm/machine.c +6 -10
index f66b8df..8fa738e 100644
@@ -27,11 +27,9 @@ void cpu_save(QEMUFile *f, void *opaque)
     qemu_put_be32(f, env->cp15.c1_coproc);
     qemu_put_be32(f, env->cp15.c1_xscaleauxcr);
     qemu_put_be32(f, env->cp15.c1_scr);
-    qemu_put_be32(f, env->cp15.c2_base0);
-    qemu_put_be32(f, env->cp15.c2_base1);
+    qemu_put_be64(f, env->cp15.c2_base0);
+    qemu_put_be64(f, env->cp15.c2_base1);
     qemu_put_be32(f, env->cp15.c2_control);
-    qemu_put_be32(f, env->cp15.c2_mask);
-    qemu_put_be32(f, env->cp15.c2_base_mask);
     qemu_put_be32(f, env->cp15.c2_data);
     qemu_put_be32(f, env->cp15.c2_insn);
     qemu_put_be32(f, env->cp15.c3);
@@ -42,7 +40,7 @@ void cpu_save(QEMUFile *f, void *opaque)
     }
     qemu_put_be32(f, env->cp15.c6_insn);
     qemu_put_be32(f, env->cp15.c6_data);
-    qemu_put_be32(f, env->cp15.c7_par);
+    qemu_put_be64(f, env->cp15.c7_par);
     qemu_put_be32(f, env->cp15.c9_insn);
     qemu_put_be32(f, env->cp15.c9_data);
     qemu_put_be32(f, env->cp15.c9_pmcr);
@@ -145,11 +143,9 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     env->cp15.c1_coproc = qemu_get_be32(f);
     env->cp15.c1_xscaleauxcr = qemu_get_be32(f);
     env->cp15.c1_scr = qemu_get_be32(f);
-    env->cp15.c2_base0 = qemu_get_be32(f);
-    env->cp15.c2_base1 = qemu_get_be32(f);
+    env->cp15.c2_base0 = qemu_get_be64(f);
+    env->cp15.c2_base1 = qemu_get_be64(f);
     env->cp15.c2_control = qemu_get_be32(f);
-    env->cp15.c2_mask = qemu_get_be32(f);
-    env->cp15.c2_base_mask = qemu_get_be32(f);
     env->cp15.c2_data = qemu_get_be32(f);
     env->cp15.c2_insn = qemu_get_be32(f);
     env->cp15.c3 = qemu_get_be32(f);
@@ -160,7 +156,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     }
     env->cp15.c6_insn = qemu_get_be32(f);
     env->cp15.c6_data = qemu_get_be32(f);
-    env->cp15.c7_par = qemu_get_be32(f);
+    env->cp15.c7_par = qemu_get_be64(f);
     env->cp15.c9_insn = qemu_get_be32(f);
     env->cp15.c9_data = qemu_get_be32(f);
     env->cp15.c9_pmcr = qemu_get_be32(f);
#1 lore raw

PATCH v4 2/3 Support for MRCC and MCRR instructions

---
 target-arm/helper.c    |   28 ++++++++++++++++++++++++++++
 target-arm/helper.h    |    2 ++
 target-arm/translate.c |   47 +++++++++++++++++++++++++++++------------------
 3 files changed, 59 insertions(+), 18 deletions(-)
target-arm/helper.c +28 -0
index 2e61861..2517498 100644
@@ -670,6 +670,16 @@ uint32_t HELPER(get_cp15)(CPUARMState *env, uint32_t insn)
     cpu_abort(env, "cp15 insn %08x\n", insn);
 }
 
+void HELPER(set_cp15_64)(CPUState * env, uint32_t insn, uint64_t val)
+{
+    cpu_abort(env, "cp15 insn %08x\n", insn);
+}
+
+uint64_t HELPER(get_cp15_64)(CPUState * env, uint32_t insn)
+{
+    cpu_abort(env, "cp15 insn %08x\n", insn);
+}
+
 /* These should probably raise undefined insn exceptions.  */
 void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val)
 {
@@ -2261,6 +2271,24 @@ bad_reg:
     return 0;
 }
 
+void HELPER(set_cp15_64)(CPUState *env, uint32_t insn, uint64_t val)
+{
+    int crm = insn & 0xf;
+    int opc1 = (insn >> 4) & 0xf;
+    cpu_abort(env, "Unimplemented cp15 register 64bit write (c%d[%d])\n",
+              crm, opc1);
+}
+
+uint64_t HELPER(get_cp15_64)(CPUState *env, uint32_t insn)
+{
+    /* Used for block cache operations, so just return 0 */
+#if 0
+    cpu_abort(env, "Unimplemented cp15 register 64bit read (c%d[%d])\n",
+              crm, opc1);
+#endif
+    return 0;
+}
+
 void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val)
 {
     if ((env->uncached_cpsr & CPSR_M) == mode) {
target-arm/helper.h +2 -0
index 16dd5fc..bc8151c 100644
@@ -60,7 +60,9 @@ DEF_HELPER_3(v7m_msr, void, env, i32, i32)
 DEF_HELPER_2(v7m_mrs, i32, env, i32)
 
 DEF_HELPER_3(set_cp15, void, env, i32, i32)
+DEF_HELPER_3(set_cp15_64, void, env, i32, i64)
 DEF_HELPER_2(get_cp15, i32, env, i32)
+DEF_HELPER_2(get_cp15_64, i64, env, i32)
 
 DEF_HELPER_3(set_cp, void, env, i32, i32)
 DEF_HELPER_2(get_cp, i32, env, i32)
target-arm/translate.c +29 -18

62 lines not on this page · raw message

#2 lore raw

PATCH v4 3/3 Minimal ARM LPAE support.

In reply to Alexey Starikovskiy

Sufficient to boot Linux kernel on vexpress-a15

Missing:
* Extends the DBGDRAR and DBGDSAR to 64 bits, to hold PAs of up to 40 bits.
* Defines two Memory Attribute Indirection Registers, MAIRn, to replace PRRR and NMRR when using the Long-descriptor translation table format.
* Provides two IMPLEMENTATION DEFINED Auxiliary Memory Attribute Indirection Registers 0 AMAIRn.

Does not change behaviour of Short-descriptor format (AKA _v6)

---
 target-arm/cpu.h    |    1 
 target-arm/helper.c |  223 ++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 211 insertions(+), 13 deletions(-)
target-arm/cpu.h +1 -0
index a0cdde3..93544bf 100644
@@ -381,6 +381,7 @@ enum arm_features {
     ARM_FEATURE_ARM_DIV, /* divide supported in ARM encoding */
     ARM_FEATURE_VFP4, /* VFPv4 (implies that NEON is v2) */
     ARM_FEATURE_GENERIC_TIMER,
+    ARM_FEATURE_LPAE, /* Large Physical Address Extension */
 };
 
 static inline int arm_feature(CPUARMState *env, int feature)
target-arm/helper.c +210 -13

305 lines not on this page · raw message

#3 lore raw

Re: [Qemu-devel] [PATCH v4 3/3] Minimal ARM LPAE support.

Quoted 10 lines · Alexey Starikovskiy

Sufficient to boot Linux kernel on vexpress-a15

Missing:
* Extends the DBGDRAR and DBGDSAR to 64 bits, to hold PAs of up to 40 bits.
* Defines two Memory Attribute Indirection Registers, MAIRn, to replace PRRR and NMRR when using the Long-descriptor translation table format.
* Provides two IMPLEMENTATION DEFINED Auxiliary Memory Attribute Indirection Registers 0 AMAIRn.

Please add code that detects the use of unimplemented features and aborts (or better, implement the missing features). This way when Linux (or another guest) starts to use these features, we don't get silent breakage.

Signature · 1 line
error compiling committee.c: too many arguments to function
#4 lore raw

Re: [Qemu-devel] [PATCH v4 3/3] Minimal ARM LPAE support.

Quoted 2 lines · Avi Kivity

Please add code that detects the use of unimplemented features and aborts

I'm not a great fan of letting the guest cause QEMU to abort...

-- PMM

#5 lore raw

Re: [Qemu-devel] [PATCH v4 3/3] Minimal ARM LPAE support.

Quoted 5 lines · Peter Maydell
Quoted 2 lines · Avi Kivity

Please add code that detects the use of unimplemented features and aborts

I'm not a great fan of letting the guest cause QEMU to abort...

Why not? It (the guest) is going to malfunction anyway.

Signature · 1 line
error compiling committee.c: too many arguments to function
#6 lore raw

Re: [Qemu-devel] [PATCH v4 3/3] Minimal ARM LPAE support.

Quoted 8 lines · Avi Kivity
Quoted 5 lines · Peter Maydell
Quoted 2 lines · Avi Kivity

Please add code that detects the use of unimplemented features and aborts

I'm not a great fan of letting the guest cause QEMU to abort...

Why not?  It (the guest) is going to malfunction anyway.

It would be cleaner to cause the guest to take an exception IMHO. (This is typically what ought to happen anyway if the guest accesses an unimplemented cp15 register, although our current mess has a habit of underdecoding these things.)

-- PMM

#7 lore raw

Re: [Qemu-devel] [PATCH v4 3/3] Minimal ARM LPAE support.

Quoted 6 lines · Peter Maydell
Quoted 5 lines · Avi Kivity
Quoted 4 lines · Peter Maydell
Quoted 2 lines · Avi Kivity

Please add code that detects the use of unimplemented features and aborts

Quoted 8 lines
Quoted 3 lines
Quoted 1 line

I'm not a great fan of letting the guest cause QEMU to abort...

Why not? It (the guest) is going to malfunction anyway.

It would be cleaner to cause the guest to take an exception IMHO. (This is typically what ought to happen anyway if the guest accesses an unimplemented cp15 register, although our current mess has a habit of underdecoding these things.)

At the very least, print something out so it's clear that qemu may be at fault, not the guest. This is what kvm does in such cases (which we discourage, but still exist).

Signature · 1 line
error compiling committee.c: too many arguments to function
#8 lore raw

Re: [Qemu-devel] [PATCH v4 3/3] Minimal ARM LPAE support.

Quoted 9 lines · Avi Kivity
Quoted 4 lines · Peter Maydell

It would be cleaner to cause the guest to take an exception IMHO. (This is typically what ought to happen anyway if the guest accesses an unimplemented cp15 register, although our current mess has a habit of underdecoding these things.)

At the very least, print something out so it's clear that qemu may be at fault, not the guest.  This is what kvm does in such cases (which we discourage, but still exist).

We really need better logging support to do this properly, so you can enable or disable it with some sensible granularity. (=> I agree in principle but I don't think we have the facilities and with what we have at the moment I prefer silence.)

-- PMM