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, 98 u_register_t x2, 99 u_register_t x3, 100 u_register_t x4, 101 void *cookie, 102 void *handle, 103 u_register_t flags) 104 { 105 if (((smc_fid >> FUNCID_CC_SHIFT) & FUNCID_CC_MASK) == SMC_32) { 106 /* 32-bit SMC function, clear top parameter bits */ 107 108 x1 &= UINT32_MAX; 109 x2 &= UINT32_MAX; 110 x3 &= UINT32_MAX; 111 x4 &= UINT32_MAX; 112 } 113 114 /* 115 * Dispatch PSCI calls to PSCI SMC handler and return its return 116 * value 117 */ 118 if (is_psci_fid(smc_fid)) { 119 uint64_t ret; 120 121 #if ENABLE_RUNTIME_INSTRUMENTATION 122 123 /* 124 * Flush cache line so that even if CPU power down happens 125 * the timestamp update is reflected in memory. 126 */ 127 PMF_WRITE_TIMESTAMP(rt_instr_svc, 128 RT_INSTR_ENTER_PSCI, 129 PMF_CACHE_MAINT, 130 get_cpu_data(cpu_data_pmf_ts[CPU_DATA_PMF_TS0_IDX])); 131 #endif 132 133 ret = psci_smc_handler(smc_fid, x1, x2, x3, x4, 134 cookie, handle, flags); 135 136 #if ENABLE_RUNTIME_INSTRUMENTATION 137 PMF_CAPTURE_TIMESTAMP(rt_instr_svc, 138 RT_INSTR_EXIT_PSCI, 139 PMF_NO_CACHE_MAINT); 140 #endif 141 142 SMC_RET1(handle, ret); 143 } 144 145 #if SPM_MM 146 /* 147 * Dispatch SPM calls to SPM SMC handler and return its return 148 * value 149 */ 150 if (is_spm_mm_fid(smc_fid)) { 151 return spm_mm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, 152 handle, flags); 153 } 154 #endif 155 156 #if defined(SPD_spmd) 157 /* 158 * Dispatch FFA calls to the FFA SMC handler implemented by the SPM 159 * dispatcher and return its return value 160 */ 161 if (is_ffa_fid(smc_fid)) { 162 return spmd_ffa_smc_handler(smc_fid, x1, x2, x3, x4, cookie, 163 handle, flags); 164 } 165 #endif 166 167 #if SDEI_SUPPORT 168 if (is_sdei_fid(smc_fid)) { 169 return sdei_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, 170 flags); 171 } 172 #endif 173 174 #if TRNG_SUPPORT 175 if (is_trng_fid(smc_fid)) { 176 return trng_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, 177 flags); 178 } 179 #endif /* TRNG_SUPPORT */ 180 181 #if ERRATA_ABI_SUPPORT 182 if (is_errata_fid(smc_fid)) { 183 return errata_abi_smc_handler(smc_fid, x1, x2, x3, x4, cookie, 184 handle, flags); 185 } 186 #endif /* ERRATA_ABI_SUPPORT */ 187 188 #if ENABLE_RME 189 190 if (is_rmmd_el3_fid(smc_fid)) { 191 return rmmd_rmm_el3_handler(smc_fid, x1, x2, x3, x4, cookie, 192 handle, flags); 193 } 194 195 if (is_rmi_fid(smc_fid)) { 196 return rmmd_rmi_handler(smc_fid, x1, x2, x3, x4, cookie, 197 handle, flags); 198 } 199 #endif 200 201 #if SMC_PCI_SUPPORT 202 if (is_pci_fid(smc_fid)) { 203 return pci_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, 204 flags); 205 } 206 #endif 207 208 #if DRTM_SUPPORT 209 if (is_drtm_fid(smc_fid)) { 210 return drtm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, 211 flags); 212 } 213 #endif /* DRTM_SUPPORT */ 214 215 switch (smc_fid) { 216 case ARM_STD_SVC_CALL_COUNT: 217 /* 218 * Return the number of Standard Service Calls. PSCI is the only 219 * standard service implemented; so return number of PSCI calls 220 */ 221 SMC_RET1(handle, PSCI_NUM_CALLS); 222 223 case ARM_STD_SVC_UID: 224 /* Return UID to the caller */ 225 SMC_UUID_RET(handle, arm_svc_uid); 226 227 case ARM_STD_SVC_VERSION: 228 /* Return the version of current implementation */ 229 SMC_RET2(handle, STD_SVC_VERSION_MAJOR, STD_SVC_VERSION_MINOR); 230 231 default: 232 VERBOSE("Unimplemented Standard Service Call: 0x%x \n", smc_fid); 233 SMC_RET1(handle, SMC_UNK); 234 } 235 } 236 237 /* Register Standard Service Calls as runtime service */ 238 DECLARE_RT_SVC( 239 std_svc, 240 241 OEN_STD_START, 242 OEN_STD_END, 243 SMC_TYPE_FAST, 244 std_svc_setup, 245 std_svc_smc_handler 246 ); 247