aboutsummaryrefslogtreecommitdiff
path: root/secure_fw
diff options
context:
space:
mode:
authorKen Liu <Ken.Liu@arm.com>2021-05-12 16:19:04 +0800
committerMingyang Sun <mingyang.sun@arm.com>2021-05-31 14:35:50 +0800
commitacd2a57beb782bda6d840dcc868923a38f2e0f19 (patch)
treed0899a286411c5d5a5b5a024c2b6fdac666ec842 /secure_fw
parent9c7b9bec77d87a408f9d5594e429667c3c241e68 (diff)
downloadtrusted-firmware-m-acd2a57beb782bda6d840dcc868923a38f2e0f19.tar.gz
SPM: Refine 'load' interfaces
- Partitions need load info assemling MACROs, move them out of 'partition_static_load.h'. - Rename 'partition_static_load.h' into 'spm_load_api.h', and create a static load implementation 'static_load.c'. - Refine the load logic, call API provided in 'spm_load_api.h'. - Service lookup now list based. - Rename 'load info' variable in partition and service runtime defs. Change-Id: I73901094458ff1f11674100f8660eaa44a457d09 Signed-off-by: Ken Liu <Ken.Liu@arm.com>
Diffstat (limited to 'secure_fw')
-rw-r--r--secure_fw/include/compile_check_defs.h2
-rw-r--r--secure_fw/partitions/ns_proxy_partition/load_info_ns_proxy.c9
-rw-r--r--secure_fw/partitions/partition_load_info.template15
-rw-r--r--secure_fw/partitions/tfm_service_list.inc.template2
-rwxr-xr-xsecure_fw/spm/CMakeLists.txt1
-rw-r--r--secure_fw/spm/cmsis_psa/spm_ipc.c194
-rw-r--r--secure_fw/spm/cmsis_psa/spm_ipc.h4
-rw-r--r--secure_fw/spm/cmsis_psa/static_load.c155
-rw-r--r--secure_fw/spm/ffm/psa_client_service_apis.c18
-rw-r--r--secure_fw/spm/ffm/spm_psa_client_call.c4
-rw-r--r--secure_fw/spm/ffm/tfm_boot_data.c2
-rw-r--r--secure_fw/spm/include/load/asset_defs.h3
-rw-r--r--secure_fw/spm/include/load/partition_defs.h5
-rw-r--r--secure_fw/spm/include/load/partition_static_load.h49
-rw-r--r--secure_fw/spm/include/load/service_defs.h3
-rw-r--r--secure_fw/spm/include/load/spm_load_api.h54
16 files changed, 290 insertions, 230 deletions
diff --git a/secure_fw/include/compile_check_defs.h b/secure_fw/include/compile_check_defs.h
index 13a868981..89a94b8a4 100644
--- a/secure_fw/include/compile_check_defs.h
+++ b/secure_fw/include/compile_check_defs.h
@@ -8,7 +8,7 @@
#ifndef __COMPILE_CHECK_DEFS_H__
#define __COMPILE_CHECK_DEFS_H__
-#include "load/partition_static_load.h"
+#include "load/spm_load_api.h"
#include "tfm_thread.h"
#if TO_THREAD_PRIORITY(PARTITION_PRI_HIGHEST) != THRD_PRIOR_HIGHEST || \
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 2a1446779..fed4832dc 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
@@ -12,7 +12,6 @@
#include "region.h"
#include "region_defs.h"
#include "spm_partition_defs.h"
-#include "load/partition_static_load.h"
#include "load/partition_defs.h"
#include "load/service_defs.h"
#include "load/asset_defs.h"
@@ -36,8 +35,8 @@ struct partition_tfm_sp_ns_proxy_load_info_t {
/* common length data */
struct partition_load_info_t cmn_info;
/* per-partition variable length data */
- uintptr_t stack_pos;
- uintptr_t heap_pos;
+ uintptr_t stack_addr;
+ uintptr_t heap_addr;
#if TFM_LVL == 3
struct asset_desc_t assets[TFM_SP_NS_PROXY_NASSETS];
#endif
@@ -63,8 +62,8 @@ const struct partition_tfm_sp_ns_proxy_load_info_t
.nassets = TFM_SP_NS_PROXY_NASSETS,
#endif
},
- .stack_pos = PART_REGION_ADDR(ARM_LIB_STACK, $$ZI$$Base),
- .heap_pos = 0,
+ .stack_addr = PART_REGION_ADDR(ARM_LIB_STACK, $$ZI$$Base),
+ .heap_addr = 0,
#if TFM_LVL == 3
.assets = {
{
diff --git a/secure_fw/partitions/partition_load_info.template b/secure_fw/partitions/partition_load_info.template
index ad005ddda..94e5bed57 100644
--- a/secure_fw/partitions/partition_load_info.template
+++ b/secure_fw/partitions/partition_load_info.template
@@ -10,7 +10,6 @@
#include <stdint.h>
#include <stddef.h>
#include "region.h"
-#include "load/partition_static_load.h"
#include "load/partition_defs.h"
#include "load/service_defs.h"
#include "load/asset_defs.h"
@@ -58,13 +57,13 @@ struct partition_{{manifest.name|lower}}_load_info_t {
/* common length data */
struct partition_load_info_t cmn_info;
/* per-partition variable length data */
- uintptr_t stack_pos;
- uintptr_t heap_pos;
+ uintptr_t stack_addr;
+ uintptr_t heap_addr;
{% if manifest.dependencies %}
uint32_t deps[{{(manifest.name|upper + "_NDEPS")}}];
{% endif %}
{% if manifest.services %}
- struct service_load_info_t services[{{(manifest.name|upper + "_NSERVS")}}];
+ struct service_load_info_t services[{{(manifest.name|upper + "_NSERVS")}}];
{% endif %}
#if TFM_LVL == 3
struct asset_desc_t assets[{{(manifest.name|upper + "_NASSETS")}}];
@@ -106,8 +105,8 @@ const struct partition_{{manifest.name|lower}}_load_info_t {{manifest.name|lower
.nservices = {{(manifest.name|upper + "_NSERVS")}},
.nassets = {{(manifest.name|upper + "_NASSETS")}},
},
- .stack_pos = PTR_TO_POSITION({{manifest.name|lower}}_stack),
- .heap_pos = 0,
+ .stack_addr = (uintptr_t){{manifest.name|lower}}_stack,
+ .heap_addr = 0,
{% if manifest.dependencies %}
.deps = {
{% for dep in manifest.dependencies %}
@@ -155,7 +154,7 @@ const struct partition_{{manifest.name|lower}}_load_info_t {{manifest.name|lower
#ifdef {{region.conditional}}
{% endif %}
{
- .dev.addr_ref = PTR_TO_POSITION({{region.name}}),
+ .dev.addr_ref = PTR_TO_REFERENCE({{region.name}}),
.attr = ASSET_DEV_REF_BIT,
},
{% if region.conditional %}
@@ -171,7 +170,7 @@ const struct partition_{{manifest.name|lower}}_load_info_t {{manifest.name|lower
#ifdef {{region.conditional}}
{% endif %}
{
- .dev.addr_ref = PTR_TO_POSITION({{region.name}}),
+ .dev.addr_ref = PTR_TO_REFERENCE({{region.name}}),
.attr = ASSET_DEV_REF_BIT,
},
{% if region.conditional %}
diff --git a/secure_fw/partitions/tfm_service_list.inc.template b/secure_fw/partitions/tfm_service_list.inc.template
index 386c46347..ac0e74acf 100644
--- a/secure_fw/partitions/tfm_service_list.inc.template
+++ b/secure_fw/partitions/tfm_service_list.inc.template
@@ -31,7 +31,7 @@ struct service_t g_services[] =
/******** {{partition.manifest.name}} ********/
{% for service in partition.manifest.services %}
{{'{'}}
- .service_db = NULL,
+ .p_ldinf = NULL,
.partition = NULL,
.handle_list = {0},
.list = {0},
diff --git a/secure_fw/spm/CMakeLists.txt b/secure_fw/spm/CMakeLists.txt
index fb5571b81..ff7d28d56 100755
--- a/secure_fw/spm/CMakeLists.txt
+++ b/secure_fw/spm/CMakeLists.txt
@@ -45,6 +45,7 @@ target_sources(tfm_spm
$<$<BOOL:${TFM_PSA_API}>:cmsis_psa/arch/tfm_arch.c>
$<$<BOOL:${TFM_PSA_API}>:cmsis_psa/main.c>
$<$<BOOL:${TFM_PSA_API}>:cmsis_psa/spm_ipc.c>
+ $<$<BOOL:${TFM_PSA_API}>:cmsis_psa/static_load.c>
$<$<BOOL:${TFM_PSA_API}>:ffm/spm_psa_client_call.c>
$<$<BOOL:${TFM_PSA_API}>:ffm/psa_client_service_apis.c>
$<$<BOOL:${TFM_PSA_API}>:cmsis_psa/tfm_core_svcalls_ipc.c>
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.c b/secure_fw/spm/cmsis_psa/spm_ipc.c
index 1642626ea..e812d2c9f 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.c
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.c
@@ -28,18 +28,16 @@
#include "tfm_core_trustzone.h"
#include "lists.h"
#include "tfm_pools.h"
-#include "region.h"
-#include "region_defs.h"
#include "spm_partition_defs.h"
#include "psa_manifest/pid.h"
#include "tfm/tfm_spm_services.h"
#include "load/partition_defs.h"
#include "load/service_defs.h"
#include "load/asset_defs.h"
-#include "load/partition_static_load.h"
+#include "load/spm_load_api.h"
-#include "secure_fw/partitions/tfm_service_list.inc"
-#include "tfm_spm_db_ipc.inc"
+extern struct spm_partition_db_t g_spm_partition_db;
+static struct service_t *all_services;
/* Pools */
TFM_POOL_DECLARE(conn_handle_pool, sizeof(struct tfm_conn_handle_t),
@@ -50,10 +48,6 @@ void tfm_set_irq_signal(uint32_t partition_id, psa_signal_t signal,
#include "tfm_secure_irq_handlers_ipc.inc"
-/* Partition static data region */
-REGION_DECLARE(Image$$, TFM_SP_STATIC_LIST, $$RO$$Base);
-REGION_DECLARE(Image$$, TFM_SP_STATIC_LIST, $$RO$$Limit);
-
/*********************** Connection handle conversion APIs *******************/
#define CONVERSION_FACTOR_BITOFFSET 3
@@ -251,9 +245,9 @@ struct tfm_msg_body_t *tfm_spm_get_msg_by_signal(struct partition_t *partition,
*/
BI_LIST_FOR_EACH(node, head) {
tmp_msg = TO_CONTAINER(node, struct tfm_msg_body_t, msg_node);
- if (tmp_msg->service->service_db->signal == signal && msg) {
+ if (tmp_msg->service->p_ldinf->signal == signal && msg) {
return msg;
- } else if (tmp_msg->service->service_db->signal == signal) {
+ } else if (tmp_msg->service->p_ldinf->signal == signal) {
msg = tmp_msg;
BI_LIST_REMOVE_NODE(node);
}
@@ -281,7 +275,7 @@ static uint32_t get_partition_idx(uint32_t partition_id)
}
for (i = 0; i < g_spm_partition_db.partition_count; ++i) {
- if (g_spm_partition_db.partitions[i].p_static->pid == partition_id) {
+ if (g_spm_partition_db.partitions[i].p_ldinf->pid == partition_id) {
return i;
}
}
@@ -299,7 +293,7 @@ static uint32_t get_partition_idx(uint32_t partition_id)
*/
static uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx)
{
- return g_spm_partition_db.partitions[partition_idx].p_static->flags;
+ return g_spm_partition_db.partitions[partition_idx].p_ldinf->flags;
}
#if TFM_LVL != 1
@@ -349,16 +343,16 @@ bool tfm_is_partition_privileged(uint32_t partition_idx)
struct service_t *tfm_spm_get_service_by_sid(uint32_t sid)
{
- uint32_t i, num;
+ struct service_t *p_serv = all_services;
- num = sizeof(g_services) / sizeof(struct service_t);
- for (i = 0; i < num; i++) {
- if (g_services[i].service_db->sid == sid) {
- return &g_services[i];
- }
+ while (p_serv && p_serv->p_ldinf->sid != sid) {
+ p_serv = TO_CONTAINER(BI_LIST_NEXT_NODE(&p_serv->list),
+ struct service_t, list);
+ if (p_serv == all_services)
+ return NULL;
}
- return NULL;
+ return p_serv;
}
/**
@@ -395,14 +389,14 @@ int32_t tfm_spm_check_client_version(struct service_t *service,
{
TFM_CORE_ASSERT(service);
- switch (SERVICE_GET_VERSION_POLICY(service->service_db->flags)) {
+ switch (SERVICE_GET_VERSION_POLICY(service->p_ldinf->flags)) {
case TFM_VERSION_POLICY_RELAXED:
- if (version > service->service_db->version) {
+ if (version > service->p_ldinf->version) {
return SPM_ERROR_VERSION;
}
break;
case TFM_VERSION_POLICY_STRICT:
- if (version != service->service_db->version) {
+ if (version != service->p_ldinf->version) {
return SPM_ERROR_VERSION;
}
break;
@@ -423,7 +417,7 @@ int32_t tfm_spm_check_authorization(uint32_t sid,
TFM_CORE_ASSERT(service);
if (ns_caller) {
- if (!SERVICE_IS_NS_ACCESSIBLE(service->service_db->flags)) {
+ if (!SERVICE_IS_NS_ACCESSIBLE(service->p_ldinf->flags)) {
return SPM_ERROR_GENERIC;
}
} else {
@@ -432,14 +426,14 @@ int32_t tfm_spm_check_authorization(uint32_t sid,
tfm_core_panic();
}
- dep = (uint32_t *)LOAD_INFO_DEPS(partition->p_static);
- for (i = 0; i < partition->p_static->ndeps; i++) {
+ dep = (uint32_t *)LOAD_INFO_DEPS(partition->p_ldinf);
+ for (i = 0; i < partition->p_ldinf->ndeps; i++) {
if (dep[i] == sid) {
break;
}
}
- if (i == partition->p_static->ndeps) {
+ if (i == partition->p_ldinf->ndeps) {
return SPM_ERROR_GENERIC;
}
}
@@ -481,7 +475,7 @@ struct tfm_msg_body_t *tfm_spm_get_msg_from_handle(psa_handle_t msg_handle)
/* Check that the running partition owns the message */
partition_id = tfm_spm_partition_get_running_partition_id();
- if (partition_id != p_msg->service->partition->p_static->pid) {
+ if (partition_id != p_msg->service->partition->p_ldinf->pid) {
return NULL;
}
@@ -560,12 +554,12 @@ void tfm_spm_send_event(struct service_t *service,
struct partition_t *partition = NULL;
psa_signal_t signal = 0;
- if (!msg || !service || !service->service_db || !service->partition) {
+ if (!msg || !service || !service->p_ldinf || !service->partition) {
tfm_core_panic();
}
partition = service->partition;
- signal = service->service_db->signal;
+ signal = service->p_ldinf->signal;
/* Add message to partition message list tail */
BI_LIST_INSERT_BEFORE(&partition->msg_list, &msg->msg_node);
@@ -594,8 +588,8 @@ uint32_t tfm_spm_partition_get_running_partition_id(void)
struct partition_t *partition;
partition = tfm_spm_get_running_partition();
- if (partition && partition->p_static) {
- return partition->p_static->pid;
+ if (partition && partition->p_ldinf) {
+ return partition->p_ldinf->pid;
} else {
return INVALID_PARTITION_ID;
}
@@ -646,59 +640,13 @@ int32_t tfm_memory_check(const void *buffer, size_t len, bool ns_caller,
return SPM_ERROR_MEMORY_CHECK;
}
-/* Allocate runtime space for partition from the pool. Static allocation. */
-static struct partition_t *tfm_allocate_partition(void)
-{
- static uint32_t partition_pool_pos = 0;
- struct partition_t *p_partition_allocated = NULL;
-
- if (partition_pool_pos >= g_spm_partition_db.partition_count) {
- return NULL;
- }
-
- p_partition_allocated = &g_spm_partition_db.partitions[partition_pool_pos];
- partition_pool_pos++;
-
- return p_partition_allocated;
-}
-
-/* Allocate runtime space for service from the pool. Static allocation. */
-static struct service_t *tfm_allocate_service(uint32_t service_count)
-{
- static uint32_t service_pool_pos = 0;
- struct service_t *p_service_allocated = NULL;
- uint32_t num_of_services = sizeof(g_services) / sizeof(struct service_t);
-
- if ((service_count == 0) ||
- (service_count > num_of_services) ||
- (service_pool_pos >= num_of_services) ||
- (service_pool_pos + service_count > num_of_services)) {
- return NULL;
- }
-
- p_service_allocated = &g_services[service_pool_pos];
- service_pool_pos += service_count;
-
- return p_service_allocated;
-}
-
-/* Check partition static data validation */
-bool tfm_validate_partition_static(struct partition_load_info_t *p_cmninf)
-{
- return ((p_cmninf->psa_ff_ver & PARTITION_INFO_MAGIC_MASK)
- == PARTITION_INFO_MAGIC);
-}
-
uint32_t tfm_spm_init(void)
{
- uint32_t i, j, part_idx;
+ uint32_t i, j, part_idx = 0;
struct partition_t *partition;
- struct service_t *service;
struct tfm_core_thread_t *pth, *p_ns_entry_thread = NULL;
const struct platform_data_t *platform_data_p;
- uintptr_t part_load_start, part_load_end;
- struct partition_load_info_t *p_cmninf;
- struct service_load_info_t *p_service_static;
+ const struct partition_load_info_t *p_cmninf;
struct asset_desc_t *p_asset_load;
#ifdef TFM_FIH_PROFILE_ON
fih_int fih_rc = FIH_FAILURE;
@@ -709,49 +657,17 @@ uint32_t tfm_spm_init(void)
sizeof(struct tfm_conn_handle_t),
TFM_CONN_HANDLE_MAX_NUM);
- /* Load partition and service data */
- part_idx = 0;
- part_load_start = PART_REGION_ADDR(TFM_SP_STATIC_LIST, $$RO$$Base);
- part_load_end = PART_REGION_ADDR(TFM_SP_STATIC_LIST, $$RO$$Limit);
- while (part_load_start < part_load_end) {
- p_cmninf = (struct partition_load_info_t *)part_load_start;
-
- /* Validate static info section range */
- part_load_start += LOAD_INFSZ_BYTES(p_cmninf);
- if (part_load_start > part_load_end) {
- tfm_core_panic();
+ while (1) {
+ partition = load_a_partition_assuredly();
+ if (partition == NULL) {
+ break;
}
- /* Validate partition static info */
- if (!tfm_validate_partition_static(p_cmninf)) {
- tfm_core_panic();
- }
- if (!(p_cmninf->flags & SPM_PART_FLAG_IPC)) {
- tfm_core_panic();
- }
- if ((p_cmninf->psa_ff_ver & PARTITION_INFO_VERSION_MASK)
- > PSA_FRAMEWORK_VERSION) {
- ERROR_MSG("Warning: Partition requires higher framework version!");
- tfm_core_panic();
- }
+ load_services_assuredly(partition, &all_services);
- /* Allocate runtime space */
- partition = tfm_allocate_partition();
- if (!partition) {
- tfm_core_panic();
- }
- if (p_cmninf->nservices) {
- service = tfm_allocate_service(p_cmninf->nservices);
- if (!service) {
- tfm_core_panic();
- }
- } else {
- service = NULL;
- }
-
- partition->p_static = p_cmninf;
+ p_cmninf = partition->p_ldinf;
- /* Init partition device object assets */
+ /* Init mmio assets */
p_asset_load = (struct asset_desc_t *)LOAD_INFO_ASSET(p_cmninf);
for (i = 0; i < p_cmninf->nassets; i++) {
/* Skip the memory-based asset */
@@ -759,8 +675,8 @@ uint32_t tfm_spm_init(void)
continue;
}
- platform_data_p = POSITION_TO_PTR(p_asset_load[i].dev.addr_ref,
- struct platform_data_t *);
+ platform_data_p = REFERENCE_TO_PTR(p_asset_load[i].dev.addr_ref,
+ struct platform_data_t *);
/*
* TODO: some partitions declare MMIO not exist on specific
@@ -825,7 +741,7 @@ uint32_t tfm_spm_init(void)
LOAD_ALLOCED_STACK_ADDR(p_cmninf) + p_cmninf->stack_size,
LOAD_ALLOCED_STACK_ADDR(p_cmninf));
- pth->prior = TO_THREAD_PRIORITY(PARTITION_GET_PRIOR(p_cmninf->flags));
+ pth->prior = TO_THREAD_PRIORITY(PARTITION_PRIORITY(p_cmninf->flags));
if (p_cmninf->pid == TFM_SP_NON_SECURE_ID) {
p_ns_entry_thread = pth;
@@ -837,32 +753,6 @@ uint32_t tfm_spm_init(void)
tfm_core_panic();
}
- /* Init Services in the partition */
- p_service_static =
- (struct service_load_info_t *)LOAD_INFO_SERVICE(p_cmninf);
- for (i = 0; i < p_cmninf->nservices; i++) {
- /* Fill service runtime data */
- partition->signals_allowed |= p_service_static[i].signal;
- service[i].service_db = &p_service_static[i];
- service[i].partition = partition;
-
- /* Populate the p_service of stateless_service_ref[] */
- if (SERVICE_IS_STATELESS(p_service_static[i].flags)) {
- for (j = 0; j < STATIC_HANDLE_NUM_LIMIT; j++) {
- if (stateless_service_ref[j].sid ==
- p_service_static[i].sid) {
- stateless_service_ref[j].p_service = &service[i];
- break;
- }
- }
- /* Stateless service not found in tracking table */
- if (j >= STATIC_HANDLE_NUM_LIMIT) {
- tfm_core_panic();
- }
- }
-
- BI_LIST_INIT_NODE(&service[i].handle_list);
- }
part_idx++;
}
@@ -900,7 +790,7 @@ void tfm_pendsv_do_schedule(struct tfm_arch_ctx_t *p_actx)
p_next_partition = TO_CONTAINER(pth_next,
struct partition_t,
sp_thread);
- p_part_static = p_next_partition->p_static;
+ p_part_static = p_next_partition->p_ldinf;
if (p_part_static->flags & SPM_PART_FLAG_PSA_ROT) {
is_privileged = TFM_PARTITION_PRIVILEGED_MODE;
} else {
@@ -1059,7 +949,7 @@ void tfm_spm_validate_caller(struct partition_t *p_cur_sp, uint32_t *p_ctx,
* the preempted context of SP can be different with the one who
* preempts veneer.
*/
- if (p_cur_sp->p_static->pid != TFM_SP_NON_SECURE_ID) {
+ if (p_cur_sp->p_ldinf->pid != TFM_SP_NON_SECURE_ID) {
tfm_core_panic();
}
@@ -1084,7 +974,7 @@ void tfm_spm_validate_caller(struct partition_t *p_cur_sp, uint32_t *p_ctx,
if (stacked_ctx_pos != p_cur_sp->sp_thread.stk_top) {
tfm_core_panic();
}
- } else if (p_cur_sp->p_static->pid <= 0) {
+ } else if (p_cur_sp->p_ldinf->pid <= 0) {
tfm_core_panic();
}
}
@@ -1104,7 +994,7 @@ void tfm_spm_request_handler(const struct tfm_state_context_t *svc_ctx)
if (!partition) {
tfm_core_panic();
}
- running_partition_flags = partition->p_static->flags;
+ running_partition_flags = partition->p_ldinf->flags;
/* Currently only PSA Root of Trust services are allowed to make Reset
* vote request
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.h b/secure_fw/spm/cmsis_psa/spm_ipc.h
index 52ca01adf..b193b81db 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.h
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.h
@@ -83,7 +83,7 @@ struct tfm_msg_body_t {
* divided to structures, to keep the related fields close to each other.
*/
struct partition_t {
- const struct partition_load_info_t *p_static;
+ const struct partition_load_info_t *p_ldinf;
void *p_platform;
void *p_interrupts;
void *p_metadata;
@@ -102,7 +102,7 @@ struct spm_partition_db_t {
/* RoT Service data */
struct service_t {
- const struct service_load_info_t *service_db; /* Service static pointer */
+ const struct service_load_info_t *p_ldinf; /* Service static pointer */
struct partition_t *partition; /* Owner of the service */
struct bi_list_node_t handle_list; /* Service handle list */
struct bi_list_node_t list; /* For list operation */
diff --git a/secure_fw/spm/cmsis_psa/static_load.c b/secure_fw/spm/cmsis_psa/static_load.c
new file mode 100644
index 000000000..e8316c321
--- /dev/null
+++ b/secure_fw/spm/cmsis_psa/static_load.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <limits.h>
+#include <stdint.h>
+#include "lists.h"
+#include "region.h"
+#include "region_defs.h"
+#include "spm_ipc.h"
+#include "utilities.h"
+#include "load/partition_defs.h"
+#include "load/spm_load_api.h"
+#include "load/service_defs.h"
+#include "psa/client.h"
+
+#include "secure_fw/partitions/tfm_service_list.inc"
+#include "tfm_spm_db_ipc.inc"
+
+/* Partition static data region */
+REGION_DECLARE(Image$$, TFM_SP_STATIC_LIST, $$RO$$Base);
+REGION_DECLARE(Image$$, TFM_SP_STATIC_LIST, $$RO$$Limit);
+
+static uintptr_t ldinf_sa = PART_REGION_ADDR(TFM_SP_STATIC_LIST, $$RO$$Base);
+static uintptr_t ldinf_ea = PART_REGION_ADDR(TFM_SP_STATIC_LIST, $$RO$$Limit);
+
+/* Allocate runtime space for partition from the pool. Static allocation. */
+static struct partition_t *tfm_allocate_partition_assuredly(void)
+{
+ static uint32_t partition_pool_pos = 0;
+ struct partition_t *p_partition_allocated = NULL;
+
+ if (partition_pool_pos >= g_spm_partition_db.partition_count) {
+ tfm_core_panic();
+ }
+
+ p_partition_allocated = &g_spm_partition_db.partitions[partition_pool_pos];
+ partition_pool_pos++;
+
+ return p_partition_allocated;
+}
+
+/* Allocate runtime space for service from the pool. Static allocation. */
+static struct service_t *tfm_allocate_service_assuredly(uint32_t service_count)
+{
+ static uint32_t service_pool_pos = 0;
+ struct service_t *p_service_allocated = NULL;
+ uint32_t num_of_services = sizeof(g_services) / sizeof(struct service_t);
+
+ if (service_count == 0) {
+ return NULL;
+ } else if ((service_count > num_of_services) ||
+ (service_pool_pos >= num_of_services) ||
+ (service_pool_pos + service_count > num_of_services)) {
+ tfm_core_panic();
+ }
+
+ p_service_allocated = &g_services[service_pool_pos];
+ service_pool_pos += service_count;
+
+ return p_service_allocated;
+}
+
+struct partition_t *load_a_partition_assuredly(void)
+{
+ struct partition_load_info_t *p_ptldinf;
+ struct partition_t *partition;
+
+ if ((UINTPTR_MAX - ldinf_sa < sizeof(struct partition_load_info_t)) ||
+ (ldinf_sa + sizeof(struct partition_load_info_t) >= ldinf_ea)) {
+ return NULL;
+ }
+
+ p_ptldinf = (struct partition_load_info_t *)ldinf_sa;
+
+ if ((UINTPTR_MAX - ldinf_sa < LOAD_INFSZ_BYTES(p_ptldinf)) ||
+ (ldinf_sa + LOAD_INFSZ_BYTES(p_ptldinf) > ldinf_ea)) {
+ tfm_core_panic();
+ }
+
+ /* Magic ensures data integrity */
+ if ((p_ptldinf->psa_ff_ver & PARTITION_INFO_MAGIC_MASK)
+ != PARTITION_INFO_MAGIC) {
+ tfm_core_panic();
+ }
+
+ if ((p_ptldinf->psa_ff_ver & PARTITION_INFO_VERSION_MASK)
+ > PSA_FRAMEWORK_VERSION) {
+ tfm_core_panic();
+ }
+
+ if (!(p_ptldinf->flags & SPM_PART_FLAG_IPC)) {
+ tfm_core_panic();
+ }
+
+ partition = tfm_allocate_partition_assuredly();
+ partition->p_ldinf = p_ptldinf;
+
+ ldinf_sa += LOAD_INFSZ_BYTES(p_ptldinf);
+
+ return partition;
+}
+
+void load_services_assuredly(struct partition_t *p_partition,
+ struct service_t **list_head)
+{
+ uint32_t i, j;
+ struct service_t *services;
+ const struct partition_load_info_t *p_ptldinf;
+ const struct service_load_info_t *p_servldinf;
+
+ if (p_partition == NULL) {
+ tfm_core_panic();
+ }
+
+ p_ptldinf = p_partition->p_ldinf;
+ p_servldinf = (struct service_load_info_t *)LOAD_INFO_SERVICE(p_ptldinf);
+
+ /*
+ * 'services' CAN be NULL when no services, which is a rational result.
+ * The loop won't go in the NULL case.
+ */
+ services = tfm_allocate_service_assuredly(p_ptldinf->nservices);
+ for (i = 0; i < p_ptldinf->nservices && services; i++) {
+ p_partition->signals_allowed |= p_servldinf[i].signal;
+ services[i].p_ldinf = &p_servldinf[i];
+ services[i].partition = p_partition;
+
+ /* Populate the p_service of stateless_service_ref[] */
+ if (SERVICE_IS_STATELESS(p_servldinf[i].flags)) {
+ for (j = 0; j < STATIC_HANDLE_NUM_LIMIT; j++) {
+ if (stateless_service_ref[j].sid == p_servldinf[i].sid) {
+ stateless_service_ref[j].p_service = &services[i];
+ break;
+ }
+ }
+ /* Stateless service not found in tracking table */
+ if (j >= STATIC_HANDLE_NUM_LIMIT) {
+ tfm_core_panic();
+ }
+ }
+ BI_LIST_INIT_NODE(&services[i].handle_list);
+ BI_LIST_INIT_NODE(&services[i].list);
+
+ if (list_head) {
+ if (*list_head) {
+ BI_LIST_INSERT_AFTER(&(*list_head)->list, &services[i].list);
+ } else {
+ *list_head = &services[i];
+ }
+ }
+ }
+}
diff --git a/secure_fw/spm/ffm/psa_client_service_apis.c b/secure_fw/spm/ffm/psa_client_service_apis.c
index 57c1b82a4..87c7f3bd4 100644
--- a/secure_fw/spm/ffm/psa_client_service_apis.c
+++ b/secure_fw/spm/ffm/psa_client_service_apis.c
@@ -76,7 +76,7 @@ psa_status_t tfm_spm_psa_call(uint32_t *args, bool ns_caller, uint32_t lr)
tfm_core_panic();
}
privileged = tfm_spm_partition_get_privileged_mode(
- partition->p_static->flags);
+ partition->p_ldinf->flags);
type = (int32_t)(int16_t)((args[1] & TYPE_MASK) >> TYPE_OFFSET);
in_num = (size_t)((args[1] & IN_LEN_MASK) >> IN_LEN_OFFSET);
@@ -174,7 +174,7 @@ psa_status_t tfm_spm_psa_get(uint32_t *args)
tfm_core_panic();
}
privileged = tfm_spm_partition_get_privileged_mode(
- partition->p_static->flags);
+ partition->p_ldinf->flags);
/*
* Write the message to the service buffer. It is a fatal error if the
@@ -237,7 +237,7 @@ void tfm_spm_psa_set_rhandle(uint32_t *args)
}
/* It is a PROGRAMMER ERROR if a stateless service sets rhandle. */
- if (SERVICE_IS_STATELESS(msg->service->service_db->flags)) {
+ if (SERVICE_IS_STATELESS(msg->service->p_ldinf->flags)) {
tfm_core_panic();
}
@@ -273,7 +273,7 @@ size_t tfm_spm_psa_read(uint32_t *args)
partition = msg->service->partition;
privileged = tfm_spm_partition_get_privileged_mode(
- partition->p_static->flags);
+ partition->p_ldinf->flags);
/*
* It is a fatal error if message handle does not refer to a request
@@ -396,7 +396,7 @@ void tfm_spm_psa_write(uint32_t *args)
partition = msg->service->partition;
privileged = tfm_spm_partition_get_privileged_mode(
- partition->p_static->flags);
+ partition->p_ldinf->flags);
/*
* It is a fatal error if message handle does not refer to a request
@@ -513,7 +513,7 @@ void tfm_spm_psa_reply(uint32_t *args)
* psa_call().
*/
update_caller_outvec_len(msg);
- if (SERVICE_IS_STATELESS(service->service_db->flags)) {
+ if (SERVICE_IS_STATELESS(service->p_ldinf->flags)) {
tfm_spm_free_conn_handle(service, conn_handle);
}
} else {
@@ -585,7 +585,7 @@ void tfm_spm_psa_eoi(uint32_t *args)
tfm_core_panic();
}
- irq_line = get_irq_line_for_signal(partition->p_static->pid, irq_signal);
+ irq_line = get_irq_line_for_signal(partition->p_ldinf->pid, irq_signal);
/* It is a fatal error if passed signal is not an interrupt signal. */
if (irq_line < 0) {
tfm_core_panic();
@@ -624,7 +624,7 @@ void tfm_spm_irq_enable(uint32_t *args)
tfm_core_panic();
}
- irq_line = get_irq_line_for_signal(partition->p_static->pid, irq_signal);
+ irq_line = get_irq_line_for_signal(partition->p_ldinf->pid, irq_signal);
if (irq_line < 0) {
tfm_core_panic();
}
@@ -645,7 +645,7 @@ psa_irq_status_t tfm_spm_irq_disable(uint32_t *args)
tfm_core_panic();
}
- irq_line = get_irq_line_for_signal(partition->p_static->pid, irq_signal);
+ irq_line = get_irq_line_for_signal(partition->p_ldinf->pid, irq_signal);
if (irq_line < 0) {
tfm_core_panic();
}
diff --git a/secure_fw/spm/ffm/spm_psa_client_call.c b/secure_fw/spm/ffm/spm_psa_client_call.c
index 3bcf6a880..805e9f3d8 100644
--- a/secure_fw/spm/ffm/spm_psa_client_call.c
+++ b/secure_fw/spm/ffm/spm_psa_client_call.c
@@ -47,7 +47,7 @@ uint32_t tfm_spm_client_psa_version(uint32_t sid, bool ns_caller)
return PSA_VERSION_NONE;
}
- return service->service_db->version;
+ return service->p_ldinf->version;
}
psa_status_t tfm_spm_client_psa_connect(uint32_t sid, uint32_t version,
@@ -85,7 +85,7 @@ psa_status_t tfm_spm_client_psa_connect(uint32_t sid, uint32_t version,
}
/* It is a PROGRAMMER ERROR if connecting to a stateless service. */
- if (SERVICE_IS_STATELESS(service->service_db->flags)) {
+ if (SERVICE_IS_STATELESS(service->p_ldinf->flags)) {
TFM_PROGRAMMER_ERROR(ns_caller, PSA_ERROR_PROGRAMMER_ERROR);
}
diff --git a/secure_fw/spm/ffm/tfm_boot_data.c b/secure_fw/spm/ffm/tfm_boot_data.c
index d3bb96d6d..1b9ed64e0 100644
--- a/secure_fw/spm/ffm/tfm_boot_data.c
+++ b/secure_fw/spm/ffm/tfm_boot_data.c
@@ -174,7 +174,7 @@ void tfm_core_get_boot_data_handler(uint32_t args[])
tfm_core_panic();
}
privileged =
- tfm_spm_partition_get_privileged_mode(partition->p_static->flags);
+ tfm_spm_partition_get_privileged_mode(partition->p_ldinf->flags);
if (tfm_memory_check(buf_start, buf_size, false, TFM_MEMORY_ACCESS_RW,
privileged) != SPM_SUCCESS) {
diff --git a/secure_fw/spm/include/load/asset_defs.h b/secure_fw/spm/include/load/asset_defs.h
index 6e5c8d059..af1289c68 100644
--- a/secure_fw/spm/include/load/asset_defs.h
+++ b/secure_fw/spm/include/load/asset_defs.h
@@ -17,6 +17,9 @@
/* Customized objects such as device or symbol. Refer by 'dev' in the union. */
#define ASSET_DEV_REF_BIT (1U << 3)
+#define PTR_TO_REFERENCE(x) (uintptr_t)(x)
+#define REFERENCE_TO_PTR(x, t) (t)(x)
+
struct asset_desc_t {
union {
struct { /* Memory asset type */
diff --git a/secure_fw/spm/include/load/partition_defs.h b/secure_fw/spm/include/load/partition_defs.h
index 80edfd978..119359ed8 100644
--- a/secure_fw/spm/include/load/partition_defs.h
+++ b/secure_fw/spm/include/load/partition_defs.h
@@ -36,6 +36,11 @@
#define SPM_PART_FLAG_PSA_ROT (1U << 8)
#define SPM_PART_FLAG_IPC (1U << 9)
+#define PARTITION_PRIORITY(flag) ((flag) & PARTITION_PRI_MASK)
+#define TO_THREAD_PRIORITY(x) (x)
+
+#define ENTRY_TO_POSITION(x) (uintptr_t)(x)
+#define POSITION_TO_ENTRY(x, t) (t)(x)
/*
* Common partition structure type, the extendable data is right after it.
* Extendable data has different size for each partition, and must be 4-byte
diff --git a/secure_fw/spm/include/load/partition_static_load.h b/secure_fw/spm/include/load/partition_static_load.h
deleted file mode 100644
index 698c03474..000000000
--- a/secure_fw/spm/include/load/partition_static_load.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef __PARTITION_STATIC_LOAD_H__
-#define __PARTITION_STATIC_LOAD_H__
-
-#include "partition_defs.h"
-#include "service_defs.h"
-
-#define PARTITION_GET_PRIOR(flag) ((flag) & PARTITION_PRI_MASK)
-#define TO_THREAD_PRIORITY(x) (x)
-
-#define STRID_TO_STRING_PTR(strid) (const char *)(strid)
-#define STRING_PTR_TO_STRID(str) (uintptr_t)(str)
-
-#define ENTRY_TO_POSITION(x) (uintptr_t)(x)
-#define POSITION_TO_ENTRY(x, t) (t)(x)
-
-#define PTR_TO_POSITION(x) (uintptr_t)(x)
-#define POSITION_TO_PTR(x, t) (t)(x)
-
-/* Length of extendable variables in partition static type */
-#define LOAD_INFO_EXT_LENGTH 2
-/*
- * Argument "ps_ptr" must have be a "struct partition_load_info_t *" type and
- * must be validated before using.
- */
-#define LOAD_INFSZ_BYTES(ps_ptr) \
- (sizeof(*(ps_ptr)) + LOAD_INFO_EXT_LENGTH * sizeof(uintptr_t) + \
- (ps_ptr)->ndeps * sizeof(uint32_t) + \
- (ps_ptr)->nservices * sizeof(struct service_load_info_t) + \
- (ps_ptr)->nassets * sizeof(struct asset_desc_t))
-
-/* 'Allocate' stack based on load info */
-#define LOAD_ALLOCED_STACK_ADDR(ps_ptr) (*((uintptr_t *)(ps_ptr + 1)))
-
-#define LOAD_INFO_DEPS(ps_ptr) \
- ((uintptr_t)(ps_ptr + 1) + LOAD_INFO_EXT_LENGTH * sizeof(uintptr_t))
-#define LOAD_INFO_SERVICE(ps_ptr) \
- ((uintptr_t)LOAD_INFO_DEPS(ps_ptr) + (ps_ptr)->ndeps * sizeof(uint32_t))
-#define LOAD_INFO_ASSET(ps_ptr) \
- ((uintptr_t)LOAD_INFO_SERVICE(ps_ptr) + \
- (ps_ptr)->nservices * sizeof(struct service_load_info_t))
-
-#endif /* __PARTITION_STATIC_LOAD_H__ */
diff --git a/secure_fw/spm/include/load/service_defs.h b/secure_fw/spm/include/load/service_defs.h
index d0825072d..3692846ef 100644
--- a/secure_fw/spm/include/load/service_defs.h
+++ b/secure_fw/spm/include/load/service_defs.h
@@ -31,6 +31,9 @@
#define SERVICE_GET_VERSION_POLICY(flag) \
((flag) & SERVICE_VERSION_POLICY_MASK)
+#define STRID_TO_STRING_PTR(strid) (const char *)(strid)
+#define STRING_PTR_TO_STRID(str) (uintptr_t)(str)
+
/* Common service structure type */
struct service_load_info_t {
uintptr_t name_strid; /* String ID for name */
diff --git a/secure_fw/spm/include/load/spm_load_api.h b/secure_fw/spm/include/load/spm_load_api.h
new file mode 100644
index 000000000..a04760845
--- /dev/null
+++ b/secure_fw/spm/include/load/spm_load_api.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* !! For SPM load usage, no including by components out of SPM !! */
+#ifndef __SPM_LOAD_API_H__
+#define __SPM_LOAD_API_H__
+
+#include "asset_defs.h"
+#include "partition_defs.h"
+#include "service_defs.h"
+#include "spm_ipc.h"
+
+/* Length of extendable variables in partition static type */
+#define LOAD_INFO_EXT_LENGTH 2
+/* Argument "pldinf" must be a "struct partition_load_info_t *". */
+#define LOAD_INFSZ_BYTES(pldinf) \
+ (sizeof(*(pldinf)) + LOAD_INFO_EXT_LENGTH * sizeof(uintptr_t) + \
+ (pldinf)->ndeps * sizeof(uint32_t) + \
+ (pldinf)->nservices * sizeof(struct service_load_info_t) + \
+ (pldinf)->nassets * sizeof(struct asset_desc_t))
+
+/* 'Allocate' stack based on load info */
+#define LOAD_ALLOCED_STACK_ADDR(pldinf) (*((uintptr_t *)(pldinf + 1)))
+
+#define LOAD_INFO_DEPS(pldinf) \
+ ((uintptr_t)(pldinf + 1) + LOAD_INFO_EXT_LENGTH * sizeof(uintptr_t))
+#define LOAD_INFO_SERVICE(pldinf) \
+ ((uintptr_t)LOAD_INFO_DEPS(pldinf) + (pldinf)->ndeps * sizeof(uint32_t))
+#define LOAD_INFO_ASSET(pldinf) \
+ ((uintptr_t)LOAD_INFO_SERVICE(pldinf) + \
+ (pldinf)->nservices * sizeof(struct service_load_info_t))
+
+/*
+ * Allocate a partition object and return if a load is successful.
+ * An 'assuredly' function, return NULL for no more partitions and
+ * return a valid pointer if succeed. Other errors simply panic
+ * the system and never return.
+ */
+struct partition_t *load_a_partition_assuredly(void);
+
+/*
+ * Allocated numbers of service objects based on given partition.
+ * Link services with 'list_head' if it is provided.
+ * An 'assuredly' function, errors simply panic the system and never
+ * return.
+ */
+void load_services_assuredly(struct partition_t *p_partition,
+ struct service_t **list_head);
+
+#endif /* __SPM_LOAD_API_H__ */