
Part1: rework id register storage Cornelia Huck ----------------------------------------------------------------- Patch#1 arm/cpu: Add sysreg definitions in cpu-sysregs.h Patch#2 arm/cpu: Store aa64isar0/aa64zfr0 into the idregs arrays Patch#3 arm/cpu: Store aa64isar1/2 into the idregs array Patch#4 arm/cpu: Store aa64pfr0/1 into the idregs array Patch#5 arm/cpu: Store aa64mmfr0-2 into the idregs array Patch#6 arm/cpu: Store aa64dfr0/1 into the idregs array Patch#7 arm/cpu: Store aa64dfr0/1 into the idregs array Patch#8 arm/cpu: Store aa64smfr0 into the idregs array Patch#9 arm/cpu: Store id_isar0-7 into the idregs array Patch#10 arm/cpu: Store id_pfr0/1/2 into the idregs array Patch#11 arm/cpu: Store id_mmfr0-5 into the idregs array Patch#12 arm/cpu: Add sysreg generation scripts Patch#13 arm/cpu: switch to a generated cpu-sysregs.h.inc Part2: Introduce a customizable aarch64 KVM host model ----------------------------------------------------------------- Patch#14 arm/kvm: use fd instead of fdarray[2] Patch#15 arm/cpu: Add infra to handle generated ID register definitions Patch#16 arm/cpu: Add sysreg properties generation Patch#17 arm/cpu: Add generated sysreg properties Patch#18 kvm: kvm_get_writable_id_regs Patch#19 arm/cpu: accessors for writable id registers Patch#20 arm/kvm: Allow reading all the writable ID registers Patch#21 arm/kvm: write back modified ID regs to KVM Patch#22 arm/cpu: more customization for the kvm host cpu model Patch#23 arm-qmp-cmds: introspection for ID register props Patch#24 arm/cpu-features: document ID reg properties Patch#25 arm/cpu: manually make IDR/REVIDR/AIDR writable Patch#26 arm/cpu: enable MIDR writable Part3: Errata management for VM Live migration ----------------------------------------------------------------- Patch#27 target/arm/kvm: Add SMMC hypercall definitions Patch#28 hw/arm/virt: Initial support to set target_impl CPUs Patch#29 target/arm/kvm: Use PSCI_VERSIOn for version info Patch#30 target/arm/kvm: Set DISCOVER_IMPL_* hypercalls Cornelia Huck (7): arm/cpu: switch to a generated cpu-sysregs.h.inc arm/kvm: use fd instead of fdarray[2] arm/cpu: Add generated sysreg properties kvm: kvm_get_writable_id_regs arm/cpu: accessors for writable id registers arm-qmp-cmds: introspection for ID register props arm/cpu-features: document ID reg properties Eric Auger (17): arm/cpu: Add sysreg definitions in cpu-sysregs.h arm/cpu: Store aa64isar0/aa64zfr0 into the idregs arrays arm/cpu: Store aa64isar1/2 into the idregs array arm/cpu: Store aa64pfr0/1 into the idregs array arm/cpu: Store aa64mmfr0-2 into the idregs array arm/cpu: Store aa64dfr0/1 into the idregs array arm/cpu: Store aa64smfr0 into the idregs array arm/cpu: Store id_isar0-7 into the idregs array arm/cpu: Store id_pfr0/1/2 into the idregs array arm/cpu: Store id_dfr0/1 into the idregs array arm/cpu: Store id_mmfr0-5 into the idregs array arm/cpu: Add sysreg generation scripts arm/cpu: Add infra to handle generated ID register definitions arm/cpu: Add sysreg properties generation arm/kvm: Allow reading all the writable ID registers arm/kvm: write back modified ID regs to KVM arm/cpu: more customization for the kvm host cpu model Qingtong Jia (2): arm/cpu: manually make IDR/REVIDR/AIDR writable arm/cpu: enable MIDR writable Shameer Kolothum (4): target/arm/kvm: Add SMMC hypercall definitions hw/arm/virt: Initial support to set target_impl CPUs target/arm/kvm: Use PSCI_VERSIOn for version info target/arm/kvm: Set DISCOVER_IMPL_* hypercalls MAINTAINERS | 1 + accel/kvm/kvm-all.c | 7 + docs/system/arm/cpu-features.rst | 104 +++- hw/arm/virt.c | 65 ++- hw/intc/armv7m_nvic.c | 27 +- include/hw/boards.h | 3 + scripts/arm-gen-cpu-sysregs-header.awk | 40 ++ scripts/gen-cpu-sysreg-properties.awk | 346 +++++++++++ scripts/update-aarch64-sysreg-code.sh | 35 ++ target/arm/arm-qmp-cmds.c | 19 + target/arm/cpu-custom.h | 60 ++ target/arm/cpu-features.h | 295 +++++----- target/arm/cpu-sysreg-properties.c | 764 +++++++++++++++++++++++++ target/arm/cpu-sysregs.h | 48 ++ target/arm/cpu-sysregs.h.inc | 55 ++ target/arm/cpu.c | 124 ++-- target/arm/cpu.h | 126 +++- target/arm/cpu64.c | 202 ++++--- target/arm/helper.c | 66 +-- target/arm/hvf/hvf.c | 23 +- target/arm/internals.h | 6 +- target/arm/kvm-rme.c | 5 +- target/arm/kvm.c | 188 +++++- target/arm/kvm64.c | 365 +++++++++--- target/arm/kvm_arm.h | 46 +- target/arm/meson.build | 1 + target/arm/ptw.c | 6 +- target/arm/tcg/cpu32.c | 498 ++++++++-------- target/arm/tcg/cpu64.c | 455 +++++++-------- target/arm/trace-events | 8 + 30 files changed, 3035 insertions(+), 953 deletions(-) create mode 100755 scripts/arm-gen-cpu-sysregs-header.awk create mode 100755 scripts/gen-cpu-sysreg-properties.awk create mode 100755 scripts/update-aarch64-sysreg-code.sh create mode 100644 target/arm/cpu-custom.h create mode 100644 target/arm/cpu-sysreg-properties.c create mode 100644 target/arm/cpu-sysregs.h create mode 100644 target/arm/cpu-sysregs.h.inc -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> This new header contains macros that define aarch64 registers. In a subsequent patch, this will be replaced by a more exhaustive version that will be generated from linux arch/arm64/tools/sysreg file. Those macros are sufficient to migrate the storage of those ID regs from named fields in isar struct to an array cell. [CH: reworked to use different structures] [CH: moved accessors from the patches first using them to here, dropped interaction with writable registers, which will happen later] [CH: use DEF magic suggested by rth] Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Sebastian Ott <sebott@redhat.com> Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/cpu-sysregs.h | 42 +++++++++++++++++++++++++++++++ target/arm/cpu-sysregs.h.inc | 36 ++++++++++++++++++++++++++ target/arm/cpu.h | 49 ++++++++++++++++++++++++++++++++++++ target/arm/cpu64.c | 22 ++++++++++++++++ 4 files changed, 149 insertions(+) create mode 100644 target/arm/cpu-sysregs.h create mode 100644 target/arm/cpu-sysregs.h.inc diff --git a/target/arm/cpu-sysregs.h b/target/arm/cpu-sysregs.h new file mode 100644 index 0000000000..7877a3b06a --- /dev/null +++ b/target/arm/cpu-sysregs.h @@ -0,0 +1,42 @@ +/* + * Definitions for Arm ID system registers + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef ARM_CPU_SYSREGS_H +#define ARM_CPU_SYSREGS_H + +/* + * Following is similar to the coprocessor regs encodings, but with an argument + * ordering that matches the ARM ARM. We also reuse the various CP_REG_ defines + * that actually are the same as the equivalent KVM_REG_ values. + */ +#define ENCODE_ID_REG(op0, op1, crn, crm, op2) \ + (((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | \ + ((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \ + ((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | \ + ((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) | \ + ((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT)) + +#define DEF(NAME, OP0, OP1, CRN, CRM, OP2) NAME##_IDX, + +typedef enum ARMIDRegisterIdx { +#include "cpu-sysregs.h.inc" + NUM_ID_IDX, +} ARMIDRegisterIdx; + +#undef DEF +#define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \ + SYS_##NAME = ENCODE_ID_REG(OP0, OP1, CRN, CRM, OP2), + +typedef enum ARMSysRegs { +#include "cpu-sysregs.h.inc" +} ARMSysRegs; + +#undef DEF + +extern const uint32_t id_register_sysreg[NUM_ID_IDX]; + +int get_sysreg_idx(ARMSysRegs sysreg); + +#endif /* ARM_CPU_SYSREGS_H */ diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc new file mode 100644 index 0000000000..cb99286f70 --- /dev/null +++ b/target/arm/cpu-sysregs.h.inc @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +DEF(ID_AA64PFR0_EL1, 3, 0, 0, 4, 0) +DEF(ID_AA64PFR1_EL1, 3, 0, 0, 4, 1) +DEF(ID_AA64SMFR0_EL1, 3, 0, 0, 4, 5) +DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0) +DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1) +DEF(ID_AA64ISAR0_EL1, 3, 0, 0, 6, 0) +DEF(ID_AA64ISAR1_EL1, 3, 0, 0, 6, 1) +DEF(ID_AA64ISAR2_EL1, 3, 0, 0, 6, 2) +DEF(ID_AA64MMFR0_EL1, 3, 0, 0, 7, 0) +DEF(ID_AA64MMFR1_EL1, 3, 0, 0, 7, 1) +DEF(ID_AA64MMFR2_EL1, 3, 0, 0, 7, 2) +DEF(ID_AA64MMFR3_EL1, 3, 0, 0, 7, 3) +DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0) +DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1) +DEF(ID_DFR0_EL1, 3, 0, 0, 1, 2) +DEF(ID_MMFR0_EL1, 3, 0, 0, 1, 4) +DEF(ID_MMFR1_EL1, 3, 0, 0, 1, 5) +DEF(ID_MMFR2_EL1, 3, 0, 0, 1, 6) +DEF(ID_MMFR3_EL1, 3, 0, 0, 1, 7) +DEF(ID_ISAR0_EL1, 3, 0, 0, 2, 0) +DEF(ID_ISAR1_EL1, 3, 0, 0, 2, 1) +DEF(ID_ISAR2_EL1, 3, 0, 0, 2, 2) +DEF(ID_ISAR3_EL1, 3, 0, 0, 2, 3) +DEF(ID_ISAR4_EL1, 3, 0, 0, 2, 4) +DEF(ID_ISAR5_EL1, 3, 0, 0, 2, 5) +DEF(ID_MMFR4_EL1, 3, 0, 0, 2, 6) +DEF(ID_ISAR6_EL1, 3, 0, 0, 2, 7) +DEF(MVFR0_EL1, 3, 0, 0, 3, 0) +DEF(MVFR1_EL1, 3, 0, 0, 3, 1) +DEF(MVFR2_EL1, 3, 0, 0, 3, 2) +DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4) +DEF(ID_DFR1_EL1, 3, 0, 0, 3, 5) +DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6) +DEF(ID_AA64ZFR0_EL1, 3, 0, 0, 4, 4) +DEF(CTR_EL0, 3, 3, 0, 0, 1) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index cb546a93e2..6933b1a73f 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -26,6 +26,7 @@ #include "cpu-qom.h" #include "exec/cpu-defs.h" #include "qapi/qapi-types-common.h" +#include "target/arm/cpu-sysregs.h" /* ARM processors have a weak memory model */ #define TCG_GUEST_DEFAULT_MO (0) @@ -845,6 +846,53 @@ typedef struct { uint32_t map, init, supported; } ARMVQMap; +/* REG is ID_XXX */ +#define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE) \ + ({ \ + ARMISARegisters *i_ = (ISAR); \ + uint64_t regval = i_->idregs[REG ## _EL1_IDX]; \ + regval = FIELD_DP64(regval, REG, FIELD, VALUE); \ + i_->idregs[REG ## _EL1_IDX] = regval; \ + }) + +#define FIELD_DP32_IDREG(ISAR, REG, FIELD, VALUE) \ + ({ \ + ARMISARegisters *i_ = (ISAR); \ + uint64_t regval = i_->idregs[REG ## _EL1_IDX]; \ + regval = FIELD_DP32(regval, REG, FIELD, VALUE); \ + i_->idregs[REG ## _EL1_IDX] = regval; \ + }) + +#define FIELD_EX64_IDREG(ISAR, REG, FIELD) \ + ({ \ + const ARMISARegisters *i_ = (ISAR); \ + FIELD_EX64(i_->idregs[REG ## _EL1_IDX], REG, FIELD); \ + }) + +#define FIELD_EX32_IDREG(ISAR, REG, FIELD) \ + ({ \ + const ARMISARegisters *i_ = (ISAR); \ + FIELD_EX32(i_->idregs[REG ## _EL1_IDX], REG, FIELD); \ + }) + +#define FIELD_SEX64_IDREG(ISAR, REG, FIELD) \ + ({ \ + const ARMISARegisters *i_ = (ISAR); \ + FIELD_SEX64(i_->idregs[REG ## _EL1_IDX], REG, FIELD); \ + }) + +#define SET_IDREG(ISAR, REG, VALUE) \ + ({ \ + ARMISARegisters *i_ = (ISAR); \ + i_->idregs[REG ## _EL1_IDX] = VALUE; \ + }) + +#define GET_IDREG(ISAR, REG) \ + ({ \ + const ARMISARegisters *i_ = (ISAR); \ + i_->idregs[REG ## _EL1_IDX]; \ + }) + /** * ARMCPU: * @env: #CPUARMState @@ -1047,6 +1095,7 @@ struct ArchCPU { uint64_t id_aa64zfr0; uint64_t id_aa64smfr0; uint64_t reset_pmcr_el0; + uint64_t idregs[NUM_ID_IDX]; } isar; uint64_t midr; uint32_t revidr; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 4cf8446b6e..20e49aa72a 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -35,6 +35,28 @@ #include "cpu-features.h" #include "cpregs.h" +/* convert between <register>_IDX and SYS_<register> */ +#define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \ + [NAME##_IDX] = SYS_##NAME, + +const uint32_t id_register_sysreg[NUM_ID_IDX] = { +#include "cpu-sysregs.h.inc" +}; + +#undef DEF +#define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \ + case SYS_##NAME: return NAME##_IDX; + +int get_sysreg_idx(ARMSysRegs sysreg) +{ + switch (sysreg) { +#include "cpu-sysregs.h.inc" + } + g_assert_not_reached(); +} + +#undef DEF + void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { /* -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> Also add kvm accessors for storing host features into idregs. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Sebastian Ott <sebott@redhat.com> Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/cpu-features.h | 57 ++++++++++++++++++++------------------- target/arm/cpu-sysregs.h | 4 +++ target/arm/cpu.c | 9 +++---- target/arm/cpu.h | 2 -- target/arm/cpu64.c | 12 +++++---- target/arm/helper.c | 6 +++-- target/arm/hvf/hvf.c | 3 ++- target/arm/kvm.c | 1 + target/arm/kvm64.c | 29 +++++++++++++++++--- target/arm/tcg/cpu64.c | 44 ++++++++++++++++++------------ 10 files changed, 103 insertions(+), 64 deletions(-) diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index 165a497f7b..b9ece5f03a 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -20,6 +20,7 @@ #ifndef TARGET_ARM_FEATURES_H #define TARGET_ARM_FEATURES_H +#include "cpu-sysregs.h" /* * Naming convention for isar_feature functions: * Functions which test 32-bit ID registers should have _aa32_ in @@ -373,92 +374,92 @@ static inline bool isar_feature_aa32_doublelock(const ARMISARegisters *id) */ static inline bool isar_feature_aa64_aes(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, AES) != 0; } static inline bool isar_feature_aa64_pmull(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) > 1; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, AES) > 1; } static inline bool isar_feature_aa64_sha1(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA1) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, SHA1) != 0; } static inline bool isar_feature_aa64_sha256(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, SHA2) != 0; } static inline bool isar_feature_aa64_sha512(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) > 1; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, SHA2) > 1; } static inline bool isar_feature_aa64_crc32(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, CRC32) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, CRC32) != 0; } static inline bool isar_feature_aa64_atomics(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, ATOMIC) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, ATOMIC) != 0; } static inline bool isar_feature_aa64_rdm(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RDM) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, RDM) != 0; } static inline bool isar_feature_aa64_sha3(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA3) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, SHA3) != 0; } static inline bool isar_feature_aa64_sm3(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM3) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, SM3) != 0; } static inline bool isar_feature_aa64_sm4(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM4) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, SM4) != 0; } static inline bool isar_feature_aa64_dp(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, DP) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, DP) != 0; } static inline bool isar_feature_aa64_fhm(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, FHM) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, FHM) != 0; } static inline bool isar_feature_aa64_condm_4(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, TS) != 0; } static inline bool isar_feature_aa64_condm_5(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) >= 2; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, TS) >= 2; } static inline bool isar_feature_aa64_rndr(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RNDR) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, RNDR) != 0; } static inline bool isar_feature_aa64_tlbirange(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) == 2; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, TLB) == 2; } static inline bool isar_feature_aa64_tlbios(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR0, TLB) != 0; } static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id) @@ -869,52 +870,52 @@ static inline bool isar_feature_aa64_doublelock(const ARMISARegisters *id) static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SVEVER) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ZFR0, SVEVER) != 0; } static inline bool isar_feature_aa64_sve2_aes(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, AES) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ZFR0, AES) != 0; } static inline bool isar_feature_aa64_sve2_pmull128(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, AES) >= 2; + return FIELD_EX64_IDREG(id, ID_AA64ZFR0, AES) >= 2; } static inline bool isar_feature_aa64_sve2_bitperm(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BITPERM) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ZFR0, BITPERM) != 0; } static inline bool isar_feature_aa64_sve_bf16(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BFLOAT16) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ZFR0, BFLOAT16) != 0; } static inline bool isar_feature_aa64_sve2_sha3(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SHA3) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ZFR0, SHA3) != 0; } static inline bool isar_feature_aa64_sve2_sm4(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SM4) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ZFR0, SM4) != 0; } static inline bool isar_feature_aa64_sve_i8mm(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, I8MM) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ZFR0, I8MM) != 0; } static inline bool isar_feature_aa64_sve_f32mm(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, F32MM) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ZFR0, F32MM) != 0; } static inline bool isar_feature_aa64_sve_f64mm(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, F64MM) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ZFR0, F64MM) != 0; } static inline bool isar_feature_aa64_sme_f64f64(const ARMISARegisters *id) diff --git a/target/arm/cpu-sysregs.h b/target/arm/cpu-sysregs.h index 7877a3b06a..e89a110590 100644 --- a/target/arm/cpu-sysregs.h +++ b/target/arm/cpu-sysregs.h @@ -39,4 +39,8 @@ extern const uint32_t id_register_sysreg[NUM_ID_IDX]; int get_sysreg_idx(ARMSysRegs sysreg); +#ifdef CONFIG_KVM +uint64_t idregs_sysreg_to_kvm_reg(ARMSysRegs sysreg); +#endif + #endif /* ARM_CPU_SYSREGS_H */ diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 3de2e1a3c3..262c5017d2 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1815,6 +1815,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); ARMCPU *cpu = ARM_CPU(dev); + ARMISARegisters *isar = &cpu->isar; ARMCPUClass *acc = ARM_CPU_GET_CLASS(dev); CPUARMState *env = &cpu->env; int pagebits; @@ -2008,7 +2009,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) unset_feature(env, ARM_FEATURE_NEON); - t = cpu->isar.id_aa64isar0; + t = GET_IDREG(isar, ID_AA64ISAR0); t = FIELD_DP64(t, ID_AA64ISAR0, AES, 0); t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 0); t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 0); @@ -2016,7 +2017,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 0); t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 0); t = FIELD_DP64(t, ID_AA64ISAR0, DP, 0); - cpu->isar.id_aa64isar0 = t; + SET_IDREG(isar, ID_AA64ISAR0, t); t = cpu->isar.id_aa64isar1; t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 0); @@ -2061,9 +2062,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) uint64_t t; uint32_t u; - t = cpu->isar.id_aa64isar0; - t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 0); - cpu->isar.id_aa64isar0 = t; + FIELD_DP64_IDREG(isar, ID_AA64ISAR0, FHM, 0); t = cpu->isar.id_aa64isar1; t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 0); diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 6933b1a73f..b6e988e570 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1082,7 +1082,6 @@ struct ArchCPU { uint32_t dbgdidr; uint32_t dbgdevid; uint32_t dbgdevid1; - uint64_t id_aa64isar0; uint64_t id_aa64isar1; uint64_t id_aa64isar2; uint64_t id_aa64pfr0; @@ -1092,7 +1091,6 @@ struct ArchCPU { uint64_t id_aa64mmfr2; uint64_t id_aa64dfr0; uint64_t id_aa64dfr1; - uint64_t id_aa64zfr0; uint64_t id_aa64smfr0; uint64_t reset_pmcr_el0; uint64_t idregs[NUM_ID_IDX]; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 20e49aa72a..4d31d34591 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -136,7 +136,7 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) * SVE is disabled and so are all vector lengths. Good. * Disable all SVE extensions as well. */ - cpu->isar.id_aa64zfr0 = 0; + SET_IDREG(&cpu->isar, ID_AA64ZFR0, 0); return; } @@ -738,6 +738,7 @@ void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp) static void aarch64_a57_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,cortex-a57"; set_feature(&cpu->env, ARM_FEATURE_V8); @@ -774,7 +775,7 @@ static void aarch64_a57_initfn(Object *obj) cpu->isar.id_isar6 = 0; cpu->isar.id_aa64pfr0 = 0x00002222; cpu->isar.id_aa64dfr0 = 0x10305106; - cpu->isar.id_aa64isar0 = 0x00011120; + SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); cpu->isar.id_aa64mmfr0 = 0x00001124; cpu->isar.dbgdidr = 0x3516d000; cpu->isar.dbgdevid = 0x01110f13; @@ -795,6 +796,7 @@ static void aarch64_a57_initfn(Object *obj) static void aarch64_a53_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,cortex-a53"; set_feature(&cpu->env, ARM_FEATURE_V8); @@ -831,7 +833,7 @@ static void aarch64_a53_initfn(Object *obj) cpu->isar.id_isar6 = 0; cpu->isar.id_aa64pfr0 = 0x00002222; cpu->isar.id_aa64dfr0 = 0x10305106; - cpu->isar.id_aa64isar0 = 0x00011120; + SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */ cpu->isar.dbgdidr = 0x3516d000; cpu->isar.dbgdevid = 0x00110f13; @@ -887,7 +889,7 @@ static void aarch64_a72_initfn(Object *obj) cpu->isar.id_isar5 = 0x00011121; cpu->isar.id_aa64pfr0 = 0x00002222; cpu->isar.id_aa64dfr0 = 0x10305106; - cpu->isar.id_aa64isar0 = 0x00011120; + SET_IDREG(&cpu->isar, ID_AA64ISAR0, 0x00011120); cpu->isar.id_aa64mmfr0 = 0x00001124; cpu->isar.dbgdidr = 0x3516d000; cpu->clidr = 0x0a200023; @@ -916,7 +918,7 @@ static void aarch64_kunpeng_920_initfn(Object *obj) cpu->ctr = 0x84448004; cpu->isar.id_aa64pfr0 = 0x11001111; cpu->isar.id_aa64dfr0 = 0x110305408; - cpu->isar.id_aa64isar0 = 0x10211120; + SET_IDREG(&cpu->isar, ID_AA64ISAR0, 0x10211120); cpu->isar.id_aa64mmfr0 = 0x101125; } diff --git a/target/arm/helper.c b/target/arm/helper.c index 0370a739e3..02c0033712 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8202,6 +8202,8 @@ void register_cp_regs_for_features(ARMCPU *cpu) { /* Register all the coprocessor registers based on feature bits */ CPUARMState *env = &cpu->env; + ARMISARegisters *isar = &cpu->isar; + if (arm_feature(env, ARM_FEATURE_M)) { /* M profile has no coprocessor registers */ return; @@ -8393,7 +8395,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 4, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, - .resetvalue = cpu->isar.id_aa64zfr0 }, + .resetvalue = GET_IDREG(isar, ID_AA64ZFR0)}, { .name = "ID_AA64SMFR0_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5, .access = PL1_R, .type = ARM_CP_CONST, @@ -8453,7 +8455,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, - .resetvalue = cpu->isar.id_aa64isar0 }, + .resetvalue = GET_IDREG(isar, ID_AA64ISAR0)}, { .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index d7cc00a084..3953e6257d 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -18,6 +18,7 @@ #include "sysemu/hw_accel.h" #include "hvf_arm.h" #include "cpregs.h" +#include "cpu-sysregs.h" #include <mach/mach_time.h> @@ -845,7 +846,7 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) { HV_SYS_REG_ID_AA64PFR1_EL1, &host_isar.id_aa64pfr1 }, { HV_SYS_REG_ID_AA64DFR0_EL1, &host_isar.id_aa64dfr0 }, { HV_SYS_REG_ID_AA64DFR1_EL1, &host_isar.id_aa64dfr1 }, - { HV_SYS_REG_ID_AA64ISAR0_EL1, &host_isar.id_aa64isar0 }, + { HV_SYS_REG_ID_AA64ISAR0_EL1, &host_isar.idregs[ID_AA64ISAR0_EL1_IDX] }, { HV_SYS_REG_ID_AA64ISAR1_EL1, &host_isar.id_aa64isar1 }, /* Add ID_AA64ISAR2_EL1 here when HVF supports it */ { HV_SYS_REG_ID_AA64MMFR0_EL1, &host_isar.id_aa64mmfr0 }, diff --git a/target/arm/kvm.c b/target/arm/kvm.c index f45783a9da..e0b404962d 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -23,6 +23,7 @@ #include "sysemu/kvm_int.h" #include "kvm_arm.h" #include "cpu.h" +#include "cpu-sysregs.h" #include "trace.h" #include "internals.h" #include "hw/pci/pci.h" diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 6a8aad0f06..f47a5be3ac 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -17,6 +17,7 @@ #include <linux/kvm.h> #include "qapi/error.h" +#include "qapi/visitor.h" #include "cpu.h" #include "qemu/timer.h" #include "qemu/error-report.h" @@ -251,6 +252,27 @@ static bool kvm_arm_pauth_supported(void) kvm_check_extension(kvm_state, KVM_CAP_ARM_PTRAUTH_GENERIC)); } +uint64_t idregs_sysreg_to_kvm_reg(ARMSysRegs sysreg) +{ + return ARM64_SYS_REG((sysreg & CP_REG_ARM64_SYSREG_OP0_MASK) >> CP_REG_ARM64_SYSREG_OP0_SHIFT, + (sysreg & CP_REG_ARM64_SYSREG_OP1_MASK) >> CP_REG_ARM64_SYSREG_OP1_SHIFT, + (sysreg & CP_REG_ARM64_SYSREG_CRN_MASK) >> CP_REG_ARM64_SYSREG_CRN_SHIFT, + (sysreg & CP_REG_ARM64_SYSREG_CRM_MASK) >> CP_REG_ARM64_SYSREG_CRM_SHIFT, + (sysreg & CP_REG_ARM64_SYSREG_OP2_MASK) >> CP_REG_ARM64_SYSREG_OP2_SHIFT); +} + +/* read a sysreg value and store it in the idregs */ +static int get_host_cpu_reg(int fd, ARMHostCPUFeatures *ahcf, ARMIDRegisterIdx index) +{ + uint64_t *reg; + int ret; + + reg = &ahcf->isar.idregs[index]; + ret = read_sys_reg64(fd, reg, + idregs_sysreg_to_kvm_reg(id_register_sysreg[index])); + return ret; +} + bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) { /* Identify the feature bits corresponding to the host CPU, and @@ -310,6 +332,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) ahcf->target = init.target; ahcf->dtb_compatible = "arm,arm-v8"; + int fd = fdarray[2]; err = read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr0, ARM64_SYS_REG(3, 0, 0, 4, 0)); @@ -341,8 +364,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) KVM_REG_ARM_ID_AA64DFR0_EL1); err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr1, ARM64_SYS_REG(3, 0, 0, 5, 1)); - err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar0, - ARM64_SYS_REG(3, 0, 0, 6, 0)); + err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR0_EL1_IDX); err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1, ARM64_SYS_REG(3, 0, 0, 6, 1)); err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar2, @@ -449,8 +471,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) * enabled SVE support, which resulted in an error rather than RAZ. * So only read the register if we set KVM_ARM_VCPU_SVE above. */ - err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64zfr0, - ARM64_SYS_REG(3, 0, 0, 4, 4)); + err |= get_host_cpu_reg(fd, ahcf, ID_AA64ZFR0_EL1_IDX); } } diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c index fcda99e158..2515026ce5 100644 --- a/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c @@ -58,6 +58,7 @@ static uint64_t make_ccsidr64(unsigned assoc, unsigned linesize, static void aarch64_a35_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,cortex-a35"; set_feature(&cpu->env, ARM_FEATURE_V8); @@ -91,7 +92,7 @@ static void aarch64_a35_initfn(Object *obj) cpu->isar.id_aa64pfr1 = 0; cpu->isar.id_aa64dfr0 = 0x10305106; cpu->isar.id_aa64dfr1 = 0; - cpu->isar.id_aa64isar0 = 0x00011120; + SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); cpu->isar.id_aa64isar1 = 0; cpu->isar.id_aa64mmfr0 = 0x00101122; cpu->isar.id_aa64mmfr1 = 0; @@ -226,6 +227,7 @@ static Property arm_cpu_lpa2_property = static void aarch64_a55_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,cortex-a55"; set_feature(&cpu->env, ARM_FEATURE_V8); @@ -242,7 +244,7 @@ static void aarch64_a55_initfn(Object *obj) cpu->ctr = 0x84448004; /* L1Ip = VIPT */ cpu->dcz_blocksize = 4; /* 64 bytes */ cpu->isar.id_aa64dfr0 = 0x0000000010305408ull; - cpu->isar.id_aa64isar0 = 0x0000100010211120ull; + SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull); cpu->isar.id_aa64isar1 = 0x0000000000100001ull; cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull; cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; @@ -294,6 +296,7 @@ static void aarch64_a55_initfn(Object *obj) static void aarch64_a72_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,cortex-a72"; set_feature(&cpu->env, ARM_FEATURE_V8); @@ -328,7 +331,7 @@ static void aarch64_a72_initfn(Object *obj) cpu->isar.id_isar5 = 0x00011121; cpu->isar.id_aa64pfr0 = 0x00002222; cpu->isar.id_aa64dfr0 = 0x10305106; - cpu->isar.id_aa64isar0 = 0x00011120; + SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); cpu->isar.id_aa64mmfr0 = 0x00001124; cpu->isar.dbgdidr = 0x3516d000; cpu->isar.dbgdevid = 0x01110f13; @@ -349,6 +352,7 @@ static void aarch64_a72_initfn(Object *obj) static void aarch64_a76_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,cortex-a76"; set_feature(&cpu->env, ARM_FEATURE_V8); @@ -365,7 +369,7 @@ static void aarch64_a76_initfn(Object *obj) cpu->ctr = 0x8444C004; cpu->dcz_blocksize = 4; cpu->isar.id_aa64dfr0 = 0x0000000010305408ull; - cpu->isar.id_aa64isar0 = 0x0000100010211120ull; + SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull); cpu->isar.id_aa64isar1 = 0x0000000000100001ull; cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull; cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; @@ -418,6 +422,7 @@ static void aarch64_a76_initfn(Object *obj) static void aarch64_a64fx_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,a64fx"; set_feature(&cpu->env, ARM_FEATURE_V8); @@ -440,9 +445,9 @@ static void aarch64_a64fx_initfn(Object *obj) cpu->isar.id_aa64mmfr0 = 0x0000000000001122; cpu->isar.id_aa64mmfr1 = 0x0000000011212100; cpu->isar.id_aa64mmfr2 = 0x0000000000001011; - cpu->isar.id_aa64isar0 = 0x0000000010211120; + SET_IDREG(isar, ID_AA64ISAR0, 0x0000000010211120); cpu->isar.id_aa64isar1 = 0x0000000000010001; - cpu->isar.id_aa64zfr0 = 0x0000000000000000; + SET_IDREG(isar, ID_AA64ZFR0, 0x0000000000000000); cpu->clidr = 0x0000000080000023; cpu->ccsidr[0] = 0x7007e01c; /* 64KB L1 dcache */ cpu->ccsidr[1] = 0x2007e01c; /* 64KB L1 icache */ @@ -587,6 +592,7 @@ static void define_neoverse_v1_cp_reginfo(ARMCPU *cpu) static void aarch64_neoverse_n1_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,neoverse-n1"; set_feature(&cpu->env, ARM_FEATURE_V8); @@ -603,7 +609,7 @@ static void aarch64_neoverse_n1_initfn(Object *obj) cpu->ctr = 0x8444c004; cpu->dcz_blocksize = 4; cpu->isar.id_aa64dfr0 = 0x0000000110305408ull; - cpu->isar.id_aa64isar0 = 0x0000100010211120ull; + SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull); cpu->isar.id_aa64isar1 = 0x0000000000100001ull; cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull; cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; @@ -658,6 +664,7 @@ static void aarch64_neoverse_n1_initfn(Object *obj) static void aarch64_neoverse_v1_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,neoverse-v1"; set_feature(&cpu->env, ARM_FEATURE_V8); @@ -677,7 +684,7 @@ static void aarch64_neoverse_v1_initfn(Object *obj) cpu->id_aa64afr1 = 0x00000000; cpu->isar.id_aa64dfr0 = 0x000001f210305519ull; cpu->isar.id_aa64dfr1 = 0x00000000; - cpu->isar.id_aa64isar0 = 0x1011111110212120ull; /* with FEAT_RNG */ + SET_IDREG(isar, ID_AA64ISAR0, 0x1011111110212120ull); /* with FEAT_RNG */ cpu->isar.id_aa64isar1 = 0x0111000001211032ull; cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull; cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; @@ -733,7 +740,7 @@ static void aarch64_neoverse_v1_initfn(Object *obj) cpu->isar.mvfr2 = 0x00000043; /* From 3.7.5 ID_AA64ZFR0_EL1 */ - cpu->isar.id_aa64zfr0 = 0x0000100000100000; + SET_IDREG(isar, ID_AA64ZFR0, 0x0000100000100000); cpu->sve_vq.supported = (1 << 0) /* 128bit */ | (1 << 1); /* 256bit */ @@ -880,6 +887,7 @@ static const ARMCPRegInfo cortex_a710_cp_reginfo[] = { static void aarch64_a710_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,cortex-a710"; set_feature(&cpu->env, ARM_FEATURE_V8); @@ -916,12 +924,12 @@ static void aarch64_a710_initfn(Object *obj) cpu->isar.id_pfr2 = 0x00000011; cpu->isar.id_aa64pfr0 = 0x1201111120111112ull; /* GIC filled in later */ cpu->isar.id_aa64pfr1 = 0x0000000000000221ull; - cpu->isar.id_aa64zfr0 = 0x0000110100110021ull; /* with Crypto */ + SET_IDREG(isar, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */ cpu->isar.id_aa64dfr0 = 0x000011f010305619ull; cpu->isar.id_aa64dfr1 = 0; cpu->id_aa64afr0 = 0; cpu->id_aa64afr1 = 0; - cpu->isar.id_aa64isar0 = 0x0221111110212120ull; /* with Crypto */ + SET_IDREG(isar, ID_AA64ISAR0, 0x0221111110212120ull); /* with Crypto */ cpu->isar.id_aa64isar1 = 0x0010111101211052ull; cpu->isar.id_aa64mmfr0 = 0x0000022200101122ull; cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; @@ -977,6 +985,7 @@ static const ARMCPRegInfo neoverse_n2_cp_reginfo[] = { static void aarch64_neoverse_n2_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,neoverse-n2"; set_feature(&cpu->env, ARM_FEATURE_V8); @@ -1013,12 +1022,12 @@ static void aarch64_neoverse_n2_initfn(Object *obj) cpu->isar.id_pfr2 = 0x00000011; cpu->isar.id_aa64pfr0 = 0x1201111120111112ull; /* GIC filled in later */ cpu->isar.id_aa64pfr1 = 0x0000000000000221ull; - cpu->isar.id_aa64zfr0 = 0x0000110100110021ull; /* with Crypto */ + SET_IDREG(isar, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */ cpu->isar.id_aa64dfr0 = 0x000011f210305619ull; cpu->isar.id_aa64dfr1 = 0; cpu->id_aa64afr0 = 0; cpu->id_aa64afr1 = 0; - cpu->isar.id_aa64isar0 = 0x1221111110212120ull; /* with Crypto and FEAT_RNG */ + SET_IDREG(isar, ID_AA64ISAR0, 0x1221111110212120ull); /* with Crypto and FEAT_RNG */ cpu->isar.id_aa64isar1 = 0x0011111101211052ull; cpu->isar.id_aa64mmfr0 = 0x0000022200101125ull; cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; @@ -1074,6 +1083,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj) void aarch64_max_tcg_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; uint64_t t; uint32_t u; @@ -1105,7 +1115,7 @@ void aarch64_max_tcg_initfn(Object *obj) u = FIELD_DP32(u, CLIDR_EL1, LOUU, 0); cpu->clidr = u; - t = cpu->isar.id_aa64isar0; + t = GET_IDREG(isar, ID_AA64ISAR0); t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* FEAT_PMULL */ t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); /* FEAT_SHA1 */ t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* FEAT_SHA512 */ @@ -1120,7 +1130,7 @@ void aarch64_max_tcg_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* FEAT_FlagM2 */ t = FIELD_DP64(t, ID_AA64ISAR0, TLB, 2); /* FEAT_TLBIRANGE */ t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1); /* FEAT_RNG */ - cpu->isar.id_aa64isar0 = t; + SET_IDREG(isar, ID_AA64ISAR0, t); t = cpu->isar.id_aa64isar1; t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); /* FEAT_DPB2 */ @@ -1204,7 +1214,7 @@ void aarch64_max_tcg_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64MMFR2, E0PD, 1); /* FEAT_E0PD */ cpu->isar.id_aa64mmfr2 = t; - t = cpu->isar.id_aa64zfr0; + t = GET_IDREG(isar, ID_AA64ZFR0); t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1); t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* FEAT_SVE_PMULL128 */ t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1); /* FEAT_SVE_BitPerm */ @@ -1214,7 +1224,7 @@ void aarch64_max_tcg_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1); /* FEAT_I8MM */ t = FIELD_DP64(t, ID_AA64ZFR0, F32MM, 1); /* FEAT_F32MM */ t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1); /* FEAT_F64MM */ - cpu->isar.id_aa64zfr0 = t; + SET_IDREG(isar, ID_AA64ZFR0, t); t = cpu->isar.id_aa64dfr0; t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 9); /* FEAT_Debugv8p4 */ -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Sebastian Ott <sebott@redhat.com> Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/cpu-features.h | 36 ++++++++++++++++++------------------ target/arm/cpu.c | 13 ++++--------- target/arm/cpu.h | 2 -- target/arm/cpu64.c | 9 +++++---- target/arm/helper.c | 4 ++-- target/arm/hvf/hvf.c | 2 +- target/arm/kvm64.c | 6 ++---- target/arm/tcg/cpu64.c | 24 ++++++++++++------------ 8 files changed, 44 insertions(+), 52 deletions(-) diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index b9ece5f03a..06f3666d07 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -464,12 +464,12 @@ static inline bool isar_feature_aa64_tlbios(const ARMISARegisters *id) static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR1, JSCVT) != 0; } static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR1, FCMA) != 0; } /* @@ -493,9 +493,9 @@ isar_feature_pauth_feature(const ARMISARegisters *id) * Architecturally, only one of {APA,API,APA3} may be active (non-zero) * and the other two must be zero. Thus we may avoid conditionals. */ - return (FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) | - FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, API) | - FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, APA3)); + return (FIELD_EX64_IDREG(id, ID_AA64ISAR1, APA) | + FIELD_EX64_IDREG(id, ID_AA64ISAR1, API) | + FIELD_EX64_IDREG(id, ID_AA64ISAR2, APA3)); } static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id) @@ -513,7 +513,7 @@ static inline bool isar_feature_aa64_pauth_qarma5(const ARMISARegisters *id) * Return true if pauth is enabled with the architected QARMA5 algorithm. * QEMU will always enable or disable both APA and GPA. */ - return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR1, APA) != 0; } static inline bool isar_feature_aa64_pauth_qarma3(const ARMISARegisters *id) @@ -522,62 +522,62 @@ static inline bool isar_feature_aa64_pauth_qarma3(const ARMISARegisters *id) * Return true if pauth is enabled with the architected QARMA3 algorithm. * QEMU will always enable or disable both APA3 and GPA3. */ - return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, APA3) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR2, APA3) != 0; } static inline bool isar_feature_aa64_sb(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR1, SB) != 0; } static inline bool isar_feature_aa64_predinv(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SPECRES) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR1, SPECRES) != 0; } static inline bool isar_feature_aa64_frint(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR1, FRINTTS) != 0; } static inline bool isar_feature_aa64_dcpop(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR1, DPB) != 0; } static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2; + return FIELD_EX64_IDREG(id, ID_AA64ISAR1, DPB) >= 2; } static inline bool isar_feature_aa64_bf16(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, BF16) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR1, BF16) != 0; } static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR1, LRCPC) != 0; } static inline bool isar_feature_aa64_rcpc_8_4(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) >= 2; + return FIELD_EX64_IDREG(id, ID_AA64ISAR1, LRCPC) >= 2; } static inline bool isar_feature_aa64_i8mm(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, I8MM) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR1, I8MM) != 0; } static inline bool isar_feature_aa64_hbc(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, BC) != 0; + return FIELD_EX64_IDREG(id, ID_AA64ISAR2, BC) != 0; } static inline bool isar_feature_aa64_mops(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, MOPS); + return FIELD_EX64_IDREG(id, ID_AA64ISAR2, MOPS); } static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 262c5017d2..a61f081ec5 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1964,9 +1964,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) uint64_t t; uint32_t u; - t = cpu->isar.id_aa64isar1; - t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 0); - cpu->isar.id_aa64isar1 = t; + FIELD_DP64_IDREG(isar, ID_AA64ISAR1, JSCVT, 0); t = cpu->isar.id_aa64pfr0; t = FIELD_DP64(t, ID_AA64PFR0, FP, 0xf); @@ -2019,11 +2017,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) t = FIELD_DP64(t, ID_AA64ISAR0, DP, 0); SET_IDREG(isar, ID_AA64ISAR0, t); - t = cpu->isar.id_aa64isar1; + t = GET_IDREG(isar, ID_AA64ISAR1); t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 0); t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 0); t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 0); - cpu->isar.id_aa64isar1 = t; + SET_IDREG(isar, ID_AA64ISAR1, t); t = cpu->isar.id_aa64pfr0; t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 0xf); @@ -2059,14 +2057,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) } if (!cpu->has_neon && !cpu->has_vfp) { - uint64_t t; uint32_t u; FIELD_DP64_IDREG(isar, ID_AA64ISAR0, FHM, 0); - t = cpu->isar.id_aa64isar1; - t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 0); - cpu->isar.id_aa64isar1 = t; + FIELD_DP64_IDREG(isar, ID_AA64ISAR1, FRINTTS, 0); u = cpu->isar.mvfr0; u = FIELD_DP32(u, MVFR0, SIMDREG, 0); diff --git a/target/arm/cpu.h b/target/arm/cpu.h index b6e988e570..fa5a916c92 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1082,8 +1082,6 @@ struct ArchCPU { uint32_t dbgdidr; uint32_t dbgdevid; uint32_t dbgdevid1; - uint64_t id_aa64isar1; - uint64_t id_aa64isar2; uint64_t id_aa64pfr0; uint64_t id_aa64pfr1; uint64_t id_aa64mmfr0; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 4d31d34591..b646c7bdeb 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -502,6 +502,7 @@ void aarch64_add_sme_properties(Object *obj) void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) { ARMPauthFeature features = cpu_isar_feature(pauth_feature, cpu); + ARMISARegisters *isar = &cpu->isar; uint64_t isar1, isar2; /* @@ -512,13 +513,13 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) * * Begin by disabling all fields. */ - isar1 = cpu->isar.id_aa64isar1; + isar1 = GET_IDREG(isar, ID_AA64ISAR1); isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, APA, 0); isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPA, 0); isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, API, 0); isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPI, 0); - isar2 = cpu->isar.id_aa64isar2; + isar2 = GET_IDREG(isar, ID_AA64ISAR2); isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, APA3, 0); isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, GPA3, 0); @@ -565,8 +566,8 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) } } - cpu->isar.id_aa64isar1 = isar1; - cpu->isar.id_aa64isar2 = isar2; + SET_IDREG(isar, ID_AA64ISAR1, isar1); + SET_IDREG(isar, ID_AA64ISAR2, isar2); } static Property arm_cpu_pauth_property = diff --git a/target/arm/helper.c b/target/arm/helper.c index 02c0033712..6758e82440 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8460,12 +8460,12 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, - .resetvalue = cpu->isar.id_aa64isar1 }, + .resetvalue = GET_IDREG(isar, ID_AA64ISAR1)}, { .name = "ID_AA64ISAR2_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, - .resetvalue = cpu->isar.id_aa64isar2 }, + .resetvalue = GET_IDREG(isar, ID_AA64ISAR2)}, { .name = "ID_AA64ISAR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 3, .access = PL1_R, .type = ARM_CP_CONST, diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index 3953e6257d..80c1e36d10 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -847,7 +847,7 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) { HV_SYS_REG_ID_AA64DFR0_EL1, &host_isar.id_aa64dfr0 }, { HV_SYS_REG_ID_AA64DFR1_EL1, &host_isar.id_aa64dfr1 }, { HV_SYS_REG_ID_AA64ISAR0_EL1, &host_isar.idregs[ID_AA64ISAR0_EL1_IDX] }, - { HV_SYS_REG_ID_AA64ISAR1_EL1, &host_isar.id_aa64isar1 }, + { HV_SYS_REG_ID_AA64ISAR1_EL1, &host_isar.idregs[ID_AA64ISAR1_EL1_IDX] }, /* Add ID_AA64ISAR2_EL1 here when HVF supports it */ { HV_SYS_REG_ID_AA64MMFR0_EL1, &host_isar.id_aa64mmfr0 }, { HV_SYS_REG_ID_AA64MMFR1_EL1, &host_isar.id_aa64mmfr1 }, diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index f47a5be3ac..5ff37ab24d 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -365,10 +365,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr1, ARM64_SYS_REG(3, 0, 0, 5, 1)); err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR0_EL1_IDX); - err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1, - ARM64_SYS_REG(3, 0, 0, 6, 1)); - err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar2, - ARM64_SYS_REG(3, 0, 0, 6, 2)); + err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR1_EL1_IDX); + err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR2_EL1_IDX); err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr0, ARM64_SYS_REG(3, 0, 0, 7, 0)); err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1, diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c index 2515026ce5..a62d735029 100644 --- a/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c @@ -93,7 +93,7 @@ static void aarch64_a35_initfn(Object *obj) cpu->isar.id_aa64dfr0 = 0x10305106; cpu->isar.id_aa64dfr1 = 0; SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); - cpu->isar.id_aa64isar1 = 0; + SET_IDREG(isar, ID_AA64ISAR1, 0); cpu->isar.id_aa64mmfr0 = 0x00101122; cpu->isar.id_aa64mmfr1 = 0; cpu->clidr = 0x0a200023; @@ -245,7 +245,7 @@ static void aarch64_a55_initfn(Object *obj) cpu->dcz_blocksize = 4; /* 64 bytes */ cpu->isar.id_aa64dfr0 = 0x0000000010305408ull; SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull); - cpu->isar.id_aa64isar1 = 0x0000000000100001ull; + SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000100001ull); cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull; cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull; @@ -370,7 +370,7 @@ static void aarch64_a76_initfn(Object *obj) cpu->dcz_blocksize = 4; cpu->isar.id_aa64dfr0 = 0x0000000010305408ull; SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull); - cpu->isar.id_aa64isar1 = 0x0000000000100001ull; + SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000100001ull); cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull; cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull; @@ -446,7 +446,7 @@ static void aarch64_a64fx_initfn(Object *obj) cpu->isar.id_aa64mmfr1 = 0x0000000011212100; cpu->isar.id_aa64mmfr2 = 0x0000000000001011; SET_IDREG(isar, ID_AA64ISAR0, 0x0000000010211120); - cpu->isar.id_aa64isar1 = 0x0000000000010001; + SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000010001); SET_IDREG(isar, ID_AA64ZFR0, 0x0000000000000000); cpu->clidr = 0x0000000080000023; cpu->ccsidr[0] = 0x7007e01c; /* 64KB L1 dcache */ @@ -610,7 +610,7 @@ static void aarch64_neoverse_n1_initfn(Object *obj) cpu->dcz_blocksize = 4; cpu->isar.id_aa64dfr0 = 0x0000000110305408ull; SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull); - cpu->isar.id_aa64isar1 = 0x0000000000100001ull; + SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000100001ull); cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull; cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull; @@ -685,7 +685,7 @@ static void aarch64_neoverse_v1_initfn(Object *obj) cpu->isar.id_aa64dfr0 = 0x000001f210305519ull; cpu->isar.id_aa64dfr1 = 0x00000000; SET_IDREG(isar, ID_AA64ISAR0, 0x1011111110212120ull); /* with FEAT_RNG */ - cpu->isar.id_aa64isar1 = 0x0111000001211032ull; + SET_IDREG(&cpu->isar, ID_AA64ISAR1, 0x0111000001211032ull); cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull; cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; cpu->isar.id_aa64mmfr2 = 0x0220011102101011ull; @@ -930,7 +930,7 @@ static void aarch64_a710_initfn(Object *obj) cpu->id_aa64afr0 = 0; cpu->id_aa64afr1 = 0; SET_IDREG(isar, ID_AA64ISAR0, 0x0221111110212120ull); /* with Crypto */ - cpu->isar.id_aa64isar1 = 0x0010111101211052ull; + SET_IDREG(isar, ID_AA64ISAR1, 0x0010111101211052ull); cpu->isar.id_aa64mmfr0 = 0x0000022200101122ull; cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; cpu->isar.id_aa64mmfr2 = 0x1221011110101011ull; @@ -1028,7 +1028,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj) cpu->id_aa64afr0 = 0; cpu->id_aa64afr1 = 0; SET_IDREG(isar, ID_AA64ISAR0, 0x1221111110212120ull); /* with Crypto and FEAT_RNG */ - cpu->isar.id_aa64isar1 = 0x0011111101211052ull; + SET_IDREG(isar, ID_AA64ISAR1, 0x0011111101211052ull); cpu->isar.id_aa64mmfr0 = 0x0000022200101125ull; cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; cpu->isar.id_aa64mmfr2 = 0x1221011112101011ull; @@ -1132,7 +1132,7 @@ void aarch64_max_tcg_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1); /* FEAT_RNG */ SET_IDREG(isar, ID_AA64ISAR0, t); - t = cpu->isar.id_aa64isar1; + t = GET_IDREG(isar, ID_AA64ISAR1); t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); /* FEAT_DPB2 */ t = FIELD_DP64(t, ID_AA64ISAR1, APA, PauthFeat_FPACCOMBINED); t = FIELD_DP64(t, ID_AA64ISAR1, API, 1); @@ -1145,12 +1145,12 @@ void aarch64_max_tcg_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1); /* FEAT_BF16 */ t = FIELD_DP64(t, ID_AA64ISAR1, DGH, 1); /* FEAT_DGH */ t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1); /* FEAT_I8MM */ - cpu->isar.id_aa64isar1 = t; + SET_IDREG(&cpu->isar, ID_AA64ISAR1, t); - t = cpu->isar.id_aa64isar2; + t = GET_IDREG(isar, ID_AA64ISAR2); t = FIELD_DP64(t, ID_AA64ISAR2, MOPS, 1); /* FEAT_MOPS */ t = FIELD_DP64(t, ID_AA64ISAR2, BC, 1); /* FEAT_HBC */ - cpu->isar.id_aa64isar2 = t; + SET_IDREG(&cpu->isar, ID_AA64ISAR2, t); t = cpu->isar.id_aa64pfr0; t = FIELD_DP64(t, ID_AA64PFR0, FP, 1); /* FEAT_FP16 */ -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Sebastian Ott <sebott@redhat.com> Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/cpu-features.h | 38 +++++++++++++++---------------- target/arm/cpu.c | 27 +++++++--------------- target/arm/cpu.h | 2 -- target/arm/cpu64.c | 18 +++++---------- target/arm/helper.c | 6 ++--- target/arm/hvf/hvf.c | 6 ++--- target/arm/kvm64.c | 12 +++++----- target/arm/tcg/cpu64.c | 47 ++++++++++++++++++--------------------- 8 files changed, 66 insertions(+), 90 deletions(-) diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index 06f3666d07..d3935981d1 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -583,68 +583,68 @@ static inline bool isar_feature_aa64_mops(const ARMISARegisters *id) static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id) { /* We always set the AdvSIMD and FP fields identically. */ - return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) != 0xf; + return FIELD_EX64_IDREG(id, ID_AA64PFR0, FP) != 0xf; } static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id) { /* We always set the AdvSIMD and FP fields identically wrt FP16. */ - return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1; + return FIELD_EX64_IDREG(id, ID_AA64PFR0, FP) == 1; } static inline bool isar_feature_aa64_aa32(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL0) >= 2; + return FIELD_EX64_IDREG(id, 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; + return FIELD_EX64_IDREG(id, ID_AA64PFR0, EL1) >= 2; } static inline bool isar_feature_aa64_aa32_el2(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL2) >= 2; + return FIELD_EX64_IDREG(id, ID_AA64PFR0, EL2) >= 2; } static inline bool isar_feature_aa64_ras(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RAS) != 0; + return FIELD_EX64_IDREG(id, ID_AA64PFR0, RAS) != 0; } static inline bool isar_feature_aa64_doublefault(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RAS) >= 2; + return FIELD_EX64_IDREG(id, ID_AA64PFR0, RAS) >= 2; } static inline bool isar_feature_aa64_sve(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0; + return FIELD_EX64_IDREG(id, ID_AA64PFR0, SVE) != 0; } static inline bool isar_feature_aa64_sel2(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SEL2) != 0; + return FIELD_EX64_IDREG(id, ID_AA64PFR0, SEL2) != 0; } static inline bool isar_feature_aa64_rme(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RME) != 0; + return FIELD_EX64_IDREG(id, ID_AA64PFR0, RME) != 0; } static inline bool isar_feature_aa64_dit(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0; + return FIELD_EX64_IDREG(id, ID_AA64PFR0, DIT) != 0; } static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id) { - int key = FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, CSV2); + int key = FIELD_EX64_IDREG(id, ID_AA64PFR0, CSV2); if (key >= 2) { return true; /* FEAT_CSV2_2 */ } if (key == 1) { - key = FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, CSV2_FRAC); + key = FIELD_EX64_IDREG(id, ID_AA64PFR1, CSV2_FRAC); return key >= 2; /* FEAT_CSV2_1p2 */ } return false; @@ -652,32 +652,32 @@ static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id) static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0; + return FIELD_EX64_IDREG(id, ID_AA64PFR1, SSBS) != 0; } static inline bool isar_feature_aa64_bti(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0; + return FIELD_EX64_IDREG(id, ID_AA64PFR1, BT) != 0; } static inline bool isar_feature_aa64_mte_insn_reg(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) != 0; + return FIELD_EX64_IDREG(id, ID_AA64PFR1, MTE) != 0; } static inline bool isar_feature_aa64_mte(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) >= 2; + return FIELD_EX64_IDREG(id, ID_AA64PFR1, MTE) >= 2; } static inline bool isar_feature_aa64_mte3(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) >= 3; + return FIELD_EX64_IDREG(id, ID_AA64PFR1, MTE) >= 3; } static inline bool isar_feature_aa64_sme(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SME) != 0; + return FIELD_EX64_IDREG(id, ID_AA64PFR1, SME) != 0; } static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index a61f081ec5..f708782d00 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1961,14 +1961,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) } if (!cpu->has_vfp) { - uint64_t t; uint32_t u; FIELD_DP64_IDREG(isar, ID_AA64ISAR1, JSCVT, 0); - t = cpu->isar.id_aa64pfr0; - t = FIELD_DP64(t, ID_AA64PFR0, FP, 0xf); - cpu->isar.id_aa64pfr0 = t; + FIELD_DP64_IDREG(isar, ID_AA64PFR0, FP, 0xf); u = cpu->isar.id_isar6; u = FIELD_DP32(u, ID_ISAR6, JSCVT, 0); @@ -2023,9 +2020,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 0); SET_IDREG(isar, ID_AA64ISAR1, t); - t = cpu->isar.id_aa64pfr0; - t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 0xf); - cpu->isar.id_aa64pfr0 = t; + FIELD_DP64_IDREG(isar, ID_AA64PFR0, ADVSIMD, 0xf); u = cpu->isar.id_isar5; u = FIELD_DP32(u, ID_ISAR5, AES, 0); @@ -2159,12 +2154,10 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) */ cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1, ID_PFR1, SECURITY, 0); cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPSDBG, 0); - cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0, - ID_AA64PFR0, EL3, 0); + FIELD_DP64_IDREG(isar, ID_AA64PFR0, EL3, 0); /* Disable the realm management extension, which requires EL3. */ - cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0, - ID_AA64PFR0, RME, 0); + FIELD_DP64_IDREG(isar, ID_AA64PFR0, RME, 0); } if (!cpu->has_el2) { @@ -2199,8 +2192,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) * Disable the hypervisor feature bits in the processor feature * registers if we don't have EL2. */ - cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0, - ID_AA64PFR0, EL2, 0); + FIELD_DP64_IDREG(isar, ID_AA64PFR0, EL2, 0); cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1, ID_PFR1, VIRTUALIZATION, 0); } @@ -2221,8 +2213,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) * This matches Cortex-A710 BROADCASTMTE input being LOW. */ if (cpu->tag_memory == NULL) { - cpu->isar.id_aa64pfr1 = - FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 1); + FIELD_DP64_IDREG(isar, ID_AA64PFR1, MTE, 1); } #endif } @@ -2254,13 +2245,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, MMAPTRC, 0); /* FEAT_AMU (Activity Monitors Extension) */ - cpu->isar.id_aa64pfr0 = - FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, AMU, 0); + FIELD_DP64_IDREG(isar, ID_AA64PFR0, AMU, 0); cpu->isar.id_pfr0 = FIELD_DP32(cpu->isar.id_pfr0, ID_PFR0, AMU, 0); /* FEAT_MPAM (Memory Partitioning and Monitoring Extension) */ - cpu->isar.id_aa64pfr0 = - FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, MPAM, 0); + FIELD_DP64_IDREG(isar, ID_AA64PFR0, MPAM, 0); /* FEAT_NV (Nested Virtualization) */ cpu->isar.id_aa64mmfr2 = FIELD_DP64(cpu->isar.id_aa64mmfr2, ID_AA64MMFR2, NV, 0); diff --git a/target/arm/cpu.h b/target/arm/cpu.h index fa5a916c92..057d669075 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1082,8 +1082,6 @@ struct ArchCPU { uint32_t dbgdidr; uint32_t dbgdevid; uint32_t dbgdevid1; - uint64_t id_aa64pfr0; - uint64_t id_aa64pfr1; uint64_t id_aa64mmfr0; uint64_t id_aa64mmfr1; uint64_t id_aa64mmfr2; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index b646c7bdeb..2c03735a93 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -310,16 +310,13 @@ static bool cpu_arm_get_sve(Object *obj, Error **errp) static void cpu_arm_set_sve(Object *obj, bool value, Error **errp) { ARMCPU *cpu = ARM_CPU(obj); - uint64_t t; if (value && kvm_enabled() && !kvm_arm_sve_supported()) { error_setg(errp, "'sve' feature not supported by KVM on this host"); return; } - t = cpu->isar.id_aa64pfr0; - t = FIELD_DP64(t, ID_AA64PFR0, SVE, value); - cpu->isar.id_aa64pfr0 = t; + FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR0, SVE, value); } void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp) @@ -370,11 +367,8 @@ static bool cpu_arm_get_sme(Object *obj, Error **errp) static void cpu_arm_set_sme(Object *obj, bool value, Error **errp) { ARMCPU *cpu = ARM_CPU(obj); - uint64_t t; - t = cpu->isar.id_aa64pfr1; - t = FIELD_DP64(t, ID_AA64PFR1, SME, value); - cpu->isar.id_aa64pfr1 = t; + FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR1, SME, value); } static bool cpu_arm_get_sme_fa64(Object *obj, Error **errp) @@ -774,7 +768,7 @@ static void aarch64_a57_initfn(Object *obj) cpu->isar.id_isar4 = 0x00011142; cpu->isar.id_isar5 = 0x00011121; cpu->isar.id_isar6 = 0; - cpu->isar.id_aa64pfr0 = 0x00002222; + SET_IDREG(isar, ID_AA64PFR0, 0x00002222); cpu->isar.id_aa64dfr0 = 0x10305106; SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); cpu->isar.id_aa64mmfr0 = 0x00001124; @@ -832,7 +826,7 @@ static void aarch64_a53_initfn(Object *obj) cpu->isar.id_isar4 = 0x00011142; cpu->isar.id_isar5 = 0x00011121; cpu->isar.id_isar6 = 0; - cpu->isar.id_aa64pfr0 = 0x00002222; + SET_IDREG(isar, ID_AA64PFR0, 0x00002222); cpu->isar.id_aa64dfr0 = 0x10305106; SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */ @@ -888,7 +882,7 @@ static void aarch64_a72_initfn(Object *obj) cpu->isar.id_isar3 = 0x01112131; cpu->isar.id_isar4 = 0x00011142; cpu->isar.id_isar5 = 0x00011121; - cpu->isar.id_aa64pfr0 = 0x00002222; + SET_IDREG(&cpu->isar, ID_AA64PFR0, 0x00002222); cpu->isar.id_aa64dfr0 = 0x10305106; SET_IDREG(&cpu->isar, ID_AA64ISAR0, 0x00011120); cpu->isar.id_aa64mmfr0 = 0x00001124; @@ -917,7 +911,7 @@ static void aarch64_kunpeng_920_initfn(Object *obj) cpu->midr = 0x480fd010; cpu->ctr = 0x84448004; - cpu->isar.id_aa64pfr0 = 0x11001111; + SET_IDREG(&cpu->isar, ID_AA64PFR0, 0x11001111); cpu->isar.id_aa64dfr0 = 0x110305408; SET_IDREG(&cpu->isar, ID_AA64ISAR0, 0x10211120); cpu->isar.id_aa64mmfr0 = 0x101125; diff --git a/target/arm/helper.c b/target/arm/helper.c index 6758e82440..970cc890c0 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -7279,7 +7279,7 @@ static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri) static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri) { ARMCPU *cpu = env_archcpu(env); - uint64_t pfr0 = cpu->isar.id_aa64pfr0; + uint64_t pfr0 = GET_IDREG(&cpu->isar, ID_AA64PFR0); if (env->gicv3state) { pfr0 |= 1 << 24; @@ -8368,7 +8368,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) .access = PL1_R, #ifdef CONFIG_USER_ONLY .type = ARM_CP_CONST, - .resetvalue = cpu->isar.id_aa64pfr0 + .resetvalue = GET_IDREG(isar, ID_AA64PFR0) #else .type = ARM_CP_NO_RAW, .accessfn = access_aa64_tid3, @@ -8380,7 +8380,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, - .resetvalue = cpu->isar.id_aa64pfr1}, + .resetvalue = GET_IDREG(isar, ID_AA64PFR1)}, { .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index 80c1e36d10..9484d057a2 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -842,8 +842,8 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) int reg; uint64_t *val; } regs[] = { - { HV_SYS_REG_ID_AA64PFR0_EL1, &host_isar.id_aa64pfr0 }, - { HV_SYS_REG_ID_AA64PFR1_EL1, &host_isar.id_aa64pfr1 }, + { HV_SYS_REG_ID_AA64PFR0_EL1, &host_isar.idregs[ID_AA64PFR0_EL1_IDX] }, + { HV_SYS_REG_ID_AA64PFR1_EL1, &host_isar.idregs[ID_AA64PFR1_EL1_IDX] }, { HV_SYS_REG_ID_AA64DFR0_EL1, &host_isar.id_aa64dfr0 }, { HV_SYS_REG_ID_AA64DFR1_EL1, &host_isar.id_aa64dfr1 }, { HV_SYS_REG_ID_AA64ISAR0_EL1, &host_isar.idregs[ID_AA64ISAR0_EL1_IDX] }, @@ -892,7 +892,7 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) ahcf->reset_sctlr |= 0x00800000; /* Make sure we don't advertise AArch32 support for EL0/EL1 */ - if ((host_isar.id_aa64pfr0 & 0xff) != 0x11) { + if ((GET_IDREG(&host_isar, ID_AA64PFR0) & 0xff) != 0x11) { return false; } diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 5ff37ab24d..cf61c18bfc 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -334,8 +334,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) ahcf->dtb_compatible = "arm,arm-v8"; int fd = fdarray[2]; - err = read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr0, - ARM64_SYS_REG(3, 0, 0, 4, 0)); + err = get_host_cpu_reg(fd, ahcf, ID_AA64PFR0_EL1_IDX); if (unlikely(err < 0)) { /* * Before v4.15, the kernel only exposed a limited number of system @@ -353,11 +352,10 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) * ??? Either of these sounds like too much effort just * to work around running a modern host kernel. */ - ahcf->isar.id_aa64pfr0 = 0x00000011; /* EL1&0, AArch64 only */ + SET_IDREG(&ahcf->isar, ID_AA64PFR0, 0x00000011); /* EL1&0, AArch64 only */ err = 0; } else { - err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr1, - ARM64_SYS_REG(3, 0, 0, 4, 1)); + err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR1_EL1_IDX); err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64smfr0, ARM64_SYS_REG(3, 0, 0, 4, 5)); err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr0, @@ -435,14 +433,14 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) * arch/arm64/kvm/sys_regs.c:trap_dbgidr() does. * We only do this if the CPU supports AArch32 at EL1. */ - if (FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL1) >= 2) { + if (FIELD_EX32_IDREG(&ahcf->isar, ID_AA64PFR0, EL1) >= 2) { int wrps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, WRPS); int brps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, BRPS); int ctx_cmps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS); int version = 6; /* ARMv8 debug architecture */ bool has_el3 = - !!FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL3); + !!FIELD_EX32_IDREG(&ahcf->isar, ID_AA64PFR0, EL3); uint32_t dbgdidr = 0; dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, WRPS, wrps); diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c index a62d735029..39e319e62a 100644 --- a/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c @@ -88,8 +88,8 @@ static void aarch64_a35_initfn(Object *obj) cpu->isar.id_isar3 = 0x01112131; cpu->isar.id_isar4 = 0x00011142; cpu->isar.id_isar5 = 0x00011121; - cpu->isar.id_aa64pfr0 = 0x00002222; - cpu->isar.id_aa64pfr1 = 0; + SET_IDREG(isar, ID_AA64PFR0, 0x00002222); + SET_IDREG(isar, ID_AA64PFR1, 0); cpu->isar.id_aa64dfr0 = 0x10305106; cpu->isar.id_aa64dfr1 = 0; SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); @@ -180,11 +180,8 @@ static bool cpu_arm_get_rme(Object *obj, Error **errp) static void cpu_arm_set_rme(Object *obj, bool value, Error **errp) { ARMCPU *cpu = ARM_CPU(obj); - uint64_t t; - t = cpu->isar.id_aa64pfr0; - t = FIELD_DP64(t, ID_AA64PFR0, RME, value); - cpu->isar.id_aa64pfr0 = t; + FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR0, RME, value); } static void cpu_max_set_l0gptsz(Object *obj, Visitor *v, const char *name, @@ -249,8 +246,8 @@ static void aarch64_a55_initfn(Object *obj) cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull; cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull; - cpu->isar.id_aa64pfr0 = 0x0000000010112222ull; - cpu->isar.id_aa64pfr1 = 0x0000000000000010ull; + SET_IDREG(isar, ID_AA64PFR0, 0x0000000010112222ull); + SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000010ull); cpu->id_afr0 = 0x00000000; cpu->isar.id_dfr0 = 0x04010088; cpu->isar.id_isar0 = 0x02101110; @@ -329,7 +326,7 @@ static void aarch64_a72_initfn(Object *obj) cpu->isar.id_isar3 = 0x01112131; cpu->isar.id_isar4 = 0x00011142; cpu->isar.id_isar5 = 0x00011121; - cpu->isar.id_aa64pfr0 = 0x00002222; + SET_IDREG(isar, ID_AA64PFR0, 0x00002222); cpu->isar.id_aa64dfr0 = 0x10305106; SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); cpu->isar.id_aa64mmfr0 = 0x00001124; @@ -374,8 +371,8 @@ static void aarch64_a76_initfn(Object *obj) cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull; cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull; - cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; /* GIC filled in later */ - cpu->isar.id_aa64pfr1 = 0x0000000000000010ull; + SET_IDREG(isar, ID_AA64PFR0, 0x1100000010111112ull); /* GIC filled in later */ + SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000010ull); cpu->id_afr0 = 0x00000000; cpu->isar.id_dfr0 = 0x04010088; cpu->isar.id_isar0 = 0x02101110; @@ -436,8 +433,8 @@ static void aarch64_a64fx_initfn(Object *obj) cpu->revidr = 0x00000000; cpu->ctr = 0x86668006; cpu->reset_sctlr = 0x30000180; - cpu->isar.id_aa64pfr0 = 0x0000000101111111; /* No RAS Extensions */ - cpu->isar.id_aa64pfr1 = 0x0000000000000000; + SET_IDREG(isar, ID_AA64PFR0, 0x0000000101111111); /* No RAS Extensions */ + SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000000); cpu->isar.id_aa64dfr0 = 0x0000000010305408; cpu->isar.id_aa64dfr1 = 0x0000000000000000; cpu->id_aa64afr0 = 0x0000000000000000; @@ -614,8 +611,8 @@ static void aarch64_neoverse_n1_initfn(Object *obj) cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull; cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull; - cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; /* GIC filled in later */ - cpu->isar.id_aa64pfr1 = 0x0000000000000020ull; + SET_IDREG(isar, ID_AA64PFR0, 0x1100000010111112ull); /* GIC filled in later */ + SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000020ull); cpu->id_afr0 = 0x00000000; cpu->isar.id_dfr0 = 0x04010088; cpu->isar.id_isar0 = 0x02101110; @@ -689,8 +686,8 @@ static void aarch64_neoverse_v1_initfn(Object *obj) cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull; cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; cpu->isar.id_aa64mmfr2 = 0x0220011102101011ull; - cpu->isar.id_aa64pfr0 = 0x1101110120111112ull; /* GIC filled in later */ - cpu->isar.id_aa64pfr1 = 0x0000000000000020ull; + SET_IDREG(isar, ID_AA64PFR0, 0x1101110120111112ull); /* GIC filled in later */ + SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000020ull); cpu->id_afr0 = 0x00000000; cpu->isar.id_dfr0 = 0x15011099; cpu->isar.id_isar0 = 0x02101110; @@ -922,8 +919,8 @@ static void aarch64_a710_initfn(Object *obj) cpu->isar.mvfr1 = 0x13211111; cpu->isar.mvfr2 = 0x00000043; cpu->isar.id_pfr2 = 0x00000011; - cpu->isar.id_aa64pfr0 = 0x1201111120111112ull; /* GIC filled in later */ - cpu->isar.id_aa64pfr1 = 0x0000000000000221ull; + SET_IDREG(isar, ID_AA64PFR0, 0x1201111120111112ull); /* GIC filled in later */ + SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000221ull); SET_IDREG(isar, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */ cpu->isar.id_aa64dfr0 = 0x000011f010305619ull; cpu->isar.id_aa64dfr1 = 0; @@ -1020,8 +1017,8 @@ static void aarch64_neoverse_n2_initfn(Object *obj) cpu->isar.mvfr1 = 0x13211111; cpu->isar.mvfr2 = 0x00000043; cpu->isar.id_pfr2 = 0x00000011; - cpu->isar.id_aa64pfr0 = 0x1201111120111112ull; /* GIC filled in later */ - cpu->isar.id_aa64pfr1 = 0x0000000000000221ull; + SET_IDREG(isar, ID_AA64PFR0, 0x1201111120111112ull); /* GIC filled in later */ + SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000221ull); SET_IDREG(isar, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */ cpu->isar.id_aa64dfr0 = 0x000011f210305619ull; cpu->isar.id_aa64dfr1 = 0; @@ -1152,7 +1149,7 @@ void aarch64_max_tcg_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64ISAR2, BC, 1); /* FEAT_HBC */ SET_IDREG(&cpu->isar, ID_AA64ISAR2, t); - t = cpu->isar.id_aa64pfr0; + t = GET_IDREG(isar, ID_AA64PFR0); t = FIELD_DP64(t, ID_AA64PFR0, FP, 1); /* FEAT_FP16 */ t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); /* FEAT_FP16 */ t = FIELD_DP64(t, ID_AA64PFR0, RAS, 2); /* FEAT_RASv1p1 + FEAT_DoubleFault */ @@ -1161,9 +1158,9 @@ void aarch64_max_tcg_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */ t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 2); /* FEAT_CSV2_2 */ t = FIELD_DP64(t, ID_AA64PFR0, CSV3, 1); /* FEAT_CSV3 */ - cpu->isar.id_aa64pfr0 = t; + SET_IDREG(isar, ID_AA64PFR0, t); - t = cpu->isar.id_aa64pfr1; + t = GET_IDREG(isar, ID_AA64PFR1); t = FIELD_DP64(t, ID_AA64PFR1, BT, 1); /* FEAT_BTI */ t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2); /* FEAT_SSBS2 */ /* @@ -1175,7 +1172,7 @@ void aarch64_max_tcg_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64PFR1, RAS_FRAC, 0); /* FEAT_RASv1p1 + FEAT_DoubleFault */ t = FIELD_DP64(t, ID_AA64PFR1, SME, 1); /* FEAT_SME */ t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_2 */ - cpu->isar.id_aa64pfr1 = t; + SET_IDREG(isar, ID_AA64PFR1, t); t = cpu->isar.id_aa64mmfr0; t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */ -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Sebastian Ott <sebott@redhat.com> Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/cpu-features.h | 62 +++++++++++++++++++-------------------- target/arm/cpu.c | 3 +- target/arm/cpu.h | 3 -- target/arm/cpu64.c | 12 ++++---- target/arm/helper.c | 6 ++-- target/arm/hvf/hvf.c | 8 ++--- target/arm/kvm64.c | 9 ++---- target/arm/ptw.c | 6 ++-- target/arm/tcg/cpu64.c | 60 ++++++++++++++++++------------------- 9 files changed, 81 insertions(+), 88 deletions(-) diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index d3935981d1..aefde4b057 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -682,162 +682,162 @@ static inline bool isar_feature_aa64_sme(const ARMISARegisters *id) static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id) { - return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1; + return FIELD_SEX64_IDREG(id, ID_AA64MMFR0, TGRAN4) >= 1; } static inline bool isar_feature_aa64_tgran4_2_lpa2(const ARMISARegisters *id) { - unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2); + unsigned t = FIELD_EX64_IDREG(id, ID_AA64MMFR0, TGRAN4_2); return t >= 3 || (t == 0 && isar_feature_aa64_tgran4_lpa2(id)); } static inline bool isar_feature_aa64_tgran16_lpa2(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 2; + return FIELD_EX64_IDREG(id, ID_AA64MMFR0, TGRAN16) >= 2; } static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id) { - unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2); + unsigned t = FIELD_EX64_IDREG(id, ID_AA64MMFR0, TGRAN16_2); return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id)); } static inline bool isar_feature_aa64_tgran4(const ARMISARegisters *id) { - return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 0; + return FIELD_SEX64_IDREG(id, ID_AA64MMFR0, TGRAN4) >= 0; } static inline bool isar_feature_aa64_tgran16(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 1; + return FIELD_EX64_IDREG(id, ID_AA64MMFR0, TGRAN16) >= 1; } static inline bool isar_feature_aa64_tgran64(const ARMISARegisters *id) { - return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64) >= 0; + return FIELD_SEX64_IDREG(id, ID_AA64MMFR0, TGRAN64) >= 0; } static inline bool isar_feature_aa64_tgran4_2(const ARMISARegisters *id) { - unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2); + unsigned t = FIELD_EX64_IDREG(id, ID_AA64MMFR0, TGRAN4_2); return t >= 2 || (t == 0 && isar_feature_aa64_tgran4(id)); } static inline bool isar_feature_aa64_tgran16_2(const ARMISARegisters *id) { - unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2); + unsigned t = FIELD_EX64_IDREG(id, ID_AA64MMFR0, TGRAN16_2); return t >= 2 || (t == 0 && isar_feature_aa64_tgran16(id)); } static inline bool isar_feature_aa64_tgran64_2(const ARMISARegisters *id) { - unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64_2); + unsigned t = FIELD_EX64_IDREG(id, ID_AA64MMFR0, TGRAN64_2); return t >= 2 || (t == 0 && isar_feature_aa64_tgran64(id)); } static inline bool isar_feature_aa64_fgt(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, FGT) != 0; + return FIELD_EX64_IDREG(id, ID_AA64MMFR0, FGT) != 0; } static inline bool isar_feature_aa64_vh(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0; + return FIELD_EX64_IDREG(id, ID_AA64MMFR1, VH) != 0; } static inline bool isar_feature_aa64_lor(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0; + return FIELD_EX64_IDREG(id, ID_AA64MMFR1, LO) != 0; } static inline bool isar_feature_aa64_pan(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) != 0; + return FIELD_EX64_IDREG(id, ID_AA64MMFR1, PAN) != 0; } static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2; + return FIELD_EX64_IDREG(id, ID_AA64MMFR1, PAN) >= 2; } static inline bool isar_feature_aa64_pan3(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 3; + return FIELD_EX64_IDREG(id, ID_AA64MMFR1, PAN) >= 3; } static inline bool isar_feature_aa64_hcx(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HCX) != 0; + return FIELD_EX64_IDREG(id, ID_AA64MMFR1, HCX) != 0; } static inline bool isar_feature_aa64_tidcp1(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, TIDCP1) != 0; + return FIELD_EX64_IDREG(id, ID_AA64MMFR1, TIDCP1) != 0; } static inline bool isar_feature_aa64_hafs(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) != 0; + return FIELD_EX64_IDREG(id, ID_AA64MMFR1, HAFDBS) != 0; } static inline bool isar_feature_aa64_hdbs(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) >= 2; + return FIELD_EX64_IDREG(id, ID_AA64MMFR1, HAFDBS) >= 2; } static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0; + return FIELD_EX64_IDREG(id, ID_AA64MMFR1, XNX) != 0; } static inline bool isar_feature_aa64_uao(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, UAO) != 0; + return FIELD_EX64_IDREG(id, ID_AA64MMFR2, UAO) != 0; } static inline bool isar_feature_aa64_st(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, ST) != 0; + return FIELD_EX64_IDREG(id, ID_AA64MMFR2, ST) != 0; } static inline bool isar_feature_aa64_lse2(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, AT) != 0; + return FIELD_EX64_IDREG(id, ID_AA64MMFR2, AT) != 0; } static inline bool isar_feature_aa64_fwb(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, FWB) != 0; + return FIELD_EX64_IDREG(id, ID_AA64MMFR2, FWB) != 0; } static inline bool isar_feature_aa64_ids(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, IDS) != 0; + return FIELD_EX64_IDREG(id, ID_AA64MMFR2, IDS) != 0; } static inline bool isar_feature_aa64_half_evt(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, EVT) >= 1; + return FIELD_EX64_IDREG(id, ID_AA64MMFR2, EVT) >= 1; } static inline bool isar_feature_aa64_evt(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, EVT) >= 2; + return FIELD_EX64_IDREG(id, ID_AA64MMFR2, EVT) >= 2; } static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0; + return FIELD_EX64_IDREG(id, ID_AA64MMFR2, CCIDX) != 0; } static inline bool isar_feature_aa64_lva(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0; + return FIELD_EX64_IDREG(id, ID_AA64MMFR2, VARANGE) != 0; } static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0; + return FIELD_EX64_IDREG(id, ID_AA64MMFR2, E0PD) != 0; } static inline bool isar_feature_aa64_pmuv3p1(const ARMISARegisters *id) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index f708782d00..7ac964b550 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2251,8 +2251,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) /* FEAT_MPAM (Memory Partitioning and Monitoring Extension) */ FIELD_DP64_IDREG(isar, ID_AA64PFR0, MPAM, 0); /* FEAT_NV (Nested Virtualization) */ - cpu->isar.id_aa64mmfr2 = - FIELD_DP64(cpu->isar.id_aa64mmfr2, ID_AA64MMFR2, NV, 0); + FIELD_DP64_IDREG(isar, ID_AA64MMFR2, NV, 0); } /* MPU can be configured out of a PMSA CPU either by setting has-mpu diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 057d669075..3ef3a6f958 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1082,9 +1082,6 @@ struct ArchCPU { uint32_t dbgdidr; uint32_t dbgdevid; uint32_t dbgdevid1; - uint64_t id_aa64mmfr0; - uint64_t id_aa64mmfr1; - uint64_t id_aa64mmfr2; uint64_t id_aa64dfr0; uint64_t id_aa64dfr1; uint64_t id_aa64smfr0; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 2c03735a93..f980f1efd2 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -722,12 +722,12 @@ void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp) return; } - t = cpu->isar.id_aa64mmfr0; + t = GET_IDREG(&cpu->isar, ID_AA64MMFR0); t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 2); /* 16k pages w/ LPA2 */ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4, 1); /* 4k pages w/ LPA2 */ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 3); /* 16k stage2 w/ LPA2 */ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 3); /* 4k stage2 w/ LPA2 */ - cpu->isar.id_aa64mmfr0 = t; + SET_IDREG(&cpu->isar, ID_AA64MMFR0, t); } static void aarch64_a57_initfn(Object *obj) @@ -771,7 +771,7 @@ static void aarch64_a57_initfn(Object *obj) SET_IDREG(isar, ID_AA64PFR0, 0x00002222); cpu->isar.id_aa64dfr0 = 0x10305106; SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); - cpu->isar.id_aa64mmfr0 = 0x00001124; + SET_IDREG(isar, ID_AA64MMFR0, 0x00001124); cpu->isar.dbgdidr = 0x3516d000; cpu->isar.dbgdevid = 0x01110f13; cpu->isar.dbgdevid1 = 0x2; @@ -829,7 +829,7 @@ static void aarch64_a53_initfn(Object *obj) SET_IDREG(isar, ID_AA64PFR0, 0x00002222); cpu->isar.id_aa64dfr0 = 0x10305106; SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); - cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */ + SET_IDREG(isar, ID_AA64MMFR0, 0x00001122); /* 40 bit physical addr */ cpu->isar.dbgdidr = 0x3516d000; cpu->isar.dbgdevid = 0x00110f13; cpu->isar.dbgdevid1 = 0x1; @@ -885,7 +885,7 @@ static void aarch64_a72_initfn(Object *obj) SET_IDREG(&cpu->isar, ID_AA64PFR0, 0x00002222); cpu->isar.id_aa64dfr0 = 0x10305106; SET_IDREG(&cpu->isar, ID_AA64ISAR0, 0x00011120); - cpu->isar.id_aa64mmfr0 = 0x00001124; + SET_IDREG(&cpu->isar, ID_AA64MMFR0, 0x00001124); cpu->isar.dbgdidr = 0x3516d000; cpu->clidr = 0x0a200023; cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */ @@ -914,7 +914,7 @@ static void aarch64_kunpeng_920_initfn(Object *obj) SET_IDREG(&cpu->isar, ID_AA64PFR0, 0x11001111); cpu->isar.id_aa64dfr0 = 0x110305408; SET_IDREG(&cpu->isar, ID_AA64ISAR0, 0x10211120); - cpu->isar.id_aa64mmfr0 = 0x101125; + SET_IDREG(&cpu->isar, ID_AA64MMFR0, 0x101125); } static void aarch64_host_initfn(Object *obj) diff --git a/target/arm/helper.c b/target/arm/helper.c index 970cc890c0..a44c13b2b0 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8495,17 +8495,17 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, - .resetvalue = cpu->isar.id_aa64mmfr0 }, + .resetvalue = GET_IDREG(isar, ID_AA64MMFR0)}, { .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, - .resetvalue = cpu->isar.id_aa64mmfr1 }, + .resetvalue = GET_IDREG(isar, ID_AA64MMFR1) }, { .name = "ID_AA64MMFR2_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, - .resetvalue = cpu->isar.id_aa64mmfr2 }, + .resetvalue = GET_IDREG(isar, ID_AA64MMFR2) }, { .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3, .access = PL1_R, .type = ARM_CP_CONST, diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index 9484d057a2..7bf5276484 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -849,9 +849,9 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) { HV_SYS_REG_ID_AA64ISAR0_EL1, &host_isar.idregs[ID_AA64ISAR0_EL1_IDX] }, { HV_SYS_REG_ID_AA64ISAR1_EL1, &host_isar.idregs[ID_AA64ISAR1_EL1_IDX] }, /* Add ID_AA64ISAR2_EL1 here when HVF supports it */ - { HV_SYS_REG_ID_AA64MMFR0_EL1, &host_isar.id_aa64mmfr0 }, - { HV_SYS_REG_ID_AA64MMFR1_EL1, &host_isar.id_aa64mmfr1 }, - { HV_SYS_REG_ID_AA64MMFR2_EL1, &host_isar.id_aa64mmfr2 }, + { HV_SYS_REG_ID_AA64MMFR0_EL1, &host_isar.idregs[ID_AA64MMFR0_EL1_IDX] }, + { HV_SYS_REG_ID_AA64MMFR1_EL1, &host_isar.idregs[ID_AA64MMFR1_EL1_IDX] }, + { HV_SYS_REG_ID_AA64MMFR2_EL1, &host_isar.idregs[ID_AA64MMFR2_EL1_IDX] }, }; hv_vcpu_t fd; hv_return_t r = HV_SUCCESS; @@ -987,7 +987,7 @@ int hvf_arch_init_vcpu(CPUState *cpu) /* We're limited to underlying hardware caps, override internal versions */ ret = hv_vcpu_get_sys_reg(cpu->accel->fd, HV_SYS_REG_ID_AA64MMFR0_EL1, - &arm_cpu->isar.id_aa64mmfr0); + &arm_cpu->isar.idregs[ID_AA64MMFR0_EL1_IDX]); assert_hvf_ok(ret); return 0; diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index cf61c18bfc..1d0dc2e2b3 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -365,12 +365,9 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR0_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR1_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR2_EL1_IDX); - err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr0, - ARM64_SYS_REG(3, 0, 0, 7, 0)); - err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1, - ARM64_SYS_REG(3, 0, 0, 7, 1)); - err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr2, - ARM64_SYS_REG(3, 0, 0, 7, 2)); + err |= get_host_cpu_reg(fd, ahcf, ID_AA64MMFR0_EL1_IDX); + err |= get_host_cpu_reg(fd, ahcf, ID_AA64MMFR1_EL1_IDX); + err |= get_host_cpu_reg(fd, ahcf, ID_AA64MMFR2_EL1_IDX); /* * Note that if AArch32 support is not present in the host, diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 1762b058ae..0fe20ddea6 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -100,7 +100,7 @@ unsigned int arm_pamax(ARMCPU *cpu) { if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { unsigned int parange = - FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE); + FIELD_EX64_IDREG(&cpu->isar, ID_AA64MMFR0, PARANGE); /* * id_aa64mmfr0 is a read-only register so values outside of the @@ -313,7 +313,7 @@ static bool granule_protection_check(CPUARMState *env, uint64_t paddress, * physical address size is invalid. */ pps = FIELD_EX64(gpccr, GPCCR, PPS); - if (pps > FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE)) { + if (pps > FIELD_EX64_IDREG(&cpu->isar, ID_AA64MMFR0, PARANGE)) { goto fault_walk; } pps = pamax_map[pps]; @@ -1651,7 +1651,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, * ID_AA64MMFR0 is a read-only register so values outside of the * supported mappings can be considered an implementation error. */ - ps = FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE); + ps = FIELD_EX64_IDREG(&cpu->isar, ID_AA64MMFR0, PARANGE); ps = MIN(ps, param.ps); assert(ps < ARRAY_SIZE(pamax_map)); outputsize = pamax_map[ps]; diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c index 39e319e62a..4805af8409 100644 --- a/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c @@ -94,8 +94,8 @@ static void aarch64_a35_initfn(Object *obj) cpu->isar.id_aa64dfr1 = 0; SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); SET_IDREG(isar, ID_AA64ISAR1, 0); - cpu->isar.id_aa64mmfr0 = 0x00101122; - cpu->isar.id_aa64mmfr1 = 0; + SET_IDREG(isar, ID_AA64MMFR0, 0x00101122); + SET_IDREG(isar, ID_AA64MMFR1, 0); cpu->clidr = 0x0a200023; cpu->dcz_blocksize = 4; @@ -243,9 +243,9 @@ static void aarch64_a55_initfn(Object *obj) cpu->isar.id_aa64dfr0 = 0x0000000010305408ull; SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull); SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000100001ull); - cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull; - cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; - cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull; + SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000101122ull); + SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull); + SET_IDREG(isar, ID_AA64MMFR2, 0x0000000000001011ull); SET_IDREG(isar, ID_AA64PFR0, 0x0000000010112222ull); SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000010ull); cpu->id_afr0 = 0x00000000; @@ -329,7 +329,7 @@ static void aarch64_a72_initfn(Object *obj) SET_IDREG(isar, ID_AA64PFR0, 0x00002222); cpu->isar.id_aa64dfr0 = 0x10305106; SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); - cpu->isar.id_aa64mmfr0 = 0x00001124; + SET_IDREG(isar, ID_AA64MMFR0, 0x00001124); cpu->isar.dbgdidr = 0x3516d000; cpu->isar.dbgdevid = 0x01110f13; cpu->isar.dbgdevid1 = 0x2; @@ -368,9 +368,9 @@ static void aarch64_a76_initfn(Object *obj) cpu->isar.id_aa64dfr0 = 0x0000000010305408ull; SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull); SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000100001ull); - cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull; - cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; - cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull; + SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000101122ull); + SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull); + SET_IDREG(isar, ID_AA64MMFR2, 0x0000000000001011ull); SET_IDREG(isar, ID_AA64PFR0, 0x1100000010111112ull); /* GIC filled in later */ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000010ull); cpu->id_afr0 = 0x00000000; @@ -439,9 +439,9 @@ static void aarch64_a64fx_initfn(Object *obj) cpu->isar.id_aa64dfr1 = 0x0000000000000000; cpu->id_aa64afr0 = 0x0000000000000000; cpu->id_aa64afr1 = 0x0000000000000000; - cpu->isar.id_aa64mmfr0 = 0x0000000000001122; - cpu->isar.id_aa64mmfr1 = 0x0000000011212100; - cpu->isar.id_aa64mmfr2 = 0x0000000000001011; + SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000001122); + SET_IDREG(isar, ID_AA64MMFR1, 0x0000000011212100); + SET_IDREG(isar, ID_AA64MMFR2, 0x0000000000001011); SET_IDREG(isar, ID_AA64ISAR0, 0x0000000010211120); SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000010001); SET_IDREG(isar, ID_AA64ZFR0, 0x0000000000000000); @@ -608,9 +608,9 @@ static void aarch64_neoverse_n1_initfn(Object *obj) cpu->isar.id_aa64dfr0 = 0x0000000110305408ull; SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull); SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000100001ull); - cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull; - cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; - cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull; + SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000101125ull); + SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull); + SET_IDREG(isar, ID_AA64MMFR2, 0x0000000000001011ull); SET_IDREG(isar, ID_AA64PFR0, 0x1100000010111112ull); /* GIC filled in later */ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000020ull); cpu->id_afr0 = 0x00000000; @@ -683,9 +683,9 @@ static void aarch64_neoverse_v1_initfn(Object *obj) cpu->isar.id_aa64dfr1 = 0x00000000; SET_IDREG(isar, ID_AA64ISAR0, 0x1011111110212120ull); /* with FEAT_RNG */ SET_IDREG(&cpu->isar, ID_AA64ISAR1, 0x0111000001211032ull); - cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull; - cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; - cpu->isar.id_aa64mmfr2 = 0x0220011102101011ull; + SET_IDREG(&cpu->isar, ID_AA64MMFR0, 0x0000000000101125ull); + SET_IDREG(&cpu->isar, ID_AA64MMFR1, 0x0000000010212122ull); + SET_IDREG(&cpu->isar, ID_AA64MMFR2, 0x0220011102101011ull); SET_IDREG(isar, ID_AA64PFR0, 0x1101110120111112ull); /* GIC filled in later */ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000020ull); cpu->id_afr0 = 0x00000000; @@ -928,9 +928,9 @@ static void aarch64_a710_initfn(Object *obj) cpu->id_aa64afr1 = 0; SET_IDREG(isar, ID_AA64ISAR0, 0x0221111110212120ull); /* with Crypto */ SET_IDREG(isar, ID_AA64ISAR1, 0x0010111101211052ull); - cpu->isar.id_aa64mmfr0 = 0x0000022200101122ull; - cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; - cpu->isar.id_aa64mmfr2 = 0x1221011110101011ull; + SET_IDREG(isar, ID_AA64MMFR0, 0x0000022200101122ull); + SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull); + SET_IDREG(isar, ID_AA64MMFR2, 0x1221011110101011ull); cpu->clidr = 0x0000001482000023ull; cpu->gm_blocksize = 4; cpu->ctr = 0x000000049444c004ull; @@ -1026,9 +1026,9 @@ static void aarch64_neoverse_n2_initfn(Object *obj) cpu->id_aa64afr1 = 0; SET_IDREG(isar, ID_AA64ISAR0, 0x1221111110212120ull); /* with Crypto and FEAT_RNG */ SET_IDREG(isar, ID_AA64ISAR1, 0x0011111101211052ull); - cpu->isar.id_aa64mmfr0 = 0x0000022200101125ull; - cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull; - cpu->isar.id_aa64mmfr2 = 0x1221011112101011ull; + SET_IDREG(isar, ID_AA64MMFR0, 0x0000022200101125ull); + SET_IDREG(isar, ID_AA64MMFR1, 0x0000000010212122ull); + SET_IDREG(isar, ID_AA64MMFR2, 0x1221011112101011ull); cpu->clidr = 0x0000001482000023ull; cpu->gm_blocksize = 4; cpu->ctr = 0x00000004b444c004ull; @@ -1174,16 +1174,16 @@ void aarch64_max_tcg_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_2 */ SET_IDREG(isar, ID_AA64PFR1, t); - t = cpu->isar.id_aa64mmfr0; + t = GET_IDREG(isar, ID_AA64MMFR0); t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 1); /* 16k pages supported */ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 2); /* 16k stage2 supported */ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN64_2, 2); /* 64k stage2 supported */ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */ t = FIELD_DP64(t, ID_AA64MMFR0, FGT, 1); /* FEAT_FGT */ - cpu->isar.id_aa64mmfr0 = t; + SET_IDREG(isar, ID_AA64MMFR0, t); - t = cpu->isar.id_aa64mmfr1; + t = GET_IDREG(isar, ID_AA64MMFR1); t = FIELD_DP64(t, ID_AA64MMFR1, HAFDBS, 2); /* FEAT_HAFDBS */ t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* FEAT_VMID16 */ t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */ @@ -1194,9 +1194,9 @@ void aarch64_max_tcg_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64MMFR1, ETS, 1); /* FEAT_ETS */ t = FIELD_DP64(t, ID_AA64MMFR1, HCX, 1); /* FEAT_HCX */ t = FIELD_DP64(t, ID_AA64MMFR1, TIDCP1, 1); /* FEAT_TIDCP1 */ - cpu->isar.id_aa64mmfr1 = t; + SET_IDREG(isar, ID_AA64MMFR1, t); - t = cpu->isar.id_aa64mmfr2; + t = GET_IDREG(isar, ID_AA64MMFR2); t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* FEAT_TTCNP */ t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); /* FEAT_UAO */ t = FIELD_DP64(t, ID_AA64MMFR2, IESB, 1); /* FEAT_IESB */ @@ -1209,7 +1209,7 @@ void aarch64_max_tcg_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2); /* FEAT_BBM at level 2 */ t = FIELD_DP64(t, ID_AA64MMFR2, EVT, 2); /* FEAT_EVT */ t = FIELD_DP64(t, ID_AA64MMFR2, E0PD, 1); /* FEAT_E0PD */ - cpu->isar.id_aa64mmfr2 = t; + SET_IDREG(isar, ID_AA64MMFR2, t); t = GET_IDREG(isar, ID_AA64ZFR0); t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1); -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Sebastian Ott <sebott@redhat.com> Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/cpu-features.h | 16 ++++++++-------- target/arm/cpu.c | 15 +++++---------- target/arm/cpu.h | 2 -- target/arm/cpu64.c | 16 ++++++++-------- target/arm/helper.c | 4 ++-- target/arm/hvf/hvf.c | 4 ++-- target/arm/internals.h | 6 +++--- target/arm/kvm-rme.c | 5 +++-- target/arm/kvm.c | 2 +- target/arm/kvm64.c | 12 +++++------- target/arm/tcg/cpu64.c | 32 ++++++++++++++++---------------- 11 files changed, 53 insertions(+), 61 deletions(-) diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index aefde4b057..eea88ea681 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -842,30 +842,30 @@ static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id) static inline bool isar_feature_aa64_pmuv3p1(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 && - FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf; + return FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) >= 4 && + FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) != 0xf; } static inline bool isar_feature_aa64_pmuv3p4(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 && - FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf; + return FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) >= 5 && + FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) != 0xf; } static inline bool isar_feature_aa64_pmuv3p5(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 6 && - FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf; + return FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) >= 6 && + FIELD_EX64_IDREG(id, ID_AA64DFR0, PMUVER) != 0xf; } static inline bool isar_feature_aa64_debugv8p2(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, DEBUGVER) >= 8; + return FIELD_EX64_IDREG(id, ID_AA64DFR0, DEBUGVER) >= 8; } static inline bool isar_feature_aa64_doublelock(const ARMISARegisters *id) { - return FIELD_SEX64(id->id_aa64dfr0, ID_AA64DFR0, DOUBLELOCK) >= 0; + return FIELD_SEX64_IDREG(id, ID_AA64DFR0, DOUBLELOCK) >= 0; } static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 7ac964b550..22c3335522 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2180,8 +2180,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) cpu); #endif } else { - cpu->isar.id_aa64dfr0 = - FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMUVER, 0); + FIELD_DP64_IDREG(isar, ID_AA64DFR0, PMUVER, 0); cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0); cpu->pmceid0 = 0; cpu->pmceid1 = 0; @@ -2226,19 +2225,15 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) * try to access the non-existent system registers for them. */ /* FEAT_SPE (Statistical Profiling Extension) */ - cpu->isar.id_aa64dfr0 = - FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMSVER, 0); + FIELD_DP64_IDREG(isar, ID_AA64DFR0, PMSVER, 0); /* FEAT_TRBE (Trace Buffer Extension) */ - cpu->isar.id_aa64dfr0 = - FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEBUFFER, 0); + FIELD_DP64_IDREG(isar, ID_AA64DFR0, TRACEBUFFER, 0); /* FEAT_TRF (Self-hosted Trace Extension) */ - cpu->isar.id_aa64dfr0 = - FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEFILT, 0); + FIELD_DP64_IDREG(isar, ID_AA64DFR0, TRACEFILT, 0); cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, TRACEFILT, 0); /* Trace Macrocell system register access */ - cpu->isar.id_aa64dfr0 = - FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEVER, 0); + FIELD_DP64_IDREG(isar, ID_AA64DFR0, TRACEVER, 0); cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPTRC, 0); /* Memory mapped trace */ diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 3ef3a6f958..be5587411f 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1082,8 +1082,6 @@ struct ArchCPU { uint32_t dbgdidr; uint32_t dbgdevid; uint32_t dbgdevid1; - uint64_t id_aa64dfr0; - uint64_t id_aa64dfr1; uint64_t id_aa64smfr0; uint64_t reset_pmcr_el0; uint64_t idregs[NUM_ID_IDX]; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index f980f1efd2..d1946909cf 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -602,7 +602,7 @@ static void arm_cpu_get_num_wps(Object *obj, Visitor *v, const char *name, val = cpu->num_wps; if (val == 0) { - val = FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1; + val = FIELD_EX64_IDREG(&cpu->isar, ID_AA64DFR0, BRPS) + 1; } visit_type_uint8(v, name, &val, errp); @@ -613,7 +613,7 @@ static void arm_cpu_set_num_wps(Object *obj, Visitor *v, const char *name, { uint8_t val; ARMCPU *cpu = ARM_CPU(obj); - uint8_t max_wps = FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1; + uint8_t max_wps = FIELD_EX64_IDREG(&cpu->isar, ID_AA64DFR0, WRPS) + 1; if (!visit_type_uint8(v, name, &val, errp)) { return; @@ -635,7 +635,7 @@ static void arm_cpu_get_num_bps(Object *obj, Visitor *v, const char *name, val = cpu->num_bps; if (val == 0) { - val = FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1; + val = FIELD_EX64_IDREG(&cpu->isar, ID_AA64DFR0, BRPS) + 1; } visit_type_uint8(v, name, &val, errp); @@ -646,7 +646,7 @@ static void arm_cpu_set_num_bps(Object *obj, Visitor *v, const char *name, { uint8_t val; ARMCPU *cpu = ARM_CPU(obj); - uint8_t max_bps = FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1; + uint8_t max_bps = FIELD_EX64_IDREG(&cpu->isar, ID_AA64DFR0, BRPS) + 1; if (!visit_type_uint8(v, name, &val, errp)) { return; @@ -769,7 +769,7 @@ static void aarch64_a57_initfn(Object *obj) cpu->isar.id_isar5 = 0x00011121; cpu->isar.id_isar6 = 0; SET_IDREG(isar, ID_AA64PFR0, 0x00002222); - cpu->isar.id_aa64dfr0 = 0x10305106; + SET_IDREG(isar, ID_AA64DFR0, 0x10305106); SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); SET_IDREG(isar, ID_AA64MMFR0, 0x00001124); cpu->isar.dbgdidr = 0x3516d000; @@ -827,7 +827,7 @@ static void aarch64_a53_initfn(Object *obj) cpu->isar.id_isar5 = 0x00011121; cpu->isar.id_isar6 = 0; SET_IDREG(isar, ID_AA64PFR0, 0x00002222); - cpu->isar.id_aa64dfr0 = 0x10305106; + SET_IDREG(isar, ID_AA64DFR0, 0x10305106); SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); SET_IDREG(isar, ID_AA64MMFR0, 0x00001122); /* 40 bit physical addr */ cpu->isar.dbgdidr = 0x3516d000; @@ -883,7 +883,7 @@ static void aarch64_a72_initfn(Object *obj) cpu->isar.id_isar4 = 0x00011142; cpu->isar.id_isar5 = 0x00011121; SET_IDREG(&cpu->isar, ID_AA64PFR0, 0x00002222); - cpu->isar.id_aa64dfr0 = 0x10305106; + SET_IDREG(&cpu->isar, ID_AA64DFR0, 0x10305106); SET_IDREG(&cpu->isar, ID_AA64ISAR0, 0x00011120); SET_IDREG(&cpu->isar, ID_AA64MMFR0, 0x00001124); cpu->isar.dbgdidr = 0x3516d000; @@ -912,7 +912,7 @@ static void aarch64_kunpeng_920_initfn(Object *obj) cpu->midr = 0x480fd010; cpu->ctr = 0x84448004; SET_IDREG(&cpu->isar, ID_AA64PFR0, 0x11001111); - cpu->isar.id_aa64dfr0 = 0x110305408; + SET_IDREG(&cpu->isar, ID_AA64DFR0, 0x110305408); SET_IDREG(&cpu->isar, ID_AA64ISAR0, 0x10211120); SET_IDREG(&cpu->isar, ID_AA64MMFR0, 0x101125); } diff --git a/target/arm/helper.c b/target/arm/helper.c index a44c13b2b0..46f0b4089b 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8415,12 +8415,12 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, - .resetvalue = cpu->isar.id_aa64dfr0 }, + .resetvalue = GET_IDREG(isar, ID_AA64DFR0) }, { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, - .resetvalue = cpu->isar.id_aa64dfr1 }, + .resetvalue = GET_IDREG(isar, ID_AA64DFR1) }, { .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index 7bf5276484..13d72b0bd6 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -844,8 +844,8 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) } regs[] = { { HV_SYS_REG_ID_AA64PFR0_EL1, &host_isar.idregs[ID_AA64PFR0_EL1_IDX] }, { HV_SYS_REG_ID_AA64PFR1_EL1, &host_isar.idregs[ID_AA64PFR1_EL1_IDX] }, - { HV_SYS_REG_ID_AA64DFR0_EL1, &host_isar.id_aa64dfr0 }, - { HV_SYS_REG_ID_AA64DFR1_EL1, &host_isar.id_aa64dfr1 }, + { HV_SYS_REG_ID_AA64DFR0_EL1, &host_isar.idregs[ID_AA64DFR0_EL1_IDX] }, + { HV_SYS_REG_ID_AA64DFR1_EL1, &host_isar.idregs[ID_AA64DFR1_EL1_IDX] }, { HV_SYS_REG_ID_AA64ISAR0_EL1, &host_isar.idregs[ID_AA64ISAR0_EL1_IDX] }, { HV_SYS_REG_ID_AA64ISAR1_EL1, &host_isar.idregs[ID_AA64ISAR1_EL1_IDX] }, /* Add ID_AA64ISAR2_EL1 here when HVF supports it */ diff --git a/target/arm/internals.h b/target/arm/internals.h index efc58c7146..dc0c5d9051 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -831,7 +831,7 @@ static inline bool regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx) static inline int arm_num_brps(ARMCPU *cpu) { if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { - return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1; + return FIELD_EX64_IDREG(&cpu->isar, ID_AA64DFR0, BRPS) + 1; } else { return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, BRPS) + 1; } @@ -845,7 +845,7 @@ static inline int arm_num_brps(ARMCPU *cpu) static inline int arm_num_wrps(ARMCPU *cpu) { if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { - return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1; + return FIELD_EX64_IDREG(&cpu->isar, ID_AA64DFR0, WRPS) + 1; } else { return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, WRPS) + 1; } @@ -859,7 +859,7 @@ static inline int arm_num_wrps(ARMCPU *cpu) static inline int arm_num_ctx_cmps(ARMCPU *cpu) { if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { - return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) + 1; + return FIELD_EX64_IDREG(&cpu->isar, ID_AA64DFR0, CTX_CMPS) + 1; } else { return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, CTX_CMPS) + 1; } diff --git a/target/arm/kvm-rme.c b/target/arm/kvm-rme.c index 26dda39df6..43ff825425 100644 --- a/target/arm/kvm-rme.c +++ b/target/arm/kvm-rme.c @@ -267,8 +267,9 @@ static int rme_log_realm_create(Error **errp) params.flags |= REALM_PARAMS_FLAG_SVE; params.sve_vl = cpu->sve_max_vq - 1; } - params.num_bps = FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS); - params.num_wps = FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS); + + params.num_bps = FIELD_EX64_IDREG(&cpu->isar, ID_AA64DFR0, BRPS); + params.num_wps = FIELD_EX64_IDREG(&cpu->isar, ID_AA64DFR0, WRPS); switch (rme_guest->measurement_algo) { case RME_GUEST_MEASUREMENT_ALGORITHM_SHA256: diff --git a/target/arm/kvm.c b/target/arm/kvm.c index e0b404962d..b6cb525e43 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -692,7 +692,7 @@ static void kvm_arm_configure_aa64dfr0(ARMCPU *cpu) return; } - newval = cpu->isar.id_aa64dfr0; + newval = GET_IDREG(&cpu->isar, ID_AA64DFR0); if (cpu->num_bps) { uint64_t ctx_cmps = FIELD_EX64(newval, ID_AA64DFR0, CTX_CMPS); diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 1d0dc2e2b3..e46afd00bb 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -358,10 +358,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR1_EL1_IDX); err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64smfr0, ARM64_SYS_REG(3, 0, 0, 4, 5)); - err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr0, - KVM_REG_ARM_ID_AA64DFR0_EL1); - err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr1, - ARM64_SYS_REG(3, 0, 0, 5, 1)); + err |= get_host_cpu_reg(fd, ahcf, ID_AA64DFR0_EL1_IDX); + err |= get_host_cpu_reg(fd, ahcf, ID_AA64DFR1_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR0_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR1_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR2_EL1_IDX); @@ -431,10 +429,10 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) * We only do this if the CPU supports AArch32 at EL1. */ if (FIELD_EX32_IDREG(&ahcf->isar, ID_AA64PFR0, EL1) >= 2) { - int wrps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, WRPS); - int brps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, BRPS); + int wrps = FIELD_EX64_IDREG(&ahcf->isar, ID_AA64DFR0, WRPS); + int brps = FIELD_EX64_IDREG(&ahcf->isar, ID_AA64DFR0, BRPS); int ctx_cmps = - FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS); + FIELD_EX64_IDREG(&ahcf->isar, ID_AA64DFR0, CTX_CMPS); int version = 6; /* ARMv8 debug architecture */ bool has_el3 = !!FIELD_EX32_IDREG(&ahcf->isar, ID_AA64PFR0, EL3); diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c index 4805af8409..b0a020c14e 100644 --- a/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c @@ -90,8 +90,8 @@ static void aarch64_a35_initfn(Object *obj) cpu->isar.id_isar5 = 0x00011121; SET_IDREG(isar, ID_AA64PFR0, 0x00002222); SET_IDREG(isar, ID_AA64PFR1, 0); - cpu->isar.id_aa64dfr0 = 0x10305106; - cpu->isar.id_aa64dfr1 = 0; + SET_IDREG(isar, ID_AA64DFR0, 0x10305106); + SET_IDREG(isar, ID_AA64DFR1, 0); SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); SET_IDREG(isar, ID_AA64ISAR1, 0); SET_IDREG(isar, ID_AA64MMFR0, 0x00101122); @@ -240,7 +240,7 @@ static void aarch64_a55_initfn(Object *obj) cpu->clidr = 0x82000023; cpu->ctr = 0x84448004; /* L1Ip = VIPT */ cpu->dcz_blocksize = 4; /* 64 bytes */ - cpu->isar.id_aa64dfr0 = 0x0000000010305408ull; + SET_IDREG(isar, ID_AA64DFR0, 0x0000000010305408ull); SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull); SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000100001ull); SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000101122ull); @@ -327,7 +327,7 @@ static void aarch64_a72_initfn(Object *obj) cpu->isar.id_isar4 = 0x00011142; cpu->isar.id_isar5 = 0x00011121; SET_IDREG(isar, ID_AA64PFR0, 0x00002222); - cpu->isar.id_aa64dfr0 = 0x10305106; + SET_IDREG(isar, ID_AA64DFR0, 0x10305106); SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); SET_IDREG(isar, ID_AA64MMFR0, 0x00001124); cpu->isar.dbgdidr = 0x3516d000; @@ -365,7 +365,7 @@ static void aarch64_a76_initfn(Object *obj) cpu->clidr = 0x82000023; cpu->ctr = 0x8444C004; cpu->dcz_blocksize = 4; - cpu->isar.id_aa64dfr0 = 0x0000000010305408ull; + SET_IDREG(isar, ID_AA64DFR0, 0x0000000010305408ull), SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull); SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000100001ull); SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000101122ull); @@ -435,8 +435,8 @@ static void aarch64_a64fx_initfn(Object *obj) cpu->reset_sctlr = 0x30000180; SET_IDREG(isar, ID_AA64PFR0, 0x0000000101111111); /* No RAS Extensions */ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000000); - cpu->isar.id_aa64dfr0 = 0x0000000010305408; - cpu->isar.id_aa64dfr1 = 0x0000000000000000; + SET_IDREG(isar, ID_AA64DFR0, 0x0000000010305408), + SET_IDREG(isar, ID_AA64DFR1, 0x0000000000000000), cpu->id_aa64afr0 = 0x0000000000000000; cpu->id_aa64afr1 = 0x0000000000000000; SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000001122); @@ -605,7 +605,7 @@ static void aarch64_neoverse_n1_initfn(Object *obj) cpu->clidr = 0x82000023; cpu->ctr = 0x8444c004; cpu->dcz_blocksize = 4; - cpu->isar.id_aa64dfr0 = 0x0000000110305408ull; + SET_IDREG(isar, ID_AA64DFR0, 0x0000000110305408ull); SET_IDREG(isar, ID_AA64ISAR0, 0x0000100010211120ull); SET_IDREG(isar, ID_AA64ISAR1, 0x0000000000100001ull); SET_IDREG(isar, ID_AA64MMFR0, 0x0000000000101125ull); @@ -679,8 +679,8 @@ static void aarch64_neoverse_v1_initfn(Object *obj) cpu->dcz_blocksize = 4; cpu->id_aa64afr0 = 0x00000000; cpu->id_aa64afr1 = 0x00000000; - cpu->isar.id_aa64dfr0 = 0x000001f210305519ull; - cpu->isar.id_aa64dfr1 = 0x00000000; + SET_IDREG(isar, ID_AA64DFR0, 0x000001f210305519ull), + SET_IDREG(isar, ID_AA64DFR1, 0x00000000), SET_IDREG(isar, ID_AA64ISAR0, 0x1011111110212120ull); /* with FEAT_RNG */ SET_IDREG(&cpu->isar, ID_AA64ISAR1, 0x0111000001211032ull); SET_IDREG(&cpu->isar, ID_AA64MMFR0, 0x0000000000101125ull); @@ -922,8 +922,8 @@ static void aarch64_a710_initfn(Object *obj) SET_IDREG(isar, ID_AA64PFR0, 0x1201111120111112ull); /* GIC filled in later */ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000221ull); SET_IDREG(isar, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */ - cpu->isar.id_aa64dfr0 = 0x000011f010305619ull; - cpu->isar.id_aa64dfr1 = 0; + SET_IDREG(isar, ID_AA64DFR0, 0x000011f010305619ull); + SET_IDREG(isar, ID_AA64DFR1, 0); cpu->id_aa64afr0 = 0; cpu->id_aa64afr1 = 0; SET_IDREG(isar, ID_AA64ISAR0, 0x0221111110212120ull); /* with Crypto */ @@ -1020,8 +1020,8 @@ static void aarch64_neoverse_n2_initfn(Object *obj) SET_IDREG(isar, ID_AA64PFR0, 0x1201111120111112ull); /* GIC filled in later */ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000221ull); SET_IDREG(isar, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */ - cpu->isar.id_aa64dfr0 = 0x000011f210305619ull; - cpu->isar.id_aa64dfr1 = 0; + SET_IDREG(isar, ID_AA64DFR0, 0x000011f210305619ull); + SET_IDREG(isar, ID_AA64DFR1, 0); cpu->id_aa64afr0 = 0; cpu->id_aa64afr1 = 0; SET_IDREG(isar, ID_AA64ISAR0, 0x1221111110212120ull); /* with Crypto and FEAT_RNG */ @@ -1223,11 +1223,11 @@ void aarch64_max_tcg_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1); /* FEAT_F64MM */ SET_IDREG(isar, ID_AA64ZFR0, t); - t = cpu->isar.id_aa64dfr0; + t = GET_IDREG(isar, ID_AA64DFR0); t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 9); /* FEAT_Debugv8p4 */ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 6); /* FEAT_PMUv3p5 */ t = FIELD_DP64(t, ID_AA64DFR0, HPMN0, 1); /* FEAT_HPMN0 */ - cpu->isar.id_aa64dfr0 = t; + SET_IDREG(isar, ID_AA64DFR0, t); t = cpu->isar.id_aa64smfr0; t = FIELD_DP64(t, ID_AA64SMFR0, F32F32, 1); /* FEAT_SME */ -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Sebastian Ott <sebott@redhat.com> Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/cpu-features.h | 6 +++--- target/arm/cpu.h | 1 - target/arm/cpu64.c | 7 ++----- target/arm/helper.c | 2 +- target/arm/kvm64.c | 3 +-- target/arm/tcg/cpu64.c | 4 ++-- 6 files changed, 9 insertions(+), 14 deletions(-) diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index eea88ea681..9e73c90cae 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -920,17 +920,17 @@ static inline bool isar_feature_aa64_sve_f64mm(const ARMISARegisters *id) static inline bool isar_feature_aa64_sme_f64f64(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, F64F64); + return FIELD_EX64_IDREG(id, ID_AA64SMFR0, F64F64); } static inline bool isar_feature_aa64_sme_i16i64(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, I16I64) == 0xf; + return FIELD_EX64_IDREG(id, ID_AA64SMFR0, I16I64) == 0xf; } static inline bool isar_feature_aa64_sme_fa64(const ARMISARegisters *id) { - return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, FA64); + return FIELD_EX64_IDREG(id, ID_AA64SMFR0, FA64); } /* diff --git a/target/arm/cpu.h b/target/arm/cpu.h index be5587411f..429b36a248 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1082,7 +1082,6 @@ struct ArchCPU { uint32_t dbgdidr; uint32_t dbgdevid; uint32_t dbgdevid1; - uint64_t id_aa64smfr0; uint64_t reset_pmcr_el0; uint64_t idregs[NUM_ID_IDX]; } isar; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index d1946909cf..686cef8bd0 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -328,7 +328,7 @@ void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp) if (vq_map == 0) { if (!cpu_isar_feature(aa64_sme, cpu)) { - cpu->isar.id_aa64smfr0 = 0; + SET_IDREG(&cpu->isar, ID_AA64SMFR0, 0); return; } @@ -381,11 +381,8 @@ static bool cpu_arm_get_sme_fa64(Object *obj, Error **errp) static void cpu_arm_set_sme_fa64(Object *obj, bool value, Error **errp) { ARMCPU *cpu = ARM_CPU(obj); - uint64_t t; - t = cpu->isar.id_aa64smfr0; - t = FIELD_DP64(t, ID_AA64SMFR0, FA64, value); - cpu->isar.id_aa64smfr0 = t; + FIELD_DP64_IDREG(&cpu->isar, ID_AA64SMFR0, FA64, value); } #ifdef CONFIG_USER_ONLY diff --git a/target/arm/helper.c b/target/arm/helper.c index 46f0b4089b..0ed6c4a37e 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8400,7 +8400,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, - .resetvalue = cpu->isar.id_aa64smfr0 }, + .resetvalue = GET_IDREG(isar, ID_AA64SMFR0)}, { .name = "ID_AA64PFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST, diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index e46afd00bb..b50af4acd9 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -356,8 +356,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) err = 0; } else { err |= get_host_cpu_reg(fd, ahcf, ID_AA64PFR1_EL1_IDX); - err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64smfr0, - ARM64_SYS_REG(3, 0, 0, 4, 5)); + err |= get_host_cpu_reg(fd, ahcf, ID_AA64SMFR0_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_AA64DFR0_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_AA64DFR1_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_AA64ISAR0_EL1_IDX); diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c index b0a020c14e..04deff475e 100644 --- a/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c @@ -1229,7 +1229,7 @@ void aarch64_max_tcg_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64DFR0, HPMN0, 1); /* FEAT_HPMN0 */ SET_IDREG(isar, ID_AA64DFR0, t); - t = cpu->isar.id_aa64smfr0; + t = GET_IDREG(isar, ID_AA64SMFR0); t = FIELD_DP64(t, ID_AA64SMFR0, F32F32, 1); /* FEAT_SME */ t = FIELD_DP64(t, ID_AA64SMFR0, B16F32, 1); /* FEAT_SME */ t = FIELD_DP64(t, ID_AA64SMFR0, F16F32, 1); /* FEAT_SME */ @@ -1237,7 +1237,7 @@ void aarch64_max_tcg_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64SMFR0, F64F64, 1); /* FEAT_SME_F64F64 */ t = FIELD_DP64(t, ID_AA64SMFR0, I16I64, 0xf); /* FEAT_SME_I16I64 */ t = FIELD_DP64(t, ID_AA64SMFR0, FA64, 1); /* FEAT_SME_FA64 */ - cpu->isar.id_aa64smfr0 = t; + SET_IDREG(isar, ID_AA64SMFR0, t); /* Replicate the same data to the 32-bit id registers. */ aa32_max_features(cpu); -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Sebastian Ott <sebott@redhat.com> Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- hw/intc/armv7m_nvic.c | 12 +- target/arm/cpu-features.h | 36 +++--- target/arm/cpu.c | 24 ++-- target/arm/cpu.h | 7 -- target/arm/cpu64.c | 40 +++---- target/arm/helper.c | 14 +-- target/arm/kvm64.c | 21 ++-- target/arm/tcg/cpu32.c | 238 +++++++++++++++++++++----------------- target/arm/tcg/cpu64.c | 108 ++++++++--------- 9 files changed, 252 insertions(+), 248 deletions(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 942be7bd11..5f68b0e711 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -1303,32 +1303,32 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_isar0; + return GET_IDREG(&cpu->isar, ID_ISAR0); case 0xd64: /* ISAR1. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_isar1; + return GET_IDREG(&cpu->isar, ID_ISAR1); case 0xd68: /* ISAR2. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_isar2; + return GET_IDREG(&cpu->isar, ID_ISAR2); case 0xd6c: /* ISAR3. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_isar3; + return GET_IDREG(&cpu->isar, ID_ISAR3); case 0xd70: /* ISAR4. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_isar4; + return GET_IDREG(&cpu->isar, ID_ISAR4); case 0xd74: /* ISAR5. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_isar5; + return GET_IDREG(&cpu->isar, ID_ISAR5); case 0xd78: /* CLIDR */ return cpu->clidr; case 0xd7c: /* CTR */ diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index 9e73c90cae..25180e4b77 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -42,93 +42,93 @@ */ static inline bool isar_feature_aa32_thumb_div(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) != 0; + return FIELD_EX32_IDREG(id, ID_ISAR0, DIVIDE) != 0; } static inline bool isar_feature_aa32_arm_div(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1; + return FIELD_EX32_IDREG(id, ID_ISAR0, DIVIDE) > 1; } static inline bool isar_feature_aa32_lob(const ARMISARegisters *id) { /* (M-profile) low-overhead loops and branch future */ - return FIELD_EX32(id->id_isar0, ID_ISAR0, CMPBRANCH) >= 3; + return FIELD_EX32_IDREG(id, ID_ISAR0, CMPBRANCH) >= 3; } static inline bool isar_feature_aa32_jazelle(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0; + return FIELD_EX32_IDREG(id, ID_ISAR1, JAZELLE) != 0; } static inline bool isar_feature_aa32_aes(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0; + return FIELD_EX32_IDREG(id, ID_ISAR5, AES) != 0; } static inline bool isar_feature_aa32_pmull(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) > 1; + return FIELD_EX32_IDREG(id, ID_ISAR5, AES) > 1; } static inline bool isar_feature_aa32_sha1(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA1) != 0; + return FIELD_EX32_IDREG(id, ID_ISAR5, SHA1) != 0; } static inline bool isar_feature_aa32_sha2(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA2) != 0; + return FIELD_EX32_IDREG(id, ID_ISAR5, SHA2) != 0; } static inline bool isar_feature_aa32_crc32(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar5, ID_ISAR5, CRC32) != 0; + return FIELD_EX32_IDREG(id, ID_ISAR5, CRC32) != 0; } static inline bool isar_feature_aa32_rdm(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar5, ID_ISAR5, RDM) != 0; + return FIELD_EX32_IDREG(id, ID_ISAR5, RDM) != 0; } static inline bool isar_feature_aa32_vcma(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar5, ID_ISAR5, VCMA) != 0; + return FIELD_EX32_IDREG(id, ID_ISAR5, VCMA) != 0; } static inline bool isar_feature_aa32_jscvt(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar6, ID_ISAR6, JSCVT) != 0; + return FIELD_EX32_IDREG(id, ID_ISAR6, JSCVT) != 0; } static inline bool isar_feature_aa32_dp(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar6, ID_ISAR6, DP) != 0; + return FIELD_EX32_IDREG(id, ID_ISAR6, DP) != 0; } static inline bool isar_feature_aa32_fhm(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar6, ID_ISAR6, FHM) != 0; + return FIELD_EX32_IDREG(id, ID_ISAR6, FHM) != 0; } static inline bool isar_feature_aa32_sb(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar6, ID_ISAR6, SB) != 0; + return FIELD_EX32_IDREG(id, ID_ISAR6, SB) != 0; } static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0; + return FIELD_EX32_IDREG(id, ID_ISAR6, SPECRES) != 0; } static inline bool isar_feature_aa32_bf16(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar6, ID_ISAR6, BF16) != 0; + return FIELD_EX32_IDREG(id, ID_ISAR6, BF16) != 0; } static inline bool isar_feature_aa32_i8mm(const ARMISARegisters *id) { - return FIELD_EX32(id->id_isar6, ID_ISAR6, I8MM) != 0; + return FIELD_EX32_IDREG(id, ID_ISAR6, I8MM) != 0; } static inline bool isar_feature_aa32_ras(const ARMISARegisters *id) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 22c3335522..7667530e9d 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1967,10 +1967,10 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) FIELD_DP64_IDREG(isar, ID_AA64PFR0, FP, 0xf); - u = cpu->isar.id_isar6; + u = GET_IDREG(isar, ID_ISAR6); u = FIELD_DP32(u, ID_ISAR6, JSCVT, 0); u = FIELD_DP32(u, ID_ISAR6, BF16, 0); - cpu->isar.id_isar6 = u; + SET_IDREG(isar, ID_ISAR6, u); u = cpu->isar.mvfr0; u = FIELD_DP32(u, MVFR0, FPSP, 0); @@ -2022,20 +2022,20 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) FIELD_DP64_IDREG(isar, ID_AA64PFR0, ADVSIMD, 0xf); - u = cpu->isar.id_isar5; + u = GET_IDREG(isar, ID_ISAR5); u = FIELD_DP32(u, ID_ISAR5, AES, 0); u = FIELD_DP32(u, ID_ISAR5, SHA1, 0); u = FIELD_DP32(u, ID_ISAR5, SHA2, 0); u = FIELD_DP32(u, ID_ISAR5, RDM, 0); u = FIELD_DP32(u, ID_ISAR5, VCMA, 0); - cpu->isar.id_isar5 = u; + SET_IDREG(isar, ID_ISAR5, u); - u = cpu->isar.id_isar6; + u = GET_IDREG(isar, ID_ISAR6); u = FIELD_DP32(u, ID_ISAR6, DP, 0); u = FIELD_DP32(u, ID_ISAR6, FHM, 0); u = FIELD_DP32(u, ID_ISAR6, BF16, 0); u = FIELD_DP32(u, ID_ISAR6, I8MM, 0); - cpu->isar.id_isar6 = u; + SET_IDREG(isar, ID_ISAR6, u); if (!arm_feature(env, ARM_FEATURE_M)) { u = cpu->isar.mvfr1; @@ -2073,19 +2073,17 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) unset_feature(env, ARM_FEATURE_THUMB_DSP); - u = cpu->isar.id_isar1; - u = FIELD_DP32(u, ID_ISAR1, EXTEND, 1); - cpu->isar.id_isar1 = u; + FIELD_DP32_IDREG(isar, ID_ISAR1, EXTEND, 1); - u = cpu->isar.id_isar2; + u = GET_IDREG(isar, ID_ISAR2); u = FIELD_DP32(u, ID_ISAR2, MULTU, 1); u = FIELD_DP32(u, ID_ISAR2, MULTS, 1); - cpu->isar.id_isar2 = u; + SET_IDREG(isar, ID_ISAR2, u); - u = cpu->isar.id_isar3; + u = GET_IDREG(isar, ID_ISAR3); u = FIELD_DP32(u, ID_ISAR3, SIMD, 1); u = FIELD_DP32(u, ID_ISAR3, SATURATE, 0); - cpu->isar.id_isar3 = u; + SET_IDREG(isar, ID_ISAR3, u); } diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 429b36a248..4c29657ec7 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1058,13 +1058,6 @@ struct ArchCPU { * field by reading the value from the KVM vCPU. */ struct ARMISARegisters { - uint32_t id_isar0; - uint32_t id_isar1; - uint32_t id_isar2; - uint32_t id_isar3; - uint32_t id_isar4; - uint32_t id_isar5; - uint32_t id_isar6; uint32_t id_mmfr0; uint32_t id_mmfr1; uint32_t id_mmfr2; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 686cef8bd0..76ba47488f 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -758,13 +758,13 @@ static void aarch64_a57_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x40000000; cpu->isar.id_mmfr2 = 0x01260000; cpu->isar.id_mmfr3 = 0x02102211; - cpu->isar.id_isar0 = 0x02101110; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232042; - cpu->isar.id_isar3 = 0x01112131; - cpu->isar.id_isar4 = 0x00011142; - cpu->isar.id_isar5 = 0x00011121; - cpu->isar.id_isar6 = 0; + SET_IDREG(isar, ID_ISAR0, 0x02101110); + SET_IDREG(isar, ID_ISAR1, 0x13112111); + SET_IDREG(isar, ID_ISAR2, 0x21232042); + SET_IDREG(isar, ID_ISAR3, 0x01112131); + SET_IDREG(isar, ID_ISAR4, 0x00011142); + SET_IDREG(isar, ID_ISAR5, 0x00011121); + SET_IDREG(isar, ID_ISAR6, 0); SET_IDREG(isar, ID_AA64PFR0, 0x00002222); SET_IDREG(isar, ID_AA64DFR0, 0x10305106); SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); @@ -816,13 +816,13 @@ static void aarch64_a53_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x40000000; cpu->isar.id_mmfr2 = 0x01260000; cpu->isar.id_mmfr3 = 0x02102211; - cpu->isar.id_isar0 = 0x02101110; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232042; - cpu->isar.id_isar3 = 0x01112131; - cpu->isar.id_isar4 = 0x00011142; - cpu->isar.id_isar5 = 0x00011121; - cpu->isar.id_isar6 = 0; + SET_IDREG(isar, ID_ISAR0, 0x02101110); + SET_IDREG(isar, ID_ISAR1, 0x13112111); + SET_IDREG(isar, ID_ISAR2, 0x21232042); + SET_IDREG(isar, ID_ISAR3, 0x01112131); + SET_IDREG(isar, ID_ISAR4, 0x00011142); + SET_IDREG(isar, ID_ISAR5, 0x00011121); + SET_IDREG(isar, ID_ISAR6, 0); SET_IDREG(isar, ID_AA64PFR0, 0x00002222); SET_IDREG(isar, ID_AA64DFR0, 0x10305106); SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); @@ -873,12 +873,12 @@ static void aarch64_a72_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x40000000; cpu->isar.id_mmfr2 = 0x01260000; cpu->isar.id_mmfr3 = 0x02102211; - cpu->isar.id_isar0 = 0x02101110; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232042; - cpu->isar.id_isar3 = 0x01112131; - cpu->isar.id_isar4 = 0x00011142; - cpu->isar.id_isar5 = 0x00011121; + SET_IDREG(&cpu->isar, ID_ISAR0, 0x02101110); + SET_IDREG(&cpu->isar, ID_ISAR1, 0x13112111); + SET_IDREG(&cpu->isar, ID_ISAR2, 0x21232042); + SET_IDREG(&cpu->isar, ID_ISAR3, 0x01112131); + SET_IDREG(&cpu->isar, ID_ISAR4, 0x00011142); + SET_IDREG(&cpu->isar, ID_ISAR5, 0x00011121); SET_IDREG(&cpu->isar, ID_AA64PFR0, 0x00002222); SET_IDREG(&cpu->isar, ID_AA64DFR0, 0x10305106); SET_IDREG(&cpu->isar, ID_AA64ISAR0, 0x00011120); diff --git a/target/arm/helper.c b/target/arm/helper.c index 0ed6c4a37e..d2d9de8b0b 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8278,32 +8278,32 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa32_tid3, - .resetvalue = cpu->isar.id_isar0 }, + .resetvalue = GET_IDREG(isar, ID_ISAR0)}, { .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa32_tid3, - .resetvalue = cpu->isar.id_isar1 }, + .resetvalue = GET_IDREG(isar, ID_ISAR1)}, { .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa32_tid3, - .resetvalue = cpu->isar.id_isar2 }, + .resetvalue = GET_IDREG(isar, ID_ISAR2)}, { .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa32_tid3, - .resetvalue = cpu->isar.id_isar3 }, + .resetvalue = GET_IDREG(isar, ID_ISAR3) }, { .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa32_tid3, - .resetvalue = cpu->isar.id_isar4 }, + .resetvalue = GET_IDREG(isar, ID_ISAR4) }, { .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa32_tid3, - .resetvalue = cpu->isar.id_isar5 }, + .resetvalue = GET_IDREG(isar, ID_ISAR5) }, { .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST, @@ -8313,7 +8313,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa32_tid3, - .resetvalue = cpu->isar.id_isar6 }, + .resetvalue = GET_IDREG(isar, ID_ISAR6) }, }; define_arm_cp_regs(cpu, v6_idregs); define_arm_cp_regs(cpu, v6_cp_reginfo); diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index b50af4acd9..2e57ba4224 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -387,22 +387,15 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) ARM64_SYS_REG(3, 0, 0, 1, 6)); err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr3, ARM64_SYS_REG(3, 0, 0, 1, 7)); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar0, - ARM64_SYS_REG(3, 0, 0, 2, 0)); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar1, - ARM64_SYS_REG(3, 0, 0, 2, 1)); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar2, - ARM64_SYS_REG(3, 0, 0, 2, 2)); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar3, - ARM64_SYS_REG(3, 0, 0, 2, 3)); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar4, - ARM64_SYS_REG(3, 0, 0, 2, 4)); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar5, - ARM64_SYS_REG(3, 0, 0, 2, 5)); + err |= get_host_cpu_reg(fd, ahcf, ID_ISAR0_EL1_IDX); + err |= get_host_cpu_reg(fd, ahcf, ID_ISAR1_EL1_IDX); + err |= get_host_cpu_reg(fd, ahcf, ID_ISAR2_EL1_IDX); + err |= get_host_cpu_reg(fd, ahcf, ID_ISAR3_EL1_IDX); + err |= get_host_cpu_reg(fd, ahcf, ID_ISAR4_EL1_IDX); + err |= get_host_cpu_reg(fd, ahcf, ID_ISAR5_EL1_IDX); + err |= get_host_cpu_reg(fd, ahcf, ID_ISAR6_EL1_IDX); err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr4, ARM64_SYS_REG(3, 0, 0, 2, 6)); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar6, - ARM64_SYS_REG(3, 0, 0, 2, 7)); err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr0, ARM64_SYS_REG(3, 0, 0, 3, 0)); diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c index d9e0e2a4dd..8da34b6b46 100644 --- a/target/arm/tcg/cpu32.c +++ b/target/arm/tcg/cpu32.c @@ -26,18 +26,19 @@ void aa32_max_features(ARMCPU *cpu) { uint32_t t; + ARMISARegisters *isar = &cpu->isar; /* Add additional features supported by QEMU */ - t = cpu->isar.id_isar5; + t = GET_IDREG(isar, ID_ISAR5); t = FIELD_DP32(t, ID_ISAR5, AES, 2); /* FEAT_PMULL */ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1); /* FEAT_SHA1 */ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1); /* FEAT_SHA256 */ t = FIELD_DP32(t, ID_ISAR5, CRC32, 1); t = FIELD_DP32(t, ID_ISAR5, RDM, 1); /* FEAT_RDM */ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1); /* FEAT_FCMA */ - cpu->isar.id_isar5 = t; + SET_IDREG(isar, ID_ISAR5, t); - t = cpu->isar.id_isar6; + t = GET_IDREG(isar, ID_ISAR6); t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1); /* FEAT_JSCVT */ t = FIELD_DP32(t, ID_ISAR6, DP, 1); /* Feat_DotProd */ t = FIELD_DP32(t, ID_ISAR6, FHM, 1); /* FEAT_FHM */ @@ -45,7 +46,7 @@ void aa32_max_features(ARMCPU *cpu) t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1); /* FEAT_SPECRES */ t = FIELD_DP32(t, ID_ISAR6, BF16, 1); /* FEAT_AA32BF16 */ t = FIELD_DP32(t, ID_ISAR6, I8MM, 1); /* FEAT_AA32I8MM */ - cpu->isar.id_isar6 = t; + SET_IDREG(isar, ID_ISAR6, t); t = cpu->isar.mvfr1; t = FIELD_DP32(t, MVFR1, FPHP, 3); /* FEAT_FP16 */ @@ -141,7 +142,7 @@ static void arm926_initfn(Object *obj) * ARMv5 does not have the ID_ISAR registers, but we can still * set the field to indicate Jazelle support within QEMU. */ - cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1); + FIELD_DP32_IDREG(&cpu->isar, ID_ISAR1, JAZELLE, 1); /* * Similarly, we need to set MVFR0 fields to enable vfp and short vector * support even though ARMv5 doesn't have this register. @@ -183,7 +184,7 @@ static void arm1026_initfn(Object *obj) * ARMv5 does not have the ID_ISAR registers, but we can still * set the field to indicate Jazelle support within QEMU. */ - cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1); + FIELD_DP32_IDREG(&cpu->isar, ID_ISAR1, JAZELLE, 1); /* * Similarly, we need to set MVFR0 fields to enable vfp and short vector * support even though ARMv5 doesn't have this register. @@ -207,6 +208,7 @@ static void arm1026_initfn(Object *obj) static void arm1136_r2_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; /* * What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an * older core than plain "arm1136". In particular this does not @@ -234,17 +236,18 @@ static void arm1136_r2_initfn(Object *obj) cpu->isar.id_mmfr0 = 0x01130003; cpu->isar.id_mmfr1 = 0x10030302; cpu->isar.id_mmfr2 = 0x01222110; - cpu->isar.id_isar0 = 0x00140011; - cpu->isar.id_isar1 = 0x12002111; - cpu->isar.id_isar2 = 0x11231111; - cpu->isar.id_isar3 = 0x01102131; - cpu->isar.id_isar4 = 0x141; + SET_IDREG(isar, ID_ISAR0, 0x00140011); + SET_IDREG(isar, ID_ISAR1, 0x12002111); + SET_IDREG(isar, ID_ISAR2, 0x11231111); + SET_IDREG(isar, ID_ISAR3, 0x01102131); + SET_IDREG(isar, ID_ISAR4, 0x141); cpu->reset_auxcr = 7; } static void arm1136_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,arm1136"; set_feature(&cpu->env, ARM_FEATURE_V6K); @@ -265,17 +268,18 @@ static void arm1136_initfn(Object *obj) cpu->isar.id_mmfr0 = 0x01130003; cpu->isar.id_mmfr1 = 0x10030302; cpu->isar.id_mmfr2 = 0x01222110; - cpu->isar.id_isar0 = 0x00140011; - cpu->isar.id_isar1 = 0x12002111; - cpu->isar.id_isar2 = 0x11231111; - cpu->isar.id_isar3 = 0x01102131; - cpu->isar.id_isar4 = 0x141; + SET_IDREG(isar, ID_ISAR0, 0x00140011); + SET_IDREG(isar, ID_ISAR1, 0x12002111); + SET_IDREG(isar, ID_ISAR2, 0x11231111); + SET_IDREG(isar, ID_ISAR3, 0x01102131); + SET_IDREG(isar, ID_ISAR4, 0x141); cpu->reset_auxcr = 7; } static void arm1176_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,arm1176"; set_feature(&cpu->env, ARM_FEATURE_V6K); @@ -297,17 +301,18 @@ static void arm1176_initfn(Object *obj) cpu->isar.id_mmfr0 = 0x01130003; cpu->isar.id_mmfr1 = 0x10030302; cpu->isar.id_mmfr2 = 0x01222100; - cpu->isar.id_isar0 = 0x0140011; - cpu->isar.id_isar1 = 0x12002111; - cpu->isar.id_isar2 = 0x11231121; - cpu->isar.id_isar3 = 0x01102131; - cpu->isar.id_isar4 = 0x01141; + SET_IDREG(isar, ID_ISAR0, 0x0140011); + SET_IDREG(isar, ID_ISAR1, 0x12002111); + SET_IDREG(isar, ID_ISAR2, 0x11231121); + SET_IDREG(isar, ID_ISAR3, 0x01102131); + SET_IDREG(isar, ID_ISAR4, 0x01141); cpu->reset_auxcr = 7; } static void arm11mpcore_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,arm11mpcore"; set_feature(&cpu->env, ARM_FEATURE_V6K); @@ -326,11 +331,11 @@ static void arm11mpcore_initfn(Object *obj) cpu->isar.id_mmfr0 = 0x01100103; cpu->isar.id_mmfr1 = 0x10020302; cpu->isar.id_mmfr2 = 0x01222000; - cpu->isar.id_isar0 = 0x00100011; - cpu->isar.id_isar1 = 0x12002111; - cpu->isar.id_isar2 = 0x11221011; - cpu->isar.id_isar3 = 0x01102131; - cpu->isar.id_isar4 = 0x141; + SET_IDREG(isar, ID_ISAR0, 0x00100011); + SET_IDREG(isar, ID_ISAR1, 0x12002111); + SET_IDREG(isar, ID_ISAR2, 0x11221011); + SET_IDREG(isar, ID_ISAR3, 0x01102131); + SET_IDREG(isar, ID_ISAR4, 0x141); cpu->reset_auxcr = 1; } @@ -344,6 +349,7 @@ static const ARMCPRegInfo cortexa8_cp_reginfo[] = { static void cortex_a8_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,cortex-a8"; set_feature(&cpu->env, ARM_FEATURE_V7); @@ -366,11 +372,11 @@ static void cortex_a8_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x20000000; cpu->isar.id_mmfr2 = 0x01202000; cpu->isar.id_mmfr3 = 0x11; - cpu->isar.id_isar0 = 0x00101111; - cpu->isar.id_isar1 = 0x12112111; - cpu->isar.id_isar2 = 0x21232031; - cpu->isar.id_isar3 = 0x11112131; - cpu->isar.id_isar4 = 0x00111142; + SET_IDREG(isar, ID_ISAR0, 0x00101111); + SET_IDREG(isar, ID_ISAR1, 0x12112111); + SET_IDREG(isar, ID_ISAR2, 0x21232031); + SET_IDREG(isar, ID_ISAR3, 0x11112131); + SET_IDREG(isar, ID_ISAR4, 0x00111142); cpu->isar.dbgdidr = 0x15141000; cpu->clidr = (1 << 27) | (2 << 24) | 3; cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */ @@ -413,6 +419,7 @@ static const ARMCPRegInfo cortexa9_cp_reginfo[] = { static void cortex_a9_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,cortex-a9"; set_feature(&cpu->env, ARM_FEATURE_V7); @@ -441,11 +448,11 @@ static void cortex_a9_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x20000000; cpu->isar.id_mmfr2 = 0x01230000; cpu->isar.id_mmfr3 = 0x00002111; - cpu->isar.id_isar0 = 0x00101111; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232041; - cpu->isar.id_isar3 = 0x11112131; - cpu->isar.id_isar4 = 0x00111142; + SET_IDREG(isar, ID_ISAR0, 0x00101111); + SET_IDREG(isar, ID_ISAR1, 0x13112111); + SET_IDREG(isar, ID_ISAR2, 0x21232041); + SET_IDREG(isar, ID_ISAR3, 0x11112131); + SET_IDREG(isar, ID_ISAR4, 0x00111142); cpu->isar.dbgdidr = 0x35141000; cpu->clidr = (1 << 27) | (1 << 24) | 3; cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */ @@ -480,6 +487,7 @@ static const ARMCPRegInfo cortexa15_cp_reginfo[] = { static void cortex_a7_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,cortex-a7"; set_feature(&cpu->env, ARM_FEATURE_V7VE); @@ -509,11 +517,11 @@ static void cortex_a7_initfn(Object *obj) * a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but * table 4-41 gives 0x02101110, which includes the arm div insns. */ - cpu->isar.id_isar0 = 0x02101110; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232041; - cpu->isar.id_isar3 = 0x11112131; - cpu->isar.id_isar4 = 0x10011142; + SET_IDREG(isar, ID_ISAR0, 0x02101110); + SET_IDREG(isar, ID_ISAR1, 0x13112111); + SET_IDREG(isar, ID_ISAR2, 0x21232041); + SET_IDREG(isar, ID_ISAR3, 0x11112131); + SET_IDREG(isar, ID_ISAR4, 0x10011142); cpu->isar.dbgdidr = 0x3515f005; cpu->isar.dbgdevid = 0x01110f13; cpu->isar.dbgdevid1 = 0x1; @@ -528,6 +536,7 @@ static void cortex_a7_initfn(Object *obj) static void cortex_a15_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; cpu->dtb_compatible = "arm,cortex-a15"; set_feature(&cpu->env, ARM_FEATURE_V7VE); @@ -555,11 +564,11 @@ static void cortex_a15_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x20000000; cpu->isar.id_mmfr2 = 0x01240000; cpu->isar.id_mmfr3 = 0x02102211; - cpu->isar.id_isar0 = 0x02101110; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232041; - cpu->isar.id_isar3 = 0x11112131; - cpu->isar.id_isar4 = 0x10011142; + SET_IDREG(isar, ID_ISAR0, 0x02101110); + SET_IDREG(isar, ID_ISAR1, 0x13112111); + SET_IDREG(isar, ID_ISAR2, 0x21232041); + SET_IDREG(isar, ID_ISAR3, 0x11112131); + SET_IDREG(isar, ID_ISAR4, 0x10011142); cpu->isar.dbgdidr = 0x3515f021; cpu->isar.dbgdevid = 0x01110f13; cpu->isar.dbgdevid1 = 0x0; @@ -574,6 +583,8 @@ static void cortex_a15_initfn(Object *obj) static void cortex_m0_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; + set_feature(&cpu->env, ARM_FEATURE_V6); set_feature(&cpu->env, ARM_FEATURE_M); @@ -595,18 +606,20 @@ static void cortex_m0_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x00000000; cpu->isar.id_mmfr2 = 0x00000000; cpu->isar.id_mmfr3 = 0x00000000; - cpu->isar.id_isar0 = 0x01141110; - cpu->isar.id_isar1 = 0x02111000; - cpu->isar.id_isar2 = 0x21112231; - cpu->isar.id_isar3 = 0x01111110; - cpu->isar.id_isar4 = 0x01310102; - cpu->isar.id_isar5 = 0x00000000; - cpu->isar.id_isar6 = 0x00000000; + SET_IDREG(isar, ID_ISAR0, 0x01141110); + SET_IDREG(isar, ID_ISAR1, 0x02111000); + SET_IDREG(isar, ID_ISAR2, 0x21112231); + SET_IDREG(isar, ID_ISAR3, 0x01111110); + SET_IDREG(isar, ID_ISAR4, 0x01310102); + SET_IDREG(isar, ID_ISAR5, 0); + SET_IDREG(isar, ID_ISAR6, 0); } static void cortex_m3_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; + set_feature(&cpu->env, ARM_FEATURE_V7); set_feature(&cpu->env, ARM_FEATURE_M); set_feature(&cpu->env, ARM_FEATURE_M_MAIN); @@ -620,18 +633,19 @@ static void cortex_m3_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x00000000; cpu->isar.id_mmfr2 = 0x00000000; cpu->isar.id_mmfr3 = 0x00000000; - cpu->isar.id_isar0 = 0x01141110; - cpu->isar.id_isar1 = 0x02111000; - cpu->isar.id_isar2 = 0x21112231; - cpu->isar.id_isar3 = 0x01111110; - cpu->isar.id_isar4 = 0x01310102; - cpu->isar.id_isar5 = 0x00000000; - cpu->isar.id_isar6 = 0x00000000; + SET_IDREG(isar, ID_ISAR0, 0x01141110); + SET_IDREG(isar, ID_ISAR1, 0x02111000); + SET_IDREG(isar, ID_ISAR2, 0x21112231); + SET_IDREG(isar, ID_ISAR3, 0x01111110); + SET_IDREG(isar, ID_ISAR4, 0x01310102); + SET_IDREG(isar, ID_ISAR5, 0); + SET_IDREG(isar, ID_ISAR6, 0); } static void cortex_m4_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; set_feature(&cpu->env, ARM_FEATURE_V7); set_feature(&cpu->env, ARM_FEATURE_M); @@ -650,18 +664,19 @@ static void cortex_m4_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x00000000; cpu->isar.id_mmfr2 = 0x00000000; cpu->isar.id_mmfr3 = 0x00000000; - cpu->isar.id_isar0 = 0x01141110; - cpu->isar.id_isar1 = 0x02111000; - cpu->isar.id_isar2 = 0x21112231; - cpu->isar.id_isar3 = 0x01111110; - cpu->isar.id_isar4 = 0x01310102; - cpu->isar.id_isar5 = 0x00000000; - cpu->isar.id_isar6 = 0x00000000; + SET_IDREG(isar, ID_ISAR0, 0x01141110); + SET_IDREG(isar, ID_ISAR1, 0x02111000); + SET_IDREG(isar, ID_ISAR2, 0x21112231); + SET_IDREG(isar, ID_ISAR3, 0x01111110); + SET_IDREG(isar, ID_ISAR4, 0x01310102); + SET_IDREG(isar, ID_ISAR5, 0); + SET_IDREG(isar, ID_ISAR6, 0); } static void cortex_m7_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; set_feature(&cpu->env, ARM_FEATURE_V7); set_feature(&cpu->env, ARM_FEATURE_M); @@ -680,18 +695,19 @@ static void cortex_m7_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x00000000; cpu->isar.id_mmfr2 = 0x01000000; cpu->isar.id_mmfr3 = 0x00000000; - cpu->isar.id_isar0 = 0x01101110; - cpu->isar.id_isar1 = 0x02112000; - cpu->isar.id_isar2 = 0x20232231; - cpu->isar.id_isar3 = 0x01111131; - cpu->isar.id_isar4 = 0x01310132; - cpu->isar.id_isar5 = 0x00000000; - cpu->isar.id_isar6 = 0x00000000; + SET_IDREG(isar, ID_ISAR0, 0x01101110); + SET_IDREG(isar, ID_ISAR1, 0x02112000); + SET_IDREG(isar, ID_ISAR2, 0x20232231); + SET_IDREG(isar, ID_ISAR3, 0x01111131); + SET_IDREG(isar, ID_ISAR4, 0x01310132); + SET_IDREG(isar, ID_ISAR5, 0); + SET_IDREG(isar, ID_ISAR6, 0); } static void cortex_m33_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_M); @@ -712,13 +728,13 @@ static void cortex_m33_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x00000000; cpu->isar.id_mmfr2 = 0x01000000; cpu->isar.id_mmfr3 = 0x00000000; - cpu->isar.id_isar0 = 0x01101110; - cpu->isar.id_isar1 = 0x02212000; - cpu->isar.id_isar2 = 0x20232232; - cpu->isar.id_isar3 = 0x01111131; - cpu->isar.id_isar4 = 0x01310132; - cpu->isar.id_isar5 = 0x00000000; - cpu->isar.id_isar6 = 0x00000000; + SET_IDREG(isar, ID_ISAR0, 0x01101110); + SET_IDREG(isar, ID_ISAR1, 0x02212000); + SET_IDREG(isar, ID_ISAR2, 0x20232232); + SET_IDREG(isar, ID_ISAR3, 0x01111131); + SET_IDREG(isar, ID_ISAR4, 0x01310132); + SET_IDREG(isar, ID_ISAR5, 0); + SET_IDREG(isar, ID_ISAR6, 0); cpu->clidr = 0x00000000; cpu->ctr = 0x8000c000; } @@ -726,7 +742,8 @@ static void cortex_m33_initfn(Object *obj) static void cortex_m55_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); - + ARMISARegisters *isar = &cpu->isar; + set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_V8_1M); set_feature(&cpu->env, ARM_FEATURE_M); @@ -749,13 +766,13 @@ static void cortex_m55_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x00000000; cpu->isar.id_mmfr2 = 0x01000000; cpu->isar.id_mmfr3 = 0x00000011; - cpu->isar.id_isar0 = 0x01103110; - cpu->isar.id_isar1 = 0x02212000; - cpu->isar.id_isar2 = 0x20232232; - cpu->isar.id_isar3 = 0x01111131; - cpu->isar.id_isar4 = 0x01310132; - cpu->isar.id_isar5 = 0x00000000; - cpu->isar.id_isar6 = 0x00000000; + SET_IDREG(isar, ID_ISAR0, 0x01103110); + SET_IDREG(isar, ID_ISAR1, 0x02212000); + SET_IDREG(isar, ID_ISAR2, 0x20232232); + SET_IDREG(isar, ID_ISAR3, 0x01111131); + SET_IDREG(isar, ID_ISAR4, 0x01310132); + SET_IDREG(isar, ID_ISAR5, 0); + SET_IDREG(isar, ID_ISAR6, 0); cpu->clidr = 0x00000000; /* caches not implemented */ cpu->ctr = 0x8303c003; } @@ -773,6 +790,7 @@ static const ARMCPRegInfo cortexr5_cp_reginfo[] = { static void cortex_r5_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; set_feature(&cpu->env, ARM_FEATURE_V7); set_feature(&cpu->env, ARM_FEATURE_V7MP); @@ -787,13 +805,13 @@ static void cortex_r5_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x00000000; cpu->isar.id_mmfr2 = 0x01200000; cpu->isar.id_mmfr3 = 0x0211; - cpu->isar.id_isar0 = 0x02101111; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232141; - cpu->isar.id_isar3 = 0x01112131; - cpu->isar.id_isar4 = 0x0010142; - cpu->isar.id_isar5 = 0x0; - cpu->isar.id_isar6 = 0x0; + SET_IDREG(isar, ID_ISAR0, 0x02101111); + SET_IDREG(isar, ID_ISAR1, 0x13112111); + SET_IDREG(isar, ID_ISAR2, 0x21232141); + SET_IDREG(isar, ID_ISAR3, 0x01112131); + SET_IDREG(isar, ID_ISAR4, 0x0010142); + SET_IDREG(isar, ID_ISAR5, 0x0); + SET_IDREG(isar, ID_ISAR6, 0x0); cpu->mp_is_up = true; cpu->pmsav7_dregion = 16; cpu->isar.reset_pmcr_el0 = 0x41151800; @@ -803,6 +821,7 @@ static void cortex_r5_initfn(Object *obj) static void cortex_r52_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; set_feature(&cpu->env, ARM_FEATURE_V8); set_feature(&cpu->env, ARM_FEATURE_EL2); @@ -826,12 +845,12 @@ static void cortex_r52_initfn(Object *obj) cpu->isar.id_mmfr2 = 0x01200000; cpu->isar.id_mmfr3 = 0xf0102211; cpu->isar.id_mmfr4 = 0x00000010; - cpu->isar.id_isar0 = 0x02101110; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232142; - cpu->isar.id_isar3 = 0x01112131; - cpu->isar.id_isar4 = 0x00010142; - cpu->isar.id_isar5 = 0x00010001; + SET_IDREG(isar, ID_ISAR0, 0x02101110); + SET_IDREG(isar, ID_ISAR1, 0x13112111); + SET_IDREG(isar, ID_ISAR2, 0x21232142); + SET_IDREG(isar, ID_ISAR3, 0x01112131); + SET_IDREG(isar, ID_ISAR4, 0x00010142); + SET_IDREG(isar, ID_ISAR5, 0x00010001); cpu->isar.dbgdidr = 0x77168000; cpu->clidr = (1 << 27) | (1 << 24) | 0x3; cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */ @@ -1058,6 +1077,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data) static void arm_max_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMISARegisters *isar = &cpu->isar; /* aarch64_a57_initfn, advertising none of the aarch64 features */ cpu->dtb_compatible = "arm,cortex-a57"; @@ -1084,13 +1104,13 @@ static void arm_max_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x40000000; cpu->isar.id_mmfr2 = 0x01260000; cpu->isar.id_mmfr3 = 0x02102211; - cpu->isar.id_isar0 = 0x02101110; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232042; - cpu->isar.id_isar3 = 0x01112131; - cpu->isar.id_isar4 = 0x00011142; - cpu->isar.id_isar5 = 0x00011121; - cpu->isar.id_isar6 = 0; + SET_IDREG(isar, ID_ISAR0, 0x02101110); + SET_IDREG(isar, ID_ISAR1, 0x13112111); + SET_IDREG(isar, ID_ISAR2, 0x21232042); + SET_IDREG(isar, ID_ISAR3, 0x01112131); + SET_IDREG(isar, ID_ISAR4, 0x00011142); + SET_IDREG(isar, ID_ISAR5, 0x00011121); + SET_IDREG(isar, ID_ISAR6, 0); cpu->isar.dbgdidr = 0x3516d000; cpu->isar.dbgdevid = 0x00110f13; cpu->isar.dbgdevid1 = 0x2; diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c index 04deff475e..6be05f87f6 100644 --- a/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c @@ -82,12 +82,12 @@ static void aarch64_a35_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x40000000; cpu->isar.id_mmfr2 = 0x01260000; cpu->isar.id_mmfr3 = 0x02102211; - cpu->isar.id_isar0 = 0x02101110; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232042; - cpu->isar.id_isar3 = 0x01112131; - cpu->isar.id_isar4 = 0x00011142; - cpu->isar.id_isar5 = 0x00011121; + SET_IDREG(isar, ID_ISAR0, 0x02101110); + SET_IDREG(isar, ID_ISAR1, 0x13112111); + SET_IDREG(isar, ID_ISAR2, 0x21232042); + SET_IDREG(isar, ID_ISAR3, 0x01112131); + SET_IDREG(isar, ID_ISAR4, 0x00011142); + SET_IDREG(isar, ID_ISAR5, 0x00011121); SET_IDREG(isar, ID_AA64PFR0, 0x00002222); SET_IDREG(isar, ID_AA64PFR1, 0); SET_IDREG(isar, ID_AA64DFR0, 0x10305106); @@ -250,13 +250,13 @@ static void aarch64_a55_initfn(Object *obj) SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000010ull); cpu->id_afr0 = 0x00000000; cpu->isar.id_dfr0 = 0x04010088; - cpu->isar.id_isar0 = 0x02101110; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232042; - cpu->isar.id_isar3 = 0x01112131; - cpu->isar.id_isar4 = 0x00011142; - cpu->isar.id_isar5 = 0x01011121; - cpu->isar.id_isar6 = 0x00000010; + SET_IDREG(isar, ID_ISAR0, 0x02101110); + SET_IDREG(isar, ID_ISAR1, 0x13112111); + SET_IDREG(isar, ID_ISAR2, 0x21232042); + SET_IDREG(isar, ID_ISAR3, 0x01112131); + SET_IDREG(isar, ID_ISAR4, 0x00011142); + SET_IDREG(isar, ID_ISAR5, 0x01011121); + SET_IDREG(isar, ID_ISAR6, 0x00000010); cpu->isar.id_mmfr0 = 0x10201105; cpu->isar.id_mmfr1 = 0x40000000; cpu->isar.id_mmfr2 = 0x01260000; @@ -320,12 +320,12 @@ static void aarch64_a72_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x40000000; cpu->isar.id_mmfr2 = 0x01260000; cpu->isar.id_mmfr3 = 0x02102211; - cpu->isar.id_isar0 = 0x02101110; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232042; - cpu->isar.id_isar3 = 0x01112131; - cpu->isar.id_isar4 = 0x00011142; - cpu->isar.id_isar5 = 0x00011121; + SET_IDREG(isar, ID_ISAR0, 0x02101110); + SET_IDREG(isar, ID_ISAR1, 0x13112111); + SET_IDREG(isar, ID_ISAR2, 0x21232042); + SET_IDREG(isar, ID_ISAR3, 0x01112131); + SET_IDREG(isar, ID_ISAR4, 0x00011142); + SET_IDREG(isar, ID_ISAR5, 0x00011121); SET_IDREG(isar, ID_AA64PFR0, 0x00002222); SET_IDREG(isar, ID_AA64DFR0, 0x10305106); SET_IDREG(isar, ID_AA64ISAR0, 0x00011120); @@ -375,13 +375,13 @@ static void aarch64_a76_initfn(Object *obj) SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000010ull); cpu->id_afr0 = 0x00000000; cpu->isar.id_dfr0 = 0x04010088; - cpu->isar.id_isar0 = 0x02101110; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232042; - cpu->isar.id_isar3 = 0x01112131; - cpu->isar.id_isar4 = 0x00010142; - cpu->isar.id_isar5 = 0x01011121; - cpu->isar.id_isar6 = 0x00000010; + SET_IDREG(isar, ID_ISAR0, 0x02101110); + SET_IDREG(isar, ID_ISAR1, 0x13112111); + SET_IDREG(isar, ID_ISAR2, 0x21232042); + SET_IDREG(isar, ID_ISAR3, 0x01112131); + SET_IDREG(isar, ID_ISAR4, 0x00010142); + SET_IDREG(isar, ID_ISAR5, 0x01011121); + SET_IDREG(isar, ID_ISAR6, 0x00000010); cpu->isar.id_mmfr0 = 0x10201105; cpu->isar.id_mmfr1 = 0x40000000; cpu->isar.id_mmfr2 = 0x01260000; @@ -615,13 +615,13 @@ static void aarch64_neoverse_n1_initfn(Object *obj) SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000020ull); cpu->id_afr0 = 0x00000000; cpu->isar.id_dfr0 = 0x04010088; - cpu->isar.id_isar0 = 0x02101110; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232042; - cpu->isar.id_isar3 = 0x01112131; - cpu->isar.id_isar4 = 0x00010142; - cpu->isar.id_isar5 = 0x01011121; - cpu->isar.id_isar6 = 0x00000010; + SET_IDREG(isar, ID_ISAR0, 0x02101110); + SET_IDREG(isar, ID_ISAR1, 0x13112111); + SET_IDREG(isar, ID_ISAR2, 0x21232042); + SET_IDREG(isar, ID_ISAR3, 0x01112131); + SET_IDREG(isar, ID_ISAR4, 0x00010142); + SET_IDREG(isar, ID_ISAR5, 0x01011121); + SET_IDREG(isar, ID_ISAR6, 0x00000010); cpu->isar.id_mmfr0 = 0x10201105; cpu->isar.id_mmfr1 = 0x40000000; cpu->isar.id_mmfr2 = 0x01260000; @@ -690,13 +690,13 @@ static void aarch64_neoverse_v1_initfn(Object *obj) SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000020ull); cpu->id_afr0 = 0x00000000; cpu->isar.id_dfr0 = 0x15011099; - cpu->isar.id_isar0 = 0x02101110; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232042; - cpu->isar.id_isar3 = 0x01112131; - cpu->isar.id_isar4 = 0x00010142; - cpu->isar.id_isar5 = 0x11011121; - cpu->isar.id_isar6 = 0x01100111; + SET_IDREG(isar, ID_ISAR0, 0x02101110); + SET_IDREG(isar, ID_ISAR1, 0x13112111); + SET_IDREG(isar, ID_ISAR2, 0x21232042); + SET_IDREG(isar, ID_ISAR3, 0x01112131); + SET_IDREG(isar, ID_ISAR4, 0x00010142); + SET_IDREG(isar, ID_ISAR5, 0x11011121); + SET_IDREG(isar, ID_ISAR6, 0x01100111); cpu->isar.id_mmfr0 = 0x10201105; cpu->isar.id_mmfr1 = 0x40000000; cpu->isar.id_mmfr2 = 0x01260000; @@ -907,14 +907,14 @@ static void aarch64_a710_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x40000000; cpu->isar.id_mmfr2 = 0x01260000; cpu->isar.id_mmfr3 = 0x02122211; - cpu->isar.id_isar0 = 0x02101110; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232042; - cpu->isar.id_isar3 = 0x01112131; - cpu->isar.id_isar4 = 0x00010142; - cpu->isar.id_isar5 = 0x11011121; /* with Crypto */ + SET_IDREG(isar, ID_ISAR0, 0x02101110); + SET_IDREG(isar, ID_ISAR1, 0x13112111); + SET_IDREG(isar, ID_ISAR2, 0x21232042); + SET_IDREG(isar, ID_ISAR3, 0x01112131); + SET_IDREG(isar, ID_ISAR4, 0x00010142); + SET_IDREG(isar, ID_ISAR5, 0x11011121); /* with Crypto */ cpu->isar.id_mmfr4 = 0x21021110; - cpu->isar.id_isar6 = 0x01111111; + SET_IDREG(isar, ID_ISAR6, 0x01111111); cpu->isar.mvfr0 = 0x10110222; cpu->isar.mvfr1 = 0x13211111; cpu->isar.mvfr2 = 0x00000043; @@ -1005,14 +1005,14 @@ static void aarch64_neoverse_n2_initfn(Object *obj) cpu->isar.id_mmfr1 = 0x40000000; cpu->isar.id_mmfr2 = 0x01260000; cpu->isar.id_mmfr3 = 0x02122211; - cpu->isar.id_isar0 = 0x02101110; - cpu->isar.id_isar1 = 0x13112111; - cpu->isar.id_isar2 = 0x21232042; - cpu->isar.id_isar3 = 0x01112131; - cpu->isar.id_isar4 = 0x00010142; - cpu->isar.id_isar5 = 0x11011121; /* with Crypto */ + SET_IDREG(isar, ID_ISAR0, 0x02101110); + SET_IDREG(isar, ID_ISAR1, 0x13112111); + SET_IDREG(isar, ID_ISAR2, 0x21232042); + SET_IDREG(isar, ID_ISAR3, 0x01112131); + SET_IDREG(isar, ID_ISAR4, 0x00010142); + SET_IDREG(isar, ID_ISAR5, 0x11011121); /* with Crypto */ cpu->isar.id_mmfr4 = 0x01021110; - cpu->isar.id_isar6 = 0x01111111; + SET_IDREG(isar, ID_ISAR6, 0x01111111); cpu->isar.mvfr0 = 0x10110222; cpu->isar.mvfr1 = 0x13211111; cpu->isar.mvfr2 = 0x00000043; -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Sebastian Ott <sebott@redhat.com> Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- hw/intc/armv7m_nvic.c | 5 +-- target/arm/cpu-features.h | 10 +++--- target/arm/cpu.c | 8 ++--- target/arm/cpu.h | 3 -- target/arm/cpu64.c | 12 +++---- target/arm/helper.c | 8 ++--- target/arm/kvm64.c | 9 ++--- target/arm/tcg/cpu32.c | 76 +++++++++++++++++++-------------------- target/arm/tcg/cpu64.c | 44 +++++++++++------------ 9 files changed, 84 insertions(+), 91 deletions(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 5f68b0e711..b613b2cafe 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -988,6 +988,7 @@ static void nvic_nmi_trigger(void *opaque, int n, int level) static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) { ARMCPU *cpu = s->cpu; + ARMISARegisters *isar = &cpu->isar; uint32_t val; switch (offset) { @@ -1263,12 +1264,12 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_pfr0; + return GET_IDREG(isar, ID_PFR0); case 0xd44: /* PFR1. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_pfr1; + return GET_IDREG(isar, ID_PFR1); case 0xd48: /* DFR0. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index 25180e4b77..fe73988141 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -133,12 +133,12 @@ static inline bool isar_feature_aa32_i8mm(const ARMISARegisters *id) static inline bool isar_feature_aa32_ras(const ARMISARegisters *id) { - return FIELD_EX32(id->id_pfr0, ID_PFR0, RAS) != 0; + return FIELD_EX32_IDREG(id, ID_PFR0, RAS) != 0; } static inline bool isar_feature_aa32_mprofile(const ARMISARegisters *id) { - return FIELD_EX32(id->id_pfr1, ID_PFR1, MPROGMOD) != 0; + return FIELD_EX32_IDREG(id, ID_PFR1, MPROGMOD) != 0; } static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id) @@ -147,7 +147,7 @@ static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id) * Return true if M-profile state handling insns * (VSCCLRM, CLRM, FPCTX access insns) are implemented */ - return FIELD_EX32(id->id_pfr1, ID_PFR1, SECURITY) >= 3; + return FIELD_EX32_IDREG(id, ID_PFR1, SECURITY) >= 3; } static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id) @@ -346,12 +346,12 @@ static inline bool isar_feature_aa32_evt(const ARMISARegisters *id) static inline bool isar_feature_aa32_dit(const ARMISARegisters *id) { - return FIELD_EX32(id->id_pfr0, ID_PFR0, DIT) != 0; + return FIELD_EX32_IDREG(id, ID_PFR0, DIT) != 0; } static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id) { - return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0; + return FIELD_EX32_IDREG(id, ID_PFR2, SSBS) != 0; } static inline bool isar_feature_aa32_debugv7p1(const ARMISARegisters *id) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 7667530e9d..60654e8630 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2150,7 +2150,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) * Disable the security extension feature bits in the processor * feature registers as well. */ - cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1, ID_PFR1, SECURITY, 0); + FIELD_DP32_IDREG(isar, ID_PFR1, SECURITY, 0); cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPSDBG, 0); FIELD_DP64_IDREG(isar, ID_AA64PFR0, EL3, 0); @@ -2190,8 +2190,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) * registers if we don't have EL2. */ FIELD_DP64_IDREG(isar, ID_AA64PFR0, EL2, 0); - cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1, - ID_PFR1, VIRTUALIZATION, 0); + FIELD_DP32_IDREG(isar, ID_PFR1, VIRTUALIZATION, 0); } if (cpu_isar_feature(aa64_mte, cpu)) { @@ -2239,8 +2238,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, MMAPTRC, 0); /* FEAT_AMU (Activity Monitors Extension) */ FIELD_DP64_IDREG(isar, ID_AA64PFR0, AMU, 0); - cpu->isar.id_pfr0 = - FIELD_DP32(cpu->isar.id_pfr0, ID_PFR0, AMU, 0); + FIELD_DP32_IDREG(isar, ID_PFR0, AMU, 0); /* FEAT_MPAM (Memory Partitioning and Monitoring Extension) */ FIELD_DP64_IDREG(isar, ID_AA64PFR0, MPAM, 0); /* FEAT_NV (Nested Virtualization) */ diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 4c29657ec7..e9ef2fd484 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1064,9 +1064,6 @@ struct ArchCPU { uint32_t id_mmfr3; uint32_t id_mmfr4; uint32_t id_mmfr5; - uint32_t id_pfr0; - uint32_t id_pfr1; - uint32_t id_pfr2; uint32_t mvfr0; uint32_t mvfr1; uint32_t mvfr2; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 76ba47488f..2f24fc045c 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -750,8 +750,8 @@ static void aarch64_a57_initfn(Object *obj) cpu->isar.mvfr2 = 0x00000043; cpu->ctr = 0x8444c004; cpu->reset_sctlr = 0x00c50838; - cpu->isar.id_pfr0 = 0x00000131; - cpu->isar.id_pfr1 = 0x00011011; + SET_IDREG(isar, ID_PFR0, 0x00000131); + SET_IDREG(isar, ID_PFR1, 0x00011011); cpu->isar.id_dfr0 = 0x03010066; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10101105; @@ -808,8 +808,8 @@ static void aarch64_a53_initfn(Object *obj) cpu->isar.mvfr2 = 0x00000043; cpu->ctr = 0x84448004; /* L1Ip = VIPT */ cpu->reset_sctlr = 0x00c50838; - cpu->isar.id_pfr0 = 0x00000131; - cpu->isar.id_pfr1 = 0x00011011; + SET_IDREG(isar, ID_PFR0, 0x00000131); + SET_IDREG(isar, ID_PFR1, 0x00011011); cpu->isar.id_dfr0 = 0x03010066; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10101105; @@ -865,8 +865,8 @@ static void aarch64_a72_initfn(Object *obj) cpu->isar.mvfr2 = 0x00000043; cpu->ctr = 0x8444c004; cpu->reset_sctlr = 0x00c50838; - cpu->isar.id_pfr0 = 0x00000131; - cpu->isar.id_pfr1 = 0x00011011; + SET_IDREG(&cpu->isar, ID_PFR0, 0x00000131); + SET_IDREG(&cpu->isar, ID_PFR1, 0x00011011); cpu->isar.id_dfr0 = 0x03010066; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10201105; diff --git a/target/arm/helper.c b/target/arm/helper.c index d2d9de8b0b..9895e8e74f 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -7268,7 +7268,7 @@ static void define_pmu_regs(ARMCPU *cpu) static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri) { ARMCPU *cpu = env_archcpu(env); - uint64_t pfr1 = cpu->isar.id_pfr1; + uint64_t pfr1 = GET_IDREG(&cpu->isar, ID_PFR1); if (env->gicv3state) { pfr1 |= 1 << 28; @@ -8225,7 +8225,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa32_tid3, - .resetvalue = cpu->isar.id_pfr0 }, + .resetvalue = GET_IDREG(isar, ID_PFR0)}, /* * ID_PFR1 is not a plain ARM_CP_CONST because we don't know * the value of the GIC field until after we define these regs. @@ -8236,7 +8236,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) .accessfn = access_aa32_tid3, #ifdef CONFIG_USER_ONLY .type = ARM_CP_CONST, - .resetvalue = cpu->isar.id_pfr1, + .resetvalue = GET_IDREG(isar, ID_PFR1), #else .type = ARM_CP_NO_RAW, .accessfn = access_aa32_tid3, @@ -8582,7 +8582,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, - .resetvalue = cpu->isar.id_pfr2 }, + .resetvalue = GET_IDREG(isar, ID_PFR2)}, { .name = "ID_DFR1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5, .access = PL1_R, .type = ARM_CP_CONST, diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 2e57ba4224..74eba5ce47 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -373,10 +373,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) * than skipping the reads and leaving 0, as we must avoid * considering the values in every case. */ - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr0, - ARM64_SYS_REG(3, 0, 0, 1, 0)); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr1, - ARM64_SYS_REG(3, 0, 0, 1, 1)); + err |= get_host_cpu_reg(fd, ahcf, ID_PFR0_EL1_IDX); + err |= get_host_cpu_reg(fd, ahcf, ID_PFR1_EL1_IDX); err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0, ARM64_SYS_REG(3, 0, 0, 1, 2)); err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0, @@ -403,8 +401,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) ARM64_SYS_REG(3, 0, 0, 3, 1)); err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr2, ARM64_SYS_REG(3, 0, 0, 3, 2)); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr2, - ARM64_SYS_REG(3, 0, 0, 3, 4)); + err |= get_host_cpu_reg(fd, ahcf, ID_PFR2_EL1_IDX); err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr1, ARM64_SYS_REG(3, 0, 0, 3, 5)); err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr5, diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c index 8da34b6b46..dd949de260 100644 --- a/target/arm/tcg/cpu32.c +++ b/target/arm/tcg/cpu32.c @@ -74,16 +74,16 @@ void aa32_max_features(ARMCPU *cpu) t = FIELD_DP32(t, ID_MMFR5, ETS, 1); /* FEAT_ETS */ cpu->isar.id_mmfr5 = t; - t = cpu->isar.id_pfr0; + t = GET_IDREG(isar, ID_PFR0); t = FIELD_DP32(t, ID_PFR0, CSV2, 2); /* FEAT_CVS2 */ t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */ t = FIELD_DP32(t, ID_PFR0, RAS, 1); /* FEAT_RAS */ - cpu->isar.id_pfr0 = t; + SET_IDREG(isar, ID_PFR0, t); - t = cpu->isar.id_pfr2; + t = GET_IDREG(isar, ID_PFR2); t = FIELD_DP32(t, ID_PFR2, CSV3, 1); /* FEAT_CSV3 */ t = FIELD_DP32(t, ID_PFR2, SSBS, 1); /* FEAT_SSBS */ - cpu->isar.id_pfr2 = t; + SET_IDREG(isar, ID_PFR2, t); t = cpu->isar.id_dfr0; t = FIELD_DP32(t, ID_DFR0, COPDBG, 9); /* FEAT_Debugv8p4 */ @@ -229,8 +229,8 @@ static void arm1136_r2_initfn(Object *obj) cpu->isar.mvfr1 = 0x00000000; cpu->ctr = 0x1dd20d2; cpu->reset_sctlr = 0x00050078; - cpu->isar.id_pfr0 = 0x111; - cpu->isar.id_pfr1 = 0x1; + SET_IDREG(isar, ID_PFR0, 0x111); + SET_IDREG(isar, ID_PFR1, 0x1); cpu->isar.id_dfr0 = 0x2; cpu->id_afr0 = 0x3; cpu->isar.id_mmfr0 = 0x01130003; @@ -261,8 +261,8 @@ static void arm1136_initfn(Object *obj) cpu->isar.mvfr1 = 0x00000000; cpu->ctr = 0x1dd20d2; cpu->reset_sctlr = 0x00050078; - cpu->isar.id_pfr0 = 0x111; - cpu->isar.id_pfr1 = 0x1; + SET_IDREG(isar, ID_PFR0, 0x111); + SET_IDREG(isar, ID_PFR1, 0x1); cpu->isar.id_dfr0 = 0x2; cpu->id_afr0 = 0x3; cpu->isar.id_mmfr0 = 0x01130003; @@ -294,8 +294,8 @@ static void arm1176_initfn(Object *obj) cpu->isar.mvfr1 = 0x00000000; cpu->ctr = 0x1dd20d2; cpu->reset_sctlr = 0x00050078; - cpu->isar.id_pfr0 = 0x111; - cpu->isar.id_pfr1 = 0x11; + SET_IDREG(isar, ID_PFR0, 0x111); + SET_IDREG(isar, ID_PFR1, 0x11); cpu->isar.id_dfr0 = 0x33; cpu->id_afr0 = 0; cpu->isar.id_mmfr0 = 0x01130003; @@ -324,8 +324,8 @@ static void arm11mpcore_initfn(Object *obj) cpu->isar.mvfr0 = 0x11111111; cpu->isar.mvfr1 = 0x00000000; cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */ - cpu->isar.id_pfr0 = 0x111; - cpu->isar.id_pfr1 = 0x1; + SET_IDREG(isar, ID_PFR0, 0x111); + SET_IDREG(isar, ID_PFR1, 0x1); cpu->isar.id_dfr0 = 0; cpu->id_afr0 = 0x2; cpu->isar.id_mmfr0 = 0x01100103; @@ -364,8 +364,8 @@ static void cortex_a8_initfn(Object *obj) cpu->isar.mvfr1 = 0x00011111; cpu->ctr = 0x82048004; cpu->reset_sctlr = 0x00c50078; - cpu->isar.id_pfr0 = 0x1031; - cpu->isar.id_pfr1 = 0x11; + SET_IDREG(isar, ID_PFR0, 0x1031); + SET_IDREG(isar, ID_PFR1, 0x11); cpu->isar.id_dfr0 = 0x400; cpu->id_afr0 = 0; cpu->isar.id_mmfr0 = 0x31100003; @@ -440,8 +440,8 @@ static void cortex_a9_initfn(Object *obj) cpu->isar.mvfr1 = 0x01111111; cpu->ctr = 0x80038003; cpu->reset_sctlr = 0x00c50078; - cpu->isar.id_pfr0 = 0x1031; - cpu->isar.id_pfr1 = 0x11; + SET_IDREG(isar, ID_PFR0, 0x1031); + SET_IDREG(isar, ID_PFR1, 0x11); cpu->isar.id_dfr0 = 0x000; cpu->id_afr0 = 0; cpu->isar.id_mmfr0 = 0x00100103; @@ -505,8 +505,8 @@ static void cortex_a7_initfn(Object *obj) cpu->isar.mvfr1 = 0x11111111; cpu->ctr = 0x84448003; cpu->reset_sctlr = 0x00c50078; - cpu->isar.id_pfr0 = 0x00001131; - cpu->isar.id_pfr1 = 0x00011011; + SET_IDREG(isar, ID_PFR0, 0x00001131); + SET_IDREG(isar, ID_PFR1, 0x00011011); cpu->isar.id_dfr0 = 0x02010555; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10101105; @@ -556,8 +556,8 @@ static void cortex_a15_initfn(Object *obj) cpu->isar.mvfr1 = 0x11111111; cpu->ctr = 0x8444c004; cpu->reset_sctlr = 0x00c50078; - cpu->isar.id_pfr0 = 0x00001131; - cpu->isar.id_pfr1 = 0x00011011; + SET_IDREG(isar, ID_PFR0, 0x00001131); + SET_IDREG(isar, ID_PFR1, 0x00011011); cpu->isar.id_dfr0 = 0x02010555; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10201105; @@ -598,8 +598,8 @@ static void cortex_m0_initfn(Object *obj) * by looking at ID register fields. We use the same values as * for the M3. */ - cpu->isar.id_pfr0 = 0x00000030; - cpu->isar.id_pfr1 = 0x00000200; + SET_IDREG(&cpu->isar, ID_PFR0, 0x00000030); + SET_IDREG(&cpu->isar, ID_PFR1, 0x00000200); cpu->isar.id_dfr0 = 0x00100000; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00000030; @@ -625,8 +625,8 @@ static void cortex_m3_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_M_MAIN); cpu->midr = 0x410fc231; cpu->pmsav7_dregion = 8; - cpu->isar.id_pfr0 = 0x00000030; - cpu->isar.id_pfr1 = 0x00000200; + SET_IDREG(&cpu->isar, ID_PFR0, 0x00000030); + SET_IDREG(&cpu->isar, ID_PFR1, 0x00000200); cpu->isar.id_dfr0 = 0x00100000; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00000030; @@ -656,8 +656,8 @@ static void cortex_m4_initfn(Object *obj) cpu->isar.mvfr0 = 0x10110021; cpu->isar.mvfr1 = 0x11000011; cpu->isar.mvfr2 = 0x00000000; - cpu->isar.id_pfr0 = 0x00000030; - cpu->isar.id_pfr1 = 0x00000200; + SET_IDREG(&cpu->isar, ID_PFR0, 0x00000030); + SET_IDREG(&cpu->isar, ID_PFR1, 0x00000200); cpu->isar.id_dfr0 = 0x00100000; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00000030; @@ -687,8 +687,8 @@ static void cortex_m7_initfn(Object *obj) cpu->isar.mvfr0 = 0x10110221; cpu->isar.mvfr1 = 0x12000011; cpu->isar.mvfr2 = 0x00000040; - cpu->isar.id_pfr0 = 0x00000030; - cpu->isar.id_pfr1 = 0x00000200; + SET_IDREG(&cpu->isar, ID_PFR0, 0x00000030); + SET_IDREG(&cpu->isar, ID_PFR1, 0x00000200); cpu->isar.id_dfr0 = 0x00100000; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00100030; @@ -720,8 +720,8 @@ static void cortex_m33_initfn(Object *obj) cpu->isar.mvfr0 = 0x10110021; cpu->isar.mvfr1 = 0x11000011; cpu->isar.mvfr2 = 0x00000040; - cpu->isar.id_pfr0 = 0x00000030; - cpu->isar.id_pfr1 = 0x00000210; + SET_IDREG(&cpu->isar, ID_PFR0, 0x00000030); + SET_IDREG(&cpu->isar, ID_PFR1, 0x00000210); cpu->isar.id_dfr0 = 0x00200000; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00101F40; @@ -758,8 +758,8 @@ static void cortex_m55_initfn(Object *obj) cpu->isar.mvfr0 = 0x10110221; cpu->isar.mvfr1 = 0x12100211; cpu->isar.mvfr2 = 0x00000040; - cpu->isar.id_pfr0 = 0x20000030; - cpu->isar.id_pfr1 = 0x00000230; + SET_IDREG(&cpu->isar, ID_PFR0, 0x20000030); + SET_IDREG(&cpu->isar, ID_PFR1, 0x00000230); cpu->isar.id_dfr0 = 0x10200000; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00111040; @@ -797,8 +797,8 @@ static void cortex_r5_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_PMSA); set_feature(&cpu->env, ARM_FEATURE_PMU); cpu->midr = 0x411fc153; /* r1p3 */ - cpu->isar.id_pfr0 = 0x0131; - cpu->isar.id_pfr1 = 0x001; + SET_IDREG(isar, ID_PFR0, 0x0131); + SET_IDREG(isar, ID_PFR1, 0x001); cpu->isar.id_dfr0 = 0x010400; cpu->id_afr0 = 0x0; cpu->isar.id_mmfr0 = 0x0210030; @@ -836,8 +836,8 @@ static void cortex_r52_initfn(Object *obj) cpu->isar.mvfr2 = 0x00000043; cpu->ctr = 0x8144c004; cpu->reset_sctlr = 0x30c50838; - cpu->isar.id_pfr0 = 0x00000131; - cpu->isar.id_pfr1 = 0x10111001; + SET_IDREG(isar, ID_PFR0, 0x00000131); + SET_IDREG(isar, ID_PFR1, 0x10111001); cpu->isar.id_dfr0 = 0x03010006; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00211040; @@ -1096,8 +1096,8 @@ static void arm_max_initfn(Object *obj) cpu->isar.mvfr2 = 0x00000043; cpu->ctr = 0x8444c004; cpu->reset_sctlr = 0x00c50838; - cpu->isar.id_pfr0 = 0x00000131; - cpu->isar.id_pfr1 = 0x00011011; + SET_IDREG(isar, ID_PFR0, 0x00000131); + SET_IDREG(isar, ID_PFR1, 0x00011011); cpu->isar.id_dfr0 = 0x03010066; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10101105; diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c index 6be05f87f6..dbfeeb92a0 100644 --- a/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c @@ -74,8 +74,8 @@ static void aarch64_a35_initfn(Object *obj) cpu->midr = 0x411fd040; cpu->revidr = 0; cpu->ctr = 0x84448004; - cpu->isar.id_pfr0 = 0x00000131; - cpu->isar.id_pfr1 = 0x00011011; + SET_IDREG(isar, ID_PFR0, 0x00000131); + SET_IDREG(isar, ID_PFR1, 0x00011011); cpu->isar.id_dfr0 = 0x03010066; cpu->id_afr0 = 0; cpu->isar.id_mmfr0 = 0x10201105; @@ -262,9 +262,9 @@ static void aarch64_a55_initfn(Object *obj) cpu->isar.id_mmfr2 = 0x01260000; cpu->isar.id_mmfr3 = 0x02122211; cpu->isar.id_mmfr4 = 0x00021110; - cpu->isar.id_pfr0 = 0x10010131; - cpu->isar.id_pfr1 = 0x00011011; - cpu->isar.id_pfr2 = 0x00000011; + SET_IDREG(isar, ID_PFR0, 0x10010131); + SET_IDREG(isar, ID_PFR1, 0x00011011); + SET_IDREG(isar, ID_PFR2, 0x00000011); cpu->midr = 0x412FD050; /* r2p0 */ cpu->revidr = 0; @@ -312,8 +312,8 @@ static void aarch64_a72_initfn(Object *obj) cpu->isar.mvfr2 = 0x00000043; cpu->ctr = 0x8444c004; cpu->reset_sctlr = 0x00c50838; - cpu->isar.id_pfr0 = 0x00000131; - cpu->isar.id_pfr1 = 0x00011011; + SET_IDREG(isar, ID_PFR0, 0x00000131); + SET_IDREG(isar, ID_PFR1, 0x00011011); cpu->isar.id_dfr0 = 0x03010066; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10201105; @@ -387,9 +387,9 @@ static void aarch64_a76_initfn(Object *obj) cpu->isar.id_mmfr2 = 0x01260000; cpu->isar.id_mmfr3 = 0x02122211; cpu->isar.id_mmfr4 = 0x00021110; - cpu->isar.id_pfr0 = 0x10010131; - cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */ - cpu->isar.id_pfr2 = 0x00000011; + SET_IDREG(isar, ID_PFR0, 0x10010131); + SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */ + SET_IDREG(isar, ID_PFR2, 0x00000011); cpu->midr = 0x414fd0b1; /* r4p1 */ cpu->revidr = 0; @@ -627,9 +627,9 @@ static void aarch64_neoverse_n1_initfn(Object *obj) cpu->isar.id_mmfr2 = 0x01260000; cpu->isar.id_mmfr3 = 0x02122211; cpu->isar.id_mmfr4 = 0x00021110; - cpu->isar.id_pfr0 = 0x10010131; - cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */ - cpu->isar.id_pfr2 = 0x00000011; + SET_IDREG(isar, ID_PFR0, 0x10010131); + SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */ + SET_IDREG(isar, ID_PFR2, 0x00000011); cpu->midr = 0x414fd0c1; /* r4p1 */ cpu->revidr = 0; @@ -702,9 +702,9 @@ static void aarch64_neoverse_v1_initfn(Object *obj) cpu->isar.id_mmfr2 = 0x01260000; cpu->isar.id_mmfr3 = 0x02122211; cpu->isar.id_mmfr4 = 0x01021110; - cpu->isar.id_pfr0 = 0x21110131; - cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */ - cpu->isar.id_pfr2 = 0x00000011; + SET_IDREG(isar, ID_PFR0, 0x21110131); + SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */ + SET_IDREG(isar, ID_PFR2, 0x00000011); cpu->midr = 0x411FD402; /* r1p2 */ cpu->revidr = 0; @@ -899,8 +899,8 @@ static void aarch64_a710_initfn(Object *obj) /* Ordered by Section B.4: AArch64 registers */ cpu->midr = 0x412FD471; /* r2p1 */ cpu->revidr = 0; - cpu->isar.id_pfr0 = 0x21110131; - cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */ + SET_IDREG(isar, ID_PFR0, 0x21110131); + SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */ cpu->isar.id_dfr0 = 0x16011099; cpu->id_afr0 = 0; cpu->isar.id_mmfr0 = 0x10201105; @@ -918,7 +918,7 @@ static void aarch64_a710_initfn(Object *obj) cpu->isar.mvfr0 = 0x10110222; cpu->isar.mvfr1 = 0x13211111; cpu->isar.mvfr2 = 0x00000043; - cpu->isar.id_pfr2 = 0x00000011; + SET_IDREG(isar, ID_PFR2, 0x00000011); SET_IDREG(isar, ID_AA64PFR0, 0x1201111120111112ull); /* GIC filled in later */ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000221ull); SET_IDREG(isar, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */ @@ -997,8 +997,8 @@ static void aarch64_neoverse_n2_initfn(Object *obj) /* Ordered by Section B.5: AArch64 ID registers */ cpu->midr = 0x410FD493; /* r0p3 */ cpu->revidr = 0; - cpu->isar.id_pfr0 = 0x21110131; - cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */ + SET_IDREG(isar, ID_PFR0, 0x21110131); + SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */ cpu->isar.id_dfr0 = 0x16011099; cpu->id_afr0 = 0; cpu->isar.id_mmfr0 = 0x10201105; @@ -1016,7 +1016,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj) cpu->isar.mvfr0 = 0x10110222; cpu->isar.mvfr1 = 0x13211111; cpu->isar.mvfr2 = 0x00000043; - cpu->isar.id_pfr2 = 0x00000011; + SET_IDREG(isar, ID_PFR2, 0x00000011); SET_IDREG(isar, ID_AA64PFR0, 0x1201111120111112ull); /* GIC filled in later */ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000221ull); SET_IDREG(isar, ID_AA64ZFR0, 0x0000110100110021ull); /* with Crypto */ -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Sebastian Ott <sebott@redhat.com> Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- hw/intc/armv7m_nvic.c | 2 +- target/arm/cpu-features.h | 16 +++++++-------- target/arm/cpu.c | 13 +++++------- target/arm/cpu.h | 2 -- target/arm/cpu64.c | 6 +++--- target/arm/helper.c | 4 ++-- target/arm/kvm64.c | 6 ++---- target/arm/tcg/cpu32.c | 42 +++++++++++++++++++-------------------- target/arm/tcg/cpu64.c | 16 +++++++-------- 9 files changed, 49 insertions(+), 58 deletions(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index b613b2cafe..d0415d9acd 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -1274,7 +1274,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_dfr0; + return GET_IDREG(isar, ID_DFR0); case 0xd4c: /* AFR0. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index fe73988141..2af4b258de 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -296,22 +296,22 @@ static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id) static inline bool isar_feature_aa32_pmuv3p1(const ARMISARegisters *id) { /* 0xf means "non-standard IMPDEF PMU" */ - return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 4 && - FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf; + return FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) >= 4 && + FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) != 0xf; } static inline bool isar_feature_aa32_pmuv3p4(const ARMISARegisters *id) { /* 0xf means "non-standard IMPDEF PMU" */ - return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 5 && - FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf; + return FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) >= 5 && + FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) != 0xf; } static inline bool isar_feature_aa32_pmuv3p5(const ARMISARegisters *id) { /* 0xf means "non-standard IMPDEF PMU" */ - return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 6 && - FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf; + return FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) >= 6 && + FIELD_EX32_IDREG(id, ID_DFR0, PERFMON) != 0xf; } static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id) @@ -356,12 +356,12 @@ static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id) static inline bool isar_feature_aa32_debugv7p1(const ARMISARegisters *id) { - return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 5; + return FIELD_EX32_IDREG(id, ID_DFR0, COPDBG) >= 5; } static inline bool isar_feature_aa32_debugv8p2(const ARMISARegisters *id) { - return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 8; + return FIELD_EX32_IDREG(id, ID_DFR0, COPDBG) >= 8; } static inline bool isar_feature_aa32_doublelock(const ARMISARegisters *id) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 60654e8630..08d83c4e1a 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2151,7 +2151,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) * feature registers as well. */ FIELD_DP32_IDREG(isar, ID_PFR1, SECURITY, 0); - cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPSDBG, 0); + FIELD_DP32_IDREG(isar, ID_DFR0, COPSDBG, 0); FIELD_DP64_IDREG(isar, ID_AA64PFR0, EL3, 0); /* Disable the realm management extension, which requires EL3. */ @@ -2179,7 +2179,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) #endif } else { FIELD_DP64_IDREG(isar, ID_AA64DFR0, PMUVER, 0); - cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0); + FIELD_DP32_IDREG(isar, ID_DFR0, PERFMON, 0); cpu->pmceid0 = 0; cpu->pmceid1 = 0; } @@ -2227,15 +2227,12 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) FIELD_DP64_IDREG(isar, ID_AA64DFR0, TRACEBUFFER, 0); /* FEAT_TRF (Self-hosted Trace Extension) */ FIELD_DP64_IDREG(isar, ID_AA64DFR0, TRACEFILT, 0); - cpu->isar.id_dfr0 = - FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, TRACEFILT, 0); + FIELD_DP32_IDREG(isar, ID_DFR0, TRACEFILT, 0); /* Trace Macrocell system register access */ FIELD_DP64_IDREG(isar, ID_AA64DFR0, TRACEVER, 0); - cpu->isar.id_dfr0 = - FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPTRC, 0); + FIELD_DP32_IDREG(isar, ID_DFR0, COPTRC, 0); /* Memory mapped trace */ - cpu->isar.id_dfr0 = - FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, MMAPTRC, 0); + FIELD_DP32_IDREG(isar, ID_DFR0, MMAPTRC, 0); /* FEAT_AMU (Activity Monitors Extension) */ FIELD_DP64_IDREG(isar, ID_AA64PFR0, AMU, 0); FIELD_DP32_IDREG(isar, ID_PFR0, AMU, 0); diff --git a/target/arm/cpu.h b/target/arm/cpu.h index e9ef2fd484..7b9d2bfda4 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1067,8 +1067,6 @@ struct ArchCPU { uint32_t mvfr0; uint32_t mvfr1; uint32_t mvfr2; - uint32_t id_dfr0; - uint32_t id_dfr1; uint32_t dbgdidr; uint32_t dbgdevid; uint32_t dbgdevid1; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 2f24fc045c..f211493720 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -752,7 +752,7 @@ static void aarch64_a57_initfn(Object *obj) cpu->reset_sctlr = 0x00c50838; SET_IDREG(isar, ID_PFR0, 0x00000131); SET_IDREG(isar, ID_PFR1, 0x00011011); - cpu->isar.id_dfr0 = 0x03010066; + SET_IDREG(isar, ID_DFR0, 0x03010066); cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10101105; cpu->isar.id_mmfr1 = 0x40000000; @@ -810,7 +810,7 @@ static void aarch64_a53_initfn(Object *obj) cpu->reset_sctlr = 0x00c50838; SET_IDREG(isar, ID_PFR0, 0x00000131); SET_IDREG(isar, ID_PFR1, 0x00011011); - cpu->isar.id_dfr0 = 0x03010066; + SET_IDREG(isar, ID_DFR0, 0x03010066); cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10101105; cpu->isar.id_mmfr1 = 0x40000000; @@ -867,7 +867,7 @@ static void aarch64_a72_initfn(Object *obj) cpu->reset_sctlr = 0x00c50838; SET_IDREG(&cpu->isar, ID_PFR0, 0x00000131); SET_IDREG(&cpu->isar, ID_PFR1, 0x00011011); - cpu->isar.id_dfr0 = 0x03010066; + SET_IDREG(&cpu->isar, ID_DFR0, 0x03010066); cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10201105; cpu->isar.id_mmfr1 = 0x40000000; diff --git a/target/arm/helper.c b/target/arm/helper.c index 9895e8e74f..7e4a222d13 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8248,7 +8248,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa32_tid3, - .resetvalue = cpu->isar.id_dfr0 }, + .resetvalue = GET_IDREG(isar, ID_DFR0)}, { .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3, .access = PL1_R, .type = ARM_CP_CONST, @@ -8587,7 +8587,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, - .resetvalue = cpu->isar.id_dfr1 }, + .resetvalue = GET_IDREG(isar, ID_DFR1)}, { .name = "ID_MMFR5", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST, diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 74eba5ce47..56d5aa70a4 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -375,8 +375,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) */ err |= get_host_cpu_reg(fd, ahcf, ID_PFR0_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_PFR1_EL1_IDX); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0, - ARM64_SYS_REG(3, 0, 0, 1, 2)); + err |= get_host_cpu_reg(fd, ahcf, ID_DFR0_EL1_IDX); err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0, ARM64_SYS_REG(3, 0, 0, 1, 4)); err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr1, @@ -402,8 +401,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr2, ARM64_SYS_REG(3, 0, 0, 3, 2)); err |= get_host_cpu_reg(fd, ahcf, ID_PFR2_EL1_IDX); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr1, - ARM64_SYS_REG(3, 0, 0, 3, 5)); + err |= get_host_cpu_reg(fd, ahcf, ID_DFR1_EL1_IDX); err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr5, ARM64_SYS_REG(3, 0, 0, 3, 6)); diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c index dd949de260..3898b0d1bd 100644 --- a/target/arm/tcg/cpu32.c +++ b/target/arm/tcg/cpu32.c @@ -85,15 +85,13 @@ void aa32_max_features(ARMCPU *cpu) t = FIELD_DP32(t, ID_PFR2, SSBS, 1); /* FEAT_SSBS */ SET_IDREG(isar, ID_PFR2, t); - t = cpu->isar.id_dfr0; + t = GET_IDREG(isar, ID_DFR0); t = FIELD_DP32(t, ID_DFR0, COPDBG, 9); /* FEAT_Debugv8p4 */ t = FIELD_DP32(t, ID_DFR0, COPSDBG, 9); /* FEAT_Debugv8p4 */ t = FIELD_DP32(t, ID_DFR0, PERFMON, 6); /* FEAT_PMUv3p5 */ - cpu->isar.id_dfr0 = t; + SET_IDREG(isar, ID_DFR0, t); - t = cpu->isar.id_dfr1; - t = FIELD_DP32(t, ID_DFR1, HPMN0, 1); /* FEAT_HPMN0 */ - cpu->isar.id_dfr1 = t; + FIELD_DP32_IDREG(isar, ID_DFR1, HPMN0, 1); /* FEAT_HPMN0 */ } /* CPU models. These are not needed for the AArch64 linux-user build. */ @@ -231,7 +229,7 @@ static void arm1136_r2_initfn(Object *obj) cpu->reset_sctlr = 0x00050078; SET_IDREG(isar, ID_PFR0, 0x111); SET_IDREG(isar, ID_PFR1, 0x1); - cpu->isar.id_dfr0 = 0x2; + SET_IDREG(isar, ID_DFR0, 0x2); cpu->id_afr0 = 0x3; cpu->isar.id_mmfr0 = 0x01130003; cpu->isar.id_mmfr1 = 0x10030302; @@ -263,7 +261,7 @@ static void arm1136_initfn(Object *obj) cpu->reset_sctlr = 0x00050078; SET_IDREG(isar, ID_PFR0, 0x111); SET_IDREG(isar, ID_PFR1, 0x1); - cpu->isar.id_dfr0 = 0x2; + SET_IDREG(isar, ID_DFR0, 0x2); cpu->id_afr0 = 0x3; cpu->isar.id_mmfr0 = 0x01130003; cpu->isar.id_mmfr1 = 0x10030302; @@ -296,7 +294,7 @@ static void arm1176_initfn(Object *obj) cpu->reset_sctlr = 0x00050078; SET_IDREG(isar, ID_PFR0, 0x111); SET_IDREG(isar, ID_PFR1, 0x11); - cpu->isar.id_dfr0 = 0x33; + SET_IDREG(isar, ID_DFR0, 0x33); cpu->id_afr0 = 0; cpu->isar.id_mmfr0 = 0x01130003; cpu->isar.id_mmfr1 = 0x10030302; @@ -326,7 +324,7 @@ static void arm11mpcore_initfn(Object *obj) cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */ SET_IDREG(isar, ID_PFR0, 0x111); SET_IDREG(isar, ID_PFR1, 0x1); - cpu->isar.id_dfr0 = 0; + SET_IDREG(isar, ID_DFR0, 0); cpu->id_afr0 = 0x2; cpu->isar.id_mmfr0 = 0x01100103; cpu->isar.id_mmfr1 = 0x10020302; @@ -366,7 +364,7 @@ static void cortex_a8_initfn(Object *obj) cpu->reset_sctlr = 0x00c50078; SET_IDREG(isar, ID_PFR0, 0x1031); SET_IDREG(isar, ID_PFR1, 0x11); - cpu->isar.id_dfr0 = 0x400; + SET_IDREG(isar, ID_DFR0, 0x400); cpu->id_afr0 = 0; cpu->isar.id_mmfr0 = 0x31100003; cpu->isar.id_mmfr1 = 0x20000000; @@ -442,7 +440,7 @@ static void cortex_a9_initfn(Object *obj) cpu->reset_sctlr = 0x00c50078; SET_IDREG(isar, ID_PFR0, 0x1031); SET_IDREG(isar, ID_PFR1, 0x11); - cpu->isar.id_dfr0 = 0x000; + SET_IDREG(isar, ID_DFR0, 0x000); cpu->id_afr0 = 0; cpu->isar.id_mmfr0 = 0x00100103; cpu->isar.id_mmfr1 = 0x20000000; @@ -507,7 +505,7 @@ static void cortex_a7_initfn(Object *obj) cpu->reset_sctlr = 0x00c50078; SET_IDREG(isar, ID_PFR0, 0x00001131); SET_IDREG(isar, ID_PFR1, 0x00011011); - cpu->isar.id_dfr0 = 0x02010555; + SET_IDREG(isar, ID_DFR0, 0x02010555); cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10101105; cpu->isar.id_mmfr1 = 0x40000000; @@ -558,7 +556,7 @@ static void cortex_a15_initfn(Object *obj) cpu->reset_sctlr = 0x00c50078; SET_IDREG(isar, ID_PFR0, 0x00001131); SET_IDREG(isar, ID_PFR1, 0x00011011); - cpu->isar.id_dfr0 = 0x02010555; + SET_IDREG(isar, ID_DFR0, 0x02010555); cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10201105; cpu->isar.id_mmfr1 = 0x20000000; @@ -600,7 +598,7 @@ static void cortex_m0_initfn(Object *obj) */ SET_IDREG(&cpu->isar, ID_PFR0, 0x00000030); SET_IDREG(&cpu->isar, ID_PFR1, 0x00000200); - cpu->isar.id_dfr0 = 0x00100000; + SET_IDREG(&cpu->isar, ID_DFR0, 0x00100000); cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00000030; cpu->isar.id_mmfr1 = 0x00000000; @@ -627,7 +625,7 @@ static void cortex_m3_initfn(Object *obj) cpu->pmsav7_dregion = 8; SET_IDREG(&cpu->isar, ID_PFR0, 0x00000030); SET_IDREG(&cpu->isar, ID_PFR1, 0x00000200); - cpu->isar.id_dfr0 = 0x00100000; + SET_IDREG(&cpu->isar, ID_DFR0, 0x00100000); cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00000030; cpu->isar.id_mmfr1 = 0x00000000; @@ -658,7 +656,7 @@ static void cortex_m4_initfn(Object *obj) cpu->isar.mvfr2 = 0x00000000; SET_IDREG(&cpu->isar, ID_PFR0, 0x00000030); SET_IDREG(&cpu->isar, ID_PFR1, 0x00000200); - cpu->isar.id_dfr0 = 0x00100000; + SET_IDREG(&cpu->isar, ID_DFR0, 0x00100000); cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00000030; cpu->isar.id_mmfr1 = 0x00000000; @@ -689,7 +687,7 @@ static void cortex_m7_initfn(Object *obj) cpu->isar.mvfr2 = 0x00000040; SET_IDREG(&cpu->isar, ID_PFR0, 0x00000030); SET_IDREG(&cpu->isar, ID_PFR1, 0x00000200); - cpu->isar.id_dfr0 = 0x00100000; + SET_IDREG(&cpu->isar, ID_DFR0, 0x00100000); cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00100030; cpu->isar.id_mmfr1 = 0x00000000; @@ -722,7 +720,7 @@ static void cortex_m33_initfn(Object *obj) cpu->isar.mvfr2 = 0x00000040; SET_IDREG(&cpu->isar, ID_PFR0, 0x00000030); SET_IDREG(&cpu->isar, ID_PFR1, 0x00000210); - cpu->isar.id_dfr0 = 0x00200000; + SET_IDREG(&cpu->isar, ID_DFR0, 0x00200000); cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00101F40; cpu->isar.id_mmfr1 = 0x00000000; @@ -760,7 +758,7 @@ static void cortex_m55_initfn(Object *obj) cpu->isar.mvfr2 = 0x00000040; SET_IDREG(&cpu->isar, ID_PFR0, 0x20000030); SET_IDREG(&cpu->isar, ID_PFR1, 0x00000230); - cpu->isar.id_dfr0 = 0x10200000; + SET_IDREG(&cpu->isar, ID_DFR0, 0x10200000); cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00111040; cpu->isar.id_mmfr1 = 0x00000000; @@ -799,7 +797,7 @@ static void cortex_r5_initfn(Object *obj) cpu->midr = 0x411fc153; /* r1p3 */ SET_IDREG(isar, ID_PFR0, 0x0131); SET_IDREG(isar, ID_PFR1, 0x001); - cpu->isar.id_dfr0 = 0x010400; + SET_IDREG(isar, ID_DFR0, 0x010400); cpu->id_afr0 = 0x0; cpu->isar.id_mmfr0 = 0x0210030; cpu->isar.id_mmfr1 = 0x00000000; @@ -838,7 +836,7 @@ static void cortex_r52_initfn(Object *obj) cpu->reset_sctlr = 0x30c50838; SET_IDREG(isar, ID_PFR0, 0x00000131); SET_IDREG(isar, ID_PFR1, 0x10111001); - cpu->isar.id_dfr0 = 0x03010006; + SET_IDREG(isar, ID_DFR0, 0x03010006); cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00211040; cpu->isar.id_mmfr1 = 0x40000000; @@ -1098,7 +1096,7 @@ static void arm_max_initfn(Object *obj) cpu->reset_sctlr = 0x00c50838; SET_IDREG(isar, ID_PFR0, 0x00000131); SET_IDREG(isar, ID_PFR1, 0x00011011); - cpu->isar.id_dfr0 = 0x03010066; + SET_IDREG(isar, ID_DFR0, 0x03010066); cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10101105; cpu->isar.id_mmfr1 = 0x40000000; diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c index dbfeeb92a0..6646f265ee 100644 --- a/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c @@ -76,7 +76,7 @@ static void aarch64_a35_initfn(Object *obj) cpu->ctr = 0x84448004; SET_IDREG(isar, ID_PFR0, 0x00000131); SET_IDREG(isar, ID_PFR1, 0x00011011); - cpu->isar.id_dfr0 = 0x03010066; + SET_IDREG(isar, ID_DFR0, 0x03010066); cpu->id_afr0 = 0; cpu->isar.id_mmfr0 = 0x10201105; cpu->isar.id_mmfr1 = 0x40000000; @@ -249,7 +249,7 @@ static void aarch64_a55_initfn(Object *obj) SET_IDREG(isar, ID_AA64PFR0, 0x0000000010112222ull); SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000010ull); cpu->id_afr0 = 0x00000000; - cpu->isar.id_dfr0 = 0x04010088; + SET_IDREG(isar, ID_DFR0, 0x04010088); SET_IDREG(isar, ID_ISAR0, 0x02101110); SET_IDREG(isar, ID_ISAR1, 0x13112111); SET_IDREG(isar, ID_ISAR2, 0x21232042); @@ -314,7 +314,7 @@ static void aarch64_a72_initfn(Object *obj) cpu->reset_sctlr = 0x00c50838; SET_IDREG(isar, ID_PFR0, 0x00000131); SET_IDREG(isar, ID_PFR1, 0x00011011); - cpu->isar.id_dfr0 = 0x03010066; + SET_IDREG(isar, ID_DFR0, 0x03010066); cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10201105; cpu->isar.id_mmfr1 = 0x40000000; @@ -374,7 +374,7 @@ static void aarch64_a76_initfn(Object *obj) SET_IDREG(isar, ID_AA64PFR0, 0x1100000010111112ull); /* GIC filled in later */ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000010ull); cpu->id_afr0 = 0x00000000; - cpu->isar.id_dfr0 = 0x04010088; + SET_IDREG(isar, ID_DFR0, 0x04010088); SET_IDREG(isar, ID_ISAR0, 0x02101110); SET_IDREG(isar, ID_ISAR1, 0x13112111); SET_IDREG(isar, ID_ISAR2, 0x21232042); @@ -614,7 +614,7 @@ static void aarch64_neoverse_n1_initfn(Object *obj) SET_IDREG(isar, ID_AA64PFR0, 0x1100000010111112ull); /* GIC filled in later */ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000020ull); cpu->id_afr0 = 0x00000000; - cpu->isar.id_dfr0 = 0x04010088; + SET_IDREG(isar, ID_DFR0, 0x04010088); SET_IDREG(isar, ID_ISAR0, 0x02101110); SET_IDREG(isar, ID_ISAR1, 0x13112111); SET_IDREG(isar, ID_ISAR2, 0x21232042); @@ -689,7 +689,7 @@ static void aarch64_neoverse_v1_initfn(Object *obj) SET_IDREG(isar, ID_AA64PFR0, 0x1101110120111112ull); /* GIC filled in later */ SET_IDREG(isar, ID_AA64PFR1, 0x0000000000000020ull); cpu->id_afr0 = 0x00000000; - cpu->isar.id_dfr0 = 0x15011099; + SET_IDREG(isar, ID_DFR0, 0x15011099); SET_IDREG(isar, ID_ISAR0, 0x02101110); SET_IDREG(isar, ID_ISAR1, 0x13112111); SET_IDREG(isar, ID_ISAR2, 0x21232042); @@ -901,7 +901,7 @@ static void aarch64_a710_initfn(Object *obj) cpu->revidr = 0; SET_IDREG(isar, ID_PFR0, 0x21110131); SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */ - cpu->isar.id_dfr0 = 0x16011099; + SET_IDREG(isar, ID_DFR0, 0x16011099); cpu->id_afr0 = 0; cpu->isar.id_mmfr0 = 0x10201105; cpu->isar.id_mmfr1 = 0x40000000; @@ -999,7 +999,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj) cpu->revidr = 0; SET_IDREG(isar, ID_PFR0, 0x21110131); SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */ - cpu->isar.id_dfr0 = 0x16011099; + SET_IDREG(isar, ID_DFR0, 0x16011099); cpu->id_afr0 = 0; cpu->isar.id_mmfr0 = 0x10201105; cpu->isar.id_mmfr1 = 0x40000000; -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Sebastian Ott <sebott@redhat.com> Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- hw/intc/armv7m_nvic.c | 8 +-- target/arm/cpu-features.h | 18 ++--- target/arm/cpu.h | 6 -- target/arm/cpu64.c | 24 +++---- target/arm/helper.c | 12 ++-- target/arm/kvm64.c | 18 ++--- target/arm/tcg/cpu32.c | 142 ++++++++++++++++++-------------------- target/arm/tcg/cpu64.c | 76 ++++++++++---------- 8 files changed, 144 insertions(+), 160 deletions(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index d0415d9acd..e34ca591f0 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -1284,22 +1284,22 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_mmfr0; + return GET_IDREG(isar, ID_MMFR0); case 0xd54: /* MMFR1. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_mmfr1; + return GET_IDREG(isar, ID_MMFR1); case 0xd58: /* MMFR2. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_mmfr2; + return GET_IDREG(isar, ID_MMFR2); case 0xd5c: /* MMFR3. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_mmfr3; + return GET_IDREG(isar, ID_MMFR3); case 0xd60: /* ISAR0. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index 2af4b258de..46a1016302 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -280,17 +280,17 @@ static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id) static inline bool isar_feature_aa32_pxn(const ARMISARegisters *id) { - return FIELD_EX32(id->id_mmfr0, ID_MMFR0, VMSA) >= 4; + return FIELD_EX32_IDREG(id, ID_MMFR0, VMSA) >= 4; } static inline bool isar_feature_aa32_pan(const ARMISARegisters *id) { - return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) != 0; + return FIELD_EX32_IDREG(id, ID_MMFR3, PAN) != 0; } static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id) { - return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) >= 2; + return FIELD_EX32_IDREG(id, ID_MMFR3, PAN) >= 2; } static inline bool isar_feature_aa32_pmuv3p1(const ARMISARegisters *id) @@ -316,32 +316,32 @@ static inline bool isar_feature_aa32_pmuv3p5(const ARMISARegisters *id) static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id) { - return FIELD_EX32(id->id_mmfr4, ID_MMFR4, HPDS) != 0; + return FIELD_EX32_IDREG(id, ID_MMFR4, HPDS) != 0; } static inline bool isar_feature_aa32_ac2(const ARMISARegisters *id) { - return FIELD_EX32(id->id_mmfr4, ID_MMFR4, AC2) != 0; + return FIELD_EX32_IDREG(id, ID_MMFR4, AC2) != 0; } static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id) { - return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0; + return FIELD_EX32_IDREG(id, ID_MMFR4, CCIDX) != 0; } static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id) { - return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0; + return FIELD_EX32_IDREG(id, ID_MMFR4, XNX) != 0; } static inline bool isar_feature_aa32_half_evt(const ARMISARegisters *id) { - return FIELD_EX32(id->id_mmfr4, ID_MMFR4, EVT) >= 1; + return FIELD_EX32_IDREG(id, ID_MMFR4, EVT) >= 1; } static inline bool isar_feature_aa32_evt(const ARMISARegisters *id) { - return FIELD_EX32(id->id_mmfr4, ID_MMFR4, EVT) >= 2; + return FIELD_EX32_IDREG(id, ID_MMFR4, EVT) >= 2; } static inline bool isar_feature_aa32_dit(const ARMISARegisters *id) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 7b9d2bfda4..2c8f2ffd45 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1058,12 +1058,6 @@ struct ArchCPU { * field by reading the value from the KVM vCPU. */ struct ARMISARegisters { - uint32_t id_mmfr0; - uint32_t id_mmfr1; - uint32_t id_mmfr2; - uint32_t id_mmfr3; - uint32_t id_mmfr4; - uint32_t id_mmfr5; uint32_t mvfr0; uint32_t mvfr1; uint32_t mvfr2; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index f211493720..85a3b930e9 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -754,10 +754,10 @@ static void aarch64_a57_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x00011011); SET_IDREG(isar, ID_DFR0, 0x03010066); cpu->id_afr0 = 0x00000000; - cpu->isar.id_mmfr0 = 0x10101105; - cpu->isar.id_mmfr1 = 0x40000000; - cpu->isar.id_mmfr2 = 0x01260000; - cpu->isar.id_mmfr3 = 0x02102211; + SET_IDREG(isar, ID_MMFR0, 0x10101105); + SET_IDREG(isar, ID_MMFR1, 0x40000000); + SET_IDREG(isar, ID_MMFR2, 0x01260000); + SET_IDREG(isar, ID_MMFR3, 0x02102211); SET_IDREG(isar, ID_ISAR0, 0x02101110); SET_IDREG(isar, ID_ISAR1, 0x13112111); SET_IDREG(isar, ID_ISAR2, 0x21232042); @@ -812,10 +812,10 @@ static void aarch64_a53_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x00011011); SET_IDREG(isar, ID_DFR0, 0x03010066); cpu->id_afr0 = 0x00000000; - cpu->isar.id_mmfr0 = 0x10101105; - cpu->isar.id_mmfr1 = 0x40000000; - cpu->isar.id_mmfr2 = 0x01260000; - cpu->isar.id_mmfr3 = 0x02102211; + SET_IDREG(isar, ID_MMFR0, 0x10101105); + SET_IDREG(isar, ID_MMFR1, 0x40000000); + SET_IDREG(isar, ID_MMFR2, 0x01260000); + SET_IDREG(isar, ID_MMFR3, 0x02102211); SET_IDREG(isar, ID_ISAR0, 0x02101110); SET_IDREG(isar, ID_ISAR1, 0x13112111); SET_IDREG(isar, ID_ISAR2, 0x21232042); @@ -869,10 +869,10 @@ static void aarch64_a72_initfn(Object *obj) SET_IDREG(&cpu->isar, ID_PFR1, 0x00011011); SET_IDREG(&cpu->isar, ID_DFR0, 0x03010066); cpu->id_afr0 = 0x00000000; - cpu->isar.id_mmfr0 = 0x10201105; - cpu->isar.id_mmfr1 = 0x40000000; - cpu->isar.id_mmfr2 = 0x01260000; - cpu->isar.id_mmfr3 = 0x02102211; + SET_IDREG(&cpu->isar, ID_MMFR0, 0x10201105); + SET_IDREG(&cpu->isar, ID_MMFR1, 0x40000000); + SET_IDREG(&cpu->isar, ID_MMFR2, 0x01260000); + SET_IDREG(&cpu->isar, ID_MMFR3, 0x02102211); SET_IDREG(&cpu->isar, ID_ISAR0, 0x02101110); SET_IDREG(&cpu->isar, ID_ISAR1, 0x13112111); SET_IDREG(&cpu->isar, ID_ISAR2, 0x21232042); diff --git a/target/arm/helper.c b/target/arm/helper.c index 7e4a222d13..f50baa0f7b 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8258,22 +8258,22 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa32_tid3, - .resetvalue = cpu->isar.id_mmfr0 }, + .resetvalue = GET_IDREG(isar, ID_MMFR0)}, { .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa32_tid3, - .resetvalue = cpu->isar.id_mmfr1 }, + .resetvalue = GET_IDREG(isar, ID_MMFR1)}, { .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa32_tid3, - .resetvalue = cpu->isar.id_mmfr2 }, + .resetvalue = GET_IDREG(isar, ID_MMFR2)}, { .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa32_tid3, - .resetvalue = cpu->isar.id_mmfr3 }, + .resetvalue = GET_IDREG(isar, ID_MMFR3)}, { .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, @@ -8308,7 +8308,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa32_tid3, - .resetvalue = cpu->isar.id_mmfr4 }, + .resetvalue = GET_IDREG(isar, ID_MMFR4)}, { .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7, .access = PL1_R, .type = ARM_CP_CONST, @@ -8592,7 +8592,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, - .resetvalue = cpu->isar.id_mmfr5 }, + .resetvalue = GET_IDREG(isar, ID_MMFR5)}, { .name = "RES_0_C0_C3_7", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 7, .access = PL1_R, .type = ARM_CP_CONST, diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 56d5aa70a4..4e184fe1d5 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -376,14 +376,10 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) err |= get_host_cpu_reg(fd, ahcf, ID_PFR0_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_PFR1_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_DFR0_EL1_IDX); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0, - ARM64_SYS_REG(3, 0, 0, 1, 4)); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr1, - ARM64_SYS_REG(3, 0, 0, 1, 5)); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr2, - ARM64_SYS_REG(3, 0, 0, 1, 6)); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr3, - ARM64_SYS_REG(3, 0, 0, 1, 7)); + err |= get_host_cpu_reg(fd, ahcf, ID_MMFR0_EL1_IDX); + err |= get_host_cpu_reg(fd, ahcf, ID_MMFR1_EL1_IDX); + err |= get_host_cpu_reg(fd, ahcf, ID_MMFR2_EL1_IDX); + err |= get_host_cpu_reg(fd, ahcf, ID_MMFR3_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_ISAR0_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_ISAR1_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_ISAR2_EL1_IDX); @@ -391,8 +387,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) err |= get_host_cpu_reg(fd, ahcf, ID_ISAR4_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_ISAR5_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_ISAR6_EL1_IDX); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr4, - ARM64_SYS_REG(3, 0, 0, 2, 6)); + err |= get_host_cpu_reg(fd, ahcf, ID_MMFR4_EL1_IDX); err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr0, ARM64_SYS_REG(3, 0, 0, 3, 0)); @@ -402,8 +397,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) ARM64_SYS_REG(3, 0, 0, 3, 2)); err |= get_host_cpu_reg(fd, ahcf, ID_PFR2_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_DFR1_EL1_IDX); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr5, - ARM64_SYS_REG(3, 0, 0, 3, 6)); + err |= get_host_cpu_reg(fd, ahcf, ID_MMFR5_EL1_IDX); /* * DBGDIDR is a bit complicated because the kernel doesn't diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c index 3898b0d1bd..f58c20e81d 100644 --- a/target/arm/tcg/cpu32.c +++ b/target/arm/tcg/cpu32.c @@ -58,21 +58,17 @@ void aa32_max_features(ARMCPU *cpu) t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */ cpu->isar.mvfr2 = t; - t = cpu->isar.id_mmfr3; - t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* FEAT_PAN2 */ - cpu->isar.id_mmfr3 = t; + FIELD_DP32_IDREG(isar, ID_MMFR3, PAN, 2); /* FEAT_PAN2 */ - t = cpu->isar.id_mmfr4; + t = GET_IDREG(isar, ID_MMFR4); t = FIELD_DP32(t, ID_MMFR4, HPDS, 2); /* FEAT_HPDS2 */ t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */ t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* FEAT_TTCNP */ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* FEAT_XNX */ t = FIELD_DP32(t, ID_MMFR4, EVT, 2); /* FEAT_EVT */ - cpu->isar.id_mmfr4 = t; + SET_IDREG(isar, ID_MMFR4, t); - t = cpu->isar.id_mmfr5; - t = FIELD_DP32(t, ID_MMFR5, ETS, 1); /* FEAT_ETS */ - cpu->isar.id_mmfr5 = t; + FIELD_DP32_IDREG(isar, ID_MMFR5, ETS, 1); /* FEAT_ETS */ t = GET_IDREG(isar, ID_PFR0); t = FIELD_DP32(t, ID_PFR0, CSV2, 2); /* FEAT_CVS2 */ @@ -231,9 +227,9 @@ static void arm1136_r2_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x1); SET_IDREG(isar, ID_DFR0, 0x2); cpu->id_afr0 = 0x3; - cpu->isar.id_mmfr0 = 0x01130003; - cpu->isar.id_mmfr1 = 0x10030302; - cpu->isar.id_mmfr2 = 0x01222110; + SET_IDREG(isar, ID_MMFR0, 0x01130003); + SET_IDREG(isar, ID_MMFR1, 0x10030302); + SET_IDREG(isar, ID_MMFR2, 0x01222110); SET_IDREG(isar, ID_ISAR0, 0x00140011); SET_IDREG(isar, ID_ISAR1, 0x12002111); SET_IDREG(isar, ID_ISAR2, 0x11231111); @@ -263,9 +259,9 @@ static void arm1136_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x1); SET_IDREG(isar, ID_DFR0, 0x2); cpu->id_afr0 = 0x3; - cpu->isar.id_mmfr0 = 0x01130003; - cpu->isar.id_mmfr1 = 0x10030302; - cpu->isar.id_mmfr2 = 0x01222110; + SET_IDREG(isar, ID_MMFR0, 0x01130003); + SET_IDREG(isar, ID_MMFR1, 0x10030302); + SET_IDREG(isar, ID_MMFR2, 0x01222110); SET_IDREG(isar, ID_ISAR0, 0x00140011); SET_IDREG(isar, ID_ISAR1, 0x12002111); SET_IDREG(isar, ID_ISAR2, 0x11231111); @@ -296,9 +292,9 @@ static void arm1176_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x11); SET_IDREG(isar, ID_DFR0, 0x33); cpu->id_afr0 = 0; - cpu->isar.id_mmfr0 = 0x01130003; - cpu->isar.id_mmfr1 = 0x10030302; - cpu->isar.id_mmfr2 = 0x01222100; + SET_IDREG(isar, ID_MMFR0, 0x01130003); + SET_IDREG(isar, ID_MMFR1, 0x10030302); + SET_IDREG(isar, ID_MMFR2, 0x01222100); SET_IDREG(isar, ID_ISAR0, 0x0140011); SET_IDREG(isar, ID_ISAR1, 0x12002111); SET_IDREG(isar, ID_ISAR2, 0x11231121); @@ -326,9 +322,9 @@ static void arm11mpcore_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x1); SET_IDREG(isar, ID_DFR0, 0); cpu->id_afr0 = 0x2; - cpu->isar.id_mmfr0 = 0x01100103; - cpu->isar.id_mmfr1 = 0x10020302; - cpu->isar.id_mmfr2 = 0x01222000; + SET_IDREG(isar, ID_MMFR0, 0x01100103); + SET_IDREG(isar, ID_MMFR1, 0x10020302); + SET_IDREG(isar, ID_MMFR2, 0x01222000); SET_IDREG(isar, ID_ISAR0, 0x00100011); SET_IDREG(isar, ID_ISAR1, 0x12002111); SET_IDREG(isar, ID_ISAR2, 0x11221011); @@ -366,10 +362,10 @@ static void cortex_a8_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x11); SET_IDREG(isar, ID_DFR0, 0x400); cpu->id_afr0 = 0; - cpu->isar.id_mmfr0 = 0x31100003; - cpu->isar.id_mmfr1 = 0x20000000; - cpu->isar.id_mmfr2 = 0x01202000; - cpu->isar.id_mmfr3 = 0x11; + SET_IDREG(isar, ID_MMFR0, 0x31100003); + SET_IDREG(isar, ID_MMFR1, 0x20000000); + SET_IDREG(isar, ID_MMFR2, 0x01202000); + SET_IDREG(isar, ID_MMFR3, 0x11); SET_IDREG(isar, ID_ISAR0, 0x00101111); SET_IDREG(isar, ID_ISAR1, 0x12112111); SET_IDREG(isar, ID_ISAR2, 0x21232031); @@ -442,10 +438,10 @@ static void cortex_a9_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x11); SET_IDREG(isar, ID_DFR0, 0x000); cpu->id_afr0 = 0; - cpu->isar.id_mmfr0 = 0x00100103; - cpu->isar.id_mmfr1 = 0x20000000; - cpu->isar.id_mmfr2 = 0x01230000; - cpu->isar.id_mmfr3 = 0x00002111; + SET_IDREG(isar, ID_MMFR0, 0x00100103); + SET_IDREG(isar, ID_MMFR1, 0x20000000); + SET_IDREG(isar, ID_MMFR2, 0x01230000); + SET_IDREG(isar, ID_MMFR3, 0x00002111); SET_IDREG(isar, ID_ISAR0, 0x00101111); SET_IDREG(isar, ID_ISAR1, 0x13112111); SET_IDREG(isar, ID_ISAR2, 0x21232041); @@ -507,10 +503,10 @@ static void cortex_a7_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x00011011); SET_IDREG(isar, ID_DFR0, 0x02010555); cpu->id_afr0 = 0x00000000; - cpu->isar.id_mmfr0 = 0x10101105; - cpu->isar.id_mmfr1 = 0x40000000; - cpu->isar.id_mmfr2 = 0x01240000; - cpu->isar.id_mmfr3 = 0x02102211; + SET_IDREG(isar, ID_MMFR0, 0x10101105); + SET_IDREG(isar, ID_MMFR1, 0x40000000); + SET_IDREG(isar, ID_MMFR2, 0x01240000); + SET_IDREG(isar, ID_MMFR3, 0x02102211); /* * a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but * table 4-41 gives 0x02101110, which includes the arm div insns. @@ -558,10 +554,10 @@ static void cortex_a15_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x00011011); SET_IDREG(isar, ID_DFR0, 0x02010555); cpu->id_afr0 = 0x00000000; - cpu->isar.id_mmfr0 = 0x10201105; - cpu->isar.id_mmfr1 = 0x20000000; - cpu->isar.id_mmfr2 = 0x01240000; - cpu->isar.id_mmfr3 = 0x02102211; + SET_IDREG(isar, ID_MMFR0, 0x10201105); + SET_IDREG(isar, ID_MMFR1, 0x20000000); + SET_IDREG(isar, ID_MMFR2, 0x01240000); + SET_IDREG(isar, ID_MMFR3, 0x02102211); SET_IDREG(isar, ID_ISAR0, 0x02101110); SET_IDREG(isar, ID_ISAR1, 0x13112111); SET_IDREG(isar, ID_ISAR2, 0x21232041); @@ -600,10 +596,10 @@ static void cortex_m0_initfn(Object *obj) SET_IDREG(&cpu->isar, ID_PFR1, 0x00000200); SET_IDREG(&cpu->isar, ID_DFR0, 0x00100000); cpu->id_afr0 = 0x00000000; - cpu->isar.id_mmfr0 = 0x00000030; - cpu->isar.id_mmfr1 = 0x00000000; - cpu->isar.id_mmfr2 = 0x00000000; - cpu->isar.id_mmfr3 = 0x00000000; + SET_IDREG(&cpu->isar, ID_MMFR0, 0x00000030); + SET_IDREG(&cpu->isar, ID_MMFR1, 0x00000000); + SET_IDREG(&cpu->isar, ID_MMFR2, 0x00000000); + SET_IDREG(&cpu->isar, ID_MMFR3, 0x00000000); SET_IDREG(isar, ID_ISAR0, 0x01141110); SET_IDREG(isar, ID_ISAR1, 0x02111000); SET_IDREG(isar, ID_ISAR2, 0x21112231); @@ -627,10 +623,10 @@ static void cortex_m3_initfn(Object *obj) SET_IDREG(&cpu->isar, ID_PFR1, 0x00000200); SET_IDREG(&cpu->isar, ID_DFR0, 0x00100000); cpu->id_afr0 = 0x00000000; - cpu->isar.id_mmfr0 = 0x00000030; - cpu->isar.id_mmfr1 = 0x00000000; - cpu->isar.id_mmfr2 = 0x00000000; - cpu->isar.id_mmfr3 = 0x00000000; + SET_IDREG(&cpu->isar, ID_MMFR0, 0x00000030); + SET_IDREG(&cpu->isar, ID_MMFR1, 0x00000000); + SET_IDREG(&cpu->isar, ID_MMFR2, 0x00000000); + SET_IDREG(&cpu->isar, ID_MMFR3, 0x00000000); SET_IDREG(isar, ID_ISAR0, 0x01141110); SET_IDREG(isar, ID_ISAR1, 0x02111000); SET_IDREG(isar, ID_ISAR2, 0x21112231); @@ -658,10 +654,10 @@ static void cortex_m4_initfn(Object *obj) SET_IDREG(&cpu->isar, ID_PFR1, 0x00000200); SET_IDREG(&cpu->isar, ID_DFR0, 0x00100000); cpu->id_afr0 = 0x00000000; - cpu->isar.id_mmfr0 = 0x00000030; - cpu->isar.id_mmfr1 = 0x00000000; - cpu->isar.id_mmfr2 = 0x00000000; - cpu->isar.id_mmfr3 = 0x00000000; + SET_IDREG(&cpu->isar, ID_MMFR0, 0x00000030); + SET_IDREG(&cpu->isar, ID_MMFR1, 0x00000000); + SET_IDREG(&cpu->isar, ID_MMFR2, 0x00000000); + SET_IDREG(&cpu->isar, ID_MMFR3, 0x00000000); SET_IDREG(isar, ID_ISAR0, 0x01141110); SET_IDREG(isar, ID_ISAR1, 0x02111000); SET_IDREG(isar, ID_ISAR2, 0x21112231); @@ -689,10 +685,10 @@ static void cortex_m7_initfn(Object *obj) SET_IDREG(&cpu->isar, ID_PFR1, 0x00000200); SET_IDREG(&cpu->isar, ID_DFR0, 0x00100000); cpu->id_afr0 = 0x00000000; - cpu->isar.id_mmfr0 = 0x00100030; - cpu->isar.id_mmfr1 = 0x00000000; - cpu->isar.id_mmfr2 = 0x01000000; - cpu->isar.id_mmfr3 = 0x00000000; + SET_IDREG(&cpu->isar, ID_MMFR0, 0x00100030); + SET_IDREG(&cpu->isar, ID_MMFR1, 0x00000000); + SET_IDREG(&cpu->isar, ID_MMFR2, 0x01000000); + SET_IDREG(&cpu->isar, ID_MMFR3, 0x00000000); SET_IDREG(isar, ID_ISAR0, 0x01101110); SET_IDREG(isar, ID_ISAR1, 0x02112000); SET_IDREG(isar, ID_ISAR2, 0x20232231); @@ -722,10 +718,10 @@ static void cortex_m33_initfn(Object *obj) SET_IDREG(&cpu->isar, ID_PFR1, 0x00000210); SET_IDREG(&cpu->isar, ID_DFR0, 0x00200000); cpu->id_afr0 = 0x00000000; - cpu->isar.id_mmfr0 = 0x00101F40; - cpu->isar.id_mmfr1 = 0x00000000; - cpu->isar.id_mmfr2 = 0x01000000; - cpu->isar.id_mmfr3 = 0x00000000; + SET_IDREG(&cpu->isar, ID_MMFR0, 0x00101F40); + SET_IDREG(&cpu->isar, ID_MMFR1, 0x00000000); + SET_IDREG(&cpu->isar, ID_MMFR2, 0x01000000); + SET_IDREG(&cpu->isar, ID_MMFR3, 0x00000000); SET_IDREG(isar, ID_ISAR0, 0x01101110); SET_IDREG(isar, ID_ISAR1, 0x02212000); SET_IDREG(isar, ID_ISAR2, 0x20232232); @@ -760,10 +756,10 @@ static void cortex_m55_initfn(Object *obj) SET_IDREG(&cpu->isar, ID_PFR1, 0x00000230); SET_IDREG(&cpu->isar, ID_DFR0, 0x10200000); cpu->id_afr0 = 0x00000000; - cpu->isar.id_mmfr0 = 0x00111040; - cpu->isar.id_mmfr1 = 0x00000000; - cpu->isar.id_mmfr2 = 0x01000000; - cpu->isar.id_mmfr3 = 0x00000011; + SET_IDREG(&cpu->isar, ID_MMFR0, 0x00111040); + SET_IDREG(&cpu->isar, ID_MMFR1, 0x00000000); + SET_IDREG(&cpu->isar, ID_MMFR2, 0x01000000); + SET_IDREG(&cpu->isar, ID_MMFR3, 0x00000011); SET_IDREG(isar, ID_ISAR0, 0x01103110); SET_IDREG(isar, ID_ISAR1, 0x02212000); SET_IDREG(isar, ID_ISAR2, 0x20232232); @@ -799,10 +795,10 @@ static void cortex_r5_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x001); SET_IDREG(isar, ID_DFR0, 0x010400); cpu->id_afr0 = 0x0; - cpu->isar.id_mmfr0 = 0x0210030; - cpu->isar.id_mmfr1 = 0x00000000; - cpu->isar.id_mmfr2 = 0x01200000; - cpu->isar.id_mmfr3 = 0x0211; + SET_IDREG(isar, ID_MMFR0, 0x0210030); + SET_IDREG(isar, ID_MMFR1, 0x00000000); + SET_IDREG(isar, ID_MMFR2, 0x01200000); + SET_IDREG(isar, ID_MMFR3, 0x0211); SET_IDREG(isar, ID_ISAR0, 0x02101111); SET_IDREG(isar, ID_ISAR1, 0x13112111); SET_IDREG(isar, ID_ISAR2, 0x21232141); @@ -838,11 +834,11 @@ static void cortex_r52_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x10111001); SET_IDREG(isar, ID_DFR0, 0x03010006); cpu->id_afr0 = 0x00000000; - cpu->isar.id_mmfr0 = 0x00211040; - cpu->isar.id_mmfr1 = 0x40000000; - cpu->isar.id_mmfr2 = 0x01200000; - cpu->isar.id_mmfr3 = 0xf0102211; - cpu->isar.id_mmfr4 = 0x00000010; + SET_IDREG(isar, ID_MMFR0, 0x00211040); + SET_IDREG(isar, ID_MMFR1, 0x40000000); + SET_IDREG(isar, ID_MMFR2, 0x01200000); + SET_IDREG(isar, ID_MMFR3, 0xf0102211); + SET_IDREG(isar, ID_MMFR4, 0x00000010); SET_IDREG(isar, ID_ISAR0, 0x02101110); SET_IDREG(isar, ID_ISAR1, 0x13112111); SET_IDREG(isar, ID_ISAR2, 0x21232142); @@ -1098,10 +1094,10 @@ static void arm_max_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x00011011); SET_IDREG(isar, ID_DFR0, 0x03010066); cpu->id_afr0 = 0x00000000; - cpu->isar.id_mmfr0 = 0x10101105; - cpu->isar.id_mmfr1 = 0x40000000; - cpu->isar.id_mmfr2 = 0x01260000; - cpu->isar.id_mmfr3 = 0x02102211; + SET_IDREG(isar, ID_MMFR0, 0x10101105); + SET_IDREG(isar, ID_MMFR1, 0x40000000); + SET_IDREG(isar, ID_MMFR2, 0x01260000); + SET_IDREG(isar, ID_MMFR3, 0x02102211); SET_IDREG(isar, ID_ISAR0, 0x02101110); SET_IDREG(isar, ID_ISAR1, 0x13112111); SET_IDREG(isar, ID_ISAR2, 0x21232042); diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c index 6646f265ee..31a5a6b9c5 100644 --- a/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c @@ -78,10 +78,10 @@ static void aarch64_a35_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x00011011); SET_IDREG(isar, ID_DFR0, 0x03010066); cpu->id_afr0 = 0; - cpu->isar.id_mmfr0 = 0x10201105; - cpu->isar.id_mmfr1 = 0x40000000; - cpu->isar.id_mmfr2 = 0x01260000; - cpu->isar.id_mmfr3 = 0x02102211; + SET_IDREG(isar, ID_MMFR0, 0x10201105); + SET_IDREG(isar, ID_MMFR1, 0x40000000); + SET_IDREG(isar, ID_MMFR2, 0x01260000); + SET_IDREG(isar, ID_MMFR3, 0x02102211); SET_IDREG(isar, ID_ISAR0, 0x02101110); SET_IDREG(isar, ID_ISAR1, 0x13112111); SET_IDREG(isar, ID_ISAR2, 0x21232042); @@ -257,11 +257,11 @@ static void aarch64_a55_initfn(Object *obj) SET_IDREG(isar, ID_ISAR4, 0x00011142); SET_IDREG(isar, ID_ISAR5, 0x01011121); SET_IDREG(isar, ID_ISAR6, 0x00000010); - cpu->isar.id_mmfr0 = 0x10201105; - cpu->isar.id_mmfr1 = 0x40000000; - cpu->isar.id_mmfr2 = 0x01260000; - cpu->isar.id_mmfr3 = 0x02122211; - cpu->isar.id_mmfr4 = 0x00021110; + SET_IDREG(isar, ID_MMFR0, 0x10201105); + SET_IDREG(isar, ID_MMFR1, 0x40000000); + SET_IDREG(isar, ID_MMFR2, 0x01260000); + SET_IDREG(isar, ID_MMFR3, 0x02122211); + SET_IDREG(isar, ID_MMFR4, 0x00021110); SET_IDREG(isar, ID_PFR0, 0x10010131); SET_IDREG(isar, ID_PFR1, 0x00011011); SET_IDREG(isar, ID_PFR2, 0x00000011); @@ -316,10 +316,10 @@ static void aarch64_a72_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x00011011); SET_IDREG(isar, ID_DFR0, 0x03010066); cpu->id_afr0 = 0x00000000; - cpu->isar.id_mmfr0 = 0x10201105; - cpu->isar.id_mmfr1 = 0x40000000; - cpu->isar.id_mmfr2 = 0x01260000; - cpu->isar.id_mmfr3 = 0x02102211; + SET_IDREG(isar, ID_MMFR0, 0x10201105); + SET_IDREG(isar, ID_MMFR1, 0x40000000); + SET_IDREG(isar, ID_MMFR2, 0x01260000); + SET_IDREG(isar, ID_MMFR3, 0x02102211); SET_IDREG(isar, ID_ISAR0, 0x02101110); SET_IDREG(isar, ID_ISAR1, 0x13112111); SET_IDREG(isar, ID_ISAR2, 0x21232042); @@ -382,11 +382,11 @@ static void aarch64_a76_initfn(Object *obj) SET_IDREG(isar, ID_ISAR4, 0x00010142); SET_IDREG(isar, ID_ISAR5, 0x01011121); SET_IDREG(isar, ID_ISAR6, 0x00000010); - cpu->isar.id_mmfr0 = 0x10201105; - cpu->isar.id_mmfr1 = 0x40000000; - cpu->isar.id_mmfr2 = 0x01260000; - cpu->isar.id_mmfr3 = 0x02122211; - cpu->isar.id_mmfr4 = 0x00021110; + SET_IDREG(isar, ID_MMFR0, 0x10201105); + SET_IDREG(isar, ID_MMFR1, 0x40000000); + SET_IDREG(isar, ID_MMFR2, 0x01260000); + SET_IDREG(isar, ID_MMFR3, 0x02122211); + SET_IDREG(isar, ID_MMFR4, 0x00021110); SET_IDREG(isar, ID_PFR0, 0x10010131); SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */ SET_IDREG(isar, ID_PFR2, 0x00000011); @@ -622,11 +622,11 @@ static void aarch64_neoverse_n1_initfn(Object *obj) SET_IDREG(isar, ID_ISAR4, 0x00010142); SET_IDREG(isar, ID_ISAR5, 0x01011121); SET_IDREG(isar, ID_ISAR6, 0x00000010); - cpu->isar.id_mmfr0 = 0x10201105; - cpu->isar.id_mmfr1 = 0x40000000; - cpu->isar.id_mmfr2 = 0x01260000; - cpu->isar.id_mmfr3 = 0x02122211; - cpu->isar.id_mmfr4 = 0x00021110; + SET_IDREG(isar, ID_MMFR0, 0x10201105); + SET_IDREG(isar, ID_MMFR1, 0x40000000); + SET_IDREG(isar, ID_MMFR2, 0x01260000); + SET_IDREG(isar, ID_MMFR3, 0x02122211); + SET_IDREG(isar, ID_MMFR4, 0x00021110); SET_IDREG(isar, ID_PFR0, 0x10010131); SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */ SET_IDREG(isar, ID_PFR2, 0x00000011); @@ -697,11 +697,11 @@ static void aarch64_neoverse_v1_initfn(Object *obj) SET_IDREG(isar, ID_ISAR4, 0x00010142); SET_IDREG(isar, ID_ISAR5, 0x11011121); SET_IDREG(isar, ID_ISAR6, 0x01100111); - cpu->isar.id_mmfr0 = 0x10201105; - cpu->isar.id_mmfr1 = 0x40000000; - cpu->isar.id_mmfr2 = 0x01260000; - cpu->isar.id_mmfr3 = 0x02122211; - cpu->isar.id_mmfr4 = 0x01021110; + SET_IDREG(isar, ID_MMFR0, 0x10201105); + SET_IDREG(isar, ID_MMFR1, 0x40000000); + SET_IDREG(isar, ID_MMFR2, 0x01260000); + SET_IDREG(isar, ID_MMFR3, 0x02122211); + SET_IDREG(isar, ID_MMFR4, 0x01021110); SET_IDREG(isar, ID_PFR0, 0x21110131); SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */ SET_IDREG(isar, ID_PFR2, 0x00000011); @@ -903,17 +903,17 @@ static void aarch64_a710_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */ SET_IDREG(isar, ID_DFR0, 0x16011099); cpu->id_afr0 = 0; - cpu->isar.id_mmfr0 = 0x10201105; - cpu->isar.id_mmfr1 = 0x40000000; - cpu->isar.id_mmfr2 = 0x01260000; - cpu->isar.id_mmfr3 = 0x02122211; + SET_IDREG(isar, ID_MMFR0, 0x10201105); + SET_IDREG(isar, ID_MMFR1, 0x40000000); + SET_IDREG(isar, ID_MMFR2, 0x01260000); + SET_IDREG(isar, ID_MMFR3, 0x02122211); SET_IDREG(isar, ID_ISAR0, 0x02101110); SET_IDREG(isar, ID_ISAR1, 0x13112111); SET_IDREG(isar, ID_ISAR2, 0x21232042); SET_IDREG(isar, ID_ISAR3, 0x01112131); SET_IDREG(isar, ID_ISAR4, 0x00010142); SET_IDREG(isar, ID_ISAR5, 0x11011121); /* with Crypto */ - cpu->isar.id_mmfr4 = 0x21021110; + SET_IDREG(isar, ID_MMFR4, 0x21021110); SET_IDREG(isar, ID_ISAR6, 0x01111111); cpu->isar.mvfr0 = 0x10110222; cpu->isar.mvfr1 = 0x13211111; @@ -1001,17 +1001,17 @@ static void aarch64_neoverse_n2_initfn(Object *obj) SET_IDREG(isar, ID_PFR1, 0x00010000); /* GIC filled in later */ SET_IDREG(isar, ID_DFR0, 0x16011099); cpu->id_afr0 = 0; - cpu->isar.id_mmfr0 = 0x10201105; - cpu->isar.id_mmfr1 = 0x40000000; - cpu->isar.id_mmfr2 = 0x01260000; - cpu->isar.id_mmfr3 = 0x02122211; + SET_IDREG(isar, ID_MMFR0, 0x10201105); + SET_IDREG(isar, ID_MMFR1, 0x40000000); + SET_IDREG(isar, ID_MMFR2, 0x01260000); + SET_IDREG(isar, ID_MMFR3, 0x02122211); SET_IDREG(isar, ID_ISAR0, 0x02101110); SET_IDREG(isar, ID_ISAR1, 0x13112111); SET_IDREG(isar, ID_ISAR2, 0x21232042); SET_IDREG(isar, ID_ISAR3, 0x01112131); SET_IDREG(isar, ID_ISAR4, 0x00010142); SET_IDREG(isar, ID_ISAR5, 0x11011121); /* with Crypto */ - cpu->isar.id_mmfr4 = 0x01021110; + SET_IDREG(isar, ID_MMFR4, 0x01021110); SET_IDREG(isar, ID_ISAR6, 0x01111111); cpu->isar.mvfr0 = 0x10110222; cpu->isar.mvfr1 = 0x13211111; -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> Introduce scripts that automate the generation of system register definitions from a given linux source tree arch/arm64/tools/sysreg. Invocation of ./update-aarch64-sysreg-code.sh $PATH_TO_LINUX_SOURCE_TREE in scripts directory generates target/arm/cpu-sysregs.h.inc containing defines for all system registers. [CH: update to handle current kernel sysregs structure, and to emit the re-worked register structures; cpu properties will be added later] Reviewed-by: Sebastian Ott <sebott@redhat.com> Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- MAINTAINERS | 1 + scripts/arm-gen-cpu-sysregs-header.awk | 37 ++++++++++++++++++++++++++ scripts/update-aarch64-sysreg-code.sh | 32 ++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100755 scripts/arm-gen-cpu-sysregs-header.awk create mode 100755 scripts/update-aarch64-sysreg-code.sh diff --git a/MAINTAINERS b/MAINTAINERS index ada87bfa9e..73ae0ba448 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -459,6 +459,7 @@ M: Peter Maydell <peter.maydell@linaro.org> L: qemu-arm@nongnu.org S: Maintained F: target/arm/kvm.c +F: scripts/*-sysreg* MIPS KVM CPUs M: Huacai Chen <chenhuacai@kernel.org> diff --git a/scripts/arm-gen-cpu-sysregs-header.awk b/scripts/arm-gen-cpu-sysregs-header.awk new file mode 100755 index 0000000000..f92bbbafa7 --- /dev/null +++ b/scripts/arm-gen-cpu-sysregs-header.awk @@ -0,0 +1,37 @@ +#!/bin/awk -f +# SPDX-License-Identifier: GPL-2.0-or-later +# arm-gen-cpu-sysregs-header.awk: arm64 sysreg header include generator +# +# Usage: awk -f arm-gen-cpu-sysregs-header.awk $LINUX_PATH/arch/arm64/tools/sysreg + +BEGIN { + print "/* SPDX-License-Identifier: GPL-2.0-or-later */" + print "/* GENERATED FILE, DO NOT EDIT */" + print "/* use arm-gen-cpu-sysregs-header.awk to regenerate */" +} END { + print "" +} + +# skip blank lines and comment lines +/^$/ { next } +/^[\t ]*#/ { next } + +/^Sysreg\t/ || /^Sysreg /{ + + reg = $2 + op0 = $3 + op1 = $4 + crn = $5 + crm = $6 + op2 = $7 + + if (op0 == 3 && (op1==0 || op1==1 || op1==3) && crn==0 && (crm>=0 && crm<=7) && (op2>=0 && op2<=7)) { + print "DEF("reg", "op0", "op1", "crn", "crm", "op2")" + } + next +} + +{ + /* skip all other lines */ + next +} diff --git a/scripts/update-aarch64-sysreg-code.sh b/scripts/update-aarch64-sysreg-code.sh new file mode 100755 index 0000000000..7bba0bcd6f --- /dev/null +++ b/scripts/update-aarch64-sysreg-code.sh @@ -0,0 +1,32 @@ +#!/bin/sh -e +# +# SPDX-License-Identifier: GPL-2.0-or-later +# Update target/arm/cpu-sysregs.h +# from a linux source tree (arch/arm64/tools/sysreg) +# +# Copyright Red Hat, Inc. 2024 +# +# Authors: +# Eric Auger <eric.auger@redhat.com> +# + +scripts="$(dirname "$0")" +linux="$1" +output="$2" + +if [ -z "$linux" ] || ! [ -d "$linux" ]; then + cat << EOF +usage: update-aarch64-sysreg-code.sh LINUX_PATH [OUTPUT_PATH] + +LINUX_PATH Linux kernel directory to obtain the register definitions from +OUTPUT_PATH output directory, usually the qemu source tree (default: $PWD) +EOF + exit 1 +fi + +if [ -z "$output" ]; then + output="$PWD" +fi + +awk -f $scripts/arm-gen-cpu-sysregs-header.awk \ + $linux/arch/arm64/tools/sysreg > $output/target/arm/cpu-sysregs.h.inc -- 2.33.0

From: Cornelia Huck <cohuck@redhat.com> Generated against Linux 6.15. Reviewed-by: Sebastian Ott <sebott@redhat.com> Reviewed-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/cpu-sysregs.h.inc | 43 +++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc index cb99286f70..1dddd3d357 100644 --- a/target/arm/cpu-sysregs.h.inc +++ b/target/arm/cpu-sysregs.h.inc @@ -1,19 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -DEF(ID_AA64PFR0_EL1, 3, 0, 0, 4, 0) -DEF(ID_AA64PFR1_EL1, 3, 0, 0, 4, 1) -DEF(ID_AA64SMFR0_EL1, 3, 0, 0, 4, 5) -DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0) -DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1) -DEF(ID_AA64ISAR0_EL1, 3, 0, 0, 6, 0) -DEF(ID_AA64ISAR1_EL1, 3, 0, 0, 6, 1) -DEF(ID_AA64ISAR2_EL1, 3, 0, 0, 6, 2) -DEF(ID_AA64MMFR0_EL1, 3, 0, 0, 7, 0) -DEF(ID_AA64MMFR1_EL1, 3, 0, 0, 7, 1) -DEF(ID_AA64MMFR2_EL1, 3, 0, 0, 7, 2) -DEF(ID_AA64MMFR3_EL1, 3, 0, 0, 7, 3) +/* GENERATED FILE, DO NOT EDIT */ +/* use arm-gen-cpu-sysregs-header.awk to regenerate */ DEF(ID_PFR0_EL1, 3, 0, 0, 1, 0) DEF(ID_PFR1_EL1, 3, 0, 0, 1, 1) DEF(ID_DFR0_EL1, 3, 0, 0, 1, 2) +DEF(ID_AFR0_EL1, 3, 0, 0, 1, 3) DEF(ID_MMFR0_EL1, 3, 0, 0, 1, 4) DEF(ID_MMFR1_EL1, 3, 0, 0, 1, 5) DEF(ID_MMFR2_EL1, 3, 0, 0, 1, 6) @@ -24,13 +15,39 @@ DEF(ID_ISAR2_EL1, 3, 0, 0, 2, 2) DEF(ID_ISAR3_EL1, 3, 0, 0, 2, 3) DEF(ID_ISAR4_EL1, 3, 0, 0, 2, 4) DEF(ID_ISAR5_EL1, 3, 0, 0, 2, 5) -DEF(ID_MMFR4_EL1, 3, 0, 0, 2, 6) DEF(ID_ISAR6_EL1, 3, 0, 0, 2, 7) +DEF(ID_MMFR4_EL1, 3, 0, 0, 2, 6) DEF(MVFR0_EL1, 3, 0, 0, 3, 0) DEF(MVFR1_EL1, 3, 0, 0, 3, 1) DEF(MVFR2_EL1, 3, 0, 0, 3, 2) DEF(ID_PFR2_EL1, 3, 0, 0, 3, 4) DEF(ID_DFR1_EL1, 3, 0, 0, 3, 5) DEF(ID_MMFR5_EL1, 3, 0, 0, 3, 6) +DEF(ID_AA64PFR0_EL1, 3, 0, 0, 4, 0) +DEF(ID_AA64PFR1_EL1, 3, 0, 0, 4, 1) +DEF(ID_AA64PFR2_EL1, 3, 0, 0, 4, 2) DEF(ID_AA64ZFR0_EL1, 3, 0, 0, 4, 4) +DEF(ID_AA64SMFR0_EL1, 3, 0, 0, 4, 5) +DEF(ID_AA64FPFR0_EL1, 3, 0, 0, 4, 7) +DEF(ID_AA64DFR0_EL1, 3, 0, 0, 5, 0) +DEF(ID_AA64DFR1_EL1, 3, 0, 0, 5, 1) +DEF(ID_AA64DFR2_EL1, 3, 0, 0, 5, 2) +DEF(ID_AA64AFR0_EL1, 3, 0, 0, 5, 4) +DEF(ID_AA64AFR1_EL1, 3, 0, 0, 5, 5) +DEF(ID_AA64ISAR0_EL1, 3, 0, 0, 6, 0) +DEF(ID_AA64ISAR1_EL1, 3, 0, 0, 6, 1) +DEF(ID_AA64ISAR2_EL1, 3, 0, 0, 6, 2) +DEF(ID_AA64ISAR3_EL1, 3, 0, 0, 6, 3) +DEF(ID_AA64MMFR0_EL1, 3, 0, 0, 7, 0) +DEF(ID_AA64MMFR1_EL1, 3, 0, 0, 7, 1) +DEF(ID_AA64MMFR2_EL1, 3, 0, 0, 7, 2) +DEF(ID_AA64MMFR3_EL1, 3, 0, 0, 7, 3) +DEF(ID_AA64MMFR4_EL1, 3, 0, 0, 7, 4) +DEF(CCSIDR_EL1, 3, 1, 0, 0, 0) +DEF(CLIDR_EL1, 3, 1, 0, 0, 1) +DEF(CCSIDR2_EL1, 3, 1, 0, 0, 2) +DEF(GMID_EL1, 3, 1, 0, 0, 4) +DEF(SMIDR_EL1, 3, 1, 0, 0, 6) DEF(CTR_EL0, 3, 3, 0, 0, 1) +DEF(DCZID_EL0, 3, 3, 0, 0, 7) + -- 2.33.0

From: Cornelia Huck <cohuck@redhat.com> We have fd, so might as well neaten things up. Suggested-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/kvm64.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 4e184fe1d5..bdac9ef549 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -389,11 +389,11 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) err |= get_host_cpu_reg(fd, ahcf, ID_ISAR6_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_MMFR4_EL1_IDX); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr0, + err |= read_sys_reg32(fd, &ahcf->isar.mvfr0, ARM64_SYS_REG(3, 0, 0, 3, 0)); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr1, + err |= read_sys_reg32(fd, &ahcf->isar.mvfr1, ARM64_SYS_REG(3, 0, 0, 3, 1)); - err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr2, + err |= read_sys_reg32(fd, &ahcf->isar.mvfr2, ARM64_SYS_REG(3, 0, 0, 3, 2)); err |= get_host_cpu_reg(fd, ahcf, ID_PFR2_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_DFR1_EL1_IDX); @@ -431,7 +431,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) if (pmu_supported) { /* PMCR_EL0 is only accessible if the vCPU has feature PMU_V3 */ - err |= read_sys_reg64(fdarray[2], &ahcf->isar.reset_pmcr_el0, + err |= read_sys_reg64(fd, &ahcf->isar.reset_pmcr_el0, KVM_REG_ARM_PMCR_EL0); } -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> The known ID regs are described in a new initialization function dubbed initialize_cpu_sysreg_properties(). That code will be automatically generated from linux arch/arm64/tools/sysreg. For the time being let's just describe a single id reg, CTR_EL0. In this description we only care about non RES/RAZ fields, ie. named fields. The registers are populated in an array indexed by ARMIDRegisterIdx and their fields are added in a sorted list. [CH: adapted to reworked register storage] Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/cpu-custom.h | 60 ++++++++++++++++++++++++++++++ target/arm/cpu-sysreg-properties.c | 41 ++++++++++++++++++++ target/arm/cpu64.c | 2 + target/arm/meson.build | 1 + 4 files changed, 104 insertions(+) create mode 100644 target/arm/cpu-custom.h create mode 100644 target/arm/cpu-sysreg-properties.c diff --git a/target/arm/cpu-custom.h b/target/arm/cpu-custom.h new file mode 100644 index 0000000000..615347376e --- /dev/null +++ b/target/arm/cpu-custom.h @@ -0,0 +1,60 @@ +/* + * handle ID registers and their fields + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef ARM_CPU_CUSTOM_H +#define ARM_CPU_CUSTOM_H + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "cpu.h" +#include "cpu-sysregs.h" + +typedef struct ARM64SysRegField { + const char *name; /* name of the field, for instance CTR_EL0_IDC */ + int index; + int lower; + int upper; +} ARM64SysRegField; + +typedef struct ARM64SysReg { + const char *name; /* name of the sysreg, for instance CTR_EL0 */ + ARMSysRegs sysreg; + int index; + GList *fields; /* list of named fields, excluding RES* */ +} ARM64SysReg; + +void initialize_cpu_sysreg_properties(void); + +/* + * List of exposed ID regs (automatically populated from linux + * arch/arm64/tools/sysreg) + */ +extern ARM64SysReg arm64_id_regs[NUM_ID_IDX]; + +/* Allocate a new field and insert it at the head of the @reg list */ +static inline GList *arm64_sysreg_add_field(ARM64SysReg *reg, const char *name, + uint8_t min, uint8_t max) { + + ARM64SysRegField *field = g_new0(ARM64SysRegField, 1); + + field->name = name; + field->lower = min; + field->upper = max; + field->index = reg->index; + + reg->fields = g_list_append(reg->fields, field); + return reg->fields; +} + +static inline ARM64SysReg *arm64_sysreg_get(ARMIDRegisterIdx index) +{ + ARM64SysReg *reg = &arm64_id_regs[index]; + + reg->index = index; + reg->sysreg = id_register_sysreg[index]; + return reg; +} + +#endif diff --git a/target/arm/cpu-sysreg-properties.c b/target/arm/cpu-sysreg-properties.c new file mode 100644 index 0000000000..8b7ef5badf --- /dev/null +++ b/target/arm/cpu-sysreg-properties.c @@ -0,0 +1,41 @@ +/* + * QEMU ARM CPU SYSREG PROPERTIES + * to be generated from linux sysreg + * + * Copyright (c) Red Hat, Inc. 2024 + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + * <http://www.gnu.org/licenses/gpl-2.0.html> + */ + +#include "cpu-custom.h" + +ARM64SysReg arm64_id_regs[NUM_ID_IDX]; + +void initialize_cpu_sysreg_properties(void) +{ + memset(arm64_id_regs, 0, sizeof(ARM64SysReg) * NUM_ID_IDX); + /* CTR_EL0 */ + ARM64SysReg *CTR_EL0 = arm64_sysreg_get(CTR_EL0_IDX); + CTR_EL0->name = "CTR_EL0"; + arm64_sysreg_add_field(CTR_EL0, "TminLine", 32, 37); + arm64_sysreg_add_field(CTR_EL0, "DIC", 29, 29); + arm64_sysreg_add_field(CTR_EL0, "IDC", 28, 28); + arm64_sysreg_add_field(CTR_EL0, "CWG", 24, 27); + arm64_sysreg_add_field(CTR_EL0, "ERG", 20, 23); + arm64_sysreg_add_field(CTR_EL0, "DminLine", 16, 19); + arm64_sysreg_add_field(CTR_EL0, "L1Ip", 14, 15); + arm64_sysreg_add_field(CTR_EL0, "IminLine", 0, 3); +} + diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 85a3b930e9..828840c1d6 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -34,6 +34,7 @@ #include "internals.h" #include "cpu-features.h" #include "cpregs.h" +#include "cpu-custom.h" /* convert between <register>_IDX and SYS_<register> */ #define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \ @@ -1071,6 +1072,7 @@ static void aarch64_cpu_register_types(void) { size_t i; + initialize_cpu_sysreg_properties(); type_register_static(&aarch64_cpu_type_info); for (i = 0; i < ARRAY_SIZE(aarch64_cpus); ++i) { diff --git a/target/arm/meson.build b/target/arm/meson.build index 7973b35cca..963ad9592b 100644 --- a/target/arm/meson.build +++ b/target/arm/meson.build @@ -15,6 +15,7 @@ arm_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c', 'kvm64.c', 'kvm-tmm.c'), arm_ss.add(when: 'TARGET_AARCH64', if_true: files( 'cpu64.c', 'gdbstub64.c', + 'cpu-sysreg-properties.c', )) arm_system_ss = ss.source_set() -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> Introduce a script that automates the generation of system register properties definitions from a given linux source tree arch/arm64/tools/sysreg. Invocation of ./update-aarch64-sysreg-code.sh $PATH_TO_LINUX_SOURCE_TREE in scripts directory additionally generates target/arm/cpu-sysreg-properties.c containing definitions for feature ID registers. update-aarch64-sysreg-code.sh additionally calls gen-cpu-sysreg-properties.awk which is inherited from kernel arch/arm64/tools/gen-sysreg.awk. All credits to Mark Rutland the original author of this script. [CH: split off from original patch adding both sysreg definitions and properties] Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- scripts/gen-cpu-sysreg-properties.awk | 325 ++++++++++++++++++++++++++ scripts/update-aarch64-sysreg-code.sh | 5 +- 2 files changed, 329 insertions(+), 1 deletion(-) create mode 100755 scripts/gen-cpu-sysreg-properties.awk diff --git a/scripts/gen-cpu-sysreg-properties.awk b/scripts/gen-cpu-sysreg-properties.awk new file mode 100755 index 0000000000..da00d377ff --- /dev/null +++ b/scripts/gen-cpu-sysreg-properties.awk @@ -0,0 +1,325 @@ +#!/bin/awk -f +# SPDX-License-Identifier: GPL-2.0 +# gen-cpu-sysreg-properties.awk: arm64 sysreg header generator +# +# Usage: awk -f gen-cpu-sysreg-properties.awk $LINUX_PATH/arch/arm64/tools/sysreg + +function block_current() { + return __current_block[__current_block_depth]; +} + +# Log an error and terminate +function fatal(msg) { + print "Error at " NR ": " msg > "/dev/stderr" + + printf "Current block nesting:" + + for (i = 0; i <= __current_block_depth; i++) { + printf " " __current_block[i] + } + printf "\n" + + exit 1 +} + +# Enter a new block, setting the active block to @block +function block_push(block) { + __current_block[++__current_block_depth] = block +} + +# Exit a block, setting the active block to the parent block +function block_pop() { + if (__current_block_depth == 0) + fatal("error: block_pop() in root block") + + __current_block_depth--; +} + +# Sanity check the number of records for a field makes sense. If not, produce +# an error and terminate. +function expect_fields(nf) { + if (NF != nf) + fatal(NF " fields found where " nf " expected") +} + +# Print a CPP macro definition, padded with spaces so that the macro bodies +# line up in a column +function define(name, val) { + printf "%-56s%s\n", "#define " name, val +} + +# Print standard BITMASK/SHIFT/WIDTH CPP definitions for a field +function define_field(reg, field, msb, lsb, idreg) { + if (idreg) + print " arm64_sysreg_add_field("reg", \""field"\", "lsb", "msb");" +} + +# Print a field _SIGNED definition for a field +function define_field_sign(reg, field, sign, idreg) { + if (idreg) + print " arm64_sysreg_add_field("reg", \""field"\", "lsb", "msb");" +} + +# Parse a "<msb>[:<lsb>]" string into the global variables @msb and @lsb +function parse_bitdef(reg, field, bitdef, _bits) +{ + if (bitdef ~ /^[0-9]+$/) { + msb = bitdef + lsb = bitdef + } else if (split(bitdef, _bits, ":") == 2) { + msb = _bits[1] + lsb = _bits[2] + } else { + fatal("invalid bit-range definition '" bitdef "'") + } + + + if (msb != next_bit) + fatal(reg "." field " starts at " msb " not " next_bit) + if (63 < msb || msb < 0) + fatal(reg "." field " invalid high bit in '" bitdef "'") + if (63 < lsb || lsb < 0) + fatal(reg "." field " invalid low bit in '" bitdef "'") + if (msb < lsb) + fatal(reg "." field " invalid bit-range '" bitdef "'") + if (low > high) + fatal(reg "." field " has invalid range " high "-" low) + + next_bit = lsb - 1 +} + +BEGIN { + print "#include \"cpu-custom.h\"" + print "" + print "ARM64SysReg arm64_id_regs[NUM_ID_IDX];" + print "" + print "void initialize_cpu_sysreg_properties(void)" + print "{" + print " memset(arm64_id_regs, 0, sizeof(ARM64SysReg) * NUM_ID_IDX);" + print "" + + __current_block_depth = 0 + __current_block[__current_block_depth] = "Root" +} + +END { + if (__current_block_depth != 0) + fatal("Missing terminator for " block_current() " block") + + print "}" +} + +# skip blank lines and comment lines +/^$/ { next } +/^[\t ]*#/ { next } + +/^SysregFields/ && block_current() == "Root" { + block_push("SysregFields") + + expect_fields(2) + + reg = $2 + + res0 = "UL(0)" + res1 = "UL(0)" + unkn = "UL(0)" + + next_bit = 63 + + next +} + +/^EndSysregFields/ && block_current() == "SysregFields" { + if (next_bit > 0) + fatal("Unspecified bits in " reg) + + reg = null + res0 = null + res1 = null + unkn = null + + block_pop() + next +} + +/^Sysreg/ && block_current() == "Root" { + block_push("Sysreg") + + expect_fields(7) + + reg = $2 + op0 = $3 + op1 = $4 + crn = $5 + crm = $6 + op2 = $7 + + res0 = "UL(0)" + res1 = "UL(0)" + unkn = "UL(0)" + + if (op0 == 3 && (op1<2 || op1==3) && crn==0 && (crm>=0 && crm<=7) && (op2>=0 && op2<=7)) { + idreg = 1 + } else { + idreg = 0 + } + + if (idreg == 1) { + print " /* "reg" */" + print " ARM64SysReg *"reg" = arm64_sysreg_get("reg"_IDX);" + print " "reg"->name = \""reg"\";" + } + + next_bit = 63 + + next +} + +/^EndSysreg/ && block_current() == "Sysreg" { + if (next_bit > 0) + fatal("Unspecified bits in " reg) + + reg = null + op0 = null + op1 = null + crn = null + crm = null + op2 = null + res0 = null + res1 = null + unkn = null + + if (idreg==1) + print "" + block_pop() + next +} + +# Currently this is effectivey a comment, in future we may want to emit +# defines for the fields. +(/^Fields/ || /^Mapping/) && block_current() == "Sysreg" { + expect_fields(2) + + if (next_bit != 63) + fatal("Some fields already defined for " reg) + + print "/* For " reg " fields see " $2 " */" + print "" + + next_bit = 0 + res0 = null + res1 = null + unkn = null + + next +} + + +/^Res0/ && (block_current() == "Sysreg" || block_current() == "SysregFields") { + expect_fields(2) + parse_bitdef(reg, "RES0", $2) + field = "RES0_" msb "_" lsb + + res0 = res0 " | GENMASK_ULL(" msb ", " lsb ")" + + next +} + +/^Res1/ && (block_current() == "Sysreg" || block_current() == "SysregFields") { + expect_fields(2) + parse_bitdef(reg, "RES1", $2) + field = "RES1_" msb "_" lsb + + res1 = res1 " | GENMASK_ULL(" msb ", " lsb ")" + + next +} + +/^Unkn/ && (block_current() == "Sysreg" || block_current() == "SysregFields") { + expect_fields(2) + parse_bitdef(reg, "UNKN", $2) + field = "UNKN_" msb "_" lsb + + unkn = unkn " | GENMASK_ULL(" msb ", " lsb ")" + + next +} + +/^Field/ && (block_current() == "Sysreg" || block_current() == "SysregFields") { + expect_fields(3) + field = $3 + parse_bitdef(reg, field, $2) + + + define_field(reg, field, msb, lsb, idreg) + + next +} + +/^Raz/ && (block_current() == "Sysreg" || block_current() == "SysregFields") { + expect_fields(2) + parse_bitdef(reg, field, $2) + + next +} + +/^SignedEnum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") { + block_push("Enum") + + expect_fields(3) + field = $3 + parse_bitdef(reg, field, $2) + + define_field(reg, field, msb, lsb, idreg) + define_field_sign(reg, field, "true", idreg) + + next +} + +/^UnsignedEnum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") { + block_push("Enum") + + expect_fields(3) + field = $3 + parse_bitdef(reg, field, $2) + + define_field(reg, field, msb, lsb, idreg) + #define_field_sign(reg, field, "false", idreg) + + next +} + +/^Enum/ && (block_current() == "Sysreg" || block_current() == "SysregFields") { + block_push("Enum") + + expect_fields(3) + field = $3 + parse_bitdef(reg, field, $2) + + define_field(reg, field, msb, lsb, idreg) + + next +} + +/^EndEnum/ && block_current() == "Enum" { + + field = null + msb = null + lsb = null + + block_pop() + next +} + +/0b[01]+/ && block_current() == "Enum" { + expect_fields(2) + val = $1 + name = $2 + + next +} + +# Any lines not handled by previous rules are unexpected +{ + fatal("unhandled statement") +} diff --git a/scripts/update-aarch64-sysreg-code.sh b/scripts/update-aarch64-sysreg-code.sh index 7bba0bcd6f..764c63a9cc 100755 --- a/scripts/update-aarch64-sysreg-code.sh +++ b/scripts/update-aarch64-sysreg-code.sh @@ -1,7 +1,7 @@ #!/bin/sh -e # # SPDX-License-Identifier: GPL-2.0-or-later -# Update target/arm/cpu-sysregs.h +# Update target/arm/cpu-sysreg-properties.c and target/arm/cpu-sysregs.h # from a linux source tree (arch/arm64/tools/sysreg) # # Copyright Red Hat, Inc. 2024 @@ -30,3 +30,6 @@ fi awk -f $scripts/arm-gen-cpu-sysregs-header.awk \ $linux/arch/arm64/tools/sysreg > $output/target/arm/cpu-sysregs.h.inc + +awk -f $scripts/gen-cpu-sysreg-properties.awk \ + $linux/arch/arm64/tools/sysreg > $output/target/arm/cpu-sysreg-properties.c \ No newline at end of file -- 2.33.0

From: Cornelia Huck <cohuck@redhat.com> Generated against Linux 6.14-rc4. Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/cpu-sysreg-properties.c | 748 ++++++++++++++++++++++++++++- 1 file changed, 726 insertions(+), 22 deletions(-) diff --git a/target/arm/cpu-sysreg-properties.c b/target/arm/cpu-sysreg-properties.c index 8b7ef5badf..94cc496438 100644 --- a/target/arm/cpu-sysreg-properties.c +++ b/target/arm/cpu-sysreg-properties.c @@ -1,24 +1,3 @@ -/* - * QEMU ARM CPU SYSREG PROPERTIES - * to be generated from linux sysreg - * - * Copyright (c) Red Hat, Inc. 2024 - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see - * <http://www.gnu.org/licenses/gpl-2.0.html> - */ - #include "cpu-custom.h" ARM64SysReg arm64_id_regs[NUM_ID_IDX]; @@ -26,6 +5,657 @@ ARM64SysReg arm64_id_regs[NUM_ID_IDX]; void initialize_cpu_sysreg_properties(void) { memset(arm64_id_regs, 0, sizeof(ARM64SysReg) * NUM_ID_IDX); + +/* For SPMACCESSR_EL12 fields see SPMACCESSR_EL1 */ + + /* ID_PFR0_EL1 */ + ARM64SysReg *ID_PFR0_EL1 = arm64_sysreg_get(ID_PFR0_EL1_IDX); + ID_PFR0_EL1->name = "ID_PFR0_EL1"; + arm64_sysreg_add_field(ID_PFR0_EL1, "RAS", 28, 31); + arm64_sysreg_add_field(ID_PFR0_EL1, "DIT", 24, 27); + arm64_sysreg_add_field(ID_PFR0_EL1, "AMU", 20, 23); + arm64_sysreg_add_field(ID_PFR0_EL1, "CSV2", 16, 19); + arm64_sysreg_add_field(ID_PFR0_EL1, "State3", 12, 15); + arm64_sysreg_add_field(ID_PFR0_EL1, "State2", 8, 11); + arm64_sysreg_add_field(ID_PFR0_EL1, "State1", 4, 7); + arm64_sysreg_add_field(ID_PFR0_EL1, "State0", 0, 3); + + /* ID_PFR1_EL1 */ + ARM64SysReg *ID_PFR1_EL1 = arm64_sysreg_get(ID_PFR1_EL1_IDX); + ID_PFR1_EL1->name = "ID_PFR1_EL1"; + arm64_sysreg_add_field(ID_PFR1_EL1, "GIC", 28, 31); + arm64_sysreg_add_field(ID_PFR1_EL1, "Virt_frac", 24, 27); + arm64_sysreg_add_field(ID_PFR1_EL1, "Sec_frac", 20, 23); + arm64_sysreg_add_field(ID_PFR1_EL1, "GenTimer", 16, 19); + arm64_sysreg_add_field(ID_PFR1_EL1, "Virtualization", 12, 15); + arm64_sysreg_add_field(ID_PFR1_EL1, "MProgMod", 8, 11); + arm64_sysreg_add_field(ID_PFR1_EL1, "Security", 4, 7); + arm64_sysreg_add_field(ID_PFR1_EL1, "ProgMod", 0, 3); + + /* ID_DFR0_EL1 */ + ARM64SysReg *ID_DFR0_EL1 = arm64_sysreg_get(ID_DFR0_EL1_IDX); + ID_DFR0_EL1->name = "ID_DFR0_EL1"; + arm64_sysreg_add_field(ID_DFR0_EL1, "TraceFilt", 28, 31); + arm64_sysreg_add_field(ID_DFR0_EL1, "PerfMon", 24, 27); + arm64_sysreg_add_field(ID_DFR0_EL1, "MProfDbg", 20, 23); + arm64_sysreg_add_field(ID_DFR0_EL1, "MMapTrc", 16, 19); + arm64_sysreg_add_field(ID_DFR0_EL1, "CopTrc", 12, 15); + arm64_sysreg_add_field(ID_DFR0_EL1, "MMapDbg", 8, 11); + arm64_sysreg_add_field(ID_DFR0_EL1, "CopSDbg", 4, 7); + arm64_sysreg_add_field(ID_DFR0_EL1, "CopDbg", 0, 3); + + /* ID_AFR0_EL1 */ + ARM64SysReg *ID_AFR0_EL1 = arm64_sysreg_get(ID_AFR0_EL1_IDX); + ID_AFR0_EL1->name = "ID_AFR0_EL1"; + arm64_sysreg_add_field(ID_AFR0_EL1, "IMPDEF3", 12, 15); + arm64_sysreg_add_field(ID_AFR0_EL1, "IMPDEF2", 8, 11); + arm64_sysreg_add_field(ID_AFR0_EL1, "IMPDEF1", 4, 7); + arm64_sysreg_add_field(ID_AFR0_EL1, "IMPDEF0", 0, 3); + + /* ID_MMFR0_EL1 */ + ARM64SysReg *ID_MMFR0_EL1 = arm64_sysreg_get(ID_MMFR0_EL1_IDX); + ID_MMFR0_EL1->name = "ID_MMFR0_EL1"; + arm64_sysreg_add_field(ID_MMFR0_EL1, "InnerShr", 28, 31); + arm64_sysreg_add_field(ID_MMFR0_EL1, "FCSE", 24, 27); + arm64_sysreg_add_field(ID_MMFR0_EL1, "AuxReg", 20, 23); + arm64_sysreg_add_field(ID_MMFR0_EL1, "TCM", 16, 19); + arm64_sysreg_add_field(ID_MMFR0_EL1, "ShareLvl", 12, 15); + arm64_sysreg_add_field(ID_MMFR0_EL1, "OuterShr", 8, 11); + arm64_sysreg_add_field(ID_MMFR0_EL1, "PMSA", 4, 7); + arm64_sysreg_add_field(ID_MMFR0_EL1, "VMSA", 0, 3); + + /* ID_MMFR1_EL1 */ + ARM64SysReg *ID_MMFR1_EL1 = arm64_sysreg_get(ID_MMFR1_EL1_IDX); + ID_MMFR1_EL1->name = "ID_MMFR1_EL1"; + arm64_sysreg_add_field(ID_MMFR1_EL1, "BPred", 28, 31); + arm64_sysreg_add_field(ID_MMFR1_EL1, "L1TstCln", 24, 27); + arm64_sysreg_add_field(ID_MMFR1_EL1, "L1Uni", 20, 23); + arm64_sysreg_add_field(ID_MMFR1_EL1, "L1Hvd", 16, 19); + arm64_sysreg_add_field(ID_MMFR1_EL1, "L1UniSW", 12, 15); + arm64_sysreg_add_field(ID_MMFR1_EL1, "L1HvdSW", 8, 11); + arm64_sysreg_add_field(ID_MMFR1_EL1, "L1UniVA", 4, 7); + arm64_sysreg_add_field(ID_MMFR1_EL1, "L1HvdVA", 0, 3); + + /* ID_MMFR2_EL1 */ + ARM64SysReg *ID_MMFR2_EL1 = arm64_sysreg_get(ID_MMFR2_EL1_IDX); + ID_MMFR2_EL1->name = "ID_MMFR2_EL1"; + arm64_sysreg_add_field(ID_MMFR2_EL1, "HWAccFlg", 28, 31); + arm64_sysreg_add_field(ID_MMFR2_EL1, "WFIStall", 24, 27); + arm64_sysreg_add_field(ID_MMFR2_EL1, "MemBarr", 20, 23); + arm64_sysreg_add_field(ID_MMFR2_EL1, "UniTLB", 16, 19); + arm64_sysreg_add_field(ID_MMFR2_EL1, "HvdTLB", 12, 15); + arm64_sysreg_add_field(ID_MMFR2_EL1, "L1HvdRng", 8, 11); + arm64_sysreg_add_field(ID_MMFR2_EL1, "L1HvdBG", 4, 7); + arm64_sysreg_add_field(ID_MMFR2_EL1, "L1HvdFG", 0, 3); + + /* ID_MMFR3_EL1 */ + ARM64SysReg *ID_MMFR3_EL1 = arm64_sysreg_get(ID_MMFR3_EL1_IDX); + ID_MMFR3_EL1->name = "ID_MMFR3_EL1"; + arm64_sysreg_add_field(ID_MMFR3_EL1, "Supersec", 28, 31); + arm64_sysreg_add_field(ID_MMFR3_EL1, "CMemSz", 24, 27); + arm64_sysreg_add_field(ID_MMFR3_EL1, "CohWalk", 20, 23); + arm64_sysreg_add_field(ID_MMFR3_EL1, "PAN", 16, 19); + arm64_sysreg_add_field(ID_MMFR3_EL1, "MaintBcst", 12, 15); + arm64_sysreg_add_field(ID_MMFR3_EL1, "BPMaint", 8, 11); + arm64_sysreg_add_field(ID_MMFR3_EL1, "CMaintSW", 4, 7); + arm64_sysreg_add_field(ID_MMFR3_EL1, "CMaintVA", 0, 3); + + /* ID_ISAR0_EL1 */ + ARM64SysReg *ID_ISAR0_EL1 = arm64_sysreg_get(ID_ISAR0_EL1_IDX); + ID_ISAR0_EL1->name = "ID_ISAR0_EL1"; + arm64_sysreg_add_field(ID_ISAR0_EL1, "Divide", 24, 27); + arm64_sysreg_add_field(ID_ISAR0_EL1, "Debug", 20, 23); + arm64_sysreg_add_field(ID_ISAR0_EL1, "Coproc", 16, 19); + arm64_sysreg_add_field(ID_ISAR0_EL1, "CmpBranch", 12, 15); + arm64_sysreg_add_field(ID_ISAR0_EL1, "BitField", 8, 11); + arm64_sysreg_add_field(ID_ISAR0_EL1, "BitCount", 4, 7); + arm64_sysreg_add_field(ID_ISAR0_EL1, "Swap", 0, 3); + + /* ID_ISAR1_EL1 */ + ARM64SysReg *ID_ISAR1_EL1 = arm64_sysreg_get(ID_ISAR1_EL1_IDX); + ID_ISAR1_EL1->name = "ID_ISAR1_EL1"; + arm64_sysreg_add_field(ID_ISAR1_EL1, "Jazelle", 28, 31); + arm64_sysreg_add_field(ID_ISAR1_EL1, "Interwork", 24, 27); + arm64_sysreg_add_field(ID_ISAR1_EL1, "Immediate", 20, 23); + arm64_sysreg_add_field(ID_ISAR1_EL1, "IfThen", 16, 19); + arm64_sysreg_add_field(ID_ISAR1_EL1, "Extend", 12, 15); + arm64_sysreg_add_field(ID_ISAR1_EL1, "Except_AR", 8, 11); + arm64_sysreg_add_field(ID_ISAR1_EL1, "Except", 4, 7); + arm64_sysreg_add_field(ID_ISAR1_EL1, "Endian", 0, 3); + + /* ID_ISAR2_EL1 */ + ARM64SysReg *ID_ISAR2_EL1 = arm64_sysreg_get(ID_ISAR2_EL1_IDX); + ID_ISAR2_EL1->name = "ID_ISAR2_EL1"; + arm64_sysreg_add_field(ID_ISAR2_EL1, "Reversal", 28, 31); + arm64_sysreg_add_field(ID_ISAR2_EL1, "PSR_AR", 24, 27); + arm64_sysreg_add_field(ID_ISAR2_EL1, "MultU", 20, 23); + arm64_sysreg_add_field(ID_ISAR2_EL1, "MultS", 16, 19); + arm64_sysreg_add_field(ID_ISAR2_EL1, "Mult", 12, 15); + arm64_sysreg_add_field(ID_ISAR2_EL1, "MultiAccessInt", 8, 11); + arm64_sysreg_add_field(ID_ISAR2_EL1, "MemHint", 4, 7); + arm64_sysreg_add_field(ID_ISAR2_EL1, "LoadStore", 0, 3); + + /* ID_ISAR3_EL1 */ + ARM64SysReg *ID_ISAR3_EL1 = arm64_sysreg_get(ID_ISAR3_EL1_IDX); + ID_ISAR3_EL1->name = "ID_ISAR3_EL1"; + arm64_sysreg_add_field(ID_ISAR3_EL1, "T32EE", 28, 31); + arm64_sysreg_add_field(ID_ISAR3_EL1, "TrueNOP", 24, 27); + arm64_sysreg_add_field(ID_ISAR3_EL1, "T32Copy", 20, 23); + arm64_sysreg_add_field(ID_ISAR3_EL1, "TabBranch", 16, 19); + arm64_sysreg_add_field(ID_ISAR3_EL1, "SynchPrim", 12, 15); + arm64_sysreg_add_field(ID_ISAR3_EL1, "SVC", 8, 11); + arm64_sysreg_add_field(ID_ISAR3_EL1, "SIMD", 4, 7); + arm64_sysreg_add_field(ID_ISAR3_EL1, "Saturate", 0, 3); + + /* ID_ISAR4_EL1 */ + ARM64SysReg *ID_ISAR4_EL1 = arm64_sysreg_get(ID_ISAR4_EL1_IDX); + ID_ISAR4_EL1->name = "ID_ISAR4_EL1"; + arm64_sysreg_add_field(ID_ISAR4_EL1, "SWP_frac", 28, 31); + arm64_sysreg_add_field(ID_ISAR4_EL1, "PSR_M", 24, 27); + arm64_sysreg_add_field(ID_ISAR4_EL1, "SynchPrim_frac", 20, 23); + arm64_sysreg_add_field(ID_ISAR4_EL1, "Barrier", 16, 19); + arm64_sysreg_add_field(ID_ISAR4_EL1, "SMC", 12, 15); + arm64_sysreg_add_field(ID_ISAR4_EL1, "Writeback", 8, 11); + arm64_sysreg_add_field(ID_ISAR4_EL1, "WithShifts", 4, 7); + arm64_sysreg_add_field(ID_ISAR4_EL1, "Unpriv", 0, 3); + + /* ID_ISAR5_EL1 */ + ARM64SysReg *ID_ISAR5_EL1 = arm64_sysreg_get(ID_ISAR5_EL1_IDX); + ID_ISAR5_EL1->name = "ID_ISAR5_EL1"; + arm64_sysreg_add_field(ID_ISAR5_EL1, "VCMA", 28, 31); + arm64_sysreg_add_field(ID_ISAR5_EL1, "RDM", 24, 27); + arm64_sysreg_add_field(ID_ISAR5_EL1, "CRC32", 16, 19); + arm64_sysreg_add_field(ID_ISAR5_EL1, "SHA2", 12, 15); + arm64_sysreg_add_field(ID_ISAR5_EL1, "SHA1", 8, 11); + arm64_sysreg_add_field(ID_ISAR5_EL1, "AES", 4, 7); + arm64_sysreg_add_field(ID_ISAR5_EL1, "SEVL", 0, 3); + + /* ID_ISAR6_EL1 */ + ARM64SysReg *ID_ISAR6_EL1 = arm64_sysreg_get(ID_ISAR6_EL1_IDX); + ID_ISAR6_EL1->name = "ID_ISAR6_EL1"; + arm64_sysreg_add_field(ID_ISAR6_EL1, "I8MM", 24, 27); + arm64_sysreg_add_field(ID_ISAR6_EL1, "BF16", 20, 23); + arm64_sysreg_add_field(ID_ISAR6_EL1, "SPECRES", 16, 19); + arm64_sysreg_add_field(ID_ISAR6_EL1, "SB", 12, 15); + arm64_sysreg_add_field(ID_ISAR6_EL1, "FHM", 8, 11); + arm64_sysreg_add_field(ID_ISAR6_EL1, "DP", 4, 7); + arm64_sysreg_add_field(ID_ISAR6_EL1, "JSCVT", 0, 3); + + /* ID_MMFR4_EL1 */ + ARM64SysReg *ID_MMFR4_EL1 = arm64_sysreg_get(ID_MMFR4_EL1_IDX); + ID_MMFR4_EL1->name = "ID_MMFR4_EL1"; + arm64_sysreg_add_field(ID_MMFR4_EL1, "EVT", 28, 31); + arm64_sysreg_add_field(ID_MMFR4_EL1, "CCIDX", 24, 27); + arm64_sysreg_add_field(ID_MMFR4_EL1, "LSM", 20, 23); + arm64_sysreg_add_field(ID_MMFR4_EL1, "HPDS", 16, 19); + arm64_sysreg_add_field(ID_MMFR4_EL1, "CnP", 12, 15); + arm64_sysreg_add_field(ID_MMFR4_EL1, "XNX", 8, 11); + arm64_sysreg_add_field(ID_MMFR4_EL1, "AC2", 4, 7); + arm64_sysreg_add_field(ID_MMFR4_EL1, "SpecSEI", 0, 3); + + /* MVFR0_EL1 */ + ARM64SysReg *MVFR0_EL1 = arm64_sysreg_get(MVFR0_EL1_IDX); + MVFR0_EL1->name = "MVFR0_EL1"; + arm64_sysreg_add_field(MVFR0_EL1, "FPRound", 28, 31); + arm64_sysreg_add_field(MVFR0_EL1, "FPShVec", 24, 27); + arm64_sysreg_add_field(MVFR0_EL1, "FPSqrt", 20, 23); + arm64_sysreg_add_field(MVFR0_EL1, "FPDivide", 16, 19); + arm64_sysreg_add_field(MVFR0_EL1, "FPTrap", 12, 15); + arm64_sysreg_add_field(MVFR0_EL1, "FPDP", 8, 11); + arm64_sysreg_add_field(MVFR0_EL1, "FPSP", 4, 7); + arm64_sysreg_add_field(MVFR0_EL1, "SIMDReg", 0, 3); + + /* MVFR1_EL1 */ + ARM64SysReg *MVFR1_EL1 = arm64_sysreg_get(MVFR1_EL1_IDX); + MVFR1_EL1->name = "MVFR1_EL1"; + arm64_sysreg_add_field(MVFR1_EL1, "SIMDFMAC", 28, 31); + arm64_sysreg_add_field(MVFR1_EL1, "FPHP", 24, 27); + arm64_sysreg_add_field(MVFR1_EL1, "SIMDHP", 20, 23); + arm64_sysreg_add_field(MVFR1_EL1, "SIMDSP", 16, 19); + arm64_sysreg_add_field(MVFR1_EL1, "SIMDInt", 12, 15); + arm64_sysreg_add_field(MVFR1_EL1, "SIMDLS", 8, 11); + arm64_sysreg_add_field(MVFR1_EL1, "FPDNaN", 4, 7); + arm64_sysreg_add_field(MVFR1_EL1, "FPFtZ", 0, 3); + + /* MVFR2_EL1 */ + ARM64SysReg *MVFR2_EL1 = arm64_sysreg_get(MVFR2_EL1_IDX); + MVFR2_EL1->name = "MVFR2_EL1"; + arm64_sysreg_add_field(MVFR2_EL1, "FPMisc", 4, 7); + arm64_sysreg_add_field(MVFR2_EL1, "SIMDMisc", 0, 3); + + /* ID_PFR2_EL1 */ + ARM64SysReg *ID_PFR2_EL1 = arm64_sysreg_get(ID_PFR2_EL1_IDX); + ID_PFR2_EL1->name = "ID_PFR2_EL1"; + arm64_sysreg_add_field(ID_PFR2_EL1, "RAS_frac", 8, 11); + arm64_sysreg_add_field(ID_PFR2_EL1, "SSBS", 4, 7); + arm64_sysreg_add_field(ID_PFR2_EL1, "CSV3", 0, 3); + + /* ID_DFR1_EL1 */ + ARM64SysReg *ID_DFR1_EL1 = arm64_sysreg_get(ID_DFR1_EL1_IDX); + ID_DFR1_EL1->name = "ID_DFR1_EL1"; + arm64_sysreg_add_field(ID_DFR1_EL1, "HPMN0", 4, 7); + arm64_sysreg_add_field(ID_DFR1_EL1, "MTPMU", 0, 3); + + /* ID_MMFR5_EL1 */ + ARM64SysReg *ID_MMFR5_EL1 = arm64_sysreg_get(ID_MMFR5_EL1_IDX); + ID_MMFR5_EL1->name = "ID_MMFR5_EL1"; + arm64_sysreg_add_field(ID_MMFR5_EL1, "nTLBPA", 4, 7); + arm64_sysreg_add_field(ID_MMFR5_EL1, "ETS", 0, 3); + + /* ID_AA64PFR0_EL1 */ + ARM64SysReg *ID_AA64PFR0_EL1 = arm64_sysreg_get(ID_AA64PFR0_EL1_IDX); + ID_AA64PFR0_EL1->name = "ID_AA64PFR0_EL1"; + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "CSV3", 60, 63); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "CSV2", 56, 59); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "RME", 52, 55); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "DIT", 48, 51); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "AMU", 44, 47); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "MPAM", 40, 43); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "SEL2", 36, 39); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "SVE", 32, 35); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "RAS", 28, 31); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "GIC", 24, 27); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "AdvSIMD", 20, 23); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "AdvSIMD", 20, 23); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "FP", 16, 19); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "FP", 16, 19); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "EL3", 12, 15); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "EL2", 8, 11); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "EL1", 4, 7); + arm64_sysreg_add_field(ID_AA64PFR0_EL1, "EL0", 0, 3); + + /* ID_AA64PFR1_EL1 */ + ARM64SysReg *ID_AA64PFR1_EL1 = arm64_sysreg_get(ID_AA64PFR1_EL1_IDX); + ID_AA64PFR1_EL1->name = "ID_AA64PFR1_EL1"; + arm64_sysreg_add_field(ID_AA64PFR1_EL1, "PFAR", 60, 63); + arm64_sysreg_add_field(ID_AA64PFR1_EL1, "DF2", 56, 59); + arm64_sysreg_add_field(ID_AA64PFR1_EL1, "MTEX", 52, 55); + arm64_sysreg_add_field(ID_AA64PFR1_EL1, "THE", 48, 51); + arm64_sysreg_add_field(ID_AA64PFR1_EL1, "GCS", 44, 47); + arm64_sysreg_add_field(ID_AA64PFR1_EL1, "MTE_frac", 40, 43); + arm64_sysreg_add_field(ID_AA64PFR1_EL1, "NMI", 36, 39); + arm64_sysreg_add_field(ID_AA64PFR1_EL1, "CSV2_frac", 32, 35); + arm64_sysreg_add_field(ID_AA64PFR1_EL1, "RNDR_trap", 28, 31); + arm64_sysreg_add_field(ID_AA64PFR1_EL1, "SME", 24, 27); + arm64_sysreg_add_field(ID_AA64PFR1_EL1, "MPAM_frac", 16, 19); + arm64_sysreg_add_field(ID_AA64PFR1_EL1, "RAS_frac", 12, 15); + arm64_sysreg_add_field(ID_AA64PFR1_EL1, "MTE", 8, 11); + arm64_sysreg_add_field(ID_AA64PFR1_EL1, "SSBS", 4, 7); + arm64_sysreg_add_field(ID_AA64PFR1_EL1, "BT", 0, 3); + + /* ID_AA64PFR2_EL1 */ + ARM64SysReg *ID_AA64PFR2_EL1 = arm64_sysreg_get(ID_AA64PFR2_EL1_IDX); + ID_AA64PFR2_EL1->name = "ID_AA64PFR2_EL1"; + arm64_sysreg_add_field(ID_AA64PFR2_EL1, "FPMR", 32, 35); + arm64_sysreg_add_field(ID_AA64PFR2_EL1, "UINJ", 16, 19); + arm64_sysreg_add_field(ID_AA64PFR2_EL1, "MTEFAR", 8, 11); + arm64_sysreg_add_field(ID_AA64PFR2_EL1, "MTESTOREONLY", 4, 7); + arm64_sysreg_add_field(ID_AA64PFR2_EL1, "MTEPERM", 0, 3); + + /* ID_AA64ZFR0_EL1 */ + ARM64SysReg *ID_AA64ZFR0_EL1 = arm64_sysreg_get(ID_AA64ZFR0_EL1_IDX); + ID_AA64ZFR0_EL1->name = "ID_AA64ZFR0_EL1"; + arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "F64MM", 56, 59); + arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "F32MM", 52, 55); + arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "F16MM", 48, 51); + arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "I8MM", 44, 47); + arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "SM4", 40, 43); + arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "SHA3", 32, 35); + arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "B16B16", 24, 27); + arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "BF16", 20, 23); + arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "BitPerm", 16, 19); + arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "EltPerm", 12, 15); + arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "AES", 4, 7); + arm64_sysreg_add_field(ID_AA64ZFR0_EL1, "SVEver", 0, 3); + + /* ID_AA64SMFR0_EL1 */ + ARM64SysReg *ID_AA64SMFR0_EL1 = arm64_sysreg_get(ID_AA64SMFR0_EL1_IDX); + ID_AA64SMFR0_EL1->name = "ID_AA64SMFR0_EL1"; + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "FA64", 63, 63); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "LUTv2", 60, 60); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SMEver", 56, 59); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "I16I64", 52, 55); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F64F64", 48, 48); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "I16I32", 44, 47); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "B16B16", 43, 43); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F16F16", 42, 42); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F8F16", 41, 41); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F8F32", 40, 40); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "I8I32", 36, 39); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F16F32", 35, 35); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "B16F32", 34, 34); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "BI32I32", 33, 33); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "F32F32", 32, 32); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SF8FMA", 30, 30); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SF8DP4", 29, 29); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SF8DP2", 28, 28); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SBitPerm", 25, 25); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "AES", 24, 24); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SFEXPA", 23, 23); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "STMOP", 16, 16); + arm64_sysreg_add_field(ID_AA64SMFR0_EL1, "SMOP4", 0, 0); + + /* ID_AA64FPFR0_EL1 */ + ARM64SysReg *ID_AA64FPFR0_EL1 = arm64_sysreg_get(ID_AA64FPFR0_EL1_IDX); + ID_AA64FPFR0_EL1->name = "ID_AA64FPFR0_EL1"; + arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8CVT", 31, 31); + arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8FMA", 30, 30); + arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8DP4", 29, 29); + arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8DP2", 28, 28); + arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8MM8", 27, 27); + arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8MM4", 26, 26); + arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8E4M3", 1, 1); + arm64_sysreg_add_field(ID_AA64FPFR0_EL1, "F8E5M2", 0, 0); + + /* ID_AA64DFR0_EL1 */ + ARM64SysReg *ID_AA64DFR0_EL1 = arm64_sysreg_get(ID_AA64DFR0_EL1_IDX); + ID_AA64DFR0_EL1->name = "ID_AA64DFR0_EL1"; + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "HPMN0", 60, 63); + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "ExtTrcBuff", 56, 59); + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "BRBE", 52, 55); + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "MTPMU", 48, 51); + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "MTPMU", 48, 51); + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "TraceBuffer", 44, 47); + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "TraceFilt", 40, 43); + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "DoubleLock", 36, 39); + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "PMSVer", 32, 35); + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "CTX_CMPs", 28, 31); + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "SEBEP", 24, 27); + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "WRPs", 20, 23); + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "PMSS", 16, 19); + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "BRPs", 12, 15); + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "PMUVer", 8, 11); + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "TraceVer", 4, 7); + arm64_sysreg_add_field(ID_AA64DFR0_EL1, "DebugVer", 0, 3); + + /* ID_AA64DFR1_EL1 */ + ARM64SysReg *ID_AA64DFR1_EL1 = arm64_sysreg_get(ID_AA64DFR1_EL1_IDX); + ID_AA64DFR1_EL1->name = "ID_AA64DFR1_EL1"; + arm64_sysreg_add_field(ID_AA64DFR1_EL1, "ABL_CMPs", 56, 63); + arm64_sysreg_add_field(ID_AA64DFR1_EL1, "DPFZS", 52, 55); + arm64_sysreg_add_field(ID_AA64DFR1_EL1, "EBEP", 48, 51); + arm64_sysreg_add_field(ID_AA64DFR1_EL1, "ITE", 44, 47); + arm64_sysreg_add_field(ID_AA64DFR1_EL1, "ABLE", 40, 43); + arm64_sysreg_add_field(ID_AA64DFR1_EL1, "PMICNTR", 36, 39); + arm64_sysreg_add_field(ID_AA64DFR1_EL1, "SPMU", 32, 35); + arm64_sysreg_add_field(ID_AA64DFR1_EL1, "CTX_CMPs", 24, 31); + arm64_sysreg_add_field(ID_AA64DFR1_EL1, "WRPs", 16, 23); + arm64_sysreg_add_field(ID_AA64DFR1_EL1, "BRPs", 8, 15); + arm64_sysreg_add_field(ID_AA64DFR1_EL1, "SYSPMUID", 0, 7); + + /* ID_AA64DFR2_EL1 */ + ARM64SysReg *ID_AA64DFR2_EL1 = arm64_sysreg_get(ID_AA64DFR2_EL1_IDX); + ID_AA64DFR2_EL1->name = "ID_AA64DFR2_EL1"; + arm64_sysreg_add_field(ID_AA64DFR2_EL1, "TRBE_EXC", 24, 27); + arm64_sysreg_add_field(ID_AA64DFR2_EL1, "SPE_nVM", 20, 23); + arm64_sysreg_add_field(ID_AA64DFR2_EL1, "SPE_EXC", 16, 19); + arm64_sysreg_add_field(ID_AA64DFR2_EL1, "BWE", 4, 7); + arm64_sysreg_add_field(ID_AA64DFR2_EL1, "STEP", 0, 3); + + /* ID_AA64AFR0_EL1 */ + ARM64SysReg *ID_AA64AFR0_EL1 = arm64_sysreg_get(ID_AA64AFR0_EL1_IDX); + ID_AA64AFR0_EL1->name = "ID_AA64AFR0_EL1"; + arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF7", 28, 31); + arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF6", 24, 27); + arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF5", 20, 23); + arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF4", 16, 19); + arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF3", 12, 15); + arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF2", 8, 11); + arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF1", 4, 7); + arm64_sysreg_add_field(ID_AA64AFR0_EL1, "IMPDEF0", 0, 3); + + /* ID_AA64AFR1_EL1 */ + ARM64SysReg *ID_AA64AFR1_EL1 = arm64_sysreg_get(ID_AA64AFR1_EL1_IDX); + ID_AA64AFR1_EL1->name = "ID_AA64AFR1_EL1"; + + /* ID_AA64ISAR0_EL1 */ + ARM64SysReg *ID_AA64ISAR0_EL1 = arm64_sysreg_get(ID_AA64ISAR0_EL1_IDX); + ID_AA64ISAR0_EL1->name = "ID_AA64ISAR0_EL1"; + arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "RNDR", 60, 63); + arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "TLB", 56, 59); + arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "TS", 52, 55); + arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "FHM", 48, 51); + arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "DP", 44, 47); + arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "SM4", 40, 43); + arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "SM3", 36, 39); + arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "SHA3", 32, 35); + arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "RDM", 28, 31); + arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "TME", 24, 27); + arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "ATOMIC", 20, 23); + arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "CRC32", 16, 19); + arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "SHA2", 12, 15); + arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "SHA1", 8, 11); + arm64_sysreg_add_field(ID_AA64ISAR0_EL1, "AES", 4, 7); + + /* ID_AA64ISAR1_EL1 */ + ARM64SysReg *ID_AA64ISAR1_EL1 = arm64_sysreg_get(ID_AA64ISAR1_EL1_IDX); + ID_AA64ISAR1_EL1->name = "ID_AA64ISAR1_EL1"; + arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "LS64", 60, 63); + arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "XS", 56, 59); + arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "I8MM", 52, 55); + arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "DGH", 48, 51); + arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "BF16", 44, 47); + arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "SPECRES", 40, 43); + arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "SB", 36, 39); + arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "FRINTTS", 32, 35); + arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "GPI", 28, 31); + arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "GPA", 24, 27); + arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "LRCPC", 20, 23); + arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "FCMA", 16, 19); + arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "JSCVT", 12, 15); + arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "API", 8, 11); + arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "APA", 4, 7); + arm64_sysreg_add_field(ID_AA64ISAR1_EL1, "DPB", 0, 3); + + /* ID_AA64ISAR2_EL1 */ + ARM64SysReg *ID_AA64ISAR2_EL1 = arm64_sysreg_get(ID_AA64ISAR2_EL1_IDX); + ID_AA64ISAR2_EL1->name = "ID_AA64ISAR2_EL1"; + arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "ATS1A", 60, 63); + arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "LUT", 56, 59); + arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "CSSC", 52, 55); + arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "RPRFM", 48, 51); + arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "PCDPHINT", 44, 47); + arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "PRFMSLC", 40, 43); + arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "SYSINSTR_128", 36, 39); + arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "SYSREG_128", 32, 35); + arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "CLRBHB", 28, 31); + arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "PAC_frac", 24, 27); + arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "BC", 20, 23); + arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "MOPS", 16, 19); + arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "APA3", 12, 15); + arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "GPA3", 8, 11); + arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "RPRES", 4, 7); + arm64_sysreg_add_field(ID_AA64ISAR2_EL1, "WFxT", 0, 3); + + /* ID_AA64ISAR3_EL1 */ + ARM64SysReg *ID_AA64ISAR3_EL1 = arm64_sysreg_get(ID_AA64ISAR3_EL1_IDX); + ID_AA64ISAR3_EL1->name = "ID_AA64ISAR3_EL1"; + arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "FPRCVT", 28, 31); + arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "LSUI", 24, 27); + arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "OCCMO", 20, 23); + arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "LSFE", 16, 19); + arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "PACM", 12, 15); + arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "TLBIW", 8, 11); + arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "FAMINMAX", 4, 7); + arm64_sysreg_add_field(ID_AA64ISAR3_EL1, "CPA", 0, 3); + + /* ID_AA64MMFR0_EL1 */ + ARM64SysReg *ID_AA64MMFR0_EL1 = arm64_sysreg_get(ID_AA64MMFR0_EL1_IDX); + ID_AA64MMFR0_EL1->name = "ID_AA64MMFR0_EL1"; + arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "ECV", 60, 63); + arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "FGT", 56, 59); + arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "EXS", 44, 47); + arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN4_2", 40, 43); + arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN64_2", 36, 39); + arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN16_2", 32, 35); + arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN4", 28, 31); + arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN4", 28, 31); + arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN64", 24, 27); + arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN64", 24, 27); + arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "TGRAN16", 20, 23); + arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "BIGENDEL0", 16, 19); + arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "SNSMEM", 12, 15); + arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "BIGEND", 8, 11); + arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "ASIDBITS", 4, 7); + arm64_sysreg_add_field(ID_AA64MMFR0_EL1, "PARANGE", 0, 3); + + /* ID_AA64MMFR1_EL1 */ + ARM64SysReg *ID_AA64MMFR1_EL1 = arm64_sysreg_get(ID_AA64MMFR1_EL1_IDX); + ID_AA64MMFR1_EL1->name = "ID_AA64MMFR1_EL1"; + arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "ECBHB", 60, 63); + arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "CMOW", 56, 59); + arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "TIDCP1", 52, 55); + arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "nTLBPA", 48, 51); + arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "AFP", 44, 47); + arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "HCX", 40, 43); + arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "ETS", 36, 39); + arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "TWED", 32, 35); + arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "XNX", 28, 31); + arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "SpecSEI", 24, 27); + arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "PAN", 20, 23); + arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "LO", 16, 19); + arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "HPDS", 12, 15); + arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "VH", 8, 11); + arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "VMIDBits", 4, 7); + arm64_sysreg_add_field(ID_AA64MMFR1_EL1, "HAFDBS", 0, 3); + + /* ID_AA64MMFR2_EL1 */ + ARM64SysReg *ID_AA64MMFR2_EL1 = arm64_sysreg_get(ID_AA64MMFR2_EL1_IDX); + ID_AA64MMFR2_EL1->name = "ID_AA64MMFR2_EL1"; + arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "E0PD", 60, 63); + arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "EVT", 56, 59); + arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "BBM", 52, 55); + arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "TTL", 48, 51); + arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "FWB", 40, 43); + arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "IDS", 36, 39); + arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "AT", 32, 35); + arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "ST", 28, 31); + arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "NV", 24, 27); + arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "CCIDX", 20, 23); + arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "VARange", 16, 19); + arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "IESB", 12, 15); + arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "LSM", 8, 11); + arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "UAO", 4, 7); + arm64_sysreg_add_field(ID_AA64MMFR2_EL1, "CnP", 0, 3); + + /* ID_AA64MMFR3_EL1 */ + ARM64SysReg *ID_AA64MMFR3_EL1 = arm64_sysreg_get(ID_AA64MMFR3_EL1_IDX); + ID_AA64MMFR3_EL1->name = "ID_AA64MMFR3_EL1"; + arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "Spec_FPACC", 60, 63); + arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "ADERR", 56, 59); + arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "SDERR", 52, 55); + arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "ANERR", 44, 47); + arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "SNERR", 40, 43); + arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "D128_2", 36, 39); + arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "D128", 32, 35); + arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "MEC", 28, 31); + arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "AIE", 24, 27); + arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "S2POE", 20, 23); + arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "S1POE", 16, 19); + arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "S2PIE", 12, 15); + arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "S1PIE", 8, 11); + arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "SCTLRX", 4, 7); + arm64_sysreg_add_field(ID_AA64MMFR3_EL1, "TCRX", 0, 3); + + /* ID_AA64MMFR4_EL1 */ + ARM64SysReg *ID_AA64MMFR4_EL1 = arm64_sysreg_get(ID_AA64MMFR4_EL1_IDX); + ID_AA64MMFR4_EL1->name = "ID_AA64MMFR4_EL1"; + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "SRMASK", 44, 47); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "E3DSE", 36, 39); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "RMEGDI", 28, 31); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "E2H0", 24, 27); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "E2H0", 24, 27); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "NV_frac", 20, 23); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "FGWTE3", 16, 19); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "HACDBS", 12, 15); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "ASID2", 8, 11); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "EIESB", 4, 7); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "EIESB", 4, 7); + arm64_sysreg_add_field(ID_AA64MMFR4_EL1, "PoPS", 0, 3); + +/* For SCTLR_EL12 fields see SCTLR_EL1 */ + +/* For SCTLRALIAS_EL1 fields see SCTLR_EL1 */ + +/* For ACTLR_EL12 fields see ACTLR_EL1 */ + +/* For ACTLRALIAS_EL1 fields see ACTLR_EL1 */ + +/* For CPACR_EL12 fields see CPACR_EL1 */ + +/* For CPACRALIAS_EL1 fields see CPACR_EL1 */ + +/* For ACTLRMASK_EL12 fields see ACTLRMASK_EL1 */ + +/* For CPACRMASK_EL12 fields see CPACRMASK_EL1 */ + +/* For PFAR_EL12 fields see PFAR_EL1 */ + +/* For SCTLR2_EL12 fields see SCTLR2_EL1 */ + +/* For SCTLR2ALIAS_EL1 fields see SCTLR2_EL1 */ + +/* For SCTLR2MASK_EL12 fields see SCTLR2MASK_EL1 */ + +/* For SCTLRMASK_EL12 fields see SCTLRMASK_EL1 */ + +/* For TCR2MASK_EL12 fields see TCR2MASK_EL1 */ + +/* For TCRMASK_EL12 fields see TCRMASK_EL1 */ + +/* For TRCITECR_EL12 fields see TRCITECR_EL1 */ + +/* For ZCR_EL1 fields see ZCR_ELx */ + +/* For SMCR_EL1 fields see SMCR_ELx */ + +/* For GCSCR_EL1 fields see GCSCR_ELx */ + +/* For GCSPR_EL1 fields see GCSPR_ELx */ + +/* For CONTEXTIDR_EL1 fields see CONTEXTIDR_ELx */ + + /* CCSIDR_EL1 */ + ARM64SysReg *CCSIDR_EL1 = arm64_sysreg_get(CCSIDR_EL1_IDX); + CCSIDR_EL1->name = "CCSIDR_EL1"; + arm64_sysreg_add_field(CCSIDR_EL1, "NumSets", 13, 27); + arm64_sysreg_add_field(CCSIDR_EL1, "Associativity", 3, 12); + arm64_sysreg_add_field(CCSIDR_EL1, "LineSize", 0, 2); + + /* CLIDR_EL1 */ + ARM64SysReg *CLIDR_EL1 = arm64_sysreg_get(CLIDR_EL1_IDX); + CLIDR_EL1->name = "CLIDR_EL1"; + arm64_sysreg_add_field(CLIDR_EL1, "Ttypen", 33, 46); + arm64_sysreg_add_field(CLIDR_EL1, "ICB", 30, 32); + arm64_sysreg_add_field(CLIDR_EL1, "LoUU", 27, 29); + arm64_sysreg_add_field(CLIDR_EL1, "LoC", 24, 26); + arm64_sysreg_add_field(CLIDR_EL1, "LoUIS", 21, 23); + arm64_sysreg_add_field(CLIDR_EL1, "Ctype7", 18, 20); + arm64_sysreg_add_field(CLIDR_EL1, "Ctype6", 15, 17); + arm64_sysreg_add_field(CLIDR_EL1, "Ctype5", 12, 14); + arm64_sysreg_add_field(CLIDR_EL1, "Ctype4", 9, 11); + arm64_sysreg_add_field(CLIDR_EL1, "Ctype3", 6, 8); + arm64_sysreg_add_field(CLIDR_EL1, "Ctype2", 3, 5); + arm64_sysreg_add_field(CLIDR_EL1, "Ctype1", 0, 2); + + /* CCSIDR2_EL1 */ + ARM64SysReg *CCSIDR2_EL1 = arm64_sysreg_get(CCSIDR2_EL1_IDX); + CCSIDR2_EL1->name = "CCSIDR2_EL1"; + arm64_sysreg_add_field(CCSIDR2_EL1, "NumSets", 0, 23); + + /* GMID_EL1 */ + ARM64SysReg *GMID_EL1 = arm64_sysreg_get(GMID_EL1_IDX); + GMID_EL1->name = "GMID_EL1"; + arm64_sysreg_add_field(GMID_EL1, "BS", 0, 3); + + /* SMIDR_EL1 */ + ARM64SysReg *SMIDR_EL1 = arm64_sysreg_get(SMIDR_EL1_IDX); + SMIDR_EL1->name = "SMIDR_EL1"; + arm64_sysreg_add_field(SMIDR_EL1, "IMPLEMENTER", 24, 31); + arm64_sysreg_add_field(SMIDR_EL1, "REVISION", 16, 23); + arm64_sysreg_add_field(SMIDR_EL1, "SMPS", 15, 15); + arm64_sysreg_add_field(SMIDR_EL1, "AFFINITY", 0, 11); + /* CTR_EL0 */ ARM64SysReg *CTR_EL0 = arm64_sysreg_get(CTR_EL0_IDX); CTR_EL0->name = "CTR_EL0"; @@ -37,5 +667,79 @@ void initialize_cpu_sysreg_properties(void) arm64_sysreg_add_field(CTR_EL0, "DminLine", 16, 19); arm64_sysreg_add_field(CTR_EL0, "L1Ip", 14, 15); arm64_sysreg_add_field(CTR_EL0, "IminLine", 0, 3); -} + /* DCZID_EL0 */ + ARM64SysReg *DCZID_EL0 = arm64_sysreg_get(DCZID_EL0_IDX); + DCZID_EL0->name = "DCZID_EL0"; + arm64_sysreg_add_field(DCZID_EL0, "DZP", 4, 4); + arm64_sysreg_add_field(DCZID_EL0, "BS", 0, 3); + +/* For GCSPR_EL0 fields see GCSPR_ELx */ + +/* For ZCR_EL2 fields see ZCR_ELx */ + +/* For SMCR_EL2 fields see SMCR_ELx */ + +/* For GCSCR_EL2 fields see GCSCR_ELx */ + +/* For GCSPR_EL2 fields see GCSPR_ELx */ + +/* For CONTEXTIDR_EL2 fields see CONTEXTIDR_ELx */ + +/* For CPACR_EL12 fields see CPACR_EL1 */ + +/* For ZCR_EL12 fields see ZCR_EL1 */ + +/* For TRFCR_EL12 fields see TRFCR_EL1 */ + +/* For SMCR_EL12 fields see SMCR_EL1 */ + +/* For GCSCR_EL12 fields see GCSCR_EL1 */ + +/* For GCSPR_EL12 fields see GCSPR_EL1 */ + +/* For MPAM1_EL12 fields see MPAM1_ELx */ + +/* For CONTEXTIDR_EL12 fields see CONTEXTIDR_EL1 */ + +/* For TTBR0_EL1 fields see TTBRx_EL1 */ + +/* For TTBR1_EL1 fields see TTBRx_EL1 */ + +/* For TCR_EL12 fields see TCR_EL1 */ + +/* For TCRALIAS_EL1 fields see TCR_EL1 */ + +/* For TCR2_EL12 fields see TCR2_EL1 */ + +/* For TCR2ALIAS_EL1 fields see TCR2_EL1 */ + +/* For MAIR2_EL1 fields see MAIR2_ELx */ + +/* For MAIR2_EL2 fields see MAIR2_ELx */ + +/* For PIRE0_EL1 fields see PIRx_ELx */ + +/* For PIRE0_EL12 fields see PIRE0_EL1 */ + +/* For PIRE0_EL2 fields see PIRx_ELx */ + +/* For PIR_EL1 fields see PIRx_ELx */ + +/* For PIR_EL12 fields see PIR_EL1 */ + +/* For PIR_EL2 fields see PIRx_ELx */ + +/* For POR_EL0 fields see PIRx_ELx */ + +/* For POR_EL1 fields see PIRx_ELx */ + +/* For POR_EL2 fields see PIRx_ELx */ + +/* For POR_EL12 fields see POR_EL1 */ + +/* For S2POR_EL1 fields see PIRx_ELx */ + +/* For S2PIR_EL2 fields see PIRx_ELx */ + +} -- 2.33.0

From: Cornelia Huck <cohuck@redhat.com> Add an helper to retrieve the writable id reg bitmask. The status of the query is stored in the CPU struct so that an an error, if any, can be reported on vcpu realize(). Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/cpu.h | 26 ++++++++++++++++++++++++++ target/arm/kvm.c | 32 ++++++++++++++++++++++++++++++++ target/arm/kvm_arm.h | 7 +++++++ 3 files changed, 65 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 2c8f2ffd45..3f57363baf 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -846,6 +846,26 @@ typedef struct { uint32_t map, init, supported; } ARMVQMap; +typedef enum ARMIdRegsState { + WRITABLE_ID_REGS_UNKNOWN, + WRITABLE_ID_REGS_NOT_DISCOVERABLE, + WRITABLE_ID_REGS_FAILED, + WRITABLE_ID_REGS_AVAIL, +} ARMIdRegsState; + +/* + * The following structures are for the purpose of mapping the output of + * KVM_ARM_GET_REG_WRITABLE_MASKS that also may cover id registers we do + * not support in QEMU + * ID registers in op0==3, op1=={0,1,3}, crn=0, crm=={0-7}, op2=={0-7}, + * as used by the KVM_ARM_GET_REG_WRITABLE_MASKS ioctl call. + */ +#define NR_ID_REGS (3 * 8 * 8) + +typedef struct IdRegMap { + uint64_t regs[NR_ID_REGS]; +} IdRegMap; + /* REG is ID_XXX */ #define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE) \ ({ \ @@ -1035,6 +1055,12 @@ struct ArchCPU { */ bool host_cpu_probe_failed; + /* + * state of writable id regs query used to report an error, if any, + * on KVM custom vcpu model realize + */ + ARMIdRegsState writable_id_regs; + /* Specify the number of cores in this CPU cluster. Used for the L2CTLR * register. */ diff --git a/target/arm/kvm.c b/target/arm/kvm.c index b6cb525e43..04a880df1e 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -43,6 +43,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { static bool cap_has_mp_state; static bool cap_has_inject_serror_esr; static bool cap_has_inject_ext_dabt; +static int cap_writable_id_regs; static ARMHostCPUFeatures arm_host_cpu_features; @@ -194,6 +195,37 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu) env->features = arm_host_cpu_features.features; } +int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap) +{ + struct reg_mask_range range = { + .range = 0, /* up to now only a single range is supported */ + .addr = (uint64_t)idregmap, + }; + int ret; + + if (!kvm_enabled()) { + cpu->writable_id_regs = WRITABLE_ID_REGS_NOT_DISCOVERABLE; + return -ENOSYS; + } + + cap_writable_id_regs = + kvm_check_extension(kvm_state, KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES); + + if (!cap_writable_id_regs || + !(cap_writable_id_regs & (1 << KVM_ARM_FEATURE_ID_RANGE))) { + cpu->writable_id_regs = WRITABLE_ID_REGS_NOT_DISCOVERABLE; + return -ENOSYS; + } + + ret = kvm_vm_ioctl(kvm_state, KVM_ARM_GET_REG_WRITABLE_MASKS, &range); + if (ret) { + cpu->writable_id_regs = WRITABLE_ID_REGS_FAILED; + return ret; + } + cpu->writable_id_regs = WRITABLE_ID_REGS_AVAIL; + return ret; +} + static bool kvm_no_adjvtime_get(Object *obj, Error **errp) { return !ARM_CPU(obj)->kvm_adjvtime; diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 8e9b2039c4..50ae2be9c5 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -461,6 +461,8 @@ void kvm_arm_rme_init_gpa_space(hwaddr highest_gpa, PCIBus *pci_bus); */ Object *kvm_arm_rme_get_measurement_log(void); +int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap); + #else /* @@ -501,6 +503,11 @@ static inline Object *kvm_arm_rme_get_measurement_log(void) return NULL; } +static inline int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap) +{ + return -ENOSYS; +} + /* * These functions should never actually be called without KVM support. */ -- 2.33.0

From: Cornelia Huck <cohuck@redhat.com> Also add conversion between the different indices. Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/cpu.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 3f57363baf..a75f057430 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -866,6 +866,13 @@ typedef struct IdRegMap { uint64_t regs[NR_ID_REGS]; } IdRegMap; +#define ARM_FEATURE_ID_RANGE_IDX(op0, op1, crn, crm, op2) \ + ({ \ + __u64 __op1 = (op1) & 3; \ + __op1 -= (__op1 == 3); \ + (__op1 << 6 | ((crm) & 7) << 3 | (op2)); \ + }) + /* REG is ID_XXX */ #define FIELD_DP64_IDREG(ISAR, REG, FIELD, VALUE) \ ({ \ @@ -913,6 +920,17 @@ typedef struct IdRegMap { i_->idregs[REG ## _EL1_IDX]; \ }) +#define GET_IDREG_WRITABLE(MAP, REG) \ + ({ \ + const IdRegMap *m_ = (MAP); \ + int index = ARM_FEATURE_ID_RANGE_IDX((sysreg >> 14) & 0x0000c000, \ + (sysreg >> 11) & 0x00003800, \ + (sysreg >> 7) & 0x00000780, \ + (sysreg >> 3) & 0x00000078, \ + sysreg & 0x00000007); \ + m_->regs[index]; \ + }) + /** * ARMCPU: * @env: #CPUARMState -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> At the moment kvm_arm_get_host_cpu_features() reads a subset of the ID regs. As we want to introduce properties for all writable ID reg fields, we want more genericity and read more default host register values. Introduce a new get_host_cpu_idregs() helper and add a new exhaustive boolean parameter to kvm_arm_get_host_cpu_features() and kvm_arm_set_cpu_features_from_host() to select the right behavior. The host cpu model will keep the legacy behavior unless the writable id register interface is available. A writable_map IdRegMap is introduced in the CPU object. A subsequent patch will populate it. Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/cpu-sysregs.h | 2 ++ target/arm/cpu.h | 5 ++- target/arm/cpu64.c | 2 +- target/arm/kvm.c | 4 +-- target/arm/kvm64.c | 74 +++++++++++++++++++++++++++++++++++++++- target/arm/kvm_arm.h | 17 ++++++--- target/arm/trace-events | 3 ++ 7 files changed, 98 insertions(+), 9 deletions(-) diff --git a/target/arm/cpu-sysregs.h b/target/arm/cpu-sysregs.h index e89a110590..367fab51f1 100644 --- a/target/arm/cpu-sysregs.h +++ b/target/arm/cpu-sysregs.h @@ -41,6 +41,8 @@ int get_sysreg_idx(ARMSysRegs sysreg); #ifdef CONFIG_KVM uint64_t idregs_sysreg_to_kvm_reg(ARMSysRegs sysreg); +int kvm_idx_to_idregs_idx(int kidx); +int idregs_idx_to_kvm_idx(ARMIDRegisterIdx idx); #endif #endif /* ARM_CPU_SYSREGS_H */ diff --git a/target/arm/cpu.h b/target/arm/cpu.h index a75f057430..7f174ca319 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1078,7 +1078,10 @@ struct ArchCPU { * on KVM custom vcpu model realize */ ARMIdRegsState writable_id_regs; - + + /* ID reg writable bitmask (KVM only) */ + IdRegMap *writable_map; + /* Specify the number of cores in this CPU cluster. Used for the L2CTLR * register. */ diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 828840c1d6..71efd464a9 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -919,7 +919,7 @@ static void aarch64_host_initfn(Object *obj) { #if defined(CONFIG_KVM) ARMCPU *cpu = ARM_CPU(obj); - kvm_arm_set_cpu_features_from_host(cpu); + kvm_arm_set_cpu_features_from_host(cpu, false); if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { aarch64_add_sve_properties(obj); aarch64_add_pauth_properties(obj); diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 04a880df1e..e97bdcb7e1 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -173,13 +173,13 @@ void kvm_arm_destroy_scratch_host_vcpu(int *fdarray) } } -void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu) +void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, bool exhaustive) { CPUARMState *env = &cpu->env; if (!arm_host_cpu_features.dtb_compatible) { if (!kvm_enabled() || - !kvm_arm_get_host_cpu_features(&arm_host_cpu_features)) { + !kvm_arm_get_host_cpu_features(cpu, &arm_host_cpu_features, exhaustive)) { /* We can't report this error yet, so flag that we need to * in arm_cpu_realizefn(). */ diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index bdac9ef549..da9352b14d 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -27,11 +27,13 @@ #include "sysemu/runstate.h" #include "sysemu/kvm.h" #include "sysemu/kvm_int.h" +#include "trace.h" #include "kvm_arm.h" #include "internals.h" #include "cpu-features.h" #include "hw/acpi/acpi.h" #include "hw/acpi/ghes.h" +#include "cpu-custom.h" static bool have_guest_debug; @@ -273,7 +275,72 @@ static int get_host_cpu_reg(int fd, ARMHostCPUFeatures *ahcf, ARMIDRegisterIdx i return ret; } -bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) +int kvm_idx_to_idregs_idx(int kidx) +{ + int op1, crm, op2; + ARMSysRegs sysreg; + + op1 = kidx / 64; + if (op1 == 2) { + op1 = 3; + } + crm = (kidx % 64) / 8; + op2 = kidx % 8; + sysreg = ENCODE_ID_REG(3, op1, 0, crm, op2); + return get_sysreg_idx(sysreg); +} + +int idregs_idx_to_kvm_idx(ARMIDRegisterIdx idx) +{ + ARMSysRegs sysreg = id_register_sysreg[idx]; + + return KVM_ARM_FEATURE_ID_RANGE_IDX((sysreg & CP_REG_ARM64_SYSREG_OP0_MASK) >> CP_REG_ARM64_SYSREG_OP0_SHIFT, + (sysreg & CP_REG_ARM64_SYSREG_OP1_MASK) >> CP_REG_ARM64_SYSREG_OP1_SHIFT, + (sysreg & CP_REG_ARM64_SYSREG_CRN_MASK) >> CP_REG_ARM64_SYSREG_CRN_SHIFT, + (sysreg & CP_REG_ARM64_SYSREG_CRM_MASK) >> CP_REG_ARM64_SYSREG_CRM_SHIFT, + (sysreg & CP_REG_ARM64_SYSREG_OP2_MASK) >> CP_REG_ARM64_SYSREG_OP2_SHIFT); +} + + +/* + * get_host_cpu_idregs: Read all the writable ID reg host values + * + * Need to be called once the writable mask has been populated + * Note we may want to read all the known id regs but some of them are not + * writable and return an error, hence the choice of reading only those which + * are writable. Those are also readable! + */ +static int get_host_cpu_idregs(ARMCPU *cpu, int fd, ARMHostCPUFeatures *ahcf) +{ + int err = 0; + int i; + + for (i = 0; i < NUM_ID_IDX; i++) { + ARM64SysReg *sysregdesc = &arm64_id_regs[i]; + ARMSysRegs sysreg = sysregdesc->sysreg; + uint64_t writable_mask = cpu->writable_map->regs[idregs_idx_to_kvm_idx(i)]; + uint64_t *reg; + int ret; + + if (!writable_mask) { + continue; + } + + reg = &ahcf->isar.idregs[i]; + ret = read_sys_reg64(fd, reg, idregs_sysreg_to_kvm_reg(sysreg)); + trace_get_host_cpu_idregs(sysregdesc->name, *reg); + if (ret) { + error_report("%s error reading value of host %s register (%m)", + __func__, sysregdesc->name); + + err = ret; + } + } + return err; +} + +bool kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf, + bool exhaustive) { /* Identify the feature bits corresponding to the host CPU, and * fill out the ARMHostCPUClass fields accordingly. To do this @@ -399,6 +466,11 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) err |= get_host_cpu_reg(fd, ahcf, ID_DFR1_EL1_IDX); err |= get_host_cpu_reg(fd, ahcf, ID_MMFR5_EL1_IDX); + /* Make sure writable ID reg values are read */ + if (exhaustive) { + err |= get_host_cpu_idregs(cpu, fd, ahcf); + } + /* * DBGDIDR is a bit complicated because the kernel doesn't * provide an accessor for it in 64-bit mode, which is what this diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 50ae2be9c5..b82e04e25b 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -237,14 +237,18 @@ typedef struct ARMHostCPUFeatures { /** * kvm_arm_get_host_cpu_features: + * @cpu: cpu object * @ahcf: ARMHostCPUClass to fill in - * + * @exhaustive: if true, all the feature ID regs are queried instead of + * a subset + * Probe the capabilities of the host kernel's preferred CPU and fill * in the ARMHostCPUClass struct accordingly. * * Returns true on success and false otherwise. */ -bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf); +bool kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf, + bool exhaustive); /** * kvm_arm_sve_get_vls: @@ -262,8 +266,12 @@ uint32_t kvm_arm_sve_get_vls(CPUState *cs); * * Set up the ARMCPU struct fields up to match the information probed * from the host CPU. + * + * @cpu: cpu object + * @exhaustive: if true, all the feature ID regs are queried instead of + * a subset */ -void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu); +void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, bool exhaustive); /** * kvm_arm_add_vcpu_properties: @@ -511,7 +519,8 @@ static inline int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap) /* * These functions should never actually be called without KVM support. */ -static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu) +static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, + bool exhaustive) { g_assert_not_reached(); } diff --git a/target/arm/trace-events b/target/arm/trace-events index 48cc0512db..49162b87b2 100644 --- a/target/arm/trace-events +++ b/target/arm/trace-events @@ -10,5 +10,8 @@ arm_gt_imask_toggle(int timer) "gt_ctl_write: timer %d IMASK toggle" arm_gt_cntvoff_write(uint64_t value) "gt_cntvoff_write: value 0x%" PRIx64 arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d" +# kvm64.c +get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu host value for %s is 0x%"PRIx64 + # kvm.c kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64 -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> We want to give a chance to override the value of host ID regs. In a previous patch we made sure all their values could be fetched through kvm_get_one_reg() calls before their modification. After their potential modification we need to make sure we write back the values through kvm_set_one_reg() calls. Make sure the cpreg_list is modified with updated values and transfer those values back to kvm. Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/kvm.c | 34 ++++++++++++++++++++++++++++++++++ target/arm/kvm64.c | 13 +++++++++++-- target/arm/kvm_arm.h | 6 ++++++ target/arm/trace-events | 1 + 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index e97bdcb7e1..bb9225cb2f 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -23,6 +23,7 @@ #include "sysemu/kvm_int.h" #include "kvm_arm.h" #include "cpu.h" +#include "cpu-custom.h" #include "cpu-sysregs.h" #include "trace.h" #include "internals.h" @@ -794,6 +795,39 @@ static void kvm_arm_configure_vcpu_regs(ARMCPU *cpu) kvm_arm_configure_pmcr(cpu); } +void kvm_arm_writable_idregs_to_cpreg_list(ARMCPU *cpu) +{ + if (!cpu->writable_map) { + return; + } + for (int i = 0; i < NR_ID_REGS; i++) { + uint64_t writable_mask = cpu->writable_map->regs[i]; + uint64_t *cpreg; + + if (writable_mask) { + uint64_t previous, new; + int idx = kvm_idx_to_idregs_idx(i); + ARM64SysReg *sysregdesc; + uint32_t sysreg; + + if (idx == -1) { + /* sysreg writable, but we don't know it */ + continue; + } + sysregdesc = &arm64_id_regs[idx]; + sysreg = sysregdesc->sysreg; + cpreg = kvm_arm_get_cpreg_ptr(cpu, idregs_sysreg_to_kvm_reg(sysreg)); + previous = *cpreg; + new = cpu->isar.idregs[idx]; + if (previous != new) { + *cpreg = new; + trace_kvm_arm_writable_idregs_to_cpreg_list(sysregdesc->name, + previous, new); + } + } + } +} + void kvm_arm_reset_vcpu(ARMCPU *cpu) { int ret; diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index da9352b14d..be9233f936 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -470,7 +470,7 @@ bool kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf, if (exhaustive) { err |= get_host_cpu_idregs(cpu, fd, ahcf); } - + /* * DBGDIDR is a bit complicated because the kernel doesn't * provide an accessor for it in 64-bit mode, which is what this @@ -757,7 +757,16 @@ int kvm_arch_init_vcpu(CPUState *cs) /* Check whether user space can specify guest syndrome value */ kvm_arm_init_serror_injection(cs); - return kvm_arm_init_cpreg_list(cpu); + ret = kvm_arm_init_cpreg_list(cpu); + if (ret) { + return ret; + } + /* overwrite writable ID regs with their updated property values */ + kvm_arm_writable_idregs_to_cpreg_list(cpu); + + write_list_to_kvmstate(cpu, 3); + + return 0; } int kvm_arch_destroy_vcpu(CPUState *cs) diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index b82e04e25b..e7126d1844 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -471,6 +471,8 @@ Object *kvm_arm_rme_get_measurement_log(void); int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap); +void kvm_arm_writable_idregs_to_cpreg_list(ARMCPU *cpu); + #else /* @@ -516,6 +518,10 @@ static inline int kvm_arm_get_writable_id_regs(ARMCPU *cpu, IdRegMap *idregmap) return -ENOSYS; } +void kvm_arm_writable_idregs_to_cpreg_list(ARMCPU *cpu) +{ + g_assert_not_reached(); +} /* * These functions should never actually be called without KVM support. */ diff --git a/target/arm/trace-events b/target/arm/trace-events index 49162b87b2..fe8721d66a 100644 --- a/target/arm/trace-events +++ b/target/arm/trace-events @@ -15,3 +15,4 @@ get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu host value f # kvm.c kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64 +kvm_arm_writable_idregs_to_cpreg_list(const char *name, uint64_t previous, uint64_t new) "%s overwrite default 0x%"PRIx64" with 0x%"PRIx64 -- 2.33.0

From: Eric Auger <eric.auger@redhat.com> If the interface for writable ID registers is available, expose uint64 SYSREG properties for writable ID reg fields exposed by the host kernel. Properties are named SYSREG_<REG>_<FIELD> with REG and FIELD being those used in linux arch/arm64/tools/sysreg. This done by matching the writable fields retrieved from the host kernel against the generated description of sysregs. An example of invocation is: -cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0 which sets DP field of ID_AA64ISAR0_EL1 to 0. [CH: add properties to the host model instead of introducing a new "custom" model] Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/cpu.c | 12 ++++ target/arm/cpu64.c | 22 ++++++- target/arm/kvm64.c | 136 ++++++++++++++++++++++++++++++++++++++++ target/arm/kvm_arm.h | 10 +++ target/arm/trace-events | 4 ++ 5 files changed, 183 insertions(+), 1 deletion(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 08d83c4e1a..0764f96879 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1839,6 +1839,18 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) return; } + /* + * If we failed to retrieve the set of writable ID registers for the "host" + * CPU model, report it here. No error if the interface for discovering + * writable ID registers is not available. + * In case we did get the set of writable ID registers, set the features to + * the configured values here and perform some sanity checks. + */ + if (cpu->writable_id_regs == WRITABLE_ID_REGS_FAILED) { + error_setg(errp, "Failed to discover writable id registers"); + return; + } + #ifndef CONFIG_USER_ONLY /* The NVIC and M-profile CPU are two halves of a single piece of * hardware; trying to use one without the other is a command line diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 71efd464a9..bf8a242c80 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -919,12 +919,32 @@ static void aarch64_host_initfn(Object *obj) { #if defined(CONFIG_KVM) ARMCPU *cpu = ARM_CPU(obj); - kvm_arm_set_cpu_features_from_host(cpu, false); + bool expose_id_regs = true; + int ret; + + cpu->writable_map = g_malloc(sizeof(IdRegMap)); + + /* discover via KVM_ARM_GET_REG_WRITABLE_MASKS */ + ret = kvm_arm_get_writable_id_regs(cpu, cpu->writable_map); + if (ret == -ENOSYS) { + /* legacy: continue without writable id regs */ + expose_id_regs = false; + } else if (ret) { + /* function will have marked an error */ + return; + } + + kvm_arm_set_cpu_features_from_host(cpu, expose_id_regs); if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { aarch64_add_sve_properties(obj); aarch64_add_pauth_properties(obj); aarch64_add_kvm_writable_properties(obj); } + if (expose_id_regs) { + /* generate SYSREG properties according to writable masks */ + kvm_arm_expose_idreg_properties(cpu, arm64_id_regs); + } + #elif defined(CONFIG_HVF) ARMCPU *cpu = ARM_CPU(obj); hvf_arm_set_cpu_features_from_host(cpu); diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index be9233f936..2fe2c4b290 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -339,6 +339,142 @@ static int get_host_cpu_idregs(ARMCPU *cpu, int fd, ARMHostCPUFeatures *ahcf) return err; } + +static ARM64SysRegField *get_field(int i, ARM64SysReg *reg) +{ + GList *l; + + for (l = reg->fields; l; l = l->next) { + ARM64SysRegField *field = (ARM64SysRegField *)l->data; + + if (i >= field->lower && i <= field->upper) { + return field; + } + } + return NULL; +} + +static void set_sysreg_prop(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + ARM64SysRegField *field = (ARM64SysRegField *)opaque; + ARMCPU *cpu = ARM_CPU(obj); + uint64_t *idregs = cpu->isar.idregs; + uint64_t old, value, mask; + int lower = field->lower; + int upper = field->upper; + int length = upper - lower + 1; + int index = field->index; + + if (!visit_type_uint64(v, name, &value, errp)) { + return; + } + + if (length < 64 && value > ((1 << length) - 1)) { + error_setg(errp, + "idreg %s set value (0x%lx) exceeds length of field (%d)!", + name, value, length); + return; + } + + mask = MAKE_64BIT_MASK(lower, length); + value = value << lower; + old = idregs[index]; + idregs[index] = old & ~mask; + idregs[index] |= value; + trace_set_sysreg_prop(name, old, mask, value, idregs[index]); +} + +static void get_sysreg_prop(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + ARM64SysRegField *field = (ARM64SysRegField *)opaque; + ARMCPU *cpu = ARM_CPU(obj); + uint64_t *idregs = cpu->isar.idregs; + uint64_t value, mask; + int lower = field->lower; + int upper = field->upper; + int length = upper - lower + 1; + int index = field->index; + + mask = MAKE_64BIT_MASK(lower, length); + value = (idregs[index] & mask) >> lower; + visit_type_uint64(v, name, &value, errp); + trace_get_sysreg_prop(name, value); +} + +/* + * decode_idreg_writemap: Generate props for writable fields + * + * @obj: CPU object + * @index: index of the sysreg + * @map: writable map for the sysreg + * @reg: description of the sysreg + */ +static int +decode_idreg_writemap(Object *obj, int index, uint64_t map, ARM64SysReg *reg) +{ + int i = ctz64(map); + int nb_sysreg_props = 0; + + while (map) { + + ARM64SysRegField *field = get_field(i, reg); + int lower, upper; + uint64_t mask; + char *prop_name; + + if (!field) { + /* the field cannot be matched to any know id named field */ + warn_report("%s bit %d of %s is writable but cannot be matched", + __func__, i, reg->name); + warn_report("%s is cpu-sysreg-properties.c up to date?", __func__); + map = map & ~BIT_ULL(i); + i = ctz64(map); + continue; + } + lower = field->lower; + upper = field->upper; + prop_name = g_strdup_printf("SYSREG_%s_%s", reg->name, field->name); + trace_decode_idreg_writemap(field->name, lower, upper, prop_name); + object_property_add(obj, prop_name, "uint64", + get_sysreg_prop, set_sysreg_prop, NULL, field); + nb_sysreg_props++; + + mask = MAKE_64BIT_MASK(lower, upper - lower + 1); + map = map & ~mask; + i = ctz64(map); + } + trace_nb_sysreg_props(reg->name, nb_sysreg_props); + return 0; +} + +/* analyze the writable mask and generate properties for writable fields */ +void kvm_arm_expose_idreg_properties(ARMCPU *cpu, ARM64SysReg *regs) +{ + int i, idx; + IdRegMap *map = cpu->writable_map; + Object *obj = OBJECT(cpu); + + for (i = 0; i < NR_ID_REGS; i++) { + uint64_t mask = map->regs[i]; + + if (mask) { + /* reg @i has some writable fields, decode them */ + idx = kvm_idx_to_idregs_idx(i); + if (idx < 0) { + /* no matching reg? */ + warn_report("%s: reg %d writable, but not in list of idregs?", + __func__, i); + } else { + decode_idreg_writemap(obj, i, mask, ®s[idx]); + } + } + } +} + bool kvm_arm_get_host_cpu_features(ARMCPU *cpu, ARMHostCPUFeatures *ahcf, bool exhaustive) { diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index e7126d1844..df8258ef34 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -282,6 +282,16 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu, bool exhaustive); */ void kvm_arm_add_vcpu_properties(Object *obj); +typedef struct ARM64SysReg ARM64SysReg; +/** + * kvm_arm_expose_idreg_properties: + * @cpu: The CPU object to generate the properties for + * @reg: registers from the host + * + * analyze the writable mask and generate properties for writable fields + */ +void kvm_arm_expose_idreg_properties(ARMCPU *cpu, ARM64SysReg *regs); + /** * @cs: CPUState * @feature: a KVM_ARM_VCPU_* feature diff --git a/target/arm/trace-events b/target/arm/trace-events index fe8721d66a..a5f08547a7 100644 --- a/target/arm/trace-events +++ b/target/arm/trace-events @@ -12,6 +12,10 @@ arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d" # kvm64.c get_host_cpu_idregs(const char *name, uint64_t value) "scratch vcpu host value for %s is 0x%"PRIx64 +decode_idreg_writemap(const char* name, int lower, int upper, char *prop_name) "%s [%d:%d] is writable (prop %s)" +get_sysreg_prop(const char *name, uint64_t value) "%s 0x%"PRIx64 +set_sysreg_prop(const char *name, uint64_t old, uint64_t mask, uint64_t field_value, uint64_t new) "%s old reg value=0x%"PRIx64" mask=0x%"PRIx64" new field value=0x%"PRIx64" new reg value=0x%"PRIx64 +nb_sysreg_props(const char *name, int count) "%s: %d SYSREG properties" # kvm.c kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64 -- 2.33.0

From: Cornelia Huck <cohuck@redhat.com> Implement the capability to query available ID register values by adding SYSREG_* options and values to the cpu model expansion for the host model, if available. Excerpt: (QEMU) query-cpu-model-expansion type=full model={"name":"host"} {"return": {"model": {"name": "host", "props": {"SYSREG_ID_AA64PFR0_EL1_EL3": 1224979098931106066, "SYSREG_ID_AA64ISAR2_EL1_CLRBHB": 0, ../.. So this allows the upper stack to detect available writable ID regs and the "host passthrough model" values. [CH: moved SYSREG_* values to host model] Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- target/arm/arm-qmp-cmds.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c index d201d319bd..5109aeb873 100644 --- a/target/arm/arm-qmp-cmds.c +++ b/target/arm/arm-qmp-cmds.c @@ -21,6 +21,7 @@ */ #include "qemu/osdep.h" +#include "qemu/error-report.h" #include "hw/boards.h" #include "kvm_arm.h" #include "qapi/error.h" @@ -218,6 +219,24 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, } } + /* If writable ID regs are supported, add them as well */ + if (ARM_CPU(obj)->writable_id_regs == WRITABLE_ID_REGS_AVAIL) { + ObjectProperty *prop; + ObjectPropertyIterator iter; + + object_property_iter_init(&iter, obj); + + while ((prop = object_property_iter_next(&iter))) { + QObject *value; + + if (!g_str_has_prefix(prop->name, "SYSREG_")) { + continue; + } + value = object_property_get_qobject(obj, prop->name, &error_abort); + qdict_put_obj(qdict_out, prop->name, value); + } + } + if (!qdict_size(qdict_out)) { qobject_unref(qdict_out); } else { -- 2.33.0

From: Cornelia Huck <cohuck@redhat.com> Add some documentation for how individual ID registers can be configured with the host cpu model. [CH: adapt to removal of the 'custom' model, added some more explanations about using the ID register props] Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com> --- docs/system/arm/cpu-features.rst | 104 ++++++++++++++++++++++++++++--- 1 file changed, 96 insertions(+), 8 deletions(-) diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst index a5fb929243..8b497134ab 100644 --- a/docs/system/arm/cpu-features.rst +++ b/docs/system/arm/cpu-features.rst @@ -2,7 +2,10 @@ Arm CPU Features ================ CPU features are optional features that a CPU of supporting type may -choose to implement or not. In QEMU, optional CPU features have +choose to implement or not. QEMU provides two different mechanisms +to configure those features: + +1. For most CPU models, optional CPU features may have corresponding boolean CPU proprieties that, when enabled, indicate that the feature is implemented, and, conversely, when disabled, indicate that it is not implemented. An example of an Arm CPU feature @@ -29,6 +32,16 @@ supports the feature. While ``aarch64`` currently only works with KVM, it could work with TCG. CPU features that are specific to KVM are prefixed with "kvm-" and are described in "KVM VCPU Features". +2. Additionally, the ``host`` CPU model on KVM allows to configure optional +CPU features via the corresponding ID registers. The host kernel allows +to write a subset of ID register fields. The host model exposes +properties for each writable ID register field. Those options are named +SYSREG_<IDREG>_<FIELD>. IDREG and FIELD names are those used in the +ARM ARM Reference Manual. They can also be found in the Linux +arch/arm64/tool/sysreg file which is used to automatically generate the +description for those registers and fields. This currently only has been +implemented for KVM. + CPU Feature Probing =================== @@ -124,13 +137,20 @@ A note about CPU models and KVM Named CPU models generally do not work with KVM. There are a few cases that do work, e.g. using the named CPU model ``cortex-a57`` with KVM on a -seattle host, but mostly if KVM is enabled the ``host`` CPU type must be -used. This means the guest is provided all the same CPU features as the -host CPU type has. And, for this reason, the ``host`` CPU type should -enable all CPU features that the host has by default. Indeed it's even -a bit strange to allow disabling CPU features that the host has when using -the ``host`` CPU type, but in the absence of CPU models it's the best we can -do if we want to launch guests without all the host's CPU features enabled. +seattle host, but mostly if KVM is enabled, the ``host`` CPU model must be +used. + +Using the ``host`` type means the guest is provided all the same CPU +features as the host CPU type has. And, for this reason, the ``host`` +CPU type should enable all CPU features that the host has by default. + +In case some features need to be hidden to the guest, and the host kernel +supports it, the ``host`` model can be instructed to disable individual +ID register values. This is especially useful for migration purposes. +However, this interface will not allow configuring an arbitrary set of +features; the ID registers must describe a subset of the host's features, +and all differences to the host's configuration must actually be supported +by the kernel to be deconfigured. Enabling KVM also affects the ``query-cpu-model-expansion`` QMP command. The affect is not only limited to specific features, as pointed out in example @@ -167,6 +187,13 @@ disabling many SVE vector lengths would be quite verbose, the ``sve<N>`` CPU properties have special semantics (see "SVE CPU Property Parsing Semantics"). +Additionally, if supported by KVM on the host kernel, the ``host`` CPU model +may be configured via individual ID register field properties, for example:: + + $ qemu-system-aarch64 -M virt -cpu host,SYSREG_ID_AA64ISAR0_EL1_DP=0x0 + +This forces ID_AA64ISAR0_EL1 DP field to 0. + KVM VCPU Features ================= @@ -463,3 +490,64 @@ Legal values for ``S`` are 30, 34, 36, and 39; the default is 30. As with ``x-rme``, the ``x-l0gptsz`` property may be renamed or removed in some future QEMU release. + +Configuring CPU features via ID register fields +=============================================== + +Note that this is currently only supported under KVM, and with the +``host`` CPU model. + +Querying available ID register fields +------------------------------------- + +QEMU will create properties for all ID register fields that are +reported as being writable by the kernel, and that are known to the +QEMU instance. Therefore, the same QEMU binary may expose different +properties when run under a different kernel. + +To find out all available writable ID register fields, use the +``query-cpu-model-expansion`` QMP command:: + + (QEMU) query-cpu-model-expansion type=full model={"name":"host"} + {"return": { + "model": {"name": "host", "props": { + "SYSREG_ID_AA64PFR0_EL1_EL3": 1, "SYSREG_ID_AA64ISAR2_EL1_CLRBHB": 0, + "SYSREG_CTR_EL0_L1Ip": 3, "SYSREG_CTR_EL0_DminLine": 4, + "SYSREG_ID_AA64MMFR0_EL1_BIGEND": 1, "SYSREG_ID_AA64MMFR1_EL1_ECBHB": 0, + "SYSREG_ID_AA64MMFR2_EL1_CnP": 1, "SYSREG_ID_DFR0_EL1_PerfMon": 4, + "SYSREG_ID_AA64PFR0_EL1_DIT": 0, "SYSREG_ID_AA64MMFR1_EL1_HAFDBS": 2, + "SYSREG_ID_AA64ISAR0_EL1_FHM": 0, "SYSREG_ID_AA64ISAR2_EL1_CSSC": 0, + "SYSREG_ID_AA64ISAR0_EL1_DP": 1, (...) + }}}} + +If a certain field in an ID register does not show up in this list, it +is not writable with the specific host kernel. + +A note on compatibility +----------------------- + +A common use case for providing a defined set of ID register values is +to be able to present a fixed set of features to a guest, often referred +to as "stable guest ABI". This may take the form of ironing out differences +between two similar CPUs with the intention of being able to migrate +between machines with those CPUs, or providing the same CPU across Linux +kernel updates on the host. + +Over the course of time, the Linux kernel is changing the set of ID register +fields that are writable by userspace. Newly introduced writable ID +registers should be initialized to 0 to ensure compatibility. However, ID +registers that have already been introduced that undergo a change as to +which fields are writable may introduce incompatibities that need to be +addressed on a case-by-case basis for the systems that you wish to migrate +inbetween. + +A note on Arm CPU features (FEAT_xxx) +------------------------------------- + +Configuring CPUs is done on a feature level on other architectures, and this +would imply configuring FEAT_xxx values on Arm. However, differences between +CPUs may not map to FEAT_xxx, but to differences in other registers in the +ID register range; for example, differences in the cache architecture exposed +via ``CTR_EL0``. We therefore cannot rely on configuration via FEAT_xxx. A +feature-based interface more similar to other architectures may be implemented +on top of the ID register interface in the future. -- 2.33.0

From: Qingtong Jia <jiaqingtong@huawei.com> Signed-off-by: Qingtong Jia <jiaqingtong@huawei.com> --- scripts/arm-gen-cpu-sysregs-header.awk | 5 ++++- scripts/gen-cpu-sysreg-properties.awk | 21 +++++++++++++++++++++ target/arm/cpu-sysreg-properties.c | 19 +++++++++++++++++++ target/arm/cpu-sysregs.h.inc | 4 +++- target/arm/cpu64.c | 2 +- 5 files changed, 48 insertions(+), 3 deletions(-) diff --git a/scripts/arm-gen-cpu-sysregs-header.awk b/scripts/arm-gen-cpu-sysregs-header.awk index f92bbbafa7..9f16e420f8 100755 --- a/scripts/arm-gen-cpu-sysregs-header.awk +++ b/scripts/arm-gen-cpu-sysregs-header.awk @@ -9,7 +9,10 @@ BEGIN { print "/* GENERATED FILE, DO NOT EDIT */" print "/* use arm-gen-cpu-sysregs-header.awk to regenerate */" } END { - print "" + /* add MIDR, REVIDR, and AIDR */ + print "DEF(MIDR_EL1, 3, 0, 0, 0, 0)" + print "DEF(REVIDR_EL1, 3, 0, 0, 0, 6)" + print "DEF(AIDR_EL1, 3, 1, 0, 0, 7)" } # skip blank lines and comment lines diff --git a/scripts/gen-cpu-sysreg-properties.awk b/scripts/gen-cpu-sysreg-properties.awk index da00d377ff..56d9d8f002 100755 --- a/scripts/gen-cpu-sysreg-properties.awk +++ b/scripts/gen-cpu-sysreg-properties.awk @@ -106,6 +106,27 @@ END { if (__current_block_depth != 0) fatal("Missing terminator for " block_current() " block") + # Manually add MIDR/REVIDR/AIDR + print "" + print " /* MIDR_EL1 */" + print " ARM64SysReg *MIDR_EL1 = arm64_sysreg_get(MIDR_EL1_IDX);" + print " MIDR_EL1->name = \"MIDR_EL1\";" + print " arm64_sysreg_add_field(MIDR_EL1, \"Implementer\", 24, 31);" + print " arm64_sysreg_add_field(MIDR_EL1, \"Variant\", 20, 23);" + print " arm64_sysreg_add_field(MIDR_EL1, \"Architecture\", 16, 19);" + print " arm64_sysreg_add_field(MIDR_EL1, \"PartNum\", 4, 15);" + print " arm64_sysreg_add_field(MIDR_EL1, \"Revision\", 0, 3);" + print "" + print " /* REVIDR_EL1 */" + print " ARM64SysReg *REVIDR_EL1 = arm64_sysreg_get(REVIDR_EL1_IDX);" + print " REVIDR_EL1->name = \"REVIDR_EL1\";" + print " arm64_sysreg_add_field(REVIDR_EL1, \"IMPDEF\", 0, 63);" + print "" + print " /* AIDR_EL1 */" + print " ARM64SysReg *AIDR_EL1 = arm64_sysreg_get(AIDR_EL1_IDX);" + print " AIDR_EL1->name = \"AIDR_EL1\";" + print " arm64_sysreg_add_field(AIDR_EL1, \"IMPDEF\", 0, 63);" + print "" print "}" } diff --git a/target/arm/cpu-sysreg-properties.c b/target/arm/cpu-sysreg-properties.c index 94cc496438..c8a43c9eb4 100644 --- a/target/arm/cpu-sysreg-properties.c +++ b/target/arm/cpu-sysreg-properties.c @@ -742,4 +742,23 @@ void initialize_cpu_sysreg_properties(void) /* For S2PIR_EL2 fields see PIRx_ELx */ + /* MIDR_EL1 */ + ARM64SysReg *MIDR_EL1 = arm64_sysreg_get(MIDR_EL1_IDX); + MIDR_EL1->name = "MIDR_EL1"; + arm64_sysreg_add_field(MIDR_EL1, "Implementer", 24, 31); + arm64_sysreg_add_field(MIDR_EL1, "Variant", 20, 23); + arm64_sysreg_add_field(MIDR_EL1, "Architecture", 16, 19); + arm64_sysreg_add_field(MIDR_EL1, "PartNum", 4, 15); + arm64_sysreg_add_field(MIDR_EL1, "Revision", 0, 3); + + /* REVIDR_EL1 */ + ARM64SysReg *REVIDR_EL1 = arm64_sysreg_get(REVIDR_EL1_IDX); + REVIDR_EL1->name = "REVIDR_EL1"; + arm64_sysreg_add_field(REVIDR_EL1, "IMPDEF", 0, 63); + + /* AIDR_EL1 */ + ARM64SysReg *AIDR_EL1 = arm64_sysreg_get(AIDR_EL1_IDX); + AIDR_EL1->name = "AIDR_EL1"; + arm64_sysreg_add_field(AIDR_EL1, "IMPDEF", 0, 63); + } diff --git a/target/arm/cpu-sysregs.h.inc b/target/arm/cpu-sysregs.h.inc index 1dddd3d357..e3e81e11ee 100644 --- a/target/arm/cpu-sysregs.h.inc +++ b/target/arm/cpu-sysregs.h.inc @@ -50,4 +50,6 @@ DEF(GMID_EL1, 3, 1, 0, 0, 4) DEF(SMIDR_EL1, 3, 1, 0, 0, 6) DEF(CTR_EL0, 3, 3, 0, 0, 1) DEF(DCZID_EL0, 3, 3, 0, 0, 7) - +DEF(MIDR_EL1, 3, 0, 0, 0, 0) +DEF(REVIDR_EL1, 3, 0, 0, 0, 6) +DEF(AIDR_EL1, 3, 1, 0, 0, 7) \ No newline at end of file diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index bf8a242c80..593bfea299 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -53,7 +53,7 @@ int get_sysreg_idx(ARMSysRegs sysreg) switch (sysreg) { #include "cpu-sysregs.h.inc" } - g_assert_not_reached(); + return -1; } #undef DEF -- 2.33.0

From: Qingtong Jia <jiaqingtong@huawei.com> Signed-off-by: Qingtong Jia <jiaqingtong@huawei.com> --- accel/kvm/kvm-all.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 6e3a3f14a1..a321bf514c 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2680,6 +2680,13 @@ static int kvm_init(MachineState *ms) query_stats_schemas_cb); } + if (kvm_check_extension(kvm_state, KVM_CAP_ARM_WRITABLE_IMP_ID_REGS)) { + ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_WRITABLE_IMP_ID_REGS, 0); + if (ret) { + fprintf(stderr, "Could not enable KVM_CAP_ARM_WRITABLE_IMP_ID_REGS: %d\n", ret); + } + } + return 0; err: -- 2.33.0

From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> ToDo: Do it properly using update-linux-headers.sh Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> --- target/arm/kvm.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index bb9225cb2f..610a913062 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -37,6 +37,53 @@ #include "qapi/visitor.h" #include "qemu/log.h" +/* + * SMMCC KVM Vendor hypercall definitions. + * ToDo: Include using update-linux-headers.sh + */ +#define ARM_SMCCC_FAST_CALL _AC(1,U) +#define ARM_SMCCC_TYPE_SHIFT 31 + +#define ARM_SMCCC_SMC_32 0 +#define ARM_SMCCC_SMC_64 1 +#define ARM_SMCCC_CALL_CONV_SHIFT 30 + +#define ARM_SMCCC_OWNER_MASK 0x3F +#define ARM_SMCCC_OWNER_SHIFT 24 + +#define ARM_SMCCC_FUNC_MASK 0xFFFF + +#define ARM_SMCCC_OWNER_VENDOR_HYP 6 + + +#define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER 64 +#define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS 65 + +#define ARM_SMCCC_KVM_DISCOVER_IMPL_VER_1_0 0x10000 + +#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \ + (((type) << ARM_SMCCC_TYPE_SHIFT) | \ + ((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \ + (((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \ + ((func_num) & ARM_SMCCC_FUNC_MASK)) + +#define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_64, \ + ARM_SMCCC_OWNER_VENDOR_HYP, \ + ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER) + +#define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_64, \ + ARM_SMCCC_OWNER_VENDOR_HYP, \ + ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS) + +#define SMCCC_RET_SUCCESS 0 +#define SMCCC_RET_NOT_SUPPORTED -1 +#define SMCCC_RET_NOT_REQUIRED -2 +#define SMCCC_RET_INVALID_PARAMETER -3 + const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO }; -- 2.33.0

From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> This is a hacked interface to test the kernel. Usage Eg: -machine virt,.., x-target-impl-cpus=0xMIDR1:0xREVIDR1-0xMIDR2:REVIDR2 The HVC/SMC hypercall exit handling part is loosly based on this patch, https://lore.kernel.org/qemu-devel/20240614001510.202991-1-salil.mehta@huawe... Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> --- hw/arm/virt.c | 65 ++++++++++++++++++++++++++++++++++++++- include/hw/boards.h | 3 ++ target/arm/kvm.c | 72 +++++++++++++++++++++++++++++++++++++++++--- target/arm/kvm_arm.h | 6 ++++ 4 files changed, 140 insertions(+), 6 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index cf4156ed49..d8890e319f 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -29,6 +29,7 @@ */ #include "qemu/osdep.h" +#include "qemu/cutils.h" #include "qemu/datadir.h" #include "qemu/units.h" #include "qemu/option.h" @@ -3112,6 +3113,62 @@ static void virt_set_oem_table_id(Object *obj, const char *value, strncpy(vms->oem_table_id, value, 8); } +static TargetImplCpu target_impl_cpus[MAX_TARGET_IMPL_CPUS]; + +static void virt_set_target_impl_cpus(Object *obj, const char *value, + Error **errp) +{ + MachineState *ms = MACHINE(obj); + g_autofree char *target_dup = g_strdup(value); + char *target_impl = strtok(target_dup, "-"); + int cnt = 0; + + while (target_impl) { + char num[16]; + long val; + const char *num_start = target_impl; + const char *num_end = strchr(num_start, ':'); + + if (!num_end) { + error_setg(errp, + "Wrong format, Please use 0xmidr:0xrevid-0xmidr:0xrevid"); + return; + } + + strncpy(num, num_start, num_end - num_start); + num[num_end - num_start] = '\0'; + if (qemu_strtol(num, NULL, 16, &val)) { + error_setg(errp, + "Wrong format, Please use 0xmidr:0xrevid-0xmidr:0xrevid"); + return; + } + target_impl_cpus[cnt].midr = val; + num_start = num_end + 1; + if (!(*num_start)) { + error_setg(errp, + "Wrong format, Please use 0xmidr:0xrevid-0xmidr:0xrevid"); + return; + } + + strncpy(num, num_start, sizeof(num) - 1); + num[sizeof(num) - 1] = '\0'; + if (qemu_strtol(num, NULL, 16, &val)) { + error_setg(errp, + "Wrong format, Please use 0xmidr:0xrevid-0xmidr:0xrevid"); + return; + } + target_impl_cpus[cnt].revidr = val; + cnt++; + if (cnt >= MAX_TARGET_IMPL_CPUS) { + error_setg(errp, + "Wrong format, Max %d targets can be set for now!", MAX_TARGET_IMPL_CPUS); + return; + } + target_impl = strtok(NULL, "-"); + } + ms->target_ipml_cpu_num = cnt; + ms->target_ipml_cpu = target_impl_cpus; +} bool virt_is_acpi_enabled(VirtMachineState *vms) { @@ -4094,7 +4151,13 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) "Override the default value of field OEM Table ID " "in ACPI table header." "The string may be up to 8 bytes in size"); - + + object_class_property_add_str(oc, "x-target-impl-cpus", + NULL, + virt_set_target_impl_cpus); + object_class_property_set_description(oc, "x-target-impl-cpus", + "Describe target cpu impl in the format midr1:revidr1-midr2:revidr2" + "Maximum 4 midr:revidr pair is supported"); } static char *virt_get_kvm_type(Object *obj, Error **errp G_GNUC_UNUSED) diff --git a/include/hw/boards.h b/include/hw/boards.h index 8ac8cad2a2..192dc7dc09 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -402,6 +402,9 @@ struct MachineState { CpuTopology smp; struct NVDIMMState *nvdimms_state; struct NumaState *numa_state; + + uint32_t target_ipml_cpu_num; + void *target_ipml_cpu; }; #define DEFINE_MACHINE(namestr, machine_initfn) \ diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 610a913062..165e0034bb 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -59,7 +59,7 @@ #define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER 64 #define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS 65 -#define ARM_SMCCC_KVM_DISCOVER_IMPL_VER_1_0 0x10000 +#define ARM_SMCCC_KVM_DISCOVER_IMPL_VER_1_0 0x100000000 #define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \ (((type) << ARM_SMCCC_TYPE_SHIFT) | \ @@ -436,6 +436,16 @@ int kvm_arch_init(MachineState *ms, KVMState *s) if (ret) { error_report("Failed to enable RME: %s", strerror(-ret)); } + + if (kvm_arm_set_smccc_filter(ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID, + KVM_SMCCC_FILTER_FWD_TO_USER)) { + error_report("ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER fwd filter install failed"); + } + + if (kvm_arm_set_smccc_filter(ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID, + KVM_SMCCC_FILTER_FWD_TO_USER)) { + error_report("ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS fwd filter install failed"); + } return ret; } @@ -1174,6 +1184,55 @@ void kvm_arm_vm_state_change(void *opaque, bool running, RunState state) } } +static bool arm_handle_smcc_kvm_vendor_hypercall(ARMCPU *cpu) +{ + MachineState *ms = MACHINE(qdev_get_machine()); + CPUARMState *env = &cpu->env; + uint64_t param[4]; + int idx; + int i; + + for (i = 0; i < 4; i++) { + /* + * All PSCI functions take explicit 32-bit or native int sized + * arguments so we can simply zero-extend all arguments regardless + * of which exact function we are about to call. + */ + param[i] = is_a64(env) ? env->xregs[i] : env->regs[i]; + } + + if (is_a64(env)) { + TargetImplCpu *target = ms->target_ipml_cpu; + + switch (param[0]) { + case ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID: + if (!ms->target_ipml_cpu_num) { + env->xregs[0] = SMCCC_RET_NOT_SUPPORTED; + break; + } + env->xregs[0] = SMCCC_RET_SUCCESS; + env->xregs[1] = ARM_SMCCC_KVM_DISCOVER_IMPL_VER_1_0; + env->xregs[2] = ms->target_ipml_cpu_num; + break; + case ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID: + idx = param[1]; + if (idx >= ms->target_ipml_cpu_num) { + env->xregs[0] = SMCCC_RET_INVALID_PARAMETER; + break; + } + env->xregs[0] = SMCCC_RET_SUCCESS; + env->xregs[1] = target[idx].midr; + env->xregs[2] = target[idx].revidr; + break; + default: + return false; + } + } else { + return false; + } + return true; +} + /** * kvm_arm_handle_dabt_nisv: * @cs: CPUState @@ -1236,9 +1295,12 @@ static int kvm_arm_handle_hypercall(CPUState *cs, struct kvm_run *run) env->exception.syndrome = syn_aa64_hvc(0); } env->exception.target_el = 1; - qemu_mutex_lock_iothread(); - arm_cpu_do_interrupt(cs); - qemu_mutex_unlock_iothread(); + + if (!arm_handle_smcc_kvm_vendor_hypercall(cpu)) { + qemu_mutex_lock_iothread(); + arm_cpu_do_interrupt(cs); + qemu_mutex_unlock_iothread(); + } /* * For PSCI, exit the kvm_run loop and process the work. Especially @@ -1263,7 +1325,7 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) run->arm_nisv.fault_ipa); break; case KVM_EXIT_HYPERCALL: - ret = kvm_arm_handle_hypercall(cs, run); + ret = kvm_arm_handle_hypercall(cs, run); break; default: qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n", diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index df8258ef34..8c69957fbf 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -21,6 +21,12 @@ #define KVM_REG_ARM_ID_AA64DFR0_EL1 ARM64_SYS_REG(3, 0, 0, 5, 0) #define KVM_REG_ARM_PMCR_EL0 ARM64_SYS_REG(3, 3, 9, 12, 0) +#define MAX_TARGET_IMPL_CPUS 8 +typedef struct TargetImplCpu { + uint32_t midr; + uint32_t revidr; +} TargetImplCpu; + /** * kvm_arm_init_debug() - initialize guest debug capabilities * @s: KVMState -- 2.33.0

From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> --- target/arm/kvm.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 165e0034bb..96b0784b90 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -59,8 +59,6 @@ #define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER 64 #define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS 65 -#define ARM_SMCCC_KVM_DISCOVER_IMPL_VER_1_0 0x100000000 - #define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \ (((type) << ARM_SMCCC_TYPE_SHIFT) | \ ((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \ @@ -1211,7 +1209,7 @@ static bool arm_handle_smcc_kvm_vendor_hypercall(ARMCPU *cpu) break; } env->xregs[0] = SMCCC_RET_SUCCESS; - env->xregs[1] = ARM_SMCCC_KVM_DISCOVER_IMPL_VER_1_0; + env->xregs[1] = PSCI_VERSION(1, 0); env->xregs[2] = ms->target_ipml_cpu_num; break; case ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID: -- 2.33.0

From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> --- target/arm/kvm64.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 2fe2c4b290..406c054ace 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -793,6 +793,14 @@ static int kvm_arm_sve_set_vls(CPUState *cs) return kvm_set_one_reg(cs, KVM_REG_ARM64_SVE_VLS, &vls[0]); } +static int kvm_arm_set_vend_hyp_bmap_2(ARMCPU *cpu) +{ + /* Set DISCOVER_IMPL_* hypercalls */ + uint64_t bmap_2 = MAKE_64BIT_MASK(0, 2); + + return kvm_set_one_reg(CPU(cpu), KVM_REG_ARM_VENDOR_HYP_BMAP_2, &bmap_2); +} + #define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5 int kvm_arch_init_vcpu(CPUState *cs) @@ -869,6 +877,7 @@ int kvm_arch_init_vcpu(CPUState *cs) } } + kvm_arm_set_vend_hyp_bmap_2(cpu); /* * KVM reports the exact PSCI version it is implementing via a * special sysreg. If it is present, use its contents to determine -- 2.33.0
participants (1)
-
Jinqian Yang