diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs index 2d9f77fa9b425796f948ade7aec25d333e513cae..baebc50f68e5ec51a99ab251f213f7a6f68856df 100644 --- a/target-arm/Makefile.objs +++ b/target-arm/Makefile.objs @@ -5,3 +5,4 @@ obj-$(CONFIG_NO_KVM) += kvm-stub.o obj-y += translate.o op_helper.o helper.o cpu.o obj-y += neon_helper.o iwmmxt_helper.o obj-y += gdbstub.o +obj-$(TARGET_AARCH64) += cpu64.o diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index 9f47baebf82d817391c6bfec97a8b7c10da4b231..fbe846e3730538c76a16dcc1df0d83b72e0d3897 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -130,6 +130,18 @@ typedef struct ARMCPU { uint32_t reset_auxcr; } ARMCPU; +#define TYPE_AARCH64_CPU "aarch64-cpu" +#define AARCH64_CPU_CLASS(klass) \ + OBJECT_CLASS_CHECK(AArch64CPUClass, (klass), TYPE_AARCH64_CPU) +#define AARCH64_CPU_GET_CLASS(obj) \ + OBJECT_GET_CLASS(AArch64CPUClass, (obj), TYPE_AArch64_CPU) + +typedef struct AArch64CPUClass { + /*< private >*/ + ARMCPUClass parent_class; + /*< public >*/ +} AArch64CPUClass; + static inline ARMCPU *arm_env_get_cpu(CPUARMState *env) { return container_of(env, ARMCPU, env); diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c new file mode 100644 index 0000000000000000000000000000000000000000..faee0f048fcf15cda9089c8bd53f103690869bc9 --- /dev/null +++ b/target-arm/cpu64.c @@ -0,0 +1,111 @@ +/* + * QEMU AArch64 CPU + * + * Copyright (c) 2013 Linaro Ltd + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + * + */ + +#include "cpu.h" +#include "qemu-common.h" +#if !defined(CONFIG_USER_ONLY) +#include "hw/loader.h" +#endif +#include "hw/arm/arm.h" +#include "sysemu/sysemu.h" +#include "sysemu/kvm.h" + +static inline void set_feature(CPUARMState *env, int feature) +{ + env->features |= 1ULL << feature; +} + +#ifdef CONFIG_USER_ONLY +static void aarch64_any_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + set_feature(&cpu->env, ARM_FEATURE_V8); + set_feature(&cpu->env, ARM_FEATURE_VFP4); + set_feature(&cpu->env, ARM_FEATURE_VFP_FP16); + set_feature(&cpu->env, ARM_FEATURE_NEON); + set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); + set_feature(&cpu->env, ARM_FEATURE_ARM_DIV); + set_feature(&cpu->env, ARM_FEATURE_V7MP); + set_feature(&cpu->env, ARM_FEATURE_AARCH64); +} +#endif + +typedef struct ARMCPUInfo { + const char *name; + void (*initfn)(Object *obj); + void (*class_init)(ObjectClass *oc, void *data); +} ARMCPUInfo; + +static const ARMCPUInfo aarch64_cpus[] = { +#ifdef CONFIG_USER_ONLY + { .name = "any", .initfn = aarch64_any_initfn }, +#endif +}; + +static void aarch64_cpu_initfn(Object *obj) +{ +} + +static void aarch64_cpu_finalizefn(Object *obj) +{ +} + +static void aarch64_cpu_class_init(ObjectClass *oc, void *data) +{ +} + +static void aarch64_cpu_register(const ARMCPUInfo *info) +{ + TypeInfo type_info = { + .parent = TYPE_AARCH64_CPU, + .instance_size = sizeof(ARMCPU), + .instance_init = info->initfn, + .class_size = sizeof(ARMCPUClass), + .class_init = info->class_init, + }; + + type_info.name = g_strdup_printf("%s-" TYPE_ARM_CPU, info->name); + type_register(&type_info); + g_free((void *)type_info.name); +} + +static const TypeInfo aarch64_cpu_type_info = { + .name = TYPE_AARCH64_CPU, + .parent = TYPE_ARM_CPU, + .instance_size = sizeof(ARMCPU), + .instance_init = aarch64_cpu_initfn, + .instance_finalize = aarch64_cpu_finalizefn, + .abstract = true, + .class_size = sizeof(AArch64CPUClass), + .class_init = aarch64_cpu_class_init, +}; + +static void aarch64_cpu_register_types(void) +{ + int i; + + type_register_static(&aarch64_cpu_type_info); + for (i = 0; i < ARRAY_SIZE(aarch64_cpus); i++) { + aarch64_cpu_register(&aarch64_cpus[i]); + } +} + +type_init(aarch64_cpu_register_types)