diff options
author | Sergey Fedorov <serge.fdrv@gmail.com> | 2015-06-19 14:17:44 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-06-19 14:17:44 +0100 |
commit | b061a82b8afcc45ce09d770d9c0acdf429401054 (patch) | |
tree | b1e1802ada51ed4c87c8676c154ef69136359f51 /target-arm/helper.c | |
parent | decf4f807b4498ca35a87e9de82bc9a4e64cc29a (diff) | |
download | qemu-b061a82b8afcc45ce09d770d9c0acdf429401054.zip |
target-arm: Do not reset sysregs marked as ALIAS
cp_reg_reset() is called from g_hash_table_foreach() which does not
define a specific ordering of the hash table iteration. Thus doing reset
for registers marked as ALIAS would give an ambiguous result when
resetvalue is different for original and alias registers. Exit
cp_reg_reset() early when passed an alias register. Then clean up alias
register definitions from needless resetvalue and resetfn.
In particular, this fixes a bug in the handling of the PMCR register,
which had different resetvalues for its 32 and 64-bit views.
Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Message-id: 1434554713-10220-1-git-send-email-serge.fdrv@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-arm/helper.c')
-rw-r--r-- | target-arm/helper.c | 28 |
1 files changed, 9 insertions, 19 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c index 00509b1382..fbf20b619e 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -984,7 +984,7 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { { .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 2, .access = PL1_RW, .type = ARM_CP_ALIAS, .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), - .resetvalue = 0, .writefn = pmintenclr_write, }, + .writefn = pmintenclr_write, }, { .name = "VBAR", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0, .access = PL1_RW, .writefn = vbar_write, @@ -1323,7 +1323,6 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = { .type = ARM_CP_ALIAS, .access = PL1_RW | PL0_R, .accessfn = gt_cntfrq_access, .fieldoffset = offsetoflow32(CPUARMState, cp15.c14_cntfrq), - .resetfn = arm_cp_reset_ignore, }, { .name = "CNTFRQ_EL0", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0, @@ -1344,7 +1343,6 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = { .accessfn = gt_ptimer_access, .fieldoffset = offsetoflow32(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl), - .resetfn = arm_cp_reset_ignore, .writefn = gt_ctl_write, .raw_writefn = raw_write, }, { .name = "CNTP_CTL_EL0", .state = ARM_CP_STATE_AA64, @@ -1360,7 +1358,6 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = { .accessfn = gt_vtimer_access, .fieldoffset = offsetoflow32(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl), - .resetfn = arm_cp_reset_ignore, .writefn = gt_ctl_write, .raw_writefn = raw_write, }, { .name = "CNTV_CTL_EL0", .state = ARM_CP_STATE_AA64, @@ -1422,7 +1419,7 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = { .access = PL1_RW | PL0_R, .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS, .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval), - .accessfn = gt_ptimer_access, .resetfn = arm_cp_reset_ignore, + .accessfn = gt_ptimer_access, .writefn = gt_cval_write, .raw_writefn = raw_write, }, { .name = "CNTP_CVAL_EL0", .state = ARM_CP_STATE_AA64, @@ -1437,7 +1434,7 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = { .access = PL1_RW | PL0_R, .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS, .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval), - .accessfn = gt_vtimer_access, .resetfn = arm_cp_reset_ignore, + .accessfn = gt_vtimer_access, .writefn = gt_cval_write, .raw_writefn = raw_write, }, { .name = "CNTV_CVAL_EL0", .state = ARM_CP_STATE_AA64, @@ -1714,12 +1711,10 @@ 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_ALIAS, .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_data_ap), - .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_ALIAS, .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_insn_ap), - .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, @@ -1851,8 +1846,7 @@ static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = { { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0, .access = PL1_RW, .type = ARM_CP_ALIAS, .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dfsr_s), - offsetoflow32(CPUARMState, cp15.dfsr_ns) }, - .resetfn = arm_cp_reset_ignore, }, + offsetoflow32(CPUARMState, cp15.dfsr_ns) }, }, { .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1, .access = PL1_RW, .resetvalue = 0, .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.ifsr_s), @@ -1890,7 +1884,7 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = { .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[1]) }, { .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2, .access = PL1_RW, .type = ARM_CP_ALIAS, .writefn = vmsa_ttbcr_write, - .resetfn = arm_cp_reset_ignore, .raw_writefn = vmsa_ttbcr_raw_write, + .raw_writefn = vmsa_ttbcr_raw_write, .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tcr_el[3]), offsetoflow32(CPUARMState, cp15.tcr_el[1])} }, REGINFO_SENTINEL @@ -2109,12 +2103,12 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = { .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS, .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s), offsetof(CPUARMState, cp15.ttbr0_ns) }, - .writefn = vmsa_ttbr_write, .resetfn = arm_cp_reset_ignore }, + .writefn = vmsa_ttbr_write, }, { .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1, .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS, .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s), offsetof(CPUARMState, cp15.ttbr1_ns) }, - .writefn = vmsa_ttbr_write, .resetfn = arm_cp_reset_ignore }, + .writefn = vmsa_ttbr_write, }, REGINFO_SENTINEL }; @@ -2641,7 +2635,6 @@ static const ARMCPRegInfo el2_cp_reginfo[] = { .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) }, { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2, .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS, - .resetvalue = 0, .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) }, { .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0, @@ -2666,7 +2659,7 @@ static const ARMCPRegInfo el3_cp_reginfo[] = { { .name = "SCR", .type = ARM_CP_ALIAS, .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0, .access = PL3_RW, .fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3), - .resetfn = arm_cp_reset_ignore, .writefn = scr_write }, + .writefn = scr_write }, { .name = "SDER32_EL3", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 1, .access = PL3_RW, .resetvalue = 0, @@ -2761,8 +2754,7 @@ static const ARMCPRegInfo debug_cp_reginfo[] = { .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0, .type = ARM_CP_ALIAS, .access = PL1_R, - .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), - .resetfn = arm_cp_reset_ignore }, + .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), }, /* We define a dummy WI OSLAR_EL1, because Linux writes to it. */ { .name = "OSLAR_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4, @@ -3721,14 +3713,12 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r, if ((r->state == ARM_CP_STATE_BOTH && ns) || (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) { r2->type |= ARM_CP_ALIAS; - r2->resetfn = arm_cp_reset_ignore; } } else if ((secstate != r->secure) && !ns) { /* The register is not banked so we only want to allow migration of * the non-secure instance. */ r2->type |= ARM_CP_ALIAS; - r2->resetfn = arm_cp_reset_ignore; } if (r->state == ARM_CP_STATE_BOTH) { |