1 /* 2 * Copyright (C) 2018-2024 Marvell International Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * https://spdx.org/licenses 6 */ 7 8 #include <assert.h> 9 10 #include <arch.h> 11 #include <common/bl_common.h> 12 #include <common/debug.h> 13 #ifdef USE_CCI 14 #include <drivers/arm/cci.h> 15 #endif 16 #include <drivers/console.h> 17 #include <plat/common/platform.h> 18 19 #include <marvell_def.h> 20 #include <marvell_plat_priv.h> 21 #include <plat_marvell.h> 22 23 /* 24 * Placeholder variables for copying the arguments that have been passed to 25 * BL31 from BL2. 26 */ 27 static entry_point_info_t bl32_image_ep_info; 28 static entry_point_info_t bl33_image_ep_info; 29 30 /* Weak definitions may be overridden in specific ARM standard platform */ 31 #pragma weak bl31_early_platform_setup2 32 #pragma weak bl31_platform_setup 33 #pragma weak bl31_plat_arch_setup 34 #pragma weak bl31_plat_get_next_image_ep_info 35 #pragma weak plat_get_syscnt_freq2 36 37 /***************************************************************************** 38 * Return a pointer to the 'entry_point_info' structure of the next image for 39 * the security state specified. BL33 corresponds to the non-secure image type 40 * while BL32 corresponds to the secure image type. A NULL pointer is returned 41 * if the image does not exist. 42 ***************************************************************************** 43 */ 44 entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) 45 { 46 entry_point_info_t *next_image_info; 47 48 assert(sec_state_is_valid(type)); 49 next_image_info = (type == NON_SECURE) 50 ? &bl33_image_ep_info : &bl32_image_ep_info; 51 52 return next_image_info; 53 } 54 55 /***************************************************************************** 56 * Perform any BL31 early platform setup common to ARM standard platforms. 57 * Here is an opportunity to copy parameters passed by the calling EL (S-EL1 58 * in BL2 & EL3 in BL1) before they are lost (potentially). This needs to be 59 * done before the MMU is initialized so that the memory layout can be used 60 * while creating page tables. BL2 has flushed this information to memory, so 61 * we are guaranteed to pick up good data. 62 ***************************************************************************** 63 */ 64 void marvell_bl31_early_platform_setup(void *from_bl2, 65 uintptr_t soc_fw_config, 66 uintptr_t hw_config, 67 void *plat_params_from_bl2) 68 { 69 /* Initialize the console to provide early debug support */ 70 marvell_console_boot_init(); 71 72 #if RESET_TO_BL31 73 /* There are no parameters from BL2 if BL31 is a reset vector */ 74 assert(from_bl2 == NULL); 75 assert(plat_params_from_bl2 == NULL); 76 77 #ifdef BL32_BASE 78 /* Populate entry point information for BL32 */ 79 SET_PARAM_HEAD(&bl32_image_ep_info, 80 PARAM_EP, 81 VERSION_1, 82 0); 83 SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); 84 bl32_image_ep_info.pc = BL32_BASE; 85 bl32_image_ep_info.spsr = marvell_get_spsr_for_bl32_entry(); 86 #endif /* BL32_BASE */ 87 88 /* Populate entry point information for BL33 */ 89 SET_PARAM_HEAD(&bl33_image_ep_info, 90 PARAM_EP, 91 VERSION_1, 92 0); 93 /* 94 * Tell BL31 where the non-trusted software image 95 * is located and the entry state information 96 */ 97 bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); 98 bl33_image_ep_info.spsr = marvell_get_spsr_for_bl33_entry(); 99 SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); 100 101 #else 102 /* 103 * In debug builds, we pass a special value in 'plat_params_from_bl2' 104 * to verify platform parameters from BL2 to BL31. 105 * In release builds, it's not used. 106 */ 107 assert(((unsigned long long)plat_params_from_bl2) == 108 MARVELL_BL31_PLAT_PARAM_VAL); 109 110 /* 111 * Check params passed from BL2 should not be NULL, 112 */ 113 bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2; 114 assert(params_from_bl2 != NULL); 115 assert(params_from_bl2->h.type == PARAM_BL_PARAMS); 116 assert(params_from_bl2->h.version >= VERSION_2); 117 118 bl_params_node_t *bl_params = params_from_bl2->head; 119 120 /* 121 * Copy BL33 and BL32 (if present), entry point information. 122 * They are stored in Secure RAM, in BL2's address space. 123 */ 124 while (bl_params != NULL) { 125 if (bl_params->image_id == BL32_IMAGE_ID) 126 bl32_image_ep_info = *bl_params->ep_info; 127 128 if (bl_params->image_id == BL33_IMAGE_ID) 129 bl33_image_ep_info = *bl_params->ep_info; 130 131 bl_params = bl_params->next_params_info; 132 } 133 #endif 134 } 135 136 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, 137 u_register_t arg2, u_register_t arg3) 138 139 { 140 marvell_bl31_early_platform_setup((void *)arg0, arg1, arg2, 141 (void *)arg3); 142 143 #ifdef USE_CCI 144 /* 145 * Initialize CCI for this cluster during cold boot. 146 * No need for locks as no other CPU is active. 147 */ 148 plat_marvell_interconnect_init(); 149 150 /* 151 * Enable CCI coherency for the primary CPU's cluster. 152 * Platform specific PSCI code will enable coherency for other 153 * clusters. 154 */ 155 plat_marvell_interconnect_enter_coherency(); 156 #endif 157 } 158 159 /***************************************************************************** 160 * Perform any BL31 platform setup common to ARM standard platforms 161 ***************************************************************************** 162 */ 163 void marvell_bl31_platform_setup(void) 164 { 165 /* Initialize the GIC driver, cpu and distributor interfaces */ 166 plat_marvell_gic_driver_init(); 167 plat_marvell_gic_init(); 168 169 /* For Armada-8k-plus family, the SoC includes more than 170 * a single AP die, but the default die that boots is AP #0. 171 * For other families there is only one die (#0). 172 * Initialize psci arch from die 0 173 */ 174 marvell_psci_arch_init(0); 175 } 176 177 /***************************************************************************** 178 * Perform any BL31 platform runtime setup prior to BL31 exit common to ARM 179 * standard platforms 180 ***************************************************************************** 181 */ 182 void marvell_bl31_plat_runtime_setup(void) 183 { 184 /* Initialize the runtime console */ 185 marvell_console_runtime_init(); 186 } 187 188 void bl31_platform_setup(void) 189 { 190 marvell_bl31_platform_setup(); 191 } 192 193 void bl31_plat_runtime_setup(void) 194 { 195 marvell_bl31_plat_runtime_setup(); 196 } 197 198 /***************************************************************************** 199 * Perform the very early platform specific architectural setup shared between 200 * ARM standard platforms. This only does basic initialization. Later 201 * architectural setup (bl31_arch_setup()) does not do anything platform 202 * specific. 203 ***************************************************************************** 204 */ 205 void marvell_bl31_plat_arch_setup(void) 206 { 207 marvell_setup_page_tables(BL31_BASE, 208 BL31_END - BL31_BASE, 209 BL_CODE_BASE, 210 BL_CODE_END, 211 BL_RO_DATA_BASE, 212 BL_RO_DATA_END 213 #if USE_COHERENT_MEM 214 , BL_COHERENT_RAM_BASE, 215 BL_COHERENT_RAM_END 216 #endif 217 ); 218 219 #if BL31_CACHE_DISABLE 220 enable_mmu_el3(DISABLE_DCACHE); 221 INFO("Cache is disabled in BL3\n"); 222 #else 223 enable_mmu_el3(0); 224 #endif 225 } 226 227 void bl31_plat_arch_setup(void) 228 { 229 marvell_bl31_plat_arch_setup(); 230 } 231 232 unsigned int plat_get_syscnt_freq2(void) 233 { 234 return PLAT_REF_CLK_IN_HZ; 235 } 236