blob: e093a82b2e76df56c89176ebf111f6d772b8a788 [file] [log] [blame]
Marc Bonnici8e1a7552021-12-01 17:57:04 +00001/*
Nishant Sharma9dc905b2022-04-28 10:58:24 +01002 * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved.
Marc Bonnici8e1a7552021-12-01 17:57:04 +00003 *
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;
Marc Bonnicia9395942022-11-15 11:15:48 +0000134
135 /* Track the source partition ID to validate a direct response. */
136 uint16_t dir_req_origin_id;
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000137};
138
139/*
140 * Structure to describe the cumulative properties of an SP.
141 */
142struct secure_partition_desc {
143 /*
144 * Execution contexts allocated to this endpoint. Ideally,
145 * we need as many contexts as there are physical cpus only
146 * for a S-EL1 SP which is MP-pinned.
147 */
148 struct sp_exec_ctx ec[PLATFORM_CORE_COUNT];
149
150 /* ID of the Secure Partition. */
151 uint16_t sp_id;
152
153 /* Runtime EL. */
154 enum sp_runtime_el runtime_el;
155
156 /* Partition UUID. */
157 uint32_t uuid[4];
158
159 /* Partition Properties. */
160 uint32_t properties;
161
162 /* Supported FF-A Version. */
163 uint32_t ffa_version;
164
165 /* Execution State. */
166 enum sp_execution_state execution_state;
167
Marc Bonniciecc460a2021-09-02 13:18:41 +0100168 /* Mailbox tracking. */
169 struct mailbox mailbox;
170
Nishant Sharma32d340b2022-04-28 12:16:57 +0100171 /* Lock to protect the runtime state of a S-EL0 SP execution context. */
172 spinlock_t rt_state_lock;
173
Nishant Sharma9dc905b2022-04-28 10:58:24 +0100174 /* Pointer to translation table context of a S-EL0 SP. */
175 xlat_ctx_t *xlat_ctx_handle;
176
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000177 /* Secondary entrypoint. Only valid for a S-EL1 SP. */
178 uintptr_t secondary_ep;
Marc Bonnici25f4b542022-04-12 17:18:13 +0100179
180 /*
181 * Store whether the SP has subscribed to any power management messages.
182 */
183 uint16_t pwr_mgmt_msgs;
Marc Bonnici08f28ef2022-04-19 16:52:59 +0100184
185 /*
186 * Store whether the SP has requested the use of the NS bit for memory
187 * management transactions if it is using FF-A v1.0.
188 */
189 bool ns_bit_requested;
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000190};
191
192/*
193 * This define identifies the only SP that will be initialised and participate
194 * in FF-A communication. The implementation leaves the door open for more SPs
195 * to be managed in future but for now it is reasonable to assume that either a
196 * single S-EL0 or a single S-EL1 SP will be supported. This define will be used
197 * to identify which SP descriptor to initialise and manage during SP runtime.
198 */
199#define ACTIVE_SP_DESC_INDEX 0
200
201/*
202 * Structure to describe the cumulative properties of the Hypervisor and
203 * NS-Endpoints.
204 */
205struct ns_endpoint_desc {
206 /*
207 * ID of the NS-Endpoint or Hypervisor.
208 */
209 uint16_t ns_ep_id;
210
211 /*
Marc Bonniciecc460a2021-09-02 13:18:41 +0100212 * Mailbox tracking.
213 */
214 struct mailbox mailbox;
215
216 /*
217 * Supported FF-A Version
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000218 */
219 uint32_t ffa_version;
220};
221
Marc Bonnici25f4b542022-04-12 17:18:13 +0100222/* Reference to power management hooks */
223extern const spd_pm_ops_t spmc_pm;
224
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000225/* Setup Function for different SP types. */
226void spmc_sp_common_setup(struct secure_partition_desc *sp,
Achin Guptaeaf17162021-10-19 12:21:16 +0100227 entry_point_info_t *ep_info,
228 int32_t boot_info_reg);
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000229void spmc_el1_sp_setup(struct secure_partition_desc *sp,
230 entry_point_info_t *ep_info);
231void spmc_sp_common_ep_commit(struct secure_partition_desc *sp,
232 entry_point_info_t *ep_info);
Nishant Sharma9dc905b2022-04-28 10:58:24 +0100233void spmc_el0_sp_spsr_setup(entry_point_info_t *ep_info);
234void spmc_el0_sp_setup(struct secure_partition_desc *sp,
Nishant Sharma6817bdb2022-04-28 11:52:07 +0100235 int32_t boot_info_reg,
236 void *sp_manifest);
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000237
238/*
239 * Helper function to perform a synchronous entry into a SP.
240 */
241uint64_t spmc_sp_synchronous_entry(struct sp_exec_ctx *ec);
242
243/*
244 * Helper function to obtain the descriptor of the current SP on a physical cpu.
245 */
246struct secure_partition_desc *spmc_get_current_sp_ctx(void);
247
248/*
249 * Helper function to obtain the execution context of an SP on a
250 * physical cpu.
251 */
252struct sp_exec_ctx *spmc_get_sp_ec(struct secure_partition_desc *sp);
253
254/*
255 * Helper function to obtain the index of the execution context of an SP on a
256 * physical cpu.
257 */
258unsigned int get_ec_index(struct secure_partition_desc *sp);
259
260uint64_t spmc_ffa_error_return(void *handle, int error_code);
261
262/*
263 * Ensure a partition ID does not clash and follows the secure world convention.
264 */
265bool is_ffa_secure_id_valid(uint16_t partition_id);
266
Marc Bonnici9a297042022-02-14 17:06:09 +0000267/*
268 * Helper function to obtain the array storing the EL3
269 * Logical Partition descriptors.
270 */
271struct el3_lp_desc *get_el3_lp_array(void);
272
Marc Bonnicia2cfa612021-11-24 10:33:48 +0000273/*
274 * Helper function to obtain the RX/TX buffer pair descriptor of the Hypervisor
275 * or OS kernel in the normal world or the last SP that was run.
276 */
277struct mailbox *spmc_get_mbox_desc(bool secure_origin);
278
Marc Bonnici336630f2022-01-13 11:39:10 +0000279/*
280 * Helper function to obtain the context of an SP with a given partition ID.
281 */
282struct secure_partition_desc *spmc_get_sp_ctx(uint16_t id);
283
Marc Bonnicid1907f02022-04-19 17:42:53 +0100284/*
285 * Add helper function to obtain the FF-A version of the calling
286 * partition.
287 */
288uint32_t get_partition_ffa_version(bool secure_origin);
289
Marc Bonnici336630f2022-01-13 11:39:10 +0000290
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000291#endif /* SPMC_H */