summary refs log tree commit diff stats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/9pfs/virtio-9p.h2
-rw-r--r--hw/acpi.c2
-rw-r--r--hw/an5206.c12
-rw-r--r--hw/apb_pci.c13
-rw-r--r--hw/arm-misc.h5
-rw-r--r--hw/armv7m.c22
-rw-r--r--hw/axis_dev88.c16
-rw-r--r--hw/bt.h332
-rw-r--r--hw/cirrus_vga.c2
-rw-r--r--hw/collie.c16
-rw-r--r--hw/dec_pci.c13
-rw-r--r--hw/dummy_m68k.c7
-rw-r--r--hw/flash.h23
-rw-r--r--hw/fw_cfg.c3
-rw-r--r--hw/g364fb.c361
-rw-r--r--hw/grackle_pci.c13
-rw-r--r--hw/gumstix.c28
-rw-r--r--hw/hpet_emul.h4
-rw-r--r--hw/ide/ahci.c9
-rw-r--r--hw/ide/ahci.h7
-rw-r--r--hw/ide/atapi.c33
-rw-r--r--hw/ide/core.c27
-rw-r--r--hw/ide/internal.h1
-rw-r--r--hw/ide/macio.c40
-rw-r--r--hw/integratorcp.c28
-rw-r--r--hw/leon3.c15
-rw-r--r--hw/lm32_boards.c29
-rw-r--r--hw/mainstone.c33
-rw-r--r--hw/mcf5208.c72
-rw-r--r--hw/milkymist-minimac2.c43
-rw-r--r--hw/milkymist-softusb.c48
-rw-r--r--hw/milkymist-tmu2.c2
-rw-r--r--hw/milkymist.c16
-rw-r--r--hw/mips.h7
-rw-r--r--hw/mips_jazz.c16
-rw-r--r--hw/mips_malta.c71
-rw-r--r--hw/mips_r4k.c20
-rw-r--r--hw/musicpal.c15
-rw-r--r--hw/nseries.c52
-rw-r--r--hw/omap.h14
-rw-r--r--hw/omap2.c3
-rw-r--r--hw/omap_gpmc.c713
-rw-r--r--hw/omap_sx1.c21
-rw-r--r--hw/onenand.c164
-rw-r--r--hw/pc.c4
-rw-r--r--hw/pci-stub.c2
-rw-r--r--hw/pci.c38
-rw-r--r--hw/pci_host.c86
-rw-r--r--hw/pci_host.h16
-rw-r--r--hw/pcie.c12
-rw-r--r--hw/pcie_aer.c9
-rw-r--r--hw/petalogix_ml605_mmu.c7
-rw-r--r--hw/petalogix_s3adsp1800_mmu.c8
-rw-r--r--hw/pflash_cfi01.c67
-rw-r--r--hw/pflash_cfi02.c93
-rw-r--r--hw/piix_pci.c13
-rw-r--r--hw/ppc405_boards.c63
-rw-r--r--hw/ppc4xx_pci.c10
-rw-r--r--hw/ppce500_pci.c21
-rw-r--r--hw/prep_pci.c12
-rw-r--r--hw/pxa2xx_lcd.c2
-rw-r--r--hw/qxl.c4
-rw-r--r--hw/r2d.c9
-rw-r--r--hw/rc4030.c2
-rw-r--r--hw/scsi-disk.c17
-rw-r--r--hw/sh_pci.c2
-rw-r--r--hw/smbios.c6
-rw-r--r--hw/smbios.h22
-rw-r--r--hw/srp.h10
-rw-r--r--hw/stellaris.c5
-rw-r--r--hw/stellaris_enet.c29
-rw-r--r--hw/sun4u.c8
-rw-r--r--hw/sysbus.c34
-rw-r--r--hw/sysbus.h9
-rw-r--r--hw/tusb6010.c115
-rw-r--r--hw/tusb6010.h28
-rw-r--r--hw/unin_pci.c82
-rw-r--r--hw/usb-ccid.c18
-rw-r--r--hw/vga.c1
-rw-r--r--hw/vhost.c74
-rw-r--r--hw/vhost.h2
-rw-r--r--hw/vhost_net.c16
-rw-r--r--hw/virtex_ml507.c7
-rw-r--r--hw/virtio-balloon.h2
-rw-r--r--hw/virtio-blk.c20
-rw-r--r--hw/virtio-blk.h2
-rw-r--r--hw/virtio-net.h2
-rw-r--r--hw/virtio-serial.h2
-rw-r--r--hw/vmware_vga.c2
-rw-r--r--hw/xen_disk.c5
-rw-r--r--hw/xilinx_ethlite.c27
-rw-r--r--hw/xilinx_intc.c29
-rw-r--r--hw/xilinx_timer.c31
-rw-r--r--hw/xilinx_uartlite.c32
-rw-r--r--hw/z2.c15
-rw-r--r--hw/zaurus.c2
96 files changed, 2076 insertions, 1431 deletions
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 28fe1ff3a3..9d1b508e16 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -327,7 +327,7 @@ struct virtio_9p_config
     uint16_t tag_len;
     /* Variable size tag name */
     uint8_t tag[0];
-} __attribute__((packed));
+} QEMU_PACKED;
 
 typedef struct V9fsMkState {
     V9fsPDU *pdu;
diff --git a/hw/acpi.c b/hw/acpi.c
index d04b965977..1cf35e116a 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -32,7 +32,7 @@ struct acpi_table_header {
     uint32_t oem_revision;    /* OEM revision number */
     char asl_compiler_id[4];  /* ASL compiler vendor ID */
     uint32_t asl_compiler_revision; /* ASL compiler revision number */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #define ACPI_TABLE_HDR_SIZE sizeof(struct acpi_table_header)
 #define ACPI_TABLE_PFX_SIZE sizeof(uint16_t)  /* size of the extra prefix */
diff --git a/hw/an5206.c b/hw/an5206.c
index 481ae60449..04ca420a90 100644
--- a/hw/an5206.c
+++ b/hw/an5206.c
@@ -12,7 +12,6 @@
 #include "boards.h"
 #include "loader.h"
 #include "elf.h"
-#include "exec-memory.h"
 
 #define KERNEL_LOAD_ADDR 0x10000
 #define AN5206_MBAR_ADDR 0x10000000
@@ -38,9 +37,6 @@ static void an5206_init(ram_addr_t ram_size,
     int kernel_size;
     uint64_t elf_entry;
     target_phys_addr_t entry;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
-    MemoryRegion *sram = g_new(MemoryRegion, 1);
 
     if (!cpu_model)
         cpu_model = "m5206";
@@ -56,12 +52,12 @@ static void an5206_init(ram_addr_t ram_size,
     env->rambar0 = AN5206_RAMBAR_ADDR | 1;
 
     /* DRAM at address zero */
-    memory_region_init_ram(ram, NULL, "an5206.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0, ram);
+    cpu_register_physical_memory(0, ram_size,
+        qemu_ram_alloc(NULL, "an5206.ram", ram_size) | IO_MEM_RAM);
 
     /* Internal SRAM.  */
-    memory_region_init_ram(sram, NULL, "an5206.sram", 512);
-    memory_region_add_subregion(address_space_mem, AN5206_RAMBAR_ADDR, sram);
+    cpu_register_physical_memory(AN5206_RAMBAR_ADDR, 512,
+        qemu_ram_alloc(NULL, "an5206.sram", 512) | IO_MEM_RAM);
 
     mcf5206_init(AN5206_MBAR_ADDR, env);
 
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 6ee2068128..c232946280 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -71,6 +71,7 @@ typedef struct APBState {
     PCIBus      *bus;
     MemoryRegion apb_config;
     MemoryRegion pci_config;
+    MemoryRegion pci_mmio;
     MemoryRegion pci_ioport;
     uint32_t iommu[4];
     uint32_t pci_control[16];
@@ -336,12 +337,14 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
     sysbus_mmio_map(s, 2, special_base + 0x2000000ULL);
     d = FROM_SYSBUS(APBState, s);
 
+    memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL);
+    memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio);
+
     d->bus = pci_register_bus(&d->busdev.qdev, "pci",
-                                         pci_apb_set_irq, pci_pbm_map_irq, d,
-                                         get_system_memory(),
-                                         get_system_io(),
-                                         0, 32);
-    pci_bus_set_mem_base(d->bus, mem_base);
+                              pci_apb_set_irq, pci_pbm_map_irq, d,
+                              &d->pci_mmio,
+                              get_system_io(),
+                              0, 32);
 
     for (i = 0; i < 32; i++) {
         sysbus_connect_irq(s, i, pic[i]);
diff --git a/hw/arm-misc.h b/hw/arm-misc.h
index af403a159a..f8a747289b 100644
--- a/hw/arm-misc.h
+++ b/hw/arm-misc.h
@@ -11,16 +11,13 @@
 #ifndef ARM_MISC_H
 #define ARM_MISC_H 1
 
-#include "memory.h"
-
 /* The CPU is also modeled as an interrupt controller.  */
 #define ARM_PIC_CPU_IRQ 0
 #define ARM_PIC_CPU_FIQ 1
 qemu_irq *arm_pic_init_cpu(CPUState *env);
 
 /* armv7m.c */
-qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
-                      int flash_size, int sram_size,
+qemu_irq *armv7m_init(int flash_size, int sram_size,
                       const char *kernel_filename, const char *cpu_model);
 
 /* arm_boot.c */
diff --git a/hw/armv7m.c b/hw/armv7m.c
index 28d41b82a6..a932f16a44 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -156,8 +156,7 @@ static void armv7m_reset(void *opaque)
    flash_size and sram_size are in kb.
    Returns the NVIC array.  */
 
-qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
-                      int flash_size, int sram_size,
+qemu_irq *armv7m_init(int flash_size, int sram_size,
                       const char *kernel_filename, const char *cpu_model)
 {
     CPUState *env;
@@ -170,9 +169,6 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
     uint64_t lowaddr;
     int i;
     int big_endian;
-    MemoryRegion *sram = g_new(MemoryRegion, 1);
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
-    MemoryRegion *hack = g_new(MemoryRegion, 1);
 
     flash_size *= 1024;
     sram_size *= 1024;
@@ -198,11 +194,12 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
 #endif
 
     /* Flash programming is done via the SCU, so pretend it is ROM.  */
-    memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size);
-    memory_region_set_readonly(flash, true);
-    memory_region_add_subregion(address_space_mem, 0, flash);
-    memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size);
-    memory_region_add_subregion(address_space_mem, 0x20000000, sram);
+    cpu_register_physical_memory(0, flash_size,
+                                 qemu_ram_alloc(NULL, "armv7m.flash",
+                                                flash_size) | IO_MEM_ROM);
+    cpu_register_physical_memory(0x20000000, sram_size,
+                                 qemu_ram_alloc(NULL, "armv7m.sram",
+                                                sram_size) | IO_MEM_RAM);
     armv7m_bitband_init();
 
     nvic = qdev_create(NULL, "armv7m_nvic");
@@ -235,8 +232,9 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
     /* Hack to map an additional page of ram at the top of the address
        space.  This stops qemu complaining about executing code outside RAM
        when returning from an exception.  */
-    memory_region_init_ram(hack, NULL, "armv7m.hack", 0x1000);
-    memory_region_add_subregion(address_space_mem, 0xfffff000, hack);
+    cpu_register_physical_memory(0xfffff000, 0x1000,
+                                 qemu_ram_alloc(NULL, "armv7m.hack", 
+                                                0x1000) | IO_MEM_RAM);
 
     qemu_register_reset(armv7m_reset, env);
     return pic;
diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index 73eb39d43b..06200e257a 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -31,7 +31,6 @@
 #include "elf.h"
 #include "cris-boot.h"
 #include "blockdev.h"
-#include "exec-memory.h"
 
 #define D(x)
 #define DNAND(x)
@@ -260,9 +259,8 @@ void axisdev88_init (ram_addr_t ram_size,
     int i;
     int nand_regs;
     int gpio_regs;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
-    MemoryRegion *phys_intmem = g_new(MemoryRegion, 1);
+    ram_addr_t phys_ram;
+    ram_addr_t phys_intmem;
 
     /* init CPUs */
     if (cpu_model == NULL) {
@@ -271,13 +269,15 @@ void axisdev88_init (ram_addr_t ram_size,
     env = cpu_init(cpu_model);
 
     /* allocate RAM */
-    memory_region_init_ram(phys_ram, NULL, "axisdev88.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0x40000000, phys_ram);
+    phys_ram = qemu_ram_alloc(NULL, "axisdev88.ram", ram_size);
+    cpu_register_physical_memory(0x40000000, ram_size, phys_ram | IO_MEM_RAM);
 
     /* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the 
        internal memory.  */
-    memory_region_init_ram(phys_intmem, NULL, "axisdev88.chipram", INTMEM_SIZE);
-    memory_region_add_subregion(address_space_mem, 0x38000000, phys_intmem);
+    phys_intmem = qemu_ram_alloc(NULL, "axisdev88.chipram", INTMEM_SIZE);
+    cpu_register_physical_memory(0x38000000, INTMEM_SIZE,
+                                 phys_intmem | IO_MEM_RAM);
+
 
       /* Attach a NAND flash to CS1.  */
     nand = drive_get(IF_MTD, 0, 0);
diff --git a/hw/bt.h b/hw/bt.h
index 3797254691..a48b8d4b13 100644
--- a/hw/bt.h
+++ b/hw/bt.h
@@ -26,7 +26,7 @@
 /* BD Address */
 typedef struct {
     uint8_t b[6];
-} __attribute__((packed)) bdaddr_t;
+} QEMU_PACKED bdaddr_t;
 
 #define BDADDR_ANY	(&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
 #define BDADDR_ALL	(&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}})
@@ -446,13 +446,13 @@ typedef struct {
     uint8_t	lap[3];
     uint8_t	length;		/* 1.28s units */
     uint8_t	num_rsp;
-} __attribute__ ((packed)) inquiry_cp;
+} QEMU_PACKED inquiry_cp;
 #define INQUIRY_CP_SIZE 5
 
 typedef struct {
     uint8_t		status;
     bdaddr_t	bdaddr;
-} __attribute__ ((packed)) status_bdaddr_rp;
+} QEMU_PACKED status_bdaddr_rp;
 #define STATUS_BDADDR_RP_SIZE 7
 
 #define OCF_INQUIRY_CANCEL		0x0002
@@ -464,7 +464,7 @@ typedef struct {
     uint8_t	lap[3];
     uint8_t	length;		/* 1.28s units */
     uint8_t	num_rsp;
-} __attribute__ ((packed)) periodic_inquiry_cp;
+} QEMU_PACKED periodic_inquiry_cp;
 #define PERIODIC_INQUIRY_CP_SIZE 9
 
 #define OCF_EXIT_PERIODIC_INQUIRY	0x0004
@@ -477,55 +477,55 @@ typedef struct {
     uint8_t	pscan_mode;
     uint16_t	clock_offset;
     uint8_t	role_switch;
-} __attribute__ ((packed)) create_conn_cp;
+} QEMU_PACKED create_conn_cp;
 #define CREATE_CONN_CP_SIZE 13
 
 #define OCF_DISCONNECT			0x0006
 typedef struct {
     uint16_t	handle;
     uint8_t	reason;
-} __attribute__ ((packed)) disconnect_cp;
+} QEMU_PACKED disconnect_cp;
 #define DISCONNECT_CP_SIZE 3
 
 #define OCF_ADD_SCO			0x0007
 typedef struct {
     uint16_t	handle;
     uint16_t	pkt_type;
-} __attribute__ ((packed)) add_sco_cp;
+} QEMU_PACKED add_sco_cp;
 #define ADD_SCO_CP_SIZE 4
 
 #define OCF_CREATE_CONN_CANCEL		0x0008
 typedef struct {
     uint8_t	status;
     bdaddr_t	bdaddr;
-} __attribute__ ((packed)) create_conn_cancel_cp;
+} QEMU_PACKED create_conn_cancel_cp;
 #define CREATE_CONN_CANCEL_CP_SIZE 6
 
 typedef struct {
     uint8_t	status;
     bdaddr_t	bdaddr;
-} __attribute__ ((packed)) create_conn_cancel_rp;
+} QEMU_PACKED create_conn_cancel_rp;
 #define CREATE_CONN_CANCEL_RP_SIZE 7
 
 #define OCF_ACCEPT_CONN_REQ		0x0009
 typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	role;
-} __attribute__ ((packed)) accept_conn_req_cp;
+} QEMU_PACKED accept_conn_req_cp;
 #define ACCEPT_CONN_REQ_CP_SIZE	7
 
 #define OCF_REJECT_CONN_REQ		0x000A
 typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	reason;
-} __attribute__ ((packed)) reject_conn_req_cp;
+} QEMU_PACKED reject_conn_req_cp;
 #define REJECT_CONN_REQ_CP_SIZE	7
 
 #define OCF_LINK_KEY_REPLY		0x000B
 typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	link_key[16];
-} __attribute__ ((packed)) link_key_reply_cp;
+} QEMU_PACKED link_key_reply_cp;
 #define LINK_KEY_REPLY_CP_SIZE 22
 
 #define OCF_LINK_KEY_NEG_REPLY		0x000C
@@ -535,7 +535,7 @@ typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	pin_len;
     uint8_t	pin_code[16];
-} __attribute__ ((packed)) pin_code_reply_cp;
+} QEMU_PACKED pin_code_reply_cp;
 #define PIN_CODE_REPLY_CP_SIZE 23
 
 #define OCF_PIN_CODE_NEG_REPLY		0x000E
@@ -544,32 +544,32 @@ typedef struct {
 typedef struct {
     uint16_t	 handle;
     uint16_t	 pkt_type;
-} __attribute__ ((packed)) set_conn_ptype_cp;
+} QEMU_PACKED set_conn_ptype_cp;
 #define SET_CONN_PTYPE_CP_SIZE 4
 
 #define OCF_AUTH_REQUESTED		0x0011
 typedef struct {
     uint16_t	 handle;
-} __attribute__ ((packed)) auth_requested_cp;
+} QEMU_PACKED auth_requested_cp;
 #define AUTH_REQUESTED_CP_SIZE 2
 
 #define OCF_SET_CONN_ENCRYPT		0x0013
 typedef struct {
     uint16_t	handle;
     uint8_t	encrypt;
-} __attribute__ ((packed)) set_conn_encrypt_cp;
+} QEMU_PACKED set_conn_encrypt_cp;
 #define SET_CONN_ENCRYPT_CP_SIZE 3
 
 #define OCF_CHANGE_CONN_LINK_KEY	0x0015
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) change_conn_link_key_cp;
+} QEMU_PACKED change_conn_link_key_cp;
 #define CHANGE_CONN_LINK_KEY_CP_SIZE 2
 
 #define OCF_MASTER_LINK_KEY		0x0017
 typedef struct {
     uint8_t	key_flag;
-} __attribute__ ((packed)) master_link_key_cp;
+} QEMU_PACKED master_link_key_cp;
 #define MASTER_LINK_KEY_CP_SIZE 1
 
 #define OCF_REMOTE_NAME_REQ		0x0019
@@ -578,50 +578,50 @@ typedef struct {
     uint8_t	pscan_rep_mode;
     uint8_t	pscan_mode;
     uint16_t	clock_offset;
-} __attribute__ ((packed)) remote_name_req_cp;
+} QEMU_PACKED remote_name_req_cp;
 #define REMOTE_NAME_REQ_CP_SIZE 10
 
 #define OCF_REMOTE_NAME_REQ_CANCEL	0x001A
 typedef struct {
     bdaddr_t	bdaddr;
-} __attribute__ ((packed)) remote_name_req_cancel_cp;
+} QEMU_PACKED remote_name_req_cancel_cp;
 #define REMOTE_NAME_REQ_CANCEL_CP_SIZE 6
 
 typedef struct {
     uint8_t		status;
     bdaddr_t	bdaddr;
-} __attribute__ ((packed)) remote_name_req_cancel_rp;
+} QEMU_PACKED remote_name_req_cancel_rp;
 #define REMOTE_NAME_REQ_CANCEL_RP_SIZE 7
 
 #define OCF_READ_REMOTE_FEATURES	0x001B
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) read_remote_features_cp;
+} QEMU_PACKED read_remote_features_cp;
 #define READ_REMOTE_FEATURES_CP_SIZE 2
 
 #define OCF_READ_REMOTE_EXT_FEATURES	0x001C
 typedef struct {
     uint16_t	handle;
     uint8_t	page_num;
-} __attribute__ ((packed)) read_remote_ext_features_cp;
+} QEMU_PACKED read_remote_ext_features_cp;
 #define READ_REMOTE_EXT_FEATURES_CP_SIZE 3
 
 #define OCF_READ_REMOTE_VERSION		0x001D
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) read_remote_version_cp;
+} QEMU_PACKED read_remote_version_cp;
 #define READ_REMOTE_VERSION_CP_SIZE 2
 
 #define OCF_READ_CLOCK_OFFSET		0x001F
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) read_clock_offset_cp;
+} QEMU_PACKED read_clock_offset_cp;
 #define READ_CLOCK_OFFSET_CP_SIZE 2
 
 #define OCF_READ_LMP_HANDLE		0x0020
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) read_lmp_handle_cp;
+} QEMU_PACKED read_lmp_handle_cp;
 #define READ_LMP_HANDLE_CP_SIZE 2
 
 typedef struct {
@@ -629,7 +629,7 @@ typedef struct {
     uint16_t	handle;
     uint8_t	lmp_handle;
     uint32_t	reserved;
-} __attribute__ ((packed)) read_lmp_handle_rp;
+} QEMU_PACKED read_lmp_handle_rp;
 #define READ_LMP_HANDLE_RP_SIZE 8
 
 #define OCF_SETUP_SYNC_CONN		0x0028
@@ -641,7 +641,7 @@ typedef struct {
     uint16_t	voice_setting;
     uint8_t	retrans_effort;
     uint16_t	pkt_type;
-} __attribute__ ((packed)) setup_sync_conn_cp;
+} QEMU_PACKED setup_sync_conn_cp;
 #define SETUP_SYNC_CONN_CP_SIZE 17
 
 #define OCF_ACCEPT_SYNC_CONN_REQ	0x0029
@@ -653,14 +653,14 @@ typedef struct {
     uint16_t	voice_setting;
     uint8_t	retrans_effort;
     uint16_t	pkt_type;
-} __attribute__ ((packed)) accept_sync_conn_req_cp;
+} QEMU_PACKED accept_sync_conn_req_cp;
 #define ACCEPT_SYNC_CONN_REQ_CP_SIZE 21
 
 #define OCF_REJECT_SYNC_CONN_REQ	0x002A
 typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	reason;
-} __attribute__ ((packed)) reject_sync_conn_req_cp;
+} QEMU_PACKED reject_sync_conn_req_cp;
 #define REJECT_SYNC_CONN_REQ_CP_SIZE 7
 
 /* Link Policy */
@@ -671,7 +671,7 @@ typedef struct {
     uint16_t	handle;
     uint16_t	max_interval;
     uint16_t	min_interval;
-} __attribute__ ((packed)) hold_mode_cp;
+} QEMU_PACKED hold_mode_cp;
 #define HOLD_MODE_CP_SIZE 6
 
 #define OCF_SNIFF_MODE			0x0003
@@ -681,13 +681,13 @@ typedef struct {
     uint16_t	min_interval;
     uint16_t	attempt;
     uint16_t	timeout;
-} __attribute__ ((packed)) sniff_mode_cp;
+} QEMU_PACKED sniff_mode_cp;
 #define SNIFF_MODE_CP_SIZE 10
 
 #define OCF_EXIT_SNIFF_MODE		0x0004
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) exit_sniff_mode_cp;
+} QEMU_PACKED exit_sniff_mode_cp;
 #define EXIT_SNIFF_MODE_CP_SIZE 2
 
 #define OCF_PARK_MODE			0x0005
@@ -695,13 +695,13 @@ typedef struct {
     uint16_t	handle;
     uint16_t	max_interval;
     uint16_t	min_interval;
-} __attribute__ ((packed)) park_mode_cp;
+} QEMU_PACKED park_mode_cp;
 #define PARK_MODE_CP_SIZE 6
 
 #define OCF_EXIT_PARK_MODE		0x0006
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) exit_park_mode_cp;
+} QEMU_PACKED exit_park_mode_cp;
 #define EXIT_PARK_MODE_CP_SIZE 2
 
 #define OCF_QOS_SETUP			0x0007
@@ -711,56 +711,56 @@ typedef struct {
     uint32_t	peak_bandwidth;		/* Byte per seconds */
     uint32_t	latency;		/* Microseconds */
     uint32_t	delay_variation;	/* Microseconds */
-} __attribute__ ((packed)) hci_qos;
+} QEMU_PACKED hci_qos;
 #define HCI_QOS_CP_SIZE 17
 typedef struct {
     uint16_t 	handle;
     uint8_t 	flags;			/* Reserved */
     hci_qos 	qos;
-} __attribute__ ((packed)) qos_setup_cp;
+} QEMU_PACKED qos_setup_cp;
 #define QOS_SETUP_CP_SIZE (3 + HCI_QOS_CP_SIZE)
 
 #define OCF_ROLE_DISCOVERY		0x0009
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) role_discovery_cp;
+} QEMU_PACKED role_discovery_cp;
 #define ROLE_DISCOVERY_CP_SIZE 2
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint8_t	role;
-} __attribute__ ((packed)) role_discovery_rp;
+} QEMU_PACKED role_discovery_rp;
 #define ROLE_DISCOVERY_RP_SIZE 4
 
 #define OCF_SWITCH_ROLE			0x000B
 typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	role;
-} __attribute__ ((packed)) switch_role_cp;
+} QEMU_PACKED switch_role_cp;
 #define SWITCH_ROLE_CP_SIZE 7
 
 #define OCF_READ_LINK_POLICY		0x000C
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) read_link_policy_cp;
+} QEMU_PACKED read_link_policy_cp;
 #define READ_LINK_POLICY_CP_SIZE 2
 typedef struct {
     uint8_t 	status;
     uint16_t	handle;
     uint16_t	policy;
-} __attribute__ ((packed)) read_link_policy_rp;
+} QEMU_PACKED read_link_policy_rp;
 #define READ_LINK_POLICY_RP_SIZE 5
 
 #define OCF_WRITE_LINK_POLICY		0x000D
 typedef struct {
     uint16_t	handle;
     uint16_t	policy;
-} __attribute__ ((packed)) write_link_policy_cp;
+} QEMU_PACKED write_link_policy_cp;
 #define WRITE_LINK_POLICY_CP_SIZE 4
 typedef struct {
     uint8_t 	status;
     uint16_t	handle;
-} __attribute__ ((packed)) write_link_policy_rp;
+} QEMU_PACKED write_link_policy_rp;
 #define WRITE_LINK_POLICY_RP_SIZE 3
 
 #define OCF_READ_DEFAULT_LINK_POLICY	0x000E
@@ -776,7 +776,7 @@ typedef struct {
     uint16_t	max_local_latency;
     uint16_t	min_remote_timeout;
     uint16_t	min_local_timeout;
-} __attribute__ ((packed)) sniff_subrate_cp;
+} QEMU_PACKED sniff_subrate_cp;
 #define SNIFF_SUBRATE_CP_SIZE 10
 
 /* Host Controller and Baseband */
@@ -785,7 +785,7 @@ typedef struct {
 #define OCF_SET_EVENT_MASK		0x0001
 typedef struct {
     uint8_t	mask[8];
-} __attribute__ ((packed)) set_event_mask_cp;
+} QEMU_PACKED set_event_mask_cp;
 #define SET_EVENT_MASK_CP_SIZE 8
 
 #define OCF_RESET			0x0003
@@ -795,7 +795,7 @@ typedef struct {
     uint8_t	flt_type;
     uint8_t	cond_type;
     uint8_t	condition[0];
-} __attribute__ ((packed)) set_event_flt_cp;
+} QEMU_PACKED set_event_flt_cp;
 #define SET_EVENT_FLT_CP_SIZE 2
 
 enum bt_filter_type {
@@ -821,26 +821,26 @@ enum conn_setup_cond {
 #define OCF_FLUSH			0x0008
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) flush_cp;
+} QEMU_PACKED flush_cp;
 #define FLUSH_CP_SIZE 2
 
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
-} __attribute__ ((packed)) flush_rp;
+} QEMU_PACKED flush_rp;
 #define FLUSH_RP_SIZE 3
 
 #define OCF_READ_PIN_TYPE		0x0009
 typedef struct {
     uint8_t	status;
     uint8_t	pin_type;
-} __attribute__ ((packed)) read_pin_type_rp;
+} QEMU_PACKED read_pin_type_rp;
 #define READ_PIN_TYPE_RP_SIZE 2
 
 #define OCF_WRITE_PIN_TYPE		0x000A
 typedef struct {
     uint8_t	pin_type;
-} __attribute__ ((packed)) write_pin_type_cp;
+} QEMU_PACKED write_pin_type_cp;
 #define WRITE_PIN_TYPE_CP_SIZE 1
 
 #define OCF_CREATE_NEW_UNIT_KEY		0x000B
@@ -849,89 +849,89 @@ typedef struct {
 typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	read_all;
-} __attribute__ ((packed)) read_stored_link_key_cp;
+} QEMU_PACKED read_stored_link_key_cp;
 #define READ_STORED_LINK_KEY_CP_SIZE 7
 typedef struct {
     uint8_t	status;
     uint16_t	max_keys;
     uint16_t	num_keys;
-} __attribute__ ((packed)) read_stored_link_key_rp;
+} QEMU_PACKED read_stored_link_key_rp;
 #define READ_STORED_LINK_KEY_RP_SIZE 5
 
 #define OCF_WRITE_STORED_LINK_KEY	0x0011
 typedef struct {
     uint8_t	num_keys;
     /* variable length part */
-} __attribute__ ((packed)) write_stored_link_key_cp;
+} QEMU_PACKED write_stored_link_key_cp;
 #define WRITE_STORED_LINK_KEY_CP_SIZE 1
 typedef struct {
     uint8_t	status;
     uint8_t	num_keys;
-} __attribute__ ((packed)) write_stored_link_key_rp;
+} QEMU_PACKED write_stored_link_key_rp;
 #define READ_WRITE_LINK_KEY_RP_SIZE 2
 
 #define OCF_DELETE_STORED_LINK_KEY	0x0012
 typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	delete_all;
-} __attribute__ ((packed)) delete_stored_link_key_cp;
+} QEMU_PACKED delete_stored_link_key_cp;
 #define DELETE_STORED_LINK_KEY_CP_SIZE 7
 typedef struct {
     uint8_t	status;
     uint16_t	num_keys;
-} __attribute__ ((packed)) delete_stored_link_key_rp;
+} QEMU_PACKED delete_stored_link_key_rp;
 #define DELETE_STORED_LINK_KEY_RP_SIZE 3
 
 #define OCF_CHANGE_LOCAL_NAME		0x0013
 typedef struct {
     char	name[248];
-} __attribute__ ((packed)) change_local_name_cp;
+} QEMU_PACKED change_local_name_cp;
 #define CHANGE_LOCAL_NAME_CP_SIZE 248 
 
 #define OCF_READ_LOCAL_NAME		0x0014
 typedef struct {
     uint8_t	status;
     char	name[248];
-} __attribute__ ((packed)) read_local_name_rp;
+} QEMU_PACKED read_local_name_rp;
 #define READ_LOCAL_NAME_RP_SIZE 249 
 
 #define OCF_READ_CONN_ACCEPT_TIMEOUT	0x0015
 typedef struct {
     uint8_t	status;
     uint16_t	timeout;
-} __attribute__ ((packed)) read_conn_accept_timeout_rp;
+} QEMU_PACKED read_conn_accept_timeout_rp;
 #define READ_CONN_ACCEPT_TIMEOUT_RP_SIZE 3
 
 #define OCF_WRITE_CONN_ACCEPT_TIMEOUT	0x0016
 typedef struct {
     uint16_t	timeout;
-} __attribute__ ((packed)) write_conn_accept_timeout_cp;
+} QEMU_PACKED write_conn_accept_timeout_cp;
 #define WRITE_CONN_ACCEPT_TIMEOUT_CP_SIZE 2
 
 #define OCF_READ_PAGE_TIMEOUT		0x0017
 typedef struct {
     uint8_t	status;
     uint16_t	timeout;
-} __attribute__ ((packed)) read_page_timeout_rp;
+} QEMU_PACKED read_page_timeout_rp;
 #define READ_PAGE_TIMEOUT_RP_SIZE 3
 
 #define OCF_WRITE_PAGE_TIMEOUT		0x0018
 typedef struct {
     uint16_t	timeout;
-} __attribute__ ((packed)) write_page_timeout_cp;
+} QEMU_PACKED write_page_timeout_cp;
 #define WRITE_PAGE_TIMEOUT_CP_SIZE 2
 
 #define OCF_READ_SCAN_ENABLE		0x0019
 typedef struct {
     uint8_t	status;
     uint8_t	enable;
-} __attribute__ ((packed)) read_scan_enable_rp;
+} QEMU_PACKED read_scan_enable_rp;
 #define READ_SCAN_ENABLE_RP_SIZE 2
 
 #define OCF_WRITE_SCAN_ENABLE		0x001A
 typedef struct {
     uint8_t	scan_enable;
-} __attribute__ ((packed)) write_scan_enable_cp;
+} QEMU_PACKED write_scan_enable_cp;
 #define WRITE_SCAN_ENABLE_CP_SIZE 1
 
 enum scan_enable_bits {
@@ -945,14 +945,14 @@ typedef struct {
     uint8_t	status;
     uint16_t	interval;
     uint16_t	window;
-} __attribute__ ((packed)) read_page_activity_rp;
+} QEMU_PACKED read_page_activity_rp;
 #define READ_PAGE_ACTIVITY_RP_SIZE 5
 
 #define OCF_WRITE_PAGE_ACTIVITY		0x001C
 typedef struct {
     uint16_t	interval;
     uint16_t	window;
-} __attribute__ ((packed)) write_page_activity_cp;
+} QEMU_PACKED write_page_activity_cp;
 #define WRITE_PAGE_ACTIVITY_CP_SIZE 4
 
 #define OCF_READ_INQ_ACTIVITY		0x001D
@@ -960,14 +960,14 @@ typedef struct {
     uint8_t	status;
     uint16_t	interval;
     uint16_t	window;
-} __attribute__ ((packed)) read_inq_activity_rp;
+} QEMU_PACKED read_inq_activity_rp;
 #define READ_INQ_ACTIVITY_RP_SIZE 5
 
 #define OCF_WRITE_INQ_ACTIVITY		0x001E
 typedef struct {
     uint16_t	interval;
     uint16_t	window;
-} __attribute__ ((packed)) write_inq_activity_cp;
+} QEMU_PACKED write_inq_activity_cp;
 #define WRITE_INQ_ACTIVITY_CP_SIZE 4
 
 #define OCF_READ_AUTH_ENABLE		0x001F
@@ -989,26 +989,26 @@ typedef struct {
 typedef struct {
     uint8_t	status;
     uint8_t	dev_class[3];
-} __attribute__ ((packed)) read_class_of_dev_rp;
+} QEMU_PACKED read_class_of_dev_rp;
 #define READ_CLASS_OF_DEV_RP_SIZE 4 
 
 #define OCF_WRITE_CLASS_OF_DEV		0x0024
 typedef struct {
     uint8_t	dev_class[3];
-} __attribute__ ((packed)) write_class_of_dev_cp;
+} QEMU_PACKED write_class_of_dev_cp;
 #define WRITE_CLASS_OF_DEV_CP_SIZE 3
 
 #define OCF_READ_VOICE_SETTING		0x0025
 typedef struct {
     uint8_t	status;
     uint16_t	voice_setting;
-} __attribute__ ((packed)) read_voice_setting_rp;
+} QEMU_PACKED read_voice_setting_rp;
 #define READ_VOICE_SETTING_RP_SIZE 3
 
 #define OCF_WRITE_VOICE_SETTING		0x0026
 typedef struct {
     uint16_t	voice_setting;
-} __attribute__ ((packed)) write_voice_setting_cp;
+} QEMU_PACKED write_voice_setting_cp;
 #define WRITE_VOICE_SETTING_CP_SIZE 2
 
 #define OCF_READ_AUTOMATIC_FLUSH_TIMEOUT	0x0027
@@ -1027,13 +1027,13 @@ typedef struct {
 typedef struct {
     uint16_t	handle;
     uint8_t	type;
-} __attribute__ ((packed)) read_transmit_power_level_cp;
+} QEMU_PACKED read_transmit_power_level_cp;
 #define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
     int8_t	level;
-} __attribute__ ((packed)) read_transmit_power_level_rp;
+} QEMU_PACKED read_transmit_power_level_rp;
 #define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4
 
 #define OCF_HOST_BUFFER_SIZE		0x0033
@@ -1042,7 +1042,7 @@ typedef struct {
     uint8_t	sco_mtu;
     uint16_t	acl_max_pkt;
     uint16_t	sco_max_pkt;
-} __attribute__ ((packed)) host_buffer_size_cp;
+} QEMU_PACKED host_buffer_size_cp;
 #define HOST_BUFFER_SIZE_CP_SIZE 7
 
 #define OCF_HOST_NUMBER_OF_COMPLETED_PACKETS	0x0035
@@ -1052,19 +1052,19 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint16_t	link_sup_to;
-} __attribute__ ((packed)) read_link_supervision_timeout_rp;
+} QEMU_PACKED read_link_supervision_timeout_rp;
 #define READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE 5
 
 #define OCF_WRITE_LINK_SUPERVISION_TIMEOUT	0x0037
 typedef struct {
     uint16_t	handle;
     uint16_t	link_sup_to;
-} __attribute__ ((packed)) write_link_supervision_timeout_cp;
+} QEMU_PACKED write_link_supervision_timeout_cp;
 #define WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE 4
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
-} __attribute__ ((packed)) write_link_supervision_timeout_rp;
+} QEMU_PACKED write_link_supervision_timeout_rp;
 #define WRITE_LINK_SUPERVISION_TIMEOUT_RP_SIZE 3
 
 #define OCF_READ_NUM_SUPPORTED_IAC	0x0038
@@ -1075,14 +1075,14 @@ typedef struct {
     uint8_t	status;
     uint8_t	num_current_iac;
     uint8_t	lap[MAX_IAC_LAP][3];
-} __attribute__ ((packed)) read_current_iac_lap_rp;
+} QEMU_PACKED read_current_iac_lap_rp;
 #define READ_CURRENT_IAC_LAP_RP_SIZE 2+3*MAX_IAC_LAP
 
 #define OCF_WRITE_CURRENT_IAC_LAP	0x003A
 typedef struct {
     uint8_t	num_current_iac;
     uint8_t	lap[MAX_IAC_LAP][3];
-} __attribute__ ((packed)) write_current_iac_lap_cp;
+} QEMU_PACKED write_current_iac_lap_cp;
 #define WRITE_CURRENT_IAC_LAP_CP_SIZE 1+3*MAX_IAC_LAP
 
 #define OCF_READ_PAGE_SCAN_PERIOD_MODE	0x003B
@@ -1096,45 +1096,45 @@ typedef struct {
 #define OCF_SET_AFH_CLASSIFICATION	0x003F
 typedef struct {
     uint8_t	map[10];
-} __attribute__ ((packed)) set_afh_classification_cp;
+} QEMU_PACKED set_afh_classification_cp;
 #define SET_AFH_CLASSIFICATION_CP_SIZE 10
 typedef struct {
     uint8_t	status;
-} __attribute__ ((packed)) set_afh_classification_rp;
+} QEMU_PACKED set_afh_classification_rp;
 #define SET_AFH_CLASSIFICATION_RP_SIZE 1
 
 #define OCF_READ_INQUIRY_SCAN_TYPE	0x0042
 typedef struct {
     uint8_t	status;
     uint8_t	type;
-} __attribute__ ((packed)) read_inquiry_scan_type_rp;
+} QEMU_PACKED read_inquiry_scan_type_rp;
 #define READ_INQUIRY_SCAN_TYPE_RP_SIZE 2
 
 #define OCF_WRITE_INQUIRY_SCAN_TYPE	0x0043
 typedef struct {
     uint8_t	type;
-} __attribute__ ((packed)) write_inquiry_scan_type_cp;
+} QEMU_PACKED write_inquiry_scan_type_cp;
 #define WRITE_INQUIRY_SCAN_TYPE_CP_SIZE 1
 typedef struct {
     uint8_t	status;
-} __attribute__ ((packed)) write_inquiry_scan_type_rp;
+} QEMU_PACKED write_inquiry_scan_type_rp;
 #define WRITE_INQUIRY_SCAN_TYPE_RP_SIZE 1
 
 #define OCF_READ_INQUIRY_MODE		0x0044
 typedef struct {
     uint8_t	status;
     uint8_t	mode;
-} __attribute__ ((packed)) read_inquiry_mode_rp;
+} QEMU_PACKED read_inquiry_mode_rp;
 #define READ_INQUIRY_MODE_RP_SIZE 2
 
 #define OCF_WRITE_INQUIRY_MODE		0x0045
 typedef struct {
     uint8_t	mode;
-} __attribute__ ((packed)) write_inquiry_mode_cp;
+} QEMU_PACKED write_inquiry_mode_cp;
 #define WRITE_INQUIRY_MODE_CP_SIZE 1
 typedef struct {
     uint8_t	status;
-} __attribute__ ((packed)) write_inquiry_mode_rp;
+} QEMU_PACKED write_inquiry_mode_rp;
 #define WRITE_INQUIRY_MODE_RP_SIZE 1
 
 #define OCF_READ_PAGE_SCAN_TYPE		0x0046
@@ -1145,17 +1145,17 @@ typedef struct {
 typedef struct {
     uint8_t	status;
     uint8_t	mode;
-} __attribute__ ((packed)) read_afh_mode_rp;
+} QEMU_PACKED read_afh_mode_rp;
 #define READ_AFH_MODE_RP_SIZE 2
 
 #define OCF_WRITE_AFH_MODE		0x0049
 typedef struct {
     uint8_t	mode;
-} __attribute__ ((packed)) write_afh_mode_cp;
+} QEMU_PACKED write_afh_mode_cp;
 #define WRITE_AFH_MODE_CP_SIZE 1
 typedef struct {
     uint8_t	status;
-} __attribute__ ((packed)) write_afh_mode_rp;
+} QEMU_PACKED write_afh_mode_rp;
 #define WRITE_AFH_MODE_RP_SIZE 1
 
 #define OCF_READ_EXT_INQUIRY_RESPONSE	0x0051
@@ -1163,18 +1163,18 @@ typedef struct {
     uint8_t	status;
     uint8_t	fec;
     uint8_t	data[240];
-} __attribute__ ((packed)) read_ext_inquiry_response_rp;
+} QEMU_PACKED read_ext_inquiry_response_rp;
 #define READ_EXT_INQUIRY_RESPONSE_RP_SIZE 242
 
 #define OCF_WRITE_EXT_INQUIRY_RESPONSE	0x0052
 typedef struct {
     uint8_t	fec;
     uint8_t	data[240];
-} __attribute__ ((packed)) write_ext_inquiry_response_cp;
+} QEMU_PACKED write_ext_inquiry_response_cp;
 #define WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE 241
 typedef struct {
     uint8_t	status;
-} __attribute__ ((packed)) write_ext_inquiry_response_rp;
+} QEMU_PACKED write_ext_inquiry_response_rp;
 #define WRITE_EXT_INQUIRY_RESPONSE_RP_SIZE 1
 
 /* Informational Parameters */
@@ -1188,34 +1188,34 @@ typedef struct {
     uint8_t	lmp_ver;
     uint16_t	manufacturer;
     uint16_t	lmp_subver;
-} __attribute__ ((packed)) read_local_version_rp;
+} QEMU_PACKED read_local_version_rp;
 #define READ_LOCAL_VERSION_RP_SIZE 9
 
 #define OCF_READ_LOCAL_COMMANDS		0x0002
 typedef struct {
     uint8_t	status;
     uint8_t	commands[64];
-} __attribute__ ((packed)) read_local_commands_rp;
+} QEMU_PACKED read_local_commands_rp;
 #define READ_LOCAL_COMMANDS_RP_SIZE 65
 
 #define OCF_READ_LOCAL_FEATURES		0x0003
 typedef struct {
     uint8_t	status;
     uint8_t	features[8];
-} __attribute__ ((packed)) read_local_features_rp;
+} QEMU_PACKED read_local_features_rp;
 #define READ_LOCAL_FEATURES_RP_SIZE 9
 
 #define OCF_READ_LOCAL_EXT_FEATURES	0x0004
 typedef struct {
     uint8_t	page_num;
-} __attribute__ ((packed)) read_local_ext_features_cp;
+} QEMU_PACKED read_local_ext_features_cp;
 #define READ_LOCAL_EXT_FEATURES_CP_SIZE 1
 typedef struct {
     uint8_t	status;
     uint8_t	page_num;
     uint8_t	max_page_num;
     uint8_t	features[8];
-} __attribute__ ((packed)) read_local_ext_features_rp;
+} QEMU_PACKED read_local_ext_features_rp;
 #define READ_LOCAL_EXT_FEATURES_RP_SIZE 11
 
 #define OCF_READ_BUFFER_SIZE		0x0005
@@ -1225,21 +1225,21 @@ typedef struct {
     uint8_t	sco_mtu;
     uint16_t	acl_max_pkt;
     uint16_t	sco_max_pkt;
-} __attribute__ ((packed)) read_buffer_size_rp;
+} QEMU_PACKED read_buffer_size_rp;
 #define READ_BUFFER_SIZE_RP_SIZE 8
 
 #define OCF_READ_COUNTRY_CODE		0x0007
 typedef struct {
     uint8_t	status;
     uint8_t	country_code;
-} __attribute__ ((packed)) read_country_code_rp;
+} QEMU_PACKED read_country_code_rp;
 #define READ_COUNTRY_CODE_RP_SIZE 2
 
 #define OCF_READ_BD_ADDR		0x0009
 typedef struct {
     uint8_t	status;
     bdaddr_t	bdaddr;
-} __attribute__ ((packed)) read_bd_addr_rp;
+} QEMU_PACKED read_bd_addr_rp;
 #define READ_BD_ADDR_RP_SIZE 7
 
 /* Status params */
@@ -1250,27 +1250,27 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint8_t	counter;
-} __attribute__ ((packed)) read_failed_contact_counter_rp;
+} QEMU_PACKED read_failed_contact_counter_rp;
 #define READ_FAILED_CONTACT_COUNTER_RP_SIZE 4
 
 #define OCF_RESET_FAILED_CONTACT_COUNTER	0x0002
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
-} __attribute__ ((packed)) reset_failed_contact_counter_rp;
+} QEMU_PACKED reset_failed_contact_counter_rp;
 #define RESET_FAILED_CONTACT_COUNTER_RP_SIZE 4
 
 #define OCF_READ_LINK_QUALITY		0x0003
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) read_link_quality_cp;
+} QEMU_PACKED read_link_quality_cp;
 #define READ_LINK_QUALITY_CP_SIZE 4
 
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint8_t	link_quality;
-} __attribute__ ((packed)) read_link_quality_rp;
+} QEMU_PACKED read_link_quality_rp;
 #define READ_LINK_QUALITY_RP_SIZE 4
 
 #define OCF_READ_RSSI			0x0005
@@ -1278,7 +1278,7 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     int8_t	rssi;
-} __attribute__ ((packed)) read_rssi_rp;
+} QEMU_PACKED read_rssi_rp;
 #define READ_RSSI_RP_SIZE 4
 
 #define OCF_READ_AFH_MAP		0x0006
@@ -1287,21 +1287,21 @@ typedef struct {
     uint16_t	handle;
     uint8_t	mode;
     uint8_t	map[10];
-} __attribute__ ((packed)) read_afh_map_rp;
+} QEMU_PACKED read_afh_map_rp;
 #define READ_AFH_MAP_RP_SIZE 14
 
 #define OCF_READ_CLOCK			0x0007
 typedef struct {
     uint16_t	handle;
     uint8_t	which_clock;
-} __attribute__ ((packed)) read_clock_cp;
+} QEMU_PACKED read_clock_cp;
 #define READ_CLOCK_CP_SIZE 3
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint32_t	clock;
     uint16_t	accuracy;
-} __attribute__ ((packed)) read_clock_rp;
+} QEMU_PACKED read_clock_rp;
 #define READ_CLOCK_RP_SIZE 9
 
 /* Testing commands */
@@ -1323,7 +1323,7 @@ typedef struct {
     uint8_t	pscan_mode;
     uint8_t	dev_class[3];
     uint16_t	clock_offset;
-} __attribute__ ((packed)) inquiry_info;
+} QEMU_PACKED inquiry_info;
 #define INQUIRY_INFO_SIZE 14
 
 #define EVT_CONN_COMPLETE		0x03
@@ -1333,7 +1333,7 @@ typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	link_type;
     uint8_t	encr_mode;
-} __attribute__ ((packed)) evt_conn_complete;
+} QEMU_PACKED evt_conn_complete;
 #define EVT_CONN_COMPLETE_SIZE 11
 
 #define EVT_CONN_REQUEST		0x04
@@ -1341,7 +1341,7 @@ typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	dev_class[3];
     uint8_t	link_type;
-} __attribute__ ((packed)) evt_conn_request;
+} QEMU_PACKED evt_conn_request;
 #define EVT_CONN_REQUEST_SIZE 10
 
 #define EVT_DISCONN_COMPLETE		0x05
@@ -1349,14 +1349,14 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint8_t	reason;
-} __attribute__ ((packed)) evt_disconn_complete;
+} QEMU_PACKED evt_disconn_complete;
 #define EVT_DISCONN_COMPLETE_SIZE 4
 
 #define EVT_AUTH_COMPLETE		0x06
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
-} __attribute__ ((packed)) evt_auth_complete;
+} QEMU_PACKED evt_auth_complete;
 #define EVT_AUTH_COMPLETE_SIZE 3
 
 #define EVT_REMOTE_NAME_REQ_COMPLETE	0x07
@@ -1364,7 +1364,7 @@ typedef struct {
     uint8_t	status;
     bdaddr_t	bdaddr;
     char	name[248];
-} __attribute__ ((packed)) evt_remote_name_req_complete;
+} QEMU_PACKED evt_remote_name_req_complete;
 #define EVT_REMOTE_NAME_REQ_COMPLETE_SIZE 255
 
 #define EVT_ENCRYPT_CHANGE		0x08
@@ -1372,14 +1372,14 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint8_t	encrypt;
-} __attribute__ ((packed)) evt_encrypt_change;
+} QEMU_PACKED evt_encrypt_change;
 #define EVT_ENCRYPT_CHANGE_SIZE 5
 
 #define EVT_CHANGE_CONN_LINK_KEY_COMPLETE	0x09
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
-}  __attribute__ ((packed)) evt_change_conn_link_key_complete;
+}  QEMU_PACKED evt_change_conn_link_key_complete;
 #define EVT_CHANGE_CONN_LINK_KEY_COMPLETE_SIZE 3
 
 #define EVT_MASTER_LINK_KEY_COMPLETE		0x0A
@@ -1387,7 +1387,7 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint8_t	key_flag;
-} __attribute__ ((packed)) evt_master_link_key_complete;
+} QEMU_PACKED evt_master_link_key_complete;
 #define EVT_MASTER_LINK_KEY_COMPLETE_SIZE 4
 
 #define EVT_READ_REMOTE_FEATURES_COMPLETE	0x0B
@@ -1395,7 +1395,7 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint8_t	features[8];
-} __attribute__ ((packed)) evt_read_remote_features_complete;
+} QEMU_PACKED evt_read_remote_features_complete;
 #define EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE 11
 
 #define EVT_READ_REMOTE_VERSION_COMPLETE	0x0C
@@ -1405,7 +1405,7 @@ typedef struct {
     uint8_t	lmp_ver;
     uint16_t	manufacturer;
     uint16_t	lmp_subver;
-} __attribute__ ((packed)) evt_read_remote_version_complete;
+} QEMU_PACKED evt_read_remote_version_complete;
 #define EVT_READ_REMOTE_VERSION_COMPLETE_SIZE 8
 
 #define EVT_QOS_SETUP_COMPLETE		0x0D
@@ -1414,14 +1414,14 @@ typedef struct {
     uint16_t	handle;
     uint8_t	flags;			/* Reserved */
     hci_qos	qos;
-} __attribute__ ((packed)) evt_qos_setup_complete;
+} QEMU_PACKED evt_qos_setup_complete;
 #define EVT_QOS_SETUP_COMPLETE_SIZE (4 + HCI_QOS_CP_SIZE)
 
 #define EVT_CMD_COMPLETE 		0x0E
 typedef struct {
     uint8_t	ncmd;
     uint16_t	opcode;
-} __attribute__ ((packed)) evt_cmd_complete;
+} QEMU_PACKED evt_cmd_complete;
 #define EVT_CMD_COMPLETE_SIZE 3
 
 #define EVT_CMD_STATUS 			0x0F
@@ -1429,19 +1429,19 @@ typedef struct {
     uint8_t	status;
     uint8_t	ncmd;
     uint16_t	opcode;
-} __attribute__ ((packed)) evt_cmd_status;
+} QEMU_PACKED evt_cmd_status;
 #define EVT_CMD_STATUS_SIZE 4
 
 #define EVT_HARDWARE_ERROR		0x10
 typedef struct {
     uint8_t	code;
-} __attribute__ ((packed)) evt_hardware_error;
+} QEMU_PACKED evt_hardware_error;
 #define EVT_HARDWARE_ERROR_SIZE 1
 
 #define EVT_FLUSH_OCCURRED		0x11
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) evt_flush_occurred;
+} QEMU_PACKED evt_flush_occurred;
 #define EVT_FLUSH_OCCURRED_SIZE 2
 
 #define EVT_ROLE_CHANGE			0x12
@@ -1449,7 +1449,7 @@ typedef struct {
     uint8_t	status;
     bdaddr_t	bdaddr;
     uint8_t	role;
-} __attribute__ ((packed)) evt_role_change;
+} QEMU_PACKED evt_role_change;
 #define EVT_ROLE_CHANGE_SIZE 8
 
 #define EVT_NUM_COMP_PKTS		0x13
@@ -1459,7 +1459,7 @@ typedef struct {
         uint16_t handle;
         uint16_t num_packets;
     } connection[0];
-} __attribute__ ((packed)) evt_num_comp_pkts;
+} QEMU_PACKED evt_num_comp_pkts;
 #define EVT_NUM_COMP_PKTS_SIZE(num_hndl) (1 + 4 * (num_hndl))
 
 #define EVT_MODE_CHANGE			0x14
@@ -1468,26 +1468,26 @@ typedef struct {
     uint16_t	handle;
     uint8_t	mode;
     uint16_t	interval;
-} __attribute__ ((packed)) evt_mode_change;
+} QEMU_PACKED evt_mode_change;
 #define EVT_MODE_CHANGE_SIZE 6
 
 #define EVT_RETURN_LINK_KEYS		0x15
 typedef struct {
     uint8_t	num_keys;
     /* variable length part */
-} __attribute__ ((packed)) evt_return_link_keys;
+} QEMU_PACKED evt_return_link_keys;
 #define EVT_RETURN_LINK_KEYS_SIZE 1
 
 #define EVT_PIN_CODE_REQ		0x16
 typedef struct {
     bdaddr_t	bdaddr;
-} __attribute__ ((packed)) evt_pin_code_req;
+} QEMU_PACKED evt_pin_code_req;
 #define EVT_PIN_CODE_REQ_SIZE 6
 
 #define EVT_LINK_KEY_REQ		0x17
 typedef struct {
     bdaddr_t	bdaddr;
-} __attribute__ ((packed)) evt_link_key_req;
+} QEMU_PACKED evt_link_key_req;
 #define EVT_LINK_KEY_REQ_SIZE 6
 
 #define EVT_LINK_KEY_NOTIFY		0x18
@@ -1495,7 +1495,7 @@ typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	link_key[16];
     uint8_t	key_type;
-} __attribute__ ((packed)) evt_link_key_notify;
+} QEMU_PACKED evt_link_key_notify;
 #define EVT_LINK_KEY_NOTIFY_SIZE 23
 
 #define EVT_LOOPBACK_COMMAND		0x19
@@ -1503,14 +1503,14 @@ typedef struct {
 #define EVT_DATA_BUFFER_OVERFLOW	0x1A
 typedef struct {
     uint8_t	link_type;
-} __attribute__ ((packed)) evt_data_buffer_overflow;
+} QEMU_PACKED evt_data_buffer_overflow;
 #define EVT_DATA_BUFFER_OVERFLOW_SIZE 1
 
 #define EVT_MAX_SLOTS_CHANGE		0x1B
 typedef struct {
     uint16_t	handle;
     uint8_t	max_slots;
-} __attribute__ ((packed)) evt_max_slots_change;
+} QEMU_PACKED evt_max_slots_change;
 #define EVT_MAX_SLOTS_CHANGE_SIZE 3
 
 #define EVT_READ_CLOCK_OFFSET_COMPLETE	0x1C
@@ -1518,7 +1518,7 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint16_t	clock_offset;
-} __attribute__ ((packed)) evt_read_clock_offset_complete;
+} QEMU_PACKED evt_read_clock_offset_complete;
 #define EVT_READ_CLOCK_OFFSET_COMPLETE_SIZE 5
 
 #define EVT_CONN_PTYPE_CHANGED		0x1D
@@ -1526,20 +1526,20 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint16_t	ptype;
-} __attribute__ ((packed)) evt_conn_ptype_changed;
+} QEMU_PACKED evt_conn_ptype_changed;
 #define EVT_CONN_PTYPE_CHANGED_SIZE 5
 
 #define EVT_QOS_VIOLATION		0x1E
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) evt_qos_violation;
+} QEMU_PACKED evt_qos_violation;
 #define EVT_QOS_VIOLATION_SIZE 2
 
 #define EVT_PSCAN_REP_MODE_CHANGE	0x20
 typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	pscan_rep_mode;
-} __attribute__ ((packed)) evt_pscan_rep_mode_change;
+} QEMU_PACKED evt_pscan_rep_mode_change;
 #define EVT_PSCAN_REP_MODE_CHANGE_SIZE 7
 
 #define EVT_FLOW_SPEC_COMPLETE		0x21
@@ -1549,7 +1549,7 @@ typedef struct {
     uint8_t	flags;
     uint8_t	direction;
     hci_qos	qos;
-} __attribute__ ((packed)) evt_flow_spec_complete;
+} QEMU_PACKED evt_flow_spec_complete;
 #define EVT_FLOW_SPEC_COMPLETE_SIZE (5 + HCI_QOS_CP_SIZE)
 
 #define EVT_INQUIRY_RESULT_WITH_RSSI	0x22
@@ -1561,7 +1561,7 @@ typedef struct {
     uint8_t	dev_class[3];
     uint16_t	clock_offset;
     int8_t	rssi;
-} __attribute__ ((packed)) inquiry_info_with_rssi;
+} QEMU_PACKED inquiry_info_with_rssi;
 #define INQUIRY_INFO_WITH_RSSI_SIZE 15
 typedef struct {
     uint8_t	num_responses;
@@ -1572,7 +1572,7 @@ typedef struct {
     uint8_t	dev_class[3];
     uint16_t	clock_offset;
     int8_t	rssi;
-} __attribute__ ((packed)) inquiry_info_with_rssi_and_pscan_mode;
+} QEMU_PACKED inquiry_info_with_rssi_and_pscan_mode;
 #define INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE 16
 
 #define EVT_READ_REMOTE_EXT_FEATURES_COMPLETE	0x23
@@ -1582,7 +1582,7 @@ typedef struct {
     uint8_t	page_num;
     uint8_t	max_page_num;
     uint8_t	features[8];
-} __attribute__ ((packed)) evt_read_remote_ext_features_complete;
+} QEMU_PACKED evt_read_remote_ext_features_complete;
 #define EVT_READ_REMOTE_EXT_FEATURES_COMPLETE_SIZE 13
 
 #define EVT_SYNC_CONN_COMPLETE		0x2C
@@ -1596,7 +1596,7 @@ typedef struct {
     uint16_t	rx_pkt_len;
     uint16_t	tx_pkt_len;
     uint8_t	air_mode;
-} __attribute__ ((packed)) evt_sync_conn_complete;
+} QEMU_PACKED evt_sync_conn_complete;
 #define EVT_SYNC_CONN_COMPLETE_SIZE 17
 
 #define EVT_SYNC_CONN_CHANGED		0x2D
@@ -1607,7 +1607,7 @@ typedef struct {
     uint8_t	retrans_window;
     uint16_t	rx_pkt_len;
     uint16_t	tx_pkt_len;
-} __attribute__ ((packed)) evt_sync_conn_changed;
+} QEMU_PACKED evt_sync_conn_changed;
 #define EVT_SYNC_CONN_CHANGED_SIZE 9
 
 #define EVT_SNIFF_SUBRATE		0x2E
@@ -1618,7 +1618,7 @@ typedef struct {
     uint16_t	max_local_latency;
     uint16_t	min_remote_timeout;
     uint16_t	min_local_timeout;
-} __attribute__ ((packed)) evt_sniff_subrate;
+} QEMU_PACKED evt_sniff_subrate;
 #define EVT_SNIFF_SUBRATE_SIZE 11
 
 #define EVT_EXTENDED_INQUIRY_RESULT	0x2F
@@ -1630,7 +1630,7 @@ typedef struct {
     uint16_t	clock_offset;
     int8_t	rssi;
     uint8_t	data[240];
-} __attribute__ ((packed)) extended_inquiry_info;
+} QEMU_PACKED extended_inquiry_info;
 #define EXTENDED_INQUIRY_INFO_SIZE 254
 
 #define EVT_TESTING			0xFE
@@ -1656,22 +1656,22 @@ typedef struct {
 struct hci_command_hdr {
     uint16_t 	opcode;		/* OCF & OGF */
     uint8_t	plen;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 struct hci_event_hdr {
     uint8_t	evt;
     uint8_t	plen;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 struct hci_acl_hdr {
     uint16_t	handle;		/* Handle & Flags(PB, BC) */
     uint16_t	dlen;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 struct hci_sco_hdr {
     uint16_t	handle;
     uint8_t	dlen;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 /* L2CAP layer defines */
 
@@ -1718,25 +1718,25 @@ typedef struct {
     uint16_t	len;
     uint16_t	cid;
     uint8_t	data[0];
-} __attribute__ ((packed)) l2cap_hdr;
+} QEMU_PACKED l2cap_hdr;
 #define L2CAP_HDR_SIZE 4
 
 typedef struct {
     uint8_t	code;
     uint8_t	ident;
     uint16_t	len;
-} __attribute__ ((packed)) l2cap_cmd_hdr;
+} QEMU_PACKED l2cap_cmd_hdr;
 #define L2CAP_CMD_HDR_SIZE 4
 
 typedef struct {
     uint16_t	reason;
-} __attribute__ ((packed)) l2cap_cmd_rej;
+} QEMU_PACKED l2cap_cmd_rej;
 #define L2CAP_CMD_REJ_SIZE 2
 
 typedef struct {
     uint16_t	dcid;
     uint16_t	scid;
-} __attribute__ ((packed)) l2cap_cmd_rej_cid;
+} QEMU_PACKED l2cap_cmd_rej_cid;
 #define L2CAP_CMD_REJ_CID_SIZE 4
 
 /* reject reason */
@@ -1749,7 +1749,7 @@ enum bt_l2cap_rej_reason {
 typedef struct {
     uint16_t	psm;
     uint16_t	scid;
-} __attribute__ ((packed)) l2cap_conn_req;
+} QEMU_PACKED l2cap_conn_req;
 #define L2CAP_CONN_REQ_SIZE 4
 
 typedef struct {
@@ -1757,7 +1757,7 @@ typedef struct {
     uint16_t	scid;
     uint16_t	result;
     uint16_t	status;
-} __attribute__ ((packed)) l2cap_conn_rsp;
+} QEMU_PACKED l2cap_conn_rsp;
 #define L2CAP_CONN_RSP_SIZE 8
 
 /* connect result */
@@ -1780,7 +1780,7 @@ typedef struct {
     uint16_t	dcid;
     uint16_t	flags;
     uint8_t	data[0];
-} __attribute__ ((packed)) l2cap_conf_req;
+} QEMU_PACKED l2cap_conf_req;
 #define L2CAP_CONF_REQ_SIZE(datalen) (4 + (datalen))
 
 typedef struct {
@@ -1788,7 +1788,7 @@ typedef struct {
     uint16_t	flags;
     uint16_t	result;
     uint8_t	data[0];
-} __attribute__ ((packed)) l2cap_conf_rsp;
+} QEMU_PACKED l2cap_conf_rsp;
 #define L2CAP_CONF_RSP_SIZE(datalen) (6 + datalen)
 
 enum bt_l2cap_conf_res {
@@ -1802,7 +1802,7 @@ typedef struct {
     uint8_t	type;
     uint8_t	len;
     uint8_t	val[0];
-} __attribute__ ((packed)) l2cap_conf_opt;
+} QEMU_PACKED l2cap_conf_opt;
 #define L2CAP_CONF_OPT_SIZE 2
 
 enum bt_l2cap_conf_val {
@@ -1821,7 +1821,7 @@ typedef struct {
     uint32_t	peak_bandwidth;
     uint32_t	latency;
     uint32_t	delay_variation;
-} __attribute__ ((packed)) l2cap_conf_opt_qos;
+} QEMU_PACKED l2cap_conf_opt_qos;
 #define L2CAP_CONF_OPT_QOS_SIZE 22
 
 enum bt_l2cap_conf_opt_qos_st {
@@ -1841,25 +1841,25 @@ enum bt_l2cap_mode {
 typedef struct {
     uint16_t	dcid;
     uint16_t	scid;
-} __attribute__ ((packed)) l2cap_disconn_req;
+} QEMU_PACKED l2cap_disconn_req;
 #define L2CAP_DISCONN_REQ_SIZE 4
 
 typedef struct {
     uint16_t	dcid;
     uint16_t	scid;
-} __attribute__ ((packed)) l2cap_disconn_rsp;
+} QEMU_PACKED l2cap_disconn_rsp;
 #define L2CAP_DISCONN_RSP_SIZE 4
 
 typedef struct {
     uint16_t	type;
-} __attribute__ ((packed)) l2cap_info_req;
+} QEMU_PACKED l2cap_info_req;
 #define L2CAP_INFO_REQ_SIZE 2
 
 typedef struct {
     uint16_t	type;
     uint16_t	result;
     uint8_t	data[0];
-} __attribute__ ((packed)) l2cap_info_rsp;
+} QEMU_PACKED l2cap_info_rsp;
 #define L2CAP_INFO_RSP_SIZE 4
 
 /* info type */
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index ec7ea8207b..4d0ef0d54c 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2424,7 +2424,6 @@ static void cirrus_update_memory_access(CirrusVGAState *s)
 {
     unsigned mode;
 
-    memory_region_transaction_begin();
     if ((s->vga.sr[0x17] & 0x44) == 0x44) {
         goto generic_io;
     } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
@@ -2444,7 +2443,6 @@ static void cirrus_update_memory_access(CirrusVGAState *s)
             unmap_linear_vram(s);
         }
     }
-    memory_region_transaction_commit();
 }
 
 
