[Spice-commits] 87 commits - VERSION audio/ossaudio.c block/qcow2-cluster.c configure cpus.c default-configs/arm-softmmu.mak docs/memory.txt exec.c gdbstub.c hw/Makefile.objs hw/acpi hw/arm hw/block hw/char hw/core hw/cpu hw/cris hw/display hw/i386 hw/ide hw/intc hw/lm32 hw/m68k hw/mips hw/misc hw/net hw/pci hw/pcmcia hw/s390x hw/scsi hw/sh4 hw/sparc hw/timer hw/unicore32 hw/usb hw/virtio hw/xen include/hw include/qemu include/qom qapi/qapi-dealloc-visitor.c qdev-monitor.c tests/Makefile tests/endianness-test.c tests/qom-test.c tests/test-bitops.c tests/test-opts-visitor.c tests/test-qmp-input-visitor.c ui/sdl.c vl.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Thu Nov 14 01:32:20 PST 2013


 VERSION                          |    2 
 audio/ossaudio.c                 |    2 
 block/qcow2-cluster.c            |    2 
 configure                        |   40 +----
 cpus.c                           |   42 +++--
 default-configs/arm-softmmu.mak  |    1 
 docs/memory.txt                  |   64 ++++++++
 exec.c                           |    7 
 gdbstub.c                        |    3 
 hw/Makefile.objs                 |    1 
 hw/acpi/core.c                   |    3 
 hw/acpi/piix4.c                  |    2 
 hw/arm/armv7m.c                  |   25 +--
 hw/arm/exynos4_boards.c          |    3 
 hw/arm/gumstix.c                 |   11 -
 hw/arm/mainstone.c               |    5 
 hw/arm/omap_sx1.c                |    3 
 hw/arm/palm.c                    |    3 
 hw/arm/z2.c                      |    5 
 hw/block/cdrom.c                 |   10 -
 hw/block/tc58128.c               |   10 -
 hw/char/milkymist-uart.c         |   24 +--
 hw/core/qdev.c                   |   12 -
 hw/cpu/Makefile.objs             |    1 
 hw/cpu/a15mpcore.c               |   81 +++++------
 hw/cpu/a9mpcore.c                |  120 +++++++++-------
 hw/cpu/arm11mpcore.c             |  251 +++++++++-------------------------
 hw/cpu/realview_mpcore.c         |  139 +++++++++++++++++++
 hw/cris/axis_dev88.c             |   11 -
 hw/display/qxl.c                 |   33 ----
 hw/display/qxl.h                 |    3 
 hw/display/vga.c                 |    1 
 hw/display/vga_template.h        |   14 +
 hw/i386/pc.c                     |   47 +++---
 hw/i386/pc_piix.c                |    2 
 hw/ide/atapi.c                   |   16 +-
 hw/ide/core.c                    |   49 ------
 hw/ide/internal.h                |    2 
 hw/ide/microdrive.c              |  226 +++++++++++++++++++++----------
 hw/intc/arm_gic_common.c         |   18 +-
 hw/intc/gic_internal.h           |   80 -----------
 hw/intc/realview_gic.c           |   58 ++++---
 hw/lm32/milkymist.c              |    3 
 hw/m68k/an5206.c                 |    4 
 hw/m68k/mcf5208.c                |    4 
 hw/mips/mips_mipssim.c           |    4 
 hw/misc/Makefile.objs            |    4 
 hw/misc/a9scu.c                  |   25 ---
 hw/misc/arm11scu.c               |  100 +++++++++++++
 hw/misc/pxa2xx_pcmcia.c          |  207 ----------------------------
 hw/net/e1000.c                   |   24 +--
 hw/net/ne2000.c                  |    4 
 hw/net/rtl8139.c                 |    5 
 hw/net/virtio-net.c              |    2 
 hw/pci/pci-hotplug-old.c         |    2 
 hw/pci/pci_bridge.c              |    2 
 hw/pci/pcie.c                    |    2 
 hw/pci/pcie_aer.c                |    4 
 hw/pci/shpc.c                    |    2 
 hw/pcmcia/Makefile.objs          |    2 
 hw/pcmcia/pcmcia.c               |   24 +++
 hw/pcmcia/pxa2xx.c               |  283 +++++++++++++++++++++++++++++++++++++++
 hw/s390x/virtio-ccw.c            |    2 
 hw/scsi/scsi-bus.c               |    6 
 hw/sh4/shix.c                    |   16 --
 hw/sparc/leon3.c                 |    3 
 hw/timer/arm_mptimer.c           |   60 ++------
 hw/timer/mc146818rtc.c           |    9 -
 hw/unicore32/puv3.c              |    4 
 hw/usb/bus.c                     |    7 
 hw/usb/dev-storage.c             |    2 
 hw/usb/host-legacy.c             |    2 
 hw/virtio/virtio-bus.c           |    4 
 hw/xen/xen_platform.c            |    2 
 include/hw/arm/pxa.h             |    2 
 include/hw/cpu/a15mpcore.h       |   44 ++++++
 include/hw/cpu/a9mpcore.h        |   37 +++++
 include/hw/cpu/arm11mpcore.h     |   35 ++++
 include/hw/intc/arm_gic.h        |   42 +++++
 include/hw/intc/arm_gic_common.h |   92 ++++++++++++
 include/hw/intc/realview_gic.h   |   28 +++
 include/hw/misc/a9scu.h          |   31 ++++
 include/hw/misc/arm11scu.h       |   29 +++
 include/hw/pci/pci.h             |    8 -
 include/hw/pcmcia.h              |   46 ++++--
 include/hw/qdev-core.h           |    1 
 include/hw/timer/arm_mptimer.h   |   54 +++++++
 include/qemu/bswap.h             |   47 ------
 include/qom/object.h             |   73 +++++++---
 qapi/qapi-dealloc-visitor.c      |   20 ++
 qdev-monitor.c                   |   63 +++++---
 tests/Makefile                   |   26 +++
 tests/endianness-test.c          |    3 
 tests/qom-test.c                 |  253 ++++++++++++++++++++++++++++++++++
 tests/test-bitops.c              |    4 
 tests/test-opts-visitor.c        |    2 
 tests/test-qmp-input-visitor.c   |    1 
 ui/sdl.c                         |   23 ++-
 vl.c                             |    6 
 99 files changed, 2086 insertions(+), 1140 deletions(-)

New commits:
commit 964668b03d26f0b5baa5e5aff0c966f4fcb76e9e
Author: Anthony Liguori <aliguori at amazon.com>
Date:   Wed Nov 6 21:49:39 2013 -0800

    Update version for 1.7.0-rc0 release
    
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/VERSION b/VERSION
index 0a8112b..86e63cc 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.6.50
+1.6.90
commit 898ae2846de4dcb19da0b80f99ef2215dd137e56
Author: Lei Li <lilei at linux.vnet.ibm.com>
Date:   Wed Sep 4 17:07:16 2013 +0800

    sdl: Reverse support for video mode setting
    
    Currently, If the setting of video mode failed, qemu will exit. It
    should go back to the previous setting if the new screen resolution
    failed. This patch fixes LP#1216368, add support to revert to existing
    surface for the failure of video mode setting.
    
    Reported-by: Sascha Krissler <sascha at srlabs.de>
    Signed-off-by: Lei Li <lilei at linux.vnet.ibm.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1378285636-7091-1-git-send-email-lilei at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/ui/sdl.c b/ui/sdl.c
