diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c index c5bced0..4b21b92 100644 --- a/drivers/arm/gic/v2/gicv2_main.c +++ b/drivers/arm/gic/v2/gicv2_main.c @@ -247,6 +247,15 @@ 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 77dc350..97b75b0 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -332,6 +332,18 @@ 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 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); }