[Spice-commits] 50 commits - MAINTAINERS Makefile Makefile.objs Makefile.target bsd-user/mmap.c configure disas/Makefile.objs fpu/softfloat.c fsdev/Makefile.objs hw/Makefile.objs hw/adb.c hw/adb.h hw/arm_boot.c hw/arm_sysctl.c hw/cuda.c hw/fw_cfg.c hw/grackle_pci.c hw/heathrow_pic.c hw/ide hw/ide.h hw/m25p80.c hw/mac_nvram.c hw/macio.c hw/omap1.c hw/omap_dma.c hw/omap_spi.c hw/openpic.c hw/openpic.h hw/pci hw/pflash_cfi02.c hw/ppc hw/ppc_mac.h hw/ppc_newworld.c hw/ppc_oldworld.c hw/pxa2xx_timer.c hw/smc91c111.c hw/spapr.c hw/spapr_pci.c hw/spapr_pci.h hw/spapr_vio.c hw/unin_pci.c hw/vmware_vga.c hw/xilinx_ethlite.c include/sysemu qemu-char.c qom/Makefile.objs scripts/make_device_config.sh target-ppc/translate_init.c tests/Makefile tests/test-string-input-visitor.c util/oslib-posix.c vl.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Mon Jan 28 00:44:08 PST 2013


 MAINTAINERS                       |    4 
 Makefile                          |   15 -
 Makefile.objs                     |   43 +--
 Makefile.target                   |    3 
 bsd-user/mmap.c                   |    4 
 configure                         |    2 
 disas/Makefile.objs               |   30 +-
 fpu/softfloat.c                   |    4 
 fsdev/Makefile.objs               |    8 
 hw/Makefile.objs                  |   10 
 hw/adb.c                          |  252 +++++++++++++++-----
 hw/adb.h                          |   46 ++-
 hw/arm_boot.c                     |    9 
 hw/arm_sysctl.c                   |    2 
 hw/cuda.c                         |  106 +++-----
 hw/fw_cfg.c                       |   13 -
 hw/grackle_pci.c                  |    2 
 hw/heathrow_pic.c                 |    2 
 hw/ide.h                          |    4 
 hw/ide/macio.c                    |   84 ++++--
 hw/m25p80.c                       |    2 
 hw/mac_nvram.c                    |   88 ++++---
 hw/macio.c                        |  289 ++++++++++++++++++-----
 hw/omap1.c                        |    3 
 hw/omap_dma.c                     |   12 
 hw/omap_spi.c                     |   24 +
 hw/openpic.c                      |  363 +++++++++++++++++++----------
 hw/openpic.h                      |    1 
 hw/pci/Makefile.objs              |    2 
 hw/pflash_cfi02.c                 |    1 
 hw/ppc/Makefile.objs              |    9 
 hw/ppc/e500.c                     |    6 
 hw/ppc/e500.h                     |    2 
 hw/ppc/e500plat.c                 |    4 
 hw/ppc/mac.h                      |  181 ++++++++++++++
 hw/ppc/mac_newworld.c             |  469 ++++++++++++++++++++++++++++++++++++++
 hw/ppc/mac_oldworld.c             |  355 ++++++++++++++++++++++++++++
 hw/ppc/mpc8544ds.c                |    2 
 hw/ppc_mac.h                      |   81 ------
 hw/ppc_newworld.c                 |  453 ------------------------------------
 hw/ppc_oldworld.c                 |  352 ----------------------------
 hw/pxa2xx_timer.c                 |   47 +++
 hw/smc91c111.c                    |    1 
 hw/spapr.c                        |   13 -
 hw/spapr_pci.c                    |  102 ++++++--
 hw/spapr_pci.h                    |   22 +
 hw/spapr_vio.c                    |    2 
 hw/unin_pci.c                     |    2 
 hw/vmware_vga.c                   |   18 +
 hw/xilinx_ethlite.c               |   23 +
 include/sysemu/sysemu.h           |    2 
 qemu-char.c                       |    8 
 qom/Makefile.objs                 |    4 
 scripts/make_device_config.sh     |    2 
 target-ppc/translate_init.c       |   12 
 tests/Makefile                    |   18 -
 tests/test-string-input-visitor.c |   49 +++
 util/oslib-posix.c                |    3 
 vl.c                              |    2 
 59 files changed, 2247 insertions(+), 1425 deletions(-)

New commits:
commit 6034fe7bdb555c43022706e228cde8d52a8b341a
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Sun Jan 27 01:05:00 2013 +0100

    xilinx_ethlite: Avoid build warnings in debug code
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c
index 9463e92..11dfbc3 100644
--- a/hw/xilinx_ethlite.c
+++ b/hw/xilinx_ethlite.c
@@ -89,7 +89,7 @@ eth_read(void *opaque, hwaddr addr, unsigned int size)
         case R_RX_CTRL1:
         case R_RX_CTRL0:
             r = s->regs[addr];
-            D(qemu_log("%s %x=%x\n", __func__, addr * 4, r));
+            D(qemu_log("%s " TARGET_FMT_plx "=%x\n", __func__, addr * 4, r));
             break;
 
         default:
