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