Add example_partition from tf-m-tools
Signed-off-by: Anton Komlev <anton.komlev@arm.com>
Change-Id: I29baec63c1ea8e06457b92a6277fc5f2fa9ec335
diff --git a/examples/example_partition/CMakeLists.txt b/examples/example_partition/CMakeLists.txt
new file mode 100644
index 0000000..0aabff2
--- /dev/null
+++ b/examples/example_partition/CMakeLists.txt
@@ -0,0 +1,74 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+if (NOT TFM_PARTITION_EXAMPLE)
+ return()
+endif()
+
+cmake_minimum_required(VERSION 3.15)
+cmake_policy(SET CMP0079 NEW)
+
+# The name of the target is required to be of the pattern
+# tfm_app_rot_partition_x or tfm_psa_rot_partition_x, as it affects how the
+# 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>
+)
+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>
+)
+
+target_include_directories(tfm_app_rot_partition_example
+ PRIVATE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+ PUBLIC
+ ${CMAKE_BINARY_DIR}/generated/secure_fw/partitions/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
+ INTERFACE
+ ${CMAKE_CURRENT_SOURCE_DIR}/tfm_example_partition_secure_api.c
+)
+
+# 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
+ PROPERTIES
+ COMPILE_FLAGS -Wno-implicit-function-declaration
+)
+
+############################ Partition Defs ####################################
+
+target_link_libraries(tfm_partitions
+ INTERFACE
+ tfm_app_rot_partition_example
+)
+
+target_compile_definitions(tfm_partition_defs
+ INTERFACE
+ TFM_PARTITION_EXAMPLE
+)
diff --git a/examples/example_partition/tfm_example_partition.c b/examples/example_partition/tfm_example_partition.c
new file mode 100644
index 0000000..7a1eeb4
--- /dev/null
+++ b/examples/example_partition/tfm_example_partition.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+
+#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 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) {
+ case PSA_IPC_CONNECT:
+ case PSA_IPC_DISCONNECT:
+ /* 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)) {
+ status = PSA_ERROR_PROGRAMMER_ERROR;
+ break;
+ }
+
+ /* Print arg from client */
+ 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:
+ /* Invalid message type */
+ status = PSA_ERROR_PROGRAMMER_ERROR;
+ 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);
+}
+
+/**
+ * \brief The example partition's entry function.
+ */
+void tfm_example_partition_main(void)
+{
+ psa_signal_t signals;
+
+ /* 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();
+ }
+ }
+}
diff --git a/examples/example_partition/tfm_example_partition.yaml b/examples/example_partition/tfm_example_partition.yaml
new file mode 100644
index 0000000..26be598
--- /dev/null
+++ b/examples/example_partition/tfm_example_partition.yaml
@@ -0,0 +1,39 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+{
+ "psa_framework_version": 1.0,
+ "name": "TFM_SP_EXAMPLE",
+ "type": "APPLICATION-ROT",
+ "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
+ "sid": "0x00001000",
+ "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
new file mode 100644
index 0000000..5e83cd5
--- /dev/null
+++ b/examples/example_partition/tfm_example_partition_api.c
@@ -0,0 +1,31 @@
+/*
+ * 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"
+
+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;
+}
diff --git a/examples/example_partition/tfm_example_partition_api.h b/examples/example_partition/tfm_example_partition_api.h
new file mode 100644
index 0000000..f8876ef
--- /dev/null
+++ b/examples/example_partition/tfm_example_partition_api.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_EXAMPLE_PARTITION_API_H__
+#define __TFM_EXAMPLE_PARTITION_API_H__
+
+#include <stdint.h>
+
+#include "psa/error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Makes a psa_call to the example partition.
+ *
+ * \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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_EXAMPLE_PARTITION_API_H__ */
diff --git a/examples/example_partition/tfm_example_partition_readme.rst b/examples/example_partition/tfm_example_partition_readme.rst
new file mode 100644
index 0000000..416ee7f
--- /dev/null
+++ b/examples/example_partition/tfm_example_partition_readme.rst
@@ -0,0 +1,44 @@
+###############################
+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
new file mode 100644
index 0000000..0a958c2
--- /dev/null
+++ b/examples/example_partition/tfm_example_partition_secure_api.c
@@ -0,0 +1,32 @@
+/*
+ * 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;
+}
diff --git a/examples/examples_readme.rst b/examples/examples_readme.rst
index c36c6d6..9b7faac 100755
--- a/examples/examples_readme.rst
+++ b/examples/examples_readme.rst
@@ -29,6 +29,17 @@
-----------
Jianliang Shen `<jianliang.shen@arm.com> <jianliang.shen@arm.com>`_
+example_partition
+=================
+
+Description
+-----------
+A simple secure partition implementation.
+
+Maintainers
+-----------
+Jianliang Shen `<jianliang.shen@arm.com> <jianliang.shen@arm.com>`_
+
---------------------------
*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*