diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c index 5bbed3a36a..39ad935266 100644 --- a/xen/arch/x86/pv/dom0_build.c +++ b/xen/arch/x86/pv/dom0_build.c @@ -354,6 +354,8 @@ static struct page_info * __init alloc_chunk(struct domain *d, return page; } +extern void serial_debug(void); + int __init dom0_construct_pv(struct domain *d, const module_t *image, unsigned long image_headroom, @@ -412,6 +414,7 @@ int __init dom0_construct_pv(struct domain *d, /* Machine address of next candidate page-table page. */ paddr_t mpt_alloc; + serial_debug(); printk(XENLOG_INFO "*** Building a PV Dom%d ***\n", d->domain_id); d->max_pages = ~0U; diff --git a/xen/drivers/char/serial.c b/xen/drivers/char/serial.c index 324024c29a..d6a4d62a07 100644 --- a/xen/drivers/char/serial.c +++ b/xen/drivers/char/serial.c @@ -71,6 +71,80 @@ void serial_rx_interrupt(struct serial_port *port, struct cpu_user_regs *regs) (*fn)(c & 0x7f, regs); } +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef NS16550_PCI +#include +#include +#include +#endif +#include +#include +#include +#ifdef CONFIG_HAS_DEVICE_TREE +#include +#endif +#ifdef CONFIG_X86 +#include +#endif + +#define NS16550_PCI + +struct ns16550 { + int baud, clock_hz, data_bits, parity, stop_bits, fifo_size, irq; + u64 io_base; /* I/O port or memory-mapped I/O address. */ + u64 io_size; + int reg_shift; /* Bits to shift register offset by */ + int reg_width; /* Size of access to use, the registers + * themselves are still bytes */ + char __iomem *remapped_io_base; /* Remapped virtual address of MMIO. */ + /* UART with IRQ line: interrupt-driven I/O. */ + struct irqaction irqaction; + u8 lsr_mask; +#ifdef CONFIG_ARM + struct vuart_info vuart; +#endif + /* UART with no IRQ line: periodically-polled I/O. */ + struct timer timer; + struct timer resume_timer; + unsigned int timeout_ms; + bool intr_works; + bool dw_usr_bsy; +#ifdef NS16550_PCI + /* PCI card parameters. */ + bool pb_bdf_enable; /* if =1, pb-bdf effective, port behind bridge */ + bool ps_bdf_enable; /* if =1, ps_bdf effective, port on pci card */ + unsigned int pb_bdf[3]; /* pci bridge BDF */ + unsigned int ps_bdf[3]; /* pci serial port BDF */ + u32 bar; + u32 bar64; + u16 cr; + u8 bar_idx; + bool msi; + const struct ns16550_config_param *param; /* Points into .init.*! */ +#endif +}; + +int skipped_interrupts = 0; + +void serial_debug(void) +{ + struct serial_port *port = &com[SERHND_COM1]; + struct ns16550 *uart = port->uart; + printk("SERIAL DEBUG: txbufc: %#x, txbufp: %#x, uart intr_works: %d, serial_txbufsz: %#x, tx_ready: %d, " + "lsr_mask: %#x, msi: %d, io_size: %ld, skipped_interrupts: %d\n", + port->txbufc, port->txbufp, uart->intr_works, + serial_txbufsz, + port->driver->tx_ready(port), + uart->lsr_mask, uart->msi, uart->io_size, skipped_interrupts); +} + void serial_tx_interrupt(struct serial_port *port, struct cpu_user_regs *regs) { int i, n; @@ -85,8 +159,10 @@ void serial_tx_interrupt(struct serial_port *port, struct cpu_user_regs *regs) */ while ( !spin_trylock(&port->tx_lock) ) { - if ( port->driver->tx_ready(port) <= 0 ) + if ( port->driver->tx_ready(port) <= 0 ) { + skipped_interrupts++; goto out; + } cpu_relax(); }