1 /* 2 * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <arch.h> 32 #include <arch_helpers.h> 33 #include <assert.h> 34 #include <auth_mod.h> 35 #include <bl_common.h> 36 #include <debug.h> 37 #include <platform.h> 38 #include <platform_def.h> 39 #include <stdint.h> 40 #include "bl2_private.h" 41 42 /******************************************************************************* 43 * Load the BL3-0 image if there's one. 44 * If a platform does not want to attempt to load BL3-0 image it must leave 45 * BL30_BASE undefined. 46 * Return 0 on success or if there's no BL3-0 image to load, a negative error 47 * code otherwise. 48 ******************************************************************************/ 49 static int load_bl30(void) 50 { 51 int e = 0; 52 #ifdef BL30_BASE 53 meminfo_t bl30_mem_info; 54 image_info_t bl30_image_info; 55 56 /* 57 * It is up to the platform to specify where BL3-0 should be loaded if 58 * it exists. It could create space in the secure sram or point to a 59 * completely different memory. 60 * 61 * The entry point information is not relevant in this case as the AP 62 * won't execute the BL3-0 image. 63 */ 64 INFO("BL2: Loading BL3-0\n"); 65 bl2_plat_get_bl30_meminfo(&bl30_mem_info); 66 bl30_image_info.h.version = VERSION_1; 67 e = load_auth_image(&bl30_mem_info, 68 BL30_IMAGE_ID, 69 BL30_BASE, 70 &bl30_image_info, 71 NULL); 72 73 if (e == 0) { 74 /* The subsequent handling of BL3-0 is platform specific */ 75 e = bl2_plat_handle_bl30(&bl30_image_info); 76 if (e) { 77 ERROR("Failure in platform-specific handling of BL3-0 image.\n"); 78 } 79 } 80 #endif /* BL30_BASE */ 81 82 return e; 83 } 84 85 /******************************************************************************* 86 * Load the BL3-1 image. 87 * The bl2_to_bl31_params and bl31_ep_info params will be updated with the 88 * relevant BL3-1 information. 89 * Return 0 on success, a negative error code otherwise. 90 ******************************************************************************/ 91 static int load_bl31(bl31_params_t *bl2_to_bl31_params, 92 entry_point_info_t *bl31_ep_info) 93 { 94 meminfo_t *bl2_tzram_layout; 95 int e; 96 97 INFO("BL2: Loading BL3-1\n"); 98 assert(bl2_to_bl31_params != NULL); 99 assert(bl31_ep_info != NULL); 100 101 /* Find out how much free trusted ram remains after BL2 load */ 102 bl2_tzram_layout = bl2_plat_sec_mem_layout(); 103 104 /* Set the X0 parameter to BL3-1 */ 105 bl31_ep_info->args.arg0 = (unsigned long)bl2_to_bl31_params; 106 107 /* Load the BL3-1 image */ 108 e = load_auth_image(bl2_tzram_layout, 109 BL31_IMAGE_ID, 110 BL31_BASE, 111 bl2_to_bl31_params->bl31_image_info, 112 bl31_ep_info); 113 114 if (e == 0) { 115 bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info, 116 bl31_ep_info); 117 } 118 119 return e; 120 } 121 122 /******************************************************************************* 123 * Load the BL3-2 image if there's one. 124 * The bl2_to_bl31_params param will be updated with the relevant BL3-2 125 * information. 126 * If a platform does not want to attempt to load BL3-2 image it must leave 127 * BL32_BASE undefined. 128 * Return 0 on success or if there's no BL3-2 image to load, a negative error 129 * code otherwise. 130 ******************************************************************************/ 131 static int load_bl32(bl31_params_t *bl2_to_bl31_params) 132 { 133 int e = 0; 134 #ifdef BL32_BASE 135 meminfo_t bl32_mem_info; 136 137 INFO("BL2: Loading BL3-2\n"); 138 assert(bl2_to_bl31_params != NULL); 139 140 /* 141 * It is up to the platform to specify where BL3-2 should be loaded if 142 * it exists. It could create space in the secure sram or point to a 143 * completely different memory. 144 */ 145 bl2_plat_get_bl32_meminfo(&bl32_mem_info); 146 e = load_auth_image(&bl32_mem_info, 147 BL32_IMAGE_ID, 148 BL32_BASE, 149 bl2_to_bl31_params->bl32_image_info, 150 bl2_to_bl31_params->bl32_ep_info); 151 152 if (e == 0) { 153 bl2_plat_set_bl32_ep_info( 154 bl2_to_bl31_params->bl32_image_info, 155 bl2_to_bl31_params->bl32_ep_info); 156 } 157 #endif /* BL32_BASE */ 158 159 return e; 160 } 161 162 /******************************************************************************* 163 * Load the BL3-3 image. 164 * The bl2_to_bl31_params param will be updated with the relevant BL3-3 165 * information. 166 * Return 0 on success, a negative error code otherwise. 167 ******************************************************************************/ 168 static int load_bl33(bl31_params_t *bl2_to_bl31_params) 169 { 170 meminfo_t bl33_mem_info; 171 int e; 172 173 INFO("BL2: Loading BL3-3\n"); 174 assert(bl2_to_bl31_params != NULL); 175 176 bl2_plat_get_bl33_meminfo(&bl33_mem_info); 177 178 /* Load the BL3-3 image in non-secure memory provided by the platform */ 179 e = load_auth_image(&bl33_mem_info, 180 BL33_IMAGE_ID, 181 plat_get_ns_image_entrypoint(), 182 bl2_to_bl31_params->bl33_image_info, 183 bl2_to_bl31_params->bl33_ep_info); 184 185 if (e == 0) { 186 bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info, 187 bl2_to_bl31_params->bl33_ep_info); 188 } 189 190 return e; 191 } 192 193 /******************************************************************************* 194 * The only thing to do in BL2 is to load further images and pass control to 195 * BL3-1. The memory occupied by BL2 will be reclaimed by BL3-x stages. BL2 runs 196 * entirely in S-EL1. 197 ******************************************************************************/ 198 void bl2_main(void) 199 { 200 bl31_params_t *bl2_to_bl31_params; 201 entry_point_info_t *bl31_ep_info; 202 int e; 203 204 NOTICE("BL2: %s\n", version_string); 205 NOTICE("BL2: %s\n", build_message); 206 207 /* Perform remaining generic architectural setup in S-EL1 */ 208 bl2_arch_setup(); 209 210 #if TRUSTED_BOARD_BOOT 211 /* Initialize authentication module */ 212 auth_mod_init(); 213 #endif /* TRUSTED_BOARD_BOOT */ 214 215 /* 216 * Load the subsequent bootloader images 217 */ 218 e = load_bl30(); 219 if (e) { 220 ERROR("Failed to load BL3-0 (%i)\n", e); 221 panic(); 222 } 223 224 /* Perform platform setup in BL2 after loading BL3-0 */ 225 bl2_platform_setup(); 226 227 /* 228 * Get a pointer to the memory the platform has set aside to pass 229 * information to BL3-1. 230 */ 231 bl2_to_bl31_params = bl2_plat_get_bl31_params(); 232 bl31_ep_info = bl2_plat_get_bl31_ep_info(); 233 234 e = load_bl31(bl2_to_bl31_params, bl31_ep_info); 235 if (e) { 236 ERROR("Failed to load BL3-1 (%i)\n", e); 237 panic(); 238 } 239 240 e = load_bl32(bl2_to_bl31_params); 241 if (e) { 242 if (e == LOAD_AUTH_ERR) { 243 ERROR("Failed to authenticate BL3-2\n"); 244 panic(); 245 } else { 246 WARN("Failed to load BL3-2 (%i)\n", e); 247 } 248 } 249 250 e = load_bl33(bl2_to_bl31_params); 251 if (e) { 252 ERROR("Failed to load BL3-3 (%i)\n", e); 253 panic(); 254 } 255 256 /* Flush the params to be passed to memory */ 257 bl2_plat_flush_bl31_params(); 258 259 /* 260 * Run BL3-1 via an SMC to BL1. Information on how to pass control to 261 * the BL3-2 (if present) and BL3-3 software images will be passed to 262 * BL3-1 as an argument. 263 */ 264 smc(RUN_IMAGE, (unsigned long)bl31_ep_info, 0, 0, 0, 0, 0, 0); 265 } 266