aboutsummaryrefslogtreecommitdiff
path: root/target/arm/cpu64.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/arm/cpu64.c')
-rw-r--r--target/arm/cpu64.c222
1 files changed, 73 insertions, 149 deletions
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 8188ede..1f34067 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -36,6 +36,28 @@
#include "cpu-features.h"
#include "cpregs.h"
+/* convert between <register>_IDX and SYS_<register> */
+#define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \
+ [NAME##_IDX] = SYS_##NAME,
+
+const uint32_t id_register_sysreg[NUM_ID_IDX] = {
+#include "cpu-sysregs.h.inc"
+};
+
+#undef DEF
+#define DEF(NAME, OP0, OP1, CRN, CRM, OP2) \
+ case SYS_##NAME: return NAME##_IDX;
+
+int get_sysreg_idx(ARMSysRegs sysreg)
+{
+ switch (sysreg) {
+#include "cpu-sysregs.h.inc"
+ }
+ g_assert_not_reached();
+}
+
+#undef DEF
+
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
{
/*
@@ -114,7 +136,7 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
* SVE is disabled and so are all vector lengths. Good.
* Disable all SVE extensions as well.
*/
- cpu->isar.id_aa64zfr0 = 0;
+ SET_IDREG(&cpu->isar, ID_AA64ZFR0, 0);
return;
}
@@ -288,16 +310,13 @@ static bool cpu_arm_get_sve(Object *obj, Error **errp)
static void cpu_arm_set_sve(Object *obj, bool value, Error **errp)
{
ARMCPU *cpu = ARM_CPU(obj);
- uint64_t t;
if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
error_setg(errp, "'sve' feature not supported by KVM on this host");
return;
}
- t = cpu->isar.id_aa64pfr0;
- t = FIELD_DP64(t, ID_AA64PFR0, SVE, value);
- cpu->isar.id_aa64pfr0 = t;
+ FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR0, SVE, value);
}
void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp)
@@ -309,7 +328,7 @@ void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp)
if (vq_map == 0) {
if (!cpu_isar_feature(aa64_sme, cpu)) {
- cpu->isar.id_aa64smfr0 = 0;
+ SET_IDREG(&cpu->isar, ID_AA64SMFR0, 0);
return;
}
@@ -348,11 +367,8 @@ static bool cpu_arm_get_sme(Object *obj, Error **errp)
static void cpu_arm_set_sme(Object *obj, bool value, Error **errp)
{
ARMCPU *cpu = ARM_CPU(obj);
- uint64_t t;
- t = cpu->isar.id_aa64pfr1;
- t = FIELD_DP64(t, ID_AA64PFR1, SME, value);
- cpu->isar.id_aa64pfr1 = t;
+ FIELD_DP64_IDREG(&cpu->isar, ID_AA64PFR1, SME, value);
}
static bool cpu_arm_get_sme_fa64(Object *obj, Error **errp)
@@ -365,11 +381,8 @@ static bool cpu_arm_get_sme_fa64(Object *obj, Error **errp)
static void cpu_arm_set_sme_fa64(Object *obj, bool value, Error **errp)
{
ARMCPU *cpu = ARM_CPU(obj);
- uint64_t t;
- t = cpu->isar.id_aa64smfr0;
- t = FIELD_DP64(t, ID_AA64SMFR0, FA64, value);
- cpu->isar.id_aa64smfr0 = t;
+ FIELD_DP64_IDREG(&cpu->isar, ID_AA64SMFR0, FA64, value);
}
#ifdef CONFIG_USER_ONLY
@@ -480,6 +493,7 @@ void aarch64_add_sme_properties(Object *obj)
void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
{
ARMPauthFeature features = cpu_isar_feature(pauth_feature, cpu);
+ ARMISARegisters *isar = &cpu->isar;
uint64_t isar1, isar2;
/*
@@ -490,13 +504,13 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
*
* Begin by disabling all fields.
*/
- isar1 = cpu->isar.id_aa64isar1;
+ isar1 = GET_IDREG(isar, ID_AA64ISAR1);
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, APA, 0);
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPA, 0);
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, API, 0);
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPI, 0);
- isar2 = cpu->isar.id_aa64isar2;
+ isar2 = GET_IDREG(isar, ID_AA64ISAR2);
isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, APA3, 0);
isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, GPA3, 0);
@@ -558,8 +572,8 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
}
}
- cpu->isar.id_aa64isar1 = isar1;
- cpu->isar.id_aa64isar2 = isar2;
+ SET_IDREG(isar, ID_AA64ISAR1, isar1);
+ SET_IDREG(isar, ID_AA64ISAR2, isar2);
}
static const Property arm_cpu_pauth_property =
@@ -606,17 +620,18 @@ void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp)
return;
}
- t = cpu->isar.id_aa64mmfr0;
+ t = GET_IDREG(&cpu->isar, ID_AA64MMFR0);
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 2); /* 16k pages w/ LPA2 */
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4, 1); /* 4k pages w/ LPA2 */
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 3); /* 16k stage2 w/ LPA2 */
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 3); /* 4k stage2 w/ LPA2 */
- cpu->isar.id_aa64mmfr0 = t;
+ SET_IDREG(&cpu->isar, ID_AA64MMFR0, t);
}
static void aarch64_a57_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a57";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -637,25 +652,25 @@ static void aarch64_a57_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50838;
- cpu->isar.id_pfr0 = 0x00000131;
- cpu->isar.id_pfr1 = 0x00011011;
- cpu->isar.id_dfr0 = 0x03010066;
+ SET_IDREG(isar, ID_PFR0, 0x00000131);
+ SET_IDREG(isar, ID_PFR1, 0x00011011);
+ SET_IDREG(isar, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000;
- 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_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00011142;
- cpu->isar.id_isar5 = 0x00011121;
- cpu->isar.id_isar6 = 0;
- cpu->isar.id_aa64pfr0 = 0x00002222;
- cpu->isar.id_aa64dfr0 = 0x10305106;
- cpu->isar.id_aa64isar0 = 0x00011120;
- cpu->isar.id_aa64mmfr0 = 0x00001124;
+ SET_IDREG(isar, ID_MMFR0, 0x10101105);
+ SET_IDREG(isar, ID_MMFR1, 0x40000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01260000);
+ SET_IDREG(isar, ID_MMFR3, 0x02102211);
+ SET_IDREG(isar, ID_ISAR0, 0x02101110);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232042);
+ SET_IDREG(isar, ID_ISAR3, 0x01112131);
+ SET_IDREG(isar, ID_ISAR4, 0x00011142);
+ SET_IDREG(isar, ID_ISAR5, 0x00011121);
+ SET_IDREG(isar, ID_ISAR6, 0);
+ SET_IDREG(isar, ID_AA64PFR0, 0x00002222);
+ SET_IDREG(isar, ID_AA64DFR0, 0x10305106);
+ SET_IDREG(isar, ID_AA64ISAR0, 0x00011120);
+ SET_IDREG(isar, ID_AA64MMFR0, 0x00001124);
cpu->isar.dbgdidr = 0x3516d000;
cpu->isar.dbgdevid = 0x01110f13;
cpu->isar.dbgdevid1 = 0x2;
@@ -678,6 +693,7 @@ static void aarch64_a57_initfn(Object *obj)
static void aarch64_a53_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+ ARMISARegisters *isar = &cpu->isar;
cpu->dtb_compatible = "arm,cortex-a53";
set_feature(&cpu->env, ARM_FEATURE_V8);
@@ -698,25 +714,25 @@ static void aarch64_a53_initfn(Object *obj)
cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x84448004; /* L1Ip = VIPT */
cpu->reset_sctlr = 0x00c50838;
- cpu->isar.id_pfr0 = 0x00000131;
- cpu->isar.id_pfr1 = 0x00011011;
- cpu->isar.id_dfr0 = 0x03010066;
+ SET_IDREG(isar, ID_PFR0, 0x00000131);
+ SET_IDREG(isar, ID_PFR1, 0x00011011);
+ SET_IDREG(isar, ID_DFR0, 0x03010066);
cpu->id_afr0 = 0x00000000;
- 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_isar3 = 0x01112131;
- cpu->isar.id_isar4 = 0x00011142;
- cpu->isar.id_isar5 = 0x00011121;
- cpu->isar.id_isar6 = 0;
- cpu->isar.id_aa64pfr0 = 0x00002222;
- cpu->isar.id_aa64dfr0 = 0x10305106;
- cpu->isar.id_aa64isar0 = 0x00011120;
- cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
+ SET_IDREG(isar, ID_MMFR0, 0x10101105);
+ SET_IDREG(isar, ID_MMFR1, 0x40000000);
+ SET_IDREG(isar, ID_MMFR2, 0x01260000);
+ SET_IDREG(isar, ID_MMFR3, 0x02102211);
+ SET_IDREG(isar, ID_ISAR0, 0x02101110);
+ SET_IDREG(isar, ID_ISAR1, 0x13112111);
+ SET_IDREG(isar, ID_ISAR2, 0x21232042);
+ SET_IDREG(isar, ID_ISAR3, 0x01112131);
+ SET_IDREG(isar, ID_ISAR4, 0x00011142);
+ SET_IDREG(isar, ID_ISAR5, 0x00011121);
+ SET_IDREG(isar, ID_ISAR6, 0);
+ SET_IDREG(isar, ID_AA64PFR0, 0x00002222);
+ SET_IDREG(isar, ID_AA64DFR0, 0x10305106);
+ SET_IDREG(isar, ID_AA64ISAR0, 0x00011120);
+ SET_IDREG(isar, ID_AA64MMFR0, 0x00001122); /* 40 bit physical addr */
cpu->isar.dbgdidr = 0x3516d000;
cpu->isar.dbgdevid = 0x00110f13;
cpu->isar.dbgdevid1 = 0x1;
@@ -781,104 +797,12 @@ static const ARMCPUInfo aarch64_cpus[] = {
#endif
};
-static bool aarch64_cpu_get_aarch64(Object *obj, Error **errp)
-{
- ARMCPU *cpu = ARM_CPU(obj);
-
- return arm_feature(&cpu->env, ARM_FEATURE_AARCH64);
-}
-
-static void aarch64_cpu_set_aarch64(Object *obj, bool value, Error **errp)
-{
- ARMCPU *cpu = ARM_CPU(obj);
-
- /* At this time, this property is only allowed if KVM is enabled. This
- * restriction allows us to avoid fixing up functionality that assumes a
- * uniform execution state like do_interrupt.
- */
- if (value == false) {
- 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");
- return;
- }
- unset_feature(&cpu->env, ARM_FEATURE_AARCH64);
- } else {
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
- }
-}
-
-static void aarch64_cpu_finalizefn(Object *obj)
-{
-}
-
-static const gchar *aarch64_gdb_arch_name(CPUState *cs)
-{
- return "aarch64";
-}
-
-static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
-{
- CPUClass *cc = CPU_CLASS(oc);
-
- cc->gdb_read_register = aarch64_cpu_gdb_read_register;
- cc->gdb_write_register = aarch64_cpu_gdb_write_register;
- cc->gdb_core_xml_file = "aarch64-core.xml";
- cc->gdb_arch_name = aarch64_gdb_arch_name;
-
- object_class_property_add_bool(oc, "aarch64", aarch64_cpu_get_aarch64,
- aarch64_cpu_set_aarch64);
- object_class_property_set_description(oc, "aarch64",
- "Set on/off to enable/disable aarch64 "
- "execution state ");
-}
-
-static void aarch64_cpu_instance_init(Object *obj)
-{
- ARMCPUClass *acc = ARM_CPU_GET_CLASS(obj);
-
- acc->info->initfn(obj);
- arm_cpu_post_init(obj);
-}
-
-static void cpu_register_class_init(ObjectClass *oc, void *data)
-{
- ARMCPUClass *acc = ARM_CPU_CLASS(oc);
-
- acc->info = data;
-}
-
-void aarch64_cpu_register(const ARMCPUInfo *info)
-{
- TypeInfo type_info = {
- .parent = TYPE_AARCH64_CPU,
- .instance_init = aarch64_cpu_instance_init,
- .class_init = info->class_init ?: cpu_register_class_init,
- .class_data = (void *)info,
- };
-
- type_info.name = g_strdup_printf("%s-" TYPE_ARM_CPU, info->name);
- type_register_static(&type_info);
- g_free((void *)type_info.name);
-}
-
-static const TypeInfo aarch64_cpu_type_info = {
- .name = TYPE_AARCH64_CPU,
- .parent = TYPE_ARM_CPU,
- .instance_finalize = aarch64_cpu_finalizefn,
- .abstract = true,
- .class_init = aarch64_cpu_class_init,
-};
-
static void aarch64_cpu_register_types(void)
{
size_t i;
- type_register_static(&aarch64_cpu_type_info);
-
for (i = 0; i < ARRAY_SIZE(aarch64_cpus); ++i) {
- aarch64_cpu_register(&aarch64_cpus[i]);
+ arm_cpu_register(&aarch64_cpus[i]);
}
}