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 <arch.h> 10 #include <arch_helpers.h> 11 #include <common/bl_common.h> 12 #include <common/debug.h> 13 #include <drivers/arm/sp804_delay_timer.h> 14 #include <lib/utils.h> 15 #include <plat/common/platform.h> 16 17 #include <bcm_console.h> 18 #include <plat_brcm.h> 19 #include <platform_def.h> 20 21 #ifdef BL33_SHARED_DDR_BASE 22 struct bl33_info *bl33_info = (struct bl33_info *)BL33_SHARED_DDR_BASE; 23 #endif 24 25 /* 26 * Placeholder variables for copying the arguments that have been passed to 27 * BL31 from BL2. 28 */ 29 static entry_point_info_t bl32_image_ep_info; 30 static entry_point_info_t bl33_image_ep_info; 31 32 /* Weak definitions may be overridden in specific BRCM platform */ 33 #pragma weak plat_bcm_bl31_early_platform_setup 34 #pragma weak plat_brcm_pwrc_setup 35 #pragma weak plat_brcm_security_setup 36 37 void plat_brcm_security_setup(void) 38 { 39 40 } 41 42 void plat_brcm_pwrc_setup(void) 43 { 44 45 } 46 47 void plat_bcm_bl31_early_platform_setup(void *from_bl2, 48 bl_params_t *plat_params_from_bl2) 49 { 50 51 } 52 53 /******************************************************************************* 54 * Return a pointer to the 'entry_point_info' structure of the next image for 55 * the security state specified. BL33 corresponds to the non-secure image type 56 * while BL32 corresponds to the secure image type. A NULL pointer is returned 57 * if the image does not exist. 58 ******************************************************************************/ 59 struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type) 60 { 61 entry_point_info_t *next_image_info; 62 63 assert(sec_state_is_valid(type)); 64 next_image_info = (type == NON_SECURE) 65 ? &bl33_image_ep_info : &bl32_image_ep_info; 66 /* 67 * None of the images on the ARM development platforms can have 0x0 68 * as the entrypoint 69 */ 70 if (next_image_info->pc) 71 return next_image_info; 72 else 73 return NULL; 74 } 75 76 /******************************************************************************* 77 * Perform any BL31 early platform setup common to ARM standard platforms. 78 * Here is an opportunity to copy parameters passed by the calling EL (S-EL1 79 * in BL2 & EL3 in BL1) before they are lost (potentially). This needs to be 80 * done before the MMU is initialized so that the memory layout can be used 81 * while creating page tables. BL2 has flushed this information to memory, so 82 * we are guaranteed to pick up good data. 83 ******************************************************************************/ 84 void __init brcm_bl31_early_platform_setup(void *from_bl2, 85 uintptr_t soc_fw_config, 86 uintptr_t hw_config, 87 void *plat_params_from_bl2) 88 { 89 /* Initialize the console to provide early debug support */ 90 bcm_console_boot_init(); 91 92 /* Initialize delay timer driver using SP804 dual timer 0 */ 93 sp804_timer_init(SP804_TIMER0_BASE, 94 SP804_TIMER0_CLKMULT, SP804_TIMER0_CLKDIV); 95 96 #if RESET_TO_BL31 97 /* There are no parameters from BL2 if BL31 is a reset vector */ 98 assert(from_bl2 == NULL); 99 assert(plat_params_from_bl2 == NULL); 100 101 # ifdef BL32_BASE 102 /* Populate entry point information for BL32 */ 103 SET_PARAM_HEAD(&bl32_image_ep_info, 104 PARAM_EP, 105 VERSION_1, 106 0); 107 SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); 108 bl32_image_ep_info.pc = BL32_BASE; 109 bl32_image_ep_info.spsr = brcm_get_spsr_for_bl32_entry(); 110 # endif /* BL32_BASE */ 111 112 /* Populate entry point information for BL33 */ 113 SET_PARAM_HEAD(&bl33_image_ep_info, 114 PARAM_EP, 115 VERSION_1, 116 0); 117 /* 118 * Tell BL31 where the non-trusted software image 119 * is located and the entry state information 120 */ 121 bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); 122 123 bl33_image_ep_info.spsr = brcm_get_spsr_for_bl33_entry(); 124 SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); 125 126 # if ARM_LINUX_KERNEL_AS_BL33 127 /* 128 * According to the file ``Documentation/arm64/booting.txt`` of the 129 * Linux kernel tree, Linux expects the physical address of the device 130 * tree blob (DTB) in x0, while x1-x3 are reserved for future use and 131 * must be 0. 132 */ 133 bl33_image_ep_info.args.arg0 = (u_register_t)PRELOADED_DTB_BASE; 134 bl33_image_ep_info.args.arg1 = 0U; 135 bl33_image_ep_info.args.arg2 = 0U; 136 bl33_image_ep_info.args.arg3 = 0U; 137 # endif 138 139 #else /* RESET_TO_BL31 */ 140 141 /* 142 * In debug builds, we pass a special value in 'plat_params_from_bl2' 143 * to verify platform parameters from BL2 to BL31. 144 * In release builds, it's not used. 145 */ 146 assert(((unsigned long long)plat_params_from_bl2) == 147 BRCM_BL31_PLAT_PARAM_VAL); 148 149 /* 150 * Check params passed from BL2 should not be NULL 151 */ 152 bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2; 153 154 assert(params_from_bl2 != NULL); 155 assert(params_from_bl2->h.type == PARAM_BL_PARAMS); 156 assert(params_from_bl2->h.version >= VERSION_2); 157 158 bl_params_node_t *bl_params = params_from_bl2->head; 159 160 /* 161 * Copy BL33 and BL32 (if present), entry point information. 162 * They are stored in Secure RAM, in BL2's address space. 163 */ 164 while (bl_params != NULL) { 165 if (bl_params->image_id == BL32_IMAGE_ID && 166 bl_params->image_info->h.attr != IMAGE_ATTRIB_SKIP_LOADING) 167 bl32_image_ep_info = *bl_params->ep_info; 168 169 if (bl_params->image_id == BL33_IMAGE_ID) 170 bl33_image_ep_info = *bl_params->ep_info; 171 172 bl_params = bl_params->next_params_info; 173 } 174 175 if (bl33_image_ep_info.pc == 0U) 176 panic(); 177 #endif /* RESET_TO_BL31 */ 178 179 #ifdef BL33_SHARED_DDR_BASE 180 /* Pass information to BL33 thorugh x0 */ 181 bl33_image_ep_info.args.arg0 = (u_register_t)BL33_SHARED_DDR_BASE; 182 bl33_image_ep_info.args.arg1 = 0ULL; 183 bl33_image_ep_info.args.arg2 = 0ULL; 184 bl33_image_ep_info.args.arg3 = 0ULL; 185 #endif 186 } 187 188 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, 189 u_register_t arg2, u_register_t arg3) 190 { 191 #ifdef BL31_LOG_LEVEL 192 SET_LOG_LEVEL(BL31_LOG_LEVEL); 193 #endif 194 195 brcm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); 196 197 plat_bcm_bl31_early_platform_setup((void *)arg0, (void *)arg3); 198 199 #ifdef DRIVER_CC_ENABLE 200 /* 201 * Initialize Interconnect for this cluster during cold boot. 202 * No need for locks as no other CPU is active. 203 */ 204 plat_brcm_interconnect_init(); 205 206 /* 207 * Enable Interconnect coherency for the primary CPU's cluster. 208 * Earlier bootloader stages might already do this (e.g. Trusted 209 * Firmware's BL1 does it) but we can't assume so. There is no harm in 210 * executing this code twice anyway. 211 * Platform specific PSCI code will enable coherency for other 212 * clusters. 213 */ 214 plat_brcm_interconnect_enter_coherency(); 215 #endif 216 } 217 218 /******************************************************************************* 219 * Perform any BL31 platform setup common to ARM standard platforms 220 ******************************************************************************/ 221 void brcm_bl31_platform_setup(void) 222 { 223 /* Initialize the GIC driver, cpu and distributor interfaces */ 224 plat_brcm_gic_driver_init(); 225 plat_brcm_gic_init(); 226 227 /* Initialize power controller before setting up topology */ 228 plat_brcm_pwrc_setup(); 229 } 230 231 /******************************************************************************* 232 * Perform any BL31 platform runtime setup prior to BL31 exit common to ARM 233 * standard platforms 234 * Perform BL31 platform setup 235 ******************************************************************************/ 236 void brcm_bl31_plat_runtime_setup(void) 237 { 238 /* Initialize the runtime console */ 239 bcm_console_runtime_init(); 240 } 241 242 void bl31_platform_setup(void) 243 { 244 brcm_bl31_platform_setup(); 245 246 /* Initialize the secure environment */ 247 plat_brcm_security_setup(); 248 } 249 250 void bl31_plat_runtime_setup(void) 251 { 252 brcm_bl31_plat_runtime_setup(); 253 } 254 255 /******************************************************************************* 256 * Perform the very early platform specific architectural setup shared between 257 * ARM standard platforms. This only does basic initialization. Later 258 * architectural setup (bl31_arch_setup()) does not do anything platform 259 * specific. 260 ******************************************************************************/ 261 void __init brcm_bl31_plat_arch_setup(void) 262 { 263 #ifndef MMU_DISABLED 264 const mmap_region_t bl_regions[] = { 265 MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE, 266 MT_MEMORY | MT_RW | MT_SECURE), 267 MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, 268 MT_CODE | MT_SECURE), 269 MAP_REGION_FLAT(BL_RO_DATA_BASE, 270 BL_RO_DATA_END - BL_RO_DATA_BASE, 271 MT_RO_DATA | MT_SECURE), 272 #if USE_COHERENT_MEM 273 MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, 274 BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, 275 MT_DEVICE | MT_RW | MT_SECURE), 276 #endif 277 {0} 278 }; 279 280 setup_page_tables(bl_regions, plat_brcm_get_mmap()); 281 282 enable_mmu_el3(0); 283 #endif 284 } 285 286 void __init bl31_plat_arch_setup(void) 287 { 288 brcm_bl31_plat_arch_setup(); 289 } 290