[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v5 11/15] emul/ns16x50: implement put_rx() hook



From: Denis Mukhin <dmukhin@xxxxxxxx> 

Implement put_rx() vUART hook for placing a character into the emulated RX
FIFO from console driver.

That implements physical console forwarding to the guest OS over emulated
NS16550.

Signed-off-by: Denis Mukhin <dmukhin@xxxxxxxx>
---
Changes since v4:
- new patch
---
 xen/common/emul/vuart/ns16x50.c | 48 ++++++++++++++++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x50.c
index d57695564329..1fb65370d464 100644
--- a/xen/common/emul/vuart/ns16x50.c
+++ b/xen/common/emul/vuart/ns16x50.c
@@ -804,13 +804,59 @@ static void cf_check ns16x50_free(void *arg)
     XVFREE(vdev);
 }
 
+static int cf_check ns16x50_put_rx(void *arg, char ch)
+{
+    struct vuart_ns16x50 *vdev = arg;
+    uint8_t *regs;
+    uint8_t dlab;
+    int rc = -EBUSY;
+
+    spin_lock(&vdev->lock);
+
+    dlab = ns16x50_dlab_get(vdev);
+    regs = vdev->regs;
+
+    if ( dlab )
+        ns16x50_debug(vdev, "THR/RBR access disabled: DLAB=1\n");
+    else if ( regs[UART_MCR] & UART_MCR_LOOP )
+        ns16x50_debug(vdev, "THR/RBR access disabled: loopback mode\n");
+    else
+    {
+        struct vuart *vuart = container_of(arg, struct vuart, vdev);
+        struct domain *d = vuart->owner;
+        uint8_t val = 0;
+
+        rc = ns16x50_fifo_rx_putchar(vdev, ch);
+        if ( rc == -ENOSPC )
+            val |= UART_LSR_OE;
+
+        /* NB: UART_LSR_DR is also set when UART_LSR is accessed. */
+        regs[UART_LSR] |= UART_LSR_DR | val;
+
+        /*
+         * Echo the user input on Xen console iff Xen console input is owned
+         * by ns16x50 domain.
+         * NB: use 'console_timestamps=none' to disable Xen timestamps.
+         */
+        if ( is_console_printable(ch) )
+            guest_printk(d, "%c", ch);
+
+        /* FIXME: check FCR when to fire an interrupt */
+        ns16x50_irq_check(vdev);
+    }
+
+    spin_unlock(&vdev->lock);
+
+    return rc;
+}
+
 #define ns16x50_emulator                \
 {                                       \
     .compatible = "ns16550",            \
     .alloc      = ns16x50_alloc,        \
     .free       = ns16x50_free,         \
     .dump_state = NULL,                 \
-    .put_rx     = NULL,                 \
+    .put_rx     = ns16x50_put_rx,       \
 }
 
 VUART_REGISTER(ns16x50, ns16x50_emulator);
-- 
2.51.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.