qemu-devel
[Top][All Lists]
Advanced

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

[kvm-unit-tests PATCH v4 11/12] arm: gic: Introduce gic_irq_set_clr_enab


From: Eric Auger
Subject: [kvm-unit-tests PATCH v4 11/12] arm: gic: Introduce gic_irq_set_clr_enable() helper
Date: Fri, 3 Apr 2020 09:13:25 +0200

Allows to set or clear the enable state of a PPI/SGI/SPI.

Signed-off-by: Eric Auger <address@hidden>

---
---
 lib/arm/asm/gic.h |  4 ++++
 lib/arm/gic.c     | 31 +++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/lib/arm/asm/gic.h b/lib/arm/asm/gic.h
index 922cbe9..57e81c6 100644
--- a/lib/arm/asm/gic.h
+++ b/lib/arm/asm/gic.h
@@ -82,5 +82,9 @@ extern void gic_ipi_send_single(int irq, int cpu);
 extern void gic_ipi_send_mask(int irq, const cpumask_t *dest);
 extern enum gic_irq_state gic_irq_state(int irq);
 
+void gic_irq_set_clr_enable(int irq, bool enable);
+#define gic_enable_irq(irq) gic_irq_set_clr_enable(irq, true);
+#define gic_disable_irq(irq) gic_irq_set_clr_enable(irq, false);
+
 #endif /* !__ASSEMBLY__ */
 #endif /* _ASMARM_GIC_H_ */
diff --git a/lib/arm/gic.c b/lib/arm/gic.c
index c3c5f6b..8a1a8c8 100644
--- a/lib/arm/gic.c
+++ b/lib/arm/gic.c
@@ -147,6 +147,36 @@ void gic_ipi_send_mask(int irq, const cpumask_t *dest)
        gic_common_ops->ipi_send_mask(irq, dest);
 }
 
+void gic_irq_set_clr_enable(int irq, bool enable)
+{
+       u32 offset, split = 32, shift = (irq % 32);
+       u32 reg, mask = BIT(shift);
+       void *base;
+
+       assert(irq < 1020);
+
+       switch (gic_version()) {
+       case 2:
+               offset = enable ? GICD_ISENABLER : GICD_ICENABLER;
+               base = gicv2_dist_base();
+               break;
+       case 3:
+               if (irq < 32) {
+                       offset = enable ? GICR_ISENABLER0 : GICR_ICENABLER0;
+                       base = gicv3_sgi_base();
+               } else {
+                       offset = enable ? GICD_ISENABLER : GICD_ICENABLER;
+                       base = gicv3_dist_base();
+               }
+               break;
+       default:
+               assert(0);
+       }
+       base += offset + (irq / split) * 4;
+       reg = readl(base);
+       writel(reg | mask, base);
+}
+
 enum gic_irq_state gic_irq_state(int irq)
 {
        enum gic_irq_state state;
@@ -191,3 +221,4 @@ enum gic_irq_state gic_irq_state(int irq)
 
        return state;
 }
+
-- 
2.20.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]