diff mbox series

[v2,5/5] hw/char: cadence_uart: Ignore access when unclocked or in reset for uart_{read, write}()

Message ID 20210901032724.23256-6-bmeng.cn@gmail.com (mailing list archive)
State New, archived
Headers show
Series hw/arm: xilinx_zynq: Fix upstream U-Boot boot failure | expand

Commit Message

Bin Meng Sept. 1, 2021, 3:27 a.m. UTC
Read or write to uart registers when unclocked or in reset should be
ignored. Add the check there, and as a result of this, the check in
uart_write_tx_fifo() is now unnecessary.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>

---

Changes in v2:
- new patch: hw/char: cadence_uart: Ignore access when unclocked or in reset for uart_{read,write}()

 hw/char/cadence_uart.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

Comments

Edgar E. Iglesias Sept. 1, 2021, 8:32 a.m. UTC | #1
On Wed, Sep 01, 2021 at 11:27:24AM +0800, Bin Meng wrote:
> Read or write to uart registers when unclocked or in reset should be
> ignored. Add the check there, and as a result of this, the check in
> uart_write_tx_fifo() is now unnecessary.

Hi Bin,

I thought I had replied to this but it must have gotten lost somewhere.

We've got SW that expects FSBL (Bootlooader) to setup clocks and resets.
It's quite common that users run that SW on QEMU without FSBL (FSBL typically
requires the Xilinx tools installed). That's fine, since users can stil use
-device loader to enable clocks etc.

To help folks understand what's going, a log (guest-error) message would
be helpful here. In particular with the serial port since things will go
very quiet if they get things wrong.

Otherwise, this patch is fine with me.

Thanks,
Edgar


