Hi Philippe,

On 3/25/19 2:28 PM, Philippe Mathieu-Daudé wrote:
> Hi Damien,
> 
> Le lun. 25 mars 2019 12:16, Damien Hedde <damien.he...@greensocs.com
> <mailto:damien.he...@greensocs.com>> a écrit :
> 
>     Change the legacy reset function into the init phase and test the
>     resetting flag in register accesses.
> 
>     Signed-off-by: Damien Hedde <damien.he...@greensocs.com
>     <mailto:damien.he...@greensocs.com>>
>     ---
>      hw/misc/zynq_slcr.c | 14 +++++++++++---
>      1 file changed, 11 insertions(+), 3 deletions(-)
> [...]
>     @@ -346,6 +346,10 @@ static uint64_t zynq_slcr_read(void *opaque,
>     hwaddr offset,
>          offset /= 4;
>          uint32_t ret = s->regs[offset];
> 
>     +    if (qdev_is_resetting((DeviceState *) opaque)) {
>     +        return 0;
>     +    }
>     +
>          if (!zynq_slcr_check_offset(offset, true)) {
>              qemu_log_mask(LOG_GUEST_ERROR, "zynq_slcr: Invalid read
>     access to "
>                            " addr %" HWADDR_PRIx "\n", offset * 4);
>     @@ -361,6 +365,10 @@ static void zynq_slcr_write(void *opaque,
>     hwaddr offset,
>          ZynqSLCRState *s = (ZynqSLCRState *)opaque;
>          offset /= 4;
> 
>     +    if (qdev_is_resetting((DeviceState *) opaque)) {
>     +        return;
> 
> 
> I wonder if that could be moved to generic parent, as an abstract method. 
> But then I'm not sure we can use a generic read() return value. 
> 

I agree it would be better not have to add this kind of test everywhere.
It is one my unresolved problem but I am not sure what is the best solution.

There is two approachs here I think:
Either we disable/enable explicitely the memory regions in the reset
handlers. But then we have to handle the migration of the memory regions
flags.
Or the memory region handlers somehow check the resetting state (like
here) and we have only to handle the resetting state migration.

Memory region are added using the following code in sysbus:
```
memory_region_init_io(&s->iomem, obj, &uart_ops, s, "uart", 0x1000);
sysbus_init_mmio(sbd, &s->iomem);
sysbus_mmio_map(s, mmio_index, addr);
```
To intercept the read and write without needing a modification of every
read/write handlers, I see two options:

+ we can either find a way to "override" the read and write handlers of
the memory regions. For example, this could be done in sysbus_init_mmio,
or in a dedicated version of the function (eg sysbus_init_mmio_with_reset)

+ or we can use the MemoryRegion owner field (here _obj_ in
memory_region_init_io call) to test if the owner is Resettable and
whether it is resetting or not before calling the handlers. In that
case, this will not be limited to sysbus devices.

--
Thanks
Damien




Reply via email to