1 /*
2 * Arm SCP/MCP Software
3 * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Description:
8 * Identifiers.
9 */
10
11 #include <internal/fwk_id.h>
12
13 #include <fwk_assert.h>
14 #include <fwk_attributes.h>
15 #include <fwk_id.h>
16 #include <fwk_macros.h>
17 #include <fwk_module.h>
18
19 #include <stdint.h>
20 #include <stdio.h>
21 #include <string.h>
22
fwk_id_format(char * buffer,size_t buffer_size,fwk_id_t id)23 static void fwk_id_format(char *buffer, size_t buffer_size, fwk_id_t id)
24 {
25 static const char *types[__FWK_ID_TYPE_COUNT] = {
26 [__FWK_ID_TYPE_INVALID] = "INV",
27 [__FWK_ID_TYPE_NONE] = "NON",
28 [__FWK_ID_TYPE_MODULE] = "MOD",
29 [__FWK_ID_TYPE_ELEMENT] = "ELM",
30 [__FWK_ID_TYPE_SUB_ELEMENT] = "SUB",
31 [__FWK_ID_TYPE_API] = "API",
32 [__FWK_ID_TYPE_EVENT] = "EVT",
33 [__FWK_ID_TYPE_NOTIFICATION] = "NOT",
34 };
35
36 size_t length = 0;
37
38 enum __fwk_id_type com_id_type = (enum __fwk_id_type)id.common.type;
39
40 unsigned int indices[] = { 0, 0, 0 };
41
42 fwk_assert(buffer_size > 0);
43
44 if (id.common.type >= FWK_ARRAY_SIZE(types) ||
45 id.common.type == (uint32_t)__FWK_ID_TYPE_INVALID) {
46 (void)snprintf(
47 buffer,
48 buffer_size,
49 "[%s]",
50 types[(uint32_t)__FWK_ID_TYPE_INVALID]);
51 return;
52 }
53
54 indices[0] = id.common.module_idx;
55
56 switch (com_id_type) {
57 case __FWK_ID_TYPE_SUB_ELEMENT:
58 indices[2] = id.sub_element.sub_element_idx;
59
60 FWK_FALLTHROUGH;
61
62 case __FWK_ID_TYPE_ELEMENT:
63 indices[1] = id.element.element_idx;
64
65 break;
66
67 case __FWK_ID_TYPE_API:
68 indices[1] = id.api.api_idx;
69
70 break;
71
72 case __FWK_ID_TYPE_EVENT:
73 indices[1] = id.event.event_idx;
74
75 break;
76
77 case __FWK_ID_TYPE_NOTIFICATION:
78 indices[1] = id.notification.notification_idx;
79
80 break;
81
82 default:
83 break;
84 }
85
86 length += snprintf(
87 buffer + length,
88 buffer_size - length,
89 "[%s %u",
90 types[id.common.type],
91 indices[0]);
92
93 switch (com_id_type) {
94 case __FWK_ID_TYPE_ELEMENT:
95 case __FWK_ID_TYPE_SUB_ELEMENT:
96 case __FWK_ID_TYPE_API:
97 case __FWK_ID_TYPE_EVENT:
98 case __FWK_ID_TYPE_NOTIFICATION:
99 length +=
100 snprintf(buffer + length, buffer_size - length, ":%u", indices[1]);
101
102 break;
103
104 default:
105 break;
106 }
107
108 switch (com_id_type) {
109 case __FWK_ID_TYPE_SUB_ELEMENT:
110 length +=
111 snprintf(buffer + length, buffer_size - length, ":%u", indices[2]);
112
113 break;
114
115 default:
116 break;
117 }
118
119 (void)snprintf(buffer + length, buffer_size - length, "]");
120 }
121
__fwk_id_str(fwk_id_t id)122 struct __fwk_id_fmt __fwk_id_str(fwk_id_t id)
123 {
124 struct __fwk_id_fmt fmt = { { 0 } };
125
126 fwk_id_format(fmt.str, sizeof(fmt.str), id);
127
128 return fmt;
129 }
130
fwk_id_is_type(fwk_id_t id,enum fwk_id_type type)131 bool fwk_id_is_type(fwk_id_t id, enum fwk_id_type type)
132 {
133 fwk_assert(id.common.type != __FWK_ID_TYPE_INVALID);
134 fwk_assert(id.common.type < __FWK_ID_TYPE_COUNT);
135
136 return id.common.type == type;
137 }
138
fwk_id_type_is_valid(fwk_id_t id)139 bool fwk_id_type_is_valid(fwk_id_t id)
140 {
141 if ((id.common.type != __FWK_ID_TYPE_INVALID) &&
142 (id.common.type < __FWK_ID_TYPE_COUNT)) {
143 return true;
144 }
145
146 return false;
147 }
148
fwk_id_get_type(fwk_id_t id)149 enum fwk_id_type fwk_id_get_type(fwk_id_t id)
150 {
151 fwk_assert(id.common.type != __FWK_ID_TYPE_INVALID);
152 fwk_assert(id.common.type < __FWK_ID_TYPE_COUNT);
153
154 return (enum fwk_id_type)id.common.type;
155 }
156
fwk_id_is_equal(fwk_id_t left,fwk_id_t right)157 bool fwk_id_is_equal(fwk_id_t left, fwk_id_t right)
158 {
159 fwk_assert(left.common.type != __FWK_ID_TYPE_INVALID);
160 fwk_assert(left.common.type < __FWK_ID_TYPE_COUNT);
161
162 return left.value == right.value;
163 }
164
fwk_optional_id_is_defined(fwk_optional_id_t id)165 bool fwk_optional_id_is_defined(fwk_optional_id_t id)
166 {
167 fwk_assert(id.common.type < __FWK_ID_TYPE_COUNT);
168 return id.common.type != __FWK_ID_TYPE_INVALID;
169 }
170
fwk_id_build_module_id(fwk_id_t id)171 fwk_id_t fwk_id_build_module_id(fwk_id_t id)
172 {
173 fwk_assert(id.common.type != __FWK_ID_TYPE_INVALID);
174 fwk_assert(id.common.type < __FWK_ID_TYPE_COUNT);
175
176 return FWK_ID_MODULE(id.common.module_idx);
177 }
178
fwk_id_build_element_id(fwk_id_t id,unsigned int element_idx)179 fwk_id_t fwk_id_build_element_id(fwk_id_t id, unsigned int element_idx)
180 {
181 fwk_assert(id.common.type != __FWK_ID_TYPE_INVALID);
182 fwk_assert(id.common.type < __FWK_ID_TYPE_COUNT);
183
184 return FWK_ID_ELEMENT(id.common.module_idx, element_idx);
185 }
186
fwk_id_build_sub_element_id(fwk_id_t id,unsigned int sub_element_idx)187 fwk_id_t fwk_id_build_sub_element_id(fwk_id_t id, unsigned int sub_element_idx)
188 {
189 fwk_assert(id.common.type == __FWK_ID_TYPE_ELEMENT);
190
191 return FWK_ID_SUB_ELEMENT(
192 id.common.module_idx, id.element.element_idx, sub_element_idx);
193 }
194
fwk_id_build_api_id(fwk_id_t id,unsigned int api_idx)195 fwk_id_t fwk_id_build_api_id(fwk_id_t id, unsigned int api_idx)
196 {
197 fwk_assert(id.common.type != __FWK_ID_TYPE_INVALID);
198 fwk_assert(id.common.type < __FWK_ID_TYPE_COUNT);
199
200 return FWK_ID_API(id.common.module_idx, api_idx);
201 }
202
203 /*
204 * Following functions are enabled only for debug build, release build
205 * will use inline equivalents, see fwk_id.h
206 */
207 #if !defined(NDEBUG)
fwk_id_get_module_idx(fwk_id_t id)208 unsigned int fwk_id_get_module_idx(fwk_id_t id)
209 {
210 fwk_assert(id.common.type != __FWK_ID_TYPE_INVALID);
211 fwk_assert(id.common.type < __FWK_ID_TYPE_COUNT);
212
213 return id.common.module_idx;
214 }
215
fwk_id_get_element_idx(fwk_id_t element_id)216 unsigned int fwk_id_get_element_idx(fwk_id_t element_id)
217 {
218 fwk_assert(
219 (element_id.common.type == __FWK_ID_TYPE_ELEMENT) ||
220 (element_id.common.type == __FWK_ID_TYPE_SUB_ELEMENT));
221
222 return element_id.element.element_idx;
223 }
224
fwk_id_get_sub_element_idx(fwk_id_t sub_element_id)225 unsigned int fwk_id_get_sub_element_idx(fwk_id_t sub_element_id)
226 {
227 fwk_assert(sub_element_id.common.type == __FWK_ID_TYPE_SUB_ELEMENT);
228
229 return sub_element_id.sub_element.sub_element_idx;
230 }
231 #endif
232
fwk_id_get_api_idx(fwk_id_t api_id)233 unsigned int fwk_id_get_api_idx(fwk_id_t api_id)
234 {
235 fwk_assert(api_id.common.type == __FWK_ID_TYPE_API);
236
237 return api_id.api.api_idx;
238 }
239
fwk_id_get_event_idx(fwk_id_t event_id)240 unsigned int fwk_id_get_event_idx(fwk_id_t event_id)
241 {
242 fwk_assert(event_id.common.type == __FWK_ID_TYPE_EVENT);
243
244 return event_id.event.event_idx;
245 }
246
fwk_id_get_notification_idx(fwk_id_t notification_id)247 unsigned int fwk_id_get_notification_idx(fwk_id_t notification_id)
248 {
249 fwk_assert(notification_id.common.type == __FWK_ID_TYPE_NOTIFICATION);
250
251 return notification_id.notification.notification_idx;
252 }
253
254 static_assert(sizeof(fwk_id_t) == sizeof(uint32_t),
255 "fwk_id_t has invalid size");
256