Docs: Added docs for RoT implementation

Added section for RoT service implementation

Change-Id: I58ce1511167c9c5b6168bfb8679905c35edf5d70
Signed-off-by: Boris Deletic <boris.deletic@arm.com>
diff --git a/docs/reference/services/tfm_secure_partition_addition.rst b/docs/reference/services/tfm_secure_partition_addition.rst
index b635cca..9a5663d 100644
--- a/docs/reference/services/tfm_secure_partition_addition.rst
+++ b/docs/reference/services/tfm_secure_partition_addition.rst
@@ -100,7 +100,7 @@
     "name": "TFM_SP_EXAMPLE",
     "type": "PSA-ROT",
     "priority": "HIGH",
-    "entry_point": "EXAMPLE_main",
+    "entry_point": "example_main",
     "stack_size": "0x0200",
     "services" : [
       {
@@ -273,6 +273,10 @@
    The CMakeLists.inc is not mandatory, the user can put everything in
    CMakeLists.txt.
 
+The current CMake configuration should also be updated, by updating
+CommonConfig.cmake to include the definition of the newly introduced partition
+and adding the relevant subdirectoy in ``secure_fw/CMakeLists.txt``.
+
 Please refer to the source code of TF-M for more detail.
 
 Update manifest list
@@ -301,7 +305,7 @@
       "short_name": "TFM_SP_EXAMPLE",
       "manifest": "secure_fw/partitions/EXAMPLE/tfm_example.yaml",
       "tfm_partition_ipc": true,
-      "conditional": "TFM_PARTITION_EXAMPLE_ENABLE",
+      "conditional": "TFM_PARTITION_EXAMPLE",
       "version_major": 0,
       "version_minor": 1,
       "pid": 256
@@ -320,8 +324,135 @@
 
 Implement the RoT services
 ==========================
-The following not-binding rules, as currently implemented, can be used as
-guidelines:
+To implement RoT services, the partition needs a source file which contains the
+implementations of the services, as well as the partition entry point. The user
+can create this source file under
+``<TF-M base folder>/secure_fw/partitions/EXAMPLE/EXAMPLE.c``. The linker
+detects source files according to the pattern matching defined by the
+"linker_pattern" attribute in the ``tfm_manifest_list.yaml`` file.
+
+As an example, the RoT service with SID **ROT_A** will be implemented.
+
+Entry point function
+--------------------
+This function acts as a main() function for the partition.
+On incoming signals for service calls, the entry point function handles
+signals by calling the relevant service function.
+An example entry point is given
+
+.. code-block:: c
+
+    void example_main(void)
+    {
+        psa_signal_t signals = 0;
+
+        while (1) {
+            signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
+            if (signals & ROT_A_SIGNAL) {
+                rot_A();
+            } else {
+                /* Should not come here */
+                psa_panic();
+            }
+        }
+    }
+
+Service implementation
+----------------------
+The service is implemented by the ``rot_A()`` function, which is called upon an
+incoming signal. This implementation is up to the user, however an example
+service has been included for reference. The following example sends a message
+"Hello World" when called.
+
+.. code-block:: c
+
+    static void rot_A(void)
+    {
+        const int BUFFER_LEN = 32;
+        psa_msg_t msg;
+        psa_status_t r;
+        int i;
+        uint8_t rec_buf[BUFFER_LEN];
+        uint8_t send_buf[BUFFER_LEN] = "Hello World";
+
+        psa_get(ROT_A_SIGNAL, &msg);
+        switch (msg.type) {
+        case PSA_IPC_CONNECT:
+            if (service_in_use & ROT_A_SIGNAL) {
+                r = PSA_ERROR_CONNECTION_REFUSED;
+            } else {
+                service_in_use |= ROT_A_SIGNAL;
+                r = PSA_SUCCESS;
+            }
+            psa_reply(msg.handle, r);
+            break;
+        case PSA_IPC_CALL:
+            for (i = 0; i < PSA_MAX_IOVEC; i++) {
+                if (msg.in_size[i] != 0) {
+                    psa_read(msg.handle, i, rec_buf, BUFFER_LEN);
+                }
+                if (msg.out_size[i] != 0) {
+                    psa_write(msg.handle, i, send_buf, BUFFER_LEN);
+                }
+            }
+            psa_reply(msg.handle, PSA_SUCCESS);
+            break;
+        case PSA_IPC_DISCONNECT:
+            assert((service_in_use & ROT_A_SIGNAL) != 0);
+            service_in_use &= ~ROT_A_SIGNAL;
+            psa_reply(msg.handle, PSA_SUCCESS);
+            break;
+        default:
+            /* cannot get here [broken SPM] */
+            psa_panic();
+            break;
+        }
+    }
+
+Test connection
+---------------
+To test that the service has been implemented correctly, the user needs to call
+it from somewhere. One option is to create a new testsuite, such as
+``<TF-M-test base folder>/test/suites/example/non_secure/example_ns_interface_testsuite.c``.
+
+.. code-block:: c
+
+    static void tfm_example_test_1001(struct test_result_t *ret)
+    {
+        char str1[] = "str1";
+        char str2[] = "str2";
+        char str3[128], str4[128];
+        struct psa_invec invecs[2] = {{str1, sizeof(str1)},
+                                      {str2, sizeof(str2)}};
+        struct psa_outvec outvecs[2] = {{str3, sizeof(str3)},
+                                        {str4, sizeof(str4)}};
+        psa_handle_t handle;
+        psa_status_t status;
+        uint32_t version;
+
+        version = psa_version(ROT_A_SID);
+        TEST_LOG("TFM service support version is %d.\r\n", version);
+        handle = psa_connect(ROT_A_SID, ROT_A_VERSION);
+        status = psa_call(handle, PSA_IPC_CALL, invecs, 2, outvecs, 2);
+        if (status >= 0) {
+            TEST_LOG("psa_call is successful!\r\n");
+        } else {
+            TEST_FAIL("psa_call is failed!\r\n");
+            return;
+        }
+
+        TEST_LOG("outvec1 is: %s\r\n", outvecs[0].base);
+        TEST_LOG("outvec2 is: %s\r\n", outvecs[1].base);
+        psa_close(handle);
+        ret->val = TEST_PASSED;
+    }
+
+Once the test and service has been implemented, the project can be built and
+executed. The user should see the "Hello World" message in the console as
+received by the testsuite.
+
+Further Notes
+-------------
 
 - In the IPC model, Use PSA FF proposed memory accessing mechanism. SPM
   provides APIs and checking between isolation boundaries, a free accessing