The new "cfgend" parameter can be given after the CPU name, e.g. "-cpu=arm926,cfgend=yes". Unlike earlier versions of the patch, CPU attribute parsing is left to board initialisation code: for the "virt" board, this was being done already, and this patch makes the integratorcp board init do so too.
Signed-off-by: Julian Brown <jul...@codesourcery.com> --- hw/arm/integratorcp.c | 19 +++++++++++++++++-- target/arm/cpu.c | 14 ++++++++++++++ target/arm/cpu.h | 7 +++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c index 039812a..337c689 100644 --- a/hw/arm/integratorcp.c +++ b/hw/arm/integratorcp.c @@ -535,27 +535,42 @@ static void integratorcp_init(MachineState *machine) const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; + char **cpustr; ObjectClass *cpu_oc; + CPUClass *cc; Object *cpuobj; ARMCPU *cpu; + const char *typename; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *ram_alias = g_new(MemoryRegion, 1); qemu_irq pic[32]; DeviceState *dev, *sic, *icp; int i; + Error *err = NULL; if (!cpu_model) { cpu_model = "arm926"; } - cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model); + cpustr = g_strsplit(cpu_model, ",", 2); + + cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]); if (!cpu_oc) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } + typename = object_class_get_name(cpu_oc); + + cc = CPU_CLASS(cpu_oc); + cc->parse_features(typename, cpustr[1], &err); + g_strfreev(cpustr); + if (err) { + error_report(err); + exit(1); + } - cpuobj = object_new(object_class_get_name(cpu_oc)); + cpuobj = object_new(typename); /* By default ARM1176 CPUs have EL3 enabled. This board does not * currently support EL3 so the CPU EL3 property is disabled before diff --git a/target/arm/cpu.c b/target/arm/cpu.c index c29aafe..bdf86de 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -33,6 +33,7 @@ #include "sysemu/sysemu.h" #include "sysemu/kvm.h" #include "kvm_arm.h" +#include "exec/cpu-common.h" static void arm_cpu_set_pc(CPUState *cs, vaddr value) { @@ -502,6 +503,9 @@ static Property arm_cpu_has_el2_property = static Property arm_cpu_has_el3_property = DEFINE_PROP_BOOL("has_el3", ARMCPU, has_el3, true); +static Property arm_cpu_cfgend_property = + DEFINE_PROP_BOOL("cfgend", ARMCPU, cfgend, false); + /* use property name "pmu" to match other archs and virt tools */ static Property arm_cpu_has_pmu_property = DEFINE_PROP_BOOL("pmu", ARMCPU, has_pmu, true); @@ -569,6 +573,8 @@ static void arm_cpu_post_init(Object *obj) } } + qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property, + &error_abort); } static void arm_cpu_finalizefn(Object *obj) @@ -770,6 +776,14 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) address_space_init_shareable(cs->memory, "cpu-memory"), ARMASIdx_NS); + + if (cpu->cfgend) { + if (arm_feature(&cpu->env, ARM_FEATURE_V7)) { + cpu->reset_sctlr |= SCTLR_EE; + } else { + cpu->reset_sctlr |= SCTLR_B; + } + } #endif qemu_init_vcpu(cs); diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 151a5d7..ac8d625 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -669,6 +669,13 @@ struct ARMCPU { int gic_vpribits; /* number of virtual priority bits */ int gic_vprebits; /* number of virtual preemption bits */ + /* Whether the cfgend input is high (i.e. this CPU should reset into + * big-endian mode). This setting isn't used directly: instead it modifies + * the reset_sctlr value to have SCTLR_B or SCTLR_EE set, depending on the + * architecture version. + */ + bool cfgend; + ARMELChangeHook *el_change_hook; void *el_change_hook_opaque; }; -- 2.8.1