Tegra: platform handler to relocate BL32 image

This patch provides platforms an opportunity to relocate the
BL32 image, during cold boot. Tegra186 platforms, for example,
relocate BL32 images to TZDRAM memory as the previous bootloader
relies on BL31 to do so.

Change-Id: Ibb864901e43aca5bf55d8c79e918b598c12e8a28
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
This commit is contained in:
Varun Wadekar 2018-06-20 14:30:59 -07:00
parent ee21281a5f
commit 6f47acdb3b
5 changed files with 52 additions and 36 deletions

View File

@ -35,8 +35,6 @@
/* length of Trusty's input parameters (in bytes) */
#define TRUSTY_PARAMS_LEN_BYTES (4096*2)
extern void memcpy16(void *dest, const void *src, unsigned int length);
/*******************************************************************************
* Declarations of linker defined symbols which will help us find the layout
* of trusted SRAM
@ -102,7 +100,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
{
struct tegra_bl31_params *arg_from_bl2 = (struct tegra_bl31_params *) arg0;
plat_params_from_bl2_t *plat_params = (plat_params_from_bl2_t *)arg1;
image_info_t bl32_img_info = { {0} };
int32_t ret;
/*
@ -195,42 +192,14 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
tegra_memctrl_tzdram_setup(plat_bl31_params_from_bl2.tzdram_base,
(uint32_t)plat_bl31_params_from_bl2.tzdram_size);
#if RELOCATE_BL32_IMAGE
/*
* The previous bootloader might not have placed the BL32 image
* inside the TZDRAM. We check the BL32 image info to find out
* the base/PC values and relocate the image if necessary.
* inside the TZDRAM. Platform handler to allow relocation of BL32
* image to TZDRAM memory. This behavior might change per platform.
*/
if (arg_from_bl2->bl32_image_info != NULL) {
uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end;
bl32_img_info = *arg_from_bl2->bl32_image_info;
/* Relocate BL32 if it resides outside of the TZDRAM */
tzdram_start = plat_bl31_params_from_bl2.tzdram_base;
tzdram_end = plat_bl31_params_from_bl2.tzdram_base +
plat_bl31_params_from_bl2.tzdram_size;
bl32_start = bl32_img_info.image_base;
bl32_end = bl32_img_info.image_base + bl32_img_info.image_size;
assert(tzdram_end > tzdram_start);
assert(bl32_end > bl32_start);
assert(bl32_image_ep_info.pc > tzdram_start);
assert(bl32_image_ep_info.pc < tzdram_end);
/* relocate BL32 */
if ((bl32_start >= tzdram_end) || (bl32_end <= tzdram_start)) {
INFO("Relocate BL32 to TZDRAM\n");
(void)memcpy16((void *)(uintptr_t)bl32_image_ep_info.pc,
(void *)(uintptr_t)bl32_start,
bl32_img_info.image_size);
/* clean up non-secure intermediate buffer */
zeromem((void *)(uintptr_t)bl32_start,
bl32_img_info.image_size);
}
}
plat_relocate_bl32_image(arg_from_bl2->bl32_image_info);
#endif
/*
* Add timestamp for platform early setup exit.

View File

@ -77,6 +77,7 @@ struct tegra_bl31_params *plat_get_bl31_params(void);
plat_params_from_bl2_t *plat_get_bl31_plat_params(void);
void plat_early_platform_setup(void);
void plat_late_platform_setup(void);
void plat_relocate_bl32_image(const image_info_t *bl32_img_info);
/* Declarations for plat_secondary.c */
void plat_secondary_setup(void);

View File

@ -42,10 +42,14 @@ OVERRIDE_LIBC := 1
# prior to Tegra186
ENABLE_WDT_LEGACY_FIQ_HANDLING ?= 0
# Flag to allow relocation of BL32 image to TZDRAM during boot
RELOCATE_BL32_IMAGE ?= 0
include plat/nvidia/tegra/common/tegra_common.mk
include ${SOC_DIR}/platform_${TARGET_SOC}.mk
$(eval $(call add_define,ENABLE_WDT_LEGACY_FIQ_HANDLING))
$(eval $(call add_define,RELOCATE_BL32_IMAGE))
# modify BUILD_PLAT to point to SoC specific build directory
BUILD_PLAT := ${BUILD_BASE}/${PLAT}/${TARGET_SOC}/${BUILD_TYPE}

View File

@ -12,6 +12,7 @@
#include <bl31/interrupt_mgmt.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <common/ep_info.h>
#include <common/interrupt_props.h>
#include <context.h>
#include <cortex_a57.h>
@ -20,6 +21,7 @@
#include <drivers/arm/gicv2.h>
#include <drivers/console.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
@ -28,6 +30,8 @@
#include <tegra_platform.h>
#include <tegra_private.h>
extern void memcpy16(void *dest, const void *src, unsigned int length);
/*******************************************************************************
* Tegra186 CPU numbers in cluster #0
*******************************************************************************
@ -286,3 +290,39 @@ int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
return ret;
}
void plat_relocate_bl32_image(const image_info_t *bl32_img_info)
{
const plat_params_from_bl2_t *plat_bl31_params = plat_get_bl31_plat_params();
const entry_point_info_t *bl32_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end;
if ((bl32_img_info != NULL) && (bl32_ep_info != NULL)) {
/* Relocate BL32 if it resides outside of the TZDRAM */
tzdram_start = plat_bl31_params->tzdram_base;
tzdram_end = plat_bl31_params->tzdram_base +
plat_bl31_params->tzdram_size;
bl32_start = bl32_img_info->image_base;
bl32_end = bl32_img_info->image_base + bl32_img_info->image_size;
assert(tzdram_end > tzdram_start);
assert(bl32_end > bl32_start);
assert(bl32_ep_info->pc > tzdram_start);
assert(bl32_ep_info->pc < tzdram_end);
/* relocate BL32 */
if ((bl32_start >= tzdram_end) || (bl32_end <= tzdram_start)) {
INFO("Relocate BL32 to TZDRAM\n");
(void)memcpy16((void *)(uintptr_t)bl32_ep_info->pc,
(void *)(uintptr_t)bl32_start,
bl32_img_info->image_size);
/* clean up non-secure intermediate buffer */
zeromem((void *)(uintptr_t)bl32_start,
bl32_img_info->image_size);
}
}
}

View File

@ -18,6 +18,8 @@ PROGRAMMABLE_RESET_ADDRESS := 1
COLD_BOOT_SINGLE_CPU := 1
RELOCATE_BL32_IMAGE := 1
# platform settings
TZDRAM_BASE := 0x30000000
$(eval $(call add_define,TZDRAM_BASE))