diff mbox

pflash_cfi01/pflash_cfi02: convert to memory API

Message ID 1314546216-26613-1-git-send-email-avi@redhat.com
State New
Headers show

Commit Message

Avi Kivity Aug. 28, 2011, 3:43 p.m. UTC
cfi02 is annoying in that is ignores some address bits; we probably
want explicit support in the memory API for that.

In order to get the correct opaque into the MemoryRegion object, the
allocation scheme is changed so that the flash emulation code allocates
memory, instead of the caller.  This clears a FIXME in the flash code.

Signed-off-by: Avi Kivity <avi@redhat.com>
---

This is a rework of the pflash conversion to the memory API.  It has changed
significantly - the change in allocation described above - so please review
carefully.

The mips_malta change also changes behavious - previously on of the two
aliases was mapped as rom/device while the other was mapped as plain rom.
Now both aliases are mapped as rom/device.  I'm guessing that this is the
right behaviour, and the old behaviour was just an implementation limitation,
but if someone can check, that would be even better.  That file has the most
sensitive changes so please review it extra carefully.

 hw/collie.c                   |    7 +--
 hw/flash.h                    |   11 ++++-
 hw/gumstix.c                  |    6 +--
 hw/lm32_boards.c              |    8 +---
 hw/mainstone.c                |    7 +--
 hw/milkymist.c                |    4 +-
 hw/mips_malta.c               |   44 +++++++++++++------
 hw/mips_r4k.c                 |   13 +++---
 hw/musicpal.c                 |    8 ++--
 hw/omap_sx1.c                 |    8 ++--
 hw/petalogix_ml605_mmu.c      |    5 +-
 hw/petalogix_s3adsp1800_mmu.c |    5 +-
 hw/pflash_cfi01.c             |   73 ++++++++++++-------------------
 hw/pflash_cfi02.c             |   95 +++++++++++++++++++++--------------------
 hw/ppc405_boards.c            |   49 ++++++++++++---------
 hw/r2d.c                      |    2 +-
 hw/virtex_ml507.c             |    4 +-
 hw/z2.c                       |    2 +-
 18 files changed, 174 insertions(+), 177 deletions(-)

Comments

Edgar E. Iglesias Aug. 28, 2011, 6:14 p.m. UTC | #1
On Sun, Aug 28, 2011 at 06:43:36PM +0300, Avi Kivity wrote:
> cfi02 is annoying in that is ignores some address bits; we probably
> want explicit support in the memory API for that.
> 
> In order to get the correct opaque into the MemoryRegion object, the
> allocation scheme is changed so that the flash emulation code allocates
> memory, instead of the caller.  This clears a FIXME in the flash code.
> 
> Signed-off-by: Avi Kivity <avi@redhat.com>
> ---
> 
> This is a rework of the pflash conversion to the memory API.  It has changed
> significantly - the change in allocation described above - so please review
> carefully.
> 
> The mips_malta change also changes behavious - previously on of the two
> aliases was mapped as rom/device while the other was mapped as plain rom.
> Now both aliases are mapped as rom/device.  I'm guessing that this is the
> right behaviour, and the old behaviour was just an implementation limitation,
> but if someone can check, that would be even better.  That file has the most
> sensitive changes so please review it extra carefully.

Regarding the flash mapping, your description matches my understanding of it.
There is a difference between the 0x1fc and the 0x1e0 mappings though, in that
reading from 0x1fc00010 does not map to the flash but instead gets decoded
into a read from a revision register. To read from the flash at 0x10, you
need to go via the 0x1e0 mapping.

That was never modelled by QEMU, instead the malta board writes into the
backing ram of the flash area, see:
/* Board ID = 0x420 (Malta Board with CoreLV)
   XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
   map to the board ID. */
stl_p(memory_region_get_ram_ptr(bios) + 0x10, 0x00000420);

I assume this will continue to work even after your changes but it would be
good to test it. I can check it.

A problem, with my compiler I see this:
qemu/hw/mips_malta.c: In function ‘mips_malta_init’:
qemu/hw/mips_malta.c:860:37: error: ‘bios’ may be used uninitialized in this function [-Werror=uninitialized]

Cheers
Edgar E. Iglesias Aug. 28, 2011, 6:46 p.m. UTC | #2
On Sun, Aug 28, 2011 at 8:14 PM, Edgar E. Iglesias <edgar.iglesias@gmail.com
> wrote:

> On Sun, Aug 28, 2011 at 06:43:36PM +0300, Avi Kivity wrote:
> > cfi02 is annoying in that is ignores some address bits; we probably
> > want explicit support in the memory API for that.
> >
> > In order to get the correct opaque into the MemoryRegion object, the
> > allocation scheme is changed so that the flash emulation code allocates
> > memory, instead of the caller.  This clears a FIXME in the flash code.
> >
> > Signed-off-by: Avi Kivity <avi@redhat.com>
> > ---
> >
> > This is a rework of the pflash conversion to the memory API.  It has
> changed
> > significantly - the change in allocation described above - so please
> review
> > carefully.
> >
> > The mips_malta change also changes behavious - previously on of the two
> > aliases was mapped as rom/device while the other was mapped as plain rom.
> > Now both aliases are mapped as rom/device.  I'm guessing that this is the
> > right behaviour, and the old behaviour was just an implementation
> limitation,
> > but if someone can check, that would be even better.  That file has the
> most
> > sensitive changes so please review it extra carefully.
>
> Regarding the flash mapping, your description matches my understanding of
> it.
> There is a difference between the 0x1fc and the 0x1e0 mappings though, in
> that
> reading from 0x1fc00010 does not map to the flash but instead gets decoded
> into a read from a revision register. To read from the flash at 0x10, you
> need to go via the 0x1e0 mapping.
>
> That was never modelled by QEMU, instead the malta board writes into the
> backing ram of the flash area, see:
> /* Board ID = 0x420 (Malta Board with CoreLV)
>   XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
>   map to the board ID. */
> stl_p(memory_region_get_ram_ptr(bios) + 0x10, 0x00000420);
>
> I assume this will continue to work even after your changes but it would be
> good to test it. I can check it.
>

The 0x10 hack still works as expected.

Cheers
Edgar E. Iglesias Aug. 28, 2011, 7:33 p.m. UTC | #3
On Sun, Aug 28, 2011 at 06:43:36PM +0300, Avi Kivity wrote:
> cfi02 is annoying in that is ignores some address bits; we probably
> want explicit support in the memory API for that.
> 
> In order to get the correct opaque into the MemoryRegion object, the
> allocation scheme is changed so that the flash emulation code allocates
> memory, instead of the caller.  This clears a FIXME in the flash code.

Hi Avi,

Something is going wrong with the flash devices. It can be reproduced
with the microblaze image on the wiki, you'll see the kernel complain
with:
pflash_write: Unimplemented flash cmd sequence (offset 00000000, wcycle 0x0 cmd 0x0 value 0xf0)
of-flash a0000000.flash: do_map_probe() failed

When it should be saying:
a0000000.flash: Found 1 x8 devices at 0x0 in 8-bit bank. Manufacturer ID 0x000000 Chip ID 0x000000
Intel/Sharp Extended Query Table at 0x0031

Cheers
Edgar E. Iglesias Aug. 28, 2011, 8:37 p.m. UTC | #4
On Sun, Aug 28, 2011 at 06:43:36PM +0300, Avi Kivity wrote:
> cfi02 is annoying in that is ignores some address bits; we probably
> want explicit support in the memory API for that.
> 
> In order to get the correct opaque into the MemoryRegion object, the
> allocation scheme is changed so that the flash emulation code allocates
> memory, instead of the caller.  This clears a FIXME in the flash code.
> 
> Signed-off-by: Avi Kivity <avi@redhat.com>
> ---



> diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c
> index 90e1301..b597304 100644
> --- a/hw/pflash_cfi01.c
> +++ b/hw/pflash_cfi01.c
> @@ -40,6 +40,7 @@
>  #include "flash.h"
>  #include "block.h"
>  #include "qemu-timer.h"
> +#include "exec-memory.h"
>  
>  #define PFLASH_BUG(fmt, ...) \
>  do { \
> @@ -74,8 +75,7 @@ struct pflash_t {
>      target_phys_addr_t counter;
>      unsigned int writeblock_size;
>      QEMUTimer *timer;
> -    ram_addr_t off;
> -    int fl_mem;
> +    MemoryRegion mem;
>      void *storage;
>  };
>  
> @@ -89,8 +89,7 @@ static void pflash_timer (void *opaque)
>      if (pfl->bypass) {
>          pfl->wcycle = 2;
>      } else {
> -        cpu_register_physical_memory(pfl->base, pfl->total_len,
> -                        pfl->off | IO_MEM_ROMD | pfl->fl_mem);
> +        memory_region_rom_device_set_readable(&pfl->mem, true);
>          pfl->wcycle = 0;
>      }
>      pfl->cmd = 0;
> @@ -263,7 +262,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
>  
>      if (!pfl->wcycle) {
>          /* Set the device in I/O access mode */
> -        cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem);
> +        memory_region_rom_device_set_readable(&pfl->mem, false);
>      }

I get the impression that this one is not biting. Reads are not reaching
the IO callbacks at times when they should..

Cheers
Avi Kivity Aug. 29, 2011, 5:35 a.m. UTC | #5
On 08/28/2011 09:14 PM, Edgar E. Iglesias wrote:
> On Sun, Aug 28, 2011 at 06:43:36PM +0300, Avi Kivity wrote:
> >  cfi02 is annoying in that is ignores some address bits; we probably
> >  want explicit support in the memory API for that.
> >
> >  In order to get the correct opaque into the MemoryRegion object, the
> >  allocation scheme is changed so that the flash emulation code allocates
> >  memory, instead of the caller.  This clears a FIXME in the flash code.
> >
> >  Signed-off-by: Avi Kivity<avi@redhat.com>
> >  ---
> >
> >  This is a rework of the pflash conversion to the memory API.  It has changed
> >  significantly - the change in allocation described above - so please review
> >  carefully.
> >
> >  The mips_malta change also changes behavious - previously on of the two
> >  aliases was mapped as rom/device while the other was mapped as plain rom.
> >  Now both aliases are mapped as rom/device.  I'm guessing that this is the
> >  right behaviour, and the old behaviour was just an implementation limitation,
> >  but if someone can check, that would be even better.  That file has the most
> >  sensitive changes so please review it extra carefully.
>
> Regarding the flash mapping, your description matches my understanding of it.
> There is a difference between the 0x1fc and the 0x1e0 mappings though, in that
> reading from 0x1fc00010 does not map to the flash but instead gets decoded
> into a read from a revision register. To read from the flash at 0x10, you
> need to go via the 0x1e0 mapping.
>
> That was never modelled by QEMU, instead the malta board writes into the
> backing ram of the flash area, see:
> /* Board ID = 0x420 (Malta Board with CoreLV)
>     XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
>     map to the board ID. */
> stl_p(memory_region_get_ram_ptr(bios) + 0x10, 0x00000420);

This can be modelled correctly, using a container and a new region for 
0x10-0x14.  I'll live that as an exercise to the interested writer.

> I assume this will continue to work even after your changes but it would be
> good to test it. I can check it.
>
> A problem, with my compiler I see this:
> qemu/hw/mips_malta.c: In function ‘mips_malta_init’:
> qemu/hw/mips_malta.c:860:37: error: ‘bios’ may be used uninitialized in this function [-Werror=uninitialized]
>

Thanks, I have a fix for this and will post an updated patch once the 
other issues are resolved.
Avi Kivity Aug. 29, 2011, 5:36 a.m. UTC | #6
On 08/28/2011 10:33 PM, Edgar E. Iglesias wrote:
> On Sun, Aug 28, 2011 at 06:43:36PM +0300, Avi Kivity wrote:
> >  cfi02 is annoying in that is ignores some address bits; we probably
> >  want explicit support in the memory API for that.
> >
> >  In order to get the correct opaque into the MemoryRegion object, the
> >  allocation scheme is changed so that the flash emulation code allocates
> >  memory, instead of the caller.  This clears a FIXME in the flash code.
>
> Hi Avi,
>
> Something is going wrong with the flash devices. It can be reproduced
> with the microblaze image on the wiki, you'll see the kernel complain
> with:
> pflash_write: Unimplemented flash cmd sequence (offset 00000000, wcycle 0x0 cmd 0x0 value 0xf0)
> of-flash a0000000.flash: do_map_probe() failed
>
> When it should be saying:
> a0000000.flash: Found 1 x8 devices at 0x0 in 8-bit bank. Manufacturer ID 0x000000 Chip ID 0x000000
> Intel/Sharp Extended Query Table at 0x0031
>
>

I get exactly the same behaviour with upstream - 9f94778.  With what 
version does it work correctly?
Avi Kivity Aug. 29, 2011, 5:38 a.m. UTC | #7
On 08/28/2011 11:37 PM, Edgar E. Iglesias wrote:
> On Sun, Aug 28, 2011 at 06:43:36PM +0300, Avi Kivity wrote:
> >  cfi02 is annoying in that is ignores some address bits; we probably
> >  want explicit support in the memory API for that.
> >
> >  In order to get the correct opaque into the MemoryRegion object, the
> >  allocation scheme is changed so that the flash emulation code allocates
> >  memory, instead of the caller.  This clears a FIXME in the flash code.
> >
> >  Signed-off-by: Avi Kivity<avi@redhat.com>
> >  ---
>
>
>
> >  diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c
> >  index 90e1301..b597304 100644
> >  --- a/hw/pflash_cfi01.c
> >  +++ b/hw/pflash_cfi01.c
> >  @@ -40,6 +40,7 @@
> >   #include "flash.h"
> >   #include "block.h"
> >   #include "qemu-timer.h"
> >  +#include "exec-memory.h"
> >
> >   #define PFLASH_BUG(fmt, ...) \
> >   do { \
> >  @@ -74,8 +75,7 @@ struct pflash_t {
> >       target_phys_addr_t counter;
> >       unsigned int writeblock_size;
> >       QEMUTimer *timer;
> >  -    ram_addr_t off;
> >  -    int fl_mem;
> >  +    MemoryRegion mem;
> >       void *storage;
> >   };
> >
> >  @@ -89,8 +89,7 @@ static void pflash_timer (void *opaque)
> >       if (pfl->bypass) {
> >           pfl->wcycle = 2;
> >       } else {
> >  -        cpu_register_physical_memory(pfl->base, pfl->total_len,
> >  -                        pfl->off | IO_MEM_ROMD | pfl->fl_mem);
> >  +        memory_region_rom_device_set_readable(&pfl->mem, true);
> >           pfl->wcycle = 0;
> >       }
> >       pfl->cmd = 0;
> >  @@ -263,7 +262,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
> >
> >       if (!pfl->wcycle) {
> >           /* Set the device in I/O access mode */
> >  -        cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem);
> >  +        memory_region_rom_device_set_readable(&pfl->mem, false);
> >       }
>
> I get the impression that this one is not biting. Reads are not reaching
> the IO callbacks at times when they should..
>

