From: Jens Wiklander Date: Tue, 22 Nov 2022 13:39:26 +0000 (+0100) Subject: feat(qemu): support s-el2 spmc X-Git-Tag: baikal/aarch64/sdk5.10~1^2~304^2~3 X-Git-Url: https://git.baikalelectronics.ru/?a=commitdiff_plain;h=36802e2c792f79ab630b53298dfd4f1e5a95d173;p=arm-tf.git feat(qemu): support s-el2 spmc 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 Signed-off-by: Olivier Deprez Signed-off-by: Jens Wiklander Change-Id: I4b61c4c048f31540d4f1ef9e05f0b12deb341e06 --- diff --git a/plat/qemu/common/qemu_bl2_mem_params_desc.c b/plat/qemu/common/qemu_bl2_mem_params_desc.c index 8d8047c92..bb1797d15 100644 --- a/plat/qemu/common/qemu_bl2_mem_params_desc.c +++ b/plat/qemu/common/qemu_bl2_mem_params_desc.c @@ -9,6 +9,18 @@ #include #include +#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 */ diff --git a/plat/qemu/common/qemu_bl2_setup.c b/plat/qemu/common/qemu_bl2_setup.c index 6afa3a44d..be5587714 100644 --- a/plat/qemu/common/qemu_bl2_setup.c +++ b/plat/qemu/common/qemu_bl2_setup.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/plat/qemu/common/qemu_io_storage.c b/plat/qemu/common/qemu_io_storage.c index e2d4932c0..4c61b1466 100644 --- a/plat/qemu/common/qemu_io_storage.c +++ b/plat/qemu/common/qemu_io_storage.c @@ -11,6 +11,8 @@ #include #include +#include +#include #include #include #include @@ -20,10 +22,13 @@ #include #include +#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; diff --git a/plat/qemu/common/qemu_private.h b/plat/qemu/common/qemu_private.h index c313cb63f..159c44f7a 100644 --- a/plat/qemu/common/qemu_private.h +++ b/plat/qemu/common/qemu_private.h @@ -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); diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h index 5c3239cb8..490c2dc7c 100644 --- a/plat/qemu/qemu/include/platform_def.h +++ b/plat/qemu/qemu/include/platform_def.h @@ -118,7 +118,9 @@ #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) /* diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk index 02493025a..cd8c06f19 100644 --- a/plat/qemu/qemu/platform.mk +++ b/plat/qemu/qemu/platform.mk @@ -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