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

[Xen-devel] [RFC PATCH 19/19] 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>
---
 xen/arch/arm/gic-v3-its.c         |   10 ++++++++++
 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        |   28 ++++++++++++++++++++--------
 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, 78 insertions(+), 8 deletions(-)

diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c
index dbfda30..b2116d9 100644
--- a/xen/arch/arm/gic-v3-its.c
+++ b/xen/arch/arm/gic-v3-its.c
@@ -900,6 +900,16 @@ int its_make_dt_node(const struct domain *d,
     return res;
 }
 
+void its_domain_init(struct domain *d)
+{
+    if ( is_hardware_domain(d) )
+    {
+        d->arch.vits->phys_base = its->phys_base;
+        d->arch.vits->phys_size = its->phys_size;
+    }
+    /* TODO: To implement for domU */
+}
+
 static int its_probe(struct dt_device_node *node)
 {
     paddr_t its_addr, its_size;
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index b654535..67d34a6 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -658,6 +658,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;
@@ -670,6 +675,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);
@@ -1269,10 +1283,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 c4d352a..dbd906d 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -74,6 +74,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_eoi_irq(struct irq_desc *d)
 {
     gic_hw_ops->eoi_irq(d);
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 43b626b..8c75e0e 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -762,6 +762,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 51b9614..e12111d 100644
--- a/xen/arch/arm/vgic-v3-its.c
+++ b/xen/arch/arm/vgic-v3-its.c
@@ -1544,19 +1544,31 @@ static int vgic_map_translation_space(struct domain *d)
 
 int vgic_its_domain_init(struct domain *d) 
 {
-    d->arch.vits = xzalloc(struct vgic_its);
-    if ( d->arch.vits == NULL )
-        return -ENOMEM;
+    if ( gic_lpi_supported() )
+    {
+        d->arch.vits = xzalloc(struct vgic_its);
+        if ( d->arch.vits == NULL )
+            return -ENOMEM;
+
+        INIT_LIST_HEAD(&d->arch.vits->vits_dev_list);
+        spin_lock_init(&d->arch.vits->lock);
+
+        its_domain_init(d);
 
-    INIT_LIST_HEAD(&d->arch.vits->vits_dev_list);
-    spin_lock_init(&d->arch.vits->lock);
+        register_mmio_handler(d, &vgic_gits_mmio_handler, 
d->arch.vits->phys_base,
+                              SZ_64K);
 
-    register_mmio_handler(d, &vgic_gits_mmio_handler, d->arch.vits->phys_base,
-                          SZ_64K);
+        return vgic_map_translation_space(d);
+    }
 
-    return vgic_map_translation_space(d);
+    return 0;
 }
 
+void vgic_its_init(void)
+{
+    if ( gic_lpi_supported() )
+        its_lpi_init(gic_nr_id_bits());
+}
 
 /*
  * Local variables:
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 89e6195..fa7b241 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -1124,6 +1124,7 @@ static int vgic_v3_domain_init(struct domain *d)
         register_mmio_handler(d, &vgic_rdistr_mmio_handler,
             d->arch.vgic.rbase[i], d->arch.vgic.rbase_size[i]);
 
+    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 0defe6e..329b8a0 100644
--- a/xen/include/asm-arm/gic-its.h
+++ b/xen/include/asm-arm/gic-its.h
@@ -22,6 +22,8 @@
 #ifndef __ASM_ARM_GIC_ITS_H__
 #define __ASM_ARM_GIC_ITS_H__
 
+#include <asm/gic_v3_defs.h>
+
 #define IRQ_PER_CHUNK 32
 
 /* ITS device structure */
@@ -238,6 +240,9 @@ int its_get_physical_cid(uint32_t *col_id, uint64_t ta);
 int gic_its_send_cmd(struct vcpu *v, struct its_cmd_block *phys_cmd);
 int its_make_dt_node(const struct domain *d,
                      const struct dt_device_node *node, void *fdt);
+void its_domain_init(struct domain *d);
+int its_cpu_init(void);
+int its_init(struct dt_device_node *node, struct rdist_prop *rdist);
 
 #endif /* __ASM_ARM_GIC_ITS_H__ */
 
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index efc9ac3..67a7122 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -279,6 +279,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,
@@ -294,6 +298,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_its_hw_operations {
diff --git a/xen/include/asm-arm/gic_v3_defs.h 
b/xen/include/asm-arm/gic_v3_defs.h
index b81f83f..574a838 100644
--- a/xen/include/asm-arm/gic_v3_defs.h
+++ b/xen/include/asm-arm/gic_v3_defs.h
@@ -133,6 +133,7 @@
 #define GICR_TYPER_LAST              (1U << 4)
 #define GICR_TYPER_DISTRIBUTED_IMP   (1U << 3)
 
+#define GICD_TYPER_LPIS_SUPPORTED    (1U << 17)
 #define DEFAULT_PMR_VALUE            0xff
 
 #define GICH_VMCR_EOI                (1 << 9)
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index 74d5a4e..e0a6166 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®.