1 /* 2 * Copyright (c) 2018-2024, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 9 #include <platform_def.h> 10 11 #include <arch.h> 12 #include <arch_helpers.h> 13 #include <common/bl_common.h> 14 #include <common/debug.h> 15 #include <drivers/arm/pl011.h> 16 #include <lib/mmio.h> 17 #include <sq_common.h> 18 19 static console_t console; 20 static entry_point_info_t bl32_image_ep_info; 21 static entry_point_info_t bl33_image_ep_info; 22 23 IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_START__, SPM_SHIM_EXCEPTIONS_START); 24 IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_END__, SPM_SHIM_EXCEPTIONS_END); 25 IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_LMA__, SPM_SHIM_EXCEPTIONS_LMA); 26 27 unsigned int plat_get_syscnt_freq2(void) 28 { 29 unsigned int counter_base_frequency; 30 31 /* Read the frequency from Frequency modes table */ 32 counter_base_frequency = mmio_read_32(SQ_SYS_CNTCTL_BASE + CNTFID_OFF); 33 34 /* The first entry of the frequency modes table must not be 0 */ 35 if (counter_base_frequency == 0) 36 panic(); 37 38 return counter_base_frequency; 39 } 40 41 entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) 42 { 43 assert(sec_state_is_valid(type)); 44 return type == NON_SECURE ? &bl33_image_ep_info : &bl32_image_ep_info; 45 } 46 47 #if !RESET_TO_BL31 48 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, 49 u_register_t arg2, u_register_t arg3) 50 { 51 void *from_bl2 = (void *) arg0; 52 bl_params_node_t *bl_params = ((bl_params_t *) from_bl2)->head; 53 54 /* Initialize the console to provide early debug support */ 55 (void)console_pl011_register(PLAT_SQ_BOOT_UART_BASE, 56 PLAT_SQ_BOOT_UART_CLK_IN_HZ, 57 SQ_CONSOLE_BAUDRATE, &console); 58 59 console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); 60 61 /* Initialize power controller before setting up topology */ 62 plat_sq_pwrc_setup(); 63 64 while (bl_params) { 65 if (bl_params->image_id == BL32_IMAGE_ID) 66 bl32_image_ep_info = *bl_params->ep_info; 67 68 if (bl_params->image_id == BL33_IMAGE_ID) 69 bl33_image_ep_info = *bl_params->ep_info; 70 71 bl_params = bl_params->next_params_info; 72 } 73 } 74 75 #else 76 /******************************************************************************* 77 * Gets SPSR for BL32 entry 78 ******************************************************************************/ 79 uint32_t sq_get_spsr_for_bl32_entry(void) 80 { 81 /* 82 * The Secure Payload Dispatcher service is responsible for 83 * setting the SPSR prior to entry into the BL32 image. 84 */ 85 return 0; 86 } 87 88 /******************************************************************************* 89 * Gets SPSR for BL33 entry 90 ******************************************************************************/ 91 uint32_t sq_get_spsr_for_bl33_entry(void) 92 { 93 unsigned long el_status; 94 unsigned int mode; 95 uint32_t spsr; 96 97 /* Figure out what mode we enter the non-secure world in */ 98 el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; 99 el_status &= ID_AA64PFR0_ELX_MASK; 100 101 mode = (el_status) ? MODE_EL2 : MODE_EL1; 102 103 spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); 104 return spsr; 105 } 106 107 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, 108 u_register_t arg2, u_register_t arg3) 109 { 110 /* Initialize the console to provide early debug support */ 111 (void)console_pl011_register(PLAT_SQ_BOOT_UART_BASE, 112 PLAT_SQ_BOOT_UART_CLK_IN_HZ, 113 SQ_CONSOLE_BAUDRATE, &console); 114 115 console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); 116 117 /* There are no parameters from BL2 if BL31 is a reset vector */ 118 assert(arg0 == 0U); 119 assert(arg1 == 0U); 120 121 /* Initialize power controller before setting up topology */ 122 plat_sq_pwrc_setup(); 123 124 #ifdef SPD_opteed 125 struct draminfo di = {0}; 126 127 sq_scp_get_draminfo(&di); 128 129 /* 130 * Check if OP-TEE has been loaded in Secure RAM allocated 131 * from DRAM1 region 132 */ 133 if ((di.base1 + di.size1) <= BL32_BASE) { 134 NOTICE("OP-TEE has been loaded by SCP firmware\n"); 135 /* Populate entry point information for BL32 */ 136 SET_PARAM_HEAD(&bl32_image_ep_info, 137 PARAM_EP, 138 VERSION_1, 139 0); 140 SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); 141 bl32_image_ep_info.pc = BL32_BASE; 142 bl32_image_ep_info.spsr = sq_get_spsr_for_bl32_entry(); 143 } else { 144 NOTICE("OP-TEE has not been loaded by SCP firmware\n"); 145 } 146 #endif /* SPD_opteed */ 147 148 /* Populate entry point information for BL33 */ 149 SET_PARAM_HEAD(&bl33_image_ep_info, 150 PARAM_EP, 151 VERSION_1, 152 0); 153 /* 154 * Tell BL31 where the non-trusted software image 155 * is located and the entry state information 156 */ 157 bl33_image_ep_info.pc = PRELOADED_BL33_BASE; 158 bl33_image_ep_info.spsr = sq_get_spsr_for_bl33_entry(); 159 SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); 160 } 161 #endif 162 163 static void sq_configure_sys_timer(void) 164 { 165 unsigned int reg_val; 166 unsigned int freq_val = plat_get_syscnt_freq2(); 167 168 reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT); 169 reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT); 170 reg_val |= (1 << CNTACR_RWVT_SHIFT) | (1 << CNTACR_RWPT_SHIFT); 171 mmio_write_32(SQ_SYS_TIMCTL_BASE + 172 CNTACR_BASE(PLAT_SQ_NSTIMER_FRAME_ID), reg_val); 173 174 reg_val = (1 << CNTNSAR_NS_SHIFT(PLAT_SQ_NSTIMER_FRAME_ID)); 175 mmio_write_32(SQ_SYS_TIMCTL_BASE + CNTNSAR, reg_val); 176 177 /* Initialize CNTFRQ register in CNTCTLBase frame */ 178 mmio_write_32(SQ_SYS_TIMCTL_BASE + CNTCTLBASE_CNTFRQ, freq_val); 179 180 /* 181 * Initialize CNTFRQ register in Non-secure CNTBase frame. 182 * This is required for SynQuacer, because it does not 183 * follow ARM ARM in that the value updated in CNTFRQ is not 184 * reflected in CNTBASEN_CNTFRQ. Hence update the value manually. 185 */ 186 mmio_write_32(SQ_SYS_CNT_BASE_NS + CNTBASEN_CNTFRQ, freq_val); 187 } 188 189 void bl31_platform_setup(void) 190 { 191 /* Initialize the CCN interconnect */ 192 plat_sq_interconnect_init(); 193 plat_sq_interconnect_enter_coherency(); 194 195 /* Initialize the GIC driver, cpu and distributor interfaces */ 196 sq_gic_driver_init(); 197 sq_gic_init(); 198 199 /* Enable and initialize the System level generic timer */ 200 mmio_write_32(SQ_SYS_CNTCTL_BASE + CNTCR_OFF, 201 CNTCR_FCREQ(0U) | CNTCR_EN); 202 203 /* Allow access to the System counter timer module */ 204 sq_configure_sys_timer(); 205 } 206 207 void bl31_plat_runtime_setup(void) 208 { 209 struct draminfo *di = (struct draminfo *)(unsigned long)DRAMINFO_BASE; 210 211 sq_scp_get_draminfo(di); 212 } 213 214 void bl31_plat_arch_setup(void) 215 { 216 static const mmap_region_t secure_partition_mmap[] = { 217 #if SPM_MM 218 MAP_REGION_FLAT(PLAT_SPM_BUF_BASE, 219 PLAT_SPM_BUF_SIZE, 220 MT_RW_DATA | MT_SECURE), 221 MAP_REGION_FLAT(PLAT_SQ_SP_PRIV_BASE, 222 PLAT_SQ_SP_PRIV_SIZE, 223 MT_RW_DATA | MT_SECURE), 224 #endif 225 #if !RESET_TO_BL31 226 MAP_REGION_FLAT(BL2_MAILBOX_BASE, 227 BL2_MAILBOX_SIZE, 228 MT_RW | MT_SECURE), 229 #endif 230 {0}, 231 }; 232 233 sq_mmap_setup(BL31_BASE, BL31_SIZE, secure_partition_mmap); 234 enable_mmu_el3(XLAT_TABLE_NC); 235 236 #if SPM_MM 237 memcpy((void *)SPM_SHIM_EXCEPTIONS_START, 238 (void *)SPM_SHIM_EXCEPTIONS_LMA, 239 (uintptr_t)SPM_SHIM_EXCEPTIONS_END - 240 (uintptr_t)SPM_SHIM_EXCEPTIONS_START); 241 #endif 242 } 243 244 void bl31_plat_enable_mmu(uint32_t flags) 245 { 246 enable_mmu_el3(flags | XLAT_TABLE_NC); 247 } 248