@@ -136,12 +136,14 @@ struct MachineClass {
bool rom_file_has_mr;
int minimum_page_bits;
bool has_hotpluggable_cpus;
+ const char *base_cpu_type;
HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
DeviceState *dev);
unsigned (*cpu_index_to_socket_id)(unsigned cpu_index);
const CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine);
const char *(*default_cpu_model)(MachineState *machine);
+ bool (*cpu_model_valid)(MachineState *machine, const char *cpu_model);
};
/**
@@ -182,6 +184,7 @@ struct MachineState {
char *kernel_cmdline;
char *initrd_filename;
const char *cpu_model;
+ const char *cpu_typename;
AccelState *accelerator;
CPUArchIdList *possible_cpus;
};
@@ -105,6 +105,4 @@ enum {
/* ppc_booke.c */
void ppc_booke_timers_init(PowerPCCPU *cpu, uint32_t freq, uint32_t flags);
-
-void ppc_cpu_parse_features(const char *cpu_model);
#endif
@@ -169,7 +169,7 @@ static const char *valid_cpus[] = {
"host",
};
-static bool cpuname_valid(const char *cpu)
+static bool cpuname_valid(MachineState *machine, const char *cpu)
{
int i;
@@ -1244,12 +1244,6 @@ static void machvirt_init(MachineState *machine)
MemoryRegion *secure_sysmem = NULL;
int n, virt_max_cpus;
MemoryRegion *ram = g_new(MemoryRegion, 1);
- const char *cpu_model = machine->cpu_model;
- char **cpustr;
- ObjectClass *oc;
- const char *typename;
- CPUClass *cc;
- Error *err = NULL;
bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
/* We can probe only here because during property set
@@ -1268,14 +1262,6 @@ static void machvirt_init(MachineState *machine)
}
}
- /* Separate the actual CPU model name from any appended features */
- cpustr = g_strsplit(cpu_model, ",", 2);
-
- if (!cpuname_valid(cpustr[0])) {
- error_report("mach-virt: CPU %s not supported", cpustr[0]);
- exit(1);
- }
-
/* If we have an EL3 boot ROM then the assumption is that it will
* implement PSCI itself, so disable QEMU's internal implementation
* so it doesn't get in the way. Instead of starting secondary
@@ -1342,22 +1328,6 @@ static void machvirt_init(MachineState *machine)
create_fdt(vms);
- oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]);
- if (!oc) {
- error_report("Unable to find CPU definition");
- exit(1);
- }
- typename = object_class_get_name(oc);
-
- /* convert -smp CPU options specified by the user into global props */
- cc = CPU_CLASS(oc);
- cc->parse_features(typename, cpustr[1], &err);
- g_strfreev(cpustr);
- if (err) {
- error_report_err(err);
- exit(1);
- }
-
mc->possible_cpu_arch_ids(machine);
for (n = 0; n < machine->possible_cpus->len; n++) {
Object *cpuobj;
@@ -1367,7 +1337,7 @@ static void machvirt_init(MachineState *machine)
break;
}
- cpuobj = object_new(typename);
+ cpuobj = object_new(machine->cpu_typename);
object_property_set_int(cpuobj, machine->possible_cpus->cpus[n].arch_id,
"mp-affinity", NULL);
@@ -1583,6 +1553,8 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
mc->minimum_page_bits = 12;
mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
mc->default_cpu_model = virt_default_cpu_model;
+ mc->cpu_model_valid = cpuname_valid;
+ mc->base_cpu_type = TYPE_ARM_CPU;
}
static const TypeInfo virt_machine_info = {
@@ -575,8 +575,12 @@ bool machine_mem_merge(MachineState *machine)
return machine->mem_merge;
}
-void machine_run_board_init(MachineState *machine)
+static void machine_parse_cpu_model(MachineState *machine)
{
+ ObjectClass *oc;
+ char **cpustr;
+ CPUClass *cc;
+ Error *err = NULL;
MachineClass *machine_class = MACHINE_GET_CLASS(machine);
/* Force all boards to provide default_cpu_model callback */
@@ -585,6 +589,44 @@ void machine_run_board_init(MachineState *machine)
machine->cpu_model = machine_class->default_cpu_model(machine);
}
+ /* Separate the actual CPU model name from any appended features */
+ cpustr = g_strsplit(machine->cpu_model, ",", 2);
+ if (!cpustr[0]) {
+ error_setg(&err, "Invalid/empty CPU model name");
+ goto out;
+ }
+
+ if (machine_class->cpu_model_valid &&
+ !machine_class->cpu_model_valid(machine, cpustr[0])) {
+ error_report("CPU %s not supported", cpustr[0]);
+ exit(1);
+ }
+
+ /* Force all boards to provide base_cpu_type */
+ assert(machine_class->base_cpu_type);
+ oc = cpu_class_by_name(machine_class->base_cpu_type, cpustr[0]);
+ if (!oc) {
+ error_report("Unable to find CPU definition: %s", cpustr[0]);
+ exit(1);
+ }
+ machine->cpu_typename = object_class_get_name(oc);
+
+ /* convert -smp CPU options specified by the user into global props */
+ cc = CPU_CLASS(oc);
+ cc->parse_features(machine->cpu_typename, cpustr[1], &err);
+out:
+ g_strfreev(cpustr);
+ if (err) {
+ error_report_err(err);
+ exit(1);
+ }
+}
+
+void machine_run_board_init(MachineState *machine)
+{
+ MachineClass *machine_class = MACHINE_GET_CLASS(machine);
+
+ machine_parse_cpu_model(machine);
machine_class->init(machine);
}
@@ -1140,31 +1140,11 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
void pc_cpus_init(PCMachineState *pcms)
{
int i;
- CPUClass *cc;
- ObjectClass *oc;
- const char *typename;
- gchar **model_pieces;
const CPUArchIdList *possible_cpus;
MachineState *machine = MACHINE(pcms);
MachineClass *mc = MACHINE_GET_CLASS(pcms);
/* init CPUs */
- model_pieces = g_strsplit(machine->cpu_model, ",", 2);
- if (!model_pieces[0]) {
- error_report("Invalid/empty CPU model name");
- exit(1);
- }
-
- oc = cpu_class_by_name(TYPE_X86_CPU, model_pieces[0]);
- if (oc == NULL) {
- error_report("Unable to find CPU definition: %s", model_pieces[0]);
- exit(1);
- }
- typename = object_class_get_name(oc);
- cc = CPU_CLASS(oc);
- cc->parse_features(typename, model_pieces[1], &error_fatal);
- g_strfreev(model_pieces);
-
/* Calculates the limit to CPU APIC ID values
*
* Limit for the APIC ID value, so that all
@@ -1175,7 +1155,8 @@ void pc_cpus_init(PCMachineState *pcms)
pcms->apic_id_limit = x86_cpu_apic_id_from_index(max_cpus - 1) + 1;
possible_cpus = mc->possible_cpu_arch_ids(machine);
for (i = 0; i < smp_cpus; i++) {
- pc_new_cpu(typename, possible_cpus->cpus[i].arch_id, &error_fatal);
+ pc_new_cpu(machine->cpu_typename,
+ possible_cpus->cpus[i].arch_id, &error_fatal);
}
}
@@ -2326,6 +2307,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
mc->hot_add_cpu = pc_hot_add_cpu;
mc->max_cpus = 255;
mc->default_cpu_model = pc_default_cpu_model;
+ mc->base_cpu_type = TYPE_X86_CPU;
mc->reset = pc_machine_reset;
hc->pre_plug = pc_machine_device_pre_plug_cb;
hc->plug = pc_machine_device_plug_cb;
@@ -1364,28 +1364,3 @@ PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id)
return NULL;
}
-
-void ppc_cpu_parse_features(const char *cpu_model)
-{
- CPUClass *cc;
- ObjectClass *oc;
- const char *typename;
- gchar **model_pieces;
-
- model_pieces = g_strsplit(cpu_model, ",", 2);
- if (!model_pieces[0]) {
- error_report("Invalid/empty CPU model name");
- exit(1);
- }
-
- oc = cpu_class_by_name(TYPE_POWERPC_CPU, model_pieces[0]);
- if (oc == NULL) {
- error_report("Unable to find CPU definition: %s", model_pieces[0]);
- exit(1);
- }
-
- typename = object_class_get_name(oc);
- cc = CPU_CLASS(oc);
- cc->parse_features(typename, model_pieces[1], &error_fatal);
- g_strfreev(model_pieces);
-}
@@ -1920,8 +1920,6 @@ static void ppc_spapr_init(MachineState *machine)
}
/* init CPUs */
- ppc_cpu_parse_features(machine->cpu_model);
-
spapr_init_cpus(spapr);
if (kvm_enabled()) {
@@ -2896,6 +2894,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
mc->cpu_index_to_socket_id = spapr_cpu_index_to_socket_id;
mc->possible_cpu_arch_ids = spapr_possible_cpu_arch_ids;
mc->default_cpu_model = spapr_default_cpu_model;
+ mc->base_cpu_type = TYPE_POWERPC_CPU;
hc->unplug_request = spapr_machine_device_unplug_request;
smc->dr_lmb_enabled = true;
Parse cpu_model string into cpu_type and [=-]foo features in common machine code instead of doing the same on every board. TODO: patch handles only virt-arm/spapr/pc boards, but to avoid bisection breakage it should take care of all boards. Signed-off-by: Igor Mammedov <imammedo@redhat.com> --- include/hw/boards.h | 3 +++ include/hw/ppc/ppc.h | 2 -- hw/arm/virt.c | 36 ++++-------------------------------- hw/core/machine.c | 44 +++++++++++++++++++++++++++++++++++++++++++- hw/i386/pc.c | 24 +++--------------------- hw/ppc/ppc.c | 25 ------------------------- hw/ppc/spapr.c | 3 +-- 7 files changed, 54 insertions(+), 83 deletions(-)