|
| 1 | +/* SPDX-License-Identifier: BSD-2-Clause */ |
| 2 | +/* |
| 3 | + * Copyright (c) 2015-2020, Linaro Limited |
| 4 | + */ |
| 5 | +#ifndef _OPTEE_MSG_H |
| 6 | +#define _OPTEE_MSG_H |
| 7 | + |
| 8 | +/* |
| 9 | + * TODO: Zephyr has similar macros defined in stdint.h and called UINT32_C, |
| 10 | + * UINT64_C etc. This should be refactored to use macro from Zephyr. |
| 11 | + */ |
| 12 | +#define U(v) v ## U |
| 13 | + |
| 14 | +/* |
| 15 | + * This file defines the OP-TEE message protocol used to communicate |
| 16 | + * with an instance of OP-TEE running in secure world. |
| 17 | + */ |
| 18 | + |
| 19 | +/***************************************************************************** |
| 20 | + * Part 1 - formatting of messages |
| 21 | + *****************************************************************************/ |
| 22 | + |
| 23 | +#define OPTEE_MSG_ATTR_TYPE_NONE U(0x0) |
| 24 | +#define OPTEE_MSG_ATTR_TYPE_VALUE_INPUT U(0x1) |
| 25 | +#define OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT U(0x2) |
| 26 | +#define OPTEE_MSG_ATTR_TYPE_VALUE_INOUT U(0x3) |
| 27 | +#define OPTEE_MSG_ATTR_TYPE_RMEM_INPUT U(0x5) |
| 28 | +#define OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT U(0x6) |
| 29 | +#define OPTEE_MSG_ATTR_TYPE_RMEM_INOUT U(0x7) |
| 30 | +#define OPTEE_MSG_ATTR_TYPE_FMEM_INPUT OPTEE_MSG_ATTR_TYPE_RMEM_INPUT |
| 31 | +#define OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT |
| 32 | +#define OPTEE_MSG_ATTR_TYPE_FMEM_INOUT OPTEE_MSG_ATTR_TYPE_RMEM_INOUT |
| 33 | +#define OPTEE_MSG_ATTR_TYPE_TMEM_INPUT U(0x9) |
| 34 | +#define OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT U(0xa) |
| 35 | +#define OPTEE_MSG_ATTR_TYPE_TMEM_INOUT U(0xb) |
| 36 | + |
| 37 | +#define OPTEE_MSG_ATTR_TYPE_MASK GENMASK(7, 0) |
| 38 | + |
| 39 | +/* |
| 40 | + * Meta parameter to be absorbed by the Secure OS and not passed |
| 41 | + * to the Trusted Application. |
| 42 | + * |
| 43 | + * Currently only used with OPTEE_MSG_CMD_OPEN_SESSION. |
| 44 | + */ |
| 45 | +#define OPTEE_MSG_ATTR_META BIT(8) |
| 46 | + |
| 47 | +/* |
| 48 | + * Pointer to a list of pages used to register user-defined SHM buffer. |
| 49 | + * Used with OPTEE_MSG_ATTR_TYPE_TMEM_*. |
| 50 | + * buf_ptr should point to the beginning of the buffer. Buffer will contain |
| 51 | + * list of page addresses. OP-TEE core can reconstruct contiguous buffer from |
| 52 | + * that page addresses list. Page addresses are stored as 64 bit values. |
| 53 | + * Last entry on a page should point to the next page of buffer. |
| 54 | + * Every entry in buffer should point to a 4k page beginning (12 least |
| 55 | + * significant bits must be equal to zero). |
| 56 | + * |
| 57 | + * 12 least significant bits of optee_msg_param.u.tmem.buf_ptr should hold |
| 58 | + * page offset of user buffer. |
| 59 | + * |
| 60 | + * So, entries should be placed like members of this structure: |
| 61 | + * |
| 62 | + * struct page_data { |
| 63 | + * uint64_t pages_array[OPTEE_MSG_NONCONTIG_PAGE_SIZE/sizeof(uint64_t) - 1]; |
| 64 | + * uint64_t next_page_data; |
| 65 | + * }; |
| 66 | + * |
| 67 | + * Structure is designed to exactly fit into the page size |
| 68 | + * OPTEE_MSG_NONCONTIG_PAGE_SIZE which is a standard 4KB page. |
| 69 | + * |
| 70 | + * The size of 4KB is chosen because this is the smallest page size for ARM |
| 71 | + * architectures. If REE uses larger pages, it should divide them to 4KB ones. |
| 72 | + */ |
| 73 | +#define OPTEE_MSG_ATTR_NONCONTIG BIT(9) |
| 74 | + |
| 75 | +/* |
| 76 | + * Memory attributes for caching passed with temp memrefs. The actual value |
| 77 | + * used is defined outside the message protocol with the exception of |
| 78 | + * OPTEE_MSG_ATTR_CACHE_PREDEFINED which means the attributes already |
| 79 | + * defined for the memory range should be used. If optee_smc.h is used as |
| 80 | + * bearer of this protocol OPTEE_SMC_SHM_* is used for values. |
| 81 | + */ |
| 82 | +#define OPTEE_MSG_ATTR_CACHE_SHIFT U(16) |
| 83 | +#define OPTEE_MSG_ATTR_CACHE_MASK GENMASK(2, 0) |
| 84 | +#define OPTEE_MSG_ATTR_CACHE_PREDEFINED U(0) |
| 85 | + |
| 86 | +/* |
| 87 | + * Same values as TEE_LOGIN_* from TEE Internal API |
| 88 | + */ |
| 89 | +#define OPTEE_MSG_LOGIN_PUBLIC U(0x00000000) |
| 90 | +#define OPTEE_MSG_LOGIN_USER U(0x00000001) |
| 91 | +#define OPTEE_MSG_LOGIN_GROUP U(0x00000002) |
| 92 | +#define OPTEE_MSG_LOGIN_APPLICATION U(0x00000004) |
| 93 | +#define OPTEE_MSG_LOGIN_APPLICATION_USER U(0x00000005) |
| 94 | +#define OPTEE_MSG_LOGIN_APPLICATION_GROUP U(0x00000006) |
| 95 | + |
| 96 | +/* |
| 97 | + * Page size used in non-contiguous buffer entries |
| 98 | + */ |
| 99 | +#define OPTEE_MSG_NONCONTIG_PAGE_SIZE U(4096) |
| 100 | + |
| 101 | +#define OPTEE_MSG_FMEM_INVALID_GLOBAL_ID 0xffffffffffffffff |
| 102 | + |
| 103 | +#ifndef __ASSEMBLER__ |
| 104 | +/** |
| 105 | + * struct optee_msg_param_tmem - temporary memory reference parameter |
| 106 | + * @buf_ptr: Address of the buffer |
| 107 | + * @size: Size of the buffer |
| 108 | + * @shm_ref: Temporary shared memory reference, pointer to a struct tee_shm |
| 109 | + * |
| 110 | + * Secure and normal world communicates pointers as physical address |
| 111 | + * instead of the virtual address. This is because secure and normal world |
| 112 | + * have completely independent memory mapping. Normal world can even have a |
| 113 | + * hypervisor which need to translate the guest physical address (AKA IPA |
| 114 | + * in ARM documentation) to a real physical address before passing the |
| 115 | + * structure to secure world. |
| 116 | + */ |
| 117 | +struct optee_msg_param_tmem { |
| 118 | + uint64_t buf_ptr; |
| 119 | + uint64_t size; |
| 120 | + uint64_t shm_ref; |
| 121 | +}; |
| 122 | + |
| 123 | +/** |
| 124 | + * struct optee_msg_param_rmem - registered memory reference parameter |
| 125 | + * @offs: Offset into shared memory reference |
| 126 | + * @size: Size of the buffer |
| 127 | + * @shm_ref: Shared memory reference, pointer to a struct tee_shm |
| 128 | + */ |
| 129 | +struct optee_msg_param_rmem { |
| 130 | + uint64_t offs; |
| 131 | + uint64_t size; |
| 132 | + uint64_t shm_ref; |
| 133 | +}; |
| 134 | + |
| 135 | +/** |
| 136 | + * struct optee_msg_param_fmem - FF-A memory reference parameter |
| 137 | + * @offs_lower: Lower bits of offset into shared memory reference |
| 138 | + * @offs_upper: Upper bits of offset into shared memory reference |
| 139 | + * @internal_offs: Internal offset into the first page of shared memory |
| 140 | + * reference |
| 141 | + * @size: Size of the buffer |
| 142 | + * @global_id: Global identifier of the shared memory |
| 143 | + */ |
| 144 | +struct optee_msg_param_fmem { |
| 145 | + uint32_t offs_low; |
| 146 | + uint16_t offs_high; |
| 147 | + uint16_t internal_offs; |
| 148 | + uint64_t size; |
| 149 | + uint64_t global_id; |
| 150 | +}; |
| 151 | + |
| 152 | +/** |
| 153 | + * struct optee_msg_param_value - opaque value parameter |
| 154 | + * |
| 155 | + * Value parameters are passed unchecked between normal and secure world. |
| 156 | + */ |
| 157 | +struct optee_msg_param_value { |
| 158 | + uint64_t a; |
| 159 | + uint64_t b; |
| 160 | + uint64_t c; |
| 161 | +}; |
| 162 | + |
| 163 | +/** |
| 164 | + * struct optee_msg_param - parameter used together with struct optee_msg_arg |
| 165 | + * @attr: attributes |
| 166 | + * @tmem: parameter by temporary memory reference |
| 167 | + * @rmem: parameter by registered memory reference |
| 168 | + * @fmem: parameter by FF-A registered memory reference |
| 169 | + * @value: parameter by opaque value |
| 170 | + * |
| 171 | + * @attr & OPTEE_MSG_ATTR_TYPE_MASK indicates if tmem, rmem or value is used in |
| 172 | + * the union. OPTEE_MSG_ATTR_TYPE_VALUE_* indicates value, |
| 173 | + * OPTEE_MSG_ATTR_TYPE_TMEM_* indicates @tmem and |
| 174 | + * OPTEE_MSG_ATTR_TYPE_RMEM_* or the alias PTEE_MSG_ATTR_TYPE_FMEM_* indicates |
| 175 | + * @rmem or @fmem depending on the conduit. |
| 176 | + * OPTEE_MSG_ATTR_TYPE_NONE indicates that none of the members are used. |
| 177 | + */ |
| 178 | +struct optee_msg_param { |
| 179 | + uint64_t attr; |
| 180 | + union { |
| 181 | + struct optee_msg_param_tmem tmem; |
| 182 | + struct optee_msg_param_rmem rmem; |
| 183 | + struct optee_msg_param_fmem fmem; |
| 184 | + struct optee_msg_param_value value; |
| 185 | + } u; |
| 186 | +}; |
| 187 | + |
| 188 | +/** |
| 189 | + * struct optee_msg_arg - call argument |
| 190 | + * @cmd: Command, one of OPTEE_MSG_CMD_* or OPTEE_MSG_RPC_CMD_* |
| 191 | + * @func: Trusted Application function, specific to the Trusted Application, |
| 192 | + * used if cmd == OPTEE_MSG_CMD_INVOKE_COMMAND |
| 193 | + * @session: In parameter for all OPTEE_MSG_CMD_* except |
| 194 | + * OPTEE_MSG_CMD_OPEN_SESSION where it's an output parameter instead |
| 195 | + * @cancel_id: Cancellation id, a unique value to identify this request |
| 196 | + * @ret: return value |
| 197 | + * @ret_origin: origin of the return value |
| 198 | + * @num_params: number of parameters supplied to the OS Command |
| 199 | + * @params: the parameters supplied to the OS Command |
| 200 | + * |
| 201 | + * All normal calls to Trusted OS uses this struct. If cmd requires further |
| 202 | + * information than what these fields hold it can be passed as a parameter |
| 203 | + * tagged as meta (setting the OPTEE_MSG_ATTR_META bit in corresponding |
| 204 | + * attrs field). All parameters tagged as meta have to come first. |
| 205 | + */ |
| 206 | +struct optee_msg_arg { |
| 207 | + uint32_t cmd; |
| 208 | + uint32_t func; |
| 209 | + uint32_t session; |
| 210 | + uint32_t cancel_id; |
| 211 | + uint32_t pad; |
| 212 | + uint32_t ret; |
| 213 | + uint32_t ret_origin; |
| 214 | + uint32_t num_params; |
| 215 | + |
| 216 | + /* num_params tells the actual number of element in params */ |
| 217 | + struct optee_msg_param params[]; |
| 218 | +}; |
| 219 | + |
| 220 | +/** |
| 221 | + * OPTEE_MSG_GET_ARG_SIZE - return size of struct optee_msg_arg |
| 222 | + * |
| 223 | + * @num_params: Number of parameters embedded in the struct optee_msg_arg |
| 224 | + * |
| 225 | + * Returns the size of the struct optee_msg_arg together with the number |
| 226 | + * of embedded parameters. |
| 227 | + */ |
| 228 | +#define OPTEE_MSG_GET_ARG_SIZE(num_params) \ |
| 229 | + (sizeof(struct optee_msg_arg) + \ |
| 230 | + sizeof(struct optee_msg_param) * (num_params)) |
| 231 | + |
| 232 | +/* |
| 233 | + * Defines the maximum value of @num_params that can be passed to |
| 234 | + * OPTEE_MSG_GET_ARG_SIZE without a risk of crossing page boundary. |
| 235 | + */ |
| 236 | +#define OPTEE_MSG_MAX_NUM_PARAMS \ |
| 237 | + ((OPTEE_MSG_NONCONTIG_PAGE_SIZE - sizeof(struct optee_msg_arg)) / \ |
| 238 | + sizeof(struct optee_msg_param)) |
| 239 | + |
| 240 | +#endif /*__ASSEMBLER__*/ |
| 241 | + |
| 242 | +/***************************************************************************** |
| 243 | + * Part 2 - requests from normal world |
| 244 | + *****************************************************************************/ |
| 245 | + |
| 246 | +/* |
| 247 | + * Return the following UID if using API specified in this file without |
| 248 | + * further extensions: |
| 249 | + * 384fb3e0-e7f8-11e3-af63-0002a5d5c51b. |
| 250 | + * Represented in 4 32-bit words in OPTEE_MSG_UID_0, OPTEE_MSG_UID_1, |
| 251 | + * OPTEE_MSG_UID_2, OPTEE_MSG_UID_3. |
| 252 | + */ |
| 253 | +#define OPTEE_MSG_UID_0 U(0x384fb3e0) |
| 254 | +#define OPTEE_MSG_UID_1 U(0xe7f811e3) |
| 255 | +#define OPTEE_MSG_UID_2 U(0xaf630002) |
| 256 | +#define OPTEE_MSG_UID_3 U(0xa5d5c51b) |
| 257 | +#define OPTEE_MSG_FUNCID_CALLS_UID U(0xFF01) |
| 258 | + |
| 259 | +/* |
| 260 | + * Returns 2.0 if using API specified in this file without further |
| 261 | + * extensions. Represented in 2 32-bit words in OPTEE_MSG_REVISION_MAJOR |
| 262 | + * and OPTEE_MSG_REVISION_MINOR |
| 263 | + */ |
| 264 | +#define OPTEE_MSG_REVISION_MAJOR U(2) |
| 265 | +#define OPTEE_MSG_REVISION_MINOR U(0) |
| 266 | +#define OPTEE_MSG_FUNCID_CALLS_REVISION U(0xFF03) |
| 267 | + |
| 268 | +/* |
| 269 | + * Get UUID of Trusted OS. |
| 270 | + * |
| 271 | + * Used by non-secure world to figure out which Trusted OS is installed. |
| 272 | + * Note that returned UUID is the UUID of the Trusted OS, not of the API. |
| 273 | + * |
| 274 | + * Returns UUID in 4 32-bit words in the same way as |
| 275 | + * OPTEE_MSG_FUNCID_CALLS_UID described above. |
| 276 | + */ |
| 277 | +#define OPTEE_MSG_OS_OPTEE_UUID_0 U(0x486178e0) |
| 278 | +#define OPTEE_MSG_OS_OPTEE_UUID_1 U(0xe7f811e3) |
| 279 | +#define OPTEE_MSG_OS_OPTEE_UUID_2 U(0xbc5e0002) |
| 280 | +#define OPTEE_MSG_OS_OPTEE_UUID_3 U(0xa5d5c51b) |
| 281 | +#define OPTEE_MSG_FUNCID_GET_OS_UUID U(0x0000) |
| 282 | + |
| 283 | +/* |
| 284 | + * Get revision of Trusted OS. |
| 285 | + * |
| 286 | + * Used by non-secure world to figure out which version of the Trusted OS |
| 287 | + * is installed. Note that the returned revision is the revision of the |
| 288 | + * Trusted OS, not of the API. |
| 289 | + * |
| 290 | + * Returns revision in 2 32-bit words in the same way as |
| 291 | + * OPTEE_MSG_CALLS_REVISION described above. |
| 292 | + */ |
| 293 | +#define OPTEE_MSG_FUNCID_GET_OS_REVISION U(0x0001) |
| 294 | + |
| 295 | +/* |
| 296 | + * Do a secure call with struct optee_msg_arg as argument |
| 297 | + * The OPTEE_MSG_CMD_* below defines what goes in struct optee_msg_arg::cmd |
| 298 | + * |
| 299 | + * OPTEE_MSG_CMD_OPEN_SESSION opens a session to a Trusted Application. |
| 300 | + * The first two parameters are tagged as meta, holding two value |
| 301 | + * parameters to pass the following information: |
| 302 | + * param[0].u.value.a-b uuid of Trusted Application |
| 303 | + * param[1].u.value.a-b uuid of Client |
| 304 | + * param[1].u.value.c Login class of client OPTEE_MSG_LOGIN_* |
| 305 | + * |
| 306 | + * OPTEE_MSG_CMD_INVOKE_COMMAND invokes a command a previously opened |
| 307 | + * session to a Trusted Application. struct optee_msg_arg::func is Trusted |
| 308 | + * Application function, specific to the Trusted Application. |
| 309 | + * |
| 310 | + * OPTEE_MSG_CMD_CLOSE_SESSION closes a previously opened session to |
| 311 | + * Trusted Application. |
| 312 | + * |
| 313 | + * OPTEE_MSG_CMD_CANCEL cancels a currently invoked command. |
| 314 | + * |
| 315 | + * OPTEE_MSG_CMD_REGISTER_SHM registers a shared memory reference. The |
| 316 | + * information is passed as: |
| 317 | + * [in] param[0].attr OPTEE_MSG_ATTR_TYPE_TMEM_INPUT |
| 318 | + * [| OPTEE_MSG_ATTR_NONCONTIG] |
| 319 | + * [in] param[0].u.tmem.buf_ptr physical address (of first fragment) |
| 320 | + * [in] param[0].u.tmem.size size (of first fragment) |
| 321 | + * [in] param[0].u.tmem.shm_ref holds shared memory reference |
| 322 | + * |
| 323 | + * OPTEE_MSG_CMD_UNREGISTER_SHM unregisteres a previously registered shared |
| 324 | + * memory reference. The information is passed as: |
| 325 | + * [in] param[0].attr OPTEE_MSG_ATTR_TYPE_RMEM_INPUT |
| 326 | + * [in] param[0].u.rmem.shm_ref holds shared memory reference |
| 327 | + * [in] param[0].u.rmem.offs 0 |
| 328 | + * [in] param[0].u.rmem.size 0 |
| 329 | + * |
| 330 | + * OPTEE_MSG_CMD_DO_BOTTOM_HALF does the scheduled bottom half processing |
| 331 | + * of a driver. |
| 332 | + * |
| 333 | + * OPTEE_MSG_CMD_STOP_ASYNC_NOTIF informs secure world that from now is |
| 334 | + * normal world unable to process asynchronous notifications. Typically |
| 335 | + * used when the driver is shut down. |
| 336 | + */ |
| 337 | +#define OPTEE_MSG_CMD_OPEN_SESSION U(0) |
| 338 | +#define OPTEE_MSG_CMD_INVOKE_COMMAND U(1) |
| 339 | +#define OPTEE_MSG_CMD_CLOSE_SESSION U(2) |
| 340 | +#define OPTEE_MSG_CMD_CANCEL U(3) |
| 341 | +#define OPTEE_MSG_CMD_REGISTER_SHM U(4) |
| 342 | +#define OPTEE_MSG_CMD_UNREGISTER_SHM U(5) |
| 343 | +#define OPTEE_MSG_CMD_DO_BOTTOM_HALF U(6) |
| 344 | +#define OPTEE_MSG_CMD_STOP_ASYNC_NOTIF U(7) |
| 345 | +#define OPTEE_MSG_FUNCID_CALL_WITH_ARG U(0x0004) |
| 346 | + |
| 347 | +#endif /* _OPTEE_MSG_H */ |
0 commit comments