diff --git a/target/arm/cpu.c b/target/arm/cpu.c index af879d5311..376db154f0 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -769,6 +769,9 @@ static Property arm_cpu_has_vfp_property = static Property arm_cpu_has_neon_property = DEFINE_PROP_BOOL("neon", ARMCPU, has_neon, true); +static Property arm_cpu_has_dsp_property = + DEFINE_PROP_BOOL("dsp", ARMCPU, has_dsp, true); + static Property arm_cpu_has_mpu_property = DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true); @@ -881,6 +884,12 @@ void arm_cpu_post_init(Object *obj) } } + if (arm_feature(&cpu->env, ARM_FEATURE_M) && + arm_feature(&cpu->env, ARM_FEATURE_THUMB_DSP)) { + qdev_property_add_static(DEVICE(obj), &arm_cpu_has_dsp_property, + &error_abort); + } + if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) { qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property, &error_abort); @@ -1100,6 +1109,26 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) cpu->isar.mvfr0 = u; } + if (arm_feature(env, ARM_FEATURE_M) && !cpu->has_dsp) { + uint32_t u; + + unset_feature(env, ARM_FEATURE_THUMB_DSP); + + u = cpu->isar.id_isar1; + u = FIELD_DP32(u, ID_ISAR1, EXTEND, 1); + cpu->isar.id_isar1 = u; + + u = cpu->isar.id_isar2; + u = FIELD_DP32(u, ID_ISAR2, MULTU, 1); + u = FIELD_DP32(u, ID_ISAR2, MULTS, 1); + cpu->isar.id_isar2 = u; + + u = cpu->isar.id_isar3; + u = FIELD_DP32(u, ID_ISAR3, SIMD, 1); + u = FIELD_DP32(u, ID_ISAR3, SATURATE, 0); + cpu->isar.id_isar3 = u; + } + /* Some features automatically imply others: */ if (arm_feature(env, ARM_FEATURE_V8)) { if (arm_feature(env, ARM_FEATURE_M)) { diff --git a/target/arm/cpu.h b/target/arm/cpu.h index cf2496aeee..a98c45b1ff 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -790,6 +790,8 @@ struct ARMCPU { bool has_vfp; /* CPU has Neon */ bool has_neon; + /* CPU has M-profile DSP extension */ + bool has_dsp; /* CPU has memory protection unit */ bool has_mpu;