1 /* 2 * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved. 3 * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 /* Top level SMC handler for SiP calls. Dispatch PM calls to PM SMC handler. */ 9 10 #include <inttypes.h> 11 12 #include <common/debug.h> 13 #include <common/runtime_svc.h> 14 #include <tools_share/uuid.h> 15 16 #include "ipi_mailbox_svc.h" 17 #include "pm_svc_main.h" 18 19 /* SMC function IDs for SiP Service queries */ 20 #define VERSAL_SIP_SVC_UID U(0x8200ff01) 21 #define VERSAL_SIP_SVC_VERSION U(0x8200ff03) 22 23 /* SiP Service Calls version numbers */ 24 #define SIP_SVC_VERSION_MAJOR U(0) 25 #define SIP_SVC_VERSION_MINOR U(2) 26 27 /* These macros are used to identify PM calls from the SMC function ID */ 28 #define SIP_FID_MASK GENMASK(23, 16) 29 #define XLNX_FID_MASK GENMASK(23, 12) 30 #define PM_FID_VALUE 0u 31 #define IPI_FID_VALUE 0x1000u 32 #define is_pm_fid(_fid) (((_fid) & XLNX_FID_MASK) == PM_FID_VALUE) 33 #define is_ipi_fid(_fid) (((_fid) & XLNX_FID_MASK) == IPI_FID_VALUE) 34 35 /* SiP Service UUID */ 36 DEFINE_SVC_UUID2(versal_sip_uuid, 37 0x2ab9e4ecU, 0x93b9U, 0x11e7U, 0xa0U, 0x19U, 38 0xdfU, 0xe0U, 0xdbU, 0xadU, 0x0aU, 0xe0U); 39 40 /** 41 * sip_svc_setup() - Setup SiP Service 42 * 43 * Return: 0 on success,negative error code on failure. 44 * 45 * Invokes PM setup. 46 */ 47 static int32_t sip_svc_setup(void) 48 { 49 /* PM implementation as SiP Service */ 50 (void)pm_setup(); 51 52 return 0; 53 } 54 55 /** 56 * sip_svc_smc_handler() - Top-level SiP Service SMC handler. 57 * @smc_fid: Function Identifier. 58 * @x1: SMC64 Arguments 1 from kernel. 59 * @x2: SMC64 Arguments 2 from kernel. 60 * @x3: SMC64 Arguments 3 from kernel(upper 32-bits). 61 * @x4: SMC64 Arguments 4 from kernel. 62 * @cookie: Unused 63 * @handle: Pointer to caller's context structure. 64 * @flags: SECURE_FLAG or NON_SECURE_FLAG. 65 * 66 * Handler for all SiP SMC calls. Handles standard SIP requests 67 * and calls PM SMC handler if the call is for a PM-API function. 68 * 69 * Return: Unused. 70 */ 71 static uintptr_t sip_svc_smc_handler(uint32_t smc_fid, 72 u_register_t x1, 73 u_register_t x2, 74 u_register_t x3, 75 u_register_t x4, 76 void *cookie, 77 void *handle, 78 u_register_t flags) 79 { 80 VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n", 81 smc_fid, x1, x2, x3, x4); 82 83 if ((smc_fid & SIP_FID_MASK) != 0U) { 84 WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid); 85 SMC_RET1(handle, SMC_UNK); 86 } 87 88 /* Let PM SMC handler deal with PM-related requests */ 89 if (is_pm_fid(smc_fid)) { 90 return pm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, 91 flags); 92 } 93 94 /* Let IPI SMC handler deal with IPI-related requests */ 95 if (is_ipi_fid(smc_fid)) { 96 return ipi_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, 97 flags); 98 } 99 100 /* Let PM SMC handler deal with PM-related requests */ 101 switch (smc_fid) { 102 case VERSAL_SIP_SVC_UID: 103 SMC_UUID_RET(handle, versal_sip_uuid); 104 105 case VERSAL_SIP_SVC_VERSION: 106 SMC_RET2(handle, SIP_SVC_VERSION_MAJOR, SIP_SVC_VERSION_MINOR); 107 108 default: 109 WARN("Unimplemented SiP Service Call: 0x%x\n", smc_fid); 110 SMC_RET1(handle, SMC_UNK); 111 } 112 } 113 114 /* Register PM Service Calls as runtime service */ 115 DECLARE_RT_SVC( 116 sip_svc, 117 OEN_SIP_START, 118 OEN_SIP_END, 119 SMC_TYPE_FAST, 120 sip_svc_setup, 121 sip_svc_smc_handler); 122