1 /* 2 * SPDX-License-Identifier: BSD-3-Clause 3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors. 4 */ 5 6 #ifndef SMC_H 7 #define SMC_H 8 9 #include <utils_def.h> 10 11 /* FID: Type - Fast Call */ 12 #define SMC_TYPE_SHIFT U(31) 13 #define SMC_TYPE_MASK U(1) 14 #define SMC_TYPE_FAST U(1) 15 16 /* FID: Calling convention - SMC32/SMC64 */ 17 #define SMC_CC_SHIFT U(30) 18 #define SMC_CC_MASK U(1) 19 #define SMC_CC_SMC32 U(0) 20 #define SMC_CC_SMC64 U(1) 21 22 /* FID: Owning entity number - Standard Secure Service Calls */ 23 #define SMC_OEN_SHIFT U(24) 24 #define SMC_OEN_MASK U(0x3F) 25 #define SMC_OEN_STD U(0x4) 26 #define SMC_OEN_ARCH U(0x0) 27 28 /* FID: Must be zero (MBZ) */ 29 #define SMC_MBZ_SHIFT U(16) 30 #define SMC_MBZ_MASK U(0xFF) 31 #define SMC_MBZ_ZERO U(0x0) 32 33 /* FID: Function number */ 34 #define SMC_FNUM_SHIFT U(0) 35 #define SMC_FNUM_MASK U(0xFFFF) 36 37 #define SMC_FIELD_VAL(_field, _val) \ 38 (((_val) & SMC_##_field##_MASK) << SMC_##_field##_SHIFT) 39 40 #define SMC_SET_FIELD(_init_val, _field, _val) \ 41 (((_init_val) & ~SMC_FIELD_VAL(_field, SMC_##_field##_MASK)) | \ 42 SMC_FIELD_VAL(_field, _val)) 43 44 #define SMC_GET_FIELD(_fid, _field) \ 45 (((_fid) >> SMC_##_field##_SHIFT) & SMC_##_field##_MASK) 46 47 /* Arm Architecture Call range function IDs */ 48 /* 0x80000000 */ 49 #define SMC_ARCH_CALL_BASE (SMC_SET_FIELD(U(0), TYPE, SMC_TYPE_FAST) | \ 50 SMC_SET_FIELD(U(0), OEN, SMC_OEN_ARCH)) 51 52 /* 0x8000FFFF */ 53 #define SMC_ARCH_CALL_LIMIT (SMC_SET_FIELD(SMC_ARCH_CALL_BASE, FNUM, \ 54 U(0xFFFF))) 55 56 /* 57 * We allocate all RMM calls as function IDs within the Standard Secure 58 * Service Call range category defined in the SMCCC. 59 */ 60 /* 0x84000000 */ 61 #define SMC_STD_CALL_BASE (SMC_SET_FIELD(U(0), TYPE, SMC_TYPE_FAST) | \ 62 SMC_SET_FIELD(U(0), OEN, SMC_OEN_STD)) 63 64 /* 0x840001CF */ 65 #define SMC_STD_CALL_LIMIT (SMC_SET_FIELD(SMC_STD_CALL_BASE, FNUM, \ 66 U(0x1CF))) 67 68 /* STD calls FNUM Min/Max ranges */ 69 #define SMC32_PSCI_FNUM_MIN (U(0x0)) 70 #define SMC32_PSCI_FNUM_MAX (U(0x14)) 71 72 #define SMC64_PSCI_FNUM_MIN (U(0x0)) 73 #define SMC64_PSCI_FNUM_MAX (U(0x14)) 74 75 #define SMC64_RMI_FNUM_MIN (U(0x150)) 76 #define SMC64_RMI_FNUM_MAX (U(0x169)) 77 78 #define SMC64_RSI_FNUM_MIN (U(0x190)) 79 #define SMC64_RSI_FNUM_MAX (U(0x1AF)) 80 81 #define SMC64_RMM_EL3_FNUM_MIN (U(0x1B0)) 82 #define SMC64_RMM_EL3_FNUM_MAX (U(0x1CF)) 83 84 /* Utility macros for FID range values */ 85 #define SMC32_ARCH_FID(_offset) \ 86 (SMC_SET_FIELD(SMC_ARCH_CALL_BASE, CC, SMC_CC_SMC32) | \ 87 SMC_SET_FIELD(SMC_ARCH_CALL_BASE, FNUM, (_offset))) 88 89 #define SMC32_STD_FID(_range, _offset) \ 90 (SMC_SET_FIELD(SMC_STD_CALL_BASE, CC, SMC_CC_SMC32) | \ 91 SMC_SET_FIELD(SMC_STD_CALL_BASE, FNUM, \ 92 (SMC32_##_range##_FNUM_MIN + (_offset)))) 93 94 #define SMC64_STD_FID(_range, _offset) \ 95 (SMC_SET_FIELD(SMC_STD_CALL_BASE, CC, SMC_CC_SMC64) | \ 96 SMC_SET_FIELD(SMC_STD_CALL_BASE, FNUM, \ 97 (SMC64_##_range##_FNUM_MIN + (_offset)))) 98 99 #define IS_SMC64_FID_IN_RANGE(_range, _fid) \ 100 ((SMC_GET_FIELD(_fid, FNUM) >= SMC64_##_range##_FNUM_MIN) && \ 101 (SMC_GET_FIELD(_fid, FNUM) <= SMC64_##_range##_FNUM_MAX)) 102 103 #define IS_SMC32_FID_IN_RANGE(_range, _fid) \ 104 ((SMC_GET_FIELD(_fid, FNUM) >= SMC32_##_range##_FNUM_MIN) && \ 105 (SMC_GET_FIELD(_fid, FNUM) <= SMC32_##_range##_FNUM_MAX)) 106 107 #define IS_SMC64_FID_STD_FAST(_fid) \ 108 (((_fid) & ~SMC_FIELD_VAL(FNUM, SMC_FNUM_MASK)) == \ 109 ((SMC_FIELD_VAL(CC, SMC_CC_SMC64) | \ 110 SMC_FIELD_VAL(TYPE, SMC_TYPE_FAST) | \ 111 SMC_FIELD_VAL(OEN, SMC_OEN_STD)))) 112 113 #define IS_SMC32_FID_STD_FAST(_fid) \ 114 (((_fid) & ~SMC_FIELD_VAL(FNUM, SMC_FNUM_MASK)) == \ 115 ((SMC_FIELD_VAL(CC, SMC_CC_SMC32) | \ 116 SMC_FIELD_VAL(TYPE, SMC_TYPE_FAST) | \ 117 SMC_FIELD_VAL(OEN, SMC_OEN_STD)))) 118 119 #define IS_SMC64_STD_FAST_IN_RANGE(_range, _fid) \ 120 (IS_SMC64_FID_STD_FAST(_fid) && IS_SMC64_FID_IN_RANGE(_range, _fid)) 121 122 #define IS_SMC32_STD_FAST_IN_RANGE(_range, _fid) \ 123 (IS_SMC32_FID_STD_FAST(_fid) && IS_SMC32_FID_IN_RANGE(_range, _fid)) 124 125 #define SMC64_NUM_FIDS_IN_RANGE(_range) \ 126 (SMC64_##_range##_FNUM_MAX - SMC64_##_range##_FNUM_MIN + 1) 127 128 /* Gets the offset in a range. Inputs must be pre-verified */ 129 #define SMC64_FID_OFFSET_FROM_RANGE_MIN(_range, _fid) \ 130 (SMC_GET_FIELD(_fid, FNUM) - SMC64_##_range##_FNUM_MIN) 131 132 /* Implementation defined FID values */ 133 /* 0x18F */ 134 #define SMC_RMM_REQ_COMPLETE SMC64_STD_FID(RMI, U(0x3F)) 135 136 /* 0x1B0 - 0x1B3 */ 137 #define SMC_ASC_MARK_SECURE SMC64_STD_FID(RMM_EL3, U(0)) 138 #define SMC_ASC_MARK_NONSECURE SMC64_STD_FID(RMM_EL3, U(1)) 139 140 /* ARM ARCH call FIDs */ 141 #define SMCCC_VERSION SMC32_ARCH_FID(U(0)) 142 #define SMCCC_ARCH_FEATURES SMC32_ARCH_FID(U(1)) 143 #define SMCCC_ARCH_SOC_ID SMC32_ARCH_FID(U(2)) 144 #define SMCCC_ARCH_WORKAROUND_2 SMC32_ARCH_FID(U(0x7FFF)) 145 #define SMCCC_ARCH_WORKAROUND_1 SMC32_ARCH_FID(U(0x8000)) 146 147 /* Implemented version of the SMC Calling Convention */ 148 #define SMCCC_VERSION_MAJOR U(1) 149 #define SMCCC_VERSION_MINOR U(2) 150 151 /* 152 * SMCCC version encoding: 153 * Bit[31] must be zero 154 * Bits [30:16] Major version 155 * Bits [15:0] Minor version 156 */ 157 #define SMCCC_VERSION_NUMBER \ 158 ((SMCCC_VERSION_MAJOR << U(16)) | SMCCC_VERSION_MINOR) 159 160 /* SMCCC return codes */ 161 #define SMC_SUCCESS 0 162 #define SMC_NOT_SUPPORTED (-1) 163 #define SMC_NOT_REQUIRED (-2) 164 #define SMC_INVALID_PARAMETER (-3) 165 166 #define SMC_UNKNOWN (-1) 167 168 #ifndef __ASSEMBLER__ 169 unsigned long monitor_call(unsigned long id, 170 unsigned long arg0, 171 unsigned long arg1, 172 unsigned long arg2, 173 unsigned long arg3, 174 unsigned long arg4, 175 unsigned long arg5); 176 177 /* Result registers X0-X4 */ 178 #define SMC_RESULT_REGS 5U 179 180 struct smc_result { 181 unsigned long x[SMC_RESULT_REGS]; 182 }; 183 184 void monitor_call_with_res(unsigned long id, 185 unsigned long arg0, 186 unsigned long arg1, 187 unsigned long arg2, 188 unsigned long arg3, 189 unsigned long arg4, 190 unsigned long arg5, 191 struct smc_result *res); 192 193 #endif /* __ASSEMBLER__ */ 194 195 #endif /* SMC_H */ 196