> 
> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
> 
> ---
> 
> Changes in v2:
> - new patch: hw/char: cadence_uart: Ignore access when unclocked or in reset for uart_{read,write}()
> 
>  hw/char/cadence_uart.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
> index 8bcf2b718a..5f5a4645ac 100644
> --- a/hw/char/cadence_uart.c
> +++ b/hw/char/cadence_uart.c
> @@ -335,11 +335,6 @@ static gboolean cadence_uart_xmit(void *do_not_use, GIOCondition cond,
>  static void uart_write_tx_fifo(CadenceUARTState *s, const uint8_t *buf,
>                                 int size)
>  {
> -    /* ignore characters when unclocked or in reset */
> -    if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
> -        return;
> -    }
> -
>      if ((s->r[R_CR] & UART_CR_TX_DIS) || !(s->r[R_CR] & UART_CR_TX_EN)) {
>          return;
>      }
> @@ -416,6 +411,11 @@ static MemTxResult uart_write(void *opaque, hwaddr offset,
>  {
>      CadenceUARTState *s = opaque;
>  
> +    /* ignore access when unclocked or in reset */
> +    if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
> +        return MEMTX_ERROR;
> +    }
> +
>      DB_PRINT(" offset:%x data:%08x\n", (unsigned)offset, (unsigned)value);
>      offset >>= 2;
>      if (offset >= CADENCE_UART_R_MAX) {
> @@ -476,6 +476,11 @@ static MemTxResult uart_read(void *opaque, hwaddr offset,
>      CadenceUARTState *s = opaque;
>      uint32_t c = 0;
>  
> +    /* ignore access when unclocked or in reset */
> +    if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
> +        return MEMTX_ERROR;
> +    }
> +
>      offset >>= 2;
>      if (offset >= CADENCE_UART_R_MAX) {
>          return MEMTX_DECODE_ERROR;
> -- 
> 2.25.1
>
Bin Meng Sept. 1, 2021, 10:52 a.m. UTC | #2
Hi Edgar,

On Wed, Sep 1, 2021 at 4:32 PM Edgar E. Iglesias
<edgar.iglesias@xilinx.com> wrote:
>
> On Wed, Sep 01, 2021 at 11:27:24AM +0800, Bin Meng wrote:
> > Read or write to uart registers when unclocked or in reset should be
> > ignored. Add the check there, and as a result of this, the check in
> > uart_write_tx_fifo() is now unnecessary.
>
> Hi Bin,
>
> I thought I had replied to this but it must have gotten lost somewhere.
>
> We've got SW that expects FSBL (Bootlooader) to setup clocks and resets.
> It's quite common that users run that SW on QEMU without FSBL (FSBL typically
> requires the Xilinx tools installed). That's fine, since users can stil use
> -device loader to enable clocks etc.
>
> To help folks understand what's going, a log (guest-error) message would
> be helpful here. In particular with the serial port since things will go
> very quiet if they get things wrong.
>
> Otherwise, this patch is fine with me.
>

Thanks. Will add a separate patch to enable a log message for all places.

Regards,
Bin
Philippe Mathieu-Daudé Sept. 2, 2021, 6:09 a.m. UTC | #3
On 9/1/21 5:27 AM, Bin Meng wrote:
> Read or write to uart registers when unclocked or in reset should be
> ignored. Add the check there, and as a result of this, the check in
> uart_write_tx_fifo() is now unnecessary.
> 
> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
> 
> ---
> 
> Changes in v2:
> - new patch: hw/char: cadence_uart: Ignore access when unclocked or in reset for uart_{read,write}()
> 
>  hw/char/cadence_uart.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Philippe Mathieu-Daudé Sept. 2, 2021, 6:10 a.m. UTC | #4
On 9/1/21 10:32 AM, Edgar E. Iglesias wrote:
> On Wed, Sep 01, 2021 at 11:27:24AM +0800, Bin Meng wrote:
>> Read or write to uart registers when unclocked or in reset should be
>> ignored. Add the check there, and as a result of this, the check in
>> uart_write_tx_fifo() is now unnecessary.
> 
> Hi Bin,
> 
> I thought I had replied to this but it must have gotten lost somewhere.
> 
> We've got SW that expects FSBL (Bootlooader) to setup clocks and resets.
> It's quite common that users run that SW on QEMU without FSBL (FSBL typically
> requires the Xilinx tools installed). That's fine, since users can stil use
> -device loader to enable clocks etc.
> 
> To help folks understand what's going, a log (guest-error) message would
> be helpful here. In particular with the serial port since things will go
> very quiet if they get things wrong.

Interesting, I was expecting this error to be reported by
memory_region_access_valid() but indeed it is not in the path.

Alternative is to implement MemoryRegionOps::accepts().
Philippe Mathieu-Daudé Sept. 2, 2021, 6:11 a.m. UTC | #5
On 9/2/21 8:09 AM, Philippe Mathieu-Daudé wrote:
> On 9/1/21 5:27 AM, Bin Meng wrote:
>> Read or write to uart registers when unclocked or in reset should be
>> ignored. Add the check there, and as a result of this, the check in
>> uart_write_tx_fifo() is now unnecessary.
>>
>> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
>>
>> ---
>>
>> Changes in v2:
>> - new patch: hw/char: cadence_uart: Ignore access when unclocked or in reset for uart_{read,write}()
>>
>>  hw/char/cadence_uart.c | 15 ++++++++++-----
>>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

Just realized it is simpler to implement MemoryRegionOps::accepts().
Bin Meng Sept. 5, 2021, 2:31 p.m. UTC | #6
On Thu, Sep 2, 2021 at 2:11 PM Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>
> On 9/2/21 8:09 AM, Philippe Mathieu-Daudé wrote:
> > On 9/1/21 5:27 AM, Bin Meng wrote:
> >> Read or write to uart registers when unclocked or in reset should be
> >> ignored. Add the check there, and as a result of this, the check in
> >> uart_write_tx_fifo() is now unnecessary.
> >>
> >> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
> >>
> >> ---
> >>
> >> Changes in v2:
> >> - new patch: hw/char: cadence_uart: Ignore access when unclocked or in reset for uart_{read,write}()
> >>
> >>  hw/char/cadence_uart.c | 15 ++++++++++-----
> >>  1 file changed, 10 insertions(+), 5 deletions(-)
> >
> > Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
>
> Just realized it is simpler to implement MemoryRegionOps::accepts().

Is there any guidance on what condition falls into
MemoryRegionOps::accepts() to check?

For example, should we move the register offset check to accepts()?

It looks like only a few codes implemented the MemoryRegionOps::accepts().

Regards,
Bin
diff mbox series

Patch

diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index 8bcf2b718a..5f5a4645ac 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -335,11 +335,6 @@  static gboolean cadence_uart_xmit(void *do_not_use, GIOCondition cond,
 static void uart_write_tx_fifo(CadenceUARTState *s, const uint8_t *buf,
                                int size)
 {
-    /* ignore characters when unclocked or in reset */
-    if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
-        return;
-    }
-
     if ((s->r[R_CR] & UART_CR_TX_DIS) || !(s->r[R_CR] & UART_CR_TX_EN)) {
         return;
     }
@@ -416,6 +411,11 @@  static MemTxResult uart_write(void *opaque, hwaddr offset,
 {
     CadenceUARTState *s = opaque;
 
+    /* ignore access when unclocked or in reset */
+    if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
+        return MEMTX_ERROR;
+    }
+
     DB_PRINT(" offset:%x data:%08x\n", (unsigned)offset, (unsigned)value);
     offset >>= 2;
     if (offset >= CADENCE_UART_R_MAX) {
@@ -476,6 +476,11 @@  static MemTxResult uart_read(void *opaque, hwaddr offset,
     CadenceUARTState *s = opaque;
     uint32_t c = 0;
 
+    /* ignore access when unclocked or in reset */
+    if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
+        return MEMTX_ERROR;
+    }
+
     offset >>= 2;
     if (offset >= CADENCE_UART_R_MAX) {
         return MEMTX_DECODE_ERROR;