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