diff mbox

[v3,04/39] vga: convert vga and its derivatives to the memory API

Message ID 1312463195-13605-5-git-send-email-avi@redhat.com
State New
Headers show

Commit Message

Avi Kivity Aug. 4, 2011, 1:06 p.m. UTC
Convert all vga memory to the memory API.  Note we need to fall back to
get_system_memory(), since the various buses don't pass the vga window
as a memory region.

We no longer need to sync the dirty bitmap of the cirrus mapped memory
banks, since the memory API takes care of that for us.

[jan: fix vga-pci logging]

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/cirrus_vga.c |  343 ++++++++++++++++++++++++++++++++----------------------
 hw/qxl-render.c |    2 +-
 hw/qxl.c        |  135 ++++++++--------------
 hw/qxl.h        |    6 +-
 hw/vga-isa-mm.c |   45 +++++---
 hw/vga-isa.c    |   11 +-
 hw/vga-pci.c    |   28 +----
 hw/vga.c        |  147 +++++++++++-------------
 hw/vga_int.h    |   14 +--
 hw/vmware_vga.c |  143 ++++++++++++-----------
 10 files changed, 440 insertions(+), 434 deletions(-)

Comments

Anthony Liguori Aug. 5, 2011, 2:02 p.m. UTC | #1
On 08/04/2011 08:06 AM, Avi Kivity wrote:
> Convert all vga memory to the memory API.  Note we need to fall back to
> get_system_memory(), since the various buses don't pass the vga window
> as a memory region.
>
> We no longer need to sync the dirty bitmap of the cirrus mapped memory
> banks, since the memory API takes care of that for us.
>
> [jan: fix vga-pci logging]
>
> Reviewed-by: Richard Henderson<rth@twiddle.net>
> Signed-off-by: Avi Kivity<avi@redhat.com>
> ---
>   hw/cirrus_vga.c |  343 ++++++++++++++++++++++++++++++++----------------------
>   hw/qxl-render.c |    2 +-
>   hw/qxl.c        |  135 ++++++++--------------
>   hw/qxl.h        |    6 +-
>   hw/vga-isa-mm.c |   45 +++++---
>   hw/vga-isa.c    |   11 +-
>   hw/vga-pci.c    |   28 +----
>   hw/vga.c        |  147 +++++++++++-------------
>   hw/vga_int.h    |   14 +--
>   hw/vmware_vga.c |  143 ++++++++++++-----------
>   10 files changed, 440 insertions(+), 434 deletions(-)
>
> diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
> index f39d1f8..d1475dd 100644
> --- a/hw/cirrus_vga.c
> +++ b/hw/cirrus_vga.c
> @@ -200,9 +200,14 @@ typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
>   typedef struct CirrusVGAState {
>       VGACommonState vga;
>
> -    int cirrus_linear_io_addr;
> -    int cirrus_linear_bitblt_io_addr;
> -    int cirrus_mmio_io_addr;
> +    MemoryRegion cirrus_linear_io;
> +    MemoryRegion cirrus_linear_bitblt_io;
> +    MemoryRegion cirrus_mmio_io;
> +    MemoryRegion pci_bar;
> +    bool linear_vram;  /* vga.vram mapped over cirrus_linear_io */
> +    MemoryRegion low_mem_container; /* container for 0xa0000-0xc0000 */
> +    MemoryRegion low_mem;           /* always mapped, overridden by: */
> +    MemoryRegion *cirrus_bank[2];   /*   aliases at 0xa0000-0xb0000  */
>       uint32_t cirrus_addr_mask;
>       uint32_t linear_mmio_mask;
>       uint8_t cirrus_shadow_gr0;
> @@ -612,7 +617,7 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
>   	off_cur_end = (off_cur + bytesperline)&  s->cirrus_addr_mask;
>   	off_cur&= TARGET_PAGE_MASK;
>   	while (off_cur<  off_cur_end) {
> -	    cpu_physical_memory_set_dirty(s->vga.vram_offset + off_cur);
> +	    memory_region_set_dirty(&s->vga.vram, off_cur);
>   	    off_cur += TARGET_PAGE_SIZE;
>   	}
>   	off_begin += off_pitch;
> @@ -1177,12 +1182,6 @@ static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
>       }
>
>       if (limit>  0) {
> -        /* Thinking about changing bank base? First, drop the dirty bitmap information
> -         * on the current location, otherwise we lose this pointer forever */
> -        if (s->vga.lfb_vram_mapped) {
> -            target_phys_addr_t base_addr = isa_mem_base + 0xa0000 + bank_index * 0x8000;
> -            cpu_physical_sync_dirty_bitmap(base_addr, base_addr + 0x8000);
> -        }
>   	s->cirrus_bank_base[bank_index] = offset;
>   	s->cirrus_bank_limit[bank_index] = limit;
>       } else {
> @@ -1921,8 +1920,8 @@ static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
>   	val<<= 1;
>   	dst++;
>       }
> -    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset);
> -    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 7);
> +    memory_region_set_dirty(&s->vga.vram, offset);
> +    memory_region_set_dirty(&s->vga.vram, offset + 7);
>   }
>
>   static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
> @@ -1946,8 +1945,8 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
>   	val<<= 1;
>   	dst += 2;
>       }
> -    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset);
> -    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 15);
> +    memory_region_set_dirty(&s->vga.vram, offset);
> +    memory_region_set_dirty(&s->vga.vram, offset + 15);
>   }
>
>   /***************************************
> @@ -2057,8 +2056,7 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
>   		mode = s->vga.gr[0x05]&  0x7;
>   		if (mode<  4 || mode>  5 || ((s->vga.gr[0x0B]&  0x4) == 0)) {
>   		    *(s->vga.vram_ptr + bank_offset) = mem_value;
> -		    cpu_physical_memory_set_dirty(s->vga.vram_offset +
> -						  bank_offset);
> +		    memory_region_set_dirty(&s->vga.vram, bank_offset);
>   		} else {
>   		    if ((s->vga.gr[0x0B]&  0x14) != 0x14) {
>   			cirrus_mem_writeb_mode4and5_8bpp(s, mode,
> @@ -2099,16 +2097,37 @@ static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_
>       cirrus_vga_mem_writeb(opaque, addr + 3, (val>>  24)&  0xff);
>   }
>
> -static CPUReadMemoryFunc * const cirrus_vga_mem_read[3] = {
> -    cirrus_vga_mem_readb,
> -    cirrus_vga_mem_readw,
> -    cirrus_vga_mem_readl,
> +static uint64_t cirrus_vga_mem_read(void *opaque,
> +                                    target_phys_addr_t addr,
> +                                    uint32_t size)
> +{
> +    CirrusVGAState *s = opaque;
> +
> +    switch (size) {
> +    case 1: return cirrus_vga_mem_readb(s, addr);
> +    case 2: return cirrus_vga_mem_readw(s, addr);
> +    case 4: return cirrus_vga_mem_readl(s, addr);
> +    default: abort();
> +    }
> +}
> +
> +static void cirrus_vga_mem_write(void *opaque, target_phys_addr_t addr,
> +                                 uint64_t data, unsigned size)
> +{
> +    CirrusVGAState *s = opaque;
> +
> +    switch (size) {
> +    case 1: return cirrus_vga_mem_writeb(s, addr, data);
> +    case 2: return cirrus_vga_mem_writew(s, addr, data);
> +    case 4: return cirrus_vga_mem_writel(s, addr, data);
> +    default: abort();
> +    }
>   };
>
> -static CPUWriteMemoryFunc * const cirrus_vga_mem_write[3] = {
> -    cirrus_vga_mem_writeb,
> -    cirrus_vga_mem_writew,
> -    cirrus_vga_mem_writel,
> +static const MemoryRegionOps cirrus_vga_mem_ops = {
> +    .read = cirrus_vga_mem_read,
> +    .write = cirrus_vga_mem_write,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
>   };

Any reason for not using old_mmio here?

>
>   /***************************************
> @@ -2365,7 +2384,7 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
>   	mode = s->vga.gr[0x05]&  0x7;
>   	if (mode<  4 || mode>  5 || ((s->vga.gr[0x0B]&  0x4) == 0)) {
>   	    *(s->vga.vram_ptr + addr) = (uint8_t) val;
> -	    cpu_physical_memory_set_dirty(s->vga.vram_offset + addr);
> +	    memory_region_set_dirty(&s->vga.vram, addr);
>   	} else {
>   	    if ((s->vga.gr[0x0B]&  0x14) != 0x14) {
>   		cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
> @@ -2393,17 +2412,31 @@ static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr,
>   }
>
>
> -static CPUReadMemoryFunc * const cirrus_linear_read[3] = {
> -    cirrus_linear_readb,
> -    cirrus_linear_readw,
> -    cirrus_linear_readl,
> -};
> +static uint64_t cirrus_linear_read(void *opaque, target_phys_addr_t addr,
> +                                   unsigned size)
> +{
> +    CirrusVGAState *s = opaque;
>
> -static CPUWriteMemoryFunc * const cirrus_linear_write[3] = {
> -    cirrus_linear_writeb,
> -    cirrus_linear_writew,
> -    cirrus_linear_writel,
> -};
> +    switch (size) {
> +    case 1: return cirrus_linear_readb(s, addr);
> +    case 2: return cirrus_linear_readw(s, addr);
> +    case 4: return cirrus_linear_readl(s, addr);
> +    default: abort();
> +    }
> +}
> +
> +static void cirrus_linear_write(void *opaque, target_phys_addr_t addr,
> +                                uint64_t data, unsigned size)
> +{
> +    CirrusVGAState *s = opaque;
> +
> +    switch (size) {
> +    case 1: return cirrus_linear_writeb(s, addr, data);
> +    case 2: return cirrus_linear_writew(s, addr, data);
> +    case 4: return cirrus_linear_writel(s, addr, data);
> +    default: abort();
> +    }
> +}
>
>   /***************************************
>    *
> @@ -2471,67 +2504,97 @@ static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr,
>       cirrus_linear_bitblt_writeb(opaque, addr + 3, (val>>  24)&  0xff);
>   }
>
> +static uint64_t cirrus_linear_bitblt_read(void *opaque,
> +                                          target_phys_addr_t addr,
> +                                          unsigned size)
> +{
> +    CirrusVGAState *s = opaque;
> +
> +    switch (size) {
> +    case 1: return cirrus_linear_bitblt_readb(s, addr);
> +    case 2: return cirrus_linear_bitblt_readw(s, addr);
> +    case 4: return cirrus_linear_bitblt_readl(s, addr);
> +    default: abort();
> +    }
> +};
> +
> +static void cirrus_linear_bitblt_write(void *opaque,
> +                                       target_phys_addr_t addr,
> +                                       uint64_t data,
> +                                       unsigned size)
> +{
> +    CirrusVGAState *s = opaque;
>
> -static CPUReadMemoryFunc * const cirrus_linear_bitblt_read[3] = {
> -    cirrus_linear_bitblt_readb,
> -    cirrus_linear_bitblt_readw,
> -    cirrus_linear_bitblt_readl,
> +    switch (size) {
> +    case 1: return cirrus_linear_bitblt_writeb(s, addr, data);
> +    case 2: return cirrus_linear_bitblt_writew(s, addr, data);
> +    case 4: return cirrus_linear_bitblt_writel(s, addr, data);
> +    default: abort();
> +    }
>   };
>
> -static CPUWriteMemoryFunc * const cirrus_linear_bitblt_write[3] = {
> -    cirrus_linear_bitblt_writeb,
> -    cirrus_linear_bitblt_writew,
> -    cirrus_linear_bitblt_writel,
> +static const MemoryRegionOps cirrus_linear_bitblt_io_ops = {
> +    .read = cirrus_linear_bitblt_read,
> +    .write = cirrus_linear_bitblt_write,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
>   };


Likewise, here.

>
> -static void map_linear_vram(CirrusVGAState *s)
> +#include "exec-memory.h"
> +

Please move this to the top of the file.

> +static void unmap_bank(CirrusVGAState *s, unsigned bank)
>   {
> -    if (!s->vga.map_addr&&  s->vga.lfb_addr&&  s->vga.lfb_end) {
> -        s->vga.map_addr = s->vga.lfb_addr;
> -        s->vga.map_end = s->vga.lfb_end;
> -        cpu_register_physical_memory_log(s->vga.map_addr,
> -					 s->vga.map_end - s->vga.map_addr,
> -					 s->vga.vram_offset, 0, true);
> +    if (s->cirrus_bank[bank]) {
> +        memory_region_del_subregion(&s->low_mem_container,
> +                                    s->cirrus_bank[bank]);
> +        memory_region_destroy(s->cirrus_bank[bank]);
> +        qemu_free(s->cirrus_bank[bank]);
> +        s->cirrus_bank[bank] = NULL;
>       }
> +}
>
> -    if (!s->vga.map_addr)
> -        return;
> -
> -    s->vga.lfb_vram_mapped = 0;
> +static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank)
> +{
> +    MemoryRegion *mr;
> +    static const char *names[] = { "vga.bank0", "vga.bank1" };
>
>       if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)
>           &&  !((s->vga.sr[0x07]&  0x01) == 0)
>           &&  !((s->vga.gr[0x0B]&  0x14) == 0x14)
>           &&  !(s->vga.gr[0x0B]&  0x02)) {
>
> -        cpu_register_physical_memory_log(isa_mem_base + 0xa0000, 0x8000,
> -					 (s->vga.vram_offset +
> -					  s->cirrus_bank_base[0]) |
> -					 IO_MEM_RAM, 0, true);
> -        cpu_register_physical_memory_log(isa_mem_base + 0xa8000, 0x8000,
> -					 (s->vga.vram_offset +
> -					  s->cirrus_bank_base[1]) |
> -					 IO_MEM_RAM, 0, true);
> -
> -        s->vga.lfb_vram_mapped = 1;
> -    }
> -    else {
> -        cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
> -                                     s->vga.vga_io_memory);
> +        mr = qemu_malloc(sizeof(*mr));
> +        memory_region_init_alias(mr, names[bank],&s->vga.vram,
> +                                 s->cirrus_bank_base[bank], 0x8000);
> +        memory_region_add_subregion_overlap(
> +&s->low_mem_container,
> +            0x8000 * bank,
> +            mr,
> +            1);
> +        unmap_bank(s, bank);
> +        s->cirrus_bank[bank] = mr;
> +    } else {
> +        unmap_bank(s, bank);
>       }
> +}
>
> -    vga_dirty_log_start(&s->vga);
> +static void map_linear_vram(CirrusVGAState *s)
> +{
> +    if (!s->linear_vram) {
> +        s->linear_vram = true;
> +        memory_region_add_subregion_overlap(&s->pci_bar, 0,&s->vga.vram, 1);
> +    }
> +    map_linear_vram_bank(s, 0);
> +    map_linear_vram_bank(s, 1);
>   }
>
>   static void unmap_linear_vram(CirrusVGAState *s)
>   {
> -    if (s->vga.map_addr&&  s->vga.lfb_addr&&  s->vga.lfb_end) {
> -        s->vga.map_addr = s->vga.map_end = 0;
> -         cpu_register_physical_memory(s->vga.lfb_addr, s->vga.vram_size,
> -                                      s->cirrus_linear_io_addr);
> +    if (s->linear_vram) {
> +        s->linear_vram = false;
> +        memory_region_del_subregion(&s->pci_bar,&s->vga.vram);
>       }
> -    cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
> -                                 s->vga.vga_io_memory);
> +    unmap_bank(s, 0);
> +    unmap_bank(s, 1);
>   }
>
>   /* Compute the memory access functions */
> @@ -2829,16 +2892,36 @@ static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr,
>   }
>
>
> -static CPUReadMemoryFunc * const cirrus_mmio_read[3] = {
> -    cirrus_mmio_readb,
> -    cirrus_mmio_readw,
> -    cirrus_mmio_readl,
> +static uint64_t cirrus_mmio_read(void *opaque, target_phys_addr_t addr,
> +                                 unsigned size)
> +{
> +    CirrusVGAState *s = opaque;
> +
> +    switch (size) {
> +    case 1: return cirrus_mmio_readb(s, addr);
> +    case 2: return cirrus_mmio_readw(s, addr);
> +    case 4: return cirrus_mmio_readl(s, addr);
> +    default: abort();
> +    }
>   };
>
> -static CPUWriteMemoryFunc * const cirrus_mmio_write[3] = {
> -    cirrus_mmio_writeb,
> -    cirrus_mmio_writew,
> -    cirrus_mmio_writel,
> +static void cirrus_mmio_write(void *opaque, target_phys_addr_t addr,
> +                              uint64_t data, unsigned size)
> +{
> +    CirrusVGAState *s = opaque;
> +
> +    switch (size) {
> +    case 1: return cirrus_mmio_writeb(s, addr, data);
> +    case 2: return cirrus_mmio_writew(s, addr, data);
> +    case 4: return cirrus_mmio_writel(s, addr, data);
> +    default: abort();
> +    }
> +};
> +
> +static const MemoryRegionOps cirrus_mmio_io_ops = {
> +    .read = cirrus_mmio_read,
> +    .write = cirrus_mmio_write,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
>   };
>
>   /* load/save state */
> @@ -2947,6 +3030,12 @@ static void cirrus_reset(void *opaque)
>       s->cirrus_hidden_dac_data = 0;
>   }
>
> +static const MemoryRegionOps cirrus_linear_io_ops = {
> +    .read = cirrus_linear_read,
> +    .write = cirrus_linear_write,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
> +};
> +

Some more opportunities for old_mmio.

>   static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
>   {
>       int i;
> @@ -2993,28 +3082,33 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
>       register_ioport_read(0x3ba, 1, 1, cirrus_vga_ioport_read, s);
>       register_ioport_read(0x3da, 1, 1, cirrus_vga_ioport_read, s);
>
> -    s->vga.vga_io_memory = cpu_register_io_memory(cirrus_vga_mem_read,
> -                                                  cirrus_vga_mem_write, s,
> -                                                  DEVICE_LITTLE_ENDIAN);
> -    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
> -                                 s->vga.vga_io_memory);
> -    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
> +    memory_region_init(&s->low_mem_container,
> +                       "cirrus-lowmem-container",
> +                       0x20000);
> +
> +    memory_region_init_io(&s->low_mem,&cirrus_vga_mem_ops, s,
> +                          "cirrus-low-memory", 0x20000);
> +    memory_region_add_subregion(&s->low_mem_container, 0,&s->low_mem);
> +    memory_region_add_subregion_overlap(get_system_memory(),
> +                                        isa_mem_base + 0x000a0000,
> +&s->low_mem_container,
> +                                        1);
> +    memory_region_set_coalescing(&s->low_mem);
>
>       /* I/O handler for LFB */
> -    s->cirrus_linear_io_addr =
> -        cpu_register_io_memory(cirrus_linear_read, cirrus_linear_write, s,
> -                               DEVICE_LITTLE_ENDIAN);
> +    memory_region_init_io(&s->cirrus_linear_io,&cirrus_linear_io_ops, s,
> +                          "cirrus-linear-io", VGA_RAM_SIZE);
>
>       /* I/O handler for LFB */
> -    s->cirrus_linear_bitblt_io_addr =
> -        cpu_register_io_memory(cirrus_linear_bitblt_read,
> -                               cirrus_linear_bitblt_write, s,
> -                               DEVICE_LITTLE_ENDIAN);
> +    memory_region_init_io(&s->cirrus_linear_bitblt_io,
> +&cirrus_linear_bitblt_io_ops,
> +                          s,
> +                          "cirrus-bitblt-mmio",
> +                          0x400000);
>
>       /* I/O handler for memory-mapped I/O */
> -    s->cirrus_mmio_io_addr =
> -        cpu_register_io_memory(cirrus_mmio_read, cirrus_mmio_write, s,
> -                               DEVICE_LITTLE_ENDIAN);
> +    memory_region_init_io(&s->cirrus_mmio_io,&cirrus_mmio_io_ops, s,
> +                          "cirrus-mmio", CIRRUS_PNPMMIO_SIZE);
>
>       s->real_vram_size =
>           (s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024;
> @@ -3060,42 +3154,6 @@ void isa_cirrus_vga_init(void)
>    *
>    ***************************************/
>
> -static void cirrus_pci_lfb_map(PCIDevice *d, int region_num,
> -			       pcibus_t addr, pcibus_t size, int type)
> -{
> -    CirrusVGAState *s =&DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga;
> -
> -    /* XXX: add byte swapping apertures */
> -    cpu_register_physical_memory(addr, s->vga.vram_size,
> -				 s->cirrus_linear_io_addr);
> -    cpu_register_physical_memory(addr + 0x1000000, 0x400000,
> -				 s->cirrus_linear_bitblt_io_addr);
> -
> -    s->vga.map_addr = s->vga.map_end = 0;
> -    s->vga.lfb_addr = addr&  TARGET_PAGE_MASK;
> -    s->vga.lfb_end = ((addr + VGA_RAM_SIZE) + TARGET_PAGE_SIZE - 1)&  TARGET_PAGE_MASK;
> -    /* account for overflow */
> -    if (s->vga.lfb_end<  addr + VGA_RAM_SIZE)
> -        s->vga.lfb_end = addr + VGA_RAM_SIZE;
> -
> -    vga_dirty_log_start(&s->vga);
> -}
> -
> -static void pci_cirrus_write_config(PCIDevice *d,
> -                                    uint32_t address, uint32_t val, int len)
> -{
> -    PCICirrusVGAState *pvs = DO_UPCAST(PCICirrusVGAState, dev, d);
> -    CirrusVGAState *s =&pvs->cirrus_vga;
> -
> -    pci_default_write_config(d, address, val, len);
> -    if (s->vga.map_addr&&  d->io_regions[0].addr == PCI_BAR_UNMAPPED) {
> -        s->vga.map_addr = 0;
> -        s->vga.lfb_addr = 0;
> -        s->vga.lfb_end = 0;
> -    }
> -    cirrus_update_memory_access(s);
> -}
> -
>   static int pci_cirrus_vga_initfn(PCIDevice *dev)
>   {
>        PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);
> @@ -3112,15 +3170,21 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
>
>        /* setup PCI */
>
> +    memory_region_init(&s->pci_bar, "cirrus-pci-bar0", 0x2000000);
> +
> +    /* XXX: add byte swapping apertures */
> +    memory_region_add_subregion(&s->pci_bar, 0,&s->cirrus_linear_io);
> +    memory_region_add_subregion(&s->pci_bar, 0x1000000,
> +&s->cirrus_linear_bitblt_io);
> +
>        /* setup memory space */
>        /* memory #0 LFB */
>        /* memory #1 memory-mapped I/O */
>        /* XXX: s->vga.vram_size must be a power of two */
> -     pci_register_bar(&d->dev, 0, 0x2000000,
> -                      PCI_BASE_ADDRESS_MEM_PREFETCH, cirrus_pci_lfb_map);
> +     pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH,
> +&s->pci_bar);
>        if (device_id == CIRRUS_ID_CLGD5446) {
> -         pci_register_bar_simple(&d->dev, 1, CIRRUS_PNPMMIO_SIZE, 0,
> -                                 s->cirrus_mmio_io_addr);
> +         pci_register_bar_region(&d->dev, 1, 0,&s->cirrus_mmio_io);
>        }
>        return 0;
>   }
> @@ -3138,7 +3202,6 @@ static PCIDeviceInfo cirrus_vga_info = {
>       .no_hotplug   = 1,
>       .init         = pci_cirrus_vga_initfn,
>       .romfile      = VGABIOS_CIRRUS_FILENAME,
> -    .config_write = pci_cirrus_write_config,
>       .vendor_id    = PCI_VENDOR_ID_CIRRUS,
>       .device_id    = CIRRUS_ID_CLGD5446,
>       .class_id     = PCI_CLASS_DISPLAY_VGA,
> diff --git a/hw/qxl-render.c b/hw/qxl-render.c
> index 1316066..4f626dc 100644
> --- a/hw/qxl-render.c
> +++ b/hw/qxl-render.c
> @@ -86,7 +86,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
>           }
>           qemu_free_displaysurface(vga->ds);
>
> -        qxl->guest_primary.data = qemu_get_ram_ptr(qxl->vga.vram_offset);
> +        qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
>           if (qxl->guest_primary.stride<  0) {
>               /* spice surface is upside down ->  need extra buffer to flip */
>               qxl->guest_primary.stride = -qxl->guest_primary.stride;
> diff --git a/hw/qxl.c b/hw/qxl.c
> index a6fb7f0..b17b58b 100644
> --- a/hw/qxl.c
> +++ b/hw/qxl.c
> @@ -147,7 +147,7 @@ static ram_addr_t qxl_rom_size(void)
>
>   static void init_qxl_rom(PCIQXLDevice *d)
>   {
> -    QXLRom *rom = qemu_get_ram_ptr(d->rom_offset);
> +    QXLRom *rom = memory_region_get_ram_ptr(&d->rom_bar);
>       QXLModes *modes = (QXLModes *)(rom + 1);
>       uint32_t ram_header_size;
>       uint32_t surface0_area_size;
> @@ -223,39 +223,37 @@ static void init_qxl_ram(PCIQXLDevice *d)
>   }
>
>   /* can be called from spice server thread context */
> -static void qxl_set_dirty(ram_addr_t addr, ram_addr_t end)
> +static void qxl_set_dirty(MemoryRegion *mr, ram_addr_t addr, ram_addr_t end)
>   {
>       while (addr<  end) {
> -        cpu_physical_memory_set_dirty(addr);
> +        memory_region_set_dirty(mr, addr);
>           addr += TARGET_PAGE_SIZE;
>       }
>   }
>
>   static void qxl_rom_set_dirty(PCIQXLDevice *qxl)
>   {
> -    ram_addr_t addr = qxl->rom_offset;
> -    qxl_set_dirty(addr, addr + qxl->rom_size);
> +    qxl_set_dirty(&qxl->rom_bar, 0, qxl->rom_size);
>   }
>
>   /* called from spice server thread context only */
>   static void qxl_ram_set_dirty(PCIQXLDevice *qxl, void *ptr)
>   {
> -    ram_addr_t addr = qxl->vga.vram_offset;
>       void *base = qxl->vga.vram_ptr;
>       intptr_t offset;
>
>       offset = ptr - base;
>       offset&= ~(TARGET_PAGE_SIZE-1);
>       assert(offset<  qxl->vga.vram_size);
> -    qxl_set_dirty(addr + offset, addr + offset + TARGET_PAGE_SIZE);
> +    qxl_set_dirty(&qxl->vga.vram, offset, offset + TARGET_PAGE_SIZE);
>   }
>
>   /* can be called from spice server thread context */
>   static void qxl_ring_set_dirty(PCIQXLDevice *qxl)
>   {
> -    ram_addr_t addr = qxl->vga.vram_offset + qxl->shadow_rom.ram_header_offset;
> -    ram_addr_t end  = qxl->vga.vram_offset + qxl->vga.vram_size;
> -    qxl_set_dirty(addr, end);
> +    ram_addr_t addr = qxl->shadow_rom.ram_header_offset;
> +    ram_addr_t end  = qxl->vga.vram_size;
> +    qxl_set_dirty(&qxl->vga.vram, addr, end);
>   }
>
>   /*
> @@ -629,20 +627,6 @@ static void qxl_set_irq(PCIQXLDevice *d)
>       qxl_ring_set_dirty(d);
>   }
>
> -static void qxl_write_config(PCIDevice *d, uint32_t address,
> -                             uint32_t val, int len)
> -{
> -    PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, d);
> -    VGACommonState *vga =&qxl->vga;
> -
> -    vga_dirty_log_stop(vga);
> -    pci_default_write_config(d, address, val, len);
> -    if (vga->map_addr&&  qxl->pci.io_regions[0].addr == -1) {
> -        vga->map_addr = 0;
> -    }
> -    vga_dirty_log_start(vga);
> -}
> -
>   static void qxl_check_state(PCIQXLDevice *d)
>   {
>       QXLRam *ram = d->ram;
> @@ -768,10 +752,10 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
>
>       switch (pci_region) {
>       case QXL_RAM_RANGE_INDEX:
> -        virt_start = (intptr_t)qemu_get_ram_ptr(d->vga.vram_offset);
> +        virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vga.vram);
>           break;
>       case QXL_VRAM_RANGE_INDEX:
> -        virt_start = (intptr_t)qemu_get_ram_ptr(d->vram_offset);
> +        virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vram_bar);
>           break;
>       default:
>           /* should not happen */
> @@ -931,10 +915,11 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
>       qxl_rom_set_dirty(d);
>   }
>
> -static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
> +static void ioport_write(void *opaque, target_phys_addr_t addr,
> +                         uint64_t val, unsigned size)
>   {
>       PCIQXLDevice *d = opaque;
> -    uint32_t io_port = addr - d->io_base;
> +    uint32_t io_port = addr;
>
>       switch (io_port) {
>       case QXL_IO_RESET:
> @@ -982,7 +967,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
>           d->oom_running = 0;
>           break;
>       case QXL_IO_SET_MODE:
> -        dprint(d, 1, "QXL_SET_MODE %d\n", val);
> +        dprint(d, 1, "QXL_SET_MODE %d\n", (int)val);
>           qxl_set_mode(d, val, 0);
>           break;
>       case QXL_IO_LOG:
> @@ -1027,7 +1012,8 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
>       }
>   }
>
> -static uint32_t ioport_read(void *opaque, uint32_t addr)
> +static uint64_t ioport_read(void *opaque, target_phys_addr_t addr,
> +                            unsigned size)
>   {
>       PCIQXLDevice *d = opaque;
>
> @@ -1035,42 +1021,14 @@ static uint32_t ioport_read(void *opaque, uint32_t addr)
>       return 0xff;
>   }
>
> -static void qxl_map(PCIDevice *pci, int region_num,
> -                    pcibus_t addr, pcibus_t size, int type)
> -{
> -    static const char *names[] = {
> -        [ QXL_IO_RANGE_INDEX ]   = "ioports",
> -        [ QXL_RAM_RANGE_INDEX ]  = "devram",
> -        [ QXL_ROM_RANGE_INDEX ]  = "rom",
> -        [ QXL_VRAM_RANGE_INDEX ] = "vram",
> -    };
> -    PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, pci);
> -
> -    dprint(qxl, 1, "%s: bar %d [%s] addr 0x%lx size 0x%lx\n", __FUNCTION__,
> -            region_num, names[region_num], addr, size);
> -
> -    switch (region_num) {
> -    case QXL_IO_RANGE_INDEX:
> -        register_ioport_write(addr, size, 1, ioport_write, pci);
> -        register_ioport_read(addr, size, 1, ioport_read, pci);
> -        qxl->io_base = addr;
> -        break;
> -    case QXL_RAM_RANGE_INDEX:
> -        cpu_register_physical_memory(addr, size, qxl->vga.vram_offset | IO_MEM_RAM);
> -        qxl->vga.map_addr = addr;
> -        qxl->vga.map_end = addr + size;
> -        if (qxl->id == 0) {
> -            vga_dirty_log_start(&qxl->vga);
> -        }
> -        break;
> -    case QXL_ROM_RANGE_INDEX:
> -        cpu_register_physical_memory(addr, size, qxl->rom_offset | IO_MEM_ROM);
> -        break;
> -    case QXL_VRAM_RANGE_INDEX:
> -        cpu_register_physical_memory(addr, size, qxl->vram_offset | IO_MEM_RAM);
> -        break;
> -    }
> -}
> +static const MemoryRegionOps qxl_io_ops = {
> +    .read = ioport_read,
> +    .write = ioport_write,
> +    .valid = {
> +        .min_access_size = 1,
> +        .max_access_size = 1,
> +    },
> +};
>
>   static void pipe_read(void *opaque)
>   {
> @@ -1190,10 +1148,9 @@ static void qxl_vm_change_state_handler(void *opaque, int running, int reason)
>            * to make sure they are saved */
>           /* FIXME #1: should go out during "live" stage */
>           /* FIXME #2: we only need to save the areas which are actually used */
> -        ram_addr_t vram_addr = qxl->vram_offset;
> -        ram_addr_t surface0_addr = qxl->vga.vram_offset + qxl->shadow_rom.draw_area_offset;
> -        qxl_set_dirty(vram_addr, vram_addr + qxl->vram_size);
> -        qxl_set_dirty(surface0_addr, surface0_addr + qxl->shadow_rom.surface0_area_size);
> +        qxl_set_dirty(&qxl->vram_bar, 0, qxl->vram_size);
> +        qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
> +                      qxl->shadow_rom.surface0_area_size);
>       }
>   }
>
> @@ -1251,7 +1208,8 @@ static int qxl_init_common(PCIQXLDevice *qxl)
>       pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
>
>       qxl->rom_size = qxl_rom_size();
> -    qxl->rom_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vrom", qxl->rom_size);
> +    memory_region_init_ram(&qxl->rom_bar,&qxl->pci.qdev, "qxl.vrom",
> +                           qxl->rom_size);
>       init_qxl_rom(qxl);
>       init_qxl_ram(qxl);
>
> @@ -1262,26 +1220,32 @@ static int qxl_init_common(PCIQXLDevice *qxl)
>           qxl->vram_size = 4096;
>       }
>       qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1);
> -    qxl->vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vram", qxl->vram_size);
> +    memory_region_init_ram(&qxl->vram_bar,&qxl->pci.qdev, "qxl.vram",
> +                           qxl->vram_size);
>
>       io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1);
>       if (qxl->revision == 1) {
>           io_size = 8;
>       }
>
> -    pci_register_bar(&qxl->pci, QXL_IO_RANGE_INDEX,
> -                     io_size, PCI_BASE_ADDRESS_SPACE_IO, qxl_map);
> +    memory_region_init_io(&qxl->io_bar,&qxl_io_ops, qxl,
> +                          "qxl-ioports", io_size);
> +    if (qxl->id == 0) {
> +        vga_dirty_log_start(&qxl->vga);
> +    }
> +
> +
> +    pci_register_bar_region(&qxl->pci, QXL_IO_RANGE_INDEX,
> +                            PCI_BASE_ADDRESS_SPACE_IO,&qxl->io_bar);
>
> -    pci_register_bar(&qxl->pci, QXL_ROM_RANGE_INDEX,
> -                     qxl->rom_size, PCI_BASE_ADDRESS_SPACE_MEMORY,
> -                     qxl_map);
> +    pci_register_bar_region(&qxl->pci, QXL_ROM_RANGE_INDEX,
> +                            PCI_BASE_ADDRESS_SPACE_MEMORY,&qxl->rom_bar);
>
> -    pci_register_bar(&qxl->pci, QXL_RAM_RANGE_INDEX,
> -                     qxl->vga.vram_size, PCI_BASE_ADDRESS_SPACE_MEMORY,
> -                     qxl_map);
> +    pci_register_bar_region(&qxl->pci, QXL_RAM_RANGE_INDEX,
> +                            PCI_BASE_ADDRESS_SPACE_MEMORY,&qxl->vga.vram);
>
> -    pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX, qxl->vram_size,
> -                     PCI_BASE_ADDRESS_SPACE_MEMORY, qxl_map);
> +    pci_register_bar_region(&qxl->pci, QXL_VRAM_RANGE_INDEX,
> +                            PCI_BASE_ADDRESS_SPACE_MEMORY,&qxl->vram_bar);
>
>       qxl->ssd.qxl.base.sif =&qxl_interface.base;
>       qxl->ssd.qxl.id = qxl->id;
> @@ -1340,9 +1304,9 @@ static int qxl_init_secondary(PCIDevice *dev)
>           ram_size = 16 * 1024 * 1024;
>       }
>       qxl->vga.vram_size = ram_size;
> -    qxl->vga.vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vgavram",
> -                                          qxl->vga.vram_size);
> -    qxl->vga.vram_ptr = qemu_get_ram_ptr(qxl->vga.vram_offset);
> +    memory_region_init_ram(&qxl->vga.vram,&qxl->pci.qdev, "qxl.vgavram",
> +                           qxl->vga.vram_size);
> +    qxl->vga.vram_ptr = memory_region_get_ram_ptr(&qxl->vga.vram);
>
>       return qxl_init_common(qxl);
>   }
> @@ -1505,7 +1469,6 @@ static PCIDeviceInfo qxl_info_primary = {
>       .qdev.vmsd    =&qxl_vmstate,
>       .no_hotplug   = 1,
>       .init         = qxl_init_primary,
> -    .config_write = qxl_write_config,
>       .romfile      = "vgabios-qxl.bin",
>       .vendor_id    = REDHAT_PCI_VENDOR_ID,
>       .device_id    = QXL_DEVICE_ID_STABLE,
> diff --git a/hw/qxl.h b/hw/qxl.h
> index f6c450d..987a5e7 100644
> --- a/hw/qxl.h
> +++ b/hw/qxl.h
> @@ -72,14 +72,14 @@ typedef struct PCIQXLDevice {
>       QXLRom             *rom;
>       QXLModes           *modes;
>       uint32_t           rom_size;
> -    uint64_t           rom_offset;
> +    MemoryRegion       rom_bar;
>
>       /* vram pci bar */
>       uint32_t           vram_size;
> -    uint64_t           vram_offset;
> +    MemoryRegion       vram_bar;
>
>       /* io bar */
> -    uint32_t           io_base;
> +    MemoryRegion       io_bar;
>   } PCIQXLDevice;
>
>   #define PANIC_ON(x) if ((x)) {                         \
> diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c
> index 4954bb1..baa1e92 100644
> --- a/hw/vga-isa-mm.c
> +++ b/hw/vga-isa-mm.c
> @@ -79,35 +79,46 @@ static void vga_mm_writel (void *opaque,
>       vga_ioport_write(&s->vga, addr>>  s->it_shift, value);
>   }
>
> -static CPUReadMemoryFunc * const vga_mm_read_ctrl[] = {
> -&vga_mm_readb,
> -&vga_mm_readw,
> -&vga_mm_readl,
> +static const MemoryRegionOps vga_mm_ctrl_ops = {
> +    .old_mmio = {
> +        .read = {
> +            vga_mm_readb,
> +            vga_mm_readw,
> +            vga_mm_readl,
> +        },
> +        .write = {
> +            vga_mm_writeb,
> +            vga_mm_writew,
> +            vga_mm_writel,
> +        },
> +    },
> +    .endianness = DEVICE_NATIVE_ENDIAN,
>   };
>
> -static CPUWriteMemoryFunc * const vga_mm_write_ctrl[] = {
> -&vga_mm_writeb,
> -&vga_mm_writew,
> -&vga_mm_writel,
> -};
> +#include "exec-memory.h"
>
>   static void vga_mm_init(ISAVGAMMState *s, target_phys_addr_t vram_base,
>                           target_phys_addr_t ctrl_base, int it_shift)
>   {
> -    int s_ioport_ctrl, vga_io_memory;
> +    MemoryRegion *s_ioport_ctrl, *vga_io_memory;
>
>       s->it_shift = it_shift;
> -    s_ioport_ctrl = cpu_register_io_memory(vga_mm_read_ctrl, vga_mm_write_ctrl, s,
> -                                           DEVICE_NATIVE_ENDIAN);
> -    vga_io_memory = cpu_register_io_memory(vga_mem_read, vga_mem_write, s,
> -                                           DEVICE_NATIVE_ENDIAN);
> +    s_ioport_ctrl = qemu_malloc(sizeof(*s_ioport_ctrl));
> +    memory_region_init_io(s_ioport_ctrl,&vga_mm_ctrl_ops, s,
> +                          "vga-mm-ctrl", 0x100000);
> +
> +    vga_io_memory = qemu_malloc(sizeof(*vga_io_memory));
> +    /* XXX: endianness? */
> +    memory_region_init_io(vga_io_memory,&vga_mem_ops,&s->vga,
> +                          "vga-mem", 0x20000);
>
>       vmstate_register(NULL, 0,&vmstate_vga_common, s);
>
> -    cpu_register_physical_memory(ctrl_base, 0x100000, s_ioport_ctrl);
> +    memory_region_add_subregion(get_system_memory(), ctrl_base, s_ioport_ctrl);
>       s->vga.bank_offset = 0;
> -    cpu_register_physical_memory(vram_base + 0x000a0000, 0x20000, vga_io_memory);
> -    qemu_register_coalesced_mmio(vram_base + 0x000a0000, 0x20000);
> +    memory_region_add_subregion(get_system_memory(),
> +                                vram_base + 0x000a0000, vga_io_memory);
> +    memory_region_set_coalescing(vga_io_memory);
>   }
>
>   int isa_vga_mm_init(target_phys_addr_t vram_base,
> diff --git a/hw/vga-isa.c b/hw/vga-isa.c
> index 245841f..518cecc 100644
> --- a/hw/vga-isa.c
> +++ b/hw/vga-isa.c
> @@ -42,17 +42,20 @@ static void vga_reset_isa(DeviceState *dev)
>       vga_common_reset(s);
>   }
>
> +#include "exec-memory.h"
> +

Should move to top of file.

>   static int vga_initfn(ISADevice *dev)
>   {
>       ISAVGAState *d = DO_UPCAST(ISAVGAState, dev, dev);
>       VGACommonState *s =&d->state;
> -    int vga_io_memory;
> +    MemoryRegion *vga_io_memory;
>
>       vga_common_init(s, VGA_RAM_SIZE);
>       vga_io_memory = vga_init_io(s);
> -    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
> -                                 vga_io_memory);
> -    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
> +    memory_region_add_subregion_overlap(get_system_memory(),
> +                                        isa_mem_base + 0x000a0000,
> +                                        vga_io_memory, 1);
> +    memory_region_set_coalescing(vga_io_memory);
>       isa_init_ioport(dev, 0x3c0);
>       isa_init_ioport(dev, 0x3b4);
>       isa_init_ioport(dev, 0x3ba);
> diff --git a/hw/vga-pci.c b/hw/vga-pci.c
> index 481f448..7062c4d 100644
> --- a/hw/vga-pci.c
> +++ b/hw/vga-pci.c
> @@ -47,29 +47,6 @@ static const VMStateDescription vmstate_vga_pci = {
>       }
>   };
>
> -static void vga_map(PCIDevice *pci_dev, int region_num,
> -                    pcibus_t addr, pcibus_t size, int type)
> -{
> -    PCIVGAState *d = (PCIVGAState *)pci_dev;
> -    VGACommonState *s =&d->vga;
> -
> -    cpu_register_physical_memory(addr, s->vram_size, s->vram_offset);
> -    s->map_addr = addr;
> -    s->map_end = addr + s->vram_size;
> -    vga_dirty_log_start(s);
> -}
> -
> -static void pci_vga_write_config(PCIDevice *d,
> -                                 uint32_t address, uint32_t val, int len)
> -{
> -    PCIVGAState *pvs = container_of(d, PCIVGAState, dev);
> -    VGACommonState *s =&pvs->vga;
> -
> -    pci_default_write_config(d, address, val, len);
> -    if (s->map_addr&&  pvs->dev.io_regions[0].addr == -1)
> -        s->map_addr = 0;
> -}
> -
>   static int pci_vga_initfn(PCIDevice *dev)
>   {
>        PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
> @@ -83,8 +60,8 @@ static int pci_vga_initfn(PCIDevice *dev)
>                                     s->screen_dump, s->text_update, s);
>
>        /* XXX: VGA_RAM_SIZE must be a power of two */
> -     pci_register_bar(&d->dev, 0, VGA_RAM_SIZE,
> -                      PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map);
> +     pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH,
> +&s->vram);
>
>        if (!dev->rom_bar) {
>            /* compatibility with pc-0.13 and older */
> @@ -106,7 +83,6 @@ static PCIDeviceInfo vga_info = {
>       .qdev.vmsd    =&vmstate_vga_pci,
>       .no_hotplug   = 1,
>       .init         = pci_vga_initfn,
> -    .config_write = pci_vga_write_config,
>       .romfile      = "vgabios-stdvga.bin",
>
>       /* dummy VGA (same as Bochs ID) */
> diff --git a/hw/vga.c b/hw/vga.c
> index 0f54734..cdd8255 100644
> --- a/hw/vga.c
> +++ b/hw/vga.c
> @@ -825,7 +825,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
>               printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
>   #endif
>               s->plane_updated |= mask; /* only used to detect font change */
> -            cpu_physical_memory_set_dirty(s->vram_offset + addr);
> +            memory_region_set_dirty(&s->vram, addr);
>           }
>       } else if (s->gr[5]&  0x10) {
>           /* odd/even mode (aka text mode mapping) */
> @@ -838,7 +838,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
>               printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
>   #endif
>               s->plane_updated |= mask; /* only used to detect font change */
> -            cpu_physical_memory_set_dirty(s->vram_offset + addr);
> +            memory_region_set_dirty(&s->vram, addr);
>           }
>       } else {
>           /* standard VGA latched access */
> @@ -912,7 +912,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
>           printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n",
>                  addr * 4, write_mask, val);
>   #endif
> -        cpu_physical_memory_set_dirty(s->vram_offset + (addr<<  2));
> +        memory_region_set_dirty(&s->vram, addr<<  2);
>       }
>   }
>
> @@ -1553,57 +1553,17 @@ void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
>
>   static void vga_sync_dirty_bitmap(VGACommonState *s)
>   {
> -    if (s->map_addr)
> -        cpu_physical_sync_dirty_bitmap(s->map_addr, s->map_end);
> -
> -    if (s->lfb_vram_mapped) {
> -        cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa0000, 0xa8000);
> -        cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa8000, 0xb0000);
> -    }
> -
> -#ifdef CONFIG_BOCHS_VBE
> -    if (s->vbe_mapped) {
> -        cpu_physical_sync_dirty_bitmap(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
> -                                       VBE_DISPI_LFB_PHYSICAL_ADDRESS + s->vram_size);
> -    }
> -#endif
> -
> +    memory_region_sync_dirty_bitmap(&s->vram);
>   }
>
>   void vga_dirty_log_start(VGACommonState *s)
>   {
> -    if (s->map_addr) {
> -        cpu_physical_log_start(s->map_addr, s->map_end - s->map_addr);
> -    }
> -
> -    if (s->lfb_vram_mapped) {
> -        cpu_physical_log_start(isa_mem_base + 0xa0000, 0x8000);
> -        cpu_physical_log_start(isa_mem_base + 0xa8000, 0x8000);
> -    }
> -
> -#ifdef CONFIG_BOCHS_VBE
> -    if (s->vbe_mapped) {
> -        cpu_physical_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size);
> -    }
> -#endif
> +    memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
>   }
>
>   void vga_dirty_log_stop(VGACommonState *s)
>   {
> -    if (s->map_addr) {
> -        cpu_physical_log_stop(s->map_addr, s->map_end - s->map_addr);
> -    }
> -
> -    if (s->lfb_vram_mapped) {
> -        cpu_physical_log_stop(isa_mem_base + 0xa0000, 0x8000);
> -        cpu_physical_log_stop(isa_mem_base + 0xa8000, 0x8000);
> -    }
> -
> -#ifdef CONFIG_BOCHS_VBE
> -    if (s->vbe_mapped) {
> -        cpu_physical_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size);
> -    }
> -#endif
> +    memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
>   }
>
>   void vga_dirty_log_restart(VGACommonState *s)
> @@ -1773,15 +1733,16 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
>           if (!(s->cr[0x17]&  2)) {
>               addr = (addr&  ~0x8000) | ((y1&  2)<<  14);
>           }
> -        page0 = s->vram_offset + (addr&  TARGET_PAGE_MASK);
> -        page1 = s->vram_offset + ((addr + bwidth - 1)&  TARGET_PAGE_MASK);
> +        page0 = addr&  TARGET_PAGE_MASK;
> +        page1 = (addr + bwidth - 1)&  TARGET_PAGE_MASK;
>           update = full_update |
> -            cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) |
> -            cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG);
> +            memory_region_get_dirty(&s->vram, page0, DIRTY_MEMORY_VGA) |
> +            memory_region_get_dirty(&s->vram, page1, DIRTY_MEMORY_VGA);
>           if ((page1 - page0)>  TARGET_PAGE_SIZE) {
>               /* if wide line, can use another page */
> -            update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE,
> -                                                    VGA_DIRTY_FLAG);
> +            update |= memory_region_get_dirty(&s->vram,
> +                                              page0 + TARGET_PAGE_SIZE,
> +                                              DIRTY_MEMORY_VGA);
>           }
>           /* explicit invalidation for the hardware cursor */
>           update |= (s->invalidated_y_table[y>>  5]>>  (y&  0x1f))&  1;
> @@ -1826,8 +1787,10 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
>       }
>       /* reset modified pages */
>       if (page_max>= page_min) {
> -        cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE,
> -                                        VGA_DIRTY_FLAG);
> +        memory_region_reset_dirty(&s->vram,
> +                                  page_min,
> +                                  page_max + TARGET_PAGE_SIZE - page_min,
> +                                  DIRTY_MEMORY_VGA);
>       }
>       memset(s->invalidated_y_table, 0, ((height + 31)>>  5) * 4);
>   }
> @@ -1906,11 +1869,6 @@ static void vga_invalidate_display(void *opaque)
>
>   void vga_common_reset(VGACommonState *s)
>   {
> -    s->lfb_addr = 0;
> -    s->lfb_end = 0;
> -    s->map_addr = 0;
> -    s->map_end = 0;
> -    s->lfb_vram_mapped = 0;
>       s->sr_index = 0;
>       memset(s->sr, '\0', sizeof(s->sr));
>       s->gr_index = 0;
> @@ -2141,16 +2099,36 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
>       dpy_update(s->ds, 0, 0, s->last_width, height);
>   }
>
> -CPUReadMemoryFunc * const vga_mem_read[3] = {
> -    vga_mem_readb,
> -    vga_mem_readw,
> -    vga_mem_readl,
> -};
> +static uint64_t vga_mem_read(void *opaque, target_phys_addr_t addr,
> +                             unsigned size)
> +{
> +    VGACommonState *s = opaque;
> +
> +    switch (size) {
> +    case 1: return vga_mem_readb(s, addr);
> +    case 2: return vga_mem_readw(s, addr);
> +    case 4: return vga_mem_readl(s, addr);
> +    default: abort();
> +    }
> +}
> +
> +static void vga_mem_write(void *opaque, target_phys_addr_t addr,
> +                          uint64_t data, unsigned size)
> +{
> +    VGACommonState *s = opaque;
> +
> +    switch (size) {
> +    case 1: return vga_mem_writeb(s, addr, data);
> +    case 2: return vga_mem_writew(s, addr, data);
> +    case 4: return vga_mem_writel(s, addr, data);
> +    default: abort();
> +    }
> +}
>
> -CPUWriteMemoryFunc * const vga_mem_write[3] = {
> -    vga_mem_writeb,
> -    vga_mem_writew,
> -    vga_mem_writel,
> +const MemoryRegionOps vga_mem_ops = {
> +    .read = vga_mem_read,
> +    .write = vga_mem_write,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
>   };
>
>   static int vga_common_post_load(void *opaque, int version_id)
> @@ -2236,8 +2214,8 @@ void vga_common_init(VGACommonState *s, int vga_ram_size)
>   #else
>       s->is_vbe_vmstate = 0;
>   #endif
> -    s->vram_offset = qemu_ram_alloc(NULL, "vga.vram", vga_ram_size);
> -    s->vram_ptr = qemu_get_ram_ptr(s->vram_offset);
> +    memory_region_init_ram(&s->vram, NULL, "vga.vram", vga_ram_size);
> +    s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
>       s->vram_size = vga_ram_size;
>       s->get_bpp = vga_get_bpp;
>       s->get_offsets = vga_get_offsets;
> @@ -2257,11 +2235,14 @@ void vga_common_init(VGACommonState *s, int vga_ram_size)
>           s->update_retrace_info = vga_precise_update_retrace_info;
>           break;
>       }
> +    vga_dirty_log_start(s);
>   }
>
>   /* used by both ISA and PCI */
> -int vga_init_io(VGACommonState *s)
> +MemoryRegion *vga_init_io(VGACommonState *s)
>   {
> +    MemoryRegion *vga_mem;
> +
>       register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
>
>       register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
> @@ -2292,30 +2273,38 @@ int vga_init_io(VGACommonState *s)
>   #endif
>   #endif /* CONFIG_BOCHS_VBE */
>
> -    return cpu_register_io_memory(vga_mem_read, vga_mem_write, s,
> -                                  DEVICE_LITTLE_ENDIAN);
> +    vga_mem = qemu_malloc(sizeof(*vga_mem));
> +    memory_region_init_io(vga_mem,&vga_mem_ops, s,
> +                          "vga-lowmem", 0x20000);
> +
> +    return vga_mem;
>   }
>
> +#include "exec-memory.h"
> +