@@ -115,7 +115,8 @@ eth_write(void *opaque, hwaddr addr,
             if (addr == R_TX_CTRL1)
                 base = 0x800 / 4;
 
-            D(qemu_log("%s addr=%x val=%x\n", __func__, addr * 4, value));
+            D(qemu_log("%s addr=" TARGET_FMT_plx " val=%x\n",
+                       __func__, addr * 4, value));
             if ((value & (CTRL_P | CTRL_S)) == CTRL_S) {
                 qemu_send_packet(&s->nic->nc,
                                  (void *) &s->regs[base],
@@ -143,7 +144,8 @@ eth_write(void *opaque, hwaddr addr,
         case R_TX_LEN0:
         case R_TX_LEN1:
         case R_TX_GIE0:
-            D(qemu_log("%s addr=%x val=%x\n", __func__, addr * 4, value));
+            D(qemu_log("%s addr=" TARGET_FMT_plx " val=%x\n",
+                       __func__, addr * 4, value));
             s->regs[addr] = value;
             break;
 
@@ -185,7 +187,7 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
         return -1;
     }
 
-    D(qemu_log("%s %d rxbase=%x\n", __func__, size, rxbase));
+    D(qemu_log("%s %zd rxbase=%x\n", __func__, size, rxbase));
     memcpy(&s->regs[rxbase + R_RX_BUF0], buf, size);
 
     s->regs[rxbase + R_RX_CTRL0] |= CTRL_S;
commit a56d305a6d706cd75cfe0fa473f45772694f2a4a
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Fri Jan 25 17:58:38 2013 -0800

    m25p80.c: Return state to IDLE after COLLECTING
    
    Default to moving back to the IDLE state after the COLLECTING_DATA
    state. For a well behaved guest this patch has no consequence, but
    A bad guest could crash QEMU by using one of the erase commands
    followed by a longer than 5 byte argument (undefined behaviour).
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/hw/m25p80.c b/hw/m25p80.c
index d392656..788c196 100644
--- a/hw/m25p80.c
+++ b/hw/m25p80.c
@@ -358,6 +358,8 @@ static void complete_collecting_data(Flash *s)
     s->cur_addr |= s->data[1] << 8;
     s->cur_addr |= s->data[2];
 
+    s->state = STATE_IDLE;
+
     switch (s->cmd_in_progress) {
     case DPP:
     case QPP:
commit 2f991adb8e8cad3233ae653be12cfd72d44168ba
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Sat Jan 26 12:36:23 2013 -0800

    xilinx_ethlite: Flush queued packets on SW service
    
    Software services a received packet by clearing the CTRL_S bit in the RX_CTRLn
    register. If this bit is cleared, flush any packets queued for the device.
    
    Reported-by: John Williams <john.williams at xilinx.com>
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c
index 972b85e..9463e92 100644
--- a/hw/xilinx_ethlite.c
+++ b/hw/xilinx_ethlite.c
@@ -135,11 +135,14 @@ eth_write(void *opaque, hwaddr addr,
             break;
 
         /* Keep these native.  */
+        case R_RX_CTRL0:
+        case R_RX_CTRL1:
+            if (!(value & CTRL_S)) {
+                qemu_flush_queued_packets(&s->nic->nc);
+            }
         case R_TX_LEN0:
         case R_TX_LEN1:
         case R_TX_GIE0:
-        case R_RX_CTRL0:
-        case R_RX_CTRL1:
             D(qemu_log("%s addr=%x val=%x\n", __func__, addr * 4, value));
             s->regs[addr] = value;
             break;
commit 808fb9f277abda16601e9db938d29aeaf2548585
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Sat Jan 26 12:36:22 2013 -0800

    xilinx_ethlite: fix eth_can_rx() for ping-pong
    
    The eth_can_rx() function only checks the first buffers status ("ping"). The
    controller should be able to receive into "pong" when ping-pong is enabled.
    Checks the active buffer (either "ping" or "pong") when determining can_rx()
    rather than just testing "ping".
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c
index 2254851..972b85e 100644
--- a/hw/xilinx_ethlite.c
+++ b/hw/xilinx_ethlite.c
@@ -163,9 +163,9 @@ static const MemoryRegionOps eth_ops = {
 static int eth_can_rx(NetClientState *nc)
 {
     struct xlx_ethlite *s = DO_UPCAST(NICState, nc, nc)->opaque;
-    int r;
-    r = !(s->regs[R_RX_CTRL0] & CTRL_S);
-    return r;
+    unsigned int rxbase = s->rxbuf * (0x800 / 4);
+
+    return !(s->regs[rxbase + R_RX_CTRL0] & CTRL_S);
 }
 
 static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
commit 13144781d4e9e6100b398213f9000576a3dc88f9
Merge: c5cd02b f5fba9d
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Jan 26 14:18:28 2013 +0000

    Merge branch 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf
    
    * 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf:
      PPC: e500: Select MPIC v4.2 on ppce500 platform
      PPC: e500: fix mpic_iack address
      openpic: add basic support for MPIC v4.2
      openpic: fix timer address decoding
      openpic: fix remaining issues from idr-to-destmask conversion
      pseries: Adjust default VIO address allocations to play better with libvirt
      pseries: Improve handling of multiple PCI host bridges
      target-ppc: Give a meaningful error if too many threads are specified
      cuda: Move ADB bus into CUDA state
      adb: QOM'ify ADB devices
      adb: QOM'ify Apple Desktop Bus
      cuda: QOM'ify CUDA
      ide/macio: QOM'ify MacIO IDE
      mac_nvram: QOM'ify MacIO NVRAM
      mac_nvram: Mark as Big Endian
      mac_nvram: Clean up public API
      macio: Split MacIO in two
      macio: Delay qdev init until all fields are initialized
      macio: QOM'ify some more
      ppc: Move Mac machines to hw/ppc/

commit c5cd02ba16e784699d04456c8e406445db997121
Author: Andreas Färber <afaerber at suse.de>
Date:   Sat Jan 26 12:45:14 2013 +0100

    tests: Add gcov support for x86_64 qtest
    
    Since x86_64 is a superset of i386 and reuses all its test cases, adopt
    all the i386 gcov source files as well, substituting their paths
    appropriately.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tests/Makefile b/tests/Makefile
index a6341f2..442b286 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -57,6 +57,7 @@ gcov-files-i386-y += hw/hd-geometry.c
 check-qtest-i386-y += tests/rtc-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-sparc-y = tests/m48t59-test$(EXESUF)
 check-qtest-sparc64-y = tests/m48t59-test$(EXESUF)
 gcov-files-sparc-y += hw/m48t59.c
commit cba040c2b19f584bb33ae83af8517ecc9796e328
Author: Andreas Färber <afaerber at suse.de>
Date:   Sat Jan 26 12:45:13 2013 +0100

    tests: Add gcov support for sparc64 qtest
    
    m48t59-test is individually being executed for sparc and sparc64, so add
    the gcov source file for sparc64 as well.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tests/Makefile b/tests/Makefile
index a4cc554..a6341f2 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -60,6 +60,7 @@ gcov-files-i386-y += i386-softmmu/hw/mc146818rtc.c
 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-arm-y = tests/tmp105-test$(EXESUF)
 gcov-files-arm-y += hw/tmp105.c
 
commit 6a6944957801f5b981e09d6bff4f1bd5529f7019
Author: Andreas Färber <afaerber at suse.de>
Date:   Sat Jan 26 12:45:12 2013 +0100

    tests: Fix gcov typo for tmp105-test
    
    Commit 6e9989034b176a8e4cfdccd85892abfa73977ba7 introduced a new qtest
    test case but misspelled gcov, leading to no coverage analysis. Fix it.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tests/Makefile b/tests/Makefile
index d2e326f..a4cc554 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -61,7 +61,7 @@ check-qtest-sparc-y = tests/m48t59-test$(EXESUF)
 check-qtest-sparc64-y = tests/m48t59-test$(EXESUF)
 gcov-files-sparc-y += hw/m48t59.c
 check-qtest-arm-y = tests/tmp105-test$(EXESUF)
-qcov-files-arm-y += hw/tmp105.c
+gcov-files-arm-y += hw/tmp105.c
 
 GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h tests/test-qmp-commands.h
 
commit 8cb6bfb54e91b1a31a6ae704def595c2099efde1
Author: Michael Tokarev <mjt at tls.msk.ru>
Date:   Fri Jan 25 21:23:24 2013 +0400

    vmware_vga: fix out of bounds and invalid rects updating
    
    This is a follow up for several attempts to fix this issue.
    
    Previous incarnations:
    
    1. http://thread.gmane.org/gmane.linux.ubuntu.bugs.general/3156089
    https://bugs.launchpad.net/bugs/918791
    "qemu-kvm dies when using vmvga driver and unity in the guest" bug.
    Fix by Serge Hallyn:
     https://launchpadlibrarian.net/94916786/qemu-vmware.debdiff
    This fix is incomplete, since it does not check width and height
    for being negative.  Serge weren't sure if that's the right place
    to fix it, maybe the fix should be up the stack somewhere.
    
    2. http://thread.gmane.org/gmane.comp.emulators.qemu/166064
    by Marek Vasut: "vmware_vga: Redraw only visible area"
    
    This one adds the (incomplete) check to vmsvga_update_rect_delayed(),
    the routine just queues the rect updating but does no interesting
    stuff.  It is also incomplete in the same way as patch by Serge,
    but also does not touch width&height at all after adjusting x&y,
    which is wrong.
    
    As far as I can see, when processing guest requests, the device
    places them into a queue (vmsvga_update_rect_delayed()) and
    processes this queue in different place/time, namely, in
    vmsvga_update_rect().  Sometimes, vmsvga_update_rect() is
    called directly, without placing the request to the gueue.
    This is the place this patch changes, which is the last
    (deepest) in the stack.  I'm not sure if this is the right
    place still, since it is possible we have some queue optimization
    (or may have in the future) which will be upset by negative/wrong
    values here, so maybe we should check for validity of input
    right when receiving request from the guest (and maybe even
    use unsigned types there).  But I don't know the protocol
    and implementation enough to have a definitive answer.
    
    But since vmsvga_update_rect() has other sanity checks already,
    I'm adding the missing ones there as well.
    
    Cc'ing BALATON Zoltan and Andrzej Zaborowski who shows in `git blame'
    output and may know something in this area.
    
    If this patch is accepted, it should be applied to all active
    stable branches (at least since 1.1, maybe even before), with
    minor context change (ds_get_*(s->vga.ds) => s->*).  I'm not
    Cc'ing -stable yet, will do it explicitly once the patch is
    accepted.
    
    BTW, these checks use fprintf(stderr) -- it should be converted
    to something more appropriate, since stderr will most likely
    disappear somewhere.
    
    Cc: Marek Vasut <marex at denx.de>
    CC: Serge Hallyn <serge.hallyn at ubuntu.com>
    Cc: BALATON Zoltan <balaton at eik.bme.hu>
    Cc: Andrzej Zaborowski <balrogg at gmail.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>
    Reviewed-by: Marek Vasut <marex at denx.de>
    Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 62771bb..cd15ee4 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -296,6 +296,15 @@ static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
     uint8_t *src;
     uint8_t *dst;
 
+    if (x < 0) {
+        fprintf(stderr, "%s: update x was < 0 (%d)\n", __func__, x);
+        w += x;
+        x = 0;
+    }
+    if (w < 0) {
+        fprintf(stderr, "%s: update w was < 0 (%d)\n", __func__, w);
+        w = 0;
+    }
     if (x + w > ds_get_width(s->vga.ds)) {
         fprintf(stderr, "%s: update width too large x: %d, w: %d\n",
                 __func__, x, w);
@@ -303,6 +312,15 @@ static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
         w = ds_get_width(s->vga.ds) - x;
     }
 
+    if (y < 0) {
+        fprintf(stderr, "%s: update y was < 0 (%d)\n",  __func__, y);
+        h += y;
+        y = 0;
+    }
+    if (h < 0) {
+        fprintf(stderr, "%s: update h was < 0 (%d)\n",  __func__, h);
+        h = 0;
+    }
     if (y + h > ds_get_height(s->vga.ds)) {
         fprintf(stderr, "%s: update height too large y: %d, h: %d\n",
                 __func__, y, h);
commit 3f0f31a0f1c9a89314e9f9ed423371f4d925d5a6
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Jan 19 15:43:53 2013 +0000

    tests: add fuzzing to visitor tests
    
    Perform input tests on random data.
    
    Improvement to code coverage for qapi/string-input-visitor.c
    is about 3 percentage points.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c
index 899feda..f6b0093 100644
--- a/tests/test-string-input-visitor.c
+++ b/tests/test-string-input-visitor.c
@@ -165,6 +165,53 @@ static void test_visitor_in_enum(TestInputVisitorData *data,
     data->siv = NULL;
 }
 
+/* Try to crash the visitors */
+static void test_visitor_in_fuzz(TestInputVisitorData *data,
+                                 const void *unused)
+{
+    int64_t ires;
+    bool bres;
+    double nres;
+    char *sres;
+    EnumOne eres;
+    Error *errp = NULL;
+    Visitor *v;
+    unsigned int i;
+    char buf[10000];
+
+    for (i = 0; i < 100; i++) {
+        unsigned int j;
+
+        j = g_test_rand_int_range(0, sizeof(buf) - 1);
+
+        buf[j] = '\0';
+
+        if (j != 0) {
+            for (j--; j != 0; j--) {
+                buf[j - 1] = (char)g_test_rand_int_range(0, 256);
+            }
+        }
+
+        v = visitor_input_test_init(data, buf);
+        visit_type_int(v, &ires, NULL, &errp);
+
+        v = visitor_input_test_init(data, buf);
+        visit_type_bool(v, &bres, NULL, &errp);
+        visitor_input_teardown(data, NULL);
+
+        v = visitor_input_test_init(data, buf);
+        visit_type_number(v, &nres, NULL, &errp);
+
+        v = visitor_input_test_init(data, buf);
+        visit_type_str(v, &sres, NULL, &errp);
+        g_free(sres);
+
+        v = visitor_input_test_init(data, buf);
+        visit_type_EnumOne(v, &eres, NULL, &errp);
+        visitor_input_teardown(data, NULL);
+    }
+}
+
 static void input_visitor_test_add(const char *testpath,
                                    TestInputVisitorData *data,
                                    void (*test_func)(TestInputVisitorData *data, const void *user_data))
@@ -189,6 +236,8 @@ int main(int argc, char **argv)
                             &in_visitor_data, test_visitor_in_string);
     input_visitor_test_add("/string-visitor/input/enum",
                             &in_visitor_data, test_visitor_in_enum);
+    input_visitor_test_add("/string-visitor/input/fuzz",
+                            &in_visitor_data, test_visitor_in_fuzz);
 
     g_test_run();
 
commit 0c3c89d649d029b29bf245f739c82339fcf2e699
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Jan 15 09:49:37 2013 +0100

    build: remove *.lo, *.a, *.la files from all subdirectories on make clean
    
    .lo files in stubs/, util/ and libcacard/ were not cleaned.
    Fix this.
    
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Reported-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Michal Privoznik <mprivozn at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/Makefile b/Makefile
index bd885ca..0d9099a 100644
--- a/Makefile
+++ b/Makefile
@@ -213,9 +213,9 @@ clean:
 # avoid old build problems by removing potentially incorrect old files
 	rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
 	rm -f qemu-options.def
-	find . -name '*.[od]' -type f -exec rm -f {} +
-	rm -f *.a *.lo $(TOOLS) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~
-	rm -f *.la
+	find . -name '*.[oda]' -type f -exec rm -f {} +
+	find . -name '*.l[oa]' -type f -exec rm -f {} +
+	rm -f $(TOOLS) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~
 	rm -Rf .libs
 	rm -f qemu-img-cmds.h
 	@# May not be present in GENERATED_HEADERS
commit 98ed805c388baaf4ce7d9acbbbc04bbf185f30fc
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Jan 24 19:02:28 2013 +0000

    hw/arm_boot: Align device tree to 4KB boundary, not page
    
    Align the device tree blob to a 4KB boundary, not to QEMU's
    idea of a page boundary -- the latter is the smallest possible
    page size for the architecture, which on ARM is 1KB.
    The documentation for Linux does not impose separation
    or alignment requirements on the device tree blob, but
    in practice some kernels will happily trash the entire
    page the initrd ends in after they have finished uncompressing
    the initrd. So 4KB-align the DTB to ensure it does not get
    trampled by these kernels.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/arm_boot.c b/hw/arm_boot.c
index 115f583..4065424 100644
--- a/hw/arm_boot.c
+++ b/hw/arm_boot.c
@@ -441,9 +441,12 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
          * we point to the kernel args.
          */
         if (info->dtb_filename) {
-            /* Place the DTB after the initrd in memory */
-            hwaddr dtb_start = TARGET_PAGE_ALIGN(info->initrd_start +
-                                                 initrd_size);
+            /* Place the DTB after the initrd in memory. Note that some
+             * kernels will trash anything in the 4K page the initrd
+             * ends in, so make sure the DTB isn't caught up in that.
+             */
+            hwaddr dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size,
+                                             4096);
             if (load_dtb(dtb_start, info)) {
                 exit(1);
             }
commit 390999910bf1b1be59e04a0314867f4dea7a28f3
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Jan 24 16:14:39 2013 +0000

    qemu-char: Avoid unused variable warning in some configs
    
    Avoid unused variable warnings:
    qemu-char.c: In function 'qmp_chardev_open_port':
    qemu-char.c:3132: warning: unused variable 'fd'
    qemu-char.c:3132: warning: unused variable 'flags'
    
    in configurations with neither HAVE_CHARDEV_TTY nor
    HAVE_CHARDEV_PARPORT set.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/qemu-char.c b/qemu-char.c
index 9ba0573..da1db1d 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3129,11 +3129,11 @@ static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp)
 
 static CharDriverState *qmp_chardev_open_port(ChardevPort *port, Error **errp)
 {
-    int flags, fd;
-
     switch (port->type) {
 #ifdef HAVE_CHARDEV_TTY
     case CHARDEV_PORT_KIND_SERIAL:
+    {
+        int flags, fd;
         flags = O_RDWR;
         fd = qmp_chardev_open_file_source(port->device, flags, errp);
         if (error_is_set(errp)) {
@@ -3141,15 +3141,19 @@ static CharDriverState *qmp_chardev_open_port(ChardevPort *port, Error **errp)
         }
         socket_set_nonblock(fd);
         return qemu_chr_open_tty_fd(fd);
+    }
 #endif
 #ifdef HAVE_CHARDEV_PARPORT
     case CHARDEV_PORT_KIND_PARALLEL:
+    {
+        int flags, fd;
         flags = O_RDWR;
         fd = qmp_chardev_open_file_source(port->device, flags, errp);
         if (error_is_set(errp)) {
             return NULL;
         }
         return qemu_chr_open_pp_fd(fd);
+    }
 #endif
     default:
         error_setg(errp, "unknown chardev port (%d)", port->type);
commit 23bf49b5eca716aaad073f2b47613434e1515cb5
Author: Andreas Färber <afaerber at suse.de>
Date:   Thu Jan 24 16:47:55 2013 +0100

    make_device_config.sh: Fix target path in generated dependency file
    
    config-devices.mak.d is included from Makefile.target, i.e. from inside
    the *-softmmu/ directory. It included the directory path, so never
    applied to the actual ./config-devices.mak. Symptoms were spurious
    build failures due to missing dependency on default-configs/pci.mak.
    
    Fix this by using `basename` to strip the directory path.
    
    Reported-by: Gerhard Wiesinger <lists at wiesinger.com>
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/scripts/make_device_config.sh b/scripts/make_device_config.sh
index 5d14885..0778fe2 100644
--- a/scripts/make_device_config.sh
+++ b/scripts/make_device_config.sh
@@ -25,4 +25,4 @@ done
 process_includes $src > $dest
 
 cat $src $all_includes | grep -v '^include' > $dest
-echo "$1: $all_includes" > $dep
+echo "`basename $1`: $all_includes" > $dep
commit 9f8863ebd7f584762a906881a62a04ac05ce4898
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Jan 23 18:25:09 2013 +0100

    fw_cfg: Drop a few superfluous initializers
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index b7da5c7..bdcd836 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -60,8 +60,8 @@ static char *read_splashfile(char *filename, size_t *file_sizep,
     GError *err = NULL;
     gboolean res;
     gchar *content;
-    int file_type = -1;
-    unsigned int filehead = 0;
+    int file_type;
+    unsigned int filehead;
     int bmp_bpp;
 
     res = g_file_get_contents(filename, &content, file_sizep, &err);
@@ -113,7 +113,7 @@ static void fw_cfg_bootsplash(FWCfgState *s)
     char *p;
     char *filename, *file_data;
     size_t file_size;
-    int file_type = -1;
+    int file_type;
     const char *temp;
 
     /* get user configuration */
commit d09acb9b5ef0bb4fa94d3d459919a6ebaf8804bc
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Jan 23 18:25:08 2013 +0100

    fw_cfg: Splash image loader can overrun a stack variable, fix
    
    read_splashfile() passes the address of an int variable as size_t *
    parameter to g_file_get_contents(), with a cast to gag the compiler.
    
    No problem on machines where sizeof(size_t) == sizeof(int).
    
    Happens to work on my x86_64 box (64 bit little endian): the least
    significant 32 bits of the file size end up in the right place
    (caller's variable file_size), and the most significant 32 bits
    clobber a place that gets assigned to before its next use (caller's
    variable file_type).
    
    I'd expect it to break on a 64 bit big-endian box.
    
    Fix up the variable types and drop the problematic cast.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index e4dc7c3..b7da5c7 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -54,7 +54,8 @@ struct FWCfgState {
 #define JPG_FILE 0
 #define BMP_FILE 1
 
-static char *read_splashfile(char *filename, int *file_sizep, int *file_typep)
+static char *read_splashfile(char *filename, size_t *file_sizep,
+                             int *file_typep)
 {
     GError *err = NULL;
     gboolean res;
@@ -63,7 +64,7 @@ static char *read_splashfile(char *filename, int *file_sizep, int *file_typep)
     unsigned int filehead = 0;
     int bmp_bpp;
 
-    res = g_file_get_contents(filename, &content, (gsize *)file_sizep, &err);
+    res = g_file_get_contents(filename, &content, file_sizep, &err);
     if (res == FALSE) {
         error_report("failed to read splash file '%s'", filename);
         g_error_free(err);
@@ -111,7 +112,7 @@ static void fw_cfg_bootsplash(FWCfgState *s)
     const char *boot_splash_filename = NULL;
     char *p;
     char *filename, *file_data;
-    int file_size;
+    size_t file_size;
     int file_type = -1;
     const char *temp;
 
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 337ce7d..1d9599e 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -122,7 +122,7 @@ extern int semihosting_enabled;
 extern int old_param;
 extern int boot_menu;
 extern uint8_t *boot_splash_filedata;
-extern int boot_splash_filedata_size;
+extern size_t boot_splash_filedata_size;
 extern uint8_t qemu_extra_params_fw[2];
 extern QEMUClock *rtc_clock;
 
diff --git a/vl.c b/vl.c
index 4ee1302..7aab73b 100644
--- a/vl.c
+++ b/vl.c
@@ -231,7 +231,7 @@ unsigned int nb_prom_envs = 0;
 const char *prom_envs[MAX_PROM_ENVS];
 int boot_menu;
 uint8_t *boot_splash_filedata;
-int boot_splash_filedata_size;
+size_t boot_splash_filedata_size;
 uint8_t qemu_extra_params_fw[2];
 
 typedef struct FWBootEntry FWBootEntry;
commit a6e7c18476f5383720b3f57ef4f467b2e7c2565e
Author: Richard Sandiford <rdsandiford at googlemail.com>
Date:   Tue Jan 22 17:03:05 2013 +0000

    softfloat: Handle float_muladd_negate_c when product is zero
    
    Honour float_muladd_negate_c in the case where the product is zero and
    c is nonzero.  Previously we would fail to negate c.
    
    Seen in (and tested against) the gfortran testsuite on MIPS.
    
    Signed-off-by: Richard Sandiford <rdsandiford at googlemail.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index ac3d150..83ccc4b 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2234,7 +2234,7 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags STATUS_PARAM)
             }
         }
         /* Zero plus something non-zero : just return the something */
-        return make_float32(float32_val(c) ^ (signflip << 31));
+        return packFloat32(cSign ^ signflip, cExp, cSig);
     }
 
     if (aExp == 0) {
@@ -3787,7 +3787,7 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM)
             }
         }
         /* Zero plus something non-zero : just return the something */
-        return make_float64(float64_val(c) ^ ((uint64_t)signflip << 63));
+        return packFloat64(cSign ^ signflip, cExp, cSig);
     }
 
     if (aExp == 0) {
commit de16017dc8f2c33c73bd3faebf3c626c400af5e4
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Jan 21 12:50:56 2013 +0000

    hw/pxa2xx_timer: Explicitly mark fallthroughs
    
    Explicitly mark the fallthroughs as intentional in the code
    pattern where we gradually increment an index before falling
    into the code to read/write that array entry:
        case THINGY_3: idx++;
        case THINGY_2: idx++;
        case THINGY_1: idx++;
        case THINGY_0: return s->thingy[idx];
    
    This makes static analysers happy.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/pxa2xx_timer.c b/hw/pxa2xx_timer.c
index 32c1872..5c9d2e8 100644
--- a/hw/pxa2xx_timer.c
+++ b/hw/pxa2xx_timer.c
@@ -157,17 +157,27 @@ static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset,
 
     switch (offset) {
     case OSMR3:  tm ++;
+        /* fall through */
     case OSMR2:  tm ++;
+        /* fall through */
     case OSMR1:  tm ++;
+        /* fall through */
     case OSMR0:
         return s->timer[tm].value;
     case OSMR11: tm ++;
+        /* fall through */
     case OSMR10: tm ++;
+        /* fall through */
     case OSMR9:  tm ++;
+        /* fall through */
     case OSMR8:  tm ++;
+        /* fall through */
     case OSMR7:  tm ++;
+        /* fall through */
     case OSMR6:  tm ++;
+        /* fall through */
     case OSMR5:  tm ++;
+        /* fall through */
     case OSMR4:
         if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
@@ -176,12 +186,19 @@ static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset,
         return s->clock + muldiv64(qemu_get_clock_ns(vm_clock) -
                         s->lastload, s->freq, get_ticks_per_sec());
     case OSCR11: tm ++;
+        /* fall through */
     case OSCR10: tm ++;
+        /* fall through */
     case OSCR9:  tm ++;
+        /* fall through */
     case OSCR8:  tm ++;
+        /* fall through */
     case OSCR7:  tm ++;
+        /* fall through */
     case OSCR6:  tm ++;
+        /* fall through */
     case OSCR5:  tm ++;
+        /* fall through */
     case OSCR4:
         if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
@@ -207,12 +224,19 @@ static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset,
     case OWER:
         return s->reset3;
     case OMCR11: tm ++;
+        /* fall through */
     case OMCR10: tm ++;
+        /* fall through */
     case OMCR9:  tm ++;
+        /* fall through */
     case OMCR8:  tm ++;
+        /* fall through */
     case OMCR7:  tm ++;
+        /* fall through */
     case OMCR6:  tm ++;
+        /* fall through */
     case OMCR5:  tm ++;
+        /* fall through */
     case OMCR4:
         if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
@@ -235,19 +259,29 @@ static void pxa2xx_timer_write(void *opaque, hwaddr offset,
 
     switch (offset) {
     case OSMR3:  tm ++;
+        /* fall through */
     case OSMR2:  tm ++;
+        /* fall through */
     case OSMR1:  tm ++;
+        /* fall through */
     case OSMR0:
         s->timer[tm].value = value;
         pxa2xx_timer_update(s, qemu_get_clock_ns(vm_clock));
         break;
     case OSMR11: tm ++;
+        /* fall through */
     case OSMR10: tm ++;
+        /* fall through */
     case OSMR9:  tm ++;
+        /* fall through */
     case OSMR8:  tm ++;
+        /* fall through */
     case OSMR7:  tm ++;
+        /* fall through */
     case OSMR6:  tm ++;
+        /* fall through */
     case OSMR5:  tm ++;
+        /* fall through */
     case OSMR4:
         if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
@@ -261,12 +295,19 @@ static void pxa2xx_timer_write(void *opaque, hwaddr offset,
         pxa2xx_timer_update(s, s->lastload);
         break;
     case OSCR11: tm ++;
+        /* fall through */
     case OSCR10: tm ++;
+        /* fall through */
     case OSCR9:  tm ++;
+        /* fall through */
     case OSCR8:  tm ++;
+        /* fall through */
     case OSCR7:  tm ++;
+        /* fall through */
     case OSCR6:  tm ++;
+        /* fall through */
     case OSCR5:  tm ++;
+        /* fall through */
     case OSCR4:
         if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
@@ -291,8 +332,11 @@ static void pxa2xx_timer_write(void *opaque, hwaddr offset,
         s->reset3 = value;
         break;
     case OMCR7:  tm ++;
+        /* fall through */
     case OMCR6:  tm ++;
+        /* fall through */
     case OMCR5:  tm ++;
+        /* fall through */
     case OMCR4:
         if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
@@ -306,8 +350,11 @@ static void pxa2xx_timer_write(void *opaque, hwaddr offset,
         }
         break;
     case OMCR11: tm ++;
+        /* fall through */
     case OMCR10: tm ++;
+        /* fall through */
     case OMCR9:  tm ++;
+        /* fall through */
     case OMCR8:  tm += 4;
         if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
commit 89556d1725d7c10a54ec66087e940727873f38a3
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Jan 21 12:50:55 2013 +0000

    hw/smc91c111: Add explicit 'return' rather than relying on fallthrough
    
    Add an explicit 'return' statement to a case in smc91c111_readb
    rather than relying on fallthrough to the following case's
    return statement, for code clarity and to placate static analysers.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index 36cb4ed..fe2389b 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -442,6 +442,7 @@ static void smc91c111_writeb(void *opaque, hwaddr offset,
             return;
         case 12: /* Early receive.  */
             s->ercv = value & 0x1f;
+            return;
         case 13:
             /* Ignore.  */
             return;
commit 3095485029ddbd061aa4f8e26c0437f200975d18
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Jan 21 12:50:54 2013 +0000

    hw/pflash_cfi02.c: Mark deliberate fallthrough
    
    Mark the deliberate fallthrough where we treat the case of
    an attempt to read flash when it is an unknown command
    state as if it were a normal read.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c
index b4220c1..44bd465 100644
--- a/hw/pflash_cfi02.c
+++ b/hw/pflash_cfi02.c
@@ -157,6 +157,7 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
         DPRINTF("%s: unknown command state: %x\n", __func__, pfl->cmd);
         pfl->wcycle = 0;
         pfl->cmd = 0;
+        /* fall through to the read code */
     case 0x80:
         /* We accept reads during second unlock sequence... */
     case 0x00:
commit be688dfb8ddf7841fb277800977a0a878b68ae42
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Jan 21 12:50:53 2013 +0000

    hw/omap_dma, hw/omap_spi: Explicitly mark fallthroughs
    
    Explicitly mark the fallthroughs as intentional in the code
    pattern where we gradually increment an index before falling
    into the code to read/write that array entry:
      case THINGY_3: idx++;
      case THINGY_2: idx++;
      case THINGY_1: idx++;
      case THINGY_0: return s->thingy[idx];
    
    This makes static analysers happy.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/omap_dma.c b/hw/omap_dma.c
index aec5874..0c878b6 100644
--- a/hw/omap_dma.c
+++ b/hw/omap_dma.c
@@ -1709,19 +1709,25 @@ static uint64_t omap_dma4_read(void *opaque, hwaddr addr,
 
     case 0x14:	/* DMA4_IRQSTATUS_L3 */
         irqn ++;
+        /* fall through */
     case 0x10:	/* DMA4_IRQSTATUS_L2 */
         irqn ++;
+        /* fall through */
     case 0x0c:	/* DMA4_IRQSTATUS_L1 */
         irqn ++;
+        /* fall through */
     case 0x08:	/* DMA4_IRQSTATUS_L0 */
         return s->irqstat[irqn];
 
     case 0x24:	/* DMA4_IRQENABLE_L3 */
         irqn ++;
+        /* fall through */
     case 0x20:	/* DMA4_IRQENABLE_L2 */
         irqn ++;
+        /* fall through */
     case 0x1c:	/* DMA4_IRQENABLE_L1 */
         irqn ++;
+        /* fall through */
     case 0x18:	/* DMA4_IRQENABLE_L0 */
         return s->irqen[irqn];
 
@@ -1856,10 +1862,13 @@ static void omap_dma4_write(void *opaque, hwaddr addr,
     switch (addr) {
     case 0x14:	/* DMA4_IRQSTATUS_L3 */
         irqn ++;
+        /* fall through */
     case 0x10:	/* DMA4_IRQSTATUS_L2 */
         irqn ++;
+        /* fall through */
     case 0x0c:	/* DMA4_IRQSTATUS_L1 */
         irqn ++;
+        /* fall through */
     case 0x08:	/* DMA4_IRQSTATUS_L0 */
         s->irqstat[irqn] &= ~value;
         if (!s->irqstat[irqn])
@@ -1868,10 +1877,13 @@ static void omap_dma4_write(void *opaque, hwaddr addr,
 
     case 0x24:	/* DMA4_IRQENABLE_L3 */
         irqn ++;
+        /* fall through */
     case 0x20:	/* DMA4_IRQENABLE_L2 */
         irqn ++;
+        /* fall through */
     case 0x1c:	/* DMA4_IRQENABLE_L1 */
         irqn ++;
+        /* fall through */
     case 0x18:	/* DMA4_IRQENABLE_L0 */
         s->irqen[irqn] = value;
         return;
diff --git a/hw/omap_spi.c b/hw/omap_spi.c
index 42d5149..8ff01ed 100644
--- a/hw/omap_spi.c
+++ b/hw/omap_spi.c
@@ -167,32 +167,47 @@ static uint64_t omap_mcspi_read(void *opaque, hwaddr addr,
         return s->control;
 
     case 0x68: ch ++;
+        /* fall through */
     case 0x54: ch ++;
+        /* fall through */
     case 0x40: ch ++;
+        /* fall through */
     case 0x2c:	/* MCSPI_CHCONF */
         return s->ch[ch].config;
 
     case 0x6c: ch ++;
+        /* fall through */
     case 0x58: ch ++;
+        /* fall through */
     case 0x44: ch ++;
+        /* fall through */
     case 0x30:	/* MCSPI_CHSTAT */
         return s->ch[ch].status;
 
     case 0x70: ch ++;
+        /* fall through */
     case 0x5c: ch ++;
+        /* fall through */
     case 0x48: ch ++;
+        /* fall through */
     case 0x34:	/* MCSPI_CHCTRL */
         return s->ch[ch].control;
 
     case 0x74: ch ++;
+        /* fall through */
     case 0x60: ch ++;
+        /* fall through */
     case 0x4c: ch ++;
+        /* fall through */
     case 0x38:	/* MCSPI_TX */
         return s->ch[ch].tx;
 
     case 0x78: ch ++;
+        /* fall through */
     case 0x64: ch ++;
+        /* fall through */
     case 0x50: ch ++;
+        /* fall through */
     case 0x3c:	/* MCSPI_RX */
         s->ch[ch].status &= ~(1 << 0);			/* RXS */
         ret = s->ch[ch].rx;
@@ -269,8 +284,11 @@ static void omap_mcspi_write(void *opaque, hwaddr addr,
         break;
 
     case 0x68: ch ++;
+        /* fall through */
     case 0x54: ch ++;
+        /* fall through */
     case 0x40: ch ++;
+        /* fall through */
     case 0x2c:	/* MCSPI_CHCONF */
         if ((value ^ s->ch[ch].config) & (3 << 14))	/* DMAR | DMAW */
             omap_mcspi_dmarequest_update(s->ch + ch);
@@ -283,8 +301,11 @@ static void omap_mcspi_write(void *opaque, hwaddr addr,
         break;
 
     case 0x70: ch ++;
+        /* fall through */
     case 0x5c: ch ++;
+        /* fall through */
     case 0x48: ch ++;
+        /* fall through */
     case 0x34:	/* MCSPI_CHCTRL */
         if (value & ~s->ch[ch].control & 1) {		/* EN */
             s->ch[ch].control |= 1;
@@ -294,8 +315,11 @@ static void omap_mcspi_write(void *opaque, hwaddr addr,
         break;
 
     case 0x74: ch ++;
+        /* fall through */
     case 0x60: ch ++;
+        /* fall through */
     case 0x4c: ch ++;
+        /* fall through */
     case 0x38:	/* MCSPI_TX */
         s->ch[ch].tx = value;
         s->ch[ch].status &= ~(1 << 1);			/* TXS */
commit 139bd956eaf1675209009b22764a46bd220e287c
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Jan 21 12:50:52 2013 +0000

    hw/omap1.c: Add fallthrough markers and breaks
    
    Explicitly mark cases where we are deliberately falling
    through to the following code. In one case we insert a
    'break' instead of falling through to a 'break', as this
    seems slightly clearer.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/omap1.c b/hw/omap1.c
index 1870f4d..623b101 100644
--- a/hw/omap1.c
+++ b/hw/omap1.c
@@ -529,6 +529,7 @@ static uint64_t omap_ulpd_pm_read(void *opaque, hwaddr addr,
     case 0x28:	/* Reserved */
     case 0x2c:	/* Reserved */
         OMAP_BAD_REG(addr);
+        /* fall through */
     case 0x00:	/* COUNTER_32_LSB */
     case 0x04:	/* COUNTER_32_MSB */
     case 0x08:	/* COUNTER_HIGH_FREQ_LSB */
@@ -633,6 +634,7 @@ static void omap_ulpd_pm_write(void *opaque, hwaddr addr,
     case 0x28:	/* Reserved */
     case 0x2c:	/* Reserved */
         OMAP_BAD_REG(addr);
+        /* fall through */
     case 0x24:	/* SETUP_ANALOG_CELL3_ULPD1 */
     case 0x38:	/* COUNTER_32_FIQ */
     case 0x48:	/* LOCL_TIME */
@@ -1089,6 +1091,7 @@ static void omap_mpui_write(void *opaque, hwaddr addr,
     /* Not in OMAP310 */
     case 0x14:	/* DSP_STATUS */
         OMAP_RO_REG(addr);
+        break;
     case 0x18:	/* DSP_BOOT_CONFIG */
     case 0x1c:	/* DSP_MPUI_CONFIG */
         break;
commit bf4229d3cb09be2efc0add569feba33834fc5d93
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Jan 21 12:50:51 2013 +0000

    hw/arm_sysctl.c: Add missing 'break' statements
    
    Add some break statements that were accidentally omitted
    from some cases of arm_sysctl_write(). The omission was
    harmless because in both cases the following case did
    an immediate break, but adding the breaks explicitly
    placates static analysers and avoids weird behaviour if
    the following register is ever implemented as something
    other than a no-op.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index 755a5df..da36f8a 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -199,6 +199,7 @@ static void arm_sysctl_write(void *opaque, hwaddr offset,
     switch (offset) {
     case 0x08: /* LED */
         s->leds = val;
+        break;
     case 0x0c: /* OSC0 */
     case 0x10: /* OSC1 */
     case 0x14: /* OSC2 */
@@ -295,6 +296,7 @@ static void arm_sysctl_write(void *opaque, hwaddr offset,
             /* On VExpress this register is unimplemented and will RAZ/WI */
             break;
         }
+        break;
     case 0x54: /* CLCDSER */
     case 0x64: /* DMAPSR0 */
     case 0x68: /* DMAPSR1 */
commit b4451996e712653f9ef4d53d975a158572b8574d
Author: Michael Tokarev <mjt at tls.msk.ru>
Date:   Sat Jan 19 18:58:09 2013 +0400

    link seccomp only with softmmu targets
    
    Now, if seccomp is detected, it is linked into every executable,
    but is used only by softmmu targets (from vl.c).  So link it
    only where it is actually needed.
    
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/configure b/configure
index c6172ef..b7635e4 100755
--- a/configure
+++ b/configure
@@ -1434,7 +1434,7 @@ fi
 
 if test "$seccomp" != "no" ; then
     if $pkg_config --atleast-version=1.0.0 libseccomp --modversion >/dev/null 2>&1; then
-        LIBS=`$pkg_config --libs libseccomp`
+        libs_softmmu="$libs_softmmu `$pkg_config --libs libseccomp`"
 	seccomp="yes"
     else
 	if test "$seccomp" = "yes"; then
commit 0360ccffbe41bd732b42a90cd04de63335933bea
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Jan 19 09:49:09 2013 +0000

    bsd-user: avoid conflict with qemu_vmalloc
    
    Rename qemu_vmalloc() to bsd_vmalloc(), adjust the only user.
    
    Remove #ifdeffery in oslib-posix.c.
    
    Tested-by: Andreas Färber <andreas.faerber at web.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index 5d6cffc..aae8ea1 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -74,7 +74,7 @@ void mmap_unlock(void)
 }
 #endif
 
-void *qemu_vmalloc(size_t size)
+static void *bsd_vmalloc(size_t size)
 {
     void *p;
     mmap_lock();
@@ -98,7 +98,7 @@ void *g_malloc(size_t size)
 {
     char * p;
     size += 16;
-    p = qemu_vmalloc(size);
+    p = bsd_vmalloc(size);
     *(size_t *)p = size;
     return p + 16;
 }
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 4f5ec67..b4152fb 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -105,8 +105,6 @@ void *qemu_memalign(size_t alignment, size_t size)
     return ptr;
 }
 
-/* conflicts with qemu_vmalloc in bsd-user/mmap.c */
-#if !defined(CONFIG_BSD_USER)
 /* alloc shared memory pages */
 void *qemu_vmalloc(size_t size)
 {
@@ -129,7 +127,6 @@ void *qemu_vmalloc(size_t size)
     trace_qemu_vmalloc(size, ptr);
     return ptr;
 }
-#endif
 
 void qemu_vfree(void *ptr)
 {
commit 82cb6b041c307bd96c067147af69cd98be91a682
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Sat Jan 19 11:06:48 2013 +0100

    build: remove extra-obj-y
    
    extra-obj-y is somewhat complicated to understand.  Replace it with a
    special CONFIG_ALL symbol that is defined only at toplevel.
    This limits the case of directories defining more than one
    *-obj-y target.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/Makefile b/Makefile
index 55b5d36..bd885ca 100644
--- a/Makefile
+++ b/Makefile
@@ -105,6 +105,7 @@ defconfig:
 -include config-all-disas.mak
 CONFIG_SOFTMMU := $(if $(filter %-softmmu,$(TARGET_DIRS)),y)
 CONFIG_USER_ONLY := $(if $(filter %-user,$(TARGET_DIRS)),y)
+CONFIG_ALL=y
 
 ifneq ($(wildcard config-host.mak),)
 include $(SRC_PATH)/Makefile.objs
@@ -135,7 +136,7 @@ pixman/Makefile: $(SRC_PATH)/pixman/configure
 $(SRC_PATH)/pixman/configure:
 	(cd $(SRC_PATH)/pixman; autoreconf -v --install)
 
-$(SUBDIR_RULES): libqemuutil.a libqemustub.a $(common-obj-y) $(extra-obj-y)
+$(SUBDIR_RULES): libqemuutil.a libqemustub.a $(common-obj-y)
 
 ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
 romsubdir-%:
diff --git a/Makefile.objs b/Makefile.objs
index 63ddaaf..68eb0ce 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -55,7 +55,6 @@ common-obj-$(CONFIG_WIN32) += os-win32.o
 common-obj-$(CONFIG_POSIX) += os-posix.o
 
 common-obj-$(CONFIG_LINUX) += fsdev/
-extra-obj-$(CONFIG_LINUX) += fsdev/
 
 common-obj-y += migration.o migration-tcp.o
 common-obj-y += qemu-char.o #aio.o
@@ -68,7 +67,6 @@ common-obj-$(CONFIG_SPICE) += spice-qemu-char.o
 
 common-obj-y += audio/
 common-obj-y += hw/
-extra-obj-y += hw/
 
 common-obj-y += ui/
 common-obj-y += bt-host.o bt-vhci.o
@@ -118,6 +116,5 @@ nested-vars += \
 	util-obj-y \
 	qga-obj-y \
 	block-obj-y \
-	common-obj-y \
-	extra-obj-y
+	common-obj-y
 dummy := $(call unnest-vars)
diff --git a/fsdev/Makefile.objs b/fsdev/Makefile.objs
index ee16ca6..206289c 100644
--- a/fsdev/Makefile.objs
+++ b/fsdev/Makefile.objs
@@ -1,10 +1,10 @@
 ifeq ($(CONFIG_REALLY_VIRTFS),y)
 common-obj-y = qemu-fsdev.o virtio-9p-marshal.o
-
-# Toplevel always builds this; targets without virtio will put it in
-# common-obj-y
-extra-obj-y = qemu-fsdev-dummy.o
 else
 common-obj-y = qemu-fsdev-dummy.o
 endif
 common-obj-y += qemu-fsdev-opts.o
+
+# Toplevel always builds this; targets without virtio will put it in
+# common-obj-y
+common-obj-$(CONFIG_ALL) += qemu-fsdev-dummy.o
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 260885d..447e32a 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -44,8 +44,6 @@ common-obj-$(CONFIG_I8259) += i8259_common.o i8259.o
 common-obj-y += fifo.o
 common-obj-y += pam.o
 
-extra-obj-y += pci/
-
 # PPC devices
 common-obj-$(CONFIG_PREP_PCI) += prep_pci.o
 common-obj-$(CONFIG_I82378) += i82378.o
diff --git a/hw/pci/Makefile.objs b/hw/pci/Makefile.objs
index fe965fe..1cd6cde 100644
--- a/hw/pci/Makefile.objs
+++ b/hw/pci/Makefile.objs
@@ -6,4 +6,4 @@ common-obj-$(CONFIG_PCI) += pci_host.o pcie_host.o
 common-obj-$(CONFIG_PCI) += pcie.o pcie_aer.o pcie_port.o
 common-obj-$(CONFIG_NO_PCI) += pci-stub.o
 
-extra-obj-y += pci-stub.o
+common-obj-$(CONFIG_ALL) += pci-stub.o
commit 000823449ca07e50086413338f907d7a817db2ce
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Sat Jan 19 11:06:47 2013 +0100

    build: remove universal-obj-y
    
    All of universal-obj-y, user-obj-y (right now unused) and common-obj-y can
    be unified into common-obj-y if we take care of defining CONFIG_SOFTMMU
    and CONFIG_USER_ONLY in the toplevel makefile.  This is similar to how
    we define symbols for hardware components.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/Makefile b/Makefile
index 73adf42..55b5d36 100644
--- a/Makefile
+++ b/Makefile
@@ -103,6 +103,8 @@ defconfig:
 
 -include config-all-devices.mak
 -include config-all-disas.mak
+CONFIG_SOFTMMU := $(if $(filter %-softmmu,$(TARGET_DIRS)),y)
+CONFIG_USER_ONLY := $(if $(filter %-user,$(TARGET_DIRS)),y)
 
 ifneq ($(wildcard config-host.mak),)
 include $(SRC_PATH)/Makefile.objs
@@ -133,11 +135,7 @@ pixman/Makefile: $(SRC_PATH)/pixman/configure
 $(SRC_PATH)/pixman/configure:
 	(cd $(SRC_PATH)/pixman; autoreconf -v --install)
 
-$(SUBDIR_RULES): libqemuutil.a libqemustub.a
-
-$(filter %-softmmu,$(SUBDIR_RULES)): $(universal-obj-y) $(common-obj-y) $(extra-obj-y)
-
-$(filter %-user,$(SUBDIR_RULES)): $(universal-obj-y) $(user-obj-y)
+$(SUBDIR_RULES): libqemuutil.a libqemustub.a $(common-obj-y) $(extra-obj-y)
 
 ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
 romsubdir-%:
diff --git a/Makefile.objs b/Makefile.objs
index 3bdb248..63ddaaf 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -47,6 +47,7 @@ libcacard-y += libcacard/card_7816.o
 # suppress *all* target specific code in case of system emulation, i.e. a
 # single QEMU executable should support all CPUs and machines.
 
+ifeq ($(CONFIG_SOFTMMU),y)
 common-obj-y = $(block-obj-y) blockdev.o blockdev-nbd.o block/
 common-obj-y += net/
 common-obj-y += readline.o
@@ -89,15 +90,15 @@ common-obj-$(CONFIG_SMARTCARD_NSS) += $(libcacard-y)
 
 common-obj-y += qmp-marshal.o qapi-visit.o qapi-types.o
 common-obj-y += qmp.o hmp.o
+endif
 
 #######################################################################
 # Target-independent parts used in system and user emulation
-universal-obj-y =
-universal-obj-y += qemu-log.o
-universal-obj-y += tcg-runtime.o
-universal-obj-y += hw/
-universal-obj-y += qom/
-universal-obj-y += disas/
+common-obj-y += qemu-log.o
+common-obj-y += tcg-runtime.o
+common-obj-y += hw/
+common-obj-y += qom/
+common-obj-y += disas/
 
 ######################################################################
 # guest agent
@@ -118,6 +119,5 @@ nested-vars += \
 	qga-obj-y \
 	block-obj-y \
 	common-obj-y \
-	universal-obj-y \
 	extra-obj-y
 dummy := $(call unnest-vars)
diff --git a/Makefile.target b/Makefile.target
index eb84b1f..760da1e 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -145,8 +145,7 @@ nested-vars += obj-y
 include $(SRC_PATH)/Makefile.objs
 
 all-obj-y = $(obj-y)
-all-obj-y += $(addprefix ../, $(universal-obj-y))
-all-obj-$(CONFIG_SOFTMMU) += $(addprefix ../, $(common-obj-y))
+all-obj-y += $(addprefix ../, $(common-obj-y))
 
 ifdef QEMU_PROGW
 # The linker builds a windows executable. Make also a console executable.
diff --git a/disas/Makefile.objs b/disas/Makefile.objs
index 3f5c5b9..ed75f9a 100644
--- a/disas/Makefile.objs
+++ b/disas/Makefile.objs
@@ -1,18 +1,18 @@
-universal-obj-$(CONFIG_ALPHA_DIS) += alpha.o
-universal-obj-$(CONFIG_ARM_DIS) += arm.o
-universal-obj-$(CONFIG_CRIS_DIS) += cris.o
-universal-obj-$(CONFIG_HPPA_DIS) += hppa.o
-universal-obj-$(CONFIG_I386_DIS) += i386.o
-universal-obj-$(CONFIG_IA64_DIS) += ia64.o
-universal-obj-$(CONFIG_M68K_DIS) += m68k.o
-universal-obj-$(CONFIG_MICROBLAZE_DIS) += microblaze.o
-universal-obj-$(CONFIG_MIPS_DIS) += mips.o
-universal-obj-$(CONFIG_PPC_DIS) += ppc.o
-universal-obj-$(CONFIG_S390_DIS) += s390.o
-universal-obj-$(CONFIG_SH4_DIS) += sh4.o
-universal-obj-$(CONFIG_SPARC_DIS) += sparc.o
-universal-obj-$(CONFIG_LM32_DIS) += lm32.o
+common-obj-$(CONFIG_ALPHA_DIS) += alpha.o
+common-obj-$(CONFIG_ARM_DIS) += arm.o
+common-obj-$(CONFIG_CRIS_DIS) += cris.o
+common-obj-$(CONFIG_HPPA_DIS) += hppa.o
+common-obj-$(CONFIG_I386_DIS) += i386.o
+common-obj-$(CONFIG_IA64_DIS) += ia64.o
+common-obj-$(CONFIG_M68K_DIS) += m68k.o
+common-obj-$(CONFIG_MICROBLAZE_DIS) += microblaze.o
+common-obj-$(CONFIG_MIPS_DIS) += mips.o
+common-obj-$(CONFIG_PPC_DIS) += ppc.o
+common-obj-$(CONFIG_S390_DIS) += s390.o
+common-obj-$(CONFIG_SH4_DIS) += sh4.o
+common-obj-$(CONFIG_SPARC_DIS) += sparc.o
+common-obj-$(CONFIG_LM32_DIS) += lm32.o
 
 # TODO: As long as the TCG interpreter and its generated code depend
 # on the QEMU target, we cannot compile the disassembler here.
-#universal-obj-$(CONFIG_TCI_DIS) += tci.o
+#common-obj-$(CONFIG_TCI_DIS) += tci.o
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 23ac249..260885d 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -1,9 +1,10 @@
 # core qdev-related obj files, also used by *-user:
-universal-obj-y += qdev.o qdev-properties.o
+common-obj-y += qdev.o qdev-properties.o
 # irq.o needed for qdev GPIO handling:
-universal-obj-y += irq.o
+common-obj-y += irq.o
 
-common-obj-y = usb/ ide/ pci/
+ifeq ($(CONFIG_SOFTMMU),y)
+common-obj-y += usb/ ide/ pci/
 common-obj-y += loader.o
 common-obj-$(CONFIG_VIRTIO) += virtio-console.o
 common-obj-$(CONFIG_VIRTIO) += virtio-rng.o
@@ -217,3 +218,4 @@ obj-$(CONFIG_LINUX) += vfio_pci.o
 endif
 
 $(obj)/baum.o: QEMU_CFLAGS += $(SDL_CFLAGS) 
+endif
diff --git a/qom/Makefile.objs b/qom/Makefile.objs
index 1899a4c..6a93ac7 100644
--- a/qom/Makefile.objs
+++ b/qom/Makefile.objs
@@ -1,2 +1,2 @@
-universal-obj-y = object.o container.o qom-qobject.o
-universal-obj-y += cpu.o
+common-obj-y = object.o container.o qom-qobject.o
+common-obj-y += cpu.o
commit 737f351892e271fb3080c3c26e6453d939dd1d68
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Sat Jan 19 11:06:46 2013 +0100

    build: use -$(CONFIG_SECCOMP) instead of ifeq
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Acked-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/Makefile.objs b/Makefile.objs
index 3548f9b..3bdb248 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -80,11 +80,7 @@ common-obj-$(CONFIG_SLIRP) += slirp/
 
 common-obj-y += backends/
 
-######################################################################
-# libseccomp
-ifeq ($(CONFIG_SECCOMP),y)
-common-obj-y += qemu-seccomp.o
-endif
+common-obj-$(CONFIG_SECCOMP) += qemu-seccomp.o
 
 common-obj-$(CONFIG_SMARTCARD_NSS) += $(libcacard-y)
 
commit 659800159092333593084593abed2d85c51c5a16
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Sat Jan 19 11:06:45 2013 +0100

    build: move around libcacard-y definition
    
    It is also needed if !CONFIG_SOFTMMU, unlike everything that surrounds it.
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/Makefile.objs b/Makefile.objs
index d465a72..3548f9b 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -34,6 +34,15 @@ CONFIG_REALLY_VIRTFS=y
 endif
 
 ######################################################################
+# smartcard
+
+libcacard-y += libcacard/cac.o libcacard/event.o
+libcacard-y += libcacard/vcard.o libcacard/vreader.o
+libcacard-y += libcacard/vcard_emul_nss.o
+libcacard-y += libcacard/vcard_emul_type.o
+libcacard-y += libcacard/card_7816.o
+
+######################################################################
 # Target independent part of system emulation. The long term path is to
 # suppress *all* target specific code in case of system emulation, i.e. a
 # single QEMU executable should support all CPUs and machines.
@@ -77,15 +86,6 @@ ifeq ($(CONFIG_SECCOMP),y)
 common-obj-y += qemu-seccomp.o
 endif
 
-######################################################################
-# smartcard
-
-libcacard-y += libcacard/cac.o libcacard/event.o
-libcacard-y += libcacard/vcard.o libcacard/vreader.o
-libcacard-y += libcacard/vcard_emul_nss.o
-libcacard-y += libcacard/vcard_emul_type.o
-libcacard-y += libcacard/card_7816.o
-
 common-obj-$(CONFIG_SMARTCARD_NSS) += $(libcacard-y)
 
 ######################################################################
commit 5f7a74a1a605d2065c3d74e42b563d69241089ec
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Jan 15 09:49:35 2013 +0100

    tests: adjust gcov variables for directory movement
    
    I had missed the introduction of the gcov-files-* variables.
    
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tests/Makefile b/tests/Makefile
index d86e95a..d2e326f 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,17 +1,17 @@
 export SRC_PATH
 
 check-unit-y = tests/check-qdict$(EXESUF)
-gcov-files-check-qdict-y = qdict.c
+gcov-files-check-qdict-y = qobject/qdict.c
 check-unit-y += tests/check-qfloat$(EXESUF)
-gcov-files-check-qfloat-y = qfloat.c
+gcov-files-check-qfloat-y = qobject/qfloat.c
 check-unit-y += tests/check-qint$(EXESUF)
-gcov-files-check-qint-y = qint.c
+gcov-files-check-qint-y = qobject/qint.c
 check-unit-y += tests/check-qstring$(EXESUF)
-gcov-files-check-qstring-y = qstring.c
+gcov-files-check-qstring-y = qobject/qstring.c
 check-unit-y += tests/check-qlist$(EXESUF)
-gcov-files-check-qlist-y = qlist.c
+gcov-files-check-qlist-y = qobject/qlist.c
 check-unit-y += tests/check-qjson$(EXESUF)
-gcov-files-check-qjson-y = qjson.c
+gcov-files-check-qjson-y = qobject/qjson.c
 check-unit-y += tests/test-qmp-output-visitor$(EXESUF)
 gcov-files-test-qmp-output-visitor-y = qapi/qmp-output-visitor.c
 check-unit-y += tests/test-qmp-input-visitor$(EXESUF)
@@ -39,7 +39,7 @@ endif
 endif
 check-unit-y += tests/test-visitor-serialization$(EXESUF)
 check-unit-y += tests/test-iov$(EXESUF)
-gcov-files-test-iov-y = iov.c
+gcov-files-test-iov-y = util/iov.c
 check-unit-y += tests/test-aio$(EXESUF)
 gcov-files-test-aio-$(CONFIG_WIN32) = aio-win32.c
 gcov-files-test-aio-$(CONFIG_POSIX) = aio-posix.c
commit f5fba9d27f14603dc7f85779e7b7362fb1cfcbd8
Author: Scott Wood <scottwood at freescale.com>
Date:   Mon Jan 21 15:53:55 2013 +0000

    PPC: e500: Select MPIC v4.2 on ppce500 platform
    
    The compatible string is changed to fsl,mpic on all e500 platforms, to
    advertise the existence of BRR1.  This matches what the device tree will
    have on real hardware.
    
    With MPIC v4.2 max_cpu can be increased from 15 to 32.
    
    Signed-off-by: Scott Wood <scottwood at freescale.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 530f929..b7474c0 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -297,7 +297,7 @@ static int ppce500_load_device_tree(CPUPPCState *env,
     snprintf(mpic, sizeof(mpic), "%s/pic@%llx", soc, MPC8544_MPIC_REGS_OFFSET);
     qemu_devtree_add_subnode(fdt, mpic);
     qemu_devtree_setprop_string(fdt, mpic, "device_type", "open-pic");
-    qemu_devtree_setprop_string(fdt, mpic, "compatible", "chrp,open-pic");
+    qemu_devtree_setprop_string(fdt, mpic, "compatible", "fsl,mpic");
     qemu_devtree_setprop_cells(fdt, mpic, "reg", MPC8544_MPIC_REGS_OFFSET,
                                0x40000);
     qemu_devtree_setprop_cell(fdt, mpic, "#address-cells", 0);
@@ -545,7 +545,7 @@ void ppce500_init(PPCE500Params *params)
     mpic = g_new(qemu_irq, 256);
     dev = qdev_create(NULL, "openpic");
     qdev_prop_set_uint32(dev, "nb_cpus", smp_cpus);
-    qdev_prop_set_uint32(dev, "model", OPENPIC_MODEL_FSL_MPIC_20);
+    qdev_prop_set_uint32(dev, "model", params->mpic_version);
     qdev_init_nofail(dev);
     s = SYS_BUS_DEVICE(dev);
 
diff --git a/hw/ppc/e500.h b/hw/ppc/e500.h
index f5ff273..226c93d 100644
--- a/hw/ppc/e500.h
+++ b/hw/ppc/e500.h
@@ -16,6 +16,8 @@ typedef struct PPCE500Params {
 
     /* required -- must at least add toplevel board compatible */
     void (*fixup_devtree)(struct PPCE500Params *params, void *fdt);
+
+    int mpic_version;
 } PPCE500Params;
 
 void ppce500_init(PPCE500Params *params);
diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c
index 2dcc4a9..25ac4b1 100644
--- a/hw/ppc/e500plat.c
+++ b/hw/ppc/e500plat.c
@@ -15,6 +15,7 @@
 #include "../boards.h"
 #include "sysemu/device_tree.h"
 #include "hw/pci/pci.h"
+#include "hw/openpic.h"
 
 static void e500plat_fixup_devtree(PPCE500Params *params, void *fdt)
 {
@@ -44,6 +45,7 @@ static void e500plat_init(QEMUMachineInitArgs *args)
         .pci_first_slot = 0x1,
         .pci_nr_slots = PCI_SLOT_MAX - 1,
         .fixup_devtree = e500plat_fixup_devtree,
+        .mpic_version = OPENPIC_MODEL_FSL_MPIC_42,
     };
 
     ppce500_init(&params);
@@ -53,7 +55,7 @@ static QEMUMachine e500plat_machine = {
     .name = "ppce500",
     .desc = "generic paravirt e500 platform",
     .init = e500plat_init,
-    .max_cpus = 15,
+    .max_cpus = 32,
     DEFAULT_MACHINE_OPTIONS,
 };
 
diff --git a/hw/ppc/mpc8544ds.c b/hw/ppc/mpc8544ds.c
index 8e05e55..e25c70b 100644
--- a/hw/ppc/mpc8544ds.c
+++ b/hw/ppc/mpc8544ds.c
@@ -14,6 +14,7 @@
 #include "e500.h"
 #include "../boards.h"
 #include "sysemu/device_tree.h"
+#include "hw/openpic.h"
 
 static void mpc8544ds_fixup_devtree(PPCE500Params *params, void *fdt)
 {
@@ -43,6 +44,7 @@ static void mpc8544ds_init(QEMUMachineInitArgs *args)
         .pci_first_slot = 0x11,
         .pci_nr_slots = 2,
         .fixup_devtree = mpc8544ds_fixup_devtree,
+        .mpic_version = OPENPIC_MODEL_FSL_MPIC_20,
     };
 
     ppce500_init(&params);
commit bd25922e737a2c90668a7bdd1e1319413a7a51f3
Author: Scott Wood <scottwood at freescale.com>
Date:   Mon Jan 21 15:53:54 2013 +0000

    PPC: e500: fix mpic_iack address
    
    MPIC+0xa0 is IACK for the current CPU.  MPIC+0x200a0 is IACK for CPU 0.
    This fix allows EPR to work with an SMP target.
    
    Signed-off-by: Scott Wood <scottwood at freescale.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 9ccf4d1..530f929 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -505,7 +505,7 @@ void ppce500_init(PPCE500Params *params)
         irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT];
         env->spr[SPR_BOOKE_PIR] = cs->cpu_index = i;
         env->mpic_iack = MPC8544_CCSRBAR_BASE +
-                         MPC8544_MPIC_REGS_OFFSET + 0x200A0;
+                         MPC8544_MPIC_REGS_OFFSET + 0xa0;
 
         ppc_booke_timers_init(cpu, 400000000, PPC_TIMER_E500);
 
commit e0dfe5b18919a6a4deb841dcf3212e3e998c95e5
Author: Scott Wood <scottwood at freescale.com>
Date:   Mon Jan 21 15:53:53 2013 +0000

    openpic: add basic support for MPIC v4.2
    
    Besides the new value in the version register, this provides:
    - ILR support, which includes:
      - IDR becoming a pure CPU bitmap, allowing 32 CPUs
      - machine check output support (though other parts of QEMU need to
        be fixed for it to do something other than immediately reboot the
        guest)
    - dummy error interrupt support (EISR0/EIMR0 read as zero)
      - actually all FSL MPICs get all summary registers returning zero for now,
        which includes EISR0/EIMR0
    
    Various refactoring is done to support these changes and to ease
    new functionality (e.g. a more flexible way of declaring regions).
    
    Just as the code was already not a full implementation of MPIC v2.0,
    this is not a full implementation of MPIC v4.2 -- e.g. it still has only
    one bank of MSIs.
    
    Signed-off-by: Scott Wood <scottwood at freescale.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/openpic.c b/hw/openpic.c
index 0a4379f..20a479c 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -56,7 +56,7 @@ static const int debug_openpic = 0;
         } \
     } while (0)
 
-#define MAX_CPU     15
+#define MAX_CPU     32
 #define MAX_SRC     256
 #define MAX_TMR     4
 #define MAX_IPI     4
@@ -66,6 +66,7 @@ static const int debug_openpic = 0;
 
 /* OpenPIC capability flags */
 #define OPENPIC_FLAG_IDR_CRIT     (1 << 0)
+#define OPENPIC_FLAG_ILR          (2 << 0)
 
 /* OpenPIC address map */
 #define OPENPIC_GLB_REG_START        0x0
@@ -74,6 +75,8 @@ static const int debug_openpic = 0;
 #define OPENPIC_TMR_REG_SIZE         0x220
 #define OPENPIC_MSI_REG_START        0x1600
 #define OPENPIC_MSI_REG_SIZE         0x200
+#define OPENPIC_SUMMARY_REG_START   0x3800
+#define OPENPIC_SUMMARY_REG_SIZE    0x800
 #define OPENPIC_SRC_REG_START        0x10000
 #define OPENPIC_SRC_REG_SIZE         (MAX_SRC * 0x20)
 #define OPENPIC_CPU_REG_START        0x20000
@@ -94,33 +97,17 @@ static const int debug_openpic = 0;
 /* First doorbell IRQ */
 #define RAVEN_DBL_IRQ    (RAVEN_IPI_IRQ + (RAVEN_MAX_CPU * RAVEN_MAX_IPI))
 
-/* FSL_MPIC_20 */
-#define FSL_MPIC_20_MAX_CPU      1
-#define FSL_MPIC_20_MAX_EXT     12
-#define FSL_MPIC_20_MAX_INT     64
-#define FSL_MPIC_20_MAX_IRQ     MAX_IRQ
+typedef struct FslMpicInfo {
+    int max_ext;
+} FslMpicInfo;
 
-/* Interrupt definitions */
-/* IRQs, accessible through the IRQ region */
-#define FSL_MPIC_20_EXT_IRQ      0x00
-#define FSL_MPIC_20_INT_IRQ      0x10
-#define FSL_MPIC_20_MSG_IRQ      0xb0
-#define FSL_MPIC_20_MSI_IRQ      0xe0
-/* These are available through separate regions, but
-   for simplicity's sake mapped into the same number space */
-#define FSL_MPIC_20_TMR_IRQ      0x100
-#define FSL_MPIC_20_IPI_IRQ      0x104
+static FslMpicInfo fsl_mpic_20 = {
+    .max_ext = 12,
+};
 
-/*
- * Block Revision Register1 (BRR1): QEMU does not fully emulate
- * any version on MPIC. So to start with, set the IP version to 0.
- *
- * NOTE: This is Freescale MPIC specific register. Keep it here till
- * this code is refactored for different variants of OPENPIC and MPIC.
- */
-#define FSL_BRR1_IPID (0x0040 << 16) /* 16 bit IP-block ID */
-#define FSL_BRR1_IPMJ (0x00 << 8) /* 8 bit IP major number */
-#define FSL_BRR1_IPMN 0x00 /* 8 bit IP minor number */
+static FslMpicInfo fsl_mpic_42 = {
+    .max_ext = 12,
+};
 
 #define FRR_NIRQ_SHIFT    16
 #define FRR_NCPU_SHIFT     8
@@ -146,6 +133,49 @@ static const int debug_openpic = 0;
 #define IDR_P1_SHIFT      1
 #define IDR_P0_SHIFT      0
 
+#define ILR_INTTGT_MASK   0x000000ff
+#define ILR_INTTGT_INT    0x00
+#define ILR_INTTGT_CINT   0x01 /* critical */
+#define ILR_INTTGT_MCP    0x02 /* machine check */
+
+/* The currently supported INTTGT values happen to be the same as QEMU's
+ * openpic output codes, but don't depend on this.  The output codes
+ * could change (unlikely, but...) or support could be added for
+ * more INTTGT values.
+ */
+static const int inttgt_output[][2] = {
+    { ILR_INTTGT_INT, OPENPIC_OUTPUT_INT },
+    { ILR_INTTGT_CINT, OPENPIC_OUTPUT_CINT },
+    { ILR_INTTGT_MCP, OPENPIC_OUTPUT_MCK },
+};
+
+static int inttgt_to_output(int inttgt)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(inttgt_output); i++) {
+        if (inttgt_output[i][0] == inttgt) {
+            return inttgt_output[i][1];
+        }
+    }
+
+    fprintf(stderr, "%s: unsupported inttgt %d\n", __func__, inttgt);
+    return OPENPIC_OUTPUT_INT;
+}
+
+static int output_to_inttgt(int output)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(inttgt_output); i++) {
+        if (inttgt_output[i][1] == output) {
+            return inttgt_output[i][0];
+        }
+    }
+
+    abort();
+}
+
 #define MSIIR_OFFSET       0x140
 #define MSIIR_SRS_SHIFT    29
 #define MSIIR_SRS_MASK     (0x7 << MSIIR_SRS_SHIFT)
@@ -230,6 +260,7 @@ typedef struct OpenPICState {
     MemoryRegion mem;
 
     /* Behavior control */
+    FslMpicInfo *fsl;
     uint32_t model;
     uint32_t flags;
     uint32_t nb_irqs;
@@ -243,7 +274,7 @@ typedef struct OpenPICState {
     uint32_t mpic_mode_mask;
 
     /* Sub-regions */
-    MemoryRegion sub_io_mem[5];
+    MemoryRegion sub_io_mem[6];
 
     /* Global registers */
     uint32_t frr; /* Feature reporting register */
@@ -558,6 +589,15 @@ static inline uint32_t read_IRQreg_idr(OpenPICState *opp, int n_IRQ)
     return opp->src[n_IRQ].idr;
 }
 
+static inline uint32_t read_IRQreg_ilr(OpenPICState *opp, int n_IRQ)
+{
+    if (opp->flags & OPENPIC_FLAG_ILR) {
+        return output_to_inttgt(opp->src[n_IRQ].output);
+    }
+
+    return 0xffffffff;
+}
+
 static inline uint32_t read_IRQreg_ivpr(OpenPICState *opp, int n_IRQ)
 {
     return opp->src[n_IRQ].ivpr;
@@ -608,6 +648,19 @@ static inline void write_IRQreg_idr(OpenPICState *opp, int n_IRQ, uint32_t val)
     }
 }
 
+static inline void write_IRQreg_ilr(OpenPICState *opp, int n_IRQ, uint32_t val)
+{
+    if (opp->flags & OPENPIC_FLAG_ILR) {
+        IRQSource *src = &opp->src[n_IRQ];
+
+        src->output = inttgt_to_output(val & ILR_INTTGT_MASK);
+        DPRINTF("Set ILR %d to 0x%08x, output %d\n", n_IRQ, src->idr,
+                src->output);
+
+        /* TODO: on MPIC v4.0 only, set nomask for non-INT */
+    }
+}
+
 static inline void write_IRQreg_ivpr(OpenPICState *opp, int n_IRQ, uint32_t val)
 {
     uint32_t mask;
@@ -874,17 +927,20 @@ static void openpic_src_write(void *opaque, hwaddr addr, uint64_t val,
 
     DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n",
             __func__, addr, val);
-    if (addr & 0xF) {
-        return;
-    }
-    addr = addr & 0xFFF0;
+
+    addr = addr & 0xffff;
     idx = addr >> 5;
-    if (addr & 0x10) {
-        /* EXDE / IFEDE / IEEDE */
-        write_IRQreg_idr(opp, idx, val);
-    } else {
-        /* EXVP / IFEVP / IEEVP */
+
+    switch (addr & 0x1f) {
+    case 0x00:
         write_IRQreg_ivpr(opp, idx, val);
+        break;
+    case 0x10:
+        write_IRQreg_idr(opp, idx, val);
+        break;
+    case 0x18:
+        write_IRQreg_ilr(opp, idx, val);
+        break;
     }
 }
 
@@ -896,20 +952,23 @@ static uint64_t openpic_src_read(void *opaque, uint64_t addr, unsigned len)
 
     DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
     retval = 0xFFFFFFFF;
-    if (addr & 0xF) {
-        return retval;
-    }
-    addr = addr & 0xFFF0;
+
+    addr = addr & 0xffff;
     idx = addr >> 5;
-    if (addr & 0x10) {
-        /* EXDE / IFEDE / IEEDE */
-        retval = read_IRQreg_idr(opp, idx);
-    } else {
-        /* EXVP / IFEVP / IEEVP */
+
+    switch (addr & 0x1f) {
+    case 0x00:
         retval = read_IRQreg_ivpr(opp, idx);
+        break;
+    case 0x10:
+        retval = read_IRQreg_idr(opp, idx);
+        break;
+    case 0x18:
+        retval = read_IRQreg_ilr(opp, idx);
+        break;
     }
-    DPRINTF("%s: => 0x%08x\n", __func__, retval);
 
+    DPRINTF("%s: => 0x%08x\n", __func__, retval);
     return retval;
 }
 
@@ -977,6 +1036,26 @@ static uint64_t openpic_msi_read(void *opaque, hwaddr addr, unsigned size)
     return r;
 }
 
+static uint64_t openpic_summary_read(void *opaque, hwaddr addr, unsigned size)
+{
+    uint64_t r = 0;
+
+    DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
+
+    /* TODO: EISR/EIMR */
+
+    return r;
+}
+
+static void openpic_summary_write(void *opaque, hwaddr addr, uint64_t val,
+                                  unsigned size)
+{
+    DPRINTF("%s: addr %#" HWADDR_PRIx " <= 0x%08" PRIx64 "\n",
+            __func__, addr, val);
+
+    /* TODO: EISR/EIMR */
+}
+
 static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
                                        uint32_t val, int idx)
 {
@@ -1242,19 +1321,19 @@ static const MemoryRegionOps openpic_src_ops_be = {
     },
 };
 
-static const MemoryRegionOps openpic_msi_ops_le = {
+static const MemoryRegionOps openpic_msi_ops_be = {
     .read = openpic_msi_read,
     .write = openpic_msi_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
+    .endianness = DEVICE_BIG_ENDIAN,
     .impl = {
         .min_access_size = 4,
         .max_access_size = 4,
     },
 };
 
-static const MemoryRegionOps openpic_msi_ops_be = {
-    .read = openpic_msi_read,
-    .write = openpic_msi_write,
+static const MemoryRegionOps openpic_summary_ops_be = {
+    .read = openpic_summary_read,
+    .write = openpic_summary_write,
     .endianness = DEVICE_BIG_ENDIAN,
     .impl = {
         .min_access_size = 4,
@@ -1387,78 +1466,128 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)
 typedef struct MemReg {
     const char             *name;
     MemoryRegionOps const  *ops;
-    bool                   map;
     hwaddr      start_addr;
     ram_addr_t              size;
 } MemReg;
 
+static void fsl_common_init(OpenPICState *opp)
+{
+    int i;
+    int virq = MAX_SRC;
+
+    opp->vid = VID_REVISION_1_2;
+    opp->vir = VIR_GENERIC;
+    opp->vector_mask = 0xFFFF;
+    opp->tfrr_reset = 0;
+    opp->ivpr_reset = IVPR_MASK_MASK;
+    opp->idr_reset = 1 << 0;
+    opp->max_irq = MAX_IRQ;
+
+    opp->irq_ipi0 = virq;
+    virq += MAX_IPI;
+    opp->irq_tim0 = virq;
+    virq += MAX_TMR;
+
+    assert(virq <= MAX_IRQ);
+
+    opp->irq_msi = 224;
+
+    msi_supported = true;
+    for (i = 0; i < opp->fsl->max_ext; i++) {
+        opp->src[i].level = false;
+    }
+
+    /* Internal interrupts, including message and MSI */
+    for (i = 16; i < MAX_SRC; i++) {
+        opp->src[i].type = IRQ_TYPE_FSLINT;
+        opp->src[i].level = true;
+    }
+
+    /* timers and IPIs */
+    for (i = MAX_SRC; i < virq; i++) {
+        opp->src[i].type = IRQ_TYPE_FSLSPECIAL;
+        opp->src[i].level = false;
+    }
+}
+
+static void map_list(OpenPICState *opp, const MemReg *list, int *count)
+{
+    while (list->name) {
+        assert(*count < ARRAY_SIZE(opp->sub_io_mem));
+
+        memory_region_init_io(&opp->sub_io_mem[*count], list->ops, opp,
+                              list->name, list->size);
+
+        memory_region_add_subregion(&opp->mem, list->start_addr,
+                                    &opp->sub_io_mem[*count]);
+
+        (*count)++;
+        list++;
+    }
+}
+
 static int openpic_init(SysBusDevice *dev)
 {
     OpenPICState *opp = FROM_SYSBUS(typeof (*opp), dev);
     int i, j;
-    MemReg list_le[] = {
-        {"glb", &openpic_glb_ops_le, true,
+    int list_count = 0;
+    static const MemReg list_le[] = {
+        {"glb", &openpic_glb_ops_le,
                 OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE},
-        {"tmr", &openpic_tmr_ops_le, true,
+        {"tmr", &openpic_tmr_ops_le,
                 OPENPIC_TMR_REG_START, OPENPIC_TMR_REG_SIZE},
-        {"msi", &openpic_msi_ops_le, true,
-                OPENPIC_MSI_REG_START, OPENPIC_MSI_REG_SIZE},
-        {"src", &openpic_src_ops_le, true,
+        {"src", &openpic_src_ops_le,
                 OPENPIC_SRC_REG_START, OPENPIC_SRC_REG_SIZE},
-        {"cpu", &openpic_cpu_ops_le, true,
+        {"cpu", &openpic_cpu_ops_le,
                 OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE},
+        {NULL}
     };
-    MemReg list_be[] = {
-        {"glb", &openpic_glb_ops_be, true,
+    static const MemReg list_be[] = {
+        {"glb", &openpic_glb_ops_be,
                 OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE},
-        {"tmr", &openpic_tmr_ops_be, true,
+        {"tmr", &openpic_tmr_ops_be,
                 OPENPIC_TMR_REG_START, OPENPIC_TMR_REG_SIZE},
-        {"msi", &openpic_msi_ops_be, true,
-                OPENPIC_MSI_REG_START, OPENPIC_MSI_REG_SIZE},
-        {"src", &openpic_src_ops_be, true,
+        {"src", &openpic_src_ops_be,
                 OPENPIC_SRC_REG_START, OPENPIC_SRC_REG_SIZE},
-        {"cpu", &openpic_cpu_ops_be, true,
+        {"cpu", &openpic_cpu_ops_be,
                 OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE},
+        {NULL}
     };
-    MemReg *list;
+    static const MemReg list_fsl[] = {
+        {"msi", &openpic_msi_ops_be,
+                OPENPIC_MSI_REG_START, OPENPIC_MSI_REG_SIZE},
+        {"summary", &openpic_summary_ops_be,
+                OPENPIC_SUMMARY_REG_START, OPENPIC_SUMMARY_REG_SIZE},
+        {NULL}
+    };
+
+    memory_region_init(&opp->mem, "openpic", 0x40000);
 
     switch (opp->model) {
     case OPENPIC_MODEL_FSL_MPIC_20:
     default:
+        opp->fsl = &fsl_mpic_20;
+        opp->brr1 = 0x00400200;
         opp->flags |= OPENPIC_FLAG_IDR_CRIT;
         opp->nb_irqs = 80;
-        opp->vid = VID_REVISION_1_2;
-        opp->vir = VIR_GENERIC;
-        opp->vector_mask = 0xFFFF;
-        opp->tfrr_reset = 0;
-        opp->ivpr_reset = IVPR_MASK_MASK;
-        opp->idr_reset = 1 << 0;
-        opp->max_irq = FSL_MPIC_20_MAX_IRQ;
-        opp->irq_ipi0 = FSL_MPIC_20_IPI_IRQ;
-        opp->irq_tim0 = FSL_MPIC_20_TMR_IRQ;
-        opp->irq_msi = FSL_MPIC_20_MSI_IRQ;
-        opp->brr1 = FSL_BRR1_IPID | FSL_BRR1_IPMJ | FSL_BRR1_IPMN;
-        /* XXX really only available as of MPIC 4.0 */
-        opp->mpic_mode_mask = GCR_MODE_PROXY;
+        opp->mpic_mode_mask = GCR_MODE_MIXED;
 
-        msi_supported = true;
-        list = list_be;
+        fsl_common_init(opp);
+        map_list(opp, list_be, &list_count);
+        map_list(opp, list_fsl, &list_count);
 
-        for (i = 0; i < FSL_MPIC_20_MAX_EXT; i++) {
-            opp->src[i].level = false;
-        }
+        break;
 
-        /* Internal interrupts, including message and MSI */
-        for (i = 16; i < MAX_SRC; i++) {
-            opp->src[i].type = IRQ_TYPE_FSLINT;
-            opp->src[i].level = true;
-        }
+    case OPENPIC_MODEL_FSL_MPIC_42:
+        opp->fsl = &fsl_mpic_42;
+        opp->brr1 = 0x00400402;
+        opp->flags |= OPENPIC_FLAG_ILR;
+        opp->nb_irqs = 196;
+        opp->mpic_mode_mask = GCR_MODE_PROXY;
 
-        /* timers and IPIs */
-        for (i = MAX_SRC; i < MAX_IRQ; i++) {
-            opp->src[i].type = IRQ_TYPE_FSLSPECIAL;
-            opp->src[i].level = false;
-        }
+        fsl_common_init(opp);
+        map_list(opp, list_be, &list_count);
+        map_list(opp, list_fsl, &list_count);
 
         break;
 
@@ -1475,29 +1604,14 @@ static int openpic_init(SysBusDevice *dev)
         opp->irq_tim0 = RAVEN_TMR_IRQ;
         opp->brr1 = -1;
         opp->mpic_mode_mask = GCR_MODE_MIXED;
-        list = list_le;
-        /* Don't map MSI region */
-        list[2].map = false;
 
         /* Only UP supported today */
         if (opp->nb_cpus != 1) {
             return -EINVAL;
         }
-        break;
-    }
-
-    memory_region_init(&opp->mem, "openpic", 0x40000);
 
-    for (i = 0; i < ARRAY_SIZE(list_le); i++) {
-        if (!list[i].map) {
-            continue;
-        }
-
-        memory_region_init_io(&opp->sub_io_mem[i], list[i].ops, opp,
-                              list[i].name, list[i].size);
-
-        memory_region_add_subregion(&opp->mem, list[i].start_addr,
-                                    &opp->sub_io_mem[i]);
+        map_list(opp, list_le, &list_count);
+        break;
     }
 
     for (i = 0; i < opp->nb_cpus; i++) {
diff --git a/hw/openpic.h b/hw/openpic.h
index e226d7b..9dcaf0e 100644
--- a/hw/openpic.h
+++ b/hw/openpic.h
@@ -13,5 +13,6 @@ enum {
 
 #define OPENPIC_MODEL_RAVEN       0
 #define OPENPIC_MODEL_FSL_MPIC_20 1
+#define OPENPIC_MODEL_FSL_MPIC_42 2
 
 #endif /* __OPENPIC_H__ */
commit 03274d44f655f7b822e845e79fa32b261cdb0774
Author: Scott Wood <scottwood at freescale.com>
Date:   Mon Jan 21 15:53:52 2013 +0000

    openpic: fix timer address decoding
    
    The timer memory range begins at 0x10f0, so that address 0x1120 shows
    up as 0x30, 0x1130 shows up as 0x40, etc.  However, the address
    decoding (other than TFRR) is not adjusted for this, causing the
    wrong registers to be accessed.
    
    Signed-off-by: Scott Wood <scottwood at freescale.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/openpic.c b/hw/openpic.c
index a4488c2..0a4379f 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -792,19 +792,23 @@ static void openpic_tmr_write(void *opaque, hwaddr addr, uint64_t val,
     OpenPICState *opp = opaque;
     int idx;
 
+    addr += 0x10f0;
+
     DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n",
             __func__, addr, val);
     if (addr & 0xF) {
         return;
     }
-    idx = (addr >> 6) & 0x3;
-    addr = addr & 0x30;
 
-    if (addr == 0x0) {
+    if (addr == 0x10f0) {
         /* TFRR */
         opp->tfrr = val;
         return;
     }
+
+    idx = (addr >> 6) & 0x3;
+    addr = addr & 0x30;
+
     switch (addr & 0x30) {
     case 0x00: /* TCCR */
         break;
commit f40c360c0da020a1a478f8e60dd205d7412bc315
Author: Scott Wood <scottwood at freescale.com>
Date:   Mon Jan 21 15:53:51 2013 +0000

    openpic: fix remaining issues from idr-to-destmask conversion
    
    openpic_update_irq() was checking idr rather than destmask, treating
    it as if it were a simple bitmap of cpus.  Changed to use destmask.
    
    IPI delivery was removing bits directly from .idr, without calling
    write_IRQreg_idr so that the change could be conveyed to destmask.
    Changed to use destmask directly.
    
    Save/restore destmask when serializing, as due to the IPI change it
    cannot be reproduced from idr.
    
    Signed-off-by: Scott Wood <scottwood at freescale.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/openpic.c b/hw/openpic.c
index 25aa9bf..a4488c2 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -436,13 +436,13 @@ static void openpic_update_irq(OpenPICState *opp, int n_IRQ)
         src->ivpr &= ~IVPR_ACTIVITY_MASK;
     }
 
-    if (src->idr == 0) {
+    if (src->destmask == 0) {
         /* No target */
         DPRINTF("%s: IRQ %d has no target\n", __func__, n_IRQ);
         return;
     }
 
-    if (src->idr == (1 << src->last_cpu)) {
+    if (src->destmask == (1 << src->last_cpu)) {
         /* Only one CPU is allowed to receive this IRQ */
         IRQ_local_pipe(opp, src->last_cpu, n_IRQ, active, was_active);
     } else if (!(src->ivpr & IVPR_MODE_MASK)) {
@@ -1000,8 +1000,7 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
     case 0x70:
         idx = (addr - 0x40) >> 4;
         /* we use IDE as mask which CPUs to deliver the IPI to still. */
-        write_IRQreg_idr(opp, opp->irq_ipi0 + idx,
-                         opp->src[opp->irq_ipi0 + idx].idr | val);
+        opp->src[opp->irq_ipi0 + idx].destmask |= val;
         openpic_set_irq(opp, opp->irq_ipi0 + idx, 1);
         openpic_set_irq(opp, opp->irq_ipi0 + idx, 0);
         break;
@@ -1101,8 +1100,8 @@ static uint32_t openpic_iack(OpenPICState *opp, IRQDest *dst, int cpu)
     }
 
     if ((irq >= opp->irq_ipi0) &&  (irq < (opp->irq_ipi0 + MAX_IPI))) {
-        src->idr &= ~(1 << cpu);
-        if (src->idr && !src->level) {
+        src->destmask &= ~(1 << cpu);
+        if (src->destmask && !src->level) {
             /* trigger on CPUs that didn't know about it yet */
             openpic_set_irq(opp, irq, 1);
             openpic_set_irq(opp, irq, 0);
@@ -1307,6 +1306,7 @@ static void openpic_save(QEMUFile* f, void *opaque)
     for (i = 0; i < opp->max_irq; i++) {
         qemu_put_be32s(f, &opp->src[i].ivpr);
         qemu_put_be32s(f, &opp->src[i].idr);
+        qemu_get_be32s(f, &opp->src[i].destmask);
         qemu_put_sbe32s(f, &opp->src[i].last_cpu);
         qemu_put_sbe32s(f, &opp->src[i].pending);
     }
@@ -1372,6 +1372,7 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)
 
         qemu_get_be32s(f, &opp->src[i].ivpr);
         qemu_get_be32s(f, &opp->src[i].idr);
+        qemu_get_be32s(f, &opp->src[i].destmask);
         qemu_get_sbe32s(f, &opp->src[i].last_cpu);
         qemu_get_sbe32s(f, &opp->src[i].pending);
     }
commit 1ea1ce8ac305d9e006bc8b0f5f3554793fd2fa43
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Wed Jan 23 17:20:43 2013 +0000

    pseries: Adjust default VIO address allocations to play better with libvirt
    
    Currently, if VIO devices for pseries don't have addresses explicitly
    allocated, they get automatically numbered from 0x1000.  This is in the
    same general range that libvirt will typically assign VIO device addresses.
    
    That means that if there is a device libvirt doesn't know about, and it
    gets an address assigned before the libvirt assigned devices are processed,
    we can end up with an address conflict (qemu will abort with an error).
    
    While the real solution is to teach libvirt about the other devices, so it
    can correctly manage the whole allocation, this patch reduces the interim
    inconvenience by moving qemu allocations to a range that libvirt is less
    likely to conflict with.
    
    Because the guest gets the device addresses through the device tree, these
    addresses are truly arbitrary and can be changed without breaking guests.
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 2054219..34c9ca6 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -492,7 +492,7 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
 
     qbus = qbus_create(TYPE_SPAPR_VIO_BUS, dev, "spapr-vio");
     bus = DO_UPCAST(VIOsPAPRBus, bus, qbus);
-    bus->next_reg = 0x1000;
+    bus->next_reg = 0x71000000;
 
     /* hcall-vio */
     spapr_register_hypercall(H_VIO_SIGNAL, h_vio_signal);
commit caae58cba07efec5f0616f568531c9dfaf1e9179
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Wed Jan 23 17:20:39 2013 +0000

    pseries: Improve handling of multiple PCI host bridges
    
    Multiple - even many - PCI host bridges (i.e. PCI domains) are very
    common on real PAPR compliant hardware.  For reasons related to the
    PAPR specified IOMMU interfaces, PCI device assignment with VFIO will
    generally require at least two (virtual) PHBs and possibly more
    depending on which devices are assigned.
    
    At the moment the qemu PAPR PCI code will not deal with this well,
    leaving several crucial parameters of PHBs other than the default one
    uninitialized.  This patch reworks the code to allow this.
    
    Every PHB needs a unique BUID (Bus Unit Identifier, the id used for
    the PAPR PCI related interfaces) and a unique LIOBN (Logical IO Bus
    Number, the id used for the PAPR IOMMU related interfaces).  In
    addition they need windows in CPU real address space to access PCI
    memory space, PCI IO space and MSIs.  Properties are added to the PCI
    host bridge qdevice to allow configuration of all these.
    
    To simplify configuration of multiple PHBs for common cases, a
    convenience "index" property is also added.  This can be set instead
    of the low-level properties, and will generate suitable values for the
    other parameters, different for each index value.
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/spapr.c b/hw/spapr.c
index d80b792..e88a27a 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -77,12 +77,6 @@
 #define MAX_CPUS                256
 #define XICS_IRQS               1024
 
-#define SPAPR_PCI_BUID          0x800000020000001ULL
-#define SPAPR_PCI_MEM_WIN_ADDR  (0x10000000000ULL + 0xA0000000)
-#define SPAPR_PCI_MEM_WIN_SIZE  0x20000000
-#define SPAPR_PCI_IO_WIN_ADDR   (0x10000000000ULL + 0x80000000)
-#define SPAPR_PCI_MSI_WIN_ADDR  (0x10000000000ULL + 0x90000000)
-
 #define PHANDLE_XICP            0x00001111
 
 #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
@@ -857,12 +851,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
     /* Set up PCI */
     spapr_pci_rtas_init();
 
-    spapr_create_phb(spapr, "pci", SPAPR_PCI_BUID,
-                     SPAPR_PCI_MEM_WIN_ADDR,
-                     SPAPR_PCI_MEM_WIN_SIZE,
-                     SPAPR_PCI_IO_WIN_ADDR,
-                     SPAPR_PCI_MSI_WIN_ADDR);
-    phb = PCI_HOST_BRIDGE(QLIST_FIRST(&spapr->phbs));
+    phb = spapr_create_phb(spapr, 0, "pci");
 
     for (i = 0; i < nb_nics; i++) {
         NICInfo *nd = &nd_table[i];
diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c
index bbcc9fc..4eacbcf 100644
--- a/hw/spapr_pci.c
+++ b/hw/spapr_pci.c
@@ -435,7 +435,7 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level)
      */
     sPAPRPHBState *phb = opaque;
 
-    trace_spapr_pci_lsi_set(phb->busname, irq_num, phb->lsi_table[irq_num].irq);
+    trace_spapr_pci_lsi_set(phb->dtbusname, irq_num, phb->lsi_table[irq_num].irq);
     qemu_set_irq(spapr_phb_lsi_qirq(phb, irq_num), level);
 }
 
@@ -522,7 +522,63 @@ static int spapr_phb_init(SysBusDevice *s)
     int i;
     PCIBus *bus;
 
+    if (sphb->index != -1) {
+        hwaddr windows_base;
+
+        if ((sphb->buid != -1) || (sphb->dma_liobn != -1)
+            || (sphb->mem_win_addr != -1)
+            || (sphb->io_win_addr != -1)
+            || (sphb->msi_win_addr != -1)) {
+            fprintf(stderr, "Either \"index\" or other parameters must"
+                    " be specified for PAPR PHB, not both\n");
+            return -1;
+        }
+
+        sphb->buid = SPAPR_PCI_BASE_BUID + sphb->index;
+        sphb->dma_liobn = SPAPR_PCI_BASE_LIOBN + sphb->index;
+
+        windows_base = SPAPR_PCI_WINDOW_BASE
+            + sphb->index * SPAPR_PCI_WINDOW_SPACING;
+        sphb->mem_win_addr = windows_base + SPAPR_PCI_MMIO_WIN_OFF;
+        sphb->io_win_addr = windows_base + SPAPR_PCI_IO_WIN_OFF;
+        sphb->msi_win_addr = windows_base + SPAPR_PCI_MSI_WIN_OFF;
+    }
+
+    if (sphb->buid == -1) {
+        fprintf(stderr, "BUID not specified for PHB\n");
+        return -1;
+    }
+
+    if (sphb->dma_liobn == -1) {
+        fprintf(stderr, "LIOBN not specified for PHB\n");
+        return -1;
+    }
+
+    if (sphb->mem_win_addr == -1) {
+        fprintf(stderr, "Memory window address not specified for PHB\n");
+        return -1;
+    }
+
+    if (sphb->io_win_addr == -1) {
+        fprintf(stderr, "IO window address not specified for PHB\n");
+        return -1;
+    }
+
+    if (sphb->msi_win_addr == -1) {
+        fprintf(stderr, "MSI window address not specified for PHB\n");
+        return -1;
+    }
+
+    if (find_phb(spapr, sphb->buid)) {
+        fprintf(stderr, "PCI host bridges must have unique BUIDs\n");
+        return -1;
+    }
+
     sphb->dtbusname = g_strdup_printf("pci@%" PRIx64, sphb->buid);
+    if (!sphb->busname) {
+        sphb->busname = sphb->dtbusname;
+    }
+
     namebuf = alloca(strlen(sphb->dtbusname) + 32);
 
     /* Initialize memory regions */
@@ -565,17 +621,19 @@ static int spapr_phb_init(SysBusDevice *s)
                                     &sphb->msiwindow);
     }
 
-    bus = pci_register_bus(DEVICE(s),
-                           sphb->busname ? sphb->busname : sphb->dtbusname,
+    bus = pci_register_bus(DEVICE(s), sphb->busname,
                            pci_spapr_set_irq, pci_spapr_map_irq, sphb,
                            &sphb->memspace, &sphb->iospace,
                            PCI_DEVFN(0, 0), PCI_NUM_PINS);
     phb->bus = bus;
 
-    sphb->dma_liobn = SPAPR_PCI_BASE_LIOBN | (pci_find_domain(bus) << 16);
     sphb->dma_window_start = 0;
     sphb->dma_window_size = 0x40000000;
     sphb->dma = spapr_tce_new_dma_context(sphb->dma_liobn, sphb->dma_window_size);
+    if (!sphb->dma) {
+        fprintf(stderr, "Unable to create TCE table for %s\n", sphb->dtbusname);
+        return -1;
+    }
     pci_setup_iommu(bus, spapr_pci_dma_context_fn, sphb);
 
     QLIST_INSERT_HEAD(&spapr->phbs, sphb, list);
@@ -605,13 +663,17 @@ static void spapr_phb_reset(DeviceState *qdev)
 }
 
 static Property spapr_phb_properties[] = {
-    DEFINE_PROP_HEX64("buid", sPAPRPHBState, buid, 0),
     DEFINE_PROP_STRING("busname", sPAPRPHBState, busname),
-    DEFINE_PROP_HEX64("mem_win_addr", sPAPRPHBState, mem_win_addr, 0),
-    DEFINE_PROP_HEX64("mem_win_size", sPAPRPHBState, mem_win_size, 0x20000000),
-    DEFINE_PROP_HEX64("io_win_addr", sPAPRPHBState, io_win_addr, 0),
-    DEFINE_PROP_HEX64("io_win_size", sPAPRPHBState, io_win_size, 0x10000),
-    DEFINE_PROP_HEX64("msi_win_addr", sPAPRPHBState, msi_win_addr, 0),
+    DEFINE_PROP_INT32("index", sPAPRPHBState, index, -1),
+    DEFINE_PROP_HEX64("buid", sPAPRPHBState, buid, -1),
+    DEFINE_PROP_HEX32("liobn", sPAPRPHBState, dma_liobn, -1),
+    DEFINE_PROP_HEX64("mem_win_addr", sPAPRPHBState, mem_win_addr, -1),
+    DEFINE_PROP_HEX64("mem_win_size", sPAPRPHBState, mem_win_size,
+                      SPAPR_PCI_MMIO_WIN_SIZE),
+    DEFINE_PROP_HEX64("io_win_addr", sPAPRPHBState, io_win_addr, -1),
+    DEFINE_PROP_HEX64("io_win_size", sPAPRPHBState, io_win_size,
+                      SPAPR_PCI_IO_WIN_SIZE),
+    DEFINE_PROP_HEX64("msi_win_addr", sPAPRPHBState, msi_win_addr, -1),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -632,25 +694,17 @@ static const TypeInfo spapr_phb_info = {
     .class_init    = spapr_phb_class_init,
 };
 
-void spapr_create_phb(sPAPREnvironment *spapr,
-                      const char *busname, uint64_t buid,
-                      uint64_t mem_win_addr, uint64_t mem_win_size,
-                      uint64_t io_win_addr, uint64_t msi_win_addr)
+PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index,
+                               const char *busname)
 {
     DeviceState *dev;
 
     dev = qdev_create(NULL, TYPE_SPAPR_PCI_HOST_BRIDGE);
-
-    if (busname) {
-        qdev_prop_set_string(dev, "busname", g_strdup(busname));
-    }
-    qdev_prop_set_uint64(dev, "buid", buid);
-    qdev_prop_set_uint64(dev, "mem_win_addr", mem_win_addr);
-    qdev_prop_set_uint64(dev, "mem_win_size", mem_win_size);
-    qdev_prop_set_uint64(dev, "io_win_addr", io_win_addr);
-    qdev_prop_set_uint64(dev, "msi_win_addr", msi_win_addr);
-
+    qdev_prop_set_uint32(dev, "index", index);
+    qdev_prop_set_string(dev, "busname", busname);
     qdev_init_nofail(dev);
+
+    return PCI_HOST_BRIDGE(dev);
 }
 
 /* Macros to operate with address in OF binding to PCI */
diff --git a/hw/spapr_pci.h b/hw/spapr_pci.h
index 7b26ba1..8bb3c62 100644
--- a/hw/spapr_pci.h
+++ b/hw/spapr_pci.h
@@ -37,6 +37,7 @@
 typedef struct sPAPRPHBState {
     PCIHostState parent_obj;
 
+    int32_t index;
     uint64_t buid;
     char *busname;
     char *dtbusname;
@@ -64,18 +65,25 @@ typedef struct sPAPRPHBState {
     QLIST_ENTRY(sPAPRPHBState) list;
 } sPAPRPHBState;
 
+#define SPAPR_PCI_BASE_BUID          0x800000020000000ULL
+
+#define SPAPR_PCI_WINDOW_BASE        0x10000000000ULL
+#define SPAPR_PCI_WINDOW_SPACING     0x1000000000ULL
+#define SPAPR_PCI_MMIO_WIN_OFF       0xA0000000
+#define SPAPR_PCI_MMIO_WIN_SIZE      0x20000000
+#define SPAPR_PCI_IO_WIN_OFF         0x80000000
+#define SPAPR_PCI_IO_WIN_SIZE        0x10000
+#define SPAPR_PCI_MSI_WIN_OFF        0x90000000
+
+#define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL
+
 static inline qemu_irq spapr_phb_lsi_qirq(struct sPAPRPHBState *phb, int pin)
 {
     return xics_get_qirq(spapr->icp, phb->lsi_table[pin].irq);
 }
 
-#define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL
-#define SPAPR_PCI_IO_WIN_SIZE        0x10000
-
-void spapr_create_phb(sPAPREnvironment *spapr,
-                      const char *busname, uint64_t buid,
-                      uint64_t mem_win_addr, uint64_t mem_win_size,
-                      uint64_t io_win_addr, uint64_t msi_win_addr);
+PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index,
+                               const char *busname);
 
 int spapr_populate_pci_dt(sPAPRPHBState *phb,
                           uint32_t xics_phandle,
commit fe828a4d4b7a5617cda7b24e95e327bfb71d790e
Author: Mike Qiu <qiudayu at linux.vnet.ibm.com>
Date:   Wed Jan 23 17:20:38 2013 +0000

    target-ppc: Give a meaningful error if too many threads are specified
    
    Currently the target-ppc tcg code only supports a single thread.  You can
    specify more, but they're treated identically to multiple cores.  On KVM
    we obviously can't support more threads than the hardware; if more are
    specified it will cause strange and cryptic errors.
    
    This patch clarifies the situation by giving a simple meaningful error if
    more threads are specified than we can support.
    
    Signed-off-by: Mike Qiu <qiudayu at linux.vnet.ibm.com>
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 2d78529..4f767c9 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -28,6 +28,7 @@
 #include <sysemu/kvm.h>
 #include "kvm_ppc.h"
 #include "sysemu/arch_init.h"
+#include "sysemu/cpus.h"
 
 //#define PPC_DUMP_CPU
 //#define PPC_DEBUG_SPR
@@ -10036,6 +10037,17 @@ static void ppc_cpu_realize(Object *obj, Error **errp)
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
     ppc_def_t *def = pcc->info;
     Error *local_err = NULL;
+#if !defined(CONFIG_USER_ONLY)
+    int max_smt = kvm_enabled() ? kvmppc_smt_threads() : 1;
+#endif
+
+#if !defined(CONFIG_USER_ONLY)
+    if (smp_threads > max_smt) {
+        fprintf(stderr, "Cannot support more than %d threads on PPC with %s\n",
+                max_smt, kvm_enabled() ? "KVM" : "TCG");
+        exit(1);
+    }
+#endif
 
     if (kvm_enabled()) {
         if (kvmppc_fixup_cpu(cpu) != 0) {
commit 293c867d8c7399d17e6b593053411a6515171f38
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jan 23 23:04:05 2013 +0000

    cuda: Move ADB bus into CUDA state
    
    Replace the global adb_bus with a CUDA-internal one, accessed using
    regular qdev child bus accessor.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/adb.h b/hw/adb.h
index 2fe981f..721f1ac 100644
--- a/hw/adb.h
+++ b/hw/adb.h
@@ -84,5 +84,4 @@ int adb_poll(ADBBusState *s, uint8_t *buf_out);
 #define TYPE_ADB_KEYBOARD "adb-keyboard"
 #define TYPE_ADB_MOUSE "adb-mouse"
 
-extern ADBBusState adb_bus;
 #endif /* !defined(__ADB_H__) */
diff --git a/hw/cuda.c b/hw/cuda.c
index b3a875c..b36c535 100644
--- a/hw/cuda.c
+++ b/hw/cuda.c
@@ -108,8 +108,6 @@
 /* CUDA returns time_t's offset from Jan 1, 1904, not 1970 */
 #define RTC_OFFSET                      2082844800
 
-ADBBusState adb_bus;
-
 static void cuda_update(CUDAState *s);
 static void cuda_receive_packet_from_host(CUDAState *s,
                                           const uint8_t *data, int len);
@@ -459,7 +457,7 @@ static void cuda_adb_poll(void *opaque)
     uint8_t obuf[ADB_MAX_OUT_LEN + 2];
     int olen;
 
-    olen = adb_poll(&adb_bus, obuf + 2);
+    olen = adb_poll(&s->adb_bus, obuf + 2);
     if (olen > 0) {
         obuf[0] = ADB_PACKET;
         obuf[1] = 0x40; /* polled data */
@@ -555,7 +553,7 @@ static void cuda_receive_packet_from_host(CUDAState *s,
         {
             uint8_t obuf[ADB_MAX_OUT_LEN + 2];
             int olen;
-            olen = adb_request(&adb_bus, obuf + 2, data + 1, len - 1);
+            olen = adb_request(&s->adb_bus, obuf + 2, data + 1, len - 1);
             if (olen > 0) {
                 obuf[0] = ADB_PACKET;
                 obuf[1] = 0x00;
@@ -713,7 +711,7 @@ static void cuda_initfn(Object *obj)
         s->timers[i].index = i;
     }
 
-    qbus_create_inplace((BusState *)&adb_bus, TYPE_ADB_BUS, DEVICE(obj),
+    qbus_create_inplace((BusState *)&s->adb_bus, TYPE_ADB_BUS, DEVICE(obj),
                         "adb.0");
 }
 
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
index 26cb497..b17107b 100644
--- a/hw/ppc/mac.h
+++ b/hw/ppc/mac.h
@@ -28,6 +28,7 @@
 #include "exec/memory.h"
 #include "hw/sysbus.h"
 #include "hw/ide/internal.h"
+#include "hw/adb.h"
 
 /* SMP is not enabled, for now */
 #define MAX_CPUS 1
@@ -93,6 +94,7 @@ typedef struct CUDAState {
     uint8_t ier;
     uint8_t anh;
 
+    ADBBusState adb_bus;
     CUDATimer timers[2];
 
     uint32_t tick_offset;
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 2892b36..6de810b 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -149,6 +149,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
     PCIBus *pci_bus;
     PCIDevice *macio;
     MACIOIDEState *macio_ide;
+    BusState *adb_bus;
     MacIONVRAMState *nvr;
     int bios_size;
     MemoryRegion *pic_mem, *escc_mem;
@@ -381,9 +382,11 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
                                                         "ide[1]"));
     macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]);
 
-    dev = qdev_create(BUS(&adb_bus), TYPE_ADB_KEYBOARD);
+    dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda"));
+    adb_bus = qdev_get_child_bus(dev, "adb.0");
+    dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD);
     qdev_init_nofail(dev);
-    dev = qdev_create(BUS(&adb_bus), TYPE_ADB_MOUSE);
+    dev = qdev_create(adb_bus, TYPE_ADB_MOUSE);
     qdev_init_nofail(dev);
 
     if (usb_enabled(machine_arch == ARCH_MAC99_U3)) {
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 59b7199..9ed303a 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -92,6 +92,7 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
     PCIDevice *macio;
     MACIOIDEState *macio_ide;
     DeviceState *dev;
+    BusState *adb_bus;
     int bios_size;
     MemoryRegion *pic_mem;
     MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1);
@@ -281,9 +282,11 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
     hd[3] = hd[2] = NULL;
     pci_cmd646_ide_init(pci_bus, hd, 0);
 
-    dev = qdev_create(BUS(&adb_bus), TYPE_ADB_KEYBOARD);
+    dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda"));
+    adb_bus = qdev_get_child_bus(dev, "adb.0");
+    dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD);
     qdev_init_nofail(dev);
-    dev = qdev_create(BUS(&adb_bus), TYPE_ADB_MOUSE);
+    dev = qdev_create(adb_bus, TYPE_ADB_MOUSE);
     qdev_init_nofail(dev);
 
     if (usb_enabled(false)) {
commit 2e4a7c9c5df442d4223e738f7e8f73192b8b2a65
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jan 23 23:04:04 2013 +0000

    adb: QOM'ify ADB devices
    
    They were not qdev'ified before. Derive ADBDevice from DeviceState and
    convert reset callbacks to DeviceClass::reset, ADBDevice::opaque pointer
    to ADBDevice subtypes for mouse and keyboard and adb_{kbd,mouse}_init()
    to regular qdev functions.
    
    Fixing Coding Style issues and splitting keyboard and mouse off into
    their own files is left for a later point in time.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/adb.c b/hw/adb.c
index 5d46f59..6cf5465 100644
--- a/hw/adb.c
+++ b/hw/adb.c
@@ -48,16 +48,21 @@ do { printf("ADB: " fmt , ## __VA_ARGS__); } while (0)
 #define ADB_CMD_CHANGE_ID_AND_ENABLE	0x00
 
 /* ADB default device IDs (upper 4 bits of ADB command byte) */
-#define ADB_DONGLE	1
-#define ADB_KEYBOARD	2
-#define ADB_MOUSE	3
-#define ADB_TABLET	4
-#define ADB_MODEM	5
-#define ADB_MISC	7
+#define ADB_DEVID_DONGLE   1
+#define ADB_DEVID_KEYBOARD 2
+#define ADB_DEVID_MOUSE    3
+#define ADB_DEVID_TABLET   4
+#define ADB_DEVID_MODEM    5
+#define ADB_DEVID_MISC     7
 
 /* error codes */
 #define ADB_RET_NOTPRESENT (-2)
 
+static void adb_device_reset(ADBDevice *d)
+{
+    qdev_reset_all(DEVICE(d));
+}
+
 int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
 {
     ADBDevice *d;
@@ -66,18 +71,17 @@ int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
     cmd = buf[0] & 0xf;
     if (cmd == ADB_BUSRESET) {
         for(i = 0; i < s->nb_devices; i++) {
-            d = &s->devices[i];
-            if (d->devreset) {
-                d->devreset(d);
-            }
+            d = s->devices[i];
+            adb_device_reset(d);
         }
         return 0;
     }
     devaddr = buf[0] >> 4;
     for(i = 0; i < s->nb_devices; i++) {
-        d = &s->devices[i];
+        d = s->devices[i];
         if (d->devaddr == devaddr) {
-            return d->devreq(d, obuf, buf, len);
+            ADBDeviceClass *adc = ADB_DEVICE_GET_CLASS(d);
+            return adc->devreq(d, obuf, buf, len);
         }
     }
     return ADB_RET_NOTPRESENT;
@@ -94,7 +98,7 @@ int adb_poll(ADBBusState *s, uint8_t *obuf)
     for(i = 0; i < s->nb_devices; i++) {
         if (s->poll_index >= s->nb_devices)
             s->poll_index = 0;
-        d = &s->devices[s->poll_index];
+        d = s->devices[s->poll_index];
         buf[0] = ADB_READREG | (d->devaddr << 4);
         olen = adb_request(s, obuf + 1, buf, 1);
         /* if there is data, we poll again the same device */
@@ -108,38 +112,67 @@ int adb_poll(ADBBusState *s, uint8_t *obuf)
     return olen;
 }
 
-static ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
-                                      ADBDeviceRequest *devreq,
-                                      ADBDeviceReset *devreset,
-                                      void *opaque)
-{
-    ADBDevice *d;
-    if (s->nb_devices >= MAX_ADB_DEVICES)
-        return NULL;
-    d = &s->devices[s->nb_devices++];
-    d->bus = s;
-    d->devaddr = devaddr;
-    d->devreq = devreq;
-    d->devreset = devreset;
-    d->opaque = opaque;
-    qemu_register_reset((QEMUResetHandler *)devreset, d);
-    return d;
-}
-
 static const TypeInfo adb_bus_type_info = {
     .name = TYPE_ADB_BUS,
     .parent = TYPE_BUS,
     .instance_size = sizeof(ADBBusState),
 };
 
+static void adb_device_realizefn(DeviceState *dev, Error **errp)
+{
+    ADBDevice *d = ADB_DEVICE(dev);
+    ADBBusState *bus = ADB_BUS(qdev_get_parent_bus(dev));
+
+    if (bus->nb_devices >= MAX_ADB_DEVICES) {
+        return;
+    }
+
+    bus->devices[bus->nb_devices++] = d;
+}
+
+static void adb_device_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = adb_device_realizefn;
+    dc->bus_type = TYPE_ADB_BUS;
+}
+
+static const TypeInfo adb_device_type_info = {
+    .name = TYPE_ADB_DEVICE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(ADBDevice),
+    .abstract = true,
+    .class_init = adb_device_class_init,
+};
+
 /***************************************************************/
 /* Keyboard ADB device */
 
+#define ADB_KEYBOARD(obj) OBJECT_CHECK(KBDState, (obj), TYPE_ADB_KEYBOARD)
+
 typedef struct KBDState {
+    /*< private >*/
+    ADBDevice parent_obj;
+    /*< public >*/
+
     uint8_t data[128];
     int rptr, wptr, count;
 } KBDState;
 
+#define ADB_KEYBOARD_CLASS(class) \
+    OBJECT_CLASS_CHECK(ADBKeyboardClass, (class), TYPE_ADB_KEYBOARD)
+#define ADB_KEYBOARD_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(ADBKeyboardClass, (obj), TYPE_ADB_KEYBOARD)
+
+typedef struct ADBKeyboardClass {
+    /*< private >*/
+    ADBDeviceClass parent_class;
+    /*< public >*/
+
+    DeviceRealize parent_realize;
+} ADBKeyboardClass;
+
 static const uint8_t pc_to_adb_keycode[256] = {
   0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
  12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54,  0,  1,
@@ -161,8 +194,7 @@ static const uint8_t pc_to_adb_keycode[256] = {
 
 static void adb_kbd_put_keycode(void *opaque, int keycode)
 {
-    ADBDevice *d = opaque;
-    KBDState *s = d->opaque;
+    KBDState *s = opaque;
 
     if (s->count < sizeof(s->data)) {
         s->data[s->wptr] = keycode;
@@ -175,7 +207,7 @@ static void adb_kbd_put_keycode(void *opaque, int keycode)
 static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
 {
     static int ext_keycode;
-    KBDState *s = d->opaque;
+    KBDState *s = ADB_KEYBOARD(d);
     int adb_keycode, keycode;
     int olen;
 
@@ -209,7 +241,7 @@ static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
 static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
                            const uint8_t *buf, int len)
 {
-    KBDState *s = d->opaque;
+    KBDState *s = ADB_KEYBOARD(d);
     int cmd, reg, olen;
 
     if ((buf[0] & 0x0f) == ADB_FLUSH) {
@@ -281,41 +313,90 @@ static const VMStateDescription vmstate_adb_kbd = {
     }
 };
 
-static int adb_kbd_reset(ADBDevice *d)
+static void adb_kbd_reset(DeviceState *dev)
 {
-    KBDState *s = d->opaque;
+    ADBDevice *d = ADB_DEVICE(dev);
+    KBDState *s = ADB_KEYBOARD(dev);
 
     d->handler = 1;
-    d->devaddr = ADB_KEYBOARD;
-    memset(s, 0, sizeof(KBDState));
-
-    return 0;
+    d->devaddr = ADB_DEVID_KEYBOARD;
+    memset(s->data, 0, sizeof(s->data));
+    s->rptr = 0;
+    s->wptr = 0;
+    s->count = 0;
 }
 
-void adb_kbd_init(ADBBusState *bus)
+static void adb_kbd_realizefn(DeviceState *dev, Error **errp)
 {
-    ADBDevice *d;
-    KBDState *s;
-    s = g_malloc0(sizeof(KBDState));
-    d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
-                            adb_kbd_reset, s);
+    ADBDevice *d = ADB_DEVICE(dev);
+    ADBKeyboardClass *akc = ADB_KEYBOARD_GET_CLASS(dev);
+
+    akc->parent_realize(dev, errp);
+
     qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
-    vmstate_register(NULL, -1, &vmstate_adb_kbd, s);
 }
 
+static void adb_kbd_initfn(Object *obj)
+{
+    ADBDevice *d = ADB_DEVICE(obj);
+
+    d->devaddr = ADB_DEVID_KEYBOARD;
+}
+
+static void adb_kbd_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+    ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
+    ADBKeyboardClass *akc = ADB_KEYBOARD_CLASS(oc);
+
+    akc->parent_realize = dc->realize;
+    dc->realize = adb_kbd_realizefn;
+
+    adc->devreq = adb_kbd_request;
+    dc->reset = adb_kbd_reset;
+    dc->vmsd = &vmstate_adb_kbd;
+}
+
+static const TypeInfo adb_kbd_type_info = {
+    .name = TYPE_ADB_KEYBOARD,
+    .parent = TYPE_ADB_DEVICE,
+    .instance_size = sizeof(KBDState),
+    .instance_init = adb_kbd_initfn,
+    .class_init = adb_kbd_class_init,
+    .class_size = sizeof(ADBKeyboardClass),
+};
+
 /***************************************************************/
 /* Mouse ADB device */
 
+#define ADB_MOUSE(obj) OBJECT_CHECK(MouseState, (obj), TYPE_ADB_MOUSE)
+
 typedef struct MouseState {
+    /*< public >*/
+    ADBDevice parent_obj;
+    /*< private >*/
+
     int buttons_state, last_buttons_state;
     int dx, dy, dz;
 } MouseState;
 
+#define ADB_MOUSE_CLASS(class) \
+    OBJECT_CLASS_CHECK(ADBMouseClass, (class), TYPE_ADB_MOUSE)
+#define ADB_MOUSE_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(ADBMouseClass, (obj), TYPE_ADB_MOUSE)
+
+typedef struct ADBMouseClass {
+    /*< public >*/
+    ADBDeviceClass parent_class;
+    /*< private >*/
+
+    DeviceRealize parent_realize;
+} ADBMouseClass;
+
 static void adb_mouse_event(void *opaque,
                             int dx1, int dy1, int dz1, int buttons_state)
 {
-    ADBDevice *d = opaque;
-    MouseState *s = d->opaque;
+    MouseState *s = opaque;
 
     s->dx += dx1;
     s->dy += dy1;
@@ -326,7 +407,7 @@ static void adb_mouse_event(void *opaque,
 
 static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
 {
-    MouseState *s = d->opaque;
+    MouseState *s = ADB_MOUSE(d);
     int dx, dy;
 
     if (s->last_buttons_state == s->buttons_state &&
@@ -365,7 +446,7 @@ static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
 static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
                              const uint8_t *buf, int len)
 {
-    MouseState *s = d->opaque;
+    MouseState *s = ADB_MOUSE(d);
     int cmd, reg, olen;
 
     if ((buf[0] & 0x0f) == ADB_FLUSH) {
@@ -422,15 +503,15 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
     return olen;
 }
 
-static int adb_mouse_reset(ADBDevice *d)
+static void adb_mouse_reset(DeviceState *dev)
 {
-    MouseState *s = d->opaque;
+    ADBDevice *d = ADB_DEVICE(dev);
+    MouseState *s = ADB_MOUSE(dev);
 
     d->handler = 2;
-    d->devaddr = ADB_MOUSE;
-    memset(s, 0, sizeof(MouseState));
-
-    return 0;
+    d->devaddr = ADB_DEVID_MOUSE;
+    s->last_buttons_state = s->buttons_state = 0;
+    s->dx = s->dy = s->dz = 0;
 }
 
 static const VMStateDescription vmstate_adb_mouse = {
@@ -448,22 +529,53 @@ static const VMStateDescription vmstate_adb_mouse = {
     }
 };
 
-void adb_mouse_init(ADBBusState *bus)
+static void adb_mouse_realizefn(DeviceState *dev, Error **errp)
 {
-    ADBDevice *d;
-    MouseState *s;
+    MouseState *s = ADB_MOUSE(dev);
+    ADBMouseClass *amc = ADB_MOUSE_GET_CLASS(dev);
+
+    amc->parent_realize(dev, errp);
+
+    qemu_add_mouse_event_handler(adb_mouse_event, s, 0, "QEMU ADB Mouse");
+}
+
+static void adb_mouse_initfn(Object *obj)
+{
+    ADBDevice *d = ADB_DEVICE(obj);
 
-    s = g_malloc0(sizeof(MouseState));
-    d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request,
-                            adb_mouse_reset, s);
-    qemu_add_mouse_event_handler(adb_mouse_event, d, 0, "QEMU ADB Mouse");
-    vmstate_register(NULL, -1, &vmstate_adb_mouse, s);
+    d->devaddr = ADB_DEVID_MOUSE;
 }
 
+static void adb_mouse_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+    ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
+    ADBMouseClass *amc = ADB_MOUSE_CLASS(oc);
+
+    amc->parent_realize = dc->realize;
+    dc->realize = adb_mouse_realizefn;
+
+    adc->devreq = adb_mouse_request;
+    dc->reset = adb_mouse_reset;
+    dc->vmsd = &vmstate_adb_mouse;
+}
+
+static const TypeInfo adb_mouse_type_info = {
+    .name = TYPE_ADB_MOUSE,
+    .parent = TYPE_ADB_DEVICE,
+    .instance_size = sizeof(MouseState),
+    .instance_init = adb_mouse_initfn,
+    .class_init = adb_mouse_class_init,
+    .class_size = sizeof(ADBMouseClass),
+};
+
 
 static void adb_register_types(void)
 {
     type_register_static(&adb_bus_type_info);
+    type_register_static(&adb_device_type_info);
+    type_register_static(&adb_kbd_type_info);
+    type_register_static(&adb_mouse_type_info);
 }
 
 type_init(adb_register_types)
diff --git a/hw/adb.h b/hw/adb.h
index c23f804..2fe981f 100644
--- a/hw/adb.h
+++ b/hw/adb.h
@@ -38,17 +38,32 @@ typedef struct ADBDevice ADBDevice;
 /* buf = NULL means polling */
 typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out,
                               const uint8_t *buf, int len);
-typedef int ADBDeviceReset(ADBDevice *d);
+
+#define TYPE_ADB_DEVICE "adb-device"
+#define ADB_DEVICE(obj) OBJECT_CHECK(ADBDevice, (obj), TYPE_ADB_DEVICE)
 
 struct ADBDevice {
-    ADBBusState *bus;
+    /*< private >*/
+    DeviceState parent_obj;
+    /*< public >*/
+
     int devaddr;
     int handler;
-    ADBDeviceRequest *devreq;
-    ADBDeviceReset *devreset;
-    void *opaque;
 };
 
+#define ADB_DEVICE_CLASS(cls) \
+    OBJECT_CLASS_CHECK(ADBDeviceClass, (cls), TYPE_ADB_DEVICE)
+#define ADB_DEVICE_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(ADBDeviceClass, (obj), TYPE_ADB_DEVICE)
+
+typedef struct ADBDeviceClass {
+    /*< private >*/
+    DeviceClass parent_class;
+    /*< public >*/
+
+    ADBDeviceRequest *devreq;
+} ADBDeviceClass;
+
 #define TYPE_ADB_BUS "apple-desktop-bus"
 #define ADB_BUS(obj) OBJECT_CHECK(ADBBusState, (obj), TYPE_ADB_BUS)
 
@@ -57,7 +72,7 @@ struct ADBBusState {
     BusState parent_obj;
     /*< public >*/
 
-    ADBDevice devices[MAX_ADB_DEVICES];
+    ADBDevice *devices[MAX_ADB_DEVICES];
     int nb_devices;
     int poll_index;
 };
@@ -66,8 +81,8 @@ int adb_request(ADBBusState *s, uint8_t *buf_out,
                 const uint8_t *buf, int len);
 int adb_poll(ADBBusState *s, uint8_t *buf_out);
 
-void adb_kbd_init(ADBBusState *bus);
-void adb_mouse_init(ADBBusState *bus);
+#define TYPE_ADB_KEYBOARD "adb-keyboard"
+#define TYPE_ADB_MOUSE "adb-mouse"
 
 extern ADBBusState adb_bus;
 #endif /* !defined(__ADB_H__) */
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index b9c58c1..2892b36 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -381,8 +381,10 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
                                                         "ide[1]"));
     macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]);
 
-    adb_kbd_init(&adb_bus);
-    adb_mouse_init(&adb_bus);
+    dev = qdev_create(BUS(&adb_bus), TYPE_ADB_KEYBOARD);
+    qdev_init_nofail(dev);
+    dev = qdev_create(BUS(&adb_bus), TYPE_ADB_MOUSE);
+    qdev_init_nofail(dev);
 
     if (usb_enabled(machine_arch == ARCH_MAC99_U3)) {
         pci_create_simple(pci_bus, -1, "pci-ohci");
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 9d9212a..59b7199 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -281,8 +281,10 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
     hd[3] = hd[2] = NULL;
     pci_cmd646_ide_init(pci_bus, hd, 0);
 
-    adb_kbd_init(&adb_bus);
-    adb_mouse_init(&adb_bus);
+    dev = qdev_create(BUS(&adb_bus), TYPE_ADB_KEYBOARD);
+    qdev_init_nofail(dev);
+    dev = qdev_create(BUS(&adb_bus), TYPE_ADB_MOUSE);
+    qdev_init_nofail(dev);
 
     if (usb_enabled(false)) {
         pci_create_simple(pci_bus, -1, "pci-ohci");
commit 84ede329083b649c54f078276e7e06d48e910b9d
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jan 23 23:04:03 2013 +0000

    adb: QOM'ify Apple Desktop Bus
    
    It was not a qbus before, turn it into a first-class bus and initialize
    it properly from CUDA. Leave it a global variable as long as devices are
    not QOM'ified yet.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/adb.c b/hw/adb.c
index cc8ad8e..5d46f59 100644
--- a/hw/adb.c
+++ b/hw/adb.c
@@ -126,6 +126,12 @@ static ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
     return d;
 }
 
+static const TypeInfo adb_bus_type_info = {
+    .name = TYPE_ADB_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(ADBBusState),
+};
+
 /***************************************************************/
 /* Keyboard ADB device */
 
@@ -453,3 +459,11 @@ void adb_mouse_init(ADBBusState *bus)
     qemu_add_mouse_event_handler(adb_mouse_event, d, 0, "QEMU ADB Mouse");
     vmstate_register(NULL, -1, &vmstate_adb_mouse, s);
 }
+
+
+static void adb_register_types(void)
+{
+    type_register_static(&adb_bus_type_info);
+}
+
+type_init(adb_register_types)
diff --git a/hw/adb.h b/hw/adb.h
index 5b27da2..c23f804 100644
--- a/hw/adb.h
+++ b/hw/adb.h
@@ -26,10 +26,13 @@
 #if !defined(__ADB_H__)
 #define __ADB_H__
 
+#include "qdev.h"
+
 #define MAX_ADB_DEVICES 16
 
 #define ADB_MAX_OUT_LEN 16
 
+typedef struct ADBBusState ADBBusState;
 typedef struct ADBDevice ADBDevice;
 
 /* buf = NULL means polling */
@@ -38,7 +41,7 @@ typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out,
 typedef int ADBDeviceReset(ADBDevice *d);
 
 struct ADBDevice {
-    struct ADBBusState *bus;
+    ADBBusState *bus;
     int devaddr;
     int handler;
     ADBDeviceRequest *devreq;
@@ -46,11 +49,18 @@ struct ADBDevice {
     void *opaque;
 };
 
-typedef struct ADBBusState {
+#define TYPE_ADB_BUS "apple-desktop-bus"
+#define ADB_BUS(obj) OBJECT_CHECK(ADBBusState, (obj), TYPE_ADB_BUS)
+
+struct ADBBusState {
+    /*< private >*/
+    BusState parent_obj;
+    /*< public >*/
+
     ADBDevice devices[MAX_ADB_DEVICES];
     int nb_devices;
     int poll_index;
-} ADBBusState;
+};
 
 int adb_request(ADBBusState *s, uint8_t *buf_out,
                 const uint8_t *buf, int len);
diff --git a/hw/cuda.c b/hw/cuda.c
index f863c38..b3a875c 100644
--- a/hw/cuda.c
+++ b/hw/cuda.c
@@ -712,6 +712,9 @@ static void cuda_initfn(Object *obj)
     for (i = 0; i < ARRAY_SIZE(s->timers); i++) {
         s->timers[i].index = i;
     }
+
+    qbus_create_inplace((BusState *)&adb_bus, TYPE_ADB_BUS, DEVICE(obj),
+                        "adb.0");
 }
 
 static void cuda_class_init(ObjectClass *oc, void *data)
commit 45fa67fb68e73b395cd93ec97e45785944d4ee6a
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jan 23 23:04:02 2013 +0000

    cuda: QOM'ify CUDA
    
    It was not qdev'ified before. Turn it into a SysBusDevice and embed it
    in MacIO.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/cuda.c b/hw/cuda.c
index bbd1fda..f863c38 100644
--- a/hw/cuda.c
+++ b/hw/cuda.c
@@ -108,48 +108,6 @@
 /* CUDA returns time_t's offset from Jan 1, 1904, not 1970 */
 #define RTC_OFFSET                      2082844800
 
-typedef struct CUDATimer {
-    int index;
-    uint16_t latch;
-    uint16_t counter_value; /* counter value at load time */
-    int64_t load_time;
-    int64_t next_irq_time;
-    QEMUTimer *timer;
-} CUDATimer;
-
-typedef struct CUDAState {
-    MemoryRegion mem;
-    /* cuda registers */
-    uint8_t b;      /* B-side data */
-    uint8_t a;      /* A-side data */
-    uint8_t dirb;   /* B-side direction (1=output) */
-    uint8_t dira;   /* A-side direction (1=output) */
-    uint8_t sr;     /* Shift register */
-    uint8_t acr;    /* Auxiliary control register */
-    uint8_t pcr;    /* Peripheral control register */
-    uint8_t ifr;    /* Interrupt flag register */
-    uint8_t ier;    /* Interrupt enable register */
-    uint8_t anh;    /* A-side data, no handshake */
-
-    CUDATimer timers[2];
-
-    uint32_t tick_offset;
-
-    uint8_t last_b; /* last value of B register */
-    uint8_t last_acr; /* last value of B register */
-
-    int data_in_size;
-    int data_in_index;
-    int data_out_index;
-
-    qemu_irq irq;
-    uint8_t autopoll;
-    uint8_t data_in[128];
-    uint8_t data_out[16];
-    QEMUTimer *adb_poll_timer;
-} CUDAState;
-
-static CUDAState cuda_state;
 ADBBusState adb_bus;
 
 static void cuda_update(CUDAState *s);
@@ -701,9 +659,9 @@ static const VMStateDescription vmstate_cuda = {
     }
 };
 
-static void cuda_reset(void *opaque)
+static void cuda_reset(DeviceState *dev)
 {
-    CUDAState *s = opaque;
+    CUDAState *s = CUDA(dev);
 
     s->b = 0;
     s->a = 0;
@@ -728,25 +686,54 @@ static void cuda_reset(void *opaque)
     set_counter(s, &s->timers[1], 0xffff);
 }
 
-void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq)
+static void cuda_realizefn(DeviceState *dev, Error **errp)
 {
+    CUDAState *s = CUDA(dev);
     struct tm tm;
-    CUDAState *s = &cuda_state;
-
-    s->irq = irq;
 
-    s->timers[0].index = 0;
     s->timers[0].timer = qemu_new_timer_ns(vm_clock, cuda_timer1, s);
 
-    s->timers[1].index = 1;
-
     qemu_get_timedate(&tm, 0);
     s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
 
     s->adb_poll_timer = qemu_new_timer_ns(vm_clock, cuda_adb_poll, s);
+}
+
+static void cuda_initfn(Object *obj)
+{
+    SysBusDevice *d = SYS_BUS_DEVICE(obj);
+    CUDAState *s = CUDA(obj);
+    int i;
+
     memory_region_init_io(&s->mem, &cuda_ops, s, "cuda", 0x2000);
+    sysbus_init_mmio(d, &s->mem);
+    sysbus_init_irq(d, &s->irq);
+
+    for (i = 0; i < ARRAY_SIZE(s->timers); i++) {
+        s->timers[i].index = i;
+    }
+}
+
+static void cuda_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
 
-    *cuda_mem = &s->mem;
-    vmstate_register(NULL, -1, &vmstate_cuda, s);
-    qemu_register_reset(cuda_reset, s);
+    dc->realize = cuda_realizefn;
+    dc->reset = cuda_reset;
+    dc->vmsd = &vmstate_cuda;
 }
+
+static const TypeInfo cuda_type_info = {
+    .name = TYPE_CUDA,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(CUDAState),
+    .instance_init = cuda_initfn,
+    .class_init = cuda_class_init,
+};
+
+static void cuda_register_types(void)
+{
+    type_register_static(&cuda_type_info);
+}
+
+type_init(cuda_register_types)
diff --git a/hw/macio.c b/hw/macio.c
index 36c00e3..74bdcd1 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -38,9 +38,9 @@ typedef struct MacIOState
     /*< public >*/
 
     MemoryRegion bar;
+    CUDAState cuda;
     void *dbdma;
     MemoryRegion *pic_mem;
-    MemoryRegion *cuda_mem;
     MemoryRegion *escc_mem;
 } MacIOState;
 
@@ -52,7 +52,7 @@ typedef struct OldWorldMacIOState {
     MacIOState parent_obj;
     /*< public >*/
 
-    qemu_irq irqs[2];
+    qemu_irq irqs[3];
 
     MacIONVRAMState nvram;
     MACIOIDEState ide;
@@ -65,7 +65,7 @@ typedef struct NewWorldMacIOState {
     /*< private >*/
     MacIOState parent_obj;
     /*< public >*/
-    qemu_irq irqs[4];
+    qemu_irq irqs[5];
     MACIOIDEState ide[2];
 } NewWorldMacIOState;
 
@@ -76,17 +76,24 @@ static void macio_bar_setup(MacIOState *macio_state)
     if (macio_state->escc_mem) {
         memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem);
     }
-    if (macio_state->cuda_mem) {
-        memory_region_add_subregion(bar, 0x16000, macio_state->cuda_mem);
-    }
 }
 
 static int macio_common_initfn(PCIDevice *d)
 {
     MacIOState *s = MACIO(d);
+    SysBusDevice *sysbus_dev;
+    int ret;
 
     d->config[0x3d] = 0x01; // interrupt on pin 1
 
+    ret = qdev_init(DEVICE(&s->cuda));
+    if (ret < 0) {
+        return ret;
+    }
+    sysbus_dev = SYS_BUS_DEVICE(&s->cuda);
+    memory_region_add_subregion(&s->bar, 0x16000,
+                                sysbus_mmio_get_region(sysbus_dev, 0));
+
     macio_bar_setup(s);
     pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
 
@@ -103,6 +110,9 @@ static int macio_oldworld_initfn(PCIDevice *d)
         return ret;
     }
 
+    sysbus_dev = SYS_BUS_DEVICE(&s->cuda);
+    sysbus_connect_irq(sysbus_dev, 0, os->irqs[0]);
+
     ret = qdev_init(DEVICE(&os->nvram));
     if (ret < 0) {
         return ret;
@@ -118,8 +128,8 @@ static int macio_oldworld_initfn(PCIDevice *d)
     }
 
     sysbus_dev = SYS_BUS_DEVICE(&os->ide);
-    sysbus_connect_irq(sysbus_dev, 0, os->irqs[0]);
-    sysbus_connect_irq(sysbus_dev, 1, os->irqs[1]);
+    sysbus_connect_irq(sysbus_dev, 0, os->irqs[1]);
+    sysbus_connect_irq(sysbus_dev, 1, os->irqs[2]);
     macio_ide_register_dma(&os->ide, s->dbdma, 0x16);
     ret = qdev_init(DEVICE(&os->ide));
     if (ret < 0) {
@@ -158,14 +168,17 @@ static int macio_newworld_initfn(PCIDevice *d)
         return ret;
     }
 
+    sysbus_dev = SYS_BUS_DEVICE(&s->cuda);
+    sysbus_connect_irq(sysbus_dev, 0, ns->irqs[0]);
+
     if (s->pic_mem) {
         /* OpenPIC */
         memory_region_add_subregion(&s->bar, 0x40000, s->pic_mem);
     }
 
     sysbus_dev = SYS_BUS_DEVICE(&ns->ide[0]);
-    sysbus_connect_irq(sysbus_dev, 0, ns->irqs[0]);
-    sysbus_connect_irq(sysbus_dev, 1, ns->irqs[1]);
+    sysbus_connect_irq(sysbus_dev, 0, ns->irqs[1]);
+    sysbus_connect_irq(sysbus_dev, 1, ns->irqs[2]);
     macio_ide_register_dma(&ns->ide[0], s->dbdma, 0x16);
     ret = qdev_init(DEVICE(&ns->ide[0]));
     if (ret < 0) {
@@ -173,8 +186,8 @@ static int macio_newworld_initfn(PCIDevice *d)
     }
 
     sysbus_dev = SYS_BUS_DEVICE(&ns->ide[1]);
-    sysbus_connect_irq(sysbus_dev, 0, ns->irqs[2]);
-    sysbus_connect_irq(sysbus_dev, 1, ns->irqs[3]);
+    sysbus_connect_irq(sysbus_dev, 0, ns->irqs[3]);
+    sysbus_connect_irq(sysbus_dev, 1, ns->irqs[4]);
     macio_ide_register_dma(&ns->ide[0], s->dbdma, 0x1a);
     ret = qdev_init(DEVICE(&ns->ide[1]));
     if (ret < 0) {
@@ -211,6 +224,10 @@ static void macio_instance_init(Object *obj)
 
     memory_region_init(&s->bar, "macio", 0x80000);
 
+    object_initialize(&s->cuda, TYPE_CUDA);
+    qdev_set_parent_bus(DEVICE(&s->cuda), sysbus_get_default());
+    object_property_add_child(obj, "cuda", OBJECT(&s->cuda), NULL);
+
     s->dbdma = DBDMA_init(&dbdma_mem);
     memory_region_add_subregion(&s->bar, 0x08000, dbdma_mem);
 }
@@ -275,13 +292,11 @@ type_init(macio_register_types)
 
 void macio_init(PCIDevice *d,
                 MemoryRegion *pic_mem,
-                MemoryRegion *cuda_mem,
                 MemoryRegion *escc_mem)
 {
     MacIOState *macio_state = MACIO(d);
 
     macio_state->pic_mem = pic_mem;
-    macio_state->cuda_mem = cuda_mem;
     macio_state->escc_mem = escc_mem;
     /* Note: this code is strongly inspirated from the corresponding code
        in PearPC */
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
index 3e390d3..26cb497 100644
--- a/hw/ppc/mac.h
+++ b/hw/ppc/mac.h
@@ -44,7 +44,72 @@
 #define ESCC_CLOCK 3686400
 
 /* Cuda */
-void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq);
+#define TYPE_CUDA "cuda"
+#define CUDA(obj) OBJECT_CHECK(CUDAState, (obj), TYPE_CUDA)
+
+/**
+ * CUDATimer:
+ * @counter_value: counter value at load time
+ */
+typedef struct CUDATimer {
+    int index;
+    uint16_t latch;
+    uint16_t counter_value;
+    int64_t load_time;
+    int64_t next_irq_time;
+    QEMUTimer *timer;
+} CUDATimer;
+
+/**
+ * CUDAState:
+ * @b: B-side data
+ * @a: A-side data
+ * @dirb: B-side direction (1=output)
+ * @dira: A-side direction (1=output)
+ * @sr: Shift register
+ * @acr: Auxiliary control register
+ * @pcr: Peripheral control register
+ * @ifr: Interrupt flag register
+ * @ier: Interrupt enable register
+ * @anh: A-side data, no handshake
+ * @last_b: last value of B register
+ * @last_acr: last value of ACR register
+ */
+typedef struct CUDAState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    MemoryRegion mem;
+    /* cuda registers */
+    uint8_t b;
+    uint8_t a;
+    uint8_t dirb;
+    uint8_t dira;
+    uint8_t sr;
+    uint8_t acr;
+    uint8_t pcr;
+    uint8_t ifr;
+    uint8_t ier;
+    uint8_t anh;
+
+    CUDATimer timers[2];
+
+    uint32_t tick_offset;
+
+    uint8_t last_b;
+    uint8_t last_acr;
+
+    int data_in_size;
+    int data_in_index;
+    int data_out_index;
+
+    qemu_irq irq;
+    uint8_t autopoll;
+    uint8_t data_in[128];
+    uint8_t data_out[16];
+    QEMUTimer *adb_poll_timer;
+} CUDAState;
 
 /* MacIO */
 #define TYPE_OLDWORLD_MACIO "macio-oldworld"
@@ -71,7 +136,6 @@ void macio_ide_register_dma(MACIOIDEState *ide, void *dbdma, int channel);
 
 void macio_init(PCIDevice *dev,
                 MemoryRegion *pic_mem,
-                MemoryRegion *cuda_mem,
                 MemoryRegion *escc_mem);
 
 /* Heathrow PIC */
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 4fd86b0..b9c58c1 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -151,7 +151,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
     MACIOIDEState *macio_ide;
     MacIONVRAMState *nvr;
     int bios_size;
-    MemoryRegion *pic_mem, *cuda_mem, *escc_mem;
+    MemoryRegion *pic_mem, *escc_mem;
     MemoryRegion *escc_bar = g_new(MemoryRegion, 1);
     int ppc_boot_device;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
@@ -363,18 +363,14 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
 
     ide_drive_get(hd, MAX_IDE_BUS);
 
-    cuda_init(&cuda_mem, pic[0x19]);
-
-    adb_kbd_init(&adb_bus);
-    adb_mouse_init(&adb_bus);
-
     macio = pci_create(pci_bus, -1, TYPE_NEWWORLD_MACIO);
     dev = DEVICE(macio);
-    qdev_connect_gpio_out(dev, 0, pic[0x0d]); /* IDE */
-    qdev_connect_gpio_out(dev, 1, pic[0x02]); /* IDE DMA */
-    qdev_connect_gpio_out(dev, 2, pic[0x0e]); /* IDE */
-    qdev_connect_gpio_out(dev, 3, pic[0x02]); /* IDE DMA */
-    macio_init(macio, pic_mem, cuda_mem, escc_bar);
+    qdev_connect_gpio_out(dev, 0, pic[0x19]); /* CUDA */
+    qdev_connect_gpio_out(dev, 1, pic[0x0d]); /* IDE */
+    qdev_connect_gpio_out(dev, 2, pic[0x02]); /* IDE DMA */
+    qdev_connect_gpio_out(dev, 3, pic[0x0e]); /* IDE */
+    qdev_connect_gpio_out(dev, 4, pic[0x02]); /* IDE DMA */
+    macio_init(macio, pic_mem, escc_bar);
 
     /* We only emulate 2 out of 3 IDE controllers for now */
     macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
@@ -385,6 +381,9 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
                                                         "ide[1]"));
     macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]);
 
+    adb_kbd_init(&adb_bus);
+    adb_mouse_init(&adb_bus);
+
     if (usb_enabled(machine_arch == ARCH_MAC99_U3)) {
         pci_create_simple(pci_bus, -1, "pci-ohci");
         /* U3 needs to use USB for input because Linux doesn't support via-cuda
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 6039ea6..9d9212a 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -93,7 +93,7 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
     MACIOIDEState *macio_ide;
     DeviceState *dev;
     int bios_size;
-    MemoryRegion *pic_mem, *cuda_mem;
+    MemoryRegion *pic_mem;
     MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1);
     uint16_t ppc_boot_device;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
@@ -263,17 +263,12 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
 
     ide_drive_get(hd, MAX_IDE_BUS);
 
-    /* cuda also initialize ADB */
-    cuda_init(&cuda_mem, pic[0x12]);
-
-    adb_kbd_init(&adb_bus);
-    adb_mouse_init(&adb_bus);
-
     macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO);
     dev = DEVICE(macio);
-    qdev_connect_gpio_out(dev, 0, pic[0x0D]); /* IDE */
-    qdev_connect_gpio_out(dev, 1, pic[0x02]); /* IDE DMA */
-    macio_init(macio, pic_mem, cuda_mem, escc_bar);
+    qdev_connect_gpio_out(dev, 0, pic[0x12]); /* CUDA */
+    qdev_connect_gpio_out(dev, 1, pic[0x0D]); /* IDE */
+    qdev_connect_gpio_out(dev, 2, pic[0x02]); /* IDE DMA */
+    macio_init(macio, pic_mem, escc_bar);
 
     /* First IDE channel is a MAC IDE on the MacIO bus */
     macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
@@ -286,6 +281,9 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
     hd[3] = hd[2] = NULL;
     pci_cmd646_ide_init(pci_bus, hd, 0);
 
+    adb_kbd_init(&adb_bus);
+    adb_mouse_init(&adb_bus);
+
     if (usb_enabled(false)) {
         pci_create_simple(pci_bus, -1, "pci-ohci");
     }
commit 07a7484e5d713f1eb7c1c37b18a8ab0d56d88875
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jan 23 23:04:01 2013 +0000

    ide/macio: QOM'ify MacIO IDE
    
    It was not qdev'ified before. Turn it into a SysBusDevice.
    Embed them into the MacIO devices.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/ide.h b/hw/ide.h
index 7e23cda..9b357c0 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -19,10 +19,6 @@ PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 
-/* ide-macio.c */
-MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
-		   void *dbdma, int channel, qemu_irq dma_irq);
-
 /* ide-mmio.c */
 void mmio_ide_init (hwaddr membase, hwaddr membase2,
                     MemoryRegion *address_space,
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index e0f04dc..375c46f 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -33,12 +33,6 @@
 /***********************************************************/
 /* MacIO based PowerPC IDE */
 
-typedef struct MACIOIDEState {
-    MemoryRegion mem;
-    IDEBus bus;
-    BlockDriverAIOCB *aiocb;
-} MACIOIDEState;
-
 #define MACIO_PAGE_SIZE 4096
 
 static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
@@ -321,30 +315,70 @@ static const VMStateDescription vmstate_pmac = {
     }
 };
 
-static void pmac_ide_reset(void *opaque)
+static void macio_ide_reset(DeviceState *dev)
 {
-    MACIOIDEState *d = opaque;
+    MACIOIDEState *d = MACIO_IDE(dev);
 
     ide_bus_reset(&d->bus);
 }
 
-/* hd_table must contain 4 block drivers */
-/* PowerMac uses memory mapped registers, not I/O. Return the memory
-   I/O index to access the ide. */
-MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
-                             void *dbdma, int channel, qemu_irq dma_irq)
+static void macio_ide_realizefn(DeviceState *dev, Error **errp)
 {
-    MACIOIDEState *d;
+    MACIOIDEState *s = MACIO_IDE(dev);
+
+    ide_init2(&s->bus, s->irq);
+}
+
+static void macio_ide_initfn(Object *obj)
+{
+    SysBusDevice *d = SYS_BUS_DEVICE(obj);
+    MACIOIDEState *s = MACIO_IDE(obj);
+
+    ide_bus_new(&s->bus, DEVICE(obj), 0);
+    memory_region_init_io(&s->mem, &pmac_ide_ops, s, "pmac-ide", 0x1000);
+    sysbus_init_mmio(d, &s->mem);
+    sysbus_init_irq(d, &s->irq);
+    sysbus_init_irq(d, &s->dma_irq);
+}
+
+static void macio_ide_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = macio_ide_realizefn;
+    dc->reset = macio_ide_reset;
+    dc->vmsd = &vmstate_pmac;
+}
 
-    d = g_malloc0(sizeof(MACIOIDEState));
-    ide_init2_with_non_qdev_drives(&d->bus, hd_table[0], hd_table[1], irq);
+static const TypeInfo macio_ide_type_info = {
+    .name = TYPE_MACIO_IDE,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MACIOIDEState),
+    .instance_init = macio_ide_initfn,
+    .class_init = macio_ide_class_init,
+};
 
-    if (dbdma)
-        DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, pmac_ide_flush, d);
+static void macio_ide_register_types(void)
+{
+    type_register_static(&macio_ide_type_info);
+}
 
-    memory_region_init_io(&d->mem, &pmac_ide_ops, d, "pmac-ide", 0x1000);
-    vmstate_register(NULL, 0, &vmstate_pmac, d);
-    qemu_register_reset(pmac_ide_reset, d);
+/* hd_table must contain 4 block drivers */
+void macio_ide_init_drives(MACIOIDEState *s, DriveInfo **hd_table)
+{
+    int i;
 
-    return &d->mem;
+    for (i = 0; i < 2; i++) {
+        if (hd_table[i]) {
+            ide_create_drive(&s->bus, i, hd_table[i]);
+        }
+    }
 }
+
+void macio_ide_register_dma(MACIOIDEState *s, void *dbdma, int channel)
+{
+    DBDMA_register_channel(dbdma, channel, s->dma_irq,
+                           pmac_ide_transfer, pmac_ide_flush, s);
+}
+
+type_init(macio_ide_register_types)
diff --git a/hw/macio.c b/hw/macio.c
index 32f359c..36c00e3 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -25,6 +25,7 @@
 #include "hw.h"
 #include "ppc/mac.h"
 #include "pci/pci.h"
+#include "mac_dbdma.h"
 #include "escc.h"
 
 #define TYPE_MACIO "macio"
@@ -37,12 +38,10 @@ typedef struct MacIOState
     /*< public >*/
 
     MemoryRegion bar;
+    void *dbdma;
     MemoryRegion *pic_mem;
-    MemoryRegion *dbdma_mem;
     MemoryRegion *cuda_mem;
     MemoryRegion *escc_mem;
-    int nb_ide;
-    MemoryRegion *ide_mem[4];
 } MacIOState;
 
 #define OLDWORLD_MACIO(obj) \
@@ -53,29 +52,33 @@ typedef struct OldWorldMacIOState {
     MacIOState parent_obj;
     /*< public >*/
 
+    qemu_irq irqs[2];
+
     MacIONVRAMState nvram;
+    MACIOIDEState ide;
 } OldWorldMacIOState;
 
+#define NEWWORLD_MACIO(obj) \
+    OBJECT_CHECK(NewWorldMacIOState, (obj), TYPE_NEWWORLD_MACIO)
+
+typedef struct NewWorldMacIOState {
+    /*< private >*/
+    MacIOState parent_obj;
+    /*< public >*/
+    qemu_irq irqs[4];
+    MACIOIDEState ide[2];
+} NewWorldMacIOState;
+
 static void macio_bar_setup(MacIOState *macio_state)
 {
-    int i;
     MemoryRegion *bar = &macio_state->bar;
 
-    if (macio_state->dbdma_mem) {
-        memory_region_add_subregion(bar, 0x08000, macio_state->dbdma_mem);
-    }
     if (macio_state->escc_mem) {
         memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem);
     }
     if (macio_state->cuda_mem) {
         memory_region_add_subregion(bar, 0x16000, macio_state->cuda_mem);
     }
-    for (i = 0; i < macio_state->nb_ide; i++) {
-        if (macio_state->ide_mem[i]) {
-            memory_region_add_subregion(bar, 0x1f000 + (i * 0x1000),
-                                        macio_state->ide_mem[i]);
-        }
-    }
 }
 
 static int macio_common_initfn(PCIDevice *d)
@@ -114,23 +117,42 @@ static int macio_oldworld_initfn(PCIDevice *d)
         memory_region_add_subregion(&s->bar, 0x00000, s->pic_mem);
     }
 
+    sysbus_dev = SYS_BUS_DEVICE(&os->ide);
+    sysbus_connect_irq(sysbus_dev, 0, os->irqs[0]);
+    sysbus_connect_irq(sysbus_dev, 1, os->irqs[1]);
+    macio_ide_register_dma(&os->ide, s->dbdma, 0x16);
+    ret = qdev_init(DEVICE(&os->ide));
+    if (ret < 0) {
+        return ret;
+    }
+
     return 0;
 }
 
 static void macio_oldworld_init(Object *obj)
 {
+    MacIOState *s = MACIO(obj);
     OldWorldMacIOState *os = OLDWORLD_MACIO(obj);
     DeviceState *dev;
 
+    qdev_init_gpio_out(DEVICE(obj), os->irqs, ARRAY_SIZE(os->irqs));
+
     object_initialize(&os->nvram, TYPE_MACIO_NVRAM);
     dev = DEVICE(&os->nvram);
     qdev_prop_set_uint32(dev, "size", 0x2000);
     qdev_prop_set_uint32(dev, "it_shift", 4);
+
+    object_initialize(&os->ide, TYPE_MACIO_IDE);
+    qdev_set_parent_bus(DEVICE(&os->ide), sysbus_get_default());
+    memory_region_add_subregion(&s->bar, 0x1f000 + (1 * 0x1000), &os->ide.mem);
+    object_property_add_child(obj, "ide", OBJECT(&os->ide), NULL);
 }
 
 static int macio_newworld_initfn(PCIDevice *d)
 {
     MacIOState *s = MACIO(d);
+    NewWorldMacIOState *ns = NEWWORLD_MACIO(d);
+    SysBusDevice *sysbus_dev;
     int ret = macio_common_initfn(d);
     if (ret < 0) {
         return ret;
@@ -141,14 +163,56 @@ static int macio_newworld_initfn(PCIDevice *d)
         memory_region_add_subregion(&s->bar, 0x40000, s->pic_mem);
     }
 
+    sysbus_dev = SYS_BUS_DEVICE(&ns->ide[0]);
+    sysbus_connect_irq(sysbus_dev, 0, ns->irqs[0]);
+    sysbus_connect_irq(sysbus_dev, 1, ns->irqs[1]);
+    macio_ide_register_dma(&ns->ide[0], s->dbdma, 0x16);
+    ret = qdev_init(DEVICE(&ns->ide[0]));
+    if (ret < 0) {
+        return ret;
+    }
+
+    sysbus_dev = SYS_BUS_DEVICE(&ns->ide[1]);
+    sysbus_connect_irq(sysbus_dev, 0, ns->irqs[2]);
+    sysbus_connect_irq(sysbus_dev, 1, ns->irqs[3]);
+    macio_ide_register_dma(&ns->ide[0], s->dbdma, 0x1a);
+    ret = qdev_init(DEVICE(&ns->ide[1]));
+    if (ret < 0) {
+        return ret;
+    }
+
     return 0;
 }
 
+static void macio_newworld_init(Object *obj)
+{
+    MacIOState *s = MACIO(obj);
+    NewWorldMacIOState *ns = NEWWORLD_MACIO(obj);
+    int i;
+    gchar *name;
+
+    qdev_init_gpio_out(DEVICE(obj), ns->irqs, ARRAY_SIZE(ns->irqs));
+
+    for (i = 0; i < 2; i++) {
+        object_initialize(&ns->ide[i], TYPE_MACIO_IDE);
+        qdev_set_parent_bus(DEVICE(&ns->ide[i]), sysbus_get_default());
+        memory_region_add_subregion(&s->bar, 0x1f000 + ((i + 1) * 0x1000),
+                                    &ns->ide[i].mem);
+        name = g_strdup_printf("ide[%i]", i);
+        object_property_add_child(obj, name, OBJECT(&ns->ide[i]), NULL);
+        g_free(name);
+    }
+}
+
 static void macio_instance_init(Object *obj)
 {
     MacIOState *s = MACIO(obj);
+    MemoryRegion *dbdma_mem;
 
     memory_region_init(&s->bar, "macio", 0x80000);
+
+    s->dbdma = DBDMA_init(&dbdma_mem);
+    memory_region_add_subregion(&s->bar, 0x08000, dbdma_mem);
 }
 
 static void macio_oldworld_class_init(ObjectClass *oc, void *data)
@@ -186,6 +250,8 @@ static const TypeInfo macio_oldworld_type_info = {
 static const TypeInfo macio_newworld_type_info = {
     .name          = TYPE_NEWWORLD_MACIO,
     .parent        = TYPE_MACIO,
+    .instance_size = sizeof(NewWorldMacIOState),
+    .instance_init = macio_newworld_init,
     .class_init    = macio_newworld_class_init,
 };
 
@@ -208,23 +274,15 @@ static void macio_register_types(void)
 type_init(macio_register_types)
 
 void macio_init(PCIDevice *d,
-                MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
+                MemoryRegion *pic_mem,
                 MemoryRegion *cuda_mem,
-                int nb_ide, MemoryRegion **ide_mem,
                 MemoryRegion *escc_mem)
 {
     MacIOState *macio_state = MACIO(d);
-    int i;
 
     macio_state->pic_mem = pic_mem;
-    macio_state->dbdma_mem = dbdma_mem;
     macio_state->cuda_mem = cuda_mem;
     macio_state->escc_mem = escc_mem;
-    if (nb_ide > 4)
-        nb_ide = 4;
-    macio_state->nb_ide = nb_ide;
-    for (i = 0; i < nb_ide; i++)
-        macio_state->ide_mem[i] = ide_mem[i];
     /* Note: this code is strongly inspirated from the corresponding code
        in PearPC */
 
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
index 581e95c..3e390d3 100644
--- a/hw/ppc/mac.h
+++ b/hw/ppc/mac.h
@@ -27,6 +27,7 @@
 
 #include "exec/memory.h"
 #include "hw/sysbus.h"
+#include "hw/ide/internal.h"
 
 /* SMP is not enabled, for now */
 #define MAX_CPUS 1
@@ -48,10 +49,30 @@ void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq);
 /* MacIO */
 #define TYPE_OLDWORLD_MACIO "macio-oldworld"
 #define TYPE_NEWWORLD_MACIO "macio-newworld"
+
+#define TYPE_MACIO_IDE "macio-ide"
+#define MACIO_IDE(obj) OBJECT_CHECK(MACIOIDEState, (obj), TYPE_MACIO_IDE)
+
+typedef struct MACIOIDEState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    qemu_irq irq;
+    qemu_irq dma_irq;
+
+    MemoryRegion mem;
+    IDEBus bus;
+    BlockDriverAIOCB *aiocb;
+} MACIOIDEState;
+
+void macio_ide_init_drives(MACIOIDEState *ide, DriveInfo **hd_table);
+void macio_ide_register_dma(MACIOIDEState *ide, void *dbdma, int channel);
+
 void macio_init(PCIDevice *dev,
-                MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
+                MemoryRegion *pic_mem,
                 MemoryRegion *cuda_mem,
-                int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem);
+                MemoryRegion *escc_mem);
 
 /* Heathrow PIC */
 qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index a4b38fb..4fd86b0 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -148,15 +148,14 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
     long kernel_size, initrd_size;
     PCIBus *pci_bus;
     PCIDevice *macio;
+    MACIOIDEState *macio_ide;
     MacIONVRAMState *nvr;
     int bios_size;
-    MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem, *escc_mem;
+    MemoryRegion *pic_mem, *cuda_mem, *escc_mem;
     MemoryRegion *escc_bar = g_new(MemoryRegion, 1);
-    MemoryRegion *ide_mem[3];
     int ppc_boot_device;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     void *fw_cfg;
-    void *dbdma;
     int machine_arch;
     SysBusDevice *s;
     DeviceState *dev;
@@ -363,12 +362,6 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
         pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
 
     ide_drive_get(hd, MAX_IDE_BUS);
-    dbdma = DBDMA_init(&dbdma_mem);
-
-    /* We only emulate 2 out of 3 IDE controllers for now */
-    ide_mem[0] = NULL;
-    ide_mem[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]);
-    ide_mem[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]);
 
     cuda_init(&cuda_mem, pic[0x19]);
 
@@ -376,8 +369,21 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
     adb_mouse_init(&adb_bus);
 
     macio = pci_create(pci_bus, -1, TYPE_NEWWORLD_MACIO);
-    macio_init(macio, pic_mem,
-               dbdma_mem, cuda_mem, 3, ide_mem, escc_bar);
+    dev = DEVICE(macio);
+    qdev_connect_gpio_out(dev, 0, pic[0x0d]); /* IDE */
+    qdev_connect_gpio_out(dev, 1, pic[0x02]); /* IDE DMA */
+    qdev_connect_gpio_out(dev, 2, pic[0x0e]); /* IDE */
+    qdev_connect_gpio_out(dev, 3, pic[0x02]); /* IDE DMA */
+    macio_init(macio, pic_mem, cuda_mem, escc_bar);
+
+    /* We only emulate 2 out of 3 IDE controllers for now */
+    macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
+                                                        "ide[0]"));
+    macio_ide_init_drives(macio_ide, hd);
+
+    macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
+                                                        "ide[1]"));
+    macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]);
 
     if (usb_enabled(machine_arch == ARCH_MAC99_U3)) {
         pci_create_simple(pci_bus, -1, "pci-ohci");
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 29b3277..6039ea6 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -27,7 +27,6 @@
 #include "hw/ppc.h"
 #include "mac.h"
 #include "hw/adb.h"
-#include "hw/mac_dbdma.h"
 #include "hw/nvram.h"
 #include "sysemu/sysemu.h"
 #include "net/net.h"
@@ -91,13 +90,14 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
     int32_t kernel_size, initrd_size;
     PCIBus *pci_bus;
     PCIDevice *macio;
+    MACIOIDEState *macio_ide;
+    DeviceState *dev;
     int bios_size;
-    MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem;
-    MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1), *ide_mem[2];
+    MemoryRegion *pic_mem, *cuda_mem;
+    MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1);
     uint16_t ppc_boot_device;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     void *fw_cfg;
-    void *dbdma;
 
     linux_boot = (kernel_filename != NULL);
 
@@ -263,17 +263,6 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
 
     ide_drive_get(hd, MAX_IDE_BUS);
 
-    /* First IDE channel is a MAC IDE on the MacIO bus */
-    dbdma = DBDMA_init(&dbdma_mem);
-    ide_mem[0] = NULL;
-    ide_mem[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]);
-
-    /* Second IDE channel is a CMD646 on the PCI bus */
-    hd[0] = hd[MAX_IDE_DEVS];
-    hd[1] = hd[MAX_IDE_DEVS + 1];
-    hd[3] = hd[2] = NULL;
-    pci_cmd646_ide_init(pci_bus, hd, 0);
-
     /* cuda also initialize ADB */
     cuda_init(&cuda_mem, pic[0x12]);
 
@@ -281,8 +270,21 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
     adb_mouse_init(&adb_bus);
 
     macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO);
-    macio_init(macio, pic_mem,
-               dbdma_mem, cuda_mem, 2, ide_mem, escc_bar);
+    dev = DEVICE(macio);
+    qdev_connect_gpio_out(dev, 0, pic[0x0D]); /* IDE */
+    qdev_connect_gpio_out(dev, 1, pic[0x02]); /* IDE DMA */
+    macio_init(macio, pic_mem, cuda_mem, escc_bar);
+
+    /* First IDE channel is a MAC IDE on the MacIO bus */
+    macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
+                                                        "ide"));
+    macio_ide_init_drives(macio_ide, hd);
+
+    /* Second IDE channel is a CMD646 on the PCI bus */
+    hd[0] = hd[MAX_IDE_DEVS];
+    hd[1] = hd[MAX_IDE_DEVS + 1];
+    hd[3] = hd[2] = NULL;
+    pci_cmd646_ide_init(pci_bus, hd, 0);
 
     if (usb_enabled(false)) {
         pci_create_simple(pci_bus, -1, "pci-ohci");
commit 95ed3b7cf1677dc9f995a6e1fcc7bf377cf94a0e
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jan 23 23:04:00 2013 +0000

    mac_nvram: QOM'ify MacIO NVRAM
    
    It was not qdev'ified before. Turn it into a SysBusDevice and
    initialize it via static properties.
    
    Prepare Old World specific MacIO state and embed the NVRAM state there.
    
    Drop macio_nvram_setup_bar() in favor of sysbus_mmio_map() or
    direct use of Memory API.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/mac_nvram.c b/hw/mac_nvram.c
index 0a22e66..25121fa 100644
--- a/hw/mac_nvram.c
+++ b/hw/mac_nvram.c
@@ -37,13 +37,6 @@
 #define NVR_DPRINTF(fmt, ...)
 #endif
 
-struct MacIONVRAMState {
-    uint32_t size;
-    MemoryRegion mem;
-    unsigned int it_shift;
-    uint8_t *data;
-};
-
 #define DEF_SYSTEM_SIZE 0xc10
 
 /* Direct access to NVRAM */
@@ -111,32 +104,56 @@ static const VMStateDescription vmstate_macio_nvram = {
 };
 
 
-static void macio_nvram_reset(void *opaque)
+static void macio_nvram_reset(DeviceState *dev)
 {
 }
 
-MacIONVRAMState *macio_nvram_init (hwaddr size,
-                                   unsigned int it_shift)
+static void macio_nvram_realizefn(DeviceState *dev, Error **errp)
 {
-    MacIONVRAMState *s;
+    SysBusDevice *d = SYS_BUS_DEVICE(dev);
+    MacIONVRAMState *s = MACIO_NVRAM(dev);
 
-    s = g_malloc0(sizeof(MacIONVRAMState));
-    s->data = g_malloc0(size);
-    s->size = size;
-    s->it_shift = it_shift;
+    s->data = g_malloc0(s->size);
 
     memory_region_init_io(&s->mem, &macio_nvram_ops, s, "macio-nvram",
-                          size << it_shift);
-    vmstate_register(NULL, -1, &vmstate_macio_nvram, s);
-    qemu_register_reset(macio_nvram_reset, s);
+                          s->size << s->it_shift);
+    sysbus_init_mmio(d, &s->mem);
+}
+
+static void macio_nvram_unrealizefn(DeviceState *dev, Error **errp)
+{
+    MacIONVRAMState *s = MACIO_NVRAM(dev);
+
+    g_free(s->data);
+}
 
-    return s;
+static Property macio_nvram_properties[] = {
+    DEFINE_PROP_UINT32("size", MacIONVRAMState, size, 0),
+    DEFINE_PROP_UINT32("it_shift", MacIONVRAMState, it_shift, 0),
+    DEFINE_PROP_END_OF_LIST()
+};
+
+static void macio_nvram_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = macio_nvram_realizefn;
+    dc->unrealize = macio_nvram_unrealizefn;
+    dc->reset = macio_nvram_reset;
+    dc->vmsd = &vmstate_macio_nvram;
+    dc->props = macio_nvram_properties;
 }
 
-void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar,
-                           hwaddr mem_base)
+static const TypeInfo macio_nvram_type_info = {
+    .name = TYPE_MACIO_NVRAM,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MacIONVRAMState),
+    .class_init = macio_nvram_class_init,
+};
+
+static void macio_nvram_register_types(void)
 {
-    memory_region_add_subregion(bar, mem_base, &s->mem);
+    type_register_static(&macio_nvram_type_info);
 }
 
 /* Set up a system OpenBIOS NVRAM partition */
@@ -175,3 +192,5 @@ void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len)
     end = len;
     OpenBIOS_finish_partition(part_header, end - start);
 }
+
+type_init(macio_nvram_register_types)
diff --git a/hw/macio.c b/hw/macio.c
index 0e6fc8d..32f359c 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -41,11 +41,21 @@ typedef struct MacIOState
     MemoryRegion *dbdma_mem;
     MemoryRegion *cuda_mem;
     MemoryRegion *escc_mem;
-    void *nvram;
     int nb_ide;
     MemoryRegion *ide_mem[4];
 } MacIOState;
 
