blob: e78c93d0c0f025b5b30793ae3d734afcbb684a1c [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
Imre Kisc81995e2021-01-12 22:28:21 +010012static const struct sp_uuid uuid_nil = { 0 };
Imre Kis66321592020-11-23 03:15:50 +010013
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;
Imre Kisc81995e2021-01-12 22:28:21 +010048 struct ffa_uuid ffa_uuid = { 0 };
Imre Kis66321592020-11-23 03:15:50 +010049 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
Imre Kisc81995e2021-01-12 22:28:21 +010081static sp_result
82partition_info_get_single(const struct sp_uuid *uuid,
83 const struct ffa_partition_information **info)
84{
85 uint32_t count = 0;
86 sp_result sp_res = SP_RESULT_OK;
87
88 if (uuid == NULL)
89 return SP_RESULT_INVALID_PARAMETERS;
90
91 /*
92 * Nil UUID means querying all partitions which is handled by a separate
93 * function.
94 */
95 if (memcmp(&uuid_nil, uuid, sizeof(struct sp_uuid)) == 0)
96 return SP_RESULT_INVALID_PARAMETERS;
97
98 sp_res = partition_info_get(uuid, info, &count);
99 if (sp_res != SP_RESULT_OK)
100 return sp_res;
101
102 if (count == 0)
103 return SP_RESULT_NOT_FOUND;
104
105 return SP_RESULT_OK;
106}
107
Imre Kis66321592020-11-23 03:15:50 +0100108static void unpack_ffa_info(const struct ffa_partition_information ffa_info[],
109 struct sp_partition_info *sp_info)
110{
111 uint32_t props = ffa_info->partition_properties;
112
113 sp_info->partition_id = ffa_info->partition_id;
114 sp_info->execution_context_count = ffa_info->execution_context_count;
115 sp_info->supports_direct_requests =
Imre Kisc81995e2021-01-12 22:28:21 +0100116 props & FFA_PARTITION_SUPPORTS_DIRECT_REQUESTS;
Imre Kis66321592020-11-23 03:15:50 +0100117 sp_info->can_send_direct_requests =
Imre Kisc81995e2021-01-12 22:28:21 +0100118 props & FFA_PARTITION_CAN_SEND_DIRECT_REQUESTS;
Imre Kis66321592020-11-23 03:15:50 +0100119 sp_info->supports_indirect_requests =
Imre Kisc81995e2021-01-12 22:28:21 +0100120 props & FFA_PARTITION_SUPPORTS_INDIRECT_REQUESTS;
Imre Kis66321592020-11-23 03:15:50 +0100121}
122
123sp_result sp_discovery_partition_id_get(const struct sp_uuid *uuid,
124 uint16_t *id)
125{
126 const struct ffa_partition_information *ffa_info = NULL;
127 uint32_t count = 0;
128 sp_result sp_res = SP_RESULT_OK;
129
Imre Kisc81995e2021-01-12 22:28:21 +0100130 if (id == NULL)
Imre Kis66321592020-11-23 03:15:50 +0100131 return SP_RESULT_INVALID_PARAMETERS;
132
Imre Kisc81995e2021-01-12 22:28:21 +0100133 sp_res = partition_info_get_single(uuid, &ffa_info);
Imre Kis66321592020-11-23 03:15:50 +0100134 if (sp_res != SP_RESULT_OK) {
135 *id = FFA_ID_GET_ID_MASK;
136 return sp_res;
137 }
138
Imre Kis66321592020-11-23 03:15:50 +0100139 *id = ffa_info->partition_id;
140
141 return SP_RESULT_OK;
142}
143
144sp_result sp_discovery_partition_info_get(const struct sp_uuid *uuid,
145 struct sp_partition_info *info)
146{
147 const struct ffa_partition_information *ffa_info = NULL;
148 uint32_t count = 0;
149 sp_result sp_res = SP_RESULT_OK;
150
Imre Kisc81995e2021-01-12 22:28:21 +0100151 if (info == NULL)
Imre Kis66321592020-11-23 03:15:50 +0100152 return SP_RESULT_INVALID_PARAMETERS;
153
Imre Kisc81995e2021-01-12 22:28:21 +0100154 sp_res = partition_info_get_single(uuid, &ffa_info);
Imre Kis66321592020-11-23 03:15:50 +0100155 if (sp_res != SP_RESULT_OK) {
Imre Kisc81995e2021-01-12 22:28:21 +0100156 *info = (struct sp_partition_info){ 0 };
Imre Kis66321592020-11-23 03:15:50 +0100157 return sp_res;
158 }
159
Imre Kis66321592020-11-23 03:15:50 +0100160 unpack_ffa_info(ffa_info, info);
161
162 return SP_RESULT_OK;
163}
164
165sp_result sp_discovery_partition_info_get_all(struct sp_partition_info info[],
166 uint32_t *count)
167{
168 const struct ffa_partition_information *ffa_info = NULL;
169 uint32_t ffa_count = 0;
170 uint32_t i = 0;
171 sp_result sp_res = SP_RESULT_OK;
172
Imre Kisc81995e2021-01-12 22:28:21 +0100173 if (count == NULL)
Imre Kis66321592020-11-23 03:15:50 +0100174 return SP_RESULT_INVALID_PARAMETERS;
175
Imre Kisc81995e2021-01-12 22:28:21 +0100176 if (info == NULL) {
177 *count = UINT32_C(0);
178 return SP_RESULT_INVALID_PARAMETERS;
179 }
180
Imre Kis66321592020-11-23 03:15:50 +0100181 sp_res = partition_info_get(&uuid_nil, &ffa_info, &ffa_count);
182 if (sp_res != SP_RESULT_OK) {
183 *count = UINT32_C(0);
184 return sp_res;
185 }
186
187 *count = MIN(*count, ffa_count);
188 for (i = 0; i < *count; i++)
189 unpack_ffa_info(&ffa_info[i], &info[i]);
190
191 return SP_RESULT_OK;
192}