Patchwork [2/2] cpu: for cpu-user and cpu-softmmu and make cpu-softmmu a child of DeviceState

login
register
mail settings
Submitter Anthony Liguori
Date Aug. 10, 2012, 5 p.m.
Message ID <1344618044-18704-3-git-send-email-aliguori@us.ibm.com>
Download mbox | patch
Permalink /patch/176546/
State New
Headers show

Comments

Anthony Liguori - Aug. 10, 2012, 5 p.m.
The line between linux-user and softmmu is not very well defined right now.
linux-user really don't want to include devices and making CpuState a child of
DeviceState would require pulling lots of stuff into linux-user.

To solve this, we simply fork cpu-user and cpu-softmmu letting them evolve
independently.

We also need to push a qdev_init_nofail() into all callers of cpu_init().  This
is needed eventually anyway so might as well do this now.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 Makefile.objs                 |    6 ---
 hw/armv7m.c                   |    1 +
 hw/axis_dev88.c               |    1 +
 hw/exynos4210.c               |    1 +
 hw/highbank.c                 |    1 +
 hw/integratorcp.c             |    1 +
 hw/leon3.c                    |    1 +
 hw/lm32_boards.c              |    2 +
 hw/milkymist.c                |    1 +
 hw/mips_fulong2e.c            |    1 +
 hw/mips_jazz.c                |    1 +
 hw/mips_malta.c               |    1 +
 hw/mips_mipssim.c             |    1 +
 hw/mips_r4k.c                 |    1 +
 hw/musicpal.c                 |    1 +
 hw/omap1.c                    |    1 +
 hw/omap2.c                    |    1 +
 hw/pc.c                       |    1 +
 hw/petalogix_ml605_mmu.c      |    1 +
 hw/petalogix_s3adsp1800_mmu.c |    1 +
 hw/ppc440_bamboo.c            |    1 +
 hw/ppc4xx_devs.c              |    1 +
 hw/ppc_newworld.c             |    1 +
 hw/ppc_oldworld.c             |    1 +
 hw/ppc_prep.c                 |    1 +
 hw/ppce500_mpc8544ds.c        |    1 +
 hw/pxa2xx.c                   |    1 +
 hw/r2d.c                      |    1 +
 hw/realview.c                 |    1 +
 hw/s390-virtio.c              |    1 +
 hw/spapr.c                    |    1 +
 hw/strongarm.c                |    1 +
 hw/sun4m.c                    |    1 +
 hw/sun4u.c                    |    1 +
 hw/versatilepb.c              |    1 +
 hw/vexpress.c                 |    2 +
 hw/virtex_ml507.c             |    1 +
 hw/xen_machine_pv.c           |    1 +
 hw/xilinx_zynq.c              |    1 +
 hw/xtensa_lx60.c              |    1 +
 hw/xtensa_sim.c               |    1 +
 include/qemu/cpu-softmmu.h    |   82 +++++++++++++++++++++++++++++++++++++++
 include/qemu/cpu-user.h       |   75 ++++++++++++++++++++++++++++++++++++
 include/qemu/cpu.h            |   85 ++---------------------------------------
 qemu-common.h                 |    3 +-
 qom/Makefile.objs             |    5 +-
 qom/cpu-softmmu.c             |   66 +++++++++++++++++++++++++++++++
 qom/cpu-user.c                |   70 +++++++++++++++++++++++++++++++++
 48 files changed, 343 insertions(+), 91 deletions(-)
 create mode 100644 include/qemu/cpu-softmmu.h
 create mode 100644 include/qemu/cpu-user.h
 create mode 100644 qom/cpu-softmmu.c
 create mode 100644 qom/cpu-user.c
Eduardo Habkost - Aug. 10, 2012, 5:09 p.m.
On Fri, Aug 10, 2012 at 12:00:44PM -0500, Anthony Liguori wrote:
> The line between linux-user and softmmu is not very well defined right now.
> linux-user really don't want to include devices and making CpuState a child of
> DeviceState would require pulling lots of stuff into linux-user.
> 
> To solve this, we simply fork cpu-user and cpu-softmmu letting them evolve
> independently.
> 
> We also need to push a qdev_init_nofail() into all callers of cpu_init().  This
> is needed eventually anyway so might as well do this now.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
[...]
> --- /dev/null
> +++ b/qom/cpu-user.c
[...]
> +static TypeInfo cpu_type_info = {
> +    .name = TYPE_CPU,
> +#ifdef CONFIG_USER_ONLY
> +    .parent = TYPE_OBJECT,
> +#else
> +    .parent = TYPE_DEVICE,
> +#endif

Is this #ifdef supposed to be here?

> +    .instance_size = sizeof(CPUState),
> +    .abstract = true,
> +    .class_size = sizeof(CPUClass),
> +    .class_init = cpu_class_init,
> +};
> +
> +static void cpu_register_types(void)
> +{
> +    type_register_static(&cpu_type_info);
> +}
> +
> +type_init(cpu_register_types)
> -- 
> 1.7.5.4
>
Anthony Liguori - Aug. 10, 2012, 6:28 p.m.
Eduardo Habkost <ehabkost@redhat.com> writes:

> On Fri, Aug 10, 2012 at 12:00:44PM -0500, Anthony Liguori wrote:
>> The line between linux-user and softmmu is not very well defined right now.
>> linux-user really don't want to include devices and making CpuState a child of
>> DeviceState would require pulling lots of stuff into linux-user.
>> 
>> To solve this, we simply fork cpu-user and cpu-softmmu letting them evolve
>> independently.
>> 
>> We also need to push a qdev_init_nofail() into all callers of cpu_init().  This
>> is needed eventually anyway so might as well do this now.
>> 
>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>> ---
> [...]
>> --- /dev/null
>> +++ b/qom/cpu-user.c
> [...]
>> +static TypeInfo cpu_type_info = {
>> +    .name = TYPE_CPU,
>> +#ifdef CONFIG_USER_ONLY
>> +    .parent = TYPE_OBJECT,
>> +#else
>> +    .parent = TYPE_DEVICE,
>> +#endif
>
> Is this #ifdef supposed to be here?

Nope.  Thanks.

Regards,

Anthony Liguori

>
>> +    .instance_size = sizeof(CPUState),
>> +    .abstract = true,
>> +    .class_size = sizeof(CPUClass),
>> +    .class_init = cpu_class_init,
>> +};
>> +
>> +static void cpu_register_types(void)
>> +{
>> +    type_register_static(&cpu_type_info);
>> +}
>> +
>> +type_init(cpu_register_types)
>> -- 
>> 1.7.5.4
>> 
>
> -- 
> Eduardo
Andreas Färber - Aug. 15, 2012, 3:41 p.m.
Am 10.08.2012 19:00, schrieb Anthony Liguori:
> The line between linux-user and softmmu is not very well defined right now.
> linux-user really don't want to include devices and making CpuState a child of
> DeviceState would require pulling lots of stuff into linux-user.
> 
> To solve this, we simply fork cpu-user and cpu-softmmu letting them evolve
> independently.

In the KVM call discussion there was no consensus that such independent
evolution is actually desirable.

For example, moving forward with eliminating the CPU_COMMON mess this
will mean duplicating the implementation of cpu_common_reset() -
currently empty but in need of at least some zero'ing in the future. My
fear is that such duplication will lead to fixes getting applied to the
softmmu version only and contributors forgetting / being unaware that
there is a second place to apply the same change.

Putting different TypeInfos into seperate source files is fine with me,
but I would rather have shared implementations with an #ifdef than
duplicating things.
By comparison, forgetting to add a new field in either struct would lead
to a compilation failure, getting noticed, so that seems doable.

> We also need to push a qdev_init_nofail() into all callers of cpu_init().  This
> is needed eventually anyway so might as well do this now.

Patch would be better readable doing that as a follow-up...

> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
>  Makefile.objs                 |    6 ---
>  hw/armv7m.c                   |    1 +
>  hw/axis_dev88.c               |    1 +
>  hw/exynos4210.c               |    1 +
>  hw/highbank.c                 |    1 +
>  hw/integratorcp.c             |    1 +
>  hw/leon3.c                    |    1 +
>  hw/lm32_boards.c              |    2 +
>  hw/milkymist.c                |    1 +
>  hw/mips_fulong2e.c            |    1 +
>  hw/mips_jazz.c                |    1 +
>  hw/mips_malta.c               |    1 +
>  hw/mips_mipssim.c             |    1 +
>  hw/mips_r4k.c                 |    1 +
>  hw/musicpal.c                 |    1 +
>  hw/omap1.c                    |    1 +
>  hw/omap2.c                    |    1 +
>  hw/pc.c                       |    1 +
>  hw/petalogix_ml605_mmu.c      |    1 +
>  hw/petalogix_s3adsp1800_mmu.c |    1 +
>  hw/ppc440_bamboo.c            |    1 +
>  hw/ppc4xx_devs.c              |    1 +
>  hw/ppc_newworld.c             |    1 +
>  hw/ppc_oldworld.c             |    1 +
>  hw/ppc_prep.c                 |    1 +
>  hw/ppce500_mpc8544ds.c        |    1 +
>  hw/pxa2xx.c                   |    1 +
>  hw/r2d.c                      |    1 +
>  hw/realview.c                 |    1 +
>  hw/s390-virtio.c              |    1 +
>  hw/spapr.c                    |    1 +
>  hw/strongarm.c                |    1 +
>  hw/sun4m.c                    |    1 +
>  hw/sun4u.c                    |    1 +
>  hw/versatilepb.c              |    1 +
>  hw/vexpress.c                 |    2 +
>  hw/virtex_ml507.c             |    1 +
>  hw/xen_machine_pv.c           |    1 +
>  hw/xilinx_zynq.c              |    1 +
>  hw/xtensa_lx60.c              |    1 +
>  hw/xtensa_sim.c               |    1 +
>  include/qemu/cpu-softmmu.h    |   82 +++++++++++++++++++++++++++++++++++++++
>  include/qemu/cpu-user.h       |   75 ++++++++++++++++++++++++++++++++++++
>  include/qemu/cpu.h            |   85 ++---------------------------------------
>  qemu-common.h                 |    3 +-
>  qom/Makefile.objs             |    5 +-
>  qom/cpu-softmmu.c             |   66 +++++++++++++++++++++++++++++++
>  qom/cpu-user.c                |   70 +++++++++++++++++++++++++++++++++
>  48 files changed, 343 insertions(+), 91 deletions(-)
>  create mode 100644 include/qemu/cpu-softmmu.h
>  create mode 100644 include/qemu/cpu-user.h
>  create mode 100644 qom/cpu-softmmu.c
>  create mode 100644 qom/cpu-user.c
> 
> diff --git a/Makefile.objs b/Makefile.objs
> index 5ebbcfa..f285926 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -12,12 +12,6 @@ qobject-obj-y += qerror.o error.o qemu-error.o
>  universal-obj-y += $(qobject-obj-y)
>  
>  #######################################################################
> -# QOM
> -qom-obj-y = qom/
> -
> -universal-obj-y += $(qom-obj-y)
> -
> -#######################################################################
>  # oslib-obj-y is code depending on the OS (win32 vs posix)
>  oslib-obj-y = osdep.o
>  oslib-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o
[...]
> diff --git a/include/qemu/cpu-softmmu.h b/include/qemu/cpu-softmmu.h
> new file mode 100644
> index 0000000..4f7b602
> --- /dev/null
> +++ b/include/qemu/cpu-softmmu.h
> @@ -0,0 +1,82 @@
> +/*
> + * QEMU CPU model
> + *
> + * Copyright (c) 2012 SUSE LINUX Products GmbH
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, see
> + * <http://www.gnu.org/licenses/gpl-2.0.html>
> + */
> +#ifndef QEMU_CPU_H
> +#define QEMU_CPU_H
> +
> +#include "hw/qdev-core.h"
> +#include "qemu-thread.h"
> +
> +/**
> + * SECTION:cpu
> + * @section_id: QEMU-cpu
> + * @title: CPU Class
> + * @short_description: Base class for all CPUs
> + */
> +
> +#define TYPE_CPU "cpu"
> +
> +#define CPU(obj) OBJECT_CHECK(CPUState, (obj), TYPE_CPU)
> +#define CPU_CLASS(class) OBJECT_CLASS_CHECK(CPUClass, (class), TYPE_CPU)
> +#define CPU_GET_CLASS(obj) OBJECT_GET_CLASS(CPUClass, (obj), TYPE_CPU)
> +
> +typedef struct CPUState CPUState;
> +
> +/**
> + * CPUClass:
> + * @reset: Callback to reset the #CPUState to its initial state.
> + *
> + * Represents a CPU family or model.
> + */
> +typedef struct CPUClass {
> +    /*< private >*/
> +    DeviceClass parent_class;
> +    /*< public >*/
> +
> +    void (*reset)(CPUState *cpu);
> +} CPUClass;
> +
> +/**
> + * CPUState:
> + *
> + * State of one CPU core or thread.
> + */
> +struct CPUState {
> +    /*< private >*/
> +    DeviceState parent_obj;
> +    /*< public >*/
> +
> +    struct QemuThread *thread;
> +#ifdef _WIN32
> +   HANDLE hThread;
> +#endif
> +    bool thread_kicked;
> +
> +    /* TODO Move common fields from CPUArchState here. */
> +};
> +
> +
> +/**
> + * cpu_reset:
> + * @cpu: The CPU whose state is to be reset.
> + */
> +void cpu_reset(CPUState *cpu);
> +
> +
> +#endif
> diff --git a/include/qemu/cpu-user.h b/include/qemu/cpu-user.h
> new file mode 100644
> index 0000000..78b65b3
> --- /dev/null
> +++ b/include/qemu/cpu-user.h
> @@ -0,0 +1,75 @@
> +/*
> + * QEMU CPU model
> + *
> + * Copyright (c) 2012 SUSE LINUX Products GmbH
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, see
> + * <http://www.gnu.org/licenses/gpl-2.0.html>
> + */
> +#ifndef QEMU_CPU_H
> +#define QEMU_CPU_H
> +
> +#include "qemu/object.h"
> +
> +/**
> + * SECTION:cpu
> + * @section_id: QEMU-cpu
> + * @title: CPU Class
> + * @short_description: Base class for all CPUs
> + */
> +
> +#define TYPE_CPU "cpu"
> +
> +#define CPU(obj) OBJECT_CHECK(CPUState, (obj), TYPE_CPU)
> +#define CPU_CLASS(class) OBJECT_CLASS_CHECK(CPUClass, (class), TYPE_CPU)
> +#define CPU_GET_CLASS(obj) OBJECT_GET_CLASS(CPUClass, (obj), TYPE_CPU)
> +
> +typedef struct CPUState CPUState;
> +
> +/**
> + * CPUClass:
> + * @reset: Callback to reset the #CPUState to its initial state.
> + *
> + * Represents a CPU family or model.
> + */
> +typedef struct CPUClass {
> +    /*< private >*/
> +    ObjectClass parent_class;
> +    /*< public >*/
> +
> +    void (*reset)(CPUState *cpu);
> +} CPUClass;
> +
> +/**
> + * CPUState:
> + *
> + * State of one CPU core or thread.
> + */
> +struct CPUState {
> +    /*< private >*/
> +    Object parent_obj;
> +    /*< public >*/
> +
> +    /* TODO Move common fields from CPUArchState here. */
> +};
> +
> +
> +/**
> + * cpu_reset:
> + * @cpu: The CPU whose state is to be reset.
> + */
> +void cpu_reset(CPUState *cpu);
> +
> +
> +#endif
> diff --git a/include/qemu/cpu.h b/include/qemu/cpu.h
> index ad706a6..862988a 100644
> --- a/include/qemu/cpu.h
> +++ b/include/qemu/cpu.h
> @@ -1,82 +1,5 @@
> -/*
> - * QEMU CPU model
> - *
> - * Copyright (c) 2012 SUSE LINUX Products GmbH
> - *
> - * This program is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU General Public License
> - * as published by the Free Software Foundation; either version 2
> - * of the License, or (at your option) any later version.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program; if not, see
> - * <http://www.gnu.org/licenses/gpl-2.0.html>
> - */

If we empty this file, suggest to use either a GPLv2+ or MIT header to
clarify licensing.

> -#ifndef QEMU_CPU_H
> -#define QEMU_CPU_H
> -
> -#include "qemu/object.h"
> -#include "qemu-thread.h"
> -
> -/**
> - * SECTION:cpu
> - * @section_id: QEMU-cpu
> - * @title: CPU Class
> - * @short_description: Base class for all CPUs
> - */
> -
> -#define TYPE_CPU "cpu"
> -
> -#define CPU(obj) OBJECT_CHECK(CPUState, (obj), TYPE_CPU)
> -#define CPU_CLASS(class) OBJECT_CLASS_CHECK(CPUClass, (class), TYPE_CPU)
> -#define CPU_GET_CLASS(obj) OBJECT_GET_CLASS(CPUClass, (obj), TYPE_CPU)
> -
> -typedef struct CPUState CPUState;
> -
> -/**
> - * CPUClass:
> - * @reset: Callback to reset the #CPUState to its initial state.
> - *
> - * Represents a CPU family or model.
> - */
> -typedef struct CPUClass {
> -    /*< private >*/
> -    ObjectClass parent_class;
> -    /*< public >*/
> -
> -    void (*reset)(CPUState *cpu);
> -} CPUClass;
> -
> -/**
> - * CPUState:
> - *
> - * State of one CPU core or thread.
> - */
> -struct CPUState {
> -    /*< private >*/
> -    Object parent_obj;
> -    /*< public >*/
> -
> -    struct QemuThread *thread;
> -#ifdef _WIN32
> -    HANDLE hThread;
> -#endif
> -    bool thread_kicked;
> -
> -    /* TODO Move common fields from CPUArchState here. */
> -};
> -
> -
> -/**
> - * cpu_reset:
> - * @cpu: The CPU whose state is to be reset.
> - */
> -void cpu_reset(CPUState *cpu);

