Include cpu-idregs.h.inc multiple times with different definitions for the X-macros. This will generate tables for all Arm64 ID registers and their fields. Additionally, initialize the tables with all architecturally defined values. These tables will be consumed by the property layer in future patches.
Co-authored-by: Khushit Shah <[email protected]> Signed-off-by: Shaju Abraham <[email protected]> --- target/arm/cpu-idregs.c | 124 ++++++++++++++++++++++++++++++++++++++++ target/arm/cpu-idregs.h | 81 ++++++++++++++++++++++++++ target/arm/meson.build | 1 + 3 files changed, 206 insertions(+) create mode 100644 target/arm/cpu-idregs.c diff --git a/target/arm/cpu-idregs.c b/target/arm/cpu-idregs.c new file mode 100644 index 0000000000..8fced7d8d7 --- /dev/null +++ b/target/arm/cpu-idregs.c @@ -0,0 +1,124 @@ +/* + * ARM ID register field table. + * + * Builds the per-id-register field descriptor arrays and the global + * arm_idregs[] table. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qapi/error.h" +#include "cpu.h" +#include "cpu-idregs.h" + +/* generate an array of architecturely defined values for bitfields + * in arch-value format*/ +#define IDREG_START(reg) +#define IDREG_END(reg) +#define IDREG_FIELD_START(reg, field, shift, length, safe, defval) \ + static const ArmIdRegArchVal reg##_##field##_arch_vals[] = { +#define IDREG_FIELD_ARCH_VAL(v, n) { (v), (n) }, +#define IDREG_FIELD_ARCH_VAL_ANY { 0xffffffffUL, NULL }, +#define IDREG_FIELD_END(reg, field) \ + }; +#include "cpu-idregs.h.inc" +#undef IDREG_START +#undef IDREG_END +#undef IDREG_FIELD_START +#undef IDREG_FIELD_ARCH_VAL +#undef IDREG_FIELD_ARCH_VAL_ANY +#undef IDREG_FIELD_END +/* generate an array of per-register ArmIdRegField[] descriptors */ +#define IDREG_FIELD_ARCH_VAL(v, n) +#define IDREG_FIELD_ARCH_VAL_ANY +#define IDREG_FIELD_END(reg, field) +#define IDREG_START(reg) \ + static ArmIdRegField reg##_fields[] = { + +#define IDREG_END(reg) \ + }; + +#define IDREG_FIELD_START(reg, field, _shift, _length, safe, defval) \ + { \ + .name = #field, \ + .shift = (_shift), \ + .length = (_length), \ + .safe_rule = IDREG_SAFE_##safe, \ + .default_val = (defval), \ + .arch_vals = (ArmIdRegArchVal *)reg##_##field##_arch_vals, \ + .arch_vals_count = ARRAY_SIZE(reg##_##field##_arch_vals), \ + }, +#include "cpu-idregs.h.inc" +#undef IDREG_START +#undef IDREG_END +#undef IDREG_FIELD_START +#undef IDREG_FIELD_ARCH_VAL +#undef IDREG_FIELD_END + +/* generate an array of top level ID registers */ +#define IDREG_END(reg) +#define IDREG_FIELD_START(reg, field, shift, length, safe, defval) +#define IDREG_FIELD_ARCH_VAL(v, n) +#define IDREG_FIELD_ARCH_VAL_ANY +#define IDREG_FIELD_END(reg, field) + +#define IDREG_START(reg) \ + [reg##_IDX] = { \ + .name = #reg, \ + .fields = reg##_fields, \ + .fields_count = ARRAY_SIZE(reg##_fields), \ + }, + +ArmIdReg arm_idregs[NUM_ID_IDX] = { +#include "cpu-idregs.h.inc" +}; +#undef IDREG_START +#undef IDREG_END +#undef IDREG_FIELD_START +#undef IDREG_FIELD_ARCH_VAL +#undef IDREG_FIELD_END + + +/* Per-register field position enums (0..N-1 inside each register). */ +#define IDREG_START(reg) enum { +#define IDREG_END(reg) reg##_FIELD_POS__MAX }; +#define IDREG_FIELD_START(reg, field, shift, length, safe, defval) \ + reg##_FIELD_POS_##field, +#define IDREG_FIELD_ARCH_VAL(v, n) +#define IDREG_FIELD_ARCH_VAL_ANY +#define IDREG_FIELD_END(reg, field) + +#include "cpu-idregs.h.inc" + +#undef IDREG_FIELD_END +#undef IDREG_FIELD_ARCH_VAL_ANY +#undef IDREG_FIELD_ARCH_VAL +#undef IDREG_FIELD_START +#undef IDREG_END +#undef IDREG_START + +/* Flat ArmFieldIdx -> {reg, field slot, shift, length}. */ +#define IDREG_START(reg) +#define IDREG_END(reg) +#define IDREG_FIELD_START(reg, field, _shift, _length, safe, defval) \ + [ARM_FIELD_##reg##_##field] = { \ + .reg_idx = reg##_IDX, \ + .field_idx = reg##_FIELD_POS_##field, \ + .shift = (_shift), \ + .length = (_length), \ + }, +#define IDREG_FIELD_ARCH_VAL(v, n) +#define IDREG_FIELD_ARCH_VAL_ANY +#define IDREG_FIELD_END(reg, field) + +const ArmIdRegFieldLoc arm_field_locs[ARM_FIELD__MAX] = { +#include "cpu-idregs.h.inc" +}; + +#undef IDREG_FIELD_END +#undef IDREG_FIELD_ARCH_VAL_ANY +#undef IDREG_FIELD_ARCH_VAL +#undef IDREG_FIELD_START +#undef IDREG_END +#undef IDREG_START diff --git a/target/arm/cpu-idregs.h b/target/arm/cpu-idregs.h index 403190cbd7..4e568e877d 100644 --- a/target/arm/cpu-idregs.h +++ b/target/arm/cpu-idregs.h @@ -7,6 +7,8 @@ #ifndef CPU_IDREGS_H #define CPU_IDREGS_H +#include "cpu-sysregs.h" + typedef enum ArmIdRegSafeRule { IDREG_SAFE_LOWER, IDREG_SAFE_HIGHER, @@ -37,5 +39,84 @@ typedef struct ArmIdReg { uint32_t fields_count; } ArmIdReg; +/* Map short register names to canonical _EL1/_EL0 IDX values */ +#define ID_AA64ISAR0_IDX ID_AA64ISAR0_EL1_IDX +#define ID_AA64ISAR1_IDX ID_AA64ISAR1_EL1_IDX +#define ID_AA64ISAR2_IDX ID_AA64ISAR2_EL1_IDX +#define ID_AA64ISAR3_IDX ID_AA64ISAR3_EL1_IDX +#define ID_AA64PFR0_IDX ID_AA64PFR0_EL1_IDX +#define ID_AA64PFR1_IDX ID_AA64PFR1_EL1_IDX +#define ID_AA64PFR2_IDX ID_AA64PFR2_EL1_IDX +#define ID_AA64MMFR0_IDX ID_AA64MMFR0_EL1_IDX +#define ID_AA64MMFR1_IDX ID_AA64MMFR1_EL1_IDX +#define ID_AA64MMFR2_IDX ID_AA64MMFR2_EL1_IDX +#define ID_AA64MMFR3_IDX ID_AA64MMFR3_EL1_IDX +#define ID_AA64MMFR4_IDX ID_AA64MMFR4_EL1_IDX +#define ID_AA64DFR0_IDX ID_AA64DFR0_EL1_IDX +#define ID_AA64DFR1_IDX ID_AA64DFR1_EL1_IDX +#define ID_AA64ZFR0_IDX ID_AA64ZFR0_EL1_IDX +#define ID_AA64SMFR0_IDX ID_AA64SMFR0_EL1_IDX +#define ID_AA64AFR0_IDX ID_AA64AFR0_EL1_IDX +#define ID_AA64AFR1_IDX ID_AA64AFR1_EL1_IDX +#define ID_AA64FPFR0_IDX ID_AA64FPFR0_EL1_IDX +#define ID_PFR0_IDX ID_PFR0_EL1_IDX +#define ID_PFR1_IDX ID_PFR1_EL1_IDX +#define ID_PFR2_IDX ID_PFR2_EL1_IDX +#define ID_DFR0_IDX ID_DFR0_EL1_IDX +#define ID_DFR1_IDX ID_DFR1_EL1_IDX +#define ID_AFR0_IDX ID_AFR0_EL1_IDX +#define ID_MMFR0_IDX ID_MMFR0_EL1_IDX +#define ID_MMFR1_IDX ID_MMFR1_EL1_IDX +#define ID_MMFR2_IDX ID_MMFR2_EL1_IDX +#define ID_MMFR3_IDX ID_MMFR3_EL1_IDX +#define ID_MMFR4_IDX ID_MMFR4_EL1_IDX +#define ID_MMFR5_IDX ID_MMFR5_EL1_IDX +#define ID_ISAR0_IDX ID_ISAR0_EL1_IDX +#define ID_ISAR1_IDX ID_ISAR1_EL1_IDX +#define ID_ISAR2_IDX ID_ISAR2_EL1_IDX +#define ID_ISAR3_IDX ID_ISAR3_EL1_IDX +#define ID_ISAR4_IDX ID_ISAR4_EL1_IDX +#define ID_ISAR5_IDX ID_ISAR5_EL1_IDX +#define ID_ISAR6_IDX ID_ISAR6_EL1_IDX +#define MVFR0_IDX MVFR0_EL1_IDX +#define MVFR1_IDX MVFR1_EL1_IDX +#define MVFR2_IDX MVFR2_EL1_IDX +#define MIDR_IDX MIDR_EL1_IDX +#define REVIDR_IDX REVIDR_EL1_IDX +#define AIDR_IDX AIDR_EL1_IDX +#define DCZID_IDX DCZID_EL0_IDX + +/* ArmFieldIdx: per-field enum generated from cpu-idregs.h.inc */ +#define IDREG_START(reg) +#define IDREG_END(reg) +#define IDREG_FIELD_START(reg, field, shift, length, safe, defval) \ + ARM_FIELD_##reg##_##field, +#define IDREG_FIELD_ARCH_VAL(v, n) +#define IDREG_FIELD_ARCH_VAL_ANY +#define IDREG_FIELD_END(reg, field) +typedef enum ArmFieldIdx { +#include "cpu-idregs.h.inc" + ARM_FIELD__MAX, +} ArmFieldIdx; +#undef IDREG_FIELD_END +#undef IDREG_FIELD_ARCH_VAL_ANY +#undef IDREG_FIELD_ARCH_VAL +#undef IDREG_FIELD_START +#undef IDREG_END +#undef IDREG_START + +typedef struct ArmIdRegFieldLoc { + ARMIDRegisterIdx reg_idx; + uint16_t field_idx; + uint8_t shift; + uint8_t length; +} ArmIdRegFieldLoc; +extern const ArmIdRegFieldLoc arm_field_locs[ARM_FIELD__MAX]; +#define ARM_FIELD_REG(idx) (arm_field_locs[(idx)].reg_idx) +#define ARM_FIELD_REG_FIELD(idx) (arm_field_locs[(idx)].field_idx) +#define ARM_FIELD_SHIFT(idx) (arm_field_locs[(idx)].shift) +#define ARM_FIELD_LENGTH(idx) (arm_field_locs[(idx)].length) +#define ARM_FIELD_IDX(reg, field) ARM_FIELD_##reg##_##field +extern ArmIdReg arm_idregs[NUM_ID_IDX]; #endif /* CPU_IDREGS_H */ diff --git a/target/arm/meson.build b/target/arm/meson.build index 4723f9f170..64d1ec63ab 100644 --- a/target/arm/meson.build +++ b/target/arm/meson.build @@ -19,6 +19,7 @@ arm_common_ss.add(files( arm_common_system_ss.add(files( 'arm-qmp-cmds.c', + 'cpu-idregs.c', )) arm_system_ss.add(when: 'CONFIG_KVM', if_true: files('hyp_gdbstub.c', 'kvm.c')) arm_system_ss.add(when: 'CONFIG_HVF', if_true: files('hyp_gdbstub.c')) -- 2.52.0
