aboutsummaryrefslogtreecommitdiff
path: root/target/ppc
diff options
context:
space:
mode:
Diffstat (limited to 'target/ppc')
-rw-r--r--target/ppc/cpu-qom.h1
-rw-r--r--target/ppc/translate_init.c57
2 files changed, 58 insertions, 0 deletions
diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
index d0cf6ca..429b47f 100644
--- a/target/ppc/cpu-qom.h
+++ b/target/ppc/cpu-qom.h
@@ -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);
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 0d6379f..3d16481 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -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;