blob: 523365002ed4b73be115649359cefd8b8d67329f [file] [log] [blame]
Marc Bonnici8e1a7552021-12-01 17:57:04 +00001/*
2 * Copyright (c) 2022, 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
Claus Pedersen785e66c2022-09-12 22:42:58 +000012#include <common/bl_common.h>
Marc Bonnici8e1a7552021-12-01 17:57:04 +000013#include <lib/psci/psci.h>
14#include <lib/spinlock.h>
Marc Bonnici9a297042022-02-14 17:06:09 +000015#include <services/el3_spmc_logical_sp.h>
Marc Bonnici8e1a7552021-12-01 17:57:04 +000016#include "spm_common.h"
17
18/*
19 * Ranges of FF-A IDs for Normal world and Secure world components. The
20 * convention matches that used by other SPMCs i.e. Hafnium and OP-TEE.
21 */
22#define FFA_NWD_ID_BASE 0x0
23#define FFA_NWD_ID_LIMIT 0x7FFF
24#define FFA_SWD_ID_BASE 0x8000
25#define FFA_SWD_ID_LIMIT SPMD_DIRECT_MSG_ENDPOINT_ID - 1
26#define FFA_SWD_ID_MASK 0x8000
27
Marc Bonnici8eb15202021-11-29 17:05:33 +000028/* ID 0 is reserved for the normal world entity, (Hypervisor or OS Kernel). */
29#define FFA_NWD_ID U(0)
Marc Bonnici8e1a7552021-12-01 17:57:04 +000030/* First ID is reserved for the SPMC */
31#define FFA_SPMC_ID U(FFA_SWD_ID_BASE)
32/* SP IDs are allocated after the SPMC ID */
33#define FFA_SP_ID_BASE (FFA_SPMC_ID + 1)
34/* Align with Hafnium implementation */
35#define INV_SP_ID 0x7FFF
36
Marc Bonnicid4bb2452021-12-13 11:08:59 +000037/* FF-A Related helper macros. */
Marc Bonnici764e6672021-08-31 17:57:04 +010038#define FFA_ID_MASK U(0xFFFF)
39#define FFA_PARTITION_ID_SHIFT U(16)
Marc Bonnicid4bb2452021-12-13 11:08:59 +000040#define FFA_FEATURES_BIT31_MASK U(0x1u << 31)
Marc Bonnici08f28ef2022-04-19 16:52:59 +010041#define FFA_FEATURES_RET_REQ_NS_BIT U(0x1 << 1)
Marc Bonnicid4bb2452021-12-13 11:08:59 +000042
Marc Bonnici764e6672021-08-31 17:57:04 +010043#define FFA_RUN_EP_ID(ep_vcpu_ids) \
44 ((ep_vcpu_ids >> FFA_PARTITION_ID_SHIFT) & FFA_ID_MASK)
45#define FFA_RUN_VCPU_ID(ep_vcpu_ids) \
46 (ep_vcpu_ids & FFA_ID_MASK)
47
Marc Bonnici0cf1a152021-08-25 12:09:37 +010048#define FFA_PAGE_SIZE (4096)
49#define FFA_RXTX_PAGE_COUNT_MASK 0x1F
50
51/* Ensure that the page size used by TF-A is 4k aligned. */
52CASSERT((PAGE_SIZE % FFA_PAGE_SIZE) == 0, assert_aligned_page_size);
53
Marc Bonnici8e1a7552021-12-01 17:57:04 +000054/*
Marc Bonnici25f4b542022-04-12 17:18:13 +010055 * Defines to allow an SP to subscribe for power management messages
56 */
57#define FFA_PM_MSG_SUB_CPU_OFF U(1 << 0)
58#define FFA_PM_MSG_SUB_CPU_SUSPEND U(1 << 1)
59#define FFA_PM_MSG_SUB_CPU_SUSPEND_RESUME U(1 << 2)
60
61/*
Marc Bonnici8e1a7552021-12-01 17:57:04 +000062 * Runtime states of an execution context as per the FF-A v1.1 specification.
63 */
64enum sp_runtime_states {
65 RT_STATE_WAITING,
66 RT_STATE_RUNNING,
67 RT_STATE_PREEMPTED,
68 RT_STATE_BLOCKED
69};
70
71/*
72 * Runtime model of an execution context as per the FF-A v1.1 specification. Its
73 * value is valid only if the execution context is not in the waiting state.
74 */
75enum sp_runtime_model {
76 RT_MODEL_DIR_REQ,
77 RT_MODEL_RUN,
78 RT_MODEL_INIT,
79 RT_MODEL_INTR
80};
81
82enum sp_runtime_el {
83 EL1 = 0,
84 S_EL0,
85 S_EL1
86};
87
88enum sp_execution_state {
89 SP_STATE_AARCH64 = 0,
90 SP_STATE_AARCH32
91};
92
Marc Bonniciecc460a2021-09-02 13:18:41 +010093enum mailbox_state {
94 /* There is no message in the mailbox. */
95 MAILBOX_STATE_EMPTY,
96
97 /* There is a message that has been populated in the mailbox. */
98 MAILBOX_STATE_FULL,
99};
100
101struct mailbox {
102 enum mailbox_state state;
103
104 /* RX/TX Buffers. */
105 void *rx_buffer;
106 const void *tx_buffer;
107
108 /* Size of RX/TX Buffer. */
109 uint32_t rxtx_page_count;
110
111 /* Lock access to mailbox. */
112 spinlock_t lock;
113};
114
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000115/*
116 * Execution context members for an SP. This is a bit like struct
117 * vcpu in a hypervisor.
118 */
119struct sp_exec_ctx {
120 /*
121 * Store the stack address to restore C runtime context from after
122 * returning from a synchronous entry into the SP.
123 */
124 uint64_t c_rt_ctx;
125
126 /* Space to maintain the architectural state of an SP. */
127 cpu_context_t cpu_ctx;
128
129 /* Track the current runtime state of the SP. */
130 enum sp_runtime_states rt_state;
131
132 /* Track the current runtime model of the SP. */
133 enum sp_runtime_model rt_model;
134};
135
136/*
137 * Structure to describe the cumulative properties of an SP.
138 */
139struct secure_partition_desc {
140 /*
141 * Execution contexts allocated to this endpoint. Ideally,
142 * we need as many contexts as there are physical cpus only
143 * for a S-EL1 SP which is MP-pinned.
144 */
145 struct sp_exec_ctx ec[PLATFORM_CORE_COUNT];
146
147 /* ID of the Secure Partition. */
148 uint16_t sp_id;
149
150 /* Runtime EL. */
151 enum sp_runtime_el runtime_el;
152
153 /* Partition UUID. */
154 uint32_t uuid[4];
155
156 /* Partition Properties. */
157 uint32_t properties;
158
159 /* Supported FF-A Version. */
160 uint32_t ffa_version;
161
162 /* Execution State. */
163 enum sp_execution_state execution_state;
164
Marc Bonniciecc460a2021-09-02 13:18:41 +0100165 /* Mailbox tracking. */
166 struct mailbox mailbox;
167
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000168 /* Secondary entrypoint. Only valid for a S-EL1 SP. */
169 uintptr_t secondary_ep;
Marc Bonnici25f4b542022-04-12 17:18:13 +0100170
171 /*
172 * Store whether the SP has subscribed to any power management messages.
173 */
174 uint16_t pwr_mgmt_msgs;
Marc Bonnici08f28ef2022-04-19 16:52:59 +0100175
176 /*
177 * Store whether the SP has requested the use of the NS bit for memory
178 * management transactions if it is using FF-A v1.0.
179 */
180 bool ns_bit_requested;
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000181};
182
183/*
184 * This define identifies the only SP that will be initialised and participate
185 * in FF-A communication. The implementation leaves the door open for more SPs
186 * to be managed in future but for now it is reasonable to assume that either a
187 * single S-EL0 or a single S-EL1 SP will be supported. This define will be used
188 * to identify which SP descriptor to initialise and manage during SP runtime.
189 */
190#define ACTIVE_SP_DESC_INDEX 0
191
192/*
193 * Structure to describe the cumulative properties of the Hypervisor and
194 * NS-Endpoints.
195 */
196struct ns_endpoint_desc {
197 /*
198 * ID of the NS-Endpoint or Hypervisor.
199 */
200 uint16_t ns_ep_id;
201
202 /*
Marc Bonniciecc460a2021-09-02 13:18:41 +0100203 * Mailbox tracking.
204 */
205 struct mailbox mailbox;
206
207 /*
208 * Supported FF-A Version
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000209 */
210 uint32_t ffa_version;
211};
212
Marc Bonnici37dd8e12021-08-17 18:00:07 +0100213/**
214 * Holds information returned for each partition by the FFA_PARTITION_INFO_GET
215 * interface.
216 */
217struct ffa_partition_info_v1_0 {
218 uint16_t ep_id;
219 uint16_t execution_ctx_count;
220 uint32_t properties;
221};
222
223/* Extended structure for v1.1. */
224struct ffa_partition_info_v1_1 {
225 uint16_t ep_id;
226 uint16_t execution_ctx_count;
227 uint32_t properties;
228 uint32_t uuid[4];
229};
230
Marc Bonnici25f4b542022-04-12 17:18:13 +0100231/* Reference to power management hooks */
232extern const spd_pm_ops_t spmc_pm;
233
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000234/* Setup Function for different SP types. */
235void spmc_sp_common_setup(struct secure_partition_desc *sp,
Achin Guptaeaf17162021-10-19 12:21:16 +0100236 entry_point_info_t *ep_info,
237 int32_t boot_info_reg);
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000238void spmc_el1_sp_setup(struct secure_partition_desc *sp,
239 entry_point_info_t *ep_info);
240void spmc_sp_common_ep_commit(struct secure_partition_desc *sp,
241 entry_point_info_t *ep_info);
242
243/*
244 * Helper function to perform a synchronous entry into a SP.
245 */
246uint64_t spmc_sp_synchronous_entry(struct sp_exec_ctx *ec);
247
248/*
249 * Helper function to obtain the descriptor of the current SP on a physical cpu.
250 */
251struct secure_partition_desc *spmc_get_current_sp_ctx(void);
252
253/*
254 * Helper function to obtain the execution context of an SP on a
255 * physical cpu.
256 */
257struct sp_exec_ctx *spmc_get_sp_ec(struct secure_partition_desc *sp);
258
259/*
260 * Helper function to obtain the index of the execution context of an SP on a
261 * physical cpu.
262 */
263unsigned int get_ec_index(struct secure_partition_desc *sp);
264
265uint64_t spmc_ffa_error_return(void *handle, int error_code);
266
267/*
268 * Ensure a partition ID does not clash and follows the secure world convention.
269 */
270bool is_ffa_secure_id_valid(uint16_t partition_id);
271
Marc Bonnici9a297042022-02-14 17:06:09 +0000272/*
273 * Helper function to obtain the array storing the EL3
274 * Logical Partition descriptors.
275 */
276struct el3_lp_desc *get_el3_lp_array(void);
277
Marc Bonnicia2cfa612021-11-24 10:33:48 +0000278/*
279 * Helper function to obtain the RX/TX buffer pair descriptor of the Hypervisor
280 * or OS kernel in the normal world or the last SP that was run.
281 */
282struct mailbox *spmc_get_mbox_desc(bool secure_origin);
283
Marc Bonnici336630f2022-01-13 11:39:10 +0000284/*
285 * Helper function to obtain the context of an SP with a given partition ID.
286 */
287struct secure_partition_desc *spmc_get_sp_ctx(uint16_t id);
288
Marc Bonnicid1907f02022-04-19 17:42:53 +0100289/*
290 * Add helper function to obtain the FF-A version of the calling
291 * partition.
292 */
293uint32_t get_partition_ffa_version(bool secure_origin);
294
Marc Bonnici336630f2022-01-13 11:39:10 +0000295
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000296#endif /* SPMC_H */