[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 11/15] target-arm: Add 64 bit PAR, TTBR0, TTBR1 for
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PATCH 11/15] target-arm: Add 64 bit PAR, TTBR0, TTBR1 for LPAE |
Date: |
Thu, 12 Jul 2012 14:36:52 +0100 |
Under LPAE, the cp15 registers PAR, TTBR0 and TTBR1 are extended
to 64 bits, with a 64 bit (MRRC/MCRR) access path to read the
full width of the register. Add the state fields for the top
half and the 64 bit access path. Actual use of the top half of
the register will come with the addition of the long-descriptor
translation table format support.
For the PAR we also need to correct the masking applied for
32 bit writes (there are no bits reserved if LPAE is implemented)
and clear the high half when doing a 32 bit result VA-to-PA
lookup.
Signed-off-by: Peter Maydell <address@hidden>
---
target-arm/cpu.h | 7 +++-
target-arm/helper.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++-
target-arm/machine.c | 6 ++++
3 files changed, 87 insertions(+), 3 deletions(-)
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 3c5d2be..191895c 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -113,7 +113,9 @@ typedef struct CPUARMState {
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. */
+ 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. */
uint32_t c2_mask; /* MMU translation table base selection mask. */
uint32_t c2_base_mask; /* MMU translation table base 0 mask. */
@@ -127,6 +129,7 @@ typedef struct CPUARMState {
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 */
uint32_t c9_insn; /* Cache lockdown registers. */
uint32_t c9_data;
uint32_t c9_pmcr; /* performance monitor control register */
@@ -638,7 +641,7 @@ static inline CPUARMState *cpu_init(const char *cpu_model)
#define cpu_signal_handler cpu_arm_signal_handler
#define cpu_list arm_cpu_list
-#define CPU_SAVE_VERSION 8
+#define CPU_SAVE_VERSION 9
/* MMU modes definitions */
#define MMU_MODE0_SUFFIX _kernel
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 0cf7b8d..6bb6767 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -491,7 +491,9 @@ 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_V7)) {
+ if (arm_feature(env, ARM_FEATURE_LPAE)) {
+ env->cp15.c7_par = value;
+ } else if (arm_feature(env, ARM_FEATURE_V7)) {
env->cp15.c7_par = value & 0xfffff6ff;
} else {
env->cp15.c7_par = value & 0xfffff1ff;
@@ -528,6 +530,7 @@ static int ats_write(CPUARMState *env, const ARMCPRegInfo
*ri, uint64_t value)
((ret & (12 << 1)) >> 6) |
((ret & 0xf) << 1) | 1;
}
+ env->cp15.c7_par_hi = 0;
return 0;
}
#endif
@@ -871,6 +874,69 @@ static const ARMCPRegInfo mpidr_cp_reginfo[] = {
REGINFO_SENTINEL
};
+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;
+ 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;
+ return 0;
+}
+
+static void par64_reset(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ env->cp15.c7_par_hi = 0;
+ env->cp15.c7_par = 0;
+}
+
+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;
+ return 0;
+}
+
+static int ttbr064_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ env->cp15.c2_base0_hi = value >> 32;
+ env->cp15.c2_base0 = value;
+ /* Writes to the 64 bit format TTBRs may change the ASID */
+ tlb_flush(env, 1);
+ return 0;
+}
+
+static void ttbr064_reset(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ env->cp15.c2_base0_hi = 0;
+ env->cp15.c2_base0 = 0;
+}
+
+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;
+ 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;
+ return 0;
+}
+
+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 tha rather
* broadly specified TLB_LOCKDOWN entry in the generic cp_reginfo.
@@ -886,6 +952,15 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
.access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
{ .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,
+ .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, .resetfn = ttbr064_reset },
+ { .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1,
+ .access = PL1_RW, .type = ARM_CP_64BIT, .readfn = ttbr164_read,
+ .writefn = ttbr164_write, .resetfn = ttbr164_reset },
REGINFO_SENTINEL
};
diff --git a/target-arm/machine.c b/target-arm/machine.c
index 429cbc8..68dca7f 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -27,7 +27,9 @@ void cpu_save(QEMUFile *f, void *opaque)
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_base0_hi);
qemu_put_be32(f, env->cp15.c2_base1);
+ qemu_put_be32(f, env->cp15.c2_base1_hi);
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);
@@ -42,6 +44,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_be32(f, env->cp15.c7_par_hi);
qemu_put_be32(f, env->cp15.c9_insn);
qemu_put_be32(f, env->cp15.c9_data);
qemu_put_be32(f, env->cp15.c9_pmcr);
@@ -144,7 +147,9 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
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_base0_hi = qemu_get_be32(f);
env->cp15.c2_base1 = qemu_get_be32(f);
+ env->cp15.c2_base1_hi = qemu_get_be32(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);
@@ -159,6 +164,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_hi = qemu_get_be32(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.7.1
- [Qemu-devel] [PULL 00/15] target-arm queue, Peter Maydell, 2012/07/12
- [Qemu-devel] [PATCH 14/15] target-arm: Implement TTBCR changes for LPAE, Peter Maydell, 2012/07/12
- [Qemu-devel] [PATCH 04/15] target-arm: Fix TCG temp handling in 64 bit cp writes, Peter Maydell, 2012/07/12
- [Qemu-devel] [PATCH 07/15] target-arm: Implement privileged-execute-never (PXN), Peter Maydell, 2012/07/12
- [Qemu-devel] [PATCH 09/15] target-arm: Add AMAIR0, AMAIR1 LPAE cp15 registers, Peter Maydell, 2012/07/12
- [Qemu-devel] [PATCH 06/15] ARM: Make target_phys_addr_t 64 bits and physaddrs 40 bits, Peter Maydell, 2012/07/12
- [Qemu-devel] [PATCH 10/15] target-arm: Add 64 bit variants of DBGDRAR and DBGDSAR for LPAE, Peter Maydell, 2012/07/12
- [Qemu-devel] [PATCH 11/15] target-arm: Add 64 bit PAR, TTBR0, TTBR1 for LPAE,
Peter Maydell <=
- [Qemu-devel] [PATCH 15/15] target-arm: Add support for long format translation table walks, Peter Maydell, 2012/07/12
- [Qemu-devel] [PATCH 03/15] target-arm: Fix some copy-and-paste errors in cp register names, Peter Maydell, 2012/07/12
- [Qemu-devel] [PATCH 12/15] target-arm: Use target_phys_addr_t in get_phys_addr(), Peter Maydell, 2012/07/12
- [Qemu-devel] [PATCH 01/15] target-arm: Fix CP15 based WFI, Peter Maydell, 2012/07/12
- [Qemu-devel] [PATCH 08/15] target-arm: Extend feature flags to 64 bits, Peter Maydell, 2012/07/12
- [Qemu-devel] [PATCH 02/15] target-arm: Fix typo that meant TTBR1 accesses went to TTBR0, Peter Maydell, 2012/07/12
- [Qemu-devel] [PATCH 13/15] target-arm: Implement long-descriptor PAR format, Peter Maydell, 2012/07/12
- [Qemu-devel] [PATCH 05/15] hw/imx_avic.c: Avoid format error when target_phys_addr_t is 64 bits, Peter Maydell, 2012/07/12
- Re: [Qemu-devel] [PULL 00/15] target-arm queue, Blue Swirl, 2012/07/14