aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Wiklander <jens.wiklander@linaro.org>2020-06-02 17:58:28 +0200
committerJérôme Forissier <jerome@forissier.org>2020-07-20 13:21:16 +0200
commitc13d4bd7d4d863445689a1e6a2ee1e2ba2e4cfce (patch)
tree83ebbd1523d8c1dd166c4df390dccd277713b18f
parente0e3828a958f41a71aa426beb1bc4586c5a51790 (diff)
core: add optee_ffa.h defining the OP-TEE ABI for FF-A
Adds optee_ffa.h which defines the OP-TEE ABI when Arm Platform Security Architecture Firmware Framework for Arm V8-A [1] is used as transport instead of raw proprietary SMCs. This ABI where OP-TEE specific implementation is used to fill the implementation specific gaps in the specification is called OP-TEE FF-A, or sometimes just FF-A. A new memref type, struct optee_msg_param_fmem, is added to carry information needed to create new shared memory mobjs. Link: [1] https://static.docs.arm.com/den0077/a/DEN0077A_PSA_Firmware_Framework_Arm_v8-A_1.0_EAC.pdf Acked-by: Etienne Carriere <etienne.carriere@linaro.org> Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
-rw-r--r--core/arch/arm/include/optee_ffa.h201
-rw-r--r--core/include/optee_msg.h49
2 files changed, 237 insertions, 13 deletions
diff --git a/core/arch/arm/include/optee_ffa.h b/core/arch/arm/include/optee_ffa.h
new file mode 100644
index 00000000..8498fbab
--- /dev/null
+++ b/core/arch/arm/include/optee_ffa.h
@@ -0,0 +1,201 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Copyright (c) 2019, Linaro Limited
+ */
+
+/*
+ * This file is exported by OP-TEE and is kept in sync between secure world
+ * and normal world drivers. We're using ARM FF-A 1.0 EAC specification.
+ */
+
+#ifndef __OPTEE_FFA_H
+#define __OPTEE_FFA_H
+
+#include <ffa.h>
+
+/*
+ * Normal world sends requests with FFA_MSG_SEND_DIRECT_REQ and
+ * responses are returned with FFA_MSG_SEND_DIRECT_RESP for normal
+ * messages.
+ *
+ * All requests with FFA_MSG_SEND_DIRECT_REQ and FFA_MSG_SEND_DIRECT_RESP
+ * are using the AArch32 SMC calling convention with register usage as
+ * defined in FF-A specification:
+ * w0: Function ID (0x8400006F or 0x84000070)
+ * w1: Source/Destination IDs
+ * w2: Reserved (MBZ)
+ * w3-w7: Implementation defined, free to be used below
+ */
+
+#define OPTEE_FFA_VERSION_MAJOR UINT32_C(0)
+#define OPTEE_FFA_VERSION_MINOR UINT32_C(9)
+
+#define OPTEE_FFA_BLOCKING_CALL(id) UINT32_C(id)
+#define OPTEE_FFA_YIELDING_CALL_BIT 31
+#define OPTEE_FFA_YIELDING_CALL(id) (UINT32_C(id) | \
+ BIT32(OPTEE_FFA_YIELDING_CALL_BIT))
+
+/*
+ * Returns the API version implemented, currently follows the FF-A version.
+ * Call register usage:
+ * w3: Service ID, OPTEE_FFA_GET_API_VERSION
+ * w4-w7: Not used (MBZ)
+ *
+ * Return register usage:
+ * w3: OPTEE_FFA_VERSION_MAJOR
+ * w4: OPTEE_FFA_VERSION_MINOR
+ * w5-w7: Not used (MBZ)
+ */
+#define OPTEE_FFA_GET_API_VERSION OPTEE_FFA_BLOCKING_CALL(0)
+
+/*
+ * Returns the revision of OP-TEE.
+ *
+ * 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.
+ *
+ * Call register usage:
+ * w3: Service ID, OPTEE_FFA_GET_OS_VERSION
+ * w4-w7: Unused (MBZ)
+ *
+ * Return register usage:
+ * w3: CFG_OPTEE_REVISION_MAJOR
+ * w4: CFG_OPTEE_REVISION_MINOR
+ * w5: TEE_IMPL_GIT_SHA1 (or zero if not supported)
+ */
+#define OPTEE_FFA_GET_OS_VERSION OPTEE_FFA_BLOCKING_CALL(1)
+
+/*
+ * Exchange capabilities between normal world and secure world.
+ *
+ * Currently there are no defined capabilities. When features are added new
+ * capabilities may be added.
+ *
+ * Call register usage:
+ * w3: Service ID, OPTEE_FFA_EXCHANGE_CAPABILITIES
+ * w4-w7: Note used (MBZ)
+ *
+ * Return register usage:
+ * w3: Error code, 0 on success
+ * w4: Bit[1:0]: Number of 4kB pages of shared memory to register with
+ * OPTEE_FFA_REGISTER_RPC_SHM to support RPC
+ * Bit[31:2]: Reserved (MBZ)
+ * w5-w7: Note used (MBZ)
+ */
+#define OPTEE_FFA_EXCHANGE_CAPABILITIES OPTEE_FFA_BLOCKING_CALL(2)
+
+/*
+ * Call with struct optee_msg_arg as argument in the supplied shared memory
+ * with a zero internal offset and normal cached memory attributes.
+ * Register usage:
+ * w3: Service ID, OPTEE_FFA_YIELDING_CALL_WITH_ARG
+ * w4: Lower 32 bits of a 64-bit Shared memory handle
+ * w5: Upper 32 bits of a 64-bit Shared memory handle
+ * w6: Offset into shared memory pointing to a struct optee_msg_arg
+ * w7: Not used (MBZ)
+ *
+ * Call to register shared memory. The data is supplied in shared
+ * memory with a zero internal offset and normal cached memory attributes.
+ * The data is formatted as described in FF-A 1.0 EAC Table 44
+ * "Lend, donate or share memory transaction descriptor".
+ * Register usage:
+ * w3: Service ID, OPTEE_FFA_YIELDING_CALL_REGISTER_SHM
+ * w4: Lower 32 bits of a 64-bit Shared memory handle
+ * w5: Upper 32 bits of a 64-bit Shared memory handle
+ * w6-w7: Not used (MBZ)
+ *
+ * Call to unregister shared memory. Register usage:
+ * w3: Service ID, OPTEE_FFA_YIELDING_CALL_UNREGISTER_SHM
+ * w4: Lower 32 bits of a 64-bit Shared memory handle
+ * w5: Upper 32 bits of a 64-bit Shared memory handle
+ * w6-w7: Not used (MBZ)
+ *
+ * Resume from RPC. Register usage:
+ * w3: Service ID, OPTEE_FFA_YIELDING_CALL_RESUME
+ * If returning from OPTEE_FFA_YIELDING_CALL_RETURN_ALLOC_SHM:
+ * w4: Lower 32 bits of a 64-bit Shared memory handle
+ * w5: Upper 32 bits of a 64-bit Shared memory handle
+ * If the allocation failed both w4 and w5 are 0
+ * w6: Offset into shared memory pointing the table. If internal
+ * offset > 0 then one more 4kB page than requested has been
+ * allocated.
+ * else if resuming from another RPC:
+ * w4-w6: Not used (MBZ)
+ * w7: Resume info
+ *
+ * Normal return (yielding call is completed). Register usage:
+ * w3: Error code, 0 on success
+ * w4: OPTEE_FFA_YIELDING_CALL_RETURN_DONE
+ * w5-w7: Not used (MBZ)
+ *
+ * Alloc SHM return (RPC from secure world). Register usage:
+ * w3: Error code == 0
+ * w4: OPTEE_FFA_YIELDING_CALL_RETURN_ALLOC_KERN_SHM or
+ * OPTEE_FFA_YIELDING_CALL_RETURN_ALLOC_SUPPL_SHM
+ * allocate kernel private or supplicant memory respectively.
+ * w5: Number of 4kB pages of shared memory
+ * w6: Not used (MBZ)
+ * w7: Resume info
+ *
+ * Free SHM return (RPC from secure world). Register usage:
+ * w3: Error code == 0
+ * w4: OPTEE_FFA_YIELDING_CALL_RETURN_FREE_KERN_SHM or
+ * OPTEE_FFA_YIELDING_CALL_RETURN_FREE_SUPPL_SHM
+ * free kernel private or supplicant memory respectively.
+ * w5: Lower 32 bits of a 64-bit Shared memory handle
+ * w6: Upper 32 bits of a 64-bit Shared memory handle
+ * The handle previously allocated with
+ * OPTEE_FFA_YIELDING_CALL_RETURN_ALLOC_KERN_SHM or
+ * OPTEE_FFA_YIELDING_CALL_RETURN_ALLOC_SUPPL_SHM.
+ * w7: Resume info
+ *
+ * RPC cmd return (RPC from secure world). Register usage:
+ * w3: Error code == 0
+ * w4: OPTEE_FFA_YIELDING_CALL_RETURN_RPC_CMD
+ * w5: Lower 32 bits of a 64-bit Shared memory handle
+ * w6: Upper 32 bits of a 64-bit Shared memory handle
+ * The handle contains aed the RPC.
+ * w7: Resume info
+ *
+ * RPC interrupt return (RPC from secure world). Register usage:
+ * w3: Error code == 0
+ * w4: OPTEE_FFA_YIELDING_CALL_RETURN_INTERRUPT
+ * w5-w6: Not used (MBZ)
+ * w7: Resume info
+ *
+ * Possible error codes in register w3:
+ * 0: Success
+ * FFA_DENIED: w4 isn't one of OPTEE_FFA_YIELDING_CALL_START
+ * OPTEE_FFA_YIELDING_CALL_REGISTER_SHM,
+ * OPTEE_FFA_YIELDING_CALL_UNREGISTER_SHM or
+ * OPTEE_FFA_YIELDING_CALL_RESUME
+ *
+ * Possible error codes for OPTEE_FFA_YIELDING_CALL_START,
+ * OPTEE_FFA_YIELDING_CALL_REGISTER_SHM and
+ * OPTEE_FFA_YIELDING_CALL_UNREGISTER_SHM
+ * FFA_BUSY: Number of OP-TEE OS threads exceeded,
+ * try again later
+ * FFA_DENIED: RPC shared memory object not found
+ * FFA_INVALID_PARAMETER: Bad shared memory handle or offset into the memory
+ *
+ * Possible error codes for OPTEE_FFA_YIELDING_CALL_RESUME
+ * FFA_INVALID_PARAMETER: Bad resume info
+ */
+#define OPTEE_FFA_YIELDING_CALL_WITH_ARG OPTEE_FFA_YIELDING_CALL(0)
+#define OPTEE_FFA_YIELDING_CALL_REGISTER_SHM OPTEE_FFA_YIELDING_CALL(1)
+#define OPTEE_FFA_YIELDING_CALL_UNREGISTER_SHM OPTEE_FFA_YIELDING_CALL(2)
+#define OPTEE_FFA_YIELDING_CALL_RESUME OPTEE_FFA_YIELDING_CALL(3)
+
+#define OPTEE_FFA_YIELDING_CALL_RETURN_DONE 0
+#define OPTEE_FFA_YIELDING_CALL_RETURN_ALLOC_KERN_SHM 1
+#define OPTEE_FFA_YIELDING_CALL_RETURN_ALLOC_SUPPL_SHM 2
+#define OPTEE_FFA_YIELDING_CALL_RETURN_RESERVED0 3
+#define OPTEE_FFA_YIELDING_CALL_RETURN_FREE_KERN_SHM 4
+#define OPTEE_FFA_YIELDING_CALL_RETURN_FREE_SUPPL_SHM 5
+#define OPTEE_FFA_YIELDING_CALL_RETURN_RESERVED1 6
+#define OPTEE_FFA_YIELDING_CALL_RETURN_RPC_CMD 7
+#define OPTEE_FFA_YIELDING_CALL_RETURN_INTERRUPT 8
+
+#endif /*__OPTEE_FFA_H*/
+
diff --git a/core/include/optee_msg.h b/core/include/optee_msg.h
index 72eaeae9..57467c77 100644
--- a/core/include/optee_msg.h
+++ b/core/include/optee_msg.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
- * Copyright (c) 2015-2017, Linaro Limited
+ * Copyright (c) 2015-2020, Linaro Limited
*/
#ifndef _OPTEE_MSG_H
#define _OPTEE_MSG_H
@@ -25,6 +25,9 @@
#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_FMEM_INPUT OPTEE_MSG_ATTR_TYPE_RMEM_INPUT
+#define OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT
+#define OPTEE_MSG_ATTR_TYPE_FMEM_INOUT OPTEE_MSG_ATTR_TYPE_RMEM_INOUT
#define OPTEE_MSG_ATTR_TYPE_TMEM_INPUT 0x9
#define OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT 0xa
#define OPTEE_MSG_ATTR_TYPE_TMEM_INOUT 0xb
@@ -49,8 +52,8 @@
* Every entry in buffer should point to a 4k page beginning (12 least
* significant bits must be equal to zero).
*
- * 12 least significant of optee_msg_param.u.tmem.buf_ptr should hold page
- * offset of user buffer.
+ * 12 least significant bits of optee_msg_param.u.tmem.buf_ptr should hold
+ * page offset of user buffer.
*
* So, entries should be placed like members of this structure:
*
@@ -126,10 +129,26 @@ struct optee_msg_param_rmem {
};
/**
- * struct optee_msg_param_value - values
- * @a: first value
- * @b: second value
- * @c: third value
+ * struct optee_msg_param_fmem - FF-A memory reference parameter
+ * @offs_lower: Lower bits of offset into shared memory reference
+ * @offs_upper: Upper bits of offset into shared memory reference
+ * @internal_offs: Internal offset into the first page of shared memory
+ * reference
+ * @size: Size of the buffer
+ * @global_id: Global identifier of the shared memory
+ */
+struct optee_msg_param_fmem {
+ uint32_t offs_low;
+ uint16_t offs_high;
+ uint16_t internal_offs;
+ uint64_t size;
+ uint64_t global_id;
+};
+
+/**
+ * struct optee_msg_param_value - opaque value parameter
+ *
+ * Value parameters are passed unchecked between normal and secure world.
*/
struct optee_msg_param_value {
uint64_t a;
@@ -138,15 +157,18 @@ struct optee_msg_param_value {
};
/**
- * struct optee_msg_param - parameter
- * @attr: attributes
- * @memref: a memory reference
- * @value: a value
+ * 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
+ * @fmem: parameter by FF-A 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_TMEM_* indicates @tmem and
+ * OPTEE_MSG_ATTR_TYPE_RMEM_* or the alias PTEE_MSG_ATTR_TYPE_FMEM_* indicates
+ * @rmem or @fmem depending on the conduit.
* OPTEE_MSG_ATTR_TYPE_NONE indicates that none of the members are used.
*/
struct optee_msg_param {
@@ -154,6 +176,7 @@ struct optee_msg_param {
union {
struct optee_msg_param_tmem tmem;
struct optee_msg_param_rmem rmem;
+ struct optee_msg_param_fmem fmem;
struct optee_msg_param_value value;
} u;
};