13fc4124cSDan Handley /* 2*59ea3648SManish V Badarkhe * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. 33fc4124cSDan Handley * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 53fc4124cSDan Handley */ 63fc4124cSDan Handley 70ab49645SAlexei Fedorov #include <assert.h> 8*59ea3648SManish V Badarkhe #include <errno.h> 90ab49645SAlexei Fedorov 100ab49645SAlexei Fedorov #include <bl1/bl1.h> 1109d40e0eSAntonio Nino Diaz #include <common/tbbr/tbbr_img_def.h> 121461ad9fSAlexei Fedorov #include <drivers/arm/smmu_v3.h> 13b0c97dafSAditya Angadi #include <drivers/arm/sp805.h> 14*59ea3648SManish V Badarkhe #include <lib/mmio.h> 151461ad9fSAlexei Fedorov #include <plat/arm/common/arm_config.h> 16bd9344f6SAntonio Nino Diaz #include <plat/arm/common/plat_arm.h> 17b0c97dafSAditya Angadi #include <plat/arm/common/arm_def.h> 1809d40e0eSAntonio Nino Diaz #include <plat/common/platform.h> 1909d40e0eSAntonio Nino Diaz #include "fvp_private.h" 203fc4124cSDan Handley 213fc4124cSDan Handley /******************************************************************************* 223fc4124cSDan Handley * Perform any BL1 specific platform actions. 233fc4124cSDan Handley ******************************************************************************/ 243fc4124cSDan Handley void bl1_early_platform_setup(void) 253fc4124cSDan Handley { 263fc4124cSDan Handley arm_bl1_early_platform_setup(); 273fc4124cSDan Handley 283fc4124cSDan Handley /* Initialize the platform config for future decision making */ 293fc4124cSDan Handley fvp_config_setup(); 303fc4124cSDan Handley 313fc4124cSDan Handley /* 326355f234SVikram Kanigiri * Initialize Interconnect for this cluster during cold boot. 333fc4124cSDan Handley * No need for locks as no other CPU is active. 343fc4124cSDan Handley */ 356355f234SVikram Kanigiri fvp_interconnect_init(); 363fc4124cSDan Handley /* 376355f234SVikram Kanigiri * Enable coherency in Interconnect for the primary CPU's cluster. 383fc4124cSDan Handley */ 396355f234SVikram Kanigiri fvp_interconnect_enable(); 403fc4124cSDan Handley } 41b0c97dafSAditya Angadi 42b0c97dafSAditya Angadi void plat_arm_secure_wdt_start(void) 43b0c97dafSAditya Angadi { 44b0c97dafSAditya Angadi sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL); 45b0c97dafSAditya Angadi } 46b0c97dafSAditya Angadi 47b0c97dafSAditya Angadi void plat_arm_secure_wdt_stop(void) 48b0c97dafSAditya Angadi { 49b0c97dafSAditya Angadi sp805_stop(ARM_SP805_TWDG_BASE); 50b0c97dafSAditya Angadi } 511461ad9fSAlexei Fedorov 521461ad9fSAlexei Fedorov void bl1_platform_setup(void) 531461ad9fSAlexei Fedorov { 541461ad9fSAlexei Fedorov arm_bl1_platform_setup(); 551461ad9fSAlexei Fedorov 561b597c22SAlexei Fedorov /* Initialize System level generic or SP804 timer */ 571b597c22SAlexei Fedorov fvp_timer_init(); 581b597c22SAlexei Fedorov 591461ad9fSAlexei Fedorov /* On FVP RevC, initialize SMMUv3 */ 601461ad9fSAlexei Fedorov if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) 611461ad9fSAlexei Fedorov smmuv3_security_init(PLAT_FVP_SMMUV3_BASE); 621461ad9fSAlexei Fedorov } 6337b70031SAmbroise Vincent 6437b70031SAmbroise Vincent __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) 6537b70031SAmbroise Vincent { 66*59ea3648SManish V Badarkhe uint32_t nv_flags = mmio_read_32(V2M_SYS_NVFLAGS_ADDR); 67*59ea3648SManish V Badarkhe 68*59ea3648SManish V Badarkhe /* Clear the NV flags register. */ 69*59ea3648SManish V Badarkhe mmio_write_32((V2M_SYSREGS_BASE + V2M_SYS_NVFLAGSCLR), 70*59ea3648SManish V Badarkhe nv_flags); 71*59ea3648SManish V Badarkhe 7237b70031SAmbroise Vincent /* Setup the watchdog to reset the system as soon as possible */ 7337b70031SAmbroise Vincent sp805_refresh(ARM_SP805_TWDG_BASE, 1U); 7437b70031SAmbroise Vincent 7592069086SJimmy Brisson while (true) 7637b70031SAmbroise Vincent wfi(); 7737b70031SAmbroise Vincent } 780ab49645SAlexei Fedorov 790ab49645SAlexei Fedorov #if MEASURED_BOOT 800ab49645SAlexei Fedorov /* 814a135bc3SAlexei Fedorov * Calculates and writes BL2 hash data to TB_FW_CONFIG DTB. 824a135bc3SAlexei Fedorov */ 834a135bc3SAlexei Fedorov void bl1_plat_set_bl2_hash(const image_desc_t *image_desc) 844a135bc3SAlexei Fedorov { 854a135bc3SAlexei Fedorov arm_bl1_set_bl2_hash(image_desc); 864a135bc3SAlexei Fedorov } 874a135bc3SAlexei Fedorov 884a135bc3SAlexei Fedorov /* 890ab49645SAlexei Fedorov * Implementation for bl1_plat_handle_post_image_load(). This function 900ab49645SAlexei Fedorov * populates the default arguments to BL2. The BL2 memory layout structure 910ab49645SAlexei Fedorov * is allocated and the calculated layout is populated in arg1 to BL2. 920ab49645SAlexei Fedorov */ 930ab49645SAlexei Fedorov int bl1_plat_handle_post_image_load(unsigned int image_id) 940ab49645SAlexei Fedorov { 950ab49645SAlexei Fedorov meminfo_t *bl2_tzram_layout; 960ab49645SAlexei Fedorov meminfo_t *bl1_tzram_layout; 970ab49645SAlexei Fedorov image_desc_t *image_desc; 980ab49645SAlexei Fedorov entry_point_info_t *ep_info; 990ab49645SAlexei Fedorov 1000ab49645SAlexei Fedorov if (image_id != BL2_IMAGE_ID) { 1010ab49645SAlexei Fedorov return 0; 1020ab49645SAlexei Fedorov } 1030ab49645SAlexei Fedorov 1040ab49645SAlexei Fedorov /* Get the image descriptor */ 1050ab49645SAlexei Fedorov image_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); 1060ab49645SAlexei Fedorov assert(image_desc != NULL); 1070ab49645SAlexei Fedorov 1080ab49645SAlexei Fedorov /* Calculate BL2 hash and set it in TB_FW_CONFIG */ 1094a135bc3SAlexei Fedorov bl1_plat_set_bl2_hash(image_desc); 1100ab49645SAlexei Fedorov 1110ab49645SAlexei Fedorov /* Get the entry point info */ 1120ab49645SAlexei Fedorov ep_info = &image_desc->ep_info; 1130ab49645SAlexei Fedorov 1140ab49645SAlexei Fedorov /* Find out how much free trusted ram remains after BL1 load */ 1150ab49645SAlexei Fedorov bl1_tzram_layout = bl1_plat_sec_mem_layout(); 1160ab49645SAlexei Fedorov 1170ab49645SAlexei Fedorov /* 1180ab49645SAlexei Fedorov * Create a new layout of memory for BL2 as seen by BL1 i.e. 1190ab49645SAlexei Fedorov * tell it the amount of total and free memory available. 1200ab49645SAlexei Fedorov * This layout is created at the first free address visible 1210ab49645SAlexei Fedorov * to BL2. BL2 will read the memory layout before using its 1220ab49645SAlexei Fedorov * memory for other purposes. 1230ab49645SAlexei Fedorov */ 1240ab49645SAlexei Fedorov bl2_tzram_layout = (meminfo_t *)bl1_tzram_layout->total_base; 1250ab49645SAlexei Fedorov 1260ab49645SAlexei Fedorov bl1_calc_bl2_mem_layout(bl1_tzram_layout, bl2_tzram_layout); 1270ab49645SAlexei Fedorov 1280ab49645SAlexei Fedorov ep_info->args.arg1 = (uintptr_t)bl2_tzram_layout; 1290ab49645SAlexei Fedorov 1300ab49645SAlexei Fedorov VERBOSE("BL1: BL2 memory layout address = %p\n", 1310ab49645SAlexei Fedorov (void *)bl2_tzram_layout); 1320ab49645SAlexei Fedorov return 0; 1330ab49645SAlexei Fedorov } 1340ab49645SAlexei Fedorov #endif /* MEASURED_BOOT */ 135*59ea3648SManish V Badarkhe 136*59ea3648SManish V Badarkhe /******************************************************************************* 137*59ea3648SManish V Badarkhe * The following function checks if Firmware update is needed by checking error 138*59ea3648SManish V Badarkhe * reported in NV flag. 139*59ea3648SManish V Badarkhe ******************************************************************************/ 140*59ea3648SManish V Badarkhe bool plat_arm_bl1_fwu_needed(void) 141*59ea3648SManish V Badarkhe { 142*59ea3648SManish V Badarkhe int32_t nv_flags = (int32_t)mmio_read_32(V2M_SYS_NVFLAGS_ADDR); 143*59ea3648SManish V Badarkhe 144*59ea3648SManish V Badarkhe /* if image load/authentication failed */ 145*59ea3648SManish V Badarkhe return ((nv_flags == -EAUTH) || (nv_flags == -ENOENT)); 146*59ea3648SManish V Badarkhe } 147