blob: 1f512a7b921e6b4eb45a54ef3bcdd66635190312 [file] [log] [blame]
Imre Kis66321592020-11-23 03:15:50 +01001// SPDX-License-Identifier: BSD-3-Clause
2/*
Imre Kis78f102c2021-01-12 22:27:20 +01003 * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
Imre Kis66321592020-11-23 03:15:50 +01004 */
5
6#include "sp_discovery.h"
7#include "ffa_api.h"
8#include "sp_rxtx.h"
9#include "util.h"
10#include <string.h>
11
12static const struct sp_uuid uuid_nil = {0};
13
14sp_result sp_discovery_ffa_version_get(uint16_t *major, uint16_t *minor)
15{
16 uint32_t version = 0;
17 ffa_result ffa_res = FFA_OK;
18
19 ffa_res = ffa_version(&version);
20 if (ffa_res != FFA_OK) {
21 *major = UINT16_C(0);
22 *minor = UINT16_C(0);
23
24 return SP_RESULT_FFA(ffa_res);
25 }
26
27 *major = (version >> FFA_VERSION_MAJOR_SHIFT) & FFA_VERSION_MAJOR_MASK;
28 *minor = (version >> FFA_VERSION_MINOR_SHIFT) & FFA_VERSION_MINOR_MASK;
29
30 return SP_RESULT_OK;
31}
32
33sp_result sp_discovery_own_id_get(uint16_t *id)
34{
35 ffa_result ffa_res = FFA_OK;
36
37 ffa_res = ffa_id_get(id);
38 return SP_RESULT_FFA(ffa_res);
39}
40
41static sp_result
42partition_info_get(const struct sp_uuid *uuid,
43 const struct ffa_partition_information **info,
44 uint32_t *count)
45{
46 const void *buffer = NULL;
47 size_t buffer_size = 0;
48 struct ffa_uuid ffa_uuid = {0};
49 sp_result sp_res = SP_RESULT_OK;
50 ffa_result ffa_res = FFA_OK;
51
52 sp_res = sp_rxtx_buffer_rx_get(&buffer, &buffer_size);
53 if (sp_res != SP_RESULT_OK) {
54 *count = UINT32_C(0);
55 return sp_res;
56 }
57
58 /* Safely convert to FF-A UUID format */
59 memcpy(&ffa_uuid.uuid, uuid->uuid, sizeof(ffa_uuid.uuid));
60
61 ffa_res = ffa_partition_info_get(&ffa_uuid, count);
62 if (ffa_res != FFA_OK) {
63 *count = UINT32_C(0);
64 return SP_RESULT_FFA(ffa_res);
65 }
66
Imre Kis78f102c2021-01-12 22:27:20 +010067 if ((*count * sizeof(struct ffa_partition_information)) > buffer_size) {
Imre Kis66321592020-11-23 03:15:50 +010068 /*
69 * The indicated amount of info structures doesn't fit into the
70 * RX buffer.
71 */
72 *count = UINT32_C(0);
73 return SP_RESULT_INTERNAL_ERROR;
74 }
75
76 *info = (const struct ffa_partition_information *)buffer;
77
78 return SP_RESULT_OK;
79}
80
81static void unpack_ffa_info(const struct ffa_partition_information ffa_info[],
82 struct sp_partition_info *sp_info)
83{
84 uint32_t props = ffa_info->partition_properties;
85
86 sp_info->partition_id = ffa_info->partition_id;
87 sp_info->execution_context_count = ffa_info->execution_context_count;
88 sp_info->supports_direct_requests =
89 props & FFA_PARTITION_SUPPORTS_DIRECT_REQUESTS;
90 sp_info->can_send_direct_requests =
91 props & FFA_PARTITION_CAN_SEND_DIRECT_REQUESTS;
92 sp_info->supports_indirect_requests =
93 props & FFA_PARTITION_SUPPORTS_INDIRECT_REQUESTS;
94}
95
96sp_result sp_discovery_partition_id_get(const struct sp_uuid *uuid,
97 uint16_t *id)
98{
99 const struct ffa_partition_information *ffa_info = NULL;
100 uint32_t count = 0;
101 sp_result sp_res = SP_RESULT_OK;
102
103 if (uuid == NULL || id == NULL)
104 return SP_RESULT_INVALID_PARAMETERS;
105
106 /*
107 * Nil UUID means querying all partitions which is handled by a separate
108 * function.
109 */
110 if (memcmp(&uuid_nil, uuid, sizeof(struct sp_uuid)) == 0) {
111 *id = FFA_ID_GET_ID_MASK;
112 return SP_RESULT_INVALID_PARAMETERS;
113 }
114
115 sp_res = partition_info_get(uuid, &ffa_info, &count);
116 if (sp_res != SP_RESULT_OK) {
117 *id = FFA_ID_GET_ID_MASK;
118 return sp_res;
119 }
120
121 if (count == 0) {
122 *id = FFA_ID_GET_ID_MASK;
123 return SP_RESULT_NOT_FOUND;
124 }
125
126 *id = ffa_info->partition_id;
127
128 return SP_RESULT_OK;
129}
130
131sp_result sp_discovery_partition_info_get(const struct sp_uuid *uuid,
132 struct sp_partition_info *info)
133{
134 const struct ffa_partition_information *ffa_info = NULL;
135 uint32_t count = 0;
136 sp_result sp_res = SP_RESULT_OK;
137
138 if (uuid == NULL || info == NULL)
139 return SP_RESULT_INVALID_PARAMETERS;
140
141 /*
142 * Nil UUID means querying all partitions which is handled by a separate
143 * function.
144 */
145 if (memcmp(&uuid_nil, uuid, sizeof(struct sp_uuid)) == 0) {
146 *info = (struct sp_partition_info){0};
147 return SP_RESULT_INVALID_PARAMETERS;
148 }
149
150 sp_res = partition_info_get(uuid, &ffa_info, &count);
151 if (sp_res != SP_RESULT_OK) {
152 *info = (struct sp_partition_info){0};
153 return sp_res;
154 }
155
156 if (count == 0) {
157 *info = (struct sp_partition_info){0};
158 return SP_RESULT_NOT_FOUND;
159 }
160
161 unpack_ffa_info(ffa_info, info);
162
163 return SP_RESULT_OK;
164}
165
166sp_result sp_discovery_partition_info_get_all(struct sp_partition_info info[],
167 uint32_t *count)
168{
169 const struct ffa_partition_information *ffa_info = NULL;
170 uint32_t ffa_count = 0;
171 uint32_t i = 0;
172 sp_result sp_res = SP_RESULT_OK;
173
174 if (info == NULL || count == NULL)
175 return SP_RESULT_INVALID_PARAMETERS;
176
177 sp_res = partition_info_get(&uuid_nil, &ffa_info, &ffa_count);
178 if (sp_res != SP_RESULT_OK) {
179 *count = UINT32_C(0);
180 return sp_res;
181 }
182
183 *count = MIN(*count, ffa_count);
184 for (i = 0; i < *count; i++)
185 unpack_ffa_info(&ffa_info[i], &info[i]);
186
187 return SP_RESULT_OK;
188}