1 /* 2 * Copyright (c) 2014-2026, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <stdint.h> 9 10 #include <arch_features.h> 11 #include <common/debug.h> 12 #include <common/runtime_svc.h> 13 #include <lib/el3_runtime/cpu_data.h> 14 #include <lib/pmf/pmf.h> 15 #include <lib/psci/psci.h> 16 #include <lib/runtime_instr.h> 17 #include <services/drtm_svc.h> 18 #include <services/errata_abi_svc.h> 19 #include <services/firme_svc.h> 20 #include <services/lfa_svc.h> 21 #include <services/pci_svc.h> 22 #include <services/rmmd_svc.h> 23 #include <services/sdei.h> 24 #include <services/spm_mm_svc.h> 25 #include <services/spmc_svc.h> 26 #include <services/spmd_svc.h> 27 #include <services/std_svc.h> 28 #include <services/trng_svc.h> 29 #include <smccc_helpers.h> 30 #include <tools_share/uuid.h> 31 32 /* Standard Service UUID */ 33 static uuid_t arm_svc_uid = { 34 {0x5b, 0x90, 0x8d, 0x10}, 35 {0x63, 0xf8}, 36 {0xe8, 0x47}, 37 0xae, 0x2d, 38 {0xc0, 0xfb, 0x56, 0x41, 0xf6, 0xe2} 39 }; 40 41 /* Setup Standard Services */ 42 static int32_t std_svc_setup(void) 43 { 44 uintptr_t svc_arg; 45 int ret = 0; 46 47 svc_arg = get_arm_std_svc_args(PSCI_FID_MASK); 48 assert(svc_arg); 49 50 /* 51 * PSCI is one of the specifications implemented as a Standard Service. 52 * The `psci_setup()` also does EL3 architectural setup. 53 */ 54 if (psci_setup((const psci_lib_args_t *)svc_arg) != PSCI_E_SUCCESS) { 55 ret = 1; 56 } 57 58 #if SPM_MM 59 if (spm_mm_setup() != 0) { 60 ret = 1; 61 } 62 #endif 63 64 #if defined(SPD_spmd) 65 if (spmd_setup() != 0) { 66 ret = 1; 67 } 68 #endif 69 70 #if ENABLE_RMM 71 if (is_feat_rme_supported() && (rmmd_setup() != 0)) { 72 WARN("RMMD setup failed. Continuing boot.\n"); 73 } 74 #endif 75 76 #if SDEI_SUPPORT 77 /* SDEI initialisation */ 78 sdei_init(); 79 #endif 80 81 #if TRNG_SUPPORT 82 /* TRNG initialisation */ 83 trng_setup(); 84 #endif /* TRNG_SUPPORT */ 85 86 #if DRTM_SUPPORT 87 if (drtm_setup() != 0) { 88 ret = 1; 89 } 90 #endif /* DRTM_SUPPORT */ 91 92 #if LFA_SUPPORT 93 /* 94 * Setup/Initialize resources useful during LFA 95 */ 96 if (lfa_setup() != 0) { 97 ret = 1; 98 } 99 #endif /* LFA_SUPPORT */ 100 101 return ret; 102 } 103 104 /* 105 * Top-level Standard Service SMC handler. This handler will in turn dispatch 106 * calls to PSCI SMC handler 107 */ 108 static uintptr_t std_svc_smc_handler(uint32_t smc_fid, 109 u_register_t x1_arg, 110 u_register_t x2_arg, 111 u_register_t x3_arg, 112 u_register_t x4_arg, 113 void *cookie, 114 void *handle, 115 u_register_t flags) 116 { 117 u_register_t x1 = x1_arg; 118 u_register_t x2 = x2_arg; 119 u_register_t x3 = x3_arg; 120 u_register_t x4 = x4_arg; 121 122 if (((smc_fid >> FUNCID_CC_SHIFT) & FUNCID_CC_MASK) == SMC_32) { 123 /* 32-bit SMC function, clear top parameter bits */ 124 125 x1 &= UINT32_MAX; 126 x2 &= UINT32_MAX; 127 x3 &= UINT32_MAX; 128 x4 &= UINT32_MAX; 129 } 130 131 /* 132 * Dispatch PSCI calls to PSCI SMC handler and return its return 133 * value 134 */ 135 if (is_psci_fid(smc_fid)) { 136 uint64_t ret; 137 138 #if ENABLE_RUNTIME_INSTRUMENTATION 139 140 /* 141 * Flush cache line so that even if CPU power down happens 142 * the timestamp update is reflected in memory. 143 */ 144 PMF_WRITE_TIMESTAMP(rt_instr_svc, 145 RT_INSTR_ENTER_PSCI, 146 PMF_CACHE_MAINT, 147 get_cpu_data(cpu_data_pmf_ts[CPU_DATA_PMF_TS0_IDX])); 148 #endif 149 150 ret = psci_smc_handler(smc_fid, x1, x2, x3, x4, 151 cookie, handle, flags); 152 153 #if ENABLE_RUNTIME_INSTRUMENTATION 154 PMF_CAPTURE_TIMESTAMP(rt_instr_svc, 155 RT_INSTR_EXIT_PSCI, 156 PMF_NO_CACHE_MAINT); 157 #endif 158 159 SMC_RET1(handle, ret); 160 } 161 162 #if SPM_MM 163 /* 164 * Dispatch SPM calls to SPM SMC handler and return its return 165 * value 166 */ 167 if (is_spm_mm_fid(smc_fid)) { 168 return spm_mm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, 169 handle, flags); 170 } 171 #endif 172 173 #if defined(SPD_spmd) 174 /* 175 * Dispatch FFA calls to the FFA SMC handler implemented by the SPM 176 * dispatcher and return its return value 177 */ 178 if (is_ffa_fid(smc_fid)) { 179 return spmd_ffa_smc_handler(smc_fid, x1, x2, x3, x4, cookie, 180 handle, flags); 181 } 182 #endif 183 184 #if SDEI_SUPPORT 185 if (is_sdei_fid(smc_fid)) { 186 return sdei_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, 187 flags); 188 } 189 #endif 190 191 #if TRNG_SUPPORT 192 if (is_trng_fid(smc_fid)) { 193 return trng_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, 194 flags); 195 } 196 #endif /* TRNG_SUPPORT */ 197 198 #if ERRATA_ABI_SUPPORT 199 if (is_errata_fid(smc_fid)) { 200 return errata_abi_smc_handler(smc_fid, x1, x2, x3, x4, cookie, 201 handle, flags); 202 } 203 #endif /* ERRATA_ABI_SUPPORT */ 204 205 #if ENABLE_RMM 206 207 if (is_rmmd_el3_fid(smc_fid)) { 208 return rmmd_rmm_el3_handler(smc_fid, x1, x2, x3, x4, cookie, 209 handle, flags); 210 } 211 212 if (is_rmi_fid(smc_fid)) { 213 return rmmd_rmi_handler(smc_fid, x1, x2, x3, x4, cookie, 214 handle, flags); 215 } 216 #endif 217 218 #if FIRME_SUPPORT 219 if (is_firme_fid(smc_fid)) { 220 return firme_handler(smc_fid, x1, x2, x3, x4, cookie, handle, 221 flags); 222 } 223 #endif 224 225 #if SMC_PCI_SUPPORT 226 if (is_pci_fid(smc_fid)) { 227 return pci_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, 228 flags); 229 } 230 #endif 231 232 #if DRTM_SUPPORT 233 if (is_drtm_fid(smc_fid)) { 234 return drtm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, 235 flags); 236 } 237 #endif /* DRTM_SUPPORT */ 238 239 #if LFA_SUPPORT 240 if (is_lfa_fid(smc_fid)) { 241 return lfa_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); 242 } 243 #endif /* LFA_SUPPORT */ 244 245 246 switch (smc_fid) { 247 case ARM_STD_SVC_CALL_COUNT: 248 /* 249 * Return the number of Standard Service Calls. PSCI is the only 250 * standard service implemented; so return number of PSCI calls 251 */ 252 SMC_RET1(handle, PSCI_NUM_CALLS); 253 254 case ARM_STD_SVC_UID: 255 /* Return UID to the caller */ 256 SMC_UUID_RET(handle, arm_svc_uid); 257 258 case ARM_STD_SVC_VERSION: 259 /* Return the version of current implementation */ 260 SMC_RET2(handle, STD_SVC_VERSION_MAJOR, STD_SVC_VERSION_MINOR); 261 262 default: 263 VERBOSE("Unimplemented Standard Service Call: 0x%x \n", smc_fid); 264 SMC_RET1(handle, SMC_UNK); 265 } 266 } 267 268 /* Register Standard Service Calls as runtime service */ 269 DECLARE_RT_SVC( 270 std_svc, 271 272 OEN_STD_START, 273 OEN_STD_END, 274 SMC_TYPE_FAST, 275 std_svc_setup, 276 std_svc_smc_handler 277 ); 278