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