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 grace-v1 named model hierarchy is: kvm-base-v1 KVM-imposed quirks (chain root) arm-v8_4-a-v1 ARMv8.4-A architectural mandate arm-v9_0-a-v1 ARMv9.0-A architectural deltas neoverse-v2-v1 Neoverse V2 grace-v1 NVIDIA Grace arm-v8_4-a-v1, arm-v9_0-a-v1: Only features mandated by the corresponding ARM ARM revision. No optional features. neoverse-v[12]-v1: Referrence manual derived feature values for the reference core. Values differ from reference core values based on what was exposed to the guest with -cpu host. grace-v1: SoC integration choices (crypto pin, cache hints, PAuth alg). model realization logic: 1. arm_idregs_reset_to_defaults(cpu): Reset cpu->isar.idregs[] to the default values. 2. Add all properties to the CPU Object 3. arm_realize_model_chain(obj, model, &error_abort): Walk the parent chain from root first and apply all the properties. Co-authored-by: Khushit Shah <[email protected]> Signed-off-by: Shaju Abraham <[email protected]> --- hw/arm/virt.c | 8 ++ target/arm/arm-cpu-models.c | 214 ++++++++++++++++++++++++++++++++ target/arm/arm-cpu-models.h | 43 +++++++ target/arm/arm-v8_4-a-v1.inc.h | 22 ++++ target/arm/arm-v9_0-a-v1.inc.h | 28 +++++ target/arm/grace-v1.inc.h | 17 +++ target/arm/graviton3-v1.inc.h | 16 +++ target/arm/kvm-base-v1.inc.h | 13 ++ target/arm/meson.build | 5 +- target/arm/neoverse-v1-v1.inc.h | 64 ++++++++++ target/arm/neoverse-v2-v1.inc.h | 64 ++++++++++ 11 files changed, 493 insertions(+), 1 deletion(-) create mode 100644 target/arm/arm-cpu-models.c create mode 100644 target/arm/arm-cpu-models.h create mode 100644 target/arm/arm-v8_4-a-v1.inc.h create mode 100644 target/arm/arm-v9_0-a-v1.inc.h create mode 100644 target/arm/grace-v1.inc.h create mode 100644 target/arm/graviton3-v1.inc.h create mode 100644 target/arm/kvm-base-v1.inc.h create mode 100644 target/arm/neoverse-v1-v1.inc.h create mode 100644 target/arm/neoverse-v2-v1.inc.h diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 10b1954382..bbb5f0a241 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -4069,6 +4069,14 @@ 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("arm-v9_0-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("neoverse-v2-v1"))); + g_ptr_array_add(vct, g_strdup(ARM_CPU_TYPE_NAME("grace-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..fff7522a64 --- /dev/null +++ b/target/arm/arm-cpu-models.c @@ -0,0 +1,214 @@ +/* + * ARM named CPU model definitions. + * + * Each model is defined in its own .inc.h file using the ARM_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 (single-parent inheritance): + * + * kvm-base-v1 KVM-imposed quirks (chain root) + * arm-v8_4-a-v1 ARMv8.4-A architectural mandate + * arm-v9_0-a-v1 ARMv9.0-A architectural deltas + * neoverse-v2-v1 Neoverse V2 (TRM 102375) + * grace-v1 NVIDIA Grace + * 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 "arm-cpu-props.h" +#include "cpu-idregs.h" + +static const ArmModelPropValue kvm_base_v1_props[] = { +#include "kvm-base-v1.inc.h" +}; + +static const ArmModelPropValue armv8_4_a_v1_props[] = { +#include "arm-v8_4-a-v1.inc.h" +}; + +static const ArmModelPropValue armv9_0_a_v1_props[] = { +#include "arm-v9_0-a-v1.inc.h" +}; + +static const ArmModelPropValue neoverse_v1_v1_props[] = { +#include "neoverse-v1-v1.inc.h" +}; + +static const ArmModelPropValue neoverse_v2_v1_props[] = { +#include "neoverse-v2-v1.inc.h" +}; + +static const ArmModelPropValue grace_v1_props[] = { +#include "grace-v1.inc.h" +}; + +static const ArmModelPropValue graviton3_v1_props[] = { +#include "graviton3-v1.inc.h" +}; + +static const ArmNamedCpuModel arm_cpu_models[] = { + { + .name = "kvm-base-v1", + .parent = NULL, + .props = kvm_base_v1_props, + }, + { + .name = "arm-v8_4-a-v1", + .parent = "kvm-base-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, + }, + { + .name = "arm-v9_0-a-v1", + .parent = "arm-v8_4-a-v1", + .props = armv9_0_a_v1_props, + }, + { + .name = "neoverse-v2-v1", + .parent = "arm-v9_0-a-v1", + .props = neoverse_v2_v1_props, + }, + { + .name = "grace-v1", + .parent = "neoverse-v2-v1", + .props = grace_v1_props, + }, +}; + +static ARMCPUInfo arm_named_cpu_infos[ARRAY_SIZE(arm_cpu_models)]; +static 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_STR: + object_property_set_str(obj, pv->name, pv->str, errp); + break; + case ARM_MODEL_PROP_BOOL: + object_property_set_bool(obj, pv->name, pv->b, errp); + break; + case ARM_MODEL_PROP_NUM: + object_property_set_uint(obj, pv->name, pv->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; + } + + arm_idregs_reset_to_defaults(cpu); + + aarch64_add_sve_properties(obj); + aarch64_add_pauth_properties(obj); + arm_add_cpu_props(obj); + + 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..830a9bdc4a --- /dev/null +++ b/target/arm/arm-cpu-models.h @@ -0,0 +1,43 @@ +/* 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_STR, + ARM_MODEL_PROP_BOOL, + ARM_MODEL_PROP_NUM, +} ArmModelPropType; + +typedef struct ArmModelPropValue { + const char *name; + ArmModelPropType type; + bool b; + uint64_t num; + const char *str; +} ArmModelPropValue; + +typedef struct ArmNamedCpuModel { + const char *name; + const char *parent; + const ArmModelPropValue *props; +} ArmNamedCpuModel; + +#define ARM_PROP_FIELD_STR str +#define ARM_PROP_FIELD_BOOL b +#define ARM_PROP_FIELD_NUM num + +#define ARM_PROP(_name, _type, _value) \ + { .name = (_name), .type = ARM_MODEL_PROP_##_type, \ + .ARM_PROP_FIELD_##_type = (_value) } + +#define ARM_PROP_END { .name = NULL } + +void arm_register_named_cpu_models(void); + +#endif /* ARM_CPU_MODELS_H */ diff --git a/target/arm/arm-v8_4-a-v1.inc.h b/target/arm/arm-v8_4-a-v1.inc.h new file mode 100644 index 0000000000..1bad59ba2d --- /dev/null +++ b/target/arm/arm-v8_4-a-v1.inc.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +ARM_PROP("feat_CRC32", STR, "on"), +ARM_PROP("feat_ATOMIC", STR, "on"), +ARM_PROP("feat_HPDS", STR, "on"), +ARM_PROP("feat_LO", STR, "on"), + +ARM_PROP("feat_DPB", STR, "on"), +ARM_PROP("feat_RAS", STR, "1.0"), +ARM_PROP("feat_PAN", STR, "pan2"), +ARM_PROP("feat_UAO", STR, "on"), +ARM_PROP("feat_CNP", STR, "on"), +ARM_PROP("feat_IESB", STR, "on"), + +ARM_PROP("feat_DIT", STR, "on"), +ARM_PROP("feat_DBG", STR, "v8p4"), +ARM_PROP("feat_PMU", STR, "v3p4"), +ARM_PROP("feat_TS", STR, "flagm"), +ARM_PROP("feat_LRCPC", STR, "lrcpc2"), +ARM_PROP("feat_AT", STR, "on"), +ARM_PROP("hw_prop_IDS", STR, "0x18"), + +ARM_PROP_END, diff --git a/target/arm/arm-v9_0-a-v1.inc.h b/target/arm/arm-v9_0-a-v1.inc.h new file mode 100644 index 0000000000..5ebe728133 --- /dev/null +++ b/target/arm/arm-v9_0-a-v1.inc.h @@ -0,0 +1,28 @@ + +/* SPDX-License-Identifier: GPL-2.0-or-later */ +ARM_PROP("feat_BT", STR, "on"), +ARM_PROP("feat_CSV2", STR, "1.0"), +ARM_PROP("feat_CSV3", STR, "on"), +ARM_PROP("feat_DPB", STR, "dpb2"), +ARM_PROP("feat_E0PD", STR, "on"), +ARM_PROP("feat_SB", STR, "on"), +ARM_PROP("feat_SPECRES", STR, "on"), +ARM_PROP("feat_SSBS", STR, "ssbs2"), + +ARM_PROP("feat_DoubleLock", STR, "off"), +ARM_PROP("feat_FP", STR, "on"), +ARM_PROP("feat_AdvSIMD", STR, "on"), +ARM_PROP("feat_TS", STR, "flagm2"), +ARM_PROP("feat_FRINTTS", STR, "on"), +ARM_PROP("feat_RDM", STR, "on"), +ARM_PROP("feat_DP", STR, "on"), +ARM_PROP("feat_FHM", STR, "on"), +ARM_PROP("feat_FCMA", STR, "on"), +ARM_PROP("feat_JSCVT", STR, "on"), + +ARM_PROP("feat_SVE", STR, "on"), +ARM_PROP("feat_SEL2", STR, "on"), +ARM_PROP("feat_VH", STR, "on"), +ARM_PROP("feat_XNX", STR, "on"), + +ARM_PROP_END, diff --git a/target/arm/grace-v1.inc.h b/target/arm/grace-v1.inc.h new file mode 100644 index 0000000000..048ebb993d --- /dev/null +++ b/target/arm/grace-v1.inc.h @@ -0,0 +1,17 @@ + +/* SPDX-License-Identifier: GPL-2.0-or-later */ +ARM_PROP("cpu_revision", NUM, 0x0), + +ARM_PROP("feat_AES", STR, "pmull"), +ARM_PROP("feat_SHA1", STR, "on"), +ARM_PROP("feat_SHA2", STR, "sha512"), +ARM_PROP("feat_SHA3", STR, "on"), +ARM_PROP("feat_SM3", STR, "on"), +ARM_PROP("feat_SM4", STR, "on"), + +ARM_PROP("hw_prop_IDC", BOOL, true), +ARM_PROP("hw_prop_DIC", BOOL, true), + +ARM_PROP("cpu_revidr", NUM, 1), + +ARM_PROP_END, diff --git a/target/arm/graviton3-v1.inc.h b/target/arm/graviton3-v1.inc.h new file mode 100644 index 0000000000..9538c3e539 --- /dev/null +++ b/target/arm/graviton3-v1.inc.h @@ -0,0 +1,16 @@ + +/* SPDX-License-Identifier: GPL-2.0-or-later */ +ARM_PROP("feat_AES", STR, "pmull"), +ARM_PROP("feat_SHA1", STR, "on"), +ARM_PROP("feat_SHA2", STR, "sha512"), +ARM_PROP("feat_SHA3", STR, "on"), +ARM_PROP("feat_SM3", STR, "on"), +ARM_PROP("feat_SM4", STR, "on"), +ARM_PROP("feat_RNDR", STR, "on"), + +ARM_PROP("hw_prop_IDC", BOOL, true), +ARM_PROP("hw_prop_DIC", BOOL, true), + +ARM_PROP("cpu_revidr", NUM, 1), + +ARM_PROP_END, diff --git a/target/arm/kvm-base-v1.inc.h b/target/arm/kvm-base-v1.inc.h new file mode 100644 index 0000000000..e0bae90629 --- /dev/null +++ b/target/arm/kvm-base-v1.inc.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +ARM_PROP("el0_mode", STR, "aarch64"), +ARM_PROP("el1_mode", STR, "aarch64"), +ARM_PROP("el2_mode", STR, "off"), +ARM_PROP("el3_mode", STR, "off"), +ARM_PROP("feat_GIC", STR, "on"), +ARM_PROP("feat_AMU", STR, "off"), +ARM_PROP("feat_MPAM", STR, "0.0"), +ARM_PROP("feat_NV", STR, "0.0"), +ARM_PROP("feat_MTE_FRAC", STR, "async"), +ARM_PROP("hw_prop_CCIDX", STR, "32"), + +ARM_PROP_END, diff --git a/target/arm/meson.build b/target/arm/meson.build index 01b1e91a1c..79a22eec3f 100644 --- a/target/arm/meson.build +++ b/target/arm/meson.build @@ -22,7 +22,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: 'CONFIG_KVM', + if_true: files('arm-cpu-models.c', + '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')) diff --git a/target/arm/neoverse-v1-v1.inc.h b/target/arm/neoverse-v1-v1.inc.h new file mode 100644 index 0000000000..5ded208a5e --- /dev/null +++ b/target/arm/neoverse-v1-v1.inc.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +ARM_PROP("cpu_implementer", NUM, 0x41), +ARM_PROP("cpu_variant", NUM, 0x1), +ARM_PROP("cpu_architecture", NUM, 0xF), +ARM_PROP("cpu_partnum", NUM, 0xD40), +ARM_PROP("cpu_revision", NUM, 0x1), + +ARM_PROP("hw_prop_BRPS", NUM, 0x5), +ARM_PROP("hw_prop_WRPs", NUM, 0x3), +ARM_PROP("hw_prop_CTX_CMPs", NUM, 0x1), +ARM_PROP("feat_DoubleLock", STR, "off"), + +ARM_PROP("feat_RDM", STR, "on"), +ARM_PROP("feat_DP", STR, "on"), +ARM_PROP("feat_FHM", STR, "on"), + +ARM_PROP("feat_DPB", STR, "dpb2"), +ARM_PROP("feat_JSCVT", STR, "on"), +ARM_PROP("feat_FCMA", STR, "on"), +ARM_PROP("feat_BF16", STR, "on"), +ARM_PROP("feat_DGH", STR, "on"), +ARM_PROP("feat_I8MM", STR, "on"), + +ARM_PROP("feat_FP", STR, "fp16"), +ARM_PROP("feat_AdvSIMD", STR, "fp16"), +ARM_PROP("feat_RAS", STR, "1.1_base"), +ARM_PROP("feat_CSV2", STR, "1.0"), +ARM_PROP("feat_CSV3", STR, "on"), + +ARM_PROP("feat_SSBS", STR, "ssbs2"), + +ARM_PROP("hw_prop_PARANGE", STR, "48"), +ARM_PROP("hw_prop_ASIDBITS", STR, "16"), +ARM_PROP("feat_BIGEND", STR, "on"), +ARM_PROP("feat_SNSMEM", STR, "on"), +ARM_PROP("hw_prop_TGRAN4", STR, "on"), +ARM_PROP("hw_prop_TGRAN16", STR, "on"), +ARM_PROP("hw_prop_TGRAN64", STR, "on"), +ARM_PROP("hw_prop_TGRAN4_2", STR, "tgran4"), +ARM_PROP("hw_prop_TGRAN16_2", STR, "tgran16"), +ARM_PROP("hw_prop_TGRAN64_2", STR, "tgran64"), + +ARM_PROP("feat_HAFDBS", STR, "dbm"), +ARM_PROP("hw_prop_VMIDBITS", STR, "16"), +ARM_PROP("feat_VH", STR, "on"), +ARM_PROP("feat_HPDS", STR, "hpds2"), +ARM_PROP("feat_XNX", STR, "on"), +ARM_PROP("feat_SpecSEI", STR, "off"), + +ARM_PROP("hw_prop_FWB", STR, "on"), +ARM_PROP("feat_BBM", STR, "2"), +ARM_PROP("feat_EVT", STR, "ttlbxs"), + +ARM_PROP("feat_E2H0", STR, "on"), + +ARM_PROP("hw_prop_IMInline", NUM, 4), +ARM_PROP("hw_prop_L1IP", STR, "pipt"), +ARM_PROP("hw_prop_DMInline", NUM, 4), +ARM_PROP("hw_prop_ERG", NUM, 4), +ARM_PROP("hw_prop_CWG", NUM, 4), + +ARM_PROP("hw_prop_BS", NUM, 0x4), + +ARM_PROP_END, diff --git a/target/arm/neoverse-v2-v1.inc.h b/target/arm/neoverse-v2-v1.inc.h new file mode 100644 index 0000000000..a32f80cd55 --- /dev/null +++ b/target/arm/neoverse-v2-v1.inc.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +ARM_PROP("cpu_implementer", NUM, 0x41), +ARM_PROP("cpu_variant", NUM, 0x0), +ARM_PROP("cpu_architecture", NUM, 0xF), +ARM_PROP("cpu_partnum", NUM, 0xD4F), +ARM_PROP("cpu_revision", NUM, 0x2), + +ARM_PROP("hw_prop_BRPS", NUM, 0x5), +ARM_PROP("hw_prop_WRPs", NUM, 0x3), +ARM_PROP("hw_prop_CTX_CMPs", NUM, 0x1), +ARM_PROP("feat_PMU", STR, "v3p5"), + +ARM_PROP("feat_TLB", STR, "range"), + +ARM_PROP("feat_BF16", STR, "on"), +ARM_PROP("feat_DGH", STR, "on"), +ARM_PROP("feat_I8MM", STR, "on"), + +ARM_PROP("feat_FP", STR, "fp16"), +ARM_PROP("feat_AdvSIMD", STR, "fp16"), +ARM_PROP("feat_RAS", STR, "1.1_base"), + +/* + * V2 silicon may report CSV2=2 (FEAT_CSV2_2) per TRM page 392, but + * KVM clamps the guest-visible limit to 1. + */ +ARM_PROP("feat_CSV2", STR, "1.0"), + + +ARM_PROP("hw_prop_PARANGE", STR, "48"), +ARM_PROP("hw_prop_ASIDBITS", STR, "16"), +ARM_PROP("feat_BIGEND", STR, "on"), +ARM_PROP("feat_SNSMEM", STR, "on"), +ARM_PROP("hw_prop_TGRAN16", STR, "on"), +ARM_PROP("hw_prop_TGRAN64", STR, "on"), +ARM_PROP("hw_prop_TGRAN4", STR, "on"), +ARM_PROP("hw_prop_TGRAN16_2", STR, "on"), +ARM_PROP("hw_prop_TGRAN64_2", STR, "on"), +ARM_PROP("hw_prop_TGRAN4_2", STR, "on"), + +ARM_PROP("feat_HAFDBS", STR, "dbm"), +ARM_PROP("hw_prop_VMIDBITS", STR, "16"), +ARM_PROP("feat_HPDS", STR, "hpds2"), +ARM_PROP("feat_PAN", STR, "pan3"), +ARM_PROP("feat_ECBHB", STR, "off"), +ARM_PROP("feat_SpecSEI", STR, "off"), + +ARM_PROP("hw_prop_FWB", STR, "on"), +ARM_PROP("hw_prop_ST", STR, "48_47"), +ARM_PROP("feat_TTL", STR, "on"), +ARM_PROP("feat_BBM", STR, "2"), +ARM_PROP("feat_EVT", STR, "ttlbxs"), +ARM_PROP("feat_E2H0", STR, "on"), + + +ARM_PROP("hw_prop_IMInline", NUM, 4), +ARM_PROP("hw_prop_L1IP", STR, "pipt"), +ARM_PROP("hw_prop_DMInline", NUM, 4), +ARM_PROP("hw_prop_ERG", NUM, 4), +ARM_PROP("hw_prop_CWG", NUM, 4), + +ARM_PROP("hw_prop_BS", NUM, 0x4), + +ARM_PROP_END, -- 2.52.0
