#include "kvm_arm.h"
#include "qapi/visitor.h"
-static inline void set_feature(CPUARMState *env, int feature)
-{
- env->features |= 1ULL << feature;
-}
-
-static inline void unset_feature(CPUARMState *env, int feature)
-{
- env->features &= ~(1ULL << feature);
-}
-
#ifndef CONFIG_USER_ONLY
static uint64_t a57_a53_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
cpu->dtb_compatible = "arm,cortex-a57";
set_feature(&cpu->env, ARM_FEATURE_V8);
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
set_feature(&cpu->env, ARM_FEATURE_NEON);
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
cpu->id_pfr1 = 0x00011011;
cpu->isar.id_dfr0 = 0x03010066;
cpu->id_afr0 = 0x00000000;
- cpu->id_mmfr0 = 0x10101105;
- cpu->id_mmfr1 = 0x40000000;
- cpu->id_mmfr2 = 0x01260000;
- cpu->id_mmfr3 = 0x02102211;
+ cpu->isar.id_mmfr0 = 0x10101105;
+ cpu->isar.id_mmfr1 = 0x40000000;
+ cpu->isar.id_mmfr2 = 0x01260000;
+ cpu->isar.id_mmfr3 = 0x02102211;
cpu->isar.id_isar0 = 0x02101110;
cpu->isar.id_isar1 = 0x13112111;
cpu->isar.id_isar2 = 0x21232042;
cpu->isar.id_isar5 = 0x00011121;
cpu->isar.id_isar6 = 0;
cpu->isar.id_aa64pfr0 = 0x00002222;
- cpu->id_aa64dfr0 = 0x10305106;
+ cpu->isar.id_aa64dfr0 = 0x10305106;
cpu->isar.id_aa64isar0 = 0x00011120;
cpu->isar.id_aa64mmfr0 = 0x00001124;
- cpu->dbgdidr = 0x3516d000;
+ cpu->isar.dbgdidr = 0x3516d000;
cpu->clidr = 0x0a200023;
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
cpu->dtb_compatible = "arm,cortex-a53";
set_feature(&cpu->env, ARM_FEATURE_V8);
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
set_feature(&cpu->env, ARM_FEATURE_NEON);
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
cpu->id_pfr1 = 0x00011011;
cpu->isar.id_dfr0 = 0x03010066;
cpu->id_afr0 = 0x00000000;
- cpu->id_mmfr0 = 0x10101105;
- cpu->id_mmfr1 = 0x40000000;
- cpu->id_mmfr2 = 0x01260000;
- cpu->id_mmfr3 = 0x02102211;
+ cpu->isar.id_mmfr0 = 0x10101105;
+ cpu->isar.id_mmfr1 = 0x40000000;
+ cpu->isar.id_mmfr2 = 0x01260000;
+ cpu->isar.id_mmfr3 = 0x02102211;
cpu->isar.id_isar0 = 0x02101110;
cpu->isar.id_isar1 = 0x13112111;
cpu->isar.id_isar2 = 0x21232042;
cpu->isar.id_isar5 = 0x00011121;
cpu->isar.id_isar6 = 0;
cpu->isar.id_aa64pfr0 = 0x00002222;
- cpu->id_aa64dfr0 = 0x10305106;
+ cpu->isar.id_aa64dfr0 = 0x10305106;
cpu->isar.id_aa64isar0 = 0x00011120;
cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
- cpu->dbgdidr = 0x3516d000;
+ cpu->isar.dbgdidr = 0x3516d000;
cpu->clidr = 0x0a200023;
cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
cpu->dtb_compatible = "arm,cortex-a72";
set_feature(&cpu->env, ARM_FEATURE_V8);
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
set_feature(&cpu->env, ARM_FEATURE_NEON);
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
cpu->id_pfr1 = 0x00011011;
cpu->isar.id_dfr0 = 0x03010066;
cpu->id_afr0 = 0x00000000;
- cpu->id_mmfr0 = 0x10201105;
- cpu->id_mmfr1 = 0x40000000;
- cpu->id_mmfr2 = 0x01260000;
- cpu->id_mmfr3 = 0x02102211;
+ cpu->isar.id_mmfr0 = 0x10201105;
+ cpu->isar.id_mmfr1 = 0x40000000;
+ cpu->isar.id_mmfr2 = 0x01260000;
+ cpu->isar.id_mmfr3 = 0x02102211;
cpu->isar.id_isar0 = 0x02101110;
cpu->isar.id_isar1 = 0x13112111;
cpu->isar.id_isar2 = 0x21232042;
cpu->isar.id_isar4 = 0x00011142;
cpu->isar.id_isar5 = 0x00011121;
cpu->isar.id_aa64pfr0 = 0x00002222;
- cpu->id_aa64dfr0 = 0x10305106;
+ cpu->isar.id_aa64dfr0 = 0x10305106;
cpu->isar.id_aa64isar0 = 0x00011120;
cpu->isar.id_aa64mmfr0 = 0x00001124;
- cpu->dbgdidr = 0x3516d000;
+ cpu->isar.dbgdidr = 0x3516d000;
cpu->clidr = 0x0a200023;
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
/* Collect the set of vector lengths supported by KVM. */
bitmap_zero(kvm_supported, ARM_MAX_VQ);
- if (kvm_enabled() && kvm_arm_sve_supported(CPU(cpu))) {
+ if (kvm_enabled() && kvm_arm_sve_supported()) {
kvm_arm_sve_get_vls(CPU(cpu), kvm_supported);
} else if (kvm_enabled()) {
assert(!cpu_isar_feature(aa64_sve, cpu));
void *opaque, Error **errp)
{
ARMCPU *cpu = ARM_CPU(obj);
- Error *err = NULL;
uint32_t max_vq;
- visit_type_uint32(v, name, &max_vq, &err);
- if (err) {
- error_propagate(errp, err);
+ if (!visit_type_uint32(v, name, &max_vq, errp)) {
return;
}
- if (kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
+ if (kvm_enabled() && !kvm_arm_sve_supported()) {
error_setg(errp, "cannot set sve-max-vq");
error_append_hint(errp, "SVE not supported by KVM on this host\n");
return;
{
ARMCPU *cpu = ARM_CPU(obj);
uint32_t vq = atoi(&name[3]) / 128;
- Error *err = NULL;
bool value;
- visit_type_bool(v, name, &value, &err);
- if (err) {
- error_propagate(errp, err);
+ if (!visit_type_bool(v, name, &value, errp)) {
return;
}
- if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
+ if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
error_setg(errp, "cannot enable %s", name);
error_append_hint(errp, "SVE not supported by KVM on this host\n");
return;
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);
+ if (!visit_type_bool(v, name, &value, errp)) {
return;
}
- if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
+ if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
error_setg(errp, "'sve' feature not supported by KVM on this host");
return;
}
uint32_t vq;
object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
- cpu_arm_set_sve, NULL, NULL, &error_fatal);
+ cpu_arm_set_sve, NULL, NULL);
for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
char name[8];
sprintf(name, "sve%d", vq * 128);
object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
- cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
+ cpu_arm_set_sve_vq, NULL, NULL);
}
}
if (kvm_enabled()) {
kvm_arm_set_cpu_features_from_host(cpu);
- kvm_arm_add_vcpu_properties(obj);
} else {
uint64_t t;
uint32_t u;
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
+ t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* ARMv8.4-RCPC */
cpu->isar.id_aa64isar1 = t;
t = cpu->isar.id_aa64pfr0;
t = cpu->isar.id_aa64pfr1;
t = FIELD_DP64(t, ID_AA64PFR1, BT, 1);
+ /*
+ * Begin with full support for MTE; will be downgraded to MTE=1
+ * during realize if the board provides no tag memory.
+ */
+ t = FIELD_DP64(t, ID_AA64PFR1, MTE, 2);
cpu->isar.id_aa64pfr1 = t;
t = cpu->isar.id_aa64mmfr1;
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */
+ t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */
cpu->isar.id_aa64mmfr1 = t;
t = cpu->isar.id_aa64mmfr2;
t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
+ t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */
cpu->isar.id_aa64mmfr2 = t;
/* Replicate the same data to the 32-bit id registers. */
u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
cpu->isar.id_isar6 = u;
- u = cpu->id_mmfr3;
+ u = cpu->isar.id_mmfr3;
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
- cpu->id_mmfr3 = u;
+ cpu->isar.id_mmfr3 = u;
+
+ u = cpu->isar.id_mmfr4;
+ u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
+ u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
+ u = FIELD_DP32(u, ID_MMFR4, CNP, 1); /* TTCNP */
+ u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
+ cpu->isar.id_mmfr4 = u;
+
+ t = cpu->isar.id_aa64dfr0;
+ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
+ cpu->isar.id_aa64dfr0 = t;
+
+ u = cpu->isar.id_dfr0;
+ u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
+ cpu->isar.id_dfr0 = u;
/*
* FIXME: We do not yet support ARMv8.2-fp16 for AArch32 yet,
aarch64_add_sve_properties(obj);
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
- cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
+ cpu_max_set_sve_max_vq, NULL, NULL);
}
-struct ARMCPUInfo {
- const char *name;
- void (*initfn)(Object *obj);
- void (*class_init)(ObjectClass *oc, void *data);
-};
-
static const ARMCPUInfo aarch64_cpus[] = {
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
{ .name = "max", .initfn = aarch64_max_initfn },
- { .name = NULL }
};
static bool aarch64_cpu_get_aarch64(Object *obj, Error **errp)
* uniform execution state like do_interrupt.
*/
if (value == false) {
- if (!kvm_enabled() || !kvm_arm_aarch32_supported(CPU(cpu))) {
+ if (!kvm_enabled() || !kvm_arm_aarch32_supported()) {
error_setg(errp, "'aarch64' feature cannot be disabled "
"unless KVM is enabled and 32-bit EL1 "
"is supported");
static void aarch64_cpu_initfn(Object *obj)
{
object_property_add_bool(obj, "aarch64", aarch64_cpu_get_aarch64,
- aarch64_cpu_set_aarch64, NULL);
+ aarch64_cpu_set_aarch64);
object_property_set_description(obj, "aarch64",
"Set on/off to enable/disable aarch64 "
- "execution state ",
- NULL);
+ "execution state ");
}
static void aarch64_cpu_finalizefn(Object *obj)
acc->info = data;
}
-static void aarch64_cpu_register(const ARMCPUInfo *info)
+void aarch64_cpu_register(const ARMCPUInfo *info)
{
TypeInfo type_info = {
.parent = TYPE_AARCH64_CPU,
static void aarch64_cpu_register_types(void)
{
- const ARMCPUInfo *info = aarch64_cpus;
+ size_t i;
type_register_static(&aarch64_cpu_type_info);
- while (info->name) {
- aarch64_cpu_register(info);
- info++;
+ for (i = 0; i < ARRAY_SIZE(aarch64_cpus); ++i) {
+ aarch64_cpu_register(&aarch64_cpus[i]);
}
}