1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * (C) Copyright 2017 Rockchip Electronics Co., Ltd 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+ 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun #ifndef TEESMC_H 8*4882a593Smuzhiyun #define TEESMC_H 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #include <optee_include/tee_base_types.h> 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun #ifndef ASM 13*4882a593Smuzhiyun /* 14*4882a593Smuzhiyun * This section depends on uint64_t, uint32_t uint8_t already being 15*4882a593Smuzhiyun * defined. Since this file is used in several different environments 16*4882a593Smuzhiyun * (secure world OS and normal world Linux kernel to start with) where 17*4882a593Smuzhiyun * stdint.h may not be available it's the responsibility of the one 18*4882a593Smuzhiyun * including this file to provide those types. 19*4882a593Smuzhiyun */ 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun /* 22*4882a593Smuzhiyun * Trusted OS SMC interface. 23*4882a593Smuzhiyun * 24*4882a593Smuzhiyun * The SMC interface follows SMC Calling Convention 25*4882a593Smuzhiyun * (ARM_DEN0028A_SMC_Calling_Convention). 26*4882a593Smuzhiyun * 27*4882a593Smuzhiyun * The primary objective of this API is to provide a transport layer on 28*4882a593Smuzhiyun * which a Global Platform compliant TEE interfaces can be deployed. But the 29*4882a593Smuzhiyun * interface can also be used for other implementations. 30*4882a593Smuzhiyun * 31*4882a593Smuzhiyun * This file is divided in two parts. 32*4882a593Smuzhiyun * Part 1 deals with passing parameters to Trusted Applications running in 33*4882a593Smuzhiyun * a trusted OS in secure world. 34*4882a593Smuzhiyun * Part 2 deals with the lower level handling of the SMC. 35*4882a593Smuzhiyun */ 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun /* 38*4882a593Smuzhiyun ******************************************************************************* 39*4882a593Smuzhiyun * Part 1 - passing parameters to Trusted Applications 40*4882a593Smuzhiyun ******************************************************************************* 41*4882a593Smuzhiyun */ 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun /* 44*4882a593Smuzhiyun * Same values as TEE_PARAM_* from TEE Internal API 45*4882a593Smuzhiyun */ 46*4882a593Smuzhiyun #define TEESMC_ATTR_TYPE_NONE 0 47*4882a593Smuzhiyun #define TEESMC_ATTR_TYPE_VALUE_INPUT 1 48*4882a593Smuzhiyun #define TEESMC_ATTR_TYPE_VALUE_OUTPUT 2 49*4882a593Smuzhiyun #define TEESMC_ATTR_TYPE_VALUE_INOUT 3 50*4882a593Smuzhiyun #define TEESMC_ATTR_TYPE_MEMREF_INPUT 5 51*4882a593Smuzhiyun #define TEESMC_ATTR_TYPE_MEMREF_OUTPUT 6 52*4882a593Smuzhiyun #define TEESMC_ATTR_TYPE_MEMREF_INOUT 7 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun #define TEESMC_ATTR_TYPE_MASK 0x7 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun /* 57*4882a593Smuzhiyun * Meta parameter to be absorbed by the Secure OS and not passed 58*4882a593Smuzhiyun * to the Trusted Application. 59*4882a593Smuzhiyun * 60*4882a593Smuzhiyun * One example of this is a struct teesmc_meta_open_session which 61*4882a593Smuzhiyun * is added to TEESMC{32,64}_CMD_OPEN_SESSION. 62*4882a593Smuzhiyun */ 63*4882a593Smuzhiyun #define TEESMC_ATTR_META 0x8 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun /* 66*4882a593Smuzhiyun * Used as an indication from normal world of compatible cache usage. 67*4882a593Smuzhiyun * 'I' stands for inner cache and 'O' for outer cache. 68*4882a593Smuzhiyun */ 69*4882a593Smuzhiyun #define TEESMC_ATTR_CACHE_I_NONCACHE 0x0 70*4882a593Smuzhiyun #define TEESMC_ATTR_CACHE_I_WRITE_THR 0x1 71*4882a593Smuzhiyun #define TEESMC_ATTR_CACHE_I_WRITE_BACK 0x2 72*4882a593Smuzhiyun #define TEESMC_ATTR_CACHE_O_NONCACHE 0x0 73*4882a593Smuzhiyun #define TEESMC_ATTR_CACHE_O_WRITE_THR 0x4 74*4882a593Smuzhiyun #define TEESMC_ATTR_CACHE_O_WRITE_BACK 0x8 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun #define TEESMC_ATTR_CACHE_NONCACHE 0x0 77*4882a593Smuzhiyun #define TEESMC_ATTR_CACHE_DEFAULT (TEESMC_ATTR_CACHE_I_WRITE_BACK | \ 78*4882a593Smuzhiyun TEESMC_ATTR_CACHE_O_WRITE_BACK) 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun #define TEESMC_ATTR_CACHE_SHIFT 4 81*4882a593Smuzhiyun #define TEESMC_ATTR_CACHE_MASK 0xf 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun #define TEESMC_CMD_OPEN_SESSION 0 84*4882a593Smuzhiyun #define TEESMC_CMD_INVOKE_COMMAND 1 85*4882a593Smuzhiyun #define TEESMC_CMD_CLOSE_SESSION 2 86*4882a593Smuzhiyun #define TEESMC_CMD_CANCEL 3 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun /** 89*4882a593Smuzhiyun * struct teesmc32_param_memref - memory reference 90*4882a593Smuzhiyun * @buf_ptr: Address of the buffer 91*4882a593Smuzhiyun * @size: Size of the buffer 92*4882a593Smuzhiyun * 93*4882a593Smuzhiyun * Secure and normal world communicates pointer via physical address instead of 94*4882a593Smuzhiyun * the virtual address with is usually used for pointers. This is because 95*4882a593Smuzhiyun * Secure and normal world has completely independant memory mapping. Normal 96*4882a593Smuzhiyun * world can even have a hypervisor which need to translate the guest 97*4882a593Smuzhiyun * physical address (AKA IPA in ARM lingo) to a real physical address 98*4882a593Smuzhiyun * before passing the structure to secure world. 99*4882a593Smuzhiyun */ 100*4882a593Smuzhiyun struct teesmc32_param_memref { 101*4882a593Smuzhiyun uint32_t buf_ptr; 102*4882a593Smuzhiyun uint32_t size; 103*4882a593Smuzhiyun }; 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun /** 106*4882a593Smuzhiyun * struct teesmc32_param_memref - memory reference 107*4882a593Smuzhiyun * @buf_ptr: Address of the buffer 108*4882a593Smuzhiyun * @size: Size of the buffer 109*4882a593Smuzhiyun * 110*4882a593Smuzhiyun * See description of struct teesmc32_param_memref. 111*4882a593Smuzhiyun */ 112*4882a593Smuzhiyun struct teesmc64_param_memref { 113*4882a593Smuzhiyun uint64_t buf_ptr; 114*4882a593Smuzhiyun uint64_t size; 115*4882a593Smuzhiyun }; 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun /** 118*4882a593Smuzhiyun * struct teesmc32_param_value - values 119*4882a593Smuzhiyun * @a: first value 120*4882a593Smuzhiyun * @b: second value 121*4882a593Smuzhiyun */ 122*4882a593Smuzhiyun struct teesmc32_param_value { 123*4882a593Smuzhiyun uint32_t a; 124*4882a593Smuzhiyun uint32_t b; 125*4882a593Smuzhiyun }; 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun /** 128*4882a593Smuzhiyun * struct teesmc64_param_value - values 129*4882a593Smuzhiyun * @a: first value 130*4882a593Smuzhiyun * @b: second value 131*4882a593Smuzhiyun */ 132*4882a593Smuzhiyun struct teesmc64_param_value { 133*4882a593Smuzhiyun uint64_t a; 134*4882a593Smuzhiyun uint64_t b; 135*4882a593Smuzhiyun }; 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun /** 138*4882a593Smuzhiyun * struct teesmc32_param - parameter 139*4882a593Smuzhiyun * @attr: attributes 140*4882a593Smuzhiyun * @memref: a memory reference 141*4882a593Smuzhiyun * @value: a value 142*4882a593Smuzhiyun * 143*4882a593Smuzhiyun * attr & TEESMC_ATTR_TYPE_MASK indicates if memref or value is used in the 144*4882a593Smuzhiyun * union. TEESMC_ATTR_TYPE_VALUE_* indicates value and 145*4882a593Smuzhiyun * TEESMC_ATTR_TYPE_MEMREF_* indicates memref. TEESMC_ATTR_TYPE_NONE 146*4882a593Smuzhiyun * indicates that none of the members are used. 147*4882a593Smuzhiyun */ 148*4882a593Smuzhiyun struct teesmc32_param { 149*4882a593Smuzhiyun uint32_t attr; 150*4882a593Smuzhiyun union { 151*4882a593Smuzhiyun struct teesmc32_param_memref memref; 152*4882a593Smuzhiyun struct teesmc32_param_value value; 153*4882a593Smuzhiyun } u; 154*4882a593Smuzhiyun }; 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun /** 157*4882a593Smuzhiyun * struct teesmc64_param - parameter 158*4882a593Smuzhiyun * @attr: attributes 159*4882a593Smuzhiyun * @memref: a memory reference 160*4882a593Smuzhiyun * @value: a value 161*4882a593Smuzhiyun * 162*4882a593Smuzhiyun * See description of union teesmc32_param. 163*4882a593Smuzhiyun */ 164*4882a593Smuzhiyun struct teesmc64_param { 165*4882a593Smuzhiyun uint64_t attr; 166*4882a593Smuzhiyun union { 167*4882a593Smuzhiyun struct teesmc64_param_memref memref; 168*4882a593Smuzhiyun struct teesmc64_param_value value; 169*4882a593Smuzhiyun } u; 170*4882a593Smuzhiyun }; 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun /** 173*4882a593Smuzhiyun * struct teesmc32_arg - SMC argument for Trusted OS 174*4882a593Smuzhiyun * @cmd: Command, one of TEESMC_CMD_* 175*4882a593Smuzhiyun * @ta_func: Trusted Application function, specific to the Trusted Application, 176*4882a593Smuzhiyun * used if cmd == TEESMC_CMD_INVOKE_COMMAND 177*4882a593Smuzhiyun * @session: In parameter for all TEESMC_CMD_* except 178*4882a593Smuzhiyun * TEESMC_CMD_OPEN_SESSION where it's an output paramter instead 179*4882a593Smuzhiyun * @ret: return value 180*4882a593Smuzhiyun * @ret_origin: origin of the return value 181*4882a593Smuzhiyun * @num_params: number of parameters supplied to the OS Command 182*4882a593Smuzhiyun * @params: the parameters supplied to the OS Command 183*4882a593Smuzhiyun * 184*4882a593Smuzhiyun * All normal SMC calls to Trusted OS uses this struct. If cmd requires 185*4882a593Smuzhiyun * further information than what these field holds it can be passed as a 186*4882a593Smuzhiyun * parameter tagged as meta (setting the TEESMC_ATTR_META bit in 187*4882a593Smuzhiyun * corresponding param_attrs). This is used for TEESMC_CMD_OPEN_SESSION 188*4882a593Smuzhiyun * to pass a struct teesmc32_meta_open_session which is needed find the 189*4882a593Smuzhiyun * Trusted Application and to indicate the credentials of the client. 190*4882a593Smuzhiyun */ 191*4882a593Smuzhiyun struct teesmc32_arg { 192*4882a593Smuzhiyun uint32_t cmd; 193*4882a593Smuzhiyun uint32_t ta_func; 194*4882a593Smuzhiyun uint32_t session; 195*4882a593Smuzhiyun uint32_t ret; 196*4882a593Smuzhiyun uint32_t ret_origin; 197*4882a593Smuzhiyun uint32_t num_params; 198*4882a593Smuzhiyun /* 199*4882a593Smuzhiyun * Commented out element used to visualize the layout dynamic part 200*4882a593Smuzhiyun * of the struct. Note that this field is not available at all 201*4882a593Smuzhiyun * if num_params == 0. 202*4882a593Smuzhiyun * 203*4882a593Smuzhiyun * params is accessed through the macro TEESMC32_GET_PARAMS 204*4882a593Smuzhiyun * 205*4882a593Smuzhiyun * struct teesmc32_param params[num_params]; 206*4882a593Smuzhiyun */ 207*4882a593Smuzhiyun }; 208*4882a593Smuzhiyun 209*4882a593Smuzhiyun /** 210*4882a593Smuzhiyun * struct teesmc64_arg - SMC argument for Trusted OS 211*4882a593Smuzhiyun * @cmd: OS Command, one of TEESMC_CMD_* 212*4882a593Smuzhiyun * @ta_func: Trusted Application function, specific to the Trusted Application 213*4882a593Smuzhiyun * @session: In parameter for all TEESMC_CMD_* but 214*4882a593Smuzhiyun * TEESMC_CMD_OPEN_SESSION 215*4882a593Smuzhiyun * @ret: return value 216*4882a593Smuzhiyun * @ret_origin: origin of the return value 217*4882a593Smuzhiyun * @num_params: number of parameters supplied to the OS Command 218*4882a593Smuzhiyun * @params: the parameters supplied to the OS Command 219*4882a593Smuzhiyun * 220*4882a593Smuzhiyun * See description of struct teesmc32_arg. 221*4882a593Smuzhiyun */ 222*4882a593Smuzhiyun struct teesmc64_arg { 223*4882a593Smuzhiyun uint64_t cmd; 224*4882a593Smuzhiyun uint64_t ta_func; 225*4882a593Smuzhiyun uint64_t session; 226*4882a593Smuzhiyun uint64_t ret; 227*4882a593Smuzhiyun uint64_t ret_origin; 228*4882a593Smuzhiyun uint64_t num_params; 229*4882a593Smuzhiyun /* 230*4882a593Smuzhiyun * Commented out element used to visualize the layout dynamic part 231*4882a593Smuzhiyun * of the struct. Note that this field is not available at all 232*4882a593Smuzhiyun * if num_params == 0. 233*4882a593Smuzhiyun * 234*4882a593Smuzhiyun * params is accessed through the macro TEESMC64_GET_PARAMS 235*4882a593Smuzhiyun * 236*4882a593Smuzhiyun * struct teesmc64_param params[num_params]; 237*4882a593Smuzhiyun */ 238*4882a593Smuzhiyun }; 239*4882a593Smuzhiyun 240*4882a593Smuzhiyun /** 241*4882a593Smuzhiyun * TEESMC64_GET_PARAMS - return pointer to union teesmc64_param * 242*4882a593Smuzhiyun * 243*4882a593Smuzhiyun * @x: Pointer to a struct teesmc64_arg 244*4882a593Smuzhiyun * 245*4882a593Smuzhiyun * Returns a pointer to the params[] inside a struct teesmc64_arg. 246*4882a593Smuzhiyun */ 247*4882a593Smuzhiyun #define TEESMC64_GET_PARAMS(x) \ 248*4882a593Smuzhiyun (struct teesmc64_param *)(((struct teesmc64_arg *)(x)) + 1) 249*4882a593Smuzhiyun 250*4882a593Smuzhiyun /** 251*4882a593Smuzhiyun * TEESMC64_GET_ARG_SIZE - return size of struct teesmc64_arg 252*4882a593Smuzhiyun * 253*4882a593Smuzhiyun * @num_params: Number of parameters embedded in the struct teesmc64_arg 254*4882a593Smuzhiyun * 255*4882a593Smuzhiyun * Returns the size of the struct teesmc64_arg together with the number 256*4882a593Smuzhiyun * of embedded paramters. 257*4882a593Smuzhiyun */ 258*4882a593Smuzhiyun #define TEESMC64_GET_ARG_SIZE(num_params) \ 259*4882a593Smuzhiyun (sizeof(struct teesmc64_arg) + \ 260*4882a593Smuzhiyun sizeof(struct teesmc64_param) * (num_params)) 261*4882a593Smuzhiyun 262*4882a593Smuzhiyun #define TEESMC_UUID_LEN 16 263*4882a593Smuzhiyun 264*4882a593Smuzhiyun /** 265*4882a593Smuzhiyun * struct teesmc_meta_open_session - additional parameters for 266*4882a593Smuzhiyun * TEESMC32_CMD_OPEN_SESSION and 267*4882a593Smuzhiyun * TEESMC64_CMD_OPEN_SESSION 268*4882a593Smuzhiyun * @uuid: UUID of the Trusted Application 269*4882a593Smuzhiyun * @clnt_uuid: UUID of client 270*4882a593Smuzhiyun * @clnt_login: Login class of client, TEE_LOGIN_* if being Global Platform 271*4882a593Smuzhiyun * compliant 272*4882a593Smuzhiyun * 273*4882a593Smuzhiyun * This struct is passed in the first parameter as an input memref tagged 274*4882a593Smuzhiyun * as meta on an TEESMC{32,64}_CMD_OPEN_SESSION cmd. It's important 275*4882a593Smuzhiyun * that it really is the first parameter to make it easy for an eventual 276*4882a593Smuzhiyun * hypervisor to inspect and possibly update clnt_* values. 277*4882a593Smuzhiyun */ 278*4882a593Smuzhiyun struct teesmc_meta_open_session { 279*4882a593Smuzhiyun uint8_t uuid[TEESMC_UUID_LEN]; 280*4882a593Smuzhiyun uint8_t clnt_uuid[TEESMC_UUID_LEN]; 281*4882a593Smuzhiyun uint32_t clnt_login; 282*4882a593Smuzhiyun }; 283*4882a593Smuzhiyun 284*4882a593Smuzhiyun 285*4882a593Smuzhiyun #endif /*!ASM*/ 286*4882a593Smuzhiyun 287*4882a593Smuzhiyun /* 288*4882a593Smuzhiyun ******************************************************************************* 289*4882a593Smuzhiyun * Part 2 - low level SMC interaction 290*4882a593Smuzhiyun ******************************************************************************* 291*4882a593Smuzhiyun */ 292*4882a593Smuzhiyun 293*4882a593Smuzhiyun #define TEESMC_32 0 294*4882a593Smuzhiyun #define TEESMC_64 0x40000000 295*4882a593Smuzhiyun #define TEESMC_FAST_CALL 0x80000000 296*4882a593Smuzhiyun #define TEESMC_STD_CALL 0 297*4882a593Smuzhiyun 298*4882a593Smuzhiyun #define TEESMC_OWNER_MASK 0x3F 299*4882a593Smuzhiyun #define TEESMC_OWNER_SHIFT 24 300*4882a593Smuzhiyun 301*4882a593Smuzhiyun #define TEESMC_FUNC_MASK 0xFFFF 302*4882a593Smuzhiyun 303*4882a593Smuzhiyun #define TEESMC_IS_FAST_CALL(smc_val) ((smc_val) & TEESMC_FAST_CALL) 304*4882a593Smuzhiyun #define TEESMC_IS_64(smc_val) ((smc_val) & TEESMC_64) 305*4882a593Smuzhiyun #define TEESMC_FUNC_NUM(smc_val) ((smc_val) & TEESMC_FUNC_MASK) 306*4882a593Smuzhiyun #define TEESMC_OWNER_NUM(smc_val) (((smc_val) >> TEESMC_OWNER_SHIFT) & \ 307*4882a593Smuzhiyun TEESMC_OWNER_MASK) 308*4882a593Smuzhiyun 309*4882a593Smuzhiyun #define TEESMC_CALL_VAL(type, calling_convention, owner, func_num) \ 310*4882a593Smuzhiyun ((type) | (calling_convention) | \ 311*4882a593Smuzhiyun (((owner) & TEESMC_OWNER_MASK) << TEESMC_OWNER_SHIFT) |\ 312*4882a593Smuzhiyun ((func_num) & TEESMC_FUNC_MASK)) 313*4882a593Smuzhiyun 314*4882a593Smuzhiyun #define TEESMC_OWNER_ARCH 0 315*4882a593Smuzhiyun #define TEESMC_OWNER_CPU 1 316*4882a593Smuzhiyun #define TEESMC_OWNER_SIP 2 317*4882a593Smuzhiyun #define TEESMC_OWNER_OEM 3 318*4882a593Smuzhiyun #define TEESMC_OWNER_STANDARD 4 319*4882a593Smuzhiyun #define TEESMC_OWNER_TRUSTED_APP 48 320*4882a593Smuzhiyun #define TEESMC_OWNER_TRUSTED_OS 50 321*4882a593Smuzhiyun 322*4882a593Smuzhiyun #define TEESMC_OWNER_TRUSTED_OS_OPTEED 62 323*4882a593Smuzhiyun #define TEESMC_OWNER_TRUSTED_OS_API 63 324*4882a593Smuzhiyun 325*4882a593Smuzhiyun /* 326*4882a593Smuzhiyun * Function specified by SMC Calling convention. 327*4882a593Smuzhiyun */ 328*4882a593Smuzhiyun #define TEESMC32_FUNCID_CALLS_COUNT 0xFF00 329*4882a593Smuzhiyun #define TEESMC32_CALLS_COUNT \ 330*4882a593Smuzhiyun TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, \ 331*4882a593Smuzhiyun TEESMC_OWNER_TRUSTED_OS_API, \ 332*4882a593Smuzhiyun TEESMC32_FUNCID_CALLS_COUNT) 333*4882a593Smuzhiyun 334*4882a593Smuzhiyun /* 335*4882a593Smuzhiyun * Function specified by SMC Calling convention 336*4882a593Smuzhiyun * 337*4882a593Smuzhiyun * Return one of the following UIDs if using API specified in this file 338*4882a593Smuzhiyun * without further extentions: 339*4882a593Smuzhiyun * 65cb6b93-af0c-4617-8ed6-644a8d1140f8 : Only 32 bit calls are supported 340*4882a593Smuzhiyun * 65cb6b93-af0c-4617-8ed6-644a8d1140f9 : Both 32 and 64 bit calls are supported 341*4882a593Smuzhiyun */ 342*4882a593Smuzhiyun #define TEESMC_UID_R0 0x65cb6b93 343*4882a593Smuzhiyun #define TEESMC_UID_R1 0xaf0c4617 344*4882a593Smuzhiyun #define TEESMC_UID_R2 0x8ed6644a 345*4882a593Smuzhiyun #define TEESMC_UID32_R3 0x8d1140f8 346*4882a593Smuzhiyun #define TEESMC_UID64_R3 0x8d1140f9 347*4882a593Smuzhiyun #define TEESMC32_FUNCID_CALLS_UID 0xFF01 348*4882a593Smuzhiyun #define TEESMC32_CALLS_UID \ 349*4882a593Smuzhiyun TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, \ 350*4882a593Smuzhiyun TEESMC_OWNER_TRUSTED_OS_API, \ 351*4882a593Smuzhiyun TEESMC32_FUNCID_CALLS_UID) 352*4882a593Smuzhiyun 353*4882a593Smuzhiyun /* 354*4882a593Smuzhiyun * Function specified by SMC Calling convention 355*4882a593Smuzhiyun * 356*4882a593Smuzhiyun * Returns 1.0 if using API specified in this file without further extentions. 357*4882a593Smuzhiyun */ 358*4882a593Smuzhiyun #define TEESMC_REVISION_MAJOR 1 359*4882a593Smuzhiyun #define TEESMC_REVISION_MINOR 0 360*4882a593Smuzhiyun #define TEESMC32_FUNCID_CALLS_REVISION 0xFF03 361*4882a593Smuzhiyun #define TEESMC32_CALLS_REVISION \ 362*4882a593Smuzhiyun TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, \ 363*4882a593Smuzhiyun TEESMC_OWNER_TRUSTED_OS_API, \ 364*4882a593Smuzhiyun TEESMC32_FUNCID_CALLS_REVISION) 365*4882a593Smuzhiyun 366*4882a593Smuzhiyun /* 367*4882a593Smuzhiyun * Get UUID of Trusted OS. 368*4882a593Smuzhiyun * 369*4882a593Smuzhiyun * Used by non-secure world to figure out which Trusted OS is installed. 370*4882a593Smuzhiyun * Note that returned UUID is the UUID of the Trusted OS, not of the API. 371*4882a593Smuzhiyun * 372*4882a593Smuzhiyun * Returns UUID in r0-4/w0-4 in the same way as TEESMC32_CALLS_UID 373*4882a593Smuzhiyun * described above. 374*4882a593Smuzhiyun */ 375*4882a593Smuzhiyun #define TEESMC_FUNCID_GET_OS_UUID 0 376*4882a593Smuzhiyun #define TEESMC32_CALL_GET_OS_UUID \ 377*4882a593Smuzhiyun TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, TEESMC_OWNER_TRUSTED_OS, \ 378*4882a593Smuzhiyun TEESMC_FUNCID_GET_OS_UUID) 379*4882a593Smuzhiyun 380*4882a593Smuzhiyun /* 381*4882a593Smuzhiyun * Get revision of Trusted OS. 382*4882a593Smuzhiyun * 383*4882a593Smuzhiyun * Used by non-secure world to figure out which version of the Trusted OS 384*4882a593Smuzhiyun * is installed. Note that the returned revision is the revision of the 385*4882a593Smuzhiyun * Trusted OS, not of the API. 386*4882a593Smuzhiyun * 387*4882a593Smuzhiyun * Returns revision in r0-1/w0-1 in the same way as TEESMC32_CALLS_REVISION 388*4882a593Smuzhiyun * described above. 389*4882a593Smuzhiyun */ 390*4882a593Smuzhiyun #define TEESMC_FUNCID_GET_OS_REVISION 1 391*4882a593Smuzhiyun #define TEESMC32_CALL_GET_OS_REVISION \ 392*4882a593Smuzhiyun TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, TEESMC_OWNER_TRUSTED_OS, \ 393*4882a593Smuzhiyun TEESMC_FUNCID_GET_OS_REVISION) 394*4882a593Smuzhiyun 395*4882a593Smuzhiyun 396*4882a593Smuzhiyun 397*4882a593Smuzhiyun /* 398*4882a593Smuzhiyun * Call with struct teesmc32_arg as argument 399*4882a593Smuzhiyun * 400*4882a593Smuzhiyun * Call register usage: 401*4882a593Smuzhiyun * r0/x0 SMC Function ID, TEESMC32_CALL_WITH_ARG 402*4882a593Smuzhiyun * r1/x1 Physical pointer to a struct teesmc32_arg 403*4882a593Smuzhiyun * r2-6/x2-6 Not used 404*4882a593Smuzhiyun * r7/x7 Hypervisor Client ID register 405*4882a593Smuzhiyun * 406*4882a593Smuzhiyun * Normal return register usage: 407*4882a593Smuzhiyun * r0/x0 Return value, TEESMC_RETURN_* 408*4882a593Smuzhiyun * r1-3/x1-3 Not used 409*4882a593Smuzhiyun * r4-7/x4-7 Preserved 410*4882a593Smuzhiyun * 411*4882a593Smuzhiyun * Ebusy return register usage: 412*4882a593Smuzhiyun * r0/x0 Return value, TEESMC_RETURN_EBUSY 413*4882a593Smuzhiyun * r1-3/x1-3 Preserved 414*4882a593Smuzhiyun * r4-7/x4-7 Preserved 415*4882a593Smuzhiyun * 416*4882a593Smuzhiyun * RPC return register usage: 417*4882a593Smuzhiyun * r0/x0 Return value, TEESMC_RETURN_IS_RPC(val) 418*4882a593Smuzhiyun * r1-2/x1-2 RPC parameters 419*4882a593Smuzhiyun * r3-7/x3-7 Resume information, must be preserved 420*4882a593Smuzhiyun * 421*4882a593Smuzhiyun * Possible return values: 422*4882a593Smuzhiyun * TEESMC_RETURN_UNKNOWN_FUNCTION Trusted OS does not recognize this 423*4882a593Smuzhiyun * function. 424*4882a593Smuzhiyun * TEESMC_RETURN_OK Call completed, result updated in 425*4882a593Smuzhiyun * the previously supplied struct 426*4882a593Smuzhiyun * teesmc32_arg. 427*4882a593Smuzhiyun * TEESMC_RETURN_EBUSY Trusted OS busy, try again later. 428*4882a593Smuzhiyun * TEESMC_RETURN_EBADADDR Bad physcial pointer to struct 429*4882a593Smuzhiyun * teesmc32_arg. 430*4882a593Smuzhiyun * TEESMC_RETURN_EBADCMD Bad/unknown cmd in struct teesmc32_arg 431*4882a593Smuzhiyun * TEESMC_RETURN_IS_RPC() Call suspended by RPC call to normal 432*4882a593Smuzhiyun * world. 433*4882a593Smuzhiyun */ 434*4882a593Smuzhiyun #define TEESMC_FUNCID_CALL_WITH_ARG 2 435*4882a593Smuzhiyun #define TEESMC32_CALL_WITH_ARG \ 436*4882a593Smuzhiyun TEESMC_CALL_VAL(TEESMC_32, TEESMC_STD_CALL, TEESMC_OWNER_TRUSTED_OS, \ 437*4882a593Smuzhiyun TEESMC_FUNCID_CALL_WITH_ARG) 438*4882a593Smuzhiyun /* Same as TEESMC32_CALL_WITH_ARG but a "fast call". */ 439*4882a593Smuzhiyun #define TEESMC32_FASTCALL_WITH_ARG \ 440*4882a593Smuzhiyun TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, TEESMC_OWNER_TRUSTED_OS, \ 441*4882a593Smuzhiyun TEESMC_FUNCID_CALL_WITH_ARG) 442*4882a593Smuzhiyun 443*4882a593Smuzhiyun /* 444*4882a593Smuzhiyun * Call with struct teesmc64_arg as argument 445*4882a593Smuzhiyun * 446*4882a593Smuzhiyun * See description of TEESMC32_CALL_WITH_ARG above, uses struct 447*4882a593Smuzhiyun * teesmc64_arg in x1 instead. 448*4882a593Smuzhiyun */ 449*4882a593Smuzhiyun #define TEESMC64_CALL_WITH_ARG \ 450*4882a593Smuzhiyun TEESMC_CALL_VAL(TEESMC_64, TEESMC_STD_CALL, TEESMC_OWNER_TRUSTED_OS, \ 451*4882a593Smuzhiyun TEESMC_FUNCID_CALL_WITH_ARG) 452*4882a593Smuzhiyun /* Same as TEESMC64_CALL_WITH_ARG but a "fast call". */ 453*4882a593Smuzhiyun #define TEESMC64_FASTCALL_WITH_ARG \ 454*4882a593Smuzhiyun TEESMC_CALL_VAL(TEESMC_64, TEESMC_FAST_CALL, TEESMC_OWNER_TRUSTED_OS, \ 455*4882a593Smuzhiyun TEESMC_FUNCID_CALL_WITH_ARG) 456*4882a593Smuzhiyun 457*4882a593Smuzhiyun /* 458*4882a593Smuzhiyun * Resume from RPC (for example after processing an IRQ) 459*4882a593Smuzhiyun * 460*4882a593Smuzhiyun * Call register usage: 461*4882a593Smuzhiyun * r0/x0 SMC Function ID, 462*4882a593Smuzhiyun * TEESMC32_CALL_RETURN_FROM_RPC or 463*4882a593Smuzhiyun * TEESMC32_FASTCALL_RETURN_FROM_RPC 464*4882a593Smuzhiyun * r1-3/x1-3 Value of r1-3/x1-3 when TEESMC32_CALL_WITH_ARG returned 465*4882a593Smuzhiyun * TEESMC_RETURN_RPC in r0/x0 466*4882a593Smuzhiyun * 467*4882a593Smuzhiyun * Return register usage is the same as for TEESMC32_CALL_WITH_ARG above. 468*4882a593Smuzhiyun * 469*4882a593Smuzhiyun * Possible return values 470*4882a593Smuzhiyun * TEESMC_RETURN_UNKNOWN_FUNCTION Trusted OS does not recognize this 471*4882a593Smuzhiyun * function. 472*4882a593Smuzhiyun * TEESMC_RETURN_OK Original call completed, result 473*4882a593Smuzhiyun * updated in the previously supplied. 474*4882a593Smuzhiyun * struct teesmc32_arg 475*4882a593Smuzhiyun * TEESMC_RETURN_RPC Call suspended by RPC call to normal 476*4882a593Smuzhiyun * world. 477*4882a593Smuzhiyun * TEESMC_RETURN_EBUSY Trusted OS busy, try again later. 478*4882a593Smuzhiyun * TEESMC_RETURN_ERESUME Resume failed, the opaque resume 479*4882a593Smuzhiyun * information was corrupt. 480*4882a593Smuzhiyun */ 481*4882a593Smuzhiyun #define TEESMC_FUNCID_RETURN_FROM_RPC 3 482*4882a593Smuzhiyun #define TEESMC32_CALL_RETURN_FROM_RPC \ 483*4882a593Smuzhiyun TEESMC_CALL_VAL(TEESMC_32, TEESMC_STD_CALL, TEESMC_OWNER_TRUSTED_OS, \ 484*4882a593Smuzhiyun TEESMC_FUNCID_RETURN_FROM_RPC) 485*4882a593Smuzhiyun /* Same as TEESMC32_CALL_RETURN_FROM_RPC but a "fast call". */ 486*4882a593Smuzhiyun #define TEESMC32_FASTCALL_RETURN_FROM_RPC \ 487*4882a593Smuzhiyun TEESMC_CALL_VAL(TEESMC_32, TEESMC_STD_CALL, TEESMC_OWNER_TRUSTED_OS, \ 488*4882a593Smuzhiyun TEESMC_FUNCID_RETURN_FROM_RPC) 489*4882a593Smuzhiyun 490*4882a593Smuzhiyun /* 491*4882a593Smuzhiyun * Resume from RPC (for example after processing an IRQ) 492*4882a593Smuzhiyun * 493*4882a593Smuzhiyun * See description of TEESMC32_CALL_RETURN_FROM_RPC above, used when 494*4882a593Smuzhiyun * it's a 64bit call that has returned. 495*4882a593Smuzhiyun */ 496*4882a593Smuzhiyun #define TEESMC64_CALL_RETURN_FROM_RPC \ 497*4882a593Smuzhiyun TEESMC_CALL_VAL(TEESMC_64, TEESMC_STD_CALL, TEESMC_OWNER_TRUSTED_OS, \ 498*4882a593Smuzhiyun TEESMC_FUNCID_RETURN_FROM_RPC) 499*4882a593Smuzhiyun /* Same as TEESMC64_CALL_RETURN_FROM_RPC but a "fast call". */ 500*4882a593Smuzhiyun #define TEESMC64_FASTCALL_RETURN_FROM_RPC \ 501*4882a593Smuzhiyun TEESMC_CALL_VAL(TEESMC_64, TEESMC_STD_CALL, TEESMC_OWNER_TRUSTED_OS, \ 502*4882a593Smuzhiyun TEESMC_FUNCID_RETURN_FROM_RPC) 503*4882a593Smuzhiyun 504*4882a593Smuzhiyun #define TEESMC_RETURN_RPC_PREFIX_MASK 0xFFFF0000 505*4882a593Smuzhiyun #define TEESMC_RETURN_RPC_PREFIX 0xFFFF0000 506*4882a593Smuzhiyun #define TEESMC_RETURN_RPC_FUNC_MASK 0x0000FFFF 507*4882a593Smuzhiyun 508*4882a593Smuzhiyun #define TEESMC_RETURN_GET_RPC_FUNC(ret) ((ret) & TEESMC_RETURN_RPC_FUNC_MASK) 509*4882a593Smuzhiyun 510*4882a593Smuzhiyun #define TEESMC_RPC_VAL(func) ((func) | TEESMC_RETURN_RPC_PREFIX) 511*4882a593Smuzhiyun 512*4882a593Smuzhiyun /* 513*4882a593Smuzhiyun * Allocate argument memory for RPC parameter passing. 514*4882a593Smuzhiyun * Argument memory is used to hold a struct teesmc32_arg. 515*4882a593Smuzhiyun * 516*4882a593Smuzhiyun * "Call" register usage: 517*4882a593Smuzhiyun * r0/x0 This value, TEESMC_RETURN_RPC_ALLOC 518*4882a593Smuzhiyun * r1/x1 Size in bytes of required argument memory 519*4882a593Smuzhiyun * r2-7/x2-7 Resume information, must be preserved 520*4882a593Smuzhiyun * 521*4882a593Smuzhiyun * "Return" register usage: 522*4882a593Smuzhiyun * r0/x0 SMC Function ID, TEESMC32_CALL_RETURN_FROM_RPC if it was an 523*4882a593Smuzhiyun * AArch32 SMC return or TEESMC64_CALL_RETURN_FROM_RPC for 524*4882a593Smuzhiyun * AArch64 SMC return 525*4882a593Smuzhiyun * r1/x1 Physical pointer to allocated argument memory, 0 if size 526*4882a593Smuzhiyun * was 0 or if memory can't be allocated 527*4882a593Smuzhiyun * r2-7/x2-7 Preserved 528*4882a593Smuzhiyun */ 529*4882a593Smuzhiyun #define TEESMC_RPC_FUNC_ALLOC_ARG 0 530*4882a593Smuzhiyun #define TEESMC_RETURN_RPC_ALLOC_ARG \ 531*4882a593Smuzhiyun TEESMC_RPC_VAL(TEESMC_RPC_FUNC_ALLOC_ARG) 532*4882a593Smuzhiyun 533*4882a593Smuzhiyun /* 534*4882a593Smuzhiyun * Allocate payload memory for RPC parameter passing. 535*4882a593Smuzhiyun * Payload memory is used to hold the memory referred to by struct 536*4882a593Smuzhiyun * teesmc32_param_memref. 537*4882a593Smuzhiyun * 538*4882a593Smuzhiyun * "Call" register usage: 539*4882a593Smuzhiyun * r0/x0 This value, TEESMC_RETURN_RPC_ALLOC 540*4882a593Smuzhiyun * r1/x1 Size in bytes of required payload memory 541*4882a593Smuzhiyun * r2-7/x2-7 Resume information, must be preserved 542*4882a593Smuzhiyun * 543*4882a593Smuzhiyun * "Return" register usage: 544*4882a593Smuzhiyun * r0/x0 SMC Function ID, TEESMC32_CALL_RETURN_FROM_RPC if it was an 545*4882a593Smuzhiyun * AArch32 SMC return or TEESMC64_CALL_RETURN_FROM_RPC for 546*4882a593Smuzhiyun * AArch64 SMC return 547*4882a593Smuzhiyun * r1/x1 Physical pointer to allocated payload memory, 0 if size 548*4882a593Smuzhiyun * was 0 or if memory can't be allocated 549*4882a593Smuzhiyun * r2-7/x2-7 Preserved 550*4882a593Smuzhiyun */ 551*4882a593Smuzhiyun #define TEESMC_RPC_FUNC_ALLOC_PAYLOAD 1 552*4882a593Smuzhiyun #define TEESMC_RETURN_RPC_ALLOC_PAYLOAD \ 553*4882a593Smuzhiyun TEESMC_RPC_VAL(TEESMC_RPC_FUNC_ALLOC_PAYLOAD) 554*4882a593Smuzhiyun 555*4882a593Smuzhiyun /* 556*4882a593Smuzhiyun * Free memory previously allocated by TEESMC_RETURN_RPC_ALLOC_ARG. 557*4882a593Smuzhiyun * 558*4882a593Smuzhiyun * "Call" register usage: 559*4882a593Smuzhiyun * r0/x0 This value, TEESMC_RETURN_RPC_FREE 560*4882a593Smuzhiyun * r1/x1 Physical pointer to previously allocated argument memory 561*4882a593Smuzhiyun * r2-7/x2-7 Resume information, must be preserved 562*4882a593Smuzhiyun * 563*4882a593Smuzhiyun * "Return" register usage: 564*4882a593Smuzhiyun * r0/x0 SMC Function ID, TEESMC32_CALL_RETURN_FROM_RPC if it was an 565*4882a593Smuzhiyun * AArch32 SMC return or TEESMC64_CALL_RETURN_FROM_RPC for 566*4882a593Smuzhiyun * AArch64 SMC return 567*4882a593Smuzhiyun * r1/x1 Not used 568*4882a593Smuzhiyun * r2-7/x2-7 Preserved 569*4882a593Smuzhiyun */ 570*4882a593Smuzhiyun #define TEESMC_RPC_FUNC_FREE_ARG 2 571*4882a593Smuzhiyun #define TEESMC_RETURN_RPC_FREE_ARG TEESMC_RPC_VAL(TEESMC_RPC_FUNC_FREE_ARG) 572*4882a593Smuzhiyun 573*4882a593Smuzhiyun /* 574*4882a593Smuzhiyun * Free memory previously allocated by TEESMC_RETURN_RPC_ALLOC_PAYLOAD. 575*4882a593Smuzhiyun * 576*4882a593Smuzhiyun * "Call" register usage: 577*4882a593Smuzhiyun * r0/x0 This value, TEESMC_RETURN_RPC_FREE 578*4882a593Smuzhiyun * r1/x1 Physical pointer to previously allocated payload memory 579*4882a593Smuzhiyun * r3-7/x3-7 Resume information, must be preserved 580*4882a593Smuzhiyun * 581*4882a593Smuzhiyun * "Return" register usage: 582*4882a593Smuzhiyun * r0/x0 SMC Function ID, TEESMC32_CALL_RETURN_FROM_RPC if it was an 583*4882a593Smuzhiyun * AArch32 SMC return or TEESMC64_CALL_RETURN_FROM_RPC for 584*4882a593Smuzhiyun * AArch64 SMC return 585*4882a593Smuzhiyun * r1-2/x1-2 Not used 586*4882a593Smuzhiyun * r3-7/x3-7 Preserved 587*4882a593Smuzhiyun */ 588*4882a593Smuzhiyun #define TEESMC_RPC_FUNC_FREE_PAYLOAD 3 589*4882a593Smuzhiyun #define TEESMC_RETURN_RPC_FREE_PAYLOAD \ 590*4882a593Smuzhiyun TEESMC_RPC_VAL(TEESMC_RPC_FUNC_FREE_PAYLOAD) 591*4882a593Smuzhiyun 592*4882a593Smuzhiyun /* 593*4882a593Smuzhiyun * Deliver an IRQ in normal world. 594*4882a593Smuzhiyun * 595*4882a593Smuzhiyun * "Call" register usage: 596*4882a593Smuzhiyun * r0/x0 TEESMC_RETURN_RPC_IRQ 597*4882a593Smuzhiyun * r1-7/x1-7 Resume information, must be preserved 598*4882a593Smuzhiyun * 599*4882a593Smuzhiyun * "Return" register usage: 600*4882a593Smuzhiyun * r0/x0 SMC Function ID, TEESMC32_CALL_RETURN_FROM_RPC if it was an 601*4882a593Smuzhiyun * AArch32 SMC return or TEESMC64_CALL_RETURN_FROM_RPC for 602*4882a593Smuzhiyun * AArch64 SMC return 603*4882a593Smuzhiyun * r1-7/x1-7 Preserved 604*4882a593Smuzhiyun */ 605*4882a593Smuzhiyun #define TEESMC_RPC_FUNC_IRQ 4 606*4882a593Smuzhiyun #define TEESMC_RETURN_RPC_IRQ TEESMC_RPC_VAL(TEESMC_RPC_FUNC_IRQ) 607*4882a593Smuzhiyun 608*4882a593Smuzhiyun /* 609*4882a593Smuzhiyun * Do an RPC request. The supplied struct teesmc{32,64}_arg tells which 610*4882a593Smuzhiyun * request to do and the paramters for the request. The following fields 611*4882a593Smuzhiyun * are used (the rest are unused): 612*4882a593Smuzhiyun * - cmd the Request ID 613*4882a593Smuzhiyun * - ret return value of the request, filled in by normal world 614*4882a593Smuzhiyun * - num_params number of parameters for the request 615*4882a593Smuzhiyun * - params the parameters 616*4882a593Smuzhiyun * - param_attrs attributes of the parameters 617*4882a593Smuzhiyun * 618*4882a593Smuzhiyun * "Call" register usage: 619*4882a593Smuzhiyun * r0/x0 TEESMC_RETURN_RPC_CMD 620*4882a593Smuzhiyun * r1/x1 Physical pointer to a struct teesmc32_arg if returning from 621*4882a593Smuzhiyun * a AArch32 SMC or a struct teesmc64_arg if returning from a 622*4882a593Smuzhiyun * AArch64 SMC, must be preserved, only the data should 623*4882a593Smuzhiyun * be updated 624*4882a593Smuzhiyun * r2-7/x2-7 Resume information, must be preserved 625*4882a593Smuzhiyun * 626*4882a593Smuzhiyun * "Return" register usage: 627*4882a593Smuzhiyun * r0/x0 SMC Function ID, TEESMC32_CALL_RETURN_FROM_RPC if it was an 628*4882a593Smuzhiyun * AArch32 SMC return or TEESMC64_CALL_RETURN_FROM_RPC for 629*4882a593Smuzhiyun * AArch64 SMC return 630*4882a593Smuzhiyun * r1-7/x1-7 Preserved 631*4882a593Smuzhiyun */ 632*4882a593Smuzhiyun #define TEESMC_RPC_FUNC_CMD 5 633*4882a593Smuzhiyun #define TEESMC_RETURN_RPC_CMD TEESMC_RPC_VAL(TEESMC_RPC_FUNC_CMD) 634*4882a593Smuzhiyun 635*4882a593Smuzhiyun 636*4882a593Smuzhiyun /* Returned in r0 */ 637*4882a593Smuzhiyun #define TEESMC_RETURN_UNKNOWN_FUNCTION 0xFFFFFFFF 638*4882a593Smuzhiyun 639*4882a593Smuzhiyun /* Returned in r0 only from Trusted OS functions */ 640*4882a593Smuzhiyun #define TEESMC_RETURN_OK 0x0 641*4882a593Smuzhiyun #define TEESMC_RETURN_EBUSY 0x1 642*4882a593Smuzhiyun #define TEESMC_RETURN_ERESUME 0x2 643*4882a593Smuzhiyun #define TEESMC_RETURN_EBADADDR 0x3 644*4882a593Smuzhiyun #define TEESMC_RETURN_EBADCMD 0x4 645*4882a593Smuzhiyun #define TEESMC_RETURN_IS_RPC(ret) \ 646*4882a593Smuzhiyun (((ret) & TEESMC_RETURN_RPC_PREFIX_MASK) == TEESMC_RETURN_RPC_PREFIX) 647*4882a593Smuzhiyun 648*4882a593Smuzhiyun typedef struct teesmc_meta_open_session t_teesmc_meta_open_session; 649*4882a593Smuzhiyun 650*4882a593Smuzhiyun void tee_smc_call(ARM_SMC_ARGS *param); 651*4882a593Smuzhiyun 652*4882a593Smuzhiyun #endif /* TEESMC_H */ 653