SPM: Add idle Partition for single core topology
This patch adds an idle Partition. When all other Partitions are
waiting for signals, this Partition will be scheduled and it simply
waits for interrupts.
Note: Multi-core topology has already the idle thread.
Change-Id: I862eaccb33f4f119fc75a75cd25dc0ddc7869554
Signed-off-by: Kevin Peng <kevin.peng@arm.com>
diff --git a/secure_fw/CMakeLists.txt b/secure_fw/CMakeLists.txt
index f75af4e..bf8d21a 100644
--- a/secure_fw/CMakeLists.txt
+++ b/secure_fw/CMakeLists.txt
@@ -18,6 +18,7 @@
# directories of the partitions
add_library(tfm_partition_defs INTERFACE)
+add_subdirectory(spm)
add_subdirectory(partitions/lib/sprt)
add_subdirectory(partitions/audit_logging)
add_subdirectory(partitions/crypto)
@@ -29,7 +30,7 @@
add_subdirectory(partitions/firmware_update)
add_subdirectory(partitions/tfm_ffm11_partition)
add_subdirectory(partitions/ns_proxy_partition)
-add_subdirectory(spm)
+add_subdirectory(partitions/idle_partition)
target_include_directories(secure_fw
INTERFACE
diff --git a/secure_fw/partitions/idle_partition/CMakeLists.txt b/secure_fw/partitions/idle_partition/CMakeLists.txt
new file mode 100644
index 0000000..326d057
--- /dev/null
+++ b/secure_fw/partitions/idle_partition/CMakeLists.txt
@@ -0,0 +1,23 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+if (NOT TFM_PSA_API OR TFM_MULTI_CORE_TOPOLOGY)
+ return()
+endif()
+
+cmake_minimum_required(VERSION 3.15)
+cmake_policy(SET CMP0079 NEW)
+
+target_sources(tfm_spm
+ PRIVATE
+ idle_partition.c
+)
+
+target_sources(tfm_partitions
+ INTERFACE
+ ${CMAKE_CURRENT_SOURCE_DIR}/load_info_idle_sp.c
+)
diff --git a/secure_fw/partitions/idle_partition/idle_partition.c b/secure_fw/partitions/idle_partition/idle_partition.c
new file mode 100644
index 0000000..e2725b4
--- /dev/null
+++ b/secure_fw/partitions/idle_partition/idle_partition.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cmsis.h"
+#include "fih.h"
+
+void tfm_idle_thread(void)
+{
+ while (1) {
+ __WFI();
+ }
+
+#ifdef TFM_FIH_PROFILE_ON
+ fih_delay();
+
+ while (1) {
+ __WFI();
+ }
+#endif
+}
diff --git a/secure_fw/partitions/idle_partition/load_info_idle_sp.c b/secure_fw/partitions/idle_partition/load_info_idle_sp.c
new file mode 100644
index 0000000..b59bb7e
--- /dev/null
+++ b/secure_fw/partitions/idle_partition/load_info_idle_sp.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include "spm_ipc.h"
+#include "spm_partition_defs.h"
+#include "load/partition_defs.h"
+#include "load/service_defs.h"
+#include "load/asset_defs.h"
+
+#define IDLE_SP_STACK_SIZE (0x50)
+
+struct partition_tfm_sp_idle_load_info_t {
+ /* common length load data */
+ struct partition_load_info_t load_info;
+ /* per-partition variable length load data */
+ uintptr_t stack_addr;
+ uintptr_t heap_addr;
+} __attribute__((aligned(4)));
+
+/* Entrypoint function declaration */
+extern void tfm_idle_thread(void);
+/* Stack */
+uint8_t idle_sp_stack[IDLE_SP_STACK_SIZE] __attribute__((aligned(8)));
+
+/* Partition load, deps, service load data. Put to a dedicated section. */
+const struct partition_tfm_sp_idle_load_info_t
+ tfm_sp_idle_load __attribute__((used, section(".part_load"))) = {
+ .load_info = {
+ .psa_ff_ver = 0x0101 | PARTITION_INFO_MAGIC,
+ .pid = TFM_SP_IDLE_ID,
+ .flags = PARTITION_PRI_LOWEST | SPM_PART_FLAG_IPC
+ | SPM_PART_FLAG_PSA_ROT,
+ .entry = ENTRY_TO_POSITION(tfm_idle_thread),
+ .stack_size = IDLE_SP_STACK_SIZE,
+ .heap_size = 0,
+ .ndeps = 0,
+ .nservices = 0,
+ .nassets = 0,
+ },
+ .stack_addr = (uintptr_t)idle_sp_stack,
+ .heap_addr = 0,
+};
+
+/* Placeholder for partition runtime space. Do not reference it. */
+static struct partition_t tfm_idle_partition_runtime_item
+ __attribute__((used, section(".bss.part_runtime")));
diff --git a/secure_fw/partitions/ns_proxy_partition/load_info_ns_proxy.c b/secure_fw/partitions/ns_proxy_partition/load_info_ns_proxy.c
index 6f5fcc0..85e6387 100644
--- a/secure_fw/partitions/ns_proxy_partition/load_info_ns_proxy.c
+++ b/secure_fw/partitions/ns_proxy_partition/load_info_ns_proxy.c
@@ -16,8 +16,6 @@
#include "load/partition_defs.h"
#include "load/service_defs.h"
#include "load/asset_defs.h"
-#include "psa_manifest/pid.h"
-#include "psa_manifest/sid.h"
#define TFM_SP_NS_PROXY_NDEPS (0)
#define TFM_SP_NS_PROXY_NSERVS (0)
@@ -49,7 +47,8 @@
.load_info = {
.psa_ff_ver = 0x0100 | PARTITION_INFO_MAGIC,
.pid = TFM_SP_NON_SECURE_ID,
- .flags = PARTITION_PRI_LOWEST | SPM_PART_FLAG_IPC
+ .flags = (PARTITION_PRI_LOWEST - 1)
+ | SPM_PART_FLAG_IPC
#if TFM_MULTI_CORE_TOPOLOGY
| SPM_PART_FLAG_PSA_ROT
#endif
@@ -63,13 +62,16 @@
.nassets = TFM_SP_NS_PROXY_NASSETS,
#endif
},
- .stack_addr = PART_REGION_ADDR(ARM_LIB_STACK, $$ZI$$Base),
+ .stack_addr = PART_REGION_ADDR(ARM_LIB_STACK,
+ $$ZI$$Base),
.heap_addr = 0,
#if TFM_LVL == 3
.assets = {
{
- .mem.addr_x = PART_REGION_ADDR(ARM_LIB_STACK, $$ZI$$Base),
- .mem.addr_y = PART_REGION_ADDR(ARM_LIB_STACK, $$ZI$$Limit),
+ .mem.addr_x = PART_REGION_ADDR(ARM_LIB_STACK,
+ $$ZI$$Base),
+ .mem.addr_y = PART_REGION_ADDR(ARM_LIB_STACK,
+ $$ZI$$Limit),
.attr = ASSET_MEM_RD_BIT | ASSET_MEM_WR_BIT,
},
},
diff --git a/secure_fw/spm/include/spm_partition_defs.h b/secure_fw/spm/include/spm_partition_defs.h
index 07f224e..c811cb6 100644
--- a/secure_fw/spm/include/spm_partition_defs.h
+++ b/secure_fw/spm/include/spm_partition_defs.h
@@ -24,6 +24,7 @@
* operations.
*/
#define TFM_SP_NON_SECURE_ID (0)
+#define TFM_SP_IDLE_ID (1)
/* A dummy partition for TFM_SP_CORE is created to handle secure partition
* calls done directly from the core, before NS execution started.
*/