arm: drop intermediate cpu_model -> cpu type parsing and use cpu type directly

there are 2 use cases to deal with:
1: fixed CPU models per board/soc
2: boards with user configurable cpu_model and fallback to
default cpu_model if user hasn't specified one explicitly

For the 1st
drop intermediate cpu_model parsing and use const cpu type
directly, which replaces:
typename = object_class_get_name(
cpu_class_by_name(TYPE_ARM_CPU, cpu_model))
object_new(typename)
with
object_new(FOO_CPU_TYPE_NAME)
or
cpu_generic_init(BASE_CPU_TYPE, "my cpu model")
with
cpu_create(FOO_CPU_TYPE_NAME)

as result 1st use case doesn't have to invoke not necessary
translation and not needed code is removed.

For the 2nd
1: set default cpu type with MachineClass::default_cpu_type and
2: use generic cpu_model parsing that done before machine_init()
is run and:
2.1: drop custom cpu_model parsing where pattern is:
typename = object_class_get_name(
cpu_class_by_name(TYPE_ARM_CPU, cpu_model))
[parse_features(typename, cpu_model, &err) ]

2.2: or replace cpu_generic_init() which does what
2.1 does + create_cpu(typename) with just
create_cpu(machine->cpu_type)
as result cpu_name -> cpu_type translation is done using
generic machine code one including parsing optional features
if supported/present (removes a bunch of duplicated cpu_model
parsing code) and default cpu type is defined in an uniform way
within machine_class_init callbacks instead of adhoc places
in boadr's machine_init code.

Backports commit ba1ba5cca3962a9cc400c713c736b4fb8db1f38e from qemu
This commit is contained in:
Igor Mammedov 2018-03-20 13:34:26 -04:00 committed by Lioncash
parent 20f67e8f9a
commit 7fe1504224
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -58,43 +58,38 @@ typedef struct {
#define VIRT_MACHINE_CLASS(uc, klass) \
OBJECT_CLASS_CHECK(uc, VirtMachineClass, klass, TYPE_VIRT_MACHINE)
static const char *valid_cpus[] = {
ARM_CPU_TYPE_NAME("cortex-a15"),
ARM_CPU_TYPE_NAME("cortex-a53"),
ARM_CPU_TYPE_NAME("cortex-a57"),
ARM_CPU_TYPE_NAME("host"),
// Unicorn: added to allow enabling all CPU features
ARM_CPU_TYPE_NAME("max"),
};
static bool cpu_type_valid(const char *cpu)
{
int i;
for (i = 0; i < ARRAY_SIZE(valid_cpus); i++) {
if (strcmp(cpu, valid_cpus[i]) == 0) {
return true;
}
}
return false;
}
static int machvirt_init(struct uc_struct *uc, MachineState *machine)
{
const char *cpu_model = machine->cpu_model;
char **cpustr;
ObjectClass *oc;
const char *typename;
CPUClass *cc;
Error *err = NULL;
int n;
if (!cpu_model) {
// Unicorn: "max" used instead to allow use of ARMv8.1+ instructions.
//cpu_model = "cortex-a57"; // ARM64
cpu_model = "max";
}
/* Separate the actual CPU model name from any appended features */
cpustr = g_strsplit(cpu_model, ",", 2);
oc = cpu_class_by_name(uc, TYPE_ARM_CPU, cpustr[0]);
if (!oc) {
fprintf(stderr, "Unable to find CPU definition");
return -1;
}
typename = object_class_get_name(oc);
/* convert -smp CPU options specified by the user into global props */
cc = CPU_CLASS(uc, oc);
cc->parse_features(uc, typename, cpustr[1], &err);
g_strfreev(cpustr);
if (err) {
fprintf(stderr, "Error parsing cpu features");
if (!cpu_type_valid(machine->cpu_type)) {
fprintf(stderr, "mach-virt: CPU type %s not supported", machine->cpu_type);
return -1;
}
for (n = 0; n < smp_cpus; n++) {
Object *cpuobj = object_new(uc, typename);
Object *cpuobj = object_new(uc, machine->cpu_type);
uc->cpu = CPU(cpuobj);
object_property_set_bool(uc, cpuobj, true, "realized", NULL);
@ -142,6 +137,8 @@ static void virt_class_init(struct uc_struct *uc, ObjectClass *oc, void *data)
mc->max_cpus = 8;
mc->is_default = 1;
mc->arch = UC_ARCH_ARM64;
// Unicorn: Enable all CPU features
mc->default_cpu_type = ARM_CPU_TYPE_NAME("max");
}
static const TypeInfo machvirt_info = {