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

[PATCH v5 12/15] emul/ns16550: implement dump_state() hook



From: Denis Mukhin <dmukhin@xxxxxxxx> 

Implement dump_state() vUART hook for debugging UART state machine over Xen
console. dump_state() prints state of all emulated registers (including
state-less IIR) and state of RX/TX FIFOs.

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

diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x50.c
index 1fb65370d464..5c1be854b544 100644
--- a/xen/common/emul/vuart/ns16x50.c
+++ b/xen/common/emul/vuart/ns16x50.c
@@ -636,6 +636,58 @@ static int ns16x50_io_read(
     return rc;
 }
 
+static void cf_check ns16x50_dump_state(void *arg)
+{
+#ifdef CONFIG_VUART_NS16X50_DEBUG
+    struct vuart_ns16x50 *vdev = arg;
+    const struct domain *d = vdev->owner;
+    const struct vuart_info *info = vdev->info;
+    const struct xencons_interface *cons;
+    const uint8_t *regs;
+
+    if ( !vdev )
+        return;
+
+    /* Allow printing state in case of a deadlock. */
+    if ( !spin_trylock(&vdev->lock) )
+        return;
+
+    cons = &vdev->cons;
+    regs = &vdev->regs[0];
+
+    printk("Virtual " pr_prefix " (%s) I/O port 0x%04"PRIx64" IRQ#%d owner 
%pd\n",
+            vdev->name, info->base_addr, info->irq, d);
+
+    printk("  RX FIFO size %ld in_prod %d in_cons %d used %d\n",
+            ARRAY_SIZE(cons->in), cons->in_prod, cons->in_cons,
+            cons->in_prod - cons->in_cons);
+
+    printk("  TX FIFO size %ld out_prod %d out_cons %d used %d\n",
+            ARRAY_SIZE(cons->out), cons->out_prod, cons->out_cons,
+            cons->out_prod - cons->out_cons);
+
+    printk("  %02"PRIx8" RBR %02"PRIx8" THR %02"PRIx8" DLL %02"PRIx8" DLM 
%02"PRIx8"\n",
+            UART_RBR,
+            cons->in[MASK_XENCONS_IDX(cons->in_prod, cons)],
+            cons->out[MASK_XENCONS_IDX(cons->out_prod, cons)],
+            regs[NS16X50_REGS_NUM + UART_DLL],
+            regs[NS16X50_REGS_NUM + UART_DLM]);
+
+    printk("  %02"PRIx8" IER %02"PRIx8"\n", UART_IER, regs[UART_IER]);
+
+    printk("  %02"PRIx8" FCR %02"PRIx8" IIR %02"PRIx8"\n",
+            UART_FCR, regs[UART_FCR], ns16x50_iir_get(vdev));
+
+    printk("  %02"PRIx8" LCR %02"PRIx8"\n", UART_LCR, regs[UART_LCR]);
+    printk("  %02"PRIx8" MCR %02"PRIx8"\n", UART_MCR, regs[UART_MCR]);
+    printk("  %02"PRIx8" LSR %02"PRIx8"\n", UART_LSR, regs[UART_LSR]);
+    printk("  %02"PRIx8" MSR %02"PRIx8"\n", UART_MSR, regs[UART_MSR]);
+    printk("  %02"PRIx8" SCR %02"PRIx8"\n", UART_SCR, regs[UART_SCR]);
+
+    spin_unlock(&vdev->lock);
+#endif /* CONFIG_VUART_NS16X50_DEBUG */
+}
+
 /*
  * Emulate I/O access to ns16x50 register.
  * Note, emulation always returns X86EMUL_OKAY, once I/O port trap is enabled.
@@ -712,6 +764,9 @@ static int cf_check ns16x50_io_handle(
 
     spin_unlock(&vdev->lock);
 
+    if ( ns16x50_log_level >= 3 ) 
+        ns16x50_dump_state(vdev);
+
 out:
     rcu_unlock_domain(d);
 
@@ -846,6 +901,8 @@ static int cf_check ns16x50_put_rx(void *arg, char ch)
     }
 
     spin_unlock(&vdev->lock);
+    if ( ns16x50_log_level >= 3 )
+        ns16x50_dump_state(vdev);
 
     return rc;
 }
@@ -855,7 +912,7 @@ static int cf_check ns16x50_put_rx(void *arg, char ch)
     .compatible = "ns16550",            \
     .alloc      = ns16x50_alloc,        \
     .free       = ns16x50_free,         \
-    .dump_state = NULL,                 \
+    .dump_state = ns16x50_dump_state,   \
     .put_rx     = ns16x50_put_rx,       \
 }
 
-- 
2.51.0




 


Rackspace

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