From af903caed9fc62cc60a589da75e61ea8008c8265 Mon Sep 17 00:00:00 2001 From: Aaron Lindsay Date: Wed, 3 Feb 2021 11:13:40 -0500 Subject: target/arm: Don't migrate CPUARMState.features As feature flags are added or removed, the meanings of bits in the `features` field can change between QEMU versions, causing migration failures. Additionally, migrating the field is not useful because it is a constant function of the CPU being used. Fixes: LP:1914696 Signed-off-by: Aaron Lindsay Suggested-by: Peter Maydell Reviewed-by: Andrew Jones Tested-by: Andrew Jones Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- target/arm/machine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/arm/machine.c b/target/arm/machine.c index 581852bc53..6ad1d306b1 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -810,7 +810,7 @@ const VMStateDescription vmstate_arm_cpu = { VMSTATE_UINT64(env.exclusive_addr, ARMCPU), VMSTATE_UINT64(env.exclusive_val, ARMCPU), VMSTATE_UINT64(env.exclusive_high, ARMCPU), - VMSTATE_UINT64(env.features, ARMCPU), + VMSTATE_UNUSED(sizeof(uint64_t)), VMSTATE_UINT32(env.exception.syndrome, ARMCPU), VMSTATE_UINT32(env.exception.fsr, ARMCPU), VMSTATE_UINT64(env.exception.vaddress, ARMCPU), -- cgit v1.2.3-55-g7522 From 10d0ef3e6cfe228df4b2d3e27325f1b0e2b71fd5 Mon Sep 17 00:00:00 2001 From: Mike Nawrocki Date: Wed, 3 Feb 2021 11:55:52 -0500 Subject: target/arm: Fix SCR RES1 handling The FW and AW bits of SCR_EL3 are RES1 only in some contexts. Force them to 1 only when there is no support for AArch32 at EL1 or above. The reset value will be 0x30 only if the CPU is AArch64-only; if there is support for AArch32 at EL1 or above, it will be reset to 0. Also adds helper function isar_feature_aa64_aa32_el1 to check if AArch32 is supported at EL1 or above. Signed-off-by: Mike Nawrocki Reviewed-by: Richard Henderson Message-id: 20210203165552.16306-2-michael.nawrocki@gtri.gatech.edu Signed-off-by: Peter Maydell --- target/arm/cpu.h | 5 +++++ target/arm/helper.c | 16 ++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index d080239863..39633f73f3 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -4033,6 +4033,11 @@ static inline bool isar_feature_aa64_aa32(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL0) >= 2; } +static inline bool isar_feature_aa64_aa32_el1(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL1) >= 2; +} + static inline bool isar_feature_aa64_sve(const ARMISARegisters *id) { return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0; diff --git a/target/arm/helper.c b/target/arm/helper.c index 1a64bd748c..51330a0c48 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -2024,7 +2024,10 @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) ARMCPU *cpu = env_archcpu(env); if (ri->state == ARM_CP_STATE_AA64) { - value |= SCR_FW | SCR_AW; /* these two bits are RES1. */ + if (arm_feature(env, ARM_FEATURE_AARCH64) && + !cpu_isar_feature(aa64_aa32_el1, cpu)) { + value |= SCR_FW | SCR_AW; /* these two bits are RES1. */ + } valid_mask &= ~SCR_NET; if (cpu_isar_feature(aa64_lor, cpu)) { @@ -2063,6 +2066,15 @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) raw_write(env, ri, value); } +static void scr_reset(CPUARMState *env, const ARMCPRegInfo *ri) +{ + /* + * scr_write will set the RES1 bits on an AArch64-only CPU. + * The reset value will be 0x30 on an AArch64-only CPU and 0 otherwise. + */ + scr_write(env, ri, 0); +} + static CPAccessResult access_aa64_tid2(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) @@ -5785,7 +5797,7 @@ static const ARMCPRegInfo el3_cp_reginfo[] = { { .name = "SCR_EL3", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0, .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3), - .resetvalue = 0, .writefn = scr_write }, + .resetfn = scr_reset, .writefn = scr_write }, { .name = "SCR", .type = ARM_CP_ALIAS | ARM_CP_NEWEL, .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0, .access = PL1_RW, .accessfn = access_trap_aa32s_el1, -- cgit v1.2.3-55-g7522 From 377a3ba25c984303029588e9032002235f157d34 Mon Sep 17 00:00:00 2001 From: Hao Wu Date: Thu, 28 Jan 2021 16:58:40 -0800 Subject: hw/arm: Remove GPIO from unimplemented NPCM7XX NPCM7XX GPIO devices have been implemented in hw/gpio/npcm7xx-gpio.c. So we removed them from the unimplemented devices list. Reviewed-by: Doug Evans Reviewed-by: Tyrong Ting Signed-off-by: Hao Wu Message-id: 20210129005845.416272-2-wuhaotsh@google.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/npcm7xx.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c index 72040d4079..d1fe9bd1df 100644 --- a/hw/arm/npcm7xx.c +++ b/hw/arm/npcm7xx.c @@ -576,14 +576,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp) create_unimplemented_device("npcm7xx.pcierc", 0xe1000000, 64 * KiB); create_unimplemented_device("npcm7xx.kcs", 0xf0007000, 4 * KiB); create_unimplemented_device("npcm7xx.gfxi", 0xf000e000, 4 * KiB); - create_unimplemented_device("npcm7xx.gpio[0]", 0xf0010000, 4 * KiB); - create_unimplemented_device("npcm7xx.gpio[1]", 0xf0011000, 4 * KiB); - create_unimplemented_device("npcm7xx.gpio[2]", 0xf0012000, 4 * KiB); - create_unimplemented_device("npcm7xx.gpio[3]", 0xf0013000, 4 * KiB); - create_unimplemented_device("npcm7xx.gpio[4]", 0xf0014000, 4 * KiB); - create_unimplemented_device("npcm7xx.gpio[5]", 0xf0015000, 4 * KiB); - create_unimplemented_device("npcm7xx.gpio[6]", 0xf0016000, 4 * KiB); - create_unimplemented_device("npcm7xx.gpio[7]", 0xf0017000, 4 * KiB); create_unimplemented_device("npcm7xx.smbus[0]", 0xf0080000, 4 * KiB); create_unimplemented_device("npcm7xx.smbus[1]", 0xf0081000, 4 * KiB); create_unimplemented_device("npcm7xx.smbus[2]", 0xf0082000, 4 * KiB); -- cgit v1.2.3-55-g7522 From dc8b18534ea1dcc90d80ad9a61a3b0aa7eb312fb Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Sun, 7 Feb 2021 23:56:57 -0700 Subject: target/arm: Add support for FEAT_DIT, Data Independent Timing Add support for FEAT_DIT. DIT (Data Independent Timing) is a required feature for ARMv8.4. Since virtual machine execution is largely nondeterministic and TCG is outside of the security domain, it's implemented as a NOP. Signed-off-by: Rebecca Cran Reviewed-by: Richard Henderson Message-id: 20210208065700.19454-2-rebecca@nuviainc.com Signed-off-by: Peter Maydell --- target/arm/cpu.h | 12 ++++++++++++ target/arm/helper.c | 22 ++++++++++++++++++++++ target/arm/internals.h | 6 ++++++ target/arm/translate-a64.c | 12 ++++++++++++ 4 files changed, 52 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 39633f73f3..f240275407 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1243,6 +1243,7 @@ void pmu_init(ARMCPU *cpu); #define CPSR_IT_2_7 (0xfc00U) #define CPSR_GE (0xfU << 16) #define CPSR_IL (1U << 20) +#define CPSR_DIT (1U << 21) #define CPSR_PAN (1U << 22) #define CPSR_J (1U << 24) #define CPSR_IT_0_1 (3U << 25) @@ -1310,6 +1311,7 @@ void pmu_init(ARMCPU *cpu); #define PSTATE_SS (1U << 21) #define PSTATE_PAN (1U << 22) #define PSTATE_UAO (1U << 23) +#define PSTATE_DIT (1U << 24) #define PSTATE_TCO (1U << 25) #define PSTATE_V (1U << 28) #define PSTATE_C (1U << 29) @@ -3876,6 +3878,11 @@ static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id) return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0; } +static inline bool isar_feature_aa32_dit(const ARMISARegisters *id) +{ + return FIELD_EX32(id->id_pfr0, ID_PFR0, DIT) != 0; +} + /* * 64-bit feature tests via id registers. */ @@ -4125,6 +4132,11 @@ static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0; } +static inline bool isar_feature_aa64_dit(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0; +} + /* * Feature tests for "does this exist in either 32-bit or 64-bit?" */ diff --git a/target/arm/helper.c b/target/arm/helper.c index 51330a0c48..cf8e80419d 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -4431,6 +4431,24 @@ static const ARMCPRegInfo uao_reginfo = { .readfn = aa64_uao_read, .writefn = aa64_uao_write }; +static uint64_t aa64_dit_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return env->pstate & PSTATE_DIT; +} + +static void aa64_dit_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->pstate = (env->pstate & ~PSTATE_DIT) | (value & PSTATE_DIT); +} + +static const ARMCPRegInfo dit_reginfo = { + .name = "DIT", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 5, + .type = ARM_CP_NO_RAW, .access = PL0_RW, + .readfn = aa64_dit_read, .writefn = aa64_dit_write +}; + static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) @@ -8224,6 +8242,10 @@ void register_cp_regs_for_features(ARMCPU *cpu) define_one_arm_cp_reg(cpu, &uao_reginfo); } + if (cpu_isar_feature(aa64_dit, cpu)) { + define_one_arm_cp_reg(cpu, &dit_reginfo); + } + if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) { define_arm_cp_regs(cpu, vhe_reginfo); } diff --git a/target/arm/internals.h b/target/arm/internals.h index 448982dd2f..b251fe4450 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1228,6 +1228,9 @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features, if (isar_feature_aa32_pan(id)) { valid |= CPSR_PAN; } + if (isar_feature_aa32_dit(id)) { + valid |= CPSR_DIT; + } return valid; } @@ -1246,6 +1249,9 @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id) if (isar_feature_aa64_uao(id)) { valid |= PSTATE_UAO; } + if (isar_feature_aa64_dit(id)) { + valid |= PSTATE_DIT; + } if (isar_feature_aa64_mte(id)) { valid |= PSTATE_TCO; } diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index ffc060e5d7..1c4b8d02f3 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -1700,6 +1700,18 @@ static void handle_msr_i(DisasContext *s, uint32_t insn, tcg_temp_free_i32(t1); break; + case 0x1a: /* DIT */ + if (!dc_isar_feature(aa64_dit, s)) { + goto do_unallocated; + } + if (crm & 1) { + set_pstate_bits(PSTATE_DIT); + } else { + clear_pstate_bits(PSTATE_DIT); + } + /* There's no need to rebuild hflags because DIT is a nop */ + break; + case 0x1e: /* DAIFSet */ t1 = tcg_const_i32(crm); gen_helper_msr_i_daifset(cpu_env, t1); -- cgit v1.2.3-55-g7522 From f944a854ce4007000accf7c191b5b52916947198 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Sun, 7 Feb 2021 23:56:58 -0700 Subject: target/arm: Support AA32 DIT by moving PSTATE_SS from cpsr into env->pstate cpsr has been treated as being the same as spsr, but it isn't. Since PSTATE_SS isn't in cpsr, remove it and move it into env->pstate. This allows us to add support for CPSR_DIT, adding helper functions to merge SPSR_ELx to and from CPSR. Signed-off-by: Rebecca Cran Reviewed-by: Richard Henderson Message-id: 20210208065700.19454-3-rebecca@nuviainc.com Signed-off-by: Peter Maydell --- target/arm/helper-a64.c | 27 +++++++++++++++++++++++---- target/arm/helper.c | 24 ++++++++++++++++++------ target/arm/op_helper.c | 9 +-------- 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c index c426c23d2c..ae611d73c2 100644 --- a/target/arm/helper-a64.c +++ b/target/arm/helper-a64.c @@ -945,11 +945,31 @@ static int el_from_spsr(uint32_t spsr) } } +static void cpsr_write_from_spsr_elx(CPUARMState *env, + uint32_t val) +{ + uint32_t mask; + + /* Save SPSR_ELx.SS into PSTATE. */ + env->pstate = (env->pstate & ~PSTATE_SS) | (val & PSTATE_SS); + val &= ~PSTATE_SS; + + /* Move DIT to the correct location for CPSR */ + if (val & PSTATE_DIT) { + val &= ~PSTATE_DIT; + val |= CPSR_DIT; + } + + mask = aarch32_cpsr_valid_mask(env->features, \ + &env_archcpu(env)->isar); + cpsr_write(env, val, mask, CPSRWriteRaw); +} + void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc) { int cur_el = arm_current_el(env); unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el); - uint32_t mask, spsr = env->banked_spsr[spsr_idx]; + uint32_t spsr = env->banked_spsr[spsr_idx]; int new_el; bool return_to_aa64 = (spsr & PSTATE_nRW) == 0; @@ -998,10 +1018,9 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc) * will sort the register banks out for us, and we've already * caught all the bad-mode cases in el_from_spsr(). */ - mask = aarch32_cpsr_valid_mask(env->features, &env_archcpu(env)->isar); - cpsr_write(env, spsr, mask, CPSRWriteRaw); + cpsr_write_from_spsr_elx(env, spsr); if (!arm_singlestep_active(env)) { - env->uncached_cpsr &= ~PSTATE_SS; + env->pstate &= ~PSTATE_SS; } aarch64_sync_64_to_32(env); diff --git a/target/arm/helper.c b/target/arm/helper.c index cf8e80419d..2c27077fb2 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -9445,7 +9445,7 @@ static void take_aarch32_exception(CPUARMState *env, int new_mode, * For exceptions taken to AArch32 we must clear the SS bit in both * PSTATE and in the old-state value we save to SPSR_, so zero it now. */ - env->uncached_cpsr &= ~PSTATE_SS; + env->pstate &= ~PSTATE_SS; env->spsr = cpsr_read(env); /* Clear IT bits. */ env->condexec_bits = 0; @@ -9801,6 +9801,21 @@ static int aarch64_regnum(CPUARMState *env, int aarch32_reg) } } +static uint32_t cpsr_read_for_spsr_elx(CPUARMState *env) +{ + uint32_t ret = cpsr_read(env); + + /* Move DIT to the correct location for SPSR_ELx */ + if (ret & CPSR_DIT) { + ret &= ~CPSR_DIT; + ret |= PSTATE_DIT; + } + /* Merge PSTATE.SS into SPSR_ELx */ + ret |= env->pstate & PSTATE_SS; + + return ret; +} + /* Handle exception entry to a target EL which is using AArch64 */ static void arm_cpu_do_interrupt_aarch64(CPUState *cs) { @@ -9923,7 +9938,7 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs) aarch64_save_sp(env, arm_current_el(env)); env->elr_el[new_el] = env->pc; } else { - old_mode = cpsr_read(env); + old_mode = cpsr_read_for_spsr_elx(env); env->elr_el[new_el] = env->regs[15]; aarch64_sync_32_to_64(env); @@ -13217,7 +13232,6 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, target_ulong *cs_base, uint32_t *pflags) { uint32_t flags = env->hflags; - uint32_t pstate_for_ss; *cs_base = 0; assert_hflags_rebuild_correctly(env); @@ -13227,7 +13241,6 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, if (cpu_isar_feature(aa64_bti, env_archcpu(env))) { flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype); } - pstate_for_ss = env->pstate; } else { *pc = env->regs[15]; @@ -13275,7 +13288,6 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, flags = FIELD_DP32(flags, TBFLAG_AM32, THUMB, env->thumb); flags = FIELD_DP32(flags, TBFLAG_AM32, CONDEXEC, env->condexec_bits); - pstate_for_ss = env->uncached_cpsr; } /* @@ -13288,7 +13300,7 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, * SS_ACTIVE is set in hflags; PSTATE_SS is computed every TB. */ if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE) && - (pstate_for_ss & PSTATE_SS)) { + (env->pstate & PSTATE_SS)) { flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1); } diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c index 5e0f123043..65cb37d088 100644 --- a/target/arm/op_helper.c +++ b/target/arm/op_helper.c @@ -389,14 +389,7 @@ void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome) uint32_t HELPER(cpsr_read)(CPUARMState *env) { - /* - * We store the ARMv8 PSTATE.SS bit in env->uncached_cpsr. - * This is convenient for populating SPSR_ELx, but must be - * hidden from aarch32 mode, where it is not visible. - * - * TODO: ARMv8.4-DIT -- need to move SS somewhere else. - */ - return cpsr_read(env) & ~(CPSR_EXEC | PSTATE_SS); + return cpsr_read(env) & ~CPSR_EXEC; } void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask) -- cgit v1.2.3-55-g7522 From 2bf1eff9e9125a3d73901991dcfb9cb2ace03be1 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Sun, 7 Feb 2021 23:56:59 -0700 Subject: target/arm: Set ID_AA64PFR0.DIT and ID_PFR0.DIT to 1 for "max" AA64 CPU Enable FEAT_DIT for the "max" AARCH64 CPU. Signed-off-by: Rebecca Cran Reviewed-by: Richard Henderson Message-id: 20210208065700.19454-4-rebecca@nuviainc.com Signed-off-by: Peter Maydell --- target/arm/cpu64.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 10c5118176..c255f1bcc3 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -669,6 +669,7 @@ static void aarch64_max_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64PFR0, FP, 1); t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); + t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); cpu->isar.id_aa64pfr0 = t; t = cpu->isar.id_aa64pfr1; @@ -718,6 +719,10 @@ static void aarch64_max_initfn(Object *obj) u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1); cpu->isar.id_isar6 = u; + u = cpu->isar.id_pfr0; + u = FIELD_DP32(u, ID_PFR0, DIT, 1); + cpu->isar.id_pfr0 = u; + u = cpu->isar.id_mmfr3; u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */ cpu->isar.id_mmfr3 = u; -- cgit v1.2.3-55-g7522 From 5385320c2b3183f2e18dbc55c23ecba9272500c2 Mon Sep 17 00:00:00 2001 From: Rebecca Cran Date: Sun, 7 Feb 2021 23:57:00 -0700 Subject: target/arm: Set ID_PFR0.DIT to 1 for "max" 32-bit CPU Enable FEAT_DIT for the "max" 32-bit CPU. Signed-off-by: Rebecca Cran Reviewed-by: Richard Henderson Message-id: 20210208065700.19454-5-rebecca@nuviainc.com Signed-off-by: Peter Maydell --- target/arm/cpu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 8ddb2556f8..5cf6c056c5 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2202,6 +2202,10 @@ static void arm_max_initfn(Object *obj) t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */ cpu->isar.id_mmfr4 = t; + + t = cpu->isar.id_pfr0; + t = FIELD_DP32(t, ID_PFR0, DIT, 1); + cpu->isar.id_pfr0 = t; } #endif } -- cgit v1.2.3-55-g7522 From 932a8d1f11ccfbf196ee6fb4a5ccdf274b14a78c Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 5 Feb 2021 17:14:56 +0000 Subject: arm: Update infocenter.arm.com URLs Update infocenter.arm.com URLs for various pieces of Arm documentation to the new developer.arm.com equivalents. (There is a redirection in place from the old URLs, but we might as well update our comments in case the redirect ever disappears in future.) This patch covers all the URLs which are not MPS2/SSE-200/IoTKit related (those are dealt with in a different patch). Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Message-id: 20210205171456.19939-1-peter.maydell@linaro.org --- hw/arm/aspeed_ast2600.c | 2 +- hw/arm/musca.c | 4 ++-- hw/misc/arm_integrator_debug.c | 2 +- hw/timer/arm_timer.c | 7 ++++--- include/hw/dma/pl080.h | 7 ++++--- include/hw/misc/arm_integrator_debug.h | 2 +- include/hw/ssi/pl022.h | 5 +++-- 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c index 12e4a16d37..bf31ca351f 100644 --- a/hw/arm/aspeed_ast2600.c +++ b/hw/arm/aspeed_ast2600.c @@ -216,7 +216,7 @@ static void aspeed_soc_ast2600_init(Object *obj) /* * ASPEED ast2600 has 0xf as cluster ID * - * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0388e/CIHEBGFG.html + * https://developer.arm.com/documentation/ddi0388/e/the-system-control-coprocessors/summary-of-system-control-coprocessor-registers/multiprocessor-affinity-register */ static uint64_t aspeed_calc_affinity(int cpu) { diff --git a/hw/arm/musca.c b/hw/arm/musca.c index 945643c3cd..7a83f7dda7 100644 --- a/hw/arm/musca.c +++ b/hw/arm/musca.c @@ -15,8 +15,8 @@ * https://developer.arm.com/products/system-design/development-boards/iot-test-chips-and-boards/musca-a-test-chip-board * https://developer.arm.com/products/system-design/development-boards/iot-test-chips-and-boards/musca-b-test-chip-board * We model the A and B1 variants of this board, as described in the TRMs: - * http://infocenter.arm.com/help/topic/com.arm.doc.101107_0000_00_en/index.html - * http://infocenter.arm.com/help/topic/com.arm.doc.101312_0000_00_en/index.html + * https://developer.arm.com/documentation/101107/latest/ + * https://developer.arm.com/documentation/101312/latest/ */ #include "qemu/osdep.h" diff --git a/hw/misc/arm_integrator_debug.c b/hw/misc/arm_integrator_debug.c index ec0d4b90d3..9a19727829 100644 --- a/hw/misc/arm_integrator_debug.c +++ b/hw/misc/arm_integrator_debug.c @@ -6,7 +6,7 @@ * to this area. * * The real h/w is described at: - * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0159b/Babbfijf.html + * https://developer.arm.com/documentation/dui0159/b/peripherals-and-interfaces/debug-leds-and-dip-switch-interface * * Copyright (c) 2013 Alex Bennée * diff --git a/hw/timer/arm_timer.c b/hw/timer/arm_timer.c index 98e70b2d26..15caff0e41 100644 --- a/hw/timer/arm_timer.c +++ b/hw/timer/arm_timer.c @@ -185,10 +185,11 @@ static arm_timer_state *arm_timer_init(uint32_t freq) return s; } -/* ARM PrimeCell SP804 dual timer module. +/* + * ARM PrimeCell SP804 dual timer module. * Docs at - * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0271d/index.html -*/ + * https://developer.arm.com/documentation/ddi0271/latest/ + */ #define TYPE_SP804 "sp804" OBJECT_DECLARE_SIMPLE_TYPE(SP804State, SP804) diff --git a/include/hw/dma/pl080.h b/include/hw/dma/pl080.h index 1883f04270..3c9659e438 100644 --- a/include/hw/dma/pl080.h +++ b/include/hw/dma/pl080.h @@ -10,11 +10,12 @@ * (at your option) any later version. */ -/* This is a model of the Arm PrimeCell PL080/PL081 DMA controller: +/* + * This is a model of the Arm PrimeCell PL080/PL081 DMA controller: * The PL080 TRM is: - * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0196g/DDI0196.pdf + * https://developer.arm.com/documentation/ddi0196/latest * and the PL081 TRM is: - * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0218e/DDI0218.pdf + * https://developer.arm.com/documentation/ddi0218/latest * * QEMU interface: * + sysbus IRQ 0: DMACINTR combined interrupt line diff --git a/include/hw/misc/arm_integrator_debug.h b/include/hw/misc/arm_integrator_debug.h index 0077dacb44..798b082164 100644 --- a/include/hw/misc/arm_integrator_debug.h +++ b/include/hw/misc/arm_integrator_debug.h @@ -3,7 +3,7 @@ * * Browse the data sheet: * - * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0159b/Babbfijf.html + * https://developer.arm.com/documentation/dui0159/b/peripherals-and-interfaces/debug-leds-and-dip-switch-interface * * Copyright (c) 2013 Alex Bennée * diff --git a/include/hw/ssi/pl022.h b/include/hw/ssi/pl022.h index 545b52689c..25d58db5f3 100644 --- a/include/hw/ssi/pl022.h +++ b/include/hw/ssi/pl022.h @@ -9,9 +9,10 @@ * (at your option) any later version. */ -/* This is a model of the Arm PrimeCell PL022 synchronous serial port. +/* + * This is a model of the Arm PrimeCell PL022 synchronous serial port. * The PL022 TRM is: - * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0194h/DDI0194H_ssp_pl022_trm.pdf + * https://developer.arm.com/documentation/ddi0194/latest * * QEMU interface: * + sysbus IRQ: SSPINTR combined interrupt line -- cgit v1.2.3-55-g7522 From e6a41a045c298538d303cd8fe8d7ae29a0c066ad Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 29 Jan 2021 13:03:30 +0000 Subject: accel/tcg: Add URL of clang bug to comment about our workaround In cpu_exec() we have a longstanding workaround for compilers which do not correctly implement the part of the sigsetjmp()/siglongjmp() spec which requires that local variables which are not changed between the setjmp and the longjmp retain their value. I recently ran across the upstream clang bug report for this; add a link to it to the comment describing the workaround, and generally expand the comment, so that we have a reasonable chance in future of understanding why it's there and determining when we can remove it, assuming clang eventually fixes the bug. Remove the /* buggy compiler */ comments on the #else and #endif: they don't add anything to understanding and are somewhat misleading since they're sandwiching the code path for *non*-buggy compilers. Signed-off-by: Peter Maydell Reviewed-by: Alex Bennée Message-id: 20210129130330.30820-1-peter.maydell@linaro.org --- accel/tcg/cpu-exec.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index d9ef69121c..f2819eec7d 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -773,17 +773,30 @@ int cpu_exec(CPUState *cpu) /* prepare setjmp context for exception handling */ if (sigsetjmp(cpu->jmp_env, 0) != 0) { #if defined(__clang__) - /* Some compilers wrongly smash all local variables after - * siglongjmp. There were bug reports for gcc 4.5.0 and clang. + /* + * Some compilers wrongly smash all local variables after + * siglongjmp (the spec requires that only non-volatile locals + * which are changed between the sigsetjmp and siglongjmp are + * permitted to be trashed). There were bug reports for gcc + * 4.5.0 and clang. The bug is fixed in all versions of gcc + * that we support, but is still unfixed in clang: + * https://bugs.llvm.org/show_bug.cgi?id=21183 + * * Reload essential local variables here for those compilers. - * Newer versions of gcc would complain about this code (-Wclobbered). */ + * Newer versions of gcc would complain about this code (-Wclobbered), + * so we only perform the workaround for clang. + */ cpu = current_cpu; cc = CPU_GET_CLASS(cpu); -#else /* buggy compiler */ - /* Assert that the compiler does not smash local variables. */ +#else + /* + * Non-buggy compilers preserve these locals; assert that + * they have the correct value. + */ g_assert(cpu == current_cpu); g_assert(cc == CPU_GET_CLASS(cpu)); -#endif /* buggy compiler */ +#endif + #ifndef CONFIG_SOFTMMU tcg_debug_assert(!have_mmap_lock()); #endif -- cgit v1.2.3-55-g7522 From 4565d826163d2e3a4ca3a5ebf3904e6b3b04a487 Mon Sep 17 00:00:00 2001 From: Edgar E. Iglesias Date: Wed, 10 Feb 2021 15:20:48 +0100 Subject: hw/arm: versal: Use nr_apu_cpus in favor of hard coding 2 Use nr_apu_cpus in favor of hard coding 2. Signed-off-by: Edgar E. Iglesias Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Luc Michel Message-id: 20210210142048.3125878-2-edgar.iglesias@gmail.com Signed-off-by: Peter Maydell --- hw/arm/xlnx-versal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c index b0777166e8..628e77ef66 100644 --- a/hw/arm/xlnx-versal.c +++ b/hw/arm/xlnx-versal.c @@ -67,10 +67,10 @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic) gicbusdev = SYS_BUS_DEVICE(&s->fpd.apu.gic); gicdev = DEVICE(&s->fpd.apu.gic); qdev_prop_set_uint32(gicdev, "revision", 3); - qdev_prop_set_uint32(gicdev, "num-cpu", 2); + qdev_prop_set_uint32(gicdev, "num-cpu", nr_apu_cpus); qdev_prop_set_uint32(gicdev, "num-irq", XLNX_VERSAL_NR_IRQS + 32); qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1); - qdev_prop_set_uint32(gicdev, "redist-region-count[0]", 2); + qdev_prop_set_uint32(gicdev, "redist-region-count[0]", nr_apu_cpus); qdev_prop_set_bit(gicdev, "has-security-extensions", true); sysbus_realize(SYS_BUS_DEVICE(&s->fpd.apu.gic), &error_fatal); -- cgit v1.2.3-55-g7522 From d3c1183ffeb71ca3a783eae3d7e1c51e71e8a621 Mon Sep 17 00:00:00 2001 From: Daniel Müller Date: Wed, 10 Feb 2021 09:41:22 -0800 Subject: target/arm: Correctly initialize MDCR_EL2.HPMN When working with performance monitoring counters, we look at MDCR_EL2.HPMN as part of the check whether a counter is enabled. This check fails, because MDCR_EL2.HPMN is reset to 0, meaning that no counters are "enabled" for < EL2. That's in violation of the Arm specification, which states that > On a Warm reset, this field [MDCR_EL2.HPMN] resets to the value in > PMCR_EL0.N That's also what a comment in the code acknowledges, but the necessary adjustment seems to have been forgotten when support for more counters was added. This change fixes the issue by setting the reset value to PMCR.N, which is four. Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- target/arm/helper.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 2c27077fb2..0e1a3b9421 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -38,6 +38,7 @@ #endif #define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */ +#define PMCR_NUM_COUNTERS 4 /* QEMU IMPDEF choice */ #ifndef CONFIG_USER_ONLY @@ -5735,13 +5736,11 @@ static const ARMCPRegInfo el2_cp_reginfo[] = { .writefn = gt_hyp_ctl_write, .raw_writefn = raw_write }, #endif /* The only field of MDCR_EL2 that has a defined architectural reset value - * is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N; but we - * don't implement any PMU event counters, so using zero as a reset - * value for MDCR_EL2 is okay + * is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N. */ { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1, - .access = PL2_RW, .resetvalue = 0, + .access = PL2_RW, .resetvalue = PMCR_NUM_COUNTERS, .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el2), }, { .name = "HPFAR", .state = ARM_CP_STATE_AA32, .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4, @@ -6672,7 +6671,7 @@ static void define_pmu_regs(ARMCPU *cpu) * field as main ID register, and we implement four counters in * addition to the cycle count register. */ - unsigned int i, pmcrn = 4; + unsigned int i, pmcrn = PMCR_NUM_COUNTERS; ARMCPRegInfo pmcr = { .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0, .access = PL0_RW, -- cgit v1.2.3-55-g7522