optee_msg.h 14.9 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) */
/*
 * Copyright (c) 2015-2019, Linaro Limited
 */
#ifndef _OPTEE_MSG_H
#define _OPTEE_MSG_H

#include <linux/bitops.h>
#include <linux/types.h>

/*
 * This file defines the OP-TEE message protocol used to communicate
 * with an instance of OP-TEE running in secure world.
 *
 * This file is divided into three sections.
 * 1. Formatting of messages.
 * 2. Requests from normal world
 * 3. Requests from secure world, Remote Procedure Call (RPC), handled by
 *    tee-supplicant.
 */

/*****************************************************************************
 * Part 1 - formatting of messages
 *****************************************************************************/

#define OPTEE_MSG_ATTR_TYPE_NONE		0x0
#define OPTEE_MSG_ATTR_TYPE_VALUE_INPUT		0x1
#define OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT	0x2
#define OPTEE_MSG_ATTR_TYPE_VALUE_INOUT		0x3
#define OPTEE_MSG_ATTR_TYPE_RMEM_INPUT		0x5
#define OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT		0x6
#define OPTEE_MSG_ATTR_TYPE_RMEM_INOUT		0x7
#define OPTEE_MSG_ATTR_TYPE_TMEM_INPUT		0x9
#define OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT		0xa
#define OPTEE_MSG_ATTR_TYPE_TMEM_INOUT		0xb

#define OPTEE_MSG_ATTR_TYPE_MASK		GENMASK(7, 0)

/*
 * Meta parameter to be absorbed by the Secure OS and not passed
 * to the Trusted Application.
 *
 * Currently only used with OPTEE_MSG_CMD_OPEN_SESSION.
 */
#define OPTEE_MSG_ATTR_META			BIT(8)

/*
 * Pointer to a list of pages used to register user-defined SHM buffer.
 * Used with OPTEE_MSG_ATTR_TYPE_TMEM_*.
 * buf_ptr should point to the beginning of the buffer. Buffer will contain
 * list of page addresses. OP-TEE core can reconstruct contiguous buffer from
 * that page addresses list. Page addresses are stored as 64 bit values.
 * Last entry on a page should point to the next page of buffer.
 * Every entry in buffer should point to a 4k page beginning (12 least
 * significant bits must be equal to zero).
 *
 * 12 least significant bints of optee_msg_param.u.tmem.buf_ptr should hold page
 * offset of the user buffer.
 *
 * So, entries should be placed like members of this structure:
 *
 * struct page_data {
 *   uint64_t pages_array[OPTEE_MSG_NONCONTIG_PAGE_SIZE/sizeof(uint64_t) - 1];
 *   uint64_t next_page_data;
 * };
 *
 * Structure is designed to exactly fit into the page size
 * OPTEE_MSG_NONCONTIG_PAGE_SIZE which is a standard 4KB page.
 *
 * The size of 4KB is chosen because this is the smallest page size for ARM
 * architectures. If REE uses larger pages, it should divide them to 4KB ones.
 */
#define OPTEE_MSG_ATTR_NONCONTIG		BIT(9)

/*
 * Memory attributes for caching passed with temp memrefs. The actual value
 * used is defined outside the message protocol with the exception of
 * OPTEE_MSG_ATTR_CACHE_PREDEFINED which means the attributes already
 * defined for the memory range should be used. If optee_smc.h is used as
 * bearer of this protocol OPTEE_SMC_SHM_* is used for values.
 */
#define OPTEE_MSG_ATTR_CACHE_SHIFT		16
#define OPTEE_MSG_ATTR_CACHE_MASK		GENMASK(2, 0)
#define OPTEE_MSG_ATTR_CACHE_PREDEFINED		0

/*
 * Same values as TEE_LOGIN_* from TEE Internal API
 */
#define OPTEE_MSG_LOGIN_PUBLIC			0x00000000
#define OPTEE_MSG_LOGIN_USER			0x00000001
#define OPTEE_MSG_LOGIN_GROUP			0x00000002
#define OPTEE_MSG_LOGIN_APPLICATION		0x00000004
#define OPTEE_MSG_LOGIN_APPLICATION_USER	0x00000005
#define OPTEE_MSG_LOGIN_APPLICATION_GROUP	0x00000006

/*
 * Page size used in non-contiguous buffer entries
 */
#define OPTEE_MSG_NONCONTIG_PAGE_SIZE		4096

/**
 * struct optee_msg_param_tmem - temporary memory reference parameter
 * @buf_ptr:	Address of the buffer
 * @size:	Size of the buffer
 * @shm_ref:	Temporary shared memory reference, pointer to a struct tee_shm
 *
 * Secure and normal world communicates pointers as physical address
 * instead of the virtual address. This is because secure and normal world
 * have completely independent memory mapping. Normal world can even have a
 * hypervisor which need to translate the guest physical address (AKA IPA
 * in ARM documentation) to a real physical address before passing the
 * structure to secure world.
 */
struct optee_msg_param_tmem {
	u64 buf_ptr;
	u64 size;
	u64 shm_ref;
};

/**
 * struct optee_msg_param_rmem - registered memory reference parameter
 * @offs:	Offset into shared memory reference
 * @size:	Size of the buffer
 * @shm_ref:	Shared memory reference, pointer to a struct tee_shm
 */
struct optee_msg_param_rmem {
	u64 offs;
	u64 size;
	u64 shm_ref;
};

/**
 * struct optee_msg_param_value - opaque value parameter
 *
 * Value parameters are passed unchecked between normal and secure world.
 */
struct optee_msg_param_value {
	u64 a;
	u64 b;
	u64 c;
};

/**
 * struct optee_msg_param - parameter used together with struct optee_msg_arg
 * @attr:	attributes
 * @tmem:	parameter by temporary memory reference
 * @rmem:	parameter by registered memory reference
 * @value:	parameter by opaque value
 *
 * @attr & OPTEE_MSG_ATTR_TYPE_MASK indicates if tmem, rmem or value is used in
 * the union. OPTEE_MSG_ATTR_TYPE_VALUE_* indicates value,
 * OPTEE_MSG_ATTR_TYPE_TMEM_* indicates @tmem and
 * OPTEE_MSG_ATTR_TYPE_RMEM_* indicates @rmem,
 * OPTEE_MSG_ATTR_TYPE_NONE indicates that none of the members are used.
 */
struct optee_msg_param {
	u64 attr;
	union {
		struct optee_msg_param_tmem tmem;
		struct optee_msg_param_rmem rmem;
		struct optee_msg_param_value value;
	} u;
};

/**
 * struct optee_msg_arg - call argument
 * @cmd: Command, one of OPTEE_MSG_CMD_* or OPTEE_MSG_RPC_CMD_*
 * @func: Trusted Application function, specific to the Trusted Application,
 *	     used if cmd == OPTEE_MSG_CMD_INVOKE_COMMAND
 * @session: In parameter for all OPTEE_MSG_CMD_* except
 *	     OPTEE_MSG_CMD_OPEN_SESSION where it's an output parameter instead
 * @cancel_id: Cancellation id, a unique value to identify this request
 * @ret: return value
 * @ret_origin: origin of the return value
 * @num_params: number of parameters supplied to the OS Command
 * @params: the parameters supplied to the OS Command
 *
 * All normal calls to Trusted OS uses this struct. If cmd requires further
 * information than what these field holds it can be passed as a parameter
 * tagged as meta (setting the OPTEE_MSG_ATTR_META bit in corresponding
 * attrs field). All parameters tagged as meta has to come first.
 *
 * Temp memref parameters can be fragmented if supported by the Trusted OS
 * (when optee_smc.h is bearer of this protocol this is indicated with
 * OPTEE_SMC_SEC_CAP_UNREGISTERED_SHM). If a logical memref parameter is
 * fragmented then has all but the last fragment the
 * OPTEE_MSG_ATTR_FRAGMENT bit set in attrs. Even if a memref is fragmented
 * it will still be presented as a single logical memref to the Trusted
 * Application.
 */
struct optee_msg_arg {
	u32 cmd;
	u32 func;
	u32 session;
	u32 cancel_id;
	u32 pad;
	u32 ret;
	u32 ret_origin;
	u32 num_params;

	/* num_params tells the actual number of element in params */
	struct optee_msg_param params[0];
};

/**
 * OPTEE_MSG_GET_ARG_SIZE - return size of struct optee_msg_arg
 *
 * @num_params: Number of parameters embedded in the struct optee_msg_arg
 *
 * Returns the size of the struct optee_msg_arg together with the number
 * of embedded parameters.
 */
#define OPTEE_MSG_GET_ARG_SIZE(num_params) \
	(sizeof(struct optee_msg_arg) + \
	 sizeof(struct optee_msg_param) * (num_params))

/*****************************************************************************
 * Part 2 - requests from normal world
 *****************************************************************************/

/*
 * Return the following UID if using API specified in this file without
 * further extensions:
 * 384fb3e0-e7f8-11e3-af63-0002a5d5c51b.
 * Represented in 4 32-bit words in OPTEE_MSG_UID_0, OPTEE_MSG_UID_1,
 * OPTEE_MSG_UID_2, OPTEE_MSG_UID_3.
 */
#define OPTEE_MSG_UID_0			0x384fb3e0
#define OPTEE_MSG_UID_1			0xe7f811e3
#define OPTEE_MSG_UID_2			0xaf630002
#define OPTEE_MSG_UID_3			0xa5d5c51b
#define OPTEE_MSG_FUNCID_CALLS_UID	0xFF01

/*
 * Returns 2.0 if using API specified in this file without further
 * extensions. Represented in 2 32-bit words in OPTEE_MSG_REVISION_MAJOR
 * and OPTEE_MSG_REVISION_MINOR
 */
#define OPTEE_MSG_REVISION_MAJOR	2
#define OPTEE_MSG_REVISION_MINOR	0
#define OPTEE_MSG_FUNCID_CALLS_REVISION	0xFF03

/*
 * Get UUID of Trusted OS.
 *
 * Used by non-secure world to figure out which Trusted OS is installed.
 * Note that returned UUID is the UUID of the Trusted OS, not of the API.
 *
 * Returns UUID in 4 32-bit words in the same way as
 * OPTEE_MSG_FUNCID_CALLS_UID described above.
 */
#define OPTEE_MSG_OS_OPTEE_UUID_0	0x486178e0
#define OPTEE_MSG_OS_OPTEE_UUID_1	0xe7f811e3
#define OPTEE_MSG_OS_OPTEE_UUID_2	0xbc5e0002
#define OPTEE_MSG_OS_OPTEE_UUID_3	0xa5d5c51b
#define OPTEE_MSG_FUNCID_GET_OS_UUID	0x0000

/*
 * Get revision of Trusted OS.
 *
 * Used by non-secure world to figure out which version of the Trusted OS
 * is installed. Note that the returned revision is the revision of the
 * Trusted OS, not of the API.
 *
 * Returns revision in 2 32-bit words in the same way as
 * OPTEE_MSG_CALLS_REVISION described above.
 */
#define OPTEE_MSG_FUNCID_GET_OS_REVISION	0x0001

/*
 * Do a secure call with struct optee_msg_arg as argument
 * The OPTEE_MSG_CMD_* below defines what goes in struct optee_msg_arg::cmd
 *
 * OPTEE_MSG_CMD_OPEN_SESSION opens a session to a Trusted Application.
 * The first two parameters are tagged as meta, holding two value
 * parameters to pass the following information:
 * param[0].u.value.a-b uuid of Trusted Application
 * param[1].u.value.a-b uuid of Client
 * param[1].u.value.c Login class of client OPTEE_MSG_LOGIN_*
 *
 * OPTEE_MSG_CMD_INVOKE_COMMAND invokes a command a previously opened
 * session to a Trusted Application.  struct optee_msg_arg::func is Trusted
 * Application function, specific to the Trusted Application.
 *
 * OPTEE_MSG_CMD_CLOSE_SESSION closes a previously opened session to
 * Trusted Application.
 *
 * OPTEE_MSG_CMD_CANCEL cancels a currently invoked command.
 *
 * OPTEE_MSG_CMD_REGISTER_SHM registers a shared memory reference. The
 * information is passed as:
 * [in] param[0].attr			OPTEE_MSG_ATTR_TYPE_TMEM_INPUT
 *					[| OPTEE_MSG_ATTR_FRAGMENT]
 * [in] param[0].u.tmem.buf_ptr		physical address (of first fragment)
 * [in] param[0].u.tmem.size		size (of first fragment)
 * [in] param[0].u.tmem.shm_ref		holds shared memory reference
 * ...
 * The shared memory can optionally be fragmented, temp memrefs can follow
 * each other with all but the last with the OPTEE_MSG_ATTR_FRAGMENT bit set.
 *
 * OPTEE_MSG_CMD_UNREGISTER_SHM unregisteres a previously registered shared
 * memory reference. The information is passed as:
 * [in] param[0].attr			OPTEE_MSG_ATTR_TYPE_RMEM_INPUT
 * [in] param[0].u.rmem.shm_ref		holds shared memory reference
 * [in] param[0].u.rmem.offs		0
 * [in] param[0].u.rmem.size		0
 */
#define OPTEE_MSG_CMD_OPEN_SESSION	0
#define OPTEE_MSG_CMD_INVOKE_COMMAND	1
#define OPTEE_MSG_CMD_CLOSE_SESSION	2
#define OPTEE_MSG_CMD_CANCEL		3
#define OPTEE_MSG_CMD_REGISTER_SHM	4
#define OPTEE_MSG_CMD_UNREGISTER_SHM	5
#define OPTEE_MSG_FUNCID_CALL_WITH_ARG	0x0004

/*****************************************************************************
 * Part 3 - Requests from secure world, RPC
 *****************************************************************************/