+#define OLDWORLD_MACIO(obj) \
+    OBJECT_CHECK(OldWorldMacIOState, (obj), TYPE_OLDWORLD_MACIO)
+
+typedef struct OldWorldMacIOState {
+    /*< private >*/
+    MacIOState parent_obj;
+    /*< public >*/
+
+    MacIONVRAMState nvram;
+} OldWorldMacIOState;
+
 static void macio_bar_setup(MacIOState *macio_state)
 {
     int i;
@@ -66,8 +76,6 @@ static void macio_bar_setup(MacIOState *macio_state)
                                         macio_state->ide_mem[i]);
         }
     }
-    if (macio_state->nvram != NULL)
-        macio_nvram_setup_bar(macio_state->nvram, bar, 0x60000);
 }
 
 static int macio_common_initfn(PCIDevice *d)
@@ -85,11 +93,22 @@ static int macio_common_initfn(PCIDevice *d)
 static int macio_oldworld_initfn(PCIDevice *d)
 {
     MacIOState *s = MACIO(d);
+    OldWorldMacIOState *os = OLDWORLD_MACIO(d);
+    SysBusDevice *sysbus_dev;
     int ret = macio_common_initfn(d);
     if (ret < 0) {
         return ret;
     }
 
+    ret = qdev_init(DEVICE(&os->nvram));
+    if (ret < 0) {
+        return ret;
+    }
+    sysbus_dev = SYS_BUS_DEVICE(&os->nvram);
+    memory_region_add_subregion(&s->bar, 0x60000,
+                                sysbus_mmio_get_region(sysbus_dev, 0));
+    pmac_format_nvram_partition(&os->nvram, os->nvram.size);
+
     if (s->pic_mem) {
         /* Heathrow PIC */
         memory_region_add_subregion(&s->bar, 0x00000, s->pic_mem);
@@ -98,6 +117,17 @@ static int macio_oldworld_initfn(PCIDevice *d)
     return 0;
 }
 
+static void macio_oldworld_init(Object *obj)
+{
+    OldWorldMacIOState *os = OLDWORLD_MACIO(obj);
+    DeviceState *dev;
+
+    object_initialize(&os->nvram, TYPE_MACIO_NVRAM);
+    dev = DEVICE(&os->nvram);
+    qdev_prop_set_uint32(dev, "size", 0x2000);
+    qdev_prop_set_uint32(dev, "it_shift", 4);
+}
+
 static int macio_newworld_initfn(PCIDevice *d)
 {
     MacIOState *s = MACIO(d);
@@ -148,6 +178,8 @@ static void macio_class_init(ObjectClass *klass, void *data)
 static const TypeInfo macio_oldworld_type_info = {
     .name          = TYPE_OLDWORLD_MACIO,
     .parent        = TYPE_MACIO,
+    .instance_size = sizeof(OldWorldMacIOState),
+    .instance_init = macio_oldworld_init,
     .class_init    = macio_oldworld_class_init,
 };
 
@@ -177,7 +209,7 @@ type_init(macio_register_types)
 
 void macio_init(PCIDevice *d,
                 MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
-                MemoryRegion *cuda_mem, void *nvram,
+                MemoryRegion *cuda_mem,
                 int nb_ide, MemoryRegion **ide_mem,
                 MemoryRegion *escc_mem)
 {
@@ -188,7 +220,6 @@ void macio_init(PCIDevice *d,
     macio_state->dbdma_mem = dbdma_mem;
     macio_state->cuda_mem = cuda_mem;
     macio_state->escc_mem = escc_mem;
-    macio_state->nvram = nvram;
     if (nb_ide > 4)
         nb_ide = 4;
     macio_state->nb_ide = nb_ide;
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
index 6441794..581e95c 100644
--- a/hw/ppc/mac.h
+++ b/hw/ppc/mac.h
@@ -26,6 +26,7 @@
 #define __PPC_MAC_H__
 
 #include "exec/memory.h"
+#include "hw/sysbus.h"
 
 /* SMP is not enabled, for now */
 #define MAX_CPUS 1
@@ -49,7 +50,7 @@ void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq);
 #define TYPE_NEWWORLD_MACIO "macio-newworld"
 void macio_init(PCIDevice *dev,
                 MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
-                MemoryRegion *cuda_mem, void *nvram,
+                MemoryRegion *cuda_mem,
                 int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem);
 
 /* Heathrow PIC */
@@ -71,12 +72,22 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
                          MemoryRegion *address_space_io);
 
 /* Mac NVRAM */
-typedef struct MacIONVRAMState MacIONVRAMState;
+#define TYPE_MACIO_NVRAM "macio-nvram"
+#define MACIO_NVRAM(obj) \
+    OBJECT_CHECK(MacIONVRAMState, (obj), TYPE_MACIO_NVRAM)
+
+typedef struct MacIONVRAMState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    uint32_t size;
+    uint32_t it_shift;
+
+    MemoryRegion mem;
+    uint8_t *data;
+} MacIONVRAMState;
 
-MacIONVRAMState *macio_nvram_init (hwaddr size,
-                                   unsigned int it_shift);
-void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar,
-                           hwaddr mem_base);
 void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len);
 uint8_t macio_nvram_read(MacIONVRAMState *s, uint32_t addr);
 void macio_nvram_write(MacIONVRAMState *s, uint32_t addr, uint8_t val);
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index a62a6e9..a4b38fb 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -377,7 +377,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
 
     macio = pci_create(pci_bus, -1, TYPE_NEWWORLD_MACIO);
     macio_init(macio, pic_mem,
-               dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_bar);
+               dbdma_mem, cuda_mem, 3, ide_mem, escc_bar);
 
     if (usb_enabled(machine_arch == ARCH_MAC99_U3)) {
         pci_create_simple(pci_bus, -1, "pci-ohci");
@@ -393,9 +393,13 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
         graphic_depth = 15;
 
     /* The NewWorld NVRAM is not located in the MacIO device */
-    nvr = macio_nvram_init(0x2000, 1);
+    dev = qdev_create(NULL, TYPE_MACIO_NVRAM);
+    qdev_prop_set_uint32(dev, "size", 0x2000);
+    qdev_prop_set_uint32(dev, "it_shift", 1);
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xFFF04000);
+    nvr = MACIO_NVRAM(dev);
     pmac_format_nvram_partition(nvr, 0x2000);
