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>
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();
 }