164f6ea9bSJeenu Viswambharan /* 2*cf48f49fSManish V Badarkhe * Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved. 364f6ea9bSJeenu Viswambharan * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 564f6ea9bSJeenu Viswambharan */ 664f6ea9bSJeenu Viswambharan 758e946aeSSoby Mathew #include <assert.h> 897043ac9SDan Handley #include <stdint.h> 909d40e0eSAntonio Nino Diaz 1009d40e0eSAntonio Nino Diaz #include <common/debug.h> 1109d40e0eSAntonio Nino Diaz #include <common/runtime_svc.h> 1209d40e0eSAntonio Nino Diaz #include <lib/el3_runtime/cpu_data.h> 1309d40e0eSAntonio Nino Diaz #include <lib/pmf/pmf.h> 1409d40e0eSAntonio Nino Diaz #include <lib/psci/psci.h> 1509d40e0eSAntonio Nino Diaz #include <lib/runtime_instr.h> 16e62748e3SManish V Badarkhe #include <services/drtm_svc.h> 17ffea3844SSona Mathew #include <services/errata_abi_svc.h> 18*cf48f49fSManish V Badarkhe #include <services/lfa_svc.h> 191cdf1eb8SJeremy Linton #include <services/pci_svc.h> 2077c27753SZelalem Aweke #include <services/rmmd_svc.h> 2109d40e0eSAntonio Nino Diaz #include <services/sdei.h> 220bf9f567SPaul Beesley #include <services/spm_mm_svc.h> 23bb01a673SMarc Bonnici #include <services/spmc_svc.h> 242a7b403dSAchin Gupta #include <services/spmd_svc.h> 2509d40e0eSAntonio Nino Diaz #include <services/std_svc.h> 267dfb9911SJimmy Brisson #include <services/trng_svc.h> 2709d40e0eSAntonio Nino Diaz #include <smccc_helpers.h> 2809d40e0eSAntonio Nino Diaz #include <tools_share/uuid.h> 2964f6ea9bSJeenu Viswambharan 3064f6ea9bSJeenu Viswambharan /* Standard Service UUID */ 3103364865SRoberto Vargas static uuid_t arm_svc_uid = { 3203364865SRoberto Vargas {0x5b, 0x90, 0x8d, 0x10}, 3303364865SRoberto Vargas {0x63, 0xf8}, 3403364865SRoberto Vargas {0xe8, 0x47}, 3503364865SRoberto Vargas 0xae, 0x2d, 3603364865SRoberto Vargas {0xc0, 0xfb, 0x56, 0x41, 0xf6, 0xe2} 3703364865SRoberto Vargas }; 3864f6ea9bSJeenu Viswambharan 3958e946aeSSoby Mathew /* Setup Standard Services */ 4058e946aeSSoby Mathew static int32_t std_svc_setup(void) 4158e946aeSSoby Mathew { 4258e946aeSSoby Mathew uintptr_t svc_arg; 432fccb228SAntonio Nino Diaz int ret = 0; 4458e946aeSSoby Mathew 4558e946aeSSoby Mathew svc_arg = get_arm_std_svc_args(PSCI_FID_MASK); 4658e946aeSSoby Mathew assert(svc_arg); 4758e946aeSSoby Mathew 4858e946aeSSoby Mathew /* 492fccb228SAntonio Nino Diaz * PSCI is one of the specifications implemented as a Standard Service. 5058e946aeSSoby Mathew * The `psci_setup()` also does EL3 architectural setup. 5158e946aeSSoby Mathew */ 522fccb228SAntonio Nino Diaz if (psci_setup((const psci_lib_args_t *)svc_arg) != PSCI_E_SUCCESS) { 532fccb228SAntonio Nino Diaz ret = 1; 542fccb228SAntonio Nino Diaz } 552fccb228SAntonio Nino Diaz 56538b0020SPaul Beesley #if SPM_MM 570bf9f567SPaul Beesley if (spm_mm_setup() != 0) { 582fccb228SAntonio Nino Diaz ret = 1; 592fccb228SAntonio Nino Diaz } 602fccb228SAntonio Nino Diaz #endif 612fccb228SAntonio Nino Diaz 622a7b403dSAchin Gupta #if defined(SPD_spmd) 632a7b403dSAchin Gupta if (spmd_setup() != 0) { 642a7b403dSAchin Gupta ret = 1; 652a7b403dSAchin Gupta } 662a7b403dSAchin Gupta #endif 672a7b403dSAchin Gupta 68b9fd2d3cSSubhasish Ghosh #if ENABLE_RME 69b9fd2d3cSSubhasish Ghosh if (rmmd_setup() != 0) { 70fdd8a24bSVarun Wadekar WARN("RMMD setup failed. Continuing boot.\n"); 71b9fd2d3cSSubhasish Ghosh } 72b9fd2d3cSSubhasish Ghosh #endif 73b9fd2d3cSSubhasish Ghosh 74b7cb133eSJeenu Viswambharan #if SDEI_SUPPORT 75b7cb133eSJeenu Viswambharan /* SDEI initialisation */ 76b7cb133eSJeenu Viswambharan sdei_init(); 77b7cb133eSJeenu Viswambharan #endif 78b7cb133eSJeenu Viswambharan 790b22e591SJayanth Dodderi Chidanand #if TRNG_SUPPORT 800b22e591SJayanth Dodderi Chidanand /* TRNG initialisation */ 817dfb9911SJimmy Brisson trng_setup(); 820b22e591SJayanth Dodderi Chidanand #endif /* TRNG_SUPPORT */ 837dfb9911SJimmy Brisson 84e62748e3SManish V Badarkhe #if DRTM_SUPPORT 85e62748e3SManish V Badarkhe if (drtm_setup() != 0) { 86e62748e3SManish V Badarkhe ret = 1; 87e62748e3SManish V Badarkhe } 88e62748e3SManish V Badarkhe #endif /* DRTM_SUPPORT */ 89e62748e3SManish V Badarkhe 90*cf48f49fSManish V Badarkhe #if LFA_SUPPORT 91*cf48f49fSManish V Badarkhe /* 92*cf48f49fSManish V Badarkhe * Setup/Initialize resources useful during LFA 93*cf48f49fSManish V Badarkhe */ 94*cf48f49fSManish V Badarkhe if (lfa_setup() != 0) { 95*cf48f49fSManish V Badarkhe ret = 1; 96*cf48f49fSManish V Badarkhe } 97*cf48f49fSManish V Badarkhe #endif /* LFA_SUPPORT */ 98*cf48f49fSManish V Badarkhe 992fccb228SAntonio Nino Diaz return ret; 10058e946aeSSoby Mathew } 10158e946aeSSoby Mathew 10264f6ea9bSJeenu Viswambharan /* 10364f6ea9bSJeenu Viswambharan * Top-level Standard Service SMC handler. This handler will in turn dispatch 10464f6ea9bSJeenu Viswambharan * calls to PSCI SMC handler 10564f6ea9bSJeenu Viswambharan */ 1067fabe1a8SRoberto Vargas static uintptr_t std_svc_smc_handler(uint32_t smc_fid, 1071a0f565bSMaheedhar Bollapalli u_register_t x1_arg, 1081a0f565bSMaheedhar Bollapalli u_register_t x2_arg, 1091a0f565bSMaheedhar Bollapalli u_register_t x3_arg, 1101a0f565bSMaheedhar Bollapalli u_register_t x4_arg, 11164f6ea9bSJeenu Viswambharan void *cookie, 11264f6ea9bSJeenu Viswambharan void *handle, 1134c0d0390SSoby Mathew u_register_t flags) 11464f6ea9bSJeenu Viswambharan { 1151a0f565bSMaheedhar Bollapalli u_register_t x1 = x1_arg; 1161a0f565bSMaheedhar Bollapalli u_register_t x2 = x2_arg; 1171a0f565bSMaheedhar Bollapalli u_register_t x3 = x3_arg; 1181a0f565bSMaheedhar Bollapalli u_register_t x4 = x4_arg; 1191a0f565bSMaheedhar Bollapalli 120475333c8SJeremy Linton if (((smc_fid >> FUNCID_CC_SHIFT) & FUNCID_CC_MASK) == SMC_32) { 121475333c8SJeremy Linton /* 32-bit SMC function, clear top parameter bits */ 122475333c8SJeremy Linton 123475333c8SJeremy Linton x1 &= UINT32_MAX; 124475333c8SJeremy Linton x2 &= UINT32_MAX; 125475333c8SJeremy Linton x3 &= UINT32_MAX; 126475333c8SJeremy Linton x4 &= UINT32_MAX; 127475333c8SJeremy Linton } 128475333c8SJeremy Linton 12964f6ea9bSJeenu Viswambharan /* 13064f6ea9bSJeenu Viswambharan * Dispatch PSCI calls to PSCI SMC handler and return its return 13164f6ea9bSJeenu Viswambharan * value 13264f6ea9bSJeenu Viswambharan */ 13364f6ea9bSJeenu Viswambharan if (is_psci_fid(smc_fid)) { 134872be88aSdp-arm uint64_t ret; 135872be88aSdp-arm 136872be88aSdp-arm #if ENABLE_RUNTIME_INSTRUMENTATION 137bfef6106Sdp-arm 138bfef6106Sdp-arm /* 139bfef6106Sdp-arm * Flush cache line so that even if CPU power down happens 140bfef6106Sdp-arm * the timestamp update is reflected in memory. 141bfef6106Sdp-arm */ 142872be88aSdp-arm PMF_WRITE_TIMESTAMP(rt_instr_svc, 143872be88aSdp-arm RT_INSTR_ENTER_PSCI, 144bfef6106Sdp-arm PMF_CACHE_MAINT, 145872be88aSdp-arm get_cpu_data(cpu_data_pmf_ts[CPU_DATA_PMF_TS0_IDX])); 146872be88aSdp-arm #endif 147872be88aSdp-arm 148872be88aSdp-arm ret = psci_smc_handler(smc_fid, x1, x2, x3, x4, 149872be88aSdp-arm cookie, handle, flags); 150872be88aSdp-arm 151872be88aSdp-arm #if ENABLE_RUNTIME_INSTRUMENTATION 152872be88aSdp-arm PMF_CAPTURE_TIMESTAMP(rt_instr_svc, 153872be88aSdp-arm RT_INSTR_EXIT_PSCI, 154872be88aSdp-arm PMF_NO_CACHE_MAINT); 155872be88aSdp-arm #endif 156872be88aSdp-arm 157872be88aSdp-arm SMC_RET1(handle, ret); 15864f6ea9bSJeenu Viswambharan } 15964f6ea9bSJeenu Viswambharan 1603f3c341aSPaul Beesley #if SPM_MM 1612fccb228SAntonio Nino Diaz /* 1622fccb228SAntonio Nino Diaz * Dispatch SPM calls to SPM SMC handler and return its return 1632fccb228SAntonio Nino Diaz * value 1642fccb228SAntonio Nino Diaz */ 1650bf9f567SPaul Beesley if (is_spm_mm_fid(smc_fid)) { 1660bf9f567SPaul Beesley return spm_mm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, 1672fccb228SAntonio Nino Diaz handle, flags); 1682fccb228SAntonio Nino Diaz } 1692fccb228SAntonio Nino Diaz #endif 1702fccb228SAntonio Nino Diaz 1712a7b403dSAchin Gupta #if defined(SPD_spmd) 1722a7b403dSAchin Gupta /* 173662af36dSJ-Alves * Dispatch FFA calls to the FFA SMC handler implemented by the SPM 1742a7b403dSAchin Gupta * dispatcher and return its return value 1752a7b403dSAchin Gupta */ 176662af36dSJ-Alves if (is_ffa_fid(smc_fid)) { 177bb01a673SMarc Bonnici return spmd_ffa_smc_handler(smc_fid, x1, x2, x3, x4, cookie, 1782a7b403dSAchin Gupta handle, flags); 1792a7b403dSAchin Gupta } 1802a7b403dSAchin Gupta #endif 1812a7b403dSAchin Gupta 182b7cb133eSJeenu Viswambharan #if SDEI_SUPPORT 183b7cb133eSJeenu Viswambharan if (is_sdei_fid(smc_fid)) { 184b7cb133eSJeenu Viswambharan return sdei_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, 185b7cb133eSJeenu Viswambharan flags); 186b7cb133eSJeenu Viswambharan } 187b7cb133eSJeenu Viswambharan #endif 188b7cb133eSJeenu Viswambharan 189323b6c63SAndre Przywara #if TRNG_SUPPORT 1907dfb9911SJimmy Brisson if (is_trng_fid(smc_fid)) { 1917dfb9911SJimmy Brisson return trng_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, 1927dfb9911SJimmy Brisson flags); 1937dfb9911SJimmy Brisson } 1940b22e591SJayanth Dodderi Chidanand #endif /* TRNG_SUPPORT */ 1950b22e591SJayanth Dodderi Chidanand 196ffea3844SSona Mathew #if ERRATA_ABI_SUPPORT 197ffea3844SSona Mathew if (is_errata_fid(smc_fid)) { 198ffea3844SSona Mathew return errata_abi_smc_handler(smc_fid, x1, x2, x3, x4, cookie, 199ffea3844SSona Mathew handle, flags); 200ffea3844SSona Mathew } 201ffea3844SSona Mathew #endif /* ERRATA_ABI_SUPPORT */ 202ffea3844SSona Mathew 20377c27753SZelalem Aweke #if ENABLE_RME 204319fb084SSoby Mathew 205319fb084SSoby Mathew if (is_rmmd_el3_fid(smc_fid)) { 206319fb084SSoby Mathew return rmmd_rmm_el3_handler(smc_fid, x1, x2, x3, x4, cookie, 20777c27753SZelalem Aweke handle, flags); 20877c27753SZelalem Aweke } 209b9fd2d3cSSubhasish Ghosh 210b9fd2d3cSSubhasish Ghosh if (is_rmi_fid(smc_fid)) { 211b9fd2d3cSSubhasish Ghosh return rmmd_rmi_handler(smc_fid, x1, x2, x3, x4, cookie, 212b9fd2d3cSSubhasish Ghosh handle, flags); 213b9fd2d3cSSubhasish Ghosh } 21477c27753SZelalem Aweke #endif 2157dfb9911SJimmy Brisson 2161cdf1eb8SJeremy Linton #if SMC_PCI_SUPPORT 2171cdf1eb8SJeremy Linton if (is_pci_fid(smc_fid)) { 2181cdf1eb8SJeremy Linton return pci_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, 2191cdf1eb8SJeremy Linton flags); 2201cdf1eb8SJeremy Linton } 2211cdf1eb8SJeremy Linton #endif 2221cdf1eb8SJeremy Linton 223e62748e3SManish V Badarkhe #if DRTM_SUPPORT 224e62748e3SManish V Badarkhe if (is_drtm_fid(smc_fid)) { 225e62748e3SManish V Badarkhe return drtm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, 226e62748e3SManish V Badarkhe flags); 227e62748e3SManish V Badarkhe } 228e62748e3SManish V Badarkhe #endif /* DRTM_SUPPORT */ 229e62748e3SManish V Badarkhe 230*cf48f49fSManish V Badarkhe #if LFA_SUPPORT 231*cf48f49fSManish V Badarkhe if (is_lfa_fid(smc_fid)) { 232*cf48f49fSManish V Badarkhe return lfa_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); 233*cf48f49fSManish V Badarkhe } 234*cf48f49fSManish V Badarkhe #endif /* LFA_SUPPORT */ 235*cf48f49fSManish V Badarkhe 236*cf48f49fSManish V Badarkhe 23764f6ea9bSJeenu Viswambharan switch (smc_fid) { 23864f6ea9bSJeenu Viswambharan case ARM_STD_SVC_CALL_COUNT: 23964f6ea9bSJeenu Viswambharan /* 24064f6ea9bSJeenu Viswambharan * Return the number of Standard Service Calls. PSCI is the only 24164f6ea9bSJeenu Viswambharan * standard service implemented; so return number of PSCI calls 24264f6ea9bSJeenu Viswambharan */ 24364f6ea9bSJeenu Viswambharan SMC_RET1(handle, PSCI_NUM_CALLS); 24464f6ea9bSJeenu Viswambharan 24564f6ea9bSJeenu Viswambharan case ARM_STD_SVC_UID: 24664f6ea9bSJeenu Viswambharan /* Return UID to the caller */ 24764f6ea9bSJeenu Viswambharan SMC_UUID_RET(handle, arm_svc_uid); 24864f6ea9bSJeenu Viswambharan 24964f6ea9bSJeenu Viswambharan case ARM_STD_SVC_VERSION: 25064f6ea9bSJeenu Viswambharan /* Return the version of current implementation */ 25164f6ea9bSJeenu Viswambharan SMC_RET2(handle, STD_SVC_VERSION_MAJOR, STD_SVC_VERSION_MINOR); 25264f6ea9bSJeenu Viswambharan 25364f6ea9bSJeenu Viswambharan default: 25467fad514SAndre Przywara VERBOSE("Unimplemented Standard Service Call: 0x%x \n", smc_fid); 25564f6ea9bSJeenu Viswambharan SMC_RET1(handle, SMC_UNK); 25664f6ea9bSJeenu Viswambharan } 25764f6ea9bSJeenu Viswambharan } 25864f6ea9bSJeenu Viswambharan 25964f6ea9bSJeenu Viswambharan /* Register Standard Service Calls as runtime service */ 26064f6ea9bSJeenu Viswambharan DECLARE_RT_SVC( 26164f6ea9bSJeenu Viswambharan std_svc, 26264f6ea9bSJeenu Viswambharan 26364f6ea9bSJeenu Viswambharan OEN_STD_START, 26464f6ea9bSJeenu Viswambharan OEN_STD_END, 26564f6ea9bSJeenu Viswambharan SMC_TYPE_FAST, 26658e946aeSSoby Mathew std_svc_setup, 26764f6ea9bSJeenu Viswambharan std_svc_smc_handler 26864f6ea9bSJeenu Viswambharan ); 269