blob: a4d0dc594276d52ff9f167bfb2deb63afcfc0463 [file] [log] [blame]
Daniel Boulbyb2fb80e2021-02-03 15:09:23 +00001/*
2 * Copyright 2021 The Hafnium Authors.
3 *
4 * Use of this source code is governed by a BSD-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/BSD-3-Clause.
7 */
8
9#pragma once
10
11#include "hf/ffa.h"
Olivier Deprez55a189e2021-06-09 15:45:27 +020012#include "hf/vcpu.h"
J-Alvesc003a7a2021-03-18 13:06:53 +000013#include "hf/vm.h"
Daniel Boulbyb2fb80e2021-02-03 15:09:23 +000014
J-Alves13394022021-06-30 13:48:49 +010015/**
16 * The following enum relates to a state machine to guide the handling of the
17 * Scheduler Receiver Interrupt.
18 * The SRI is used to signal the receiver scheduler that there are pending
19 * notifications for the receiver, and it is sent when there is a valid call to
20 * FFA_NOTIFICATION_SET.
21 * The FFA_NOTIFICATION_INFO_GET interface must be called in the SRI handler,
22 * after which the FF-A driver should process the returned list, and request
23 * the receiver scheduler to give the receiver CPU cycles to process the
24 * notification.
25 * The use of the following state machine allows for synchronized sending
26 * and handling of the SRI, as well as avoiding the occurrence of spurious
27 * SRI. A spurious SRI would be one such that upon handling a call to
28 * FFA_NOTIFICATION_INFO_GET would return error FFA_NO_DATA, which is plausible
29 * in an MP system.
30 * The state machine also aims at resolving the delay of the SRI by setting
31 * flag FFA_NOTIFICATIONS_FLAG_DELAY_SRI in the arguments of the set call. By
32 * delaying, the SRI is sent in context switching to the primary endpoint.
33 * The SPMC is implemented under the assumption the receiver scheduler is a
34 * NWd endpoint, hence the SRI is triggered at the world switch.
35 * If concurrently another notification is set that requires immediate action,
36 * the SRI is triggered immediately within that same execution context.
37 *
38 * HANDLED is the initial state, and means a new SRI can be sent. The following
39 * state transitions are possible:
40 * * HANDLED => DELAYED: Setting notification, and requesting SRI delay.
41 * * HANDLED => TRIGGERED: Setting notification, and not requesting SRI delay.
42 * * DELAYED => TRIGGERED: SRI was delayed, and the context switch to the
43 * receiver scheduler is being done.
44 * * DELAYED => HANDLED: the scheduler called FFA_NOTIFICATION_INFO_GET.
45 * * TRIGGERED => HANDLED: the scheduler called FFA_NOTIFICATION_INFO_GET.
46 */
47enum plat_ffa_sri_state {
48 HANDLED = 0,
49 DELAYED,
50 TRIGGERED,
51};
52
Daniel Boulby87b2dc82021-08-04 14:07:43 +010053/** Returns information on features that are specific to the platform. */
J-Alves6f72ca82021-11-01 12:34:58 +000054struct ffa_value plat_ffa_features(uint32_t function_feature_id);
Daniel Boulbyb2fb80e2021-02-03 15:09:23 +000055/** Returns the SPMC ID. */
56struct ffa_value plat_ffa_spmc_id_get(void);
Olivier Deprez55a189e2021-06-09 15:45:27 +020057
58void plat_ffa_log_init(void);
59void plat_ffa_init(bool tee_enabled);
60bool plat_ffa_is_direct_request_valid(struct vcpu *current,
61 ffa_vm_id_t sender_vm_id,
62 ffa_vm_id_t receiver_vm_id);
63bool plat_ffa_is_direct_response_valid(struct vcpu *current,
64 ffa_vm_id_t sender_vm_id,
65 ffa_vm_id_t receiver_vm_id);
66bool plat_ffa_direct_request_forward(ffa_vm_id_t receiver_vm_id,
67 struct ffa_value args,
68 struct ffa_value *ret);
J-Alvesa0f317d2021-06-09 13:31:59 +010069bool plat_ffa_is_notifications_create_valid(struct vcpu *current,
70 ffa_vm_id_t vm_id);
J-Alvesc003a7a2021-03-18 13:06:53 +000071
72bool plat_ffa_is_notifications_bind_valid(struct vcpu *current,
73 ffa_vm_id_t sender_id,
74 ffa_vm_id_t receiver_id);
J-Alvesb15e9402021-09-08 11:44:42 +010075bool plat_ffa_notifications_update_bindings_forward(
76 ffa_vm_id_t receiver_id, ffa_vm_id_t sender_id, uint32_t flags,
77 ffa_notifications_bitmap_t bitmap, bool is_bind, struct ffa_value *ret);
J-Alvesc003a7a2021-03-18 13:06:53 +000078
J-Alvesaa79c012021-07-09 14:29:45 +010079bool plat_ffa_is_notification_set_valid(struct vcpu *current,
80 ffa_vm_id_t sender_id,
81 ffa_vm_id_t receiver_id);
82
J-Alvesde7bd2f2021-09-09 19:54:35 +010083bool plat_ffa_notification_set_forward(ffa_vm_id_t sender_vm_id,
84 ffa_vm_id_t receiver_vm_id,
85 uint32_t flags,
86 ffa_notifications_bitmap_t bitmap,
87 struct ffa_value *ret);
88
J-Alvesaa79c012021-07-09 14:29:45 +010089bool plat_ffa_is_notification_get_valid(struct vcpu *current,
90 ffa_vm_id_t receiver_id);
91
J-Alves98ff9562021-09-09 14:39:41 +010092bool plat_ffa_notifications_get_from_sp(struct vm_locked receiver_locked,
93 ffa_vcpu_index_t vcpu_id,
94 ffa_notifications_bitmap_t *from_sp,
95 struct ffa_value *ret);
96
J-Alvesaa79c012021-07-09 14:29:45 +010097bool plat_ffa_notifications_get_call(ffa_vm_id_t receiver_id, uint32_t vcpu_id,
98 uint32_t flags, struct ffa_value *ret);
99
Olivier Deprez55a189e2021-06-09 15:45:27 +0200100/**
Maksims Svecovs9ddf86a2021-05-06 17:17:21 +0100101 * Checks whether managed exit is supported by given SP.
102 */
103bool plat_ffa_vm_managed_exit_supported(struct vm *vm);
104
105/**
Olivier Deprez55a189e2021-06-09 15:45:27 +0200106 * Encodes memory handle according to section 5.10.2 of the FF-A v1.0 spec.
107 */
108ffa_memory_handle_t plat_ffa_memory_handle_make(uint64_t index);
109
110/**
111 * Checks whether given handle was allocated by current world, according to
112 * handle encoding rules.
113 */
114bool plat_ffa_memory_handle_allocated_by_current_world(
115 ffa_memory_handle_t handle);
Maksims Svecovsb596eab2021-04-27 00:52:27 +0100116
117/**
118 * Return the FF-A partition info VM/SP properties given the VM id.
119 */
120ffa_partition_properties_t plat_ffa_partition_properties(
J-Alvesfa782092021-10-13 16:02:16 +0100121 ffa_vm_id_t vm_id, const struct vm *target);
J-Alvesa0f317d2021-06-09 13:31:59 +0100122
123/**
124 * Get NWd VM's structure.
125 */
126struct vm_locked plat_ffa_vm_find_locked(ffa_vm_id_t vm_id);
127
128/**
129 * Creates a bitmap for the VM of the given ID.
130 */
131struct ffa_value plat_ffa_notifications_bitmap_create(
132 ffa_vm_id_t vm_id, ffa_vcpu_count_t vcpu_count);
133
134/**
J-Alvesa9c7cba2021-08-25 16:26:11 +0100135 * Issues a FFA_NOTIFICATION_BITMAP_CREATE.
J-Alvesa4730db2021-11-02 10:31:01 +0000136 * Returns true if the call goes well, and false if call returns with
137 * FFA_ERROR_32.
J-Alvesa9c7cba2021-08-25 16:26:11 +0100138 */
139bool plat_ffa_notifications_bitmap_create_call(ffa_vm_id_t vm_id,
J-Alvesa4730db2021-11-02 10:31:01 +0000140 ffa_vcpu_count_t vcpu_count);
J-Alvesa9c7cba2021-08-25 16:26:11 +0100141
142/**
J-Alvesa0f317d2021-06-09 13:31:59 +0100143 * Destroys the notifications bitmap for the given VM ID.
144 */
145struct ffa_value plat_ffa_notifications_bitmap_destroy(ffa_vm_id_t vm_id);
J-Alvesc003a7a2021-03-18 13:06:53 +0000146
147/**
148 * Helper to get the struct notifications, depending on the sender's id.
149 */
150struct notifications *plat_ffa_vm_get_notifications_senders_world(
151 struct vm_locked vm_locked, ffa_vm_id_t sender_id);
152
153/**
154 * Helper to check if FF-A ID is a VM ID.
155 */
156bool plat_ffa_is_vm_id(ffa_vm_id_t vm_id);
Raghu Krishnamurthy62f97a72021-07-27 02:14:59 -0700157
158/**
159 * Forward normal world calls of FFA_RUN ABI to other world.
160 */
161bool plat_ffa_run_forward(ffa_vm_id_t vm_id, ffa_vcpu_index_t vcpu_idx,
162 struct ffa_value *ret);
J-Alvesc8e8a222021-06-08 17:33:52 +0100163
164bool plat_ffa_notification_info_get_call(struct ffa_value *ret);
165
166bool plat_ffa_vm_notifications_info_get(uint16_t *ids, uint32_t *ids_count,
167 uint32_t *lists_sizes,
168 uint32_t *lists_count,
169 const uint32_t ids_count_max);
Raghu Krishnamurthyea6d25f2021-09-14 15:27:06 -0700170
J-Alves13394022021-06-30 13:48:49 +0100171/** Helper to set SRI current state. */
172void plat_ffa_sri_state_set(enum plat_ffa_sri_state state);
173
174/**
175 * Helper to send SRI and safely update `ffa_sri_state`, if there has been
176 * a call to FFA_NOTIFICATION_SET, and the SRI has been delayed.
177 * To be called at a context switch to the NWd.
178 */
179void plat_ffa_sri_trigger_if_delayed(struct cpu *cpu);
180
181/**
182 * Helper to send SRI and safely update `ffa_sri_state`, if it hasn't been
183 * delayed in call to FFA_NOTIFICATION_SET.
184 */
185void plat_ffa_sri_trigger_not_delayed(struct cpu *cpu);
186
187/**
188 * Initialize Schedule Receiver Interrupts needed in the context of
189 * notifications support.
190 */
191void plat_ffa_sri_init(struct cpu *cpu);
192
J-Alvesca058c22021-09-10 14:02:07 +0100193void plat_ffa_notification_info_get_forward(uint16_t *ids, uint32_t *ids_count,
194 uint32_t *lists_sizes,
195 uint32_t *lists_count,
196 const uint32_t ids_count_max);
197
Raghu Krishnamurthyea6d25f2021-09-14 15:27:06 -0700198bool plat_ffa_is_mem_perm_get_valid(const struct vcpu *current);
199bool plat_ffa_is_mem_perm_set_valid(const struct vcpu *current);
Madhukar Pappireddyb11e0d12021-08-02 19:44:35 -0500200
201/**
202 * Check if current SP can resume target VM/SP using FFA_RUN ABI.
203 */
204bool plat_ffa_run_checks(struct vcpu *current, ffa_vm_id_t target_vm_id,
205 struct ffa_value *run_ret, struct vcpu **next);
Madhukar Pappireddyf675bb62021-08-03 12:57:10 -0500206
207/**
208 * Deactivate interrupt.
209 */
210int64_t plat_ffa_interrupt_deactivate(uint32_t pint_id, uint32_t vint_id,
211 struct vcpu *current);
Madhukar Pappireddycbecc962021-08-03 13:11:57 -0500212
213void plat_ffa_secure_interrupt(struct vcpu *current, struct vcpu **next);
Madhukar Pappireddy9e7a11f2021-08-03 13:59:42 -0500214struct ffa_value plat_ffa_delegate_ffa_interrupt(struct vcpu *current,
215 struct vcpu **next);
Madhukar Pappireddyed4ab942021-08-03 14:22:53 -0500216struct ffa_value plat_ffa_normal_world_resume(struct vcpu *current,
217 struct vcpu **next);
218struct ffa_value plat_ffa_preempted_vcpu_resume(struct vcpu *current,
219 struct vcpu **next);
J-Alves7461ef22021-10-18 17:21:33 +0100220
221void plat_ffa_inject_notification_pending_interrupt_context_switch(
222 struct vcpu *next, struct vcpu *current);