Interface: Refactor NS lock and SVC's interface

The NS lock implementation is refactored to use X
macros. This improves maintenability and readability
as limits only to tfm_ns_svc.h the file to be modified
when a new SVC interface has to be added. The SVC
declarations are also amended to use X macros.

Change-Id: I5d20e9a99c3193594b8882967be085406b8a354b
Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
diff --git a/app/main_ns.c b/app/main_ns.c
index 1af2c23..13725d0 100644
--- a/app/main_ns.c
+++ b/app/main_ns.c
@@ -14,14 +14,7 @@
 #include "cmsis_os2.h"
 #include "tfm_integ_test.h"
 #include "tfm_ns_svc.h"
-#include "tfm_sst_svc_handler.h"
 #include "tfm_ns_lock.h"
-#ifdef TFM_PARTITION_TEST_CORE
-#include "svc_core_test_ns.h"
-#endif
-#ifdef TFM_PARTITION_TEST_SST
-#include "sst_test_service_svc.h"
-#endif
 #ifdef TEST_FRAMEWORK_NS
 #include "test/framework/integ_test.h"
 #endif
@@ -41,31 +34,24 @@
        void * const osRtxUserSVC[1+USER_SVC_COUNT] = {
   (void *)USER_SVC_COUNT,
 
-/* SERVICES_TEST_NS */
-  (void *)tfm_sst_svc_get_handle,
-  (void *)tfm_sst_svc_create,
-  (void *)tfm_sst_svc_get_attributes,
-  (void *)tfm_sst_svc_read,
-  (void *)tfm_sst_svc_write,
-  (void *)tfm_sst_svc_delete,
+#define X(SVC_ENUM, SVC_HANDLER) (void*)SVC_HANDLER,
+    /* SVC API for Services */
+    LIST_SVC_DISPATCHERS
 
 #if defined(CORE_TEST_INTERACTIVE)
-  (void *)svc_secure_decrement_ns_lock_1,
-  (void *)svc_secure_decrement_ns_lock_2,
+    LIST_SVC_CORE_TEST_INTERACTIVE
 #endif /* CORE_TEST_INTERACTIVE */
 
 #if defined(TFM_PARTITION_TEST_CORE)
-  (void *)svc_tfm_core_test,
-  (void *)svc_tfm_core_test_multiple_calls,
+    LIST_SVC_TFM_PARTITION_TEST_CORE
 #endif /* TFM_PARTITION_TEST_CORE */
 
 #if defined(TFM_PARTITION_TEST_SST)
-  (void *)sst_test_service_svc_setup,
-  (void *)sst_test_service_svc_dummy_encrypt,
-  (void *)sst_test_service_svc_dummy_decrypt,
-  (void *)sst_test_service_svc_clean,
+    LIST_SVC_TFM_PARTITION_TEST_SST
 #endif /* TFM_PARTITION_TEST_SST */
 
+#undef X
+
 //(void *)user_function1,
 // ...
 };
diff --git a/app/tfm_integ_test.h b/app/tfm_integ_test.h
index 5be104b..a823ff1 100644
--- a/app/tfm_integ_test.h
+++ b/app/tfm_integ_test.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -26,15 +26,6 @@
  */
 #define UNUSED_VARIABLE(X) ((void)(X))
 
