feat(tc): get the parent component provided DPE context_handle

Each client who wants to communicate with the DPE service
must own a valid context handle issued by the DPE service.
A context handle can be used for a single time then it will
be invalidated by the DPE service. In case of calls from
the same component, the next valid context handle is
returned in the response to a DPE command. When a component
finishes their job then the next component in the boot flow
inherits its first context handle from its parent.
How the inheritance is done can be client or
platform-dependent. It can be shared through shared
memory or be part of a DTB object passed to the next
bootloader stage.

Signed-off-by: Tamas Ban <tamas.ban@arm.com>
Signed-off-by: David Vincze <david.vincze@arm.com>
Change-Id: Ic82f074f1c5b15953e78f9fa5404ed7f48674cbb
diff --git a/plat/arm/board/tc/tc_bl1_dpe.c b/plat/arm/board/tc/tc_bl1_dpe.c
index 25fdf95..c206b55 100644
--- a/plat/arm/board/tc/tc_bl1_dpe.c
+++ b/plat/arm/board/tc/tc_bl1_dpe.c
@@ -7,7 +7,10 @@
 #include <stdint.h>
 
 #include <common/debug.h>
+#include <drivers/arm/css/sds.h>
 #include <drivers/arm/rss_comms.h>
+#include <drivers/delay_timer.h>
+#include <drivers/generic_delay_timer.h>
 #include <drivers/measured_boot/metadata.h>
 #include <drivers/measured_boot/rss/dice_prot_env.h>
 #include <plat/arm/common/plat_arm.h>
@@ -44,6 +47,10 @@
 		.id = DPE_INVALID_ID }
 };
 
+/* Effective timeout of 10000 ms */
+#define RSS_DPE_BOOT_10US_RETRIES		1000000
+#define TC2_SDS_DPE_CTX_HANDLE_STRUCT_ID	0x0000000A
+
 /* Context handle is meant to be used by BL2. Sharing it via TB_FW_CONFIG */
 static int new_ctx_handle;
 
@@ -52,6 +59,53 @@
 	new_ctx_handle = *ctx_handle;
 }
 
+void plat_dpe_get_context_handle(int *ctx_handle)
+{
+	int retry = RSS_DPE_BOOT_10US_RETRIES;
+	int ret;
+
+	/* Initialize System level generic or SP804 timer */
+	generic_delay_timer_init();
+
+	/* Check the initialization of the Shared Data Storage area between RSS
+	 * and AP. Since AP_BL1 is executed first then a bit later the RSS
+	 * runtime, which initialize this area, therefore AP needs to check it
+	 * in a loop until it gets written by RSS Secure Runtime.
+	 */
+	VERBOSE("Waiting for DPE service initialization in RSS Secure Runtime\n");
+	while (retry > 0) {
+		ret = sds_init(SDS_RSS_AP_REGION_ID);
+		if (ret != SDS_OK) {
+			udelay(10);
+			retry--;
+		} else {
+			break;
+		}
+	}
+
+	if (retry == 0) {
+		ERROR("DPE init timeout\n");
+		plat_panic_handler();
+	} else {
+		VERBOSE("DPE init succeeded in %dms.\n",
+			(RSS_DPE_BOOT_10US_RETRIES - retry) / 100);
+	}
+
+	/* TODO: call this in a loop to avoid reading unfinished data */
+	ret = sds_struct_read(SDS_RSS_AP_REGION_ID,
+			      TC2_SDS_DPE_CTX_HANDLE_STRUCT_ID,
+			      0,
+			      ctx_handle,
+			      sizeof(*ctx_handle),
+			      SDS_ACCESS_MODE_NON_CACHED);
+	if (ret != SDS_OK) {
+		ERROR("Unable to get DPE context handle from SDS area\n");
+		plat_panic_handler();
+	}
+
+	VERBOSE("Received DPE context handle: 0x%x\n", *ctx_handle);
+}
+
 void bl1_plat_mboot_init(void)
 {
 	/* Initialize the communication channel between AP and RSS */