blob: ee2a3ccbc224cb2afe24921e08052f75d1208688 [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"
Raghu Krishnamurthyb49549e2021-07-02 08:27:38 -070012#include "hf/manifest.h"
Olivier Deprez55a189e2021-06-09 15:45:27 +020013#include "hf/vcpu.h"
J-Alvesc003a7a2021-03-18 13:06:53 +000014#include "hf/vm.h"
Daniel Boulbyb2fb80e2021-02-03 15:09:23 +000015
J-Alves13394022021-06-30 13:48:49 +010016/**
17 * The following enum relates to a state machine to guide the handling of the
18 * Scheduler Receiver Interrupt.
19 * The SRI is used to signal the receiver scheduler that there are pending
20 * notifications for the receiver, and it is sent when there is a valid call to
21 * FFA_NOTIFICATION_SET.
22 * The FFA_NOTIFICATION_INFO_GET interface must be called in the SRI handler,
23 * after which the FF-A driver should process the returned list, and request
24 * the receiver scheduler to give the receiver CPU cycles to process the
25 * notification.
26 * The use of the following state machine allows for synchronized sending
27 * and handling of the SRI, as well as avoiding the occurrence of spurious
28 * SRI. A spurious SRI would be one such that upon handling a call to
29 * FFA_NOTIFICATION_INFO_GET would return error FFA_NO_DATA, which is plausible
30 * in an MP system.
31 * The state machine also aims at resolving the delay of the SRI by setting
32 * flag FFA_NOTIFICATIONS_FLAG_DELAY_SRI in the arguments of the set call. By
33 * delaying, the SRI is sent in context switching to the primary endpoint.
34 * The SPMC is implemented under the assumption the receiver scheduler is a
35 * NWd endpoint, hence the SRI is triggered at the world switch.
36 * If concurrently another notification is set that requires immediate action,
37 * the SRI is triggered immediately within that same execution context.
38 *
39 * HANDLED is the initial state, and means a new SRI can be sent. The following
40 * state transitions are possible:
41 * * HANDLED => DELAYED: Setting notification, and requesting SRI delay.
42 * * HANDLED => TRIGGERED: Setting notification, and not requesting SRI delay.
43 * * DELAYED => TRIGGERED: SRI was delayed, and the context switch to the
44 * receiver scheduler is being done.
45 * * DELAYED => HANDLED: the scheduler called FFA_NOTIFICATION_INFO_GET.
46 * * TRIGGERED => HANDLED: the scheduler called FFA_NOTIFICATION_INFO_GET.
47 */
48enum plat_ffa_sri_state {
49 HANDLED = 0,
50 DELAYED,
51 TRIGGERED,
52};
53
Daniel Boulby87b2dc82021-08-04 14:07:43 +010054/** Returns information on features that are specific to the platform. */
J-Alves6f72ca82021-11-01 12:34:58 +000055struct ffa_value plat_ffa_features(uint32_t function_feature_id);
Daniel Boulbyb2fb80e2021-02-03 15:09:23 +000056/** Returns the SPMC ID. */
57struct ffa_value plat_ffa_spmc_id_get(void);
Olivier Deprez55a189e2021-06-09 15:45:27 +020058
59void plat_ffa_log_init(void);
60void plat_ffa_init(bool tee_enabled);
61bool plat_ffa_is_direct_request_valid(struct vcpu *current,
62 ffa_vm_id_t sender_vm_id,
63 ffa_vm_id_t receiver_vm_id);
64bool plat_ffa_is_direct_response_valid(struct vcpu *current,
65 ffa_vm_id_t sender_vm_id,
66 ffa_vm_id_t receiver_vm_id);
67bool plat_ffa_direct_request_forward(ffa_vm_id_t receiver_vm_id,
68 struct ffa_value args,
69 struct ffa_value *ret);
J-Alvesa0f317d2021-06-09 13:31:59 +010070bool plat_ffa_is_notifications_create_valid(struct vcpu *current,
71 ffa_vm_id_t vm_id);
J-Alvesc003a7a2021-03-18 13:06:53 +000072
73bool plat_ffa_is_notifications_bind_valid(struct vcpu *current,
74 ffa_vm_id_t sender_id,
75 ffa_vm_id_t receiver_id);
J-Alvesb15e9402021-09-08 11:44:42 +010076bool plat_ffa_notifications_update_bindings_forward(
77 ffa_vm_id_t receiver_id, ffa_vm_id_t sender_id, uint32_t flags,
78 ffa_notifications_bitmap_t bitmap, bool is_bind, struct ffa_value *ret);
J-Alvesc003a7a2021-03-18 13:06:53 +000079
J-Alvesaa79c012021-07-09 14:29:45 +010080bool plat_ffa_is_notification_set_valid(struct vcpu *current,
81 ffa_vm_id_t sender_id,
82 ffa_vm_id_t receiver_id);
83
J-Alvesde7bd2f2021-09-09 19:54:35 +010084bool plat_ffa_notification_set_forward(ffa_vm_id_t sender_vm_id,
85 ffa_vm_id_t receiver_vm_id,
86 uint32_t flags,
87 ffa_notifications_bitmap_t bitmap,
88 struct ffa_value *ret);
89
J-Alvesaa79c012021-07-09 14:29:45 +010090bool plat_ffa_is_notification_get_valid(struct vcpu *current,
91 ffa_vm_id_t receiver_id);
92
J-Alves98ff9562021-09-09 14:39:41 +010093bool plat_ffa_notifications_get_from_sp(struct vm_locked receiver_locked,
94 ffa_vcpu_index_t vcpu_id,
95 ffa_notifications_bitmap_t *from_sp,
96 struct ffa_value *ret);
97
J-Alvesaa79c012021-07-09 14:29:45 +010098bool plat_ffa_notifications_get_call(ffa_vm_id_t receiver_id, uint32_t vcpu_id,
99 uint32_t flags, struct ffa_value *ret);
100
Olivier Deprez55a189e2021-06-09 15:45:27 +0200101/**
Maksims Svecovs9ddf86a2021-05-06 17:17:21 +0100102 * Checks whether managed exit is supported by given SP.
103 */
104bool plat_ffa_vm_managed_exit_supported(struct vm *vm);
105
106/**
Olivier Deprez55a189e2021-06-09 15:45:27 +0200107 * Encodes memory handle according to section 5.10.2 of the FF-A v1.0 spec.
108 */
109ffa_memory_handle_t plat_ffa_memory_handle_make(uint64_t index);
110
111/**
112 * Checks whether given handle was allocated by current world, according to
113 * handle encoding rules.
114 */
115bool plat_ffa_memory_handle_allocated_by_current_world(
116 ffa_memory_handle_t handle);
Maksims Svecovsb596eab2021-04-27 00:52:27 +0100117
118/**
119 * Return the FF-A partition info VM/SP properties given the VM id.
120 */
121ffa_partition_properties_t plat_ffa_partition_properties(
J-Alvesfa782092021-10-13 16:02:16 +0100122 ffa_vm_id_t vm_id, const struct vm *target);
J-Alvesa0f317d2021-06-09 13:31:59 +0100123
124/**
125 * Get NWd VM's structure.
126 */
127struct vm_locked plat_ffa_vm_find_locked(ffa_vm_id_t vm_id);
128
129/**
130 * Creates a bitmap for the VM of the given ID.
131 */
132struct ffa_value plat_ffa_notifications_bitmap_create(
133 ffa_vm_id_t vm_id, ffa_vcpu_count_t vcpu_count);
134
135/**
J-Alvesa9c7cba2021-08-25 16:26:11 +0100136 * Issues a FFA_NOTIFICATION_BITMAP_CREATE.
J-Alvesa4730db2021-11-02 10:31:01 +0000137 * Returns true if the call goes well, and false if call returns with
138 * FFA_ERROR_32.
J-Alvesa9c7cba2021-08-25 16:26:11 +0100139 */
140bool plat_ffa_notifications_bitmap_create_call(ffa_vm_id_t vm_id,
J-Alvesa4730db2021-11-02 10:31:01 +0000141 ffa_vcpu_count_t vcpu_count);
J-Alvesa9c7cba2021-08-25 16:26:11 +0100142
143/**
J-Alvesa0f317d2021-06-09 13:31:59 +0100144 * Destroys the notifications bitmap for the given VM ID.
145 */
146struct ffa_value plat_ffa_notifications_bitmap_destroy(ffa_vm_id_t vm_id);
J-Alvesc003a7a2021-03-18 13:06:53 +0000147
148/**
149 * Helper to get the struct notifications, depending on the sender's id.
150 */
151struct notifications *plat_ffa_vm_get_notifications_senders_world(
152 struct vm_locked vm_locked, ffa_vm_id_t sender_id);
153
154/**
155 * Helper to check if FF-A ID is a VM ID.
156 */
157bool plat_ffa_is_vm_id(ffa_vm_id_t vm_id);
Raghu Krishnamurthy62f97a72021-07-27 02:14:59 -0700158
159/**
160 * Forward normal world calls of FFA_RUN ABI to other world.
161 */
162bool plat_ffa_run_forward(ffa_vm_id_t vm_id, ffa_vcpu_index_t vcpu_idx,
163 struct ffa_value *ret);
J-Alvesc8e8a222021-06-08 17:33:52 +0100164
165bool plat_ffa_notification_info_get_call(struct ffa_value *ret);
166
167bool plat_ffa_vm_notifications_info_get(uint16_t *ids, uint32_t *ids_count,
168 uint32_t *lists_sizes,
169 uint32_t *lists_count,
170 const uint32_t ids_count_max);
Raghu Krishnamurthyea6d25f2021-09-14 15:27:06 -0700171
J-Alves13394022021-06-30 13:48:49 +0100172/** Helper to set SRI current state. */
173void plat_ffa_sri_state_set(enum plat_ffa_sri_state state);
174
175/**
176 * Helper to send SRI and safely update `ffa_sri_state`, if there has been
177 * a call to FFA_NOTIFICATION_SET, and the SRI has been delayed.
178 * To be called at a context switch to the NWd.
179 */
180void plat_ffa_sri_trigger_if_delayed(struct cpu *cpu);
181
182/**
183 * Helper to send SRI and safely update `ffa_sri_state`, if it hasn't been
184 * delayed in call to FFA_NOTIFICATION_SET.
185 */
186void plat_ffa_sri_trigger_not_delayed(struct cpu *cpu);
187
188/**
189 * Initialize Schedule Receiver Interrupts needed in the context of
190 * notifications support.
191 */
192void plat_ffa_sri_init(struct cpu *cpu);
193
J-Alvesca058c22021-09-10 14:02:07 +0100194void plat_ffa_notification_info_get_forward(uint16_t *ids, uint32_t *ids_count,
195 uint32_t *lists_sizes,
196 uint32_t *lists_count,
197 const uint32_t ids_count_max);
198
Raghu Krishnamurthyea6d25f2021-09-14 15:27:06 -0700199bool plat_ffa_is_mem_perm_get_valid(const struct vcpu *current);
200bool plat_ffa_is_mem_perm_set_valid(const struct vcpu *current);
Madhukar Pappireddyb11e0d12021-08-02 19:44:35 -0500201
202/**
203 * Check if current SP can resume target VM/SP using FFA_RUN ABI.
204 */
205bool plat_ffa_run_checks(struct vcpu *current, ffa_vm_id_t target_vm_id,
Raghu Krishnamurthy048d63f2021-12-11 12:45:41 -0800206 ffa_vcpu_index_t vcpu_idx, struct ffa_value *run_ret,
207 struct vcpu **next);
Madhukar Pappireddyf675bb62021-08-03 12:57:10 -0500208
209/**
210 * Deactivate interrupt.
211 */
212int64_t plat_ffa_interrupt_deactivate(uint32_t pint_id, uint32_t vint_id,
213 struct vcpu *current);
Madhukar Pappireddycbecc962021-08-03 13:11:57 -0500214
215void plat_ffa_secure_interrupt(struct vcpu *current, struct vcpu **next);
Madhukar Pappireddy9e7a11f2021-08-03 13:59:42 -0500216struct ffa_value plat_ffa_delegate_ffa_interrupt(struct vcpu *current,
217 struct vcpu **next);
Madhukar Pappireddyed4ab942021-08-03 14:22:53 -0500218struct ffa_value plat_ffa_normal_world_resume(struct vcpu *current,
219 struct vcpu **next);
220struct ffa_value plat_ffa_preempted_vcpu_resume(struct vcpu *current,
221 struct vcpu **next);
J-Alves7461ef22021-10-18 17:21:33 +0100222
223void plat_ffa_inject_notification_pending_interrupt_context_switch(
224 struct vcpu *next, struct vcpu *current);
Olivier Depreze562e542020-06-11 17:31:54 +0200225
226void plat_ffa_partition_info_get_forward(const struct ffa_uuid *uuid,
Daniel Boulbyb46cad12021-12-13 17:47:21 +0000227 const uint32_t flags,
Olivier Depreze562e542020-06-11 17:31:54 +0200228 struct ffa_partition_info *partitions,
229 ffa_vm_count_t *ret_count);
Raghu Krishnamurthyb49549e2021-07-02 08:27:38 -0700230
231void plat_ffa_parse_partition_manifest(struct mm_stage1_locked stage1_locked,
232 paddr_t fdt_addr,
233 size_t fdt_allocated_size,
234 const struct manifest_vm *manifest_vm,
235 struct mpool *ppool);