feat(qemu): enable transfer list to BL31/32

Enable handoff to BL31 and BL32 using transfer list.
Encode TL_TAG_OPTEE_PAGABLE_PART as transfer entry.
Fallback to default handoff args when transfer list is disabled or
fails to archieve args from transfer entries.
Refactor handoff from BL2 to BL33.
Minor fixes of comment style.

Change-Id: I55d92ca7f5c4727bacc9725a7216c0ac70d16aec
Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
This commit is contained in:
Raymond Mao 2023-10-04 09:58:29 -07:00
parent 0e8def996e
commit 305825b490
2 changed files with 74 additions and 33 deletions

View file

@ -19,9 +19,7 @@
#include <common/fdt_fixup.h>
#include <common/fdt_wrappers.h>
#include <lib/optee_utils.h>
#if TRANSFER_LIST
#include <lib/transfer_list.h>
#endif
#include <lib/utils.h>
#include <plat/common/platform.h>
#if ENABLE_RME
@ -55,9 +53,7 @@
/* Data structure which holds the extents of the trusted SRAM for BL2 */
static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
#if TRANSFER_LIST
static struct transfer_list_header *bl2_tl;
#endif
void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
@ -122,7 +118,7 @@ static void update_dt(void)
ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, ret);
#if TRANSFER_LIST
// create a TE
/* create a TE */
te = transfer_list_add(bl2_tl, TL_TAG_FDT, fdt_totalsize(fdt), fdt);
if (!te) {
ERROR("Failed to add FDT entry to Transfer List\n");
@ -321,6 +317,23 @@ static int load_sps_from_tb_fw_config(struct image_info *image_info)
}
#endif /*defined(SPD_spmd) && SPMD_SPM_AT_SEL2*/
#if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) || defined(SPMC_OPTEE)
static int handoff_pageable_part(uint64_t pagable_part)
{
#if TRANSFER_LIST
struct transfer_list_entry *te;
te = transfer_list_add(bl2_tl, TL_TAG_OPTEE_PAGABLE_PART,
sizeof(pagable_part), &pagable_part);
if (!te) {
INFO("Cannot add TE for pageable part\n");
return -1;
}
#endif
return 0;
}
#endif
static int qemu_bl2_handle_post_image_load(unsigned int image_id)
{
int err = 0;
@ -334,12 +347,24 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
#endif
#if TRANSFER_LIST
struct transfer_list_header *ns_tl = NULL;
struct transfer_list_entry *te = NULL;
#endif
assert(bl_mem_params);
switch (image_id) {
#if TRANSFER_LIST
case BL31_IMAGE_ID:
/*
* arg0 is a bl_params_t reserved for bl31_early_platform_setup2
* we just need arg1 and arg3 for BL31 to update th TL from S
* to NS memory before it exits
*/
bl_mem_params->ep_info.args.arg1 =
TRANSFER_LIST_SIGNATURE |
REGISTER_CONVENTION_VERSION_MASK;
bl_mem_params->ep_info.args.arg3 = (uintptr_t)bl2_tl;
break;
#endif
case BL32_IMAGE_ID:
#if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) || defined(SPMC_OPTEE)
pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
@ -354,8 +379,21 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
if (err != 0) {
WARN("OPTEE header parse error.\n");
}
/* add TL_TAG_OPTEE_PAGABLE_PART entry to the TL */
if (handoff_pageable_part(bl_mem_params->ep_info.args.arg1)) {
return -1;
}
#endif
INFO("Handoff to BL32\n");
bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl32_entry();
if (TRANSFER_LIST &&
transfer_list_set_handoff_args(bl2_tl,
&bl_mem_params->ep_info))
break;
INFO("Using default arguments\n");
#if defined(SPMC_OPTEE)
/*
* Explicit zeroes to unused registers since they may have
@ -379,7 +417,6 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
bl_mem_params->ep_info.args.arg2 = ARM_PRELOADED_DTB_BASE;
bl_mem_params->ep_info.args.arg3 = 0;
#endif
bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl32_entry();
break;
case BL33_IMAGE_ID:
@ -406,7 +443,7 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
bl_mem_params->ep_info.args.arg3 = 0U;
#elif TRANSFER_LIST
if (bl2_tl) {
// relocate the tl to pre-allocate NS memory
/* relocate the tl to pre-allocate NS memory */
ns_tl = transfer_list_relocate(bl2_tl,
(void *)(uintptr_t)FW_NS_HANDOFF_BASE,
bl2_tl->max_size);
@ -415,37 +452,18 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
(unsigned long)FW_NS_HANDOFF_BASE);
return -1;
}
NOTICE("Transfer list handoff to BL33\n");
transfer_list_dump(ns_tl);
}
te = transfer_list_find(ns_tl, TL_TAG_FDT);
bl_mem_params->ep_info.args.arg1 =
TRANSFER_LIST_SIGNATURE |
REGISTER_CONVENTION_VERSION_MASK;
bl_mem_params->ep_info.args.arg3 = (uintptr_t)ns_tl;
if (GET_RW(bl_mem_params->ep_info.spsr) == MODE_RW_32) {
// aarch32
bl_mem_params->ep_info.args.arg0 = 0;
bl_mem_params->ep_info.args.arg2 = te ?
(uintptr_t)transfer_list_entry_data(te)
: 0;
} else {
// aarch64
bl_mem_params->ep_info.args.arg0 = te ?
(uintptr_t)transfer_list_entry_data(te)
: 0;
bl_mem_params->ep_info.args.arg2 = 0;
}
} else {
// Legacy handoff
INFO("Handoff to BL33\n");
if (!transfer_list_set_handoff_args(ns_tl,
&bl_mem_params->ep_info)) {
INFO("Invalid TL, fallback to default arguments\n");
bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
}
#else
/* BL33 expects to receive the primary CPU MPID (through r0) */
bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
#endif // ARM_LINUX_KERNEL_AS_BL33
#endif /* ARM_LINUX_KERNEL_AS_BL33 */
break;
#ifdef SPD_spmd

View file

@ -9,6 +9,7 @@
#include <common/bl_common.h>
#include <drivers/arm/pl061_gpio.h>
#include <lib/gpt_rme/gpt_rme.h>
#include <lib/transfer_list.h>
#include <plat/common/platform.h>
#include "qemu_private.h"
@ -44,6 +45,7 @@ static entry_point_info_t bl33_image_ep_info;
#if ENABLE_RME
static entry_point_info_t rmm_image_ep_info;
#endif
static struct transfer_list_header *bl31_tl;
/*******************************************************************************
* Perform any BL3-1 early platform setup. Here is an opportunity to copy
@ -100,6 +102,12 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
if (!rmm_image_ep_info.pc)
panic();
#endif
if (TRANSFER_LIST && arg1 == (TRANSFER_LIST_SIGNATURE |
REGISTER_CONVENTION_VERSION_MASK) &&
transfer_list_check_header((void *)arg3) != TL_OPS_NON) {
bl31_tl = (void *)arg3; /* saved TL address from BL2 */
}
}
void bl31_plat_arch_setup(void)
@ -188,3 +196,18 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
else
return NULL;
}
void bl31_plat_runtime_setup(void)
{
console_switch_state(CONSOLE_FLAG_RUNTIME);
#if TRANSFER_LIST
if (bl31_tl) {
/*
* update the TL from S to NS memory before jump to BL33
* to reflect all changes in TL done by BL32
*/
memcpy((void *)FW_NS_HANDOFF_BASE, bl31_tl, bl31_tl->max_size);
}
#endif
}