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