index 39a42d6..9d8583c 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -86,6 +86,7 @@ static void sdl_update(DisplayChangeListener *dcl,
 static void do_sdl_resize(int width, int height, int bpp)
 {
     int flags;
+    SDL_Surface *tmp_screen;
 
     //    printf("resizing to %d %d\n", w, h);
 
@@ -98,12 +99,26 @@ static void do_sdl_resize(int width, int height, int bpp)
     if (gui_noframe)
         flags |= SDL_NOFRAME;
 
-    real_screen = SDL_SetVideoMode(width, height, bpp, flags);
+    tmp_screen = SDL_SetVideoMode(width, height, bpp, flags);
     if (!real_screen) {
-	fprintf(stderr, "Could not open SDL display (%dx%dx%d): %s\n", width, 
-		height, bpp, SDL_GetError());
-        exit(1);
+        if (!tmp_screen) {
+            fprintf(stderr, "Could not open SDL display (%dx%dx%d): %s\n",
+                    width, height, bpp, SDL_GetError());
+            exit(1);
+        }
+    } else {
+        /*
+         * Revert to the previous video mode if the change of resizing or
+         * resolution failed.
+         */
+        if (!tmp_screen) {
+            fprintf(stderr, "Failed to set SDL display (%dx%dx%d): %s\n",
+                    width, height, bpp, SDL_GetError());
+            return;
+        }
     }
+
+    real_screen = tmp_screen;
 }
 
 static void sdl_switch(DisplayChangeListener *dcl,
commit 5f3e31012e334f3410e04abae7f88565df17c91a
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Oct 28 17:32:18 2013 +0100

    timers: fix stop/cont with -icount
    
    Stop/cont commands are broken with -icount due to a deadlock.  The
    real problem is that the computation of timers_state.cpu_ticks_offset
    makes no sense with -icount enabled: we set it to an icount clock value
    in cpu_disable_ticks, and subtract a TSC (or similar, whatever
    cpu_get_real_ticks happens to return) value in cpu_enable_ticks.
    
    The fix is simple.  timers_state.cpu_ticks_offset is only used
    together with cpu_get_real_ticks, so we can use cpu_get_real_ticks
    in cpu_disable_ticks.  There is no need to update cpu_ticks_prev
    at the time cpu_disable_ticks is called; instead, we can do it
    the next time cpu_get_ticks is called.
    
    The change to cpu_disable_ticks is the important part of the patch.
    The rest modifies the code to always check timers_state.cpu_ticks_prev,
    even when the ticks are not advancing (i.e. the VM is stopped).  It also
    makes a similar change to cpu_get_clock_locked, so that the code remains
    similar for cpu_get_ticks and cpu_get_clock_locked.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1382977938-13844-1-git-send-email-pbonzini at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/cpus.c b/cpus.c
index 912938c..01d128d 100644
--- a/cpus.c
+++ b/cpus.c
@@ -165,36 +165,38 @@ int64_t cpu_get_icount(void)
 /* Caller must hold the BQL */
 int64_t cpu_get_ticks(void)
 {
+    int64_t ticks;
+
     if (use_icount) {
         return cpu_get_icount();
     }
-    if (!timers_state.cpu_ticks_enabled) {
-        return timers_state.cpu_ticks_offset;
-    } else {
-        int64_t ticks;
-        ticks = cpu_get_real_ticks();
-        if (timers_state.cpu_ticks_prev > ticks) {
-            /* Note: non increasing ticks may happen if the host uses
-               software suspend */
-            timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks;
-        }
-        timers_state.cpu_ticks_prev = ticks;
-        return ticks + timers_state.cpu_ticks_offset;
+
+    ticks = timers_state.cpu_ticks_offset;
+    if (timers_state.cpu_ticks_enabled) {
+        ticks += cpu_get_real_ticks();
+    }
+
+    if (timers_state.cpu_ticks_prev > ticks) {
+        /* Note: non increasing ticks may happen if the host uses
+           software suspend */
+        timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks;
+        ticks = timers_state.cpu_ticks_prev;
     }
+
+    timers_state.cpu_ticks_prev = ticks;
+    return ticks;
 }
 
 static int64_t cpu_get_clock_locked(void)
 {
-    int64_t ti;
+    int64_t ticks;
 
-    if (!timers_state.cpu_ticks_enabled) {
-        ti = timers_state.cpu_clock_offset;
-    } else {
-        ti = get_clock();
-        ti += timers_state.cpu_clock_offset;
+    ticks = timers_state.cpu_clock_offset;
+    if (timers_state.cpu_ticks_enabled) {
+        ticks += get_clock();
     }
 
-    return ti;
+    return ticks;
 }
 
 /* return the host CPU monotonic timer and handle stop/restart */
@@ -235,7 +237,7 @@ void cpu_disable_ticks(void)
     /* Here, the really thing protected by seqlock is cpu_clock_offset. */
     seqlock_write_lock(&timers_state.vm_clock_seqlock);
     if (timers_state.cpu_ticks_enabled) {
-        timers_state.cpu_ticks_offset = cpu_get_ticks();
+        timers_state.cpu_ticks_offset += cpu_get_real_ticks();
         timers_state.cpu_clock_offset = cpu_get_clock_locked();
         timers_state.cpu_ticks_enabled = 0;
     }
commit cd5be5829c1ce87aa6b3a7806524fac07ac9a757
Author: Amos Kong <akong at redhat.com>
Date:   Tue Nov 5 19:17:18 2013 +0800

    e1000/rtl8139: update HMP NIC when every bit is written
    
    We currently just update the HMP NIC info when the last bit of macaddr
    is written. This assumes that guest driver will write all the macaddr
    from bit 0 to bit 5 when it changes the macaddr, this is the current
    behavior of linux driver (e1000/rtl8139cp), but we can't do this
    assumption.
    
    The macaddr that is used for rx-filter will be updated when every bit
    is changed. This patch updates the e1000/rtl8139 nic to update HMP NIC
    info when every bit is changed. It will be same as virtio-net.
    
    Signed-off-by: Amos Kong <akong at redhat.com>
    Reviewed-by: Alex Williamson <alex.williamson at redhat.com>
    Message-id: 1383650238-16015-1-git-send-email-akong at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 8387443..ae63591 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -1106,7 +1106,7 @@ mac_writereg(E1000State *s, int index, uint32_t val)
 
     s->mac_reg[index] = val;
 
-    if (index == RA + 1) {
+    if (index == RA || index == RA + 1) {
         macaddr[0] = cpu_to_le32(s->mac_reg[RA]);
         macaddr[1] = cpu_to_le32(s->mac_reg[RA + 1]);
         qemu_format_nic_info_str(qemu_get_queue(s->nic), (uint8_t *)macaddr);
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 5329f44..7f2b4db 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -2741,10 +2741,7 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
 
     switch (addr)
     {
-        case MAC0 ... MAC0+4:
-            s->phys[addr - MAC0] = val;
-            break;
-        case MAC0+5:
+        case MAC0 ... MAC0+5:
             s->phys[addr - MAC0] = val;
             qemu_format_nic_info_str(qemu_get_queue(s->nic), s->phys);
             break;
commit fe2dafa02de4f80ab36f6e0f4ddfcd6418c03c49
Author: Jason Wang <jasowang at redhat.com>
Date:   Wed Nov 6 16:58:08 2013 +0800

    virtio-net: only delete bh that existed
    
    We delete without check whether it existed during exit. This will lead NULL
    pointer deference since it was created conditionally depends on guest driver
    status and features. So add a check of existence before trying to delete it.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Jason Wang <jasowang at redhat.com>
    Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
    Message-id: 1383728288-28469-1-git-send-email-jasowang at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 22dbd05..ae51d96 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1601,7 +1601,7 @@ static int virtio_net_device_exit(DeviceState *qdev)
         if (q->tx_timer) {
             timer_del(q->tx_timer);
             timer_free(q->tx_timer);
-        } else {
+        } else if (q->tx_bh) {
             qemu_bh_delete(q->tx_bh);
         }
     }
commit c2d30667760e3d7b81290d801e567d4f758825ca
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Aug 14 13:29:43 2013 +0200

    rtc: remove dead SQW IRQ code
    
    This was once introduced by commit 100d9891d6 but was never used in-tree
    and then got broken by commit 32e0c8260d. Time to clean up.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Message-id: 520B6A27.4040207 at siemens.com
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 7230a6e..b011638 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -70,7 +70,6 @@ typedef struct RTCState {
     uint64_t last_update;
     int64_t offset;
     qemu_irq irq;
-    qemu_irq sqw_irq;
     int it_shift;
     /* periodic timer */
     QEMUTimer *periodic_timer;
@@ -151,8 +150,7 @@ static void periodic_timer_update(RTCState *s, int64_t current_time)
 
     period_code = s->cmos_data[RTC_REG_A] & 0x0f;
     if (period_code != 0
-        && ((s->cmos_data[RTC_REG_B] & REG_B_PIE)
-            || ((s->cmos_data[RTC_REG_B] & REG_B_SQWE) && s->sqw_irq))) {
+        && (s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
         if (period_code <= 2)
             period_code += 7;
         /* period in 32 Khz cycles */
@@ -202,11 +200,6 @@ static void rtc_periodic_timer(void *opaque)
 #endif
         qemu_irq_raise(s->irq);
     }
-    if (s->cmos_data[RTC_REG_B] & REG_B_SQWE) {
-        /* Not square wave at all but we don't want 2048Hz interrupts!
-           Must be seen as a pulse.  */
-        qemu_irq_raise(s->sqw_irq);
-    }
 }
 
 /* handle update-ended timer */
commit 2c8ebac7ccf51a8e683de593c4240d2ed7d592ec
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date:   Tue Nov 5 16:15:54 2013 +0100

    vga: fix invalid read after free
    
    After calling dpy_gfx_replace_surface(s->con, surface), the outer
    surface is invalid.
    
    ==5370== Invalid read of size 4
    ==5370==    at 0x460229: surface_bits_per_pixel (console.h:250)
    ==5370==    by 0x466A81: get_depth_index (vga.c:1173)
    ==5370==    by 0x467EC2: vga_draw_graphic (vga.c:1718)
    ==5370==    by 0x4687A5: vga_update_display (vga.c:1914)
    ==5370==    by 0x2A782E: qxl_hw_update (qxl.c:1766)
    ==5370==    by 0x3EB83B: graphic_hw_update (console.c:254)
    ==5370==    by 0x3FBE31: qemu_spice_display_refresh (spice-display.c:418)
    ==5370==    by 0x2A7D01: display_refresh (qxl.c:1886)
    ==5370==    by 0x3EEE1C: dpy_refresh (console.c:1436)
    ==5370==    by 0x3EB543: gui_update (console.c:192)
    ==5370==    by 0x3C43B3: timerlist_run_timers (qemu-timer.c:488)
    ==5370==    by 0x3C4416: qemu_clock_run_timers (qemu-timer.c:499)
    ==5370==  Address 0x22ffb1e0 is 0 bytes inside a block of size 56 free'd
    ==5370==    at 0x4A074C4: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==5370==    by 0x4245FC: free_and_trace (vl.c:2771)
    ==5370==    by 0x50899AE: g_free (gmem.c:252)
    ==5370==    by 0x3EE8D3: qemu_free_displaysurface (console.c:1332)
    ==5370==    by 0x3EEDB7: dpy_gfx_replace_surface (console.c:1427)
    ==5370==    by 0x467EB6: vga_draw_graphic (vga.c:1714)
    ==5370==    by 0x4687A5: vga_update_display (vga.c:1914)
    ==5370==    by 0x2A782E: qxl_hw_update (qxl.c:1766)
    ==5370==    by 0x3EB83B: graphic_hw_update (console.c:254)
    ==5370==    by 0x3FBE31: qemu_spice_display_refresh (spice-display.c:418)
    ==5370==    by 0x2A7D01: display_refresh (qxl.c:1886)
    ==5370==    by 0x3EEE1C: dpy_refresh (console.c:1436)
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
    Reviewed-by: Gerd Hoffmann <kraxel at redhat.com>
    Message-id: 1383664554-15248-1-git-send-email-marcandre.lureau at gmail.com
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/hw/display/vga.c b/hw/display/vga.c
index b5e2284..063319d 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1707,7 +1707,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     } else if (is_buffer_shared(surface) &&
                (full_update || surface_data(surface) != s->vram_ptr
                 + (s->start_addr * 4))) {
-        DisplaySurface *surface;
         surface = qemu_create_displaysurface_from(disp_width,
                 height, depth, s->line_offset,
                 s->vram_ptr + (s->start_addr * 4), byteswap);
commit 5cb6be2ca3094f4b6b6fd4c44eabec0098acd3e3
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Tue Nov 5 17:42:48 2013 +0100

    tests: fix 64-bit int literals for 32-bit hosts
    
    On 32-bit hosts:
    
      CC    tests/test-opts-visitor.o
    tests/test-opts-visitor.c: In function 'test_value':
    tests/test-opts-visitor.c:128: warning: integer constant is too large for 'long' type
      CC    tests/test-bitops.o
    tests/test-bitops.c:34: warning: integer constant is too large for 'long' type
    tests/test-bitops.c:35: warning: integer constant is too large for 'long' type
    tests/test-bitops.c:35: warning: integer constant is too large for 'long' type
      CC    tests/endianness-test.o
    tests/endianness-test.c:47: warning: integer constant is too large for 'long' type
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Message-id: 1383669768-23926-1-git-send-email-stefanha at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/tests/endianness-test.c b/tests/endianness-test.c
index feb32a8..8719c09 100644
--- a/tests/endianness-test.c
+++ b/tests/endianness-test.c
@@ -44,7 +44,8 @@ static const TestCase test_cases[] = {
     { "ppc", "prep", 0x80000000, .bswap = true },
     { "ppc", "bamboo", 0xe8000000, .bswap = true, .superio = "i82378" },
     { "ppc64", "mac99", 0xf2000000, .bswap = true, .superio = "i82378" },
-    { "ppc64", "pseries", 0x10080000000, .bswap = true, .superio = "i82378" },
+    { "ppc64", "pseries", 0x10080000000ULL,
+      .bswap = true, .superio = "i82378" },
     { "sh4", "r2d", 0xfe240000, .superio = "i82378" },
     { "sh4eb", "r2d", 0xfe240000, .bswap = true, .superio = "i82378" },
     { "sparc64", "sun4u", 0x1fe02000000LL, .bswap = true },
diff --git a/tests/test-bitops.c b/tests/test-bitops.c
index 4e713e4..8238eb5 100644
--- a/tests/test-bitops.c
+++ b/tests/test-bitops.c
@@ -31,8 +31,8 @@ static const S32Test test_s32_data[] = {
 };
 
 static const S64Test test_s64_data[] = {
-    { 0x8459826734967223, 60, 4, -8 },
-    { 0x8459826734967223, 0, 64, 0x8459826734967223 },
+    { 0x8459826734967223ULL, 60, 4, -8 },
+    { 0x8459826734967223ULL, 0, 64, 0x8459826734967223LL },
 };
 
 static void test_sextract32(void)
diff --git a/tests/test-opts-visitor.c b/tests/test-opts-visitor.c
index 9f902b5..ebeee5d 100644
--- a/tests/test-opts-visitor.c
+++ b/tests/test-opts-visitor.c
@@ -125,7 +125,7 @@ test_value(OptsVisitorFixture *f, gconstpointer test_data)
         g_assert((magic & bitval) == 0);
         magic |= bitval;
     }
-    g_assert(magic == 0xBADC0FFEE0DDF00D);
+    g_assert(magic == 0xBADC0FFEE0DDF00DULL);
 
     magic = 0;
     for (u16 = f->userdef->u16; u16 != NULL; u16 = u16->next) {
commit 6f1ce94a2935dab5d0aa3bd13ecc33e352213dc7
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Oct 15 15:42:34 2013 +0100

    docs/memory.txt: Clarify and expand priority/overlap documentation
    
    The documentation of how overlapping memory regions behave and how
    the priority system works was rather brief, and confusion about
    priorities seems to be quite common for developers trying to understand
    how the memory region system works, so expand and clarify it.
    This includes a worked example with overlaps, documentation of the
    behaviour when an overlapped container has "holes", and mention
    that it's valid for a region to have both MMIO callbacks and
    subregions (and how this interacts with priorities when it does).
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
    Message-id: 1381848154-31602-1-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/docs/memory.txt b/docs/memory.txt
index 174c0d7..22eaec7 100644
--- a/docs/memory.txt
+++ b/docs/memory.txt
@@ -52,6 +52,15 @@ MemoryRegion):
   hole".  Aliases may point to any type of region, including other aliases,
   but an alias may not point back to itself, directly or indirectly.
 
+It is valid to add subregions to a region which is not a pure container
+(that is, to an MMIO, RAM or ROM region). This means that the region
+will act like a container, except that any addresses within the container's
+region which are not claimed by any subregion are handled by the
+container itself (ie by its MMIO callbacks or RAM backing). However
+it is generally possible to achieve the same effect with a pure container
+one of whose subregions is a low priority "background" region covering
+the whole address range; this is often clearer and is preferred.
+Subregions cannot be added to an alias region.
 
 Region names
 ------------
@@ -85,6 +94,49 @@ you can use memory_region_add_subregion_overlap() both to specify a region
 that must sit 'above' any others (with a positive priority) and also a
 background region that sits 'below' others (with a negative priority).
 
+If the higher priority region in an overlap is a container or alias, then
+the lower priority region will appear in any "holes" that the higher priority
+region has left by not mapping subregions to that area of its address range.
+(This applies recursively -- if the subregions are themselves containers or
+aliases that leave holes then the lower priority region will appear in these
+holes too.)
+
+For example, suppose we have a container A of size 0x8000 with two subregions
+B and C. B is a container mapped at 0x2000, size 0x4000, priority 1; C is
+an MMIO region mapped at 0x0, size 0x6000, priority 2. B currently has two
+of its own subregions: D of size 0x1000 at offset 0 and E of size 0x1000 at
+offset 0x2000. As a diagram:
+
+        0      1000   2000   3000   4000   5000   6000   7000    8000
+        |------|------|------|------|------|------|------|-------|
+  A:    [                                                       ]
+  C:    [CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC]
+  B:                  [                          ]
+  D:                  [DDDDD]
+  E:                                [EEEEE]
+
+The regions that will be seen within this address range then are:
+        [CCCCCCCCCCCC][DDDDD][CCCCC][EEEEE][CCCCC]
+
+Since B has higher priority than C, its subregions appear in the flat map
+even where they overlap with C. In ranges where B has not mapped anything
+C's region appears.
+
+If B had provided its own MMIO operations (ie it was not a pure container)
+then these would be used for any addresses in its range not handled by
+D or E, and the result would be:
+        [CCCCCCCCCCCC][DDDDD][BBBBB][EEEEE][BBBBB]
+
+Priority values are local to a container, because the priorities of two
+regions are only compared when they are both children of the same container.
+This means that the device in charge of the container (typically modelling
+a bus or a memory controller) can use them to manage the interaction of
+its child regions without any side effects on other parts of the system.
+In the example above, the priorities of D and E are unimportant because
+they do not overlap each other. It is the relative priority of B and C
+that causes D and E to appear on top of C: D and E's priorities are never
+compared against the priority of C.
+
 Visibility
 ----------
 The memory core uses the following rules to select a memory region when the
@@ -94,11 +146,19 @@ guest accesses an address:
   descending priority order
   - if the address lies outside the region offset/size, the subregion is
     discarded
-  - if the subregion is a leaf (RAM or MMIO), the search terminates
+  - if the subregion is a leaf (RAM or MMIO), the search terminates, returning
+    this leaf region
   - if the subregion is a container, the same algorithm is used within the
     subregion (after the address is adjusted by the subregion offset)
-  - if the subregion is an alias, the search is continues at the alias target
+  - if the subregion is an alias, the search is continued at the alias target
     (after the address is adjusted by the subregion offset and alias offset)
+  - if a recursive search within a container or alias subregion does not
+    find a match (because of a "hole" in the container's coverage of its
+    address range), then if this is a container with its own MMIO or RAM
+    backing the search terminates, returning the container itself. Otherwise
+    we continue with the next subregion in priority order
+- if none of the subregions match the address then the search terminates
+  with no match found
 
 Example memory map
 ------------------
commit 61cc919f73ea7ca134c0ac41b748981ad63a253b
Author: Mike Frysinger <vapier at gentoo.org>
Date:   Sun Jun 30 23:30:18 2013 -0400

    configure: detect endian via compile test
    
    This avoids needing to execute a program and keeping an (incomplete)
    list when cross-compiling.
    
    Signed-off-by: Mike Frysinger <vapier at gentoo.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Tested-by: James Hogan <james.hogan at imgtec.com> [mips]
    Message-id: 1372649418-4987-1-git-send-email-vapier at gentoo.org
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/configure b/configure
index 91372f9..9addff1 100755
--- a/configure
+++ b/configure
@@ -1433,39 +1433,27 @@ feature_not_found() {
       "configure was not able to find it"
 }
 
-if test -z "$cross_prefix" ; then
-
 # ---
 # big/little endian test
 cat > $TMPC << EOF
-#include <inttypes.h>
-int main(void) {
-        volatile uint32_t i=0x01234567;
-        return (*((uint8_t*)(&i))) == 0x67;
+short big_endian[] = { 0x4269, 0x4765, 0x4e64, 0x4961, 0x4e00, 0, };
+short little_endian[] = { 0x694c, 0x7454, 0x654c, 0x6e45, 0x6944, 0x6e41, 0, };
+extern int foo(short *, short *);
+int main(int argc, char *argv[]) {
+    return foo(big_endian, little_endian);
 }
 EOF
 
-if compile_prog "" "" ; then
-$TMPE && bigendian="yes"
-else
-echo big/little test failed
-fi
-
-else
-
-# if cross compiling, cannot launch a program, so make a static guess
-case "$cpu" in
-  arm)
-    # ARM can be either way; ask the compiler which one we are
-    if check_define __ARMEB__; then
-      bigendian=yes
+if compile_object ; then
+    if grep -q BiGeNdIaN $TMPO ; then
+        bigendian="yes"
+    elif grep -q LiTtLeEnDiAn $TMPO ; then
+        bigendian="no"
+    else
+        echo big/little test failed
     fi
-  ;;
-  hppa|m68k|mips|mips64|ppc|ppc64|s390|s390x|sparc|sparc64)
-    bigendian=yes
-  ;;
-esac
-
+else
+    echo big/little test failed
 fi
 
 ##########################################
commit 8aa15b6e527f234e491a6d354bed4d10da3a01a7
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Wed Nov 6 02:35:51 2013 +0800

    tests: fix memleak in error path test for input visitor
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Message-id: 1383676551-18806-3-git-send-email-xiawenc at linux.vnet.ibm.com
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index 0beb8fb..1e1c6fa 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -604,6 +604,7 @@ static void test_visitor_in_errors(TestInputVisitorData *data,
     g_assert(error_is_set(&errp));
     g_assert(p->string == NULL);
 
+    error_free(errp);
     g_free(p->string);
     g_free(p);
 }
commit 3dce9cad5a6c0b0dbe0830973b270c9466c8ab4b
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Wed Nov 6 02:35:50 2013 +0800

    qapi: fix memleak by adding implict struct functions in dealloc visitor
    
    Otherwise member "base" is leaked in a qapi_free_STRUCTURE() call.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Message-id: 1383676551-18806-2-git-send-email-xiawenc at linux.vnet.ibm.com
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index 1334de3..dc53545 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -76,6 +76,24 @@ static void qapi_dealloc_end_struct(Visitor *v, Error **errp)
     }
 }
 
+static void qapi_dealloc_start_implicit_struct(Visitor *v,
+                                               void **obj,
+                                               size_t size,
+                                               Error **errp)
+{
+    QapiDeallocVisitor *qov = to_qov(v);
+    qapi_dealloc_push(qov, obj);
+}
+
+static void qapi_dealloc_end_implicit_struct(Visitor *v, Error **errp)
+{
+    QapiDeallocVisitor *qov = to_qov(v);
+    void **obj = qapi_dealloc_pop(qov);
+    if (obj) {
+        g_free(*obj);
+    }
+}
+
 static void qapi_dealloc_start_list(Visitor *v, const char *name, Error **errp)
 {
     QapiDeallocVisitor *qov = to_qov(v);
@@ -162,6 +180,8 @@ QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
 
     v->visitor.start_struct = qapi_dealloc_start_struct;
     v->visitor.end_struct = qapi_dealloc_end_struct;
+    v->visitor.start_implicit_struct = qapi_dealloc_start_implicit_struct;
+    v->visitor.end_implicit_struct = qapi_dealloc_end_implicit_struct;
     v->visitor.start_list = qapi_dealloc_start_list;
     v->visitor.next_list = qapi_dealloc_next_list;
     v->visitor.end_list = qapi_dealloc_end_list;
commit 7d579514a5a7b308b52d4e8567aa9bd1f7aa761b
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Nov 5 16:38:37 2013 +0000

    bswap.h: Remove cpu_to_32wu()
    
    Replace the legacy cpu_to_32wu() with stl_p().
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
    Message-id: 1383669517-25598-10-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/hw/display/vga_template.h b/hw/display/vga_template.h
index f6f6a01..6cfae56 100644
--- a/hw/display/vga_template.h
+++ b/hw/display/vga_template.h
@@ -113,20 +113,22 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
     do {
         font_data = font_ptr[0];
 #if BPP == 1
-        cpu_to_32wu((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol);
+        stl_p((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol);
         v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
-        cpu_to_32wu(((uint32_t *)d)+1, v);
+        stl_p(((uint32_t *)d)+1, v);
         if (dup9)
             ((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
         else
             ((uint8_t *)d)[8] = bgcol;
 
 #elif BPP == 2
-        cpu_to_32wu(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol);
-        cpu_to_32wu(((uint32_t *)d)+1, (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol);
-        cpu_to_32wu(((uint32_t *)d)+2, (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol);
+        stl_p(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol);
+        stl_p(((uint32_t *)d)+1,
+              (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol);
+        stl_p(((uint32_t *)d)+2,
+              (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol);
         v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
-        cpu_to_32wu(((uint32_t *)d)+3, v);
+        stl_p(((uint32_t *)d)+3, v);
         if (dup9)
             ((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
         else
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 4cbd6e7..437b8e0 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -410,13 +410,6 @@ static inline void stfq_be_p(void *ptr, float64 v)
     stq_be_p(ptr, u.ll);
 }
 
-/* Legacy unaligned versions.  Note that we never had a complete set.  */
-
-static inline void cpu_to_32wu(uint32_t *p, uint32_t v)
-{
-    stl_p(p, v);
-}
-
 static inline unsigned long leul_to_cpu(unsigned long v)
 {
     /* In order to break an include loop between here and
commit e4ef9f465cf7cbc66b85e9df4eebe13086b46f11
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Nov 5 16:38:36 2013 +0000

    bswap.h: Remove cpu_to_be64wu()
    
    Replace the legacy cpu_to_be64wu() with stq_be_p().
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
    Message-id: 1383669517-25598-9-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 0348b97..f242244 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -101,7 +101,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
     /* set new table */
     BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ACTIVATE_TABLE);
     cpu_to_be32w((uint32_t*)data, new_l1_size);
-    cpu_to_be64wu((uint64_t*)(data + 4), new_l1_table_offset);
+    stq_be_p(data + 4, new_l1_table_offset);
     ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data));
     if (ret < 0) {
         goto fail;
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index b95cc73..4cbd6e7 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -412,11 +412,6 @@ static inline void stfq_be_p(void *ptr, float64 v)
 
 /* Legacy unaligned versions.  Note that we never had a complete set.  */
 
-static inline void cpu_to_be64wu(uint64_t *p, uint64_t v)
-{
-    stq_be_p(p, v);
-}
-
 static inline void cpu_to_32wu(uint32_t *p, uint32_t v)
 {
     stl_p(p, v);
commit 6bd194ab9957361f83fdbfb22d452d97b4af28e2
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Nov 5 16:38:35 2013 +0000

    bswap.h: Remove cpu_to_be32wu()
    
    Replace the legacy cpu_to_be32wu() with stl_be_p().
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
    Message-id: 1383669517-25598-8-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/hw/block/cdrom.c b/hw/block/cdrom.c
index 5c69f34..4e1019c 100644
--- a/hw/block/cdrom.c
+++ b/hw/block/cdrom.c
@@ -59,7 +59,7 @@ int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track)
             q += 3;
         } else {
             /* sector 0 */
-            cpu_to_be32wu((uint32_t *)q, 0);
+            stl_be_p(q, 0);
             q += 4;
         }
     }
@@ -73,7 +73,7 @@ int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track)
         lba_to_msf(q, nb_sectors);
         q += 3;
     } else {
-        cpu_to_be32wu((uint32_t *)q, nb_sectors);
+        stl_be_p(q, nb_sectors);
         q += 4;
     }
     len = q - buf;
@@ -127,7 +127,7 @@ int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num)
         lba_to_msf(q, nb_sectors);
         q += 3;
     } else {
-        cpu_to_be32wu((uint32_t *)q, nb_sectors);
+        stl_be_p(q, nb_sectors);
         q += 4;
     }
 
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 34ac625..8387443 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -599,8 +599,7 @@ xmit_seg(E1000State *s)
         DBGOUT(TXSUM, "tcp %d tucss %d len %d\n", tp->tcp, css, len);
         if (tp->tcp) {
             sofar = frames * tp->mss;
-            cpu_to_be32wu((uint32_t *)(tp->data+css+4),	// seq
-                ldl_be_p(tp->data+css+4)+sofar);
+            stl_be_p(tp->data+css+4, ldl_be_p(tp->data+css+4)+sofar); /* seq */
             if (tp->paylen - sofar > tp->mss)
                 tp->data[css + 13] &= ~9;		// PSH, FIN
         } else	// UDP
diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
index 32aa0c6..991502e 100644
--- a/hw/pci/pcie_aer.c
+++ b/hw/pci/pcie_aer.c
@@ -425,7 +425,7 @@ static void pcie_aer_update_log(PCIDevice *dev, const PCIEAERErr *err)
             /* 7.10.8 Header Log Register */
             uint8_t *header_log =
                 aer_cap + PCI_ERR_HEADER_LOG + i * sizeof err->header[0];
-            cpu_to_be32wu((uint32_t*)header_log, err->header[i]);
+            stl_be_p(header_log, err->header[i]);
         }
     } else {
         assert(!(err->flags & PCIE_AER_ERR_TLP_PREFIX_PRESENT));
@@ -439,7 +439,7 @@ static void pcie_aer_update_log(PCIDevice *dev, const PCIEAERErr *err)
             /* 7.10.12 tlp prefix log register */
             uint8_t *prefix_log =
                 aer_cap + PCI_ERR_TLP_PREFIX_LOG + i * sizeof err->prefix[0];
-            cpu_to_be32wu((uint32_t*)prefix_log, err->prefix[i]);
+            stl_be_p(prefix_log, err->prefix[i]);
         }
         errcap |= PCI_ERR_CAP_TLP;
     } else {
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 3bb6b71..b95cc73 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -412,11 +412,6 @@ static inline void stfq_be_p(void *ptr, float64 v)
 
 /* Legacy unaligned versions.  Note that we never had a complete set.  */
 
-static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
-{
-    stl_be_p(p, v);
-}
-
 static inline void cpu_to_be64wu(uint64_t *p, uint64_t v)
 {
     stq_be_p(p, v);
commit d8ee2591e495d5feb0e0250866222dedc805c8d8
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Nov 5 16:38:34 2013 +0000

    bswap.h: Remove cpu_to_be16wu()
    
    Replace the legacy cpu_to_be16wu() with stw_be_p().
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
    Message-id: 1383669517-25598-7-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/hw/block/cdrom.c b/hw/block/cdrom.c
index 38469fa..5c69f34 100644
--- a/hw/block/cdrom.c
+++ b/hw/block/cdrom.c
@@ -77,7 +77,7 @@ int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track)
         q += 4;
     }
     len = q - buf;
-    cpu_to_be16wu((uint16_t *)buf, len - 2);
+    stw_be_p(buf, len - 2);
     return len;
 }
 
@@ -150,6 +150,6 @@ int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num)
     }
 
     len = q - buf;
-    cpu_to_be16wu((uint16_t *)buf, len - 2);
+    stw_be_p(buf, len - 2);
     return len;
 }
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 05e60b1..f7d2009 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -437,7 +437,7 @@ static int ide_dvd_read_structure(IDEState *s, int format,
                 cpu_to_ube32(buf + 16, total_sectors - 1); /* l0 end sector */
 
                 /* Size of buffer, not including 2 byte size field */
-                cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
+                stw_be_p(buf, 2048 + 2);
 
                 /* 2k data + 4 byte header */
                 return (2048 + 4);
@@ -448,7 +448,7 @@ static int ide_dvd_read_structure(IDEState *s, int format,
             buf[5] = 0; /* no region restrictions */
 
             /* Size of buffer, not including 2 byte size field */
-            cpu_to_be16wu((uint16_t *)buf, 4 + 2);
+            stw_be_p(buf, 4 + 2);
 
             /* 4 byte header + 4 byte data */
             return (4 + 4);
@@ -458,7 +458,7 @@ static int ide_dvd_read_structure(IDEState *s, int format,
 
         case 0x04: /* DVD disc manufacturing information */
             /* Size of buffer, not including 2 byte size field */
-            cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
+            stw_be_p(buf, 2048 + 2);
 
             /* 2k data + 4 byte header */
             return (2048 + 4);
@@ -471,22 +471,22 @@ static int ide_dvd_read_structure(IDEState *s, int format,
 
             buf[4] = 0x00; /* Physical format */
             buf[5] = 0x40; /* Not writable, is readable */
-            cpu_to_be16wu((uint16_t *)(buf + 6), 2048 + 4);
+            stw_be_p(buf + 6, 2048 + 4);
 
             buf[8] = 0x01; /* Copyright info */
             buf[9] = 0x40; /* Not writable, is readable */
-            cpu_to_be16wu((uint16_t *)(buf + 10), 4 + 4);
+            stw_be_p(buf + 10, 4 + 4);
 
             buf[12] = 0x03; /* BCA info */
             buf[13] = 0x40; /* Not writable, is readable */
-            cpu_to_be16wu((uint16_t *)(buf + 14), 188 + 4);
+            stw_be_p(buf + 14, 188 + 4);
 
             buf[16] = 0x04; /* Manufacturing info */
             buf[17] = 0x40; /* Not writable, is readable */
-            cpu_to_be16wu((uint16_t *)(buf + 18), 2048 + 4);
+            stw_be_p(buf + 18, 2048 + 4);
 
             /* Size of buffer, not including 2 byte size field */
-            cpu_to_be16wu((uint16_t *)buf, 16 + 2);
+            stw_be_p(buf, 16 + 2);
 
             /* data written + 4 byte header */
             return (16 + 4);
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index a5fb8fc..34ac625 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -528,8 +528,7 @@ putsum(uint8_t *data, uint32_t n, uint32_t sloc, uint32_t css, uint32_t cse)
         n = cse + 1;
     if (sloc < n-1) {
         sum = net_checksum_add(n-css, data+css);
-        cpu_to_be16wu((uint16_t *)(data + sloc),
-                      net_checksum_finish(sum));
+        stw_be_p(data + sloc, net_checksum_finish(sum));
     }
 }
 
@@ -590,13 +589,11 @@ xmit_seg(E1000State *s)
         DBGOUT(TXSUM, "frames %d size %d ipcss %d\n",
                frames, tp->size, css);
         if (tp->ip) {		// IPv4
-            cpu_to_be16wu((uint16_t *)(tp->data+css+2),
-                          tp->size - css);
-            cpu_to_be16wu((uint16_t *)(tp->data+css+4),
+            stw_be_p(tp->data+css+2, tp->size - css);
+            stw_be_p(tp->data+css+4,
                           be16_to_cpup((uint16_t *)(tp->data+css+4))+frames);
         } else			// IPv6
-            cpu_to_be16wu((uint16_t *)(tp->data+css+4),
-                          tp->size - css);
+            stw_be_p(tp->data+css+4, tp->size - css);
         css = tp->tucss;
         len = tp->size - css;
         DBGOUT(TXSUM, "tcp %d tucss %d len %d\n", tp->tcp, css, len);
@@ -607,14 +604,14 @@ xmit_seg(E1000State *s)
             if (tp->paylen - sofar > tp->mss)
                 tp->data[css + 13] &= ~9;		// PSH, FIN
         } else	// UDP
-            cpu_to_be16wu((uint16_t *)(tp->data+css+4), len);
+            stw_be_p(tp->data+css+4, len);
         if (tp->sum_needed & E1000_TXD_POPTS_TXSM) {
             unsigned int phsum;
             // add pseudo-header length before checksum calculation
             sp = (uint16_t *)(tp->data + tp->tucso);
             phsum = be16_to_cpup(sp) + len;
             phsum = (phsum >> 16) + (phsum & 0xffff);
-            cpu_to_be16wu(sp, phsum);
+            stw_be_p(sp, phsum);
         }
         tp->tso_frames++;
     }
@@ -684,9 +681,9 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
     if (vlan_enabled(s) && is_vlan_txd(txd_lower) &&
         (tp->cptse || txd_lower & E1000_TXD_CMD_EOP)) {
         tp->vlan_needed = 1;
-        cpu_to_be16wu((uint16_t *)(tp->vlan_header),
+        stw_be_p(tp->vlan_header,
                       le16_to_cpup((uint16_t *)(s->mac_reg + VET)));
-        cpu_to_be16wu((uint16_t *)(tp->vlan_header + 2),
+        stw_be_p(tp->vlan_header + 2,
                       le16_to_cpu(dp->upper.fields.special));
     }
         
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 9524931..3bb6b71 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -412,11 +412,6 @@ static inline void stfq_be_p(void *ptr, float64 v)
 
 /* Legacy unaligned versions.  Note that we never had a complete set.  */
 
-static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
-{
-    stw_be_p(p, v);
-}
-
 static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
 {
     stl_be_p(p, v);
commit 09fa8439730c707b34af6ab055fc353f6cadc57d
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Nov 5 16:38:33 2013 +0000

    bswap.h: Remove be32_to_cpupu()
    
    Replace the legacy be32_to_cpupu() with ldl_be_p().
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
    Message-id: 1383669517-25598-6-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index ec8ecd7..a5fb8fc 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -603,7 +603,7 @@ xmit_seg(E1000State *s)
         if (tp->tcp) {
             sofar = frames * tp->mss;
             cpu_to_be32wu((uint32_t *)(tp->data+css+4),	// seq
-                be32_to_cpupu((uint32_t *)(tp->data+css+4))+sofar);
+                ldl_be_p(tp->data+css+4)+sofar);
             if (tp->paylen - sofar > tp->mss)
                 tp->data[css + 13] &= ~9;		// PSH, FIN
         } else	// UDP
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index ac5b2e0..9524931 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -412,11 +412,6 @@ static inline void stfq_be_p(void *ptr, float64 v)
 
 /* Legacy unaligned versions.  Note that we never had a complete set.  */
 
-static inline uint32_t be32_to_cpupu(const uint32_t *p)
-{
-    return ldl_be_p(p);
-}
-
 static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
 {
     stw_be_p(p, v);
commit f567656a67e3859a8be2371c45ff66e90321a2c1
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Nov 5 16:38:32 2013 +0000

    bswap.h: Remove le32_to_cpupu()
    
    Replace the legacy le32_to_cpupu() with ldl_le_p().
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
    Message-id: 1383669517-25598-5-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index 9ba3d1e..4c32e9e 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -497,7 +497,7 @@ static inline uint32_t ne2000_mem_readl(NE2000State *s, uint32_t addr)
     addr &= ~1; /* XXX: check exact behaviour if not even */
     if (addr < 32 ||
         (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
-        return le32_to_cpupu((uint32_t *)(s->mem + addr));
+        return ldl_le_p(s->mem + addr);
     } else {
         return 0xffffffff;
     }
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 9c961a9..b783e68 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -439,7 +439,7 @@ pci_set_long(uint8_t *config, uint32_t val)
 static inline uint32_t
 pci_get_long(const uint8_t *config)
 {
-    return le32_to_cpupu((const uint32_t *)config);
+    return ldl_le_p(config);
 }
 
 static inline void
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 1c50002..ac5b2e0 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -412,11 +412,6 @@ static inline void stfq_be_p(void *ptr, float64 v)
 
 /* Legacy unaligned versions.  Note that we never had a complete set.  */
 
-static inline uint32_t le32_to_cpupu(const uint32_t *p)
-{
-    return ldl_le_p(p);
-}
-
 static inline uint32_t be32_to_cpupu(const uint32_t *p)
 {
     return ldl_be_p(p);
commit c65e5de94dbe667743d1523d6b4ac301cd76b0fe
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Nov 5 16:38:31 2013 +0000

    bswap.h: Remove le16_to_cpupu()
    
    Replace the legacy le16_to_cpupu() with lduw_le_p().
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
    Message-id: 1383669517-25598-4-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index 246ade3..58308a3 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -170,8 +170,7 @@ static void acpi_table_install(const char unsigned *blob, size_t bloblen,
     }
 
     /* increase number of tables */
-    stw_le_p(acpi_tables,
-             le16_to_cpupu((uint16_t *)acpi_tables) + 1u);
+    stw_le_p(acpi_tables, lduw_le_p(acpi_tables) + 1u);
 
     /* Update the header fields. The strings need not be NUL-terminated. */
     changed_fields = 0;
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 9cd0642..9c961a9 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -427,7 +427,7 @@ pci_set_word(uint8_t *config, uint16_t val)
 static inline uint16_t
 pci_get_word(const uint8_t *config)
 {
-    return le16_to_cpupu((const uint16_t *)config);
+    return lduw_le_p(config);
 }
 
 static inline void
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index d0c4ff0..1c50002 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -412,11 +412,6 @@ static inline void stfq_be_p(void *ptr, float64 v)
 
 /* Legacy unaligned versions.  Note that we never had a complete set.  */
 
-static inline uint16_t le16_to_cpupu(const uint16_t *p)
-{
-    return lduw_le_p(p);
-}
-
 static inline uint32_t le32_to_cpupu(const uint32_t *p)
 {
     return ldl_le_p(p);
commit 6e931878c1bde26ff594f284a6857e0d786674bc
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Nov 5 16:38:30 2013 +0000

    bswap.h: Remove cpu_to_le32wu()
    
    Replace the legacy cpu_to_le32wu() with stl_le_p().
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
    Message-id: 1383669517-25598-3-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index a94cf74..9ba3d1e 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -467,7 +467,7 @@ static inline void ne2000_mem_writel(NE2000State *s, uint32_t addr,
     addr &= ~1; /* XXX: check exact behaviour if not even */
     if (addr < 32 ||
         (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
-        cpu_to_le32wu((uint32_t *)(s->mem + addr), val);
+        stl_le_p(s->mem + addr, val);
     }
 }
 
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index fae2170..9cd0642 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -433,7 +433,7 @@ pci_get_word(const uint8_t *config)
 static inline void
 pci_set_long(uint8_t *config, uint32_t val)
 {
-    cpu_to_le32wu((uint32_t *)config, val);
+    stl_le_p(config, val);
 }
 
 static inline uint32_t
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index ada1084..d0c4ff0 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -412,11 +412,6 @@ static inline void stfq_be_p(void *ptr, float64 v)
 
 /* Legacy unaligned versions.  Note that we never had a complete set.  */
 
-static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
-{
-    stl_le_p(p, v);
-}
-
 static inline uint16_t le16_to_cpupu(const uint16_t *p)
 {
     return lduw_le_p(p);
commit 587ae227607d86d07b0a0fb30fff55604ff9ee80
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Nov 5 16:38:29 2013 +0000

    bswap.h: Remove cpu_to_le16wu()
    
    Replace the legacy cpu_to_le16wu() with stw_le_p().
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
    Message-id: 1383669517-25598-2-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index d8dff5b..246ade3 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -170,8 +170,8 @@ static void acpi_table_install(const char unsigned *blob, size_t bloblen,
     }
 
     /* increase number of tables */
-    cpu_to_le16wu((uint16_t *)acpi_tables,
-                  le16_to_cpupu((uint16_t *)acpi_tables) + 1u);
+    stw_le_p(acpi_tables,
+             le16_to_cpupu((uint16_t *)acpi_tables) + 1u);
 
     /* Update the header fields. The strings need not be NUL-terminated. */
     changed_fields = 0;
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 37ffa53..fae2170 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -421,7 +421,7 @@ pci_get_byte(const uint8_t *config)
 static inline void
 pci_set_word(uint8_t *config, uint16_t val)
 {
-    cpu_to_le16wu((uint16_t *)config, val);
+    stw_le_p(config, val);
 }
 
 static inline uint16_t
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 14a5f65..ada1084 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -412,11 +412,6 @@ static inline void stfq_be_p(void *ptr, float64 v)
 
 /* Legacy unaligned versions.  Note that we never had a complete set.  */
 
-static inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
-{
-    stw_le_p(p, v);
-}
-
 static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
 {
     stl_le_p(p, v);
commit a30b377e0a921bf93349dc4adb94580a3bec7ea4
Merge: c905c50 80bbaee
Author: Anthony Liguori <aliguori at amazon.com>
Date:   Tue Nov 5 10:33:32 2013 -0800

    Merge remote-tracking branch 'afaerber/tags/qom-devices-for-anthony' into staging
    
    QOM device refactorings
    
    * QTest coverage for all machines
    * QOM realize for Milkymist UART
    * QOM realize for ARM MPCore
    * device_add bug fixes and cleanups
    * QOM for PCMCIA/MicroDrive (last legacy IDE device)
    
    # gpg: Signature made Tue 05 Nov 2013 09:07:03 AM PST using RSA key ID 3E7E013F
    # gpg: Can't check signature: public key not found
    
    # By Andreas Färber (49) and others
    # Via Andreas Färber
    * afaerber/tags/qom-devices-for-anthony: (54 commits)
      pcmcia/pxa2xx: QOM'ify PXA2xxPCMCIAState
      ide: Drop ide_init2_with_non_qdev_drives()
      microdrive: Coding Style cleanups
      pcmcia: QOM'ify PCMCIACardState and MicroDriveState
      pxa: Fix typo "dettach"
      qom: Fix pointer to int property helpers' documentation
      qdev-monitor: Inline qdev_init() for device_add
      qdev-monitor: Avoid qdev as variable name
      qdev: Drop misleading qdev_free() function
      qdev-monitor: Unref device when device_add fails
      qdev-monitor: Fix crash when device_add is called with abstract driver
      qdev-monitor: Clean up qdev_device_add() variable naming
      arm11mpcore: Split off RealView MPCore
      arm11mpcore: Prepare for QOM embedding
      arm11mpcore: Convert mpcore_rirq_state to QOM realize
      realview_gic: Prepare for QOM embedding
      realview_gic: Convert to QOM realize
      arm11mpcore: Convert ARM11MPCorePriveState to QOM realize
      arm11mpcore: Split off SCU device
      arm11mpcore: Create container MemoryRegion in instance_init
      ...

commit 80bbaee66ac38bcb5fe5a6f285e20457afcc8bec
Author: Andreas Färber <afaerber at suse.de>
Date:   Sat Aug 3 12:23:05 2013 +0200

    pcmcia/pxa2xx: QOM'ify PXA2xxPCMCIAState
    
    Turn it into a SysBusDevice and use a container MemoryRegion.
    
    Add a link<pcmcia-card> property to the PCMCIACardState.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/pcmcia/pxa2xx.c b/hw/pcmcia/pxa2xx.c
index 2c515be..8f17596 100644
--- a/hw/pcmcia/pxa2xx.c
+++ b/hw/pcmcia/pxa2xx.c
@@ -11,19 +11,27 @@
  */
 
 #include "hw/hw.h"
+#include "hw/sysbus.h"
 #include "hw/pcmcia.h"
 #include "hw/arm/pxa.h"
 
+#define TYPE_PXA2XX_PCMCIA "pxa2xx-pcmcia"
+#define PXA2XX_PCMCIA(obj) \
+    OBJECT_CHECK(PXA2xxPCMCIAState, obj, TYPE_PXA2XX_PCMCIA)
 
 struct PXA2xxPCMCIAState {
+    SysBusDevice parent_obj;
+
     PCMCIASocket slot;
-    PCMCIACardState *card;
+    MemoryRegion container_mem;
     MemoryRegion common_iomem;
     MemoryRegion attr_iomem;
     MemoryRegion iomem;
 
     qemu_irq irq;
     qemu_irq cd_irq;
+
+    PCMCIACardState *card;
 };
 
 static uint64_t pxa2xx_pcmcia_common_read(void *opaque,
@@ -134,15 +142,43 @@ static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
 PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
                                       hwaddr base)
 {
+    DeviceState *dev;
     PXA2xxPCMCIAState *s;
 
-    s = (PXA2xxPCMCIAState *)
-            g_malloc0(sizeof(PXA2xxPCMCIAState));
+    dev = qdev_create(NULL, TYPE_PXA2XX_PCMCIA);
+    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
+    s = PXA2XX_PCMCIA(dev);
+
+    if (base == 0x30000000) {
+        s->slot.slot_string = "PXA PC Card Socket 1";
+    } else {
+        s->slot.slot_string = "PXA PC Card Socket 0";
+    }
+
+    qdev_init_nofail(dev);
+
+    return s;
+}
+
+static void pxa2xx_pcmcia_realize(DeviceState *dev, Error **errp)
+{
+    PXA2xxPCMCIAState *s = PXA2XX_PCMCIA(dev);
+
+    pcmcia_socket_register(&s->slot);
+}
+
+static void pxa2xx_pcmcia_initfn(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    PXA2xxPCMCIAState *s = PXA2XX_PCMCIA(obj);
+
+    memory_region_init(&s->container_mem, obj, "container", 0x10000000);
+    sysbus_init_mmio(sbd, &s->container_mem);
 
     /* Socket I/O Memory Space */
     memory_region_init_io(&s->iomem, NULL, &pxa2xx_pcmcia_io_ops, s,
                           "pxa2xx-pcmcia-io", 0x04000000);
-    memory_region_add_subregion(sysmem, base | 0x00000000,
+    memory_region_add_subregion(&s->container_mem, 0x00000000,
                                 &s->iomem);
 
     /* Then next 64 MB is reserved */
@@ -150,23 +186,19 @@ PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
     /* Socket Attribute Memory Space */
     memory_region_init_io(&s->attr_iomem, NULL, &pxa2xx_pcmcia_attr_ops, s,
                           "pxa2xx-pcmcia-attribute", 0x04000000);
-    memory_region_add_subregion(sysmem, base | 0x08000000,
+    memory_region_add_subregion(&s->container_mem, 0x08000000,
                                 &s->attr_iomem);
 
     /* Socket Common Memory Space */
     memory_region_init_io(&s->common_iomem, NULL, &pxa2xx_pcmcia_common_ops, s,
                           "pxa2xx-pcmcia-common", 0x04000000);
-    memory_region_add_subregion(sysmem, base | 0x0c000000,
+    memory_region_add_subregion(&s->container_mem, 0x0c000000,
                                 &s->common_iomem);
 
-    if (base == 0x30000000)
-        s->slot.slot_string = "PXA PC Card Socket 1";
-    else
-        s->slot.slot_string = "PXA PC Card Socket 0";
     s->slot.irq = qemu_allocate_irqs(pxa2xx_pcmcia_set_irq, s, 1)[0];
-    pcmcia_socket_register(&s->slot);
 
-    return s;
+    object_property_add_link(obj, "card", TYPE_PCMCIA_CARD,
+                             (Object **)&s->card, NULL);
 }
 
 /* Insert a new card into a slot */
@@ -227,3 +259,25 @@ void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq)
     s->irq = irq;
     s->cd_irq = cd_irq;
 }
+
+static void pxa2xx_pcmcia_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = pxa2xx_pcmcia_realize;
+}
+
+static const TypeInfo pxa2xx_pcmcia_type_info = {
+    .name = TYPE_PXA2XX_PCMCIA,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PXA2xxPCMCIAState),
+    .instance_init = pxa2xx_pcmcia_initfn,
+    .class_init = pxa2xx_pcmcia_class_init,
+};
+
+static void pxa2xx_pcmcia_register_types(void)
+{
+    type_register_static(&pxa2xx_pcmcia_type_info);
+}
+
+type_init(pxa2xx_pcmcia_register_types)
commit e3d4d36d1bff6b1a0b68b794c33bbe8666afc840
Author: Andreas Färber <afaerber at suse.de>
Date:   Sat Aug 3 11:30:50 2013 +0200

    ide: Drop ide_init2_with_non_qdev_drives()
    
    All its users have finally been converted.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 399b1ba..e1f4c33 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2215,55 +2215,6 @@ void ide_init2(IDEBus *bus, qemu_irq irq)
     bus->dma = &ide_dma_nop;
 }
 
-/* TODO convert users to qdev and remove */
-void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
-                                    DriveInfo *hd1, qemu_irq irq)
-{
-    int i, trans;
-    DriveInfo *dinfo;
-    uint32_t cyls, heads, secs;
-
-    for(i = 0; i < 2; i++) {
-        dinfo = i == 0 ? hd0 : hd1;
-        ide_init1(bus, i);
-        if (dinfo) {
-            cyls  = dinfo->cyls;
-            heads = dinfo->heads;
-            secs  = dinfo->secs;
-            trans = dinfo->trans;
-            if (!cyls && !heads && !secs) {
-                hd_geometry_guess(dinfo->bdrv, &cyls, &heads, &secs, &trans);
-            } else if (trans == BIOS_ATA_TRANSLATION_AUTO) {
-                trans = hd_bios_chs_auto_trans(cyls, heads, secs);
-            }
-            if (cyls < 1 || cyls > 65535) {
-                error_report("cyls must be between 1 and 65535");
-                exit(1);
-            }
-            if (heads < 1 || heads > 16) {
-                error_report("heads must be between 1 and 16");
-                exit(1);
-            }
-            if (secs < 1 || secs > 255) {
-                error_report("secs must be between 1 and 255");
-                exit(1);
-            }
-            if (ide_init_drive(&bus->ifs[i], dinfo->bdrv,
-                               dinfo->media_cd ? IDE_CD : IDE_HD,
-                               NULL, dinfo->serial, NULL, 0,
-                               cyls, heads, secs, trans) < 0) {
-                error_report("Can't set up IDE drive %s", dinfo->id);
-                exit(1);
-            }
-            bdrv_attach_dev_nofail(dinfo->bdrv, &bus->ifs[i]);
-        } else {
-            ide_reset(&bus->ifs[i]);
-        }
-    }
-    bus->irq = irq;
-    bus->dma = &ide_dma_nop;
-}
-
 static const MemoryRegionPortio ide_portio_list[] = {
     { 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write },
     { 0, 2, 2, .read = ide_data_readw, .write = ide_data_writew },
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 5d1cf87..0567a52 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -553,8 +553,6 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
                    uint32_t cylinders, uint32_t heads, uint32_t secs,
                    int chs_trans);
 void ide_init2(IDEBus *bus, qemu_irq irq);
-void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
-                                    DriveInfo *hd1, qemu_irq irq);
 void ide_init_ioport(IDEBus *bus, ISADevice *isa, int iobase, int iobase2);
 
 void ide_exec_cmd(IDEBus *bus, uint32_t val);
commit a6cb20fcba97bffd893e532f8cc70442200d3e15
Author: Andreas Färber <afaerber at suse.de>
Date:   Sat Aug 3 10:32:49 2013 +0200

    microdrive: Coding Style cleanups
    
    Add missing braces.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c
index cdf0eb9..21d6495 100644
--- a/hw/ide/microdrive.c
+++ b/hw/ide/microdrive.c
@@ -103,10 +103,12 @@ static inline void md_interrupt_update(MicroDriveState *s)
 static void md_set_irq(void *opaque, int irq, int level)
 {
     MicroDriveState *s = opaque;
-    if (level)
+
+    if (level) {
         s->stat |= STAT_INT;
-    else
+    } else {
         s->stat &= ~STAT_INT;
+    }
 
     md_interrupt_update(s);
 }
@@ -142,10 +144,11 @@ static uint8_t md_attr_read(PCMCIACardState *card, uint32_t at)
     case 0x00:	/* Configuration Option Register */
         return s->opt;
     case 0x02:	/* Card Configuration Status Register */
-        if (s->ctrl & CTRL_IEN)
+        if (s->ctrl & CTRL_IEN) {
             return s->stat & ~STAT_INT;
-        else
+        } else {
             return s->stat;
+        }
     case 0x04:	/* Pin Replacement Register */
         return (s->pins & PINS_CRDY) | 0x0c;
     case 0x06:	/* Socket and Copy Register */
@@ -174,8 +177,9 @@ static void md_attr_write(PCMCIACardState *card, uint32_t at, uint8_t value)
         md_interrupt_update(s);
         break;
     case 0x02:	/* Card Configuration Status Register */
-        if ((s->stat ^ value) & STAT_PWRDWN)
+        if ((s->stat ^ value) & STAT_PWRDWN) {
             s->pins |= PINS_CRDY;
+        }
         s->stat &= 0x82;
         s->stat |= value & 0x74;
         md_interrupt_update(s);
@@ -201,23 +205,26 @@ static uint16_t md_common_read(PCMCIACardState *card, uint32_t at)
 
     switch (s->opt & OPT_MODE) {
     case OPT_MODE_MMAP:
-        if ((at & ~0x3ff) == 0x400)
+        if ((at & ~0x3ff) == 0x400) {
             at = 0;
+        }
         break;
     case OPT_MODE_IOMAP16:
         at &= 0xf;
         break;
     case OPT_MODE_IOMAP1:
-        if ((at & ~0xf) == 0x3f0)
+        if ((at & ~0xf) == 0x3f0) {
             at -= 0x3e8;
-        else if ((at & ~0xf) == 0x1f0)
+        } else if ((at & ~0xf) == 0x1f0) {
             at -= 0x1f0;
+        }
         break;
     case OPT_MODE_IOMAP2:
-        if ((at & ~0xf) == 0x370)
+        if ((at & ~0xf) == 0x370) {
             at -= 0x368;
-        else if ((at & ~0xf) == 0x170)
+        } else if ((at & ~0xf) == 0x170) {
             at -= 0x170;
+        }
     }
 
     switch (at) {
@@ -226,9 +233,9 @@ static uint16_t md_common_read(PCMCIACardState *card, uint32_t at)
         return ide_data_readw(&s->bus, 0);
 
         /* TODO: 8-bit accesses */
-        if (s->cycle)
+        if (s->cycle) {
             ret = s->io >> 8;
-        else {
+        } else {
             s->io = ide_data_readw(&s->bus, 0);
             ret = s->io & 0xff;
         }
@@ -240,10 +247,11 @@ static uint16_t md_common_read(PCMCIACardState *card, uint32_t at)
         return ide_ioport_read(&s->bus, 0x1);
     case 0xe:	/* Alternate Status */
         ifs = idebus_active_if(&s->bus);
-        if (ifs->bs)
+        if (ifs->bs) {
             return ifs->status;
-        else
+        } else {
             return 0;
+        }
     case 0xf:	/* Device Address */
         ifs = idebus_active_if(&s->bus);
         return 0xc2 | ((~ifs->select << 2) & 0x3c);
@@ -261,23 +269,26 @@ static void md_common_write(PCMCIACardState *card, uint32_t at, uint16_t value)
 
     switch (s->opt & OPT_MODE) {
     case OPT_MODE_MMAP:
-        if ((at & ~0x3ff) == 0x400)
+        if ((at & ~0x3ff) == 0x400) {
             at = 0;
+        }
         break;
     case OPT_MODE_IOMAP16:
         at &= 0xf;
         break;
     case OPT_MODE_IOMAP1:
-        if ((at & ~0xf) == 0x3f0)
+        if ((at & ~0xf) == 0x3f0) {
             at -= 0x3e8;
-        else if ((at & ~0xf) == 0x1f0)
+        } else if ((at & ~0xf) == 0x1f0) {
             at -= 0x1f0;
+        }
         break;
     case OPT_MODE_IOMAP2:
-        if ((at & ~0xf) == 0x370)
+        if ((at & ~0xf) == 0x370) {
             at -= 0x368;
-        else if ((at & ~0xf) == 0x170)
+        } else if ((at & ~0xf) == 0x170) {
             at -= 0x170;
+        }
     }
 
     switch (at) {
@@ -287,10 +298,11 @@ static void md_common_write(PCMCIACardState *card, uint32_t at, uint16_t value)
         break;
 
         /* TODO: 8-bit accesses */
-        if (s->cycle)
+        if (s->cycle) {
             ide_data_writew(&s->bus, 0, s->io | (value << 8));
-        else
+        } else {
             s->io = value & 0xff;
+        }
         s->cycle = !s->cycle;
         break;
     case 0x9:
@@ -546,8 +558,10 @@ static int dscm1xxxx_detach(PCMCIACardState *card)
 
 PCMCIACardState *dscm1xxxx_init(DriveInfo *dinfo)
 {
-    MicroDriveState *md = MICRODRIVE(object_new(TYPE_DSCM1XXXX));
-    PCMCIACardState *card = PCMCIA_CARD(md);
+    MicroDriveState *md;
+
+    md = MICRODRIVE(object_new(TYPE_DSCM1XXXX));
+    qdev_init_nofail(DEVICE(md));
 
     if (dinfo != NULL) {
         ide_create_drive(&md->bus, 0, dinfo);
@@ -556,7 +570,7 @@ PCMCIACardState *dscm1xxxx_init(DriveInfo *dinfo)
     md->bus.ifs[0].mdata_size = METADATA_SIZE;
     md->bus.ifs[0].mdata_storage = (uint8_t *) g_malloc0(METADATA_SIZE);
 
-    return card;
+    return PCMCIA_CARD(md);
 }
 
 static void dscm1xxxx_class_init(ObjectClass *oc, void *data)
commit d1f2c96a81a4d18b99b7f471bf58e65c9afab33f
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jul 17 19:46:16 2013 +0200

    pcmcia: QOM'ify PCMCIACardState and MicroDriveState
    
    Turn PCMCIACardState into a device.
    Move callbacks to new PCMCIACardClass.
    
    Derive TYPE_MICRODRIVE from TYPE_PCMCIA_CARD.
    Replace ide_init2_with_non_qdev_drives().
    
    Signed-off-by: Othmar Pasteka <pasteka at kabsi.at>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 0243d6a..d91b9cc 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -18,6 +18,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += net/
 devices-dirs-$(CONFIG_SOFTMMU) += nvram/
 devices-dirs-$(CONFIG_SOFTMMU) += pci/
 devices-dirs-$(CONFIG_PCI) += pci-bridge/ pci-host/
+devices-dirs-$(CONFIG_SOFTMMU) += pcmcia/
 devices-dirs-$(CONFIG_SOFTMMU) += scsi/
 devices-dirs-$(CONFIG_SOFTMMU) += sd/
 devices-dirs-$(CONFIG_SOFTMMU) += ssi/
diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c
index 92c1df0..cdf0eb9 100644
--- a/hw/ide/microdrive.c
+++ b/hw/ide/microdrive.c
@@ -30,15 +30,22 @@
 
 #include <hw/ide/internal.h>
 
+#define TYPE_MICRODRIVE "microdrive"
+#define MICRODRIVE(obj) OBJECT_CHECK(MicroDriveState, (obj), TYPE_MICRODRIVE)
+
 /***********************************************************/
 /* CF-ATA Microdrive */
 
 #define METADATA_SIZE	0x20
 
 /* DSCM-1XXXX Microdrive hard disk with CF+ II / PCMCIA interface.  */
-typedef struct {
+
+typedef struct MicroDriveState {
+    /*< private >*/
+    PCMCIACardState parent_obj;
+    /*< public >*/
+
     IDEBus bus;
-    PCMCIACardState card;
     uint32_t attr_base;
     uint32_t io_base;
 
@@ -81,10 +88,13 @@ enum md_ctrl {
 
 static inline void md_interrupt_update(MicroDriveState *s)
 {
-    if (!s->card.slot)
+    PCMCIACardState *card = PCMCIA_CARD(s);
+
+    if (card->slot == NULL) {
         return;
+    }
 
-    qemu_set_irq(s->card.slot->irq,
+    qemu_set_irq(card->slot->irq,
                     !(s->stat & STAT_INT) &&	/* Inverted */
                     !(s->ctrl & (CTRL_IEN | CTRL_SRST)) &&
                     !(s->opt & OPT_SRESET));
@@ -101,8 +111,10 @@ static void md_set_irq(void *opaque, int irq, int level)
     md_interrupt_update(s);
 }
 
-static void md_reset(MicroDriveState *s)
+static void md_reset(DeviceState *dev)
 {
+    MicroDriveState *s = MICRODRIVE(dev);
+
     s->opt = OPT_MODE_MMAP;
     s->stat = 0;
     s->pins = 0;
@@ -111,14 +123,17 @@ static void md_reset(MicroDriveState *s)
     ide_bus_reset(&s->bus);
 }
 
-static uint8_t md_attr_read(void *opaque, uint32_t at)
+static uint8_t md_attr_read(PCMCIACardState *card, uint32_t at)
 {
-    MicroDriveState *s = opaque;
+    MicroDriveState *s = MICRODRIVE(card);
+    PCMCIACardClass *pcc = PCMCIA_CARD_GET_CLASS(card);
+
     if (at < s->attr_base) {
-        if (at < s->card.cis_len)
-            return s->card.cis[at];
-        else
+        if (at < pcc->cis_len) {
+            return pcc->cis[at];
+        } else {
             return 0x00;
+        }
     }
 
     at -= s->attr_base;
@@ -144,16 +159,18 @@ static uint8_t md_attr_read(void *opaque, uint32_t at)
     return 0;
 }
 
-static void md_attr_write(void *opaque, uint32_t at, uint8_t value)
+static void md_attr_write(PCMCIACardState *card, uint32_t at, uint8_t value)
 {
-    MicroDriveState *s = opaque;
+    MicroDriveState *s = MICRODRIVE(card);
+
     at -= s->attr_base;
 
     switch (at) {
     case 0x00:	/* Configuration Option Register */
         s->opt = value & 0xcf;
-        if (value & OPT_SRESET)
-            md_reset(s);
+        if (value & OPT_SRESET) {
+            device_reset(DEVICE(s));
+        }
         md_interrupt_update(s);
         break;
     case 0x02:	/* Card Configuration Status Register */
@@ -175,9 +192,9 @@ static void md_attr_write(void *opaque, uint32_t at, uint8_t value)
     }
 }
 
-static uint16_t md_common_read(void *opaque, uint32_t at)
+static uint16_t md_common_read(PCMCIACardState *card, uint32_t at)
 {
-    MicroDriveState *s = opaque;
+    MicroDriveState *s = MICRODRIVE(card);
     IDEState *ifs;
     uint16_t ret;
     at -= s->io_base;
@@ -237,9 +254,9 @@ static uint16_t md_common_read(void *opaque, uint32_t at)
     return 0;
 }
 
-static void md_common_write(void *opaque, uint32_t at, uint16_t value)
+static void md_common_write(PCMCIACardState *card, uint32_t at, uint16_t value)
 {
-    MicroDriveState *s = opaque;
+    MicroDriveState *s = MICRODRIVE(card);
     at -= s->io_base;
 
     switch (s->opt & OPT_MODE) {
@@ -285,8 +302,9 @@ static void md_common_write(void *opaque, uint32_t at, uint16_t value)
         break;
     case 0xe:	/* Device Control */
         s->ctrl = value;
-        if (value & CTRL_SRST)
-            md_reset(s);
+        if (value & CTRL_SRST) {
+            device_reset(DEVICE(s));
+        }
         md_interrupt_update(s);
         break;
     default:
@@ -501,49 +519,107 @@ static const uint8_t dscm1xxxx_cis[0x14a] = {
     [0x146] = CISTPL_END,	/* Tuple End */
 };
 
-static int dscm1xxxx_attach(void *opaque)
+#define TYPE_DSCM1XXXX "dscm1xxxx"
+
+static int dscm1xxxx_attach(PCMCIACardState *card)
 {
-    MicroDriveState *md = opaque;
-    md->card.attr_read = md_attr_read;
-    md->card.attr_write = md_attr_write;
-    md->card.common_read = md_common_read;
-    md->card.common_write = md_common_write;
-    md->card.io_read = md_common_read;
-    md->card.io_write = md_common_write;
-
-    md->attr_base = md->card.cis[0x74] | (md->card.cis[0x76] << 8);
+    MicroDriveState *md = MICRODRIVE(card);
+    PCMCIACardClass *pcc = PCMCIA_CARD_GET_CLASS(card);
+
+    md->attr_base = pcc->cis[0x74] | (pcc->cis[0x76] << 8);
     md->io_base = 0x0;
 
-    md_reset(md);
+    device_reset(DEVICE(md));
     md_interrupt_update(md);
 
-    md->card.slot->card_string = "DSCM-1xxxx Hitachi Microdrive";
+    card->slot->card_string = "DSCM-1xxxx Hitachi Microdrive";
     return 0;
 }
 
-static int dscm1xxxx_detach(void *opaque)
+static int dscm1xxxx_detach(PCMCIACardState *card)
 {
-    MicroDriveState *md = opaque;
-    md_reset(md);
+    MicroDriveState *md = MICRODRIVE(card);
+
+    device_reset(DEVICE(md));
     return 0;
 }
 
-PCMCIACardState *dscm1xxxx_init(DriveInfo *bdrv)
+PCMCIACardState *dscm1xxxx_init(DriveInfo *dinfo)
 {
-    MicroDriveState *md = (MicroDriveState *) g_malloc0(sizeof(MicroDriveState));
-    md->card.state = md;
-    md->card.attach = dscm1xxxx_attach;
-    md->card.detach = dscm1xxxx_detach;
-    md->card.cis = dscm1xxxx_cis;
-    md->card.cis_len = sizeof(dscm1xxxx_cis);
-
-    ide_init2_with_non_qdev_drives(&md->bus, bdrv, NULL,
-                                   qemu_allocate_irqs(md_set_irq, md, 1)[0]);
+    MicroDriveState *md = MICRODRIVE(object_new(TYPE_DSCM1XXXX));
+    PCMCIACardState *card = PCMCIA_CARD(md);
+
+    if (dinfo != NULL) {
+        ide_create_drive(&md->bus, 0, dinfo);
+    }
     md->bus.ifs[0].drive_kind = IDE_CFATA;
     md->bus.ifs[0].mdata_size = METADATA_SIZE;
     md->bus.ifs[0].mdata_storage = (uint8_t *) g_malloc0(METADATA_SIZE);
 
-    vmstate_register(NULL, -1, &vmstate_microdrive, md);
+    return card;
+}
+
+static void dscm1xxxx_class_init(ObjectClass *oc, void *data)
+{
+    PCMCIACardClass *pcc = PCMCIA_CARD_CLASS(oc);
+
+    pcc->cis = dscm1xxxx_cis;
+    pcc->cis_len = sizeof(dscm1xxxx_cis);
+
+    pcc->attach = dscm1xxxx_attach;
+    pcc->detach = dscm1xxxx_detach;
+}
+
+static const TypeInfo dscm1xxxx_type_info = {
+    .name = TYPE_DSCM1XXXX,
+    .parent = TYPE_MICRODRIVE,
+    .class_init = dscm1xxxx_class_init,
+};
+
+static void microdrive_realize(DeviceState *dev, Error **errp)
+{
+    MicroDriveState *md = MICRODRIVE(dev);
+
+    ide_init2(&md->bus, qemu_allocate_irqs(md_set_irq, md, 1)[0]);
+}
+
+static void microdrive_init(Object *obj)
+{
+    MicroDriveState *md = MICRODRIVE(obj);
+
+    ide_bus_new(&md->bus, sizeof(md->bus), DEVICE(obj), 0, 1);
+}
 
-    return &md->card;
+static void microdrive_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+    PCMCIACardClass *pcc = PCMCIA_CARD_CLASS(oc);
+
+    pcc->attr_read = md_attr_read;
+    pcc->attr_write = md_attr_write;
+    pcc->common_read = md_common_read;
+    pcc->common_write = md_common_write;
+    pcc->io_read = md_common_read;
+    pcc->io_write = md_common_write;
+
+    dc->realize = microdrive_realize;
+    dc->reset = md_reset;
+    dc->vmsd = &vmstate_microdrive;
 }
+
+static const TypeInfo microdrive_type_info = {
+    .name = TYPE_MICRODRIVE,
+    .parent = TYPE_PCMCIA_CARD,
+    .instance_size = sizeof(MicroDriveState),
+    .instance_init = microdrive_init,
+    .abstract = true,
+    .class_init = microdrive_class_init,
+};
+
+static void microdrive_register_types(void)
+{
+    type_register_static(&microdrive_type_info);
+    type_register_static(&dscm1xxxx_type_info);
+}
+
+type_init(microdrive_register_types)
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 9fbcebd..f674365 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -38,7 +38,6 @@ obj-$(CONFIG_OMAP) += omap_gpmc.o
 obj-$(CONFIG_OMAP) += omap_l4.o
 obj-$(CONFIG_OMAP) += omap_sdrc.o
 obj-$(CONFIG_OMAP) += omap_tap.o
-obj-$(CONFIG_PXA2XX) += pxa2xx_pcmcia.o
 obj-$(CONFIG_SLAVIO) += slavio_misc.o
 obj-$(CONFIG_ZYNQ) += zynq_slcr.o
 
diff --git a/hw/misc/pxa2xx_pcmcia.c b/hw/misc/pxa2xx_pcmcia.c
deleted file mode 100644
index 76724a6..0000000
--- a/hw/misc/pxa2xx_pcmcia.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Intel XScale PXA255/270 PC Card and CompactFlash Interface.
- *
- * Copyright (c) 2006 Openedhand Ltd.
- * Written by Andrzej Zaborowski <balrog at zabor.org>
- *
- * This code is licensed under the GPLv2.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "hw/hw.h"
-#include "hw/pcmcia.h"
-#include "hw/arm/pxa.h"
-
-
-struct PXA2xxPCMCIAState {
-    PCMCIASocket slot;
-    PCMCIACardState *card;
-    MemoryRegion common_iomem;
-    MemoryRegion attr_iomem;
-    MemoryRegion iomem;
-
-    qemu_irq irq;
-    qemu_irq cd_irq;
-};
-
-static uint64_t pxa2xx_pcmcia_common_read(void *opaque,
-                hwaddr offset, unsigned size)
-{
-    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
-
-    if (s->slot.attached) {
-        return s->card->common_read(s->card->state, offset);
-    }
-
-    return 0;
-}
-
-static void pxa2xx_pcmcia_common_write(void *opaque, hwaddr offset,
-                                       uint64_t value, unsigned size)
-{
-    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
-
-    if (s->slot.attached) {
-        s->card->common_write(s->card->state, offset, value);
-    }
-}
-
-static uint64_t pxa2xx_pcmcia_attr_read(void *opaque,
-                hwaddr offset, unsigned size)
-{
-    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
-
-    if (s->slot.attached) {
-        return s->card->attr_read(s->card->state, offset);
-    }
-
-    return 0;
-}
-
-static void pxa2xx_pcmcia_attr_write(void *opaque, hwaddr offset,
-                                     uint64_t value, unsigned size)
-{
-    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
-
-    if (s->slot.attached) {
-        s->card->attr_write(s->card->state, offset, value);
-    }
-}
-
-static uint64_t pxa2xx_pcmcia_io_read(void *opaque,
-                hwaddr offset, unsigned size)
-{
-    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
-
-    if (s->slot.attached) {
-        return s->card->io_read(s->card->state, offset);
-    }
-
-    return 0;
-}
-
-static void pxa2xx_pcmcia_io_write(void *opaque, hwaddr offset,
-                                   uint64_t value, unsigned size)
-{
-    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
-
-    if (s->slot.attached) {
-        s->card->io_write(s->card->state, offset, value);
-    }
-}
-
-static const MemoryRegionOps pxa2xx_pcmcia_common_ops = {
-    .read = pxa2xx_pcmcia_common_read,
-    .write = pxa2xx_pcmcia_common_write,
-    .endianness = DEVICE_NATIVE_ENDIAN
-};
-
-static const MemoryRegionOps pxa2xx_pcmcia_attr_ops = {
-    .read = pxa2xx_pcmcia_attr_read,
-    .write = pxa2xx_pcmcia_attr_write,
-    .endianness = DEVICE_NATIVE_ENDIAN
-};
-
-static const MemoryRegionOps pxa2xx_pcmcia_io_ops = {
-    .read = pxa2xx_pcmcia_io_read,
-    .write = pxa2xx_pcmcia_io_write,
-    .endianness = DEVICE_NATIVE_ENDIAN
-};
-
-static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
-{
-    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
-    if (!s->irq)
-        return;
-
-    qemu_set_irq(s->irq, level);
-}
-
-PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
-                                      hwaddr base)
-{
-    PXA2xxPCMCIAState *s;
-
-    s = (PXA2xxPCMCIAState *)
-            g_malloc0(sizeof(PXA2xxPCMCIAState));
-
-    /* Socket I/O Memory Space */
-    memory_region_init_io(&s->iomem, NULL, &pxa2xx_pcmcia_io_ops, s,
-                          "pxa2xx-pcmcia-io", 0x04000000);
-    memory_region_add_subregion(sysmem, base | 0x00000000,
-                                &s->iomem);
-
-    /* Then next 64 MB is reserved */
-
-    /* Socket Attribute Memory Space */
-    memory_region_init_io(&s->attr_iomem, NULL, &pxa2xx_pcmcia_attr_ops, s,
-                          "pxa2xx-pcmcia-attribute", 0x04000000);
-    memory_region_add_subregion(sysmem, base | 0x08000000,
-                                &s->attr_iomem);
-
-    /* Socket Common Memory Space */
-    memory_region_init_io(&s->common_iomem, NULL, &pxa2xx_pcmcia_common_ops, s,
-                          "pxa2xx-pcmcia-common", 0x04000000);
-    memory_region_add_subregion(sysmem, base | 0x0c000000,
-                                &s->common_iomem);
-
-    if (base == 0x30000000)
-        s->slot.slot_string = "PXA PC Card Socket 1";
-    else
-        s->slot.slot_string = "PXA PC Card Socket 0";
-    s->slot.irq = qemu_allocate_irqs(pxa2xx_pcmcia_set_irq, s, 1)[0];
-    pcmcia_socket_register(&s->slot);
-
-    return s;
-}
-
-/* Insert a new card into a slot */
-int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card)
-{
-    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
-    if (s->slot.attached)
-        return -EEXIST;
-
-    if (s->cd_irq) {
-        qemu_irq_raise(s->cd_irq);
-    }
-
-    s->card = card;
-
-    s->slot.attached = 1;
-    s->card->slot = &s->slot;
-    s->card->attach(s->card->state);
-
-    return 0;
-}
-
-/* Eject card from the slot */
-int pxa2xx_pcmcia_detach(void *opaque)
-{
-    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
-    if (!s->slot.attached)
-        return -ENOENT;
-
-    s->card->detach(s->card->state);
-    s->card->slot = NULL;
-    s->card = NULL;
-
-    s->slot.attached = 0;
-
-    if (s->irq)
-        qemu_irq_lower(s->irq);
-    if (s->cd_irq)
-        qemu_irq_lower(s->cd_irq);
-
-    return 0;
-}
-
-/* Who to notify on card events */
-void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq)
-{
-    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
-    s->irq = irq;
-    s->cd_irq = cd_irq;
-}
diff --git a/hw/pcmcia/Makefile.objs b/hw/pcmcia/Makefile.objs
new file mode 100644
index 0000000..4eac060
--- /dev/null
+++ b/hw/pcmcia/Makefile.objs
@@ -0,0 +1,2 @@
+common-obj-y += pcmcia.o
+obj-$(CONFIG_PXA2XX) += pxa2xx.o
diff --git a/hw/pcmcia/pcmcia.c b/hw/pcmcia/pcmcia.c
new file mode 100644
index 0000000..78efe5a
--- /dev/null
+++ b/hw/pcmcia/pcmcia.c
@@ -0,0 +1,24 @@
+/*
+ * PCMCIA emulation
+ *
+ * Copyright 2013 SUSE LINUX Products GmbH
+ */
+
+#include "qemu-common.h"
+#include "hw/hw.h"
+#include "hw/pcmcia.h"
+
+static const TypeInfo pcmcia_card_type_info = {
+    .name = TYPE_PCMCIA_CARD,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(PCMCIACardState),
+    .abstract = true,
+    .class_size = sizeof(PCMCIACardClass),
+};
+
+static void pcmcia_register_types(void)
+{
+    type_register_static(&pcmcia_card_type_info);
+}
+
+type_init(pcmcia_register_types)
diff --git a/hw/pcmcia/pxa2xx.c b/hw/pcmcia/pxa2xx.c
new file mode 100644
index 0000000..2c515be
--- /dev/null
+++ b/hw/pcmcia/pxa2xx.c
@@ -0,0 +1,229 @@
+/*
+ * Intel XScale PXA255/270 PC Card and CompactFlash Interface.
+ *
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Written by Andrzej Zaborowski <balrog at zabor.org>
+ *
+ * This code is licensed under the GPLv2.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include "hw/hw.h"
+#include "hw/pcmcia.h"
+#include "hw/arm/pxa.h"
+
+
+struct PXA2xxPCMCIAState {
+    PCMCIASocket slot;
+    PCMCIACardState *card;
+    MemoryRegion common_iomem;
+    MemoryRegion attr_iomem;
+    MemoryRegion iomem;
+
+    qemu_irq irq;
+    qemu_irq cd_irq;
+};
+
+static uint64_t pxa2xx_pcmcia_common_read(void *opaque,
+                hwaddr offset, unsigned size)
+{
+    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
+    PCMCIACardClass *pcc;
+
+    if (s->slot.attached) {
+        pcc = PCMCIA_CARD_GET_CLASS(s->card);
+        return pcc->common_read(s->card, offset);
+    }
+
+    return 0;
+}
+
+static void pxa2xx_pcmcia_common_write(void *opaque, hwaddr offset,
+                                       uint64_t value, unsigned size)
+{
+    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
+    PCMCIACardClass *pcc;
+
+    if (s->slot.attached) {
+        pcc = PCMCIA_CARD_GET_CLASS(s->card);
+        pcc->common_write(s->card, offset, value);
+    }
+}
+
+static uint64_t pxa2xx_pcmcia_attr_read(void *opaque,
+                hwaddr offset, unsigned size)
+{
+    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
+    PCMCIACardClass *pcc;
+
+    if (s->slot.attached) {
+        pcc = PCMCIA_CARD_GET_CLASS(s->card);
+        return pcc->attr_read(s->card, offset);
+    }
+
+    return 0;
+}
+
+static void pxa2xx_pcmcia_attr_write(void *opaque, hwaddr offset,
+                                     uint64_t value, unsigned size)
+{
+    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
+    PCMCIACardClass *pcc;
+
+    if (s->slot.attached) {
+        pcc = PCMCIA_CARD_GET_CLASS(s->card);
+        pcc->attr_write(s->card, offset, value);
+    }
+}
+
+static uint64_t pxa2xx_pcmcia_io_read(void *opaque,
+                hwaddr offset, unsigned size)
+{
+    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
+    PCMCIACardClass *pcc;
+
+    if (s->slot.attached) {
+        pcc = PCMCIA_CARD_GET_CLASS(s->card);
+        return pcc->io_read(s->card, offset);
+    }
+
+    return 0;
+}
+
+static void pxa2xx_pcmcia_io_write(void *opaque, hwaddr offset,
+                                   uint64_t value, unsigned size)
+{
+    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
+    PCMCIACardClass *pcc;
+
+    if (s->slot.attached) {
+        pcc = PCMCIA_CARD_GET_CLASS(s->card);
+        pcc->io_write(s->card, offset, value);
+    }
+}
+
+static const MemoryRegionOps pxa2xx_pcmcia_common_ops = {
+    .read = pxa2xx_pcmcia_common_read,
+    .write = pxa2xx_pcmcia_common_write,
+    .endianness = DEVICE_NATIVE_ENDIAN
+};
+
+static const MemoryRegionOps pxa2xx_pcmcia_attr_ops = {
+    .read = pxa2xx_pcmcia_attr_read,
+    .write = pxa2xx_pcmcia_attr_write,
+    .endianness = DEVICE_NATIVE_ENDIAN
+};
+
+static const MemoryRegionOps pxa2xx_pcmcia_io_ops = {
+    .read = pxa2xx_pcmcia_io_read,
+    .write = pxa2xx_pcmcia_io_write,
+    .endianness = DEVICE_NATIVE_ENDIAN
+};
+
+static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
+{
+    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
+    if (!s->irq)
+        return;
+
+    qemu_set_irq(s->irq, level);
+}
+
+PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
+                                      hwaddr base)
+{
+    PXA2xxPCMCIAState *s;
+
+    s = (PXA2xxPCMCIAState *)
+            g_malloc0(sizeof(PXA2xxPCMCIAState));
+
+    /* Socket I/O Memory Space */
+    memory_region_init_io(&s->iomem, NULL, &pxa2xx_pcmcia_io_ops, s,
+                          "pxa2xx-pcmcia-io", 0x04000000);
+    memory_region_add_subregion(sysmem, base | 0x00000000,
+                                &s->iomem);
+
+    /* Then next 64 MB is reserved */
+
+    /* Socket Attribute Memory Space */
+    memory_region_init_io(&s->attr_iomem, NULL, &pxa2xx_pcmcia_attr_ops, s,
+                          "pxa2xx-pcmcia-attribute", 0x04000000);
+    memory_region_add_subregion(sysmem, base | 0x08000000,
+                                &s->attr_iomem);
+
+    /* Socket Common Memory Space */
+    memory_region_init_io(&s->common_iomem, NULL, &pxa2xx_pcmcia_common_ops, s,
+                          "pxa2xx-pcmcia-common", 0x04000000);
+    memory_region_add_subregion(sysmem, base | 0x0c000000,
+                                &s->common_iomem);
+
+    if (base == 0x30000000)
+        s->slot.slot_string = "PXA PC Card Socket 1";
+    else
+        s->slot.slot_string = "PXA PC Card Socket 0";
+    s->slot.irq = qemu_allocate_irqs(pxa2xx_pcmcia_set_irq, s, 1)[0];
+    pcmcia_socket_register(&s->slot);
+
+    return s;
+}
+
+/* Insert a new card into a slot */
+int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card)
+{
+    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
+    PCMCIACardClass *pcc;
+
+    if (s->slot.attached) {
+        return -EEXIST;
+    }
+
+    if (s->cd_irq) {
+        qemu_irq_raise(s->cd_irq);
+    }
+
+    s->card = card;
+    pcc = PCMCIA_CARD_GET_CLASS(s->card);
+
+    s->slot.attached = true;
+    s->card->slot = &s->slot;
+    pcc->attach(s->card);
+
+    return 0;
+}
+
+/* Eject card from the slot */
+int pxa2xx_pcmcia_detach(void *opaque)
+{
+    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
+    PCMCIACardClass *pcc;
+
+    if (!s->slot.attached) {
+        return -ENOENT;
+    }
+
+    pcc = PCMCIA_CARD_GET_CLASS(s->card);
+    pcc->detach(s->card);
+    s->card->slot = NULL;
+    s->card = NULL;
+
+    s->slot.attached = false;
+
+    if (s->irq) {
+        qemu_irq_lower(s->irq);
+    }
+    if (s->cd_irq) {
+        qemu_irq_lower(s->cd_irq);
+    }
+
+    return 0;
+}
+
+/* Who to notify on card events */
+void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq)
+{
+    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
+    s->irq = irq;
+    s->cd_irq = cd_irq;
+}
diff --git a/include/hw/pcmcia.h b/include/hw/pcmcia.h
index f916693..2695d3c 100644
--- a/include/hw/pcmcia.h
+++ b/include/hw/pcmcia.h
@@ -3,11 +3,11 @@
 
 /* PCMCIA/Cardbus */
 
-#include "qemu-common.h"
+#include "hw/qdev.h"
 
-typedef struct {
+typedef struct PCMCIASocket {
     qemu_irq irq;
-    int attached;
+    bool attached;
     const char *slot_string;
     const char *card_string;
 } PCMCIASocket;
@@ -16,22 +16,42 @@ void pcmcia_socket_register(PCMCIASocket *socket);
 void pcmcia_socket_unregister(PCMCIASocket *socket);
 void pcmcia_info(Monitor *mon, const QDict *qdict);
 
+#define TYPE_PCMCIA_CARD "pcmcia-card"
+#define PCMCIA_CARD(obj) \
+    OBJECT_CHECK(PCMCIACardState, (obj), TYPE_PCMCIA_CARD)
+#define PCMCIA_CARD_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(PCMCIACardClass, obj, TYPE_PCMCIA_CARD)
+#define PCMCIA_CARD_CLASS(cls) \
+    OBJECT_CLASS_CHECK(PCMCIACardClass, cls, TYPE_PCMCIA_CARD)
+
 struct PCMCIACardState {
-    void *state;
+    /*< private >*/
+    DeviceState parent_obj;
+    /*< public >*/
+
     PCMCIASocket *slot;
-    int (*attach)(void *state);
-    int (*detach)(void *state);
+};
+
+typedef struct PCMCIACardClass {
+    /*< private >*/
+    DeviceClass parent_class;
+    /*< public >*/
+
+    int (*attach)(PCMCIACardState *state);
+    int (*detach)(PCMCIACardState *state);
+
     const uint8_t *cis;
     int cis_len;
 
     /* Only valid if attached */
-    uint8_t (*attr_read)(void *state, uint32_t address);
-    void (*attr_write)(void *state, uint32_t address, uint8_t value);
-    uint16_t (*common_read)(void *state, uint32_t address);
-    void (*common_write)(void *state, uint32_t address, uint16_t value);
-    uint16_t (*io_read)(void *state, uint32_t address);
-    void (*io_write)(void *state, uint32_t address, uint16_t value);
-};
+    uint8_t (*attr_read)(PCMCIACardState *card, uint32_t address);
+    void (*attr_write)(PCMCIACardState *card, uint32_t address, uint8_t value);
+    uint16_t (*common_read)(PCMCIACardState *card, uint32_t address);
+    void (*common_write)(PCMCIACardState *card,
+                         uint32_t address, uint16_t value);
+    uint16_t (*io_read)(PCMCIACardState *card, uint32_t address);
+    void (*io_write)(PCMCIACardState *card, uint32_t address, uint16_t value);
+} PCMCIACardClass;
 
 #define CISTPL_DEVICE		0x01	/* 5V Device Information Tuple */
 #define CISTPL_NO_LINK		0x14	/* No Link Tuple */
commit 853ca11dafb625e36db036b8e83d6e2168703e1f
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jul 17 19:06:47 2013 +0200

    pxa: Fix typo "dettach"
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/misc/pxa2xx_pcmcia.c b/hw/misc/pxa2xx_pcmcia.c
index ef71a2a..76724a6 100644
--- a/hw/misc/pxa2xx_pcmcia.c
+++ b/hw/misc/pxa2xx_pcmcia.c
@@ -178,7 +178,7 @@ int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card)
 }
 
 /* Eject card from the slot */
-int pxa2xx_pcmcia_dettach(void *opaque)
+int pxa2xx_pcmcia_detach(void *opaque)
 {
     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
     if (!s->slot.attached)
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
index 668232c..a4e1a66 100644
--- a/include/hw/arm/pxa.h
+++ b/include/hw/arm/pxa.h
@@ -97,7 +97,7 @@ typedef struct PXA2xxPCMCIAState PXA2xxPCMCIAState;
 PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
                                       hwaddr base);
 int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card);
-int pxa2xx_pcmcia_dettach(void *opaque);
+int pxa2xx_pcmcia_detach(void *opaque);
 void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq);
 
 /* pxa2xx_keypad.c */
commit a25ebcacdda4dd6e68ac62acb4c72f3f868b938d
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Mon Oct 7 12:35:01 2013 +0300

    qom: Fix pointer to int property helpers' documentation
    
    Relocate to alongside the other object_property_add_* helpers while at it.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/include/qom/object.h b/include/qom/object.h
index d02172a..a275db2 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -795,27 +795,6 @@ void object_property_add(Object *obj, const char *name, const char *type,
 void object_property_del(Object *obj, const char *name, Error **errp);
 
 /**
- * object_property_add_uint8_ptr:
- * object_property_add_uint16_ptr:
- * object_property_add_uint32_ptr:
- * object_property_add_uint64_ptr:
- * @obj: the object to add a property to
- * @name: the name of the property
- * @v: pointer to value
- *
- * Add an integer property in memory.  This function will add a
- * property of the appropriate type.
- */
-void object_property_add_uint8_ptr(Object *obj, const char *name,
-                                   const uint8_t *v, Error **errp);
-void object_property_add_uint16_ptr(Object *obj, const char *name,
-                                    const uint16_t *v, Error **errp);
-void object_property_add_uint32_ptr(Object *obj, const char *name,
-                                    const uint32_t *v, Error **errp);
-void object_property_add_uint64_ptr(Object *obj, const char *name,
-                                    const uint64_t *v, Error **Errp);
-
-/**
  * object_property_find:
  * @obj: the object
  * @name: the name of the property
@@ -1134,6 +1113,58 @@ void object_property_add_bool(Object *obj, const char *name,
                               Error **errp);
 
 /**
+ * object_property_add_uint8_ptr:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @v: pointer to value
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Add an integer property in memory.  This function will add a
+ * property of type 'uint8'.
+ */
+void object_property_add_uint8_ptr(Object *obj, const char *name,
+                                   const uint8_t *v, Error **errp);
+
+/**
+ * object_property_add_uint16_ptr:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @v: pointer to value
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Add an integer property in memory.  This function will add a
+ * property of type 'uint16'.
+ */
+void object_property_add_uint16_ptr(Object *obj, const char *name,
+                                    const uint16_t *v, Error **errp);
+
+/**
+ * object_property_add_uint32_ptr:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @v: pointer to value
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Add an integer property in memory.  This function will add a
+ * property of type 'uint32'.
+ */
+void object_property_add_uint32_ptr(Object *obj, const char *name,
+                                    const uint32_t *v, Error **errp);
+
+/**
+ * object_property_add_uint64_ptr:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @v: pointer to value
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Add an integer property in memory.  This function will add a
+ * property of type 'uint64'.
+ */
+void object_property_add_uint64_ptr(Object *obj, const char *name,
+                                    const uint64_t *v, Error **Errp);
+
+/**
  * object_child_foreach:
  * @obj: the object whose children will be navigated
  * @fn: the iterator function to be called
commit 852e2c5008563692a8868260480e76b95bb9018c
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Oct 7 16:42:34 2013 +0200

    qdev-monitor: Inline qdev_init() for device_add
    
    For historic reasons, qdev_init() unparents the device on failure.
    Inline this to make the error paths clearer and consistent.
    
    Reviewed-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/qdev-monitor.c b/qdev-monitor.c
index a46da32..dc37a43 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -458,6 +458,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
     const char *driver, *path, *id;
     DeviceState *dev;
     BusState *bus = NULL;
+    Error *err = NULL;
 
     driver = qemu_opt_get(opts, "driver");
     if (!driver) {
@@ -540,7 +541,11 @@ DeviceState *qdev_device_add(QemuOpts *opts)
                                   OBJECT(dev), NULL);
         g_free(name);
     }
-    if (qdev_init(dev) < 0) {
+    object_property_set_bool(OBJECT(dev), true, "realized", &err);
+    if (err != NULL) {
+        qerror_report_err(err);
+        error_free(err);
+        object_unparent(OBJECT(dev));
         object_unref(OBJECT(dev));
         qerror_report(QERR_DEVICE_INIT_FAILED, driver);
         return NULL;
commit 2bcb0c62f620a7033e9e25c5b645d50bf9e6a8f2
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Oct 7 16:17:54 2013 +0200

    qdev-monitor: Avoid qdev as variable name
    
    Prepares for bringing error cleanup code into canonical QOM form.
    
    Includes a whitespace removal after curly brace by Stefan.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/qdev-monitor.c b/qdev-monitor.c
index 8e8ed4c..a46da32 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -456,7 +456,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
     ObjectClass *oc;
     DeviceClass *dc;
     const char *driver, *path, *id;
-    DeviceState *qdev;
+    DeviceState *dev;
     BusState *bus = NULL;
 
     driver = qemu_opt_get(opts, "driver");
@@ -515,38 +515,38 @@ DeviceState *qdev_device_add(QemuOpts *opts)
     }
 
     /* create device, set properties */
-    qdev = DEVICE(object_new(driver));
+    dev = DEVICE(object_new(driver));
 
     if (bus) {
-        qdev_set_parent_bus(qdev, bus);
+        qdev_set_parent_bus(dev, bus);
     }
 
     id = qemu_opts_id(opts);
     if (id) {
-        qdev->id = id;
+        dev->id = id;
     }
-    if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
-        object_unparent(OBJECT(qdev));
-        object_unref(OBJECT(qdev));
+    if (qemu_opt_foreach(opts, set_property, dev, 1) != 0) {
+        object_unparent(OBJECT(dev));
+        object_unref(OBJECT(dev));
         return NULL;
     }
-    if (qdev->id) {
-        object_property_add_child(qdev_get_peripheral(), qdev->id,
-                                  OBJECT(qdev), NULL);
+    if (dev->id) {
+        object_property_add_child(qdev_get_peripheral(), dev->id,
+                                  OBJECT(dev), NULL);
     } else {
         static int anon_count;
         gchar *name = g_strdup_printf("device[%d]", anon_count++);
         object_property_add_child(qdev_get_peripheral_anon(), name,
-                                  OBJECT(qdev), NULL);
+                                  OBJECT(dev), NULL);
         g_free(name);
-    }        
-    if (qdev_init(qdev) < 0) {
-        object_unref(OBJECT(qdev));
+    }
+    if (qdev_init(dev) < 0) {
+        object_unref(OBJECT(dev));
         qerror_report(QERR_DEVICE_INIT_FAILED, driver);
         return NULL;
     }
-    qdev->opts = opts;
-    return qdev;
+    dev->opts = opts;
+    return dev;
 }
 
 
commit 02a5c4c97422b40034f31265e0f139f7846172a8
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Wed Sep 11 14:54:09 2013 +0200

    qdev: Drop misleading qdev_free() function
    
    The qdev_free() function name is misleading since all the function does
    is unlink the device from its parent.  The device is not necessarily
    freed.
    
    The device will be freed when its QObject refcount reaches zero.  It is
    usual for the parent (bus) to hold the final reference but there are
    cases where something else holds a reference so "free" is a misleading
    name.
    
    Call object_unparent(obj) directly instead of having a qdev wrapper
    function.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 3bcd890..93849c8 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -328,7 +328,7 @@ static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots)
             if (pc->no_hotplug) {
                 slot_free = false;
             } else {
-                qdev_free(qdev);
+                object_unparent(OBJECT(qdev));
             }
         }
     }
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 533f6dd..e374a93 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -164,7 +164,7 @@ int qdev_init(DeviceState *dev)
     if (local_err != NULL) {
         qerror_report_err(local_err);
         error_free(local_err);
-        qdev_free(dev);
+        object_unparent(OBJECT(dev));
         return -1;
     }
     return 0;
@@ -258,7 +258,7 @@ void qbus_reset_all_fn(void *opaque)
 int qdev_simple_unplug_cb(DeviceState *dev)
 {
     /* just zap it */
-    qdev_free(dev);
+    object_unparent(OBJECT(dev));
     return 0;
 }
 
@@ -280,12 +280,6 @@ void qdev_init_nofail(DeviceState *dev)
     }
 }
 
-/* Unlink device from bus and free the structure.  */
-void qdev_free(DeviceState *dev)
-{
-    object_unparent(OBJECT(dev));
-}
-
 void qdev_machine_creation_done(void)
 {
     /*
@@ -458,7 +452,7 @@ static void bus_unparent(Object *obj)
 
     while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
         DeviceState *dev = kid->child;
-        qdev_free(dev);
+        object_unparent(OBJECT(dev));
     }
     if (bus->parent) {
         QLIST_REMOVE(bus, sibling);
diff --git a/hw/pci/pci-hotplug-old.c b/hw/pci/pci-hotplug-old.c
index 619fe47..8dbc3c1 100644
--- a/hw/pci/pci-hotplug-old.c
+++ b/hw/pci/pci-hotplug-old.c
@@ -248,7 +248,7 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
         }
         dev = pci_create(bus, devfn, "virtio-blk-pci");
         if (qdev_prop_set_drive(&dev->qdev, "drive", dinfo->bdrv) < 0) {
-            qdev_free(&dev->qdev);
+            object_unparent(OBJECT(dev));
             dev = NULL;
             break;
         }
diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
index e6b22b8..290abab 100644
--- a/hw/pci/pci_bridge.c
+++ b/hw/pci/pci_bridge.c
@@ -391,7 +391,7 @@ void pci_bridge_exitfn(PCIDevice *pci_dev)
     pci_bridge_region_cleanup(s, s->windows);
     memory_region_destroy(&s->address_space_mem);
     memory_region_destroy(&s->address_space_io);
-    /* qbus_free() is called automatically by qdev_free() */
+    /* qbus_free() is called automatically during device deletion */
 }
 
 /*
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 268a696..ca60cf2 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -251,7 +251,7 @@ static int pcie_cap_slot_hotplug(DeviceState *qdev,
                                    PCI_EXP_SLTSTA_PDS);
         pcie_cap_slot_event(d, PCI_EXP_HP_EV_PDC);
     } else {
-        qdev_free(&pci_dev->qdev);
+        object_unparent(OBJECT(pci_dev));
         pci_word_test_and_clear_mask(exp_cap + PCI_EXP_SLTSTA,
                                      PCI_EXP_SLTSTA_PDS);
         pcie_cap_slot_event(d, PCI_EXP_HP_EV_PDC);
diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
index 0bbd36e..576244b 100644
--- a/hw/pci/shpc.c
+++ b/hw/pci/shpc.c
@@ -254,7 +254,7 @@ static void shpc_free_devices_in_slot(SHPCDevice *shpc, int slot)
          ++devfn) {
         PCIDevice *affected_dev = shpc->sec_bus->devices[devfn];
         if (affected_dev) {
-            qdev_free(&affected_dev->qdev);
+            object_unparent(OBJECT(affected_dev));
         }
     }
 }
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index cd67db5..f93a81c 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -1239,7 +1239,7 @@ static int virtio_ccw_busdev_unplug(DeviceState *dev)
 
     css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, 1, 0);
 
-    qdev_free(dev);
+    object_unparent(OBJECT(dev));
     return 0;
 }
 
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 24ec52f..ea916d1 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -178,7 +178,7 @@ static int scsi_qdev_init(DeviceState *qdev)
         d = scsi_device_find(bus, dev->channel, dev->id, dev->lun);
         assert(d);
         if (d->lun == dev->lun && dev != d) {
-            qdev_free(&d->qdev);
+            object_unparent(OBJECT(d));
         }
     }
 
@@ -231,13 +231,13 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
     }
     if (qdev_prop_set_drive(dev, "drive", bdrv) < 0) {
         error_setg(errp, "Setting drive property failed");
-        qdev_free(dev);
+        object_unparent(OBJECT(dev));
         return NULL;
     }
     object_property_set_bool(OBJECT(dev), true, "realized", &err);
     if (err != NULL) {
         error_propagate(errp, err);
-        qdev_free(dev);
+        object_unparent(OBJECT(dev));
         return NULL;
     }
     return SCSI_DEVICE(dev);
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 72d5b92..ca329be 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -356,8 +356,9 @@ void usb_port_location(USBPort *downstream, USBPort *upstream, int portnr)
 
 void usb_unregister_port(USBBus *bus, USBPort *port)
 {
-    if (port->dev)
-        qdev_free(&port->dev->qdev);
+    if (port->dev) {
+        object_unparent(OBJECT(port->dev));
+    }
     QTAILQ_REMOVE(&bus->free, port, next);
     bus->nfree--;
 }
@@ -505,7 +506,7 @@ int usb_device_delete_addr(int busnr, int addr)
         return -1;
     dev = port->dev;
 
-    qdev_free(&dev->qdev);
+    object_unparent(OBJECT(dev));
     return 0;
 }
 
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index 1d81ac2..c434c56 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -703,7 +703,7 @@ static USBDevice *usb_msd_init(USBBus *bus, const char *filename)
         return NULL;
     }
     if (qdev_prop_set_drive(&dev->qdev, "drive", dinfo->bdrv) < 0) {
-        qdev_free(&dev->qdev);
+        object_unparent(OBJECT(dev));
         return NULL;
     }
     if (qdev_init(&dev->qdev) < 0)
diff --git a/hw/usb/host-legacy.c b/hw/usb/host-legacy.c
index 3a5f705..3cc9c42 100644
--- a/hw/usb/host-legacy.c
+++ b/hw/usb/host-legacy.c
@@ -132,7 +132,7 @@ USBDevice *usb_host_device_open(USBBus *bus, const char *devname)
     return dev;
 
 fail:
-    qdev_free(&dev->qdev);
+    object_unparent(OBJECT(dev));
     return NULL;
 }
 
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index 6849a01..e6b103c 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -67,7 +67,6 @@ void virtio_bus_reset(VirtioBusState *bus)
 /* Destroy the VirtIODevice */
 void virtio_bus_destroy_device(VirtioBusState *bus)
 {
-    DeviceState *qdev;
     BusState *qbus = BUS(bus);
     VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);
     DPRINTF("%s: remove device.\n", qbus->name);
@@ -76,8 +75,7 @@ void virtio_bus_destroy_device(VirtioBusState *bus)
         if (klass->device_unplug != NULL) {
             klass->device_unplug(qbus->parent);
         }
-        qdev = DEVICE(bus->vdev);
-        qdev_free(qdev);
+        object_unparent(OBJECT(bus->vdev));
         bus->vdev = NULL;
     }
 }
