Add a KVM-only named CPU model for the Armv9.0-A baseline, following
DDI0487 revision M.c. The property list is the architecture-mandated
ID-register field view.
Pointer authentication is omitted because a v9.0-A core may implement
any PAuth algorithm.
Named models start from a zeroed ID-register view, so features whose
"not implemented" encoding is non-zero (for example TGran64=0xF,
DoubleLock=0xF) are set explicitly.
The model is not realizable on its own; implementation-defined fields
such as CTR_EL0.{CWG,ERG} and ID_AA64DFR0_EL1.CTX_CMPs still have to be
supplied on the command line. However, this provides a useful baseline
for upcoming reference core models.
Final ID register state requested from KVM for "arm-v9.0-a-v1":
[ 0] AIDR_EL1 = 0x0000000000000000
[ 1] CLIDR_EL1 = 0x0000000000000000
[ 2] CTR_EL0 = 0x0000000080008000
[ 3] DCZID_EL0 = 0x0000000000000000
[ 4] GMID_EL1 = 0x0000000000000000
[ 5] ID_AA64AFR0_EL1 = 0x0000000000000000
[ 6] ID_AA64AFR1_EL1 = 0x0000000000000000
[ 7] ID_AA64DFR0_EL1 = 0x000000f000000009
[ 8] ID_AA64DFR1_EL1 = 0x0000000000000000
[ 9] ID_AA64DFR2_EL1 = 0x0000000000000000
[ 10] ID_AA64FPFR0_EL1 = 0x0000000000000000
[ 11] ID_AA64ISAR0_EL1 = 0x0221100010210000
[ 12] ID_AA64ISAR1_EL1 = 0x0000011100211002
[ 13] ID_AA64ISAR2_EL1 = 0x0000000000000000
[ 14] ID_AA64ISAR3_EL1 = 0x0000000000000000
[ 15] ID_AA64MMFR0_EL1 = 0x000001110f000000
[ 16] ID_AA64MMFR1_EL1 = 0x0000000000211000
[ 17] ID_AA64MMFR2_EL1 = 0x1001001100000011
[ 18] ID_AA64MMFR3_EL1 = 0x0000000000000000
[ 19] ID_AA64MMFR4_EL1 = 0x000000000f000000
[ 20] ID_AA64PFR0_EL1 = 0x1101000010110011
[ 21] ID_AA64PFR1_EL1 = 0x0000000000000001
[ 22] ID_AA64PFR2_EL1 = 0x0000000000000000
[ 23] ID_AA64SMFR0_EL1 = 0x0000000000000000
[ 24] ID_AA64ZFR0_EL1 = 0x0000000000000000
[ 25] ID_AFR0_EL1 = 0x0000000000000000
[ 26] ID_DFR0_EL1 = 0x0000000000000000
[ 27] ID_DFR1_EL1 = 0x0000000000000000
[ 28] ID_ISAR0_EL1 = 0x0000000000000000
[ 29] ID_ISAR1_EL1 = 0x0000000000000000
[ 30] ID_ISAR2_EL1 = 0x0000000000000000
[ 31] ID_ISAR3_EL1 = 0x0000000000000000
[ 32] ID_ISAR4_EL1 = 0x0000000000000000
[ 33] ID_ISAR5_EL1 = 0x0000000000000000
[ 34] ID_ISAR6_EL1 = 0x0000000000000000
[ 35] ID_MMFR0_EL1 = 0x0000000000000000
[ 36] ID_MMFR1_EL1 = 0x0000000000000000
[ 37] ID_MMFR2_EL1 = 0x0000000000000000
[ 38] ID_MMFR3_EL1 = 0x0000000000000000
[ 39] ID_MMFR4_EL1 = 0x0000000000000000
[ 40] ID_MMFR5_EL1 = 0x0000000000000000
[ 41] ID_PFR0_EL1 = 0x0000000000000000
[ 42] ID_PFR1_EL1 = 0x0000000000000000
[ 43] ID_PFR2_EL1 = 0x0000000000000000
[ 44] MIDR_EL1 = 0x0000000000000000
[ 45] MPIDR_EL1 = 0x0000000080000000
[ 46] MVFR0_EL1 = 0x0000000000000000
[ 47] MVFR1_EL1 = 0x0000000000000000
[ 48] MVFR2_EL1 = 0x0000000000000000
[ 49] REVIDR_EL1 = 0x0000000000000000
[ 50] SMIDR_EL1 = 0x0000000000000000
Signed-off-by: Khushit Shah <[email protected]>
---
hw/arm/virt.c | 3 ++
target/arm/cpu-models.c | 75 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 78 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index e7a56e37f7..01381ab5e7 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -4144,6 +4144,9 @@ static GPtrArray *virt_get_valid_cpu_types(const
MachineState *ms)
g_ptr_array_add(vct, g_strdup(ARM_CPU_TYPE_NAME("neoverse-v1")));
g_ptr_array_add(vct, g_strdup(ARM_CPU_TYPE_NAME("neoverse-n2")));
}
+ if (kvm_enabled() && target_aarch64()) {
+ g_ptr_array_add(vct, g_strdup(ARM_CPU_TYPE_NAME("arm-v9.0-a-v1")));
+ }
if (target_aarch64()) {
g_ptr_array_add(vct, g_strdup(ARM_CPU_TYPE_NAME("cortex-a53")));
g_ptr_array_add(vct, g_strdup(ARM_CPU_TYPE_NAME("cortex-a57")));
diff --git a/target/arm/cpu-models.c b/target/arm/cpu-models.c
index 153ee10ae6..7394dd358e 100644
--- a/target/arm/cpu-models.c
+++ b/target/arm/cpu-models.c
@@ -39,7 +39,82 @@
/* Maximum parent-chain depth for named CPU models. */
#define ARM_NAMED_CPU_MODEL_MAX_DEPTH 16
+/* Arm-v9.0-a mandatory features. */
+static const ArmModelPropValue arm_v9_0_a_v1_props[] = {
+ /* ID_AA64PFR0_EL1 */
+ MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_EL0", NUM, 1), /* only FEAT_AA64EL0
(Armv9.0) */
+ MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_EL1", NUM, 1), /* only FEAT_AA64EL1
(Armv9.0) */
+ MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_RAS", NUM, 1), /* FEAT_RAS (Armv8.2) */
+ MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_DIT", NUM, 1), /* FEAT_DIT (Armv8.4) */
+ MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_CSV2", NUM, 1), /* FEAT_CSV2 (Armv8.5)
*/
+ MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_CSV3", NUM, 1), /* FEAT_CSV3 (Armv8.5)
*/
+ MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_FP", NUM, 1), /* FEAT_FP16 */
+ MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_AdvSIMD", NUM, 1), /* FEAT_FP16 */
+
+ /* ID_AA64PFR1_EL1 */
+ /* KVM zeroes out these field when MTE is not enabled. */
+ MODEL_PROP("SYSREG_ID_AA64PFR1_EL1_MTE_frac", NUM, 0),
+ MODEL_PROP("SYSREG_ID_AA64PFR1_EL1_BT", NUM, 1), /* FEAT_BTI (Armv8.5) */
+
+ /* ID_AA64MMFR0_EL1 */
+ MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran64", NUM, 0xF), /* not mandatory
*/
+ MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran4", NUM, 0), /* 4K granular
support */
+ MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran16_2", NUM, 1), /* not mandatory
*/
+ MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran64_2", NUM, 1), /* not mandatory
*/
+ MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran4_2", NUM, 1), /* not mandatory */
+
+ /* ID_AA64DFR0_EL1 */
+ MODEL_PROP("SYSREG_ID_AA64DFR0_EL1_DebugVer", NUM, 9), /* FEAT_Debugv8p4
(Armv8.4) */
+ MODEL_PROP("SYSREG_ID_AA64DFR0_EL1_DoubleLock", NUM, 0xF), /* not
implemented */
+ /* no PMU for named models */
+ MODEL_PROP("SYSREG_ID_AA64DFR0_EL1_PMUVer", NUM, 0),
+
+ /* CTR_EL0 */
+ MODEL_PROP("SYSREG_CTR_EL0_L1Ip", NUM, 2), /* FEAT_IVIPT: VIPT cache impl.
*/
+
+ /* ID_AA64MMFR4_EL1 */
+ MODEL_PROP("SYSREG_ID_AA64MMFR4_EL1_E2H0", NUM, 0xF), /* FEAT_E2H0 not
mandatory */
+
+ /* ID_AA64ISAR0_EL1 */
+ MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_CRC32", NUM, 1), /* FEAT_CRC32
(Armv8.1) */
+ MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_Atomic", NUM, 2), /* FEAT_LSE
(Armv8.1) */
+ MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_TS", NUM, 2), /* FEAT_FlagM2 (Armv9.0
& FP) */
+ MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_TLB", NUM, 2), /* FEAT_TLBIRANGE
(Armv8.4) */
+ MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_RDM", NUM, 1), /* FEAT_RDM (Armv9.0 &
FP) */
+ MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_DP", NUM, 1), /* FEAT_DotProd (Armv9.0
& FP) */
+ MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_FHM", NUM, 1), /* FEAT_FHM (Armv9.0 &
FP) */
+
+ /* ID_AA64ISAR1_EL1 */
+ MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_LRCPC", NUM, 2), /* FEAT_LRCPC2
(Armv8.4) */
+ MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_FRINTTS", NUM, 1), /* FEAT_FRINTTS
(v9.0 & FP) */
+ MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_FCMA", NUM, 1), /* FEAT_FCMA (Armv9.0
& FP) */
+ MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_JSCVT", NUM, 1), /* FEAT_JSCVT
(Armv9.0 & FP) */
+ MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_DPB", NUM, 2), /* FEAT_DPB2 (Armv8.5)
*/
+ MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_SB", NUM, 1), /* FEAT_SB (Armv8.5) */
+ MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_SPECRES", NUM, 1), /* FEAT_SPECRES
(Armv8.5) */
+ /*
+ * FEAT_PAuth is mandated by Armv8.3 but is excluded here as reference
+ * core can choose to implement any PAuth algorithm (APA/API/APA3).
+ */
+
+ /* ID_AA64MMFR1_EL1 */
+ MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_HPDS", NUM, 1), /* FEAT_HPDS (Armv8.1)
*/
+ MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_LO", NUM, 1), /* FEAT_LOR (Armv8.1) */
+ MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_PAN", NUM, 2), /* FEAT_PAN2 (Armv8.2)
*/
+
+ /* ID_AA64MMFR2_EL1 */
+ MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_UAO", NUM, 1), /* FEAT_UAO (Armv8.2) */
+ MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_CnP", NUM, 1), /* FEAT_TTCNP (Armv8.2)
*/
+ MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_TTL", NUM, 1), /* FEAT_TTL (Armv8.4) */
+ MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_AT", NUM, 1), /* FEAT_LSE2 (Armv8.4) */
+ MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_IDS", NUM, 1), /* FEAT_IDST (Armv8.4)
*/
+ MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_E0PD", NUM, 1), /* FEAT_E0PD (Armv8.5)
*/
+
+ MODEL_PROP_END,
+};
+
static const ArmNamedCpuModel arm_cpu_models[] = {
+ {"arm-v9.0-a-v1", NULL, arm_v9_0_a_v1_props},
{NULL, NULL, NULL}
};
--
2.52.0