1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2015-2023, 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 #include <string.h> 9*91f16700Schasinglulu 10*91f16700Schasinglulu #include <platform_def.h> 11*91f16700Schasinglulu 12*91f16700Schasinglulu #include <arch_features.h> 13*91f16700Schasinglulu #include <arch_helpers.h> 14*91f16700Schasinglulu #include <common/bl_common.h> 15*91f16700Schasinglulu #include <common/debug.h> 16*91f16700Schasinglulu #include <common/desc_image_load.h> 17*91f16700Schasinglulu #include <drivers/generic_delay_timer.h> 18*91f16700Schasinglulu #include <drivers/partition/partition.h> 19*91f16700Schasinglulu #include <lib/fconf/fconf.h> 20*91f16700Schasinglulu #include <lib/fconf/fconf_dyn_cfg_getter.h> 21*91f16700Schasinglulu #include <lib/gpt_rme/gpt_rme.h> 22*91f16700Schasinglulu #ifdef SPD_opteed 23*91f16700Schasinglulu #include <lib/optee_utils.h> 24*91f16700Schasinglulu #endif 25*91f16700Schasinglulu #include <lib/utils.h> 26*91f16700Schasinglulu #if ENABLE_RME 27*91f16700Schasinglulu #include <plat/arm/common/arm_pas_def.h> 28*91f16700Schasinglulu #endif 29*91f16700Schasinglulu #include <plat/arm/common/plat_arm.h> 30*91f16700Schasinglulu #include <plat/common/platform.h> 31*91f16700Schasinglulu 32*91f16700Schasinglulu /* Data structure which holds the extents of the trusted SRAM for BL2 */ 33*91f16700Schasinglulu static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); 34*91f16700Schasinglulu 35*91f16700Schasinglulu /* Base address of fw_config received from BL1 */ 36*91f16700Schasinglulu static uintptr_t config_base; 37*91f16700Schasinglulu 38*91f16700Schasinglulu /* 39*91f16700Schasinglulu * Check that BL2_BASE is above ARM_FW_CONFIG_LIMIT. This reserved page is 40*91f16700Schasinglulu * for `meminfo_t` data structure and fw_configs passed from BL1. 41*91f16700Schasinglulu */ 42*91f16700Schasinglulu CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows); 43*91f16700Schasinglulu 44*91f16700Schasinglulu /* Weak definitions may be overridden in specific ARM standard platform */ 45*91f16700Schasinglulu #pragma weak bl2_early_platform_setup2 46*91f16700Schasinglulu #pragma weak bl2_platform_setup 47*91f16700Schasinglulu #pragma weak bl2_plat_arch_setup 48*91f16700Schasinglulu #pragma weak bl2_plat_sec_mem_layout 49*91f16700Schasinglulu 50*91f16700Schasinglulu #if ENABLE_RME 51*91f16700Schasinglulu #define MAP_BL2_TOTAL MAP_REGION_FLAT( \ 52*91f16700Schasinglulu bl2_tzram_layout.total_base, \ 53*91f16700Schasinglulu bl2_tzram_layout.total_size, \ 54*91f16700Schasinglulu MT_MEMORY | MT_RW | MT_ROOT) 55*91f16700Schasinglulu #else 56*91f16700Schasinglulu #define MAP_BL2_TOTAL MAP_REGION_FLAT( \ 57*91f16700Schasinglulu bl2_tzram_layout.total_base, \ 58*91f16700Schasinglulu bl2_tzram_layout.total_size, \ 59*91f16700Schasinglulu MT_MEMORY | MT_RW | MT_SECURE) 60*91f16700Schasinglulu #endif /* ENABLE_RME */ 61*91f16700Schasinglulu 62*91f16700Schasinglulu #pragma weak arm_bl2_plat_handle_post_image_load 63*91f16700Schasinglulu 64*91f16700Schasinglulu /******************************************************************************* 65*91f16700Schasinglulu * BL1 has passed the extents of the trusted SRAM that should be visible to BL2 66*91f16700Schasinglulu * in x0. This memory layout is sitting at the base of the free trusted SRAM. 67*91f16700Schasinglulu * Copy it to a safe location before its reclaimed by later BL2 functionality. 68*91f16700Schasinglulu ******************************************************************************/ 69*91f16700Schasinglulu void arm_bl2_early_platform_setup(uintptr_t fw_config, 70*91f16700Schasinglulu struct meminfo *mem_layout) 71*91f16700Schasinglulu { 72*91f16700Schasinglulu int __maybe_unused ret; 73*91f16700Schasinglulu 74*91f16700Schasinglulu /* Initialize the console to provide early debug support */ 75*91f16700Schasinglulu arm_console_boot_init(); 76*91f16700Schasinglulu 77*91f16700Schasinglulu /* Setup the BL2 memory layout */ 78*91f16700Schasinglulu bl2_tzram_layout = *mem_layout; 79*91f16700Schasinglulu 80*91f16700Schasinglulu config_base = fw_config; 81*91f16700Schasinglulu 82*91f16700Schasinglulu /* Initialise the IO layer and register platform IO devices */ 83*91f16700Schasinglulu plat_arm_io_setup(); 84*91f16700Schasinglulu 85*91f16700Schasinglulu /* Load partition table */ 86*91f16700Schasinglulu #if ARM_GPT_SUPPORT 87*91f16700Schasinglulu ret = gpt_partition_init(); 88*91f16700Schasinglulu if (ret != 0) { 89*91f16700Schasinglulu ERROR("GPT partition initialisation failed!\n"); 90*91f16700Schasinglulu panic(); 91*91f16700Schasinglulu } 92*91f16700Schasinglulu 93*91f16700Schasinglulu #endif /* ARM_GPT_SUPPORT */ 94*91f16700Schasinglulu } 95*91f16700Schasinglulu 96*91f16700Schasinglulu void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) 97*91f16700Schasinglulu { 98*91f16700Schasinglulu arm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1); 99*91f16700Schasinglulu 100*91f16700Schasinglulu generic_delay_timer_init(); 101*91f16700Schasinglulu } 102*91f16700Schasinglulu 103*91f16700Schasinglulu /* 104*91f16700Schasinglulu * Perform BL2 preload setup. Currently we initialise the dynamic 105*91f16700Schasinglulu * configuration here. 106*91f16700Schasinglulu */ 107*91f16700Schasinglulu void bl2_plat_preload_setup(void) 108*91f16700Schasinglulu { 109*91f16700Schasinglulu arm_bl2_dyn_cfg_init(); 110*91f16700Schasinglulu 111*91f16700Schasinglulu #if ARM_GPT_SUPPORT && !PSA_FWU_SUPPORT 112*91f16700Schasinglulu /* Always use the FIP from bank 0 */ 113*91f16700Schasinglulu arm_set_fip_addr(0U); 114*91f16700Schasinglulu #endif /* ARM_GPT_SUPPORT && !PSA_FWU_SUPPORT */ 115*91f16700Schasinglulu } 116*91f16700Schasinglulu 117*91f16700Schasinglulu /* 118*91f16700Schasinglulu * Perform ARM standard platform setup. 119*91f16700Schasinglulu */ 120*91f16700Schasinglulu void arm_bl2_platform_setup(void) 121*91f16700Schasinglulu { 122*91f16700Schasinglulu #if !ENABLE_RME 123*91f16700Schasinglulu /* Initialize the secure environment */ 124*91f16700Schasinglulu plat_arm_security_setup(); 125*91f16700Schasinglulu #endif 126*91f16700Schasinglulu 127*91f16700Schasinglulu #if defined(PLAT_ARM_MEM_PROT_ADDR) 128*91f16700Schasinglulu arm_nor_psci_do_static_mem_protect(); 129*91f16700Schasinglulu #endif 130*91f16700Schasinglulu } 131*91f16700Schasinglulu 132*91f16700Schasinglulu void bl2_platform_setup(void) 133*91f16700Schasinglulu { 134*91f16700Schasinglulu arm_bl2_platform_setup(); 135*91f16700Schasinglulu } 136*91f16700Schasinglulu 137*91f16700Schasinglulu #if ENABLE_RME 138*91f16700Schasinglulu static void arm_bl2_plat_gpt_setup(void) 139*91f16700Schasinglulu { 140*91f16700Schasinglulu /* 141*91f16700Schasinglulu * The GPT library might modify the gpt regions structure to optimize 142*91f16700Schasinglulu * the layout, so the array cannot be constant. 143*91f16700Schasinglulu */ 144*91f16700Schasinglulu pas_region_t pas_regions[] = { 145*91f16700Schasinglulu ARM_PAS_KERNEL, 146*91f16700Schasinglulu ARM_PAS_SECURE, 147*91f16700Schasinglulu ARM_PAS_REALM, 148*91f16700Schasinglulu ARM_PAS_EL3_DRAM, 149*91f16700Schasinglulu ARM_PAS_GPTS, 150*91f16700Schasinglulu ARM_PAS_KERNEL_1 151*91f16700Schasinglulu }; 152*91f16700Schasinglulu 153*91f16700Schasinglulu /* Initialize entire protected space to GPT_GPI_ANY. */ 154*91f16700Schasinglulu if (gpt_init_l0_tables(GPCCR_PPS_64GB, ARM_L0_GPT_ADDR_BASE, 155*91f16700Schasinglulu ARM_L0_GPT_SIZE) < 0) { 156*91f16700Schasinglulu ERROR("gpt_init_l0_tables() failed!\n"); 157*91f16700Schasinglulu panic(); 158*91f16700Schasinglulu } 159*91f16700Schasinglulu 160*91f16700Schasinglulu /* Carve out defined PAS ranges. */ 161*91f16700Schasinglulu if (gpt_init_pas_l1_tables(GPCCR_PGS_4K, 162*91f16700Schasinglulu ARM_L1_GPT_ADDR_BASE, 163*91f16700Schasinglulu ARM_L1_GPT_SIZE, 164*91f16700Schasinglulu pas_regions, 165*91f16700Schasinglulu (unsigned int)(sizeof(pas_regions) / 166*91f16700Schasinglulu sizeof(pas_region_t))) < 0) { 167*91f16700Schasinglulu ERROR("gpt_init_pas_l1_tables() failed!\n"); 168*91f16700Schasinglulu panic(); 169*91f16700Schasinglulu } 170*91f16700Schasinglulu 171*91f16700Schasinglulu INFO("Enabling Granule Protection Checks\n"); 172*91f16700Schasinglulu if (gpt_enable() < 0) { 173*91f16700Schasinglulu ERROR("gpt_enable() failed!\n"); 174*91f16700Schasinglulu panic(); 175*91f16700Schasinglulu } 176*91f16700Schasinglulu } 177*91f16700Schasinglulu #endif /* ENABLE_RME */ 178*91f16700Schasinglulu 179*91f16700Schasinglulu /******************************************************************************* 180*91f16700Schasinglulu * Perform the very early platform specific architectural setup here. 181*91f16700Schasinglulu * When RME is enabled the secure environment is initialised before 182*91f16700Schasinglulu * initialising and enabling Granule Protection. 183*91f16700Schasinglulu * This function initialises the MMU in a quick and dirty way. 184*91f16700Schasinglulu ******************************************************************************/ 185*91f16700Schasinglulu void arm_bl2_plat_arch_setup(void) 186*91f16700Schasinglulu { 187*91f16700Schasinglulu #if USE_COHERENT_MEM 188*91f16700Schasinglulu /* Ensure ARM platforms don't use coherent memory in BL2. */ 189*91f16700Schasinglulu assert((BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE) == 0U); 190*91f16700Schasinglulu #endif 191*91f16700Schasinglulu 192*91f16700Schasinglulu const mmap_region_t bl_regions[] = { 193*91f16700Schasinglulu MAP_BL2_TOTAL, 194*91f16700Schasinglulu ARM_MAP_BL_RO, 195*91f16700Schasinglulu #if USE_ROMLIB 196*91f16700Schasinglulu ARM_MAP_ROMLIB_CODE, 197*91f16700Schasinglulu ARM_MAP_ROMLIB_DATA, 198*91f16700Schasinglulu #endif 199*91f16700Schasinglulu ARM_MAP_BL_CONFIG_REGION, 200*91f16700Schasinglulu #if ENABLE_RME 201*91f16700Schasinglulu ARM_MAP_L0_GPT_REGION, 202*91f16700Schasinglulu #endif 203*91f16700Schasinglulu {0} 204*91f16700Schasinglulu }; 205*91f16700Schasinglulu 206*91f16700Schasinglulu #if ENABLE_RME 207*91f16700Schasinglulu /* Initialise the secure environment */ 208*91f16700Schasinglulu plat_arm_security_setup(); 209*91f16700Schasinglulu #endif 210*91f16700Schasinglulu setup_page_tables(bl_regions, plat_arm_get_mmap()); 211*91f16700Schasinglulu 212*91f16700Schasinglulu #ifdef __aarch64__ 213*91f16700Schasinglulu #if ENABLE_RME 214*91f16700Schasinglulu /* BL2 runs in EL3 when RME enabled. */ 215*91f16700Schasinglulu assert(get_armv9_2_feat_rme_support() != 0U); 216*91f16700Schasinglulu enable_mmu_el3(0); 217*91f16700Schasinglulu 218*91f16700Schasinglulu /* Initialise and enable granule protection after MMU. */ 219*91f16700Schasinglulu arm_bl2_plat_gpt_setup(); 220*91f16700Schasinglulu #else 221*91f16700Schasinglulu enable_mmu_el1(0); 222*91f16700Schasinglulu #endif 223*91f16700Schasinglulu #else 224*91f16700Schasinglulu enable_mmu_svc_mon(0); 225*91f16700Schasinglulu #endif 226*91f16700Schasinglulu 227*91f16700Schasinglulu arm_setup_romlib(); 228*91f16700Schasinglulu } 229*91f16700Schasinglulu 230*91f16700Schasinglulu void bl2_plat_arch_setup(void) 231*91f16700Schasinglulu { 232*91f16700Schasinglulu const struct dyn_cfg_dtb_info_t *tb_fw_config_info; 233*91f16700Schasinglulu 234*91f16700Schasinglulu arm_bl2_plat_arch_setup(); 235*91f16700Schasinglulu 236*91f16700Schasinglulu /* Fill the properties struct with the info from the config dtb */ 237*91f16700Schasinglulu fconf_populate("FW_CONFIG", config_base); 238*91f16700Schasinglulu 239*91f16700Schasinglulu /* TB_FW_CONFIG was also loaded by BL1 */ 240*91f16700Schasinglulu tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); 241*91f16700Schasinglulu assert(tb_fw_config_info != NULL); 242*91f16700Schasinglulu 243*91f16700Schasinglulu fconf_populate("TB_FW", tb_fw_config_info->config_addr); 244*91f16700Schasinglulu } 245*91f16700Schasinglulu 246*91f16700Schasinglulu int arm_bl2_handle_post_image_load(unsigned int image_id) 247*91f16700Schasinglulu { 248*91f16700Schasinglulu int err = 0; 249*91f16700Schasinglulu bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); 250*91f16700Schasinglulu #ifdef SPD_opteed 251*91f16700Schasinglulu bl_mem_params_node_t *pager_mem_params = NULL; 252*91f16700Schasinglulu bl_mem_params_node_t *paged_mem_params = NULL; 253*91f16700Schasinglulu #endif 254*91f16700Schasinglulu assert(bl_mem_params != NULL); 255*91f16700Schasinglulu 256*91f16700Schasinglulu switch (image_id) { 257*91f16700Schasinglulu #ifdef __aarch64__ 258*91f16700Schasinglulu case BL32_IMAGE_ID: 259*91f16700Schasinglulu #ifdef SPD_opteed 260*91f16700Schasinglulu pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); 261*91f16700Schasinglulu assert(pager_mem_params); 262*91f16700Schasinglulu 263*91f16700Schasinglulu paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); 264*91f16700Schasinglulu assert(paged_mem_params); 265*91f16700Schasinglulu 266*91f16700Schasinglulu err = parse_optee_header(&bl_mem_params->ep_info, 267*91f16700Schasinglulu &pager_mem_params->image_info, 268*91f16700Schasinglulu &paged_mem_params->image_info); 269*91f16700Schasinglulu if (err != 0) { 270*91f16700Schasinglulu WARN("OPTEE header parse error.\n"); 271*91f16700Schasinglulu } 272*91f16700Schasinglulu #endif 273*91f16700Schasinglulu bl_mem_params->ep_info.spsr = arm_get_spsr_for_bl32_entry(); 274*91f16700Schasinglulu break; 275*91f16700Schasinglulu #endif 276*91f16700Schasinglulu 277*91f16700Schasinglulu case BL33_IMAGE_ID: 278*91f16700Schasinglulu /* BL33 expects to receive the primary CPU MPID (through r0) */ 279*91f16700Schasinglulu bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); 280*91f16700Schasinglulu bl_mem_params->ep_info.spsr = arm_get_spsr_for_bl33_entry(); 281*91f16700Schasinglulu break; 282*91f16700Schasinglulu 283*91f16700Schasinglulu #ifdef SCP_BL2_BASE 284*91f16700Schasinglulu case SCP_BL2_IMAGE_ID: 285*91f16700Schasinglulu /* The subsequent handling of SCP_BL2 is platform specific */ 286*91f16700Schasinglulu err = plat_arm_bl2_handle_scp_bl2(&bl_mem_params->image_info); 287*91f16700Schasinglulu if (err) { 288*91f16700Schasinglulu WARN("Failure in platform-specific handling of SCP_BL2 image.\n"); 289*91f16700Schasinglulu } 290*91f16700Schasinglulu break; 291*91f16700Schasinglulu #endif 292*91f16700Schasinglulu default: 293*91f16700Schasinglulu /* Do nothing in default case */ 294*91f16700Schasinglulu break; 295*91f16700Schasinglulu } 296*91f16700Schasinglulu 297*91f16700Schasinglulu return err; 298*91f16700Schasinglulu } 299*91f16700Schasinglulu 300*91f16700Schasinglulu /******************************************************************************* 301*91f16700Schasinglulu * This function can be used by the platforms to update/use image 302*91f16700Schasinglulu * information for given `image_id`. 303*91f16700Schasinglulu ******************************************************************************/ 304*91f16700Schasinglulu int arm_bl2_plat_handle_post_image_load(unsigned int image_id) 305*91f16700Schasinglulu { 306*91f16700Schasinglulu #if defined(SPD_spmd) && BL2_ENABLE_SP_LOAD 307*91f16700Schasinglulu /* For Secure Partitions we don't need post processing */ 308*91f16700Schasinglulu if ((image_id >= (MAX_NUMBER_IDS - MAX_SP_IDS)) && 309*91f16700Schasinglulu (image_id < MAX_NUMBER_IDS)) { 310*91f16700Schasinglulu return 0; 311*91f16700Schasinglulu } 312*91f16700Schasinglulu #endif 313*91f16700Schasinglulu return arm_bl2_handle_post_image_load(image_id); 314*91f16700Schasinglulu } 315