On 8/5/26 1:35 PM, Khushit Shah wrote:
>
>> On 26 Jul 2026, at 7:04 PM, Eric Auger <[email protected]> wrote:
>>
>> !-------------------------------------------------------------------|
>>  CAUTION: External Email
>>
>> |-------------------------------------------------------------------!
>>
>> Hi Khushit,
>>
>> On 7/16/26 11:38 PM, Khushit Shah wrote:
>>> From: Shaju Abraham <[email protected]>
>>>
>>> Introduce a small named-CPU-model layer on top of the field-backed
>>> property infrastructure. Each model is a flat table of (name, value)
>>> overrides and a parent pointer. At instance-init, the parent chain is
>>> walked root-first and every level's properties are applied via QOM,
>>> so a child entry overrides its ancestors for the same name.
>>>
>>> For example, the graviton3-v1 named model hierarchy is:
>>> non-zero-defaults-v1    Known non-zero default ID regs field values
>>>  arm-v8_4-a-v1       ARMv8.4-A architectural mandate
>>>    neoverse-v1-v1    Neoverse V1
>>>      graviton3-v1    AWS Graviton3
>>>
>>> non-zero-defaults-v1:
>>>   Field that should be populated with some non zero value by default.
>> following which specification? This is not clear to me. Is that layer
>> really meaningful? Shouldn't we start with the next one?
> Okay, makes sense. We can get rid of this layer.
>
>>> arm-v8_4-a-v1:
>>>  Only features mandated by the ARM ARM.
>>>
>>> neoverse-v1-v1:
>>>  Reference manual derived feature values for the reference core.
>>>  Values differ from TRM values based on what was exposed to the guest
>>>  with -cpu host.
>>>
>>> graviton3-v1:
>>>  SoC integration choices (crypto pin, cache hints, PAuth alg).
>>>
>>> The model values are figured out from ID register dump visible to
>>> QEMU with -cpu host on Graviton3 machine.
>>>
>>> Model realization:
>>> 1. Zero out ID regs array.
>>> 2. Add all properties to the CPU Object
>>> 3. arm_realize_model_chain: Walk the parent chain from root first and
>>>                            apply all the properties.
>>>
>>> Co-authored-by: Shaju Abraham <[email protected]>
>>> Signed-off-by: Khushit Shah <[email protected]>
>>> ---
>>> hw/arm/virt.c               |   5 +
>>> target/arm/arm-cpu-models.c | 336 ++++++++++++++++++++++++++++++++++++
>>> target/arm/arm-cpu-models.h |  35 ++++
>>> target/arm/meson.build      |   7 +-
>>> 4 files changed, 381 insertions(+), 2 deletions(-)
>>> create mode 100644 target/arm/arm-cpu-models.c
>>> create mode 100644 target/arm/arm-cpu-models.h
>>>
>>> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
>>> index fe19030886..34e56dc1f1 100644
>>> --- a/hw/arm/virt.c
>>> +++ b/hw/arm/virt.c
>>> @@ -3812,6 +3812,11 @@ static GPtrArray *virt_get_valid_cpu_types(const 
>>> MachineState *ms)
>>>             g_ptr_array_add(vct, g_strdup(ARM_CPU_TYPE_NAME("host")));
>>>         }
>>>     }
>>> +    if (kvm_enabled() && target_aarch64()) {
>>> +        g_ptr_array_add(vct, g_strdup(ARM_CPU_TYPE_NAME("arm-v8_4-a-v1")));
>>> +        g_ptr_array_add(vct, 
>>> g_strdup(ARM_CPU_TYPE_NAME("neoverse-v1-v1")));
>>> +        g_ptr_array_add(vct, g_strdup(ARM_CPU_TYPE_NAME("graviton3-v1")));
>>> +    }
>>>     g_ptr_array_add(vct, g_strdup(ARM_CPU_TYPE_NAME("max"))); return vct; 
>>> diff --git a/target/arm/arm-cpu-models.c
>>> b/target/arm/arm-cpu-models.c new file mode 100644 index
>>> 0000000000..747e0df010 --- /dev/null +++ b/target/arm/arm-cpu-models.c
>>> @@ -0,0 +1,336 @@ +/* + * ARM named CPU model definitions. + * + *
>>> Each model is defined as an array of MODEL_PROP macro, listing only +
>>> * the properties that DIFFER from the parent model. + * + * At
>>> realisation the parent chain is walked root-first and + * every
>>> level's props are applied via QOM, so the leaf's values + * naturally
>>> override its ancestors. + * + * Hierarchy: + * + *
>>> non-zero-defaults-v1 Known non-zero default ID reg field values + *
>>> arm-v8_4-a-v1 ARMv8.4-A architectural mandate + * neoverse-v1-v1
>>> Neoverse V1 (TRM 102649) + * graviton3-v1 AWS Graviton3 + * + *
>>> SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h"
>>> +#include "qapi/error.h"
>>> +#include "qemu/error-report.h"
>>> +#include "system/kvm.h"
>>> +#include "cpu.h"
>>> +#include "internals.h"
>>> +#include "kvm_arm.h"
>>> +#include "arm-cpu-models.h"
>>> +#include "cpu-idregs.h"
>>> +
>>> +#define MODEL_PROP_FIELD_STR  str
>>> +#define MODEL_PROP_FIELD_BOOL b
>>> +#define MODEL_PROP_FIELD_NUM  num
>>> +
>>> +#define MODEL_PROP(_name, _type, _value) \
>>> +    { .name = (_name), .type = ARM_MODEL_PROP_##_type, \
>>> +      .u.MODEL_PROP_FIELD_##_type = (_value) }
>>> +
>>> +#define MODEL_PROP_END  { .name = NULL }
>> Regarding settings somehow we end up with something that is quite
>> similar to TCG CPU
>> definitions like in
>> aarch64_neoverse_n1_initfn(). To me this is in general more readable
>> because we use name fields instead of putting the full reg value.
>> This does not prevent us from adding comments along settings to make
>> this more readable and explicit.
> Can you please specify further on what types of comments?
> Like what does each property value means?
yes, something alike what is done when we populate acpi table fields
>
>>> +
>>> +/*
>>> + * These fields should be populated with some non-zero default values.
>>> + */
>>> +static const ArmModelPropValue non_zero_defaults_v1_props[] = {
>>> +    /* ID_AA64PFR0_EL1 */
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_EL0", NUM, 0b0001),
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_EL1", NUM, 0b0001),
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_FP", NUM, 0b1111),
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_AdvSIMD", NUM, 0b1111),
>>> +
>>> +    /* ID_AA64PFR1_EL1 */
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR1_EL1_MTE_frac", NUM, 0b1111),
>> so I still believe we want a wrapper that transparently either sets a
>> prop if the field happens to be writable or simply performs checks
>> against the host if the prop is not available.
> Can’t we do that easily afterwards once the ID reg view is finalised?
> Doing it here means all the qmp paths which do not intend to actually
> create any vCPUs will error out here, which is undesirable.
sorry but I don't catch
>
>>> +
>>> +    /* ID_AA64MMFR0_EL1 */
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran64", NUM, 0b1111),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran4", NUM, 0b1111),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran16_2", NUM, 0b0001),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran64_2", NUM, 0b0001),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran4_2", NUM, 0b0001),
>>> +
>>> +    /* ID_AA64DFR0_EL1 */
>>> +    MODEL_PROP("SYSREG_ID_AA64DFR0_EL1_DebugVer", NUM, 0x6),
>>> +    MODEL_PROP("SYSREG_ID_AA64DFR0_EL1_DoubleLock", NUM, 0b1111),
>>> +
>>> +    /* CTR_EL0 */
>>> +    MODEL_PROP("SYSREG_CTR_EL0_L1Ip", NUM, 0b10),
>>> +    MODEL_PROP("SYSREG_CTR_EL0_RES1_31", NUM, 1),
>>> +
>>> +    /* ID_AA64MMFR4_EL1 */
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR4_EL1_E2H0", NUM, 0b1111),
>>> +
>>> +    MODEL_PROP_END,
>>> +};
>> To ease the review I would suggest to put a dump of all id regs of a
>> leaf model in the commit description. It is less error prone that
>> understanding the various overrides.
>> I would suggest to have separate patches for each model too.
> Ack to both. Will do this in v4.
>
>> So you said a leaf model shall have explicit values for each field,
>> including non writable ones. The code does not check that. How do we
>> make sure we are not missing settings?
> I am not sure where I say that, assumption is:
> Base model starts with a zeroed IO reg view, each model in
> chain applies some settings, a child model’s setting
> overrides parents’ settings.
Ah ok I must have misunderstood then.
>
> For verification we can dump the leaf ID regs view, it
> should match with the one in the commit message as per
> your suggestion.
>>> +
>>> +static const ArmModelPropValue armv8_4_a_v1_props[] = {
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_CRC32", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_Atomic", NUM, 2),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_HPDS", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_LO", NUM, 1),
>>> +
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_DPB", NUM, 1),
>>> +
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_RAS", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR1_EL1_RAS_frac", NUM, 0),
>>> +
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_PAN", NUM, 2),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_UAO", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_CnP", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_IESB", NUM, 1),
>>> +
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_DIT", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64DFR0_EL1_DebugVer", NUM, 9),
>>> +    MODEL_PROP("SYSREG_ID_AA64DFR0_EL1_PMUVer", NUM, 5),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_TS", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_LRCPC", NUM, 2),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_AT", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_IDS", NUM, 1),
>>> +    /* KVM zeroes out these field when MTE is not enabled. */
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR1_EL1_MTE_frac", NUM, 0),
>>> +    MODEL_PROP_END,
>>> +};
>>> +
>>> +static const ArmModelPropValue neoverse_v1_v1_props[] = {
>>> +    MODEL_PROP("SYSREG_MIDR_EL1_Implementer", NUM, 0x41),
>>> +    MODEL_PROP("SYSREG_MIDR_EL1_Variant", NUM, 0x1),
>>> +    MODEL_PROP("SYSREG_MIDR_EL1_Architecture", NUM, 0xF),
>>> +    MODEL_PROP("SYSREG_MIDR_EL1_PartNum", NUM, 0xD40),
>>> +    MODEL_PROP("SYSREG_MIDR_EL1_Revision", NUM, 0x1),
>>> +
>>> +    MODEL_PROP("SYSREG_ID_AA64DFR0_EL1_BRPs", NUM, 0x5),
>>> +    MODEL_PROP("SYSREG_ID_AA64DFR0_EL1_WRPs", NUM, 0x3),
>>> +    MODEL_PROP("SYSREG_ID_AA64DFR0_EL1_CTX_CMPs", NUM, 0x1),
>>> +    MODEL_PROP("SYSREG_ID_AA64DFR0_EL1_DoubleLock", NUM, 0xF),
>>> +
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_RDM", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_DP", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_FHM", NUM, 1),
>>> +
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_DPB", NUM, 2),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_JSCVT", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_FCMA", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_BF16", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_DGH", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_I8MM", NUM, 1),
>>> +
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_FP", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_AdvSIMD", NUM, 1),
>>> +
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_RAS", NUM, 2),
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR1_EL1_RAS_frac", NUM, 0),
>>> +
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_CSV2", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR1_EL1_CSV2_frac", NUM, 0),
>>> +
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_CSV3", NUM, 1),
>>> +
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR1_EL1_SSBS", NUM, 2),
>>> +
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_PARange", NUM, 5),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_ASIDBits", NUM, 2),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_BigEnd", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_SNSMem", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran4", NUM, 0),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran16", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran64", NUM, 0),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran4_2", NUM, 0),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran16_2", NUM, 0),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR0_EL1_TGran64_2", NUM, 0),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_HAFDBS", NUM, 2),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_VMIDBits", NUM, 2),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_VH", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_HPDS", NUM, 2),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_XNX", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR1_EL1_SpecSEI", NUM, 0),
>>> +
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_FWB", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_BBM", NUM, 2),
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR2_EL1_EVT", NUM, 2),
>>> +
>>> +    MODEL_PROP("SYSREG_ID_AA64MMFR4_EL1_E2H0", NUM, 0),
>>> +
>>> +    MODEL_PROP("SYSREG_CTR_EL0_IminLine", NUM, 4),
>>> +    MODEL_PROP("SYSREG_CTR_EL0_L1Ip", NUM, 3),
>>> +    MODEL_PROP("SYSREG_CTR_EL0_DminLine", NUM, 4),
>>> +    MODEL_PROP("SYSREG_CTR_EL0_ERG", NUM, 4),
>>> +    MODEL_PROP("SYSREG_CTR_EL0_CWG", NUM, 4),
>>> +
>>> +    MODEL_PROP("SYSREG_DCZID_EL0_BS", NUM, 0x4),
>>> +
>>> +    /* pauth */
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_APA", NUM, 3),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR1_EL1_GPA", NUM, 1),
>>> +
>>> +    /* sve */
>>> +    MODEL_PROP("SYSREG_ID_AA64PFR0_EL1_SVE", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64ZFR0_EL1_BF16", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64ZFR0_EL1_I8MM", NUM, 1),
>>> +    MODEL_PROP("sve128", BOOL, true),
>>> +
>>> +    MODEL_PROP_END,
>>> +};
>>> +
>>> +static const ArmModelPropValue graviton3_v1_props[] = {
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_AES", NUM, 2),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_SHA1", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_SHA2", NUM, 2),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_SHA3", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_SM3", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_SM4", NUM, 1),
>>> +    MODEL_PROP("SYSREG_ID_AA64ISAR0_EL1_RNDR", NUM, 1),
>>> +
>>> +    MODEL_PROP("SYSREG_CTR_EL0_IDC", NUM, 1),
>>> +    MODEL_PROP("SYSREG_CTR_EL0_DIC", NUM, 1),
>>> +
>>> +    MODEL_PROP("SYSREG_REVIDR_EL1_VAL", NUM, 1),
>>> +
>>> +    MODEL_PROP_END,
>>> +};
>>> +
>>> +static const ArmNamedCpuModel arm_cpu_models[] = {
>>> +    {
>>> +        .name   = "non-zero-defaults-v1",
>>> +        .parent = NULL,
>>> +        .props  = non_zero_defaults_v1_props,
>>> +    },
>>> +    {
>>> +        .name   = "arm-v8_4-a-v1",
>>> +        .parent = "non-zero-defaults-v1",
>>> +        .props  = armv8_4_a_v1_props,
>>> +    },
>>> +    {
>>> +        .name   = "neoverse-v1-v1",
>>> +        .parent = "arm-v8_4-a-v1",
>>> +        .props  = neoverse_v1_v1_props,
>>> +    },
>>> +    {
>>> +        .name   = "graviton3-v1",
>>> +        .parent = "neoverse-v1-v1",
>>> +        .props  = graviton3_v1_props,
>>> +    },
>>> +};
>>> +
>>> +static ARMCPUInfo arm_named_cpu_infos[ARRAY_SIZE(arm_cpu_models)];
>>> +const ArmNamedCpuModel *arm_find_model(const char *name)
>>> +{
>>> +    size_t i;
>>> +    for (i = 0; i < ARRAY_SIZE(arm_cpu_models); i++) {
>>> +        if (g_str_equal(arm_cpu_models[i].name, name)) {
>>> +            return &arm_cpu_models[i];
>>> +        }
>>> +    }
>>> +    return NULL;
>>> +}
>>> +
>>> +static void arm_apply_model_props(Object *obj, const ArmModelPropValue 
>>> *props,
>>> +                                  Error **errp)
>>> +{
>>> +    const ArmModelPropValue *pv;
>>> +    ERRP_GUARD();
>>> +
>>> +    for (pv = props; pv->name; pv++) {
>>> +        switch (pv->type) {
>>> +        case ARM_MODEL_PROP_BOOL:
>>> +            object_property_set_bool(obj, pv->name, pv->u.b, errp);
>>> +            break;
>>> +        case ARM_MODEL_PROP_NUM:
>>> +            object_property_set_uint(obj, pv->name, pv->u.num, errp);
>>> +            break;
>>> +        default:
>>> +            g_assert_not_reached();
>>> +        }
>>> +        if (*errp) {
>>> +            error_prepend(errp, "property '%s': ", pv->name);
>>> +            return;
>>> +        }
>>> +    }
>>> +}
>>> +
>>> +static void arm_realize_model_chain(Object *obj, const ArmNamedCpuModel 
>>> *model,
>>> +                                    Error **errp)
>>> +{
>>> +    const ArmNamedCpuModel *cur, *parent;
>>> +    const ArmNamedCpuModel *chain[ARRAY_SIZE(arm_cpu_models)];
>>> +    size_t depth = 0;
>>> +    for (cur = model; cur; ) {
>>> +        if (depth >= ARRAY_SIZE(chain)) {
>>> +            error_setg(errp, "model '%s': parent chain too deep "
>>> +                       "(possible cycle)", model->name);
>>> +            return;
>>> +        }
>>> +        chain[depth++] = cur;
>>> +
>>> +        if (!cur->parent) {
>>> +            break;
>>> +        }
>>> +        parent = arm_find_model(cur->parent);
>>> +        if (!parent) {
>>> +            error_setg(errp, "model '%s': unknown parent '%s'",
>>> +                       cur->name, cur->parent);
>>> +            return;
>>> +        }
>>> +        cur = parent;
>>> +    }
>>> +
>>> +    while (depth--) {
>>> +        arm_apply_model_props(obj, chain[depth]->props, errp);
>>> +        if (*errp) {
>>> +            return;
>>> +        }
>>> +    }
>>> +}
>>> +
>>> +static void arm_named_cpu_initfn(Object *obj)
>>> +{
>>> +    ARMCPU *cpu = ARM_CPU(obj);
>>> +    ARMCPUClass *acc = ARM_CPU_GET_CLASS(obj);
>>> +    const ArmNamedCpuModel *model = arm_find_model(acc->info->name);
>>> +    if (!model) {
>>> +        error_report("'%s' CPU model entry not found)",
>>> +                     acc->info->name);
>>> +        return;
>>> +    }
>>> +
>>> +    if (!kvm_enabled()) {
>>> +        error_report("'%s' CPU model requires KVM (-accel kvm)",
>>> +                     acc->info->name);
>>> +        return;
>>> +    }
>>> +
>>> +    kvm_arm_set_cpu_features_from_host(cpu);
>>> +    if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
>>> +        return;
>>> +    }
>>> +
>>> +    /* 1. Reset ID regs to 0 */
>>> +    memset(cpu->isar.idregs, 0, sizeof(cpu->isar.idregs));
>>> +
>>> +    /* 2. Add sveNNNN and SYSREG_ properties */
>>> +    aarch64_add_sve_properties(obj);
>>> +    aarch64_add_idregs_properties(obj);
>>> +
>>> +    /* 3. Realize the model chain. */
>>> +    arm_realize_model_chain(obj, model, &error_abort);
>>> +}
>>> +
>>> +void arm_register_named_cpu_models(void)
>>> +{
>>> +    size_t i;
>>> +    for (i = 0; i < ARRAY_SIZE(arm_cpu_models); i++) {
>>> +        arm_named_cpu_infos[i].name = arm_cpu_models[i].name;
>>> +        arm_named_cpu_infos[i].initfn = arm_named_cpu_initfn;
>>> +        arm_cpu_register(&arm_named_cpu_infos[i]);
>>> +    }
>>> +}
>>> +
>>> +type_init(arm_register_named_cpu_models)
>>> diff --git a/target/arm/arm-cpu-models.h b/target/arm/arm-cpu-models.h
>>> new file mode 100644
>>> index 0000000000..ac4e510499
>>> --- /dev/null
>>> +++ b/target/arm/arm-cpu-models.h
>>> @@ -0,0 +1,35 @@
>>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>>> +/*
>>> + * ARM named CPU model definitions - public API.
>>> + */
>>> +#ifndef ARM_CPU_MODELS_H
>>> +#define ARM_CPU_MODELS_H
>>> +
>>> +#include "qapi/error.h"
>>> +#include "qom/object.h"
>>> +
>>> +typedef enum ArmModelPropType {
>>> +    ARM_MODEL_PROP_BOOL,
>>> +    ARM_MODEL_PROP_NUM,
>>> +} ArmModelPropType;
>>> +
>>> +typedef struct ArmModelPropValue {
>>> +    const char     *name;
>>> +    ArmModelPropType type;
>>> +    union {
>>> +        bool            b;
>>> +        uint64_t        num;
>>> +    } u;
>>> +} ArmModelPropValue;
>>> +
>>> +typedef struct ArmNamedCpuModel {
>>> +    const char              *name;
>>> +    const char              *parent;
>>> +    const ArmModelPropValue *props;
>>> +} ArmNamedCpuModel;
>>> +
>>> +void arm_register_named_cpu_models(void);
>>> +
>>> +const ArmNamedCpuModel *arm_find_model(const char *name);
>>> +
>>> +#endif /* ARM_CPU_MODELS_H */
>>> diff --git a/target/arm/meson.build b/target/arm/meson.build
>>> index 64d1ec63ab..72eed1bcc6 100644
>>> --- a/target/arm/meson.build
>>> +++ b/target/arm/meson.build
>>> @@ -10,7 +10,7 @@ arm_user_ss.add(files('gdbstub.c'))
>>>
>>> arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
>>>   'cpu64.c',
>>> -  'gdbstub64.c'
>>> +  'gdbstub64.c',
>>> ))
>>>
>>> arm_common_ss.add(files(
>>> @@ -21,7 +21,10 @@ 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: 'TARGET_AARCH64', if_true: 
>>> files('arm-cpu-models.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'))
>>>
>>> arm_user_ss.add(files('cpu.c'))
>> Thanks
>>
>> Eric
>
Thanks

Eric


Reply via email to