Register NS shared memory for SP's activity logs and TA sessions
authorVarun Wadekar <vwadekar@nvidia.com>
Fri, 13 Mar 2015 08:49:11 +0000 (14:19 +0530)
committerVarun Wadekar <vwadekar@nvidia.com>
Tue, 31 Mar 2015 04:36:15 +0000 (10:06 +0530)
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>
include/bl32/payloads/tlk.h
services/spd/tlkd/tlkd_main.c

index d9fa79499543e7c6d720d4a021ca57456c2c2e6a..b6299a8b5997a229821c41d11c058f3426cf7b4e 100644 (file)
 #ifndef __TLK_H__
 #define __TLK_H__
 
+/*
+ * Generate function IDs for the Trusted OS/Apps
+ */
+#define TLK_TOS_STD_FID(fid)   ((fid) | 0x72000000 | (0 << 31))
+
+/*
+ * Trusted OS specific function IDs
+ */
+#define TLK_REGISTER_LOGBUF    TLK_TOS_STD_FID(0x1)
+#define TLK_REGISTER_REQBUF    TLK_TOS_STD_FID(0x2)
+
 /*
  * SMC function IDs that TLK uses to signal various forms of completions
  * to the secure payload dispatcher.
  */
+#define TLK_REQUEST_DONE       (0x32000001 | (1 << 31))
 #define TLK_ENTRY_DONE         (0x32000003 | (1 << 31))
 #define TLK_FID_SHARED_MEMBUF  (0x32000005 | (1 << 31))
 
index 65466aa2ec731c5f16c2ac679c58eaa3c3ef9bbb..8d2d437ed572d0d5363f22ec417e440314a272a7 100644 (file)
@@ -186,6 +186,7 @@ uint64_t tlkd_smc_handler(uint32_t smc_fid,
                         void *handle,
                         uint64_t flags)
 {
+       cpu_context_t *ns_cpu_context;
        uint32_t ns;
 
        /* Passing a NULL context is a critical programming error */
@@ -196,12 +197,92 @@ uint64_t tlkd_smc_handler(uint32_t smc_fid,
 
        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);
 
                /*