14f6ad66aSAchin Gupta /* 2e83b0cadSDan Handley * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. 34f6ad66aSAchin Gupta * 44f6ad66aSAchin Gupta * Redistribution and use in source and binary forms, with or without 54f6ad66aSAchin Gupta * modification, are permitted provided that the following conditions are met: 64f6ad66aSAchin Gupta * 74f6ad66aSAchin Gupta * Redistributions of source code must retain the above copyright notice, this 84f6ad66aSAchin Gupta * list of conditions and the following disclaimer. 94f6ad66aSAchin Gupta * 104f6ad66aSAchin Gupta * Redistributions in binary form must reproduce the above copyright notice, 114f6ad66aSAchin Gupta * this list of conditions and the following disclaimer in the documentation 124f6ad66aSAchin Gupta * and/or other materials provided with the distribution. 134f6ad66aSAchin Gupta * 144f6ad66aSAchin Gupta * Neither the name of ARM nor the names of its contributors may be used 154f6ad66aSAchin Gupta * to endorse or promote products derived from this software without specific 164f6ad66aSAchin Gupta * prior written permission. 174f6ad66aSAchin Gupta * 184f6ad66aSAchin Gupta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 194f6ad66aSAchin Gupta * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 204f6ad66aSAchin Gupta * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 214f6ad66aSAchin Gupta * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 224f6ad66aSAchin Gupta * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 234f6ad66aSAchin Gupta * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 244f6ad66aSAchin Gupta * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 254f6ad66aSAchin Gupta * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 264f6ad66aSAchin Gupta * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 274f6ad66aSAchin Gupta * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 284f6ad66aSAchin Gupta * POSSIBILITY OF SUCH DAMAGE. 294f6ad66aSAchin Gupta */ 304f6ad66aSAchin Gupta 3197043ac9SDan Handley #include <arch.h> 324f6ad66aSAchin Gupta #include <arch_helpers.h> 3397043ac9SDan Handley #include <assert.h> 344f6ad66aSAchin Gupta #include <bl_common.h> 3535e98e55SDan Handley #include <debug.h> 3697043ac9SDan Handley #include <platform.h> 375f0cdb05SDan Handley #include <platform_def.h> 3897043ac9SDan Handley #include <stdio.h> 395b827a8fSDan Handley #include "bl2_private.h" 404f6ad66aSAchin Gupta 41*93d81d64SSandrine Bailleux /******************************************************************************* 42*93d81d64SSandrine Bailleux * Load the BL3-0 image if there's one. 43*93d81d64SSandrine Bailleux * If a platform does not want to attempt to load BL3-0 image it must leave 44*93d81d64SSandrine Bailleux * BL30_BASE undefined. 45*93d81d64SSandrine Bailleux * Return 0 on success or if there's no BL3-0 image to load, a negative error 46*93d81d64SSandrine Bailleux * code otherwise. 47*93d81d64SSandrine Bailleux ******************************************************************************/ 48*93d81d64SSandrine Bailleux static int load_bl30(void) 49*93d81d64SSandrine Bailleux { 50*93d81d64SSandrine Bailleux int e = 0; 51*93d81d64SSandrine Bailleux #ifdef BL30_BASE 52*93d81d64SSandrine Bailleux meminfo_t bl30_mem_info; 53*93d81d64SSandrine Bailleux image_info_t bl30_image_info; 54*93d81d64SSandrine Bailleux 55*93d81d64SSandrine Bailleux /* 56*93d81d64SSandrine Bailleux * It is up to the platform to specify where BL3-0 should be loaded if 57*93d81d64SSandrine Bailleux * it exists. It could create space in the secure sram or point to a 58*93d81d64SSandrine Bailleux * completely different memory. 59*93d81d64SSandrine Bailleux * 60*93d81d64SSandrine Bailleux * The entry point information is not relevant in this case as the AP 61*93d81d64SSandrine Bailleux * won't execute the BL3-0 image. 62*93d81d64SSandrine Bailleux */ 63*93d81d64SSandrine Bailleux bl2_plat_get_bl30_meminfo(&bl30_mem_info); 64*93d81d64SSandrine Bailleux e = load_image(&bl30_mem_info, 65*93d81d64SSandrine Bailleux BL30_IMAGE_NAME, 66*93d81d64SSandrine Bailleux BL30_BASE, 67*93d81d64SSandrine Bailleux &bl30_image_info, 68*93d81d64SSandrine Bailleux NULL); 69*93d81d64SSandrine Bailleux 70*93d81d64SSandrine Bailleux if (e == 0) { 71*93d81d64SSandrine Bailleux /* The subsequent handling of BL3-0 is platform specific */ 72*93d81d64SSandrine Bailleux bl2_plat_handle_bl30(&bl30_image_info); 73*93d81d64SSandrine Bailleux } 74*93d81d64SSandrine Bailleux #endif /* BL30_BASE */ 75*93d81d64SSandrine Bailleux 76*93d81d64SSandrine Bailleux return e; 77*93d81d64SSandrine Bailleux } 7829fb905dSVikram Kanigiri 7929fb905dSVikram Kanigiri /******************************************************************************* 80*93d81d64SSandrine Bailleux * Load the BL3-1 image. 81*93d81d64SSandrine Bailleux * The bl2_to_bl31_params and bl31_ep_info params will be updated with the 82*93d81d64SSandrine Bailleux * relevant BL3-1 information. 83*93d81d64SSandrine Bailleux * Return 0 on success, a negative error code otherwise. 844f6ad66aSAchin Gupta ******************************************************************************/ 85*93d81d64SSandrine Bailleux static int load_bl31(bl31_params_t *bl2_to_bl31_params, 86*93d81d64SSandrine Bailleux entry_point_info_t *bl31_ep_info) 874f6ad66aSAchin Gupta { 88fb037bfbSDan Handley meminfo_t *bl2_tzram_layout; 894112bfa0SVikram Kanigiri int e; 904f6ad66aSAchin Gupta 91*93d81d64SSandrine Bailleux assert(bl2_to_bl31_params != NULL); 92*93d81d64SSandrine Bailleux assert(bl31_ep_info != NULL); 934f6ad66aSAchin Gupta 944f6ad66aSAchin Gupta /* Find out how much free trusted ram remains after BL2 load */ 95ee12f6f7SSandrine Bailleux bl2_tzram_layout = bl2_plat_sec_mem_layout(); 964f6ad66aSAchin Gupta 97*93d81d64SSandrine Bailleux /* Set the X0 parameter to BL3-1 */ 9803462671SAndrew Thoelke bl31_ep_info->args.arg0 = (unsigned long)bl2_to_bl31_params; 9903462671SAndrew Thoelke 1008f55dfb4SSandrine Bailleux /* Load the BL3-1 image */ 1014112bfa0SVikram Kanigiri e = load_image(bl2_tzram_layout, 1024112bfa0SVikram Kanigiri BL31_IMAGE_NAME, 1034112bfa0SVikram Kanigiri BL31_BASE, 1044112bfa0SVikram Kanigiri bl2_to_bl31_params->bl31_image_info, 1054112bfa0SVikram Kanigiri bl31_ep_info); 1064f6ad66aSAchin Gupta 107*93d81d64SSandrine Bailleux if (e == 0) 1084112bfa0SVikram Kanigiri bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info, 1094112bfa0SVikram Kanigiri bl31_ep_info); 110a3050ed5SAchin Gupta 111*93d81d64SSandrine Bailleux return e; 112561cd33eSHarry Liebel } 113e4d084eaSAchin Gupta 114*93d81d64SSandrine Bailleux /******************************************************************************* 115*93d81d64SSandrine Bailleux * Load the BL3-2 image if there's one. 116*93d81d64SSandrine Bailleux * The bl2_to_bl31_params param will be updated with the relevant BL3-2 117*93d81d64SSandrine Bailleux * information. 118*93d81d64SSandrine Bailleux * If a platform does not want to attempt to load BL3-2 image it must leave 119*93d81d64SSandrine Bailleux * BL32_BASE undefined. 120*93d81d64SSandrine Bailleux * Return 0 on success or if there's no BL3-2 image to load, a negative error 121*93d81d64SSandrine Bailleux * code otherwise. 122*93d81d64SSandrine Bailleux ******************************************************************************/ 123*93d81d64SSandrine Bailleux static int load_bl32(bl31_params_t *bl2_to_bl31_params) 124*93d81d64SSandrine Bailleux { 125*93d81d64SSandrine Bailleux int e = 0; 1261151c821SDan Handley #ifdef BL32_BASE 127*93d81d64SSandrine Bailleux meminfo_t bl32_mem_info; 128*93d81d64SSandrine Bailleux 129*93d81d64SSandrine Bailleux assert(bl2_to_bl31_params != NULL); 130*93d81d64SSandrine Bailleux 13129fb905dSVikram Kanigiri /* 132*93d81d64SSandrine Bailleux * It is up to the platform to specify where BL3-2 should be loaded if 133*93d81d64SSandrine Bailleux * it exists. It could create space in the secure sram or point to a 1341151c821SDan Handley * completely different memory. 13529fb905dSVikram Kanigiri */ 1366871c5d3SVikram Kanigiri bl2_plat_get_bl32_meminfo(&bl32_mem_info); 1376871c5d3SVikram Kanigiri e = load_image(&bl32_mem_info, 13829fb905dSVikram Kanigiri BL32_IMAGE_NAME, 1394112bfa0SVikram Kanigiri BL32_BASE, 1404112bfa0SVikram Kanigiri bl2_to_bl31_params->bl32_image_info, 1414112bfa0SVikram Kanigiri bl2_to_bl31_params->bl32_ep_info); 14229fb905dSVikram Kanigiri 143*93d81d64SSandrine Bailleux if (e == 0) { 1444112bfa0SVikram Kanigiri bl2_plat_set_bl32_ep_info( 1454112bfa0SVikram Kanigiri bl2_to_bl31_params->bl32_image_info, 1464112bfa0SVikram Kanigiri bl2_to_bl31_params->bl32_ep_info); 147a3050ed5SAchin Gupta } 1481151c821SDan Handley #endif /* BL32_BASE */ 1494112bfa0SVikram Kanigiri 150*93d81d64SSandrine Bailleux return e; 151*93d81d64SSandrine Bailleux } 152*93d81d64SSandrine Bailleux 153*93d81d64SSandrine Bailleux /******************************************************************************* 154*93d81d64SSandrine Bailleux * Load the BL3-3 image. 155*93d81d64SSandrine Bailleux * The bl2_to_bl31_params param will be updated with the relevant BL3-3 156*93d81d64SSandrine Bailleux * information. 157*93d81d64SSandrine Bailleux * Return 0 on success, a negative error code otherwise. 158*93d81d64SSandrine Bailleux ******************************************************************************/ 159*93d81d64SSandrine Bailleux static int load_bl33(bl31_params_t *bl2_to_bl31_params) 160*93d81d64SSandrine Bailleux { 161*93d81d64SSandrine Bailleux meminfo_t bl33_mem_info; 162*93d81d64SSandrine Bailleux int e; 163*93d81d64SSandrine Bailleux 164*93d81d64SSandrine Bailleux assert(bl2_to_bl31_params != NULL); 165*93d81d64SSandrine Bailleux 166*93d81d64SSandrine Bailleux bl2_plat_get_bl33_meminfo(&bl33_mem_info); 167*93d81d64SSandrine Bailleux 168*93d81d64SSandrine Bailleux /* Load the BL3-3 image in non-secure memory provided by the platform */ 169*93d81d64SSandrine Bailleux e = load_image(&bl33_mem_info, 170*93d81d64SSandrine Bailleux BL33_IMAGE_NAME, 171*93d81d64SSandrine Bailleux plat_get_ns_image_entrypoint(), 172*93d81d64SSandrine Bailleux bl2_to_bl31_params->bl33_image_info, 173*93d81d64SSandrine Bailleux bl2_to_bl31_params->bl33_ep_info); 174*93d81d64SSandrine Bailleux 175*93d81d64SSandrine Bailleux if (e == 0) 176*93d81d64SSandrine Bailleux bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info, 177*93d81d64SSandrine Bailleux bl2_to_bl31_params->bl33_ep_info); 178*93d81d64SSandrine Bailleux 179*93d81d64SSandrine Bailleux return e; 180*93d81d64SSandrine Bailleux } 181*93d81d64SSandrine Bailleux 182*93d81d64SSandrine Bailleux /******************************************************************************* 183*93d81d64SSandrine Bailleux * The only thing to do in BL2 is to load further images and pass control to 184*93d81d64SSandrine Bailleux * BL3-1. The memory occupied by BL2 will be reclaimed by BL3-x stages. BL2 runs 185*93d81d64SSandrine Bailleux * entirely in S-EL1. 186*93d81d64SSandrine Bailleux ******************************************************************************/ 187*93d81d64SSandrine Bailleux void bl2_main(void) 188*93d81d64SSandrine Bailleux { 189*93d81d64SSandrine Bailleux bl31_params_t *bl2_to_bl31_params; 190*93d81d64SSandrine Bailleux entry_point_info_t *bl31_ep_info; 191*93d81d64SSandrine Bailleux int e; 192*93d81d64SSandrine Bailleux 193*93d81d64SSandrine Bailleux /* Perform remaining generic architectural setup in S-EL1 */ 194*93d81d64SSandrine Bailleux bl2_arch_setup(); 195*93d81d64SSandrine Bailleux 196*93d81d64SSandrine Bailleux /* Perform platform setup in BL2 */ 197*93d81d64SSandrine Bailleux bl2_platform_setup(); 198*93d81d64SSandrine Bailleux 199*93d81d64SSandrine Bailleux printf("BL2 %s\n\r", build_message); 200*93d81d64SSandrine Bailleux 201*93d81d64SSandrine Bailleux /* 202*93d81d64SSandrine Bailleux * Load the subsequent bootloader images 203*93d81d64SSandrine Bailleux */ 204*93d81d64SSandrine Bailleux e = load_bl30(); 205*93d81d64SSandrine Bailleux if (e) { 206*93d81d64SSandrine Bailleux ERROR("Failed to load BL3-0 (%i)\n", e); 207*93d81d64SSandrine Bailleux panic(); 208*93d81d64SSandrine Bailleux } 209*93d81d64SSandrine Bailleux 210*93d81d64SSandrine Bailleux /* 211*93d81d64SSandrine Bailleux * Get a pointer to the memory the platform has set aside to pass 212*93d81d64SSandrine Bailleux * information to BL3-1. 213*93d81d64SSandrine Bailleux */ 214*93d81d64SSandrine Bailleux bl2_to_bl31_params = bl2_plat_get_bl31_params(); 215*93d81d64SSandrine Bailleux bl31_ep_info = bl2_plat_get_bl31_ep_info(); 216*93d81d64SSandrine Bailleux 217*93d81d64SSandrine Bailleux e = load_bl31(bl2_to_bl31_params, bl31_ep_info); 218*93d81d64SSandrine Bailleux if (e) { 219*93d81d64SSandrine Bailleux ERROR("Failed to load BL3-1 (%i)\n", e); 220*93d81d64SSandrine Bailleux panic(); 221*93d81d64SSandrine Bailleux } 222*93d81d64SSandrine Bailleux 223*93d81d64SSandrine Bailleux e = load_bl32(bl2_to_bl31_params); 224*93d81d64SSandrine Bailleux if (e) 225*93d81d64SSandrine Bailleux WARN("Failed to load BL3-2 (%i)\n", e); 226*93d81d64SSandrine Bailleux 227*93d81d64SSandrine Bailleux e = load_bl33(bl2_to_bl31_params); 228*93d81d64SSandrine Bailleux if (e) { 229*93d81d64SSandrine Bailleux ERROR("Failed to load BL3-3 (%i)\n", e); 230*93d81d64SSandrine Bailleux panic(); 231*93d81d64SSandrine Bailleux } 232*93d81d64SSandrine Bailleux 23303462671SAndrew Thoelke /* Flush the params to be passed to memory */ 23403462671SAndrew Thoelke bl2_plat_flush_bl31_params(); 23503462671SAndrew Thoelke 2364f6ad66aSAchin Gupta /* 237*93d81d64SSandrine Bailleux * Run BL3-1 via an SMC to BL1. Information on how to pass control to 238*93d81d64SSandrine Bailleux * the BL3-2 (if present) and BL3-3 software images will be passed to 239*93d81d64SSandrine Bailleux * BL3-1 as an argument. 2404f6ad66aSAchin Gupta */ 24103462671SAndrew Thoelke smc(RUN_IMAGE, (unsigned long)bl31_ep_info, 0, 0, 0, 0, 0, 0); 2424f6ad66aSAchin Gupta } 243