SPM: Add a tracking table for stateless service

This patch adds a tracking table for static services, which stores
handle values and service structure pointers. Also add runtime
initialization of the tracking table.

Change-Id: I614c6a638245ed58cddbeee6290cfc05bc54fa0d
Signed-off-by: Mingyang Sun <mingyang.sun@arm.com>
diff --git a/secure_fw/partitions/tfm_service_list.inc.template b/secure_fw/partitions/tfm_service_list.inc.template
index 0816d2f..75e9949 100644
--- a/secure_fw/partitions/tfm_service_list.inc.template
+++ b/secure_fw/partitions/tfm_service_list.inc.template
@@ -92,4 +92,17 @@
 {% endfor %}
 };
 
+/* p_service field of tracking table will be populated in spm_init() */
+struct stateless_service_tracking_t stateless_service_ref[] = {
+    {% for service in stateless_services %}
+    {{'{'}}
+            {% if service is not none %}
+        .sid = {{service.sid}},
+            {% else %}
+        .sid = 0,
+            {% endif %}
+    {{'}'}},
+    {% endfor %}
+};
+
 #endif /* __TFM_SERVICE_LIST_INC__ */
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.c b/secure_fw/spm/cmsis_psa/spm_ipc.c
index fa828aa..0a32695 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.c
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.c
@@ -741,6 +741,7 @@
     /* Init Service */
     num = sizeof(service) / sizeof(struct tfm_spm_service_t);
     for (i = 0; i < num; i++) {
+        int32_t j = 0;
         service[i].service_db = &service_db[i];
         partition =
             tfm_spm_get_partition_by_id(service[i].service_db->partition_id);
@@ -750,6 +751,20 @@
         service[i].partition = partition;
         partition->signals_allowed |= service[i].service_db->signal;
 
+        /* Populate the p_service of stateless_service_ref[] */
+        if (service_db[i].connection_based == false) {
+            for (j = 0; j < STATIC_HANDLE_VALUE_LIMIT; j++) {
+                if (stateless_service_ref[j].sid == service_db[i].sid) {
+                    stateless_service_ref[j].p_service = &service[i];
+                    break;
+                }
+            }
+            /* Stateless service not found in tracking table */
+            if (j >= STATIC_HANDLE_VALUE_LIMIT) {
+                tfm_core_panic();
+            }
+        }
+
         BI_LIST_INIT_NODE(&service[i].handle_list);
     }
 
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.h b/secure_fw/spm/cmsis_psa/spm_ipc.h
index 188420e..6aa0842 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.h
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.h
@@ -139,6 +139,12 @@
     struct bi_list_node_t list;              /* For list operation           */
 };
 
+/* Stateless RoT service tracking array item type. Indexed by static handle */
+struct stateless_service_tracking_t {
+    uint32_t                 sid;           /* Service ID */
+    struct tfm_spm_service_t *p_service;    /* Service instance */
+};
+
 /* RoT connection handle list */
 struct tfm_conn_handle_t {
     void *rhandle;                      /* Reverse handle value              */