|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v8 13/26] 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>
---
xen/common/emul/vuart/ns16x50.c | 64 ++++++++++++++++++++++++++++++++-
1 file changed, 63 insertions(+), 1 deletion(-)
diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x50.c
index 404e12311090..cda21c15cf78 100644
--- a/xen/common/emul/vuart/ns16x50.c
+++ b/xen/common/emul/vuart/ns16x50.c
@@ -728,6 +728,62 @@ 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;
+ const struct vuart_info *info;
+ const struct xencons_interface *cons;
+ const uint8_t *regs;
+ const char *as = (info->base_type & IORESOURCE_IO) ? "ioport":
+ "iomem";
+ unsigned long flags;
+
+ ASSERT(vdev);
+
+ /* Allow printing state in case of a deadlock. */
+ if ( !ns16x50_trylock(vdev, &flags) )
+ return;
+
+ d = vdev->owner;
+ info = vdev->info;
+ cons = &vdev->cons;
+ regs = &vdev->regs[0];
+
+ printk("Virtual " pr_prefix " (%s) %s %#"PRIx64" IRQ#%d owner %pd\n",
+ vdev->name, as, 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->in)],
+ cons->out[MASK_XENCONS_IDX(cons->out_prod, cons->out)],
+ 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]);
+
+ ns16x50_unlock(vdev, &flags);
+#endif /* CONFIG_VUART_NS16X50_DEBUG */
+}
+
static void ns16x50_access(int dir, unsigned int type,
unsigned long addr, unsigned int size,
uint32_t *data)
@@ -794,6 +850,9 @@ static void ns16x50_access(int dir, unsigned int type,
rc = ns16x50_io_read(vdev, reg, size, data);
+ if ( ns16x50_log_level >= 3 )
+ ns16x50_dump_state(vdev);
+
if ( rc == 0 )
ns16x50_debug(vdev, "%c %s %#"PRIx64" %d: LCR=%#02x %#02x %#08x\n",
op, as, addr, size, vdev->regs[UART_LCR], reg, *data);
@@ -971,6 +1030,9 @@ static int cf_check ns16x50_put_rx(void *arg, char ch)
ns16x50_unlock(vdev, &flags);
+ if ( ns16x50_log_level >= 3 )
+ ns16x50_dump_state(vdev);
+
return rc;
}
@@ -979,7 +1041,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.56.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |