Re: Question on Qemu flash driver - pflash_cfi01

2023-09-23 Thread Srivatsa Vaddagiri
* Peter Maydell  [2023-09-23 13:39:55]:

> On Sat, 23 Sept 2023 at 13:11, Srivatsa Vaddagiri
>  wrote:
> >
> > cfi01 driver initializes a rom device with ops represented by 
> > pflash_cfi01_ops.
> >
> > static const MemoryRegionOps pflash_cfi01_ops = {
> > .read_with_attrs = pflash_mem_read_with_attrs,
> > .write_with_attrs = pflash_mem_write_with_attrs,
> > .endianness = DEVICE_NATIVE_ENDIAN,
> > };
> >
> >
> > memory_region_init_rom_device(
> > >mem, OBJECT(dev),
> > _cfi01_ops,
> > pfl,
> > pfl->name, total_len, errp);
> >
> > This region is also mapped in guest address space. For ex: hw/arm/virt.c 
> > does
> > that by:
> >
> > virt_flash_map1() {
> >
> > memory_region_add_subregion(sysmem, base,
> > sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0));
> > }
> >
> > It is not clear to me under what circumstance would the callbacks listed in
> > pflash_cfi01_ops be invoked. Is rom device memory supposed to be of 
> > trap/emulate
> > type, so that guest read of that memory will get trapped and handled by ops
> > listed in pflash_cfi01_ops? I see that a hypervisor accelerator's memory
> > listener callback gets notified of that memory range and appears to be
> > registering that as "read-only" memory. A read of that memory range from 
> > guest
> > need not necessarily cause a trap for example, in which case when would
> > pflash_mem_read_with_attrs get invoked?
> 
> A "rom device" is (as described in
> https://www.qemu.org/docs/master/devel/memory.html) a device which
> works like RAM for reads (directly accessing a region of host memory),
> but like MMIO for writes (invoking a callback).
> 
> ROM devices also have two modes:
>  (1) "romd mode" is the default; as above, reads go to memory,
>  and writes go to the write function in the MemoryRegionOps
>  (2) "romd mode disabled" means that both reads and writes
>  go to the functions in the MemoryRegionOps
> The device can use memory_region_rom_device_set_romd() to
> switch between these.
> 
> For the pflash devices, we use these so that in normal
> circumstances, execution and reading from the flash is fast.
> But the guest still has the ability to reprogram the flash
> (by writing commands to it); when the guest is programming the
> flash, reads from the device don't return the flash data, they
> return command responses. So when the guest starts programming
> the flash, the device puts itself into "romd disabled" mode,
> so that it can handle the read accesses correctly. Once the
> programming has finished it can switch back into romd mode again.

Ah ok ..its clear to me now.

I see that when romd_mode is false, accelerators like KVM remove memory
mapping so both read/writes trap, which matches what you describe above.

Thanks!
vatsa



Re: Question on Qemu flash driver - pflash_cfi01

2023-09-23 Thread Peter Maydell
On Sat, 23 Sept 2023 at 13:11, Srivatsa Vaddagiri
 wrote:
>
> cfi01 driver initializes a rom device with ops represented by 
> pflash_cfi01_ops.
>
> static const MemoryRegionOps pflash_cfi01_ops = {
> .read_with_attrs = pflash_mem_read_with_attrs,
> .write_with_attrs = pflash_mem_write_with_attrs,
> .endianness = DEVICE_NATIVE_ENDIAN,
> };
>
>
> memory_region_init_rom_device(
> >mem, OBJECT(dev),
> _cfi01_ops,
> pfl,
> pfl->name, total_len, errp);
>
> This region is also mapped in guest address space. For ex: hw/arm/virt.c does
> that by:
>
> virt_flash_map1() {
>
> memory_region_add_subregion(sysmem, base,
> sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0));
> }
>
> It is not clear to me under what circumstance would the callbacks listed in
> pflash_cfi01_ops be invoked. Is rom device memory supposed to be of 
> trap/emulate
> type, so that guest read of that memory will get trapped and handled by ops
> listed in pflash_cfi01_ops? I see that a hypervisor accelerator's memory
> listener callback gets notified of that memory range and appears to be
> registering that as "read-only" memory. A read of that memory range from guest
> need not necessarily cause a trap for example, in which case when would
> pflash_mem_read_with_attrs get invoked?

A "rom device" is (as described in
https://www.qemu.org/docs/master/devel/memory.html) a device which
works like RAM for reads (directly accessing a region of host memory),
but like MMIO for writes (invoking a callback).

ROM devices also have two modes:
 (1) "romd mode" is the default; as above, reads go to memory,
 and writes go to the write function in the MemoryRegionOps
 (2) "romd mode disabled" means that both reads and writes
 go to the functions in the MemoryRegionOps
The device can use memory_region_rom_device_set_romd() to
switch between these.

For the pflash devices, we use these so that in normal
circumstances, execution and reading from the flash is fast.
But the guest still has the ability to reprogram the flash
(by writing commands to it); when the guest is programming the
flash, reads from the device don't return the flash data, they
return command responses. So when the guest starts programming
the flash, the device puts itself into "romd disabled" mode,
so that it can handle the read accesses correctly. Once the
programming has finished it can switch back into romd mode again.

thanks
-- PMM