diff options
author | Balint Dobszay <balint.dobszay@arm.com> | 2021-03-16 15:03:05 +0100 |
---|---|---|
committer | Balint Dobszay <balint.dobszay@arm.com> | 2021-03-22 18:41:28 +0100 |
commit | 43024ed02d3696a02c56815d9485a1544f044652 (patch) | |
tree | 40682254ae746ff6f8c6d3f2631ce880239ad2cb | |
parent | b98be2ca1eff68b8d9515870120f7f2c5639009c (diff) | |
download | optee_os-43024ed02d3696a02c56815d9485a1544f044652.tar.gz |
SPM: DT handling improvements
Small improvements and cleanup of DT handling functions and prepares
for adding the FIP SP storage backend.
Change-Id: Ie61a33f43302b3d717fa8c9ff821c49acf39e38f
Signed-off-by: Balint Dobszay <balint.dobszay@arm.com>
-rw-r--r-- | core/arch/arm/include/kernel/sp.h | 8 | ||||
-rw-r--r-- | core/arch/arm/kernel/sp.c | 119 |
2 files changed, 89 insertions, 38 deletions
diff --git a/core/arch/arm/include/kernel/sp.h b/core/arch/arm/include/kernel/sp.h index d198f738f..42fbde281 100644 --- a/core/arch/arm/include/kernel/sp.h +++ b/core/arch/arm/include/kernel/sp.h @@ -1,7 +1,8 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2020, Arm Limited. + * Copyright (c) 2020-2021, Arm Limited */ + #ifndef __KERNEL_SP_H #define __KERNEL_SP_H @@ -74,6 +75,11 @@ struct sp_session { void sp_sessions_list_head(struct sp_sessions_head **open_sessions); +TEE_Result sp_dt_get_u64(const void *fdt, int node, const char *property, + uint64_t *value); +TEE_Result sp_dt_get_u32(const void *fdt, int node, const char *property, + uint32_t *value); +TEE_Result sp_dt_get_uuid(const void *fdt, int node, TEE_UUID *uuid); TEE_Result sp_start_init_thread(void); TEE_Result sp_init_user_session(const TEE_UUID *uuid, struct tee_ta_session *s); struct sp_session *sp_get_session(uint32_t session_id); diff --git a/core/arch/arm/kernel/sp.c b/core/arch/arm/kernel/sp.c index feb8df19d..2f00fc83d 100644 --- a/core/arch/arm/kernel/sp.c +++ b/core/arch/arm/kernel/sp.c @@ -1,7 +1,8 @@ // SPDX-License-Identifier: BSD-2-Clause /* - * Copyright (c) 2020, Arm Limited + * Copyright (c) 2020-2021, Arm Limited */ + #include <assert.h> #include <bench.h> #include <bitstring.h> @@ -75,8 +76,8 @@ static void set_sp_ctx_ops(struct tee_ta_ctx *ctx) ctx->ops = _sp_ops; } -static TEE_Result sp_dt_get_u64(void *fdt, int node, const char *property, - uint64_t *value) +TEE_Result sp_dt_get_u64(const void *fdt, int node, const char *property, + uint64_t *value) { int len = 0; const fdt64_t *cuint64 = NULL; @@ -89,8 +90,8 @@ static TEE_Result sp_dt_get_u64(void *fdt, int node, const char *property, return TEE_SUCCESS; } -static TEE_Result sp_dt_get_u32(void *fdt, int node, const char *property, - uint32_t *value) +TEE_Result sp_dt_get_u32(const void *fdt, int node, const char *property, + uint32_t *value) { int len = 0; const fdt32_t *cuint32 = NULL; @@ -103,6 +104,31 @@ static TEE_Result sp_dt_get_u32(void *fdt, int node, const char *property, return TEE_SUCCESS; } +TEE_Result sp_dt_get_uuid(const void *fdt, int node, TEE_UUID *uuid) +{ + int i = 0; + int len = 0; + const fdt32_t *prop = NULL; + uint32_t uuid_array[4] = { 0 }; + + if (fdt_node_check_compatible(fdt, node, "arm,ffa-manifest-1.0")) + return TEE_ERROR_BAD_FORMAT; + + prop = fdt_getprop(fdt, node, "uuid", &len); + if (!prop || len != 16) { + EMSG("Missing or invalid UUID in SP manifest"); + return TEE_ERROR_BAD_FORMAT; + } + + for (i = 0; i < 4; i++) { + uuid_array[i] = fdt32_to_cpu(prop[i]); + uuid_array[i] = TEE_U32_TO_BIG_ENDIAN(uuid_array[i]); + } + tee_uuid_from_octets(uuid, (uint8_t *)uuid_array); + + return TEE_SUCCESS; +} + static TEE_Result map_region(struct sp_session *sp_s, uint64_t pa, size_t num_pgs, uint32_t prot, vaddr_t *va) { @@ -127,16 +153,21 @@ static TEE_Result map_region(struct sp_session *sp_s, uint64_t pa, return res; } -static TEE_Result sp_map_device_regions(struct sp_session *s, void *fdt, +static TEE_Result sp_map_device_regions(struct sp_session *s, const void *fdt, int off) { int sp_node = 0; + int dev_regions_offs = 0; if (!fdt) return TEE_ERROR_ITEM_NOT_FOUND; - off = fdt_subnode_offset(fdt, off, "device-regions"); - fdt_for_each_subnode(sp_node, fdt, off) { + dev_regions_offs = fdt_subnode_offset(fdt, off, "device-regions"); + if (dev_regions_offs < 0) + /* No device regions in this DT */ + return TEE_SUCCESS; + + fdt_for_each_subnode(sp_node, fdt, dev_regions_offs) { vaddr_t va = 0; uint64_t pa = 0; uint32_t sz = 0; @@ -176,43 +207,54 @@ static TEE_Result sp_map_device_regions(struct sp_session *s, void *fdt, return TEE_SUCCESS; } -static TEE_Result sp_process_manifest(struct sp_session *s, - const TEE_UUID *uuid) +static TEE_Result sp_get_manifest(const TEE_UUID *uuid, const void **fdt, + int *node) { - void *fdt = NULL; + if (!uuid || !fdt || !node) + return TEE_ERROR_BAD_PARAMETERS; + +#ifdef CFG_EARLY_TA + TEE_UUID node_uuid = {}; + int root = 0; int sp_node = 0; - int node = 0; - const fdt32_t *cuint32 = NULL; - int len = 0; - fdt = get_embedded_dt(); - if (!fdt) - return TEE_ERROR_ITEM_NOT_FOUND; + *fdt = get_embedded_dt(); + if (!*fdt) { + EMSG("Embedded DT missing, cannot get SP manifest for %pUl", + (void *)uuid); + return TEE_ERROR_GENERIC; + } - node = fdt_path_offset(fdt, "/"); + root = fdt_path_offset(*fdt, "/"); - fdt_for_each_subnode(sp_node, fdt, node) { - cuint32 = fdt_getprop(fdt, sp_node, "uuid", &len); + fdt_for_each_subnode(sp_node, *fdt, root) { + sp_dt_get_uuid(*fdt, sp_node, &node_uuid); + if (!memcmp(&node_uuid, uuid, sizeof(*uuid))) { + *node = sp_node; + return TEE_SUCCESS; + } + } +#endif - if (len != sizeof(TEE_UUID)) - return TEE_ERROR_ITEM_NOT_FOUND; + return TEE_ERROR_ITEM_NOT_FOUND; +} - if (cuint32) { - TEE_UUID dt_uuid = {}; +static TEE_Result sp_process_manifest(struct sp_session *s, + const TEE_UUID *uuid) +{ + TEE_Result res = TEE_SUCCESS; + const void *fdt = NULL; + int sp_node = 0; - tee_uuid_from_uint32_t(&dt_uuid, - fdt32_to_cpu(cuint32[0]), - fdt32_to_cpu(cuint32[1]), - fdt32_to_cpu(cuint32[2]), - fdt32_to_cpu(cuint32[3])); + res = sp_get_manifest(uuid, &fdt, &sp_node); + if (res) + return res; - if (!memcmp(&dt_uuid, uuid, sizeof(*uuid))) { - sp_map_device_regions(s, fdt, sp_node); - return TEE_SUCCESS; - } - } - } - return TEE_ERROR_ITEM_NOT_FOUND; + res = sp_map_device_regions(s, fdt, sp_node); + if (res) + return res; + + return TEE_SUCCESS; } static void sp_init_info(struct sp_session *sp_s, @@ -623,7 +665,10 @@ static TEE_Result sp_enter_open_session(struct tee_ta_session *s, tee_ta_push_current_session(sp_s->s); sp_init_info(sp_s, &secure_partition_info); - sp_process_manifest(sp_s, &sp_s->s->ctx->uuid); + res = sp_process_manifest(sp_s, &sp_s->s->ctx->uuid); + if (res) + return res; + tee_ta_pop_current_session(); sp_init_set_registers(sp_s); |