diff --git a/qemu/aarch64.h b/qemu/aarch64.h
index 3be2220a..d0ea77a8 100644
--- a/qemu/aarch64.h
+++ b/qemu/aarch64.h
@@ -1947,6 +1947,7 @@
#define page_size_init page_size_init_aarch64
#define par_write par_write_aarch64
#define parse_array parse_array_aarch64
+#define parse_cpu_model parse_cpu_model_aarch64
#define parse_error parse_error_aarch64
#define parse_escape parse_escape_aarch64
#define parse_keyword parse_keyword_aarch64
diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h
index ddfc84a5..d6a79ac7 100644
--- a/qemu/aarch64eb.h
+++ b/qemu/aarch64eb.h
@@ -1947,6 +1947,7 @@
#define page_size_init page_size_init_aarch64eb
#define par_write par_write_aarch64eb
#define parse_array parse_array_aarch64eb
+#define parse_cpu_model parse_cpu_model_aarch64eb
#define parse_error parse_error_aarch64eb
#define parse_escape parse_escape_aarch64eb
#define parse_keyword parse_keyword_aarch64eb
diff --git a/qemu/arm.h b/qemu/arm.h
index da113846..bd0a792c 100644
--- a/qemu/arm.h
+++ b/qemu/arm.h
@@ -1947,6 +1947,7 @@
#define page_size_init page_size_init_arm
#define par_write par_write_arm
#define parse_array parse_array_arm
+#define parse_cpu_model parse_cpu_model_arm
#define parse_error parse_error_arm
#define parse_escape parse_escape_arm
#define parse_keyword parse_keyword_arm
diff --git a/qemu/armeb.h b/qemu/armeb.h
index d44cf486..2dcb704b 100644
--- a/qemu/armeb.h
+++ b/qemu/armeb.h
@@ -1947,6 +1947,7 @@
#define page_size_init page_size_init_armeb
#define par_write par_write_armeb
#define parse_array parse_array_armeb
+#define parse_cpu_model parse_cpu_model_armeb
#define parse_error parse_error_armeb
#define parse_escape parse_escape_armeb
#define parse_keyword parse_keyword_armeb
diff --git a/qemu/exec.c b/qemu/exec.c
index 6565e0d1..6c6613ac 100644
--- a/qemu/exec.c
+++ b/qemu/exec.c
@@ -620,6 +620,29 @@ void cpu_exec_init(CPUState *cpu, void *opaque)
#endif
}
+const char *parse_cpu_model(struct uc_struct *uc, const char *cpu_model)
+{
+ ObjectClass *oc;
+ CPUClass *cc;
+ gchar **model_pieces;
+ const char *cpu_type;
+
+ model_pieces = g_strsplit(cpu_model, ",", 2);
+
+ oc = cpu_class_by_name(uc, CPU_RESOLVING_TYPE, model_pieces[0]);
+ if (oc == NULL) {
+ fprintf(stderr, "unable to find CPU model '%s'", model_pieces[0]);
+ g_strfreev(model_pieces);
+ return NULL;
+ }
+
+ cpu_type = object_class_get_name(oc);
+ cc = CPU_CLASS(uc, oc);
+ cc->parse_features(uc, cpu_type, model_pieces[1], &error_fatal);
+ g_strfreev(model_pieces);
+ return cpu_type;
+}
+
#if defined(CONFIG_USER_ONLY)
static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
{
diff --git a/qemu/glib_compat.c b/qemu/glib_compat.c
index 1c3a4039..d2f536ad 100644
--- a/qemu/glib_compat.c
+++ b/qemu/glib_compat.c
@@ -224,6 +224,106 @@ void g_list_free(GList *list)
}
}
+/**
+ * g_list_free_full:
+ * @list: a pointer to a #GList
+ * @free_func: the function to be called to free each element's data
+ *
+ * Convenience method, which frees all the memory used by a #GList, and
+ * calls the specified destroy function on every element's data.
+ *
+ * Since: 2.28
+ */
+void
+g_list_free_full (GList *list,
+ GDestroyNotify free_func)
+{
+ g_list_foreach (list, (GFunc) free_func, NULL);
+ g_list_free (list);
+}
+
+/**
+ * g_list_last:
+ * @list: a #GList
+ *
+ * Gets the last element in a #GList.
+ *
+ * Returns: the last element in the #GList,
+ * or %NULL if the #GList has no elements
+ */
+GList*
+g_list_last (GList *list)
+{
+ if (list)
+ {
+ while (list->next)
+ list = list->next;
+ }
+
+ return list;
+}
+
+/**
+ * g_list_append:
+ * @list: a pointer to a #GList
+ * @data: the data for the new element
+ *
+ * Adds a new element on to the end of the list.
+ *
+ *
+ * The return value is the new start of the list, which
+ * may have changed, so make sure you store the new value.
+ *
+ *
+ *
+ * Note that g_list_append() has to traverse the entire list
+ * to find the end, which is inefficient when adding multiple
+ * elements. A common idiom to avoid the inefficiency is to prepend
+ * the elements and reverse the list when all elements have been added.
+ *
+ *
+ * |[
+ * /* Notice that these are initialized to the empty list. */
+ * GList *list = NULL, *number_list = NULL;
+ *
+ * /* This is a list of strings. */
+ * list = g_list_append (list, "first");
+ * list = g_list_append (list, "second");
+ *
+ * /* This is a list of integers. */
+ * number_list = g_list_append (number_list, GINT_TO_POINTER (27));
+ * number_list = g_list_append (number_list, GINT_TO_POINTER (14));
+ * ]|
+ *
+ * Returns: the new start of the #GList
+ */
+GList*
+g_list_append (GList *list,
+ gpointer data)
+{
+ GList *new_list;
+ GList *last;
+
+ new_list = g_new0(GList, 1);
+ new_list->data = data;
+ new_list->next = NULL;
+
+ if (list)
+ {
+ last = g_list_last (list);
+ /* g_assert (last != NULL); */
+ last->next = new_list;
+ new_list->prev = last;
+
+ return list;
+ }
+ else
+ {
+ new_list->prev = NULL;
+ return new_list;
+ }
+}
+
GList *g_list_insert_sorted(GList *list, gpointer data, GCompareFunc compare)
{
GList *i;
diff --git a/qemu/header_gen.py b/qemu/header_gen.py
index e8b82956..8b8cbe89 100644
--- a/qemu/header_gen.py
+++ b/qemu/header_gen.py
@@ -1953,6 +1953,7 @@ symbols = (
'page_size_init',
'par_write',
'parse_array',
+ 'parse_cpu_model',
'parse_error',
'parse_escape',
'parse_keyword',
diff --git a/qemu/hw/arm/tosa.c b/qemu/hw/arm/tosa.c
index 56fd871a..3aa40192 100644
--- a/qemu/hw/arm/tosa.c
+++ b/qemu/hw/arm/tosa.c
@@ -22,9 +22,9 @@
static int tosa_init(struct uc_struct *uc, MachineState *machine)
{
if (uc->mode & UC_MODE_MCLASS) {
- uc->cpu = cpu_init(uc, "cortex-m3");
+ uc->cpu = cpu_create(uc, "cortex-m3");
} else {
- uc->cpu = cpu_init(uc, "cortex-a15");
+ uc->cpu = cpu_create(uc, "cortex-a15");
}
return 0;
diff --git a/qemu/hw/m68k/dummy_m68k.c b/qemu/hw/m68k/dummy_m68k.c
index 0423bafd..3acc3d3c 100644
--- a/qemu/hw/m68k/dummy_m68k.c
+++ b/qemu/hw/m68k/dummy_m68k.c
@@ -19,14 +19,10 @@
/* Board init. */
static int dummy_m68k_init(struct uc_struct *uc, MachineState *machine)
{
- const char *cpu_model = machine->cpu_model;
CPUM68KState *env;
+ const char *cpu_type = parse_cpu_model(uc, "cf4ve");
- if (!cpu_model) {
- cpu_model = "cfv4e";
- }
-
- uc->cpu = cpu_init(uc, cpu_model);
+ uc->cpu = cpu_create(uc, cpu_type);
if (!uc->cpu) {
fprintf(stderr, "Unable to find m68k CPU definition\n");
return -1;
@@ -45,6 +41,7 @@ static void dummy_m68k_machine_init(struct uc_struct *uc, MachineClass *mc)
mc->init = dummy_m68k_init;
mc->is_default = 1;
mc->arch = UC_ARCH_M68K;
+ mc->default_cpu_type = M68K_CPU_TYPE_NAME("cfv4e");
}
DEFINE_MACHINE("dummy", dummy_m68k_machine_init)
diff --git a/qemu/hw/mips/mips_r4k.c b/qemu/hw/mips/mips_r4k.c
index 48fd0df6..267f0e81 100644
--- a/qemu/hw/mips/mips_r4k.c
+++ b/qemu/hw/mips/mips_r4k.c
@@ -25,18 +25,14 @@
static int mips_r4k_init(struct uc_struct *uc, MachineState *machine)
{
- const char *cpu_model = machine->cpu_model;
-
- /* init CPUs */
- if (cpu_model == NULL) {
#ifdef TARGET_MIPS64
- cpu_model = "R4000";
+ const char *cpu_model = MIPS_CPU_TYPE_NAME("R4000");
#else
- cpu_model = "24Kf";
+ const char *cpu_model = MIPS_CPU_TYPE_NAME("24Kf");
#endif
- }
+ const char *cpu_type = parse_cpu_model(uc, cpu_model);
- uc->cpu = cpu_generic_init(uc, TYPE_MIPS_CPU, cpu_model);
+ uc->cpu = cpu_create(uc, cpu_type);
if (uc->cpu == NULL) {
fprintf(stderr, "Unable to find CPU definition\n");
return -1;
@@ -50,6 +46,11 @@ static void mips_machine_init(struct uc_struct *uc, MachineClass *mc)
mc->init = mips_r4k_init;
mc->is_default = 1;
mc->arch = UC_ARCH_MIPS;
+#ifdef TARGET_MIPS64
+ mc->default_cpu_type = MIPS_CPU_TYPE_NAME("R4000");
+#else
+ mc->default_cpu_type = MIPS_CPU_TYPE_NAME("24Kf");
+#endif
}
DEFINE_MACHINE("mips", mips_machine_init)
diff --git a/qemu/hw/sparc/leon3.c b/qemu/hw/sparc/leon3.c
index 68083974..64ff7d6c 100644
--- a/qemu/hw/sparc/leon3.c
+++ b/qemu/hw/sparc/leon3.c
@@ -38,15 +38,10 @@
static int leon3_generic_hw_init(struct uc_struct *uc, MachineState *machine)
{
- const char *cpu_model = machine->cpu_model;
+ const char *cpu_type = parse_cpu_model(uc, "LEON3");
SPARCCPU *cpu;
- /* Init CPU */
- if (!cpu_model) {
- cpu_model = "LEON3";
- }
-
- uc->cpu = cpu_init(uc, cpu_model);
+ uc->cpu = cpu_create(uc, cpu_type);
cpu = SPARC_CPU(uc, uc->cpu);
if (cpu == NULL) {
fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
@@ -63,6 +58,7 @@ static void leon3_generic_machine_init(struct uc_struct *uc, MachineClass *mc)
mc->init = leon3_generic_hw_init;
mc->is_default = 1;
mc->arch = UC_ARCH_SPARC;
+ mc->default_cpu_type = SPARC_CPU_TYPE_NAME("LEON3");
}
DEFINE_MACHINE("leon3_generic", leon3_generic_machine_init)
diff --git a/qemu/hw/sparc64/sun4u.c b/qemu/hw/sparc64/sun4u.c
index 7b0246a9..e2e68810 100644
--- a/qemu/hw/sparc64/sun4u.c
+++ b/qemu/hw/sparc64/sun4u.c
@@ -36,14 +36,10 @@
/* Sun4u hardware initialisation */
static int sun4u_init(struct uc_struct *uc, MachineState *machine)
{
- const char *cpu_model = machine->cpu_model;
+ const char *cpu_type = parse_cpu_model(uc, "Sun UltraSparc IV");
SPARCCPU *cpu;
- if (cpu_model == NULL) {
- cpu_model = "Sun UltraSparc IV";
- }
-
- uc->cpu = cpu_init(uc, cpu_model);
+ uc->cpu = cpu_create(uc, cpu_type);
cpu = SPARC_CPU(uc, uc->cpu);
if (cpu == NULL) {
fprintf(stderr, "Unable to find Sparc CPU definition\n");
@@ -61,6 +57,7 @@ static void sun4u_class_init(struct uc_struct *uc, ObjectClass *oc, void *data)
mc->max_cpus = 1; /* XXX for now */
mc->is_default = 1;
mc->arch = UC_ARCH_SPARC;
+ mc->default_cpu_type = SPARC_CPU_TYPE_NAME("Sun UltraSparc IV");
}
static const TypeInfo sun4u_type = {
diff --git a/qemu/include/glib_compat.h b/qemu/include/glib_compat.h
index 5f3f8af7..b4599055 100644
--- a/qemu/include/glib_compat.h
+++ b/qemu/include/glib_compat.h
@@ -74,9 +74,12 @@ typedef struct _GList {
struct _GList *prev;
} GList;
+GList* g_list_append(GList *list, gpointer data);
GList *g_list_first(GList *list);
+GList* g_list_last(GList *list);
void g_list_foreach(GList *list, GFunc func, gpointer user_data);
void g_list_free(GList *list);
+void g_list_free_full(GList *list, GDestroyNotify free_func);
GList* g_list_insert_before(GList *list, GList *sibling, gpointer data);
GList *g_list_insert_sorted(GList *list, gpointer data, GCompareFunc compare);
#define g_list_next(list) (list->next)
diff --git a/qemu/include/hw/boards.h b/qemu/include/hw/boards.h
index cf76a842..27efd7db 100644
--- a/qemu/include/hw/boards.h
+++ b/qemu/include/hw/boards.h
@@ -112,7 +112,6 @@ struct MachineState {
/*< public >*/
ram_addr_t ram_size;
ram_addr_t maxram_size;
- const char *cpu_model;
const char *cpu_type;
struct uc_struct *uc;
AccelState *accelerator;
diff --git a/qemu/include/qom/cpu.h b/qemu/include/qom/cpu.h
index 339ffb40..0345167c 100644
--- a/qemu/include/qom/cpu.h
+++ b/qemu/include/qom/cpu.h
@@ -538,26 +538,14 @@ ObjectClass *cpu_class_by_name(struct uc_struct *uc, const char *typename, const
CPUState *cpu_create(struct uc_struct *uc, const char *typename);
/**
- * cpu_parse_cpu_model:
- * @typename: The CPU base type or CPU type.
+ * parse_cpu_model:
* @cpu_model: The model string including optional parameters.
*
* processes optional parameters and registers them as global properties
*
* Returns: type of CPU to create or %NULL if an error occurred.
*/
-const char *cpu_parse_cpu_model(struct uc_struct *uc, const char *typename, const char *cpu_model);
-
-/**
- * cpu_generic_init:
- * @typename: The CPU base type.
- * @cpu_model: The model string including optional parameters.
- *
- * Instantiates a CPU, processes optional parameters and realizes the CPU.
- *
- * Returns: A #CPUState or %NULL if an error occurred.
- */
-CPUState *cpu_generic_init(struct uc_struct *uc, const char *typename, const char *cpu_model);
+const char *parse_cpu_model(struct uc_struct *uc, const char *cpu_model);
/**
* cpu_has_work:
diff --git a/qemu/m68k.h b/qemu/m68k.h
index 926f1bb3..ecd7499b 100644
--- a/qemu/m68k.h
+++ b/qemu/m68k.h
@@ -1947,6 +1947,7 @@
#define page_size_init page_size_init_m68k
#define par_write par_write_m68k
#define parse_array parse_array_m68k
+#define parse_cpu_model parse_cpu_model_m68k
#define parse_error parse_error_m68k
#define parse_escape parse_escape_m68k
#define parse_keyword parse_keyword_m68k
diff --git a/qemu/mips.h b/qemu/mips.h
index f35826b9..d66d73a6 100644
--- a/qemu/mips.h
+++ b/qemu/mips.h
@@ -1947,6 +1947,7 @@
#define page_size_init page_size_init_mips
#define par_write par_write_mips
#define parse_array parse_array_mips
+#define parse_cpu_model parse_cpu_model_mips
#define parse_error parse_error_mips
#define parse_escape parse_escape_mips
#define parse_keyword parse_keyword_mips
diff --git a/qemu/mips64.h b/qemu/mips64.h
index e10cb052..42e318b3 100644
--- a/qemu/mips64.h
+++ b/qemu/mips64.h
@@ -1947,6 +1947,7 @@
#define page_size_init page_size_init_mips64
#define par_write par_write_mips64
#define parse_array parse_array_mips64
+#define parse_cpu_model parse_cpu_model_mips64
#define parse_error parse_error_mips64
#define parse_escape parse_escape_mips64
#define parse_keyword parse_keyword_mips64
diff --git a/qemu/mips64el.h b/qemu/mips64el.h
index c3fd3f7a..b281b9aa 100644
--- a/qemu/mips64el.h
+++ b/qemu/mips64el.h
@@ -1947,6 +1947,7 @@
#define page_size_init page_size_init_mips64el
#define par_write par_write_mips64el
#define parse_array parse_array_mips64el
+#define parse_cpu_model parse_cpu_model_mips64el
#define parse_error parse_error_mips64el
#define parse_escape parse_escape_mips64el
#define parse_keyword parse_keyword_mips64el
diff --git a/qemu/mipsel.h b/qemu/mipsel.h
index 8e67aa8d..81df74e8 100644
--- a/qemu/mipsel.h
+++ b/qemu/mipsel.h
@@ -1947,6 +1947,7 @@
#define page_size_init page_size_init_mipsel
#define par_write par_write_mipsel
#define parse_array parse_array_mipsel
+#define parse_cpu_model parse_cpu_model_mipsel
#define parse_error parse_error_mipsel
#define parse_escape parse_escape_mipsel
#define parse_keyword parse_keyword_mipsel
diff --git a/qemu/powerpc.h b/qemu/powerpc.h
index f527cdca..4a0946bf 100644
--- a/qemu/powerpc.h
+++ b/qemu/powerpc.h
@@ -1947,6 +1947,7 @@
#define page_size_init page_size_init_powerpc
#define par_write par_write_powerpc
#define parse_array parse_array_powerpc
+#define parse_cpu_model parse_cpu_model_powerpc
#define parse_error parse_error_powerpc
#define parse_escape parse_escape_powerpc
#define parse_keyword parse_keyword_powerpc
diff --git a/qemu/qom/cpu.c b/qemu/qom/cpu.c
index 0946f5ce..fcb0e5f8 100644
--- a/qemu/qom/cpu.c
+++ b/qemu/qom/cpu.c
@@ -53,46 +53,6 @@ CPUState *cpu_create(struct uc_struct *uc, const char *typename)
return cpu;
}
-const char *cpu_parse_cpu_model(struct uc_struct *uc, const char *typename, const char *cpu_model)
-{
- ObjectClass *oc;
- CPUClass *cc;
- Error *err = NULL;
- gchar **model_pieces;
- const char *cpu_type;
-
- model_pieces = g_strsplit(cpu_model, ",", 2);
-
- oc = cpu_class_by_name(uc, typename, model_pieces[0]);
- if (oc == NULL) {
- g_strfreev(model_pieces);
- return NULL;
- }
-
- cpu_type = object_class_get_name(oc);
- cc = CPU_CLASS(uc, oc);
- cc->parse_features(uc, cpu_type, model_pieces[1], &err);
- g_strfreev(model_pieces);
- if (err != NULL) {
- error_free(err);
- return NULL;
- }
- return cpu_type;
-}
-
-CPUState *cpu_generic_init(struct uc_struct *uc, const char *typename, const char *cpu_model)
-{
- /* TODO: all callers of cpu_generic_init() need to be converted to
- * call cpu_parse_features() only once, before calling cpu_generic_init().
- */
- const char *cpu_type = cpu_parse_cpu_model(uc, typename, cpu_model);
-
- if (cpu_type) {
- return cpu_create(uc, cpu_type);
- }
- return NULL;
-}
-
bool cpu_paging_enabled(const CPUState *cpu)
{
CPUClass *cc = CPU_GET_CLASS(cpu->uc, cpu);
@@ -234,22 +194,17 @@ static ObjectClass *cpu_common_class_by_name(struct uc_struct *uc, const char *c
static void cpu_common_parse_features(struct uc_struct *uc, const char *typename, char *features,
Error **errp)
{
- char *featurestr; /* Single "key=value" string being parsed */
char *val;
+ /* Single "key=value" string being parsed */
+ char *featurestr = features ? strtok(features, ",") : NULL;
- /* TODO: all callers of ->parse_features() need to be changed to
- * call it only once, so we can remove this check (or change it
- * to assert(!cpu_globals_initialized).
- * Current callers of ->parse_features() are:
- * - cpu_generic_init()
- */
+ /* should be called only once, catch invalid users */
+ assert(!uc->cpu_globals_initialized);
if (uc->cpu_globals_initialized) {
return;
}
uc->cpu_globals_initialized = true;
- featurestr = features ? strtok(features, ",") : NULL;
-
while (featurestr) {
val = strchr(featurestr, '=');
if (val) {
diff --git a/qemu/sparc.h b/qemu/sparc.h
index 7f3d0ca4..f705f196 100644
--- a/qemu/sparc.h
+++ b/qemu/sparc.h
@@ -1947,6 +1947,7 @@
#define page_size_init page_size_init_sparc
#define par_write par_write_sparc
#define parse_array parse_array_sparc
+#define parse_cpu_model parse_cpu_model_sparc
#define parse_error parse_error_sparc
#define parse_escape parse_escape_sparc
#define parse_keyword parse_keyword_sparc
diff --git a/qemu/sparc64.h b/qemu/sparc64.h
index 8667a157..bca41e2c 100644
--- a/qemu/sparc64.h
+++ b/qemu/sparc64.h
@@ -1947,6 +1947,7 @@
#define page_size_init page_size_init_sparc64
#define par_write par_write_sparc64
#define parse_array parse_array_sparc64
+#define parse_cpu_model parse_cpu_model_sparc64
#define parse_error parse_error_sparc64
#define parse_escape parse_escape_sparc64
#define parse_keyword parse_keyword_sparc64
diff --git a/qemu/target/sparc/cpu.c b/qemu/target/sparc/cpu.c
index 831e7a6b..3b055a9f 100644
--- a/qemu/target/sparc/cpu.c
+++ b/qemu/target/sparc/cpu.c
@@ -514,105 +514,97 @@ static void print_features(FILE *f, fprintf_function cpu_fprintf,
}
#endif
-static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
+static void
+cpu_add_feat_as_prop(const char *typename, const char *name, const char *val)
{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
- if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
- *features |= 1 << i;
- return;
- }
- }
- //error_report("CPU feature %s not found", flagname);
+ // Unicorn: if'd out
+#if 0
+ GlobalProperty *prop = g_new0(typeof(*prop), 1);
+ prop->driver = typename;
+ prop->property = g_strdup(name);
+ prop->value = g_strdup(val);
+ prop->errp = &error_fatal;
+ qdev_prop_register_global(prop);
+#endif
}
-static void sparc_cpu_parse_features(CPUState *cs, char *features,
+/* Parse "+feature,-feature,feature=foo" CPU feature string */
+static void sparc_cpu_parse_features(struct uc_struct *uc, const char *typename, char *features,
Error **errp)
{
- SPARCCPU *cpu = SPARC_CPU(cs->uc, cs);
- sparc_def_t *cpu_def = &cpu->env.def;
- char *featurestr;
- uint32_t plus_features = 0;
- uint32_t minus_features = 0;
- uint64_t iu_version;
- uint32_t fpu_version, mmu_version, nwindows;
+ GList *l, *plus_features = NULL, *minus_features = NULL;
+ char *featurestr; /* Single 'key=value" string being parsed */
+ static bool cpu_globals_initialized;
- featurestr = features ? strtok(features, ",") : NULL;
- while (featurestr) {
- char *val;
+ if (cpu_globals_initialized) {
+ return;
+ }
+ cpu_globals_initialized = true;
+ if (!features) {
+ return;
+ }
+
+ for (featurestr = strtok(features, ",");
+ featurestr;
+ featurestr = strtok(NULL, ",")) {
+ const char *name;
+ const char *val = NULL;
+ char *eq = NULL;
+
+ /* Compatibility syntax: */
if (featurestr[0] == '+') {
- add_flagname_to_bitmaps(featurestr + 1, &plus_features);
+ plus_features = g_list_append(plus_features,
+ g_strdup(featurestr + 1));
+ continue;
} else if (featurestr[0] == '-') {
- add_flagname_to_bitmaps(featurestr + 1, &minus_features);
- } else if ((val = strchr(featurestr, '='))) {
- *val = 0; val++;
- if (!strcmp(featurestr, "iu_version")) {
- char *err;
+ minus_features = g_list_append(minus_features,
+ g_strdup(featurestr + 1));
+ continue;
+ }
- iu_version = strtoll(val, &err, 0);
- if (!*val || *err) {
- error_setg(errp, "bad numerical value %s", val);
- return;
- }
- cpu_def->iu_version = iu_version;
-#ifdef DEBUG_FEATURES
- fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version);
-#endif
- } else if (!strcmp(featurestr, "fpu_version")) {
- char *err;
+ eq = strchr(featurestr, '=');
+ name = featurestr;
+ if (eq) {
+ *eq++ = 0;
+ val = eq;
- fpu_version = strtol(val, &err, 0);
- if (!*val || *err) {
- error_setg(errp, "bad numerical value %s", val);
- return;
- }
- cpu_def->fpu_version = fpu_version;
-#ifdef DEBUG_FEATURES
- fprintf(stderr, "fpu_version %x\n", fpu_version);
-#endif
- } else if (!strcmp(featurestr, "mmu_version")) {
- char *err;
-
- mmu_version = strtol(val, &err, 0);
- if (!*val || *err) {
- error_setg(errp, "bad numerical value %s", val);
- return;
- }
- cpu_def->mmu_version = mmu_version;
-#ifdef DEBUG_FEATURES
- fprintf(stderr, "mmu_version %x\n", mmu_version);
-#endif
- } else if (!strcmp(featurestr, "nwindows")) {
- char *err;
-
- nwindows = strtol(val, &err, 0);
- if (!*val || *err || nwindows > MAX_NWINDOWS ||
- nwindows < MIN_NWINDOWS) {
- error_setg(errp, "bad numerical value %s", val);
- return;
- }
- cpu_def->nwindows = nwindows;
-#ifdef DEBUG_FEATURES
- fprintf(stderr, "nwindows %d\n", nwindows);
-#endif
- } else {
- error_setg(errp, "unrecognized feature %s", featurestr);
+ /*
+ * Temporarily, only +feat/-feat will be supported
+ * for boolean properties until we remove the
+ * minus-overrides-plus semantics and just follow
+ * the order options appear on the command-line.
+ *
+ * TODO: warn if user is relying on minus-override-plus semantics
+ * TODO: remove minus-override-plus semantics after
+ * warning for a few releases
+ */
+ if (!strcasecmp(val, "on") ||
+ !strcasecmp(val, "off") ||
+ !strcasecmp(val, "true") ||
+ !strcasecmp(val, "false")) {
+ error_setg(errp, "Boolean properties in format %s=%s"
+ " are not supported", name, val);
return;
}
} else {
- error_setg(errp, "feature string `%s' not in format "
- "(+feature|-feature|feature=xyz)", featurestr);
+ error_setg(errp, "Unsupported property format: %s", name);
return;
}
- featurestr = strtok(NULL, ",");
+ cpu_add_feat_as_prop(typename, name, val);
}
- cpu_def->features |= plus_features;
- cpu_def->features &= ~minus_features;
-#ifdef DEBUG_FEATURES
- print_features(stderr, fprintf, cpu_def->features, NULL);
-#endif
+
+ for (l = plus_features; l; l = l->next) {
+ const char *name = l->data;
+ cpu_add_feat_as_prop(typename, name, "on");
+ }
+ g_list_free_full(plus_features, g_free);
+
+ for (l = minus_features; l; l = l->next) {
+ const char *name = l->data;
+ cpu_add_feat_as_prop(typename, name, "off");
+ }
+ g_list_free_full(minus_features, g_free);
}
#if 0
diff --git a/qemu/vl.c b/qemu/vl.c
index b2b8d42f..4a0ef6e6 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -162,12 +162,8 @@ int machine_initialize(struct uc_struct *uc)
machine_class->max_cpus = 1;
configure_accelerator(current_machine);
- current_machine->cpu_model = NULL;
-
/* parse features once if machine provides default cpu_type */
- if (machine_class->default_cpu_type) {
- current_machine->cpu_type = machine_class->default_cpu_type;
- }
+ current_machine->cpu_type = machine_class->default_cpu_type;
return machine_class->init(uc, current_machine);
}
diff --git a/qemu/x86_64.h b/qemu/x86_64.h
index 8802fe8b..26eb361e 100644
--- a/qemu/x86_64.h
+++ b/qemu/x86_64.h
@@ -1947,6 +1947,7 @@
#define page_size_init page_size_init_x86_64
#define par_write par_write_x86_64
#define parse_array parse_array_x86_64
+#define parse_cpu_model parse_cpu_model_x86_64
#define parse_error parse_error_x86_64
#define parse_escape parse_escape_x86_64
#define parse_keyword parse_keyword_x86_64