-/**
- * \brief Declarations for User defined SVC functions
- *        used in CORE_TEST_INTERACTIVE or
- *        CORE_TEST_POSITIVE
- *
- */
-void svc_secure_decrement_ns_lock_1(void);
-void svc_secure_decrement_ns_lock_2(void);
-
 #ifdef TEST_FRAMEWORK_NS
 /**
  * \brief Main test application for the RTX-TFM core
diff --git a/interface/include/tfm_ns_svc.h b/interface/include/tfm_ns_svc.h
index 330bd84..4e4d731 100644
--- a/interface/include/tfm_ns_svc.h
+++ b/interface/include/tfm_ns_svc.h
@@ -16,12 +16,85 @@
 #endif
 
 /**
+ * \brief Include all the SVC handler headers
+ */
+#include "tfm_sst_svc_handler.h"
+#include "svc_core_test_ns.h"
+#include "sst_test_service_svc.h"
+
+/**
  * \brief Macro to encode an svc instruction
  *
  */
 #define SVC(code) __ASM("svc %0" : : "I" (code))
 
 /**
+ * \def LIST_SVC_DISPATCHERS
+ *
+ * \brief This is an X macro which lists
+ *        the SVC interface exposed by the
+ *        available secure services. The
+ *        enumerator and corresponding
+ *        SVC handler function need to be
+ *        registered.
+ *
+ */
+#define LIST_SVC_DISPATCHERS \
+    X(SVC_TFM_SST_GET_HANDLE, tfm_sst_svc_get_handle) \
+    X(SVC_TFM_SST_CREATE, tfm_sst_svc_create) \
+    X(SVC_TFM_SST_GET_ATTRIBUTES, tfm_sst_svc_get_attributes) \
+    X(SVC_TFM_SST_READ, tfm_sst_svc_read) \
+    X(SVC_TFM_SST_WRITE, tfm_sst_svc_write) \
+    X(SVC_TFM_SST_DELETE, tfm_sst_svc_delete)
+
+/**
+ * \def LIST_SVC_CORE_TEST_INTERACTIVE
+ *
+ * \brief This is an X macro which lists
+ *        the SVC interface available for
+ *        the CORE_TEST_INTERACTIVE. The
+ *        enumerator and corresponding
+ *        SVC handler function need to be
+ *        registered.
+ *
+ */
+#define LIST_SVC_CORE_TEST_INTERACTIVE \
+    X(SVC_SECURE_DECREMENT_NS_LOCK_1, svc_secure_decrement_ns_lock_1) \
+    X(SVC_SECURE_DECREMENT_NS_LOCK_2, svc_secure_decrement_ns_lock_2)
+
+/**
+ * \def LIST_SVC_TFM_PARTITION_TEST_CORE
+ *
+ * \brief This is an X macro which lists
+ *        the SVC interface available for
+ *        the TEST_CORE partition. The
+ *        enumerator and corresponding
+ *        SVC handler function need to be
+ *        registered.
+ *
+ */
+#define LIST_SVC_TFM_PARTITION_TEST_CORE \
+    X(SVC_TFM_CORE_TEST, svc_tfm_core_test) \
+    X(SVC_TFM_CORE_TEST_MULTIPLE_CALLS, svc_tfm_core_test_multiple_calls)
+
+/**
+ * \def LIST_SVC_TFM_PARTITION_TEST_SST
+ *
+ * \brief This is an X macro which lists
+ *        the SVC interface available for
+ *        TEST_SST partition. The
+ *        enumerator and corresponding
+ *        SVC handler function need to be
+ *        registered.
+ *
+ */
+#define LIST_SVC_TFM_PARTITION_TEST_SST \
+    X(SVC_SST_TEST_SERVICE_SETUP, sst_test_service_svc_setup) \
+    X(SVC_SST_TEST_SERVICE_DUMMY_ENCRYPT, sst_test_service_svc_dummy_encrypt) \
+    X(SVC_SST_TEST_SERVICE_DUMMY_DECRYPT, sst_test_service_svc_dummy_decrypt) \
+    X(SVC_SST_TEST_SERVICE_CLEAN, sst_test_service_svc_clean)
+
+/**
  * \brief Numbers associated to each SVC available
  *
  * \details Start from 1 as 0 is reserved by RTX
@@ -29,31 +102,24 @@
 enum tfm_svc_num {
     SVC_INVALID = 0,
 
-/* SVC API for SST */
-    SVC_TFM_SST_GET_HANDLE,
-    SVC_TFM_SST_CREATE,
-    SVC_TFM_SST_GET_ATTRIBUTES,
-    SVC_TFM_SST_READ,
-    SVC_TFM_SST_WRITE,
-    SVC_TFM_SST_DELETE,
+#define X(SVC_ENUM, SVC_HANDLER) SVC_ENUM,
+    /* SVC API for Services */
+    LIST_SVC_DISPATCHERS
 
 #if defined(CORE_TEST_INTERACTIVE)
-    SVC_SECURE_DECREMENT_NS_LOCK_1,
-    SVC_SECURE_DECREMENT_NS_LOCK_2,
+    LIST_SVC_CORE_TEST_INTERACTIVE
 #endif /* CORE_TEST_INTERACTIVE */
 
 #if defined(TFM_PARTITION_TEST_CORE)
-    SVC_TFM_CORE_TEST,
-    SVC_TFM_CORE_TEST_MULTIPLE_CALLS,
+    LIST_SVC_TFM_PARTITION_TEST_CORE
 #endif /* TFM_PARTITION_TEST_CORE */
 
 #if defined(TFM_PARTITION_TEST_SST)
-    SVC_SST_TEST_SERVICE_SETUP,
-    SVC_SST_TEST_SERVICE_DUMMY_ENCRYPT,
-    SVC_SST_TEST_SERVICE_DUMMY_DECRYPT,
-    SVC_SST_TEST_SERVICE_CLEAN,
+    LIST_SVC_TFM_PARTITION_TEST_SST
 #endif /* TFM_PARTITION_TEST_SST */
 
+#undef X
+
     /* add all the new entries above this line */
     SVC_TFM_MAX,
 };
diff --git a/interface/src/tfm_ns_lock_rtx.c b/interface/src/tfm_ns_lock_rtx.c
index cf5fd6d..5ec6638 100644
--- a/interface/src/tfm_ns_lock_rtx.c
+++ b/interface/src/tfm_ns_lock_rtx.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -36,76 +36,49 @@
 };
 
 /**
- * \def NUM_SVC_DISPATCHERS
+ * \def TFM_SVC_DISPATCH_NAME
  *
+ * \brief Macro to declare a SVC dispatch function name
  */
-#define NUM_SVC_DISPATCHERS (6)
+#define TFM_SVC_DISPATCH_NAME(SVC_ENUM) tfm_svc_dispatch_##SVC_ENUM
+
+/**
+ * \def TFM_SVC_DISPATCH_FUNCTION
+ *
+ * \brief Macro to declare a SVC dispatch naked function body (4 bytes each)
+ */
+#define TFM_SVC_DISPATCH_FUNCTION(SVC_ENUM) \
+    __attribute__((naked)) \
+    static uint32_t TFM_SVC_DISPATCH_NAME(SVC_ENUM)(uint32_t arg0, \
+                                                    uint32_t arg1, \
+                                                    uint32_t arg2, \
+                                                    uint32_t arg3) \
+    { \
+        SVC(SVC_ENUM); \
+        __ASM("BX LR"); \
+    }
 
 /**
  * \brief Naked functions associated to each
- *        SVC needed
+ *        SVC in the list of X macros
+ *        \ref LIST_SVC_DISPATCHERS
  */
-__attribute__((naked))
-static uint32_t tfm_svc_dispatch_SST_GET_HANDLE(uint32_t arg0, uint32_t arg1,
-                                                uint32_t arg2, uint32_t arg3)
-{
-    SVC(SVC_TFM_SST_GET_HANDLE);
-    __ASM("BX LR");
-}
-
-__attribute__((naked))
-static uint32_t tfm_svc_dispatch_SST_CREATE(uint32_t arg0, uint32_t arg1,
-                                                uint32_t arg2, uint32_t arg3)
-{
-    SVC(SVC_TFM_SST_CREATE);
-    __ASM("BX LR");
-}
-
-__attribute__((naked))
-static uint32_t tfm_svc_dispatch_SST_GET_ATTRIBUTES(uint32_t arg0,uint32_t arg1,
-                                                    uint32_t arg2,uint32_t arg3)
-{
-    SVC(SVC_TFM_SST_GET_ATTRIBUTES);
-    __ASM("BX LR");
-}
-
-__attribute__((naked))
-static uint32_t tfm_svc_dispatch_SST_READ(uint32_t arg0, uint32_t arg1,
-                                              uint32_t arg2, uint32_t arg3)
-{
-    SVC(SVC_TFM_SST_READ);
-    __ASM("BX LR");
-}
-
-__attribute__((naked))
-static uint32_t tfm_svc_dispatch_SST_WRITE(uint32_t arg0, uint32_t arg1,
-                                               uint32_t arg2, uint32_t arg3)
-{
-    SVC(SVC_TFM_SST_WRITE);
-    __ASM("BX LR");
-}
-
-__attribute__((naked))
-static uint32_t tfm_svc_dispatch_SST_DELETE(uint32_t arg0, uint32_t arg1,
-                                                uint32_t arg2, uint32_t arg3)
-{
-    SVC(SVC_TFM_SST_DELETE);
-    __ASM("BX LR");
-}
+#define X(SVC_ENUM, SVC_HANDLER) TFM_SVC_DISPATCH_FUNCTION(SVC_ENUM);
+LIST_SVC_DISPATCHERS
+#undef X
 
 /**
  * \brief Array with function pointers to the
  *        naked functions. Entry 0 is treated
-*         as invalid
+ *        as invalid. The other entries are
+ *        taken automatically from the list of
+ *        X macros \ref LIST_SVC_DISPATCHERS
  */
