|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH RFC] ARM: vPL011: use receive timeout interrupt
Hi Andre,
I verified this patch on qualcomm platform. It is working fine.
On 18 October 2017 at 19:11, Andre Przywara <andre.przywara@xxxxxxx> wrote:
> Instead of asserting the receive interrupt (RXI) on the first character
> in the FIFO, lets (ab)use the receive timeout interrupt (RTI) for that
> purpose. That seems to be closer to the spec and what hardware does.
> Improve the readability of vpl011_data_avail() on the way.
>
> Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx>
> ---
> Hi,
>
> this one is the approach I mentioned in the email earlier today.
> It goes on top of Bhupinders v12 27/27, but should eventually be merged
> into this one once we agreed on the subject. I just carved it out here
> for clarity to make it clearer what has been changed.
> Would be good if someone could test it.
>
> Cheers,
> Andre.
> xen/arch/arm/vpl011.c | 61
> ++++++++++++++++++++++++---------------------------
> 1 file changed, 29 insertions(+), 32 deletions(-)
>
> diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c
> index adf1711571..ae18bddd81 100644
> --- a/xen/arch/arm/vpl011.c
> +++ b/xen/arch/arm/vpl011.c
> @@ -105,9 +105,13 @@ static uint8_t vpl011_read_data(struct domain *d)
> if ( fifo_level == 0 )
> {
> vpl011->uartfr |= RXFE;
> - vpl011->uartris &= ~RXI;
> - vpl011_update_interrupt_status(d);
> + vpl011->uartris &= ~RTI;
> }
> +
> + if ( fifo_level < sizeof(intf->in) - SBSA_UART_FIFO_SIZE / 2 )
> + vpl011->uartris &= ~RXI;
> +
> + vpl011_update_interrupt_status(d);
I think we check if ( fifo_level < SBSA_UART_FIFO_SIZE / 2 ) which
should be a valid condition to clear the RX interrupt.
> }
> else
> gprintk(XENLOG_ERR, "vpl011: Unexpected IN ring buffer empty\n");
> @@ -129,7 +133,7 @@ static void vpl011_update_tx_fifo_status(struct vpl011
> *vpl011,
> unsigned int fifo_level)
> {
> struct xencons_interface *intf = vpl011->ring_buf;
> - unsigned int fifo_threshold;
> + unsigned int fifo_threshold = sizeof(intf->out) - SBSA_UART_FIFO_SIZE/2;
>
> BUILD_BUG_ON(sizeof (intf->out) < SBSA_UART_FIFO_SIZE);
>
> @@ -137,8 +141,6 @@ static void vpl011_update_tx_fifo_status(struct vpl011
> *vpl011,
> * Set the TXI bit only when there is space for fifo_size/2 bytes which
> * is the trigger level for asserting/de-assterting the TX interrupt.
> */
> - fifo_threshold = sizeof(intf->out) - SBSA_UART_FIFO_SIZE/2;
> -
> if ( fifo_level <= fifo_threshold )
> vpl011->uartris |= TXI;
> else
> @@ -390,35 +392,30 @@ static void vpl011_data_avail(struct domain *d)
> out_cons,
> sizeof(intf->out));
>
> - /* Update the uart rx state if the buffer is not empty. */
> - if ( in_fifo_level != 0 )
> - {
> + /**** Update the UART RX state ****/
> +
> + /* Clear the FIFO_EMPTY bit if the FIFO holds at least one character. */
> + if ( in_fifo_level > 0 )
> vpl011->uartfr &= ~RXFE;
>
> - if ( in_fifo_level == sizeof(intf->in) )
> - vpl011->uartfr |= RXFF;
> + /* Set the FIFO_FULL bit if the ring buffer is full. */
> + if ( in_fifo_level == sizeof(intf->in) )
> + vpl011->uartfr |= RXFF;
>
> - /*
> - * Currently, the RXI bit is getting set even if there is a single
> - * byte of data in the rx fifo. Ideally, the RXI bit should be set
> - * only if the rx fifo level reaches the threshold.
> - *
> - * However, since currently RX timeout interrupt is not
> - * implemented as there is not enough clarity in the SBSA spec,
> - * the guest may keep waiting for an interrupt to read more
> - * data. To ensure that guest reads all the data without
> - * any delay, the RXI interrupt is raised if there is RX data
> - * available without checking whether fifo level has reached
> - * the threshold.
> - *
> - * TBD: Once there is more clarity in the SBSA spec on whether RX
> - * timeout interrupt needs to be implemented, the RXI interrupt
> - * will be raised only when rx fifo level reaches the threshold.
> - */
> + /* The FIFO trigger level is fixed to half of the FIFO. */
> + if ( in_fifo_level >= sizeof(intf->in) - SBSA_UART_FIFO_SIZE / 2 )
> vpl011->uartris |= RXI;
Here also should not we check if ( in_fifo_level >=
SBSA_UART_FIFO_SIZE / 2 ) since it is a valid condition to raise the
RX interrupt?
> - }
>
> - /* Update the uart tx state if the buffer is not full. */
> + /*
> + * If the input queue is not empty, we assert the receive timeout
> interrupt.
> + * As we don't emulate any timing here, we ignore the actual timeout
> + * of 32 bit periods.
> + */
> + if ( in_fifo_level > 0 )
> + vpl011->uartris |= RTI;
> +
> + /**** Update the UART TX state ****/
> +
> if ( out_fifo_level != sizeof(intf->out) )
> {
> vpl011->uartfr &= ~TXFF;
> @@ -431,13 +428,13 @@ static void vpl011_data_avail(struct domain *d)
> vpl011->uartfr &= ~BUSY;
>
> vpl011_update_tx_fifo_status(vpl011, out_fifo_level);
> -
> - if ( out_fifo_level == 0 )
> - vpl011->uartfr |= TXFE;
> }
>
> vpl011_update_interrupt_status(d);
>
> + if ( out_fifo_level == 0 )
> + vpl011->uartfr |= TXFE;
> +
> VPL011_UNLOCK(d, flags);
> }
>
> --
> 2.14.1
>
Regards,
Bhupinder
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |