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;
-}