1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2016-2020, 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 <bl32/sp_min/platform_sp_min.h> 12*91f16700Schasinglulu #include <common/bl_common.h> 13*91f16700Schasinglulu #include <common/debug.h> 14*91f16700Schasinglulu #include <drivers/console.h> 15*91f16700Schasinglulu #include <lib/mmio.h> 16*91f16700Schasinglulu #include <plat/arm/common/plat_arm.h> 17*91f16700Schasinglulu #include <plat/common/platform.h> 18*91f16700Schasinglulu 19*91f16700Schasinglulu static entry_point_info_t bl33_image_ep_info; 20*91f16700Schasinglulu 21*91f16700Schasinglulu /* Weak definitions may be overridden in specific ARM standard platform */ 22*91f16700Schasinglulu #pragma weak sp_min_platform_setup 23*91f16700Schasinglulu #pragma weak sp_min_plat_arch_setup 24*91f16700Schasinglulu #pragma weak plat_arm_sp_min_early_platform_setup 25*91f16700Schasinglulu 26*91f16700Schasinglulu #define MAP_BL_SP_MIN_TOTAL MAP_REGION_FLAT( \ 27*91f16700Schasinglulu BL32_BASE, \ 28*91f16700Schasinglulu BL32_END - BL32_BASE, \ 29*91f16700Schasinglulu MT_MEMORY | MT_RW | MT_SECURE) 30*91f16700Schasinglulu 31*91f16700Schasinglulu /* 32*91f16700Schasinglulu * Check that BL32_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page 33*91f16700Schasinglulu * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2. 34*91f16700Schasinglulu */ 35*91f16700Schasinglulu #if !RESET_TO_SP_MIN 36*91f16700Schasinglulu CASSERT(BL32_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl32_base_overflows); 37*91f16700Schasinglulu #endif 38*91f16700Schasinglulu 39*91f16700Schasinglulu /******************************************************************************* 40*91f16700Schasinglulu * Return a pointer to the 'entry_point_info' structure of the next image for the 41*91f16700Schasinglulu * security state specified. BL33 corresponds to the non-secure image type 42*91f16700Schasinglulu * while BL32 corresponds to the secure image type. A NULL pointer is returned 43*91f16700Schasinglulu * if the image does not exist. 44*91f16700Schasinglulu ******************************************************************************/ 45*91f16700Schasinglulu entry_point_info_t *sp_min_plat_get_bl33_ep_info(void) 46*91f16700Schasinglulu { 47*91f16700Schasinglulu entry_point_info_t *next_image_info; 48*91f16700Schasinglulu 49*91f16700Schasinglulu next_image_info = &bl33_image_ep_info; 50*91f16700Schasinglulu 51*91f16700Schasinglulu /* 52*91f16700Schasinglulu * None of the images on the ARM development platforms can have 0x0 53*91f16700Schasinglulu * as the entrypoint 54*91f16700Schasinglulu */ 55*91f16700Schasinglulu if (next_image_info->pc) 56*91f16700Schasinglulu return next_image_info; 57*91f16700Schasinglulu else 58*91f16700Schasinglulu return NULL; 59*91f16700Schasinglulu } 60*91f16700Schasinglulu 61*91f16700Schasinglulu /******************************************************************************* 62*91f16700Schasinglulu * Utility function to perform early platform setup. 63*91f16700Schasinglulu ******************************************************************************/ 64*91f16700Schasinglulu void arm_sp_min_early_platform_setup(void *from_bl2, uintptr_t tos_fw_config, 65*91f16700Schasinglulu uintptr_t hw_config, void *plat_params_from_bl2) 66*91f16700Schasinglulu { 67*91f16700Schasinglulu /* Initialize the console to provide early debug support */ 68*91f16700Schasinglulu arm_console_boot_init(); 69*91f16700Schasinglulu 70*91f16700Schasinglulu #if RESET_TO_SP_MIN 71*91f16700Schasinglulu /* There are no parameters from BL2 if SP_MIN is a reset vector */ 72*91f16700Schasinglulu assert(from_bl2 == NULL); 73*91f16700Schasinglulu assert(plat_params_from_bl2 == NULL); 74*91f16700Schasinglulu 75*91f16700Schasinglulu /* Populate entry point information for BL33 */ 76*91f16700Schasinglulu SET_PARAM_HEAD(&bl33_image_ep_info, 77*91f16700Schasinglulu PARAM_EP, 78*91f16700Schasinglulu VERSION_1, 79*91f16700Schasinglulu 0); 80*91f16700Schasinglulu /* 81*91f16700Schasinglulu * Tell SP_MIN where the non-trusted software image 82*91f16700Schasinglulu * is located and the entry state information 83*91f16700Schasinglulu */ 84*91f16700Schasinglulu bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); 85*91f16700Schasinglulu bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry(); 86*91f16700Schasinglulu SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); 87*91f16700Schasinglulu 88*91f16700Schasinglulu # if ARM_LINUX_KERNEL_AS_BL33 89*91f16700Schasinglulu /* 90*91f16700Schasinglulu * According to the file ``Documentation/arm/Booting`` of the Linux 91*91f16700Schasinglulu * kernel tree, Linux expects: 92*91f16700Schasinglulu * r0 = 0 93*91f16700Schasinglulu * r1 = machine type number, optional in DT-only platforms (~0 if so) 94*91f16700Schasinglulu * r2 = Physical address of the device tree blob 95*91f16700Schasinglulu */ 96*91f16700Schasinglulu bl33_image_ep_info.args.arg0 = 0U; 97*91f16700Schasinglulu bl33_image_ep_info.args.arg1 = ~0U; 98*91f16700Schasinglulu bl33_image_ep_info.args.arg2 = (u_register_t)ARM_PRELOADED_DTB_BASE; 99*91f16700Schasinglulu # endif 100*91f16700Schasinglulu 101*91f16700Schasinglulu #else /* RESET_TO_SP_MIN */ 102*91f16700Schasinglulu 103*91f16700Schasinglulu /* 104*91f16700Schasinglulu * Check params passed from BL2 should not be NULL, 105*91f16700Schasinglulu */ 106*91f16700Schasinglulu bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2; 107*91f16700Schasinglulu assert(params_from_bl2 != NULL); 108*91f16700Schasinglulu assert(params_from_bl2->h.type == PARAM_BL_PARAMS); 109*91f16700Schasinglulu assert(params_from_bl2->h.version >= VERSION_2); 110*91f16700Schasinglulu 111*91f16700Schasinglulu bl_params_node_t *bl_params = params_from_bl2->head; 112*91f16700Schasinglulu 113*91f16700Schasinglulu /* 114*91f16700Schasinglulu * Copy BL33 entry point information. 115*91f16700Schasinglulu * They are stored in Secure RAM, in BL2's address space. 116*91f16700Schasinglulu */ 117*91f16700Schasinglulu while (bl_params) { 118*91f16700Schasinglulu if (bl_params->image_id == BL33_IMAGE_ID) { 119*91f16700Schasinglulu bl33_image_ep_info = *bl_params->ep_info; 120*91f16700Schasinglulu break; 121*91f16700Schasinglulu } 122*91f16700Schasinglulu 123*91f16700Schasinglulu bl_params = bl_params->next_params_info; 124*91f16700Schasinglulu } 125*91f16700Schasinglulu 126*91f16700Schasinglulu if (bl33_image_ep_info.pc == 0) 127*91f16700Schasinglulu panic(); 128*91f16700Schasinglulu 129*91f16700Schasinglulu #endif /* RESET_TO_SP_MIN */ 130*91f16700Schasinglulu 131*91f16700Schasinglulu } 132*91f16700Schasinglulu 133*91f16700Schasinglulu /******************************************************************************* 134*91f16700Schasinglulu * Default implementation for sp_min_platform_setup2() for ARM platforms 135*91f16700Schasinglulu ******************************************************************************/ 136*91f16700Schasinglulu void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1, 137*91f16700Schasinglulu u_register_t arg2, u_register_t arg3) 138*91f16700Schasinglulu { 139*91f16700Schasinglulu arm_sp_min_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); 140*91f16700Schasinglulu 141*91f16700Schasinglulu /* 142*91f16700Schasinglulu * Initialize Interconnect for this cluster during cold boot. 143*91f16700Schasinglulu * No need for locks as no other CPU is active. 144*91f16700Schasinglulu */ 145*91f16700Schasinglulu plat_arm_interconnect_init(); 146*91f16700Schasinglulu 147*91f16700Schasinglulu /* 148*91f16700Schasinglulu * Enable Interconnect coherency for the primary CPU's cluster. 149*91f16700Schasinglulu * Earlier bootloader stages might already do this (e.g. Trusted 150*91f16700Schasinglulu * Firmware's BL1 does it) but we can't assume so. There is no harm in 151*91f16700Schasinglulu * executing this code twice anyway. 152*91f16700Schasinglulu * Platform specific PSCI code will enable coherency for other 153*91f16700Schasinglulu * clusters. 154*91f16700Schasinglulu */ 155*91f16700Schasinglulu plat_arm_interconnect_enter_coherency(); 156*91f16700Schasinglulu } 157*91f16700Schasinglulu 158*91f16700Schasinglulu void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, 159*91f16700Schasinglulu u_register_t arg2, u_register_t arg3) 160*91f16700Schasinglulu { 161*91f16700Schasinglulu plat_arm_sp_min_early_platform_setup(arg0, arg1, arg2, arg3); 162*91f16700Schasinglulu } 163*91f16700Schasinglulu 164*91f16700Schasinglulu /******************************************************************************* 165*91f16700Schasinglulu * Perform any SP_MIN platform runtime setup prior to SP_MIN exit. 166*91f16700Schasinglulu * Common to ARM standard platforms. 167*91f16700Schasinglulu ******************************************************************************/ 168*91f16700Schasinglulu void arm_sp_min_plat_runtime_setup(void) 169*91f16700Schasinglulu { 170*91f16700Schasinglulu /* Initialize the runtime console */ 171*91f16700Schasinglulu arm_console_runtime_init(); 172*91f16700Schasinglulu 173*91f16700Schasinglulu #if PLAT_RO_XLAT_TABLES 174*91f16700Schasinglulu arm_xlat_make_tables_readonly(); 175*91f16700Schasinglulu #endif 176*91f16700Schasinglulu } 177*91f16700Schasinglulu 178*91f16700Schasinglulu /******************************************************************************* 179*91f16700Schasinglulu * Perform platform specific setup for SP_MIN 180*91f16700Schasinglulu ******************************************************************************/ 181*91f16700Schasinglulu void sp_min_platform_setup(void) 182*91f16700Schasinglulu { 183*91f16700Schasinglulu /* Initialize the GIC driver, cpu and distributor interfaces */ 184*91f16700Schasinglulu plat_arm_gic_driver_init(); 185*91f16700Schasinglulu plat_arm_gic_init(); 186*91f16700Schasinglulu 187*91f16700Schasinglulu /* 188*91f16700Schasinglulu * Do initial security configuration to allow DRAM/device access 189*91f16700Schasinglulu * (if earlier BL has not already done so). 190*91f16700Schasinglulu */ 191*91f16700Schasinglulu #if RESET_TO_SP_MIN && !JUNO_AARCH32_EL3_RUNTIME 192*91f16700Schasinglulu plat_arm_security_setup(); 193*91f16700Schasinglulu 194*91f16700Schasinglulu #if defined(PLAT_ARM_MEM_PROT_ADDR) 195*91f16700Schasinglulu arm_nor_psci_do_dyn_mem_protect(); 196*91f16700Schasinglulu #endif /* PLAT_ARM_MEM_PROT_ADDR */ 197*91f16700Schasinglulu 198*91f16700Schasinglulu #endif 199*91f16700Schasinglulu 200*91f16700Schasinglulu /* Enable and initialize the System level generic timer */ 201*91f16700Schasinglulu #ifdef ARM_SYS_CNTCTL_BASE 202*91f16700Schasinglulu mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF, 203*91f16700Schasinglulu CNTCR_FCREQ(0U) | CNTCR_EN); 204*91f16700Schasinglulu #endif 205*91f16700Schasinglulu #ifdef ARM_SYS_TIMCTL_BASE 206*91f16700Schasinglulu /* Allow access to the System counter timer module */ 207*91f16700Schasinglulu arm_configure_sys_timer(); 208*91f16700Schasinglulu #endif 209*91f16700Schasinglulu /* Initialize power controller before setting up topology */ 210*91f16700Schasinglulu plat_arm_pwrc_setup(); 211*91f16700Schasinglulu } 212*91f16700Schasinglulu 213*91f16700Schasinglulu void sp_min_plat_runtime_setup(void) 214*91f16700Schasinglulu { 215*91f16700Schasinglulu arm_sp_min_plat_runtime_setup(); 216*91f16700Schasinglulu } 217*91f16700Schasinglulu 218*91f16700Schasinglulu /******************************************************************************* 219*91f16700Schasinglulu * Perform the very early platform specific architectural setup here. At the 220*91f16700Schasinglulu * moment this only initializes the MMU 221*91f16700Schasinglulu ******************************************************************************/ 222*91f16700Schasinglulu void arm_sp_min_plat_arch_setup(void) 223*91f16700Schasinglulu { 224*91f16700Schasinglulu const mmap_region_t bl_regions[] = { 225*91f16700Schasinglulu MAP_BL_SP_MIN_TOTAL, 226*91f16700Schasinglulu ARM_MAP_BL_RO, 227*91f16700Schasinglulu #if USE_COHERENT_MEM 228*91f16700Schasinglulu ARM_MAP_BL_COHERENT_RAM, 229*91f16700Schasinglulu #endif 230*91f16700Schasinglulu {0} 231*91f16700Schasinglulu }; 232*91f16700Schasinglulu 233*91f16700Schasinglulu setup_page_tables(bl_regions, plat_arm_get_mmap()); 234*91f16700Schasinglulu 235*91f16700Schasinglulu enable_mmu_svc_mon(0); 236*91f16700Schasinglulu } 237*91f16700Schasinglulu 238*91f16700Schasinglulu void sp_min_plat_arch_setup(void) 239*91f16700Schasinglulu { 240*91f16700Schasinglulu arm_sp_min_plat_arch_setup(); 241*91f16700Schasinglulu } 242