blob: 7f92b6bcbbe2e6f2a3617b9deda4d8006823af58 [file] [log] [blame]
Imre Kis66321592020-11-23 03:15:50 +01001// SPDX-License-Identifier: BSD-3-Clause
2/*
Jelle Sels318263e2022-12-07 14:15:39 +01003 * Copyright (c) 2020-2023, 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
Jelle Sels318263e2022-12-07 14:15:39 +010041static void unpack_ffa_info(const struct ffa_partition_information *ffa_info,
Imre Kis66321592020-11-23 03:15:50 +010042 struct sp_partition_info *sp_info)
43{
44 uint32_t props = ffa_info->partition_properties;
45
46 sp_info->partition_id = ffa_info->partition_id;
47 sp_info->execution_context_count = ffa_info->execution_context_count;
48 sp_info->supports_direct_requests =
Imre Kisc81995e2021-01-12 22:28:21 +010049 props & FFA_PARTITION_SUPPORTS_DIRECT_REQUESTS;
Imre Kis66321592020-11-23 03:15:50 +010050 sp_info->can_send_direct_requests =
Imre Kisc81995e2021-01-12 22:28:21 +010051 props & FFA_PARTITION_CAN_SEND_DIRECT_REQUESTS;
Imre Kis66321592020-11-23 03:15:50 +010052 sp_info->supports_indirect_requests =
Imre Kisc81995e2021-01-12 22:28:21 +010053 props & FFA_PARTITION_SUPPORTS_INDIRECT_REQUESTS;
Imre Kis66321592020-11-23 03:15:50 +010054}
55
Jelle Sels318263e2022-12-07 14:15:39 +010056static sp_result
57partition_info_get(const struct sp_uuid *uuid,
58 struct sp_partition_info info[],
59 uint32_t *count,
60 bool allow_nil_uuid)
Imre Kis66321592020-11-23 03:15:50 +010061{
62 const struct ffa_partition_information *ffa_info = NULL;
63 uint32_t ffa_count = 0;
64 uint32_t i = 0;
65 sp_result sp_res = SP_RESULT_OK;
Jelle Sels318263e2022-12-07 14:15:39 +010066 const void *buffer = NULL;
67 size_t buffer_size = 0;
68 struct ffa_uuid ffa_uuid = { 0 };
69 ffa_result ffa_res = FFA_OK;
Imre Kis66321592020-11-23 03:15:50 +010070
Imre Kisc81995e2021-01-12 22:28:21 +010071 if (count == NULL)
Imre Kis66321592020-11-23 03:15:50 +010072 return SP_RESULT_INVALID_PARAMETERS;
73
Imre Kisc81995e2021-01-12 22:28:21 +010074 if (info == NULL) {
75 *count = UINT32_C(0);
76 return SP_RESULT_INVALID_PARAMETERS;
77 }
78
Jelle Sels318263e2022-12-07 14:15:39 +010079 if (uuid == NULL || (!allow_nil_uuid &&
80 memcmp(&uuid_nil, uuid, sizeof(struct sp_uuid)) == 0)) {
81 sp_res = SP_RESULT_INVALID_PARAMETERS;
82 goto out;
83 }
84
85 sp_res = sp_rxtx_buffer_rx_get(&buffer, &buffer_size);
Imre Kis66321592020-11-23 03:15:50 +010086 if (sp_res != SP_RESULT_OK) {
Jelle Sels318263e2022-12-07 14:15:39 +010087 goto out;
88 }
89
90 /* Safely convert to FF-A UUID format */
91 memcpy(&ffa_uuid.uuid, uuid->uuid, sizeof(ffa_uuid.uuid));
92
93 ffa_res = ffa_partition_info_get(&ffa_uuid, &ffa_count);
94 if (ffa_res != FFA_OK) {
95 sp_res = SP_RESULT_FFA(ffa_res);
96 goto out;
97 }
98
99 if ((ffa_count * sizeof(struct ffa_partition_information)) > buffer_size) {
100 /*
101 * The indicated amount of info structures doesn't fit into the
102 * RX buffer.
103 */
104 sp_res = SP_RESULT_INTERNAL_ERROR;
105 goto out;
106 }
107
108 ffa_info = (const struct ffa_partition_information *)buffer;
109
110 if (ffa_count == 0) {
111 sp_res = SP_RESULT_NOT_FOUND;
112 goto out;
Imre Kis66321592020-11-23 03:15:50 +0100113 }
114
115 *count = MIN(*count, ffa_count);
116 for (i = 0; i < *count; i++)
117 unpack_ffa_info(&ffa_info[i], &info[i]);
118
119 return SP_RESULT_OK;
Jelle Sels318263e2022-12-07 14:15:39 +0100120
121out:
122 for (i = 0; i < *count; i++)
123 info[i] = (struct sp_partition_info){ 0 };
124 *count = UINT32_C(0);
125
126 return sp_res;
127}
128
129sp_result sp_discovery_partition_id_get(const struct sp_uuid *uuid,
130 uint16_t *id)
131{
132 struct sp_partition_info sp_info = { 0 };
133 sp_result sp_res = SP_RESULT_OK;
134 uint32_t count = 1;
135
136 if (id == NULL)
137 return SP_RESULT_INVALID_PARAMETERS;
138
139 *id = FFA_ID_GET_ID_MASK;
140
141 if (uuid == NULL || memcmp(&uuid_nil, uuid, sizeof(struct sp_uuid)) == 0)
142 return SP_RESULT_INVALID_PARAMETERS;
143
144 sp_res = partition_info_get(uuid, &sp_info, &count, false);
145 if (sp_res != SP_RESULT_OK)
146 return sp_res;
147
148 *id = sp_info.partition_id;
149
150 return SP_RESULT_OK;
151}
152
153sp_result sp_discovery_partition_info_get(const struct sp_uuid *uuid,
154 struct sp_partition_info info[],
155 uint32_t *count)
156{
157 return partition_info_get(uuid, info, count, false);
158}
159
160sp_result sp_discovery_partition_info_get_all(struct sp_partition_info info[],
161 uint32_t *count)
162{
163 return partition_info_get(&uuid_nil, info, count, true);
Imre Kis66321592020-11-23 03:15:50 +0100164}