[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.