Here too.

Regards,

Anthony Liguori
diff mbox

Patch

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index f39d1f8..d1475dd 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -200,9 +200,14 @@  typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
 typedef struct CirrusVGAState {
     VGACommonState vga;
 
-    int cirrus_linear_io_addr;
-    int cirrus_linear_bitblt_io_addr;
-    int cirrus_mmio_io_addr;
+    MemoryRegion cirrus_linear_io;
+    MemoryRegion cirrus_linear_bitblt_io;
+    MemoryRegion cirrus_mmio_io;
+    MemoryRegion pci_bar;
+    bool linear_vram;  /* vga.vram mapped over cirrus_linear_io */
+    MemoryRegion low_mem_container; /* container for 0xa0000-0xc0000 */
+    MemoryRegion low_mem;           /* always mapped, overridden by: */
+    MemoryRegion *cirrus_bank[2];   /*   aliases at 0xa0000-0xb0000  */
     uint32_t cirrus_addr_mask;
     uint32_t linear_mmio_mask;
     uint8_t cirrus_shadow_gr0;
@@ -612,7 +617,7 @@  static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
 	off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
 	off_cur &= TARGET_PAGE_MASK;
 	while (off_cur < off_cur_end) {
-	    cpu_physical_memory_set_dirty(s->vga.vram_offset + off_cur);
+	    memory_region_set_dirty(&s->vga.vram, off_cur);
 	    off_cur += TARGET_PAGE_SIZE;
 	}
 	off_begin += off_pitch;
@@ -1177,12 +1182,6 @@  static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
     }
 
     if (limit > 0) {
-        /* Thinking about changing bank base? First, drop the dirty bitmap information
-         * on the current location, otherwise we lose this pointer forever */
-        if (s->vga.lfb_vram_mapped) {
-            target_phys_addr_t base_addr = isa_mem_base + 0xa0000 + bank_index * 0x8000;
-            cpu_physical_sync_dirty_bitmap(base_addr, base_addr + 0x8000);
-        }
 	s->cirrus_bank_base[bank_index] = offset;
 	s->cirrus_bank_limit[bank_index] = limit;
     } else {
@@ -1921,8 +1920,8 @@  static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
 	val <<= 1;
 	dst++;
     }
-    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset);
-    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 7);
+    memory_region_set_dirty(&s->vga.vram, offset);
+    memory_region_set_dirty(&s->vga.vram, offset + 7);
 }
 
 static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
@@ -1946,8 +1945,8 @@  static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
 	val <<= 1;
 	dst += 2;
     }
-    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset);
-    cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 15);
+    memory_region_set_dirty(&s->vga.vram, offset);
+    memory_region_set_dirty(&s->vga.vram, offset + 15);
 }
 
 /***************************************
@@ -2057,8 +2056,7 @@  static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
 		mode = s->vga.gr[0x05] & 0x7;
 		if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
 		    *(s->vga.vram_ptr + bank_offset) = mem_value;
-		    cpu_physical_memory_set_dirty(s->vga.vram_offset +
-						  bank_offset);
+		    memory_region_set_dirty(&s->vga.vram, bank_offset);
 		} else {
 		    if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
 			cirrus_mem_writeb_mode4and5_8bpp(s, mode,
@@ -2099,16 +2097,37 @@  static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_
     cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
 }
 
-static CPUReadMemoryFunc * const cirrus_vga_mem_read[3] = {
-    cirrus_vga_mem_readb,
-    cirrus_vga_mem_readw,
-    cirrus_vga_mem_readl,
+static uint64_t cirrus_vga_mem_read(void *opaque,
+                                    target_phys_addr_t addr,
+                                    uint32_t size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_vga_mem_readb(s, addr);
+    case 2: return cirrus_vga_mem_readw(s, addr);
+    case 4: return cirrus_vga_mem_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void cirrus_vga_mem_write(void *opaque, target_phys_addr_t addr,
+                                 uint64_t data, unsigned size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_vga_mem_writeb(s, addr, data);
+    case 2: return cirrus_vga_mem_writew(s, addr, data);
+    case 4: return cirrus_vga_mem_writel(s, addr, data);
+    default: abort();
+    }
 };
 
-static CPUWriteMemoryFunc * const cirrus_vga_mem_write[3] = {
-    cirrus_vga_mem_writeb,
-    cirrus_vga_mem_writew,
-    cirrus_vga_mem_writel,
+static const MemoryRegionOps cirrus_vga_mem_ops = {
+    .read = cirrus_vga_mem_read,
+    .write = cirrus_vga_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 /***************************************
@@ -2365,7 +2384,7 @@  static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
 	mode = s->vga.gr[0x05] & 0x7;
 	if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
 	    *(s->vga.vram_ptr + addr) = (uint8_t) val;
-	    cpu_physical_memory_set_dirty(s->vga.vram_offset + addr);
+	    memory_region_set_dirty(&s->vga.vram, addr);
 	} else {
 	    if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
 		cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
@@ -2393,17 +2412,31 @@  static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr,
 }
 
 
-static CPUReadMemoryFunc * const cirrus_linear_read[3] = {
-    cirrus_linear_readb,
-    cirrus_linear_readw,
-    cirrus_linear_readl,
-};
+static uint64_t cirrus_linear_read(void *opaque, target_phys_addr_t addr,
+                                   unsigned size)
+{
+    CirrusVGAState *s = opaque;
 
-static CPUWriteMemoryFunc * const cirrus_linear_write[3] = {
-    cirrus_linear_writeb,
-    cirrus_linear_writew,
-    cirrus_linear_writel,
-};
+    switch (size) {
+    case 1: return cirrus_linear_readb(s, addr);
+    case 2: return cirrus_linear_readw(s, addr);
+    case 4: return cirrus_linear_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void cirrus_linear_write(void *opaque, target_phys_addr_t addr,
+                                uint64_t data, unsigned size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_linear_writeb(s, addr, data);
+    case 2: return cirrus_linear_writew(s, addr, data);
+    case 4: return cirrus_linear_writel(s, addr, data);
+    default: abort();
+    }
+}
 
 /***************************************
  *
@@ -2471,67 +2504,97 @@  static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr,
     cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff);
 }
 
+static uint64_t cirrus_linear_bitblt_read(void *opaque,
+                                          target_phys_addr_t addr,
+                                          unsigned size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_linear_bitblt_readb(s, addr);
+    case 2: return cirrus_linear_bitblt_readw(s, addr);
+    case 4: return cirrus_linear_bitblt_readl(s, addr);
+    default: abort();
+    }
+};
+
+static void cirrus_linear_bitblt_write(void *opaque,
+                                       target_phys_addr_t addr,
+                                       uint64_t data,
+                                       unsigned size)
+{
+    CirrusVGAState *s = opaque;
 
-static CPUReadMemoryFunc * const cirrus_linear_bitblt_read[3] = {
-    cirrus_linear_bitblt_readb,
-    cirrus_linear_bitblt_readw,
-    cirrus_linear_bitblt_readl,
+    switch (size) {
+    case 1: return cirrus_linear_bitblt_writeb(s, addr, data);
+    case 2: return cirrus_linear_bitblt_writew(s, addr, data);
+    case 4: return cirrus_linear_bitblt_writel(s, addr, data);
+    default: abort();
+    }
 };
 
-static CPUWriteMemoryFunc * const cirrus_linear_bitblt_write[3] = {
-    cirrus_linear_bitblt_writeb,
-    cirrus_linear_bitblt_writew,
-    cirrus_linear_bitblt_writel,
+static const MemoryRegionOps cirrus_linear_bitblt_io_ops = {
+    .read = cirrus_linear_bitblt_read,
+    .write = cirrus_linear_bitblt_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static void map_linear_vram(CirrusVGAState *s)
+#include "exec-memory.h"
+
+static void unmap_bank(CirrusVGAState *s, unsigned bank)
 {
-    if (!s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) {
-        s->vga.map_addr = s->vga.lfb_addr;
-        s->vga.map_end = s->vga.lfb_end;
-        cpu_register_physical_memory_log(s->vga.map_addr,
-					 s->vga.map_end - s->vga.map_addr,
-					 s->vga.vram_offset, 0, true);
+    if (s->cirrus_bank[bank]) {
+        memory_region_del_subregion(&s->low_mem_container,
+                                    s->cirrus_bank[bank]);
+        memory_region_destroy(s->cirrus_bank[bank]);
+        qemu_free(s->cirrus_bank[bank]);
+        s->cirrus_bank[bank] = NULL;
     }
+}
 
-    if (!s->vga.map_addr)
-        return;
-
-    s->vga.lfb_vram_mapped = 0;
+static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank)
+{
+    MemoryRegion *mr;
+    static const char *names[] = { "vga.bank0", "vga.bank1" };
 
     if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)
         && !((s->vga.sr[0x07] & 0x01) == 0)
         && !((s->vga.gr[0x0B] & 0x14) == 0x14)
         && !(s->vga.gr[0x0B] & 0x02)) {
 
-        cpu_register_physical_memory_log(isa_mem_base + 0xa0000, 0x8000,
-					 (s->vga.vram_offset +
-					  s->cirrus_bank_base[0]) |
-					 IO_MEM_RAM, 0, true);
-        cpu_register_physical_memory_log(isa_mem_base + 0xa8000, 0x8000,
-					 (s->vga.vram_offset +
-					  s->cirrus_bank_base[1]) |
-					 IO_MEM_RAM, 0, true);
-
-        s->vga.lfb_vram_mapped = 1;
-    }
-    else {
-        cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
-                                     s->vga.vga_io_memory);
+        mr = qemu_malloc(sizeof(*mr));
+        memory_region_init_alias(mr, names[bank], &s->vga.vram,
+                                 s->cirrus_bank_base[bank], 0x8000);
+        memory_region_add_subregion_overlap(
+            &s->low_mem_container,
+            0x8000 * bank,
+            mr,
+            1);
+        unmap_bank(s, bank);
+        s->cirrus_bank[bank] = mr;
+    } else {
+        unmap_bank(s, bank);
     }
+}
 
-    vga_dirty_log_start(&s->vga);
+static void map_linear_vram(CirrusVGAState *s)
+{
+    if (!s->linear_vram) {
+        s->linear_vram = true;
+        memory_region_add_subregion_overlap(&s->pci_bar, 0, &s->vga.vram, 1);
+    }
+    map_linear_vram_bank(s, 0);
+    map_linear_vram_bank(s, 1);
 }
 
 static void unmap_linear_vram(CirrusVGAState *s)
 {
-    if (s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) {
-        s->vga.map_addr = s->vga.map_end = 0;
-         cpu_register_physical_memory(s->vga.lfb_addr, s->vga.vram_size,
-                                      s->cirrus_linear_io_addr);
+    if (s->linear_vram) {
+        s->linear_vram = false;
+        memory_region_del_subregion(&s->pci_bar, &s->vga.vram);
     }
-    cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
-                                 s->vga.vga_io_memory);
+    unmap_bank(s, 0);
+    unmap_bank(s, 1);
 }
 
 /* Compute the memory access functions */
@@ -2829,16 +2892,36 @@  static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr,
 }
 
 
-static CPUReadMemoryFunc * const cirrus_mmio_read[3] = {
-    cirrus_mmio_readb,
-    cirrus_mmio_readw,
-    cirrus_mmio_readl,
+static uint64_t cirrus_mmio_read(void *opaque, target_phys_addr_t addr,
+                                 unsigned size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_mmio_readb(s, addr);
+    case 2: return cirrus_mmio_readw(s, addr);
+    case 4: return cirrus_mmio_readl(s, addr);
+    default: abort();
+    }
 };
 
-static CPUWriteMemoryFunc * const cirrus_mmio_write[3] = {
-    cirrus_mmio_writeb,
-    cirrus_mmio_writew,
-    cirrus_mmio_writel,
+static void cirrus_mmio_write(void *opaque, target_phys_addr_t addr,
+                              uint64_t data, unsigned size)
+{
+    CirrusVGAState *s = opaque;
+
+    switch (size) {
+    case 1: return cirrus_mmio_writeb(s, addr, data);
+    case 2: return cirrus_mmio_writew(s, addr, data);
+    case 4: return cirrus_mmio_writel(s, addr, data);
+    default: abort();
+    }
+};
+
+static const MemoryRegionOps cirrus_mmio_io_ops = {
+    .read = cirrus_mmio_read,
+    .write = cirrus_mmio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 /* load/save state */
@@ -2947,6 +3030,12 @@  static void cirrus_reset(void *opaque)
     s->cirrus_hidden_dac_data = 0;
 }
 
+static const MemoryRegionOps cirrus_linear_io_ops = {
+    .read = cirrus_linear_read,
+    .write = cirrus_linear_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
 {
     int i;
@@ -2993,28 +3082,33 @@  static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
     register_ioport_read(0x3ba, 1, 1, cirrus_vga_ioport_read, s);
     register_ioport_read(0x3da, 1, 1, cirrus_vga_ioport_read, s);
 
-    s->vga.vga_io_memory = cpu_register_io_memory(cirrus_vga_mem_read,
-                                                  cirrus_vga_mem_write, s,
-                                                  DEVICE_LITTLE_ENDIAN);
-    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
-                                 s->vga.vga_io_memory);
-    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
+    memory_region_init(&s->low_mem_container,
+                       "cirrus-lowmem-container",
+                       0x20000);
+
+    memory_region_init_io(&s->low_mem, &cirrus_vga_mem_ops, s,
+                          "cirrus-low-memory", 0x20000);
+    memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem);
+    memory_region_add_subregion_overlap(get_system_memory(),
+                                        isa_mem_base + 0x000a0000,
+                                        &s->low_mem_container,
+                                        1);
+    memory_region_set_coalescing(&s->low_mem);
 
     /* I/O handler for LFB */
-    s->cirrus_linear_io_addr =
-        cpu_register_io_memory(cirrus_linear_read, cirrus_linear_write, s,
-                               DEVICE_LITTLE_ENDIAN);
+    memory_region_init_io(&s->cirrus_linear_io, &cirrus_linear_io_ops, s,
+                          "cirrus-linear-io", VGA_RAM_SIZE);
 
     /* I/O handler for LFB */
-    s->cirrus_linear_bitblt_io_addr =
-        cpu_register_io_memory(cirrus_linear_bitblt_read,
-                               cirrus_linear_bitblt_write, s,
-                               DEVICE_LITTLE_ENDIAN);
+    memory_region_init_io(&s->cirrus_linear_bitblt_io,
+                          &cirrus_linear_bitblt_io_ops,
+                          s,
+                          "cirrus-bitblt-mmio",
+                          0x400000);
 
     /* I/O handler for memory-mapped I/O */
-    s->cirrus_mmio_io_addr =
-        cpu_register_io_memory(cirrus_mmio_read, cirrus_mmio_write, s,
-                               DEVICE_LITTLE_ENDIAN);
+    memory_region_init_io(&s->cirrus_mmio_io, &cirrus_mmio_io_ops, s,
+                          "cirrus-mmio", CIRRUS_PNPMMIO_SIZE);
 
     s->real_vram_size =
         (s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024;
@@ -3060,42 +3154,6 @@  void isa_cirrus_vga_init(void)
  *
  ***************************************/
 
-static void cirrus_pci_lfb_map(PCIDevice *d, int region_num,
-			       pcibus_t addr, pcibus_t size, int type)
-{
-    CirrusVGAState *s = &DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga;
-
-    /* XXX: add byte swapping apertures */
-    cpu_register_physical_memory(addr, s->vga.vram_size,
-				 s->cirrus_linear_io_addr);
-    cpu_register_physical_memory(addr + 0x1000000, 0x400000,
-				 s->cirrus_linear_bitblt_io_addr);
-
-    s->vga.map_addr = s->vga.map_end = 0;
-    s->vga.lfb_addr = addr & TARGET_PAGE_MASK;
-    s->vga.lfb_end = ((addr + VGA_RAM_SIZE) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
-    /* account for overflow */
-    if (s->vga.lfb_end < addr + VGA_RAM_SIZE)
-        s->vga.lfb_end = addr + VGA_RAM_SIZE;
-
-    vga_dirty_log_start(&s->vga);
-}
-
-static void pci_cirrus_write_config(PCIDevice *d,
-                                    uint32_t address, uint32_t val, int len)
-{
-    PCICirrusVGAState *pvs = DO_UPCAST(PCICirrusVGAState, dev, d);
-    CirrusVGAState *s = &pvs->cirrus_vga;
-
-    pci_default_write_config(d, address, val, len);
-    if (s->vga.map_addr && d->io_regions[0].addr == PCI_BAR_UNMAPPED) {
-        s->vga.map_addr = 0;
-        s->vga.lfb_addr = 0;
-        s->vga.lfb_end = 0;
-    }
-    cirrus_update_memory_access(s);
-}
-
 static int pci_cirrus_vga_initfn(PCIDevice *dev)
 {
      PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);
@@ -3112,15 +3170,21 @@  static int pci_cirrus_vga_initfn(PCIDevice *dev)
 
      /* setup PCI */
 
+    memory_region_init(&s->pci_bar, "cirrus-pci-bar0", 0x2000000);
+
+    /* XXX: add byte swapping apertures */
+    memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io);
+    memory_region_add_subregion(&s->pci_bar, 0x1000000,
+                                &s->cirrus_linear_bitblt_io);
+
      /* setup memory space */
      /* memory #0 LFB */
      /* memory #1 memory-mapped I/O */
      /* XXX: s->vga.vram_size must be a power of two */
-     pci_register_bar(&d->dev, 0, 0x2000000,
-                      PCI_BASE_ADDRESS_MEM_PREFETCH, cirrus_pci_lfb_map);
+     pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH,
+                             &s->pci_bar);
      if (device_id == CIRRUS_ID_CLGD5446) {
-         pci_register_bar_simple(&d->dev, 1, CIRRUS_PNPMMIO_SIZE, 0,
-                                 s->cirrus_mmio_io_addr);
+         pci_register_bar_region(&d->dev, 1, 0, &s->cirrus_mmio_io);
      }
      return 0;
 }