As commented on IRC, I would prefer this to stay in a shared cpu.h since
it is used identically for softmmu and *-user. Simplifies rewriting
documentation or adding Error** or whatever.

Same for TYPE_CPU and cast macros, they do not differ.

> -
> -
> +#ifdef CONFIG_USER_ONLY
> +#include "qemu/cpu-user.h"
> +#else
> +#include "qemu/cpu-softmmu.h"
>  #endif
> diff --git a/qemu-common.h b/qemu-common.h
> index f9deca6..47a3aab 100644
> --- a/qemu-common.h
> +++ b/qemu-common.h
> @@ -270,7 +270,6 @@ typedef struct PCIEPort PCIEPort;
>  typedef struct PCIESlot PCIESlot;
>  typedef struct MSIMessage MSIMessage;
>  typedef struct SerialState SerialState;
> -typedef struct IRQState *qemu_irq;
>  typedef struct PCMCIACardState PCMCIACardState;
>  typedef struct MouseTransformInfo MouseTransformInfo;
>  typedef struct uWireSlave uWireSlave;
> @@ -281,6 +280,8 @@ typedef struct VirtIODevice VirtIODevice;
>  typedef struct QEMUSGList QEMUSGList;
>  typedef struct SHPCDevice SHPCDevice;
>  
> +#include "hw/irq.h"

Independent of cpu split?

> +
>  typedef uint64_t pcibus_t;
>  
>  typedef enum LostTickPolicy {
> diff --git a/qom/Makefile.objs b/qom/Makefile.objs
> index 5ef060a..a24fadf 100644
> --- a/qom/Makefile.objs
> +++ b/qom/Makefile.objs
> @@ -1,4 +1,3 @@
>  qom-obj-y = object.o container.o qom-qobject.o
> -qom-obj-twice-y = cpu.o
> -common-obj-y = $(qom-obj-twice-y)
> -user-obj-y = $(qom-obj-twice-y)
> +common-obj-y += $(qom-obj-y) cpu-softmmu.o
> +user-obj-y += $(qom-obj-y) cpu-user.o

This is silently making cpu.c unused without deleting it, no?

> diff --git a/qom/cpu-softmmu.c b/qom/cpu-softmmu.c
> new file mode 100644
> index 0000000..5790944
> --- /dev/null
> +++ b/qom/cpu-softmmu.c
> @@ -0,0 +1,66 @@
> +/*
> + * QEMU CPU model
> + *
> + * Copyright (c) 2012 SUSE LINUX Products GmbH
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, see
> + * <http://www.gnu.org/licenses/gpl-2.0.html>
> + */
> +
> +#include "qemu/cpu.h"
> +#include "qemu-common.h"
> +#include "hw/qdev.h"
> +
> +void cpu_reset(CPUState *cpu)
> +{
> +    CPUClass *klass = CPU_GET_CLASS(cpu);
> +
> +    if (klass->reset != NULL) {
> +        (*klass->reset)(cpu);
> +    }
> +}
> +
> +static void cpu_common_reset(CPUState *cpu)
> +{
> +}
> +
> +static int cpu_realize(DeviceState *dev)
> +{
> +    return 0;
> +}
> +
> +static void cpu_class_init(ObjectClass *klass, void *data)
> +{
> +    CPUClass *k = CPU_CLASS(klass);
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    k->reset = cpu_common_reset;
> +    dc->init = cpu_realize;
> +}
> +
> +static TypeInfo cpu_type_info = {

const was/is missing... o;-)

Since this has been getting late - sorry - and there being no follow-ups
for v1.2, what about applying patch 1/2 and deferring 2/2 to v1.3 /
cpu-next?

Regards,
Andreas

> +    .name = TYPE_CPU,
> +    .parent = TYPE_DEVICE,
> +    .instance_size = sizeof(CPUState),
> +    .abstract = true,
> +    .class_size = sizeof(CPUClass),
> +    .class_init = cpu_class_init,
> +};
> +
> +static void cpu_register_types(void)
> +{
> +    type_register_static(&cpu_type_info);
> +}
> +
> +type_init(cpu_register_types)
> diff --git a/qom/cpu-user.c b/qom/cpu-user.c
> new file mode 100644
> index 0000000..17b796f
> --- /dev/null
> +++ b/qom/cpu-user.c
> @@ -0,0 +1,70 @@
> +/*
> + * QEMU CPU model
> + *
> + * Copyright (c) 2012 SUSE LINUX Products GmbH
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, see
> + * <http://www.gnu.org/licenses/gpl-2.0.html>
> + */
> +
> +#include "qemu/cpu.h"
> +#include "qemu-common.h"
> +
> +void cpu_reset(CPUState *cpu)
> +{
> +    CPUClass *klass = CPU_GET_CLASS(cpu);
> +
> +    if (klass->reset != NULL) {
> +        (*klass->reset)(cpu);
> +    }
> +}
> +
> +static void cpu_common_reset(CPUState *cpu)
> +{
> +}
> +
> +static void cpu_class_init(ObjectClass *klass, void *data)
> +{
> +#ifndef CONFIG_USER_ONLY
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +#endif
> +    CPUClass *k = CPU_CLASS(klass);
> +
> +#ifndef CONFIG_USER_ONLY
> +    /* Overwrite this in subclasses for which hotplug is supported. */
> +    dc->no_user = 1;
> +#endif
> +
> +    k->reset = cpu_common_reset;
> +}
> +
> +static TypeInfo cpu_type_info = {
> +    .name = TYPE_CPU,
> +#ifdef CONFIG_USER_ONLY
> +    .parent = TYPE_OBJECT,
> +#else
> +    .parent = TYPE_DEVICE,
> +#endif
> +    .instance_size = sizeof(CPUState),
> +    .abstract = true,
> +    .class_size = sizeof(CPUClass),
> +    .class_init = cpu_class_init,
> +};
> +
> +static void cpu_register_types(void)
> +{
> +    type_register_static(&cpu_type_info);
> +}
> +
> +type_init(cpu_register_types)
Anthony Liguori - Aug. 15, 2012, 4:29 p.m.
Andreas Färber <afaerber@suse.de> writes:

> Am 10.08.2012 19:00, schrieb Anthony Liguori:
>> The line between linux-user and softmmu is not very well defined right now.
>> linux-user really don't want to include devices and making CpuState a child of
>> DeviceState would require pulling lots of stuff into linux-user.
>> 
>> To solve this, we simply fork cpu-user and cpu-softmmu letting them evolve
>> independently.
>
> In the KVM call discussion there was no consensus that such independent
> evolution is actually desirable.
>
> For example, moving forward with eliminating the CPU_COMMON mess this
> will mean duplicating the implementation of cpu_common_reset() -
> currently empty but in need of at least some zero'ing in the future. My
> fear is that such duplication will lead to fixes getting applied to the
> softmmu version only and contributors forgetting / being unaware that
> there is a second place to apply the same change.

Well the alternative is to build qdev for linux-user.

I tried very hard to make that work but I gave up.  That is without a
doubt the Right Solution.

>
> Putting different TypeInfos into seperate source files is fine with me,
> but I would rather have shared implementations with an #ifdef than
> duplicating things.

I fear a tremendous amount of #ifdef's becoming necessary to make this
work long term.  That's why I prefer divergence.  linux-user can stay
simple and softmmu will be unaffected.

> By comparison, forgetting to add a new field in either struct would lead
> to a compilation failure, getting noticed, so that seems doable.
>
>> We also need to push a qdev_init_nofail() into all callers of cpu_init().  This
>> is needed eventually anyway so might as well do this now.
>
> Patch would be better readable doing that as a follow-up...

Pretty sure that causes a breakage although I don't remember why so I
don't think splitting up the patch is possible.

