1*f10796a0Sdp-arm /* 2*f10796a0Sdp-arm * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3*f10796a0Sdp-arm * 4*f10796a0Sdp-arm * Redistribution and use in source and binary forms, with or without 5*f10796a0Sdp-arm * modification, are permitted provided that the following conditions are met: 6*f10796a0Sdp-arm * 7*f10796a0Sdp-arm * Redistributions of source code must retain the above copyright notice, this 8*f10796a0Sdp-arm * list of conditions and the following disclaimer. 9*f10796a0Sdp-arm * 10*f10796a0Sdp-arm * Redistributions in binary form must reproduce the above copyright notice, 11*f10796a0Sdp-arm * this list of conditions and the following disclaimer in the documentation 12*f10796a0Sdp-arm * and/or other materials provided with the distribution. 13*f10796a0Sdp-arm * 14*f10796a0Sdp-arm * Neither the name of ARM nor the names of its contributors may be used 15*f10796a0Sdp-arm * to endorse or promote products derived from this software without specific 16*f10796a0Sdp-arm * prior written permission. 17*f10796a0Sdp-arm * 18*f10796a0Sdp-arm * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*f10796a0Sdp-arm * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*f10796a0Sdp-arm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*f10796a0Sdp-arm * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*f10796a0Sdp-arm * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*f10796a0Sdp-arm * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*f10796a0Sdp-arm * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*f10796a0Sdp-arm * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*f10796a0Sdp-arm * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*f10796a0Sdp-arm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*f10796a0Sdp-arm * POSSIBILITY OF SUCH DAMAGE. 29*f10796a0Sdp-arm */ 30*f10796a0Sdp-arm 31*f10796a0Sdp-arm #include <arm_sip_svc.h> 32*f10796a0Sdp-arm #include <debug.h> 33*f10796a0Sdp-arm #include <pmf.h> 34*f10796a0Sdp-arm #include <runtime_svc.h> 35*f10796a0Sdp-arm #include <stdint.h> 36*f10796a0Sdp-arm #include <uuid.h> 37*f10796a0Sdp-arm 38*f10796a0Sdp-arm 39*f10796a0Sdp-arm /* ARM SiP Service UUID */ 40*f10796a0Sdp-arm DEFINE_SVC_UUID(arm_sip_svc_uid, 41*f10796a0Sdp-arm 0xe2756d55, 0x3360, 0x4bb5, 0xbf, 0xf3, 42*f10796a0Sdp-arm 0x62, 0x79, 0xfd, 0x11, 0x37, 0xff); 43*f10796a0Sdp-arm 44*f10796a0Sdp-arm static int arm_sip_setup(void) 45*f10796a0Sdp-arm { 46*f10796a0Sdp-arm if (pmf_setup() != 0) 47*f10796a0Sdp-arm return 1; 48*f10796a0Sdp-arm return 0; 49*f10796a0Sdp-arm } 50*f10796a0Sdp-arm 51*f10796a0Sdp-arm /* 52*f10796a0Sdp-arm * This function handles ARM defined SiP Calls 53*f10796a0Sdp-arm */ 54*f10796a0Sdp-arm static uintptr_t arm_sip_handler(unsigned int smc_fid, 55*f10796a0Sdp-arm u_register_t x1, 56*f10796a0Sdp-arm u_register_t x2, 57*f10796a0Sdp-arm u_register_t x3, 58*f10796a0Sdp-arm u_register_t x4, 59*f10796a0Sdp-arm void *cookie, 60*f10796a0Sdp-arm void *handle, 61*f10796a0Sdp-arm u_register_t flags) 62*f10796a0Sdp-arm { 63*f10796a0Sdp-arm /* 64*f10796a0Sdp-arm * Dispatch PMF calls to PMF SMC handler and return its return 65*f10796a0Sdp-arm * value 66*f10796a0Sdp-arm */ 67*f10796a0Sdp-arm if (is_pmf_fid(smc_fid)) { 68*f10796a0Sdp-arm return pmf_smc_handler(smc_fid, x1, x2, x3, x4, cookie, 69*f10796a0Sdp-arm handle, flags); 70*f10796a0Sdp-arm } 71*f10796a0Sdp-arm 72*f10796a0Sdp-arm switch (smc_fid) { 73*f10796a0Sdp-arm case ARM_SIP_SVC_CALL_COUNT: 74*f10796a0Sdp-arm /* 75*f10796a0Sdp-arm * Return the number of SiP Service Calls. PMF is the only 76*f10796a0Sdp-arm * SiP service implemented; so return number of PMF calls 77*f10796a0Sdp-arm */ 78*f10796a0Sdp-arm SMC_RET1(handle, PMF_NUM_SMC_CALLS); 79*f10796a0Sdp-arm 80*f10796a0Sdp-arm case ARM_SIP_SVC_UID: 81*f10796a0Sdp-arm /* Return UID to the caller */ 82*f10796a0Sdp-arm SMC_UUID_RET(handle, arm_sip_svc_uid); 83*f10796a0Sdp-arm 84*f10796a0Sdp-arm case ARM_SIP_SVC_VERSION: 85*f10796a0Sdp-arm /* Return the version of current implementation */ 86*f10796a0Sdp-arm SMC_RET2(handle, ARM_SIP_SVC_VERSION_MAJOR, ARM_SIP_SVC_VERSION_MINOR); 87*f10796a0Sdp-arm 88*f10796a0Sdp-arm default: 89*f10796a0Sdp-arm WARN("Unimplemented ARM SiP Service Call: 0x%x \n", smc_fid); 90*f10796a0Sdp-arm SMC_RET1(handle, SMC_UNK); 91*f10796a0Sdp-arm } 92*f10796a0Sdp-arm 93*f10796a0Sdp-arm } 94*f10796a0Sdp-arm 95*f10796a0Sdp-arm 96*f10796a0Sdp-arm /* Define a runtime service descriptor for fast SMC calls */ 97*f10796a0Sdp-arm DECLARE_RT_SVC( 98*f10796a0Sdp-arm arm_sip_svc, 99*f10796a0Sdp-arm OEN_SIP_START, 100*f10796a0Sdp-arm OEN_SIP_END, 101*f10796a0Sdp-arm SMC_TYPE_FAST, 102*f10796a0Sdp-arm arm_sip_setup, 103*f10796a0Sdp-arm arm_sip_handler 104*f10796a0Sdp-arm ); 105