1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <stdint.h> 8*91f16700Schasinglulu 9*91f16700Schasinglulu #include <common/debug.h> 10*91f16700Schasinglulu #include <common/runtime_svc.h> 11*91f16700Schasinglulu #include <drivers/arm/ethosn.h> 12*91f16700Schasinglulu #include <lib/debugfs.h> 13*91f16700Schasinglulu #include <lib/pmf/pmf.h> 14*91f16700Schasinglulu #include <plat/arm/common/arm_sip_svc.h> 15*91f16700Schasinglulu #include <plat/arm/common/plat_arm.h> 16*91f16700Schasinglulu #include <tools_share/uuid.h> 17*91f16700Schasinglulu 18*91f16700Schasinglulu /* ARM SiP Service UUID */ 19*91f16700Schasinglulu DEFINE_SVC_UUID2(arm_sip_svc_uid, 20*91f16700Schasinglulu 0x556d75e2, 0x6033, 0xb54b, 0xb5, 0x75, 21*91f16700Schasinglulu 0x62, 0x79, 0xfd, 0x11, 0x37, 0xff); 22*91f16700Schasinglulu 23*91f16700Schasinglulu static int arm_sip_setup(void) 24*91f16700Schasinglulu { 25*91f16700Schasinglulu if (pmf_setup() != 0) { 26*91f16700Schasinglulu return 1; 27*91f16700Schasinglulu } 28*91f16700Schasinglulu 29*91f16700Schasinglulu #if USE_DEBUGFS 30*91f16700Schasinglulu 31*91f16700Schasinglulu if (debugfs_smc_setup() != 0) { 32*91f16700Schasinglulu return 1; 33*91f16700Schasinglulu } 34*91f16700Schasinglulu 35*91f16700Schasinglulu #endif /* USE_DEBUGFS */ 36*91f16700Schasinglulu 37*91f16700Schasinglulu #if ETHOSN_NPU_DRIVER 38*91f16700Schasinglulu 39*91f16700Schasinglulu if (ethosn_smc_setup() != 0) { 40*91f16700Schasinglulu return 1; 41*91f16700Schasinglulu } 42*91f16700Schasinglulu 43*91f16700Schasinglulu #endif /* ETHOSN_NPU_DRIVER */ 44*91f16700Schasinglulu 45*91f16700Schasinglulu return 0; 46*91f16700Schasinglulu } 47*91f16700Schasinglulu 48*91f16700Schasinglulu /* 49*91f16700Schasinglulu * This function handles ARM defined SiP Calls 50*91f16700Schasinglulu */ 51*91f16700Schasinglulu static uintptr_t arm_sip_handler(unsigned int smc_fid, 52*91f16700Schasinglulu u_register_t x1, 53*91f16700Schasinglulu u_register_t x2, 54*91f16700Schasinglulu u_register_t x3, 55*91f16700Schasinglulu u_register_t x4, 56*91f16700Schasinglulu void *cookie, 57*91f16700Schasinglulu void *handle, 58*91f16700Schasinglulu u_register_t flags) 59*91f16700Schasinglulu { 60*91f16700Schasinglulu int call_count = 0; 61*91f16700Schasinglulu 62*91f16700Schasinglulu #if ENABLE_PMF 63*91f16700Schasinglulu 64*91f16700Schasinglulu /* 65*91f16700Schasinglulu * Dispatch PMF calls to PMF SMC handler and return its return 66*91f16700Schasinglulu * value 67*91f16700Schasinglulu */ 68*91f16700Schasinglulu if (is_pmf_fid(smc_fid)) { 69*91f16700Schasinglulu return pmf_smc_handler(smc_fid, x1, x2, x3, x4, cookie, 70*91f16700Schasinglulu handle, flags); 71*91f16700Schasinglulu } 72*91f16700Schasinglulu 73*91f16700Schasinglulu #endif /* ENABLE_PMF */ 74*91f16700Schasinglulu 75*91f16700Schasinglulu #if USE_DEBUGFS 76*91f16700Schasinglulu 77*91f16700Schasinglulu if (is_debugfs_fid(smc_fid)) { 78*91f16700Schasinglulu return debugfs_smc_handler(smc_fid, x1, x2, x3, x4, cookie, 79*91f16700Schasinglulu handle, flags); 80*91f16700Schasinglulu } 81*91f16700Schasinglulu 82*91f16700Schasinglulu #endif /* USE_DEBUGFS */ 83*91f16700Schasinglulu 84*91f16700Schasinglulu #if ETHOSN_NPU_DRIVER 85*91f16700Schasinglulu 86*91f16700Schasinglulu if (is_ethosn_fid(smc_fid)) { 87*91f16700Schasinglulu return ethosn_smc_handler(smc_fid, x1, x2, x3, x4, cookie, 88*91f16700Schasinglulu handle, flags); 89*91f16700Schasinglulu } 90*91f16700Schasinglulu 91*91f16700Schasinglulu #endif /* ETHOSN_NPU_DRIVER */ 92*91f16700Schasinglulu 93*91f16700Schasinglulu switch (smc_fid) { 94*91f16700Schasinglulu case ARM_SIP_SVC_EXE_STATE_SWITCH: { 95*91f16700Schasinglulu /* Execution state can be switched only if EL3 is AArch64 */ 96*91f16700Schasinglulu #ifdef __aarch64__ 97*91f16700Schasinglulu /* Allow calls from non-secure only */ 98*91f16700Schasinglulu if (!is_caller_non_secure(flags)) 99*91f16700Schasinglulu SMC_RET1(handle, STATE_SW_E_DENIED); 100*91f16700Schasinglulu 101*91f16700Schasinglulu /* 102*91f16700Schasinglulu * Pointers used in execution state switch are all 32 bits wide 103*91f16700Schasinglulu */ 104*91f16700Schasinglulu return (uintptr_t) arm_execution_state_switch(smc_fid, 105*91f16700Schasinglulu (uint32_t) x1, (uint32_t) x2, (uint32_t) x3, 106*91f16700Schasinglulu (uint32_t) x4, handle); 107*91f16700Schasinglulu #else 108*91f16700Schasinglulu /* State switch denied */ 109*91f16700Schasinglulu SMC_RET1(handle, STATE_SW_E_DENIED); 110*91f16700Schasinglulu #endif /* __aarch64__ */ 111*91f16700Schasinglulu } 112*91f16700Schasinglulu 113*91f16700Schasinglulu case ARM_SIP_SVC_CALL_COUNT: 114*91f16700Schasinglulu /* PMF calls */ 115*91f16700Schasinglulu call_count += PMF_NUM_SMC_CALLS; 116*91f16700Schasinglulu 117*91f16700Schasinglulu #if ETHOSN_NPU_DRIVER 118*91f16700Schasinglulu /* ETHOSN calls */ 119*91f16700Schasinglulu call_count += ETHOSN_NUM_SMC_CALLS; 120*91f16700Schasinglulu #endif /* ETHOSN_NPU_DRIVER */ 121*91f16700Schasinglulu 122*91f16700Schasinglulu /* State switch call */ 123*91f16700Schasinglulu call_count += 1; 124*91f16700Schasinglulu 125*91f16700Schasinglulu SMC_RET1(handle, call_count); 126*91f16700Schasinglulu 127*91f16700Schasinglulu case ARM_SIP_SVC_UID: 128*91f16700Schasinglulu /* Return UID to the caller */ 129*91f16700Schasinglulu SMC_UUID_RET(handle, arm_sip_svc_uid); 130*91f16700Schasinglulu 131*91f16700Schasinglulu case ARM_SIP_SVC_VERSION: 132*91f16700Schasinglulu /* Return the version of current implementation */ 133*91f16700Schasinglulu SMC_RET2(handle, ARM_SIP_SVC_VERSION_MAJOR, ARM_SIP_SVC_VERSION_MINOR); 134*91f16700Schasinglulu 135*91f16700Schasinglulu default: 136*91f16700Schasinglulu break; 137*91f16700Schasinglulu } 138*91f16700Schasinglulu 139*91f16700Schasinglulu /* 140*91f16700Schasinglulu * Fall back to allow Arm platform specific handler. 141*91f16700Schasinglulu * TODO: Refactor needed to move out generic handlers from this file and 142*91f16700Schasinglulu * only keep Arm Platform specific handlers here. 143*91f16700Schasinglulu */ 144*91f16700Schasinglulu return plat_arm_sip_handler(smc_fid, x1, x2, x3, x4, 145*91f16700Schasinglulu cookie, handle, flags); 146*91f16700Schasinglulu } 147*91f16700Schasinglulu 148*91f16700Schasinglulu 149*91f16700Schasinglulu /* Define a runtime service descriptor for fast SMC calls */ 150*91f16700Schasinglulu DECLARE_RT_SVC( 151*91f16700Schasinglulu arm_sip_svc, 152*91f16700Schasinglulu OEN_SIP_START, 153*91f16700Schasinglulu OEN_SIP_END, 154*91f16700Schasinglulu SMC_TYPE_FAST, 155*91f16700Schasinglulu arm_sip_setup, 156*91f16700Schasinglulu arm_sip_handler 157*91f16700Schasinglulu ); 158