1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu 9*91f16700Schasinglulu #include "../../../../bl1/bl1_private.h" 10*91f16700Schasinglulu #include <arch.h> 11*91f16700Schasinglulu #include <arch_features.h> 12*91f16700Schasinglulu #include <arch_helpers.h> 13*91f16700Schasinglulu #include <bl1/bl1.h> 14*91f16700Schasinglulu #include <common/bl_common.h> 15*91f16700Schasinglulu #include <common/debug.h> 16*91f16700Schasinglulu #include <drivers/auth/auth_mod.h> 17*91f16700Schasinglulu #include <drivers/console.h> 18*91f16700Schasinglulu #include <lib/cpus/errata.h> 19*91f16700Schasinglulu #include <lib/utils.h> 20*91f16700Schasinglulu #include <smccc_helpers.h> 21*91f16700Schasinglulu #include <tools_share/uuid.h> 22*91f16700Schasinglulu #include <plat/arm/common/plat_arm.h> 23*91f16700Schasinglulu #include <plat/common/platform.h> 24*91f16700Schasinglulu 25*91f16700Schasinglulu #include <platform_def.h> 26*91f16700Schasinglulu 27*91f16700Schasinglulu 28*91f16700Schasinglulu void cm_prepare_el2_exit(void); 29*91f16700Schasinglulu 30*91f16700Schasinglulu void bl1_run_next_image(const struct entry_point_info *bl_ep_info); 31*91f16700Schasinglulu 32*91f16700Schasinglulu /******************************************************************************* 33*91f16700Schasinglulu * Function to perform late architectural and platform specific initialization. 34*91f16700Schasinglulu * It also queries the platform to load and run next BL image. Only called 35*91f16700Schasinglulu * by the primary cpu after a cold boot. 36*91f16700Schasinglulu ******************************************************************************/ 37*91f16700Schasinglulu void bl1_transfer_bl33(void) 38*91f16700Schasinglulu { 39*91f16700Schasinglulu unsigned int image_id; 40*91f16700Schasinglulu 41*91f16700Schasinglulu /* Get the image id of next image to load and run. */ 42*91f16700Schasinglulu image_id = bl1_plat_get_next_image_id(); 43*91f16700Schasinglulu 44*91f16700Schasinglulu #if !ARM_DISABLE_TRUSTED_WDOG 45*91f16700Schasinglulu /* Disable watchdog before leaving BL1 */ 46*91f16700Schasinglulu plat_arm_secure_wdt_stop(); 47*91f16700Schasinglulu #endif 48*91f16700Schasinglulu 49*91f16700Schasinglulu bl1_run_next_image(&bl1_plat_get_image_desc(image_id)->ep_info); 50*91f16700Schasinglulu } 51*91f16700Schasinglulu 52*91f16700Schasinglulu /******************************************************************************* 53*91f16700Schasinglulu * This function locates and loads the BL33 raw binary image in the trusted SRAM. 54*91f16700Schasinglulu * Called by the primary cpu after a cold boot. 55*91f16700Schasinglulu * TODO: Add support for alternative image load mechanism e.g using virtio/elf 56*91f16700Schasinglulu * loader etc. 57*91f16700Schasinglulu ******************************************************************************/ 58*91f16700Schasinglulu void bl1_load_bl33(void) 59*91f16700Schasinglulu { 60*91f16700Schasinglulu image_desc_t *desc; 61*91f16700Schasinglulu image_info_t *info; 62*91f16700Schasinglulu int err; 63*91f16700Schasinglulu 64*91f16700Schasinglulu /* Get the image descriptor */ 65*91f16700Schasinglulu desc = bl1_plat_get_image_desc(BL33_IMAGE_ID); 66*91f16700Schasinglulu assert(desc != NULL); 67*91f16700Schasinglulu 68*91f16700Schasinglulu /* Get the image info */ 69*91f16700Schasinglulu info = &desc->image_info; 70*91f16700Schasinglulu INFO("BL1: Loading BL33\n"); 71*91f16700Schasinglulu 72*91f16700Schasinglulu err = bl1_plat_handle_pre_image_load(BL33_IMAGE_ID); 73*91f16700Schasinglulu if (err != 0) { 74*91f16700Schasinglulu ERROR("Failure in pre image load handling of BL33 (%d)\n", err); 75*91f16700Schasinglulu plat_error_handler(err); 76*91f16700Schasinglulu } 77*91f16700Schasinglulu 78*91f16700Schasinglulu err = load_auth_image(BL33_IMAGE_ID, info); 79*91f16700Schasinglulu if (err != 0) { 80*91f16700Schasinglulu ERROR("Failed to load BL33 firmware.\n"); 81*91f16700Schasinglulu plat_error_handler(err); 82*91f16700Schasinglulu } 83*91f16700Schasinglulu 84*91f16700Schasinglulu /* Allow platform to handle image information. */ 85*91f16700Schasinglulu err = bl1_plat_handle_post_image_load(BL33_IMAGE_ID); 86*91f16700Schasinglulu if (err != 0) { 87*91f16700Schasinglulu ERROR("Failure in post image load handling of BL33 (%d)\n", err); 88*91f16700Schasinglulu plat_error_handler(err); 89*91f16700Schasinglulu } 90*91f16700Schasinglulu 91*91f16700Schasinglulu NOTICE("BL1: Booting BL33\n"); 92*91f16700Schasinglulu } 93*91f16700Schasinglulu 94*91f16700Schasinglulu /******************************************************************************* 95*91f16700Schasinglulu * Helper utility to calculate the BL2 memory layout taking into consideration 96*91f16700Schasinglulu * the BL1 RW data assuming that it is at the top of the memory layout. 97*91f16700Schasinglulu ******************************************************************************/ 98*91f16700Schasinglulu void bl1_calc_bl2_mem_layout(const meminfo_t *bl1_mem_layout, 99*91f16700Schasinglulu meminfo_t *bl2_mem_layout) 100*91f16700Schasinglulu { 101*91f16700Schasinglulu assert(bl1_mem_layout != NULL); 102*91f16700Schasinglulu assert(bl2_mem_layout != NULL); 103*91f16700Schasinglulu 104*91f16700Schasinglulu /* 105*91f16700Schasinglulu * Remove BL1 RW data from the scope of memory visible to BL2. 106*91f16700Schasinglulu * This is assuming BL1 RW data is at the top of bl1_mem_layout. 107*91f16700Schasinglulu */ 108*91f16700Schasinglulu assert(bl1_mem_layout->total_base < BL1_RW_BASE); 109*91f16700Schasinglulu bl2_mem_layout->total_base = bl1_mem_layout->total_base; 110*91f16700Schasinglulu bl2_mem_layout->total_size = BL1_RW_BASE - bl1_mem_layout->total_base; 111*91f16700Schasinglulu 112*91f16700Schasinglulu flush_dcache_range((uintptr_t)bl2_mem_layout, sizeof(meminfo_t)); 113*91f16700Schasinglulu } 114*91f16700Schasinglulu 115*91f16700Schasinglulu /******************************************************************************* 116*91f16700Schasinglulu * This function prepares for entry to BL33 117*91f16700Schasinglulu ******************************************************************************/ 118*91f16700Schasinglulu void bl1_prepare_next_image(unsigned int image_id) 119*91f16700Schasinglulu { 120*91f16700Schasinglulu unsigned int mode = MODE_EL1; 121*91f16700Schasinglulu image_desc_t *desc; 122*91f16700Schasinglulu entry_point_info_t *next_bl_ep; 123*91f16700Schasinglulu 124*91f16700Schasinglulu #if CTX_INCLUDE_AARCH32_REGS 125*91f16700Schasinglulu /* 126*91f16700Schasinglulu * Ensure that the build flag to save AArch32 system registers in CPU 127*91f16700Schasinglulu * context is not set for AArch64-only platforms. 128*91f16700Schasinglulu */ 129*91f16700Schasinglulu if (el_implemented(1) == EL_IMPL_A64ONLY) { 130*91f16700Schasinglulu ERROR("EL1 supports AArch64-only. Please set build flag %s", 131*91f16700Schasinglulu "CTX_INCLUDE_AARCH32_REGS = 0\n"); 132*91f16700Schasinglulu panic(); 133*91f16700Schasinglulu } 134*91f16700Schasinglulu #endif 135*91f16700Schasinglulu 136*91f16700Schasinglulu /* Get the image descriptor. */ 137*91f16700Schasinglulu desc = bl1_plat_get_image_desc(image_id); 138*91f16700Schasinglulu assert(desc != NULL); 139*91f16700Schasinglulu 140*91f16700Schasinglulu /* Get the entry point info. */ 141*91f16700Schasinglulu next_bl_ep = &desc->ep_info; 142*91f16700Schasinglulu 143*91f16700Schasinglulu /* FVP-R is only secure */ 144*91f16700Schasinglulu assert(GET_SECURITY_STATE(next_bl_ep->h.attr) == SECURE); 145*91f16700Schasinglulu 146*91f16700Schasinglulu /* Prepare the SPSR for the next BL image. */ 147*91f16700Schasinglulu next_bl_ep->spsr = (uint32_t)SPSR_64((uint64_t) mode, 148*91f16700Schasinglulu (uint64_t)MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); 149*91f16700Schasinglulu 150*91f16700Schasinglulu /* Allow platform to make change */ 151*91f16700Schasinglulu bl1_plat_set_ep_info(image_id, next_bl_ep); 152*91f16700Schasinglulu 153*91f16700Schasinglulu /* Prepare context for the next EL */ 154*91f16700Schasinglulu cm_prepare_el2_exit(); 155*91f16700Schasinglulu 156*91f16700Schasinglulu /* Indicate that image is in execution state. */ 157*91f16700Schasinglulu desc->state = IMAGE_STATE_EXECUTED; 158*91f16700Schasinglulu 159*91f16700Schasinglulu print_entry_point_info(next_bl_ep); 160*91f16700Schasinglulu } 161*91f16700Schasinglulu 162*91f16700Schasinglulu /******************************************************************************* 163*91f16700Schasinglulu * Setup function for BL1. 164*91f16700Schasinglulu ******************************************************************************/ 165*91f16700Schasinglulu void bl1_setup(void) 166*91f16700Schasinglulu { 167*91f16700Schasinglulu /* Perform early platform-specific setup */ 168*91f16700Schasinglulu bl1_early_platform_setup(); 169*91f16700Schasinglulu 170*91f16700Schasinglulu /* Perform late platform-specific setup */ 171*91f16700Schasinglulu bl1_plat_arch_setup(); 172*91f16700Schasinglulu } 173*91f16700Schasinglulu 174*91f16700Schasinglulu /******************************************************************************* 175*91f16700Schasinglulu * Function to perform late architectural and platform specific initialization. 176*91f16700Schasinglulu * It also queries the platform to load and run next BL image. Only called 177*91f16700Schasinglulu * by the primary cpu after a cold boot. 178*91f16700Schasinglulu ******************************************************************************/ 179*91f16700Schasinglulu void bl1_main(void) 180*91f16700Schasinglulu { 181*91f16700Schasinglulu unsigned int image_id; 182*91f16700Schasinglulu 183*91f16700Schasinglulu /* Announce our arrival */ 184*91f16700Schasinglulu NOTICE(FIRMWARE_WELCOME_STR); 185*91f16700Schasinglulu NOTICE("BL1: %s\n", version_string); 186*91f16700Schasinglulu NOTICE("BL1: %s\n", build_message); 187*91f16700Schasinglulu 188*91f16700Schasinglulu INFO("BL1: RAM %p - %p\n", (void *)BL1_RAM_BASE, (void *)BL1_RAM_LIMIT); 189*91f16700Schasinglulu 190*91f16700Schasinglulu print_errata_status(); 191*91f16700Schasinglulu 192*91f16700Schasinglulu #if ENABLE_ASSERTIONS 193*91f16700Schasinglulu u_register_t val; 194*91f16700Schasinglulu /* 195*91f16700Schasinglulu * Ensure that MMU/Caches and coherency are turned on 196*91f16700Schasinglulu */ 197*91f16700Schasinglulu val = read_sctlr_el2(); 198*91f16700Schasinglulu 199*91f16700Schasinglulu assert((val & SCTLR_M_BIT) != 0U); 200*91f16700Schasinglulu assert((val & SCTLR_C_BIT) != 0U); 201*91f16700Schasinglulu assert((val & SCTLR_I_BIT) != 0U); 202*91f16700Schasinglulu /* 203*91f16700Schasinglulu * Check that Cache Writeback Granule (CWG) in CTR_EL0 matches the 204*91f16700Schasinglulu * provided platform value 205*91f16700Schasinglulu */ 206*91f16700Schasinglulu val = (read_ctr_el0() >> CTR_CWG_SHIFT) & CTR_CWG_MASK; 207*91f16700Schasinglulu /* 208*91f16700Schasinglulu * If CWG is zero, then no CWG information is available but we can 209*91f16700Schasinglulu * at least check the platform value is less than the architectural 210*91f16700Schasinglulu * maximum. 211*91f16700Schasinglulu */ 212*91f16700Schasinglulu if (val != 0) { 213*91f16700Schasinglulu assert(SIZE_FROM_LOG2_WORDS(val) == CACHE_WRITEBACK_GRANULE); 214*91f16700Schasinglulu } else { 215*91f16700Schasinglulu assert(MAX_CACHE_LINE_SIZE >= CACHE_WRITEBACK_GRANULE); 216*91f16700Schasinglulu } 217*91f16700Schasinglulu #endif /* ENABLE_ASSERTIONS */ 218*91f16700Schasinglulu 219*91f16700Schasinglulu /* Perform remaining generic architectural setup from ELmax */ 220*91f16700Schasinglulu bl1_arch_setup(); 221*91f16700Schasinglulu 222*91f16700Schasinglulu #if TRUSTED_BOARD_BOOT 223*91f16700Schasinglulu /* Initialize authentication module */ 224*91f16700Schasinglulu auth_mod_init(); 225*91f16700Schasinglulu #endif /* TRUSTED_BOARD_BOOT */ 226*91f16700Schasinglulu 227*91f16700Schasinglulu /* Perform platform setup in BL1. */ 228*91f16700Schasinglulu bl1_platform_setup(); 229*91f16700Schasinglulu 230*91f16700Schasinglulu /* Get the image id of next image to load and run. */ 231*91f16700Schasinglulu image_id = bl1_plat_get_next_image_id(); 232*91f16700Schasinglulu 233*91f16700Schasinglulu /* 234*91f16700Schasinglulu * We currently interpret any image id other than 235*91f16700Schasinglulu * BL2_IMAGE_ID as the start of firmware update. 236*91f16700Schasinglulu */ 237*91f16700Schasinglulu if (image_id == BL33_IMAGE_ID) { 238*91f16700Schasinglulu bl1_load_bl33(); 239*91f16700Schasinglulu } else { 240*91f16700Schasinglulu NOTICE("BL1-FWU: *******FWU Process Started*******\n"); 241*91f16700Schasinglulu } 242*91f16700Schasinglulu 243*91f16700Schasinglulu bl1_prepare_next_image(image_id); 244*91f16700Schasinglulu 245*91f16700Schasinglulu console_flush(); 246*91f16700Schasinglulu 247*91f16700Schasinglulu bl1_transfer_bl33(); 248*91f16700Schasinglulu } 249*91f16700Schasinglulu 250*91f16700Schasinglulu /******************************************************************************* 251*91f16700Schasinglulu * Function called just before handing over to the next BL to inform the user 252*91f16700Schasinglulu * about the boot progress. In debug mode, also print details about the BL 253*91f16700Schasinglulu * image's execution context. 254*91f16700Schasinglulu ******************************************************************************/ 255*91f16700Schasinglulu void bl1_print_next_bl_ep_info(const entry_point_info_t *bl_ep_info) 256*91f16700Schasinglulu { 257*91f16700Schasinglulu NOTICE("BL1: Booting BL31\n"); 258*91f16700Schasinglulu print_entry_point_info(bl_ep_info); 259*91f16700Schasinglulu } 260*91f16700Schasinglulu 261*91f16700Schasinglulu #if SPIN_ON_BL1_EXIT 262*91f16700Schasinglulu void print_debug_loop_message(void) 263*91f16700Schasinglulu { 264*91f16700Schasinglulu NOTICE("BL1: Debug loop, spinning forever\n"); 265*91f16700Schasinglulu NOTICE("BL1: Please connect the debugger to continue\n"); 266*91f16700Schasinglulu } 267*91f16700Schasinglulu #endif 268*91f16700Schasinglulu 269