[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 26/27 v8] xen/arm: vpl011: Correct the logic for asserting/de-asserting SBSA UART TX interrupt
This patch fixes the issue observed when pl011 patches were tested on the junos hardware by Andre/Julien. It was observed that when large output is generated such as on running 'find /', output was getting truncated intermittently due to OUT ring buffer getting full. This issue was due to the fact that the SBSA UART driver expects that when a TX interrupt is asserted then the FIFO queue should be atleast half empty and that it can write N bytes in the FIFO, where N is half the FIFO queue size, without the bytes getting dropped due to FIFO getting full. This requirement is as per section 3.4.2 of [1], which is: ------------------------------------------------------------------------------- UARTTXINTR If the FIFOs are enabled and the transmit FIFO reaches the programmed trigger level. When this happens, the transmit interrupt is asserted HIGH. The transmit interrupt is cleared by writing data to the transmit FIFO until it becomes greater than the trigger level, or by clearing the interrupt. ------------------------------------------------------------------------------- The SBSA UART fifo size is 32 bytes and so it expects that space for 16 bytes should be available when TX interrupt is asserted. The pl011 emulation logic was asserting the TX interrupt as soon as any space became available in the FIFO and the SBSA UART driver tried to write more data (upto 16 bytes) in the FIFO expecting that there is enough space available. The fix was to ensure that the TX interriupt is raised only when there is space available for 16 bytes or more in the FIFO. [1] http://infocenter.arm.com/help/topic/com.arm.doc.ddi0183f/DDI0183.pdf Signed-off-by: Bhupinder Thakur <bhupinder.thakur@xxxxxxxxxx> --- CC: Julien Grall <julien.grall@xxxxxxx> CC: Andre Przywara <andre.przywara@xxxxxxx> CC: Stefano Stabellini <sstabellini@xxxxxxxxxx> xen/arch/arm/vpl011.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c index 56d9cbe..1e72fca 100644 --- a/xen/arch/arm/vpl011.c +++ b/xen/arch/arm/vpl011.c @@ -152,12 +152,20 @@ static void vpl011_write_data(struct domain *d, uint8_t data) else gprintk(XENLOG_ERR, "vpl011: Unexpected OUT ring buffer full\n"); - if ( xencons_queued(out_prod, out_cons, sizeof(intf->out)) == - sizeof (intf->out) ) - { - vpl011->uartfr |= TXFF; + /* + * Ensure that there is space for atleast 16 bytes before asserting the + * TXI interrupt status bit because the SBSA UART driver may write + * 16 bytes (i.e. half the SBSA UART fifo size of 32) on getting + * a TX interrupt. + */ + if ( xencons_queued(out_prod, out_cons, sizeof(intf->out)) <= + (sizeof (intf->out) - 16) ) + vpl011->uartris |= TXI; + else if ( xencons_queued(out_prod, out_cons, sizeof(intf->out)) != + sizeof (intf->out) ) vpl011->uartris &= ~TXI; - } + else + vpl011->uartfr |= TXFF; vpl011->uartfr |= BUSY; @@ -368,7 +376,16 @@ static void vpl011_data_avail(struct domain *d) if ( out_ring_qsize != sizeof(intf->out) ) { vpl011->uartfr &= ~TXFF; - vpl011->uartris |= TXI; + + /* + * Ensure that there is space for atleast 16 bytes before asserting the + * TXI interrupt status bit because the SBSA UART driver may write upto + * 16 bytes (i.e. half the SBSA UART fifo size of 32) on getting + * a TX interrupt. + */ + if ( out_ring_qsize <= (sizeof(intf->out) - 16) ) + vpl011->uartris |= TXI; + if ( out_ring_qsize == 0 ) { vpl011->uartfr &= ~BUSY; -- 2.7.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |