aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/arm/gic/v2/gicv2_main.c9
-rw-r--r--include/drivers/arm/gicv3.h24
2 files changed, 33 insertions, 0 deletions
diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c
index c5bced00d8..4b21b920a7 100644
--- a/drivers/arm/gic/v2/gicv2_main.c
+++ b/drivers/arm/gic/v2/gicv2_main.c
@@ -247,6 +247,15 @@ void gicv2_end_of_interrupt(unsigned int id)
assert(driver_data != NULL);
assert(driver_data->gicc_base != 0U);
+ /*
+ * Ensure the write to peripheral registers are *complete* before the write
+ * to GIC_EOIR.
+ *
+ * Note: The completion gurantee depends on various factors of system design
+ * and the barrier is the best core can do by which execution of further
+ * instructions waits till the barrier is alive.
+ */
+ dsbishst();
gicc_write_EOIR(driver_data->gicc_base, id);
}
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);
}