Patchwork [16/24] pflash_cfi01/pflash_cfi02: convert to memory API

login
register
mail settings
Submitter Avi Kivity
Date Aug. 24, 2011, 10:11 a.m.
Message ID <1314180683-8227-17-git-send-email-avi@redhat.com>
Download mbox | patch
Permalink /patch/111293/
State New
Headers show

Comments

Avi Kivity - Aug. 24, 2011, 10:11 a.m.
cfi02 is annoying in that is ignores some address bits; we probably
want explicit support in the memory API for that.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/collie.c                   |   17 ++++---
 hw/flash.h                    |   16 +++++--
 hw/gumstix.c                  |   29 +++++++-----
 hw/lm32_boards.c              |   15 ++++---
 hw/mainstone.c                |   21 +++++----
 hw/milkymist.c                |    8 ++-
 hw/mips_malta.c               |   44 ++++++++++---------
 hw/mips_r4k.c                 |   19 +++++---
 hw/musicpal.c                 |   16 ++++---
 hw/omap_sx1.c                 |   22 ++++++----
 hw/petalogix_ml605_mmu.c      |    8 ++-
 hw/petalogix_s3adsp1800_mmu.c |    9 +++-
 hw/pflash_cfi01.c             |   67 ++++++++++-------------------
 hw/pflash_cfi02.c             |   95 ++++++++++++++++++++---------------------
 hw/ppc405_boards.c            |   61 ++++++++++++++------------
 hw/r2d.c                      |    8 +++-
 hw/virtex_ml507.c             |    8 ++-
 hw/z2.c                       |   16 ++++---
 18 files changed, 256 insertions(+), 223 deletions(-)

Patch

diff --git a/hw/collie.c b/hw/collie.c
index 9b724aa..6f30d24 100644
--- a/hw/collie.c
+++ b/hw/collie.c
@@ -5,6 +5,7 @@ 
  *
  * This code is licensed under GNU GPL v2.
  */
+#include <glib.h>
 #include "hw.h"
 #include "sysbus.h"
 #include "boards.h"
@@ -28,7 +29,7 @@  static void collie_init(MemoryRegion *address_space_mem,
 {
     StrongARMState *s;
     DriveInfo *dinfo;
-    ram_addr_t phys_flash;
+    MemoryRegion *phys_flash = g_new(MemoryRegion, 2);
 
     if (!cpu_model) {
         cpu_model = "sa1110";
@@ -36,17 +37,19 @@  static void collie_init(MemoryRegion *address_space_mem,
 
     s = sa1110_init(collie_binfo.ram_size, cpu_model);
 
-    phys_flash = qemu_ram_alloc(NULL, "collie.fl1", 0x02000000);
+    memory_region_init_rom_device(&phys_flash[0], &pflash_cfi01_ops_le,
+                                  NULL, "collie.fl1", 0x02000000);
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    pflash_cfi01_register(SA_CS0, phys_flash,
+    pflash_cfi01_register(SA_CS0, &phys_flash[0],
                     dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-                    512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+                    512, 4, 0x00, 0x00, 0x00, 0x00);
 
-    phys_flash = qemu_ram_alloc(NULL, "collie.fl2", 0x02000000);
+    memory_region_init_rom_device(&phys_flash[1], &pflash_cfi01_ops_le,
+                                  NULL, "collie.fl2", 0x02000000);
     dinfo = drive_get(IF_PFLASH, 0, 1);
-    pflash_cfi01_register(SA_CS1, phys_flash,
+    pflash_cfi01_register(SA_CS1, &phys_flash[1],
                     dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-                    512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+                    512, 4, 0x00, 0x00, 0x00, 0x00);
 
     sysbus_create_simple("scoop", 0x40800000, NULL);
 
diff --git a/hw/flash.h b/hw/flash.h
index 140ae39..7fb012b 100644
--- a/hw/flash.h
+++ b/hw/flash.h
@@ -1,21 +1,27 @@ 
+#include "memory.h"
+
 /* NOR flash devices */
 typedef struct pflash_t pflash_t;
 
 /* pflash_cfi01.c */
-pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
+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,
                                 BlockDriverState *bs,
                                 uint32_t sector_len, int nb_blocs, int width,
                                 uint16_t id0, uint16_t id1,
-                                uint16_t id2, uint16_t id3, int be);
+                                uint16_t id2, uint16_t id3);
 
 /* pflash_cfi02.c */
-pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
+pflash_t *pflash_cfi02_register(target_phys_addr_t base, MemoryRegion *mem,
                                 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,
-                                int be);
+                                uint16_t unlock_addr0, uint16_t unlock_addr1);
 
 /* nand.c */
 DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id);
diff --git a/hw/gumstix.c b/hw/gumstix.c
index ccdd834..620bdd7 100644
--- a/hw/gumstix.c
+++ b/hw/gumstix.c
@@ -31,6 +31,7 @@ 
  * # qemu-system-arm -M verdex -pflash flash -monitor null -nographic -m 289
  */
 
+#include <glib.h>
 #include "hw.h"
 #include "pxa.h"
 #include "net.h"
@@ -50,7 +51,8 @@  static void connex_init(MemoryRegion *address_space_mem,
 {
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    int be;
+    const MemoryRegionOps *flash_ops;
+    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     uint32_t connex_rom = 0x01000000;
     uint32_t connex_ram = 0x04000000;
@@ -65,14 +67,15 @@  static void connex_init(MemoryRegion *address_space_mem,
     }
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
+    flash_ops = &pflash_cfi01_ops_be;
 #else
-    be = 0;
+    flash_ops = &pflash_cfi01_ops_le;
 #endif
-    if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "connext.rom",
-                                                          connex_rom),
+    memory_region_init_rom_device(flash, flash_ops,
+                                  NULL, "connext.rom", connex_rom);
+    if (!pflash_cfi01_register(0x00000000, flash,
                                dinfo->bdrv, sector_len, connex_rom / sector_len,
-                               2, 0, 0, 0, 0, be)) {
+                               2, 0, 0, 0, 0)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
     }
@@ -91,7 +94,8 @@  static void verdex_init(MemoryRegion *address_space_mem,
 {
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    int be;
+    MemoryRegion *flash = g_new(MemoryRegion, 1);
+    const MemoryRegionOps *flash_ops;
 
     uint32_t verdex_rom = 0x02000000;
     uint32_t verdex_ram = 0x10000000;
@@ -106,14 +110,15 @@  static void verdex_init(MemoryRegion *address_space_mem,
     }
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
+    flash_ops = &pflash_cfi01_ops_be;
 #else
-    be = 0;
+    flash_ops = &pflash_cfi01_ops_le;
 #endif
-    if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "verdex.rom",
-                                                          verdex_rom),
+    memory_region_init_rom_device(flash, flash_ops,
+                                  NULL, "verdex.rom", verdex_rom);
+    if (!pflash_cfi01_register(0x00000000, flash,
                                dinfo->bdrv, sector_len, verdex_rom / sector_len,
-                               2, 0, 0, 0, 0, be)) {
+                               2, 0, 0, 0, 0)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
     }
diff --git a/hw/lm32_boards.c b/hw/lm32_boards.c
index fced5d1..3c6b5af 100644
--- a/hw/lm32_boards.c
+++ b/hw/lm32_boards.c
@@ -17,6 +17,7 @@ 
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <glib.h>
 #include "sysbus.h"
 #include "hw.h"
 #include "net.h"
@@ -79,7 +80,7 @@  static void lm32_evr_init(MemoryRegion *address_space_mem,
     CPUState *env;
     DriveInfo *dinfo;
     ram_addr_t phys_ram;
-    ram_addr_t phys_flash;
+    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
     qemu_irq *cpu_irq, irq[32];
     ResetInfo *reset_info;
     int i;
@@ -110,13 +111,14 @@  static void lm32_evr_init(MemoryRegion *address_space_mem,
     phys_ram = qemu_ram_alloc(NULL, "lm32_evr.sdram", ram_size);
     cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "lm32_evr.flash", flash_size);
+    memory_region_init_rom_device(phys_flash, &pflash_cfi02_ops_be,
+                                  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, 1);
+                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
@@ -169,7 +171,7 @@  static void lm32_uclinux_init(MemoryRegion *address_space_mem,
     CPUState *env;
     DriveInfo *dinfo;
     ram_addr_t phys_ram;
-    ram_addr_t phys_flash;
+    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
     qemu_irq *cpu_irq, irq[32];
     HWSetup *hw;
     ResetInfo *reset_info;
@@ -207,13 +209,14 @@  static void lm32_uclinux_init(MemoryRegion *address_space_mem,
     phys_ram = qemu_ram_alloc(NULL, "lm32_uclinux.sdram", ram_size);
     cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "lm32_uclinux.flash", flash_size);
+    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
+                                  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, 1);
+                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
diff --git a/hw/mainstone.c b/hw/mainstone.c
index 227f6f8..cb62abb 100644
--- a/hw/mainstone.c
+++ b/hw/mainstone.c
@@ -8,6 +8,7 @@ 
  *
  * This code is licensed under the GNU GPL v2.
  */
+#include <glib.h>
 #include "hw.h"
 #include "pxa.h"
 #include "arm-misc.h"
@@ -101,7 +102,8 @@  static void mainstone_common_init(ram_addr_t ram_size,
     DeviceState *mst_irq;
     DriveInfo *dinfo;
     int i;
-    int be;
+    MemoryRegion *flashes = g_new(MemoryRegion, 2);
+    const MemoryRegionOps *flash_ops;
 
     if (!cpu_model)
         cpu_model = "pxa270-c5";
@@ -113,9 +115,9 @@  static void mainstone_common_init(ram_addr_t ram_size,
                                    MAINSTONE_ROM) | IO_MEM_ROM);
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
+    flash_ops = &pflash_cfi01_ops_be;
 #else
-    be = 0;
+    flash_ops = &pflash_cfi01_ops_le;
 #endif
     /* There are two 32MiB flash devices on the board */
     for (i = 0; i < 2; i ++) {
@@ -126,13 +128,14 @@  static void mainstone_common_init(ram_addr_t ram_size,
             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],
-                                   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)) {
+                                   &flashes[i], dinfo->bdrv, sector_len,
+                                   MAINSTONE_FLASH / sector_len, 4, 0, 0, 0,
+                                   0)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
             exit(1);
         }
diff --git a/hw/milkymist.c b/hw/milkymist.c
index e599917..74994a7 100644
--- a/hw/milkymist.c
+++ b/hw/milkymist.c
@@ -17,6 +17,7 @@ 
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <glib.h>
 #include "sysbus.h"
 #include "hw.h"
 #include "net.h"
@@ -85,7 +86,7 @@  milkymist_init(MemoryRegion *address_space_mem,
     int kernel_size;
     DriveInfo *dinfo;
     ram_addr_t phys_sdram;
-    ram_addr_t phys_flash;
+    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
     qemu_irq irq[32], *cpu_irq;
     int i;
     char *bios_filename;
@@ -116,13 +117,14 @@  milkymist_init(MemoryRegion *address_space_mem,
     cpu_register_physical_memory(sdram_base, sdram_size,
             phys_sdram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "milkymist.flash", flash_size);
+    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
+                                  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, 1);
+                          0x00, 0x89, 0x00, 0x1d);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index ceb6254..c57bcab 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -22,6 +22,7 @@ 
  * THE SOFTWARE.
  */
 
+#include <glib.h>
 #include "hw.h"
 #include "pc.h"
 #include "fdc.h"
@@ -764,7 +765,9 @@  void mips_malta_init (MemoryRegion *address_space_mem,
 {
     char *filename;
     ram_addr_t ram_offset;
-    ram_addr_t bios_offset;
+    MemoryRegion *bios = g_new(MemoryRegion, 1);
+    MemoryRegion *bios_1e0 = g_new(MemoryRegion, 1);
+    MemoryRegion *bios_1fc = g_new(MemoryRegion, 1);
     target_long bios_size;
     int64_t kernel_entry;
     PCIBus *pci_bus;
@@ -779,7 +782,7 @@  void mips_malta_init (MemoryRegion *address_space_mem,
     DriveInfo *fd[MAX_FD];
     int fl_idx = 0;
     int fl_sectors = 0;
-    int be;
+    const MemoryRegionOps *bios_ops;
 
     /* Make sure the first 3 serial ports are associated with a device. */
     for(i = 0; i < 3; i++) {
@@ -812,23 +815,24 @@  void mips_malta_init (MemoryRegion *address_space_mem,
                 ((unsigned int)ram_size / (1 << 20)));
         exit(1);
     }
-    ram_offset = qemu_ram_alloc(NULL, "mips_malta.ram", ram_size);
-    bios_offset = qemu_ram_alloc(NULL, "mips_malta.bios", BIOS_SIZE);
+#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);
 
     cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
 
     /* Map the bios at two physical locations, as on the real board. */
-    cpu_register_physical_memory(0x1e000000LL,
-                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
-    cpu_register_physical_memory(0x1fc00000LL,
-                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
+    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);
 
-#ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
-#else
-    be = 0;
-#endif
     /* FPGA */
     malta_fpga_init(0x1f000000LL, env->irq[2], serial_hds[2]);
 
@@ -840,7 +844,7 @@  void mips_malta_init (MemoryRegion *address_space_mem,
         loaderparams.kernel_cmdline = kernel_cmdline;
         loaderparams.initrd_filename = initrd_filename;
         kernel_entry = load_kernel();
-        write_bootloader(env, qemu_get_ram_ptr(bios_offset), kernel_entry);
+        write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
     } else {
         dinfo = drive_get(IF_PFLASH, 0, fl_idx);
         if (dinfo) {
@@ -849,13 +853,13 @@  void mips_malta_init (MemoryRegion *address_space_mem,
             fl_sectors = bios_size >> 16;
 #ifdef DEBUG_BOARD_INIT
             printf("Register parallel flash %d size " TARGET_FMT_lx " at "
-                   "offset %08lx addr %08llx '%s' %x\n",
-                   fl_idx, bios_size, bios_offset, 0x1e000000LL,
+                   "addr %08llx '%s' %x\n",
+                   fl_idx, bios_size, 0x1e000000LL,
                    bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-            pflash_cfi01_register(0x1e000000LL, bios_offset,
+            pflash_cfi01_register(0x1e000000LL, bios,
                                   dinfo->bdrv, 65536, fl_sectors,
-                                  4, 0x0000, 0x0000, 0x0000, 0x0000, be);
+                                  4, 0x0000, 0x0000, 0x0000, 0x0000);
             fl_idx++;
         } else {
             /* Load a BIOS image. */
@@ -880,7 +884,7 @@  void mips_malta_init (MemoryRegion *address_space_mem,
            a neat trick which allows bi-endian firmware. */
 #ifndef TARGET_WORDS_BIGENDIAN
         {
-            uint32_t *addr = qemu_get_ram_ptr(bios_offset);;
+            uint32_t *addr = memory_region_get_ram_ptr(bios);
             uint32_t *end = addr + bios_size;
             while (addr < end) {
                 bswap32s(addr);
@@ -892,7 +896,7 @@  void mips_malta_init (MemoryRegion *address_space_mem,
     /* Board ID = 0x420 (Malta Board with CoreLV)
        XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
        map to the board ID. */
-    stl_p(qemu_get_ram_ptr(bios_offset) + 0x10, 0x00000420);
+    stl_p(memory_region_get_ram_ptr(bios) + 0x10, 0x00000420);
 
     /* Init internal devices */
     cpu_mips_irq_init_cpu(env);
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 7a07bcd..8eec51d 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -7,6 +7,7 @@ 
  * All peripherial devices are attached to this "bus" with
  * the standard PC ISA addresses.
 */
+#include <glib.h>
 #include "hw.h"
 #include "mips.h"
 #include "mips_cpudevs.h"
@@ -165,7 +166,7 @@  void mips_r4k_init (MemoryRegion *address_space_mem,
 {
     char *filename;
     ram_addr_t ram_offset;
-    ram_addr_t bios_offset;
+    MemoryRegion *bios = g_new(MemoryRegion, 1);
     int bios_size;
     CPUState *env;
     ResetData *reset_info;
@@ -229,18 +230,20 @@  void mips_r4k_init (MemoryRegion *address_space_mem,
     be = 0;
 #endif
     if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) {
-        bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", BIOS_SIZE);
-	cpu_register_physical_memory(0x1fc00000, BIOS_SIZE,
-                                     bios_offset | IO_MEM_ROM);
-
+        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);
         load_image_targphys(filename, 0x1fc00000, BIOS_SIZE);
     } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
         uint32_t mips_rom = 0x00400000;
-        bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", mips_rom);
-        if (!pflash_cfi01_register(0x1fc00000, bios_offset,
+        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,
                                    dinfo->bdrv, sector_len,
                                    mips_rom / sector_len,
-                                   4, 0, 0, 0, 0, be)) {
+                                   4, 0, 0, 0, 0)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
 	}
     }
diff --git a/hw/musicpal.c b/hw/musicpal.c
index becd579..fd697bd 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -6,6 +6,7 @@ 
  * This code is licensed under the GNU GPL v2.
  */
 
+#include <glib.h>
 #include "sysbus.h"
 #include "arm-misc.h"
 #include "devices.h"
@@ -1504,6 +1505,7 @@  static void musicpal_init(MemoryRegion *address_space_mem,
     unsigned long flash_size;
     DriveInfo *dinfo;
     ram_addr_t sram_off;
+    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     if (!cpu_model) {
         cpu_model = "arm926";
@@ -1567,21 +1569,23 @@  static void musicpal_init(MemoryRegion *address_space_mem,
          * image is smaller than 32 MB.
          */
 #ifdef TARGET_WORDS_BIGENDIAN
-        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL,
-                              "musicpal.flash", flash_size),
+        memory_region_init_rom_device(flash, &pflash_cfi02_ops_be,
+                                      NULL, "musicpal.flash", flash_size);
+        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, flash,
                               dinfo->bdrv, 0x10000,
                               (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
-                              0x5555, 0x2AAA, 1);
+                              0x5555, 0x2AAA);
 #else
-        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL,
-                              "musicpal.flash", flash_size),
+        memory_region_init_rom_device(flash, &pflash_cfi02_ops_le,
+                                      NULL, "musicpal.flash", flash_size);
+        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, flash,
                               dinfo->bdrv, 0x10000,
                               (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
-                              0x5555, 0x2AAA, 0);
+                              0x5555, 0x2AAA);
 #endif
 
     }
diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c
index e1cceec..35f5b79 100644
--- a/hw/omap_sx1.c
+++ b/hw/omap_sx1.c
@@ -25,6 +25,7 @@ 
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
+#include <glib.h>
 #include "hw.h"
 #include "console.h"
 #include "omap.h"
@@ -129,7 +130,8 @@  static void sx1_init(ram_addr_t ram_size,
     DriveInfo *dinfo;
     int fl_idx;
     uint32_t flash_size = flash0_size;
-    int be;
+    const MemoryRegionOps *flash_ops;
+    MemoryRegion *flash = g_new(MemoryRegion, 2);
 
     if (version == 2) {
         flash_size = flash2_size;
@@ -155,17 +157,18 @@  static void sx1_init(ram_addr_t ram_size,
 
     fl_idx = 0;
 #ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
+    flash_ops = &pflash_cfi01_ops_be;
 #else
-    be = 0;
+    flash_ops = &pflash_cfi01_ops_le;
 #endif
 
     if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
-        if (!pflash_cfi01_register(OMAP_CS0_BASE, qemu_ram_alloc(NULL,
-                                   "omap_sx1.flash0-1", flash_size),
+        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],
                                    dinfo->bdrv, sector_size,
                                    flash_size / sector_size,
-                                   4, 0, 0, 0, 0, be)) {
+                                   4, 0, 0, 0, 0)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                            fl_idx);
         }
@@ -182,11 +185,12 @@  static void sx1_init(ram_addr_t ram_size,
         cpu_register_physical_memory(OMAP_CS1_BASE + flash1_size,
                         OMAP_CS1_SIZE - flash1_size, io);
 
-        if (!pflash_cfi01_register(OMAP_CS1_BASE, qemu_ram_alloc(NULL,
-                                   "omap_sx1.flash1-1", flash1_size),
+        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],
                                    dinfo->bdrv, sector_size,
                                    flash1_size / sector_size,
-                                   4, 0, 0, 0, 0, be)) {
+                                   4, 0, 0, 0, 0)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                            fl_idx);
         }
diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
index b0758ea..c76d229 100644
--- a/hw/petalogix_ml605_mmu.c
+++ b/hw/petalogix_ml605_mmu.c
@@ -25,6 +25,7 @@ 
  * THE SOFTWARE.
  */
 
+#include <glib.h>
 #include "sysbus.h"
 #include "hw.h"
 #include "net.h"
@@ -150,7 +151,7 @@  petalogix_ml605_init(MemoryRegion *address_space_mem,
     target_phys_addr_t ddr_base = MEMORY_BASEADDR;
     ram_addr_t phys_lmb_bram;
     ram_addr_t phys_ram;
-    ram_addr_t phys_flash;
+    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
     qemu_irq irq[32], *cpu_irq;
 
     /* init CPUs */
@@ -170,14 +171,15 @@  petalogix_ml605_init(MemoryRegion *address_space_mem,
     phys_ram = qemu_ram_alloc(NULL, "petalogix_ml605.ram", ram_size);
     cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "petalogix_ml605.flash", FLASH_SIZE);
+    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_le,
+                                  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, 0);
+                          2, 0x89, 0x18, 0x0000, 0x0);
 
 
     cpu_irq = microblaze_pic_init_cpu(env);
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index b5d9f8a..aa29e57 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -23,6 +23,7 @@ 
  * THE SOFTWARE.
  */
 
+#include <glib.h>
 #include "sysbus.h"
 #include "hw.h"
 #include "net.h"
@@ -127,7 +128,7 @@  petalogix_s3adsp1800_init(MemoryRegion *address_space_mem,
     target_phys_addr_t ddr_base = 0x90000000;
     ram_addr_t phys_lmb_bram;
     ram_addr_t phys_ram;
-    ram_addr_t phys_flash;
+    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
     qemu_irq irq[32], *cpu_irq;
 
     /* init CPUs */
@@ -148,12 +149,14 @@  petalogix_s3adsp1800_init(MemoryRegion *address_space_mem,
     phys_ram = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.ram", ram_size);
     cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE);
+    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
+                                  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);
+                          1, 0x89, 0x18, 0x0000, 0x0);
 
     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 90e1301..2144c6a 100644
--- a/hw/pflash_cfi01.c
+++ b/hw/pflash_cfi01.c
@@ -40,6 +40,7 @@ 
 #include "flash.h"
 #include "block.h"
 #include "qemu-timer.h"
+#include "exec-memory.h"
 
 #define PFLASH_BUG(fmt, ...) \
 do { \
@@ -74,8 +75,7 @@  struct pflash_t {
     target_phys_addr_t counter;
     unsigned int writeblock_size;
     QEMUTimer *timer;
-    ram_addr_t off;
-    int fl_mem;
+    MemoryRegion *mem;
     void *storage;
 };
 
@@ -89,8 +89,7 @@  static void pflash_timer (void *opaque)
     if (pfl->bypass) {
         pfl->wcycle = 2;
     } else {
-        cpu_register_physical_memory(pfl->base, pfl->total_len,
-                        pfl->off | IO_MEM_ROMD | pfl->fl_mem);
+        memory_region_rom_device_set_readable(pfl->mem, true);
         pfl->wcycle = 0;
     }
     pfl->cmd = 0;
@@ -263,7 +262,7 @@  static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
 
     if (!pfl->wcycle) {
         /* Set the device in I/O access mode */
-        cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem);
+        memory_region_rom_device_set_readable(pfl->mem, false);
     }
 
     switch (pfl->wcycle) {
@@ -422,8 +421,7 @@  static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
            __func__, offset, pfl->wcycle, pfl->cmd, value);
 
  reset_flash:
-    cpu_register_physical_memory(pfl->base, pfl->total_len,
-                    pfl->off | IO_MEM_ROMD | pfl->fl_mem);
+    memory_region_rom_device_set_readable(pfl->mem, true);
 
     pfl->bypass = 0;
     pfl->wcycle = 0;
@@ -514,28 +512,20 @@  static void pflash_writel_le(void *opaque, target_phys_addr_t addr,
     pflash_write(pfl, addr, value, 4, 0);
 }
 
-static CPUWriteMemoryFunc * const pflash_write_ops_be[] = {
-    &pflash_writeb_be,
-    &pflash_writew_be,
-    &pflash_writel_be,
+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 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,
+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,
 };
 
 /* Count trailing zeroes of a 32 bits quantity */
@@ -574,12 +564,11 @@  static int ctz32 (uint32_t n)
     return ret;
 }
 
-pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
+pflash_t *pflash_cfi01_register(target_phys_addr_t base, MemoryRegion *mem,
                                 BlockDriverState *bs, uint32_t sector_len,
                                 int nb_blocs, int width,
                                 uint16_t id0, uint16_t id1,
-                                uint16_t id2, uint16_t id3,
-                                int be)
+                                uint16_t id2, uint16_t id3)
 {
     pflash_t *pfl;
     target_phys_addr_t total_len;
@@ -597,26 +586,16 @@  pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
     pfl = g_malloc0(sizeof(pflash_t));
 
     /* FIXME: Allocate ram ourselves.  */
-    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->storage = memory_region_get_ram_ptr(mem);
+    pfl->mem = mem;
+    memory_region_add_subregion(get_system_memory(), base, mem);
 
     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) {
-            cpu_unregister_io_memory(pfl->fl_mem);
+            memory_region_del_subregion(get_system_memory(), mem);
             g_free(pfl);
             return NULL;
         }
diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c
index ac5115e..5dca826 100644
--- a/hw/pflash_cfi02.c
+++ b/hw/pflash_cfi02.c
@@ -35,10 +35,13 @@ 
  * It does not implement multiple sectors erase
  */
 
+#include <glib.h>
+
 #include "hw.h"
 #include "flash.h"
 #include "qemu-timer.h"
 #include "block.h"
+#include "exec-memory.h"
 
 //#define PFLASH_DEBUG
 #ifdef PFLASH_DEBUG
@@ -69,25 +72,39 @@  struct pflash_t {
     uint8_t cfi_len;
     uint8_t cfi_table[0x52];
     QEMUTimer *timer;
-    ram_addr_t off;
-    int fl_mem;
+    /* 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;
     int rom_mode;
     int read_counter; /* used for lazy switch-back to rom mode */
     void *storage;
 };
 
-static void pflash_register_memory(pflash_t *pfl, int rom_mode)
+/*
+ * Set up replicated mappings of the same region.
+ */
+static void pflash_setup_mappings(pflash_t *pfl, MemoryRegion *mem)
 {
-    unsigned long phys_offset = pfl->fl_mem;
-    int i;
-
-    if (rom_mode)
-        phys_offset |= pfl->off | IO_MEM_ROMD;
-    pfl->rom_mode = rom_mode;
+    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]);
+    }
+}
 
-    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_register_memory(pflash_t *pfl, int rom_mode)
+{
+    memory_region_rom_device_set_readable(pfl->orig_mem, rom_mode);
 }
 
 static void pflash_timer (void *opaque)
@@ -538,28 +555,20 @@  static void pflash_writel_le(void *opaque, target_phys_addr_t addr,
     pflash_write(pfl, addr, value, 4, 0);
 }
 
-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_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_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,
+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,
 };
 
 /* Count trailing zeroes of a 32 bits quantity */
@@ -598,13 +607,12 @@  static int ctz32 (uint32_t n)
     return ret;
 }
 
-pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
+pflash_t *pflash_cfi02_register(target_phys_addr_t base, MemoryRegion *mem,
                                 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,
-                                int be)
+                                uint16_t unlock_addr0, uint16_t unlock_addr1)
 {
     pflash_t *pfl;
     int32_t chip_len;
@@ -619,31 +627,22 @@  pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
 #endif
     pfl = g_malloc0(sizeof(pflash_t));
     /* FIXME: Allocate ram ourselves.  */
-    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->storage = memory_region_get_ram_ptr(mem);
     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/ppc405_boards.c b/hw/ppc405_boards.c
index 90eb98e..9a8b888 100644
--- a/hw/ppc405_boards.c
+++ b/hw/ppc405_boards.c
@@ -21,6 +21,7 @@ 
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+#include <glib.h>
 #include "hw.h"
 #include "ppc.h"
 #include "ppc405.h"
@@ -183,7 +184,8 @@  static void ref405ep_init (MemoryRegion *address_space_mem,
     ppc4xx_bd_info_t bd;
     CPUPPCState *env;
     qemu_irq *pic;
-    ram_addr_t sram_offset, bios_offset, bdloc;
+    ram_addr_t sram_offset, bdloc;
+    MemoryRegion *bios = g_new(MemoryRegion, 1);
     MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
     target_phys_addr_t ram_bases[2], ram_sizes[2];
     target_ulong sram_size;
@@ -226,18 +228,18 @@  static void ref405ep_init (MemoryRegion *address_space_mem,
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
     if (dinfo) {
         bios_size = bdrv_getlength(dinfo->bdrv);
-        bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", bios_size);
+        memory_region_init_rom_device(bios, &pflash_cfi02_ops_be,
+                                      NULL, "ef405ep.bios", bios_size);
         fl_sectors = (bios_size + 65535) >> 16;
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at offset %08lx addr %lx '%s' %d\n",
-               fl_idx, bios_size, bios_offset, -bios_size,
+               " at addr %lx '%s' %d\n",
+               fl_idx, bios_size, -bios_size,
                bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-        pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
+        pflash_cfi02_register((uint32_t)(-bios_size), bios,
                               dinfo->bdrv, 65536, fl_sectors, 1,
-                              2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
-                              1);
+                              2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
         fl_idx++;
     } else
 #endif
@@ -245,12 +247,12 @@  static void ref405ep_init (MemoryRegion *address_space_mem,
 #ifdef DEBUG_BOARD_INIT
         printf("Load BIOS from file\n");
 #endif
-        bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", BIOS_SIZE);
+        memory_region_init_ram(bios, 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, qemu_get_ram_ptr(bios_offset));
+            bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
             g_free(filename);
         } else {
             bios_size = -1;
@@ -261,8 +263,9 @@  static void ref405ep_init (MemoryRegion *address_space_mem,
             exit(1);
         }
         bios_size = (bios_size + 0xfff) & ~0xfff;
-        cpu_register_physical_memory((uint32_t)(-bios_size),
-                                     bios_size, bios_offset | IO_MEM_ROM);
+        memory_region_set_readonly(bios, true);
+        memory_region_add_subregion(address_space_mem, (uint32_t)(-bios_size),
+                                    bios);
     }
     /* Register FPGA */
 #ifdef DEBUG_BOARD_INIT
@@ -511,7 +514,8 @@  static void taihu_405ep_init(MemoryRegion *address_space_mem,
 {
     char *filename;
     qemu_irq *pic;
-    ram_addr_t bios_offset;
+    MemoryRegion *bios = g_new(MemoryRegion, 1);
+    MemoryRegion *flash = g_new(MemoryRegion, 1);
     MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
     target_phys_addr_t ram_bases[2], ram_sizes[2];
     long bios_size;
@@ -548,17 +552,17 @@  static void taihu_405ep_init(MemoryRegion *address_space_mem,
         /* XXX: should check that size is 2MB */
         //        bios_size = 2 * 1024 * 1024;
         fl_sectors = (bios_size + 65535) >> 16;
-        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", bios_size);
+        memory_region_init_rom_device(bios, &pflash_cfi02_ops_be,
+                                      NULL, "taihu_405ep.bios", bios_size);
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at offset %08lx addr %lx '%s' %d\n",
-               fl_idx, bios_size, bios_offset, -bios_size,
+               " at addr %lx '%s' %d\n",
+               fl_idx, bios_size, -bios_size,
                bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-        pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
+        pflash_cfi02_register((uint32_t)(-bios_size), bios,
                               dinfo->bdrv, 65536, fl_sectors, 1,
-                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
-                              1);
+                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
         fl_idx++;
     } else
 #endif
@@ -568,10 +572,10 @@  static void taihu_405ep_init(MemoryRegion *address_space_mem,
 #endif
         if (bios_name == NULL)
             bios_name = BIOS_FILENAME;
-        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", BIOS_SIZE);
+        memory_region_init_ram(bios, NULL, "taihu_405ep.bios", BIOS_SIZE);
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (filename) {
-            bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset));
+            bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
             g_free(filename);
         } else {
             bios_size = -1;
@@ -582,8 +586,9 @@  static void taihu_405ep_init(MemoryRegion *address_space_mem,
             exit(1);
         }
         bios_size = (bios_size + 0xfff) & ~0xfff;
-        cpu_register_physical_memory((uint32_t)(-bios_size),
-                                     bios_size, bios_offset | IO_MEM_ROM);
+        memory_region_set_readonly(bios, true);
+        memory_region_add_subregion(address_space_mem,
+                                    (uint32_t)(-bios_size), bios);
     }
     /* Register Linux flash */
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
@@ -594,15 +599,15 @@  static void taihu_405ep_init(MemoryRegion *address_space_mem,
         fl_sectors = (bios_size + 65535) >> 16;
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at offset %08lx  addr " TARGET_FMT_lx " '%s'\n",
-               fl_idx, bios_size, bios_offset, (target_ulong)0xfc000000,
+               " at addr " TARGET_FMT_lx " '%s'\n",
+               fl_idx, bios_size, (target_ulong)0xfc000000,
                bdrv_get_device_name(dinfo->bdrv));
 #endif
-        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.flash", bios_size);
-        pflash_cfi02_register(0xfc000000, bios_offset,
+        memory_region_init_rom_device(flash, &pflash_cfi02_ops_be,
+                                      NULL, "taihu_405ep.flash", bios_size);
+        pflash_cfi02_register(0xfc000000, flash,
                               dinfo->bdrv, 65536, fl_sectors, 1,
-                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
-                              1);
+                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
         fl_idx++;
     }
     /* Register CLPD & LCD display */
diff --git a/hw/r2d.c b/hw/r2d.c
index 923fd4e..5bd5633 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -23,6 +23,7 @@ 
  * THE SOFTWARE.
  */
 
+#include <glib.h>
 #include "sysbus.h"
 #include "hw.h"
 #include "sh.h"
@@ -237,6 +238,7 @@  static void r2d_init(MemoryRegion *address_space_mem,
     qemu_irq *irq;
     DriveInfo *dinfo;
     int i;
+    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     if (!cpu_model)
         cpu_model = "SH7751R";
@@ -269,11 +271,13 @@  static void r2d_init(MemoryRegion *address_space_mem,
 
     /* onboard flash memory */
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    pflash_cfi02_register(0x0, qemu_ram_alloc(NULL, "r2d.flash", FLASH_SIZE),
+    memory_region_init_rom_device(flash, &pflash_cfi02_ops_le,
+                                  NULL, "r2d.flash", FLASH_SIZE);
+    pflash_cfi02_register(0x0, flash,
                           dinfo ? dinfo->bdrv : NULL, (16 * 1024),
                           FLASH_SIZE >> 16,
                           1, 4, 0x0000, 0x0000, 0x0000, 0x0000,
-                          0x555, 0x2aa, 0);
+                          0x555, 0x2aa);
 
     /* NIC: rtl8139 on-board, and 2 slots. */
     for (i = 0; i < nb_nics; i++)
diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c
index 4503851..35982ff 100644
--- a/hw/virtex_ml507.c
+++ b/hw/virtex_ml507.c
@@ -22,6 +22,7 @@ 
  * THE SOFTWARE.
  */
 
+#include <glib.h>
 #include "sysbus.h"
 #include "hw.h"
 #include "pc.h"
@@ -198,7 +199,7 @@  static void virtex_init(MemoryRegion *address_space_mem,
     target_phys_addr_t ram_base = 0;
     DriveInfo *dinfo;
     ram_addr_t phys_ram;
-    ram_addr_t phys_flash;
+    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
     qemu_irq irq[32], *cpu_irq;
     clk_setup_t clk_setup[7];
     int kernel_size;
@@ -217,12 +218,13 @@  static void virtex_init(MemoryRegion *address_space_mem,
     phys_ram = qemu_ram_alloc(NULL, "ram", ram_size);
     cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "virtex.flash", FLASH_SIZE);
+    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
+                                  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);
+                          1, 0x89, 0x18, 0x0000, 0x0);
 
     cpu_irq = (qemu_irq *) &env->irq_inputs[PPC40x_INPUT_INT];
     dev = xilinx_intc_create(0x81800000, cpu_irq[0], 0);
diff --git a/hw/z2.c b/hw/z2.c
index f1db41b..a6a4761 100644
--- a/hw/z2.c
+++ b/hw/z2.c
@@ -8,6 +8,7 @@ 
  * This code is licensed under the GNU GPL v2.
  */
 
+#include <glib.h>
 #include "hw.h"
 #include "pxa.h"
 #include "arm-misc.h"
@@ -282,10 +283,11 @@  static void z2_init(MemoryRegion *address_space_mem,
     uint32_t sector_len = 0x10000;
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    int be;
+    const MemoryRegionOps *flash_ops;
     void *z2_lcd;
     i2c_bus *bus;
     DeviceState *wm;
+    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     if (!cpu_model) {
         cpu_model = "pxa270-c5";
@@ -295,9 +297,9 @@  static void z2_init(MemoryRegion *address_space_mem,
     cpu = pxa270_init(z2_binfo.ram_size, cpu_model);
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
+    flash_ops = &pflash_cfi01_ops_be;
 #else
-    be = 0;
+    flash_ops = &pflash_cfi01_ops_le;
 #endif
     dinfo = drive_get(IF_PFLASH, 0, 0);
     if (!dinfo) {
@@ -306,11 +308,11 @@  static void z2_init(MemoryRegion *address_space_mem,
         exit(1);
     }
 
-    if (!pflash_cfi01_register(Z2_FLASH_BASE,
-                               qemu_ram_alloc(NULL, "z2.flash0", Z2_FLASH_SIZE),
+    memory_region_init_rom_device(flash, flash_ops,
+                                  NULL, "z2.flash0", Z2_FLASH_SIZE);
+    if (!pflash_cfi01_register(Z2_FLASH_BASE, flash,
                                dinfo->bdrv, sector_len,
-                               Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0,
-                               be)) {
+                               Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
     }