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