1 /*
2  * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef SPMC_H
8 #define SPMC_H
9 
10 #include <stdint.h>
11 #include <lib/psci/psci.h>
12 
13 
14 #include "spm_common.h"
15 
16 /*
17  * Ranges of FF-A IDs for Normal world and Secure world components. The
18  * convention matches that used by other SPMCs i.e. Hafnium and OP-TEE.
19  */
20 #define FFA_NWLD_ID_BASE	0x0
21 #define FFA_NWLD_ID_LIMIT	0x7FFF
22 #define FFA_SWLD_ID_BASE	0x8000
23 #define FFA_SWLD_ID_LIMIT	0xFFFF
24 #define FFA_SWLD_ID_MASK	0x8000
25 
26 #define FFA_HYP_ID		FFA_NWLD_ID_BASE	/* Hypervisor or physical OS is assigned 0x0 as per SMCCC */
27 #define FFA_SPMC_ID		U(FFA_SWLD_ID_BASE)	/* First ID is reserved for the SPMC */
28 #define FFA_SP_ID_BASE		(FFA_SPMC_ID + 1)	/* SP IDs are allocated after the SPMC ID */
29 #define INV_SP_ID		0x7FFF			/* Align with Hafnium implementation */
30 
31 #define FFA_PAGE_SIZE (4096)
32 
33 /*
34  * Runtime states of an execution context as per the FF-A v1.1 specification.
35  */
36 enum runtime_states {
37 	RT_STATE_WAITING,
38 	RT_STATE_RUNNING,
39 	RT_STATE_PREEMPTED,
40 	RT_STATE_BLOCKED
41 };
42 
43 /*
44  * Runtime model of an execution context as per the FF-A v1.1 specification. Its
45  * value is valid only if the execution context is not in the waiting state.
46  */
47 enum runtime_model {
48 	RT_MODEL_DIR_REQ,
49 	RT_MODEL_RUN,
50 	RT_MODEL_INIT,
51 	RT_MODEL_INTR
52 };
53 
54 enum runtime_el {
55 	EL0 = 0,
56 	EL1,
57 	EL2,
58 	EL3
59 };
60 
61 enum mailbox_state {
62 	/** There is no message in the mailbox. */
63 	MAILBOX_STATE_EMPTY,
64 
65 	/** There is a message that has been populated in the mailbox. */
66 	MAILBOX_STATE_FULL,
67 };
68 
69 
70 struct mailbox {
71 	enum mailbox_state state;
72 
73 	/* RX/TX Buffers */
74 	void *rx_buffer;
75 	const void *tx_buffer;
76 
77 	/*
78 	 * Size of RX/TX Buffer
79 	 */
80 	uint32_t rxtx_page_count;
81 
82 	/* Lock access to mailbox */
83 	struct spinlock lock;
84 };
85 
86 /*
87  * Execution context members common to both S-EL0 and S-EL1 SPs. This is a bit
88  * like struct vcpu in a hypervisor.
89  */
90 typedef struct sp_exec_ctx {
91 	uint64_t c_rt_ctx;
92 	cpu_context_t cpu_ctx;
93 	enum runtime_states rt_state;
94 	enum runtime_model rt_model;
95 } sp_exec_ctx_t;
96 
97 /*
98  * Structure to describe the cumulative properties of S-EL0 and S-EL1 SPs.
99  */
100 typedef struct secure_partition_desc {
101 	/*
102 	 * Execution contexts allocated to this endpoint. Ideally,
103 	 * we need as many contexts as there are physical cpus only for a S-EL1
104 	 * SP which is MP-pinned. We need only a single context for a S-EL0 SP
105 	 * which is UP-migrateable. So, we end up wasting space when only a
106 	 * S-EL0 SP is deployed.
107 	 */
108 	sp_exec_ctx_t ec[PLATFORM_CORE_COUNT];
109 
110 	/*
111 	 * ID of the Secure Partition
112 	 */
113 	uint16_t sp_id;
114 
115 	/*
116 	 * Runtime EL
117 	 */
118 	uint16_t runtime_el;
119 
120 	/*
121 	 * Mailbox tracking
122 	 */
123 	struct mailbox mailbox;
124 
125 	/*
126 	 * Partition UUID
127 	 */
128 	uint32_t uuid[4];
129 
130 	/*
131 	 * Partition Properties
132 	 */
133 	uint32_t properties;
134 
135 	/*
136 	 * Supported FFA Version
137 	 */
138 	uint32_t ffa_version;
139 
140 	/*
141 	 * Execution State
142 	 */
143 	uint32_t execution_state;
144 
145 	/*
146 	 * Lock to protect the runtime state of a S-EL0 SP execution context.
147 	 */
148 	spinlock_t rt_state_lock;
149 
150 	/*
151 	 * Pointer to translation table context of a S-EL0 SP.
152 	 */
153 	xlat_ctx_t *xlat_ctx_handle;
154 
155 	/*
156 	 * Stack base of a S-EL0 SP.
157 	 */
158 	uint64_t   sp_stack_base;
159 
160 	/*
161 	 * Stack size of a S-EL0 SP.
162 	 */
163 	uint64_t   sp_stack_size;
164 
165 	/*
166 	 * Secondary entrypoint. Only valid for a S-EL1 SP.
167 	 */
168 	uintptr_t    secondary_ep;
169 
170 	/*
171 	 * Lock to protect the secondary entrypoint update in a SP descriptor.
172 	 */
173 	spinlock_t secondary_ep_lock;
174 } sp_desc_t;
175 
176 /*
177  * This define identifies the only SP that will be initialised and participate
178  * in FF-A communication. The implementation leaves the door open for more SPs
179  * to be managed in future but for now it reasonable to assume that either a
180  * single S-EL0 or a single S-EL1 SP will be supported. This define will be used
181  * to identify which SP descriptor to initialise and manage during SP runtime.
182  */
183 #define ACTIVE_SP_DESC_INDEX	0
184 
185 /*
186  * Structure to describe the cumulative properties of the Hypervisor and
187  * NS-Endpoints.
188  */
189 typedef struct ns_endpoint_desc {
190 	/*
191 	 * ID of the NS-Endpoint or Hypervisor
192 	 */
193 	uint16_t ns_ep_id;
194 
195 	/*
196 	 * Mailbox tracking
197 	 */
198 	struct mailbox mailbox;
199 
200 	/*
201 	 * Supported FFA Version
202 	 */
203 	uint32_t ffa_version;
204 
205 } ns_ep_desc_t;
206 
207 /**
208  * Holds information returned for each partition by the FFA_PARTITION_INFO_GET
209  * interface.
210  */
211 struct ffa_partition_info {
212 	uint16_t ep_id;
213 	uint16_t execution_ctx_count;
214 	uint32_t properties;
215 };
216 
217 /* Reference to power management hooks */
218 extern const spd_pm_ops_t spmc_pm;
219 
220 /* Setup Function for different SP types. */
221 void spmc_sp_common_setup(sp_desc_t *sp, entry_point_info_t *ep_info);
222 void spmc_el0_sp_setup(sp_desc_t *sp, entry_point_info_t *ep_info);
223 void spmc_el1_sp_setup(sp_desc_t *sp, entry_point_info_t *ep_info);
224 
225 /*
226  * Helper function to perform a synchronous entry into a SP.
227  */
228 uint64_t spmc_sp_synchronous_entry(sp_exec_ctx_t *ec);
229 
230 /*
231  * Helper function to obtain the descriptor of the current SP on a physical cpu.
232  */
233 sp_desc_t* spmc_get_current_sp_ctx();
234 
235 /*
236  * Helper function to obtain the index of the execution context of an SP on a
237  * physical cpu.
238  */
239 unsigned int get_ec_index(sp_desc_t *sp);
240 
241 uint64_t spmc_ffa_error_return(void *handle, int error_code);
242 
243 /*
244  * Helper function to obtain the RX/TX buffer pair descriptor of the Hypervisor
245  * or the last SP that was run.
246  */
247 struct mailbox *spmc_get_mbox_desc(uint64_t flags);
248 
249 #endif /* SPMC_H */
250