1 /* 2 * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 9 #include <platform_def.h> 10 11 #include <arch.h> 12 #include <bl1/bl1.h> 13 #include <common/bl_common.h> 14 #include <lib/fconf/fconf.h> 15 #include <lib/fconf/fconf_dyn_cfg_getter.h> 16 #include <lib/utils.h> 17 #include <lib/xlat_tables/xlat_tables_compat.h> 18 #include <plat/arm/common/plat_arm.h> 19 #include <plat/common/platform.h> 20 21 /* Weak definitions may be overridden in specific ARM standard platform */ 22 #pragma weak bl1_early_platform_setup 23 #pragma weak bl1_plat_arch_setup 24 #pragma weak bl1_plat_sec_mem_layout 25 #pragma weak bl1_plat_prepare_exit 26 #pragma weak bl1_plat_get_next_image_id 27 #pragma weak plat_arm_bl1_fwu_needed 28 29 #define MAP_BL1_TOTAL MAP_REGION_FLAT( \ 30 bl1_tzram_layout.total_base, \ 31 bl1_tzram_layout.total_size, \ 32 MT_MEMORY | MT_RW | MT_SECURE) 33 /* 34 * If SEPARATE_CODE_AND_RODATA=1 we define a region for each section 35 * otherwise one region is defined containing both 36 */ 37 #if SEPARATE_CODE_AND_RODATA 38 #define MAP_BL1_RO MAP_REGION_FLAT( \ 39 BL_CODE_BASE, \ 40 BL1_CODE_END - BL_CODE_BASE, \ 41 MT_CODE | MT_SECURE), \ 42 MAP_REGION_FLAT( \ 43 BL1_RO_DATA_BASE, \ 44 BL1_RO_DATA_END \ 45 - BL_RO_DATA_BASE, \ 46 MT_RO_DATA | MT_SECURE) 47 #else 48 #define MAP_BL1_RO MAP_REGION_FLAT( \ 49 BL_CODE_BASE, \ 50 BL1_CODE_END - BL_CODE_BASE, \ 51 MT_CODE | MT_SECURE) 52 #endif 53 54 /* Data structure which holds the extents of the trusted SRAM for BL1*/ 55 static meminfo_t bl1_tzram_layout; 56 57 struct meminfo *bl1_plat_sec_mem_layout(void) 58 { 59 return &bl1_tzram_layout; 60 } 61 62 /******************************************************************************* 63 * BL1 specific platform actions shared between ARM standard platforms. 64 ******************************************************************************/ 65 void arm_bl1_early_platform_setup(void) 66 { 67 68 #if !ARM_DISABLE_TRUSTED_WDOG 69 /* Enable watchdog */ 70 plat_arm_secure_wdt_start(); 71 #endif 72 73 /* Initialize the console to provide early debug support */ 74 arm_console_boot_init(); 75 76 /* Allow BL1 to see the whole Trusted RAM */ 77 bl1_tzram_layout.total_base = ARM_BL_RAM_BASE; 78 bl1_tzram_layout.total_size = ARM_BL_RAM_SIZE; 79 } 80 81 void bl1_early_platform_setup(void) 82 { 83 arm_bl1_early_platform_setup(); 84 85 /* 86 * Initialize Interconnect for this cluster during cold boot. 87 * No need for locks as no other CPU is active. 88 */ 89 plat_arm_interconnect_init(); 90 /* 91 * Enable Interconnect coherency for the primary CPU's cluster. 92 */ 93 plat_arm_interconnect_enter_coherency(); 94 } 95 96 /****************************************************************************** 97 * Perform the very early platform specific architecture setup shared between 98 * ARM standard platforms. This only does basic initialization. Later 99 * architectural setup (bl1_arch_setup()) does not do anything platform 100 * specific. 101 *****************************************************************************/ 102 void arm_bl1_plat_arch_setup(void) 103 { 104 #if USE_COHERENT_MEM && !ARM_CRYPTOCELL_INTEG 105 /* 106 * Ensure ARM platforms don't use coherent memory in BL1 unless 107 * cryptocell integration is enabled. 108 */ 109 assert((BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE) == 0U); 110 #endif 111 112 const mmap_region_t bl_regions[] = { 113 MAP_BL1_TOTAL, 114 MAP_BL1_RO, 115 #if USE_ROMLIB 116 ARM_MAP_ROMLIB_CODE, 117 ARM_MAP_ROMLIB_DATA, 118 #endif 119 #if ARM_CRYPTOCELL_INTEG 120 ARM_MAP_BL_COHERENT_RAM, 121 #endif 122 {0} 123 }; 124 125 setup_page_tables(bl_regions, plat_arm_get_mmap()); 126 #ifdef __aarch64__ 127 enable_mmu_el3(0); 128 #else 129 enable_mmu_svc_mon(0); 130 #endif /* __aarch64__ */ 131 132 arm_setup_romlib(); 133 } 134 135 void bl1_plat_arch_setup(void) 136 { 137 arm_bl1_plat_arch_setup(); 138 } 139 140 /* 141 * Perform the platform specific architecture setup shared between 142 * ARM standard platforms. 143 */ 144 void arm_bl1_platform_setup(void) 145 { 146 const struct dyn_cfg_dtb_info_t *fw_config_info; 147 image_desc_t *desc; 148 uint32_t fw_config_max_size; 149 int err = -1; 150 151 /* Initialise the IO layer and register platform IO devices */ 152 plat_arm_io_setup(); 153 154 /* Check if we need FWU before further processing */ 155 err = plat_arm_bl1_fwu_needed(); 156 if (err) { 157 ERROR("Skip platform setup as FWU detected\n"); 158 return; 159 } 160 161 /* Set global DTB info for fixed fw_config information */ 162 fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE; 163 set_fw_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size); 164 165 /* Fill the device tree information struct with the info from the config dtb */ 166 err = fconf_load_config(FW_CONFIG_ID); 167 if (err < 0) { 168 ERROR("Loading of FW_CONFIG failed %d\n", err); 169 plat_error_handler(err); 170 } 171 172 /* 173 * FW_CONFIG loaded successfully. If FW_CONFIG device tree parsing 174 * is successful then load TB_FW_CONFIG device tree. 175 */ 176 fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID); 177 if (fw_config_info != NULL) { 178 err = fconf_populate_dtb_registry(fw_config_info->config_addr); 179 if (err < 0) { 180 ERROR("Parsing of FW_CONFIG failed %d\n", err); 181 plat_error_handler(err); 182 } 183 /* load TB_FW_CONFIG */ 184 err = fconf_load_config(TB_FW_CONFIG_ID); 185 if (err < 0) { 186 ERROR("Loading of TB_FW_CONFIG failed %d\n", err); 187 plat_error_handler(err); 188 } 189 } else { 190 ERROR("Invalid FW_CONFIG address\n"); 191 plat_error_handler(err); 192 } 193 194 /* The BL2 ep_info arg0 is modified to point to FW_CONFIG */ 195 desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); 196 assert(desc != NULL); 197 desc->ep_info.args.arg0 = fw_config_info->config_addr; 198 199 #if TRUSTED_BOARD_BOOT 200 /* Share the Mbed TLS heap info with other images */ 201 arm_bl1_set_mbedtls_heap(); 202 #endif /* TRUSTED_BOARD_BOOT */ 203 204 /* 205 * Allow access to the System counter timer module and program 206 * counter frequency for non secure images during FWU 207 */ 208 #ifdef ARM_SYS_TIMCTL_BASE 209 arm_configure_sys_timer(); 210 #endif 211 #if (ARM_ARCH_MAJOR > 7) || defined(ARMV7_SUPPORTS_GENERIC_TIMER) 212 write_cntfrq_el0(plat_get_syscnt_freq2()); 213 #endif 214 } 215 216 void bl1_plat_prepare_exit(entry_point_info_t *ep_info) 217 { 218 #if !ARM_DISABLE_TRUSTED_WDOG 219 /* Disable watchdog before leaving BL1 */ 220 plat_arm_secure_wdt_stop(); 221 #endif 222 223 #ifdef EL3_PAYLOAD_BASE 224 /* 225 * Program the EL3 payload's entry point address into the CPUs mailbox 226 * in order to release secondary CPUs from their holding pen and make 227 * them jump there. 228 */ 229 plat_arm_program_trusted_mailbox(ep_info->pc); 230 dsbsy(); 231 sev(); 232 #endif 233 } 234 235 /* 236 * On Arm platforms, the FWU process is triggered when the FIP image has 237 * been tampered with. 238 */ 239 bool plat_arm_bl1_fwu_needed(void) 240 { 241 return !arm_io_is_toc_valid(); 242 } 243 244 /******************************************************************************* 245 * The following function checks if Firmware update is needed, 246 * by checking if TOC in FIP image is valid or not. 247 ******************************************************************************/ 248 unsigned int bl1_plat_get_next_image_id(void) 249 { 250 return plat_arm_bl1_fwu_needed() ? NS_BL1U_IMAGE_ID : BL2_IMAGE_ID; 251 } 252