|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |