qemu_bl31_setup.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*
  2. * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <common/bl_common.h>
  8. #include <drivers/arm/pl061_gpio.h>
  9. #include <lib/gpt_rme/gpt_rme.h>
  10. #include <lib/transfer_list.h>
  11. #include <plat/common/platform.h>
  12. #if ENABLE_RME
  13. #ifdef PLAT_qemu
  14. #include <qemu_pas_def.h>
  15. #elif PLAT_qemu_sbsa
  16. #include <qemu_sbsa_pas_def.h>
  17. #endif /* PLAT_qemu */
  18. #endif /* ENABLE_RME */
  19. #ifdef PLAT_qemu_sbsa
  20. #include <sbsa_platform.h>
  21. #endif
  22. #include "qemu_private.h"
  23. #define MAP_BL31_TOTAL MAP_REGION_FLAT( \
  24. BL31_BASE, \
  25. BL31_END - BL31_BASE, \
  26. MT_MEMORY | MT_RW | EL3_PAS)
  27. #define MAP_BL31_RO MAP_REGION_FLAT( \
  28. BL_CODE_BASE, \
  29. BL_CODE_END - BL_CODE_BASE, \
  30. MT_CODE | EL3_PAS), \
  31. MAP_REGION_FLAT( \
  32. BL_RO_DATA_BASE, \
  33. BL_RO_DATA_END \
  34. - BL_RO_DATA_BASE, \
  35. MT_RO_DATA | EL3_PAS)
  36. #if USE_COHERENT_MEM
  37. #define MAP_BL_COHERENT_RAM MAP_REGION_FLAT( \
  38. BL_COHERENT_RAM_BASE, \
  39. BL_COHERENT_RAM_END \
  40. - BL_COHERENT_RAM_BASE, \
  41. MT_DEVICE | MT_RW | EL3_PAS)
  42. #endif
  43. /*
  44. * Placeholder variables for copying the arguments that have been passed to
  45. * BL3-1 from BL2.
  46. */
  47. static entry_point_info_t bl32_image_ep_info;
  48. static entry_point_info_t bl33_image_ep_info;
  49. #if ENABLE_RME
  50. static entry_point_info_t rmm_image_ep_info;
  51. #endif
  52. static struct transfer_list_header *bl31_tl;
  53. /*******************************************************************************
  54. * Perform any BL3-1 early platform setup. Here is an opportunity to copy
  55. * parameters passed by the calling EL (S-EL1 in BL2 & EL3 in BL1) before
  56. * they are lost (potentially). This needs to be done before the MMU is
  57. * initialized so that the memory layout can be used while creating page
  58. * tables. BL2 has flushed this information to memory, so we are guaranteed
  59. * to pick up good data.
  60. ******************************************************************************/
  61. void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
  62. u_register_t arg2, u_register_t arg3)
  63. {
  64. /* Initialize the console to provide early debug support */
  65. qemu_console_init();
  66. /* Platform names have to be lowercase. */
  67. #ifdef PLAT_qemu_sbsa
  68. sbsa_platform_init();
  69. #endif
  70. /*
  71. * Check params passed from BL2
  72. */
  73. bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
  74. assert(params_from_bl2);
  75. assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
  76. assert(params_from_bl2->h.version >= VERSION_2);
  77. bl_params_node_t *bl_params = params_from_bl2->head;
  78. /*
  79. * Copy BL33, BL32 and RMM (if present), entry point information.
  80. * They are stored in Secure RAM, in BL2's address space.
  81. */
  82. while (bl_params) {
  83. if (bl_params->image_id == BL32_IMAGE_ID)
  84. bl32_image_ep_info = *bl_params->ep_info;
  85. #if ENABLE_RME
  86. if (bl_params->image_id == RMM_IMAGE_ID)
  87. rmm_image_ep_info = *bl_params->ep_info;
  88. #endif
  89. if (bl_params->image_id == BL33_IMAGE_ID)
  90. bl33_image_ep_info = *bl_params->ep_info;
  91. bl_params = bl_params->next_params_info;
  92. }
  93. if (!bl33_image_ep_info.pc)
  94. panic();
  95. #if ENABLE_RME
  96. if (!rmm_image_ep_info.pc)
  97. panic();
  98. #endif
  99. if (TRANSFER_LIST && arg1 == (TRANSFER_LIST_SIGNATURE |
  100. REGISTER_CONVENTION_VERSION_MASK) &&
  101. transfer_list_check_header((void *)arg3) != TL_OPS_NON) {
  102. bl31_tl = (void *)arg3; /* saved TL address from BL2 */
  103. }
  104. }
  105. #if ENABLE_RME
  106. #if PLAT_qemu
  107. /*
  108. * The GPT library might modify the gpt regions structure to optimize
  109. * the layout, so the array cannot be constant.
  110. */
  111. static pas_region_t pas_regions[] = {
  112. QEMU_PAS_ROOT,
  113. QEMU_PAS_SECURE,
  114. QEMU_PAS_GPTS,
  115. QEMU_PAS_NS0,
  116. QEMU_PAS_REALM,
  117. QEMU_PAS_NS1,
  118. };
  119. static inline void bl31_adjust_pas_regions(void) {}
  120. #elif PLAT_qemu_sbsa
  121. /*
  122. * The GPT library might modify the gpt regions structure to optimize
  123. * the layout, so the array cannot be constant.
  124. */
  125. static pas_region_t pas_regions[] = {
  126. QEMU_PAS_ROOT,
  127. QEMU_PAS_SECURE,
  128. QEMU_PAS_GPTS,
  129. QEMU_PAS_REALM,
  130. QEMU_PAS_NS0,
  131. };
  132. static void bl31_adjust_pas_regions(void)
  133. {
  134. uint64_t base_addr = 0, total_size = 0;
  135. struct platform_memory_data data;
  136. uint32_t node;
  137. /*
  138. * The amount of memory supported by the SBSA platform is dynamic
  139. * and dependent on user input. Since the configuration of the GPT
  140. * needs to reflect the system memory, QEMU_PAS_NS0 needs to be set
  141. * based on the information found in the device tree.
  142. */
  143. for (node = 0; node < sbsa_platform_num_memnodes(); node++) {
  144. data = sbsa_platform_memory_node(node);
  145. if (data.nodeid == 0) {
  146. base_addr = data.addr_base;
  147. }
  148. total_size += data.addr_size;
  149. }
  150. /* Index '4' correspond to QEMU_PAS_NS0, see pas_regions[] above */
  151. pas_regions[4].base_pa = base_addr;
  152. pas_regions[4].size = total_size;
  153. }
  154. #endif /* PLAT_qemu */
  155. static void bl31_plat_gpt_setup(void)
  156. {
  157. /*
  158. * Initialize entire protected space to GPT_GPI_ANY. With each L0 entry
  159. * covering 1GB (currently the only supported option), then covering
  160. * 256TB of RAM (48-bit PA) would require a 2MB L0 region. At the
  161. * moment we use a 8KB table, which covers 1TB of RAM (40-bit PA).
  162. */
  163. if (gpt_init_l0_tables(PLATFORM_GPCCR_PPS, PLAT_QEMU_L0_GPT_BASE,
  164. PLAT_QEMU_L0_GPT_SIZE +
  165. PLAT_QEMU_GPT_BITLOCK_SIZE) < 0) {
  166. ERROR("gpt_init_l0_tables() failed!\n");
  167. panic();
  168. }
  169. bl31_adjust_pas_regions();
  170. /* Carve out defined PAS ranges. */
  171. if (gpt_init_pas_l1_tables(GPCCR_PGS_4K,
  172. PLAT_QEMU_L1_GPT_BASE,
  173. PLAT_QEMU_L1_GPT_SIZE,
  174. pas_regions,
  175. (unsigned int)(sizeof(pas_regions) /
  176. sizeof(pas_region_t))) < 0) {
  177. ERROR("gpt_init_pas_l1_tables() failed!\n");
  178. panic();
  179. }
  180. INFO("Enabling Granule Protection Checks\n");
  181. if (gpt_enable() < 0) {
  182. ERROR("gpt_enable() failed!\n");
  183. panic();
  184. }
  185. }
  186. #endif
  187. void bl31_plat_arch_setup(void)
  188. {
  189. const mmap_region_t bl_regions[] = {
  190. MAP_BL31_TOTAL,
  191. MAP_BL31_RO,
  192. #if USE_COHERENT_MEM
  193. MAP_BL_COHERENT_RAM,
  194. #endif
  195. #if ENABLE_RME
  196. MAP_GPT_L0_REGION,
  197. MAP_GPT_L1_REGION,
  198. MAP_RMM_SHARED_MEM,
  199. #endif
  200. {0}
  201. };
  202. setup_page_tables(bl_regions, plat_qemu_get_mmap());
  203. enable_mmu_el3(0);
  204. #if ENABLE_RME
  205. /* Initialise and enable granule protection after MMU. */
  206. bl31_plat_gpt_setup();
  207. /*
  208. * Initialise Granule Protection library and enable GPC for the primary
  209. * processor. The tables have already been initialized by a previous BL
  210. * stage, so there is no need to provide any PAS here. This function
  211. * sets up pointers to those tables.
  212. */
  213. if (gpt_runtime_init() < 0) {
  214. ERROR("gpt_runtime_init() failed!\n");
  215. panic();
  216. }
  217. #endif /* ENABLE_RME */
  218. }
  219. static void qemu_gpio_init(void)
  220. {
  221. #ifdef SECURE_GPIO_BASE
  222. pl061_gpio_init();
  223. pl061_gpio_register(SECURE_GPIO_BASE, 0);
  224. #endif
  225. }
  226. void bl31_platform_setup(void)
  227. {
  228. plat_qemu_gic_init();
  229. qemu_gpio_init();
  230. }
  231. unsigned int plat_get_syscnt_freq2(void)
  232. {
  233. return read_cntfrq_el0();
  234. }
  235. /*******************************************************************************
  236. * Return a pointer to the 'entry_point_info' structure of the next image
  237. * for the security state specified. BL3-3 corresponds to the non-secure
  238. * image type while BL3-2 corresponds to the secure image type. A NULL
  239. * pointer is returned if the image does not exist.
  240. ******************************************************************************/
  241. entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
  242. {
  243. entry_point_info_t *next_image_info;
  244. assert(sec_state_is_valid(type));
  245. if (type == NON_SECURE) {
  246. next_image_info = &bl33_image_ep_info;
  247. }
  248. #if ENABLE_RME
  249. else if (type == REALM) {
  250. next_image_info = &rmm_image_ep_info;
  251. }
  252. #endif
  253. else {
  254. next_image_info = &bl32_image_ep_info;
  255. }
  256. /*
  257. * None of the images on the ARM development platforms can have 0x0
  258. * as the entrypoint
  259. */
  260. if (next_image_info->pc)
  261. return next_image_info;
  262. else
  263. return NULL;
  264. }
  265. void bl31_plat_runtime_setup(void)
  266. {
  267. #if TRANSFER_LIST
  268. if (bl31_tl) {
  269. /*
  270. * update the TL from S to NS memory before jump to BL33
  271. * to reflect all changes in TL done by BL32
  272. */
  273. memcpy((void *)FW_NS_HANDOFF_BASE, bl31_tl, bl31_tl->max_size);
  274. }
  275. #endif
  276. console_flush();
  277. console_switch_state(CONSOLE_FLAG_RUNTIME);
  278. }