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