|
[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 |