diff --git a/hw/xen/xen_platform.c b/hw/xen/xen_platform.c
index 79bf0b3..70875e4 100644
--- a/hw/xen/xen_platform.c
+++ b/hw/xen/xen_platform.c
@@ -95,7 +95,7 @@ static void unplug_nic(PCIBus *b, PCIDevice *d, void *o)
     if (pci_get_word(d->config + PCI_CLASS_DEVICE) ==
             PCI_CLASS_NETWORK_ETHERNET
             && strcmp(d->name, "xen-pci-passthrough") != 0) {
-        qdev_free(DEVICE(d));
+        object_unparent(OBJECT(d));
     }
 }
 
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index e191ca0..f2043a6 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -221,7 +221,6 @@ void qdev_init_nofail(DeviceState *dev);
 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
                                  int required_for_version);
 void qdev_unplug(DeviceState *dev, Error **errp);
-void qdev_free(DeviceState *dev);
 int qdev_simple_unplug_cb(DeviceState *dev);
 void qdev_machine_creation_done(void);
 bool qdev_machine_modified(void);
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 9099d3d..8e8ed4c 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -526,7 +526,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
         qdev->id = id;
     }
     if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
-        qdev_free(qdev);
+        object_unparent(OBJECT(qdev));
         object_unref(OBJECT(qdev));
         return NULL;
     }
commit ee6abeb6ec08473713848ce9028110f1684853b7
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Tue Sep 10 18:21:08 2013 +0200

    qdev-monitor: Unref device when device_add fails
    
    qdev_device_add() leaks the created device upon failure.  I suspect this
    problem crept in because qdev_free() unparents the device but does not
    drop a reference - confusing name.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/qdev-monitor.c b/qdev-monitor.c
index 753bab7..9099d3d 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -527,6 +527,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
     }
     if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
         qdev_free(qdev);
+        object_unref(OBJECT(qdev));
         return NULL;
     }
     if (qdev->id) {
@@ -540,6 +541,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
         g_free(name);
     }        
     if (qdev_init(qdev) < 0) {
+        object_unref(OBJECT(qdev));
         qerror_report(QERR_DEVICE_INIT_FAILED, driver);
         return NULL;
     }
commit 2fa4e56d88aa0039062bbc7f9a88e9f90c77ed94
Author: Igor Mammedov <imammedo at redhat.com>
Date:   Tue Sep 17 15:32:32 2013 +0200

    qdev-monitor: Fix crash when device_add is called with abstract driver
    
    User is able to crash running QEMU when following monitor
    command is called:
    
     device_add intel-hda-generic
    
    Crash is caused by assertion in object_initialize_with_type()
    when type is abstract.
    
    Checking if type is abstract before instance is created in
    qdev_device_add() allows to prevent crash on incorrect user input.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/qdev-monitor.c b/qdev-monitor.c
index 8f9f6cb..753bab7 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -481,6 +481,12 @@ DeviceState *qdev_device_add(QemuOpts *opts)
         return NULL;
     }
 
+    if (object_class_is_abstract(oc)) {
+        qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver",
+                      "non-abstract device type");
+        return NULL;
+    }
+
     dc = DEVICE_CLASS(oc);
 
     /* find bus */
commit f4d85795605c7dc594c013221a4b6d62967bd8ab
Author: Andreas Färber <afaerber at suse.de>
Date:   Sat Aug 24 01:21:22 2013 +0200

    qdev-monitor: Clean up qdev_device_add() variable naming
    
    Avoid confusion between object (obj) and object class (oc).
    Tidy DeviceClass variable while at it (k -> dc).
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/qdev-monitor.c b/qdev-monitor.c
index a02c925..8f9f6cb 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -453,8 +453,8 @@ static BusState *qbus_find(const char *path)
 
 DeviceState *qdev_device_add(QemuOpts *opts)
 {
-    ObjectClass *obj;
-    DeviceClass *k;
+    ObjectClass *oc;
+    DeviceClass *dc;
     const char *driver, *path, *id;
     DeviceState *qdev;
     BusState *bus = NULL;
@@ -466,22 +466,22 @@ DeviceState *qdev_device_add(QemuOpts *opts)
     }
 
     /* find driver */
-    obj = object_class_by_name(driver);
-    if (!obj) {
+    oc = object_class_by_name(driver);
+    if (!oc) {
         const char *typename = find_typename_by_alias(driver);
 
         if (typename) {
             driver = typename;
-            obj = object_class_by_name(driver);
+            oc = object_class_by_name(driver);
         }
     }
 
-    if (!obj) {
+    if (!oc) {
         qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "device type");
         return NULL;
     }
 
-    k = DEVICE_CLASS(obj);
+    dc = DEVICE_CLASS(oc);
 
     /* find bus */
     path = qemu_opt_get(opts, "bus");
@@ -490,16 +490,16 @@ DeviceState *qdev_device_add(QemuOpts *opts)
         if (!bus) {
             return NULL;
         }
-        if (!object_dynamic_cast(OBJECT(bus), k->bus_type)) {
+        if (!object_dynamic_cast(OBJECT(bus), dc->bus_type)) {
             qerror_report(QERR_BAD_BUS_FOR_DEVICE,
                           driver, object_get_typename(OBJECT(bus)));
             return NULL;
         }
-    } else if (k->bus_type != NULL) {
-        bus = qbus_find_recursive(sysbus_get_default(), NULL, k->bus_type);
+    } else if (dc->bus_type != NULL) {
+        bus = qbus_find_recursive(sysbus_get_default(), NULL, dc->bus_type);
         if (!bus) {
             qerror_report(QERR_NO_BUS_FOR_DEVICE,
-                          k->bus_type, driver);
+                          dc->bus_type, driver);
             return NULL;
         }
     }
commit 9c219b7be6eeaf31dccaf9b74d738e0ce2ea813b
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Aug 19 01:33:59 2013 +0200

    arm11mpcore: Split off RealView MPCore
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/cpu/Makefile.objs b/hw/cpu/Makefile.objs
index df287c1..6381238 100644
--- a/hw/cpu/Makefile.objs
+++ b/hw/cpu/Makefile.objs
@@ -1,4 +1,5 @@
 obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o
+obj-$(CONFIG_REALVIEW) += realview_mpcore.o
 obj-$(CONFIG_A9MPCORE) += a9mpcore.o
 obj-$(CONFIG_A15MPCORE) += a15mpcore.o
 obj-$(CONFIG_ICC_BUS) += icc_bus.o
diff --git a/hw/cpu/arm11mpcore.c b/hw/cpu/arm11mpcore.c
index 0ec27c7..717d3e4 100644
--- a/hw/cpu/arm11mpcore.c
+++ b/hw/cpu/arm11mpcore.c
@@ -134,126 +134,6 @@ static void mpcore_priv_initfn(Object *obj)
     qdev_set_parent_bus(DEVICE(&s->wdtimer), sysbus_get_default());
 }
 
-#define TYPE_REALVIEW_MPCORE_RIRQ "realview_mpcore"
-#define REALVIEW_MPCORE_RIRQ(obj) \
-    OBJECT_CHECK(mpcore_rirq_state, (obj), TYPE_REALVIEW_MPCORE_RIRQ)
-
-/* Dummy PIC to route IRQ lines.  The baseboard has 4 independent IRQ
-   controllers.  The output of these, plus some of the raw input lines
-   are fed into a single SMP-aware interrupt controller on the CPU.  */
-typedef struct {
-    SysBusDevice parent_obj;
-
-    qemu_irq cpuic[32];
-    qemu_irq rvic[4][64];
-    uint32_t num_cpu;
-
-    ARM11MPCorePriveState priv;
-    RealViewGICState gic[4];
-} mpcore_rirq_state;
-
-/* Map baseboard IRQs onto CPU IRQ lines.  */
-static const int mpcore_irq_map[32] = {
-    -1, -1, -1, -1,  1,  2, -1, -1,
-    -1, -1,  6, -1,  4,  5, -1, -1,
-    -1, 14, 15,  0,  7,  8, -1, -1,
-    -1, -1, -1, -1,  9,  3, -1, -1,
-};
-
-static void mpcore_rirq_set_irq(void *opaque, int irq, int level)
-{
-    mpcore_rirq_state *s = (mpcore_rirq_state *)opaque;
-    int i;
-
-    for (i = 0; i < 4; i++) {
-        qemu_set_irq(s->rvic[i][irq], level);
-    }
-    if (irq < 32) {
-        irq = mpcore_irq_map[irq];
-        if (irq >= 0) {
-            qemu_set_irq(s->cpuic[irq], level);
-        }
-    }
-}
-
-static void realview_mpcore_realize(DeviceState *dev, Error **errp)
-{
-    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-    mpcore_rirq_state *s = REALVIEW_MPCORE_RIRQ(dev);
-    DeviceState *priv = DEVICE(&s->priv);
-    DeviceState *gic;
-    SysBusDevice *gicbusdev;
-    Error *err = NULL;
-    int n;
-    int i;
-
-    qdev_prop_set_uint32(priv, "num-cpu", s->num_cpu);
-    object_property_set_bool(OBJECT(&s->priv), true, "realized", &err);
-    if (err != NULL) {
-        error_propagate(errp, err);
-        return;
-    }
-    sysbus_pass_irq(sbd, SYS_BUS_DEVICE(&s->priv));
-    for (i = 0; i < 32; i++) {
-        s->cpuic[i] = qdev_get_gpio_in(priv, i);
-    }
-    /* ??? IRQ routing is hardcoded to "normal" mode.  */
-    for (n = 0; n < 4; n++) {
-        object_property_set_bool(OBJECT(&s->gic[n]), true, "realized", &err);
-        if (err != NULL) {
-            error_propagate(errp, err);
-            return;
-        }
-        gic = DEVICE(&s->gic[n]);
-        gicbusdev = SYS_BUS_DEVICE(&s->gic[n]);
-        sysbus_mmio_map(gicbusdev, 0, 0x10040000 + n * 0x10000);
-        sysbus_connect_irq(gicbusdev, 0, s->cpuic[10 + n]);
-        for (i = 0; i < 64; i++) {
-            s->rvic[n][i] = qdev_get_gpio_in(gic, i);
-        }
-    }
-    qdev_init_gpio_in(dev, mpcore_rirq_set_irq, 64);
-}
-
-static void mpcore_rirq_init(Object *obj)
-{
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
-    mpcore_rirq_state *s = REALVIEW_MPCORE_RIRQ(obj);
-    SysBusDevice *privbusdev;
-    int i;
-
-    object_initialize(&s->priv, sizeof(s->priv), TYPE_ARM11MPCORE_PRIV);
-    qdev_set_parent_bus(DEVICE(&s->priv), sysbus_get_default());
-    privbusdev = SYS_BUS_DEVICE(&s->priv);
-    sysbus_init_mmio(sbd, sysbus_mmio_get_region(privbusdev, 0));
-
-    for (i = 0; i < 4; i++) {
-        object_initialize(&s->gic[i], sizeof(s->gic[i]), TYPE_REALVIEW_GIC);
-        qdev_set_parent_bus(DEVICE(&s->gic[i]), sysbus_get_default());
-    }
-}
-
-static Property mpcore_rirq_properties[] = {
-    DEFINE_PROP_UINT32("num-cpu", mpcore_rirq_state, num_cpu, 1),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void mpcore_rirq_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-
-    dc->realize = realview_mpcore_realize;
-    dc->props = mpcore_rirq_properties;
-}
-
-static const TypeInfo mpcore_rirq_info = {
-    .name          = TYPE_REALVIEW_MPCORE_RIRQ,
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(mpcore_rirq_state),
-    .instance_init = mpcore_rirq_init,
-    .class_init    = mpcore_rirq_class_init,
-};
-
 static Property mpcore_priv_properties[] = {
     DEFINE_PROP_UINT32("num-cpu", ARM11MPCorePriveState, num_cpu, 1),
     /* The ARM11 MPCORE TRM says the on-chip controller may have
@@ -286,7 +166,6 @@ static const TypeInfo mpcore_priv_info = {
 
 static void arm11mpcore_register_types(void)
 {
-    type_register_static(&mpcore_rirq_info);
     type_register_static(&mpcore_priv_info);
 }
 
diff --git a/hw/cpu/realview_mpcore.c b/hw/cpu/realview_mpcore.c
new file mode 100644
index 0000000..c39a2da
--- /dev/null
+++ b/hw/cpu/realview_mpcore.c
@@ -0,0 +1,139 @@
+/*
+ * RealView ARM11MPCore internal peripheral emulation
+ *
+ * Copyright (c) 2006-2007 CodeSourcery.
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ * Written by Paul Brook and Andreas Färber
+ *
+ * This code is licensed under the GPL.
+ */
+
+#include "hw/cpu/arm11mpcore.h"
+#include "hw/intc/realview_gic.h"
+
+#define TYPE_REALVIEW_MPCORE_RIRQ "realview_mpcore"
+#define REALVIEW_MPCORE_RIRQ(obj) \
+    OBJECT_CHECK(mpcore_rirq_state, (obj), TYPE_REALVIEW_MPCORE_RIRQ)
+
+/* Dummy PIC to route IRQ lines.  The baseboard has 4 independent IRQ
+   controllers.  The output of these, plus some of the raw input lines
+   are fed into a single SMP-aware interrupt controller on the CPU.  */
+typedef struct {
+    SysBusDevice parent_obj;
+
+    qemu_irq cpuic[32];
+    qemu_irq rvic[4][64];
+    uint32_t num_cpu;
+
+    ARM11MPCorePriveState priv;
+    RealViewGICState gic[4];
+} mpcore_rirq_state;
+
+/* Map baseboard IRQs onto CPU IRQ lines.  */
+static const int mpcore_irq_map[32] = {
+    -1, -1, -1, -1,  1,  2, -1, -1,
+    -1, -1,  6, -1,  4,  5, -1, -1,
+    -1, 14, 15,  0,  7,  8, -1, -1,
+    -1, -1, -1, -1,  9,  3, -1, -1,
+};
+
+static void mpcore_rirq_set_irq(void *opaque, int irq, int level)
+{
+    mpcore_rirq_state *s = (mpcore_rirq_state *)opaque;
+    int i;
+
+    for (i = 0; i < 4; i++) {
+        qemu_set_irq(s->rvic[i][irq], level);
+    }
+    if (irq < 32) {
+        irq = mpcore_irq_map[irq];
+        if (irq >= 0) {
+            qemu_set_irq(s->cpuic[irq], level);
+        }
+    }
+}
+
+static void realview_mpcore_realize(DeviceState *dev, Error **errp)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    mpcore_rirq_state *s = REALVIEW_MPCORE_RIRQ(dev);
+    DeviceState *priv = DEVICE(&s->priv);
+    DeviceState *gic;
+    SysBusDevice *gicbusdev;
+    Error *err = NULL;
+    int n;
+    int i;
+
+    qdev_prop_set_uint32(priv, "num-cpu", s->num_cpu);
+    object_property_set_bool(OBJECT(&s->priv), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_pass_irq(sbd, SYS_BUS_DEVICE(&s->priv));
+    for (i = 0; i < 32; i++) {
+        s->cpuic[i] = qdev_get_gpio_in(priv, i);
+    }
+    /* ??? IRQ routing is hardcoded to "normal" mode.  */
+    for (n = 0; n < 4; n++) {
+        object_property_set_bool(OBJECT(&s->gic[n]), true, "realized", &err);
+        if (err != NULL) {
+            error_propagate(errp, err);
+            return;
+        }
+        gic = DEVICE(&s->gic[n]);
+        gicbusdev = SYS_BUS_DEVICE(&s->gic[n]);
+        sysbus_mmio_map(gicbusdev, 0, 0x10040000 + n * 0x10000);
+        sysbus_connect_irq(gicbusdev, 0, s->cpuic[10 + n]);
+        for (i = 0; i < 64; i++) {
+            s->rvic[n][i] = qdev_get_gpio_in(gic, i);
+        }
+    }
+    qdev_init_gpio_in(dev, mpcore_rirq_set_irq, 64);
+}
+
+static void mpcore_rirq_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    mpcore_rirq_state *s = REALVIEW_MPCORE_RIRQ(obj);
+    SysBusDevice *privbusdev;
+    int i;
+
+    object_initialize(&s->priv, sizeof(s->priv), TYPE_ARM11MPCORE_PRIV);
+    qdev_set_parent_bus(DEVICE(&s->priv), sysbus_get_default());
+    privbusdev = SYS_BUS_DEVICE(&s->priv);
+    sysbus_init_mmio(sbd, sysbus_mmio_get_region(privbusdev, 0));
+
+    for (i = 0; i < 4; i++) {
+        object_initialize(&s->gic[i], sizeof(s->gic[i]), TYPE_REALVIEW_GIC);
+        qdev_set_parent_bus(DEVICE(&s->gic[i]), sysbus_get_default());
+    }
+}
+
+static Property mpcore_rirq_properties[] = {
+    DEFINE_PROP_UINT32("num-cpu", mpcore_rirq_state, num_cpu, 1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void mpcore_rirq_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = realview_mpcore_realize;
+    dc->props = mpcore_rirq_properties;
+}
+
+static const TypeInfo mpcore_rirq_info = {
+    .name          = TYPE_REALVIEW_MPCORE_RIRQ,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(mpcore_rirq_state),
+    .instance_init = mpcore_rirq_init,
+    .class_init    = mpcore_rirq_class_init,
+};
+
+static void realview_mpcore_register_types(void)
+{
+    type_register_static(&mpcore_rirq_info);
+}
+
+type_init(realview_mpcore_register_types)
commit 7b960dc37df088f9ca71bdc2a611864eae38c5c4
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Aug 19 01:27:19 2013 +0200

    arm11mpcore: Prepare for QOM embedding
    
    Move state struct, type constant and cast macro to a new header.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/cpu/arm11mpcore.c b/hw/cpu/arm11mpcore.c
index 578e3d3..0ec27c7 100644
--- a/hw/cpu/arm11mpcore.c
+++ b/hw/cpu/arm11mpcore.c
@@ -7,33 +7,8 @@
  * This code is licensed under the GPL.
  */
 
-#include "hw/sysbus.h"
-#include "hw/misc/arm11scu.h"
-#include "hw/intc/arm_gic.h"
+#include "hw/cpu/arm11mpcore.h"
 #include "hw/intc/realview_gic.h"
-#include "hw/timer/arm_mptimer.h"
-#include "qemu/timer.h"
-
-/* MPCore private memory region.  */
-
-#define TYPE_ARM11MPCORE_PRIV "arm11mpcore_priv"
-#define ARM11MPCORE_PRIV(obj) \
-    OBJECT_CHECK(ARM11MPCorePriveState, (obj), TYPE_ARM11MPCORE_PRIV)
-
-typedef struct ARM11MPCorePriveState {
-    SysBusDevice parent_obj;
-
-    uint32_t num_cpu;
-    MemoryRegion container;
-    uint32_t num_irq;
-
-    ARM11SCUState scu;
-    GICState gic;
-    ARMMPTimerState mptimer;
-    ARMMPTimerState wdtimer;
-} ARM11MPCorePriveState;
-
-/* Per-CPU private memory mapped IO.  */
 
 
 static void mpcore_priv_set_irq(void *opaque, int irq, int level)
diff --git a/include/hw/cpu/arm11mpcore.h b/include/hw/cpu/arm11mpcore.h
new file mode 100644
index 0000000..6196109
--- /dev/null
+++ b/include/hw/cpu/arm11mpcore.h
@@ -0,0 +1,35 @@
+/*
+ * ARM11MPCore internal peripheral emulation.
+ *
+ * Copyright (c) 2006-2007 CodeSourcery.
+ * Written by Paul Brook
+ *
+ * This code is licensed under the GPL.
+ */
+
+#ifndef HW_CPU_ARM11MPCORE_H
+#define HW_CPU_ARM11MPCORE_H
+
+#include "hw/sysbus.h"
+#include "hw/misc/arm11scu.h"
+#include "hw/intc/arm_gic.h"
+#include "hw/timer/arm_mptimer.h"
+
+#define TYPE_ARM11MPCORE_PRIV "arm11mpcore_priv"
+#define ARM11MPCORE_PRIV(obj) \
+    OBJECT_CHECK(ARM11MPCorePriveState, (obj), TYPE_ARM11MPCORE_PRIV)
+
+typedef struct ARM11MPCorePriveState {
+    SysBusDevice parent_obj;
+
+    uint32_t num_cpu;
+    MemoryRegion container;
+    uint32_t num_irq;
+
+    ARM11SCUState scu;
+    GICState gic;
+    ARMMPTimerState mptimer;
+    ARMMPTimerState wdtimer;
+} ARM11MPCorePriveState;
+
+#endif
commit 306476eaec483afbbf7f31abeae97874e6d3d29c
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Aug 18 23:38:15 2013 +0200

    arm11mpcore: Convert mpcore_rirq_state to QOM realize
    
    Embed ARM11MPCorePriveState and RealViewGICState and replace SysBus
    initfn with realizefn.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/cpu/arm11mpcore.c b/hw/cpu/arm11mpcore.c
index f372283..578e3d3 100644
--- a/hw/cpu/arm11mpcore.c
+++ b/hw/cpu/arm11mpcore.c
@@ -10,6 +10,7 @@
 #include "hw/sysbus.h"
 #include "hw/misc/arm11scu.h"
 #include "hw/intc/arm_gic.h"
+#include "hw/intc/realview_gic.h"
 #include "hw/timer/arm_mptimer.h"
 #include "qemu/timer.h"
 
@@ -168,10 +169,12 @@ static void mpcore_priv_initfn(Object *obj)
 typedef struct {
     SysBusDevice parent_obj;
 
-    SysBusDevice *priv;
     qemu_irq cpuic[32];
     qemu_irq rvic[4][64];
     uint32_t num_cpu;
+
+    ARM11MPCorePriveState priv;
+    RealViewGICState gic[4];
 } mpcore_rirq_state;
 
 /* Map baseboard IRQs onto CPU IRQ lines.  */
@@ -198,34 +201,61 @@ static void mpcore_rirq_set_irq(void *opaque, int irq, int level)
     }
 }
 
