[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
- Re: [Qemu-devel] [RFC PATCH 18/21] target-arm: switch banked CP registers, (continued)
- Re: [Qemu-devel] [RFC PATCH 18/21] target-arm: switch banked CP registers, Peter Crosthwaite, 2013/12/21
- Re: [Qemu-devel] [RFC PATCH 18/21] target-arm: switch banked CP registers, Peter Maydell, 2013/12/22
- Re: [Qemu-devel] [RFC PATCH 18/21] target-arm: switch banked CP registers, Fedorov Sergey, 2013/12/23
- Re: [Qemu-devel] [RFC PATCH 18/21] target-arm: switch banked CP registers, Fedorov Sergey, 2013/12/23
- Re: [Qemu-devel] [RFC PATCH 18/21] target-arm: switch banked CP registers, Peter Maydell, 2013/12/23
[Qemu-devel] [RFC PATCH 15/21] target-arm: add banked coprocessor register type, Sergey Fedorov, 2013/12/03
[Qemu-devel] [RFC PATCH 16/21] target-arm: convert appropriate coprocessor registers to banked type,
Sergey Fedorov <=
[Qemu-devel] [RFC PATCH 13/21] target-arm: add SDER definition, Sergey Fedorov, 2013/12/03
[Qemu-devel] [RFC PATCH 02/21] target-arm: move SCR & VBAR into TrustZone register list, Sergey Fedorov, 2013/12/03
[Qemu-devel] [RFC PATCH 06/21] target-arm: add arm_is_secure() helper, Sergey Fedorov, 2013/12/03
[Qemu-devel] [RFC PATCH 20/21] target-arm: implement SMC instruction, Sergey Fedorov, 2013/12/03
[Qemu-devel] [RFC PATCH 19/21] target-arm: add MVBAR support, Sergey Fedorov, 2013/12/03
[Qemu-devel] [RFC PATCH 21/21] target-arm: implement IRQ/FIQ routing to Monitor mode, Sergey Fedorov, 2013/12/03