172600226SYatharth Kochar /* 2*291e493dSHarrison Mutai * Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved. 372600226SYatharth Kochar * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 572600226SYatharth Kochar */ 672600226SYatharth Kochar 772600226SYatharth Kochar #include <assert.h> 872600226SYatharth Kochar 9*291e493dSHarrison Mutai #include <plat/common/platform.h> 10*291e493dSHarrison Mutai 1109d40e0eSAntonio Nino Diaz #include <arch_helpers.h> 1209d40e0eSAntonio Nino Diaz #include <common/bl_common.h> 1309d40e0eSAntonio Nino Diaz #include <common/desc_image_load.h> 14d9af1f7bSJulius Werner #include <common/tbbr/tbbr_img_def.h> 1572600226SYatharth Kochar 1672600226SYatharth Kochar static bl_load_info_t bl_load_info; 1772600226SYatharth Kochar static bl_params_t next_bl_params; 1872600226SYatharth Kochar 1972600226SYatharth Kochar 2072600226SYatharth Kochar /******************************************************************************* 2172600226SYatharth Kochar * This function flushes the data structures so that they are visible 2272600226SYatharth Kochar * in memory for the next BL image. 2372600226SYatharth Kochar ******************************************************************************/ 2472600226SYatharth Kochar void flush_bl_params_desc(void) 2572600226SYatharth Kochar { 265b8d50e4SSathees Balya flush_bl_params_desc_args(bl_mem_params_desc_ptr, 275b8d50e4SSathees Balya bl_mem_params_desc_num, 285b8d50e4SSathees Balya &next_bl_params); 295b8d50e4SSathees Balya } 30c2a9ee63SDan Handley 315b8d50e4SSathees Balya /******************************************************************************* 325b8d50e4SSathees Balya * This function flushes the data structures specified as arguments so that they 335b8d50e4SSathees Balya * are visible in memory for the next BL image. 345b8d50e4SSathees Balya ******************************************************************************/ 355b8d50e4SSathees Balya void flush_bl_params_desc_args(bl_mem_params_node_t *mem_params_desc_ptr, 365b8d50e4SSathees Balya unsigned int mem_params_desc_num, 375b8d50e4SSathees Balya bl_params_t *next_bl_params_ptr) 385b8d50e4SSathees Balya { 395b8d50e4SSathees Balya assert(mem_params_desc_ptr != NULL); 405b8d50e4SSathees Balya assert(mem_params_desc_num != 0U); 415b8d50e4SSathees Balya assert(next_bl_params_ptr != NULL); 425b8d50e4SSathees Balya 435b8d50e4SSathees Balya flush_dcache_range((uintptr_t)mem_params_desc_ptr, 445b8d50e4SSathees Balya sizeof(*mem_params_desc_ptr) * mem_params_desc_num); 455b8d50e4SSathees Balya 465b8d50e4SSathees Balya flush_dcache_range((uintptr_t)next_bl_params_ptr, 475b8d50e4SSathees Balya sizeof(*next_bl_params_ptr)); 4872600226SYatharth Kochar } 4972600226SYatharth Kochar 5072600226SYatharth Kochar /******************************************************************************* 5172600226SYatharth Kochar * This function returns the index for given image_id, within the 5272600226SYatharth Kochar * image descriptor array provided by bl_image_info_descs_ptr, if the 5372600226SYatharth Kochar * image is found else it returns -1. 5472600226SYatharth Kochar ******************************************************************************/ 5572600226SYatharth Kochar int get_bl_params_node_index(unsigned int image_id) 5672600226SYatharth Kochar { 5781542c00SAntonio Nino Diaz unsigned int index; 5872600226SYatharth Kochar assert(image_id != INVALID_IMAGE_ID); 5972600226SYatharth Kochar 6081542c00SAntonio Nino Diaz for (index = 0U; index < bl_mem_params_desc_num; index++) { 6172600226SYatharth Kochar if (bl_mem_params_desc_ptr[index].image_id == image_id) 6281542c00SAntonio Nino Diaz return (int)index; 6372600226SYatharth Kochar } 6472600226SYatharth Kochar 6572600226SYatharth Kochar return -1; 6672600226SYatharth Kochar } 6772600226SYatharth Kochar 6872600226SYatharth Kochar /******************************************************************************* 6972600226SYatharth Kochar * This function returns the pointer to `bl_mem_params_node_t` object for 7072600226SYatharth Kochar * given image_id, within the image descriptor array provided by 7172600226SYatharth Kochar * bl_mem_params_desc_ptr, if the image is found else it returns NULL. 7272600226SYatharth Kochar ******************************************************************************/ 7372600226SYatharth Kochar bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id) 7472600226SYatharth Kochar { 7572600226SYatharth Kochar int index; 7672600226SYatharth Kochar assert(image_id != INVALID_IMAGE_ID); 7772600226SYatharth Kochar 7872600226SYatharth Kochar index = get_bl_params_node_index(image_id); 7972600226SYatharth Kochar if (index >= 0) 8072600226SYatharth Kochar return &bl_mem_params_desc_ptr[index]; 8172600226SYatharth Kochar else 8272600226SYatharth Kochar return NULL; 8372600226SYatharth Kochar } 8472600226SYatharth Kochar 8572600226SYatharth Kochar /******************************************************************************* 8672600226SYatharth Kochar * This function creates the list of loadable images, by populating and 8772600226SYatharth Kochar * linking each `bl_load_info_node_t` type node, using the internal array 8872600226SYatharth Kochar * of image descriptor provided by bl_mem_params_desc_ptr. It also populates 8972600226SYatharth Kochar * and returns `bl_load_info_t` type structure that contains head of the list 9072600226SYatharth Kochar * of loadable images. 9172600226SYatharth Kochar ******************************************************************************/ 9272600226SYatharth Kochar bl_load_info_t *get_bl_load_info_from_mem_params_desc(void) 9372600226SYatharth Kochar { 9481542c00SAntonio Nino Diaz unsigned int index = 0; 9572600226SYatharth Kochar 9672600226SYatharth Kochar /* If there is no image to start with, return NULL */ 9781542c00SAntonio Nino Diaz if (bl_mem_params_desc_num == 0U) 9872600226SYatharth Kochar return NULL; 9972600226SYatharth Kochar 10072600226SYatharth Kochar /* Assign initial data structures */ 10172600226SYatharth Kochar bl_load_info_node_t *bl_node_info = 10272600226SYatharth Kochar &bl_mem_params_desc_ptr[index].load_node_mem; 10372600226SYatharth Kochar bl_load_info.head = bl_node_info; 10481542c00SAntonio Nino Diaz SET_PARAM_HEAD(&bl_load_info, PARAM_BL_LOAD_INFO, VERSION_2, 0U); 10572600226SYatharth Kochar 10672600226SYatharth Kochar /* Go through the image descriptor array and create the list */ 10772600226SYatharth Kochar for (; index < bl_mem_params_desc_num; index++) { 10872600226SYatharth Kochar 10972600226SYatharth Kochar /* Populate the image information */ 11072600226SYatharth Kochar bl_node_info->image_id = bl_mem_params_desc_ptr[index].image_id; 11172600226SYatharth Kochar bl_node_info->image_info = &bl_mem_params_desc_ptr[index].image_info; 11272600226SYatharth Kochar 11372600226SYatharth Kochar /* Link next image if present */ 11481542c00SAntonio Nino Diaz if ((index + 1U) < bl_mem_params_desc_num) { 11572600226SYatharth Kochar /* Get the memory and link the next node */ 11672600226SYatharth Kochar bl_node_info->next_load_info = 11781542c00SAntonio Nino Diaz &bl_mem_params_desc_ptr[index + 1U].load_node_mem; 11872600226SYatharth Kochar bl_node_info = bl_node_info->next_load_info; 11972600226SYatharth Kochar } 12072600226SYatharth Kochar } 12172600226SYatharth Kochar 12272600226SYatharth Kochar return &bl_load_info; 12372600226SYatharth Kochar } 12472600226SYatharth Kochar 12572600226SYatharth Kochar /******************************************************************************* 12672600226SYatharth Kochar * This function creates the list of executable images, by populating and 12772600226SYatharth Kochar * linking each `bl_params_node_t` type node, using the internal array of 12872600226SYatharth Kochar * image descriptor provided by bl_mem_params_desc_ptr. It also populates 12972600226SYatharth Kochar * and returns `bl_params_t` type structure that contains head of the list 13072600226SYatharth Kochar * of executable images. 13172600226SYatharth Kochar ******************************************************************************/ 13272600226SYatharth Kochar bl_params_t *get_next_bl_params_from_mem_params_desc(void) 13372600226SYatharth Kochar { 13481542c00SAntonio Nino Diaz unsigned int count; 13581542c00SAntonio Nino Diaz unsigned int img_id = 0U; 13681542c00SAntonio Nino Diaz unsigned int link_index = 0U; 13772600226SYatharth Kochar bl_params_node_t *bl_current_exec_node = NULL; 13872600226SYatharth Kochar bl_params_node_t *bl_last_exec_node = NULL; 13972600226SYatharth Kochar bl_mem_params_node_t *desc_ptr; 14072600226SYatharth Kochar 14172600226SYatharth Kochar /* If there is no image to start with, return NULL */ 14281542c00SAntonio Nino Diaz if (bl_mem_params_desc_num == 0U) 14372600226SYatharth Kochar return NULL; 14472600226SYatharth Kochar 14572600226SYatharth Kochar /* Get the list HEAD */ 14681542c00SAntonio Nino Diaz for (count = 0U; count < bl_mem_params_desc_num; count++) { 14772600226SYatharth Kochar 14872600226SYatharth Kochar desc_ptr = &bl_mem_params_desc_ptr[count]; 14972600226SYatharth Kochar 15072600226SYatharth Kochar if ((EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE) && 15172600226SYatharth Kochar (EP_GET_FIRST_EXE(desc_ptr->ep_info.h.attr) == EP_FIRST_EXE)) { 15272600226SYatharth Kochar next_bl_params.head = &desc_ptr->params_node_mem; 15372600226SYatharth Kochar link_index = count; 15472600226SYatharth Kochar break; 15572600226SYatharth Kochar } 15672600226SYatharth Kochar } 15772600226SYatharth Kochar 15872600226SYatharth Kochar /* Make sure we have a HEAD node */ 15972600226SYatharth Kochar assert(next_bl_params.head != NULL); 16072600226SYatharth Kochar 16172600226SYatharth Kochar /* Populate the HEAD information */ 16281542c00SAntonio Nino Diaz SET_PARAM_HEAD(&next_bl_params, PARAM_BL_PARAMS, VERSION_2, 0U); 16372600226SYatharth Kochar 16472600226SYatharth Kochar /* 16572600226SYatharth Kochar * Go through the image descriptor array and create the list. 16672600226SYatharth Kochar * This bounded loop is to make sure that we are not looping forever. 16772600226SYatharth Kochar */ 16881542c00SAntonio Nino Diaz for (count = 0U; count < bl_mem_params_desc_num; count++) { 16972600226SYatharth Kochar 17072600226SYatharth Kochar desc_ptr = &bl_mem_params_desc_ptr[link_index]; 17172600226SYatharth Kochar 17272600226SYatharth Kochar /* Make sure the image is executable */ 17372600226SYatharth Kochar assert(EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE); 17472600226SYatharth Kochar 17572600226SYatharth Kochar /* Get the memory for current node */ 17672600226SYatharth Kochar bl_current_exec_node = &desc_ptr->params_node_mem; 17772600226SYatharth Kochar 17872600226SYatharth Kochar /* Populate the image information */ 17972600226SYatharth Kochar bl_current_exec_node->image_id = desc_ptr->image_id; 18072600226SYatharth Kochar bl_current_exec_node->image_info = &desc_ptr->image_info; 18172600226SYatharth Kochar bl_current_exec_node->ep_info = &desc_ptr->ep_info; 18272600226SYatharth Kochar 18381542c00SAntonio Nino Diaz if (bl_last_exec_node != NULL) { 18472600226SYatharth Kochar /* Assert if loop detected */ 18572600226SYatharth Kochar assert(bl_last_exec_node->next_params_info == NULL); 18672600226SYatharth Kochar 18772600226SYatharth Kochar /* Link the previous node to the current one */ 18872600226SYatharth Kochar bl_last_exec_node->next_params_info = bl_current_exec_node; 18972600226SYatharth Kochar } 19072600226SYatharth Kochar 19172600226SYatharth Kochar /* Update the last node */ 19272600226SYatharth Kochar bl_last_exec_node = bl_current_exec_node; 19372600226SYatharth Kochar 19472600226SYatharth Kochar /* If no next hand-off image then break out */ 19572600226SYatharth Kochar img_id = desc_ptr->next_handoff_image_id; 19672600226SYatharth Kochar if (img_id == INVALID_IMAGE_ID) 19772600226SYatharth Kochar break; 19872600226SYatharth Kochar 19972600226SYatharth Kochar /* Get the index for the next hand-off image */ 20072600226SYatharth Kochar link_index = get_bl_params_node_index(img_id); 20181542c00SAntonio Nino Diaz assert((link_index > 0U) && 20272600226SYatharth Kochar (link_index < bl_mem_params_desc_num)); 20372600226SYatharth Kochar } 20472600226SYatharth Kochar 20572600226SYatharth Kochar /* Invalid image is expected to terminate the loop */ 20672600226SYatharth Kochar assert(img_id == INVALID_IMAGE_ID); 20772600226SYatharth Kochar 20872600226SYatharth Kochar return &next_bl_params; 20972600226SYatharth Kochar } 210cab0b5b0SSoby Mathew 211cab0b5b0SSoby Mathew /******************************************************************************* 212cab0b5b0SSoby Mathew * This function populates the entry point information with the corresponding 213cab0b5b0SSoby Mathew * config file for all executable BL images described in bl_params. 214cab0b5b0SSoby Mathew ******************************************************************************/ 215cab0b5b0SSoby Mathew void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params) 216cab0b5b0SSoby Mathew { 217*291e493dSHarrison Mutai /* 218*291e493dSHarrison Mutai * With Firmware Handoff configuration data is shared dynamically, most of 219*291e493dSHarrison Mutai * the *_CONFIG files will be deprecated. Avoid populating the entry point 220*291e493dSHarrison Mutai * arguments with their information as they're discarded anyway. 221*291e493dSHarrison Mutai */ 222*291e493dSHarrison Mutai #if !TRANSFER_LIST 223cab0b5b0SSoby Mathew bl_params_node_t *params_node; 224cab0b5b0SSoby Mathew unsigned int fw_config_id; 22542c33ba3SJavier Almansa Sobrino uintptr_t fw_config_base; 226cab0b5b0SSoby Mathew bl_mem_params_node_t *mem_params; 22742c33ba3SJavier Almansa Sobrino uintptr_t hw_config_base = 0; 228cab0b5b0SSoby Mathew 229da5f2745SSoby Mathew assert(bl2_to_next_bl_params != NULL); 230cab0b5b0SSoby Mathew 231cab0b5b0SSoby Mathew /* 232cab0b5b0SSoby Mathew * Get the `bl_mem_params_node_t` corresponding to HW_CONFIG 233cab0b5b0SSoby Mathew * if available. 234cab0b5b0SSoby Mathew */ 235cab0b5b0SSoby Mathew mem_params = get_bl_mem_params_node(HW_CONFIG_ID); 23642c33ba3SJavier Almansa Sobrino 237cab0b5b0SSoby Mathew if (mem_params != NULL) 238cab0b5b0SSoby Mathew hw_config_base = mem_params->image_info.image_base; 239cab0b5b0SSoby Mathew 240cab0b5b0SSoby Mathew for (params_node = bl2_to_next_bl_params->head; params_node != NULL; 241cab0b5b0SSoby Mathew params_node = params_node->next_params_info) { 242cab0b5b0SSoby Mathew 243cab0b5b0SSoby Mathew fw_config_base = 0; 244cab0b5b0SSoby Mathew 245cab0b5b0SSoby Mathew switch (params_node->image_id) { 246cab0b5b0SSoby Mathew case BL31_IMAGE_ID: 247cab0b5b0SSoby Mathew fw_config_id = SOC_FW_CONFIG_ID; 248cab0b5b0SSoby Mathew break; 249cab0b5b0SSoby Mathew case BL32_IMAGE_ID: 25042c33ba3SJavier Almansa Sobrino /* 25142c33ba3SJavier Almansa Sobrino * At the moment, OPTEE cannot accept a DTB in secure memory, 25242c33ba3SJavier Almansa Sobrino * so fall back and use NT_FW_CONFIG instead. 25342c33ba3SJavier Almansa Sobrino * This MUST be fixed as soon as OPTEE has support to 25442c33ba3SJavier Almansa Sobrino * receive DTBs in secure memory. 25542c33ba3SJavier Almansa Sobrino */ 25642c33ba3SJavier Almansa Sobrino #ifndef SPD_opteed 257cab0b5b0SSoby Mathew fw_config_id = TOS_FW_CONFIG_ID; 258cab0b5b0SSoby Mathew break; 25942c33ba3SJavier Almansa Sobrino #endif 260cab0b5b0SSoby Mathew case BL33_IMAGE_ID: 261cab0b5b0SSoby Mathew fw_config_id = NT_FW_CONFIG_ID; 262cab0b5b0SSoby Mathew break; 263cab0b5b0SSoby Mathew default: 264cab0b5b0SSoby Mathew fw_config_id = INVALID_IMAGE_ID; 265cab0b5b0SSoby Mathew break; 266cab0b5b0SSoby Mathew } 267cab0b5b0SSoby Mathew 268cab0b5b0SSoby Mathew if (fw_config_id != INVALID_IMAGE_ID) { 269cab0b5b0SSoby Mathew mem_params = get_bl_mem_params_node(fw_config_id); 2700cb64d01SAchin Gupta if (mem_params != NULL) { 271cab0b5b0SSoby Mathew fw_config_base = mem_params->image_info.image_base; 272cab0b5b0SSoby Mathew } 2730cb64d01SAchin Gupta } 27442c33ba3SJavier Almansa Sobrino 27542c33ba3SJavier Almansa Sobrino #ifdef SPD_opteed 276cab0b5b0SSoby Mathew /* 27742c33ba3SJavier Almansa Sobrino * If SPD_opteed is enabled, arg[0,2] are populated by 27842c33ba3SJavier Almansa Sobrino * parse_optee_header(), which is called by 27942c33ba3SJavier Almansa Sobrino * arm_bl2_handle_post_image_load(). The meaning of the 28042c33ba3SJavier Almansa Sobrino * arguments are: 28142c33ba3SJavier Almansa Sobrino * arg0 <-- MODE_RW 28242c33ba3SJavier Almansa Sobrino * arg1 <-- Paged image base 28342c33ba3SJavier Almansa Sobrino * arg2 <-- Paged image size 28442c33ba3SJavier Almansa Sobrino */ 28542c33ba3SJavier Almansa Sobrino if (params_node->image_id == BL32_IMAGE_ID) { 28642c33ba3SJavier Almansa Sobrino params_node->ep_info->args.arg3 = fw_config_base; 287*291e493dSHarrison Mutai } else 28842c33ba3SJavier Almansa Sobrino #endif 289*291e493dSHarrison Mutai { 29042c33ba3SJavier Almansa Sobrino /* 29142c33ba3SJavier Almansa Sobrino * Pass hw and tb_fw config addresses to next images. 29242c33ba3SJavier Almansa Sobrino * NOTE - for EL3 runtime images (BL31 for AArch64 29342c33ba3SJavier Almansa Sobrino * and BL32 for AArch32), arg0 is already used by 29442c33ba3SJavier Almansa Sobrino * generic code. Take care of not overwriting the 29542c33ba3SJavier Almansa Sobrino * previous initialisations. 296cab0b5b0SSoby Mathew */ 297cab0b5b0SSoby Mathew if (params_node == bl2_to_next_bl_params->head) { 29881542c00SAntonio Nino Diaz if (params_node->ep_info->args.arg1 == 0U) 2991cc99de8SAmit Daniel Kachhap params_node->ep_info->args.arg1 = 3001cc99de8SAmit Daniel Kachhap fw_config_base; 30181542c00SAntonio Nino Diaz if (params_node->ep_info->args.arg2 == 0U) 3021cc99de8SAmit Daniel Kachhap params_node->ep_info->args.arg2 = 3031cc99de8SAmit Daniel Kachhap hw_config_base; 304*291e493dSHarrison Mutai } 305*291e493dSHarrison Mutai #if USE_KERNEL_DT_CONVENTION 306*291e493dSHarrison Mutai else if (params_node->image_id == BL33_IMAGE_ID) { 307*291e493dSHarrison Mutai hw_config_base = plat_get_hw_dt_base(); 308*291e493dSHarrison Mutai 309*291e493dSHarrison Mutai if (params_node->ep_info->args.arg0 == 0U) { 310*291e493dSHarrison Mutai params_node->ep_info->args.arg0 = 311*291e493dSHarrison Mutai hw_config_base; 312*291e493dSHarrison Mutai } 313*291e493dSHarrison Mutai } 314*291e493dSHarrison Mutai #endif /* USE_KERNEL_DT_CONVENTION */ 315*291e493dSHarrison Mutai else { 316*291e493dSHarrison Mutai if (params_node->ep_info->args.arg0 == 0U) { 3171cc99de8SAmit Daniel Kachhap params_node->ep_info->args.arg0 = 3181cc99de8SAmit Daniel Kachhap fw_config_base; 319*291e493dSHarrison Mutai } 320*291e493dSHarrison Mutai if (params_node->ep_info->args.arg1 == 0U) { 3211cc99de8SAmit Daniel Kachhap params_node->ep_info->args.arg1 = 3221cc99de8SAmit Daniel Kachhap hw_config_base; 323cab0b5b0SSoby Mathew } 32442c33ba3SJavier Almansa Sobrino } 325cab0b5b0SSoby Mathew } 326cab0b5b0SSoby Mathew } 327*291e493dSHarrison Mutai #endif /* !TRANSFER_LIST */ 328*291e493dSHarrison Mutai } 329d9af1f7bSJulius Werner 330d9af1f7bSJulius Werner /******************************************************************************* 331d9af1f7bSJulius Werner * Helper to extract BL32/BL33 entry point info from arg0 passed to BL31, for 332d9af1f7bSJulius Werner * platforms that are only interested in those. Platforms that need to extract 333d9af1f7bSJulius Werner * more information can parse the structures themselves. 334d9af1f7bSJulius Werner ******************************************************************************/ 335d9af1f7bSJulius Werner 336d9af1f7bSJulius Werner void bl31_params_parse_helper(u_register_t param, 337d9af1f7bSJulius Werner entry_point_info_t *bl32_ep_info_out, 338d9af1f7bSJulius Werner entry_point_info_t *bl33_ep_info_out) 339d9af1f7bSJulius Werner { 340d9af1f7bSJulius Werner bl_params_node_t *node; 341d9af1f7bSJulius Werner bl_params_t *v2 = (void *)(uintptr_t)param; 342d9af1f7bSJulius Werner 343d9af1f7bSJulius Werner #if !ERROR_DEPRECATED 344d9af1f7bSJulius Werner if (v2->h.version == PARAM_VERSION_1) { 345d9af1f7bSJulius Werner struct { /* Deprecated version 1 parameter structure. */ 346d9af1f7bSJulius Werner param_header_t h; 347d9af1f7bSJulius Werner image_info_t *bl31_image_info; 348d9af1f7bSJulius Werner entry_point_info_t *bl32_ep_info; 349d9af1f7bSJulius Werner image_info_t *bl32_image_info; 350d9af1f7bSJulius Werner entry_point_info_t *bl33_ep_info; 351d9af1f7bSJulius Werner image_info_t *bl33_image_info; 352d9af1f7bSJulius Werner } *v1 = (void *)(uintptr_t)param; 353d9af1f7bSJulius Werner assert(v1->h.type == PARAM_BL31); 354466bb285SZelalem if (bl32_ep_info_out != NULL) 355d9af1f7bSJulius Werner *bl32_ep_info_out = *v1->bl32_ep_info; 356466bb285SZelalem if (bl33_ep_info_out != NULL) 357d9af1f7bSJulius Werner *bl33_ep_info_out = *v1->bl33_ep_info; 358d9af1f7bSJulius Werner return; 359d9af1f7bSJulius Werner } 360d9af1f7bSJulius Werner #endif /* !ERROR_DEPRECATED */ 361d9af1f7bSJulius Werner 362d9af1f7bSJulius Werner assert(v2->h.version == PARAM_VERSION_2); 363d9af1f7bSJulius Werner assert(v2->h.type == PARAM_BL_PARAMS); 364466bb285SZelalem for (node = v2->head; node != NULL; node = node->next_params_info) { 365d9af1f7bSJulius Werner if (node->image_id == BL32_IMAGE_ID) 366466bb285SZelalem if (bl32_ep_info_out != NULL) 367d9af1f7bSJulius Werner *bl32_ep_info_out = *node->ep_info; 368d9af1f7bSJulius Werner if (node->image_id == BL33_IMAGE_ID) 369466bb285SZelalem if (bl33_ep_info_out != NULL) 370d9af1f7bSJulius Werner *bl33_ep_info_out = *node->ep_info; 371d9af1f7bSJulius Werner } 372d9af1f7bSJulius Werner } 373