blob: 8ce3d10a1e69ccd1060b4840fcd6204c3a288704 [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. */
54struct ffa_value plat_ffa_features(uint32_t function_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.
136 */
137bool plat_ffa_notifications_bitmap_create_call(ffa_vm_id_t vm_id,
138 ffa_vcpu_count_t vcpu_count,
139 struct ffa_value *ret);
140
141/**
J-Alvesa0f317d2021-06-09 13:31:59 +0100142 * Destroys the notifications bitmap for the given VM ID.
143 */
144struct ffa_value plat_ffa_notifications_bitmap_destroy(ffa_vm_id_t vm_id);
J-Alvesc003a7a2021-03-18 13:06:53 +0000145
146/**
147 * Helper to get the struct notifications, depending on the sender's id.
148 */
149struct notifications *plat_ffa_vm_get_notifications_senders_world(
150 struct vm_locked vm_locked, ffa_vm_id_t sender_id);
151
152/**
153 * Helper to check if FF-A ID is a VM ID.
154 */
155bool plat_ffa_is_vm_id(ffa_vm_id_t vm_id);
Raghu Krishnamurthy62f97a72021-07-27 02:14:59 -0700156
157/**
158 * Forward normal world calls of FFA_RUN ABI to other world.
159 */
160bool plat_ffa_run_forward(ffa_vm_id_t vm_id, ffa_vcpu_index_t vcpu_idx,
161 struct ffa_value *ret);
J-Alvesc8e8a222021-06-08 17:33:52 +0100162
163bool plat_ffa_notification_info_get_call(struct ffa_value *ret);
164
165bool plat_ffa_vm_notifications_info_get(uint16_t *ids, uint32_t *ids_count,
166 uint32_t *lists_sizes,
167 uint32_t *lists_count,
168 const uint32_t ids_count_max);
Raghu Krishnamurthyea6d25f2021-09-14 15:27:06 -0700169
J-Alves13394022021-06-30 13:48:49 +0100170/** Helper to set SRI current state. */
171void plat_ffa_sri_state_set(enum plat_ffa_sri_state state);
172
173/**
174 * Helper to send SRI and safely update `ffa_sri_state`, if there has been
175 * a call to FFA_NOTIFICATION_SET, and the SRI has been delayed.
176 * To be called at a context switch to the NWd.
177 */
178void plat_ffa_sri_trigger_if_delayed(struct cpu *cpu);
179
180/**
181 * Helper to send SRI and safely update `ffa_sri_state`, if it hasn't been
182 * delayed in call to FFA_NOTIFICATION_SET.
183 */
184void plat_ffa_sri_trigger_not_delayed(struct cpu *cpu);
185
186/**
187 * Initialize Schedule Receiver Interrupts needed in the context of
188 * notifications support.
189 */
190void plat_ffa_sri_init(struct cpu *cpu);
191
J-Alvesca058c22021-09-10 14:02:07 +0100192void plat_ffa_notification_info_get_forward(uint16_t *ids, uint32_t *ids_count,
193 uint32_t *lists_sizes,
194 uint32_t *lists_count,
195 const uint32_t ids_count_max);
196
Raghu Krishnamurthyea6d25f2021-09-14 15:27:06 -0700197bool plat_ffa_is_mem_perm_get_valid(const struct vcpu *current);
198bool plat_ffa_is_mem_perm_set_valid(const struct vcpu *current);
Madhukar Pappireddyb11e0d12021-08-02 19:44:35 -0500199
200/**
201 * Check if current SP can resume target VM/SP using FFA_RUN ABI.
202 */
203bool plat_ffa_run_checks(struct vcpu *current, ffa_vm_id_t target_vm_id,
204 struct ffa_value *run_ret, struct vcpu **next);
Madhukar Pappireddyf675bb62021-08-03 12:57:10 -0500205
206/**
207 * Deactivate interrupt.
208 */
209int64_t plat_ffa_interrupt_deactivate(uint32_t pint_id, uint32_t vint_id,
210 struct vcpu *current);
Madhukar Pappireddycbecc962021-08-03 13:11:57 -0500211
212void plat_ffa_secure_interrupt(struct vcpu *current, struct vcpu **next);
Madhukar Pappireddy9e7a11f2021-08-03 13:59:42 -0500213struct ffa_value plat_ffa_delegate_ffa_interrupt(struct vcpu *current,
214 struct vcpu **next);
Madhukar Pappireddyed4ab942021-08-03 14:22:53 -0500215struct ffa_value plat_ffa_normal_world_resume(struct vcpu *current,
216 struct vcpu **next);
217struct ffa_value plat_ffa_preempted_vcpu_resume(struct vcpu *current,
218 struct vcpu **next);
J-Alves7461ef22021-10-18 17:21:33 +0100219
220void plat_ffa_inject_notification_pending_interrupt_context_switch(
221 struct vcpu *next, struct vcpu *current);