aboutsummaryrefslogtreecommitdiff
path: root/include/drivers/arm/gicv3.h
diff options
context:
space:
mode:
authorSandeep Tripathy <sandeep.tripathy@broadcom.com>2020-06-05 22:04:21 +0530
committerSandeep Tripathy <sandeep.tripathy@broadcom.com>2020-06-22 16:08:35 +0530
commit5eb16c4717ac08de7c627cb1ee47c3269f0ec363 (patch)
treef0881455450d68e705244408e423ee886699724c /include/drivers/arm/gicv3.h
parent71c074c55291e38958ddcf5160dec0447f8fec73 (diff)
downloadtrusted-firmware-a-5eb16c4717ac08de7c627cb1ee47c3269f0ec363.tar.gz
TF-A GIC driver: Add barrier before eoi
It is desired to have the peripheral writes completed to clear the interrupt condition and de-assert the interrupt request to GIC before EOI write. Failing which spurious interrupt will occurred. A barrier is needed to ensure peripheral register write transfers are complete before EOI is done. GICv2 memory mapped DEVICE nGnR(n)E writes are ordered from core point of view. However these writes may pass over different interconnects, bridges, buffers leaving some rare chances for the actual write to complete out of order. GICv3 ICC EOI system register writes have no ordering against nGnR(n)E memory writes as they are over different interfaces. Hence a dsb can ensure from core no writes are issued before the previous writes are *complete*. Signed-off-by: Sandeep Tripathy <sandeep.tripathy@broadcom.com> Change-Id: Ie6362009e2f91955be99dca8ece14ade7b4811d6
Diffstat (limited to 'include/drivers/arm/gicv3.h')
-rw-r--r--include/drivers/arm/gicv3.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index 77dc350ddb..97b75b0dae 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -332,6 +332,18 @@ static inline uint32_t gicv3_get_pending_interrupt_id_sel1(void)
static inline void gicv3_end_of_interrupt_sel1(unsigned int id)
{
+ /*
+ * Interrupt request deassertion from peripheral to GIC happens
+ * by clearing interrupt condition by a write to the peripheral
+ * register. It is desired that the write transfer is complete
+ * before the core tries to change GIC state from 'AP/Active' to
+ * a new state on seeing 'EOI write'.
+ * Since ICC interface writes are not ordered against Device
+ * memory writes, a barrier is required to ensure the ordering.
+ * The dsb will also ensure *completion* of previous writes with
+ * DEVICE nGnRnE attribute.
+ */
+ dsbishst();
write_icc_eoir1_el1(id);
}
@@ -345,6 +357,18 @@ static inline uint32_t gicv3_acknowledge_interrupt(void)
static inline void gicv3_end_of_interrupt(unsigned int id)
{
+ /*
+ * Interrupt request deassertion from peripheral to GIC happens
+ * by clearing interrupt condition by a write to the peripheral
+ * register. It is desired that the write transfer is complete
+ * before the core tries to change GIC state from 'AP/Active' to
+ * a new state on seeing 'EOI write'.
+ * Since ICC interface writes are not ordered against Device
+ * memory writes, a barrier is required to ensure the ordering.
+ * The dsb will also ensure *completion* of previous writes with
+ * DEVICE nGnRnE attribute.
+ */
+ dsbishst();
return write_icc_eoir0_el1(id);
}