Commit 73234775 authored by Andrew Jones's avatar Andrew Jones Committed by Peter Maydell
Browse files

target/arm: Allow SVE to be disabled via a CPU property



Since 97a28b0e ("target/arm: Allow VFP and Neon to be disabled via
a CPU property") we can disable the 'max' cpu model's VFP and neon
features, but there's no way to disable SVE. Add the 'sve=on|off'
property to give it that flexibility. We also rename
cpu_max_get/set_sve_vq to cpu_max_get/set_sve_max_vq in order for them
to follow the typical *_get/set_<property-name> pattern.

Signed-off-by: default avatarAndrew Jones <drjones@redhat.com>
Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Reviewed-by: default avatarEric Auger <eric.auger@redhat.com>
Tested-by: default avatarMasayoshi Mizuma <m.mizuma@jp.fujitsu.com>
Reviewed-by: default avatarBeata Michalska <beata.michalska@linaro.org>
Message-id: 20191031142734.8590-4-drjones@redhat.com
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent bd31b751
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -200,7 +200,8 @@ static void arm_cpu_reset(CPUState *s)
        env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
        env->cp15.cptr_el[3] |= CPTR_EZ;
        /* with maximum vector length */
        env->vfp.zcr_el[1] = cpu->sve_max_vq - 1;
        env->vfp.zcr_el[1] = cpu_isar_feature(aa64_sve, cpu) ?
                             cpu->sve_max_vq - 1 : 0;
        env->vfp.zcr_el[2] = env->vfp.zcr_el[1];
        env->vfp.zcr_el[3] = env->vfp.zcr_el[1];
        /*
+45 −7
Original line number Diff line number Diff line
@@ -256,14 +256,22 @@ static void aarch64_a72_initfn(Object *obj)
    define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
}

static void cpu_max_get_sve_vq(Object *obj, Visitor *v, const char *name,
static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name,
                                   void *opaque, Error **errp)
{
    ARMCPU *cpu = ARM_CPU(obj);
    visit_type_uint32(v, name, &cpu->sve_max_vq, errp);
    uint32_t value;

    /* All vector lengths are disabled when SVE is off. */
    if (!cpu_isar_feature(aa64_sve, cpu)) {
        value = 0;
    } else {
        value = cpu->sve_max_vq;
    }
    visit_type_uint32(v, name, &value, errp);
}

static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name,
static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
                                   void *opaque, Error **errp)
{
    ARMCPU *cpu = ARM_CPU(obj);
@@ -279,6 +287,34 @@ static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name,
    error_propagate(errp, err);
}

static void cpu_arm_get_sve(Object *obj, Visitor *v, const char *name,
                            void *opaque, Error **errp)
{
    ARMCPU *cpu = ARM_CPU(obj);
    bool value = cpu_isar_feature(aa64_sve, cpu);

    visit_type_bool(v, name, &value, errp);
}

static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
                            void *opaque, Error **errp)
{
    ARMCPU *cpu = ARM_CPU(obj);
    Error *err = NULL;
    bool value;
    uint64_t t;

    visit_type_bool(v, name, &value, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    t = cpu->isar.id_aa64pfr0;
    t = FIELD_DP64(t, ID_AA64PFR0, SVE, value);
    cpu->isar.id_aa64pfr0 = t;
}

/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
 * otherwise, a CPU with as many features enabled as our emulation supports.
 * The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
@@ -391,8 +427,10 @@ static void aarch64_max_initfn(Object *obj)
#endif

        cpu->sve_max_vq = ARM_MAX_VQ;
        object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_vq,
                            cpu_max_set_sve_vq, NULL, NULL, &error_fatal);
        object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
                            cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
        object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
                            cpu_arm_set_sve, NULL, NULL, &error_fatal);
    }
}

+1 −1
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
 * then the order that considers those dependencies must be used.
 */
static const char *cpu_model_advertised_features[] = {
    "aarch64", "pmu",
    "aarch64", "pmu", "sve",
    NULL
};

+1 −0
Original line number Diff line number Diff line
@@ -197,6 +197,7 @@ static void test_query_cpu_model_expansion(const void *data)

    if (g_str_equal(qtest_get_arch(), "aarch64")) {
        assert_has_feature(qts, "max", "aarch64");
        assert_has_feature(qts, "max", "sve");
        assert_has_feature(qts, "cortex-a57", "pmu");
        assert_has_feature(qts, "cortex-a57", "aarch64");