summaryrefslogtreecommitdiffstats
path: root/target-arm/helper.c
diff options
context:
space:
mode:
authorPeter Maydell2014-04-15 20:18:49 +0200
committerPeter Maydell2014-04-17 22:34:06 +0200
commitf318cec6adcb73c688d68b0874686a30c0f34a2e (patch)
treefa722ad17c8c35c4fae6391bbd88f007c25e2b9b /target-arm/helper.c
parenttarget-arm: Implement Cortex-A57 implementation-defined system registers (diff)
downloadqemu-f318cec6adcb73c688d68b0874686a30c0f34a2e.tar.gz
qemu-f318cec6adcb73c688d68b0874686a30c0f34a2e.tar.xz
qemu-f318cec6adcb73c688d68b0874686a30c0f34a2e.zip
target-arm: Implement CBAR for Cortex-A57
The Cortex-A57, like most of the other ARM cores, has a CBAR register which defines the base address of the per-CPU peripherals. However it has a 64-bit view as well as a 32-bit view; expand the QOM reset-cbar property from UINT32 to UINT64 so this can be specified, and implement the 32-bit and 64-bit views of a 64-bit CBAR. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Diffstat (limited to 'target-arm/helper.c')
-rw-r--r--target-arm/helper.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 2bcd400ff4..43c1b4f01d 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2464,12 +2464,39 @@ void register_cp_regs_for_features(ARMCPU *cpu)
}
if (arm_feature(env, ARM_FEATURE_CBAR)) {
- ARMCPRegInfo cbar = {
- .name = "CBAR", .cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0,
- .access = PL1_R|PL3_W, .resetvalue = cpu->reset_cbar,
- .fieldoffset = offsetof(CPUARMState, cp15.c15_config_base_address)
- };
- define_one_arm_cp_reg(cpu, &cbar);
+ if (arm_feature(env, ARM_FEATURE_AARCH64)) {
+ /* 32 bit view is [31:18] 0...0 [43:32]. */
+ uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18)
+ | extract64(cpu->reset_cbar, 32, 12);
+ ARMCPRegInfo cbar_reginfo[] = {
+ { .name = "CBAR",
+ .type = ARM_CP_CONST,
+ .cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0,
+ .access = PL1_R, .resetvalue = cpu->reset_cbar },
+ { .name = "CBAR_EL1", .state = ARM_CP_STATE_AA64,
+ .type = ARM_CP_CONST,
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 0,
+ .access = PL1_R, .resetvalue = cbar32 },
+ REGINFO_SENTINEL
+ };
+ /* We don't implement a r/w 64 bit CBAR currently */
+ assert(arm_feature(env, ARM_FEATURE_CBAR_RO));
+ define_arm_cp_regs(cpu, cbar_reginfo);
+ } else {
+ ARMCPRegInfo cbar = {
+ .name = "CBAR",
+ .cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0,
+ .access = PL1_R|PL3_W, .resetvalue = cpu->reset_cbar,
+ .fieldoffset = offsetof(CPUARMState,
+ cp15.c15_config_base_address)
+ };
+ if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {
+ cbar.access = PL1_R;
+ cbar.fieldoffset = 0;
+ cbar.type = ARM_CP_CONST;
+ }
+ define_one_arm_cp_reg(cpu, &cbar);
+ }
}
/* Generic registers whose values depend on the implementation */