From 93d81d64d3947aa7712fab602a16b781a12c78bb Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Tue, 24 Jun 2014 14:19:36 +0100 Subject: Add support for BL3-0 image - Add support for loading a BL3-0 image in BL2. Information about memory extents is populated by platform-specific code. Subsequent handling of BL3-0 is also platform specific. The BL2 main function has been broken down to improve readability. The BL3-2 image is now loaded before the BL3-3 image to align with the boot flow. - Build system: Add support for specifying a BL3-0 image that will be included into the FIP image. - IO FIP driver: Add support for identifying a BL3-0 image inside a FIP image. - Update the documentation to reflect the above changes. Change-Id: I067c184afd52ccaa86569f13664757570c86fc48 --- bl2/bl2_main.c | 223 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 159 insertions(+), 64 deletions(-) (limited to 'bl2') diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c index 7efd9f6d..d96e199c 100644 --- a/bl2/bl2_main.c +++ b/bl2/bl2_main.c @@ -38,85 +38,100 @@ #include #include "bl2_private.h" +/******************************************************************************* + * Load the BL3-0 image if there's one. + * If a platform does not want to attempt to load BL3-0 image it must leave + * BL30_BASE undefined. + * Return 0 on success or if there's no BL3-0 image to load, a negative error + * code otherwise. + ******************************************************************************/ +static int load_bl30(void) +{ + int e = 0; +#ifdef BL30_BASE + meminfo_t bl30_mem_info; + image_info_t bl30_image_info; + + /* + * It is up to the platform to specify where BL3-0 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 BL3-0 image. + */ + bl2_plat_get_bl30_meminfo(&bl30_mem_info); + e = load_image(&bl30_mem_info, + BL30_IMAGE_NAME, + BL30_BASE, + &bl30_image_info, + NULL); + + if (e == 0) { + /* The subsequent handling of BL3-0 is platform specific */ + bl2_plat_handle_bl30(&bl30_image_info); + } +#endif /* BL30_BASE */ + + return e; +} /******************************************************************************* - * The only thing to do in BL2 is to load further images and pass control to - * BL3-1. The memory occupied by BL2 will be reclaimed by BL3-x stages. BL2 runs - * entirely in S-EL1. + * Load the BL3-1 image. + * The bl2_to_bl31_params and bl31_ep_info params will be updated with the + * relevant BL3-1 information. + * Return 0 on success, a negative error code otherwise. ******************************************************************************/ -void bl2_main(void) +static int load_bl31(bl31_params_t *bl2_to_bl31_params, + entry_point_info_t *bl31_ep_info) { meminfo_t *bl2_tzram_layout; - bl31_params_t *bl2_to_bl31_params; - entry_point_info_t *bl31_ep_info; - meminfo_t bl32_mem_info; - meminfo_t bl33_mem_info; int e; - /* Perform remaining generic architectural setup in S-El1 */ - bl2_arch_setup(); - - /* Perform platform setup in BL1 */ - bl2_platform_setup(); - - printf("BL2 %s\n\r", build_message); + assert(bl2_to_bl31_params != NULL); + assert(bl31_ep_info != NULL); /* Find out how much free trusted ram remains after BL2 load */ bl2_tzram_layout = bl2_plat_sec_mem_layout(); - /* - * 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(); - - /* Set the X0 parameter to bl31 */ + /* Set the X0 parameter to BL3-1 */ bl31_ep_info->args.arg0 = (unsigned long)bl2_to_bl31_params; /* Load the BL3-1 image */ e = load_image(bl2_tzram_layout, - BL31_IMAGE_NAME, - BL31_BASE, - bl2_to_bl31_params->bl31_image_info, - bl31_ep_info); + BL31_IMAGE_NAME, + BL31_BASE, + bl2_to_bl31_params->bl31_image_info, + bl31_ep_info); - /* Assert if it has not been possible to load BL31 */ - if (e) { - ERROR("Failed to load BL3-1.\n"); - panic(); - } + if (e == 0) + bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info, + bl31_ep_info); - bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info, - bl31_ep_info); - - bl2_plat_get_bl33_meminfo(&bl33_mem_info); - - /* Load the BL33 image in non-secure memory provided by the platform */ - e = load_image(&bl33_mem_info, - BL33_IMAGE_NAME, - plat_get_ns_image_entrypoint(), - bl2_to_bl31_params->bl33_image_info, - bl2_to_bl31_params->bl33_ep_info); + return e; +} - /* Halt if failed to load normal world firmware. */ - if (e) { - ERROR("Failed to load BL3-3.\n"); - panic(); - } - bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info, - bl2_to_bl31_params->bl33_ep_info); +/******************************************************************************* + * Load the BL3-2 image if there's one. + * The bl2_to_bl31_params param will be updated with the relevant BL3-2 + * information. + * If a platform does not want to attempt to load BL3-2 image it must leave + * BL32_BASE undefined. + * Return 0 on success or if there's no BL3-2 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; + assert(bl2_to_bl31_params != NULL); -#ifdef BL32_BASE /* - * Load the BL32 image if there's one. It is upto to platform - * to specify where BL32 should be loaded if it exists. It - * could create space in the secure sram or point to a + * It is up to the platform to specify where BL3-2 should be loaded if + * it exists. It could create space in the secure sram or point to a * completely different memory. - * - * If a platform does not want to attempt to load BL3-2 image - * it must leave BL32_BASE undefined */ bl2_plat_get_bl32_meminfo(&bl32_mem_info); e = load_image(&bl32_mem_info, @@ -125,23 +140,103 @@ void bl2_main(void) bl2_to_bl31_params->bl32_image_info, bl2_to_bl31_params->bl32_ep_info); - /* Issue a diagnostic if no Secure Payload could be loaded */ - if (e) { - WARN("Failed to load BL3-2.\n"); - } else { + 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 BL3-3 image. + * The bl2_to_bl31_params param will be updated with the relevant BL3-3 + * 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; + + assert(bl2_to_bl31_params != NULL); + + bl2_plat_get_bl33_meminfo(&bl33_mem_info); + + /* Load the BL3-3 image in non-secure memory provided by the platform */ + e = load_image(&bl33_mem_info, + BL33_IMAGE_NAME, + 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; +} + +/******************************************************************************* + * The only thing to do in BL2 is to load further images and pass control to + * BL3-1. The memory occupied by BL2 will be reclaimed by BL3-x 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; + + /* Perform remaining generic architectural setup in S-EL1 */ + bl2_arch_setup(); + + /* Perform platform setup in BL2 */ + bl2_platform_setup(); + + printf("BL2 %s\n\r", build_message); + + /* + * Load the subsequent bootloader images + */ + e = load_bl30(); + if (e) { + ERROR("Failed to load BL3-0 (%i)\n", e); + panic(); + } + + /* + * Get a pointer to the memory the platform has set aside to pass + * information to BL3-1. + */ + bl2_to_bl31_params = bl2_plat_get_bl31_params(); + bl31_ep_info = bl2_plat_get_bl31_ep_info(); + + e = load_bl31(bl2_to_bl31_params, bl31_ep_info); + if (e) { + ERROR("Failed to load BL3-1 (%i)\n", e); + panic(); + } + + e = load_bl32(bl2_to_bl31_params); + if (e) + WARN("Failed to load BL3-2 (%i)\n", e); + + e = load_bl33(bl2_to_bl31_params); + if (e) { + ERROR("Failed to load BL3-3 (%i)\n", e); + panic(); + } + /* Flush the params to be passed to memory */ bl2_plat_flush_bl31_params(); /* - * 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. + * Run BL3-1 via an SMC to BL1. Information on how to pass control to + * the BL3-2 (if present) and BL3-3 software images will be passed to + * BL3-1 as an argument. */ smc(RUN_IMAGE, (unsigned long)bl31_ep_info, 0, 0, 0, 0, 0, 0); } -- cgit v1.2.3