It does bite, as I saw with gdb.  You can even see that from the qemu 
error - it complains about unimplemented command 0xf0, that comes from 
pflash_write() later on.
Edgar E. Iglesias Aug. 29, 2011, 6 a.m. UTC | #8
On Mon, Aug 29, 2011 at 08:38:26AM +0300, Avi Kivity wrote:
> On 08/28/2011 11:37 PM, Edgar E. Iglesias wrote:
> >On Sun, Aug 28, 2011 at 06:43:36PM +0300, Avi Kivity wrote:
> >>  cfi02 is annoying in that is ignores some address bits; we probably
> >>  want explicit support in the memory API for that.
> >>
> >>  In order to get the correct opaque into the MemoryRegion object, the
> >>  allocation scheme is changed so that the flash emulation code allocates
> >>  memory, instead of the caller.  This clears a FIXME in the flash code.
> >>
> >>  Signed-off-by: Avi Kivity<avi@redhat.com>
> >>  ---
> >
> >
> >
> >>  diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c
> >>  index 90e1301..b597304 100644
> >>  --- a/hw/pflash_cfi01.c
> >>  +++ b/hw/pflash_cfi01.c
> >>  @@ -40,6 +40,7 @@
> >>   #include "flash.h"
> >>   #include "block.h"
> >>   #include "qemu-timer.h"
> >>  +#include "exec-memory.h"
> >>
> >>   #define PFLASH_BUG(fmt, ...) \
> >>   do { \
> >>  @@ -74,8 +75,7 @@ struct pflash_t {
> >>       target_phys_addr_t counter;
> >>       unsigned int writeblock_size;
> >>       QEMUTimer *timer;
> >>  -    ram_addr_t off;
> >>  -    int fl_mem;
> >>  +    MemoryRegion mem;
> >>       void *storage;
> >>   };
> >>
> >>  @@ -89,8 +89,7 @@ static void pflash_timer (void *opaque)
> >>       if (pfl->bypass) {
> >>           pfl->wcycle = 2;
> >>       } else {
> >>  -        cpu_register_physical_memory(pfl->base, pfl->total_len,
> >>  -                        pfl->off | IO_MEM_ROMD | pfl->fl_mem);
> >>  +        memory_region_rom_device_set_readable(&pfl->mem, true);
> >>           pfl->wcycle = 0;
> >>       }
> >>       pfl->cmd = 0;
> >>  @@ -263,7 +262,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
> >>
> >>       if (!pfl->wcycle) {
> >>           /* Set the device in I/O access mode */
> >>  -        cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem);
> >>  +        memory_region_rom_device_set_readable(&pfl->mem, false);
> >>       }
> >
> >I get the impression that this one is not biting. Reads are not reaching
> >the IO callbacks at times when they should..
> >
> 
> It does bite, as I saw with gdb.  You can even see that from the
> qemu error - it complains about unimplemented command 0xf0, that
> comes from pflash_write() later on.

I wasn't clear enough maybe, the code in question is running, but the
set_readble is not having any effect AFAICT. The reads, that
should come through via IO callbacks when switching mode are
not getting through. Do you ever see pflash_read beeing called?

Cheers
Edgar E. Iglesias Aug. 29, 2011, 6:04 a.m. UTC | #9
On Mon, Aug 29, 2011 at 08:36:14AM +0300, Avi Kivity wrote:
> On 08/28/2011 10:33 PM, Edgar E. Iglesias wrote:
> >On Sun, Aug 28, 2011 at 06:43:36PM +0300, Avi Kivity wrote:
> >>  cfi02 is annoying in that is ignores some address bits; we probably
> >>  want explicit support in the memory API for that.
> >>
> >>  In order to get the correct opaque into the MemoryRegion object, the
> >>  allocation scheme is changed so that the flash emulation code allocates
> >>  memory, instead of the caller.  This clears a FIXME in the flash code.
> >
> >Hi Avi,
> >
> >Something is going wrong with the flash devices. It can be reproduced
> >with the microblaze image on the wiki, you'll see the kernel complain
> >with:
> >pflash_write: Unimplemented flash cmd sequence (offset 00000000, wcycle 0x0 cmd 0x0 value 0xf0)
> >of-flash a0000000.flash: do_map_probe() failed
> >
> >When it should be saying:
> >a0000000.flash: Found 1 x8 devices at 0x0 in 8-bit bank. Manufacturer ID 0x000000 Chip ID 0x000000
> >Intel/Sharp Extended Query Table at 0x0031
> >
> >
> 
> I get exactly the same behaviour with upstream - 9f94778.  With what
> version does it work correctly?

Im on a slightly patched tree, will try clean upstream versions.
Maybe the flashes never worked with that board in upstream... :/

Cheers
Edgar E. Iglesias Aug. 29, 2011, 6:13 a.m. UTC | #10
On Mon, Aug 29, 2011 at 08:36:14AM +0300, Avi Kivity wrote:
> On 08/28/2011 10:33 PM, Edgar E. Iglesias wrote:
> >On Sun, Aug 28, 2011 at 06:43:36PM +0300, Avi Kivity wrote:
> >>  cfi02 is annoying in that is ignores some address bits; we probably
> >>  want explicit support in the memory API for that.
> >>
> >>  In order to get the correct opaque into the MemoryRegion object, the
> >>  allocation scheme is changed so that the flash emulation code allocates
> >>  memory, instead of the caller.  This clears a FIXME in the flash code.
> >
> >Hi Avi,
> >
> >Something is going wrong with the flash devices. It can be reproduced
> >with the microblaze image on the wiki, you'll see the kernel complain
> >with:
> >pflash_write: Unimplemented flash cmd sequence (offset 00000000, wcycle 0x0 cmd 0x0 value 0xf0)
> >of-flash a0000000.flash: do_map_probe() failed
> >
> >When it should be saying:
> >a0000000.flash: Found 1 x8 devices at 0x0 in 8-bit bank. Manufacturer ID 0x000000 Chip ID 0x000000
> >Intel/Sharp Extended Query Table at 0x0031
> >
> >
> 
> I get exactly the same behaviour with upstream - 9f94778.  With what
> version does it work correctly?

With:
commit 9f94778c1603420e48d779a495e84eb82945cc75
Author: Artyom Tarasenko <atar4qemu@gmail.com>
Date:   Mon Jul 25 19:22:38 2011 +0200

    Fix disabling interrupts in sun4u
    
    clear interrupt request if the interrupt priority < CPU pil
    clear hardware interrupt request if interrupts are disabled
    
    Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
    [blauwirbel@gmail.com: added a comment about magic 2]
    Signed-off-by: Blue Swirl <blauwirbel@gmail.com>


It works, with some qemu complaints about non uinmplemented sequences,
but the flashes are found.

pflash_write: Unimplemented flash cmd sequence (offset 00000000, wcycle 0x0 cmd 0x0 value 0xf0)
[    0.596261] a0000000.flash: Found 1 x8 devices at 0x0 in 8-bit bank
[    0.597003]  Intel/Sharp Extended Query Table at 0x0031
pflash_write: Unimplemented flash cmd sequence (offset 00000000, wcycle 0x0 cmd 0x0 value 0xf0)


With GDB I see pflash_read, beeing called.

With, the latest patches applied:

commit f38f0030afddba4c9df42bdb25ce123c41aafeb6
Author: Avi Kivity <avi@redhat.com>
Date:   Sun Aug 28 18:43:36 2011 +0300

    pflash_cfi01/pflash_cfi02: convert to memory API
    
    cfi02 is annoying in that is ignores some address bits; we probably
    want explicit support in the memory API for that.
    
    In order to get the correct opaque into the MemoryRegion object, the
    allocation scheme is changed so that the flash emulation code allocates
    memory, instead of the caller.  This clears a FIXME in the flash code.
    
    Signed-off-by: Avi Kivity <avi@redhat.com>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>

commit 6f997f56903060383ddc7672c33fc3d40dfd9cb9
Merge: 9f94778 75f5941
Author: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Date:   Sun Aug 28 19:29:16 2011 +0200

    Merge branch 'memory/core' of git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm



I see the following:
pflash_write: Unimplemented flash cmd sequence (offset 00000000, wcycle 0x0 cmd 0x0 value 0xf0)
[    0.605584] of-flash a0000000.flash: do_map_probe() failed

The flash is never found.

And, pflash_read is never called.

The set_readable doesnt seem to bite..

Hope this helps..

Cheers
Avi Kivity Aug. 29, 2011, 6:15 a.m. UTC | #11
On 08/29/2011 09:00 AM, Edgar E. Iglesias wrote:
> >
> >  It does bite, as I saw with gdb.  You can even see that from the
> >  qemu error - it complains about unimplemented command 0xf0, that
> >  comes from pflash_write() later on.
>
> I wasn't clear enough maybe, the code in question is running, but the
> set_readble is not having any effect AFAICT. The reads, that
> should come through via IO callbacks when switching mode are
> not getting through. Do you ever see pflash_read beeing called?
>

