desc_image_load.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /*
  2. * Copyright (c) 2016-2019, 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 hw_config_base = 0, fw_config_base;
  178. bl_mem_params_node_t *mem_params;
  179. assert(bl2_to_next_bl_params != NULL);
  180. /*
  181. * Get the `bl_mem_params_node_t` corresponding to HW_CONFIG
  182. * if available.
  183. */
  184. mem_params = get_bl_mem_params_node(HW_CONFIG_ID);
  185. if (mem_params != NULL)
  186. hw_config_base = mem_params->image_info.image_base;
  187. for (params_node = bl2_to_next_bl_params->head; params_node != NULL;
  188. params_node = params_node->next_params_info) {
  189. fw_config_base = 0;
  190. switch (params_node->image_id) {
  191. case BL31_IMAGE_ID:
  192. fw_config_id = SOC_FW_CONFIG_ID;
  193. break;
  194. case BL32_IMAGE_ID:
  195. fw_config_id = TOS_FW_CONFIG_ID;
  196. break;
  197. case BL33_IMAGE_ID:
  198. fw_config_id = NT_FW_CONFIG_ID;
  199. break;
  200. default:
  201. fw_config_id = INVALID_IMAGE_ID;
  202. break;
  203. }
  204. if (fw_config_id != INVALID_IMAGE_ID) {
  205. mem_params = get_bl_mem_params_node(fw_config_id);
  206. if (mem_params != NULL)
  207. fw_config_base = mem_params->image_info.image_base;
  208. }
  209. /*
  210. * Pass hw and tb_fw config addresses to next images. NOTE - for
  211. * EL3 runtime images (BL31 for AArch64 and BL32 for AArch32),
  212. * arg0 is already used by generic code. Take care of not
  213. * overwriting the previous initialisations.
  214. */
  215. if (params_node == bl2_to_next_bl_params->head) {
  216. if (params_node->ep_info->args.arg1 == 0U)
  217. params_node->ep_info->args.arg1 =
  218. fw_config_base;
  219. if (params_node->ep_info->args.arg2 == 0U)
  220. params_node->ep_info->args.arg2 =
  221. hw_config_base;
  222. } else {
  223. if (params_node->ep_info->args.arg0 == 0U)
  224. params_node->ep_info->args.arg0 =
  225. fw_config_base;
  226. if (params_node->ep_info->args.arg1 == 0U)
  227. params_node->ep_info->args.arg1 =
  228. hw_config_base;
  229. }
  230. }
  231. }
  232. /*******************************************************************************
  233. * Helper to extract BL32/BL33 entry point info from arg0 passed to BL31, for
  234. * platforms that are only interested in those. Platforms that need to extract
  235. * more information can parse the structures themselves.
  236. ******************************************************************************/
  237. void bl31_params_parse_helper(u_register_t param,
  238. entry_point_info_t *bl32_ep_info_out,
  239. entry_point_info_t *bl33_ep_info_out)
  240. {
  241. bl_params_node_t *node;
  242. bl_params_t *v2 = (void *)(uintptr_t)param;
  243. #if !ERROR_DEPRECATED
  244. if (v2->h.version == PARAM_VERSION_1) {
  245. struct { /* Deprecated version 1 parameter structure. */
  246. param_header_t h;
  247. image_info_t *bl31_image_info;
  248. entry_point_info_t *bl32_ep_info;
  249. image_info_t *bl32_image_info;
  250. entry_point_info_t *bl33_ep_info;
  251. image_info_t *bl33_image_info;
  252. } *v1 = (void *)(uintptr_t)param;
  253. assert(v1->h.type == PARAM_BL31);
  254. if (bl32_ep_info_out)
  255. *bl32_ep_info_out = *v1->bl32_ep_info;
  256. if (bl33_ep_info_out)
  257. *bl33_ep_info_out = *v1->bl33_ep_info;
  258. return;
  259. }
  260. #endif /* !ERROR_DEPRECATED */
  261. assert(v2->h.version == PARAM_VERSION_2);
  262. assert(v2->h.type == PARAM_BL_PARAMS);
  263. for (node = v2->head; node; node = node->next_params_info) {
  264. if (node->image_id == BL32_IMAGE_ID)
  265. if (bl32_ep_info_out)
  266. *bl32_ep_info_out = *node->ep_info;
  267. if (node->image_id == BL33_IMAGE_ID)
  268. if (bl33_ep_info_out)
  269. *bl33_ep_info_out = *node->ep_info;
  270. }
  271. }