int hikey_bl2_handle_post_image_load(unsigned int image_id) { int err = 0; bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); #ifdef SPD_opteed bl_mem_params_node_t *pager_mem_params = NULL; bl_mem_params_node_t *paged_mem_params = NULL; #endif assert(bl_mem_params); switch (image_id) { #ifdef AARCH64 case BL32_IMAGE_ID: #ifdef SPD_opteed pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); assert(pager_mem_params); paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); assert(paged_mem_params); err = parse_optee_header(&bl_mem_params->ep_info, &pager_mem_params->image_info, &paged_mem_params->image_info); if (err != 0) { WARN("OPTEE header parse error.\n"); } #endif bl_mem_params->ep_info.spsr = hikey_get_spsr_for_bl32_entry(); break; #endif case BL33_IMAGE_ID: /* BL33 expects to receive the primary CPU MPID (through r0) */ bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); bl_mem_params->ep_info.spsr = hikey_get_spsr_for_bl33_entry(); break; #ifdef SCP_BL2_BASE case SCP_BL2_IMAGE_ID: /* The subsequent handling of SCP_BL2 is platform specific */ err = plat_hikey_bl2_handle_scp_bl2(&bl_mem_params->image_info); if (err) { WARN("Failure in platform-specific handling of SCP_BL2 image.\n"); } break; #endif default: /* Do nothing in default case */ break; } return err; }
struct image_info *uniphier_get_image_info(unsigned int image_id) { struct bl_mem_params_node *desc; desc = get_bl_mem_params_node(image_id); assert(desc); return &desc->image_info; }
/******************************************************************************* * This function can be used by the platforms to update/use image * information for given `image_id`. ******************************************************************************/ int bl2_plat_handle_post_image_load(unsigned int image_id) { int err = 0; bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); #ifdef SPD_opteed bl_mem_params_node_t *pager_mem_params = NULL; bl_mem_params_node_t *paged_mem_params = NULL; #endif assert(bl_mem_params != NULL); switch (image_id) { case BL32_IMAGE_ID: #ifdef SPD_opteed pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); assert(pager_mem_params); paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); assert(paged_mem_params); err = parse_optee_header(&bl_mem_params->ep_info, &pager_mem_params->image_info, &paged_mem_params->image_info); if (err != 0) WARN("OPTEE header parse error.\n"); #endif bl_mem_params->ep_info.spsr = rpi3_get_spsr_for_bl32_entry(); break; case BL33_IMAGE_ID: /* BL33 expects to receive the primary CPU MPID (through r0) */ bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); bl_mem_params->ep_info.spsr = rpi3_get_spsr_for_bl33_entry(); /* Shutting down the SDHost driver to let BL33 drives SDHost.*/ rpi3_sdhost_stop(); break; default: /* Do nothing in default case */ break; } return err; }
/******************************************************************************* * This function changes the spsr for BL32 image to bypass * the check in BL1 AArch64 exception handler. This is needed in the aarch32 * boot flow as the core comes up in aarch64 and to enter the BL32 image a warm * reset in aarch32 state is required. ******************************************************************************/ int bl2_plat_handle_post_image_load(unsigned int image_id) { int err = arm_bl2_handle_post_image_load(image_id); if (!err && (image_id == BL32_IMAGE_ID)) { bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); assert(bl_mem_params); bl_mem_params->ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); } return err; }
int ls_bl2_handle_post_image_load(unsigned int image_id) { int err = 0; bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); assert(bl_mem_params); switch (image_id) { #ifdef AARCH64 case BL32_IMAGE_ID: bl_mem_params->ep_info.spsr = ls_get_spsr_for_bl32_entry(); break; #endif case BL33_IMAGE_ID: /* BL33 expects to receive the primary CPU MPID (through r0) */ bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); bl_mem_params->ep_info.spsr = ls_get_spsr_for_bl33_entry(); break; } return err; }
/* * BL2 utility function to initialize dynamic configuration specified by * TB_FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if * specified in TB_FW_CONFIG. */ void arm_bl2_dyn_cfg_init(void) { int err = 0, tb_fw_node; unsigned int i; bl_mem_params_node_t *cfg_mem_params = NULL; uint64_t image_base; uint32_t image_size; const unsigned int config_ids[] = { HW_CONFIG_ID, SOC_FW_CONFIG_ID, NT_FW_CONFIG_ID, #ifdef SPD_tspd /* Currently tos_fw_config is only present for TSP */ TOS_FW_CONFIG_ID #endif }; if (tb_fw_cfg_dtb == NULL) { VERBOSE("No TB_FW_CONFIG specified\n"); return; } err = arm_dyn_tb_fw_cfg_init(tb_fw_cfg_dtb, &tb_fw_node); if (err < 0) { ERROR("Invalid TB_FW_CONFIG passed from BL1\n"); panic(); } /* Iterate through all the fw config IDs */ for (i = 0; i < ARRAY_SIZE(config_ids); i++) { /* Get the config load address and size from TB_FW_CONFIG */ cfg_mem_params = get_bl_mem_params_node(config_ids[i]); if (cfg_mem_params == NULL) { VERBOSE("Couldn't find HW_CONFIG in bl_mem_params_node\n"); continue; } err = arm_dyn_get_config_load_info(tb_fw_cfg_dtb, tb_fw_node, config_ids[i], &image_base, &image_size); if (err < 0) { VERBOSE("Couldn't find config_id %d load info in TB_FW_CONFIG\n", config_ids[i]); continue; } /* * Do some runtime checks on the load addresses of soc_fw_config, * tos_fw_config, nt_fw_config. This is not a comprehensive check * of all invalid addresses but to prevent trivial porting errors. */ if (config_ids[i] != HW_CONFIG_ID) { if (check_uptr_overflow(image_base, image_size)) continue; #ifdef BL31_BASE /* Ensure the configs don't overlap with BL31 */ if ((image_base > BL31_BASE) || ((image_base + image_size) > BL31_BASE)) continue; #endif /* Ensure the configs are loaded in a valid address */ if (image_base < ARM_BL_RAM_BASE) continue; #ifdef BL32_BASE /* * If BL32 is present, ensure that the configs don't * overlap with it. */ if (image_base >= BL32_BASE && image_base <= BL32_LIMIT) continue; #endif } cfg_mem_params->image_info.image_base = (uintptr_t)image_base; cfg_mem_params->image_info.image_max_size = image_size; /* Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from HW_CONFIG node */ cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; } #if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH) uint32_t disable_auth = 0; err = arm_dyn_get_disable_auth(tb_fw_cfg_dtb, tb_fw_node, &disable_auth); if (err < 0) return; if (disable_auth == 1) dyn_disable_auth(); #endif }
/******************************************************************************* * This function populates the entry point information with the corresponding * config file for all executable BL images described in bl_params. ******************************************************************************/ void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params) { bl_params_node_t *params_node; unsigned int fw_config_id; uintptr_t hw_config_base = 0, fw_config_base; bl_mem_params_node_t *mem_params; assert(bl2_to_next_bl_params != NULL); /* * Get the `bl_mem_params_node_t` corresponding to HW_CONFIG * if available. */ mem_params = get_bl_mem_params_node(HW_CONFIG_ID); if (mem_params != NULL) hw_config_base = mem_params->image_info.image_base; for (params_node = bl2_to_next_bl_params->head; params_node != NULL; params_node = params_node->next_params_info) { fw_config_base = 0; switch (params_node->image_id) { case BL31_IMAGE_ID: fw_config_id = SOC_FW_CONFIG_ID; break; case BL32_IMAGE_ID: fw_config_id = TOS_FW_CONFIG_ID; break; case BL33_IMAGE_ID: fw_config_id = NT_FW_CONFIG_ID; break; default: fw_config_id = INVALID_IMAGE_ID; break; } if (fw_config_id != INVALID_IMAGE_ID) { mem_params = get_bl_mem_params_node(fw_config_id); if (mem_params != NULL) fw_config_base = mem_params->image_info.image_base; } /* * Pass hw and tb_fw config addresses to next images. NOTE - for * EL3 runtime images (BL31 for AArch64 and BL32 for AArch32), * arg0 is already used by generic code. Take care of not * overwriting the previous initialisations. */ if (params_node == bl2_to_next_bl_params->head) { if (params_node->ep_info->args.arg1 == 0) params_node->ep_info->args.arg1 = fw_config_base; if (params_node->ep_info->args.arg2 == 0) params_node->ep_info->args.arg2 = hw_config_base; } else { if (params_node->ep_info->args.arg0 == 0) params_node->ep_info->args.arg0 = fw_config_base; if (params_node->ep_info->args.arg1 == 0) params_node->ep_info->args.arg1 = hw_config_base; } } }