[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC 18/22] xen/arm: gic-v3: Move Distributor and Re-Distributors info in gic_info ...
... in order to decouple the vGIC driver to the GIC driver. Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx> --- xen/arch/arm/gic-v3.c | 86 +++++++++++++++++++++++------------------------ xen/include/asm-arm/gic.h | 9 +++++ 2 files changed, 51 insertions(+), 44 deletions(-) diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c index c109433..13250c5 100644 --- a/xen/arch/arm/gic-v3.c +++ b/xen/arch/arm/gic-v3.c @@ -42,19 +42,10 @@ #include <asm/gic_v3_defs.h> #include <asm/cpufeature.h> -struct rdist_region { - paddr_t base; - paddr_t size; - void __iomem *map_base; -}; - /* Global state */ static struct { - paddr_t dbase; /* Address of distributor registers */ void __iomem *map_dbase; /* Mapped address of distributor registers */ - struct rdist_region *rdist_regions; - uint32_t rdist_stride; - unsigned int rdist_count; /* Number of rdist regions count */ + void __iomem **rdist_regions; unsigned int nr_priorities; spinlock_t lock; } gicv3; @@ -629,16 +620,16 @@ static int __init gicv3_populate_rdist(void) MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 | MPIDR_AFFINITY_LEVEL(mpidr, 0)); - for ( i = 0; i < gicv3.rdist_count; i++ ) + for ( i = 0; i < gicv3_info.nr_rdist_regions; i++ ) { - void __iomem *ptr = gicv3.rdist_regions[i].map_base; + void __iomem *ptr = gicv3.rdist_regions[i]; reg = readl_relaxed(ptr + GICR_PIDR2) & GICR_PIDR2_ARCH_REV_MASK; if ( (reg >> GICR_PIDR2_ARCH_REV_SHIFT) != GICR_PIDR2_ARCH_GICV3 ) { dprintk(XENLOG_ERR, "GICv3: No redistributor present @%"PRIpaddr"\n", - gicv3.rdist_regions[i].base); + gicv3_info.rdist_regions[i].base); break; } @@ -652,8 +643,8 @@ static int __init gicv3_populate_rdist(void) smp_processor_id(), i, ptr); return 0; } - if ( gicv3.rdist_stride ) - ptr += gicv3.rdist_stride; + if ( gicv3_info.rdist_stride ) + ptr += gicv3_info.rdist_stride; else { ptr += SZ_64K * 2; /* Skip RD_base + SGI_base */ @@ -915,9 +906,9 @@ static int gicv_v3_init(struct domain *d) { unsigned int first_cpu = 0; - d->arch.vgic.dbase = gicv3.dbase; + d->arch.vgic.dbase = gicv3_info.dbase; - d->arch.vgic.rdist_stride = gicv3.rdist_stride; + d->arch.vgic.rdist_stride = gicv3_info.rdist_stride; /* * If the stride is not set, the default stride for GICv3 is 2 * 64K: * - first 64k page for Control and Physical LPIs @@ -926,11 +917,11 @@ static int gicv_v3_init(struct domain *d) if ( !d->arch.vgic.rdist_stride ) d->arch.vgic.rdist_stride = 2 * SZ_64K; - for ( i = 0; i < gicv3.rdist_count; i++ ) + for ( i = 0; i < gicv3_info.nr_rdist_regions; i++ ) { - paddr_t size = gicv3.rdist_regions[i].size; + paddr_t size = gicv3_info.rdist_regions[i].size; - d->arch.vgic.rdist_regions[i].base = gicv3.rdist_regions[i].base; + d->arch.vgic.rdist_regions[i].base = gicv3_info.rdist_regions[i].base; d->arch.vgic.rdist_regions[i].size = size; /* Set the first CPU handled by this region */ @@ -938,7 +929,7 @@ static int gicv_v3_init(struct domain *d) first_cpu += size / d->arch.vgic.rdist_stride; } - d->arch.vgic.nr_regions = gicv3.rdist_count; + d->arch.vgic.nr_regions = gicv3_info.nr_rdist_regions; } else { @@ -1187,15 +1178,15 @@ static int __init gicv3_init(void) return -ENODEV; } - res = dt_device_get_address(node, 0, &gicv3.dbase, NULL); - if ( res || !gicv3.dbase ) + res = dt_device_get_address(node, 0, &gicv3_info.dbase, NULL); + if ( res || !gicv3_info.dbase ) panic("GICv3: Cannot find a valid distributor address"); - if ( (gicv3.dbase & ~PAGE_MASK) ) + if ( (gicv3_info.dbase & ~PAGE_MASK) ) panic("GICv3: Found unaligned distributor address %"PRIpaddr"", - gicv3.dbase); + gicv3_info.dbase); - gicv3.map_dbase = ioremap_nocache(gicv3.dbase, SZ_64K); + gicv3.map_dbase = ioremap_nocache(gicv3_info.dbase, SZ_64K); if ( !gicv3.map_dbase ) panic("GICv3: Failed to ioremap for GIC distributor\n"); @@ -1204,18 +1195,19 @@ static int __init gicv3_init(void) panic("GICv3: no distributor detected\n"); if ( !dt_property_read_u32(node, "#redistributor-regions", - &gicv3.rdist_count) ) - gicv3.rdist_count = 1; + &gicv3_info.nr_rdist_regions) ) + gicv3_info.nr_rdist_regions = 1; - if ( gicv3.rdist_count > MAX_RDIST_COUNT ) + if ( gicv3_info.nr_rdist_regions > MAX_RDIST_COUNT ) panic("GICv3: Number of redistributor regions is more than" "%d (Increase MAX_RDIST_COUNT!!)\n", MAX_RDIST_COUNT); - rdist_regs = xzalloc_array(struct rdist_region, gicv3.rdist_count); + rdist_regs = xzalloc_array(struct rdist_region, + gicv3_info.nr_rdist_regions); if ( !rdist_regs ) panic("GICv3: Failed to allocate memory for rdist regions\n"); - for ( i = 0; i < gicv3.rdist_count; i++ ) + for ( i = 0; i < gicv3_info.nr_rdist_regions; i++ ) { uint64_t rdist_base, rdist_size; @@ -1228,26 +1220,32 @@ static int __init gicv3_init(void) } /* The vGIC code requires the region to be sorted */ - sort(rdist_regs, gicv3.rdist_count, sizeof(*rdist_regs), cmp_rdist, NULL); + sort(rdist_regs, gicv3_info.nr_rdist_regions, + sizeof(*rdist_regs), cmp_rdist, NULL); - if ( !dt_property_read_u32(node, "redistributor-stride", &gicv3.rdist_stride) ) - gicv3.rdist_stride = 0; + if ( !dt_property_read_u32(node, "redistributor-stride", + &gicv3_info.rdist_stride) ) + gicv3_info.rdist_stride = 0; - gicv3.rdist_regions= rdist_regs; + gicv3_info.rdist_regions = rdist_regs; res = platform_get_irq(node, 0); if ( res < 0 ) panic("GICv3: Cannot find the maintenance IRQ"); gicv3_info.maintenance_irq = res; - for ( i = 0; i < gicv3.rdist_count; i++ ) + gicv3.rdist_regions = xmalloc_array(void *, gicv3_info.nr_rdist_regions); + if ( !gicv3.rdist_regions ) + panic("GICv3: Fail to allocate the array for rdist regions pointer\n"); + + for ( i = 0; i < gicv3_info.nr_rdist_regions; i++ ) { /* map dbase & rdist regions */ - gicv3.rdist_regions[i].map_base = - ioremap_nocache(gicv3.rdist_regions[i].base, - gicv3.rdist_regions[i].size); + gicv3.rdist_regions[i] = + ioremap_nocache(gicv3_info.rdist_regions[i].base, + gicv3_info.rdist_regions[i].size); - if ( !gicv3.rdist_regions[i].map_base ) + if ( !gicv3.rdist_regions[i] ) panic("GICv3: Failed to ioremap rdist region for region %d\n", i); } @@ -1256,12 +1254,12 @@ static int __init gicv3_init(void) " gic_maintenance_irq=%u\n" " gic_rdist_stride=%#x\n" " gic_rdist_regions=%d\n", - gicv3.dbase, gicv3_info.maintenance_irq, - gicv3.rdist_stride, gicv3.rdist_count); + gicv3_info.dbase, gicv3_info.maintenance_irq, + gicv3_info.rdist_stride, gicv3_info.nr_rdist_regions); printk(" redistributor regions:\n"); - for ( i = 0; i < gicv3.rdist_count; i++ ) + for ( i = 0; i < gicv3_info.nr_rdist_regions; i++ ) { - const struct rdist_region *r = &gicv3.rdist_regions[i]; + const struct rdist_region *r = &gicv3_info.rdist_regions[i]; printk(" - region %u: %#"PRIpaddr" - %#"PRIpaddr"\n", i, r->base, r->base + r->size); diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index 1e569a0..be0f610 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -296,6 +296,15 @@ struct gic_info { paddr_t cbase; /* Virtual CPU interface address (GICv2 compatible only) */ paddr_t vbase; +#ifdef CONFIG_ARM_64 + /* Re-Distributor regions (GICv3 compatible only) */ + unsigned int nr_rdist_regions; + const struct rdist_region { + paddr_t base; + paddr_t size; + } *rdist_regions; + uint32_t rdist_stride; /* Re-Distributor stride */ +#endif }; struct gic_hw_operations { -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |