diff options
Diffstat (limited to 'secure_fw')
-rw-r--r-- | secure_fw/include/compile_check_defs.h | 2 | ||||
-rw-r--r-- | secure_fw/partitions/ns_proxy_partition/load_info_ns_proxy.c | 9 | ||||
-rw-r--r-- | secure_fw/partitions/partition_load_info.template | 15 | ||||
-rw-r--r-- | secure_fw/partitions/tfm_service_list.inc.template | 2 | ||||
-rwxr-xr-x | secure_fw/spm/CMakeLists.txt | 1 | ||||
-rw-r--r-- | secure_fw/spm/cmsis_psa/spm_ipc.c | 194 | ||||
-rw-r--r-- | secure_fw/spm/cmsis_psa/spm_ipc.h | 4 | ||||
-rw-r--r-- | secure_fw/spm/cmsis_psa/static_load.c | 155 | ||||
-rw-r--r-- | secure_fw/spm/ffm/psa_client_service_apis.c | 18 | ||||
-rw-r--r-- | secure_fw/spm/ffm/spm_psa_client_call.c | 4 | ||||
-rw-r--r-- | secure_fw/spm/ffm/tfm_boot_data.c | 2 | ||||
-rw-r--r-- | secure_fw/spm/include/load/asset_defs.h | 3 | ||||
-rw-r--r-- | secure_fw/spm/include/load/partition_defs.h | 5 | ||||
-rw-r--r-- | secure_fw/spm/include/load/partition_static_load.h | 49 | ||||
-rw-r--r-- | secure_fw/spm/include/load/service_defs.h | 3 | ||||
-rw-r--r-- | secure_fw/spm/include/load/spm_load_api.h | 54 |
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 13a8689811..89a94b8a49 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 2a1446779f..fed4832dc7 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 ad005dddae..94e5bed571 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 386c463474..ac0e74acf8 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 fb5571b817..ff7d28d562 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 1642626eab..e812d2c9fd 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 52ca01adf0..b193b81db4 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 0000000000..e8316c321c --- /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 57c1b82a41..87c7f3bd46 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 3bcf6a8805..805e9f3d8f 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 d3bb96d6d7..1b9ed64e04 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 6e5c8d059e..af1289c68f 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 80edfd978a..119359ed82 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 698c03474f..0000000000 --- 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 d0825072d4..3692846efe 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 0000000000..a04760845c --- /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__ */ |