Thanks for the clarification.  I don't, and there is now a fix on

   git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git

Please check it out.
Edgar E. Iglesias Aug. 29, 2011, 6:18 a.m. UTC | #12
On Mon, Aug 29, 2011 at 09:15:40AM +0300, Avi Kivity wrote:
> On 08/29/2011 09:00 AM, Edgar E. Iglesias wrote:
> >>
> >>  It does bite, as I saw with gdb.  You can even see that from the
> >>  qemu error - it complains about unimplemented command 0xf0, that
> >>  comes from pflash_write() later on.
> >
> >I wasn't clear enough maybe, the code in question is running, but the
> >set_readble is not having any effect AFAICT. The reads, that
> >should come through via IO callbacks when switching mode are
> >not getting through. Do you ever see pflash_read beeing called?
> >
> 
> Thanks for the clarification.  I don't, and there is now a fix on
> 
>   git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git
> 
> Please check it out.

Great, have to run now, but I'll try it out later today.

Cheers
Avi Kivity Aug. 29, 2011, 7:21 a.m. UTC | #13
On 08/29/2011 09:15 AM, Avi Kivity wrote:
> On 08/29/2011 09:00 AM, Edgar E. Iglesias wrote:
>> >
>> >  It does bite, as I saw with gdb.  You can even see that from the
>> >  qemu error - it complains about unimplemented command 0xf0, that
>> >  comes from pflash_write() later on.
>>
>> I wasn't clear enough maybe, the code in question is running, but the
>> set_readble is not having any effect AFAICT. The reads, that
>> should come through via IO callbacks when switching mode are
>> not getting through. Do you ever see pflash_read beeing called?
>>
>
> Thanks for the clarification.  I don't, and there is now a fix on
>
>   git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git
>

Forgot the branch:

   git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git  fix-pflash
Edgar E. Iglesias Aug. 29, 2011, 7:30 a.m. UTC | #14
On Mon, Aug 29, 2011 at 10:21:03AM +0300, Avi Kivity wrote:
> On 08/29/2011 09:15 AM, Avi Kivity wrote:
> > On 08/29/2011 09:00 AM, Edgar E. Iglesias wrote:
> >> >
> >> >  It does bite, as I saw with gdb.  You can even see that from the
> >> >  qemu error - it complains about unimplemented command 0xf0, that
> >> >  comes from pflash_write() later on.
> >>
> >> I wasn't clear enough maybe, the code in question is running, but the
> >> set_readble is not having any effect AFAICT. The reads, that
> >> should come through via IO callbacks when switching mode are
> >> not getting through. Do you ever see pflash_read beeing called?
> >>
> >
> > Thanks for the clarification.  I don't, and there is now a fix on
> >
> >   git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git
> >
> 
> Forgot the branch:
> 
>    git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git  fix-pflash


That works

Thanks
Avi Kivity Aug. 29, 2011, 8:15 a.m. UTC | #15
On 08/29/2011 10:30 AM, Edgar E. Iglesias wrote:
> >
> >  Forgot the branch:
> >
> >     git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git  fix-pflash
>
>
> That works
>

Thanks for all the testing and help.  I'll post the fixes for merging soon.
diff mbox

Patch