-static int realview_mpcore_init(SysBusDevice *sbd)
+static void realview_mpcore_realize(DeviceState *dev, Error **errp)
 {
-    DeviceState *dev = DEVICE(sbd);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
     mpcore_rirq_state *s = REALVIEW_MPCORE_RIRQ(dev);
+    DeviceState *priv = DEVICE(&s->priv);
     DeviceState *gic;
-    DeviceState *priv;
+    SysBusDevice *gicbusdev;
+    Error *err = NULL;
     int n;
     int i;
 
-    priv = qdev_create(NULL, TYPE_ARM11MPCORE_PRIV);
     qdev_prop_set_uint32(priv, "num-cpu", s->num_cpu);
-    qdev_init_nofail(priv);
-    s->priv = SYS_BUS_DEVICE(priv);
-    sysbus_pass_irq(sbd, s->priv);
+    object_property_set_bool(OBJECT(&s->priv), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_pass_irq(sbd, SYS_BUS_DEVICE(&s->priv));
     for (i = 0; i < 32; i++) {
         s->cpuic[i] = qdev_get_gpio_in(priv, i);
     }
     /* ??? IRQ routing is hardcoded to "normal" mode.  */
     for (n = 0; n < 4; n++) {
-        gic = sysbus_create_simple("realview_gic", 0x10040000 + n * 0x10000,
-                                   s->cpuic[10 + n]);
+        object_property_set_bool(OBJECT(&s->gic[n]), true, "realized", &err);
+        if (err != NULL) {
+            error_propagate(errp, err);
+            return;
+        }
+        gic = DEVICE(&s->gic[n]);
+        gicbusdev = SYS_BUS_DEVICE(&s->gic[n]);
+        sysbus_mmio_map(gicbusdev, 0, 0x10040000 + n * 0x10000);
+        sysbus_connect_irq(gicbusdev, 0, s->cpuic[10 + n]);
         for (i = 0; i < 64; i++) {
             s->rvic[n][i] = qdev_get_gpio_in(gic, i);
         }
     }
     qdev_init_gpio_in(dev, mpcore_rirq_set_irq, 64);
-    sysbus_init_mmio(sbd, sysbus_mmio_get_region(s->priv, 0));
-    return 0;
+}
+
+static void mpcore_rirq_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    mpcore_rirq_state *s = REALVIEW_MPCORE_RIRQ(obj);
+    SysBusDevice *privbusdev;
+    int i;
+
+    object_initialize(&s->priv, sizeof(s->priv), TYPE_ARM11MPCORE_PRIV);
+    qdev_set_parent_bus(DEVICE(&s->priv), sysbus_get_default());
+    privbusdev = SYS_BUS_DEVICE(&s->priv);
+    sysbus_init_mmio(sbd, sysbus_mmio_get_region(privbusdev, 0));
+
+    for (i = 0; i < 4; i++) {
+        object_initialize(&s->gic[i], sizeof(s->gic[i]), TYPE_REALVIEW_GIC);
+        qdev_set_parent_bus(DEVICE(&s->gic[i]), sysbus_get_default());
+    }
 }
 
 static Property mpcore_rirq_properties[] = {
@@ -236,9 +266,8 @@ static Property mpcore_rirq_properties[] = {
 static void mpcore_rirq_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    k->init = realview_mpcore_init;
+    dc->realize = realview_mpcore_realize;
     dc->props = mpcore_rirq_properties;
 }
 
@@ -246,6 +275,7 @@ static const TypeInfo mpcore_rirq_info = {
     .name          = TYPE_REALVIEW_MPCORE_RIRQ,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(mpcore_rirq_state),
+    .instance_init = mpcore_rirq_init,
     .class_init    = mpcore_rirq_class_init,
 };
 
commit ce31825de64c305cbf0def5657edac21aab7368b
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Aug 19 00:48:55 2013 +0200

    realview_gic: Prepare for QOM embedding
    
    Move state struct, type constant and cast macro to a new header.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/intc/realview_gic.c b/hw/intc/realview_gic.c
index 4ff48bb..6c81296 100644
--- a/hw/intc/realview_gic.c
+++ b/hw/intc/realview_gic.c
@@ -7,20 +7,7 @@
  * This code is licensed under the GPL.
  */
 
-#include "hw/sysbus.h"
-#include "hw/intc/arm_gic.h"
-
-#define TYPE_REALVIEW_GIC "realview_gic"
-#define REALVIEW_GIC(obj) \
-    OBJECT_CHECK(RealViewGICState, (obj), TYPE_REALVIEW_GIC)
-
-typedef struct RealViewGICState {
-    SysBusDevice parent_obj;
-
-    MemoryRegion container;
-
-    GICState gic;
-} RealViewGICState;
+#include "hw/intc/realview_gic.h"
 
 static void realview_gic_set_irq(void *opaque, int irq, int level)
 {
diff --git a/include/hw/intc/realview_gic.h b/include/hw/intc/realview_gic.h
new file mode 100644
index 0000000..1783ea1
--- /dev/null
+++ b/include/hw/intc/realview_gic.h
@@ -0,0 +1,28 @@
+/*
+ * ARM RealView Emulation Baseboard Interrupt Controller
+ *
+ * Copyright (c) 2006-2007 CodeSourcery.
+ * Written by Paul Brook
+ *
+ * This code is licensed under the GPL.
+ */
+
+#ifndef HW_INTC_REALVIEW_GIC_H
+#define HW_INTC_REALVIEW_GIC_H
+
+#include "hw/sysbus.h"
+#include "hw/intc/arm_gic.h"
+
+#define TYPE_REALVIEW_GIC "realview_gic"
+#define REALVIEW_GIC(obj) \
+    OBJECT_CHECK(RealViewGICState, (obj), TYPE_REALVIEW_GIC)
+
+typedef struct RealViewGICState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion container;
+
+    GICState gic;
+} RealViewGICState;
+
+#endif
commit 612daf06283e2cf6b3aa6178826516512d219de0
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Aug 19 00:37:07 2013 +0200

    realview_gic: Convert to QOM realize
    
    Embed GICState and replace SysBus initfn with realizefn.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/intc/realview_gic.c b/hw/intc/realview_gic.c
index ce80447..4ff48bb 100644
--- a/hw/intc/realview_gic.c
+++ b/hw/intc/realview_gic.c
@@ -8,40 +8,46 @@
  */
 
 #include "hw/sysbus.h"
+#include "hw/intc/arm_gic.h"
 
 #define TYPE_REALVIEW_GIC "realview_gic"
 #define REALVIEW_GIC(obj) \
     OBJECT_CHECK(RealViewGICState, (obj), TYPE_REALVIEW_GIC)
 
-typedef struct {
+typedef struct RealViewGICState {
     SysBusDevice parent_obj;
 
-    DeviceState *gic;
     MemoryRegion container;
+
+    GICState gic;
 } RealViewGICState;
 
 static void realview_gic_set_irq(void *opaque, int irq, int level)
 {
     RealViewGICState *s = (RealViewGICState *)opaque;
-    qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
+
+    qemu_set_irq(qdev_get_gpio_in(DEVICE(&s->gic), irq), level);
 }
 
-static int realview_gic_init(SysBusDevice *sbd)
+static void realview_gic_realize(DeviceState *dev, Error **errp)
 {
-    DeviceState *dev = DEVICE(sbd);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
     RealViewGICState *s = REALVIEW_GIC(dev);
     SysBusDevice *busdev;
+    Error *err = NULL;
     /* The GICs on the RealView boards have a fixed nonconfigurable
      * number of interrupt lines, so we don't need to expose this as
      * a qdev property.
      */
     int numirq = 96;
 
-    s->gic = qdev_create(NULL, "arm_gic");
-    qdev_prop_set_uint32(s->gic, "num-cpu", 1);
-    qdev_prop_set_uint32(s->gic, "num-irq", numirq);
-    qdev_init_nofail(s->gic);
-    busdev = SYS_BUS_DEVICE(s->gic);
+    qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", numirq);
+    object_property_set_bool(OBJECT(&s->gic), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+    busdev = SYS_BUS_DEVICE(&s->gic);
 
     /* Pass through outbound IRQ lines from the GIC */
     sysbus_pass_irq(sbd, busdev);
@@ -49,27 +55,40 @@ static int realview_gic_init(SysBusDevice *sbd)
     /* Pass through inbound GPIO lines to the GIC */
     qdev_init_gpio_in(dev, realview_gic_set_irq, numirq - 32);
 
-    memory_region_init(&s->container, OBJECT(s),
-                       "realview-gic-container", 0x2000);
     memory_region_add_subregion(&s->container, 0,
                                 sysbus_mmio_get_region(busdev, 1));
     memory_region_add_subregion(&s->container, 0x1000,
                                 sysbus_mmio_get_region(busdev, 0));
+}
+
+static void realview_gic_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    RealViewGICState *s = REALVIEW_GIC(obj);
+    DeviceState *gicdev;
+
+    memory_region_init(&s->container, OBJECT(s),
+                       "realview-gic-container", 0x2000);
     sysbus_init_mmio(sbd, &s->container);
-    return 0;
+
+    object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC);
+    gicdev = DEVICE(&s->gic);
+    qdev_set_parent_bus(gicdev, sysbus_get_default());
+    qdev_prop_set_uint32(gicdev, "num-cpu", 1);
 }
 
-static void realview_gic_class_init(ObjectClass *klass, void *data)
+static void realview_gic_class_init(ObjectClass *oc, void *data)
 {
-    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(oc);
 
-    sdc->init = realview_gic_init;
+    dc->realize = realview_gic_realize;
 }
 
 static const TypeInfo realview_gic_info = {
     .name          = TYPE_REALVIEW_GIC,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(RealViewGICState),
+    .instance_init = realview_gic_init,
     .class_init    = realview_gic_class_init,
 };
 
commit 08602ac5bf4f024d7e979de3a4e5df87db01b0ae
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Aug 18 22:04:31 2013 +0200

    arm11mpcore: Convert ARM11MPCorePriveState to QOM realize
    
    Embed child devices and replace SysBus initfn with realizefn.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/cpu/arm11mpcore.c b/hw/cpu/arm11mpcore.c
index 5dcc73a..f372283 100644
--- a/hw/cpu/arm11mpcore.c
+++ b/hw/cpu/arm11mpcore.c
@@ -9,6 +9,8 @@
 
 #include "hw/sysbus.h"
 #include "hw/misc/arm11scu.h"
+#include "hw/intc/arm_gic.h"
+#include "hw/timer/arm_mptimer.h"
 #include "qemu/timer.h"
 
 /* MPCore private memory region.  */
@@ -22,12 +24,12 @@ typedef struct ARM11MPCorePriveState {
 
     uint32_t num_cpu;
     MemoryRegion container;
-    DeviceState *mptimer;
-    DeviceState *wdtimer;
-    DeviceState *gic;
     uint32_t num_irq;
 
     ARM11SCUState scu;
+    GICState gic;
+    ARMMPTimerState mptimer;
+    ARMMPTimerState wdtimer;
 } ARM11MPCorePriveState;
 
 /* Per-CPU private memory mapped IO.  */
@@ -36,16 +38,18 @@ typedef struct ARM11MPCorePriveState {
 static void mpcore_priv_set_irq(void *opaque, int irq, int level)
 {
     ARM11MPCorePriveState *s = (ARM11MPCorePriveState *)opaque;
-    qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
+
+    qemu_set_irq(qdev_get_gpio_in(DEVICE(&s->gic), irq), level);
 }
 
 static void mpcore_priv_map_setup(ARM11MPCorePriveState *s)
 {
     int i;
     SysBusDevice *scubusdev = SYS_BUS_DEVICE(&s->scu);
-    SysBusDevice *gicbusdev = SYS_BUS_DEVICE(s->gic);
-    SysBusDevice *timerbusdev = SYS_BUS_DEVICE(s->mptimer);
-    SysBusDevice *wdtbusdev = SYS_BUS_DEVICE(s->wdtimer);
+    DeviceState *gicdev = DEVICE(&s->gic);
+    SysBusDevice *gicbusdev = SYS_BUS_DEVICE(&s->gic);
+    SysBusDevice *timerbusdev = SYS_BUS_DEVICE(&s->mptimer);
+    SysBusDevice *wdtbusdev = SYS_BUS_DEVICE(&s->wdtimer);
 
     memory_region_add_subregion(&s->container, 0,
                                 sysbus_mmio_get_region(scubusdev, 0));
@@ -76,44 +80,58 @@ static void mpcore_priv_map_setup(ARM11MPCorePriveState *s)
     for (i = 0; i < s->num_cpu; i++) {
         int ppibase = (s->num_irq - 32) + i * 32;
         sysbus_connect_irq(timerbusdev, i,
-                           qdev_get_gpio_in(s->gic, ppibase + 29));
+                           qdev_get_gpio_in(gicdev, ppibase + 29));
         sysbus_connect_irq(wdtbusdev, i,
-                           qdev_get_gpio_in(s->gic, ppibase + 30));
+                           qdev_get_gpio_in(gicdev, ppibase + 30));
     }
 }
 
-static int mpcore_priv_init(SysBusDevice *sbd)
+static void mpcore_priv_realize(DeviceState *dev, Error **errp)
 {
-    DeviceState *dev = DEVICE(sbd);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
     ARM11MPCorePriveState *s = ARM11MPCORE_PRIV(dev);
     DeviceState *scudev = DEVICE(&s->scu);
+    DeviceState *gicdev = DEVICE(&s->gic);
+    DeviceState *mptimerdev = DEVICE(&s->mptimer);
+    DeviceState *wdtimerdev = DEVICE(&s->wdtimer);
+    Error *err = NULL;
 
     qdev_prop_set_uint32(scudev, "num-cpu", s->num_cpu);
-    qdev_init_nofail(scudev);
+    object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
 
-    s->gic = qdev_create(NULL, "arm_gic");
-    qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
-    qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
-    /* Request the legacy 11MPCore GIC behaviour: */
-    qdev_prop_set_uint32(s->gic, "revision", 0);
-    qdev_init_nofail(s->gic);
+    qdev_prop_set_uint32(gicdev, "num-cpu", s->num_cpu);
+    qdev_prop_set_uint32(gicdev, "num-irq", s->num_irq);
+    object_property_set_bool(OBJECT(&s->gic), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
 
     /* Pass through outbound IRQ lines from the GIC */
-    sysbus_pass_irq(sbd, SYS_BUS_DEVICE(s->gic));
+    sysbus_pass_irq(sbd, SYS_BUS_DEVICE(&s->gic));
 
     /* Pass through inbound GPIO lines to the GIC */
     qdev_init_gpio_in(dev, mpcore_priv_set_irq, s->num_irq - 32);
 
-    s->mptimer = qdev_create(NULL, "arm_mptimer");
-    qdev_prop_set_uint32(s->mptimer, "num-cpu", s->num_cpu);
-    qdev_init_nofail(s->mptimer);
+    qdev_prop_set_uint32(mptimerdev, "num-cpu", s->num_cpu);
+    object_property_set_bool(OBJECT(&s->mptimer), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
 
-    s->wdtimer = qdev_create(NULL, "arm_mptimer");
-    qdev_prop_set_uint32(s->wdtimer, "num-cpu", s->num_cpu);
-    qdev_init_nofail(s->wdtimer);
+    qdev_prop_set_uint32(wdtimerdev, "num-cpu", s->num_cpu);
+    object_property_set_bool(OBJECT(&s->wdtimer), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
 
     mpcore_priv_map_setup(s);
-    return 0;
 }
 
 static void mpcore_priv_initfn(Object *obj)
@@ -127,6 +145,17 @@ static void mpcore_priv_initfn(Object *obj)
 
     object_initialize(&s->scu, sizeof(s->scu), TYPE_ARM11_SCU);
     qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
+
+    object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC);
+    qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default());
+    /* Request the legacy 11MPCore GIC behaviour: */
+    qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 0);
+
+    object_initialize(&s->mptimer, sizeof(s->mptimer), TYPE_ARM_MPTIMER);
+    qdev_set_parent_bus(DEVICE(&s->mptimer), sysbus_get_default());
+
+    object_initialize(&s->wdtimer, sizeof(s->wdtimer), TYPE_ARM_MPTIMER);
+    qdev_set_parent_bus(DEVICE(&s->wdtimer), sysbus_get_default());
 }
 
 #define TYPE_REALVIEW_MPCORE_RIRQ "realview_mpcore"
@@ -237,9 +266,8 @@ static Property mpcore_priv_properties[] = {
 static void mpcore_priv_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    k->init = mpcore_priv_init;
+    dc->realize = mpcore_priv_realize;
     dc->props = mpcore_priv_properties;
 }
 
commit 53cb9a1c2ffa78f5b5f6e4084dc03b98558cea4f
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Aug 18 20:07:36 2013 +0200

    arm11mpcore: Split off SCU device
    
    Inspired by a9scu.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 7e69137..a555eef 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -61,6 +61,7 @@ CONFIG_BITBANG_I2C=y
 CONFIG_FRAMEBUFFER=y
 CONFIG_XILINX_SPIPS=y
 
+CONFIG_ARM11SCU=y
 CONFIG_A9SCU=y
 CONFIG_MARVELL_88W8618=y
 CONFIG_OMAP=y
diff --git a/hw/cpu/arm11mpcore.c b/hw/cpu/arm11mpcore.c
index 5f80e7b..5dcc73a 100644
--- a/hw/cpu/arm11mpcore.c
+++ b/hw/cpu/arm11mpcore.c
@@ -8,6 +8,7 @@
  */
 
 #include "hw/sysbus.h"
+#include "hw/misc/arm11scu.h"
 #include "qemu/timer.h"
 
 /* MPCore private memory region.  */
@@ -19,64 +20,18 @@
 typedef struct ARM11MPCorePriveState {
     SysBusDevice parent_obj;
 
-    uint32_t scu_control;
     uint32_t num_cpu;
-    MemoryRegion iomem;
     MemoryRegion container;
     DeviceState *mptimer;
     DeviceState *wdtimer;
     DeviceState *gic;
     uint32_t num_irq;
+
+    ARM11SCUState scu;
 } ARM11MPCorePriveState;
 
 /* Per-CPU private memory mapped IO.  */
 
-static uint64_t mpcore_scu_read(void *opaque, hwaddr offset,
-                                unsigned size)
-{
-    ARM11MPCorePriveState *s = (ARM11MPCorePriveState *)opaque;
-    int id;
-    /* SCU */
-    switch (offset) {
-    case 0x00: /* Control.  */
-        return s->scu_control;
-    case 0x04: /* Configuration.  */
-        id = ((1 << s->num_cpu) - 1) << 4;
-        return id | (s->num_cpu - 1);
-    case 0x08: /* CPU status.  */
-        return 0;
-    case 0x0c: /* Invalidate all.  */
-        return 0;
-    default:
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "mpcore_priv_read: Bad offset %x\n", (int)offset);
-        return 0;
-    }
-}
-
-static void mpcore_scu_write(void *opaque, hwaddr offset,
-                             uint64_t value, unsigned size)
-{
-    ARM11MPCorePriveState *s = (ARM11MPCorePriveState *)opaque;
-    /* SCU */
-    switch (offset) {
-    case 0: /* Control register.  */
-        s->scu_control = value & 1;
-        break;
-    case 0x0c: /* Invalidate all.  */
-        /* This is a no-op as cache is not emulated.  */
-        break;
-    default:
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "mpcore_priv_read: Bad offset %x\n", (int)offset);
-    }
-}
-
-static const MemoryRegionOps mpcore_scu_ops = {
-    .read = mpcore_scu_read,
-    .write = mpcore_scu_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-};
 
 static void mpcore_priv_set_irq(void *opaque, int irq, int level)
 {
@@ -87,12 +42,13 @@ static void mpcore_priv_set_irq(void *opaque, int irq, int level)
 static void mpcore_priv_map_setup(ARM11MPCorePriveState *s)
 {
     int i;
+    SysBusDevice *scubusdev = SYS_BUS_DEVICE(&s->scu);
     SysBusDevice *gicbusdev = SYS_BUS_DEVICE(s->gic);
     SysBusDevice *timerbusdev = SYS_BUS_DEVICE(s->mptimer);
     SysBusDevice *wdtbusdev = SYS_BUS_DEVICE(s->wdtimer);
-    memory_region_init_io(&s->iomem, OBJECT(s),
-                          &mpcore_scu_ops, s, "mpcore-scu", 0x100);
-    memory_region_add_subregion(&s->container, 0, &s->iomem);
+
+    memory_region_add_subregion(&s->container, 0,
+                                sysbus_mmio_get_region(scubusdev, 0));
     /* GIC CPU interfaces: "current CPU" at 0x100, then specific CPUs
      * at 0x200, 0x300...
      */
@@ -130,6 +86,10 @@ static int mpcore_priv_init(SysBusDevice *sbd)
 {
     DeviceState *dev = DEVICE(sbd);
     ARM11MPCorePriveState *s = ARM11MPCORE_PRIV(dev);
+    DeviceState *scudev = DEVICE(&s->scu);
+
+    qdev_prop_set_uint32(scudev, "num-cpu", s->num_cpu);
+    qdev_init_nofail(scudev);
 
     s->gic = qdev_create(NULL, "arm_gic");
     qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
@@ -164,6 +124,9 @@ static void mpcore_priv_initfn(Object *obj)
     memory_region_init(&s->container, OBJECT(s),
                        "mpcore-priv-container", 0x2000);
     sysbus_init_mmio(sbd, &s->container);
+
+    object_initialize(&s->scu, sizeof(s->scu), TYPE_ARM11_SCU);
+    qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
 }
 
 #define TYPE_REALVIEW_MPCORE_RIRQ "realview_mpcore"
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 0a36c97..9fbcebd 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -12,6 +12,7 @@ obj-$(CONFIG_VMPORT) += vmport.o
 common-obj-$(CONFIG_PL310) += arm_l2x0.o
 common-obj-$(CONFIG_INTEGRATOR_DEBUG) += arm_integrator_debug.o
 common-obj-$(CONFIG_A9SCU) += a9scu.o
+common-obj-$(CONFIG_ARM11SCU) += arm11scu.o
 
 # PKUnity SoC devices
 common-obj-$(CONFIG_PUV3) += puv3_pm.o
diff --git a/hw/misc/arm11scu.c b/hw/misc/arm11scu.c
new file mode 100644
index 0000000..a791675
--- /dev/null
+++ b/hw/misc/arm11scu.c
@@ -0,0 +1,100 @@
+/*
+ * ARM11MPCore Snoop Control Unit (SCU) emulation
+ *
+ * Copyright (c) 2006-2007 CodeSourcery.
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ * Written by Paul Brook and Andreas Färber
+ *
+ * This code is licensed under the GPL.
+ */
+
+#include "hw/misc/arm11scu.h"
+
+static uint64_t mpcore_scu_read(void *opaque, hwaddr offset,
+                                unsigned size)
+{
+    ARM11SCUState *s = (ARM11SCUState *)opaque;
+    int id;
+    /* SCU */
+    switch (offset) {
+    case 0x00: /* Control.  */
+        return s->control;
+    case 0x04: /* Configuration.  */
+        id = ((1 << s->num_cpu) - 1) << 4;
+        return id | (s->num_cpu - 1);
+    case 0x08: /* CPU status.  */
+        return 0;
+    case 0x0c: /* Invalidate all.  */
+        return 0;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "mpcore_priv_read: Bad offset %x\n", (int)offset);
+        return 0;
+    }
+}
+
+static void mpcore_scu_write(void *opaque, hwaddr offset,
+                             uint64_t value, unsigned size)
+{
+    ARM11SCUState *s = (ARM11SCUState *)opaque;
+    /* SCU */
+    switch (offset) {
+    case 0: /* Control register.  */
+        s->control = value & 1;
+        break;
+    case 0x0c: /* Invalidate all.  */
+        /* This is a no-op as cache is not emulated.  */
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "mpcore_priv_read: Bad offset %x\n", (int)offset);
+    }
+}
+
+static const MemoryRegionOps mpcore_scu_ops = {
+    .read = mpcore_scu_read,
+    .write = mpcore_scu_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void arm11_scu_realize(DeviceState *dev, Error **errp)
+{
+}
+
+static void arm11_scu_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    ARM11SCUState *s = ARM11_SCU(obj);
+
+    memory_region_init_io(&s->iomem, OBJECT(s),
+                          &mpcore_scu_ops, s, "mpcore-scu", 0x100);
+    sysbus_init_mmio(sbd, &s->iomem);
+}
+
+static Property arm11_scu_properties[] = {
+    DEFINE_PROP_UINT32("num-cpu", ARM11SCUState, num_cpu, 1),
+    DEFINE_PROP_END_OF_LIST()
+};
+
+static void arm11_scu_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = arm11_scu_realize;
+    dc->props = arm11_scu_properties;
+}
+
+static const TypeInfo arm11_scu_type_info = {
+    .name          = TYPE_ARM11_SCU,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(ARM11SCUState),
+    .instance_init = arm11_scu_init,
+    .class_init    = arm11_scu_class_init,
+};
+
+static void arm11_scu_register_types(void)
+{
+    type_register_static(&arm11_scu_type_info);
+}
+
+type_init(arm11_scu_register_types)
diff --git a/include/hw/misc/arm11scu.h b/include/hw/misc/arm11scu.h
new file mode 100644
index 0000000..5ad0f3d
--- /dev/null
+++ b/include/hw/misc/arm11scu.h
@@ -0,0 +1,29 @@
+/*
+ * ARM11MPCore Snoop Control Unit (SCU) emulation
+ *
+ * Copyright (c) 2006-2007 CodeSourcery.
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ * Written by Paul Brook and Andreas Färber
+ *
+ * This code is licensed under the GPL.
+ */
+
+#ifndef HW_MISC_ARM11SCU_H
+#define HW_MISC_ARM11SCU_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_ARM11_SCU "arm11-scu"
+#define ARM11_SCU(obj) OBJECT_CHECK(ARM11SCUState, (obj), TYPE_ARM11_SCU)
+
+typedef struct ARM11SCUState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    uint32_t control;
+    uint32_t num_cpu;
+    MemoryRegion iomem;
+} ARM11SCUState;
+
+#endif
commit 2c42c3a063c2a8dda74b613bfab021b86ebc7ee5
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Aug 18 20:48:33 2013 +0200

    arm11mpcore: Create container MemoryRegion in instance_init
    
    This allows to map the region directly after object initialization.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/cpu/arm11mpcore.c b/hw/cpu/arm11mpcore.c
index 8719634..5f80e7b 100644
--- a/hw/cpu/arm11mpcore.c
+++ b/hw/cpu/arm11mpcore.c
@@ -90,8 +90,6 @@ static void mpcore_priv_map_setup(ARM11MPCorePriveState *s)
     SysBusDevice *gicbusdev = SYS_BUS_DEVICE(s->gic);
     SysBusDevice *timerbusdev = SYS_BUS_DEVICE(s->mptimer);
     SysBusDevice *wdtbusdev = SYS_BUS_DEVICE(s->wdtimer);
-    memory_region_init(&s->container, OBJECT(s),
-                       "mpcore-priv-container", 0x2000);
     memory_region_init_io(&s->iomem, OBJECT(s),
                           &mpcore_scu_ops, s, "mpcore-scu", 0x100);
     memory_region_add_subregion(&s->container, 0, &s->iomem);
@@ -155,10 +153,19 @@ static int mpcore_priv_init(SysBusDevice *sbd)
     qdev_init_nofail(s->wdtimer);
 
     mpcore_priv_map_setup(s);
-    sysbus_init_mmio(sbd, &s->container);
     return 0;
 }
 
+static void mpcore_priv_initfn(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    ARM11MPCorePriveState *s = ARM11MPCORE_PRIV(obj);
+
+    memory_region_init(&s->container, OBJECT(s),
+                       "mpcore-priv-container", 0x2000);
+    sysbus_init_mmio(sbd, &s->container);
+}
+
 #define TYPE_REALVIEW_MPCORE_RIRQ "realview_mpcore"
 #define REALVIEW_MPCORE_RIRQ(obj) \
     OBJECT_CHECK(mpcore_rirq_state, (obj), TYPE_REALVIEW_MPCORE_RIRQ)
@@ -277,6 +284,7 @@ static const TypeInfo mpcore_priv_info = {
     .name          = TYPE_ARM11MPCORE_PRIV,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(ARM11MPCorePriveState),
+    .instance_init = mpcore_priv_initfn,
     .class_init    = mpcore_priv_class_init,
 };
 
commit 21ebaf1d812471e3379c85ffb8b0cc2311d5bff0
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Aug 18 22:08:59 2013 +0200

    arm11mpcore: Drop unused fields
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/cpu/arm11mpcore.c b/hw/cpu/arm11mpcore.c
index 27cd32b..8719634 100644
--- a/hw/cpu/arm11mpcore.c
+++ b/hw/cpu/arm11mpcore.c
@@ -20,8 +20,6 @@ typedef struct ARM11MPCorePriveState {
     SysBusDevice parent_obj;
 
     uint32_t scu_control;
-    int iomemtype;
-    uint32_t old_timer_status[8];
     uint32_t num_cpu;
     MemoryRegion iomem;
     MemoryRegion container;
commit 4c14253c9e889ab1cbd6126eed883682c1cd2718
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Aug 18 20:36:33 2013 +0200

    arm11mpcore: Fix typo in MemoryRegion name
    
    "mpcode" -> "mpcore"
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/cpu/arm11mpcore.c b/hw/cpu/arm11mpcore.c
index a786c62..27cd32b 100644
--- a/hw/cpu/arm11mpcore.c
+++ b/hw/cpu/arm11mpcore.c
@@ -93,7 +93,7 @@ static void mpcore_priv_map_setup(ARM11MPCorePriveState *s)
     SysBusDevice *timerbusdev = SYS_BUS_DEVICE(s->mptimer);
     SysBusDevice *wdtbusdev = SYS_BUS_DEVICE(s->wdtimer);
     memory_region_init(&s->container, OBJECT(s),
-                       "mpcode-priv-container", 0x2000);
+                       "mpcore-priv-container", 0x2000);
     memory_region_init_io(&s->iomem, OBJECT(s),
                           &mpcore_scu_ops, s, "mpcore-scu", 0x100);
     memory_region_add_subregion(&s->container, 0, &s->iomem);
commit b4a37f17fef343f6400f0ccc1d1e037c6c430807
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Aug 18 21:00:29 2013 +0200

    a9scu: Build only once
    
    It does not have a target or ARMCPU dependency.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index cca5c05..0a36c97 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -11,6 +11,7 @@ obj-$(CONFIG_VMPORT) += vmport.o
 # ARM devices
 common-obj-$(CONFIG_PL310) += arm_l2x0.o
 common-obj-$(CONFIG_INTEGRATOR_DEBUG) += arm_integrator_debug.o
+common-obj-$(CONFIG_A9SCU) += a9scu.o
 
 # PKUnity SoC devices
 common-obj-$(CONFIG_PUV3) += puv3_pm.o
@@ -23,7 +24,6 @@ obj-$(CONFIG_LINUX) += vfio.o
 endif
 
 obj-$(CONFIG_REALVIEW) += arm_sysctl.o
-obj-$(CONFIG_A9SCU) += a9scu.o
 obj-$(CONFIG_NSERIES) += cbus.o
 obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o
commit 43482f72dbe48448442c3b27f0a26b16d49e8f97
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Sun Jun 30 21:31:01 2013 +0200

    a15mpcore: Prepare for QOM embedding
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/hw/cpu/a15mpcore.c b/hw/cpu/a15mpcore.c
index 10dc35a..acc419e 100644
--- a/hw/cpu/a15mpcore.c
+++ b/hw/cpu/a15mpcore.c
@@ -18,27 +18,8 @@
  * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "hw/sysbus.h"
+#include "hw/cpu/a15mpcore.h"
 #include "sysemu/kvm.h"
