spl: atf: add support for LOAD_IMAGE_V2
Newer platforms use the LOAD_IMAGE_V2 parameter passing method. Add support for it. Signed-off-by: Michael Walle <michael@walle.cc>
This commit is contained in:
parent
553825c109
commit
7b866825cd
@ -1276,6 +1276,15 @@ config SPL_ATF
|
|||||||
is loaded by SPL (which is considered as BL2 in ATF terminology).
|
is loaded by SPL (which is considered as BL2 in ATF terminology).
|
||||||
More detail at: https://github.com/ARM-software/arm-trusted-firmware
|
More detail at: https://github.com/ARM-software/arm-trusted-firmware
|
||||||
|
|
||||||
|
config SPL_ATF_LOAD_IMAGE_V2
|
||||||
|
bool "Use the new LOAD_IMAGE_V2 parameter passing"
|
||||||
|
depends on SPL_ATF
|
||||||
|
help
|
||||||
|
Some platforms use the newer LOAD_IMAGE_V2 parameter passing.
|
||||||
|
|
||||||
|
If you want to load a bl31 image from the SPL and need the new
|
||||||
|
method, say Y.
|
||||||
|
|
||||||
config SPL_ATF_NO_PLATFORM_PARAM
|
config SPL_ATF_NO_PLATFORM_PARAM
|
||||||
bool "Pass no platform parameter"
|
bool "Pass no platform parameter"
|
||||||
depends on SPL_ATF
|
depends on SPL_ATF
|
||||||
|
@ -29,6 +29,19 @@ struct bl2_to_bl31_params_mem {
|
|||||||
struct entry_point_info bl31_ep_info;
|
struct entry_point_info bl31_ep_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct bl2_to_bl31_params_mem_v2 {
|
||||||
|
struct bl_params bl_params;
|
||||||
|
struct bl_params_node bl31_params_node;
|
||||||
|
struct bl_params_node bl32_params_node;
|
||||||
|
struct bl_params_node bl33_params_node;
|
||||||
|
struct atf_image_info bl31_image_info;
|
||||||
|
struct atf_image_info bl32_image_info;
|
||||||
|
struct atf_image_info bl33_image_info;
|
||||||
|
struct entry_point_info bl33_ep_info;
|
||||||
|
struct entry_point_info bl32_ep_info;
|
||||||
|
struct entry_point_info bl31_ep_info;
|
||||||
|
};
|
||||||
|
|
||||||
struct bl31_params *bl2_plat_get_bl31_params_default(uintptr_t bl32_entry,
|
struct bl31_params *bl2_plat_get_bl31_params_default(uintptr_t bl32_entry,
|
||||||
uintptr_t bl33_entry,
|
uintptr_t bl33_entry,
|
||||||
uintptr_t fdt_addr)
|
uintptr_t fdt_addr)
|
||||||
@ -96,6 +109,79 @@ __weak struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry,
|
|||||||
fdt_addr);
|
fdt_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct bl_params *bl2_plat_get_bl31_params_v2_default(uintptr_t bl32_entry,
|
||||||
|
uintptr_t bl33_entry,
|
||||||
|
uintptr_t fdt_addr)
|
||||||
|
{
|
||||||
|
static struct bl2_to_bl31_params_mem_v2 bl31_params_mem;
|
||||||
|
struct bl_params *bl_params;
|
||||||
|
struct bl_params_node *bl_params_node;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the memory for all the arguments that needs to
|
||||||
|
* be passed to BL31
|
||||||
|
*/
|
||||||
|
memset(&bl31_params_mem, 0, sizeof(bl31_params_mem));
|
||||||
|
|
||||||
|
/* Assign memory for TF related information */
|
||||||
|
bl_params = &bl31_params_mem.bl_params;
|
||||||
|
SET_PARAM_HEAD(bl_params, ATF_PARAM_BL_PARAMS, ATF_VERSION_2, 0);
|
||||||
|
bl_params->head = &bl31_params_mem.bl31_params_node;
|
||||||
|
|
||||||
|
/* Fill BL31 related information */
|
||||||
|
bl_params_node = &bl31_params_mem.bl31_params_node;
|
||||||
|
bl_params_node->image_id = ATF_BL31_IMAGE_ID;
|
||||||
|
bl_params_node->image_info = &bl31_params_mem.bl31_image_info;
|
||||||
|
bl_params_node->ep_info = &bl31_params_mem.bl31_ep_info;
|
||||||
|
bl_params_node->next_params_info = &bl31_params_mem.bl32_params_node;
|
||||||
|
SET_PARAM_HEAD(bl_params_node->image_info, ATF_PARAM_IMAGE_BINARY,
|
||||||
|
ATF_VERSION_2, 0);
|
||||||
|
|
||||||
|
/* Fill BL32 related information */
|
||||||
|
bl_params_node = &bl31_params_mem.bl32_params_node;
|
||||||
|
bl_params_node->image_id = ATF_BL32_IMAGE_ID;
|
||||||
|
bl_params_node->image_info = &bl31_params_mem.bl32_image_info;
|
||||||
|
bl_params_node->ep_info = &bl31_params_mem.bl32_ep_info;
|
||||||
|
bl_params_node->next_params_info = &bl31_params_mem.bl33_params_node;
|
||||||
|
SET_PARAM_HEAD(bl_params_node->ep_info, ATF_PARAM_EP,
|
||||||
|
ATF_VERSION_2, ATF_EP_SECURE);
|
||||||
|
|
||||||
|
/* secure payload is optional, so set pc to 0 if absent */
|
||||||
|
bl_params_node->ep_info->args.arg3 = fdt_addr;
|
||||||
|
bl_params_node->ep_info->pc = bl32_entry ? bl32_entry : 0;
|
||||||
|
bl_params_node->ep_info->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
|
||||||
|
DISABLE_ALL_EXECPTIONS);
|
||||||
|
SET_PARAM_HEAD(bl_params_node->image_info, ATF_PARAM_IMAGE_BINARY,
|
||||||
|
ATF_VERSION_2, 0);
|
||||||
|
|
||||||
|
/* Fill BL33 related information */
|
||||||
|
bl_params_node = &bl31_params_mem.bl33_params_node;
|
||||||
|
bl_params_node->image_id = ATF_BL33_IMAGE_ID;
|
||||||
|
bl_params_node->image_info = &bl31_params_mem.bl33_image_info;
|
||||||
|
bl_params_node->ep_info = &bl31_params_mem.bl33_ep_info;
|
||||||
|
bl_params_node->next_params_info = NULL;
|
||||||
|
SET_PARAM_HEAD(bl_params_node->ep_info, ATF_PARAM_EP,
|
||||||
|
ATF_VERSION_2, ATF_EP_NON_SECURE);
|
||||||
|
|
||||||
|
/* BL33 expects to receive the primary CPU MPID (through x0) */
|
||||||
|
bl_params_node->ep_info->args.arg0 = 0xffff & read_mpidr();
|
||||||
|
bl_params_node->ep_info->pc = bl33_entry;
|
||||||
|
bl_params_node->ep_info->spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
|
||||||
|
DISABLE_ALL_EXECPTIONS);
|
||||||
|
SET_PARAM_HEAD(bl_params_node->image_info, ATF_PARAM_IMAGE_BINARY,
|
||||||
|
ATF_VERSION_2, 0);
|
||||||
|
|
||||||
|
return bl_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak struct bl_params *bl2_plat_get_bl31_params_v2(uintptr_t bl32_entry,
|
||||||
|
uintptr_t bl33_entry,
|
||||||
|
uintptr_t fdt_addr)
|
||||||
|
{
|
||||||
|
return bl2_plat_get_bl31_params_v2_default(bl32_entry, bl33_entry,
|
||||||
|
fdt_addr);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void raw_write_daif(unsigned int daif)
|
static inline void raw_write_daif(unsigned int daif)
|
||||||
{
|
{
|
||||||
__asm__ __volatile__("msr DAIF, %0\n\t" : : "r" (daif) : "memory");
|
__asm__ __volatile__("msr DAIF, %0\n\t" : : "r" (daif) : "memory");
|
||||||
@ -106,16 +192,21 @@ typedef void (*atf_entry_t)(struct bl31_params *params, void *plat_params);
|
|||||||
static void bl31_entry(uintptr_t bl31_entry, uintptr_t bl32_entry,
|
static void bl31_entry(uintptr_t bl31_entry, uintptr_t bl32_entry,
|
||||||
uintptr_t bl33_entry, uintptr_t fdt_addr)
|
uintptr_t bl33_entry, uintptr_t fdt_addr)
|
||||||
{
|
{
|
||||||
struct bl31_params *bl31_params;
|
|
||||||
atf_entry_t atf_entry = (atf_entry_t)bl31_entry;
|
atf_entry_t atf_entry = (atf_entry_t)bl31_entry;
|
||||||
|
void *bl31_params;
|
||||||
|
|
||||||
bl31_params = bl2_plat_get_bl31_params(bl32_entry, bl33_entry,
|
if (CONFIG_IS_ENABLED(ATF_LOAD_IMAGE_V2))
|
||||||
fdt_addr);
|
bl31_params = bl2_plat_get_bl31_params_v2(bl32_entry,
|
||||||
|
bl33_entry,
|
||||||
|
fdt_addr);
|
||||||
|
else
|
||||||
|
bl31_params = bl2_plat_get_bl31_params(bl32_entry, bl33_entry,
|
||||||
|
fdt_addr);
|
||||||
|
|
||||||
raw_write_daif(SPSR_EXCEPTION_MASK);
|
raw_write_daif(SPSR_EXCEPTION_MASK);
|
||||||
dcache_disable();
|
dcache_disable();
|
||||||
|
|
||||||
atf_entry((void *)bl31_params, (void *)fdt_addr);
|
atf_entry(bl31_params, (void *)fdt_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spl_fit_images_find(void *blob, int os)
|
static int spl_fit_images_find(void *blob, int os)
|
||||||
|
@ -14,8 +14,14 @@
|
|||||||
#define ATF_PARAM_EP 0x01
|
#define ATF_PARAM_EP 0x01
|
||||||
#define ATF_PARAM_IMAGE_BINARY 0x02
|
#define ATF_PARAM_IMAGE_BINARY 0x02
|
||||||
#define ATF_PARAM_BL31 0x03
|
#define ATF_PARAM_BL31 0x03
|
||||||
|
#define ATF_PARAM_BL_PARAMS 0x05
|
||||||
|
|
||||||
#define ATF_VERSION_1 0x01
|
#define ATF_VERSION_1 0x01
|
||||||
|
#define ATF_VERSION_2 0x02
|
||||||
|
|
||||||
|
#define ATF_BL31_IMAGE_ID 0x03
|
||||||
|
#define ATF_BL32_IMAGE_ID 0x04
|
||||||
|
#define ATF_BL33_IMAGE_ID 0x05
|
||||||
|
|
||||||
#define ATF_EP_SECURE 0x0
|
#define ATF_EP_SECURE 0x0
|
||||||
#define ATF_EP_NON_SECURE 0x1
|
#define ATF_EP_NON_SECURE 0x1
|
||||||
@ -121,6 +127,9 @@ struct atf_image_info {
|
|||||||
struct param_header h;
|
struct param_header h;
|
||||||
uintptr_t image_base; /* physical address of base of image */
|
uintptr_t image_base; /* physical address of base of image */
|
||||||
uint32_t image_size; /* bytes read from image file */
|
uint32_t image_size; /* bytes read from image file */
|
||||||
|
#if CONFIG_IS_ENABLED(ATF_LOAD_IMAGE_V2)
|
||||||
|
uint32_t image_max_size;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -162,6 +171,27 @@ struct bl31_params {
|
|||||||
struct atf_image_info *bl33_image_info;
|
struct atf_image_info *bl33_image_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* BL image node in the BL image execution sequence */
|
||||||
|
struct bl_params_node {
|
||||||
|
unsigned int image_id;
|
||||||
|
struct atf_image_info *image_info;
|
||||||
|
struct entry_point_info *ep_info;
|
||||||
|
struct bl_params_node *next_params_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BL image head node in the BL image execution sequence
|
||||||
|
* It is also used to pass information to next BL image.
|
||||||
|
*/
|
||||||
|
struct bl_params {
|
||||||
|
struct param_header h;
|
||||||
|
struct bl_params_node *head;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define for_each_bl_params_node(bl_params, node) \
|
||||||
|
for ((node) = (bl_params)->head; \
|
||||||
|
(node); \
|
||||||
|
(node) = (node)->next_params_info)
|
||||||
|
|
||||||
#endif /*__ASSEMBLY__ */
|
#endif /*__ASSEMBLY__ */
|
||||||
|
|
||||||
|
@ -564,6 +564,41 @@ struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry,
|
|||||||
struct bl31_params *bl2_plat_get_bl31_params_default(uintptr_t bl32_entry,
|
struct bl31_params *bl2_plat_get_bl31_params_default(uintptr_t bl32_entry,
|
||||||
uintptr_t bl33_entry,
|
uintptr_t bl33_entry,
|
||||||
uintptr_t fdt_addr);
|
uintptr_t fdt_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bl2_plat_get_bl31_params_v2() - return params for bl31
|
||||||
|
* @bl32_entry: address of BL32 executable (secure)
|
||||||
|
* @bl33_entry: address of BL33 executable (non secure)
|
||||||
|
* @fdt_addr: address of Flat Device Tree
|
||||||
|
*
|
||||||
|
* This function does the same as bl2_plat_get_bl31_params() except that is is
|
||||||
|
* used for the new LOAD_IMAGE_V2 option, which uses a slightly different
|
||||||
|
* method to pass the parameters.
|
||||||
|
*
|
||||||
|
* Return: bl31 params structure pointer
|
||||||
|
*/
|
||||||
|
struct bl_params *bl2_plat_get_bl31_params_v2(uintptr_t bl32_entry,
|
||||||
|
uintptr_t bl33_entry,
|
||||||
|
uintptr_t fdt_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bl2_plat_get_bl31_params_v2_default() - prepare params for bl31.
|
||||||
|
* @bl32_entry: address of BL32 executable (secure)
|
||||||
|
* @bl33_entry: address of BL33 executable (non secure)
|
||||||
|
* @fdt_addr: address of Flat Device Tree
|
||||||
|
*
|
||||||
|
* This is the default implementation of bl2_plat_get_bl31_params_v2(). It
|
||||||
|
* prepares the linked list of the bl31 params, populates the image types and
|
||||||
|
* set the entry points for bl32 and bl33 (if available).
|
||||||
|
*
|
||||||
|
* NOTE: The memory is statically allocated, thus this function should be
|
||||||
|
* called only once. All subsequent calls will overwrite any changes.
|
||||||
|
*
|
||||||
|
* Return: bl31 params structure pointer
|
||||||
|
*/
|
||||||
|
struct bl_params *bl2_plat_get_bl31_params_v2_default(uintptr_t bl32_entry,
|
||||||
|
uintptr_t bl33_entry,
|
||||||
|
uintptr_t fdt_addr);
|
||||||
/**
|
/**
|
||||||
* spl_optee_entry - entry function for optee
|
* spl_optee_entry - entry function for optee
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user