1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright 2018-2022 NXP 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu * 6*91f16700Schasinglulu */ 7*91f16700Schasinglulu 8*91f16700Schasinglulu #include <assert.h> 9*91f16700Schasinglulu 10*91f16700Schasinglulu #include <common/desc_image_load.h> 11*91f16700Schasinglulu #include <dcfg.h> 12*91f16700Schasinglulu #ifdef POLICY_FUSE_PROVISION 13*91f16700Schasinglulu #include <fuse_io.h> 14*91f16700Schasinglulu #endif 15*91f16700Schasinglulu #include <mmu_def.h> 16*91f16700Schasinglulu #include <plat_common.h> 17*91f16700Schasinglulu #ifdef NXP_NV_SW_MAINT_LAST_EXEC_DATA 18*91f16700Schasinglulu #include <plat_nv_storage.h> 19*91f16700Schasinglulu #endif 20*91f16700Schasinglulu 21*91f16700Schasinglulu #pragma weak bl2_el3_early_platform_setup 22*91f16700Schasinglulu #pragma weak bl2_el3_plat_arch_setup 23*91f16700Schasinglulu #pragma weak bl2_el3_plat_prepare_exit 24*91f16700Schasinglulu 25*91f16700Schasinglulu static dram_regions_info_t dram_regions_info = {0}; 26*91f16700Schasinglulu 27*91f16700Schasinglulu /******************************************************************************* 28*91f16700Schasinglulu * Return the pointer to the 'dram_regions_info structure of the DRAM. 29*91f16700Schasinglulu * This structure is populated after init_ddr(). 30*91f16700Schasinglulu ******************************************************************************/ 31*91f16700Schasinglulu dram_regions_info_t *get_dram_regions_info(void) 32*91f16700Schasinglulu { 33*91f16700Schasinglulu return &dram_regions_info; 34*91f16700Schasinglulu } 35*91f16700Schasinglulu 36*91f16700Schasinglulu #ifdef DDR_INIT 37*91f16700Schasinglulu static void populate_dram_regions_info(void) 38*91f16700Schasinglulu { 39*91f16700Schasinglulu long long dram_remain_size = dram_regions_info.total_dram_size; 40*91f16700Schasinglulu uint8_t reg_id = 0U; 41*91f16700Schasinglulu 42*91f16700Schasinglulu dram_regions_info.region[reg_id].addr = NXP_DRAM0_ADDR; 43*91f16700Schasinglulu dram_regions_info.region[reg_id].size = 44*91f16700Schasinglulu dram_remain_size > NXP_DRAM0_MAX_SIZE ? 45*91f16700Schasinglulu NXP_DRAM0_MAX_SIZE : dram_remain_size; 46*91f16700Schasinglulu 47*91f16700Schasinglulu if (dram_regions_info.region[reg_id].size != NXP_DRAM0_SIZE) { 48*91f16700Schasinglulu ERROR("Incorrect DRAM0 size is defined in platform_def.h\n"); 49*91f16700Schasinglulu } 50*91f16700Schasinglulu 51*91f16700Schasinglulu dram_remain_size -= dram_regions_info.region[reg_id].size; 52*91f16700Schasinglulu dram_regions_info.region[reg_id].size -= (NXP_SECURE_DRAM_SIZE 53*91f16700Schasinglulu + NXP_SP_SHRD_DRAM_SIZE); 54*91f16700Schasinglulu 55*91f16700Schasinglulu assert(dram_regions_info.region[reg_id].size > 0); 56*91f16700Schasinglulu 57*91f16700Schasinglulu /* Reducing total dram size by 66MB */ 58*91f16700Schasinglulu dram_regions_info.total_dram_size -= (NXP_SECURE_DRAM_SIZE 59*91f16700Schasinglulu + NXP_SP_SHRD_DRAM_SIZE); 60*91f16700Schasinglulu 61*91f16700Schasinglulu #if defined(NXP_DRAM1_ADDR) && defined(NXP_DRAM1_MAX_SIZE) 62*91f16700Schasinglulu if (dram_remain_size > 0) { 63*91f16700Schasinglulu reg_id++; 64*91f16700Schasinglulu dram_regions_info.region[reg_id].addr = NXP_DRAM1_ADDR; 65*91f16700Schasinglulu dram_regions_info.region[reg_id].size = 66*91f16700Schasinglulu dram_remain_size > NXP_DRAM1_MAX_SIZE ? 67*91f16700Schasinglulu NXP_DRAM1_MAX_SIZE : dram_remain_size; 68*91f16700Schasinglulu dram_remain_size -= dram_regions_info.region[reg_id].size; 69*91f16700Schasinglulu } 70*91f16700Schasinglulu #endif 71*91f16700Schasinglulu #if defined(NXP_DRAM2_ADDR) && defined(NXP_DRAM2_MAX_SIZE) 72*91f16700Schasinglulu if (dram_remain_size > 0) { 73*91f16700Schasinglulu reg_id++; 74*91f16700Schasinglulu dram_regions_info.region[reg_id].addr = NXP_DRAM1_ADDR; 75*91f16700Schasinglulu dram_regions_info.region[reg_id].size = 76*91f16700Schasinglulu dram_remain_size > NXP_DRAM1_MAX_SIZE ? 77*91f16700Schasinglulu NXP_DRAM1_MAX_SIZE : dram_remain_size; 78*91f16700Schasinglulu dram_remain_size -= dram_regions_info.region[reg_id].size; 79*91f16700Schasinglulu } 80*91f16700Schasinglulu #endif 81*91f16700Schasinglulu reg_id++; 82*91f16700Schasinglulu dram_regions_info.num_dram_regions = reg_id; 83*91f16700Schasinglulu } 84*91f16700Schasinglulu #endif 85*91f16700Schasinglulu 86*91f16700Schasinglulu #ifdef IMAGE_BL32 87*91f16700Schasinglulu /******************************************************************************* 88*91f16700Schasinglulu * Gets SPSR for BL32 entry 89*91f16700Schasinglulu ******************************************************************************/ 90*91f16700Schasinglulu static uint32_t ls_get_spsr_for_bl32_entry(void) 91*91f16700Schasinglulu { 92*91f16700Schasinglulu /* 93*91f16700Schasinglulu * The Secure Payload Dispatcher service is responsible for 94*91f16700Schasinglulu * setting the SPSR prior to entry into the BL32 image. 95*91f16700Schasinglulu */ 96*91f16700Schasinglulu return 0U; 97*91f16700Schasinglulu } 98*91f16700Schasinglulu #endif 99*91f16700Schasinglulu 100*91f16700Schasinglulu /******************************************************************************* 101*91f16700Schasinglulu * Gets SPSR for BL33 entry 102*91f16700Schasinglulu ******************************************************************************/ 103*91f16700Schasinglulu #ifndef AARCH32 104*91f16700Schasinglulu static uint32_t ls_get_spsr_for_bl33_entry(void) 105*91f16700Schasinglulu { 106*91f16700Schasinglulu unsigned int mode; 107*91f16700Schasinglulu uint32_t spsr; 108*91f16700Schasinglulu 109*91f16700Schasinglulu /* Figure out what mode we enter the non-secure world in */ 110*91f16700Schasinglulu mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1; 111*91f16700Schasinglulu 112*91f16700Schasinglulu /* 113*91f16700Schasinglulu * TODO: Consider the possibility of specifying the SPSR in 114*91f16700Schasinglulu * the FIP ToC and allowing the platform to have a say as 115*91f16700Schasinglulu * well. 116*91f16700Schasinglulu */ 117*91f16700Schasinglulu spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); 118*91f16700Schasinglulu return spsr; 119*91f16700Schasinglulu } 120*91f16700Schasinglulu #else 121*91f16700Schasinglulu /******************************************************************************* 122*91f16700Schasinglulu * Gets SPSR for BL33 entry 123*91f16700Schasinglulu ******************************************************************************/ 124*91f16700Schasinglulu static uint32_t ls_get_spsr_for_bl33_entry(void) 125*91f16700Schasinglulu { 126*91f16700Schasinglulu unsigned int hyp_status, mode, spsr; 127*91f16700Schasinglulu 128*91f16700Schasinglulu hyp_status = GET_VIRT_EXT(read_id_pfr1()); 129*91f16700Schasinglulu 130*91f16700Schasinglulu mode = (hyp_status) ? MODE32_hyp : MODE32_svc; 131*91f16700Schasinglulu 132*91f16700Schasinglulu /* 133*91f16700Schasinglulu * TODO: Consider the possibility of specifying the SPSR in 134*91f16700Schasinglulu * the FIP ToC and allowing the platform to have a say as 135*91f16700Schasinglulu * well. 136*91f16700Schasinglulu */ 137*91f16700Schasinglulu spsr = SPSR_MODE32(mode, plat_get_ns_image_entrypoint() & 0x1, 138*91f16700Schasinglulu SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS); 139*91f16700Schasinglulu return spsr; 140*91f16700Schasinglulu } 141*91f16700Schasinglulu #endif /* AARCH32 */ 142*91f16700Schasinglulu 143*91f16700Schasinglulu void bl2_el3_early_platform_setup(u_register_t arg0 __unused, 144*91f16700Schasinglulu u_register_t arg1 __unused, 145*91f16700Schasinglulu u_register_t arg2 __unused, 146*91f16700Schasinglulu u_register_t arg3 __unused) 147*91f16700Schasinglulu { 148*91f16700Schasinglulu /* 149*91f16700Schasinglulu * SoC specific early init 150*91f16700Schasinglulu * Any errata handling or SoC specific early initialization can 151*91f16700Schasinglulu * be done here 152*91f16700Schasinglulu * Set Counter Base Frequency in CNTFID0 and in cntfrq_el0. 153*91f16700Schasinglulu * Initialize the interconnect. 154*91f16700Schasinglulu * Enable coherency for primary CPU cluster 155*91f16700Schasinglulu */ 156*91f16700Schasinglulu soc_early_init(); 157*91f16700Schasinglulu 158*91f16700Schasinglulu /* Initialise the IO layer and register platform IO devices */ 159*91f16700Schasinglulu plat_io_setup(); 160*91f16700Schasinglulu 161*91f16700Schasinglulu if (dram_regions_info.total_dram_size > 0) { 162*91f16700Schasinglulu populate_dram_regions_info(); 163*91f16700Schasinglulu } 164*91f16700Schasinglulu 165*91f16700Schasinglulu #ifdef NXP_NV_SW_MAINT_LAST_EXEC_DATA 166*91f16700Schasinglulu read_nv_app_data(); 167*91f16700Schasinglulu #if DEBUG 168*91f16700Schasinglulu const nv_app_data_t *nv_app_data = get_nv_data(); 169*91f16700Schasinglulu 170*91f16700Schasinglulu INFO("Value of warm_reset flag = 0x%x\n", nv_app_data->warm_rst_flag); 171*91f16700Schasinglulu INFO("Value of WDT flag = 0x%x\n", nv_app_data->wdt_rst_flag); 172*91f16700Schasinglulu #endif 173*91f16700Schasinglulu #endif 174*91f16700Schasinglulu } 175*91f16700Schasinglulu 176*91f16700Schasinglulu /******************************************************************************* 177*91f16700Schasinglulu * Perform the very early platform specific architectural setup here. At the 178*91f16700Schasinglulu * moment this is only initializes the mmu in a quick and dirty way. 179*91f16700Schasinglulu ******************************************************************************/ 180*91f16700Schasinglulu void ls_bl2_el3_plat_arch_setup(void) 181*91f16700Schasinglulu { 182*91f16700Schasinglulu unsigned int flags = 0U; 183*91f16700Schasinglulu /* Initialise the IO layer and register platform IO devices */ 184*91f16700Schasinglulu ls_setup_page_tables( 185*91f16700Schasinglulu #if SEPARATE_BL2_NOLOAD_REGION 186*91f16700Schasinglulu BL2_START, 187*91f16700Schasinglulu BL2_LIMIT - BL2_START, 188*91f16700Schasinglulu #else 189*91f16700Schasinglulu BL2_BASE, 190*91f16700Schasinglulu (unsigned long)(&__BL2_END__) - BL2_BASE, 191*91f16700Schasinglulu #endif 192*91f16700Schasinglulu BL_CODE_BASE, 193*91f16700Schasinglulu BL_CODE_END, 194*91f16700Schasinglulu BL_RO_DATA_BASE, 195*91f16700Schasinglulu BL_RO_DATA_END 196*91f16700Schasinglulu #if USE_COHERENT_MEM 197*91f16700Schasinglulu , BL_COHERENT_RAM_BASE, 198*91f16700Schasinglulu BL_COHERENT_RAM_END 199*91f16700Schasinglulu #endif 200*91f16700Schasinglulu ); 201*91f16700Schasinglulu 202*91f16700Schasinglulu if ((dram_regions_info.region[0].addr == 0) 203*91f16700Schasinglulu && (dram_regions_info.total_dram_size == 0)) { 204*91f16700Schasinglulu flags = XLAT_TABLE_NC; 205*91f16700Schasinglulu } 206*91f16700Schasinglulu 207*91f16700Schasinglulu #ifdef AARCH32 208*91f16700Schasinglulu enable_mmu_secure(0); 209*91f16700Schasinglulu #else 210*91f16700Schasinglulu enable_mmu_el3(flags); 211*91f16700Schasinglulu #endif 212*91f16700Schasinglulu } 213*91f16700Schasinglulu 214*91f16700Schasinglulu void bl2_el3_plat_arch_setup(void) 215*91f16700Schasinglulu { 216*91f16700Schasinglulu ls_bl2_el3_plat_arch_setup(); 217*91f16700Schasinglulu } 218*91f16700Schasinglulu 219*91f16700Schasinglulu void bl2_platform_setup(void) 220*91f16700Schasinglulu { 221*91f16700Schasinglulu /* 222*91f16700Schasinglulu * Perform platform setup before loading the image. 223*91f16700Schasinglulu */ 224*91f16700Schasinglulu } 225*91f16700Schasinglulu 226*91f16700Schasinglulu /* Handling image information by platform. */ 227*91f16700Schasinglulu int ls_bl2_handle_post_image_load(unsigned int image_id) 228*91f16700Schasinglulu { 229*91f16700Schasinglulu int err = 0; 230*91f16700Schasinglulu bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); 231*91f16700Schasinglulu 232*91f16700Schasinglulu assert(bl_mem_params); 233*91f16700Schasinglulu 234*91f16700Schasinglulu switch (image_id) { 235*91f16700Schasinglulu case BL31_IMAGE_ID: 236*91f16700Schasinglulu bl_mem_params->ep_info.args.arg3 = 237*91f16700Schasinglulu (u_register_t) &dram_regions_info; 238*91f16700Schasinglulu 239*91f16700Schasinglulu /* Pass the value of PORSR1 register in Argument 4 */ 240*91f16700Schasinglulu bl_mem_params->ep_info.args.arg4 = 241*91f16700Schasinglulu (u_register_t)read_reg_porsr1(); 242*91f16700Schasinglulu flush_dcache_range((uintptr_t)&dram_regions_info, 243*91f16700Schasinglulu sizeof(dram_regions_info)); 244*91f16700Schasinglulu break; 245*91f16700Schasinglulu #if defined(AARCH64) && defined(IMAGE_BL32) 246*91f16700Schasinglulu case BL32_IMAGE_ID: 247*91f16700Schasinglulu bl_mem_params->ep_info.spsr = ls_get_spsr_for_bl32_entry(); 248*91f16700Schasinglulu break; 249*91f16700Schasinglulu #endif 250*91f16700Schasinglulu case BL33_IMAGE_ID: 251*91f16700Schasinglulu /* BL33 expects to receive the primary CPU MPID (through r0) */ 252*91f16700Schasinglulu bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); 253*91f16700Schasinglulu bl_mem_params->ep_info.spsr = ls_get_spsr_for_bl33_entry(); 254*91f16700Schasinglulu break; 255*91f16700Schasinglulu } 256*91f16700Schasinglulu 257*91f16700Schasinglulu return err; 258*91f16700Schasinglulu } 259*91f16700Schasinglulu 260*91f16700Schasinglulu /******************************************************************************* 261*91f16700Schasinglulu * This function can be used by the platforms to update/use image 262*91f16700Schasinglulu * information for given `image_id`. 263*91f16700Schasinglulu ******************************************************************************/ 264*91f16700Schasinglulu int bl2_plat_handle_post_image_load(unsigned int image_id) 265*91f16700Schasinglulu { 266*91f16700Schasinglulu return ls_bl2_handle_post_image_load(image_id); 267*91f16700Schasinglulu } 268*91f16700Schasinglulu 269*91f16700Schasinglulu void bl2_el3_plat_prepare_exit(void) 270*91f16700Schasinglulu { 271*91f16700Schasinglulu return soc_bl2_prepare_exit(); 272*91f16700Schasinglulu } 273*91f16700Schasinglulu 274*91f16700Schasinglulu /* Called to do the dynamic initialization required 275*91f16700Schasinglulu * before loading the next image. 276*91f16700Schasinglulu */ 277*91f16700Schasinglulu void bl2_plat_preload_setup(void) 278*91f16700Schasinglulu { 279*91f16700Schasinglulu 280*91f16700Schasinglulu soc_preload_setup(); 281*91f16700Schasinglulu 282*91f16700Schasinglulu #ifdef DDR_INIT 283*91f16700Schasinglulu if (dram_regions_info.total_dram_size <= 0) { 284*91f16700Schasinglulu ERROR("Asserting as the DDR is not initialized yet."); 285*91f16700Schasinglulu assert(false); 286*91f16700Schasinglulu } 287*91f16700Schasinglulu #endif 288*91f16700Schasinglulu 289*91f16700Schasinglulu if ((dram_regions_info.region[0].addr == 0) 290*91f16700Schasinglulu && (dram_regions_info.total_dram_size > 0)) { 291*91f16700Schasinglulu populate_dram_regions_info(); 292*91f16700Schasinglulu #ifdef PLAT_XLAT_TABLES_DYNAMIC 293*91f16700Schasinglulu mmap_add_ddr_region_dynamically(); 294*91f16700Schasinglulu #endif 295*91f16700Schasinglulu } 296*91f16700Schasinglulu 297*91f16700Schasinglulu /* setup the memory region access permissions */ 298*91f16700Schasinglulu soc_mem_access(); 299*91f16700Schasinglulu 300*91f16700Schasinglulu #ifdef POLICY_FUSE_PROVISION 301*91f16700Schasinglulu fip_fuse_provisioning((uintptr_t)FUSE_BUF, FUSE_SZ); 302*91f16700Schasinglulu #endif 303*91f16700Schasinglulu } 304