-    macio_nvram_setup_bar(nvr, get_system_memory(), 0xFFF04000);
     /* No PCI init: the BIOS will do it */
 
     fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 2801992..29b3277 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -91,7 +91,6 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
     int32_t kernel_size, initrd_size;
     PCIBus *pci_bus;
     PCIDevice *macio;
-    MacIONVRAMState *nvr;
     int bios_size;
     MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem;
     MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1), *ide_mem[2];
@@ -281,12 +280,9 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
     adb_kbd_init(&adb_bus);
     adb_mouse_init(&adb_bus);
 
-    nvr = macio_nvram_init(0x2000, 4);
-    pmac_format_nvram_partition(nvr, 0x2000);
-
     macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO);
     macio_init(macio, pic_mem,
-               dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_bar);
+               dbdma_mem, cuda_mem, 2, ide_mem, escc_bar);
 
     if (usb_enabled(false)) {
         pci_create_simple(pci_bus, -1, "pci-ohci");
commit d8c6d07fdff2523ca78f95c7d8a7fe90ee7ea5a7
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jan 23 23:03:59 2013 +0000

    mac_nvram: Mark as Big Endian
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/mac_nvram.c b/hw/mac_nvram.c
index bcde07d..0a22e66 100644
--- a/hw/mac_nvram.c
+++ b/hw/mac_nvram.c
@@ -96,7 +96,7 @@ static uint64_t macio_nvram_readb(void *opaque, hwaddr addr,
 static const MemoryRegionOps macio_nvram_ops = {
     .read = macio_nvram_readb,
     .write = macio_nvram_writeb,
-    .endianness = DEVICE_NATIVE_ENDIAN,
+    .endianness = DEVICE_BIG_ENDIAN,
 };
 
 static const VMStateDescription vmstate_macio_nvram = {
commit 3743cca7d55c700e727e958d4a0b0b5d6c15e2e8
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jan 23 23:03:58 2013 +0000

    mac_nvram: Clean up public API
    
    The state data field is accessed in uint8_t quantities, so switch from
    uint32_t argument and return value to uint8_t.
    
    Fix debug format specifiers while at it.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/mac_nvram.c b/hw/mac_nvram.c
index eec7ca4..bcde07d 100644
--- a/hw/mac_nvram.c
+++ b/hw/mac_nvram.c
@@ -47,27 +47,26 @@ struct MacIONVRAMState {
 #define DEF_SYSTEM_SIZE 0xc10
 
 /* Direct access to NVRAM */
-uint32_t macio_nvram_read (void *opaque, uint32_t addr)
+uint8_t macio_nvram_read(MacIONVRAMState *s, uint32_t addr)
 {
-    MacIONVRAMState *s = opaque;
     uint32_t ret;
 
-    if (addr < s->size)
+    if (addr < s->size) {
         ret = s->data[addr];
-    else
+    } else {
         ret = -1;
-    NVR_DPRINTF("read addr %04x val %x\n", addr, ret);
+    }
+    NVR_DPRINTF("read addr %04" PRIx32 " val %" PRIx8 "\n", addr, ret);
 
     return ret;
 }
 
-void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val)
+void macio_nvram_write(MacIONVRAMState *s, uint32_t addr, uint8_t val)
 {
-    MacIONVRAMState *s = opaque;
-
-    NVR_DPRINTF("write addr %04x val %x\n", addr, val);
-    if (addr < s->size)
+    NVR_DPRINTF("write addr %04" PRIx32 " val %" PRIx8 "\n", addr, val);
+    if (addr < s->size) {
         s->data[addr] = val;
+    }
 }
 
 /* macio style NVRAM device */
@@ -78,7 +77,7 @@ static void macio_nvram_writeb(void *opaque, hwaddr addr,
 
     addr = (addr >> s->it_shift) & (s->size - 1);
     s->data[addr] = value;
-    NVR_DPRINTF("writeb addr %04x val %x\n", (int)addr, value);
+    NVR_DPRINTF("writeb addr %04" PHYS_PRIx " val %" PRIx64 "\n", addr, value);
 }
 
 static uint64_t macio_nvram_readb(void *opaque, hwaddr addr,
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
index 864a610..6441794 100644
--- a/hw/ppc/mac.h
+++ b/hw/ppc/mac.h
@@ -78,6 +78,6 @@ MacIONVRAMState *macio_nvram_init (hwaddr size,
 void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar,
                            hwaddr mem_base);
 void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len);
-uint32_t macio_nvram_read (void *opaque, uint32_t addr);
-void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val);
+uint8_t macio_nvram_read(MacIONVRAMState *s, uint32_t addr);
+void macio_nvram_write(MacIONVRAMState *s, uint32_t addr, uint8_t val);
 #endif /* !defined(__PPC_MAC_H__) */
commit d037834a9d3847499e8a146bd1893a5c856411be
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jan 23 23:03:57 2013 +0000

    macio: Split MacIO in two
    
    Let the machines create two different types. This prepares to move
    knowledge about sub-devices from the machines into the devices.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/macio.c b/hw/macio.c
index 8b4b48d..0e6fc8d 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -36,7 +36,6 @@ typedef struct MacIOState
     PCIDevice parent;
     /*< public >*/
 
-    int is_oldworld;
     MemoryRegion bar;
     MemoryRegion *pic_mem;
     MemoryRegion *dbdma_mem;
@@ -52,15 +51,6 @@ static void macio_bar_setup(MacIOState *macio_state)
     int i;
     MemoryRegion *bar = &macio_state->bar;
 
-    if (macio_state->pic_mem) {
-        if (macio_state->is_oldworld) {
-            /* Heathrow PIC */
-            memory_region_add_subregion(bar, 0x00000, macio_state->pic_mem);
-        } else {
-            /* OpenPIC */
-            memory_region_add_subregion(bar, 0x40000, macio_state->pic_mem);
-        }
-    }
     if (macio_state->dbdma_mem) {
         memory_region_add_subregion(bar, 0x08000, macio_state->dbdma_mem);
     }
@@ -80,7 +70,7 @@ static void macio_bar_setup(MacIOState *macio_state)
         macio_nvram_setup_bar(macio_state->nvram, bar, 0x60000);
 }
 
-static int macio_initfn(PCIDevice *d)
+static int macio_common_initfn(PCIDevice *d)
 {
     MacIOState *s = MACIO(d);
 
@@ -92,6 +82,38 @@ static int macio_initfn(PCIDevice *d)
     return 0;
 }
 
+static int macio_oldworld_initfn(PCIDevice *d)
+{
+    MacIOState *s = MACIO(d);
+    int ret = macio_common_initfn(d);
+    if (ret < 0) {
+        return ret;
+    }
+
+    if (s->pic_mem) {
+        /* Heathrow PIC */
+        memory_region_add_subregion(&s->bar, 0x00000, s->pic_mem);
+    }
+
+    return 0;
+}
+
+static int macio_newworld_initfn(PCIDevice *d)
+{
+    MacIOState *s = MACIO(d);
+    int ret = macio_common_initfn(d);
+    if (ret < 0) {
+        return ret;
+    }
+
+    if (s->pic_mem) {
+        /* OpenPIC */
+        memory_region_add_subregion(&s->bar, 0x40000, s->pic_mem);
+    }
+
+    return 0;
+}
+
 static void macio_instance_init(Object *obj)
 {
     MacIOState *s = MACIO(obj);
@@ -99,44 +121,69 @@ static void macio_instance_init(Object *obj)
     memory_region_init(&s->bar, "macio", 0x80000);
 }
 
+static void macio_oldworld_class_init(ObjectClass *oc, void *data)
+{
+    PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc);
+
+    pdc->init = macio_oldworld_initfn;
+    pdc->device_id = PCI_DEVICE_ID_APPLE_343S1201;
+}
+
+static void macio_newworld_class_init(ObjectClass *oc, void *data)
+{
+    PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc);
+
+    pdc->init = macio_newworld_initfn;
+    pdc->device_id = PCI_DEVICE_ID_APPLE_UNI_N_KEYL;
+}
+
 static void macio_class_init(ObjectClass *klass, void *data)
 {
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-    k->init = macio_initfn;
     k->vendor_id = PCI_VENDOR_ID_APPLE;
     k->class_id = PCI_CLASS_OTHERS << 8;
 }
 
