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

[PATCH v2 01/10] xen/arm: gicv3: refactor obtaining GIC addresses for common operations


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Leonid Komarianskyi <Leonid_Komarianskyi@xxxxxxxx>
  • Date: Thu, 7 Aug 2025 12:33:30 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=epam.com; dmarc=pass action=none header.from=epam.com; dkim=pass header.d=epam.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=lC6NDosY+1Aunr9L72guv4I+Ysx9FQyAJ4/28AnhYr8=; b=qzbUXEQHatSLfIkr+H9s6uLSRrmtN5VcaybRu3J/Lwc3UGATwXCLX/Onobf6cz2bvp7M49uZc8F7Y+zI0Eg6UPyjuM+mwmNcqkA7T37vjf7+BRfFL8SaMyYJi3BDKdJCKjI92JL9RKP6KlrKHSS7qK2C6zAEfNdvWbQK1q/1fP40NmcbSCVGi7IqqH4CzZLHCnJ24j93/r8Tofs6tYjI/j5StEjjbRc5JUINOgd8k/h/6SrtBFVQk3hE5zi0suHPZF/GBhrmTXp5cMthHJQSwuQJ1KKMIr9GHZxXHJyCAJUwKVmADoZ4VXSItT6CKoAEqgAWS2p9hOBgXd3pbgFsfA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=GsAt98nWPiu7Kl83rRVH74UqFRGYcqeT7ph12IL61gVIrPg/q8OGWBmEuzVP+u49Kt/6gNWKy4ly9eeP8n94tc4yO42EMxgJqpcvU4XlazWph1JiOZN1y4iJbfqzS+Kc57Oi9SwGs00Dt4wnIz06dHfWZ3TpLBLpwFUvURZ9yVwRoAqf1kt5+3uuVEiHiGfX4UM67Z+zdhVx1BTNyISv8W5cIJ8UrRxg5Hsbgq7HLLmwlJ1wtkl1jOLZIcl0H/uOjm29eQT3QutuIrS1fmbwkNVkEhNT6HQJuB/gx3UXB97AzJ0R5ukTWuKFk2ES7KpoiqEfb2qp0mEa4w7Dxr/aqA==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=epam.com;
  • Cc: Leonid Komarianskyi <Leonid_Komarianskyi@xxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Thu, 07 Aug 2025 12:33:41 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHcB5d7cCAQRdJCgUKSzBGsZt4ytQ==
  • Thread-topic: [PATCH v2 01/10] xen/arm: gicv3: refactor obtaining GIC addresses for common operations

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@xxxxxxxx>

---
Changes in V2:
- no changes
---
 xen/arch/arm/gic-v3.c          | 99 ++++++++++++++++++++++------------
 xen/arch/arm/include/asm/irq.h |  1 +
 2 files changed, 67 insertions(+), 33 deletions(-)

diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index cd3e1acf79..8fd78aba44 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -445,17 +445,62 @@ 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 */
+    panic("Invalid offset 0x%x for IRQ#%d", offset, irqd->irq);
+
+    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;
-
-    if ( irqd->irq < NR_GIC_LOCAL_IRQS )
-        base = GICD_RDIST_SGI_BASE;
-    else
-        base = GICD;
+    void __iomem *addr = get_addr_by_offset(irqd, offset);
 
-    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 +508,9 @@ 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;
-
-    if ( irq >= NR_GIC_LOCAL_IRQS)
-        base = GICD + (irq / 32) * 4;
-    else
-        base = GICD_RDIST_SGI_BASE;
+    void __iomem *addr = get_addr_by_offset(irqd, offset);
 
-    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 +597,26 @@ 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);
 
-    if ( irq >= NR_GIC_LOCAL_IRQS)
-        base = GICD + GICD_ICFGR + (irq / 16) * 4;
-    else
-        base = GICD_RDIST_SGI_BASE + GICR_ICFGR1;
+    addr = get_addr_by_offset(desc, GICD_ICFGR);
 
-    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,15 +635,12 @@ 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;
 
     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);
+    addr = get_addr_by_offset(desc, GICD_IPRIORITYR);
+    writeb_relaxed(priority, addr);
 
     spin_unlock(&gicv3.lock);
 }
@@ -1273,6 +1305,7 @@ 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);
 
     ASSERT(!cpumask_empty(mask));
 
@@ -1284,7 +1317,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



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.