[Spice-commits] 89 commits - HACKING bsd-user/qemu-types.h bsd-user/qemu.h configure cpu-all.h exec-all.h exec.c fsdev/virtfs-proxy-helper.c hw/a9mpcore.c hw/acpi.c hw/acpi.h hw/acpi_ich9.c hw/acpi_ich9.h hw/acpi_piix4.c hw/apm.c hw/apm.h hw/cirrus_vga.c hw/device-hotplug.c hw/dma.c hw/ich9.h hw/isa-bus.c hw/isa.h hw/lpc_ich9.c hw/mips_mipssim.c hw/pc.c hw/pc_piix.c hw/pc_sysfw.c hw/pci-hotplug.c hw/pm_smbus.c hw/pm_smbus.h hw/qdev-core.h hw/qdev.c hw/s390x hw/sd.c hw/serial.c hw/serial.h hw/smbus_ich9.c hw/usb hw/usb.h hw/vt82c686.c hw/xilinx_axienet.c hw/xilinx_uartlite.c linux-user/arm linux-user/i386 linux-user/qemu-types.h linux-user/qemu.h linux-user/sparc linux-user/strace.list linux-user/syscall.c linux-user/unicore32 net/tap-win32.c qapi/qmp-registry.c qemu-common.h qemu-config.c qemu-options.hx qemu-types.h qemu-user-types.h qga/channel-posix.c qlist.h slirp/ip_icmp.c sysemu.h target-alpha/cpu.h target-alpha/translate.c target-arm/translate.c target-cris/translate.c target -i386/cpu.c target-i386/cpu.h target-i386/translate.c target-lm32/translate.c target-m68k/cpu.h target-m68k/translate.c target-microblaze/translate.c target-mips/dsp_helper.c target-mips/translate.c target-openrisc/translate.c target-ppc/translate.c target-s390x/translate.c target-sh4/translate.c target-sparc/cpu.h target-sparc/translate.c target-unicore32/translate.c target-xtensa/cpu.c target-xtensa/cpu.h target-xtensa/helper.c target-xtensa/helper.h target-xtensa/op_helper.c target-xtensa/overlay_tool.h target-xtensa/translate.c tcg/tcg.h tests/qemu-iotests tests/tcg translate-all.c ui/curses.c ui/vnc-palette.c uri.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Mon Dec 10 23:28:29 PST 2012


 HACKING                            |   20 +
 bsd-user/qemu-types.h              |   24 --
 bsd-user/qemu.h                    |    2 
 configure                          |   21 +-
 cpu-all.h                          |    2 
 exec-all.h                         |    4 
 exec.c                             |    2 
 fsdev/virtfs-proxy-helper.c        |   93 ++++++---
 hw/a9mpcore.c                      |    1 
 hw/acpi.c                          |  113 +++++++++--
 hw/acpi.h                          |   18 -
 hw/acpi_ich9.c                     |  199 +++++--------------
 hw/acpi_ich9.h                     |    3 
 hw/acpi_piix4.c                    |  185 ++++++++----------
 hw/apm.c                           |   23 +-
 hw/apm.h                           |    5 
 hw/cirrus_vga.c                    |   48 ++--
 hw/device-hotplug.c                |   11 -
 hw/dma.c                           |  106 ++++++----
 hw/ich9.h                          |    1 
 hw/isa-bus.c                       |    9 
 hw/isa.h                           |    1 
 hw/lpc_ich9.c                      |   31 ++-
 hw/mips_mipssim.c                  |    3 
 hw/pc.c                            |   49 +++-
 hw/pc_piix.c                       |   24 ++
 hw/pc_sysfw.c                      |    4 
 hw/pci-hotplug.c                   |    7 
 hw/pm_smbus.c                      |   17 +
 hw/pm_smbus.h                      |    3 
 hw/qdev-core.h                     |   11 -
 hw/qdev.c                          |    8 
 hw/s390x/sclp.h                    |    4 
 hw/s390x/sclpconsole.c             |    4 
 hw/sd.c                            |    4 
 hw/serial.c                        |    4 
 hw/serial.h                        |    2 
 hw/smbus_ich9.c                    |   64 +-----
 hw/usb.h                           |    8 
 hw/usb/bus.c                       |    3 
 hw/usb/core.c                      |    4 
 hw/usb/dev-hid.c                   |   85 ++++++++
 hw/usb/dev-hub.c                   |    2 
 hw/usb/dev-network.c               |    7 
 hw/usb/dev-wacom.c                 |    4 
 hw/usb/hcd-ehci.c                  |   39 +++
 hw/usb/hcd-ehci.h                  |    1 
 hw/usb/host-bsd.c                  |    1 
 hw/usb/host-linux.c                |    1 
 hw/usb/redirect.c                  |    4 
 hw/vt82c686.c                      |  104 +---------
 hw/xilinx_axienet.c                |    4 
 hw/xilinx_uartlite.c               |    7 
 linux-user/arm/syscall_nr.h        |    4 
 linux-user/i386/syscall_nr.h       |    4 
 linux-user/qemu-types.h            |   36 ---
 linux-user/qemu.h                  |    2 
 linux-user/sparc/syscall_nr.h      |    4 
 linux-user/strace.list             |    6 
 linux-user/syscall.c               |   18 -
 linux-user/unicore32/syscall_nr.h  |    4 
 net/tap-win32.c                    |    7 
 qapi/qmp-registry.c                |    2 
 qemu-common.h                      |   52 -----
 qemu-config.c                      |   49 ----
 qemu-options.hx                    |    2 
 qemu-types.h                       |   61 +++++
 qemu-user-types.h                  |   36 +++
 qga/channel-posix.c                |    5 
 qlist.h                            |    1 
 slirp/ip_icmp.c                    |    2 
 sysemu.h                           |    5 
 target-alpha/cpu.h                 |    7 
 target-alpha/translate.c           |   12 -
 target-arm/translate.c             |   12 -
 target-cris/translate.c            |   14 -
 target-i386/cpu.c                  |  105 ++++++----
 target-i386/cpu.h                  |    2 
 target-i386/translate.c            |   19 -
 target-lm32/translate.c            |   12 -
 target-m68k/cpu.h                  |    3 
 target-m68k/translate.c            |   12 -
 target-microblaze/translate.c      |   12 -
 target-mips/dsp_helper.c           |   19 -
 target-mips/translate.c            |   12 -
 target-openrisc/translate.c        |   12 -
 target-ppc/translate.c             |   12 -
 target-s390x/translate.c           |   12 -
 target-sh4/translate.c             |   12 -
 target-sparc/cpu.h                 |    1 
 target-sparc/translate.c           |   12 -
 target-unicore32/translate.c       |   12 -
 target-xtensa/cpu.c                |    3 
 target-xtensa/cpu.h                |   14 +
 target-xtensa/helper.c             |   75 +++++--
 target-xtensa/helper.h             |    1 
 target-xtensa/op_helper.c          |   57 +++++
 target-xtensa/overlay_tool.h       |   12 +
 target-xtensa/translate.c          |  377 ++++++++++++++++++++-----------------
 tcg/tcg.h                          |    7 
 tests/qemu-iotests/iotests.py      |    2 
 tests/tcg/mips/mips32-dsp/insv.c   |    2 
 tests/tcg/mips/mips32-dsp/shilo.c  |   18 +
 tests/tcg/mips/mips32-dsp/shilov.c |   20 +
 tests/tcg/xtensa/Makefile          |    2 
 tests/tcg/xtensa/macros.inc        |    2 
 tests/tcg/xtensa/test_s32c1i.S     |   39 +++
 tests/tcg/xtensa/test_sr.S         |   90 ++++++++
 translate-all.c                    |    9 
 ui/curses.c                        |    4 
 ui/vnc-palette.c                   |    2 
 uri.c                              |    4 
 112 files changed, 1626 insertions(+), 1132 deletions(-)

New commits:
commit 1c97e303d4ea80a2691334b0febe87a50660f99d
Merge: 7c12fd9... b34d12d...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Dec 10 08:35:15 2012 -0600

    Merge remote-tracking branch 'afaerber/qom-cpu' into staging
    
    * afaerber/qom-cpu:
      target-i386: Postpone cpuid_level update to realize time
      target-i386: Use define for cpuid vendor string size
      target-i386: Separate feature string parsing from CPU model lookup
      target-i386/cpu.c: Coding style fixes
      qdev: qdev_create(): use error_report() instead of hw_error()
      sysemu.h: Include qemu-types.h instead of qemu-common.h
      Create qemu-types.h for struct typedefs
      qlist.h: Do not include qemu-common.h
      qga/channel-posix.c: Include headers it needs
      qapi/qmp-registry.c: Include headers it needs
      ui/vnc-palette.c: Include headers it needs
      user: Rename qemu-types.h to qemu-user-types.h
      user: Move *-user/qemu-types.h to main directory
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 7c12fd9b29c6ca2119396f143d84706f2fba6222
Merge: 8385b17... 654598c...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Dec 10 08:34:29 2012 -0600

    Merge remote-tracking branch 'stefanha/trivial-patches' into staging
    
    * stefanha/trivial-patches:
      pc_sysfw: Plug memory leak on pc_fw_add_pflash_drv() error path
      qemu-options: Fix space at EOL
      Fix spelling in comments and documentation
      Clean up pci_drive_hot_add()'s use of BlockInterfaceType
      arm: a9mpcore: remove un-used ptimer_iomem field
      target-sparc: Remove t0, t1 from CPUSPARCState
      target-m68k: Remove t1 from CPUM68KState
      target-alpha: Remove t0, t1 from CPUAlphaState
      s390x: Spelling fixes (endianess -> endianness, occured -> occurred)
      Fix comments (adress -> address, layed -> laid, wierd -> weird)
      Fix spelling (prefered -> preferred)
      configure: Remove stray debug output
      sd: Send debug printfery to stderr not stdout
    
    Conflicts:
    	configure
    
    Resolve spelling conflict in configure.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --cc configure
index e5aedef,79605d2..38b1cc6
--- a/configure
+++ b/configure
@@@ -2138,8 -2129,8 +2138,8 @@@ if test "$pixman" = "system"; the
    pixman_libs=`$pkg_config --libs pixman-1 2>/dev/null`
  else
    if test ! -d ${source_path}/pixman/pixman; then
 -    echo "ERROR: pixman not present. Your options:"
 +    echo "ERROR: pixman not present (or older than 0.18.4). Your options:"
-     echo "  (1) Prefered: Install the pixman devel package (any recent"
+     echo "  (1) Preferred: Install the pixman devel package (any recent"
      echo "      distro should have packages as Xorg needs pixman too)."
      echo "  (2) Fetch the pixman submodule, using:"
      echo "      git submodule update --init pixman"
commit 8385b173a0ca4c2345434104e6cc2a7259adc4b9
Merge: 16ef55c... 3e43749...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Dec 10 08:33:11 2012 -0600

    Merge remote-tracking branch 'kraxel/acpi.1' into staging
    
    * kraxel/acpi.1:
      acpi: drop debug port
      q35: update lpc pci config space according to configured devices
      apci: switch piix4 pci hotplug to memory api
      acpi: remove acpi_gpe_blk
      apci: switch piix4 gpe to memory api
      acpi: fix piix4 smbus mapping
      acpi: switch smbus to memory api
      acpi: cleanup ich9 memory region
      apci: switch ich9 smi to memory api
      apci: switch ich9 gpe to memory api
      acpi: cleanup vt82c686 memory region
      acpi: cleanup piix4 memory region
      apci: switch evt to memory api
      apci: switch cnt to memory api
      apci: switch timer to memory api
      apci: switch vt82c686 to memory api
      apci: switch ich9 to memory api
      apci: switch piix4 to memory api
    
    Conflicts:
    	hw/lpc_ich9.c
    
    Resolved merge conflict due to apm_init adding an argument.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --cc hw/acpi_piix4.c
index dbddde1,b03454e..0b5b0d3
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@@ -438,10 -391,8 +391,8 @@@ static int piix4_pm_initfn(PCIDevice *d
      pci_conf[0x3d] = 0x01; // interrupt pin 1
  
      /* APM */
 -    apm_init(&s->apm, apm_ctrl_changed, s);
 +    apm_init(dev, &s->apm, apm_ctrl_changed, s);
  
-     register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s);
- 
      if (s->kvm_enabled) {
          /* Mark SMM as already inited to prevent SMM from running.  KVM does not
           * support SMM mode. */
diff --cc hw/lpc_ich9.c
index 7de5427,6585236..878a43e
--- a/hw/lpc_ich9.c
+++ b/hw/lpc_ich9.c
@@@ -472,7 -497,11 +497,11 @@@ static int ich9_lpc_initfn(PCIDevice *d
      lpc->isa_bus = isa_bus;
  
      ich9_cc_init(lpc);
 -    apm_init(&lpc->apm, ich9_apm_ctrl_changed, lpc);
 +    apm_init(d, &lpc->apm, ich9_apm_ctrl_changed, lpc);
+ 
+     lpc->machine_ready.notify = ich9_lpc_machine_ready;
+     qemu_add_machine_init_done_notifier(&lpc->machine_ready);
+ 
      return 0;
  }
  
diff --cc hw/vt82c686.c
index 7f11dbe,5016e95..57d16c0
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@@ -424,15 -351,18 +351,18 @@@ static int vt82c686b_pm_initfn(PCIDevic
      pci_conf[0x90] = s->smb_io_base | 1;
      pci_conf[0x91] = s->smb_io_base >> 8;
      pci_conf[0xd2] = 0x90;
-     register_ioport_write(s->smb_io_base, 0xf, 1, smb_ioport_writeb, &s->smb);
-     register_ioport_read(s->smb_io_base, 0xf, 1, smb_ioport_readb, &s->smb);
+     pm_smbus_init(&s->dev.qdev, &s->smb);
+     memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io);
  
 -    apm_init(&s->apm, NULL, s);
 +    apm_init(dev, &s->apm, NULL, s);
  
-     acpi_pm_tmr_init(&s->ar, pm_tmr_timer);
-     acpi_pm1_cnt_init(&s->ar);
+     memory_region_init(&s->io, "vt82c686-pm", 64);
+     memory_region_set_enabled(&s->io, false);
+     memory_region_add_subregion(get_system_io(), 0, &s->io);
  
-     pm_smbus_init(&s->dev.qdev, &s->smb);
+     acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
+     acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
+     acpi_pm1_cnt_init(&s->ar, &s->io);
  
      return 0;
  }
commit 16ef55ca85ac8c8fcac46547108bd1c8b44943a2
Merge: c62adbe... 9fd2ecd...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Dec 10 08:32:15 2012 -0600

    Merge remote-tracking branch 'aneesh/for-upstream' into staging
    
    * aneesh/for-upstream:
      virtfs-proxy-helper: use setresuid and setresgid
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit c62adbee15deae473aa02a37193ddd6b054b0c9f
Merge: e49d021... 427e3aa...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Dec 10 08:31:19 2012 -0600

    Merge remote-tracking branch 'kraxel/usb.74' into staging
    
    * kraxel/usb.74:
      usb-tablet: Allow connecting to ehci
      ehci: Lower timer freq when the periodic schedule is idle
      usb: Allow overriding of usb_desc at the device level
      usb: Don't allow USB_RET_ASYNC for interrupt packets
      usb: Call wakeup when data becomes available for all devices with int eps
      add pc-1.4
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit e49d021e574c3ee8e443bcc84d1fb7dfb4c87c42
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Dec 7 15:39:13 2012 +0000

    configure: Default to 'cc', not 'gcc'
    
    Default to 'cc' as our compiler, rather than 'gcc'. We used to have
    to insist on gcc when we still kept the CPU env in a fixed global
    register, but this is no longer necessary and we will now compile OK
    on clang as well as gcc.  Using 'cc' should generally result in us
    using the most standard and maintained system compiler for the
    platform.  (For instance on newer MacOS X 'gcc' exists but is an
    elderly compiler provided mostly for legacy reasons, and 'cc'
    (which is clang) is definitely the better choice.) On Linux there
    will generally be no user-visible change since cc will be gcc.
    
    This changeover necessitates a slight reworking of how we set the
    'cc' variable, because GNU cross toolchains generally provide a
    '${cross_prefix}gcc' but not a '${cross_prefix}cc'.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/configure b/configure
index 44034d6..e5aedef 100755
--- a/configure
+++ b/configure
@@ -116,7 +116,7 @@ audio_drv_list=""
 audio_card_list="ac97 es1370 sb16 hda"
 audio_possible_cards="ac97 es1370 sb16 cs4231a adlib gus hda"
 block_drv_whitelist=""
-host_cc="gcc"
+host_cc="cc"
 libs_softmmu=""
 libs_tools=""
 audio_pt_int=""
@@ -250,7 +250,16 @@ done
 # Using uname is really, really broken.  Once we have the right set of checks
 # we can eliminate its usage altogether.
 
-cc="${CC-${cross_prefix}gcc}"
+# Preferred compiler:
+#  ${CC} (if set)
+#  ${cross_prefix}gcc (if cross-prefix specified)
+#  system compiler
+if test -z "${CC}${cross_prefix}"; then
+  cc="$host_cc"
+else
+  cc="${CC-${cross_prefix}gcc}"
+fi
+
 ar="${AR-${cross_prefix}ar}"
 objcopy="${OBJCOPY-${cross_prefix}objcopy}"
 ld="${LD-${cross_prefix}ld}"
commit 24c35a504e8b09e697d0268bbefb2a329b901611
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Oct 12 03:55:51 2012 +0000

    linux-user: Merge pread/pwrite into pread64/pwrite64
    
    The Linux syscalls underlying pread() and pwrite() take a 64 bit
    offset on all architectures, even if some of them name the syscall
    "pread/pwrite" rather than "pread64/pwrite64" for historical reasons.
    So move the four QEMU target architectures (arm, i386, sparc,
    unicore32) which were defining TARGET_NR_pread/pwrite to define
    TARGET_NR_pread64/pwrite64 instead, and drop the TARGET_NR_pread/pwrite
    implementation code completely.
    
    (Based on examination of the kernel sources for the four architectures
    this patch affects.)
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/linux-user/arm/syscall_nr.h b/linux-user/arm/syscall_nr.h
index 5356395..42d6855 100644
--- a/linux-user/arm/syscall_nr.h
+++ b/linux-user/arm/syscall_nr.h
@@ -182,8 +182,8 @@
 #define TARGET_NR_rt_sigtimedwait		(177)
 #define TARGET_NR_rt_sigqueueinfo		(178)
 #define TARGET_NR_rt_sigsuspend		(179)
-#define TARGET_NR_pread			(180)
-#define TARGET_NR_pwrite			(181)
+#define TARGET_NR_pread64                       (180)
+#define TARGET_NR_pwrite64                      (181)
 #define TARGET_NR_chown			(182)
 #define TARGET_NR_getcwd			(183)
 #define TARGET_NR_capget			(184)
diff --git a/linux-user/i386/syscall_nr.h b/linux-user/i386/syscall_nr.h
index 74abfca..f080305 100644
--- a/linux-user/i386/syscall_nr.h
+++ b/linux-user/i386/syscall_nr.h
@@ -182,8 +182,8 @@
 #define TARGET_NR_rt_sigtimedwait	177
 #define TARGET_NR_rt_sigqueueinfo	178
 #define TARGET_NR_rt_sigsuspend	179
-#define TARGET_NR_pread		180
-#define TARGET_NR_pwrite		181
+#define TARGET_NR_pread64               180
+#define TARGET_NR_pwrite64              181
 #define TARGET_NR_chown		182
 #define TARGET_NR_getcwd		183
 #define TARGET_NR_capget		184
diff --git a/linux-user/sparc/syscall_nr.h b/linux-user/sparc/syscall_nr.h
index f201f9f..061711c 100644
--- a/linux-user/sparc/syscall_nr.h
+++ b/linux-user/sparc/syscall_nr.h
@@ -62,8 +62,8 @@
 #define TARGET_NR_getpagesize         64 /* Common                                      */
 #define TARGET_NR_msync               65 /* Common in newer 1.3.x revs...               */
 #define TARGET_NR_vfork               66 /* Common                                      */
-#define TARGET_NR_pread               67 /* Linux Specific                              */
-#define TARGET_NR_pwrite              68 /* Linux Specific                              */
+#define TARGET_NR_pread64             67 /* Linux Specific */
+#define TARGET_NR_pwrite64            68 /* Linux Specific */
 #define TARGET_NR_geteuid32           69 /* Linux sparc32, sbrk under SunOS             */
 #define TARGET_NR_getegid32           70 /* Linux sparc32, sstk under SunOS             */
 #define TARGET_NR_mmap                71 /* Common                                      */
diff --git a/linux-user/strace.list b/linux-user/strace.list
index af3c6a0..08f115d 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -972,9 +972,6 @@
 #ifdef TARGET_NR_prctl
 { TARGET_NR_prctl, "prctl" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_pread
-{ TARGET_NR_pread, "pread" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_pread64
 { TARGET_NR_pread64, "pread64" , NULL, NULL, NULL },
 #endif
@@ -993,9 +990,6 @@
 #ifdef TARGET_NR_putpmsg
 { TARGET_NR_putpmsg, "putpmsg" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_pwrite
-{ TARGET_NR_pwrite, "pwrite" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_pwrite64
 { TARGET_NR_pwrite64, "pwrite64" , NULL, NULL, NULL },
 #endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e4291ed..31d5276 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7449,24 +7449,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         goto unimplemented;
 #endif
 #endif
-#ifdef TARGET_NR_pread
-    case TARGET_NR_pread:
-        if (regpairs_aligned(cpu_env))
-            arg4 = arg5;
-        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
-            goto efault;
-        ret = get_errno(pread(arg1, p, arg3, arg4));
-        unlock_user(p, arg2, ret);
-        break;
-    case TARGET_NR_pwrite:
-        if (regpairs_aligned(cpu_env))
-            arg4 = arg5;
-        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
-            goto efault;
-        ret = get_errno(pwrite(arg1, p, arg3, arg4));
-        unlock_user(p, arg2, 0);
-        break;
-#endif
 #ifdef TARGET_NR_pread64
     case TARGET_NR_pread64:
         if (regpairs_aligned(cpu_env)) {
diff --git a/linux-user/unicore32/syscall_nr.h b/linux-user/unicore32/syscall_nr.h
index 9c72d84..486b8c4 100644
--- a/linux-user/unicore32/syscall_nr.h
+++ b/linux-user/unicore32/syscall_nr.h
@@ -187,8 +187,8 @@
 #define TARGET_NR_rt_sigtimedwait               177
 #define TARGET_NR_rt_sigqueueinfo               178
 #define TARGET_NR_rt_sigsuspend                 179
-#define TARGET_NR_pread                         180
-#define TARGET_NR_pwrite                        181
+#define TARGET_NR_pread64                       180
+#define TARGET_NR_pwrite64                      181
 #define TARGET_NR_chown                         182
 #define TARGET_NR_getcwd                        183
 #define TARGET_NR_capget                        184
commit f877d09e63bd94424dab049da75bc1cd601a7609
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Wed Dec 5 07:15:27 2012 +0400

    target-xtensa: use movcond where possible
    
    Use movcond for all sorts of conditional moves, ABS, CLAMPS, MIN/MAX
    opcodes.
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 52edcef..5d8762c 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -1403,12 +1403,14 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
 
                 case 1: /*ABS*/
                     {
-                        int label = gen_new_label();
-                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
-                        tcg_gen_brcondi_i32(
-                                TCG_COND_GE, cpu_R[RRR_R], 0, label);
-                        tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
-                        gen_set_label(label);
+                        TCGv_i32 zero = tcg_const_i32(0);
+                        TCGv_i32 neg = tcg_temp_new_i32();
+
+                        tcg_gen_neg_i32(neg, cpu_R[RRR_T]);
+                        tcg_gen_movcond_i32(TCG_COND_GE, cpu_R[RRR_R],
+                                cpu_R[RRR_T], zero, cpu_R[RRR_T], neg);
+                        tcg_temp_free(neg);
+                        tcg_temp_free(zero);
                     }
                     break;
 
@@ -1755,22 +1757,20 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
                 {
                     TCGv_i32 tmp1 = tcg_temp_new_i32();
                     TCGv_i32 tmp2 = tcg_temp_new_i32();
-                    int label = gen_new_label();
+                    TCGv_i32 zero = tcg_const_i32(0);
 
                     tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 24 - RRR_T);
                     tcg_gen_xor_i32(tmp2, tmp1, cpu_R[RRR_S]);
                     tcg_gen_andi_i32(tmp2, tmp2, 0xffffffff << (RRR_T + 7));
-                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
-                    tcg_gen_brcondi_i32(TCG_COND_EQ, tmp2, 0, label);
 
                     tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 31);
-                    tcg_gen_xori_i32(cpu_R[RRR_R], tmp1,
-                            0xffffffff >> (25 - RRR_T));
-
-                    gen_set_label(label);
+                    tcg_gen_xori_i32(tmp1, tmp1, 0xffffffff >> (25 - RRR_T));
 
+                    tcg_gen_movcond_i32(TCG_COND_EQ, cpu_R[RRR_R], tmp2, zero,
+                            cpu_R[RRR_S], tmp1);
                     tcg_temp_free(tmp1);
                     tcg_temp_free(tmp2);
+                    tcg_temp_free(zero);
                 }
                 break;
 
@@ -1787,19 +1787,9 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
                         TCG_COND_LEU,
                         TCG_COND_GEU
                     };
-                    int label = gen_new_label();
-
-                    if (RRR_R != RRR_T) {
-                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
-                        tcg_gen_brcond_i32(cond[OP2 - 4],
-                                cpu_R[RRR_S], cpu_R[RRR_T], label);
-                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
-                    } else {
-                        tcg_gen_brcond_i32(cond[OP2 - 4],
-                                cpu_R[RRR_T], cpu_R[RRR_S], label);
-                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
-                    }
-                    gen_set_label(label);
+                    tcg_gen_movcond_i32(cond[OP2 - 4], cpu_R[RRR_R],
+                            cpu_R[RRR_S], cpu_R[RRR_T],
+                            cpu_R[RRR_S], cpu_R[RRR_T]);
                 }
                 break;
 
@@ -1810,15 +1800,16 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
                 gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
                 {
                     static const TCGCond cond[] = {
-                        TCG_COND_NE,
                         TCG_COND_EQ,
+                        TCG_COND_NE,
+                        TCG_COND_LT,
                         TCG_COND_GE,
-                        TCG_COND_LT
                     };
-                    int label = gen_new_label();
-                    tcg_gen_brcondi_i32(cond[OP2 - 8], cpu_R[RRR_T], 0, label);
-                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
-                    gen_set_label(label);
+                    TCGv_i32 zero = tcg_const_i32(0);
+
+                    tcg_gen_movcond_i32(cond[OP2 - 8], cpu_R[RRR_R],
+                            cpu_R[RRR_T], zero, cpu_R[RRR_S], cpu_R[RRR_R]);
+                    tcg_temp_free(zero);
                 }
                 break;
 
@@ -1827,16 +1818,16 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
                 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
                 gen_window_check2(dc, RRR_R, RRR_S);
                 {
-                    int label = gen_new_label();
+                    TCGv_i32 zero = tcg_const_i32(0);
                     TCGv_i32 tmp = tcg_temp_new_i32();
 
                     tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRR_T);
-                    tcg_gen_brcondi_i32(
-                            OP2 & 1 ? TCG_COND_EQ : TCG_COND_NE,
-                            tmp, 0, label);
-                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
-                    gen_set_label(label);
+                    tcg_gen_movcond_i32(OP2 & 1 ? TCG_COND_NE : TCG_COND_EQ,
+                            cpu_R[RRR_R], tmp, zero,
+                            cpu_R[RRR_S], cpu_R[RRR_R]);
+
                     tcg_temp_free(tmp);
+                    tcg_temp_free(zero);
                 }
                 break;
 
@@ -2127,15 +2118,16 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
                 gen_check_cpenable(dc, 0);
                 {
                     static const TCGCond cond[] = {
-                        TCG_COND_NE,
                         TCG_COND_EQ,
+                        TCG_COND_NE,
+                        TCG_COND_LT,
                         TCG_COND_GE,
-                        TCG_COND_LT
                     };
-                    int label = gen_new_label();
-                    tcg_gen_brcondi_i32(cond[OP2 - 8], cpu_R[RRR_T], 0, label);
-                    tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_FR[RRR_S]);
-                    gen_set_label(label);
+                    TCGv_i32 zero = tcg_const_i32(0);
+
+                    tcg_gen_movcond_i32(cond[OP2 - 8], cpu_FR[RRR_R],
+                            cpu_R[RRR_T], zero, cpu_FR[RRR_S], cpu_FR[RRR_R]);
+                    tcg_temp_free(zero);
                 }
                 break;
 
@@ -2144,16 +2136,16 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
                 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
                 gen_check_cpenable(dc, 0);
                 {
-                    int label = gen_new_label();
+                    TCGv_i32 zero = tcg_const_i32(0);
                     TCGv_i32 tmp = tcg_temp_new_i32();
 
                     tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRR_T);
-                    tcg_gen_brcondi_i32(
-                            OP2 & 1 ? TCG_COND_EQ : TCG_COND_NE,
-                            tmp, 0, label);
-                    tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_FR[RRR_S]);
-                    gen_set_label(label);
+                    tcg_gen_movcond_i32(OP2 & 1 ? TCG_COND_NE : TCG_COND_EQ,
+                            cpu_FR[RRR_R], tmp, zero,
+                            cpu_FR[RRR_S], cpu_FR[RRR_R]);
+
                     tcg_temp_free(tmp);
+                    tcg_temp_free(zero);
                 }
                 break;
 
commit 5dacd229ebb46c236cb1dd0c65a4e4f2cfb55dfb
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Wed Dec 5 07:15:26 2012 +0400

    target-xtensa: add s32c1i unit tests
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tests/tcg/xtensa/Makefile b/tests/tcg/xtensa/Makefile
index 56cfe0f..002fd87 100644
--- a/tests/tcg/xtensa/Makefile
+++ b/tests/tcg/xtensa/Makefile
@@ -42,6 +42,7 @@ endif
 TESTCASES += test_quo.tst
 TESTCASES += test_rem.tst
 TESTCASES += test_rst0.tst
+TESTCASES += test_s32c1i.tst
 TESTCASES += test_sar.tst
 TESTCASES += test_sext.tst
 TESTCASES += test_shift.tst
diff --git a/tests/tcg/xtensa/test_s32c1i.S b/tests/tcg/xtensa/test_s32c1i.S
new file mode 100644
index 0000000..4536015
--- /dev/null
+++ b/tests/tcg/xtensa/test_s32c1i.S
@@ -0,0 +1,39 @@
+.include "macros.inc"
+
+test_suite s32c1i
+
+test s32c1i_nowrite
+    movi    a2, 1f
+    movi    a3, 1
+    wsr     a3, scompare1
+    movi    a1, 2
+    s32c1i  a1, a2, 0
+    assert  ne, a1, a3
+    l32i    a1, a2, 0
+    assert  eqi, a1, 3
+
+.data
+.align 4
+1:
+    .word   3
+.text
+test_end
+
+test s32c1i_write
+    movi    a2, 1f
+    movi    a3, 3
+    wsr     a3, scompare1
+    movi    a1, 2
+    s32c1i  a1, a2, 0
+    assert  eq, a1, a3
+    l32i    a1, a2, 0
+    assert  eqi, a1, 2
+
+.data
+.align 4
+1:
+    .word   3
+.text
+test_end
+
+test_suite_end
commit efdfac94f48f8589a0d60b650c7bed989a341eaa
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Wed Dec 5 07:15:25 2012 +0400

    target-xtensa: add SR accessibility unit tests
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tests/tcg/xtensa/Makefile b/tests/tcg/xtensa/Makefile
index 0ff0ccf..56cfe0f 100644
--- a/tests/tcg/xtensa/Makefile
+++ b/tests/tcg/xtensa/Makefile
@@ -45,6 +45,7 @@ TESTCASES += test_rst0.tst
 TESTCASES += test_sar.tst
 TESTCASES += test_sext.tst
 TESTCASES += test_shift.tst
+TESTCASES += test_sr.tst
 TESTCASES += test_timer.tst
 TESTCASES += test_windowed.tst
 
diff --git a/tests/tcg/xtensa/macros.inc b/tests/tcg/xtensa/macros.inc
index 23bf3e9..c9be1ce 100644
--- a/tests/tcg/xtensa/macros.inc
+++ b/tests/tcg/xtensa/macros.inc
@@ -1,7 +1,7 @@
 .macro test_suite name
 .data
 status: .word result
-result: .space 20
+result: .space 256
 .text
 .global main
 .align 4
diff --git a/tests/tcg/xtensa/test_sr.S b/tests/tcg/xtensa/test_sr.S
new file mode 100644
index 0000000..470c03d
--- /dev/null
+++ b/tests/tcg/xtensa/test_sr.S
@@ -0,0 +1,90 @@
+.include "macros.inc"
+
+test_suite sr
+
+.macro  sr_op sym, op_sym, op_byte, sr
+    .if \sym
+    \op_sym a4, \sr
+    .else
+    .byte 0x40, \sr, \op_byte
+    .endif
+.endm
+
+.macro 	test_sr_op sym, mask, op, op_byte, sr
+    movi    a4, 0
+    .if (\mask)
+    set_vector kernel, 0
+    sr_op   \sym, \op, \op_byte, \sr
+    .else
+    set_vector kernel, 2f
+1:
+    sr_op   \sym, \op, \op_byte, \sr
+    test_fail
+2:
+    reset_ps
+    rsr     a2, exccause
+    assert  eqi, a2, 0
+    rsr     a2, epc1
+    movi    a3, 1b
+    assert  eq, a2, a3
+    .endif
+.endm
+
+.macro  test_sr_mask sr, sym, mask
+test \sr
+    test_sr_op \sym, \mask & 1, rsr, 0x03, \sr
+    test_sr_op \sym, \mask & 2, wsr, 0x13, \sr
+    test_sr_op \sym, \mask & 4, xsr, 0x61, \sr
+test_end
+.endm
+
+.macro  test_sr sr, conf
+    test_sr_mask    \sr, \conf, 7
+.endm
+
+test_sr acchi, 1
+test_sr acclo, 1
+test_sr_mask /*atomctl*/99, 0, 0
+test_sr_mask /*br*/4, 0, 0
+test_sr_mask /*cacheattr*/98, 0, 0
+test_sr ccompare0, 1
+test_sr ccount, 1
+test_sr cpenable, 1
+test_sr dbreaka0, 1
+test_sr dbreakc0, 1
+test_sr_mask debugcause, 1, 1
+test_sr depc, 1
+test_sr dtlbcfg, 1
+test_sr epc1, 1
+test_sr epc2, 1
+test_sr eps2, 1
+test_sr exccause, 1
+test_sr excsave1, 1
+test_sr excsave2, 1
+test_sr excvaddr, 1
+test_sr ibreaka0, 1
+test_sr ibreakenable, 1
+test_sr icount, 1
+test_sr icountlevel, 1
+test_sr_mask /*intclear*/227, 0, 2
+test_sr_mask /*interrupt*/226, 0, 3
+test_sr intenable, 1
+test_sr itlbcfg, 1
+test_sr lbeg, 1
+test_sr lcount, 1
+test_sr lend, 1
+test_sr litbase, 1
+test_sr m0, 1
+test_sr misc0, 1
+test_sr_mask /*prefctl*/40, 0, 0
+test_sr_mask /*prid*/235, 0, 1
+test_sr ps, 1
+test_sr ptevaddr, 1
+test_sr rasid, 1
+test_sr sar, 1
+test_sr scompare1, 1
+test_sr vecbase, 1
+test_sr windowbase, 1
+test_sr windowstart, 1
+
+test_suite_end
commit b7909d81f7658f64bba0faed83e7c2fd6a52fcba
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Wed Dec 5 07:15:24 2012 +0400

    target-xtensa: implement MISC SR
    
    The Miscellaneous Special Registers Option provides zero to four scratch
    registers within the processor readable and writable by RSR, WSR, and
    XSR. These registers are privileged. They may be useful for some
    application-specific exception and interrupt processing tasks in the
    kernel. The MISC registers are undefined after reset.
    See ISA, 4.7.3 for details.
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index a73d32d..08fd5bc 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -153,6 +153,7 @@ enum {
     ICOUNTLEVEL = 237,
     EXCVADDR = 238,
     CCOMPARE = 240,
+    MISC = 244,
 };
 
 #define PS_INTLEVEL 0xf
diff --git a/target-xtensa/overlay_tool.h b/target-xtensa/overlay_tool.h
index 0b47029..dd4f51a 100644
--- a/target-xtensa/overlay_tool.h
+++ b/target-xtensa/overlay_tool.h
@@ -95,6 +95,7 @@
     /* Other, TODO */ \
     XCHAL_OPTION(XCHAL_HAVE_WINDOWED, XTENSA_OPTION_WINDOWED_REGISTER) | \
     XCHAL_OPTION(XCHAL_HAVE_DEBUG, XTENSA_OPTION_DEBUG) |\
+    XCHAL_OPTION(XCHAL_NUM_MISC_REGS > 0, XTENSA_OPTION_MISC_SR) | \
     XCHAL_OPTION(XCHAL_HAVE_THREADPTR, XTENSA_OPTION_THREAD_POINTER) | \
     XCHAL_OPTION(XCHAL_HAVE_PRID, XTENSA_OPTION_PROCESSOR_ID))
 
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 3303e5f..52edcef 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -179,6 +179,10 @@ static const XtensaReg sregnames[256] = {
             XTENSA_OPTION_TIMER_INTERRUPT),
     [CCOMPARE + 2] = XTENSA_REG("CCOMPARE2",
             XTENSA_OPTION_TIMER_INTERRUPT),
+    [MISC] = XTENSA_REG("MISC0", XTENSA_OPTION_MISC_SR),
+    [MISC + 1] = XTENSA_REG("MISC1", XTENSA_OPTION_MISC_SR),
+    [MISC + 2] = XTENSA_REG("MISC2", XTENSA_OPTION_MISC_SR),
+    [MISC + 3] = XTENSA_REG("MISC3", XTENSA_OPTION_MISC_SR),
 };
 
 static const XtensaReg uregnames[256] = {
commit 53593e90d13264dc88b3281ddf75ceaa641df05a
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Wed Dec 5 07:15:23 2012 +0400

    target-xtensa: better control rsr/wsr/xsr access to SRs
    
    There are read-only (DEBUGCAUSE, PRID) and write-only (INTCLEAR) SRs,
    and INTERRUPT/INTSET SR allows rsr/wsr, but not xsr. Raise illeagal
    opcode exception on illegal access to these SRs.
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 74b7b0f..3303e5f 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -81,16 +81,27 @@ static TCGv_i32 cpu_UR[256];
 typedef struct XtensaReg {
     const char *name;
     uint64_t opt_bits;
+    enum {
+        SR_R = 1,
+        SR_W = 2,
+        SR_X = 4,
+        SR_RW = 3,
+        SR_RWX = 7,
+    } access;
 } XtensaReg;
 
-#define XTENSA_REG(regname, opt) { \
+#define XTENSA_REG_ACCESS(regname, opt, acc) { \
         .name = (regname), \
         .opt_bits = XTENSA_OPTION_BIT(opt), \
+        .access = (acc), \
     }
 
+#define XTENSA_REG(regname, opt) XTENSA_REG_ACCESS(regname, opt, SR_RWX)
+
 #define XTENSA_REG_BITS(regname, opt) { \
         .name = (regname), \
         .opt_bits = (opt), \
