1 /* 2 * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <errno.h> 9 10 #include <bl1/bl1.h> 11 #include <common/tbbr/tbbr_img_def.h> 12 #include <drivers/arm/smmu_v3.h> 13 #include <drivers/arm/sp805.h> 14 #include <lib/mmio.h> 15 #include <plat/arm/common/arm_config.h> 16 #include <plat/arm/common/plat_arm.h> 17 #include <plat/arm/common/arm_def.h> 18 #include <plat/common/platform.h> 19 #include "fvp_private.h" 20 21 /******************************************************************************* 22 * Perform any BL1 specific platform actions. 23 ******************************************************************************/ 24 void bl1_early_platform_setup(void) 25 { 26 arm_bl1_early_platform_setup(); 27 28 /* Initialize the platform config for future decision making */ 29 fvp_config_setup(); 30 31 /* 32 * Initialize Interconnect for this cluster during cold boot. 33 * No need for locks as no other CPU is active. 34 */ 35 fvp_interconnect_init(); 36 /* 37 * Enable coherency in Interconnect for the primary CPU's cluster. 38 */ 39 fvp_interconnect_enable(); 40 } 41 42 void plat_arm_secure_wdt_start(void) 43 { 44 sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL); 45 } 46 47 void plat_arm_secure_wdt_stop(void) 48 { 49 sp805_stop(ARM_SP805_TWDG_BASE); 50 } 51 52 void bl1_platform_setup(void) 53 { 54 arm_bl1_platform_setup(); 55 56 /* Initialize System level generic or SP804 timer */ 57 fvp_timer_init(); 58 59 /* On FVP RevC, initialize SMMUv3 */ 60 if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) 61 smmuv3_security_init(PLAT_FVP_SMMUV3_BASE); 62 } 63 64 __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) 65 { 66 uint32_t nv_flags = mmio_read_32(V2M_SYS_NVFLAGS_ADDR); 67 68 /* Clear the NV flags register. */ 69 mmio_write_32((V2M_SYSREGS_BASE + V2M_SYS_NVFLAGSCLR), 70 nv_flags); 71 72 /* Setup the watchdog to reset the system as soon as possible */ 73 sp805_refresh(ARM_SP805_TWDG_BASE, 1U); 74 75 while (true) 76 wfi(); 77 } 78 79 #if MEASURED_BOOT 80 /* 81 * Calculates and writes BL2 hash data to TB_FW_CONFIG DTB. 82 */ 83 void bl1_plat_set_bl2_hash(const image_desc_t *image_desc) 84 { 85 arm_bl1_set_bl2_hash(image_desc); 86 } 87 88 /* 89 * Implementation for bl1_plat_handle_post_image_load(). This function 90 * populates the default arguments to BL2. The BL2 memory layout structure 91 * is allocated and the calculated layout is populated in arg1 to BL2. 92 */ 93 int bl1_plat_handle_post_image_load(unsigned int image_id) 94 { 95 meminfo_t *bl2_tzram_layout; 96 meminfo_t *bl1_tzram_layout; 97 image_desc_t *image_desc; 98 entry_point_info_t *ep_info; 99 100 if (image_id != BL2_IMAGE_ID) { 101 return 0; 102 } 103 104 /* Get the image descriptor */ 105 image_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); 106 assert(image_desc != NULL); 107 108 /* Calculate BL2 hash and set it in TB_FW_CONFIG */ 109 bl1_plat_set_bl2_hash(image_desc); 110 111 /* Get the entry point info */ 112 ep_info = &image_desc->ep_info; 113 114 /* Find out how much free trusted ram remains after BL1 load */ 115 bl1_tzram_layout = bl1_plat_sec_mem_layout(); 116 117 /* 118 * Create a new layout of memory for BL2 as seen by BL1 i.e. 119 * tell it the amount of total and free memory available. 120 * This layout is created at the first free address visible 121 * to BL2. BL2 will read the memory layout before using its 122 * memory for other purposes. 123 */ 124 bl2_tzram_layout = (meminfo_t *)bl1_tzram_layout->total_base; 125 126 bl1_calc_bl2_mem_layout(bl1_tzram_layout, bl2_tzram_layout); 127 128 ep_info->args.arg1 = (uintptr_t)bl2_tzram_layout; 129 130 VERBOSE("BL1: BL2 memory layout address = %p\n", 131 (void *)bl2_tzram_layout); 132 return 0; 133 } 134 #endif /* MEASURED_BOOT */ 135 136 /******************************************************************************* 137 * The following function checks if Firmware update is needed by checking error 138 * reported in NV flag. 139 ******************************************************************************/ 140 bool plat_arm_bl1_fwu_needed(void) 141 { 142 int32_t nv_flags = (int32_t)mmio_read_32(V2M_SYS_NVFLAGS_ADDR); 143 144 /* if image load/authentication failed */ 145 return ((nv_flags == -EAUTH) || (nv_flags == -ENOENT)); 146 } 147