From d76fddaeeec674cab4802b585db6c9fb3a0066dc Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Thu, 7 Mar 2013 19:12:43 +0100 Subject: [PATCH 01/17] cpu: Fix qemu_get_cpu() to return NULL if CPU not found MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 55e5c2850 breaks CPU not found return value, and returns CPU corresponding to the last non NULL env. Fix it by returning CPU only if env is not NULL, otherwise CPU is not found and function should return NULL. Signed-off-by: Igor Mammedov Signed-off-by: Andreas Färber --- exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exec.c b/exec.c index 46a283071a..0a96ddbc93 100644 --- a/exec.c +++ b/exec.c @@ -260,7 +260,7 @@ CPUState *qemu_get_cpu(int index) env = env->next_cpu; } - return cpu; + return env ? cpu : NULL; } void cpu_exec_init(CPUArchState *env) From 1c8bb3cc7b98ad07a028567b86fc6baa5c5a0b7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 15 Feb 2013 17:01:09 +0100 Subject: [PATCH 02/17] monitor: Use qemu_get_cpu() in monitor_set_cpu() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No functional change, just a reduction of CPU loops. The mon_cpu field is left untouched for now since changing that requires a number of larger prerequisites, including cpu_synchronize_state() and mon_get_cpu(). Reviewed-by: Luiz Capitulino Reviewed-by: Markus Armbruster Signed-off-by: Andreas Färber --- monitor.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/monitor.c b/monitor.c index c48530bd55..ab05c49abb 100644 --- a/monitor.c +++ b/monitor.c @@ -855,17 +855,14 @@ EventInfoList *qmp_query_events(Error **errp) /* set the current CPU defined by the user */ int monitor_set_cpu(int cpu_index) { - CPUArchState *env; CPUState *cpu; - for (env = first_cpu; env != NULL; env = env->next_cpu) { - cpu = ENV_GET_CPU(env); - if (cpu->cpu_index == cpu_index) { - cur_mon->mon_cpu = env; - return 0; - } + cpu = qemu_get_cpu(cpu_index); + if (cpu == NULL) { + return -1; } - return -1; + cur_mon->mon_cpu = cpu->env_ptr; + return 0; } static CPUArchState *mon_get_cpu(void) From 151d1322a3a0c865089c09aeb50f18215121921a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 15 Feb 2013 15:41:49 +0100 Subject: [PATCH 03/17] cpus: Replace open-coded CPU loop in qmp_memsave() with qemu_get_cpu() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No functional change, just less usages of first_cpu and next_cpu fields. env is passed to cpu_memory_rw_debug(), which in turn passes it to target-specific cpu_get_phys_page_debug(). Changing both would be a larger refactoring, so defer that by using env_ptr for now. Reviewed-by: Luiz Capitulino Signed-off-by: Andreas Färber --- cpus.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/cpus.c b/cpus.c index c4b021dd2e..46355c1321 100644 --- a/cpus.c +++ b/cpus.c @@ -1241,18 +1241,13 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename, cpu_index = 0; } - for (env = first_cpu; env; env = env->next_cpu) { - cpu = ENV_GET_CPU(env); - if (cpu_index == cpu->cpu_index) { - break; - } - } - - if (env == NULL) { + cpu = qemu_get_cpu(cpu_index); + if (cpu == NULL) { error_set(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index", "a CPU number"); return; } + env = cpu->env_ptr; f = fopen(filename, "wb"); if (!f) { From c1b382e77d8693955d8838c19b33aeb214724f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Mon, 19 Nov 2012 02:42:18 +0100 Subject: [PATCH 04/17] target-sh4: Introduce SuperHCPU subclasses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Store legacy name in SuperHCPUClass for -cpu ? and for case-insensitive class lookup. List CPUs by iterating over TYPE_SUPERH_CPU subclasses. Signed-off-by: Andreas Färber --- target-sh4/cpu-qom.h | 7 ++ target-sh4/cpu.c | 180 ++++++++++++++++++++++++++++++++++++++++- target-sh4/translate.c | 84 ------------------- 3 files changed, 186 insertions(+), 85 deletions(-) diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h index f4e8976478..19d8b084ff 100644 --- a/target-sh4/cpu-qom.h +++ b/target-sh4/cpu-qom.h @@ -24,6 +24,10 @@ #define TYPE_SUPERH_CPU "superh-cpu" +#define TYPE_SH7750R_CPU "sh7750r-" TYPE_SUPERH_CPU +#define TYPE_SH7751R_CPU "sh7751r-" TYPE_SUPERH_CPU +#define TYPE_SH7785_CPU "sh7785-" TYPE_SUPERH_CPU + #define SUPERH_CPU_CLASS(klass) \ OBJECT_CLASS_CHECK(SuperHCPUClass, (klass), TYPE_SUPERH_CPU) #define SUPERH_CPU(obj) \ @@ -35,6 +39,7 @@ * SuperHCPUClass: * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. + * @name: The name. * * A SuperH CPU model. */ @@ -45,6 +50,8 @@ typedef struct SuperHCPUClass { DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); + + const char *name; } SuperHCPUClass; /** diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index ef0e62195d..fba1534f86 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -54,6 +54,180 @@ static void superh_cpu_reset(CPUState *s) set_default_nan_mode(1, &env->fp_status); } +typedef struct SuperHCPUListState { + fprintf_function cpu_fprintf; + FILE *file; +} SuperHCPUListState; + +/* Sort alphabetically by type name. */ +static gint superh_cpu_list_compare(gconstpointer a, gconstpointer b) +{ + ObjectClass *class_a = (ObjectClass *)a; + ObjectClass *class_b = (ObjectClass *)b; + const char *name_a, *name_b; + + name_a = object_class_get_name(class_a); + name_b = object_class_get_name(class_b); + return strcmp(name_a, name_b); +} + +static void superh_cpu_list_entry(gpointer data, gpointer user_data) +{ + ObjectClass *oc = data; + SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); + SuperHCPUListState *s = user_data; + + (*s->cpu_fprintf)(s->file, "%s\n", + scc->name); +} + +void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf) +{ + SuperHCPUListState s = { + .cpu_fprintf = cpu_fprintf, + .file = f, + }; + GSList *list; + + list = object_class_get_list(TYPE_SUPERH_CPU, false); + list = g_slist_sort(list, superh_cpu_list_compare); + g_slist_foreach(list, superh_cpu_list_entry, &s); + g_slist_free(list); +} + +static gint superh_cpu_name_compare(gconstpointer a, gconstpointer b) +{ + const SuperHCPUClass *scc = SUPERH_CPU_CLASS(a); + const char *name = b; + + return strcasecmp(scc->name, name); +} + +static ObjectClass *superh_cpu_class_by_name(const char *cpu_model) +{ + ObjectClass *oc; + GSList *list, *item; + + if (cpu_model == NULL) { + return NULL; + } + if (strcasecmp(cpu_model, "any") == 0) { + return object_class_by_name(TYPE_SH7750R_CPU); + } + + oc = object_class_by_name(cpu_model); + if (oc != NULL && object_class_dynamic_cast(oc, TYPE_SUPERH_CPU) != NULL + && !object_class_is_abstract(oc)) { + return oc; + } + + oc = NULL; + list = object_class_get_list(TYPE_SUPERH_CPU, false); + item = g_slist_find_custom(list, cpu_model, superh_cpu_name_compare); + if (item != NULL) { + oc = item->data; + } + g_slist_free(list); + return oc; +} + +SuperHCPU *cpu_sh4_init(const char *cpu_model) +{ + SuperHCPU *cpu; + CPUSH4State *env; + ObjectClass *oc; + + oc = superh_cpu_class_by_name(cpu_model); + if (oc == NULL) { + return NULL; + } + cpu = SUPERH_CPU(object_new(object_class_get_name(oc))); + env = &cpu->env; + env->cpu_model_str = cpu_model; + + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); + + return cpu; +} + +static void sh7750r_cpu_initfn(Object *obj) +{ + SuperHCPU *cpu = SUPERH_CPU(obj); + CPUSH4State *env = &cpu->env; + + env->id = SH_CPU_SH7750R; + env->pvr = 0x00050000; + env->prr = 0x00000100; + env->cvr = 0x00110000; + env->features = SH_FEATURE_BCR3_AND_BCR4; +} + +static void sh7750r_class_init(ObjectClass *oc, void *data) +{ + SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); + + scc->name = "SH7750R"; +} + +static const TypeInfo sh7750r_type_info = { + .name = TYPE_SH7750R_CPU, + .parent = TYPE_SUPERH_CPU, + .class_init = sh7750r_class_init, + .instance_init = sh7750r_cpu_initfn, +}; + +static void sh7751r_cpu_initfn(Object *obj) +{ + SuperHCPU *cpu = SUPERH_CPU(obj); + CPUSH4State *env = &cpu->env; + + env->id = SH_CPU_SH7751R; + env->pvr = 0x04050005; + env->prr = 0x00000113; + env->cvr = 0x00110000; /* Neutered caches, should be 0x20480000 */ + env->features = SH_FEATURE_BCR3_AND_BCR4; +} + +static void sh7751r_class_init(ObjectClass *oc, void *data) +{ + SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); + + scc->name = "SH7751R"; +} + +static const TypeInfo sh7751r_type_info = { + .name = TYPE_SH7751R_CPU, + .parent = TYPE_SUPERH_CPU, + .class_init = sh7751r_class_init, + .instance_init = sh7751r_cpu_initfn, +}; + +static void sh7785_cpu_initfn(Object *obj) +{ + SuperHCPU *cpu = SUPERH_CPU(obj); + CPUSH4State *env = &cpu->env; + + env->id = SH_CPU_SH7785; + env->pvr = 0x10300700; + env->prr = 0x00000200; + env->cvr = 0x71440211; + env->features = SH_FEATURE_SH4A; +} + +static void sh7785_class_init(ObjectClass *oc, void *data) +{ + SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); + + scc->name = "SH7785"; +} + +static const TypeInfo sh7785_type_info = { + .name = TYPE_SH7785_CPU, + .parent = TYPE_SUPERH_CPU, + .class_init = sh7785_class_init, + .instance_init = sh7785_cpu_initfn, +}; + static void superh_cpu_realizefn(DeviceState *dev, Error **errp) { SuperHCPU *cpu = SUPERH_CPU(dev); @@ -98,6 +272,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data) scc->parent_reset = cc->reset; cc->reset = superh_cpu_reset; + cc->class_by_name = superh_cpu_class_by_name; dc->vmsd = &vmstate_sh_cpu; } @@ -106,7 +281,7 @@ static const TypeInfo superh_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(SuperHCPU), .instance_init = superh_cpu_initfn, - .abstract = false, + .abstract = true, .class_size = sizeof(SuperHCPUClass), .class_init = superh_cpu_class_init, }; @@ -114,6 +289,9 @@ static const TypeInfo superh_cpu_type_info = { static void superh_cpu_register_types(void) { type_register_static(&superh_cpu_type_info); + type_register_static(&sh7750r_type_info); + type_register_static(&sh7751r_type_info); + type_register_static(&sh7785_type_info); } type_init(superh_cpu_register_types) diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 7f300e3444..14fdb8fc2d 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -175,90 +175,6 @@ void cpu_dump_state(CPUSH4State * env, FILE * f, } } -typedef struct { - const char *name; - int id; - uint32_t pvr; - uint32_t prr; - uint32_t cvr; - uint32_t features; -} sh4_def_t; - -static sh4_def_t sh4_defs[] = { - { - .name = "SH7750R", - .id = SH_CPU_SH7750R, - .pvr = 0x00050000, - .prr = 0x00000100, - .cvr = 0x00110000, - .features = SH_FEATURE_BCR3_AND_BCR4, - }, { - .name = "SH7751R", - .id = SH_CPU_SH7751R, - .pvr = 0x04050005, - .prr = 0x00000113, - .cvr = 0x00110000, /* Neutered caches, should be 0x20480000 */ - .features = SH_FEATURE_BCR3_AND_BCR4, - }, { - .name = "SH7785", - .id = SH_CPU_SH7785, - .pvr = 0x10300700, - .prr = 0x00000200, - .cvr = 0x71440211, - .features = SH_FEATURE_SH4A, - }, -}; - -static const sh4_def_t *cpu_sh4_find_by_name(const char *name) -{ - int i; - - if (strcasecmp(name, "any") == 0) - return &sh4_defs[0]; - - for (i = 0; i < ARRAY_SIZE(sh4_defs); i++) - if (strcasecmp(name, sh4_defs[i].name) == 0) - return &sh4_defs[i]; - - return NULL; -} - -void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(sh4_defs); i++) - (*cpu_fprintf)(f, "%s\n", sh4_defs[i].name); -} - -static void cpu_register(CPUSH4State *env, const sh4_def_t *def) -{ - env->pvr = def->pvr; - env->prr = def->prr; - env->cvr = def->cvr; - env->id = def->id; -} - -SuperHCPU *cpu_sh4_init(const char *cpu_model) -{ - SuperHCPU *cpu; - CPUSH4State *env; - const sh4_def_t *def; - - def = cpu_sh4_find_by_name(cpu_model); - if (!def) - return NULL; - cpu = SUPERH_CPU(object_new(TYPE_SUPERH_CPU)); - env = &cpu->env; - env->features = def->features; - env->cpu_model_str = cpu_model; - cpu_register(env, def); - - object_property_set_bool(OBJECT(cpu), true, "realized", NULL); - - return cpu; -} - static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest) { TranslationBlock *tb; From b350ab758342c764a6ead6ef064b15a72c830808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Tue, 20 Nov 2012 16:15:47 +0100 Subject: [PATCH 05/17] target-sh4: Move PVR/PRR/CVR into SuperHCPUClass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They are never changed once initialized, and moving them to the class will allow to inspect them before instantiating. Signed-off-by: Andreas Färber --- hw/sh4/sh7750.c | 10 +++++++--- target-sh4/cpu-qom.h | 6 ++++++ target-sh4/cpu.c | 18 +++++++++--------- target-sh4/cpu.h | 3 --- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/hw/sh4/sh7750.c b/hw/sh4/sh7750.c index 6778c94f8e..e4d37ad6ac 100644 --- a/hw/sh4/sh7750.c +++ b/hw/sh4/sh7750.c @@ -255,6 +255,7 @@ static uint32_t sh7750_mem_readw(void *opaque, hwaddr addr) static uint32_t sh7750_mem_readl(void *opaque, hwaddr addr) { SH7750State *s = opaque; + SuperHCPUClass *scc; switch (addr) { case SH7750_BCR1_A7: @@ -288,11 +289,14 @@ static uint32_t sh7750_mem_readl(void *opaque, hwaddr addr) case SH7750_CCR_A7: return s->ccr; case 0x1f000030: /* Processor version */ - return s->cpu->pvr; + scc = SUPERH_CPU_GET_CLASS(s->cpu); + return scc->pvr; case 0x1f000040: /* Cache version */ - return s->cpu->cvr; + scc = SUPERH_CPU_GET_CLASS(s->cpu); + return scc->cvr; case 0x1f000044: /* Processor revision */ - return s->cpu->prr; + scc = SUPERH_CPU_GET_CLASS(s->cpu); + return scc->prr; default: error_access("long read", addr); abort(); diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h index 19d8b084ff..29628c8077 100644 --- a/target-sh4/cpu-qom.h +++ b/target-sh4/cpu-qom.h @@ -40,6 +40,9 @@ * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * @name: The name. + * @pvr: Processor Version Register + * @prr: Processor Revision Register + * @cvr: Cache Version Register * * A SuperH CPU model. */ @@ -52,6 +55,9 @@ typedef struct SuperHCPUClass { void (*parent_reset)(CPUState *cpu); const char *name; + uint32_t pvr; + uint32_t prr; + uint32_t cvr; } SuperHCPUClass; /** diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index fba1534f86..5251aa08a5 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -156,9 +156,6 @@ static void sh7750r_cpu_initfn(Object *obj) CPUSH4State *env = &cpu->env; env->id = SH_CPU_SH7750R; - env->pvr = 0x00050000; - env->prr = 0x00000100; - env->cvr = 0x00110000; env->features = SH_FEATURE_BCR3_AND_BCR4; } @@ -167,6 +164,9 @@ static void sh7750r_class_init(ObjectClass *oc, void *data) SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); scc->name = "SH7750R"; + scc->pvr = 0x00050000; + scc->prr = 0x00000100; + scc->cvr = 0x00110000; } static const TypeInfo sh7750r_type_info = { @@ -182,9 +182,6 @@ static void sh7751r_cpu_initfn(Object *obj) CPUSH4State *env = &cpu->env; env->id = SH_CPU_SH7751R; - env->pvr = 0x04050005; - env->prr = 0x00000113; - env->cvr = 0x00110000; /* Neutered caches, should be 0x20480000 */ env->features = SH_FEATURE_BCR3_AND_BCR4; } @@ -193,6 +190,9 @@ static void sh7751r_class_init(ObjectClass *oc, void *data) SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); scc->name = "SH7751R"; + scc->pvr = 0x04050005; + scc->prr = 0x00000113; + scc->cvr = 0x00110000; /* Neutered caches, should be 0x20480000 */ } static const TypeInfo sh7751r_type_info = { @@ -208,9 +208,6 @@ static void sh7785_cpu_initfn(Object *obj) CPUSH4State *env = &cpu->env; env->id = SH_CPU_SH7785; - env->pvr = 0x10300700; - env->prr = 0x00000200; - env->cvr = 0x71440211; env->features = SH_FEATURE_SH4A; } @@ -219,6 +216,9 @@ static void sh7785_class_init(ObjectClass *oc, void *data) SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); scc->name = "SH7785"; + scc->pvr = 0x10300700; + scc->prr = 0x00000200; + scc->cvr = 0x71440211; } static const TypeInfo sh7785_type_info = { diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index 49dcd9e7f3..f805778075 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -179,9 +179,6 @@ typedef struct CPUSH4State { CPU_COMMON int id; /* CPU model */ - uint32_t pvr; /* Processor Version Register */ - uint32_t prr; /* Processor Revision Register */ - uint32_t cvr; /* Cache Version Register */ void *intc_handle; int in_sleep; /* SR_BL ignored during sleep */ From d7650eab429a033c23947f20d1ae14c4d1e719a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Mon, 18 Feb 2013 21:41:59 +0100 Subject: [PATCH 06/17] vmstate: Make vmstate_register() static inline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids adding a duplicate stub for CONFIG_USER_ONLY. Suggested-by: Eduardo Habkost Reviewed-by: Eduardo Habkost Reviewed-by: Juan Quintela Signed-off-by: Andreas Färber --- include/migration/vmstate.h | 12 ++++++++++-- savevm.c | 7 ------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index a64db941bc..20db76fdf7 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -638,12 +638,20 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, void *opaque, int version_id); void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd, void *opaque); -int vmstate_register(DeviceState *dev, int instance_id, - const VMStateDescription *vmsd, void *base); + int vmstate_register_with_alias_id(DeviceState *dev, int instance_id, const VMStateDescription *vmsd, void *base, int alias_id, int required_for_version); + +static inline int vmstate_register(DeviceState *dev, int instance_id, + const VMStateDescription *vmsd, + void *opaque) +{ + return vmstate_register_with_alias_id(dev, instance_id, vmsd, + opaque, -1, 0); +} + void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd, void *opaque); diff --git a/savevm.c b/savevm.c index 147e2d232e..35c8d1e445 100644 --- a/savevm.c +++ b/savevm.c @@ -1423,13 +1423,6 @@ int vmstate_register_with_alias_id(DeviceState *dev, int instance_id, return 0; } -int vmstate_register(DeviceState *dev, int instance_id, - const VMStateDescription *vmsd, void *opaque) -{ - return vmstate_register_with_alias_id(dev, instance_id, vmsd, - opaque, -1, 0); -} - void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd, void *opaque) { From c71c3e99b8897323af8c2fe0b9851610cd148538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Mon, 18 Feb 2013 17:56:20 +0100 Subject: [PATCH 07/17] stubs: Add a vmstate_dummy struct for CONFIG_USER_ONLY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Juan Quintela Reviewed-by: Eduardo Habkost Signed-off-by: Andreas Färber --- include/migration/vmstate.h | 4 ++++ stubs/vmstate.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 20db76fdf7..6666d27b25 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -134,6 +134,10 @@ struct VMStateDescription { const VMStateSubsection *subsections; }; +#ifdef CONFIG_USER_ONLY +extern const VMStateDescription vmstate_dummy; +#endif + extern const VMStateInfo vmstate_info_bool; extern const VMStateInfo vmstate_info_int8; diff --git a/stubs/vmstate.c b/stubs/vmstate.c index 3682af599e..778bc3fc69 100644 --- a/stubs/vmstate.c +++ b/stubs/vmstate.c @@ -1,6 +1,8 @@ #include "qemu-common.h" #include "migration/vmstate.h" +const VMStateDescription vmstate_dummy = {}; + int vmstate_register_with_alias_id(DeviceState *dev, int instance_id, const VMStateDescription *vmsd, From b170fce3dd06372f7bfec9a780ebcb1fce6d57e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 20 Jan 2013 20:23:22 +0100 Subject: [PATCH 08/17] cpu: Register VMStateDescription through CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In comparison to DeviceClass::vmsd, CPU VMState is split in two, "cpu_common" and "cpu", and uses cpu_index as instance_id instead of -1. Therefore add a CPU-specific CPUClass::vmsd field. Unlike the legacy CPUArchState registration, rather register CPUState. Signed-off-by: Juan Quintela Signed-off-by: Andreas Färber Reviewed-by: Eduardo Habkost --- exec.c | 11 +++++++++-- include/qom/cpu.h | 3 +++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/exec.c b/exec.c index 0a96ddbc93..254ae620ce 100644 --- a/exec.c +++ b/exec.c @@ -219,7 +219,7 @@ void cpu_exec_init_all(void) #endif } -#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY) +#if !defined(CONFIG_USER_ONLY) static int cpu_common_post_load(void *opaque, int version_id) { @@ -245,6 +245,8 @@ static const VMStateDescription vmstate_cpu_common = { VMSTATE_END_OF_LIST() } }; +#else +#define vmstate_cpu_common vmstate_dummy #endif CPUState *qemu_get_cpu(int index) @@ -266,6 +268,7 @@ CPUState *qemu_get_cpu(int index) void cpu_exec_init(CPUArchState *env) { CPUState *cpu = ENV_GET_CPU(env); + CPUClass *cc = CPU_GET_CLASS(cpu); CPUArchState **penv; int cpu_index; @@ -290,11 +293,15 @@ void cpu_exec_init(CPUArchState *env) #if defined(CONFIG_USER_ONLY) cpu_list_unlock(); #endif -#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY) vmstate_register(NULL, cpu_index, &vmstate_cpu_common, env); +#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY) register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION, cpu_save, cpu_load, env); + assert(cc->vmsd == NULL); #endif + if (cc->vmsd != NULL) { + vmstate_register(NULL, cpu_index, cc->vmsd, cpu); + } } #if defined(TARGET_HAS_ICE) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index ab2657c558..5b1b0d7ac4 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -44,6 +44,7 @@ typedef struct CPUState CPUState; * @class_by_name: Callback to map -cpu command line model name to an * instantiatable CPU type. * @reset: Callback to reset the #CPUState to its initial state. + * @vmsd: State description for migration. * * Represents a CPU family or model. */ @@ -55,6 +56,8 @@ typedef struct CPUClass { ObjectClass *(*class_by_name)(const char *cpu_model); void (*reset)(CPUState *cpu); + + const struct VMStateDescription *vmsd; } CPUClass; struct KVMState; From ca91b15f2d2e43eba8f9a3ec5090f0a11b861ba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 22 Feb 2013 21:50:10 +0100 Subject: [PATCH 09/17] cpu: Introduce cpu_class_set_vmsd() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This setter avoids redefining each VMStateDescription value to vmstate_dummy by not referencing the value for CONFIG_USER_ONLY. Suggested-by: Juan Quintela Reviewed-by: Eduardo Habkost Signed-off-by: Andreas Färber --- include/qom/cpu.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 5b1b0d7ac4..90c5f4579f 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -137,6 +137,27 @@ void cpu_reset(CPUState *cpu); */ ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model); +/** + * cpu_class_set_vmsd: + * @cc: CPU class + * @value: Value to set. Unused for %CONFIG_USER_ONLY. + * + * Sets #VMStateDescription for @cc. + * + * The @value argument is intentionally discarded for the non-softmmu targets + * to avoid linker errors or excessive preprocessor usage. If this behavior + * is undesired, you should assign #CPUState.vmsd directly instead. + */ +#ifndef CONFIG_USER_ONLY +static inline void cpu_class_set_vmsd(CPUClass *cc, + const struct VMStateDescription *value) +{ + cc->vmsd = value; +} +#else +#define cpu_class_set_vmsd(cc, value) ((cc)->vmsd = NULL) +#endif + /** * qemu_cpu_has_work: * @cpu: The vCPU to check. From f56e3a147683f0ed69d8339e497b7a36e3260c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 2 Feb 2013 13:38:08 +0100 Subject: [PATCH 10/17] target-i386: Update VMStateDescription to X86CPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expose vmstate_cpu as vmstate_x86_cpu and hook it up to CPUClass::vmsd. Adapt opaques and VMState fields to X86CPU. Drop cpu_{save,load}(). Reviewed-by: Eduardo Habkost Signed-off-by: Andreas Färber --- target-i386/cpu-qom.h | 4 + target-i386/cpu.c | 2 + target-i386/cpu.h | 2 - target-i386/machine.c | 207 +++++++++++++++++++++--------------------- 4 files changed, 109 insertions(+), 106 deletions(-) diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index b7bdcb6892..83c5318d3a 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -76,4 +76,8 @@ static inline X86CPU *x86_env_get_cpu(CPUX86State *env) #define ENV_OFFSET offsetof(X86CPU, env) +#ifndef CONFIG_USER_ONLY +extern const struct VMStateDescription vmstate_x86_cpu; +#endif + #endif diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 8fb736a5b4..8ff2fff9f7 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2250,6 +2250,8 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) xcc->parent_reset = cc->reset; cc->reset = x86_cpu_reset; + + cpu_class_set_vmsd(cc, &vmstate_x86_cpu); } static const TypeInfo x86_cpu_type_info = { diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 493dda8bb6..0c1c5c54ab 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -1092,8 +1092,6 @@ static inline CPUX86State *cpu_init(const char *cpu_model) #define cpu_list x86_cpu_list #define cpudef_setup x86_cpudef_setup -#define CPU_SAVE_VERSION 12 - /* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel #define MMU_MODE1_SUFFIX _user diff --git a/target-i386/machine.c b/target-i386/machine.c index 8df6a6b645..c9984b87a1 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -171,14 +171,16 @@ static const VMStateInfo vmstate_fpreg_1_no_mmx = { static bool fpregs_is_0(void *opaque, int version_id) { - CPUX86State *env = opaque; + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; return (env->fpregs_format_vmstate == 0); } static bool fpregs_is_1_mmx(void *opaque, int version_id) { - CPUX86State *env = opaque; + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; int guess_mmx; guess_mmx = ((env->fptag_vmstate == 0xff) && @@ -188,7 +190,8 @@ static bool fpregs_is_1_mmx(void *opaque, int version_id) static bool fpregs_is_1_no_mmx(void *opaque, int version_id) { - CPUX86State *env = opaque; + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; int guess_mmx; guess_mmx = ((env->fptag_vmstate == 0xff) && @@ -237,7 +240,8 @@ static const VMStateInfo vmstate_hack_uint64_as_uint32 = { static void cpu_pre_save(void *opaque) { - CPUX86State *env = opaque; + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; int i; /* FPU */ @@ -252,7 +256,8 @@ static void cpu_pre_save(void *opaque) static int cpu_post_load(void *opaque, int version_id) { - CPUX86State *env = opaque; + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; int i; /* XXX: restore FPU round state */ @@ -275,16 +280,16 @@ static int cpu_post_load(void *opaque, int version_id) static bool async_pf_msr_needed(void *opaque) { - CPUX86State *cpu = opaque; + X86CPU *cpu = opaque; - return cpu->async_pf_en_msr != 0; + return cpu->env.async_pf_en_msr != 0; } static bool pv_eoi_msr_needed(void *opaque) { - CPUX86State *cpu = opaque; + X86CPU *cpu = opaque; - return cpu->pv_eoi_en_msr != 0; + return cpu->env.pv_eoi_en_msr != 0; } static const VMStateDescription vmstate_async_pf_msr = { @@ -293,7 +298,7 @@ static const VMStateDescription vmstate_async_pf_msr = { .minimum_version_id = 1, .minimum_version_id_old = 1, .fields = (VMStateField []) { - VMSTATE_UINT64(async_pf_en_msr, CPUX86State), + VMSTATE_UINT64(env.async_pf_en_msr, X86CPU), VMSTATE_END_OF_LIST() } }; @@ -304,14 +309,15 @@ static const VMStateDescription vmstate_pv_eoi_msr = { .minimum_version_id = 1, .minimum_version_id_old = 1, .fields = (VMStateField []) { - VMSTATE_UINT64(pv_eoi_en_msr, CPUX86State), + VMSTATE_UINT64(env.pv_eoi_en_msr, X86CPU), VMSTATE_END_OF_LIST() } }; static bool fpop_ip_dp_needed(void *opaque) { - CPUX86State *env = opaque; + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; return env->fpop != 0 || env->fpip != 0 || env->fpdp != 0; } @@ -322,16 +328,17 @@ static const VMStateDescription vmstate_fpop_ip_dp = { .minimum_version_id = 1, .minimum_version_id_old = 1, .fields = (VMStateField []) { - VMSTATE_UINT16(fpop, CPUX86State), - VMSTATE_UINT64(fpip, CPUX86State), - VMSTATE_UINT64(fpdp, CPUX86State), + VMSTATE_UINT16(env.fpop, X86CPU), + VMSTATE_UINT64(env.fpip, X86CPU), + VMSTATE_UINT64(env.fpdp, X86CPU), VMSTATE_END_OF_LIST() } }; static bool tsc_adjust_needed(void *opaque) { - CPUX86State *env = opaque; + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; return env->tsc_adjust != 0; } @@ -342,14 +349,15 @@ static const VMStateDescription vmstate_msr_tsc_adjust = { .minimum_version_id = 1, .minimum_version_id_old = 1, .fields = (VMStateField[]) { - VMSTATE_UINT64(tsc_adjust, CPUX86State), + VMSTATE_UINT64(env.tsc_adjust, X86CPU), VMSTATE_END_OF_LIST() } }; static bool tscdeadline_needed(void *opaque) { - CPUX86State *env = opaque; + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; return env->tsc_deadline != 0; } @@ -360,14 +368,15 @@ static const VMStateDescription vmstate_msr_tscdeadline = { .minimum_version_id = 1, .minimum_version_id_old = 1, .fields = (VMStateField []) { - VMSTATE_UINT64(tsc_deadline, CPUX86State), + VMSTATE_UINT64(env.tsc_deadline, X86CPU), VMSTATE_END_OF_LIST() } }; static bool misc_enable_needed(void *opaque) { - CPUX86State *env = opaque; + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; return env->msr_ia32_misc_enable != MSR_IA32_MISC_ENABLE_DEFAULT; } @@ -378,111 +387,111 @@ static const VMStateDescription vmstate_msr_ia32_misc_enable = { .minimum_version_id = 1, .minimum_version_id_old = 1, .fields = (VMStateField []) { - VMSTATE_UINT64(msr_ia32_misc_enable, CPUX86State), + VMSTATE_UINT64(env.msr_ia32_misc_enable, X86CPU), VMSTATE_END_OF_LIST() } }; -static const VMStateDescription vmstate_cpu = { +const VMStateDescription vmstate_x86_cpu = { .name = "cpu", - .version_id = CPU_SAVE_VERSION, + .version_id = 12, .minimum_version_id = 3, .minimum_version_id_old = 3, .pre_save = cpu_pre_save, .post_load = cpu_post_load, .fields = (VMStateField []) { - VMSTATE_UINTTL_ARRAY(regs, CPUX86State, CPU_NB_REGS), - VMSTATE_UINTTL(eip, CPUX86State), - VMSTATE_UINTTL(eflags, CPUX86State), - VMSTATE_UINT32(hflags, CPUX86State), + VMSTATE_UINTTL_ARRAY(env.regs, X86CPU, CPU_NB_REGS), + VMSTATE_UINTTL(env.eip, X86CPU), + VMSTATE_UINTTL(env.eflags, X86CPU), + VMSTATE_UINT32(env.hflags, X86CPU), /* FPU */ - VMSTATE_UINT16(fpuc, CPUX86State), - VMSTATE_UINT16(fpus_vmstate, CPUX86State), - VMSTATE_UINT16(fptag_vmstate, CPUX86State), - VMSTATE_UINT16(fpregs_format_vmstate, CPUX86State), - VMSTATE_FP_REGS(fpregs, CPUX86State, 8), + VMSTATE_UINT16(env.fpuc, X86CPU), + VMSTATE_UINT16(env.fpus_vmstate, X86CPU), + VMSTATE_UINT16(env.fptag_vmstate, X86CPU), + VMSTATE_UINT16(env.fpregs_format_vmstate, X86CPU), + VMSTATE_FP_REGS(env.fpregs, X86CPU, 8), - VMSTATE_SEGMENT_ARRAY(segs, CPUX86State, 6), - VMSTATE_SEGMENT(ldt, CPUX86State), - VMSTATE_SEGMENT(tr, CPUX86State), - VMSTATE_SEGMENT(gdt, CPUX86State), - VMSTATE_SEGMENT(idt, CPUX86State), + VMSTATE_SEGMENT_ARRAY(env.segs, X86CPU, 6), + VMSTATE_SEGMENT(env.ldt, X86CPU), + VMSTATE_SEGMENT(env.tr, X86CPU), + VMSTATE_SEGMENT(env.gdt, X86CPU), + VMSTATE_SEGMENT(env.idt, X86CPU), - VMSTATE_UINT32(sysenter_cs, CPUX86State), + VMSTATE_UINT32(env.sysenter_cs, X86CPU), #ifdef TARGET_X86_64 /* Hack: In v7 size changed from 32 to 64 bits on x86_64 */ - VMSTATE_HACK_UINT32(sysenter_esp, CPUX86State, less_than_7), - VMSTATE_HACK_UINT32(sysenter_eip, CPUX86State, less_than_7), - VMSTATE_UINTTL_V(sysenter_esp, CPUX86State, 7), - VMSTATE_UINTTL_V(sysenter_eip, CPUX86State, 7), + VMSTATE_HACK_UINT32(env.sysenter_esp, X86CPU, less_than_7), + VMSTATE_HACK_UINT32(env.sysenter_eip, X86CPU, less_than_7), + VMSTATE_UINTTL_V(env.sysenter_esp, X86CPU, 7), + VMSTATE_UINTTL_V(env.sysenter_eip, X86CPU, 7), #else - VMSTATE_UINTTL(sysenter_esp, CPUX86State), - VMSTATE_UINTTL(sysenter_eip, CPUX86State), + VMSTATE_UINTTL(env.sysenter_esp, X86CPU), + VMSTATE_UINTTL(env.sysenter_eip, X86CPU), #endif - VMSTATE_UINTTL(cr[0], CPUX86State), - VMSTATE_UINTTL(cr[2], CPUX86State), - VMSTATE_UINTTL(cr[3], CPUX86State), - VMSTATE_UINTTL(cr[4], CPUX86State), - VMSTATE_UINTTL_ARRAY(dr, CPUX86State, 8), + VMSTATE_UINTTL(env.cr[0], X86CPU), + VMSTATE_UINTTL(env.cr[2], X86CPU), + VMSTATE_UINTTL(env.cr[3], X86CPU), + VMSTATE_UINTTL(env.cr[4], X86CPU), + VMSTATE_UINTTL_ARRAY(env.dr, X86CPU, 8), /* MMU */ - VMSTATE_INT32(a20_mask, CPUX86State), + VMSTATE_INT32(env.a20_mask, X86CPU), /* XMM */ - VMSTATE_UINT32(mxcsr, CPUX86State), - VMSTATE_XMM_REGS(xmm_regs, CPUX86State, CPU_NB_REGS), + VMSTATE_UINT32(env.mxcsr, X86CPU), + VMSTATE_XMM_REGS(env.xmm_regs, X86CPU, CPU_NB_REGS), #ifdef TARGET_X86_64 - VMSTATE_UINT64(efer, CPUX86State), - VMSTATE_UINT64(star, CPUX86State), - VMSTATE_UINT64(lstar, CPUX86State), - VMSTATE_UINT64(cstar, CPUX86State), - VMSTATE_UINT64(fmask, CPUX86State), - VMSTATE_UINT64(kernelgsbase, CPUX86State), + VMSTATE_UINT64(env.efer, X86CPU), + VMSTATE_UINT64(env.star, X86CPU), + VMSTATE_UINT64(env.lstar, X86CPU), + VMSTATE_UINT64(env.cstar, X86CPU), + VMSTATE_UINT64(env.fmask, X86CPU), + VMSTATE_UINT64(env.kernelgsbase, X86CPU), #endif - VMSTATE_UINT32_V(smbase, CPUX86State, 4), + VMSTATE_UINT32_V(env.smbase, X86CPU, 4), - VMSTATE_UINT64_V(pat, CPUX86State, 5), - VMSTATE_UINT32_V(hflags2, CPUX86State, 5), + VMSTATE_UINT64_V(env.pat, X86CPU, 5), + VMSTATE_UINT32_V(env.hflags2, X86CPU, 5), - VMSTATE_UINT32_TEST(halted, CPUX86State, version_is_5), - VMSTATE_UINT64_V(vm_hsave, CPUX86State, 5), - VMSTATE_UINT64_V(vm_vmcb, CPUX86State, 5), - VMSTATE_UINT64_V(tsc_offset, CPUX86State, 5), - VMSTATE_UINT64_V(intercept, CPUX86State, 5), - VMSTATE_UINT16_V(intercept_cr_read, CPUX86State, 5), - VMSTATE_UINT16_V(intercept_cr_write, CPUX86State, 5), - VMSTATE_UINT16_V(intercept_dr_read, CPUX86State, 5), - VMSTATE_UINT16_V(intercept_dr_write, CPUX86State, 5), - VMSTATE_UINT32_V(intercept_exceptions, CPUX86State, 5), - VMSTATE_UINT8_V(v_tpr, CPUX86State, 5), + VMSTATE_UINT32_TEST(env.halted, X86CPU, version_is_5), + VMSTATE_UINT64_V(env.vm_hsave, X86CPU, 5), + VMSTATE_UINT64_V(env.vm_vmcb, X86CPU, 5), + VMSTATE_UINT64_V(env.tsc_offset, X86CPU, 5), + VMSTATE_UINT64_V(env.intercept, X86CPU, 5), + VMSTATE_UINT16_V(env.intercept_cr_read, X86CPU, 5), + VMSTATE_UINT16_V(env.intercept_cr_write, X86CPU, 5), + VMSTATE_UINT16_V(env.intercept_dr_read, X86CPU, 5), + VMSTATE_UINT16_V(env.intercept_dr_write, X86CPU, 5), + VMSTATE_UINT32_V(env.intercept_exceptions, X86CPU, 5), + VMSTATE_UINT8_V(env.v_tpr, X86CPU, 5), /* MTRRs */ - VMSTATE_UINT64_ARRAY_V(mtrr_fixed, CPUX86State, 11, 8), - VMSTATE_UINT64_V(mtrr_deftype, CPUX86State, 8), - VMSTATE_MTRR_VARS(mtrr_var, CPUX86State, 8, 8), + VMSTATE_UINT64_ARRAY_V(env.mtrr_fixed, X86CPU, 11, 8), + VMSTATE_UINT64_V(env.mtrr_deftype, X86CPU, 8), + VMSTATE_MTRR_VARS(env.mtrr_var, X86CPU, 8, 8), /* KVM-related states */ - VMSTATE_INT32_V(interrupt_injected, CPUX86State, 9), - VMSTATE_UINT32_V(mp_state, CPUX86State, 9), - VMSTATE_UINT64_V(tsc, CPUX86State, 9), - VMSTATE_INT32_V(exception_injected, CPUX86State, 11), - VMSTATE_UINT8_V(soft_interrupt, CPUX86State, 11), - VMSTATE_UINT8_V(nmi_injected, CPUX86State, 11), - VMSTATE_UINT8_V(nmi_pending, CPUX86State, 11), - VMSTATE_UINT8_V(has_error_code, CPUX86State, 11), - VMSTATE_UINT32_V(sipi_vector, CPUX86State, 11), + VMSTATE_INT32_V(env.interrupt_injected, X86CPU, 9), + VMSTATE_UINT32_V(env.mp_state, X86CPU, 9), + VMSTATE_UINT64_V(env.tsc, X86CPU, 9), + VMSTATE_INT32_V(env.exception_injected, X86CPU, 11), + VMSTATE_UINT8_V(env.soft_interrupt, X86CPU, 11), + VMSTATE_UINT8_V(env.nmi_injected, X86CPU, 11), + VMSTATE_UINT8_V(env.nmi_pending, X86CPU, 11), + VMSTATE_UINT8_V(env.has_error_code, X86CPU, 11), + VMSTATE_UINT32_V(env.sipi_vector, X86CPU, 11), /* MCE */ - VMSTATE_UINT64_V(mcg_cap, CPUX86State, 10), - VMSTATE_UINT64_V(mcg_status, CPUX86State, 10), - VMSTATE_UINT64_V(mcg_ctl, CPUX86State, 10), - VMSTATE_UINT64_ARRAY_V(mce_banks, CPUX86State, MCE_BANKS_DEF *4, 10), + VMSTATE_UINT64_V(env.mcg_cap, X86CPU, 10), + VMSTATE_UINT64_V(env.mcg_status, X86CPU, 10), + VMSTATE_UINT64_V(env.mcg_ctl, X86CPU, 10), + VMSTATE_UINT64_ARRAY_V(env.mce_banks, X86CPU, MCE_BANKS_DEF * 4, 10), /* rdtscp */ - VMSTATE_UINT64_V(tsc_aux, CPUX86State, 11), + VMSTATE_UINT64_V(env.tsc_aux, X86CPU, 11), /* KVM pvclock msr */ - VMSTATE_UINT64_V(system_time_msr, CPUX86State, 11), - VMSTATE_UINT64_V(wall_clock_msr, CPUX86State, 11), + VMSTATE_UINT64_V(env.system_time_msr, X86CPU, 11), + VMSTATE_UINT64_V(env.wall_clock_msr, X86CPU, 11), /* XSAVE related fields */ - VMSTATE_UINT64_V(xcr0, CPUX86State, 12), - VMSTATE_UINT64_V(xstate_bv, CPUX86State, 12), - VMSTATE_YMMH_REGS_VARS(ymmh_regs, CPUX86State, CPU_NB_REGS, 12), + VMSTATE_UINT64_V(env.xcr0, X86CPU, 12), + VMSTATE_UINT64_V(env.xstate_bv, X86CPU, 12), + VMSTATE_YMMH_REGS_VARS(env.ymmh_regs, X86CPU, CPU_NB_REGS, 12), VMSTATE_END_OF_LIST() /* The above list is not sorted /wrt version numbers, watch out! */ }, @@ -510,13 +519,3 @@ static const VMStateDescription vmstate_cpu = { } } }; - -void cpu_save(QEMUFile *f, void *opaque) -{ - vmstate_save_state(f, &vmstate_cpu, opaque); -} - -int cpu_load(QEMUFile *f, void *opaque, int version_id) -{ - return vmstate_load_state(f, &vmstate_cpu, opaque, version_id); -} From 21317bc222ef4cdca594b1856eea62f3dfbbfb6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 25 Jan 2013 17:37:28 +0100 Subject: [PATCH 11/17] target-cris/helper.c: Update Coding Style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reindent, add missing braces and drop/adjust whitespace. Prepares for CPUArchState-to-CPUState field movements in cpu_cris_handle_mmu_fault(), do_interruptv10() and do_interrupt(). The remaining functions were so minor that they can be fixed in one go. Acked-by: Edgar E. Iglesias Signed-off-by: Andreas Färber --- target-cris/helper.c | 345 +++++++++++++++++++++---------------------- 1 file changed, 172 insertions(+), 173 deletions(-) diff --git a/target-cris/helper.c b/target-cris/helper.c index 6e75e9819e..de04143da8 100644 --- a/target-cris/helper.c +++ b/target-cris/helper.c @@ -36,19 +36,19 @@ #if defined(CONFIG_USER_ONLY) -void do_interrupt (CPUCRISState *env) +void do_interrupt(CPUCRISState *env) { - env->exception_index = -1; - env->pregs[PR_ERP] = env->pc; + env->exception_index = -1; + env->pregs[PR_ERP] = env->pc; } int cpu_cris_handle_mmu_fault(CPUCRISState * env, target_ulong address, int rw, int mmu_idx) { - env->exception_index = 0xaa; - env->pregs[PR_EDA] = address; - cpu_dump_state(env, stderr, fprintf, 0); - return 1; + env->exception_index = 0xaa; + env->pregs[PR_EDA] = address; + cpu_dump_state(env, stderr, fprintf, 0); + return 1; } #else /* !CONFIG_USER_ONLY */ @@ -56,211 +56,210 @@ int cpu_cris_handle_mmu_fault(CPUCRISState * env, target_ulong address, int rw, static void cris_shift_ccs(CPUCRISState *env) { - uint32_t ccs; - /* Apply the ccs shift. */ - ccs = env->pregs[PR_CCS]; - ccs = ((ccs & 0xc0000000) | ((ccs << 12) >> 2)) & ~0x3ff; - env->pregs[PR_CCS] = ccs; + uint32_t ccs; + /* Apply the ccs shift. */ + ccs = env->pregs[PR_CCS]; + ccs = ((ccs & 0xc0000000) | ((ccs << 12) >> 2)) & ~0x3ff; + env->pregs[PR_CCS] = ccs; } -int cpu_cris_handle_mmu_fault (CPUCRISState *env, target_ulong address, int rw, - int mmu_idx) +int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw, + int mmu_idx) { - struct cris_mmu_result res; - int prot, miss; - int r = -1; - target_ulong phy; + struct cris_mmu_result res; + int prot, miss; + int r = -1; + target_ulong phy; - D(printf ("%s addr=%x pc=%x rw=%x\n", __func__, address, env->pc, rw)); - miss = cris_mmu_translate(&res, env, address & TARGET_PAGE_MASK, - rw, mmu_idx, 0); - if (miss) - { - if (env->exception_index == EXCP_BUSFAULT) - cpu_abort(env, - "CRIS: Illegal recursive bus fault." - "addr=%x rw=%d\n", - address, rw); + D(printf("%s addr=%x pc=%x rw=%x\n", __func__, address, env->pc, rw)); + miss = cris_mmu_translate(&res, env, address & TARGET_PAGE_MASK, + rw, mmu_idx, 0); + if (miss) { + if (env->exception_index == EXCP_BUSFAULT) { + cpu_abort(env, + "CRIS: Illegal recursive bus fault." + "addr=%x rw=%d\n", + address, rw); + } - env->pregs[PR_EDA] = address; - env->exception_index = EXCP_BUSFAULT; - env->fault_vector = res.bf_vec; - r = 1; - } - else - { - /* - * Mask off the cache selection bit. The ETRAX busses do not - * see the top bit. - */ - phy = res.phy & ~0x80000000; - prot = res.prot; - tlb_set_page(env, address & TARGET_PAGE_MASK, phy, - prot, mmu_idx, TARGET_PAGE_SIZE); - r = 0; - } - if (r > 0) - D_LOG("%s returns %d irqreq=%x addr=%x phy=%x vec=%x pc=%x\n", - __func__, r, env->interrupt_request, address, res.phy, - res.bf_vec, env->pc); - return r; + env->pregs[PR_EDA] = address; + env->exception_index = EXCP_BUSFAULT; + env->fault_vector = res.bf_vec; + r = 1; + } else { + /* + * Mask off the cache selection bit. The ETRAX busses do not + * see the top bit. + */ + phy = res.phy & ~0x80000000; + prot = res.prot; + tlb_set_page(env, address & TARGET_PAGE_MASK, phy, + prot, mmu_idx, TARGET_PAGE_SIZE); + r = 0; + } + if (r > 0) { + D_LOG("%s returns %d irqreq=%x addr=%x phy=%x vec=%x pc=%x\n", + __func__, r, env->interrupt_request, address, res.phy, + res.bf_vec, env->pc); + } + return r; } static void do_interruptv10(CPUCRISState *env) { - int ex_vec = -1; + int ex_vec = -1; - D_LOG( "exception index=%d interrupt_req=%d\n", - env->exception_index, - env->interrupt_request); + D_LOG("exception index=%d interrupt_req=%d\n", + env->exception_index, + env->interrupt_request); - assert(!(env->pregs[PR_CCS] & PFIX_FLAG)); - switch (env->exception_index) - { - case EXCP_BREAK: - /* These exceptions are genereated by the core itself. - ERP should point to the insn following the brk. */ - ex_vec = env->trap_vector; - env->pregs[PRV10_BRP] = env->pc; - break; + assert(!(env->pregs[PR_CCS] & PFIX_FLAG)); + switch (env->exception_index) { + case EXCP_BREAK: + /* These exceptions are genereated by the core itself. + ERP should point to the insn following the brk. */ + ex_vec = env->trap_vector; + env->pregs[PRV10_BRP] = env->pc; + break; - case EXCP_NMI: - /* NMI is hardwired to vector zero. */ - ex_vec = 0; - env->pregs[PR_CCS] &= ~M_FLAG_V10; - env->pregs[PRV10_BRP] = env->pc; - break; + case EXCP_NMI: + /* NMI is hardwired to vector zero. */ + ex_vec = 0; + env->pregs[PR_CCS] &= ~M_FLAG_V10; + env->pregs[PRV10_BRP] = env->pc; + break; - case EXCP_BUSFAULT: - cpu_abort(env, "Unhandled busfault"); - break; + case EXCP_BUSFAULT: + cpu_abort(env, "Unhandled busfault"); + break; - default: - /* The interrupt controller gives us the vector. */ - ex_vec = env->interrupt_vector; - /* Normal interrupts are taken between - TB's. env->pc is valid here. */ - env->pregs[PR_ERP] = env->pc; - break; - } + default: + /* The interrupt controller gives us the vector. */ + ex_vec = env->interrupt_vector; + /* Normal interrupts are taken between + TB's. env->pc is valid here. */ + env->pregs[PR_ERP] = env->pc; + break; + } - if (env->pregs[PR_CCS] & U_FLAG) { - /* Swap stack pointers. */ - env->pregs[PR_USP] = env->regs[R_SP]; - env->regs[R_SP] = env->ksp; - } + if (env->pregs[PR_CCS] & U_FLAG) { + /* Swap stack pointers. */ + env->pregs[PR_USP] = env->regs[R_SP]; + env->regs[R_SP] = env->ksp; + } - /* Now that we are in kernel mode, load the handlers address. */ - env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4); - env->locked_irq = 1; - env->pregs[PR_CCS] |= F_FLAG_V10; /* set F. */ + /* Now that we are in kernel mode, load the handlers address. */ + env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4); + env->locked_irq = 1; + env->pregs[PR_CCS] |= F_FLAG_V10; /* set F. */ - qemu_log_mask(CPU_LOG_INT, "%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n", - __func__, env->pc, ex_vec, - env->pregs[PR_CCS], - env->pregs[PR_PID], - env->pregs[PR_ERP]); + qemu_log_mask(CPU_LOG_INT, "%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n", + __func__, env->pc, ex_vec, + env->pregs[PR_CCS], + env->pregs[PR_PID], + env->pregs[PR_ERP]); } void do_interrupt(CPUCRISState *env) { - int ex_vec = -1; + int ex_vec = -1; - if (env->pregs[PR_VR] < 32) - return do_interruptv10(env); + if (env->pregs[PR_VR] < 32) { + return do_interruptv10(env); + } - D_LOG( "exception index=%d interrupt_req=%d\n", - env->exception_index, - env->interrupt_request); + D_LOG("exception index=%d interrupt_req=%d\n", + env->exception_index, + env->interrupt_request); - switch (env->exception_index) - { - case EXCP_BREAK: - /* These exceptions are genereated by the core itself. - ERP should point to the insn following the brk. */ - ex_vec = env->trap_vector; - env->pregs[PR_ERP] = env->pc; - break; + switch (env->exception_index) { + case EXCP_BREAK: + /* These exceptions are genereated by the core itself. + ERP should point to the insn following the brk. */ + ex_vec = env->trap_vector; + env->pregs[PR_ERP] = env->pc; + break; - case EXCP_NMI: - /* NMI is hardwired to vector zero. */ - ex_vec = 0; - env->pregs[PR_CCS] &= ~M_FLAG_V32; - env->pregs[PR_NRP] = env->pc; - break; + case EXCP_NMI: + /* NMI is hardwired to vector zero. */ + ex_vec = 0; + env->pregs[PR_CCS] &= ~M_FLAG_V32; + env->pregs[PR_NRP] = env->pc; + break; - case EXCP_BUSFAULT: - ex_vec = env->fault_vector; - env->pregs[PR_ERP] = env->pc; - break; + case EXCP_BUSFAULT: + ex_vec = env->fault_vector; + env->pregs[PR_ERP] = env->pc; + break; - default: - /* The interrupt controller gives us the vector. */ - ex_vec = env->interrupt_vector; - /* Normal interrupts are taken between - TB's. env->pc is valid here. */ - env->pregs[PR_ERP] = env->pc; - break; - } + default: + /* The interrupt controller gives us the vector. */ + ex_vec = env->interrupt_vector; + /* Normal interrupts are taken between + TB's. env->pc is valid here. */ + env->pregs[PR_ERP] = env->pc; + break; + } - /* Fill in the IDX field. */ - env->pregs[PR_EXS] = (ex_vec & 0xff) << 8; + /* Fill in the IDX field. */ + env->pregs[PR_EXS] = (ex_vec & 0xff) << 8; - if (env->dslot) { - D_LOG("excp isr=%x PC=%x ds=%d SP=%x" - " ERP=%x pid=%x ccs=%x cc=%d %x\n", - ex_vec, env->pc, env->dslot, - env->regs[R_SP], - env->pregs[PR_ERP], env->pregs[PR_PID], - env->pregs[PR_CCS], - env->cc_op, env->cc_mask); - /* We loose the btarget, btaken state here so rexec the - branch. */ - env->pregs[PR_ERP] -= env->dslot; - /* Exception starts with dslot cleared. */ - env->dslot = 0; - } + if (env->dslot) { + D_LOG("excp isr=%x PC=%x ds=%d SP=%x" + " ERP=%x pid=%x ccs=%x cc=%d %x\n", + ex_vec, env->pc, env->dslot, + env->regs[R_SP], + env->pregs[PR_ERP], env->pregs[PR_PID], + env->pregs[PR_CCS], + env->cc_op, env->cc_mask); + /* We loose the btarget, btaken state here so rexec the + branch. */ + env->pregs[PR_ERP] -= env->dslot; + /* Exception starts with dslot cleared. */ + env->dslot = 0; + } - if (env->pregs[PR_CCS] & U_FLAG) { - /* Swap stack pointers. */ - env->pregs[PR_USP] = env->regs[R_SP]; - env->regs[R_SP] = env->ksp; - } + if (env->pregs[PR_CCS] & U_FLAG) { + /* Swap stack pointers. */ + env->pregs[PR_USP] = env->regs[R_SP]; + env->regs[R_SP] = env->ksp; + } - /* Apply the CRIS CCS shift. Clears U if set. */ - cris_shift_ccs(env); + /* Apply the CRIS CCS shift. Clears U if set. */ + cris_shift_ccs(env); - /* Now that we are in kernel mode, load the handlers address. - This load may not fault, real hw leaves that behaviour as - undefined. */ - env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4); + /* Now that we are in kernel mode, load the handlers address. + This load may not fault, real hw leaves that behaviour as + undefined. */ + env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4); - /* Clear the excption_index to avoid spurios hw_aborts for recursive - bus faults. */ - env->exception_index = -1; + /* Clear the excption_index to avoid spurios hw_aborts for recursive + bus faults. */ + env->exception_index = -1; - D_LOG("%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n", - __func__, env->pc, ex_vec, - env->pregs[PR_CCS], - env->pregs[PR_PID], - env->pregs[PR_ERP]); + D_LOG("%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n", + __func__, env->pc, ex_vec, + env->pregs[PR_CCS], + env->pregs[PR_PID], + env->pregs[PR_ERP]); } hwaddr cpu_get_phys_page_debug(CPUCRISState * env, target_ulong addr) { - uint32_t phy = addr; - struct cris_mmu_result res; - int miss; + uint32_t phy = addr; + struct cris_mmu_result res; + int miss; - miss = cris_mmu_translate(&res, env, addr, 0, 0, 1); - /* If D TLB misses, try I TLB. */ - if (miss) { - miss = cris_mmu_translate(&res, env, addr, 2, 0, 1); - } + miss = cris_mmu_translate(&res, env, addr, 0, 0, 1); + /* If D TLB misses, try I TLB. */ + if (miss) { + miss = cris_mmu_translate(&res, env, addr, 2, 0, 1); + } - if (!miss) - phy = res.phy; - D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy)); - return phy; + if (!miss) { + phy = res.phy; + } + D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy)); + return phy; } #endif From 259186a7d2f7184efc96ae99bc5658e6159f53ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 17 Jan 2013 18:51:17 +0100 Subject: [PATCH 12/17] cpu: Move halted and interrupt_request fields to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both fields are used in VMState, thus need to be moved together. Explicitly zero them on reset since they were located before breakpoints. Pass PowerPCCPU to kvmppc_handle_halt(). Signed-off-by: Andreas Färber --- cpu-exec.c | 34 ++++++++++---------- cpus.c | 4 +-- exec.c | 16 +++++----- gdbstub.c | 2 +- hw/arm/omap1.c | 7 +++-- hw/arm/pxa2xx_gpio.c | 3 +- hw/arm/pxa2xx_pic.c | 3 +- hw/i386/xen_machine_pv.c | 6 ++-- hw/openrisc/cputimer.c | 4 ++- hw/ppc/e500.c | 10 +++--- hw/ppc/ppc.c | 22 ++++++++----- hw/ppc/ppce500_spin.c | 2 +- hw/ppc/spapr.c | 10 ++++-- hw/ppc/spapr_hcall.c | 2 +- hw/ppc/spapr_rtas.c | 6 ++-- hw/s390x/s390-virtio.c | 14 ++++++--- hw/sparc/leon3.c | 5 +-- hw/sparc/sun4m.c | 21 +++++++------ hw/sparc64/sun4u.c | 15 ++++++--- hw/xtensa/pic_cpu.c | 8 +++-- include/exec/cpu-defs.h | 2 -- include/qom/cpu.h | 4 +++ kvm-all.c | 2 +- qom/cpu.c | 2 ++ target-alpha/cpu.h | 4 +-- target-alpha/translate.c | 3 +- target-arm/cpu.h | 4 +-- target-arm/helper.c | 4 ++- target-arm/op_helper.c | 4 ++- target-cris/cpu.h | 4 +-- target-cris/helper.c | 9 ++++-- target-cris/translate.c | 3 +- target-i386/cpu.c | 2 +- target-i386/cpu.h | 20 ++++++------ target-i386/helper.c | 12 ++++--- target-i386/kvm.c | 50 ++++++++++++++++-------------- target-i386/machine.c | 2 +- target-i386/misc_helper.c | 21 ++++++++----- target-i386/svm_helper.c | 9 ++++-- target-lm32/cpu.h | 4 +-- target-lm32/op_helper.c | 4 ++- target-m68k/cpu.h | 4 +-- target-m68k/op_helper.c | 4 ++- target-m68k/qregs.def | 1 - target-m68k/translate.c | 8 ++++- target-microblaze/cpu.h | 4 +-- target-mips/cpu.h | 4 +-- target-mips/op_helper.c | 10 ++++-- target-mips/translate.c | 4 +-- target-openrisc/cpu.h | 4 +-- target-openrisc/interrupt_helper.c | 3 +- target-openrisc/sys_helper.c | 3 +- target-ppc/cpu.h | 5 +-- target-ppc/excp_helper.c | 22 ++++++++----- target-ppc/helper_regs.h | 11 ++++--- target-ppc/kvm.c | 16 +++++----- target-ppc/translate.c | 3 +- target-s390x/cpu.c | 8 ++--- target-s390x/cpu.h | 5 +-- target-s390x/helper.c | 7 +++-- target-sh4/cpu.h | 4 +-- target-sh4/helper.c | 5 +-- target-sh4/op_helper.c | 4 ++- target-sparc/cpu.h | 5 +-- target-sparc/helper.c | 4 ++- target-unicore32/cpu.h | 4 +-- target-unicore32/softmmu.c | 3 +- target-xtensa/op_helper.c | 5 ++- translate-all.c | 10 +++--- xen-all.c | 10 +++--- 70 files changed, 319 insertions(+), 224 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 9092145d0b..c9e1a8208b 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -203,12 +203,12 @@ int cpu_exec(CPUArchState *env) uint8_t *tc_ptr; tcg_target_ulong next_tb; - if (env->halted) { + if (cpu->halted) { if (!cpu_has_work(cpu)) { return EXCP_HALTED; } - env->halted = 0; + cpu->halted = 0; } cpu_single_env = env; @@ -278,14 +278,14 @@ int cpu_exec(CPUArchState *env) next_tb = 0; /* force lookup of first TB */ for(;;) { - interrupt_request = env->interrupt_request; + interrupt_request = cpu->interrupt_request; if (unlikely(interrupt_request)) { if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) { /* Mask out external interrupts for this step. */ interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK; } if (interrupt_request & CPU_INTERRUPT_DEBUG) { - env->interrupt_request &= ~CPU_INTERRUPT_DEBUG; + cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG; env->exception_index = EXCP_DEBUG; cpu_loop_exit(env); } @@ -293,8 +293,8 @@ int cpu_exec(CPUArchState *env) defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \ defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || defined(TARGET_UNICORE32) if (interrupt_request & CPU_INTERRUPT_HALT) { - env->interrupt_request &= ~CPU_INTERRUPT_HALT; - env->halted = 1; + cpu->interrupt_request &= ~CPU_INTERRUPT_HALT; + cpu->halted = 1; env->exception_index = EXCP_HLT; cpu_loop_exit(env); } @@ -302,7 +302,7 @@ int cpu_exec(CPUArchState *env) #if defined(TARGET_I386) #if !defined(CONFIG_USER_ONLY) if (interrupt_request & CPU_INTERRUPT_POLL) { - env->interrupt_request &= ~CPU_INTERRUPT_POLL; + cpu->interrupt_request &= ~CPU_INTERRUPT_POLL; apic_poll_irq(env->apic_state); } #endif @@ -319,17 +319,17 @@ int cpu_exec(CPUArchState *env) !(env->hflags & HF_SMM_MASK)) { cpu_svm_check_intercept_param(env, SVM_EXIT_SMI, 0); - env->interrupt_request &= ~CPU_INTERRUPT_SMI; + cpu->interrupt_request &= ~CPU_INTERRUPT_SMI; do_smm_enter(env); next_tb = 0; } else if ((interrupt_request & CPU_INTERRUPT_NMI) && !(env->hflags2 & HF2_NMI_MASK)) { - env->interrupt_request &= ~CPU_INTERRUPT_NMI; + cpu->interrupt_request &= ~CPU_INTERRUPT_NMI; env->hflags2 |= HF2_NMI_MASK; do_interrupt_x86_hardirq(env, EXCP02_NMI, 1); next_tb = 0; } else if (interrupt_request & CPU_INTERRUPT_MCE) { - env->interrupt_request &= ~CPU_INTERRUPT_MCE; + cpu->interrupt_request &= ~CPU_INTERRUPT_MCE; do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0); next_tb = 0; } else if ((interrupt_request & CPU_INTERRUPT_HARD) && @@ -341,7 +341,8 @@ int cpu_exec(CPUArchState *env) int intno; cpu_svm_check_intercept_param(env, SVM_EXIT_INTR, 0); - env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ); + cpu->interrupt_request &= ~(CPU_INTERRUPT_HARD | + CPU_INTERRUPT_VIRQ); intno = cpu_get_pic_interrupt(env); qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno); do_interrupt_x86_hardirq(env, intno, 1); @@ -359,7 +360,7 @@ int cpu_exec(CPUArchState *env) intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector)); qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno); do_interrupt_x86_hardirq(env, intno, 1); - env->interrupt_request &= ~CPU_INTERRUPT_VIRQ; + cpu->interrupt_request &= ~CPU_INTERRUPT_VIRQ; next_tb = 0; #endif } @@ -370,8 +371,9 @@ int cpu_exec(CPUArchState *env) } if (interrupt_request & CPU_INTERRUPT_HARD) { ppc_hw_interrupt(env); - if (env->pending_interrupts == 0) - env->interrupt_request &= ~CPU_INTERRUPT_HARD; + if (env->pending_interrupts == 0) { + cpu->interrupt_request &= ~CPU_INTERRUPT_HARD; + } next_tb = 0; } #elif defined(TARGET_LM32) @@ -548,8 +550,8 @@ int cpu_exec(CPUArchState *env) #endif /* Don't use the cached interrupt_request value, do_interrupt may have updated the EXITTB flag. */ - if (env->interrupt_request & CPU_INTERRUPT_EXITTB) { - env->interrupt_request &= ~CPU_INTERRUPT_EXITTB; + if (cpu->interrupt_request & CPU_INTERRUPT_EXITTB) { + cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB; /* ensure that no TB jump will be modified as the program flow was changed */ next_tb = 0; diff --git a/cpus.c b/cpus.c index 46355c1321..8d47bfd85b 100644 --- a/cpus.c +++ b/cpus.c @@ -72,7 +72,7 @@ static bool cpu_thread_is_idle(CPUArchState *env) if (cpu->stopped || !runstate_is_running()) { return true; } - if (!env->halted || qemu_cpu_has_work(cpu) || + if (!cpu->halted || qemu_cpu_has_work(cpu) || kvm_async_interrupts_enabled()) { return false; } @@ -1198,7 +1198,7 @@ CpuInfoList *qmp_query_cpus(Error **errp) info->value = g_malloc0(sizeof(*info->value)); info->value->CPU = cpu->cpu_index; info->value->current = (env == first_cpu); - info->value->halted = env->halted; + info->value->halted = cpu->halted; info->value->thread_id = cpu->thread_id; #if defined(TARGET_I386) info->value->has_pc = true; diff --git a/exec.c b/exec.c index 254ae620ce..4462edf076 100644 --- a/exec.c +++ b/exec.c @@ -223,12 +223,12 @@ void cpu_exec_init_all(void) static int cpu_common_post_load(void *opaque, int version_id) { - CPUArchState *env = opaque; + CPUState *cpu = opaque; /* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the version_id is increased. */ - env->interrupt_request &= ~0x01; - tlb_flush(env, 1); + cpu->interrupt_request &= ~0x01; + tlb_flush(cpu->env_ptr, 1); return 0; } @@ -240,8 +240,8 @@ static const VMStateDescription vmstate_cpu_common = { .minimum_version_id_old = 1, .post_load = cpu_common_post_load, .fields = (VMStateField []) { - VMSTATE_UINT32(halted, CPUArchState), - VMSTATE_UINT32(interrupt_request, CPUArchState), + VMSTATE_UINT32(halted, CPUState), + VMSTATE_UINT32(interrupt_request, CPUState), VMSTATE_END_OF_LIST() } }; @@ -293,7 +293,7 @@ void cpu_exec_init(CPUArchState *env) #if defined(CONFIG_USER_ONLY) cpu_list_unlock(); #endif - vmstate_register(NULL, cpu_index, &vmstate_cpu_common, env); + vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu); #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY) register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION, cpu_save, cpu_load, env); @@ -494,7 +494,9 @@ void cpu_single_step(CPUArchState *env, int enabled) void cpu_reset_interrupt(CPUArchState *env, int mask) { - env->interrupt_request &= ~mask; + CPUState *cpu = ENV_GET_CPU(env); + + cpu->interrupt_request &= ~mask; } void cpu_exit(CPUArchState *env) diff --git a/gdbstub.c b/gdbstub.c index e414ad9157..43b7d4d00f 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2408,7 +2408,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) cpu_synchronize_state(env); len = snprintf((char *)mem_buf, sizeof(mem_buf), "CPU#%d [%s]", cpu->cpu_index, - env->halted ? "halted " : "running"); + cpu->halted ? "halted " : "running"); memtohex(buf, mem_buf, len); put_packet(s, buf); } diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c index 6f0a8ca074..7afd590ec7 100644 --- a/hw/arm/omap1.c +++ b/hw/arm/omap1.c @@ -1721,6 +1721,7 @@ static uint64_t omap_clkdsp_read(void *opaque, hwaddr addr, unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; + CPUState *cpu = CPU(s->cpu); if (size != 2) { return omap_badwidth_read16(opaque, addr); @@ -1737,8 +1738,9 @@ static uint64_t omap_clkdsp_read(void *opaque, hwaddr addr, return s->clkm.dsp_rstct2; case 0x18: /* DSP_SYSST */ + cpu = CPU(s->cpu); return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start | - (s->cpu->env.halted << 6); /* Quite useless... */ + (cpu->halted << 6); /* Quite useless... */ } OMAP_BAD_REG(addr); @@ -3754,8 +3756,9 @@ static void omap_setup_dsp_mapping(MemoryRegion *system_memory, void omap_mpu_wakeup(void *opaque, int irq, int req) { struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque; + CPUState *cpu = CPU(mpu->cpu); - if (mpu->cpu->env.halted) { + if (cpu->halted) { cpu_interrupt(&mpu->cpu->env, CPU_INTERRUPT_EXITTB); } } diff --git a/hw/arm/pxa2xx_gpio.c b/hw/arm/pxa2xx_gpio.c index eef8411e86..d2da928ac0 100644 --- a/hw/arm/pxa2xx_gpio.c +++ b/hw/arm/pxa2xx_gpio.c @@ -93,6 +93,7 @@ static const int pxa2xx_gpio_wake[PXA2XX_GPIO_BANKS] = { static void pxa2xx_gpio_set(void *opaque, int line, int level) { PXA2xxGPIOInfo *s = (PXA2xxGPIOInfo *) opaque; + CPUState *cpu = CPU(s->cpu); int bank; uint32_t mask; @@ -118,7 +119,7 @@ static void pxa2xx_gpio_set(void *opaque, int line, int level) pxa2xx_gpio_irq_update(s); /* Wake-up GPIOs */ - if (s->cpu->env.halted && (mask & ~s->dir[bank] & pxa2xx_gpio_wake[bank])) { + if (cpu->halted && (mask & ~s->dir[bank] & pxa2xx_gpio_wake[bank])) { cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_EXITTB); } } diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c index 145fc78c2f..b55ce479f4 100644 --- a/hw/arm/pxa2xx_pic.c +++ b/hw/arm/pxa2xx_pic.c @@ -46,8 +46,9 @@ static void pxa2xx_pic_update(void *opaque) { uint32_t mask[2]; PXA2xxPICState *s = (PXA2xxPICState *) opaque; + CPUState *cpu = CPU(s->cpu); - if (s->cpu->env.halted) { + if (cpu->halted) { mask[0] = s->int_pending[0] & (s->int_enabled[0] | s->int_idle); mask[1] = s->int_pending[1] & (s->int_enabled[1] | s->int_idle); if (mask[0] || mask[1]) { diff --git a/hw/i386/xen_machine_pv.c b/hw/i386/xen_machine_pv.c index a8177b6340..37ba34e5a9 100644 --- a/hw/i386/xen_machine_pv.c +++ b/hw/i386/xen_machine_pv.c @@ -36,7 +36,7 @@ static void xen_init_pv(QEMUMachineInitArgs *args) const char *kernel_cmdline = args->kernel_cmdline; const char *initrd_filename = args->initrd_filename; X86CPU *cpu; - CPUX86State *env; + CPUState *cs; DriveInfo *dinfo; int i; @@ -49,8 +49,8 @@ static void xen_init_pv(QEMUMachineInitArgs *args) #endif } cpu = cpu_x86_init(cpu_model); - env = &cpu->env; - env->halted = 1; + cs = CPU(cpu); + cs->halted = 1; /* Initialize backend core & drivers */ if (xen_be_init() != 0) { diff --git a/hw/openrisc/cputimer.c b/hw/openrisc/cputimer.c index f6c877f425..4144b34be7 100644 --- a/hw/openrisc/cputimer.c +++ b/hw/openrisc/cputimer.c @@ -73,8 +73,10 @@ static void openrisc_timer_cb(void *opaque) if ((cpu->env.ttmr & TTMR_IE) && qemu_timer_expired(cpu->env.timer, qemu_get_clock_ns(vm_clock))) { + CPUState *cs = CPU(cpu); + cpu->env.ttmr |= TTMR_IP; - cpu->env.interrupt_request |= CPU_INTERRUPT_TIMER; + cs->interrupt_request |= CPU_INTERRUPT_TIMER; } switch (cpu->env.ttmr & TTMR_M) { diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 451682cb83..fef9c5d842 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -420,26 +420,28 @@ static void mmubooke_create_initial_mapping(CPUPPCState *env) static void ppce500_cpu_reset_sec(void *opaque) { PowerPCCPU *cpu = opaque; + CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; - cpu_reset(CPU(cpu)); + cpu_reset(cs); /* Secondary CPU starts in halted state for now. Needs to change when implementing non-kernel boot. */ - env->halted = 1; + cs->halted = 1; env->exception_index = EXCP_HLT; } static void ppce500_cpu_reset(void *opaque) { PowerPCCPU *cpu = opaque; + CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; struct boot_info *bi = env->load_info; - cpu_reset(CPU(cpu)); + cpu_reset(cs); /* Set initial guest state. */ - env->halted = 0; + cs->halted = 0; env->gpr[1] = (16<<20) - 8; env->gpr[3] = bi->dt_base; env->nip = bi->entry; diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index c9437fc6a7..b2d7fe8df7 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -72,7 +72,7 @@ void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level) LOG_IRQ("%s: %p n_IRQ %d level %d => pending %08" PRIx32 "req %08x\n", __func__, env, n_IRQ, level, - env->pending_interrupts, env->interrupt_request); + env->pending_interrupts, CPU(cpu)->interrupt_request); } /* PowerPC 6xx / 7xx internal IRQ controller */ @@ -87,6 +87,8 @@ static void ppc6xx_set_irq(void *opaque, int pin, int level) cur_level = (env->irq_input_state >> pin) & 1; /* Don't generate spurious events */ if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { + CPUState *cs = CPU(cpu); + switch (pin) { case PPC6xx_INPUT_TBEN: /* Level sensitive - active high */ @@ -126,7 +128,7 @@ static void ppc6xx_set_irq(void *opaque, int pin, int level) /* XXX: Note that the only way to restart the CPU is to reset it */ if (level) { LOG_IRQ("%s: stop the CPU\n", __func__); - env->halted = 1; + cs->halted = 1; } break; case PPC6xx_INPUT_HRESET: @@ -174,6 +176,8 @@ static void ppc970_set_irq(void *opaque, int pin, int level) cur_level = (env->irq_input_state >> pin) & 1; /* Don't generate spurious events */ if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { + CPUState *cs = CPU(cpu); + switch (pin) { case PPC970_INPUT_INT: /* Level sensitive - active high */ @@ -203,11 +207,11 @@ static void ppc970_set_irq(void *opaque, int pin, int level) /* XXX: TODO: relay the signal to CKSTP_OUT pin */ if (level) { LOG_IRQ("%s: stop the CPU\n", __func__); - env->halted = 1; + cs->halted = 1; } else { LOG_IRQ("%s: restart the CPU\n", __func__); - env->halted = 0; - qemu_cpu_kick(CPU(cpu)); + cs->halted = 0; + qemu_cpu_kick(cs); } break; case PPC970_INPUT_HRESET: @@ -295,6 +299,8 @@ static void ppc40x_set_irq(void *opaque, int pin, int level) cur_level = (env->irq_input_state >> pin) & 1; /* Don't generate spurious events */ if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { + CPUState *cs = CPU(cpu); + switch (pin) { case PPC40x_INPUT_RESET_SYS: if (level) { @@ -332,11 +338,11 @@ static void ppc40x_set_irq(void *opaque, int pin, int level) /* Level sensitive - active low */ if (level) { LOG_IRQ("%s: stop the CPU\n", __func__); - env->halted = 1; + cs->halted = 1; } else { LOG_IRQ("%s: restart the CPU\n", __func__); - env->halted = 0; - qemu_cpu_kick(CPU(cpu)); + cs->halted = 0; + qemu_cpu_kick(cs); } break; case PPC40x_INPUT_DEBUG: diff --git a/hw/ppc/ppce500_spin.c b/hw/ppc/ppce500_spin.c index d904fbe176..1290d37bb9 100644 --- a/hw/ppc/ppce500_spin.c +++ b/hw/ppc/ppce500_spin.c @@ -112,7 +112,7 @@ static void spin_kick(void *data) map_start = ldq_p(&curspin->addr) & ~(map_size - 1); mmubooke_create_initial_mapping(env, 0, map_start, map_size); - env->halted = 0; + cpu->halted = 0; env->exception_index = -1; cpu->stopped = false; qemu_cpu_kick(cpu); diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index fd2411310c..f355a9bb84 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -617,6 +617,8 @@ static void spapr_reset_htab(sPAPREnvironment *spapr) static void ppc_spapr_reset(void) { + CPUState *first_cpu_cpu; + /* Reset the hash table & recalc the RMA */ spapr_reset_htab(spapr); @@ -627,9 +629,10 @@ static void ppc_spapr_reset(void) spapr->rtas_size); /* Set up the entry state */ + first_cpu_cpu = CPU(first_cpu); first_cpu->gpr[3] = spapr->fdt_addr; first_cpu->gpr[5] = 0; - first_cpu->halted = 0; + first_cpu_cpu->halted = 0; first_cpu->nip = spapr->entry_point; } @@ -637,14 +640,15 @@ static void ppc_spapr_reset(void) static void spapr_cpu_reset(void *opaque) { PowerPCCPU *cpu = opaque; + CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; - cpu_reset(CPU(cpu)); + cpu_reset(cs); /* All CPUs start halted. CPU0 is unhalted from the machine level * reset code and the rest are explicitly started up by the guest * using an RTAS call */ - env->halted = 1; + cs->halted = 1; env->spr[SPR_HIOR] = 0; diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 77c052fcb1..dd72743b52 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -543,7 +543,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr, env->msr |= (1ULL << MSR_EE); hreg_compute_hflags(env); if (!cpu_has_work(cs)) { - env->halted = 1; + cs->halted = 1; env->exception_index = EXCP_HLT; cs->exit_request = 1; } diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 5ec787f29d..a24e853d4d 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -145,7 +145,7 @@ static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr, continue; } - if (env->halted) { + if (cpu->halted) { rtas_st(rets, 1, 0); } else { rtas_st(rets, 1, 2); @@ -184,7 +184,7 @@ static void rtas_start_cpu(sPAPREnvironment *spapr, continue; } - if (!env->halted) { + if (!cpu->halted) { rtas_st(rets, 0, -1); return; } @@ -197,7 +197,7 @@ static void rtas_start_cpu(sPAPREnvironment *spapr, env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME); env->nip = start; env->gpr[3] = r3; - env->halted = 0; + cpu->halted = 0; qemu_cpu_kick(cpu); diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c index e25c330320..ca275bd9d7 100644 --- a/hw/s390x/s390-virtio.c +++ b/hw/s390x/s390-virtio.c @@ -132,23 +132,25 @@ static unsigned s390_running_cpus; void s390_add_running_cpu(S390CPU *cpu) { + CPUState *cs = CPU(cpu); CPUS390XState *env = &cpu->env; - if (env->halted) { + if (cs->halted) { s390_running_cpus++; - env->halted = 0; + cs->halted = 0; env->exception_index = -1; } } unsigned s390_del_running_cpu(S390CPU *cpu) { + CPUState *cs = CPU(cpu); CPUS390XState *env = &cpu->env; - if (env->halted == 0) { + if (cs->halted == 0) { assert(s390_running_cpus >= 1); s390_running_cpus--; - env->halted = 1; + cs->halted = 1; env->exception_index = EXCP_HLT; } return s390_running_cpus; @@ -183,11 +185,13 @@ void s390_init_cpus(const char *cpu_model, uint8_t *storage_keys) for (i = 0; i < smp_cpus; i++) { S390CPU *cpu; + CPUState *cs; cpu = cpu_s390x_init(cpu_model); + cs = CPU(cpu); ipi_states[i] = cpu; - cpu->env.halted = 1; + cs->halted = 1; cpu->env.exception_index = EXCP_HLT; cpu->env.storage_keys = storage_keys; } diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index f58061f8ed..a9167e6f93 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -49,11 +49,12 @@ typedef struct ResetData { static void main_cpu_reset(void *opaque) { ResetData *s = (ResetData *)opaque; + CPUState *cpu = CPU(s->cpu); CPUSPARCState *env = &s->cpu->env; - cpu_reset(CPU(s->cpu)); + cpu_reset(cpu); - env->halted = 0; + cpu->halted = 0; env->pc = s->entry; env->npc = s->entry + 4; } diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index 37bd04108d..a7e6966435 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -256,10 +256,11 @@ void cpu_check_irqs(CPUSPARCState *env) static void cpu_kick_irq(SPARCCPU *cpu) { CPUSPARCState *env = &cpu->env; + CPUState *cs = CPU(cpu); - env->halted = 0; + cs->halted = 0; cpu_check_irqs(env); - qemu_cpu_kick(CPU(cpu)); + qemu_cpu_kick(cs); } static void cpu_set_irq(void *opaque, int irq, int level) @@ -285,19 +286,19 @@ static void dummy_cpu_set_irq(void *opaque, int irq, int level) static void main_cpu_reset(void *opaque) { SPARCCPU *cpu = opaque; - CPUSPARCState *env = &cpu->env; + CPUState *cs = CPU(cpu); - cpu_reset(CPU(cpu)); - env->halted = 0; + cpu_reset(cs); + cs->halted = 0; } static void secondary_cpu_reset(void *opaque) { SPARCCPU *cpu = opaque; - CPUSPARCState *env = &cpu->env; + CPUState *cs = CPU(cpu); - cpu_reset(CPU(cpu)); - env->halted = 1; + cpu_reset(cs); + cs->halted = 1; } static void cpu_halt_signal(void *opaque, int irq, int level) @@ -826,6 +827,7 @@ static const TypeInfo ram_info = { static void cpu_devinit(const char *cpu_model, unsigned int id, uint64_t prom_addr, qemu_irq **cpu_irqs) { + CPUState *cs; SPARCCPU *cpu; CPUSPARCState *env; @@ -841,7 +843,8 @@ static void cpu_devinit(const char *cpu_model, unsigned int id, qemu_register_reset(main_cpu_reset, cpu); } else { qemu_register_reset(secondary_cpu_reset, cpu); - env->halted = 1; + cs = CPU(cpu); + cs->halted = 1; } *cpu_irqs = qemu_allocate_irqs(cpu_set_irq, cpu, MAX_PILS); env->prom_addr = prom_addr; diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index 51ffa1c09b..ae3c95b5cf 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -254,6 +254,7 @@ static uint64_t sun4u_load_kernel(const char *kernel_filename, void cpu_check_irqs(CPUSPARCState *env) { + CPUState *cs; uint32_t pil = env->pil_in | (env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER)); @@ -261,6 +262,7 @@ void cpu_check_irqs(CPUSPARCState *env) if (env->ivec_status & 0x20) { return; } + cs = CPU(sparc_env_get_cpu(env)); /* check if TM or SM in SOFTINT are set setting these also causes interrupt 14 */ if (env->softint & (SOFTINT_TIMER | SOFTINT_STIMER)) { @@ -270,7 +272,7 @@ void cpu_check_irqs(CPUSPARCState *env) /* The bit corresponding to psrpil is (1<< psrpil), the next bit is (2 << psrpil). */ if (pil < (2 << env->psrpil)){ - if (env->interrupt_request & CPU_INTERRUPT_HARD) { + if (cs->interrupt_request & CPU_INTERRUPT_HARD) { CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n", env->interrupt_index); env->interrupt_index = 0; @@ -302,7 +304,7 @@ void cpu_check_irqs(CPUSPARCState *env) break; } } - } else if (env->interrupt_request & CPU_INTERRUPT_HARD) { + } else if (cs->interrupt_request & CPU_INTERRUPT_HARD) { CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x " "current interrupt %x\n", pil, env->pil_in, env->softint, env->interrupt_index); @@ -313,22 +315,25 @@ void cpu_check_irqs(CPUSPARCState *env) static void cpu_kick_irq(SPARCCPU *cpu) { + CPUState *cs = CPU(cpu); CPUSPARCState *env = &cpu->env; - env->halted = 0; + cs->halted = 0; cpu_check_irqs(env); - qemu_cpu_kick(CPU(cpu)); + qemu_cpu_kick(cs); } static void cpu_set_ivec_irq(void *opaque, int irq, int level) { SPARCCPU *cpu = opaque; CPUSPARCState *env = &cpu->env; + CPUState *cs; if (level) { if (!(env->ivec_status & 0x20)) { CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq); - env->halted = 0; + cs = CPU(cpu); + cs->halted = 0; env->interrupt_index = TT_IVEC; env->ivec_status |= 0x20; env->ivec_data[0] = (0x1f << 6) | irq; diff --git a/hw/xtensa/pic_cpu.c b/hw/xtensa/pic_cpu.c index f485a1465c..12f66b6f55 100644 --- a/hw/xtensa/pic_cpu.c +++ b/hw/xtensa/pic_cpu.c @@ -47,6 +47,7 @@ void xtensa_advance_ccount(CPUXtensaState *env, uint32_t d) void check_interrupts(CPUXtensaState *env) { + CPUState *cs = CPU(xtensa_env_get_cpu(env)); int minlevel = xtensa_get_cintlevel(env); uint32_t int_set_enabled = env->sregs[INTSET] & env->sregs[INTENABLE]; int level; @@ -54,7 +55,7 @@ void check_interrupts(CPUXtensaState *env) /* If the CPU is halted advance CCOUNT according to the vm_clock time * elapsed since the moment when it was advanced last time. */ - if (env->halted) { + if (cs->halted) { int64_t now = qemu_get_clock_ns(vm_clock); xtensa_advance_ccount(env, @@ -127,11 +128,12 @@ static void xtensa_ccompare_cb(void *opaque) { XtensaCPU *cpu = opaque; CPUXtensaState *env = &cpu->env; + CPUState *cs = CPU(cpu); - if (env->halted) { + if (cs->halted) { env->halt_clock = qemu_get_clock_ns(vm_clock); xtensa_advance_ccount(env, env->wake_ccount - env->sregs[CCOUNT]); - if (!cpu_has_work(CPU(cpu))) { + if (!cpu_has_work(cs)) { env->sregs[CCOUNT] = env->wake_ccount + 1; xtensa_rearm_ccompare_timer(env); } diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 3dc96568ac..0ae967ae20 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -156,8 +156,6 @@ typedef struct CPUWatchpoint { accessed */ \ target_ulong mem_io_vaddr; /* target virtual addr at which the \ memory was accessed */ \ - uint32_t halted; /* Nonzero if the CPU is in suspend state */ \ - uint32_t interrupt_request; \ CPU_COMMON_TLB \ struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \ /* buffer for temporaries in the code generator */ \ diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 90c5f4579f..23c80b9251 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -72,6 +72,8 @@ struct kvm_run; * @host_tid: Host thread ID. * @running: #true if CPU is currently running (usermode). * @created: Indicates whether the CPU thread has been successfully created. + * @interrupt_request: Indicates a pending interrupt request. + * @halted: Nonzero if the CPU is in suspended state. * @stop: Indicates a pending stop request. * @stopped: Indicates the CPU has been artificially stopped. * @tcg_exit_req: Set to force TCG to stop executing linked TBs for this @@ -106,6 +108,7 @@ struct CPUState { bool stopped; volatile sig_atomic_t exit_request; volatile sig_atomic_t tcg_exit_req; + uint32_t interrupt_request; void *env_ptr; /* CPUArchState */ struct TranslationBlock *current_tb; @@ -117,6 +120,7 @@ struct CPUState { /* TODO Move common fields from CPUArchState here. */ int cpu_index; /* used by alpha TCG */ + uint32_t halted; /* used by alpha, cris, ppc TCG */ }; diff --git a/kvm-all.c b/kvm-all.c index 4decfdccd3..2b761e0a0d 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -830,7 +830,7 @@ static void kvm_handle_interrupt(CPUArchState *env, int mask) { CPUState *cpu = ENV_GET_CPU(env); - env->interrupt_request |= mask; + cpu->interrupt_request |= mask; if (!qemu_cpu_is_self(cpu)) { qemu_cpu_kick(cpu); diff --git a/qom/cpu.c b/qom/cpu.c index 0a2194d413..0aa9be793d 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -33,7 +33,9 @@ void cpu_reset(CPUState *cpu) static void cpu_common_reset(CPUState *cpu) { cpu->exit_request = 0; + cpu->interrupt_request = 0; cpu->current_tb = NULL; + cpu->halted = 0; } ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model) diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index f1db6518ce..90f78acc30 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -517,8 +517,6 @@ static inline void cpu_set_tls(CPUAlphaState *env, target_ulong newtls) static inline bool cpu_has_work(CPUState *cpu) { - CPUAlphaState *env = &ALPHA_CPU(cpu)->env; - /* Here we are checking to see if the CPU should wake up from HALT. We will have gotten into this state only for WTINT from PALmode. */ /* ??? I'm not sure how the IPL state works with WTINT to keep a CPU @@ -526,7 +524,7 @@ static inline bool cpu_has_work(CPUState *cpu) assume that if a CPU really wants to stay asleep, it will mask interrupts at the chipset level, which will prevent these bits from being set in the first place. */ - return env->interrupt_request & (CPU_INTERRUPT_HARD + return cpu->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER | CPU_INTERRUPT_SMP | CPU_INTERRUPT_MCHK); diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 657f5e1e5f..4db16db462 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -1686,7 +1686,8 @@ static ExitStatus gen_mtpr(DisasContext *ctx, int rb, int regno) case 253: /* WAIT */ tmp = tcg_const_i64(1); - tcg_gen_st32_i64(tmp, cpu_env, offsetof(CPUAlphaState, halted)); + tcg_gen_st32_i64(tmp, cpu_env, -offsetof(AlphaCPU, env) + + offsetof(CPUState, halted)); return gen_excp(ctx, EXCP_HLT, 0); case 252: diff --git a/target-arm/cpu.h b/target-arm/cpu.h index c28a0d94c3..957866c0e2 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -722,9 +722,7 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, static inline bool cpu_has_work(CPUState *cpu) { - CPUARMState *env = &ARM_CPU(cpu)->env; - - return env->interrupt_request & + return cpu->interrupt_request & (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB); } diff --git a/target-arm/helper.c b/target-arm/helper.c index 6cad936d3e..d7e22dda13 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1801,6 +1801,7 @@ static void do_interrupt_v7m(CPUARMState *env) /* Handle a CPU exception. */ void do_interrupt(CPUARMState *env) { + CPUState *cs; uint32_t addr; uint32_t mask; int new_mode; @@ -1907,7 +1908,8 @@ void do_interrupt(CPUARMState *env) } env->regs[14] = env->regs[15] + offset; env->regs[15] = addr; - env->interrupt_request |= CPU_INTERRUPT_EXITTB; + cs = CPU(arm_env_get_cpu(env)); + cs->interrupt_request |= CPU_INTERRUPT_EXITTB; } /* Check section/page access permissions. diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c index a52231346c..a918e5b27a 100644 --- a/target-arm/op_helper.c +++ b/target-arm/op_helper.c @@ -218,8 +218,10 @@ uint32_t HELPER(usat16)(CPUARMState *env, uint32_t x, uint32_t shift) void HELPER(wfi)(CPUARMState *env) { + CPUState *cs = CPU(arm_env_get_cpu(env)); + env->exception_index = EXCP_HLT; - env->halted = 1; + cs->halted = 1; cpu_loop_exit(env); } diff --git a/target-cris/cpu.h b/target-cris/cpu.h index ebf2d4027f..2fc7c5c772 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -289,9 +289,7 @@ void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf); static inline bool cpu_has_work(CPUState *cpu) { - CPUCRISState *env = &CRIS_CPU(cpu)->env; - - return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI); + return cpu->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI); } #include "exec/exec-all.h" diff --git a/target-cris/helper.c b/target-cris/helper.c index de04143da8..885f67fa33 100644 --- a/target-cris/helper.c +++ b/target-cris/helper.c @@ -66,6 +66,7 @@ static void cris_shift_ccs(CPUCRISState *env) int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw, int mmu_idx) { + D(CPUState *cpu = CPU(cris_env_get_cpu(env))); struct cris_mmu_result res; int prot, miss; int r = -1; @@ -99,7 +100,7 @@ int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw, } if (r > 0) { D_LOG("%s returns %d irqreq=%x addr=%x phy=%x vec=%x pc=%x\n", - __func__, r, env->interrupt_request, address, res.phy, + __func__, r, cpu->interrupt_request, address, res.phy, res.bf_vec, env->pc); } return r; @@ -107,11 +108,12 @@ int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw, static void do_interruptv10(CPUCRISState *env) { + D(CPUState *cs = CPU(cris_env_get_cpu(env))); int ex_vec = -1; D_LOG("exception index=%d interrupt_req=%d\n", env->exception_index, - env->interrupt_request); + cs->interrupt_request); assert(!(env->pregs[PR_CCS] & PFIX_FLAG)); switch (env->exception_index) { @@ -162,6 +164,7 @@ static void do_interruptv10(CPUCRISState *env) void do_interrupt(CPUCRISState *env) { + D(CPUState *cs = CPU(cris_env_get_cpu(env))); int ex_vec = -1; if (env->pregs[PR_VR] < 32) { @@ -170,7 +173,7 @@ void do_interrupt(CPUCRISState *env) D_LOG("exception index=%d interrupt_req=%d\n", env->exception_index, - env->interrupt_request); + cs->interrupt_request); switch (env->exception_index) { case EXCP_BREAK: diff --git a/target-cris/translate.c b/target-cris/translate.c index ec71ef4721..dbcb811b7b 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -2888,7 +2888,8 @@ static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc) cris_cc_mask(dc, 0); if (dc->op2 == 15) { - t_gen_mov_env_TN(halted, tcg_const_tl(1)); + tcg_gen_st_i32(tcg_const_i32(1), cpu_env, + -offsetof(CRISCPU, env) + offsetof(CPUState, halted)); tcg_gen_movi_tl(env_pc, dc->pc + 2); t_gen_raise_exception(EXCP_HLT); return 2; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 8ff2fff9f7..2bdbf1b453 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2014,7 +2014,7 @@ static void x86_cpu_reset(CPUState *s) apic_designate_bsp(env->apic_state); } - env->halted = !cpu_is_bsp(cpu); + s->halted = !cpu_is_bsp(cpu); #endif } diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 0c1c5c54ab..bf6e21073d 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -967,6 +967,7 @@ static inline void cpu_x86_load_seg_cache(CPUX86State *env, static inline void cpu_x86_load_seg_cache_sipi(X86CPU *cpu, int sipi_vector) { + CPUState *cs = CPU(cpu); CPUX86State *env = &cpu->env; env->eip = 0; @@ -974,7 +975,7 @@ static inline void cpu_x86_load_seg_cache_sipi(X86CPU *cpu, sipi_vector << 12, env->segs[R_CS].limit, env->segs[R_CS].flags); - env->halted = 0; + cs->halted = 0; } int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector, @@ -1166,17 +1167,18 @@ static inline void cpu_clone_regs(CPUX86State *env, target_ulong newsp) #include "hw/apic.h" #endif -static inline bool cpu_has_work(CPUState *cpu) +static inline bool cpu_has_work(CPUState *cs) { - CPUX86State *env = &X86_CPU(cpu)->env; + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; - return ((env->interrupt_request & (CPU_INTERRUPT_HARD | - CPU_INTERRUPT_POLL)) && + return ((cs->interrupt_request & (CPU_INTERRUPT_HARD | + CPU_INTERRUPT_POLL)) && (env->eflags & IF_MASK)) || - (env->interrupt_request & (CPU_INTERRUPT_NMI | - CPU_INTERRUPT_INIT | - CPU_INTERRUPT_SIPI | - CPU_INTERRUPT_MCE)); + (cs->interrupt_request & (CPU_INTERRUPT_NMI | + CPU_INTERRUPT_INIT | + CPU_INTERRUPT_SIPI | + CPU_INTERRUPT_MCE)); } #include "exec/exec-all.h" diff --git a/target-i386/helper.c b/target-i386/helper.c index 82a731c77d..b49a0fc5f3 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -182,6 +182,7 @@ done: void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf, int flags) { + CPUState *cs = CPU(x86_env_get_cpu(env)); int eflags, i, nb; char cc_op_name[32]; static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" }; @@ -225,7 +226,7 @@ void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf, (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1, (env->a20_mask >> 20) & 1, (env->hflags >> HF_SMM_SHIFT) & 1, - env->halted); + cs->halted); } else #endif { @@ -252,7 +253,7 @@ void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf, (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1, (env->a20_mask >> 20) & 1, (env->hflags >> HF_SMM_SHIFT) & 1, - env->halted); + cs->halted); } for(i = 0; i < 6; i++) { @@ -1281,12 +1282,13 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector, #if !defined(CONFIG_USER_ONLY) void do_cpu_init(X86CPU *cpu) { + CPUState *cs = CPU(cpu); CPUX86State *env = &cpu->env; - int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI; + int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI; uint64_t pat = env->pat; - cpu_reset(CPU(cpu)); - env->interrupt_request = sipi; + cpu_reset(cs); + cs->interrupt_request = sipi; env->pat = pat; apic_init_reset(env->apic_state); } diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 0cf413dbfd..df30fa6ed6 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1460,17 +1460,18 @@ static int kvm_put_mp_state(X86CPU *cpu) static int kvm_get_mp_state(X86CPU *cpu) { + CPUState *cs = CPU(cpu); CPUX86State *env = &cpu->env; struct kvm_mp_state mp_state; int ret; - ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MP_STATE, &mp_state); + ret = kvm_vcpu_ioctl(cs, KVM_GET_MP_STATE, &mp_state); if (ret < 0) { return ret; } env->mp_state = mp_state.mp_state; if (kvm_irqchip_in_kernel()) { - env->halted = (mp_state.mp_state == KVM_MP_STATE_HALTED); + cs->halted = (mp_state.mp_state == KVM_MP_STATE_HALTED); } return 0; } @@ -1762,8 +1763,8 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run) int ret; /* Inject NMI */ - if (env->interrupt_request & CPU_INTERRUPT_NMI) { - env->interrupt_request &= ~CPU_INTERRUPT_NMI; + if (cpu->interrupt_request & CPU_INTERRUPT_NMI) { + cpu->interrupt_request &= ~CPU_INTERRUPT_NMI; DPRINTF("injected NMI\n"); ret = kvm_vcpu_ioctl(cpu, KVM_NMI); if (ret < 0) { @@ -1775,18 +1776,18 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run) if (!kvm_irqchip_in_kernel()) { /* Force the VCPU out of its inner loop to process any INIT requests * or pending TPR access reports. */ - if (env->interrupt_request & + if (cpu->interrupt_request & (CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) { cpu->exit_request = 1; } /* Try to inject an interrupt if the guest can accept it */ if (run->ready_for_interrupt_injection && - (env->interrupt_request & CPU_INTERRUPT_HARD) && + (cpu->interrupt_request & CPU_INTERRUPT_HARD) && (env->eflags & IF_MASK)) { int irq; - env->interrupt_request &= ~CPU_INTERRUPT_HARD; + cpu->interrupt_request &= ~CPU_INTERRUPT_HARD; irq = cpu_get_pic_interrupt(env); if (irq >= 0) { struct kvm_interrupt intr; @@ -1806,7 +1807,7 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run) * interrupt, request an interrupt window exit. This will * cause a return to userspace as soon as the guest is ready to * receive interrupts. */ - if ((env->interrupt_request & CPU_INTERRUPT_HARD)) { + if ((cpu->interrupt_request & CPU_INTERRUPT_HARD)) { run->request_interrupt_window = 1; } else { run->request_interrupt_window = 0; @@ -1836,11 +1837,11 @@ int kvm_arch_process_async_events(CPUState *cs) X86CPU *cpu = X86_CPU(cs); CPUX86State *env = &cpu->env; - if (env->interrupt_request & CPU_INTERRUPT_MCE) { + if (cs->interrupt_request & CPU_INTERRUPT_MCE) { /* We must not raise CPU_INTERRUPT_MCE if it's not supported. */ assert(env->mcg_cap); - env->interrupt_request &= ~CPU_INTERRUPT_MCE; + cs->interrupt_request &= ~CPU_INTERRUPT_MCE; kvm_cpu_synchronize_state(env); @@ -1853,7 +1854,7 @@ int kvm_arch_process_async_events(CPUState *cs) env->exception_injected = EXCP12_MCHK; env->has_error_code = 0; - env->halted = 0; + cs->halted = 0; if (kvm_irqchip_in_kernel() && env->mp_state == KVM_MP_STATE_HALTED) { env->mp_state = KVM_MP_STATE_RUNNABLE; } @@ -1863,41 +1864,42 @@ int kvm_arch_process_async_events(CPUState *cs) return 0; } - if (env->interrupt_request & CPU_INTERRUPT_POLL) { - env->interrupt_request &= ~CPU_INTERRUPT_POLL; + if (cs->interrupt_request & CPU_INTERRUPT_POLL) { + cs->interrupt_request &= ~CPU_INTERRUPT_POLL; apic_poll_irq(env->apic_state); } - if (((env->interrupt_request & CPU_INTERRUPT_HARD) && + if (((cs->interrupt_request & CPU_INTERRUPT_HARD) && (env->eflags & IF_MASK)) || - (env->interrupt_request & CPU_INTERRUPT_NMI)) { - env->halted = 0; + (cs->interrupt_request & CPU_INTERRUPT_NMI)) { + cs->halted = 0; } - if (env->interrupt_request & CPU_INTERRUPT_INIT) { + if (cs->interrupt_request & CPU_INTERRUPT_INIT) { kvm_cpu_synchronize_state(env); do_cpu_init(cpu); } - if (env->interrupt_request & CPU_INTERRUPT_SIPI) { + if (cs->interrupt_request & CPU_INTERRUPT_SIPI) { kvm_cpu_synchronize_state(env); do_cpu_sipi(cpu); } - if (env->interrupt_request & CPU_INTERRUPT_TPR) { - env->interrupt_request &= ~CPU_INTERRUPT_TPR; + if (cs->interrupt_request & CPU_INTERRUPT_TPR) { + cs->interrupt_request &= ~CPU_INTERRUPT_TPR; kvm_cpu_synchronize_state(env); apic_handle_tpr_access_report(env->apic_state, env->eip, env->tpr_access_type); } - return env->halted; + return cs->halted; } static int kvm_handle_halt(X86CPU *cpu) { + CPUState *cs = CPU(cpu); CPUX86State *env = &cpu->env; - if (!((env->interrupt_request & CPU_INTERRUPT_HARD) && + if (!((cs->interrupt_request & CPU_INTERRUPT_HARD) && (env->eflags & IF_MASK)) && - !(env->interrupt_request & CPU_INTERRUPT_NMI)) { - env->halted = 1; + !(cs->interrupt_request & CPU_INTERRUPT_NMI)) { + cs->halted = 1; return EXCP_HLT; } diff --git a/target-i386/machine.c b/target-i386/machine.c index c9984b87a1..b80a5f4470 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -453,7 +453,7 @@ const VMStateDescription vmstate_x86_cpu = { VMSTATE_UINT64_V(env.pat, X86CPU, 5), VMSTATE_UINT32_V(env.hflags2, X86CPU, 5), - VMSTATE_UINT32_TEST(env.halted, X86CPU, version_is_5), + VMSTATE_UINT32_TEST(parent_obj.halted, X86CPU, version_is_5), VMSTATE_UINT64_V(env.vm_hsave, X86CPU, 5), VMSTATE_UINT64_V(env.vm_vmcb, X86CPU, 5), VMSTATE_UINT64_V(env.tsc_offset, X86CPU, 5), diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c index b6d574019a..dfbc07b7f8 100644 --- a/target-i386/misc_helper.c +++ b/target-i386/misc_helper.c @@ -553,20 +553,25 @@ void helper_rdmsr(CPUX86State *env) } #endif -static void do_hlt(CPUX86State *env) +static void do_hlt(X86CPU *cpu) { + CPUState *cs = CPU(cpu); + CPUX86State *env = &cpu->env; + env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */ - env->halted = 1; + cs->halted = 1; env->exception_index = EXCP_HLT; cpu_loop_exit(env); } void helper_hlt(CPUX86State *env, int next_eip_addend) { + X86CPU *cpu = x86_env_get_cpu(env); + cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0); EIP += next_eip_addend; - do_hlt(env); + do_hlt(cpu); } void helper_monitor(CPUX86State *env, target_ulong ptr) @@ -580,7 +585,8 @@ void helper_monitor(CPUX86State *env, target_ulong ptr) void helper_mwait(CPUX86State *env, int next_eip_addend) { - CPUState *cpu; + CPUState *cs; + X86CPU *cpu; if ((uint32_t)ECX != 0) { raise_exception(env, EXCP0D_GPF); @@ -588,13 +594,14 @@ void helper_mwait(CPUX86State *env, int next_eip_addend) cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0); EIP += next_eip_addend; - cpu = CPU(x86_env_get_cpu(env)); + cpu = x86_env_get_cpu(env); + cs = CPU(cpu); /* XXX: not complete but not completely erroneous */ - if (cpu->cpu_index != 0 || env->next_cpu != NULL) { + if (cs->cpu_index != 0 || env->next_cpu != NULL) { /* more than one CPU: do not sleep because another CPU may wake this one */ } else { - do_hlt(env); + do_hlt(cpu); } } diff --git a/target-i386/svm_helper.c b/target-i386/svm_helper.c index 3f246e9073..c46a213c9c 100644 --- a/target-i386/svm_helper.c +++ b/target-i386/svm_helper.c @@ -271,7 +271,9 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend) env->hflags2 |= HF2_GIF_MASK; if (int_ctl & V_IRQ_MASK) { - env->interrupt_request |= CPU_INTERRUPT_VIRQ; + CPUState *cs = CPU(x86_env_get_cpu(env)); + + cs->interrupt_request |= CPU_INTERRUPT_VIRQ; } /* maybe we need to inject an event */ @@ -548,6 +550,7 @@ void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param, /* Note: currently only 32 bits of exit_code are used */ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1) { + CPUState *cs = CPU(x86_env_get_cpu(env)); uint32_t int_ctl; qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016" @@ -594,7 +597,7 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1) int_ctl = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)); int_ctl &= ~(V_TPR_MASK | V_IRQ_MASK); int_ctl |= env->v_tpr & V_TPR_MASK; - if (env->interrupt_request & CPU_INTERRUPT_VIRQ) { + if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) { int_ctl |= V_IRQ_MASK; } stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), int_ctl); @@ -615,7 +618,7 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1) env->hflags &= ~HF_SVMI_MASK; env->intercept = 0; env->intercept_exceptions = 0; - env->interrupt_request &= ~CPU_INTERRUPT_VIRQ; + cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ; env->tsc_offset = 0; env->gdt.base = ldq_phys(env->vm_hsave + offsetof(struct vmcb, diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h index 6948d0e248..d81f103e66 100644 --- a/target-lm32/cpu.h +++ b/target-lm32/cpu.h @@ -254,9 +254,7 @@ static inline void cpu_get_tb_cpu_state(CPULM32State *env, target_ulong *pc, static inline bool cpu_has_work(CPUState *cpu) { - CPULM32State *env = &LM32_CPU(cpu)->env; - - return env->interrupt_request & CPU_INTERRUPT_HARD; + return cpu->interrupt_request & CPU_INTERRUPT_HARD; } #include "exec/exec-all.h" diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c index 53410b176e..ebc94a0681 100644 --- a/target-lm32/op_helper.c +++ b/target-lm32/op_helper.c @@ -25,7 +25,9 @@ void helper_raise_exception(CPULM32State *env, uint32_t index) void helper_hlt(CPULM32State *env) { - env->halted = 1; + CPUState *cs = CPU(lm32_env_get_cpu(env)); + + cs->halted = 1; env->exception_index = EXCP_HLT; cpu_loop_exit(env); } diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index 2672eae7c8..bb2fbd6d4d 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -265,9 +265,7 @@ static inline void cpu_get_tb_cpu_state(CPUM68KState *env, target_ulong *pc, static inline bool cpu_has_work(CPUState *cpu) { - CPUM68KState *env = &M68K_CPU(cpu)->env; - - return env->interrupt_request & CPU_INTERRUPT_HARD; + return cpu->interrupt_request & CPU_INTERRUPT_HARD; } #include "exec/exec-all.h" diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c index 16df24c0ca..e11f34b0f9 100644 --- a/target-m68k/op_helper.c +++ b/target-m68k/op_helper.c @@ -84,6 +84,7 @@ static void do_rte(CPUM68KState *env) static void do_interrupt_all(CPUM68KState *env, int is_hw) { + CPUState *cs; uint32_t sp; uint32_t fmt; uint32_t retaddr; @@ -108,7 +109,8 @@ static void do_interrupt_all(CPUM68KState *env, int is_hw) do_m68k_semihosting(env, env->dregs[0]); return; } - env->halted = 1; + cs = CPU(m68k_env_get_cpu(env)); + cs->halted = 1; env->exception_index = EXCP_HLT; cpu_loop_exit(env); return; diff --git a/target-m68k/qregs.def b/target-m68k/qregs.def index 49400c4475..4235b02764 100644 --- a/target-m68k/qregs.def +++ b/target-m68k/qregs.def @@ -8,6 +8,5 @@ DEFO32(CC_X, cc_x) DEFO32(DIV1, div1) DEFO32(DIV2, div2) DEFO32(EXCEPTION, exception_index) -DEFO32(HALTED, halted) DEFO32(MACSR, macsr) DEFO32(MAC_MASK, mac_mask) diff --git a/target-m68k/translate.c b/target-m68k/translate.c index 20a86d8efe..32b8132da6 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -42,6 +42,8 @@ #undef DEFO64 #undef DEFF64 +static TCGv_i32 cpu_halted; + static TCGv_ptr cpu_env; static char cpu_reg_names[3*8*3 + 5*4]; @@ -76,6 +78,10 @@ void m68k_tcg_init(void) #undef DEFO64 #undef DEFF64 + cpu_halted = tcg_global_mem_new_i32(TCG_AREG0, + -offsetof(M68kCPU, env) + + offsetof(CPUState, halted), "HALTED"); + cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); p = cpu_reg_names; @@ -2024,7 +2030,7 @@ DISAS_INSN(stop) s->pc += 2; gen_set_sr_im(s, ext, 0); - tcg_gen_movi_i32(QREG_HALTED, 1); + tcg_gen_movi_i32(cpu_halted, 1); gen_exception(s, s->pc, EXCP_HLT); } diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h index c3dd7f6219..7548aa903d 100644 --- a/target-microblaze/cpu.h +++ b/target-microblaze/cpu.h @@ -374,9 +374,7 @@ void cpu_unassigned_access(CPUMBState *env1, hwaddr addr, static inline bool cpu_has_work(CPUState *cpu) { - CPUMBState *env = &MICROBLAZE_CPU(cpu)->env; - - return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI); + return cpu->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI); } #include "exec/exec-all.h" diff --git a/target-mips/cpu.h b/target-mips/cpu.h index ca63148b18..22b0497757 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -722,7 +722,7 @@ static inline bool cpu_has_work(CPUState *cpu) /* It is implementation dependent if non-enabled interrupts wake-up the CPU, however most of the implementations only check for interrupts that can be taken. */ - if ((env->interrupt_request & CPU_INTERRUPT_HARD) && + if ((cpu->interrupt_request & CPU_INTERRUPT_HARD) && cpu_mips_hw_interrupts_pending(env)) { has_work = true; } @@ -731,7 +731,7 @@ static inline bool cpu_has_work(CPUState *cpu) if (env->CP0_Config3 & (1 << CP0C3_MT)) { /* The QEMU model will issue an _WAKE request whenever the CPUs should be woken up. */ - if (env->interrupt_request & CPU_INTERRUPT_WAKE) { + if (cpu->interrupt_request & CPU_INTERRUPT_WAKE) { has_work = true; } diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 45cbb2f1c2..3ab4356587 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -515,11 +515,12 @@ void helper_sdm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, /* SMP helpers. */ static bool mips_vpe_is_wfi(MIPSCPU *c) { + CPUState *cpu = CPU(c); CPUMIPSState *env = &c->env; /* If the VPE is halted but otherwise active, it means it's waiting for an interrupt. */ - return env->halted && mips_vpe_active(env); + return cpu->halted && mips_vpe_active(env); } static inline void mips_vpe_wake(CPUMIPSState *c) @@ -532,11 +533,12 @@ static inline void mips_vpe_wake(CPUMIPSState *c) static inline void mips_vpe_sleep(MIPSCPU *cpu) { + CPUState *cs = CPU(cpu); CPUMIPSState *c = &cpu->env; /* The VPE was shut off, really go to bed. Reset any old _WAKE requests. */ - c->halted = 1; + cs->halted = 1; cpu_reset_interrupt(c, CPU_INTERRUPT_WAKE); } @@ -2099,7 +2101,9 @@ void helper_pmon(CPUMIPSState *env, int function) void helper_wait(CPUMIPSState *env) { - env->halted = 1; + CPUState *cs = CPU(mips_env_get_cpu(env)); + + cs->halted = 1; cpu_reset_interrupt(env, CPU_INTERRUPT_WAKE); helper_raise_exception(env, EXCP_HLT); } diff --git a/target-mips/translate.c b/target-mips/translate.c index 694f07c49f..b7f8203e57 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -16004,7 +16004,7 @@ void cpu_state_reset(CPUMIPSState *env) env->tcs[i].CP0_TCHalt = 1; } env->active_tc.CP0_TCHalt = 1; - env->halted = 1; + cs->halted = 1; if (cs->cpu_index == 0) { /* VPE0 starts up enabled. */ @@ -16012,7 +16012,7 @@ void cpu_state_reset(CPUMIPSState *env) env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA); /* TC0 starts up unhalted. */ - env->halted = 0; + cs->halted = 0; env->active_tc.CP0_TCHalt = 0; env->tcs[0].CP0_TCHalt = 0; /* With thread 0 active. */ diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index 4cfd1c74fb..64370a3772 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -423,9 +423,7 @@ static inline int cpu_mmu_index(CPUOpenRISCState *env) #define CPU_INTERRUPT_TIMER CPU_INTERRUPT_TGT_INT_0 static inline bool cpu_has_work(CPUState *cpu) { - CPUOpenRISCState *env = &OPENRISC_CPU(cpu)->env; - - return env->interrupt_request & (CPU_INTERRUPT_HARD | + return cpu->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER); } diff --git a/target-openrisc/interrupt_helper.c b/target-openrisc/interrupt_helper.c index a176441b01..844648f780 100644 --- a/target-openrisc/interrupt_helper.c +++ b/target-openrisc/interrupt_helper.c @@ -24,6 +24,7 @@ void HELPER(rfe)(CPUOpenRISCState *env) { OpenRISCCPU *cpu = openrisc_env_get_cpu(env); + CPUState *cs = CPU(cpu); #ifndef CONFIG_USER_ONLY int need_flush_tlb = (cpu->env.sr & (SR_SM | SR_IME | SR_DME)) ^ (cpu->env.esr & (SR_SM | SR_IME | SR_DME)); @@ -53,5 +54,5 @@ void HELPER(rfe)(CPUOpenRISCState *env) tlb_flush(&cpu->env, 1); } #endif - cpu->env.interrupt_request |= CPU_INTERRUPT_EXITTB; + cs->interrupt_request |= CPU_INTERRUPT_EXITTB; } diff --git a/target-openrisc/sys_helper.c b/target-openrisc/sys_helper.c index 3c5f45ab75..cccbc0e939 100644 --- a/target-openrisc/sys_helper.c +++ b/target-openrisc/sys_helper.c @@ -31,6 +31,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, int idx; OpenRISCCPU *cpu = openrisc_env_get_cpu(env); + CPUState *cs = CPU(cpu); switch (spr) { case TO_SPR(0, 0): /* VR */ @@ -132,7 +133,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, env->ttmr = (rb & ~TTMR_IP) + ip; } else { /* Clear IP bit. */ env->ttmr = rb & ~TTMR_IP; - env->interrupt_request &= ~CPU_INTERRUPT_TIMER; + cs->interrupt_request &= ~CPU_INTERRUPT_TIMER; } cpu_openrisc_count_update(cpu); diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 417abb0dd1..1b31b1d9c9 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -2217,9 +2217,10 @@ extern void (*cpu_ppc_hypercall)(PowerPCCPU *); static inline bool cpu_has_work(CPUState *cpu) { - CPUPPCState *env = &POWERPC_CPU(cpu)->env; + PowerPCCPU *ppc_cpu = POWERPC_CPU(cpu); + CPUPPCState *env = &ppc_cpu->env; - return msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD); + return msr_ee && (cpu->interrupt_request & CPU_INTERRUPT_HARD); } #include "exec/exec-all.h" diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c index 0a1ac86a42..79ce7bf7c4 100644 --- a/target-ppc/excp_helper.c +++ b/target-ppc/excp_helper.c @@ -66,6 +66,7 @@ static inline void dump_syscall(CPUPPCState *env) static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) { CPUPPCState *env = &cpu->env; + CPUState *cs; target_ulong msr, new_msr, vector; int srr0, srr1, asrr0, asrr1; int lpes0, lpes1, lev; @@ -131,8 +132,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) fprintf(stderr, "Machine check while not allowed. " "Entering checkstop state\n"); } - env->halted = 1; - env->interrupt_request |= CPU_INTERRUPT_EXITTB; + cs = CPU(cpu); + cs->halted = 1; + cs->interrupt_request |= CPU_INTERRUPT_EXITTB; } if (0) { /* XXX: find a suitable condition to enable the hypervisor mode */ @@ -663,11 +665,12 @@ void ppc_hw_interrupt(CPUPPCState *env) { PowerPCCPU *cpu = ppc_env_get_cpu(env); int hdice; - #if 0 + CPUState *cs = CPU(cpu); + qemu_log_mask(CPU_LOG_INT, "%s: %p pending %08x req %08x me %d ee %d\n", - __func__, env, env->pending_interrupts, - env->interrupt_request, (int)msr_me, (int)msr_ee); + __func__, env, env->pending_interrupts, + cs->interrupt_request, (int)msr_me, (int)msr_ee); #endif /* External reset */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) { @@ -807,9 +810,12 @@ void helper_raise_exception(CPUPPCState *env, uint32_t exception) #if !defined(CONFIG_USER_ONLY) void helper_store_msr(CPUPPCState *env, target_ulong val) { + CPUState *cs; + val = hreg_store_msr(env, val, 0); if (val != 0) { - env->interrupt_request |= CPU_INTERRUPT_EXITTB; + cs = CPU(ppc_env_get_cpu(env)); + cs->interrupt_request |= CPU_INTERRUPT_EXITTB; helper_raise_exception(env, val); } } @@ -817,6 +823,8 @@ void helper_store_msr(CPUPPCState *env, target_ulong val) static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr, target_ulong msrm, int keep_msrh) { + CPUState *cs = CPU(ppc_env_get_cpu(env)); + #if defined(TARGET_PPC64) if (msr_is_64bit(env, msr)) { nip = (uint64_t)nip; @@ -841,7 +849,7 @@ static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr, /* No need to raise an exception here, * as rfi is always the last insn of a TB */ - env->interrupt_request |= CPU_INTERRUPT_EXITTB; + cs->interrupt_request |= CPU_INTERRUPT_EXITTB; } void helper_rfi(CPUPPCState *env) diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h index 3c988502ed..a6d5e2fe2f 100644 --- a/target-ppc/helper_regs.h +++ b/target-ppc/helper_regs.h @@ -68,10 +68,13 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value, int alter_hv) { int excp; +#if !defined(CONFIG_USER_ONLY) + CPUState *cs = CPU(ppc_env_get_cpu(env)); +#endif excp = 0; value &= env->msr_mask; -#if !defined (CONFIG_USER_ONLY) +#if !defined(CONFIG_USER_ONLY) if (!alter_hv) { /* mtmsr cannot alter the hypervisor state */ value &= ~MSR_HVB; @@ -82,7 +85,7 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value, /* Flush all tlb when changing translation mode */ tlb_flush(env, 1); excp = POWERPC_EXCP_NONE; - env->interrupt_request |= CPU_INTERRUPT_EXITTB; + cs->interrupt_request |= CPU_INTERRUPT_EXITTB; } if (unlikely((env->flags & POWERPC_FLAG_TGPR) && ((value ^ env->msr) & (1 << MSR_TGPR)))) { @@ -96,10 +99,10 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value, #endif env->msr = value; hreg_compute_hflags(env); -#if !defined (CONFIG_USER_ONLY) +#if !defined(CONFIG_USER_ONLY) if (unlikely(msr_pow == 1)) { if ((*env->check_pow)(env)) { - env->halted = 1; + cs->halted = 1; excp = EXCP_HALTED; } } diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 9dff7607f1..e663ff0acb 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -993,7 +993,7 @@ void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) * interrupt, reset, etc) in PPC-specific env->irq_input_state. */ if (!cap_interrupt_level && run->ready_for_interrupt_injection && - (env->interrupt_request & CPU_INTERRUPT_HARD) && + (cs->interrupt_request & CPU_INTERRUPT_HARD) && (env->irq_input_state & (1<env.halted; + return cs->halted; } -static int kvmppc_handle_halt(CPUPPCState *env) +static int kvmppc_handle_halt(PowerPCCPU *cpu) { - if (!(env->interrupt_request & CPU_INTERRUPT_HARD) && (msr_ee)) { - env->halted = 1; + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + + if (!(cs->interrupt_request & CPU_INTERRUPT_HARD) && (msr_ee)) { + cs->halted = 1; env->exception_index = EXCP_HLT; } @@ -1073,7 +1075,7 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) break; case KVM_EXIT_HLT: dprintf("handle halt\n"); - ret = kvmppc_handle_halt(env); + ret = kvmppc_handle_halt(cpu); break; #ifdef CONFIG_PSERIES case KVM_EXIT_PAPR_HCALL: diff --git a/target-ppc/translate.c b/target-ppc/translate.c index fa9e9e3857..380a884131 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -3103,7 +3103,8 @@ static void gen_sync(DisasContext *ctx) static void gen_wait(DisasContext *ctx) { TCGv_i32 t0 = tcg_temp_new_i32(); - tcg_gen_st_i32(t0, cpu_env, offsetof(CPUPPCState, halted)); + tcg_gen_st_i32(t0, cpu_env, + -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted)); tcg_temp_free_i32(t0); /* Stop translation, as the CPU is supposed to sleep from now */ gen_exception_err(ctx, EXCP_HLT, 1); diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index b74654724d..738a0ad1ee 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -80,10 +80,10 @@ static void s390_cpu_reset(CPUState *s) env->cregs[0] = CR0_RESET; env->cregs[14] = CR14_RESET; /* set halted to 1 to make sure we can add the cpu in - * s390_ipl_cpu code, where env->halted is set back to 0 + * s390_ipl_cpu code, where CPUState::halted is set back to 0 * after incrementing the cpu counter */ #if !defined(CONFIG_USER_ONLY) - env->halted = 1; + s->halted = 1; #endif tlb_flush(env, 1); } @@ -129,10 +129,10 @@ static void s390_cpu_initfn(Object *obj) env->tod_basetime = 0; env->tod_timer = qemu_new_timer_ns(vm_clock, s390x_tod_timer, cpu); env->cpu_timer = qemu_new_timer_ns(vm_clock, s390x_cpu_timer, cpu); - /* set env->halted state to 1 to avoid decrementing the running + /* set CPUState::halted state to 1 to avoid decrementing the running * cpu counter in s390_cpu_reset to a negative number at * initial ipl */ - env->halted = 1; + cs->halted = 1; #endif env->cpu_num = cpu_num++; env->ext_index = -1; diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index 9cb739da1e..db263bf4e3 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -1039,9 +1039,10 @@ static inline void cpu_inject_crw_mchk(S390CPU *cpu) static inline bool cpu_has_work(CPUState *cpu) { - CPUS390XState *env = &S390_CPU(cpu)->env; + S390CPU *s390_cpu = S390_CPU(cpu); + CPUS390XState *env = &s390_cpu->env; - return (env->interrupt_request & CPU_INTERRUPT_HARD) && + return (cpu->interrupt_request & CPU_INTERRUPT_HARD) && (env->psw.mask & PSW_MASK_EXT); } diff --git a/target-s390x/helper.c b/target-s390x/helper.c index 1183b45ca1..c88a58743e 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -437,6 +437,7 @@ void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr) { if (mask & PSW_MASK_WAIT) { S390CPU *cpu = s390_env_get_cpu(env); + CPUState *cs = CPU(cpu); if (!(mask & (PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK))) { if (s390_del_running_cpu(cpu) == 0) { #ifndef CONFIG_USER_ONLY @@ -444,7 +445,7 @@ void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr) #endif } } - env->halted = 1; + cs->halted = 1; env->exception_index = EXCP_HLT; } @@ -739,6 +740,7 @@ static void do_mchk_interrupt(CPUS390XState *env) void do_interrupt(CPUS390XState *env) { S390CPU *cpu = s390_env_get_cpu(env); + CPUState *cs; qemu_log_mask(CPU_LOG_INT, "%s: %d at pc=%" PRIx64 "\n", __func__, env->exception_index, env->psw.addr); @@ -797,7 +799,8 @@ void do_interrupt(CPUS390XState *env) env->exception_index = -1; if (!env->pending_int) { - env->interrupt_request &= ~CPU_INTERRUPT_HARD; + cs = CPU(s390_env_get_cpu(env)); + cs->interrupt_request &= ~CPU_INTERRUPT_HARD; } } diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index f805778075..49663556ef 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -369,9 +369,7 @@ static inline void cpu_get_tb_cpu_state(CPUSH4State *env, target_ulong *pc, static inline bool cpu_has_work(CPUState *cpu) { - CPUSH4State *env = &SUPERH_CPU(cpu)->env; - - return env->interrupt_request & CPU_INTERRUPT_HARD; + return cpu->interrupt_request & CPU_INTERRUPT_HARD; } #include "exec/exec-all.h" diff --git a/target-sh4/helper.c b/target-sh4/helper.c index ddebc78964..fd4efee4a6 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -78,9 +78,10 @@ int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr) #define MMU_DADDR_ERROR_READ (-12) #define MMU_DADDR_ERROR_WRITE (-13) -void do_interrupt(CPUSH4State * env) +void do_interrupt(CPUSH4State *env) { - int do_irq = env->interrupt_request & CPU_INTERRUPT_HARD; + CPUState *cs = CPU(sh_env_get_cpu(env)); + int do_irq = cs->interrupt_request & CPU_INTERRUPT_HARD; int do_exp, irq_vector = env->exception_index; /* prioritize exceptions over interrupts */ diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c index 09e3d23aff..e955e810b5 100644 --- a/target-sh4/op_helper.c +++ b/target-sh4/op_helper.c @@ -102,7 +102,9 @@ void helper_debug(CPUSH4State *env) void helper_sleep(CPUSH4State *env) { - env->halted = 1; + CPUState *cs = CPU(sh_env_get_cpu(env)); + + cs->halted = 1; env->in_sleep = 1; raise_exception(env, EXCP_HLT, 0); } diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index a2f2cc8989..8a2f8df992 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -762,9 +762,10 @@ static inline bool tb_am_enabled(int tb_flags) static inline bool cpu_has_work(CPUState *cpu) { - CPUSPARCState *env1 = &SPARC_CPU(cpu)->env; + SPARCCPU *sparc_cpu = SPARC_CPU(cpu); + CPUSPARCState *env1 = &sparc_cpu->env; - return (env1->interrupt_request & CPU_INTERRUPT_HARD) && + return (cpu->interrupt_request & CPU_INTERRUPT_HARD) && cpu_interrupts_enabled(env1); } diff --git a/target-sparc/helper.c b/target-sparc/helper.c index 58e7efe567..57c20af478 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -229,7 +229,9 @@ target_ulong helper_tsubcctv(CPUSPARCState *env, target_ulong src1, #ifndef TARGET_SPARC64 void helper_power_down(CPUSPARCState *env) { - env->halted = 1; + CPUState *cs = CPU(sparc_env_get_cpu(env)); + + cs->halted = 1; env->exception_index = EXCP_HLT; env->pc = env->npc; env->npc = env->pc + 4; diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h index ae9a9d623d..58f1f20ca5 100644 --- a/target-unicore32/cpu.h +++ b/target-unicore32/cpu.h @@ -181,9 +181,7 @@ void switch_mode(CPUUniCore32State *, int); static inline bool cpu_has_work(CPUState *cpu) { - CPUUniCore32State *env = &UNICORE32_CPU(cpu)->env; - - return env->interrupt_request & + return cpu->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB); } diff --git a/target-unicore32/softmmu.c b/target-unicore32/softmmu.c index fc27100f27..1c4c7f5245 100644 --- a/target-unicore32/softmmu.c +++ b/target-unicore32/softmmu.c @@ -74,6 +74,7 @@ void switch_mode(CPUUniCore32State *env, int mode) /* Handle a CPU exception. */ void do_interrupt(CPUUniCore32State *env) { + CPUState *cs = CPU(uc32_env_get_cpu(env)); uint32_t addr; int new_mode; @@ -112,7 +113,7 @@ void do_interrupt(CPUUniCore32State *env) /* The PC already points to the proper instruction. */ env->regs[30] = env->regs[31]; env->regs[31] = addr; - env->interrupt_request |= CPU_INTERRUPT_EXITTB; + cs->interrupt_request |= CPU_INTERRUPT_EXITTB; } static int get_phys_addr_ucv2(CPUUniCore32State *env, uint32_t address, diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c index 3813a72626..1037101f2e 100644 --- a/target-xtensa/op_helper.c +++ b/target-xtensa/op_helper.c @@ -373,6 +373,8 @@ void HELPER(dump_state)(CPUXtensaState *env) void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel) { + CPUState *cpu; + env->pc = pc; env->sregs[PS] = (env->sregs[PS] & ~PS_INTLEVEL) | (intlevel << PS_INTLEVEL_SHIFT); @@ -382,8 +384,9 @@ void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel) return; } + cpu = CPU(xtensa_env_get_cpu(env)); env->halt_clock = qemu_get_clock_ns(vm_clock); - env->halted = 1; + cpu->halted = 1; if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT)) { xtensa_rearm_ccompare_timer(env); } diff --git a/translate-all.c b/translate-all.c index 90ea002935..f0c7d1e4c9 100644 --- a/translate-all.c +++ b/translate-all.c @@ -1077,8 +1077,8 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, tb_phys_invalidate(tb, -1); if (cpu != NULL) { cpu->current_tb = saved_tb; - if (env && env->interrupt_request && cpu->current_tb) { - cpu_interrupt(env, env->interrupt_request); + if (env && cpu->interrupt_request && cpu->current_tb) { + cpu_interrupt(env, cpu->interrupt_request); } } } @@ -1387,8 +1387,8 @@ static void tcg_handle_interrupt(CPUArchState *env, int mask) CPUState *cpu = ENV_GET_CPU(env); int old_mask; - old_mask = env->interrupt_request; - env->interrupt_request |= mask; + old_mask = cpu->interrupt_request; + cpu->interrupt_request |= mask; /* * If called from iothread context, wake the target cpu in @@ -1556,7 +1556,7 @@ void cpu_interrupt(CPUArchState *env, int mask) { CPUState *cpu = ENV_GET_CPU(env); - env->interrupt_request |= mask; + cpu->interrupt_request |= mask; cpu->tcg_exit_req = 1; } diff --git a/xen-all.c b/xen-all.c index 110f958a53..8c05843faf 100644 --- a/xen-all.c +++ b/xen-all.c @@ -578,16 +578,18 @@ void qmp_xen_set_global_dirty_log(bool enable, Error **errp) static void xen_reset_vcpu(void *opaque) { - CPUArchState *env = opaque; + CPUState *cpu = opaque; - env->halted = 1; + cpu->halted = 1; } void xen_vcpu_init(void) { if (first_cpu != NULL) { - qemu_register_reset(xen_reset_vcpu, first_cpu); - xen_reset_vcpu(first_cpu); + CPUState *cpu = ENV_GET_CPU(first_cpu); + + qemu_register_reset(xen_reset_vcpu, cpu); + xen_reset_vcpu(cpu); } /* if rtc_clock is left to default (host_clock), disable it */ if (rtc_clock == host_clock) { From d8ed887bdcd29ce2e967f8b15a6a2b6dcaa11cd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 17 Jan 2013 22:30:20 +0100 Subject: [PATCH 13/17] exec: Pass CPUState to cpu_reset_interrupt() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move it to qom/cpu.c to avoid build failures depending on include order of cpu-qom.h and exec/cpu-all.h. Change opaques of various ..._irq_handler() functions to the appropriate CPU type to facilitate using cpu_reset_interrupt(). Fix Coding Style issues while at it (missing braces, indentation). Signed-off-by: Andreas Färber --- exec.c | 7 ------- hw/alpha_typhoon.c | 8 +++++--- hw/apic.c | 4 ++-- hw/arm/pic_cpu.c | 15 +++++++++------ hw/arm/pxa2xx_pic.c | 4 ++-- hw/cris/pic_cpu.c | 13 ++++++++----- hw/i386/pc.c | 8 +++++--- hw/lm32/lm32_boards.c | 8 +++++--- hw/lm32/milkymist.c | 8 +++++--- hw/microblaze/pic_cpu.c | 14 +++++++++----- hw/mips/mips_int.c | 8 +++++--- hw/openrisc/pic_cpu.c | 3 ++- hw/ppc/ppc.c | 6 ++++-- hw/sh_intc.c | 9 +++++---- hw/sparc/leon3.c | 4 +++- hw/sparc/sun4m.c | 5 ++++- hw/sparc64/sun4u.c | 7 ++++--- hw/unicore32/puv3.c | 9 ++++++--- hw/xtensa/pic_cpu.c | 2 +- include/exec/cpu-all.h | 2 -- include/qom/cpu.h | 9 +++++++++ qom/cpu.c | 5 +++++ target-m68k/helper.c | 8 +++++--- target-mips/op_helper.c | 5 ++--- 24 files changed, 105 insertions(+), 66 deletions(-) diff --git a/exec.c b/exec.c index 4462edf076..ae5a4b4430 100644 --- a/exec.c +++ b/exec.c @@ -492,13 +492,6 @@ void cpu_single_step(CPUArchState *env, int enabled) #endif } -void cpu_reset_interrupt(CPUArchState *env, int mask) -{ - CPUState *cpu = ENV_GET_CPU(env); - - cpu->interrupt_request &= ~mask; -} - void cpu_exit(CPUArchState *env) { CPUState *cpu = ENV_GET_CPU(env); diff --git a/hw/alpha_typhoon.c b/hw/alpha_typhoon.c index 95571ffc5d..7bfde5771c 100644 --- a/hw/alpha_typhoon.c +++ b/hw/alpha_typhoon.c @@ -63,10 +63,11 @@ static void cpu_irq_change(AlphaCPU *cpu, uint64_t req) /* If there are any non-masked interrupts, tell the cpu. */ if (cpu != NULL) { CPUAlphaState *env = &cpu->env; + CPUState *cs = CPU(cpu); if (req) { cpu_interrupt(env, CPU_INTERRUPT_HARD); } else { - cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } } } @@ -359,16 +360,17 @@ static void cchip_write(void *opaque, hwaddr addr, AlphaCPU *cpu = s->cchip.cpu[i]; if (cpu != NULL) { CPUAlphaState *env = &cpu->env; + CPUState *cs = CPU(cpu); /* IPI can be either cleared or set by the write. */ if (newval & (1 << (i + 8))) { cpu_interrupt(env, CPU_INTERRUPT_SMP); } else { - cpu_reset_interrupt(env, CPU_INTERRUPT_SMP); + cpu_reset_interrupt(cs, CPU_INTERRUPT_SMP); } /* ITI can only be cleared by the write. */ if ((newval & (1 << (i + 4))) == 0) { - cpu_reset_interrupt(env, CPU_INTERRUPT_TIMER); + cpu_reset_interrupt(cs, CPU_INTERRUPT_TIMER); } } } diff --git a/hw/apic.c b/hw/apic.c index 8eddba06e5..cc9236a41c 100644 --- a/hw/apic.c +++ b/hw/apic.c @@ -187,7 +187,7 @@ void apic_deliver_pic_intr(DeviceState *d, int level) reset_bit(s->irr, lvt & 0xff); /* fall through */ case APIC_DM_EXTINT: - cpu_reset_interrupt(&s->cpu->env, CPU_INTERRUPT_HARD); + cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_HARD); break; } } @@ -485,7 +485,7 @@ void apic_sipi(DeviceState *d) { APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); - cpu_reset_interrupt(&s->cpu->env, CPU_INTERRUPT_SIPI); + cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI); if (!s->wait_for_sipi) return; diff --git a/hw/arm/pic_cpu.c b/hw/arm/pic_cpu.c index 82236006d2..95f5bf1777 100644 --- a/hw/arm/pic_cpu.c +++ b/hw/arm/pic_cpu.c @@ -16,19 +16,22 @@ static void arm_pic_cpu_handler(void *opaque, int irq, int level) { ARMCPU *cpu = opaque; CPUARMState *env = &cpu->env; + CPUState *cs = CPU(cpu); switch (irq) { case ARM_PIC_CPU_IRQ: - if (level) + if (level) { cpu_interrupt(env, CPU_INTERRUPT_HARD); - else - cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); + } else { + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); + } break; case ARM_PIC_CPU_FIQ: - if (level) + if (level) { cpu_interrupt(env, CPU_INTERRUPT_FIQ); - else - cpu_reset_interrupt(env, CPU_INTERRUPT_FIQ); + } else { + cpu_reset_interrupt(cs, CPU_INTERRUPT_FIQ); + } break; default: hw_error("arm_pic_cpu_handler: Bad interrupt line %d\n", irq); diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c index b55ce479f4..b45b371435 100644 --- a/hw/arm/pxa2xx_pic.c +++ b/hw/arm/pxa2xx_pic.c @@ -62,13 +62,13 @@ static void pxa2xx_pic_update(void *opaque) if ((mask[0] & s->is_fiq[0]) || (mask[1] & s->is_fiq[1])) { cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_FIQ); } else { - cpu_reset_interrupt(&s->cpu->env, CPU_INTERRUPT_FIQ); + cpu_reset_interrupt(cpu, CPU_INTERRUPT_FIQ); } if ((mask[0] & ~s->is_fiq[0]) || (mask[1] & ~s->is_fiq[1])) { cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_HARD); } else { - cpu_reset_interrupt(&s->cpu->env, CPU_INTERRUPT_HARD); + cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD); } } diff --git a/hw/cris/pic_cpu.c b/hw/cris/pic_cpu.c index 7f50471e53..afd0df8041 100644 --- a/hw/cris/pic_cpu.c +++ b/hw/cris/pic_cpu.c @@ -30,16 +30,19 @@ static void cris_pic_cpu_handler(void *opaque, int irq, int level) { - CPUCRISState *env = (CPUCRISState *)opaque; + CRISCPU *cpu = opaque; + CPUCRISState *env = &cpu->env; + CPUState *cs = CPU(cpu); int type = irq ? CPU_INTERRUPT_NMI : CPU_INTERRUPT_HARD; - if (level) + if (level) { cpu_interrupt(env, type); - else - cpu_reset_interrupt(env, type); + } else { + cpu_reset_interrupt(cs, type); + } } qemu_irq *cris_pic_init_cpu(CPUCRISState *env) { - return qemu_allocate_irqs(cris_pic_cpu_handler, env, 2); + return qemu_allocate_irqs(cris_pic_cpu_handler, cris_env_get_cpu(env), 2); } diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 309bb83cab..c731bdc024 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -190,10 +190,12 @@ static void pic_irq_request(void *opaque, int irq, int level) env = env->next_cpu; } } else { - if (level) + CPUState *cs = CPU(x86_env_get_cpu(env)); + if (level) { cpu_interrupt(env, CPU_INTERRUPT_HARD); - else - cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); + } else { + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); + } } } diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c index 1ce466a1b1..538c20397f 100644 --- a/hw/lm32/lm32_boards.c +++ b/hw/lm32/lm32_boards.c @@ -41,12 +41,14 @@ typedef struct { static void cpu_irq_handler(void *opaque, int irq, int level) { - CPULM32State *env = opaque; + LM32CPU *cpu = opaque; + CPULM32State *env = &cpu->env; + CPUState *cs = CPU(cpu); if (level) { cpu_interrupt(env, CPU_INTERRUPT_HARD); } else { - cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } } @@ -117,7 +119,7 @@ static void lm32_evr_init(QEMUMachineInitArgs *args) 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1); /* create irq lines */ - cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1); + cpu_irq = qemu_allocate_irqs(cpu_irq_handler, cpu, 1); env->pic_state = lm32_pic_init(*cpu_irq); for (i = 0; i < 32; i++) { irq[i] = qdev_get_gpio_in(env->pic_state, i); diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c index fd36de57b5..9ff6d28854 100644 --- a/hw/lm32/milkymist.c +++ b/hw/lm32/milkymist.c @@ -46,12 +46,14 @@ typedef struct { static void cpu_irq_handler(void *opaque, int irq, int level) { - CPULM32State *env = opaque; + LM32CPU *cpu = opaque; + CPULM32State *env = &cpu->env; + CPUState *cs = CPU(cpu); if (level) { cpu_interrupt(env, CPU_INTERRUPT_HARD); } else { - cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } } @@ -123,7 +125,7 @@ milkymist_init(QEMUMachineInitArgs *args) 0x00, 0x89, 0x00, 0x1d, 1); /* create irq lines */ - cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1); + cpu_irq = qemu_allocate_irqs(cpu_irq_handler, cpu, 1); env->pic_state = lm32_pic_init(*cpu_irq); for (i = 0; i < 32; i++) { irq[i] = qdev_get_gpio_in(env->pic_state, i); diff --git a/hw/microblaze/pic_cpu.c b/hw/microblaze/pic_cpu.c index d4743ab390..47568505c7 100644 --- a/hw/microblaze/pic_cpu.c +++ b/hw/microblaze/pic_cpu.c @@ -29,16 +29,20 @@ static void microblaze_pic_cpu_handler(void *opaque, int irq, int level) { - CPUMBState *env = (CPUMBState *)opaque; + MicroBlazeCPU *cpu = opaque; + CPUMBState *env = &cpu->env; + CPUState *cs = CPU(cpu); int type = irq ? CPU_INTERRUPT_NMI : CPU_INTERRUPT_HARD; - if (level) + if (level) { cpu_interrupt(env, type); - else - cpu_reset_interrupt(env, type); + } else { + cpu_reset_interrupt(cs, type); + } } qemu_irq *microblaze_pic_init_cpu(CPUMBState *env) { - return qemu_allocate_irqs(microblaze_pic_cpu_handler, env, 2); + return qemu_allocate_irqs(microblaze_pic_cpu_handler, mb_env_get_cpu(env), + 2); } diff --git a/hw/mips/mips_int.c b/hw/mips/mips_int.c index ddd3b1bb01..3a78999e02 100644 --- a/hw/mips/mips_int.c +++ b/hw/mips/mips_int.c @@ -26,7 +26,9 @@ static void cpu_mips_irq_request(void *opaque, int irq, int level) { - CPUMIPSState *env = (CPUMIPSState *)opaque; + MIPSCPU *cpu = opaque; + CPUMIPSState *env = &cpu->env; + CPUState *cs = CPU(cpu); if (irq < 0 || irq > 7) return; @@ -40,7 +42,7 @@ static void cpu_mips_irq_request(void *opaque, int irq, int level) if (env->CP0_Cause & CP0Ca_IP_mask) { cpu_interrupt(env, CPU_INTERRUPT_HARD); } else { - cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } } @@ -49,7 +51,7 @@ void cpu_mips_irq_init_cpu(CPUMIPSState *env) qemu_irq *qi; int i; - qi = qemu_allocate_irqs(cpu_mips_irq_request, env, 8); + qi = qemu_allocate_irqs(cpu_mips_irq_request, mips_env_get_cpu(env), 8); for (i = 0; i < 8; i++) { env->irq[i] = qi[i]; } diff --git a/hw/openrisc/pic_cpu.c b/hw/openrisc/pic_cpu.c index 931511ec0f..7e4f9e015e 100644 --- a/hw/openrisc/pic_cpu.c +++ b/hw/openrisc/pic_cpu.c @@ -25,6 +25,7 @@ static void openrisc_pic_cpu_handler(void *opaque, int irq, int level) { OpenRISCCPU *cpu = (OpenRISCCPU *)opaque; + CPUState *cs = CPU(cpu); int i; uint32_t irq_bit = 1 << irq; @@ -42,7 +43,7 @@ static void openrisc_pic_cpu_handler(void *opaque, int irq, int level) if ((cpu->env.picsr && (1 << i)) && (cpu->env.picmr && (1 << i))) { cpu_interrupt(&cpu->env, CPU_INTERRUPT_HARD); } else { - cpu_reset_interrupt(&cpu->env, CPU_INTERRUPT_HARD); + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); cpu->env.picsr &= ~(1 << i); } } diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index b2d7fe8df7..ae2ed70181 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -52,6 +52,7 @@ static void cpu_ppc_tb_start (CPUPPCState *env); void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level) { + CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; unsigned int old_pending = env->pending_interrupts; @@ -60,8 +61,9 @@ void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level) cpu_interrupt(env, CPU_INTERRUPT_HARD); } else { env->pending_interrupts &= ~(1 << n_IRQ); - if (env->pending_interrupts == 0) - cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); + if (env->pending_interrupts == 0) { + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); + } } if (old_pending != env->pending_interrupts) { diff --git a/hw/sh_intc.c b/hw/sh_intc.c index 9e64e4d353..97903140ab 100644 --- a/hw/sh_intc.c +++ b/hw/sh_intc.c @@ -42,15 +42,16 @@ void sh_intc_toggle_source(struct intc_source *source, pending_changed = 1; if (pending_changed) { + CPUState *cpu = CPU(sh_env_get_cpu(first_cpu)); if (source->pending) { source->parent->pending++; if (source->parent->pending == 1) cpu_interrupt(first_cpu, CPU_INTERRUPT_HARD); - } - else { + } else { source->parent->pending--; - if (source->parent->pending == 0) - cpu_reset_interrupt(first_cpu, CPU_INTERRUPT_HARD); + if (source->parent->pending == 0) { + cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD); + } } } diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index a9167e6f93..b1fbde0ff7 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -67,6 +67,7 @@ void leon3_irq_ack(void *irq_manager, int intno) static void leon3_set_pil_in(void *opaque, uint32_t pil_in) { CPUSPARCState *env = (CPUSPARCState *)opaque; + CPUState *cs; assert(env != NULL); @@ -89,9 +90,10 @@ static void leon3_set_pil_in(void *opaque, uint32_t pil_in) } } } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) { + cs = CPU(sparc_env_get_cpu(env)); trace_leon3_reset_irq(env->interrupt_index & 15); env->interrupt_index = 0; - cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } } diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index a7e6966435..a1822f16f3 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -230,6 +230,8 @@ void sun4m_irq_info(Monitor *mon, const QDict *qdict) void cpu_check_irqs(CPUSPARCState *env) { + CPUState *cs; + if (env->pil_in && (env->interrupt_index == 0 || (env->interrupt_index & ~15) == TT_EXTINT)) { unsigned int i; @@ -247,9 +249,10 @@ void cpu_check_irqs(CPUSPARCState *env) } } } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) { + cs = CPU(sparc_env_get_cpu(env)); trace_sun4m_cpu_reset_interrupt(env->interrupt_index & 15); env->interrupt_index = 0; - cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } } diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index ae3c95b5cf..817c23cde3 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -276,7 +276,7 @@ void cpu_check_irqs(CPUSPARCState *env) CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n", env->interrupt_index); env->interrupt_index = 0; - cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } return; } @@ -309,7 +309,7 @@ void cpu_check_irqs(CPUSPARCState *env) "current interrupt %x\n", pil, env->pil_in, env->softint, env->interrupt_index); env->interrupt_index = 0; - cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } } @@ -344,8 +344,9 @@ static void cpu_set_ivec_irq(void *opaque, int irq, int level) } else { if (env->ivec_status & 0x20) { CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq); + cs = CPU(cpu); env->ivec_status &= ~0x20; - cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } } } diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c index f9d0c2bab1..6e87c41f28 100644 --- a/hw/unicore32/puv3.c +++ b/hw/unicore32/puv3.c @@ -26,13 +26,15 @@ static void puv3_intc_cpu_handler(void *opaque, int irq, int level) { - CPUUniCore32State *env = opaque; + UniCore32CPU *cpu = opaque; + CPUUniCore32State *env = &cpu->env; + CPUState *cs = CPU(cpu); assert(irq == 0); if (level) { cpu_interrupt(env, CPU_INTERRUPT_HARD); } else { - cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } } @@ -44,7 +46,8 @@ static void puv3_soc_init(CPUUniCore32State *env) int i; /* Initialize interrupt controller */ - cpu_intc = qemu_allocate_irqs(puv3_intc_cpu_handler, env, 1); + cpu_intc = qemu_allocate_irqs(puv3_intc_cpu_handler, + uc32_env_get_cpu(env), 1); dev = sysbus_create_simple("puv3_intc", PUV3_INTC_BASE, *cpu_intc); for (i = 0; i < PUV3_IRQS_NR; i++) { irqs[i] = qdev_get_gpio_in(dev, i); diff --git a/hw/xtensa/pic_cpu.c b/hw/xtensa/pic_cpu.c index 12f66b6f55..fd590c64ce 100644 --- a/hw/xtensa/pic_cpu.c +++ b/hw/xtensa/pic_cpu.c @@ -80,7 +80,7 @@ void check_interrupts(CPUXtensaState *env) } } env->pending_irq_level = 0; - cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } static void xtensa_set_irq(void *opaque, int irq, int active) diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 249e0464f2..5218a53576 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -434,8 +434,6 @@ static inline void cpu_interrupt(CPUArchState *s, int mask) void cpu_interrupt(CPUArchState *env, int mask); #endif /* USER_ONLY */ -void cpu_reset_interrupt(CPUArchState *env, int mask); - void cpu_exit(CPUArchState *s); /* Breakpoint/watchpoint flags */ diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 23c80b9251..b83ba6f150 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -221,5 +221,14 @@ void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data); */ CPUState *qemu_get_cpu(int index); +/** + * cpu_reset_interrupt: + * @cpu: The CPU to clear the interrupt on. + * @mask: The interrupt mask to clear. + * + * Resets interrupts on the vCPU @cpu. + */ +void cpu_reset_interrupt(CPUState *cpu, int mask); + #endif diff --git a/qom/cpu.c b/qom/cpu.c index 0aa9be793d..e242dcbeb4 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -21,6 +21,11 @@ #include "qom/cpu.h" #include "qemu-common.h" +void cpu_reset_interrupt(CPUState *cpu, int mask) +{ + cpu->interrupt_request &= ~mask; +} + void cpu_reset(CPUState *cpu) { CPUClass *klass = CPU_GET_CLASS(cpu); diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 1bae3ab326..d9c8374be4 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -312,14 +312,16 @@ int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw, simplicitly we calculate it when the interrupt is signalled. */ void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector) { + CPUState *cs = CPU(cpu); CPUM68KState *env = &cpu->env; env->pending_level = level; env->pending_vector = vector; - if (level) + if (level) { cpu_interrupt(env, CPU_INTERRUPT_HARD); - else - cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); + } else { + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); + } } #endif diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 3ab4356587..d568188703 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -534,12 +534,11 @@ static inline void mips_vpe_wake(CPUMIPSState *c) static inline void mips_vpe_sleep(MIPSCPU *cpu) { CPUState *cs = CPU(cpu); - CPUMIPSState *c = &cpu->env; /* The VPE was shut off, really go to bed. Reset any old _WAKE requests. */ cs->halted = 1; - cpu_reset_interrupt(c, CPU_INTERRUPT_WAKE); + cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE); } static inline void mips_tc_wake(MIPSCPU *cpu, int tc) @@ -2104,7 +2103,7 @@ void helper_wait(CPUMIPSState *env) CPUState *cs = CPU(mips_env_get_cpu(env)); cs->halted = 1; - cpu_reset_interrupt(env, CPU_INTERRUPT_WAKE); + cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE); helper_raise_exception(env, EXCP_HLT); } From c3affe5670e5d0df8a7e06f1d6e80853633146df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 18 Jan 2013 15:03:43 +0100 Subject: [PATCH 14/17] cpu: Pass CPUState to cpu_interrupt() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move it to qom/cpu.h to avoid issues with include order. Change pc_acpi_smi_interrupt() opaque to X86CPU. Signed-off-by: Andreas Färber --- cpus.c | 2 +- exec.c | 2 +- hw/alpha_typhoon.c | 10 ++++------ hw/apic.c | 21 +++++++++++---------- hw/arm/omap1.c | 4 ++-- hw/arm/pic_cpu.c | 5 ++--- hw/arm/pxa2xx.c | 7 ++++--- hw/arm/pxa2xx_gpio.c | 2 +- hw/arm/pxa2xx_pic.c | 6 +++--- hw/cris/pic_cpu.c | 3 +-- hw/i386/pc.c | 6 +++--- hw/i386/pc_piix.c | 3 ++- hw/lm32/lm32_boards.c | 3 +-- hw/lm32/milkymist.c | 3 +-- hw/lpc_ich9.c | 2 +- hw/microblaze/pic_cpu.c | 3 +-- hw/mips/mips_int.c | 2 +- hw/openrisc/pic_cpu.c | 2 +- hw/ppc/ppc.c | 6 +++--- hw/ppc/ppc405_uc.c | 4 ++-- hw/sh_intc.c | 5 +++-- hw/sparc/leon3.c | 3 ++- hw/sparc/sun4m.c | 9 ++++++--- hw/sparc64/sun4u.c | 4 ++-- hw/unicore32/puv3.c | 3 +-- hw/xtensa/pic_cpu.c | 2 +- include/exec/cpu-all.h | 13 ------------- include/qom/cpu.h | 24 ++++++++++++++++++++++++ kvm-all.c | 4 +--- target-arm/helper.c | 2 +- target-i386/helper.c | 6 +++--- target-m68k/helper.c | 2 +- target-mips/op_helper.c | 8 ++++---- target-ppc/excp_helper.c | 2 +- target-s390x/cpu.h | 6 +++--- target-s390x/helper.c | 4 ++-- translate-all.c | 12 +++++------- 37 files changed, 106 insertions(+), 99 deletions(-) diff --git a/cpus.c b/cpus.c index 8d47bfd85b..e919dd7fb6 100644 --- a/cpus.c +++ b/cpus.c @@ -1309,7 +1309,7 @@ void qmp_inject_nmi(Error **errp) for (env = first_cpu; env != NULL; env = env->next_cpu) { if (!env->apic_state) { - cpu_interrupt(env, CPU_INTERRUPT_NMI); + cpu_interrupt(CPU(x86_env_get_cpu(env)), CPU_INTERRUPT_NMI); } else { apic_deliver_nmi(env->apic_state); } diff --git a/exec.c b/exec.c index ae5a4b4430..c5e65a9380 100644 --- a/exec.c +++ b/exec.c @@ -1467,7 +1467,7 @@ static void check_watchpoint(int offset, int len_mask, int flags) /* We re-entered the check after replacing the TB. Now raise * the debug interrupt so that is will trigger after the * current instruction. */ - cpu_interrupt(env, CPU_INTERRUPT_DEBUG); + cpu_interrupt(ENV_GET_CPU(env), CPU_INTERRUPT_DEBUG); return; } vaddr = (env->mem_io_vaddr & TARGET_PAGE_MASK) + offset; diff --git a/hw/alpha_typhoon.c b/hw/alpha_typhoon.c index 7bfde5771c..770dc8cf0d 100644 --- a/hw/alpha_typhoon.c +++ b/hw/alpha_typhoon.c @@ -62,10 +62,9 @@ static void cpu_irq_change(AlphaCPU *cpu, uint64_t req) { /* If there are any non-masked interrupts, tell the cpu. */ if (cpu != NULL) { - CPUAlphaState *env = &cpu->env; CPUState *cs = CPU(cpu); if (req) { - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } @@ -359,11 +358,10 @@ static void cchip_write(void *opaque, hwaddr addr, for (i = 0; i < 4; ++i) { AlphaCPU *cpu = s->cchip.cpu[i]; if (cpu != NULL) { - CPUAlphaState *env = &cpu->env; CPUState *cs = CPU(cpu); /* IPI can be either cleared or set by the write. */ if (newval & (1 << (i + 8))) { - cpu_interrupt(env, CPU_INTERRUPT_SMP); + cpu_interrupt(cs, CPU_INTERRUPT_SMP); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_SMP); } @@ -687,7 +685,7 @@ static void typhoon_set_timer_irq(void *opaque, int irq, int level) /* Set the ITI bit for this cpu. */ s->cchip.misc |= 1 << (i + 4); /* And signal the interrupt. */ - cpu_interrupt(&cpu->env, CPU_INTERRUPT_TIMER); + cpu_interrupt(CPU(cpu), CPU_INTERRUPT_TIMER); } } } @@ -700,7 +698,7 @@ static void typhoon_alarm_timer(void *opaque) /* Set the ITI bit for this cpu. */ s->cchip.misc |= 1 << (cpu + 4); - cpu_interrupt(&s->cchip.cpu[cpu]->env, CPU_INTERRUPT_TIMER); + cpu_interrupt(CPU(s->cchip.cpu[cpu]), CPU_INTERRUPT_TIMER); } PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus, diff --git a/hw/apic.c b/hw/apic.c index cc9236a41c..d2395f04dd 100644 --- a/hw/apic.c +++ b/hw/apic.c @@ -151,15 +151,15 @@ static void apic_local_deliver(APICCommonState *s, int vector) switch ((lvt >> 8) & 7) { case APIC_DM_SMI: - cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_SMI); + cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_SMI); break; case APIC_DM_NMI: - cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_NMI); + cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_NMI); break; case APIC_DM_EXTINT: - cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_HARD); + cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HARD); break; case APIC_DM_FIXED: @@ -248,20 +248,20 @@ static void apic_bus_deliver(const uint32_t *deliver_bitmask, case APIC_DM_SMI: foreach_apic(apic_iter, deliver_bitmask, - cpu_interrupt(&apic_iter->cpu->env, CPU_INTERRUPT_SMI) + cpu_interrupt(CPU(apic_iter->cpu), CPU_INTERRUPT_SMI) ); return; case APIC_DM_NMI: foreach_apic(apic_iter, deliver_bitmask, - cpu_interrupt(&apic_iter->cpu->env, CPU_INTERRUPT_NMI) + cpu_interrupt(CPU(apic_iter->cpu), CPU_INTERRUPT_NMI) ); return; case APIC_DM_INIT: /* normal INIT IPI sent to processors */ foreach_apic(apic_iter, deliver_bitmask, - cpu_interrupt(&apic_iter->cpu->env, + cpu_interrupt(CPU(apic_iter->cpu), CPU_INTERRUPT_INIT) ); return; @@ -363,15 +363,16 @@ static int apic_irq_pending(APICCommonState *s) /* signal the CPU if an irq is pending */ static void apic_update_irq(APICCommonState *s) { - CPUState *cpu = CPU(s->cpu); + CPUState *cpu; if (!(s->spurious_vec & APIC_SV_ENABLE)) { return; } + cpu = CPU(s->cpu); if (!qemu_cpu_is_self(cpu)) { - cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_POLL); + cpu_interrupt(cpu, CPU_INTERRUPT_POLL); } else if (apic_irq_pending(s) > 0) { - cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_HARD); + cpu_interrupt(cpu, CPU_INTERRUPT_HARD); } } @@ -478,7 +479,7 @@ static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask, static void apic_startup(APICCommonState *s, int vector_num) { s->sipi_vector = vector_num; - cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_SIPI); + cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI); } void apic_sipi(DeviceState *d) diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c index 7afd590ec7..3245c62e68 100644 --- a/hw/arm/omap1.c +++ b/hw/arm/omap1.c @@ -1523,7 +1523,7 @@ static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s, omap_clk clk; if (value & (1 << 11)) { /* SETARM_IDLE */ - cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_HALT); + cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT); } if (!(value & (1 << 10))) /* WKUP_MODE */ qemu_system_shutdown_request(); /* XXX: disable wakeup from IRQ */ @@ -3759,7 +3759,7 @@ void omap_mpu_wakeup(void *opaque, int irq, int req) CPUState *cpu = CPU(mpu->cpu); if (cpu->halted) { - cpu_interrupt(&mpu->cpu->env, CPU_INTERRUPT_EXITTB); + cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB); } } diff --git a/hw/arm/pic_cpu.c b/hw/arm/pic_cpu.c index 95f5bf1777..3a3f06566b 100644 --- a/hw/arm/pic_cpu.c +++ b/hw/arm/pic_cpu.c @@ -15,20 +15,19 @@ static void arm_pic_cpu_handler(void *opaque, int irq, int level) { ARMCPU *cpu = opaque; - CPUARMState *env = &cpu->env; CPUState *cs = CPU(cpu); switch (irq) { case ARM_PIC_CPU_IRQ: if (level) { - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } break; case ARM_PIC_CPU_FIQ: if (level) { - cpu_interrupt(env, CPU_INTERRUPT_FIQ); + cpu_interrupt(cs, CPU_INTERRUPT_FIQ); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_FIQ); } diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c index c0f50c90fe..7467cca4f7 100644 --- a/hw/arm/pxa2xx.c +++ b/hw/arm/pxa2xx.c @@ -263,14 +263,14 @@ static int pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri, case 1: /* Idle */ if (!(s->cm_regs[CCCR >> 2] & (1 << 31))) { /* CPDIS */ - cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_HALT); + cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT); break; } /* Fall through. */ case 2: /* Deep-Idle */ - cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_HALT); + cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT); s->pm_regs[RCSR >> 2] |= 0x8; /* Set GPR */ goto message; @@ -301,7 +301,8 @@ static int pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri, #endif /* Suspend */ - cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT); + cpu_interrupt(CPU(arm_env_get_cpu(cpu_single_env)), + CPU_INTERRUPT_HALT); goto message; diff --git a/hw/arm/pxa2xx_gpio.c b/hw/arm/pxa2xx_gpio.c index d2da928ac0..55ebcd724a 100644 --- a/hw/arm/pxa2xx_gpio.c +++ b/hw/arm/pxa2xx_gpio.c @@ -120,7 +120,7 @@ static void pxa2xx_gpio_set(void *opaque, int line, int level) /* Wake-up GPIOs */ if (cpu->halted && (mask & ~s->dir[bank] & pxa2xx_gpio_wake[bank])) { - cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_EXITTB); + cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB); } } diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c index b45b371435..25e90895e1 100644 --- a/hw/arm/pxa2xx_pic.c +++ b/hw/arm/pxa2xx_pic.c @@ -52,7 +52,7 @@ static void pxa2xx_pic_update(void *opaque) mask[0] = s->int_pending[0] & (s->int_enabled[0] | s->int_idle); mask[1] = s->int_pending[1] & (s->int_enabled[1] | s->int_idle); if (mask[0] || mask[1]) { - cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_EXITTB); + cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB); } } @@ -60,13 +60,13 @@ static void pxa2xx_pic_update(void *opaque) mask[1] = s->int_pending[1] & s->int_enabled[1]; if ((mask[0] & s->is_fiq[0]) || (mask[1] & s->is_fiq[1])) { - cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_FIQ); + cpu_interrupt(cpu, CPU_INTERRUPT_FIQ); } else { cpu_reset_interrupt(cpu, CPU_INTERRUPT_FIQ); } if ((mask[0] & ~s->is_fiq[0]) || (mask[1] & ~s->is_fiq[1])) { - cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_HARD); + cpu_interrupt(cpu, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD); } diff --git a/hw/cris/pic_cpu.c b/hw/cris/pic_cpu.c index afd0df8041..85c68c0497 100644 --- a/hw/cris/pic_cpu.c +++ b/hw/cris/pic_cpu.c @@ -31,12 +31,11 @@ static void cris_pic_cpu_handler(void *opaque, int irq, int level) { CRISCPU *cpu = opaque; - CPUCRISState *env = &cpu->env; CPUState *cs = CPU(cpu); int type = irq ? CPU_INTERRUPT_NMI : CPU_INTERRUPT_HARD; if (level) { - cpu_interrupt(env, type); + cpu_interrupt(cs, type); } else { cpu_reset_interrupt(cs, type); } diff --git a/hw/i386/pc.c b/hw/i386/pc.c index c731bdc024..ed7d9badb5 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -192,7 +192,7 @@ static void pic_irq_request(void *opaque, int irq, int level) } else { CPUState *cs = CPU(x86_env_get_cpu(env)); if (level) { - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } @@ -856,10 +856,10 @@ DeviceState *cpu_get_current_apic(void) void pc_acpi_smi_interrupt(void *opaque, int irq, int level) { - CPUX86State *s = opaque; + X86CPU *cpu = opaque; if (level) { - cpu_interrupt(s, CPU_INTERRUPT_SMI); + cpu_interrupt(CPU(cpu), CPU_INTERRUPT_SMI); } } diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 0ee3b3b806..0abc9f11e3 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -205,7 +205,8 @@ static void pc_init1(MemoryRegion *system_memory, if (pci_enabled && acpi_enabled) { i2c_bus *smbus; - smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1); + smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, + x86_env_get_cpu(first_cpu), 1); /* TODO: Populate SPD eeprom data. */ smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, gsi[9], *smi_irq, diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c index 538c20397f..db92948092 100644 --- a/hw/lm32/lm32_boards.c +++ b/hw/lm32/lm32_boards.c @@ -42,11 +42,10 @@ typedef struct { static void cpu_irq_handler(void *opaque, int irq, int level) { LM32CPU *cpu = opaque; - CPULM32State *env = &cpu->env; CPUState *cs = CPU(cpu); if (level) { - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c index 9ff6d28854..b347cf964c 100644 --- a/hw/lm32/milkymist.c +++ b/hw/lm32/milkymist.c @@ -47,11 +47,10 @@ typedef struct { static void cpu_irq_handler(void *opaque, int irq, int level) { LM32CPU *cpu = opaque; - CPULM32State *env = &cpu->env; CPUState *cs = CPU(cpu); if (level) { - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } diff --git a/hw/lpc_ich9.c b/hw/lpc_ich9.c index 0ca0a59ef7..ff0a3092d5 100644 --- a/hw/lpc_ich9.c +++ b/hw/lpc_ich9.c @@ -381,7 +381,7 @@ static void ich9_apm_ctrl_changed(uint32_t val, void *arg) /* SMI_EN = PMBASE + 30. SMI control and enable register */ if (lpc->pm.smi_en & ICH9_PMIO_SMI_EN_APMC_EN) { - cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI); + cpu_interrupt(CPU(x86_env_get_cpu(first_cpu)), CPU_INTERRUPT_SMI); } } diff --git a/hw/microblaze/pic_cpu.c b/hw/microblaze/pic_cpu.c index 47568505c7..6248de92bb 100644 --- a/hw/microblaze/pic_cpu.c +++ b/hw/microblaze/pic_cpu.c @@ -30,12 +30,11 @@ static void microblaze_pic_cpu_handler(void *opaque, int irq, int level) { MicroBlazeCPU *cpu = opaque; - CPUMBState *env = &cpu->env; CPUState *cs = CPU(cpu); int type = irq ? CPU_INTERRUPT_NMI : CPU_INTERRUPT_HARD; if (level) { - cpu_interrupt(env, type); + cpu_interrupt(cs, type); } else { cpu_reset_interrupt(cs, type); } diff --git a/hw/mips/mips_int.c b/hw/mips/mips_int.c index 3a78999e02..0e5e86699c 100644 --- a/hw/mips/mips_int.c +++ b/hw/mips/mips_int.c @@ -40,7 +40,7 @@ static void cpu_mips_irq_request(void *opaque, int irq, int level) } if (env->CP0_Cause & CP0Ca_IP_mask) { - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } diff --git a/hw/openrisc/pic_cpu.c b/hw/openrisc/pic_cpu.c index 7e4f9e015e..ca0b7c11bd 100644 --- a/hw/openrisc/pic_cpu.c +++ b/hw/openrisc/pic_cpu.c @@ -41,7 +41,7 @@ static void openrisc_pic_cpu_handler(void *opaque, int irq, int level) for (i = 0; i < 32; i++) { if ((cpu->env.picsr && (1 << i)) && (cpu->env.picmr && (1 << i))) { - cpu_interrupt(&cpu->env, CPU_INTERRUPT_HARD); + cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); cpu->env.picsr &= ~(1 << i); diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index ae2ed70181..85bc821d94 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -58,7 +58,7 @@ void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level) if (level) { env->pending_interrupts |= 1 << n_IRQ; - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { env->pending_interrupts &= ~(1 << n_IRQ); if (env->pending_interrupts == 0) { @@ -137,7 +137,7 @@ static void ppc6xx_set_irq(void *opaque, int pin, int level) /* Level sensitive - active low */ if (level) { LOG_IRQ("%s: reset the CPU\n", __func__); - cpu_interrupt(env, CPU_INTERRUPT_RESET); + cpu_interrupt(cs, CPU_INTERRUPT_RESET); } break; case PPC6xx_INPUT_SRESET: @@ -219,7 +219,7 @@ static void ppc970_set_irq(void *opaque, int pin, int level) case PPC970_INPUT_HRESET: /* Level sensitive - active low */ if (level) { - cpu_interrupt(env, CPU_INTERRUPT_RESET); + cpu_interrupt(cs, CPU_INTERRUPT_RESET); } break; case PPC970_INPUT_SRESET: diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c index 8465f6dcd4..56bae8f6e0 100644 --- a/hw/ppc/ppc405_uc.c +++ b/hw/ppc/ppc405_uc.c @@ -1776,7 +1776,7 @@ void ppc40x_core_reset(PowerPCCPU *cpu) target_ulong dbsr; printf("Reset PowerPC core\n"); - cpu_interrupt(env, CPU_INTERRUPT_RESET); + cpu_interrupt(CPU(cpu), CPU_INTERRUPT_RESET); dbsr = env->spr[SPR_40x_DBSR]; dbsr &= ~0x00000300; dbsr |= 0x00000100; @@ -1789,7 +1789,7 @@ void ppc40x_chip_reset(PowerPCCPU *cpu) target_ulong dbsr; printf("Reset PowerPC chip\n"); - cpu_interrupt(env, CPU_INTERRUPT_RESET); + cpu_interrupt(CPU(cpu), CPU_INTERRUPT_RESET); /* XXX: TODO reset all internal peripherals */ dbsr = env->spr[SPR_40x_DBSR]; dbsr &= ~0x00000300; diff --git a/hw/sh_intc.c b/hw/sh_intc.c index 97903140ab..29e3d8f127 100644 --- a/hw/sh_intc.c +++ b/hw/sh_intc.c @@ -45,8 +45,9 @@ void sh_intc_toggle_source(struct intc_source *source, CPUState *cpu = CPU(sh_env_get_cpu(first_cpu)); if (source->pending) { source->parent->pending++; - if (source->parent->pending == 1) - cpu_interrupt(first_cpu, CPU_INTERRUPT_HARD); + if (source->parent->pending == 1) { + cpu_interrupt(cpu, CPU_INTERRUPT_HARD); + } } else { source->parent->pending--; if (source->parent->pending == 0) { diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index b1fbde0ff7..bf06bf4b51 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -83,8 +83,9 @@ static void leon3_set_pil_in(void *opaque, uint32_t pil_in) env->interrupt_index = TT_EXTINT | i; if (old_interrupt != env->interrupt_index) { + cs = CPU(sparc_env_get_cpu(env)); trace_leon3_set_irq(i); - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(cs, CPU_INTERRUPT_HARD); } break; } diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index a1822f16f3..2f214da557 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -242,8 +242,9 @@ void cpu_check_irqs(CPUSPARCState *env) env->interrupt_index = TT_EXTINT | i; if (old_interrupt != env->interrupt_index) { + cs = CPU(sparc_env_get_cpu(env)); trace_sun4m_cpu_interrupt(i); - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(cs, CPU_INTERRUPT_HARD); } break; } @@ -306,8 +307,10 @@ static void secondary_cpu_reset(void *opaque) static void cpu_halt_signal(void *opaque, int irq, int level) { - if (level && cpu_single_env) - cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT); + if (level && cpu_single_env) { + cpu_interrupt(CPU(sparc_env_get_cpu(cpu_single_env)), + CPU_INTERRUPT_HALT); + } } static uint64_t translate_kernel_address(void *opaque, uint64_t addr) diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index 817c23cde3..4c39cf6607 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -299,7 +299,7 @@ void cpu_check_irqs(CPUSPARCState *env) env->interrupt_index = new_interrupt; CPUIRQ_DPRINTF("Set CPU IRQ %d old=%x new=%x\n", i, old_interrupt, new_interrupt); - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(cs, CPU_INTERRUPT_HARD); } break; } @@ -339,7 +339,7 @@ static void cpu_set_ivec_irq(void *opaque, int irq, int level) env->ivec_data[0] = (0x1f << 6) | irq; env->ivec_data[1] = 0; env->ivec_data[2] = 0; - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(cs, CPU_INTERRUPT_HARD); } } else { if (env->ivec_status & 0x20) { diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c index 6e87c41f28..78ab13f9ed 100644 --- a/hw/unicore32/puv3.c +++ b/hw/unicore32/puv3.c @@ -27,12 +27,11 @@ static void puv3_intc_cpu_handler(void *opaque, int irq, int level) { UniCore32CPU *cpu = opaque; - CPUUniCore32State *env = &cpu->env; CPUState *cs = CPU(cpu); assert(irq == 0); if (level) { - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } diff --git a/hw/xtensa/pic_cpu.c b/hw/xtensa/pic_cpu.c index fd590c64ce..7f015ff5ab 100644 --- a/hw/xtensa/pic_cpu.c +++ b/hw/xtensa/pic_cpu.c @@ -66,7 +66,7 @@ void check_interrupts(CPUXtensaState *env) for (level = env->config->nlevel; level > minlevel; --level) { if (env->config->level_mask[level] & int_set_enabled) { env->pending_irq_level = level; - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(cs, CPU_INTERRUPT_HARD); qemu_log_mask(CPU_LOG_INT, "%s level = %d, cintlevel = %d, " "pc = %08x, a0 = %08x, ps = %08x, " diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 5218a53576..e9c3717863 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -421,19 +421,6 @@ DECLARE_TLS(CPUArchState *,cpu_single_env); | CPU_INTERRUPT_TGT_EXT_3 \ | CPU_INTERRUPT_TGT_EXT_4) -#ifndef CONFIG_USER_ONLY -typedef void (*CPUInterruptHandler)(CPUArchState *, int); - -extern CPUInterruptHandler cpu_interrupt_handler; - -static inline void cpu_interrupt(CPUArchState *s, int mask) -{ - cpu_interrupt_handler(s, mask); -} -#else /* USER_ONLY */ -void cpu_interrupt(CPUArchState *env, int mask); -#endif /* USER_ONLY */ - void cpu_exit(CPUArchState *s); /* Breakpoint/watchpoint flags */ diff --git a/include/qom/cpu.h b/include/qom/cpu.h index b83ba6f150..2e08135acd 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -221,6 +221,30 @@ void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data); */ CPUState *qemu_get_cpu(int index); +#ifndef CONFIG_USER_ONLY + +typedef void (*CPUInterruptHandler)(CPUState *, int); + +extern CPUInterruptHandler cpu_interrupt_handler; + +/** + * cpu_interrupt: + * @cpu: The CPU to set an interrupt on. + * @mask: The interupts to set. + * + * Invokes the interrupt handler. + */ +static inline void cpu_interrupt(CPUState *cpu, int mask) +{ + cpu_interrupt_handler(cpu, mask); +} + +#else /* USER_ONLY */ + +void cpu_interrupt(CPUState *cpu, int mask); + +#endif /* USER_ONLY */ + /** * cpu_reset_interrupt: * @cpu: The CPU to clear the interrupt on. diff --git a/kvm-all.c b/kvm-all.c index 2b761e0a0d..9b433d3163 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -826,10 +826,8 @@ static MemoryListener kvm_io_listener = { .priority = 10, }; -static void kvm_handle_interrupt(CPUArchState *env, int mask) +static void kvm_handle_interrupt(CPUState *cpu, int mask) { - CPUState *cpu = ENV_GET_CPU(env); - cpu->interrupt_request |= mask; if (!qemu_cpu_is_self(cpu)) { diff --git a/target-arm/helper.c b/target-arm/helper.c index d7e22dda13..f839726f52 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -764,7 +764,7 @@ static int omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { /* Wait-for-interrupt (deprecated) */ - cpu_interrupt(env, CPU_INTERRUPT_HALT); + cpu_interrupt(CPU(arm_env_get_cpu(env)), CPU_INTERRUPT_HALT); return 0; } diff --git a/target-i386/helper.c b/target-i386/helper.c index b49a0fc5f3..9449a0c49d 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -389,7 +389,7 @@ void x86_cpu_set_a20(X86CPU *cpu, int a20_state) #endif /* if the cpu is currently executing code, we must unlink it and all the potentially executing TB */ - cpu_interrupt(env, CPU_INTERRUPT_EXITTB); + cpu_interrupt(CPU(cpu), CPU_INTERRUPT_EXITTB); /* when a20 is changed, all the MMU mappings are invalid, so we must flush everything */ @@ -1169,7 +1169,7 @@ static void do_inject_x86_mce(void *data) banks[3] = params->misc; cenv->mcg_status = params->mcg_status; banks[1] = params->status; - cpu_interrupt(cenv, CPU_INTERRUPT_MCE); + cpu_interrupt(cpu, CPU_INTERRUPT_MCE); } else if (!(banks[1] & MCI_STATUS_VAL) || !(banks[1] & MCI_STATUS_UC)) { if (banks[1] & MCI_STATUS_VAL) { @@ -1241,7 +1241,7 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access) if (kvm_enabled()) { env->tpr_access_type = access; - cpu_interrupt(env, CPU_INTERRUPT_TPR); + cpu_interrupt(CPU(x86_env_get_cpu(env)), CPU_INTERRUPT_TPR); } else { cpu_restore_state(env, env->mem_io_pc); diff --git a/target-m68k/helper.c b/target-m68k/helper.c index d9c8374be4..54fa419ace 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -318,7 +318,7 @@ void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector) env->pending_level = level; env->pending_vector = vector; if (level) { - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index d568188703..3fa0d00cf9 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -523,12 +523,12 @@ static bool mips_vpe_is_wfi(MIPSCPU *c) return cpu->halted && mips_vpe_active(env); } -static inline void mips_vpe_wake(CPUMIPSState *c) +static inline void mips_vpe_wake(MIPSCPU *c) { /* Dont set ->halted = 0 directly, let it be done via cpu_has_work because there might be other conditions that state that c should be sleeping. */ - cpu_interrupt(c, CPU_INTERRUPT_WAKE); + cpu_interrupt(CPU(c), CPU_INTERRUPT_WAKE); } static inline void mips_vpe_sleep(MIPSCPU *cpu) @@ -547,7 +547,7 @@ static inline void mips_tc_wake(MIPSCPU *cpu, int tc) /* FIXME: TC reschedule. */ if (mips_vpe_active(c) && !mips_vpe_is_wfi(cpu)) { - mips_vpe_wake(c); + mips_vpe_wake(cpu); } } @@ -1725,7 +1725,7 @@ target_ulong helper_evpe(CPUMIPSState *env) && !mips_vpe_is_wfi(other_cpu)) { /* Enable the VPE. */ other_cpu_env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP); - mips_vpe_wake(other_cpu_env); /* And wake it up. */ + mips_vpe_wake(other_cpu); /* And wake it up. */ } other_cpu_env = other_cpu_env->next_cpu; } while (other_cpu_env); diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c index 79ce7bf7c4..d1767340ef 100644 --- a/target-ppc/excp_helper.c +++ b/target-ppc/excp_helper.c @@ -991,7 +991,7 @@ void helper_msgsnd(target_ulong rb) for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) { if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) { cenv->pending_interrupts |= 1 << irq; - cpu_interrupt(cenv, CPU_INTERRUPT_HARD); + cpu_interrupt(CPU(ppc_env_get_cpu(cenv)), CPU_INTERRUPT_HARD); } } } diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index db263bf4e3..642e661e7d 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -992,7 +992,7 @@ static inline void cpu_inject_ext(S390CPU *cpu, uint32_t code, uint32_t param, env->ext_queue[env->ext_index].param64 = param64; env->pending_int |= INTERRUPT_EXT; - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD); } static inline void cpu_inject_io(S390CPU *cpu, uint16_t subchannel_id, @@ -1016,7 +1016,7 @@ static inline void cpu_inject_io(S390CPU *cpu, uint16_t subchannel_id, env->io_queue[env->io_index[isc]][isc].word = io_int_word; env->pending_int |= INTERRUPT_IO; - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD); } static inline void cpu_inject_crw_mchk(S390CPU *cpu) @@ -1034,7 +1034,7 @@ static inline void cpu_inject_crw_mchk(S390CPU *cpu) env->mchk_queue[env->mchk_index].type = 1; env->pending_int |= INTERRUPT_MCHK; - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD); } static inline bool cpu_has_work(CPUState *cpu) diff --git a/target-s390x/helper.c b/target-s390x/helper.c index c88a58743e..2cb8dc86e3 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -57,7 +57,7 @@ void s390x_tod_timer(void *opaque) CPUS390XState *env = &cpu->env; env->pending_int |= INTERRUPT_TOD; - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD); } void s390x_cpu_timer(void *opaque) @@ -66,7 +66,7 @@ void s390x_cpu_timer(void *opaque) CPUS390XState *env = &cpu->env; env->pending_int |= INTERRUPT_CPUTIMER; - cpu_interrupt(env, CPU_INTERRUPT_HARD); + cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD); } #endif diff --git a/translate-all.c b/translate-all.c index f0c7d1e4c9..1f3237e60e 100644 --- a/translate-all.c +++ b/translate-all.c @@ -1077,8 +1077,8 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, tb_phys_invalidate(tb, -1); if (cpu != NULL) { cpu->current_tb = saved_tb; - if (env && cpu->interrupt_request && cpu->current_tb) { - cpu_interrupt(env, cpu->interrupt_request); + if (cpu->interrupt_request && cpu->current_tb) { + cpu_interrupt(cpu, cpu->interrupt_request); } } } @@ -1382,9 +1382,9 @@ void tb_check_watchpoint(CPUArchState *env) #ifndef CONFIG_USER_ONLY /* mask must never be zero, except for A20 change call */ -static void tcg_handle_interrupt(CPUArchState *env, int mask) +static void tcg_handle_interrupt(CPUState *cpu, int mask) { - CPUState *cpu = ENV_GET_CPU(env); + CPUArchState *env = cpu->env_ptr; int old_mask; old_mask = cpu->interrupt_request; @@ -1552,10 +1552,8 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf) #else /* CONFIG_USER_ONLY */ -void cpu_interrupt(CPUArchState *env, int mask) +void cpu_interrupt(CPUState *cpu, int mask) { - CPUState *cpu = ENV_GET_CPU(env); - cpu->interrupt_request |= mask; cpu->tcg_exit_req = 1; } From 97a8ea5a3ae7938cb54fd4dc19d3a413024bc6c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 2 Feb 2013 10:57:51 +0100 Subject: [PATCH 15/17] cpu: Replace do_interrupt() by CPUClass::do_interrupt method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This removes a global per-target function and thus takes us one step closer to compiling multiple targets into one executable. It will also allow to override the interrupt handling for certain CPU families. Signed-off-by: Andreas Färber --- cpu-exec.c | 36 ++++++++++++++++++++---------------- include/qom/cpu.h | 2 ++ target-alpha/cpu-qom.h | 2 ++ target-alpha/cpu.c | 1 + target-alpha/cpu.h | 1 - target-alpha/helper.c | 4 +++- target-arm/cpu-qom.h | 2 ++ target-arm/cpu.c | 1 + target-arm/cpu.h | 1 - target-arm/helper.c | 11 +++++++---- target-cris/cpu-qom.h | 2 ++ target-cris/cpu.c | 1 + target-cris/cpu.h | 1 - target-cris/helper.c | 10 +++++++--- target-i386/cpu-qom.h | 6 ++++++ target-i386/cpu.c | 1 + target-i386/cpu.h | 3 +-- target-i386/seg_helper.c | 5 ++++- target-lm32/cpu-qom.h | 2 ++ target-lm32/cpu.c | 2 ++ target-lm32/cpu.h | 1 - target-lm32/helper.c | 5 ++++- target-m68k/cpu-qom.h | 2 ++ target-m68k/cpu.c | 1 + target-m68k/cpu.h | 1 - target-m68k/op_helper.c | 10 ++++++++-- target-microblaze/cpu-qom.h | 2 ++ target-microblaze/cpu.c | 1 + target-microblaze/cpu.h | 1 - target-microblaze/helper.c | 9 +++++++-- target-mips/cpu-qom.h | 2 ++ target-mips/cpu.c | 2 ++ target-mips/cpu.h | 1 - target-mips/helper.c | 5 +++-- target-openrisc/cpu.c | 1 + target-openrisc/cpu.h | 2 +- target-openrisc/interrupt.c | 4 +++- target-ppc/cpu-qom.h | 2 ++ target-ppc/cpu.h | 1 - target-ppc/excp_helper.c | 10 +++++++--- target-ppc/translate_init.c | 1 + target-s390x/cpu-qom.h | 2 ++ target-s390x/cpu.c | 1 + target-s390x/cpu.h | 1 - target-s390x/helper.c | 12 +++++++----- target-sh4/cpu-qom.h | 2 ++ target-sh4/cpu.c | 1 + target-sh4/cpu.h | 1 - target-sh4/helper.c | 12 ++++++++---- target-sparc/cpu-qom.h | 2 ++ target-sparc/cpu.c | 2 ++ target-sparc/cpu.h | 1 - target-sparc/int32_helper.c | 4 +++- target-sparc/int64_helper.c | 4 +++- target-unicore32/cpu-qom.h | 2 ++ target-unicore32/cpu.c | 1 + target-unicore32/cpu.h | 1 - target-unicore32/helper.c | 5 ++++- target-unicore32/softmmu.c | 5 +++-- target-xtensa/cpu-qom.h | 2 ++ target-xtensa/cpu.c | 1 + target-xtensa/cpu.h | 1 - target-xtensa/helper.c | 5 ++++- 63 files changed, 159 insertions(+), 67 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index c9e1a8208b..94fedc5805 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -198,6 +198,10 @@ volatile sig_atomic_t exit_request; int cpu_exec(CPUArchState *env) { CPUState *cpu = ENV_GET_CPU(env); +#if !(defined(CONFIG_USER_ONLY) && \ + (defined(TARGET_M68K) || defined(TARGET_PPC) || defined(TARGET_S390X))) + CPUClass *cc = CPU_GET_CLASS(cpu); +#endif int ret, interrupt_request; TranslationBlock *tb; uint8_t *tc_ptr; @@ -265,12 +269,12 @@ int cpu_exec(CPUArchState *env) which will be handled outside the cpu execution loop */ #if defined(TARGET_I386) - do_interrupt(env); + cc->do_interrupt(cpu); #endif ret = env->exception_index; break; #else - do_interrupt(env); + cc->do_interrupt(cpu); env->exception_index = -1; #endif } @@ -380,7 +384,7 @@ int cpu_exec(CPUArchState *env) if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->ie & IE_IE)) { env->exception_index = EXCP_IRQ; - do_interrupt(env); + cc->do_interrupt(cpu); next_tb = 0; } #elif defined(TARGET_MICROBLAZE) @@ -389,7 +393,7 @@ int cpu_exec(CPUArchState *env) && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP)) && !(env->iflags & (D_FLAG | IMM_FLAG))) { env->exception_index = EXCP_IRQ; - do_interrupt(env); + cc->do_interrupt(cpu); next_tb = 0; } #elif defined(TARGET_MIPS) @@ -398,7 +402,7 @@ int cpu_exec(CPUArchState *env) /* Raise it */ env->exception_index = EXCP_EXT_INTERRUPT; env->error_code = 0; - do_interrupt(env); + cc->do_interrupt(cpu); next_tb = 0; } #elif defined(TARGET_OPENRISC) @@ -414,7 +418,7 @@ int cpu_exec(CPUArchState *env) } if (idx >= 0) { env->exception_index = idx; - do_interrupt(env); + cc->do_interrupt(cpu); next_tb = 0; } } @@ -429,7 +433,7 @@ int cpu_exec(CPUArchState *env) cpu_pil_allowed(env, pil)) || type != TT_EXTINT) { env->exception_index = env->interrupt_index; - do_interrupt(env); + cc->do_interrupt(cpu); next_tb = 0; } } @@ -438,7 +442,7 @@ int cpu_exec(CPUArchState *env) if (interrupt_request & CPU_INTERRUPT_FIQ && !(env->uncached_cpsr & CPSR_F)) { env->exception_index = EXCP_FIQ; - do_interrupt(env); + cc->do_interrupt(cpu); next_tb = 0; } /* ARMv7-M interrupt return works by loading a magic value @@ -454,19 +458,19 @@ int cpu_exec(CPUArchState *env) && ((IS_M(env) && env->regs[15] < 0xfffffff0) || !(env->uncached_cpsr & CPSR_I))) { env->exception_index = EXCP_IRQ; - do_interrupt(env); + cc->do_interrupt(cpu); next_tb = 0; } #elif defined(TARGET_UNICORE32) if (interrupt_request & CPU_INTERRUPT_HARD && !(env->uncached_asr & ASR_I)) { env->exception_index = UC32_EXCP_INTR; - do_interrupt(env); + cc->do_interrupt(cpu); next_tb = 0; } #elif defined(TARGET_SH4) if (interrupt_request & CPU_INTERRUPT_HARD) { - do_interrupt(env); + cc->do_interrupt(cpu); next_tb = 0; } #elif defined(TARGET_ALPHA) @@ -497,7 +501,7 @@ int cpu_exec(CPUArchState *env) if (idx >= 0) { env->exception_index = idx; env->error_code = 0; - do_interrupt(env); + cc->do_interrupt(cpu); next_tb = 0; } } @@ -506,7 +510,7 @@ int cpu_exec(CPUArchState *env) && (env->pregs[PR_CCS] & I_FLAG) && !env->locked_irq) { env->exception_index = EXCP_IRQ; - do_interrupt(env); + cc->do_interrupt(cpu); next_tb = 0; } if (interrupt_request & CPU_INTERRUPT_NMI) { @@ -518,7 +522,7 @@ int cpu_exec(CPUArchState *env) } if ((env->pregs[PR_CCS] & m_flag_archval)) { env->exception_index = EXCP_NMI; - do_interrupt(env); + cc->do_interrupt(cpu); next_tb = 0; } } @@ -538,13 +542,13 @@ int cpu_exec(CPUArchState *env) #elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY) if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->psw.mask & PSW_MASK_EXT)) { - do_interrupt(env); + cc->do_interrupt(cpu); next_tb = 0; } #elif defined(TARGET_XTENSA) if (interrupt_request & CPU_INTERRUPT_HARD) { env->exception_index = EXC_IRQ; - do_interrupt(env); + cc->do_interrupt(cpu); next_tb = 0; } #endif diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 2e08135acd..3664a1b631 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -44,6 +44,7 @@ typedef struct CPUState CPUState; * @class_by_name: Callback to map -cpu command line model name to an * instantiatable CPU type. * @reset: Callback to reset the #CPUState to its initial state. + * @do_interrupt: Callback for interrupt handling. * @vmsd: State description for migration. * * Represents a CPU family or model. @@ -56,6 +57,7 @@ typedef struct CPUClass { ObjectClass *(*class_by_name)(const char *cpu_model); void (*reset)(CPUState *cpu); + void (*do_interrupt)(CPUState *cpu); const struct VMStateDescription *vmsd; } CPUClass; diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h index 252bd14821..32ee286db3 100644 --- a/target-alpha/cpu-qom.h +++ b/target-alpha/cpu-qom.h @@ -74,4 +74,6 @@ static inline AlphaCPU *alpha_env_get_cpu(CPUAlphaState *env) #define ENV_OFFSET offsetof(AlphaCPU, env) +void alpha_cpu_do_interrupt(CPUState *cpu); + #endif diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c index cec9989925..cad1716601 100644 --- a/target-alpha/cpu.c +++ b/target-alpha/cpu.c @@ -263,6 +263,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data) dc->realize = alpha_cpu_realizefn; cc->class_by_name = alpha_cpu_class_by_name; + cc->do_interrupt = alpha_cpu_do_interrupt; } static const TypeInfo alpha_cpu_type_info = { diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index 90f78acc30..2156a1e5fd 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -449,7 +449,6 @@ int cpu_alpha_signal_handler(int host_signum, void *pinfo, int cpu_alpha_handle_mmu_fault (CPUAlphaState *env, uint64_t address, int rw, int mmu_idx); #define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault -void do_interrupt (CPUAlphaState *env); void do_restore_state(CPUAlphaState *, uintptr_t retaddr); void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int); void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t); diff --git a/target-alpha/helper.c b/target-alpha/helper.c index 22c9c6ec8c..5741ec25ea 100644 --- a/target-alpha/helper.c +++ b/target-alpha/helper.c @@ -345,8 +345,10 @@ int cpu_alpha_handle_mmu_fault(CPUAlphaState *env, target_ulong addr, int rw, } #endif /* USER_ONLY */ -void do_interrupt (CPUAlphaState *env) +void alpha_cpu_do_interrupt(CPUState *cs) { + AlphaCPU *cpu = ALPHA_CPU(cs); + CPUAlphaState *env = &cpu->env; int i = env->exception_index; if (qemu_loglevel_mask(CPU_LOG_INT)) { diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index 7539727768..eeecc9265d 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -113,4 +113,6 @@ static inline ARMCPU *arm_env_get_cpu(CPUARMState *env) void register_cp_regs_for_features(ARMCPU *cpu); +void arm_cpu_do_interrupt(CPUState *cpu); + #endif diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 5dfcb740d9..aeaa3b7834 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -802,6 +802,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) cc->reset = arm_cpu_reset; cc->class_by_name = arm_cpu_class_by_name; + cc->do_interrupt = arm_cpu_do_interrupt; } static void cpu_register(const ARMCPUInfo *info) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 957866c0e2..2b97221209 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -236,7 +236,6 @@ ARMCPU *cpu_arm_init(const char *cpu_model); void arm_translate_init(void); void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu); int cpu_arm_exec(CPUARMState *s); -void do_interrupt(CPUARMState *); int bank_number(int mode); void switch_mode(CPUARMState *, int); uint32_t do_arm_semihosting(CPUARMState *env); diff --git a/target-arm/helper.c b/target-arm/helper.c index f839726f52..b4cbb8718a 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1567,8 +1567,11 @@ uint32_t HELPER(rbit)(uint32_t x) #if defined(CONFIG_USER_ONLY) -void do_interrupt (CPUARMState *env) +void arm_cpu_do_interrupt(CPUState *cs) { + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + env->exception_index = -1; } @@ -1799,9 +1802,10 @@ static void do_interrupt_v7m(CPUARMState *env) } /* Handle a CPU exception. */ -void do_interrupt(CPUARMState *env) +void arm_cpu_do_interrupt(CPUState *cs) { - CPUState *cs; + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; uint32_t addr; uint32_t mask; int new_mode; @@ -1908,7 +1912,6 @@ void do_interrupt(CPUARMState *env) } env->regs[14] = env->regs[15] + offset; env->regs[15] = addr; - cs = CPU(arm_env_get_cpu(env)); cs->interrupt_request |= CPU_INTERRUPT_EXITTB; } diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h index 11e528661d..deea1d804b 100644 --- a/target-cris/cpu-qom.h +++ b/target-cris/cpu-qom.h @@ -73,4 +73,6 @@ static inline CRISCPU *cris_env_get_cpu(CPUCRISState *env) #define ENV_OFFSET offsetof(CRISCPU, env) +void cris_cpu_do_interrupt(CPUState *cpu); + #endif diff --git a/target-cris/cpu.c b/target-cris/cpu.c index 7974be33f2..95cbf399d9 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -243,6 +243,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data) cc->reset = cris_cpu_reset; cc->class_by_name = cris_cpu_class_by_name; + cc->do_interrupt = cris_cpu_do_interrupt; } static const TypeInfo cris_cpu_type_info = { diff --git a/target-cris/cpu.h b/target-cris/cpu.h index 2fc7c5c772..dbd7d36870 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -175,7 +175,6 @@ typedef struct CPUCRISState { CRISCPU *cpu_cris_init(const char *cpu_model); int cpu_cris_exec(CPUCRISState *s); -void do_interrupt(CPUCRISState *env); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */ diff --git a/target-cris/helper.c b/target-cris/helper.c index 885f67fa33..e1ef7bcc0b 100644 --- a/target-cris/helper.c +++ b/target-cris/helper.c @@ -36,8 +36,11 @@ #if defined(CONFIG_USER_ONLY) -void do_interrupt(CPUCRISState *env) +void cris_cpu_do_interrupt(CPUState *cs) { + CRISCPU *cpu = CRIS_CPU(cs); + CPUCRISState *env = &cpu->env; + env->exception_index = -1; env->pregs[PR_ERP] = env->pc; } @@ -162,9 +165,10 @@ static void do_interruptv10(CPUCRISState *env) env->pregs[PR_ERP]); } -void do_interrupt(CPUCRISState *env) +void cris_cpu_do_interrupt(CPUState *cs) { - D(CPUState *cs = CPU(cris_env_get_cpu(env))); + CRISCPU *cpu = CRIS_CPU(cs); + CPUCRISState *env = &cpu->env; int ex_vec = -1; if (env->pregs[PR_VR] < 32) { diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index 83c5318d3a..08f9eb67b2 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -80,4 +80,10 @@ static inline X86CPU *x86_env_get_cpu(CPUX86State *env) extern const struct VMStateDescription vmstate_x86_cpu; #endif +/** + * x86_cpu_do_interrupt: + * @cpu: vCPU the interrupt is to be handled by. + */ +void x86_cpu_do_interrupt(CPUState *cpu); + #endif diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 2bdbf1b453..a0640db9e3 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2251,6 +2251,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) xcc->parent_reset = cc->reset; cc->reset = x86_cpu_reset; + cc->do_interrupt = x86_cpu_do_interrupt; cpu_class_set_vmsd(cc, &vmstate_x86_cpu); } diff --git a/target-i386/cpu.h b/target-i386/cpu.h index bf6e21073d..48f41ca3e3 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -1252,8 +1252,7 @@ void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type, uint64_t param); void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1); -/* op_helper.c */ -void do_interrupt(CPUX86State *env); +/* seg_helper.c */ void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw); void do_smm_enter(CPUX86State *env1); diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c index 3247deeb60..906e4f3d20 100644 --- a/target-i386/seg_helper.c +++ b/target-i386/seg_helper.c @@ -1231,8 +1231,11 @@ static void do_interrupt_all(CPUX86State *env, int intno, int is_int, #endif } -void do_interrupt(CPUX86State *env) +void x86_cpu_do_interrupt(CPUState *cs) { + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; + #if defined(CONFIG_USER_ONLY) /* if user mode only, we simulate a fake exception which will be handled outside the cpu execution diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h index c0b6ce5897..3ba86b7c88 100644 --- a/target-lm32/cpu-qom.h +++ b/target-lm32/cpu-qom.h @@ -71,4 +71,6 @@ static inline LM32CPU *lm32_env_get_cpu(CPULM32State *env) #define ENV_OFFSET offsetof(LM32CPU, env) +void lm32_cpu_do_interrupt(CPUState *cpu); + #endif diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index a2badb5701..a4692b7d5f 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -83,6 +83,8 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data) lcc->parent_reset = cc->reset; cc->reset = lm32_cpu_reset; + + cc->do_interrupt = lm32_cpu_do_interrupt; } static const TypeInfo lm32_cpu_type_info = { diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h index d81f103e66..1be9778400 100644 --- a/target-lm32/cpu.h +++ b/target-lm32/cpu.h @@ -189,7 +189,6 @@ struct CPULM32State { LM32CPU *cpu_lm32_init(const char *cpu_model); void cpu_lm32_list(FILE *f, fprintf_function cpu_fprintf); int cpu_lm32_exec(CPULM32State *s); -void do_interrupt(CPULM32State *env); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */ diff --git a/target-lm32/helper.c b/target-lm32/helper.c index 47ae7e775a..a0a8399906 100644 --- a/target-lm32/helper.c +++ b/target-lm32/helper.c @@ -42,8 +42,11 @@ hwaddr cpu_get_phys_page_debug(CPULM32State *env, target_ulong addr) return addr & TARGET_PAGE_MASK; } -void do_interrupt(CPULM32State *env) +void lm32_cpu_do_interrupt(CPUState *cs) { + LM32CPU *cpu = LM32_CPU(cs); + CPULM32State *env = &cpu->env; + qemu_log_mask(CPU_LOG_INT, "exception at pc=%x type=%x\n", env->pc, env->exception_index); diff --git a/target-m68k/cpu-qom.h b/target-m68k/cpu-qom.h index f4c33b2eb3..846aa7453e 100644 --- a/target-m68k/cpu-qom.h +++ b/target-m68k/cpu-qom.h @@ -70,4 +70,6 @@ static inline M68kCPU *m68k_env_get_cpu(CPUM68KState *env) #define ENV_OFFSET offsetof(M68kCPU, env) +void m68k_cpu_do_interrupt(CPUState *cpu); + #endif diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index f5a109854b..3c65b4e44f 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -186,6 +186,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data) cc->reset = m68k_cpu_reset; cc->class_by_name = m68k_cpu_class_by_name; + cc->do_interrupt = m68k_cpu_do_interrupt; dc->vmsd = &vmstate_m68k_cpu; } diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index bb2fbd6d4d..c90c40c370 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -119,7 +119,6 @@ void m68k_tcg_init(void); void m68k_cpu_init_gdb(M68kCPU *cpu); M68kCPU *cpu_m68k_init(const char *cpu_model); int cpu_m68k_exec(CPUM68KState *s); -void do_interrupt(CPUM68KState *env1); void do_interrupt_m68k_hardirq(CPUM68KState *env1); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c index e11f34b0f9..30f7d8b1ab 100644 --- a/target-m68k/op_helper.c +++ b/target-m68k/op_helper.c @@ -21,8 +21,11 @@ #if defined(CONFIG_USER_ONLY) -void do_interrupt(CPUM68KState *env) +void m68k_cpu_do_interrupt(CPUState *cs) { + M68kCPU *cpu = M68K_CPU(cs); + CPUM68KState *env = &cpu->env; + env->exception_index = -1; } @@ -149,8 +152,11 @@ static void do_interrupt_all(CPUM68KState *env, int is_hw) env->pc = cpu_ldl_kernel(env, env->vbr + vector); } -void do_interrupt(CPUM68KState *env) +void m68k_cpu_do_interrupt(CPUState *cs) { + M68kCPU *cpu = M68K_CPU(cs); + CPUM68KState *env = &cpu->env; + do_interrupt_all(env, 0); } diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h index a0248a5a22..aa51cf6406 100644 --- a/target-microblaze/cpu-qom.h +++ b/target-microblaze/cpu-qom.h @@ -70,4 +70,6 @@ static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env) #define ENV_OFFSET offsetof(MicroBlazeCPU, env) +void mb_cpu_do_interrupt(CPUState *cs); + #endif diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c index 81359db168..0f4293dbd5 100644 --- a/target-microblaze/cpu.c +++ b/target-microblaze/cpu.c @@ -131,6 +131,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data) mcc->parent_reset = cc->reset; cc->reset = mb_cpu_reset; + cc->do_interrupt = mb_cpu_do_interrupt; dc->vmsd = &vmstate_mb_cpu; } diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h index 7548aa903d..1813939fc9 100644 --- a/target-microblaze/cpu.h +++ b/target-microblaze/cpu.h @@ -275,7 +275,6 @@ struct CPUMBState { void mb_tcg_init(void); MicroBlazeCPU *cpu_mb_init(const char *cpu_model); int cpu_mb_exec(CPUMBState *s); -void do_interrupt(CPUMBState *env); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */ diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c index 97aedc52bb..a0416d0b72 100644 --- a/target-microblaze/helper.c +++ b/target-microblaze/helper.c @@ -26,8 +26,11 @@ #if defined(CONFIG_USER_ONLY) -void do_interrupt (CPUMBState *env) +void mb_cpu_do_interrupt(CPUState *cs) { + MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs); + CPUMBState *env = &cpu->env; + env->exception_index = -1; env->res_addr = RES_ADDR_NONE; env->regs[14] = env->sregs[SR_PC]; @@ -109,8 +112,10 @@ int cpu_mb_handle_mmu_fault (CPUMBState *env, target_ulong address, int rw, return r; } -void do_interrupt(CPUMBState *env) +void mb_cpu_do_interrupt(CPUState *cs) { + MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs); + CPUMBState *env = &cpu->env; uint32_t t; /* IMM flag cannot propagate across a branch and into the dslot. */ diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h index c6bcddfb9a..32e3cad7bf 100644 --- a/target-mips/cpu-qom.h +++ b/target-mips/cpu-qom.h @@ -74,4 +74,6 @@ static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env) #define ENV_OFFSET offsetof(MIPSCPU, env) +void mips_cpu_do_interrupt(CPUState *cpu); + #endif diff --git a/target-mips/cpu.c b/target-mips/cpu.c index 4d62031c36..5315f7bda0 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -78,6 +78,8 @@ static void mips_cpu_class_init(ObjectClass *c, void *data) mcc->parent_reset = cc->reset; cc->reset = mips_cpu_reset; + + cc->do_interrupt = mips_cpu_do_interrupt; } static const TypeInfo mips_cpu_type_info = { diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 22b0497757..cedf03df43 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -663,7 +663,6 @@ void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int level); int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw, int mmu_idx); #define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault -void do_interrupt (CPUMIPSState *env); #if !defined(CONFIG_USER_ONLY) void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra); hwaddr cpu_mips_translate_address (CPUMIPSState *env, target_ulong address, diff --git a/target-mips/helper.c b/target-mips/helper.c index e877b8db78..3a54acf706 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -396,10 +396,11 @@ static void set_hflags_for_handler (CPUMIPSState *env) } #endif -void do_interrupt (CPUMIPSState *env) +void mips_cpu_do_interrupt(CPUState *cs) { + MIPSCPU *cpu = MIPS_CPU(cs); + CPUMIPSState *env = &cpu->env; #if !defined(CONFIG_USER_ONLY) - MIPSCPU *cpu = mips_env_get_cpu(env); target_ulong offset; int cause = -1; const char *name; diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c index 72d5e8d2a5..ffe14f3c8d 100644 --- a/target-openrisc/cpu.c +++ b/target-openrisc/cpu.c @@ -148,6 +148,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data) cc->reset = openrisc_cpu_reset; cc->class_by_name = openrisc_cpu_class_by_name; + cc->do_interrupt = openrisc_cpu_do_interrupt; } static void cpu_register(const OpenRISCCPUInfo *info) diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index 64370a3772..b9c55ba83b 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -346,7 +346,7 @@ OpenRISCCPU *cpu_openrisc_init(const char *cpu_model); void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf); int cpu_openrisc_exec(CPUOpenRISCState *s); -void do_interrupt(CPUOpenRISCState *env); +void openrisc_cpu_do_interrupt(CPUState *cpu); void openrisc_translate_init(void); int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env, target_ulong address, diff --git a/target-openrisc/interrupt.c b/target-openrisc/interrupt.c index 7f2c025da2..16ef4b3e79 100644 --- a/target-openrisc/interrupt.c +++ b/target-openrisc/interrupt.c @@ -25,8 +25,10 @@ #include "hw/loader.h" #endif -void do_interrupt(CPUOpenRISCState *env) +void openrisc_cpu_do_interrupt(CPUState *cs) { + OpenRISCCPU *cpu = OPENRISC_CPU(cs); + CPUOpenRISCState *env = &cpu->env; #ifndef CONFIG_USER_ONLY if (env->flags & D_FLAG) { /* Delay Slot insn */ env->flags &= ~D_FLAG; diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h index 2bf0ab62d4..09bfae3d54 100644 --- a/target-ppc/cpu-qom.h +++ b/target-ppc/cpu-qom.h @@ -95,4 +95,6 @@ static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env) PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr); +void ppc_cpu_do_interrupt(CPUState *cpu); + #endif diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 1b31b1d9c9..6886666d6e 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1133,7 +1133,6 @@ int cpu_ppc_signal_handler (int host_signum, void *pinfo, int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw, int mmu_idx); #define cpu_handle_mmu_fault cpu_ppc_handle_mmu_fault -void do_interrupt (CPUPPCState *env); void ppc_hw_interrupt (CPUPPCState *env); #if !defined(CONFIG_USER_ONLY) diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c index d1767340ef..4a0fc6dd57 100644 --- a/target-ppc/excp_helper.c +++ b/target-ppc/excp_helper.c @@ -38,8 +38,11 @@ void (*cpu_ppc_hypercall)(PowerPCCPU *); /*****************************************************************************/ /* Exception processing */ #if defined(CONFIG_USER_ONLY) -void do_interrupt(CPUPPCState *env) +void ppc_cpu_do_interrupt(CPUState *cs) { + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + env->exception_index = POWERPC_EXCP_NONE; env->error_code = 0; } @@ -654,9 +657,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) } } -void do_interrupt(CPUPPCState *env) +void ppc_cpu_do_interrupt(CPUState *cs) { - PowerPCCPU *cpu = ppc_env_get_cpu(env); + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; powerpc_excp(cpu, env->excp_model, env->exception_index); } diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 09ad4ba639..15eebe9177 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -8427,6 +8427,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data) cc->reset = ppc_cpu_reset; cc->class_by_name = ppc_cpu_class_by_name; + cc->do_interrupt = ppc_cpu_do_interrupt; } static const TypeInfo ppc_cpu_type_info = { diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h index f6e514570c..34d45c262b 100644 --- a/target-s390x/cpu-qom.h +++ b/target-s390x/cpu-qom.h @@ -71,4 +71,6 @@ static inline S390CPU *s390_env_get_cpu(CPUS390XState *env) #define ENV_OFFSET offsetof(S390CPU, env) +void s390_cpu_do_interrupt(CPUState *cpu); + #endif diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index 738a0ad1ee..23fe51f0f4 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -169,6 +169,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data) scc->parent_reset = cc->reset; cc->reset = s390_cpu_reset; + cc->do_interrupt = s390_cpu_do_interrupt; dc->vmsd = &vmstate_s390_cpu; } diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index 642e661e7d..e351005901 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -315,7 +315,6 @@ static inline int get_ilen(uint8_t opc) S390CPU *cpu_s390x_init(const char *cpu_model); void s390x_translate_init(void); int cpu_s390x_exec(CPUS390XState *s); -void do_interrupt (CPUS390XState *env); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero diff --git a/target-s390x/helper.c b/target-s390x/helper.c index 2cb8dc86e3..b425054be8 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -86,8 +86,11 @@ S390CPU *cpu_s390x_init(const char *cpu_model) #if defined(CONFIG_USER_ONLY) -void do_interrupt(CPUS390XState *env) +void s390_cpu_do_interrupt(CPUState *cs) { + S390CPU *cpu = S390_CPU(cs); + CPUS390XState *env = &cpu->env; + env->exception_index = -1; } @@ -737,10 +740,10 @@ static void do_mchk_interrupt(CPUS390XState *env) load_psw(env, mask, addr); } -void do_interrupt(CPUS390XState *env) +void s390_cpu_do_interrupt(CPUState *cs) { - S390CPU *cpu = s390_env_get_cpu(env); - CPUState *cs; + S390CPU *cpu = S390_CPU(cs); + CPUS390XState *env = &cpu->env; qemu_log_mask(CPU_LOG_INT, "%s: %d at pc=%" PRIx64 "\n", __func__, env->exception_index, env->psw.addr); @@ -799,7 +802,6 @@ void do_interrupt(CPUS390XState *env) env->exception_index = -1; if (!env->pending_int) { - cs = CPU(s390_env_get_cpu(env)); cs->interrupt_request &= ~CPU_INTERRUPT_HARD; } } diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h index 29628c8077..f8c80d30b4 100644 --- a/target-sh4/cpu-qom.h +++ b/target-sh4/cpu-qom.h @@ -83,4 +83,6 @@ static inline SuperHCPU *sh_env_get_cpu(CPUSH4State *env) #define ENV_OFFSET offsetof(SuperHCPU, env) +void superh_cpu_do_interrupt(CPUState *cpu); + #endif diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index 5251aa08a5..898aecde4f 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -273,6 +273,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data) cc->reset = superh_cpu_reset; cc->class_by_name = superh_cpu_class_by_name; + cc->do_interrupt = superh_cpu_do_interrupt; dc->vmsd = &vmstate_sh_cpu; } diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index 49663556ef..fd7da92548 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -196,7 +196,6 @@ int cpu_sh4_signal_handler(int host_signum, void *pinfo, int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw, int mmu_idx); #define cpu_handle_mmu_fault cpu_sh4_handle_mmu_fault -void do_interrupt(CPUSH4State * env); void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf); #if !defined(CONFIG_USER_ONLY) diff --git a/target-sh4/helper.c b/target-sh4/helper.c index fd4efee4a6..0a9cb3ac98 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -31,9 +31,12 @@ #if defined(CONFIG_USER_ONLY) -void do_interrupt (CPUSH4State *env) +void superh_cpu_do_interrupt(CPUState *cs) { - env->exception_index = -1; + SuperHCPU *cpu = SUPERH_CPU(cs); + CPUSH4State *env = &cpu->env; + + env->exception_index = -1; } int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw, @@ -78,9 +81,10 @@ int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr) #define MMU_DADDR_ERROR_READ (-12) #define MMU_DADDR_ERROR_WRITE (-13) -void do_interrupt(CPUSH4State *env) +void superh_cpu_do_interrupt(CPUState *cs) { - CPUState *cs = CPU(sh_env_get_cpu(env)); + SuperHCPU *cpu = SUPERH_CPU(cs); + CPUSH4State *env = &cpu->env; int do_irq = cs->interrupt_request & CPU_INTERRUPT_HARD; int do_exp, irq_vector = env->exception_index; diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h index efeeca0d97..d4fe89ebfd 100644 --- a/target-sparc/cpu-qom.h +++ b/target-sparc/cpu-qom.h @@ -75,4 +75,6 @@ static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env) #define ENV_OFFSET offsetof(SPARCCPU, env) +void sparc_cpu_do_interrupt(CPUState *cpu); + #endif diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index 50def61848..ab1adfd7ea 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -891,6 +891,8 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data) scc->parent_reset = cc->reset; cc->reset = sparc_cpu_reset; + + cc->do_interrupt = sparc_cpu_do_interrupt; } static const TypeInfo sparc_cpu_type_info = { diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 8a2f8df992..6fa77789cd 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -553,7 +553,6 @@ int cpu_cwp_dec(CPUSPARCState *env1, int cwp); void cpu_set_cwp(CPUSPARCState *env1, int new_cwp); /* int_helper.c */ -void do_interrupt(CPUSPARCState *env); void leon3_irq_manager(CPUSPARCState *env, void *irq_manager, int intno); /* sun4m.c, sun4u.c */ diff --git a/target-sparc/int32_helper.c b/target-sparc/int32_helper.c index c35f522e0f..722146065a 100644 --- a/target-sparc/int32_helper.c +++ b/target-sparc/int32_helper.c @@ -58,8 +58,10 @@ static const char * const excp_names[0x80] = { }; #endif -void do_interrupt(CPUSPARCState *env) +void sparc_cpu_do_interrupt(CPUState *cs) { + SPARCCPU *cpu = SPARC_CPU(cs); + CPUSPARCState *env = &cpu->env; int cwp, intno = env->exception_index; /* Compute PSR before exposing state. */ diff --git a/target-sparc/int64_helper.c b/target-sparc/int64_helper.c index df37aa1d14..f411884c6e 100644 --- a/target-sparc/int64_helper.c +++ b/target-sparc/int64_helper.c @@ -59,8 +59,10 @@ static const char * const excp_names[0x80] = { }; #endif -void do_interrupt(CPUSPARCState *env) +void sparc_cpu_do_interrupt(CPUState *cs) { + SPARCCPU *cpu = SPARC_CPU(cs); + CPUSPARCState *env = &cpu->env; int intno = env->exception_index; trap_state *tsptr; diff --git a/target-unicore32/cpu-qom.h b/target-unicore32/cpu-qom.h index c6590bdf01..ba4dee4b9f 100644 --- a/target-unicore32/cpu-qom.h +++ b/target-unicore32/cpu-qom.h @@ -60,4 +60,6 @@ static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env) #define ENV_OFFSET offsetof(UniCore32CPU, env) +void uc32_cpu_do_interrupt(CPUState *cpu); + #endif diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c index b7024c85bb..66a1a74646 100644 --- a/target-unicore32/cpu.c +++ b/target-unicore32/cpu.c @@ -132,6 +132,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data) dc->realize = uc32_cpu_realizefn; cc->class_by_name = uc32_cpu_class_by_name; + cc->do_interrupt = uc32_cpu_do_interrupt; dc->vmsd = &vmstate_uc32_cpu; } diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h index 58f1f20ca5..5b2b9d1cc7 100644 --- a/target-unicore32/cpu.h +++ b/target-unicore32/cpu.h @@ -176,7 +176,6 @@ static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc } void uc32_translate_init(void); -void do_interrupt(CPUUniCore32State *); void switch_mode(CPUUniCore32State *, int); static inline bool cpu_has_work(CPUState *cpu) diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c index 7eeb9bc633..61eb2c374a 100644 --- a/target-unicore32/helper.c +++ b/target-unicore32/helper.c @@ -242,8 +242,11 @@ void switch_mode(CPUUniCore32State *env, int mode) } } -void do_interrupt(CPUUniCore32State *env) +void uc32_cpu_do_interrupt(CPUState *cs) { + UniCore32CPU *cpu = UNICORE32_CPU(cs); + CPUUniCore32State *env = &cpu->env; + cpu_abort(env, "NO interrupt in user mode\n"); } diff --git a/target-unicore32/softmmu.c b/target-unicore32/softmmu.c index 1c4c7f5245..eadaeb11ab 100644 --- a/target-unicore32/softmmu.c +++ b/target-unicore32/softmmu.c @@ -72,9 +72,10 @@ void switch_mode(CPUUniCore32State *env, int mode) } /* Handle a CPU exception. */ -void do_interrupt(CPUUniCore32State *env) +void uc32_cpu_do_interrupt(CPUState *cs) { - CPUState *cs = CPU(uc32_env_get_cpu(env)); + UniCore32CPU *cpu = UNICORE32_CPU(cs); + CPUUniCore32State *env = &cpu->env; uint32_t addr; int new_mode; diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h index c78136bf72..af0ce2823c 100644 --- a/target-xtensa/cpu-qom.h +++ b/target-xtensa/cpu-qom.h @@ -80,4 +80,6 @@ static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env) #define ENV_OFFSET offsetof(XtensaCPU, env) +void xtensa_cpu_do_interrupt(CPUState *cpu); + #endif diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c index 785e56d367..6e93dd8d24 100644 --- a/target-xtensa/cpu.c +++ b/target-xtensa/cpu.c @@ -101,6 +101,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data) xcc->parent_reset = cc->reset; cc->reset = xtensa_cpu_reset; + cc->do_interrupt = xtensa_cpu_do_interrupt; dc->vmsd = &vmstate_xtensa_cpu; } diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index dece224478..6c9fc35dcc 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -388,7 +388,6 @@ void xtensa_translate_init(void); void xtensa_breakpoint_handler(CPUXtensaState *env); int cpu_xtensa_exec(CPUXtensaState *s); void xtensa_register_core(XtensaConfigList *node); -void do_interrupt(CPUXtensaState *s); void check_interrupts(CPUXtensaState *s); void xtensa_irq_init(CPUXtensaState *env); void *xtensa_get_extint(CPUXtensaState *env, unsigned extint); diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c index a8a64932da..6f613c66a6 100644 --- a/target-xtensa/helper.c +++ b/target-xtensa/helper.c @@ -178,8 +178,11 @@ static void handle_interrupt(CPUXtensaState *env) } } -void do_interrupt(CPUXtensaState *env) +void xtensa_cpu_do_interrupt(CPUState *cs) { + XtensaCPU *cpu = XTENSA_CPU(cs); + CPUXtensaState *env = &cpu->env; + if (env->exception_index == EXC_IRQ) { qemu_log_mask(CPU_LOG_INT, "%s(EXC_IRQ) level = %d, cintlevel = %d, " From e6f010cc27177c97596455b2e2b589bd19b2a486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 2 Feb 2013 12:33:14 +0100 Subject: [PATCH 16/17] target-arm: Override do_interrupt for ARMv7-M profile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable ARMCPUInfo to specify a custom class_init functions. Introduce arm_v7m_class_init() and use it for "cortex-m3" model. Instead of forwarding from arm_cpu_do_interrupt() to do_interrupt_v7m(), override CPUClass::do_interrupt with arm_v7m_cpu_do_interrupt() in arm_v7m_class_init(). Acked-by: Peter Maydell Signed-off-by: Andreas Färber --- target-arm/cpu-qom.h | 1 + target-arm/cpu.c | 14 +++++++++++++- target-arm/helper.c | 10 +++++----- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index eeecc9265d..25895509be 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -114,5 +114,6 @@ static inline ARMCPU *arm_env_get_cpu(CPUARMState *env) void register_cp_regs_for_features(ARMCPU *cpu); void arm_cpu_do_interrupt(CPUState *cpu); +void arm_v7m_cpu_do_interrupt(CPUState *cpu); #endif diff --git a/target-arm/cpu.c b/target-arm/cpu.c index aeaa3b7834..a1e90939d6 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -412,6 +412,15 @@ static void cortex_m3_initfn(Object *obj) cpu->midr = 0x410fc231; } +static void arm_v7m_class_init(ObjectClass *oc, void *data) +{ +#ifndef CONFIG_USER_ONLY + CPUClass *cc = CPU_CLASS(oc); + + cc->do_interrupt = arm_v7m_cpu_do_interrupt; +#endif +} + static const ARMCPRegInfo cortexa8_cp_reginfo[] = { { .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 0, .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, @@ -752,6 +761,7 @@ static void arm_any_initfn(Object *obj) typedef struct ARMCPUInfo { const char *name; void (*initfn)(Object *obj); + void (*class_init)(ObjectClass *oc, void *data); } ARMCPUInfo; static const ARMCPUInfo arm_cpus[] = { @@ -766,7 +776,8 @@ static const ARMCPUInfo arm_cpus[] = { { .name = "arm1136", .initfn = arm1136_initfn }, { .name = "arm1176", .initfn = arm1176_initfn }, { .name = "arm11mpcore", .initfn = arm11mpcore_initfn }, - { .name = "cortex-m3", .initfn = cortex_m3_initfn }, + { .name = "cortex-m3", .initfn = cortex_m3_initfn, + .class_init = arm_v7m_class_init }, { .name = "cortex-a8", .initfn = cortex_a8_initfn }, { .name = "cortex-a9", .initfn = cortex_a9_initfn }, { .name = "cortex-a15", .initfn = cortex_a15_initfn }, @@ -812,6 +823,7 @@ static void cpu_register(const ARMCPUInfo *info) .instance_size = sizeof(ARMCPU), .instance_init = info->initfn, .class_size = sizeof(ARMCPUClass), + .class_init = info->class_init, }; type_info.name = g_strdup_printf("%s-" TYPE_ARM_CPU, info->name); diff --git a/target-arm/helper.c b/target-arm/helper.c index b4cbb8718a..fd055e89f2 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1725,8 +1725,10 @@ static void do_v7m_exception_exit(CPUARMState *env) pointer. */ } -static void do_interrupt_v7m(CPUARMState *env) +void arm_v7m_cpu_do_interrupt(CPUState *cs) { + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; uint32_t xpsr = xpsr_read(env); uint32_t lr; uint32_t addr; @@ -1811,10 +1813,8 @@ void arm_cpu_do_interrupt(CPUState *cs) int new_mode; uint32_t offset; - if (IS_M(env)) { - do_interrupt_v7m(env); - return; - } + assert(!IS_M(env)); + /* TODO: Vectored interrupt controller. */ switch (env->exception_index) { case EXCP_UDEF: From 0ad6773f1151c9e172b0b714aada78655dda4cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 2 Feb 2013 13:45:29 +0100 Subject: [PATCH 17/17] target-lm32: Update VMStateDescription to LM32CPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a vmstate_lm32_cpu referencing the previous VMStateDescription as a sub-struct and hook it up to CPUClass::vmsd. Drop cpu_{save,load}(). Acked-by: Michael Walle Signed-off-by: Andreas Färber --- target-lm32/cpu-qom.h | 4 ++++ target-lm32/cpu.c | 1 + target-lm32/cpu.h | 2 -- target-lm32/machine.c | 25 +++++++++++++------------ 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h index 3ba86b7c88..957186075b 100644 --- a/target-lm32/cpu-qom.h +++ b/target-lm32/cpu-qom.h @@ -71,6 +71,10 @@ static inline LM32CPU *lm32_env_get_cpu(CPULM32State *env) #define ENV_OFFSET offsetof(LM32CPU, env) +#ifndef CONFIG_USER_ONLY +extern const struct VMStateDescription vmstate_lm32_cpu; +#endif + void lm32_cpu_do_interrupt(CPUState *cpu); #endif diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index a4692b7d5f..bbb7fbf768 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -85,6 +85,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data) cc->reset = lm32_cpu_reset; cc->do_interrupt = lm32_cpu_do_interrupt; + cpu_class_set_vmsd(cc, &vmstate_lm32_cpu); } static const TypeInfo lm32_cpu_type_info = { diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h index 1be9778400..fd50b534fc 100644 --- a/target-lm32/cpu.h +++ b/target-lm32/cpu.h @@ -211,8 +211,6 @@ static inline CPULM32State *cpu_init(const char *cpu_model) #define cpu_gen_code cpu_lm32_gen_code #define cpu_signal_handler cpu_lm32_signal_handler -#define CPU_SAVE_VERSION 1 - int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw, int mmu_idx); #define cpu_handle_mmu_fault cpu_lm32_handle_mmu_fault diff --git a/target-lm32/machine.c b/target-lm32/machine.c index 6802e818f8..9e0919c254 100644 --- a/target-lm32/machine.c +++ b/target-lm32/machine.c @@ -1,9 +1,9 @@ #include "hw/hw.h" #include "hw/boards.h" -static const VMStateDescription vmstate_cpu = { - .name = "cpu", - .version_id = CPU_SAVE_VERSION, +static const VMStateDescription vmstate_env = { + .name = "env", + .version_id = 1, .minimum_version_id = 1, .minimum_version_id_old = 1, .fields = (VMStateField[]) { @@ -22,12 +22,13 @@ static const VMStateDescription vmstate_cpu = { } }; -void cpu_save(QEMUFile *f, void *opaque) -{ - vmstate_save_state(f, &vmstate_cpu, opaque); -} - -int cpu_load(QEMUFile *f, void *opaque, int version_id) -{ - return vmstate_load_state(f, &vmstate_cpu, opaque, version_id); -} +const VMStateDescription vmstate_lm32_cpu = { + .name = "cpu", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_STRUCT(env, LM32CPU, 1, vmstate_env, CPULM32State), + VMSTATE_END_OF_LIST() + } +};