1 /* 2 * Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 9 #include <platform_def.h> 10 11 #include <bl32/sp_min/platform_sp_min.h> 12 #include <common/bl_common.h> 13 #include <common/debug.h> 14 #include <drivers/console.h> 15 #include <lib/mmio.h> 16 #include <plat/arm/common/plat_arm.h> 17 #include <plat/common/platform.h> 18 19 struct transfer_list_header *secure_tl; 20 struct transfer_list_header *ns_tl __unused; 21 22 static entry_point_info_t bl33_image_ep_info; 23 24 #if USE_GIC_DRIVER == 3 25 static const uintptr_t gicr_base_addrs[2] = { 26 PLAT_ARM_GICR_BASE, /* GICR Base address of the primary CPU */ 27 0U /* Zero Termination */ 28 }; 29 #endif 30 31 /* Weak definitions may be overridden in specific ARM standard platform */ 32 #pragma weak sp_min_platform_setup 33 #pragma weak sp_min_plat_arch_setup 34 #pragma weak plat_arm_sp_min_early_platform_setup 35 36 #define MAP_BL_SP_MIN_TOTAL MAP_REGION_FLAT( \ 37 BL32_BASE, \ 38 BL32_END - BL32_BASE, \ 39 MT_MEMORY | MT_RW | MT_SECURE) 40 41 #define MAP_EL3_FW_HANDOFF \ 42 MAP_REGION_FLAT(PLAT_ARM_EL3_FW_HANDOFF_BASE, \ 43 PLAT_ARM_FW_HANDOFF_SIZE, MT_MEMORY | MT_RW | EL3_PAS) 44 45 #define MAP_FW_NS_HANDOFF \ 46 MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, PLAT_ARM_FW_HANDOFF_SIZE, \ 47 MT_MEMORY | MT_RW | MT_NS) 48 49 /* 50 * Check that BL32_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page 51 * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2. 52 */ 53 #if !RESET_TO_SP_MIN 54 #if TRANSFER_LIST 55 CASSERT(BL32_BASE >= PLAT_ARM_EL3_FW_HANDOFF_LIMIT, assert_bl32_base_overflows); 56 #else 57 CASSERT(BL32_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl32_base_overflows); 58 #endif 59 #endif 60 61 /******************************************************************************* 62 * Return a pointer to the 'entry_point_info' structure of the next image for the 63 * security state specified. BL33 corresponds to the non-secure image type 64 * while BL32 corresponds to the secure image type. A NULL pointer is returned 65 * if the image does not exist. 66 ******************************************************************************/ 67 entry_point_info_t *sp_min_plat_get_bl33_ep_info(void) 68 { 69 entry_point_info_t *next_image_info; 70 71 next_image_info = &bl33_image_ep_info; 72 73 /* 74 * None of the images on the ARM development platforms can have 0x0 75 * as the entrypoint 76 */ 77 if (next_image_info->pc) 78 return next_image_info; 79 else 80 return NULL; 81 } 82 83 /******************************************************************************* 84 * Utility function to perform early platform setup. 85 ******************************************************************************/ 86 void arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1, 87 u_register_t arg2, u_register_t arg3) 88 { 89 struct transfer_list_entry *te __unused; 90 91 /* Initialize the console to provide early debug support */ 92 arm_console_boot_init(); 93 94 #if TRANSFER_LIST 95 secure_tl = (struct transfer_list_header *)arg3; 96 97 te = transfer_list_find(secure_tl, TL_TAG_EXEC_EP_INFO32); 98 assert(te != NULL); 99 100 bl33_image_ep_info = 101 *(struct entry_point_info *)transfer_list_entry_data(te); 102 return; 103 #endif /* TRANSFER_LIST */ 104 105 #if RESET_TO_SP_MIN 106 /* Populate entry point information for BL33 */ 107 SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0); 108 /* 109 * Tell SP_MIN where the non-trusted software image 110 * is located and the entry state information 111 */ 112 bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); 113 bl33_image_ep_info.spsr = arm_get_spsr(BL33_IMAGE_ID); 114 SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); 115 116 #if ARM_LINUX_KERNEL_AS_BL33 117 /* 118 * According to the file ``Documentation/arm/Booting`` of the Linux 119 * kernel tree, Linux expects: 120 * r0 = 0 121 * r1 = machine type number, optional in DT-only platforms (~0 if so) 122 * r2 = Physical address of the device tree blob 123 */ 124 bl33_image_ep_info.args.arg0 = 0U; 125 bl33_image_ep_info.args.arg1 = ~0U; 126 bl33_image_ep_info.args.arg2 = (u_register_t)ARM_PRELOADED_DTB_BASE; 127 # endif 128 129 #else /* RESET_TO_SP_MIN */ 130 131 /* 132 * Check params passed from BL2 should not be NULL, 133 */ 134 bl_params_t *params_from_bl2 = (bl_params_t *)arg0; 135 assert(params_from_bl2 != NULL); 136 assert(params_from_bl2->h.type == PARAM_BL_PARAMS); 137 assert(params_from_bl2->h.version >= VERSION_2); 138 139 bl_params_node_t *bl_params = params_from_bl2->head; 140 141 /* 142 * Copy BL33 entry point information. 143 * They are stored in Secure RAM, in BL2's address space. 144 */ 145 while (bl_params) { 146 if (bl_params->image_id == BL33_IMAGE_ID) { 147 bl33_image_ep_info = *bl_params->ep_info; 148 break; 149 } 150 151 bl_params = bl_params->next_params_info; 152 } 153 154 if (bl33_image_ep_info.pc == 0) 155 panic(); 156 157 #endif /* RESET_TO_SP_MIN */ 158 159 } 160 161 /******************************************************************************* 162 * Default implementation for sp_min_platform_setup2() for ARM platforms 163 ******************************************************************************/ 164 void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1, 165 u_register_t arg2, u_register_t arg3) 166 { 167 arm_sp_min_early_platform_setup(arg0, arg1, arg2, arg3); 168 169 #if !HW_ASSISTED_COHERENCY 170 /* 171 * Initialize Interconnect for this cluster during cold boot. 172 * No need for locks as no other CPU is active. 173 */ 174 plat_arm_interconnect_init(); 175 176 /* 177 * Enable Interconnect coherency for the primary CPU's cluster. 178 * Earlier bootloader stages might already do this (e.g. Trusted 179 * Firmware's BL1 does it) but we can't assume so. There is no harm in 180 * executing this code twice anyway. 181 * Platform specific PSCI code will enable coherency for other 182 * clusters. 183 */ 184 plat_arm_interconnect_enter_coherency(); 185 #endif 186 } 187 188 void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, 189 u_register_t arg2, u_register_t arg3) 190 { 191 plat_arm_sp_min_early_platform_setup(arg0, arg1, arg2, arg3); 192 } 193 194 /******************************************************************************* 195 * Perform any SP_MIN platform runtime setup prior to SP_MIN exit. 196 * Common to ARM standard platforms. 197 ******************************************************************************/ 198 void arm_sp_min_plat_runtime_setup(void) 199 { 200 /* Initialize the runtime console */ 201 arm_console_runtime_init(); 202 203 #if PLAT_RO_XLAT_TABLES 204 arm_xlat_make_tables_readonly(); 205 #endif 206 } 207 208 /******************************************************************************* 209 * Perform platform specific setup for SP_MIN 210 ******************************************************************************/ 211 void sp_min_platform_setup(void) 212 { 213 struct transfer_list_entry *te __unused; 214 215 /* Initialize the GIC driver, cpu and distributor interfaces */ 216 unsigned int core_pos = plat_my_core_pos(); 217 218 #if USE_GIC_DRIVER == 3 219 gic_set_gicr_frames(gicr_base_addrs); 220 #endif 221 gic_init(core_pos); 222 gic_pcpu_init(core_pos); 223 gic_cpuif_enable(core_pos); 224 225 #if TRANSFER_LIST 226 ns_tl = transfer_list_ensure((void *)FW_NS_HANDOFF_BASE, 227 PLAT_ARM_FW_HANDOFF_SIZE); 228 if (ns_tl == NULL) { 229 ERROR("Non-secure transfer list initialisation failed!\n"); 230 panic(); 231 } 232 233 te = transfer_list_find(secure_tl, TL_TAG_FDT); 234 if (te != NULL) { 235 te = transfer_list_add(ns_tl, TL_TAG_FDT, te->data_size, 236 (void *)transfer_list_entry_data(te)); 237 if (te == NULL) { 238 ERROR("Failed to relocate device tree into non-secure memory.\n"); 239 panic(); 240 } 241 } 242 243 transfer_list_set_handoff_args(ns_tl, &bl33_image_ep_info); 244 #endif 245 246 /* 247 * Do initial security configuration to allow DRAM/device access 248 * (if earlier BL has not already done so). 249 */ 250 #if RESET_TO_SP_MIN && !JUNO_AARCH32_EL3_RUNTIME 251 plat_arm_security_setup(); 252 253 #if defined(PLAT_ARM_MEM_PROT_ADDR) 254 arm_nor_psci_do_dyn_mem_protect(); 255 #endif /* PLAT_ARM_MEM_PROT_ADDR */ 256 257 #endif 258 259 /* Enable and initialize the System level generic timer */ 260 #ifdef ARM_SYS_CNTCTL_BASE 261 mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF, 262 CNTCR_FCREQ(0U) | CNTCR_EN); 263 #endif 264 #ifdef ARM_SYS_TIMCTL_BASE 265 /* Allow access to the System counter timer module */ 266 arm_configure_sys_timer(); 267 #endif 268 /* Initialize power controller before setting up topology */ 269 plat_arm_pwrc_setup(); 270 } 271 272 void sp_min_plat_runtime_setup(void) 273 { 274 arm_sp_min_plat_runtime_setup(); 275 } 276 277 /******************************************************************************* 278 * Perform the very early platform specific architectural setup here. At the 279 * moment this only initializes the MMU 280 ******************************************************************************/ 281 void arm_sp_min_plat_arch_setup(void) 282 { 283 const mmap_region_t bl_regions[] = { 284 MAP_BL_SP_MIN_TOTAL, 285 ARM_MAP_BL_RO, 286 #if USE_COHERENT_MEM 287 ARM_MAP_BL_COHERENT_RAM, 288 #endif 289 #if TRANSFER_LIST 290 MAP_EL3_FW_HANDOFF, 291 MAP_FW_NS_HANDOFF, 292 #endif 293 {0} 294 }; 295 296 setup_page_tables(bl_regions, plat_arm_get_mmap()); 297 298 enable_mmu_svc_mon(0); 299 } 300 301 void sp_min_plat_arch_setup(void) 302 { 303 arm_sp_min_plat_arch_setup(); 304 } 305