1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2022, 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 #ifdef TEST_ON_TARGET
12 #    include <fwk_id.h>
13 #    include <fwk_module.h>
14 #else
15 
16 #    include <Mockfwk_id.h>
17 #    include <Mockfwk_module.h>
18 #endif
19 
20 #include <Mockmod_scmi_extra.h>
21 
22 #include <internal/mod_scmi.h>
23 
24 #include <mod_scmi.h>
25 
26 #include <fwk_element.h>
27 #include <fwk_macros.h>
28 
29 #include UNIT_TEST_SRC
30 #include <mod_scmi_base.c>
31 
32 #define BUILD_HAS_BASE_PROTOCOL
33 
34 #define FAKE_MODULE_ID 0x5
35 
36 enum fake_services {
37     FAKE_SERVICE_IDX_PSCI,
38     FAKE_SERVICE_IDX_OSPM,
39     FAKE_SERVICE_IDX_COUNT,
40 };
41 
42 #define FAKE_API_IDX_SCMI_TRANSPORT 0x3
43 #define FAKE_SCMI_AGENT_IDX_PSCI    0x6
44 #define FAKE_SCMI_AGENT_IDX_OSPM    0x7
45 
46 static const struct fwk_element element_table[] = {
47     [FAKE_SERVICE_IDX_PSCI] = {
48         .name = "PSCI",
49         .data = &(struct mod_scmi_service_config) {
50             .transport_id = FWK_ID_ELEMENT_INIT(
51                 FAKE_MODULE_ID,
52                 FAKE_SERVICE_IDX_PSCI),
53             .transport_api_id = FWK_ID_API_INIT(
54                 FAKE_MODULE_ID,
55                 FAKE_API_IDX_SCMI_TRANSPORT),
56             .scmi_agent_id = (unsigned int) FAKE_SCMI_AGENT_IDX_PSCI,
57             .scmi_p2a_id = FWK_ID_NONE_INIT,
58         },
59     },
60 
61     [FAKE_SERVICE_IDX_OSPM] = {
62         .name = "OSPM-A2P-0",
63         .data = &(struct mod_scmi_service_config) {
64             .transport_id = FWK_ID_ELEMENT_INIT(
65                 FAKE_MODULE_ID,
66                 FAKE_SERVICE_IDX_OSPM),
67             .transport_api_id = FWK_ID_API_INIT(
68                 FAKE_MODULE_ID,
69                 FAKE_API_IDX_SCMI_TRANSPORT),
70             .scmi_agent_id = (unsigned int) FAKE_SCMI_AGENT_IDX_OSPM,
71             .scmi_p2a_id = FWK_ID_NONE_INIT,
72         },
73     },
74 
75     [FAKE_SERVICE_IDX_COUNT] = { 0 },
76 
77 };
78 
79 static const struct mod_scmi_agent agent_table[] = {
80     [FAKE_SCMI_AGENT_IDX_OSPM] = {
81         .type = SCMI_AGENT_TYPE_OSPM,
82         .name = "OSPM",
83     },
84     [FAKE_SCMI_AGENT_IDX_PSCI] = {
85         .type = SCMI_AGENT_TYPE_PSCI,
86         .name = "PSCI",
87     },
88 };
89 
get_element_table(fwk_id_t module_id)90 static const struct fwk_element *get_element_table(fwk_id_t module_id)
91 {
92     return element_table;
93 }
94 
95 struct fwk_module_config config_scmi = {
96     .data =
97         &(struct mod_scmi_config){
98             .protocol_count_max = 6,
99             .agent_count = FWK_ARRAY_SIZE(agent_table) - 1,
100             .agent_table = agent_table,
101             .vendor_identifier = "arm",
102             .sub_vendor_identifier = "arm",
103         },
104 
105     .elements = FWK_MODULE_DYNAMIC_ELEMENTS(get_element_table),
106 };
107 
108 static struct mod_scmi_to_transport_api to_transport_api = {
109     .get_secure = mod_scmi_to_transport_api_get_secure,
110     .get_max_payload_size = mod_scmi_to_transport_api_get_max_payload_size,
111     .get_message_header = mod_scmi_to_transport_api_get_message_header,
112     .get_payload = mod_scmi_to_transport_api_get_payload,
113     .write_payload = mod_scmi_to_transport_api_write_payload,
114     .respond = mod_scmi_to_transport_api_respond,
115     .transmit = mod_scmi_to_transport_api_transmit,
116     .release_transport_channel_lock =
117         mod_scmi_to_transport_api_release_transport_channel_lock,
118 };
119 
120 static const struct mod_scmi_from_protocol_api from_protocol_api = {
121     .get_agent_count = mod_scmi_from_protocol_get_agent_count,
122     .get_agent_id = mod_scmi_from_protocol_get_agent_id,
123     .get_agent_type = mod_scmi_from_protocol_get_agent_type,
124     .get_max_payload_size = mod_scmi_from_protocol_get_max_payload_size,
125     .write_payload = mod_scmi_from_protocol_write_payload,
126     .respond = mod_scmi_from_protocol_respond,
127     .notify = mod_scmi_from_protocol_notify,
128 };
129 
setUp(void)130 void setUp(void)
131 {
132     struct scmi_service_ctx *ctx;
133     const struct mod_scmi_to_transport_api *transport_api = &to_transport_api;
134     scmi_ctx.config = (struct mod_scmi_config *)config_scmi.data;
135     scmi_ctx.protocol_table = fwk_mm_calloc(
136         scmi_ctx.config->protocol_count_max +
137             PROTOCOL_TABLE_RESERVED_ENTRIES_COUNT,
138         sizeof(scmi_ctx.protocol_table[0]));
139     scmi_ctx.protocol_table[PROTOCOL_TABLE_BASE_PROTOCOL_IDX].message_handler =
140         scmi_base_message_handler;
141     scmi_ctx.service_ctx_table = fwk_mm_calloc(
142         FAKE_SERVICE_IDX_COUNT, sizeof(scmi_ctx.service_ctx_table[0]));
143     scmi_ctx.scmi_protocol_id_to_idx[MOD_SCMI_PROTOCOL_ID_BASE] =
144         PROTOCOL_TABLE_BASE_PROTOCOL_IDX;
145 
146     scmi_base_set_shared_ctx(&scmi_ctx);
147     scmi_base_set_api(&from_protocol_api);
148 
149     ctx = &scmi_ctx.service_ctx_table[FAKE_SERVICE_IDX_PSCI];
150     ctx->config =
151         (struct mod_scmi_service_config *)element_table[FAKE_SERVICE_IDX_PSCI]
152             .data;
153     ctx->transport_api = transport_api;
154     ctx->transport_id = ctx->config->transport_id;
155     ctx->respond = transport_api->respond;
156     ctx->transmit = transport_api->transmit;
157 
158     ctx = &scmi_ctx.service_ctx_table[FAKE_SERVICE_IDX_OSPM];
159     ctx->config =
160         (struct mod_scmi_service_config *)element_table[FAKE_SERVICE_IDX_OSPM]
161             .data;
162     ctx->transport_api = transport_api;
163     ctx->transport_id = ctx->config->transport_id;
164     ctx->respond = transport_api->respond;
165     ctx->transmit = transport_api->transmit;
166 }
167 
tearDown(void)168 void tearDown(void)
169 {
170 }
171 
test_function_get_max_payload_size_invalid_param(void)172 void test_function_get_max_payload_size_invalid_param(void)
173 {
174     int status;
175 
176     fwk_id_t service_id =
177         FWK_ID_ELEMENT_INIT(FAKE_MODULE_ID, FAKE_SERVICE_IDX_OSPM);
178 
179     status = get_max_payload_size(service_id, NULL);
180     TEST_ASSERT_EQUAL(status, FWK_E_PARAM);
181 }
182 
test_function_get_max_payload_size_valid_param(void)183 void test_function_get_max_payload_size_valid_param(void)
184 {
185     int status;
186     size_t size;
187 
188     fwk_id_t service_id =
189         FWK_ID_ELEMENT_INIT(FAKE_MODULE_ID, FAKE_SERVICE_IDX_OSPM);
190 #if !defined(TEST_ON_TARGET)
191     fwk_id_get_element_idx_ExpectAndReturn(service_id, FAKE_SERVICE_IDX_OSPM);
192 #endif
193 
194     mod_scmi_to_transport_api_get_max_payload_size_ExpectAnyArgsAndReturn(
195         FWK_SUCCESS);
196 
197     status = get_max_payload_size(service_id, &size);
198 
199     TEST_ASSERT_EQUAL(status, FWK_SUCCESS);
200 }
201 
test_function_scmi_base_discover_sub_vendor_handler(void)202 void test_function_scmi_base_discover_sub_vendor_handler(void)
203 {
204     fwk_id_t service_id =
205         FWK_ID_ELEMENT_INIT(FAKE_MODULE_ID, FAKE_SERVICE_IDX_OSPM);
206 
207 #if !defined(TEST_ON_TARGET)
208     fwk_id_get_element_idx_ExpectAndReturn(service_id, FAKE_SERVICE_IDX_OSPM);
209     fwk_module_get_element_name_ExpectAndReturn(service_id, "OSPM");
210 #endif
211 
212     mod_scmi_from_protocol_respond_ExpectAnyArgsAndReturn(FWK_SUCCESS);
213 
214     TEST_ASSERT_EQUAL(
215         FWK_SUCCESS, scmi_base_discover_sub_vendor_handler(service_id, NULL));
216 }
217 
scmi_test_main(void)218 int scmi_test_main(void)
219 {
220     UNITY_BEGIN();
221     RUN_TEST(test_function_scmi_base_discover_sub_vendor_handler);
222     RUN_TEST(test_function_get_max_payload_size_invalid_param);
223     RUN_TEST(test_function_get_max_payload_size_valid_param);
224     return UNITY_END();
225 }
226 
227 #if !defined(TEST_ON_TARGET)
main(void)228 int main(void)
229 {
230     return scmi_test_main();
231 }
232 #endif
233