All of lore.kernel.org
 help / color / mirror / Atom feed
From: dmukhin@xen.org
To: Stefano Stabellini <sstabellini@kernel.org>
Cc: xen-devel@lists.xenproject.org, andrew.cooper3@citrix.com,
	anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org,
	michal.orzel@amd.com, roger.pau@citrix.com, dmukhin@ford.com
Subject: Re: [PATCH v5 06/15] emul/ns16x50: implement THR/RBR registers
Date: Fri, 5 Sep 2025 15:29:29 -0700	[thread overview]
Message-ID: <aLtkSe2ONQJCgxXx@kraken> (raw)
In-Reply-To: <alpine.DEB.2.22.394.2508291331590.341243@ubuntu-linux-20-04-desktop>

On Fri, Aug 29, 2025 at 01:34:39PM -0700, Stefano Stabellini wrote:
> On Fri, 29 Aug 2025, Stefano Stabellini wrote:
> > On Thu, 28 Aug 2025, dmukhin@xen.org wrote:
> > > From: Denis Mukhin <dmukhin@ford.com> 
> > > 
> > > Add RBR/THR registers emulation to the I/O port handlder.
> > > 
> > > Also, add RX/TX FIFO management code since RBR depends on RX FIFO and
> > > THR depends on TX FIFO.
> > > 
> > > FIFOs are not emulated as per UART specs for simplicity (not need to emulate
> > > baud rate). Emulator does not emulate NS8250 (no FIFO), NS16550a (16 bytes) or
> > > NS16750 (64 bytes).
> > > 
> > > FIFOs are emulated by means of using xencons_interface which conveniently
> > > provides primitives for buffer management and later can be used for
> > > inter-domain communication similarly to vpl011.
> > > 
> > > Signed-off-by: Denis Mukhin <dmukhin@ford.com>
> > > ---
> > > Changes since v4:
> > > - new patch
> > > ---
> > >  xen/common/emul/vuart/ns16x50.c | 135 ++++++++++++++++++++++++++++++++
> > >  1 file changed, 135 insertions(+)
> > > 
> > > diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x50.c
> > > index 20597cc36b35..efb2f4c6441c 100644
> > > --- a/xen/common/emul/vuart/ns16x50.c
> > > +++ b/xen/common/emul/vuart/ns16x50.c
> > > @@ -92,6 +92,119 @@ static bool ns16x50_fifo_rx_empty(const struct vuart_ns16x50 *vdev)
> > >      return cons->in_prod == cons->in_cons;
> > >  }
> > >  
> > > +static bool ns16x50_fifo_rx_full(const struct vuart_ns16x50 *vdev)
> > > +{
> > > +    const struct xencons_interface *cons = &vdev->cons;
> > > +
> > > +    return cons->in_prod - cons->in_cons == ARRAY_SIZE(cons->in);
> > > +}
> > > +
> > > +static void ns16x50_fifo_rx_reset(struct vuart_ns16x50 *vdev)
> > > +{
> > > +    struct xencons_interface *cons = &vdev->cons;
> > > +
> > > +    cons->in_cons = cons->in_prod;
> > > +}
> > > +
> > > +static int ns16x50_fifo_rx_getchar(struct vuart_ns16x50 *vdev)
> > > +{
> > > +    struct xencons_interface *cons = &vdev->cons;
> > > +    int rc;
> > > +
> > > +    if ( ns16x50_fifo_rx_empty(vdev) )
> > > +    {
> > > +        ns16x50_debug(vdev, "RX FIFO empty\n");
> > > +        rc = -ENODATA;
> > > +    }
> > > +    else
> > > +    {
> > > +        rc = cons->in[MASK_XENCONS_IDX(cons->in_cons, cons->in)];
> > > +        cons->in_cons++;
> > > +    }
> > > +
> > > +    return rc;
> > 
> > The signed integer to char conversion here is not great from a MISRA
> > perspective. I think it would be better to keep rc as success/failure
> > return value and take the read char as a pointer parameter.
> > 
> > 
> > > +}
> > > +
> > > +static int ns16x50_fifo_rx_putchar(struct vuart_ns16x50 *vdev, char c)
> > > +{
> > > +    struct xencons_interface *cons = &vdev->cons;
> > > +    int rc;
> > > +
> > > +    /*
> > > +     * FIFO-less 8250/16450 UARTs: newly arrived word overwrites the contents
> > > +     * of the THR.
> > > +     */
> > > +    if ( ns16x50_fifo_rx_full(vdev) )
> > > +    {
> > > +        ns16x50_debug(vdev, "RX FIFO full; resetting\n");
> > > +        ns16x50_fifo_rx_reset(vdev);
> > > +        rc = -ENOSPC;
> > > +    }
> > > +    else
> > > +        rc = 0;
> > > +
> > > +    cons->in[MASK_XENCONS_IDX(cons->in_prod, cons->in)] = c;
> > > +    cons->in_prod++;
> > > +
> > > +    return rc;
> > > +}
> > > +
> > > +static bool ns16x50_fifo_tx_empty(const struct vuart_ns16x50 *vdev)
> > > +{
> > > +    const struct xencons_interface *cons = &vdev->cons;
> > > +
> > > +    return cons->out_prod == cons->out_cons;
> > > +}
> > > +
> > > +static void ns16x50_fifo_tx_reset(struct vuart_ns16x50 *vdev)
> > > +{
> > > +    struct xencons_interface *cons = &vdev->cons;
> > > +
> > > +    cons->out_prod = 0;
> > > +    ASSERT(cons->out_cons == cons->out_prod);
> > 
> > I am not sure about this.. why resetting the out_prod index? In theory
> > it could keep increasing until wrap around and still go forward thanks
> > to the mask
> 
> I get it now .. it is because it is called from ns16x50_fifo_tx_flush
> right after printing to the real console.
> 
> I think it is better to simply do:
> 
>   cons->out_cons = cons->out_prod;
> 
> which effectively clears out the whole buffer. It is dangerous to do:

That was OK to use TX buffer in such awkward manner because of the assertions
and buffer size checks. I reworked that part in v6.

> 
>   cons->out_prod = 0;
> 
> without also doing:
> 
>   cons->out_cons = 0;
> 
> Also, if ns16x50_fifo_tx_flush is the only caller of
> ns16x50_fifo_tx_reset, I would open code the implementation directly
> inside ns16x50_fifo_tx_flush to make it more obvious.

The will be another callsite for ns16x50_fifo_tx_reset() - FCR (in v6).

> 
> 
> > > +}
> > > +
> > > +/*
> > > + * Flush cached output to Xen console.
> > > + */
> > > +static void ns16x50_fifo_tx_flush(struct vuart_ns16x50 *vdev)
> > > +{
> > > +    struct xencons_interface *cons = &vdev->cons;
> > > +    struct domain *d = vdev->owner;
> > > +
> > > +    if ( ns16x50_fifo_tx_empty(vdev) )
> > > +        return;
> > > +
> > > + UART_IIR_THR   ASSERT(cons->out_prod < ARRAY_SIZE(cons->out));
> > > +    cons->out[cons->out_prod] = '\0';
> > 
> > should use MASK_XENCONS_IDX to access the array
> > 
> > 
> > > +    cons->out_prod++;
> > > +
> > > +    guest_printk(d, guest_prefix "%s", cons->out);
> > > +
> > > +    ns16x50_fifo_tx_reset(vdev);
> > 
> > set UART_IIR_THR and call ns16x50_irq_check ?
> > 
> > 
> > > +}
> 


  reply	other threads:[~2025-09-05 22:29 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-28 23:53 [PATCH v5 00/15] x86: introduce NS16550-compatible UART emulator dmukhin
2025-08-28 23:53 ` [PATCH v5 01/15] emul/vuart: introduce framework for UART emulators dmukhin
2025-08-29 19:27   ` Stefano Stabellini
2025-09-01  8:14     ` Jan Beulich
2025-09-01 22:27       ` dmukhin
2025-09-02  6:14         ` Jan Beulich
2025-09-01 22:11     ` dmukhin
2025-08-28 23:53 ` [PATCH v5 02/15] xen/8250-uart: update definitions dmukhin
2025-08-29 19:32   ` Stefano Stabellini
2025-09-01 22:28     ` dmukhin
2025-08-28 23:53 ` [PATCH v5 03/15] emul/ns16x50: implement emulator stub dmukhin
2025-08-29 19:57   ` Stefano Stabellini
2025-09-01 23:11     ` dmukhin
2025-09-02  9:32       ` Jan Beulich
2025-09-05 23:34         ` dmukhin
2025-09-06  0:07           ` dmukhin
2025-09-02  9:36     ` Jan Beulich
2025-09-05 23:34       ` dmukhin
2025-08-28 23:53 ` [PATCH v5 04/15] emul/ns16x50: implement DLL/DLM registers dmukhin
2025-08-28 23:53 ` [PATCH v5 05/15] emul/ns16x50: implement EIR/IIR registers dmukhin
2025-08-29 20:14   ` Stefano Stabellini
2025-09-05 22:05     ` dmukhin
2025-08-28 23:54 ` [PATCH v5 06/15] emul/ns16x50: implement THR/RBR registers dmukhin
2025-08-29 20:28   ` Stefano Stabellini
2025-08-29 20:34     ` Stefano Stabellini
2025-09-05 22:29       ` dmukhin [this message]
2025-09-05 22:20     ` dmukhin
2025-08-28 23:54 ` [PATCH v5 07/15] emul/ns16x50: implement FCR register (write-only) dmukhin
2025-08-29 20:38   ` Stefano Stabellini
2025-09-05 22:33     ` dmukhin
2025-08-28 23:54 ` [PATCH v5 08/15] emul/ns16x50: implement LCR/LSR registers dmukhin
2025-08-28 23:54 ` [PATCH v5 09/15] emul/ns16x50: implement MCR/MSR registers dmukhin
2025-08-28 23:54 ` [PATCH v5 10/15] emul/ns16x50: implement SCR register dmukhin
2025-08-28 23:54 ` [PATCH v5 11/15] emul/ns16x50: implement put_rx() hook dmukhin
2025-08-28 23:54 ` [PATCH v5 12/15] emul/ns16550: implement dump_state() hook dmukhin
2025-08-28 23:54 ` [PATCH v5 13/15] x86/domain: enable per-domain I/O port bitmaps dmukhin
2025-08-29 21:43   ` Stefano Stabellini
2025-09-05 22:38     ` dmukhin
2025-08-28 23:54 ` [PATCH v5 14/15] xen/domain: allocate d->irq_caps before arch-specific initialization dmukhin
2025-08-29 21:46   ` Stefano Stabellini
2025-09-05 22:43     ` dmukhin
2025-08-28 23:54 ` [PATCH v5 15/15] emul/ns16x50: implement IRQ emulation via vIOAPIC dmukhin
2025-08-29 22:21   ` Stefano Stabellini
2025-09-05 22:54     ` dmukhin
2025-09-05 23:01       ` Stefano Stabellini
2025-09-05 23:44         ` dmukhin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aLtkSe2ONQJCgxXx@kraken \
    --to=dmukhin@xen.org \
    --cc=andrew.cooper3@citrix.com \
    --cc=anthony.perard@vates.tech \
    --cc=dmukhin@ford.com \
    --cc=jbeulich@suse.com \
    --cc=julien@xen.org \
    --cc=michal.orzel@amd.com \
    --cc=roger.pau@citrix.com \
    --cc=sstabellini@kernel.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.