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