]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
feat(qemu): support s-el2 spmc
authorJens Wiklander <jens.wiklander@linaro.org>
Tue, 22 Nov 2022 13:39:26 +0000 (14:39 +0100)
committerJens Wiklander <jens.wiklander@linaro.org>
Thu, 8 Dec 2022 14:40:03 +0000 (15:40 +0100)
Supports S-EL2 SPMC + S-EL1 SP on qemu. S-EL1 SPs packaged in .pkg files
are added to the FIP as blob with an UUID. BL2 parses TB_FW_CONFIG to
know which SP blobs to load into memory.

Co-developed-by: Olivier Deprez <olivier.deprez@arm.com>
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Change-Id: I4b61c4c048f31540d4f1ef9e05f0b12deb341e06

plat/qemu/common/qemu_bl2_mem_params_desc.c
plat/qemu/common/qemu_bl2_setup.c
plat/qemu/common/qemu_io_storage.c
plat/qemu/common/qemu_private.h
plat/qemu/qemu/include/platform_def.h
plat/qemu/qemu/platform.mk

index 8d8047c92964bea15db8ebdc47d25539817af986..bb1797d1505359c3081109f8700e6cb7accd922c 100644 (file)
@@ -9,6 +9,18 @@
 #include <common/desc_image_load.h>
 #include <plat/common/platform.h>
 
+#define SP_PKG_ENTRY(id) \
+       { \
+               .image_id = (id), \
+               SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY, VERSION_2, \
+                                     entry_point_info_t, \
+                                     SECURE | NON_EXECUTABLE), \
+               SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, \
+                                     VERSION_2, image_info_t, \
+                                     IMAGE_ATTRIB_SKIP_LOADING), \
+               .next_handoff_image_id = INVALID_IMAGE_ID, \
+       }
+
 /*******************************************************************************
  * Following descriptor provides BL image/ep information that gets used
  * by BL2 to load the images and also subset of this information is
@@ -136,8 +148,34 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
                                         TOS_FW_CONFIG_BASE,
            .next_handoff_image_id = INVALID_IMAGE_ID,
        },
-#endif
 
+#if SPMD_SPM_AT_SEL2
+       /* Fill TB_FW_CONFIG related information */
+       {
+           .image_id = TB_FW_CONFIG_ID,
+           SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+                   VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+           SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+                   VERSION_2, image_info_t, 0),
+           .image_info.image_base = TB_FW_CONFIG_BASE,
+           .image_info.image_max_size = TB_FW_CONFIG_LIMIT - TB_FW_CONFIG_BASE,
+           .next_handoff_image_id = INVALID_IMAGE_ID,
+       },
+
+       /*
+        * Empty entries for SP packages to be filled in according to
+        * TB_FW_CONFIG.
+        */
+       SP_PKG_ENTRY(SP_PKG1_ID),
+       SP_PKG_ENTRY(SP_PKG2_ID),
+       SP_PKG_ENTRY(SP_PKG3_ID),
+       SP_PKG_ENTRY(SP_PKG4_ID),
+       SP_PKG_ENTRY(SP_PKG5_ID),
+       SP_PKG_ENTRY(SP_PKG6_ID),
+       SP_PKG_ENTRY(SP_PKG7_ID),
+       SP_PKG_ENTRY(SP_PKG8_ID),
+#endif
+#endif
 # endif /* QEMU_LOAD_BL32 */
 
        /* Fill BL33 related information */
index 6afa3a44d5497955d6e1ec5c5002eba826a45132..be5587714a4eac6bed341e64bf5491df01baeaaa 100644 (file)
@@ -16,6 +16,7 @@
 #include <common/debug.h>
 #include <common/desc_image_load.h>
 #include <common/fdt_fixup.h>
+#include <common/fdt_wrappers.h>
 #include <lib/optee_utils.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
@@ -140,6 +141,48 @@ static uint32_t qemu_get_spsr_for_bl33_entry(void)
        return spsr;
 }
 
