[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC 13/15] xen/arm: Allow vpl011 to be used by DomU
Make vpl011 being able to be used without a userspace component in Dom0. In that case, output is printed to the Xen serial and input is received from the Xen serial one character at a time. Call domain_vpl011_init during construct_domU. Signed-off-by: Stefano Stabellini <stefanos@xxxxxxxxxx> --- xen/arch/arm/domain_build.c | 9 +++- xen/arch/arm/vpl011.c | 98 +++++++++++++++++++++++++++++++++----------- xen/include/asm-arm/vpl011.h | 2 + 3 files changed, 84 insertions(+), 25 deletions(-) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index ff65057..97f14ca 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -2482,7 +2482,14 @@ int __init construct_domU(struct domain *d, struct dt_device_node *node) if ( rc < 0 ) return rc; - return __construct_domain(d, &kinfo); + rc = __construct_domain(d, &kinfo); + if ( rc < 0 ) + return rc; + +#ifdef CONFIG_SBSA_VUART_CONSOLE + rc = domain_vpl011_init(d, NULL); +#endif + return rc; } int __init construct_dom0(struct domain *d) diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c index a281eab..5f1dc7a 100644 --- a/xen/arch/arm/vpl011.c +++ b/xen/arch/arm/vpl011.c @@ -34,6 +34,8 @@ #include <asm/vgic-emul.h> #include <asm/vpl011.h> +static void vpl011_data_avail(struct domain *d); + /* * Since pl011 registers are 32-bit registers, all registers * are handled similarly allowing 8-bit, 16-bit and 32-bit @@ -77,6 +79,29 @@ static void vpl011_update_interrupt_status(struct domain *d) #endif } +void vpl011_read_char(struct domain *d, char c) +{ + unsigned long flags; + XENCONS_RING_IDX in_cons, in_prod; + struct xencons_interface *intf = d->arch.vpl011.ring_buf; + + VPL011_LOCK(d, flags); + + in_cons = intf->in_cons; + in_prod = intf->in_prod; + if (xencons_queued(in_prod, in_cons, sizeof(intf->in)) == sizeof(intf->in)) + { + VPL011_UNLOCK(d, flags); + return; + } + + intf->in[xencons_mask(in_prod, sizeof(intf->in))] = c; + intf->in_prod = in_prod + 1; + + VPL011_UNLOCK(d, flags); + vpl011_data_avail(d); +} + static uint8_t vpl011_read_data(struct domain *d) { unsigned long flags; @@ -166,9 +191,18 @@ static void vpl011_write_data(struct domain *d, uint8_t data) struct vpl011 *vpl011 = &d->arch.vpl011; struct xencons_interface *intf = vpl011->ring_buf; XENCONS_RING_IDX out_cons, out_prod; + unsigned int fifo_level = 0; VPL011_LOCK(d, flags); + if ( vpl011->ring_page == NULL ) + { + printk("%c", data); + if (data == '\n') + printk("DOM%u: ", d->domain_id); + goto done; + } + out_cons = intf->out_cons; out_prod = intf->out_prod; @@ -184,13 +218,10 @@ static void vpl011_write_data(struct domain *d, uint8_t data) if ( xencons_queued(out_prod, out_cons, sizeof(intf->out)) != sizeof (intf->out) ) { - unsigned int fifo_level; - intf->out[xencons_mask(out_prod, sizeof(intf->out))] = data; out_prod += 1; smp_wmb(); intf->out_prod = out_prod; - fifo_level = xencons_queued(out_prod, out_cons, sizeof(intf->out)); if ( fifo_level == sizeof(intf->out) ) @@ -205,14 +236,15 @@ static void vpl011_write_data(struct domain *d, uint8_t data) */ vpl011->uartfr |= BUSY; } - - vpl011_update_tx_fifo_status(vpl011, fifo_level); - - vpl011_update_interrupt_status(d); } else gprintk(XENLOG_ERR, "vpl011: Unexpected OUT ring buffer full\n"); +done: + vpl011_update_tx_fifo_status(vpl011, fifo_level); + + vpl011_update_interrupt_status(d); + vpl011->uartfr &= ~TXFE; VPL011_UNLOCK(d, flags); @@ -462,13 +494,30 @@ int domain_vpl011_init(struct domain *d, struct vpl011_init_info *info) if ( vpl011->ring_buf ) return -EINVAL; - /* Map the guest PFN to Xen address space. */ - rc = prepare_ring_for_helper(d, - gfn_x(info->gfn), - &vpl011->ring_page, - &vpl011->ring_buf); - if ( rc < 0 ) - goto out; + if ( info != NULL ) + { + /* Map the guest PFN to Xen address space. */ + rc = prepare_ring_for_helper(d, + gfn_x(info->gfn), + &vpl011->ring_page, + &vpl011->ring_buf); + if ( rc < 0 ) + goto out; + + rc = alloc_unbound_xen_event_channel(d, 0, info->console_domid, + vpl011_notification); + if ( rc < 0 ) + goto out2; + + vpl011->evtchn = info->evtchn = rc; + } else { + vpl011->ring_buf = xzalloc(struct xencons_interface); + if ( vpl011->ring_buf == NULL ) + { + rc = -EINVAL; + goto out; + } + } rc = vgic_reserve_virq(d, GUEST_VPL011_SPI); if ( !rc ) @@ -477,13 +526,6 @@ int domain_vpl011_init(struct domain *d, struct vpl011_init_info *info) goto out1; } - rc = alloc_unbound_xen_event_channel(d, 0, info->console_domid, - vpl011_notification); - if ( rc < 0 ) - goto out2; - - vpl011->evtchn = info->evtchn = rc; - spin_lock_init(&vpl011->lock); register_mmio_handler(d, &vpl011_mmio_handler, @@ -495,7 +537,10 @@ out2: vgic_free_virq(d, GUEST_VPL011_SPI); out1: - destroy_ring_for_helper(&vpl011->ring_buf, vpl011->ring_page); + if ( vpl011->ring_page == NULL && vpl011->ring_buf != NULL ) + xfree(vpl011->ring_buf); + else + destroy_ring_for_helper(&vpl011->ring_buf, vpl011->ring_page); out: return rc; @@ -508,8 +553,13 @@ void domain_vpl011_deinit(struct domain *d) if ( !vpl011->ring_buf ) return; - free_xen_event_channel(d, vpl011->evtchn); - destroy_ring_for_helper(&vpl011->ring_buf, vpl011->ring_page); + if ( vpl011->ring_page == NULL && vpl011->ring_buf != NULL ) + { + xfree(vpl011->ring_buf); + } else { + free_xen_event_channel(d, vpl011->evtchn); + destroy_ring_for_helper(&vpl011->ring_buf, vpl011->ring_page); + } } /* diff --git a/xen/include/asm-arm/vpl011.h b/xen/include/asm-arm/vpl011.h index db95ff8..8d9b0da 100644 --- a/xen/include/asm-arm/vpl011.h +++ b/xen/include/asm-arm/vpl011.h @@ -53,6 +53,7 @@ struct vpl011_init_info { int domain_vpl011_init(struct domain *d, struct vpl011_init_info *info); void domain_vpl011_deinit(struct domain *d); +void vpl011_read_char(struct domain *d, char c); #else static inline int domain_vpl011_init(struct domain *d, struct vpl011_init_info *info) @@ -61,6 +62,7 @@ static inline int domain_vpl011_init(struct domain *d, } static inline void domain_vpl011_deinit(struct domain *d) { } +static inline void vpl011_read_char(struct domain *d, char c) { } #endif #endif /* _VPL011_H_ */ -- 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |