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 <bl_common.h> 35 #include <debug.h> 36 #include <platform.h> 37 #include <platform_def.h> 38 #include "bl2_private.h" 39 40 /******************************************************************************* 41 * Load the BL3-0 image if there's one. 42 * If a platform does not want to attempt to load BL3-0 image it must leave 43 * BL30_BASE undefined. 44 * Return 0 on success or if there's no BL3-0 image to load, a negative error 45 * code otherwise. 46 ******************************************************************************/ 47 static int load_bl30(void) 48 { 49 int e = 0; 50 #ifdef BL30_BASE 51 meminfo_t bl30_mem_info; 52 image_info_t bl30_image_info; 53 54 /* 55 * It is up to the platform to specify where BL3-0 should be loaded if 56 * it exists. It could create space in the secure sram or point to a 57 * completely different memory. 58 * 59 * The entry point information is not relevant in this case as the AP 60 * won't execute the BL3-0 image. 61 */ 62 INFO("BL2: Loading BL3-0\n"); 63 bl2_plat_get_bl30_meminfo(&bl30_mem_info); 64 e = load_image(&bl30_mem_info, 65 BL30_IMAGE_NAME, 66 BL30_BASE, 67 &bl30_image_info, 68 NULL); 69 70 if (e == 0) { 71 /* The subsequent handling of BL3-0 is platform specific */ 72 bl2_plat_handle_bl30(&bl30_image_info); 73 } 74 #endif /* BL30_BASE */ 75 76 return e; 77 } 78 79 /******************************************************************************* 80 * Load the BL3-1 image. 81 * The bl2_to_bl31_params and bl31_ep_info params will be updated with the 82 * relevant BL3-1 information. 83 * Return 0 on success, a negative error code otherwise. 84 ******************************************************************************/ 85 static int load_bl31(bl31_params_t *bl2_to_bl31_params, 86 entry_point_info_t *bl31_ep_info) 87 { 88 meminfo_t *bl2_tzram_layout; 89 int e; 90 91 INFO("BL2: Loading BL3-1\n"); 92 assert(bl2_to_bl31_params != NULL); 93 assert(bl31_ep_info != NULL); 94 95 /* Find out how much free trusted ram remains after BL2 load */ 96 bl2_tzram_layout = bl2_plat_sec_mem_layout(); 97 98 /* Set the X0 parameter to BL3-1 */ 99 bl31_ep_info->args.arg0 = (unsigned long)bl2_to_bl31_params; 100 101 /* Load the BL3-1 image */ 102 e = load_image(bl2_tzram_layout, 103 BL31_IMAGE_NAME, 104 BL31_BASE, 105 bl2_to_bl31_params->bl31_image_info, 106 bl31_ep_info); 107 108 if (e == 0) 109 bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info, 110 bl31_ep_info); 111 112 return e; 113 } 114 115 /******************************************************************************* 116 * Load the BL3-2 image if there's one. 117 * The bl2_to_bl31_params param will be updated with the relevant BL3-2 118 * information. 119 * If a platform does not want to attempt to load BL3-2 image it must leave 120 * BL32_BASE undefined. 121 * Return 0 on success or if there's no BL3-2 image to load, a negative error 122 * code otherwise. 123 ******************************************************************************/ 124 static int load_bl32(bl31_params_t *bl2_to_bl31_params) 125 { 126 int e = 0; 127 #ifdef BL32_BASE 128 meminfo_t bl32_mem_info; 129 130 INFO("BL2: Loading BL3-2\n"); 131 assert(bl2_to_bl31_params != NULL); 132 133 /* 134 * It is up to the platform to specify where BL3-2 should be loaded if 135 * it exists. It could create space in the secure sram or point to a 136 * completely different memory. 137 */ 138 bl2_plat_get_bl32_meminfo(&bl32_mem_info); 139 e = load_image(&bl32_mem_info, 140 BL32_IMAGE_NAME, 141 BL32_BASE, 142 bl2_to_bl31_params->bl32_image_info, 143 bl2_to_bl31_params->bl32_ep_info); 144 145 if (e == 0) { 146 bl2_plat_set_bl32_ep_info( 147 bl2_to_bl31_params->bl32_image_info, 148 bl2_to_bl31_params->bl32_ep_info); 149 } 150 #endif /* BL32_BASE */ 151 152 return e; 153 } 154 155 /******************************************************************************* 156 * Load the BL3-3 image. 157 * The bl2_to_bl31_params param will be updated with the relevant BL3-3 158 * information. 159 * Return 0 on success, a negative error code otherwise. 160 ******************************************************************************/ 161 static int load_bl33(bl31_params_t *bl2_to_bl31_params) 162 { 163 meminfo_t bl33_mem_info; 164 int e; 165 166 INFO("BL2: Loading BL3-3\n"); 167 assert(bl2_to_bl31_params != NULL); 168 169 bl2_plat_get_bl33_meminfo(&bl33_mem_info); 170 171 /* Load the BL3-3 image in non-secure memory provided by the platform */ 172 e = load_image(&bl33_mem_info, 173 BL33_IMAGE_NAME, 174 plat_get_ns_image_entrypoint(), 175 bl2_to_bl31_params->bl33_image_info, 176 bl2_to_bl31_params->bl33_ep_info); 177 178 if (e == 0) 179 bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info, 180 bl2_to_bl31_params->bl33_ep_info); 181 182 return e; 183 } 184 185 /******************************************************************************* 186 * The only thing to do in BL2 is to load further images and pass control to 187 * BL3-1. The memory occupied by BL2 will be reclaimed by BL3-x stages. BL2 runs 188 * entirely in S-EL1. 189 ******************************************************************************/ 190 void bl2_main(void) 191 { 192 bl31_params_t *bl2_to_bl31_params; 193 entry_point_info_t *bl31_ep_info; 194 int e; 195 196 NOTICE("BL2: %s\n", version_string); 197 NOTICE("BL2: %s\n", build_message); 198 199 /* Perform remaining generic architectural setup in S-EL1 */ 200 bl2_arch_setup(); 201 202 /* 203 * Load the subsequent bootloader images 204 */ 205 e = load_bl30(); 206 if (e) { 207 ERROR("Failed to load BL3-0 (%i)\n", e); 208 panic(); 209 } 210 211 /* Perform platform setup in BL2 after loading BL3-0 */ 212 bl2_platform_setup(); 213 214 /* 215 * Get a pointer to the memory the platform has set aside to pass 216 * information to BL3-1. 217 */ 218 bl2_to_bl31_params = bl2_plat_get_bl31_params(); 219 bl31_ep_info = bl2_plat_get_bl31_ep_info(); 220 221 e = load_bl31(bl2_to_bl31_params, bl31_ep_info); 222 if (e) { 223 ERROR("Failed to load BL3-1 (%i)\n", e); 224 panic(); 225 } 226 227 e = load_bl32(bl2_to_bl31_params); 228 if (e) 229 WARN("Failed to load BL3-2 (%i)\n", e); 230 231 e = load_bl33(bl2_to_bl31_params); 232 if (e) { 233 ERROR("Failed to load BL3-3 (%i)\n", e); 234 panic(); 235 } 236 237 /* Flush the params to be passed to memory */ 238 bl2_plat_flush_bl31_params(); 239 240 /* 241 * Run BL3-1 via an SMC to BL1. Information on how to pass control to 242 * the BL3-2 (if present) and BL3-3 software images will be passed to 243 * BL3-1 as an argument. 244 */ 245 smc(RUN_IMAGE, (unsigned long)bl31_ep_info, 0, 0, 0, 0, 0, 0); 246 } 247