ppc: move '-cpu foo,compat=xxx' parsing into ppc_cpu_parse_featurestr()

there is a dedicated callback CPUClass::parse_features
which purpose is to convert -cpu features into a set of
global properties AND deal with compat/legacy features
that couldn't be directly translated into CPU's properties.

Create ppc variant of it (ppc_cpu_parse_featurestr) and
move 'compat=val' handling from spapr_cpu_core.c into it.
That removes a dependency of board/core code on cpu_model
parsing and would let to reuse common -cpu parsing
introduced by 6063d4c0

Set "max-cpu-compat" property only if it exists, in practice
it should limit 'compat' hack to spapr machine and allow
to avoid including machine/spapr headers in target/ppc/cpu.c

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
master
Igor Mammedov 2017-10-09 21:50:59 +02:00 committed by David Gibson
parent a1063aa8a5
commit b8e999673b
5 changed files with 59 additions and 52 deletions

View File

@ -2373,7 +2373,7 @@ static void ppc_spapr_init(MachineState *machine)
machine->cpu_model = kvm_enabled() ? "host" : smc->tcg_default_cpu;
}
spapr_cpu_parse_features(spapr);
cpu_parse_cpu_model(TYPE_POWERPC_CPU, machine->cpu_model);
spapr_set_vsmt_mode(spapr, &error_fatal);

View File

@ -21,56 +21,6 @@
#include "sysemu/hw_accel.h"
#include "qemu/error-report.h"
void spapr_cpu_parse_features(sPAPRMachineState *spapr)
{
/*
* Backwards compatibility hack:
*
* CPUs had a "compat=" property which didn't make sense for
* anything except pseries. It was replaced by "max-cpu-compat"
* machine option. This supports old command lines like
* -cpu POWER8,compat=power7
* By stripping the compat option and applying it to the machine
* before passing it on to the cpu level parser.
*/
gchar **inpieces;
gchar *newprops;
int i, j;
gchar *compat_str = NULL;
inpieces = g_strsplit(MACHINE(spapr)->cpu_model, ",", 0);
/* inpieces[0] is the actual model string */
i = 1;
j = 1;
while (inpieces[i]) {
if (g_str_has_prefix(inpieces[i], "compat=")) {
/* in case of multiple compat= options */
g_free(compat_str);
compat_str = inpieces[i];
} else {
j++;
}
i++;
/* Excise compat options from list */
inpieces[j] = inpieces[i];
}
if (compat_str) {
char *val = compat_str + strlen("compat=");
object_property_set_str(OBJECT(spapr), val, "max-cpu-compat",
&error_fatal);
}
newprops = g_strjoinv(",", inpieces);
cpu_parse_cpu_model(TYPE_POWERPC_CPU, newprops);
g_free(newprops);
g_strfreev(inpieces);
}
static void spapr_cpu_reset(void *opaque)
{
PowerPCCPU *cpu = opaque;

View File

@ -659,7 +659,6 @@ void spapr_hotplug_req_add_by_count_indexed(sPAPRDRConnectorType drc_type,
uint32_t count, uint32_t index);
void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_type,
uint32_t count, uint32_t index);
void spapr_cpu_parse_features(sPAPRMachineState *spapr);
int spapr_hpt_shift_for_ramsize(uint64_t ramsize);
void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
Error **errp);

View File

@ -181,6 +181,7 @@ typedef struct PowerPCCPUClass {
DeviceRealize parent_realize;
DeviceUnrealize parent_unrealize;
void (*parent_reset)(CPUState *cpu);
void (*parent_parse_features)(const char *type, char *str, Error **errp);
uint32_t pvr;
bool (*pvr_match)(struct PowerPCCPUClass *pcc, uint32_t pvr);

View File

@ -10097,6 +10097,61 @@ static ObjectClass *ppc_cpu_class_by_name(const char *name)
return NULL;
}
static void ppc_cpu_parse_featurestr(const char *type, char *features,
Error **errp)
{
Object *machine = qdev_get_machine();
const PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(object_class_by_name(type));
if (!features) {
return;
}
if (object_property_find(machine, "max-cpu-compat", NULL)) {
int i;
char **inpieces;
char *s = features;
Error *local_err = NULL;
char *compat_str = NULL;
/*
* Backwards compatibility hack:
*
* CPUs had a "compat=" property which didn't make sense for
* anything except pseries. It was replaced by "max-cpu-compat"
* machine option. This supports old command lines like
* -cpu POWER8,compat=power7
* By stripping the compat option and applying it to the machine
* before passing it on to the cpu level parser.
*/
inpieces = g_strsplit(features, ",", 0);
*s = '\0';
for (i = 0; inpieces[i]; i++) {
if (g_str_has_prefix(inpieces[i], "compat=")) {
compat_str = inpieces[i];
continue;
}
if ((i != 0) && (s != features)) {
s = g_stpcpy(s, ",");
}
s = g_stpcpy(s, inpieces[i]);
}
if (compat_str) {
char *v = compat_str + strlen("compat=");
object_property_set_str(machine, v, "max-cpu-compat", &local_err);
}
g_strfreev(inpieces);
if (local_err) {
error_propagate(errp, local_err);
return;
}
}
/* do property processing with generic handler */
pcc->parent_parse_features(type, features, errp);
}
const char *ppc_cpu_lookup_alias(const char *alias)
{
int ai;
@ -10489,6 +10544,8 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
cc->reset = ppc_cpu_reset;
cc->class_by_name = ppc_cpu_class_by_name;
pcc->parent_parse_features = cc->parse_features;
cc->parse_features = ppc_cpu_parse_featurestr;
cc->has_work = ppc_cpu_has_work;
cc->do_interrupt = ppc_cpu_do_interrupt;
cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;