@@ -3138,7 +3202,6 @@  static PCIDeviceInfo cirrus_vga_info = {
     .no_hotplug   = 1,
     .init         = pci_cirrus_vga_initfn,
     .romfile      = VGABIOS_CIRRUS_FILENAME,
-    .config_write = pci_cirrus_write_config,
     .vendor_id    = PCI_VENDOR_ID_CIRRUS,
     .device_id    = CIRRUS_ID_CLGD5446,
     .class_id     = PCI_CLASS_DISPLAY_VGA,
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 1316066..4f626dc 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -86,7 +86,7 @@  void qxl_render_update(PCIQXLDevice *qxl)
         }
         qemu_free_displaysurface(vga->ds);
 
-        qxl->guest_primary.data = qemu_get_ram_ptr(qxl->vga.vram_offset);
+        qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
         if (qxl->guest_primary.stride < 0) {
             /* spice surface is upside down -> need extra buffer to flip */
             qxl->guest_primary.stride = -qxl->guest_primary.stride;
diff --git a/hw/qxl.c b/hw/qxl.c
index a6fb7f0..b17b58b 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -147,7 +147,7 @@  static ram_addr_t qxl_rom_size(void)
 
 static void init_qxl_rom(PCIQXLDevice *d)
 {
-    QXLRom *rom = qemu_get_ram_ptr(d->rom_offset);
+    QXLRom *rom = memory_region_get_ram_ptr(&d->rom_bar);
     QXLModes *modes = (QXLModes *)(rom + 1);
     uint32_t ram_header_size;
     uint32_t surface0_area_size;
@@ -223,39 +223,37 @@  static void init_qxl_ram(PCIQXLDevice *d)
 }
 
 /* can be called from spice server thread context */
-static void qxl_set_dirty(ram_addr_t addr, ram_addr_t end)
+static void qxl_set_dirty(MemoryRegion *mr, ram_addr_t addr, ram_addr_t end)
 {
     while (addr < end) {
-        cpu_physical_memory_set_dirty(addr);
+        memory_region_set_dirty(mr, addr);
         addr += TARGET_PAGE_SIZE;
     }
 }
 
 static void qxl_rom_set_dirty(PCIQXLDevice *qxl)
 {
-    ram_addr_t addr = qxl->rom_offset;
-    qxl_set_dirty(addr, addr + qxl->rom_size);
+    qxl_set_dirty(&qxl->rom_bar, 0, qxl->rom_size);
 }
 
 /* called from spice server thread context only */
 static void qxl_ram_set_dirty(PCIQXLDevice *qxl, void *ptr)
 {
-    ram_addr_t addr = qxl->vga.vram_offset;
     void *base = qxl->vga.vram_ptr;
     intptr_t offset;
 
     offset = ptr - base;
     offset &= ~(TARGET_PAGE_SIZE-1);
     assert(offset < qxl->vga.vram_size);
-    qxl_set_dirty(addr + offset, addr + offset + TARGET_PAGE_SIZE);
+    qxl_set_dirty(&qxl->vga.vram, offset, offset + TARGET_PAGE_SIZE);
 }
 
 /* can be called from spice server thread context */
 static void qxl_ring_set_dirty(PCIQXLDevice *qxl)
 {
-    ram_addr_t addr = qxl->vga.vram_offset + qxl->shadow_rom.ram_header_offset;
-    ram_addr_t end  = qxl->vga.vram_offset + qxl->vga.vram_size;
-    qxl_set_dirty(addr, end);
+    ram_addr_t addr = qxl->shadow_rom.ram_header_offset;
+    ram_addr_t end  = qxl->vga.vram_size;
+    qxl_set_dirty(&qxl->vga.vram, addr, end);
 }
 
 /*
@@ -629,20 +627,6 @@  static void qxl_set_irq(PCIQXLDevice *d)
     qxl_ring_set_dirty(d);
 }
 
-static void qxl_write_config(PCIDevice *d, uint32_t address,
-                             uint32_t val, int len)
-{
-    PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, d);
-    VGACommonState *vga = &qxl->vga;
-
-    vga_dirty_log_stop(vga);
-    pci_default_write_config(d, address, val, len);
-    if (vga->map_addr && qxl->pci.io_regions[0].addr == -1) {
-        vga->map_addr = 0;
-    }
-    vga_dirty_log_start(vga);
-}
-
 static void qxl_check_state(PCIQXLDevice *d)
 {
     QXLRam *ram = d->ram;
@@ -768,10 +752,10 @@  static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta)
 
     switch (pci_region) {
     case QXL_RAM_RANGE_INDEX:
-        virt_start = (intptr_t)qemu_get_ram_ptr(d->vga.vram_offset);
+        virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vga.vram);
         break;
     case QXL_VRAM_RANGE_INDEX:
-        virt_start = (intptr_t)qemu_get_ram_ptr(d->vram_offset);
+        virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vram_bar);
         break;
     default:
         /* should not happen */
@@ -931,10 +915,11 @@  static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
     qxl_rom_set_dirty(d);
 }
 