>
>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>> ---
>>  Makefile.objs                 |    6 ---
>>  hw/armv7m.c                   |    1 +
>>  hw/axis_dev88.c               |    1 +
>>  hw/exynos4210.c               |    1 +
>>  hw/highbank.c                 |    1 +
>>  hw/integratorcp.c             |    1 +
>>  hw/leon3.c                    |    1 +
>>  hw/lm32_boards.c              |    2 +
>>  hw/milkymist.c                |    1 +
>>  hw/mips_fulong2e.c            |    1 +
>>  hw/mips_jazz.c                |    1 +
>>  hw/mips_malta.c               |    1 +
>>  hw/mips_mipssim.c             |    1 +
>>  hw/mips_r4k.c                 |    1 +
>>  hw/musicpal.c                 |    1 +
>>  hw/omap1.c                    |    1 +
>>  hw/omap2.c                    |    1 +
>>  hw/pc.c                       |    1 +
>>  hw/petalogix_ml605_mmu.c      |    1 +
>>  hw/petalogix_s3adsp1800_mmu.c |    1 +
>>  hw/ppc440_bamboo.c            |    1 +
>>  hw/ppc4xx_devs.c              |    1 +
>>  hw/ppc_newworld.c             |    1 +
>>  hw/ppc_oldworld.c             |    1 +
>>  hw/ppc_prep.c                 |    1 +
>>  hw/ppce500_mpc8544ds.c        |    1 +
>>  hw/pxa2xx.c                   |    1 +
>>  hw/r2d.c                      |    1 +
>>  hw/realview.c                 |    1 +
>>  hw/s390-virtio.c              |    1 +
>>  hw/spapr.c                    |    1 +
>>  hw/strongarm.c                |    1 +
>>  hw/sun4m.c                    |    1 +
>>  hw/sun4u.c                    |    1 +
>>  hw/versatilepb.c              |    1 +
>>  hw/vexpress.c                 |    2 +
>>  hw/virtex_ml507.c             |    1 +
>>  hw/xen_machine_pv.c           |    1 +
>>  hw/xilinx_zynq.c              |    1 +
>>  hw/xtensa_lx60.c              |    1 +
>>  hw/xtensa_sim.c               |    1 +
>>  include/qemu/cpu-softmmu.h    |   82 +++++++++++++++++++++++++++++++++++++++
>>  include/qemu/cpu-user.h       |   75 ++++++++++++++++++++++++++++++++++++
>>  include/qemu/cpu.h            |   85 ++---------------------------------------
>>  qemu-common.h                 |    3 +-
>>  qom/Makefile.objs             |    5 +-
>>  qom/cpu-softmmu.c             |   66 +++++++++++++++++++++++++++++++
>>  qom/cpu-user.c                |   70 +++++++++++++++++++++++++++++++++
>>  48 files changed, 343 insertions(+), 91 deletions(-)
>>  create mode 100644 include/qemu/cpu-softmmu.h
>>  create mode 100644 include/qemu/cpu-user.h
>>  create mode 100644 qom/cpu-softmmu.c
>>  create mode 100644 qom/cpu-user.c
>> 
>> diff --git a/Makefile.objs b/Makefile.objs
>> index 5ebbcfa..f285926 100644
>> --- a/Makefile.objs
>> +++ b/Makefile.objs
>> @@ -12,12 +12,6 @@ qobject-obj-y += qerror.o error.o qemu-error.o
>>  universal-obj-y += $(qobject-obj-y)
>>  
>>  #######################################################################
>> -# QOM
>> -qom-obj-y = qom/
>> -
>> -universal-obj-y += $(qom-obj-y)
>> -
>> -#######################################################################
>>  # oslib-obj-y is code depending on the OS (win32 vs posix)
>>  oslib-obj-y = osdep.o
>>  oslib-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o
> [...]
>> diff --git a/include/qemu/cpu-softmmu.h b/include/qemu/cpu-softmmu.h
>> new file mode 100644
>> index 0000000..4f7b602
>> --- /dev/null
>> +++ b/include/qemu/cpu-softmmu.h
>> @@ -0,0 +1,82 @@
>> +/*
>> + * QEMU CPU model
>> + *
>> + * Copyright (c) 2012 SUSE LINUX Products GmbH
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License
>> + * as published by the Free Software Foundation; either version 2
>> + * of the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, see
>> + * <http://www.gnu.org/licenses/gpl-2.0.html>
>> + */
>> +#ifndef QEMU_CPU_H
>> +#define QEMU_CPU_H
>> +
>> +#include "hw/qdev-core.h"
>> +#include "qemu-thread.h"
>> +
>> +/**
>> + * SECTION:cpu
>> + * @section_id: QEMU-cpu
>> + * @title: CPU Class
>> + * @short_description: Base class for all CPUs
>> + */
>> +
>> +#define TYPE_CPU "cpu"
>> +
>> +#define CPU(obj) OBJECT_CHECK(CPUState, (obj), TYPE_CPU)
>> +#define CPU_CLASS(class) OBJECT_CLASS_CHECK(CPUClass, (class), TYPE_CPU)
>> +#define CPU_GET_CLASS(obj) OBJECT_GET_CLASS(CPUClass, (obj), TYPE_CPU)
>> +
>> +typedef struct CPUState CPUState;
>> +
>> +/**
>> + * CPUClass:
>> + * @reset: Callback to reset the #CPUState to its initial state.
>> + *
>> + * Represents a CPU family or model.
>> + */
>> +typedef struct CPUClass {
>> +    /*< private >*/
>> +    DeviceClass parent_class;
>> +    /*< public >*/
>> +
>> +    void (*reset)(CPUState *cpu);
>> +} CPUClass;
>> +
>> +/**
>> + * CPUState:
>> + *
>> + * State of one CPU core or thread.
>> + */
>> +struct CPUState {
>> +    /*< private >*/
>> +    DeviceState parent_obj;
>> +    /*< public >*/
>> +
>> +    struct QemuThread *thread;
>> +#ifdef _WIN32
>> +   HANDLE hThread;
>> +#endif
>> +    bool thread_kicked;
>> +
>> +    /* TODO Move common fields from CPUArchState here. */
>> +};
>> +
>> +
>> +/**
>> + * cpu_reset:
>> + * @cpu: The CPU whose state is to be reset.
>> + */
>> +void cpu_reset(CPUState *cpu);
>> +
>> +
>> +#endif
>> diff --git a/include/qemu/cpu-user.h b/include/qemu/cpu-user.h
>> new file mode 100644
>> index 0000000..78b65b3
>> --- /dev/null
>> +++ b/include/qemu/cpu-user.h
>> @@ -0,0 +1,75 @@
>> +/*
>> + * QEMU CPU model
>> + *
>> + * Copyright (c) 2012 SUSE LINUX Products GmbH
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License
>> + * as published by the Free Software Foundation; either version 2
>> + * of the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, see
>> + * <http://www.gnu.org/licenses/gpl-2.0.html>
>> + */
>> +#ifndef QEMU_CPU_H
>> +#define QEMU_CPU_H
>> +
>> +#include "qemu/object.h"
>> +
>> +/**
>> + * SECTION:cpu
>> + * @section_id: QEMU-cpu
>> + * @title: CPU Class
>> + * @short_description: Base class for all CPUs
>> + */
>> +
>> +#define TYPE_CPU "cpu"
>> +
>> +#define CPU(obj) OBJECT_CHECK(CPUState, (obj), TYPE_CPU)
>> +#define CPU_CLASS(class) OBJECT_CLASS_CHECK(CPUClass, (class), TYPE_CPU)
>> +#define CPU_GET_CLASS(obj) OBJECT_GET_CLASS(CPUClass, (obj), TYPE_CPU)
>> +
>> +typedef struct CPUState CPUState;
>> +
>> +/**
>> + * CPUClass:
>> + * @reset: Callback to reset the #CPUState to its initial state.
>> + *
>> + * Represents a CPU family or model.
>> + */
>> +typedef struct CPUClass {
>> +    /*< private >*/
>> +    ObjectClass parent_class;
>> +    /*< public >*/
>> +
>> +    void (*reset)(CPUState *cpu);
>> +} CPUClass;
>> +
>> +/**
>> + * CPUState:
>> + *
>> + * State of one CPU core or thread.
>> + */
>> +struct CPUState {
>> +    /*< private >*/
>> +    Object parent_obj;
>> +    /*< public >*/
>> +
>> +    /* TODO Move common fields from CPUArchState here. */
>> +};
>> +
>> +
>> +/**
>> + * cpu_reset:
>> + * @cpu: The CPU whose state is to be reset.
>> + */
>> +void cpu_reset(CPUState *cpu);
>> +
>> +
>> +#endif
>> diff --git a/include/qemu/cpu.h b/include/qemu/cpu.h
>> index ad706a6..862988a 100644
>> --- a/include/qemu/cpu.h
>> +++ b/include/qemu/cpu.h
>> @@ -1,82 +1,5 @@
>> -/*
>> - * QEMU CPU model
>> - *
>> - * Copyright (c) 2012 SUSE LINUX Products GmbH
>> - *
>> - * This program is free software; you can redistribute it and/or
>> - * modify it under the terms of the GNU General Public License
>> - * as published by the Free Software Foundation; either version 2
>> - * of the License, or (at your option) any later version.
>> - *
>> - * This program is distributed in the hope that it will be useful,
>> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> - * GNU General Public License for more details.
>> - *
>> - * You should have received a copy of the GNU General Public License
>> - * along with this program; if not, see
>> - * <http://www.gnu.org/licenses/gpl-2.0.html>
>> - */
>
> If we empty this file, suggest to use either a GPLv2+ or MIT header to
> clarify licensing.
>
>> -#ifndef QEMU_CPU_H
>> -#define QEMU_CPU_H
>> -
>> -#include "qemu/object.h"
>> -#include "qemu-thread.h"
>> -
>> -/**
>> - * SECTION:cpu
>> - * @section_id: QEMU-cpu
>> - * @title: CPU Class
>> - * @short_description: Base class for all CPUs
>> - */
>> -
>> -#define TYPE_CPU "cpu"
>> -
>> -#define CPU(obj) OBJECT_CHECK(CPUState, (obj), TYPE_CPU)
>> -#define CPU_CLASS(class) OBJECT_CLASS_CHECK(CPUClass, (class), TYPE_CPU)
>> -#define CPU_GET_CLASS(obj) OBJECT_GET_CLASS(CPUClass, (obj), TYPE_CPU)
>> -
>> -typedef struct CPUState CPUState;
>> -
>> -/**
>> - * CPUClass:
>> - * @reset: Callback to reset the #CPUState to its initial state.
>> - *
>> - * Represents a CPU family or model.
>> - */
>> -typedef struct CPUClass {
>> -    /*< private >*/
>> -    ObjectClass parent_class;
>> -    /*< public >*/
>> -
>> -    void (*reset)(CPUState *cpu);
>> -} CPUClass;
>> -
>> -/**
>> - * CPUState:
>> - *
>> - * State of one CPU core or thread.
>> - */
>> -struct CPUState {
>> -    /*< private >*/
>> -    Object parent_obj;
>> -    /*< public >*/
>> -
>> -    struct QemuThread *thread;
>> -#ifdef _WIN32
>> -    HANDLE hThread;
>> -#endif
>> -    bool thread_kicked;
>> -
>> -    /* TODO Move common fields from CPUArchState here. */
>> -};
>> -
>> -
>> -/**
>> - * cpu_reset:
>> - * @cpu: The CPU whose state is to be reset.
>> - */
>> -void cpu_reset(CPUState *cpu);
>
> As commented on IRC, I would prefer this to stay in a shared cpu.h since
> it is used identically for softmmu and *-user. Simplifies rewriting
> documentation or adding Error** or whatever.
>
> Same for TYPE_CPU and cast macros, they do not differ.
>
>> -
>> -
>> +#ifdef CONFIG_USER_ONLY
>> +#include "qemu/cpu-user.h"
>> +#else
>> +#include "qemu/cpu-softmmu.h"
>>  #endif
>> diff --git a/qemu-common.h b/qemu-common.h
>> index f9deca6..47a3aab 100644
>> --- a/qemu-common.h
>> +++ b/qemu-common.h
>> @@ -270,7 +270,6 @@ typedef struct PCIEPort PCIEPort;
>>  typedef struct PCIESlot PCIESlot;
>>  typedef struct MSIMessage MSIMessage;
>>  typedef struct SerialState SerialState;
>> -typedef struct IRQState *qemu_irq;
>>  typedef struct PCMCIACardState PCMCIACardState;
>>  typedef struct MouseTransformInfo MouseTransformInfo;
>>  typedef struct uWireSlave uWireSlave;
>> @@ -281,6 +280,8 @@ typedef struct VirtIODevice VirtIODevice;
>>  typedef struct QEMUSGList QEMUSGList;
>>  typedef struct SHPCDevice SHPCDevice;
>>  
>> +#include "hw/irq.h"
>
> Independent of cpu split?
>
>> +
>>  typedef uint64_t pcibus_t;
>>  
>>  typedef enum LostTickPolicy {
>> diff --git a/qom/Makefile.objs b/qom/Makefile.objs
>> index 5ef060a..a24fadf 100644
>> --- a/qom/Makefile.objs
>> +++ b/qom/Makefile.objs
>> @@ -1,4 +1,3 @@
>>  qom-obj-y = object.o container.o qom-qobject.o
>> -qom-obj-twice-y = cpu.o
>> -common-obj-y = $(qom-obj-twice-y)
>> -user-obj-y = $(qom-obj-twice-y)
>> +common-obj-y += $(qom-obj-y) cpu-softmmu.o
>> +user-obj-y += $(qom-obj-y) cpu-user.o
>
> This is silently making cpu.c unused without deleting it, no?
>
>> diff --git a/qom/cpu-softmmu.c b/qom/cpu-softmmu.c
>> new file mode 100644
>> index 0000000..5790944
>> --- /dev/null
>> +++ b/qom/cpu-softmmu.c
>> @@ -0,0 +1,66 @@
>> +/*
>> + * QEMU CPU model
>> + *
>> + * Copyright (c) 2012 SUSE LINUX Products GmbH
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License
>> + * as published by the Free Software Foundation; either version 2
>> + * of the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, see
>> + * <http://www.gnu.org/licenses/gpl-2.0.html>
>> + */
>> +
>> +#include "qemu/cpu.h"
>> +#include "qemu-common.h"
>> +#include "hw/qdev.h"
>> +
>> +void cpu_reset(CPUState *cpu)
>> +{
>> +    CPUClass *klass = CPU_GET_CLASS(cpu);
>> +
>> +    if (klass->reset != NULL) {
>> +        (*klass->reset)(cpu);
>> +    }
>> +}
>> +
>> +static void cpu_common_reset(CPUState *cpu)
>> +{
>> +}
>> +
>> +static int cpu_realize(DeviceState *dev)
>> +{
>> +    return 0;
>> +}
>> +
>> +static void cpu_class_init(ObjectClass *klass, void *data)
>> +{
>> +    CPUClass *k = CPU_CLASS(klass);
>> +    DeviceClass *dc = DEVICE_CLASS(klass);
>> +
>> +    k->reset = cpu_common_reset;
>> +    dc->init = cpu_realize;
>> +}
>> +
>> +static TypeInfo cpu_type_info = {
>
> const was/is missing... o;-)

Ack.

>
> Since this has been getting late - sorry - and there being no follow-ups
> for v1.2, what about applying patch 1/2 and deferring 2/2 to v1.3 /
> cpu-next?

I think we should apply 1/2 for 1.2.  For 1.3, we need a better solution
and I think the better solution is to do this split and insist on people
that care about linux-user doing the work to make qdev buildable.

I was concerned about this from the beginning (introducing qom into
linux-user).  I think we need to draw a line here and say that
linux-user needs to keep up with the rate of change here.  We can't
burden softmmu to do all the work on linux-user.

If anyone has a better idea about how to isolate linux-user here I'm all
for it but if it's going to need to interact with QOM, it needs to be
able to handle qdev and everything else that comes with it.

Regards,

Anthony Liguori

>
> Regards,
> Andreas
>
>> +    .name = TYPE_CPU,
>> +    .parent = TYPE_DEVICE,
>> +    .instance_size = sizeof(CPUState),
>> +    .abstract = true,
>> +    .class_size = sizeof(CPUClass),
>> +    .class_init = cpu_class_init,
>> +};
>> +
>> +static void cpu_register_types(void)
>> +{
>> +    type_register_static(&cpu_type_info);
>> +}
>> +
>> +type_init(cpu_register_types)
>> diff --git a/qom/cpu-user.c b/qom/cpu-user.c
>> new file mode 100644
>> index 0000000..17b796f
>> --- /dev/null
>> +++ b/qom/cpu-user.c
>> @@ -0,0 +1,70 @@
>> +/*
>> + * QEMU CPU model
>> + *
>> + * Copyright (c) 2012 SUSE LINUX Products GmbH
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License
>> + * as published by the Free Software Foundation; either version 2
>> + * of the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, see
>> + * <http://www.gnu.org/licenses/gpl-2.0.html>
>> + */
>> +
>> +#include "qemu/cpu.h"
>> +#include "qemu-common.h"
>> +
>> +void cpu_reset(CPUState *cpu)
>> +{
>> +    CPUClass *klass = CPU_GET_CLASS(cpu);
>> +
>> +    if (klass->reset != NULL) {
>> +        (*klass->reset)(cpu);
>> +    }
>> +}
>> +
>> +static void cpu_common_reset(CPUState *cpu)
>> +{
>> +}
>> +
>> +static void cpu_class_init(ObjectClass *klass, void *data)
>> +{
>> +#ifndef CONFIG_USER_ONLY
>> +    DeviceClass *dc = DEVICE_CLASS(klass);
>> +#endif
>> +    CPUClass *k = CPU_CLASS(klass);
>> +
>> +#ifndef CONFIG_USER_ONLY
>> +    /* Overwrite this in subclasses for which hotplug is supported. */
>> +    dc->no_user = 1;
>> +#endif
>> +
>> +    k->reset = cpu_common_reset;
>> +}
>> +
>> +static TypeInfo cpu_type_info = {
>> +    .name = TYPE_CPU,
>> +#ifdef CONFIG_USER_ONLY
>> +    .parent = TYPE_OBJECT,
>> +#else
>> +    .parent = TYPE_DEVICE,
>> +#endif
>> +    .instance_size = sizeof(CPUState),
>> +    .abstract = true,
>> +    .class_size = sizeof(CPUClass),
>> +    .class_init = cpu_class_init,
>> +};
>> +
>> +static void cpu_register_types(void)
>> +{
>> +    type_register_static(&cpu_type_info);
>> +}
>> +
>> +type_init(cpu_register_types)
>
>
> -- 
> SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
> GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