+static const TypeInfo macio_oldworld_type_info = {
+    .name          = TYPE_OLDWORLD_MACIO,
+    .parent        = TYPE_MACIO,
+    .class_init    = macio_oldworld_class_init,
+};
+
+static const TypeInfo macio_newworld_type_info = {
+    .name          = TYPE_NEWWORLD_MACIO,
+    .parent        = TYPE_MACIO,
+    .class_init    = macio_newworld_class_init,
+};
+
 static const TypeInfo macio_type_info = {
     .name          = TYPE_MACIO,
     .parent        = TYPE_PCI_DEVICE,
     .instance_size = sizeof(MacIOState),
     .instance_init = macio_instance_init,
+    .abstract      = true,
     .class_init    = macio_class_init,
 };
 
 static void macio_register_types(void)
 {
     type_register_static(&macio_type_info);
+    type_register_static(&macio_oldworld_type_info);
+    type_register_static(&macio_newworld_type_info);
 }
 
 type_init(macio_register_types)
 
-void macio_init (PCIBus *bus, int device_id, int is_oldworld,
-                 MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
-                 MemoryRegion *cuda_mem, void *nvram,
-                 int nb_ide, MemoryRegion **ide_mem,
-                 MemoryRegion *escc_mem)
+void macio_init(PCIDevice *d,
+                MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
+                MemoryRegion *cuda_mem, void *nvram,
+                int nb_ide, MemoryRegion **ide_mem,
+                MemoryRegion *escc_mem)
 {
-    PCIDevice *d;
-    MacIOState *macio_state;
+    MacIOState *macio_state = MACIO(d);
     int i;
 
-    d = pci_create(bus, -1, TYPE_MACIO);
-
-    macio_state = MACIO(d);
-    macio_state->is_oldworld = is_oldworld;
     macio_state->pic_mem = pic_mem;
     macio_state->dbdma_mem = dbdma_mem;
     macio_state->cuda_mem = cuda_mem;
@@ -147,12 +194,8 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld,
     macio_state->nb_ide = nb_ide;
     for (i = 0; i < nb_ide; i++)
         macio_state->ide_mem[i] = ide_mem[i];
-    for (; i < 4; i++)
-        macio_state->ide_mem[i] = NULL;
     /* Note: this code is strongly inspirated from the corresponding code
        in PearPC */
 
-    pci_config_set_device_id(d->config, device_id);
-
     qdev_init_nofail(DEVICE(d));
 }
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
index 89c7d66..864a610 100644
--- a/hw/ppc/mac.h
+++ b/hw/ppc/mac.h
@@ -45,10 +45,12 @@
 void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq);
 
 /* MacIO */
