[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v1 05/16] arm/vpl011: use void pointer in domain struct
From: Denis Mukhin <dmukhin@xxxxxxxx> Switch to using void pointer in domain struct to reduce compile-time dependencies for PL011 emulator. Signed-off-by: Denis Mukhin <dmukhin@xxxxxxxx> --- xen/arch/arm/include/asm/domain.h | 3 +- xen/arch/arm/vpl011.c | 139 +++++++++++++++++------------- 2 files changed, 79 insertions(+), 63 deletions(-) diff --git a/xen/arch/arm/include/asm/domain.h b/xen/arch/arm/include/asm/domain.h index 746ea687d523..2ee9976b55a8 100644 --- a/xen/arch/arm/include/asm/domain.h +++ b/xen/arch/arm/include/asm/domain.h @@ -9,7 +9,6 @@ #include <asm/mmio.h> #include <asm/gic.h> #include <asm/vgic.h> -#include <asm/vpl011.h> #include <public/hvm/params.h> struct hvm_domain @@ -114,7 +113,7 @@ struct arch_domain } monitor; #ifdef CONFIG_HAS_VUART_PL011 - struct vpl011 vpl011; + void *vpl011; #endif #ifdef CONFIG_TEE diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c index a97c3b74208c..3c027ccf0b4e 100644 --- a/xen/arch/arm/vpl011.c +++ b/xen/arch/arm/vpl011.c @@ -22,6 +22,7 @@ #include <xen/console.h> #include <xen/serial.h> #include <xen/vuart.h> +#include <xen/xvmalloc.h> #include <public/domctl.h> #include <public/io/console.h> #include <asm/domain_build.h> @@ -31,6 +32,43 @@ #include <asm/vpl011.h> #include <asm/vreg.h> +static void __vpl011_exit(struct vpl011 *vpl011, struct domain *d) +{ + if ( vpl011->virq ) + { + vgic_free_virq(d, vpl011->virq); + + /* + * Set to invalid irq (we use SPI) to prevent extra free and to avoid + * freeing irq that could have already been reserved by someone else. + */ + vpl011->virq = 0; + } + + if ( vpl011->backend_in_domain ) + { + if ( vpl011->backend.dom.ring_buf ) + destroy_ring_for_helper(&vpl011->backend.dom.ring_buf, + vpl011->backend.dom.ring_page); + + if ( vpl011->evtchn ) + { + free_xen_event_channel(d, vpl011->evtchn); + + /* + * Set to invalid event channel port to prevent extra free and to + * avoid freeing port that could have already been allocated for + * other purposes. + */ + vpl011->evtchn = 0; + } + } + else + XFREE(vpl011->backend.xen); + + xfree(vpl011); +} + /* * Since pl011 registers are 32-bit registers, all registers * are handled similarly allowing 8-bit, 16-bit and 32-bit @@ -43,7 +81,7 @@ static bool vpl011_reg32_check_access(struct hsr_dabt dabt) static void vpl011_update_interrupt_status(struct domain *d) { - struct vpl011 *vpl011 = &d->arch.vpl011; + struct vpl011 *vpl011 = d->arch.vpl011; uint32_t uartmis = vpl011->uartris & vpl011->uartimsc; /* @@ -81,7 +119,7 @@ static void vpl011_update_interrupt_status(struct domain *d) static void vpl011_write_data_xen(struct domain *d, uint8_t data) { unsigned long flags; - struct vpl011 *vpl011 = &d->arch.vpl011; + struct vpl011 *vpl011 = d->arch.vpl011; struct vpl011_xen_backend *intf = vpl011->backend.xen; struct domain *input = console_get_domain(); @@ -140,7 +178,7 @@ static uint8_t vpl011_read_data_xen(struct domain *d) { unsigned long flags; uint8_t data = 0; - struct vpl011 *vpl011 = &d->arch.vpl011; + struct vpl011 *vpl011 = d->arch.vpl011; struct vpl011_xen_backend *intf = vpl011->backend.xen; XENCONS_RING_IDX in_cons, in_prod; @@ -199,7 +237,7 @@ static uint8_t vpl011_read_data(struct domain *d) { unsigned long flags; uint8_t data = 0; - struct vpl011 *vpl011 = &d->arch.vpl011; + struct vpl011 *vpl011 = d->arch.vpl011; struct xencons_interface *intf = vpl011->backend.dom.ring_buf; XENCONS_RING_IDX in_cons, in_prod; @@ -284,7 +322,7 @@ static void vpl011_update_tx_fifo_status(struct vpl011 *vpl011, static void vpl011_write_data(struct domain *d, uint8_t data) { unsigned long flags; - struct vpl011 *vpl011 = &d->arch.vpl011; + struct vpl011 *vpl011 = d->arch.vpl011; struct xencons_interface *intf = vpl011->backend.dom.ring_buf; XENCONS_RING_IDX out_cons, out_prod; @@ -350,10 +388,9 @@ static int vpl011_mmio_read(struct vcpu *v, register_t *r, void *priv) { + struct vpl011 *vpl011 = v->domain->arch.vpl011; struct hsr_dabt dabt = info->dabt; - uint32_t vpl011_reg = (uint32_t)(info->gpa - - v->domain->arch.vpl011.base_addr); - struct vpl011 *vpl011 = &v->domain->arch.vpl011; + uint32_t vpl011_reg = (uint32_t)(info->gpa - vpl011->base_addr); struct domain *d = v->domain; unsigned long flags; @@ -439,10 +476,9 @@ static int vpl011_mmio_write(struct vcpu *v, register_t r, void *priv) { + struct vpl011 *vpl011 = v->domain->arch.vpl011; struct hsr_dabt dabt = info->dabt; - uint32_t vpl011_reg = (uint32_t)(info->gpa - - v->domain->arch.vpl011.base_addr); - struct vpl011 *vpl011 = &v->domain->arch.vpl011; + uint32_t vpl011_reg = (uint32_t)(info->gpa - vpl011->base_addr); struct domain *d = v->domain; unsigned long flags; @@ -518,7 +554,7 @@ static void vpl011_data_avail(struct domain *d, XENCONS_RING_IDX out_fifo_level, XENCONS_RING_IDX out_size) { - struct vpl011 *vpl011 = &d->arch.vpl011; + struct vpl011 *vpl011 = d->arch.vpl011; /**** Update the UART RX state ****/ @@ -576,7 +612,7 @@ static void vpl011_data_avail(struct domain *d, int vuart_putchar(struct domain *d, char c) { unsigned long flags; - struct vpl011 *vpl011 = &d->arch.vpl011; + struct vpl011 *vpl011 = d->arch.vpl011; struct vpl011_xen_backend *intf = vpl011->backend.xen; XENCONS_RING_IDX in_cons, in_prod, in_fifo_level; @@ -614,7 +650,7 @@ static void vpl011_notification(struct vcpu *v, unsigned int port) { unsigned long flags; struct domain *d = v->domain; - struct vpl011 *vpl011 = &d->arch.vpl011; + struct vpl011 *vpl011 = d->arch.vpl011; struct xencons_interface *intf = vpl011->backend.dom.ring_buf; XENCONS_RING_IDX in_cons, in_prod, out_cons, out_prod; XENCONS_RING_IDX in_fifo_level, out_fifo_level; @@ -644,11 +680,14 @@ static void vpl011_notification(struct vcpu *v, unsigned int port) int vuart_init(struct domain *d, struct vuart_params *params) { + struct vpl011 *vpl011; int rc; - struct vpl011 *vpl011 = &d->arch.vpl011; - if ( vpl011->backend.dom.ring_buf ) - return -EINVAL; + BUG_ON(d->arch.vpl011); + + vpl011 = xvzalloc(typeof(*vpl011)); + if ( !vpl011 ) + return -ENOMEM; /* * The VPL011 virq is GUEST_VPL011_SPI, except for direct-map domains @@ -670,7 +709,8 @@ int vuart_init(struct domain *d, struct vuart_params *params) { printk(XENLOG_ERR "vpl011: Unable to re-use the Xen UART information.\n"); - return -EINVAL; + rc = -EINVAL; + goto err_out; } /* @@ -684,7 +724,8 @@ int vuart_init(struct domain *d, struct vuart_params *params) { printk(XENLOG_ERR "vpl011: Can't re-use the Xen UART MMIO region as it is too small.\n"); - return -EINVAL; + rc = -EINVAL; + goto err_out; } } else @@ -707,12 +748,12 @@ int vuart_init(struct domain *d, struct vuart_params *params) &vpl011->backend.dom.ring_page, &vpl011->backend.dom.ring_buf); if ( rc < 0 ) - goto out; + goto err_out; rc = alloc_unbound_xen_event_channel(d, 0, params->console_domid, vpl011_notification); if ( rc < 0 ) - goto out1; + goto err_out; vpl011->evtchn = params->evtchn = rc; } @@ -725,7 +766,7 @@ int vuart_init(struct domain *d, struct vuart_params *params) if ( vpl011->backend.xen == NULL ) { rc = -ENOMEM; - goto out; + goto err_out; } } @@ -733,7 +774,7 @@ int vuart_init(struct domain *d, struct vuart_params *params) if ( !rc ) { rc = -EINVAL; - goto out1; + goto err_out; } vpl011->uartfr = TXFE | RXFE; @@ -743,50 +784,22 @@ int vuart_init(struct domain *d, struct vuart_params *params) register_mmio_handler(d, &vpl011_mmio_handler, vpl011->base_addr, GUEST_PL011_SIZE, NULL); + d->arch.vpl011 = vpl011; + return 0; -out1: - vuart_exit(d); - -out: +err_out: + __vpl011_exit(vpl011, d); return rc; } void vuart_exit(struct domain *d) { - struct vpl011 *vpl011 = &d->arch.vpl011; - - if ( vpl011->virq ) + if ( d->arch.vpl011 ) { - vgic_free_virq(d, vpl011->virq); - - /* - * Set to invalid irq (we use SPI) to prevent extra free and to avoid - * freeing irq that could have already been reserved by someone else. - */ - vpl011->virq = 0; + __vpl011_exit(d->arch.vpl011, d); + d->arch.vpl011 = NULL; } - - if ( vpl011->backend_in_domain ) - { - if ( vpl011->backend.dom.ring_buf ) - destroy_ring_for_helper(&vpl011->backend.dom.ring_buf, - vpl011->backend.dom.ring_page); - - if ( vpl011->evtchn ) - { - free_xen_event_channel(d, vpl011->evtchn); - - /* - * Set to invalid event channel port to prevent extra free and to - * avoid freeing port that could have already been allocated for - * other purposes. - */ - vpl011->evtchn = 0; - } - } - else - XFREE(vpl011->backend.xen); } int __init vuart_add_fwnode(struct domain *d, void *node) @@ -797,8 +810,12 @@ int __init vuart_add_fwnode(struct domain *d, void *node) gic_interrupt_t intr; __be32 reg[GUEST_ROOT_ADDRESS_CELLS + GUEST_ROOT_SIZE_CELLS]; __be32 *cells; + struct vpl011 *vpl011 = d->arch.vpl011; - res = domain_fdt_begin_node(fdt, "sbsa-uart", d->arch.vpl011.base_addr); + if ( !vpl011 ) + return 0; + + res = domain_fdt_begin_node(fdt, "sbsa-uart", vpl011->base_addr); if ( res ) return res; @@ -808,14 +825,14 @@ int __init vuart_add_fwnode(struct domain *d, void *node) cells = ®[0]; dt_child_set_range(&cells, GUEST_ROOT_ADDRESS_CELLS, - GUEST_ROOT_SIZE_CELLS, d->arch.vpl011.base_addr, + GUEST_ROOT_SIZE_CELLS, vpl011->base_addr, GUEST_PL011_SIZE); res = fdt_property(fdt, "reg", reg, sizeof(reg)); if ( res ) return res; - set_interrupt(intr, d->arch.vpl011.virq, 0xf, DT_IRQ_TYPE_LEVEL_HIGH); + set_interrupt(intr, vpl011->virq, 0xf, DT_IRQ_TYPE_LEVEL_HIGH); res = fdt_property(fdt, "interrupts", intr, sizeof (intr)); if ( res ) -- 2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |