1 /*
2  * Copyright 2024 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 #include "hf/ffa/setup_and_discovery.h"
10 
11 #include "hf/check.h"
12 #include "hf/manifest.h"
13 #include "hf/vm.h"
14 
15 #include "smc.h"
16 
ffa_setup_spmc_id_get(void)17 struct ffa_value ffa_setup_spmc_id_get(void)
18 {
19 	/*
20 	 * Since we are running in the SPMC use FFA_ID_GET to fetch our
21 	 * ID from the SPMD.
22 	 */
23 	return smc_ffa_call((struct ffa_value){.func = FFA_ID_GET_32});
24 }
25 
26 /**
27  * Returns FFA_SUCCESS as FFA_SECONDARY_EP_REGISTER is supported at the
28  * secure virtual FF-A instance.
29  */
ffa_setup_is_secondary_ep_register_supported(void)30 bool ffa_setup_is_secondary_ep_register_supported(void)
31 {
32 	return true;
33 }
34 
ffa_setup_rxtx_map_forward(struct vm_locked vm_locked)35 void ffa_setup_rxtx_map_forward(struct vm_locked vm_locked)
36 {
37 	(void)vm_locked;
38 }
39 
ffa_setup_rxtx_unmap_forward(struct vm_locked vm_locked)40 void ffa_setup_rxtx_unmap_forward(struct vm_locked vm_locked)
41 {
42 	(void)vm_locked;
43 }
44 
ffa_setup_partition_info_get_regs_forward_allowed(void)45 bool ffa_setup_partition_info_get_regs_forward_allowed(void)
46 {
47 	/*
48 	 * Allow forwarding from the SPMC to SPMD unconditionally.
49 	 */
50 	return true;
51 }
52 
53 /** Forward helper for FFA_PARTITION_INFO_GET. */
ffa_setup_partition_info_get_forward(const struct ffa_uuid * uuid,uint32_t flags,struct ffa_partition_info * partitions,const size_t partitions_max_len,size_t entries_count)54 size_t ffa_setup_partition_info_get_forward(
55 	const struct ffa_uuid *uuid, uint32_t flags,
56 	struct ffa_partition_info *partitions, const size_t partitions_max_len,
57 	size_t entries_count)
58 {
59 	/*
60 	 * The SPMC does not forward FFA_PARTITION_INFO_GET.
61 	 * Discovery of LSPs should be done vai FFA_PARTITION_INFO_GET_REGS.
62 	 * The SPMD doesn't access RXTX buffers.
63 	 */
64 
65 	(void)uuid;
66 	(void)flags;
67 	(void)partitions;
68 	(void)partitions_max_len;
69 
70 	return entries_count;
71 }
72 
ffa_setup_parse_partition_manifest(struct mm_stage1_locked stage1_locked,paddr_t fdt_addr,size_t fdt_allocated_size,const struct manifest_vm * manifest_vm,const struct boot_params * boot_params,struct mpool * ppool)73 void ffa_setup_parse_partition_manifest(struct mm_stage1_locked stage1_locked,
74 					paddr_t fdt_addr,
75 					size_t fdt_allocated_size,
76 					const struct manifest_vm *manifest_vm,
77 					const struct boot_params *boot_params,
78 					struct mpool *ppool)
79 {
80 	(void)boot_params;
81 	(void)stage1_locked;
82 	(void)fdt_addr;
83 	(void)fdt_allocated_size;
84 	(void)manifest_vm;
85 	(void)ppool;
86 	/* should never be called in SPMC */
87 	CHECK(false);
88 }
89 
ffa_setup_partition_properties(ffa_id_t caller_id,const struct vm * target)90 ffa_partition_properties_t ffa_setup_partition_properties(
91 	ffa_id_t caller_id, const struct vm *target)
92 {
93 	ffa_partition_properties_t result = target->messaging_method;
94 	bool is_ffa_version_ge_v1_2 = (target->ffa_version >= FFA_VERSION_1_2);
95 	ffa_partition_properties_t final_mask;
96 	ffa_partition_properties_t dir_msg_mask = FFA_PARTITION_DIRECT_REQ_RECV;
97 	ffa_partition_properties_t dir_msg2_mask =
98 		FFA_PARTITION_DIRECT_REQ2_RECV;
99 
100 	/*
101 	 * SPs support full direct messaging communication with other SPs,
102 	 * and are allowed to only receive direct requests from the other world.
103 	 * SPs cannot send direct requests to the other world.
104 	 *
105 	 * If caller is an SP, advertise that target can send messages.
106 	 * If caller is a VM, advertise that target can't send messages.
107 	 */
108 	if (vm_id_is_current_world(caller_id)) {
109 		dir_msg_mask |= FFA_PARTITION_DIRECT_REQ_SEND;
110 		dir_msg2_mask |= FFA_PARTITION_DIRECT_REQ2_SEND;
111 	}
112 
113 	/* Consider dir_msg2_mask if FFA_VERSION is 1.2 or above. */
114 	final_mask = is_ffa_version_ge_v1_2 ? (dir_msg2_mask | dir_msg_mask)
115 					    : dir_msg_mask;
116 
117 	return result & final_mask;
118 }
119 
ffa_setup_rx_release_forward(struct vm_locked vm_locked,struct ffa_value * ret)120 bool ffa_setup_rx_release_forward(struct vm_locked vm_locked,
121 				  struct ffa_value *ret)
122 {
123 	(void)vm_locked;
124 	(void)ret;
125 
126 	return false;
127 }
128 
ffa_setup_acquire_receiver_rx(struct vm_locked to_locked,struct ffa_value * ret)129 bool ffa_setup_acquire_receiver_rx(struct vm_locked to_locked,
130 				   struct ffa_value *ret)
131 {
132 	(void)to_locked;
133 	(void)ret;
134 
135 	return true;
136 }
137