
On 16. 11. 20 22:47, Michael Walle wrote:
Newer platforms use the LOAD_IMAGE_V2 parameter passing method. Add support for it.
Signed-off-by: Michael Walle michael@walle.cc
common/spl/Kconfig | 9 ++++ common/spl/spl_atf.c | 99 ++++++++++++++++++++++++++++++++++++++++++-- include/atf_common.h | 30 ++++++++++++++ include/spl.h | 35 ++++++++++++++++ 4 files changed, 169 insertions(+), 4 deletions(-)
diff --git a/common/spl/Kconfig b/common/spl/Kconfig index d8086bd9e8..6d980be0b7 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -1276,6 +1276,15 @@ config SPL_ATF is loaded by SPL (which is considered as BL2 in ATF terminology). 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 bool "Pass no platform parameter" depends on SPL_ATF diff --git a/common/spl/spl_atf.c b/common/spl/spl_atf.c index 51b45d5dc6..e1b68dd561 100644 --- a/common/spl/spl_atf.c +++ b/common/spl/spl_atf.c @@ -29,6 +29,19 @@ struct bl2_to_bl31_params_mem { 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, uintptr_t bl33_entry, uintptr_t fdt_addr) @@ -96,6 +109,79 @@ __weak struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry, 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) { __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, uintptr_t bl33_entry, uintptr_t fdt_addr) {
- struct bl31_params *bl31_params; atf_entry_t atf_entry = (atf_entry_t)bl31_entry;
- void *bl31_params;
- bl31_params = bl2_plat_get_bl31_params(bl32_entry, bl33_entry,
fdt_addr);
if (CONFIG_IS_ENABLED(ATF_LOAD_IMAGE_V2))
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); 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) diff --git a/include/atf_common.h b/include/atf_common.h index e173a10ca9..d69892fac6 100644 --- a/include/atf_common.h +++ b/include/atf_common.h @@ -14,8 +14,14 @@ #define ATF_PARAM_EP 0x01 #define ATF_PARAM_IMAGE_BINARY 0x02 #define ATF_PARAM_BL31 0x03 +#define ATF_PARAM_BL_PARAMS 0x05
#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_NON_SECURE 0x1 @@ -121,6 +127,9 @@ struct atf_image_info { struct param_header h; uintptr_t image_base; /* physical address of base of image */ 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; };
+/* 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__ */
diff --git a/include/spl.h b/include/spl.h index dccf515511..5b389df09a 100644 --- a/include/spl.h +++ b/include/spl.h @@ -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, uintptr_t bl33_entry, 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
also kernel-doc issues.
include/spl.h:569: info: Scanning doc for bl2_plat_get_bl31_params_v2 include/spl.h:582: warning: Function parameter or member 'bl32_entry' not described in 'bl2_plat_get_bl31_params_v2' include/spl.h:582: warning: Function parameter or member 'bl33_entry' not described in 'bl2_plat_get_bl31_params_v2' include/spl.h:582: warning: Function parameter or member 'fdt_addr' not described in 'bl2_plat_get_bl31_params_v2' include/spl.h:582: warning: No description found for return value of 'bl2_plat_get_bl31_params_v2' include/spl.h:585: info: Scanning doc for bl2_plat_get_bl31_params_v2_default include/spl.h:594: warning: contents before sections include/spl.h:601: warning: Function parameter or member 'bl32_entry' not described in 'bl2_plat_get_bl31_params_v2_default' include/spl.h:601: warning: Function parameter or member 'bl33_entry' not described in 'bl2_plat_get_bl31_params_v2_default' include/spl.h:601: warning: Function parameter or member 'fdt_addr' not described in 'bl2_plat_get_bl31_params_v2_default' include/spl.h:601: warning: No description found for return value of 'bl2_plat_get_bl31_params_v2_default'
./scripts/kernel-doc -v -man include/spl.h > /dev/null
M