mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-05-02 08:49:28 +00:00

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>
213 lines
5.4 KiB
C
213 lines
5.4 KiB
C
/*
|
|
* Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <assert.h>
|
|
|
|
#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"
|
|
|
|
#define MAP_BL31_TOTAL MAP_REGION_FLAT( \
|
|
BL31_BASE, \
|
|
BL31_END - BL31_BASE, \
|
|
MT_MEMORY | MT_RW | EL3_PAS)
|
|
#define MAP_BL31_RO MAP_REGION_FLAT( \
|
|
BL_CODE_BASE, \
|
|
BL_CODE_END - BL_CODE_BASE, \
|
|
MT_CODE | EL3_PAS), \
|
|
MAP_REGION_FLAT( \
|
|
BL_RO_DATA_BASE, \
|
|
BL_RO_DATA_END \
|
|
- BL_RO_DATA_BASE, \
|
|
MT_RO_DATA | EL3_PAS)
|
|
|
|
#if USE_COHERENT_MEM
|
|
#define MAP_BL_COHERENT_RAM MAP_REGION_FLAT( \
|
|
BL_COHERENT_RAM_BASE, \
|
|
BL_COHERENT_RAM_END \
|
|
- BL_COHERENT_RAM_BASE, \
|
|
MT_DEVICE | MT_RW | EL3_PAS)
|
|
#endif
|
|
|
|
/*
|
|
* Placeholder variables for copying the arguments that have been passed to
|
|
* BL3-1 from BL2.
|
|
*/
|
|
static entry_point_info_t bl32_image_ep_info;
|
|
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
|
|
* parameters passed by the calling EL (S-EL1 in BL2 & EL3 in BL1) before
|
|
* they are lost (potentially). This needs to be done before the MMU is
|
|
* initialized so that the memory layout can be used while creating page
|
|
* tables. BL2 has flushed this information to memory, so we are guaranteed
|
|
* to pick up good data.
|
|
******************************************************************************/
|
|
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
|
|
u_register_t arg2, u_register_t arg3)
|
|
{
|
|
/* Initialize the console to provide early debug support */
|
|
qemu_console_init();
|
|
|
|
/* Platform names have to be lowercase. */
|
|
#ifdef PLAT_qemu_sbsa
|
|
sip_svc_init();
|
|
#endif
|
|
|
|
/*
|
|
* Check params passed from BL2
|
|
*/
|
|
bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
|
|
|
|
assert(params_from_bl2);
|
|
assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
|
|
assert(params_from_bl2->h.version >= VERSION_2);
|
|
|
|
bl_params_node_t *bl_params = params_from_bl2->head;
|
|
|
|
/*
|
|
* Copy BL33, BL32 and RMM (if present), entry point information.
|
|
* They are stored in Secure RAM, in BL2's address space.
|
|
*/
|
|
while (bl_params) {
|
|
if (bl_params->image_id == BL32_IMAGE_ID)
|
|
bl32_image_ep_info = *bl_params->ep_info;
|
|
|
|
#if ENABLE_RME
|
|
if (bl_params->image_id == RMM_IMAGE_ID)
|
|
rmm_image_ep_info = *bl_params->ep_info;
|
|
#endif
|
|
|
|
if (bl_params->image_id == BL33_IMAGE_ID)
|
|
bl33_image_ep_info = *bl_params->ep_info;
|
|
|
|
bl_params = bl_params->next_params_info;
|
|
}
|
|
|
|
if (!bl33_image_ep_info.pc)
|
|
panic();
|
|
#if ENABLE_RME
|
|
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)
|
|
{
|
|
const mmap_region_t bl_regions[] = {
|
|
MAP_BL31_TOTAL,
|
|
MAP_BL31_RO,
|
|
#if USE_COHERENT_MEM
|
|
MAP_BL_COHERENT_RAM,
|
|
#endif
|
|
#if ENABLE_RME
|
|
MAP_GPT_L0_REGION,
|
|
MAP_GPT_L1_REGION,
|
|
MAP_RMM_SHARED_MEM,
|
|
#endif
|
|
{0}
|
|
};
|
|
|
|
setup_page_tables(bl_regions, plat_qemu_get_mmap());
|
|
|
|
enable_mmu_el3(0);
|
|
|
|
#if ENABLE_RME
|
|
/*
|
|
* Initialise Granule Protection library and enable GPC for the primary
|
|
* processor. The tables have already been initialized by a previous BL
|
|
* stage, so there is no need to provide any PAS here. This function
|
|
* sets up pointers to those tables.
|
|
*/
|
|
if (gpt_runtime_init() < 0) {
|
|
ERROR("gpt_runtime_init() failed!\n");
|
|
panic();
|
|
}
|
|
#endif /* ENABLE_RME */
|
|
|
|
}
|
|
|
|
static void qemu_gpio_init(void)
|
|
{
|
|
#ifdef SECURE_GPIO_BASE
|
|
pl061_gpio_init();
|
|
pl061_gpio_register(SECURE_GPIO_BASE, 0);
|
|
#endif
|
|
}
|
|
|
|
void bl31_platform_setup(void)
|
|
{
|
|
plat_qemu_gic_init();
|
|
qemu_gpio_init();
|
|
}
|
|
|
|
unsigned int plat_get_syscnt_freq2(void)
|
|
{
|
|
return SYS_COUNTER_FREQ_IN_TICKS;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Return a pointer to the 'entry_point_info' structure of the next image
|
|
* for the security state specified. BL3-3 corresponds to the non-secure
|
|
* image type while BL3-2 corresponds to the secure image type. A NULL
|
|
* pointer is returned if the image does not exist.
|
|
******************************************************************************/
|
|
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
|
|
{
|
|
entry_point_info_t *next_image_info;
|
|
|
|
assert(sec_state_is_valid(type));
|
|
if (type == NON_SECURE) {
|
|
next_image_info = &bl33_image_ep_info;
|
|
}
|
|
#if ENABLE_RME
|
|
else if (type == REALM) {
|
|
next_image_info = &rmm_image_ep_info;
|
|
}
|
|
#endif
|
|
else {
|
|
next_image_info = &bl32_image_ep_info;
|
|
}
|
|
|
|
/*
|
|
* None of the images on the ARM development platforms can have 0x0
|
|
* as the entrypoint
|
|
*/
|
|
if (next_image_info->pc)
|
|
return next_image_info;
|
|
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
|
|
}
|