+#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+static int load_sps_from_tb_fw_config(struct image_info *image_info)
+{
+       void *dtb = (void *)image_info->image_base;
+       const char *compat_str = "arm,sp";
+       const struct fdt_property *uuid;
+       uint32_t load_addr;
+       const char *name;
+       int sp_node;
+       int node;
+
+       node = fdt_node_offset_by_compatible(dtb, -1, compat_str);
+       if (node < 0) {
+               ERROR("Can't find %s in TB_FW_CONFIG", compat_str);
+               return -1;
+       }
+
+       fdt_for_each_subnode(sp_node, dtb, node) {
+               name = fdt_get_name(dtb, sp_node, NULL);
+               if (name == NULL) {
+                       ERROR("Can't get name of node in dtb\n");
+                       return -1;
+               }
+               uuid = fdt_get_property(dtb, sp_node, "uuid", NULL);
+               if (uuid == NULL) {
+                       ERROR("Can't find property uuid in node %s", name);
+                       return -1;
+               }
+               if (fdt_read_uint32(dtb, sp_node, "load-address",
+                                   &load_addr) < 0) {
+                       ERROR("Can't read load-address in node %s", name);
+                       return -1;
+               }
+               if (qemu_io_register_sp_pkg(name, uuid->data, load_addr) < 0) {
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+#endif /*defined(SPD_spmd) && SPMD_SPM_AT_SEL2*/
+
 static int qemu_bl2_handle_post_image_load(unsigned int image_id)
 {
        int err = 0;
@@ -224,7 +267,12 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
 
                bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry();
                break;
-#if defined(SPD_spmd)
+#ifdef SPD_spmd
+#if SPMD_SPM_AT_SEL2
+       case TB_FW_CONFIG_ID:
+               err = load_sps_from_tb_fw_config(&bl_mem_params->image_info);
+               break;
+#endif
        case TOS_FW_CONFIG_ID:
                /* An SPMC expects TOS_FW_CONFIG in x0/r0 */
                bl32_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID);
index e2d4932c0860121aa996b91c2d6d42d43366dce7..4c61b14668285d8e34b9d60342657da22d0d2b35 100644 (file)
@@ -11,6 +11,8 @@
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <common/uuid.h>
 #include <drivers/io/io_driver.h>
 #include <drivers/io/io_encrypted.h>
 #include <drivers/io/io_fip.h>
 #include <lib/semihosting.h>
 #include <tools_share/firmware_image_package.h>
 
+#include "qemu_private.h"
+
 /* Semihosting filenames */
 #define BL2_IMAGE_NAME                 "bl2.bin"
 #define BL31_IMAGE_NAME                        "bl31.bin"
 #define BL32_IMAGE_NAME                        "bl32.bin"
+#define TB_FW_CONFIG_NAME              "tb_fw_config.dtb"
 #define TOS_FW_CONFIG_NAME             "tos_fw_config.dtb"
 #define BL32_EXTRA1_IMAGE_NAME         "bl32_extra1.bin"
 #define BL32_EXTRA2_IMAGE_NAME         "bl32_extra2.bin"
@@ -79,6 +84,10 @@ static const io_uuid_spec_t bl32_extra2_uuid_spec = {
        .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
 };
 
+static const io_uuid_spec_t tb_fw_config_uuid_spec = {
+       .uuid = UUID_TB_FW_CONFIG,
+};
+
 static const io_uuid_spec_t tos_fw_config_uuid_spec = {
        .uuid = UUID_TOS_FW_CONFIG,
 };
@@ -142,6 +151,10 @@ static const io_file_spec_t sh_file_spec[] = {
                .path = BL32_EXTRA2_IMAGE_NAME,
                .mode = FOPEN_MODE_RB
        },
+       [TB_FW_CONFIG_ID] = {
+               .path = TB_FW_CONFIG_NAME,
+               .mode = FOPEN_MODE_RB
+       },
        [TOS_FW_CONFIG_ID] = {
                .path = TOS_FW_CONFIG_NAME,
                .mode = FOPEN_MODE_RB
@@ -261,6 +274,11 @@ static const struct plat_io_policy policies[] = {
                open_fip
        },
 #endif
+       [TB_FW_CONFIG_ID] = {
+               &fip_dev_handle,
+               (uintptr_t)&tb_fw_config_uuid_spec,
+               open_fip
+       },
        [TOS_FW_CONFIG_ID] = {
                &fip_dev_handle,
                (uintptr_t)&tos_fw_config_uuid_spec,
@@ -315,6 +333,80 @@ static const struct plat_io_policy policies[] = {
 #endif /* TRUSTED_BOARD_BOOT */
 };
 
+#if defined(SPD_spmd)
+static struct sp_pkg {
+       struct plat_io_policy policy;
+       io_file_spec_t sh_file_spec;
+       uint8_t uuid[UUID_BYTES_LENGTH];
+       char path[80];
+} sp_pkgs[MAX_SP_IDS];
+static unsigned int sp_pkg_count;
+
+int qemu_io_register_sp_pkg(const char *name, const char *uuid,
+                           uintptr_t load_addr)
+{
+       struct sp_pkg *pkg;
+       bl_mem_params_node_t *mem_params;
+
+       if (sp_pkg_count == MAX_SP_IDS) {
+               INFO("Reached Max number of SPs\n");
+               return -1;
+       }
+       mem_params = get_bl_mem_params_node(SP_PKG1_ID + sp_pkg_count);
+       if (mem_params == NULL) {
+               ERROR("Can't find SP_PKG ID %u (SP_PKG%u_ID)\n",
+                     SP_PKG1_ID + sp_pkg_count, sp_pkg_count);
+               return -1;
+       }
+       pkg = sp_pkgs + sp_pkg_count;
+
+       if (read_uuid(pkg->uuid, (char *)uuid)) {
+               return -1;
+       }
+
+       strlcpy(pkg->path, name, sizeof(pkg->path));
+       strlcat(pkg->path, ".pkg", sizeof(pkg->path));
+
+       pkg->policy.dev_handle = &fip_dev_handle;
+       pkg->policy.image_spec = (uintptr_t)&pkg->uuid;
+       pkg->policy.check = open_fip;
+       pkg->sh_file_spec.path = pkg->path;
+       pkg->sh_file_spec.mode = FOPEN_MODE_RB;
+
+       mem_params->image_info.image_base = load_addr;
+       mem_params->image_info.image_max_size = SZ_4M;
+       mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
+
+       sp_pkg_count++;
+
+       return 0;
+}
+#endif /*SPD_spmd*/
+
+static const io_file_spec_t *get_io_file_spec(unsigned int image_id)
+{
+#if defined(SPD_spmd)
+       if (image_id >= SP_PKG1_ID && image_id <= SP_PKG8_ID) {
+               return &sp_pkgs[image_id - SP_PKG1_ID].sh_file_spec;
+       }
+#endif
+
+       assert(image_id < ARRAY_SIZE(sh_file_spec));
+       return &sh_file_spec[image_id];
+}
+
+static const struct plat_io_policy *get_io_policy(unsigned int image_id)
+{
+#if defined(SPD_spmd)
+       if (image_id >= SP_PKG1_ID && image_id <= SP_PKG8_ID) {
+               return &sp_pkgs[image_id - SP_PKG1_ID].policy;
+       }
+#endif
+
+       assert(image_id < ARRAY_SIZE(policies));
+       return &policies[image_id];
+}
+
 static int open_fip(const uintptr_t spec)
 {
        int result;
@@ -427,11 +519,13 @@ void plat_qemu_io_setup(void)
 static int get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle,
                                  uintptr_t *image_spec)
 {
-       int result = open_semihosting((const uintptr_t)&sh_file_spec[image_id]);
+       const io_file_spec_t *spec = get_io_file_spec(image_id);
+       int result;
 
+       result = open_semihosting((const uintptr_t)spec);
        if (result == 0) {
                *dev_handle = sh_dev_handle;
-               *image_spec = (uintptr_t)&sh_file_spec[image_id];
+               *image_spec = (uintptr_t)spec;
        }
 
        return result;
@@ -444,12 +538,9 @@ static int get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle,
 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
                          uintptr_t *image_spec)
 {
+       const struct plat_io_policy *policy = get_io_policy(image_id);
        int result;
-       const struct plat_io_policy *policy;
-
-       assert(image_id < ARRAY_SIZE(policies));
 
-       policy = &policies[image_id];
        result = policy->check(policy->image_spec);
        if (result == 0) {
                *image_spec = policy->image_spec;
index c313cb63f2a823b76d86004f0f6dcf229c2337af..159c44f7a51a208eab49cab4195cce1e233c08b7 100644 (file)
@@ -26,6 +26,8 @@ void qemu_configure_mmu_el3(unsigned long total_base, unsigned long total_size,
                        unsigned long coh_start, unsigned long coh_limit);
 
 void plat_qemu_io_setup(void);
+int qemu_io_register_sp_pkg(const char *name, const char *uuid,
+                           uintptr_t load_addr);
 unsigned int plat_qemu_calc_core_pos(u_register_t mpidr);
 
 void qemu_console_init(void);
index 5c3239cb88fd72ce3a60d4ade720cc17724e8b56..490c2dc7c3f86eecedc812077a6a550534d5078a 100644 (file)
 #define BL_RAM_BASE                    (SHARED_RAM_BASE + SHARED_RAM_SIZE)
 #define BL_RAM_SIZE                    (SEC_SRAM_SIZE - SHARED_RAM_SIZE)
 
-#define TOS_FW_CONFIG_BASE             BL_RAM_BASE
+#define TB_FW_CONFIG_BASE              BL_RAM_BASE
+#define TB_FW_CONFIG_LIMIT             (TB_FW_CONFIG_BASE + PAGE_SIZE)
+#define TOS_FW_CONFIG_BASE             TB_FW_CONFIG_LIMIT
 #define TOS_FW_CONFIG_LIMIT            (TOS_FW_CONFIG_BASE + PAGE_SIZE)
 
 /*
index 02493025aef6ec86d4ff662c25ec6eea72dae52a..cd8c06f19b6fa99b47ebaa988d2e296bd18c8879 100644 (file)
@@ -162,7 +162,8 @@ BL2_SOURCES         +=      drivers/io/io_semihosting.c             \
                                ${PLAT_QEMU_COMMON_PATH}/qemu_image_load.c              \
                                common/fdt_fixup.c                                      \
                                common/fdt_wrappers.c                                   \
-                               common/desc_image_load.c
+                               common/desc_image_load.c                                \
+                               common/uuid.c
 
 ifeq ($(add-lib-optee),yes)
 BL2_SOURCES            +=      lib/optee/optee_utils.c
@@ -236,6 +237,13 @@ $(eval $(call TOOL_ADD_IMG,bl32_extra2,--tos-fw-extra2))
 endif
 endif
 
+ifneq ($(QEMU_TB_FW_CONFIG_DTS),)
+FDT_SOURCES            +=      ${QEMU_TB_FW_CONFIG_DTS}
+QEMU_TB_FW_CONFIG      :=      ${BUILD_PLAT}/fdts/$(notdir $(basename ${QEMU_TB_FW_CONFIG_DTS})).dtb
+# Add the TB_FW_CONFIG to FIP
+$(eval $(call TOOL_ADD_PAYLOAD,${QEMU_TB_FW_CONFIG},--tb-fw-config,${QEMU_TB_FW_CONFIG}))
+endif
+
 ifneq ($(QEMU_TOS_FW_CONFIG_DTS),)
 FDT_SOURCES            +=      ${QEMU_TOS_FW_CONFIG_DTS}
 QEMU_TOS_FW_CONFIG     :=      ${BUILD_PLAT}/fdts/$(notdir $(basename ${QEMU_TOS_FW_CONFIG_DTS})).dtb