diff --git a/hw/collie.c b/hw/collie.c
index 0b955e04f1..156404d9f3 100644
--- a/hw/collie.c
+++ b/hw/collie.c
@@ -26,7 +26,7 @@ static void collie_init(ram_addr_t ram_size,
 {
     StrongARMState *s;
     DriveInfo *dinfo;
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 2);
+    ram_addr_t phys_flash;
 
     if (!cpu_model) {
         cpu_model = "sa1110";
@@ -34,19 +34,17 @@ static void collie_init(ram_addr_t ram_size,
 
     s = sa1110_init(collie_binfo.ram_size, cpu_model);
 
-    memory_region_init_rom_device(&phys_flash[0], &pflash_cfi01_ops_le,
-                                  NULL, "collie.fl1", 0x02000000);
+    phys_flash = qemu_ram_alloc(NULL, "collie.fl1", 0x02000000);
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    pflash_cfi01_register(SA_CS0, &phys_flash[0],
+    pflash_cfi01_register(SA_CS0, phys_flash,
                     dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-                    512, 4, 0x00, 0x00, 0x00, 0x00);
+                    512, 4, 0x00, 0x00, 0x00, 0x00, 0);
 
-    memory_region_init_rom_device(&phys_flash[1], &pflash_cfi01_ops_le,
-                                  NULL, "collie.fl2", 0x02000000);
+    phys_flash = qemu_ram_alloc(NULL, "collie.fl2", 0x02000000);
     dinfo = drive_get(IF_PFLASH, 0, 1);
-    pflash_cfi01_register(SA_CS1, &phys_flash[1],
+    pflash_cfi01_register(SA_CS1, phys_flash,
                     dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-                    512, 4, 0x00, 0x00, 0x00, 0x00);
+                    512, 4, 0x00, 0x00, 0x00, 0x00, 0);
 
     sysbus_create_simple("scoop", 0x40800000, NULL);
 
diff --git a/hw/dec_pci.c b/hw/dec_pci.c
index 1aec06611c..a35f382052 100644
--- a/hw/dec_pci.c
+++ b/hw/dec_pci.c
@@ -80,15 +80,16 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
 static int pci_dec_21154_init_device(SysBusDevice *dev)
 {
     DECState *s;
+    int pci_mem_config, pci_mem_data;
 
     s = FROM_SYSBUS(DECState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
-                          &s->host_state, "pci-data-idx", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    pci_mem_data = pci_host_data_register_mmio(&s->host_state,
+                                               DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
     return 0;
 }
 
diff --git a/hw/dummy_m68k.c b/hw/dummy_m68k.c
index 30146b9c9d..eed9e3843c 100644
--- a/hw/dummy_m68k.c
+++ b/hw/dummy_m68k.c
@@ -10,7 +10,6 @@
 #include "boards.h"
 #include "loader.h"
 #include "elf.h"
-#include "exec-memory.h"
 
 #define KERNEL_LOAD_ADDR 0x10000
 
@@ -22,8 +21,6 @@ static void dummy_m68k_init(ram_addr_t ram_size,
                      const char *initrd_filename, const char *cpu_model)
 {
     CPUState *env;
-    MemoryRegion *address_space_mem =  get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
     int kernel_size;
     uint64_t elf_entry;
     target_phys_addr_t entry;
@@ -40,8 +37,8 @@ static void dummy_m68k_init(ram_addr_t ram_size,
     env->vbr = 0;
 
     /* RAM at address zero */
-    memory_region_init_ram(ram, NULL, "dummy_m68k.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0, ram);
+    cpu_register_physical_memory(0, ram_size,
+        qemu_ram_alloc(NULL, "dummy_m68k.ram", ram_size) | IO_MEM_RAM);
 
     /* Load kernel.  */
     if (kernel_filename) {
diff --git a/hw/flash.h b/hw/flash.h
index 7fb012bb06..270be5e127 100644
--- a/hw/flash.h
+++ b/hw/flash.h
@@ -1,27 +1,21 @@
-#include "memory.h"
-
 /* NOR flash devices */
 typedef struct pflash_t pflash_t;
 
 /* pflash_cfi01.c */
-extern const MemoryRegionOps pflash_cfi01_ops_be;
-extern const MemoryRegionOps pflash_cfi01_ops_le;
-extern const MemoryRegionOps pflash_cfi02_ops_be;
-extern const MemoryRegionOps pflash_cfi02_ops_le;
-
-pflash_t *pflash_cfi01_register(target_phys_addr_t base, MemoryRegion *mem,
+pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
                                 BlockDriverState *bs,
                                 uint32_t sector_len, int nb_blocs, int width,
                                 uint16_t id0, uint16_t id1,
-                                uint16_t id2, uint16_t id3);
+                                uint16_t id2, uint16_t id3, int be);
 
 /* pflash_cfi02.c */
-pflash_t *pflash_cfi02_register(target_phys_addr_t base, MemoryRegion *mem,
+pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
                                 BlockDriverState *bs, uint32_t sector_len,
                                 int nb_blocs, int nb_mappings, int width,
                                 uint16_t id0, uint16_t id1,
                                 uint16_t id2, uint16_t id3,
-                                uint16_t unlock_addr0, uint16_t unlock_addr1);
+                                uint16_t unlock_addr0, uint16_t unlock_addr1,
+                                int be);
 
 /* nand.c */
 DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id);
@@ -42,12 +36,7 @@ uint32_t nand_getbuswidth(DeviceState *dev);
 #define NAND_MFR_MICRON		0x2c
 
 /* onenand.c */
-void onenand_base_update(void *opaque, target_phys_addr_t new);
-void onenand_base_unmap(void *opaque);
-void *onenand_init(BlockDriverState *bdrv,
-                uint16_t man_id, uint16_t dev_id, uint16_t ver_id,
-                int regshift, qemu_irq irq);
-void *onenand_raw_otp(void *opaque);
+void *onenand_raw_otp(DeviceState *onenand_device);
 
 /* ecc.c */
 typedef struct {
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 663ad80116..8df265c61d 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -214,7 +214,8 @@ static void fw_cfg_write(FWCfgState *s, uint8_t value)
 
     FW_CFG_DPRINTF("write %d\n", value);
 
-    if (s->cur_entry & FW_CFG_WRITE_CHANNEL && s->cur_offset < e->len) {
+    if (s->cur_entry & FW_CFG_WRITE_CHANNEL && e->callback &&
+        s->cur_offset < e->len) {
         e->data[s->cur_offset++] = value;
         if (s->cur_offset == e->len) {
             e->callback(e->callback_opaque, e->data);
diff --git a/hw/g364fb.c b/hw/g364fb.c
index a7731ecfb5..5e7bcfa278 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -1,7 +1,7 @@
 /*
  * QEMU G364 framebuffer Emulator.
  *
- * Copyright (c) 2007-2009 Herve Poussineau
+ * Copyright (c) 2007-2011 Herve Poussineau
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -18,27 +18,18 @@
  */
 
 #include "hw.h"
-#include "mips.h"
 #include "console.h"
 #include "pixel_ops.h"
-
-//#define DEBUG_G364
-
-#ifdef DEBUG_G364
-#define DPRINTF(fmt, ...) \
-do { printf("g364: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...) do {} while (0)
-#endif
-#define BADF(fmt, ...) \
-do { fprintf(stderr, "g364 ERROR: " fmt , ## __VA_ARGS__);} while (0)
+#include "trace.h"
+#include "sysbus.h"
 
 typedef struct G364State {
     /* hardware */
     uint8_t *vram;
-    MemoryRegion vram_region;
-    int vram_size;
+    uint32_t vram_size;
     qemu_irq irq;
+    MemoryRegion mem_vram;
+    MemoryRegion mem_ctrl;
     /* registers */
     uint8_t color_palette[256][3];
     uint8_t cursor_palette[3][3];
@@ -53,31 +44,31 @@ typedef struct G364State {
     int blanked;
 } G364State;
 
-#define REG_ID       0x000000
-#define REG_BOOT     0x080000
-#define REG_DISPLAY  0x080118
-#define REG_VDISPLAY 0x080150
-#define REG_CTLA     0x080300
-#define REG_TOP      0x080400
-#define REG_CURS_PAL 0x080508
-#define REG_CURS_POS 0x080638
-#define REG_CLR_PAL  0x080800
-#define REG_CURS_PAT 0x081000
-#define REG_RESET    0x180000
+#define REG_BOOT     0x000000
+#define REG_DISPLAY  0x000118
+#define REG_VDISPLAY 0x000150
+#define REG_CTLA     0x000300
+#define REG_TOP      0x000400
+#define REG_CURS_PAL 0x000508
+#define REG_CURS_POS 0x000638
+#define REG_CLR_PAL  0x000800
+#define REG_CURS_PAT 0x001000
+#define REG_RESET    0x100000
 
 #define CTLA_FORCE_BLANK 0x00000400
 #define CTLA_NO_CURSOR   0x00800000
 
 static inline int check_dirty(G364State *s, ram_addr_t page)
 {
-    return memory_region_get_dirty(&s->vram_region, page, DIRTY_MEMORY_VGA);
+    return memory_region_get_dirty(&s->mem_vram, page, DIRTY_MEMORY_VGA);
 }
 
 static inline void reset_dirty(G364State *s,
                                ram_addr_t page_min, ram_addr_t page_max)
 {
-    memory_region_reset_dirty(&s->vram_region, page_min,
-                              page_max + TARGET_PAGE_SIZE - 1,
+    memory_region_reset_dirty(&s->mem_vram,
+                              page_min,
+                              page_max + TARGET_PAGE_SIZE - page_min - 1,
                               DIRTY_MEMORY_VGA);
 }
 
@@ -111,7 +102,8 @@ static void g364fb_draw_graphic8(G364State *s)
             w = 4;
             break;
         default:
-            BADF("unknown host depth %d\n", ds_get_bits_per_pixel(s->ds));
+            hw_error("g364: unknown host depth %d",
+                     ds_get_bits_per_pixel(s->ds));
             return;
     }
 
@@ -263,7 +255,7 @@ static void g364fb_update_display(void *opaque)
     } else if (s->depth == 8) {
         g364fb_draw_graphic8(s);
     } else {
-        BADF("unknown guest depth %d\n", s->depth);
+        error_report("g364: unknown guest depth %d", s->depth);
     }
 
     qemu_irq_raise(s->irq);
@@ -276,13 +268,12 @@ static inline void g364fb_invalidate_display(void *opaque)
 
     s->blanked = 0;
     for (i = 0; i < s->vram_size; i += TARGET_PAGE_SIZE) {
-        memory_region_set_dirty(&s->vram_region, i);
+        memory_region_set_dirty(&s->mem_vram, i);
     }
 }
 
-static void g364fb_reset(void *opaque)
+static void g364fb_reset(G364State *s)
 {
-    G364State *s = opaque;
     qemu_irq_lower(s->irq);
 
     memset(s->color_palette, 0, sizeof(s->color_palette));
@@ -293,7 +284,7 @@ static void g364fb_reset(void *opaque)
     s->top_of_screen = 0;
     s->width = s->height = 0;
     memset(s->vram, 0, s->vram_size);
-    g364fb_invalidate_display(opaque);
+    g364fb_invalidate_display(s);
 }
 
 static void g364fb_screen_dump(void *opaque, const char *filename)
@@ -305,7 +296,7 @@ static void g364fb_screen_dump(void *opaque, const char *filename)
     FILE *f;
 
     if (s->depth != 8) {
-        BADF("unknown guest depth %d\n", s->depth);
+        error_report("g364: unknown guest depth %d", s->depth);
         return;
     }
 
@@ -337,7 +328,9 @@ static void g364fb_screen_dump(void *opaque, const char *filename)
 }
 
 /* called for accesses to io ports */
-static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr)
+static uint64_t g364fb_ctrl_read(void *opaque,
+                                 target_phys_addr_t addr,
+                                 unsigned int size)
 {
     G364State *s = opaque;
     uint32_t val;
@@ -354,9 +347,6 @@ static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr)
         val |= ((uint32_t)s->cursor_palette[idx][2] << 0);
     } else {
         switch (addr) {
-            case REG_ID:
-                val = 0x10; /* Mips G364 */
-                break;
             case REG_DISPLAY:
                 val = s->width / 4;
                 break;
@@ -368,33 +358,19 @@ static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr)
                 break;
             default:
             {
-                BADF("invalid read at [" TARGET_FMT_plx "]\n", addr);
+                error_report("g364: invalid read at [" TARGET_FMT_plx "]",
+                             addr);
                 val = 0;
                 break;
             }
         }
     }
 
-    DPRINTF("read 0x%08x at [" TARGET_FMT_plx "]\n", val, addr);
+    trace_g364fb_read(addr, val);
 
     return val;
 }
 
-static uint32_t g364fb_ctrl_readw(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v = g364fb_ctrl_readl(opaque, addr & ~0x3);
-    if (addr & 0x2)
-        return v >> 16;
-    else
-        return v & 0xffff;
-}
-
-static uint32_t g364fb_ctrl_readb(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v = g364fb_ctrl_readl(opaque, addr & ~0x3);
-    return (v >> (8 * (addr & 0x3))) & 0xff;
-}
-
 static void g364fb_update_depth(G364State *s)
 {
     static const int depths[8] = { 1, 2, 4, 8, 15, 16, 0 };
@@ -412,15 +388,18 @@ static void g364_invalidate_cursor_position(G364State *s)
     end = (ymax + 1) * ds_get_linesize(s->ds);
 
     for (i = start; i < end; i += TARGET_PAGE_SIZE) {
-        memory_region_set_dirty(&s->vram_region, i);
+        memory_region_set_dirty(&s->mem_vram, i);
     }
 }
 
-static void g364fb_ctrl_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void g364fb_ctrl_write(void *opaque,
+                              target_phys_addr_t addr,
+                              uint64_t val,
+                              unsigned int size)
 {
     G364State *s = opaque;
 
-    DPRINTF("write 0x%08x at [" TARGET_FMT_plx "]\n", val, addr);
+    trace_g364fb_write(addr, val);
 
     if (addr >= REG_CLR_PAL && addr < REG_CLR_PAL + 0x800) {
         /* color palette */
@@ -443,124 +422,65 @@ static void g364fb_ctrl_writel(void *opaque, target_phys_addr_t addr, uint32_t v
         g364fb_invalidate_display(s);
     } else {
         switch (addr) {
-            case REG_ID: /* Card identifier; read-only */
-            case REG_BOOT: /* Boot timing */
-            case 0x80108: /* Line timing: half sync */
-            case 0x80110: /* Line timing: back porch */
-            case 0x80120: /* Line timing: short display */
-            case 0x80128: /* Frame timing: broad pulse */
-            case 0x80130: /* Frame timing: v sync */
-            case 0x80138: /* Frame timing: v preequalise */
-            case 0x80140: /* Frame timing: v postequalise */
-            case 0x80148: /* Frame timing: v blank */
-            case 0x80158: /* Line timing: line time */
-            case 0x80160: /* Frame store: line start */
-            case 0x80168: /* vram cycle: mem init */
-            case 0x80170: /* vram cycle: transfer delay */
-            case 0x80200: /* vram cycle: mask register */
-                /* ignore */
-                break;
-            case REG_TOP:
-                s->top_of_screen = val;
-                g364fb_invalidate_display(s);
-                break;
-            case REG_DISPLAY:
-                s->width = val * 4;
-                break;
-            case REG_VDISPLAY:
-                s->height = val / 2;
-                break;
-            case REG_CTLA:
-                s->ctla = val;
-                g364fb_update_depth(s);
-                g364fb_invalidate_display(s);
-                break;
-            case REG_CURS_POS:
-                g364_invalidate_cursor_position(s);
-                s->cursor_position = val;
-                g364_invalidate_cursor_position(s);
-                break;
-            case REG_RESET:
-                g364fb_reset(s);
-                break;
-            default:
-                BADF("invalid write of 0x%08x at [" TARGET_FMT_plx "]\n", val, addr);
-                break;
+        case REG_BOOT: /* Boot timing */
+        case 0x00108: /* Line timing: half sync */
+        case 0x00110: /* Line timing: back porch */
+        case 0x00120: /* Line timing: short display */
+        case 0x00128: /* Frame timing: broad pulse */
+        case 0x00130: /* Frame timing: v sync */
+        case 0x00138: /* Frame timing: v preequalise */
+        case 0x00140: /* Frame timing: v postequalise */
+        case 0x00148: /* Frame timing: v blank */
+        case 0x00158: /* Line timing: line time */
+        case 0x00160: /* Frame store: line start */
+        case 0x00168: /* vram cycle: mem init */
+        case 0x00170: /* vram cycle: transfer delay */
+        case 0x00200: /* vram cycle: mask register */
+            /* ignore */
+            break;
+        case REG_TOP:
+            s->top_of_screen = val;
+            g364fb_invalidate_display(s);
+            break;
+        case REG_DISPLAY:
+            s->width = val * 4;
+            break;
+        case REG_VDISPLAY:
+            s->height = val / 2;
+            break;
+        case REG_CTLA:
+            s->ctla = val;
+            g364fb_update_depth(s);
+            g364fb_invalidate_display(s);
+            break;
+        case REG_CURS_POS:
+            g364_invalidate_cursor_position(s);
+            s->cursor_position = val;
+            g364_invalidate_cursor_position(s);
+            break;
+        case REG_RESET:
+            g364fb_reset(s);
+            break;
+        default:
+            error_report("g364: invalid write of 0x%" PRIx64
+                         " at [" TARGET_FMT_plx "]", val, addr);
+            break;
         }
     }
     qemu_irq_lower(s->irq);
 }
 
-static void g364fb_ctrl_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    uint32_t old_val = g364fb_ctrl_readl(opaque, addr & ~0x3);
-
-    if (addr & 0x2)
-        val = (val << 16) | (old_val & 0x0000ffff);
-    else
-        val = val | (old_val & 0xffff0000);
-    g364fb_ctrl_writel(opaque, addr & ~0x3, val);
-}
-
-static void g364fb_ctrl_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    uint32_t old_val = g364fb_ctrl_readl(opaque, addr & ~0x3);
-
-    switch (addr & 3) {
-    case 0:
-        val = val | (old_val & 0xffffff00);
-        break;
-    case 1:
-        val = (val << 8) | (old_val & 0xffff00ff);
-        break;
-    case 2:
-        val = (val << 16) | (old_val & 0xff00ffff);
-        break;
-    case 3:
-        val = (val << 24) | (old_val & 0x00ffffff);
-        break;
-    }
-    g364fb_ctrl_writel(opaque, addr & ~0x3, val);
-}
-
 static const MemoryRegionOps g364fb_ctrl_ops = {
-    .old_mmio = {
-        .read = {
-            g364fb_ctrl_readb,
-            g364fb_ctrl_readw,
-            g364fb_ctrl_readl,
-        },
-        .write = {
-            g364fb_ctrl_writeb,
-            g364fb_ctrl_writew,
-            g364fb_ctrl_writel,
-        },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+    .read = g364fb_ctrl_read,
+    .write = g364fb_ctrl_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl.min_access_size = 4,
+    .impl.max_access_size = 4,
 };
 
-static int g364fb_load(QEMUFile *f, void *opaque, int version_id)
+static int g364fb_post_load(void *opaque, int version_id)
 {
     G364State *s = opaque;
-    unsigned int i, vram_size;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    vram_size = qemu_get_be32(f);
-    if (vram_size < s->vram_size)
-        return -EINVAL;
-    qemu_get_buffer(f, s->vram, s->vram_size);
-    for (i = 0; i < 256; i++)
-        qemu_get_buffer(f, s->color_palette[i], 3);
-    for (i = 0; i < 3; i++)
-        qemu_get_buffer(f, s->cursor_palette[i], 3);
-    qemu_get_buffer(f, (uint8_t *)s->cursor, sizeof(s->cursor));
-    s->cursor_position = qemu_get_be32(f);
-    s->ctla = qemu_get_be32(f);
-    s->top_of_screen = qemu_get_be32(f);
-    s->width = qemu_get_be32(f);
-    s->height = qemu_get_be32(f);
 
     /* force refresh */
     g364fb_update_depth(s);
@@ -569,53 +489,80 @@ static int g364fb_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void g364fb_save(QEMUFile *f, void *opaque)
-{
-    G364State *s = opaque;
-    int i;
-
-    qemu_put_be32(f, s->vram_size);
-    qemu_put_buffer(f, s->vram, s->vram_size);
-    for (i = 0; i < 256; i++)
-        qemu_put_buffer(f, s->color_palette[i], 3);
-    for (i = 0; i < 3; i++)
-        qemu_put_buffer(f, s->cursor_palette[i], 3);
-    qemu_put_buffer(f, (uint8_t *)s->cursor, sizeof(s->cursor));
-    qemu_put_be32(f, s->cursor_position);
-    qemu_put_be32(f, s->ctla);
-    qemu_put_be32(f, s->top_of_screen);
-    qemu_put_be32(f, s->width);
-    qemu_put_be32(f, s->height);
-}
+static const VMStateDescription vmstate_g364fb = {
+    .name = "g364fb",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .post_load = g364fb_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_VBUFFER_UINT32(vram, G364State, 1, NULL, 0, vram_size),
+        VMSTATE_BUFFER_UNSAFE(color_palette, G364State, 0, 256 * 3),
+        VMSTATE_BUFFER_UNSAFE(cursor_palette, G364State, 0, 9),
+        VMSTATE_UINT16_ARRAY(cursor, G364State, 512),
+        VMSTATE_UINT32(cursor_position, G364State),
+        VMSTATE_UINT32(ctla, G364State),
+        VMSTATE_UINT32(top_of_screen, G364State),
+        VMSTATE_UINT32(width, G364State),
+        VMSTATE_UINT32(height, G364State),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
-int g364fb_mm_init(MemoryRegion *system_memory,
-                   target_phys_addr_t vram_base,
-                   target_phys_addr_t ctrl_base, int it_shift,
-                   qemu_irq irq)
+static void g364fb_init(DeviceState *dev, G364State *s)
 {
-    G364State *s;
-    MemoryRegion *io_ctrl = g_new(MemoryRegion, 1);
-
-    s = g_malloc0(sizeof(G364State));
-
-    s->vram_size = 8 * 1024 * 1024;
-    memory_region_init_ram(&s->vram_region, NULL, "g364fb.vram", s->vram_size);
-    s->vram = memory_region_get_ram_ptr(&s->vram_region);
-    s->irq = irq;
-
-    qemu_register_reset(g364fb_reset, s);
-    register_savevm(NULL, "g364fb", 0, 1, g364fb_save, g364fb_load, s);
-    g364fb_reset(s);
+    s->vram = g_malloc0(s->vram_size);
 
     s->ds = graphic_console_init(g364fb_update_display,
                                  g364fb_invalidate_display,
                                  g364fb_screen_dump, NULL, s);
 
-    memory_region_add_subregion(system_memory, vram_base, &s->vram_region);
+    memory_region_init_io(&s->mem_ctrl, &g364fb_ctrl_ops, s, "ctrl", 0x180000);
+    memory_region_init_ram_ptr(&s->mem_vram, dev, "vram",
+                               s->vram_size, s->vram);
+    memory_region_set_coalescing(&s->mem_vram);
+}
+
+typedef struct {
+    SysBusDevice busdev;
+    G364State g364;
+} G364SysBusState;
 
-    memory_region_init_io(io_ctrl, &g364fb_ctrl_ops, s,
-                          "g364fb-ctrl", 0x200000);
-    memory_region_add_subregion(system_memory, ctrl_base, io_ctrl);
+static int g364fb_sysbus_init(SysBusDevice *dev)
+{
+    G364State *s = &FROM_SYSBUS(G364SysBusState, dev)->g364;
+
+    g364fb_init(&dev->qdev, s);
+    sysbus_init_irq(dev, &s->irq);
+    sysbus_init_mmio_region(dev, &s->mem_ctrl);
+    sysbus_init_mmio_region(dev, &s->mem_vram);
 
     return 0;
 }
+
+static void g364fb_sysbus_reset(DeviceState *d)
+{
+    G364SysBusState *s = DO_UPCAST(G364SysBusState, busdev.qdev, d);
+    g364fb_reset(&s->g364);
+}
+
+static SysBusDeviceInfo g364fb_sysbus_info = {
+    .init = g364fb_sysbus_init,
+    .qdev.name = "sysbus-g364",
+    .qdev.desc = "G364 framebuffer",
+    .qdev.size = sizeof(G364SysBusState),
+    .qdev.vmsd = &vmstate_g364fb,
+    .qdev.reset = g364fb_sysbus_reset,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_HEX32("vram_size", G364SysBusState, g364.vram_size,
+                          8 * 1024 * 1024),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
+static void g364fb_register(void)
+{
+    sysbus_register_withprop(&g364fb_sysbus_info);
+}
+
+device_init(g364fb_register);
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index 9d3ff7d555..9a823e1c06 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -92,15 +92,16 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
 static int pci_grackle_init_device(SysBusDevice *dev)
 {
     GrackleState *s;
+    int pci_mem_config, pci_mem_data;
 
     s = FROM_SYSBUS(GrackleState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
-                          &s->host_state, "pci-data-idx", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    pci_mem_data = pci_host_data_register_mmio(&s->host_state,
+                                               DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
 
     qemu_register_reset(pci_grackle_reset, &s->host_state);
     return 0;
diff --git a/hw/gumstix.c b/hw/gumstix.c
index d3a4bb4c67..853f7e1ee8 100644
--- a/hw/gumstix.c
+++ b/hw/gumstix.c
@@ -48,8 +48,7 @@ static void connex_init(ram_addr_t ram_size,
 {
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    const MemoryRegionOps *flash_ops;
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
+    int be;
 
     uint32_t connex_rom = 0x01000000;
     uint32_t connex_ram = 0x04000000;
@@ -64,15 +63,14 @@ static void connex_init(ram_addr_t ram_size,
     }
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    flash_ops = &pflash_cfi01_ops_be;
+    be = 1;
 #else
-    flash_ops = &pflash_cfi01_ops_le;
+    be = 0;
 #endif
-    memory_region_init_rom_device(flash, flash_ops,
-                                  NULL, "connext.rom", connex_rom);
-    if (!pflash_cfi01_register(0x00000000, flash,
+    if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "connext.rom",
+                                                          connex_rom),
                                dinfo->bdrv, sector_len, connex_rom / sector_len,
-                               2, 0, 0, 0, 0)) {
+                               2, 0, 0, 0, 0, be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
     }
@@ -89,8 +87,7 @@ static void verdex_init(ram_addr_t ram_size,
 {
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
-    const MemoryRegionOps *flash_ops;
+    int be;
 
     uint32_t verdex_rom = 0x02000000;
     uint32_t verdex_ram = 0x10000000;
@@ -105,15 +102,14 @@ static void verdex_init(ram_addr_t ram_size,
     }
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    flash_ops = &pflash_cfi01_ops_be;
+    be = 1;
 #else
-    flash_ops = &pflash_cfi01_ops_le;
+    be = 0;
 #endif
-    memory_region_init_rom_device(flash, flash_ops,
-                                  NULL, "verdex.rom", verdex_rom);
-    if (!pflash_cfi01_register(0x00000000, flash,
+    if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "verdex.rom",
+                                                          verdex_rom),
                                dinfo->bdrv, sector_len, verdex_rom / sector_len,
-                               2, 0, 0, 0, 0)) {
+                               2, 0, 0, 0, 0, be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
     }
diff --git a/hw/hpet_emul.h b/hw/hpet_emul.h
index 8bf312ab21..6128702533 100644
--- a/hw/hpet_emul.h
+++ b/hw/hpet_emul.h
@@ -59,13 +59,13 @@ struct hpet_fw_entry
     uint64_t address;
     uint16_t min_tick;
     uint8_t page_prot;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 struct hpet_fw_config
 {
     uint8_t count;
     struct hpet_fw_entry hpet[8];
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 extern struct hpet_fw_config hpet_cfg;
 #endif
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 29521babf7..f4fa1545bd 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -710,6 +710,7 @@ static void ncq_cb(void *opaque, int ret)
     DPRINTF(ncq_tfs->drive->port_no, "NCQ transfer tag %d finished\n",
             ncq_tfs->tag);
 
+    bdrv_acct_done(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct);
     qemu_sglist_destroy(&ncq_tfs->sglist);
     ncq_tfs->used = 0;
 }
@@ -756,6 +757,10 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
             ncq_tfs->is_read = 1;
 
             DPRINTF(port, "tag %d aio read %ld\n", ncq_tfs->tag, ncq_tfs->lba);
+
+            bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
+                            (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE,
+                            BDRV_ACCT_READ);
             ncq_tfs->aiocb = dma_bdrv_read(ncq_tfs->drive->port.ifs[0].bs,
                                            &ncq_tfs->sglist, ncq_tfs->lba,
                                            ncq_cb, ncq_tfs);
@@ -766,6 +771,10 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
             ncq_tfs->is_read = 0;
 
             DPRINTF(port, "tag %d aio write %ld\n", ncq_tfs->tag, ncq_tfs->lba);
+
+            bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
+                            (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE,
+                            BDRV_ACCT_WRITE);
             ncq_tfs->aiocb = dma_bdrv_write(ncq_tfs->drive->port.ifs[0].bs,
                                             &ncq_tfs->sglist, ncq_tfs->lba,
                                             ncq_cb, ncq_tfs);
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index e456193b2b..3c29d93b47 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -244,13 +244,13 @@ typedef struct AHCICmdHdr {
     uint32_t    status;
     uint64_t    tbl_addr;
     uint32_t    reserved[4];
-} __attribute__ ((packed)) AHCICmdHdr;
+} QEMU_PACKED AHCICmdHdr;
 
 typedef struct AHCI_SG {
     uint64_t    addr;
     uint32_t    reserved;
     uint32_t    flags_size;
-} __attribute__ ((packed)) AHCI_SG;
+} QEMU_PACKED AHCI_SG;
 
 typedef struct AHCIDevice AHCIDevice;
 
@@ -258,6 +258,7 @@ typedef struct NCQTransferState {
     AHCIDevice *drive;
     BlockDriverAIOCB *aiocb;
     QEMUSGList sglist;
+    BlockAcctCookie acct;
     int is_read;
     uint16_t sector_count;
     uint64_t lba;
@@ -320,7 +321,7 @@ typedef struct NCQFrame {
     uint8_t reserved8;
     uint8_t reserved9;
     uint8_t reserved10;
-} __attribute__ ((packed)) NCQFrame;
+} QEMU_PACKED NCQFrame;
 
 void ahci_init(AHCIState *s, DeviceState *qdev, int ports);
 void ahci_uninit(AHCIState *s);
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index fe2fb0b806..f38d2896ae 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -104,17 +104,20 @@ static void cd_data_to_raw(uint8_t *buf, int lba)
     memset(buf, 0, 288);
 }
 
-static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
-                           int sector_size)
+static int cd_read_sector(IDEState *s, int lba, uint8_t *buf, int sector_size)
 {
     int ret;
 
     switch(sector_size) {
     case 2048:
-        ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
+        bdrv_acct_start(s->bs, &s->acct, 4 * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
+        ret = bdrv_read(s->bs, (int64_t)lba << 2, buf, 4);
+        bdrv_acct_done(s->bs, &s->acct);
         break;
     case 2352:
-        ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
+        bdrv_acct_start(s->bs, &s->acct, 4 * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
+        ret = bdrv_read(s->bs, (int64_t)lba << 2, buf + 16, 4);
+        bdrv_acct_done(s->bs, &s->acct);
         if (ret < 0)
             return ret;
         cd_data_to_raw(buf, lba);
@@ -181,7 +184,7 @@ void ide_atapi_cmd_reply_end(IDEState *s)
     } else {
         /* see if a new sector must be read */
         if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
-            ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
+            ret = cd_read_sector(s, s->lba, s->io_buffer, s->cd_sector_size);
             if (ret < 0) {
                 ide_transfer_stop(s);
                 ide_atapi_io_error(s, ret);
@@ -250,6 +253,7 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
     s->io_buffer_index = 0;
 
     if (s->atapi_dma) {
+        bdrv_acct_start(s->bs, &s->acct, size, BDRV_ACCT_READ);
         s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
         s->bus->dma->ops->start_dma(s->bus->dma, s,
                                    ide_atapi_cmd_read_dma_cb);
@@ -322,10 +326,7 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
         s->status = READY_STAT | SEEK_STAT;
         s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
         ide_set_irq(s->bus);
-    eot:
-        s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
-        ide_set_inactive(s);
-        return;
+        goto eot;
     }
 
     s->io_buffer_index = 0;
@@ -343,9 +344,11 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
 #ifdef DEBUG_AIO
     printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
 #endif
+
     s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset);
     s->bus->dma->iov.iov_len = n * 4 * 512;
     qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1);
+
     s->bus->dma->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2,
                                        &s->bus->dma->qiov, n * 4,
                                        ide_atapi_cmd_read_dma_cb, s);
@@ -355,6 +358,12 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
                             ASC_MEDIUM_NOT_PRESENT);
         goto eot;
     }
+
+    return;
+eot:
+    bdrv_acct_done(s->bs, &s->acct);
+    s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
+    ide_set_inactive(s);
 }
 
 /* start a CD-CDROM read command with DMA */
@@ -368,6 +377,8 @@ static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
     s->io_buffer_size = 0;
     s->cd_sector_size = sector_size;
 
+    bdrv_acct_start(s->bs, &s->acct, s->packet_transfer_size, BDRV_ACCT_READ);
+
     /* XXX: check if BUSY_STAT should be set */
     s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
     s->bus->dma->ops->start_dma(s->bus->dma, s,
@@ -546,13 +557,13 @@ static void cmd_get_event_status_notification(IDEState *s,
         uint8_t reserved3[2];
         uint16_t len;
         uint8_t control;
-    } __attribute__((packed)) *gesn_cdb;
+    } QEMU_PACKED *gesn_cdb;
 
     struct {
         uint16_t len;
         uint8_t notification_class;
         uint8_t supported_events;
-    } __attribute((packed)) *gesn_event_header;
+    } QEMU_PACKED *gesn_event_header;
 
     enum notification_class_request_type {
         NCR_RESERVED1 = 1 << 0,
diff --git a/hw/ide/core.c b/hw/ide/core.c
index d145b19b0c..40abc1edd2 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -473,7 +473,10 @@ void ide_sector_read(IDEState *s)
 #endif
         if (n > s->req_nb_sectors)
             n = s->req_nb_sectors;
+
+        bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
         ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
+        bdrv_acct_done(s->bs, &s->acct);
         if (ret != 0) {
             if (ide_handle_rw_error(s, -ret,
                 BM_STATUS_PIO_RETRY | BM_STATUS_RETRY_READ))
@@ -610,7 +613,10 @@ handle_rw_error:
     return;
 
 eot:
-   ide_set_inactive(s);
+    if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
+        bdrv_acct_done(s->bs, &s->acct);
+    }
+    ide_set_inactive(s);
 }
 
 static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
@@ -619,6 +625,20 @@ static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
     s->io_buffer_index = 0;
     s->io_buffer_size = 0;
     s->dma_cmd = dma_cmd;
+
+    switch (dma_cmd) {
+    case IDE_DMA_READ:
+        bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE,
+                        BDRV_ACCT_READ);
+        break;
+    case IDE_DMA_WRITE:
+        bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE,
+                        BDRV_ACCT_WRITE);
+        break;
+    default:
+        break;
+    }
+
     s->bus->dma->ops->start_dma(s->bus->dma, s, ide_dma_cb);
 }
 
@@ -641,7 +661,10 @@ void ide_sector_write(IDEState *s)
     n = s->nsector;
     if (n > s->req_nb_sectors)
         n = s->req_nb_sectors;
+
+    bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
     ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
+    bdrv_acct_done(s->bs, &s->acct);
 
     if (ret != 0) {
         if (ide_handle_rw_error(s, -ret, BM_STATUS_PIO_RETRY))
@@ -685,6 +708,7 @@ static void ide_flush_cb(void *opaque, int ret)
         }
     }
 
+    bdrv_acct_done(s->bs, &s->acct);
     s->status = READY_STAT | SEEK_STAT;
     ide_set_irq(s->bus);
 }
@@ -698,6 +722,7 @@ void ide_flush_cache(IDEState *s)
         return;
     }
 
+    bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH);
     acb = bdrv_aio_flush(s->bs, ide_flush_cb, s);
     if (acb == NULL) {
         ide_flush_cb(s, -EIO);
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 02e805f070..7f5ef8de1d 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -440,6 +440,7 @@ struct IDEState {
     int lba;
     int cd_sector_size;
     int atapi_dma; /* true if dma is requested for the packet cmd */
+    BlockAcctCookie acct;
     /* ATA DMA state */
     int io_buffer_size;
     QEMUSGList sg;
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 44fb3fef60..fdf5d75082 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -52,8 +52,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
         m->aiocb = NULL;
         qemu_sglist_destroy(&s->sg);
         ide_atapi_io_error(s, ret);
-        io->dma_end(opaque);
-        return;
+        goto done;
     }
 
     if (s->io_buffer_size > 0) {
@@ -71,8 +70,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
         ide_atapi_cmd_ok(s);
 
     if (io->len == 0) {
-        io->dma_end(opaque);
-        return;
+        goto done;
     }
 
     /* launch next transfer */
@@ -92,9 +90,14 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
         /* Note: media not present is the most likely case */
         ide_atapi_cmd_error(s, SENSE_NOT_READY,
                             ASC_MEDIUM_NOT_PRESENT);
-        io->dma_end(opaque);
-        return;
+        goto done;
     }
+    return;
+
+done:
+    bdrv_acct_done(s->bs, &s->acct);
+    io->dma_end(opaque);
+    return;
 }
 
 static void pmac_ide_transfer_cb(void *opaque, int ret)
@@ -109,8 +112,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
         m->aiocb = NULL;
         qemu_sglist_destroy(&s->sg);
 	ide_dma_error(s);
-        io->dma_end(io);
-        return;
+        goto done;
     }
 
     sector_num = ide_get_sector(s);
@@ -130,10 +132,8 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
     }
 
     /* end of DMA ? */
-
     if (io->len == 0) {
-        io->dma_end(io);
-	return;
+        goto done;
     }
 
     /* launch next transfer */
@@ -163,6 +163,12 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
 
     if (!m->aiocb)
         pmac_ide_transfer_cb(io, -1);
+    return;
+done:
+    if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
+        bdrv_acct_done(s->bs, &s->acct);
+    }
+    io->dma_end(io);
 }
 
 static void pmac_ide_transfer(DBDMA_io *io)
@@ -172,10 +178,22 @@ static void pmac_ide_transfer(DBDMA_io *io)
 
     s->io_buffer_size = 0;
     if (s->drive_kind == IDE_CD) {
+        bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ);
         pmac_ide_atapi_transfer_cb(io, 0);
         return;
     }
 
+    switch (s->dma_cmd) {
+    case IDE_DMA_READ:
+        bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ);
+        break;
+    case IDE_DMA_WRITE:
+        bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_WRITE);
+        break;
+    default:
+        break;
+    }
+
     pmac_ide_transfer_cb(io, 0);
 }
 
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index 3c8982ea29..281410899f 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -13,13 +13,11 @@
 #include "boards.h"
 #include "arm-misc.h"
 #include "net.h"
-#include "exec-memory.h"
 
 typedef struct {
     SysBusDevice busdev;
     uint32_t memsz;
-    MemoryRegion flash;
-    bool flash_mapped;
+    uint32_t flash_offset;
     uint32_t cm_osc;
     uint32_t cm_ctrl;
     uint32_t cm_lock;
@@ -110,15 +108,9 @@ static uint32_t integratorcm_read(void *opaque, target_phys_addr_t offset)
 static void integratorcm_do_remap(integratorcm_state *s, int flash)
 {
     if (flash) {
-        if (s->flash_mapped) {
-            sysbus_del_memory(&s->busdev, &s->flash);
-            s->flash_mapped = false;
-        }
+        cpu_register_physical_memory(0, 0x100000, IO_MEM_RAM);
     } else {
-        if (!s->flash_mapped) {
-            sysbus_add_memory_overlap(&s->busdev, 0, &s->flash, 1);
-            s->flash_mapped = true;
-        }
+        cpu_register_physical_memory(0, 0x100000, s->flash_offset | IO_MEM_RAM);
     }
     //??? tlb_flush (cpu_single_env, 1);
 }
@@ -260,8 +252,7 @@ static int integratorcm_init(SysBusDevice *dev)
     }
     memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
     s->cm_init = 0x00000112;
-    memory_region_init_ram(&s->flash, NULL, "integrator.flash", 0x100000);
-    s->flash_mapped = false;
+    s->flash_offset = qemu_ram_alloc(NULL, "integrator.flash", 0x100000);
 
     iomemtype = cpu_register_io_memory(integratorcm_readfn,
                                        integratorcm_writefn, s,
@@ -465,9 +456,7 @@ static void integratorcp_init(ram_addr_t ram_size,
                      const char *initrd_filename, const char *cpu_model)
 {
     CPUState *env;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
-    MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
+    ram_addr_t ram_offset;
     qemu_irq pic[32];
     qemu_irq *cpu_pic;
     DeviceState *dev;
@@ -480,14 +469,13 @@ static void integratorcp_init(ram_addr_t ram_size,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
-    memory_region_init_ram(ram, NULL, "integrator.ram", ram_size);
+    ram_offset = qemu_ram_alloc(NULL, "integrator.ram", ram_size);
     /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash.  */
     /* ??? RAM should repeat to fill physical memory space.  */
     /* SDRAM at address zero*/
-    memory_region_add_subregion(address_space_mem, 0, ram);
+    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
     /* And again at address 0x80000000 */
-    memory_region_init_alias(ram_alias, "ram.alias", ram, 0, ram_size);
-    memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias);
+    cpu_register_physical_memory(0x80000000, ram_size, ram_offset | IO_MEM_RAM);
 
     dev = qdev_create(NULL, "integrator_core");
     qdev_prop_set_uint32(dev, "memsz", ram_size >> 20);
diff --git a/hw/leon3.c b/hw/leon3.c
index 607ec852fe..a62a9419f3 100644
--- a/hw/leon3.c
+++ b/hw/leon3.c
@@ -29,7 +29,6 @@
 #include "loader.h"
 #include "elf.h"
 #include "trace.h"
-#include "exec-memory.h"
 
 #include "grlib.h"
 
@@ -101,9 +100,7 @@ static void leon3_generic_hw_init(ram_addr_t  ram_size,
                                   const char *cpu_model)
 {
     CPUState   *env;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
-    MemoryRegion *prom = g_new(MemoryRegion, 1);
+    ram_addr_t  ram_offset, prom_offset;
     int         ret;
     char       *filename;
     qemu_irq   *cpu_irqs = NULL;
@@ -142,14 +139,14 @@ static void leon3_generic_hw_init(ram_addr_t  ram_size,
         exit(1);
     }
 
-    memory_region_init_ram(ram, NULL, "leon3.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0x40000000, ram);
+    ram_offset = qemu_ram_alloc(NULL, "leon3.ram", ram_size);
+    cpu_register_physical_memory(0x40000000, ram_size, ram_offset | IO_MEM_RAM);
 
     /* Allocate BIOS */
     prom_size = 8 * 1024 * 1024; /* 8Mb */
-    memory_region_init_ram(prom, NULL, "Leon3.bios", prom_size);
-    memory_region_set_readonly(prom, true);
-    memory_region_add_subregion(address_space_mem, 0x00000000, prom);
+    prom_offset = qemu_ram_alloc(NULL, "Leon3.bios", prom_size);
+    cpu_register_physical_memory(0x00000000, prom_size,
+                                 prom_offset | IO_MEM_ROM);
 
     /* Load boot prom */
     if (bios_name == NULL) {
diff --git a/hw/lm32_boards.c b/hw/lm32_boards.c
index a84007b0ed..d18aad7435 100644
--- a/hw/lm32_boards.c
+++ b/hw/lm32_boards.c
@@ -28,7 +28,6 @@
 #include "elf.h"
 #include "lm32_hwsetup.h"
 #include "lm32.h"
-#include "exec-memory.h"
 
 typedef struct {
     CPUState *env;
@@ -77,9 +76,8 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used,
 {
     CPUState *env;
     DriveInfo *dinfo;
-    MemoryRegion *address_space_mem =  get_system_memory();
-    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_ram;
+    ram_addr_t phys_flash;
     qemu_irq *cpu_irq, irq[32];
     ResetInfo *reset_info;
     int i;
@@ -107,17 +105,16 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used,
 
     reset_info->flash_base = flash_base;
 
-    memory_region_init_ram(phys_ram, NULL, "lm32_evr.sdram", ram_size);
-    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
+    phys_ram = qemu_ram_alloc(NULL, "lm32_evr.sdram", ram_size);
+    cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi02_ops_be,
-                                  NULL, "lm32_evr.flash", flash_size);
+    phys_flash = qemu_ram_alloc(NULL, "lm32_evr.flash", flash_size);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Spansion S29NS128P */
     pflash_cfi02_register(flash_base, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                           flash_size / flash_sector_size, 1, 2,
-                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa);
+                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
@@ -167,9 +164,8 @@ static void lm32_uclinux_init(ram_addr_t ram_size_not_used,
 {
     CPUState *env;
     DriveInfo *dinfo;
-    MemoryRegion *address_space_mem =  get_system_memory();
-    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_ram;
+    ram_addr_t phys_flash;
     qemu_irq *cpu_irq, irq[32];
     HWSetup *hw;
     ResetInfo *reset_info;
@@ -204,17 +200,16 @@ static void lm32_uclinux_init(ram_addr_t ram_size_not_used,
 
     reset_info->flash_base = flash_base;
 
-    memory_region_init_ram(phys_ram, NULL, "lm32_uclinux.sdram", ram_size);
-    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
+    phys_ram = qemu_ram_alloc(NULL, "lm32_uclinux.sdram", ram_size);
+    cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
-                                  NULL, "lm32_uclinux.flash", flash_size);
+    phys_flash = qemu_ram_alloc(NULL, "lm32_uclinux.flash", flash_size);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Spansion S29NS128P */
     pflash_cfi02_register(flash_base, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                           flash_size / flash_sector_size, 1, 2,
-                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa);
+                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
diff --git a/hw/mainstone.c b/hw/mainstone.c
index 82e957149d..4792f0e3ed 100644
--- a/hw/mainstone.c
+++ b/hw/mainstone.c
@@ -17,7 +17,6 @@
 #include "flash.h"
 #include "blockdev.h"
 #include "sysbus.h"
-#include "exec-memory.h"
 
 /* Device addresses */
 #define MST_FPGA_PHYS	0x08000000
@@ -91,8 +90,7 @@ static struct arm_boot_info mainstone_binfo = {
     .ram_size = 0x04000000,
 };
 
-static void mainstone_common_init(MemoryRegion *address_space_mem,
-                ram_addr_t ram_size,
+static void mainstone_common_init(ram_addr_t ram_size,
                 const char *kernel_filename,
                 const char *kernel_cmdline, const char *initrd_filename,
                 const char *cpu_model, enum mainstone_model_e model, int arm_id)
@@ -103,23 +101,21 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
     DeviceState *mst_irq;
     DriveInfo *dinfo;
     int i;
-    MemoryRegion *rom = g_new(MemoryRegion, 1);
-    MemoryRegion *flashes = g_new(MemoryRegion, 2);
-    const MemoryRegionOps *flash_ops;
+    int be;
 
     if (!cpu_model)
         cpu_model = "pxa270-c5";
 
     /* Setup CPU & memory */
     cpu = pxa270_init(mainstone_binfo.ram_size, cpu_model);
-    memory_region_init_ram(rom, NULL, "mainstone.rom", MAINSTONE_ROM);
-    memory_region_set_readonly(rom, true);
-    memory_region_add_subregion(address_space_mem, 0, rom);
+    cpu_register_physical_memory(0, MAINSTONE_ROM,
+                    qemu_ram_alloc(NULL, "mainstone.rom",
+                                   MAINSTONE_ROM) | IO_MEM_ROM);
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    flash_ops = &pflash_cfi01_ops_be;
+    be = 1;
 #else
-    flash_ops = &pflash_cfi01_ops_le;
+    be = 0;
 #endif
     /* There are two 32MiB flash devices on the board */
     for (i = 0; i < 2; i ++) {
@@ -130,14 +126,13 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
             exit(1);
         }
 
-        memory_region_init_rom_device(&flashes[i], flash_ops,
-                                      NULL, (i ? "mainstone.flash1"
-                                               : "mainstone.flash0"),
-                                      MAINSTONE_FLASH);
         if (!pflash_cfi01_register(mainstone_flash_base[i],
-                                   &flashes[i], dinfo->bdrv, sector_len,
-                                   MAINSTONE_FLASH / sector_len, 4, 0, 0, 0,
-                                   0)) {
+                                   qemu_ram_alloc(NULL, i ? "mainstone.flash1" :
+                                                  "mainstone.flash0",
+                                                  MAINSTONE_FLASH),
+                                   dinfo->bdrv, sector_len,
+                                   MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0,
+                                   be)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
             exit(1);
         }
@@ -175,7 +170,7 @@ static void mainstone_init(ram_addr_t ram_size,
                 const char *kernel_filename, const char *kernel_cmdline,
                 const char *initrd_filename, const char *cpu_model)
 {
-    mainstone_common_init(get_system_memory(), ram_size, kernel_filename,
+    mainstone_common_init(ram_size, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, mainstone, 0x196);
 }
 
diff --git a/hw/mcf5208.c b/hw/mcf5208.c
index 1c2c0c48aa..8fe507f82f 100644
--- a/hw/mcf5208.c
+++ b/hw/mcf5208.c
@@ -13,7 +13,6 @@
 #include "boards.h"
 #include "loader.h"
 #include "elf.h"
-#include "exec-memory.h"
 
 #define SYS_FREQ 66000000
 
@@ -28,7 +27,6 @@
 #define PCSR_PRE_MASK   0x0f00
 
 typedef struct {
-    MemoryRegion iomem;
     qemu_irq irq;
     ptimer_state *timer;
     uint16_t pcsr;
@@ -45,7 +43,7 @@ static void m5208_timer_update(m5208_timer_state *s)
 }
 
 static void m5208_timer_write(void *opaque, target_phys_addr_t offset,
-                              uint64_t value, unsigned size)
+                              uint32_t value)
 {
     m5208_timer_state *s = (m5208_timer_state *)opaque;
     int prescale;
@@ -106,8 +104,7 @@ static void m5208_timer_trigger(void *opaque)
     m5208_timer_update(s);
 }
 
-static uint64_t m5208_timer_read(void *opaque, target_phys_addr_t addr,
-                                 unsigned size)
+static uint32_t m5208_timer_read(void *opaque, target_phys_addr_t addr)
 {
     m5208_timer_state *s = (m5208_timer_state *)opaque;
     switch (addr) {
@@ -123,14 +120,19 @@ static uint64_t m5208_timer_read(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static const MemoryRegionOps m5208_timer_ops = {
-    .read = m5208_timer_read,
-    .write = m5208_timer_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUReadMemoryFunc * const m5208_timer_readfn[] = {
+   m5208_timer_read,
+   m5208_timer_read,
+   m5208_timer_read
 };
 
-static uint64_t m5208_sys_read(void *opaque, target_phys_addr_t addr,
-                               unsigned size)
+static CPUWriteMemoryFunc * const m5208_timer_writefn[] = {
+   m5208_timer_write,
+   m5208_timer_write,
+   m5208_timer_write
+};
+
+static uint32_t m5208_sys_read(void *opaque, target_phys_addr_t addr)
 {
     switch (addr) {
     case 0x110: /* SDCS0 */
@@ -152,36 +154,45 @@ static uint64_t m5208_sys_read(void *opaque, target_phys_addr_t addr,
 }
 
 static void m5208_sys_write(void *opaque, target_phys_addr_t addr,
-                            uint64_t value, unsigned size)
+                            uint32_t value)
 {
     hw_error("m5208_sys_write: Bad offset 0x%x\n", (int)addr);
 }
 
-static const MemoryRegionOps m5208_sys_ops = {
-    .read = m5208_sys_read,
-    .write = m5208_sys_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUReadMemoryFunc * const m5208_sys_readfn[] = {
+   m5208_sys_read,
+   m5208_sys_read,
+   m5208_sys_read
+};
+
+static CPUWriteMemoryFunc * const m5208_sys_writefn[] = {
+   m5208_sys_write,
+   m5208_sys_write,
+   m5208_sys_write
 };
 
-static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic)
+static void mcf5208_sys_init(qemu_irq *pic)
 {
-    MemoryRegion *iomem = g_new(MemoryRegion, 1);
+    int iomemtype;
     m5208_timer_state *s;
     QEMUBH *bh;
     int i;
 
+    iomemtype = cpu_register_io_memory(m5208_sys_readfn,
+                                       m5208_sys_writefn, NULL,
+                                       DEVICE_NATIVE_ENDIAN);
     /* SDRAMC.  */
-    memory_region_init_io(iomem, &m5208_sys_ops, NULL, "m5208-sys", 0x00004000);
-    memory_region_add_subregion(address_space, 0xfc0a8000, iomem);
+    cpu_register_physical_memory(0xfc0a8000, 0x00004000, iomemtype);
     /* Timers.  */
     for (i = 0; i < 2; i++) {
         s = (m5208_timer_state *)g_malloc0(sizeof(m5208_timer_state));
         bh = qemu_bh_new(m5208_timer_trigger, s);
         s->timer = ptimer_init(bh);
-        memory_region_init_io(&s->iomem, &m5208_timer_ops, s,
-                              "m5208-timer", 0x00004000);
-        memory_region_add_subregion(address_space, 0xfc080000 + 0x4000 * i,
-                                    &s->iomem);
+        iomemtype = cpu_register_io_memory(m5208_timer_readfn,
+                                           m5208_timer_writefn, s,
+                                           DEVICE_NATIVE_ENDIAN);
+        cpu_register_physical_memory(0xfc080000 + 0x4000 * i, 0x00004000,
+                                     iomemtype);
         s->irq = pic[4 + i];
     }
 }
@@ -196,9 +207,6 @@ static void mcf5208evb_init(ram_addr_t ram_size,
     uint64_t elf_entry;
     target_phys_addr_t entry;
     qemu_irq *pic;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
-    MemoryRegion *sram = g_new(MemoryRegion, 1);
 
     if (!cpu_model)
         cpu_model = "m5208";
@@ -213,12 +221,12 @@ static void mcf5208evb_init(ram_addr_t ram_size,
     /* TODO: Configure BARs.  */
 
     /* DRAM at 0x40000000 */
-    memory_region_init_ram(ram, NULL, "mcf5208.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0x40000000, ram);
+    cpu_register_physical_memory(0x40000000, ram_size,
+        qemu_ram_alloc(NULL, "mcf5208.ram", ram_size) | IO_MEM_RAM);
 
     /* Internal SRAM.  */
-    memory_region_init_ram(sram, NULL, "mcf5208.sram", 16384);
-    memory_region_add_subregion(address_space_mem, 0x80000000, sram);
+    cpu_register_physical_memory(0x80000000, 16384,
+        qemu_ram_alloc(NULL, "mcf5208.sram", 16384) | IO_MEM_RAM);
 
     /* Internal peripherals.  */
     pic = mcf_intc_init(0xfc048000, env);
@@ -227,7 +235,7 @@ static void mcf5208evb_init(ram_addr_t ram_size,
     mcf_uart_mm_init(0xfc064000, pic[27], serial_hds[1]);
     mcf_uart_mm_init(0xfc068000, pic[28], serial_hds[2]);
 
-    mcf5208_sys_init(address_space_mem, pic);
+    mcf5208_sys_init(pic);
 
     if (nb_nics > 1) {
         fprintf(stderr, "Too many NICs\n");
diff --git a/hw/milkymist-minimac2.c b/hw/milkymist-minimac2.c
index fb48e37187..cd360264c1 100644
--- a/hw/milkymist-minimac2.c
+++ b/hw/milkymist-minimac2.c
@@ -97,8 +97,6 @@ struct MilkymistMinimac2State {
     NICConf conf;
     char *phy_model;
     target_phys_addr_t buffers_base;
-    MemoryRegion buffers;
-    MemoryRegion regs_region;
 
     qemu_irq rx_irq;
     qemu_irq tx_irq;
@@ -322,8 +320,8 @@ static ssize_t minimac2_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
     return size;
 }
 
-static uint64_t
-minimac2_read(void *opaque, target_phys_addr_t addr, unsigned size)
+static uint32_t
+minimac2_read(void *opaque, target_phys_addr_t addr)
 {
     MilkymistMinimac2State *s = opaque;
     uint32_t r = 0;
@@ -352,8 +350,7 @@ minimac2_read(void *opaque, target_phys_addr_t addr, unsigned size)
 }
 
 static void
-minimac2_write(void *opaque, target_phys_addr_t addr, uint64_t value,
-               unsigned size)
+minimac2_write(void *opaque, target_phys_addr_t addr, uint32_t value)
 {
     MilkymistMinimac2State *s = opaque;
 
@@ -398,14 +395,16 @@ minimac2_write(void *opaque, target_phys_addr_t addr, uint64_t value,
     }
 }
 
-static const MemoryRegionOps minimac2_ops = {
-    .read = minimac2_read,
-    .write = minimac2_write,
-    .valid = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUReadMemoryFunc * const minimac2_read_fn[] = {
+    NULL,
+    NULL,
+    &minimac2_read,
+};
+
+static CPUWriteMemoryFunc * const minimac2_write_fn[] = {
+    NULL,
+    NULL,
+    &minimac2_write,
 };
 
 static int minimac2_can_rx(VLANClientState *nc)
@@ -458,23 +457,25 @@ static NetClientInfo net_milkymist_minimac2_info = {
 static int milkymist_minimac2_init(SysBusDevice *dev)
 {
     MilkymistMinimac2State *s = FROM_SYSBUS(typeof(*s), dev);
+    int regs;
+    ram_addr_t buffers;
     size_t buffers_size = TARGET_PAGE_ALIGN(3 * MINIMAC2_BUFFER_SIZE);
 
     sysbus_init_irq(dev, &s->rx_irq);
     sysbus_init_irq(dev, &s->tx_irq);
 
-    memory_region_init_io(&s->regs_region, &minimac2_ops, s,
-                          "minimac2-mmio", R_MAX * 4);
-    sysbus_init_mmio_region(dev, &s->regs_region);
+    regs = cpu_register_io_memory(minimac2_read_fn, minimac2_write_fn, s,
+            DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, R_MAX * 4, regs);
 
     /* register buffers memory */
-    memory_region_init_ram(&s->buffers, NULL, "milkymist_minimac2.buffers",
-                           buffers_size);
-    s->rx0_buf = memory_region_get_ram_ptr(&s->buffers);
+    buffers = qemu_ram_alloc(NULL, "milkymist_minimac2.buffers", buffers_size);
+    s->rx0_buf = qemu_get_ram_ptr(buffers);
     s->rx1_buf = s->rx0_buf + MINIMAC2_BUFFER_SIZE;
     s->tx_buf = s->rx1_buf + MINIMAC2_BUFFER_SIZE;
 
-    sysbus_add_memory(dev, s->buffers_base, &s->buffers);
+    cpu_register_physical_memory(s->buffers_base, buffers_size,
+            buffers | IO_MEM_RAM);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf,
diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c
index ef4d9ee2ce..fe4eedb2cb 100644
--- a/hw/milkymist-softusb.c
+++ b/hw/milkymist-softusb.c
@@ -49,9 +49,6 @@ struct MilkymistSoftUsbState {
     HIDState hid_kbd;
     HIDState hid_mouse;
 
-    MemoryRegion regs_region;
-    MemoryRegion pmem;
-    MemoryRegion dmem;
     qemu_irq irq;
 
     /* device properties */
@@ -71,8 +68,7 @@ struct MilkymistSoftUsbState {
 };
 typedef struct MilkymistSoftUsbState MilkymistSoftUsbState;
 
-static uint64_t softusb_read(void *opaque, target_phys_addr_t addr,
-                             unsigned size)
+static uint32_t softusb_read(void *opaque, target_phys_addr_t addr)
 {
     MilkymistSoftUsbState *s = opaque;
     uint32_t r = 0;
@@ -95,8 +91,7 @@ static uint64_t softusb_read(void *opaque, target_phys_addr_t addr,
 }
 
 static void
-softusb_write(void *opaque, target_phys_addr_t addr, uint64_t value,
-              unsigned size)
+softusb_write(void *opaque, target_phys_addr_t addr, uint32_t value)
 {
     MilkymistSoftUsbState *s = opaque;
 
@@ -115,14 +110,16 @@ softusb_write(void *opaque, target_phys_addr_t addr, uint64_t value,
     }
 }
 
-static const MemoryRegionOps softusb_mmio_ops = {
-    .read = softusb_read,
-    .write = softusb_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-    .valid = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
+static CPUReadMemoryFunc * const softusb_read_fn[] = {
+    NULL,
+    NULL,
+    &softusb_read,
+};
+
+static CPUWriteMemoryFunc * const softusb_write_fn[] = {
+    NULL,
+    NULL,
+    &softusb_write,
 };
 
 static inline void softusb_read_dmem(MilkymistSoftUsbState *s,
@@ -259,20 +256,23 @@ static void milkymist_softusb_reset(DeviceState *d)
 static int milkymist_softusb_init(SysBusDevice *dev)
 {
     MilkymistSoftUsbState *s = FROM_SYSBUS(typeof(*s), dev);
+    int softusb_regs;
+    ram_addr_t pmem_ram;
+    ram_addr_t dmem_ram;
 
     sysbus_init_irq(dev, &s->irq);
 
-    memory_region_init_io(&s->regs_region, &softusb_mmio_ops, s,
-                          "milkymist-softusb", R_MAX * 4);
-    sysbus_init_mmio_region(dev, &s->regs_region);
+    softusb_regs = cpu_register_io_memory(softusb_read_fn, softusb_write_fn, s,
+            DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, R_MAX * 4, softusb_regs);
 
     /* register pmem and dmem */
-    memory_region_init_ram(&s->pmem, NULL, "milkymist_softusb.pmem",
-                           s->pmem_size);
-    sysbus_add_memory(dev, s->pmem_base, &s->pmem);
-    memory_region_init_ram(&s->dmem, NULL, "milkymist_softusb.dmem",
-                           s->dmem_size);
-    sysbus_add_memory(dev, s->dmem_base, &s->dmem);
+    pmem_ram = qemu_ram_alloc(NULL, "milkymist_softusb.pmem", s->pmem_size);
+    cpu_register_physical_memory(s->pmem_base, s->pmem_size,
+            pmem_ram | IO_MEM_RAM);
+    dmem_ram = qemu_ram_alloc(NULL, "milkymist_softusb.dmem", s->dmem_size);
+    cpu_register_physical_memory(s->dmem_base, s->dmem_size,
+            dmem_ram | IO_MEM_RAM);
 
     hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain);
     hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain);
diff --git a/hw/milkymist-tmu2.c b/hw/milkymist-tmu2.c
index 790cdcb41c..953d42f16b 100644
--- a/hw/milkymist-tmu2.c
+++ b/hw/milkymist-tmu2.c
@@ -73,7 +73,7 @@ enum {
 struct vertex {
     int x;
     int y;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 struct MilkymistTMU2State {
     SysBusDevice busdev;
diff --git a/hw/milkymist.c b/hw/milkymist.c
index ef21ccaba1..93288c8401 100644
--- a/hw/milkymist.c
+++ b/hw/milkymist.c
@@ -29,7 +29,6 @@
 #include "blockdev.h"
 #include "milkymist-hw.h"
 #include "lm32.h"
-#include "exec-memory.h"
 
 #define BIOS_FILENAME    "mmone-bios.bin"
 #define BIOS_OFFSET      0x00860000
@@ -82,9 +81,8 @@ milkymist_init(ram_addr_t ram_size_not_used,
     CPUState *env;
     int kernel_size;
     DriveInfo *dinfo;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *phys_sdram = g_new(MemoryRegion, 1);
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_sdram;
+    ram_addr_t phys_flash;
     qemu_irq irq[32], *cpu_irq;
     int i;
     char *bios_filename;
@@ -111,17 +109,17 @@ milkymist_init(ram_addr_t ram_size_not_used,
 
     cpu_lm32_set_phys_msb_ignore(env, 1);
 
-    memory_region_init_ram(phys_sdram, NULL, "milkymist.sdram", sdram_size);
-    memory_region_add_subregion(address_space_mem, sdram_base, phys_sdram);
+    phys_sdram = qemu_ram_alloc(NULL, "milkymist.sdram", sdram_size);
+    cpu_register_physical_memory(sdram_base, sdram_size,
+            phys_sdram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
-                                  NULL, "milkymist.flash", flash_size);
+    phys_flash = qemu_ram_alloc(NULL, "milkymist.flash", flash_size);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Numonyx JS28F256J3F105 */
     pflash_cfi01_register(flash_base, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                           flash_size / flash_sector_size, 2,
-                          0x00, 0x89, 0x00, 0x1d);
+                          0x00, 0x89, 0x00, 0x1d, 1);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
diff --git a/hw/mips.h b/hw/mips.h
index 97d7b9e5ad..8ce41fc4be 100644
--- a/hw/mips.h
+++ b/hw/mips.h
@@ -2,19 +2,12 @@
 #define HW_MIPS_H
 /* Definitions for mips board emulation.  */
 
-#include "memory.h"
-
 /* gt64xxx.c */
 PCIBus *gt64120_register(qemu_irq *pic);
 
 /* bonito.c */
 PCIBus *bonito_init(qemu_irq *pic);
 
-/* g364fb.c */
-int g364fb_mm_init(MemoryRegion *system_memory, target_phys_addr_t vram_base,
-                   target_phys_addr_t ctrl_base, int it_shift,
-                   qemu_irq irq);
-
 /* mipsnet.c */
 void mipsnet_init(int base, qemu_irq irq, NICInfo *nd);
 
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index a74108646c..f3c9f93204 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -195,8 +195,20 @@ void mips_jazz_init (ram_addr_t ram_size,
     /* Video card */
     switch (jazz_model) {
     case JAZZ_MAGNUM:
-        g364fb_mm_init(get_system_memory(), 0x40000000, 0x60000000, 0,
-                       rc4030[3]);
+        dev = qdev_create(NULL, "sysbus-g364");
+        qdev_init_nofail(dev);
+        sysbus = sysbus_from_qdev(dev);
+        sysbus_mmio_map(sysbus, 0, 0x60080000);
+        sysbus_mmio_map(sysbus, 1, 0x40000000);
+        sysbus_connect_irq(sysbus, 0, rc4030[3]);
+        {
+            /* Simple ROM, so user doesn't have to provide one */
+            ram_addr_t rom_offset = qemu_ram_alloc(NULL, "g364fb.rom", 0x80000);
+            uint8_t *rom = qemu_get_ram_ptr(rom_offset);
+            cpu_register_physical_memory(0x60000000, 0x80000,
+                                         rom_offset | IO_MEM_ROM);
+            rom[0] = 0x10; /* Mips G364 */
+        }
         break;
     case JAZZ_PICA61:
         isa_vga_mm_init(0x40000000, 0x60000000, 0, get_system_memory());
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index b5c9bcfa51..a0adb566ab 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -46,7 +46,6 @@
 #include "elf.h"
 #include "mc146818rtc.h"
 #include "blockdev.h"
-#include "exec-memory.h"
 
 //#define DEBUG_BOARD_INIT
 
@@ -733,6 +732,12 @@ static int64_t load_kernel (void)
     return kernel_entry;
 }
 
+static void malta_mips_config(CPUState *env)
+{
+    env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) |
+                         ((smp_cpus * env->nr_threads - 1) << CP0MVPC0_PTC);
+}
+
 static void main_cpu_reset(void *opaque)
 {
     CPUState *env = opaque;
@@ -744,6 +749,8 @@ static void main_cpu_reset(void *opaque)
     if (loaderparams.kernel_filename) {
         env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
     }
+
+    malta_mips_config(env);
 }
 
 static void cpu_request_exit(void *opaque, int irq, int level)
@@ -763,10 +770,7 @@ void mips_malta_init (ram_addr_t ram_size,
 {
     char *filename;
     ram_addr_t ram_offset;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *bios = g_new(MemoryRegion, 1);
-    MemoryRegion *bios_1e0 = g_new(MemoryRegion, 1);
-    MemoryRegion *bios_1fc = g_new(MemoryRegion, 1);
+    ram_addr_t bios_offset;
     target_long bios_size;
     int64_t kernel_entry;
     PCIBus *pci_bus;
@@ -781,7 +785,7 @@ void mips_malta_init (ram_addr_t ram_size,
     DriveInfo *fd[MAX_FD];
     int fl_idx = 0;
     int fl_sectors = 0;
-    const MemoryRegionOps *bios_ops;
+    int be;
 
     /* Make sure the first 3 serial ports are associated with a device. */
     for(i = 0; i < 3; i++) {
@@ -800,12 +804,19 @@ void mips_malta_init (ram_addr_t ram_size,
         cpu_model = "24Kf";
 #endif
     }
-    env = cpu_init(cpu_model);
-    if (!env) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
+
+    for (i = 0; i < smp_cpus; i++) {
+        env = cpu_init(cpu_model);
+        if (!env) {
+            fprintf(stderr, "Unable to find CPU definition\n");
+            exit(1);
+        }
+        /* Init internal devices */
+        cpu_mips_irq_init_cpu(env);
+        cpu_mips_clock_init(env);
+        qemu_register_reset(main_cpu_reset, env);
     }
-    qemu_register_reset(main_cpu_reset, env);
+    env = first_cpu;
 
     /* allocate RAM */
     if (ram_size > (256 << 20)) {
@@ -814,24 +825,23 @@ void mips_malta_init (ram_addr_t ram_size,
                 ((unsigned int)ram_size / (1 << 20)));
         exit(1);
     }
-#ifdef TARGET_WORDS_BIGENDIAN
-    bios_ops = &pflash_cfi01_ops_be;
-#else
-    bios_ops = &pflash_cfi01_ops_le;
-#endif
-
     ram_offset = qemu_ram_alloc(NULL, "mips_malta.ram", ram_size);
-    memory_region_init_rom_device(bios, bios_ops, NULL,
-                                  "mips_malta.bios", BIOS_SIZE);
+    bios_offset = qemu_ram_alloc(NULL, "mips_malta.bios", BIOS_SIZE);
+
 
     cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
 
     /* Map the bios at two physical locations, as on the real board. */
-    memory_region_init_alias(bios_1e0, "bios-1e0", bios, 0, BIOS_SIZE);
-    memory_region_add_subregion(address_space_mem, 0x1e000000LL, bios_1e0);
-    memory_region_init_alias(bios_1fc, "bios-1fc", bios, 0, BIOS_SIZE);
-    memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios_1fc);
+    cpu_register_physical_memory(0x1e000000LL,
+                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
+    cpu_register_physical_memory(0x1fc00000LL,
+                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
 
+#ifdef TARGET_WORDS_BIGENDIAN
+    be = 1;
+#else
+    be = 0;
+#endif
     /* FPGA */
     malta_fpga_init(0x1f000000LL, env->irq[2], serial_hds[2]);
 
@@ -843,7 +853,7 @@ void mips_malta_init (ram_addr_t ram_size,
         loaderparams.kernel_cmdline = kernel_cmdline;
         loaderparams.initrd_filename = initrd_filename;
         kernel_entry = load_kernel();
-        write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
+        write_bootloader(env, qemu_get_ram_ptr(bios_offset), kernel_entry);
     } else {
         dinfo = drive_get(IF_PFLASH, 0, fl_idx);
         if (dinfo) {
@@ -852,13 +862,13 @@ void mips_malta_init (ram_addr_t ram_size,
             fl_sectors = bios_size >> 16;
 #ifdef DEBUG_BOARD_INIT
             printf("Register parallel flash %d size " TARGET_FMT_lx " at "
-                   "addr %08llx '%s' %x\n",
-                   fl_idx, bios_size, 0x1e000000LL,
+                   "offset %08lx addr %08llx '%s' %x\n",
+                   fl_idx, bios_size, bios_offset, 0x1e000000LL,
                    bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-            pflash_cfi01_register(0x1e000000LL, bios,
+            pflash_cfi01_register(0x1e000000LL, bios_offset,
                                   dinfo->bdrv, 65536, fl_sectors,
-                                  4, 0x0000, 0x0000, 0x0000, 0x0000);
+                                  4, 0x0000, 0x0000, 0x0000, 0x0000, be);
             fl_idx++;
         } else {
             /* Load a BIOS image. */
@@ -883,7 +893,7 @@ void mips_malta_init (ram_addr_t ram_size,
            a neat trick which allows bi-endian firmware. */
 #ifndef TARGET_WORDS_BIGENDIAN
         {
-            uint32_t *addr = memory_region_get_ram_ptr(bios);
+            uint32_t *addr = qemu_get_ram_ptr(bios_offset);;
             uint32_t *end = addr + bios_size;
             while (addr < end) {
                 bswap32s(addr);
@@ -895,7 +905,7 @@ void mips_malta_init (ram_addr_t ram_size,
     /* Board ID = 0x420 (Malta Board with CoreLV)
        XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
        map to the board ID. */
-    stl_p(memory_region_get_ram_ptr(bios) + 0x10, 0x00000420);
+    stl_p(qemu_get_ram_ptr(bios_offset) + 0x10, 0x00000420);
 
     /* Init internal devices */
     cpu_mips_irq_init_cpu(env);
@@ -960,6 +970,7 @@ static QEMUMachine mips_malta_machine = {
     .name = "malta",
     .desc = "MIPS Malta Core LV",
     .init = mips_malta_init,
+    .max_cpus = 16,
     .is_default = 1,
 };
 
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 51dc8684be..9d90568e4e 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -23,7 +23,6 @@
 #include "elf.h"
 #include "mc146818rtc.h"
 #include "blockdev.h"
-#include "exec-memory.h"
 
 #define MAX_IDE_BUS 2
 
@@ -164,8 +163,7 @@ void mips_r4k_init (ram_addr_t ram_size,
 {
     char *filename;
     ram_addr_t ram_offset;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *bios = g_new(MemoryRegion, 1);
+    ram_addr_t bios_offset;
     int bios_size;
     CPUState *env;
     ResetData *reset_info;
@@ -229,20 +227,18 @@ void mips_r4k_init (ram_addr_t ram_size,
     be = 0;
 #endif
     if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) {
-        memory_region_init_ram(bios, NULL, "mips_r4k.bios", BIOS_SIZE);
-        memory_region_set_readonly(bios, true);
-        memory_region_add_subregion(address_space_mem, 0x1fc00000, bios);
+        bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", BIOS_SIZE);
+	cpu_register_physical_memory(0x1fc00000, BIOS_SIZE,
+                                     bios_offset | IO_MEM_ROM);
+
         load_image_targphys(filename, 0x1fc00000, BIOS_SIZE);
     } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
         uint32_t mips_rom = 0x00400000;
-        memory_region_init_rom_device(bios,
-                                      (be ? &pflash_cfi01_ops_be
-                                          : &pflash_cfi01_ops_le),
-                                      NULL, "mips_r4k.bios", mips_rom);
-        if (!pflash_cfi01_register(0x1fc00000, bios,
+        bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", mips_rom);
+        if (!pflash_cfi01_register(0x1fc00000, bios_offset,
                                    dinfo->bdrv, sector_len,
                                    mips_rom / sector_len,
-                                   4, 0, 0, 0, 0)) {
+                                   4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
 	}
     }
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 5e74ee7fd7..63dd391176 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1502,7 +1502,6 @@ static void musicpal_init(ram_addr_t ram_size,
     unsigned long flash_size;
     DriveInfo *dinfo;
     ram_addr_t sram_off;
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     if (!cpu_model) {
         cpu_model = "arm926";
@@ -1566,23 +1565,21 @@ static void musicpal_init(ram_addr_t ram_size,
          * image is smaller than 32 MB.
          */
 #ifdef TARGET_WORDS_BIGENDIAN
-        memory_region_init_rom_device(flash, &pflash_cfi02_ops_be,
-                                      NULL, "musicpal.flash", flash_size);
-        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, flash,
+        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL,
+                              "musicpal.flash", flash_size),
                               dinfo->bdrv, 0x10000,
                               (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
-                              0x5555, 0x2AAA);
+                              0x5555, 0x2AAA, 1);
 #else
-        memory_region_init_rom_device(flash, &pflash_cfi02_ops_le,
-                                      NULL, "musicpal.flash", flash_size);
-        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, flash,
+        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL,
+                              "musicpal.flash", flash_size),
                               dinfo->bdrv, 0x10000,
                               (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
-                              0x5555, 0x2AAA);
+                              0x5555, 0x2AAA, 0);
 #endif
 
     }
diff --git a/hw/nseries.c b/hw/nseries.c
index f7aae7a59e..af287dd6dc 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -32,7 +32,7 @@
 #include "bt.h"
 #include "loader.h"
 #include "blockdev.h"
-#include "tusb6010.h"
+#include "sysbus.h"
 
 /* Nokia N8x0 support */
 struct n800_s {
@@ -49,10 +49,10 @@ struct n800_s {
     int keymap[0x80];
     DeviceState *kbd;
 
-    TUSBState *usb;
+    DeviceState *usb;
     void *retu;
     void *tahvo;
-    void *nand;
+    DeviceState *nand;
 };
 
 /* GPIO pins */
@@ -167,13 +167,21 @@ static void n8x0_nand_setup(struct n800_s *s)
     char *otp_region;
     DriveInfo *dinfo;
 
-    dinfo = drive_get(IF_MTD, 0, 0);
+    s->nand = qdev_create(NULL, "onenand");
+    qdev_prop_set_uint16(s->nand, "manufacturer_id", NAND_MFR_SAMSUNG);
     /* Either 0x40 or 0x48 are OK for the device ID */
-    s->nand = onenand_init(dinfo ? dinfo->bdrv : 0,
-                    NAND_MFR_SAMSUNG, 0x48, 0, 1,
-                    qdev_get_gpio_in(s->cpu->gpio, N8X0_ONENAND_GPIO));
-    omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, 0, onenand_base_update,
-                    onenand_base_unmap, s->nand);
+    qdev_prop_set_uint16(s->nand, "device_id", 0x48);
+    qdev_prop_set_uint16(s->nand, "version_id", 0);
+    qdev_prop_set_int32(s->nand, "shift", 1);
+    dinfo = drive_get(IF_MTD, 0, 0);
+    if (dinfo && dinfo->bdrv) {
+        qdev_prop_set_drive_nofail(s->nand, "drive", dinfo->bdrv);
+    }
+    qdev_init_nofail(s->nand);
+    sysbus_connect_irq(sysbus_from_qdev(s->nand), 0,
+                       qdev_get_gpio_in(s->cpu->gpio, N8X0_ONENAND_GPIO));
+    omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS,
+                     sysbus_mmio_get_region(sysbus_from_qdev(s->nand), 0));
     otp_region = onenand_raw_otp(s->nand);
 
     memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac));
@@ -756,27 +764,21 @@ static void n8x0_uart_setup(struct n800_s *s)
     omap_uart_attach(s->cpu->uart[BT_UART], radio);
 }
 
-static void n8x0_usb_power_cb(void *opaque, int line, int level)
-{
-    struct n800_s *s = opaque;
-
-    tusb6010_power(s->usb, level);
-}
-
 static void n8x0_usb_setup(struct n800_s *s)
 {
-    qemu_irq tusb_irq = qdev_get_gpio_in(s->cpu->gpio, N8X0_TUSB_INT_GPIO);
-    qemu_irq tusb_pwr = qemu_allocate_irqs(n8x0_usb_power_cb, s, 1)[0];
-    TUSBState *tusb = tusb6010_init(tusb_irq);
-
+    SysBusDevice *dev;
+    s->usb = qdev_create(NULL, "tusb6010");
+    dev = sysbus_from_qdev(s->usb);
+    qdev_init_nofail(s->usb);
+    sysbus_connect_irq(dev, 0,
+                       qdev_get_gpio_in(s->cpu->gpio, N8X0_TUSB_INT_GPIO));
     /* Using the NOR interface */
     omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_ASYNC_CS,
-                    tusb6010_async_io(tusb), NULL, NULL, tusb);
+                     sysbus_mmio_get_region(dev, 0));
     omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_SYNC_CS,
-                    tusb6010_sync_io(tusb), NULL, NULL, tusb);
-
-    s->usb = tusb;
-    qdev_connect_gpio_out(s->cpu->gpio, N8X0_TUSB_ENABLE_GPIO, tusb_pwr);
+                     sysbus_mmio_get_region(dev, 1));
+    qdev_connect_gpio_out(s->cpu->gpio, N8X0_TUSB_ENABLE_GPIO,
+                          qdev_get_gpio_in(s->usb, 0)); /* tusb_pwr */
 }
 
 /* Setup done before the main bootloader starts by some early setup code
diff --git a/hw/omap.h b/hw/omap.h
index db101c61f3..d9ab006ae0 100644
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -118,11 +118,12 @@ void omap_sdrc_reset(struct omap_sdrc_s *s);
 
 /* OMAP2 general purpose memory controller */
 struct omap_gpmc_s;
-struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq);
+struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
+                                   target_phys_addr_t base,
+                                   qemu_irq irq, qemu_irq drq);
 void omap_gpmc_reset(struct omap_gpmc_s *s);
-void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem,
-                void (*base_upd)(void *opaque, target_phys_addr_t new),
-                void (*unmap)(void *opaque), void *opaque);
+void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem);
+void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand);
 
 /*
  * Common IRQ numbers for level 1 interrupt handler
@@ -788,6 +789,7 @@ i2c_bus *omap_i2c_bus(struct omap_i2c_s *s);
 # define cpu_is_omap2420(cpu)		(cpu->mpu_model == omap2420)
 # define cpu_is_omap2430(cpu)		(cpu->mpu_model == omap2430)
 # define cpu_is_omap3430(cpu)		(cpu->mpu_model == omap3430)
+# define cpu_is_omap3630(cpu)           (cpu->mpu_model == omap3630)
 
 # define cpu_is_omap15xx(cpu)		\
         (cpu_is_omap310(cpu) || cpu_is_omap1510(cpu))
@@ -799,7 +801,8 @@ i2c_bus *omap_i2c_bus(struct omap_i2c_s *s);
 # define cpu_class_omap1(cpu)		\
         (cpu_is_omap15xx(cpu) || cpu_is_omap16xx(cpu))
 # define cpu_class_omap2(cpu)		cpu_is_omap24xx(cpu)
-# define cpu_class_omap3(cpu)		cpu_is_omap3430(cpu)
+# define cpu_class_omap3(cpu) \
+        (cpu_is_omap3430(cpu) || cpu_is_omap3630(cpu))
 
 struct omap_mpu_state_s {
     enum omap_mpu_model {
@@ -813,6 +816,7 @@ struct omap_mpu_state_s {
         omap2423,
         omap2430,
         omap3430,
+        omap3630,
     } mpu_model;
 
     CPUState *env;
diff --git a/hw/omap2.c b/hw/omap2.c
index 7e5820a97b..ca088d9f53 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -2402,7 +2402,8 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
     sysbus_mmio_map(busdev, 4, omap_l4_region_base(ta, 5));
 
     s->sdrc = omap_sdrc_init(0x68009000);
-    s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);
+    s->gpmc = omap_gpmc_init(s, 0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ],
+                             s->drq[OMAP24XX_DMA_GPMC]);
 
     dinfo = drive_get(IF_SD, 0, 0);
     if (!dinfo) {
diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index 673dddd237..02f0c52107 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -27,82 +27,410 @@
 /* General-Purpose Memory Controller */
 struct omap_gpmc_s {
     qemu_irq irq;
+    qemu_irq drq;
     MemoryRegion iomem;
+    int accept_256;
 
+    uint8_t revision;
     uint8_t sysconfig;
     uint16_t irqst;
     uint16_t irqen;
+    uint16_t lastirq;
     uint16_t timeout;
     uint16_t config;
-    uint32_t prefconfig[2];
-    int prefcontrol;
-    int preffifo;
-    int prefcount;
     struct omap_gpmc_cs_file_s {
         uint32_t config[7];
-        target_phys_addr_t base;
-        size_t size;
         MemoryRegion *iomem;
         MemoryRegion container;
-        void (*base_update)(void *opaque, target_phys_addr_t new);
-        void (*unmap)(void *opaque);
-        void *opaque;
+        MemoryRegion nandiomem;
+        DeviceState *dev;
     } cs_file[8];
     int ecc_cs;
     int ecc_ptr;
     uint32_t ecc_cfg;
     ECCState ecc[9];
+    struct prefetch {
+        uint32_t config1; /* GPMC_PREFETCH_CONFIG1 */
+        uint32_t transfercount; /* GPMC_PREFETCH_CONFIG2:TRANSFERCOUNT */
+        int startengine; /* GPMC_PREFETCH_CONTROL:STARTENGINE */
+        int fifopointer; /* GPMC_PREFETCH_STATUS:FIFOPOINTER */
+        int count; /* GPMC_PREFETCH_STATUS:COUNTVALUE */
+        MemoryRegion iomem;
+        uint8_t fifo[64];
+    } prefetch;
 };
 
+#define OMAP_GPMC_8BIT 0
+#define OMAP_GPMC_16BIT 1
+#define OMAP_GPMC_NOR 0
+#define OMAP_GPMC_NAND 2
+
+static int omap_gpmc_devtype(struct omap_gpmc_cs_file_s *f)
+{
+    return (f->config[0] >> 10) & 3;
+}
+
+static int omap_gpmc_devsize(struct omap_gpmc_cs_file_s *f)
+{
+    /* devsize field is really 2 bits but we ignore the high
+     * bit to ensure consistent behaviour if the guest sets
+     * it (values 2 and 3 are reserved in the TRM)
+     */
+    return (f->config[0] >> 12) & 1;
+}
+
+/* Extract the chip-select value from the prefetch config1 register */
+static int prefetch_cs(uint32_t config1)
+{
+    return (config1 >> 24) & 7;
+}
+
+static int prefetch_threshold(uint32_t config1)
+{
+    return (config1 >> 8) & 0x7f;
+}
+
 static void omap_gpmc_int_update(struct omap_gpmc_s *s)
 {
-    qemu_set_irq(s->irq, s->irqen & s->irqst);
+    /* The TRM is a bit unclear, but it seems to say that
+     * the TERMINALCOUNTSTATUS bit is set only on the
+     * transition when the prefetch engine goes from
+     * active to inactive, whereas the FIFOEVENTSTATUS
+     * bit is held high as long as the fifo has at
+     * least THRESHOLD bytes available.
+     * So we do the latter here, but TERMINALCOUNTSTATUS
+     * is set elsewhere.
+     */
+    if (s->prefetch.fifopointer >= prefetch_threshold(s->prefetch.config1)) {
+        s->irqst |= 1;
+    }
+    if ((s->irqen & s->irqst) != s->lastirq) {
+        s->lastirq = s->irqen & s->irqst;
+        qemu_set_irq(s->irq, s->lastirq);
+    }
 }
 
-static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask)
+static void omap_gpmc_dma_update(struct omap_gpmc_s *s, int value)
 {
-    /* TODO: check for overlapping regions and report access errors */
-    if ((mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf) ||
-                    (base < 0 || base >= 0x40) ||
-                    (base & 0x0f & ~mask)) {
-        fprintf(stderr, "%s: wrong cs address mapping/decoding!\n",
-                        __FUNCTION__);
+    if (s->prefetch.config1 & 4) {
+        qemu_set_irq(s->drq, value);
+    }
+}
+
+/* Access functions for when a NAND-like device is mapped into memory:
+ * all addresses in the region behave like accesses to the relevant
+ * GPMC_NAND_DATA_i register (which is actually implemented to call these)
+ */
+static uint64_t omap_nand_read(void *opaque, target_phys_addr_t addr,
+                               unsigned size)
+{
+    struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
+    uint64_t v;
+    nand_setpins(f->dev, 0, 0, 0, 1, 0);
+    switch (omap_gpmc_devsize(f)) {
+    case OMAP_GPMC_8BIT:
+        v = nand_getio(f->dev);
+        if (size == 1) {
+            return v;
+        }
+        v |= (nand_getio(f->dev) << 8);
+        if (size == 2) {
+            return v;
+        }
+        v |= (nand_getio(f->dev) << 16);
+        v |= (nand_getio(f->dev) << 24);
+        return v;
+    case OMAP_GPMC_16BIT:
+        v = nand_getio(f->dev);
+        if (size == 1) {
+            /* 8 bit read from 16 bit device : probably a guest bug */
+            return v & 0xff;
+        }
+        if (size == 2) {
+            return v;
+        }
+        v |= (nand_getio(f->dev) << 16);
+        return v;
+    default:
+        abort();
+    }
+}
+
+static void omap_nand_setio(DeviceState *dev, uint64_t value,
+                            int nandsize, int size)
+{
+    /* Write the specified value to the NAND device, respecting
+     * both size of the NAND device and size of the write access.
+     */
+    switch (nandsize) {
+    case OMAP_GPMC_8BIT:
+        switch (size) {
+        case 1:
+            nand_setio(dev, value & 0xff);
+            break;
+        case 2:
+            nand_setio(dev, value & 0xff);
+            nand_setio(dev, (value >> 8) & 0xff);
+            break;
+        case 4:
+        default:
+            nand_setio(dev, value & 0xff);
+            nand_setio(dev, (value >> 8) & 0xff);
+            nand_setio(dev, (value >> 16) & 0xff);
+            nand_setio(dev, (value >> 24) & 0xff);
+            break;
+        }
+    case OMAP_GPMC_16BIT:
+        switch (size) {
+        case 1:
+            /* writing to a 16bit device with 8bit access is probably a guest
+             * bug; pass the value through anyway.
+             */
+        case 2:
+            nand_setio(dev, value & 0xffff);
+            break;
+        case 4:
+        default:
+            nand_setio(dev, value & 0xffff);
+            nand_setio(dev, (value >> 16) & 0xffff);
+            break;
+        }
+    }
+}
+
+static void omap_nand_write(void *opaque, target_phys_addr_t addr,
+                            uint64_t value, unsigned size)
+{
+    struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
+    nand_setpins(f->dev, 0, 0, 0, 1, 0);
+    omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
+}
+
+static const MemoryRegionOps omap_nand_ops = {
+    .read = omap_nand_read,
+    .write = omap_nand_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void fill_prefetch_fifo(struct omap_gpmc_s *s)
+{
+    /* Fill the prefetch FIFO by reading data from NAND.
+     * We do this synchronously, unlike the hardware which
+     * will do this asynchronously. We refill when the
+     * FIFO has THRESHOLD bytes free, and we always refill
+     * as much data as possible starting at the top end
+     * of the FIFO.
+     * (We have to refill at THRESHOLD rather than waiting
+     * for the FIFO to empty to allow for the case where
+     * the FIFO size isn't an exact multiple of THRESHOLD
+     * and we're doing DMA transfers.)
+     * This means we never need to handle wrap-around in
+     * the fifo-reading code, and the next byte of data
+     * to read is always fifo[63 - fifopointer].
+     */
+    int fptr;
+    int cs = prefetch_cs(s->prefetch.config1);
+    int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0);
+    int bytes;
+    /* Don't believe the bit of the OMAP TRM that says that COUNTVALUE
+     * and TRANSFERCOUNT are in units of 16 bit words for 16 bit NAND.
+     * Instead believe the bit that says it is always a byte count.
+     */
+    bytes = 64 - s->prefetch.fifopointer;
+    if (bytes > s->prefetch.count) {
+        bytes = s->prefetch.count;
+    }
+    s->prefetch.count -= bytes;
+    s->prefetch.fifopointer += bytes;
+    fptr = 64 - s->prefetch.fifopointer;
+    /* Move the existing data in the FIFO so it sits just
+     * before what we're about to read in
+     */
+    while (fptr < (64 - bytes)) {
+        s->prefetch.fifo[fptr] = s->prefetch.fifo[fptr + bytes];
+        fptr++;
+    }
+    while (fptr < 64) {
+        if (is16bit) {
+            uint32_t v = omap_nand_read(&s->cs_file[cs], 0, 2);
+            s->prefetch.fifo[fptr++] = v & 0xff;
+            s->prefetch.fifo[fptr++] = (v >> 8) & 0xff;
+        } else {
+            s->prefetch.fifo[fptr++] = omap_nand_read(&s->cs_file[cs], 0, 1);
+        }
+    }
+    if (s->prefetch.startengine && (s->prefetch.count == 0)) {
+        /* This was the final transfer: raise TERMINALCOUNTSTATUS */
+        s->irqst |= 2;
+        s->prefetch.startengine = 0;
+    }
+    /* If there are any bytes in the FIFO at this point then
+     * we must raise a DMA request (either this is a final part
+     * transfer, or we filled the FIFO in which case we certainly
+     * have THRESHOLD bytes available)
+     */
+    if (s->prefetch.fifopointer != 0) {
+        omap_gpmc_dma_update(s, 1);
+    }
+    omap_gpmc_int_update(s);
+}
+
+/* Access functions for a NAND-like device when the prefetch/postwrite
+ * engine is enabled -- all addresses in the region behave alike:
+ * data is read or written to the FIFO.
+ */
+static uint64_t omap_gpmc_prefetch_read(void *opaque, target_phys_addr_t addr,
+                                        unsigned size)
+{
+    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
+    uint32_t data;
+    if (s->prefetch.config1 & 1) {
+        /* The TRM doesn't define the behaviour if you read from the
+         * FIFO when the prefetch engine is in write mode. We choose
+         * to always return zero.
+         */
+        return 0;
+    }
+    /* Note that trying to read an empty fifo repeats the last byte */
+    if (s->prefetch.fifopointer) {
+        s->prefetch.fifopointer--;
+    }
+    data = s->prefetch.fifo[63 - s->prefetch.fifopointer];
+    if (s->prefetch.fifopointer ==
+        (64 - prefetch_threshold(s->prefetch.config1))) {
+        /* We've drained THRESHOLD bytes now. So deassert the
+         * DMA request, then refill the FIFO (which will probably
+         * assert it again.)
+         */
+        omap_gpmc_dma_update(s, 0);
+        fill_prefetch_fifo(s);
+    }
+    omap_gpmc_int_update(s);
+    return data;
+}
+
+static void omap_gpmc_prefetch_write(void *opaque, target_phys_addr_t addr,
+                                     uint64_t value, unsigned size)
+{
+    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
+    int cs = prefetch_cs(s->prefetch.config1);
+    if ((s->prefetch.config1 & 1) == 0) {
+        /* The TRM doesn't define the behaviour of writing to the
+         * FIFO when the prefetch engine is in read mode. We
+         * choose to ignore the write.
+         */
+        return;
+    }
+    if (s->prefetch.count == 0) {
+        /* The TRM doesn't define the behaviour of writing to the
+         * FIFO if the transfer is complete. We choose to ignore.
+         */
         return;
     }
+    /* The only reason we do any data buffering in postwrite
+     * mode is if we are talking to a 16 bit NAND device, in
+     * which case we need to buffer the first byte of the
+     * 16 bit word until the other byte arrives.
+     */
+    int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0);
+    if (is16bit) {
+        /* fifopointer alternates between 64 (waiting for first
+         * byte of word) and 63 (waiting for second byte)
+         */
+        if (s->prefetch.fifopointer == 64) {
+            s->prefetch.fifo[0] = value;
+            s->prefetch.fifopointer--;
+        } else {
+            value = (value << 8) | s->prefetch.fifo[0];
+            omap_nand_write(&s->cs_file[cs], 0, value, 2);
+            s->prefetch.count--;
+            s->prefetch.fifopointer = 64;
+        }
+    } else {
+        /* Just write the byte : fifopointer remains 64 at all times */
+        omap_nand_write(&s->cs_file[cs], 0, value, 1);
+        s->prefetch.count--;
+    }
+    if (s->prefetch.count == 0) {
+        /* Final transfer: raise TERMINALCOUNTSTATUS */
+        s->irqst |= 2;
+        s->prefetch.startengine = 0;
+    }
+    omap_gpmc_int_update(s);
+}
+
+static const MemoryRegionOps omap_prefetch_ops = {
+    .read = omap_gpmc_prefetch_read,
+    .write = omap_gpmc_prefetch_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl.min_access_size = 1,
+    .impl.max_access_size = 1,
+};
 
-    if (!f->opaque)
+static MemoryRegion *omap_gpmc_cs_memregion(struct omap_gpmc_s *s, int cs)
+{
+    /* Return the MemoryRegion* to map/unmap for this chipselect */
+    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
+    if (omap_gpmc_devtype(f) == OMAP_GPMC_NOR) {
+        return f->iomem;
+    }
+    if ((s->prefetch.config1 & 0x80) &&
+        (prefetch_cs(s->prefetch.config1) == cs)) {
+        /* The prefetch engine is enabled for this CS: map the FIFO */
+        return &s->prefetch.iomem;
+    }
+    return &f->nandiomem;
+}
+
+static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs)
+{
+    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
+    uint32_t mask = (f->config[6] >> 8) & 0xf;
+    uint32_t base = f->config[6] & 0x3f;
+    uint32_t size;
+
+    if (!f->iomem && !f->dev) {
+        return;
+    }
+
+    if (!(f->config[6] & (1 << 6))) {
+        /* Do nothing unless CSVALID */
         return;
+    }
 
-    f->base = base << 24;
-    f->size = (0x0fffffff & ~(mask << 24)) + 1;
+    /* TODO: check for overlapping regions and report access errors */
+    if (mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf
+         && !(s->accept_256 && !mask)) {
+        fprintf(stderr, "%s: invalid chip-select mask address (0x%x)\n",
+                 __func__, mask);
+    }
+
+    base <<= 24;
+    size = (0x0fffffff & ~(mask << 24)) + 1;
     /* TODO: rather than setting the size of the mapping (which should be
      * constant), the mask should cause wrapping of the address space, so
      * that the same memory becomes accessible at every <i>size</i> bytes
      * starting from <i>base</i>.  */
-    if (f->iomem) {
-        memory_region_init(&f->container, "omap-gpmc-file", f->size);
-        memory_region_add_subregion(&f->container, 0, f->iomem);
-        memory_region_add_subregion(get_system_memory(), f->base,
-                                    &f->container);
-    }
-
-    if (f->base_update)
-        f->base_update(f->opaque, f->base);
+    memory_region_init(&f->container, "omap-gpmc-file", size);
+    memory_region_add_subregion(&f->container, 0,
+                                omap_gpmc_cs_memregion(s, cs));
+    memory_region_add_subregion(get_system_memory(), base,
+                                &f->container);
 }
 
-static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f)
+static void omap_gpmc_cs_unmap(struct omap_gpmc_s *s, int cs)
 {
-    if (f->size) {
-        if (f->unmap)
-            f->unmap(f->opaque);
-        if (f->iomem) {
-            memory_region_del_subregion(get_system_memory(), &f->container);
-            memory_region_del_subregion(&f->container, f->iomem);
-            memory_region_destroy(&f->container);
-        }
-        f->base = 0;
-        f->size = 0;
+    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
+    if (!(f->config[6] & (1 << 6))) {
+        /* Do nothing unless CSVALID */
+        return;
+    }
+    if (!f->iomem && !f->dev) {
+        return;
     }
+    memory_region_del_subregion(get_system_memory(), &f->container);
+    memory_region_del_subregion(&f->container, omap_gpmc_cs_memregion(s, cs));
+    memory_region_destroy(&f->container);
 }
 
 void omap_gpmc_reset(struct omap_gpmc_s *s)
@@ -115,25 +443,32 @@ void omap_gpmc_reset(struct omap_gpmc_s *s)
     omap_gpmc_int_update(s);
     s->timeout = 0;
     s->config = 0xa00;
-    s->prefconfig[0] = 0x00004000;
-    s->prefconfig[1] = 0x00000000;
-    s->prefcontrol = 0;
-    s->preffifo = 0;
-    s->prefcount = 0;
+    s->prefetch.config1 = 0x00004000;
+    s->prefetch.transfercount = 0x00000000;
+    s->prefetch.startengine = 0;
+    s->prefetch.fifopointer = 0;
+    s->prefetch.count = 0;
     for (i = 0; i < 8; i ++) {
-        if (s->cs_file[i].config[6] & (1 << 6))			/* CSVALID */
-            omap_gpmc_cs_unmap(s->cs_file + i);
-        s->cs_file[i].config[0] = i ? 1 << 12 : 0;
+        omap_gpmc_cs_unmap(s, i);
         s->cs_file[i].config[1] = 0x101001;
         s->cs_file[i].config[2] = 0x020201;
         s->cs_file[i].config[3] = 0x10031003;
         s->cs_file[i].config[4] = 0x10f1111;
         s->cs_file[i].config[5] = 0;
         s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6);
-        if (s->cs_file[i].config[6] & (1 << 6))			/* CSVALID */
-            omap_gpmc_cs_map(&s->cs_file[i],
-                            s->cs_file[i].config[6] & 0x1f,	/* MASKADDR */
-                        (s->cs_file[i].config[6] >> 8 & 0xf));	/* BASEADDR */
+
+        s->cs_file[i].config[6] = 0xf00;
+        /* In theory we could probe attached devices for some CFG1
+         * bits here, but we just retain them across resets as they
+         * were set initially by omap_gpmc_attach().
+         */
+        if (i == 0) {
+            s->cs_file[i].config[0] &= 0x00433e00;
+            s->cs_file[i].config[6] |= 1 << 6; /* CSVALID */
+            omap_gpmc_cs_map(s, i);
+        } else {
+            s->cs_file[i].config[0] &= 0x00403c00;
+        }
     }
     s->ecc_cs = 0;
     s->ecc_ptr = 0;
@@ -142,6 +477,24 @@ void omap_gpmc_reset(struct omap_gpmc_s *s)
         ecc_reset(&s->ecc[i]);
 }
 
+static int gpmc_wordaccess_only(target_phys_addr_t addr)
+{
+    /* Return true if the register offset is to a register that
+     * only permits word width accesses.
+     * Non-word accesses are only OK for GPMC_NAND_DATA/ADDRESS/COMMAND
+     * for any chipselect.
+     */
+    if (addr >= 0x60 && addr <= 0x1d4) {
+        int cs = (addr - 0x60) / 0x30;
+        addr -= cs * 0x30;
+        if (addr >= 0x7c && addr < 0x88) {
+            /* GPMC_NAND_COMMAND, GPMC_NAND_ADDRESS, GPMC_NAND_DATA */
+            return 0;
+        }
+    }
+    return 1;
+}
+
 static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
                                unsigned size)
 {
@@ -149,13 +502,13 @@ static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
     int cs;
     struct omap_gpmc_cs_file_s *f;
 
-    if (size != 4) {
+    if (size != 4 && gpmc_wordaccess_only(addr)) {
         return omap_badwidth_read32(opaque, addr);
     }
 
     switch (addr) {
     case 0x000:	/* GPMC_REVISION */
-        return 0x20;
+        return s->revision;
 
     case 0x010:	/* GPMC_SYSCONFIG */
         return s->sysconfig;
@@ -187,36 +540,39 @@ static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
         addr -= cs * 0x30;
         f = s->cs_file + cs;
         switch (addr) {
-            case 0x60:	/* GPMC_CONFIG1 */
-                return f->config[0];
-            case 0x64:	/* GPMC_CONFIG2 */
-                return f->config[1];
-            case 0x68:	/* GPMC_CONFIG3 */
-                return f->config[2];
-            case 0x6c:	/* GPMC_CONFIG4 */
-                return f->config[3];
-            case 0x70:	/* GPMC_CONFIG5 */
-                return f->config[4];
-            case 0x74:	/* GPMC_CONFIG6 */
-                return f->config[5];
-            case 0x78:	/* GPMC_CONFIG7 */
-                return f->config[6];
-            case 0x84:	/* GPMC_NAND_DATA */
-                return 0;
+        case 0x60:      /* GPMC_CONFIG1 */
+            return f->config[0];
+        case 0x64:      /* GPMC_CONFIG2 */
+            return f->config[1];
+        case 0x68:      /* GPMC_CONFIG3 */
+            return f->config[2];
+        case 0x6c:      /* GPMC_CONFIG4 */
+            return f->config[3];
+        case 0x70:      /* GPMC_CONFIG5 */
+            return f->config[4];
+        case 0x74:      /* GPMC_CONFIG6 */
+            return f->config[5];
+        case 0x78:      /* GPMC_CONFIG7 */
+            return f->config[6];
+        case 0x84 ... 0x87: /* GPMC_NAND_DATA */
+            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
+                return omap_nand_read(f, 0, size);
+            }
+            return 0;
         }
         break;
 
     case 0x1e0:	/* GPMC_PREFETCH_CONFIG1 */
-        return s->prefconfig[0];
+        return s->prefetch.config1;
     case 0x1e4:	/* GPMC_PREFETCH_CONFIG2 */
-        return s->prefconfig[1];
+        return s->prefetch.transfercount;
     case 0x1ec:	/* GPMC_PREFETCH_CONTROL */
-        return s->prefcontrol;
+        return s->prefetch.startengine;
     case 0x1f0:	/* GPMC_PREFETCH_STATUS */
-        return (s->preffifo << 24) |
-                ((s->preffifo >
-                  ((s->prefconfig[0] >> 8) & 0x7f) ? 1 : 0) << 16) |
-                s->prefcount;
+        return (s->prefetch.fifopointer << 24) |
+                ((s->prefetch.fifopointer >=
+                  ((s->prefetch.config1 >> 8) & 0x7f) ? 1 : 0) << 16) |
+                s->prefetch.count;
 
     case 0x1f4:	/* GPMC_ECC_CONFIG */
         return s->ecc_cs;
@@ -251,7 +607,7 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
     int cs;
     struct omap_gpmc_cs_file_s *f;
 
-    if (size != 4) {
+    if (size != 4 && gpmc_wordaccess_only(addr)) {
         return omap_badwidth_write32(opaque, addr, value);
     }
 
@@ -276,7 +632,7 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
         break;
 
     case 0x018:	/* GPMC_IRQSTATUS */
-        s->irqen = ~value;
+        s->irqen &= ~value;
         omap_gpmc_int_update(s);
         break;
 
@@ -302,62 +658,109 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
         addr -= cs * 0x30;
         f = s->cs_file + cs;
         switch (addr) {
-            case 0x60:	/* GPMC_CONFIG1 */
-                f->config[0] = value & 0xffef3e13;
-                break;
-            case 0x64:	/* GPMC_CONFIG2 */
-                f->config[1] = value & 0x001f1f8f;
-                break;
-            case 0x68:	/* GPMC_CONFIG3 */
-                f->config[2] = value & 0x001f1f8f;
-                break;
-            case 0x6c:	/* GPMC_CONFIG4 */
-                f->config[3] = value & 0x1f8f1f8f;
-                break;
-            case 0x70:	/* GPMC_CONFIG5 */
-                f->config[4] = value & 0x0f1f1f1f;
-                break;
-            case 0x74:	/* GPMC_CONFIG6 */
-                f->config[5] = value & 0x00000fcf;
-                break;
-            case 0x78:	/* GPMC_CONFIG7 */
-                if ((f->config[6] ^ value) & 0xf7f) {
-                    if (f->config[6] & (1 << 6))		/* CSVALID */
-                        omap_gpmc_cs_unmap(f);
-                    if (value & (1 << 6))			/* CSVALID */
-                        omap_gpmc_cs_map(f, value & 0x1f,	/* MASKADDR */
-                                        (value >> 8 & 0xf));	/* BASEADDR */
-                }
+        case 0x60:      /* GPMC_CONFIG1 */
+            f->config[0] = value & 0xffef3e13;
+            break;
+        case 0x64:      /* GPMC_CONFIG2 */
+            f->config[1] = value & 0x001f1f8f;
+            break;
+        case 0x68:      /* GPMC_CONFIG3 */
+            f->config[2] = value & 0x001f1f8f;
+            break;
+        case 0x6c:      /* GPMC_CONFIG4 */
+            f->config[3] = value & 0x1f8f1f8f;
+            break;
+        case 0x70:      /* GPMC_CONFIG5 */
+            f->config[4] = value & 0x0f1f1f1f;
+            break;
+        case 0x74:      /* GPMC_CONFIG6 */
+            f->config[5] = value & 0x00000fcf;
+            break;
+        case 0x78:      /* GPMC_CONFIG7 */
+            if ((f->config[6] ^ value) & 0xf7f) {
+                omap_gpmc_cs_unmap(s, cs);
                 f->config[6] = value & 0x00000f7f;
-                break;
-            case 0x7c:	/* GPMC_NAND_COMMAND */
-            case 0x80:	/* GPMC_NAND_ADDRESS */
-            case 0x84:	/* GPMC_NAND_DATA */
-                break;
-
-            default:
-                goto bad_reg;
+                omap_gpmc_cs_map(s, cs);
+            }
+            break;
+        case 0x7c ... 0x7f: /* GPMC_NAND_COMMAND */
+            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
+                nand_setpins(f->dev, 1, 0, 0, 1, 0); /* CLE */
+                omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
+            }
+            break;
+        case 0x80 ... 0x83: /* GPMC_NAND_ADDRESS */
+            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
+                nand_setpins(f->dev, 0, 1, 0, 1, 0); /* ALE */
+                omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
+            }
+            break;
+        case 0x84 ... 0x87: /* GPMC_NAND_DATA */
+            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
+                omap_nand_write(f, 0, value, size);
+            }
+            break;
+        default:
+            goto bad_reg;
         }
         break;
 
     case 0x1e0:	/* GPMC_PREFETCH_CONFIG1 */
-        s->prefconfig[0] = value & 0x7f8f7fbf;
-        /* TODO: update interrupts, fifos, dmas */
+        if (!s->prefetch.startengine) {
+            uint32_t oldconfig1 = s->prefetch.config1;
+            uint32_t changed;
+            s->prefetch.config1 = value & 0x7f8f7fbf;
+            changed = oldconfig1 ^ s->prefetch.config1;
+            if (changed & (0x80 | 0x7000000)) {
+                /* Turning the engine on or off, or mapping it somewhere else.
+                 * cs_map() and cs_unmap() check the prefetch config and
+                 * overall CSVALID bits, so it is sufficient to unmap-and-map
+                 * both the old cs and the new one.
+                 */
+                int oldcs = prefetch_cs(oldconfig1);
+                int newcs = prefetch_cs(s->prefetch.config1);
+                omap_gpmc_cs_unmap(s, oldcs);
+                omap_gpmc_cs_map(s, oldcs);
+                if (newcs != oldcs) {
+                    omap_gpmc_cs_unmap(s, newcs);
+                    omap_gpmc_cs_map(s, newcs);
+                }
+            }
+        }
         break;
 
     case 0x1e4:	/* GPMC_PREFETCH_CONFIG2 */
-        s->prefconfig[1] = value & 0x3fff;
+        if (!s->prefetch.startengine) {
+            s->prefetch.transfercount = value & 0x3fff;
+        }
         break;
 
     case 0x1ec:	/* GPMC_PREFETCH_CONTROL */
-        s->prefcontrol = value & 1;
-        if (s->prefcontrol) {
-            if (s->prefconfig[0] & 1)
-                s->preffifo = 0x40;
-            else
-                s->preffifo = 0x00;
+        if (s->prefetch.startengine != (value & 1)) {
+            s->prefetch.startengine = value & 1;
+            if (s->prefetch.startengine) {
+                /* Prefetch engine start */
+                s->prefetch.count = s->prefetch.transfercount;
+                if (s->prefetch.config1 & 1) {
+                    /* Write */
+                    s->prefetch.fifopointer = 64;
+                } else {
+                    /* Read */
+                    s->prefetch.fifopointer = 0;
+                    fill_prefetch_fifo(s);
+                }
+            } else {
+                /* Prefetch engine forcibly stopped. The TRM
+                 * doesn't define the behaviour if you do this.
+                 * We clear the prefetch count, which means that
+                 * we permit no more writes, and don't read any
+                 * more data from NAND. The CPU can still drain
+                 * the FIFO of unread data.
+                 */
+                s->prefetch.count = 0;
+            }
+            omap_gpmc_int_update(s);
         }
-        /* TODO: start */
         break;
 
     case 0x1f4:	/* GPMC_ECC_CONFIG */
@@ -394,24 +797,47 @@ static const MemoryRegionOps omap_gpmc_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq)
+struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
+                                   target_phys_addr_t base,
+                                   qemu_irq irq, qemu_irq drq)
 {
+    int cs;
     struct omap_gpmc_s *s = (struct omap_gpmc_s *)
             g_malloc0(sizeof(struct omap_gpmc_s));
 
-    omap_gpmc_reset(s);
-
     memory_region_init_io(&s->iomem, &omap_gpmc_ops, s, "omap-gpmc", 0x1000);
     memory_region_add_subregion(get_system_memory(), base, &s->iomem);
 
+    s->irq = irq;
+    s->drq = drq;
+    s->accept_256 = cpu_is_omap3630(mpu);
+    s->revision = cpu_class_omap3(mpu) ? 0x50 : 0x20;
+    s->lastirq = 0;
+    omap_gpmc_reset(s);
+
+    /* We have to register a different IO memory handler for each
+     * chip select region in case a NAND device is mapped there. We
+     * make the region the worst-case size of 256MB and rely on the
+     * container memory region in cs_map to chop it down to the actual
+     * guest-requested size.
+     */
+    for (cs = 0; cs < 8; cs++) {
+        memory_region_init_io(&s->cs_file[cs].nandiomem,
+                              &omap_nand_ops,
+                              &s->cs_file[cs],
+                              "omap-nand",
+                              256 * 1024 * 1024);
+    }
+
+    memory_region_init_io(&s->prefetch.iomem, &omap_prefetch_ops, s,
+                          "omap-gpmc-prefetch", 256 * 1024 * 1024);
     return s;
 }
 
-void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem,
-                void (*base_upd)(void *opaque, target_phys_addr_t new),
-                void (*unmap)(void *opaque), void *opaque)
+void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem)
 {
     struct omap_gpmc_cs_file_s *f;
+    assert(iomem);
 
     if (cs < 0 || cs >= 8) {
         fprintf(stderr, "%s: bad chip-select %i\n", __FUNCTION__, cs);
@@ -419,12 +845,29 @@ void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem,
     }
     f = &s->cs_file[cs];
 
+    omap_gpmc_cs_unmap(s, cs);
+    f->config[0] &= ~(0xf << 10);
     f->iomem = iomem;
-    f->base_update = base_upd;
-    f->unmap = unmap;
-    f->opaque = opaque;
+    omap_gpmc_cs_map(s, cs);
+}
 
-    if (f->config[6] & (1 << 6))				/* CSVALID */
-        omap_gpmc_cs_map(f, f->config[6] & 0x1f,		/* MASKADDR */
-                        (f->config[6] >> 8 & 0xf));		/* BASEADDR */
+void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand)
+{
+    struct omap_gpmc_cs_file_s *f;
+    assert(nand);
+
+    if (cs < 0 || cs >= 8) {
+        fprintf(stderr, "%s: bad chip-select %i\n", __func__, cs);
+        exit(-1);
+    }
+    f = &s->cs_file[cs];
+
+    omap_gpmc_cs_unmap(s, cs);
+    f->config[0] &= ~(0xf << 10);
+    f->config[0] |= (OMAP_GPMC_NAND << 10);
+    f->dev = nand;
+    if (nand_getbuswidth(f->dev) == 16) {
+        f->config[0] |= OMAP_GPMC_16BIT << 12;
+    }
+    omap_gpmc_cs_map(s, cs);
 }
diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c
index 70364f4c72..a7b687bc41 100644
--- a/hw/omap_sx1.c
+++ b/hw/omap_sx1.c
@@ -129,8 +129,7 @@ static void sx1_init(ram_addr_t ram_size,
     DriveInfo *dinfo;
     int fl_idx;
     uint32_t flash_size = flash0_size;
-    const MemoryRegionOps *flash_ops;
-    MemoryRegion *flash = g_new(MemoryRegion, 2);
+    int be;
 
     if (version == 2) {
         flash_size = flash2_size;
@@ -156,18 +155,17 @@ static void sx1_init(ram_addr_t ram_size,
 
     fl_idx = 0;
 #ifdef TARGET_WORDS_BIGENDIAN
-    flash_ops = &pflash_cfi01_ops_be;
+    be = 1;
 #else
-    flash_ops = &pflash_cfi01_ops_le;
+    be = 0;
 #endif
 
     if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
-        memory_region_init_rom_device(&flash[0], flash_ops,
-                                      NULL, "omap_sx1.flash0-1", flash_size);
-        if (!pflash_cfi01_register(OMAP_CS0_BASE, &flash[0],
+        if (!pflash_cfi01_register(OMAP_CS0_BASE, qemu_ram_alloc(NULL,
+                                   "omap_sx1.flash0-1", flash_size),
                                    dinfo->bdrv, sector_size,
                                    flash_size / sector_size,
-                                   4, 0, 0, 0, 0)) {
+                                   4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                            fl_idx);
         }
@@ -184,12 +182,11 @@ static void sx1_init(ram_addr_t ram_size,
         cpu_register_physical_memory(OMAP_CS1_BASE + flash1_size,
                         OMAP_CS1_SIZE - flash1_size, io);
 
-        memory_region_init_rom_device(&flash[1], flash_ops,
-                                      NULL, "omap_sx1.flash1-1", flash1_size);
-        if (!pflash_cfi01_register(OMAP_CS1_BASE, &flash[1],
+        if (!pflash_cfi01_register(OMAP_CS1_BASE, qemu_ram_alloc(NULL,
+                                   "omap_sx1.flash1-1", flash1_size),
                                    dinfo->bdrv, sector_size,
                                    flash1_size / sector_size,
-                                   4, 0, 0, 0, 0)) {
+                                   4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                            fl_idx);
         }
diff --git a/hw/onenand.c b/hw/onenand.c
index 00276a03cb..6f68f70698 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -25,6 +25,7 @@
 #include "blockdev.h"
 #include "memory.h"
 #include "exec-memory.h"
+#include "sysbus.h"
 
 /* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
 #define PAGE_SHIFT	11
@@ -33,6 +34,7 @@
 #define BLOCK_SHIFT	(PAGE_SHIFT + 6)
 
 typedef struct {
+    SysBusDevice busdev;
     struct {
         uint16_t man;
         uint16_t dev;
@@ -49,6 +51,7 @@ typedef struct {
     uint8_t *current;
     MemoryRegion ram;
     MemoryRegion mapped_ram;
+    uint8_t current_direction;
     uint8_t *boot[2];
     uint8_t *data[2][2];
     MemoryRegion iomem;
@@ -120,27 +123,72 @@ static void onenand_mem_setup(OneNANDState *s)
                                         1);
 }
 
-void onenand_base_update(void *opaque, target_phys_addr_t new)
+static void onenand_intr_update(OneNANDState *s)
 {
-    OneNANDState *s = (OneNANDState *) opaque;
-
-    s->base = new;
-
-    memory_region_add_subregion(get_system_memory(), s->base, &s->container);
+    qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1);
 }
 
-void onenand_base_unmap(void *opaque)
+static void onenand_pre_save(void *opaque)
 {
-    OneNANDState *s = (OneNANDState *) opaque;
-
-    memory_region_del_subregion(get_system_memory(), &s->container);
+    OneNANDState *s = opaque;
+    if (s->current == s->otp) {
+        s->current_direction = 1;
+    } else if (s->current == s->image) {
+        s->current_direction = 2;
+    } else {
+        s->current_direction = 0;
+    }
 }
 
-static void onenand_intr_update(OneNANDState *s)
+static int onenand_post_load(void *opaque, int version_id)
 {
-    qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1);
+    OneNANDState *s = opaque;
+    switch (s->current_direction) {
+    case 0:
+        break;
+    case 1:
+        s->current = s->otp;
+        break;
+    case 2:
+        s->current = s->image;
+        break;
+    default:
+        return -1;
+    }
+    onenand_intr_update(s);
+    return 0;
 }
 
+static const VMStateDescription vmstate_onenand = {
+    .name = "onenand",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .pre_save = onenand_pre_save,
+    .post_load = onenand_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT8(current_direction, OneNANDState),
+        VMSTATE_INT32(cycle, OneNANDState),
+        VMSTATE_INT32(otpmode, OneNANDState),
+        VMSTATE_UINT16_ARRAY(addr, OneNANDState, 8),
+        VMSTATE_UINT16_ARRAY(unladdr, OneNANDState, 8),
+        VMSTATE_INT32(bufaddr, OneNANDState),
+        VMSTATE_INT32(count, OneNANDState),
+        VMSTATE_UINT16(command, OneNANDState),
+        VMSTATE_UINT16_ARRAY(config, OneNANDState, 2),
+        VMSTATE_UINT16(status, OneNANDState),
+        VMSTATE_UINT16(intstatus, OneNANDState),
+        VMSTATE_UINT16(wpstatus, OneNANDState),
+        VMSTATE_INT32(secs_cur, OneNANDState),
+        VMSTATE_PARTIAL_VBUFFER(blockwp, OneNANDState, blocks),
+        VMSTATE_UINT8(ecc.cp, OneNANDState),
+        VMSTATE_UINT16_ARRAY(ecc.lp, OneNANDState, 2),
+        VMSTATE_UINT16(ecc.count, OneNANDState),
+        VMSTATE_BUFFER_UNSAFE(otp, OneNANDState, 0, ((64 + 2) << PAGE_SHIFT)),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 /* Hot reset (Reset OneNAND command) or warm reset (RP pin low) */
 static void onenand_reset(OneNANDState *s, int cold)
 {
@@ -167,11 +215,17 @@ static void onenand_reset(OneNANDState *s, int cold)
         /* Lock the whole flash */
         memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks);
 
-        if (s->bdrv && bdrv_read(s->bdrv, 0, s->boot[0], 8) < 0)
-            hw_error("%s: Loading the BootRAM failed.\n", __FUNCTION__);
+        if (s->bdrv_cur && bdrv_read(s->bdrv_cur, 0, s->boot[0], 8) < 0) {
+            hw_error("%s: Loading the BootRAM failed.\n", __func__);
+        }
     }
 }
 
+static void onenand_system_reset(DeviceState *dev)
+{
+    onenand_reset(FROM_SYSBUS(OneNANDState, sysbus_from_qdev(dev)), 1);
+}
+
 static inline int onenand_load_main(OneNANDState *s, int sec, int secn,
                 void *dest)
 {
@@ -191,8 +245,8 @@ static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
     int result = 0;
 
     if (secn > 0) {
-        uint32_t size = (uint32_t) secn * 512;
-        const uint8_t *sp = (const uint8_t *) src;
+        uint32_t size = (uint32_t)secn * 512;
+        const uint8_t *sp = (const uint8_t *)src;
         uint8_t *dp = 0;
         if (s->bdrv_cur) {
             dp = g_malloc(size);
@@ -203,7 +257,7 @@ static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
             if (sec + secn > s->secs_cur) {
                 result = 1;
             } else {
-                dp = (uint8_t *) s->current + (sec << 9);
+                dp = (uint8_t *)s->current + (sec << 9);
             }
         }
         if (!result) {
@@ -245,13 +299,13 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
 {
     int result = 0;
     if (secn > 0) {
-        const uint8_t *sp = (const uint8_t *) src;
+        const uint8_t *sp = (const uint8_t *)src;
         uint8_t *dp = 0, *dpp = 0;
         if (s->bdrv_cur) {
             dp = g_malloc(512);
             if (!dp || bdrv_read(s->bdrv_cur,
-                                s->secs_cur + (sec >> 5),
-                                dp, 1) < 0) {
+                                 s->secs_cur + (sec >> 5),
+                                 dp, 1) < 0) {
                 result = 1;
             } else {
                 dpp = dp + ((sec & 31) << 4);
@@ -270,7 +324,7 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
             }
             if (s->bdrv_cur) {
                 result = bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5),
-                                dp, 1) < 0;
+                                    dp, 1) < 0;
             }
         }
         if (dp) {
@@ -326,7 +380,7 @@ fail:
     return 1;
 }
 
-static void onenand_command(OneNANDState *s, int cmd)
+static void onenand_command(OneNANDState *s)
 {
     int b;
     int sec;
@@ -346,7 +400,7 @@ static void onenand_command(OneNANDState *s, int cmd)
             s->data[(s->bufaddr >> 2) & 1][1] : s->boot[1];	\
     buf += (s->bufaddr & 3) << 4;
 
-    switch (cmd) {
+    switch (s->command) {
     case 0x00:	/* Load single/multiple sector data unit into buffer */
         SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
 
@@ -527,7 +581,7 @@ static void onenand_command(OneNANDState *s, int cmd)
         s->status |= ONEN_ERR_CMD;
         s->intstatus |= ONEN_INT;
         fprintf(stderr, "%s: unknown OneNAND command %x\n",
-                        __FUNCTION__, cmd);
+                        __func__, s->command);
     }
 
     onenand_intr_update(s);
@@ -659,7 +713,7 @@ static void onenand_write(void *opaque, target_phys_addr_t addr,
         if (s->intstatus & (1 << 15))
             break;
         s->command = value;
-        onenand_command(s, s->command);
+        onenand_command(s);
         break;
     case 0xf221:	/* System Configuration 1 */
         s->config[0] = value;
@@ -700,30 +754,25 @@ static const MemoryRegionOps onenand_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-void *onenand_init(BlockDriverState *bdrv,
-                uint16_t man_id, uint16_t dev_id, uint16_t ver_id,
-                int regshift, qemu_irq irq)
+static int onenand_initfn(SysBusDevice *dev)
 {
-    OneNANDState *s = (OneNANDState *) g_malloc0(sizeof(*s));
-    uint32_t size = 1 << (24 + ((dev_id >> 4) & 7));
+    OneNANDState *s = (OneNANDState *)dev;
+    uint32_t size = 1 << (24 + ((s->id.dev >> 4) & 7));
     void *ram;
-
-    s->shift = regshift;
-    s->intr = irq;
+    s->base = (target_phys_addr_t)-1;
     s->rdy = NULL;
-    s->id.man = man_id;
-    s->id.dev = dev_id;
-    s->id.ver = ver_id;
     s->blocks = size >> BLOCK_SHIFT;
     s->secs = size >> 9;
     s->blockwp = g_malloc(s->blocks);
-    s->density_mask = (dev_id & 0x08) ? (1 << (6 + ((dev_id >> 4) & 7))) : 0;
+    s->density_mask = (s->id.dev & 0x08)
+        ? (1 << (6 + ((s->id.dev >> 4) & 7))) : 0;
     memory_region_init_io(&s->iomem, &onenand_ops, s, "onenand",
                           0x10000 << s->shift);
-    s->bdrv = bdrv;
     if (!s->bdrv) {
         s->image = memset(g_malloc(size + (size >> 5)),
-                        0xff, size + (size >> 5));
+                          0xff, size + (size >> 5));
+    } else {
+        s->bdrv_cur = s->bdrv;
     }
     s->otp = memset(g_malloc((64 + 2) << PAGE_SHIFT),
                     0xff, (64 + 2) << PAGE_SHIFT);
@@ -736,15 +785,40 @@ void *onenand_init(BlockDriverState *bdrv,
     s->data[1][0] = ram + ((0x0200 + (1 << (PAGE_SHIFT - 1))) << s->shift);
     s->data[1][1] = ram + ((0x8010 + (1 << (PAGE_SHIFT - 6))) << s->shift);
     onenand_mem_setup(s);
+    sysbus_init_irq(dev, &s->intr);
+    sysbus_init_mmio_region(dev, &s->container);
+    vmstate_register(&dev->qdev,
+                     ((s->shift & 0x7f) << 24)
+                     | ((s->id.man & 0xff) << 16)
+                     | ((s->id.dev & 0xff) << 8)
+                     | (s->id.ver & 0xff),
+                     &vmstate_onenand, s);
+    return 0;
+}
 
-    onenand_reset(s, 1);
+static SysBusDeviceInfo onenand_info = {
+    .init = onenand_initfn,
+    .qdev.name = "onenand",
+    .qdev.size = sizeof(OneNANDState),
+    .qdev.reset = onenand_system_reset,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT16("manufacturer_id", OneNANDState, id.man, 0),
+        DEFINE_PROP_UINT16("device_id", OneNANDState, id.dev, 0),
+        DEFINE_PROP_UINT16("version_id", OneNANDState, id.ver, 0),
+        DEFINE_PROP_INT32("shift", OneNANDState, shift, 0),
+        DEFINE_PROP_DRIVE("drive", OneNANDState, bdrv),
+        DEFINE_PROP_END_OF_LIST()
+    }
+};
 
-    return s;
+static void onenand_register_device(void)
+{
+    sysbus_register_withprop(&onenand_info);
 }
 
-void *onenand_raw_otp(void *opaque)
+void *onenand_raw_otp(DeviceState *onenand_device)
 {
-    OneNANDState *s = (OneNANDState *) opaque;
-
-    return s->otp;
+    return FROM_SYSBUS(OneNANDState, sysbus_from_qdev(onenand_device))->otp;
 }
+
+device_init(onenand_register_device)
diff --git a/hw/pc.c b/hw/pc.c
index 263fb1a773..5bc845aaea 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -78,12 +78,12 @@ struct e820_entry {
     uint64_t address;
     uint64_t length;
     uint32_t type;
-} __attribute((__packed__, __aligned__(4)));
+} QEMU_PACKED __attribute((__aligned__(4)));
 
 struct e820_table {
     uint32_t count;
     struct e820_entry entry[E820_NR_ENTRIES];
-} __attribute((__packed__, __aligned__(4)));
+} QEMU_PACKED __attribute((__aligned__(4)));
 
 static struct e820_table e820_table;
 struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX};
diff --git a/hw/pci-stub.c b/hw/pci-stub.c
index c5a0aa8979..1fb105d51c 100644
--- a/hw/pci-stub.c
+++ b/hw/pci-stub.c
@@ -1,5 +1,5 @@
 /*
- * PCI stubs for plathome that doesn't support pci bus.
+ * PCI stubs for platforms that don't support pci bus.
  *
  * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
  *                    VA Linux Systems Japan K.K.
diff --git a/hw/pci.c b/hw/pci.c
index 6124790f01..57ff7b1098 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1811,6 +1811,25 @@ static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id,
     return next;
 }
 
+static uint8_t pci_find_capability_at_offset(PCIDevice *pdev, uint8_t offset)
+{
+    uint8_t next, prev, found = 0;
+
+    if (!(pdev->used[offset])) {
+        return 0;
+    }
+
+    assert(pdev->config[PCI_STATUS] & PCI_STATUS_CAP_LIST);
+
+    for (prev = PCI_CAPABILITY_LIST; (next = pdev->config[prev]);
+         prev = next + PCI_CAP_LIST_NEXT) {
+        if (next <= offset && next > found) {
+            found = next;
+        }
+    }
+    return found;
+}
+
 /* Patch the PCI vendor and device ids in a PCI rom image if necessary.
    This is needed for an option rom which is used for more than one device. */
 static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, int size)
@@ -1952,11 +1971,30 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
                        uint8_t offset, uint8_t size)
 {
     uint8_t *config;
+    int i, overlapping_cap;
+
     if (!offset) {
         offset = pci_find_space(pdev, size);
         if (!offset) {
             return -ENOSPC;
         }
+    } else {
+        /* Verify that capabilities don't overlap.  Note: device assignment
+         * depends on this check to verify that the device is not broken.
+         * Should never trigger for emulated devices, but it's helpful
+         * for debugging these. */
+        for (i = offset; i < offset + size; i++) {
+            overlapping_cap = pci_find_capability_at_offset(pdev, i);
+            if (overlapping_cap) {
+                fprintf(stderr, "ERROR: %04x:%02x:%02x.%x "
+                        "Attempt to add PCI capability %x at offset "
+                        "%x overlaps existing capability %x at offset %x\n",
+                        pci_find_domain(pdev->bus), pci_bus_num(pdev->bus),
+                        PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
+                        cap_id, offset, overlapping_cap, i);
+                return -EINVAL;
+            }
+        }
     }
 
     config = pdev->config + offset;
diff --git a/hw/pci_host.c b/hw/pci_host.c
index 44c6c207a9..2e8a29f1e3 100644
--- a/hw/pci_host.c
+++ b/hw/pci_host.c
@@ -94,72 +94,82 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
     return val;
 }
 
-static void pci_host_config_write(void *opaque, target_phys_addr_t addr,
-                                  uint64_t val, unsigned len)
+static void pci_host_config_write(ReadWriteHandler *handler,
+                                  pcibus_t addr, uint32_t val, int len)
 {
-    PCIHostState *s = opaque;
+    PCIHostState *s = container_of(handler, PCIHostState, conf_handler);
 
-    PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx64"\n",
+    PCI_DPRINTF("%s addr %" FMT_PCIBUS " %d val %"PRIx32"\n",
                 __func__, addr, len, val);
     s->config_reg = val;
 }
 
-static uint64_t pci_host_config_read(void *opaque, target_phys_addr_t addr,
-                                     unsigned len)
+static uint32_t pci_host_config_read(ReadWriteHandler *handler,
+                                     pcibus_t addr, int len)
 {
-    PCIHostState *s = opaque;
+    PCIHostState *s = container_of(handler, PCIHostState, conf_handler);
     uint32_t val = s->config_reg;
 
-    PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx32"\n",
+    PCI_DPRINTF("%s addr %" FMT_PCIBUS " len %d val %"PRIx32"\n",
                 __func__, addr, len, val);
     return val;
 }
 
-static void pci_host_data_write(void *opaque, target_phys_addr_t addr,
-                                uint64_t val, unsigned len)
+static void pci_host_data_write(ReadWriteHandler *handler,
+                                pcibus_t addr, uint32_t val, int len)
 {
-    PCIHostState *s = opaque;
-    PCI_DPRINTF("write addr " TARGET_FMT_plx " len %d val %x\n",
-                addr, len, (unsigned)val);
+    PCIHostState *s = container_of(handler, PCIHostState, data_handler);
+    PCI_DPRINTF("write addr %" FMT_PCIBUS " len %d val %x\n",
+                addr, len, val);
     if (s->config_reg & (1u << 31))
         pci_data_write(s->bus, s->config_reg | (addr & 3), val, len);
 }
 
-static uint64_t pci_host_data_read(void *opaque,
-                                   target_phys_addr_t addr, unsigned len)
+static uint32_t pci_host_data_read(ReadWriteHandler *handler,
+                                   pcibus_t addr, int len)
 {
-    PCIHostState *s = opaque;
+    PCIHostState *s = container_of(handler, PCIHostState, data_handler);
     uint32_t val;
     if (!(s->config_reg & (1 << 31)))
         return 0xffffffff;
     val = pci_data_read(s->bus, s->config_reg | (addr & 3), len);
-    PCI_DPRINTF("read addr " TARGET_FMT_plx " len %d val %x\n",
+    PCI_DPRINTF("read addr %" FMT_PCIBUS " len %d val %x\n",
                 addr, len, val);
     return val;
 }
 
-const MemoryRegionOps pci_host_conf_le_ops = {
-    .read = pci_host_config_read,
-    .write = pci_host_config_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-const MemoryRegionOps pci_host_conf_be_ops = {
-    .read = pci_host_config_read,
-    .write = pci_host_config_write,
-    .endianness = DEVICE_BIG_ENDIAN,
-};
+static void pci_host_init(PCIHostState *s)
+{
+    s->conf_handler.write = pci_host_config_write;
+    s->conf_handler.read = pci_host_config_read;
+    s->data_handler.write = pci_host_data_write;
+    s->data_handler.read = pci_host_data_read;
+}
 
-const MemoryRegionOps pci_host_data_le_ops = {
-    .read = pci_host_data_read,
-    .write = pci_host_data_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
+int pci_host_conf_register_mmio(PCIHostState *s, int endian)
+{
+    pci_host_init(s);
+    return cpu_register_io_memory_simple(&s->conf_handler, endian);
+}
 
-const MemoryRegionOps pci_host_data_be_ops = {
-    .read = pci_host_data_read,
-    .write = pci_host_data_write,
-    .endianness = DEVICE_BIG_ENDIAN,
-};
+void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s)
+{
+    pci_host_init(s);
+    register_ioport_simple(&s->conf_handler, ioport, 4, 4);
+    sysbus_init_ioports(&s->busdev, ioport, 4);
+}
 
+int pci_host_data_register_mmio(PCIHostState *s, int endian)
+{
+    pci_host_init(s);
+    return cpu_register_io_memory_simple(&s->data_handler, endian);
+}
 
+void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s)
+{
+    pci_host_init(s);
+    register_ioport_simple(&s->data_handler, ioport, 4, 1);
+    register_ioport_simple(&s->data_handler, ioport, 4, 2);
+    register_ioport_simple(&s->data_handler, ioport, 4, 4);
+    sysbus_init_ioports(&s->busdev, ioport, 4);
+}
diff --git a/hw/pci_host.h b/hw/pci_host.h
index 0211086d70..7f551143bb 100644
--- a/hw/pci_host.h
+++ b/hw/pci_host.h
@@ -29,11 +29,12 @@
 #define PCI_HOST_H
 
 #include "sysbus.h"
+#include "rwhandler.h"
 
 struct PCIHostState {
     SysBusDevice busdev;
-    MemoryRegion conf_mem;
-    MemoryRegion data_mem;
+    ReadWriteHandler conf_handler;
+    ReadWriteHandler data_handler;
     MemoryRegion *address_space;
     uint32_t config_reg;
     PCIBus *bus;
@@ -48,9 +49,12 @@ uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
 void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len);
 uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len);
 
-extern const MemoryRegionOps pci_host_conf_le_ops;
-extern const MemoryRegionOps pci_host_conf_be_ops;
-extern const MemoryRegionOps pci_host_data_le_ops;
-extern const MemoryRegionOps pci_host_data_be_ops;
+/* for mmio */
+int pci_host_conf_register_mmio(PCIHostState *s, int endian);
+int pci_host_data_register_mmio(PCIHostState *s, int endian);
+
+/* for ioio */
+void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s);
+void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s);
 
 #endif /* PCI_HOST_H */
diff --git a/hw/pcie.c b/hw/pcie.c
index 39607bf31a..5c9eb2f0ac 100644
--- a/hw/pcie.c
+++ b/hw/pcie.c
@@ -175,6 +175,14 @@ static void hotplug_event_notify(PCIDevice *dev)
     }
 }
 
+static void hotplug_event_clear(PCIDevice *dev)
+{
+    hotplug_event_update_event_status(dev);
+    if (!msix_enabled(dev) && !msi_enabled(dev) && !dev->exp.hpev_notified) {
+        qemu_set_irq(dev->irq[dev->exp.hpev_intx], 0);
+    }
+}
+
 /*
  * A PCI Express Hot-Plug Event has occurred, so update slot status register
  * and notify OS of the event if necessary.
@@ -320,6 +328,10 @@ void pcie_cap_slot_write_config(PCIDevice *dev,
     uint8_t *exp_cap = dev->config + pos;
     uint16_t sltsta = pci_get_word(exp_cap + PCI_EXP_SLTSTA);
 
+    if (ranges_overlap(addr, len, pos + PCI_EXP_SLTSTA, 2)) {
+        hotplug_event_clear(dev);
+    }
+
     if (!ranges_overlap(addr, len, pos + PCI_EXP_SLTCTL, 2)) {
         return;
     }
diff --git a/hw/pcie_aer.c b/hw/pcie_aer.c
index 2ae65ec807..62c06eafd6 100644
--- a/hw/pcie_aer.c
+++ b/hw/pcie_aer.c
@@ -415,7 +415,7 @@ static void pcie_aer_update_log(PCIDevice *dev, const PCIEAERErr *err)
     int i;
 
     assert(err->status);
-    assert(err->status & (err->status - 1));
+    assert(!(err->status & (err->status - 1)));
 
     errcap &= ~(PCI_ERR_CAP_FEP_MASK | PCI_ERR_CAP_TLP);
     errcap |= PCI_ERR_CAP_FEP(first_bit);
@@ -495,7 +495,7 @@ static int pcie_aer_record_error(PCIDevice *dev,
     int fep = PCI_ERR_CAP_FEP(errcap);
 
     assert(err->status);
-    assert(err->status & (err->status - 1));
+    assert(!(err->status & (err->status - 1)));
 
     if (errcap & PCI_ERR_CAP_MHRE &&
         (pci_get_long(aer_cap + PCI_ERR_UNCOR_STATUS) & (1U << fep))) {
@@ -979,20 +979,21 @@ int do_pcie_aer_inejct_error(Monitor *mon,
     if (pcie_aer_parse_error_string(error_name, &error_status, &correctable)) {
         char *e = NULL;
         error_status = strtoul(error_name, &e, 0);
-        correctable = !!qdict_get_int(qdict, "correctable");
+        correctable = qdict_get_try_bool(qdict, "correctable", 0);
         if (!e || *e != '\0') {
             monitor_printf(mon, "invalid error status value. \"%s\"",
                            error_name);
             return -EINVAL;
         }
     }
+    err.status = error_status;
     err.source_id = (pci_bus_num(dev->bus) << 8) | dev->devfn;
 
     err.flags = 0;
     if (correctable) {
         err.flags |= PCIE_AER_ERR_IS_CORRECTABLE;
     }
-    if (qdict_get_int(qdict, "advisory_non_fatal")) {
+    if (qdict_get_try_bool(qdict, "advisory_non_fatal", 0)) {
         err.flags |= PCIE_AER_ERR_MAYBE_ADVISORY;
     }
     if (qdict_haskey(qdict, "header0")) {
diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
index 257fccaa88..e3ca310efd 100644
--- a/hw/petalogix_ml605_mmu.c
+++ b/hw/petalogix_ml605_mmu.c
@@ -149,7 +149,7 @@ petalogix_ml605_init(ram_addr_t ram_size,
     target_phys_addr_t ddr_base = MEMORY_BASEADDR;
     ram_addr_t phys_lmb_bram;
     ram_addr_t phys_ram;
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_flash;
     qemu_irq irq[32], *cpu_irq;
 
     /* init CPUs */
@@ -169,15 +169,14 @@ petalogix_ml605_init(ram_addr_t ram_size,
     phys_ram = qemu_ram_alloc(NULL, "petalogix_ml605.ram", ram_size);
     cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_le,
-                                  NULL, "petalogix_ml605.flash", FLASH_SIZE);
+    phys_flash = qemu_ram_alloc(NULL, "petalogix_ml605.flash", FLASH_SIZE);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* 5th parameter 2 means bank-width
      * 10th paremeter 0 means little-endian */
     pflash_cfi01_register(FLASH_BASEADDR, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
-                          2, 0x89, 0x18, 0x0000, 0x0);
+                          2, 0x89, 0x18, 0x0000, 0x0, 0);
 
 
     cpu_irq = microblaze_pic_init_cpu(env);
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index 14817452c6..a43fb4c95c 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -127,7 +127,7 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
     target_phys_addr_t ddr_base = 0x90000000;
     ram_addr_t phys_lmb_bram;
     ram_addr_t phys_ram;
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_flash;
     qemu_irq irq[32], *cpu_irq;
 
     /* init CPUs */
@@ -148,14 +148,12 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
     phys_ram = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.ram", ram_size);
     cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
-                                  NULL, "petalogix_s3adsp1800.flash",
-                                  FLASH_SIZE);
+    phys_flash = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(0xa0000000, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
-                          1, 0x89, 0x18, 0x0000, 0x0);
+                          1, 0x89, 0x18, 0x0000, 0x0, 1);
 
     cpu_irq = microblaze_pic_init_cpu(env);
     dev = xilinx_intc_create(0x81800000, cpu_irq[0], 2);
diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c
index 2144c6a3fd..90e1301c5e 100644
--- a/hw/pflash_cfi01.c
+++ b/hw/pflash_cfi01.c
@@ -40,7 +40,6 @@
 #include "flash.h"
 #include "block.h"
 #include "qemu-timer.h"
-#include "exec-memory.h"
 
 #define PFLASH_BUG(fmt, ...) \
 do { \
@@ -75,7 +74,8 @@ struct pflash_t {
     target_phys_addr_t counter;
     unsigned int writeblock_size;
     QEMUTimer *timer;
-    MemoryRegion *mem;
+    ram_addr_t off;
+    int fl_mem;
     void *storage;
 };
 
@@ -89,7 +89,8 @@ static void pflash_timer (void *opaque)
     if (pfl->bypass) {
         pfl->wcycle = 2;
     } else {
-        memory_region_rom_device_set_readable(pfl->mem, true);
+        cpu_register_physical_memory(pfl->base, pfl->total_len,
+                        pfl->off | IO_MEM_ROMD | pfl->fl_mem);
         pfl->wcycle = 0;
     }
     pfl->cmd = 0;
@@ -262,7 +263,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
 
     if (!pfl->wcycle) {
         /* Set the device in I/O access mode */
-        memory_region_rom_device_set_readable(pfl->mem, false);
+        cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem);
     }
 
     switch (pfl->wcycle) {
@@ -421,7 +422,8 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
            __func__, offset, pfl->wcycle, pfl->cmd, value);
 
  reset_flash:
-    memory_region_rom_device_set_readable(pfl->mem, true);
+    cpu_register_physical_memory(pfl->base, pfl->total_len,
+                    pfl->off | IO_MEM_ROMD | pfl->fl_mem);
 
     pfl->bypass = 0;
     pfl->wcycle = 0;
@@ -512,20 +514,28 @@ static void pflash_writel_le(void *opaque, target_phys_addr_t addr,
     pflash_write(pfl, addr, value, 4, 0);
 }
 
-const MemoryRegionOps pflash_cfi01_ops_be = {
-    .old_mmio = {
-        .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
-        .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUWriteMemoryFunc * const pflash_write_ops_be[] = {
+    &pflash_writeb_be,
+    &pflash_writew_be,
+    &pflash_writel_be,
 };
 
-const MemoryRegionOps pflash_cfi01_ops_le = {
-    .old_mmio = {
-        .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
-        .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUReadMemoryFunc * const pflash_read_ops_be[] = {
+    &pflash_readb_be,
+    &pflash_readw_be,
+    &pflash_readl_be,
+};
+
+static CPUWriteMemoryFunc * const pflash_write_ops_le[] = {
+    &pflash_writeb_le,
+    &pflash_writew_le,
+    &pflash_writel_le,
+};
+
+static CPUReadMemoryFunc * const pflash_read_ops_le[] = {
+    &pflash_readb_le,
+    &pflash_readw_le,
+    &pflash_readl_le,
 };
 
 /* Count trailing zeroes of a 32 bits quantity */
@@ -564,11 +574,12 @@ static int ctz32 (uint32_t n)
     return ret;
 }
 
-pflash_t *pflash_cfi01_register(target_phys_addr_t base, MemoryRegion *mem,
+pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
                                 BlockDriverState *bs, uint32_t sector_len,
                                 int nb_blocs, int width,
                                 uint16_t id0, uint16_t id1,
-                                uint16_t id2, uint16_t id3)
+                                uint16_t id2, uint16_t id3,
+                                int be)
 {
     pflash_t *pfl;
     target_phys_addr_t total_len;
@@ -586,16 +597,26 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, MemoryRegion *mem,
     pfl = g_malloc0(sizeof(pflash_t));
 
     /* FIXME: Allocate ram ourselves.  */
-    pfl->storage = memory_region_get_ram_ptr(mem);
-    pfl->mem = mem;
-    memory_region_add_subregion(get_system_memory(), base, mem);
+    pfl->storage = qemu_get_ram_ptr(off);
+    if (be) {
+        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be,
+                                             pflash_write_ops_be, pfl,
+                                             DEVICE_NATIVE_ENDIAN);
+    } else {
+        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le,
+                                             pflash_write_ops_le, pfl,
+                                             DEVICE_NATIVE_ENDIAN);
+    }
+    pfl->off = off;
+    cpu_register_physical_memory(base, total_len,
+                    off | pfl->fl_mem | IO_MEM_ROMD);
 
     pfl->bs = bs;
     if (pfl->bs) {
         /* read the initial flash content */
         ret = bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9);
         if (ret < 0) {
-            memory_region_del_subregion(get_system_memory(), mem);
+            cpu_unregister_io_memory(pfl->fl_mem);
             g_free(pfl);
             return NULL;
         }
diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c
index e7e0408fc4..ac5115e4c8 100644
--- a/hw/pflash_cfi02.c
+++ b/hw/pflash_cfi02.c
@@ -39,7 +39,6 @@
 #include "flash.h"
 #include "qemu-timer.h"
 #include "block.h"
-#include "exec-memory.h"
 
 //#define PFLASH_DEBUG
 #ifdef PFLASH_DEBUG
@@ -70,39 +69,25 @@ struct pflash_t {
     uint8_t cfi_len;
     uint8_t cfi_table[0x52];
     QEMUTimer *timer;
-    /* The device replicates the flash memory across its memory space.  Emulate
-     * that by having a container (.mem) filled with an array of aliases
-     * (.mem_mappings) pointing to the flash memory (.orig_mem).
-     */
-    MemoryRegion mem;
-    MemoryRegion *mem_mappings;    /* array; one per mapping */
-    MemoryRegion *orig_mem;
+    ram_addr_t off;
+    int fl_mem;
     int rom_mode;
     int read_counter; /* used for lazy switch-back to rom mode */
     void *storage;
 };
 
-/*
- * Set up replicated mappings of the same region.
- */
-static void pflash_setup_mappings(pflash_t *pfl, MemoryRegion *mem)
-{
-    unsigned i;
-    target_phys_addr_t size = memory_region_size(mem);
-
-    pfl->orig_mem = mem;
-    memory_region_init(&pfl->mem, "pflash", pfl->mappings * size);
-    pfl->mem_mappings = g_new(MemoryRegion, pfl->mappings);
-    for (i = 0; i < pfl->mappings; ++i) {
-        memory_region_init_alias(&pfl->mem_mappings[i], "pflash-alias", mem,
-                                 0, size);
-        memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]);
-    }
-}
-
 static void pflash_register_memory(pflash_t *pfl, int rom_mode)
 {
-    memory_region_rom_device_set_readable(pfl->orig_mem, rom_mode);
+    unsigned long phys_offset = pfl->fl_mem;
+    int i;
+
+    if (rom_mode)
+        phys_offset |= pfl->off | IO_MEM_ROMD;
+    pfl->rom_mode = rom_mode;
+
+    for (i = 0; i < pfl->mappings; i++)
+        cpu_register_physical_memory(pfl->base + i * pfl->chip_len,
+                                     pfl->chip_len, phys_offset);
 }
 
 static void pflash_timer (void *opaque)
@@ -553,20 +538,28 @@ static void pflash_writel_le(void *opaque, target_phys_addr_t addr,
     pflash_write(pfl, addr, value, 4, 0);
 }
 
-const MemoryRegionOps pflash_cfi02_ops_be = {
-    .old_mmio = {
-        .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
-        .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUWriteMemoryFunc * const pflash_write_ops_be[] = {
+    &pflash_writeb_be,
+    &pflash_writew_be,
+    &pflash_writel_be,
+};
+
+static CPUReadMemoryFunc * const pflash_read_ops_be[] = {
+    &pflash_readb_be,
+    &pflash_readw_be,
+    &pflash_readl_be,
 };
 
-const MemoryRegionOps pflash_cfi02_ops_le = {
-    .old_mmio = {
-        .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
-        .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUWriteMemoryFunc * const pflash_write_ops_le[] = {
+    &pflash_writeb_le,
+    &pflash_writew_le,
+    &pflash_writel_le,
+};
+
+static CPUReadMemoryFunc * const pflash_read_ops_le[] = {
+    &pflash_readb_le,
+    &pflash_readw_le,
+    &pflash_readl_le,
 };
 
 /* Count trailing zeroes of a 32 bits quantity */
@@ -605,12 +598,13 @@ static int ctz32 (uint32_t n)
     return ret;
 }
 
-pflash_t *pflash_cfi02_register(target_phys_addr_t base, MemoryRegion *mem,
+pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
                                 BlockDriverState *bs, uint32_t sector_len,
                                 int nb_blocs, int nb_mappings, int width,
                                 uint16_t id0, uint16_t id1,
                                 uint16_t id2, uint16_t id3,
-                                uint16_t unlock_addr0, uint16_t unlock_addr1)
+                                uint16_t unlock_addr0, uint16_t unlock_addr1,
+                                int be)
 {
     pflash_t *pfl;
     int32_t chip_len;
@@ -625,22 +619,31 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, MemoryRegion *mem,
 #endif
     pfl = g_malloc0(sizeof(pflash_t));
     /* FIXME: Allocate ram ourselves.  */
-    pfl->storage = memory_region_get_ram_ptr(mem);
+    pfl->storage = qemu_get_ram_ptr(off);
+    if (be) {
+        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be,
+                                             pflash_write_ops_be,
+                                             pfl, DEVICE_NATIVE_ENDIAN);
+    } else {
+        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le,
+                                             pflash_write_ops_le,
+                                             pfl, DEVICE_NATIVE_ENDIAN);
+    }
+    pfl->off = off;
     pfl->base = base;
     pfl->chip_len = chip_len;
     pfl->mappings = nb_mappings;
+    pflash_register_memory(pfl, 1);
     pfl->bs = bs;
     if (pfl->bs) {
         /* read the initial flash content */
         ret = bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9);
         if (ret < 0) {
+            cpu_unregister_io_memory(pfl->fl_mem);
             g_free(pfl);
             return NULL;
         }
     }
-    pflash_setup_mappings(pfl, mem);
-    pfl->rom_mode = 1;
-    memory_region_add_subregion(get_system_memory(), pfl->base, &pfl->mem);
 #if 0 /* XXX: there should be a bit to set up read-only,
        *      the same way the hardware does (with WP pin).
        */
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 8f6ea42e2c..c563c6e1a3 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -142,7 +142,6 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
     int i, r;
     uint32_t smram;
 
-    memory_region_transaction_begin();
     update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3,
                &d->pam_regions[0]);
     for(i = 0; i < 12; i++) {
@@ -163,7 +162,6 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
             d->smram_enabled = false;
         }
     }
-    memory_region_transaction_commit();
 }
 
 static void i440fx_set_smm(int val, void *arg)
@@ -237,16 +235,9 @@ static int i440fx_pcihost_initfn(SysBusDevice *dev)
 {
     I440FXState *s = FROM_SYSBUS(I440FXState, dev);
 
-    memory_region_init_io(&s->conf_mem, &pci_host_conf_le_ops, s,
-                          "pci-conf-idx", 4);
-    sysbus_add_io(dev, 0xcf8, &s->conf_mem);
-    sysbus_init_ioports(&s->busdev, 0xcf8, 4);
-
-    memory_region_init_io(&s->data_mem, &pci_host_data_le_ops, s,
-                          "pci-conf-data", 4);
-    sysbus_add_io(dev, 0xcfc, &s->data_mem);
-    sysbus_init_ioports(&s->busdev, 0xcfc, 4);
+    pci_host_conf_register_ioport(0xcf8, s);
 
+    pci_host_data_register_ioport(0xcfc, s);
     return 0;
 }
 
diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c
index 1eb807c4c1..dec165e40f 100644
--- a/hw/ppc405_boards.c
+++ b/hw/ppc405_boards.c
@@ -32,7 +32,6 @@
 #include "qemu-log.h"
 #include "loader.h"
 #include "blockdev.h"
-#include "exec-memory.h"
 
 #define BIOS_FILENAME "ppc405_rom.bin"
 #define BIOS_SIZE (2048 * 1024)
@@ -182,9 +181,7 @@ static void ref405ep_init (ram_addr_t ram_size,
     ppc4xx_bd_info_t bd;
     CPUPPCState *env;
     qemu_irq *pic;
-    ram_addr_t sram_offset, bdloc;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *bios = g_new(MemoryRegion, 1);
+    ram_addr_t sram_offset, bios_offset, bdloc;
     MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
     target_phys_addr_t ram_bases[2], ram_sizes[2];
     target_ulong sram_size;
@@ -227,18 +224,18 @@ static void ref405ep_init (ram_addr_t ram_size,
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
     if (dinfo) {
         bios_size = bdrv_getlength(dinfo->bdrv);
-        memory_region_init_rom_device(bios, &pflash_cfi02_ops_be,
-                                      NULL, "ef405ep.bios", bios_size);
+        bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", bios_size);
         fl_sectors = (bios_size + 65535) >> 16;
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at addr %lx '%s' %d\n",
-               fl_idx, bios_size, -bios_size,
+               " at offset %08lx addr %lx '%s' %d\n",
+               fl_idx, bios_size, bios_offset, -bios_size,
                bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-        pflash_cfi02_register((uint32_t)(-bios_size), bios,
+        pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
                               dinfo->bdrv, 65536, fl_sectors, 1,
-                              2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
+                              2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
+                              1);
         fl_idx++;
     } else
 #endif
@@ -246,12 +243,12 @@ static void ref405ep_init (ram_addr_t ram_size,
 #ifdef DEBUG_BOARD_INIT
         printf("Load BIOS from file\n");
 #endif
-        memory_region_init_ram(bios, NULL, "ef405ep.bios", BIOS_SIZE);
+        bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", BIOS_SIZE);
         if (bios_name == NULL)
             bios_name = BIOS_FILENAME;
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (filename) {
-            bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
+            bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset));
             g_free(filename);
         } else {
             bios_size = -1;
@@ -262,9 +259,8 @@ static void ref405ep_init (ram_addr_t ram_size,
             exit(1);
         }
         bios_size = (bios_size + 0xfff) & ~0xfff;
-        memory_region_set_readonly(bios, true);
-        memory_region_add_subregion(address_space_mem, (uint32_t)(-bios_size),
-                                    bios);
+        cpu_register_physical_memory((uint32_t)(-bios_size),
+                                     bios_size, bios_offset | IO_MEM_ROM);
     }
     /* Register FPGA */
 #ifdef DEBUG_BOARD_INIT
@@ -511,9 +507,7 @@ static void taihu_405ep_init(ram_addr_t ram_size,
 {
     char *filename;
     qemu_irq *pic;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *bios = g_new(MemoryRegion, 1);
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
+    ram_addr_t bios_offset;
     MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
     target_phys_addr_t ram_bases[2], ram_sizes[2];
     long bios_size;
@@ -550,17 +544,17 @@ static void taihu_405ep_init(ram_addr_t ram_size,
         /* XXX: should check that size is 2MB */
         //        bios_size = 2 * 1024 * 1024;
         fl_sectors = (bios_size + 65535) >> 16;
-        memory_region_init_rom_device(bios, &pflash_cfi02_ops_be,
-                                      NULL, "taihu_405ep.bios", bios_size);
+        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", bios_size);
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at addr %lx '%s' %d\n",
-               fl_idx, bios_size, -bios_size,
+               " at offset %08lx addr %lx '%s' %d\n",
+               fl_idx, bios_size, bios_offset, -bios_size,
                bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-        pflash_cfi02_register((uint32_t)(-bios_size), bios,
+        pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
                               dinfo->bdrv, 65536, fl_sectors, 1,
-                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
+                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
+                              1);
         fl_idx++;
     } else
 #endif
@@ -570,10 +564,10 @@ static void taihu_405ep_init(ram_addr_t ram_size,
 #endif
         if (bios_name == NULL)
             bios_name = BIOS_FILENAME;
-        memory_region_init_ram(bios, NULL, "taihu_405ep.bios", BIOS_SIZE);
+        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", BIOS_SIZE);
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (filename) {
-            bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
+            bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset));
             g_free(filename);
         } else {
             bios_size = -1;
@@ -584,9 +578,8 @@ static void taihu_405ep_init(ram_addr_t ram_size,
             exit(1);
         }
         bios_size = (bios_size + 0xfff) & ~0xfff;
-        memory_region_set_readonly(bios, true);
-        memory_region_add_subregion(address_space_mem,
-                                    (uint32_t)(-bios_size), bios);
+        cpu_register_physical_memory((uint32_t)(-bios_size),
+                                     bios_size, bios_offset | IO_MEM_ROM);
     }
     /* Register Linux flash */
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
@@ -597,15 +590,15 @@ static void taihu_405ep_init(ram_addr_t ram_size,
         fl_sectors = (bios_size + 65535) >> 16;
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at addr " TARGET_FMT_lx " '%s'\n",
-               fl_idx, bios_size, (target_ulong)0xfc000000,
+               " at offset %08lx  addr " TARGET_FMT_lx " '%s'\n",
+               fl_idx, bios_size, bios_offset, (target_ulong)0xfc000000,
                bdrv_get_device_name(dinfo->bdrv));
 #endif
-        memory_region_init_rom_device(flash, &pflash_cfi02_ops_be,
-                                      NULL, "taihu_405ep.flash", bios_size);
-        pflash_cfi02_register(0xfc000000, flash,
+        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.flash", bios_size);
+        pflash_cfi02_register(0xfc000000, bios_offset,
                               dinfo->bdrv, 65536, fl_sectors, 1,
-                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
+                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
+                              1);
         fl_idx++;
     }
     /* Register CLPD & LCD display */
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index 339b38ec7a..52e2663a01 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -368,12 +368,10 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
     cpu_register_physical_memory(config_space + PCIC0_CFGADDR, 4, index);
 
     /* CFGDATA */
-    memory_region_init_io(&controller->pci_state.data_mem,
-                          &pci_host_data_be_ops,
-                          &controller->pci_state, "pci-conf-data", 4);
-    memory_region_add_subregion(get_system_memory(),
-                                config_space + PCIC0_CFGDATA,
-                                &controller->pci_state.data_mem);
+    index = pci_host_data_register_mmio(&controller->pci_state, 1);
+    if (index < 0)
+        goto free;
+    cpu_register_physical_memory(config_space + PCIC0_CFGDATA, 4, index);
 
     /* Internal registers */
     index = cpu_register_io_memory(pci_reg_read, pci_reg_write, controller,
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 2db365d0b6..4390aeb559 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -79,6 +79,8 @@ struct PPCE500PCIState {
     uint32_t gasket_time;
     qemu_irq irq[4];
     /* mmio maps */
+    int cfgaddr;
+    int cfgdata;
     int reg;
 };
 
@@ -266,18 +268,18 @@ static void e500_pci_map(SysBusDevice *dev, target_phys_addr_t base)
     PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
     PPCE500PCIState *s = DO_UPCAST(PPCE500PCIState, pci_state, h);
 
-    sysbus_add_memory(dev, base + PCIE500_CFGADDR, &h->conf_mem);
-    sysbus_add_memory(dev, base + PCIE500_CFGDATA, &h->data_mem);
+    cpu_register_physical_memory(base + PCIE500_CFGADDR, 4, s->cfgaddr);
+    cpu_register_physical_memory(base + PCIE500_CFGDATA, 4, s->cfgdata);
     cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE,
                                  s->reg);
 }
 
 static void e500_pci_unmap(SysBusDevice *dev, target_phys_addr_t base)
 {
-    PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
-
-    sysbus_del_memory(dev, &h->conf_mem);
-    sysbus_del_memory(dev, &h->data_mem);
+    cpu_register_physical_memory(base + PCIE500_CFGADDR, 4,
+                                 IO_MEM_UNASSIGNED);
+    cpu_register_physical_memory(base + PCIE500_CFGDATA, 4,
+                                 IO_MEM_UNASSIGNED);
     cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE,
                                  IO_MEM_UNASSIGNED);
 }
@@ -307,10 +309,9 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
 
     pci_create_simple(b, 0, "e500-host-bridge");
 
-    memory_region_init_io(&h->conf_mem, &pci_host_conf_be_ops, h,
-                          "pci-conf-idx", 4);
-    memory_region_init_io(&h->data_mem, &pci_host_data_le_ops, h,
-                          "pci-conf-data", 4);
+    s->cfgaddr = pci_host_conf_register_mmio(&s->pci_state, DEVICE_BIG_ENDIAN);
+    s->cfgdata = pci_host_data_register_mmio(&s->pci_state,
+                                             DEVICE_LITTLE_ENDIAN);
     s->reg = cpu_register_io_memory(e500_pci_reg_read, e500_pci_reg_write, s,
                                     DEVICE_BIG_ENDIAN);
     sysbus_init_mmio_cb2(dev, e500_pci_map, e500_pci_unmap);
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index 55e4e25099..c36232a808 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -125,15 +125,9 @@ PCIBus *pci_prep_init(qemu_irq *pic,
                               address_space_io,
                               0, 4);
 
-    memory_region_init_io(&s->conf_mem, &pci_host_conf_be_ops, s,
-                          "pci-conf-idx", 1);
-    memory_region_add_subregion(address_space_io, 0xcf8, &s->conf_mem);
-    sysbus_init_ioports(&s->busdev, 0xcf8, 1);
-
-    memory_region_init_io(&s->conf_mem, &pci_host_data_be_ops, s,
-                          "pci-conf-data", 1);
-    memory_region_add_subregion(address_space_io, 0xcfc, &s->data_mem);
-    sysbus_init_ioports(&s->busdev, 0xcfc, 1);
+    pci_host_conf_register_ioport(0xcf8, s);
+
+    pci_host_data_register_ioport(0xcfc, s);
 
     PPC_io_memory = cpu_register_io_memory(PPC_PCIIO_read,
                                            PPC_PCIIO_write, s,
diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index 97f90153b7..b73290cb3f 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -70,7 +70,7 @@ struct PXA2xxLCDState {
     int orientation;
 };
 
-typedef struct __attribute__ ((__packed__)) {
+typedef struct QEMU_PACKED {
     uint32_t fdaddr;
     uint32_t fsaddr;
     uint32_t fidr;
diff --git a/hw/qxl.c b/hw/qxl.c
index 1d9077db68..45e24016fc 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1388,11 +1388,7 @@ static void init_pipe_signaling(PCIQXLDevice *d)
        dprint(d, 1, "%s: pipe creation failed\n", __FUNCTION__);
        return;
    }
-#ifdef CONFIG_IOTHREAD
    fcntl(d->pipe[0], F_SETFL, O_NONBLOCK);
-#else
-   fcntl(d->pipe[0], F_SETFL, O_NONBLOCK /* | O_ASYNC */);
-#endif
    fcntl(d->pipe[1], F_SETFL, O_NONBLOCK);
    fcntl(d->pipe[0], F_SETOWN, getpid());
 
diff --git a/hw/r2d.c b/hw/r2d.c
index 41aa2c2bd2..771f3d0733 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -209,7 +209,7 @@ static void main_cpu_reset(void *opaque)
     env->pc = s->vector;
 }
 
-static struct __attribute__((__packed__))
+static struct QEMU_PACKED
 {
     int mount_root_rdonly;
     int ramdisk_flags;
@@ -235,7 +235,6 @@ static void r2d_init(ram_addr_t ram_size,
     qemu_irq *irq;
     DriveInfo *dinfo;
     int i;
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     if (!cpu_model)
         cpu_model = "SH7751R";
@@ -268,13 +267,11 @@ static void r2d_init(ram_addr_t ram_size,
 
     /* onboard flash memory */
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    memory_region_init_rom_device(flash, &pflash_cfi02_ops_le,
-                                  NULL, "r2d.flash", FLASH_SIZE);
-    pflash_cfi02_register(0x0, flash,
+    pflash_cfi02_register(0x0, qemu_ram_alloc(NULL, "r2d.flash", FLASH_SIZE),
                           dinfo ? dinfo->bdrv : NULL, (16 * 1024),
                           FLASH_SIZE >> 16,
                           1, 4, 0x0000, 0x0000, 0x0000, 0x0000,
-                          0x555, 0x2aa);
+                          0x555, 0x2aa, 0);
 
     /* NIC: rtl8139 on-board, and 2 slots. */
     for (i = 0; i < nb_nics; i++)
diff --git a/hw/rc4030.c b/hw/rc4030.c
index a2a20996a2..33e10709c6 100644
--- a/hw/rc4030.c
+++ b/hw/rc4030.c
@@ -50,7 +50,7 @@ do { fprintf(stderr, "rc4030 ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } whi
 typedef struct dma_pagetable_entry {
     int32_t frame;
     int32_t owner;
-} __attribute__((packed)) dma_pagetable_entry;
+} QEMU_PACKED dma_pagetable_entry;
 
 #define DMA_PAGESIZE    4096
 #define DMA_REG_ENABLE  1
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index d94b1eb53c..3cc830ff95 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -57,6 +57,7 @@ typedef struct SCSIDiskReq {
     struct iovec iov;
     QEMUIOVector qiov;
     uint32_t status;
+    BlockAcctCookie acct;
 } SCSIDiskReq;
 
 struct SCSIDiskState
@@ -107,10 +108,13 @@ static void scsi_cancel_io(SCSIRequest *req)
 static void scsi_read_complete(void * opaque, int ret)
 {
     SCSIDiskReq *r = (SCSIDiskReq *)opaque;
+    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
     int n;
 
     r->req.aiocb = NULL;
 
+    bdrv_acct_done(s->bs, &r->acct);
+
     if (ret) {
         if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_READ)) {
             return;
@@ -161,6 +165,8 @@ static void scsi_read_data(SCSIRequest *req)
 
     r->iov.iov_len = n * 512;
     qemu_iovec_init_external(&r->qiov, &r->iov, 1);
+
+    bdrv_acct_start(s->bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
     r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n,
                               scsi_read_complete, r);
     if (r->req.aiocb == NULL) {
@@ -207,11 +213,14 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type)
 static void scsi_write_complete(void * opaque, int ret)
 {
     SCSIDiskReq *r = (SCSIDiskReq *)opaque;
+    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
     uint32_t len;
     uint32_t n;
 
     r->req.aiocb = NULL;
 
+    bdrv_acct_done(s->bs, &r->acct);
+
     if (ret) {
         if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_WRITE)) {
             return;
@@ -252,6 +261,8 @@ static void scsi_write_data(SCSIRequest *req)
     n = r->iov.iov_len / 512;
     if (n) {
         qemu_iovec_init_external(&r->qiov, &r->iov, 1);
+
+        bdrv_acct_start(s->bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE);
         r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n,
                                    scsi_write_complete, r);
         if (r->req.aiocb == NULL) {
@@ -854,13 +865,19 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
         buflen = 8;
         break;
     case SYNCHRONIZE_CACHE:
+    {
+        BlockAcctCookie acct;
+
+        bdrv_acct_start(s->bs, &acct, 0, BDRV_ACCT_FLUSH);
         ret = bdrv_flush(s->bs);
+        bdrv_acct_done(s->bs, &acct);
         if (ret < 0) {
             if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_FLUSH)) {
                 return -1;
             }
         }
         break;
+    }
     case GET_CONFIGURATION:
         memset(outbuf, 0, 8);
         /* ??? This should probably return much more information.  For now
diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index 76061bb756..36f39300d5 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -150,7 +150,7 @@ static int sh_pci_init_device(SysBusDevice *dev)
                               PCI_DEVFN(0, 0), 4);
     memory_region_init_io(&s->memconfig_p4, &sh_pci_reg_ops, s,
                           "sh_pci", 0x224);
-    memory_region_init_alias(&s->memconfig_a7, "sh_pci.2", &s->memconfig_a7,
+    memory_region_init_alias(&s->memconfig_a7, "sh_pci.2", &s->memconfig_p4,
                              0, 0x224);
     isa_mmio_setup(&s->isa, 0x40000);
     sysbus_init_mmio_cb2(dev, sh_pci_map, sh_pci_unmap);
diff --git a/hw/smbios.c b/hw/smbios.c
index 8f2e965387..c9ba43e8d0 100644
--- a/hw/smbios.c
+++ b/hw/smbios.c
@@ -21,19 +21,19 @@
 struct smbios_header {
     uint16_t length;
     uint8_t type;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 struct smbios_field {
     struct smbios_header header;
     uint8_t type;
     uint16_t offset;
     uint8_t data[];
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 struct smbios_table {
     struct smbios_header header;
     uint8_t data[];
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 #define SMBIOS_FIELD_ENTRY 0
 #define SMBIOS_TABLE_ENTRY 1
diff --git a/hw/smbios.h b/hw/smbios.h
index 3a5169dbd3..94e3641f9a 100644
--- a/hw/smbios.h
+++ b/hw/smbios.h
@@ -26,7 +26,7 @@ struct smbios_structure_header {
     uint8_t type;
     uint8_t length;
     uint16_t handle;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 0 - BIOS Information */
 struct smbios_type_0 {
@@ -42,7 +42,7 @@ struct smbios_type_0 {
     uint8_t system_bios_minor_release;
     uint8_t embedded_controller_major_release;
     uint8_t embedded_controller_minor_release;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 1 - System Information */
 struct smbios_type_1 {
@@ -55,7 +55,7 @@ struct smbios_type_1 {
     uint8_t wake_up_type;
     uint8_t sku_number_str;
     uint8_t family_str;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 3 - System Enclosure (v2.3) */
 struct smbios_type_3 {
@@ -74,7 +74,7 @@ struct smbios_type_3 {
     uint8_t number_of_power_cords;
     uint8_t contained_element_count;
     // contained elements follow
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 4 - Processor Information (v2.0) */
 struct smbios_type_4 {
@@ -94,7 +94,7 @@ struct smbios_type_4 {
     uint16_t l1_cache_handle;
     uint16_t l2_cache_handle;
     uint16_t l3_cache_handle;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 16 - Physical Memory Array
  *   Associated with one type 17 (Memory Device).
@@ -107,7 +107,7 @@ struct smbios_type_16 {
     uint32_t maximum_capacity;
     uint16_t memory_error_information_handle;
     uint16_t number_of_memory_devices;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 /* SMBIOS type 17 - Memory Device
  *   Associated with one type 19
  */
@@ -124,7 +124,7 @@ struct smbios_type_17 {
     uint8_t bank_locator_str;
     uint8_t memory_type;
     uint16_t type_detail;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 19 - Memory Array Mapped Address */
 struct smbios_type_19 {
@@ -133,7 +133,7 @@ struct smbios_type_19 {
     uint32_t ending_address;
     uint16_t memory_array_handle;
     uint8_t partition_width;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 20 - Memory Device Mapped Address */
 struct smbios_type_20 {
@@ -145,18 +145,18 @@ struct smbios_type_20 {
     uint8_t partition_row_position;
     uint8_t interleave_position;
     uint8_t interleaved_data_depth;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 32 - System Boot Information */
 struct smbios_type_32 {
     struct smbios_structure_header header;
     uint8_t reserved[6];
     uint8_t boot_status;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 127 -- End-of-table */
 struct smbios_type_127 {
     struct smbios_structure_header header;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 #endif /*QEMU_SMBIOS_H */
diff --git a/hw/srp.h b/hw/srp.h
index afcd135c8f..3009bd56ce 100644
--- a/hw/srp.h
+++ b/hw/srp.h
@@ -106,7 +106,7 @@ struct srp_indirect_buf {
     struct srp_direct_buf    table_desc;
     uint32_t                 len;
     struct srp_direct_buf    desc_list[0];
-} __attribute__((packed));
+} QEMU_PACKED;
 
 enum {
     SRP_MULTICHAN_SINGLE = 0,
@@ -141,7 +141,7 @@ struct srp_login_rsp {
     uint16_t   buf_fmt;
     uint8_t    rsp_flags;
     uint8_t    reserved2[25];
-} __attribute__((packed));
+} QEMU_PACKED;
 
 struct srp_login_rej {
     uint8_t    opcode;
@@ -177,7 +177,7 @@ struct srp_tsk_mgmt {
     uint8_t    reserved1[6];
     uint64_t   tag;
     uint8_t    reserved2[4];
-    uint64_t   lun __attribute__((packed));
+    uint64_t   lun QEMU_PACKED;
     uint8_t    reserved3[2];
     uint8_t    tsk_mgmt_func;
     uint8_t    reserved4;
@@ -198,7 +198,7 @@ struct srp_cmd {
     uint8_t    data_in_desc_cnt;
     uint64_t   tag;
     uint8_t    reserved2[4];
-    uint64_t   lun __attribute__((packed));
+    uint64_t   lun QEMU_PACKED;
     uint8_t    reserved3;
     uint8_t    task_attr;
     uint8_t    reserved4;
@@ -235,6 +235,6 @@ struct srp_rsp {
     uint32_t   sense_data_len;
     uint32_t   resp_data_len;
     uint8_t    data[0];
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #endif /* SCSI_SRP_H */
diff --git a/hw/stellaris.c b/hw/stellaris.c
index 2bf1c235dc..9b0db7f511 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -15,7 +15,6 @@
 #include "i2c.h"
 #include "net.h"
 #include "boards.h"
-#include "exec-memory.h"
 
 #define GPIO_A 0
 #define GPIO_B 1
@@ -1261,7 +1260,6 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
         0x40024000, 0x40025000, 0x40026000};
     static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
 
-    MemoryRegion *address_space_mem = get_system_memory();
     qemu_irq *pic;
     DeviceState *gpio_dev[7];
     qemu_irq gpio_in[7][8];
@@ -1276,8 +1274,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
 
     flash_size = ((board->dc0 & 0xffff) + 1) << 1;
     sram_size = (board->dc0 >> 18) + 1;
-    pic = armv7m_init(address_space_mem,
-                      flash_size, sram_size, kernel_filename, cpu_model);
+    pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
 
     if (board->dc1 & (1 << 16)) {
         dev = sysbus_create_varargs("stellaris-adc", 0x40038000,
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index d5613ffffd..f9bd3da209 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -69,7 +69,7 @@ typedef struct {
     NICState *nic;
     NICConf conf;
     qemu_irq irq;
-    MemoryRegion mmio;
+    int mmio_index;
 } stellaris_enet_state;
 
 static void stellaris_enet_update(stellaris_enet_state *s)
@@ -130,8 +130,7 @@ static int stellaris_enet_can_receive(VLANClientState *nc)
     return (s->np < 31);
 }
 
-static uint64_t stellaris_enet_read(void *opaque, target_phys_addr_t offset,
-                                    unsigned size)
+static uint32_t stellaris_enet_read(void *opaque, target_phys_addr_t offset)
 {
     stellaris_enet_state *s = (stellaris_enet_state *)opaque;
     uint32_t val;
@@ -199,7 +198,7 @@ static uint64_t stellaris_enet_read(void *opaque, target_phys_addr_t offset,
 }
 
 static void stellaris_enet_write(void *opaque, target_phys_addr_t offset,
-                                 uint64_t value, unsigned size)
+                        uint32_t value)
 {
     stellaris_enet_state *s = (stellaris_enet_state *)opaque;
 
@@ -304,12 +303,17 @@ static void stellaris_enet_write(void *opaque, target_phys_addr_t offset,
     }
 }
 
-static const MemoryRegionOps stellaris_enet_ops = {
-    .read = stellaris_enet_read,
-    .write = stellaris_enet_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUReadMemoryFunc * const stellaris_enet_readfn[] = {
+   stellaris_enet_read,
+   stellaris_enet_read,
+   stellaris_enet_read
 };
 
+static CPUWriteMemoryFunc * const stellaris_enet_writefn[] = {
+   stellaris_enet_write,
+   stellaris_enet_write,
+   stellaris_enet_write
+};
 static void stellaris_enet_reset(stellaris_enet_state *s)
 {
     s->mdv = 0x80;
@@ -387,7 +391,7 @@ static void stellaris_enet_cleanup(VLANClientState *nc)
 
     unregister_savevm(&s->busdev.qdev, "stellaris_enet", s);
 
-    memory_region_destroy(&s->mmio);
+    cpu_unregister_io_memory(s->mmio_index);
 
     g_free(s);
 }
@@ -404,9 +408,10 @@ static int stellaris_enet_init(SysBusDevice *dev)
 {
     stellaris_enet_state *s = FROM_SYSBUS(stellaris_enet_state, dev);
 
-    memory_region_init_io(&s->mmio, &stellaris_enet_ops, s, "stellaris_enet",
-                          0x1000);
-    sysbus_init_mmio_region(dev, &s->mmio);
+    s->mmio_index = cpu_register_io_memory(stellaris_enet_readfn,
+                                           stellaris_enet_writefn, s,
+                                           DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, s->mmio_index);
     sysbus_init_irq(dev, &s->irq);
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 1b60e4ef59..32e6ab9beb 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -261,7 +261,9 @@ void cpu_check_irqs(CPUState *env)
         pil |= 1 << 14;
     }
 
-    if (!pil) {
+    /* The bit corresponding to psrpil is (1<< psrpil), the next bit
+       is (2 << psrpil). */
+    if (pil < (2 << env->psrpil)){
         if (env->interrupt_request & CPU_INTERRUPT_HARD) {
             CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n",
                            env->interrupt_index);
@@ -293,10 +295,12 @@ void cpu_check_irqs(CPUState *env)
                 break;
             }
         }
-    } else {
+    } else if (env->interrupt_request & CPU_INTERRUPT_HARD) {
         CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x "
                        "current interrupt %x\n",
                        pil, env->pil_in, env->softint, env->interrupt_index);
+        env->interrupt_index = 0;
+        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
     }
 }
 
diff --git a/hw/sysbus.c b/hw/sysbus.c
index 6e89f065b4..c365d39d24 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -131,6 +131,11 @@ void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory)
     dev->mmio[n].memory = memory;
 }
 
+MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n)
+{
+    return dev->mmio[n].memory;
+}
+
 void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size)
 {
     pio_addr_t i;
@@ -256,32 +261,3 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev)
 
     return strdup(path);
 }
-
-void sysbus_add_memory(SysBusDevice *dev, target_phys_addr_t addr,
-                       MemoryRegion *mem)
-{
-    memory_region_add_subregion(get_system_memory(), addr, mem);
-}
-
-void sysbus_add_memory_overlap(SysBusDevice *dev, target_phys_addr_t addr,
-                               MemoryRegion *mem, unsigned priority)
-{
-    memory_region_add_subregion_overlap(get_system_memory(), addr, mem,
-                                        priority);
-}
-
-void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem)
-{
-    memory_region_del_subregion(get_system_memory(), mem);
-}
-
-void sysbus_add_io(SysBusDevice *dev, target_phys_addr_t addr,
-                       MemoryRegion *mem)
-{
-    memory_region_add_subregion(get_system_io(), addr, mem);
-}
-
-void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem)
-{
-    memory_region_del_subregion(get_system_io(), mem);
-}
diff --git a/hw/sysbus.h b/hw/sysbus.h
index b3e1f99db5..aa3d383277 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -50,6 +50,7 @@ void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size,
 void sysbus_init_mmio_cb2(SysBusDevice *dev,
                           mmio_mapfunc cb, mmio_mapfunc unmap);
 void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory);
+MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n);
 void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p);
 void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target);
 void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size);
@@ -57,14 +58,6 @@ void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size);
 
 void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq);
 void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr);
-void sysbus_add_memory(SysBusDevice *dev, target_phys_addr_t addr,
-                       MemoryRegion *mem);
-void sysbus_add_memory_overlap(SysBusDevice *dev, target_phys_addr_t addr,
-                               MemoryRegion *mem, unsigned priority);
-void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem);
-void sysbus_add_io(SysBusDevice *dev, target_phys_addr_t addr,
-                   MemoryRegion *mem);
-void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem);
 
 /* Legacy helper function for creating devices.  */
 DeviceState *sysbus_create_varargs(const char *name,
diff --git a/hw/tusb6010.c b/hw/tusb6010.c
index b2bf35934d..de6ffc6133 100644
--- a/hw/tusb6010.c
+++ b/hw/tusb6010.c
@@ -23,9 +23,11 @@
 #include "usb.h"
 #include "omap.h"
 #include "irq.h"
-#include "tusb6010.h"
+#include "devices.h"
+#include "sysbus.h"
 
-struct TUSBState {
+typedef struct TUSBState {
+    SysBusDevice busdev;
     MemoryRegion iomem[2];
     qemu_irq irq;
     MUSBState *musb;
@@ -59,7 +61,7 @@ struct TUSBState {
     uint32_t pullup[2];
     uint32_t control_config;
     uint32_t otg_timer_val;
-};
+} TUSBState;
 
 #define TUSB_DEVCLOCK			60000000	/* 60 MHz */
 
@@ -234,16 +236,6 @@ struct TUSBState {
 #define TUSB_EP_CONFIG_XFR_SIZE(v)	((v) & 0x7fffffff)
 #define TUSB_PROD_TEST_RESET_VAL	0xa596
 
-MemoryRegion *tusb6010_sync_io(TUSBState *s)
-{
-    return &s->iomem[0];
-}
-
-MemoryRegion *tusb6010_async_io(TUSBState *s)
-{
-    return &s->iomem[1];
-}
-
 static void tusb_intr_update(TUSBState *s)
 {
     if (s->control_config & TUSB_INT_CTRL_CONF_INT_POLARITY)
@@ -723,9 +715,33 @@ static void tusb_musb_core_intr(void *opaque, int source, int level)
     }
 }
 
-TUSBState *tusb6010_init(qemu_irq intr)
+static void tusb6010_power(TUSBState *s, int on)
 {
-    TUSBState *s = g_malloc0(sizeof(*s));
+    if (!on) {
+        s->power = 0;
+    } else if (!s->power && on) {
+        s->power = 1;
+        /* Pull the interrupt down after TUSB6010 comes up.  */
+        s->intr_ok = 0;
+        tusb_intr_update(s);
+        qemu_mod_timer(s->pwr_timer,
+                       qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 2);
+    }
+}
+
+static void tusb6010_irq(void *opaque, int source, int level)
+{
+    if (source) {
+        tusb_musb_core_intr(opaque, source - 1, level);
+    } else {
+        tusb6010_power(opaque, level);
+    }
+}
+
+static void tusb6010_reset(DeviceState *dev)
+{
+    TUSBState *s = FROM_SYSBUS(TUSBState, sysbus_from_qdev(dev));
+    int i;
 
     s->test_reset = TUSB_PROD_TEST_RESET_VAL;
     s->host_mode = 0;
@@ -735,28 +751,59 @@ TUSBState *tusb6010_init(qemu_irq intr)
     s->mask = 0xffffffff;
     s->intr = 0x00000000;
     s->otg_timer_val = 0;
-    memory_region_init_io(&s->iomem[1], &tusb_async_ops, s, "tusb-async",
-                          UINT32_MAX);
-    s->irq = intr;
+    s->scratch = 0;
+    s->prcm_config = 0;
+    s->prcm_mngmt = 0;
+    s->intr_ok = 0;
+    s->usbip_intr = 0;
+    s->usbip_mask = 0;
+    s->gpio_intr = 0;
+    s->gpio_mask = 0;
+    s->gpio_config = 0;
+    s->dma_intr = 0;
+    s->dma_mask = 0;
+    s->dma_map = 0;
+    s->dma_config = 0;
+    s->ep0_config = 0;
+    s->wkup_mask = 0;
+    s->pullup[0] = s->pullup[1] = 0;
+    s->control_config = 0;
+    for (i = 0; i < 15; i++) {
+        s->rx_config[i] = s->tx_config[i] = 0;
+    }
+}
+
+static int tusb6010_init(SysBusDevice *dev)
+{
+    TUSBState *s = FROM_SYSBUS(TUSBState, dev);
+    qemu_irq *musb_irqs;
+    int i;
     s->otg_timer = qemu_new_timer_ns(vm_clock, tusb_otg_tick, s);
     s->pwr_timer = qemu_new_timer_ns(vm_clock, tusb_power_tick, s);
-    s->musb = musb_init(qemu_allocate_irqs(tusb_musb_core_intr, s,
-                            __musb_irq_max));
-
-    return s;
+    memory_region_init_io(&s->iomem[1], &tusb_async_ops, s, "tusb-async",
+                          UINT32_MAX);
+    sysbus_init_mmio_region(dev, &s->iomem[0]);
+    sysbus_init_mmio_region(dev, &s->iomem[1]);
+    sysbus_init_irq(dev, &s->irq);
+    qdev_init_gpio_in(&dev->qdev, tusb6010_irq, __musb_irq_max + 1);
+    musb_irqs = g_new0(qemu_irq, __musb_irq_max);
+    for (i = 0; i < __musb_irq_max; i++) {
+        musb_irqs[i] = qdev_get_gpio_in(&dev->qdev, i + 1);
+    }
+    s->musb = musb_init(musb_irqs);
+    return 0;
 }
 
-void tusb6010_power(TUSBState *s, int on)
-{
-    if (!on)
-        s->power = 0;
-    else if (!s->power && on) {
-        s->power = 1;
+static SysBusDeviceInfo tusb6010_info = {
+    .init = tusb6010_init,
+    .qdev.name = "tusb6010",
+    .qdev.size = sizeof(TUSBState),
+    .qdev.reset = tusb6010_reset,
+};
 
-        /* Pull the interrupt down after TUSB6010 comes up.  */
-        s->intr_ok = 0;
-        tusb_intr_update(s);
-        qemu_mod_timer(s->pwr_timer,
-                       qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 2);
-    }
+static void tusb6010_register_device(void)
+{
+    sysbus_register_withprop(&tusb6010_info);
 }
+
+device_init(tusb6010_register_device)
diff --git a/hw/tusb6010.h b/hw/tusb6010.h
deleted file mode 100644
index b85ee86215..0000000000
--- a/hw/tusb6010.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * tusb6010 interfaces
- *
- * Copyright 2011 Red Hat, Inc. and/or its affiliates
- *
- * Authors:
- *  Avi Kivity <avi@redhat.com>
- *
- * Derived from hw/devices.h.
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef TUSB6010_H
-#define TUSB6010_H
-
-#include "targphys.h"
-#include "memory.h"
-
-typedef struct TUSBState TUSBState;
-TUSBState *tusb6010_init(qemu_irq intr);
-MemoryRegion *tusb6010_sync_io(TUSBState *s);
-MemoryRegion *tusb6010_async_io(TUSBState *s);
-void tusb6010_power(TUSBState *s, int on);
-
-#endif
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 600cd1e5bd..f896f8c76b 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -41,6 +41,7 @@ static const int unin_irq_line[] = { 0x1b, 0x1c, 0x1d, 0x1e };
 typedef struct UNINState {
     SysBusDevice busdev;
     PCIHostState host_state;
+    ReadWriteHandler data_handler;
 } UNINState;
 
 static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num)
@@ -99,70 +100,67 @@ static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr)
     return retval;
 }
 
-static void unin_data_write(void *opaque, target_phys_addr_t addr,
-                            uint64_t val, unsigned len)
+static void unin_data_write(ReadWriteHandler *handler,
+                            pcibus_t addr, uint32_t val, int len)
 {
-    UNINState *s = opaque;
-    UNIN_DPRINTF("write addr %" TARGET_FMT_plx " len %d val %"PRIx64"\n",
-                 addr, len, val);
+    UNINState *s = container_of(handler, UNINState, data_handler);
+    UNIN_DPRINTF("write addr %" FMT_PCIBUS " len %d val %x\n", addr, len, val);
     pci_data_write(s->host_state.bus,
                    unin_get_config_reg(s->host_state.config_reg, addr),
                    val, len);
 }
 
-static uint64_t unin_data_read(void *opaque, target_phys_addr_t addr,
-                               unsigned len)
+static uint32_t unin_data_read(ReadWriteHandler *handler,
+                               pcibus_t addr, int len)
 {
-    UNINState *s = opaque;
+    UNINState *s = container_of(handler, UNINState, data_handler);
     uint32_t val;
 
     val = pci_data_read(s->host_state.bus,
                         unin_get_config_reg(s->host_state.config_reg, addr),
                         len);
-    UNIN_DPRINTF("read addr %" TARGET_FMT_plx " len %d val %x\n",
-                 addr, len, val);
+    UNIN_DPRINTF("read addr %" FMT_PCIBUS " len %d val %x\n", addr, len, val);
     return val;
 }
 
-static const MemoryRegionOps unin_data_ops = {
-    .read = unin_data_read,
-    .write = unin_data_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
 static int pci_unin_main_init_device(SysBusDevice *dev)
 {
     UNINState *s;
+    int pci_mem_config, pci_mem_data;
 
     /* Use values found on a real PowerMac */
     /* Uninorth main bus */
     s = FROM_SYSBUS(UNINState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s,
-                          "pci-conf-data", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    s->data_handler.read = unin_data_read;
+    s->data_handler.write = unin_data_write;
+    pci_mem_data = cpu_register_io_memory_simple(&s->data_handler,
+                                                 DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
 
     qemu_register_reset(pci_unin_reset, &s->host_state);
     return 0;
 }
 
-
 static int pci_u3_agp_init_device(SysBusDevice *dev)
 {
     UNINState *s;
+    int pci_mem_config, pci_mem_data;
 
     /* Uninorth U3 AGP bus */
     s = FROM_SYSBUS(UNINState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s,
-                          "pci-conf-data", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    s->data_handler.read = unin_data_read;
+    s->data_handler.write = unin_data_write;
+    pci_mem_data = cpu_register_io_memory_simple(&s->data_handler,
+                                                 DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
 
     qemu_register_reset(pci_unin_reset, &s->host_state);
 
@@ -172,32 +170,34 @@ static int pci_u3_agp_init_device(SysBusDevice *dev)
 static int pci_unin_agp_init_device(SysBusDevice *dev)
 {
     UNINState *s;
+    int pci_mem_config, pci_mem_data;
 
     /* Uninorth AGP bus */
     s = FROM_SYSBUS(UNINState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
-                          &s->host_state, "pci-conf-data", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    pci_mem_data = pci_host_data_register_mmio(&s->host_state,
+                                               DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
     return 0;
 }
 
 static int pci_unin_internal_init_device(SysBusDevice *dev)
 {
     UNINState *s;
+    int pci_mem_config, pci_mem_data;
 
     /* Uninorth internal bus */
     s = FROM_SYSBUS(UNINState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
-                          &s->host_state, "pci-conf-data", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    pci_mem_data = pci_host_data_register_mmio(&s->host_state,
+                                               DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
     return 0;
 }
 
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index 66aeb211af..c2f9241014 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -176,56 +176,56 @@ enum {
      */
 };
 
-typedef struct __attribute__ ((__packed__)) CCID_Header {
+typedef struct QEMU_PACKED CCID_Header {
     uint8_t     bMessageType;
     uint32_t    dwLength;
     uint8_t     bSlot;
     uint8_t     bSeq;
 } CCID_Header;
 
-typedef struct __attribute__ ((__packed__)) CCID_BULK_IN {
+typedef struct QEMU_PACKED CCID_BULK_IN {
     CCID_Header hdr;
     uint8_t     bStatus;        /* Only used in BULK_IN */
     uint8_t     bError;         /* Only used in BULK_IN */
 } CCID_BULK_IN;
 
-typedef struct __attribute__ ((__packed__)) CCID_SlotStatus {
+typedef struct QEMU_PACKED CCID_SlotStatus {
     CCID_BULK_IN b;
     uint8_t     bClockStatus;
 } CCID_SlotStatus;
 
-typedef struct __attribute__ ((__packed__)) CCID_Parameter {
+typedef struct QEMU_PACKED CCID_Parameter {
     CCID_BULK_IN b;
     uint8_t     bProtocolNum;
     uint8_t     abProtocolDataStructure[0];
 } CCID_Parameter;
 
-typedef struct __attribute__ ((__packed__)) CCID_DataBlock {
+typedef struct QEMU_PACKED CCID_DataBlock {
     CCID_BULK_IN b;
     uint8_t      bChainParameter;
     uint8_t      abData[0];
 } CCID_DataBlock;
 
 /* 6.1.4 PC_to_RDR_XfrBlock */
-typedef struct __attribute__ ((__packed__)) CCID_XferBlock {
+typedef struct QEMU_PACKED CCID_XferBlock {
     CCID_Header  hdr;
     uint8_t      bBWI; /* Block Waiting Timeout */
     uint16_t     wLevelParameter; /* XXX currently unused */
     uint8_t      abData[0];
 } CCID_XferBlock;
 
-typedef struct __attribute__ ((__packed__)) CCID_IccPowerOn {
+typedef struct QEMU_PACKED CCID_IccPowerOn {
     CCID_Header hdr;
     uint8_t     bPowerSelect;
     uint16_t    abRFU;
 } CCID_IccPowerOn;
 
-typedef struct __attribute__ ((__packed__)) CCID_IccPowerOff {
+typedef struct QEMU_PACKED CCID_IccPowerOff {
     CCID_Header hdr;
     uint16_t    abRFU;
 } CCID_IccPowerOff;
 
-typedef struct __attribute__ ((__packed__)) CCID_SetParameters {
+typedef struct QEMU_PACKED CCID_SetParameters {
     CCID_Header hdr;
     uint8_t     bProtocolNum;
     uint16_t   abRFU;
diff --git a/hw/vga.c b/hw/vga.c
index 851fd689b3..125fb293f2 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -176,6 +176,7 @@ static void vga_update_memory_access(VGACommonState *s)
             size = 0x8000;
             break;
         case 3:
+        default:
             base = 0xb8000;
             size = 0x8000;
             break;
diff --git a/hw/vhost.c b/hw/vhost.c
index 18860678ba..0870cb7d85 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -515,11 +515,6 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
     };
     struct VirtQueue *vvq = virtio_get_queue(vdev, idx);
 
-    if (!vdev->binding->set_host_notifier) {
-        fprintf(stderr, "binding does not support host notifiers\n");
-        return -ENOSYS;
-    }
-
     vq->num = state.num = virtio_queue_get_num(vdev, idx);
     r = ioctl(dev->control, VHOST_SET_VRING_NUM, &state);
     if (r) {
@@ -567,12 +562,6 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
         r = -errno;
         goto fail_alloc;
     }
-    r = vdev->binding->set_host_notifier(vdev->binding_opaque, idx, true);
-    if (r < 0) {
-        fprintf(stderr, "Error binding host notifier: %d\n", -r);
-        goto fail_host_notifier;
-    }
-
     file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq));
     r = ioctl(dev->control, VHOST_SET_VRING_KICK, &file);
     if (r) {
@@ -591,8 +580,6 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
 
 fail_call:
 fail_kick:
-    vdev->binding->set_host_notifier(vdev->binding_opaque, idx, false);
-fail_host_notifier:
 fail_alloc:
     cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
                               0, 0);
@@ -618,12 +605,6 @@ static void vhost_virtqueue_cleanup(struct vhost_dev *dev,
         .index = idx,
     };
     int r;
-    r = vdev->binding->set_host_notifier(vdev->binding_opaque, idx, false);
-    if (r < 0) {
-        fprintf(stderr, "vhost VQ %d host cleanup failed: %d\n", idx, r);
-        fflush(stderr);
-    }
-    assert (r >= 0);
     r = ioctl(dev->control, VHOST_GET_VRING_BASE, &state);
     if (r < 0) {
         fprintf(stderr, "vhost VQ %d ring restore failed: %d\n", idx, r);
@@ -697,6 +678,60 @@ bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev)
         hdev->force;
 }
 
+/* Stop processing guest IO notifications in qemu.
+ * Start processing them in vhost in kernel.
+ */
+int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev)
+{
+    int i, r;
+    if (!vdev->binding->set_host_notifier) {
+        fprintf(stderr, "binding does not support host notifiers\n");
+        r = -ENOSYS;
+        goto fail;
+    }
+
+    for (i = 0; i < hdev->nvqs; ++i) {
+        r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, true);
+        if (r < 0) {
+            fprintf(stderr, "vhost VQ %d notifier binding failed: %d\n", i, -r);
+            goto fail_vq;
+        }
+    }
+
+    return 0;
+fail_vq:
+    while (--i >= 0) {
+        r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, false);
+        if (r < 0) {
+            fprintf(stderr, "vhost VQ %d notifier cleanup error: %d\n", i, -r);
+            fflush(stderr);
+        }
+        assert (r >= 0);
+    }
+fail:
+    return r;
+}
+
+/* Stop processing guest IO notifications in vhost.
+ * Start processing them in qemu.
+ * This might actually run the qemu handlers right away,
+ * so virtio in qemu must be completely setup when this is called.
+ */
+void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev)
+{
+    int i, r;
+
+    for (i = 0; i < hdev->nvqs; ++i) {
+        r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, false);
+        if (r < 0) {
+            fprintf(stderr, "vhost VQ %d notifier cleanup failed: %d\n", i, -r);
+            fflush(stderr);
+        }
+        assert (r >= 0);
+    }
+}
+
+/* Host notifiers must be enabled at this point. */
 int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
 {
     int i, r;
@@ -762,6 +797,7 @@ fail:
     return r;
 }
 
+/* Host notifiers must be enabled at this point. */
 void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
 {
     int i, r;
diff --git a/hw/vhost.h b/hw/vhost.h
index c8c595a147..c9452f0732 100644
--- a/hw/vhost.h
+++ b/hw/vhost.h
@@ -46,5 +46,7 @@ void vhost_dev_cleanup(struct vhost_dev *hdev);
 bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev);
 int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
 void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev);
+int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
+void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
 
 #endif
diff --git a/hw/vhost_net.c b/hw/vhost_net.c
index a55981200d..950a6b8d99 100644
--- a/hw/vhost_net.c
+++ b/hw/vhost_net.c
@@ -139,16 +139,22 @@ int vhost_net_start(struct vhost_net *net,
 {
     struct vhost_vring_file file = { };
     int r;
+
+    net->dev.nvqs = 2;
+    net->dev.vqs = net->vqs;
+
+    r = vhost_dev_enable_notifiers(&net->dev, dev);
+    if (r < 0) {
+        goto fail_notifiers;
+    }
     if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
         tap_set_vnet_hdr_len(net->vc,
                              sizeof(struct virtio_net_hdr_mrg_rxbuf));
     }
 
-    net->dev.nvqs = 2;
-    net->dev.vqs = net->vqs;
     r = vhost_dev_start(&net->dev, dev);
     if (r < 0) {
-        return r;
+        goto fail_start;
     }
 
     net->vc->info->poll(net->vc, false);
@@ -173,6 +179,9 @@ fail:
     if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
         tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
     }
+fail_start:
+    vhost_dev_disable_notifiers(&net->dev, dev);
+fail_notifiers:
     return r;
 }
 
@@ -190,6 +199,7 @@ void vhost_net_stop(struct vhost_net *net,
     if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
         tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
     }
+    vhost_dev_disable_notifiers(&net->dev, dev);
 }
 
 void vhost_net_cleanup(struct vhost_net *net)
diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c
index aa9e51222f..333050cdac 100644
--- a/hw/virtex_ml507.c
+++ b/hw/virtex_ml507.c
@@ -196,7 +196,7 @@ static void virtex_init(ram_addr_t ram_size,
     target_phys_addr_t ram_base = 0;
     DriveInfo *dinfo;
     ram_addr_t phys_ram;
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_flash;
     qemu_irq irq[32], *cpu_irq;
     clk_setup_t clk_setup[7];
     int kernel_size;
@@ -215,13 +215,12 @@ static void virtex_init(ram_addr_t ram_size,
     phys_ram = qemu_ram_alloc(NULL, "ram", ram_size);
     cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
-                                  NULL, "virtex.flash", FLASH_SIZE);
+    phys_flash = qemu_ram_alloc(NULL, "virtex.flash", FLASH_SIZE);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(0xfc000000, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
-                          1, 0x89, 0x18, 0x0000, 0x0);
+                          1, 0x89, 0x18, 0x0000, 0x0, 1);
 
     cpu_irq = (qemu_irq *) &env->irq_inputs[PPC40x_INPUT_INT];
     dev = xilinx_intc_create(0x81800000, cpu_irq[0], 0);
diff --git a/hw/virtio-balloon.h b/hw/virtio-balloon.h
index e20cf6bc0d..73300ddc86 100644
--- a/hw/virtio-balloon.h
+++ b/hw/virtio-balloon.h
@@ -50,6 +50,6 @@ struct virtio_balloon_config
 typedef struct VirtIOBalloonStat {
     uint16_t tag;
     uint64_t val;
-} __attribute__((packed)) VirtIOBalloonStat;
+} QEMU_PACKED VirtIOBalloonStat;
 
 #endif
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index dad8c0a6a2..2a8ccd0aa9 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -47,6 +47,7 @@ typedef struct VirtIOBlockReq
     struct virtio_scsi_inhdr *scsi;
     QEMUIOVector qiov;
     struct VirtIOBlockReq *next;
+    BlockAcctCookie acct;
 } VirtIOBlockReq;
 
 static void virtio_blk_req_complete(VirtIOBlockReq *req, int status)
@@ -58,8 +59,6 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, int status)
     stb_p(&req->in->status, status);
     virtqueue_push(s->vq, &req->elem, req->qiov.size + sizeof(*req->in));
     virtio_notify(&s->vdev, s->vq);
-
-    g_free(req);
 }
 
 static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
@@ -81,6 +80,8 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
         vm_stop(VMSTOP_DISKFULL);
     } else {
         virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
+        bdrv_acct_done(s->bs, &req->acct);
+        g_free(req);
         bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
     }
 
@@ -100,6 +101,8 @@ static void virtio_blk_rw_complete(void *opaque, int ret)
     }
 
     virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
+    bdrv_acct_done(req->dev->bs, &req->acct);
+    g_free(req);
 }
 
 static void virtio_blk_flush_complete(void *opaque, int ret)
@@ -113,6 +116,8 @@ static void virtio_blk_flush_complete(void *opaque, int ret)
     }
 
     virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
+    bdrv_acct_done(req->dev->bs, &req->acct);
+    g_free(req);
 }
 
 static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
@@ -155,6 +160,7 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
      */
     if (req->elem.out_num < 2 || req->elem.in_num < 3) {
         virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
+        g_free(req);
         return;
     }
 
@@ -163,6 +169,7 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
      */
     if (req->elem.out_num > 2 && req->elem.in_num > 3) {
         virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
+        g_free(req);
         return;
     }
 
@@ -229,11 +236,13 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
     stl_p(&req->scsi->data_len, hdr.dxfer_len);
 
     virtio_blk_req_complete(req, status);
+    g_free(req);
 }
 #else
 static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
 {
     virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
+    g_free(req);
 }
 #endif /* __linux__ */
 
@@ -266,6 +275,8 @@ static void virtio_blk_handle_flush(VirtIOBlockReq *req, MultiReqBuffer *mrb)
 {
     BlockDriverAIOCB *acb;
 
+    bdrv_acct_start(req->dev->bs, &req->acct, 0, BDRV_ACCT_FLUSH);
+
     /*
      * Make sure all outstanding writes are posted to the backing device.
      */
@@ -284,6 +295,8 @@ static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb)
 
     sector = ldq_p(&req->out->sector);
 
+    bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_WRITE);
+
     trace_virtio_blk_handle_write(req, sector, req->qiov.size / 512);
 
     if (sector & req->dev->sector_mask) {
@@ -317,6 +330,8 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req)
 
     sector = ldq_p(&req->out->sector);
 
+    bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ);
+
     if (sector & req->dev->sector_mask) {
         virtio_blk_rw_complete(req, -EIO);
         return;
@@ -370,6 +385,7 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req,
                 s->serial ? s->serial : "",
                 MIN(req->elem.in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES));
         virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
+        g_free(req);
     } else if (type & VIRTIO_BLK_T_OUT) {
         qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
                                  req->elem.out_num - 1);
diff --git a/hw/virtio-blk.h b/hw/virtio-blk.h
index 5645d2bf3c..244dce45aa 100644
--- a/hw/virtio-blk.h
+++ b/hw/virtio-blk.h
@@ -49,7 +49,7 @@ struct virtio_blk_config
     uint8_t alignment_offset;
     uint16_t min_io_size;
     uint32_t opt_io_size;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 /* These two define direction. */
 #define VIRTIO_BLK_T_IN         0
diff --git a/hw/virtio-net.h b/hw/virtio-net.h
index 8af9a1ce55..44687414c9 100644
--- a/hw/virtio-net.h
+++ b/hw/virtio-net.h
@@ -72,7 +72,7 @@ struct virtio_net_config
     uint8_t mac[ETH_ALEN];
     /* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */
     uint16_t status;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 /* This is the first element of the scatter-gather list.  If you don't
  * specify GSO or CSUM features, you can simply ignore the header. */
diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
index 36e9d222e5..ab138038c0 100644
--- a/hw/virtio-serial.h
+++ b/hw/virtio-serial.h
@@ -37,7 +37,7 @@ struct virtio_console_config {
     uint16_t rows;
 
     uint32_t max_nr_ports;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 struct virtio_console_control {
     uint32_t id;		/* Port number */
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 52d2d26f1b..aa682376ad 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -70,7 +70,7 @@ struct vmsvga_state_s {
 
     union {
         uint32_t *fifo;
-        struct __attribute__((__packed__)) {
+        struct QEMU_PACKED {
             uint32_t min;
             uint32_t max;
             uint32_t next_cmd;
diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 31f91514f2..bd5c66916b 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -79,6 +79,7 @@ struct ioreq {
 
     struct XenBlkDev    *blkdev;
     QLIST_ENTRY(ioreq)   list;
+    BlockAcctCookie     acct;
 };
 
 struct XenBlkDev {
@@ -401,6 +402,7 @@ static void qemu_aio_complete(void *opaque, int ret)
     ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
     ioreq_unmap(ioreq);
     ioreq_finish(ioreq);
+    bdrv_acct_done(ioreq->blkdev->bs, &ioreq->acct);
     qemu_bh_schedule(ioreq->blkdev->bh);
 }
 
@@ -419,6 +421,7 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
 
     switch (ioreq->req.operation) {
     case BLKIF_OP_READ:
+        bdrv_acct_start(blkdev->bs, &ioreq->acct, ioreq->v.size, BDRV_ACCT_READ);
         ioreq->aio_inflight++;
         bdrv_aio_readv(blkdev->bs, ioreq->start / BLOCK_SIZE,
                        &ioreq->v, ioreq->v.size / BLOCK_SIZE,
@@ -429,6 +432,8 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
         if (!ioreq->req.nr_segments) {
             break;
         }
+
+        bdrv_acct_start(blkdev->bs, &ioreq->acct, ioreq->v.size, BDRV_ACCT_WRITE);
         ioreq->aio_inflight++;
         bdrv_aio_writev(blkdev->bs, ioreq->start / BLOCK_SIZE,
                         &ioreq->v, ioreq->v.size / BLOCK_SIZE,
diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c
index f35ba8461a..6f44c8466e 100644
--- a/hw/xilinx_ethlite.c
+++ b/hw/xilinx_ethlite.c
@@ -50,6 +50,7 @@
 struct xlx_ethlite
 {
     SysBusDevice busdev;
+    MemoryRegion mmio;
     qemu_irq irq;
     NICState *nic;
     NICConf conf;
@@ -70,7 +71,8 @@ static inline void eth_pulse_irq(struct xlx_ethlite *s)
     }
 }
 
-static uint32_t eth_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t
+eth_read(void *opaque, target_phys_addr_t addr, unsigned int size)
 {
     struct xlx_ethlite *s = opaque;
     uint32_t r = 0;
@@ -98,10 +100,12 @@ static uint32_t eth_readl (void *opaque, target_phys_addr_t addr)
 }
 
 static void
-eth_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+eth_write(void *opaque, target_phys_addr_t addr,
+          uint64_t val64, unsigned int size)
 {
     struct xlx_ethlite *s = opaque;
     unsigned int base = 0;
+    uint32_t value = val64;
 
     addr >>= 2;
     switch (addr) 
@@ -146,12 +150,14 @@ eth_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     }
 }
 
-static CPUReadMemoryFunc * const eth_read[] = {
-    NULL, NULL, &eth_readl,
-};
-
-static CPUWriteMemoryFunc * const eth_write[] = {
-    NULL, NULL, &eth_writel,
+static const MemoryRegionOps eth_ops = {
+    .read = eth_read,
+    .write = eth_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4
+    }
 };
 
 static int eth_can_rx(VLANClientState *nc)
@@ -206,13 +212,12 @@ static NetClientInfo net_xilinx_ethlite_info = {
 static int xilinx_ethlite_init(SysBusDevice *dev)
 {
     struct xlx_ethlite *s = FROM_SYSBUS(typeof (*s), dev);
-    int regs;
 
     sysbus_init_irq(dev, &s->irq);
     s->rxbuf = 0;
 
-    regs = cpu_register_io_memory(eth_read, eth_write, s, DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, R_MAX * 4, regs);
+    memory_region_init_io(&s->mmio, &eth_ops, s, "xilinx-ethlite", R_MAX * 4);
+    sysbus_init_mmio_region(dev, &s->mmio);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf,
diff --git a/hw/xilinx_intc.c b/hw/xilinx_intc.c
index cb72d5a14e..58b73d95cc 100644
--- a/hw/xilinx_intc.c
+++ b/hw/xilinx_intc.c
@@ -40,6 +40,7 @@
 struct xlx_pic
 {
     SysBusDevice busdev;
+    MemoryRegion mmio;
     qemu_irq parent_irq;
 
     /* Configuration reg chosen at synthesis-time. QEMU populates
@@ -72,7 +73,8 @@ static void update_irq(struct xlx_pic *p)
     }
 }
 
-static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t
+pic_read(void *opaque, target_phys_addr_t addr, unsigned int size)
 {
     struct xlx_pic *p = opaque;
     uint32_t r = 0;
@@ -91,9 +93,11 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
 }
 
 static void
-pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+pic_write(void *opaque, target_phys_addr_t addr,
+          uint64_t val64, unsigned int size)
 {
     struct xlx_pic *p = opaque;
+    uint32_t value = val64;
 
     addr >>= 2;
     D(qemu_log("%s addr=%x val=%x\n", __func__, addr * 4, value));
@@ -116,14 +120,14 @@ pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     update_irq(p);
 }
 
-static CPUReadMemoryFunc * const pic_read[] = {
-    NULL, NULL,
-    &pic_readl,
-};
-
-static CPUWriteMemoryFunc * const pic_write[] = {
-    NULL, NULL,
-    &pic_writel,
+static const MemoryRegionOps pic_ops = {
+    .read = pic_read,
+    .write = pic_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4
+    }
 };
 
 static void irq_handler(void *opaque, int irq, int level)
@@ -148,13 +152,12 @@ static void irq_handler(void *opaque, int irq, int level)
 static int xilinx_intc_init(SysBusDevice *dev)
 {
     struct xlx_pic *p = FROM_SYSBUS(typeof (*p), dev);
-    int pic_regs;
 
     qdev_init_gpio_in(&dev->qdev, irq_handler, 32);
     sysbus_init_irq(dev, &p->parent_irq);
 
-    pic_regs = cpu_register_io_memory(pic_read, pic_write, p, DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, R_MAX * 4, pic_regs);
+    memory_region_init_io(&p->mmio, &pic_ops, p, "xilinx-pic", R_MAX * 4);
+    sysbus_init_mmio_region(dev, &p->mmio);
     return 0;
 }
 
diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c
index f1c7abc99e..8779c56f0b 100644
--- a/hw/xilinx_timer.c
+++ b/hw/xilinx_timer.c
@@ -59,6 +59,7 @@ struct xlx_timer
 struct timerblock
 {
     SysBusDevice busdev;
+    MemoryRegion mmio;
     qemu_irq irq;
     uint32_t nr_timers;
     uint32_t freq_hz;
@@ -85,7 +86,8 @@ static void timer_update_irq(struct timerblock *t)
     qemu_set_irq(t->irq, !!irq);
 }
 
-static uint32_t timer_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t
+timer_read(void *opaque, target_phys_addr_t addr, unsigned int size)
 {
     struct timerblock *t = opaque;
     struct xlx_timer *xt;
@@ -134,11 +136,13 @@ static void timer_enable(struct xlx_timer *xt)
 }
 
 static void
-timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+timer_write(void *opaque, target_phys_addr_t addr,
+            uint64_t val64, unsigned int size)
 {
     struct timerblock *t = opaque;
     struct xlx_timer *xt;
     unsigned int timer;
+    uint32_t value = val64;
 
     addr >>= 2;
     timer = timer_from_addr(addr);
@@ -166,14 +170,14 @@ timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     timer_update_irq(t);
 }
 
-static CPUReadMemoryFunc * const timer_read[] = {
-    NULL, NULL,
-    &timer_readl,
-};
-
-static CPUWriteMemoryFunc * const timer_write[] = {
-    NULL, NULL,
-    &timer_writel,
+static const MemoryRegionOps timer_ops = {
+    .read = timer_read,
+    .write = timer_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4
+    }
 };
 
 static void timer_hit(void *opaque)
@@ -192,7 +196,6 @@ static int xilinx_timer_init(SysBusDevice *dev)
 {
     struct timerblock *t = FROM_SYSBUS(typeof (*t), dev);
     unsigned int i;
-    int timer_regs;
 
     /* All timers share a single irq line.  */
     sysbus_init_irq(dev, &t->irq);
@@ -209,9 +212,9 @@ static int xilinx_timer_init(SysBusDevice *dev)
         ptimer_set_freq(xt->ptimer, t->freq_hz);
     }
 
-    timer_regs = cpu_register_io_memory(timer_read, timer_write, t,
-                                        DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, R_MAX * 4 * t->nr_timers, timer_regs);
+    memory_region_init_io(&t->mmio, &timer_ops, t, "xilinx-timer",
+                          R_MAX * 4 * t->nr_timers);
+    sysbus_init_mmio_region(dev, &t->mmio);
     return 0;
 }
 
diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c
index 467a26cc9e..ceb7b4d9ed 100644
--- a/hw/xilinx_uartlite.c
+++ b/hw/xilinx_uartlite.c
@@ -49,6 +49,7 @@
 struct xlx_uartlite
 {
     SysBusDevice busdev;
+    MemoryRegion mmio;
     CharDriverState *chr;
     qemu_irq irq;
 
@@ -82,7 +83,8 @@ static void uart_update_status(struct xlx_uartlite *s)
     s->regs[R_STATUS] = r;
 }
 
-static uint32_t uart_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t
+uart_read(void *opaque, target_phys_addr_t addr, unsigned int size)
 {
     struct xlx_uartlite *s = opaque;
     uint32_t r = 0;
@@ -107,9 +109,11 @@ static uint32_t uart_readl (void *opaque, target_phys_addr_t addr)
 }
 
 static void
-uart_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+uart_write(void *opaque, target_phys_addr_t addr,
+           uint64_t val64, unsigned int size)
 {
     struct xlx_uartlite *s = opaque;
+    uint32_t value = val64;
     unsigned char ch = value;
 
     addr >>= 2;
@@ -147,16 +151,14 @@ uart_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     uart_update_irq(s);
 }
 
-static CPUReadMemoryFunc * const uart_read[] = {
-    &uart_readl,
-    &uart_readl,
-    &uart_readl,
-};
-
-static CPUWriteMemoryFunc * const uart_write[] = {
-    &uart_writel,
-    &uart_writel,
-    &uart_writel,
+static const MemoryRegionOps uart_ops = {
+    .read = uart_read,
+    .write = uart_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 4
+    }
 };
 
 static void uart_rx(void *opaque, const uint8_t *buf, int size)
@@ -196,14 +198,12 @@ static void uart_event(void *opaque, int event)
 static int xilinx_uartlite_init(SysBusDevice *dev)
 {
     struct xlx_uartlite *s = FROM_SYSBUS(typeof (*s), dev);
-    int uart_regs;
 
     sysbus_init_irq(dev, &s->irq);
 
     uart_update_status(s);
-    uart_regs = cpu_register_io_memory(uart_read, uart_write, s,
-                                       DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, R_MAX * 4, uart_regs);
+    memory_region_init_io(&s->mmio, &uart_ops, s, "xilinx-uartlite", R_MAX * 4);
+    sysbus_init_mmio_region(dev, &s->mmio);
 
     s->chr = qdev_init_chardev(&dev->qdev);
     if (s->chr)
diff --git a/hw/z2.c b/hw/z2.c
index d7b8d5327b..f93a1bf0fe 100644
--- a/hw/z2.c
+++ b/hw/z2.c
@@ -280,11 +280,10 @@ static void z2_init(ram_addr_t ram_size,
     uint32_t sector_len = 0x10000;
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    const MemoryRegionOps *flash_ops;
+    int be;
     void *z2_lcd;
     i2c_bus *bus;
     DeviceState *wm;
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     if (!cpu_model) {
         cpu_model = "pxa270-c5";
@@ -294,9 +293,9 @@ static void z2_init(ram_addr_t ram_size,
     cpu = pxa270_init(z2_binfo.ram_size, cpu_model);
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    flash_ops = &pflash_cfi01_ops_be;
+    be = 1;
 #else
-    flash_ops = &pflash_cfi01_ops_le;
+    be = 0;
 #endif
     dinfo = drive_get(IF_PFLASH, 0, 0);
     if (!dinfo) {
@@ -305,11 +304,11 @@ static void z2_init(ram_addr_t ram_size,
         exit(1);
     }
 
-    memory_region_init_rom_device(flash, flash_ops,
-                                  NULL, "z2.flash0", Z2_FLASH_SIZE);
-    if (!pflash_cfi01_register(Z2_FLASH_BASE, flash,
+    if (!pflash_cfi01_register(Z2_FLASH_BASE,
+                               qemu_ram_alloc(NULL, "z2.flash0", Z2_FLASH_SIZE),
                                dinfo->bdrv, sector_len,
-                               Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0)) {
+                               Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0,
+                               be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
     }
diff --git a/hw/zaurus.c b/hw/zaurus.c
index c24aeb5763..0eeacf7cb3 100644
--- a/hw/zaurus.c
+++ b/hw/zaurus.c
@@ -246,7 +246,7 @@ device_init(scoop_register);
 
 #define MAGIC_CHG(a, b, c, d)	((d << 24) | (c << 16) | (b << 8) | a)
 
-static struct __attribute__ ((__packed__)) sl_param_info {
+static struct QEMU_PACKED sl_param_info {
     uint32_t comadj_keyword;
     int32_t comadj;