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

[Xen-devel] [RFC PATCH v2 21/22] xen/arm: its: Initialize virtual and physical ITS driver



From: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>

Intialize physical ITS driver and virtual ITS driver
based on HW support information available in GICD_TYPER
register.

Based on outcome of lpi_supported() and gic_nr_id_bits()
functions ITS driver is initialized

Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>
---
v2: Multi-ITS support
---
 xen/arch/arm/gic-v3-its.c         |   25 +++++++++++++++++++++++--
 xen/arch/arm/gic-v3.c             |   21 +++++++++++++++++++++
 xen/arch/arm/gic.c                |   10 ++++++++++
 xen/arch/arm/setup.c              |    1 +
 xen/arch/arm/vgic-v3-its.c        |    8 ++++++++
 xen/arch/arm/vgic-v3.c            |    1 +
 xen/include/asm-arm/gic-its.h     |    5 +++++
 xen/include/asm-arm/gic.h         |    8 ++++++++
 xen/include/asm-arm/gic_v3_defs.h |    1 +
 xen/include/asm-arm/vgic.h        |    1 +
 10 files changed, 79 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c
index a59bbb5..c2c59fa 100644
--- a/xen/arch/arm/gic-v3-its.c
+++ b/xen/arch/arm/gic-v3-its.c
@@ -565,7 +565,7 @@ static int its_chunk_to_lpi(int chunk)
        return (chunk << IRQS_PER_CHUNK_SHIFT) + 8192;
 }
 
-static int its_lpi_init(u32 id_bits)
+int its_lpi_init(u32 id_bits)
 {
        lpi_chunks = its_lpi_to_chunk(1UL << id_bits);
 
@@ -1079,6 +1079,28 @@ static int its_force_quiescent(void __iomem *base)
        }
 }
 
+void its_domain_init(uint32_t its_nr, struct domain *d)
+{
+       struct its_node *its;
+       u32 nr = 0;
+
+       ASSERT(its_nr < its_get_nr_its() );
+
+       if (is_hardware_domain(d)) {
+               list_for_each_entry(its, &its_nodes, entry) {
+                       if ( nr == its_nr)
+                               break;
+                       nr++;
+               }
+
+               ASSERT(its != NULL);
+               d->arch.vits[its_nr].phys_base = its->phys_base;
+               d->arch.vits[its_nr].phys_size = its->phys_size;
+               d->arch.vits[its_nr].its  = its;
+       }
+       /* TODO: Update for DomU */
+}
+
 static int its_probe(struct dt_device_node *node)
 {
        paddr_t its_addr, its_size;
@@ -1231,7 +1253,6 @@ int its_init(struct dt_device_node *node, struct 
rdist_prop *rdists)
        gic_root_node = node;
 
        its_alloc_lpi_tables();
-       its_lpi_init(rdists->id_bits);
 
        return 0;
 }
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index ffdaecf..d3278f3 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -679,6 +679,11 @@ static int __init gicv3_populate_rdist(void)
     return -ENODEV;
 }
 
+static int gicv3_dist_supports_lpis(void)
+{
+    return readl_relaxed(GICD + GICD_TYPER) & GICD_TYPER_LPIS_SUPPORTED;
+}
+
 static int __cpuinit gicv3_cpu_init(void)
 {
     int i;
@@ -691,6 +696,15 @@ static int __cpuinit gicv3_cpu_init(void)
     if ( gicv3_enable_redist() )
         return -ENODEV;
 
+    if ( gicv3_dist_supports_lpis() )
+        gicv3_info.lpi_supported = 1;
+    else
+        gicv3_info.lpi_supported = 0;
+
+        /* Give LPIs a spin */
+    if ( gicv3_info.lpi_supported )
+        its_cpu_init();
+
     /* Set priority on PPI and SGI interrupts */
     priority = (GIC_PRI_IPI << 24 | GIC_PRI_IPI << 16 | GIC_PRI_IPI << 8 |
                 GIC_PRI_IPI);
@@ -1324,10 +1338,17 @@ static int __init gicv3_init(struct dt_device_node 
*node, const void *data)
            gicv3.rdist_regions[0].size, gicv3.rdist_regions[0].map_base,
            gicv3_info.maintenance_irq);
 
+    reg = readl_relaxed(GICD + GICD_TYPER);
+    gicv3.rdist_data.id_bits = ((reg >> 19) & 0x1f) + 1;
+    gicv3_info.nr_id_bits = gicv3.rdist_data.id_bits;
+
     spin_lock_init(&gicv3.lock);
 
     spin_lock(&gicv3.lock);
 
+    if ( gicv3_info.lpi_supported )
+        its_init(node, &gicv3.rdist_data);
+
     gicv3_dist_init();
     res = gicv3_cpu_init();
     gicv3_hyp_init();
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 6ac1f18..7c9b75c 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -68,6 +68,16 @@ unsigned int gic_number_lines(void)
     return gic_hw_ops->info->nr_lines;
 }
 
