From: Denis Mukhin <dmuk...@ford.com> 

Add LCR/LSR registers implementation to the I/O port handler.

Signed-off-by: Denis Mukhin <dmuk...@ford.com>
---
Changes since v4:
- new patch
---
 xen/common/emul/vuart/ns16x50.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x50.c
index 65ca96dd8bd3..687a7ea2fabe 100644
--- a/xen/common/emul/vuart/ns16x50.c
+++ b/xen/common/emul/vuart/ns16x50.c
@@ -347,6 +347,9 @@ static int ns16x50_io_write8(
             else
                 ns16x50_fifo_tx_putchar(vdev, val);
 
+            if ( rc == -ENOSPC )
+                regs[UART_LSR] |= UART_LSR_OE;
+
             rc = 0;
 
             break;
@@ -387,6 +390,11 @@ static int ns16x50_io_write8(
 
             break;
 
+        case UART_LCR:
+            regs[UART_LCR] = val;
+            break;
+
+        case UART_LSR: /* RO */
         default:
             rc = -EINVAL;
             break;
@@ -460,6 +468,9 @@ static int ns16x50_io_read8(
         switch ( reg )
         {
         case UART_RBR:
+            /* NB: do not forget to clear overrun condition */
+            regs[UART_LSR] &= ~UART_LSR_OE;
+
             rc = ns16x50_fifo_rx_getchar(vdev);
             if ( rc >= 0 )
                 val = (uint8_t)rc;
@@ -480,6 +491,21 @@ static int ns16x50_io_read8(
 
             break;
 
+        case UART_LCR:
+            val = regs[UART_LCR];
+            break;
+
+        case UART_LSR:
+            val = regs[UART_LSR] | UART_LSR_THRE | UART_LSR_TEMT;
+            if ( ns16x50_fifo_rx_empty(vdev) )
+                val &= ~UART_LSR_DR;
+            else
+                val |= UART_LSR_DR;
+
+            regs[UART_LSR] = val & ~UART_LSR_MASK;
+
+            break;
+
         default:
             rc = -EINVAL;
             break;
-- 
2.51.0


Reply via email to