1 /* 2 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arch_helpers.h> 8 #include <arm_def.h> 9 #include <assert.h> 10 #include <bl_common.h> 11 #include <console.h> 12 #include <debug.h> 13 #include <desc_image_load.h> 14 #include <plat_arm.h> 15 #include <platform_def.h> 16 #include <string.h> 17 #include <utils.h> 18 19 /* Data structure which holds the extents of the trusted SRAM for BL2 */ 20 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); 21 22 /* Weak definitions may be overridden in specific ARM standard platform */ 23 #pragma weak bl2_early_platform_setup 24 #pragma weak bl2_platform_setup 25 #pragma weak bl2_plat_arch_setup 26 #pragma weak bl2_plat_sec_mem_layout 27 28 #if LOAD_IMAGE_V2 29 30 #pragma weak bl2_plat_handle_post_image_load 31 32 #else /* LOAD_IMAGE_V2 */ 33 34 /******************************************************************************* 35 * This structure represents the superset of information that is passed to 36 * BL31, e.g. while passing control to it from BL2, bl31_params 37 * and other platform specific params 38 ******************************************************************************/ 39 typedef struct bl2_to_bl31_params_mem { 40 bl31_params_t bl31_params; 41 image_info_t bl31_image_info; 42 image_info_t bl32_image_info; 43 image_info_t bl33_image_info; 44 entry_point_info_t bl33_ep_info; 45 entry_point_info_t bl32_ep_info; 46 entry_point_info_t bl31_ep_info; 47 } bl2_to_bl31_params_mem_t; 48 49 50 static bl2_to_bl31_params_mem_t bl31_params_mem; 51 52 53 /* Weak definitions may be overridden in specific ARM standard platform */ 54 #pragma weak bl2_plat_get_bl31_params 55 #pragma weak bl2_plat_get_bl31_ep_info 56 #pragma weak bl2_plat_flush_bl31_params 57 #pragma weak bl2_plat_set_bl31_ep_info 58 #pragma weak bl2_plat_get_scp_bl2_meminfo 59 #pragma weak bl2_plat_get_bl32_meminfo 60 #pragma weak bl2_plat_set_bl32_ep_info 61 #pragma weak bl2_plat_get_bl33_meminfo 62 #pragma weak bl2_plat_set_bl33_ep_info 63 64 #if ARM_BL31_IN_DRAM 65 meminfo_t *bl2_plat_sec_mem_layout(void) 66 { 67 static meminfo_t bl2_dram_layout 68 __aligned(CACHE_WRITEBACK_GRANULE) = { 69 .total_base = BL31_BASE, 70 .total_size = (ARM_AP_TZC_DRAM1_BASE + 71 ARM_AP_TZC_DRAM1_SIZE) - BL31_BASE, 72 .free_base = BL31_BASE, 73 .free_size = (ARM_AP_TZC_DRAM1_BASE + 74 ARM_AP_TZC_DRAM1_SIZE) - BL31_BASE 75 }; 76 77 return &bl2_dram_layout; 78 } 79 #else 80 meminfo_t *bl2_plat_sec_mem_layout(void) 81 { 82 return &bl2_tzram_layout; 83 } 84 #endif /* ARM_BL31_IN_DRAM */ 85 86 /******************************************************************************* 87 * This function assigns a pointer to the memory that the platform has kept 88 * aside to pass platform specific and trusted firmware related information 89 * to BL31. This memory is allocated by allocating memory to 90 * bl2_to_bl31_params_mem_t structure which is a superset of all the 91 * structure whose information is passed to BL31 92 * NOTE: This function should be called only once and should be done 93 * before generating params to BL31 94 ******************************************************************************/ 95 bl31_params_t *bl2_plat_get_bl31_params(void) 96 { 97 bl31_params_t *bl2_to_bl31_params; 98 99 /* 100 * Initialise the memory for all the arguments that needs to 101 * be passed to BL31 102 */ 103 zeromem(&bl31_params_mem, sizeof(bl2_to_bl31_params_mem_t)); 104 105 /* Assign memory for TF related information */ 106 bl2_to_bl31_params = &bl31_params_mem.bl31_params; 107 SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0); 108 109 /* Fill BL31 related information */ 110 bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info; 111 SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY, 112 VERSION_1, 0); 113 114 /* Fill BL32 related information if it exists */ 115 #ifdef BL32_BASE 116 bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info; 117 SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP, 118 VERSION_1, 0); 119 bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info; 120 SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY, 121 VERSION_1, 0); 122 #endif /* BL32_BASE */ 123 124 /* Fill BL33 related information */ 125 bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info; 126 SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info, 127 PARAM_EP, VERSION_1, 0); 128 129 /* BL33 expects to receive the primary CPU MPID (through x0) */ 130 bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr(); 131 132 bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info; 133 SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY, 134 VERSION_1, 0); 135 136 return bl2_to_bl31_params; 137 } 138 139 /* Flush the TF params and the TF plat params */ 140 void bl2_plat_flush_bl31_params(void) 141 { 142 flush_dcache_range((unsigned long)&bl31_params_mem, 143 sizeof(bl2_to_bl31_params_mem_t)); 144 } 145 146 /******************************************************************************* 147 * This function returns a pointer to the shared memory that the platform 148 * has kept to point to entry point information of BL31 to BL2 149 ******************************************************************************/ 150 struct entry_point_info *bl2_plat_get_bl31_ep_info(void) 151 { 152 #if DEBUG 153 bl31_params_mem.bl31_ep_info.args.arg1 = ARM_BL31_PLAT_PARAM_VAL; 154 #endif 155 156 return &bl31_params_mem.bl31_ep_info; 157 } 158 #endif /* LOAD_IMAGE_V2 */ 159 160 /******************************************************************************* 161 * BL1 has passed the extents of the trusted SRAM that should be visible to BL2 162 * in x0. This memory layout is sitting at the base of the free trusted SRAM. 163 * Copy it to a safe location before its reclaimed by later BL2 functionality. 164 ******************************************************************************/ 165 void arm_bl2_early_platform_setup(meminfo_t *mem_layout) 166 { 167 /* Initialize the console to provide early debug support */ 168 console_init(PLAT_ARM_BOOT_UART_BASE, PLAT_ARM_BOOT_UART_CLK_IN_HZ, 169 ARM_CONSOLE_BAUDRATE); 170 171 /* Setup the BL2 memory layout */ 172 bl2_tzram_layout = *mem_layout; 173 174 /* Initialise the IO layer and register platform IO devices */ 175 plat_arm_io_setup(); 176 } 177 178 void bl2_early_platform_setup(meminfo_t *mem_layout) 179 { 180 arm_bl2_early_platform_setup(mem_layout); 181 } 182 183 /* 184 * Perform ARM standard platform setup. 185 */ 186 void arm_bl2_platform_setup(void) 187 { 188 /* Initialize the secure environment */ 189 plat_arm_security_setup(); 190 } 191 192 void bl2_platform_setup(void) 193 { 194 arm_bl2_platform_setup(); 195 } 196 197 /******************************************************************************* 198 * Perform the very early platform specific architectural setup here. At the 199 * moment this is only initializes the mmu in a quick and dirty way. 200 ******************************************************************************/ 201 void arm_bl2_plat_arch_setup(void) 202 { 203 arm_setup_page_tables(bl2_tzram_layout.total_base, 204 bl2_tzram_layout.total_size, 205 BL_CODE_BASE, 206 BL_CODE_END, 207 BL_RO_DATA_BASE, 208 BL_RO_DATA_END 209 #if USE_COHERENT_MEM 210 , BL_COHERENT_RAM_BASE, 211 BL_COHERENT_RAM_END 212 #endif 213 ); 214 215 #ifdef AARCH32 216 enable_mmu_secure(0); 217 #else 218 enable_mmu_el1(0); 219 #endif 220 } 221 222 void bl2_plat_arch_setup(void) 223 { 224 arm_bl2_plat_arch_setup(); 225 } 226 227 #if LOAD_IMAGE_V2 228 int arm_bl2_handle_post_image_load(unsigned int image_id) 229 { 230 int err = 0; 231 bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); 232 assert(bl_mem_params); 233 234 switch (image_id) { 235 #ifdef AARCH64 236 case BL32_IMAGE_ID: 237 bl_mem_params->ep_info.spsr = arm_get_spsr_for_bl32_entry(); 238 break; 239 #endif 240 241 case BL33_IMAGE_ID: 242 /* BL33 expects to receive the primary CPU MPID (through r0) */ 243 bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); 244 bl_mem_params->ep_info.spsr = arm_get_spsr_for_bl33_entry(); 245 break; 246 247 #ifdef SCP_BL2_BASE 248 case SCP_BL2_IMAGE_ID: 249 /* The subsequent handling of SCP_BL2 is platform specific */ 250 err = plat_arm_bl2_handle_scp_bl2(&bl_mem_params->image_info); 251 if (err) { 252 WARN("Failure in platform-specific handling of SCP_BL2 image.\n"); 253 } 254 break; 255 #endif 256 } 257 258 return err; 259 } 260 261 /******************************************************************************* 262 * This function can be used by the platforms to update/use image 263 * information for given `image_id`. 264 ******************************************************************************/ 265 int bl2_plat_handle_post_image_load(unsigned int image_id) 266 { 267 return arm_bl2_handle_post_image_load(image_id); 268 } 269 270 #else /* LOAD_IMAGE_V2 */ 271 272 /******************************************************************************* 273 * Populate the extents of memory available for loading SCP_BL2 (if used), 274 * i.e. anywhere in trusted RAM as long as it doesn't overwrite BL2. 275 ******************************************************************************/ 276 void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo) 277 { 278 *scp_bl2_meminfo = bl2_tzram_layout; 279 } 280 281 /******************************************************************************* 282 * Before calling this function BL31 is loaded in memory and its entrypoint 283 * is set by load_image. This is a placeholder for the platform to change 284 * the entrypoint of BL31 and set SPSR and security state. 285 * On ARM standard platforms we only set the security state of the entrypoint 286 ******************************************************************************/ 287 void bl2_plat_set_bl31_ep_info(image_info_t *bl31_image_info, 288 entry_point_info_t *bl31_ep_info) 289 { 290 SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE); 291 bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, 292 DISABLE_ALL_EXCEPTIONS); 293 } 294 295 296 /******************************************************************************* 297 * Before calling this function BL32 is loaded in memory and its entrypoint 298 * is set by load_image. This is a placeholder for the platform to change 299 * the entrypoint of BL32 and set SPSR and security state. 300 * On ARM standard platforms we only set the security state of the entrypoint 301 ******************************************************************************/ 302 #ifdef BL32_BASE 303 void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info, 304 entry_point_info_t *bl32_ep_info) 305 { 306 SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE); 307 bl32_ep_info->spsr = arm_get_spsr_for_bl32_entry(); 308 } 309 310 /******************************************************************************* 311 * Populate the extents of memory available for loading BL32 312 ******************************************************************************/ 313 void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo) 314 { 315 /* 316 * Populate the extents of memory available for loading BL32. 317 */ 318 bl32_meminfo->total_base = BL32_BASE; 319 bl32_meminfo->free_base = BL32_BASE; 320 bl32_meminfo->total_size = 321 (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; 322 bl32_meminfo->free_size = 323 (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE; 324 } 325 #endif /* BL32_BASE */ 326 327 /******************************************************************************* 328 * Before calling this function BL33 is loaded in memory and its entrypoint 329 * is set by load_image. This is a placeholder for the platform to change 330 * the entrypoint of BL33 and set SPSR and security state. 331 * On ARM standard platforms we only set the security state of the entrypoint 332 ******************************************************************************/ 333 void bl2_plat_set_bl33_ep_info(image_info_t *image, 334 entry_point_info_t *bl33_ep_info) 335 { 336 SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE); 337 bl33_ep_info->spsr = arm_get_spsr_for_bl33_entry(); 338 } 339 340 /******************************************************************************* 341 * Populate the extents of memory available for loading BL33 342 ******************************************************************************/ 343 void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo) 344 { 345 bl33_meminfo->total_base = ARM_NS_DRAM1_BASE; 346 bl33_meminfo->total_size = ARM_NS_DRAM1_SIZE; 347 bl33_meminfo->free_base = ARM_NS_DRAM1_BASE; 348 bl33_meminfo->free_size = ARM_NS_DRAM1_SIZE; 349 } 350 351 #endif /* LOAD_IMAGE_V2 */ 352