-void macio_init (PCIBus *bus, int device_id, int is_oldworld,
-                 MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
-                 MemoryRegion *cuda_mem, void *nvram,
-                 int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem);
+#define TYPE_OLDWORLD_MACIO "macio-oldworld"
+#define TYPE_NEWWORLD_MACIO "macio-newworld"
+void macio_init(PCIDevice *dev,
+                MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
+                MemoryRegion *cuda_mem, void *nvram,
+                int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem);
 
 /* Heathrow PIC */
 qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index f3c01bf..a62a6e9 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -147,6 +147,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
     hwaddr kernel_base, initrd_base, cmdline_base = 0;
     long kernel_size, initrd_size;
     PCIBus *pci_bus;
+    PCIDevice *macio;
     MacIONVRAMState *nvr;
     int bios_size;
     MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem, *escc_mem;
@@ -374,7 +375,8 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
     adb_kbd_init(&adb_bus);
     adb_mouse_init(&adb_bus);
 
-    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem,
+    macio = pci_create(pci_bus, -1, TYPE_NEWWORLD_MACIO);
+    macio_init(macio, pic_mem,
                dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_bar);
 
     if (usb_enabled(machine_arch == ARCH_MAC99_U3)) {
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index dfbfa54..2801992 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -90,6 +90,7 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
     uint32_t kernel_base, initrd_base, cmdline_base = 0;
     int32_t kernel_size, initrd_size;
     PCIBus *pci_bus;
+    PCIDevice *macio;
     MacIONVRAMState *nvr;
     int bios_size;
     MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem;
@@ -283,7 +284,8 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
     nvr = macio_nvram_init(0x2000, 4);
     pmac_format_nvram_partition(nvr, 0x2000);
 
-    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem,
+    macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO);
+    macio_init(macio, pic_mem,
                dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_bar);
 
     if (usb_enabled(false)) {
commit 7b925079e36cf26ca2e1f8db84b771ddc3d6340c
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jan 23 23:03:56 2013 +0000

    macio: Delay qdev init until all fields are initialized
    
    This turns macio_bar_setup() into an implementation detail of the qdev
    initfn, to be removed step by step.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/macio.c b/hw/macio.c
index 770e3bd..8b4b48d 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -82,7 +82,13 @@ static void macio_bar_setup(MacIOState *macio_state)
 
 static int macio_initfn(PCIDevice *d)
 {
+    MacIOState *s = MACIO(d);
+
     d->config[0x3d] = 0x01; // interrupt on pin 1
+
+    macio_bar_setup(s);
+    pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
+
     return 0;
 }
 
@@ -127,7 +133,7 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld,
     MacIOState *macio_state;
     int i;
 
-    d = pci_create_simple(bus, -1, TYPE_MACIO);
+    d = pci_create(bus, -1, TYPE_MACIO);
 
     macio_state = MACIO(d);
     macio_state->is_oldworld = is_oldworld;
@@ -148,6 +154,5 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld,
 
     pci_config_set_device_id(d->config, device_id);
 
-    macio_bar_setup(macio_state);
-    pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &macio_state->bar);
+    qdev_init_nofail(DEVICE(d));
 }
