Currently, many common functions perform the same operations to calculate
GIC register addresses. This patch consolidates the similar code into
a separate helper function to improve maintainability and reduce duplication.
This refactoring also simplifies the implementation of eSPI support in future
changes.
Signed-off-by: Leonid Komarianskyi <leonid_komarianskyi@epam.com>
Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
Acked-by: Julien Grall <jgrall@amazon.com>
---
Changes in V5:
- fixed a minor nit: changed %d to %u in the warning message because the
IRQ number cannot be less than zero
- added acked-by from Julien Grall
Changes in V4:
- no changes
Changes in V3:
- changed panic() in get_addr_by_offset() to printing warning and
ASSERT_UNREACHABLE()
- added verification of return pointer from get_addr_by_offset() in the
callers
- moved invocation of get_addr_by_offset() from spinlock guards, since
it is not necessarry
- added RB from Volodymyr Babchuk
Changes in V2:
- no changes
---
xen/arch/arm/gic-v3.c | 114 +++++++++++++++++++++++----------
xen/arch/arm/include/asm/irq.h | 1 +
2 files changed, 81 insertions(+), 34 deletions(-)
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index cd3e1acf79..29b7f68cba 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -445,17 +445,67 @@ static void gicv3_dump_state(const struct vcpu *v)
}
}
+static void __iomem *get_addr_by_offset(struct irq_desc *irqd, u32 offset)
+{
+ switch ( irqd->irq )
+ {
+ case 0 ... (NR_GIC_LOCAL_IRQS - 1):
+ switch ( offset )
+ {
+ case GICD_ISENABLER:
+ case GICD_ICENABLER:
+ case GICD_ISPENDR:
+ case GICD_ICPENDR:
+ case GICD_ISACTIVER:
+ case GICD_ICACTIVER:
+ return (GICD_RDIST_SGI_BASE + offset);
+ case GICD_ICFGR:
+ return (GICD_RDIST_SGI_BASE + GICR_ICFGR1);
+ case GICD_IPRIORITYR:
+ return (GICD_RDIST_SGI_BASE + GICR_IPRIORITYR0 + irqd->irq);
+ default:
+ break;
+ }
+ case NR_GIC_LOCAL_IRQS ... SPI_MAX_INTID:
+ switch ( offset )
+ {
+ case GICD_ISENABLER:
+ case GICD_ICENABLER:
+ case GICD_ISPENDR:
+ case GICD_ICPENDR:
+ case GICD_ISACTIVER:
+ case GICD_ICACTIVER:
+ return (GICD + offset + (irqd->irq / 32) * 4);
+ case GICD_ICFGR:
+ return (GICD + GICD_ICFGR + (irqd->irq / 16) * 4);
+ case GICD_IROUTER:
+ return (GICD + GICD_IROUTER + irqd->irq * 8);
+ case GICD_IPRIORITYR:
+ return (GICD + GICD_IPRIORITYR + irqd->irq);
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+
+ /* Something went wrong, we shouldn't be able to reach here */
+ printk(XENLOG_WARNING "GICv3: WARNING: Invalid offset 0x%x for IRQ#%u",
+ offset, irqd->irq);
+ ASSERT_UNREACHABLE();
+
+ return NULL;
+}
+
static void gicv3_poke_irq(struct irq_desc *irqd, u32 offset, bool wait_for_rwp)
{
u32 mask = 1U << (irqd->irq % 32);
- void __iomem *base;
+ void __iomem *addr = get_addr_by_offset(irqd, offset);
- if ( irqd->irq < NR_GIC_LOCAL_IRQS )
- base = GICD_RDIST_SGI_BASE;
- else
- base = GICD;
+ if ( addr == NULL )
+ return;
- writel_relaxed(mask, base + offset + (irqd->irq / 32) * 4);
+ writel_relaxed(mask, addr);
if ( wait_for_rwp )
gicv3_wait_for_rwp(irqd->irq);
@@ -463,15 +513,12 @@ static void gicv3_poke_irq(struct irq_desc *irqd, u32 offset, bool wait_for_rwp)
static bool gicv3_peek_irq(struct irq_desc *irqd, u32 offset)
{
- void __iomem *base;
- unsigned int irq = irqd->irq;
+ void __iomem *addr = get_addr_by_offset(irqd, offset);
- if ( irq >= NR_GIC_LOCAL_IRQS)
- base = GICD + (irq / 32) * 4;
- else
- base = GICD_RDIST_SGI_BASE;
+ if ( addr == NULL )
+ return false;
- return !!(readl(base + offset) & (1U << (irq % 32)));
+ return !!(readl(addr) & (1U << (irqd->irq % 32)));
}
static void gicv3_unmask_irq(struct irq_desc *irqd)
@@ -558,30 +605,28 @@ static inline uint64_t gicv3_mpidr_to_affinity(int cpu)
static void gicv3_set_irq_type(struct irq_desc *desc, unsigned int type)
{
uint32_t cfg, actual, edgebit;
- void __iomem *base;
- unsigned int irq = desc->irq;
+ void __iomem *addr;
/* SGI's are always edge-triggered not need to call GICD_ICFGR0 */
- ASSERT(irq >= NR_GIC_SGI);
+ ASSERT(desc->irq >= NR_GIC_SGI);
- spin_lock(&gicv3.lock);
+ addr = get_addr_by_offset(desc, GICD_ICFGR);
+ if ( addr == NULL )
+ return;
- if ( irq >= NR_GIC_LOCAL_IRQS)
- base = GICD + GICD_ICFGR + (irq / 16) * 4;
- else
- base = GICD_RDIST_SGI_BASE + GICR_ICFGR1;
+ spin_lock(&gicv3.lock);
- cfg = readl_relaxed(base);
+ cfg = readl_relaxed(addr);
- edgebit = 2u << (2 * (irq % 16));
+ edgebit = 2u << (2 * (desc->irq % 16));
if ( type & IRQ_TYPE_LEVEL_MASK )
cfg &= ~edgebit;
else if ( type & IRQ_TYPE_EDGE_BOTH )
cfg |= edgebit;
- writel_relaxed(cfg, base);
+ writel_relaxed(cfg, addr);
- actual = readl_relaxed(base);
+ actual = readl_relaxed(addr);
if ( ( cfg & edgebit ) ^ ( actual & edgebit ) )
{
printk(XENLOG_WARNING "GICv3: WARNING: "
@@ -600,16 +645,13 @@ static void gicv3_set_irq_type(struct irq_desc *desc, unsigned int type)
static void gicv3_set_irq_priority(struct irq_desc *desc,
unsigned int priority)
{
- unsigned int irq = desc->irq;
+ void __iomem *addr = get_addr_by_offset(desc, GICD_IPRIORITYR);
- spin_lock(&gicv3.lock);
-
- /* Set priority */
- if ( irq < NR_GIC_LOCAL_IRQS )
- writeb_relaxed(priority, GICD_RDIST_SGI_BASE + GICR_IPRIORITYR0 + irq);
- else
- writeb_relaxed(priority, GICD + GICD_IPRIORITYR + irq);
+ if ( addr == NULL )
+ return;
+ spin_lock(&gicv3.lock);
+ writeb_relaxed(priority, addr);
spin_unlock(&gicv3.lock);
}
@@ -1273,6 +1315,10 @@ static void gicv3_irq_set_affinity(struct irq_desc *desc, const cpumask_t *mask)
{
unsigned int cpu;
uint64_t affinity;
+ void __iomem *addr = get_addr_by_offset(desc, GICD_IROUTER);
+
+ if ( addr == NULL )
+ return;
ASSERT(!cpumask_empty(mask));
@@ -1284,7 +1330,7 @@ static void gicv3_irq_set_affinity(struct irq_desc *desc, const cpumask_t *mask)
affinity &= ~GICD_IROUTER_SPI_MODE_ANY;
if ( desc->irq >= NR_GIC_LOCAL_IRQS )
- writeq_relaxed_non_atomic(affinity, (GICD + GICD_IROUTER + desc->irq * 8));
+ writeq_relaxed_non_atomic(affinity, addr);
spin_unlock(&gicv3.lock);
}
diff --git a/xen/arch/arm/include/asm/irq.h b/xen/arch/arm/include/asm/irq.h
index fce7e42a33..5bc6475eb4 100644
--- a/xen/arch/arm/include/asm/irq.h
+++ b/xen/arch/arm/include/asm/irq.h
@@ -29,6 +29,7 @@ struct arch_irq_desc {
*/
#define NR_IRQS 1024
+#define SPI_MAX_INTID 1019
#define LPI_OFFSET 8192
/* LPIs are always numbered starting at 8192, so 0 is a good invalid case. */
--
2.34.1
On 29.08.25 19:06, Leonid Komarianskyi wrote:
Hello Leonid
> Currently, many common functions perform the same operations to calculate
> GIC register addresses. This patch consolidates the similar code into
> a separate helper function to improve maintainability and reduce duplication.
> This refactoring also simplifies the implementation of eSPI support in future
> changes.
>
> Signed-off-by: Leonid Komarianskyi <leonid_komarianskyi@epam.com>
> Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
> Acked-by: Julien Grall <jgrall@amazon.com>
Reviewed-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
with one NIT ...
>
> ---
> Changes in V5:
> - fixed a minor nit: changed %d to %u in the warning message because the
> IRQ number cannot be less than zero
> - added acked-by from Julien Grall
>
> Changes in V4:
> - no changes
>
> Changes in V3:
> - changed panic() in get_addr_by_offset() to printing warning and
> ASSERT_UNREACHABLE()
> - added verification of return pointer from get_addr_by_offset() in the
> callers
> - moved invocation of get_addr_by_offset() from spinlock guards, since
> it is not necessarry
> - added RB from Volodymyr Babchuk
>
> Changes in V2:
> - no changes
> ---
> xen/arch/arm/gic-v3.c | 114 +++++++++++++++++++++++----------
> xen/arch/arm/include/asm/irq.h | 1 +
> 2 files changed, 81 insertions(+), 34 deletions(-)
>
> diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
> index cd3e1acf79..29b7f68cba 100644
> --- a/xen/arch/arm/gic-v3.c
> +++ b/xen/arch/arm/gic-v3.c
> @@ -445,17 +445,67 @@ static void gicv3_dump_state(const struct vcpu *v)
> }
> }
>
> +static void __iomem *get_addr_by_offset(struct irq_desc *irqd, u32 offset)
... please use uint32_t for new code
(could probably updated on commit)
> +{
> + switch ( irqd->irq )
> + {
> + case 0 ... (NR_GIC_LOCAL_IRQS - 1):
> + switch ( offset )
> + {
> + case GICD_ISENABLER:
> + case GICD_ICENABLER:
> + case GICD_ISPENDR:
> + case GICD_ICPENDR:
> + case GICD_ISACTIVER:
> + case GICD_ICACTIVER:
> + return (GICD_RDIST_SGI_BASE + offset);
> + case GICD_ICFGR:
> + return (GICD_RDIST_SGI_BASE + GICR_ICFGR1);
> + case GICD_IPRIORITYR:
> + return (GICD_RDIST_SGI_BASE + GICR_IPRIORITYR0 + irqd->irq);
> + default:
> + break;
> + }
> + case NR_GIC_LOCAL_IRQS ... SPI_MAX_INTID:
> + switch ( offset )
> + {
> + case GICD_ISENABLER:
> + case GICD_ICENABLER:
> + case GICD_ISPENDR:
> + case GICD_ICPENDR:
> + case GICD_ISACTIVER:
> + case GICD_ICACTIVER:
> + return (GICD + offset + (irqd->irq / 32) * 4);
> + case GICD_ICFGR:
> + return (GICD + GICD_ICFGR + (irqd->irq / 16) * 4);
> + case GICD_IROUTER:
> + return (GICD + GICD_IROUTER + irqd->irq * 8);
> + case GICD_IPRIORITYR:
> + return (GICD + GICD_IPRIORITYR + irqd->irq);
> + default:
> + break;
> + }
> + default:
> + break;
> + }
> +
> + /* Something went wrong, we shouldn't be able to reach here */
> + printk(XENLOG_WARNING "GICv3: WARNING: Invalid offset 0x%x for IRQ#%u",
> + offset, irqd->irq);
> + ASSERT_UNREACHABLE();
> +
> + return NULL;
> +}
> +
> static void gicv3_poke_irq(struct irq_desc *irqd, u32 offset, bool wait_for_rwp)
> {
> u32 mask = 1U << (irqd->irq % 32);
> - void __iomem *base;
> + void __iomem *addr = get_addr_by_offset(irqd, offset);
>
> - if ( irqd->irq < NR_GIC_LOCAL_IRQS )
> - base = GICD_RDIST_SGI_BASE;
> - else
> - base = GICD;
> + if ( addr == NULL )
> + return;
>
> - writel_relaxed(mask, base + offset + (irqd->irq / 32) * 4);
> + writel_relaxed(mask, addr);
>
> if ( wait_for_rwp )
> gicv3_wait_for_rwp(irqd->irq);
> @@ -463,15 +513,12 @@ static void gicv3_poke_irq(struct irq_desc *irqd, u32 offset, bool wait_for_rwp)
>
> static bool gicv3_peek_irq(struct irq_desc *irqd, u32 offset)
> {
> - void __iomem *base;
> - unsigned int irq = irqd->irq;
> + void __iomem *addr = get_addr_by_offset(irqd, offset);
>
> - if ( irq >= NR_GIC_LOCAL_IRQS)
> - base = GICD + (irq / 32) * 4;
> - else
> - base = GICD_RDIST_SGI_BASE;
> + if ( addr == NULL )
> + return false;
>
> - return !!(readl(base + offset) & (1U << (irq % 32)));
> + return !!(readl(addr) & (1U << (irqd->irq % 32)));
> }
>
> static void gicv3_unmask_irq(struct irq_desc *irqd)
> @@ -558,30 +605,28 @@ static inline uint64_t gicv3_mpidr_to_affinity(int cpu)
> static void gicv3_set_irq_type(struct irq_desc *desc, unsigned int type)
> {
> uint32_t cfg, actual, edgebit;
> - void __iomem *base;
> - unsigned int irq = desc->irq;
> + void __iomem *addr;
>
> /* SGI's are always edge-triggered not need to call GICD_ICFGR0 */
> - ASSERT(irq >= NR_GIC_SGI);
> + ASSERT(desc->irq >= NR_GIC_SGI);
>
> - spin_lock(&gicv3.lock);
> + addr = get_addr_by_offset(desc, GICD_ICFGR);
> + if ( addr == NULL )
> + return;
>
> - if ( irq >= NR_GIC_LOCAL_IRQS)
> - base = GICD + GICD_ICFGR + (irq / 16) * 4;
> - else
> - base = GICD_RDIST_SGI_BASE + GICR_ICFGR1;
> + spin_lock(&gicv3.lock);
>
> - cfg = readl_relaxed(base);
> + cfg = readl_relaxed(addr);
>
> - edgebit = 2u << (2 * (irq % 16));
> + edgebit = 2u << (2 * (desc->irq % 16));
> if ( type & IRQ_TYPE_LEVEL_MASK )
> cfg &= ~edgebit;
> else if ( type & IRQ_TYPE_EDGE_BOTH )
> cfg |= edgebit;
>
> - writel_relaxed(cfg, base);
> + writel_relaxed(cfg, addr);
>
> - actual = readl_relaxed(base);
> + actual = readl_relaxed(addr);
> if ( ( cfg & edgebit ) ^ ( actual & edgebit ) )
> {
> printk(XENLOG_WARNING "GICv3: WARNING: "
> @@ -600,16 +645,13 @@ static void gicv3_set_irq_type(struct irq_desc *desc, unsigned int type)
> static void gicv3_set_irq_priority(struct irq_desc *desc,
> unsigned int priority)
> {
> - unsigned int irq = desc->irq;
> + void __iomem *addr = get_addr_by_offset(desc, GICD_IPRIORITYR);
>
> - spin_lock(&gicv3.lock);
> -
> - /* Set priority */
> - if ( irq < NR_GIC_LOCAL_IRQS )
> - writeb_relaxed(priority, GICD_RDIST_SGI_BASE + GICR_IPRIORITYR0 + irq);
> - else
> - writeb_relaxed(priority, GICD + GICD_IPRIORITYR + irq);
> + if ( addr == NULL )
> + return;
>
> + spin_lock(&gicv3.lock);
> + writeb_relaxed(priority, addr);
> spin_unlock(&gicv3.lock);
> }
>
> @@ -1273,6 +1315,10 @@ static void gicv3_irq_set_affinity(struct irq_desc *desc, const cpumask_t *mask)
> {
> unsigned int cpu;
> uint64_t affinity;
> + void __iomem *addr = get_addr_by_offset(desc, GICD_IROUTER);
> +
> + if ( addr == NULL )
> + return;
>
> ASSERT(!cpumask_empty(mask));
>
> @@ -1284,7 +1330,7 @@ static void gicv3_irq_set_affinity(struct irq_desc *desc, const cpumask_t *mask)
> affinity &= ~GICD_IROUTER_SPI_MODE_ANY;
>
> if ( desc->irq >= NR_GIC_LOCAL_IRQS )
> - writeq_relaxed_non_atomic(affinity, (GICD + GICD_IROUTER + desc->irq * 8));
> + writeq_relaxed_non_atomic(affinity, addr);
>
> spin_unlock(&gicv3.lock);
> }
> diff --git a/xen/arch/arm/include/asm/irq.h b/xen/arch/arm/include/asm/irq.h
> index fce7e42a33..5bc6475eb4 100644
> --- a/xen/arch/arm/include/asm/irq.h
> +++ b/xen/arch/arm/include/asm/irq.h
> @@ -29,6 +29,7 @@ struct arch_irq_desc {
> */
> #define NR_IRQS 1024
>
> +#define SPI_MAX_INTID 1019
> #define LPI_OFFSET 8192
>
> /* LPIs are always numbered starting at 8192, so 0 is a good invalid case. */
Hello Oleksandr,
Thank you for your comment and RB.
On 31.08.25 15:42, Oleksandr Tyshchenko wrote:
>
>
> On 29.08.25 19:06, Leonid Komarianskyi wrote:
>
> Hello Leonid
>
>
>> Currently, many common functions perform the same operations to calculate
>> GIC register addresses. This patch consolidates the similar code into
>> a separate helper function to improve maintainability and reduce
>> duplication.
>> This refactoring also simplifies the implementation of eSPI support in
>> future
>> changes.
>>
>> Signed-off-by: Leonid Komarianskyi <leonid_komarianskyi@epam.com>
>> Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
>> Acked-by: Julien Grall <jgrall@amazon.com>
>
> Reviewed-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
>
> with one NIT ...
>
>>
>> ---
>> Changes in V5:
>> - fixed a minor nit: changed %d to %u in the warning message because the
>> IRQ number cannot be less than zero
>> - added acked-by from Julien Grall
>>
>> Changes in V4:
>> - no changes
>>
>> Changes in V3:
>> - changed panic() in get_addr_by_offset() to printing warning and
>> ASSERT_UNREACHABLE()
>> - added verification of return pointer from get_addr_by_offset() in the
>> callers
>> - moved invocation of get_addr_by_offset() from spinlock guards, since
>> it is not necessarry
>> - added RB from Volodymyr Babchuk
>>
>> Changes in V2:
>> - no changes
>> ---
>> xen/arch/arm/gic-v3.c | 114 +++++++++++++++++++++++----------
>> xen/arch/arm/include/asm/irq.h | 1 +
>> 2 files changed, 81 insertions(+), 34 deletions(-)
>>
>> diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
>> index cd3e1acf79..29b7f68cba 100644
>> --- a/xen/arch/arm/gic-v3.c
>> +++ b/xen/arch/arm/gic-v3.c
>> @@ -445,17 +445,67 @@ static void gicv3_dump_state(const struct vcpu *v)
>> }
>> }
>> +static void __iomem *get_addr_by_offset(struct irq_desc *irqd, u32
>> offset)
>
> ... please use uint32_t for new code
>
> (could probably updated on commit)
>
>
I will fix that in V6 and review the other patches to avoid the use of
u32/u64.
>> +{
>> + switch ( irqd->irq )
>> + {
>> + case 0 ... (NR_GIC_LOCAL_IRQS - 1):
>> + switch ( offset )
>> + {
>> + case GICD_ISENABLER:
>> + case GICD_ICENABLER:
>> + case GICD_ISPENDR:
>> + case GICD_ICPENDR:
>> + case GICD_ISACTIVER:
>> + case GICD_ICACTIVER:
>> + return (GICD_RDIST_SGI_BASE + offset);
>> + case GICD_ICFGR:
>> + return (GICD_RDIST_SGI_BASE + GICR_ICFGR1);
>> + case GICD_IPRIORITYR:
>> + return (GICD_RDIST_SGI_BASE + GICR_IPRIORITYR0 + irqd->irq);
>> + default:
>> + break;
>> + }
>> + case NR_GIC_LOCAL_IRQS ... SPI_MAX_INTID:
>> + switch ( offset )
>> + {
>> + case GICD_ISENABLER:
>> + case GICD_ICENABLER:
>> + case GICD_ISPENDR:
>> + case GICD_ICPENDR:
>> + case GICD_ISACTIVER:
>> + case GICD_ICACTIVER:
>> + return (GICD + offset + (irqd->irq / 32) * 4);
>> + case GICD_ICFGR:
>> + return (GICD + GICD_ICFGR + (irqd->irq / 16) * 4);
>> + case GICD_IROUTER:
>> + return (GICD + GICD_IROUTER + irqd->irq * 8);
>> + case GICD_IPRIORITYR:
>> + return (GICD + GICD_IPRIORITYR + irqd->irq);
>> + default:
>> + break;
>> + }
>> + default:
>> + break;
>> + }
>> +
>> + /* Something went wrong, we shouldn't be able to reach here */
>> + printk(XENLOG_WARNING "GICv3: WARNING: Invalid offset 0x%x for
>> IRQ#%u",
>> + offset, irqd->irq);
>> + ASSERT_UNREACHABLE();
>> +
>> + return NULL;
>> +}
>> +
>> static void gicv3_poke_irq(struct irq_desc *irqd, u32 offset, bool
>> wait_for_rwp)
>> {
>> u32 mask = 1U << (irqd->irq % 32);
>> - void __iomem *base;
>> + void __iomem *addr = get_addr_by_offset(irqd, offset);
>> - if ( irqd->irq < NR_GIC_LOCAL_IRQS )
>> - base = GICD_RDIST_SGI_BASE;
>> - else
>> - base = GICD;
>> + if ( addr == NULL )
>> + return;
>> - writel_relaxed(mask, base + offset + (irqd->irq / 32) * 4);
>> + writel_relaxed(mask, addr);
>> if ( wait_for_rwp )
>> gicv3_wait_for_rwp(irqd->irq);
>> @@ -463,15 +513,12 @@ static void gicv3_poke_irq(struct irq_desc
>> *irqd, u32 offset, bool wait_for_rwp)
>> static bool gicv3_peek_irq(struct irq_desc *irqd, u32 offset)
>> {
>> - void __iomem *base;
>> - unsigned int irq = irqd->irq;
>> + void __iomem *addr = get_addr_by_offset(irqd, offset);
>> - if ( irq >= NR_GIC_LOCAL_IRQS)
>> - base = GICD + (irq / 32) * 4;
>> - else
>> - base = GICD_RDIST_SGI_BASE;
>> + if ( addr == NULL )
>> + return false;
>> - return !!(readl(base + offset) & (1U << (irq % 32)));
>> + return !!(readl(addr) & (1U << (irqd->irq % 32)));
>> }
>> static void gicv3_unmask_irq(struct irq_desc *irqd)
>> @@ -558,30 +605,28 @@ static inline uint64_t
>> gicv3_mpidr_to_affinity(int cpu)
>> static void gicv3_set_irq_type(struct irq_desc *desc, unsigned int
>> type)
>> {
>> uint32_t cfg, actual, edgebit;
>> - void __iomem *base;
>> - unsigned int irq = desc->irq;
>> + void __iomem *addr;
>> /* SGI's are always edge-triggered not need to call GICD_ICFGR0 */
>> - ASSERT(irq >= NR_GIC_SGI);
>> + ASSERT(desc->irq >= NR_GIC_SGI);
>> - spin_lock(&gicv3.lock);
>> + addr = get_addr_by_offset(desc, GICD_ICFGR);
>> + if ( addr == NULL )
>> + return;
>> - if ( irq >= NR_GIC_LOCAL_IRQS)
>> - base = GICD + GICD_ICFGR + (irq / 16) * 4;
>> - else
>> - base = GICD_RDIST_SGI_BASE + GICR_ICFGR1;
>> + spin_lock(&gicv3.lock);
>> - cfg = readl_relaxed(base);
>> + cfg = readl_relaxed(addr);
>> - edgebit = 2u << (2 * (irq % 16));
>> + edgebit = 2u << (2 * (desc->irq % 16));
>> if ( type & IRQ_TYPE_LEVEL_MASK )
>> cfg &= ~edgebit;
>> else if ( type & IRQ_TYPE_EDGE_BOTH )
>> cfg |= edgebit;
>> - writel_relaxed(cfg, base);
>> + writel_relaxed(cfg, addr);
>> - actual = readl_relaxed(base);
>> + actual = readl_relaxed(addr);
>> if ( ( cfg & edgebit ) ^ ( actual & edgebit ) )
>> {
>> printk(XENLOG_WARNING "GICv3: WARNING: "
>> @@ -600,16 +645,13 @@ static void gicv3_set_irq_type(struct irq_desc
>> *desc, unsigned int type)
>> static void gicv3_set_irq_priority(struct irq_desc *desc,
>> unsigned int priority)
>> {
>> - unsigned int irq = desc->irq;
>> + void __iomem *addr = get_addr_by_offset(desc, GICD_IPRIORITYR);
>> - spin_lock(&gicv3.lock);
>> -
>> - /* Set priority */
>> - if ( irq < NR_GIC_LOCAL_IRQS )
>> - writeb_relaxed(priority, GICD_RDIST_SGI_BASE +
>> GICR_IPRIORITYR0 + irq);
>> - else
>> - writeb_relaxed(priority, GICD + GICD_IPRIORITYR + irq);
>> + if ( addr == NULL )
>> + return;
>> + spin_lock(&gicv3.lock);
>> + writeb_relaxed(priority, addr);
>> spin_unlock(&gicv3.lock);
>> }
>> @@ -1273,6 +1315,10 @@ static void gicv3_irq_set_affinity(struct
>> irq_desc *desc, const cpumask_t *mask)
>> {
>> unsigned int cpu;
>> uint64_t affinity;
>> + void __iomem *addr = get_addr_by_offset(desc, GICD_IROUTER);
>> +
>> + if ( addr == NULL )
>> + return;
>> ASSERT(!cpumask_empty(mask));
>> @@ -1284,7 +1330,7 @@ static void gicv3_irq_set_affinity(struct
>> irq_desc *desc, const cpumask_t *mask)
>> affinity &= ~GICD_IROUTER_SPI_MODE_ANY;
>> if ( desc->irq >= NR_GIC_LOCAL_IRQS )
>> - writeq_relaxed_non_atomic(affinity, (GICD + GICD_IROUTER +
>> desc->irq * 8));
>> + writeq_relaxed_non_atomic(affinity, addr);
>> spin_unlock(&gicv3.lock);
>> }
>> diff --git a/xen/arch/arm/include/asm/irq.h b/xen/arch/arm/include/
>> asm/irq.h
>> index fce7e42a33..5bc6475eb4 100644
>> --- a/xen/arch/arm/include/asm/irq.h
>> +++ b/xen/arch/arm/include/asm/irq.h
>> @@ -29,6 +29,7 @@ struct arch_irq_desc {
>> */
>> #define NR_IRQS 1024
>> +#define SPI_MAX_INTID 1019
>> #define LPI_OFFSET 8192
>> /* LPIs are always numbered starting at 8192, so 0 is a good invalid
>> case. */
>
Best regards,
Leonid
© 2016 - 2025 Red Hat, Inc.