|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 13/15] xen/arm: Merge gicv_setup with vgic_domain_init
Currently, it's hard to decide whether a part of the domain
initialization should live in gicv_setup (part of the GIC
driver) and domain_init (part of the vGIC driver).
The code to initialize the domain for a specific vGIC version is always
the same no matter the version of the GIC.
Move all the domain initialization code for the vGIC in the respective
domain_init callback of each vGIC drivers.
Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx>
Cc: Zoltan Kiss <zoltan.kiss@xxxxxxxxxx>
---
Changes in v2:
- The code merged is slightly different. Although I haven't keep
Ian's ack
---
xen/arch/arm/domain.c | 3 ---
xen/arch/arm/gic-hip04.c | 42 ----------------------------------
xen/arch/arm/gic-v2.c | 42 ----------------------------------
xen/arch/arm/gic-v3.c | 58 -----------------------------------------------
xen/arch/arm/gic.c | 10 ++++----
xen/arch/arm/vgic-v2.c | 43 ++++++++++++++++++++++++++++++++---
xen/arch/arm/vgic-v3.c | 54 +++++++++++++++++++++++++++++++++++++++++--
xen/include/asm-arm/gic.h | 4 ++--
8 files changed, 99 insertions(+), 157 deletions(-)
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 8b1bf5a..21a03df 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -587,9 +587,6 @@ int arch_domain_create(struct domain *d, unsigned int
domcr_flags,
}
config->gic_version = gic_version;
- if ( (rc = gicv_setup(d)) != 0 )
- goto fail;
-
if ( (rc = domain_vgic_init(d, config->nr_spis)) != 0 )
goto fail;
diff --git a/xen/arch/arm/gic-hip04.c b/xen/arch/arm/gic-hip04.c
index 259c6d6..c5ed545 100644
--- a/xen/arch/arm/gic-hip04.c
+++ b/xen/arch/arm/gic-hip04.c
@@ -431,47 +431,6 @@ static void hip04gic_clear_lr(int lr)
writel_gich(0, HIP04_GICH_LR + lr * 4);
}
-static int hip04gicv_setup(struct domain *d)
-{
- int ret;
-
- /*
- * The hardware domain gets the hardware address.
- * Guests get the virtual platform layout.
- */
- if ( is_hardware_domain(d) )
- {
- d->arch.vgic.dbase = vgic_v2_hw.dbase;
- d->arch.vgic.cbase = vgic_v2_hw.cbase;
- }
- else
- {
- d->arch.vgic.dbase = GUEST_GICD_BASE;
- d->arch.vgic.cbase = GUEST_GICC_BASE;
- }
-
- /*
- * Map the gic virtual cpu interface in the gic cpu interface
- * region of the guest.
- *
- * The second page is always mapped at +4K irrespective of the
- * GIC_64K_STRIDE quirk. The DTB passed to the guest reflects this.
- */
- ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase), 1,
- paddr_to_pfn(vgic_v2_hw.vbase));
- if ( ret )
- return ret;
-
- if ( !platform_has_quirk(PLATFORM_QUIRK_GIC_64K_STRIDE) )
- ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
- 2, paddr_to_pfn(vgic_v2_hw.vbase + PAGE_SIZE));
- else
- ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
- 2, paddr_to_pfn(vgic_v2_hw.vbase + SZ_64K));
-
- return ret;
-}
-
static void hip04gic_read_lr(int lr, struct gic_lr *lr_reg)
{
uint32_t lrv;
@@ -752,7 +711,6 @@ const static struct gic_hw_operations hip04gic_ops = {
.save_state = hip04gic_save_state,
.restore_state = hip04gic_restore_state,
.dump_state = hip04gic_dump_state,
- .gicv_setup = hip04gicv_setup,
.gic_host_irq_type = &hip04gic_host_irq_type,
.gic_guest_irq_type = &hip04gic_guest_irq_type,
.eoi_irq = hip04gic_eoi_irq,
diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 4d94335..596126d 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -421,47 +421,6 @@ static void gicv2_clear_lr(int lr)
writel_gich(0, GICH_LR + lr * 4);
}
-static int gicv2v_setup(struct domain *d)
-{
- int ret;
-
- /*
- * The hardware domain gets the hardware address.
- * Guests get the virtual platform layout.
- */
- if ( is_hardware_domain(d) )
- {
- d->arch.vgic.dbase = vgic_v2_hw.dbase;
- d->arch.vgic.cbase = vgic_v2_hw.cbase;
- }
- else
- {
- d->arch.vgic.dbase = GUEST_GICD_BASE;
- d->arch.vgic.cbase = GUEST_GICC_BASE;
- }
-
- /*
- * Map the gic virtual cpu interface in the gic cpu interface
- * region of the guest.
- *
- * The second page is always mapped at +4K irrespective of the
- * GIC_64K_STRIDE quirk. The DTB passed to the guest reflects this.
- */
- ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase), 1,
- paddr_to_pfn(vgic_v2_hw.vbase));
- if ( ret )
- return ret;
-
- if ( !platform_has_quirk(PLATFORM_QUIRK_GIC_64K_STRIDE) )
- ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
- 2, paddr_to_pfn(vgic_v2_hw.vbase + PAGE_SIZE));
- else
- ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
- 2, paddr_to_pfn(vgic_v2_hw.vbase + SZ_64K));
-
- return ret;
-}
-
static void gicv2_read_lr(int lr, struct gic_lr *lr_reg)
{
uint32_t lrv;
@@ -738,7 +697,6 @@ const static struct gic_hw_operations gicv2_ops = {
.save_state = gicv2_save_state,
.restore_state = gicv2_restore_state,
.dump_state = gicv2_dump_state,
- .gicv_setup = gicv2v_setup,
.gic_host_irq_type = &gicv2_host_irq_type,
.gic_guest_irq_type = &gicv2_guest_irq_type,
.eoi_irq = gicv2_eoi_irq,
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index 73ea700..337fbb9 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -917,63 +917,6 @@ static void gicv3_write_lr(int lr_reg, const struct gic_lr
*lr)
gicv3_ich_write_lr(lr_reg, lrv);
}
-static int gicv_v3_init(struct domain *d)
-{
- int i;
-
- /*
- * Domain 0 gets the hardware address.
- * Guests get the virtual platform layout.
- */
- if ( is_hardware_domain(d) )
- {
- unsigned int first_cpu = 0;
-
- d->arch.vgic.dbase = vgic_v3_hw.dbase;
-
- d->arch.vgic.rdist_stride = vgic_v3_hw.rdist_stride;
- /*
- * If the stride is not set, the default stride for GICv3 is 2 * 64K:
- * - first 64k page for Control and Physical LPIs
- * - second 64k page for Control and Generation of SGIs
- */
- if ( !d->arch.vgic.rdist_stride )
- d->arch.vgic.rdist_stride = 2 * SZ_64K;
-
- for ( i = 0; i < gicv3.rdist_count; i++ )
- {
- paddr_t size = vgic_v3_hw.regions[i].size;
-
- d->arch.vgic.rdist_regions[i].base = vgic_v3_hw.regions[i].base;
- d->arch.vgic.rdist_regions[i].size = size;
-
- /* Set the first CPU handled by this region */
- d->arch.vgic.rdist_regions[i].first_cpu = first_cpu;
-
- first_cpu += size / d->arch.vgic.rdist_stride;
- }
- d->arch.vgic.nr_regions = vgic_v3_hw.nr_rdist_regions;
- }
- else
- {
- d->arch.vgic.dbase = GUEST_GICV3_GICD_BASE;
-
- /* XXX: Only one Re-distributor region mapped for the guest */
- BUILD_BUG_ON(GUEST_GICV3_RDIST_REGIONS != 1);
-
- d->arch.vgic.nr_regions = GUEST_GICV3_RDIST_REGIONS;
- d->arch.vgic.rdist_stride = GUEST_GICV3_RDIST_STRIDE;
-
- /* The first redistributor should contain enough space for all CPUs */
- BUILD_BUG_ON((GUEST_GICV3_GICR0_SIZE / GUEST_GICV3_RDIST_STRIDE) <
MAX_VIRT_CPUS);
- d->arch.vgic.rdist_regions[0].base = GUEST_GICV3_GICR0_BASE;
- d->arch.vgic.rdist_regions[0].size = GUEST_GICV3_GICR0_SIZE;
- d->arch.vgic.rdist_regions[0].first_cpu = 0;
- }
-
- return 0;
-}
-
static void gicv3_hcr_status(uint32_t flag, bool_t status)
{
uint32_t hcr;
@@ -1293,7 +1236,6 @@ static const struct gic_hw_operations gicv3_ops = {
.save_state = gicv3_save_state,
.restore_state = gicv3_restore_state,
.dump_state = gicv3_dump_state,
- .gicv_setup = gicv_v3_init,
.gic_host_irq_type = &gicv3_host_irq_type,
.gic_guest_irq_type = &gicv3_guest_irq_type,
.eoi_irq = gicv3_eoi_irq,
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 341b6df..3c09c3e 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -67,6 +67,11 @@ unsigned int gic_number_lines(void)
return gic_hw_ops->info->nr_lines;
}
+const struct gic_info *gic_info(void)
+{
+ return gic_hw_ops->info;
+}
+
void gic_save_state(struct vcpu *v)
{
ASSERT(!local_irq_is_enabled());
@@ -661,11 +666,6 @@ void gic_interrupt(struct cpu_user_regs *regs, int is_fiq)
} while (1);
}
-int gicv_setup(struct domain *d)
-{
- return gic_hw_ops->gicv_setup(d);
-}
-
static void maintenance_interrupt(int irq, void *dev_id, struct cpu_user_regs
*regs)
{
/*
diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
index 029305a..0cae6f4 100644
--- a/xen/arch/arm/vgic-v2.c
+++ b/xen/arch/arm/vgic-v2.c
@@ -24,11 +24,12 @@
#include <xen/softirq.h>
#include <xen/irq.h>
#include <xen/sched.h>
+#include <xen/sizes.h>
#include <asm/current.h>
#include <asm/mmio.h>
-#include <asm/gic.h>
+#include <asm/platform.h>
#include <asm/vgic.h>
struct vgic_v2_hw_config vgic_v2_hw;
@@ -527,14 +528,50 @@ static int vgic_v2_vcpu_init(struct vcpu *v)
static int vgic_v2_domain_init(struct domain *d)
{
- int i;
+ int i, ret;
+
+ /*
+ * The hardware domain gets the hardware address.
+ * Guests get the virtual platform layout.
+ */
+ if ( is_hardware_domain(d) )
+ {
+ d->arch.vgic.dbase = vgic_v2_hw.dbase;
+ d->arch.vgic.cbase = vgic_v2_hw.cbase;
+ }
+ else
+ {
+ d->arch.vgic.dbase = GUEST_GICD_BASE;
+ d->arch.vgic.cbase = GUEST_GICC_BASE;
+ }
+
+ /*
+ * Map the gic virtual cpu interface in the gic cpu interface
+ * region of the guest.
+ *
+ * The second page is always mapped at +4K irrespective of the
+ * GIC_64K_STRIDE quirk. The DTB passed to the guest reflects this.
+ */
+ ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase), 1,
+ paddr_to_pfn(vgic_v2_hw.vbase));
+ if ( ret )
+ return ret;
+
+ if ( !platform_has_quirk(PLATFORM_QUIRK_GIC_64K_STRIDE) )
+ ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
+ 2, paddr_to_pfn(vgic_v2_hw.vbase + PAGE_SIZE));
+ else
+ ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
+ 2, paddr_to_pfn(vgic_v2_hw.vbase + SZ_64K));
+
+ if ( ret )
+ return ret;
/* By default deliver to CPU0 */
for ( i = 0; i < DOMAIN_NR_RANKS(d); i++ )
memset(d->arch.vgic.shared_irqs[i].v2.itargets, 0x1,
sizeof(d->arch.vgic.shared_irqs[i].v2.itargets));
- /* We rely on gicv_setup() to initialize dbase(vGIC distributor base) */
register_mmio_handler(d, &vgic_v2_distr_mmio_handler, d->arch.vgic.dbase,
PAGE_SIZE);
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 5d295e4..ab6a9ac 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -29,7 +29,6 @@
#include <asm/current.h>
#include <asm/mmio.h>
#include <asm/gic_v3_defs.h>
-#include <asm/gic.h>
#include <asm/vgic.h>
/* GICD_PIDRn register values for ARM implementations */
@@ -1121,13 +1120,64 @@ static int vgic_v3_domain_init(struct domain *d)
{
int i, idx;
+ /*
+ * Domain 0 gets the hardware address.
+ * Guests get the virtual platform layout.
+ */
+ if ( is_hardware_domain(d) )
+ {
+ unsigned int first_cpu = 0;
+
+ d->arch.vgic.dbase = vgic_v3_hw.dbase;
+
+ d->arch.vgic.rdist_stride = vgic_v3_hw.rdist_stride;
+ /*
+ * If the stride is not set, the default stride for GICv3 is 2 * 64K:
+ * - first 64k page for Control and Physical LPIs
+ * - second 64k page for Control and Generation of SGIs
+ */
+ if ( !d->arch.vgic.rdist_stride )
+ d->arch.vgic.rdist_stride = 2 * SZ_64K;
+
+ for ( i = 0; i < vgic_v3_hw.nr_rdist_regions; i++ )
+ {
+ paddr_t size = vgic_v3_hw.regions[i].size;
+
+ d->arch.vgic.rdist_regions[i].base = vgic_v3_hw.regions[i].base;
+ d->arch.vgic.rdist_regions[i].size = size;
+
+ /* Set the first CPU handled by this region */
+ d->arch.vgic.rdist_regions[i].first_cpu = first_cpu;
+
+ first_cpu += size / d->arch.vgic.rdist_stride;
+ }
+ d->arch.vgic.nr_regions = vgic_v3_hw.nr_rdist_regions;
+ }
+ else
+ {
+ d->arch.vgic.dbase = GUEST_GICV3_GICD_BASE;
+
+ /* XXX: Only one Re-distributor region mapped for the guest */
+ BUILD_BUG_ON(GUEST_GICV3_RDIST_REGIONS != 1);
+
+ d->arch.vgic.nr_regions = GUEST_GICV3_RDIST_REGIONS;
+ d->arch.vgic.rdist_stride = GUEST_GICV3_RDIST_STRIDE;
+
+ /* The first redistributor should contain enough space for all CPUs */
+ BUILD_BUG_ON((GUEST_GICV3_GICR0_SIZE / GUEST_GICV3_RDIST_STRIDE) <
MAX_VIRT_CPUS);
+ d->arch.vgic.rdist_regions[0].base = GUEST_GICV3_GICR0_BASE;
+ d->arch.vgic.rdist_regions[0].size = GUEST_GICV3_GICR0_SIZE;
+ d->arch.vgic.rdist_regions[0].first_cpu = 0;
+ }
+
/* By default deliver to CPU0 */
for ( i = 0; i < DOMAIN_NR_RANKS(d); i++ )
{
for ( idx = 0; idx < 32; idx++ )
d->arch.vgic.shared_irqs[i].v3.irouter[idx] = 0;
}
- /* We rely on gicv init to get dbase and size */
+
+ /* Register mmio handle for the Distributor */
register_mmio_handler(d, &vgic_distr_mmio_handler, d->arch.vgic.dbase,
SZ_64K);
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index 71f4813..49d2b52 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -300,6 +300,8 @@ struct gic_info {
const struct dt_device_node *node;
};
+const struct gic_info *gic_info(void);
+
struct gic_hw_operations {
/* Hold GIC HW information */
const struct gic_info *info;
@@ -311,8 +313,6 @@ struct gic_hw_operations {
void (*restore_state)(const struct vcpu *);
/* Dump GIC LR register information */
void (*dump_state)(const struct vcpu *);
- /* Map MMIO region of GIC */
- int (*gicv_setup)(struct domain *);
/* hw_irq_controller to enable/disable/eoi host irq */
hw_irq_controller *gic_host_irq_type;
--
2.4.3
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |