target/arm: Make 'any' CPU just an alias for 'max'

Now we have a working '-cpu max', the linux-user-only
'any' CPU is pretty much the same thing, so implement it
that way.

For the moment we don't add any of the extra feature bits
to the system-emulation "max", because we don't set the
ID register bits we would need to to advertise those
features as present.

Backports commit a0032cc5427d0d396aa0a9383ad9980533448ea4 from qemu
This commit is contained in:
Peter Maydell 2018-03-12 10:00:01 -04:00 committed by Lioncash
parent 7388fff079
commit fabd6c7ae8
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
3 changed files with 35 additions and 25 deletions

View file

@ -64,9 +64,9 @@ static int machvirt_init(struct uc_struct *uc, MachineState *machine)
int n;
if (!cpu_model) {
// Unicorn: "any" used instead to allow use of ARMv8.1+ instructions.
// Unicorn: "max" used instead to allow use of ARMv8.1+ instructions.
//cpu_model = "cortex-a57"; // ARM64
cpu_model = "any";
cpu_model = "max";
}
for (n = 0; n < smp_cpus; n++) {

View file

@ -735,13 +735,22 @@ static ObjectClass *arm_cpu_class_by_name(struct uc_struct *uc, const char *cpu_
{
ObjectClass *oc;
char *typename;
char **cpuname;
const char *cpunamestr;
if (!cpu_model) {
return NULL;
cpuname = g_strsplit(cpu_model, ",", 1);
cpunamestr = cpuname[0];
#ifdef CONFIG_USER_ONLY
/* For backwards compatibility usermode emulation allows "-cpu any",
* which has the same semantics as "-cpu max".
*/
if (!strcmp(cpunamestr, "any")) {
cpunamestr = "max";
}
typename = g_strdup_printf("%s-" TYPE_ARM_CPU, cpu_model);
#endif
typename = g_strdup_printf(ARM_CPU_TYPE_NAME("%s"), cpunamestr);
oc = object_class_by_name(uc, typename);
g_strfreev(cpuname);
g_free(typename);
if (!oc || !object_class_dynamic_cast(uc, oc, TYPE_ARM_CPU) ||
object_class_is_abstract(oc)) {
@ -1474,17 +1483,17 @@ static void pxa270c5_initfn(struct uc_struct *uc, Object *obj, void *opaque)
*/
static void arm_max_initfn(struct uc_struct *uc, Object *obj, void *opaque)
{
ARMCPU *cpu = ARM_CPU(uc, obj);
cortex_a15_initfn(uc, obj, opaque);
/* In future we might add feature bits here even if the
* real-world A15 doesn't implement them.
*/
}
#endif
#ifdef CONFIG_USER_ONLY
static void arm_any_initfn(struct uc_struct *uc, Object *obj, void *opaque)
{
ARMCPU *cpu = ARM_CPU(uc, obj);
// Unicorn: We lie and enable them anyway
/* We don't set these in system emulation mode for the moment,
* since we don't correctly set the ID registers to advertise them,
*/
set_feature(&cpu->env, ARM_FEATURE_V8);
set_feature(&cpu->env, ARM_FEATURE_VFP4);
set_feature(&cpu->env, ARM_FEATURE_NEON);
@ -1496,7 +1505,6 @@ static void arm_any_initfn(struct uc_struct *uc, Object *obj, void *opaque)
set_feature(&cpu->env, ARM_FEATURE_CRC);
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
cpu->midr = 0xffffffff;
}
#endif
@ -1549,7 +1557,7 @@ static const ARMCPUInfo arm_cpus[] = {
{ "max", arm_max_initfn },
#endif
#ifdef CONFIG_USER_ONLY
{ "any", arm_any_initfn },
{ "any", arm_max_initfn },
#endif
#endif
{ NULL }
@ -1584,6 +1592,7 @@ static void arm_cpu_class_init(struct uc_struct *uc, ObjectClass *oc, void *data
acc->parent_reset = cc->reset;
cc->reset = arm_cpu_reset;
cc->class_by_name = arm_cpu_class_by_name;
cc->class_by_name = arm_cpu_class_by_name;
cc->has_work = arm_cpu_has_work;

View file

@ -196,18 +196,18 @@ static void aarch64_a53_initfn(struct uc_struct *uc, Object *obj, void *opaque)
* this only needs to handle 64 bits.
*/
static void aarch64_max_initfn(struct uc_struct *uc, Object *obj, void *opaque)
{
aarch64_a57_initfn(uc, obj, opaque);
/* In future we might add feature bits here even if the
* real-world A57 doesn't implement them.
*/
}
// Unicorn: enabled for the general use-case as well.
static void aarch64_any_initfn(struct uc_struct *uc, Object *obj, void *opaque)
{
ARMCPU *cpu = ARM_CPU(uc, obj);
aarch64_a57_initfn(uc, obj, opaque);
// Unicorn: we lie and enable them anyway
/* We don't set these in system emulation mode for the moment,
* since we don't correctly set the ID registers to advertise them,
* and in some cases they're only available in AArch64 and not AArch32,
* whereas the architecture requires them to be present in both if
* present in either.
*/
set_feature(&cpu->env, ARM_FEATURE_V8);
set_feature(&cpu->env, ARM_FEATURE_VFP4);
set_feature(&cpu->env, ARM_FEATURE_NEON);
@ -224,6 +224,9 @@ static void aarch64_any_initfn(struct uc_struct *uc, Object *obj, void *opaque)
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
/* For usermode -cpu max we can use a larger and more efficient DCZ
* blocksize since we don't have to follow what the hardware does.
*/
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
cpu->dcz_blocksize = 7; /* 512 bytes */
}
@ -238,8 +241,6 @@ static const ARMCPUInfo aarch64_cpus[] = {
{ "cortex-a57", aarch64_a57_initfn },
{ "cortex-a53", aarch64_a53_initfn },
{ "max", aarch64_max_initfn },
// Unicorn: enabled for the general use case as well
{ "any", aarch64_any_initfn },
{ NULL }
};