diff mbox series

hw/misc: zynq_slcr: set SLC_RST bit in REBOOT_STATUS register

Message ID 20240227222227.74935-1-greg@gpanders.com (mailing list archive)
State New, archived
Headers show
Series hw/misc: zynq_slcr: set SLC_RST bit in REBOOT_STATUS register | expand

Commit Message

Gregory Anders Feb. 27, 2024, 10:22 p.m. UTC
When the CPU is reset using PSS_RST_CTRL in the SLCR, bit 19 in
REBOOT_STATUS should be set.

Refer to page 1602 of the Xilinx Zynq 7000 Technical Reference Manual.

Signed-off-by: Gregory Anders <greg@gpanders.com>
---
 hw/misc/zynq_slcr.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

Peter Maydell March 1, 2024, 4:40 p.m. UTC | #1
On Wed, 28 Feb 2024 at 01:40, Gregory Anders <greg@gpanders.com> wrote:
>
> When the CPU is reset using PSS_RST_CTRL in the SLCR, bit 19 in
> REBOOT_STATUS should be set.
>
> Refer to page 1602 of the Xilinx Zynq 7000 Technical Reference Manual.
>
> Signed-off-by: Gregory Anders <greg@gpanders.com>
> ---
>  hw/misc/zynq_slcr.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
> index d2ac2e77f2..a8f1792bf6 100644
> --- a/hw/misc/zynq_slcr.c
> +++ b/hw/misc/zynq_slcr.c
> @@ -120,6 +120,7 @@ REG32(RS_AWDT_CTRL, 0x24c)
>  REG32(RST_REASON, 0x250)
>
>  REG32(REBOOT_STATUS, 0x258)
> +    FIELD(REBOOT_STATUS, SLC_RST, 19, 1)
>  REG32(BOOT_MODE, 0x25c)
>
>  REG32(APU_CTRL, 0x300)
> @@ -562,6 +563,7 @@ static void zynq_slcr_write(void *opaque, hwaddr offset,
>      switch (offset) {
>      case R_PSS_RST_CTRL:
>          if (FIELD_EX32(val, PSS_RST_CTRL, SOFT_RST)) {
> +            s->regs[R_REBOOT_STATUS] |= R_REBOOT_STATUS_SLC_RST_MASK;
>              qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
>          }
>          break;
> --

The manual also says that "This field is written by ROM code",
so as a model of the hardware should QEMU be writing it?

I've cc'd the Zynq maintainers for their opinion.

thanks
-- PMM
Edgar E. Iglesias March 1, 2024, 11:55 p.m. UTC | #2
On Fri, Mar 1, 2024 at 10:40 AM Peter Maydell <peter.maydell@linaro.org>
wrote:

> On Wed, 28 Feb 2024 at 01:40, Gregory Anders <greg@gpanders.com> wrote:
> >
> > When the CPU is reset using PSS_RST_CTRL in the SLCR, bit 19 in
> > REBOOT_STATUS should be set.
> >

> Refer to page 1602 of the Xilinx Zynq 7000 Technical Reference Manual.
> >
> > Signed-off-by: Gregory Anders <greg@gpanders.com>
> > ---
> >  hw/misc/zynq_slcr.c | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
> > index d2ac2e77f2..a8f1792bf6 100644
> > --- a/hw/misc/zynq_slcr.c
> > +++ b/hw/misc/zynq_slcr.c
> > @@ -120,6 +120,7 @@ REG32(RS_AWDT_CTRL, 0x24c)
> >  REG32(RST_REASON, 0x250)
> >
> >  REG32(REBOOT_STATUS, 0x258)
> > +    FIELD(REBOOT_STATUS, SLC_RST, 19, 1)
> >  REG32(BOOT_MODE, 0x25c)
> >
> >  REG32(APU_CTRL, 0x300)
> > @@ -562,6 +563,7 @@ static void zynq_slcr_write(void *opaque, hwaddr
> offset,
> >      switch (offset) {
> >      case R_PSS_RST_CTRL:
> >          if (FIELD_EX32(val, PSS_RST_CTRL, SOFT_RST)) {
> > +            s->regs[R_REBOOT_STATUS] |= R_REBOOT_STATUS_SLC_RST_MASK;
> >              qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
> >          }
> >          break;
> > --
>
> The manual also says that "This field is written by ROM code",
> so as a model of the hardware should QEMU be writing it?
>
> I've cc'd the Zynq maintainers for their opinion.
>
>
Hi,

I don't have great answers unfortunately...

We haven't been super consistent with these things but on the ZynqMP we
sometimes require the user to apply ROM behaviour using -device loader on
the command-line (not great for this case since we wouldn't want the mask
to be set until a soft reset) or we conditionalize the ROM behaviour
checking if we're doing direct Linux boots..

Best regards,
Edgar




> thanks
> -- PMM
>
Gregory Anders March 3, 2024, 7:24 p.m. UTC | #3
On Fri Mar 1, 2024 at 5:55 PM CST, Edgar E. Iglesias wrote:
> Hi,
>
> I don't have great answers unfortunately...
>
> We haven't been super consistent with these things but on the ZynqMP we
> sometimes require the user to apply ROM behaviour using -device loader on
> the command-line (not great for this case since we wouldn't want the mask
> to be set until a soft reset) or we conditionalize the ROM behaviour
> checking if we're doing direct Linux boots..
>
> Best regards,
> Edgar
>

Hi Edgar,

Perhaps it would be helpful if I explained my use case.

In our design we use the soft reset feature of the Zynq to reboot the
computer into one of two different applications. We use the persistent
bits in the REBOOT_STATUS register to store a small amount of state
which is then read in the bootloader to determine which application to
boot into.

As part of that process we also test the SLC_RST bit in the
REBOOT_STATUS register so that those bits are only considered when a
soft reset was performed by the software.

We would like to test this code path in QEMU, but it is not possible at
present since QEMU does not set the SLC_RST bit. So when QEMU performs
the soft CPU reset, our boot code does not consider the persistent bits
in the REBOOT_STATUS register.

If there is another way to do this (e.g. using a -device option, as you
mentioned) then I will gladly consider it, but setting the bit in QEMU
seems simplest to me (we have a fork of QEMU that we maintain with some
other patches, so we can apply this patch ourselves if required, but of
course it's easier for us to upstream and can hopefully benefit others
as well).

Thanks,

Gregory
diff mbox series

Patch

diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
index d2ac2e77f2..a8f1792bf6 100644
--- a/hw/misc/zynq_slcr.c
+++ b/hw/misc/zynq_slcr.c
@@ -120,6 +120,7 @@  REG32(RS_AWDT_CTRL, 0x24c)
 REG32(RST_REASON, 0x250)
 
 REG32(REBOOT_STATUS, 0x258)
+    FIELD(REBOOT_STATUS, SLC_RST, 19, 1)
 REG32(BOOT_MODE, 0x25c)
 
 REG32(APU_CTRL, 0x300)
@@ -562,6 +563,7 @@  static void zynq_slcr_write(void *opaque, hwaddr offset,
     switch (offset) {
     case R_PSS_RST_CTRL:
         if (FIELD_EX32(val, PSS_RST_CTRL, SOFT_RST)) {
+            s->regs[R_REBOOT_STATUS] |= R_REBOOT_STATUS_SLC_RST_MASK;
             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
         }
         break;