summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJeenu Viswambharan <jeenu.viswambharan@arm.com>2017-11-07 16:10:19 +0000
committerJeenu Viswambharan <jeenu.viswambharan@arm.com>2017-11-13 07:49:30 +0000
commit058efeef98315d21f59092c80dd1d24d58008b4d (patch)
tree54262034145145cfa790b45ab2f43f1a8a40e392 /drivers
parentbf2de7e49971159bc46b4215aed09150bea63176 (diff)
GICv2: Fix populating PE target data
This patch brings in the following fixes: - The per-PE target data initialized during power up needs to be flushed so as to be visible to other PEs. - Setup per-PE target data for the primary PE as well. At present, this was only setup for secondary PEs when they were powered on. Change-Id: Ibe3a57c14864e37b2326dd7ab321a5c7bf80e8af Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/arm/gic/v2/gicv2_main.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c
index 25296a63..4b0984d8 100644
--- a/drivers/arm/gic/v2/gicv2_main.c
+++ b/drivers/arm/gic/v2/gicv2_main.c
@@ -308,9 +308,26 @@ void gicv2_set_pe_target_mask(unsigned int proc_num)
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
+ }
}
/*******************************************************************************