bl2-el3: Add BL2 at EL3 support in FVP

This patch add supports for the new API added for BL2 at EL3 for
FVP. We don't have a non-TF Boot ROM for FVP, but this option can be
tested setting specific parameters in the model.

The bl2 image is loaded directly in memory instead of being loaded
by a non-TF Boot ROM and the reset address is changed:

	--data cluster0.cpu0=bl2.bin@0x4001000
	-C cluster0.cpu0.RVBAR=0x4001000

These parameters mean that in the cold boot path the processor will
jump to BL2 again. For this reason, BL2 is loaded in dram in this
case, to avoid other images reclaiming BL2 memory.

Change-Id: Ieb2ff8535a9e67ccebcd8c2212cad366e7776422
Signed-off-by: Roberto Vargas <roberto.vargas@arm.com>
This commit is contained in:
Roberto Vargas 2017-11-17 13:22:18 +00:00
parent b1d27b484f
commit 81528dbcf1
6 changed files with 141 additions and 0 deletions

View File

@ -334,6 +334,11 @@
#define BL2_BASE (BL1_RW_BASE - PLAT_ARM_MAX_BL2_SIZE)
#define BL2_LIMIT BL1_RW_BASE
#elif BL2_AT_EL3
#define BL2_BASE ARM_BL_RAM_BASE
#define BL2_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
#elif defined(AARCH32) || JUNO_AARCH32_EL3_RUNTIME
/*
* Put BL2 just below BL32.

View File

@ -145,6 +145,10 @@ uint32_t arm_get_spsr_for_bl32_entry(void);
uint32_t arm_get_spsr_for_bl33_entry(void);
int arm_bl2_handle_post_image_load(unsigned int image_id);
/* BL2 at EL3 functions */
void arm_bl2_el3_early_platform_setup(void);
void arm_bl2_el3_plat_arch_setup(void);
/* BL2U utility functions */
void arm_bl2u_early_platform_setup(struct meminfo *mem_layout,
void *plat_info);

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <plat_arm.h>
#include "fvp_private.h"
void bl2_el3_early_platform_setup(u_register_t arg0 __unused,
u_register_t arg1 __unused,
u_register_t arg2 __unused,
u_register_t arg3 __unused)
{
arm_bl2_el3_early_platform_setup();
/* Initialize the platform config for future decision making */
fvp_config_setup();
/*
* Initialize Interconnect for this cluster during cold boot.
* No need for locks as no other CPU is active.
*/
fvp_interconnect_init();
/*
* Enable coherency in Interconnect for the primary CPU's cluster.
*/
fvp_interconnect_enable();
}

View File

@ -126,6 +126,13 @@ BL2_SOURCES += drivers/io/io_semihosting.c \
plat/arm/board/fvp/fvp_trusted_boot.c \
${FVP_SECURITY_SOURCES}
ifeq (${BL2_AT_EL3},1)
BL2_SOURCES += plat/arm/board/fvp/${ARCH}/fvp_helpers.S \
plat/arm/board/fvp/fvp_bl2_el3_setup.c \
${FVP_CPU_LIBS} \
${FVP_INTERCONNECT_SOURCES}
endif
ifeq (${FVP_USE_SP804_TIMER},1)
BL2_SOURCES += drivers/arm/sp804/sp804_delay_timer.c
endif

View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <console.h>
#include <generic_delay_timer.h>
#include <plat_arm.h>
#include <platform.h>
#pragma weak bl2_el3_early_platform_setup
#pragma weak bl2_el3_plat_arch_setup
#pragma weak bl2_el3_plat_prepare_exit
static meminfo_t bl2_el3_tzram_layout;
/*
* Perform arm specific early platform setup. At this moment we only initialize
* the console and the memory layout.
*/
void arm_bl2_el3_early_platform_setup(void)
{
/* Initialize the console to provide early debug support */
console_init(PLAT_ARM_BOOT_UART_BASE, PLAT_ARM_BOOT_UART_CLK_IN_HZ,
ARM_CONSOLE_BAUDRATE);
/*
* Allow BL2 to see the whole Trusted RAM. This is determined
* statically since we cannot rely on BL1 passing this information
* in the BL2_AT_EL3 case.
*/
bl2_el3_tzram_layout.total_base = ARM_BL_RAM_BASE;
bl2_el3_tzram_layout.total_size = ARM_BL_RAM_SIZE;
/* Initialise the IO layer and register platform IO devices */
plat_arm_io_setup();
}
void bl2_el3_early_platform_setup(u_register_t arg0 __unused,
u_register_t arg1 __unused,
u_register_t arg2 __unused,
u_register_t arg3 __unused)
{
arm_bl2_el3_early_platform_setup();
/*
* Initialize Interconnect for this cluster during cold boot.
* No need for locks as no other CPU is active.
*/
plat_arm_interconnect_init();
/*
* Enable Interconnect coherency for the primary CPU's cluster.
*/
plat_arm_interconnect_enter_coherency();
generic_delay_timer_init();
}
/*******************************************************************************
* Perform the very early platform specific architectural setup here. At the
* moment this is only initializes the mmu in a quick and dirty way.
******************************************************************************/
void arm_bl2_el3_plat_arch_setup(void)
{
arm_setup_page_tables(bl2_el3_tzram_layout.total_base,
bl2_el3_tzram_layout.total_size,
BL_CODE_BASE,
BL_CODE_END,
BL_RO_DATA_BASE,
BL_RO_DATA_END
#if USE_COHERENT_MEM
, BL_COHERENT_RAM_BASE,
BL_COHERENT_RAM_END
#endif
);
#ifdef AARCH32
enable_mmu_secure(0);
#else
enable_mmu_el3(0);
#endif
}
void bl2_el3_plat_arch_setup(void)
{
arm_bl2_el3_plat_arch_setup();
}
void bl2_el3_plat_prepare_exit(void)
{
}

View File

@ -150,6 +150,11 @@ BL2_SOURCES += drivers/delay_timer/delay_timer.c \
drivers/io/io_storage.c \
plat/arm/common/arm_bl2_setup.c \
plat/arm/common/arm_io_storage.c
ifeq (${BL2_AT_EL3},1)
BL2_SOURCES += plat/arm/common/arm_bl2_el3_setup.c
endif
ifeq (${LOAD_IMAGE_V2},1)
# Because BL1/BL2 execute in AArch64 mode but BL32 in AArch32 we need to use
# the AArch32 descriptors.