1 /* 2 * Copyright (c) 2015-2018, 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/debug.h> 14 #include <common/romlib.h> 15 #include <lib/mmio.h> 16 #include <lib/xlat_tables/xlat_tables_compat.h> 17 #include <plat/arm/common/plat_arm.h> 18 #include <plat/common/platform.h> 19 #include <services/secure_partition.h> 20 21 /* Weak definitions may be overridden in specific ARM standard platform */ 22 #pragma weak plat_get_ns_image_entrypoint 23 #pragma weak plat_arm_get_mmap 24 25 /* Conditionally provide a weak definition of plat_get_syscnt_freq2 to avoid 26 * conflicts with the definition in plat/common. */ 27 #pragma weak plat_get_syscnt_freq2 28 29 30 void arm_setup_romlib(void) 31 { 32 #if USE_ROMLIB 33 if (!rom_lib_init(ROMLIB_VERSION)) 34 panic(); 35 #endif 36 } 37 38 uintptr_t plat_get_ns_image_entrypoint(void) 39 { 40 #ifdef PRELOADED_BL33_BASE 41 return PRELOADED_BL33_BASE; 42 #else 43 return PLAT_ARM_NS_IMAGE_BASE; 44 #endif 45 } 46 47 /******************************************************************************* 48 * Gets SPSR for BL32 entry 49 ******************************************************************************/ 50 uint32_t arm_get_spsr_for_bl32_entry(void) 51 { 52 /* 53 * The Secure Payload Dispatcher service is responsible for 54 * setting the SPSR prior to entry into the BL32 image. 55 */ 56 return 0; 57 } 58 59 /******************************************************************************* 60 * Gets SPSR for BL33 entry 61 ******************************************************************************/ 62 #ifndef AARCH32 63 uint32_t arm_get_spsr_for_bl33_entry(void) 64 { 65 unsigned int mode; 66 uint32_t spsr; 67 68 /* Figure out what mode we enter the non-secure world in */ 69 mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1; 70 71 /* 72 * TODO: Consider the possibility of specifying the SPSR in 73 * the FIP ToC and allowing the platform to have a say as 74 * well. 75 */ 76 spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); 77 return spsr; 78 } 79 #else 80 /******************************************************************************* 81 * Gets SPSR for BL33 entry 82 ******************************************************************************/ 83 uint32_t arm_get_spsr_for_bl33_entry(void) 84 { 85 unsigned int hyp_status, mode, spsr; 86 87 hyp_status = GET_VIRT_EXT(read_id_pfr1()); 88 89 mode = (hyp_status) ? MODE32_hyp : MODE32_svc; 90 91 /* 92 * TODO: Consider the possibility of specifying the SPSR in 93 * the FIP ToC and allowing the platform to have a say as 94 * well. 95 */ 96 spsr = SPSR_MODE32(mode, plat_get_ns_image_entrypoint() & 0x1, 97 SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS); 98 return spsr; 99 } 100 #endif /* AARCH32 */ 101 102 /******************************************************************************* 103 * Configures access to the system counter timer module. 104 ******************************************************************************/ 105 #ifdef ARM_SYS_TIMCTL_BASE 106 void arm_configure_sys_timer(void) 107 { 108 unsigned int reg_val; 109 110 /* Read the frequency of the system counter */ 111 unsigned int freq_val = plat_get_syscnt_freq2(); 112 113 #if ARM_CONFIG_CNTACR 114 reg_val = (1U << CNTACR_RPCT_SHIFT) | (1U << CNTACR_RVCT_SHIFT); 115 reg_val |= (1U << CNTACR_RFRQ_SHIFT) | (1U << CNTACR_RVOFF_SHIFT); 116 reg_val |= (1U << CNTACR_RWVT_SHIFT) | (1U << CNTACR_RWPT_SHIFT); 117 mmio_write_32(ARM_SYS_TIMCTL_BASE + CNTACR_BASE(PLAT_ARM_NSTIMER_FRAME_ID), reg_val); 118 #endif /* ARM_CONFIG_CNTACR */ 119 120 reg_val = (1U << CNTNSAR_NS_SHIFT(PLAT_ARM_NSTIMER_FRAME_ID)); 121 mmio_write_32(ARM_SYS_TIMCTL_BASE + CNTNSAR, reg_val); 122 123 /* 124 * Initialize CNTFRQ register in CNTCTLBase frame. The CNTFRQ 125 * system register initialized during psci_arch_setup() is different 126 * from this and has to be updated independently. 127 */ 128 mmio_write_32(ARM_SYS_TIMCTL_BASE + CNTCTLBASE_CNTFRQ, freq_val); 129 130 #ifdef PLAT_juno 131 /* 132 * Initialize CNTFRQ register in Non-secure CNTBase frame. 133 * This is only required for Juno, because it doesn't follow ARM ARM 134 * in that the value updated in CNTFRQ is not reflected in 135 * CNTBASEN_CNTFRQ. Hence update the value manually. 136 */ 137 mmio_write_32(ARM_SYS_CNT_BASE_NS + CNTBASEN_CNTFRQ, freq_val); 138 #endif 139 } 140 #endif /* ARM_SYS_TIMCTL_BASE */ 141 142 /******************************************************************************* 143 * Returns ARM platform specific memory map regions. 144 ******************************************************************************/ 145 const mmap_region_t *plat_arm_get_mmap(void) 146 { 147 return plat_arm_mmap; 148 } 149 150 #ifdef ARM_SYS_CNTCTL_BASE 151 152 unsigned int plat_get_syscnt_freq2(void) 153 { 154 unsigned int counter_base_frequency; 155 156 /* Read the frequency from Frequency modes table */ 157 counter_base_frequency = mmio_read_32(ARM_SYS_CNTCTL_BASE + CNTFID_OFF); 158 159 /* The first entry of the frequency modes table must not be 0 */ 160 if (counter_base_frequency == 0U) 161 panic(); 162 163 return counter_base_frequency; 164 } 165 166 #endif /* ARM_SYS_CNTCTL_BASE */ 167 168 #if SDEI_SUPPORT 169 /* 170 * Translate SDEI entry point to PA, and perform standard ARM entry point 171 * validation on it. 172 */ 173 int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) 174 { 175 uint64_t par, pa; 176 uint32_t scr_el3; 177 178 /* Doing Non-secure address translation requires SCR_EL3.NS set */ 179 scr_el3 = read_scr_el3(); 180 write_scr_el3(scr_el3 | SCR_NS_BIT); 181 isb(); 182 183 assert((client_mode == MODE_EL2) || (client_mode == MODE_EL1)); 184 if (client_mode == MODE_EL2) { 185 /* 186 * Translate entry point to Physical Address using the EL2 187 * translation regime. 188 */ 189 ats1e2r(ep); 190 } else { 191 /* 192 * Translate entry point to Physical Address using the EL1&0 193 * translation regime, including stage 2. 194 */ 195 ats12e1r(ep); 196 } 197 isb(); 198 par = read_par_el1(); 199 200 /* Restore original SCRL_EL3 */ 201 write_scr_el3(scr_el3); 202 isb(); 203 204 /* If the translation resulted in fault, return failure */ 205 if ((par & PAR_F_MASK) != 0) 206 return -1; 207 208 /* Extract Physical Address from PAR */ 209 pa = (par & (PAR_ADDR_MASK << PAR_ADDR_SHIFT)); 210 211 /* Perform NS entry point validation on the physical address */ 212 return arm_validate_ns_entrypoint(pa); 213 } 214 #endif 215