-#include "hw/intc/arm_gic.h"
-
-/* A15MP private memory region.  */
-
-#define TYPE_A15MPCORE_PRIV "a15mpcore_priv"
-#define A15MPCORE_PRIV(obj) \
-    OBJECT_CHECK(A15MPPrivState, (obj), TYPE_A15MPCORE_PRIV)
-
-typedef struct A15MPPrivState {
-    /*< private >*/
-    SysBusDevice parent_obj;
-    /*< public >*/
-
-    uint32_t num_cpu;
-    uint32_t num_irq;
-    MemoryRegion container;
-
-    GICState gic;
-} A15MPPrivState;
 
 static void a15mp_priv_set_irq(void *opaque, int irq, int level)
 {
diff --git a/include/hw/cpu/a15mpcore.h b/include/hw/cpu/a15mpcore.h
new file mode 100644
index 0000000..b423533
--- /dev/null
+++ b/include/hw/cpu/a15mpcore.h
@@ -0,0 +1,44 @@
+/*
+ * Cortex-A15MPCore internal peripheral emulation.
+ *
+ * Copyright (c) 2012 Linaro Limited.
+ * Written by Peter Maydell.
+ *
+ * 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/>.
+ */
+#ifndef HW_CPU_A15MPCORE_H
+#define HW_CPU_A15MPCORE_H
+
+#include "hw/sysbus.h"
+#include "hw/intc/arm_gic.h"
+
+/* A15MP private memory region.  */
+
+#define TYPE_A15MPCORE_PRIV "a15mpcore_priv"
+#define A15MPCORE_PRIV(obj) \
+    OBJECT_CHECK(A15MPPrivState, (obj), TYPE_A15MPCORE_PRIV)
+
+typedef struct A15MPPrivState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    uint32_t num_cpu;
+    uint32_t num_irq;
+    MemoryRegion container;
+
+    GICState gic;
+} A15MPPrivState;
+
+#endif
commit 7c76a48db48accca337e1e99b9085646b696a895
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Sun Jun 30 21:22:54 2013 +0200

    a15mpcore: Convert to QOM realize
    
    Turn SysBusDevice initfn into a QOM realizefn.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/hw/cpu/a15mpcore.c b/hw/cpu/a15mpcore.c
index b2614e7..10dc35a 100644
--- a/hw/cpu/a15mpcore.c
+++ b/hw/cpu/a15mpcore.c
@@ -67,24 +67,30 @@ static void a15mp_priv_initfn(Object *obj)
     qdev_prop_set_uint32(gicdev, "revision", 2);
 }
 
-static int a15mp_priv_init(SysBusDevice *dev)
+static void a15mp_priv_realize(DeviceState *dev, Error **errp)
 {
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
     A15MPPrivState *s = A15MPCORE_PRIV(dev);
     DeviceState *gicdev;
     SysBusDevice *busdev;
     int i;
+    Error *err = NULL;
 
     gicdev = DEVICE(&s->gic);
     qdev_prop_set_uint32(gicdev, "num-cpu", s->num_cpu);
     qdev_prop_set_uint32(gicdev, "num-irq", s->num_irq);
-    qdev_init_nofail(gicdev);
+    object_property_set_bool(OBJECT(&s->gic), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
     busdev = SYS_BUS_DEVICE(&s->gic);
 
     /* Pass through outbound IRQ lines from the GIC */
-    sysbus_pass_irq(dev, busdev);
+    sysbus_pass_irq(sbd, busdev);
 
     /* Pass through inbound GPIO lines to the GIC */
-    qdev_init_gpio_in(DEVICE(dev), a15mp_priv_set_irq, s->num_irq - 32);
+    qdev_init_gpio_in(dev, a15mp_priv_set_irq, s->num_irq - 32);
 
     /* Wire the outputs from each CPU's generic timer to the
      * appropriate GIC PPI inputs
@@ -114,8 +120,6 @@ static int a15mp_priv_init(SysBusDevice *dev)
                                 sysbus_mmio_get_region(busdev, 0));
     memory_region_add_subregion(&s->container, 0x2000,
                                 sysbus_mmio_get_region(busdev, 1));
-
-    return 0;
 }
 
 static Property a15mp_priv_properties[] = {
@@ -133,8 +137,8 @@ static Property a15mp_priv_properties[] = {
 static void a15mp_priv_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-    k->init = a15mp_priv_init;
+
+    dc->realize = a15mp_priv_realize;
     dc->props = a15mp_priv_properties;
     /* We currently have no savable state */
 }
commit 524a2d8e2628b3241f0dcaa6a96d57e8120cc439
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Sun Jun 30 21:20:26 2013 +0200

    a15mpcore: Embed GICState
    
    This covers both emulated and KVM GIC.
    
    Prepares for QOM realize.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/hw/cpu/a15mpcore.c b/hw/cpu/a15mpcore.c
index af29c35..b2614e7 100644
--- a/hw/cpu/a15mpcore.c
+++ b/hw/cpu/a15mpcore.c
@@ -20,6 +20,7 @@
 
 #include "hw/sysbus.h"
 #include "sysemu/kvm.h"
+#include "hw/intc/arm_gic.h"
 
 /* A15MP private memory region.  */
 
@@ -35,41 +36,49 @@ typedef struct A15MPPrivState {
     uint32_t num_cpu;
     uint32_t num_irq;
     MemoryRegion container;
-    DeviceState *gic;
+
+    GICState gic;
 } A15MPPrivState;
 
 static void a15mp_priv_set_irq(void *opaque, int irq, int level)
 {
     A15MPPrivState *s = (A15MPPrivState *)opaque;
-    qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
+
+    qemu_set_irq(qdev_get_gpio_in(DEVICE(&s->gic), irq), level);
 }
 
 static void a15mp_priv_initfn(Object *obj)
 {
     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
     A15MPPrivState *s = A15MPCORE_PRIV(obj);
+    DeviceState *gicdev;
+    const char *gictype = "arm_gic";
+
+    if (kvm_irqchip_in_kernel()) {
+        gictype = "kvm-arm-gic";
+    }
 
     memory_region_init(&s->container, obj, "a15mp-priv-container", 0x8000);
     sysbus_init_mmio(sbd, &s->container);
+
+    object_initialize(&s->gic, sizeof(s->gic), gictype);
+    gicdev = DEVICE(&s->gic);
+    qdev_set_parent_bus(gicdev, sysbus_get_default());
+    qdev_prop_set_uint32(gicdev, "revision", 2);
 }
 
 static int a15mp_priv_init(SysBusDevice *dev)
 {
     A15MPPrivState *s = A15MPCORE_PRIV(dev);
+    DeviceState *gicdev;
     SysBusDevice *busdev;
-    const char *gictype = "arm_gic";
     int i;
 
-    if (kvm_irqchip_in_kernel()) {
-        gictype = "kvm-arm-gic";
-    }
-
-    s->gic = qdev_create(NULL, gictype);
-    qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
-    qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
-    qdev_prop_set_uint32(s->gic, "revision", 2);
-    qdev_init_nofail(s->gic);
-    busdev = SYS_BUS_DEVICE(s->gic);
+    gicdev = DEVICE(&s->gic);
+    qdev_prop_set_uint32(gicdev, "num-cpu", s->num_cpu);
+    qdev_prop_set_uint32(gicdev, "num-irq", s->num_irq);
+    qdev_init_nofail(gicdev);
+    busdev = SYS_BUS_DEVICE(&s->gic);
 
     /* Pass through outbound IRQ lines from the GIC */
     sysbus_pass_irq(dev, busdev);
@@ -87,10 +96,10 @@ static int a15mp_priv_init(SysBusDevice *dev)
          * since a real A15 always has TrustZone but QEMU doesn't.
          */
         qdev_connect_gpio_out(cpudev, 0,
-                              qdev_get_gpio_in(s->gic, ppibase + 30));
+                              qdev_get_gpio_in(gicdev, ppibase + 30));
         /* virtual timer */
         qdev_connect_gpio_out(cpudev, 1,
-                              qdev_get_gpio_in(s->gic, ppibase + 27));
+                              qdev_get_gpio_in(gicdev, ppibase + 27));
     }
 
     /* Memory map (addresses are offsets from PERIPHBASE):
commit b9ed148d243839aba3864b4419114396f6fda2fc
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Sun Jun 30 21:07:31 2013 +0200

    a15mpcore: Split off instance_init
    
    Prepares for QOM realize.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/hw/cpu/a15mpcore.c b/hw/cpu/a15mpcore.c
index 9abba67..af29c35 100644
--- a/hw/cpu/a15mpcore.c
+++ b/hw/cpu/a15mpcore.c
@@ -44,6 +44,15 @@ static void a15mp_priv_set_irq(void *opaque, int irq, int level)
     qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
 }
 
+static void a15mp_priv_initfn(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    A15MPPrivState *s = A15MPCORE_PRIV(obj);
+
+    memory_region_init(&s->container, obj, "a15mp-priv-container", 0x8000);
+    sysbus_init_mmio(sbd, &s->container);
+}
+
 static int a15mp_priv_init(SysBusDevice *dev)
 {
     A15MPPrivState *s = A15MPCORE_PRIV(dev);
@@ -92,14 +101,11 @@ static int a15mp_priv_init(SysBusDevice *dev)
      *  0x5000-0x5fff -- GIC virtual interface control (not modelled)
      *  0x6000-0x7fff -- GIC virtual CPU interface (not modelled)
      */
-    memory_region_init(&s->container, OBJECT(s),
-                       "a15mp-priv-container", 0x8000);
     memory_region_add_subregion(&s->container, 0x1000,
                                 sysbus_mmio_get_region(busdev, 0));
     memory_region_add_subregion(&s->container, 0x2000,
                                 sysbus_mmio_get_region(busdev, 1));
 
-    sysbus_init_mmio(dev, &s->container);
     return 0;
 }
 
@@ -128,6 +134,7 @@ static const TypeInfo a15mp_priv_info = {
     .name  = TYPE_A15MPCORE_PRIV,
     .parent = TYPE_SYS_BUS_DEVICE,
     .instance_size  = sizeof(A15MPPrivState),
+    .instance_init = a15mp_priv_initfn,
     .class_init = a15mp_priv_class_init,
 };
 
commit de4c2dcf7fedf5fa727113e1dec0d0e5dd0462a0
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Sun Jun 30 20:44:23 2013 +0200

    a9mpcore: Prepare for QOM embedding
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
index a162ff0..918a7d1 100644
--- a/hw/cpu/a9mpcore.c
+++ b/hw/cpu/a9mpcore.c
@@ -8,29 +8,7 @@
  * This code is licensed under the GPL.
  */
 
-#include "hw/sysbus.h"
-#include "hw/intc/arm_gic.h"
-#include "hw/misc/a9scu.h"
-#include "hw/timer/arm_mptimer.h"
-
-#define TYPE_A9MPCORE_PRIV "a9mpcore_priv"
-#define A9MPCORE_PRIV(obj) \
-    OBJECT_CHECK(A9MPPrivState, (obj), TYPE_A9MPCORE_PRIV)
-
-typedef struct A9MPPrivState {
-    /*< private >*/
-    SysBusDevice parent_obj;
-    /*< public >*/
-
-    uint32_t num_cpu;
-    MemoryRegion container;
-    uint32_t num_irq;
-
-    GICState gic;
-    A9SCUState scu;
-    ARMMPTimerState mptimer;
-    ARMMPTimerState wdt;
-} A9MPPrivState;
+#include "hw/cpu/a9mpcore.h"
 
 static void a9mp_priv_set_irq(void *opaque, int irq, int level)
 {
diff --git a/include/hw/cpu/a9mpcore.h b/include/hw/cpu/a9mpcore.h
new file mode 100644
index 0000000..010489b
--- /dev/null
+++ b/include/hw/cpu/a9mpcore.h
@@ -0,0 +1,37 @@
+/*
+ * Cortex-A9MPCore internal peripheral emulation.
+ *
+ * Copyright (c) 2009 CodeSourcery.
+ * Copyright (c) 2011 Linaro Limited.
+ * Written by Paul Brook, Peter Maydell.
+ *
+ * This code is licensed under the GPL.
+ */
+#ifndef HW_CPU_A9MPCORE_H
+#define HW_CPU_A9MPCORE_H
+
+#include "hw/sysbus.h"
+#include "hw/intc/arm_gic.h"
+#include "hw/misc/a9scu.h"
+#include "hw/timer/arm_mptimer.h"
+
+#define TYPE_A9MPCORE_PRIV "a9mpcore_priv"
+#define A9MPCORE_PRIV(obj) \
+    OBJECT_CHECK(A9MPPrivState, (obj), TYPE_A9MPCORE_PRIV)
+
+typedef struct A9MPPrivState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    uint32_t num_cpu;
+    MemoryRegion container;
+    uint32_t num_irq;
+
+    GICState gic;
+    A9SCUState scu;
+    ARMMPTimerState mptimer;
+    ARMMPTimerState wdt;
+} A9MPPrivState;
+
+#endif
commit 837cf1013e6e1aa821ce13d7f63bb3dc0a92a1ab
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Sun Jun 30 20:36:15 2013 +0200

    a9mpcore: Convert to QOM realize
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
index db3907e..a162ff0 100644
--- a/hw/cpu/a9mpcore.c
+++ b/hw/cpu/a9mpcore.c
@@ -59,38 +59,56 @@ static void a9mp_priv_initfn(Object *obj)
     qdev_set_parent_bus(DEVICE(&s->wdt), sysbus_get_default());
 }
 
-static int a9mp_priv_init(SysBusDevice *dev)
+static void a9mp_priv_realize(DeviceState *dev, Error **errp)
 {
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
     A9MPPrivState *s = A9MPCORE_PRIV(dev);
     DeviceState *gicdev, *scudev, *mptimerdev, *wdtdev;
     SysBusDevice *timerbusdev, *wdtbusdev, *gicbusdev, *scubusdev;
+    Error *err = NULL;
     int i;
 
     gicdev = DEVICE(&s->gic);
     qdev_prop_set_uint32(gicdev, "num-cpu", s->num_cpu);
     qdev_prop_set_uint32(gicdev, "num-irq", s->num_irq);
-    qdev_init_nofail(gicdev);
+    object_property_set_bool(OBJECT(&s->gic), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
     gicbusdev = SYS_BUS_DEVICE(&s->gic);
 
     /* Pass through outbound IRQ lines from the GIC */
-    sysbus_pass_irq(dev, gicbusdev);
+    sysbus_pass_irq(sbd, gicbusdev);
 
     /* Pass through inbound GPIO lines to the GIC */
-    qdev_init_gpio_in(DEVICE(dev), a9mp_priv_set_irq, s->num_irq - 32);
+    qdev_init_gpio_in(dev, a9mp_priv_set_irq, s->num_irq - 32);
 
     scudev = DEVICE(&s->scu);
     qdev_prop_set_uint32(scudev, "num-cpu", s->num_cpu);
-    qdev_init_nofail(scudev);
+    object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
     scubusdev = SYS_BUS_DEVICE(&s->scu);
 
     mptimerdev = DEVICE(&s->mptimer);
     qdev_prop_set_uint32(mptimerdev, "num-cpu", s->num_cpu);
-    qdev_init_nofail(mptimerdev);
+    object_property_set_bool(OBJECT(&s->mptimer), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
     timerbusdev = SYS_BUS_DEVICE(&s->mptimer);
 
     wdtdev = DEVICE(&s->wdt);
     qdev_prop_set_uint32(wdtdev, "num-cpu", s->num_cpu);
-    qdev_init_nofail(wdtdev);
+    object_property_set_bool(OBJECT(&s->wdt), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
     wdtbusdev = SYS_BUS_DEVICE(&s->wdt);
 
     /* Memory map (addresses are offsets from PERIPHBASE):
@@ -129,7 +147,6 @@ static int a9mp_priv_init(SysBusDevice *dev)
         sysbus_connect_irq(wdtbusdev, i,
                            qdev_get_gpio_in(gicdev, ppibase + 30));
     }
-    return 0;
 }
 
 static Property a9mp_priv_properties[] = {
@@ -147,9 +164,8 @@ static Property a9mp_priv_properties[] = {
 static void a9mp_priv_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    k->init = a9mp_priv_init;
+    dc->realize = a9mp_priv_realize;
     dc->props = a9mp_priv_properties;
 }
 
commit eb110bd843d3ef70850a7cf44d05056b8a3e81aa
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Sun Jun 30 20:30:27 2013 +0200

    a9mpcore: Embed ARMMPTimerState
    
    Prepares for QOM realize.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
index df92e3f..db3907e 100644
--- a/hw/cpu/a9mpcore.c
+++ b/hw/cpu/a9mpcore.c
@@ -11,6 +11,7 @@
 #include "hw/sysbus.h"
 #include "hw/intc/arm_gic.h"
 #include "hw/misc/a9scu.h"
+#include "hw/timer/arm_mptimer.h"
 
 #define TYPE_A9MPCORE_PRIV "a9mpcore_priv"
 #define A9MPCORE_PRIV(obj) \
@@ -23,12 +24,12 @@ typedef struct A9MPPrivState {
 
     uint32_t num_cpu;
     MemoryRegion container;
-    DeviceState *mptimer;
-    DeviceState *wdt;
     uint32_t num_irq;
 
     GICState gic;
     A9SCUState scu;
+    ARMMPTimerState mptimer;
+    ARMMPTimerState wdt;
 } A9MPPrivState;
 
 static void a9mp_priv_set_irq(void *opaque, int irq, int level)
@@ -50,12 +51,18 @@ static void a9mp_priv_initfn(Object *obj)
 
     object_initialize(&s->scu, sizeof(s->scu), TYPE_A9_SCU);
     qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
+
+    object_initialize(&s->mptimer, sizeof(s->mptimer), TYPE_ARM_MPTIMER);
+    qdev_set_parent_bus(DEVICE(&s->mptimer), sysbus_get_default());
+
+    object_initialize(&s->wdt, sizeof(s->wdt), TYPE_ARM_MPTIMER);
+    qdev_set_parent_bus(DEVICE(&s->wdt), sysbus_get_default());
 }
 
 static int a9mp_priv_init(SysBusDevice *dev)
 {
     A9MPPrivState *s = A9MPCORE_PRIV(dev);
-    DeviceState *gicdev, *scudev;
+    DeviceState *gicdev, *scudev, *mptimerdev, *wdtdev;
     SysBusDevice *timerbusdev, *wdtbusdev, *gicbusdev, *scubusdev;
     int i;
 
@@ -76,15 +83,15 @@ static int a9mp_priv_init(SysBusDevice *dev)
     qdev_init_nofail(scudev);
     scubusdev = SYS_BUS_DEVICE(&s->scu);
 
-    s->mptimer = qdev_create(NULL, "arm_mptimer");
-    qdev_prop_set_uint32(s->mptimer, "num-cpu", s->num_cpu);
-    qdev_init_nofail(s->mptimer);
-    timerbusdev = SYS_BUS_DEVICE(s->mptimer);
+    mptimerdev = DEVICE(&s->mptimer);
+    qdev_prop_set_uint32(mptimerdev, "num-cpu", s->num_cpu);
+    qdev_init_nofail(mptimerdev);
+    timerbusdev = SYS_BUS_DEVICE(&s->mptimer);
 
-    s->wdt = qdev_create(NULL, "arm_mptimer");
-    qdev_prop_set_uint32(s->wdt, "num-cpu", s->num_cpu);
-    qdev_init_nofail(s->wdt);
-    wdtbusdev = SYS_BUS_DEVICE(s->wdt);
+    wdtdev = DEVICE(&s->wdt);
+    qdev_prop_set_uint32(wdtdev, "num-cpu", s->num_cpu);
+    qdev_init_nofail(wdtdev);
+    wdtbusdev = SYS_BUS_DEVICE(&s->wdt);
 
     /* Memory map (addresses are offsets from PERIPHBASE):
      *  0x0000-0x00ff -- Snoop Control Unit
diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c
index 2853db4..d9f9494 100644
--- a/hw/timer/arm_mptimer.c
+++ b/hw/timer/arm_mptimer.c
@@ -19,7 +19,7 @@
  * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "hw/sysbus.h"
+#include "hw/timer/arm_mptimer.h"
 #include "qemu/timer.h"
 #include "qom/cpu.h"
 
@@ -27,34 +27,6 @@
  * which is used in both the ARM11MPCore and Cortex-A9MP.
  */
 
-#define MAX_CPUS 4
-
-/* State of a single timer or watchdog block */
-typedef struct {
-    uint32_t count;
-    uint32_t load;
-    uint32_t control;
-    uint32_t status;
-    int64_t tick;
-    QEMUTimer *timer;
-    qemu_irq irq;
-    MemoryRegion iomem;
-} TimerBlock;
-
-#define TYPE_ARM_MPTIMER "arm_mptimer"
-#define ARM_MPTIMER(obj) \
-    OBJECT_CHECK(ARMMPTimerState, (obj), TYPE_ARM_MPTIMER)
-
-typedef struct {
-    /*< private >*/
-    SysBusDevice parent_obj;
-    /*< public >*/
-
-    uint32_t num_cpu;
-    TimerBlock timerblock[MAX_CPUS];
-    MemoryRegion iomem;
-} ARMMPTimerState;
-
 static inline int get_current_cpu(ARMMPTimerState *s)
 {
     if (current_cpu->cpu_index >= s->num_cpu) {
@@ -240,8 +212,9 @@ static void arm_mptimer_realize(DeviceState *dev, Error **errp)
     ARMMPTimerState *s = ARM_MPTIMER(dev);
     int i;
 
-    if (s->num_cpu < 1 || s->num_cpu > MAX_CPUS) {
-        hw_error("%s: num-cpu must be between 1 and %d\n", __func__, MAX_CPUS);
+    if (s->num_cpu < 1 || s->num_cpu > ARM_MPTIMER_MAX_CPUS) {
+        hw_error("%s: num-cpu must be between 1 and %d\n",
+                 __func__, ARM_MPTIMER_MAX_CPUS);
     }
     /* We implement one timer block per CPU, and expose multiple MMIO regions:
      *  * region 0 is "timer for this core"
diff --git a/include/hw/timer/arm_mptimer.h b/include/hw/timer/arm_mptimer.h
new file mode 100644
index 0000000..b34cba0
--- /dev/null
+++ b/include/hw/timer/arm_mptimer.h
@@ -0,0 +1,54 @@
+/*
+ * Private peripheral timer/watchdog blocks for ARM 11MPCore and A9MP
+ *
+ * Copyright (c) 2006-2007 CodeSourcery.
+ * Copyright (c) 2011 Linaro Limited
+ * Written by Paul Brook, Peter Maydell
+ *
+ * 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/>.
+ */
+#ifndef HW_TIMER_ARM_MPTIMER_H
+#define HW_TIMER_ARM_MPTIMER_H
+
+#include "hw/sysbus.h"
+
+#define ARM_MPTIMER_MAX_CPUS 4
+
+/* State of a single timer or watchdog block */
+typedef struct {
+    uint32_t count;
+    uint32_t load;
+    uint32_t control;
+    uint32_t status;
+    int64_t tick;
+    QEMUTimer *timer;
+    qemu_irq irq;
+    MemoryRegion iomem;
+} TimerBlock;
+
+#define TYPE_ARM_MPTIMER "arm_mptimer"
+#define ARM_MPTIMER(obj) \
+    OBJECT_CHECK(ARMMPTimerState, (obj), TYPE_ARM_MPTIMER)
+
+typedef struct {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    uint32_t num_cpu;
+    TimerBlock timerblock[ARM_MPTIMER_MAX_CPUS];
+    MemoryRegion iomem;
+} ARMMPTimerState;
+
+#endif
commit 0aadb4909c330bbde8542fcafc465817530cb835
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Sun Jun 30 19:42:55 2013 +0200

    arm_mptimer: Convert to QOM realize
    
    Split the SysBusDevice initfn into instance_init and realizefn.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c
index 8020c9f..2853db4 100644
--- a/hw/timer/arm_mptimer.c
+++ b/hw/timer/arm_mptimer.c
@@ -225,8 +225,18 @@ static void arm_mptimer_reset(DeviceState *dev)
     }
 }
 
-static int arm_mptimer_init(SysBusDevice *dev)
+static void arm_mptimer_init(Object *obj)
 {
+    ARMMPTimerState *s = ARM_MPTIMER(obj);
+
+    memory_region_init_io(&s->iomem, obj, &arm_thistimer_ops, s,
+                          "arm_mptimer_timer", 0x20);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
+}
+
+static void arm_mptimer_realize(DeviceState *dev, Error **errp)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
     ARMMPTimerState *s = ARM_MPTIMER(dev);
     int i;
 
@@ -243,19 +253,14 @@ static int arm_mptimer_init(SysBusDevice *dev)
      *  * timer for core 1
      * and so on.
      */
-    memory_region_init_io(&s->iomem, OBJECT(s), &arm_thistimer_ops, s,
-                          "arm_mptimer_timer", 0x20);
-    sysbus_init_mmio(dev, &s->iomem);
     for (i = 0; i < s->num_cpu; i++) {
         TimerBlock *tb = &s->timerblock[i];
         tb->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, timerblock_tick, tb);
-        sysbus_init_irq(dev, &tb->irq);
+        sysbus_init_irq(sbd, &tb->irq);
         memory_region_init_io(&tb->iomem, OBJECT(s), &timerblock_ops, tb,
                               "arm_mptimer_timerblock", 0x20);
-        sysbus_init_mmio(dev, &tb->iomem);
+        sysbus_init_mmio(sbd, &tb->iomem);
     }
-
-    return 0;
 }
 
 static const VMStateDescription vmstate_timerblock = {
@@ -292,9 +297,8 @@ static Property arm_mptimer_properties[] = {
 static void arm_mptimer_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
 
-    sbc->init = arm_mptimer_init;
+    dc->realize = arm_mptimer_realize;
     dc->vmsd = &vmstate_arm_mptimer;
     dc->reset = arm_mptimer_reset;
     dc->no_user = 1;
@@ -305,6 +309,7 @@ static const TypeInfo arm_mptimer_info = {
     .name          = TYPE_ARM_MPTIMER,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(ARMMPTimerState),
+    .instance_init = arm_mptimer_init,
     .class_init    = arm_mptimer_class_init,
 };
 
commit fc719d77412513a07b718e1f083b64dbcac62524
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Sun Jun 30 19:29:36 2013 +0200

    a9mpcore: Embed A9SCUState
    
    Prepares for QOM realize.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
index c57b149..df92e3f 100644
--- a/hw/cpu/a9mpcore.c
+++ b/hw/cpu/a9mpcore.c
@@ -10,6 +10,7 @@
 
 #include "hw/sysbus.h"
 #include "hw/intc/arm_gic.h"
+#include "hw/misc/a9scu.h"
 
 #define TYPE_A9MPCORE_PRIV "a9mpcore_priv"
 #define A9MPCORE_PRIV(obj) \
@@ -24,10 +25,10 @@ typedef struct A9MPPrivState {
     MemoryRegion container;
     DeviceState *mptimer;
     DeviceState *wdt;
-    DeviceState *scu;
     uint32_t num_irq;
 
     GICState gic;
+    A9SCUState scu;
 } A9MPPrivState;
 
 static void a9mp_priv_set_irq(void *opaque, int irq, int level)
@@ -46,12 +47,15 @@ static void a9mp_priv_initfn(Object *obj)
 
     object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC);
     qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default());
+
+    object_initialize(&s->scu, sizeof(s->scu), TYPE_A9_SCU);
+    qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
 }
 
 static int a9mp_priv_init(SysBusDevice *dev)
 {
     A9MPPrivState *s = A9MPCORE_PRIV(dev);
-    DeviceState *gicdev;
+    DeviceState *gicdev, *scudev;
     SysBusDevice *timerbusdev, *wdtbusdev, *gicbusdev, *scubusdev;
     int i;
 
@@ -67,10 +71,10 @@ static int a9mp_priv_init(SysBusDevice *dev)
     /* Pass through inbound GPIO lines to the GIC */
     qdev_init_gpio_in(DEVICE(dev), a9mp_priv_set_irq, s->num_irq - 32);
 
-    s->scu = qdev_create(NULL, "a9-scu");
-    qdev_prop_set_uint32(s->scu, "num-cpu", s->num_cpu);
-    qdev_init_nofail(s->scu);
-    scubusdev = SYS_BUS_DEVICE(s->scu);
+    scudev = DEVICE(&s->scu);
+    qdev_prop_set_uint32(scudev, "num-cpu", s->num_cpu);
+    qdev_init_nofail(scudev);
+    scubusdev = SYS_BUS_DEVICE(&s->scu);
 
     s->mptimer = qdev_create(NULL, "arm_mptimer");
     qdev_prop_set_uint32(s->mptimer, "num-cpu", s->num_cpu);
diff --git a/hw/misc/a9scu.c b/hw/misc/a9scu.c
index 2661014..4434945 100644
--- a/hw/misc/a9scu.c
+++ b/hw/misc/a9scu.c
@@ -8,23 +8,7 @@
  * This code is licensed under the GPL.
  */
 
-#include "hw/sysbus.h"
-
-/* A9MP private memory region.  */
-
-typedef struct A9SCUState {
-    /*< private >*/
-    SysBusDevice parent_obj;
-    /*< public >*/
-
-    MemoryRegion iomem;
-    uint32_t control;
-    uint32_t status;
-    uint32_t num_cpu;
-} A9SCUState;
-
-#define TYPE_A9_SCU "a9-scu"
-#define A9_SCU(obj) OBJECT_CHECK(A9SCUState, (obj), TYPE_A9_SCU)
+#include "hw/misc/a9scu.h"
 
 static uint64_t a9_scu_read(void *opaque, hwaddr offset,
                             unsigned size)
diff --git a/include/hw/misc/a9scu.h b/include/hw/misc/a9scu.h
new file mode 100644
index 0000000..efb0c30
--- /dev/null
+++ b/include/hw/misc/a9scu.h
@@ -0,0 +1,31 @@
+/*
+ * Cortex-A9MPCore Snoop Control Unit (SCU) emulation.
+ *
+ * Copyright (c) 2009 CodeSourcery.
+ * Copyright (c) 2011 Linaro Limited.
+ * Written by Paul Brook, Peter Maydell.
+ *
+ * This code is licensed under the GPL.
+ */
+#ifndef HW_MISC_A9SCU_H
+#define HW_MISC_A9SCU_H
+
+#include "hw/sysbus.h"
+
+/* A9MP private memory region.  */
+
+typedef struct A9SCUState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    MemoryRegion iomem;
+    uint32_t control;
+    uint32_t status;
+    uint32_t num_cpu;
+} A9SCUState;
+
+#define TYPE_A9_SCU "a9-scu"
+#define A9_SCU(obj) OBJECT_CHECK(A9SCUState, (obj), TYPE_A9_SCU)
+
+#endif
commit 9eb39db520cea30620b24098b6d731f78cc819a0
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Sun Jun 30 19:22:12 2013 +0200

    a9scu: QOM cleanups
    
    Rename A9SCUState::busdev field to parent_obj and turn realizefn into an
    instance_init function to allow early MMIO mapping.
    
    Reviewed-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/hw/misc/a9scu.c b/hw/misc/a9scu.c
index 601b573..2661014 100644
--- a/hw/misc/a9scu.c
+++ b/hw/misc/a9scu.c
@@ -13,7 +13,10 @@
 /* A9MP private memory region.  */
 
 typedef struct A9SCUState {
-    SysBusDevice busdev;
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
     MemoryRegion iomem;
     uint32_t control;
     uint32_t status;
@@ -114,12 +117,12 @@ static void a9_scu_reset(DeviceState *dev)
     s->control = 0;
 }
 
-static void a9_scu_realize(DeviceState *dev, Error ** errp)
+static void a9_scu_init(Object *obj)
 {
-    A9SCUState *s = A9_SCU(dev);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    A9SCUState *s = A9_SCU(obj);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 
-    memory_region_init_io(&s->iomem, OBJECT(dev), &a9_scu_ops, s,
+    memory_region_init_io(&s->iomem, obj, &a9_scu_ops, s,
                           "a9-scu", 0x100);
     sysbus_init_mmio(sbd, &s->iomem);
 }
@@ -144,7 +147,6 @@ static void a9_scu_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
-    dc->realize = a9_scu_realize;
     dc->props = a9_scu_properties;
     dc->vmsd = &vmstate_a9_scu;
     dc->reset = a9_scu_reset;
@@ -154,6 +156,7 @@ static const TypeInfo a9_scu_info = {
     .name          = TYPE_A9_SCU,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(A9SCUState),
+    .instance_init = a9_scu_init,
     .class_init    = a9_scu_class_init,
 };
 
commit 9b5f952bb8015b079783a9197f3331085075fbc4
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Sun Jun 30 19:01:18 2013 +0200

    a9mpcore: Embed GICState
    
    Prepares for conversion to QOM realize.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
index acbdab5..c57b149 100644
--- a/hw/cpu/a9mpcore.c
+++ b/hw/cpu/a9mpcore.c
@@ -9,6 +9,7 @@
  */
 
 #include "hw/sysbus.h"
+#include "hw/intc/arm_gic.h"
 
 #define TYPE_A9MPCORE_PRIV "a9mpcore_priv"
 #define A9MPCORE_PRIV(obj) \
@@ -23,15 +24,17 @@ typedef struct A9MPPrivState {
     MemoryRegion container;
     DeviceState *mptimer;
     DeviceState *wdt;
-    DeviceState *gic;
     DeviceState *scu;
     uint32_t num_irq;
+
+    GICState gic;
 } A9MPPrivState;
 
 static void a9mp_priv_set_irq(void *opaque, int irq, int level)
 {
     A9MPPrivState *s = (A9MPPrivState *)opaque;
-    qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
+
+    qemu_set_irq(qdev_get_gpio_in(DEVICE(&s->gic), irq), level);
 }
 
 static void a9mp_priv_initfn(Object *obj)
@@ -40,19 +43,23 @@ static void a9mp_priv_initfn(Object *obj)
 
     memory_region_init(&s->container, obj, "a9mp-priv-container", 0x2000);
     sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->container);
+
+    object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC);
+    qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default());
 }
 
 static int a9mp_priv_init(SysBusDevice *dev)
 {
     A9MPPrivState *s = A9MPCORE_PRIV(dev);
+    DeviceState *gicdev;
     SysBusDevice *timerbusdev, *wdtbusdev, *gicbusdev, *scubusdev;
     int i;
 
-    s->gic = qdev_create(NULL, "arm_gic");
-    qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
-    qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
-    qdev_init_nofail(s->gic);
-    gicbusdev = SYS_BUS_DEVICE(s->gic);
+    gicdev = DEVICE(&s->gic);
+    qdev_prop_set_uint32(gicdev, "num-cpu", s->num_cpu);
+    qdev_prop_set_uint32(gicdev, "num-irq", s->num_irq);
+    qdev_init_nofail(gicdev);
+    gicbusdev = SYS_BUS_DEVICE(&s->gic);
 
     /* Pass through outbound IRQ lines from the GIC */
     sysbus_pass_irq(dev, gicbusdev);
@@ -107,9 +114,9 @@ static int a9mp_priv_init(SysBusDevice *dev)
     for (i = 0; i < s->num_cpu; i++) {
         int ppibase = (s->num_irq - 32) + i * 32;
         sysbus_connect_irq(timerbusdev, i,
-                           qdev_get_gpio_in(s->gic, ppibase + 29));
+                           qdev_get_gpio_in(gicdev, ppibase + 29));
         sysbus_connect_irq(wdtbusdev, i,
-                           qdev_get_gpio_in(s->gic, ppibase + 30));
+                           qdev_get_gpio_in(gicdev, ppibase + 30));
     }
     return 0;
 }
