From 4f65809994274989bdf51c8605bb974565cb1c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 19 Jan 2013 06:17:06 +0100 Subject: [PATCH 01/47] cpu: Prepare QOM realizefn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Overwrite the default implementation with a no-op, no longer attempting to call DeviceClass::init. Signed-off-by: Andreas Färber --- qom/cpu.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qom/cpu.c b/qom/cpu.c index 8fb538bf3b..870e9baad9 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -46,6 +46,10 @@ static ObjectClass *cpu_common_class_by_name(const char *cpu_model) return NULL; } +static void cpu_common_realizefn(DeviceState *dev, Error **errp) +{ +} + static void cpu_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -53,6 +57,7 @@ static void cpu_class_init(ObjectClass *klass, void *data) k->class_by_name = cpu_common_class_by_name; k->reset = cpu_common_reset; + dc->realize = cpu_common_realizefn; dc->no_user = 1; } From bd1b282836a7885a13c13f9cc63123fa8e32f02f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 5 Jan 2013 14:01:30 +0100 Subject: [PATCH 02/47] target-alpha: Update AlphaCPU to QOM realizefn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the alpha_cpu_realize() signature and hook up to DeviceClass::realize. Set realized = true in cpu_alpha_init(). qapi/error.h is included through qdev now and no longer needed. Acked-by: Richard Henderson [AF: Invoke parent's realizefn] Signed-off-by: Andreas Färber --- target-alpha/cpu-qom.h | 2 ++ target-alpha/cpu.c | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h index 16367d2ea4..c0f6c6d165 100644 --- a/target-alpha/cpu-qom.h +++ b/target-alpha/cpu-qom.h @@ -34,6 +34,7 @@ /** * AlphaCPUClass: + * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * * An Alpha CPU model. @@ -43,6 +44,7 @@ typedef struct AlphaCPUClass { CPUClass parent_class; /*< public >*/ + DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); } AlphaCPUClass; diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c index 0ad69f0859..0cdae6986f 100644 --- a/target-alpha/cpu.c +++ b/target-alpha/cpu.c @@ -21,14 +21,16 @@ #include "cpu.h" #include "qemu-common.h" -#include "qapi/error.h" -static void alpha_cpu_realize(Object *obj, Error **errp) +static void alpha_cpu_realizefn(DeviceState *dev, Error **errp) { - AlphaCPU *cpu = ALPHA_CPU(obj); + AlphaCPU *cpu = ALPHA_CPU(dev); + AlphaCPUClass *acc = ALPHA_CPU_GET_CLASS(dev); qemu_init_vcpu(&cpu->env); + + acc->parent_realize(dev, errp); } /* Sort alphabetically by type name. */ @@ -134,7 +136,8 @@ AlphaCPU *cpu_alpha_init(const char *cpu_model) env->cpu_model_str = cpu_model; - alpha_cpu_realize(OBJECT(cpu), NULL); + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); + return cpu; } @@ -250,7 +253,12 @@ static void alpha_cpu_initfn(Object *obj) static void alpha_cpu_class_init(ObjectClass *oc, void *data) { + DeviceClass *dc = DEVICE_CLASS(oc); CPUClass *cc = CPU_CLASS(oc); + AlphaCPUClass *acc = ALPHA_CPU_CLASS(oc); + + acc->parent_realize = dc->realize; + dc->realize = alpha_cpu_realizefn; cc->class_by_name = alpha_cpu_class_by_name; } From 149692667f8a46430127ca0555b38965f52177f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 5 Jan 2013 10:18:18 +0100 Subject: [PATCH 03/47] target-arm: Update ARMCPU to QOM realizefn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turn arm_cpu_realize() into a QOM realize function, no longer called via cpu.h prototype. To maintain the semantics of cpu_init(), set realized = true explicitly in cpu_arm_init(). Move GDB coprocessor registration, CPU reset and vCPU initialization into the realizefn. Signed-off-by: Andreas Färber --- target-arm/cpu-qom.h | 3 ++- target-arm/cpu.c | 21 ++++++++++++++------- target-arm/cpu.h | 1 + target-arm/helper.c | 14 ++++++++++---- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index 0f455c40ff..aff7bf302e 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -33,6 +33,7 @@ /** * ARMCPUClass: + * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * * An ARM CPU model. @@ -42,6 +43,7 @@ typedef struct ARMCPUClass { CPUClass parent_class; /*< public >*/ + DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); } ARMCPUClass; @@ -107,7 +109,6 @@ static inline ARMCPU *arm_env_get_cpu(CPUARMState *env) #define ENV_GET_CPU(e) CPU(arm_env_get_cpu(e)) -void arm_cpu_realize(ARMCPU *cpu); void register_cp_regs_for_features(ARMCPU *cpu); #endif diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 1c6a628df4..9915172a1d 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -147,15 +147,12 @@ static void arm_cpu_finalizefn(Object *obj) g_hash_table_destroy(cpu->cp_regs); } -void arm_cpu_realize(ARMCPU *cpu) +static void arm_cpu_realizefn(DeviceState *dev, Error **errp) { - /* This function is called by cpu_arm_init() because it - * needs to do common actions based on feature bits, etc - * that have been set by the subclass init functions. - * When we have QOM realize support it should become - * a true realize function instead. - */ + ARMCPU *cpu = ARM_CPU(dev); + ARMCPUClass *acc = ARM_CPU_GET_CLASS(dev); CPUARMState *env = &cpu->env; + /* Some features automatically imply others: */ if (arm_feature(env, ARM_FEATURE_V7)) { set_feature(env, ARM_FEATURE_VAPA); @@ -197,6 +194,12 @@ void arm_cpu_realize(ARMCPU *cpu) } register_cp_regs_for_features(cpu); + arm_cpu_register_gdb_regs_for_features(cpu); + + cpu_reset(CPU(cpu)); + qemu_init_vcpu(env); + + acc->parent_realize(dev, errp); } /* CPU models */ @@ -782,6 +785,10 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) { ARMCPUClass *acc = ARM_CPU_CLASS(oc); CPUClass *cc = CPU_CLASS(acc); + DeviceClass *dc = DEVICE_CLASS(oc); + + acc->parent_realize = dc->realize; + dc->realize = arm_cpu_realizefn; acc->parent_reset = cc->reset; cc->reset = arm_cpu_reset; diff --git a/target-arm/cpu.h b/target-arm/cpu.h index ffddfcbc0d..2902ba575b 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -234,6 +234,7 @@ typedef struct CPUARMState { 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 *); void switch_mode(CPUARMState *, int); diff --git a/target-arm/helper.c b/target-arm/helper.c index eb7b2910c3..4538a09445 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1272,14 +1272,22 @@ ARMCPU *cpu_arm_init(const char *cpu_model) cpu = ARM_CPU(object_new(object_class_get_name(oc))); env = &cpu->env; env->cpu_model_str = cpu_model; - arm_cpu_realize(cpu); + + /* TODO this should be set centrally, once possible */ + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); if (tcg_enabled() && !inited) { inited = 1; arm_translate_init(); } - cpu_reset(CPU(cpu)); + return cpu; +} + +void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) +{ + CPUARMState *env = &cpu->env; + if (arm_feature(env, ARM_FEATURE_NEON)) { gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, 51, "arm-neon.xml", 0); @@ -1290,8 +1298,6 @@ ARMCPU *cpu_arm_init(const char *cpu_model) gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, 19, "arm-vfp.xml", 0); } - qemu_init_vcpu(env); - return cpu; } /* Sort alphabetically by type name, except for "any". */ From 2b6f294cacd9f4e133a7813d22e1b4e87ac6b2a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Wed, 16 Jan 2013 03:41:47 +0100 Subject: [PATCH 04/47] target-i386: Update X86CPU to QOM realizefn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adapt the signature of x86_cpu_realize(), hook up to DeviceClass::realize and set realized = true in cpu_x86_init(). The QOM realizefn cannot depend on errp being non-NULL as in cpu_x86_init(), so use a local Error to preserve error handling behavior on APIC initialization errors. Reviewed-by: Igor Mammedov Reviewed-by: Eduardo Habkost [AF: Invoke parent's realizefn] Signed-off-by: Andreas Färber --- target-i386/cpu-qom.h | 5 ++--- target-i386/cpu.c | 19 +++++++++++++++---- target-i386/helper.c | 2 +- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index 332916a185..48e6b54b1f 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -39,6 +39,7 @@ /** * X86CPUClass: + * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * * An x86 CPU model or family. @@ -48,6 +49,7 @@ typedef struct X86CPUClass { CPUClass parent_class; /*< public >*/ + DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); } X86CPUClass; @@ -72,8 +74,5 @@ static inline X86CPU *x86_env_get_cpu(CPUX86State *env) #define ENV_GET_CPU(e) CPU(x86_env_get_cpu(e)) -/* TODO Drop once ObjectClass::realize is available */ -void x86_cpu_realize(Object *obj, Error **errp); - #endif diff --git a/target-i386/cpu.c b/target-i386/cpu.c index aab35c74d9..e2fd6268ef 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2060,10 +2060,14 @@ static void x86_cpu_apic_init(X86CPU *cpu, Error **errp) } #endif -void x86_cpu_realize(Object *obj, Error **errp) +static void x86_cpu_realizefn(DeviceState *dev, Error **errp) { - X86CPU *cpu = X86_CPU(obj); + X86CPU *cpu = X86_CPU(dev); + X86CPUClass *xcc = X86_CPU_GET_CLASS(dev); CPUX86State *env = &cpu->env; +#ifndef CONFIG_USER_ONLY + Error *local_err = NULL; +#endif if (env->cpuid_7_0_ebx_features && env->cpuid_level < 7) { env->cpuid_level = 7; @@ -2105,8 +2109,9 @@ void x86_cpu_realize(Object *obj, Error **errp) qemu_register_reset(x86_cpu_machine_reset_cb, cpu); if (cpu->env.cpuid_features & CPUID_APIC || smp_cpus > 1) { - x86_cpu_apic_init(cpu, errp); - if (error_is_set(errp)) { + x86_cpu_apic_init(cpu, &local_err); + if (local_err != NULL) { + error_propagate(errp, local_err); return; } } @@ -2115,6 +2120,8 @@ void x86_cpu_realize(Object *obj, Error **errp) mce_init(cpu); qemu_init_vcpu(&cpu->env); cpu_reset(CPU(cpu)); + + xcc->parent_realize(dev, errp); } /* Enables contiguous-apic-ID mode, for compatibility */ @@ -2200,6 +2207,10 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) { X86CPUClass *xcc = X86_CPU_CLASS(oc); CPUClass *cc = CPU_CLASS(oc); + DeviceClass *dc = DEVICE_CLASS(oc); + + xcc->parent_realize = dc->realize; + dc->realize = x86_cpu_realizefn; xcc->parent_reset = cc->reset; cc->reset = x86_cpu_reset; diff --git a/target-i386/helper.c b/target-i386/helper.c index d1cb4e2445..1a872fa3d8 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1282,7 +1282,7 @@ X86CPU *cpu_x86_init(const char *cpu_model) return NULL; } - x86_cpu_realize(OBJECT(cpu), &error); + object_property_set_bool(OBJECT(cpu), true, "realized", &error); if (error) { error_free(error); object_unref(OBJECT(cpu)); From c296262bc94651a7a43639857d8343470f4129f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 5 Jan 2013 14:11:07 +0100 Subject: [PATCH 05/47] target-openrisc: Update OpenRISCCPU to QOM realizefn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the openrisc_cpu_realize() signature, hook it up to DeviceClass::realize and set realized = true in cpu_openrisc_init(). qapi/error.h is now included through qdev and no longer needed. Signed-off-by: Andreas Färber Cc: Jia Liu --- target-openrisc/cpu.c | 13 ++++++++++--- target-openrisc/cpu.h | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c index a7a8de8a37..d8cc533efe 100644 --- a/target-openrisc/cpu.c +++ b/target-openrisc/cpu.c @@ -62,12 +62,15 @@ static inline void set_feature(OpenRISCCPU *cpu, int feature) cpu->env.cpucfgr = cpu->feature; } -void openrisc_cpu_realize(Object *obj, Error **errp) +static void openrisc_cpu_realizefn(DeviceState *dev, Error **errp) { - OpenRISCCPU *cpu = OPENRISC_CPU(obj); + OpenRISCCPU *cpu = OPENRISC_CPU(dev); + OpenRISCCPUClass *occ = OPENRISC_CPU_GET_CLASS(dev); qemu_init_vcpu(&cpu->env); cpu_reset(CPU(cpu)); + + occ->parent_realize(dev, errp); } static void openrisc_cpu_initfn(Object *obj) @@ -134,6 +137,10 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data) { OpenRISCCPUClass *occ = OPENRISC_CPU_CLASS(oc); CPUClass *cc = CPU_CLASS(occ); + DeviceClass *dc = DEVICE_CLASS(oc); + + occ->parent_realize = dc->realize; + dc->realize = openrisc_cpu_realizefn; occ->parent_reset = cc->reset; cc->reset = openrisc_cpu_reset; @@ -187,7 +194,7 @@ OpenRISCCPU *cpu_openrisc_init(const char *cpu_model) cpu = OPENRISC_CPU(object_new(object_class_get_name(oc))); cpu->env.cpu_model_str = cpu_model; - openrisc_cpu_realize(OBJECT(cpu), NULL); + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); return cpu; } diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index 3beab45c3c..419f007991 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -33,7 +33,6 @@ struct OpenRISCCPU; #include "exec/cpu-defs.h" #include "fpu/softfloat.h" #include "qom/cpu.h" -#include "qapi/error.h" #define TYPE_OPENRISC_CPU "or32-cpu" @@ -46,6 +45,7 @@ struct OpenRISCCPU; /** * OpenRISCCPUClass: + * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * * A OpenRISC CPU model. @@ -55,6 +55,7 @@ typedef struct OpenRISCCPUClass { CPUClass parent_class; /*< public >*/ + DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); } OpenRISCCPUClass; @@ -340,7 +341,6 @@ static inline OpenRISCCPU *openrisc_env_get_cpu(CPUOpenRISCState *env) #define ENV_GET_CPU(e) CPU(openrisc_env_get_cpu(e)) OpenRISCCPU *cpu_openrisc_init(const char *cpu_model); -void openrisc_cpu_realize(Object *obj, Error **errp); void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf); int cpu_openrisc_exec(CPUOpenRISCState *s); From 4776ce600338e17f75d200d1ad17d4ce9effa57f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Wed, 16 Jan 2013 03:55:14 +0100 Subject: [PATCH 06/47] target-ppc: Update PowerPCCPU to QOM realizefn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adapt ppc_cpu_realize() signature, hook it up to DeviceClass and set realized = true in cpu_ppc_init(). Reviewed-by: Eduardo Habkost Signed-off-by: Andreas Färber --- target-ppc/cpu-qom.h | 2 ++ target-ppc/translate_init.c | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h index b338f8fb56..2b82cdbe40 100644 --- a/target-ppc/cpu-qom.h +++ b/target-ppc/cpu-qom.h @@ -40,6 +40,7 @@ /** * PowerPCCPUClass: + * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * * A PowerPC CPU model. @@ -49,6 +50,7 @@ typedef struct PowerPCCPUClass { CPUClass parent_class; /*< public >*/ + DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); /* TODO inline fields here */ diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 6cebaa1982..49eaeac7c5 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -10030,9 +10030,9 @@ static int ppc_fixup_cpu(PowerPCCPU *cpu) return 0; } -static void ppc_cpu_realize(Object *obj, Error **errp) +static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) { - PowerPCCPU *cpu = POWERPC_CPU(obj); + PowerPCCPU *cpu = POWERPC_CPU(dev); CPUPPCState *env = &cpu->env; PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); ppc_def_t *def = pcc->info; @@ -10083,6 +10083,8 @@ static void ppc_cpu_realize(Object *obj, Error **errp) qemu_init_vcpu(env); + pcc->parent_realize(dev, errp); + #if defined(PPC_DUMP_CPU) { const char *mmu_model, *excp_model, *bus_model; @@ -10354,7 +10356,7 @@ PowerPCCPU *cpu_ppc_init(const char *cpu_model) env->cpu_model_str = cpu_model; - ppc_cpu_realize(OBJECT(cpu), &err); + object_property_set_bool(OBJECT(cpu), true, "realized", &err); if (err != NULL) { fprintf(stderr, "%s\n", error_get_pretty(err)); error_free(err); @@ -10575,6 +10577,10 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data) { PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); CPUClass *cc = CPU_CLASS(oc); + DeviceClass *dc = DEVICE_CLASS(oc); + + pcc->parent_realize = dc->realize; + dc->realize = ppc_cpu_realizefn; pcc->parent_reset = cc->reset; cc->reset = ppc_cpu_reset; From ca45f8b0440358ccca63446cf0df05772791b2a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 5 Jan 2013 15:41:21 +0100 Subject: [PATCH 07/47] target-cris: Introduce QOM realizefn for CRISCPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce realizefn and set realized = true from cpu_cris_init(). Reviewed-by: Eduardo Habkost Signed-off-by: Andreas Färber --- target-cris/cpu-qom.h | 2 ++ target-cris/cpu.c | 15 +++++++++++++++ target-cris/translate.c | 3 +-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h index 41ab9b2fa5..7ad8398760 100644 --- a/target-cris/cpu-qom.h +++ b/target-cris/cpu-qom.h @@ -33,6 +33,7 @@ /** * CRISCPUClass: + * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * * A CRIS CPU model. @@ -42,6 +43,7 @@ typedef struct CRISCPUClass { CPUClass parent_class; /*< public >*/ + DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); } CRISCPUClass; diff --git a/target-cris/cpu.c b/target-cris/cpu.c index 3f64a5747e..34c4f75a44 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -55,6 +55,17 @@ static void cris_cpu_reset(CPUState *s) #endif } +static void cris_cpu_realizefn(DeviceState *dev, Error **errp) +{ + CRISCPU *cpu = CRIS_CPU(dev); + CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(dev); + + cpu_reset(CPU(cpu)); + qemu_init_vcpu(&cpu->env); + + ccc->parent_realize(dev, errp); +} + static void cris_cpu_initfn(Object *obj) { CRISCPU *cpu = CRIS_CPU(obj); @@ -65,9 +76,13 @@ static void cris_cpu_initfn(Object *obj) static void cris_cpu_class_init(ObjectClass *oc, void *data) { + DeviceClass *dc = DEVICE_CLASS(oc); CPUClass *cc = CPU_CLASS(oc); CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); + ccc->parent_realize = dc->realize; + dc->realize = cris_cpu_realizefn; + ccc->parent_reset = cc->reset; cc->reset = cris_cpu_reset; } diff --git a/target-cris/translate.c b/target-cris/translate.c index 09e6011ea4..25ff490399 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -3558,8 +3558,7 @@ CRISCPU *cpu_cris_init(const char *cpu_model) env->pregs[PR_VR] = vr_by_name(cpu_model); - cpu_reset(CPU(cpu)); - qemu_init_vcpu(env); + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); if (tcg_initialized) { return cpu; From 9c23169e8cd54b490d55221b6498d42966f964f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Wed, 16 Jan 2013 03:31:27 +0100 Subject: [PATCH 08/47] target-lm32: Introduce QOM realizefn for LM32CPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a realizefn and set realized = true in cpu_lm32_init(). Also move cpu_reset() call from initfn to realizefn. Signed-off-by: Andreas Färber --- target-lm32/cpu-qom.h | 2 ++ target-lm32/cpu.c | 18 ++++++++++++++++-- target-lm32/helper.c | 4 ++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h index 400cdbd554..d7525b300c 100644 --- a/target-lm32/cpu-qom.h +++ b/target-lm32/cpu-qom.h @@ -34,6 +34,7 @@ /** * LM32CPUClass: + * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * * A LatticeMico32 CPU model. @@ -43,6 +44,7 @@ typedef struct LM32CPUClass { CPUClass parent_class; /*< public >*/ + DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); } LM32CPUClass; diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index eca2dca427..6a84f51bf9 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -42,6 +42,18 @@ static void lm32_cpu_reset(CPUState *s) memset(env, 0, offsetof(CPULM32State, breakpoints)); } +static void lm32_cpu_realizefn(DeviceState *dev, Error **errp) +{ + LM32CPU *cpu = LM32_CPU(dev); + LM32CPUClass *lcc = LM32_CPU_GET_CLASS(dev); + + cpu_reset(CPU(cpu)); + + qemu_init_vcpu(&cpu->env); + + lcc->parent_realize(dev, errp); +} + static void lm32_cpu_initfn(Object *obj) { LM32CPU *cpu = LM32_CPU(obj); @@ -50,14 +62,16 @@ static void lm32_cpu_initfn(Object *obj) cpu_exec_init(env); env->flags = 0; - - cpu_reset(CPU(cpu)); } static void lm32_cpu_class_init(ObjectClass *oc, void *data) { LM32CPUClass *lcc = LM32_CPU_CLASS(oc); CPUClass *cc = CPU_CLASS(oc); + DeviceClass *dc = DEVICE_CLASS(oc); + + lcc->parent_realize = dc->realize; + dc->realize = lm32_cpu_realizefn; lcc->parent_reset = cc->reset; cc->reset = lm32_cpu_reset; diff --git a/target-lm32/helper.c b/target-lm32/helper.c index d76ea3fe09..a6691addba 100644 --- a/target-lm32/helper.c +++ b/target-lm32/helper.c @@ -212,13 +212,13 @@ LM32CPU *cpu_lm32_init(const char *cpu_model) env->num_wps = def->num_watchpoints; env->cfg = cfg_by_def(def); - qemu_init_vcpu(env); - if (tcg_enabled() && !tcg_initialized) { tcg_initialized = 1; lm32_translate_init(); } + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); + return cpu; } From 6d1bbc6273d45520c5ce6475186bfa30d8afb47c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 5 Jan 2013 15:15:30 +0100 Subject: [PATCH 09/47] target-m68k: Introduce QOM realizefn for M68kCPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce realizefn and set realized = true in cpu_m68k_init(). Split off GDB registration to a new m68k_cpu_init_gdb() so that it can be called from the realizefn. Signed-off-by: Andreas Färber --- target-m68k/cpu-qom.h | 2 ++ target-m68k/cpu.c | 16 ++++++++++++++++ target-m68k/cpu.h | 1 + target-m68k/helper.c | 14 ++++++++++---- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/target-m68k/cpu-qom.h b/target-m68k/cpu-qom.h index 170daa7c96..20e5684552 100644 --- a/target-m68k/cpu-qom.h +++ b/target-m68k/cpu-qom.h @@ -33,6 +33,7 @@ /** * M68kCPUClass: + * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * * A Motorola 68k CPU model. @@ -42,6 +43,7 @@ typedef struct M68kCPUClass { CPUClass parent_class; /*< public >*/ + DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); } M68kCPUClass; diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index c71f715174..e3eaffc9ed 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -139,6 +139,19 @@ static const M68kCPUInfo m68k_cpus[] = { { .name = "any", .instance_init = any_cpu_initfn }, }; +static void m68k_cpu_realizefn(DeviceState *dev, Error **errp) +{ + M68kCPU *cpu = M68K_CPU(dev); + M68kCPUClass *mcc = M68K_CPU_GET_CLASS(dev); + + m68k_cpu_init_gdb(cpu); + + cpu_reset(CPU(cpu)); + qemu_init_vcpu(&cpu->env); + + mcc->parent_realize(dev, errp); +} + static void m68k_cpu_initfn(Object *obj) { M68kCPU *cpu = M68K_CPU(obj); @@ -158,6 +171,9 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data) CPUClass *cc = CPU_CLASS(c); DeviceClass *dc = DEVICE_CLASS(c); + mcc->parent_realize = dc->realize; + dc->realize = m68k_cpu_realizefn; + mcc->parent_reset = cc->reset; cc->reset = m68k_cpu_reset; diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index adaf56c471..94937c4fd7 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -116,6 +116,7 @@ typedef struct CPUM68KState { #include "cpu-qom.h" void m68k_tcg_init(void); +void m68k_cpu_init_gdb(M68kCPU *cpu); CPUM68KState *cpu_m68k_init(const char *cpu_model); int cpu_m68k_exec(CPUM68KState *s); void do_interrupt(CPUM68KState *env1); diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 5ddcd707fd..3ae6fa0492 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -120,15 +120,21 @@ CPUM68KState *cpu_m68k_init(const char *cpu_model) env->cpu_model_str = cpu_model; register_m68k_insns(env); + + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); + + return env; +} + +void m68k_cpu_init_gdb(M68kCPU *cpu) +{ + CPUM68KState *env = &cpu->env; + if (m68k_feature(env, M68K_FEATURE_CF_FPU)) { gdb_register_coprocessor(env, fpu_gdb_get_reg, fpu_gdb_set_reg, 11, "cf-fp.xml", 18); } /* TODO: Add [E]MAC registers. */ - - cpu_reset(ENV_GET_CPU(env)); - qemu_init_vcpu(env); - return env; } void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op) From 746b03b27cac48be5a376d8635ffaf568339ebd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 5 Jan 2013 15:27:31 +0100 Subject: [PATCH 10/47] target-microblaze: Introduce QOM realizefn for MicroBlazeCPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce realizefn and set realized = true from cpu_mb_init(). Signed-off-by: Andreas Färber --- target-microblaze/cpu-qom.h | 2 ++ target-microblaze/cpu.c | 14 ++++++++++++++ target-microblaze/translate.c | 3 +-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h index f75549dc22..5ea911c8e4 100644 --- a/target-microblaze/cpu-qom.h +++ b/target-microblaze/cpu-qom.h @@ -33,6 +33,7 @@ /** * MicroBlazeCPUClass: + * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * * A MicroBlaze CPU model. @@ -42,6 +43,7 @@ typedef struct MicroBlazeCPUClass { CPUClass parent_class; /*< public >*/ + DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); } MicroBlazeCPUClass; diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c index 39230fddcc..baae47b2c6 100644 --- a/target-microblaze/cpu.c +++ b/target-microblaze/cpu.c @@ -85,6 +85,17 @@ static void mb_cpu_reset(CPUState *s) #endif } +static void mb_cpu_realizefn(DeviceState *dev, Error **errp) +{ + MicroBlazeCPU *cpu = MICROBLAZE_CPU(dev); + MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_GET_CLASS(dev); + + cpu_reset(CPU(cpu)); + qemu_init_vcpu(&cpu->env); + + mcc->parent_realize(dev, errp); +} + static void mb_cpu_initfn(Object *obj) { MicroBlazeCPU *cpu = MICROBLAZE_CPU(obj); @@ -106,6 +117,9 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data) CPUClass *cc = CPU_CLASS(oc); MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_CLASS(oc); + mcc->parent_realize = dc->realize; + dc->realize = mb_cpu_realizefn; + mcc->parent_reset = cc->reset; cc->reset = mb_cpu_reset; diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c index 58ce71267d..a84856ba43 100644 --- a/target-microblaze/translate.c +++ b/target-microblaze/translate.c @@ -1970,8 +1970,7 @@ MicroBlazeCPU *cpu_mb_init(const char *cpu_model) cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU)); - cpu_reset(CPU(cpu)); - qemu_init_vcpu(&cpu->env); + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); if (tcg_initialized) { return cpu; From c1caf1d961288e41c25de6631c6751ae7baa20f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Wed, 16 Jan 2013 03:48:37 +0100 Subject: [PATCH 11/47] target-mips: Introduce QOM realizefn for MIPSCPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a realizefn and set realized = true from cpu_mips_init(). Signed-off-by: Andreas Färber --- target-mips/cpu-qom.h | 2 ++ target-mips/cpu.c | 15 +++++++++++++++ target-mips/translate.c | 5 +++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h index 2a4b812402..55aa692a85 100644 --- a/target-mips/cpu-qom.h +++ b/target-mips/cpu-qom.h @@ -37,6 +37,7 @@ /** * MIPSCPUClass: + * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * * A MIPS CPU model. @@ -46,6 +47,7 @@ typedef struct MIPSCPUClass { CPUClass parent_class; /*< public >*/ + DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); } MIPSCPUClass; diff --git a/target-mips/cpu.c b/target-mips/cpu.c index 10ff46d6a7..18895da80e 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -42,6 +42,17 @@ static void mips_cpu_reset(CPUState *s) cpu_state_reset(env); } +static void mips_cpu_realizefn(DeviceState *dev, Error **errp) +{ + MIPSCPU *cpu = MIPS_CPU(dev); + MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(dev); + + cpu_reset(CPU(cpu)); + qemu_init_vcpu(&cpu->env); + + mcc->parent_realize(dev, errp); +} + static void mips_cpu_initfn(Object *obj) { MIPSCPU *cpu = MIPS_CPU(obj); @@ -54,6 +65,10 @@ static void mips_cpu_class_init(ObjectClass *c, void *data) { MIPSCPUClass *mcc = MIPS_CPU_CLASS(c); CPUClass *cc = CPU_CLASS(c); + DeviceClass *dc = DEVICE_CLASS(c); + + mcc->parent_realize = dc->realize; + dc->realize = mips_cpu_realizefn; mcc->parent_reset = cc->reset; cc->reset = mips_cpu_reset; diff --git a/target-mips/translate.c b/target-mips/translate.c index 3b77b53b93..d7f650e0bf 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -15916,8 +15916,9 @@ MIPSCPU *cpu_mips_init(const char *cpu_model) fpu_init(env, def); mvp_init(env, def); mips_tcg_init(); - cpu_reset(CPU(cpu)); - qemu_init_vcpu(env); + + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); + return cpu; } From 1f1366322b21678c33003a373366697a4542d2d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Wed, 16 Jan 2013 04:00:41 +0100 Subject: [PATCH 12/47] target-s390x: Introduce QOM realizefn for S390CPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce realizefn and set realized = true in cpu_s390x_init(). Defer CPU reset from initfn to realizefn. Acked-by: Richard Henderson [AF: Invoke parent's realizefn] Signed-off-by: Andreas Färber --- target-s390x/cpu-qom.h | 2 ++ target-s390x/cpu.c | 16 ++++++++++++++-- target-s390x/helper.c | 4 +++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h index d54e4a2ee2..237184f55a 100644 --- a/target-s390x/cpu-qom.h +++ b/target-s390x/cpu-qom.h @@ -34,6 +34,7 @@ /** * S390CPUClass: + * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * * An S/390 CPU model. @@ -43,6 +44,7 @@ typedef struct S390CPUClass { CPUClass parent_class; /*< public >*/ + DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); } S390CPUClass; diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index d765e7b984..ee15783b94 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -97,6 +97,17 @@ static void s390_cpu_machine_reset_cb(void *opaque) } #endif +static void s390_cpu_realizefn(DeviceState *dev, Error **errp) +{ + S390CPU *cpu = S390_CPU(dev); + S390CPUClass *scc = S390_CPU_GET_CLASS(dev); + + qemu_init_vcpu(&cpu->env); + cpu_reset(CPU(cpu)); + + scc->parent_realize(dev, errp); +} + static void s390_cpu_initfn(Object *obj) { S390CPU *cpu = S390_CPU(obj); @@ -122,8 +133,6 @@ static void s390_cpu_initfn(Object *obj) #endif env->cpu_num = cpu_num++; env->ext_index = -1; - - cpu_reset(CPU(cpu)); } static void s390_cpu_finalize(Object *obj) @@ -146,6 +155,9 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data) CPUClass *cc = CPU_CLASS(scc); DeviceClass *dc = DEVICE_CLASS(oc); + scc->parent_realize = dc->realize; + dc->realize = s390_cpu_realizefn; + scc->parent_reset = cc->reset; cc->reset = s390_cpu_reset; diff --git a/target-s390x/helper.c b/target-s390x/helper.c index 76268317a3..d3bb4561f1 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -85,7 +85,9 @@ S390CPU *cpu_s390x_init(const char *cpu_model) } env->cpu_model_str = cpu_model; - qemu_init_vcpu(env); + + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); + return cpu; } From 55acb588dd184a1e33be0ff1fe23f8c19f88fd6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Mon, 23 Apr 2012 18:16:02 +0200 Subject: [PATCH 13/47] target-sh4: Introduce QOM realizefn for SuperHCPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a realizefn and set realized = true in cpu_sh4_init(). Signed-off-by: Andreas Färber --- target-sh4/cpu-qom.h | 2 ++ target-sh4/cpu.c | 14 ++++++++++++++ target-sh4/translate.c | 5 +++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h index 09573c9c34..d368db1b0a 100644 --- a/target-sh4/cpu-qom.h +++ b/target-sh4/cpu-qom.h @@ -33,6 +33,7 @@ /** * SuperHCPUClass: + * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * * A SuperH CPU model. @@ -42,6 +43,7 @@ typedef struct SuperHCPUClass { CPUClass parent_class; /*< public >*/ + DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); } SuperHCPUClass; diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index d2831226b9..c66442f445 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -54,6 +54,17 @@ static void superh_cpu_reset(CPUState *s) set_default_nan_mode(1, &env->fp_status); } +static void superh_cpu_realizefn(DeviceState *dev, Error **errp) +{ + SuperHCPU *cpu = SUPERH_CPU(dev); + SuperHCPUClass *scc = SUPERH_CPU_GET_CLASS(dev); + + cpu_reset(CPU(cpu)); + qemu_init_vcpu(&cpu->env); + + scc->parent_realize(dev, errp); +} + static void superh_cpu_initfn(Object *obj) { SuperHCPU *cpu = SUPERH_CPU(obj); @@ -75,6 +86,9 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data) CPUClass *cc = CPU_CLASS(oc); SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); + scc->parent_realize = dc->realize; + dc->realize = superh_cpu_realizefn; + scc->parent_reset = cc->reset; cc->reset = superh_cpu_reset; diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 260aaab559..2409a103b2 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -253,9 +253,10 @@ SuperHCPU *cpu_sh4_init(const char *cpu_model) env->features = def->features; sh4_translate_init(); env->cpu_model_str = cpu_model; - cpu_reset(CPU(cpu)); cpu_register(env, def); - qemu_init_vcpu(env); + + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); + return cpu; } From b6e91ebfe06f1d90331d162259553a5330514143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Wed, 16 Jan 2013 04:13:19 +0100 Subject: [PATCH 14/47] target-sparc: Introduce QOM realizefn for SPARCCPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce realizefn and set realized = true in cpu_sparc_init(). Signed-off-by: Andreas Färber --- target-sparc/cpu-qom.h | 2 ++ target-sparc/cpu.c | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h index 2a738ae360..89cd1cf2d3 100644 --- a/target-sparc/cpu-qom.h +++ b/target-sparc/cpu-qom.h @@ -38,6 +38,7 @@ /** * SPARCCPUClass: + * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * * A SPARC CPU model. @@ -47,6 +48,7 @@ typedef struct SPARCCPUClass { CPUClass parent_class; /*< public >*/ + DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); } SPARCCPUClass; diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index 4bc1afc755..1690cf5b15 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -122,7 +122,8 @@ SPARCCPU *cpu_sparc_init(const char *cpu_model) object_unref(OBJECT(cpu)); return NULL; } - qemu_init_vcpu(env); + + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); return cpu; } @@ -851,6 +852,16 @@ void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf, cpu_fprintf(f, "\n"); } +static void sparc_cpu_realizefn(DeviceState *dev, Error **errp) +{ + SPARCCPU *cpu = SPARC_CPU(dev); + SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev); + + qemu_init_vcpu(&cpu->env); + + scc->parent_realize(dev, errp); +} + static void sparc_cpu_initfn(Object *obj) { SPARCCPU *cpu = SPARC_CPU(obj); @@ -871,6 +882,10 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data) { SPARCCPUClass *scc = SPARC_CPU_CLASS(oc); CPUClass *cc = CPU_CLASS(oc); + DeviceClass *dc = DEVICE_CLASS(oc); + + scc->parent_realize = dc->realize; + dc->realize = sparc_cpu_realizefn; scc->parent_reset = cc->reset; cc->reset = sparc_cpu_reset; From 088383e3220776917f538d0e43933e842e16b804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 5 Jan 2013 14:38:30 +0100 Subject: [PATCH 15/47] target-unicore32: Introduce QOM realizefn for UniCore32CPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a realizefn and set realized = true in uc32_cpu_init(). Acked-by: Guan Xuetao [AF: Invoke the parent's realizefn] Signed-off-by: Andreas Färber --- target-unicore32/cpu-qom.h | 3 +++ target-unicore32/cpu.c | 14 ++++++++++++++ target-unicore32/helper.c | 3 ++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/target-unicore32/cpu-qom.h b/target-unicore32/cpu-qom.h index fe40b2d6a8..625c6143db 100644 --- a/target-unicore32/cpu-qom.h +++ b/target-unicore32/cpu-qom.h @@ -25,6 +25,7 @@ /** * UniCore32CPUClass: + * @parent_realize: The parent class' realize handler. * * A UniCore32 CPU model. */ @@ -32,6 +33,8 @@ typedef struct UniCore32CPUClass { /*< private >*/ CPUClass parent_class; /*< public >*/ + + DeviceRealize parent_realize; } UniCore32CPUClass; /** diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c index 4e4177fc57..8de17a49d6 100644 --- a/target-unicore32/cpu.c +++ b/target-unicore32/cpu.c @@ -81,6 +81,16 @@ static const UniCore32CPUInfo uc32_cpus[] = { { .name = "any", .instance_init = uc32_any_cpu_initfn }, }; +static void uc32_cpu_realizefn(DeviceState *dev, Error **errp) +{ + UniCore32CPU *cpu = UNICORE32_CPU(dev); + UniCore32CPUClass *ucc = UNICORE32_CPU_GET_CLASS(dev); + + qemu_init_vcpu(&cpu->env); + + ucc->parent_realize(dev, errp); +} + static void uc32_cpu_initfn(Object *obj) { UniCore32CPU *cpu = UNICORE32_CPU(obj); @@ -108,6 +118,10 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); CPUClass *cc = CPU_CLASS(oc); + UniCore32CPUClass *ucc = UNICORE32_CPU_CLASS(oc); + + ucc->parent_realize = dc->realize; + dc->realize = uc32_cpu_realizefn; cc->class_by_name = uc32_cpu_class_by_name; dc->vmsd = &vmstate_uc32_cpu; diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c index 3a92232de5..2442133319 100644 --- a/target-unicore32/helper.c +++ b/target-unicore32/helper.c @@ -45,7 +45,8 @@ CPUUniCore32State *uc32_cpu_init(const char *cpu_model) uc32_translate_init(); } - qemu_init_vcpu(env); + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); + return env; } From 5f6c964389ea5320e81e2fb8c2bc3aa40c5a8013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Wed, 16 Jan 2013 04:19:35 +0100 Subject: [PATCH 16/47] target-xtensa: Introduce QOM realizefn for XtensaCPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce realizefn and set realized = true in cpu_xtensa_init(). Signed-off-by: Andreas Färber --- target-xtensa/cpu-qom.h | 2 ++ target-xtensa/cpu.c | 13 +++++++++++++ target-xtensa/helper.c | 4 +++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h index e344a9aa79..270de16583 100644 --- a/target-xtensa/cpu-qom.h +++ b/target-xtensa/cpu-qom.h @@ -43,6 +43,7 @@ /** * XtensaCPUClass: + * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * * An Xtensa CPU model. @@ -52,6 +53,7 @@ typedef struct XtensaCPUClass { CPUClass parent_class; /*< public >*/ + DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); } XtensaCPUClass; diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c index ebc7e9979b..d3706a30ac 100644 --- a/target-xtensa/cpu.c +++ b/target-xtensa/cpu.c @@ -57,6 +57,16 @@ static void xtensa_cpu_reset(CPUState *s) reset_mmu(env); } +static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp) +{ + XtensaCPU *cpu = XTENSA_CPU(dev); + XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(dev); + + qemu_init_vcpu(&cpu->env); + + xcc->parent_realize(dev, errp); +} + static void xtensa_cpu_initfn(Object *obj) { XtensaCPU *cpu = XTENSA_CPU(obj); @@ -76,6 +86,9 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data) CPUClass *cc = CPU_CLASS(oc); XtensaCPUClass *xcc = XTENSA_CPU_CLASS(cc); + xcc->parent_realize = dc->realize; + dc->realize = xtensa_cpu_realizefn; + xcc->parent_reset = cc->reset; cc->reset = xtensa_cpu_reset; diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c index 94c03a1d3c..14bcc7ef23 100644 --- a/target-xtensa/helper.c +++ b/target-xtensa/helper.c @@ -104,7 +104,9 @@ XtensaCPU *cpu_xtensa_init(const char *cpu_model) } xtensa_irq_init(env); - qemu_init_vcpu(env); + + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); + return cpu; } From 79614b781df5096ffecf531992314781dbab54af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 19 Jan 2013 07:37:45 +0100 Subject: [PATCH 17/47] target-arm: Move TCG initialization to ARMCPU initfn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensures that a QOM-created ARMCPU is usable. Signed-off-by: Andreas Färber --- target-arm/cpu.c | 6 ++++++ target-arm/helper.c | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 9915172a1d..f54d20057d 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -135,10 +135,16 @@ static inline void set_feature(CPUARMState *env, int feature) static void arm_cpu_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + static bool inited; cpu_exec_init(&cpu->env); cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free); + + if (tcg_enabled() && !inited) { + inited = true; + arm_translate_init(); + } } static void arm_cpu_finalizefn(Object *obj) diff --git a/target-arm/helper.c b/target-arm/helper.c index 4538a09445..e63da57a51 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1263,7 +1263,6 @@ ARMCPU *cpu_arm_init(const char *cpu_model) ARMCPU *cpu; CPUARMState *env; ObjectClass *oc; - static int inited = 0; oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model); if (!oc) { @@ -1276,11 +1275,6 @@ ARMCPU *cpu_arm_init(const char *cpu_model) /* TODO this should be set centrally, once possible */ object_property_set_bool(OBJECT(cpu), true, "realized", NULL); - if (tcg_enabled() && !inited) { - inited = 1; - arm_translate_init(); - } - return cpu; } From d1a94fec3d8d70009fd5ac27ade5539fe58cd702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 19 Jan 2013 23:55:42 +0100 Subject: [PATCH 18/47] target-cris: Move TCG initialization to CRISCPU initfn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split out TCG initialization from cpu_cris_init(). Avoid CPUCRISState dependency for v10-specific initialization and for non-v10 by inlining the decision into the initfn as well. Signed-off-by: Andreas Färber --- target-cris/cpu.c | 10 ++++++++++ target-cris/cpu.h | 3 +++ target-cris/translate.c | 19 +++++-------------- target-cris/translate_v10.c | 5 +---- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/target-cris/cpu.c b/target-cris/cpu.c index 34c4f75a44..fedf64191d 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -70,8 +70,18 @@ static void cris_cpu_initfn(Object *obj) { CRISCPU *cpu = CRIS_CPU(obj); CPUCRISState *env = &cpu->env; + static bool tcg_initialized; cpu_exec_init(env); + + if (tcg_enabled() && !tcg_initialized) { + tcg_initialized = true; + if (env->pregs[PR_VR] < 32) { + cris_initialize_crisv10_tcg(); + } else { + cris_initialize_tcg(); + } + } } static void cris_cpu_class_init(ObjectClass *oc, void *data) diff --git a/target-cris/cpu.h b/target-cris/cpu.h index 257cb52be2..ebf2d4027f 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -182,6 +182,9 @@ void do_interrupt(CPUCRISState *env); int cpu_cris_signal_handler(int host_signum, void *pinfo, void *puc); +void cris_initialize_tcg(void); +void cris_initialize_crisv10_tcg(void); + enum { CC_OP_DYNAMIC, /* Use env->cc_op */ CC_OP_FLAGS, diff --git a/target-cris/translate.c b/target-cris/translate.c index 25ff490399..25a43faf35 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -3550,8 +3550,6 @@ CRISCPU *cpu_cris_init(const char *cpu_model) { CRISCPU *cpu; CPUCRISState *env; - static int tcg_initialized = 0; - int i; cpu = CRIS_CPU(object_new(TYPE_CRIS_CPU)); env = &cpu->env; @@ -3560,21 +3558,16 @@ CRISCPU *cpu_cris_init(const char *cpu_model) object_property_set_bool(OBJECT(cpu), true, "realized", NULL); - if (tcg_initialized) { - return cpu; - } + return cpu; +} - tcg_initialized = 1; +void cris_initialize_tcg(void) +{ + int i; #define GEN_HELPER 2 #include "helper.h" - if (env->pregs[PR_VR] < 32) { - cpu_crisv10_init(env); - return cpu; - } - - cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); cc_x = tcg_global_mem_new(TCG_AREG0, offsetof(CPUCRISState, cc_x), "cc_x"); @@ -3614,8 +3607,6 @@ CRISCPU *cpu_cris_init(const char *cpu_model) offsetof(CPUCRISState, pregs[i]), pregnames[i]); } - - return cpu; } void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb, int pc_pos) diff --git a/target-cris/translate_v10.c b/target-cris/translate_v10.c index d2cca892e0..d6ef084483 100644 --- a/target-cris/translate_v10.c +++ b/target-cris/translate_v10.c @@ -1257,7 +1257,7 @@ static unsigned int crisv10_decoder(CPUCRISState *env, DisasContext *dc) return insn_len; } -static CPUCRISState *cpu_crisv10_init (CPUCRISState *env) +void cris_initialize_crisv10_tcg(void) { int i; @@ -1300,7 +1300,4 @@ static CPUCRISState *cpu_crisv10_init (CPUCRISState *env) offsetof(CPUCRISState, pregs[i]), pregnames_v10[i]); } - - return env; } - From 868e2824276cbe6ef2e202c05c4eb3a3a19d3ee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 20 Jan 2013 00:05:12 +0100 Subject: [PATCH 19/47] target-lm32: Move TCG initialization to LM32CPU initfn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Färber --- target-lm32/cpu.c | 6 ++++++ target-lm32/helper.c | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index 6a84f51bf9..5f167340e4 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -58,10 +58,16 @@ static void lm32_cpu_initfn(Object *obj) { LM32CPU *cpu = LM32_CPU(obj); CPULM32State *env = &cpu->env; + static bool tcg_initialized; cpu_exec_init(env); env->flags = 0; + + if (tcg_enabled() && !tcg_initialized) { + tcg_initialized = true; + lm32_translate_init(); + } } static void lm32_cpu_class_init(ObjectClass *oc, void *data) diff --git a/target-lm32/helper.c b/target-lm32/helper.c index a6691addba..47ae7e775a 100644 --- a/target-lm32/helper.c +++ b/target-lm32/helper.c @@ -197,7 +197,6 @@ LM32CPU *cpu_lm32_init(const char *cpu_model) LM32CPU *cpu; CPULM32State *env; const LM32Def *def; - static int tcg_initialized; def = cpu_lm32_find_by_name(cpu_model); if (!def) { @@ -212,11 +211,6 @@ LM32CPU *cpu_lm32_init(const char *cpu_model) env->num_wps = def->num_watchpoints; env->cfg = cfg_by_def(def); - if (tcg_enabled() && !tcg_initialized) { - tcg_initialized = 1; - lm32_translate_init(); - } - object_property_set_bool(OBJECT(cpu), true, "realized", NULL); return cpu; From 1cc896195bae54d7a5f48f9032037d8f6f65abd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 20 Jan 2013 00:48:29 +0100 Subject: [PATCH 20/47] target-m68k: Move TCG initialization to M68kCPU initfn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a tcg_enabled() check to suppress it for qtest. Signed-off-by: Andreas Färber --- target-m68k/cpu.c | 6 ++++++ target-m68k/helper.c | 7 ------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index e3eaffc9ed..42735dbe40 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -156,8 +156,14 @@ static void m68k_cpu_initfn(Object *obj) { M68kCPU *cpu = M68K_CPU(obj); CPUM68KState *env = &cpu->env; + static bool inited; cpu_exec_init(env); + + if (tcg_enabled() && !inited) { + inited = true; + m68k_tcg_init(); + } } static const VMStateDescription vmstate_m68k_cpu = { diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 3ae6fa0492..6030807753 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -103,7 +103,6 @@ CPUM68KState *cpu_m68k_init(const char *cpu_model) M68kCPU *cpu; CPUM68KState *env; ObjectClass *oc; - static int inited; oc = cpu_class_by_name(TYPE_M68K_CPU, cpu_model); if (oc == NULL) { @@ -111,12 +110,6 @@ CPUM68KState *cpu_m68k_init(const char *cpu_model) } cpu = M68K_CPU(object_new(object_class_get_name(oc))); env = &cpu->env; - - if (!inited) { - inited = 1; - m68k_tcg_init(); - } - env->cpu_model_str = cpu_model; register_m68k_insns(env); From cd0c24f9095b1f825210bb9d9f99532c78668074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 20 Jan 2013 01:10:52 +0100 Subject: [PATCH 21/47] target-microblaze: Move TCG initialization to MicroBlazeCPU initfn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split off TCG initialization from cpu_mb_init() into mb_tcg_init() to call it from the initfn. Ensures that a QOM-created MicroBlazeCPU is usable. Signed-off-by: Andreas Färber --- target-microblaze/cpu.c | 6 ++++++ target-microblaze/cpu.h | 1 + target-microblaze/translate.c | 13 +++++-------- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c index baae47b2c6..28b5a88789 100644 --- a/target-microblaze/cpu.c +++ b/target-microblaze/cpu.c @@ -100,10 +100,16 @@ static void mb_cpu_initfn(Object *obj) { MicroBlazeCPU *cpu = MICROBLAZE_CPU(obj); CPUMBState *env = &cpu->env; + static bool tcg_initialized; cpu_exec_init(env); set_float_rounding_mode(float_round_nearest_even, &env->fp_status); + + if (tcg_enabled() && !tcg_initialized) { + tcg_initialized = true; + mb_tcg_init(); + } } static const VMStateDescription vmstate_mb_cpu = { diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h index 41480e71e1..c3dd7f6219 100644 --- a/target-microblaze/cpu.h +++ b/target-microblaze/cpu.h @@ -272,6 +272,7 @@ struct CPUMBState { #include "cpu-qom.h" +void mb_tcg_init(void); MicroBlazeCPU *cpu_mb_init(const char *cpu_model); int cpu_mb_exec(CPUMBState *s); void do_interrupt(CPUMBState *env); diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c index a84856ba43..12ea820522 100644 --- a/target-microblaze/translate.c +++ b/target-microblaze/translate.c @@ -1965,18 +1965,17 @@ void cpu_dump_state (CPUMBState *env, FILE *f, fprintf_function cpu_fprintf, MicroBlazeCPU *cpu_mb_init(const char *cpu_model) { MicroBlazeCPU *cpu; - static int tcg_initialized = 0; - int i; cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU)); object_property_set_bool(OBJECT(cpu), true, "realized", NULL); - if (tcg_initialized) { - return cpu; - } + return cpu; +} - tcg_initialized = 1; +void mb_tcg_init(void) +{ + int i; cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); @@ -2007,8 +2006,6 @@ MicroBlazeCPU *cpu_mb_init(const char *cpu_model) } #define GEN_HELPER 2 #include "helper.h" - - return cpu; } void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb, int pc_pos) From 78ce64f492498050083e46cdd7e6cbae6435843c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 20 Jan 2013 01:22:25 +0100 Subject: [PATCH 22/47] target-mips: Move TCG initialization to MIPSCPU initfn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make mips_tcg_init() non-static and add tcg_enabled() check to suppress it for qtest. Signed-off-by: Andreas Färber --- target-mips/cpu.c | 4 ++++ target-mips/cpu.h | 1 + target-mips/translate.c | 3 +-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/target-mips/cpu.c b/target-mips/cpu.c index 18895da80e..09d61723c5 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -59,6 +59,10 @@ static void mips_cpu_initfn(Object *obj) CPUMIPSState *env = &cpu->env; cpu_exec_init(env); + + if (tcg_enabled()) { + mips_tcg_init(); + } } static void mips_cpu_class_init(ObjectClass *c, void *data) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 5963d62973..0e198b12db 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -629,6 +629,7 @@ enum { #define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0 int cpu_mips_exec(CPUMIPSState *s); +void mips_tcg_init(void); MIPSCPU *cpu_mips_init(const char *cpu_model); int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc); diff --git a/target-mips/translate.c b/target-mips/translate.c index d7f650e0bf..4ee9615fda 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -15836,7 +15836,7 @@ void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf, #endif } -static void mips_tcg_init(void) +void mips_tcg_init(void) { int i; static int inited; @@ -15915,7 +15915,6 @@ MIPSCPU *cpu_mips_init(const char *cpu_model) #endif fpu_init(env, def); mvp_init(env, def); - mips_tcg_init(); object_property_set_bool(OBJECT(cpu), true, "realized", NULL); From 60925d2644953ce1ca7813411853d8c04e637050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 20 Jan 2013 01:26:37 +0100 Subject: [PATCH 23/47] target-ppc: Move TCG initialization to PowerPCCPU initfn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensures that a QOM-created PowerPCCPU is usable. Signed-off-by: Andreas Färber --- target-ppc/translate_init.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 49eaeac7c5..5a2acaafe8 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -10349,11 +10349,6 @@ PowerPCCPU *cpu_ppc_init(const char *cpu_model) cpu = POWERPC_CPU(object_new(object_class_get_name(oc))); env = &cpu->env; - - if (tcg_enabled()) { - ppc_translate_init(); - } - env->cpu_model_str = cpu_model; object_property_set_bool(OBJECT(cpu), true, "realized", &err); @@ -10571,6 +10566,10 @@ static void ppc_cpu_initfn(Object *obj) env->sps = defsps; } #endif /* defined(TARGET_PPC64) */ + + if (tcg_enabled()) { + ppc_translate_init(); + } } static void ppc_cpu_class_init(ObjectClass *oc, void *data) From 2b7ac76729c8253d799a8d3bb9bae76cccb0714e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 19 Jan 2013 22:43:32 +0100 Subject: [PATCH 24/47] target-s390x: Move TCG initialization to S390CPU initfn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensures that a QOM-created S390CPU is usable. Acked-by: Richard Henderson Signed-off-by: Andreas Färber --- target-s390x/cpu.c | 6 ++++++ target-s390x/helper.c | 7 ------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index ee15783b94..787c937579 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -112,6 +112,7 @@ static void s390_cpu_initfn(Object *obj) { S390CPU *cpu = S390_CPU(obj); CPUS390XState *env = &cpu->env; + static bool inited; static int cpu_num = 0; #if !defined(CONFIG_USER_ONLY) struct tm tm; @@ -133,6 +134,11 @@ static void s390_cpu_initfn(Object *obj) #endif env->cpu_num = cpu_num++; env->ext_index = -1; + + if (tcg_enabled() && !inited) { + inited = true; + s390x_translate_init(); + } } static void s390_cpu_finalize(Object *obj) diff --git a/target-s390x/helper.c b/target-s390x/helper.c index d3bb4561f1..1183b45ca1 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -74,16 +74,9 @@ S390CPU *cpu_s390x_init(const char *cpu_model) { S390CPU *cpu; CPUS390XState *env; - static int inited; cpu = S390_CPU(object_new(TYPE_S390_CPU)); env = &cpu->env; - - if (tcg_enabled() && !inited) { - inited = 1; - s390x_translate_init(); - } - env->cpu_model_str = cpu_model; object_property_set_bool(OBJECT(cpu), true, "realized", NULL); From aa7408ec18c3517b2476a3671cd0b7f171241e2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 20 Jan 2013 01:30:32 +0100 Subject: [PATCH 25/47] target-sh4: Move TCG initialization to SuperHCPU initfn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a tcg_enabled() check to suppress it for qtest. Signed-off-by: Andreas Färber --- target-sh4/cpu.c | 4 ++++ target-sh4/cpu.h | 1 + target-sh4/translate.c | 3 +-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index c66442f445..dc5d7568ea 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -73,6 +73,10 @@ static void superh_cpu_initfn(Object *obj) cpu_exec_init(env); env->movcal_backup_tail = &(env->movcal_backup); + + if (tcg_enabled()) { + sh4_translate_init(); + } } static const VMStateDescription vmstate_sh_cpu = { diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index 34e9b0acf7..49dcd9e7f3 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -191,6 +191,7 @@ typedef struct CPUSH4State { #include "cpu-qom.h" +void sh4_translate_init(void); SuperHCPU *cpu_sh4_init(const char *cpu_model); int cpu_sh4_exec(CPUSH4State * s); int cpu_sh4_signal_handler(int host_signum, void *pinfo, diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 2409a103b2..c58d79a5cd 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -71,7 +71,7 @@ static uint32_t gen_opc_hflags[OPC_BUF_SIZE]; #include "exec/gen-icount.h" -static void sh4_translate_init(void) +void sh4_translate_init(void) { int i; static int done_init = 0; @@ -251,7 +251,6 @@ SuperHCPU *cpu_sh4_init(const char *cpu_model) cpu = SUPERH_CPU(object_new(TYPE_SUPERH_CPU)); env = &cpu->env; env->features = def->features; - sh4_translate_init(); env->cpu_model_str = cpu_model; cpu_register(env, def); From 5266d20a12f2ef01841aad5f1692d73551a39dac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 20 Jan 2013 01:34:18 +0100 Subject: [PATCH 26/47] target-sparc: Move TCG initialization to SPARCCPU initfn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Färber --- target-sparc/cpu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index 1690cf5b15..759be532a3 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -114,10 +114,6 @@ SPARCCPU *cpu_sparc_init(const char *cpu_model) cpu = SPARC_CPU(object_new(TYPE_SPARC_CPU)); env = &cpu->env; - if (tcg_enabled()) { - gen_intermediate_code_init(env); - } - if (cpu_sparc_register(env, cpu_model) < 0) { object_unref(OBJECT(cpu)); return NULL; @@ -868,6 +864,10 @@ static void sparc_cpu_initfn(Object *obj) CPUSPARCState *env = &cpu->env; cpu_exec_init(env); + + if (tcg_enabled()) { + gen_intermediate_code_init(env); + } } static void sparc_cpu_uninitfn(Object *obj) From d9c27f00b174df070470d48d6577042d2186d969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 20 Jan 2013 01:36:47 +0100 Subject: [PATCH 27/47] target-unicore32: Move TCG initialization to UniCore32CPU initfn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Normalize the "inited" logic and add a tcg_enabled() check to suppress it for qtest. Ensures that a QOM-created UniCore32CPU is usable. Acked-by: Guan Xuetao Signed-off-by: Andreas Färber --- target-unicore32/cpu.c | 6 ++++++ target-unicore32/helper.c | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c index 8de17a49d6..7bcf3b3658 100644 --- a/target-unicore32/cpu.c +++ b/target-unicore32/cpu.c @@ -95,6 +95,7 @@ static void uc32_cpu_initfn(Object *obj) { UniCore32CPU *cpu = UNICORE32_CPU(obj); CPUUniCore32State *env = &cpu->env; + static bool inited; cpu_exec_init(env); @@ -107,6 +108,11 @@ static void uc32_cpu_initfn(Object *obj) #endif tlb_flush(env, 1); + + if (tcg_enabled() && !inited) { + inited = true; + uc32_translate_init(); + } } static const VMStateDescription vmstate_uc32_cpu = { diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c index 2442133319..7eeb9bc633 100644 --- a/target-unicore32/helper.c +++ b/target-unicore32/helper.c @@ -30,7 +30,6 @@ CPUUniCore32State *uc32_cpu_init(const char *cpu_model) UniCore32CPU *cpu; CPUUniCore32State *env; ObjectClass *oc; - static int inited = 1; oc = cpu_class_by_name(TYPE_UNICORE32_CPU, cpu_model); if (oc == NULL) { @@ -40,11 +39,6 @@ CPUUniCore32State *uc32_cpu_init(const char *cpu_model) env = &cpu->env; env->cpu_model_str = cpu_model; - if (inited) { - inited = 0; - uc32_translate_init(); - } - object_property_set_bool(OBJECT(cpu), true, "realized", NULL); return env; From 25733eada6c1d4928262e77e2ee1e9ed12de18fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 20 Jan 2013 01:46:45 +0100 Subject: [PATCH 28/47] target-xtensa: Move TCG initialization to XtensaCPU initfn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Combine this with breakpoint handler registration, guarding both with tcg_enabled() to suppress also TCG init for qtest. Rename the handler to xtensa_breakpoint_handler() since it needs to become global. Signed-off-by: Andreas Färber --- target-xtensa/cpu.c | 7 +++++++ target-xtensa/cpu.h | 1 + target-xtensa/helper.c | 14 +------------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c index d3706a30ac..309bb169ec 100644 --- a/target-xtensa/cpu.c +++ b/target-xtensa/cpu.c @@ -71,8 +71,15 @@ static void xtensa_cpu_initfn(Object *obj) { XtensaCPU *cpu = XTENSA_CPU(obj); CPUXtensaState *env = &cpu->env; + static bool tcg_inited; cpu_exec_init(env); + + if (tcg_enabled() && !tcg_inited) { + tcg_inited = true; + xtensa_translate_init(); + cpu_set_debug_excp_handler(xtensa_breakpoint_handler); + } } static const VMStateDescription vmstate_xtensa_cpu = { diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index 5acf78c692..dece224478 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -385,6 +385,7 @@ static inline CPUXtensaState *cpu_init(const char *cpu_model) } 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); diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c index 14bcc7ef23..a8a64932da 100644 --- a/target-xtensa/helper.c +++ b/target-xtensa/helper.c @@ -54,7 +54,7 @@ static uint32_t check_hw_breakpoints(CPUXtensaState *env) return 0; } -static void breakpoint_handler(CPUXtensaState *env) +void xtensa_breakpoint_handler(CPUXtensaState *env) { if (env->watchpoint_hit) { if (env->watchpoint_hit->flags & BP_CPU) { @@ -72,8 +72,6 @@ static void breakpoint_handler(CPUXtensaState *env) XtensaCPU *cpu_xtensa_init(const char *cpu_model) { - static int tcg_inited; - static int debug_handler_inited; XtensaCPU *cpu; CPUXtensaState *env; const XtensaConfig *config = NULL; @@ -93,16 +91,6 @@ XtensaCPU *cpu_xtensa_init(const char *cpu_model) env = &cpu->env; env->config = config; - if (!tcg_inited) { - tcg_inited = 1; - xtensa_translate_init(); - } - - if (!debug_handler_inited && tcg_enabled()) { - debug_handler_inited = 1; - cpu_set_debug_excp_handler(breakpoint_handler); - } - xtensa_irq_init(env); object_property_set_bool(OBJECT(cpu), true, "realized", NULL); From f3273ba643f2d0221492381b24bbc35fb6089a48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 18 Jan 2013 15:57:51 +0100 Subject: [PATCH 29/47] ppc405_uc: Pass PowerPCCPU to ppc40x_{core,chip,system}_reset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prepares for changing cpu_interrupt() argument to CPUState. Signed-off-by: Andreas Färber Acked-by: Alexander Graf --- hw/ppc.c | 12 ++++++------ hw/ppc.h | 6 +++--- hw/ppc405_uc.c | 16 ++++++++++------ 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/hw/ppc.c b/hw/ppc.c index 6053bd5652..8cfb84fa13 100644 --- a/hw/ppc.c +++ b/hw/ppc.c @@ -300,20 +300,20 @@ static void ppc40x_set_irq(void *opaque, int pin, int level) if (level) { LOG_IRQ("%s: reset the PowerPC system\n", __func__); - ppc40x_system_reset(env); + ppc40x_system_reset(cpu); } break; case PPC40x_INPUT_RESET_CHIP: if (level) { LOG_IRQ("%s: reset the PowerPC chip\n", __func__); - ppc40x_chip_reset(env); + ppc40x_chip_reset(cpu); } break; case PPC40x_INPUT_RESET_CORE: /* XXX: TODO: update DBSR[MRR] */ if (level) { LOG_IRQ("%s: reset the PowerPC core\n", __func__); - ppc40x_core_reset(env); + ppc40x_core_reset(cpu); } break; case PPC40x_INPUT_CINT: @@ -1011,13 +1011,13 @@ static void cpu_4xx_wdt_cb (void *opaque) /* No reset */ break; case 0x1: /* Core reset */ - ppc40x_core_reset(env); + ppc40x_core_reset(cpu); break; case 0x2: /* Chip reset */ - ppc40x_chip_reset(env); + ppc40x_chip_reset(cpu); break; case 0x3: /* System reset */ - ppc40x_system_reset(env); + ppc40x_system_reset(cpu); break; } } diff --git a/hw/ppc.h b/hw/ppc.h index ee0cd16ee5..acaf0d6580 100644 --- a/hw/ppc.h +++ b/hw/ppc.h @@ -58,9 +58,9 @@ clk_setup_cb ppc_40x_timers_init (CPUPPCState *env, uint32_t freq, unsigned int decr_excp); /* Embedded PowerPC reset */ -void ppc40x_core_reset (CPUPPCState *env); -void ppc40x_chip_reset (CPUPPCState *env); -void ppc40x_system_reset (CPUPPCState *env); +void ppc40x_core_reset(PowerPCCPU *cpu); +void ppc40x_chip_reset(PowerPCCPU *cpu); +void ppc40x_system_reset(PowerPCCPU *cpu); void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val); extern CPUWriteMemoryFunc * const PPC_io_write[]; diff --git a/hw/ppc405_uc.c b/hw/ppc405_uc.c index c96d103d1c..d8cbe875bd 100644 --- a/hw/ppc405_uc.c +++ b/hw/ppc405_uc.c @@ -1770,8 +1770,9 @@ static void ppc405_mal_init(CPUPPCState *env, qemu_irq irqs[4]) /*****************************************************************************/ /* SPR */ -void ppc40x_core_reset (CPUPPCState *env) +void ppc40x_core_reset(PowerPCCPU *cpu) { + CPUPPCState *env = &cpu->env; target_ulong dbsr; printf("Reset PowerPC core\n"); @@ -1782,8 +1783,9 @@ void ppc40x_core_reset (CPUPPCState *env) env->spr[SPR_40x_DBSR] = dbsr; } -void ppc40x_chip_reset (CPUPPCState *env) +void ppc40x_chip_reset(PowerPCCPU *cpu) { + CPUPPCState *env = &cpu->env; target_ulong dbsr; printf("Reset PowerPC chip\n"); @@ -1795,7 +1797,7 @@ void ppc40x_chip_reset (CPUPPCState *env) env->spr[SPR_40x_DBSR] = dbsr; } -void ppc40x_system_reset (CPUPPCState *env) +void ppc40x_system_reset(PowerPCCPU *cpu) { printf("Reset PowerPC system\n"); qemu_system_reset_request(); @@ -1803,21 +1805,23 @@ void ppc40x_system_reset (CPUPPCState *env) void store_40x_dbcr0 (CPUPPCState *env, uint32_t val) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); + switch ((val >> 28) & 0x3) { case 0x0: /* No action */ break; case 0x1: /* Core reset */ - ppc40x_core_reset(env); + ppc40x_core_reset(cpu); break; case 0x2: /* Chip reset */ - ppc40x_chip_reset(env); + ppc40x_chip_reset(cpu); break; case 0x3: /* System reset */ - ppc40x_system_reset(env); + ppc40x_system_reset(cpu); break; } } From c7937d9f9a99d8cc2848e85f608d89c6f326daf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 18 Jan 2013 14:03:58 +0100 Subject: [PATCH 30/47] target-m68k: Return M68kCPU from cpu_m68k_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turn cpu_init() into a static inline function for backwards compatibility. Signed-off-by: Andreas Färber --- target-m68k/cpu.h | 12 ++++++++++-- target-m68k/helper.c | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index 94937c4fd7..ed9be802d4 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -117,7 +117,7 @@ typedef struct CPUM68KState { void m68k_tcg_init(void); void m68k_cpu_init_gdb(M68kCPU *cpu); -CPUM68KState *cpu_m68k_init(const char *cpu_model); +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); @@ -215,7 +215,15 @@ void register_m68k_insns (CPUM68KState *env); #define TARGET_PHYS_ADDR_SPACE_BITS 32 #define TARGET_VIRT_ADDR_SPACE_BITS 32 -#define cpu_init cpu_m68k_init +static inline CPUM68KState *cpu_init(const char *cpu_model) +{ + M68kCPU *cpu = cpu_m68k_init(cpu_model); + if (cpu == NULL) { + return NULL; + } + return &cpu->env; +} + #define cpu_exec cpu_m68k_exec #define cpu_gen_code cpu_m68k_gen_code #define cpu_signal_handler cpu_m68k_signal_handler diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 6030807753..7d3fd944be 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -98,7 +98,7 @@ static int fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n) return 0; } -CPUM68KState *cpu_m68k_init(const char *cpu_model) +M68kCPU *cpu_m68k_init(const char *cpu_model) { M68kCPU *cpu; CPUM68KState *env; @@ -116,7 +116,7 @@ CPUM68KState *cpu_m68k_init(const char *cpu_model) object_property_set_bool(OBJECT(cpu), true, "realized", NULL); - return env; + return cpu; } void m68k_cpu_init_gdb(M68kCPU *cpu) From 4025cfd5d7175203008343a375f9287c77cd383c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 18 Jan 2013 14:10:34 +0100 Subject: [PATCH 31/47] mcf5206: Pass M68kCPU to mcf5206_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Store it in m5206_mbar_state. Prepares for passing M68kCPU to m68k_set_irq_level(). Signed-off-by: Andreas Färber --- hw/an5206.c | 11 +++++++---- hw/mcf.h | 2 +- hw/mcf5206.c | 8 ++++---- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/hw/an5206.c b/hw/an5206.c index 750115a3aa..924be81d57 100644 --- a/hw/an5206.c +++ b/hw/an5206.c @@ -24,6 +24,7 @@ static void an5206_init(QEMUMachineInitArgs *args) ram_addr_t ram_size = args->ram_size; const char *cpu_model = args->cpu_model; const char *kernel_filename = args->kernel_filename; + M68kCPU *cpu; CPUM68KState *env; int kernel_size; uint64_t elf_entry; @@ -32,12 +33,14 @@ static void an5206_init(QEMUMachineInitArgs *args) MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *sram = g_new(MemoryRegion, 1); - if (!cpu_model) + if (!cpu_model) { cpu_model = "m5206"; - env = cpu_init(cpu_model); - if (!env) { + } + cpu = cpu_m68k_init(cpu_model); + if (!cpu) { hw_error("Unable to find m68k CPU definition\n"); } + env = &cpu->env; /* Initialize CPU registers. */ env->vbr = 0; @@ -55,7 +58,7 @@ static void an5206_init(QEMUMachineInitArgs *args) vmstate_register_ram_global(sram); memory_region_add_subregion(address_space_mem, AN5206_RAMBAR_ADDR, sram); - mcf5206_init(address_space_mem, AN5206_MBAR_ADDR, env); + mcf5206_init(address_space_mem, AN5206_MBAR_ADDR, cpu); /* Load kernel. */ if (!kernel_filename) { diff --git a/hw/mcf.h b/hw/mcf.h index f929910f02..dc21028cd2 100644 --- a/hw/mcf.h +++ b/hw/mcf.h @@ -25,6 +25,6 @@ void mcf_fec_init(struct MemoryRegion *sysmem, NICInfo *nd, /* mcf5206.c */ qemu_irq *mcf5206_init(struct MemoryRegion *sysmem, - uint32_t base, CPUM68KState *env); + uint32_t base, M68kCPU *cpu); #endif diff --git a/hw/mcf5206.c b/hw/mcf5206.c index d8c0059ed6..9bb393e3d4 100644 --- a/hw/mcf5206.c +++ b/hw/mcf5206.c @@ -145,7 +145,7 @@ static m5206_timer_state *m5206_timer_init(qemu_irq irq) /* System Integration Module. */ typedef struct { - CPUM68KState *env; + M68kCPU *cpu; MemoryRegion iomem; m5206_timer_state *timer[2]; void *uart[2]; @@ -226,7 +226,7 @@ static void m5206_mbar_update(m5206_mbar_state *s) level = 0; vector = 0; } - m68k_set_irq_level(s->env, level, vector); + m68k_set_irq_level(&s->cpu->env, level, vector); } static void m5206_mbar_set_irq(void *opaque, int irq, int level) @@ -525,7 +525,7 @@ static const MemoryRegionOps m5206_mbar_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -qemu_irq *mcf5206_init(MemoryRegion *sysmem, uint32_t base, CPUM68KState *env) +qemu_irq *mcf5206_init(MemoryRegion *sysmem, uint32_t base, M68kCPU *cpu) { m5206_mbar_state *s; qemu_irq *pic; @@ -541,7 +541,7 @@ qemu_irq *mcf5206_init(MemoryRegion *sysmem, uint32_t base, CPUM68KState *env) s->timer[1] = m5206_timer_init(pic[10]); s->uart[0] = mcf_uart_init(pic[12], serial_hds[0]); s->uart[1] = mcf_uart_init(pic[13], serial_hds[1]); - s->env = env; + s->cpu = cpu; m5206_mbar_reset(s); return pic; From 9a6ee9fd35483446fe14e083fa335358c86ba595 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 18 Jan 2013 14:15:09 +0100 Subject: [PATCH 32/47] mcf_intc: Pass M68kCPU to mcf_intc_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Store it in mcf_intc_state. Prepares for passing it to m68k_set_irq_level(). Signed-off-by: Andreas Färber --- hw/mcf.h | 2 +- hw/mcf5208.c | 11 +++++++---- hw/mcf_intc.c | 8 ++++---- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/hw/mcf.h b/hw/mcf.h index dc21028cd2..fbc8dc26df 100644 --- a/hw/mcf.h +++ b/hw/mcf.h @@ -17,7 +17,7 @@ void mcf_uart_mm_init(struct MemoryRegion *sysmem, /* mcf_intc.c */ qemu_irq *mcf_intc_init(struct MemoryRegion *sysmem, hwaddr base, - CPUM68KState *env); + M68kCPU *cpu); /* mcf_fec.c */ void mcf_fec_init(struct MemoryRegion *sysmem, NICInfo *nd, diff --git a/hw/mcf5208.c b/hw/mcf5208.c index 2c9a5dc98a..86402d30d5 100644 --- a/hw/mcf5208.c +++ b/hw/mcf5208.c @@ -192,6 +192,7 @@ static void mcf5208evb_init(QEMUMachineInitArgs *args) ram_addr_t ram_size = args->ram_size; const char *cpu_model = args->cpu_model; const char *kernel_filename = args->kernel_filename; + M68kCPU *cpu; CPUM68KState *env; int kernel_size; uint64_t elf_entry; @@ -201,13 +202,15 @@ static void mcf5208evb_init(QEMUMachineInitArgs *args) MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *sram = g_new(MemoryRegion, 1); - if (!cpu_model) + if (!cpu_model) { cpu_model = "m5208"; - env = cpu_init(cpu_model); - if (!env) { + } + cpu = cpu_m68k_init(cpu_model); + if (!cpu) { fprintf(stderr, "Unable to find m68k CPU definition\n"); exit(1); } + env = &cpu->env; /* Initialize CPU registers. */ env->vbr = 0; @@ -224,7 +227,7 @@ static void mcf5208evb_init(QEMUMachineInitArgs *args) memory_region_add_subregion(address_space_mem, 0x80000000, sram); /* Internal peripherals. */ - pic = mcf_intc_init(address_space_mem, 0xfc048000, env); + pic = mcf_intc_init(address_space_mem, 0xfc048000, cpu); mcf_uart_mm_init(address_space_mem, 0xfc060000, pic[26], serial_hds[0]); mcf_uart_mm_init(address_space_mem, 0xfc064000, pic[27], serial_hds[1]); diff --git a/hw/mcf_intc.c b/hw/mcf_intc.c index 3bed3a2e4c..450f622e9d 100644 --- a/hw/mcf_intc.c +++ b/hw/mcf_intc.c @@ -16,7 +16,7 @@ typedef struct { uint64_t ifr; uint64_t enabled; uint8_t icr[64]; - CPUM68KState *env; + M68kCPU *cpu; int active_vector; } mcf_intc_state; @@ -40,7 +40,7 @@ static void mcf_intc_update(mcf_intc_state *s) } } s->active_vector = ((best == 64) ? 24 : (best + 64)); - m68k_set_irq_level(s->env, best_level, s->active_vector); + m68k_set_irq_level(&s->cpu->env, best_level, s->active_vector); } static uint64_t mcf_intc_read(void *opaque, hwaddr addr, @@ -139,12 +139,12 @@ static const MemoryRegionOps mcf_intc_ops = { qemu_irq *mcf_intc_init(MemoryRegion *sysmem, hwaddr base, - CPUM68KState *env) + M68kCPU *cpu) { mcf_intc_state *s; s = g_malloc0(sizeof(mcf_intc_state)); - s->env = env; + s->cpu = cpu; mcf_intc_reset(s); memory_region_init_io(&s->iomem, &mcf_intc_ops, s, "mcf", 0x100); From cb3fb38e91caacfcb0f86e8c587ed74ffa34fe8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 18 Jan 2013 14:20:52 +0100 Subject: [PATCH 33/47] target-m68k: Pass M68kCPU to m68k_set_irq_level() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplifies use of cpu_reset_interrupt() et al. Signed-off-by: Andreas Färber --- hw/mcf5206.c | 2 +- hw/mcf_intc.c | 2 +- target-m68k/cpu.h | 2 +- target-m68k/helper.c | 4 +++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/hw/mcf5206.c b/hw/mcf5206.c index 9bb393e3d4..ea2db2325a 100644 --- a/hw/mcf5206.c +++ b/hw/mcf5206.c @@ -226,7 +226,7 @@ static void m5206_mbar_update(m5206_mbar_state *s) level = 0; vector = 0; } - m68k_set_irq_level(&s->cpu->env, level, vector); + m68k_set_irq_level(s->cpu, level, vector); } static void m5206_mbar_set_irq(void *opaque, int irq, int level) diff --git a/hw/mcf_intc.c b/hw/mcf_intc.c index 450f622e9d..b213656300 100644 --- a/hw/mcf_intc.c +++ b/hw/mcf_intc.c @@ -40,7 +40,7 @@ static void mcf_intc_update(mcf_intc_state *s) } } s->active_vector = ((best == 64) ? 24 : (best + 64)); - m68k_set_irq_level(&s->cpu->env, best_level, s->active_vector); + m68k_set_irq_level(s->cpu, best_level, s->active_vector); } static uint64_t mcf_intc_read(void *opaque, hwaddr addr, diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index ed9be802d4..2672eae7c8 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -169,7 +169,7 @@ enum { #define MACSR_V 0x002 #define MACSR_EV 0x001 -void m68k_set_irq_level(CPUM68KState *env, int level, uint8_t vector); +void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector); void m68k_set_macsr(CPUM68KState *env, uint32_t val); void m68k_switch_sp(CPUM68KState *env); diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 7d3fd944be..1bae3ab326 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -310,8 +310,10 @@ int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw, be handled by the interrupt controller. Real hardware only requests the vector when the interrupt is acknowledged by the CPU. For simplicitly we calculate it when the interrupt is signalled. */ -void m68k_set_irq_level(CPUM68KState *env, int level, uint8_t vector) +void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector) { + CPUM68KState *env = &cpu->env; + env->pending_level = level; env->pending_vector = vector; if (level) From 6ae064fc671f1c475b1371c067fa3100ec6daf80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Wed, 6 Feb 2013 17:18:12 +0100 Subject: [PATCH 34/47] target-cris: Introduce CRISCPU subclasses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use class_init functions to initialize the VR in preparation for overriding v32+ behavior there. Move cpu_cris_init() to cpu.c and hook up a class_by_name callback. This change leads to unknown -cpu model names no longer falling back to a CPU with VR 32 but instead returning NULL. Acked-by: Edgar E. Iglesias Signed-off-by: Andreas Färber --- target-cris/cpu-qom.h | 3 + target-cris/cpu.c | 153 +++++++++++++++++++++++++++++++++++++++- target-cris/translate.c | 48 ------------- 3 files changed, 155 insertions(+), 49 deletions(-) diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h index 7ad8398760..2bac71fd81 100644 --- a/target-cris/cpu-qom.h +++ b/target-cris/cpu-qom.h @@ -35,6 +35,7 @@ * CRISCPUClass: * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. + * @vr: Version Register value. * * A CRIS CPU model. */ @@ -45,6 +46,8 @@ typedef struct CRISCPUClass { DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); + + uint32_t vr; } CRISCPUClass; /** diff --git a/target-cris/cpu.c b/target-cris/cpu.c index fedf64191d..80089884e9 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -55,6 +55,84 @@ static void cris_cpu_reset(CPUState *s) #endif } +static ObjectClass *cris_cpu_class_by_name(const char *cpu_model) +{ + ObjectClass *oc; + char *typename; + + if (cpu_model == NULL) { + return NULL; + } + + typename = g_strdup_printf("%s-" TYPE_CRIS_CPU, cpu_model); + oc = object_class_by_name(typename); + g_free(typename); + if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_CRIS_CPU) || + object_class_is_abstract(oc))) { + oc = NULL; + } + return oc; +} + +CRISCPU *cpu_cris_init(const char *cpu_model) +{ + CRISCPU *cpu; + ObjectClass *oc; + + oc = cris_cpu_class_by_name(cpu_model); + if (oc == NULL) { + return NULL; + } + cpu = CRIS_CPU(object_new(object_class_get_name(oc))); + + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); + + return cpu; +} + +/* Sort alphabetically by VR. */ +static gint cris_cpu_list_compare(gconstpointer a, gconstpointer b) +{ + CRISCPUClass *ccc_a = CRIS_CPU_CLASS(a); + CRISCPUClass *ccc_b = CRIS_CPU_CLASS(b); + + /* */ + if (ccc_a->vr > ccc_b->vr) { + return 1; + } else if (ccc_a->vr < ccc_b->vr) { + return -1; + } else { + return 0; + } +} + +static void cris_cpu_list_entry(gpointer data, gpointer user_data) +{ + ObjectClass *oc = data; + CPUListState *s = user_data; + const char *typename = object_class_get_name(oc); + char *name; + + name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_CRIS_CPU)); + (*s->cpu_fprintf)(s->file, " %s\n", name); + g_free(name); +} + +void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf) +{ + CPUListState s = { + .file = f, + .cpu_fprintf = cpu_fprintf, + }; + GSList *list; + + list = object_class_get_list(TYPE_CRIS_CPU, false); + list = g_slist_sort(list, cris_cpu_list_compare); + (*cpu_fprintf)(f, "Available CPUs:\n"); + g_slist_foreach(list, cris_cpu_list_entry, &s); + g_slist_free(list); +} + static void cris_cpu_realizefn(DeviceState *dev, Error **errp) { CRISCPU *cpu = CRIS_CPU(dev); @@ -69,11 +147,14 @@ static void cris_cpu_realizefn(DeviceState *dev, Error **errp) static void cris_cpu_initfn(Object *obj) { CRISCPU *cpu = CRIS_CPU(obj); + CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(obj); CPUCRISState *env = &cpu->env; static bool tcg_initialized; cpu_exec_init(env); + env->pregs[PR_VR] = ccc->vr; + if (tcg_enabled() && !tcg_initialized) { tcg_initialized = true; if (env->pregs[PR_VR] < 32) { @@ -84,6 +165,69 @@ static void cris_cpu_initfn(Object *obj) } } +static void crisv8_cpu_class_init(ObjectClass *oc, void *data) +{ + CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); + + ccc->vr = 8; +} + +static void crisv9_cpu_class_init(ObjectClass *oc, void *data) +{ + CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); + + ccc->vr = 9; +} + +static void crisv10_cpu_class_init(ObjectClass *oc, void *data) +{ + CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); + + ccc->vr = 10; +} + +static void crisv11_cpu_class_init(ObjectClass *oc, void *data) +{ + CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); + + ccc->vr = 11; +} + +static void crisv32_cpu_class_init(ObjectClass *oc, void *data) +{ + CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); + + ccc->vr = 32; +} + +#define TYPE(model) model "-" TYPE_CRIS_CPU + +static const TypeInfo cris_cpu_model_type_infos[] = { + { + .name = TYPE("crisv8"), + .parent = TYPE_CRIS_CPU, + .class_init = crisv8_cpu_class_init, + }, { + .name = TYPE("crisv9"), + .parent = TYPE_CRIS_CPU, + .class_init = crisv9_cpu_class_init, + }, { + .name = TYPE("crisv10"), + .parent = TYPE_CRIS_CPU, + .class_init = crisv10_cpu_class_init, + }, { + .name = TYPE("crisv11"), + .parent = TYPE_CRIS_CPU, + .class_init = crisv11_cpu_class_init, + }, { + .name = TYPE("crisv32"), + .parent = TYPE_CRIS_CPU, + .class_init = crisv32_cpu_class_init, + } +}; + +#undef TYPE + static void cris_cpu_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -95,6 +239,8 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data) ccc->parent_reset = cc->reset; cc->reset = cris_cpu_reset; + + cc->class_by_name = cris_cpu_class_by_name; } static const TypeInfo cris_cpu_type_info = { @@ -102,14 +248,19 @@ static const TypeInfo cris_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(CRISCPU), .instance_init = cris_cpu_initfn, - .abstract = false, + .abstract = true, .class_size = sizeof(CRISCPUClass), .class_init = cris_cpu_class_init, }; static void cris_cpu_register_types(void) { + int i; + type_register_static(&cris_cpu_type_info); + for (i = 0; i < ARRAY_SIZE(cris_cpu_model_type_infos); i++) { + type_register_static(&cris_cpu_model_type_infos[i]); + } } type_init(cris_cpu_register_types) diff --git a/target-cris/translate.c b/target-cris/translate.c index 25a43faf35..04a5379775 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -3513,54 +3513,6 @@ void cpu_dump_state (CPUCRISState *env, FILE *f, fprintf_function cpu_fprintf, } -struct -{ - uint32_t vr; - const char *name; -} cris_cores[] = { - {8, "crisv8"}, - {9, "crisv9"}, - {10, "crisv10"}, - {11, "crisv11"}, - {32, "crisv32"}, -}; - -void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf) -{ - unsigned int i; - - (*cpu_fprintf)(f, "Available CPUs:\n"); - for (i = 0; i < ARRAY_SIZE(cris_cores); i++) { - (*cpu_fprintf)(f, " %s\n", cris_cores[i].name); - } -} - -static uint32_t vr_by_name(const char *name) -{ - unsigned int i; - for (i = 0; i < ARRAY_SIZE(cris_cores); i++) { - if (strcmp(name, cris_cores[i].name) == 0) { - return cris_cores[i].vr; - } - } - return 32; -} - -CRISCPU *cpu_cris_init(const char *cpu_model) -{ - CRISCPU *cpu; - CPUCRISState *env; - - cpu = CRIS_CPU(object_new(TYPE_CRIS_CPU)); - env = &cpu->env; - - env->pregs[PR_VR] = vr_by_name(cpu_model); - - object_property_set_bool(OBJECT(cpu), true, "realized", NULL); - - return cpu; -} - void cris_initialize_tcg(void) { int i; From 0d34282fdde1d8f337d2a9e10f5ac793b12ef2e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Mon, 17 Dec 2012 07:12:13 +0100 Subject: [PATCH 35/47] cpu: Move host_tid field to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change gdbstub's cpu_index() argument to CPUState now that CPUArchState is no longer used. Signed-off-by: Andreas Färber --- dump.c | 8 ++++++-- gdbstub.c | 14 +++++++++----- include/exec/cpu-defs.h | 1 - include/exec/gdbstub.h | 5 ++--- include/qom/cpu.h | 2 ++ linux-user/syscall.c | 4 +++- 6 files changed, 22 insertions(+), 12 deletions(-) diff --git a/dump.c b/dump.c index 4ed1fa8622..a25f5096eb 100644 --- a/dump.c +++ b/dump.c @@ -271,11 +271,13 @@ static int write_elf64_note(DumpState *s) static int write_elf64_notes(DumpState *s) { CPUArchState *env; + CPUState *cpu; int ret; int id; for (env = first_cpu; env != NULL; env = env->next_cpu) { - id = cpu_index(env); + cpu = ENV_GET_CPU(env); + id = cpu_index(cpu); ret = cpu_write_elf64_note(fd_write_vmcore, env, id, s); if (ret < 0) { dump_error(s, "dump: failed to write elf notes.\n"); @@ -321,11 +323,13 @@ static int write_elf32_note(DumpState *s) static int write_elf32_notes(DumpState *s) { CPUArchState *env; + CPUState *cpu; int ret; int id; for (env = first_cpu; env != NULL; env = env->next_cpu) { - id = cpu_index(env); + cpu = ENV_GET_CPU(env); + id = cpu_index(cpu); ret = cpu_write_elf32_note(fd_write_vmcore, env, id, s); if (ret < 0) { dump_error(s, "dump: failed to write elf notes.\n"); diff --git a/gdbstub.c b/gdbstub.c index 6cd26f1619..32dfea9ed0 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2066,9 +2066,11 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) static CPUArchState *find_cpu(uint32_t thread_id) { CPUArchState *env; + CPUState *cpu; for (env = first_cpu; env != NULL; env = env->next_cpu) { - if (cpu_index(env) == thread_id) { + cpu = ENV_GET_CPU(env); + if (cpu_index(cpu) == thread_id) { return env; } } @@ -2096,7 +2098,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) case '?': /* TODO: Make this return the correct value for user-mode. */ snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP, - cpu_index(s->c_cpu)); + cpu_index(ENV_GET_CPU(s->c_cpu))); put_packet(s, buf); /* Remove all the breakpoints when this query is issued, * because gdb is doing and initial connect and the state @@ -2391,7 +2393,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) } else if (strcmp(p,"sThreadInfo") == 0) { report_cpuinfo: if (s->query_cpu) { - snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu)); + snprintf(buf, sizeof(buf), "m%x", + cpu_index(ENV_GET_CPU(s->query_cpu))); put_packet(s, buf); s->query_cpu = s->query_cpu->next_cpu; } else @@ -2512,6 +2515,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state) { GDBState *s = gdbserver_state; CPUArchState *env = s->c_cpu; + CPUState *cpu = ENV_GET_CPU(env); char buf[256]; const char *type; int ret; @@ -2540,7 +2544,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state) } snprintf(buf, sizeof(buf), "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";", - GDB_SIGNAL_TRAP, cpu_index(env), type, + GDB_SIGNAL_TRAP, cpu_index(cpu), type, env->watchpoint_hit->vaddr); env->watchpoint_hit = NULL; goto send_packet; @@ -2573,7 +2577,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state) ret = GDB_SIGNAL_UNKNOWN; break; } - snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_index(env)); + snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_index(cpu)); send_packet: put_packet(s, buf); diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 2911b9fc90..ae832a9f83 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -191,7 +191,6 @@ typedef struct CPUWatchpoint { int exception_index; \ \ CPUArchState *next_cpu; /* next CPU sharing TB cache */ \ - uint32_t host_tid; /* host thread ID */ \ int running; /* Nonzero if cpu is currently running(usermode). */ \ /* user data */ \ void *opaque; \ diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index 49231feb29..ba20afa091 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -30,12 +30,11 @@ void gdb_register_coprocessor(CPUArchState *env, gdb_reg_cb get_reg, gdb_reg_cb set_reg, int num_regs, const char *xml, int g_pos); -static inline int cpu_index(CPUArchState *env) +static inline int cpu_index(CPUState *cpu) { #if defined(CONFIG_USER_ONLY) && defined(CONFIG_USE_NPTL) - return env->host_tid; + return cpu->host_tid; #else - CPUState *cpu = ENV_GET_CPU(env); return cpu->cpu_index + 1; #endif } diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 46f2247274..e371655d15 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -65,6 +65,7 @@ struct kvm_run; * @nr_cores: Number of cores within this CPU package. * @nr_threads: Number of threads within this CPU. * @numa_node: NUMA node this CPU is belonging to. + * @host_tid: Host thread ID. * @created: Indicates whether the CPU thread has been successfully created. * @stop: Indicates a pending stop request. * @stopped: Indicates the CPU has been artificially stopped. @@ -86,6 +87,7 @@ struct CPUState { HANDLE hThread; #endif int thread_id; + uint32_t host_tid; struct QemuCond *halt_cond; struct qemu_work_item *queued_work_first, *queued_work_last; bool thread_kicked; diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 9e31ea7200..19630eaf20 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4312,13 +4312,15 @@ static void *clone_func(void *arg) { new_thread_info *info = arg; CPUArchState *env; + CPUState *cpu; TaskState *ts; env = info->env; + cpu = ENV_GET_CPU(env); thread_env = env; ts = (TaskState *)thread_env->opaque; info->tid = gettid(); - env->host_tid = info->tid; + cpu->host_tid = info->tid; task_settid(ts); if (info->child_tidptr) put_user_u32(info->tid, info->child_tidptr); From 0315c31cda054775585b31f8cb3c9228cc6fc28b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Mon, 17 Dec 2012 07:34:52 +0100 Subject: [PATCH 36/47] cpu: Move running field to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass CPUState to cpu_exec_{start,end}() functions. Signed-off-by: Andreas Färber --- include/exec/cpu-defs.h | 1 - include/qom/cpu.h | 2 ++ linux-user/main.c | 37 ++++++++++++++++++++++--------------- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index ae832a9f83..ba814ff10d 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -191,7 +191,6 @@ typedef struct CPUWatchpoint { int exception_index; \ \ CPUArchState *next_cpu; /* next CPU sharing TB cache */ \ - int running; /* Nonzero if cpu is currently running(usermode). */ \ /* user data */ \ void *opaque; \ \ diff --git a/include/qom/cpu.h b/include/qom/cpu.h index e371655d15..c465d88260 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -66,6 +66,7 @@ struct kvm_run; * @nr_threads: Number of threads within this CPU. * @numa_node: NUMA node this CPU is belonging to. * @host_tid: Host thread ID. + * @running: #true if CPU is currently running (usermode). * @created: Indicates whether the CPU thread has been successfully created. * @stop: Indicates a pending stop request. * @stopped: Indicates the CPU has been artificially stopped. @@ -88,6 +89,7 @@ struct CPUState { #endif int thread_id; uint32_t host_tid; + bool running; struct QemuCond *halt_cond; struct qemu_work_item *queued_work_first, *queued_work_last; bool thread_kicked; diff --git a/linux-user/main.c b/linux-user/main.c index 146a4683a5..e51568430f 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -151,13 +151,16 @@ static inline void exclusive_idle(void) static inline void start_exclusive(void) { CPUArchState *other; + CPUState *other_cpu; + pthread_mutex_lock(&exclusive_lock); exclusive_idle(); pending_cpus = 1; /* Make all other cpus stop executing. */ for (other = first_cpu; other; other = other->next_cpu) { - if (other->running) { + other_cpu = ENV_GET_CPU(other); + if (other_cpu->running) { pending_cpus++; cpu_exit(other); } @@ -176,19 +179,19 @@ static inline void end_exclusive(void) } /* Wait for exclusive ops to finish, and begin cpu execution. */ -static inline void cpu_exec_start(CPUArchState *env) +static inline void cpu_exec_start(CPUState *cpu) { pthread_mutex_lock(&exclusive_lock); exclusive_idle(); - env->running = 1; + cpu->running = true; pthread_mutex_unlock(&exclusive_lock); } /* Mark cpu as not executing, and release pending exclusive ops. */ -static inline void cpu_exec_end(CPUArchState *env) +static inline void cpu_exec_end(CPUState *cpu) { pthread_mutex_lock(&exclusive_lock); - env->running = 0; + cpu->running = false; if (pending_cpus > 1) { pending_cpus--; if (pending_cpus == 1) { @@ -210,11 +213,11 @@ void cpu_list_unlock(void) } #else /* if !CONFIG_USE_NPTL */ /* These are no-ops because we are not threadsafe. */ -static inline void cpu_exec_start(CPUArchState *env) +static inline void cpu_exec_start(CPUState *cpu) { } -static inline void cpu_exec_end(CPUArchState *env) +static inline void cpu_exec_end(CPUState *cpu) { } @@ -697,15 +700,16 @@ done: void cpu_loop(CPUARMState *env) { + CPUState *cs = CPU(arm_env_get_cpu(env)); int trapnr; unsigned int n, insn; target_siginfo_t info; uint32_t addr; for(;;) { - cpu_exec_start(env); + cpu_exec_start(cs); trapnr = cpu_arm_exec(env); - cpu_exec_end(env); + cpu_exec_end(cs); switch(trapnr) { case EXCP_UDEF: { @@ -912,14 +916,15 @@ void cpu_loop(CPUARMState *env) void cpu_loop(CPUUniCore32State *env) { + CPUState *cs = CPU(uc32_env_get_cpu(env)); int trapnr; unsigned int n, insn; target_siginfo_t info; for (;;) { - cpu_exec_start(env); + cpu_exec_start(cs); trapnr = uc32_cpu_exec(env); - cpu_exec_end(env); + cpu_exec_end(cs); switch (trapnr) { case UC32_EXCP_PRIV: { @@ -1367,14 +1372,15 @@ static int do_store_exclusive(CPUPPCState *env) void cpu_loop(CPUPPCState *env) { + CPUState *cs = CPU(ppc_env_get_cpu(env)); target_siginfo_t info; int trapnr; target_ulong ret; for(;;) { - cpu_exec_start(env); + cpu_exec_start(cs); trapnr = cpu_ppc_exec(env); - cpu_exec_end(env); + cpu_exec_end(cs); switch(trapnr) { case POWERPC_EXCP_NONE: /* Just go on */ @@ -2184,14 +2190,15 @@ static int do_store_exclusive(CPUMIPSState *env) void cpu_loop(CPUMIPSState *env) { + CPUState *cs = CPU(mips_env_get_cpu(env)); target_siginfo_t info; int trapnr, ret; unsigned int syscall_num; for(;;) { - cpu_exec_start(env); + cpu_exec_start(cs); trapnr = cpu_mips_exec(env); - cpu_exec_end(env); + cpu_exec_end(cs); switch(trapnr) { case EXCP_SYSCALL: syscall_num = env->active_tc.gpr[2] - 4000; From fcd7d0034b7eddba505a548f456f452bf5a7d56c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Mon, 17 Dec 2012 08:02:44 +0100 Subject: [PATCH 37/47] cpu: Move exit_request field to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since it was located before breakpoints field, it needs to be reset. Signed-off-by: Andreas Färber --- cpu-exec.c | 8 ++++---- exec.c | 4 +++- hw/spapr_hcall.c | 5 +++-- include/exec/cpu-defs.h | 2 -- include/qom/cpu.h | 2 ++ kvm-all.c | 6 +++--- qom/cpu.c | 1 + target-i386/kvm.c | 4 ++-- 8 files changed, 18 insertions(+), 14 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index ff9a884a96..cf103f227b 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -196,7 +196,7 @@ int cpu_exec(CPUArchState *env) cpu_single_env = env; if (unlikely(exit_request)) { - env->exit_request = 1; + cpu->exit_request = 1; } #if defined(TARGET_I386) @@ -537,8 +537,8 @@ int cpu_exec(CPUArchState *env) next_tb = 0; } } - if (unlikely(env->exit_request)) { - env->exit_request = 0; + if (unlikely(cpu->exit_request)) { + cpu->exit_request = 0; env->exception_index = EXCP_INTERRUPT; cpu_loop_exit(env); } @@ -591,7 +591,7 @@ int cpu_exec(CPUArchState *env) starting execution if there is a pending interrupt. */ env->current_tb = tb; barrier(); - if (likely(!env->exit_request)) { + if (likely(!cpu->exit_request)) { tc_ptr = tb->tc_ptr; /* execute the generated code */ next_tb = tcg_qemu_tb_exec(env, tc_ptr); diff --git a/exec.c b/exec.c index b85508ba30..dbb893a08e 100644 --- a/exec.c +++ b/exec.c @@ -492,7 +492,9 @@ void cpu_reset_interrupt(CPUArchState *env, int mask) void cpu_exit(CPUArchState *env) { - env->exit_request = 1; + CPUState *cpu = ENV_GET_CPU(env); + + cpu->exit_request = 1; cpu_unlink_tb(env); } diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c index 2889742788..af1db6ea08 100644 --- a/hw/spapr_hcall.c +++ b/hw/spapr_hcall.c @@ -513,13 +513,14 @@ static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr, target_ulong opcode, target_ulong *args) { CPUPPCState *env = &cpu->env; + CPUState *cs = CPU(cpu); env->msr |= (1ULL << MSR_EE); hreg_compute_hflags(env); - if (!cpu_has_work(CPU(cpu))) { + if (!cpu_has_work(cs)) { env->halted = 1; env->exception_index = EXCP_HLT; - env->exit_request = 1; + cs->exit_request = 1; } return H_SUCCESS; } diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index ba814ff10d..ca39f05567 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -26,7 +26,6 @@ #include "config.h" #include #include -#include #include "qemu/osdep.h" #include "qemu/queue.h" #include "exec/hwaddr.h" @@ -160,7 +159,6 @@ typedef struct CPUWatchpoint { memory was accessed */ \ uint32_t halted; /* Nonzero if the CPU is in suspend state */ \ uint32_t interrupt_request; \ - volatile sig_atomic_t exit_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 c465d88260..42f3f34bbd 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -20,6 +20,7 @@ #ifndef QEMU_CPU_H #define QEMU_CPU_H +#include #include "hw/qdev-core.h" #include "qemu/thread.h" @@ -96,6 +97,7 @@ struct CPUState { bool created; bool stop; bool stopped; + volatile sig_atomic_t exit_request; int kvm_fd; bool kvm_vcpu_dirty; diff --git a/kvm-all.c b/kvm-all.c index 04ec2d541a..4decfdccd3 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1537,7 +1537,7 @@ int kvm_cpu_exec(CPUArchState *env) DPRINTF("kvm_cpu_exec()\n"); if (kvm_arch_process_async_events(cpu)) { - env->exit_request = 0; + cpu->exit_request = 0; return EXCP_HLT; } @@ -1548,7 +1548,7 @@ int kvm_cpu_exec(CPUArchState *env) } kvm_arch_pre_run(cpu, run); - if (env->exit_request) { + if (cpu->exit_request) { DPRINTF("interrupt exit requested\n"); /* * KVM requires us to reenter the kernel after IO exits to complete @@ -1622,7 +1622,7 @@ int kvm_cpu_exec(CPUArchState *env) vm_stop(RUN_STATE_INTERNAL_ERROR); } - env->exit_request = 0; + cpu->exit_request = 0; return ret; } diff --git a/qom/cpu.c b/qom/cpu.c index 870e9baad9..7d8c675dd0 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -32,6 +32,7 @@ void cpu_reset(CPUState *cpu) static void cpu_common_reset(CPUState *cpu) { + cpu->exit_request = 0; } ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 9ebf1816d9..0cf413dbfd 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1777,7 +1777,7 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run) * or pending TPR access reports. */ if (env->interrupt_request & (CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) { - env->exit_request = 1; + cpu->exit_request = 1; } /* Try to inject an interrupt if the guest can accept it */ @@ -1847,7 +1847,7 @@ int kvm_arch_process_async_events(CPUState *cs) if (env->exception_injected == EXCP08_DBLE) { /* this means triple fault */ qemu_system_reset_request(); - env->exit_request = 1; + cs->exit_request = 1; return 0; } env->exception_injected = EXCP12_MCHK; From d77953b94ff20868b21796ee22ca57baa1cfc941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Wed, 16 Jan 2013 19:29:31 +0100 Subject: [PATCH 38/47] cpu: Move current_tb field to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Explictly NULL it on CPU reset since it was located before breakpoints. Change vapic_report_tpr_access() argument to CPUState. This also resolves the use of void* for cpu.h independence. Change vAPIC patch_instruction() argument to X86CPU. Signed-off-by: Andreas Färber --- cpu-exec.c | 13 ++++++++----- cputlb.c | 6 ++++-- hw/apic_common.c | 2 +- hw/apic_internal.h | 2 +- hw/kvmvapic.c | 13 ++++++++----- include/exec/cpu-defs.h | 1 - include/exec/exec-all.h | 4 +++- include/qom/cpu.h | 3 +++ qom/cpu.c | 1 + translate-all.c | 29 +++++++++++++++++++---------- 10 files changed, 48 insertions(+), 26 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index cf103f227b..9fcfe9e0db 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -32,7 +32,9 @@ bool qemu_cpu_has_work(CPUState *cpu) void cpu_loop_exit(CPUArchState *env) { - env->current_tb = NULL; + CPUState *cpu = ENV_GET_CPU(env); + + cpu->current_tb = NULL; longjmp(env->jmp_env, 1); } @@ -54,6 +56,7 @@ void cpu_resume_from_signal(CPUArchState *env, void *puc) static void cpu_exec_nocache(CPUArchState *env, int max_cycles, TranslationBlock *orig_tb) { + CPUState *cpu = ENV_GET_CPU(env); tcg_target_ulong next_tb; TranslationBlock *tb; @@ -64,10 +67,10 @@ static void cpu_exec_nocache(CPUArchState *env, int max_cycles, tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags, max_cycles); - env->current_tb = tb; + cpu->current_tb = tb; /* execute the generated code */ next_tb = tcg_qemu_tb_exec(env, tb->tc_ptr); - env->current_tb = NULL; + cpu->current_tb = NULL; if ((next_tb & 3) == 2) { /* Restore PC. This may happen if async event occurs before @@ -589,7 +592,7 @@ int cpu_exec(CPUArchState *env) TB, but before it is linked into a potentially infinite loop and becomes env->current_tb. Avoid starting execution if there is a pending interrupt. */ - env->current_tb = tb; + cpu->current_tb = tb; barrier(); if (likely(!cpu->exit_request)) { tc_ptr = tb->tc_ptr; @@ -623,7 +626,7 @@ int cpu_exec(CPUArchState *env) } } } - env->current_tb = NULL; + cpu->current_tb = NULL; /* reset soft MMU for next block (it can currently only be set by a memory fault) */ } /* for(;;) */ diff --git a/cputlb.c b/cputlb.c index 88239c494a..aba7e44e1e 100644 --- a/cputlb.c +++ b/cputlb.c @@ -54,6 +54,7 @@ static const CPUTLBEntry s_cputlb_empty_entry = { */ void tlb_flush(CPUArchState *env, int flush_global) { + CPUState *cpu = ENV_GET_CPU(env); int i; #if defined(DEBUG_TLB) @@ -61,7 +62,7 @@ void tlb_flush(CPUArchState *env, int flush_global) #endif /* must reset current TB so that interrupts cannot modify the links while we are modifying them */ - env->current_tb = NULL; + cpu->current_tb = NULL; for (i = 0; i < CPU_TLB_SIZE; i++) { int mmu_idx; @@ -92,6 +93,7 @@ static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr) void tlb_flush_page(CPUArchState *env, target_ulong addr) { + CPUState *cpu = ENV_GET_CPU(env); int i; int mmu_idx; @@ -110,7 +112,7 @@ void tlb_flush_page(CPUArchState *env, target_ulong addr) } /* must reset current TB so that interrupts cannot modify the links while we are modifying them */ - env->current_tb = NULL; + cpu->current_tb = NULL; addr &= TARGET_PAGE_MASK; i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); diff --git a/hw/apic_common.c b/hw/apic_common.c index 6e1b1e0320..d8c9810509 100644 --- a/hw/apic_common.c +++ b/hw/apic_common.c @@ -103,7 +103,7 @@ void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip, { APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); - vapic_report_tpr_access(s->vapic, &s->cpu->env, ip, access); + vapic_report_tpr_access(s->vapic, CPU(s->cpu), ip, access); } void apic_report_irq_delivered(int delivered) diff --git a/hw/apic_internal.h b/hw/apic_internal.h index dcbbfd41cb..9265e52cd6 100644 --- a/hw/apic_internal.h +++ b/hw/apic_internal.h @@ -143,7 +143,7 @@ bool apic_next_timer(APICCommonState *s, int64_t current_time); void apic_enable_tpr_access_reporting(DeviceState *d, bool enable); void apic_enable_vapic(DeviceState *d, hwaddr paddr); -void vapic_report_tpr_access(DeviceState *dev, void *cpu, target_ulong ip, +void vapic_report_tpr_access(DeviceState *dev, CPUState *cpu, target_ulong ip, TPRAccess access); #endif /* !QEMU_APIC_INTERNAL_H */ diff --git a/hw/kvmvapic.c b/hw/kvmvapic.c index 1b5f416a78..9265baf568 100644 --- a/hw/kvmvapic.c +++ b/hw/kvmvapic.c @@ -382,8 +382,10 @@ static void patch_call(VAPICROMState *s, CPUX86State *env, target_ulong ip, cpu_memory_rw_debug(env, ip + 1, (void *)&offset, sizeof(offset), 1); } -static void patch_instruction(VAPICROMState *s, CPUX86State *env, target_ulong ip) +static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip) { + CPUState *cs = CPU(cpu); + CPUX86State *env = &cpu->env; VAPICHandlers *handlers; uint8_t opcode[2]; uint32_t imm32; @@ -439,17 +441,18 @@ static void patch_instruction(VAPICROMState *s, CPUX86State *env, target_ulong i resume_all_vcpus(); if (!kvm_enabled()) { - env->current_tb = NULL; + cs->current_tb = NULL; tb_gen_code(env, current_pc, current_cs_base, current_flags, 1); cpu_resume_from_signal(env, NULL); } } -void vapic_report_tpr_access(DeviceState *dev, void *cpu, target_ulong ip, +void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip, TPRAccess access) { VAPICROMState *s = DO_UPCAST(VAPICROMState, busdev.qdev, dev); - CPUX86State *env = cpu; + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; cpu_synchronize_state(env); @@ -465,7 +468,7 @@ void vapic_report_tpr_access(DeviceState *dev, void *cpu, target_ulong ip, if (vapic_enable(s, env) < 0) { return; } - patch_instruction(s, env, ip); + patch_instruction(s, cpu, ip); } typedef struct VAPICEnableTPRReporting { diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index ca39f05567..ae64590cdf 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -148,7 +148,6 @@ typedef struct CPUWatchpoint { #define CPU_TEMP_BUF_NLONGS 128 #define CPU_COMMON \ - struct TranslationBlock *current_tb; /* currently executing TB */ \ /* soft mmu support */ \ /* in order to avoid passing too many arguments to the MMIO \ helpers, we store some rarely used information in the CPU \ diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index f685c28573..e856191e40 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -404,11 +404,13 @@ extern volatile sig_atomic_t exit_request; instruction of a TB so that interrupts take effect immediately. */ static inline int can_do_io(CPUArchState *env) { + CPUState *cpu = ENV_GET_CPU(env); + if (!use_icount) { return 1; } /* If not executing code then assume we are ok. */ - if (!env->current_tb) { + if (cpu->current_tb == NULL) { return 1; } return env->can_do_io != 0; diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 42f3f34bbd..c25a997808 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -71,6 +71,7 @@ struct kvm_run; * @created: Indicates whether the CPU thread has been successfully created. * @stop: Indicates a pending stop request. * @stopped: Indicates the CPU has been artificially stopped. + * @current_tb: Currently executing TB. * @kvm_fd: vCPU file descriptor for KVM. * * State of one CPU core or thread. @@ -99,6 +100,8 @@ struct CPUState { bool stopped; volatile sig_atomic_t exit_request; + struct TranslationBlock *current_tb; + int kvm_fd; bool kvm_vcpu_dirty; struct KVMState *kvm_state; diff --git a/qom/cpu.c b/qom/cpu.c index 7d8c675dd0..0a2194d413 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -33,6 +33,7 @@ void cpu_reset(CPUState *cpu) static void cpu_common_reset(CPUState *cpu) { cpu->exit_request = 0; + cpu->current_tb = NULL; } ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model) diff --git a/translate-all.c b/translate-all.c index efeb247add..52128aa0c4 100644 --- a/translate-all.c +++ b/translate-all.c @@ -998,6 +998,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, { TranslationBlock *tb, *tb_next, *saved_tb; CPUArchState *env = cpu_single_env; + CPUState *cpu = NULL; tb_page_addr_t tb_start, tb_end; PageDesc *p; int n; @@ -1020,6 +1021,9 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, /* build code bitmap */ build_page_bitmap(p); } + if (env != NULL) { + cpu = ENV_GET_CPU(env); + } /* we remove all the TBs in the range [start, end[ */ /* XXX: see if in some cases it could be faster to invalidate all @@ -1066,14 +1070,14 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, /* we need to do that to handle the case where a signal occurs while doing tb_phys_invalidate() */ saved_tb = NULL; - if (env) { - saved_tb = env->current_tb; - env->current_tb = NULL; + if (cpu != NULL) { + saved_tb = cpu->current_tb; + cpu->current_tb = NULL; } tb_phys_invalidate(tb, -1); - if (env) { - env->current_tb = saved_tb; - if (env->interrupt_request && env->current_tb) { + if (cpu != NULL) { + cpu->current_tb = saved_tb; + if (env && env->interrupt_request && cpu->current_tb) { cpu_interrupt(env, env->interrupt_request); } } @@ -1094,7 +1098,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, /* we generate a block containing just the instruction modifying the memory. It will ensure that it cannot modify itself */ - env->current_tb = NULL; + cpu->current_tb = NULL; tb_gen_code(env, current_pc, current_cs_base, current_flags, 1); cpu_resume_from_signal(env, NULL); } @@ -1142,6 +1146,7 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr, #ifdef TARGET_HAS_PRECISE_SMC TranslationBlock *current_tb = NULL; CPUArchState *env = cpu_single_env; + CPUState *cpu = NULL; int current_tb_modified = 0; target_ulong current_pc = 0; target_ulong current_cs_base = 0; @@ -1158,6 +1163,9 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr, if (tb && pc != 0) { current_tb = tb_find_pc(pc); } + if (env != NULL) { + cpu = ENV_GET_CPU(env); + } #endif while (tb != NULL) { n = (uintptr_t)tb & 3; @@ -1186,7 +1194,7 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr, /* we generate a block containing just the instruction modifying the memory. It will ensure that it cannot modify itself */ - env->current_tb = NULL; + cpu->current_tb = NULL; tb_gen_code(env, current_pc, current_cs_base, current_flags, 1); cpu_resume_from_signal(env, puc); } @@ -1414,15 +1422,16 @@ void cpu_unlink_tb(CPUArchState *env) problem and hope the cpu will stop of its own accord. For userspace emulation this often isn't actually as bad as it sounds. Often signals are used primarily to interrupt blocking syscalls. */ + CPUState *cpu = ENV_GET_CPU(env); TranslationBlock *tb; static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED; spin_lock(&interrupt_lock); - tb = env->current_tb; + tb = cpu->current_tb; /* if the cpu is currently executing code, we must unlink it and all the potentially executing TB */ if (tb) { - env->current_tb = NULL; + cpu->current_tb = NULL; tb_reset_jump_recursive(tb); } spin_unlock(&interrupt_lock); From 907a5e32f293a0af8875973d4cce12b96bea5bae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 17 Jan 2013 09:16:15 +0100 Subject: [PATCH 39/47] cputlb: Pass CPUState to cpu_unlink_tb() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CPUArchState is no longer needed. Signed-off-by: Andreas Färber --- exec.c | 2 +- translate-all.c | 9 +++++---- translate-all.h | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/exec.c b/exec.c index dbb893a08e..a41bcb8694 100644 --- a/exec.c +++ b/exec.c @@ -495,7 +495,7 @@ void cpu_exit(CPUArchState *env) CPUState *cpu = ENV_GET_CPU(env); cpu->exit_request = 1; - cpu_unlink_tb(env); + cpu_unlink_tb(cpu); } void cpu_abort(CPUArchState *env, const char *fmt, ...) diff --git a/translate-all.c b/translate-all.c index 52128aa0c4..b50fb89528 100644 --- a/translate-all.c +++ b/translate-all.c @@ -1416,13 +1416,12 @@ void tb_invalidate_phys_addr(hwaddr addr) } #endif /* TARGET_HAS_ICE && !defined(CONFIG_USER_ONLY) */ -void cpu_unlink_tb(CPUArchState *env) +void cpu_unlink_tb(CPUState *cpu) { /* FIXME: TB unchaining isn't SMP safe. For now just ignore the problem and hope the cpu will stop of its own accord. For userspace emulation this often isn't actually as bad as it sounds. Often signals are used primarily to interrupt blocking syscalls. */ - CPUState *cpu = ENV_GET_CPU(env); TranslationBlock *tb; static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED; @@ -1476,7 +1475,7 @@ static void tcg_handle_interrupt(CPUArchState *env, int mask) cpu_abort(env, "Raised interrupt while not in I/O function"); } } else { - cpu_unlink_tb(env); + cpu_unlink_tb(cpu); } } @@ -1624,8 +1623,10 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf) void cpu_interrupt(CPUArchState *env, int mask) { + CPUState *cpu = ENV_GET_CPU(env); + env->interrupt_request |= mask; - cpu_unlink_tb(env); + cpu_unlink_tb(cpu); } /* diff --git a/translate-all.h b/translate-all.h index b181fb48ad..5c38819eb8 100644 --- a/translate-all.h +++ b/translate-all.h @@ -28,7 +28,7 @@ /* translate-all.c */ void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len); -void cpu_unlink_tb(CPUArchState *env); +void cpu_unlink_tb(CPUState *cpu); void tb_check_watchpoint(CPUArchState *env); #endif /* TRANSLATE_ALL_H */ From c05efcb18ee30cdf2b00b3512aa0f5233b52911f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 17 Jan 2013 12:13:41 +0100 Subject: [PATCH 40/47] cpu: Add CPUArchState pointer to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The target-specific ENV_GET_CPU() macros have allowed us to navigate from CPUArchState to CPUState. The reverse direction was not supported. Avoid introducing CPU_GET_ENV() macros by initializing an untyped pointer that is initialized in derived instance_init functions. The field may not be called "env" due to it being poisoned. Acked-by: Richard Henderson Signed-off-by: Andreas Färber --- include/qom/cpu.h | 2 ++ target-alpha/cpu.c | 2 ++ target-arm/cpu.c | 2 ++ target-cris/cpu.c | 2 ++ target-i386/cpu.c | 1 + target-lm32/cpu.c | 2 ++ target-m68k/cpu.c | 2 ++ target-microblaze/cpu.c | 2 ++ target-mips/cpu.c | 2 ++ target-openrisc/cpu.c | 2 ++ target-ppc/translate_init.c | 2 ++ target-s390x/cpu.c | 2 ++ target-sh4/cpu.c | 2 ++ target-sparc/cpu.c | 2 ++ target-unicore32/cpu.c | 2 ++ target-xtensa/cpu.c | 2 ++ 16 files changed, 31 insertions(+) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index c25a997808..ee1a7c878a 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -71,6 +71,7 @@ struct kvm_run; * @created: Indicates whether the CPU thread has been successfully created. * @stop: Indicates a pending stop request. * @stopped: Indicates the CPU has been artificially stopped. + * @env_ptr: Pointer to subclass-specific CPUArchState field. * @current_tb: Currently executing TB. * @kvm_fd: vCPU file descriptor for KVM. * @@ -100,6 +101,7 @@ struct CPUState { bool stopped; volatile sig_atomic_t exit_request; + void *env_ptr; /* CPUArchState */ struct TranslationBlock *current_tb; int kvm_fd; diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c index 0cdae6986f..cec9989925 100644 --- a/target-alpha/cpu.c +++ b/target-alpha/cpu.c @@ -233,9 +233,11 @@ static const TypeInfo ev68_cpu_type_info = { static void alpha_cpu_initfn(Object *obj) { + CPUState *cs = CPU(obj); AlphaCPU *cpu = ALPHA_CPU(obj); CPUAlphaState *env = &cpu->env; + cs->env_ptr = env; cpu_exec_init(env); tlb_flush(env, 1); diff --git a/target-arm/cpu.c b/target-arm/cpu.c index f54d20057d..5dfcb740d9 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -134,9 +134,11 @@ static inline void set_feature(CPUARMState *env, int feature) static void arm_cpu_initfn(Object *obj) { + CPUState *cs = CPU(obj); ARMCPU *cpu = ARM_CPU(obj); static bool inited; + cs->env_ptr = &cpu->env; cpu_exec_init(&cpu->env); cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free); diff --git a/target-cris/cpu.c b/target-cris/cpu.c index 80089884e9..7974be33f2 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -146,11 +146,13 @@ static void cris_cpu_realizefn(DeviceState *dev, Error **errp) static void cris_cpu_initfn(Object *obj) { + CPUState *cs = CPU(obj); CRISCPU *cpu = CRIS_CPU(obj); CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(obj); CPUCRISState *env = &cpu->env; static bool tcg_initialized; + cs->env_ptr = env; cpu_exec_init(env); env->pregs[PR_VR] = ccc->vr; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index e2fd6268ef..635f33407e 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2164,6 +2164,7 @@ static void x86_cpu_initfn(Object *obj) CPUX86State *env = &cpu->env; static int inited; + cs->env_ptr = env; cpu_exec_init(env); object_property_add(obj, "family", "int", diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index 5f167340e4..a2badb5701 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -56,10 +56,12 @@ static void lm32_cpu_realizefn(DeviceState *dev, Error **errp) static void lm32_cpu_initfn(Object *obj) { + CPUState *cs = CPU(obj); LM32CPU *cpu = LM32_CPU(obj); CPULM32State *env = &cpu->env; static bool tcg_initialized; + cs->env_ptr = env; cpu_exec_init(env); env->flags = 0; diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index 42735dbe40..f5a109854b 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -154,10 +154,12 @@ static void m68k_cpu_realizefn(DeviceState *dev, Error **errp) static void m68k_cpu_initfn(Object *obj) { + CPUState *cs = CPU(obj); M68kCPU *cpu = M68K_CPU(obj); CPUM68KState *env = &cpu->env; static bool inited; + cs->env_ptr = env; cpu_exec_init(env); if (tcg_enabled() && !inited) { diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c index 28b5a88789..81359db168 100644 --- a/target-microblaze/cpu.c +++ b/target-microblaze/cpu.c @@ -98,10 +98,12 @@ static void mb_cpu_realizefn(DeviceState *dev, Error **errp) static void mb_cpu_initfn(Object *obj) { + CPUState *cs = CPU(obj); MicroBlazeCPU *cpu = MICROBLAZE_CPU(obj); CPUMBState *env = &cpu->env; static bool tcg_initialized; + cs->env_ptr = env; cpu_exec_init(env); set_float_rounding_mode(float_round_nearest_even, &env->fp_status); diff --git a/target-mips/cpu.c b/target-mips/cpu.c index 09d61723c5..4d62031c36 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -55,9 +55,11 @@ static void mips_cpu_realizefn(DeviceState *dev, Error **errp) static void mips_cpu_initfn(Object *obj) { + CPUState *cs = CPU(obj); MIPSCPU *cpu = MIPS_CPU(obj); CPUMIPSState *env = &cpu->env; + cs->env_ptr = env; cpu_exec_init(env); if (tcg_enabled()) { diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c index d8cc533efe..72d5e8d2a5 100644 --- a/target-openrisc/cpu.c +++ b/target-openrisc/cpu.c @@ -75,9 +75,11 @@ static void openrisc_cpu_realizefn(DeviceState *dev, Error **errp) static void openrisc_cpu_initfn(Object *obj) { + CPUState *cs = CPU(obj); OpenRISCCPU *cpu = OPENRISC_CPU(obj); static int inited; + cs->env_ptr = &cpu->env; cpu_exec_init(&cpu->env); #ifndef CONFIG_USER_ONLY diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 5a2acaafe8..5df205757b 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -10529,11 +10529,13 @@ static void ppc_cpu_reset(CPUState *s) static void ppc_cpu_initfn(Object *obj) { + CPUState *cs = CPU(obj); PowerPCCPU *cpu = POWERPC_CPU(obj); PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); CPUPPCState *env = &cpu->env; ppc_def_t *def = pcc->info; + cs->env_ptr = env; cpu_exec_init(env); env->msr_mask = def->msr_mask; diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index 787c937579..b74654724d 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -110,6 +110,7 @@ static void s390_cpu_realizefn(DeviceState *dev, Error **errp) static void s390_cpu_initfn(Object *obj) { + CPUState *cs = CPU(obj); S390CPU *cpu = S390_CPU(obj); CPUS390XState *env = &cpu->env; static bool inited; @@ -118,6 +119,7 @@ static void s390_cpu_initfn(Object *obj) struct tm tm; #endif + cs->env_ptr = env; cpu_exec_init(env); #if !defined(CONFIG_USER_ONLY) qemu_register_reset(s390_cpu_machine_reset_cb, cpu); diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index dc5d7568ea..ef0e62195d 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -67,9 +67,11 @@ static void superh_cpu_realizefn(DeviceState *dev, Error **errp) static void superh_cpu_initfn(Object *obj) { + CPUState *cs = CPU(obj); SuperHCPU *cpu = SUPERH_CPU(obj); CPUSH4State *env = &cpu->env; + cs->env_ptr = env; cpu_exec_init(env); env->movcal_backup_tail = &(env->movcal_backup); diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index 759be532a3..ef52df6d74 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -860,9 +860,11 @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp) static void sparc_cpu_initfn(Object *obj) { + CPUState *cs = CPU(obj); SPARCCPU *cpu = SPARC_CPU(obj); CPUSPARCState *env = &cpu->env; + cs->env_ptr = env; cpu_exec_init(env); if (tcg_enabled()) { diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c index 7bcf3b3658..b7024c85bb 100644 --- a/target-unicore32/cpu.c +++ b/target-unicore32/cpu.c @@ -93,10 +93,12 @@ static void uc32_cpu_realizefn(DeviceState *dev, Error **errp) static void uc32_cpu_initfn(Object *obj) { + CPUState *cs = CPU(obj); UniCore32CPU *cpu = UNICORE32_CPU(obj); CPUUniCore32State *env = &cpu->env; static bool inited; + cs->env_ptr = env; cpu_exec_init(env); #ifdef CONFIG_USER_ONLY diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c index 309bb169ec..785e56d367 100644 --- a/target-xtensa/cpu.c +++ b/target-xtensa/cpu.c @@ -69,10 +69,12 @@ static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp) static void xtensa_cpu_initfn(Object *obj) { + CPUState *cs = CPU(obj); XtensaCPU *cpu = XTENSA_CPU(obj); CPUXtensaState *env = &cpu->env; static bool tcg_inited; + cs->env_ptr = env; cpu_exec_init(env); if (tcg_enabled() && !tcg_inited) { From 440c8152bd410b0f928d4de6f187f1e2280e1324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 15 Feb 2013 15:21:13 +0100 Subject: [PATCH 41/47] e500: Replace open-coded loop with qemu_get_cpu() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we still need env for ppc-specific fields, obtain it via the new env_ptr fields to avoid "cpu" name conflicts between CPUState and PowerPCCPU for now. This fixes a potential issue with env being NULL at the end of the loop but cpu still being a valid pointer corresponding to a previous env. Acked-by: Alexander Graf Signed-off-by: Andreas Färber --- hw/ppc/e500.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index b7474c05f9..451682cb83 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -240,20 +240,15 @@ static int ppce500_load_device_tree(CPUPPCState *env, /* We need to generate the cpu nodes in reverse order, so Linux can pick the first node as boot node and be happy */ for (i = smp_cpus - 1; i >= 0; i--) { - CPUState *cpu = NULL; + CPUState *cpu; char cpu_name[128]; uint64_t cpu_release_addr = MPC8544_SPIN_BASE + (i * 0x20); - for (env = first_cpu; env != NULL; env = env->next_cpu) { - cpu = ENV_GET_CPU(env); - if (cpu->cpu_index == i) { - break; - } - } - + cpu = qemu_get_cpu(i); if (cpu == NULL) { continue; } + env = cpu->env_ptr; snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x", cpu->cpu_index); From 912ebe10eff6cf7e05f908a44283033c1c0270a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 15 Feb 2013 15:56:27 +0100 Subject: [PATCH 42/47] ppce500_spin: Replace open-coded CPU loop with qemu_get_cpu() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Potentially env could be NULL whereas cpu would still be valid and correspond to a previous env. Wrapping this in qemu_get_cpu(), env is no longer needed, so simplify code that existed before 55e5c2850293547203874098f7cec148ffd12dfa. Acked-by: Alexander Graf Signed-off-by: Andreas Färber --- hw/ppce500_spin.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/hw/ppce500_spin.c b/hw/ppce500_spin.c index 7e90fb9824..5bdce52e24 100644 --- a/hw/ppce500_spin.c +++ b/hw/ppce500_spin.c @@ -123,18 +123,11 @@ static void spin_write(void *opaque, hwaddr addr, uint64_t value, { SpinState *s = opaque; int env_idx = addr / sizeof(SpinInfo); - CPUPPCState *env; - CPUState *cpu = NULL; + CPUState *cpu; SpinInfo *curspin = &s->spin[env_idx]; uint8_t *curspin_p = (uint8_t*)curspin; - for (env = first_cpu; env != NULL; env = env->next_cpu) { - cpu = CPU(ppc_env_get_cpu(env)); - if (cpu->cpu_index == env_idx) { - break; - } - } - + cpu = qemu_get_cpu(env_idx); if (cpu == NULL) { /* Unknown CPU */ return; @@ -161,11 +154,11 @@ static void spin_write(void *opaque, hwaddr addr, uint64_t value, if (!(ldq_p(&curspin->addr) & 1)) { /* run CPU */ SpinKick kick = { - .cpu = ppc_env_get_cpu(env), + .cpu = POWERPC_CPU(cpu), .spin = curspin, }; - run_on_cpu(CPU(kick.cpu), spin_kick, &kick); + run_on_cpu(cpu, spin_kick, &kick); } } From 5353d03dd7917875b46ff03e0d9e2935770f5e9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 15 Feb 2013 16:43:08 +0100 Subject: [PATCH 43/47] spapr_hcall: Replace open-coded CPU loop with qemu_get_cpu() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The helper functions all access ppc-specific fields only so don't bother to change arguments to PowerPCCPU and use env_ptr instead. No functional change. Acked-by: Alexander Graf Signed-off-by: Andreas Färber --- hw/spapr_hcall.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c index af1db6ea08..7b8959488e 100644 --- a/hw/spapr_hcall.c +++ b/hw/spapr_hcall.c @@ -469,16 +469,11 @@ static target_ulong h_register_vpa(PowerPCCPU *cpu, sPAPREnvironment *spapr, CPUPPCState *tenv; CPUState *tcpu; - for (tenv = first_cpu; tenv; tenv = tenv->next_cpu) { - tcpu = CPU(ppc_env_get_cpu(tenv)); - if (tcpu->cpu_index == procno) { - break; - } - } - - if (!tenv) { + tcpu = qemu_get_cpu(procno); + if (!tcpu) { return H_PARAMETER; } + tenv = tcpu->env_ptr; switch (flags) { case FLAGS_REGISTER_VPA: From 0dac84597a66eb8f416972faef451ce786b3cdd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 2 Feb 2013 12:10:37 +0100 Subject: [PATCH 44/47] target-s390x: Drop unused cpu_s390x_close() prototype MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was never implemented. Signed-off-by: Andreas Färber --- target-s390x/cpu.h | 1 - 1 file changed, 1 deletion(-) diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index fa8dfe0737..e450db74a2 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 cpu_s390x_close(CPUS390XState *s); void do_interrupt (CPUS390XState *env); /* you can call this signal handler from your SIGBUS and SIGSEGV From 0203f86f5205e09a56df41021d872c6353754250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sat, 2 Feb 2013 12:13:15 +0100 Subject: [PATCH 45/47] target-lm32: Drop unused cpu_lm32_close() prototype MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was never implemented. Signed-off-by: Andreas Färber --- target-lm32/cpu.h | 1 - 1 file changed, 1 deletion(-) diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h index 4e202db32c..6948d0e248 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 cpu_lm32_close(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 From 5c3c6a682dedb3ef6becf112867cf92abf203816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 1 Feb 2013 15:12:13 +0100 Subject: [PATCH 46/47] target-i386: Move cpu_x86_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consolidate CPU functions in cpu.c. Allows to make cpu_x86_register() static. No functional changes. Reviewed-by: Eduardo Habkost Reviewed-by: Igor Mammedov Signed-off-by: Andreas Färber --- target-i386/cpu.c | 26 +++++++++++++++++++++++++- target-i386/cpu.h | 1 - target-i386/helper.c | 24 ------------------------ 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 635f33407e..462d6c9c2d 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -1516,7 +1516,7 @@ static void filter_features_for_kvm(X86CPU *cpu) } #endif -int cpu_x86_register(X86CPU *cpu, const char *cpu_model) +static int cpu_x86_register(X86CPU *cpu, const char *cpu_model) { CPUX86State *env = &cpu->env; x86_def_t def1, *def = &def1; @@ -1576,6 +1576,30 @@ out: return 0; } +X86CPU *cpu_x86_init(const char *cpu_model) +{ + X86CPU *cpu; + CPUX86State *env; + Error *error = NULL; + + cpu = X86_CPU(object_new(TYPE_X86_CPU)); + env = &cpu->env; + env->cpu_model_str = cpu_model; + + if (cpu_x86_register(cpu, cpu_model) < 0) { + object_unref(OBJECT(cpu)); + return NULL; + } + + object_property_set_bool(OBJECT(cpu), true, "realized", &error); + if (error) { + error_free(error); + object_unref(OBJECT(cpu)); + return NULL; + } + return cpu; +} + #if !defined(CONFIG_USER_ONLY) void cpu_clear_apic_feature(CPUX86State *env) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 9e6e1a652f..7577e4f8bb 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -1002,7 +1002,6 @@ int cpu_x86_signal_handler(int host_signum, void *pinfo, void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); -int cpu_x86_register(X86CPU *cpu, const char *cpu_model); void cpu_clear_apic_feature(CPUX86State *env); void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); diff --git a/target-i386/helper.c b/target-i386/helper.c index 1a872fa3d8..4bf9db7f7d 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1267,30 +1267,6 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector, return 1; } -X86CPU *cpu_x86_init(const char *cpu_model) -{ - X86CPU *cpu; - CPUX86State *env; - Error *error = NULL; - - cpu = X86_CPU(object_new(TYPE_X86_CPU)); - env = &cpu->env; - env->cpu_model_str = cpu_model; - - if (cpu_x86_register(cpu, cpu_model) < 0) { - object_unref(OBJECT(cpu)); - return NULL; - } - - object_property_set_bool(OBJECT(cpu), true, "realized", &error); - if (error) { - error_free(error); - object_unref(OBJECT(cpu)); - return NULL; - } - return cpu; -} - #if !defined(CONFIG_USER_ONLY) void do_cpu_init(X86CPU *cpu) { From 2d64255bd7c0d3933ff5ab2cabff11bcb09117a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Fri, 15 Feb 2013 14:06:56 +0100 Subject: [PATCH 47/47] target-i386: Split command line parsing out of cpu_x86_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to instantiate a CPU subtype we will need to know which type, so move the cpu_model splitting into cpu_x86_init(). Parameters need to be set on the X86CPU instance, so move cpu_x86_parse_featurestr() into cpu_x86_init() as well. This leaves cpu_x86_register() operating on the model name only. Signed-off-by: Andreas Färber Signed-off-by: Igor Mammedov Reviewed-by: Eduardo Habkost Signed-off-by: Andreas Färber --- hw/pc.c | 1 - target-i386/cpu.c | 110 +++++++++++++++++++++++----------------------- 2 files changed, 55 insertions(+), 56 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index 53cc173eb2..07caba78ba 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -876,7 +876,6 @@ void pc_cpus_init(const char *cpu_model) for (i = 0; i < smp_cpus; i++) { if (!cpu_x86_init(cpu_model)) { - fprintf(stderr, "Unable to find x86 CPU definition\n"); exit(1); } } diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 462d6c9c2d..dfcf86e862 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -1516,16 +1516,50 @@ static void filter_features_for_kvm(X86CPU *cpu) } #endif -static int cpu_x86_register(X86CPU *cpu, const char *cpu_model) +static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp) { CPUX86State *env = &cpu->env; x86_def_t def1, *def = &def1; - Error *error = NULL; - char *name, *features; - gchar **model_pieces; memset(def, 0, sizeof(*def)); + if (cpu_x86_find_by_name(def, name) < 0) { + error_setg(errp, "Unable to find CPU definition: %s", name); + return; + } + + if (kvm_enabled()) { + def->kvm_features |= kvm_default_features; + } + def->ext_features |= CPUID_EXT_HYPERVISOR; + + object_property_set_str(OBJECT(cpu), def->vendor, "vendor", errp); + object_property_set_int(OBJECT(cpu), def->level, "level", errp); + object_property_set_int(OBJECT(cpu), def->family, "family", errp); + object_property_set_int(OBJECT(cpu), def->model, "model", errp); + object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp); + env->cpuid_features = def->features; + env->cpuid_ext_features = def->ext_features; + env->cpuid_ext2_features = def->ext2_features; + env->cpuid_ext3_features = def->ext3_features; + object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp); + env->cpuid_kvm_features = def->kvm_features; + env->cpuid_svm_features = def->svm_features; + env->cpuid_ext4_features = def->ext4_features; + env->cpuid_7_0_ebx_features = def->cpuid_7_0_ebx_features; + env->cpuid_xlevel2 = def->xlevel2; + + object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp); +} + +X86CPU *cpu_x86_init(const char *cpu_model) +{ + X86CPU *cpu = NULL; + CPUX86State *env; + gchar **model_pieces; + char *name, *features; + Error *error = NULL; + model_pieces = g_strsplit(cpu_model, ",", 2); if (!model_pieces[0]) { error_setg(&error, "Invalid/empty CPU model name"); @@ -1534,68 +1568,34 @@ static int cpu_x86_register(X86CPU *cpu, const char *cpu_model) name = model_pieces[0]; features = model_pieces[1]; - if (cpu_x86_find_by_name(def, name) < 0) { - error_setg(&error, "Unable to find CPU definition: %s", name); - goto out; - } + cpu = X86_CPU(object_new(TYPE_X86_CPU)); + env = &cpu->env; + env->cpu_model_str = cpu_model; - if (kvm_enabled()) { - def->kvm_features |= kvm_default_features; - } - def->ext_features |= CPUID_EXT_HYPERVISOR; - - object_property_set_str(OBJECT(cpu), def->vendor, "vendor", &error); - object_property_set_int(OBJECT(cpu), def->level, "level", &error); - object_property_set_int(OBJECT(cpu), def->family, "family", &error); - object_property_set_int(OBJECT(cpu), def->model, "model", &error); - object_property_set_int(OBJECT(cpu), def->stepping, "stepping", &error); - env->cpuid_features = def->features; - env->cpuid_ext_features = def->ext_features; - env->cpuid_ext2_features = def->ext2_features; - env->cpuid_ext3_features = def->ext3_features; - object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", &error); - env->cpuid_kvm_features = def->kvm_features; - env->cpuid_svm_features = def->svm_features; - env->cpuid_ext4_features = def->ext4_features; - env->cpuid_7_0_ebx_features = def->cpuid_7_0_ebx_features; - env->cpuid_xlevel2 = def->xlevel2; - - object_property_set_str(OBJECT(cpu), def->model_id, "model-id", &error); + cpu_x86_register(cpu, name, &error); if (error) { goto out; } cpu_x86_parse_featurestr(cpu, features, &error); + if (error) { + goto out; + } + + object_property_set_bool(OBJECT(cpu), true, "realized", &error); + if (error) { + goto out; + } + out: g_strfreev(model_pieces); if (error) { fprintf(stderr, "%s\n", error_get_pretty(error)); error_free(error); - return -1; - } - return 0; -} - -X86CPU *cpu_x86_init(const char *cpu_model) -{ - X86CPU *cpu; - CPUX86State *env; - Error *error = NULL; - - cpu = X86_CPU(object_new(TYPE_X86_CPU)); - env = &cpu->env; - env->cpu_model_str = cpu_model; - - if (cpu_x86_register(cpu, cpu_model) < 0) { - object_unref(OBJECT(cpu)); - return NULL; - } - - object_property_set_bool(OBJECT(cpu), true, "realized", &error); - if (error) { - error_free(error); - object_unref(OBJECT(cpu)); - return NULL; + if (cpu != NULL) { + object_unref(OBJECT(cpu)); + cpu = NULL; + } } return cpu; }