SPM: Common partition runtime entry point
Involve the common partition runtime entry point to perform generic
runtime initialization jobs such as heap initialization before the
practical partition entry point get called. This entry point is part
of SPRTL which is shared for all partitions.
This patch involves the 'sprt_main' as the first step. And, if one
partition is light enough (no heap, no other extra settings), it is
optional to apply the common partition runtime entry as partition
first entry, and the real partition entry is put under 'sub_entry'.
This patch also fixes region address alignments in link scripts.
Change-Id: I9169f6377d476a3e1dad025c75a790aba6b6ad10
Signed-off-by: Summer Qin <summer.qin@arm.com>
Co-authored-by: Kevin Peng <kevin.peng@arm.com>
diff --git a/config/tfm_ipc_config_default.cmake b/config/tfm_ipc_config_default.cmake
index 82847d0..e1f9b93 100644
--- a/config/tfm_ipc_config_default.cmake
+++ b/config/tfm_ipc_config_default.cmake
@@ -10,4 +10,4 @@
set(TFM_PSA_API ON CACHE BOOL "Use PSA API instead of secure library model")
set(CONFIG_TFM_SPM_BACKEND_IPC ON)
set(CONFIG_TFM_SPM_BACKEND_SFN OFF)
-set(CONFIG_TFM_PARTITION_META OFF)
+set(CONFIG_TFM_PARTITION_META ON)
diff --git a/platform/ext/common/gcc/tfm_common_s.ld b/platform/ext/common/gcc/tfm_common_s.ld
index 425e1f0..9d40da2 100644
--- a/platform/ext/common/gcc/tfm_common_s.ld
+++ b/platform/ext/common/gcc/tfm_common_s.ld
@@ -314,6 +314,7 @@
#endif
/**** APPLICATION RoT DATA start here */
+ . = ALIGN(32);
Image$$TFM_APP_RW_STACK_START$$Base = .;
.TFM_APP_ROT_LINKER_DATA : ALIGN(32)
diff --git a/platform/ext/target/nordic_nrf/common/core/gcc/nordic_nrf_s.ld b/platform/ext/target/nordic_nrf/common/core/gcc/nordic_nrf_s.ld
index accc5d0..255267e 100644
--- a/platform/ext/target/nordic_nrf/common/core/gcc/nordic_nrf_s.ld
+++ b/platform/ext/target/nordic_nrf/common/core/gcc/nordic_nrf_s.ld
@@ -407,6 +407,7 @@
#endif
/**** APPLICATION RoT DATA start here */
+ . = ALIGN(32);
Image$$TFM_APP_RW_STACK_START$$Base = .;
.TFM_APP_ROT_LINKER_DATA : ALIGN(32)
diff --git a/platform/ext/target/stm/common/stm32u5xx/Device/Source/gcc/tfm_common_s.ld b/platform/ext/target/stm/common/stm32u5xx/Device/Source/gcc/tfm_common_s.ld
index d4625a2..404172d 100644
--- a/platform/ext/target/stm/common/stm32u5xx/Device/Source/gcc/tfm_common_s.ld
+++ b/platform/ext/target/stm/common/stm32u5xx/Device/Source/gcc/tfm_common_s.ld
@@ -175,7 +175,7 @@
Image$$TFM_SP_META_PTR$$ZI$$Base = ADDR(.TFM_SP_META_PTR);
Image$$TFM_SP_META_PTR$$ZI$$Limit = ADDR(.TFM_SP_META_PTR) + SIZEOF(.TFM_SP_META_PTR);
#endif
- .dummy_empty :
+ .dummy_empty : ALIGH(32)
{
. += 0x0;
} > RAM
@@ -206,14 +206,7 @@
/**** APPLICATION RoT DATA end here */
Image$$TFM_APP_RW_STACK_END$$Base = .;
-#if defined(TFM_SP_META_PTR_ENABLE)
- .TFM_SP_META_PTR : ALIGN(32)
- {
- *(SP_META_PTR_SPRTL_INST)
- } > RAM
- Image$$TFM_SP_META_PTR$$RW$$Base = ADDR(.TFM_SP_META_PTR);
- Image$$TFM_SP_META_PTR$$RW$$Limit = ADDR(.TFM_SP_META_PTR) + SIZEOF(.TFM_SP_META_PTR);
-#endif
+
#ifdef CODE_SHARING
/* The code sharing between bootloader and runtime requires to share the
* global variables.
diff --git a/secure_fw/partitions/lib/sprt/CMakeLists.txt b/secure_fw/partitions/lib/sprt/CMakeLists.txt
index a76bd05..f81f47c 100644
--- a/secure_fw/partitions/lib/sprt/CMakeLists.txt
+++ b/secure_fw/partitions/lib/sprt/CMakeLists.txt
@@ -24,6 +24,7 @@
./crt_strnlen.c
./service_api.c
$<$<BOOL:${CONFIG_TFM_PARTITION_META}>:./sprt_partition_metadata_indicator.c>
+ $<$<BOOL:${CONFIG_TFM_PARTITION_META}>:./sprt_main.c>
)
target_link_libraries(tfm_sprt
@@ -40,6 +41,11 @@
$<$<BOOL:${TFM_SP_LOG_RAW_ENABLED}>:TFM_SP_LOG_RAW_ENABLED>
)
+target_include_directories(tfm_partitions
+ INTERFACE
+ $<BUILD_INTERFACE:$<$<BOOL:${CONFIG_TFM_PARTITION_META}>:${CMAKE_CURRENT_SOURCE_DIR}/include>>
+)
+
# Create a dedicated tfm_sp_log_raw library for some regression test modules
# which don't include tfm_sprt.
# tfm_sp_log_raw shall be controlled by TFM_SP_LOG_RAW_ENABLED.
diff --git a/secure_fw/partitions/lib/sprt/include/sprt_main.h b/secure_fw/partitions/lib/sprt/include/sprt_main.h
new file mode 100644
index 0000000..eee88cb
--- /dev/null
+++ b/secure_fw/partitions/lib/sprt/include/sprt_main.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __SPRT_MAIN_H__
+#define __SPRT_MAIN_H__
+
+/* Common partition runtime entry - 'sprt_main' */
+void sprt_main(void);
+
+#endif /* __SPRT_MAIN_H__ */
diff --git a/secure_fw/partitions/lib/sprt/sprt_main.c b/secure_fw/partitions/lib/sprt/sprt_main.c
new file mode 100644
index 0000000..7ca6039
--- /dev/null
+++ b/secure_fw/partitions/lib/sprt/sprt_main.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "compiler_ext_defs.h"
+#include "runtime_defs.h"
+#include "sprt_partition_metadata_indicator.h"
+#include "sprt_main.h"
+
+#if defined(__ICCARM__)
+#pragma required = meta_init_c
+#endif
+
+__used static uintptr_t runtime_init_c(void)
+{
+ return PART_METADATA()->entry;
+}
+
+__naked void sprt_main(void)
+{
+ __asm volatile(
+#if !defined(__ICCARM__)
+ ".syntax unified \n"
+#endif
+ "bl runtime_init_c \n"
+ "bx r0 \n"
+ );
+}
diff --git a/secure_fw/partitions/lib/sprt/sprt_partition_metadata_indicator.c b/secure_fw/partitions/lib/sprt/sprt_partition_metadata_indicator.c
index 62e914f..8f1aaee 100644
--- a/secure_fw/partitions/lib/sprt/sprt_partition_metadata_indicator.c
+++ b/secure_fw/partitions/lib/sprt/sprt_partition_metadata_indicator.c
@@ -7,5 +7,9 @@
#include <stdint.h>
+/*
+ * The address of Partition metadata, stored in TFM_SP_META_PTR region.
+ * All privilege RW. Gets updated by Scheduler when scheduling.
+ */
__attribute__((section(".bss.SP_META_PTR_SPRTL_INST")))
uintptr_t p_partition_metadata;
diff --git a/secure_fw/partitions/lib/sprt/sprt_partition_metadata_indicator.h b/secure_fw/partitions/lib/sprt/sprt_partition_metadata_indicator.h
new file mode 100644
index 0000000..b2ab390
--- /dev/null
+++ b/secure_fw/partitions/lib/sprt/sprt_partition_metadata_indicator.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __SPRT_PARTITION_METADATA_INDICATOR_H__
+#define __SPRT_PARTITION_METADATA_INDICATOR_H__
+
+#include <stdint.h>
+
+extern uintptr_t p_partition_metadata;
+
+/* Partition Metadata pointer */
+#define PART_METADATA() ((struct runtime_metadata_t *)p_partition_metadata)
+
+#endif /* __SPRT_PARTITION_METADATA_INDICATOR_H__ */
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.c b/secure_fw/spm/cmsis_psa/spm_ipc.c
index a06baec..249973f 100755
--- a/secure_fw/spm/cmsis_psa/spm_ipc.c
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.c
@@ -42,6 +42,9 @@
#include "load/asset_defs.h"
#include "load/spm_load_api.h"
#include "tfm_nspm.h"
+#if defined(CONFIG_TFM_PARTITION_META)
+#include "tfm_hal_memory_symbols.h"
+#endif
#if !(defined CONFIG_TFM_CONN_HANDLE_MAX_NUM) || (CONFIG_TFM_CONN_HANDLE_MAX_NUM == 0)
#error "CONFIG_TFM_CONN_HANDLE_MAX_NUM must be defined and not zero."
@@ -51,6 +54,11 @@
static struct service_head_t services_listhead;
struct service_t *stateless_services_ref_tbl[STATIC_HANDLE_NUM_LIMIT];
+#if defined(CONFIG_TFM_PARTITION_META)
+/* Indicator point to the partition meta */
+static uintptr_t *partition_meta_indicator_pos = NULL;
+#endif
+
/* Pools */
TFM_POOL_DECLARE(conn_handle_pool, sizeof(struct conn_handle_t),
CONFIG_TFM_CONN_HANDLE_MAX_NUM);
@@ -569,6 +577,10 @@
backend_instance.comp_init_assuredly(partition, service_setting);
}
+#if defined(CONFIG_TFM_PARTITION_META)
+ partition_meta_indicator_pos = (uintptr_t *)hal_mem_sp_meta_start;
+#endif
+
return backend_instance.system_run();
}
@@ -615,6 +627,13 @@
CRITICAL_SECTION_LEAVE(cs);
}
+#if defined(CONFIG_TFM_PARTITION_META)
+ /* Update meta indicator */
+ if (partition_meta_indicator_pos && (p_part_next->p_metadata)) {
+ *partition_meta_indicator_pos = (uintptr_t)(p_part_next->p_metadata);
+ }
+#endif
+
return AAPCS_DUAL_U32_AS_U64(ctx_ctrls);
}
diff --git a/secure_fw/spm/ffm/backend_ipc.c b/secure_fw/spm/ffm/backend_ipc.c
index f43cfbc..22a7794 100644
--- a/secure_fw/spm/ffm/backend_ipc.c
+++ b/secure_fw/spm/ffm/backend_ipc.c
@@ -9,6 +9,7 @@
#include <stdint.h>
#include "critical_section.h"
#include "compiler_ext_defs.h"
+#include "runtime_defs.h"
#include "spm_ipc.h"
#include "tfm_hal_isolation.h"
#include "tfm_hal_platform.h"
@@ -41,6 +42,20 @@
#endif
+static void prv_process_metadata(struct partition_t *p_pt)
+{
+ struct runtime_metadata_t *p_rtmd = NULL;
+
+ if (p_pt->p_ldinf->entry) {
+ ARCH_CTXCTRL_ALLOCATE_STACK(&p_pt->ctx_ctrl, sizeof(*p_rtmd));
+ p_rtmd = (struct runtime_metadata_t *)ARCH_CTXCTRL_ALLOCATED_PTR(
+ &p_pt->ctx_ctrl);
+ p_rtmd->entry = p_pt->p_ldinf->entry;
+ }
+
+ p_pt->p_metadata = p_rtmd;
+}
+
/*
* Send message and wake up the SP who is waiting on message queue, block the
* current thread and trigger scheduler.
@@ -101,6 +116,8 @@
return PSA_SUCCESS;
}
+extern void sprt_main(void);
+
/* Parameters are treated as assuredly */
static void ipc_comp_init_assuredly(struct partition_t *p_pt,
uint32_t service_setting)
@@ -120,6 +137,8 @@
LOAD_ALLOCED_STACK_ADDR(p_pldi),
p_pldi->stack_size);
+ prv_process_metadata(p_pt);
+
THRD_INIT(&p_pt->thrd, &p_pt->ctx_ctrl,
TO_THREAD_PRIORITY(PARTITION_PRIORITY(p_pldi->flags)));
@@ -130,7 +149,7 @@
#endif
thrd_start(&p_pt->thrd,
- POSITION_TO_ENTRY(p_pldi->entry, thrd_fn_t),
+ POSITION_TO_ENTRY(sprt_main, thrd_fn_t),
THRD_GENERAL_EXIT);
}
diff --git a/secure_fw/spm/include/interface/runtime_defs.h b/secure_fw/spm/include/interface/runtime_defs.h
new file mode 100644
index 0000000..9c22050
--- /dev/null
+++ b/secure_fw/spm/include/interface/runtime_defs.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __RUNTIME_DEFS_H__
+#define __RUNTIME_DEFS_H__
+
+#include <stdint.h>
+
+struct runtime_metadata_t {
+ uintptr_t entry;
+};
+
+#endif /* __RUNTIME_DEFS_H__ */