1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2019-2020, Linaro Limited
4  * Copyright (c) 2020, Arm Limited.
5  */
6 
7 #ifndef __KERNEL_STMM_SP_H
8 #define __KERNEL_STMM_SP_H
9 
10 #include <assert.h>
11 #include <config.h>
12 #include <kernel/tee_ta_manager.h>
13 #include <kernel/thread.h>
14 #include <kernel/user_mode_ctx_struct.h>
15 #include <types_ext.h>
16 #include <util.h>
17 
18 #define STMM_RET_SUCCESS		0
19 #define STMM_RET_NOT_SUPPORTED	        -1
20 #define STMM_RET_INVALID_PARAM	        -2
21 #define STMM_RET_DENIED		        -3
22 #define STMM_RET_NO_MEM		        -5
23 
24 #define STMM_MEM_ATTR_ACCESS_MASK	U(0x3)
25 #define STMM_MEM_ATTR_ACCESS_NONE	U(0)
26 #define STMM_MEM_ATTR_ACCESS_RW		U(1)
27 #define STMM_MEM_ATTR_ACCESS_RO		U(3)
28 #define STMM_MEM_ATTR_EXEC_NEVER	BIT(2)
29 #define STMM_MEM_ATTR_EXEC		U(0)
30 #define STMM_MEM_ATTR_ALL		(STMM_MEM_ATTR_ACCESS_RW | \
31 					 STMM_MEM_ATTR_ACCESS_RO | \
32 					 STMM_MEM_ATTR_EXEC_NEVER)
33 
34 /*
35  * Used for EDK2 StMM communication. Since StMM can be launched on an arbitrary
36  * address it uses these 2 syscalls to define the memory attributes for the
37  * data and code segments after dispatching the binaries.
38  *
39  * FFA_SVC_MEMORY_ATTRIBUTES_SET_64/FFA_SVC_MEMORY_ATTRIBUTES_SET_32:
40  *  - x4: base address
41  *  - x5: number of pages
42  *  - x6: attributes of the remapping (described above)
43  *
44  * FFA_SVC_MEMORY_ATTRIBUTES_GET_32/FFA_SVC_MEMORY_ATTRIBUTES_GET_64:
45  *  - x4: base address, currently only a single page is requested.
46  */
47 #define FFA_SVC_MEMORY_ATTRIBUTES_GET_64	UINT32_C(0xC4000064)
48 #define FFA_SVC_MEMORY_ATTRIBUTES_SET_64	UINT32_C(0xC4000065)
49 
50 #define FFA_SVC_MEMORY_ATTRIBUTES_GET_32	UINT32_C(0x84000064)
51 #define FFA_SVC_MEMORY_ATTRIBUTES_SET_32	UINT32_C(0x84000065)
52 
53 /*
54  * We need to define the RPMB IDs formally, since the plan is
55  * for them to be included in the FFA spec (for SP-to-SP future communication).
56  * This is fine for now as it represents the internal contract between the
57  * EDK2 RPMB driver and Secure Partition
58  *
59  * FFA_SVC_RPMB_WRITE/FFA_SVC_RPMB_WRITE_32:
60  *  - x4: virtual address of the buffer to write in the device
61  *  - x5: buffer byte length
62  *  - x6: byte offset in the device
63  * FFA_SVC_RPMB_READ/FFA_SVC_RPMB_READ_32:
64  *  - x4: virtual address of the buffer were RPMB contents are copied
65  *  - x5: buffer byte length to read
66  *  - x6: byte offset in the device
67  */
68 #define FFA_SVC_RPMB_READ		UINT32_C(0xC4000066)
69 #define FFA_SVC_RPMB_WRITE		UINT32_C(0xC4000067)
70 
71 #define FFA_SVC_RPMB_READ_32		UINT32_C(0x84000066)
72 #define FFA_SVC_RPMB_WRITE_32		UINT32_C(0x84000067)
73 
74 /* Param header types */
75 #define STMM_PARAM_EP			UINT8_C(0x01)
76 #define STMM_PARAM_IMAGE_BINARY		UINT8_C(0x02)
77 #define STMM_PARAM_BL31			UINT8_C(0x03)
78 #define STMM_PARAM_BL_LOAD_INFO		UINT8_C(0x04)
79 #define STMM_PARAM_BL_PARAMS		UINT8_C(0x05)
80 #define STMM_PARAM_PSCI_LIB_ARGS	UINT8_C(0x06)
81 #define STMM_PARAM_SP_IMAGE_BOOT_INFO	UINT8_C(0x07)
82 
83 /* Param header version */
84 #define STMM_PARAM_VERSION_1		UINT8_C(0x01)
85 #define STMM_PARAM_VERSION_2		UINT8_C(0x02)
86 
87 /*
88  * This structure provides information on format used to describe
89  * secure partition invocation parameters.
90  */
91 struct stmm_param_header {
92 	uint8_t type;		/* type of the structure */
93 	uint8_t version;	/* version of this structure */
94 	uint16_t size;		/* size of this structure in bytes */
95 	uint32_t attr;		/* attributes: unused bits SBZ */
96 };
97 
98 /*
99  * Flags used by the stmm_mp_info structure to describe the
100  * characteristics of a cpu. Only a single flag is defined at the moment to
101  * indicate the primary cpu.
102  */
103 #define MP_INFO_FLAG_PRIMARY_CPU	UINT32_C(0x00000001)
104 
105 /*
106  * This structure is used to provide information required to initialise a S-EL0
107  * partition.
108  */
109 struct stmm_mp_info {
110 	uint64_t mpidr;
111 	uint32_t linear_id;
112 	uint32_t flags;
113 };
114 
115 struct stmm_boot_info {
116 	struct stmm_param_header	h;
117 	uint64_t sp_mem_base;
118 	uint64_t sp_mem_limit;
119 	uint64_t sp_image_base;
120 	uint64_t sp_stack_base;
121 	uint64_t sp_heap_base;
122 	uint64_t sp_ns_comm_buf_base;
123 	uint64_t sp_shared_buf_base;
124 	uint64_t sp_image_size;
125 	uint64_t sp_pcpu_stack_size;
126 	uint64_t sp_heap_size;
127 	uint64_t sp_ns_comm_buf_size;
128 	uint64_t sp_shared_buf_size;
129 	uint32_t num_sp_mem_regions;
130 	uint32_t num_cpus;
131 	struct stmm_mp_info	*mp_info;
132 };
133 
134 struct stmm_ctx {
135 	struct user_mode_ctx uctx;
136 	struct tee_ta_ctx ta_ctx;
137 	struct thread_ctx_regs regs;
138 	vaddr_t ns_comm_buf_addr;
139 	unsigned int ns_comm_buf_size;
140 	bool is_initializing;
141 };
142 
143 extern const struct ts_ops stmm_sp_ops;
144 
is_stmm_ctx(struct ts_ctx * ctx __maybe_unused)145 static inline bool is_stmm_ctx(struct ts_ctx *ctx __maybe_unused)
146 {
147 	return IS_ENABLED(CFG_WITH_STMM_SP) && ctx && ctx->ops == &stmm_sp_ops;
148 }
149 
to_stmm_ctx(struct ts_ctx * ctx)150 static inline struct stmm_ctx *to_stmm_ctx(struct ts_ctx *ctx)
151 {
152 	assert(is_stmm_ctx(ctx));
153 	return container_of(ctx, struct stmm_ctx, ta_ctx.ts_ctx);
154 }
155 
156 #ifdef CFG_WITH_STMM_SP
157 TEE_Result stmm_init_session(const TEE_UUID *uuid,
158 			     struct tee_ta_session *s);
159 #else
160 static inline TEE_Result
stmm_init_session(const TEE_UUID * uuid __unused,struct tee_ta_session * s __unused)161 stmm_init_session(const TEE_UUID *uuid __unused,
162 		  struct tee_ta_session *s __unused)
163 {
164 	return TEE_ERROR_ITEM_NOT_FOUND;
165 }
166 #endif
167 
168 #endif /*__KERNEL_STMM_SP_H*/
169