1 /*
2 * Arm SCP/MCP Software
3 * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "scp_unity.h"
9 #include "unity.h"
10
11 #include <internal/scmi_perf.h>
12
13 #ifdef TEST_ON_TARGET
14 # include <fwk_id.h>
15 # include <fwk_module.h>
16 #else
17 # include <Mockfwk_id.h>
18 # include <Mockfwk_module.h>
19
20 # include <internal/Mockfwk_core_internal.h>
21 #endif
22 #include <Mockmod_scmi_perf_extra.h>
23 #include <config_scmi_perf.h>
24
25 #include <mod_dvfs.h>
26 #include <mod_scmi_perf.h>
27
28 #include <fwk_element.h>
29 #include <fwk_macros.h>
30
31 #ifdef BUILD_HAS_SCMI_PERF_PLUGIN_HANDLER
32 # include <perf_plugins_handler.c>
33 # include <perf_plugins_handler.h>
34 #endif
35
36 #include UNIT_TEST_SRC
37
38 static struct mod_scmi_perf_ctx scmi_perf_ctx;
39
40 struct mod_scmi_to_protocol_api *to_protocol_api = NULL;
41
42 struct mod_scmi_from_protocol_api from_protocol_api = {
43 .get_agent_count = mod_scmi_from_protocol_api_get_agent_count,
44 .get_agent_id = mod_scmi_from_protocol_api_get_agent_id,
45 .get_agent_type = mod_scmi_from_protocol_api_get_agent_type,
46 .get_max_payload_size = mod_scmi_from_protocol_api_get_max_payload_size,
47 .write_payload = mod_scmi_from_protocol_api_write_payload,
48 .respond = mod_scmi_from_protocol_api_respond,
49 .notify = mod_scmi_from_protocol_api_notify,
50 };
51
52 static const struct mod_dvfs_domain_api dvfs_domain_api = {
53 .get_current_opp = mod_dvfs_domain_api_get_current_opp,
54 .get_sustained_opp = mod_dvfs_domain_api_get_sustained_opp,
55 .get_nth_opp = mod_dvfs_domain_api_get_nth_opp,
56 .get_level_id = mod_dvfs_domain_api_get_level_id,
57 .get_opp_count = mod_dvfs_domain_api_get_opp_count,
58 .get_latency = mod_dvfs_domain_api_get_latency,
59 .set_level = mod_dvfs_domain_api_set_level,
60 };
61
62 char *name = "Test Name";
63
64 static int return_status;
65
setUp(void)66 void setUp(void)
67 {
68 scmi_perf_ctx.scmi_api = &from_protocol_api;
69 scmi_perf_ctx.config = config_scmi_perf.data;
70 scmi_perf_ctx.domain_count = scmi_perf_ctx.config->perf_doms_count;
71
72 #ifdef BUILD_HAS_SCMI_PERF_FAST_CHANNELS
73 scmi_perf_ctx.fast_channels_rate_limit = SCMI_PERF_FC_MIN_RATE_LIMIT;
74 #endif
75
76 fwk_id_get_api_idx_ExpectAnyArgsAndReturn(MOD_SCMI_PERF_PROTOCOL_API);
77
78 module_scmi_perf.process_bind_request(
79 fwk_module_id_scmi,
80 fwk_module_id_scmi_perf,
81 FWK_ID_API(FWK_MODULE_IDX_SCMI_PERF, 0),
82 (const void **)&to_protocol_api);
83
84 scmi_perf_ctx.dvfs_api = &dvfs_domain_api;
85 }
86
tearDown(void)87 void tearDown(void)
88 {
89 }
90
91 /*
92 * Test that the scmi_perf_protocol_version_handler function returns the correct
93 * version of the protocol
94 */
95
96 /* Check that the return values are as expected */
version_handler_respond_callback(fwk_id_t service_id,const void * payload,size_t size,int NumCalls)97 int version_handler_respond_callback(
98 fwk_id_t service_id,
99 const void *payload,
100 size_t size,
101 int NumCalls)
102 {
103 struct scmi_protocol_version_p2a *return_values;
104 return_values = (struct scmi_protocol_version_p2a *)payload;
105
106 TEST_ASSERT_EQUAL((int32_t)SCMI_SUCCESS, return_values->status);
107 TEST_ASSERT_EQUAL(SCMI_PROTOCOL_VERSION_PERF, return_values->version);
108
109 return FWK_SUCCESS;
110 }
111
version_handler_respond_callback_fail(fwk_id_t service_id,const void * payload,size_t size,int NumCalls)112 int version_handler_respond_callback_fail(
113 fwk_id_t service_id,
114 const void *payload,
115 size_t size,
116 int NumCalls)
117 {
118 struct scmi_protocol_version_p2a *return_values;
119 return_values = (struct scmi_protocol_version_p2a *)payload;
120
121 TEST_ASSERT_EQUAL(size, sizeof(int32_t));
122 TEST_ASSERT_EQUAL(return_status, return_values->status);
123
124 return FWK_SUCCESS;
125 }
126
utest_scmi_perf_message_handler_bad_message_id(void)127 void utest_scmi_perf_message_handler_bad_message_id(void)
128 {
129 int status;
130 fwk_id_t service_id =
131 FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, TEST_SCMI_AGENT_IDX_0);
132 struct scmi_protocol_version_p2a payload = { 0 };
133
134 mod_scmi_from_protocol_api_respond_Stub(
135 version_handler_respond_callback_fail);
136
137 return_status = SCMI_NOT_SUPPORTED;
138 status = scmi_perf_message_handler(
139 (fwk_id_t)MOD_SCMI_PROTOCOL_ID_PERF,
140 service_id,
141 (const uint32_t *)&payload,
142 payload_size_table[MOD_SCMI_PROTOCOL_VERSION],
143 MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL);
144
145 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
146 }
147
utest_scmi_perf_message_handler_not_found(void)148 void utest_scmi_perf_message_handler_not_found(void)
149 {
150 int status;
151 fwk_id_t service_id =
152 FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, TEST_SCMI_AGENT_IDX_0);
153 struct scmi_protocol_version_p2a payload = { 0 };
154
155 mod_scmi_from_protocol_api_respond_Stub(
156 version_handler_respond_callback_fail);
157
158 return_status = SCMI_NOT_FOUND;
159 status = scmi_perf_message_handler(
160 (fwk_id_t)MOD_SCMI_PROTOCOL_ID_PERF,
161 service_id,
162 (const uint32_t *)&payload,
163 payload_size_table[MOD_SCMI_PROTOCOL_VERSION],
164 FWK_ARRAY_SIZE(handler_table));
165
166 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
167 }
168
utest_scmi_perf_protocol_version_handler(void)169 void utest_scmi_perf_protocol_version_handler(void)
170 {
171 int status;
172 fwk_id_t service_id =
173 FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, TEST_SCMI_AGENT_IDX_0);
174
175 uint32_t payload = 0;
176
177 /*
178 * Whenever the mocked function mod_scmi_from_protocol_api_respond is
179 * encountered, the function version_handler_respond_callback will be called
180 */
181 mod_scmi_from_protocol_api_respond_Stub(version_handler_respond_callback);
182
183 status = to_protocol_api->message_handler(
184 (fwk_id_t)MOD_SCMI_PROTOCOL_ID_PERF,
185 service_id,
186 (const uint32_t *)&payload,
187 payload_size_table[MOD_SCMI_PROTOCOL_VERSION],
188 MOD_SCMI_PROTOCOL_VERSION);
189
190 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
191 }
192
193 /*
194 * Test that the scmi_perf_protocol_attributes_handler function returns the
195 * correct attributes associated with this protocol
196 */
197
attributes_handler_respond_callback(fwk_id_t service_id,const void * payload,size_t size,int NumCalls)198 int attributes_handler_respond_callback(
199 fwk_id_t service_id,
200 const void *payload,
201 size_t size,
202 int NumCalls)
203 {
204 struct scmi_perf_protocol_attributes_p2a *return_values;
205 return_values = (struct scmi_perf_protocol_attributes_p2a *)payload;
206
207 TEST_ASSERT_EQUAL((int32_t)SCMI_SUCCESS, return_values->status);
208 TEST_ASSERT_EQUAL(
209 SCMI_PERF_PROTOCOL_ATTRIBUTES(true, scmi_perf_ctx.domain_count),
210 return_values->attributes);
211 TEST_ASSERT_EQUAL(0, return_values->statistics_len);
212
213 return FWK_SUCCESS;
214 }
215
utest_scmi_perf_protocol_attributes_handler(void)216 void utest_scmi_perf_protocol_attributes_handler(void)
217 {
218 int status;
219 fwk_id_t service_id =
220 FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, TEST_SCMI_AGENT_IDX_0);
221 struct scmi_protocol_attributes_p2a payload = {};
222
223 mod_scmi_from_protocol_api_respond_Stub(
224 attributes_handler_respond_callback);
225
226 status = to_protocol_api->message_handler(
227 (fwk_id_t)MOD_SCMI_PROTOCOL_ID_PERF,
228 service_id,
229 (const uint32_t *)&payload,
230 payload_size_table[MOD_SCMI_PROTOCOL_ATTRIBUTES],
231 MOD_SCMI_PROTOCOL_ATTRIBUTES);
232
233 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
234 }
235
236 /* Test the message_attributes_handler function with a valid message_id */
237
message_attributes_handler_valid_param_respond_callback(fwk_id_t service_id,const void * payload,size_t size,int NumCalls)238 int message_attributes_handler_valid_param_respond_callback(
239 fwk_id_t service_id,
240 const void *payload,
241 size_t size,
242 int NumCalls)
243 {
244 struct scmi_protocol_message_attributes_p2a *return_values;
245 return_values = (struct scmi_protocol_message_attributes_p2a *)payload;
246
247 TEST_ASSERT_EQUAL((int32_t)SCMI_SUCCESS, return_values->status);
248
249 #ifdef BUILD_HAS_SCMI_PERF_FAST_CHANNELS
250 TEST_ASSERT_EQUAL(1, return_values->attributes);
251 #else
252 TEST_ASSERT_EQUAL(0, return_values->attributes);
253 #endif
254
255 return FWK_SUCCESS;
256 }
257
utest_scmi_perf_protocol_message_attributes_handler_valid_param(void)258 void utest_scmi_perf_protocol_message_attributes_handler_valid_param(void)
259 {
260 int status;
261 fwk_id_t service_id =
262 FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, TEST_SCMI_AGENT_IDX_0);
263
264 struct scmi_protocol_message_attributes_a2p payload = {
265 .message_id = MOD_SCMI_PERF_LIMITS_GET,
266 };
267
268 mod_scmi_from_protocol_api_respond_Stub(
269 message_attributes_handler_valid_param_respond_callback);
270
271 status = to_protocol_api->message_handler(
272 (fwk_id_t)MOD_SCMI_PROTOCOL_ID_PERF,
273 service_id,
274 (const uint32_t *)&payload,
275 payload_size_table[MOD_SCMI_PROTOCOL_MESSAGE_ATTRIBUTES],
276 MOD_SCMI_PROTOCOL_MESSAGE_ATTRIBUTES);
277
278 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
279 }
280
281 /* Test the message_attributes_handler function with an invalid message_id */
282
message_attributes_handler_invalid_param_respond_callback(fwk_id_t service_id,const void * payload,size_t size,int NumCalls)283 int message_attributes_handler_invalid_param_respond_callback(
284 fwk_id_t service_id,
285 const void *payload,
286 size_t size,
287 int NumCalls)
288 {
289 struct scmi_protocol_message_attributes_p2a *return_values;
290 return_values = (struct scmi_protocol_message_attributes_p2a *)payload;
291
292 TEST_ASSERT_EQUAL((int32_t)SCMI_NOT_FOUND, return_values->status);
293
294 return FWK_SUCCESS;
295 }
296
utest_scmi_perf_protocol_message_attributes_handler_invalid_param(void)297 void utest_scmi_perf_protocol_message_attributes_handler_invalid_param(void)
298 {
299 int status;
300 fwk_id_t service_id =
301 FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, TEST_SCMI_AGENT_IDX_0);
302
303 struct scmi_protocol_message_attributes_a2p payload = {
304 .message_id = FWK_ARRAY_SIZE(handler_table),
305 };
306
307 mod_scmi_from_protocol_api_respond_Stub(
308 message_attributes_handler_invalid_param_respond_callback);
309
310 status = to_protocol_api->message_handler(
311 (fwk_id_t)MOD_SCMI_PROTOCOL_ID_PERF,
312 service_id,
313 (const uint32_t *)&payload,
314 payload_size_table[MOD_SCMI_PROTOCOL_MESSAGE_ATTRIBUTES],
315 MOD_SCMI_PROTOCOL_MESSAGE_ATTRIBUTES);
316
317 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
318 }
319
320 /* Test the domain_attributes_handler function with a valid domain_id */
321
domain_attributes_handler_valid_param_respond_callback(fwk_id_t service_id,const void * payload,size_t size,int NumCalls)322 int domain_attributes_handler_valid_param_respond_callback(
323 fwk_id_t service_id,
324 const void *payload,
325 size_t size,
326 int NumCalls)
327 {
328 struct scmi_perf_domain_attributes_p2a *return_values;
329 return_values = (struct scmi_perf_domain_attributes_p2a *)payload;
330
331 TEST_ASSERT_EQUAL((int32_t)SCMI_SUCCESS, return_values->status);
332
333 bool notifications = false;
334 bool fast_channels = false;
335
336 #ifdef BUILD_HAS_SCMI_PERF_FAST_CHANNELS
337 fast_channels = true;
338 #endif
339
340 uint32_t permissions = ((uint32_t)MOD_SCMI_PERF_PERMS_SET_LIMITS) |
341 ((uint32_t)MOD_SCMI_PERF_PERMS_SET_LEVEL);
342
343 uint32_t expected_attributes = SCMI_PERF_DOMAIN_ATTRIBUTES(
344 (uint32_t)notifications,
345 (uint32_t)notifications,
346 ((permissions & (uint32_t)MOD_SCMI_PERF_PERMS_SET_LEVEL) !=
347 (uint32_t)0) ?
348 1U :
349 0U,
350 ((permissions & (uint32_t)MOD_SCMI_PERF_PERMS_SET_LIMITS) !=
351 (uint32_t)0) ?
352 1U :
353 0U,
354 (uint32_t)fast_channels);
355
356 TEST_ASSERT_EQUAL(expected_attributes, return_values->attributes);
357
358 TEST_ASSERT_EQUAL(0, return_values->rate_limit);
359
360 struct mod_dvfs_opp expected_opp_values = test_dvfs_config.opps[0];
361
362 TEST_ASSERT_EQUAL(
363 expected_opp_values.frequency, return_values->sustained_freq);
364 TEST_ASSERT_EQUAL(
365 expected_opp_values.level, return_values->sustained_perf_level);
366
367 TEST_ASSERT_EQUAL_STRING(name, (char *)return_values->name);
368
369 return FWK_SUCCESS;
370 }
371
utest_scmi_perf_domain_attributes_handler_valid_param(void)372 void utest_scmi_perf_domain_attributes_handler_valid_param(void)
373 {
374 int status;
375
376 fwk_id_t service_id =
377 FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, TEST_SCMI_AGENT_IDX_0);
378
379 struct scmi_perf_domain_attributes_a2p payload = {
380 .domain_id = 0,
381 };
382
383 unsigned int agent_id = TEST_SCMI_AGENT_IDX_0;
384
385 mod_scmi_from_protocol_api_get_agent_id_ExpectAnyArgsAndReturn(FWK_SUCCESS);
386 mod_scmi_from_protocol_api_get_agent_id_ReturnThruPtr_agent_id(&agent_id);
387
388 struct mod_dvfs_opp test_opp_values = test_dvfs_config.opps[0];
389
390 mod_dvfs_domain_api_get_sustained_opp_ExpectAnyArgsAndReturn(FWK_SUCCESS);
391 mod_dvfs_domain_api_get_sustained_opp_ReturnThruPtr_opp(&test_opp_values);
392
393 fwk_module_get_element_name_ExpectAnyArgsAndReturn(name);
394
395 mod_scmi_from_protocol_api_respond_Stub(
396 domain_attributes_handler_valid_param_respond_callback);
397
398 status = to_protocol_api->message_handler(
399 (fwk_id_t)MOD_SCMI_PROTOCOL_ID_PERF,
400 service_id,
401 (const uint32_t *)&payload,
402 payload_size_table[MOD_SCMI_PERF_DOMAIN_ATTRIBUTES],
403 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES);
404
405 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
406 }
407
408 /* Test the domain_attributes_handler function with an invalid domain_id */
409
domain_attributes_handler_invalid_param_respond_callback(fwk_id_t service_id,const void * payload,size_t size,int NumCalls)410 int domain_attributes_handler_invalid_param_respond_callback(
411 fwk_id_t service_id,
412 const void *payload,
413 size_t size,
414 int NumCalls)
415 {
416 struct scmi_perf_domain_attributes_p2a *return_values;
417 return_values = (struct scmi_perf_domain_attributes_p2a *)payload;
418
419 TEST_ASSERT_EQUAL((int32_t)SCMI_NOT_FOUND, return_values->status);
420
421 return FWK_SUCCESS;
422 }
423
utest_scmi_perf_domain_attributes_handler_invalid_param(void)424 void utest_scmi_perf_domain_attributes_handler_invalid_param(void)
425 {
426 int status;
427
428 fwk_id_t service_id =
429 FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, TEST_SCMI_AGENT_IDX_0);
430
431 struct scmi_perf_domain_attributes_a2p payload = {
432 .domain_id = scmi_perf_ctx.domain_count,
433 };
434
435 mod_scmi_from_protocol_api_respond_Stub(
436 domain_attributes_handler_invalid_param_respond_callback);
437
438 status = to_protocol_api->message_handler(
439 (fwk_id_t)MOD_SCMI_PROTOCOL_ID_PERF,
440 service_id,
441 (const uint32_t *)&payload,
442 payload_size_table[MOD_SCMI_PERF_DOMAIN_ATTRIBUTES],
443 MOD_SCMI_PERF_DOMAIN_ATTRIBUTES);
444
445 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
446 }
447
448 /* Test the describe_levels_handler function with a set of valid parameters */
449
450 /*
451 * As the dvfs_get_nth_opp function is mocked, we must manually return the
452 * requested OPP
453 */
get_nth_opp_callback(fwk_id_t domain_id,size_t n,struct mod_dvfs_opp * opp,int NumCalls)454 int get_nth_opp_callback(
455 fwk_id_t domain_id,
456 size_t n,
457 struct mod_dvfs_opp *opp,
458 int NumCalls)
459 {
460 *opp = test_dvfs_config.opps[n];
461 return FWK_SUCCESS;
462 }
463
464 /*
465 * Check that each of the returned levels is correct. Also, check that the
466 * final returned status and number of levels is correct.
467 */
describe_levels_handler_valid_param_write_payload_callback(fwk_id_t service_id,size_t offset,const void * payload,size_t size,int NumCalls)468 int describe_levels_handler_valid_param_write_payload_callback(
469 fwk_id_t service_id,
470 size_t offset,
471 const void *payload,
472 size_t size,
473 int NumCalls)
474 {
475 if (NumCalls < TEST_OPP_COUNT) {
476 struct scmi_perf_level *returned_perf_level =
477 (struct scmi_perf_level *)payload;
478
479 TEST_ASSERT_EQUAL(
480 test_dvfs_config.opps[NumCalls].voltage,
481 returned_perf_level->power_cost);
482 TEST_ASSERT_EQUAL(
483 test_dvfs_config.opps[NumCalls].level,
484 returned_perf_level->performance_level);
485 TEST_ASSERT_EQUAL(
486 test_dvfs_config.latency, returned_perf_level->attributes);
487
488 } else if (NumCalls == TEST_OPP_COUNT) {
489 struct scmi_perf_describe_levels_p2a *return_values =
490 (struct scmi_perf_describe_levels_p2a *)payload;
491 TEST_ASSERT_EQUAL(SCMI_SUCCESS, return_values->status);
492 TEST_ASSERT_EQUAL(TEST_OPP_COUNT, return_values->num_levels);
493
494 } else {
495 return FWK_E_RANGE;
496 }
497
498 return FWK_SUCCESS;
499 }
500
utest_scmi_perf_describe_levels_handler_valid_param(void)501 void utest_scmi_perf_describe_levels_handler_valid_param(void)
502 {
503 int status;
504
505 fwk_id_t service_id =
506 FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, TEST_SCMI_AGENT_IDX_0);
507
508 struct scmi_perf_describe_levels_a2p payload = {
509 .domain_id = 0,
510 .level_index = 0,
511 };
512
513 size_t size = UINT16_MAX;
514 size_t opp_count = TEST_OPP_COUNT;
515 uint16_t latency = test_dvfs_config.latency;
516
517 /*
518 * Return an arbitrarily large max_payload_size as we are just testing
519 * whether the returned levels are correct and in the right order
520 */
521 mod_scmi_from_protocol_api_get_max_payload_size_ExpectAnyArgsAndReturn(
522 FWK_SUCCESS);
523 mod_scmi_from_protocol_api_get_max_payload_size_ReturnThruPtr_size(&size);
524
525 mod_dvfs_domain_api_get_opp_count_ExpectAnyArgsAndReturn(FWK_SUCCESS);
526 mod_dvfs_domain_api_get_opp_count_ReturnThruPtr_opp_count(&opp_count);
527
528 mod_dvfs_domain_api_get_latency_ExpectAnyArgsAndReturn(FWK_SUCCESS);
529 mod_dvfs_domain_api_get_latency_ReturnThruPtr_latency(&latency);
530
531 mod_dvfs_domain_api_get_nth_opp_Stub(get_nth_opp_callback);
532
533 mod_scmi_from_protocol_api_write_payload_Stub(
534 describe_levels_handler_valid_param_write_payload_callback);
535
536 /* Disable the previous callback for this function */
537 mod_scmi_from_protocol_api_respond_Stub(NULL);
538 mod_scmi_from_protocol_api_respond_ExpectAnyArgsAndReturn(FWK_SUCCESS);
539
540 status = to_protocol_api->message_handler(
541 (fwk_id_t)MOD_SCMI_PROTOCOL_ID_PERF,
542 service_id,
543 (const uint32_t *)&payload,
544 payload_size_table[MOD_SCMI_PERF_DESCRIBE_LEVELS],
545 MOD_SCMI_PERF_DESCRIBE_LEVELS);
546
547 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
548 }
549
550 /* Test the describe_levels_handler function with an invalid domain_id */
551
describe_levels_handler_invalid_domain_id_respond_callback(fwk_id_t service_id,const void * payload,size_t size,int NumCalls)552 int describe_levels_handler_invalid_domain_id_respond_callback(
553 fwk_id_t service_id,
554 const void *payload,
555 size_t size,
556 int NumCalls)
557 {
558 int32_t *status = (int32_t *)payload;
559 TEST_ASSERT_EQUAL((int32_t)SCMI_NOT_FOUND, *status);
560
561 return FWK_SUCCESS;
562 }
563
utest_scmi_perf_describe_levels_handler_invalid_domain_id(void)564 void utest_scmi_perf_describe_levels_handler_invalid_domain_id(void)
565 {
566 int status;
567
568 fwk_id_t service_id =
569 FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, TEST_SCMI_AGENT_IDX_0);
570
571 struct scmi_perf_describe_levels_a2p payload = {
572 .domain_id = scmi_perf_ctx.domain_count,
573 .level_index = 0,
574 };
575
576 size_t size = UINT16_MAX;
577
578 mod_scmi_from_protocol_api_get_max_payload_size_ExpectAnyArgsAndReturn(
579 FWK_SUCCESS);
580 mod_scmi_from_protocol_api_get_max_payload_size_ReturnThruPtr_size(&size);
581
582 mod_scmi_from_protocol_api_respond_Stub(
583 describe_levels_handler_invalid_domain_id_respond_callback);
584
585 status = to_protocol_api->message_handler(
586 (fwk_id_t)MOD_SCMI_PROTOCOL_ID_PERF,
587 service_id,
588 (const uint32_t *)&payload,
589 payload_size_table[MOD_SCMI_PERF_DESCRIBE_LEVELS],
590 MOD_SCMI_PERF_DESCRIBE_LEVELS);
591
592 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
593 }
594
595 /* Test the describe_levels_handler function with an invalid level_index */
596
describe_levels_handler_invalid_level_index_respond_callback(fwk_id_t service_id,const void * payload,size_t size,int NumCalls)597 int describe_levels_handler_invalid_level_index_respond_callback(
598 fwk_id_t service_id,
599 const void *payload,
600 size_t size,
601 int NumCalls)
602 {
603 int32_t *status = (int32_t *)payload;
604 TEST_ASSERT_EQUAL((int32_t)SCMI_INVALID_PARAMETERS, *status);
605
606 return FWK_SUCCESS;
607 }
608
utest_scmi_perf_describe_levels_handler_invalid_level_index(void)609 void utest_scmi_perf_describe_levels_handler_invalid_level_index(void)
610 {
611 int status;
612
613 fwk_id_t service_id =
614 FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, TEST_SCMI_AGENT_IDX_0);
615
616 struct scmi_perf_describe_levels_a2p payload = {
617 .domain_id = 0,
618 .level_index = TEST_OPP_COUNT,
619 };
620
621 size_t size = UINT16_MAX;
622 size_t opp_count = TEST_OPP_COUNT;
623
624 mod_scmi_from_protocol_api_get_max_payload_size_ExpectAnyArgsAndReturn(
625 FWK_SUCCESS);
626 mod_scmi_from_protocol_api_get_max_payload_size_ReturnThruPtr_size(&size);
627
628 mod_dvfs_domain_api_get_opp_count_ExpectAnyArgsAndReturn(FWK_SUCCESS);
629 mod_dvfs_domain_api_get_opp_count_ReturnThruPtr_opp_count(&opp_count);
630
631 mod_scmi_from_protocol_api_respond_Stub(
632 describe_levels_handler_invalid_level_index_respond_callback);
633
634 status = to_protocol_api->message_handler(
635 (fwk_id_t)MOD_SCMI_PROTOCOL_ID_PERF,
636 service_id,
637 (const uint32_t *)&payload,
638 payload_size_table[MOD_SCMI_PERF_DESCRIBE_LEVELS],
639 MOD_SCMI_PERF_DESCRIBE_LEVELS);
640
641 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
642 }
643
644 #ifdef BUILD_HAS_SCMI_PERF_FAST_CHANNELS
645
646 /*
647 * Test the scmi_perf_describe_fast_channels function with a set of valid
648 * parameters
649 */
650
describe_fast_channels_valid_params_respond_callback(fwk_id_t service_id,const void * payload,size_t size,int NumCalls)651 int describe_fast_channels_valid_params_respond_callback(
652 fwk_id_t service_id,
653 const void *payload,
654 size_t size,
655 int NumCalls)
656 {
657 struct scmi_perf_describe_fc_p2a *return_values =
658 (struct scmi_perf_describe_fc_p2a *)payload;
659
660 TEST_ASSERT_EQUAL((int32_t)SCMI_SUCCESS, return_values->status);
661 TEST_ASSERT_EQUAL(0, return_values->attributes);
662 TEST_ASSERT_EQUAL(
663 scmi_perf_ctx.fast_channels_rate_limit, return_values->rate_limit);
664
665 int chan_index = (uint32_t)MOD_SCMI_PERF_FAST_CHANNEL_LEVEL_GET;
666 TEST_ASSERT_EQUAL(
667 (uint32_t)(domains[0].fast_channels_addr_ap[chan_index] & ~0UL),
668 return_values->chan_addr_low);
669 TEST_ASSERT_EQUAL(
670 (uint32_t)(domains[0].fast_channels_addr_ap[chan_index] >> 32),
671 return_values->chan_addr_high);
672
673 TEST_ASSERT_EQUAL(
674 fast_channel_elem_size[MOD_SCMI_PERF_FAST_CHANNEL_LEVEL_GET],
675 return_values->chan_size);
676
677 return FWK_SUCCESS;
678 }
679
utest_scmi_perf_describe_fast_channels_valid_params(void)680 void utest_scmi_perf_describe_fast_channels_valid_params(void)
681 {
682 int status;
683
684 fwk_id_t service_id =
685 FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, TEST_SCMI_AGENT_IDX_0);
686
687 struct scmi_perf_describe_fc_a2p payload = {
688 .domain_id = 0,
689 .message_id = MOD_SCMI_PERF_LEVEL_GET,
690 };
691
692 mod_scmi_from_protocol_api_respond_Stub(
693 describe_fast_channels_valid_params_respond_callback);
694
695 status = to_protocol_api->message_handler(
696 (fwk_id_t)MOD_SCMI_PROTOCOL_ID_PERF,
697 service_id,
698 (const uint32_t *)&payload,
699 payload_size_table[MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL],
700 MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL);
701
702 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
703 }
704
705 /*
706 * Test the scmi_perf_describe_fast_channels function with an invalid
707 * domain_id
708 */
709
describe_fast_channels_invalid_domain_id_respond_callback(fwk_id_t service_id,const void * payload,size_t size,int NumCalls)710 int describe_fast_channels_invalid_domain_id_respond_callback(
711 fwk_id_t service_id,
712 const void *payload,
713 size_t size,
714 int NumCalls)
715 {
716 struct scmi_perf_describe_fc_p2a *return_values =
717 (struct scmi_perf_describe_fc_p2a *)payload;
718
719 TEST_ASSERT_EQUAL((int32_t)SCMI_NOT_FOUND, return_values->status);
720
721 return FWK_SUCCESS;
722 }
723
utest_scmi_perf_describe_fast_channels_invalid_domain_id(void)724 void utest_scmi_perf_describe_fast_channels_invalid_domain_id(void)
725 {
726 int status;
727
728 fwk_id_t service_id =
729 FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, TEST_SCMI_AGENT_IDX_0);
730
731 struct scmi_perf_describe_fc_a2p payload = {
732 .domain_id = scmi_perf_ctx.domain_count,
733 .message_id = MOD_SCMI_PERF_LEVEL_GET,
734 };
735
736 mod_scmi_from_protocol_api_respond_Stub(
737 describe_fast_channels_invalid_domain_id_respond_callback);
738
739 status = to_protocol_api->message_handler(
740 (fwk_id_t)MOD_SCMI_PROTOCOL_ID_PERF,
741 service_id,
742 (const uint32_t *)&payload,
743 payload_size_table[MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL],
744 MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL);
745
746 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
747 }
748
749 /*
750 * Test the scmi_perf_describe_fast_channels function with an invalid
751 * message_id
752 */
753
describe_fast_channels_invalid_message_id_respond_callback(fwk_id_t service_id,const void * payload,size_t size,int NumCalls)754 int describe_fast_channels_invalid_message_id_respond_callback(
755 fwk_id_t service_id,
756 const void *payload,
757 size_t size,
758 int NumCalls)
759 {
760 struct scmi_perf_describe_fc_p2a *return_values =
761 (struct scmi_perf_describe_fc_p2a *)payload;
762
763 TEST_ASSERT_EQUAL((int32_t)SCMI_NOT_FOUND, return_values->status);
764
765 return FWK_SUCCESS;
766 }
767
utest_scmi_perf_describe_fast_channels_invalid_message_id(void)768 void utest_scmi_perf_describe_fast_channels_invalid_message_id(void)
769 {
770 int status;
771
772 fwk_id_t service_id =
773 FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, TEST_SCMI_AGENT_IDX_0);
774
775 struct scmi_perf_describe_fc_a2p payload = {
776 .domain_id = 0,
777 .message_id = MOD_SCMI_PERF_COMMAND_COUNT,
778 };
779
780 mod_scmi_from_protocol_api_respond_Stub(
781 describe_fast_channels_invalid_message_id_respond_callback);
782
783 status = to_protocol_api->message_handler(
784 (fwk_id_t)MOD_SCMI_PROTOCOL_ID_PERF,
785 service_id,
786 (const uint32_t *)&payload,
787 payload_size_table[MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL],
788 MOD_SCMI_PERF_DESCRIBE_FAST_CHANNEL);
789
790 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
791 }
792
793 #endif
794
795 /*
796 * Test the find_opp_for_level function with a valid level, without
797 * use_nearest
798 */
utest_find_opp_for_level_valid_level(void)799 void utest_find_opp_for_level_valid_level(void)
800 {
801 int status;
802 uint32_t valid_level = test_dvfs_config.opps[1].level;
803
804 struct perf_opp_table opp_table = {
805 .opps = test_dvfs_config.opps,
806 .opp_count = TEST_OPP_COUNT,
807 };
808
809 struct mod_scmi_perf_level_limits level_limits = {
810 .minimum = test_dvfs_config.opps[0].level,
811 .maximum = test_dvfs_config.opps[TEST_OPP_COUNT - 1].level,
812 };
813
814 struct scmi_perf_domain_ctx domain_ctx = {
815 .level_limits = level_limits,
816 .opp_table = &opp_table,
817 };
818
819 status = find_opp_for_level(&domain_ctx, &valid_level, false);
820 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
821 TEST_ASSERT_EQUAL(opp_table.opps[1].level, valid_level);
822 }
823
824 /*
825 * Test the find_opp_for_level function with an invalid level, without
826 * use_nearest
827 */
utest_find_opp_for_level_invalid_level(void)828 void utest_find_opp_for_level_invalid_level(void)
829 {
830 int status;
831 uint32_t invalid_level = test_dvfs_config.opps[1].level + 1000000UL;
832
833 struct perf_opp_table opp_table = {
834 .opps = test_dvfs_config.opps,
835 .opp_count = TEST_OPP_COUNT,
836 };
837
838 struct mod_scmi_perf_level_limits level_limits = {
839 .minimum = test_dvfs_config.opps[0].level,
840 .maximum = test_dvfs_config.opps[TEST_OPP_COUNT - 1].level,
841 };
842
843 struct scmi_perf_domain_ctx domain_ctx = {
844 .level_limits = level_limits,
845 .opp_table = &opp_table,
846 };
847
848 status = find_opp_for_level(&domain_ctx, &invalid_level, false);
849 TEST_ASSERT_EQUAL(FWK_E_RANGE, status);
850 }
851
852 /*
853 * Test the find_opp_for_level function with use_nearest. In this case, expect
854 * an OPP to be found for any level.
855 */
utest_find_opp_for_level_use_nearest(void)856 void utest_find_opp_for_level_use_nearest(void)
857 {
858 int status;
859
860 struct perf_opp_table opp_table = {
861 .opps = test_dvfs_config.opps,
862 .opp_count = TEST_OPP_COUNT,
863 };
864
865 struct mod_scmi_perf_level_limits level_limits = {
866 .minimum = test_dvfs_config.opps[0].level,
867 .maximum = test_dvfs_config.opps[TEST_OPP_COUNT - 1].level,
868 };
869
870 struct scmi_perf_domain_ctx domain_ctx = {
871 .level_limits = level_limits,
872 .opp_table = &opp_table,
873 };
874
875 uint32_t approximate_level = level_limits.maximum + 1000000UL;
876
877 status = find_opp_for_level(&domain_ctx, &approximate_level, true);
878 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
879 TEST_ASSERT_EQUAL(level_limits.maximum, approximate_level);
880 }
881
882 /*
883 * Test the validate_new_limits function with a valid set of limits, without
884 * approximating the level
885 */
utest_validate_new_limits_valid_limits(void)886 void utest_validate_new_limits_valid_limits(void)
887 {
888 int status;
889
890 struct perf_opp_table opp_table = {
891 .opps = test_dvfs_config.opps,
892 .opp_count = TEST_OPP_COUNT,
893 };
894
895 struct mod_scmi_perf_level_limits level_limits = {
896 .minimum = test_dvfs_config.opps[0].level,
897 .maximum = test_dvfs_config.opps[TEST_OPP_COUNT - 1].level,
898 };
899
900 struct scmi_perf_domain_ctx domain_ctx = {
901 .level_limits = level_limits,
902 .opp_table = &opp_table,
903 };
904
905 struct mod_scmi_perf_level_limits valid_level_limits = {
906 .minimum = test_dvfs_config.opps[1].level,
907 .maximum = test_dvfs_config.opps[TEST_OPP_COUNT - 1].level,
908 };
909
910 status = validate_new_limits(&domain_ctx, &valid_level_limits);
911 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
912 }
913
914 /*
915 * Test the validate_new_limits function with an invalid set of limits, without
916 * approximating the level
917 */
utest_validate_new_limits_invalid_limits(void)918 void utest_validate_new_limits_invalid_limits(void)
919 {
920 int status;
921
922 struct perf_opp_table opp_table = {
923 .opps = test_dvfs_config.opps,
924 .opp_count = TEST_OPP_COUNT,
925 };
926
927 struct mod_scmi_perf_level_limits level_limits = {
928 .minimum = test_dvfs_config.opps[0].level,
929 .maximum = test_dvfs_config.opps[TEST_OPP_COUNT - 1].level,
930 };
931
932 struct scmi_perf_domain_ctx domain_ctx = {
933 .level_limits = level_limits,
934 .opp_table = &opp_table,
935 };
936
937 struct mod_scmi_perf_level_limits invalid_level_limits = {
938 .minimum = test_dvfs_config.opps[0].level + 1000000UL,
939 .maximum = test_dvfs_config.opps[TEST_OPP_COUNT - 1].level,
940 };
941
942 status = validate_new_limits(&domain_ctx, &invalid_level_limits);
943 TEST_ASSERT_EQUAL(FWK_E_RANGE, status);
944 }
945
946 /*
947 * Test the validate_new_limits function, approximating the level. In this
948 * case, expect any set of limits to succeed.
949 */
utest_validate_new_limits_approximate_level(void)950 void utest_validate_new_limits_approximate_level(void)
951 {
952 int status;
953
954 struct fwk_module_config config_scmi_perf_approximate_level = {
955 .data = &((struct mod_scmi_perf_config){
956 .domains = &domains,
957 .perf_doms_count = FWK_ARRAY_SIZE(domains),
958 .fast_channels_alarm_id = FWK_ID_NONE_INIT,
959 .approximate_level = true,
960 }),
961 };
962
963 scmi_perf_ctx.config = config_scmi_perf_approximate_level.data;
964
965 struct perf_opp_table opp_table = {
966 .opps = test_dvfs_config.opps,
967 .opp_count = TEST_OPP_COUNT,
968 };
969 struct mod_scmi_perf_level_limits level_limits = {
970 .minimum = test_dvfs_config.opps[0].level - 1000000UL,
971 .maximum = test_dvfs_config.opps[TEST_OPP_COUNT - 1].level + 1000000UL,
972 };
973
974 struct scmi_perf_domain_ctx domain_ctx = {
975 .level_limits = level_limits,
976 .opp_table = &opp_table,
977 };
978
979 status = validate_new_limits(&domain_ctx, &level_limits);
980 TEST_ASSERT_EQUAL(FWK_SUCCESS, status);
981 }
982
983 #ifdef BUILD_HAS_SCMI_PERF_PLUGIN_HANDLER
utest_perf_eval_performance_invalid_limits(void)984 void utest_perf_eval_performance_invalid_limits(void)
985 {
986 struct mod_scmi_perf_level_limits limits = {
987 .minimum = 1000,
988 .maximum = 100,
989 };
990 uint32_t level = 500;
991 fwk_id_t perf_id = FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, 0);
992
993 perf_eval_performance(perf_id, &limits, &level);
994 TEST_ASSERT_EQUAL(500, level);
995 }
996
utest_perf_eval_performance_unchanged_limits(void)997 void utest_perf_eval_performance_unchanged_limits(void)
998 {
999 struct scmi_perf_domain_ctx domain0_ctx;
1000 uint32_t level;
1001
1002 domain0_ctx.level_limits.minimum = test_dvfs_config.opps[0].level;
1003 domain0_ctx.level_limits.maximum =
1004 test_dvfs_config.opps[TEST_OPP_COUNT - 1].level;
1005
1006 struct mod_scmi_perf_level_limits limits = {
1007 .minimum = test_dvfs_config.opps[0].level,
1008 .maximum = test_dvfs_config.opps[TEST_OPP_COUNT - 1].level,
1009 };
1010
1011 domain0_ctx.opp_table = &((struct perf_opp_table){
1012 .opps = test_dvfs_config.opps,
1013 .opp_count = TEST_OPP_COUNT,
1014 });
1015
1016 scmi_perf_ctx.domain_ctx_table = &domain0_ctx;
1017 /*
1018 * The level to be evaluated is just above the second OPP. Due to the
1019 * default approximation for `perf_eval_performance`, it should return the
1020 * next OPP just above it.
1021 */
1022 level = test_dvfs_config.opps[1].level + 1;
1023 fwk_id_t perf_id = FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, 0);
1024
1025 fwk_id_get_element_idx_ExpectAndReturn(perf_id, 0);
1026
1027 perf_eval_performance(perf_id, &limits, &level);
1028 TEST_ASSERT_EQUAL(test_dvfs_config.opps[2].level, level);
1029 }
1030
utest_perf_eval_performance_unchanged_limits_level_down(void)1031 void utest_perf_eval_performance_unchanged_limits_level_down(void)
1032 {
1033 struct scmi_perf_domain_ctx domain0_ctx;
1034 uint32_t level;
1035
1036 domain0_ctx.level_limits.minimum = test_dvfs_config.opps[0].level;
1037 domain0_ctx.level_limits.maximum =
1038 test_dvfs_config.opps[TEST_OPP_COUNT - 2].level;
1039
1040 struct mod_scmi_perf_level_limits limits = {
1041 .minimum = test_dvfs_config.opps[0].level,
1042 .maximum = test_dvfs_config.opps[TEST_OPP_COUNT - 2].level,
1043 };
1044
1045 domain0_ctx.opp_table = &((struct perf_opp_table){
1046 .opps = test_dvfs_config.opps,
1047 .opp_count = TEST_OPP_COUNT,
1048 });
1049
1050 scmi_perf_ctx.domain_ctx_table = &domain0_ctx;
1051 /* The level will be reduced to the max limit */
1052 level = test_dvfs_config.opps[TEST_OPP_COUNT - 1].level;
1053 fwk_id_t perf_id = FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, 0);
1054
1055 fwk_id_get_element_idx_ExpectAndReturn(perf_id, 0);
1056
1057 perf_eval_performance(perf_id, &limits, &level);
1058 TEST_ASSERT_EQUAL(test_dvfs_config.opps[TEST_OPP_COUNT - 2].level, level);
1059 }
1060
utest_perf_eval_performance_unchanged_limits_level_up(void)1061 void utest_perf_eval_performance_unchanged_limits_level_up(void)
1062 {
1063 struct scmi_perf_domain_ctx domain0_ctx;
1064 uint32_t level;
1065
1066 domain0_ctx.level_limits.minimum = test_dvfs_config.opps[1].level;
1067 domain0_ctx.level_limits.maximum =
1068 test_dvfs_config.opps[TEST_OPP_COUNT - 1].level;
1069
1070 struct mod_scmi_perf_level_limits limits = {
1071 .minimum = test_dvfs_config.opps[1].level,
1072 .maximum = test_dvfs_config.opps[TEST_OPP_COUNT - 1].level,
1073 };
1074
1075 domain0_ctx.opp_table = &((struct perf_opp_table){
1076 .opps = test_dvfs_config.opps,
1077 .opp_count = TEST_OPP_COUNT,
1078 });
1079
1080 scmi_perf_ctx.domain_ctx_table = &domain0_ctx;
1081 /* The level will be increased to the min limit */
1082 level = test_dvfs_config.opps[0].level;
1083 fwk_id_t perf_id = FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, 0);
1084
1085 fwk_id_get_element_idx_ExpectAndReturn(perf_id, 0);
1086
1087 perf_eval_performance(perf_id, &limits, &level);
1088 TEST_ASSERT_EQUAL(test_dvfs_config.opps[1].level, level);
1089 }
1090
utest_perf_eval_performance_new_limits(void)1091 void utest_perf_eval_performance_new_limits(void)
1092 {
1093 struct scmi_perf_domain_ctx domain_table[2];
1094 struct perf_plugins_api *plugins_api_table[1];
1095 uint32_t level;
1096
1097 domain_table[1].level_limits.minimum = test_dvfs_config.opps[0].level;
1098 domain_table[1].level_limits.maximum =
1099 test_dvfs_config.opps[TEST_OPP_COUNT - 2].level;
1100
1101 struct mod_scmi_perf_level_limits new_limits = {
1102 .minimum = test_dvfs_config.opps[0].level,
1103 .maximum = test_dvfs_config.opps[TEST_OPP_COUNT - 1].level,
1104 };
1105
1106 domain_table[1].opp_table = &((struct perf_opp_table){
1107 .opps = test_dvfs_config.opps,
1108 .opp_count = TEST_OPP_COUNT,
1109 });
1110
1111 scmi_perf_ctx.domain_ctx_table = &domain_table[0];
1112 level = test_dvfs_config.opps[1].level;
1113 fwk_id_t perf_id = FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, 1);
1114
1115 fwk_id_get_element_idx_ExpectAndReturn(perf_id, 1);
1116 fwk_id_get_element_idx_ExpectAndReturn(perf_id, 1);
1117
1118 perf_plugins_ctx.config = config_scmi_perf.data;
1119 plugins_api_table[0] = &((struct perf_plugins_api){
1120 .update = NULL,
1121 .report = NULL,
1122 });
1123 perf_plugins_ctx.plugins_api_table = &plugins_api_table[0];
1124
1125 perf_eval_performance(perf_id, &new_limits, &level);
1126 TEST_ASSERT_EQUAL(test_dvfs_config.opps[1].level, level);
1127 }
1128
utest_perf_eval_performance_new_limits_level_down(void)1129 void utest_perf_eval_performance_new_limits_level_down(void)
1130 {
1131 struct scmi_perf_domain_ctx domain_table[2];
1132 struct perf_plugins_api *plugins_api_table[1];
1133 uint32_t level;
1134
1135 domain_table[1].level_limits.minimum = test_dvfs_config.opps[0].level;
1136 domain_table[1].level_limits.maximum =
1137 test_dvfs_config.opps[TEST_OPP_COUNT - 1].level;
1138
1139 struct mod_scmi_perf_level_limits new_limits = {
1140 .minimum = test_dvfs_config.opps[0].level,
1141 .maximum = test_dvfs_config.opps[TEST_OPP_COUNT - 2].level,
1142 };
1143
1144 domain_table[1].opp_table = &((struct perf_opp_table){
1145 .opps = test_dvfs_config.opps,
1146 .opp_count = TEST_OPP_COUNT,
1147 });
1148
1149 scmi_perf_ctx.domain_ctx_table = &domain_table[0];
1150 /* The level will be reduced to the max limit */
1151 level = test_dvfs_config.opps[TEST_OPP_COUNT - 1].level;
1152 fwk_id_t perf_id = FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, 1);
1153
1154 fwk_id_get_element_idx_ExpectAndReturn(perf_id, 1);
1155 fwk_id_get_element_idx_ExpectAndReturn(perf_id, 1);
1156
1157 perf_plugins_ctx.config = config_scmi_perf.data;
1158 plugins_api_table[0] = &((struct perf_plugins_api){
1159 .update = NULL,
1160 .report = NULL,
1161 });
1162 perf_plugins_ctx.plugins_api_table = &plugins_api_table[0];
1163
1164 perf_eval_performance(perf_id, &new_limits, &level);
1165 TEST_ASSERT_EQUAL(test_dvfs_config.opps[TEST_OPP_COUNT - 2].level, level);
1166 }
1167
utest_perf_eval_performance_new_limits_level_up(void)1168 void utest_perf_eval_performance_new_limits_level_up(void)
1169 {
1170 struct scmi_perf_domain_ctx domain_table[2];
1171 struct perf_plugins_api *plugins_api_table[1];
1172 uint32_t level;
1173
1174 domain_table[1].level_limits.minimum = test_dvfs_config.opps[0].level;
1175 domain_table[1].level_limits.maximum =
1176 test_dvfs_config.opps[TEST_OPP_COUNT - 1].level;
1177
1178 struct mod_scmi_perf_level_limits new_limits = {
1179 .minimum = test_dvfs_config.opps[1].level,
1180 .maximum = test_dvfs_config.opps[TEST_OPP_COUNT - 1].level,
1181 };
1182
1183 domain_table[1].opp_table = &((struct perf_opp_table){
1184 .opps = test_dvfs_config.opps,
1185 .opp_count = TEST_OPP_COUNT,
1186 });
1187
1188 scmi_perf_ctx.domain_ctx_table = &domain_table[0];
1189 /* The level will be increased to the min limit */
1190 level = test_dvfs_config.opps[0].level;
1191 fwk_id_t perf_id = FWK_ID_ELEMENT_INIT(TEST_MODULE_IDX, 1);
1192
1193 fwk_id_get_element_idx_ExpectAndReturn(perf_id, 1);
1194 fwk_id_get_element_idx_ExpectAndReturn(perf_id, 1);
1195
1196 perf_plugins_ctx.config = config_scmi_perf.data;
1197 plugins_api_table[0] = &((struct perf_plugins_api){
1198 .update = NULL,
1199 .report = NULL,
1200 });
1201 perf_plugins_ctx.plugins_api_table = &plugins_api_table[0];
1202
1203 perf_eval_performance(perf_id, &new_limits, &level);
1204 TEST_ASSERT_EQUAL(test_dvfs_config.opps[1].level, level);
1205 }
1206 #endif
1207
scmi_perf_test_main(void)1208 int scmi_perf_test_main(void)
1209 {
1210 UNITY_BEGIN();
1211
1212 #ifndef BUILD_HAS_SCMI_PERF_PLUGIN_HANDLER
1213 # ifndef BUILD_HAS_SCMI_PERF_FAST_CHANNELS
1214 RUN_TEST(utest_scmi_perf_message_handler_bad_message_id);
1215 RUN_TEST(utest_scmi_perf_message_handler_not_found);
1216 # endif
1217
1218 RUN_TEST(utest_scmi_perf_protocol_version_handler);
1219 RUN_TEST(utest_scmi_perf_protocol_attributes_handler);
1220
1221 RUN_TEST(utest_scmi_perf_protocol_message_attributes_handler_valid_param);
1222 RUN_TEST(utest_scmi_perf_protocol_message_attributes_handler_invalid_param);
1223
1224 RUN_TEST(utest_scmi_perf_domain_attributes_handler_valid_param);
1225 RUN_TEST(utest_scmi_perf_domain_attributes_handler_invalid_param);
1226
1227 RUN_TEST(utest_scmi_perf_describe_levels_handler_valid_param);
1228 RUN_TEST(utest_scmi_perf_describe_levels_handler_invalid_domain_id);
1229 RUN_TEST(utest_scmi_perf_describe_levels_handler_invalid_level_index);
1230
1231 #ifdef BUILD_HAS_SCMI_PERF_FAST_CHANNELS
1232 RUN_TEST(utest_scmi_perf_describe_fast_channels_valid_params);
1233 RUN_TEST(utest_scmi_perf_describe_fast_channels_invalid_domain_id);
1234 RUN_TEST(utest_scmi_perf_describe_fast_channels_invalid_message_id);
1235 #endif
1236
1237 RUN_TEST(utest_find_opp_for_level_valid_level);
1238 RUN_TEST(utest_find_opp_for_level_invalid_level);
1239 RUN_TEST(utest_find_opp_for_level_use_nearest);
1240
1241 RUN_TEST(utest_validate_new_limits_valid_limits);
1242 RUN_TEST(utest_validate_new_limits_invalid_limits);
1243 RUN_TEST(utest_validate_new_limits_approximate_level);
1244
1245 #else
1246 RUN_TEST(utest_perf_eval_performance_invalid_limits);
1247
1248 RUN_TEST(utest_perf_eval_performance_unchanged_limits);
1249 RUN_TEST(utest_perf_eval_performance_unchanged_limits_level_up);
1250 RUN_TEST(utest_perf_eval_performance_unchanged_limits_level_down);
1251
1252 RUN_TEST(utest_perf_eval_performance_new_limits);
1253 RUN_TEST(utest_perf_eval_performance_new_limits_level_up);
1254 RUN_TEST(utest_perf_eval_performance_new_limits_level_down);
1255 #endif
1256
1257 return UNITY_END();
1258 }
1259
1260 #if !defined(TEST_ON_TARGET)
main(void)1261 int main(void)
1262 {
1263 return scmi_perf_test_main();
1264 }
1265 #endif
1266