mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 00:25:27 +00:00
Use cpu_create(type) instead of cpu_init(cpu_model)
With all targets defining CPU_RESOLVING_TYPE, refactor cpu_parse_cpu_model(type, cpu_model) to parse_cpu_model(cpu_model) so that callers won't have to know internal resolving cpu type. Place it in exec.c so it could be called from both target independed vl.c and *-user/main.c. That allows us to stop abusing cpu type from MachineClass::default_cpu_type as resolver class in vl.c which were confusing part of cpu_parse_cpu_model(). Also with new parse_cpu_model(), the last users of cpu_init() in null-machine.c and bsd/linux-user targets could be switched to cpu_create() API and cpu_init() API will be removed by follow up patch. With no longer users left remove MachineState::cpu_model field, new code should use MachineState::cpu_type instead and leave cpu_model parsing to generic code in vl.c. Backports commit 2278b93941d42c30e2950d4b8dff4943d064e7de from qemu
This commit is contained in:
parent
7fe1504224
commit
f8eeacb280
|
@ -1947,6 +1947,7 @@
|
||||||
#define page_size_init page_size_init_aarch64
|
#define page_size_init page_size_init_aarch64
|
||||||
#define par_write par_write_aarch64
|
#define par_write par_write_aarch64
|
||||||
#define parse_array parse_array_aarch64
|
#define parse_array parse_array_aarch64
|
||||||
|
#define parse_cpu_model parse_cpu_model_aarch64
|
||||||
#define parse_error parse_error_aarch64
|
#define parse_error parse_error_aarch64
|
||||||
#define parse_escape parse_escape_aarch64
|
#define parse_escape parse_escape_aarch64
|
||||||
#define parse_keyword parse_keyword_aarch64
|
#define parse_keyword parse_keyword_aarch64
|
||||||
|
|
|
@ -1947,6 +1947,7 @@
|
||||||
#define page_size_init page_size_init_aarch64eb
|
#define page_size_init page_size_init_aarch64eb
|
||||||
#define par_write par_write_aarch64eb
|
#define par_write par_write_aarch64eb
|
||||||
#define parse_array parse_array_aarch64eb
|
#define parse_array parse_array_aarch64eb
|
||||||
|
#define parse_cpu_model parse_cpu_model_aarch64eb
|
||||||
#define parse_error parse_error_aarch64eb
|
#define parse_error parse_error_aarch64eb
|
||||||
#define parse_escape parse_escape_aarch64eb
|
#define parse_escape parse_escape_aarch64eb
|
||||||
#define parse_keyword parse_keyword_aarch64eb
|
#define parse_keyword parse_keyword_aarch64eb
|
||||||
|
|
|
@ -1947,6 +1947,7 @@
|
||||||
#define page_size_init page_size_init_arm
|
#define page_size_init page_size_init_arm
|
||||||
#define par_write par_write_arm
|
#define par_write par_write_arm
|
||||||
#define parse_array parse_array_arm
|
#define parse_array parse_array_arm
|
||||||
|
#define parse_cpu_model parse_cpu_model_arm
|
||||||
#define parse_error parse_error_arm
|
#define parse_error parse_error_arm
|
||||||
#define parse_escape parse_escape_arm
|
#define parse_escape parse_escape_arm
|
||||||
#define parse_keyword parse_keyword_arm
|
#define parse_keyword parse_keyword_arm
|
||||||
|
|
|
@ -1947,6 +1947,7 @@
|
||||||
#define page_size_init page_size_init_armeb
|
#define page_size_init page_size_init_armeb
|
||||||
#define par_write par_write_armeb
|
#define par_write par_write_armeb
|
||||||
#define parse_array parse_array_armeb
|
#define parse_array parse_array_armeb
|
||||||
|
#define parse_cpu_model parse_cpu_model_armeb
|
||||||
#define parse_error parse_error_armeb
|
#define parse_error parse_error_armeb
|
||||||
#define parse_escape parse_escape_armeb
|
#define parse_escape parse_escape_armeb
|
||||||
#define parse_keyword parse_keyword_armeb
|
#define parse_keyword parse_keyword_armeb
|
||||||
|
|
23
qemu/exec.c
23
qemu/exec.c
|
@ -620,6 +620,29 @@ void cpu_exec_init(CPUState *cpu, void *opaque)
|
||||||
#endif
|
#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)
|
#if defined(CONFIG_USER_ONLY)
|
||||||
static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
|
static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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.
|
||||||
|
*
|
||||||
|
* <note><para>
|
||||||
|
* The return value is the new start of the list, which
|
||||||
|
* may have changed, so make sure you store the new value.
|
||||||
|
* </para></note>
|
||||||
|
*
|
||||||
|
* <note><para>
|
||||||
|
* 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.
|
||||||
|
* </para></note>
|
||||||
|
*
|
||||||
|
* |[
|
||||||
|
* /* 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 *g_list_insert_sorted(GList *list, gpointer data, GCompareFunc compare)
|
||||||
{
|
{
|
||||||
GList *i;
|
GList *i;
|
||||||
|
|
|
@ -1953,6 +1953,7 @@ symbols = (
|
||||||
'page_size_init',
|
'page_size_init',
|
||||||
'par_write',
|
'par_write',
|
||||||
'parse_array',
|
'parse_array',
|
||||||
|
'parse_cpu_model',
|
||||||
'parse_error',
|
'parse_error',
|
||||||
'parse_escape',
|
'parse_escape',
|
||||||
'parse_keyword',
|
'parse_keyword',
|
||||||
|
|
|
@ -22,9 +22,9 @@
|
||||||
static int tosa_init(struct uc_struct *uc, MachineState *machine)
|
static int tosa_init(struct uc_struct *uc, MachineState *machine)
|
||||||
{
|
{
|
||||||
if (uc->mode & UC_MODE_MCLASS) {
|
if (uc->mode & UC_MODE_MCLASS) {
|
||||||
uc->cpu = cpu_init(uc, "cortex-m3");
|
uc->cpu = cpu_create(uc, "cortex-m3");
|
||||||
} else {
|
} else {
|
||||||
uc->cpu = cpu_init(uc, "cortex-a15");
|
uc->cpu = cpu_create(uc, "cortex-a15");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -19,14 +19,10 @@
|
||||||
/* Board init. */
|
/* Board init. */
|
||||||
static int dummy_m68k_init(struct uc_struct *uc, MachineState *machine)
|
static int dummy_m68k_init(struct uc_struct *uc, MachineState *machine)
|
||||||
{
|
{
|
||||||
const char *cpu_model = machine->cpu_model;
|
|
||||||
CPUM68KState *env;
|
CPUM68KState *env;
|
||||||
|
const char *cpu_type = parse_cpu_model(uc, "cf4ve");
|
||||||
|
|
||||||
if (!cpu_model) {
|
uc->cpu = cpu_create(uc, cpu_type);
|
||||||
cpu_model = "cfv4e";
|
|
||||||
}
|
|
||||||
|
|
||||||
uc->cpu = cpu_init(uc, cpu_model);
|
|
||||||
if (!uc->cpu) {
|
if (!uc->cpu) {
|
||||||
fprintf(stderr, "Unable to find m68k CPU definition\n");
|
fprintf(stderr, "Unable to find m68k CPU definition\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -45,6 +41,7 @@ static void dummy_m68k_machine_init(struct uc_struct *uc, MachineClass *mc)
|
||||||
mc->init = dummy_m68k_init;
|
mc->init = dummy_m68k_init;
|
||||||
mc->is_default = 1;
|
mc->is_default = 1;
|
||||||
mc->arch = UC_ARCH_M68K;
|
mc->arch = UC_ARCH_M68K;
|
||||||
|
mc->default_cpu_type = M68K_CPU_TYPE_NAME("cfv4e");
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_MACHINE("dummy", dummy_m68k_machine_init)
|
DEFINE_MACHINE("dummy", dummy_m68k_machine_init)
|
||||||
|
|
|
@ -25,18 +25,14 @@
|
||||||
|
|
||||||
static int mips_r4k_init(struct uc_struct *uc, MachineState *machine)
|
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
|
#ifdef TARGET_MIPS64
|
||||||
cpu_model = "R4000";
|
const char *cpu_model = MIPS_CPU_TYPE_NAME("R4000");
|
||||||
#else
|
#else
|
||||||
cpu_model = "24Kf";
|
const char *cpu_model = MIPS_CPU_TYPE_NAME("24Kf");
|
||||||
#endif
|
#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) {
|
if (uc->cpu == NULL) {
|
||||||
fprintf(stderr, "Unable to find CPU definition\n");
|
fprintf(stderr, "Unable to find CPU definition\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -50,6 +46,11 @@ static void mips_machine_init(struct uc_struct *uc, MachineClass *mc)
|
||||||
mc->init = mips_r4k_init;
|
mc->init = mips_r4k_init;
|
||||||
mc->is_default = 1;
|
mc->is_default = 1;
|
||||||
mc->arch = UC_ARCH_MIPS;
|
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)
|
DEFINE_MACHINE("mips", mips_machine_init)
|
||||||
|
|
|
@ -38,15 +38,10 @@
|
||||||
|
|
||||||
static int leon3_generic_hw_init(struct uc_struct *uc, MachineState *machine)
|
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;
|
SPARCCPU *cpu;
|
||||||
|
|
||||||
/* Init CPU */
|
uc->cpu = cpu_create(uc, cpu_type);
|
||||||
if (!cpu_model) {
|
|
||||||
cpu_model = "LEON3";
|
|
||||||
}
|
|
||||||
|
|
||||||
uc->cpu = cpu_init(uc, cpu_model);
|
|
||||||
cpu = SPARC_CPU(uc, uc->cpu);
|
cpu = SPARC_CPU(uc, uc->cpu);
|
||||||
if (cpu == NULL) {
|
if (cpu == NULL) {
|
||||||
fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
|
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->init = leon3_generic_hw_init;
|
||||||
mc->is_default = 1;
|
mc->is_default = 1;
|
||||||
mc->arch = UC_ARCH_SPARC;
|
mc->arch = UC_ARCH_SPARC;
|
||||||
|
mc->default_cpu_type = SPARC_CPU_TYPE_NAME("LEON3");
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_MACHINE("leon3_generic", leon3_generic_machine_init)
|
DEFINE_MACHINE("leon3_generic", leon3_generic_machine_init)
|
||||||
|
|
|
@ -36,14 +36,10 @@
|
||||||
/* Sun4u hardware initialisation */
|
/* Sun4u hardware initialisation */
|
||||||
static int sun4u_init(struct uc_struct *uc, MachineState *machine)
|
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;
|
SPARCCPU *cpu;
|
||||||
|
|
||||||
if (cpu_model == NULL) {
|
uc->cpu = cpu_create(uc, cpu_type);
|
||||||
cpu_model = "Sun UltraSparc IV";
|
|
||||||
}
|
|
||||||
|
|
||||||
uc->cpu = cpu_init(uc, cpu_model);
|
|
||||||
cpu = SPARC_CPU(uc, uc->cpu);
|
cpu = SPARC_CPU(uc, uc->cpu);
|
||||||
if (cpu == NULL) {
|
if (cpu == NULL) {
|
||||||
fprintf(stderr, "Unable to find Sparc CPU definition\n");
|
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->max_cpus = 1; /* XXX for now */
|
||||||
mc->is_default = 1;
|
mc->is_default = 1;
|
||||||
mc->arch = UC_ARCH_SPARC;
|
mc->arch = UC_ARCH_SPARC;
|
||||||
|
mc->default_cpu_type = SPARC_CPU_TYPE_NAME("Sun UltraSparc IV");
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo sun4u_type = {
|
static const TypeInfo sun4u_type = {
|
||||||
|
|
|
@ -74,9 +74,12 @@ typedef struct _GList {
|
||||||
struct _GList *prev;
|
struct _GList *prev;
|
||||||
} GList;
|
} GList;
|
||||||
|
|
||||||
|
GList* g_list_append(GList *list, gpointer data);
|
||||||
GList *g_list_first(GList *list);
|
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_foreach(GList *list, GFunc func, gpointer user_data);
|
||||||
void g_list_free(GList *list);
|
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_before(GList *list, GList *sibling, gpointer data);
|
||||||
GList *g_list_insert_sorted(GList *list, gpointer data, GCompareFunc compare);
|
GList *g_list_insert_sorted(GList *list, gpointer data, GCompareFunc compare);
|
||||||
#define g_list_next(list) (list->next)
|
#define g_list_next(list) (list->next)
|
||||||
|
|
|
@ -112,7 +112,6 @@ struct MachineState {
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
ram_addr_t ram_size;
|
ram_addr_t ram_size;
|
||||||
ram_addr_t maxram_size;
|
ram_addr_t maxram_size;
|
||||||
const char *cpu_model;
|
|
||||||
const char *cpu_type;
|
const char *cpu_type;
|
||||||
struct uc_struct *uc;
|
struct uc_struct *uc;
|
||||||
AccelState *accelerator;
|
AccelState *accelerator;
|
||||||
|
|
|
@ -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);
|
CPUState *cpu_create(struct uc_struct *uc, const char *typename);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cpu_parse_cpu_model:
|
* parse_cpu_model:
|
||||||
* @typename: The CPU base type or CPU type.
|
|
||||||
* @cpu_model: The model string including optional parameters.
|
* @cpu_model: The model string including optional parameters.
|
||||||
*
|
*
|
||||||
* processes optional parameters and registers them as global properties
|
* processes optional parameters and registers them as global properties
|
||||||
*
|
*
|
||||||
* Returns: type of CPU to create or %NULL if an error occurred.
|
* 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);
|
const char *parse_cpu_model(struct uc_struct *uc, 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);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cpu_has_work:
|
* cpu_has_work:
|
||||||
|
|
|
@ -1947,6 +1947,7 @@
|
||||||
#define page_size_init page_size_init_m68k
|
#define page_size_init page_size_init_m68k
|
||||||
#define par_write par_write_m68k
|
#define par_write par_write_m68k
|
||||||
#define parse_array parse_array_m68k
|
#define parse_array parse_array_m68k
|
||||||
|
#define parse_cpu_model parse_cpu_model_m68k
|
||||||
#define parse_error parse_error_m68k
|
#define parse_error parse_error_m68k
|
||||||
#define parse_escape parse_escape_m68k
|
#define parse_escape parse_escape_m68k
|
||||||
#define parse_keyword parse_keyword_m68k
|
#define parse_keyword parse_keyword_m68k
|
||||||
|
|
|
@ -1947,6 +1947,7 @@
|
||||||
#define page_size_init page_size_init_mips
|
#define page_size_init page_size_init_mips
|
||||||
#define par_write par_write_mips
|
#define par_write par_write_mips
|
||||||
#define parse_array parse_array_mips
|
#define parse_array parse_array_mips
|
||||||
|
#define parse_cpu_model parse_cpu_model_mips
|
||||||
#define parse_error parse_error_mips
|
#define parse_error parse_error_mips
|
||||||
#define parse_escape parse_escape_mips
|
#define parse_escape parse_escape_mips
|
||||||
#define parse_keyword parse_keyword_mips
|
#define parse_keyword parse_keyword_mips
|
||||||
|
|
|
@ -1947,6 +1947,7 @@
|
||||||
#define page_size_init page_size_init_mips64
|
#define page_size_init page_size_init_mips64
|
||||||
#define par_write par_write_mips64
|
#define par_write par_write_mips64
|
||||||
#define parse_array parse_array_mips64
|
#define parse_array parse_array_mips64
|
||||||
|
#define parse_cpu_model parse_cpu_model_mips64
|
||||||
#define parse_error parse_error_mips64
|
#define parse_error parse_error_mips64
|
||||||
#define parse_escape parse_escape_mips64
|
#define parse_escape parse_escape_mips64
|
||||||
#define parse_keyword parse_keyword_mips64
|
#define parse_keyword parse_keyword_mips64
|
||||||
|
|
|
@ -1947,6 +1947,7 @@
|
||||||
#define page_size_init page_size_init_mips64el
|
#define page_size_init page_size_init_mips64el
|
||||||
#define par_write par_write_mips64el
|
#define par_write par_write_mips64el
|
||||||
#define parse_array parse_array_mips64el
|
#define parse_array parse_array_mips64el
|
||||||
|
#define parse_cpu_model parse_cpu_model_mips64el
|
||||||
#define parse_error parse_error_mips64el
|
#define parse_error parse_error_mips64el
|
||||||
#define parse_escape parse_escape_mips64el
|
#define parse_escape parse_escape_mips64el
|
||||||
#define parse_keyword parse_keyword_mips64el
|
#define parse_keyword parse_keyword_mips64el
|
||||||
|
|
|
@ -1947,6 +1947,7 @@
|
||||||
#define page_size_init page_size_init_mipsel
|
#define page_size_init page_size_init_mipsel
|
||||||
#define par_write par_write_mipsel
|
#define par_write par_write_mipsel
|
||||||
#define parse_array parse_array_mipsel
|
#define parse_array parse_array_mipsel
|
||||||
|
#define parse_cpu_model parse_cpu_model_mipsel
|
||||||
#define parse_error parse_error_mipsel
|
#define parse_error parse_error_mipsel
|
||||||
#define parse_escape parse_escape_mipsel
|
#define parse_escape parse_escape_mipsel
|
||||||
#define parse_keyword parse_keyword_mipsel
|
#define parse_keyword parse_keyword_mipsel
|
||||||
|
|
|
@ -1947,6 +1947,7 @@
|
||||||
#define page_size_init page_size_init_powerpc
|
#define page_size_init page_size_init_powerpc
|
||||||
#define par_write par_write_powerpc
|
#define par_write par_write_powerpc
|
||||||
#define parse_array parse_array_powerpc
|
#define parse_array parse_array_powerpc
|
||||||
|
#define parse_cpu_model parse_cpu_model_powerpc
|
||||||
#define parse_error parse_error_powerpc
|
#define parse_error parse_error_powerpc
|
||||||
#define parse_escape parse_escape_powerpc
|
#define parse_escape parse_escape_powerpc
|
||||||
#define parse_keyword parse_keyword_powerpc
|
#define parse_keyword parse_keyword_powerpc
|
||||||
|
|
|
@ -53,46 +53,6 @@ CPUState *cpu_create(struct uc_struct *uc, const char *typename)
|
||||||
return cpu;
|
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)
|
bool cpu_paging_enabled(const CPUState *cpu)
|
||||||
{
|
{
|
||||||
CPUClass *cc = CPU_GET_CLASS(cpu->uc, 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,
|
static void cpu_common_parse_features(struct uc_struct *uc, const char *typename, char *features,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
char *featurestr; /* Single "key=value" string being parsed */
|
|
||||||
char *val;
|
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
|
/* should be called only once, catch invalid users */
|
||||||
* call it only once, so we can remove this check (or change it
|
assert(!uc->cpu_globals_initialized);
|
||||||
* to assert(!cpu_globals_initialized).
|
|
||||||
* Current callers of ->parse_features() are:
|
|
||||||
* - cpu_generic_init()
|
|
||||||
*/
|
|
||||||
if (uc->cpu_globals_initialized) {
|
if (uc->cpu_globals_initialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uc->cpu_globals_initialized = true;
|
uc->cpu_globals_initialized = true;
|
||||||
|
|
||||||
featurestr = features ? strtok(features, ",") : NULL;
|
|
||||||
|
|
||||||
while (featurestr) {
|
while (featurestr) {
|
||||||
val = strchr(featurestr, '=');
|
val = strchr(featurestr, '=');
|
||||||
if (val) {
|
if (val) {
|
||||||
|
|
|
@ -1947,6 +1947,7 @@
|
||||||
#define page_size_init page_size_init_sparc
|
#define page_size_init page_size_init_sparc
|
||||||
#define par_write par_write_sparc
|
#define par_write par_write_sparc
|
||||||
#define parse_array parse_array_sparc
|
#define parse_array parse_array_sparc
|
||||||
|
#define parse_cpu_model parse_cpu_model_sparc
|
||||||
#define parse_error parse_error_sparc
|
#define parse_error parse_error_sparc
|
||||||
#define parse_escape parse_escape_sparc
|
#define parse_escape parse_escape_sparc
|
||||||
#define parse_keyword parse_keyword_sparc
|
#define parse_keyword parse_keyword_sparc
|
||||||
|
|
|
@ -1947,6 +1947,7 @@
|
||||||
#define page_size_init page_size_init_sparc64
|
#define page_size_init page_size_init_sparc64
|
||||||
#define par_write par_write_sparc64
|
#define par_write par_write_sparc64
|
||||||
#define parse_array parse_array_sparc64
|
#define parse_array parse_array_sparc64
|
||||||
|
#define parse_cpu_model parse_cpu_model_sparc64
|
||||||
#define parse_error parse_error_sparc64
|
#define parse_error parse_error_sparc64
|
||||||
#define parse_escape parse_escape_sparc64
|
#define parse_escape parse_escape_sparc64
|
||||||
#define parse_keyword parse_keyword_sparc64
|
#define parse_keyword parse_keyword_sparc64
|
||||||
|
|
|
@ -514,105 +514,97 @@ static void print_features(FILE *f, fprintf_function cpu_fprintf,
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
// Unicorn: if'd out
|
||||||
|
#if 0
|
||||||
for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
|
GlobalProperty *prop = g_new0(typeof(*prop), 1);
|
||||||
if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
|
prop->driver = typename;
|
||||||
*features |= 1 << i;
|
prop->property = g_strdup(name);
|
||||||
return;
|
prop->value = g_strdup(val);
|
||||||
}
|
prop->errp = &error_fatal;
|
||||||
}
|
qdev_prop_register_global(prop);
|
||||||
//error_report("CPU feature %s not found", flagname);
|
#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)
|
Error **errp)
|
||||||
{
|
{
|
||||||
SPARCCPU *cpu = SPARC_CPU(cs->uc, cs);
|
GList *l, *plus_features = NULL, *minus_features = NULL;
|
||||||
sparc_def_t *cpu_def = &cpu->env.def;
|
char *featurestr; /* Single 'key=value" string being parsed */
|
||||||
char *featurestr;
|
static bool cpu_globals_initialized;
|
||||||
uint32_t plus_features = 0;
|
|
||||||
uint32_t minus_features = 0;
|
|
||||||
uint64_t iu_version;
|
|
||||||
uint32_t fpu_version, mmu_version, nwindows;
|
|
||||||
|
|
||||||
featurestr = features ? strtok(features, ",") : NULL;
|
if (cpu_globals_initialized) {
|
||||||
while (featurestr) {
|
return;
|
||||||
char *val;
|
}
|
||||||
|
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] == '+') {
|
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] == '-') {
|
} else if (featurestr[0] == '-') {
|
||||||
add_flagname_to_bitmaps(featurestr + 1, &minus_features);
|
minus_features = g_list_append(minus_features,
|
||||||
} else if ((val = strchr(featurestr, '='))) {
|
g_strdup(featurestr + 1));
|
||||||
*val = 0; val++;
|
continue;
|
||||||
if (!strcmp(featurestr, "iu_version")) {
|
|
||||||
char *err;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
fpu_version = strtol(val, &err, 0);
|
eq = strchr(featurestr, '=');
|
||||||
if (!*val || *err) {
|
name = featurestr;
|
||||||
error_setg(errp, "bad numerical value %s", val);
|
if (eq) {
|
||||||
return;
|
*eq++ = 0;
|
||||||
}
|
val = eq;
|
||||||
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) {
|
* Temporarily, only +feat/-feat will be supported
|
||||||
error_setg(errp, "bad numerical value %s", val);
|
* for boolean properties until we remove the
|
||||||
return;
|
* minus-overrides-plus semantics and just follow
|
||||||
}
|
* the order options appear on the command-line.
|
||||||
cpu_def->mmu_version = mmu_version;
|
*
|
||||||
#ifdef DEBUG_FEATURES
|
* TODO: warn if user is relying on minus-override-plus semantics
|
||||||
fprintf(stderr, "mmu_version %x\n", mmu_version);
|
* TODO: remove minus-override-plus semantics after
|
||||||
#endif
|
* warning for a few releases
|
||||||
} else if (!strcmp(featurestr, "nwindows")) {
|
*/
|
||||||
char *err;
|
if (!strcasecmp(val, "on") ||
|
||||||
|
!strcasecmp(val, "off") ||
|
||||||
nwindows = strtol(val, &err, 0);
|
!strcasecmp(val, "true") ||
|
||||||
if (!*val || *err || nwindows > MAX_NWINDOWS ||
|
!strcasecmp(val, "false")) {
|
||||||
nwindows < MIN_NWINDOWS) {
|
error_setg(errp, "Boolean properties in format %s=%s"
|
||||||
error_setg(errp, "bad numerical value %s", val);
|
" are not supported", name, val);
|
||||||
return;
|
|
||||||
}
|
|
||||||
cpu_def->nwindows = nwindows;
|
|
||||||
#ifdef DEBUG_FEATURES
|
|
||||||
fprintf(stderr, "nwindows %d\n", nwindows);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
error_setg(errp, "unrecognized feature %s", featurestr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error_setg(errp, "feature string `%s' not in format "
|
error_setg(errp, "Unsupported property format: %s", name);
|
||||||
"(+feature|-feature|feature=xyz)", featurestr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
featurestr = strtok(NULL, ",");
|
cpu_add_feat_as_prop(typename, name, val);
|
||||||
}
|
}
|
||||||
cpu_def->features |= plus_features;
|
|
||||||
cpu_def->features &= ~minus_features;
|
for (l = plus_features; l; l = l->next) {
|
||||||
#ifdef DEBUG_FEATURES
|
const char *name = l->data;
|
||||||
print_features(stderr, fprintf, cpu_def->features, NULL);
|
cpu_add_feat_as_prop(typename, name, "on");
|
||||||
#endif
|
}
|
||||||
|
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
|
#if 0
|
||||||
|
|
|
@ -162,12 +162,8 @@ int machine_initialize(struct uc_struct *uc)
|
||||||
machine_class->max_cpus = 1;
|
machine_class->max_cpus = 1;
|
||||||
configure_accelerator(current_machine);
|
configure_accelerator(current_machine);
|
||||||
|
|
||||||
current_machine->cpu_model = NULL;
|
|
||||||
|
|
||||||
/* parse features once if machine provides default cpu_type */
|
/* 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);
|
return machine_class->init(uc, current_machine);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1947,6 +1947,7 @@
|
||||||
#define page_size_init page_size_init_x86_64
|
#define page_size_init page_size_init_x86_64
|
||||||
#define par_write par_write_x86_64
|
#define par_write par_write_x86_64
|
||||||
#define parse_array parse_array_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_error parse_error_x86_64
|
||||||
#define parse_escape parse_escape_x86_64
|
#define parse_escape parse_escape_x86_64
|
||||||
#define parse_keyword parse_keyword_x86_64
|
#define parse_keyword parse_keyword_x86_64
|
||||||
|
|
Loading…
Reference in a new issue