-static void *tfm_svc_dispatch_functions[NUM_SVC_DISPATCHERS+1] = {
+static void *tfm_svc_dispatch_functions[] = {
     (void *) NULL, /* SVC_INVALID */
-    (void *) tfm_svc_dispatch_SST_GET_HANDLE,
-    (void *) tfm_svc_dispatch_SST_CREATE,
-    (void *) tfm_svc_dispatch_SST_GET_ATTRIBUTES,
-    (void *) tfm_svc_dispatch_SST_READ,
-    (void *) tfm_svc_dispatch_SST_WRITE,
-    (void *) tfm_svc_dispatch_SST_DELETE
+#define X(SVC_ENUM, SVC_HANDLER) (void *)TFM_SVC_DISPATCH_NAME(SVC_ENUM),
+    LIST_SVC_DISPATCHERS
+#undef X
 };
 
 /**
@@ -119,7 +92,10 @@
 {
     uint32_t result;
     uint32_t (*tfm_svc_dispatch_function_p)(uint32_t, uint32_t,
-                                                uint32_t, uint32_t);
+                                            uint32_t, uint32_t);
+
+    const uint32_t num_svc_dispatchers =
+      sizeof(tfm_svc_dispatch_functions)/sizeof(tfm_svc_dispatch_functions[0]);
 
     /* Check the NS lock has been initialized */
     if (ns_lock.init == false) {
@@ -127,7 +103,7 @@
     }
 
     /* Validate the SVC number requested */
-    if ((svc_num > SVC_INVALID) && (svc_num < (NUM_SVC_DISPATCHERS+1))) {
+    if ((svc_num > SVC_INVALID) && (svc_num < num_svc_dispatchers)) {
         tfm_svc_dispatch_function_p = tfm_svc_dispatch_functions[svc_num];
 
         /* TFM request protected by NS lock */
diff --git a/test/interface/include/svc_core_test_ns.h b/test/interface/include/svc_core_test_ns.h
index 55b87c7..19bebd7 100644
--- a/test/interface/include/svc_core_test_ns.h
+++ b/test/interface/include/svc_core_test_ns.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -28,6 +28,18 @@
  */
 int32_t svc_tfm_core_test_multiple_calls(void);
 
+/**
+ * \brief SVC handler used in CORE_TEST_INTERACTIVE, to test
+ *        requests to TF-M core from different NS threads.
+ */
+void svc_secure_decrement_ns_lock_1(void);
+
+/**
+ * \brief SVC handler used in CORE_TEST_INTERACTIVE, to test
+ *        requests to TF-M core from different NS threads.
+ */
+void svc_secure_decrement_ns_lock_2(void);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/test/suites/core/non_secure/core_test_api.c b/test/suites/core/non_secure/core_test_api.c
index 828bdbc..430d4db 100644
--- a/test/suites/core/non_secure/core_test_api.c
+++ b/test/suites/core/non_secure/core_test_api.c
@@ -1,12 +1,10 @@
 /*
- * Copyright (c) 2017, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
  */
 
-#include "app/tfm_integ_test.h"
-
 #include "core_test_api.h"
 #include "tfm_ns_svc.h"