arm-trusted-firmware/bl2/bl2_main.c

294 lines
9.1 KiB
C
Raw Normal View History

2013-10-25 09:08:21 +01:00
/*
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
2013-10-25 09:08:21 +01:00
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <arch.h>
2013-10-25 09:08:21 +01:00
#include <arch_helpers.h>
#include <assert.h>
#include <auth_mod.h>
2015-10-10 19:06:53 +01:00
#include <bl1.h>
2013-10-25 09:08:21 +01:00
#include <bl_common.h>
#include <debug.h>
#include <errno.h>
#include <platform.h>
#include <platform_def.h>
Use numbers to identify images instead of names The Trusted firmware code identifies BL images by name. The platform port defines a name for each image e.g. the IO framework uses this mechanism in the platform function plat_get_image_source(). For a given image name, it returns the handle to the image file which involves comparing images names. In addition, if the image is packaged in a FIP, a name comparison is required to find the UUID for the image. This method is not optimal. This patch changes the interface between the generic and platform code with regard to identifying images. The platform port must now allocate a unique number (ID) for every image. The generic code will use the image ID instead of the name to access its attributes. As a result, the plat_get_image_source() function now takes an image ID as an input parameter. The organisation of data structures within the IO framework has been rationalised to use an image ID as an index into an array which contains attributes of the image such as UUID and name. This prevents the name comparisons. A new type 'io_uuid_spec_t' has been introduced in the IO framework to specify images identified by UUID (i.e. when the image is contained in a FIP file). There is no longer need to maintain a look-up table [iname_name --> uuid] in the io_fip driver code. Because image names are no longer mandatory in the platform port, the debug messages in the generic code will show the image identifier instead of the file name. The platforms that support semihosting to load images (i.e. FVP) must provide the file names as definitions private to the platform. The ARM platform ports and documentation have been updated accordingly. All ARM platforms reuse the image IDs defined in the platform common code. These IDs will be used to access other attributes of an image in subsequent patches. IMPORTANT: applying this patch breaks compatibility for platforms that use TF BL1 or BL2 images or the image loading code. The platform port must be updated to match the new interface. Change-Id: I9c1b04cb1a0684c6ee65dee66146dd6731751ea5
2015-04-13 17:36:19 +01:00
#include <stdint.h>
#include "bl2_private.h"
2013-10-25 09:08:21 +01:00
/*
* Check for platforms that use obsolete image terminology
*/
#ifdef BL30_BASE
# error "BL30_BASE platform define no longer used - please use SCP_BL2_BASE"
#endif
/*******************************************************************************
* Load the SCP_BL2 image if there's one.
* If a platform does not want to attempt to load SCP_BL2 image it must leave
* SCP_BL2_BASE undefined.
* Return 0 on success or if there's no SCP_BL2 image to load, a negative error
* code otherwise.
******************************************************************************/
static int load_scp_bl2(void)
{
int e = 0;
#ifdef SCP_BL2_BASE
meminfo_t scp_bl2_mem_info;
image_info_t scp_bl2_image_info;
/*
* It is up to the platform to specify where SCP_BL2 should be loaded if
* it exists. It could create space in the secure sram or point to a
* completely different memory.
*
* The entry point information is not relevant in this case as the AP
* won't execute the SCP_BL2 image.
*/
INFO("BL2: Loading SCP_BL2\n");
bl2_plat_get_scp_bl2_meminfo(&scp_bl2_mem_info);
scp_bl2_image_info.h.version = VERSION_1;
e = load_auth_image(&scp_bl2_mem_info,
SCP_BL2_IMAGE_ID,
SCP_BL2_BASE,
&scp_bl2_image_info,
NULL);
if (e == 0) {
/* The subsequent handling of SCP_BL2 is platform specific */
e = bl2_plat_handle_scp_bl2(&scp_bl2_image_info);
if (e) {
ERROR("Failure in platform-specific handling of SCP_BL2 image.\n");
}
}
#endif /* SCP_BL2_BASE */
return e;
}
CSS: Enable booting of EL3 payloads This patch adds support for booting EL3 payloads on CSS platforms, for example Juno. In this scenario, the Trusted Firmware follows its normal boot flow up to the point where it would normally pass control to the BL31 image. At this point, it jumps to the EL3 payload entry point address instead. Before handing over to the EL3 payload, the data SCP writes for AP at the beginning of the Trusted SRAM is restored, i.e. we zero the first 128 bytes and restore the SCP Boot configuration. The latter is saved before transferring the BL30 image to SCP and is restored just after the transfer (in BL2). The goal is to make it appear that the EL3 payload is the first piece of software to run on the target. The BL31 entrypoint info structure is updated to make the primary CPU jump to the EL3 payload instead of the BL31 image. The mailbox is populated with the EL3 payload entrypoint address, which releases the secondary CPUs out of their holding pen (if the SCP has powered them on). The arm_program_trusted_mailbox() function has been exported for this purpose. The TZC-400 configuration in BL2 is simplified: it grants secure access only to the whole DRAM. Other security initialization is unchanged. This alternative boot flow is disabled by default. A new build option EL3_PAYLOAD_BASE has been introduced to enable it and provide the EL3 payload's entry point address. The build system has been modified such that BL31 and BL33 are not compiled and/or not put in the FIP in this case, as those images are not used in this boot flow. Change-Id: Id2e26fa57988bbc32323a0effd022ab42f5b5077
2015-11-26 16:31:34 +00:00
#ifndef EL3_PAYLOAD_BASE
2013-10-25 09:08:21 +01:00
/*******************************************************************************
* Load the BL31 image.
* The bl2_to_bl31_params and bl31_ep_info params will be updated with the
* relevant BL31 information.
* Return 0 on success, a negative error code otherwise.
2013-10-25 09:08:21 +01:00
******************************************************************************/
static int load_bl31(bl31_params_t *bl2_to_bl31_params,
entry_point_info_t *bl31_ep_info)
2013-10-25 09:08:21 +01:00
{
meminfo_t *bl2_tzram_layout;
int e;
2013-10-25 09:08:21 +01:00
INFO("BL2: Loading BL31\n");
assert(bl2_to_bl31_params != NULL);
assert(bl31_ep_info != NULL);
2013-10-25 09:08:21 +01:00
/* Find out how much free trusted ram remains after BL2 load */
bl2_tzram_layout = bl2_plat_sec_mem_layout();
2013-10-25 09:08:21 +01:00
/* Set the X0 parameter to BL31 */
bl31_ep_info->args.arg0 = (unsigned long)bl2_to_bl31_params;
/* Load the BL31 image */
e = load_auth_image(bl2_tzram_layout,
BL31_IMAGE_ID,
BL31_BASE,
bl2_to_bl31_params->bl31_image_info,
bl31_ep_info);
2013-10-25 09:08:21 +01:00
if (e == 0) {
bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info,
bl31_ep_info);
}
return e;
}
/*******************************************************************************
* Load the BL32 image if there's one.
* The bl2_to_bl31_params param will be updated with the relevant BL32
* information.
* If a platform does not want to attempt to load BL32 image it must leave
* BL32_BASE undefined.
* Return 0 on success or if there's no BL32 image to load, a negative error
* code otherwise.
******************************************************************************/
static int load_bl32(bl31_params_t *bl2_to_bl31_params)
{
int e = 0;
#ifdef BL32_BASE
meminfo_t bl32_mem_info;
INFO("BL2: Loading BL32\n");
assert(bl2_to_bl31_params != NULL);
/*
* It is up to the platform to specify where BL32 should be loaded if
* it exists. It could create space in the secure sram or point to a
* completely different memory.
*/
bl2_plat_get_bl32_meminfo(&bl32_mem_info);
e = load_auth_image(&bl32_mem_info,
BL32_IMAGE_ID,
BL32_BASE,
bl2_to_bl31_params->bl32_image_info,
bl2_to_bl31_params->bl32_ep_info);
if (e == 0) {
bl2_plat_set_bl32_ep_info(
bl2_to_bl31_params->bl32_image_info,
bl2_to_bl31_params->bl32_ep_info);
}
#endif /* BL32_BASE */
return e;
}
/*******************************************************************************
* Load the BL33 image.
* The bl2_to_bl31_params param will be updated with the relevant BL33
* information.
* Return 0 on success, a negative error code otherwise.
******************************************************************************/
static int load_bl33(bl31_params_t *bl2_to_bl31_params)
{
meminfo_t bl33_mem_info;
int e;
INFO("BL2: Loading BL33\n");
assert(bl2_to_bl31_params != NULL);
bl2_plat_get_bl33_meminfo(&bl33_mem_info);
/* Load the BL33 image in non-secure memory provided by the platform */
e = load_auth_image(&bl33_mem_info,
BL33_IMAGE_ID,
plat_get_ns_image_entrypoint(),
bl2_to_bl31_params->bl33_image_info,
bl2_to_bl31_params->bl33_ep_info);
if (e == 0) {
bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info,
bl2_to_bl31_params->bl33_ep_info);
}
return e;
}
CSS: Enable booting of EL3 payloads This patch adds support for booting EL3 payloads on CSS platforms, for example Juno. In this scenario, the Trusted Firmware follows its normal boot flow up to the point where it would normally pass control to the BL31 image. At this point, it jumps to the EL3 payload entry point address instead. Before handing over to the EL3 payload, the data SCP writes for AP at the beginning of the Trusted SRAM is restored, i.e. we zero the first 128 bytes and restore the SCP Boot configuration. The latter is saved before transferring the BL30 image to SCP and is restored just after the transfer (in BL2). The goal is to make it appear that the EL3 payload is the first piece of software to run on the target. The BL31 entrypoint info structure is updated to make the primary CPU jump to the EL3 payload instead of the BL31 image. The mailbox is populated with the EL3 payload entrypoint address, which releases the secondary CPUs out of their holding pen (if the SCP has powered them on). The arm_program_trusted_mailbox() function has been exported for this purpose. The TZC-400 configuration in BL2 is simplified: it grants secure access only to the whole DRAM. Other security initialization is unchanged. This alternative boot flow is disabled by default. A new build option EL3_PAYLOAD_BASE has been introduced to enable it and provide the EL3 payload's entry point address. The build system has been modified such that BL31 and BL33 are not compiled and/or not put in the FIP in this case, as those images are not used in this boot flow. Change-Id: Id2e26fa57988bbc32323a0effd022ab42f5b5077
2015-11-26 16:31:34 +00:00
#endif /* EL3_PAYLOAD_BASE */
/*******************************************************************************
* The only thing to do in BL2 is to load further images and pass control to
* BL31. The memory occupied by BL2 will be reclaimed by BL3x stages. BL2 runs
* entirely in S-EL1.
******************************************************************************/
void bl2_main(void)
{
bl31_params_t *bl2_to_bl31_params;
entry_point_info_t *bl31_ep_info;
int e;
NOTICE("BL2: %s\n", version_string);
NOTICE("BL2: %s\n", build_message);
/* Perform remaining generic architectural setup in S-EL1 */
bl2_arch_setup();
#if TRUSTED_BOARD_BOOT
/* Initialize authentication module */
auth_mod_init();
#endif /* TRUSTED_BOARD_BOOT */
/*
* Load the subsequent bootloader images
*/
e = load_scp_bl2();
if (e) {
ERROR("Failed to load SCP_BL2 (%i)\n", e);
plat_error_handler(e);
}
/* Perform platform setup in BL2 after loading SCP_BL2 */
bl2_platform_setup();
/*
* Get a pointer to the memory the platform has set aside to pass
* information to BL31.
*/
bl2_to_bl31_params = bl2_plat_get_bl31_params();
bl31_ep_info = bl2_plat_get_bl31_ep_info();
CSS: Enable booting of EL3 payloads This patch adds support for booting EL3 payloads on CSS platforms, for example Juno. In this scenario, the Trusted Firmware follows its normal boot flow up to the point where it would normally pass control to the BL31 image. At this point, it jumps to the EL3 payload entry point address instead. Before handing over to the EL3 payload, the data SCP writes for AP at the beginning of the Trusted SRAM is restored, i.e. we zero the first 128 bytes and restore the SCP Boot configuration. The latter is saved before transferring the BL30 image to SCP and is restored just after the transfer (in BL2). The goal is to make it appear that the EL3 payload is the first piece of software to run on the target. The BL31 entrypoint info structure is updated to make the primary CPU jump to the EL3 payload instead of the BL31 image. The mailbox is populated with the EL3 payload entrypoint address, which releases the secondary CPUs out of their holding pen (if the SCP has powered them on). The arm_program_trusted_mailbox() function has been exported for this purpose. The TZC-400 configuration in BL2 is simplified: it grants secure access only to the whole DRAM. Other security initialization is unchanged. This alternative boot flow is disabled by default. A new build option EL3_PAYLOAD_BASE has been introduced to enable it and provide the EL3 payload's entry point address. The build system has been modified such that BL31 and BL33 are not compiled and/or not put in the FIP in this case, as those images are not used in this boot flow. Change-Id: Id2e26fa57988bbc32323a0effd022ab42f5b5077
2015-11-26 16:31:34 +00:00
#ifdef EL3_PAYLOAD_BASE
/*
* In the case of an EL3 payload, we don't need to load any further
* images. Just update the BL31 entrypoint info structure to make BL1
* jump to the EL3 payload.
* The pointer to the memory the platform has set aside to pass
* information to BL31 in the normal boot flow is reused here, even
CSS: Enable booting of EL3 payloads This patch adds support for booting EL3 payloads on CSS platforms, for example Juno. In this scenario, the Trusted Firmware follows its normal boot flow up to the point where it would normally pass control to the BL31 image. At this point, it jumps to the EL3 payload entry point address instead. Before handing over to the EL3 payload, the data SCP writes for AP at the beginning of the Trusted SRAM is restored, i.e. we zero the first 128 bytes and restore the SCP Boot configuration. The latter is saved before transferring the BL30 image to SCP and is restored just after the transfer (in BL2). The goal is to make it appear that the EL3 payload is the first piece of software to run on the target. The BL31 entrypoint info structure is updated to make the primary CPU jump to the EL3 payload instead of the BL31 image. The mailbox is populated with the EL3 payload entrypoint address, which releases the secondary CPUs out of their holding pen (if the SCP has powered them on). The arm_program_trusted_mailbox() function has been exported for this purpose. The TZC-400 configuration in BL2 is simplified: it grants secure access only to the whole DRAM. Other security initialization is unchanged. This alternative boot flow is disabled by default. A new build option EL3_PAYLOAD_BASE has been introduced to enable it and provide the EL3 payload's entry point address. The build system has been modified such that BL31 and BL33 are not compiled and/or not put in the FIP in this case, as those images are not used in this boot flow. Change-Id: Id2e26fa57988bbc32323a0effd022ab42f5b5077
2015-11-26 16:31:34 +00:00
* though only a fraction of the information contained in the
* bl31_params_t structure makes sense in the context of EL3 payloads.
* This will be refined in the future.
*/
VERBOSE("BL2: Populating the entrypoint info for the EL3 payload\n");
bl31_ep_info->pc = EL3_PAYLOAD_BASE;
bl31_ep_info->args.arg0 = (unsigned long) bl2_to_bl31_params;
bl2_plat_set_bl31_ep_info(NULL, bl31_ep_info);
#else
e = load_bl31(bl2_to_bl31_params, bl31_ep_info);
if (e) {
ERROR("Failed to load BL31 (%i)\n", e);
plat_error_handler(e);
}
e = load_bl32(bl2_to_bl31_params);
if (e) {
if (e == -EAUTH) {
ERROR("Failed to authenticate BL32\n");
plat_error_handler(e);
} else {
WARN("Failed to load BL32 (%i)\n", e);
}
}
e = load_bl33(bl2_to_bl31_params);
if (e) {
ERROR("Failed to load BL33 (%i)\n", e);
plat_error_handler(e);
}
CSS: Enable booting of EL3 payloads This patch adds support for booting EL3 payloads on CSS platforms, for example Juno. In this scenario, the Trusted Firmware follows its normal boot flow up to the point where it would normally pass control to the BL31 image. At this point, it jumps to the EL3 payload entry point address instead. Before handing over to the EL3 payload, the data SCP writes for AP at the beginning of the Trusted SRAM is restored, i.e. we zero the first 128 bytes and restore the SCP Boot configuration. The latter is saved before transferring the BL30 image to SCP and is restored just after the transfer (in BL2). The goal is to make it appear that the EL3 payload is the first piece of software to run on the target. The BL31 entrypoint info structure is updated to make the primary CPU jump to the EL3 payload instead of the BL31 image. The mailbox is populated with the EL3 payload entrypoint address, which releases the secondary CPUs out of their holding pen (if the SCP has powered them on). The arm_program_trusted_mailbox() function has been exported for this purpose. The TZC-400 configuration in BL2 is simplified: it grants secure access only to the whole DRAM. Other security initialization is unchanged. This alternative boot flow is disabled by default. A new build option EL3_PAYLOAD_BASE has been introduced to enable it and provide the EL3 payload's entry point address. The build system has been modified such that BL31 and BL33 are not compiled and/or not put in the FIP in this case, as those images are not used in this boot flow. Change-Id: Id2e26fa57988bbc32323a0effd022ab42f5b5077
2015-11-26 16:31:34 +00:00
#endif /* EL3_PAYLOAD_BASE */
/* Flush the params to be passed to memory */
bl2_plat_flush_bl31_params();
2013-10-25 09:08:21 +01:00
/*
* Run BL31 via an SMC to BL1. Information on how to pass control to
* the BL32 (if present) and BL33 software images will be passed to
* BL31 as an argument.
2013-10-25 09:08:21 +01:00
*/
2015-10-10 19:06:53 +01:00
smc(BL1_SMC_RUN_IMAGE, (unsigned long)bl31_ep_info, 0, 0, 0, 0, 0, 0);
2013-10-25 09:08:21 +01:00
}