]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
feat(optee): add device tree for coreboot table
authorJeffrey Kardatzke <jkardatzke@google.com>
Thu, 9 Feb 2023 18:45:35 +0000 (10:45 -0800)
committerManish Pandey <manish.pandey2@arm.com>
Thu, 11 May 2023 08:46:57 +0000 (10:46 +0200)
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

include/lib/coreboot.h
lib/coreboot/coreboot_table.c
services/spd/opteed/opteed.mk
services/spd/opteed/opteed_main.c

index 0aa65791dd2150c958b386778b3fd3aa590f32f3..42d4149aaf4b308a5dba218db64d5111710c3417 100644 (file)
@@ -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 */
index fb31ef1e078db7710fcdb7b3eeaadf210ab7bd1c..43e9835903725427f5b1213b922f4b3cea9f0a48 100644 (file)
@@ -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++) {
index 477b45d98ea501e10a89ba33c051c318e7b4fbf5..f394744e90ce8f02c94881218c972418183f6d0c 100644 (file)
@@ -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
index f069775d2402ee4c203970ebd49049c7ba3e3c17..4d055db176f3de82e3bb6ee1f8d6627a96ed26e0 100644 (file)
 #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;