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

[Xen-devel] [RFC PATCH v2 16/22] xen/arm: its: implement hw_irq_controller for LPIs



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

This patch implements hw_irq_controller api's required
to handle LPI's.

Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>
---
v2: - Reused hw_irq_controller ops of gicv3 for LPIs
---
 xen/arch/arm/gic-v3-its.c     |  103 ++++++-----------------------------------
 xen/arch/arm/gic-v3.c         |   26 ++++++++---
 xen/include/asm-arm/gic-its.h |    2 +
 xen/include/asm-arm/gic.h     |    1 +
 4 files changed, 37 insertions(+), 95 deletions(-)

diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c
index e382f8d..eacd244 100644
--- a/xen/arch/arm/gic-v3-its.c
+++ b/xen/arch/arm/gic-v3-its.c
@@ -440,7 +440,7 @@ post:
        its_wait_for_range_completion(its, cmd, next_cmd);
 }
 
-void its_send_inv(struct its_device *dev, u32 event_id)
+static void its_send_inv(struct its_device *dev, u32 event_id)
 {
        struct its_cmd_desc desc;
 
@@ -461,8 +461,7 @@ static void its_send_mapc(struct its_node *its, struct 
its_collection *col,
        its_send_single_command(its, its_build_mapc_cmd, &desc);
 }
 
-/* TODO: Remove static for the sake of compilation */
-void its_send_movi(struct its_node *its, struct its_collection *col,
+static void its_send_movi(struct its_node *its, struct its_collection *col,
                   u32 dev_id, u32 id)
 {
        struct its_cmd_desc desc;
@@ -483,28 +482,19 @@ static void its_send_invall(struct its_node *its, struct 
its_collection *col)
        its_send_single_command(its, its_build_invall_cmd, &desc);
 }
 
-/*
- * The below irqchip functions are no more required.
- * TODO: Will be implemented as separate patch
- */
-#if 0
-/*
- * irqchip functions - assumes MSI, mostly.
- */
-
-static inline u32 its_get_event_id(struct irq_data *d)
+static inline u32 its_get_event_id(struct irq_desc *d)
 {
-       struct its_device *its_dev = irq_data_get_irq_chip_data(d);
-       return d->hwirq - its_dev->lpi_base;
+       struct its_device *its_dev = irq_get_desc_data(d);
+       return d->irq - its_dev->lpi_base;
 }
 
-static void lpi_set_config(struct irq_data *d, bool enable)
+void lpi_set_config(struct irq_desc *d, int enable)
 {
-       struct its_device *its_dev = irq_data_get_irq_chip_data(d);
-       irq_hw_number_t hwirq = d->hwirq;
+       u8 *cfg;
        u32 id = its_get_event_id(d);
-       u8 *cfg = page_address(gic_rdists->prop_page) + hwirq - 8192;
+       struct its_device *its_dev = irq_get_desc_data(d);
 
+       cfg = gic_rdists->prop_page + d->irq - NR_GIC_LPI;
        if (enable)
                *cfg |= LPI_PROP_ENABLED;
        else
@@ -516,89 +506,26 @@ static void lpi_set_config(struct irq_data *d, bool 
enable)
         * Humpf...
         */
        if (gic_rdists->flags & RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING)
-               __flush_dcache_area(cfg, sizeof(*cfg));
+               clean_and_invalidate_dcache_va_range(cfg, sizeof(*cfg));
        else
                dsb(ishst);
-       its_send_inv(its_dev, id);
-}
 
-static void its_mask_irq(struct irq_data *d)
-{
-       lpi_set_config(d, false);
-}
-
-static void its_unmask_irq(struct irq_data *d)
-{
-       lpi_set_config(d, true);
-}
-
-static void its_eoi_irq(struct irq_data *d)
-{
-       gic_write_eoir(d->hwirq);
+       its_send_inv(its_dev, id);
 }
 
-static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
-                           bool force)
+void its_set_affinity(struct irq_desc *d, int cpu)
 {
-       unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
-       struct its_device *its_dev = irq_data_get_irq_chip_data(d);
+       struct its_device *its_dev = irq_get_desc_data(d);
        struct its_collection *target_col;
        u32 id = its_get_event_id(d);
 
-       if (cpu >= nr_cpu_ids)
-               return -EINVAL;
-
+       /* Physical collection id */
        target_col = &its_dev->its->collections[cpu];
-       its_send_movi(its_dev, target_col, id);
        its_dev->collection = target_col;
 
-       return IRQ_SET_MASK_OK_DONE;
+       its_send_movi(its_dev->its, target_col, its_dev->device_id, id);
 }
 
-static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
-{
-       struct its_device *its_dev = irq_data_get_irq_chip_data(d);
-       struct its_node *its;
-       u64 addr;
-
-       its = its_dev->its;
-       addr = its->phys_base + GITS_TRANSLATER;
-
-       msg->address_lo         = addr & ((1UL << 32) - 1);
-       msg->address_hi         = addr >> 32;
-       msg->data               = its_get_event_id(d);
-}
-
-static struct irq_chip its_irq_chip = {
-       .name                   = "ITS",
-       .irq_mask               = its_mask_irq,
-       .irq_unmask             = its_unmask_irq,
-       .irq_eoi                = its_eoi_irq,
-       .irq_set_affinity       = its_set_affinity,
-       .irq_compose_msi_msg    = its_irq_compose_msi_msg,
-};
-
-static void its_mask_msi_irq(struct irq_data *d)
-{
-       pci_msi_mask_irq(d);
-       irq_chip_mask_parent(d);
-}
-
-static void its_unmask_msi_irq(struct irq_data *d)
-{
-       pci_msi_unmask_irq(d);
-       irq_chip_unmask_parent(d);
-}
-
-static struct irq_chip its_msi_irq_chip = {
-       .name                   = "ITS-MSI",
-       .irq_unmask             = its_unmask_msi_irq,
-       .irq_mask               = its_mask_msi_irq,
-       .irq_eoi                = irq_chip_eoi_parent,
-       .irq_write_msi_msg      = pci_msi_domain_write_msg,
-};
-#endif
-
 /*
  * How we allocate LPIs:
  *
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index 2b406e6..1b3ecd7 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -40,6 +40,7 @@
 #include <asm/device.h>
 #include <asm/gic.h>
 #include <asm/gic_v3_defs.h>
+#include <asm/gic-its.h>
 #include <asm/cpufeature.h>
 
 struct rdist_region {
@@ -427,12 +428,18 @@ static void gicv3_poke_irq(struct irq_desc *irqd, u32 
offset)
 
 static void gicv3_unmask_irq(struct irq_desc *irqd)
 {
-    gicv3_poke_irq(irqd, GICD_ISENABLER);
+    if ( is_lpi(irqd->irq) )
+        lpi_set_config(irqd, 1);
+    else
+        gicv3_poke_irq(irqd, GICD_ISENABLER);
 }
 
 static void gicv3_mask_irq(struct irq_desc *irqd)
 {
-    gicv3_poke_irq(irqd, GICD_ICENABLER);
+    if ( is_lpi(irqd->irq) )
+        lpi_set_config(irqd, 0);
+    else
+        gicv3_poke_irq(irqd, GICD_ICENABLER);
 }
 
 static void gicv3_eoi_irq(struct irq_desc *irqd)
@@ -1070,13 +1077,18 @@ static void gicv3_irq_set_affinity(struct irq_desc 
*desc, const cpumask_t *mask)
     spin_lock(&gicv3.lock);
 
     cpu = gicv3_get_cpu_from_mask(mask);
-    affinity = gicv3_mpidr_to_affinity(cpu);
-    /* Make sure we don't broadcast the interrupt */
-    affinity &= ~GICD_IROUTER_SPI_MODE_ANY;
 
-    if ( desc->irq >= NR_GIC_LOCAL_IRQS )
-        writeq_relaxed(affinity, (GICD + GICD_IROUTER + desc->irq * 8));
+    if ( is_lpi(desc->irq) )
+        its_set_affinity(desc, cpu);
+    else
+    {
+        affinity = gicv3_mpidr_to_affinity(cpu);
+        /* Make sure we don't broadcast the interrupt */
+        affinity &= ~GICD_IROUTER_SPI_MODE_ANY;
 
+        if ( desc->irq >= NR_GIC_LOCAL_IRQS )
+            writeq_relaxed(affinity, (GICD + GICD_IROUTER + desc->irq * 8));
+    }
     spin_unlock(&gicv3.lock);
 }
 
diff --git a/xen/include/asm-arm/gic-its.h b/xen/include/asm-arm/gic-its.h
index e1a5fa0..af28d66 100644
--- a/xen/include/asm-arm/gic-its.h
+++ b/xen/include/asm-arm/gic-its.h
@@ -225,6 +225,8 @@ int its_alloc_device_irq(struct its_device *dev, uint32_t 
*plpi);
 int gic_its_send_cmd(struct vcpu *v, struct its_node *its,
                      struct its_cmd_block *phys_cmd, int send_all);
 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);
 unsigned long *its_lpi_alloc_chunks(int nirqs, int *base, int *nr_ids);
 uint32_t its_get_pta_type(void);
 uint32_t its_get_nr_its(void);
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index f15174b..e4555e8 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -162,6 +162,7 @@
 
 #define DT_MATCH_GIC_V3 DT_MATCH_COMPATIBLE("arm,gic-v3")
 
+#define is_lpi(lpi) (lpi >= NR_GIC_LPI)
 /*
  * GICv3 registers that needs to be saved/restored
  */
-- 
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®.