Update the example Partition

- Updates the README.
- Upgrades to firmware framework v1.1
- Combine the service APIs into a single file
- Adds manifest list

Signed-off-by: Kevin Peng <kevin.peng@arm.com>
Change-Id: I1f9c35413bfe4214a08f8eb56cb435480863139e
diff --git a/examples/example_partition/CMakeLists.txt b/examples/example_partition/CMakeLists.txt
index 0aabff2..87e46b3 100644
--- a/examples/example_partition/CMakeLists.txt
+++ b/examples/example_partition/CMakeLists.txt
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -17,46 +17,53 @@
 # linker script will lay the partition in memory.
 add_library(tfm_app_rot_partition_example STATIC)
 
-# Add the source files generated by parse tools when building. The intermedia
-# file defines the partition stack. The load info file includes the static data
-# of the partition.
 target_sources(tfm_app_rot_partition_example
     PRIVATE
         tfm_example_partition.c
-        $<$<BOOL:${TFM_PSA_API}>:
-            ${CMAKE_BINARY_DIR}/generated/secure_fw/partitions/example_partition/auto_generated/intermedia_tfm_example_partition.c>
 )
+
+# Add the source files generated by parse tools when building.
+# The intermedia file defines the partition stack.
+target_sources(tfm_app_rot_partition_example
+    PRIVATE
+        ${CMAKE_BINARY_DIR}/generated/example_partition/auto_generated/intermedia_tfm_example_partition.c
+)
+
+# The load info file includes the static data of the partition.
 target_sources(tfm_partitions
     INTERFACE
-        $<$<BOOL:${TFM_PSA_API}>:
-            ${CMAKE_BINARY_DIR}/generated/secure_fw/partitions/example_partition/auto_generated/load_info_tfm_example_partition.c>
+        ${CMAKE_BINARY_DIR}/generated/example_partition/auto_generated/load_info_tfm_example_partition.c
 )
 
 target_include_directories(tfm_app_rot_partition_example
     PRIVATE
-        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+        ${CMAKE_CURRENT_SOURCE_DIR}
     PUBLIC
-        ${CMAKE_BINARY_DIR}/generated/secure_fw/partitions/example_partition
+        ${CMAKE_BINARY_DIR}/generated/example_partition
 )
 
 target_link_libraries(tfm_app_rot_partition_example
     PRIVATE
         tfm_secure_api
         psa_interface
-        platform_s
         tfm_sprt
 )
 
 ############################ Secure API ########################################
 
-target_sources(tfm_secure_api
+target_sources(tfm_sprt
     INTERFACE
-        ${CMAKE_CURRENT_SOURCE_DIR}/tfm_example_partition_secure_api.c
+        ${CMAKE_CURRENT_SOURCE_DIR}/tfm_example_partition_api.c
+)
+
+target_include_directories(tfm_sprt
+    PUBLIC
+        .
 )
 
 # The veneers give warnings about not being properly declared so they get hidden
 # to not overshadow _real_ warnings.
-set_source_files_properties(tfm_example_partition_secure_api.c
+set_source_files_properties(tfm_example_partition_api.c
     PROPERTIES
         COMPILE_FLAGS -Wno-implicit-function-declaration
 )
diff --git a/examples/example_partition/README.rst b/examples/example_partition/README.rst
new file mode 100644
index 0000000..de9fcd7
--- /dev/null
+++ b/examples/example_partition/README.rst
@@ -0,0 +1,150 @@
+######################
+TF-M Example Partition
+######################
+The TF-M example partition is a simple Secure Partition implementation provided
+to aid development of new Secure Partitions.
+
+It is an Application RoT, SFN model Secure Partition and implements an
+connection-based RoT Service.
+
+Please refer to `PSA Firmware Framework 1.0`_
+and `Firmware Framework for M 1.1 Extensions`_
+for details of the attributes of Secure Partitions.
+
+Please refer to `Adding Secure Partition`_
+for more details of adding a new Secure Partition to TF-M.
+
+**************
+File structure
+**************
+
+.. code-block:: bash
+
+   .
+   ├── CMakeLists.txt
+   ├── README.rst
+   ├── tfm_example_manifest_list.yaml
+   ├── tfm_example_partition_api.c
+   ├── tfm_example_partition_api.h
+   ├── tfm_example_partition.c
+   └── tfm_example_partition.yaml
+
+- ``CMakeLists.txt``
+
+  The CMake file for building this example Secure Partitions.
+  It is specific to the TF-M build system.
+
+- ``README.rst``
+
+  This document.
+
+- ``tfm_example_partition.yaml``
+
+  The manifest of this Secure Partition.
+
+- ``tfm_example_manifest_list.yaml``
+
+  The manifest list that describes the Secure Partition manifest of this Secure
+  Partition. See `TF-M Manifest List`_ for details of manifest lists.
+
+- ``tfm_example_partition.c``
+
+  The core implementation of this Secure Partition.
+
+- ``tfm_example_partition_api.c``
+
+  The APIs for accessing the RoT Services provided by this Secure Partition.
+
+- ``tfm_example_partition_api.h``
+
+  The header file that declares the RoT Services APIs.
+
+************
+How to Build
+************
+It is recommended to build this example Secure Partition via out-of-tree build.
+It can minimize the changes to TF-M source code for building and testing the
+example.
+
+To build, append the following extra build configurations to the CMake build
+commands.
+
+- ``-DTFM_PARTITION_EXAMPLE``
+
+  This is the configuration switch to enable or disable building this example.
+  Set to ``ON`` to enable or ``OFF`` to disable.
+
+- ``-DTFM_EXTRA_PARTITION_PATHS``
+
+  Set it to the absolute path of this directory.
+
+- ``-DTFM_EXTRA_MANIFEST_LIST_FILES``
+
+  Set it to the absolute path of the manifest list mentioned above -
+  ``tfm_example_manifest_list.yaml``.
+
+Refer to `Out-of-tree Secure Partition build`_ for more details.
+
+***********
+How to Test
+***********
+To test the RoT Services, you need to build the APIs and call the service APIs
+somewhere.
+
+If you want to add comprehensive tests using the TF-M test framework, please
+refer to `Adding TF-M Regression Test Suite`_.
+
+Testing in NSPE
+===============
+Any NSPE can be used to test the example RoT services.
+If you are using the tf-m-tests repo as NSPE, you can:
+
+- Add the ``tfm_example_partition_api.c`` to ``tfm_ns_api`` CMake library.
+- Add the current directory in the include directory of ``tfm_ns_api``.
+- Call the services APIs in the ``test_app`` function.
+
+Testing in SPE
+==============
+
+Testing in SPE is to test requesting the RoT Services in any Secure Partition.
+
+- Add the example services to the ``dependencies`` attribute in the target
+  Secure Partition's manifest.
+- Call the services APIs somewhere in the Secure Partition, for example, in the
+  entry function.
+
+Note that the API source file has already been added in the ``CMakeLists.txt``.
+There are no extra steps to build the APIs for testing in SPE.
+
+**********
+References
+**********
+
+| `PSA Firmware Framework 1.0`_
+| `Firmware Framework for M 1.1 Extensions`_
+| `Adding Secure Partition`_
+| `TF-M Manifest List`_
+| `Out-of-tree Secure Partition build`_
+| `Adding TF-M Regression Test Suite`_
+
+.. _PSA Firmware Framework 1.0:
+  https://developer.arm.com/-/media/Files/pdf/PlatformSecurityArchitecture/Architect/DEN0063-PSA_Firmware_Framework-1.0.0-2.pdf?revision=2d1429fa-4b5b-461a-a60e-4ef3d8f7f4b4
+
+.. _Firmware Framework for M 1.1 Extensions:
+  https://documentation-service.arm.com/static/600067c09b9c2d1bb22cd1c5?token=
+
+.. _Adding Secure Partition:
+  https://tf-m-user-guide.trustedfirmware.org/integration_guide/services/tfm_secure_partition_addition.html
+
+.. _TF-M Manifest List:
+  https://tf-m-user-guide.trustedfirmware.org/integration_guide/services/tfm_manifest_tool_user_guide.html#manifest-list
+
+.. _Out-of-tree Secure Partition build:
+  https://tf-m-user-guide.trustedfirmware.org/integration_guide/services/tfm_secure_partition_addition.html#out-of-tree-secure-partition-build
+
+.. _Adding TF-M Regression Test Suite:
+  https://git.trustedfirmware.org/TF-M/tf-m-tests.git/tree/docs/tfm_test_suites_addition.rst
+
+--------------
+
+*Copyright (c) 2020-2022, Arm Limited. All rights reserved.*
diff --git a/examples/example_partition/tfm_example_manifest_list.yaml b/examples/example_partition/tfm_example_manifest_list.yaml
new file mode 100644
index 0000000..11c570c
--- /dev/null
+++ b/examples/example_partition/tfm_example_manifest_list.yaml
@@ -0,0 +1,22 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+{
+  "manifest_list": [
+    {
+      "name": "TF-M Example Partition",
+      "manifest": "tfm_example_partition.yaml",
+      "output_path": "example_partition",
+      "conditional": "TFM_PARTITION_EXAMPLE",
+      "linker_pattern": {
+          "library_list": [
+            "*tfm_*partition_example.*"
+        ]
+      }
+    }
+  ]
+}
diff --git a/examples/example_partition/tfm_example_partition.c b/examples/example_partition/tfm_example_partition.c
index 7a1eeb4..d9c9cf3 100644
--- a/examples/example_partition/tfm_example_partition.c
+++ b/examples/example_partition/tfm_example_partition.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -9,51 +9,37 @@
 
 #include "psa/service.h"
 #include "psa_manifest/tfm_example_partition.h"
-#include "tfm/tfm_spm_services.h"
-#include "tfm_plat_test.h"
 #include "tfm_sp_log.h"
 
 /**
  * \brief An example service implementation that prints out an argument from the
  *        client and then starts a timer.
  */
-static void tfm_example_service(void)
+psa_status_t tfm_example_service_sfn(const psa_msg_t *msg)
 {
     psa_status_t status;
     uint32_t arg;
-    psa_msg_t msg;
-
-    /* Retrieve the message corresponding to the example service signal */
-    status = psa_get(TFM_EXAMPLE_SERVICE_SIGNAL, &msg);
-    if (status != PSA_SUCCESS) {
-        return;
-    }
 
     /* Decode the message */
-    switch (msg.type) {
+    switch (msg->type) {
     case PSA_IPC_CONNECT:
     case PSA_IPC_DISCONNECT:
-        /* This service does not require any setup or teardown on connect or
+        /*
+         * This service does not require any setup or teardown on connect or
          * disconnect, so just reply with success.
          */
         status = PSA_SUCCESS;
         break;
     case PSA_IPC_CALL:
-        if (msg.in_size[0] != sizeof(arg)) {
+        if (msg->in_size[0] != sizeof(arg)) {
             status = PSA_ERROR_PROGRAMMER_ERROR;
             break;
         }
 
         /* Print arg from client */
-        psa_read(msg.handle, 0, &arg, sizeof(arg));
+        psa_read(msg->handle, 0, &arg, sizeof(arg));
         LOG_INFFMT("[Example partition] Service called! arg=%p\r\n", arg);
 
-        /* Start timer. The interrupt triggered when it expires will be handled
-         * by tfm_example_timer_handler().
-         */
-        tfm_plat_test_secure_timer_start();
-        LOG_INFFMT("[Example partition] Timer started...\r\n");
-
         status = PSA_SUCCESS;
         break;
     default:
@@ -62,42 +48,15 @@
         break;
     }
 
-    /* Reply with the message result status to unblock the client */
-    psa_reply(msg.handle, status);
-}
-
-/**
- * \brief An example interrupt handler.
- */
-static void tfm_example_timer_handler(void)
-{
-    /* Stop timer */
-    tfm_plat_test_secure_timer_stop();
-    /* Inform the SPM that the timer interrupt has been handled */
-    psa_eoi(TFM_EXAMPLE_SIGNAL_TIMER_0_IRQ);
+    return status;
 }
 
 /**
  * \brief The example partition's entry function.
  */
-void tfm_example_partition_main(void)
+psa_status_t tfm_example_partition_main(void)
 {
-    psa_signal_t signals;
+    LOG_INFFMT("Example Partition initializing\r\n");
 
-    /* Enable timer IRQ */
-    psa_irq_enable(TFM_EXAMPLE_SIGNAL_TIMER_0_IRQ);
-
-    /* Continually wait for one or more of the partition's RoT Service or
-     * interrupt signals to be asserted and then handle the asserted signal(s).
-     */
-    while (1) {
-        signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
-
-        if (signals & TFM_EXAMPLE_SERVICE_SIGNAL) {
-            tfm_example_service();
-        }
-        if (signals & TFM_EXAMPLE_SIGNAL_TIMER_0_IRQ) {
-            tfm_example_timer_handler();
-        }
-    }
+    return PSA_SUCCESS;
 }
diff --git a/examples/example_partition/tfm_example_partition.yaml b/examples/example_partition/tfm_example_partition.yaml
index 26be598..255708e 100644
--- a/examples/example_partition/tfm_example_partition.yaml
+++ b/examples/example_partition/tfm_example_partition.yaml
@@ -1,39 +1,28 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
 
 {
-  "psa_framework_version": 1.0,
+  "psa_framework_version": 1.1,
   "name": "TFM_SP_EXAMPLE",
   "type": "APPLICATION-ROT",
+  "model": "SFN",
   "priority": "NORMAL",
   "entry_point": "tfm_example_partition_main",
   "stack_size": "0x200",
-  "mmio_regions": [
-    {
-      "name": "TFM_PERIPHERAL_TIMER0",
-      "permission": "READ-WRITE"
-    }
-  ],
   "services": [
     {
       "name": "TFM_EXAMPLE_SERVICE",
       # SIDs must be unique, ones that are currently in use are documented in
-      # tfm_secure_partition_addition.rst on line 184
+      # tfm_secure_partition_addition.rst
       "sid": "0x00001000",
+      "connection_based": true,
       "non_secure_clients": true,
       "version": 1,
       "version_policy": "STRICT"
     }
   ],
-  "irqs": [
-    {
-      "source": "TFM_TIMER0_IRQ",
-      "signal": "TFM_EXAMPLE_SIGNAL_TIMER_0_IRQ",
-      "tfm_irq_priority": 64,
-    }
-  ],
 }
diff --git a/examples/example_partition/tfm_example_partition_api.c b/examples/example_partition/tfm_example_partition_api.c
index 5e83cd5..e1af4b6 100644
--- a/examples/example_partition/tfm_example_partition_api.c
+++ b/examples/example_partition/tfm_example_partition_api.c
@@ -10,7 +10,7 @@
 #include "psa/client.h"
 #include "psa_manifest/sid.h"
 
-psa_status_t tfm_example_partition_call(uint32_t arg)
+psa_status_t tfm_example_service(uint32_t arg)
 {
     psa_status_t status;
     psa_handle_t handle;
@@ -23,7 +23,7 @@
         return PSA_HANDLE_TO_ERROR(handle);
     }
 
-    status = psa_call(handle, PSA_IPC_CALL, in_vec, 1, NULL, 0);
+    status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), NULL, 0);
 
     psa_close(handle);
 
diff --git a/examples/example_partition/tfm_example_partition_api.h b/examples/example_partition/tfm_example_partition_api.h
index f8876ef..2c7be55 100644
--- a/examples/example_partition/tfm_example_partition_api.h
+++ b/examples/example_partition/tfm_example_partition_api.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -17,13 +17,13 @@
 #endif
 
 /**
- * \brief Makes a psa_call to the example partition.
+ * \brief Makes a request to the example service.
  *
  * \param[in] arg  Example parameter
  *
  * \return Returns error code as specified in \ref psa_status_t
  */
-psa_status_t tfm_example_partition_call(uint32_t arg);
+psa_status_t tfm_example_service(uint32_t arg);
 
 #ifdef __cplusplus
 }
diff --git a/examples/example_partition/tfm_example_partition_readme.rst b/examples/example_partition/tfm_example_partition_readme.rst
deleted file mode 100644
index 416ee7f..0000000
--- a/examples/example_partition/tfm_example_partition_readme.rst
+++ /dev/null
@@ -1,44 +0,0 @@
-###############################
-TF-M Example Partition - Readme
-###############################
-The TF-M example partition is a simple secure partition implementation provided
-to aid development of new secure partitions. It implements one App RoT Service
-and one interrupt handler.
-
-********************************
-How to run the example partition
-********************************
-#. Copy the ``example_partition`` directory to the ``secure_fw/partitions``
-   directory of the TF-M repo.
-
-#. Add the partition to the TF-M CMake by inserting
-   ``add_subdirectory(partitions/example_partition)`` in
-   ``secure_fw/CMakeLists.txt``, in the block below the line
-   ``add_subdirectory(partitions/lib/sprt)``.
-
-#. Add the following entry to ``tools/tfm_manifest_list.yaml``. The ``pid``
-   field must be unique (currently used partition ids are documented in
-   tfm_secure_partition_addition.rst on line 150), or can omitted which will
-   allocate one automatically. ::
-
-    {
-      "name": "TF-M Example Partition",
-      "short_name": "TFM_SP_EXAMPLE",
-      "manifest": "secure_fw/partitions/example_partition/tfm_example_partition.yaml",
-      "conditional": "TFM_PARTITION_EXAMPLE",
-      "version_major": 0,
-      "version_minor": 1,
-      "pid": 356,
-      "linker_pattern": {
-        "library_list": [
-           "*tfm_*partition_example.*"
-        ]
-      }
-    }
-
-#. Build TF-M in the usual way, but provide ``-DTFM_PARTITION_EXAMPLE=ON`` as a
-   parameter to the CMake command.
-
---------------
-
-*Copyright (c) 2020-2021, Arm Limited. All rights reserved.*
diff --git a/examples/example_partition/tfm_example_partition_secure_api.c b/examples/example_partition/tfm_example_partition_secure_api.c
deleted file mode 100644
index 0a958c2..0000000
--- a/examples/example_partition/tfm_example_partition_secure_api.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#include "tfm_example_partition_api.h"
-
-#include "psa/client.h"
-#include "psa_manifest/sid.h"
-
-__attribute__((section("SFN")))
-psa_status_t tfm_example_partition_call(uint32_t arg)
-{
-    psa_status_t status;
-    psa_handle_t handle;
-    psa_invec in_vec[] = {
-        { .base = &arg, .len = sizeof(arg) },
-    };
-
-    handle = psa_connect(TFM_EXAMPLE_SERVICE_SID, TFM_EXAMPLE_SERVICE_VERSION);
-    if (!PSA_HANDLE_IS_VALID(handle)) {
-        return PSA_HANDLE_TO_ERROR(handle);
-    }
-
-    status = psa_call(handle, PSA_IPC_CALL, in_vec, 1, NULL, 0);
-
-    psa_close(handle);
-
-    return status;
-}