+        .access = SR_RWX, \
     }
 
 static const XtensaReg sregnames[256] = {
@@ -151,15 +162,15 @@ static const XtensaReg sregnames[256] = {
     [EXCSAVE1 + 6] = XTENSA_REG("EXCSAVE7",
             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
     [CPENABLE] = XTENSA_REG("CPENABLE", XTENSA_OPTION_COPROCESSOR),
-    [INTSET] = XTENSA_REG("INTSET", XTENSA_OPTION_INTERRUPT),
-    [INTCLEAR] = XTENSA_REG("INTCLEAR", XTENSA_OPTION_INTERRUPT),
+    [INTSET] = XTENSA_REG_ACCESS("INTSET", XTENSA_OPTION_INTERRUPT, SR_RW),
+    [INTCLEAR] = XTENSA_REG_ACCESS("INTCLEAR", XTENSA_OPTION_INTERRUPT, SR_W),
     [INTENABLE] = XTENSA_REG("INTENABLE", XTENSA_OPTION_INTERRUPT),
     [PS] = XTENSA_REG_BITS("PS", XTENSA_OPTION_ALL),
     [VECBASE] = XTENSA_REG("VECBASE", XTENSA_OPTION_RELOCATABLE_VECTOR),
     [EXCCAUSE] = XTENSA_REG("EXCCAUSE", XTENSA_OPTION_EXCEPTION),
-    [DEBUGCAUSE] = XTENSA_REG("DEBUGCAUSE", XTENSA_OPTION_DEBUG),
+    [DEBUGCAUSE] = XTENSA_REG_ACCESS("DEBUGCAUSE", XTENSA_OPTION_DEBUG, SR_R),
     [CCOUNT] = XTENSA_REG("CCOUNT", XTENSA_OPTION_TIMER_INTERRUPT),
-    [PRID] = XTENSA_REG("PRID", XTENSA_OPTION_PROCESSOR_ID),
+    [PRID] = XTENSA_REG_ACCESS("PRID", XTENSA_OPTION_PROCESSOR_ID, SR_R),
     [ICOUNT] = XTENSA_REG("ICOUNT", XTENSA_OPTION_DEBUG),
     [ICOUNTLEVEL] = XTENSA_REG("ICOUNTLEVEL", XTENSA_OPTION_DEBUG),
     [EXCVADDR] = XTENSA_REG("EXCVADDR", XTENSA_OPTION_EXCEPTION),
@@ -476,7 +487,7 @@ static void gen_brcondi(DisasContext *dc, TCGCond cond,
     tcg_temp_free(tmp);
 }
 
-static void gen_check_sr(DisasContext *dc, uint32_t sr)
+static void gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
 {
     if (!xtensa_option_bits_enabled(dc->config, sregnames[sr].opt_bits)) {
         if (sregnames[sr].name) {
@@ -485,6 +496,16 @@ static void gen_check_sr(DisasContext *dc, uint32_t sr)
             qemu_log("SR %d is not implemented\n", sr);
         }
         gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
+    } else if (!(sregnames[sr].access & access)) {
+        static const char * const access_text[] = {
+            [SR_R] = "rsr",
+            [SR_W] = "wsr",
+            [SR_X] = "xsr",
+        };
+        assert(access < ARRAY_SIZE(access_text) && access_text[access]);
+        qemu_log("SR %s is not available for %s\n", sregnames[sr].name,
+                access_text[access]);
+        gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
     }
 }
 
@@ -679,14 +700,6 @@ static void gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v)
     gen_jumpi_check_loop_end(dc, -1);
 }
 
-static void gen_wsr_debugcause(DisasContext *dc, uint32_t sr, TCGv_i32 v)
-{
-}
-
-static void gen_wsr_prid(DisasContext *dc, uint32_t sr, TCGv_i32 v)
-{
-}
-
 static void gen_wsr_icount(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 {
     if (dc->icount) {
@@ -744,8 +757,6 @@ static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
         [INTCLEAR] = gen_wsr_intclear,
         [INTENABLE] = gen_wsr_intenable,
         [PS] = gen_wsr_ps,
-        [DEBUGCAUSE] = gen_wsr_debugcause,
-        [PRID] = gen_wsr_prid,
         [ICOUNT] = gen_wsr_icount,
         [ICOUNTLEVEL] = gen_wsr_icountlevel,
         [CCOMPARE] = gen_wsr_ccompare,
@@ -1467,7 +1478,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
             case 6: /*XSR*/
                 {
                     TCGv_i32 tmp = tcg_temp_new_i32();
-                    gen_check_sr(dc, RSR_SR);
+                    gen_check_sr(dc, RSR_SR, SR_X);
                     if (RSR_SR >= 64) {
                         gen_check_privilege(dc);
                     }
@@ -1698,7 +1709,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
         case 3: /*RST3*/
             switch (OP2) {
             case 0: /*RSR*/
-                gen_check_sr(dc, RSR_SR);
+                gen_check_sr(dc, RSR_SR, SR_R);
                 if (RSR_SR >= 64) {
                     gen_check_privilege(dc);
                 }
@@ -1707,7 +1718,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
                 break;
 
             case 1: /*WSR*/
-                gen_check_sr(dc, RSR_SR);
+                gen_check_sr(dc, RSR_SR, SR_W);
                 if (RSR_SR >= 64) {
                     gen_check_privilege(dc);
                 }
commit fe0bd475aa31e60674f7f53b85dc293108026202
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Wed Dec 5 07:15:22 2012 +0400

    target-xtensa: restrict available SRs by enabled options
    
    Beginning with the RA-2004.1 release, SR access instructions (rsr, wsr,
    xsr) are associated with their corresponding SR and raise illegal opcode
    exception in case the register is not configured for the core.
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index 068ad69..a73d32d 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -416,6 +416,7 @@ void debug_exception_env(CPUXtensaState *new_env, uint32_t cause);
 
 
 #define XTENSA_OPTION_BIT(opt) (((uint64_t)1) << (opt))
+#define XTENSA_OPTION_ALL (~(uint64_t)0)
 
 static inline bool xtensa_option_bits_enabled(const XtensaConfig *config,
         uint64_t opt)
diff --git a/target-xtensa/overlay_tool.h b/target-xtensa/overlay_tool.h
index 45205b8..0b47029 100644
--- a/target-xtensa/overlay_tool.h
+++ b/target-xtensa/overlay_tool.h
@@ -94,7 +94,9 @@
     XCHAL_OPTION(XCHAL_HAVE_CACHEATTR, XTENSA_OPTION_CACHEATTR) | \
     /* Other, TODO */ \
     XCHAL_OPTION(XCHAL_HAVE_WINDOWED, XTENSA_OPTION_WINDOWED_REGISTER) | \
-    XCHAL_OPTION(XCHAL_HAVE_DEBUG, XTENSA_OPTION_DEBUG))
+    XCHAL_OPTION(XCHAL_HAVE_DEBUG, XTENSA_OPTION_DEBUG) |\
+    XCHAL_OPTION(XCHAL_HAVE_THREADPTR, XTENSA_OPTION_THREAD_POINTER) | \
+    XCHAL_OPTION(XCHAL_HAVE_PRID, XTENSA_OPTION_PROCESSOR_ID))
 
 #ifndef XCHAL_WINDOW_OF4_VECOFS
 #define XCHAL_WINDOW_OF4_VECOFS         0x00000000
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index eb48120..74b7b0f 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -78,78 +78,102 @@ static TCGv_i32 cpu_UR[256];
 
 #include "gen-icount.h"
 
-static const char * const sregnames[256] = {
-    [LBEG] = "LBEG",
-    [LEND] = "LEND",
-    [LCOUNT] = "LCOUNT",
-    [SAR] = "SAR",
-    [BR] = "BR",
-    [LITBASE] = "LITBASE",
-    [SCOMPARE1] = "SCOMPARE1",
-    [ACCLO] = "ACCLO",
-    [ACCHI] = "ACCHI",
-    [MR] = "MR0",
-    [MR + 1] = "MR1",
-    [MR + 2] = "MR2",
-    [MR + 3] = "MR3",
-    [WINDOW_BASE] = "WINDOW_BASE",
-    [WINDOW_START] = "WINDOW_START",
-    [PTEVADDR] = "PTEVADDR",
-    [RASID] = "RASID",
-    [ITLBCFG] = "ITLBCFG",
-    [DTLBCFG] = "DTLBCFG",
-    [IBREAKENABLE] = "IBREAKENABLE",
-    [CACHEATTR] = "CACHEATTR",
-    [ATOMCTL] = "ATOMCTL",
-    [IBREAKA] = "IBREAKA0",
-    [IBREAKA + 1] = "IBREAKA1",
-    [DBREAKA] = "DBREAKA0",
-    [DBREAKA + 1] = "DBREAKA1",
-    [DBREAKC] = "DBREAKC0",
-    [DBREAKC + 1] = "DBREAKC1",
-    [EPC1] = "EPC1",
-    [EPC1 + 1] = "EPC2",
-    [EPC1 + 2] = "EPC3",
-    [EPC1 + 3] = "EPC4",
-    [EPC1 + 4] = "EPC5",
-    [EPC1 + 5] = "EPC6",
-    [EPC1 + 6] = "EPC7",
-    [DEPC] = "DEPC",
-    [EPS2] = "EPS2",
-    [EPS2 + 1] = "EPS3",
-    [EPS2 + 2] = "EPS4",
-    [EPS2 + 3] = "EPS5",
-    [EPS2 + 4] = "EPS6",
-    [EPS2 + 5] = "EPS7",
-    [EXCSAVE1] = "EXCSAVE1",
-    [EXCSAVE1 + 1] = "EXCSAVE2",
-    [EXCSAVE1 + 2] = "EXCSAVE3",
-    [EXCSAVE1 + 3] = "EXCSAVE4",
-    [EXCSAVE1 + 4] = "EXCSAVE5",
-    [EXCSAVE1 + 5] = "EXCSAVE6",
-    [EXCSAVE1 + 6] = "EXCSAVE7",
-    [CPENABLE] = "CPENABLE",
-    [INTSET] = "INTSET",
-    [INTCLEAR] = "INTCLEAR",
-    [INTENABLE] = "INTENABLE",
-    [PS] = "PS",
-    [VECBASE] = "VECBASE",
-    [EXCCAUSE] = "EXCCAUSE",
-    [DEBUGCAUSE] = "DEBUGCAUSE",
-    [CCOUNT] = "CCOUNT",
-    [PRID] = "PRID",
-    [ICOUNT] = "ICOUNT",
-    [ICOUNTLEVEL] = "ICOUNTLEVEL",
-    [EXCVADDR] = "EXCVADDR",
-    [CCOMPARE] = "CCOMPARE0",
-    [CCOMPARE + 1] = "CCOMPARE1",
-    [CCOMPARE + 2] = "CCOMPARE2",
+typedef struct XtensaReg {
+    const char *name;
+    uint64_t opt_bits;
+} XtensaReg;
+
+#define XTENSA_REG(regname, opt) { \
+        .name = (regname), \
+        .opt_bits = XTENSA_OPTION_BIT(opt), \
+    }
+
+#define XTENSA_REG_BITS(regname, opt) { \
+        .name = (regname), \
+        .opt_bits = (opt), \
+    }
+
+static const XtensaReg sregnames[256] = {
+    [LBEG] = XTENSA_REG("LBEG", XTENSA_OPTION_LOOP),
+    [LEND] = XTENSA_REG("LEND", XTENSA_OPTION_LOOP),
+    [LCOUNT] = XTENSA_REG("LCOUNT", XTENSA_OPTION_LOOP),
+    [SAR] = XTENSA_REG_BITS("SAR", XTENSA_OPTION_ALL),
+    [BR] = XTENSA_REG("BR", XTENSA_OPTION_BOOLEAN),
+    [LITBASE] = XTENSA_REG("LITBASE", XTENSA_OPTION_EXTENDED_L32R),
+    [SCOMPARE1] = XTENSA_REG("SCOMPARE1", XTENSA_OPTION_CONDITIONAL_STORE),
+    [ACCLO] = XTENSA_REG("ACCLO", XTENSA_OPTION_MAC16),
+    [ACCHI] = XTENSA_REG("ACCHI", XTENSA_OPTION_MAC16),
+    [MR] = XTENSA_REG("MR0", XTENSA_OPTION_MAC16),
+    [MR + 1] = XTENSA_REG("MR1", XTENSA_OPTION_MAC16),
+    [MR + 2] = XTENSA_REG("MR2", XTENSA_OPTION_MAC16),
+    [MR + 3] = XTENSA_REG("MR3", XTENSA_OPTION_MAC16),
+    [WINDOW_BASE] = XTENSA_REG("WINDOW_BASE", XTENSA_OPTION_WINDOWED_REGISTER),
+    [WINDOW_START] = XTENSA_REG("WINDOW_START",
+            XTENSA_OPTION_WINDOWED_REGISTER),
+    [PTEVADDR] = XTENSA_REG("PTEVADDR", XTENSA_OPTION_MMU),
+    [RASID] = XTENSA_REG("RASID", XTENSA_OPTION_MMU),
+    [ITLBCFG] = XTENSA_REG("ITLBCFG", XTENSA_OPTION_MMU),
+    [DTLBCFG] = XTENSA_REG("DTLBCFG", XTENSA_OPTION_MMU),
+    [IBREAKENABLE] = XTENSA_REG("IBREAKENABLE", XTENSA_OPTION_DEBUG),
+    [CACHEATTR] = XTENSA_REG("CACHEATTR", XTENSA_OPTION_CACHEATTR),
+    [ATOMCTL] = XTENSA_REG("ATOMCTL", XTENSA_OPTION_ATOMCTL),
+    [IBREAKA] = XTENSA_REG("IBREAKA0", XTENSA_OPTION_DEBUG),
+    [IBREAKA + 1] = XTENSA_REG("IBREAKA1", XTENSA_OPTION_DEBUG),
+    [DBREAKA] = XTENSA_REG("DBREAKA0", XTENSA_OPTION_DEBUG),
+    [DBREAKA + 1] = XTENSA_REG("DBREAKA1", XTENSA_OPTION_DEBUG),
+    [DBREAKC] = XTENSA_REG("DBREAKC0", XTENSA_OPTION_DEBUG),
+    [DBREAKC + 1] = XTENSA_REG("DBREAKC1", XTENSA_OPTION_DEBUG),
+    [EPC1] = XTENSA_REG("EPC1", XTENSA_OPTION_EXCEPTION),
+    [EPC1 + 1] = XTENSA_REG("EPC2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [EPC1 + 2] = XTENSA_REG("EPC3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [EPC1 + 3] = XTENSA_REG("EPC4", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [EPC1 + 4] = XTENSA_REG("EPC5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [EPC1 + 5] = XTENSA_REG("EPC6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [EPC1 + 6] = XTENSA_REG("EPC7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [DEPC] = XTENSA_REG("DEPC", XTENSA_OPTION_EXCEPTION),
+    [EPS2] = XTENSA_REG("EPS2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [EPS2 + 1] = XTENSA_REG("EPS3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [EPS2 + 2] = XTENSA_REG("EPS4", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [EPS2 + 3] = XTENSA_REG("EPS5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [EPS2 + 4] = XTENSA_REG("EPS6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [EPS2 + 5] = XTENSA_REG("EPS7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [EXCSAVE1] = XTENSA_REG("EXCSAVE1", XTENSA_OPTION_EXCEPTION),
+    [EXCSAVE1 + 1] = XTENSA_REG("EXCSAVE2",
+            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [EXCSAVE1 + 2] = XTENSA_REG("EXCSAVE3",
+            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [EXCSAVE1 + 3] = XTENSA_REG("EXCSAVE4",
+            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [EXCSAVE1 + 4] = XTENSA_REG("EXCSAVE5",
+            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [EXCSAVE1 + 5] = XTENSA_REG("EXCSAVE6",
+            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [EXCSAVE1 + 6] = XTENSA_REG("EXCSAVE7",
+            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
+    [CPENABLE] = XTENSA_REG("CPENABLE", XTENSA_OPTION_COPROCESSOR),
+    [INTSET] = XTENSA_REG("INTSET", XTENSA_OPTION_INTERRUPT),
+    [INTCLEAR] = XTENSA_REG("INTCLEAR", XTENSA_OPTION_INTERRUPT),
+    [INTENABLE] = XTENSA_REG("INTENABLE", XTENSA_OPTION_INTERRUPT),
+    [PS] = XTENSA_REG_BITS("PS", XTENSA_OPTION_ALL),
+    [VECBASE] = XTENSA_REG("VECBASE", XTENSA_OPTION_RELOCATABLE_VECTOR),
+    [EXCCAUSE] = XTENSA_REG("EXCCAUSE", XTENSA_OPTION_EXCEPTION),
+    [DEBUGCAUSE] = XTENSA_REG("DEBUGCAUSE", XTENSA_OPTION_DEBUG),
+    [CCOUNT] = XTENSA_REG("CCOUNT", XTENSA_OPTION_TIMER_INTERRUPT),
+    [PRID] = XTENSA_REG("PRID", XTENSA_OPTION_PROCESSOR_ID),
+    [ICOUNT] = XTENSA_REG("ICOUNT", XTENSA_OPTION_DEBUG),
+    [ICOUNTLEVEL] = XTENSA_REG("ICOUNTLEVEL", XTENSA_OPTION_DEBUG),
+    [EXCVADDR] = XTENSA_REG("EXCVADDR", XTENSA_OPTION_EXCEPTION),
+    [CCOMPARE] = XTENSA_REG("CCOMPARE0", XTENSA_OPTION_TIMER_INTERRUPT),
+    [CCOMPARE + 1] = XTENSA_REG("CCOMPARE1",
+            XTENSA_OPTION_TIMER_INTERRUPT),
+    [CCOMPARE + 2] = XTENSA_REG("CCOMPARE2",
+            XTENSA_OPTION_TIMER_INTERRUPT),
 };
 
-static const char * const uregnames[256] = {
-    [THREADPTR] = "THREADPTR",
-    [FCR] = "FCR",
-    [FSR] = "FSR",
+static const XtensaReg uregnames[256] = {
+    [THREADPTR] = XTENSA_REG("THREADPTR", XTENSA_OPTION_THREAD_POINTER),
+    [FCR] = XTENSA_REG("FCR", XTENSA_OPTION_FP_COPROCESSOR),
+    [FSR] = XTENSA_REG("FSR", XTENSA_OPTION_FP_COPROCESSOR),
 };
 
 void xtensa_translate_init(void)
@@ -185,18 +209,18 @@ void xtensa_translate_init(void)
     }
 
     for (i = 0; i < 256; ++i) {
-        if (sregnames[i]) {
+        if (sregnames[i].name) {
             cpu_SR[i] = tcg_global_mem_new_i32(TCG_AREG0,
                     offsetof(CPUXtensaState, sregs[i]),
-                    sregnames[i]);
+                    sregnames[i].name);
         }
     }
 
     for (i = 0; i < 256; ++i) {
-        if (uregnames[i]) {
+        if (uregnames[i].name) {
             cpu_UR[i] = tcg_global_mem_new_i32(TCG_AREG0,
                     offsetof(CPUXtensaState, uregs[i]),
-                    uregnames[i]);
+                    uregnames[i].name);
         }
     }
 #define GEN_HELPER 2
@@ -452,6 +476,18 @@ static void gen_brcondi(DisasContext *dc, TCGCond cond,
     tcg_temp_free(tmp);
 }
 
+static void gen_check_sr(DisasContext *dc, uint32_t sr)
+{
+    if (!xtensa_option_bits_enabled(dc->config, sregnames[sr].opt_bits)) {
+        if (sregnames[sr].name) {
+            qemu_log("SR %s is not configured\n", sregnames[sr].name);
+        } else {
+            qemu_log("SR %d is not implemented\n", sr);
+        }
+        gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
+    }
+}
+
 static void gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr)
 {
     gen_advance_ccount(dc);
@@ -473,14 +509,10 @@ static void gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
         [PTEVADDR] = gen_rsr_ptevaddr,
     };
 
-    if (sregnames[sr]) {
-        if (rsr_handler[sr]) {
-            rsr_handler[sr](dc, d, sr);
-        } else {
-            tcg_gen_mov_i32(d, cpu_SR[sr]);
-        }
+    if (rsr_handler[sr]) {
+        rsr_handler[sr](dc, d, sr);
     } else {
-        qemu_log("RSR %d not implemented, ", sr);
+        tcg_gen_mov_i32(d, cpu_SR[sr]);
     }
 }
 
@@ -721,14 +753,10 @@ static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
         [CCOMPARE + 2] = gen_wsr_ccompare,
     };
 
-    if (sregnames[sr]) {
-        if (wsr_handler[sr]) {
-            wsr_handler[sr](dc, sr, s);
-        } else {
-            tcg_gen_mov_i32(cpu_SR[sr], s);
-        }
+    if (wsr_handler[sr]) {
+        wsr_handler[sr](dc, sr, s);
     } else {
-        qemu_log("WSR %d not implemented, ", sr);
+        tcg_gen_mov_i32(cpu_SR[sr], s);
     }
 }
 
@@ -1439,6 +1467,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
             case 6: /*XSR*/
                 {
                     TCGv_i32 tmp = tcg_temp_new_i32();
+                    gen_check_sr(dc, RSR_SR);
                     if (RSR_SR >= 64) {
                         gen_check_privilege(dc);
                     }
@@ -1447,9 +1476,6 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
                     gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
                     gen_wsr(dc, RSR_SR, tmp);
                     tcg_temp_free(tmp);
-                    if (!sregnames[RSR_SR]) {
-                        TBD();
-                    }
                 }
                 break;
 
@@ -1672,25 +1698,21 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
         case 3: /*RST3*/
             switch (OP2) {
             case 0: /*RSR*/
+                gen_check_sr(dc, RSR_SR);
                 if (RSR_SR >= 64) {
                     gen_check_privilege(dc);
                 }
                 gen_window_check1(dc, RRR_T);
                 gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
-                if (!sregnames[RSR_SR]) {
-                    TBD();
-                }
                 break;
 
             case 1: /*WSR*/
+                gen_check_sr(dc, RSR_SR);
                 if (RSR_SR >= 64) {
                     gen_check_privilege(dc);
                 }
                 gen_window_check1(dc, RRR_T);
                 gen_wsr(dc, RSR_SR, cpu_R[RRR_T]);
-                if (!sregnames[RSR_SR]) {
-                    TBD();
-                }
                 break;
 
             case 2: /*SEXTu*/
@@ -1807,7 +1829,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
                 gen_window_check1(dc, RRR_R);
                 {
                     int st = (RRR_S << 4) + RRR_T;
-                    if (uregnames[st]) {
+                    if (uregnames[st].name) {
                         tcg_gen_mov_i32(cpu_R[RRR_R], cpu_UR[st]);
                     } else {
                         qemu_log("RUR %d not implemented, ", st);
@@ -1818,7 +1840,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
 
             case 15: /*WUR*/
                 gen_window_check1(dc, RRR_T);
-                if (uregnames[RSR_SR]) {
+                if (uregnames[RSR_SR].name) {
                     gen_wur(RSR_SR, cpu_R[RRR_T]);
                 } else {
                     qemu_log("WUR %d not implemented, ", RSR_SR);
@@ -3000,8 +3022,8 @@ void cpu_dump_state(CPUXtensaState *env, FILE *f, fprintf_function cpu_fprintf,
     cpu_fprintf(f, "PC=%08x\n\n", env->pc);
 
     for (i = j = 0; i < 256; ++i) {
-        if (sregnames[i]) {
-            cpu_fprintf(f, "%s=%08x%c", sregnames[i], env->sregs[i],
+        if (xtensa_option_bits_enabled(env->config, sregnames[i].opt_bits)) {
+            cpu_fprintf(f, "%12s=%08x%c", sregnames[i].name, env->sregs[i],
                     (j++ % 4) == 3 ? '\n' : ' ');
         }
     }
@@ -3009,8 +3031,8 @@ void cpu_dump_state(CPUXtensaState *env, FILE *f, fprintf_function cpu_fprintf,
     cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
 
     for (i = j = 0; i < 256; ++i) {
-        if (uregnames[i]) {
-            cpu_fprintf(f, "%s=%08x%c", uregnames[i], env->uregs[i],
+        if (xtensa_option_bits_enabled(env->config, uregnames[i].opt_bits)) {
+            cpu_fprintf(f, "%s=%08x%c", uregnames[i].name, env->uregs[i],
                     (j++ % 4) == 3 ? '\n' : ' ');
         }
     }
@@ -3018,7 +3040,7 @@ void cpu_dump_state(CPUXtensaState *env, FILE *f, fprintf_function cpu_fprintf,
     cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
 
     for (i = 0; i < 16; ++i) {
-        cpu_fprintf(f, "A%02d=%08x%c", i, env->regs[i],
+        cpu_fprintf(f, " A%02d=%08x%c", i, env->regs[i],
                 (i % 4) == 3 ? '\n' : ' ');
     }
 
commit 4e41d2f5830a76d3fe92b3d3b18cc9f2ee927770
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Wed Dec 5 07:15:21 2012 +0400

    target-xtensa: implement CACHEATTR SR
    
    In XEA1, the Options for Memory Protection and Translation and the
    corresponding TLB management instructions are not available. Instead,
    functionality similar to the Region Protection Option is available
    through the cache attribute register. See ISA, A.2.14 for details.
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index c6aa45e..035b07c 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -48,6 +48,7 @@ static void xtensa_cpu_reset(CPUState *s)
             XTENSA_OPTION_INTERRUPT) ? 0x1f : 0x10;
     env->sregs[VECBASE] = env->config->vecbase;
     env->sregs[IBREAKENABLE] = 0;
+    env->sregs[CACHEATTR] = 0x22222222;
     env->sregs[ATOMCTL] = xtensa_option_enabled(env->config,
             XTENSA_OPTION_ATOMCTL) ? 0x28 : 0x15;
 
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index d240ab7..068ad69 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -94,6 +94,7 @@ enum {
     XTENSA_OPTION_REGION_PROTECTION,
     XTENSA_OPTION_REGION_TRANSLATION,
     XTENSA_OPTION_MMU,
+    XTENSA_OPTION_CACHEATTR,
 
     /* Other */
     XTENSA_OPTION_WINDOWED_REGISTER,
@@ -129,6 +130,7 @@ enum {
     ITLBCFG = 91,
     DTLBCFG = 92,
     IBREAKENABLE = 96,
+    CACHEATTR = 98,
     ATOMCTL = 99,
     IBREAKA = 128,
     DBREAKA = 144,
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index ecd0182..200fb43 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -438,6 +438,24 @@ static unsigned region_attr_to_access(uint32_t attr)
     return access[attr & 0xf];
 }
 
+/*!
+ * Convert cacheattr to PAGE_{READ,WRITE,EXEC} mask.
+ * See ISA, A.2.14 The Cache Attribute Register
+ */
+static unsigned cacheattr_attr_to_access(uint32_t attr)
+{
+    static const unsigned access[16] = {
+         [0] = PAGE_READ | PAGE_WRITE             | PAGE_CACHE_WT,
+         [1] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_WT,
+         [2] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_BYPASS,
+         [3] =                          PAGE_EXEC | PAGE_CACHE_WB,
+         [4] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_WB,
+        [14] = PAGE_READ | PAGE_WRITE             | PAGE_CACHE_ISOLATE,
+    };
+
+    return access[attr & 0xf];
+}
+
 static bool is_access_granted(unsigned access, int is_write)
 {
     switch (is_write) {
@@ -584,7 +602,8 @@ int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb,
     } else {
         *paddr = vaddr;
         *page_size = TARGET_PAGE_SIZE;
-        *access = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_BYPASS;
+        *access = cacheattr_attr_to_access(
+                env->sregs[CACHEATTR] >> ((vaddr & 0xe0000000) >> 27));
         return 0;
     }
 }
diff --git a/target-xtensa/overlay_tool.h b/target-xtensa/overlay_tool.h
index 50bf573..45205b8 100644
--- a/target-xtensa/overlay_tool.h
+++ b/target-xtensa/overlay_tool.h
@@ -91,6 +91,7 @@
     XCHAL_OPTION(XCHAL_HAVE_XLT_CACHEATTR, \
             XTENSA_OPTION_REGION_TRANSLATION) | \
     XCHAL_OPTION(XCHAL_HAVE_PTP_MMU, XTENSA_OPTION_MMU) | \
+    XCHAL_OPTION(XCHAL_HAVE_CACHEATTR, XTENSA_OPTION_CACHEATTR) | \
     /* Other, TODO */ \
     XCHAL_OPTION(XCHAL_HAVE_WINDOWED, XTENSA_OPTION_WINDOWED_REGISTER) | \
     XCHAL_OPTION(XCHAL_HAVE_DEBUG, XTENSA_OPTION_DEBUG))
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index dc08de5..eb48120 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -99,6 +99,7 @@ static const char * const sregnames[256] = {
     [ITLBCFG] = "ITLBCFG",
     [DTLBCFG] = "DTLBCFG",
     [IBREAKENABLE] = "IBREAKENABLE",
+    [CACHEATTR] = "CACHEATTR",
     [ATOMCTL] = "ATOMCTL",
     [IBREAKA] = "IBREAKA0",
     [IBREAKA + 1] = "IBREAKA1",
commit fcc803d119a4c01a9b0ee5bda35fda1eeabffa33
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Wed Dec 5 07:15:20 2012 +0400

    target-xtensa: implement ATOMCTL SR
    
    ATOMCTL SR controls s32c1i opcode behavior depending on targeted memory
    type. See ISA, 4.3.12.4 for details.
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index 9d01983..c6aa45e 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -48,6 +48,8 @@ static void xtensa_cpu_reset(CPUState *s)
             XTENSA_OPTION_INTERRUPT) ? 0x1f : 0x10;
     env->sregs[VECBASE] = env->config->vecbase;
     env->sregs[IBREAKENABLE] = 0;
+    env->sregs[ATOMCTL] = xtensa_option_enabled(env->config,
+            XTENSA_OPTION_ATOMCTL) ? 0x28 : 0x15;
 
     env->pending_irq_level = 0;
     reset_mmu(env);
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index 74e9888..d240ab7 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -65,6 +65,7 @@ enum {
     XTENSA_OPTION_FP_COPROCESSOR,
     XTENSA_OPTION_MP_SYNCHRO,
     XTENSA_OPTION_CONDITIONAL_STORE,
+    XTENSA_OPTION_ATOMCTL,
 
     /* Interrupts and exceptions */
     XTENSA_OPTION_EXCEPTION,
@@ -128,6 +129,7 @@ enum {
     ITLBCFG = 91,
     DTLBCFG = 92,
     IBREAKENABLE = 96,
+    ATOMCTL = 99,
     IBREAKA = 128,
     DBREAKA = 144,
     DBREAKC = 160,
@@ -193,6 +195,14 @@ enum {
 
 #define REGION_PAGE_MASK 0xe0000000
 
+#define PAGE_CACHE_MASK    0x700
+#define PAGE_CACHE_SHIFT   8
+#define PAGE_CACHE_INVALID 0x000
+#define PAGE_CACHE_BYPASS  0x100
+#define PAGE_CACHE_WT      0x200
+#define PAGE_CACHE_WB      0x400
+#define PAGE_CACHE_ISOLATE 0x600
+
 enum {
     /* Static vectors */
     EXC_RESET,
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index d94bae2..ecd0182 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -390,6 +390,7 @@ int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb,
 static unsigned mmu_attr_to_access(uint32_t attr)
 {
     unsigned access = 0;
+
     if (attr < 12) {
         access |= PAGE_READ;
         if (attr & 0x1) {
@@ -398,8 +399,22 @@ static unsigned mmu_attr_to_access(uint32_t attr)
         if (attr & 0x2) {
             access |= PAGE_WRITE;
         }
+
+        switch (attr & 0xc) {
+        case 0:
+            access |= PAGE_CACHE_BYPASS;
+            break;
+
+        case 4:
+            access |= PAGE_CACHE_WB;
+            break;
+
+        case 8:
+            access |= PAGE_CACHE_WT;
+            break;
+        }
     } else if (attr == 13) {
-        access |= PAGE_READ | PAGE_WRITE;
+        access |= PAGE_READ | PAGE_WRITE | PAGE_CACHE_ISOLATE;
     }
     return access;
 }
@@ -410,14 +425,17 @@ static unsigned mmu_attr_to_access(uint32_t attr)
  */
 static unsigned region_attr_to_access(uint32_t attr)
 {
-    unsigned access = 0;
-    if ((attr < 6 && attr != 3) || attr == 14) {
-        access |= PAGE_READ | PAGE_WRITE;
-    }
-    if (attr > 0 && attr < 6) {
-        access |= PAGE_EXEC;
-    }
-    return access;
+    static const unsigned access[16] = {
+         [0] = PAGE_READ | PAGE_WRITE             | PAGE_CACHE_WT,
+         [1] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_WT,
+         [2] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_BYPASS,
+         [3] =                          PAGE_EXEC | PAGE_CACHE_WB,
+         [4] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_WB,
+         [5] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_WB,
+        [14] = PAGE_READ | PAGE_WRITE             | PAGE_CACHE_ISOLATE,
+    };
+
+    return access[attr & 0xf];
 }
 
 static bool is_access_granted(unsigned access, int is_write)
@@ -566,7 +584,7 @@ int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb,
     } else {
         *paddr = vaddr;
         *page_size = TARGET_PAGE_SIZE;
-        *access = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+        *access = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_BYPASS;
         return 0;
     }
 }
@@ -599,24 +617,34 @@ static void dump_tlb(FILE *f, fprintf_function cpu_fprintf,
                 xtensa_tlb_get_entry(env, dtlb, wi, ei);
 
             if (entry->asid) {
+                static const char * const cache_text[8] = {
+                    [PAGE_CACHE_BYPASS >> PAGE_CACHE_SHIFT] = "Bypass",
+                    [PAGE_CACHE_WT >> PAGE_CACHE_SHIFT] = "WT",
+                    [PAGE_CACHE_WB >> PAGE_CACHE_SHIFT] = "WB",
+                    [PAGE_CACHE_ISOLATE >> PAGE_CACHE_SHIFT] = "Isolate",
+                };
                 unsigned access = attr_to_access(entry->attr);
+                unsigned cache_idx = (access & PAGE_CACHE_MASK) >>
+                    PAGE_CACHE_SHIFT;
 
                 if (print_header) {
                     print_header = false;
                     cpu_fprintf(f, "Way %u (%d %s)\n", wi, sz, sz_text);
                     cpu_fprintf(f,
-                            "\tVaddr       Paddr       ASID  Attr RWX\n"
-                            "\t----------  ----------  ----  ---- ---\n");
+                            "\tVaddr       Paddr       ASID  Attr RWX Cache\n"
+                            "\t----------  ----------  ----  ---- --- -------\n");
                 }
                 cpu_fprintf(f,
-                        "\t0x%08x  0x%08x  0x%02x  0x%02x %c%c%c\n",
+                        "\t0x%08x  0x%08x  0x%02x  0x%02x %c%c%c %-7s\n",
                         entry->vaddr,
                         entry->paddr,
                         entry->asid,
                         entry->attr,
                         (access & PAGE_READ) ? 'R' : '-',
                         (access & PAGE_WRITE) ? 'W' : '-',
-                        (access & PAGE_EXEC) ? 'X' : '-');
+                        (access & PAGE_EXEC) ? 'X' : '-',
+                        cache_text[cache_idx] ? cache_text[cache_idx] :
+                            "Invalid");
             }
         }
     }
diff --git a/target-xtensa/helper.h b/target-xtensa/helper.h
index 1163c09..5b4cd27 100644
--- a/target-xtensa/helper.h
+++ b/target-xtensa/helper.h
@@ -23,6 +23,7 @@ DEF_HELPER_3(waiti, void, env, i32, i32)
 DEF_HELPER_3(timer_irq, void, env, i32, i32)
 DEF_HELPER_2(advance_ccount, void, env, i32)
 DEF_HELPER_1(check_interrupts, void, env)
+DEF_HELPER_3(check_atomctl, void, env, i32, i32)
 
 DEF_HELPER_2(wsr_rasid, void, env, i32)
 DEF_HELPER_FLAGS_3(rtlb0, TCG_CALL_NO_RWG_SE, i32, env, i32, i32)
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index ae0c099..0e0f21d 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -415,6 +415,63 @@ void HELPER(check_interrupts)(CPUXtensaState *env)
     check_interrupts(env);
 }
 
+/*!
+ * Check vaddr accessibility/cache attributes and raise an exception if
+ * specified by the ATOMCTL SR.
+ *
+ * Note: local memory exclusion is not implemented
+ */
+void HELPER(check_atomctl)(CPUXtensaState *env, uint32_t pc, uint32_t vaddr)
+{
+    uint32_t paddr, page_size, access;
+    uint32_t atomctl = env->sregs[ATOMCTL];
+    int rc = xtensa_get_physical_addr(env, true, vaddr, 1,
+            xtensa_get_cring(env), &paddr, &page_size, &access);
+
+    /*
+     * s32c1i never causes LOAD_PROHIBITED_CAUSE exceptions,
+     * see opcode description in the ISA
+     */
+    if (rc == 0 &&
+            (access & (PAGE_READ | PAGE_WRITE)) != (PAGE_READ | PAGE_WRITE)) {
+        rc = STORE_PROHIBITED_CAUSE;
+    }
+
+    if (rc) {
+        HELPER(exception_cause_vaddr)(env, pc, rc, vaddr);
+    }
+
+    /*
+     * When data cache is not configured use ATOMCTL bypass field.
+     * See ISA, 4.3.12.4 The Atomic Operation Control Register (ATOMCTL)
+     * under the Conditional Store Option.
+     */
+    if (!xtensa_option_enabled(env->config, XTENSA_OPTION_DCACHE)) {
+        access = PAGE_CACHE_BYPASS;
+    }
+
+    switch (access & PAGE_CACHE_MASK) {
+    case PAGE_CACHE_WB:
+        atomctl >>= 2;
+    case PAGE_CACHE_WT:
+        atomctl >>= 2;
+    case PAGE_CACHE_BYPASS:
+        if ((atomctl & 0x3) == 0) {
+            HELPER(exception_cause_vaddr)(env, pc,
+                    LOAD_STORE_ERROR_CAUSE, vaddr);
+        }
+        break;
+
+    case PAGE_CACHE_ISOLATE:
+        HELPER(exception_cause_vaddr)(env, pc,
+                LOAD_STORE_ERROR_CAUSE, vaddr);
+        break;
+
+    default:
+        break;
+    }
+}
+
 void HELPER(wsr_rasid)(CPUXtensaState *env, uint32_t v)
 {
     v = (v & 0xffffff00) | 0x1;
diff --git a/target-xtensa/overlay_tool.h b/target-xtensa/overlay_tool.h
index e395053..50bf573 100644
--- a/target-xtensa/overlay_tool.h
+++ b/target-xtensa/overlay_tool.h
@@ -42,6 +42,10 @@
 #define XCHAL_VECBASE_RESET_VADDR 0
 #endif
 
+#ifndef XCHAL_HW_MIN_VERSION
+#define XCHAL_HW_MIN_VERSION 0
+#endif
+
 #define XCHAL_OPTION(xchal, qemu) ((xchal) ? XTENSA_OPTION_BIT(qemu) : 0)
 
 #define XTENSA_OPTIONS ( \
@@ -62,6 +66,8 @@
     XCHAL_OPTION(XCHAL_HAVE_FP, XTENSA_OPTION_FP_COPROCESSOR) | \
     XCHAL_OPTION(XCHAL_HAVE_RELEASE_SYNC, XTENSA_OPTION_MP_SYNCHRO) | \
     XCHAL_OPTION(XCHAL_HAVE_S32C1I, XTENSA_OPTION_CONDITIONAL_STORE) | \
+    XCHAL_OPTION(XCHAL_HAVE_S32C1I && XCHAL_HW_MIN_VERSION >= 230000, \
+        XTENSA_OPTION_ATOMCTL) | \
     /* Interrupts and exceptions */ \
     XCHAL_OPTION(XCHAL_HAVE_EXCEPTIONS, XTENSA_OPTION_EXCEPTION) | \
     XCHAL_OPTION(XCHAL_HAVE_VECBASE, XTENSA_OPTION_RELOCATABLE_VECTOR) | \
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 828b9ca..dc08de5 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -99,6 +99,7 @@ static const char * const sregnames[256] = {
     [ITLBCFG] = "ITLBCFG",
     [DTLBCFG] = "DTLBCFG",
     [IBREAKENABLE] = "IBREAKENABLE",
+    [ATOMCTL] = "ATOMCTL",
     [IBREAKA] = "IBREAKA0",
     [IBREAKA + 1] = "IBREAKA1",
     [DBREAKA] = "DBREAKA0",
@@ -556,6 +557,11 @@ static void gen_wsr_ibreakenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
     gen_jumpi_check_loop_end(dc, 0);
 }
 
+static void gen_wsr_atomctl(DisasContext *dc, uint32_t sr, TCGv_i32 v)
+{
+    tcg_gen_andi_i32(cpu_SR[sr], v, 0x3f);
+}
+
 static void gen_wsr_ibreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 {
     unsigned id = sr - IBREAKA;
@@ -693,6 +699,7 @@ static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
         [ITLBCFG] = gen_wsr_tlbcfg,
         [DTLBCFG] = gen_wsr_tlbcfg,
         [IBREAKENABLE] = gen_wsr_ibreakenable,
+        [ATOMCTL] = gen_wsr_atomctl,
         [IBREAKA] = gen_wsr_ibreaka,
         [IBREAKA + 1] = gen_wsr_ibreaka,
         [DBREAKA] = gen_wsr_dbreaka,
@@ -2317,10 +2324,15 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
                 int label = gen_new_label();
                 TCGv_i32 tmp = tcg_temp_local_new_i32();
                 TCGv_i32 addr = tcg_temp_local_new_i32();
+                TCGv_i32 tpc;
 
                 tcg_gen_mov_i32(tmp, cpu_R[RRI8_T]);
                 tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2);
                 gen_load_store_alignment(dc, 2, addr, true);
+
+                gen_advance_ccount(dc);
+                tpc = tcg_const_i32(dc->pc);
+                gen_helper_check_atomctl(cpu_env, tpc, addr);
                 tcg_gen_qemu_ld32u(cpu_R[RRI8_T], addr, dc->cring);
                 tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[RRI8_T],
                         cpu_SR[SCOMPARE1], label);
@@ -2328,6 +2340,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
                 tcg_gen_qemu_st32(tmp, addr, dc->cring);
 
                 gen_set_label(label);
+                tcg_temp_free(tpc);
                 tcg_temp_free(addr);
                 tcg_temp_free(tmp);
             }
commit 536b558f5896ebbd635b57fa393e82faaa32ad52
Merge: 511c68d... 19e6c50...
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Dec 8 17:50:57 2012 +0000

    Merge branch 'master' of git.qemu-project.org:/pub/git/qemu
    
    * 'master' of git.qemu-project.org:/pub/git/qemu:
      target-mips: Fix incorrect shift for SHILO and SHILOV
      target-mips: Fix incorrect code and test for INSV
      xilinx_uartlite: Accept input after rx FIFO pop
      xilinx_uartlite: suppress "cannot receive message"
      xilinx_axienet: Implement R_IS behaviour

commit 511c68d3af626cb0a39034cb77e7ac64d3a26c0c
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Tue Dec 4 16:32:58 2012 -0200

    finally kill cpudef config section support
    
    The external CPU models were removed on QEMU 1.2, and the support for
    the "cpudef" config sections was documented as deprecated, but the
    actual removal of the config section was pending.
    
    Now that QEMU 1.3 was released, we can finally kill the support for
    cpudef config sections, and support only the built-in CPU models from
    target-i386/cpu.c.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/qemu-config.c b/qemu-config.c
index 10d1ba4..aa78fb9 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -417,54 +417,6 @@ static QemuOptsList qemu_trace_opts = {
     },
 };
 
-static QemuOptsList qemu_cpudef_opts = {
-    .name = "cpudef",
-    .head = QTAILQ_HEAD_INITIALIZER(qemu_cpudef_opts.head),
-    .desc = {
-        {
-            .name = "name",
-            .type = QEMU_OPT_STRING,
-        },{
-            .name = "level",
-            .type = QEMU_OPT_NUMBER,
-        },{
-            .name = "vendor",
-            .type = QEMU_OPT_STRING,
-        },{
-            .name = "family",
-            .type = QEMU_OPT_NUMBER,
-        },{
-            .name = "model",
-            .type = QEMU_OPT_NUMBER,
-        },{
-            .name = "stepping",
-            .type = QEMU_OPT_NUMBER,
-        },{
-            .name = "feature_edx",      /* cpuid 0000_0001.edx */
-            .type = QEMU_OPT_STRING,
-        },{
-            .name = "feature_ecx",      /* cpuid 0000_0001.ecx */
-            .type = QEMU_OPT_STRING,
-        },{
-            .name = "extfeature_edx",   /* cpuid 8000_0001.edx */
-            .type = QEMU_OPT_STRING,
-        },{
-            .name = "extfeature_ecx",   /* cpuid 8000_0001.ecx */
-            .type = QEMU_OPT_STRING,
-        },{
-            .name = "xlevel",
-            .type = QEMU_OPT_NUMBER,
-        },{
-            .name = "model_id",
-            .type = QEMU_OPT_STRING,
-        },{
-            .name = "vendor_override",
-            .type = QEMU_OPT_NUMBER,
-        },
-        { /* end of list */ }
-    },
-};
-
 QemuOptsList qemu_spice_opts = {
     .name = "spice",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_spice_opts.head),
@@ -700,7 +652,6 @@ static QemuOptsList *vm_config_groups[32] = {
     &qemu_rtc_opts,
     &qemu_global_opts,
     &qemu_mon_opts,
-    &qemu_cpudef_opts,
     &qemu_trace_opts,
     &qemu_option_rom_opts,
     &qemu_machine_opts,
commit 4cdd2e665ec4bd10c20c26432ee9ffe4db7bcc1c
Merge: 4753631... 5822993...
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Dec 8 14:28:13 2012 +0000

    Merge branch 'memory-ioport' of git://github.com/afaerber/qemu-cpu
    
    * 'memory-ioport' of git://github.com/afaerber/qemu-cpu:
      hw/dma.c: Replace register_ioport_*
      hw/pc.c: Replace register_ioport_*
      serial: Replace register_ioport_*
      hw/cirrus_vga.c: Replace register_ioport_*
      hw/apm.c: Replace register_ioport_*
      isa: Add isa_address_space_io()

commit 475363176c80feedb8feb5e335ba64de68c7b055
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Wed Oct 31 09:30:47 2012 +0000

    HACKING: List areas where we may rely on impdef C behaviour
    
    Add a section to HACKING saying which version of the C spec
    we use and describing the bits of implementation defined C
    compiler behaviour which C code in QEMU is allowed to rely on.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/HACKING b/HACKING
index 89a6b3a..6654d33 100644
--- a/HACKING
+++ b/HACKING
@@ -123,3 +123,23 @@ gcc's printf attribute directive in the prototype.
 This makes it so gcc's -Wformat and -Wformat-security options can do
 their jobs and cross-check format strings with the number and types
 of arguments.
+
+6. C standard, implementation defined and undefined behaviors
+
+C code in QEMU should be written to the C99 language specification. A copy
+of the final version of the C99 standard with corrigenda TC1, TC2, and TC3
+included, formatted as a draft, can be downloaded from:
+ http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
+
+The C language specification defines regions of undefined behavior and
+implementation defined behavior (to give compiler authors enough leeway to
+produce better code).  In general, code in QEMU should follow the language
+specification and avoid both undefined and implementation defined
+constructs. ("It works fine on the gcc I tested it with" is not a valid
+argument...) However there are a few areas where we allow ourselves to
+assume certain behaviors because in practice all the platforms we care about
+behave in the same way and writing strictly conformant code would be
+painful. These are:
+ * you may assume that integers are 2s complement representation
+ * you may assume that right shift of a signed integer duplicates
+   the sign bit (ie it is an arithmetic shift, not a logical shift)
commit 288fa40736e6eb63132d01aa6dc21ee831b796ae
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Tue Nov 27 13:19:40 2012 +0100

    pixman: require 0.18.4 or newer
    
    When older versions are found the internal pixman version is prefered.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/configure b/configure
index 994f731..44034d6 100755
--- a/configure
+++ b/configure
@@ -2118,7 +2118,7 @@ fi
 # pixman support probe
 
 if test "$pixman" = ""; then
-  if $pkg_config pixman-1 > /dev/null 2>&1; then
+  if $pkg_config --atleast-version=0.18.4 pixman-1 > /dev/null 2>&1; then
     pixman="system"
   else
     pixman="internal"
@@ -2129,7 +2129,7 @@ if test "$pixman" = "system"; then
   pixman_libs=`$pkg_config --libs pixman-1 2>/dev/null`
 else
   if test ! -d ${source_path}/pixman/pixman; then
-    echo "ERROR: pixman not present. Your options:"
+    echo "ERROR: pixman not present (or older than 0.18.4). Your options:"
     echo "  (1) Prefered: Install the pixman devel package (any recent"
     echo "      distro should have packages as Xorg needs pixman too)."
     echo "  (2) Fetch the pixman submodule, using:"
commit 94788f54e9deeaa2c82891a7d216fdd6e0e58749
Author: Evgeny Voevodin <e.voevodin at samsung.com>
Date:   Wed Nov 21 11:43:07 2012 +0400

    TCG: Remove unused global gen_opc_ arrays.
    
    Signed-off-by: Evgeny Voevodin <e.voevodin at samsung.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/exec-all.h b/exec-all.h
index 21aacda..b18d4ca 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -70,10 +70,6 @@ typedef struct TranslationBlock TranslationBlock;
 
 #define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * MAX_OPC_PARAM)
 
-extern target_ulong gen_opc_pc[OPC_BUF_SIZE];
-extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
-extern uint16_t gen_opc_icount[OPC_BUF_SIZE];
-
 #include "qemu-log.h"
 
 void gen_intermediate_code(CPUArchState *env, struct TranslationBlock *tb);
diff --git a/translate-all.c b/translate-all.c
index 2f616bf..f22e3ee 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -33,10 +33,6 @@
 /* code generation context */
 TCGContext tcg_ctx;
 
-target_ulong gen_opc_pc[OPC_BUF_SIZE];
-uint16_t gen_opc_icount[OPC_BUF_SIZE];
-uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
-
 void cpu_gen_init(void)
 {
     tcg_context_init(&tcg_ctx); 
commit ab1103def476d985c08362df97ff9cb9c112adfc
Author: Evgeny Voevodin <e.voevodin at samsung.com>
Date:   Wed Nov 21 11:43:06 2012 +0400

    TCG: Use gen_opc_instr_start from context instead of global variable.
    
    Signed-off-by: Evgeny Voevodin <e.voevodin at samsung.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 8b73fbb..71fe1a1 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3410,10 +3410,10 @@ static inline void gen_intermediate_code_internal(CPUAlphaState *env,
             if (lj < j) {
                 lj++;
                 while (lj < j)
-                    gen_opc_instr_start[lj++] = 0;
+                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
             }
             tcg_ctx.gen_opc_pc[lj] = ctx.pc;
-            gen_opc_instr_start[lj] = 1;
+            tcg_ctx.gen_opc_instr_start[lj] = 1;
             tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
@@ -3468,7 +3468,7 @@ static inline void gen_intermediate_code_internal(CPUAlphaState *env,
         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
         lj++;
         while (lj <= j)
-            gen_opc_instr_start[lj++] = 0;
+            tcg_ctx.gen_opc_instr_start[lj++] = 0;
     } else {
         tb->size = ctx.pc - pc_start;
         tb->icount = num_insns;
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 4695d8b..3cf3604 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9838,11 +9838,11 @@ static inline void gen_intermediate_code_internal(CPUARMState *env,
             if (lj < j) {
                 lj++;
                 while (lj < j)
-                    gen_opc_instr_start[lj++] = 0;
+                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
             }
             tcg_ctx.gen_opc_pc[lj] = dc->pc;
             gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
-            gen_opc_instr_start[lj] = 1;
+            tcg_ctx.gen_opc_instr_start[lj] = 1;
             tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
 
@@ -9977,7 +9977,7 @@ done_generating:
         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
         lj++;
         while (lj <= j)
-            gen_opc_instr_start[lj++] = 0;
+            tcg_ctx.gen_opc_instr_start[lj++] = 0;
     } else {
         tb->size = dc->pc - pc_start;
         tb->icount = num_insns;
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 6ec8c3c..60bdc24 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3301,7 +3301,7 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb,
             if (lj < j) {
                 lj++;
                 while (lj < j) {
-                    gen_opc_instr_start[lj++] = 0;
+                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
                 }
             }
             if (dc->delayed_branch == 1) {
@@ -3309,7 +3309,7 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb,
             } else {
                 tcg_ctx.gen_opc_pc[lj] = dc->pc;
             }
-            gen_opc_instr_start[lj] = 1;
+            tcg_ctx.gen_opc_instr_start[lj] = 1;
             tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
 
@@ -3439,7 +3439,7 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb,
         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
         lj++;
         while (lj <= j) {
-            gen_opc_instr_start[lj++] = 0;
+            tcg_ctx.gen_opc_instr_start[lj++] = 0;
         }
     } else {
         tb->size = dc->pc - pc_start;
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 80fb695..f394ea6 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -7988,11 +7988,11 @@ static inline void gen_intermediate_code_internal(CPUX86State *env,
             if (lj < j) {
                 lj++;
                 while (lj < j)
-                    gen_opc_instr_start[lj++] = 0;
+                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
             }
             tcg_ctx.gen_opc_pc[lj] = pc_ptr;
             gen_opc_cc_op[lj] = dc->cc_op;
-            gen_opc_instr_start[lj] = 1;
+            tcg_ctx.gen_opc_instr_start[lj] = 1;
             tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
@@ -8037,7 +8037,7 @@ static inline void gen_intermediate_code_internal(CPUX86State *env,
         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
         lj++;
         while (lj <= j)
-            gen_opc_instr_start[lj++] = 0;
+            tcg_ctx.gen_opc_instr_start[lj++] = 0;
     }
 
 #ifdef DEBUG_DISAS
@@ -8080,7 +8080,7 @@ void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, int pc_pos)
         int i;
         qemu_log("RESTORE:\n");
         for(i = 0;i <= pc_pos; i++) {
-            if (gen_opc_instr_start[i]) {
+            if (tcg_ctx.gen_opc_instr_start[i]) {
                 qemu_log("0x%04x: " TARGET_FMT_lx "\n", i,
                         tcg_ctx.gen_opc_pc[i]);
             }
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 4e029e0..e131ad1 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1051,11 +1051,11 @@ static void gen_intermediate_code_internal(CPULM32State *env,
             if (lj < j) {
                 lj++;
                 while (lj < j) {
-                    gen_opc_instr_start[lj++] = 0;
+                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
                 }
             }
             tcg_ctx.gen_opc_pc[lj] = dc->pc;
-            gen_opc_instr_start[lj] = 1;
+            tcg_ctx.gen_opc_instr_start[lj] = 1;
             tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
 
@@ -1110,7 +1110,7 @@ static void gen_intermediate_code_internal(CPULM32State *env,
         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
         lj++;
         while (lj <= j) {
-            gen_opc_instr_start[lj++] = 0;
+            tcg_ctx.gen_opc_instr_start[lj++] = 0;
         }
     } else {
         tb->size = dc->pc - pc_start;
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 0762085..11defc6 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -3019,10 +3019,10 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
             if (lj < j) {
                 lj++;
                 while (lj < j)
-                    gen_opc_instr_start[lj++] = 0;
+                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
             }
             tcg_ctx.gen_opc_pc[lj] = dc->pc;
-            gen_opc_instr_start[lj] = 1;
+            tcg_ctx.gen_opc_instr_start[lj] = 1;
             tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
@@ -3078,7 +3078,7 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
         lj++;
         while (lj <= j)
-            gen_opc_instr_start[lj++] = 0;
+            tcg_ctx.gen_opc_instr_start[lj++] = 0;
     } else {
         tb->size = dc->pc - pc_start;
         tb->icount = num_insns;
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index d975756..6ceff02 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1788,10 +1788,10 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
             if (lj < j) {
                 lj++;
                 while (lj < j)
-                    gen_opc_instr_start[lj++] = 0;
+                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
             }
             tcg_ctx.gen_opc_pc[lj] = dc->pc;
-            gen_opc_instr_start[lj] = 1;
+            tcg_ctx.gen_opc_instr_start[lj] = 1;
                         tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
 
@@ -1902,7 +1902,7 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
         lj++;
         while (lj <= j)
-            gen_opc_instr_start[lj++] = 0;
+            tcg_ctx.gen_opc_instr_start[lj++] = 0;
     } else {
         tb->size = dc->pc - pc_start;
                 tb->icount = num_insns;
diff --git a/target-mips/translate.c b/target-mips/translate.c
index abecfb3..65e6725 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15579,12 +15579,12 @@ gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
             if (lj < j) {
                 lj++;
                 while (lj < j)
-                    gen_opc_instr_start[lj++] = 0;
+                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
             }
             tcg_ctx.gen_opc_pc[lj] = ctx.pc;
             gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
             gen_opc_btarget[lj] = ctx.btarget;
-            gen_opc_instr_start[lj] = 1;
+            tcg_ctx.gen_opc_instr_start[lj] = 1;
             tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
@@ -15662,7 +15662,7 @@ done_generating:
         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
         lj++;
         while (lj <= j)
-            gen_opc_instr_start[lj++] = 0;
+            tcg_ctx.gen_opc_instr_start[lj++] = 0;
     } else {
         tb->size = ctx.pc - pc_start;
         tb->icount = num_insns;
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 5b08314..9ac999a 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1707,11 +1707,11 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
             if (k < j) {
                 k++;
                 while (k < j) {
-                    gen_opc_instr_start[k++] = 0;
+                    tcg_ctx.gen_opc_instr_start[k++] = 0;
                 }
             }
             tcg_ctx.gen_opc_pc[k] = dc->pc;
-            gen_opc_instr_start[k] = 1;
+            tcg_ctx.gen_opc_instr_start[k] = 1;
             tcg_ctx.gen_opc_icount[k] = num_insns;
         }
 
@@ -1787,7 +1787,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
         k++;
         while (k <= j) {
-            gen_opc_instr_start[k++] = 0;
+            tcg_ctx.gen_opc_instr_start[k++] = 0;
         }
     } else {
         tb->size = dc->pc - pc_start;
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 7fdde5f..653c2fd 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9680,10 +9680,10 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
             if (lj < j) {
                 lj++;
                 while (lj < j)
-                    gen_opc_instr_start[lj++] = 0;
+                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
             }
             tcg_ctx.gen_opc_pc[lj] = ctx.nip;
-            gen_opc_instr_start[lj] = 1;
+            tcg_ctx.gen_opc_instr_start[lj] = 1;
             tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
         LOG_DISAS("----------------\n");
@@ -9781,7 +9781,7 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
         lj++;
         while (lj <= j)
-            gen_opc_instr_start[lj++] = 0;
+            tcg_ctx.gen_opc_instr_start[lj++] = 0;
     } else {
         tb->size = ctx.nip - pc_start;
         tb->icount = num_insns;
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index b2774ee..787e3c6 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -5160,12 +5160,12 @@ static inline void gen_intermediate_code_internal(CPUS390XState *env,
             if (lj < j) {
                 lj++;
                 while (lj < j) {
-                    gen_opc_instr_start[lj++] = 0;
+                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
                 }
             }
             tcg_ctx.gen_opc_pc[lj] = dc.pc;
             gen_opc_cc_op[lj] = dc.cc_op;
-            gen_opc_instr_start[lj] = 1;
+            tcg_ctx.gen_opc_instr_start[lj] = 1;
             tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
@@ -5212,7 +5212,7 @@ static inline void gen_intermediate_code_internal(CPUS390XState *env,
         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
         lj++;
         while (lj <= j) {
-            gen_opc_instr_start[lj++] = 0;
+            tcg_ctx.gen_opc_instr_start[lj++] = 0;
         }
     } else {
         tb->size = dc.pc - pc_start;
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index ca76be5..86493e1 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -2003,11 +2003,11 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
             if (ii < i) {
                 ii++;
                 while (ii < i)
-                    gen_opc_instr_start[ii++] = 0;
+                    tcg_ctx.gen_opc_instr_start[ii++] = 0;
             }
             tcg_ctx.gen_opc_pc[ii] = ctx.pc;
             gen_opc_hflags[ii] = ctx.flags;
-            gen_opc_instr_start[ii] = 1;
+            tcg_ctx.gen_opc_instr_start[ii] = 1;
             tcg_ctx.gen_opc_icount[ii] = num_insns;
         }
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
@@ -2061,7 +2061,7 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
         i = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
         ii++;
         while (ii <= i)
-            gen_opc_instr_start[ii++] = 0;
+            tcg_ctx.gen_opc_instr_start[ii++] = 0;
     } else {
         tb->size = ctx.pc - pc_start;
         tb->icount = num_insns;
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index cbb8997..5859f2e 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5283,10 +5283,10 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
             if (lj < j) {
                 lj++;
                 while (lj < j)
-                    gen_opc_instr_start[lj++] = 0;
+                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
                 tcg_ctx.gen_opc_pc[lj] = dc->pc;
                 gen_opc_npc[lj] = dc->npc;
-                gen_opc_instr_start[lj] = 1;
+                tcg_ctx.gen_opc_instr_start[lj] = 1;
                 tcg_ctx.gen_opc_icount[lj] = num_insns;
             }
         }
@@ -5339,7 +5339,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
         lj++;
         while (lj <= j)
-            gen_opc_instr_start[lj++] = 0;
+            tcg_ctx.gen_opc_instr_start[lj++] = 0;
 #if 0
         log_page_dump();
 #endif
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 0562615..3951758 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -2003,11 +2003,11 @@ static inline void gen_intermediate_code_internal(CPUUniCore32State *env,
             if (lj < j) {
                 lj++;
                 while (lj < j) {
-                    gen_opc_instr_start[lj++] = 0;
+                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
                 }
             }
             tcg_ctx.gen_opc_pc[lj] = dc->pc;
-            gen_opc_instr_start[lj] = 1;
+            tcg_ctx.gen_opc_instr_start[lj] = 1;
             tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
 
@@ -2117,7 +2117,7 @@ done_generating:
         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
         lj++;
         while (lj <= j) {
-            gen_opc_instr_start[lj++] = 0;
+            tcg_ctx.gen_opc_instr_start[lj++] = 0;
         }
     } else {
         tb->size = dc->pc - pc_start;
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index e93c2e6..828b9ca 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -2897,11 +2897,11 @@ static void gen_intermediate_code_internal(
             if (lj < j) {
                 lj++;
                 while (lj < j) {
-                    gen_opc_instr_start[lj++] = 0;
+                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
                 }
             }
             tcg_ctx.gen_opc_pc[lj] = dc.pc;
-            gen_opc_instr_start[lj] = 1;
+            tcg_ctx.gen_opc_instr_start[lj] = 1;
             tcg_ctx.gen_opc_icount[lj] = insn_count;
         }
 
diff --git a/translate-all.c b/translate-all.c
index 177e95a..2f616bf 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -146,8 +146,9 @@ int cpu_restore_state(TranslationBlock *tb,
     if (j < 0)
         return -1;
     /* now find start of instruction before */
-    while (gen_opc_instr_start[j] == 0)
+    while (s->gen_opc_instr_start[j] == 0) {
         j--;
+    }
     env->icount_decr.u16.low -= s->gen_opc_icount[j];
 
     restore_state_to_opc(env, tb, j);
commit c9c99c22d5f8e9cfa83260fbe236a57e7383d673
Author: Evgeny Voevodin <e.voevodin at samsung.com>
Date:   Wed Nov 21 11:43:05 2012 +0400

    TCG: Use gen_opc_icount from context instead of global variable.
    
    Signed-off-by: Evgeny Voevodin <e.voevodin at samsung.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index bcde367..8b73fbb 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3414,7 +3414,7 @@ static inline void gen_intermediate_code_internal(CPUAlphaState *env,
             }
             tcg_ctx.gen_opc_pc[lj] = ctx.pc;
             gen_opc_instr_start[lj] = 1;
-            gen_opc_icount[lj] = num_insns;
+            tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
             gen_io_start();
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 8ea8bba..4695d8b 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9843,7 +9843,7 @@ static inline void gen_intermediate_code_internal(CPUARMState *env,
             tcg_ctx.gen_opc_pc[lj] = dc->pc;
             gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
             gen_opc_instr_start[lj] = 1;
-            gen_opc_icount[lj] = num_insns;
+            tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
 
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 745cd7a..6ec8c3c 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3310,7 +3310,7 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb,
                 tcg_ctx.gen_opc_pc[lj] = dc->pc;
             }
             gen_opc_instr_start[lj] = 1;
-            gen_opc_icount[lj] = num_insns;
+            tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
 
         /* Pretty disas.  */
diff --git a/target-i386/translate.c b/target-i386/translate.c
index aea843c..80fb695 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -7993,7 +7993,7 @@ static inline void gen_intermediate_code_internal(CPUX86State *env,
             tcg_ctx.gen_opc_pc[lj] = pc_ptr;
             gen_opc_cc_op[lj] = dc->cc_op;
             gen_opc_instr_start[lj] = 1;
-            gen_opc_icount[lj] = num_insns;
+            tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
             gen_io_start();
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index fcafb06..4e029e0 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1056,7 +1056,7 @@ static void gen_intermediate_code_internal(CPULM32State *env,
             }
             tcg_ctx.gen_opc_pc[lj] = dc->pc;
             gen_opc_instr_start[lj] = 1;
-            gen_opc_icount[lj] = num_insns;
+            tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
 
         /* Pretty disas.  */
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 74772dd..0762085 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -3023,7 +3023,7 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
             }
             tcg_ctx.gen_opc_pc[lj] = dc->pc;
             gen_opc_instr_start[lj] = 1;
-            gen_opc_icount[lj] = num_insns;
+            tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
             gen_io_start();
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 6803f73..d975756 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1792,7 +1792,7 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
             }
             tcg_ctx.gen_opc_pc[lj] = dc->pc;
             gen_opc_instr_start[lj] = 1;
-                        gen_opc_icount[lj] = num_insns;
+                        tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
 
         /* Pretty disas.  */
diff --git a/target-mips/translate.c b/target-mips/translate.c
index e1ea968..abecfb3 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15585,7 +15585,7 @@ gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
             gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
             gen_opc_btarget[lj] = ctx.btarget;
             gen_opc_instr_start[lj] = 1;
-            gen_opc_icount[lj] = num_insns;
+            tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
             gen_io_start();
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index b7ad6a4..5b08314 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1712,7 +1712,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
             }
             tcg_ctx.gen_opc_pc[k] = dc->pc;
             gen_opc_instr_start[k] = 1;
-            gen_opc_icount[k] = num_insns;
+            tcg_ctx.gen_opc_icount[k] = num_insns;
         }
 
         if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 276edc8..7fdde5f 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9684,7 +9684,7 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
             }
             tcg_ctx.gen_opc_pc[lj] = ctx.nip;
             gen_opc_instr_start[lj] = 1;
-            gen_opc_icount[lj] = num_insns;
+            tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
         LOG_DISAS("----------------\n");
         LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index ff2868f..b2774ee 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -5166,7 +5166,7 @@ static inline void gen_intermediate_code_internal(CPUS390XState *env,
             tcg_ctx.gen_opc_pc[lj] = dc.pc;
             gen_opc_cc_op[lj] = dc.cc_op;
             gen_opc_instr_start[lj] = 1;
-            gen_opc_icount[lj] = num_insns;
+            tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
             gen_io_start();
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 4def163..ca76be5 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -2008,7 +2008,7 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
             tcg_ctx.gen_opc_pc[ii] = ctx.pc;
             gen_opc_hflags[ii] = ctx.flags;
             gen_opc_instr_start[ii] = 1;
-            gen_opc_icount[ii] = num_insns;
+            tcg_ctx.gen_opc_icount[ii] = num_insns;
         }
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
             gen_io_start();
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 4f3a844..cbb8997 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5287,7 +5287,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
                 tcg_ctx.gen_opc_pc[lj] = dc->pc;
                 gen_opc_npc[lj] = dc->npc;
                 gen_opc_instr_start[lj] = 1;
-                gen_opc_icount[lj] = num_insns;
+                tcg_ctx.gen_opc_icount[lj] = num_insns;
             }
         }
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 32a4265..0562615 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -2008,7 +2008,7 @@ static inline void gen_intermediate_code_internal(CPUUniCore32State *env,
             }
             tcg_ctx.gen_opc_pc[lj] = dc->pc;
             gen_opc_instr_start[lj] = 1;
-            gen_opc_icount[lj] = num_insns;
+            tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
 
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 21126fc..e93c2e6 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -2902,7 +2902,7 @@ static void gen_intermediate_code_internal(
             }
             tcg_ctx.gen_opc_pc[lj] = dc.pc;
             gen_opc_instr_start[lj] = 1;
-            gen_opc_icount[lj] = insn_count;
+            tcg_ctx.gen_opc_icount[lj] = insn_count;
         }
 
         if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
diff --git a/translate-all.c b/translate-all.c
index d9c2e57..177e95a 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -148,7 +148,7 @@ int cpu_restore_state(TranslationBlock *tb,
     /* now find start of instruction before */
     while (gen_opc_instr_start[j] == 0)
         j--;
-    env->icount_decr.u16.low -= gen_opc_icount[j];
+    env->icount_decr.u16.low -= s->gen_opc_icount[j];
 
     restore_state_to_opc(env, tb, j);
 
commit 25983cad31969e3003eef77bc03a6700f46899d2
Author: Evgeny Voevodin <e.voevodin at samsung.com>
Date:   Wed Nov 21 11:43:04 2012 +0400

    TCG: Use gen_opc_pc from context instead of global variable.
    
    Signed-off-by: Evgeny Voevodin <e.voevodin at samsung.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 4045f78..bcde367 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3412,7 +3412,7 @@ static inline void gen_intermediate_code_internal(CPUAlphaState *env,
                 while (lj < j)
                     gen_opc_instr_start[lj++] = 0;
             }
-            gen_opc_pc[lj] = ctx.pc;
+            tcg_ctx.gen_opc_pc[lj] = ctx.pc;
             gen_opc_instr_start[lj] = 1;
             gen_opc_icount[lj] = num_insns;
         }
@@ -3551,5 +3551,5 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model)
 
 void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb, int pc_pos)
 {
-    env->pc = gen_opc_pc[pc_pos];
+    env->pc = tcg_ctx.gen_opc_pc[pc_pos];
 }
diff --git a/target-arm/translate.c b/target-arm/translate.c
index c42110a..8ea8bba 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9840,7 +9840,7 @@ static inline void gen_intermediate_code_internal(CPUARMState *env,
                 while (lj < j)
                     gen_opc_instr_start[lj++] = 0;
             }
-            gen_opc_pc[lj] = dc->pc;
+            tcg_ctx.gen_opc_pc[lj] = dc->pc;
             gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
             gen_opc_instr_start[lj] = 1;
             gen_opc_icount[lj] = num_insns;
@@ -10043,6 +10043,6 @@ void cpu_dump_state(CPUARMState *env, FILE *f, fprintf_function cpu_fprintf,
 
 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
 {
-    env->regs[15] = gen_opc_pc[pc_pos];
+    env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
     env->condexec_bits = gen_opc_condexec_bits[pc_pos];
 }
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 0b0e86d..745cd7a 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3305,9 +3305,9 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb,
                 }
             }
             if (dc->delayed_branch == 1) {
-                gen_opc_pc[lj] = dc->ppc | 1;
+                tcg_ctx.gen_opc_pc[lj] = dc->ppc | 1;
             } else {
-                gen_opc_pc[lj] = dc->pc;
+                tcg_ctx.gen_opc_pc[lj] = dc->pc;
             }
             gen_opc_instr_start[lj] = 1;
             gen_opc_icount[lj] = num_insns;
@@ -3621,5 +3621,5 @@ CRISCPU *cpu_cris_init(const char *cpu_model)
 
 void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb, int pc_pos)
 {
-    env->pc = gen_opc_pc[pc_pos];
+    env->pc = tcg_ctx.gen_opc_pc[pc_pos];
 }
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 8e676ba..aea843c 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -7990,7 +7990,7 @@ static inline void gen_intermediate_code_internal(CPUX86State *env,
                 while (lj < j)
                     gen_opc_instr_start[lj++] = 0;
             }
-            gen_opc_pc[lj] = pc_ptr;
+            tcg_ctx.gen_opc_pc[lj] = pc_ptr;
             gen_opc_cc_op[lj] = dc->cc_op;
             gen_opc_instr_start[lj] = 1;
             gen_opc_icount[lj] = num_insns;
@@ -8081,15 +8081,16 @@ void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, int pc_pos)
         qemu_log("RESTORE:\n");
         for(i = 0;i <= pc_pos; i++) {
             if (gen_opc_instr_start[i]) {
-                qemu_log("0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
+                qemu_log("0x%04x: " TARGET_FMT_lx "\n", i,
+                        tcg_ctx.gen_opc_pc[i]);
             }
         }
         qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
-                pc_pos, gen_opc_pc[pc_pos] - tb->cs_base,
+                pc_pos, tcg_ctx.gen_opc_pc[pc_pos] - tb->cs_base,
                 (uint32_t)tb->cs_base);
     }
 #endif
-    env->eip = gen_opc_pc[pc_pos] - tb->cs_base;
+    env->eip = tcg_ctx.gen_opc_pc[pc_pos] - tb->cs_base;
     cc_op = gen_opc_cc_op[pc_pos];
     if (cc_op != CC_OP_DYNAMIC)
         env->cc_op = cc_op;
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index af98649..fcafb06 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1054,7 +1054,7 @@ static void gen_intermediate_code_internal(CPULM32State *env,
                     gen_opc_instr_start[lj++] = 0;
                 }
             }
-            gen_opc_pc[lj] = dc->pc;
+            tcg_ctx.gen_opc_pc[lj] = dc->pc;
             gen_opc_instr_start[lj] = 1;
             gen_opc_icount[lj] = num_insns;
         }
@@ -1172,7 +1172,7 @@ void cpu_dump_state(CPULM32State *env, FILE *f, fprintf_function cpu_fprintf,
 
 void restore_state_to_opc(CPULM32State *env, TranslationBlock *tb, int pc_pos)
 {
-    env->pc = gen_opc_pc[pc_pos];
+    env->pc = tcg_ctx.gen_opc_pc[pc_pos];
 }
 
 void lm32_translate_init(void)
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index b13be48..74772dd 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -3021,7 +3021,7 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
                 while (lj < j)
                     gen_opc_instr_start[lj++] = 0;
             }
-            gen_opc_pc[lj] = dc->pc;
+            tcg_ctx.gen_opc_pc[lj] = dc->pc;
             gen_opc_instr_start[lj] = 1;
             gen_opc_icount[lj] = num_insns;
         }
@@ -3121,5 +3121,5 @@ void cpu_dump_state(CPUM68KState *env, FILE *f, fprintf_function cpu_fprintf,
 
 void restore_state_to_opc(CPUM68KState *env, TranslationBlock *tb, int pc_pos)
 {
-    env->pc = gen_opc_pc[pc_pos];
+    env->pc = tcg_ctx.gen_opc_pc[pc_pos];
 }
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index cce4494..6803f73 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1790,7 +1790,7 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
                 while (lj < j)
                     gen_opc_instr_start[lj++] = 0;
             }
-            gen_opc_pc[lj] = dc->pc;
+            tcg_ctx.gen_opc_pc[lj] = dc->pc;
             gen_opc_instr_start[lj] = 1;
                         gen_opc_icount[lj] = num_insns;
         }
@@ -2014,5 +2014,5 @@ MicroBlazeCPU *cpu_mb_init(const char *cpu_model)
 
 void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb, int pc_pos)
 {
-    env->sregs[SR_PC] = gen_opc_pc[pc_pos];
+    env->sregs[SR_PC] = tcg_ctx.gen_opc_pc[pc_pos];
 }
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 71c55bc..e1ea968 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15581,7 +15581,7 @@ gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
                 while (lj < j)
                     gen_opc_instr_start[lj++] = 0;
             }
-            gen_opc_pc[lj] = ctx.pc;
+            tcg_ctx.gen_opc_pc[lj] = ctx.pc;
             gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
             gen_opc_btarget[lj] = ctx.btarget;
             gen_opc_instr_start[lj] = 1;
@@ -16002,7 +16002,7 @@ void cpu_state_reset(CPUMIPSState *env)
 
 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
 {
-    env->active_tc.PC = gen_opc_pc[pc_pos];
+    env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
     env->hflags &= ~MIPS_HFLAG_BMASK;
     env->hflags |= gen_opc_hflags[pc_pos];
     switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index f14da7b..b7ad6a4 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1710,7 +1710,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
                     gen_opc_instr_start[k++] = 0;
                 }
             }
-            gen_opc_pc[k] = dc->pc;
+            tcg_ctx.gen_opc_pc[k] = dc->pc;
             gen_opc_instr_start[k] = 1;
             gen_opc_icount[k] = num_insns;
         }
@@ -1832,5 +1832,5 @@ void cpu_dump_state(CPUOpenRISCState *env, FILE *f,
 void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb,
                           int pc_pos)
 {
-    env->pc = gen_opc_pc[pc_pos];
+    env->pc = tcg_ctx.gen_opc_pc[pc_pos];
 }
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 987b04e..276edc8 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9682,7 +9682,7 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
                 while (lj < j)
                     gen_opc_instr_start[lj++] = 0;
             }
-            gen_opc_pc[lj] = ctx.nip;
+            tcg_ctx.gen_opc_pc[lj] = ctx.nip;
             gen_opc_instr_start[lj] = 1;
             gen_opc_icount[lj] = num_insns;
         }
@@ -9810,5 +9810,5 @@ void gen_intermediate_code_pc (CPUPPCState *env, struct TranslationBlock *tb)
 
 void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb, int pc_pos)
 {
-    env->nip = gen_opc_pc[pc_pos];
+    env->nip = tcg_ctx.gen_opc_pc[pc_pos];
 }
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 993f207..ff2868f 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -5163,7 +5163,7 @@ static inline void gen_intermediate_code_internal(CPUS390XState *env,
                     gen_opc_instr_start[lj++] = 0;
                 }
             }
-            gen_opc_pc[lj] = dc.pc;
+            tcg_ctx.gen_opc_pc[lj] = dc.pc;
             gen_opc_cc_op[lj] = dc.cc_op;
             gen_opc_instr_start[lj] = 1;
             gen_opc_icount[lj] = num_insns;
@@ -5240,7 +5240,7 @@ void gen_intermediate_code_pc (CPUS390XState *env, struct TranslationBlock *tb)
 void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb, int pc_pos)
 {
     int cc_op;
-    env->psw.addr = gen_opc_pc[pc_pos];
+    env->psw.addr = tcg_ctx.gen_opc_pc[pc_pos];
     cc_op = gen_opc_cc_op[pc_pos];
     if ((cc_op != CC_OP_DYNAMIC) && (cc_op != CC_OP_STATIC)) {
         env->cc_op = cc_op;
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 5497ded..4def163 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -2005,7 +2005,7 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
                 while (ii < i)
                     gen_opc_instr_start[ii++] = 0;
             }
-            gen_opc_pc[ii] = ctx.pc;
+            tcg_ctx.gen_opc_pc[ii] = ctx.pc;
             gen_opc_hflags[ii] = ctx.flags;
             gen_opc_instr_start[ii] = 1;
             gen_opc_icount[ii] = num_insns;
@@ -2088,6 +2088,6 @@ void gen_intermediate_code_pc(CPUSH4State * env, struct TranslationBlock *tb)
 
 void restore_state_to_opc(CPUSH4State *env, TranslationBlock *tb, int pc_pos)
 {
-    env->pc = gen_opc_pc[pc_pos];
+    env->pc = tcg_ctx.gen_opc_pc[pc_pos];
     env->flags = gen_opc_hflags[pc_pos];
 }
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 2ae8036..4f3a844 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5284,7 +5284,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
                 lj++;
                 while (lj < j)
                     gen_opc_instr_start[lj++] = 0;
-                gen_opc_pc[lj] = dc->pc;
+                tcg_ctx.gen_opc_pc[lj] = dc->pc;
                 gen_opc_npc[lj] = dc->npc;
                 gen_opc_instr_start[lj] = 1;
                 gen_opc_icount[lj] = num_insns;
@@ -5478,7 +5478,7 @@ void gen_intermediate_code_init(CPUSPARCState *env)
 void restore_state_to_opc(CPUSPARCState *env, TranslationBlock *tb, int pc_pos)
 {
     target_ulong npc;
-    env->pc = gen_opc_pc[pc_pos];
+    env->pc = tcg_ctx.gen_opc_pc[pc_pos];
     npc = gen_opc_npc[pc_pos];
     if (npc == 1) {
         /* dynamic NPC: already stored */
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 052bb45..32a4265 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -2006,7 +2006,7 @@ static inline void gen_intermediate_code_internal(CPUUniCore32State *env,
                     gen_opc_instr_start[lj++] = 0;
                 }
             }
-            gen_opc_pc[lj] = dc->pc;
+            tcg_ctx.gen_opc_pc[lj] = dc->pc;
             gen_opc_instr_start[lj] = 1;
             gen_opc_icount[lj] = num_insns;
         }
@@ -2203,5 +2203,5 @@ void cpu_dump_state(CPUUniCore32State *env, FILE *f,
 
 void restore_state_to_opc(CPUUniCore32State *env, TranslationBlock *tb, int pc_pos)
 {
-    env->regs[31] = gen_opc_pc[pc_pos];
+    env->regs[31] = tcg_ctx.gen_opc_pc[pc_pos];
 }
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index e5a3f49..21126fc 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -2900,7 +2900,7 @@ static void gen_intermediate_code_internal(
                     gen_opc_instr_start[lj++] = 0;
                 }
             }
-            gen_opc_pc[lj] = dc.pc;
+            tcg_ctx.gen_opc_pc[lj] = dc.pc;
             gen_opc_instr_start[lj] = 1;
             gen_opc_icount[lj] = insn_count;
         }
@@ -3028,5 +3028,5 @@ void cpu_dump_state(CPUXtensaState *env, FILE *f, fprintf_function cpu_fprintf,
 
 void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb, int pc_pos)
 {
-    env->pc = gen_opc_pc[pc_pos];
+    env->pc = tcg_ctx.gen_opc_pc[pc_pos];
 }
commit c3a43607d927e6a0ecce0b61e8297c1cfe604c14
Author: Evgeny Voevodin <e.voevodin at samsung.com>
Date:   Wed Nov 21 11:43:03 2012 +0400

    tcg/tcg.h: Duplicate global TCG gen_opc_ arrays into TCGContext.
    
    Signed-off-by: Evgeny Voevodin <e.voevodin at samsung.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/tcg.h b/tcg/tcg.h
index 9481e35..f6e255f 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -455,6 +455,9 @@ struct TCGContext {
 
     uint16_t *gen_opc_ptr;
     TCGArg *gen_opparam_ptr;
+    target_ulong gen_opc_pc[OPC_BUF_SIZE];
+    uint16_t gen_opc_icount[OPC_BUF_SIZE];
+    uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
 
 #if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU)
     /* labels info for qemu_ld/st IRs
commit 2aa1cb514cdce31ca68902d464cd03d31a76e998
Author: Brad Smith <brad at comstyle.com>
Date:   Mon Nov 19 04:22:12 2012 -0500

    curses: Remove OpenBSD workaround
    
    I removed the same sort of workaround for OpenBSD within the
    configure script with commit 4dcc3f5876fa638d5c35bd47be3b717ea74cc2e7
    but didn't bother to grep further to come across this same chunk
    of code in the curses code itself. So the following diff removes
    the same workaround chunk within the curses code.
    
    Signed-off-by: Brad Smith <brad at comstyle.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/ui/curses.c b/ui/curses.c
index b40b223..5dc0b2c 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -28,10 +28,6 @@
 #include <termios.h>
 #endif
 
-#ifdef __OpenBSD__
-#define resize_term resizeterm
-#endif
-
 #include "qemu-common.h"
 #include "console.h"
 #include "sysemu.h"
commit 0be4835b4932f38167b611c2b311ebaaec98a8eb
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Nov 2 09:20:46 2012 +1100

    exec: Advise huge pages for the TCG code gen buffer
    
    After allocating 32MB or more contiguous memory, huge pages
    would seem to be ideal.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/exec.c b/exec.c
index 8435de0..0594b07 100644
--- a/exec.c
+++ b/exec.c
@@ -607,6 +607,8 @@ static inline void code_gen_alloc(size_t tb_size)
         exit(1);
     }
 
+    qemu_madvise(code_gen_buffer, code_gen_buffer_size, QEMU_MADV_HUGEPAGE);
+
     /* Steal room for the prologue at the end of the buffer.  This ensures
        (via the MAX_CODE_GEN_BUFFER_SIZE limits above) that direct branches
        from TB's to the prologue are going to be in range.  It also means
commit b34d12d153e6e5c5e5e00eac510b054a94409deb
Author: Igor Mammedov <imammedo at redhat.com>
Date:   Mon Oct 22 17:03:00 2012 +0200

    target-i386: Postpone cpuid_level update to realize time
    
    Delay capping cpuid_level to 7 to realize time so property setters
    for cpuid_7_0_ebx_features and "level" could be used in any order/time
    between x86_cpu_initfn() and x86_cpu_realize().
    
    Signed-off-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index a631ae9..7be3ad8 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1381,9 +1381,6 @@ static int cpu_x86_parse_featurestr(x86_def_t *x86_cpu_def, char *features)
         if (kvm_check_features_against_host(x86_cpu_def) && enforce_cpuid)
             goto error;
     }
-    if (x86_cpu_def->cpuid_7_0_ebx_features && x86_cpu_def->level < 7) {
-        x86_cpu_def->level = 7;
-    }
     return 0;
 
 error:
@@ -2074,6 +2071,11 @@ static void x86_cpu_apic_init(X86CPU *cpu, Error **errp)
 void x86_cpu_realize(Object *obj, Error **errp)
 {
     X86CPU *cpu = X86_CPU(obj);
+    CPUX86State *env = &cpu->env;
+
+    if (env->cpuid_7_0_ebx_features && env->cpuid_level < 7) {
+        env->cpuid_level = 7;
+    }
 
 #ifndef CONFIG_USER_ONLY
     qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
commit 654598c944aa31cdbea435bd468055af9c918d16
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Nov 23 19:12:18 2012 +0100

    pc_sysfw: Plug memory leak on pc_fw_add_pflash_drv() error path
    
    Harmless, because we the error inevitably leads to another, fatal one
    in pc_system_flash_init(): PC system firmware (pflash) not available.
    Fix it anyway.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/pc_sysfw.c b/hw/pc_sysfw.c
index 9d7c5f4..40bced2 100644
--- a/hw/pc_sysfw.c
+++ b/hw/pc_sysfw.c
@@ -98,7 +98,9 @@ static void pc_fw_add_pflash_drv(void)
       return;
     }
 
-    drive_init(opts, machine->use_scsi);
+    if (!drive_init(opts, machine->use_scsi)) {
+        qemu_opts_del(opts);
+    }
 }
 
 static void pc_system_flash_init(MemoryRegion *rom_memory,
commit 3528a3cba1f59de520fad7b1c843759e8655ea2c
Author: Michal Privoznik <mprivozn at redhat.com>
Date:   Fri Nov 23 09:52:39 2012 +0100

    qemu-options: Fix space at EOL
    
    There's no need to add a space at the end of line.
    Moreover, it can make problems in some projects that
    store the help output into a file (and run couple of
    tests based on that) and have space at EOL forbidden.
    
    Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/qemu-options.hx b/qemu-options.hx
index de43b1b..231cc4f 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1331,7 +1331,7 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
     "                connect the host TAP network interface to VLAN 'n'\n"
 #else
     "-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,helper=helper][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off][,vhostfd=h][,vhostforce=on|off]\n"
-    "                connect the host TAP network interface to VLAN 'n' \n"
+    "                connect the host TAP network interface to VLAN 'n'\n"
     "                use network scripts 'file' (default=" DEFAULT_NETWORK_SCRIPT ")\n"
     "                to configure it and 'dfile' (default=" DEFAULT_NETWORK_DOWN_SCRIPT ")\n"
     "                to deconfigure it\n"
commit 993d46ce7e54f3d035d344ed1b145b13f9ac54b9
Author: Stefan Weil <sw at weilnetz.de>
Date:   Fri Nov 23 07:26:04 2012 +0100

    Fix spelling in comments and documentation
    
    These spelling bugs were found by codespell:
    
    supressing -> suppressing
    transfered -> transferred
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/usb.h b/hw/usb.h
index 7d6de69..f05eb17 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -282,7 +282,7 @@ typedef struct USBDeviceClass {
      * Called from handle_packet().
      *
      * Status gets stored in p->status, and if p->status == USB_RET_SUCCESS
-     * then the number of bytes transfered is stored in p->actual_length
+     * then the number of bytes transferred is stored in p->actual_length
      */
     void (*handle_control)(USBDevice *dev, USBPacket *p, int request, int value,
                            int index, int length, uint8_t *data);
@@ -292,7 +292,7 @@ typedef struct USBDeviceClass {
      * Called from handle_packet().
      *
      * Status gets stored in p->status, and if p->status == USB_RET_SUCCESS
-     * then the number of bytes transfered is stored in p->actual_length
+     * then the number of bytes transferred is stored in p->actual_length
      */
     void (*handle_data)(USBDevice *dev, USBPacket *p);
 
@@ -358,7 +358,7 @@ struct USBPacket {
     bool short_not_ok;
     bool int_req;
     int status; /* USB_RET_* status code */
-    int actual_length; /* Number of bytes actually transfered */
+    int actual_length; /* Number of bytes actually transferred */
     /* Internal use by the USB layer.  */
     USBPacketState state;
     USBCombinedPacket *combined;
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index b2eaf20..0be5c7e 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -43,7 +43,7 @@ def qemu_img(*args):
     return subprocess.call(qemu_img_args + list(args), stdin=devnull, stdout=devnull)
 
 def qemu_img_verbose(*args):
-    '''Run qemu-img without supressing its output and return the exit code'''
+    '''Run qemu-img without suppressing its output and return the exit code'''
     return subprocess.call(qemu_img_args + list(args))
 
 def qemu_io(*args):
commit 4dbd84e26f53d3283baa463f390f9623e8913e8f
Author: Markus Armbruster <armbru at redhat.com>
Date:   Thu Nov 22 15:16:36 2012 +0100

    Clean up pci_drive_hot_add()'s use of BlockInterfaceType
    
    pci_drive_hot_add() parameter type has the wrong type: int instead of
    BlockInterfaceType.  It's actually redundant, so we can just drop it.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/device-hotplug.c b/hw/device-hotplug.c
index eec0fe3..6d9c080 100644
--- a/hw/device-hotplug.c
+++ b/hw/device-hotplug.c
@@ -49,18 +49,16 @@ DriveInfo *add_init_drive(const char *optstr)
 }
 
 #if !defined(TARGET_I386)
-int pci_drive_hot_add(Monitor *mon, const QDict *qdict,
-                      DriveInfo *dinfo, int type)
+int pci_drive_hot_add(Monitor *mon, const QDict *qdict, DriveInfo *dinfo)
 {
     /* On non-x86 we don't do PCI hotplug */
-    monitor_printf(mon, "Can't hot-add drive to type %d\n", type);
+    monitor_printf(mon, "Can't hot-add drive to type %d\n", dinfo->type);
     return -1;
 }
 #endif
 
 void drive_hot_add(Monitor *mon, const QDict *qdict)
 {
-    int type;
     DriveInfo *dinfo = NULL;
     const char *opts = qdict_get_str(qdict, "opts");
 
@@ -72,14 +70,13 @@ void drive_hot_add(Monitor *mon, const QDict *qdict)
         monitor_printf(mon, "Parameter addr not supported\n");
         goto err;
     }
-    type = dinfo->type;
 
-    switch (type) {
+    switch (dinfo->type) {
     case IF_NONE:
         monitor_printf(mon, "OK\n");
         break;
     default:
-        if (pci_drive_hot_add(mon, qdict, dinfo, type)) {
+        if (pci_drive_hot_add(mon, qdict, dinfo)) {
             goto err;
         }
     }
diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index 0ca5546..3bcfdcc 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -111,15 +111,14 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
     return 0;
 }
 
-int pci_drive_hot_add(Monitor *mon, const QDict *qdict,
-                      DriveInfo *dinfo, int type)
+int pci_drive_hot_add(Monitor *mon, const QDict *qdict, DriveInfo *dinfo)
 {
     int dom, pci_bus;
     unsigned slot;
     PCIDevice *dev;
     const char *pci_addr = qdict_get_str(qdict, "pci_addr");
 
-    switch (type) {
+    switch (dinfo->type) {
     case IF_SCSI:
         if (pci_read_devaddr(mon, pci_addr, &dom, &pci_bus, &slot)) {
             goto err;
@@ -135,7 +134,7 @@ int pci_drive_hot_add(Monitor *mon, const QDict *qdict,
         }
         break;
     default:
-        monitor_printf(mon, "Can't hot-add drive to type %d\n", type);
+        monitor_printf(mon, "Can't hot-add drive to type %d\n", dinfo->type);
         goto err;
     }
 
diff --git a/sysemu.h b/sysemu.h
index f5ac664..c1b370b 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -145,8 +145,7 @@ extern unsigned int nb_prom_envs;
 
 /* pci-hotplug */
 void pci_device_hot_add(Monitor *mon, const QDict *qdict);
-int pci_drive_hot_add(Monitor *mon, const QDict *qdict,
-                      DriveInfo *dinfo, int type);
+int pci_drive_hot_add(Monitor *mon, const QDict *qdict, DriveInfo *dinfo);
 void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict);
 
 /* generic hotplug */
commit 036f0f8356936dba36b952c16f477b3f04f54e37
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Nov 19 15:13:49 2012 +1000

    arm: a9mpcore: remove un-used ptimer_iomem field
    
    I'm guessing this is a hangover from a previous coreification of the mptimer
    sub-module. This field is completely unused - removed.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index 824ff0a..f802de0 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -19,7 +19,6 @@ typedef struct a9mp_priv_state {
     uint32_t old_timer_status[8];
     uint32_t num_cpu;
     MemoryRegion scu_iomem;
-    MemoryRegion ptimer_iomem;
     MemoryRegion container;
     DeviceState *mptimer;
     DeviceState *gic;
commit dee17bf9e5d29bd08592c6fc47541aad70444bbc
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Nov 2 08:36:37 2012 +1100

    target-sparc: Remove t0, t1 from CPUSPARCState
    
    These fields are no longer used.
    
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 042d52a..375f20a 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -392,7 +392,6 @@ struct CPUSPARCState {
     target_ulong cc_dst;
     uint32_t cc_op;
 
-    target_ulong t0, t1; /* temporaries live across basic blocks */
     target_ulong cond; /* conditional branch result (XXX: save it in a
                           temporary register when possible) */
 
commit d694516440ca31bbcc7ad73f5e99b45fbeb2a6e6
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Nov 2 08:36:36 2012 +1100

    target-m68k: Remove t1 from CPUM68KState
    
    This field is no longer used.
    
    Cc: Paul Brook <paul at codesourcery.com>
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 780e2c9..f4fcdee 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -103,9 +103,6 @@ typedef struct CPUM68KState {
     uint32_t rambar0;
     uint32_t cacr;
 
-    /* ??? remove this.  */
-    uint32_t t1;
-
     int pending_vector;
     int pending_level;
 
commit c47d08ceff8ac76ff857016c80a8864fcf45a7d6
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Nov 2 08:36:35 2012 +1100

    target-alpha: Remove t0, t1 from CPUAlphaState
    
    These fields are no longer (or were never?) used.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 34221fb..9939d61 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -280,13 +280,6 @@ struct CPUAlphaState {
     struct QEMUTimer *alarm_timer;
     uint64_t alarm_expire;
 
-#if TARGET_LONG_BITS > HOST_LONG_BITS
-    /* temporary fixed-point registers
-     * used to emulate 64 bits target on 32 bits hosts
-     */
-    target_ulong t0, t1;
-#endif
-
     /* Those resources are used only in QEMU core */
     CPU_COMMON
 
commit 8367a14fd3c1ecd5551c91cd3f951ffc61ad7c12
Author: Stefan Weil <sw at weilnetz.de>
Date:   Fri Nov 2 08:35:54 2012 +0100

    s390x: Spelling fixes (endianess -> endianness, occured -> occurred)
    
    Replace also "write into" by "write to".
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/s390x/sclp.h b/hw/s390x/sclp.h
index fe89dad..231a38a 100644
--- a/hw/s390x/sclp.h
+++ b/hw/s390x/sclp.h
@@ -51,7 +51,7 @@
 
 /*
  * Normally packed structures are not the right thing to do, since all code
- * must take care of endianess. We cant use ldl_phys and friends for two
+ * must take care of endianness. We cannot use ldl_phys and friends for two
  * reasons, though:
  * - some of the embedded structures below the SCCB can appear multiple times
  *   at different locations, so there is no fixed offset
@@ -60,7 +60,7 @@
  *   alter the structure while we parse it. We cannot use ldl_p and friends
  *   either without doing pointer arithmetics
  * So we have to double check that all users of sclp data structures use the
- * right endianess wrappers.
+ * right endianness wrappers.
  */
 typedef struct SCCBHeader {
     uint16_t length;
diff --git a/hw/s390x/sclpconsole.c b/hw/s390x/sclpconsole.c
index 0ec5623..fece878 100644
--- a/hw/s390x/sclpconsole.c
+++ b/hw/s390x/sclpconsole.c
@@ -179,8 +179,8 @@ static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
 }
 
 /* triggered by SCLP's write_event_data
- *  - write console data into character layer
- *  returns < 0 if an error occured
+ *  - write console data to character layer
+ *  returns < 0 if an error occurred
  */
 static ssize_t write_console_data(SCLPEvent *event, const uint8_t *buf,
                                   size_t len)
commit a93cf9dfba171aa94e3c4002d58abef2a3732bfb
Author: Stefan Weil <sw at weilnetz.de>
Date:   Fri Nov 2 08:29:53 2012 +0100

    Fix comments (adress -> address, layed -> laid, wierd -> weird)
    
    Remove also a duplicated 'the'.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index d571fd0..9f1cb08 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -352,7 +352,7 @@ icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
 
   ip->ip_ttl = MAXTTL;
   ip->ip_p = IPPROTO_ICMP;
-  ip->ip_dst = ip->ip_src;    /* ip adresses */
+  ip->ip_dst = ip->ip_src;    /* ip addresses */
   ip->ip_src = m->slirp->vhost_addr;
 
   (void ) ip_output((struct socket *)NULL, m);
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 9481e35..e7de8c0 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -290,8 +290,8 @@ typedef int TCGv_i64;
 #define TCG_CALL_DUMMY_TCGV     MAKE_TCGV_I32(-1)
 #define TCG_CALL_DUMMY_ARG      ((TCGArg)(-1))
 
-/* Conditions.  Note that these are layed out for easy manipulation by
-   the the functions below:
+/* Conditions.  Note that these are laid out for easy manipulation by
+   the functions below:
      bit 0 is used for inverting;
      bit 1 is signed,
      bit 2 is unsigned,
diff --git a/uri.c b/uri.c
index dd922de..138547b 100644
--- a/uri.c
+++ b/uri.c
@@ -432,7 +432,7 @@ rfc3986_parse_host(URI *uri, const char **str)
 
     host = cur;
     /*
-     * IPv6 and future adressing scheme are enclosed between brackets
+     * IPv6 and future addressing scheme are enclosed between brackets
      */
     if (*cur == '[') {
         cur++;
@@ -1917,7 +1917,7 @@ done:
  *     http://site1.com/docs/pic1.gif   http://site1.com/docs/pic1.gif
  *
  *
- * Note: if the URI reference is really wierd or complicated, it may be
+ * Note: if the URI reference is really weird or complicated, it may be
  *       worthwhile to first convert it into a "nice" one by calling
  *       uri_resolve (using 'base') before calling this routine,
  *       since this routine (for reasonable efficiency) assumes URI has
commit eac29d87c883fcbb54913ae20ed2bdccb4bcf7a3
Author: Stefan Weil <sw at weilnetz.de>
Date:   Fri Nov 2 08:14:12 2012 +0100

    Fix spelling (prefered -> preferred)
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/configure b/configure
index 447e6ed..79605d2 100755
--- a/configure
+++ b/configure
@@ -2130,7 +2130,7 @@ if test "$pixman" = "system"; then
 else
   if test ! -d ${source_path}/pixman/pixman; then
     echo "ERROR: pixman not present. Your options:"
-    echo "  (1) Prefered: Install the pixman devel package (any recent"
+    echo "  (1) Preferred: Install the pixman devel package (any recent"
     echo "      distro should have packages as Xorg needs pixman too)."
     echo "  (2) Fetch the pixman submodule, using:"
     echo "      git submodule update --init pixman"
diff --git a/net/tap-win32.c b/net/tap-win32.c
index 8d2d32b..f9bd741 100644
--- a/net/tap-win32.c
+++ b/net/tap-win32.c
@@ -565,7 +565,7 @@ static void tap_win32_free_buffer(tap_win32_overlapped_t *overlapped,
 }
 
 static int tap_win32_open(tap_win32_overlapped_t **phandle,
-                          const char *prefered_name)
+                          const char *preferred_name)
 {
     char device_path[256];
     char device_guid[0x100];
@@ -581,8 +581,9 @@ static int tap_win32_open(tap_win32_overlapped_t **phandle,
     DWORD version_len;
     DWORD idThread;
 
-    if (prefered_name != NULL)
-        snprintf(name_buffer, sizeof(name_buffer), "%s", prefered_name);
+    if (preferred_name != NULL) {
+        snprintf(name_buffer, sizeof(name_buffer), "%s", preferred_name);
+    }
 
     rc = get_device_guid(device_guid, sizeof(device_guid), name_buffer, sizeof(name_buffer));
     if (rc)
commit bb5b5c20b7f68c79e036cd3ec5e9e6362c112670
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sat Oct 20 20:37:04 2012 +0100

    configure: Remove stray debug output
    
    Rather than printing a message saying we're silently falling
    back to gthread coroutines when running on MacOS, actually
    do it silently.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/configure b/configure
index 994f731..447e6ed 100755
--- a/configure
+++ b/configure
@@ -2969,8 +2969,6 @@ EOF
     else
 	coroutine_backend=gthread
     fi
-  else
-    echo "Silently falling back into gthread backend under darwin"
   fi
 elif test "$coroutine" = "gthread" ; then
   coroutine_backend=gthread
commit 038d3d44598232f5aad40d1c84c215f38a21576c
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Thu Nov 15 16:32:53 2012 +1000

    sd: Send debug printfery to stderr not stdout
    
    Some debug printfs for SD are coming up in stdout. Redirected them to stderr
    instead.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/sd.c b/hw/sd.c
index 3c34d43..607edba 100644
--- a/hw/sd.c
+++ b/hw/sd.c
@@ -1439,8 +1439,8 @@ send_response:
         int i;
         DPRINTF("Response:");
         for (i = 0; i < rsplen; i++)
-            printf(" %02x", response[i]);
-        printf(" state %d\n", sd->state);
+            fprintf(stderr, " %02x", response[i]);
+        fprintf(stderr, " state %d\n", sd->state);
     } else {
         DPRINTF("No response %d\n", sd->state);
     }
commit 9df694eeb8447ae5a302b4d40df9a8b91dfc61da
Author: Igor Mammedov <imammedo at redhat.com>
Date:   Mon Oct 22 17:03:10 2012 +0200

    target-i386: Use define for cpuid vendor string size
    
    Signed-off-by: Igor Mammedov <imammedo at redhat.com>
    Reviewed-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 7877df1..a631ae9 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1106,13 +1106,13 @@ static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
     char *value;
     int i;
 
-    value = (char *)g_malloc(12 + 1);
+    value = (char *)g_malloc(CPUID_VENDOR_SZ + 1);
     for (i = 0; i < 4; i++) {
         value[i    ] = env->cpuid_vendor1 >> (8 * i);
         value[i + 4] = env->cpuid_vendor2 >> (8 * i);
         value[i + 8] = env->cpuid_vendor3 >> (8 * i);
     }
-    value[12] = '\0';
+    value[CPUID_VENDOR_SZ] = '\0';
     return value;
 }
 
@@ -1123,7 +1123,7 @@ static void x86_cpuid_set_vendor(Object *obj, const char *value,
     CPUX86State *env = &cpu->env;
     int i;
 
-    if (strlen(value) != 12) {
+    if (strlen(value) != CPUID_VENDOR_SZ) {
         error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
                   "vendor", value);
         return;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 90ef1ff..386c4f6 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -510,6 +510,8 @@
 #define CPUID_7_0_EBX_ADX      (1 << 19)
 #define CPUID_7_0_EBX_SMAP     (1 << 20)
 
+#define CPUID_VENDOR_SZ      12
+
 #define CPUID_VENDOR_INTEL_1 0x756e6547 /* "Genu" */
 #define CPUID_VENDOR_INTEL_2 0x49656e69 /* "ineI" */
 #define CPUID_VENDOR_INTEL_3 0x6c65746e /* "ntel" */
commit 8f961357d06a0beeb7d3efbde1d754d82ff6a300
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Tue Dec 4 17:34:39 2012 -0200

    target-i386: Separate feature string parsing from CPU model lookup
    
    Instead of parsing the whole cpu_model string inside
    cpu_x86_find_by_name(), first split it into the CPU model name and the
    full feature string, then parse the feature string into pieces.
    
    When using CPU model classes, those two pieces of information will be
    used at different moments (CPU model name will be used to find CPU
    class, feature string will be used after CPU object was created), so
    making the split in two steps will make it easier to refactor the code
    later.
    
    This should also help on the CPU properties work, that will just need to
    replace the cpu_x86_parse_featurestr() logic (and can keep the CPU model
    lookup code as-is).
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 754af68..7877df1 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1208,25 +1208,10 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
     cpu->env.tsc_khz = value / 1000;
 }
 
-static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
+static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *name)
 {
-    unsigned int i;
     x86_def_t *def;
 
-    char *s = g_strdup(cpu_model);
-    char *featurestr, *name = strtok(s, ",");
-    /* Features to be added */
-    uint32_t plus_features = 0, plus_ext_features = 0;
-    uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
-    uint32_t plus_kvm_features = kvm_default_features, plus_svm_features = 0;
-    uint32_t plus_7_0_ebx_features = 0;
-    /* Features to be removed */
-    uint32_t minus_features = 0, minus_ext_features = 0;
-    uint32_t minus_ext2_features = 0, minus_ext3_features = 0;
-    uint32_t minus_kvm_features = 0, minus_svm_features = 0;
-    uint32_t minus_7_0_ebx_features = 0;
-    uint32_t numvalue;
-
     for (def = x86_defs; def; def = def->next) {
         if (name && !strcmp(name, def->name)) {
             break;
@@ -1235,16 +1220,37 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
     if (kvm_enabled() && name && strcmp(name, "host") == 0) {
         kvm_cpu_fill_host(x86_cpu_def);
     } else if (!def) {
-        goto error;
+        return -1;
     } else {
         memcpy(x86_cpu_def, def, sizeof(*def));
     }
 
+    return 0;
+}
+
+/* Parse "+feature,-feature,feature=foo" CPU feature string
+ */
+static int cpu_x86_parse_featurestr(x86_def_t *x86_cpu_def, char *features)
+{
+    unsigned int i;
+    char *featurestr; /* Single 'key=value" string being parsed */
+    /* Features to be added */
+    uint32_t plus_features = 0, plus_ext_features = 0;
+    uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
+    uint32_t plus_kvm_features = kvm_default_features, plus_svm_features = 0;
+    uint32_t plus_7_0_ebx_features = 0;
+    /* Features to be removed */
+    uint32_t minus_features = 0, minus_ext_features = 0;
+    uint32_t minus_ext2_features = 0, minus_ext3_features = 0;
+    uint32_t minus_kvm_features = 0, minus_svm_features = 0;
+    uint32_t minus_7_0_ebx_features = 0;
+    uint32_t numvalue;
+
     add_flagname_to_bitmaps("hypervisor", &plus_features,
             &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
             &plus_kvm_features, &plus_svm_features,  &plus_7_0_ebx_features);
 
-    featurestr = strtok(NULL, ",");
+    featurestr = features ? strtok(features, ",") : NULL;
 
     while (featurestr) {
         char *val;
@@ -1378,11 +1384,9 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
     if (x86_cpu_def->cpuid_7_0_ebx_features && x86_cpu_def->level < 7) {
         x86_cpu_def->level = 7;
     }
-    g_free(s);
     return 0;
 
 error:
-    g_free(s);
     return -1;
 }
 
@@ -1492,11 +1496,25 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
     CPUX86State *env = &cpu->env;
     x86_def_t def1, *def = &def1;
     Error *error = NULL;
+    char *name, *features;
+    gchar **model_pieces;
 
     memset(def, 0, sizeof(*def));
 
-    if (cpu_x86_find_by_name(def, cpu_model) < 0)
-        return -1;
+    model_pieces = g_strsplit(cpu_model, ",", 2);
+    if (!model_pieces[0]) {
+        goto error;
+    }
+    name = model_pieces[0];
+    features = model_pieces[1];
+
+    if (cpu_x86_find_by_name(def, name) < 0) {
+        goto error;
+    }
+
+    if (cpu_x86_parse_featurestr(def, features) < 0) {
+        goto error;
+    }
     if (def->vendor1) {
         env->cpuid_vendor1 = def->vendor1;
         env->cpuid_vendor2 = def->vendor2;
@@ -1553,9 +1571,14 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
     if (error) {
         fprintf(stderr, "%s\n", error_get_pretty(error));
         error_free(error);
-        return -1;
+        goto error;
     }
+
+    g_strfreev(model_pieces);
     return 0;
+error:
+    g_strfreev(model_pieces);
+    return -1;
 }
 
 #if !defined(CONFIG_USER_ONLY)
commit 9f3fb5657b2133a408ccf40b4ab57dec9b4ce771
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Tue Dec 4 17:34:38 2012 -0200

    target-i386/cpu.c: Coding style fixes
    
    - Use spaces instead of tabs on cpu_x86_cpuid().
    - Use braces on 'if' statement cpu_x86_find_by_name().
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index c6c2ca0..754af68 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1215,7 +1215,7 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
 
     char *s = g_strdup(cpu_model);
     char *featurestr, *name = strtok(s, ",");
-    /* Features to be added*/
+    /* Features to be added */
     uint32_t plus_features = 0, plus_ext_features = 0;
     uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
     uint32_t plus_kvm_features = kvm_default_features, plus_svm_features = 0;
@@ -1227,9 +1227,11 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
     uint32_t minus_7_0_ebx_features = 0;
     uint32_t numvalue;
 
-    for (def = x86_defs; def; def = def->next)
-        if (name && !strcmp(name, def->name))
+    for (def = x86_defs; def; def = def->next) {
+        if (name && !strcmp(name, def->name)) {
             break;
+        }
+    }
     if (kvm_enabled() && name && strcmp(name, "host") == 0) {
         kvm_cpu_fill_host(x86_cpu_def);
     } else if (!def) {
@@ -1835,17 +1837,17 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         }
         break;
     case 0x8000000A:
-	if (env->cpuid_ext3_features & CPUID_EXT3_SVM) {
-		*eax = 0x00000001; /* SVM Revision */
-		*ebx = 0x00000010; /* nr of ASIDs */
-		*ecx = 0;
-		*edx = env->cpuid_svm_features; /* optional features */
-	} else {
-		*eax = 0;
-		*ebx = 0;
-		*ecx = 0;
-		*edx = 0;
-	}
+        if (env->cpuid_ext3_features & CPUID_EXT3_SVM) {
+            *eax = 0x00000001; /* SVM Revision */
+            *ebx = 0x00000010; /* nr of ASIDs */
+            *ecx = 0;
+            *edx = env->cpuid_svm_features; /* optional features */
+        } else {
+            *eax = 0;
+            *ebx = 0;
+            *ecx = 0;
+            *edx = 0;
+        }
         break;
     case 0xC0000000:
         *eax = env->cpuid_xlevel2;
commit 23e3fbec3355e67dbf26e98bbe33ef354097df8e
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Tue Dec 4 11:19:34 2012 -0200

    qdev: qdev_create(): use error_report() instead of hw_error()
    
    hw_error() is specific for fatal hardware emulation errors, not for
    internal errors related to the qdev object/class abstraction or object
    initialization.
    
    Replace it with an error_report() call, followed by abort().
    
    This will also help reduce dependencies of the qdev code (as hw_error()
    is from cpus.o, and depends on the CPU list from exec.o).
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/qdev.c b/hw/qdev.c
index 788b4da..599382c 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -109,10 +109,12 @@ DeviceState *qdev_create(BusState *bus, const char *name)
     dev = qdev_try_create(bus, name);
     if (!dev) {
         if (bus) {
-            hw_error("Unknown device '%s' for bus '%s'\n", name,
-                     object_get_typename(OBJECT(bus)));
+            error_report("Unknown device '%s' for bus '%s'\n", name,
+                         object_get_typename(OBJECT(bus)));
+            abort();
         } else {
-            hw_error("Unknown device '%s' for default sysbus\n", name);
+            error_report("Unknown device '%s' for default sysbus\n", name);
+            abort();
         }
     }
 
commit bcf7930105c26d09ae83cbd8b982d01bb421f215
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Tue Oct 23 21:44:08 2012 -0200

    sysemu.h: Include qemu-types.h instead of qemu-common.h
    
    It just needs the Monitor and DeviceState typedefs, so it doesn't need
    all of qemu-common.h.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/sysemu.h b/sysemu.h
index f5ac664..ab1ef8b 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -2,7 +2,7 @@
 #define SYSEMU_H
 /* Misc. things related to the system emulator.  */
 
-#include "qemu-common.h"
+#include "qemu-types.h"
 #include "qemu-option.h"
 #include "qemu-queue.h"
 #include "qemu-timer.h"
commit 394e1bb79591c2fbfc873e5ccc38e92a3ba992cf
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Tue Oct 23 21:41:52 2012 -0200

    Create qemu-types.h for struct typedefs
    
    Instead of keeping all those struct typedefs in qemu-common.h, move it
    to a header that can be safely included by other headers, containing
    only the struct typedefs and not pulling in other dependencies.
    
    Also, move some of the qdev-core.h typedefs to the new file, too, so
    other headers don't need to include qdev-core.h only because of
    DeviceState and other typedefs.
    
    This will help us remove qemu-common.h dependencies from some headers
    later.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/qdev-core.h b/hw/qdev-core.h
index fff7f0f..d672cca 100644
--- a/hw/qdev-core.h
+++ b/hw/qdev-core.h
@@ -3,20 +3,11 @@
 
 #include "qemu-queue.h"
 #include "qemu-option.h"
+#include "qemu-types.h"
 #include "qemu/object.h"
 #include "hw/irq.h"
 #include "error.h"
 
-typedef struct Property Property;
-
-typedef struct PropertyInfo PropertyInfo;
-
-typedef struct CompatProperty CompatProperty;
-
-typedef struct BusState BusState;
-
-typedef struct BusClass BusClass;
-
 enum DevState {
     DEV_STATE_CREATED = 1,
     DEV_STATE_INITIALIZED,
diff --git a/qemu-common.h b/qemu-common.h
index cef264c..e674786 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -14,6 +14,7 @@
 
 #include "compiler.h"
 #include "config-host.h"
+#include "qemu-types.h"
 
 #if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__) || defined(__ia64__)
 #define WORDS_ALIGNED
@@ -21,15 +22,6 @@
 
 #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
 
-typedef struct QEMUTimer QEMUTimer;
-typedef struct QEMUFile QEMUFile;
-typedef struct QEMUBH QEMUBH;
-typedef struct DeviceState DeviceState;
-
-struct Monitor;
-typedef struct Monitor Monitor;
-typedef struct MigrationParams MigrationParams;
-
 /* we put basic includes here to avoid repeating them in device drivers */
 #include <stdlib.h>
 #include <stdio.h>
@@ -258,48 +250,6 @@ struct ParallelIOArg {
 
 typedef int (*DMA_transfer_handler) (void *opaque, int nchan, int pos, int size);
 
-/* A load of opaque types so that device init declarations don't have to
-   pull in all the real definitions.  */
-typedef struct NICInfo NICInfo;
-typedef struct HCIInfo HCIInfo;
-typedef struct AudioState AudioState;
-typedef struct BlockDriverState BlockDriverState;
-typedef struct DriveInfo DriveInfo;
-typedef struct DisplayState DisplayState;
-typedef struct DisplayChangeListener DisplayChangeListener;
-typedef struct DisplaySurface DisplaySurface;
-typedef struct PixelFormat PixelFormat;
-typedef struct QemuConsole QemuConsole;
-typedef struct CharDriverState CharDriverState;
-typedef struct MACAddr MACAddr;
-typedef struct NetClientState NetClientState;
-typedef struct i2c_bus i2c_bus;
-typedef struct ISABus ISABus;
-typedef struct ISADevice ISADevice;
-typedef struct SMBusDevice SMBusDevice;
-typedef struct PCIHostState PCIHostState;
-typedef struct PCIExpressHost PCIExpressHost;
-typedef struct PCIBus PCIBus;
-typedef struct PCIDevice PCIDevice;
-typedef struct PCIExpressDevice PCIExpressDevice;
-typedef struct PCIBridge PCIBridge;
-typedef struct PCIEAERMsg PCIEAERMsg;
-typedef struct PCIEAERLog PCIEAERLog;
-typedef struct PCIEAERErr PCIEAERErr;
-typedef struct PCIEPort PCIEPort;
-typedef struct PCIESlot PCIESlot;
-typedef struct MSIMessage MSIMessage;
-typedef struct SerialState SerialState;
-typedef struct PCMCIACardState PCMCIACardState;
-typedef struct MouseTransformInfo MouseTransformInfo;
-typedef struct uWireSlave uWireSlave;
-typedef struct I2SCodec I2SCodec;
-typedef struct SSIBus SSIBus;
-typedef struct EventNotifier EventNotifier;
-typedef struct VirtIODevice VirtIODevice;
-typedef struct QEMUSGList QEMUSGList;
-typedef struct SHPCDevice SHPCDevice;
-
 typedef uint64_t pcibus_t;
 
 typedef enum LostTickPolicy {
diff --git a/qemu-types.h b/qemu-types.h
new file mode 100644
index 0000000..fd532a2
--- /dev/null
+++ b/qemu-types.h
@@ -0,0 +1,61 @@
+#ifndef QEMU_TYPEDEFS_H
+#define QEMU_TYPEDEFS_H
+
+/* A load of opaque types so that device init declarations don't have to
+   pull in all the real definitions.  */
+typedef struct QEMUTimer QEMUTimer;
+typedef struct QEMUFile QEMUFile;
+typedef struct QEMUBH QEMUBH;
+
+struct Monitor;
+typedef struct Monitor Monitor;
+typedef struct MigrationParams MigrationParams;
+
+typedef struct Property Property;
+typedef struct PropertyInfo PropertyInfo;
+typedef struct CompatProperty CompatProperty;
+typedef struct DeviceState DeviceState;
+typedef struct BusState BusState;
+typedef struct BusClass BusClass;
+
+typedef struct NICInfo NICInfo;
+typedef struct HCIInfo HCIInfo;
+typedef struct AudioState AudioState;
+typedef struct BlockDriverState BlockDriverState;
+typedef struct DriveInfo DriveInfo;
+typedef struct DisplayState DisplayState;
+typedef struct DisplayChangeListener DisplayChangeListener;
+typedef struct DisplaySurface DisplaySurface;
+typedef struct PixelFormat PixelFormat;
+typedef struct QemuConsole QemuConsole;
+typedef struct CharDriverState CharDriverState;
+typedef struct MACAddr MACAddr;
+typedef struct NetClientState NetClientState;
+typedef struct i2c_bus i2c_bus;
+typedef struct ISABus ISABus;
+typedef struct ISADevice ISADevice;
+typedef struct SMBusDevice SMBusDevice;
+typedef struct PCIHostState PCIHostState;
+typedef struct PCIExpressHost PCIExpressHost;
+typedef struct PCIBus PCIBus;
+typedef struct PCIDevice PCIDevice;
+typedef struct PCIExpressDevice PCIExpressDevice;
+typedef struct PCIBridge PCIBridge;
+typedef struct PCIEAERMsg PCIEAERMsg;
+typedef struct PCIEAERLog PCIEAERLog;
+typedef struct PCIEAERErr PCIEAERErr;
+typedef struct PCIEPort PCIEPort;
+typedef struct PCIESlot PCIESlot;
+typedef struct MSIMessage MSIMessage;
+typedef struct SerialState SerialState;
+typedef struct PCMCIACardState PCMCIACardState;
+typedef struct MouseTransformInfo MouseTransformInfo;
+typedef struct uWireSlave uWireSlave;
+typedef struct I2SCodec I2SCodec;
+typedef struct SSIBus SSIBus;
+typedef struct EventNotifier EventNotifier;
+typedef struct VirtIODevice VirtIODevice;
+typedef struct QEMUSGList QEMUSGList;
+typedef struct SHPCDevice SHPCDevice;
+
+#endif /* QEMU_TYPEDEFS_H */
commit cad32159663c5910098e10d64f4b5b10648b0095
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Tue Oct 23 21:55:19 2012 -0200

    qlist.h: Do not include qemu-common.h
    
    I don't know why it was including it, as I don't see any code that
    depends on anything from qemu-common.h.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/qlist.h b/qlist.h
index ae776f9..7408947 100644
--- a/qlist.h
+++ b/qlist.h
@@ -15,7 +15,6 @@
 
 #include "qobject.h"
 #include "qemu-queue.h"
-#include "qemu-common.h"
 #include "qemu-queue.h"
 
 typedef struct QListEntry {
commit 4d4922c339abf67e47c79068d343ed41a020b8e2
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Tue Oct 23 21:37:20 2012 -0200

    qga/channel-posix.c: Include headers it needs
    
    Include:
     - <errno.h> for errno
     - <unistd.h> & <fcntl.h> for fcntl()
     - <stdlib.h> for exit()
     - "osdep.h" for qemu_open()
    
    Some of those headers were probably being included by accident because
    some other headers were including qemu-common.h, but those headers
    should eventually stop including qemu-common.h.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/qga/channel-posix.c b/qga/channel-posix.c
index d152827..769a559 100644
--- a/qga/channel-posix.c
+++ b/qga/channel-posix.c
@@ -1,5 +1,10 @@
 #include <glib.h>
 #include <termios.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include "osdep.h"
 #include "qemu_socket.h"
 #include "qga/channel.h"
 
commit ccff63cac4f0d391187c9ee9aa2cab754df80c41
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Tue Oct 23 21:35:44 2012 -0200

    qapi/qmp-registry.c: Include headers it needs
    
    Include:
    - <glib.h> for g_malloc0()
    - <string.h> for strcmp()
    
    Some of those headers were probably being included by accident because
    some other headers were including qemu-common.h, but those headers
    should eventually stop including qemu-common.h.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c
index 5414613..c2c31b4 100644
--- a/qapi/qmp-registry.c
+++ b/qapi/qmp-registry.c
@@ -12,6 +12,8 @@
  *
  */
 
+#include <glib.h>
+#include <string.h>
 #include "qapi/qmp-core.h"
 
 static QTAILQ_HEAD(QmpCommandList, QmpCommand) qmp_commands =
commit 90f0cfa410544727ac4e9c130f9e5032e1fb9b71
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Tue Oct 23 21:19:18 2012 -0200

    ui/vnc-palette.c: Include headers it needs
    
    Include:
     - <glib.h> for g_malloc0()
     - <string.h> for memset()
    
    Some of those headers were probably being included by accident because
    some other headers were including qemu-common.h, but those headers
    should eventually stop including qemu-common.h.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/ui/vnc-palette.c b/ui/vnc-palette.c
index 63d5f64..c130dee 100644
--- a/ui/vnc-palette.c
+++ b/ui/vnc-palette.c
@@ -27,6 +27,8 @@
  */
 
 #include "vnc-palette.h"
+#include <glib.h>
+#include <string.h>
 
 static VncPaletteEntry *palette_find(const VncPalette *palette,
                                      uint32_t color, unsigned int hash)
commit ee9baa00f2623f1f627913f62d60f2888286319a
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Tue Oct 23 22:54:34 2012 -0200

    user: Rename qemu-types.h to qemu-user-types.h
    
    The header file is specific for *-user, but I plan to introduce a more
    generic qemu-types.h file, so I'm renaming it.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 8a5ee3d..d268899 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -11,7 +11,7 @@
 #include <stdlib.h>
 #endif /* DEBUG_REMAP */
 
-#include "qemu-types.h"
+#include "qemu-user-types.h"
 
 enum BSDType {
     target_freebsd,
diff --git a/cpu-all.h b/cpu-all.h
index c9c51b8..d6b2b19 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -180,7 +180,7 @@ static inline void tswap64s(uint64_t *s)
 
 #if defined(CONFIG_USER_ONLY)
 #include <assert.h>
-#include "qemu-types.h"
+#include "qemu-user-types.h"
 
 /* On some host systems the guest address space is reserved on the host.
  * This allows the guest address space to be offset to a convenient location.
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 5e53dca..ceddb3c 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -11,7 +11,7 @@
 #include <stdlib.h>
 #endif /* DEBUG_REMAP */
 
-#include "qemu-types.h"
+#include "qemu-user-types.h"
 
 #include "thunk.h"
 #include "syscall_defs.h"
diff --git a/qemu-types.h b/qemu-types.h
deleted file mode 100644
index fe7f662..0000000
--- a/qemu-types.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef QEMU_TYPES_H
-#define QEMU_TYPES_H
-#include "cpu.h"
-
-#ifdef TARGET_ABI32
-typedef uint32_t abi_ulong;
-typedef int32_t abi_long;
-#define TARGET_ABI_FMT_lx "%08x"
-#define TARGET_ABI_FMT_ld "%d"
-#define TARGET_ABI_FMT_lu "%u"
-#define TARGET_ABI_BITS 32
-
-static inline abi_ulong tswapal(abi_ulong v)
-{
-    return tswap32(v);
-}
-
-#else
-typedef target_ulong abi_ulong;
-typedef target_long abi_long;
-#define TARGET_ABI_FMT_lx TARGET_FMT_lx
-#define TARGET_ABI_FMT_ld TARGET_FMT_ld
-#define TARGET_ABI_FMT_lu TARGET_FMT_lu
-#define TARGET_ABI_BITS TARGET_LONG_BITS
-/* for consistency, define ABI32 too */
-#if TARGET_ABI_BITS == 32
-#define TARGET_ABI32 1
-#endif
-
-static inline abi_ulong tswapal(abi_ulong v)
-{
-    return tswapl(v);
-}
-
-#endif
-#endif
diff --git a/qemu-user-types.h b/qemu-user-types.h
new file mode 100644
index 0000000..fe7f662
--- /dev/null
+++ b/qemu-user-types.h
@@ -0,0 +1,36 @@
+#ifndef QEMU_TYPES_H
+#define QEMU_TYPES_H
+#include "cpu.h"
+
+#ifdef TARGET_ABI32
+typedef uint32_t abi_ulong;
+typedef int32_t abi_long;
+#define TARGET_ABI_FMT_lx "%08x"
+#define TARGET_ABI_FMT_ld "%d"
+#define TARGET_ABI_FMT_lu "%u"
+#define TARGET_ABI_BITS 32
+
+static inline abi_ulong tswapal(abi_ulong v)
+{
+    return tswap32(v);
+}
+
+#else
+typedef target_ulong abi_ulong;
+typedef target_long abi_long;
+#define TARGET_ABI_FMT_lx TARGET_FMT_lx
+#define TARGET_ABI_FMT_ld TARGET_FMT_ld
+#define TARGET_ABI_FMT_lu TARGET_FMT_lu
+#define TARGET_ABI_BITS TARGET_LONG_BITS
+/* for consistency, define ABI32 too */
+#if TARGET_ABI_BITS == 32
+#define TARGET_ABI32 1
+#endif
+
+static inline abi_ulong tswapal(abi_ulong v)
+{
+    return tswapl(v);
+}
+
+#endif
+#endif
commit 89e0e9c71e608f3679f30e88d988903536c6f7f3
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Tue Oct 23 20:42:56 2012 -0200

    user: Move *-user/qemu-types.h to main directory
    
    The bsd-user/qemu-types.h and linux-user/qemu-types.h files are almost
    the same, but linux-user has the additional definitions of tswapal().
    
    This moves the linux-user file to the main directory, so the same file
    can be used by linux-user and bsd-user.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/bsd-user/qemu-types.h b/bsd-user/qemu-types.h
deleted file mode 100644
index 1adda9f..0000000
--- a/bsd-user/qemu-types.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef QEMU_TYPES_H
-#define QEMU_TYPES_H
-#include "cpu.h"
-
-#ifdef TARGET_ABI32
-typedef uint32_t abi_ulong;
-typedef int32_t abi_long;
-#define TARGET_ABI_FMT_lx "%08x"
-#define TARGET_ABI_FMT_ld "%d"
-#define TARGET_ABI_FMT_lu "%u"
-#define TARGET_ABI_BITS 32
-#else
-typedef target_ulong abi_ulong;
-typedef target_long abi_long;
-#define TARGET_ABI_FMT_lx TARGET_FMT_lx
-#define TARGET_ABI_FMT_ld TARGET_FMT_ld
-#define TARGET_ABI_FMT_lu TARGET_FMT_lu
-#define TARGET_ABI_BITS TARGET_LONG_BITS
-/* for consistency, define ABI32 too */
-#if TARGET_ABI_BITS == 32
-#define TARGET_ABI32 1
-#endif
-#endif
-#endif
diff --git a/linux-user/qemu-types.h b/linux-user/qemu-types.h
deleted file mode 100644
index fe7f662..0000000
--- a/linux-user/qemu-types.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef QEMU_TYPES_H
-#define QEMU_TYPES_H
-#include "cpu.h"
-
-#ifdef TARGET_ABI32
-typedef uint32_t abi_ulong;
-typedef int32_t abi_long;
-#define TARGET_ABI_FMT_lx "%08x"
-#define TARGET_ABI_FMT_ld "%d"
-#define TARGET_ABI_FMT_lu "%u"
-#define TARGET_ABI_BITS 32
-
-static inline abi_ulong tswapal(abi_ulong v)
-{
-    return tswap32(v);
-}
-
-#else
-typedef target_ulong abi_ulong;
-typedef target_long abi_long;
-#define TARGET_ABI_FMT_lx TARGET_FMT_lx
-#define TARGET_ABI_FMT_ld TARGET_FMT_ld
-#define TARGET_ABI_FMT_lu TARGET_FMT_lu
-#define TARGET_ABI_BITS TARGET_LONG_BITS
-/* for consistency, define ABI32 too */
-#if TARGET_ABI_BITS == 32
-#define TARGET_ABI32 1
-#endif
-
-static inline abi_ulong tswapal(abi_ulong v)
-{
-    return tswapl(v);
-}
-
-#endif
-#endif
diff --git a/qemu-types.h b/qemu-types.h
new file mode 100644
index 0000000..fe7f662
--- /dev/null
+++ b/qemu-types.h
@@ -0,0 +1,36 @@
+#ifndef QEMU_TYPES_H
+#define QEMU_TYPES_H
+#include "cpu.h"
+
+#ifdef TARGET_ABI32
+typedef uint32_t abi_ulong;
+typedef int32_t abi_long;
+#define TARGET_ABI_FMT_lx "%08x"
+#define TARGET_ABI_FMT_ld "%d"
+#define TARGET_ABI_FMT_lu "%u"
+#define TARGET_ABI_BITS 32
+
+static inline abi_ulong tswapal(abi_ulong v)
+{
+    return tswap32(v);
+}
+
+#else
+typedef target_ulong abi_ulong;
+typedef target_long abi_long;
+#define TARGET_ABI_FMT_lx TARGET_FMT_lx
+#define TARGET_ABI_FMT_ld TARGET_FMT_ld
+#define TARGET_ABI_FMT_lu TARGET_FMT_lu
+#define TARGET_ABI_BITS TARGET_LONG_BITS
+/* for consistency, define ABI32 too */
+#if TARGET_ABI_BITS == 32
+#define TARGET_ABI32 1
+#endif
+
+static inline abi_ulong tswapal(abi_ulong v)
+{
+    return tswapl(v);
+}
+
+#endif
+#endif
commit 19e6c50d2d843220efbdd3b2db21d83c122c364a
Author: Petar Jovanovic <petarj at mips.com>
Date:   Wed Dec 5 00:29:10 2012 +0100

    target-mips: Fix incorrect shift for SHILO and SHILOV
    
    helper_shilo has not been shifting an accumulator value correctly for negative
    values in 'shift' field. Minor optimization for shift=0 case.
    This change also adds tests that will trigger issue and check for regressions.
    
    Signed-off-by: Petar Jovanovic <petarj at mips.com>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Eric Johnson <ericj at mips.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index fda5f04..14daf91 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -3814,17 +3814,18 @@ void helper_shilo(target_ulong ac, target_ulong rs, CPUMIPSState *env)
 
     rs5_0 = rs & 0x3F;
     rs5_0 = (int8_t)(rs5_0 << 2) >> 2;
-    rs5_0 = MIPSDSP_ABS(rs5_0);
+
+    if (unlikely(rs5_0 == 0)) {
+        return;
+    }
+
     acc   = (((uint64_t)env->active_tc.HI[ac] << 32) & MIPSDSP_LHI) |
             ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
-    if (rs5_0 == 0) {
-        temp = acc;
+
+    if (rs5_0 > 0) {
+        temp = acc >> rs5_0;
     } else {
-        if (rs5_0 > 0) {
-            temp = acc >> rs5_0;
-        } else {
-            temp = acc << rs5_0;
-        }
+        temp = acc << -rs5_0;
     }
 
     env->active_tc.HI[ac] = (target_ulong)(int32_t)((temp & MIPSDSP_LHI) >> 32);
diff --git a/tests/tcg/mips/mips32-dsp/shilo.c b/tests/tcg/mips/mips32-dsp/shilo.c
index b686616..ce8ebc6 100644
--- a/tests/tcg/mips/mips32-dsp/shilo.c
+++ b/tests/tcg/mips/mips32-dsp/shilo.c
@@ -23,5 +23,23 @@ int main()
     assert(ach == resulth);
     assert(acl == resultl);
 
+
+    ach = 0x1;
+    acl = 0x80000000;
+
+    resulth = 0x3;
+    resultl = 0x0;
+
+    __asm
+        ("mthi %0, $ac1\n\t"
+         "mtlo %1, $ac1\n\t"
+         "shilo $ac1, -1\n\t"
+         "mfhi %0, $ac1\n\t"
+         "mflo %1, $ac1\n\t"
+         : "+r"(ach), "+r"(acl)
+        );
+    assert(ach == resulth);
+    assert(acl == resultl);
+
     return 0;
 }
diff --git a/tests/tcg/mips/mips32-dsp/shilov.c b/tests/tcg/mips/mips32-dsp/shilov.c
index f186032..e1d6cea 100644
--- a/tests/tcg/mips/mips32-dsp/shilov.c
+++ b/tests/tcg/mips/mips32-dsp/shilov.c
@@ -25,5 +25,25 @@ int main()
     assert(ach == resulth);
     assert(acl == resultl);
 
+
+    rs  = 0xffffffff;
+    ach = 0x1;
+    acl = 0x80000000;
+
+    resulth = 0x3;
+    resultl = 0x0;
+
+    __asm
+        ("mthi %0, $ac1\n\t"
+         "mtlo %1, $ac1\n\t"
+         "shilov $ac1, %2\n\t"
+         "mfhi %0, $ac1\n\t"
+         "mflo %1, $ac1\n\t"
+         : "+r"(ach), "+r"(acl)
+         : "r"(rs)
+        );
+    assert(ach == resulth);
+    assert(acl == resultl);
+
     return 0;
 }
commit 34f5606ee101f82a247d09d05644ad2a63c8e342
Author: Petar Jovanovic <petarj at mips.com>
Date:   Mon Nov 26 16:13:21 2012 +0100

    target-mips: Fix incorrect code and test for INSV
    
    Content of register rs should be shifted for pos before applying a mask.
    This change contains both fix for the instruction and to the existing test.
    
    Signed-off-by: Petar Jovanovic <petarj at mips.com>
    Reviewed-by: Eric Johnson <ericj at mips.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index e7949c2..fda5f04 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -3152,7 +3152,7 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong rs,  \
                                                                 \
     filter = ((int32_t)0x01 << size) - 1;                       \
     filter = filter << pos;                                     \
-    temprs = rs & filter;                                       \
+    temprs = (rs << pos) & filter;                              \
     temprt = rt & ~filter;                                      \
     temp = temprs | temprt;                                     \
                                                                 \
diff --git a/tests/tcg/mips/mips32-dsp/insv.c b/tests/tcg/mips/mips32-dsp/insv.c
index 7e3b047..243b007 100644
--- a/tests/tcg/mips/mips32-dsp/insv.c
+++ b/tests/tcg/mips/mips32-dsp/insv.c
@@ -10,7 +10,7 @@ int main()
     dsp    = 0x305;
     rt     = 0x12345678;
     rs     = 0x87654321;
-    result = 0x12345338;
+    result = 0x12345438;
     __asm
         ("wrdsp %2, 0x03\n\t"
          "insv  %0, %1\n\t"
commit 9fd2ecdc8cb2dc1a8a7c57b6c9c60bc9947b6a73
Author: Paolo Bonzini <pbonini at redhat.com>
Date:   Thu Oct 11 14:20:23 2012 +0200

    virtfs-proxy-helper: use setresuid and setresgid
    
    The setfsuid and setfsgid system calls are obscure and they complicate
    the error checking (that glibc's warn_unused_result "feature" forces
    us to do).  Switch to the standard setresuid and setresgid functions.
    
    Signed-off-by: Paolo Bonzini <pbonini at redhat.com
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c
index f9a8270..df2a939 100644
--- a/fsdev/virtfs-proxy-helper.c
+++ b/fsdev/virtfs-proxy-helper.c
@@ -272,31 +272,76 @@ static int send_status(int sockfd, struct iovec *iovec, int status)
 /*
  * from man 7 capabilities, section
  * Effect of User ID Changes on Capabilities:
- * 4. If the file system user ID is changed from 0 to nonzero (see setfsuid(2))
- * then the following capabilities are cleared from the effective set:
- * CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH,  CAP_FOWNER, CAP_FSETID,
- * CAP_LINUX_IMMUTABLE  (since  Linux 2.2.30), CAP_MAC_OVERRIDE, and CAP_MKNOD
- * (since Linux 2.2.30). If the file system UID is changed from nonzero to 0,
- * then any of these capabilities that are enabled in the permitted set
- * are enabled in the effective set.
+ * If the effective user ID is changed from nonzero to 0, then the permitted
+ * set is copied to the effective set.  If the effective user ID is changed
+ * from 0 to nonzero, then all capabilities are are cleared from the effective
+ * set.
+ *
+ * The setfsuid/setfsgid man pages warn that changing the effective user ID may
+ * expose the program to unwanted signals, but this is not true anymore: for an
+ * unprivileged (without CAP_KILL) program to send a signal, the real or
+ * effective user ID of the sending process must equal the real or saved user
+ * ID of the target process.  Even when dropping privileges, it is enough to
+ * keep the saved UID to a "privileged" value and virtfs-proxy-helper won't
+ * be exposed to signals.  So just use setresuid/setresgid.
  */
-static int setfsugid(int uid, int gid)
+static int setugid(int uid, int gid, int *suid, int *sgid)
 {
+    int retval;
+
     /*
-     * We still need DAC_OVERRIDE because  we don't change
+     * We still need DAC_OVERRIDE because we don't change
      * supplementary group ids, and hence may be subjected DAC rules
      */
     cap_value_t cap_list[] = {
         CAP_DAC_OVERRIDE,
     };
 
-    setfsgid(gid);
-    setfsuid(uid);
+    *suid = geteuid();
+    *sgid = getegid();
+
+    if (setresgid(-1, gid, *sgid) == -1) {
+        retval = -errno;
+        goto err_out;
+    }
+
+    if (setresuid(-1, uid, *suid) == -1) {
+        retval = -errno;
+        goto err_sgid;
+    }
 
     if (uid != 0 || gid != 0) {
-        return do_cap_set(cap_list, ARRAY_SIZE(cap_list), 0);
+        if (do_cap_set(cap_list, ARRAY_SIZE(cap_list), 0) < 0) {
+            retval = -errno;
+            goto err_suid;
+        }
     }
     return 0;
+
+err_suid:
+    if (setresuid(-1, *suid, *suid) == -1) {
+        abort();
+    }
+err_sgid:
+    if (setresgid(-1, *sgid, *sgid) == -1) {
+        abort();
+    }
+err_out:
+    return retval;
+}
+
+/*
+ * This is used to reset the ugid back with the saved values
+ * There is nothing much we can do checking error values here.
+ */
+static void resetugid(int suid, int sgid)
+{
+    if (setresgid(-1, sgid, sgid) == -1) {
+        abort();
+    }
+    if (setresuid(-1, suid, suid) == -1) {
+        abort();
+    }
 }
 
 /*
@@ -578,18 +623,15 @@ static int do_create_others(int type, struct iovec *iovec)
 
     v9fs_string_init(&path);
     v9fs_string_init(&oldpath);
-    cur_uid = geteuid();
-    cur_gid = getegid();
 
     retval = proxy_unmarshal(iovec, offset, "dd", &uid, &gid);
     if (retval < 0) {
         return retval;
     }
     offset += retval;
-    retval = setfsugid(uid, gid);
+    retval = setugid(uid, gid, &cur_uid, &cur_gid);
     if (retval < 0) {
-        retval = -errno;
-        goto err_out;
+        goto unmarshal_err_out;
     }
     switch (type) {
     case T_MKNOD:
@@ -619,9 +661,10 @@ static int do_create_others(int type, struct iovec *iovec)
     }
 
 err_out:
+    resetugid(cur_uid, cur_gid);
+unmarshal_err_out:
     v9fs_string_free(&path);
     v9fs_string_free(&oldpath);
-    setfsugid(cur_uid, cur_gid);
     return retval;
 }
 
@@ -641,24 +684,16 @@ static int do_create(struct iovec *iovec)
     if (ret < 0) {
         goto unmarshal_err_out;
     }
-    cur_uid = geteuid();
-    cur_gid = getegid();
-    ret = setfsugid(uid, gid);
+    ret = setugid(uid, gid, &cur_uid, &cur_gid);
     if (ret < 0) {
-        /*
-         * On failure reset back to the
-         * old uid/gid
-         */
-        ret = -errno;
-        goto err_out;
+        goto unmarshal_err_out;
     }
     ret = open(path.data, flags, mode);
     if (ret < 0) {
         ret = -errno;
     }
 
-err_out:
-    setfsugid(cur_uid, cur_gid);
+    resetugid(cur_uid, cur_gid);
 unmarshal_err_out:
     v9fs_string_free(&path);
     return ret;
commit 80625b97b52836b944a6438e8e3e9d992e6a00b6
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Wed Dec 5 16:53:44 2012 +1000

    xilinx_uartlite: Accept input after rx FIFO pop
    
    The device return false from the can receive function when the FIFO is
    full. This mean the device should check for buffered input whenever a byte is
    popped from the FIFO.
    
    Reported-by: Jason Wu <huanyu 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_uartlite.c b/hw/xilinx_uartlite.c
index f890f23..02c5850 100644
--- a/hw/xilinx_uartlite.c
+++ b/hw/xilinx_uartlite.c
@@ -97,6 +97,7 @@ uart_read(void *opaque, hwaddr addr, unsigned int size)
                 s->rx_fifo_len--;
             uart_update_status(s);
             uart_update_irq(s);
+            qemu_chr_accept_input(s->chr);
             break;
 
         default:
commit 859cc10d23e619153670fc58683373fa24d25b68
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Wed Dec 5 16:53:43 2012 +1000

    xilinx_uartlite: suppress "cannot receive message"
    
    This message is not an error condition, its just informing the user that
    the device is corking the uart traffic to not drop characters.
    
    Reported-by: Jason Wu <huanyu 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_uartlite.c b/hw/xilinx_uartlite.c
index d20fc41..f890f23 100644
--- a/hw/xilinx_uartlite.c
+++ b/hw/xilinx_uartlite.c
@@ -182,12 +182,8 @@ static void uart_rx(void *opaque, const uint8_t *buf, int size)
 static int uart_can_rx(void *opaque)
 {
     struct xlx_uartlite *s = opaque;
-    int r;
 
-    r = s->rx_fifo_len < sizeof(s->rx_fifo);
-    if (!r)
-        printf("cannot receive!\n");
-    return r;
+    return s->rx_fifo_len < sizeof(s->rx_fifo);
 }
 
 static void uart_event(void *opaque, int event)
commit d4d230da08918183929c7d6cb54824b391536904
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Wed Dec 5 16:53:42 2012 +1000

    xilinx_axienet: Implement R_IS behaviour
    
    The interrupt status register R_IS is the standard clear-on-write behaviour.
    This was unimplemented and defaulting to updating the register to the written
    value. Implemented clear-on-write.
    
    Reported-by: Jason Wu <huanyu 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_axienet.c b/hw/xilinx_axienet.c
index baae02b..f2e3bf1 100644
--- a/hw/xilinx_axienet.c
+++ b/hw/xilinx_axienet.c
@@ -591,6 +591,10 @@ static void enet_write(void *opaque, hwaddr addr,
             s->maddr[s->fmi & 3][addr & 1] = value;
             break;
 
+        case R_IS:
+            s->regs[addr] &= ~value;
+            break;
+
         case 0x8000 ... 0x83ff:
             s->ext_mtable[addr - 0x8000] = value;
             break;
commit 582299336879504353e60c7937fbc70fea93f3da
Author: Julien Grall <julien.grall at citrix.com>
Date:   Wed Sep 19 12:50:09 2012 +0100

    hw/dma.c: Replace register_ioport_*
    
    Replace all register_ioport_*() with the new Memory API functions.
    This permits to use the new Memory stuff like listeners.
    
    Signed-off-by: Julien Grall <julien.grall at citrix.com>
    Acked-by: Avi Kivity <avi at redhat.com>
    [AF: Rebased onto hwaddr]
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/dma.c b/hw/dma.c
index d6aeac2..c2d7b21 100644
--- a/hw/dma.c
+++ b/hw/dma.c
@@ -58,6 +58,8 @@ static struct dma_cont {
     int dshift;
     struct dma_regs regs[4];
     qemu_irq *cpu_request_exit;
+    MemoryRegion channel_io;
+    MemoryRegion cont_io;
 } dma_controllers[2];
 
 enum {
@@ -149,7 +151,7 @@ static inline int getff (struct dma_cont *d)
     return ff;
 }
 
-static uint32_t read_chan (void *opaque, uint32_t nport)
+static uint64_t read_chan(void *opaque, hwaddr nport, unsigned size)
 {
     struct dma_cont *d = opaque;
     int ichan, nreg, iport, ff, val, dir;
@@ -171,7 +173,8 @@ static uint32_t read_chan (void *opaque, uint32_t nport)
     return (val >> (d->dshift + (ff << 3))) & 0xff;
 }
 
-static void write_chan (void *opaque, uint32_t nport, uint32_t data)
+static void write_chan(void *opaque, hwaddr nport, uint64_t data,
+                       unsigned size)
 {
     struct dma_cont *d = opaque;
     int iport, ichan, nreg;
@@ -189,22 +192,23 @@ static void write_chan (void *opaque, uint32_t nport, uint32_t data)
     }
 }
 
-static void write_cont (void *opaque, uint32_t nport, uint32_t data)
+static void write_cont(void *opaque, hwaddr nport, uint64_t data,
+                       unsigned size)
 {
     struct dma_cont *d = opaque;
     int iport, ichan = 0;
 
     iport = (nport >> d->dshift) & 0x0f;
     switch (iport) {
-    case 0x08:                  /* command */
+    case 0x01:                  /* command */
         if ((data != 0) && (data & CMD_NOT_SUPPORTED)) {
-            dolog ("command %#x not supported\n", data);
+            dolog("command %"PRIx64" not supported\n", data);
             return;
         }
         d->command = data;
         break;
 
-    case 0x09:
+    case 0x02:
         ichan = data & 3;
         if (data & 4) {
             d->status |= 1 << (ichan + 4);
@@ -216,7 +220,7 @@ static void write_cont (void *opaque, uint32_t nport, uint32_t data)
         DMA_run();
         break;
 
-    case 0x0a:                  /* single mask */
+    case 0x03:                  /* single mask */
         if (data & 4)
             d->mask |= 1 << (data & 3);
         else
@@ -224,7 +228,7 @@ static void write_cont (void *opaque, uint32_t nport, uint32_t data)
         DMA_run();
         break;
 
-    case 0x0b:                  /* mode */
+    case 0x04:                  /* mode */
         {
             ichan = data & 3;
 #ifdef DEBUG_DMA
@@ -243,23 +247,23 @@ static void write_cont (void *opaque, uint32_t nport, uint32_t data)
             break;
         }
 
-    case 0x0c:                  /* clear flip flop */
+    case 0x05:                  /* clear flip flop */
         d->flip_flop = 0;
         break;
 
-    case 0x0d:                  /* reset */
+    case 0x06:                  /* reset */
         d->flip_flop = 0;
         d->mask = ~0;
         d->status = 0;
         d->command = 0;
         break;
 
-    case 0x0e:                  /* clear mask for all channels */
+    case 0x07:                  /* clear mask for all channels */
         d->mask = 0;
         DMA_run();
         break;
 
-    case 0x0f:                  /* write mask for all channels */
+    case 0x08:                  /* write mask for all channels */
         d->mask = data;
         DMA_run();
         break;
@@ -277,7 +281,7 @@ static void write_cont (void *opaque, uint32_t nport, uint32_t data)
 #endif
 }
 
-static uint32_t read_cont (void *opaque, uint32_t nport)
+static uint64_t read_cont(void *opaque, hwaddr nport, unsigned size)
 {
     struct dma_cont *d = opaque;
     int iport, val;
@@ -463,7 +467,7 @@ void DMA_schedule(int nchan)
 static void dma_reset(void *opaque)
 {
     struct dma_cont *d = opaque;
-    write_cont (d, (0x0d << d->dshift), 0);
+    write_cont(d, (0x06 << d->dshift), 0, 1);
 }
 
 static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len)
@@ -473,38 +477,68 @@ static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len)
     return dma_pos;
 }
 
+
+static const MemoryRegionOps channel_io_ops = {
+    .read = read_chan,
+    .write = write_chan,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
+/* IOport from page_base */
+static const MemoryRegionPortio page_portio_list[] = {
+    { 0x01, 3, 1, .write = write_page, .read = read_page, },
+    { 0x07, 1, 1, .write = write_page, .read = read_page, },
+    PORTIO_END_OF_LIST(),
+};
+
+/* IOport from pageh_base */
+static const MemoryRegionPortio pageh_portio_list[] = {
+    { 0x01, 3, 1, .write = write_pageh, .read = read_pageh, },
+    { 0x07, 3, 1, .write = write_pageh, .read = read_pageh, },
+    PORTIO_END_OF_LIST(),
+};
+
+static const MemoryRegionOps cont_io_ops = {
+    .read = read_cont,
+    .write = write_cont,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
 /* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */
 static void dma_init2(struct dma_cont *d, int base, int dshift,
                       int page_base, int pageh_base,
                       qemu_irq *cpu_request_exit)
 {
-    static const int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 };
     int i;
 
     d->dshift = dshift;
     d->cpu_request_exit = cpu_request_exit;
-    for (i = 0; i < 8; i++) {
-        register_ioport_write (base + (i << dshift), 1, 1, write_chan, d);
-        register_ioport_read (base + (i << dshift), 1, 1, read_chan, d);
-    }
-    for (i = 0; i < ARRAY_SIZE (page_port_list); i++) {
-        register_ioport_write (page_base + page_port_list[i], 1, 1,
-                               write_page, d);
-        register_ioport_read (page_base + page_port_list[i], 1, 1,
-                              read_page, d);
-        if (pageh_base >= 0) {
-            register_ioport_write (pageh_base + page_port_list[i], 1, 1,
-                                   write_pageh, d);
-            register_ioport_read (pageh_base + page_port_list[i], 1, 1,
-                                  read_pageh, d);
-        }
-    }
-    for (i = 0; i < 8; i++) {
-        register_ioport_write (base + ((i + 8) << dshift), 1, 1,
-                               write_cont, d);
-        register_ioport_read (base + ((i + 8) << dshift), 1, 1,
-                              read_cont, d);
+
+    memory_region_init_io(&d->channel_io, &channel_io_ops, d,
+                          "dma-chan", 8 << d->dshift);
+    memory_region_add_subregion(isa_address_space_io(NULL),
+                                base, &d->channel_io);
+
+    isa_register_portio_list(NULL, page_base, page_portio_list, d,
+                             "dma-page");
+    if (pageh_base >= 0) {
+        isa_register_portio_list(NULL, pageh_base, pageh_portio_list, d,
+                                 "dma-pageh");
     }
+
+    memory_region_init_io(&d->cont_io, &cont_io_ops, d, "dma-cont",
+                          8 << d->dshift);
+    memory_region_add_subregion(isa_address_space_io(NULL),
+                                base + (8 << d->dshift), &d->cont_io);
+
     qemu_register_reset(dma_reset, d);
     dma_reset(d);
     for (i = 0; i < ARRAY_SIZE (d->regs); ++i) {
commit 258711c6448c44b60b0fecef1d3b09c71e23e304
Author: Julien Grall <julien.grall at citrix.com>
Date:   Wed Sep 19 12:50:08 2012 +0100

    hw/pc.c: Replace register_ioport_*
    
    Replace all register_ioport_*() with portio_*() or a MemoryRegion.
    This permits to use the new Memory stuff like listeners.
    
    Signed-off-by: Julien Grall <julien.grall at citrix.com>
    Acked-by: Avi Kivity <avi at redhat.com>
    [AF: Rebased onto hwaddr]
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/pc.c b/hw/pc.c
index 2b5bbbf..b11e7c4 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -98,7 +98,8 @@ void gsi_handler(void *opaque, int n, int level)
     qemu_set_irq(s->ioapic_irq[n], level);
 }
 
-static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
+static void ioport80_write(void *opaque, hwaddr addr, uint64_t data,
+                           unsigned size)
 {
 }
 
@@ -116,7 +117,8 @@ void cpu_set_ferr(CPUX86State *s)
     qemu_irq_raise(ferr_irq);
 }
 
-static void ioportF0_write(void *opaque, uint32_t addr, uint32_t data)
+static void ioportF0_write(void *opaque, hwaddr addr, uint64_t data,
+                           unsigned size)
 {
     qemu_irq_lower(ferr_irq);
 }
@@ -567,6 +569,14 @@ int e820_add_entry(uint64_t address, uint64_t length, uint32_t type)
     return index;
 }
 
+static const MemoryRegionPortio bochs_bios_portio_list[] = {
+    { 0x500, 1, 1, .write = bochs_bios_write, }, /* 0x500 */
+    { 0x501, 1, 1, .write = bochs_bios_write, }, /* 0x501 */
+    { 0x501, 2, 2, .write = bochs_bios_write, }, /* 0x501 */
+    { 0x8900, 1, 1, .write = bochs_bios_write, }, /* 0x8900 */
+    PORTIO_END_OF_LIST(),
+};
+
 static void *bochs_bios_init(void)
 {
     void *fw_cfg;
@@ -574,12 +584,11 @@ static void *bochs_bios_init(void)
     size_t smbios_len;
     uint64_t *numa_fw_cfg;
     int i, j;
+    PortioList *bochs_bios_port_list = g_new(PortioList, 1);
 
-    register_ioport_write(0x8900, 1, 1, bochs_bios_write, NULL);
-
-    register_ioport_write(0x501, 1, 1, bochs_bios_write, NULL);
-    register_ioport_write(0x501, 1, 2, bochs_bios_write, NULL);
-    register_ioport_write(0x502, 1, 2, bochs_bios_write, NULL);
+    portio_list_init(bochs_bios_port_list, bochs_bios_portio_list,
+                     NULL, "bochs-bios");
+    portio_list_add(bochs_bios_port_list, get_system_io(), 0x0);
 
     fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0);
 
@@ -967,6 +976,24 @@ static void cpu_request_exit(void *opaque, int irq, int level)
     }
 }
 
+static const MemoryRegionOps ioport80_io_ops = {
+    .write = ioport80_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
+static const MemoryRegionOps ioportF0_io_ops = {
+    .write = ioportF0_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
 void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
                           ISADevice **rtc_state,
                           ISADevice **floppy,
@@ -981,10 +1008,14 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
     qemu_irq *a20_line;
     ISADevice *i8042, *port92, *vmmouse, *pit = NULL;
     qemu_irq *cpu_exit_irq;
+    MemoryRegion *ioport80_io = g_new(MemoryRegion, 1);
+    MemoryRegion *ioportF0_io = g_new(MemoryRegion, 1);
 
-    register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
+    memory_region_init_io(ioport80_io, &ioport80_io_ops, NULL, "ioport80", 1);
+    memory_region_add_subregion(isa_bus->address_space_io, 0x80, ioport80_io);
 
-    register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);
+    memory_region_init_io(ioportF0_io, &ioportF0_io_ops, NULL, "ioportF0", 1);
+    memory_region_add_subregion(isa_bus->address_space_io, 0xf0, ioportF0_io);
 
     /*
      * Check if an HPET shall be created.
commit 568fd159e4ca82d213706acd2cf4c94f27537096
Author: Julien Grall <julien.grall at citrix.com>
Date:   Wed Sep 19 12:50:07 2012 +0100

    serial: Replace register_ioport_*
    
    Replace all register_ioport_*() with a MemoryRegion.
    This permits to use the new Memory stuff like listeners.
    
    For more flexibility, the IO address space is passed as an argument.
    
    Signed-off-by: Julien Grall <julien.grall at citrix.com>
    Acked-by: Avi Kivity <avi at redhat.com>
    [AF: Rebased onto serial split]
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c
index a95a3c1..20b5f1a 100644
--- a/hw/mips_mipssim.c
+++ b/hw/mips_mipssim.c
@@ -217,7 +217,8 @@ mips_mipssim_init(QEMUMachineInitArgs *args)
     /* A single 16450 sits at offset 0x3f8. It is attached to
        MIPS CPU INT2, which is interrupt 4. */
     if (serial_hds[0])
-        serial_init(0x3f8, env->irq[4], 115200, serial_hds[0]);
+        serial_init(0x3f8, env->irq[4], 115200, serial_hds[0],
+                    get_system_io());
 
     if (nd_table[0].used)
         /* MIPSnet uses the MIPS CPU INT0, which is interrupt 2. */
diff --git a/hw/serial.c b/hw/serial.c
index 60283ea..07a2a11 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -718,7 +718,7 @@ const MemoryRegionOps serial_io_ops = {
 };
 
 SerialState *serial_init(int base, qemu_irq irq, int baudbase,
-                         CharDriverState *chr)
+                         CharDriverState *chr, MemoryRegion *system_io)
 {
     SerialState *s;
 
@@ -732,7 +732,7 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
     vmstate_register(NULL, base, &vmstate_serial, s);
 
     memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8);
-    memory_region_add_subregion(get_system_io(), base, &s->io);
+    memory_region_add_subregion(system_io, base, &s->io);
 
     return s;
 }
diff --git a/hw/serial.h b/hw/serial.h
index f1e3c4a..ed1a5cd 100644
--- a/hw/serial.h
+++ b/hw/serial.h
@@ -89,7 +89,7 @@ void serial_set_frequency(SerialState *s, uint32_t frequency);
 
 /* legacy pre qom */
 SerialState *serial_init(int base, qemu_irq irq, int baudbase,
-                         CharDriverState *chr);
+                         CharDriverState *chr, MemoryRegion *system_io);
 SerialState *serial_mm_init(MemoryRegion *address_space,
                             hwaddr base, int it_shift,
                             qemu_irq irq, int baudbase,
commit c75e6d8e354c44e76045cb0de20cda1a4ce4d575
Author: Julien Grall <julien.grall at citrix.com>
Date:   Wed Sep 19 12:50:06 2012 +0100

    hw/cirrus_vga.c: Replace register_ioport_*
    
    Replace all register_ioport_*() with the new Memory API.
    This permits to use the new Memory stuff like listeners.
    
    Signed-off-by: Julien Grall <julien.grall at citrix.com>
    Acked-by: Avi Kivity <avi at redhat.com>
    [AF: Rebased onto hwaddr]
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 9bef96e..40efa8a 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -197,6 +197,7 @@ typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
 typedef struct CirrusVGAState {
     VGACommonState vga;
 
+    MemoryRegion cirrus_vga_io;
     MemoryRegion cirrus_linear_io;
     MemoryRegion cirrus_linear_bitblt_io;
     MemoryRegion cirrus_mmio_io;
@@ -2432,13 +2433,15 @@ static void cirrus_update_memory_access(CirrusVGAState *s)
 
 /* I/O ports */
 
-static uint32_t cirrus_vga_ioport_read(void *opaque, uint32_t addr)
+static uint64_t cirrus_vga_ioport_read(void *opaque, hwaddr addr,
+                                       unsigned size)
 {
     CirrusVGAState *c = opaque;
     VGACommonState *s = &c->vga;
     int val, index;
 
     qemu_flush_coalesced_mmio_buffer();
+    addr += 0x3b0;
 
     if (vga_ioport_invalid(s, addr)) {
 	val = 0xff;
@@ -2527,13 +2530,15 @@ static uint32_t cirrus_vga_ioport_read(void *opaque, uint32_t addr)
     return val;
 }
 
-static void cirrus_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val,
+                                    unsigned size)
 {
     CirrusVGAState *c = opaque;
     VGACommonState *s = &c->vga;
     int index;
 
     qemu_flush_coalesced_mmio_buffer();
+    addr += 0x3b0;
 
     /* check port range access depending on color/monochrome mode */
     if (vga_ioport_invalid(s, addr)) {
@@ -2646,7 +2651,7 @@ static uint64_t cirrus_mmio_read(void *opaque, hwaddr addr,
     if (addr >= 0x100) {
         return cirrus_mmio_blt_read(s, addr - 0x100);
     } else {
-        return cirrus_vga_ioport_read(s, addr + 0x3c0);
+        return cirrus_vga_ioport_read(s, addr + 0x10, size);
     }
 }
 
@@ -2658,7 +2663,7 @@ static void cirrus_mmio_write(void *opaque, hwaddr addr,
     if (addr >= 0x100) {
 	cirrus_mmio_blt_write(s, addr - 0x100, val);
     } else {
-        cirrus_vga_ioport_write(s, addr + 0x3c0, val);
+        cirrus_vga_ioport_write(s, addr + 0x10, val, size);
     }
 }
 
@@ -2784,8 +2789,19 @@ static const MemoryRegionOps cirrus_linear_io_ops = {
     },
 };
 
+static const MemoryRegionOps cirrus_vga_io_ops = {
+    .read = cirrus_vga_ioport_read,
+    .write = cirrus_vga_ioport_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
 static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci,
-                               MemoryRegion *system_memory)
+                               MemoryRegion *system_memory,
+                               MemoryRegion *system_io)
 {
     int i;
     static int inited;
@@ -2817,19 +2833,10 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci,
             s->bustype = CIRRUS_BUSTYPE_ISA;
     }
 
-    register_ioport_write(0x3c0, 16, 1, cirrus_vga_ioport_write, s);
-
-    register_ioport_write(0x3b4, 2, 1, cirrus_vga_ioport_write, s);
-    register_ioport_write(0x3d4, 2, 1, cirrus_vga_ioport_write, s);
-    register_ioport_write(0x3ba, 1, 1, cirrus_vga_ioport_write, s);
-    register_ioport_write(0x3da, 1, 1, cirrus_vga_ioport_write, s);
-
-    register_ioport_read(0x3c0, 16, 1, cirrus_vga_ioport_read, s);
-
-    register_ioport_read(0x3b4, 2, 1, cirrus_vga_ioport_read, s);
-    register_ioport_read(0x3d4, 2, 1, cirrus_vga_ioport_read, s);
-    register_ioport_read(0x3ba, 1, 1, cirrus_vga_ioport_read, s);
-    register_ioport_read(0x3da, 1, 1, cirrus_vga_ioport_read, s);
+    /* Register ioport 0x3b0 - 0x3df */
+    memory_region_init_io(&s->cirrus_vga_io, &cirrus_vga_io_ops, s,
+                          "cirrus-io", 0x30);
+    memory_region_add_subregion(system_io, 0x3b0, &s->cirrus_vga_io);
 
     memory_region_init(&s->low_mem_container,
                        "cirrus-lowmem-container",
@@ -2900,7 +2907,7 @@ static int vga_initfn(ISADevice *dev)
 
     vga_common_init(s);
     cirrus_init_common(&d->cirrus_vga, CIRRUS_ID_CLGD5430, 0,
-                       isa_address_space(dev));
+                       isa_address_space(dev), isa_address_space_io(dev));
     s->ds = graphic_console_init(s->update, s->invalidate,
                                  s->screen_dump, s->text_update,
                                  s);
@@ -2948,7 +2955,8 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
 
      /* setup VGA */
      vga_common_init(&s->vga);
-     cirrus_init_common(s, device_id, 1, pci_address_space(dev));
+     cirrus_init_common(s, device_id, 1, pci_address_space(dev),
+                        pci_address_space_io(dev));
      s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate,
                                       s->vga.screen_dump, s->vga.text_update,
                                       &s->vga);
commit 42d8a3cf960659069bd2b2d9c443dafd7585607f
Author: Julien Grall <julien.grall at citrix.com>
Date:   Wed Sep 19 12:50:03 2012 +0100

    hw/apm.c: Replace register_ioport_*
    
    Replace all register_ioport_*() with a MemoryRegion.
    This permits to use the new Memory stuff like listeners.
    
    Moreover, the PCI device is added as an argument for apm_init(),
    so we can register IO inside the PCI IO address space.
    
    Signed-off-by: Julien Grall <julien.grall at citrix.com>
    Acked-by: Avi Kivity <avi at redhat.com>
    [AF: Rebased onto hwaddr and q35]
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 519269a..dbddde1 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -438,7 +438,7 @@ static int piix4_pm_initfn(PCIDevice *dev)
     pci_conf[0x3d] = 0x01; // interrupt pin 1
 
     /* APM */
-    apm_init(&s->apm, apm_ctrl_changed, s);
+    apm_init(dev, &s->apm, apm_ctrl_changed, s);
 
     register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s);
 
diff --git a/hw/apm.c b/hw/apm.c
index 2aead52..e988ad9 100644
--- a/hw/apm.c
+++ b/hw/apm.c
@@ -22,6 +22,7 @@
 
 #include "apm.h"
 #include "hw.h"
+#include "pci.h"
 
 //#define DEBUG
 
@@ -35,7 +36,8 @@
 #define APM_CNT_IOPORT  0xb2
 #define APM_STS_IOPORT  0xb3
 
-static void apm_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+static void apm_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
+                              unsigned size)
 {
     APMState *apm = opaque;
     addr &= 1;
@@ -51,7 +53,7 @@ static void apm_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
-static uint32_t apm_ioport_readb(void *opaque, uint32_t addr)
+static uint64_t apm_ioport_readb(void *opaque, hwaddr addr, unsigned size)
 {
     APMState *apm = opaque;
     uint32_t val;
@@ -78,12 +80,23 @@ const VMStateDescription vmstate_apm = {
     }
 };
 
-void apm_init(APMState *apm, apm_ctrl_changed_t callback, void *arg)
+static const MemoryRegionOps apm_ops = {
+    .read = apm_ioport_readb,
+    .write = apm_ioport_writeb,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
+void apm_init(PCIDevice *dev, APMState *apm, apm_ctrl_changed_t callback,
+              void *arg)
 {
     apm->callback = callback;
     apm->arg = arg;
 
     /* ioport 0xb2, 0xb3 */
-    register_ioport_write(APM_CNT_IOPORT, 2, 1, apm_ioport_writeb, apm);
-    register_ioport_read(APM_CNT_IOPORT, 2, 1, apm_ioport_readb, apm);
+    memory_region_init_io(&apm->io, &apm_ops, apm, "apm-io", 2);
+    memory_region_add_subregion(pci_address_space_io(dev), APM_CNT_IOPORT,
+                                &apm->io);
 }
diff --git a/hw/apm.h b/hw/apm.h
index f7c741e..5431b6d 100644
--- a/hw/apm.h
+++ b/hw/apm.h
@@ -4,6 +4,7 @@
 #include <stdint.h>
 #include "qemu-common.h"
 #include "hw.h"
+#include "memory.h"
 
 typedef void (*apm_ctrl_changed_t)(uint32_t val, void *arg);
 
@@ -13,9 +14,11 @@ typedef struct APMState {
 
     apm_ctrl_changed_t callback;
     void *arg;
+    MemoryRegion io;
 } APMState;
 
-void apm_init(APMState *s, apm_ctrl_changed_t callback, void *arg);
+void apm_init(PCIDevice *dev, APMState *s, apm_ctrl_changed_t callback,
+              void *arg);
 
 extern const VMStateDescription vmstate_apm;
 
diff --git a/hw/lpc_ich9.c b/hw/lpc_ich9.c
index 2fc83a4..7de5427 100644
--- a/hw/lpc_ich9.c
+++ b/hw/lpc_ich9.c
@@ -472,7 +472,7 @@ static int ich9_lpc_initfn(PCIDevice *d)
     lpc->isa_bus = isa_bus;
 
     ich9_cc_init(lpc);
-    apm_init(&lpc->apm, ich9_apm_ctrl_changed, lpc);
+    apm_init(d, &lpc->apm, ich9_apm_ctrl_changed, lpc);
     return 0;
 }
 
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 5d7c00c..7f11dbe 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -427,7 +427,7 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
     register_ioport_write(s->smb_io_base, 0xf, 1, smb_ioport_writeb, &s->smb);
     register_ioport_read(s->smb_io_base, 0xf, 1, smb_ioport_readb, &s->smb);
 
-    apm_init(&s->apm, NULL, s);
+    apm_init(dev, &s->apm, NULL, s);
 
     acpi_pm_tmr_init(&s->ar, pm_tmr_timer);
     acpi_pm1_cnt_init(&s->ar);
commit ac10027327e27c9b360452e01af3ef2147f5a26f
Author: Julien Grall <julien.grall at citrix.com>
Date:   Wed Sep 19 12:50:02 2012 +0100

    isa: Add isa_address_space_io()
    
    This function permits to retrieve ISA IO address space.
    It will be usefull when we need to pass IO address space as argument.
    
    Signed-off-by: Julien Grall <julien.grall at citrix.com>
    Acked-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 685fdc0..144a88e 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -264,4 +264,13 @@ MemoryRegion *isa_address_space(ISADevice *dev)
     return get_system_memory();
 }
 
+MemoryRegion *isa_address_space_io(ISADevice *dev)
+{
+    if (dev) {
+        return isa_bus_from_device(dev)->address_space_io;
+    }
+
+    return isabus->address_space_io;
+}
+
 type_init(isabus_register_types)
diff --git a/hw/isa.h b/hw/isa.h
index f9382e8..9d719fa 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -43,6 +43,7 @@ void isa_bus_irqs(ISABus *bus, qemu_irq *irqs);
 qemu_irq isa_get_irq(ISADevice *dev, int isairq);
 void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq);
 MemoryRegion *isa_address_space(ISADevice *dev);
+MemoryRegion *isa_address_space_io(ISADevice *dev);
 ISADevice *isa_create(ISABus *bus, const char *name);
 ISADevice *isa_try_create(ISABus *bus, const char *name);
 ISADevice *isa_create_simple(ISABus *bus, const char *name);
commit 427e3aa151c749225364d0c30640e2e3c1756d9d
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Sat Nov 17 12:47:18 2012 +0100

    usb-tablet: Allow connecting to ehci
    
    Our ehci code has is capable of significantly lowering the wakeup rate
    for the hcd emulation while the device is idle. It is possible to add
    similar code ot the uhci emulation, but that simply is not there atm,
    and there is no reason why a (virtual) usb-tablet can not be a USB-2 device.
    
    Making usb-hid devices connect to the emulated ehci controller instead
    of the emulated uhci controller on vms which have both lowers the cpuload
    for a fully idle vm from 20% to 2-3% (on my laptop).
    
    An alternative implementation to using a property to select the tablet
    type, would be simply making it a new device type, ie usb-tablet2, but the
    downside of that is that this will require libvirt changes to be available
    through libvirt at all, and then management tools changes to become the
    default for new vms, where as using a property will automatically get
    any pc-1.3 type vms the lower cpuload.
    
    [ kraxel: adapt compat property for post-1.3 merge ]
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
    
    tablet compat fixup
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 040cd07..19e342a 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -290,17 +290,26 @@ static QEMUMachine pc_machine_v1_4 = {
     .is_default = 1,
 };
 
+#define PC_COMPAT_1_3 \
+        {\
+            .driver   = "usb-tablet",\
+            .property = "usb_version",\
+            .value    = stringify(1),\
+        }
+
 static QEMUMachine pc_machine_v1_3 = {
     .name = "pc-1.3",
     .desc = "Standard PC",
     .init = pc_init_pci_1_3,
     .max_cpus = 255,
     .compat_props = (GlobalProperty[]) {
+        PC_COMPAT_1_3,
         { /* end of list */ }
     },
 };
 
 #define PC_COMPAT_1_2 \
+        PC_COMPAT_1_3,\
         {\
             .driver   = "nec-usb-xhci",\
             .property = "msi",\
diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c
index 55266b1..8749128 100644
--- a/hw/usb/dev-hid.c
+++ b/hw/usb/dev-hid.c
@@ -46,6 +46,7 @@ typedef struct USBHIDState {
     USBDevice dev;
     USBEndpoint *intr;
     HIDState hid;
+    uint32_t usb_version;
 } USBHIDState;
 
 enum {
@@ -131,6 +132,36 @@ static const USBDescIface desc_iface_tablet = {
     },
 };
 
+static const USBDescIface desc_iface_tablet2 = {
+    .bInterfaceNumber              = 0,
+    .bNumEndpoints                 = 1,
+    .bInterfaceClass               = USB_CLASS_HID,
+    .bInterfaceProtocol            = 0x02,
+    .ndesc                         = 1,
+    .descs = (USBDescOther[]) {
+        {
+            /* HID descriptor */
+            .data = (uint8_t[]) {
+                0x09,          /*  u8  bLength */
+                USB_DT_HID,    /*  u8  bDescriptorType */
+                0x01, 0x00,    /*  u16 HID_class */
+                0x00,          /*  u8  country_code */
+                0x01,          /*  u8  num_descriptors */
+                USB_DT_REPORT, /*  u8  type: Report */
+                74, 0,         /*  u16 len */
+            },
+        },
+    },
+    .eps = (USBDescEndpoint[]) {
+        {
+            .bEndpointAddress      = USB_DIR_IN | 0x01,
+            .bmAttributes          = USB_ENDPOINT_XFER_INT,
+            .wMaxPacketSize        = 8,
+            .bInterval             = 4, /* 2 ^ (4-1) * 125 usecs = 1 ms */
+        },
+    },
+};
+
 static const USBDescIface desc_iface_keyboard = {
     .bInterfaceNumber              = 0,
     .bNumEndpoints                 = 1,
@@ -196,6 +227,23 @@ static const USBDescDevice desc_device_tablet = {
     },
 };
 
+static const USBDescDevice desc_device_tablet2 = {
+    .bcdUSB                        = 0x0200,
+    .bMaxPacketSize0               = 64,
+    .bNumConfigurations            = 1,
+    .confs = (USBDescConfig[]) {
+        {
+            .bNumInterfaces        = 1,
+            .bConfigurationValue   = 1,
+            .iConfiguration        = STR_CONFIG_TABLET,
+            .bmAttributes          = 0xa0,
+            .bMaxPower             = 50,
+            .nif = 1,
+            .ifs = &desc_iface_tablet2,
+        },
+    },
+};
+
 static const USBDescDevice desc_device_keyboard = {
     .bcdUSB                        = 0x0100,
     .bMaxPacketSize0               = 8,
@@ -239,6 +287,20 @@ static const USBDesc desc_tablet = {
     .str  = desc_strings,
 };
 
+static const USBDesc desc_tablet2 = {
+    .id = {
+        .idVendor          = 0x0627,
+        .idProduct         = 0x0001,
+        .bcdDevice         = 0,
+        .iManufacturer     = STR_MANUFACTURER,
+        .iProduct          = STR_PRODUCT_TABLET,
+        .iSerialNumber     = STR_SERIALNUMBER,
+    },
+    .full = &desc_device_tablet,
+    .high = &desc_device_tablet2,
+    .str  = desc_strings,
+};
+
 static const USBDesc desc_keyboard = {
     .id = {
         .idVendor          = 0x0627,
@@ -508,6 +570,21 @@ static int usb_hid_initfn(USBDevice *dev, int kind)
 
 static int usb_tablet_initfn(USBDevice *dev)
 {
+    USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);
+
+    switch (us->usb_version) {
+    case 1:
+        dev->usb_desc = &desc_tablet;
+        break;
+    case 2:
+        dev->usb_desc = &desc_tablet2;
+        break;
+    default:
+        error_report("Invalid usb version %d for usb-tabler (must be 1 or 2)",
+                     us->usb_version);
+        return -1;
+    }
+
     return usb_hid_initfn(dev, HID_TABLET);
 }
 
@@ -562,8 +639,14 @@ static void usb_hid_class_initfn(ObjectClass *klass, void *data)
     uc->handle_control = usb_hid_handle_control;
     uc->handle_data    = usb_hid_handle_data;
     uc->handle_destroy = usb_hid_handle_destroy;
+    uc->handle_attach  = usb_desc_attach;
 }
 
+static Property usb_tablet_properties[] = {
+        DEFINE_PROP_UINT32("usb_version", USBHIDState, usb_version, 2),
+        DEFINE_PROP_END_OF_LIST(),
+};
+
 static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -572,8 +655,8 @@ static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
     usb_hid_class_initfn(klass, data);
     uc->init           = usb_tablet_initfn;
     uc->product_desc   = "QEMU USB Tablet";
-    uc->usb_desc       = &desc_tablet;
     dc->vmsd = &vmstate_usb_ptr;
+    dc->props = usb_tablet_properties;
 }
 
 static TypeInfo usb_tablet_info = {
commit 8082624099bce56a3139e6b9f72016c00fd10227
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Sat Nov 17 12:47:17 2012 +0100

    ehci: Lower timer freq when the periodic schedule is idle
    
    Lower the timer freq if no iso schedule packets complete for 64 frames in
    a row.
    
    We can safely do this, without adding latency, because:
    1) If there is isoc traffic this will never trigger
    2) For async handled interrupt packets (only usb-host), the completion handler
       will immediately schedule the frame_timer from a bh
    3) All devices using NAK to signal no data for interrupt endpoints now use
       wakeup, which will immediately schedule the frame_timer from a bh
    
    The advantage of this is that when we only have interrupt packets in the
    periodic schedule, async_stepdown can do its work and significantly lower
    the frequency at which the frame_timer runs.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 7df8e21..7536837 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -114,6 +114,7 @@
 #define BUFF_SIZE        5*4096   // Max bytes to transfer per transaction
 #define MAX_QH           100      // Max allowable queue heads in a chain
 #define MIN_FR_PER_TICK  3        // Min frames to process when catching up
+#define PERIODIC_ACTIVE  64
 
 /*  Internal periodic / asynchronous schedule state machine states
  */
@@ -738,6 +739,19 @@ static int ehci_register_companion(USBBus *bus, USBPort *ports[],
     return 0;
 }
 
+static void ehci_wakeup_endpoint(USBBus *bus, USBEndpoint *ep)
+{
+    EHCIState *s = container_of(bus, EHCIState, bus);
+    uint32_t portsc = s->portsc[ep->dev->port->index];
+
+    if (portsc & PORTSC_POWNER) {
+        return;
+    }
+
+    s->periodic_sched_active = PERIODIC_ACTIVE;
+    qemu_bh_schedule(s->async_bh);
+}
+
 static USBDevice *ehci_find_device(EHCIState *ehci, uint8_t addr)
 {
     USBDevice *dev;
@@ -1188,9 +1202,10 @@ static void ehci_async_complete_packet(USBPort *port, USBPacket *packet)
     trace_usb_ehci_packet_action(p->queue, p, "wakeup");
     p->async = EHCI_ASYNC_FINISHED;
 
-    if (p->queue->async) {
-        qemu_bh_schedule(p->queue->ehci->async_bh);
+    if (!p->queue->async) {
+        s->periodic_sched_active = PERIODIC_ACTIVE;
     }
+    qemu_bh_schedule(s->async_bh);
 }
 
 static void ehci_execute_complete(EHCIQueue *q)
@@ -1344,6 +1359,8 @@ static int ehci_process_itd(EHCIState *ehci,
     uint32_t i, len, pid, dir, devaddr, endp;
     uint32_t pg, off, ptr1, ptr2, max, mult;
 
+    ehci->periodic_sched_active = PERIODIC_ACTIVE;
+
     dir =(itd->bufptr[1] & ITD_BUFPTR_DIRECTION);
     devaddr = get_field(itd->bufptr[0], ITD_BUFPTR_DEVADDR);
     endp = get_field(itd->bufptr[0], ITD_BUFPTR_EP);
@@ -2033,6 +2050,9 @@ static void ehci_advance_state(EHCIState *ehci, int async)
         case EST_WRITEBACK:
             assert(q != NULL);
             again = ehci_state_writeback(q);
+            if (!async) {
+                ehci->periodic_sched_active = PERIODIC_ACTIVE;
+            }
             break;
 
         default:
@@ -2198,7 +2218,6 @@ static void ehci_frame_timer(void *opaque)
 
     if (ehci_periodic_enabled(ehci) || ehci->pstate != EST_INACTIVE) {
         need_timer++;
-        ehci->async_stepdown = 0;
 
         if (frames > ehci->maxframes) {
             skipped_frames = frames - ehci->maxframes;
@@ -2222,18 +2241,25 @@ static void ehci_frame_timer(void *opaque)
                     break;
                 }
             }
+            if (ehci->periodic_sched_active) {
+                ehci->periodic_sched_active--;
+            }
             ehci_update_frindex(ehci, 1);
             ehci_advance_periodic_state(ehci);
             ehci->last_run_ns += FRAME_TIMER_NS;
         }
     } else {
-        if (ehci->async_stepdown < ehci->maxframes / 2) {
-            ehci->async_stepdown++;
-        }
+        ehci->periodic_sched_active = 0;
         ehci_update_frindex(ehci, frames);
         ehci->last_run_ns += FRAME_TIMER_NS * frames;
     }
 
+    if (ehci->periodic_sched_active) {
+        ehci->async_stepdown = 0;
+    } else if (ehci->async_stepdown < ehci->maxframes / 2) {
+        ehci->async_stepdown++;
+    }
+
     /*  Async is not inside loop since it executes everything it can once
      *  called
      */
@@ -2301,6 +2327,7 @@ static USBPortOps ehci_port_ops = {
 
 static USBBusOps ehci_bus_ops = {
     .register_companion = ehci_register_companion,
+    .wakeup_endpoint = ehci_wakeup_endpoint,
 };
 
 static int usb_ehci_post_load(void *opaque, int version_id)
diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h
index d8078f4..772870b 100644
--- a/hw/usb/hcd-ehci.h
+++ b/hw/usb/hcd-ehci.h
@@ -311,6 +311,7 @@ struct EHCIState {
 
     uint64_t last_run_ns;
     uint32_t async_stepdown;
+    uint32_t periodic_sched_active;
     bool int_req_by_async;
 };
 
commit 386ab487ebc25d780ddfc4a9aea0b21c4a9aaa94
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Sat Nov 17 12:47:16 2012 +0100

    usb: Allow overriding of usb_desc at the device level
    
    This allows devices to present a different set of descriptors based on
    device properties.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb.h b/hw/usb.h
index 58f812f..268e653 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -230,6 +230,7 @@ struct USBDevice {
     USBEndpoint ep_out[USB_MAX_ENDPOINTS];
 
     QLIST_HEAD(, USBDescString) strings;
+    const USBDesc *usb_desc; /* Overrides class usb_desc if not NULL */
     const USBDescDevice *device;
 
     int configuration;
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 55d0edd..8264c24 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -166,6 +166,9 @@ const char *usb_device_get_product_desc(USBDevice *dev)
 const USBDesc *usb_device_get_usb_desc(USBDevice *dev)
 {
     USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (dev->usb_desc) {
+        return dev->usb_desc;
+    }
     return klass->usb_desc;
 }
 
commit be41efde3ca0372dbf7543e09ff473b4eec25057
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Sat Nov 17 12:47:15 2012 +0100

    usb: Don't allow USB_RET_ASYNC for interrupt packets
    
    It is tempting to use USB_RET_ASYNC for interrupt packets, rather then the
    current NAK + polling approach, but this causes issues for migration, as
    an async completed packet will not getting written back to guest memory until
    the next poll time, and if a migration happens in between it will get lost!
    
    Make an exception for host devices, because:
    1) host-linux actually uses async completion for interrupt endpoints
    2) host devices don't migrate anyways
    
    Ideally we would convert host-linux.c to handle (input) interrupt endpoints in
    a buffered manner like it does for isoc endpoints, keeping multiple urbs
    submitted to ensure the devices timing requirements are met, as well as making
    its interrupt ep handling the same as other usb-devices.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb.h b/hw/usb.h
index 7d6de69..58f812f 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -197,6 +197,7 @@ struct USBEndpoint {
 
 enum USBDeviceFlags {
     USB_DEV_FLAG_FULL_PATH,
+    USB_DEV_FLAG_IS_HOST,
 };
 
 /* definition of a USB device */
diff --git a/hw/usb/core.c b/hw/usb/core.c
index 52b5310..8e360d3 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -406,7 +406,11 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p)
     if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline) {
         usb_process_one(p);
         if (p->status == USB_RET_ASYNC) {
+            /* hcd drivers cannot handle async for isoc */
             assert(p->ep->type != USB_ENDPOINT_XFER_ISOC);
+            /* using async for interrupt packets breaks migration */
+            assert(p->ep->type != USB_ENDPOINT_XFER_INT ||
+                   (dev->flags & USB_DEV_FLAG_IS_HOST));
             usb_packet_set_state(p, USB_PACKET_ASYNC);
             QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
         } else if (p->status == USB_RET_ADD_TO_QUEUE) {
diff --git a/hw/usb/host-bsd.c b/hw/usb/host-bsd.c
index 6473e8b..dae0009 100644
--- a/hw/usb/host-bsd.c
+++ b/hw/usb/host-bsd.c
@@ -292,6 +292,7 @@ static void usb_host_handle_destroy(USBDevice *opaque)
 
 static int usb_host_initfn(USBDevice *dev)
 {
+    dev->flags |= (1 << USB_DEV_FLAG_IS_HOST);
     return 0;
 }
 
diff --git a/hw/usb/host-linux.c b/hw/usb/host-linux.c
index aa77b77..bdafb6b 100644
--- a/hw/usb/host-linux.c
+++ b/hw/usb/host-linux.c
@@ -1476,6 +1476,7 @@ static int usb_host_initfn(USBDevice *dev)
 {
     USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
 
+    dev->flags |= (1 << USB_DEV_FLAG_IS_HOST);
     dev->auto_attach = 0;
     s->fd = -1;
     s->hub_fd = -1;
commit 8beba9304391189666df1b62b23a5101b3831317
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Sat Nov 17 12:47:14 2012 +0100

    usb: Call wakeup when data becomes available for all devices with int eps
    
    This is necessary for proper interaction with the xhci controller, and it
    will allow other hcds to lower there frame timer while waiting for interrupt
    data.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
index 9ee60dd..470fbbb 100644
--- a/hw/usb/dev-hub.c
+++ b/hw/usb/dev-hub.c
@@ -184,6 +184,7 @@ static void usb_hub_detach(USBPort *port1)
         port->wPortStatus &= ~PORT_STAT_ENABLE;
         port->wPortChange |= PORT_STAT_C_ENABLE;
     }
+    usb_wakeup(s->intr);
 }
 
 static void usb_hub_child_detach(USBPort *port1, USBDevice *child)
@@ -363,6 +364,7 @@ static void usb_hub_handle_control(USBDevice *dev, USBPacket *p,
                     port->wPortChange |= PORT_STAT_C_RESET;
                     /* set enable bit */
                     port->wPortStatus |= PORT_STAT_ENABLE;
+                    usb_wakeup(s->intr);
                 }
                 break;
             case PORT_POWER:
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 14d9e5a..30cb033 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -639,6 +639,8 @@ typedef struct USBNetState {
     unsigned int in_ptr, in_len;
     uint8_t in_buf[2048];
 
+    USBEndpoint *intr;
+
     char usbstring_mac[13];
     NICState *nic;
     NICConf conf;
@@ -851,6 +853,10 @@ static void *rndis_queue_response(USBNetState *s, unsigned int length)
     struct rndis_response *r =
             g_malloc0(sizeof(struct rndis_response) + length);
 
+    if (QTAILQ_EMPTY(&s->rndis_resp)) {
+        usb_wakeup(s->intr);
+    }
+
     QTAILQ_INSERT_TAIL(&s->rndis_resp, r, entries);
     r->length = length;
 
@@ -1349,6 +1355,7 @@ static int usb_net_initfn(USBDevice *dev)
     s->media_state = 0;	/* NDIS_MEDIA_STATE_CONNECTED */;
     s->filter = 0;
     s->vendorid = 0x1234;
+    s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_usbnet_info, &s->conf,
diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c
index 08b416d..f7342b0 100644
--- a/hw/usb/dev-wacom.c
+++ b/hw/usb/dev-wacom.c
@@ -43,6 +43,7 @@
 
 typedef struct USBWacomState {
     USBDevice dev;
+    USBEndpoint *intr;
     QEMUPutMouseEntry *eh_entry;
     int dx, dy, dz, buttons_state;
     int x, y;
@@ -137,6 +138,7 @@ static void usb_mouse_event(void *opaque,
     s->dz += dz1;
     s->buttons_state = buttons_state;
     s->changed = 1;
+    usb_wakeup(s->intr);
 }
 
 static void usb_wacom_event(void *opaque,
@@ -150,6 +152,7 @@ static void usb_wacom_event(void *opaque,
     s->dz += dz;
     s->buttons_state = buttons_state;
     s->changed = 1;
+    usb_wakeup(s->intr);
 }
 
 static inline int int_clamp(int val, int vmin, int vmax)
@@ -337,6 +340,7 @@ static int usb_wacom_initfn(USBDevice *dev)
     USBWacomState *s = DO_UPCAST(USBWacomState, dev, dev);
     usb_desc_create_serial(dev);
     usb_desc_init(dev);
+    s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1);
     s->changed = 1;
     return 0;
 }
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 490c90f..9e7f645 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1644,6 +1644,10 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id,
             return;
         }
 
+        if (QTAILQ_EMPTY(&dev->endpoint[EP2I(ep)].bufpq)) {
+            usb_wakeup(usb_ep_get(&dev->dev, USB_TOKEN_IN, ep & 0x0f));
+        }
+
         /* bufp_alloc also adds the packet to the ep queue */
         bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
     } else {
commit f1ae2e3883c4ee3a9f91f484690abe42f5063d64
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Tue Dec 4 14:39:16 2012 +0100

    add pc-1.4
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index aa3e7f4..040cd07 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -281,8 +281,8 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
 }
 #endif
 
-static QEMUMachine pc_machine_v1_3 = {
-    .name = "pc-1.3",
+static QEMUMachine pc_machine_v1_4 = {
+    .name = "pc-1.4",
     .alias = "pc",
     .desc = "Standard PC",
     .init = pc_init_pci_1_3,
@@ -290,6 +290,16 @@ static QEMUMachine pc_machine_v1_3 = {
     .is_default = 1,
 };
 
+static QEMUMachine pc_machine_v1_3 = {
+    .name = "pc-1.3",
+    .desc = "Standard PC",
+    .init = pc_init_pci_1_3,
+    .max_cpus = 255,
+    .compat_props = (GlobalProperty[]) {
+        { /* end of list */ }
+    },
+};
+
 #define PC_COMPAT_1_2 \
         {\
             .driver   = "nec-usb-xhci",\
@@ -626,6 +636,7 @@ static QEMUMachine xenfv_machine = {
 
 static void pc_machine_init(void)
 {
+    qemu_register_machine(&pc_machine_v1_4);
     qemu_register_machine(&pc_machine_v1_3);
     qemu_register_machine(&pc_machine_v1_2);
     qemu_register_machine(&pc_machine_v1_1);
commit 3e43749882c558875f70ac5deda39cdc9797e245
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Tue Nov 27 08:24:42 2012 +0100

    acpi: drop debug port
    
    I'm pretty sure this isn't needed any more.  I think this predates the
    switch to seabios, and the seabios DSDT table has a DBUG() aml macro
    which writes stuff to the seabios debug port (0x402).
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 263338a..b03454e 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -38,8 +38,6 @@
 # define PIIX4_DPRINTF(format, ...)     do { } while (0)
 #endif
 
-#define ACPI_DBG_IO_ADDR  0xb044
-
 #define GPE_BASE 0xafe0
 #define GPE_LEN 4
 
@@ -129,11 +127,6 @@ static void apm_ctrl_changed(uint32_t val, void *arg)
     }
 }
 
-static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
-{
-    PIIX4_DPRINTF("ACPI: DBG: 0x%08x\n", val);
-}
-
 static void pm_io_space_update(PIIX4PMState *s)
 {
     uint32_t pm_io_base;
@@ -400,8 +393,6 @@ static int piix4_pm_initfn(PCIDevice *dev)
     /* APM */
     apm_init(&s->apm, apm_ctrl_changed, s);
 
-    register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s);
-
     if (s->kvm_enabled) {
         /* Mark SMM as already inited to prevent SMM from running.  KVM does not
          * support SMM mode. */
commit 3f5bc9e8af8c9ee617b143e42ad4bd2feb379a19
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Nov 23 15:02:18 2012 +0100

    q35: update lpc pci config space according to configured devices
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/ich9.h b/hw/ich9.h
index de49135..34e216f 100644
--- a/hw/ich9.h
+++ b/hw/ich9.h
@@ -51,6 +51,7 @@ typedef struct ICH9LPCState {
     /* isa bus */
     ISABus *isa_bus;
     MemoryRegion rbca_mem;
+    Notifier machine_ready;
 
     qemu_irq *pic;
     qemu_irq *ioapic;
diff --git a/hw/lpc_ich9.c b/hw/lpc_ich9.c
index 2fc83a4..6585236 100644
--- a/hw/lpc_ich9.c
+++ b/hw/lpc_ich9.c
@@ -60,6 +60,7 @@
 #include "pam.h"
 #include "pci_internals.h"
 #include "exec-memory.h"
+#include "sysemu.h"
 
 static int ich9_lpc_sci_irq(ICH9LPCState *lpc);
 
@@ -456,6 +457,30 @@ static const MemoryRegionOps rbca_mmio_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
+static void ich9_lpc_machine_ready(Notifier *n, void *opaque)
+{
+    ICH9LPCState *s = container_of(n, ICH9LPCState, machine_ready);
+    uint8_t *pci_conf;
+
+    pci_conf = s->d.config;
+    if (isa_is_ioport_assigned(0x3f8)) {
+        /* com1 */
+        pci_conf[0x82] |= 0x01;
+    }
+    if (isa_is_ioport_assigned(0x2f8)) {
+        /* com2 */
+        pci_conf[0x82] |= 0x02;
+    }
+    if (isa_is_ioport_assigned(0x378)) {
+        /* lpt */
+        pci_conf[0x82] |= 0x04;
+    }
+    if (isa_is_ioport_assigned(0x3f0)) {
+        /* floppy */
+        pci_conf[0x82] |= 0x08;
+    }
+}
+
 static int ich9_lpc_initfn(PCIDevice *d)
 {
     ICH9LPCState *lpc = ICH9_LPC_DEVICE(d);
@@ -473,6 +498,10 @@ static int ich9_lpc_initfn(PCIDevice *d)
 
     ich9_cc_init(lpc);
     apm_init(&lpc->apm, ich9_apm_ctrl_changed, lpc);
+
+    lpc->machine_ready.notify = ich9_lpc_machine_ready;
+    qemu_add_machine_init_done_notifier(&lpc->machine_ready);
+
     return 0;
 }
 
diff --git a/hw/smbus_ich9.c b/hw/smbus_ich9.c
index 54e7e12..4194785 100644
--- a/hw/smbus_ich9.c
+++ b/hw/smbus_ich9.c
@@ -78,18 +78,6 @@ static int ich9_smbus_initfn(PCIDevice *d)
     pci_config_set_interrupt_pin(d->config, 0x01); /* interrupt pin 1 */
 
     pci_set_byte(d->config + ICH9_SMB_HOSTC, 0);
-
-    /*
-     * update parameters based on
-     * paralell_hds[0]
-     * serial_hds[0]
-     * serial_hds[0]
-     * fdc
-     *
-     * Is there any OS that depends on them?
-     */
-
-    pci_set_byte(d->config + ICH9_SMB_HOSTC, 0);
     /* TODO bar0, bar1: 64bit BAR support*/
 
     pm_smbus_init(&d->qdev, &s->smb);
commit c177684c753a0b1337acebb7dbc6f3f3a9700321
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Nov 23 16:03:19 2012 +0100

    apci: switch piix4 pci hotplug to memory api
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index d2ba56e..263338a 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -42,6 +42,9 @@
 
 #define GPE_BASE 0xafe0
 #define GPE_LEN 4
+
+#define PCI_HOTPLUG_ADDR 0xae00
+#define PCI_HOTPLUG_SIZE 0x000f
 #define PCI_UP_BASE 0xae00
 #define PCI_DOWN_BASE 0xae04
 #define PCI_EJ_BASE 0xae08
@@ -58,6 +61,7 @@ typedef struct PIIX4PMState {
     PCIDevice dev;
     MemoryRegion io;
     MemoryRegion io_gpe;
+    MemoryRegion io_pci;
     ACPIREGS ar;
 
     APMState apm;
@@ -574,6 +578,27 @@ static uint32_t pcirmv_read(void *opaque, uint32_t addr)
     return s->pci0_hotplug_enable;
 }
 
+static const MemoryRegionOps piix4_pci_ops = {
+    .old_portio = (MemoryRegionPortio[]) {
+        {
+            .offset = PCI_UP_BASE - PCI_HOTPLUG_ADDR,   .len = 4, .size = 4,
+            .read = pci_up_read,
+        },{
+            .offset = PCI_DOWN_BASE - PCI_HOTPLUG_ADDR, .len = 4, .size = 4,
+            .read = pci_down_read,
+        },{
+            .offset = PCI_EJ_BASE - PCI_HOTPLUG_ADDR,   .len = 4, .size = 4,
+            .read = pci_features_read,
+            .write = pciej_write,
+        },{
+            .offset = PCI_RMV_BASE - PCI_HOTPLUG_ADDR,  .len = 4, .size = 4,
+            .read = pcirmv_read,
+        },
+        PORTIO_END_OF_LIST()
+    },
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
                                 PCIHotplugState state);
 
@@ -583,14 +608,10 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
                           GPE_LEN);
     memory_region_add_subregion(get_system_io(), GPE_BASE, &s->io_gpe);
 
-    register_ioport_read(PCI_UP_BASE, 4, 4, pci_up_read, s);
-    register_ioport_read(PCI_DOWN_BASE, 4, 4, pci_down_read, s);
-
-    register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, s);
-    register_ioport_read(PCI_EJ_BASE, 4, 4,  pci_features_read, s);
-
-    register_ioport_read(PCI_RMV_BASE, 4, 4,  pcirmv_read, s);
-
+    memory_region_init_io(&s->io_pci, &piix4_pci_ops, s, "apci-pci-hotplug",
+                          PCI_HOTPLUG_SIZE);
+    memory_region_add_subregion(get_system_io(), PCI_HOTPLUG_ADDR,
+                                &s->io_pci);
     pci_bus_hotplug(bus, piix4_device_hotplug, &s->dev.qdev);
 }
 
commit c84649ca66a32aadba20a8202062b02247270ee5
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Nov 23 15:37:05 2012 +0100

    acpi: remove acpi_gpe_blk
    
    With gpe being switched to memory api this is no longer needed.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/acpi.c b/hw/acpi.c
index e58e45f..ae29a59 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -493,11 +493,6 @@ void acpi_gpe_init(ACPIREGS *ar, uint8_t len)
     ar->gpe.en = g_malloc0(len / 2);
 }
 
-void acpi_gpe_blk(ACPIREGS *ar, uint32_t blk)
-{
-    ar->gpe.blk = blk;
-}
-
 void acpi_gpe_reset(ACPIREGS *ar)
 {
     memset(ar->gpe.sts, 0, ar->gpe.len / 2);
@@ -523,7 +518,6 @@ void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val)
 {
     uint8_t *cur;
 
-    addr -= ar->gpe.blk;
     cur = acpi_gpe_ioport_get_ptr(ar, addr);
     if (addr < ar->gpe.len / 2) {
         /* GPE_STS */
@@ -541,7 +535,6 @@ uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr)
     uint8_t *cur;
     uint32_t val;
 
-    addr -= ar->gpe.blk;
     cur = acpi_gpe_ioport_get_ptr(ar, addr);
     val = 0;
     if (cur != NULL) {
diff --git a/hw/acpi.h b/hw/acpi.h
index 918d7f5..afda153 100644
--- a/hw/acpi.h
+++ b/hw/acpi.h
@@ -104,7 +104,6 @@ struct ACPIPM1CNT {
 };
 
 struct ACPIGPE {
-    uint32_t blk;
     uint8_t len;
 
     uint8_t *sts;
@@ -150,7 +149,6 @@ void acpi_pm1_cnt_reset(ACPIREGS *ar);
 
 /* GPE0 */
 void acpi_gpe_init(ACPIREGS *ar, uint8_t len);
-void acpi_gpe_blk(ACPIREGS *ar, uint32_t blk);
 void acpi_gpe_reset(ACPIREGS *ar);
 
 void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val);
diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
index db0d7a5..c5978d3 100644
--- a/hw/acpi_ich9.c
+++ b/hw/acpi_ich9.c
@@ -212,7 +212,6 @@ void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3)
     acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io);
 
     acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN);
-    acpi_gpe_blk(&pm->acpi_regs, 0);
     memory_region_init_io(&pm->io_gpe, &ich9_gpe_ops, pm, "apci-gpe0",
                           ICH9_PMIO_GPE0_LEN);
     memory_region_add_subregion(&pm->io, ICH9_PMIO_GPE0_STS, &pm->io_gpe);
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index c1a58d3..d2ba56e 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -582,7 +582,6 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
     memory_region_init_io(&s->io_gpe, &piix4_gpe_ops, s, "apci-gpe0",
                           GPE_LEN);
     memory_region_add_subregion(get_system_io(), GPE_BASE, &s->io_gpe);
-    acpi_gpe_blk(&s->ar, 0);
 
     register_ioport_read(PCI_UP_BASE, 4, 4, pci_up_read, s);
     register_ioport_read(PCI_DOWN_BASE, 4, 4, pci_down_read, s);
commit b65b93f24cb84923d2d7d43cf87d40bc88b6bdcd
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Nov 23 15:35:13 2012 +0100

    apci: switch piix4 gpe to memory api
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index b1d5bf3..c1a58d3 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -57,6 +57,7 @@ struct pci_status {
 typedef struct PIIX4PMState {
     PCIDevice dev;
     MemoryRegion io;
+    MemoryRegion io_gpe;
     ACPIREGS ar;
 
     APMState apm;
@@ -500,7 +501,7 @@ static void piix4_pm_register_types(void)
 
 type_init(piix4_pm_register_types)
 
-static uint32_t gpe_readb(void *opaque, uint32_t addr)
+static uint64_t gpe_readb(void *opaque, hwaddr addr, unsigned width)
 {
     PIIX4PMState *s = opaque;
     uint32_t val = acpi_gpe_ioport_readb(&s->ar, addr);
@@ -509,7 +510,8 @@ static uint32_t gpe_readb(void *opaque, uint32_t addr)
     return val;
 }
 
-static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
+static void gpe_writeb(void *opaque, hwaddr addr, uint64_t val,
+                       unsigned width)
 {
     PIIX4PMState *s = opaque;
 
@@ -519,6 +521,16 @@ static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
     PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val);
 }
 
+static const MemoryRegionOps piix4_gpe_ops = {
+    .read = gpe_readb,
+    .write = gpe_writeb,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 4,
+    .impl.min_access_size = 1,
+    .impl.max_access_size = 1,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static uint32_t pci_up_read(void *opaque, uint32_t addr)
 {
     PIIX4PMState *s = opaque;
@@ -567,10 +579,10 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
 
 static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
 {
-
-    register_ioport_write(GPE_BASE, GPE_LEN, 1, gpe_writeb, s);
-    register_ioport_read(GPE_BASE, GPE_LEN, 1,  gpe_readb, s);
-    acpi_gpe_blk(&s->ar, GPE_BASE);
+    memory_region_init_io(&s->io_gpe, &piix4_gpe_ops, s, "apci-gpe0",
+                          GPE_LEN);
+    memory_region_add_subregion(get_system_io(), GPE_BASE, &s->io_gpe);
+    acpi_gpe_blk(&s->ar, 0);
 
     register_ioport_read(PCI_UP_BASE, 4, 4, pci_up_read, s);
     register_ioport_read(PCI_DOWN_BASE, 4, 4, pci_down_read, s);
commit 24fe083de67e0f736c54da4abda05f23ec37c51d
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Nov 23 14:58:04 2012 +0100

    acpi: fix piix4 smbus mapping
    
    Make write to the smbus base register and enable bit actually work.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 9e6c97e..b1d5bf3 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -142,12 +142,29 @@ static void pm_io_space_update(PIIX4PMState *s)
     memory_region_transaction_commit();
 }
 
+static void smbus_io_space_update(PIIX4PMState *s)
+{
+    s->smb_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x90));
+    s->smb_io_base &= 0xffc0;
+
+    memory_region_transaction_begin();
+    memory_region_set_enabled(&s->smb.io, s->dev.config[0xd2] & 1);
+    memory_region_set_address(&s->smb.io, s->smb_io_base);
+    memory_region_transaction_commit();
+}
+
 static void pm_write_config(PCIDevice *d,
                             uint32_t address, uint32_t val, int len)
 {
     pci_default_write_config(d, address, val, len);
-    if (range_covers_byte(address, len, 0x80))
+    if (range_covers_byte(address, len, 0x80) ||
+        ranges_overlap(address, len, 0x40, 4)) {
         pm_io_space_update((PIIX4PMState *)d);
+    }
+    if (range_covers_byte(address, len, 0xd2) ||
+        ranges_overlap(address, len, 0x90, 4)) {
+        smbus_io_space_update((PIIX4PMState *)d);
+    }
 }
 
 static void vmstate_pci_status_pre_save(void *opaque)
@@ -392,6 +409,7 @@ static int piix4_pm_initfn(PCIDevice *dev)
     pci_conf[0x91] = s->smb_io_base >> 8;
     pci_conf[0xd2] = 0x09;
     pm_smbus_init(&s->dev.qdev, &s->smb);
+    memory_region_set_enabled(&s->smb.io, pci_conf[0xd2] & 1);
     memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io);
 
     memory_region_init(&s->io, "piix4-pm", 64);
commit 798512e5522685163c8d5fc5093aea19ae9cce06
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Nov 23 14:57:01 2012 +0100

    acpi: switch smbus to memory api
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index cf8aa3d..9e6c97e 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -391,8 +391,8 @@ static int piix4_pm_initfn(PCIDevice *dev)
     pci_conf[0x90] = s->smb_io_base | 1;
     pci_conf[0x91] = s->smb_io_base >> 8;
     pci_conf[0xd2] = 0x09;
-    register_ioport_write(s->smb_io_base, 64, 1, smb_ioport_writeb, &s->smb);
-    register_ioport_read(s->smb_io_base, 64, 1, smb_ioport_readb, &s->smb);
+    pm_smbus_init(&s->dev.qdev, &s->smb);
+    memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io);
 
     memory_region_init(&s->io, "piix4-pm", 64);
     memory_region_set_enabled(&s->io, false);
@@ -406,7 +406,6 @@ static int piix4_pm_initfn(PCIDevice *dev)
     s->powerdown_notifier.notify = piix4_pm_powerdown_req;
     qemu_register_powerdown_notifier(&s->powerdown_notifier);
 
-    pm_smbus_init(&s->dev.qdev, &s->smb);
     s->machine_ready.notify = piix4_pm_machine_ready;
     qemu_add_machine_init_done_notifier(&s->machine_ready);
     qemu_register_reset(piix4_reset, s);
diff --git a/hw/pm_smbus.c b/hw/pm_smbus.c
index 5d6046d..ea1380c 100644
--- a/hw/pm_smbus.c
+++ b/hw/pm_smbus.c
@@ -94,10 +94,11 @@ static void smb_transaction(PMSMBus *s)
     s->smb_stat |= 0x04;
 }
 
-void smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
+                              unsigned width)
 {
     PMSMBus *s = opaque;
-    addr &= 0x3f;
+
     SMBUS_DPRINTF("SMB writeb port=0x%04x val=0x%02x\n", addr, val);
     switch(addr) {
     case SMBHSTSTS:
@@ -131,12 +132,11 @@ void smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
-uint32_t smb_ioport_readb(void *opaque, uint32_t addr)
+static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
 {
     PMSMBus *s = opaque;
     uint32_t val;
 
-    addr &= 0x3f;
     switch(addr) {
     case SMBHSTSTS:
         val = s->smb_stat;
@@ -170,7 +170,16 @@ uint32_t smb_ioport_readb(void *opaque, uint32_t addr)
     return val;
 }
 
+static const MemoryRegionOps pm_smbus_ops = {
+    .read = smb_ioport_readb,
+    .write = smb_ioport_writeb,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 1,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 void pm_smbus_init(DeviceState *parent, PMSMBus *smb)
 {
     smb->smbus = i2c_init_bus(parent, "i2c");
+    memory_region_init_io(&smb->io, &pm_smbus_ops, smb, "pm-smbus", 64);
 }
diff --git a/hw/pm_smbus.h b/hw/pm_smbus.h
index 4750a40..e3069bf 100644
--- a/hw/pm_smbus.h
+++ b/hw/pm_smbus.h
@@ -3,6 +3,7 @@
 
 typedef struct PMSMBus {
     i2c_bus *smbus;
+    MemoryRegion io;
 
     uint8_t smb_stat;
     uint8_t smb_ctl;
@@ -15,7 +16,5 @@ typedef struct PMSMBus {
 } PMSMBus;
 
 void pm_smbus_init(DeviceState *parent, PMSMBus *smb);
-void smb_ioport_writeb(void *opaque, uint32_t addr, uint32_t val);
-uint32_t smb_ioport_readb(void *opaque, uint32_t addr);
 
 #endif /* !PM_SMBUS_H */
diff --git a/hw/smbus_ich9.c b/hw/smbus_ich9.c
index 6940583..54e7e12 100644
--- a/hw/smbus_ich9.c
+++ b/hw/smbus_ich9.c
@@ -40,7 +40,6 @@ typedef struct ICH9SMBState {
     PCIDevice dev;
 
     PMSMBus smb;
-    MemoryRegion mem_bar;
 } ICH9SMBState;
 
 static const VMStateDescription vmstate_ich9_smbus = {
@@ -54,42 +53,23 @@ static const VMStateDescription vmstate_ich9_smbus = {
     }
 };
 
-static void ich9_smb_ioport_writeb(void *opaque, hwaddr addr,
-                                   uint64_t val, unsigned size)
+static void ich9_smbus_write_config(PCIDevice *d, uint32_t address,
+                                    uint32_t val, int len)
 {
-    ICH9SMBState *s = opaque;
-    uint8_t hostc = s->dev.config[ICH9_SMB_HOSTC];
+    ICH9SMBState *s = ICH9_SMB_DEVICE(d);
 
-    if ((hostc & ICH9_SMB_HOSTC_HST_EN) && !(hostc & ICH9_SMB_HOSTC_I2C_EN)) {
-        uint64_t offset = addr - s->dev.io_regions[ICH9_SMB_SMB_BASE_BAR].addr;
-        smb_ioport_writeb(&s->smb, offset, val);
+    pci_default_write_config(d, address, val, len);
+    if (range_covers_byte(address, len, ICH9_SMB_HOSTC)) {
+        uint8_t hostc = s->dev.config[ICH9_SMB_HOSTC];
+        if ((hostc & ICH9_SMB_HOSTC_HST_EN) &&
+            !(hostc & ICH9_SMB_HOSTC_I2C_EN)) {
+            memory_region_set_enabled(&s->smb.io, true);
+        } else {
+            memory_region_set_enabled(&s->smb.io, false);
+        }
     }
 }
 
-static uint64_t ich9_smb_ioport_readb(void *opaque, hwaddr addr,
-                                      unsigned size)
-{
-    ICH9SMBState *s = opaque;
-    uint8_t hostc = s->dev.config[ICH9_SMB_HOSTC];
-
-    if ((hostc & ICH9_SMB_HOSTC_HST_EN) && !(hostc & ICH9_SMB_HOSTC_I2C_EN)) {
-        uint64_t offset = addr - s->dev.io_regions[ICH9_SMB_SMB_BASE_BAR].addr;
-        return smb_ioport_readb(&s->smb, offset);
-    }
-
-    return 0xff;
-}
-
-static const MemoryRegionOps lpc_smb_mmio_ops = {
-    .read = ich9_smb_ioport_readb,
-    .write = ich9_smb_ioport_writeb,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-    .impl = {
-        .min_access_size = 1,
-        .max_access_size = 1,
-    },
-};
-
 static int ich9_smbus_initfn(PCIDevice *d)
 {
     ICH9SMBState *s = ICH9_SMB_DEVICE(d);
@@ -109,15 +89,12 @@ static int ich9_smbus_initfn(PCIDevice *d)
      * Is there any OS that depends on them?
      */
 
-    /* TODO smb_io_base */
     pci_set_byte(d->config + ICH9_SMB_HOSTC, 0);
     /* TODO bar0, bar1: 64bit BAR support*/
 
-    memory_region_init_io(&s->mem_bar, &lpc_smb_mmio_ops, s, "ich9-smbus-bar",
-                            ICH9_SMB_SMB_BASE_SIZE);
-    pci_register_bar(d, ICH9_SMB_SMB_BASE_BAR, PCI_BASE_ADDRESS_SPACE_IO,
-                        &s->mem_bar);
     pm_smbus_init(&d->qdev, &s->smb);
+    pci_register_bar(d, ICH9_SMB_SMB_BASE_BAR, PCI_BASE_ADDRESS_SPACE_IO,
+                     &s->smb.io);
     return 0;
 }
 
@@ -134,6 +111,7 @@ static void ich9_smb_class_init(ObjectClass *klass, void *data)
     dc->vmsd = &vmstate_ich9_smbus;
     dc->desc = "ICH9 SMBUS Bridge";
     k->init = ich9_smbus_initfn;
+    k->config_write = ich9_smbus_write_config;
 }
 
 i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base)
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 99e6b2f..5016e95 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -351,8 +351,8 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
     pci_conf[0x90] = s->smb_io_base | 1;
     pci_conf[0x91] = s->smb_io_base >> 8;
     pci_conf[0xd2] = 0x90;
-    register_ioport_write(s->smb_io_base, 0xf, 1, smb_ioport_writeb, &s->smb);
-    register_ioport_read(s->smb_io_base, 0xf, 1, smb_ioport_readb, &s->smb);
+    pm_smbus_init(&s->dev.qdev, &s->smb);
+    memory_region_add_subregion(get_system_io(), s->smb_io_base, &s->smb.io);
 
     apm_init(&s->apm, NULL, s);
 
@@ -364,8 +364,6 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
     acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
     acpi_pm1_cnt_init(&s->ar, &s->io);
 
-    pm_smbus_init(&s->dev.qdev, &s->smb);
-
     return 0;
 }
 
commit 4a522de0905c88160b6f93eb5d35883382a0c333
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Nov 22 14:01:20 2012 +0100

    acpi: cleanup ich9 memory region
    
    Nothing left to do, everything handled by subregions,
    we can zap the reaw/write handlers now.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
index 0ed17da..db0d7a5 100644
--- a/hw/acpi_ich9.c
+++ b/hw/acpi_ich9.c
@@ -42,10 +42,6 @@ do { printf("%s "fmt, __func__, ## __VA_ARGS__); } while (0)
 #define ICH9_DEBUG(fmt, ...)    do { } while (0)
 #endif
 
-static void pm_ioport_write_fallback(void *opaque, uint32_t addr, int len,
-                                     uint32_t val);
-static uint32_t pm_ioport_read_fallback(void *opaque, uint32_t addr, int len);
-
 static void pm_update_sci(ICH9LPCPMRegs *pm)
 {
     int sci_level, pm1a_sts;
@@ -71,125 +67,6 @@ static void ich9_pm_update_sci_fn(ACPIREGS *regs)
     pm_update_sci(pm);
 }
 
-static void pm_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
-    switch (addr & ICH9_PMIO_MASK) {
-    default:
-        break;
-    }
-
-    ICH9_DEBUG("port=0x%04x val=0x%04x\n", addr, val);
-}
-
-static uint32_t pm_ioport_readb(void *opaque, uint32_t addr)
-{
-    uint32_t val = 0;
-
-    switch (addr & ICH9_PMIO_MASK) {
-    default:
-        val = 0;
-        break;
-    }
-    ICH9_DEBUG("port=0x%04x val=0x%04x\n", addr, val);
-    return val;
-}
-
-static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
-{
-    switch (addr & ICH9_PMIO_MASK) {
-    default:
-        pm_ioport_write_fallback(opaque, addr, 2, val);
-        break;
-    }
-    ICH9_DEBUG("port=0x%04x val=0x%04x\n", addr, val);
-}
-
-static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
-{
-    uint32_t val;
-
-    switch (addr & ICH9_PMIO_MASK) {
-    default:
-        val = pm_ioport_read_fallback(opaque, addr, 2);
-        break;
-    }
-    ICH9_DEBUG("port=0x%04x val=0x%04x\n", addr, val);
-    return val;
-}
-
-static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
-{
-    switch (addr & ICH9_PMIO_MASK) {
-    default:
-        pm_ioport_write_fallback(opaque, addr, 4, val);
-        break;
-    }
-    ICH9_DEBUG("port=0x%04x val=0x%08x\n", addr, val);
-}
-
-static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
-{
-    uint32_t val;
-
-    switch (addr & ICH9_PMIO_MASK) {
-    default:
-        val = pm_ioport_read_fallback(opaque, addr, 4);
-        break;
-    }
-    ICH9_DEBUG("port=0x%04x val=0x%08x\n", addr, val);
-    return val;
-}
-
-static void pm_ioport_write_fallback(void *opaque, uint32_t addr, int len,
-                                     uint32_t val)
- {
-    int subsize = (len == 4) ? 2 : 1;
-    IOPortWriteFunc *ioport_write =
-        (subsize == 2) ? pm_ioport_writew : pm_ioport_writeb;
-
-    int i;
-
-    for (i = 0; i < len; i += subsize) {
-        ioport_write(opaque, addr, val);
-        val >>= 8 * subsize;
-    }
-}
-
-static uint32_t pm_ioport_read_fallback(void *opaque, uint32_t addr, int len)
-{
-    int subsize = (len == 4) ? 2 : 1;
-    IOPortReadFunc *ioport_read =
-        (subsize == 2) ? pm_ioport_readw : pm_ioport_readb;
-
-    uint32_t val;
-    int i;
-
-    val = 0;
-    for (i = 0; i < len; i += subsize) {
-        val <<= 8 * subsize;
-        val |= ioport_read(opaque, addr);
-    }
-
-    return val;
-}
-
-static const MemoryRegionOps pm_io_ops = {
-    .old_portio = (MemoryRegionPortio[]) {
-        { .offset = 0, .len = ICH9_PMIO_SIZE, .size = 1,
-          .read = pm_ioport_readb, .write = pm_ioport_writeb },
-        { .offset = 0, .len = ICH9_PMIO_SIZE, .size = 2,
-          .read = pm_ioport_readw, .write = pm_ioport_writew },
-        { .offset = 0, .len = ICH9_PMIO_SIZE, .size = 4,
-          .read = pm_ioport_readl, .write = pm_ioport_writel },
-        PORTIO_END_OF_LIST(),
-    },
-    .valid.min_access_size = 1,
-    .valid.max_access_size = 4,
-    .impl.min_access_size = 1,
-    .impl.max_access_size = 4,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
 static uint64_t ich9_gpe_readb(void *opaque, hwaddr addr, unsigned width)
 {
     ICH9LPCPMRegs *pm = opaque;
@@ -326,7 +203,7 @@ static void pm_powerdown_req(Notifier *n, void *opaque)
 
 void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3)
 {
-    memory_region_init_io(&pm->io, &pm_io_ops, pm, "ich9-pm", ICH9_PMIO_SIZE);
+    memory_region_init(&pm->io, "ich9-pm", ICH9_PMIO_SIZE);
     memory_region_set_enabled(&pm->io, false);
     memory_region_add_subregion(get_system_io(), 0, &pm->io);
 
commit 10cc69b0de8e1756e6fbda4592c9d0ba3bce58fc
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Nov 22 13:51:35 2012 +0100

    apci: switch ich9 smi to memory api
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
index 5fc160a..0ed17da 100644
--- a/hw/acpi_ich9.c
+++ b/hw/acpi_ich9.c
@@ -119,12 +119,7 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
 
 static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
 {
-    ICH9LPCPMRegs *pm = opaque;
-
     switch (addr & ICH9_PMIO_MASK) {
-    case ICH9_PMIO_SMI_EN:
-        pm->smi_en = val;
-        break;
     default:
         pm_ioport_write_fallback(opaque, addr, 4, val);
         break;
@@ -134,14 +129,9 @@ static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
 
 static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
 {
-    ICH9LPCPMRegs *pm = opaque;
     uint32_t val;
 
     switch (addr & ICH9_PMIO_MASK) {
-    case ICH9_PMIO_SMI_EN:
-        val = pm->smi_en;
-        break;
-
     default:
         val = pm_ioport_read_fallback(opaque, addr, 4);
         break;
@@ -223,6 +213,38 @@ static const MemoryRegionOps ich9_gpe_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
+static uint64_t ich9_smi_readl(void *opaque, hwaddr addr, unsigned width)
+{
+    ICH9LPCPMRegs *pm = opaque;
+    switch (addr) {
+    case 0:
+        return pm->smi_en;
+    case 4:
+        return pm->smi_sts;
+    default:
+        return 0;
+    }
+}
+
+static void ich9_smi_writel(void *opaque, hwaddr addr, uint64_t val,
+                            unsigned width)
+{
+    ICH9LPCPMRegs *pm = opaque;
+    switch (addr) {
+    case 0:
+        pm->smi_en = val;
+        break;
+    }
+}
+
+static const MemoryRegionOps ich9_smi_ops = {
+    .read = ich9_smi_readl,
+    .write = ich9_smi_writel,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 4,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base)
 {
     ICH9_DEBUG("to 0x%x\n", pm_io_base);
@@ -318,6 +340,10 @@ void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3)
                           ICH9_PMIO_GPE0_LEN);
     memory_region_add_subregion(&pm->io, ICH9_PMIO_GPE0_STS, &pm->io_gpe);
 
+    memory_region_init_io(&pm->io_smi, &ich9_smi_ops, pm, "apci-smi",
+                          8);
+    memory_region_add_subregion(&pm->io, ICH9_PMIO_SMI_EN, &pm->io_smi);
+
     pm->irq = sci_irq;
     qemu_register_reset(pm_reset, pm);
     pm->powerdown_notifier.notify = pm_powerdown_req;
diff --git a/hw/acpi_ich9.h b/hw/acpi_ich9.h
index f3b05d7..bc221d3 100644
--- a/hw/acpi_ich9.h
+++ b/hw/acpi_ich9.h
@@ -32,6 +32,7 @@ typedef struct ICH9LPCPMRegs {
     ACPIREGS acpi_regs;
     MemoryRegion io;
     MemoryRegion io_gpe;
+    MemoryRegion io_smi;
     uint32_t smi_en;
     uint32_t smi_sts;
 
commit 76a7daf97458c55b8d8e6d4eadc5c46b16c705ce
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Nov 22 13:43:17 2012 +0100

    apci: switch ich9 gpe to memory api
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
index 3b5bac6..5fc160a 100644
--- a/hw/acpi_ich9.c
+++ b/hw/acpi_ich9.c
@@ -73,12 +73,7 @@ static void ich9_pm_update_sci_fn(ACPIREGS *regs)
 
 static void pm_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
 {
-    ICH9LPCPMRegs *pm = opaque;
-
     switch (addr & ICH9_PMIO_MASK) {
-    case ICH9_PMIO_GPE0_STS ... (ICH9_PMIO_GPE0_STS + ICH9_PMIO_GPE0_LEN - 1):
-        acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val);
-        break;
     default:
         break;
     }
@@ -88,13 +83,9 @@ static void pm_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
 
 static uint32_t pm_ioport_readb(void *opaque, uint32_t addr)
 {
-    ICH9LPCPMRegs *pm = opaque;
     uint32_t val = 0;
 
     switch (addr & ICH9_PMIO_MASK) {
-    case ICH9_PMIO_GPE0_STS ... (ICH9_PMIO_GPE0_STS + ICH9_PMIO_GPE0_LEN - 1):
-        val = acpi_gpe_ioport_readb(&pm->acpi_regs, addr);
-        break;
     default:
         val = 0;
         break;
@@ -209,6 +200,29 @@ static const MemoryRegionOps pm_io_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
+static uint64_t ich9_gpe_readb(void *opaque, hwaddr addr, unsigned width)
+{
+    ICH9LPCPMRegs *pm = opaque;
+    return acpi_gpe_ioport_readb(&pm->acpi_regs, addr);
+}
+
+static void ich9_gpe_writeb(void *opaque, hwaddr addr, uint64_t val,
+                            unsigned width)
+{
+    ICH9LPCPMRegs *pm = opaque;
+    acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val);
+}
+
+static const MemoryRegionOps ich9_gpe_ops = {
+    .read = ich9_gpe_readb,
+    .write = ich9_gpe_writeb,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 4,
+    .impl.min_access_size = 1,
+    .impl.max_access_size = 1,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base)
 {
     ICH9_DEBUG("to 0x%x\n", pm_io_base);
@@ -297,8 +311,12 @@ void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3)
     acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
     acpi_pm1_evt_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
     acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io);
+
     acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN);
-    acpi_gpe_blk(&pm->acpi_regs, ICH9_PMIO_GPE0_STS);
+    acpi_gpe_blk(&pm->acpi_regs, 0);
+    memory_region_init_io(&pm->io_gpe, &ich9_gpe_ops, pm, "apci-gpe0",
+                          ICH9_PMIO_GPE0_LEN);
+    memory_region_add_subregion(&pm->io, ICH9_PMIO_GPE0_STS, &pm->io_gpe);
 
     pm->irq = sci_irq;
     qemu_register_reset(pm_reset, pm);
diff --git a/hw/acpi_ich9.h b/hw/acpi_ich9.h
index 0a2ee6c..f3b05d7 100644
--- a/hw/acpi_ich9.h
+++ b/hw/acpi_ich9.h
@@ -31,6 +31,7 @@ typedef struct ICH9LPCPMRegs {
      */
     ACPIREGS acpi_regs;
     MemoryRegion io;
+    MemoryRegion io_gpe;
     uint32_t smi_en;
     uint32_t smi_sts;
 
commit a0f95659da77c8818ebd146bb1546ad152d0833e
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Nov 23 09:00:25 2012 +0100

    acpi: cleanup vt82c686 memory region
    
    Nothing left to do, everything handled by subregions,
    we can zap the reaw/write handlers now.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 52f46f1..99e6b2f 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -197,65 +197,6 @@ static void pm_tmr_timer(ACPIREGS *ar)
     pm_update_sci(s);
 }
 
-static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
-{
-    addr &= 0x0f;
-    switch (addr) {
-    default:
-        break;
-    }
-    DPRINTF("PM writew port=0x%04x val=0x%02x\n", addr, val);
-}
-
-static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
-{
-    uint32_t val;
-
-    addr &= 0x0f;
-    switch (addr) {
-    default:
-        val = 0;
-        break;
-    }
-    DPRINTF("PM readw port=0x%04x val=0x%02x\n", addr, val);
-    return val;
-}
-
-static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
-{
-    addr &= 0x0f;
-    DPRINTF("PM writel port=0x%04x val=0x%08x\n", addr, val);
-}
-
-static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
-{
-    uint32_t val;
-
-    addr &= 0x0f;
-    switch (addr) {
-    default:
-        val = 0;
-        break;
-    }
-    DPRINTF("PM readl port=0x%04x val=0x%08x\n", addr, val);
-    return val;
-}
-
-static const MemoryRegionOps pm_io_ops = {
-    .old_portio = (MemoryRegionPortio[]) {
-        { .offset = 0, .len = 64, .size = 2,
-          .read = pm_ioport_readw, .write = pm_ioport_writew },
-        { .offset = 0, .len = 64, .size = 4,
-          .read = pm_ioport_readl, .write = pm_ioport_writel },
-        PORTIO_END_OF_LIST(),
-    },
-    .valid.min_access_size = 1,
-    .valid.max_access_size = 4,
-    .impl.min_access_size = 1,
-    .impl.max_access_size = 4,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
 static void pm_io_space_update(VT686PMState *s)
 {
     uint32_t pm_io_base;
@@ -415,7 +356,7 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
 
     apm_init(&s->apm, NULL, s);
 
-    memory_region_init_io(&s->io, &pm_io_ops, s, "vt82c686-pm", 64);
+    memory_region_init(&s->io, "vt82c686-pm", 64);
     memory_region_set_enabled(&s->io, false);
     memory_region_add_subregion(get_system_io(), 0, &s->io);
 
commit ca5d64b4b4fbb01e403f89ec9b399aaa69104b1e
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Nov 22 13:27:04 2012 +0100

    acpi: cleanup piix4 memory region
    
    Nothing left to do, everything handled by subregions,
    we can zap the reaw/write handlers now.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index d4e28c4..cf8aa3d 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -110,45 +110,6 @@ static void pm_tmr_timer(ACPIREGS *ar)
     pm_update_sci(s);
 }
 
-static void pm_ioport_write(void *opaque, hwaddr addr, uint64_t val,
-                            unsigned width)
-{
-    if (width != 2) {
-        PIIX4_DPRINTF("PM write port=0x%04x width=%d val=0x%08x\n",
-                      (unsigned)addr, width, (unsigned)val);
-    }
-
-    switch(addr) {
-    default:
-        break;
-    }
-    PIIX4_DPRINTF("PM writew port=0x%04x val=0x%04x\n", (unsigned int)addr,
-                  (unsigned int)val);
-}
-
-static uint64_t pm_ioport_read(void *opaque, hwaddr addr, unsigned width)
-{
-    uint32_t val;
-
-    switch(addr) {
-    default:
-        val = 0;
-        break;
-    }
-    PIIX4_DPRINTF("PM readw port=0x%04x val=0x%04x\n", (unsigned int)addr, val);
-    return val;
-}
-
-static const MemoryRegionOps pm_io_ops = {
-    .read = pm_ioport_read,
-    .write = pm_ioport_write,
-    .valid.min_access_size = 1,
-    .valid.max_access_size = 4,
-    .impl.min_access_size = 1,
-    .impl.max_access_size = 4,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
 static void apm_ctrl_changed(uint32_t val, void *arg)
 {
     PIIX4PMState *s = arg;
@@ -433,7 +394,7 @@ static int piix4_pm_initfn(PCIDevice *dev)
     register_ioport_write(s->smb_io_base, 64, 1, smb_ioport_writeb, &s->smb);
     register_ioport_read(s->smb_io_base, 64, 1, smb_ioport_readb, &s->smb);
 
-    memory_region_init_io(&s->io, &pm_io_ops, s, "piix4-pm", 64);
+    memory_region_init(&s->io, "piix4-pm", 64);
     memory_region_set_enabled(&s->io, false);
     memory_region_add_subregion(get_system_io(), 0, &s->io);
 
commit b5a7c024d2606e84e0bbe4a0e87d252dfda41479
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Nov 22 13:25:10 2012 +0100

    apci: switch evt to memory api
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/acpi.c b/hw/acpi.c
index 956db95..e58e45f 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -275,7 +275,7 @@ uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar)
     return ar->pm1.evt.sts;
 }
 
-void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val)
+static void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val)
 {
     uint16_t pm1_sts = acpi_pm1_evt_get_sts(ar);
     if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) {
@@ -285,7 +285,7 @@ void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val)
     ar->pm1.evt.sts &= ~val;
 }
 
-void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val)
+static void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val)
 {
     ar->pm1.evt.en = val;
     qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC,
@@ -310,6 +310,51 @@ void acpi_pm1_evt_reset(ACPIREGS *ar)
     qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER, 0);
 }
 
+static uint64_t acpi_pm_evt_read(void *opaque, hwaddr addr, unsigned width)
+{
+    ACPIREGS *ar = opaque;
+    switch (addr) {
+    case 0:
+        return acpi_pm1_evt_get_sts(ar);
+    case 2:
+        return ar->pm1.evt.en;
+    default:
+        return 0;
+    }
+}
+
+static void acpi_pm_evt_write(void *opaque, hwaddr addr, uint64_t val,
+                              unsigned width)
+{
+    ACPIREGS *ar = opaque;
+    switch (addr) {
+    case 0:
+        acpi_pm1_evt_write_sts(ar, val);
+        ar->pm1.evt.update_sci(ar);
+        break;
+    case 2:
+        acpi_pm1_evt_write_en(ar, val);
+        ar->pm1.evt.update_sci(ar);
+        break;
+    }
+}
+
+static const MemoryRegionOps acpi_pm_evt_ops = {
+    .read = acpi_pm_evt_read,
+    .write = acpi_pm_evt_write,
+    .valid.min_access_size = 2,
+    .valid.max_access_size = 2,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+void acpi_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
+                       MemoryRegion *parent)
+{
+    ar->pm1.evt.update_sci = update_sci;
+    memory_region_init_io(&ar->pm1.evt.io, &acpi_pm_evt_ops, ar, "acpi-evt", 4);
+    memory_region_add_subregion(parent, 0, &ar->pm1.evt.io);
+}
+
 /* ACPI PM_TMR */
 void acpi_pm_tmr_update(ACPIREGS *ar, bool enable)
 {
diff --git a/hw/acpi.h b/hw/acpi.h
index 97aaab8..918d7f5 100644
--- a/hw/acpi.h
+++ b/hw/acpi.h
@@ -91,8 +91,10 @@ struct ACPIPMTimer {
 };
 
 struct ACPIPM1EVT {
+    MemoryRegion io;
     uint16_t sts;
     uint16_t en;
+    acpi_update_sci_fn update_sci;
 };
 
 struct ACPIPM1CNT {
@@ -135,10 +137,10 @@ static inline int64_t acpi_pm_tmr_get_clock(void)
 
 /* PM1a_EVT: piix and ich9 don't implement PM1b. */
 uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar);
-void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val);
-void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val);
 void acpi_pm1_evt_power_down(ACPIREGS *ar);
 void acpi_pm1_evt_reset(ACPIREGS *ar);
+void acpi_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
+                       MemoryRegion *parent);
 
 /* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */
 void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent);
diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
index 7b6c2ef..3b5bac6 100644
--- a/hw/acpi_ich9.c
+++ b/hw/acpi_ich9.c
@@ -105,17 +105,7 @@ static uint32_t pm_ioport_readb(void *opaque, uint32_t addr)
 
 static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
 {
-    ICH9LPCPMRegs *pm = opaque;
-
     switch (addr & ICH9_PMIO_MASK) {
-    case ICH9_PMIO_PM1_STS:
-        acpi_pm1_evt_write_sts(&pm->acpi_regs, val);
-        pm_update_sci(pm);
-        break;
-    case ICH9_PMIO_PM1_EN:
-        pm->acpi_regs.pm1.evt.en = val;
-        pm_update_sci(pm);
-        break;
     default:
         pm_ioport_write_fallback(opaque, addr, 2, val);
         break;
@@ -125,16 +115,9 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
 
 static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
 {
-    ICH9LPCPMRegs *pm = opaque;
     uint32_t val;
 
     switch (addr & ICH9_PMIO_MASK) {
-    case ICH9_PMIO_PM1_STS:
-        val = acpi_pm1_evt_get_sts(&pm->acpi_regs);
-        break;
-    case ICH9_PMIO_PM1_EN:
-        val = pm->acpi_regs.pm1.evt.en;
-        break;
     default:
         val = pm_ioport_read_fallback(opaque, addr, 2);
         break;
@@ -312,6 +295,7 @@ void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3)
     memory_region_add_subregion(get_system_io(), 0, &pm->io);
 
     acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
+    acpi_pm1_evt_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
     acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io);
     acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN);
     acpi_gpe_blk(&pm->acpi_regs, ICH9_PMIO_GPE0_STS);
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 9d5e346..d4e28c4 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -113,22 +113,12 @@ static void pm_tmr_timer(ACPIREGS *ar)
 static void pm_ioport_write(void *opaque, hwaddr addr, uint64_t val,
                             unsigned width)
 {
-    PIIX4PMState *s = opaque;
-
     if (width != 2) {
         PIIX4_DPRINTF("PM write port=0x%04x width=%d val=0x%08x\n",
                       (unsigned)addr, width, (unsigned)val);
     }
 
     switch(addr) {
-    case 0x00:
-        acpi_pm1_evt_write_sts(&s->ar, val);
-        pm_update_sci(s);
-        break;
-    case 0x02:
-        acpi_pm1_evt_write_en(&s->ar, val);
-        pm_update_sci(s);
-        break;
     default:
         break;
     }
@@ -138,16 +128,9 @@ static void pm_ioport_write(void *opaque, hwaddr addr, uint64_t val,
 
 static uint64_t pm_ioport_read(void *opaque, hwaddr addr, unsigned width)
 {
-    PIIX4PMState *s = opaque;
     uint32_t val;
 
     switch(addr) {
-    case 0x00:
-        val = acpi_pm1_evt_get_sts(&s->ar);
-        break;
-    case 0x02:
-        val = s->ar.pm1.evt.en;
-        break;
     default:
         val = 0;
         break;
@@ -455,6 +438,7 @@ static int piix4_pm_initfn(PCIDevice *dev)
     memory_region_add_subregion(get_system_io(), 0, &s->io);
 
     acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
+    acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
     acpi_pm1_cnt_init(&s->ar, &s->io);
     acpi_gpe_init(&s->ar, GPE_LEN);
 
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 15f0b6a..52f46f1 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -199,18 +199,8 @@ static void pm_tmr_timer(ACPIREGS *ar)
 
 static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
 {
-    VT686PMState *s = opaque;
-
     addr &= 0x0f;
     switch (addr) {
-    case 0x00:
-        acpi_pm1_evt_write_sts(&s->ar, val);
-        pm_update_sci(s);
-        break;
-    case 0x02:
-        acpi_pm1_evt_write_en(&s->ar, val);
-        pm_update_sci(s);
-        break;
     default:
         break;
     }
@@ -219,17 +209,10 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
 
 static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
 {
-    VT686PMState *s = opaque;
     uint32_t val;
 
     addr &= 0x0f;
     switch (addr) {
-    case 0x00:
-        val = acpi_pm1_evt_get_sts(&s->ar);
-        break;
-    case 0x02:
-        val = s->ar.pm1.evt.en;
-        break;
     default:
         val = 0;
         break;
@@ -437,6 +420,7 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
     memory_region_add_subregion(get_system_io(), 0, &s->io);
 
     acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
+    acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
     acpi_pm1_cnt_init(&s->ar, &s->io);
 
     pm_smbus_init(&s->dev.qdev, &s->smb);
commit afafe4bbe0cf7d3318e1ac7b40925561f86a6bd4
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Nov 22 13:17:57 2012 +0100

    apci: switch cnt to memory api
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/acpi.c b/hw/acpi.c
index ba25c23..956db95 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -372,13 +372,7 @@ void acpi_pm_tmr_reset(ACPIREGS *ar)
 }
 
 /* ACPI PM1aCNT */
-void acpi_pm1_cnt_init(ACPIREGS *ar)
-{
-    ar->wakeup.notify = acpi_notify_wakeup;
-    qemu_register_wakeup_notifier(&ar->wakeup);
-}
-
-void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val, char s4)
+static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val)
 {
     ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
 
@@ -393,7 +387,7 @@ void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val, char s4)
             qemu_system_suspend_request();
             break;
         default:
-            if (sus_typ == s4) { /* S4 request */
+            if (sus_typ == ar->pm1.cnt.s4_val) { /* S4 request */
                 monitor_protocol_event(QEVENT_SUSPEND_DISK, NULL);
                 qemu_system_shutdown_request();
             }
@@ -413,6 +407,34 @@ void acpi_pm1_cnt_update(ACPIREGS *ar,
     }
 }
 
+static uint64_t acpi_pm_cnt_read(void *opaque, hwaddr addr, unsigned width)
+{
+    ACPIREGS *ar = opaque;
+    return ar->pm1.cnt.cnt;
+}
+
+static void acpi_pm_cnt_write(void *opaque, hwaddr addr, uint64_t val,
+                              unsigned width)
+{
+    acpi_pm1_cnt_write(opaque, val);
+}
+
+static const MemoryRegionOps acpi_pm_cnt_ops = {
+    .read = acpi_pm_cnt_read,
+    .write = acpi_pm_cnt_write,
+    .valid.min_access_size = 2,
+    .valid.max_access_size = 2,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent)
+{
+    ar->wakeup.notify = acpi_notify_wakeup;
+    qemu_register_wakeup_notifier(&ar->wakeup);
+    memory_region_init_io(&ar->pm1.cnt.io, &acpi_pm_cnt_ops, ar, "acpi-cnt", 2);
+    memory_region_add_subregion(parent, 4, &ar->pm1.cnt.io);
+}
+
 void acpi_pm1_cnt_reset(ACPIREGS *ar)
 {
     ar->pm1.cnt.cnt = 0;
diff --git a/hw/acpi.h b/hw/acpi.h
index 91f42c3..97aaab8 100644
--- a/hw/acpi.h
+++ b/hw/acpi.h
@@ -96,7 +96,9 @@ struct ACPIPM1EVT {
 };
 
 struct ACPIPM1CNT {
+    MemoryRegion io;
     uint16_t cnt;
+    uint8_t s4_val;
 };
 
 struct ACPIGPE {
@@ -139,8 +141,7 @@ void acpi_pm1_evt_power_down(ACPIREGS *ar);
 void acpi_pm1_evt_reset(ACPIREGS *ar);
 
 /* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */
-void acpi_pm1_cnt_init(ACPIREGS *ar);
-void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val, char s4);
+void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent);
 void acpi_pm1_cnt_update(ACPIREGS *ar,
                          bool sci_enable, bool sci_disable);
 void acpi_pm1_cnt_reset(ACPIREGS *ar);
diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
index ec6d5f2..7b6c2ef 100644
--- a/hw/acpi_ich9.c
+++ b/hw/acpi_ich9.c
@@ -116,9 +116,6 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
         pm->acpi_regs.pm1.evt.en = val;
         pm_update_sci(pm);
         break;
-    case ICH9_PMIO_PM1_CNT:
-        acpi_pm1_cnt_write(&pm->acpi_regs, val, 0);
-        break;
     default:
         pm_ioport_write_fallback(opaque, addr, 2, val);
         break;
@@ -138,9 +135,6 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
     case ICH9_PMIO_PM1_EN:
         val = pm->acpi_regs.pm1.evt.en;
         break;
-    case ICH9_PMIO_PM1_CNT:
-        val = pm->acpi_regs.pm1.cnt.cnt;
-        break;
     default:
         val = pm_ioport_read_fallback(opaque, addr, 2);
         break;
@@ -318,7 +312,7 @@ void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3)
     memory_region_add_subregion(get_system_io(), 0, &pm->io);
 
     acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
-    acpi_pm1_cnt_init(&pm->acpi_regs);
+    acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io);
     acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN);
     acpi_gpe_blk(&pm->acpi_regs, ICH9_PMIO_GPE0_STS);
 
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 75761a0..9d5e346 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -129,9 +129,6 @@ static void pm_ioport_write(void *opaque, hwaddr addr, uint64_t val,
         acpi_pm1_evt_write_en(&s->ar, val);
         pm_update_sci(s);
         break;
-    case 0x04:
-        acpi_pm1_cnt_write(&s->ar, val, s->s4_val);
-        break;
     default:
         break;
     }
@@ -151,9 +148,6 @@ static uint64_t pm_ioport_read(void *opaque, hwaddr addr, unsigned width)
     case 0x02:
         val = s->ar.pm1.evt.en;
         break;
-    case 0x04:
-        val = s->ar.pm1.cnt.cnt;
-        break;
     default:
         val = 0;
         break;
@@ -461,6 +455,7 @@ static int piix4_pm_initfn(PCIDevice *dev)
     memory_region_add_subregion(get_system_io(), 0, &s->io);
 
     acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
+    acpi_pm1_cnt_init(&s->ar, &s->io);
     acpi_gpe_init(&s->ar, GPE_LEN);
 
     s->powerdown_notifier.notify = piix4_pm_powerdown_req;
@@ -487,7 +482,6 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
 
     s = DO_UPCAST(PIIX4PMState, dev, dev);
     s->irq = sci_irq;
-    acpi_pm1_cnt_init(&s->ar);
     s->smi_irq = smi_irq;
     s->kvm_enabled = kvm_enabled;
 
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 219cfae..15f0b6a 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -211,9 +211,6 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
         acpi_pm1_evt_write_en(&s->ar, val);
         pm_update_sci(s);
         break;
-    case 0x04:
-        acpi_pm1_cnt_write(&s->ar, val, 0);
-        break;
     default:
         break;
     }
@@ -233,9 +230,6 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
     case 0x02:
         val = s->ar.pm1.evt.en;
         break;
-    case 0x04:
-        val = s->ar.pm1.cnt.cnt;
-        break;
     default:
         val = 0;
         break;
@@ -443,7 +437,7 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
     memory_region_add_subregion(get_system_io(), 0, &s->io);
 
     acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
-    acpi_pm1_cnt_init(&s->ar);
+    acpi_pm1_cnt_init(&s->ar, &s->io);
 
     pm_smbus_init(&s->dev.qdev, &s->smb);
 
commit 77d58b1e47c8d1c661f98f12b47ab519d3561488
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Nov 22 12:12:30 2012 +0100

    apci: switch timer to memory api
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/acpi.c b/hw/acpi.c
index f4aca49..ba25c23 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -331,7 +331,7 @@ void acpi_pm_tmr_calc_overflow_time(ACPIREGS *ar)
     ar->tmr.overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
 }
 
-uint32_t acpi_pm_tmr_get(ACPIREGS *ar)
+static uint32_t acpi_pm_tmr_get(ACPIREGS *ar)
 {
     uint32_t d = acpi_pm_tmr_get_clock();
     return d & 0xffffff;
@@ -344,10 +344,25 @@ static void acpi_pm_tmr_timer(void *opaque)
     ar->tmr.update_sci(ar);
 }
 
-void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci)
+static uint64_t acpi_pm_tmr_read(void *opaque, hwaddr addr, unsigned width)
+{
+    return acpi_pm_tmr_get(opaque);
+}
+
+static const MemoryRegionOps acpi_pm_tmr_ops = {
+    .read = acpi_pm_tmr_read,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 4,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
+                      MemoryRegion *parent)
 {
     ar->tmr.update_sci = update_sci;
     ar->tmr.timer = qemu_new_timer_ns(vm_clock, acpi_pm_tmr_timer, ar);
+    memory_region_init_io(&ar->tmr.io, &acpi_pm_tmr_ops, ar, "acpi-tmr", 4);
+    memory_region_add_subregion(parent, 8, &ar->tmr.io);
 }
 
 void acpi_pm_tmr_reset(ACPIREGS *ar)
diff --git a/hw/acpi.h b/hw/acpi.h
index 7337f41..91f42c3 100644
--- a/hw/acpi.h
+++ b/hw/acpi.h
@@ -84,6 +84,7 @@ typedef void (*acpi_update_sci_fn)(ACPIREGS *ar);
 
 struct ACPIPMTimer {
     QEMUTimer *timer;
+    MemoryRegion io;
     int64_t overflow_time;
 
     acpi_update_sci_fn update_sci;
@@ -119,8 +120,8 @@ struct ACPIREGS {
 /* PM_TMR */
 void acpi_pm_tmr_update(ACPIREGS *ar, bool enable);
 void acpi_pm_tmr_calc_overflow_time(ACPIREGS *ar);
-uint32_t acpi_pm_tmr_get(ACPIREGS *ar);
-void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci);
+void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
+                      MemoryRegion *parent);
 void acpi_pm_tmr_reset(ACPIREGS *ar);
 
 #include "qemu-timer.h"
diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
index bf361ec..ec6d5f2 100644
--- a/hw/acpi_ich9.c
+++ b/hw/acpi_ich9.c
@@ -170,9 +170,6 @@ static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
     uint32_t val;
 
     switch (addr & ICH9_PMIO_MASK) {
-    case ICH9_PMIO_PM1_TMR:
-        val = acpi_pm_tmr_get(&pm->acpi_regs);
-        break;
     case ICH9_PMIO_SMI_EN:
         val = pm->smi_en;
         break;
@@ -320,7 +317,7 @@ void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3)
     memory_region_set_enabled(&pm->io, false);
     memory_region_add_subregion(get_system_io(), 0, &pm->io);
 
-    acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn);
+    acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
     acpi_pm1_cnt_init(&pm->acpi_regs);
     acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN);
     acpi_gpe_blk(&pm->acpi_regs, ICH9_PMIO_GPE0_STS);
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 320e045..75761a0 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -154,9 +154,6 @@ static uint64_t pm_ioport_read(void *opaque, hwaddr addr, unsigned width)
     case 0x04:
         val = s->ar.pm1.cnt.cnt;
         break;
-    case 0x08:
-        val = acpi_pm_tmr_get(&s->ar);
-        break;
     default:
         val = 0;
         break;
@@ -463,7 +460,7 @@ static int piix4_pm_initfn(PCIDevice *dev)
     memory_region_set_enabled(&s->io, false);
     memory_region_add_subregion(get_system_io(), 0, &s->io);
 
-    acpi_pm_tmr_init(&s->ar, pm_tmr_timer);
+    acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
     acpi_gpe_init(&s->ar, GPE_LEN);
 
     s->powerdown_notifier.notify = piix4_pm_powerdown_req;
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 3fc6063..219cfae 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -252,14 +252,10 @@ static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
 
 static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
 {
-    VT686PMState *s = opaque;
     uint32_t val;
 
     addr &= 0x0f;
     switch (addr) {
-    case 0x08:
-        val = acpi_pm_tmr_get(&s->ar);
-        break;
     default:
         val = 0;
         break;
@@ -446,7 +442,7 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
     memory_region_set_enabled(&s->io, false);
     memory_region_add_subregion(get_system_io(), 0, &s->io);
 
-    acpi_pm_tmr_init(&s->ar, pm_tmr_timer);
+    acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
     acpi_pm1_cnt_init(&s->ar);
 
     pm_smbus_init(&s->dev.qdev, &s->smb);
commit a29028214c1d5d3571b27e6745f14534e6d8a662
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Nov 23 08:29:27 2012 +0100

    apci: switch vt82c686 to memory api
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 5d7c00c..3fc6063 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -24,6 +24,7 @@
 #include "pm_smbus.h"
 #include "sysemu.h"
 #include "qemu-timer.h"
+#include "exec-memory.h"
 
 typedef uint32_t pci_addr_t;
 #include "pci_host.h"
@@ -159,6 +160,7 @@ static void vt82c686b_write_config(PCIDevice * d, uint32_t address,
 
 typedef struct VT686PMState {
     PCIDevice dev;
+    MemoryRegion io;
     ACPIREGS ar;
     APMState apm;
     PMSMBus smb;
@@ -266,21 +268,32 @@ static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
     return val;
 }
 
+static const MemoryRegionOps pm_io_ops = {
+    .old_portio = (MemoryRegionPortio[]) {
+        { .offset = 0, .len = 64, .size = 2,
+          .read = pm_ioport_readw, .write = pm_ioport_writew },
+        { .offset = 0, .len = 64, .size = 4,
+          .read = pm_ioport_readl, .write = pm_ioport_writel },
+        PORTIO_END_OF_LIST(),
+    },
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 4,
+    .impl.min_access_size = 1,
+    .impl.max_access_size = 4,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static void pm_io_space_update(VT686PMState *s)
 {
     uint32_t pm_io_base;
 
-    if (s->dev.config[0x80] & 1) {
-        pm_io_base = pci_get_long(s->dev.config + 0x40);
-        pm_io_base &= 0xffc0;
+    pm_io_base = pci_get_long(s->dev.config + 0x40);
+    pm_io_base &= 0xffc0;
 
-        /* XXX: need to improve memory and ioport allocation */
-        DPRINTF("PM: mapping to 0x%x\n", pm_io_base);
-        register_ioport_write(pm_io_base, 64, 2, pm_ioport_writew, s);
-        register_ioport_read(pm_io_base, 64, 2, pm_ioport_readw, s);
-        register_ioport_write(pm_io_base, 64, 4, pm_ioport_writel, s);
-        register_ioport_read(pm_io_base, 64, 4, pm_ioport_readl, s);
-    }
+    memory_region_transaction_begin();
+    memory_region_set_enabled(&s->io, s->dev.config[0x80] & 1);
+    memory_region_set_address(&s->io, pm_io_base);
+    memory_region_transaction_commit();
 }
 
 static void pm_write_config(PCIDevice *d,
@@ -429,6 +442,10 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
 
     apm_init(&s->apm, NULL, s);
 
+    memory_region_init_io(&s->io, &pm_io_ops, s, "vt82c686-pm", 64);
+    memory_region_set_enabled(&s->io, false);
+    memory_region_add_subregion(get_system_io(), 0, &s->io);
+
     acpi_pm_tmr_init(&s->ar, pm_tmr_timer);
     acpi_pm1_cnt_init(&s->ar);
 
commit cacaab8bdd74608361a488aac600d609dafd53e5
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Nov 22 12:08:22 2012 +0100

    apci: switch ich9 to memory api
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
index 61034d3..bf361ec 100644
--- a/hw/acpi_ich9.c
+++ b/hw/acpi_ich9.c
@@ -29,6 +29,7 @@
 #include "sysemu.h"
 #include "acpi.h"
 #include "kvm.h"
+#include "exec-memory.h"
 
 #include "ich9.h"
 
@@ -217,30 +218,34 @@ static uint32_t pm_ioport_read_fallback(void *opaque, uint32_t addr, int len)
     return val;
 }
 
+static const MemoryRegionOps pm_io_ops = {
+    .old_portio = (MemoryRegionPortio[]) {
+        { .offset = 0, .len = ICH9_PMIO_SIZE, .size = 1,
+          .read = pm_ioport_readb, .write = pm_ioport_writeb },
+        { .offset = 0, .len = ICH9_PMIO_SIZE, .size = 2,
+          .read = pm_ioport_readw, .write = pm_ioport_writew },
+        { .offset = 0, .len = ICH9_PMIO_SIZE, .size = 4,
+          .read = pm_ioport_readl, .write = pm_ioport_writel },
+        PORTIO_END_OF_LIST(),
+    },
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 4,
+    .impl.min_access_size = 1,
+    .impl.max_access_size = 4,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base)
 {
     ICH9_DEBUG("to 0x%x\n", pm_io_base);
 
     assert((pm_io_base & ICH9_PMIO_MASK) == 0);
 
-    if (pm->pm_io_base != 0) {
-        isa_unassign_ioport(pm->pm_io_base, ICH9_PMIO_SIZE);
-    }
-
-    /* don't map at 0 */
-    if (pm_io_base == 0) {
-        return;
-    }
-
-    register_ioport_write(pm_io_base, ICH9_PMIO_SIZE, 1, pm_ioport_writeb, pm);
-    register_ioport_read(pm_io_base, ICH9_PMIO_SIZE, 1, pm_ioport_readb, pm);
-    register_ioport_write(pm_io_base, ICH9_PMIO_SIZE, 2, pm_ioport_writew, pm);
-    register_ioport_read(pm_io_base, ICH9_PMIO_SIZE, 2, pm_ioport_readw, pm);
-    register_ioport_write(pm_io_base, ICH9_PMIO_SIZE, 4, pm_ioport_writel, pm);
-    register_ioport_read(pm_io_base, ICH9_PMIO_SIZE, 4, pm_ioport_readl, pm);
-
     pm->pm_io_base = pm_io_base;
-    acpi_gpe_blk(&pm->acpi_regs, pm_io_base + ICH9_PMIO_GPE0_STS);
+    memory_region_transaction_begin();
+    memory_region_set_enabled(&pm->io, pm->pm_io_base != 0);
+    memory_region_set_address(&pm->io, pm->pm_io_base);
+    memory_region_transaction_commit();
 }
 
 static int ich9_pm_post_load(void *opaque, int version_id)
@@ -311,9 +316,14 @@ static void pm_powerdown_req(Notifier *n, void *opaque)
 
 void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3)
 {
+    memory_region_init_io(&pm->io, &pm_io_ops, pm, "ich9-pm", ICH9_PMIO_SIZE);
+    memory_region_set_enabled(&pm->io, false);
+    memory_region_add_subregion(get_system_io(), 0, &pm->io);
+
     acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn);
     acpi_pm1_cnt_init(&pm->acpi_regs);
     acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN);
+    acpi_gpe_blk(&pm->acpi_regs, ICH9_PMIO_GPE0_STS);
 
     pm->irq = sci_irq;
     qemu_register_reset(pm_reset, pm);
diff --git a/hw/acpi_ich9.h b/hw/acpi_ich9.h
index 180c406..0a2ee6c 100644
--- a/hw/acpi_ich9.h
+++ b/hw/acpi_ich9.h
@@ -30,6 +30,7 @@ typedef struct ICH9LPCPMRegs {
      * PM1a_CNT_BLK = 2 in FADT so it is defined as uint16_t.
      */
     ACPIREGS acpi_regs;
+    MemoryRegion io;
     uint32_t smi_en;
     uint32_t smi_sts;
 
commit af11110bb83166473064389faa27e8c6703b2008
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Nov 22 11:34:44 2012 +0100

    apci: switch piix4 to memory api
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 519269a..320e045 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -28,6 +28,7 @@
 #include "range.h"
 #include "ioport.h"
 #include "fw_cfg.h"
+#include "exec-memory.h"
 
 //#define DEBUG
 
@@ -55,7 +56,7 @@ struct pci_status {
 
 typedef struct PIIX4PMState {
     PCIDevice dev;
-    IORange ioport;
+    MemoryRegion io;
     ACPIREGS ar;
 
     APMState apm;
@@ -109,10 +110,10 @@ static void pm_tmr_timer(ACPIREGS *ar)
     pm_update_sci(s);
 }
 
-static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width,
-                            uint64_t val)
+static void pm_ioport_write(void *opaque, hwaddr addr, uint64_t val,
+                            unsigned width)
 {
-    PIIX4PMState *s = container_of(ioport, PIIX4PMState, ioport);
+    PIIX4PMState *s = opaque;
 
     if (width != 2) {
         PIIX4_DPRINTF("PM write port=0x%04x width=%d val=0x%08x\n",
@@ -138,10 +139,9 @@ static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width,
                   (unsigned int)val);
 }
 
-static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width,
-                            uint64_t *data)
+static uint64_t pm_ioport_read(void *opaque, hwaddr addr, unsigned width)
 {
-    PIIX4PMState *s = container_of(ioport, PIIX4PMState, ioport);
+    PIIX4PMState *s = opaque;
     uint32_t val;
 
     switch(addr) {
@@ -162,12 +162,17 @@ static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width,
         break;
     }
     PIIX4_DPRINTF("PM readw port=0x%04x val=0x%04x\n", (unsigned int)addr, val);
-    *data = val;
+    return val;
 }
 
-static const IORangeOps pm_iorange_ops = {
+static const MemoryRegionOps pm_io_ops = {
     .read = pm_ioport_read,
     .write = pm_ioport_write,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 4,
+    .impl.min_access_size = 1,
+    .impl.max_access_size = 4,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static void apm_ctrl_changed(uint32_t val, void *arg)
@@ -193,15 +198,13 @@ static void pm_io_space_update(PIIX4PMState *s)
 {
     uint32_t pm_io_base;
 
-    if (s->dev.config[0x80] & 1) {
-        pm_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x40));
-        pm_io_base &= 0xffc0;
+    pm_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x40));
+    pm_io_base &= 0xffc0;
 
-        /* XXX: need to improve memory and ioport allocation */
-        PIIX4_DPRINTF("PM: mapping to 0x%x\n", pm_io_base);
-        iorange_init(&s->ioport, &pm_iorange_ops, pm_io_base, 64);
-        ioport_register(&s->ioport);
-    }
+    memory_region_transaction_begin();
+    memory_region_set_enabled(&s->io, s->dev.config[0x80] & 1);
+    memory_region_set_address(&s->io, pm_io_base);
+    memory_region_transaction_commit();
 }
 
 static void pm_write_config(PCIDevice *d,
@@ -456,6 +459,10 @@ static int piix4_pm_initfn(PCIDevice *dev)
     register_ioport_write(s->smb_io_base, 64, 1, smb_ioport_writeb, &s->smb);
     register_ioport_read(s->smb_io_base, 64, 1, smb_ioport_readb, &s->smb);
 
+    memory_region_init_io(&s->io, &pm_io_ops, s, "piix4-pm", 64);
+    memory_region_set_enabled(&s->io, false);
+    memory_region_add_subregion(get_system_io(), 0, &s->io);
+
     acpi_pm_tmr_init(&s->ar, pm_tmr_timer);
     acpi_gpe_init(&s->ar, GPE_LEN);
 


More information about the Spice-commits mailing list