+unsigned int gic_nr_id_bits(void)
+{
+    return gic_hw_ops->info->nr_id_bits;
+}
+
+bool_t gic_lpi_supported(void)
+{
+    return gic_hw_ops->info->lpi_supported;
+}
+
 void gic_save_state(struct vcpu *v)
 {
     ASSERT(!local_irq_is_enabled());
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 9a1c285..ebd4bb9 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -773,6 +773,7 @@ void __init start_xen(unsigned long boot_phys_offset,
     init_xen_time();
 
     gic_init();
+    vgic_its_init();
 
     p2m_vmid_allocator_init();
 
diff --git a/xen/arch/arm/vgic-v3-its.c b/xen/arch/arm/vgic-v3-its.c
index 360be0d..bd0b8ae 100644
--- a/xen/arch/arm/vgic-v3-its.c
+++ b/xen/arch/arm/vgic-v3-its.c
@@ -1455,6 +1455,8 @@ int vgic_its_domain_init(struct domain *d)
     for ( i = 0; i < num_its; i++)
     {
          spin_lock_init(&d->arch.vits[i].lock);
+
+         its_domain_init(i, d);
          register_mmio_handler(d, &vgic_gits_mmio_handler,
                                d->arch.vits[i].phys_base,
                                SZ_64K);
@@ -1465,6 +1467,12 @@ int vgic_its_domain_init(struct domain *d)
     return 0;
 }
 
+void vgic_its_init(void)
+{
+    if ( gic_lpi_supported() )
+        its_lpi_init(gic_nr_id_bits());
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index e9ec7fa..578537f 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -1204,6 +1204,7 @@ static int vgic_v3_domain_init(struct domain *d)
             d->arch.vgic.rdist_regions[i].size);
 
     d->arch.vgic.ctlr = VGICD_CTLR_DEFAULT;
+    vgic_its_domain_init(d);
 
     return 0;
 }
diff --git a/xen/include/asm-arm/gic-its.h b/xen/include/asm-arm/gic-its.h
index ed9cbc9..519321b 100644
--- a/xen/include/asm-arm/gic-its.h
+++ b/xen/include/asm-arm/gic-its.h
@@ -226,6 +226,10 @@ int gic_its_send_cmd(struct vcpu *v, struct its_node *its,
                      struct its_cmd_block *phys_cmd, int send_all);
 int its_make_dt_node(const struct domain *d,
                      const struct dt_device_node *node, void *fdt);
+int its_cpu_init(void);
+int its_init(struct dt_device_node *node, struct rdist_prop *rdist);
+int its_lpi_init(u32 id_bits);
+void its_domain_init(uint32_t its_nr, struct domain *d);
 void its_lpi_free(unsigned long *bitmap, int base, int nr_ids);
 void its_set_affinity(struct irq_desc *d, int cpu);
 void lpi_set_config(struct irq_desc *d, int enable);
@@ -235,6 +239,7 @@ uint32_t its_get_nr_its(void);
 struct its_node * its_get_phys_node(uint32_t dev_id);
 int vgic_its_unmap_lpi_prop(struct vcpu *v);
 int vgic_its_get_pid(struct vcpu *v, uint32_t vlpi, uint32_t *plpi);
+int vgic_its_domain_init(struct domain *d);
 uint8_t vgic_its_get_priority(struct vcpu *v, uint32_t pid);
 #endif /* __ASM_ARM_GIC_ITS_H__ */
 
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index d927f35..2467212 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -271,6 +271,10 @@ extern void gic_dump_info(struct vcpu *v);
 
 /* Number of interrupt lines */
 extern unsigned int gic_number_lines(void);
+/* Number of interrupt id bits supported */
+extern unsigned int gic_nr_id_bits(void);
+/* LPI support info */
+bool_t gic_lpi_supported(void);
 
 /* IRQ translation function for the device tree */
 int gic_irq_xlate(const u32 *intspec, unsigned int intsize,
@@ -286,6 +290,10 @@ struct gic_info {
     uint8_t nr_lrs;
     /* Maintenance irq number */
     unsigned int maintenance_irq;
+    /* Number of IRQ ID bits supported */
+    uint32_t nr_id_bits;
+    /* LPIs are support information */
+    bool_t lpi_supported; 
 };
 
 struct gic_hw_operations {
diff --git a/xen/include/asm-arm/gic_v3_defs.h 
b/xen/include/asm-arm/gic_v3_defs.h
index 125fc28..214b492 100644
--- a/xen/include/asm-arm/gic_v3_defs.h
+++ b/xen/include/asm-arm/gic_v3_defs.h
@@ -48,6 +48,7 @@
 #define GICR_CTL_ENABLE              (1U << 0)
 /* Additional bits in GICD_TYPER defined by GICv3 */
 #define GICD_TYPE_ID_BITS_SHIFT 19
+#define GICD_TYPER_LPIS_SUPPORTED    (1U << 17)
 
 #define GICD_CTLR_RWP                (1UL << 31)
 #define GICD_CTLR_ARE_NS             (1U << 4)
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index dd93872..f2cb268 100644
--- a/xen/include/asm-arm/vgic.h
+++ b/xen/include/asm-arm/vgic.h
@@ -177,6 +177,7 @@ enum gic_sgi_mode;
 
 #define vgic_num_irqs(d)        ((d)->arch.vgic.nr_spis + 32)
 
+extern void vgic_its_init(void);
 extern int domain_vgic_init(struct domain *d);
 extern void domain_vgic_free(struct domain *d);
 extern int vcpu_vgic_init(struct vcpu *v);
-- 
1.7.9.5


_______________________________________________
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®.