summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Kardatzke <jkardatzke@google.com>2023-02-09 10:45:35 -0800
committerManish Pandey <manish.pandey2@arm.com>2023-05-11 10:46:57 +0200
commitf4bbf435554e87de31c0a70039aa03b19962aaea (patch)
tree6f4efa4ede0f165f00b4fa6279f62a20f2ebd3ff
parenta63de43661015b392be1e0827b64a77ae687d8f8 (diff)
downloadarm-trusted-firmware-f4bbf435554e87de31c0a70039aa03b19962aaea.tar.gz
feat(optee): add device tree for coreboot table
This adds creation of a device tree that will be passed to OP-TEE. Currently that device tree only contains the coreboot table per the Linux coreboot device tree specification. This device tree is then passed to OP-TEE so it can extract the CBMEM console information from the coreboot table for logging purposes. Signed-off-by: Jeffrey Kardatzke <jkardatzke@google.com> Change-Id: I6a26d335e16f7226018c56ad571cca77b81b0f6a
-rw-r--r--include/lib/coreboot.h1
-rw-r--r--lib/coreboot/coreboot_table.c10
-rw-r--r--services/spd/opteed/opteed.mk1
-rw-r--r--services/spd/opteed/opteed_main.c104
4 files changed, 115 insertions, 1 deletions
diff --git a/include/lib/coreboot.h b/include/lib/coreboot.h
index 0aa65791d..42d4149aa 100644
--- a/include/lib/coreboot.h
+++ b/include/lib/coreboot.h
@@ -41,5 +41,6 @@ typedef enum {
coreboot_memory_t coreboot_get_memory_type(uintptr_t start, size_t size);
void coreboot_table_setup(void *base);
+void coreboot_get_table_location(uint64_t *address, uint32_t *size);
#endif /* COREBOOT_H */
diff --git a/lib/coreboot/coreboot_table.c b/lib/coreboot/coreboot_table.c
index fb31ef1e0..43e983590 100644
--- a/lib/coreboot/coreboot_table.c
+++ b/lib/coreboot/coreboot_table.c
@@ -46,6 +46,8 @@ typedef struct {
coreboot_memrange_t coreboot_memranges[COREBOOT_MAX_MEMRANGES];
coreboot_serial_t coreboot_serial;
+uint64_t coreboot_table_addr;
+uint32_t coreboot_table_size;
/*
* The coreboot table is parsed before the MMU is enabled (i.e. with strongly
@@ -108,6 +110,12 @@ coreboot_memory_t coreboot_get_memory_type(uintptr_t start, size_t size)
return CB_MEM_NONE;
}
+void coreboot_get_table_location(uint64_t *address, uint32_t *size)
+{
+ *address = coreboot_table_addr;
+ *size = coreboot_table_size;
+}
+
void coreboot_table_setup(void *base)
{
cb_header_t *header = base;
@@ -118,6 +126,8 @@ void coreboot_table_setup(void *base)
ERROR("coreboot table signature corrupt!\n");
return;
}
+ coreboot_table_addr = (uint64_t) base;
+ coreboot_table_size = header->header_bytes + header->table_bytes;
ptr = base + header->header_bytes;
for (i = 0; i < header->table_entries; i++) {
diff --git a/services/spd/opteed/opteed.mk b/services/spd/opteed/opteed.mk
index 477b45d98..f394744e9 100644
--- a/services/spd/opteed/opteed.mk
+++ b/services/spd/opteed/opteed.mk
@@ -31,4 +31,5 @@ $(warning "OPTEE_ALLOW_SMC_LOAD is enabled which may result in an insecure \
platform")
$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
$(eval $(call add_define,OPTEE_ALLOW_SMC_LOAD))
+include lib/libfdt/libfdt.mk
endif
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index f069775d2..4d055db17 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -24,9 +24,13 @@
#include <common/bl_common.h>
#include <common/debug.h>
#include <common/runtime_svc.h>
+#include <lib/coreboot.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/optee_utils.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
+#if OPTEE_ALLOW_SMC_LOAD
+#include <libfdt.h>
+#endif /* OPTEE_ALLOW_SMC_LOAD */
#include <plat/common/platform.h>
#include <tools_share/uuid.h>
@@ -51,6 +55,10 @@ static bool opteed_allow_load;
DEFINE_SVC_UUID2(optee_image_load_uuid,
0xb1eafba3, 0x5d31, 0x4612, 0xb9, 0x06,
0xc4, 0xc7, 0xa4, 0xbe, 0x3c, 0xc0);
+
+#define OPTEED_FDT_SIZE 256
+static uint8_t fdt_buf[OPTEED_FDT_SIZE] __aligned(CACHE_WRITEBACK_GRANULE);
+
#else
static int32_t opteed_init(void);
#endif
@@ -209,6 +217,91 @@ static int32_t opteed_init(void)
#endif /* !OPTEE_ALLOW_SMC_LOAD */
#if OPTEE_ALLOW_SMC_LOAD
+#if COREBOOT
+/*
+ * Adds a firmware/coreboot node with the coreboot table information to a device
+ * tree. Returns zero on success or if there is no coreboot table information;
+ * failure code otherwise.
+ */
+static int add_coreboot_node(void *fdt)
+{
+ int ret;
+ uint64_t coreboot_table_addr;
+ uint32_t coreboot_table_size;
+ struct {
+ uint64_t addr;
+ uint32_t size;
+ } reg_node;
+ coreboot_get_table_location(&coreboot_table_addr, &coreboot_table_size);
+ if (!coreboot_table_addr || !coreboot_table_size) {
+ WARN("Unable to get coreboot table location for device tree");
+ return 0;
+ }
+ ret = fdt_begin_node(fdt, "firmware");
+ if (ret)
+ return ret;
+
+ ret = fdt_property(fdt, "ranges", NULL, 0);
+ if (ret)
+ return ret;
+
+ ret = fdt_begin_node(fdt, "coreboot");
+ if (ret)
+ return ret;
+
+ ret = fdt_property_string(fdt, "compatible", "coreboot");
+ if (ret)
+ return ret;
+
+ reg_node.addr = cpu_to_fdt64(coreboot_table_addr);
+ reg_node.size = cpu_to_fdt32(coreboot_table_size);
+ ret = fdt_property(fdt, "reg", &reg_node,
+ sizeof(uint64_t) + sizeof(uint32_t));
+ if (ret)
+ return ret;
+
+ ret = fdt_end_node(fdt);
+ if (ret)
+ return ret;
+
+ return fdt_end_node(fdt);
+}
+#endif /* COREBOOT */
+
+/*
+ * Creates a device tree for passing into OP-TEE. Currently is populated with
+ * the coreboot table address.
+ * Returns 0 on success, error code otherwise.
+ */
+static int create_opteed_dt(void)
+{
+ int ret;
+
+ ret = fdt_create(fdt_buf, OPTEED_FDT_SIZE);
+ if (ret)
+ return ret;
+
+ ret = fdt_finish_reservemap(fdt_buf);
+ if (ret)
+ return ret;
+
+ ret = fdt_begin_node(fdt_buf, "");
+ if (ret)
+ return ret;
+
+#if COREBOOT
+ ret = add_coreboot_node(fdt_buf);
+ if (ret)
+ return ret;
+#endif /* COREBOOT */
+
+ ret = fdt_end_node(fdt_buf);
+ if (ret)
+ return ret;
+
+ return fdt_finish(fdt_buf);
+}
+
/*******************************************************************************
* This function is responsible for handling the SMC that loads the OP-TEE
* binary image via a non-secure SMC call. It takes the size and physical
@@ -232,6 +325,7 @@ static int32_t opteed_handle_smc_load(uint64_t data_size, uint32_t data_pa)
uint64_t target_size;
entry_point_info_t optee_ep_info;
uint32_t linear_id = plat_my_core_pos();
+ uint64_t dt_addr = 0;
mapped_data_pa = page_align(data_pa, DOWN);
mapped_data_va = mapped_data_pa;
@@ -292,12 +386,20 @@ static int32_t opteed_handle_smc_load(uint64_t data_size, uint32_t data_pa)
/* Save the non-secure state */
cm_el1_sysregs_context_save(NON_SECURE);
+ rc = create_opteed_dt();
+ if (rc) {
+ ERROR("Failed device tree creation %d\n", rc);
+ return rc;
+ }
+ dt_addr = (uint64_t)fdt_buf;
+ flush_dcache_range(dt_addr, OPTEED_FDT_SIZE);
+
opteed_init_optee_ep_state(&optee_ep_info,
opteed_rw,
image_pa,
0,
0,
- 0,
+ dt_addr,
&opteed_sp_context[linear_id]);
if (opteed_init_with_entry_point(&optee_ep_info) == 0) {
rc = -EFAULT;