commit 83728796ad3f2ce7d6162c1cb894528b12915646
Author: Andreas Färber <afaerber at suse.de>
Date:   Tue Jul 23 03:37:49 2013 +0200

    arm_gic: Extract headers hw/intc/arm_gic{,_common}.h
    
    Rename NCPU to GIC_NCPU and move GICState away from gic_internal.h.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c
index 709b5c2..c765850 100644
--- a/hw/intc/arm_gic_common.c
+++ b/hw/intc/arm_gic_common.c
@@ -64,17 +64,17 @@ static const VMStateDescription vmstate_gic = {
     .post_load = gic_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_BOOL(enabled, GICState),
-        VMSTATE_BOOL_ARRAY(cpu_enabled, GICState, NCPU),
+        VMSTATE_BOOL_ARRAY(cpu_enabled, GICState, GIC_NCPU),
         VMSTATE_STRUCT_ARRAY(irq_state, GICState, GIC_MAXIRQ, 1,
                              vmstate_gic_irq_state, gic_irq_state),
         VMSTATE_UINT8_ARRAY(irq_target, GICState, GIC_MAXIRQ),
-        VMSTATE_UINT8_2DARRAY(priority1, GICState, GIC_INTERNAL, NCPU),
+        VMSTATE_UINT8_2DARRAY(priority1, GICState, GIC_INTERNAL, GIC_NCPU),
         VMSTATE_UINT8_ARRAY(priority2, GICState, GIC_MAXIRQ - GIC_INTERNAL),
-        VMSTATE_UINT16_2DARRAY(last_active, GICState, GIC_MAXIRQ, NCPU),
-        VMSTATE_UINT16_ARRAY(priority_mask, GICState, NCPU),
-        VMSTATE_UINT16_ARRAY(running_irq, GICState, NCPU),
-        VMSTATE_UINT16_ARRAY(running_priority, GICState, NCPU),
-        VMSTATE_UINT16_ARRAY(current_pending, GICState, NCPU),
+        VMSTATE_UINT16_2DARRAY(last_active, GICState, GIC_MAXIRQ, GIC_NCPU),
+        VMSTATE_UINT16_ARRAY(priority_mask, GICState, GIC_NCPU),
+        VMSTATE_UINT16_ARRAY(running_irq, GICState, GIC_NCPU),
+        VMSTATE_UINT16_ARRAY(running_priority, GICState, GIC_NCPU),
+        VMSTATE_UINT16_ARRAY(current_pending, GICState, GIC_NCPU),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -84,9 +84,9 @@ static void arm_gic_common_realize(DeviceState *dev, Error **errp)
     GICState *s = ARM_GIC_COMMON(dev);
     int num_irq = s->num_irq;
 
-    if (s->num_cpu > NCPU) {
+    if (s->num_cpu > GIC_NCPU) {
         error_setg(errp, "requested %u CPUs exceeds GIC maximum %d",
-                   s->num_cpu, NCPU);
+                   s->num_cpu, GIC_NCPU);
         return;
     }
     s->num_irq += GIC_BASE_IRQ;
diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h
index 1426437..3989fd1 100644
--- a/hw/intc/gic_internal.h
+++ b/hw/intc/gic_internal.h
@@ -21,16 +21,9 @@
 #ifndef QEMU_ARM_GIC_INTERNAL_H
 #define QEMU_ARM_GIC_INTERNAL_H
 
-#include "hw/sysbus.h"
+#include "hw/intc/arm_gic.h"
 
-/* Maximum number of possible interrupts, determined by the GIC architecture */
-#define GIC_MAXIRQ 1020
-/* First 32 are private to each CPU (SGIs and PPIs). */
-#define GIC_INTERNAL 32
-/* Maximum number of possible CPU interfaces, determined by GIC architecture */
-#define NCPU 8
-
-#define ALL_CPU_MASK ((unsigned)(((1 << NCPU) - 1)))
+#define ALL_CPU_MASK ((unsigned)(((1 << GIC_NCPU) - 1)))
 
 /* The NVIC has 16 internal vectors.  However these are not exposed
    through the normal GIC interface.  */
@@ -59,48 +52,6 @@
                                     s->priority2[(irq) - GIC_INTERNAL])
 #define GIC_TARGET(irq) s->irq_target[irq]
 
-typedef struct gic_irq_state {
-    /* The enable bits are only banked for per-cpu interrupts.  */
-    uint8_t enabled;
-    uint8_t pending;
-    uint8_t active;
-    uint8_t level;
-    bool model; /* 0 = N:N, 1 = 1:N */
-    bool trigger; /* nonzero = edge triggered.  */
-} gic_irq_state;
-
-typedef struct GICState {
-    /*< private >*/
-    SysBusDevice parent_obj;
-    /*< public >*/
-
-    qemu_irq parent_irq[NCPU];
-    bool enabled;
-    bool cpu_enabled[NCPU];
-
-    gic_irq_state irq_state[GIC_MAXIRQ];
-    uint8_t irq_target[GIC_MAXIRQ];
-    uint8_t priority1[GIC_INTERNAL][NCPU];
-    uint8_t priority2[GIC_MAXIRQ - GIC_INTERNAL];
-    uint16_t last_active[GIC_MAXIRQ][NCPU];
-
-    uint16_t priority_mask[NCPU];
-    uint16_t running_irq[NCPU];
-    uint16_t running_priority[NCPU];
-    uint16_t current_pending[NCPU];
-
-    uint32_t num_cpu;
-
-    MemoryRegion iomem; /* Distributor */
-    /* This is just so we can have an opaque pointer which identifies
-     * both this GIC and which CPU interface we should be accessing.
-     */
-    struct GICState *backref[NCPU];
-    MemoryRegion cpuiomem[NCPU+1]; /* CPU interfaces */
-    uint32_t num_irq;
-    uint32_t revision;
-} GICState;
-
 /* The special cases for the revision property: */
 #define REV_11MPCORE 0
 #define REV_NVIC 0xffffffff
@@ -111,31 +62,4 @@ void gic_complete_irq(GICState *s, int cpu, int irq);
 void gic_update(GICState *s);
 void gic_init_irqs_and_distributor(GICState *s, int num_irq);
 
-#define TYPE_ARM_GIC_COMMON "arm_gic_common"
-#define ARM_GIC_COMMON(obj) \
-     OBJECT_CHECK(GICState, (obj), TYPE_ARM_GIC_COMMON)
-#define ARM_GIC_COMMON_CLASS(klass) \
-     OBJECT_CLASS_CHECK(ARMGICCommonClass, (klass), TYPE_ARM_GIC_COMMON)
-#define ARM_GIC_COMMON_GET_CLASS(obj) \
-     OBJECT_GET_CLASS(ARMGICCommonClass, (obj), TYPE_ARM_GIC_COMMON)
-
-typedef struct ARMGICCommonClass {
-    SysBusDeviceClass parent_class;
-    void (*pre_save)(GICState *s);
-    void (*post_load)(GICState *s);
-} ARMGICCommonClass;
-
-#define TYPE_ARM_GIC "arm_gic"
-#define ARM_GIC(obj) \
-     OBJECT_CHECK(GICState, (obj), TYPE_ARM_GIC)
-#define ARM_GIC_CLASS(klass) \
-     OBJECT_CLASS_CHECK(ARMGICClass, (klass), TYPE_ARM_GIC)
-#define ARM_GIC_GET_CLASS(obj) \
-     OBJECT_GET_CLASS(ARMGICClass, (obj), TYPE_ARM_GIC)
-
-typedef struct ARMGICClass {
-    ARMGICCommonClass parent_class;
-    DeviceRealize parent_realize;
-} ARMGICClass;
-
 #endif /* !QEMU_ARM_GIC_INTERNAL_H */
diff --git a/include/hw/intc/arm_gic.h b/include/hw/intc/arm_gic.h
new file mode 100644
index 0000000..0971e37
--- /dev/null
+++ b/include/hw/intc/arm_gic.h
@@ -0,0 +1,42 @@
+/*
+ * ARM GIC support
+ *
+ * Copyright (c) 2012 Linaro Limited
+ * Written by Peter Maydell
+ *
+ * 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/>.
+ */
+
+#ifndef HW_ARM_GIC_H
+#define HW_ARM_GIC_H
+
+#include "arm_gic_common.h"
+
+#define TYPE_ARM_GIC "arm_gic"
+#define ARM_GIC(obj) \
+     OBJECT_CHECK(GICState, (obj), TYPE_ARM_GIC)
+#define ARM_GIC_CLASS(klass) \
+     OBJECT_CLASS_CHECK(ARMGICClass, (klass), TYPE_ARM_GIC)
+#define ARM_GIC_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(ARMGICClass, (obj), TYPE_ARM_GIC)
+
+typedef struct ARMGICClass {
+    /*< private >*/
+    ARMGICCommonClass parent_class;
+    /*< public >*/
+
+    DeviceRealize parent_realize;
+} ARMGICClass;
+
+#endif
diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h
new file mode 100644
index 0000000..4f381bd
--- /dev/null
+++ b/include/hw/intc/arm_gic_common.h
@@ -0,0 +1,92 @@
+/*
+ * ARM GIC support
+ *
+ * Copyright (c) 2012 Linaro Limited
+ * Written by Peter Maydell
+ *
+ * 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/>.
+ */
+
+#ifndef HW_ARM_GIC_COMMON_H
+#define HW_ARM_GIC_COMMON_H
+
+#include "hw/sysbus.h"
+
+/* Maximum number of possible interrupts, determined by the GIC architecture */
+#define GIC_MAXIRQ 1020
+/* First 32 are private to each CPU (SGIs and PPIs). */
+#define GIC_INTERNAL 32
+/* Maximum number of possible CPU interfaces, determined by GIC architecture */
+#define GIC_NCPU 8
+
+typedef struct gic_irq_state {
+    /* The enable bits are only banked for per-cpu interrupts.  */
+    uint8_t enabled;
+    uint8_t pending;
+    uint8_t active;
+    uint8_t level;
+    bool model; /* 0 = N:N, 1 = 1:N */
+    bool trigger; /* nonzero = edge triggered.  */
+} gic_irq_state;
+
+typedef struct GICState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    qemu_irq parent_irq[GIC_NCPU];
+    bool enabled;
+    bool cpu_enabled[GIC_NCPU];
+
+    gic_irq_state irq_state[GIC_MAXIRQ];
+    uint8_t irq_target[GIC_MAXIRQ];
+    uint8_t priority1[GIC_INTERNAL][GIC_NCPU];
+    uint8_t priority2[GIC_MAXIRQ - GIC_INTERNAL];
+    uint16_t last_active[GIC_MAXIRQ][GIC_NCPU];
+
+    uint16_t priority_mask[GIC_NCPU];
+    uint16_t running_irq[GIC_NCPU];
+    uint16_t running_priority[GIC_NCPU];
+    uint16_t current_pending[GIC_NCPU];
+
+    uint32_t num_cpu;
+
+    MemoryRegion iomem; /* Distributor */
+    /* This is just so we can have an opaque pointer which identifies
+     * both this GIC and which CPU interface we should be accessing.
+     */
+    struct GICState *backref[GIC_NCPU];
+    MemoryRegion cpuiomem[GIC_NCPU + 1]; /* CPU interfaces */
+    uint32_t num_irq;
+    uint32_t revision;
+} GICState;
+
+#define TYPE_ARM_GIC_COMMON "arm_gic_common"
+#define ARM_GIC_COMMON(obj) \
+     OBJECT_CHECK(GICState, (obj), TYPE_ARM_GIC_COMMON)
+#define ARM_GIC_COMMON_CLASS(klass) \
+     OBJECT_CLASS_CHECK(ARMGICCommonClass, (klass), TYPE_ARM_GIC_COMMON)
+#define ARM_GIC_COMMON_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(ARMGICCommonClass, (obj), TYPE_ARM_GIC_COMMON)
+
+typedef struct ARMGICCommonClass {
+    /*< private >*/
+    SysBusDeviceClass parent_class;
+    /*< public >*/
+
+    void (*pre_save)(GICState *s);
+    void (*post_load)(GICState *s);
+} ARMGICCommonClass;
+
+#endif
commit 753bc6e981101b2a1d8bd4cb68f54dcdf82e9b63
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Sun Jun 30 19:52:31 2013 +0200

    a9mpcore: Split off instance_init
    
    Prepares for QOM realize.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
index 3e675e3..acbdab5 100644
--- a/hw/cpu/a9mpcore.c
+++ b/hw/cpu/a9mpcore.c
@@ -34,6 +34,14 @@ static void a9mp_priv_set_irq(void *opaque, int irq, int level)
     qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
 }
 
+static void a9mp_priv_initfn(Object *obj)
+{
+    A9MPPrivState *s = A9MPCORE_PRIV(obj);
+
+    memory_region_init(&s->container, obj, "a9mp-priv-container", 0x2000);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->container);
+}
+
 static int a9mp_priv_init(SysBusDevice *dev)
 {
     A9MPPrivState *s = A9MPCORE_PRIV(dev);
@@ -78,7 +86,6 @@ static int a9mp_priv_init(SysBusDevice *dev)
      *
      * We should implement the global timer but don't currently do so.
      */
-    memory_region_init(&s->container, OBJECT(s), "a9mp-priv-container", 0x2000);
     memory_region_add_subregion(&s->container, 0,
                                 sysbus_mmio_get_region(scubusdev, 0));
     /* GIC CPU interface */
@@ -94,8 +101,6 @@ static int a9mp_priv_init(SysBusDevice *dev)
     memory_region_add_subregion(&s->container, 0x1000,
                                 sysbus_mmio_get_region(gicbusdev, 0));
 
-    sysbus_init_mmio(dev, &s->container);
-
     /* Wire up the interrupt from each watchdog and timer.
      * For each core the timer is PPI 29 and the watchdog PPI 30.
      */
@@ -134,6 +139,7 @@ static const TypeInfo a9mp_priv_info = {
     .name          = TYPE_A9MPCORE_PRIV,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(A9MPPrivState),
+    .instance_init = a9mp_priv_initfn,
     .class_init    = a9mp_priv_class_init,
 };
 
commit c77dd5f6140acd62ba73fbb8b8144c42c003b995
Author: Antony Pavlov <antonynpavlov at gmail.com>
Date:   Sat Aug 31 21:22:40 2013 +0400

    milkymist-uart: Use Device::realize instead of SysBusDevice::init
    
    Use of SysBusDevice::init is deprecated. Use Device::realize instead.
    
    Also introduce TypeInfo::instance_init milkymist_uart_init().
    
    Reported-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/char/milkymist-uart.c b/hw/char/milkymist-uart.c
index 2e4b5c5..2c52a0f 100644
--- a/hw/char/milkymist-uart.c
+++ b/hw/char/milkymist-uart.c
@@ -195,22 +195,26 @@ static void milkymist_uart_reset(DeviceState *d)
     s->regs[R_STAT] = STAT_THRE;
 }
 
-static int milkymist_uart_init(SysBusDevice *dev)
+static void milkymist_uart_realize(DeviceState *dev, Error **errp)
 {
     MilkymistUartState *s = MILKYMIST_UART(dev);
 
-    sysbus_init_irq(dev, &s->irq);
-
-    memory_region_init_io(&s->regs_region, OBJECT(s), &uart_mmio_ops, s,
-                          "milkymist-uart", R_MAX * 4);
-    sysbus_init_mmio(dev, &s->regs_region);
-
     s->chr = qemu_char_get_next_serial();
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
     }
+}
 
-    return 0;
+static void milkymist_uart_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    MilkymistUartState *s = MILKYMIST_UART(obj);
+
+    sysbus_init_irq(sbd, &s->irq);
+
+    memory_region_init_io(&s->regs_region, OBJECT(s), &uart_mmio_ops, s,
+                          "milkymist-uart", R_MAX * 4);
+    sysbus_init_mmio(sbd, &s->regs_region);
 }
 
 static const VMStateDescription vmstate_milkymist_uart = {
@@ -227,9 +231,8 @@ static const VMStateDescription vmstate_milkymist_uart = {
 static void milkymist_uart_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    k->init = milkymist_uart_init;
+    dc->realize = milkymist_uart_realize;
     dc->reset = milkymist_uart_reset;
     dc->vmsd = &vmstate_milkymist_uart;
 }
@@ -238,6 +241,7 @@ static const TypeInfo milkymist_uart_info = {
     .name          = TYPE_MILKYMIST_UART,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(MilkymistUartState),
+    .instance_init = milkymist_uart_init,
     .class_init    = milkymist_uart_class_init,
 };
 
commit 7c41f2177e280dec1f1d4c5cd72333c5c55943af
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 05:44:47 2013 +0200

    qtest: Prepare QOM machine tests
    
    Instantiate all [*] machines per target, so that they get a bit of test
    coverage at all. This has proven helpful during QOM refactorings.
    
    [*] ppcemb target contains some non-working non-embedded machines, and
    ppc405 CPUs are not available there either.
    i386 and x86_64 do not cover pc*-x.y or xenfv.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/tests/Makefile b/tests/Makefile
index fa4c9f0..f414f2c 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -67,25 +67,50 @@ check-qtest-i386-y += tests/boot-order-test$(EXESUF)
 check-qtest-i386-y += tests/rtc-test$(EXESUF)
 check-qtest-i386-y += tests/i440fx-test$(EXESUF)
 check-qtest-i386-y += tests/fw_cfg-test$(EXESUF)
+check-qtest-i386-y += tests/qom-test$(EXESUF)
 check-qtest-x86_64-y = $(check-qtest-i386-y)
 gcov-files-i386-y += i386-softmmu/hw/mc146818rtc.c
 gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
 check-qtest-mips-y = tests/endianness-test$(EXESUF)
 check-qtest-mips64-y = tests/endianness-test$(EXESUF)
 check-qtest-mips64el-y = tests/endianness-test$(EXESUF)
+check-qtest-mips-y += tests/qom-test$(EXESUF)
+check-qtest-mipsel-y += tests/qom-test$(EXESUF)
+check-qtest-mips64-y += tests/qom-test$(EXESUF)
+check-qtest-mips64el-y += tests/qom-test$(EXESUF)
 check-qtest-ppc-y = tests/endianness-test$(EXESUF)
 check-qtest-ppc64-y = tests/endianness-test$(EXESUF)
 check-qtest-sh4-y = tests/endianness-test$(EXESUF)
 check-qtest-sh4eb-y = tests/endianness-test$(EXESUF)
+check-qtest-sh4-y += tests/qom-test$(EXESUF)
+check-qtest-sh4eb-y += tests/qom-test$(EXESUF)
 check-qtest-sparc64-y = tests/endianness-test$(EXESUF)
 #check-qtest-sparc-y = tests/m48t59-test$(EXESUF)
 #check-qtest-sparc64-y += tests/m48t59-test$(EXESUF)
 gcov-files-sparc-y += hw/m48t59.c
 gcov-files-sparc64-y += hw/m48t59.c
+check-qtest-sparc-y += tests/qom-test$(EXESUF)
+check-qtest-sparc64-y += tests/qom-test$(EXESUF)
 check-qtest-arm-y = tests/tmp105-test$(EXESUF)
 gcov-files-arm-y += hw/tmp105.c
+check-qtest-arm-y += tests/qom-test$(EXESUF)
 check-qtest-ppc-y += tests/boot-order-test$(EXESUF)
 check-qtest-ppc64-y += tests/boot-order-test$(EXESUF)
+check-qtest-ppc-y += tests/qom-test$(EXESUF)
+check-qtest-ppc64-y += tests/qom-test$(EXESUF)
+check-qtest-ppcemb-y += tests/qom-test$(EXESUF)
+check-qtest-alpha-y += tests/qom-test$(EXESUF)
+check-qtest-cris-y += tests/qom-test$(EXESUF)
+check-qtest-lm32-y += tests/qom-test$(EXESUF)
+check-qtest-m68k-y += tests/qom-test$(EXESUF)
+check-qtest-microblaze-y += tests/qom-test$(EXESUF)
+check-qtest-microblazeel-y = $(check-qtest-microblaze-y)
+check-qtest-moxie-y += tests/qom-test$(EXESUF)
+check-qtest-or32-y += tests/qom-test$(EXESUF)
+check-qtest-s390x-y += tests/qom-test$(EXESUF)
+check-qtest-unicore32-y += tests/qom-test$(EXESUF)
+check-qtest-xtensa-y += tests/qom-test$(EXESUF)
+check-qtest-xtensaeb-y = $(check-qtest-xtensa-y)
 
 check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
         comments.json empty.json funny-char.json indented-expr.json \
@@ -174,6 +199,7 @@ tests/boot-order-test$(EXESUF): tests/boot-order-test.o $(libqos-obj-y)
 tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
 tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
 tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
+tests/qom-test$(EXESUF): tests/qom-test.o
 tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
 
 # QTest rules
diff --git a/tests/qom-test.c b/tests/qom-test.c
new file mode 100644
index 0000000..6ed23c5
--- /dev/null
+++ b/tests/qom-test.c
@@ -0,0 +1,253 @@
+/*
+ * QTest testcase for QOM
+ *
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "libqtest.h"
+
+#include <glib.h>
+#include <string.h>
+#include "qemu/osdep.h"
+
+static void test_nop(gconstpointer data)
+{
+    QTestState *s;
+    const char *machine = data;
+    char *args;
+
+    args = g_strdup_printf("-display none -machine %s", machine);
+    s = qtest_start(args);
+    if (s) {
+        qtest_quit(s);
+    }
+    g_free(args);
+}
+
+static const char *x86_machines[] = {
+    "pc",
+    "isapc",
+    "q35",
+};
+
+static const char *alpha_machines[] = {
+    "clipper",
+};
+
+static const char *arm_machines[] = {
+    "integratorcp",
+    "versatilepb",
+    "versatileab",
+    "lm3s811evb",
+    "lm3s6965evb",
+    "collie",
+    "akita",
+    "spitz",
+    "borzoi",
+    "terrier",
+    "tosa",
+    "cheetah",
+    "sx1-v1",
+    "sx1",
+    "realview-eb",
+    "realview-eb-mpcore",
+    "realview-pb-a8",
+    "realview-pbx-a9",
+    "musicpal",
+    "mainstone",
+    "connex",
+    "verdex",
+    "z2",
+    "n800",
+    "n810",
+    "kzm",
+    "vexpress-a9",
+    "vexpress-a15",
+    "smdkc210",
+    "nuri",
+    "xilinx-zynq-a9",
+    "highbank",
+    "midway",
+};
+
+static const char *cris_machines[] = {
+    "axis-dev88",
+};
+
+static const char *lm32_machines[] = {
+    "lm32-evr",
+    "lm32-uclinux",
+    "milkymist",
+};
+
+static const char *m68k_machines[] = {
+    "mcf5208evb",
+    "an5206",
+    "dummy",
+};
+
+static const char *microblaze_machines[] = {
+    "petalogix-ml605",
+    "petalogix-s3adsp1800",
+};
+
+static const char *mips_machines[] = {
+    "malta",
+    "magnum",
+    "mips",
+    "mipssim",
+    "pica61",
+};
+
+static const char *moxie_machines[] = {
+    "moxiesim",
+};
+
+static const char *openrisc_machines[] = {
+    "or32-sim",
+};
+
+static const char *ppc_machines[] = {
+    "g3beige",
+    "mac99",
+    "prep",
+    "mpc8544ds",
+    "ppce500",
+};
+
+static const char *ppc64_machines[] = {
+    "pseries",
+};
+
+static const char *ppc405_machines[] = {
+    "ref405ep",
+    "taihu",
+};
+
+static const char *ppc440_machines[] = {
+    "bamboo",
+    "virtex-ml507",
+};
+
+static const char *s390_machines[] = {
+    "s390-virtio",
+    "s390-ccw-virtio",
+};
+
+static const char *superh_machines[] = {
+    "r2d",
+    "shix",
+};
+
+static const char *sparc_machines[] = {
+    "SS-4",
+    "SS-5",
+    "SS-10",
+    "SS-20",
+    "SS-600MP",
+    "LX",
+    "SPARCClassic",
+    "SPARCbook",
+    "leon3_generic",
+};
+
+static const char *sparc64_machines[] = {
+    "sun4u",
+    "sun4v",
+    "Niagara",
+};
+
+static const char *unicore32_machines[] = {
+    "puv3",
+};
+
+static const char *xtensa_machines[] = {
+    "sim",
+    "lx60",
+    "lx200",
+};
+
+static void add_test_cases(const char *arch, const char *machine)
+{
+    char *path;
+    path = g_strdup_printf("/%s/qom/%s", arch, machine);
+    g_test_add_data_func(path, machine, test_nop);
+}
+
+#define ADD_MACHINE_TESTS(arch, array) do { \
+    int i; \
+    for (i = 0; i < ARRAY_SIZE(array); i++) { \
+        add_test_cases((arch), (array)[i]); \
+    } \
+} while (false)
+
+int main(int argc, char **argv)
+{
+    const char *arch = qtest_get_arch();
+
+    g_test_init(&argc, &argv, NULL);
+
+    add_test_cases(arch, "none");
+
+    if (strcmp(arch, "i386") == 0 ||
+        strcmp(arch, "x86_64") == 0) {
+        ADD_MACHINE_TESTS(arch, x86_machines);
+    } else if (strcmp(arch, "alpha") == 0) {
+        ADD_MACHINE_TESTS(arch, alpha_machines);
+    } else if (strcmp(arch, "arm") == 0) {
+        ADD_MACHINE_TESTS(arch, arm_machines);
+    } else if (strcmp(arch, "cris") == 0) {
+        ADD_MACHINE_TESTS(arch, cris_machines);
+    } else if (strcmp(arch, "lm32") == 0) {
+        ADD_MACHINE_TESTS(arch, lm32_machines);
+    } else if (strcmp(arch, "m68k") == 0) {
+        ADD_MACHINE_TESTS(arch, m68k_machines);
+    } else if (strcmp(arch, "microblaze") == 0 ||
+               strcmp(arch, "microblazeel") == 0) {
+        ADD_MACHINE_TESTS(arch, microblaze_machines);
+    } else if (strcmp(arch, "mips") == 0 ||
+               strcmp(arch, "mipsel") == 0 ||
+               strcmp(arch, "mips64") == 0) {
+        ADD_MACHINE_TESTS(arch, mips_machines);
+    } else if (strcmp(arch, "mips64el") == 0) {
+        ADD_MACHINE_TESTS(arch, mips_machines);
+        add_test_cases(arch, "fulong2e");
+    } else if (strcmp(arch, "moxie") == 0) {
+        ADD_MACHINE_TESTS(arch, moxie_machines);
+    } else if (strcmp(arch, "or32") == 0) {
+        ADD_MACHINE_TESTS(arch, openrisc_machines);
+    } else if (strcmp(arch, "ppcemb") == 0) {
+#if 0
+        /* XXX Available in ppcemb but don't work */
+        ADD_MACHINE_TESTS(arch, ppc405_machines);
+#endif
+        ADD_MACHINE_TESTS(arch, ppc440_machines);
+    } else if (strcmp(arch, "ppc") == 0) {
+        ADD_MACHINE_TESTS(arch, ppc405_machines);
+        ADD_MACHINE_TESTS(arch, ppc440_machines);
+        ADD_MACHINE_TESTS(arch, ppc_machines);
+    } else if (strcmp(arch, "ppc64") == 0) {
+        ADD_MACHINE_TESTS(arch, ppc405_machines);
+        ADD_MACHINE_TESTS(arch, ppc440_machines);
+        ADD_MACHINE_TESTS(arch, ppc_machines);
+        ADD_MACHINE_TESTS(arch, ppc64_machines);
+    } else if (strcmp(arch, "s390x") == 0) {
+        ADD_MACHINE_TESTS(arch, s390_machines);
+    } else if (strcmp(arch, "sh4") == 0 ||
+               strcmp(arch, "sh4eb") == 0) {
+        ADD_MACHINE_TESTS(arch, superh_machines);
+    } else if (strcmp(arch, "sparc") == 0) {
+        ADD_MACHINE_TESTS(arch, sparc_machines);
+    } else if (strcmp(arch, "sparc64") == 0) {
+        ADD_MACHINE_TESTS(arch, sparc64_machines);
+    } else if (strcmp(arch, "unicore32") == 0) {
+        ADD_MACHINE_TESTS(arch, unicore32_machines);
+    } else if (strcmp(arch, "xtensa") == 0 ||
+               strcmp(arch, "xtensaeb") == 0) {
+        ADD_MACHINE_TESTS(arch, xtensa_machines);
+    }
+
+    return g_test_run();
+}
commit 7761254120905cb2c5c435246f97e51968ddddec
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Aug 4 17:58:58 2013 +0200

    leon3: Don't enforce use of -bios with qtest
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index 390f3e4..c583c3d 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -26,6 +26,7 @@
 #include "hw/ptimer.h"
 #include "sysemu/char.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/qtest.h"
 #include "hw/boards.h"
 #include "hw/loader.h"
 #include "elf.h"
@@ -178,7 +179,7 @@ static void leon3_generic_hw_init(QEMUMachineInitArgs *args)
             fprintf(stderr, "qemu: could not load prom '%s'\n", filename);
             exit(1);
         }
-    } else if (kernel_filename == NULL) {
+    } else if (kernel_filename == NULL && !qtest_enabled()) {
         fprintf(stderr, "Can't read bios image %s\n", filename);
         exit(1);
     }
commit d32f7d2506f1dab996e977e478f19baff5d47b51
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Aug 4 17:51:15 2013 +0200

    shix: Don't require firmware presence for qtest
    
    Adopt error_report() while at it.
    
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c
index a3929d4..728f1c3 100644
--- a/hw/block/tc58128.c
+++ b/hw/block/tc58128.c
@@ -1,6 +1,8 @@
 #include "hw/hw.h"
 #include "hw/sh4/sh.h"
 #include "hw/loader.h"
+#include "sysemu/qtest.h"
+#include "qemu/error-report.h"
 
 #define CE1  0x0100
 #define CE2  0x0200