diff --git a/hw/collie.c b/hw/collie.c
index 156404d..a10cc1b 100644
--- a/hw/collie.c
+++ b/hw/collie.c
@@ -26,7 +26,6 @@  static void collie_init(ram_addr_t ram_size,
 {
     StrongARMState *s;
     DriveInfo *dinfo;
-    ram_addr_t phys_flash;
 
     if (!cpu_model) {
         cpu_model = "sa1110";
@@ -34,15 +33,13 @@  static void collie_init(ram_addr_t ram_size,
 
     s = sa1110_init(collie_binfo.ram_size, cpu_model);
 
-    phys_flash = qemu_ram_alloc(NULL, "collie.fl1", 0x02000000);
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    pflash_cfi01_register(SA_CS0, phys_flash,
+    pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x02000000,
                     dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                     512, 4, 0x00, 0x00, 0x00, 0x00, 0);
 
-    phys_flash = qemu_ram_alloc(NULL, "collie.fl2", 0x02000000);
     dinfo = drive_get(IF_PFLASH, 0, 1);
-    pflash_cfi01_register(SA_CS1, phys_flash,
+    pflash_cfi01_register(SA_CS1, NULL, "collie.fl2", 0x02000000,
                     dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                     512, 4, 0x00, 0x00, 0x00, 0x00, 0);
 
diff --git a/hw/flash.h b/hw/flash.h
index 140ae39..f92f58a 100644
--- a/hw/flash.h
+++ b/hw/flash.h
@@ -1,15 +1,22 @@ 
 /* NOR flash devices */
+
+#include "memory.h"
+
 typedef struct pflash_t pflash_t;
 
 /* pflash_cfi01.c */
-pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
+pflash_t *pflash_cfi01_register(target_phys_addr_t base,
+                                DeviceState *qdev, const char *name,
+                                target_phys_addr_t size,
                                 BlockDriverState *bs,
                                 uint32_t sector_len, int nb_blocs, int width,
                                 uint16_t id0, uint16_t id1,
                                 uint16_t id2, uint16_t id3, int be);
 
 /* pflash_cfi02.c */
-pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
+pflash_t *pflash_cfi02_register(target_phys_addr_t base,
+                                DeviceState *qdev, const char *name,
+                                target_phys_addr_t size,
                                 BlockDriverState *bs, uint32_t sector_len,
                                 int nb_blocs, int nb_mappings, int width,
                                 uint16_t id0, uint16_t id1,
diff --git a/hw/gumstix.c b/hw/gumstix.c
index 853f7e1..b8b76f4 100644
--- a/hw/gumstix.c
+++ b/hw/gumstix.c
@@ -67,8 +67,7 @@  static void connex_init(ram_addr_t ram_size,
 #else
     be = 0;
 #endif
-    if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "connext.rom",
-                                                          connex_rom),
+    if (!pflash_cfi01_register(0x00000000, NULL, "connext.rom", connex_rom,
                                dinfo->bdrv, sector_len, connex_rom / sector_len,
                                2, 0, 0, 0, 0, be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
@@ -106,8 +105,7 @@  static void verdex_init(ram_addr_t ram_size,
 #else
     be = 0;
 #endif
-    if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "verdex.rom",
-                                                          verdex_rom),
+    if (!pflash_cfi01_register(0x00000000, NULL, "verdex.rom", verdex_rom,
                                dinfo->bdrv, sector_len, verdex_rom / sector_len,
                                2, 0, 0, 0, 0, be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
diff --git a/hw/lm32_boards.c b/hw/lm32_boards.c
index d18aad7..e4acac1 100644
--- a/hw/lm32_boards.c
+++ b/hw/lm32_boards.c
@@ -77,7 +77,6 @@  static void lm32_evr_init(ram_addr_t ram_size_not_used,
     CPUState *env;
     DriveInfo *dinfo;
     ram_addr_t phys_ram;
-    ram_addr_t phys_flash;
     qemu_irq *cpu_irq, irq[32];
     ResetInfo *reset_info;
     int i;
@@ -108,10 +107,9 @@  static void lm32_evr_init(ram_addr_t ram_size_not_used,
     phys_ram = qemu_ram_alloc(NULL, "lm32_evr.sdram", ram_size);
     cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "lm32_evr.flash", flash_size);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Spansion S29NS128P */
-    pflash_cfi02_register(flash_base, phys_flash,
+    pflash_cfi02_register(flash_base, NULL, "lm32_evr.flash", flash_size,
                           dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                           flash_size / flash_sector_size, 1, 2,
                           0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
@@ -165,7 +163,6 @@  static void lm32_uclinux_init(ram_addr_t ram_size_not_used,
     CPUState *env;
     DriveInfo *dinfo;
     ram_addr_t phys_ram;
-    ram_addr_t phys_flash;
     qemu_irq *cpu_irq, irq[32];
     HWSetup *hw;
     ResetInfo *reset_info;
@@ -203,10 +200,9 @@  static void lm32_uclinux_init(ram_addr_t ram_size_not_used,
     phys_ram = qemu_ram_alloc(NULL, "lm32_uclinux.sdram", ram_size);
     cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "lm32_uclinux.flash", flash_size);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Spansion S29NS128P */
-    pflash_cfi02_register(flash_base, phys_flash,
+    pflash_cfi02_register(flash_base, NULL, "lm32_uclinux.flash", flash_size,
                           dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                           flash_size / flash_sector_size, 1, 2,
                           0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
diff --git a/hw/mainstone.c b/hw/mainstone.c
index 4792f0e..c0524d7 100644
--- a/hw/mainstone.c
+++ b/hw/mainstone.c
@@ -126,10 +126,9 @@  static void mainstone_common_init(ram_addr_t ram_size,
             exit(1);
         }
 
-        if (!pflash_cfi01_register(mainstone_flash_base[i],
-                                   qemu_ram_alloc(NULL, i ? "mainstone.flash1" :
-                                                  "mainstone.flash0",
-                                                  MAINSTONE_FLASH),
+        if (!pflash_cfi01_register(mainstone_flash_base[i], NULL,
+                                   i ? "mainstone.flash1" : "mainstone.flash0",
+                                   MAINSTONE_FLASH,
                                    dinfo->bdrv, sector_len,
                                    MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0,
                                    be)) {
diff --git a/hw/milkymist.c b/hw/milkymist.c
index 93288c8..a44b80c 100644
--- a/hw/milkymist.c
+++ b/hw/milkymist.c
@@ -82,7 +82,6 @@  milkymist_init(ram_addr_t ram_size_not_used,
     int kernel_size;
     DriveInfo *dinfo;
     ram_addr_t phys_sdram;
-    ram_addr_t phys_flash;
     qemu_irq irq[32], *cpu_irq;
     int i;
     char *bios_filename;
@@ -113,10 +112,9 @@  milkymist_init(ram_addr_t ram_size_not_used,
     cpu_register_physical_memory(sdram_base, sdram_size,
             phys_sdram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "milkymist.flash", flash_size);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Numonyx JS28F256J3F105 */
-    pflash_cfi01_register(flash_base, phys_flash,
+    pflash_cfi01_register(flash_base, NULL, "milkymist.flash", flash_size,
                           dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                           flash_size / flash_sector_size, 2,
                           0x00, 0x89, 0x00, 0x1d, 1);
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 86a8ba0..9762a57 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -46,6 +46,7 @@ 
 #include "elf.h"
 #include "mc146818rtc.h"
 #include "blockdev.h"
+#include "exec-memory.h"
 
 //#define DEBUG_BOARD_INIT
 
@@ -762,7 +763,8 @@  void mips_malta_init (ram_addr_t ram_size,
 {
     char *filename;
     ram_addr_t ram_offset;
-    ram_addr_t bios_offset;
+    MemoryRegion *system_memory = get_system_memory();
+    MemoryRegion *bios, *bios_alias = g_new(MemoryRegion, 1);
     target_long bios_size;
     int64_t kernel_entry;
     PCIBus *pci_bus;
@@ -811,17 +813,9 @@  void mips_malta_init (ram_addr_t ram_size,
         exit(1);
     }
     ram_offset = qemu_ram_alloc(NULL, "mips_malta.ram", ram_size);
-    bios_offset = qemu_ram_alloc(NULL, "mips_malta.bios", BIOS_SIZE);
-
 
     cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
 
-    /* Map the bios at two physical locations, as on the real board. */
-    cpu_register_physical_memory(0x1e000000LL,
-                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
-    cpu_register_physical_memory(0x1fc00000LL,
-                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
-
 #ifdef TARGET_WORDS_BIGENDIAN
     be = 1;
 #else
@@ -833,12 +827,19 @@  void mips_malta_init (ram_addr_t ram_size,
     /* Load firmware in flash / BIOS unless we boot directly into a kernel. */
     if (kernel_filename) {
         /* Write a small bootloader to the flash location. */
+        bios = g_new(MemoryRegion, 1);
+        memory_region_init_ram(bios, NULL, "mips_malta.bios", BIOS_SIZE);
+        memory_region_set_readonly(bios, true);
+        memory_region_init_alias(bios_alias, "bios.1fc", bios, 0, BIOS_SIZE);
+        /* Map the bios at two physical locations, as on the real board. */
+        memory_region_add_subregion(system_memory, 0x1e000000LL, bios);
+        memory_region_add_subregion(system_memory, 0x1fc00000LL, bios_alias);
         loaderparams.ram_size = ram_size;
         loaderparams.kernel_filename = kernel_filename;
         loaderparams.kernel_cmdline = kernel_cmdline;
         loaderparams.initrd_filename = initrd_filename;
         kernel_entry = load_kernel();
-        write_bootloader(env, qemu_get_ram_ptr(bios_offset), kernel_entry);
+        write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
     } else {
         dinfo = drive_get(IF_PFLASH, 0, fl_idx);
         if (dinfo) {
@@ -851,11 +852,26 @@  void mips_malta_init (ram_addr_t ram_size,
                    fl_idx, bios_size, bios_offset, 0x1e000000LL,
                    bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-            pflash_cfi01_register(0x1e000000LL, bios_offset,
+            pflash_cfi01_register(0x1e000000LL,
+                                  NULL, "mips_malta.bios", BIOS_SIZE,
                                   dinfo->bdrv, 65536, fl_sectors,
                                   4, 0x0000, 0x0000, 0x0000, 0x0000, be);
-            fl_idx++;
+            /* Map the bios at two physical locations, as on the real board. */
+            memory_region_init_alias(bios_alias, "bios.1fc",
+                                     bios, 0, BIOS_SIZE);
+            memory_region_add_subregion(system_memory, 0x1fc00000LL,
+                                        bios_alias);
+           fl_idx++;
         } else {
+            bios = g_new(MemoryRegion, 1);
+            memory_region_init_ram(bios, NULL, "mips_malta.bios", BIOS_SIZE);
+            memory_region_set_readonly(bios, true);
+            memory_region_init_alias(bios_alias, "bios.1fc",
+                                     bios, 0, BIOS_SIZE);
+            /* Map the bios at two physical locations, as on the real board. */
+            memory_region_add_subregion(system_memory, 0x1e000000LL, bios);
+            memory_region_add_subregion(system_memory, 0x1fc00000LL,
+                                        bios_alias);
             /* Load a BIOS image. */
             if (bios_name == NULL)
                 bios_name = BIOS_FILENAME;
@@ -878,7 +894,7 @@  void mips_malta_init (ram_addr_t ram_size,
            a neat trick which allows bi-endian firmware. */
 #ifndef TARGET_WORDS_BIGENDIAN
         {
-            uint32_t *addr = qemu_get_ram_ptr(bios_offset);;
+            uint32_t *addr = memory_region_get_ram_ptr(bios);
             uint32_t *end = addr + bios_size;
             while (addr < end) {
                 bswap32s(addr);
@@ -890,7 +906,7 @@  void mips_malta_init (ram_addr_t ram_size,
     /* Board ID = 0x420 (Malta Board with CoreLV)
        XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
        map to the board ID. */
-    stl_p(qemu_get_ram_ptr(bios_offset) + 0x10, 0x00000420);
+    stl_p(memory_region_get_ram_ptr(bios) + 0x10, 0x00000420);
 
     /* Init internal devices */
     cpu_mips_irq_init_cpu(env);
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 9d90568..5d002c5 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -23,6 +23,7 @@ 
 #include "elf.h"
 #include "mc146818rtc.h"
 #include "blockdev.h"
+#include "exec-memory.h"
 
 #define MAX_IDE_BUS 2
 
@@ -163,7 +164,7 @@  void mips_r4k_init (ram_addr_t ram_size,
 {
     char *filename;
     ram_addr_t ram_offset;
-    ram_addr_t bios_offset;
+    MemoryRegion *bios;
     int bios_size;
     CPUState *env;
     ResetData *reset_info;
@@ -227,15 +228,15 @@  void mips_r4k_init (ram_addr_t ram_size,
     be = 0;
 #endif
     if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) {
-        bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", BIOS_SIZE);
-	cpu_register_physical_memory(0x1fc00000, BIOS_SIZE,
-                                     bios_offset | IO_MEM_ROM);
+        bios = g_new(MemoryRegion, 1);
+        memory_region_init_ram(bios, NULL, "mips_r4k.bios", BIOS_SIZE);
+        memory_region_set_readonly(bios, true);
+        memory_region_add_subregion(get_system_memory(), 0x1fc00000, bios);
 
         load_image_targphys(filename, 0x1fc00000, BIOS_SIZE);
     } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
         uint32_t mips_rom = 0x00400000;
-        bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", mips_rom);
-        if (!pflash_cfi01_register(0x1fc00000, bios_offset,
+        if (!pflash_cfi01_register(0x1fc00000, NULL, "mips_r4k.bios", mips_rom,
                                    dinfo->bdrv, sector_len,
                                    mips_rom / sector_len,
                                    4, 0, 0, 0, 0, be)) {
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 63dd391..ade5a91 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1565,16 +1565,16 @@  static void musicpal_init(ram_addr_t ram_size,
          * image is smaller than 32 MB.
          */
 #ifdef TARGET_WORDS_BIGENDIAN
-        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL,
-                              "musicpal.flash", flash_size),
+        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, NULL,
+                              "musicpal.flash", flash_size,
                               dinfo->bdrv, 0x10000,
                               (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
                               0x5555, 0x2AAA, 1);
 #else
-        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL,
-                              "musicpal.flash", flash_size),
+        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, NULL,
+                              "musicpal.flash", flash_size,
                               dinfo->bdrv, 0x10000,
                               (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c
index a7b687b..15cfbb5 100644
--- a/hw/omap_sx1.c
+++ b/hw/omap_sx1.c
@@ -161,8 +161,8 @@  static void sx1_init(ram_addr_t ram_size,
 #endif
 
     if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
-        if (!pflash_cfi01_register(OMAP_CS0_BASE, qemu_ram_alloc(NULL,
-                                   "omap_sx1.flash0-1", flash_size),
+        if (!pflash_cfi01_register(OMAP_CS0_BASE, NULL,
+                                   "omap_sx1.flash0-1", flash_size,
                                    dinfo->bdrv, sector_size,
                                    flash_size / sector_size,
                                    4, 0, 0, 0, 0, be)) {
@@ -182,8 +182,8 @@  static void sx1_init(ram_addr_t ram_size,
         cpu_register_physical_memory(OMAP_CS1_BASE + flash1_size,
                         OMAP_CS1_SIZE - flash1_size, io);
 
-        if (!pflash_cfi01_register(OMAP_CS1_BASE, qemu_ram_alloc(NULL,
-                                   "omap_sx1.flash1-1", flash1_size),
+        if (!pflash_cfi01_register(OMAP_CS1_BASE, NULL,
+                                   "omap_sx1.flash1-1", flash1_size,
                                    dinfo->bdrv, sector_size,
                                    flash1_size / sector_size,
                                    4, 0, 0, 0, 0, be)) {
diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
index e3ca310..38db521 100644
--- a/hw/petalogix_ml605_mmu.c
+++ b/hw/petalogix_ml605_mmu.c
@@ -149,7 +149,6 @@  petalogix_ml605_init(ram_addr_t ram_size,
     target_phys_addr_t ddr_base = MEMORY_BASEADDR;
     ram_addr_t phys_lmb_bram;
     ram_addr_t phys_ram;
-    ram_addr_t phys_flash;
     qemu_irq irq[32], *cpu_irq;
 
     /* init CPUs */
@@ -169,11 +168,11 @@  petalogix_ml605_init(ram_addr_t ram_size,
     phys_ram = qemu_ram_alloc(NULL, "petalogix_ml605.ram", ram_size);
     cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "petalogix_ml605.flash", FLASH_SIZE);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* 5th parameter 2 means bank-width
      * 10th paremeter 0 means little-endian */
-    pflash_cfi01_register(FLASH_BASEADDR, phys_flash,
+    pflash_cfi01_register(FLASH_BASEADDR,
+                          NULL, "petalogix_ml605.flash", FLASH_SIZE,
                           dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
                           2, 0x89, 0x18, 0x0000, 0x0, 0);
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index a43fb4c..66fb96d 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -127,7 +127,6 @@  petalogix_s3adsp1800_init(ram_addr_t ram_size,
     target_phys_addr_t ddr_base = 0x90000000;
     ram_addr_t phys_lmb_bram;
     ram_addr_t phys_ram;
-    ram_addr_t phys_flash;
     qemu_irq irq[32], *cpu_irq;
 
     /* init CPUs */
@@ -148,9 +147,9 @@  petalogix_s3adsp1800_init(ram_addr_t ram_size,
     phys_ram = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.ram", ram_size);
     cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE);
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    pflash_cfi01_register(0xa0000000, phys_flash,
+    pflash_cfi01_register(0xa0000000,
+                          NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE,
                           dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
                           1, 0x89, 0x18, 0x0000, 0x0, 1);
diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c
index 90e1301..b597304 100644
--- a/hw/pflash_cfi01.c
+++ b/hw/pflash_cfi01.c
@@ -40,6 +40,7 @@ 
 #include "flash.h"
 #include "block.h"
 #include "qemu-timer.h"
+#include "exec-memory.h"
 
 #define PFLASH_BUG(fmt, ...) \
 do { \
@@ -74,8 +75,7 @@  struct pflash_t {
     target_phys_addr_t counter;
     unsigned int writeblock_size;
     QEMUTimer *timer;
-    ram_addr_t off;
-    int fl_mem;
+    MemoryRegion mem;
     void *storage;
 };
 
@@ -89,8 +89,7 @@  static void pflash_timer (void *opaque)
     if (pfl->bypass) {
         pfl->wcycle = 2;
     } else {
-        cpu_register_physical_memory(pfl->base, pfl->total_len,
-                        pfl->off | IO_MEM_ROMD | pfl->fl_mem);
+        memory_region_rom_device_set_readable(&pfl->mem, true);
         pfl->wcycle = 0;
     }
     pfl->cmd = 0;
@@ -263,7 +262,7 @@  static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
 
     if (!pfl->wcycle) {
         /* Set the device in I/O access mode */
-        cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem);
+        memory_region_rom_device_set_readable(&pfl->mem, false);
     }
 
     switch (pfl->wcycle) {
@@ -422,8 +421,7 @@  static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
            __func__, offset, pfl->wcycle, pfl->cmd, value);
 
  reset_flash:
-    cpu_register_physical_memory(pfl->base, pfl->total_len,
-                    pfl->off | IO_MEM_ROMD | pfl->fl_mem);
+    memory_region_rom_device_set_readable(&pfl->mem, true);
 
     pfl->bypass = 0;
     pfl->wcycle = 0;
@@ -514,28 +512,20 @@  static void pflash_writel_le(void *opaque, target_phys_addr_t addr,
     pflash_write(pfl, addr, value, 4, 0);
 }
 
-static CPUWriteMemoryFunc * const pflash_write_ops_be[] = {
-    &pflash_writeb_be,
-    &pflash_writew_be,
-    &pflash_writel_be,
+static const MemoryRegionOps pflash_cfi01_ops_be = {
+    .old_mmio = {
+        .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
+        .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUReadMemoryFunc * const pflash_read_ops_be[] = {
-    &pflash_readb_be,
-    &pflash_readw_be,
-    &pflash_readl_be,
-};
-
-static CPUWriteMemoryFunc * const pflash_write_ops_le[] = {
-    &pflash_writeb_le,
-    &pflash_writew_le,
-    &pflash_writel_le,
-};
-
-static CPUReadMemoryFunc * const pflash_read_ops_le[] = {
-    &pflash_readb_le,
-    &pflash_readw_le,
-    &pflash_readl_le,
+static const MemoryRegionOps pflash_cfi01_ops_le = {
+    .old_mmio = {
+        .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
+        .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 /* Count trailing zeroes of a 32 bits quantity */
@@ -574,12 +564,13 @@  static int ctz32 (uint32_t n)
     return ret;
 }
 
-pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
+pflash_t *pflash_cfi01_register(target_phys_addr_t base,
+                                DeviceState *qdev, const char *name,
+                                target_phys_addr_t size,
                                 BlockDriverState *bs, uint32_t sector_len,
                                 int nb_blocs, int width,
                                 uint16_t id0, uint16_t id1,
-                                uint16_t id2, uint16_t id3,
-                                int be)
+                                uint16_t id2, uint16_t id3, int be)
 {
     pflash_t *pfl;
     target_phys_addr_t total_len;
@@ -596,27 +587,19 @@  pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
 
     pfl = g_malloc0(sizeof(pflash_t));
 
-    /* FIXME: Allocate ram ourselves.  */
-    pfl->storage = qemu_get_ram_ptr(off);
-    if (be) {
-        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be,
-                                             pflash_write_ops_be, pfl,
-                                             DEVICE_NATIVE_ENDIAN);
-    } else {
-        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le,
-                                             pflash_write_ops_le, pfl,
-                                             DEVICE_NATIVE_ENDIAN);
-    }
-    pfl->off = off;
-    cpu_register_physical_memory(base, total_len,
-                    off | pfl->fl_mem | IO_MEM_ROMD);
+    memory_region_init_rom_device(
+        &pfl->mem, be ? &pflash_cfi01_ops_be : &pflash_cfi01_ops_le, pfl,
+        qdev, name, size);
+    pfl->storage = memory_region_get_ram_ptr(&pfl->mem);
+    memory_region_add_subregion(get_system_memory(), base, &pfl->mem);
 
     pfl->bs = bs;
     if (pfl->bs) {
         /* read the initial flash content */
         ret = bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9);
         if (ret < 0) {
-            cpu_unregister_io_memory(pfl->fl_mem);
+            memory_region_del_subregion(get_system_memory(), &pfl->mem);
+            memory_region_destroy(&pfl->mem);
             g_free(pfl);
             return NULL;
         }
diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c
index ac5115e..4dbec87 100644
--- a/hw/pflash_cfi02.c
+++ b/hw/pflash_cfi02.c
@@ -39,6 +39,7 @@ 
 #include "flash.h"
 #include "qemu-timer.h"
 #include "block.h"
+#include "exec-memory.h"
 
 //#define PFLASH_DEBUG
 #ifdef PFLASH_DEBUG
@@ -69,25 +70,38 @@  struct pflash_t {
     uint8_t cfi_len;
     uint8_t cfi_table[0x52];
     QEMUTimer *timer;
-    ram_addr_t off;
-    int fl_mem;
+    /* The device replicates the flash memory across its memory space.  Emulate
+     * that by having a container (.mem) filled with an array of aliases
+     * (.mem_mappings) pointing to the flash memory (.orig_mem).
+     */
+    MemoryRegion mem;
+    MemoryRegion *mem_mappings;    /* array; one per mapping */
+    MemoryRegion orig_mem;
     int rom_mode;
     int read_counter; /* used for lazy switch-back to rom mode */
     void *storage;
 };
 
-static void pflash_register_memory(pflash_t *pfl, int rom_mode)
+/*
+ * Set up replicated mappings of the same region.
+ */
+static void pflash_setup_mappings(pflash_t *pfl)
 {
-    unsigned long phys_offset = pfl->fl_mem;
-    int i;
-
-    if (rom_mode)
-        phys_offset |= pfl->off | IO_MEM_ROMD;
-    pfl->rom_mode = rom_mode;
+    unsigned i;
+    target_phys_addr_t size = memory_region_size(&pfl->orig_mem);
+
+    memory_region_init(&pfl->mem, "pflash", pfl->mappings * size);
+    pfl->mem_mappings = g_new(MemoryRegion, pfl->mappings);
+    for (i = 0; i < pfl->mappings; ++i) {
+        memory_region_init_alias(&pfl->mem_mappings[i], "pflash-alias",
+                                 &pfl->orig_mem, 0, size);
+        memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]);
+    }
+}
 
-    for (i = 0; i < pfl->mappings; i++)
-        cpu_register_physical_memory(pfl->base + i * pfl->chip_len,
-                                     pfl->chip_len, phys_offset);
+static void pflash_register_memory(pflash_t *pfl, int rom_mode)
+{
+    memory_region_rom_device_set_readable(&pfl->orig_mem, rom_mode);
 }
 
 static void pflash_timer (void *opaque)
@@ -538,28 +552,20 @@  static void pflash_writel_le(void *opaque, target_phys_addr_t addr,
     pflash_write(pfl, addr, value, 4, 0);
 }
 
-static CPUWriteMemoryFunc * const pflash_write_ops_be[] = {
-    &pflash_writeb_be,
-    &pflash_writew_be,
-    &pflash_writel_be,
-};
-
-static CPUReadMemoryFunc * const pflash_read_ops_be[] = {
-    &pflash_readb_be,
-    &pflash_readw_be,
-    &pflash_readl_be,
+static const MemoryRegionOps pflash_cfi02_ops_be = {
+    .old_mmio = {
+        .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
+        .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUWriteMemoryFunc * const pflash_write_ops_le[] = {
-    &pflash_writeb_le,
-    &pflash_writew_le,
-    &pflash_writel_le,
-};
-
-static CPUReadMemoryFunc * const pflash_read_ops_le[] = {
-    &pflash_readb_le,
-    &pflash_readw_le,
-    &pflash_readl_le,
+static const MemoryRegionOps pflash_cfi02_ops_le = {
+    .old_mmio = {
+        .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
+        .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 /* Count trailing zeroes of a 32 bits quantity */
@@ -598,7 +604,9 @@  static int ctz32 (uint32_t n)
     return ret;
 }
 
-pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
+pflash_t *pflash_cfi02_register(target_phys_addr_t base,
+                                DeviceState *qdev, const char *name,
+                                target_phys_addr_t size,
                                 BlockDriverState *bs, uint32_t sector_len,
                                 int nb_blocs, int nb_mappings, int width,
                                 uint16_t id0, uint16_t id1,
@@ -618,32 +626,25 @@  pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
         return NULL;
 #endif
     pfl = g_malloc0(sizeof(pflash_t));
-    /* FIXME: Allocate ram ourselves.  */
-    pfl->storage = qemu_get_ram_ptr(off);
-    if (be) {
-        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be,
-                                             pflash_write_ops_be,
-                                             pfl, DEVICE_NATIVE_ENDIAN);
-    } else {
-        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le,
-                                             pflash_write_ops_le,
-                                             pfl, DEVICE_NATIVE_ENDIAN);
-    }
-    pfl->off = off;
+    memory_region_init_rom_device(
+        &pfl->orig_mem, be ? &pflash_cfi02_ops_be : &pflash_cfi02_ops_le, pfl,
+        qdev, name, size);
+    pfl->storage = memory_region_get_ram_ptr(&pfl->orig_mem);
     pfl->base = base;
     pfl->chip_len = chip_len;
     pfl->mappings = nb_mappings;
-    pflash_register_memory(pfl, 1);
     pfl->bs = bs;
     if (pfl->bs) {
         /* read the initial flash content */
         ret = bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9);
         if (ret < 0) {
-            cpu_unregister_io_memory(pfl->fl_mem);
             g_free(pfl);
             return NULL;
         }
     }
+    pflash_setup_mappings(pfl);
+    pfl->rom_mode = 1;
+    memory_region_add_subregion(get_system_memory(), pfl->base, &pfl->mem);
 #if 0 /* XXX: there should be a bit to set up read-only,
        *      the same way the hardware does (with WP pin).
        */
diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c
index dec165e..e6c8ac6 100644
--- a/hw/ppc405_boards.c
+++ b/hw/ppc405_boards.c
@@ -32,6 +32,7 @@ 
 #include "qemu-log.h"
 #include "loader.h"
 #include "blockdev.h"
+#include "exec-memory.h"
 
 #define BIOS_FILENAME "ppc405_rom.bin"
 #define BIOS_SIZE (2048 * 1024)
@@ -181,7 +182,8 @@  static void ref405ep_init (ram_addr_t ram_size,
     ppc4xx_bd_info_t bd;
     CPUPPCState *env;
     qemu_irq *pic;
-    ram_addr_t sram_offset, bios_offset, bdloc;
+    MemoryRegion *bios;
+    ram_addr_t sram_offset, bdloc;
     MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
     target_phys_addr_t ram_bases[2], ram_sizes[2];
     target_ulong sram_size;
@@ -224,15 +226,15 @@  static void ref405ep_init (ram_addr_t ram_size,
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
     if (dinfo) {
         bios_size = bdrv_getlength(dinfo->bdrv);
-        bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", bios_size);
         fl_sectors = (bios_size + 65535) >> 16;
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at offset %08lx addr %lx '%s' %d\n",
-               fl_idx, bios_size, bios_offset, -bios_size,
+               " at addr %lx '%s' %d\n",
+               fl_idx, bios_size, -bios_size,
                bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-        pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
+        pflash_cfi02_register((uint32_t)(-bios_size),
+                              NULL, "ef405ep.bios", bios_size,
                               dinfo->bdrv, 65536, fl_sectors, 1,
                               2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
                               1);
@@ -243,12 +245,13 @@  static void ref405ep_init (ram_addr_t ram_size,
 #ifdef DEBUG_BOARD_INIT
         printf("Load BIOS from file\n");
 #endif
-        bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", BIOS_SIZE);
+        bios = g_new(MemoryRegion, 1);
+        memory_region_init_ram(bios, NULL, "ef405ep.bios", BIOS_SIZE);
         if (bios_name == NULL)
             bios_name = BIOS_FILENAME;
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (filename) {
-            bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset));
+            bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
             g_free(filename);
         } else {
             bios_size = -1;
@@ -259,8 +262,9 @@  static void ref405ep_init (ram_addr_t ram_size,
             exit(1);
         }
         bios_size = (bios_size + 0xfff) & ~0xfff;
-        cpu_register_physical_memory((uint32_t)(-bios_size),
-                                     bios_size, bios_offset | IO_MEM_ROM);
+        memory_region_set_readonly(bios, true);
+        memory_region_add_subregion(get_system_memory(),
+                                    (uint32_t)(-bios_size), bios);
     }
     /* Register FPGA */
 #ifdef DEBUG_BOARD_INIT
@@ -507,7 +511,7 @@  static void taihu_405ep_init(ram_addr_t ram_size,
 {
     char *filename;
     qemu_irq *pic;
-    ram_addr_t bios_offset;
+    MemoryRegion *bios;
     MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
     target_phys_addr_t ram_bases[2], ram_sizes[2];
     long bios_size;
@@ -544,14 +548,14 @@  static void taihu_405ep_init(ram_addr_t ram_size,
         /* XXX: should check that size is 2MB */
         //        bios_size = 2 * 1024 * 1024;
         fl_sectors = (bios_size + 65535) >> 16;
-        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", bios_size);
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at offset %08lx addr %lx '%s' %d\n",
-               fl_idx, bios_size, bios_offset, -bios_size,
+               " at addr %lx '%s' %d\n",
+               fl_idx, bios_size, -bios_size,
                bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-        pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
+        pflash_cfi02_register((uint32_t)(-bios_size),
+                              NULL, "taihu_405ep.bios", bios_size,
                               dinfo->bdrv, 65536, fl_sectors, 1,
                               4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
                               1);
@@ -564,10 +568,11 @@  static void taihu_405ep_init(ram_addr_t ram_size,
 #endif
         if (bios_name == NULL)
             bios_name = BIOS_FILENAME;
-        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", BIOS_SIZE);
+        bios = g_new(MemoryRegion, 1);
+        memory_region_init_ram(bios, NULL, "taihu_405ep.bios", BIOS_SIZE);
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (filename) {
-            bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset));
+            bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
             g_free(filename);
         } else {
             bios_size = -1;
@@ -578,8 +583,9 @@  static void taihu_405ep_init(ram_addr_t ram_size,
             exit(1);
         }
         bios_size = (bios_size + 0xfff) & ~0xfff;
-        cpu_register_physical_memory((uint32_t)(-bios_size),
-                                     bios_size, bios_offset | IO_MEM_ROM);
+        memory_region_set_readonly(bios, true);
+        memory_region_add_subregion(get_system_memory(), (uint32_t)(-bios_size),
+                                    bios);
     }
     /* Register Linux flash */
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
@@ -590,12 +596,11 @@  static void taihu_405ep_init(ram_addr_t ram_size,
         fl_sectors = (bios_size + 65535) >> 16;
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at offset %08lx  addr " TARGET_FMT_lx " '%s'\n",
-               fl_idx, bios_size, bios_offset, (target_ulong)0xfc000000,
+               " at addr " TARGET_FMT_lx " '%s'\n",
+               fl_idx, bios_size, (target_ulong)0xfc000000,
                bdrv_get_device_name(dinfo->bdrv));
 #endif
-        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.flash", bios_size);
-        pflash_cfi02_register(0xfc000000, bios_offset,
+        pflash_cfi02_register(0xfc000000, NULL, "taihu_405ep.flash", bios_size,
                               dinfo->bdrv, 65536, fl_sectors, 1,
                               4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
                               1);
diff --git a/hw/r2d.c b/hw/r2d.c
index 96a7ff8..ed0c586 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -267,7 +267,7 @@  static void r2d_init(ram_addr_t ram_size,
 
     /* onboard flash memory */
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    pflash_cfi02_register(0x0, qemu_ram_alloc(NULL, "r2d.flash", FLASH_SIZE),
+    pflash_cfi02_register(0x0, NULL, "r2d.flash", FLASH_SIZE,
                           dinfo ? dinfo->bdrv : NULL, (16 * 1024),
                           FLASH_SIZE >> 16,
                           1, 4, 0x0000, 0x0000, 0x0000, 0x0000,
diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c
index 333050c..7459b0b 100644
--- a/hw/virtex_ml507.c
+++ b/hw/virtex_ml507.c
@@ -196,7 +196,6 @@  static void virtex_init(ram_addr_t ram_size,
     target_phys_addr_t ram_base = 0;
     DriveInfo *dinfo;
     ram_addr_t phys_ram;
-    ram_addr_t phys_flash;
     qemu_irq irq[32], *cpu_irq;
     clk_setup_t clk_setup[7];
     int kernel_size;
@@ -215,9 +214,8 @@  static void virtex_init(ram_addr_t ram_size,
     phys_ram = qemu_ram_alloc(NULL, "ram", ram_size);
     cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "virtex.flash", FLASH_SIZE);
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    pflash_cfi01_register(0xfc000000, phys_flash,
+    pflash_cfi01_register(0xfc000000, NULL, "virtex.flash", FLASH_SIZE,
                           dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
                           1, 0x89, 0x18, 0x0000, 0x0, 1);
diff --git a/hw/z2.c b/hw/z2.c
index f93a1bf..b6ae608 100644
--- a/hw/z2.c
+++ b/hw/z2.c
@@ -305,7 +305,7 @@  static void z2_init(ram_addr_t ram_size,
     }
 
     if (!pflash_cfi01_register(Z2_FLASH_BASE,
-                               qemu_ram_alloc(NULL, "z2.flash0", Z2_FLASH_SIZE),
+                               NULL, "z2.flash0", Z2_FLASH_SIZE,
                                dinfo->bdrv, sector_len,
                                Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0,
                                be)) {