aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBalint Dobszay <balint.dobszay@arm.com>2021-03-16 15:03:05 +0100
committerBalint Dobszay <balint.dobszay@arm.com>2021-03-22 18:41:28 +0100
commit43024ed02d3696a02c56815d9485a1544f044652 (patch)
tree40682254ae746ff6f8c6d3f2631ce880239ad2cb
parentb98be2ca1eff68b8d9515870120f7f2c5639009c (diff)
downloadoptee_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.h8
-rw-r--r--core/arch/arm/kernel/sp.c119
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);