Patch

diff --git a/Makefile.objs b/Makefile.objs
index 5ebbcfa..f285926 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -12,12 +12,6 @@  qobject-obj-y += qerror.o error.o qemu-error.o
 universal-obj-y += $(qobject-obj-y)
 
 #######################################################################
-# QOM
-qom-obj-y = qom/
-
-universal-obj-y += $(qom-obj-y)
-
-#######################################################################
 # oslib-obj-y is code depending on the OS (win32 vs posix)
 oslib-obj-y = osdep.o
 oslib-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o
diff --git a/hw/armv7m.c b/hw/armv7m.c
index 8cec78d..2e8fa06 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -188,6 +188,7 @@  qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
 
 #if 0
diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index eab6327..f34fe8a 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -265,6 +265,7 @@  void axisdev88_init (ram_addr_t ram_size,
         cpu_model = "crisv32";
     }
     cpu = cpu_cris_init(cpu_model);
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
 
     /* allocate RAM */
diff --git a/hw/exynos4210.c b/hw/exynos4210.c
index 00d4db8..aca8738 100644
--- a/hw/exynos4210.c
+++ b/hw/exynos4210.c
@@ -122,6 +122,7 @@  Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
             fprintf(stderr, "Unable to find CPU %d definition\n", n);
             exit(1);
         }
