[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 |