Register NS shared memory for SP's activity logs and TA sessions

This patch registers NS memory buffer with the secure payload using
two different functions IDs - REGISTER_LOGBUF, REGISTER_REQBUF.

a. The SP uses the log-buffer to store its activity logs, in a
pre-decided format. This helps in debugging secure payload's issues.
b. The SP uses the req-buffer to get the parameters required by
sessions with Trusted Applications.

Change-Id: I6b0247cf7790524132ee0da24f1f35b1fccec5d5
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
diff --git a/services/spd/tlkd/tlkd_main.c b/services/spd/tlkd/tlkd_main.c
index 65466aa..8d2d437 100644
--- a/services/spd/tlkd/tlkd_main.c
+++ b/services/spd/tlkd/tlkd_main.c
@@ -186,6 +186,7 @@
 			 void *handle,
 			 uint64_t flags)
 {
+	cpu_context_t *ns_cpu_context;
 	uint32_t ns;
 
 	/* Passing a NULL context is a critical programming error */
@@ -197,11 +198,91 @@
 	switch (smc_fid) {
 
 	/*
+	 * This is a request from the non-secure context to:
+	 *
+	 * a. register shared memory with the SP for storing it's
+	 *    activity logs.
+	 * b. register shared memory with the SP for passing args
+	 *    required for maintaining sessions with the Trusted
+	 *    Applications.
+	 */
+	case TLK_REGISTER_LOGBUF:
+	case TLK_REGISTER_REQBUF:
+		if (!ns || !tlk_args_results_buf)
+			SMC_RET1(handle, SMC_UNK);
+
+		/*
+		 * This is a fresh request from the non-secure client.
+		 * The parameters are in x1 and x2. Figure out which
+		 * registers need to be preserved, save the non-secure
+		 * state and send the request to the secure payload.
+		 */
+		assert(handle == cm_get_context(NON_SECURE));
+
+		/* Check if we are already preempted */
+		if (get_std_smc_active_flag(tlk_ctx.state))
+			SMC_RET1(handle, SMC_UNK);
+
+		cm_el1_sysregs_context_save(NON_SECURE);
+
+		/*
+		 * Verify if there is a valid context to use.
+		 */
+		assert(&tlk_ctx.cpu_ctx == cm_get_context(SECURE));
+
+		/*
+		 * Mark the SP state as active.
+		 */
+		set_std_smc_active_flag(tlk_ctx.state);
+
+		/* Save args for use by the SP on return */
+		store_tlk_args_results(smc_fid, x1, x2, x3);
+
+		/*
+		 * We are done stashing the non-secure context. Ask the
+		 * secure payload to do the work now.
+		 */
+		cm_el1_sysregs_context_restore(SECURE);
+		cm_set_next_eret_context(SECURE);
+		SMC_RET0(&tlk_ctx.cpu_ctx);
+
+	/*
+	 * This is a request from the SP to mark completion of
+	 * a standard function ID.
+	 */
+	case TLK_REQUEST_DONE:
+		if (ns || !tlk_args_results_buf)
+			SMC_RET1(handle, SMC_UNK);
+
+		/*
+		 * Mark the SP state as inactive.
+		 */
+		clr_std_smc_active_flag(tlk_ctx.state);
+
+		/* Get a reference to the non-secure context */
+		ns_cpu_context = cm_get_context(NON_SECURE);
+		assert(ns_cpu_context);
+
+		/*
+		 * This is a request completion SMC and we must switch to
+		 * the non-secure world to pass the result.
+		 */
+		cm_el1_sysregs_context_save(SECURE);
+
+		/*
+		 * We are done stashing the secure context. Switch to the
+		 * non-secure context and return the result.
+		 */
+		cm_el1_sysregs_context_restore(NON_SECURE);
+		cm_set_next_eret_context(NON_SECURE);
+		SMC_RET1(ns_cpu_context, tlk_args_results_buf->args[0]);
+
+	/*
 	 * This function ID is used only by the SP to indicate it has
 	 * finished initialising itself after a cold boot
 	 */
 	case TLK_ENTRY_DONE:
-		if (ns)
+		if (ns || !tlk_args_results_buf)
 			SMC_RET1(handle, SMC_UNK);
 
 		/*