@@ -36,10 +38,10 @@ static void init_dev(tc58128_dev * dev, const char *filename)
 	/* Load flash image skipping the first block */
 	ret = load_image(filename, dev->flash_contents + 528 * 32);
 	if (ret < 0) {
-	    fprintf(stderr, "ret=%d\n", ret);
-	    fprintf(stderr, "qemu: could not load flash image %s\n",
-		    filename);
-	    exit(1);
+            if (!qtest_enabled()) {
+                error_report("Could not load flash image %s", filename);
+                exit(1);
+            }
 	} else {
 	    /* Build first block with number of blocks */
 	    blocks = (ret + 528 * 32 - 1) / (528 * 32);
diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c
index f008b98..904a966 100644
--- a/hw/sh4/shix.c
+++ b/hw/sh4/shix.c
@@ -30,9 +30,11 @@
 #include "hw/hw.h"
 #include "hw/sh4/sh.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/qtest.h"
 #include "hw/boards.h"
 #include "hw/loader.h"
 #include "exec/address-spaces.h"
+#include "qemu/error-report.h"
 
 #define BIOS_FILENAME "shix_bios.bin"
 #define BIOS_ADDRESS 0xA0000000
@@ -72,10 +74,9 @@ static void shix_init(QEMUMachineInitArgs *args)
     if (bios_name == NULL)
         bios_name = BIOS_FILENAME;
     ret = load_image_targphys(bios_name, 0, 0x4000);
-    if (ret < 0) {		/* Check bios size */
-	fprintf(stderr, "qemu: could not load SHIX bios '%s'\n",
-		bios_name);
-	exit(1);
+    if (ret < 0 && !qtest_enabled()) {
+        error_report("Could not load SHIX bios '%s'", bios_name);
+        exit(1);
     }
 
     /* Register peripherals */
commit b6e770ee505771a6f3c3ffbf05719c149e069e3d
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Aug 4 17:53:24 2013 +0200

    shix: Drop debug output
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c
index 1ff37f5..f008b98 100644
--- a/hw/sh4/shix.c
+++ b/hw/sh4/shix.c
@@ -50,7 +50,6 @@ static void shix_init(QEMUMachineInitArgs *args)
     if (!cpu_model)
         cpu_model = "any";
 
-    printf("Initializing CPU\n");
     cpu = cpu_sh4_init(cpu_model);
     if (cpu == NULL) {
         fprintf(stderr, "Unable to find CPU definition\n");
@@ -58,16 +57,13 @@ static void shix_init(QEMUMachineInitArgs *args)
     }
 
     /* Allocate memory space */
-    printf("Allocating ROM\n");
     memory_region_init_ram(rom, NULL, "shix.rom", 0x4000);
     vmstate_register_ram_global(rom);
     memory_region_set_readonly(rom, true);
     memory_region_add_subregion(sysmem, 0x00000000, rom);
-    printf("Allocating SDRAM 1\n");
     memory_region_init_ram(&sdram[0], NULL, "shix.sdram1", 0x01000000);
     vmstate_register_ram_global(&sdram[0]);
     memory_region_add_subregion(sysmem, 0x08000000, &sdram[0]);
-    printf("Allocating SDRAM 2\n");
     memory_region_init_ram(&sdram[1], NULL, "shix.sdram2", 0x01000000);
     vmstate_register_ram_global(&sdram[1]);
     memory_region_add_subregion(sysmem, 0x0c000000, &sdram[1]);
@@ -75,10 +71,8 @@ static void shix_init(QEMUMachineInitArgs *args)
     /* Load BIOS in 0 (and access it through P2, 0xA0000000) */
     if (bios_name == NULL)
         bios_name = BIOS_FILENAME;
-    printf("%s: load BIOS '%s'\n", __func__, bios_name);
     ret = load_image_targphys(bios_name, 0, 0x4000);
     if (ret < 0) {		/* Check bios size */
-	fprintf(stderr, "ret=%d\n", ret);
 	fprintf(stderr, "qemu: could not load SHIX bios '%s'\n",
 		bios_name);
 	exit(1);
@@ -88,7 +82,6 @@ static void shix_init(QEMUMachineInitArgs *args)
     s = sh7750_init(cpu, sysmem);
     /* XXXXX Check success */
     tc58128_init(s, "shix_linux_nand.bin", NULL);
-    fprintf(stderr, "initialization terminated\n");
 }
 
 static QEMUMachine shix_machine = {
commit c00eb5cee145ec7ff030a6bfcb98afd7285868c2
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Aug 4 16:49:28 2013 +0200

    milkymist: Suppress -kernel/-bios/-drive error for qtest
    
    Acked-by: Michael Walle <michael at walle.cc>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index f1744ec..15053c4 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -21,6 +21,7 @@
 #include "hw/hw.h"
 #include "hw/block/flash.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/qtest.h"
 #include "hw/devices.h"
 #include "hw/boards.h"
 #include "hw/loader.h"
@@ -143,7 +144,7 @@ milkymist_init(QEMUMachineInitArgs *args)
     reset_info->bootstrap_pc = BIOS_OFFSET;
 
     /* if no kernel is given no valid bios rom is a fatal error */
-    if (!kernel_filename && !dinfo && !bios_filename) {
+    if (!kernel_filename && !dinfo && !bios_filename && !qtest_enabled()) {
         fprintf(stderr, "qemu: could not load Milkymist One bios '%s'\n",
                 bios_name);
         exit(1);
commit 19c82aac7540acdd4645b033bb99ceff960f9570
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 18:48:58 2013 +0200

    an5206: Don't enforce use of kernel for qtest
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c
index a8eee44..24f2068 100644
--- a/hw/m68k/an5206.c
+++ b/hw/m68k/an5206.c
@@ -12,6 +12,7 @@
 #include "hw/loader.h"
 #include "elf.h"
 #include "exec/address-spaces.h"
+#include "sysemu/qtest.h"
 
 #define KERNEL_LOAD_ADDR 0x10000
 #define AN5206_MBAR_ADDR 0x10000000
@@ -62,6 +63,9 @@ static void an5206_init(QEMUMachineInitArgs *args)
 
     /* Load kernel.  */
     if (!kernel_filename) {
+        if (qtest_enabled()) {
+            return;
+        }
         fprintf(stderr, "Kernel image must be specified\n");
         exit(1);
     }
commit 5c12762c2d9cfc7ff9744e4af14ef35190c5369b
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 18:47:21 2013 +0200

    mcf5208: Don't enforce use of kernel for qtest
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
index fb96fe8..6e30c0b 100644
--- a/hw/m68k/mcf5208.c
+++ b/hw/m68k/mcf5208.c
@@ -10,6 +10,7 @@
 #include "qemu/timer.h"
 #include "hw/ptimer.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/qtest.h"
 #include "net/net.h"
 #include "hw/boards.h"
 #include "hw/loader.h"
@@ -267,6 +268,9 @@ static void mcf5208evb_init(QEMUMachineInitArgs *args)
 
     /* Load kernel.  */
     if (!kernel_filename) {
+        if (qtest_enabled()) {
+            return;
+        }
         fprintf(stderr, "Kernel image must be specified\n");
         exit(1);
     }
commit 5efe843a9a0e049d3d2a13411b7df7d3a430540c
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 18:40:20 2013 +0200

    axis_dev88: Don't enforce use of kernel for qtest
    
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/cris/axis_dev88.c b/hw/cris/axis_dev88.c
index 03058d3..5524088 100644
--- a/hw/cris/axis_dev88.c
+++ b/hw/cris/axis_dev88.c
@@ -32,6 +32,7 @@
 #include "boot.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
+#include "sysemu/qtest.h"
 
 #define D(x)
 #define DNAND(x)
@@ -340,14 +341,14 @@ void axisdev88_init(QEMUMachineInitArgs *args)
                              irq[0x14 + i]);
     }
 
-    if (!kernel_filename) {
+    if (kernel_filename) {
+        li.image_filename = kernel_filename;
+        li.cmdline = kernel_cmdline;
+        cris_load_image(cpu, &li);
+    } else if (!qtest_enabled()) {
         fprintf(stderr, "Kernel image must be specified\n");
         exit(1);
     }
-
-    li.image_filename = kernel_filename;
-    li.cmdline = kernel_cmdline;
-    cris_load_image(cpu, &li);
 }
 
 static QEMUMachine axisdev88_machine = {
commit 5633b90ad44f08a57c44bb602cb0ae6668420ac9
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 18:36:59 2013 +0200

    armv7m: Don't enforce use of kernel for qtest
    
    Adopt error_report().
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 89a9015..397e8df 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -11,6 +11,8 @@
 #include "hw/arm/arm.h"
 #include "hw/loader.h"
 #include "elf.h"
+#include "sysemu/qtest.h"
+#include "qemu/error-report.h"
 
 /* Bitbanded IO.  Each word corresponds to a single bit.  */
 
@@ -232,21 +234,22 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
     big_endian = 0;
 #endif
 
-    if (!kernel_filename) {
+    if (!kernel_filename && !qtest_enabled()) {
         fprintf(stderr, "Guest image must be specified (using -kernel)\n");
         exit(1);
     }
 
-    image_size = load_elf(kernel_filename, NULL, NULL, &entry, &lowaddr,
-                          NULL, big_endian, ELF_MACHINE, 1);
-    if (image_size < 0) {
-        image_size = load_image_targphys(kernel_filename, 0, flash_size);
-	lowaddr = 0;
-    }
-    if (image_size < 0) {
-        fprintf(stderr, "qemu: could not load kernel '%s'\n",
-                kernel_filename);
-        exit(1);
+    if (kernel_filename) {
+        image_size = load_elf(kernel_filename, NULL, NULL, &entry, &lowaddr,
+                              NULL, big_endian, ELF_MACHINE, 1);
+        if (image_size < 0) {
+            image_size = load_image_targphys(kernel_filename, 0, flash_size);
+            lowaddr = 0;
+        }
+        if (image_size < 0) {
+            error_report("Could not load kernel '%s'", kernel_filename);
+            exit(1);
+        }
     }
 
     /* Hack to map an additional page of ram at the top of the address
commit 4bd2f93ff9dcf5fbbdb55affc55b7f1a568e43cf
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 18:29:54 2013 +0200

    exynos4_boards: Silence lack of -smp 2 warning for qtest
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
index 2929f9f..26cedec 100644
--- a/hw/arm/exynos4_boards.c
+++ b/hw/arm/exynos4_boards.c
@@ -22,6 +22,7 @@
  */
 
 #include "sysemu/sysemu.h"
+#include "sysemu/qtest.h"
 #include "hw/sysbus.h"
 #include "net/net.h"
 #include "hw/arm/arm.h"
@@ -96,7 +97,7 @@ static void lan9215_init(uint32_t base, qemu_irq irq)
 static Exynos4210State *exynos4_boards_init_common(QEMUMachineInitArgs *args,
                                                    Exynos4BoardType board_type)
 {
-    if (smp_cpus != EXYNOS4210_NCPUS) {
+    if (smp_cpus != EXYNOS4210_NCPUS && !qtest_enabled()) {
         fprintf(stderr, "%s board supports only %d CPU cores. Ignoring smp_cpus"
                 " value.\n",
                 exynos4_machines[board_type].name,
commit db3fd06902c96644cb4d4a76f54924c754faf13c
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 18:27:58 2013 +0200

    omap_sx1: Don't enforce use of kernel or flash for qtest
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
index 03b3816..3ba263a 100644
--- a/hw/arm/omap_sx1.c
+++ b/hw/arm/omap_sx1.c
@@ -32,6 +32,7 @@
 #include "hw/arm/arm.h"
 #include "hw/block/flash.h"
 #include "sysemu/blockdev.h"
+#include "sysemu/qtest.h"
 #include "exec/address-spaces.h"
 
 /*****************************************************************************/
@@ -188,7 +189,7 @@ static void sx1_init(QEMUMachineInitArgs *args, const int version)
                                 OMAP_CS1_BASE, &cs[1]);
     }
 
-    if (!args->kernel_filename && !fl_idx) {
+    if (!args->kernel_filename && !fl_idx && !qtest_enabled()) {
         fprintf(stderr, "Kernel or Flash image must be specified\n");
         exit(1);
     }
commit 1ca8334e42d84cf246db88502cebf11042df2c51
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 18:24:47 2013 +0200

    palm: Don't enforce loading ROM or kernel for qtest
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/arm/palm.c b/hw/arm/palm.c
index 0b72bbe..fac4f69 100644
--- a/hw/arm/palm.c
+++ b/hw/arm/palm.c
@@ -19,6 +19,7 @@
 #include "hw/hw.h"
 #include "audio/audio.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/qtest.h"
 #include "ui/console.h"
 #include "hw/arm/omap.h"
 #include "hw/boards.h"
@@ -255,7 +256,7 @@ static void palmte_init(QEMUMachineInitArgs *args)
         }
     }
 
-    if (!rom_loaded && !kernel_filename) {
+    if (!rom_loaded && !kernel_filename && !qtest_enabled()) {
         fprintf(stderr, "Kernel or ROM image must be specified\n");
         exit(1);
     }
commit e25ac5f66275b3f9615a6c24d7ef5625f1b49ef4
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 17:15:55 2013 +0200

    z2: Don't enforce use of -pflash for qtest
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index a00fcc0..d52c501 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -24,6 +24,7 @@
 #include "ui/console.h"
 #include "audio/audio.h"
 #include "exec/address-spaces.h"
+#include "sysemu/qtest.h"
 
 #ifdef DEBUG_Z2
 #define DPRINTF(fmt, ...) \
@@ -323,7 +324,7 @@ static void z2_init(QEMUMachineInitArgs *args)
     be = 0;
 #endif
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    if (!dinfo) {
+    if (!dinfo && !qtest_enabled()) {
         fprintf(stderr, "Flash image must be given with the "
                 "'pflash' parameter\n");
         exit(1);
@@ -331,7 +332,7 @@ static void z2_init(QEMUMachineInitArgs *args)
 
     if (!pflash_cfi01_register(Z2_FLASH_BASE,
                                NULL, "z2.flash0", Z2_FLASH_SIZE,
-                               dinfo->bdrv, sector_len,
+                               dinfo ? dinfo->bdrv : NULL, sector_len,
                                Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0,
                                be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
commit bdf921d65f83c1958e00c347816c0f754f9bc6dc
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 17:15:01 2013 +0200

    gumstix: Don't enforce use of -pflash for qtest
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
index e97fbbd..aeea172 100644
--- a/hw/arm/gumstix.c
+++ b/hw/arm/gumstix.c
@@ -42,6 +42,7 @@
 #include "hw/boards.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
+#include "sysemu/qtest.h"
 
 static const int sector_len = 128 * 1024;
 
@@ -58,7 +59,7 @@ static void connex_init(QEMUMachineInitArgs *args)
     cpu = pxa255_init(address_space_mem, connex_ram);
 
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    if (!dinfo) {
+    if (!dinfo && !qtest_enabled()) {
         fprintf(stderr, "A flash image must be given with the "
                 "'pflash' parameter\n");
         exit(1);
@@ -70,7 +71,8 @@ static void connex_init(QEMUMachineInitArgs *args)
     be = 0;
 #endif
     if (!pflash_cfi01_register(0x00000000, NULL, "connext.rom", connex_rom,
-                               dinfo->bdrv, sector_len, connex_rom / sector_len,
+                               dinfo ? dinfo->bdrv : NULL,
+                               sector_len, connex_rom / sector_len,
                                2, 0, 0, 0, 0, be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
@@ -95,7 +97,7 @@ static void verdex_init(QEMUMachineInitArgs *args)
     cpu = pxa270_init(address_space_mem, verdex_ram, cpu_model ?: "pxa270-c0");
 
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    if (!dinfo) {
+    if (!dinfo && !qtest_enabled()) {
         fprintf(stderr, "A flash image must be given with the "
                 "'pflash' parameter\n");
         exit(1);
@@ -107,7 +109,8 @@ static void verdex_init(QEMUMachineInitArgs *args)
     be = 0;
 #endif
     if (!pflash_cfi01_register(0x00000000, NULL, "verdex.rom", verdex_rom,
-                               dinfo->bdrv, sector_len, verdex_rom / sector_len,
+                               dinfo ? dinfo->bdrv : NULL,
+                               sector_len, verdex_rom / sector_len,
                                2, 0, 0, 0, 0, be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
commit d2f7c496c32476bb5eff616f6fda293393d70740
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 17:12:41 2013 +0200

    mainstone: Don't enforce use of -pflash for qtest
    
    Simply skip flash setup for now.
    
    Also drop useless debug output.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index b244f7e..9402c84 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -21,6 +21,7 @@
 #include "sysemu/blockdev.h"
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
+#include "sysemu/qtest.h"
 
 /* Device addresses */
 #define MST_FPGA_PHYS	0x08000000
@@ -127,6 +128,9 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
     for (i = 0; i < 2; i ++) {
         dinfo = drive_get(IF_PFLASH, 0, i);
         if (!dinfo) {
+            if (qtest_enabled()) {
+                break;
+            }
             fprintf(stderr, "Two flash images must be given with the "
                     "'pflash' parameter\n");
             exit(1);
@@ -147,7 +151,6 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
                     qdev_get_gpio_in(mpu->gpio, 0));
 
     /* setup keypad */
-    printf("map addr %p\n", &map);
     pxa27x_register_keypad(mpu->kp, map, 0xe0);
 
     /* MMC/SD host */
commit f741a26c126448adebee7b85fc87b72176c3dfa5
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 18:43:57 2013 +0200

    puv3: Turn puv3_load_kernel() into a no-op for qtest without -kernel
    
    Replacing the assert() with more user-friendly error handling is left
    for a follow-up.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
index a900061..e05cbc1 100644
--- a/hw/unicore32/puv3.c
+++ b/hw/unicore32/puv3.c
@@ -17,6 +17,7 @@
 #include "hw/boards.h"
 #include "hw/loader.h"
 #include "hw/i386/pc.h"
+#include "sysemu/qtest.h"
 
 #undef DEBUG_PUV3
 #include "hw/unicore32/puv3.h"
@@ -84,6 +85,9 @@ static void puv3_load_kernel(const char *kernel_filename)
 {
     int size;
 
+    if (kernel_filename == NULL && qtest_enabled()) {
+        return;
+    }
     assert(kernel_filename != NULL);
 
     /* only zImage format supported */
commit 22d5523d3fbb95264055e11eb47738a7442a4ecb
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 17:01:37 2013 +0200

    mips_mipssim: Silence BIOS loading warning for qtest
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c
index 242bab9..239aa6a 100644
--- a/hw/mips/mips_mipssim.c
+++ b/hw/mips/mips_mipssim.c
@@ -38,6 +38,7 @@
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
 #include "qemu/error-report.h"
+#include "sysemu/qtest.h"
 
 static struct _loaderparams {
     int ram_size;
@@ -190,7 +191,8 @@ mips_mipssim_init(QEMUMachineInitArgs *args)
     } else {
         bios_size = -1;
     }
-    if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
+    if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
+        !kernel_filename && !qtest_enabled()) {
         /* Bail out if we have neither a kernel image nor boot vector code. */
         error_report("Could not load MIPS bios '%s', and no "
                      "-kernel argument was specified", filename);
commit 6d0a37354259ec446bace1a671685ba27f1fe1d6
Merge: a126050 df39076
Author: Andreas Färber <afaerber at suse.de>
Date:   Tue Nov 5 17:46:04 2013 +0100

    Merge tag 'for_anthony' of git://git.kernel.org/pub/scm/virt/kvm/mst/qemu
    
    pci, pc, pvpanic bug fixes
    
    This fixes strange pvpanic behaviour: you had to
    pause to let VM continue (and potentially reboot on panic
    if enabled).
    
    This also fixes two bugs reported by Andreas.
    One is a long-standing bug exposed by recent pci changes,
    the other affects old piix machine types and was caused
    by recent acpi changes.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

commit c905c5012ac0c6fde3b8094d2206a3139deddba2
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Sun Nov 3 08:45:54 2013 -0800

    ossaudio: do not enable by default
    
    Modern Linux's no longer support /dev/dsp so enabling it by
    default causes audio failures on newer Linux distros.
    
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>
    Tested-by: Andreas Färber <afaerber at suse.de>
    Message-id: 1383497154-9271-1-git-send-email-aliguori at amazon.com

diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index 007c641..3e04a58 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -932,7 +932,7 @@ struct audio_driver oss_audio_driver = {
     .init           = oss_audio_init,
     .fini           = oss_audio_fini,
     .pcm_ops        = &oss_pcm_ops,
-    .can_be_default = 1,
+    .can_be_default = 0,
     .max_voices_out = INT_MAX,
     .max_voices_in  = INT_MAX,
     .voice_size_out = sizeof (OSSVoiceOut),
commit 29f8f3835f63fb7c55c7bb56d26165ade793fc49
Merge: f772a83 4a46c99
Author: Anthony Liguori <aliguori at amazon.com>
Date:   Tue Nov 5 08:39:49 2013 -0800

    Merge remote-tracking branch 'spice/spice.v76' into staging
    
    # By Gerd Hoffmann
    # Via Gerd Hoffmann
    * spice/spice.v76:
      qxl: replace pipe signaling with bottom half
    
    Message-id: 1383656322-24150-1-git-send-email-kraxel at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

commit f772a83113a9b692b94dc48b4f282224a2c6ccf2
Merge: 0d6e9a2 df39076
Author: Anthony Liguori <aliguori at amazon.com>
Date:   Tue Nov 5 08:29:56 2013 -0800

    Merge remote-tracking branch 'mst/tags/for_anthony' into staging
    
    pci, pc, pvpanic bug fixes
    
    This fixes strange pvpanic behaviour: you had to
    pause to let VM continue (and potentially reboot on panic
    if enabled).
    
    This also fixes two bugs reported by Andreas.
    One is a long-standing bug exposed by recent pci changes,
    the other affects old piix machine types and was caused
    by recent acpi changes.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    
    # gpg: Signature made Mon 04 Nov 2013 05:42:46 AM PST using RSA key ID D28D5469
    # gpg: Can't check signature: public key not found
    
    # By Michael S. Tsirkin (2) and Paolo Bonzini (1)
    # Via Michael S. Tsirkin
    * mst/tags/for_anthony:
      vl: allow "cont" from panicked state
      exec: limit system memory size
      pc: disable acpi info for isapc and old pc machine
    
    Message-id: 1383572851-28326-1-git-send-email-mst at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

commit 0d6e9a23ae6a839f4fa6e3e2816367e0ffa09869
Merge: a126050 7db16f2
Author: Anthony Liguori <aliguori at amazon.com>
Date:   Tue Nov 5 08:26:57 2013 -0800

    Merge remote-tracking branch 'kraxel/e820.1' into staging
    
    # By Gerd Hoffmann
    # Via Gerd Hoffmann
    * kraxel/e820.1:
      pc: register e820 entries for ram
      pc: add etc/e820 fw_cfg file
    
    Message-id: 1383567431-13540-1-git-send-email-kraxel at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at amazon.com>

commit df39076850958b842ac9e414dc3ab2895f1877bf
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Nov 4 14:30:47 2013 +0100

    vl: allow "cont" from panicked state
    
    After reporting the GUEST_PANICKED monitor event, QEMU stops the VM.
    The reason for this is that events are edge-triggered, and can be lost if
    management dies at the wrong time.  Stopping a panicked VM lets management
    know of a panic even if it has crashed; management can learn about the
    panic when it restarts and queries running QEMU processes.  The downside
    is of course that the VM will be paused while management is not running,
    but that is acceptable if it only happens with explicit "-device pvpanic".
    
    Upon learning of a panic, management (if configured to do so) can pick a
    variety of behaviors: leave the VM paused, reset it, destroy it.  In
    addition to all of these behaviors, it is possible to dump the VM core
    from the host.
    
    However, right now, the panicked state is irreversible, and can only be
    exited by resetting the machine.  This means that any policy decision
    is entirely in the hands of the host.  In particular there is no way to
    use the "reboot on panic" option together with pvpanic.
    
    This patch makes the panicked state reversible (and removes various
    workarounds that were there because of the state being irreversible).
    With this change, management has a wider set of possible policies: it
    can just log the crash and leave policy to the guest, it can leave the
    VM paused.  In particular, the "log the crash and continue" is implemented
    simply by sending a "cont" as soon as management learns about the panic.
    Management could also implement the "irreversible paused state" itself.
    And again, all such actions can be coupled with dumping the VM core.
    
    Unfortunately we cannot change the behavior of 1.6.0.  Thus, even if
    it uses "-device pvpanic", management should check for "cont" failures.
    If "cont" fails, management can then log that the VM remained paused
    and urge the administrator to update QEMU.
    
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
    Acked-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/gdbstub.c b/gdbstub.c
index 0e5a3f5..e8ab0b2 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -368,9 +368,6 @@ static inline void gdb_continue(GDBState *s)
 #ifdef CONFIG_USER_ONLY
     s->running_state = 1;
 #else
-    if (runstate_check(RUN_STATE_GUEST_PANICKED)) {
-        runstate_set(RUN_STATE_DEBUG);
-    }
     if (!runstate_needs_reset()) {
         vm_start();
     }
diff --git a/vl.c b/vl.c
index efbff65..4ad15b8 100644
--- a/vl.c
+++ b/vl.c
@@ -638,9 +638,8 @@ static const RunStateTransition runstate_transitions_def[] = {
     { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
     { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
 
-    { RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED },
+    { RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING },
     { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
-    { RUN_STATE_GUEST_PANICKED, RUN_STATE_DEBUG },
 
     { RUN_STATE_MAX, RUN_STATE_MAX },
 };
@@ -686,8 +685,7 @@ int runstate_is_running(void)
 bool runstate_needs_reset(void)
 {
     return runstate_check(RUN_STATE_INTERNAL_ERROR) ||
-        runstate_check(RUN_STATE_SHUTDOWN) ||
-        runstate_check(RUN_STATE_GUEST_PANICKED);
+        runstate_check(RUN_STATE_SHUTDOWN);
 }
 
 StatusInfo *qmp_query_status(Error **errp)
commit 818f86b88394b7b2b59d313e51043fe15a8004db
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Mon Nov 4 08:06:08 2013 +0200

    exec: limit system memory size
    
    The page table logic in exec.c assumes
    that memory addresses are at most TARGET_PHYS_ADDR_SPACE_BITS.
    
    But pci addresses are full 64 bit so if we try to render them ignoring
    the extra bits, we get strange effects with sections overlapping each
    other.
    
    To fix, simply limit the system memory size to
     1 << TARGET_PHYS_ADDR_SPACE_BITS,
    pci addresses will be rendered within that.
    
    Cc: qemu-stable at nongnu.org
    Reported-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/exec.c b/exec.c
index b453713..79610ce 100644
--- a/exec.c
+++ b/exec.c
@@ -1741,7 +1741,12 @@ void address_space_destroy_dispatch(AddressSpace *as)
 static void memory_map_init(void)
 {
     system_memory = g_malloc(sizeof(*system_memory));
-    memory_region_init(system_memory, NULL, "system", INT64_MAX);
+
+    assert(TARGET_PHYS_ADDR_SPACE_BITS <= 64);
+
+    memory_region_init(system_memory, NULL, "system",
+                       TARGET_PHYS_ADDR_SPACE_BITS == 64 ?
+                       UINT64_MAX : (0x1ULL << TARGET_PHYS_ADDR_SPACE_BITS));
     address_space_init(&address_space_memory, system_memory, "memory");
 
     system_io = g_malloc(sizeof(*system_io));
commit 98af2ac93fa6bd83e19f7cff1cc9513fa7c4d58d
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Mon Nov 4 12:42:46 2013 +0200

    pc: disable acpi info for isapc and old pc machine
    
    Disable acpi build for isapc and no_kvmclock machine
    types (used by xen), since acpi build currently expects pci.
    
    Reported-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 24a98cb..4fdb7b6 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -309,6 +309,7 @@ static void pc_init_pci_1_2(QEMUMachineInitArgs *args)
 static void pc_init_pci_no_kvmclock(QEMUMachineInitArgs *args)
 {
     has_pci_info = false;
+    has_acpi_build = false;
     disable_kvm_pv_eoi();
     enable_compat_apic_id_mode();
     pc_init1(args, 1, 0);
@@ -317,6 +318,7 @@ static void pc_init_pci_no_kvmclock(QEMUMachineInitArgs *args)
 static void pc_init_isa(QEMUMachineInitArgs *args)
 {
     has_pci_info = false;
+    has_acpi_build = false;
     if (!args->cpu_model) {
         args->cpu_model = "486";
     }
commit 4a46c99c8118586f19894fe66fc6e353f159d4d9
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Tue Oct 29 13:29:43 2013 +0100

    qxl: replace pipe signaling with bottom half
    
    qxl creates a pipe, then writes something to it to wake up the iothread
    from the spice server thread to raise an irq.  These days qemu bottom
    halves can be scheduled from threads and signals, so there is no reason
    to do this any more.  Time to clean it up.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 5977d52..efdefd6 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -1701,15 +1701,9 @@ static const MemoryRegionOps qxl_io_ops = {
     },
 };
 
-static void pipe_read(void *opaque)
+static void qxl_update_irq_bh(void *opaque)
 {
     PCIQXLDevice *d = opaque;
-    char dummy;
-    int len;
-
-    do {
-        len = read(d->pipe[0], &dummy, sizeof(dummy));
-    } while (len == sizeof(dummy));
     qxl_update_irq(d);
 }
 
@@ -1730,28 +1724,7 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
     if ((old_pending & le_events) == le_events) {
         return;
     }
-    if (qemu_thread_is_self(&d->main)) {
-        qxl_update_irq(d);
-    } else {
-        if (write(d->pipe[1], d, 1) != 1) {
-            dprint(d, 1, "%s: write to pipe failed\n", __func__);
-        }
-    }
-}
-
-static void init_pipe_signaling(PCIQXLDevice *d)
-{
-    if (pipe(d->pipe) < 0) {
-        fprintf(stderr, "%s:%s: qxl pipe creation failed\n",
-                __FILE__, __func__);
-        exit(1);
-    }
-    fcntl(d->pipe[0], F_SETFL, O_NONBLOCK);
-    fcntl(d->pipe[1], F_SETFL, O_NONBLOCK);
-    fcntl(d->pipe[0], F_SETOWN, getpid());
-
-    qemu_thread_get_self(&d->main);
-    qemu_set_fd_handler(d->pipe[0], pipe_read, NULL, d);
+    qemu_bh_schedule(d->update_irq);
 }
 
 /* graphics console */
@@ -2044,7 +2017,7 @@ static int qxl_init_common(PCIQXLDevice *qxl)
     }
     qemu_add_vm_change_state_handler(qxl_vm_change_state_handler, qxl);
 
-    init_pipe_signaling(qxl);
+    qxl->update_irq = qemu_bh_new(qxl_update_irq_bh, qxl);
     qxl_reset_state(qxl);
 
     qxl->update_area_bh = qemu_bh_new(qxl_render_update_area_bh, qxl);
diff --git a/hw/display/qxl.h b/hw/display/qxl.h
index 84f0182..c5de3d7 100644
--- a/hw/display/qxl.h
+++ b/hw/display/qxl.h
@@ -81,8 +81,7 @@ typedef struct PCIQXLDevice {
     QemuMutex          track_lock;
 
     /* thread signaling */
-    QemuThread         main;
-    int                pipe[2];
+    QEMUBH             *update_irq;
 
     /* ram pci bar */
     QXLRam             *ram;
commit 7db16f2480db5e246d34d0c453cff4f58549df0e
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Oct 10 10:30:27 2013 +0200

    pc: register e820 entries for ram
    
    So RAM shows up in the new etc/e820 fw_cfg file.
    
    Cc: Andrea Arcangeli <aarcange at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index a653ae4..12c436e 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1174,13 +1174,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
     memory_region_init_alias(ram_below_4g, NULL, "ram-below-4g", ram,
                              0, below_4g_mem_size);
     memory_region_add_subregion(system_memory, 0, ram_below_4g);
-    if (0) {
-        /*
-         * Ideally we should do that too, but that would ruin the e820
-         * reservations added by seabios before initializing fw_cfg.
-         */
-        e820_add_entry(0, below_4g_mem_size, E820_RAM);
-    }
+    e820_add_entry(0, below_4g_mem_size, E820_RAM);
     if (above_4g_mem_size > 0) {
         ram_above_4g = g_malloc(sizeof(*ram_above_4g));
         memory_region_init_alias(ram_above_4g, NULL, "ram-above-4g", ram,
commit 7d67110f2d9a6a2d6b5215a948abc95d07258735
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Oct 18 11:31:54 2013 +0200

    pc: add etc/e820 fw_cfg file
    
    Unlike the existing FW_CFG_E820_TABLE entry which carries reservations
    only the new etc/e820 file also has entries for RAM.
    
    Format is simliar to the FW_CFG_E820_TABLE, it is a simple list of
    e820_entry structs.  Unlike FW_CFG_E820_TABLE it has no count though
    as the number of entries can be figured from the file size.
    
    Cc: Andrea Arcangeli <aarcange at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index dee409d..a653ae4 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -90,7 +90,9 @@ struct e820_table {
     struct e820_entry entry[E820_NR_ENTRIES];
 } QEMU_PACKED __attribute((__aligned__(4)));
 
-static struct e820_table e820_table;
+static struct e820_table e820_reserve;
+static struct e820_entry *e820_table;
+static unsigned e820_entries;
 struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX};
 
 void gsi_handler(void *opaque, int n, int level)
@@ -577,19 +579,32 @@ static void handle_a20_line_change(void *opaque, int irq, int level)
 
 int e820_add_entry(uint64_t address, uint64_t length, uint32_t type)
 {
-    int index = le32_to_cpu(e820_table.count);
+    int index = le32_to_cpu(e820_reserve.count);
     struct e820_entry *entry;
 
-    if (index >= E820_NR_ENTRIES)
-        return -EBUSY;
-    entry = &e820_table.entry[index++];
+    if (type != E820_RAM) {
+        /* old FW_CFG_E820_TABLE entry -- reservations only */
+        if (index >= E820_NR_ENTRIES) {
+            return -EBUSY;
+        }
+        entry = &e820_reserve.entry[index++];
+
+        entry->address = cpu_to_le64(address);
+        entry->length = cpu_to_le64(length);
+        entry->type = cpu_to_le32(type);
+
+        e820_reserve.count = cpu_to_le32(index);
+    }
 
-    entry->address = cpu_to_le64(address);
-    entry->length = cpu_to_le64(length);
-    entry->type = cpu_to_le32(type);
+    /* new "etc/e820" file -- include ram too */
+    e820_table = g_realloc(e820_table,
+                           sizeof(struct e820_entry) * (e820_entries+1));
+    e820_table[e820_entries].address = cpu_to_le64(address);
+    e820_table[e820_entries].length = cpu_to_le64(length);
+    e820_table[e820_entries].type = cpu_to_le32(type);
+    e820_entries++;
 
-    e820_table.count = cpu_to_le32(index);
-    return index;
+    return e820_entries;
 }
 
 /* Calculates the limit to CPU APIC ID values
@@ -640,7 +655,9 @@ static FWCfgState *bochs_bios_init(void)
         fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
                          smbios_table, smbios_len);
     fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE,
-                     &e820_table, sizeof(e820_table));
+                     &e820_reserve, sizeof(e820_reserve));
+    fw_cfg_add_file(fw_cfg, "etc/e820", e820_table,
+                    sizeof(struct e820_entry) * e820_entries);
 
     fw_cfg_add_bytes(fw_cfg, FW_CFG_HPET, &hpet_cfg, sizeof(hpet_cfg));
     /* allocate memory for the NUMA channel: one (64bit) word for the number


More information about the Spice-commits mailing list