Jens Wiklander | 2b7216b | 2018-09-25 16:40:11 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: BSD-2-Clause */ |
| 2 | /* |
| 3 | * Copyright (c) 2015-2018, Linaro Limited |
| 4 | */ |
| 5 | |
| 6 | #ifndef _OPTEE_MSG_H |
| 7 | #define _OPTEE_MSG_H |
| 8 | |
| 9 | #include <linux/bitops.h> |
| 10 | #include <linux/types.h> |
| 11 | |
| 12 | /* |
| 13 | * This file defines the OP-TEE message protocol used to communicate with |
| 14 | * an instance of OP-TEE running in secure world. This file is based on |
| 15 | * https://github.com/OP-TEE/optee_os/blob/master/core/include/optee_msg.h |
| 16 | * and may need to be updated when introducing new features. |
| 17 | * |
| 18 | * This file is divided into three sections. |
| 19 | * 1. Formatting of messages. |
| 20 | * 2. Requests from normal world |
| 21 | * 3. Requests from secure world, Remote Procedure Call (RPC), handled by |
| 22 | * tee-supplicant. |
| 23 | */ |
| 24 | |
| 25 | /***************************************************************************** |
| 26 | * Part 1 - formatting of messages |
| 27 | *****************************************************************************/ |
| 28 | |
| 29 | #define OPTEE_MSG_ATTR_TYPE_NONE 0x0 |
| 30 | #define OPTEE_MSG_ATTR_TYPE_VALUE_INPUT 0x1 |
| 31 | #define OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT 0x2 |
| 32 | #define OPTEE_MSG_ATTR_TYPE_VALUE_INOUT 0x3 |
| 33 | #define OPTEE_MSG_ATTR_TYPE_RMEM_INPUT 0x5 |
| 34 | #define OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT 0x6 |
| 35 | #define OPTEE_MSG_ATTR_TYPE_RMEM_INOUT 0x7 |
| 36 | #define OPTEE_MSG_ATTR_TYPE_TMEM_INPUT 0x9 |
| 37 | #define OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT 0xa |
| 38 | #define OPTEE_MSG_ATTR_TYPE_TMEM_INOUT 0xb |
| 39 | |
| 40 | #define OPTEE_MSG_ATTR_TYPE_MASK GENMASK(7, 0) |
| 41 | |
| 42 | /* |
| 43 | * Meta parameter to be absorbed by the Secure OS and not passed |
| 44 | * to the Trusted Application. |
| 45 | * |
| 46 | * Currently only used with OPTEE_MSG_CMD_OPEN_SESSION. |
| 47 | */ |
| 48 | #define OPTEE_MSG_ATTR_META BIT(8) |
| 49 | |
| 50 | /* |
| 51 | * Pointer to a list of pages used to register user-defined SHM buffer. |
| 52 | * Used with OPTEE_MSG_ATTR_TYPE_TMEM_*. |
| 53 | * buf_ptr should point to the beginning of the buffer. Buffer will contain |
| 54 | * list of page addresses. OP-TEE core can reconstruct contiguous buffer from |
| 55 | * that page addresses list. Page addresses are stored as 64 bit values. |
| 56 | * Last entry on a page should point to the next page of buffer. |
| 57 | * Every entry in buffer should point to a 4k page beginning (12 least |
| 58 | * significant bits must be equal to zero). |
| 59 | * |
| 60 | * 12 least significant bints of optee_msg_param.u.tmem.buf_ptr should hold page |
| 61 | * offset of the user buffer. |
| 62 | * |
| 63 | * So, entries should be placed like members of this structure: |
| 64 | * |
| 65 | * struct page_data { |
| 66 | * uint64_t pages_array[OPTEE_MSG_NONCONTIG_PAGE_SIZE/sizeof(uint64_t) - 1]; |
| 67 | * uint64_t next_page_data; |
| 68 | * }; |
| 69 | * |
| 70 | * Structure is designed to exactly fit into the page size |
| 71 | * OPTEE_MSG_NONCONTIG_PAGE_SIZE which is a standard 4KB page. |
| 72 | * |
| 73 | * The size of 4KB is chosen because this is the smallest page size for ARM |
| 74 | * architectures. If REE uses larger pages, it should divide them to 4KB ones. |
| 75 | */ |
| 76 | #define OPTEE_MSG_ATTR_NONCONTIG BIT(9) |
| 77 | |
| 78 | /* |
| 79 | * Memory attributes for caching passed with temp memrefs. The actual value |
| 80 | * used is defined outside the message protocol with the exception of |
| 81 | * OPTEE_MSG_ATTR_CACHE_PREDEFINED which means the attributes already |
| 82 | * defined for the memory range should be used. If optee_smc.h is used as |
| 83 | * bearer of this protocol OPTEE_SMC_SHM_* is used for values. |
| 84 | */ |
| 85 | #define OPTEE_MSG_ATTR_CACHE_SHIFT 16 |
| 86 | #define OPTEE_MSG_ATTR_CACHE_MASK GENMASK(2, 0) |
| 87 | #define OPTEE_MSG_ATTR_CACHE_PREDEFINED 0 |
| 88 | |
| 89 | /* |
Jens Wiklander | 2b7216b | 2018-09-25 16:40:11 +0200 | [diff] [blame] | 90 | * Page size used in non-contiguous buffer entries |
| 91 | */ |
| 92 | #define OPTEE_MSG_NONCONTIG_PAGE_SIZE 4096 |
| 93 | |
| 94 | /** |
| 95 | * struct optee_msg_param_tmem - temporary memory reference parameter |
| 96 | * @buf_ptr: Address of the buffer |
| 97 | * @size: Size of the buffer |
| 98 | * @shm_ref: Temporary shared memory reference, pointer to a struct tee_shm |
| 99 | * |
| 100 | * Secure and normal world communicates pointers as physical address |
| 101 | * instead of the virtual address. This is because secure and normal world |
| 102 | * have completely independent memory mapping. Normal world can even have a |
| 103 | * hypervisor which need to translate the guest physical address (AKA IPA |
| 104 | * in ARM documentation) to a real physical address before passing the |
| 105 | * structure to secure world. |
| 106 | */ |
| 107 | struct optee_msg_param_tmem { |
| 108 | u64 buf_ptr; |
| 109 | u64 size; |
| 110 | u64 shm_ref; |
| 111 | }; |
| 112 | |
| 113 | /** |
| 114 | * struct optee_msg_param_rmem - registered memory reference parameter |
| 115 | * @offs: Offset into shared memory reference |
| 116 | * @size: Size of the buffer |
| 117 | * @shm_ref: Shared memory reference, pointer to a struct tee_shm |
| 118 | */ |
| 119 | struct optee_msg_param_rmem { |
| 120 | u64 offs; |
| 121 | u64 size; |
| 122 | u64 shm_ref; |
| 123 | }; |
| 124 | |
| 125 | /** |
| 126 | * struct optee_msg_param_value - opaque value parameter |
| 127 | * |
| 128 | * Value parameters are passed unchecked between normal and secure world. |
| 129 | */ |
| 130 | struct optee_msg_param_value { |
| 131 | u64 a; |
| 132 | u64 b; |
| 133 | u64 c; |
| 134 | }; |
| 135 | |
| 136 | /** |
| 137 | * struct optee_msg_param - parameter used together with struct optee_msg_arg |
| 138 | * @attr: attributes |
| 139 | * @tmem: parameter by temporary memory reference |
| 140 | * @rmem: parameter by registered memory reference |
| 141 | * @value: parameter by opaque value |
| 142 | * |
| 143 | * @attr & OPTEE_MSG_ATTR_TYPE_MASK indicates if tmem, rmem or value is used in |
| 144 | * the union. OPTEE_MSG_ATTR_TYPE_VALUE_* indicates value, |
| 145 | * OPTEE_MSG_ATTR_TYPE_TMEM_* indicates @tmem and |
| 146 | * OPTEE_MSG_ATTR_TYPE_RMEM_* indicates @rmem, |
| 147 | * OPTEE_MSG_ATTR_TYPE_NONE indicates that none of the members are used. |
| 148 | */ |
| 149 | struct optee_msg_param { |
| 150 | u64 attr; |
| 151 | union { |
| 152 | struct optee_msg_param_tmem tmem; |
| 153 | struct optee_msg_param_rmem rmem; |
| 154 | struct optee_msg_param_value value; |
| 155 | } u; |
| 156 | }; |
| 157 | |
| 158 | /** |
| 159 | * struct optee_msg_arg - call argument |
| 160 | * @cmd: Command, one of OPTEE_MSG_CMD_* or OPTEE_MSG_RPC_CMD_* |
| 161 | * @func: Trusted Application function, specific to the Trusted Application, |
| 162 | * used if cmd == OPTEE_MSG_CMD_INVOKE_COMMAND |
| 163 | * @session: In parameter for all OPTEE_MSG_CMD_* except |
| 164 | * OPTEE_MSG_CMD_OPEN_SESSION where it's an output parameter instead |
| 165 | * @cancel_id: Cancellation id, a unique value to identify this request |
| 166 | * @ret: return value |
| 167 | * @ret_origin: origin of the return value |
| 168 | * @num_params: number of parameters supplied to the OS Command |
| 169 | * @params: the parameters supplied to the OS Command |
| 170 | * |
| 171 | * All normal calls to Trusted OS uses this struct. If cmd requires further |
| 172 | * information than what these field holds it can be passed as a parameter |
| 173 | * tagged as meta (setting the OPTEE_MSG_ATTR_META bit in corresponding |
| 174 | * attrs field). All parameters tagged as meta has to come first. |
| 175 | * |
| 176 | * Temp memref parameters can be fragmented if supported by the Trusted OS |
| 177 | * (when optee_smc.h is bearer of this protocol this is indicated with |
| 178 | * OPTEE_SMC_SEC_CAP_UNREGISTERED_SHM). If a logical memref parameter is |
| 179 | * fragmented then has all but the last fragment the |
| 180 | * OPTEE_MSG_ATTR_FRAGMENT bit set in attrs. Even if a memref is fragmented |
| 181 | * it will still be presented as a single logical memref to the Trusted |
| 182 | * Application. |
| 183 | */ |
| 184 | struct optee_msg_arg { |
| 185 | u32 cmd; |
| 186 | u32 func; |
| 187 | u32 session; |
| 188 | u32 cancel_id; |
| 189 | u32 pad; |
| 190 | u32 ret; |
| 191 | u32 ret_origin; |
| 192 | u32 num_params; |
| 193 | |
| 194 | /* num_params tells the actual number of element in params */ |
| 195 | struct optee_msg_param params[0]; |
| 196 | }; |
| 197 | |
| 198 | /** |
| 199 | * OPTEE_MSG_GET_ARG_SIZE - return size of struct optee_msg_arg |
| 200 | * |
| 201 | * @num_params: Number of parameters embedded in the struct optee_msg_arg |
| 202 | * |
| 203 | * Returns the size of the struct optee_msg_arg together with the number |
| 204 | * of embedded parameters. |
| 205 | */ |
| 206 | #define OPTEE_MSG_GET_ARG_SIZE(num_params) \ |
| 207 | (sizeof(struct optee_msg_arg) + \ |
| 208 | sizeof(struct optee_msg_param) * (num_params)) |
| 209 | |
| 210 | /***************************************************************************** |
| 211 | * Part 2 - requests from normal world |
| 212 | *****************************************************************************/ |
| 213 | |
| 214 | /* |
| 215 | * Return the following UID if using API specified in this file without |
| 216 | * further extensions: |
| 217 | * 384fb3e0-e7f8-11e3-af63-0002a5d5c51b. |
| 218 | * Represented in 4 32-bit words in OPTEE_MSG_UID_0, OPTEE_MSG_UID_1, |
| 219 | * OPTEE_MSG_UID_2, OPTEE_MSG_UID_3. |
| 220 | */ |
| 221 | #define OPTEE_MSG_UID_0 0x384fb3e0 |
| 222 | #define OPTEE_MSG_UID_1 0xe7f811e3 |
| 223 | #define OPTEE_MSG_UID_2 0xaf630002 |
| 224 | #define OPTEE_MSG_UID_3 0xa5d5c51b |
| 225 | #define OPTEE_MSG_FUNCID_CALLS_UID 0xFF01 |
| 226 | |
| 227 | /* |
| 228 | * Returns 2.0 if using API specified in this file without further |
| 229 | * extensions. Represented in 2 32-bit words in OPTEE_MSG_REVISION_MAJOR |
| 230 | * and OPTEE_MSG_REVISION_MINOR |
| 231 | */ |
| 232 | #define OPTEE_MSG_REVISION_MAJOR 2 |
| 233 | #define OPTEE_MSG_REVISION_MINOR 0 |
| 234 | #define OPTEE_MSG_FUNCID_CALLS_REVISION 0xFF03 |
| 235 | |
| 236 | /* |
| 237 | * Get UUID of Trusted OS. |
| 238 | * |
| 239 | * Used by non-secure world to figure out which Trusted OS is installed. |
| 240 | * Note that returned UUID is the UUID of the Trusted OS, not of the API. |
| 241 | * |
| 242 | * Returns UUID in 4 32-bit words in the same way as |
| 243 | * OPTEE_MSG_FUNCID_CALLS_UID described above. |
| 244 | */ |
| 245 | #define OPTEE_MSG_OS_OPTEE_UUID_0 0x486178e0 |
| 246 | #define OPTEE_MSG_OS_OPTEE_UUID_1 0xe7f811e3 |
| 247 | #define OPTEE_MSG_OS_OPTEE_UUID_2 0xbc5e0002 |
| 248 | #define OPTEE_MSG_OS_OPTEE_UUID_3 0xa5d5c51b |
| 249 | #define OPTEE_MSG_FUNCID_GET_OS_UUID 0x0000 |
| 250 | |
| 251 | /* |
| 252 | * Get revision of Trusted OS. |
| 253 | * |
| 254 | * Used by non-secure world to figure out which version of the Trusted OS |
| 255 | * is installed. Note that the returned revision is the revision of the |
| 256 | * Trusted OS, not of the API. |
| 257 | * |
| 258 | * Returns revision in 2 32-bit words in the same way as |
| 259 | * OPTEE_MSG_CALLS_REVISION described above. |
| 260 | */ |
| 261 | #define OPTEE_MSG_FUNCID_GET_OS_REVISION 0x0001 |
| 262 | |
| 263 | /* |
| 264 | * Do a secure call with struct optee_msg_arg as argument |
| 265 | * The OPTEE_MSG_CMD_* below defines what goes in struct optee_msg_arg::cmd |
| 266 | * |
| 267 | * OPTEE_MSG_CMD_OPEN_SESSION opens a session to a Trusted Application. |
| 268 | * The first two parameters are tagged as meta, holding two value |
| 269 | * parameters to pass the following information: |
| 270 | * param[0].u.value.a-b uuid of Trusted Application |
| 271 | * param[1].u.value.a-b uuid of Client |
Etienne Carriere | a86ed3a | 2021-11-09 17:08:21 +0100 | [diff] [blame^] | 272 | * param[1].u.value.c Login class of client TEE_LOGIN_* |
Jens Wiklander | 2b7216b | 2018-09-25 16:40:11 +0200 | [diff] [blame] | 273 | * |
| 274 | * OPTEE_MSG_CMD_INVOKE_COMMAND invokes a command a previously opened |
| 275 | * session to a Trusted Application. struct optee_msg_arg::func is Trusted |
| 276 | * Application function, specific to the Trusted Application. |
| 277 | * |
| 278 | * OPTEE_MSG_CMD_CLOSE_SESSION closes a previously opened session to |
| 279 | * Trusted Application. |
| 280 | * |
| 281 | * OPTEE_MSG_CMD_CANCEL cancels a currently invoked command. |
| 282 | * |
| 283 | * OPTEE_MSG_CMD_REGISTER_SHM registers a shared memory reference. The |
| 284 | * information is passed as: |
| 285 | * [in] param[0].attr OPTEE_MSG_ATTR_TYPE_TMEM_INPUT |
| 286 | * [| OPTEE_MSG_ATTR_FRAGMENT] |
| 287 | * [in] param[0].u.tmem.buf_ptr physical address (of first fragment) |
| 288 | * [in] param[0].u.tmem.size size (of first fragment) |
| 289 | * [in] param[0].u.tmem.shm_ref holds shared memory reference |
| 290 | * ... |
| 291 | * The shared memory can optionally be fragmented, temp memrefs can follow |
| 292 | * each other with all but the last with the OPTEE_MSG_ATTR_FRAGMENT bit set. |
| 293 | * |
| 294 | * OPTEE_MSG_CMD_UNREGISTER_SHM unregisteres a previously registered shared |
| 295 | * memory reference. The information is passed as: |
| 296 | * [in] param[0].attr OPTEE_MSG_ATTR_TYPE_RMEM_INPUT |
| 297 | * [in] param[0].u.rmem.shm_ref holds shared memory reference |
| 298 | * [in] param[0].u.rmem.offs 0 |
| 299 | * [in] param[0].u.rmem.size 0 |
| 300 | */ |
| 301 | #define OPTEE_MSG_CMD_OPEN_SESSION 0 |
| 302 | #define OPTEE_MSG_CMD_INVOKE_COMMAND 1 |
| 303 | #define OPTEE_MSG_CMD_CLOSE_SESSION 2 |
| 304 | #define OPTEE_MSG_CMD_CANCEL 3 |
| 305 | #define OPTEE_MSG_CMD_REGISTER_SHM 4 |
| 306 | #define OPTEE_MSG_CMD_UNREGISTER_SHM 5 |
| 307 | #define OPTEE_MSG_FUNCID_CALL_WITH_ARG 0x0004 |
| 308 | |
| 309 | /***************************************************************************** |
| 310 | * Part 3 - Requests from secure world, RPC |
| 311 | *****************************************************************************/ |
| 312 | |
| 313 | /* |
| 314 | * All RPC is done with a struct optee_msg_arg as bearer of information, |
| 315 | * struct optee_msg_arg::arg holds values defined by OPTEE_MSG_RPC_CMD_* below |
| 316 | * |
| 317 | * RPC communication with tee-supplicant is reversed compared to normal |
| 318 | * client communication desribed above. The supplicant receives requests |
| 319 | * and sends responses. |
| 320 | */ |
| 321 | |
| 322 | /* |
| 323 | * Load a TA into memory, defined in tee-supplicant |
| 324 | */ |
| 325 | #define OPTEE_MSG_RPC_CMD_LOAD_TA 0 |
| 326 | |
| 327 | /* |
| 328 | * Reserved |
| 329 | */ |
| 330 | #define OPTEE_MSG_RPC_CMD_RPMB 1 |
| 331 | |
| 332 | /* |
| 333 | * File system access, defined in tee-supplicant |
| 334 | */ |
| 335 | #define OPTEE_MSG_RPC_CMD_FS 2 |
| 336 | |
| 337 | /* |
| 338 | * Get time |
| 339 | * |
| 340 | * Returns number of seconds and nano seconds since the Epoch, |
| 341 | * 1970-01-01 00:00:00 +0000 (UTC). |
| 342 | * |
| 343 | * [out] param[0].u.value.a Number of seconds |
| 344 | * [out] param[0].u.value.b Number of nano seconds. |
| 345 | */ |
| 346 | #define OPTEE_MSG_RPC_CMD_GET_TIME 3 |
| 347 | |
| 348 | /* |
| 349 | * Wait queue primitive, helper for secure world to implement a wait queue. |
| 350 | * |
| 351 | * If secure world need to wait for a secure world mutex it issues a sleep |
| 352 | * request instead of spinning in secure world. Conversely is a wakeup |
| 353 | * request issued when a secure world mutex with a thread waiting thread is |
| 354 | * unlocked. |
| 355 | * |
| 356 | * Waiting on a key |
| 357 | * [in] param[0].u.value.a OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP |
| 358 | * [in] param[0].u.value.b wait key |
| 359 | * |
| 360 | * Waking up a key |
| 361 | * [in] param[0].u.value.a OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP |
| 362 | * [in] param[0].u.value.b wakeup key |
| 363 | */ |
| 364 | #define OPTEE_MSG_RPC_CMD_WAIT_QUEUE 4 |
| 365 | #define OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP 0 |
| 366 | #define OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP 1 |
| 367 | |
| 368 | /* |
| 369 | * Suspend execution |
| 370 | * |
| 371 | * [in] param[0].value .a number of milliseconds to suspend |
| 372 | */ |
| 373 | #define OPTEE_MSG_RPC_CMD_SUSPEND 5 |
| 374 | |
| 375 | /* |
| 376 | * Allocate a piece of shared memory |
| 377 | * |
| 378 | * Shared memory can optionally be fragmented, to support that additional |
| 379 | * spare param entries are allocated to make room for eventual fragments. |
| 380 | * The spare param entries has .attr = OPTEE_MSG_ATTR_TYPE_NONE when |
| 381 | * unused. All returned temp memrefs except the last should have the |
| 382 | * OPTEE_MSG_ATTR_FRAGMENT bit set in the attr field. |
| 383 | * |
| 384 | * [in] param[0].u.value.a type of memory one of |
| 385 | * OPTEE_MSG_RPC_SHM_TYPE_* below |
| 386 | * [in] param[0].u.value.b requested size |
| 387 | * [in] param[0].u.value.c required alignment |
| 388 | * |
| 389 | * [out] param[0].u.tmem.buf_ptr physical address (of first fragment) |
| 390 | * [out] param[0].u.tmem.size size (of first fragment) |
| 391 | * [out] param[0].u.tmem.shm_ref shared memory reference |
| 392 | * ... |
| 393 | * [out] param[n].u.tmem.buf_ptr physical address |
| 394 | * [out] param[n].u.tmem.size size |
| 395 | * [out] param[n].u.tmem.shm_ref shared memory reference (same value |
| 396 | * as in param[n-1].u.tmem.shm_ref) |
| 397 | */ |
| 398 | #define OPTEE_MSG_RPC_CMD_SHM_ALLOC 6 |
| 399 | /* Memory that can be shared with a non-secure user space application */ |
| 400 | #define OPTEE_MSG_RPC_SHM_TYPE_APPL 0 |
| 401 | /* Memory only shared with non-secure kernel */ |
| 402 | #define OPTEE_MSG_RPC_SHM_TYPE_KERNEL 1 |
| 403 | |
| 404 | /* |
| 405 | * Free shared memory previously allocated with OPTEE_MSG_RPC_CMD_SHM_ALLOC |
| 406 | * |
| 407 | * [in] param[0].u.value.a type of memory one of |
| 408 | * OPTEE_MSG_RPC_SHM_TYPE_* above |
| 409 | * [in] param[0].u.value.b value of shared memory reference |
| 410 | * returned in param[0].u.tmem.shm_ref |
| 411 | * above |
| 412 | */ |
| 413 | #define OPTEE_MSG_RPC_CMD_SHM_FREE 7 |
| 414 | |
Jorge Ramirez-Ortiz | d30807d | 2021-01-25 14:28:40 +0200 | [diff] [blame] | 415 | /* |
| 416 | * Access a device on an i2c bus |
| 417 | * |
| 418 | * [in] param[0].u.value.a mode: RD(0), WR(1) |
| 419 | * [in] param[0].u.value.b i2c adapter |
| 420 | * [in] param[0].u.value.c i2c chip |
| 421 | * |
| 422 | * [in] param[1].u.value.a i2c control flags |
| 423 | * |
| 424 | * [in/out] memref[2] buffer to exchange the transfer data |
| 425 | * with the secure world |
| 426 | * |
| 427 | * [out] param[3].u.value.a bytes transferred by the driver |
| 428 | */ |
| 429 | #define OPTEE_MSG_RPC_CMD_I2C_TRANSFER 21 |
| 430 | /* I2C master transfer modes */ |
| 431 | #define OPTEE_MSG_RPC_CMD_I2C_TRANSFER_RD 0 |
| 432 | #define OPTEE_MSG_RPC_CMD_I2C_TRANSFER_WR 1 |
| 433 | /* I2C master control flags */ |
| 434 | #define OPTEE_MSG_RPC_CMD_I2C_FLAGS_TEN_BIT BIT(0) |
| 435 | |
Jens Wiklander | 2b7216b | 2018-09-25 16:40:11 +0200 | [diff] [blame] | 436 | #endif /* _OPTEE_MSG_H */ |