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