blob: 48644ac7fb1b82aff7de5210245364a3707e235b [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;
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
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000171 /* Secondary entrypoint. Only valid for a S-EL1 SP. */
172 uintptr_t secondary_ep;
Marc Bonnici25f4b542022-04-12 17:18:13 +0100173
174 /*
175 * Store whether the SP has subscribed to any power management messages.
176 */
177 uint16_t pwr_mgmt_msgs;
Marc Bonnici08f28ef2022-04-19 16:52:59 +0100178
179 /*
180 * Store whether the SP has requested the use of the NS bit for memory
181 * management transactions if it is using FF-A v1.0.
182 */
183 bool ns_bit_requested;
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000184};
185
186/*
187 * This define identifies the only SP that will be initialised and participate
188 * in FF-A communication. The implementation leaves the door open for more SPs
189 * to be managed in future but for now it is reasonable to assume that either a
190 * single S-EL0 or a single S-EL1 SP will be supported. This define will be used
191 * to identify which SP descriptor to initialise and manage during SP runtime.
192 */
193#define ACTIVE_SP_DESC_INDEX 0
194
195/*
196 * Structure to describe the cumulative properties of the Hypervisor and
197 * NS-Endpoints.
198 */
199struct ns_endpoint_desc {
200 /*
201 * ID of the NS-Endpoint or Hypervisor.
202 */
203 uint16_t ns_ep_id;
204
205 /*
Marc Bonniciecc460a2021-09-02 13:18:41 +0100206 * Mailbox tracking.
207 */
208 struct mailbox mailbox;
209
210 /*
211 * Supported FF-A Version
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000212 */
213 uint32_t ffa_version;
214};
215
Marc Bonnici25f4b542022-04-12 17:18:13 +0100216/* Reference to power management hooks */
217extern const spd_pm_ops_t spmc_pm;
218
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000219/* Setup Function for different SP types. */
220void spmc_sp_common_setup(struct secure_partition_desc *sp,
Achin Guptaeaf17162021-10-19 12:21:16 +0100221 entry_point_info_t *ep_info,
222 int32_t boot_info_reg);
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000223void spmc_el1_sp_setup(struct secure_partition_desc *sp,
224 entry_point_info_t *ep_info);
225void spmc_sp_common_ep_commit(struct secure_partition_desc *sp,
226 entry_point_info_t *ep_info);
227
228/*
229 * Helper function to perform a synchronous entry into a SP.
230 */
231uint64_t spmc_sp_synchronous_entry(struct sp_exec_ctx *ec);
232
233/*
234 * Helper function to obtain the descriptor of the current SP on a physical cpu.
235 */
236struct secure_partition_desc *spmc_get_current_sp_ctx(void);
237
238/*
239 * Helper function to obtain the execution context of an SP on a
240 * physical cpu.
241 */
242struct sp_exec_ctx *spmc_get_sp_ec(struct secure_partition_desc *sp);
243
244/*
245 * Helper function to obtain the index of the execution context of an SP on a
246 * physical cpu.
247 */
248unsigned int get_ec_index(struct secure_partition_desc *sp);
249
250uint64_t spmc_ffa_error_return(void *handle, int error_code);
251
252/*
253 * Ensure a partition ID does not clash and follows the secure world convention.
254 */
255bool is_ffa_secure_id_valid(uint16_t partition_id);
256
Marc Bonnici9a297042022-02-14 17:06:09 +0000257/*
258 * Helper function to obtain the array storing the EL3
259 * Logical Partition descriptors.
260 */
261struct el3_lp_desc *get_el3_lp_array(void);
262
Marc Bonnicia2cfa612021-11-24 10:33:48 +0000263/*
264 * Helper function to obtain the RX/TX buffer pair descriptor of the Hypervisor
265 * or OS kernel in the normal world or the last SP that was run.
266 */
267struct mailbox *spmc_get_mbox_desc(bool secure_origin);
268
Marc Bonnici336630f2022-01-13 11:39:10 +0000269/*
270 * Helper function to obtain the context of an SP with a given partition ID.
271 */
272struct secure_partition_desc *spmc_get_sp_ctx(uint16_t id);
273
Marc Bonnicid1907f02022-04-19 17:42:53 +0100274/*
275 * Add helper function to obtain the FF-A version of the calling
276 * partition.
277 */
278uint32_t get_partition_ffa_version(bool secure_origin);
279
Marc Bonnici336630f2022-01-13 11:39:10 +0000280
Marc Bonnici8e1a7552021-12-01 17:57:04 +0000281#endif /* SPMC_H */