/*
 * All RPC is done with a struct optee_msg_arg as bearer of information,
 * struct optee_msg_arg::arg holds values defined by OPTEE_MSG_RPC_CMD_* below
 *
 * RPC communication with tee-supplicant is reversed compared to normal
 * client communication desribed above. The supplicant receives requests
 * and sends responses.
 */

/*
 * Load a TA into memory, defined in tee-supplicant
 */
#define OPTEE_MSG_RPC_CMD_LOAD_TA	0

/*
 * Reserved
 */
#define OPTEE_MSG_RPC_CMD_RPMB		1

/*
 * File system access, defined in tee-supplicant
 */
#define OPTEE_MSG_RPC_CMD_FS		2

/*
 * Get time
 *
 * Returns number of seconds and nano seconds since the Epoch,
 * 1970-01-01 00:00:00 +0000 (UTC).
 *
 * [out] param[0].u.value.a	Number of seconds
 * [out] param[0].u.value.b	Number of nano seconds.
 */
#define OPTEE_MSG_RPC_CMD_GET_TIME	3

/*
 * Wait queue primitive, helper for secure world to implement a wait queue.
 *
 * If secure world need to wait for a secure world mutex it issues a sleep
 * request instead of spinning in secure world. Conversely is a wakeup
 * request issued when a secure world mutex with a thread waiting thread is
 * unlocked.
 *
 * Waiting on a key
 * [in] param[0].u.value.a OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP
 * [in] param[0].u.value.b wait key
 *
 * Waking up a key
 * [in] param[0].u.value.a OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP
 * [in] param[0].u.value.b wakeup key
 */
#define OPTEE_MSG_RPC_CMD_WAIT_QUEUE	4
#define OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP	0
#define OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP	1

/*
 * Suspend execution
 *
 * [in] param[0].value	.a number of milliseconds to suspend
 */
#define OPTEE_MSG_RPC_CMD_SUSPEND	5

/*
 * Allocate a piece of shared memory
 *
 * Shared memory can optionally be fragmented, to support that additional
 * spare param entries are allocated to make room for eventual fragments.
 * The spare param entries has .attr = OPTEE_MSG_ATTR_TYPE_NONE when
 * unused. All returned temp memrefs except the last should have the
 * OPTEE_MSG_ATTR_FRAGMENT bit set in the attr field.
 *
 * [in]  param[0].u.value.a		type of memory one of
 *					OPTEE_MSG_RPC_SHM_TYPE_* below
 * [in]  param[0].u.value.b		requested size
 * [in]  param[0].u.value.c		required alignment
 *
 * [out] param[0].u.tmem.buf_ptr	physical address (of first fragment)
 * [out] param[0].u.tmem.size		size (of first fragment)
 * [out] param[0].u.tmem.shm_ref	shared memory reference
 * ...
 * [out] param[n].u.tmem.buf_ptr	physical address
 * [out] param[n].u.tmem.size		size
 * [out] param[n].u.tmem.shm_ref	shared memory reference (same value
 *					as in param[n-1].u.tmem.shm_ref)
 */
#define OPTEE_MSG_RPC_CMD_SHM_ALLOC	6
/* Memory that can be shared with a non-secure user space application */
#define OPTEE_MSG_RPC_SHM_TYPE_APPL	0
/* Memory only shared with non-secure kernel */
#define OPTEE_MSG_RPC_SHM_TYPE_KERNEL	1

/*
 * Free shared memory previously allocated with OPTEE_MSG_RPC_CMD_SHM_ALLOC
 *
 * [in]  param[0].u.value.a		type of memory one of
 *					OPTEE_MSG_RPC_SHM_TYPE_* above
 * [in]  param[0].u.value.b		value of shared memory reference
 *					returned in param[0].u.tmem.shm_ref
 *					above
 */
#define OPTEE_MSG_RPC_CMD_SHM_FREE	7

/*
 * Access a device on an i2c bus
 *
 * [in]  param[0].u.value.a		mode: RD(0), WR(1)
 * [in]  param[0].u.value.b		i2c adapter
 * [in]  param[0].u.value.c		i2c chip
 *
 * [in]  param[1].u.value.a		i2c control flags
 *
 * [in/out] memref[2]			buffer to exchange the transfer data
 *					with the secure world
 *
 * [out]  param[3].u.value.a		bytes transferred by the driver
 */
#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER 21
/* I2C master transfer modes */
#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER_RD 0
#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER_WR 1
/* I2C master control flags */
#define OPTEE_MSG_RPC_CMD_I2C_FLAGS_TEN_BIT  BIT(0)

#endif /* _OPTEE_MSG_H */