+        qdev_init_nofail(DEVICE(s->cpu[n]));
 
         /* Create PIC controller for each processor instance */
         irqp = arm_pic_init_cpu(s->cpu[n]);
diff --git a/hw/highbank.c b/hw/highbank.c
index 11aa131..8f66f70 100644
--- a/hw/highbank.c
+++ b/hw/highbank.c
@@ -214,6 +214,7 @@  static void highbank_init(ram_addr_t ram_size,
             fprintf(stderr, "Unable to find CPU definition\n");
             exit(1);
         }
+        qdev_init_nofail(DEVICE(cpu));
 
         /* This will become a QOM property eventually */
         cpu->reset_cbar = GIC_BASE_ADDR;
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index d0e2e90..e19d745 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -460,6 +460,7 @@  static void integratorcp_init(ram_addr_t ram_size,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
 
     memory_region_init_ram(ram, "integrator.ram", ram_size);
     vmstate_register_ram_global(ram);
diff --git a/hw/leon3.c b/hw/leon3.c
index 878d3aa..6d79631 100644
--- a/hw/leon3.c
+++ b/hw/leon3.c
@@ -123,6 +123,7 @@  static void leon3_generic_hw_init(ram_addr_t  ram_size,
         fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
 
     cpu_sparc_set_id(env, 0);
diff --git a/hw/lm32_boards.c b/hw/lm32_boards.c
index b76d800..319580b 100644
--- a/hw/lm32_boards.c
+++ b/hw/lm32_boards.c
@@ -103,6 +103,7 @@  static void lm32_evr_init(ram_addr_t ram_size_not_used,
         cpu_model = "lm32-full";
     }
     cpu = cpu_lm32_init(cpu_model);
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
     reset_info->cpu = cpu;
 
@@ -200,6 +201,7 @@  static void lm32_uclinux_init(ram_addr_t ram_size_not_used,
         cpu_model = "lm32-full";
     }
     cpu = cpu_lm32_init(cpu_model);
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
     reset_info->cpu = cpu;
 
diff --git a/hw/milkymist.c b/hw/milkymist.c
index 2e7235b..959495c 100644
--- a/hw/milkymist.c
+++ b/hw/milkymist.c
@@ -107,6 +107,7 @@  milkymist_init(ram_addr_t ram_size_not_used,
         cpu_model = "lm32-full";
     }
     cpu = cpu_lm32_init(cpu_model);
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
     reset_info->cpu = cpu;
 
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
index 38e4b86..a8a28a0 100644
--- a/hw/mips_fulong2e.c
+++ b/hw/mips_fulong2e.c
@@ -285,6 +285,7 @@  static void mips_fulong2e_init(ram_addr_t ram_size, const char *boot_device,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
 
     qemu_register_reset(main_cpu_reset, cpu);
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index db927f1..c0eee7c 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -147,6 +147,7 @@  static void mips_jazz_init(MemoryRegion *address_space,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
     qemu_register_reset(main_cpu_reset, cpu);
 
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 351c88e..8c98265 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -833,6 +833,7 @@  void mips_malta_init (ram_addr_t ram_size,
             fprintf(stderr, "Unable to find CPU definition\n");
             exit(1);
         }
+        qdev_init_nofail(DEVICE(cpu));
         env = &cpu->env;
 
         /* Init internal devices */
diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c
index 830f635..d164203 100644
--- a/hw/mips_mipssim.c
+++ b/hw/mips_mipssim.c
@@ -158,6 +158,7 @@  mips_mipssim_init (ram_addr_t ram_size,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
 
     reset_info = g_malloc0(sizeof(ResetData));
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 967a76e..6ae690a 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -185,6 +185,7 @@  void mips_r4k_init (ram_addr_t ram_size,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
 
     reset_info = g_malloc0(sizeof(ResetData));
diff --git a/hw/musicpal.c b/hw/musicpal.c
index ad725b5..c2f42f2 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1538,6 +1538,7 @@  static void musicpal_init(ram_addr_t ram_size,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
     cpu_pic = arm_pic_init_cpu(cpu);
 
     /* For now we use a fixed - the original - RAM size */
diff --git a/hw/omap1.c b/hw/omap1.c
index ad60cc4..c20cfda 100644
--- a/hw/omap1.c
+++ b/hw/omap1.c
@@ -3836,6 +3836,7 @@  struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(s->cpu));
     s->sdram_size = sdram_size;
     s->sram_size = OMAP15XX_SRAM_SIZE;
 
diff --git a/hw/omap2.c b/hw/omap2.c
index 4278dd1..aee94a3 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -2258,6 +2258,7 @@  struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(s->cpu));
     s->sdram_size = sdram_size;
     s->sram_size = OMAP242X_SRAM_SIZE;
 
diff --git a/hw/pc.c b/hw/pc.c
index 81c391c..b1f163e 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -915,6 +915,7 @@  static X86CPU *pc_new_cpu(const char *cpu_model)
         fprintf(stderr, "Unable to find x86 CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
     if ((env->cpuid_features & CPUID_APIC) || smp_cpus > 1) {
         env->apic_state = apic_init(env, env->cpuid_apic_id);
diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
index 6a7d0c0..173fb54 100644
--- a/hw/petalogix_ml605_mmu.c
+++ b/hw/petalogix_ml605_mmu.c
@@ -91,6 +91,7 @@  petalogix_ml605_init(ram_addr_t ram_size,
         cpu_model = "microblaze";
     }
     cpu = cpu_mb_init(cpu_model);
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
 
     /* Attach emulated BRAM through the LMB.  */
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index 2cf6882..1984187 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -79,6 +79,7 @@  petalogix_s3adsp1800_init(ram_addr_t ram_size,
         cpu_model = "microblaze";
     }
     cpu = cpu_mb_init(cpu_model);
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
 
     /* Attach emulated BRAM through the LMB.  */
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index 0dd4dab..cf67b06 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -192,6 +192,7 @@  static void bamboo_init(ram_addr_t ram_size,
         fprintf(stderr, "Unable to initialize CPU!\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
 
     qemu_register_reset(main_cpu_reset, cpu);
diff --git a/hw/ppc4xx_devs.c b/hw/ppc4xx_devs.c
index 41163e6..34f4172 100644
--- a/hw/ppc4xx_devs.c
+++ b/hw/ppc4xx_devs.c
@@ -61,6 +61,7 @@  CPUPPCState *ppc4xx_init (const char *cpu_model,
                 cpu_model);
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
 
     cpu_clk->cb = NULL; /* We don't care about CPU clock frequency changes */
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 4e2a6e6..b1d05fd 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -172,6 +172,7 @@  static void ppc_core99_init (ram_addr_t ram_size,
             fprintf(stderr, "Unable to find PowerPC CPU definition\n");
             exit(1);
         }
+        qdev_init_nofail(DEVICE(cpu));
         env = &cpu->env;
 
         /* Set time-base frequency to 100 Mhz */
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index f2c6908..955e961 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -110,6 +110,7 @@  static void ppc_heathrow_init (ram_addr_t ram_size,
             fprintf(stderr, "Unable to find PowerPC CPU definition\n");
             exit(1);
         }
+        qdev_init_nofail(DEVICE(cpu));
         env = &cpu->env;
 
         /* Set time-base frequency to 16.6 Mhz */
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index be2b268..649df80 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -493,6 +493,7 @@  static void ppc_prep_init (ram_addr_t ram_size,
             fprintf(stderr, "Unable to find PowerPC CPU definition\n");
             exit(1);
         }
+        qdev_init_nofail(DEVICE(cpu));
         env = &cpu->env;
 
         if (env->flags & POWERPC_FLAG_RTC_CLK) {
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 8b9fd83..130764f 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -458,6 +458,7 @@  static void mpc8544ds_init(ram_addr_t ram_size,
             fprintf(stderr, "Unable to initialize CPU!\n");
             exit(1);
         }
+        qdev_init_nofail(DEVICE(cpu));
         env = &cpu->env;
 
         if (!firstenv) {
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index d5f1420..3a5e79a 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -2021,6 +2021,7 @@  PXA2xxState *pxa270_init(MemoryRegion *address_space,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(s->cpu));
     s->reset = qemu_allocate_irqs(pxa2xx_reset, s, 1)[0];
 
     /* SDRAM & Internal Memory Storage */
diff --git a/hw/r2d.c b/hw/r2d.c
index 0f16e81..d820241 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -245,6 +245,7 @@  static void r2d_init(ram_addr_t ram_size,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
 
     reset_info = g_malloc0(sizeof(ResetData));
diff --git a/hw/realview.c b/hw/realview.c
index 19db4d0..469db99 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -94,6 +94,7 @@  static void realview_init(ram_addr_t ram_size,
             fprintf(stderr, "Unable to find CPU definition\n");
             exit(1);
         }
+        qdev_init_nofail(DEVICE(cpu));
         irqp = arm_pic_init_cpu(cpu);
         cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
     }
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 47eed35..9566aab 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -213,6 +213,7 @@  static void s390_init(ram_addr_t my_ram_size,
         CPUS390XState *tmp_env;
 
         cpu = cpu_s390x_init(cpu_model);
+        qdev_init_nofail(DEVICE(cpu));
         tmp_env = &cpu->env;
         if (!env) {
             env = tmp_env;
diff --git a/hw/spapr.c b/hw/spapr.c
index 81c9343..660246e 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -612,6 +612,7 @@  static void ppc_spapr_init(ram_addr_t ram_size,
             fprintf(stderr, "Unable to find PowerPC CPU definition\n");
             exit(1);
         }
+        qdev_init_nofail(DEVICE(cpu));
         env = &cpu->env;
 
         /* Set time-base frequency to 512 MHz */
diff --git a/hw/strongarm.c b/hw/strongarm.c
index 7150eeb..ccc3ec6 100644
--- a/hw/strongarm.c
+++ b/hw/strongarm.c
@@ -1569,6 +1569,7 @@  StrongARMState *sa1110_init(MemoryRegion *sysmem,
         error_report("Unable to find CPU definition");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(s->cpu));
 
     memory_region_init_ram(&s->sdram, "strongarm.sdram", sdram_size);
     vmstate_register_ram_global(&s->sdram);
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 0f909b5..ea2405d 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -819,6 +819,7 @@  static void cpu_devinit(const char *cpu_model, unsigned int id,
         fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
 
     cpu_sparc_set_id(env, id);
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 137a7c6..48ef0a3 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -770,6 +770,7 @@  static SPARCCPU *cpu_devinit(const char *cpu_model, const struct hwdef *hwdef)
         fprintf(stderr, "Unable to find Sparc CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
 
     env->tick = cpu_timer_create("tick", env, tick_irq,
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 4fd5d9b..7c113a2 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -197,6 +197,7 @@  static void versatile_init(ram_addr_t ram_size,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
     memory_region_init_ram(ram, "versatile.ram", ram_size);
     vmstate_register_ram_global(ram);
     /* ??? RAM should repeat to fill physical memory space.  */
diff --git a/hw/vexpress.c b/hw/vexpress.c
index b615844..8a30696 100644
--- a/hw/vexpress.c
+++ b/hw/vexpress.c
@@ -181,6 +181,7 @@  static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
             fprintf(stderr, "Unable to find CPU definition\n");
             exit(1);
         }
+        qdev_init_nofail(DEVICE(cpu));
         irqp = arm_pic_init_cpu(cpu);
         cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
     }
@@ -280,6 +281,7 @@  static void a15_daughterboard_init(const VEDBoardInfo *daughterboard,
             fprintf(stderr, "Unable to find CPU definition\n");
             exit(1);
         }
+        qdev_init_nofail(DEVICE(cpu));
         irqp = arm_pic_init_cpu(cpu);
         cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
     }
diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c
index 79bc0d1..c356400 100644
--- a/hw/virtex_ml507.c
+++ b/hw/virtex_ml507.c
@@ -92,6 +92,7 @@  static PowerPCCPU *ppc440_init_xilinx(ram_addr_t *ram_size,
         fprintf(stderr, "Unable to initialize CPU!\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
 
     ppc_booke_timers_init(env, sysclk, 0/* no flags */);
diff --git a/hw/xen_machine_pv.c b/hw/xen_machine_pv.c
index 4b72aa7..4017f43 100644
--- a/hw/xen_machine_pv.c
+++ b/hw/xen_machine_pv.c
@@ -50,6 +50,7 @@  static void xen_init_pv(ram_addr_t ram_size,
 #endif
     }
     cpu = cpu_x86_init(cpu_model);
+    qdev_init_nofail(DEVICE(cpu));
     env = &cpu->env;
     env->halted = 1;
 
diff --git a/hw/xilinx_zynq.c b/hw/xilinx_zynq.c
index 7e6c273..537351c 100644
--- a/hw/xilinx_zynq.c
+++ b/hw/xilinx_zynq.c
@@ -71,6 +71,7 @@  static void zynq_init(ram_addr_t ram_size, const char *boot_device,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
+    qdev_init_nofail(DEVICE(cpu));
     irqp = arm_pic_init_cpu(cpu);
     cpu_irq = irqp[ARM_PIC_CPU_IRQ];
 
diff --git a/hw/xtensa_lx60.c b/hw/xtensa_lx60.c
index 3653f65..9bde624 100644
--- a/hw/xtensa_lx60.c
+++ b/hw/xtensa_lx60.c
@@ -182,6 +182,7 @@  static void lx_init(const LxBoardDesc *board,
             fprintf(stderr, "Unable to find CPU definition\n");
             exit(1);
         }
+        qdev_init_nofail(DEVICE(cpu));
         env = &cpu->env;
 
         env->sregs[PRID] = n;
diff --git a/hw/xtensa_sim.c b/hw/xtensa_sim.c
index 831460b..6eb8ea1 100644
--- a/hw/xtensa_sim.c
+++ b/hw/xtensa_sim.c
@@ -60,6 +60,7 @@  static void sim_init(ram_addr_t ram_size,
             fprintf(stderr, "Unable to find CPU definition\n");
             exit(1);
         }
+        qdev_init_nofail(DEVICE(cpu));
         env = &cpu->env;
 
         env->sregs[PRID] = n;
diff --git a/include/qemu/cpu-softmmu.h b/include/qemu/cpu-softmmu.h
new file mode 100644
index 0000000..4f7b602
--- /dev/null
+++ b/include/qemu/cpu-softmmu.h
@@ -0,0 +1,82 @@ 
+/*
+ * QEMU CPU model
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
+ */
+#ifndef QEMU_CPU_H
+#define QEMU_CPU_H
+
+#include "hw/qdev-core.h"
+#include "qemu-thread.h"
+
+/**
+ * SECTION:cpu
+ * @section_id: QEMU-cpu
+ * @title: CPU Class
+ * @short_description: Base class for all CPUs
+ */
+
+#define TYPE_CPU "cpu"
+
+#define CPU(obj) OBJECT_CHECK(CPUState, (obj), TYPE_CPU)
+#define CPU_CLASS(class) OBJECT_CLASS_CHECK(CPUClass, (class), TYPE_CPU)
+#define CPU_GET_CLASS(obj) OBJECT_GET_CLASS(CPUClass, (obj), TYPE_CPU)
+
+typedef struct CPUState CPUState;
+
+/**
+ * CPUClass:
+ * @reset: Callback to reset the #CPUState to its initial state.
+ *
+ * Represents a CPU family or model.
+ */
+typedef struct CPUClass {
+    /*< private >*/
+    DeviceClass parent_class;
+    /*< public >*/
+
+    void (*reset)(CPUState *cpu);
+} CPUClass;
+
+/**
+ * CPUState:
+ *
+ * State of one CPU core or thread.
+ */
+struct CPUState {
+    /*< private >*/
+    DeviceState parent_obj;
+    /*< public >*/
+
+    struct QemuThread *thread;
+#ifdef _WIN32
+   HANDLE hThread;
+#endif
+    bool thread_kicked;
+
+    /* TODO Move common fields from CPUArchState here. */
+};
+
+
+/**
+ * cpu_reset:
+ * @cpu: The CPU whose state is to be reset.
+ */
+void cpu_reset(CPUState *cpu);
+
+
+#endif
diff --git a/include/qemu/cpu-user.h b/include/qemu/cpu-user.h
new file mode 100644
index 0000000..78b65b3
--- /dev/null
+++ b/include/qemu/cpu-user.h
@@ -0,0 +1,75 @@ 
+/*
+ * QEMU CPU model
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
+ */
+#ifndef QEMU_CPU_H
+#define QEMU_CPU_H
+
+#include "qemu/object.h"
+
+/**
+ * SECTION:cpu
+ * @section_id: QEMU-cpu
+ * @title: CPU Class
+ * @short_description: Base class for all CPUs
+ */
+
+#define TYPE_CPU "cpu"
+
+#define CPU(obj) OBJECT_CHECK(CPUState, (obj), TYPE_CPU)
+#define CPU_CLASS(class) OBJECT_CLASS_CHECK(CPUClass, (class), TYPE_CPU)
+#define CPU_GET_CLASS(obj) OBJECT_GET_CLASS(CPUClass, (obj), TYPE_CPU)
+
+typedef struct CPUState CPUState;
+
+/**
+ * CPUClass:
+ * @reset: Callback to reset the #CPUState to its initial state.
+ *
+ * Represents a CPU family or model.
+ */
+typedef struct CPUClass {
+    /*< private >*/
+    ObjectClass parent_class;
+    /*< public >*/
+
+    void (*reset)(CPUState *cpu);
+} CPUClass;
+
+/**
+ * CPUState:
+ *
+ * State of one CPU core or thread.
+ */
+struct CPUState {
+    /*< private >*/
+    Object parent_obj;
+    /*< public >*/
+
+    /* TODO Move common fields from CPUArchState here. */
+};
+
+
+/**
+ * cpu_reset:
+ * @cpu: The CPU whose state is to be reset.
+ */
+void cpu_reset(CPUState *cpu);
+
+
+#endif
diff --git a/include/qemu/cpu.h b/include/qemu/cpu.h
index ad706a6..862988a 100644
--- a/include/qemu/cpu.h
+++ b/include/qemu/cpu.h
@@ -1,82 +1,5 @@ 
-/*
- * QEMU CPU model
- *
- * Copyright (c) 2012 SUSE LINUX Products GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see
- * <http://www.gnu.org/licenses/gpl-2.0.html>
- */
-#ifndef QEMU_CPU_H
-#define QEMU_CPU_H
-
-#include "qemu/object.h"
-#include "qemu-thread.h"
-
-/**
- * SECTION:cpu
- * @section_id: QEMU-cpu
- * @title: CPU Class
- * @short_description: Base class for all CPUs
- */
-
-#define TYPE_CPU "cpu"
-
-#define CPU(obj) OBJECT_CHECK(CPUState, (obj), TYPE_CPU)
-#define CPU_CLASS(class) OBJECT_CLASS_CHECK(CPUClass, (class), TYPE_CPU)
-#define CPU_GET_CLASS(obj) OBJECT_GET_CLASS(CPUClass, (obj), TYPE_CPU)
-
-typedef struct CPUState CPUState;
-
-/**
- * CPUClass:
- * @reset: Callback to reset the #CPUState to its initial state.
- *
- * Represents a CPU family or model.
- */
-typedef struct CPUClass {
-    /*< private >*/
-    ObjectClass parent_class;
-    /*< public >*/
-
-    void (*reset)(CPUState *cpu);
-} CPUClass;
-
-/**
- * CPUState:
- *
- * State of one CPU core or thread.
- */
-struct CPUState {
-    /*< private >*/
-    Object parent_obj;
-    /*< public >*/
-
-    struct QemuThread *thread;
-#ifdef _WIN32
-    HANDLE hThread;
-#endif
-    bool thread_kicked;
-
-    /* TODO Move common fields from CPUArchState here. */
-};
-
-
-/**
- * cpu_reset:
- * @cpu: The CPU whose state is to be reset.
- */
-void cpu_reset(CPUState *cpu);
-
-
+#ifdef CONFIG_USER_ONLY
+#include "qemu/cpu-user.h"
+#else
+#include "qemu/cpu-softmmu.h"
 #endif
diff --git a/qemu-common.h b/qemu-common.h
index f9deca6..47a3aab 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -270,7 +270,6 @@  typedef struct PCIEPort PCIEPort;
 typedef struct PCIESlot PCIESlot;
 typedef struct MSIMessage MSIMessage;
 typedef struct SerialState SerialState;
-typedef struct IRQState *qemu_irq;
 typedef struct PCMCIACardState PCMCIACardState;
 typedef struct MouseTransformInfo MouseTransformInfo;
 typedef struct uWireSlave uWireSlave;
@@ -281,6 +280,8 @@  typedef struct VirtIODevice VirtIODevice;
 typedef struct QEMUSGList QEMUSGList;
 typedef struct SHPCDevice SHPCDevice;
 
+#include "hw/irq.h"
+
 typedef uint64_t pcibus_t;
 
 typedef enum LostTickPolicy {
diff --git a/qom/Makefile.objs b/qom/Makefile.objs
index 5ef060a..a24fadf 100644
--- a/qom/Makefile.objs
+++ b/qom/Makefile.objs
@@ -1,4 +1,3 @@ 
 qom-obj-y = object.o container.o qom-qobject.o
-qom-obj-twice-y = cpu.o
-common-obj-y = $(qom-obj-twice-y)
-user-obj-y = $(qom-obj-twice-y)
+common-obj-y += $(qom-obj-y) cpu-softmmu.o
+user-obj-y += $(qom-obj-y) cpu-user.o
diff --git a/qom/cpu-softmmu.c b/qom/cpu-softmmu.c
new file mode 100644
index 0000000..5790944
--- /dev/null
+++ b/qom/cpu-softmmu.c
@@ -0,0 +1,66 @@ 
+/*
+ * QEMU CPU model
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
+ */
+
+#include "qemu/cpu.h"
+#include "qemu-common.h"
+#include "hw/qdev.h"
+
+void cpu_reset(CPUState *cpu)
+{
+    CPUClass *klass = CPU_GET_CLASS(cpu);
+
+    if (klass->reset != NULL) {
+        (*klass->reset)(cpu);
+    }
+}
+
+static void cpu_common_reset(CPUState *cpu)
+{
+}
+
+static int cpu_realize(DeviceState *dev)
+{
+    return 0;
+}
+
+static void cpu_class_init(ObjectClass *klass, void *data)
+{
+    CPUClass *k = CPU_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    k->reset = cpu_common_reset;
+    dc->init = cpu_realize;
+}
+
+static TypeInfo cpu_type_info = {
+    .name = TYPE_CPU,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(CPUState),
+    .abstract = true,
+    .class_size = sizeof(CPUClass),
+    .class_init = cpu_class_init,
+};
+
+static void cpu_register_types(void)
+{
+    type_register_static(&cpu_type_info);
+}
+
+type_init(cpu_register_types)
diff --git a/qom/cpu-user.c b/qom/cpu-user.c
new file mode 100644
index 0000000..17b796f
--- /dev/null
+++ b/qom/cpu-user.c
@@ -0,0 +1,70 @@ 
+/*
+ * QEMU CPU model
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
+ */
+
+#include "qemu/cpu.h"
+#include "qemu-common.h"
+
+void cpu_reset(CPUState *cpu)
+{
+    CPUClass *klass = CPU_GET_CLASS(cpu);
+
+    if (klass->reset != NULL) {
+        (*klass->reset)(cpu);
+    }
+}
+
+static void cpu_common_reset(CPUState *cpu)
+{
+}
+
+static void cpu_class_init(ObjectClass *klass, void *data)
+{
+#ifndef CONFIG_USER_ONLY
+    DeviceClass *dc = DEVICE_CLASS(klass);
+#endif
+    CPUClass *k = CPU_CLASS(klass);
+
+#ifndef CONFIG_USER_ONLY
+    /* Overwrite this in subclasses for which hotplug is supported. */
+    dc->no_user = 1;
+#endif
+
+    k->reset = cpu_common_reset;
+}
+
+static TypeInfo cpu_type_info = {
+    .name = TYPE_CPU,
+#ifdef CONFIG_USER_ONLY
+    .parent = TYPE_OBJECT,
+#else
+    .parent = TYPE_DEVICE,
+#endif
+    .instance_size = sizeof(CPUState),
+    .abstract = true,
+    .class_size = sizeof(CPUClass),
+    .class_init = cpu_class_init,
+};
+
+static void cpu_register_types(void)
+{
+    type_register_static(&cpu_type_info);
+}
+
+type_init(cpu_register_types)