-static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void ioport_write(void *opaque, target_phys_addr_t addr,
+                         uint64_t val, unsigned size)
 {
     PCIQXLDevice *d = opaque;
-    uint32_t io_port = addr - d->io_base;
+    uint32_t io_port = addr;
 
     switch (io_port) {
     case QXL_IO_RESET:
@@ -982,7 +967,7 @@  static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
         d->oom_running = 0;
         break;
     case QXL_IO_SET_MODE:
-        dprint(d, 1, "QXL_SET_MODE %d\n", val);
+        dprint(d, 1, "QXL_SET_MODE %d\n", (int)val);
         qxl_set_mode(d, val, 0);
         break;
     case QXL_IO_LOG:
@@ -1027,7 +1012,8 @@  static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
-static uint32_t ioport_read(void *opaque, uint32_t addr)
+static uint64_t ioport_read(void *opaque, target_phys_addr_t addr,
+                            unsigned size)
 {
     PCIQXLDevice *d = opaque;
 
@@ -1035,42 +1021,14 @@  static uint32_t ioport_read(void *opaque, uint32_t addr)
     return 0xff;
 }
 
-static void qxl_map(PCIDevice *pci, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
-{
-    static const char *names[] = {
-        [ QXL_IO_RANGE_INDEX ]   = "ioports",
-        [ QXL_RAM_RANGE_INDEX ]  = "devram",
-        [ QXL_ROM_RANGE_INDEX ]  = "rom",
-        [ QXL_VRAM_RANGE_INDEX ] = "vram",
-    };
-    PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, pci);
-
-    dprint(qxl, 1, "%s: bar %d [%s] addr 0x%lx size 0x%lx\n", __FUNCTION__,
-            region_num, names[region_num], addr, size);
-
-    switch (region_num) {
-    case QXL_IO_RANGE_INDEX:
-        register_ioport_write(addr, size, 1, ioport_write, pci);
-        register_ioport_read(addr, size, 1, ioport_read, pci);
-        qxl->io_base = addr;
-        break;
-    case QXL_RAM_RANGE_INDEX:
-        cpu_register_physical_memory(addr, size, qxl->vga.vram_offset | IO_MEM_RAM);
-        qxl->vga.map_addr = addr;
-        qxl->vga.map_end = addr + size;
-        if (qxl->id == 0) {
-            vga_dirty_log_start(&qxl->vga);
-        }
-        break;
-    case QXL_ROM_RANGE_INDEX:
-        cpu_register_physical_memory(addr, size, qxl->rom_offset | IO_MEM_ROM);
-        break;
-    case QXL_VRAM_RANGE_INDEX:
-        cpu_register_physical_memory(addr, size, qxl->vram_offset | IO_MEM_RAM);
-        break;
-    }
-}
+static const MemoryRegionOps qxl_io_ops = {
+    .read = ioport_read,
+    .write = ioport_write,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
 
 static void pipe_read(void *opaque)
 {
@@ -1190,10 +1148,9 @@  static void qxl_vm_change_state_handler(void *opaque, int running, int reason)
          * to make sure they are saved */
         /* FIXME #1: should go out during "live" stage */
         /* FIXME #2: we only need to save the areas which are actually used */
-        ram_addr_t vram_addr = qxl->vram_offset;
-        ram_addr_t surface0_addr = qxl->vga.vram_offset + qxl->shadow_rom.draw_area_offset;
-        qxl_set_dirty(vram_addr, vram_addr + qxl->vram_size);
-        qxl_set_dirty(surface0_addr, surface0_addr + qxl->shadow_rom.surface0_area_size);
+        qxl_set_dirty(&qxl->vram_bar, 0, qxl->vram_size);
+        qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
+                      qxl->shadow_rom.surface0_area_size);
     }
 }
 
@@ -1251,7 +1208,8 @@  static int qxl_init_common(PCIQXLDevice *qxl)
     pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
 
     qxl->rom_size = qxl_rom_size();
-    qxl->rom_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vrom", qxl->rom_size);
+    memory_region_init_ram(&qxl->rom_bar, &qxl->pci.qdev, "qxl.vrom",
+                           qxl->rom_size);
     init_qxl_rom(qxl);
     init_qxl_ram(qxl);
 
@@ -1262,26 +1220,32 @@  static int qxl_init_common(PCIQXLDevice *qxl)
         qxl->vram_size = 4096;
     }
     qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1);
-    qxl->vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vram", qxl->vram_size);
+    memory_region_init_ram(&qxl->vram_bar, &qxl->pci.qdev, "qxl.vram",
+                           qxl->vram_size);
 
     io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1);
     if (qxl->revision == 1) {
         io_size = 8;
     }
 
-    pci_register_bar(&qxl->pci, QXL_IO_RANGE_INDEX,
-                     io_size, PCI_BASE_ADDRESS_SPACE_IO, qxl_map);
+    memory_region_init_io(&qxl->io_bar, &qxl_io_ops, qxl,
+                          "qxl-ioports", io_size);
+    if (qxl->id == 0) {
+        vga_dirty_log_start(&qxl->vga);
+    }
+
+
+    pci_register_bar_region(&qxl->pci, QXL_IO_RANGE_INDEX,
+                            PCI_BASE_ADDRESS_SPACE_IO, &qxl->io_bar);
 
-    pci_register_bar(&qxl->pci, QXL_ROM_RANGE_INDEX,
-                     qxl->rom_size, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                     qxl_map);
+    pci_register_bar_region(&qxl->pci, QXL_ROM_RANGE_INDEX,
+                            PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->rom_bar);
 
-    pci_register_bar(&qxl->pci, QXL_RAM_RANGE_INDEX,
-                     qxl->vga.vram_size, PCI_BASE_ADDRESS_SPACE_MEMORY,
-                     qxl_map);
+    pci_register_bar_region(&qxl->pci, QXL_RAM_RANGE_INDEX,
+                            PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vga.vram);
 
-    pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX, qxl->vram_size,
-                     PCI_BASE_ADDRESS_SPACE_MEMORY, qxl_map);
+    pci_register_bar_region(&qxl->pci, QXL_VRAM_RANGE_INDEX,
+                            PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vram_bar);
 
     qxl->ssd.qxl.base.sif = &qxl_interface.base;
     qxl->ssd.qxl.id = qxl->id;
