|
|
@ -38,85 +38,100 @@ |
|
|
|
#include <stdio.h> |
|
|
|
#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); |
|
|
|
} |
|
|
|