1 /* 2 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 9 #include <arch.h> 10 #include <arch_helpers.h> 11 #include <common/bl_common.h> 12 #include <common/debug.h> 13 #include <drivers/console.h> 14 #include <lib/extensions/ras.h> 15 #include <lib/mmio.h> 16 #include <lib/utils.h> 17 #include <lib/xlat_tables/xlat_tables_compat.h> 18 #include <plat/arm/common/plat_arm.h> 19 #include <plat/common/platform.h> 20 #include <platform_def.h> 21 22 /* 23 * Placeholder variables for copying the arguments that have been passed to 24 * BL31 from BL2. 25 */ 26 static entry_point_info_t bl32_image_ep_info; 27 static entry_point_info_t bl33_image_ep_info; 28 29 #if !RESET_TO_BL31 30 /* 31 * Check that BL31_BASE is above ARM_TB_FW_CONFIG_LIMIT. The reserved page 32 * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2. 33 */ 34 CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows); 35 #endif 36 37 /* Weak definitions may be overridden in specific ARM standard platform */ 38 #pragma weak bl31_early_platform_setup2 39 #pragma weak bl31_platform_setup 40 #pragma weak bl31_plat_arch_setup 41 #pragma weak bl31_plat_get_next_image_ep_info 42 43 #define MAP_BL31_TOTAL MAP_REGION_FLAT( \ 44 BL31_START, \ 45 BL31_END - BL31_START, \ 46 MT_MEMORY | MT_RW | MT_SECURE) 47 #if RECLAIM_INIT_CODE 48 IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE); 49 IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_INIT_CODE_END); 50 51 #define MAP_BL_INIT_CODE MAP_REGION_FLAT( \ 52 BL_INIT_CODE_BASE, \ 53 BL_INIT_CODE_END \ 54 - BL_INIT_CODE_BASE, \ 55 MT_CODE | MT_SECURE) 56 #endif 57 58 /******************************************************************************* 59 * Return a pointer to the 'entry_point_info' structure of the next image for the 60 * security state specified. BL33 corresponds to the non-secure image type 61 * while BL32 corresponds to the secure image type. A NULL pointer is returned 62 * if the image does not exist. 63 ******************************************************************************/ 64 struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type) 65 { 66 entry_point_info_t *next_image_info; 67 68 assert(sec_state_is_valid(type)); 69 next_image_info = (type == NON_SECURE) 70 ? &bl33_image_ep_info : &bl32_image_ep_info; 71 /* 72 * None of the images on the ARM development platforms can have 0x0 73 * as the entrypoint 74 */ 75 if (next_image_info->pc) 76 return next_image_info; 77 else 78 return NULL; 79 } 80 81 /******************************************************************************* 82 * Perform any BL31 early platform setup common to ARM standard platforms. 83 * Here is an opportunity to copy parameters passed by the calling EL (S-EL1 84 * in BL2 & EL3 in BL1) before they are lost (potentially). This needs to be 85 * done before the MMU is initialized so that the memory layout can be used 86 * while creating page tables. BL2 has flushed this information to memory, so 87 * we are guaranteed to pick up good data. 88 ******************************************************************************/ 89 void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_config, 90 uintptr_t hw_config, void *plat_params_from_bl2) 91 { 92 /* Initialize the console to provide early debug support */ 93 arm_console_boot_init(); 94 95 #if RESET_TO_BL31 96 /* There are no parameters from BL2 if BL31 is a reset vector */ 97 assert(from_bl2 == NULL); 98 assert(plat_params_from_bl2 == NULL); 99 100 # ifdef BL32_BASE 101 /* Populate entry point information for BL32 */ 102 SET_PARAM_HEAD(&bl32_image_ep_info, 103 PARAM_EP, 104 VERSION_1, 105 0); 106 SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); 107 bl32_image_ep_info.pc = BL32_BASE; 108 bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry(); 109 # endif /* BL32_BASE */ 110 111 /* Populate entry point information for BL33 */ 112 SET_PARAM_HEAD(&bl33_image_ep_info, 113 PARAM_EP, 114 VERSION_1, 115 0); 116 /* 117 * Tell BL31 where the non-trusted software image 118 * is located and the entry state information 119 */ 120 bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); 121 122 bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry(); 123 SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); 124 125 # if ARM_LINUX_KERNEL_AS_BL33 126 /* 127 * According to the file ``Documentation/arm64/booting.txt`` of the 128 * Linux kernel tree, Linux expects the physical address of the device 129 * tree blob (DTB) in x0, while x1-x3 are reserved for future use and 130 * must be 0. 131 */ 132 bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE; 133 bl33_image_ep_info.args.arg1 = 0U; 134 bl33_image_ep_info.args.arg2 = 0U; 135 bl33_image_ep_info.args.arg3 = 0U; 136 # endif 137 138 #else /* RESET_TO_BL31 */ 139 140 /* 141 * In debug builds, we pass a special value in 'plat_params_from_bl2' 142 * to verify platform parameters from BL2 to BL31. 143 * In release builds, it's not used. 144 */ 145 assert(((unsigned long long)plat_params_from_bl2) == 146 ARM_BL31_PLAT_PARAM_VAL); 147 148 /* 149 * Check params passed from BL2 should not be NULL, 150 */ 151 bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2; 152 assert(params_from_bl2 != NULL); 153 assert(params_from_bl2->h.type == PARAM_BL_PARAMS); 154 assert(params_from_bl2->h.version >= VERSION_2); 155 156 bl_params_node_t *bl_params = params_from_bl2->head; 157 158 /* 159 * Copy BL33 and BL32 (if present), entry point information. 160 * They are stored in Secure RAM, in BL2's address space. 161 */ 162 while (bl_params != NULL) { 163 if (bl_params->image_id == BL32_IMAGE_ID) 164 bl32_image_ep_info = *bl_params->ep_info; 165 166 if (bl_params->image_id == BL33_IMAGE_ID) 167 bl33_image_ep_info = *bl_params->ep_info; 168 169 bl_params = bl_params->next_params_info; 170 } 171 172 if (bl33_image_ep_info.pc == 0U) 173 panic(); 174 #endif /* RESET_TO_BL31 */ 175 } 176 177 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, 178 u_register_t arg2, u_register_t arg3) 179 { 180 arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); 181 182 /* 183 * Initialize Interconnect for this cluster during cold boot. 184 * No need for locks as no other CPU is active. 185 */ 186 plat_arm_interconnect_init(); 187 188 /* 189 * Enable Interconnect coherency for the primary CPU's cluster. 190 * Earlier bootloader stages might already do this (e.g. Trusted 191 * Firmware's BL1 does it) but we can't assume so. There is no harm in 192 * executing this code twice anyway. 193 * Platform specific PSCI code will enable coherency for other 194 * clusters. 195 */ 196 plat_arm_interconnect_enter_coherency(); 197 } 198 199 /******************************************************************************* 200 * Perform any BL31 platform setup common to ARM standard platforms 201 ******************************************************************************/ 202 void arm_bl31_platform_setup(void) 203 { 204 /* Initialize the GIC driver, cpu and distributor interfaces */ 205 plat_arm_gic_driver_init(); 206 plat_arm_gic_init(); 207 208 #if RESET_TO_BL31 209 /* 210 * Do initial security configuration to allow DRAM/device access 211 * (if earlier BL has not already done so). 212 */ 213 plat_arm_security_setup(); 214 215 #if defined(PLAT_ARM_MEM_PROT_ADDR) 216 arm_nor_psci_do_dyn_mem_protect(); 217 #endif /* PLAT_ARM_MEM_PROT_ADDR */ 218 219 #endif /* RESET_TO_BL31 */ 220 221 /* Enable and initialize the System level generic timer */ 222 mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF, 223 CNTCR_FCREQ(0U) | CNTCR_EN); 224 225 /* Allow access to the System counter timer module */ 226 arm_configure_sys_timer(); 227 228 /* Initialize power controller before setting up topology */ 229 plat_arm_pwrc_setup(); 230 231 #if RAS_EXTENSION 232 ras_init(); 233 #endif 234 } 235 236 /******************************************************************************* 237 * Perform any BL31 platform runtime setup prior to BL31 exit common to ARM 238 * standard platforms 239 * Perform BL31 platform setup 240 ******************************************************************************/ 241 void arm_bl31_plat_runtime_setup(void) 242 { 243 #if MULTI_CONSOLE_API 244 console_switch_state(CONSOLE_FLAG_RUNTIME); 245 #else 246 console_uninit(); 247 #endif 248 249 /* Initialize the runtime console */ 250 arm_console_runtime_init(); 251 #if RECLAIM_INIT_CODE 252 arm_free_init_memory(); 253 #endif 254 } 255 256 #if RECLAIM_INIT_CODE 257 /* 258 * Zero out and make RW memory used to store image boot time code so it can 259 * be reclaimed during runtime 260 */ 261 void arm_free_init_memory(void) 262 { 263 int ret = xlat_change_mem_attributes(BL_INIT_CODE_BASE, 264 BL_INIT_CODE_END - BL_INIT_CODE_BASE, 265 MT_RW_DATA); 266 267 if (ret != 0) { 268 ERROR("Could not reclaim initialization code"); 269 panic(); 270 } 271 } 272 #endif 273 274 void __init bl31_platform_setup(void) 275 { 276 arm_bl31_platform_setup(); 277 } 278 279 void bl31_plat_runtime_setup(void) 280 { 281 arm_bl31_plat_runtime_setup(); 282 } 283 284 /******************************************************************************* 285 * Perform the very early platform specific architectural setup shared between 286 * ARM standard platforms. This only does basic initialization. Later 287 * architectural setup (bl31_arch_setup()) does not do anything platform 288 * specific. 289 ******************************************************************************/ 290 void __init arm_bl31_plat_arch_setup(void) 291 { 292 const mmap_region_t bl_regions[] = { 293 MAP_BL31_TOTAL, 294 #if RECLAIM_INIT_CODE 295 MAP_BL_INIT_CODE, 296 #endif 297 ARM_MAP_BL_RO, 298 #if USE_ROMLIB 299 ARM_MAP_ROMLIB_CODE, 300 ARM_MAP_ROMLIB_DATA, 301 #endif 302 #if USE_COHERENT_MEM 303 ARM_MAP_BL_COHERENT_RAM, 304 #endif 305 {0} 306 }; 307 308 setup_page_tables(bl_regions, plat_arm_get_mmap()); 309 310 enable_mmu_el3(0); 311 312 arm_setup_romlib(); 313 } 314 315 void __init bl31_plat_arch_setup(void) 316 { 317 arm_bl31_plat_arch_setup(); 318 } 319