desc_image_load.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. /*
  2. * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <arch_helpers.h>
  8. #include <common/bl_common.h>
  9. #include <common/desc_image_load.h>
  10. #include <common/tbbr/tbbr_img_def.h>
  11. static bl_load_info_t bl_load_info;
  12. static bl_params_t next_bl_params;
  13. /*******************************************************************************
  14. * This function flushes the data structures so that they are visible
  15. * in memory for the next BL image.
  16. ******************************************************************************/
  17. void flush_bl_params_desc(void)
  18. {
  19. flush_bl_params_desc_args(bl_mem_params_desc_ptr,
  20. bl_mem_params_desc_num,
  21. &next_bl_params);
  22. }
  23. /*******************************************************************************
  24. * This function flushes the data structures specified as arguments so that they
  25. * are visible in memory for the next BL image.
  26. ******************************************************************************/
  27. void flush_bl_params_desc_args(bl_mem_params_node_t *mem_params_desc_ptr,
  28. unsigned int mem_params_desc_num,
  29. bl_params_t *next_bl_params_ptr)
  30. {
  31. assert(mem_params_desc_ptr != NULL);
  32. assert(mem_params_desc_num != 0U);
  33. assert(next_bl_params_ptr != NULL);
  34. flush_dcache_range((uintptr_t)mem_params_desc_ptr,
  35. sizeof(*mem_params_desc_ptr) * mem_params_desc_num);
  36. flush_dcache_range((uintptr_t)next_bl_params_ptr,
  37. sizeof(*next_bl_params_ptr));
  38. }
  39. /*******************************************************************************
  40. * This function returns the index for given image_id, within the
  41. * image descriptor array provided by bl_image_info_descs_ptr, if the
  42. * image is found else it returns -1.
  43. ******************************************************************************/
  44. int get_bl_params_node_index(unsigned int image_id)
  45. {
  46. unsigned int index;
  47. assert(image_id != INVALID_IMAGE_ID);
  48. for (index = 0U; index < bl_mem_params_desc_num; index++) {
  49. if (bl_mem_params_desc_ptr[index].image_id == image_id)
  50. return (int)index;
  51. }
  52. return -1;
  53. }
  54. /*******************************************************************************
  55. * This function returns the pointer to `bl_mem_params_node_t` object for
  56. * given image_id, within the image descriptor array provided by
  57. * bl_mem_params_desc_ptr, if the image is found else it returns NULL.
  58. ******************************************************************************/
  59. bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id)
  60. {
  61. int index;
  62. assert(image_id != INVALID_IMAGE_ID);
  63. index = get_bl_params_node_index(image_id);
  64. if (index >= 0)
  65. return &bl_mem_params_desc_ptr[index];
  66. else
  67. return NULL;
  68. }
  69. /*******************************************************************************
  70. * This function creates the list of loadable images, by populating and
  71. * linking each `bl_load_info_node_t` type node, using the internal array
  72. * of image descriptor provided by bl_mem_params_desc_ptr. It also populates
  73. * and returns `bl_load_info_t` type structure that contains head of the list
  74. * of loadable images.
  75. ******************************************************************************/
  76. bl_load_info_t *get_bl_load_info_from_mem_params_desc(void)
  77. {
  78. unsigned int index = 0;
  79. /* If there is no image to start with, return NULL */
  80. if (bl_mem_params_desc_num == 0U)
  81. return NULL;
  82. /* Assign initial data structures */
  83. bl_load_info_node_t *bl_node_info =
  84. &bl_mem_params_desc_ptr[index].load_node_mem;
  85. bl_load_info.head = bl_node_info;
  86. SET_PARAM_HEAD(&bl_load_info, PARAM_BL_LOAD_INFO, VERSION_2, 0U);
  87. /* Go through the image descriptor array and create the list */
  88. for (; index < bl_mem_params_desc_num; index++) {
  89. /* Populate the image information */
  90. bl_node_info->image_id = bl_mem_params_desc_ptr[index].image_id;
  91. bl_node_info->image_info = &bl_mem_params_desc_ptr[index].image_info;
  92. /* Link next image if present */
  93. if ((index + 1U) < bl_mem_params_desc_num) {
  94. /* Get the memory and link the next node */
  95. bl_node_info->next_load_info =
  96. &bl_mem_params_desc_ptr[index + 1U].load_node_mem;
  97. bl_node_info = bl_node_info->next_load_info;
  98. }
  99. }
  100. return &bl_load_info;
  101. }
  102. /*******************************************************************************
  103. * This function creates the list of executable images, by populating and
  104. * linking each `bl_params_node_t` type node, using the internal array of
  105. * image descriptor provided by bl_mem_params_desc_ptr. It also populates
  106. * and returns `bl_params_t` type structure that contains head of the list
  107. * of executable images.
  108. ******************************************************************************/
  109. bl_params_t *get_next_bl_params_from_mem_params_desc(void)
  110. {
  111. unsigned int count;
  112. unsigned int img_id = 0U;
  113. unsigned int link_index = 0U;
  114. bl_params_node_t *bl_current_exec_node = NULL;
  115. bl_params_node_t *bl_last_exec_node = NULL;
  116. bl_mem_params_node_t *desc_ptr;
  117. /* If there is no image to start with, return NULL */
  118. if (bl_mem_params_desc_num == 0U)
  119. return NULL;
  120. /* Get the list HEAD */
  121. for (count = 0U; count < bl_mem_params_desc_num; count++) {
  122. desc_ptr = &bl_mem_params_desc_ptr[count];
  123. if ((EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE) &&
  124. (EP_GET_FIRST_EXE(desc_ptr->ep_info.h.attr) == EP_FIRST_EXE)) {
  125. next_bl_params.head = &desc_ptr->params_node_mem;
  126. link_index = count;
  127. break;
  128. }
  129. }
  130. /* Make sure we have a HEAD node */
  131. assert(next_bl_params.head != NULL);
  132. /* Populate the HEAD information */
  133. SET_PARAM_HEAD(&next_bl_params, PARAM_BL_PARAMS, VERSION_2, 0U);
  134. /*
  135. * Go through the image descriptor array and create the list.
  136. * This bounded loop is to make sure that we are not looping forever.
  137. */
  138. for (count = 0U; count < bl_mem_params_desc_num; count++) {
  139. desc_ptr = &bl_mem_params_desc_ptr[link_index];
  140. /* Make sure the image is executable */
  141. assert(EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE);
  142. /* Get the memory for current node */
  143. bl_current_exec_node = &desc_ptr->params_node_mem;
  144. /* Populate the image information */
  145. bl_current_exec_node->image_id = desc_ptr->image_id;
  146. bl_current_exec_node->image_info = &desc_ptr->image_info;
  147. bl_current_exec_node->ep_info = &desc_ptr->ep_info;
  148. if (bl_last_exec_node != NULL) {
  149. /* Assert if loop detected */
  150. assert(bl_last_exec_node->next_params_info == NULL);
  151. /* Link the previous node to the current one */
  152. bl_last_exec_node->next_params_info = bl_current_exec_node;
  153. }
  154. /* Update the last node */
  155. bl_last_exec_node = bl_current_exec_node;
  156. /* If no next hand-off image then break out */
  157. img_id = desc_ptr->next_handoff_image_id;
  158. if (img_id == INVALID_IMAGE_ID)
  159. break;
  160. /* Get the index for the next hand-off image */
  161. link_index = get_bl_params_node_index(img_id);
  162. assert((link_index > 0U) &&
  163. (link_index < bl_mem_params_desc_num));
  164. }
  165. /* Invalid image is expected to terminate the loop */
  166. assert(img_id == INVALID_IMAGE_ID);
  167. return &next_bl_params;
  168. }
  169. /*******************************************************************************
  170. * This function populates the entry point information with the corresponding
  171. * config file for all executable BL images described in bl_params.
  172. ******************************************************************************/
  173. void populate_next_bl_params_config(bl_params_t *bl2_to_next_bl_params)
  174. {
  175. bl_params_node_t *params_node;
  176. unsigned int fw_config_id;
  177. uintptr_t fw_config_base;
  178. bl_mem_params_node_t *mem_params;
  179. uintptr_t hw_config_base = 0;
  180. assert(bl2_to_next_bl_params != NULL);
  181. /*
  182. * Get the `bl_mem_params_node_t` corresponding to HW_CONFIG
  183. * if available.
  184. */
  185. mem_params = get_bl_mem_params_node(HW_CONFIG_ID);
  186. if (mem_params != NULL)
  187. hw_config_base = mem_params->image_info.image_base;
  188. for (params_node = bl2_to_next_bl_params->head; params_node != NULL;
  189. params_node = params_node->next_params_info) {
  190. fw_config_base = 0;
  191. switch (params_node->image_id) {
  192. case BL31_IMAGE_ID:
  193. fw_config_id = SOC_FW_CONFIG_ID;
  194. break;
  195. case BL32_IMAGE_ID:
  196. /*
  197. * At the moment, OPTEE cannot accept a DTB in secure memory,
  198. * so fall back and use NT_FW_CONFIG instead.
  199. * This MUST be fixed as soon as OPTEE has support to
  200. * receive DTBs in secure memory.
  201. */
  202. #ifndef SPD_opteed
  203. fw_config_id = TOS_FW_CONFIG_ID;
  204. break;
  205. #endif
  206. case BL33_IMAGE_ID:
  207. fw_config_id = NT_FW_CONFIG_ID;
  208. break;
  209. default:
  210. fw_config_id = INVALID_IMAGE_ID;
  211. break;
  212. }
  213. if (fw_config_id != INVALID_IMAGE_ID) {
  214. mem_params = get_bl_mem_params_node(fw_config_id);
  215. if (mem_params != NULL) {
  216. fw_config_base = mem_params->image_info.image_base;
  217. }
  218. }
  219. #ifdef SPD_opteed
  220. /*
  221. * If SPD_opteed is enabled, arg[0,2] are populated by
  222. * parse_optee_header(), which is called by
  223. * arm_bl2_handle_post_image_load(). The meaning of the
  224. * arguments are:
  225. * arg0 <-- MODE_RW
  226. * arg1 <-- Paged image base
  227. * arg2 <-- Paged image size
  228. */
  229. if (params_node->image_id == BL32_IMAGE_ID) {
  230. params_node->ep_info->args.arg3 = fw_config_base;
  231. } else {
  232. #endif
  233. /*
  234. * Pass hw and tb_fw config addresses to next images.
  235. * NOTE - for EL3 runtime images (BL31 for AArch64
  236. * and BL32 for AArch32), arg0 is already used by
  237. * generic code. Take care of not overwriting the
  238. * previous initialisations.
  239. */
  240. if (params_node == bl2_to_next_bl_params->head) {
  241. if (params_node->ep_info->args.arg1 == 0U)
  242. params_node->ep_info->args.arg1 =
  243. fw_config_base;
  244. if (params_node->ep_info->args.arg2 == 0U)
  245. params_node->ep_info->args.arg2 =
  246. hw_config_base;
  247. } else {
  248. if (params_node->ep_info->args.arg0 == 0U)
  249. params_node->ep_info->args.arg0 =
  250. fw_config_base;
  251. if (params_node->ep_info->args.arg1 == 0U)
  252. params_node->ep_info->args.arg1 =
  253. hw_config_base;
  254. }
  255. #ifdef SPD_opteed
  256. }
  257. #endif
  258. }
  259. }
  260. /*******************************************************************************
  261. * Helper to extract BL32/BL33 entry point info from arg0 passed to BL31, for
  262. * platforms that are only interested in those. Platforms that need to extract
  263. * more information can parse the structures themselves.
  264. ******************************************************************************/
  265. void bl31_params_parse_helper(u_register_t param,
  266. entry_point_info_t *bl32_ep_info_out,
  267. entry_point_info_t *bl33_ep_info_out)
  268. {
  269. bl_params_node_t *node;
  270. bl_params_t *v2 = (void *)(uintptr_t)param;
  271. #if !ERROR_DEPRECATED
  272. if (v2->h.version == PARAM_VERSION_1) {
  273. struct { /* Deprecated version 1 parameter structure. */
  274. param_header_t h;
  275. image_info_t *bl31_image_info;
  276. entry_point_info_t *bl32_ep_info;
  277. image_info_t *bl32_image_info;
  278. entry_point_info_t *bl33_ep_info;
  279. image_info_t *bl33_image_info;
  280. } *v1 = (void *)(uintptr_t)param;
  281. assert(v1->h.type == PARAM_BL31);
  282. if (bl32_ep_info_out != NULL)
  283. *bl32_ep_info_out = *v1->bl32_ep_info;
  284. if (bl33_ep_info_out != NULL)
  285. *bl33_ep_info_out = *v1->bl33_ep_info;
  286. return;
  287. }
  288. #endif /* !ERROR_DEPRECATED */
  289. assert(v2->h.version == PARAM_VERSION_2);
  290. assert(v2->h.type == PARAM_BL_PARAMS);
  291. for (node = v2->head; node != NULL; node = node->next_params_info) {
  292. if (node->image_id == BL32_IMAGE_ID)
  293. if (bl32_ep_info_out != NULL)
  294. *bl32_ep_info_out = *node->ep_info;
  295. if (node->image_id == BL33_IMAGE_ID)
  296. if (bl33_ep_info_out != NULL)
  297. *bl33_ep_info_out = *node->ep_info;
  298. }
  299. }