diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c index 25296a6..4b0984d 100644 --- a/drivers/arm/gic/v2/gicv2_main.c +++ b/drivers/arm/gic/v2/gicv2_main.c @@ -308,9 +308,26 @@ if (driver_data->target_masks[proc_num]) return; - /* Read target register corresponding to this CPU */ - driver_data->target_masks[proc_num] = - gicv2_get_cpuif_id(driver_data->gicd_base); + /* + * Update target register corresponding to this CPU and flush for it to + * be visible to other CPUs. + */ + if (driver_data->target_masks[proc_num] == 0) { + driver_data->target_masks[proc_num] = + gicv2_get_cpuif_id(driver_data->gicd_base); +#if !HW_ASSISTED_COHERENCY + /* + * PEs only update their own masks. Primary updates it with + * caches on. But because secondaries does it with caches off, + * all updates go to memory directly, and there's no danger of + * secondaries overwriting each others' mask, despite + * target_masks[] not being cache line aligned. + */ + flush_dcache_range((uintptr_t) + &driver_data->target_masks[proc_num], + sizeof(driver_data->target_masks[proc_num])); +#endif + } } /******************************************************************************* diff --git a/plat/arm/common/arm_gicv2.c b/plat/arm/common/arm_gicv2.c index b081fa8..5644c60 100644 --- a/plat/arm/common/arm_gicv2.c +++ b/plat/arm/common/arm_gicv2.c @@ -51,6 +51,7 @@ { gicv2_distif_init(); gicv2_pcpu_distif_init(); + gicv2_set_pe_target_mask(plat_my_core_pos()); gicv2_cpuif_enable(); }