[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen master] xen/arm: Update Dom0 GIC dt node with GICv3 information



commit 5dd422c656c6781a4703bb5b681d558d7c199996
Author:     Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>
AuthorDate: Fri Sep 12 16:39:47 2014 +0530
Commit:     Ian Campbell <ian.campbell@xxxxxxxxxx>
CommitDate: Mon Sep 15 22:56:42 2014 +0100

    xen/arm: Update Dom0 GIC dt node with GICv3 information
    
    Update GIC device tree node for DOM0 with GICv3
    information. GIC hw specfic device tree information
    is moved to respective GIC driver.
    
    Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>
    Acked-by: Julien Grall <julien.grall@xxxxxxxxxx>
    Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
 xen/arch/arm/domain_build.c |   47 +-------------------------
 xen/arch/arm/gic-v2.c       |   51 ++++++++++++++++++++++++++++
 xen/arch/arm/gic-v3.c       |   78 +++++++++++++++++++++++++++++++++++++++++++
 xen/arch/arm/gic.c          |    6 +++
 xen/include/asm-arm/gic.h   |    4 ++
 5 files changed, 141 insertions(+), 45 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 2d316dd..90abc3a 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -777,9 +777,6 @@ static int make_gic_node(const struct domain *d, void *fdt,
                          const struct dt_device_node *node)
 {
     const struct dt_device_node *gic = dt_interrupt_controller;
-    const void *compatible = NULL;
-    u32 len;
-    __be32 *new_cells, *tmp;
     int res = 0;
 
     /*
@@ -794,48 +791,7 @@ static int make_gic_node(const struct domain *d, void *fdt,
 
     DPRINT("Create gic node\n");
 
-    compatible = dt_get_property(gic, "compatible", &len);
-    if ( !compatible )
-    {
-        dprintk(XENLOG_ERR, "Can't find compatible property for the gic 
node\n");
-        return -FDT_ERR_XEN(ENOENT);
-    }
-
-    res = fdt_begin_node(fdt, "interrupt-controller");
-    if ( res )
-        return res;
-
-    res = fdt_property(fdt, "compatible", compatible, len);
-    if ( res )
-        return res;
-
-    res = fdt_property_cell(fdt, "#interrupt-cells", 3);
-    if ( res )
-        return res;
-
-    res = fdt_property(fdt, "interrupt-controller", NULL, 0);
-
-    if ( res )
-        return res;
-
-    len = dt_cells_to_size(dt_n_addr_cells(node) + dt_n_size_cells(node));
-    len *= 2; /* GIC has two memory regions: Distributor + CPU interface */
-    new_cells = xzalloc_bytes(len);
-    if ( new_cells == NULL )
-        return -FDT_ERR_XEN(ENOMEM);
-
-    tmp = new_cells;
-    DPRINT("  Set Distributor Base 0x%"PRIpaddr"-0x%"PRIpaddr"\n",
-           d->arch.vgic.dbase, d->arch.vgic.dbase + PAGE_SIZE - 1);
-    dt_set_range(&tmp, node, d->arch.vgic.dbase, PAGE_SIZE);
-
-    DPRINT("  Set Cpu Base 0x%"PRIpaddr"-0x%"PRIpaddr"\n",
-           d->arch.vgic.cbase, d->arch.vgic.cbase + (PAGE_SIZE * 2) - 1);
-    dt_set_range(&tmp, node, d->arch.vgic.cbase, PAGE_SIZE * 2);
-
-    res = fdt_property(fdt, "reg", new_cells, len);
-    xfree(new_cells);
-
+    res = gic_make_node(d, node, fdt);
     if ( res )
         return res;
 
@@ -1058,6 +1014,7 @@ static int handle_node(struct domain *d, struct 
kernel_info *kinfo,
     static const struct dt_device_match gic_matches[] __initconst =
     {
         DT_MATCH_GIC_V2,
+        DT_MATCH_GIC_V3,
         { /* sentinel */ },
     };
     static const struct dt_device_match timer_matches[] __initconst =
diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 78ad4de..f053b5d 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -27,6 +27,7 @@
 #include <xen/softirq.h>
 #include <xen/list.h>
 #include <xen/device_tree.h>
+#include <xen/libfdt/libfdt.h>
 #include <asm/p2m.h>
 #include <asm/domain.h>
 #include <asm/platform.h>
@@ -585,6 +586,55 @@ static void gicv2_irq_set_affinity(struct irq_desc *desc, 
const cpumask_t *cpu_m
     spin_unlock(&gicv2.lock);
 }
 
+static int gicv2_make_dt_node(const struct domain *d,
+                              const struct dt_device_node *node, void *fdt)
+{
+    const struct dt_device_node *gic = dt_interrupt_controller;
+    const void *compatible = NULL;
+    u32 len;
+    __be32 *new_cells, *tmp;
+    int res = 0;
+
+    compatible = dt_get_property(gic, "compatible", &len);
+    if ( !compatible )
+    {
+        dprintk(XENLOG_ERR, "Can't find compatible property for the gic 
node\n");
+        return -FDT_ERR_XEN(ENOENT);
+    }
+
+    res = fdt_begin_node(fdt, "interrupt-controller");
+    if ( res )
+        return res;
+
+    res = fdt_property(fdt, "compatible", compatible, len);
+    if ( res )
+        return res;
+
+    res = fdt_property_cell(fdt, "#interrupt-cells", 3);
+    if ( res )
+        return res;
+
+    res = fdt_property(fdt, "interrupt-controller", NULL, 0);
+
+    if ( res )
+        return res;
+
+    len = dt_cells_to_size(dt_n_addr_cells(node) + dt_n_size_cells(node));
+    len *= 2; /* GIC has two memory regions: Distributor + CPU interface */
+    new_cells = xzalloc_bytes(len);
+    if ( new_cells == NULL )
+        return -FDT_ERR_XEN(ENOMEM);
+
+    tmp = new_cells;
+    dt_set_range(&tmp, node, d->arch.vgic.dbase, PAGE_SIZE);
+    dt_set_range(&tmp, node, d->arch.vgic.cbase, PAGE_SIZE * 2);
+
+    res = fdt_property(fdt, "reg", new_cells, len);
+    xfree(new_cells);
+
+    return res;
+}
+
 /* XXX different for level vs edge */
 static hw_irq_controller gicv2_host_irq_type = {
     .typename     = "gic-v2",
@@ -630,6 +680,7 @@ const static struct gic_hw_operations gicv2_ops = {
     .write_lr            = gicv2_write_lr,
     .read_vmcr_priority  = gicv2_read_vmcr_priority,
     .read_apr            = gicv2_read_apr,
+    .make_dt_node        = gicv2_make_dt_node,
 };
 
 /* Set up the GIC */
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index 6ccde02..ca450f9 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -32,6 +32,7 @@
 #include <xen/delay.h>
 #include <xen/device_tree.h>
 #include <xen/sizes.h>
+#include <xen/libfdt/libfdt.h>
 #include <asm/p2m.h>
 #include <asm/domain.h>
 #include <asm/io.h>
@@ -1027,6 +1028,82 @@ static void gicv3_irq_set_affinity(struct irq_desc 
*desc, const cpumask_t *mask)
     spin_unlock(&gicv3.lock);
 }
 
+static int gicv3_make_dt_node(const struct domain *d,
+                              const struct dt_device_node *node, void *fdt)
+{
+    const struct dt_device_node *gic = dt_interrupt_controller;
+    const void *compatible = NULL;
+    uint32_t len;
+    __be32 *new_cells, *tmp;
+    uint32_t rd_stride = 0;
+    uint32_t rd_count = 0;
+
+    int i, res = 0;
+
+    compatible = dt_get_property(gic, "compatible", &len);
+    if ( !compatible )
+    {
+        dprintk(XENLOG_ERR, "Can't find compatible property for the gic 
node\n");
+        return -FDT_ERR_XEN(ENOENT);
+    }
+
+    res = fdt_begin_node(fdt, "interrupt-controller");
+    if ( res )
+        return res;
+
+    res = fdt_property(fdt, "compatible", compatible, len);
+    if ( res )
+        return res;
+
+    res = fdt_property_cell(fdt, "#interrupt-cells", 3);
+    if ( res )
+        return res;
+
+    res = fdt_property(fdt, "interrupt-controller", NULL, 0);
+    if ( res )
+        return res;
+
+    res = dt_property_read_u32(gic, "redistributor-stride", &rd_stride);
+    if ( !res )
+        rd_stride = 0;
+
+    res = dt_property_read_u32(gic, "#redistributor-regions", &rd_count);
+    if ( !res )
+        rd_count = 1;
+
+    res = fdt_property_cell(fdt, "redistributor-stride", rd_stride);
+    if ( res )
+        return res;
+
+    res = fdt_property_cell(fdt, "#redistributor-regions", rd_count);
+    if ( res )
+        return res;
+
+    len = dt_cells_to_size(dt_n_addr_cells(node) + dt_n_size_cells(node));
+    /*
+     * GIC has two memory regions: Distributor + rdist regions
+     * CPU interface and virtual cpu interfaces accessesed as System registers
+     * So cells are created only for Distributor and rdist regions
+     */
+    len = len * (d->arch.vgic.rdist_count + 1);
+    new_cells = xzalloc_bytes(len);
+    if ( new_cells == NULL )
+        return -FDT_ERR_XEN(ENOMEM);
+
+    tmp = new_cells;
+
+    dt_set_range(&tmp, node, d->arch.vgic.dbase, d->arch.vgic.dbase_size);
+
+    for ( i = 0; i < d->arch.vgic.rdist_count; i++ )
+        dt_set_range(&tmp, node, d->arch.vgic.rbase[i],
+                     d->arch.vgic.rbase_size[i]);
+
+    res = fdt_property(fdt, "reg", new_cells, len);
+    xfree(new_cells);
+
+    return res;
+}
+
 static const hw_irq_controller gicv3_host_irq_type = {
     .typename     = "gic-v3",
     .startup      = gicv3_irq_startup,
@@ -1071,6 +1148,7 @@ static const struct gic_hw_operations gicv3_ops = {
     .read_vmcr_priority  = gicv3_read_vmcr_priority,
     .read_apr            = gicv3_read_apr,
     .secondary_init      = gicv3_secondary_cpu_init,
+    .make_dt_node        = gicv3_make_dt_node,
 };
 
 /* Set up the GIC */
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 6611ba0..70d10d6 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -625,6 +625,12 @@ void __cpuinit init_maintenance_interrupt(void)
                 "irq-maintenance", NULL);
 }
 
+int gic_make_node(const struct domain *d,const struct dt_device_node *node,
+                   void *fdt)
+{
+    return gic_hw_ops->make_dt_node(d, node, fdt);
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index c4daf5b..51a0a26 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -336,9 +336,13 @@ struct gic_hw_operations {
     unsigned int (*read_apr)(int apr_reg);
     /* Secondary CPU init */
     int (*secondary_init)(void);
+    int (*make_dt_node)(const struct domain *d,
+                        const struct dt_device_node *node, void *fdt);
 };
 
 void register_gic_ops(const struct gic_hw_operations *ops);
+int gic_make_node(const struct domain *d,const struct dt_device_node *node,
+                  void *fdt);
 
 #endif /* __ASSEMBLY__ */
 #endif
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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