@@ -1340,9 +1304,9 @@  static int qxl_init_secondary(PCIDevice *dev)
         ram_size = 16 * 1024 * 1024;
     }
     qxl->vga.vram_size = ram_size;
-    qxl->vga.vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vgavram",
-                                          qxl->vga.vram_size);
-    qxl->vga.vram_ptr = qemu_get_ram_ptr(qxl->vga.vram_offset);
+    memory_region_init_ram(&qxl->vga.vram, &qxl->pci.qdev, "qxl.vgavram",
+                           qxl->vga.vram_size);
+    qxl->vga.vram_ptr = memory_region_get_ram_ptr(&qxl->vga.vram);
 
     return qxl_init_common(qxl);
 }
@@ -1505,7 +1469,6 @@  static PCIDeviceInfo qxl_info_primary = {
     .qdev.vmsd    = &qxl_vmstate,
     .no_hotplug   = 1,
     .init         = qxl_init_primary,
-    .config_write = qxl_write_config,
     .romfile      = "vgabios-qxl.bin",
     .vendor_id    = REDHAT_PCI_VENDOR_ID,
     .device_id    = QXL_DEVICE_ID_STABLE,
diff --git a/hw/qxl.h b/hw/qxl.h
index f6c450d..987a5e7 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -72,14 +72,14 @@  typedef struct PCIQXLDevice {
     QXLRom             *rom;
     QXLModes           *modes;
     uint32_t           rom_size;
-    uint64_t           rom_offset;
+    MemoryRegion       rom_bar;
 
     /* vram pci bar */
     uint32_t           vram_size;
-    uint64_t           vram_offset;
+    MemoryRegion       vram_bar;
 
     /* io bar */
-    uint32_t           io_base;
+    MemoryRegion       io_bar;
 } PCIQXLDevice;
 
 #define PANIC_ON(x) if ((x)) {                         \
diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c
index 4954bb1..baa1e92 100644
--- a/hw/vga-isa-mm.c
+++ b/hw/vga-isa-mm.c
@@ -79,35 +79,46 @@  static void vga_mm_writel (void *opaque,
     vga_ioport_write(&s->vga, addr >> s->it_shift, value);
 }
 
-static CPUReadMemoryFunc * const vga_mm_read_ctrl[] = {
-    &vga_mm_readb,
-    &vga_mm_readw,
-    &vga_mm_readl,
+static const MemoryRegionOps vga_mm_ctrl_ops = {
+    .old_mmio = {
+        .read = {
+            vga_mm_readb,
+            vga_mm_readw,
+            vga_mm_readl,
+        },
+        .write = {
+            vga_mm_writeb,
+            vga_mm_writew,
+            vga_mm_writel,
+        },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUWriteMemoryFunc * const vga_mm_write_ctrl[] = {
-    &vga_mm_writeb,
-    &vga_mm_writew,
-    &vga_mm_writel,
-};
+#include "exec-memory.h"
 
 static void vga_mm_init(ISAVGAMMState *s, target_phys_addr_t vram_base,
                         target_phys_addr_t ctrl_base, int it_shift)
 {
-    int s_ioport_ctrl, vga_io_memory;
+    MemoryRegion *s_ioport_ctrl, *vga_io_memory;
 
     s->it_shift = it_shift;
-    s_ioport_ctrl = cpu_register_io_memory(vga_mm_read_ctrl, vga_mm_write_ctrl, s,
-                                           DEVICE_NATIVE_ENDIAN);
-    vga_io_memory = cpu_register_io_memory(vga_mem_read, vga_mem_write, s,
-                                           DEVICE_NATIVE_ENDIAN);
+    s_ioport_ctrl = qemu_malloc(sizeof(*s_ioport_ctrl));
+    memory_region_init_io(s_ioport_ctrl, &vga_mm_ctrl_ops, s,
+                          "vga-mm-ctrl", 0x100000);
+
+    vga_io_memory = qemu_malloc(sizeof(*vga_io_memory));
+    /* XXX: endianness? */
+    memory_region_init_io(vga_io_memory, &vga_mem_ops, &s->vga,
+                          "vga-mem", 0x20000);
 
     vmstate_register(NULL, 0, &vmstate_vga_common, s);
 
-    cpu_register_physical_memory(ctrl_base, 0x100000, s_ioport_ctrl);
+    memory_region_add_subregion(get_system_memory(), ctrl_base, s_ioport_ctrl);
     s->vga.bank_offset = 0;
-    cpu_register_physical_memory(vram_base + 0x000a0000, 0x20000, vga_io_memory);
-    qemu_register_coalesced_mmio(vram_base + 0x000a0000, 0x20000);
+    memory_region_add_subregion(get_system_memory(),
+                                vram_base + 0x000a0000, vga_io_memory);
+    memory_region_set_coalescing(vga_io_memory);
 }
 
 int isa_vga_mm_init(target_phys_addr_t vram_base,
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index 245841f..518cecc 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -42,17 +42,20 @@  static void vga_reset_isa(DeviceState *dev)
     vga_common_reset(s);
 }
 
+#include "exec-memory.h"
+
 static int vga_initfn(ISADevice *dev)
 {
     ISAVGAState *d = DO_UPCAST(ISAVGAState, dev, dev);
     VGACommonState *s = &d->state;
-    int vga_io_memory;
+    MemoryRegion *vga_io_memory;
 
     vga_common_init(s, VGA_RAM_SIZE);
     vga_io_memory = vga_init_io(s);
-    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
-                                 vga_io_memory);
-    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
+    memory_region_add_subregion_overlap(get_system_memory(),
+                                        isa_mem_base + 0x000a0000,
+                                        vga_io_memory, 1);
+    memory_region_set_coalescing(vga_io_memory);
     isa_init_ioport(dev, 0x3c0);
     isa_init_ioport(dev, 0x3b4);
     isa_init_ioport(dev, 0x3ba);
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index 481f448..7062c4d 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -47,29 +47,6 @@  static const VMStateDescription vmstate_vga_pci = {
     }
 };
 
-static void vga_map(PCIDevice *pci_dev, int region_num,
-                    pcibus_t addr, pcibus_t size, int type)
-{
-    PCIVGAState *d = (PCIVGAState *)pci_dev;
-    VGACommonState *s = &d->vga;
-
-    cpu_register_physical_memory(addr, s->vram_size, s->vram_offset);
-    s->map_addr = addr;
-    s->map_end = addr + s->vram_size;
-    vga_dirty_log_start(s);
-}
-
-static void pci_vga_write_config(PCIDevice *d,
-                                 uint32_t address, uint32_t val, int len)
-{
-    PCIVGAState *pvs = container_of(d, PCIVGAState, dev);
-    VGACommonState *s = &pvs->vga;
-
-    pci_default_write_config(d, address, val, len);
-    if (s->map_addr && pvs->dev.io_regions[0].addr == -1)
-        s->map_addr = 0;
-}
-
 static int pci_vga_initfn(PCIDevice *dev)
 {
      PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
@@ -83,8 +60,8 @@  static int pci_vga_initfn(PCIDevice *dev)
                                   s->screen_dump, s->text_update, s);
 
      /* XXX: VGA_RAM_SIZE must be a power of two */
-     pci_register_bar(&d->dev, 0, VGA_RAM_SIZE,
-                      PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map);
+     pci_register_bar_region(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH,
+                             &s->vram);
 
      if (!dev->rom_bar) {
          /* compatibility with pc-0.13 and older */
@@ -106,7 +83,6 @@  static PCIDeviceInfo vga_info = {
     .qdev.vmsd    = &vmstate_vga_pci,
     .no_hotplug   = 1,
     .init         = pci_vga_initfn,
-    .config_write = pci_vga_write_config,
     .romfile      = "vgabios-stdvga.bin",
 
     /* dummy VGA (same as Bochs ID) */
diff --git a/hw/vga.c b/hw/vga.c
index 0f54734..cdd8255 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -825,7 +825,7 @@  void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
             printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
 #endif
             s->plane_updated |= mask; /* only used to detect font change */
-            cpu_physical_memory_set_dirty(s->vram_offset + addr);
+            memory_region_set_dirty(&s->vram, addr);
         }
     } else if (s->gr[5] & 0x10) {
         /* odd/even mode (aka text mode mapping) */
@@ -838,7 +838,7 @@  void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
             printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
 #endif
             s->plane_updated |= mask; /* only used to detect font change */
-            cpu_physical_memory_set_dirty(s->vram_offset + addr);
+            memory_region_set_dirty(&s->vram, addr);
         }
     } else {
         /* standard VGA latched access */
@@ -912,7 +912,7 @@  void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
         printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n",
                addr * 4, write_mask, val);
 #endif
-        cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2));
+        memory_region_set_dirty(&s->vram, addr << 2);
     }
 }
 
@@ -1553,57 +1553,17 @@  void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
 
 static void vga_sync_dirty_bitmap(VGACommonState *s)
 {
-    if (s->map_addr)
-        cpu_physical_sync_dirty_bitmap(s->map_addr, s->map_end);
-
-    if (s->lfb_vram_mapped) {
-        cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa0000, 0xa8000);
-        cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa8000, 0xb0000);
-    }
-
-#ifdef CONFIG_BOCHS_VBE
-    if (s->vbe_mapped) {
-        cpu_physical_sync_dirty_bitmap(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
-                                       VBE_DISPI_LFB_PHYSICAL_ADDRESS + s->vram_size);
-    }
-#endif
-
+    memory_region_sync_dirty_bitmap(&s->vram);
 }
 
 void vga_dirty_log_start(VGACommonState *s)
 {
-    if (s->map_addr) {
-        cpu_physical_log_start(s->map_addr, s->map_end - s->map_addr);
-    }
-
-    if (s->lfb_vram_mapped) {
-        cpu_physical_log_start(isa_mem_base + 0xa0000, 0x8000);
-        cpu_physical_log_start(isa_mem_base + 0xa8000, 0x8000);
-    }
-
-#ifdef CONFIG_BOCHS_VBE
-    if (s->vbe_mapped) {
-        cpu_physical_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size);
-    }
-#endif
+    memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
 }
 
 void vga_dirty_log_stop(VGACommonState *s)
 {
-    if (s->map_addr) {
-        cpu_physical_log_stop(s->map_addr, s->map_end - s->map_addr);
-    }
-
-    if (s->lfb_vram_mapped) {
-        cpu_physical_log_stop(isa_mem_base + 0xa0000, 0x8000);
-        cpu_physical_log_stop(isa_mem_base + 0xa8000, 0x8000);
-    }
-
-#ifdef CONFIG_BOCHS_VBE
-    if (s->vbe_mapped) {
-        cpu_physical_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size);
-    }
-#endif
+    memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
 }
 
 void vga_dirty_log_restart(VGACommonState *s)
@@ -1773,15 +1733,16 @@  static void vga_draw_graphic(VGACommonState *s, int full_update)
         if (!(s->cr[0x17] & 2)) {
             addr = (addr & ~0x8000) | ((y1 & 2) << 14);
         }
-        page0 = s->vram_offset + (addr & TARGET_PAGE_MASK);
-        page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK);
+        page0 = addr & TARGET_PAGE_MASK;
+        page1 = (addr + bwidth - 1) & TARGET_PAGE_MASK;
         update = full_update |
-            cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) |
-            cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG);
+            memory_region_get_dirty(&s->vram, page0, DIRTY_MEMORY_VGA) |
+            memory_region_get_dirty(&s->vram, page1, DIRTY_MEMORY_VGA);
         if ((page1 - page0) > TARGET_PAGE_SIZE) {
             /* if wide line, can use another page */
-            update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE,
-                                                    VGA_DIRTY_FLAG);
+            update |= memory_region_get_dirty(&s->vram,
+                                              page0 + TARGET_PAGE_SIZE,
+                                              DIRTY_MEMORY_VGA);
         }
         /* explicit invalidation for the hardware cursor */
         update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
@@ -1826,8 +1787,10 @@  static void vga_draw_graphic(VGACommonState *s, int full_update)
     }
     /* reset modified pages */
     if (page_max >= page_min) {
-        cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE,
-                                        VGA_DIRTY_FLAG);
+        memory_region_reset_dirty(&s->vram,
+                                  page_min,
+                                  page_max + TARGET_PAGE_SIZE - page_min,
+                                  DIRTY_MEMORY_VGA);
     }
     memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
 }
@@ -1906,11 +1869,6 @@  static void vga_invalidate_display(void *opaque)
 
 void vga_common_reset(VGACommonState *s)
 {
-    s->lfb_addr = 0;
-    s->lfb_end = 0;
-    s->map_addr = 0;
-    s->map_end = 0;
-    s->lfb_vram_mapped = 0;
     s->sr_index = 0;
     memset(s->sr, '\0', sizeof(s->sr));
     s->gr_index = 0;
@@ -2141,16 +2099,36 @@  static void vga_update_text(void *opaque, console_ch_t *chardata)
     dpy_update(s->ds, 0, 0, s->last_width, height);
 }
 
-CPUReadMemoryFunc * const vga_mem_read[3] = {
-    vga_mem_readb,
-    vga_mem_readw,
-    vga_mem_readl,
-};
+static uint64_t vga_mem_read(void *opaque, target_phys_addr_t addr,
+                             unsigned size)
+{
+    VGACommonState *s = opaque;
+
+    switch (size) {
+    case 1: return vga_mem_readb(s, addr);
+    case 2: return vga_mem_readw(s, addr);
+    case 4: return vga_mem_readl(s, addr);
+    default: abort();
+    }
+}
+
+static void vga_mem_write(void *opaque, target_phys_addr_t addr,
+                          uint64_t data, unsigned size)
+{
+    VGACommonState *s = opaque;
+
+    switch (size) {
+    case 1: return vga_mem_writeb(s, addr, data);
+    case 2: return vga_mem_writew(s, addr, data);
+    case 4: return vga_mem_writel(s, addr, data);
+    default: abort();
+    }
+}
 
-CPUWriteMemoryFunc * const vga_mem_write[3] = {
-    vga_mem_writeb,
-    vga_mem_writew,
-    vga_mem_writel,
+const MemoryRegionOps vga_mem_ops = {
+    .read = vga_mem_read,
+    .write = vga_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static int vga_common_post_load(void *opaque, int version_id)
@@ -2236,8 +2214,8 @@  void vga_common_init(VGACommonState *s, int vga_ram_size)
 #else
     s->is_vbe_vmstate = 0;
 #endif
-    s->vram_offset = qemu_ram_alloc(NULL, "vga.vram", vga_ram_size);
-    s->vram_ptr = qemu_get_ram_ptr(s->vram_offset);
+    memory_region_init_ram(&s->vram, NULL, "vga.vram", vga_ram_size);
+    s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
     s->vram_size = vga_ram_size;
     s->get_bpp = vga_get_bpp;
     s->get_offsets = vga_get_offsets;
@@ -2257,11 +2235,14 @@  void vga_common_init(VGACommonState *s, int vga_ram_size)
         s->update_retrace_info = vga_precise_update_retrace_info;
         break;
     }
+    vga_dirty_log_start(s);
 }
 
 /* used by both ISA and PCI */
-int vga_init_io(VGACommonState *s)
+MemoryRegion *vga_init_io(VGACommonState *s)
 {
+    MemoryRegion *vga_mem;
+
     register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
 
     register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
@@ -2292,30 +2273,38 @@  int vga_init_io(VGACommonState *s)
 #endif
 #endif /* CONFIG_BOCHS_VBE */
 
-    return cpu_register_io_memory(vga_mem_read, vga_mem_write, s,
-                                  DEVICE_LITTLE_ENDIAN);
+    vga_mem = qemu_malloc(sizeof(*vga_mem));
+    memory_region_init_io(vga_mem, &vga_mem_ops, s,
+                          "vga-lowmem", 0x20000);
+
+    return vga_mem;
 }
 
+#include "exec-memory.h"
+
 void vga_init(VGACommonState *s)
 {
-    int vga_io_memory;
+    MemoryRegion *vga_io_memory;
 
     qemu_register_reset(vga_reset, s);
 
     s->bank_offset = 0;
 
     vga_io_memory = vga_init_io(s);
-    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
-                                 vga_io_memory);
-    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
+    memory_region_add_subregion_overlap(get_system_memory(),
+                                        isa_mem_base + 0x000a0000,
+                                        vga_io_memory,
+                                        1);
+    memory_region_set_coalescing(vga_io_memory);
 }
 
 void vga_init_vbe(VGACommonState *s)
 {
 #ifdef CONFIG_BOCHS_VBE
     /* XXX: use optimized standard vga accesses */
-    cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
-                                 VGA_RAM_SIZE, s->vram_offset);
+    memory_region_add_subregion(get_system_memory(),
+                                VBE_DISPI_LFB_PHYSICAL_ADDRESS,
+                                &s->vram);
     s->vbe_mapped = 1;
 #endif 
 }
diff --git a/hw/vga_int.h b/hw/vga_int.h
index eee91a8..4592d2c 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -23,6 +23,7 @@ 
  */
 
 #include <hw/hw.h>
+#include "memory.h"
 
 #define MSR_COLOR_EMULATION 0x01
 #define MSR_PAGE_SELECT     0x20
@@ -105,11 +106,7 @@  typedef void (* vga_update_retrace_info_fn)(struct VGACommonState *s);
 
 typedef struct VGACommonState {
     uint8_t *vram_ptr;
-    ram_addr_t vram_offset;
-    target_phys_addr_t lfb_addr;
-    target_phys_addr_t lfb_end;
-    target_phys_addr_t map_addr;
-    target_phys_addr_t map_end;
+    MemoryRegion vram;
     uint32_t vram_size;
     uint32_t latch;
     uint32_t lfb_vram_mapped; /* whether 0xa0000 is mapped as ram */
@@ -134,7 +131,7 @@  typedef struct VGACommonState {
     int dac_8bit;
     uint8_t palette[768];
     int32_t bank_offset;
-    int vga_io_memory;
+    MemoryRegion *vga_io_memory;
     int (*get_bpp)(struct VGACommonState *s);
     void (*get_offsets)(struct VGACommonState *s,
                         uint32_t *pline_offset,
@@ -191,7 +188,7 @@  static inline int c6_to_8(int v)
 
 void vga_common_init(VGACommonState *s, int vga_ram_size);
 void vga_init(VGACommonState *s);
-int vga_init_io(VGACommonState *s);
+MemoryRegion *vga_init_io(VGACommonState *s);
 void vga_common_reset(VGACommonState *s);
 
 void vga_dirty_log_start(VGACommonState *s);
@@ -229,5 +226,4 @@  extern const uint8_t gr_mask[16];
 #define VGABIOS_FILENAME "vgabios.bin"
 #define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin"
 
-extern CPUReadMemoryFunc * const vga_mem_read[3];
-extern CPUWriteMemoryFunc * const vga_mem_write[3];
+extern const MemoryRegionOps vga_mem_ops;
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 190b005..02b7478 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -65,10 +65,9 @@  struct vmsvga_state_s {
     int syncing;
     int fb_size;
 
-    ram_addr_t fifo_offset;
+    MemoryRegion fifo_ram;
     uint8_t *fifo_ptr;
     unsigned int fifo_size;
-    target_phys_addr_t fifo_base;
 
     union {
         uint32_t *fifo;
@@ -92,6 +91,7 @@  struct vmsvga_state_s {
 struct pci_vmsvga_state_s {
     PCIDevice card;
     struct vmsvga_state_s chip;
+    MemoryRegion io_bar;
 };
 
 #define SVGA_MAGIC		0x900000UL
@@ -789,8 +789,11 @@  static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
 #endif
         return caps;
 
-    case SVGA_REG_MEM_START:
-        return s->fifo_base;
+    case SVGA_REG_MEM_START: {
+        struct pci_vmsvga_state_s *pci_vmsvga
+            = container_of(s, struct pci_vmsvga_state_s, chip);
+        return pci_get_bar_addr(&pci_vmsvga->card, 2);
+    }
 
     case SVGA_REG_MEM_SIZE:
         return s->fifo_size;
@@ -1135,17 +1138,22 @@  static void vmsvga_vram_writel(void *opaque, target_phys_addr_t addr,
         *(uint32_t *) (s->vram_ptr + addr) = value;
 }
 
-static CPUReadMemoryFunc * const vmsvga_vram_read[] = {
-    vmsvga_vram_readb,
-    vmsvga_vram_readw,
-    vmsvga_vram_readl,
-};
+static const MemoryRegionOps vmsvga_vram_io_ops = {
+    .old_mmio = {
+        .read = {
+            vmsvga_vram_readb,
+            vmsvga_vram_readw,
+            vmsvga_vram_readl,
+        },
+        .write = {
+            vmsvga_vram_writeb,
+            vmsvga_vram_writew,
+            vmsvga_vram_writel,
+        },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
+}
 
-static CPUWriteMemoryFunc * const vmsvga_vram_write[] = {
-    vmsvga_vram_writeb,
-    vmsvga_vram_writew,
-    vmsvga_vram_writel,
-};
 #endif
 
 static int vmsvga_post_load(void *opaque, int version_id)
@@ -1211,8 +1219,8 @@  static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
 
 
     s->fifo_size = SVGA_FIFO_SIZE;
-    s->fifo_offset = qemu_ram_alloc(NULL, "vmsvga.fifo", s->fifo_size);
-    s->fifo_ptr = qemu_get_ram_ptr(s->fifo_offset);
+    memory_region_init_ram(&s->fifo_ram, NULL, "vmsvga.fifo", s->fifo_size);
+    s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram);
 
     vga_common_init(&s->vga, vga_ram_size);
     vga_init(&s->vga);
@@ -1221,79 +1229,76 @@  static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
     vmsvga_reset(s);
 }
 
-static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num,
-                pcibus_t addr, pcibus_t size, int type)
+static uint64_t vmsvga_io_read(void *opaque, target_phys_addr_t addr,
+                               unsigned size)
 {
-    struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
-    struct vmsvga_state_s *s = &d->chip;
-
-    register_ioport_read(addr + SVGA_IO_MUL * SVGA_INDEX_PORT,
-                    1, 4, vmsvga_index_read, s);
-    register_ioport_write(addr + SVGA_IO_MUL * SVGA_INDEX_PORT,
-                    1, 4, vmsvga_index_write, s);
-    register_ioport_read(addr + SVGA_IO_MUL * SVGA_VALUE_PORT,
-                    1, 4, vmsvga_value_read, s);
-    register_ioport_write(addr + SVGA_IO_MUL * SVGA_VALUE_PORT,
-                    1, 4, vmsvga_value_write, s);
-    register_ioport_read(addr + SVGA_IO_MUL * SVGA_BIOS_PORT,
-                    1, 4, vmsvga_bios_read, s);
-    register_ioport_write(addr + SVGA_IO_MUL * SVGA_BIOS_PORT,
-                    1, 4, vmsvga_bios_write, s);
+    struct vmsvga_state_s *s = opaque;
+
+    switch (addr) {
+    case SVGA_IO_MUL * SVGA_INDEX_PORT: return vmsvga_index_read(s, addr);
+    case SVGA_IO_MUL * SVGA_VALUE_PORT: return vmsvga_value_read(s, addr);
+    case SVGA_IO_MUL * SVGA_BIOS_PORT: return vmsvga_bios_read(s, addr);
+    default: return -1u;
+    }
 }
 
-static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num,
-                pcibus_t addr, pcibus_t size, int type)
+static void vmsvga_io_write(void *opaque, target_phys_addr_t addr,
+                            uint64_t data, unsigned size)
 {
-    struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
-    struct vmsvga_state_s *s = &d->chip;
-    ram_addr_t iomemtype;
-
-#ifdef DIRECT_VRAM
-    iomemtype = cpu_register_io_memory(vmsvga_vram_read,
-                    vmsvga_vram_write, s, DEVICE_NATIVE_ENDIAN);
-#else
-    iomemtype = s->vga.vram_offset | IO_MEM_RAM;
-#endif
-    cpu_register_physical_memory(addr, s->vga.vram_size,
-                    iomemtype);
+    struct vmsvga_state_s *s = opaque;
 
-    s->vga.map_addr = addr;
-    s->vga.map_end = addr + s->vga.vram_size;
-    vga_dirty_log_restart(&s->vga);
+    switch (addr) {
+    case SVGA_IO_MUL * SVGA_INDEX_PORT:
+        return vmsvga_index_write(s, addr, data);
+    case SVGA_IO_MUL * SVGA_VALUE_PORT:
+        return vmsvga_value_write(s, addr, data);
+    case SVGA_IO_MUL * SVGA_BIOS_PORT:
+        return vmsvga_bios_write(s, addr, data);
+    }
 }
 
-static void pci_vmsvga_map_fifo(PCIDevice *pci_dev, int region_num,
-                pcibus_t addr, pcibus_t size, int type)
-{
-    struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
-    struct vmsvga_state_s *s = &d->chip;
-    ram_addr_t iomemtype;
-
-    s->fifo_base = addr;
-    iomemtype = s->fifo_offset | IO_MEM_RAM;
-    cpu_register_physical_memory(s->fifo_base, s->fifo_size,
-                    iomemtype);
-}
+static const MemoryRegionOps vmsvga_io_ops = {
+    .read = vmsvga_io_read,
+    .write = vmsvga_io_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+};
 
 static int pci_vmsvga_initfn(PCIDevice *dev)
 {
     struct pci_vmsvga_state_s *s =
         DO_UPCAST(struct pci_vmsvga_state_s, card, dev);
+    MemoryRegion *iomem;
+
+#ifdef DIRECT_VRAM
+    DirectMem *directmem = qemu_malloc(sizeof(*directmem));
+
+    iomem = &directmem->mr;
+    memory_region_init_io(iomem, &vmsvga_vram_io_ops, &s->chip, "vmsvga",
+                          memory_region_size(&s->chip.vga.vram));
+#else
+    iomem = &s->chip.vga.vram;
+#endif
+
+    vga_dirty_log_restart(&s->chip.vga);
 
     s->card.config[PCI_CACHE_LINE_SIZE]	= 0x08;		/* Cache line size */
     s->card.config[PCI_LATENCY_TIMER] = 0x40;		/* Latency timer */
     s->card.config[PCI_INTERRUPT_LINE] = 0xff;		/* End */
 
-    pci_register_bar(&s->card, 0, 0x10,
-                    PCI_BASE_ADDRESS_SPACE_IO, pci_vmsvga_map_ioport);
-    pci_register_bar(&s->card, 1, VGA_RAM_SIZE,
-                    PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_mem);
-
-    pci_register_bar(&s->card, 2, SVGA_FIFO_SIZE,
-                    PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_fifo);
+    memory_region_init_io(&s->io_bar, &vmsvga_io_ops, &s->chip,
+                          "vmsvga-io", 0x10);
+    pci_register_bar_region(&s->card, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
 
     vmsvga_init(&s->chip, VGA_RAM_SIZE);
 
+    pci_register_bar_region(&s->card, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, iomem);
+    pci_register_bar_region(&s->card, 2, PCI_BASE_ADDRESS_MEM_PREFETCH,
+                            &s->chip.fifo_ram);
+
     if (!dev->rom_bar) {
         /* compatibility with pc-0.13 and older */
         vga_init_vbe(&s->chip.vga);