commit fcf1bbabf4de3bc125c4dff18ea1cb76d76f042a
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jan 23 23:03:55 2013 +0000

    macio: QOM'ify some more
    
    Move bar MemoryRegion initialization to an instance_init.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/macio.c b/hw/macio.c
index f01fc57..770e3bd 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -27,9 +27,15 @@
 #include "pci/pci.h"
 #include "escc.h"
 
+#define TYPE_MACIO "macio"
+#define MACIO(obj) OBJECT_CHECK(MacIOState, (obj), TYPE_MACIO)
+
 typedef struct MacIOState
 {
+    /*< private >*/
     PCIDevice parent;
+    /*< public >*/
+
     int is_oldworld;
     MemoryRegion bar;
     MemoryRegion *pic_mem;
@@ -46,7 +52,6 @@ static void macio_bar_setup(MacIOState *macio_state)
     int i;
     MemoryRegion *bar = &macio_state->bar;
 
-    memory_region_init(bar, "macio", 0x80000);
     if (macio_state->pic_mem) {
         if (macio_state->is_oldworld) {
             /* Heathrow PIC */
@@ -81,6 +86,13 @@ static int macio_initfn(PCIDevice *d)
     return 0;
 }
 
+static void macio_instance_init(Object *obj)
+{
+    MacIOState *s = MACIO(obj);
+
+    memory_region_init(&s->bar, "macio", 0x80000);
+}
+
 static void macio_class_init(ObjectClass *klass, void *data)
 {
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
@@ -90,16 +102,17 @@ static void macio_class_init(ObjectClass *klass, void *data)
     k->class_id = PCI_CLASS_OTHERS << 8;
 }
 
-static const TypeInfo macio_info = {
-    .name          = "macio",
+static const TypeInfo macio_type_info = {
+    .name          = TYPE_MACIO,
     .parent        = TYPE_PCI_DEVICE,
     .instance_size = sizeof(MacIOState),
+    .instance_init = macio_instance_init,
     .class_init    = macio_class_init,
 };
 
 static void macio_register_types(void)
 {
-    type_register_static(&macio_info);
+    type_register_static(&macio_type_info);
 }
 
 type_init(macio_register_types)
@@ -114,9 +127,9 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld,
     MacIOState *macio_state;
     int i;
 
-    d = pci_create_simple(bus, -1, "macio");
+    d = pci_create_simple(bus, -1, TYPE_MACIO);
 
-    macio_state = DO_UPCAST(MacIOState, parent, d);
+    macio_state = MACIO(d);
     macio_state->is_oldworld = is_oldworld;
     macio_state->pic_mem = pic_mem;
     macio_state->dbdma_mem = dbdma_mem;
commit baec19105bb9824593bf6f37556302da2f67e583
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Jan 23 23:03:54 2013 +0000

    ppc: Move Mac machines to hw/ppc/
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    [agraf: squash in MAINTAINERS fix]
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/MAINTAINERS b/MAINTAINERS
index 35c260d..9dd4c20 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -380,7 +380,7 @@ New World
 M: Alexander Graf <agraf at suse.de>
 L: qemu-ppc at nongnu.org
 S: Maintained
-F: hw/ppc_newworld.c
+F: hw/ppc/mac_newworld.c
 F: hw/unin_pci.c
 F: hw/dec_pci.[hc]
 
@@ -388,7 +388,7 @@ Old World
 M: Alexander Graf <agraf at suse.de>
 L: qemu-ppc at nongnu.org
 S: Maintained
-F: hw/ppc_oldworld.c
+F: hw/ppc/mac_oldworld.c
 F: hw/grackle_pci.c
 
 PReP
diff --git a/hw/cuda.c b/hw/cuda.c
index d59e0ae..bbd1fda 100644
--- a/hw/cuda.c
+++ b/hw/cuda.c
@@ -23,7 +23,7 @@
  * THE SOFTWARE.
  */
 #include "hw.h"
-#include "ppc_mac.h"
+#include "ppc/mac.h"
 #include "adb.h"
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index 9484166..95639d5 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -24,7 +24,7 @@
  */
 
 #include "pci/pci_host.h"
-#include "ppc_mac.h"
+#include "ppc/mac.h"
 #include "pci/pci.h"
 
 /* debug Grackle */
diff --git a/hw/heathrow_pic.c b/hw/heathrow_pic.c
index b9ec8e7..c0a71c3 100644
--- a/hw/heathrow_pic.c
+++ b/hw/heathrow_pic.c
@@ -23,7 +23,7 @@
  * THE SOFTWARE.
  */
 #include "hw.h"
-#include "ppc_mac.h"
+#include "ppc/mac.h"
 
 /* debug PIC */
 //#define DEBUG_PIC
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index d8f9b4b..e0f04dc 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -22,9 +22,9 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include <hw/hw.h>
-#include <hw/ppc_mac.h>
-#include <hw/mac_dbdma.h>
+#include "hw/hw.h"
+#include "hw/ppc/mac.h"
+#include "hw/mac_dbdma.h"
 #include "block/block.h"
 #include "sysemu/dma.h"
 
diff --git a/hw/mac_nvram.c b/hw/mac_nvram.c
index 71093c2..eec7ca4 100644
--- a/hw/mac_nvram.c
+++ b/hw/mac_nvram.c
@@ -25,7 +25,7 @@
 #include "hw.h"
 #include "firmware_abi.h"
 #include "sysemu/sysemu.h"
-#include "ppc_mac.h"
+#include "ppc/mac.h"
 
 /* debug NVR */
 //#define DEBUG_NVR
diff --git a/hw/macio.c b/hw/macio.c
index 675a71c..f01fc57 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -23,7 +23,7 @@
  * THE SOFTWARE.
  */
 #include "hw.h"
-#include "ppc_mac.h"
+#include "ppc/mac.h"
 #include "pci/pci.h"
 #include "escc.h"
 
diff --git a/hw/openpic.c b/hw/openpic.c
index d414f47..25aa9bf 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -34,7 +34,7 @@
  *
  */
 #include "hw.h"
-#include "ppc_mac.h"
+#include "ppc/mac.h"
 #include "pci/pci.h"
 #include "openpic.h"
 #include "sysbus.h"
diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index afdcc0e..462146b 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -3,10 +3,6 @@ obj-y = ppc.o ppc_booke.o
 # PREP target
 obj-y += mc146818rtc.o
 obj-y += ppc_prep.o
-# OldWorld PowerMac
-obj-y += ppc_oldworld.o
-# NewWorld PowerMac
-obj-y += ppc_newworld.o
 # IBM pSeries (sPAPR)
 obj-$(CONFIG_PSERIES) += spapr.o spapr_hcall.o spapr_rtas.o spapr_vio.o
 obj-$(CONFIG_PSERIES) += xics.o spapr_vty.o spapr_llan.o spapr_vscsi.o
@@ -28,4 +24,9 @@ obj-y += xilinx_ethlite.o
 
 obj-y := $(addprefix ../,$(obj-y))
 
+# OldWorld PowerMac
+obj-y += mac_oldworld.o
+# NewWorld PowerMac
+obj-y += mac_newworld.o
+# e500
 obj-$(CONFIG_FDT) += e500.o mpc8544ds.o e500plat.o
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
new file mode 100644
index 0000000..89c7d66
--- /dev/null
+++ b/hw/ppc/mac.h
@@ -0,0 +1,81 @@
+/*
+ * QEMU PowerMac emulation shared definitions and prototypes
+ *
+ * Copyright (c) 2004-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#if !defined(__PPC_MAC_H__)
+#define __PPC_MAC_H__
+
+#include "exec/memory.h"
+
+/* SMP is not enabled, for now */
+#define MAX_CPUS 1
+
+#define BIOS_SIZE     (1024 * 1024)
+#define BIOS_FILENAME "ppc_rom.bin"
+#define NVRAM_SIZE        0x2000
+#define PROM_FILENAME    "openbios-ppc"
+#define PROM_ADDR         0xfff00000
+
+#define KERNEL_LOAD_ADDR 0x01000000
+#define KERNEL_GAP       0x00100000
+
+#define ESCC_CLOCK 3686400
+
+/* Cuda */
+void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq);
+
+/* MacIO */
+void macio_init (PCIBus *bus, int device_id, int is_oldworld,
+                 MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
+                 MemoryRegion *cuda_mem, void *nvram,
+                 int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem);
+
+/* Heathrow PIC */
+qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
+                            int nb_cpus, qemu_irq **irqs);
+
+/* Grackle PCI */
+#define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost"
+PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io);
+
+/* UniNorth PCI */
+PCIBus *pci_pmac_init(qemu_irq *pic,
+                      MemoryRegion *address_space_mem,
+                      MemoryRegion *address_space_io);
+PCIBus *pci_pmac_u3_init(qemu_irq *pic,
+                         MemoryRegion *address_space_mem,
+                         MemoryRegion *address_space_io);
+
+/* Mac NVRAM */
+typedef struct MacIONVRAMState MacIONVRAMState;
+
+MacIONVRAMState *macio_nvram_init (hwaddr size,
+                                   unsigned int it_shift);
+void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar,
+                           hwaddr mem_base);
+void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len);
+uint32_t macio_nvram_read (void *opaque, uint32_t addr);
+void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val);
+#endif /* !defined(__PPC_MAC_H__) */
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
new file mode 100644
index 0000000..f3c01bf
--- /dev/null
+++ b/hw/ppc/mac_newworld.c
@@ -0,0 +1,453 @@
+/*
+ * QEMU PowerPC CHRP (currently NewWorld PowerMac) hardware System Emulator
+ *
+ * Copyright (c) 2004-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * PCI bus layout on a real G5 (U3 based):
+ *
+ * 0000:f0:0b.0 Host bridge [0600]: Apple Computer Inc. U3 AGP [106b:004b]
+ * 0000:f0:10.0 VGA compatible controller [0300]: ATI Technologies Inc RV350 AP [Radeon 9600] [1002:4150]
+ * 0001:00:00.0 Host bridge [0600]: Apple Computer Inc. CPC945 HT Bridge [106b:004a]
+ * 0001:00:01.0 PCI bridge [0604]: Advanced Micro Devices [AMD] AMD-8131 PCI-X Bridge [1022:7450] (rev 12)
+ * 0001:00:02.0 PCI bridge [0604]: Advanced Micro Devices [AMD] AMD-8131 PCI-X Bridge [1022:7450] (rev 12)
+ * 0001:00:03.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0045]
+ * 0001:00:04.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0046]
+ * 0001:00:05.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0047]
+ * 0001:00:06.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0048]
+ * 0001:00:07.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0049]
+ * 0001:01:07.0 Class [ff00]: Apple Computer Inc. K2 KeyLargo Mac/IO [106b:0041] (rev 20)
+ * 0001:01:08.0 USB Controller [0c03]: Apple Computer Inc. K2 KeyLargo USB [106b:0040]
+ * 0001:01:09.0 USB Controller [0c03]: Apple Computer Inc. K2 KeyLargo USB [106b:0040]
+ * 0001:02:0b.0 USB Controller [0c03]: NEC Corporation USB [1033:0035] (rev 43)
+ * 0001:02:0b.1 USB Controller [0c03]: NEC Corporation USB [1033:0035] (rev 43)
+ * 0001:02:0b.2 USB Controller [0c03]: NEC Corporation USB 2.0 [1033:00e0] (rev 04)
+ * 0001:03:0d.0 Class [ff00]: Apple Computer Inc. K2 ATA/100 [106b:0043]
+ * 0001:03:0e.0 FireWire (IEEE 1394) [0c00]: Apple Computer Inc. K2 FireWire [106b:0042]
+ * 0001:04:0f.0 Ethernet controller [0200]: Apple Computer Inc. K2 GMAC (Sun GEM) [106b:004c]
+ * 0001:05:0c.0 IDE interface [0101]: Broadcom K2 SATA [1166:0240]
+ *
+ */
+#include "hw/hw.h"
+#include "hw/ppc.h"
+#include "hw/ppc/mac.h"
+#include "hw/adb.h"
+#include "hw/mac_dbdma.h"
+#include "hw/nvram.h"
+#include "hw/pci/pci.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "hw/fw_cfg.h"
+#include "hw/escc.h"
+#include "hw/openpic.h"
+#include "hw/ide.h"
+#include "hw/loader.h"
+#include "elf.h"
+#include "sysemu/kvm.h"
+#include "kvm_ppc.h"
+#include "hw/usb.h"
+#include "sysemu/blockdev.h"
+#include "exec/address-spaces.h"
+#include "hw/sysbus.h"
+
+#define MAX_IDE_BUS 2
+#define CFG_ADDR 0xf0000510
+
+/* debug UniNorth */
+//#define DEBUG_UNIN
+
+#ifdef DEBUG_UNIN
+#define UNIN_DPRINTF(fmt, ...)                                  \
+    do { printf("UNIN: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define UNIN_DPRINTF(fmt, ...)
+#endif
+
+/* UniN device */
+static void unin_write(void *opaque, hwaddr addr, uint64_t value,
+                       unsigned size)
+{
+    UNIN_DPRINTF("write addr " TARGET_FMT_plx " val %"PRIx64"\n", addr, value);
+}
+
+static uint64_t unin_read(void *opaque, hwaddr addr, unsigned size)
+{
+    uint32_t value;
+
+    value = 0;
+    UNIN_DPRINTF("readl addr " TARGET_FMT_plx " val %x\n", addr, value);
+
+    return value;
+}
+
+static const MemoryRegionOps unin_ops = {
+    .read = unin_read,
+    .write = unin_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static int fw_cfg_boot_set(void *opaque, const char *boot_device)
+{
+    fw_cfg_add_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
+    return 0;
+}
+
+static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
+{
+    return (addr & 0x0fffffff) + KERNEL_LOAD_ADDR;
+}
+
+static hwaddr round_page(hwaddr addr)
+{
+    return (addr + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
+}
+
+static void ppc_core99_reset(void *opaque)
+{
+    PowerPCCPU *cpu = opaque;
+
+    cpu_reset(CPU(cpu));
+}
+
+/* PowerPC Mac99 hardware initialisation */
+static void ppc_core99_init(QEMUMachineInitArgs *args)
+{
+    ram_addr_t ram_size = args->ram_size;
+    const char *cpu_model = args->cpu_model;
+    const char *kernel_filename = args->kernel_filename;
+    const char *kernel_cmdline = args->kernel_cmdline;
+    const char *initrd_filename = args->initrd_filename;
+    const char *boot_device = args->boot_device;
+    PowerPCCPU *cpu = NULL;
+    CPUPPCState *env = NULL;
+    char *filename;
+    qemu_irq *pic, **openpic_irqs;
+    MemoryRegion *unin_memory = g_new(MemoryRegion, 1);
+    int linux_boot, i, j, k;
+    MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1);
+    hwaddr kernel_base, initrd_base, cmdline_base = 0;
+    long kernel_size, initrd_size;
+    PCIBus *pci_bus;
+    MacIONVRAMState *nvr;
+    int bios_size;
+    MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem, *escc_mem;
+    MemoryRegion *escc_bar = g_new(MemoryRegion, 1);
+    MemoryRegion *ide_mem[3];
+    int ppc_boot_device;
+    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
+    void *fw_cfg;
+    void *dbdma;
+    int machine_arch;
+    SysBusDevice *s;
+    DeviceState *dev;
+
+    linux_boot = (kernel_filename != NULL);
+
+    /* init CPUs */
+    if (cpu_model == NULL)
+#ifdef TARGET_PPC64
+        cpu_model = "970fx";
+#else
+        cpu_model = "G4";
+#endif
+    for (i = 0; i < smp_cpus; i++) {
+        cpu = cpu_ppc_init(cpu_model);
+        if (cpu == NULL) {
+            fprintf(stderr, "Unable to find PowerPC CPU definition\n");
+            exit(1);
+        }
+        env = &cpu->env;
+
+        /* Set time-base frequency to 100 Mhz */
+        cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
+        qemu_register_reset(ppc_core99_reset, cpu);
+    }
+
+    /* allocate RAM */
+    memory_region_init_ram(ram, "ppc_core99.ram", ram_size);
+    vmstate_register_ram_global(ram);
+    memory_region_add_subregion(get_system_memory(), 0, ram);
+
+    /* allocate and load BIOS */
+    memory_region_init_ram(bios, "ppc_core99.bios", BIOS_SIZE);
+    vmstate_register_ram_global(bios);
+    if (bios_name == NULL)
+        bios_name = PROM_FILENAME;
+    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+    memory_region_set_readonly(bios, true);
+    memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios);
+
+    /* Load OpenBIOS (ELF) */
+    if (filename) {
+        bios_size = load_elf(filename, NULL, NULL, NULL,
+                             NULL, NULL, 1, ELF_MACHINE, 0);
+
+        g_free(filename);
+    } else {
+        bios_size = -1;
+    }
+    if (bios_size < 0 || bios_size > BIOS_SIZE) {
+        hw_error("qemu: could not load PowerPC bios '%s'\n", bios_name);
+        exit(1);
+    }
+
+    if (linux_boot) {
+        uint64_t lowaddr = 0;
+        int bswap_needed;
+
+#ifdef BSWAP_NEEDED
+        bswap_needed = 1;
+#else
+        bswap_needed = 0;
+#endif
+        kernel_base = KERNEL_LOAD_ADDR;
+
+        kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
+                               NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0);
+        if (kernel_size < 0)
+            kernel_size = load_aout(kernel_filename, kernel_base,
+                                    ram_size - kernel_base, bswap_needed,
+                                    TARGET_PAGE_SIZE);
+        if (kernel_size < 0)
+            kernel_size = load_image_targphys(kernel_filename,
+                                              kernel_base,
+                                              ram_size - kernel_base);
+        if (kernel_size < 0) {
+            hw_error("qemu: could not load kernel '%s'\n", kernel_filename);
+            exit(1);
+        }
+        /* load initrd */
+        if (initrd_filename) {
+            initrd_base = round_page(kernel_base + kernel_size + KERNEL_GAP);
+            initrd_size = load_image_targphys(initrd_filename, initrd_base,
+                                              ram_size - initrd_base);
+            if (initrd_size < 0) {
+                hw_error("qemu: could not load initial ram disk '%s'\n",
+                         initrd_filename);
+                exit(1);
+            }
+            cmdline_base = round_page(initrd_base + initrd_size);
+        } else {
+            initrd_base = 0;
+            initrd_size = 0;
+            cmdline_base = round_page(kernel_base + kernel_size + KERNEL_GAP);
+        }
+        ppc_boot_device = 'm';
+    } else {
+        kernel_base = 0;
+        kernel_size = 0;
+        initrd_base = 0;
+        initrd_size = 0;
+        ppc_boot_device = '\0';
+        /* We consider that NewWorld PowerMac never have any floppy drive
+         * For now, OHW cannot boot from the network.
+         */
+        for (i = 0; boot_device[i] != '\0'; i++) {
+            if (boot_device[i] >= 'c' && boot_device[i] <= 'f') {
+                ppc_boot_device = boot_device[i];
+                break;
+            }
+        }
+        if (ppc_boot_device == '\0') {
+            fprintf(stderr, "No valid boot device for Mac99 machine\n");
+            exit(1);
+        }
+    }
+
+    /* Register 8 MB of ISA IO space */
+    isa_mmio_init(0xf2000000, 0x00800000);
+
+    /* UniN init */
+    memory_region_init_io(unin_memory, &unin_ops, NULL, "unin", 0x1000);
+    memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory);
+
+    openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
+    openpic_irqs[0] =
+        g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
+    for (i = 0; i < smp_cpus; i++) {
+        /* Mac99 IRQ connection between OpenPIC outputs pins
+         * and PowerPC input pins
+         */
+        switch (PPC_INPUT(env)) {
+        case PPC_FLAGS_INPUT_6xx:
+            openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
+            openpic_irqs[i][OPENPIC_OUTPUT_INT] =
+                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
+            openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
+                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
+            openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
+                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_MCP];
+            /* Not connected ? */
+            openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;
+            /* Check this */
+            openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
+                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_HRESET];
+            break;
+#if defined(TARGET_PPC64)
+        case PPC_FLAGS_INPUT_970:
+            openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
+            openpic_irqs[i][OPENPIC_OUTPUT_INT] =
+                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
+            openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
+                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
+            openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
+                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_MCP];
+            /* Not connected ? */
+            openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;
+            /* Check this */
+            openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
+                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_HRESET];
+            break;
+#endif /* defined(TARGET_PPC64) */
+        default:
+            hw_error("Bus model not supported on mac99 machine\n");
+            exit(1);
+        }
+    }
+
+    pic = g_new(qemu_irq, 64);
+
+    dev = qdev_create(NULL, "openpic");
+    qdev_prop_set_uint32(dev, "model", OPENPIC_MODEL_RAVEN);
+    qdev_init_nofail(dev);
+    s = SYS_BUS_DEVICE(dev);
+    pic_mem = s->mmio[0].memory;
+    k = 0;
+    for (i = 0; i < smp_cpus; i++) {
+        for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
+            sysbus_connect_irq(s, k++, openpic_irqs[i][j]);
+        }
+    }
+
+    for (i = 0; i < 64; i++) {
+        pic[i] = qdev_get_gpio_in(dev, i);
+    }
+
+    if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
+        /* 970 gets a U3 bus */
+        pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io());
+        machine_arch = ARCH_MAC99_U3;
+    } else {
+        pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io());
+        machine_arch = ARCH_MAC99;
+    }
+    /* init basic PC hardware */
+    pci_vga_init(pci_bus);
+
+    escc_mem = escc_init(0, pic[0x25], pic[0x24],
+                         serial_hds[0], serial_hds[1], ESCC_CLOCK, 4);
+    memory_region_init_alias(escc_bar, "escc-bar",
+                             escc_mem, 0, memory_region_size(escc_mem));
+
+    for(i = 0; i < nb_nics; i++)
+        pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
+
+    ide_drive_get(hd, MAX_IDE_BUS);
+    dbdma = DBDMA_init(&dbdma_mem);
+
+    /* We only emulate 2 out of 3 IDE controllers for now */
+    ide_mem[0] = NULL;
+    ide_mem[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]);
+    ide_mem[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]);
+
+    cuda_init(&cuda_mem, pic[0x19]);
+
+    adb_kbd_init(&adb_bus);
+    adb_mouse_init(&adb_bus);
+
+    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem,
+               dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_bar);
+
+    if (usb_enabled(machine_arch == ARCH_MAC99_U3)) {
+        pci_create_simple(pci_bus, -1, "pci-ohci");
+        /* U3 needs to use USB for input because Linux doesn't support via-cuda
+        on PPC64 */
+        if (machine_arch == ARCH_MAC99_U3) {
+            usbdevice_create("keyboard");
+            usbdevice_create("mouse");
+        }
+    }
+
+    if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
+        graphic_depth = 15;
+
+    /* The NewWorld NVRAM is not located in the MacIO device */
+    nvr = macio_nvram_init(0x2000, 1);
+    pmac_format_nvram_partition(nvr, 0x2000);
+    macio_nvram_setup_bar(nvr, get_system_memory(), 0xFFF04000);
+    /* No PCI init: the BIOS will do it */
+
+    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
+    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
+    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
+    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch);
+    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
+    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
+    if (kernel_cmdline) {
+        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base);
+        pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline);
+    } else {
+        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
+    }
+    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base);
+    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
+    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device);
+
+    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width);
+    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height);
+    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth);
+
+    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
+    if (kvm_enabled()) {
+#ifdef CONFIG_KVM
+        uint8_t *hypercall;
+
+        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq());
+        hypercall = g_malloc(16);
+        kvmppc_get_hypercall(env, hypercall, 16);
+        fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
+        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
+#endif
+    } else {
+        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec());
+    }
+
+    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
+}
+
+static QEMUMachine core99_machine = {
+    .name = "mac99",
+    .desc = "Mac99 based PowerMAC",
+    .init = ppc_core99_init,
+    .max_cpus = MAX_CPUS,
+#ifdef TARGET_PPC64
+    .is_default = 1,
+#endif
+    DEFAULT_MACHINE_OPTIONS,
+};
+
+static void core99_machine_init(void)
+{
+    qemu_register_machine(&core99_machine);
+}
+
+machine_init(core99_machine_init);
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
new file mode 100644
index 0000000..dfbfa54
--- /dev/null
+++ b/hw/ppc/mac_oldworld.c
@@ -0,0 +1,352 @@
+
+/*
+ * QEMU OldWorld PowerMac (currently ~G3 Beige) hardware System Emulator
+ *
+ * Copyright (c) 2004-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "hw/hw.h"
+#include "hw/ppc.h"
+#include "mac.h"
+#include "hw/adb.h"
+#include "hw/mac_dbdma.h"
+#include "hw/nvram.h"
+#include "sysemu/sysemu.h"
+#include "net/net.h"
+#include "hw/isa.h"
+#include "hw/pci/pci.h"
+#include "hw/boards.h"
+#include "hw/fw_cfg.h"
+#include "hw/escc.h"
+#include "hw/ide.h"
+#include "hw/loader.h"
+#include "elf.h"
+#include "sysemu/kvm.h"
+#include "kvm_ppc.h"
+#include "sysemu/blockdev.h"
+#include "exec/address-spaces.h"
+
+#define MAX_IDE_BUS 2
+#define CFG_ADDR 0xf0000510
+
+static int fw_cfg_boot_set(void *opaque, const char *boot_device)
+{
+    fw_cfg_add_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
+    return 0;
+}
+
+
+static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
+{
+    return (addr & 0x0fffffff) + KERNEL_LOAD_ADDR;
+}
+
+static hwaddr round_page(hwaddr addr)
+{
+    return (addr + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
+}
+
+static void ppc_heathrow_reset(void *opaque)
+{
+    PowerPCCPU *cpu = opaque;
+
+    cpu_reset(CPU(cpu));
+}
+
+static void ppc_heathrow_init(QEMUMachineInitArgs *args)
+{
+    ram_addr_t ram_size = args->ram_size;
+    const char *cpu_model = args->cpu_model;
+    const char *kernel_filename = args->kernel_filename;
+    const char *kernel_cmdline = args->kernel_cmdline;
+    const char *initrd_filename = args->initrd_filename;
+    const char *boot_device = args->boot_device;
+    MemoryRegion *sysmem = get_system_memory();
+    PowerPCCPU *cpu = NULL;
+    CPUPPCState *env = NULL;
+    char *filename;
+    qemu_irq *pic, **heathrow_irqs;
+    int linux_boot, i;
+    MemoryRegion *ram = g_new(MemoryRegion, 1);
+    MemoryRegion *bios = g_new(MemoryRegion, 1);
+    uint32_t kernel_base, initrd_base, cmdline_base = 0;
+    int32_t kernel_size, initrd_size;
+    PCIBus *pci_bus;
+    MacIONVRAMState *nvr;
+    int bios_size;
+    MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem;
+    MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1), *ide_mem[2];
+    uint16_t ppc_boot_device;
+    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
+    void *fw_cfg;
+    void *dbdma;
+
+    linux_boot = (kernel_filename != NULL);
+
+    /* init CPUs */
+    if (cpu_model == NULL)
+        cpu_model = "G3";
+    for (i = 0; i < smp_cpus; i++) {
+        cpu = cpu_ppc_init(cpu_model);
+        if (cpu == NULL) {
+            fprintf(stderr, "Unable to find PowerPC CPU definition\n");
+            exit(1);
+        }
+        env = &cpu->env;
+
+        /* Set time-base frequency to 16.6 Mhz */
+        cpu_ppc_tb_init(env,  16600000UL);
+        qemu_register_reset(ppc_heathrow_reset, cpu);
+    }
+
+    /* allocate RAM */
+    if (ram_size > (2047 << 20)) {
+        fprintf(stderr,
+                "qemu: Too much memory for this machine: %d MB, maximum 2047 MB\n",
+                ((unsigned int)ram_size / (1 << 20)));
+        exit(1);
+    }
+
+    memory_region_init_ram(ram, "ppc_heathrow.ram", ram_size);
+    vmstate_register_ram_global(ram);
+    memory_region_add_subregion(sysmem, 0, ram);
+
+    /* allocate and load BIOS */
+    memory_region_init_ram(bios, "ppc_heathrow.bios", BIOS_SIZE);
+    vmstate_register_ram_global(bios);
+    if (bios_name == NULL)
+        bios_name = PROM_FILENAME;
+    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+    memory_region_set_readonly(bios, true);
+    memory_region_add_subregion(sysmem, PROM_ADDR, bios);
+
+    /* Load OpenBIOS (ELF) */
+    if (filename) {
+        bios_size = load_elf(filename, 0, NULL, NULL, NULL, NULL,
+                             1, ELF_MACHINE, 0);
+        g_free(filename);
+    } else {
+        bios_size = -1;
+    }
+    if (bios_size < 0 || bios_size > BIOS_SIZE) {
+        hw_error("qemu: could not load PowerPC bios '%s'\n", bios_name);
+        exit(1);
+    }
+
+    if (linux_boot) {
+        uint64_t lowaddr = 0;
+        int bswap_needed;
+
+#ifdef BSWAP_NEEDED
+        bswap_needed = 1;
+#else
+        bswap_needed = 0;
+#endif
+        kernel_base = KERNEL_LOAD_ADDR;
+        kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
+                               NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0);
+        if (kernel_size < 0)
+            kernel_size = load_aout(kernel_filename, kernel_base,
+                                    ram_size - kernel_base, bswap_needed,
+                                    TARGET_PAGE_SIZE);
+        if (kernel_size < 0)
+            kernel_size = load_image_targphys(kernel_filename,
+                                              kernel_base,
+                                              ram_size - kernel_base);
+        if (kernel_size < 0) {
+            hw_error("qemu: could not load kernel '%s'\n",
+                      kernel_filename);
+            exit(1);
+        }
+        /* load initrd */
+        if (initrd_filename) {
+            initrd_base = round_page(kernel_base + kernel_size + KERNEL_GAP);
+            initrd_size = load_image_targphys(initrd_filename, initrd_base,
+                                              ram_size - initrd_base);
+            if (initrd_size < 0) {
+                hw_error("qemu: could not load initial ram disk '%s'\n",
+                         initrd_filename);
+                exit(1);
+            }
+            cmdline_base = round_page(initrd_base + initrd_size);
+        } else {
+            initrd_base = 0;
+            initrd_size = 0;
+            cmdline_base = round_page(kernel_base + kernel_size + KERNEL_GAP);
+        }
+        ppc_boot_device = 'm';
+    } else {
+        kernel_base = 0;
+        kernel_size = 0;
+        initrd_base = 0;
+        initrd_size = 0;
+        ppc_boot_device = '\0';
+        for (i = 0; boot_device[i] != '\0'; i++) {
+            /* TOFIX: for now, the second IDE channel is not properly
+             *        used by OHW. The Mac floppy disk are not emulated.
+             *        For now, OHW cannot boot from the network.
+             */
+#if 0
+            if (boot_device[i] >= 'a' && boot_device[i] <= 'f') {
+                ppc_boot_device = boot_device[i];
+                break;
+            }
+#else
+            if (boot_device[i] >= 'c' && boot_device[i] <= 'd') {
+                ppc_boot_device = boot_device[i];
+                break;
+            }
+#endif
+        }
+        if (ppc_boot_device == '\0') {
+            fprintf(stderr, "No valid boot device for G3 Beige machine\n");
+            exit(1);
+        }
+    }
+
+    /* Register 2 MB of ISA IO space */
+    isa_mmio_init(0xfe000000, 0x00200000);
+
+    /* XXX: we register only 1 output pin for heathrow PIC */
+    heathrow_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
+    heathrow_irqs[0] =
+        g_malloc0(smp_cpus * sizeof(qemu_irq) * 1);
+    /* Connect the heathrow PIC outputs to the 6xx bus */
+    for (i = 0; i < smp_cpus; i++) {
+        switch (PPC_INPUT(env)) {
+        case PPC_FLAGS_INPUT_6xx:
+            heathrow_irqs[i] = heathrow_irqs[0] + (i * 1);
+            heathrow_irqs[i][0] =
+                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
+            break;
+        default:
+            hw_error("Bus model not supported on OldWorld Mac machine\n");
+        }
+    }
+
+    /* init basic PC hardware */
+    if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
+        hw_error("Only 6xx bus is supported on heathrow machine\n");
+    }
+    pic = heathrow_pic_init(&pic_mem, 1, heathrow_irqs);
+    pci_bus = pci_grackle_init(0xfec00000, pic,
+                               get_system_memory(),
+                               get_system_io());
+    pci_vga_init(pci_bus);
+
+    escc_mem = escc_init(0, pic[0x0f], pic[0x10], serial_hds[0],
+                               serial_hds[1], ESCC_CLOCK, 4);
+    memory_region_init_alias(escc_bar, "escc-bar",
+                             escc_mem, 0, memory_region_size(escc_mem));
+
+    for(i = 0; i < nb_nics; i++)
+        pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
+
+
+    ide_drive_get(hd, MAX_IDE_BUS);
+
+    /* First IDE channel is a MAC IDE on the MacIO bus */
+    dbdma = DBDMA_init(&dbdma_mem);
+    ide_mem[0] = NULL;
+    ide_mem[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]);
+
+    /* Second IDE channel is a CMD646 on the PCI bus */
+    hd[0] = hd[MAX_IDE_DEVS];
+    hd[1] = hd[MAX_IDE_DEVS + 1];
+    hd[3] = hd[2] = NULL;
+    pci_cmd646_ide_init(pci_bus, hd, 0);
+
+    /* cuda also initialize ADB */
+    cuda_init(&cuda_mem, pic[0x12]);
+
+    adb_kbd_init(&adb_bus);
+    adb_mouse_init(&adb_bus);
+
+    nvr = macio_nvram_init(0x2000, 4);
+    pmac_format_nvram_partition(nvr, 0x2000);
+
+    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem,
+               dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_bar);
+
+    if (usb_enabled(false)) {
+        pci_create_simple(pci_bus, -1, "pci-ohci");
+    }
+
+    if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
+        graphic_depth = 15;
+
+    /* No PCI init: the BIOS will do it */
+
+    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
+    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
+    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
+    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW);
+    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
+    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
+    if (kernel_cmdline) {
+        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base);
+        pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline);
+    } else {
+        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
+    }
+    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base);
+    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
+    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device);
+
+    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width);
+    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height);
+    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth);
+
+    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
+    if (kvm_enabled()) {
+#ifdef CONFIG_KVM
+        uint8_t *hypercall;
+
+        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq());
+        hypercall = g_malloc(16);
+        kvmppc_get_hypercall(env, hypercall, 16);
+        fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
+        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
+#endif
+    } else {
+        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec());
+    }
+
+    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
+}
+
+static QEMUMachine heathrow_machine = {
+    .name = "g3beige",
+    .desc = "Heathrow based PowerMAC",
+    .init = ppc_heathrow_init,
+    .max_cpus = MAX_CPUS,
+#ifndef TARGET_PPC64
+    .is_default = 1,
+#endif
+    DEFAULT_MACHINE_OPTIONS,
+};
+
+static void heathrow_machine_init(void)
+{
+    qemu_register_machine(&heathrow_machine);
+}
+
+machine_init(heathrow_machine_init);
diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h
deleted file mode 100644
index 89c7d66..0000000
--- a/hw/ppc_mac.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * QEMU PowerMac emulation shared definitions and prototypes
- *
- * Copyright (c) 2004-2007 Fabrice Bellard
- * Copyright (c) 2007 Jocelyn Mayer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#if !defined(__PPC_MAC_H__)
-#define __PPC_MAC_H__
-
-#include "exec/memory.h"
-
-/* SMP is not enabled, for now */
-#define MAX_CPUS 1
-
-#define BIOS_SIZE     (1024 * 1024)
-#define BIOS_FILENAME "ppc_rom.bin"
-#define NVRAM_SIZE        0x2000
-#define PROM_FILENAME    "openbios-ppc"
-#define PROM_ADDR         0xfff00000
-
-#define KERNEL_LOAD_ADDR 0x01000000
-#define KERNEL_GAP       0x00100000
-
-#define ESCC_CLOCK 3686400
-
-/* Cuda */
-void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq);
-
-/* MacIO */
-void macio_init (PCIBus *bus, int device_id, int is_oldworld,
-                 MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
-                 MemoryRegion *cuda_mem, void *nvram,
-                 int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem);
-
-/* Heathrow PIC */
-qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
-                            int nb_cpus, qemu_irq **irqs);
-
-/* Grackle PCI */
-#define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost"
-PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
-                         MemoryRegion *address_space_mem,
-                         MemoryRegion *address_space_io);
-
-/* UniNorth PCI */
-PCIBus *pci_pmac_init(qemu_irq *pic,
-                      MemoryRegion *address_space_mem,
-                      MemoryRegion *address_space_io);
-PCIBus *pci_pmac_u3_init(qemu_irq *pic,
-                         MemoryRegion *address_space_mem,
-                         MemoryRegion *address_space_io);
-
-/* Mac NVRAM */
-typedef struct MacIONVRAMState MacIONVRAMState;
-
-MacIONVRAMState *macio_nvram_init (hwaddr size,
-                                   unsigned int it_shift);
-void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar,
-                           hwaddr mem_base);
-void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len);
-uint32_t macio_nvram_read (void *opaque, uint32_t addr);
-void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val);
-#endif /* !defined(__PPC_MAC_H__) */
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
deleted file mode 100644
index b1973f1..0000000
--- a/hw/ppc_newworld.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * QEMU PowerPC CHRP (currently NewWorld PowerMac) hardware System Emulator
- *
- * Copyright (c) 2004-2007 Fabrice Bellard
- * Copyright (c) 2007 Jocelyn Mayer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- * PCI bus layout on a real G5 (U3 based):
- *
- * 0000:f0:0b.0 Host bridge [0600]: Apple Computer Inc. U3 AGP [106b:004b]
- * 0000:f0:10.0 VGA compatible controller [0300]: ATI Technologies Inc RV350 AP [Radeon 9600] [1002:4150]
- * 0001:00:00.0 Host bridge [0600]: Apple Computer Inc. CPC945 HT Bridge [106b:004a]
- * 0001:00:01.0 PCI bridge [0604]: Advanced Micro Devices [AMD] AMD-8131 PCI-X Bridge [1022:7450] (rev 12)
- * 0001:00:02.0 PCI bridge [0604]: Advanced Micro Devices [AMD] AMD-8131 PCI-X Bridge [1022:7450] (rev 12)
- * 0001:00:03.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0045]
- * 0001:00:04.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0046]
- * 0001:00:05.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0047]
- * 0001:00:06.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0048]
- * 0001:00:07.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0049]
- * 0001:01:07.0 Class [ff00]: Apple Computer Inc. K2 KeyLargo Mac/IO [106b:0041] (rev 20)
- * 0001:01:08.0 USB Controller [0c03]: Apple Computer Inc. K2 KeyLargo USB [106b:0040]
- * 0001:01:09.0 USB Controller [0c03]: Apple Computer Inc. K2 KeyLargo USB [106b:0040]
- * 0001:02:0b.0 USB Controller [0c03]: NEC Corporation USB [1033:0035] (rev 43)
- * 0001:02:0b.1 USB Controller [0c03]: NEC Corporation USB [1033:0035] (rev 43)
- * 0001:02:0b.2 USB Controller [0c03]: NEC Corporation USB 2.0 [1033:00e0] (rev 04)
- * 0001:03:0d.0 Class [ff00]: Apple Computer Inc. K2 ATA/100 [106b:0043]
- * 0001:03:0e.0 FireWire (IEEE 1394) [0c00]: Apple Computer Inc. K2 FireWire [106b:0042]
- * 0001:04:0f.0 Ethernet controller [0200]: Apple Computer Inc. K2 GMAC (Sun GEM) [106b:004c]
- * 0001:05:0c.0 IDE interface [0101]: Broadcom K2 SATA [1166:0240]
- *
- */
-#include "hw.h"
-#include "ppc.h"
-#include "ppc_mac.h"
-#include "adb.h"
-#include "mac_dbdma.h"
-#include "nvram.h"
-#include "pci/pci.h"
-#include "net/net.h"
-#include "sysemu/sysemu.h"
-#include "boards.h"
-#include "fw_cfg.h"
-#include "escc.h"
-#include "openpic.h"
-#include "ide.h"
-#include "loader.h"
-#include "elf.h"
-#include "sysemu/kvm.h"
-#include "kvm_ppc.h"
-#include "hw/usb.h"
-#include "sysemu/blockdev.h"
-#include "exec/address-spaces.h"
-#include "sysbus.h"
-
-#define MAX_IDE_BUS 2
-#define CFG_ADDR 0xf0000510
-
-/* debug UniNorth */
-//#define DEBUG_UNIN
-
-#ifdef DEBUG_UNIN
-#define UNIN_DPRINTF(fmt, ...)                                  \
-    do { printf("UNIN: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define UNIN_DPRINTF(fmt, ...)
-#endif
-
-/* UniN device */
-static void unin_write(void *opaque, hwaddr addr, uint64_t value,
-                       unsigned size)
-{
-    UNIN_DPRINTF("write addr " TARGET_FMT_plx " val %"PRIx64"\n", addr, value);
-}
-
-static uint64_t unin_read(void *opaque, hwaddr addr, unsigned size)
-{
-    uint32_t value;
-
-    value = 0;
-    UNIN_DPRINTF("readl addr " TARGET_FMT_plx " val %x\n", addr, value);
-
-    return value;
-}
-
-static const MemoryRegionOps unin_ops = {
-    .read = unin_read,
-    .write = unin_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int fw_cfg_boot_set(void *opaque, const char *boot_device)
-{
-    fw_cfg_add_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
-    return 0;
-}
-
-static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
-{
-    return (addr & 0x0fffffff) + KERNEL_LOAD_ADDR;
-}
-
-static hwaddr round_page(hwaddr addr)
-{
-    return (addr + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
-}
-
-static void ppc_core99_reset(void *opaque)
-{
-    PowerPCCPU *cpu = opaque;
-
-    cpu_reset(CPU(cpu));
-}
-
-/* PowerPC Mac99 hardware initialisation */
-static void ppc_core99_init(QEMUMachineInitArgs *args)
-{
-    ram_addr_t ram_size = args->ram_size;
-    const char *cpu_model = args->cpu_model;
-    const char *kernel_filename = args->kernel_filename;
-    const char *kernel_cmdline = args->kernel_cmdline;
-    const char *initrd_filename = args->initrd_filename;
-    const char *boot_device = args->boot_device;
-    PowerPCCPU *cpu = NULL;
-    CPUPPCState *env = NULL;
-    char *filename;
-    qemu_irq *pic, **openpic_irqs;
-    MemoryRegion *unin_memory = g_new(MemoryRegion, 1);
-    int linux_boot, i, j, k;
-    MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1);
-    hwaddr kernel_base, initrd_base, cmdline_base = 0;
-    long kernel_size, initrd_size;
-    PCIBus *pci_bus;
-    MacIONVRAMState *nvr;
-    int bios_size;
-    MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem, *escc_mem;
-    MemoryRegion *escc_bar = g_new(MemoryRegion, 1);
-    MemoryRegion *ide_mem[3];
-    int ppc_boot_device;
-    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
-    void *fw_cfg;
-    void *dbdma;
-    int machine_arch;
-    SysBusDevice *s;
-    DeviceState *dev;
-
-    linux_boot = (kernel_filename != NULL);
-
-    /* init CPUs */
-    if (cpu_model == NULL)
-#ifdef TARGET_PPC64
-        cpu_model = "970fx";
-#else
-        cpu_model = "G4";
-#endif
-    for (i = 0; i < smp_cpus; i++) {
-        cpu = cpu_ppc_init(cpu_model);
-        if (cpu == NULL) {
-            fprintf(stderr, "Unable to find PowerPC CPU definition\n");
-            exit(1);
-        }
-        env = &cpu->env;
-
-        /* Set time-base frequency to 100 Mhz */
-        cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
-        qemu_register_reset(ppc_core99_reset, cpu);
-    }
-
-    /* allocate RAM */
-    memory_region_init_ram(ram, "ppc_core99.ram", ram_size);
-    vmstate_register_ram_global(ram);
-    memory_region_add_subregion(get_system_memory(), 0, ram);
-
-    /* allocate and load BIOS */
-    memory_region_init_ram(bios, "ppc_core99.bios", BIOS_SIZE);
-    vmstate_register_ram_global(bios);
-    if (bios_name == NULL)
-        bios_name = PROM_FILENAME;
-    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-    memory_region_set_readonly(bios, true);
-    memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios);
-
-    /* Load OpenBIOS (ELF) */
-    if (filename) {
-        bios_size = load_elf(filename, NULL, NULL, NULL,
-                             NULL, NULL, 1, ELF_MACHINE, 0);
-
-        g_free(filename);
-    } else {
-        bios_size = -1;
-    }
-    if (bios_size < 0 || bios_size > BIOS_SIZE) {
-        hw_error("qemu: could not load PowerPC bios '%s'\n", bios_name);
-        exit(1);
-    }
-
-    if (linux_boot) {
-        uint64_t lowaddr = 0;
-        int bswap_needed;
-
-#ifdef BSWAP_NEEDED
-        bswap_needed = 1;
-#else
-        bswap_needed = 0;
-#endif
-        kernel_base = KERNEL_LOAD_ADDR;
-
-        kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
-                               NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0);
-        if (kernel_size < 0)
-            kernel_size = load_aout(kernel_filename, kernel_base,
-                                    ram_size - kernel_base, bswap_needed,
-                                    TARGET_PAGE_SIZE);
-        if (kernel_size < 0)
-            kernel_size = load_image_targphys(kernel_filename,
-                                              kernel_base,
-                                              ram_size - kernel_base);
-        if (kernel_size < 0) {
-            hw_error("qemu: could not load kernel '%s'\n", kernel_filename);
-            exit(1);
-        }
-        /* load initrd */
-        if (initrd_filename) {
-            initrd_base = round_page(kernel_base + kernel_size + KERNEL_GAP);
-            initrd_size = load_image_targphys(initrd_filename, initrd_base,
-                                              ram_size - initrd_base);
-            if (initrd_size < 0) {
-                hw_error("qemu: could not load initial ram disk '%s'\n",
-                         initrd_filename);
-                exit(1);
-            }
-            cmdline_base = round_page(initrd_base + initrd_size);
-        } else {
-            initrd_base = 0;
-            initrd_size = 0;
-            cmdline_base = round_page(kernel_base + kernel_size + KERNEL_GAP);
-        }
-        ppc_boot_device = 'm';
-    } else {
-        kernel_base = 0;
-        kernel_size = 0;
-        initrd_base = 0;
-        initrd_size = 0;
-        ppc_boot_device = '\0';
-        /* We consider that NewWorld PowerMac never have any floppy drive
-         * For now, OHW cannot boot from the network.
-         */
-        for (i = 0; boot_device[i] != '\0'; i++) {
-            if (boot_device[i] >= 'c' && boot_device[i] <= 'f') {
-                ppc_boot_device = boot_device[i];
-                break;
-            }
-        }
-        if (ppc_boot_device == '\0') {
-            fprintf(stderr, "No valid boot device for Mac99 machine\n");
-            exit(1);
-        }
-    }
-
-    /* Register 8 MB of ISA IO space */
-    isa_mmio_init(0xf2000000, 0x00800000);
-
-    /* UniN init */
-    memory_region_init_io(unin_memory, &unin_ops, NULL, "unin", 0x1000);
-    memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory);
-
-    openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
-    openpic_irqs[0] =
-        g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
-    for (i = 0; i < smp_cpus; i++) {
-        /* Mac99 IRQ connection between OpenPIC outputs pins
-         * and PowerPC input pins
-         */
-        switch (PPC_INPUT(env)) {
-        case PPC_FLAGS_INPUT_6xx:
-            openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
-            openpic_irqs[i][OPENPIC_OUTPUT_INT] =
-                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
-            openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
-                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
-            openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
-                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_MCP];
-            /* Not connected ? */
-            openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;
-            /* Check this */
-            openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
-                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_HRESET];
-            break;
-#if defined(TARGET_PPC64)
-        case PPC_FLAGS_INPUT_970:
-            openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB);
-            openpic_irqs[i][OPENPIC_OUTPUT_INT] =
-                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
-            openpic_irqs[i][OPENPIC_OUTPUT_CINT] =
-                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT];
-            openpic_irqs[i][OPENPIC_OUTPUT_MCK] =
-                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_MCP];
-            /* Not connected ? */
-            openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL;
-            /* Check this */
-            openpic_irqs[i][OPENPIC_OUTPUT_RESET] =
-                ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_HRESET];
-            break;
-#endif /* defined(TARGET_PPC64) */
-        default:
-            hw_error("Bus model not supported on mac99 machine\n");
-            exit(1);
-        }
-    }
-
-    pic = g_new(qemu_irq, 64);
-
-    dev = qdev_create(NULL, "openpic");
-    qdev_prop_set_uint32(dev, "model", OPENPIC_MODEL_RAVEN);
-    qdev_init_nofail(dev);
-    s = SYS_BUS_DEVICE(dev);
-    pic_mem = s->mmio[0].memory;
-    k = 0;
-    for (i = 0; i < smp_cpus; i++) {
-        for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
-            sysbus_connect_irq(s, k++, openpic_irqs[i][j]);
-        }
-    }
-
-    for (i = 0; i < 64; i++) {
-        pic[i] = qdev_get_gpio_in(dev, i);
-    }
-
-    if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
-        /* 970 gets a U3 bus */
-        pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io());
-        machine_arch = ARCH_MAC99_U3;
-    } else {
-        pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io());
-        machine_arch = ARCH_MAC99;
-    }
-    /* init basic PC hardware */
-    pci_vga_init(pci_bus);
-
-    escc_mem = escc_init(0, pic[0x25], pic[0x24],
-                         serial_hds[0], serial_hds[1], ESCC_CLOCK, 4);
-    memory_region_init_alias(escc_bar, "escc-bar",
-                             escc_mem, 0, memory_region_size(escc_mem));
-
-    for(i = 0; i < nb_nics; i++)
-        pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
-
-    ide_drive_get(hd, MAX_IDE_BUS);
-    dbdma = DBDMA_init(&dbdma_mem);
-
-    /* We only emulate 2 out of 3 IDE controllers for now */
-    ide_mem[0] = NULL;
-    ide_mem[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]);
-    ide_mem[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]);
-
-    cuda_init(&cuda_mem, pic[0x19]);
-
-    adb_kbd_init(&adb_bus);
-    adb_mouse_init(&adb_bus);
-
-    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem,
-               dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_bar);
-
-    if (usb_enabled(machine_arch == ARCH_MAC99_U3)) {
-        pci_create_simple(pci_bus, -1, "pci-ohci");
-        /* U3 needs to use USB for input because Linux doesn't support via-cuda
-        on PPC64 */
-        if (machine_arch == ARCH_MAC99_U3) {
-            usbdevice_create("keyboard");
-            usbdevice_create("mouse");
-        }
-    }
-
-    if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
-        graphic_depth = 15;
-
-    /* The NewWorld NVRAM is not located in the MacIO device */
-    nvr = macio_nvram_init(0x2000, 1);
-    pmac_format_nvram_partition(nvr, 0x2000);
-    macio_nvram_setup_bar(nvr, get_system_memory(), 0xFFF04000);
-    /* No PCI init: the BIOS will do it */
-
-    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
-    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
-    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
-    if (kernel_cmdline) {
-        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base);
-        pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline);
-    } else {
-        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
-    }
-    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
-    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device);
-
-    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width);
-    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height);
-    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth);
-
-    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
-    if (kvm_enabled()) {
-#ifdef CONFIG_KVM
-        uint8_t *hypercall;
-
-        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq());
-        hypercall = g_malloc(16);
-        kvmppc_get_hypercall(env, hypercall, 16);
-        fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
-        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
-#endif
-    } else {
-        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec());
-    }
-
-    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
-}
-
-static QEMUMachine core99_machine = {
-    .name = "mac99",
-    .desc = "Mac99 based PowerMAC",
-    .init = ppc_core99_init,
-    .max_cpus = MAX_CPUS,
-#ifdef TARGET_PPC64
-    .is_default = 1,
-#endif
-    DEFAULT_MACHINE_OPTIONS,
-};
-
-static void core99_machine_init(void)
-{
-    qemu_register_machine(&core99_machine);
-}
-
-machine_init(core99_machine_init);
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
deleted file mode 100644
index de34e75..0000000
--- a/hw/ppc_oldworld.c
+++ /dev/null
@@ -1,352 +0,0 @@
-
-/*
- * QEMU OldWorld PowerMac (currently ~G3 Beige) hardware System Emulator
- *
- * Copyright (c) 2004-2007 Fabrice Bellard
- * Copyright (c) 2007 Jocelyn Mayer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "hw.h"
-#include "ppc.h"
-#include "ppc_mac.h"
-#include "adb.h"
-#include "mac_dbdma.h"
-#include "nvram.h"
-#include "sysemu/sysemu.h"
-#include "net/net.h"
-#include "isa.h"
-#include "pci/pci.h"
-#include "boards.h"
-#include "fw_cfg.h"
-#include "escc.h"
-#include "ide.h"
-#include "loader.h"
-#include "elf.h"
-#include "sysemu/kvm.h"
-#include "kvm_ppc.h"
-#include "sysemu/blockdev.h"
-#include "exec/address-spaces.h"
-
-#define MAX_IDE_BUS 2
-#define CFG_ADDR 0xf0000510
-
-static int fw_cfg_boot_set(void *opaque, const char *boot_device)
-{
-    fw_cfg_add_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
-    return 0;
-}
-
-
-static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
-{
-    return (addr & 0x0fffffff) + KERNEL_LOAD_ADDR;
-}
-
-static hwaddr round_page(hwaddr addr)
-{
-    return (addr + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
-}
-
-static void ppc_heathrow_reset(void *opaque)
-{
-    PowerPCCPU *cpu = opaque;
-
-    cpu_reset(CPU(cpu));
-}
-
-static void ppc_heathrow_init(QEMUMachineInitArgs *args)
-{
-    ram_addr_t ram_size = args->ram_size;
-    const char *cpu_model = args->cpu_model;
-    const char *kernel_filename = args->kernel_filename;
-    const char *kernel_cmdline = args->kernel_cmdline;
-    const char *initrd_filename = args->initrd_filename;
-    const char *boot_device = args->boot_device;
-    MemoryRegion *sysmem = get_system_memory();
-    PowerPCCPU *cpu = NULL;
-    CPUPPCState *env = NULL;
-    char *filename;
-    qemu_irq *pic, **heathrow_irqs;
-    int linux_boot, i;
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
-    MemoryRegion *bios = g_new(MemoryRegion, 1);
-    uint32_t kernel_base, initrd_base, cmdline_base = 0;
-    int32_t kernel_size, initrd_size;
-    PCIBus *pci_bus;
-    MacIONVRAMState *nvr;
-    int bios_size;
-    MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem;
-    MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1), *ide_mem[2];
-    uint16_t ppc_boot_device;
-    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
-    void *fw_cfg;
-    void *dbdma;
-
-    linux_boot = (kernel_filename != NULL);
-
-    /* init CPUs */
-    if (cpu_model == NULL)
-        cpu_model = "G3";
-    for (i = 0; i < smp_cpus; i++) {
-        cpu = cpu_ppc_init(cpu_model);
-        if (cpu == NULL) {
-            fprintf(stderr, "Unable to find PowerPC CPU definition\n");
-            exit(1);
-        }
-        env = &cpu->env;
-
-        /* Set time-base frequency to 16.6 Mhz */
-        cpu_ppc_tb_init(env,  16600000UL);
-        qemu_register_reset(ppc_heathrow_reset, cpu);
-    }
-
-    /* allocate RAM */
-    if (ram_size > (2047 << 20)) {
-        fprintf(stderr,
-                "qemu: Too much memory for this machine: %d MB, maximum 2047 MB\n",
-                ((unsigned int)ram_size / (1 << 20)));
-        exit(1);
-    }
-
-    memory_region_init_ram(ram, "ppc_heathrow.ram", ram_size);
-    vmstate_register_ram_global(ram);
-    memory_region_add_subregion(sysmem, 0, ram);
-
-    /* allocate and load BIOS */
-    memory_region_init_ram(bios, "ppc_heathrow.bios", BIOS_SIZE);
-    vmstate_register_ram_global(bios);
-    if (bios_name == NULL)
-        bios_name = PROM_FILENAME;
-    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-    memory_region_set_readonly(bios, true);
-    memory_region_add_subregion(sysmem, PROM_ADDR, bios);
-
-    /* Load OpenBIOS (ELF) */
-    if (filename) {
-        bios_size = load_elf(filename, 0, NULL, NULL, NULL, NULL,
-                             1, ELF_MACHINE, 0);
-        g_free(filename);
-    } else {
-        bios_size = -1;
-    }
-    if (bios_size < 0 || bios_size > BIOS_SIZE) {
-        hw_error("qemu: could not load PowerPC bios '%s'\n", bios_name);
-        exit(1);
-    }
-
-    if (linux_boot) {
-        uint64_t lowaddr = 0;
-        int bswap_needed;
-
-#ifdef BSWAP_NEEDED
-        bswap_needed = 1;
-#else
-        bswap_needed = 0;
-#endif
-        kernel_base = KERNEL_LOAD_ADDR;
-        kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
-                               NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0);
-        if (kernel_size < 0)
-            kernel_size = load_aout(kernel_filename, kernel_base,
-                                    ram_size - kernel_base, bswap_needed,
-                                    TARGET_PAGE_SIZE);
-        if (kernel_size < 0)
-            kernel_size = load_image_targphys(kernel_filename,
-                                              kernel_base,
-                                              ram_size - kernel_base);
-        if (kernel_size < 0) {
-            hw_error("qemu: could not load kernel '%s'\n",
-                      kernel_filename);
-            exit(1);
-        }
-        /* load initrd */
-        if (initrd_filename) {
-            initrd_base = round_page(kernel_base + kernel_size + KERNEL_GAP);
-            initrd_size = load_image_targphys(initrd_filename, initrd_base,
-                                              ram_size - initrd_base);
-            if (initrd_size < 0) {
-                hw_error("qemu: could not load initial ram disk '%s'\n",
-                         initrd_filename);
-                exit(1);
-            }
-            cmdline_base = round_page(initrd_base + initrd_size);
-        } else {
-            initrd_base = 0;
-            initrd_size = 0;
-            cmdline_base = round_page(kernel_base + kernel_size + KERNEL_GAP);
-        }
-        ppc_boot_device = 'm';
-    } else {
-        kernel_base = 0;
-        kernel_size = 0;
-        initrd_base = 0;
-        initrd_size = 0;
-        ppc_boot_device = '\0';
-        for (i = 0; boot_device[i] != '\0'; i++) {
-            /* TOFIX: for now, the second IDE channel is not properly
-             *        used by OHW. The Mac floppy disk are not emulated.
-             *        For now, OHW cannot boot from the network.
-             */
-#if 0
-            if (boot_device[i] >= 'a' && boot_device[i] <= 'f') {
-                ppc_boot_device = boot_device[i];
-                break;
-            }
-#else
-            if (boot_device[i] >= 'c' && boot_device[i] <= 'd') {
-                ppc_boot_device = boot_device[i];
-                break;
-            }
-#endif
-        }
-        if (ppc_boot_device == '\0') {
-            fprintf(stderr, "No valid boot device for G3 Beige machine\n");
-            exit(1);
-        }
-    }
-
-    /* Register 2 MB of ISA IO space */
-    isa_mmio_init(0xfe000000, 0x00200000);
-
-    /* XXX: we register only 1 output pin for heathrow PIC */
-    heathrow_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
-    heathrow_irqs[0] =
-        g_malloc0(smp_cpus * sizeof(qemu_irq) * 1);
-    /* Connect the heathrow PIC outputs to the 6xx bus */
-    for (i = 0; i < smp_cpus; i++) {
-        switch (PPC_INPUT(env)) {
-        case PPC_FLAGS_INPUT_6xx:
-            heathrow_irqs[i] = heathrow_irqs[0] + (i * 1);
-            heathrow_irqs[i][0] =
-                ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
-            break;
-        default:
-            hw_error("Bus model not supported on OldWorld Mac machine\n");
-        }
-    }
-
-    /* init basic PC hardware */
-    if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
-        hw_error("Only 6xx bus is supported on heathrow machine\n");
-    }
-    pic = heathrow_pic_init(&pic_mem, 1, heathrow_irqs);
-    pci_bus = pci_grackle_init(0xfec00000, pic,
-                               get_system_memory(),
-                               get_system_io());
-    pci_vga_init(pci_bus);
-
-    escc_mem = escc_init(0, pic[0x0f], pic[0x10], serial_hds[0],
-                               serial_hds[1], ESCC_CLOCK, 4);
-    memory_region_init_alias(escc_bar, "escc-bar",
-                             escc_mem, 0, memory_region_size(escc_mem));
-
-    for(i = 0; i < nb_nics; i++)
-        pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
-
-
-    ide_drive_get(hd, MAX_IDE_BUS);
-
-    /* First IDE channel is a MAC IDE on the MacIO bus */
-    dbdma = DBDMA_init(&dbdma_mem);
-    ide_mem[0] = NULL;
-    ide_mem[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]);
-
-    /* Second IDE channel is a CMD646 on the PCI bus */
-    hd[0] = hd[MAX_IDE_DEVS];
-    hd[1] = hd[MAX_IDE_DEVS + 1];
-    hd[3] = hd[2] = NULL;
-    pci_cmd646_ide_init(pci_bus, hd, 0);
-
-    /* cuda also initialize ADB */
-    cuda_init(&cuda_mem, pic[0x12]);
-
-    adb_kbd_init(&adb_bus);
-    adb_mouse_init(&adb_bus);
-
-    nvr = macio_nvram_init(0x2000, 4);
-    pmac_format_nvram_partition(nvr, 0x2000);
-
-    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem,
-               dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_bar);
-
-    if (usb_enabled(false)) {
-        pci_create_simple(pci_bus, -1, "pci-ohci");
-    }
-
-    if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
-        graphic_depth = 15;
-
-    /* No PCI init: the BIOS will do it */
-
-    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
-    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
-    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
-    if (kernel_cmdline) {
-        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base);
-        pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline);
-    } else {
-        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
-    }
-    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
-    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device);
-
-    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width);
-    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height);
-    fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth);
-
-    fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
-    if (kvm_enabled()) {
-#ifdef CONFIG_KVM
-        uint8_t *hypercall;
-
-        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq());
-        hypercall = g_malloc(16);
-        kvmppc_get_hypercall(env, hypercall, 16);
-        fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
-        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
-#endif
-    } else {
-        fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec());
-    }
-
-    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
-}
-
-static QEMUMachine heathrow_machine = {
-    .name = "g3beige",
-    .desc = "Heathrow based PowerMAC",
-    .init = ppc_heathrow_init,
-    .max_cpus = MAX_CPUS,
-#ifndef TARGET_PPC64
-    .is_default = 1,
-#endif
-    DEFAULT_MACHINE_OPTIONS,
-};
-
-static void heathrow_machine_init(void)
-{
-    qemu_register_machine(&heathrow_machine);
-}
-
-machine_init(heathrow_machine_init);
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 4675792..f1c3c20 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -22,7 +22,7 @@
  * THE SOFTWARE.
  */
 #include "hw.h"
-#include "ppc_mac.h"
+#include "ppc/mac.h"
 #include "pci/pci.h"
 #include "pci/pci_host.h"
 


More information about the Spice-commits mailing list