blob: ec6b1ccf92d57b863e7cb7a4c2d668e044b36374 [file] [log] [blame]
jaypit02ea3cd062018-10-05 12:22:38 +05301/** @file
jk-arm957cfea2021-06-18 15:52:12 +05302 * Copyright (c) 2018-2021, Arm Limited or its affiliates. All rights reserved.
jaypit02ea3cd062018-10-05 12:22:38 +05303 * SPDX-License-Identifier : Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16**/
17
18#include "val_framework.h"
19#include "val_interfaces.h"
20#include "val_dispatcher.h"
21#include "val_peripherals.h"
22#include "pal_interfaces_ns.h"
23#include "val_target.h"
24
25extern val_api_t val_api;
26extern psa_api_t psa_api;
27
28/* globals */
29test_status_buffer_t g_status_buffer;
30
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +053031#ifdef IPC
jaypit02ea3cd062018-10-05 12:22:38 +053032/**
33 * @brief Connect to given sid
34 @param -sid : RoT service id
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +053035 @param -version : version of RoT service
jaypit02ea3cd062018-10-05 12:22:38 +053036 @param -handle - return connection handle
37 * @return val_status_t
38 */
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +053039val_status_t val_ipc_connect(uint32_t sid, uint32_t version, psa_handle_t *handle )
jaypit02ea3cd062018-10-05 12:22:38 +053040{
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +053041 *handle = psa_connect(sid, version);
jaypit02ea3cd062018-10-05 12:22:38 +053042
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +053043 if (*handle > 0)
44 return VAL_STATUS_SUCCESS;
jaypit02ea3cd062018-10-05 12:22:38 +053045
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +053046 return VAL_STATUS_CONNECTION_FAILED;
jaypit02ea3cd062018-10-05 12:22:38 +053047}
48
49/**
50 * @brief Call a connected Root of Trust Service.@n
51 * The caller must provide an array of ::psa_invec_t structures as the input payload.
52 *
53 * @param handle Handle for the connection.
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +053054 * @param type Request type
jaypit02ea3cd062018-10-05 12:22:38 +053055 * @param in_vec Array of psa_invec structures.
56 * @param in_len Number of psa_invec structures in in_vec.
57 * @param out_vec Array of psa_outvec structures for optional Root of Trust Service response.
58 * @param out_len Number of psa_outvec structures in out_vec.
59 * @return val_status_t
60 */
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +053061val_status_t val_ipc_call(psa_handle_t handle,
62 int32_t type,
63 const psa_invec *in_vec,
64 size_t in_len,
65 psa_outvec *out_vec,
66 size_t out_len)
jaypit02ea3cd062018-10-05 12:22:38 +053067{
68 psa_status_t call_status = PSA_SUCCESS;
69
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +053070 call_status = psa_call(handle, type, in_vec, in_len, out_vec, out_len);
jaypit02ea3cd062018-10-05 12:22:38 +053071
72 if (call_status != PSA_SUCCESS)
73 {
74 return VAL_STATUS_CALL_FAILED;
75 }
76
77 return VAL_STATUS_SUCCESS;
78}
79
80/**
81 * @brief Close a connection to a Root of Trust Service.
82 * Sends the PSA_IPC_DISCONNECT message to the Root of Trust Service so it can clean up resources.
83 *
84 * @param handle Handle for the connection.
85 * @return void
86 */
87void val_ipc_close(psa_handle_t handle)
88{
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +053089 psa_close(handle);
jaypit02ea3cd062018-10-05 12:22:38 +053090}
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +053091#endif
92
jaypit02ea3cd062018-10-05 12:22:38 +053093/**
94 @brief - This function executes given list of tests from non-secure sequentially
95 This covers non-secure to secure IPC API scenario
96 @param - test_num : Test_num
97 @param - tests_list : list of tests to be executed
98 @param - server_hs : Initiate a server handshake
99 @return - val_status_t
100**/
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530101val_status_t val_execute_non_secure_tests(uint32_t test_num, const client_test_t *tests_list,
jaypit02ea3cd062018-10-05 12:22:38 +0530102 bool_t server_hs)
103{
104 val_status_t status = VAL_STATUS_SUCCESS;
105 val_status_t test_status = VAL_STATUS_SUCCESS;
106 boot_t boot;
jaypit02ea3cd062018-10-05 12:22:38 +0530107 uint32_t i = 1;
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530108#ifdef IPC
109 psa_handle_t handle;
jaypit02ea3cd062018-10-05 12:22:38 +0530110 test_info_t test_info;
111
112 test_info.test_num = test_num;
Vinay Kumar Kotegowder59a21912020-06-14 19:51:54 +0530113#else
114 (void)test_num;
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530115#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530116
117 status = val_get_boot_flag(&boot.state);
118 if (VAL_ERROR(status))
119 {
120 val_set_status(RESULT_FAIL(status));
121 return status;
122 }
123
Gowtham Siddarthb8926262019-08-05 12:59:35 +0530124 if (boot.state == BOOT_NOT_EXPECTED || boot.state == BOOT_EXPECTED_REENTER_TEST
125 || boot.state == BOOT_EXPECTED_CONT_TEST_EXEC)
jaypit02ea3cd062018-10-05 12:22:38 +0530126 {
jaypit02ea3cd062018-10-05 12:22:38 +0530127 while (tests_list[i] != NULL)
128 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530129 /*
130 * Reboot have been expected by test in previous ns run,
131 * consider previous run pass and jump to second test function
132 * of the same test if available.
133 */
134 if ((boot.state == BOOT_EXPECTED_REENTER_TEST) && (i == 1))
135 {
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530136 val_print(PRINT_DEBUG, "[Check 1] PASSED\n", 0);
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530137 i++;
138 continue;
139 }
140
Gowtham Siddarthb8926262019-08-05 12:59:35 +0530141 if (boot.state != BOOT_EXPECTED_CONT_TEST_EXEC)
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530142 {
Gowtham Siddarthb8926262019-08-05 12:59:35 +0530143 status = val_set_boot_flag(BOOT_NOT_EXPECTED);
144 if (VAL_ERROR(status))
145 {
146 return status;
147 }
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530148 }
149
150 if (i == 1)
151 val_print(PRINT_TEST,"[Info] Executing tests from non-secure\n", 0);
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530152#ifdef IPC
jaypit02ea3cd062018-10-05 12:22:38 +0530153 if (server_hs == TRUE)
154 {
155 /* Handshake with server tests */
156 test_info.block_num = i;
jk-arm957cfea2021-06-18 15:52:12 +0530157#if STATELESS_ROT == 1
158 status = val_execute_secure_test_func(&handle, test_info,
159 SERVER_TEST_DISPATCHER_HANDLE);
160 handle = (int32_t)SERVER_TEST_DISPATCHER_HANDLE;
161#else
jaypit02ea3cd062018-10-05 12:22:38 +0530162 status = val_execute_secure_test_func(&handle, test_info,
163 SERVER_TEST_DISPATCHER_SID);
jk-arm957cfea2021-06-18 15:52:12 +0530164#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530165 if (VAL_ERROR(status))
166 {
167 val_set_status(RESULT_FAIL(status));
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530168 val_print(PRINT_DEBUG, "[Check %d] START\n", i);
jaypit02ea3cd062018-10-05 12:22:38 +0530169 return status;
170 }
171 else
172 {
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530173 val_print(PRINT_DEBUG, "[Check %d] START\n", i);
jaypit02ea3cd062018-10-05 12:22:38 +0530174 }
175 }
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530176#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530177 /* Execute client tests */
Gowtham Siddarthb1cd50f2019-08-21 11:50:26 +0530178 test_status = tests_list[i](CALLER_NONSECURE);
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530179#ifdef IPC
jaypit02ea3cd062018-10-05 12:22:38 +0530180 if (server_hs == TRUE)
181 {
182 /* Retrive Server test status */
183 status = val_get_secure_test_result(&handle);
184 }
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530185#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530186 status = test_status ? test_status:status;
Gowtham Siddarth47223082019-01-17 09:59:50 +0530187 if (IS_TEST_SKIP(status))
188 {
189 val_set_status(status);
190 if (server_hs == TRUE)
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530191 val_print(PRINT_DEBUG, "[Check %d] SKIPPED\n", i);
Gowtham Siddarth47223082019-01-17 09:59:50 +0530192 return status;
193 }
194 else if (VAL_ERROR(status))
jaypit02ea3cd062018-10-05 12:22:38 +0530195 {
196 val_set_status(RESULT_FAIL(status));
jaypit02ac23b5b2018-11-02 13:10:19 +0530197 if (server_hs == TRUE)
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530198 val_print(PRINT_DEBUG, "[Check %d] FAILED\n", i);
Gowtham Siddarth47223082019-01-17 09:59:50 +0530199
jaypit02ea3cd062018-10-05 12:22:38 +0530200 return status;
201 }
202 else
203 {
jaypit02ac23b5b2018-11-02 13:10:19 +0530204 if (server_hs == TRUE)
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530205 val_print(PRINT_DEBUG, "[Check %d] PASSED\n", i);
jaypit02ea3cd062018-10-05 12:22:38 +0530206 }
Gowtham Siddarth47223082019-01-17 09:59:50 +0530207
jaypit02ea3cd062018-10-05 12:22:38 +0530208 i++;
209 }
210 }
211 else
212 {
213 /* If we are here means, we are in second run of this test */
214 status = VAL_STATUS_SUCCESS;
215 if (boot.state != BOOT_EXPECTED_S)
216 {
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530217 val_print(PRINT_DEBUG, "[Check 1] PASSED\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530218 }
219 }
220 return status;
221}
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530222
223#ifdef IPC
jaypit02ea3cd062018-10-05 12:22:38 +0530224/**
225 @brief - This function is used to switch to client_partition.c
226 where client tests will be executed to cover secure to secure
227 IPC scenario.
228 @param - test_num : Test_num
229 @return - val_status_t
230**/
231val_status_t val_switch_to_secure_client(uint32_t test_num)
232{
233 val_status_t status = VAL_STATUS_SUCCESS;
234 boot_t boot;
235 psa_handle_t handle;
236 test_info_t test_info;
237
238 test_info.test_num = test_num;
239 test_info.block_num = 1;
240
241 status = val_get_boot_flag(&boot.state);
242 if (VAL_ERROR(status))
243 {
244 goto exit;
245 }
246
247 if (boot.state != BOOT_EXPECTED_S)
248 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530249 /*
250 * Reboot have been expected by test in previous s run,
251 * consider previous run pass and jump to second test function
252 * of the same test if available.
253 */
254 if (boot.state == BOOT_EXPECTED_REENTER_TEST)
255 {
256 test_info.block_num++;
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530257 val_print(PRINT_DEBUG, "[Check 1] PASSED\n", 0);
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530258 }
259
jaypit02ea3cd062018-10-05 12:22:38 +0530260 status = val_set_boot_flag(BOOT_NOT_EXPECTED);
261 if (VAL_ERROR(status))
262 {
263 goto exit;
264 }
265
266 /* switch to secure client */
jk-arm957cfea2021-06-18 15:52:12 +0530267#if STATELESS_ROT == 1
268 status = val_execute_secure_test_func(&handle, test_info, CLIENT_TEST_DISPATCHER_HANDLE);
269 handle = (int32_t)CLIENT_TEST_DISPATCHER_HANDLE;
270#else
jaypit02ea3cd062018-10-05 12:22:38 +0530271 status = val_execute_secure_test_func(&handle, test_info, CLIENT_TEST_DISPATCHER_SID);
jk-arm957cfea2021-06-18 15:52:12 +0530272#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530273 if (VAL_ERROR(status))
274 {
275 goto exit;
276 }
277
278 /* Retrive secure client test status */
279 status = val_get_secure_test_result(&handle);
Gowtham Siddarth47223082019-01-17 09:59:50 +0530280 if (IS_TEST_SKIP(status))
281 {
282 val_set_status(status);
283 return status;
284 }
jaypit02ea3cd062018-10-05 12:22:38 +0530285 if (VAL_ERROR(status))
286 {
287 goto exit;
288 }
289 return status;
290 }
291 else
292 {
293 /* If we are here means, we are in third run of this test */
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530294 val_print(PRINT_DEBUG, "[Check 1] PASSED\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530295 return VAL_STATUS_SUCCESS;
296 }
297
298exit:
299 val_set_status(RESULT_FAIL(status));
300 return status;
301}
302
303/**
304 @brief - This function is used to handshake between:
305 - nonsecure client fn to server test fn
306 - secure client fn and server test fn
307 - nonsecure client fn to secure client test fn
308 @param - handle : handle returned while connecting given sid
309 @param - test_info : Test_num and block_num to be executed
310 @param - sid : RoT service to be connected. Partition dispatcher sid
311 @return - val_status_t
312**/
jk-arm957cfea2021-06-18 15:52:12 +0530313val_status_t val_execute_secure_test_func(__attribute__((unused)) psa_handle_t *handle,
314 test_info_t test_info, uint32_t sid)
jaypit02ea3cd062018-10-05 12:22:38 +0530315{
316 uint32_t test_data;
317 val_status_t status = VAL_STATUS_SUCCESS;
318 psa_status_t status_of_call = PSA_SUCCESS;
jk-arm957cfea2021-06-18 15:52:12 +0530319#if STATELESS_ROT == 1
320 test_data = ((uint32_t)(test_info.test_num) | ((uint32_t)(test_info.block_num) << BLOCK_NUM_POS)
321 | ((uint32_t)(TEST_EXECUTE_FUNC) << ACTION_POS));
322 psa_invec data[1] = { {&test_data, sizeof(test_data)} };
jaypit02ea3cd062018-10-05 12:22:38 +0530323
jk-arm957cfea2021-06-18 15:52:12 +0530324 status_of_call = psa_call(sid, 0, data, 1, NULL, 0);
325 if (status_of_call != PSA_SUCCESS)
326 {
327 status = VAL_STATUS_CALL_FAILED;
328 val_print(PRINT_ERROR, "Call to dispatch SF failed. Status=%x\n", status_of_call);
329 }
330 return status;
331#else
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530332 *handle = psa_connect(sid, 1);
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530333 if (*handle > 0)
334 {
335 test_data = ((uint32_t)(test_info.test_num) |((uint32_t)(test_info.block_num) << BLOCK_NUM_POS)
336 | ((uint32_t)(TEST_EXECUTE_FUNC) << ACTION_POS));
337 psa_invec data[1] = {{&test_data, sizeof(test_data)}};
338
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530339 status_of_call = psa_call(*handle, 0, data, 1, NULL, 0);
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530340 if (status_of_call != PSA_SUCCESS)
341 {
342 status = VAL_STATUS_CALL_FAILED;
343 val_print(PRINT_ERROR, "Call to dispatch SF failed. Status=%x\n", status_of_call);
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530344 psa_close(*handle);
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530345 }
346 }
347 else
jaypit02ea3cd062018-10-05 12:22:38 +0530348 {
349 val_print(PRINT_ERROR, "Could not connect SID. Handle=%x\n", *handle);
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530350 status = VAL_STATUS_CONNECTION_FAILED;
jaypit02ea3cd062018-10-05 12:22:38 +0530351 }
Gowtham Siddarth47223082019-01-17 09:59:50 +0530352
jaypit02ea3cd062018-10-05 12:22:38 +0530353 return status;
jk-arm957cfea2021-06-18 15:52:12 +0530354#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530355}
356
357/**
358 @brief - This function is used to retrive the status of previously connected test function
359 using val_execute_secure_test_func
360 @param - handle : handle of server function. Handle of Partition dispatcher sid
361 @return - The status of test functions
362**/
363val_status_t val_get_secure_test_result(psa_handle_t *handle)
364{
365 uint32_t test_data;
366 val_status_t status = VAL_STATUS_SUCCESS;
367 psa_status_t status_of_call = PSA_SUCCESS;
368
369 test_data = (TEST_RETURN_RESULT << ACTION_POS);
370
371 psa_outvec resp = {&status, sizeof(status)};
372 psa_invec data[1] = {{&test_data, sizeof(test_data)}};
373
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530374 status_of_call = psa_call(*handle, 0, data, 1, &resp, 1);
jaypit02ea3cd062018-10-05 12:22:38 +0530375 if (status_of_call != PSA_SUCCESS)
376 {
377 status = VAL_STATUS_CALL_FAILED;
378 val_print(PRINT_ERROR, "Call to dispatch SF failed. Status=%x\n", status_of_call);
379 }
jk-arm957cfea2021-06-18 15:52:12 +0530380#if STATELESS_ROT != 1
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530381 psa_close(*handle);
jk-arm957cfea2021-06-18 15:52:12 +0530382#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530383 return status;
384}
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530385#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530386
387/**
388 @brief - Parses input status for a given test and
389 outputs appropriate information on the console
390 @return - Test state
391**/
392uint32_t val_report_status(void)
393{
394 uint32_t status, state;
395
396 status = val_get_status();
397
398 state = (status >> TEST_STATE_BIT) & TEST_STATE_MASK;
399 status = status & TEST_STATUS_MASK;
400
401 switch (state)
402 {
403 case TEST_START:
404 state = TEST_FAIL;
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530405 val_print(PRINT_ALWAYS, "\nTEST RESULT: FAILED (Error Code=0x%x)\n",
jaypit02ea3cd062018-10-05 12:22:38 +0530406 VAL_STATUS_INIT_FAILED);
407 break;
408
409 case TEST_END:
410 state = TEST_PASS;
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530411 val_print(PRINT_ALWAYS, "\nTEST RESULT: PASSED\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530412 break;
413
414 case TEST_FAIL:
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530415 val_print(PRINT_ALWAYS, "\nTEST RESULT: FAILED (Error Code=0x%x)\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530416 break;
417
418 case TEST_SKIP:
Gowtham Siddarth47223082019-01-17 09:59:50 +0530419 state = TEST_SKIP;
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530420 val_print(PRINT_ALWAYS, "\nTEST RESULT: SKIPPED (Skip Code=0x%x)\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530421 break;
422
423 case TEST_PENDING:
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530424 val_print(PRINT_ALWAYS, "\nTEST RESULT: SIM ERROR (Error Code=0x%x)\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530425 break;
426
427 default:
428 state = TEST_FAIL;
Vinay Kumar Kotegowder18fcd402020-04-27 17:38:41 +0530429 val_print(PRINT_ALWAYS, "\nTEST RESULT: FAILED(Error Code=0x%x)\n", VAL_STATUS_INVALID);
jaypit02ea3cd062018-10-05 12:22:38 +0530430 break;
431
432 }
433
434 val_print(PRINT_ALWAYS, "\n******************************************\n", 0);
435 return state;
436}
437
438/**
439 @brief - Records the state and status of test
440 @return - val_status_t
441**/
442val_status_t val_set_status(uint32_t status)
443{
444 g_status_buffer.state = ((status >> TEST_STATE_BIT) & TEST_STATE_MASK);
445 g_status_buffer.status = (status & TEST_STATUS_MASK);
446
447 return VAL_STATUS_SUCCESS;
448}
449
450/**
451 @brief - Updates the state and status for a given test
452 @return - test status
453**/
454uint32_t val_get_status(void)
455{
456 return ((g_status_buffer.state) << TEST_STATE_BIT) | (g_status_buffer.status);
457}
458
459/*
460 @brief - This function checks if the input status argument is an error.
461 On error, we print the checkpoint value and set the status.
462 @param - checkpoint : Test debug checkpoint
463 - val_status_t : Test status
464 @return - returns the input status back to the program.
465*/
466
467val_status_t val_err_check_set(uint32_t checkpoint, val_status_t status)
468{
469 if (VAL_ERROR(status))
470 {
471 val_print(PRINT_ERROR, "\tCheckpoint %d : ", checkpoint);
472 val_print(PRINT_ERROR, "Error Code=0x%x \n", status);
473 val_set_status(RESULT_FAIL(status));
474 }
475 else
476 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530477 status = (val_get_status() & TEST_STATUS_MASK);
jaypit02ea3cd062018-10-05 12:22:38 +0530478 if (VAL_ERROR(status))
479 {
480 val_print(PRINT_ERROR, "\tCheckpoint %d : ", checkpoint);
481 val_print(PRINT_ERROR, "Error Code=0x%x \n", status);
482 }
483 else
484 {
485 val_print(PRINT_DEBUG, "\tCheckpoint %d \n", checkpoint);
486 }
487 }
488 return status;
489}
490
491/**
492 @brief This API prints the test number, description and
493 sets the test state to TEST_START on successful execution.
494 @param test_num :unique number identifying this test
495 @param desc :brief description of the test
496 @param test_bitfield :Addition test info such as
497 - test isolation level requirement
498 - Watchdog timeout type
499 @return void
500**/
501
502void val_test_init(uint32_t test_num, char8_t *desc, uint32_t test_bitfield)
503{
504 val_status_t status = VAL_STATUS_SUCCESS;
jaypit02ea3cd062018-10-05 12:22:38 +0530505
506 /*global init*/
cherat013f028722019-02-18 14:50:37 +0530507 g_status_buffer.state = TEST_FAIL;
jaypit02ea3cd062018-10-05 12:22:38 +0530508 g_status_buffer.status = VAL_STATUS_INVALID;
509
510 val_print(PRINT_ALWAYS, "\nTEST: %d | DESCRIPTION: ", test_num);
511 val_print(PRINT_ALWAYS, desc, 0);
512
513 /* common skip logic */
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530514 if (PLATFORM_PSA_ISOLATION_LEVEL < GET_TEST_ISOLATION_LEVEL(test_bitfield))
jaypit02ea3cd062018-10-05 12:22:38 +0530515 {
516 val_set_status(RESULT_SKIP(VAL_STATUS_ISOLATION_LEVEL_NOT_SUPP));
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530517 val_print(PRINT_ALWAYS, "\tSkipping test. Required isolation level is not supported\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530518 return;
519 }
520
Vinay Kumar Kotegowder9982f902019-07-15 09:13:54 +0530521#ifdef WATCHDOG_AVAILABLE
jaypit02ea3cd062018-10-05 12:22:38 +0530522 /* Initialise watchdog */
523 status = val_wd_timer_init(GET_WD_TIMOUT_TYPE(test_bitfield));
524 if (VAL_ERROR(status))
525 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530526 val_print(PRINT_ERROR, "\tval_wd_timer_init failed Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530527 return;
528 }
529
530 /* Enable watchdog Timer */
531 status = val_wd_timer_enable();
532 if (VAL_ERROR(status))
533 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530534 val_print(PRINT_ERROR, "\tval_wd_timer_enable failed Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530535 return;
536 }
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530537#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530538
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530539 val_set_status(RESULT_START(status));
jaypit02ea3cd062018-10-05 12:22:38 +0530540 return;
541}
542
543/**
544 @brief This API sets the test state to TEST_END if test is successfuly passed.
545 @param none
546 @return none
547**/
548
549void val_test_exit(void)
550{
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530551 val_status_t status = VAL_STATUS_SUCCESS;
jaypit02ea3cd062018-10-05 12:22:38 +0530552
Vinay Kumar Kotegowder9982f902019-07-15 09:13:54 +0530553#ifdef WATCHDOG_AVAILABLE
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530554 status = val_wd_timer_disable();
555 if (VAL_ERROR(status))
556 {
557 val_print(PRINT_ERROR, "\tval_wd_timer_disable failed Error=0x%x\n", status);
558 val_set_status(RESULT_FAIL(status));
559 return;
560 }
561#endif
562
Gowtham Siddarth47223082019-01-17 09:59:50 +0530563 status = val_get_status();
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530564
jaypit02ea3cd062018-10-05 12:22:38 +0530565 /* return if test skipped or failed */
Gowtham Siddarth47223082019-01-17 09:59:50 +0530566 if (IS_TEST_FAIL(status) || IS_TEST_SKIP(status))
jaypit02ea3cd062018-10-05 12:22:38 +0530567 {
Gowtham Siddarth47223082019-01-17 09:59:50 +0530568 return;
jaypit02ea3cd062018-10-05 12:22:38 +0530569 }
Gowtham Siddarth47223082019-01-17 09:59:50 +0530570 else
571 {
572 val_set_status(RESULT_END(VAL_STATUS_SUCCESS));
573 }
jaypit02ea3cd062018-10-05 12:22:38 +0530574}
575
576/**
577 @brief - This function returns the test ID of the last test that was run
578 @param - test_id address
579 @return - val_status_t
580**/
581val_status_t val_get_last_run_test_id(test_id_t *test_id)
582{
583 val_status_t status;
584 test_count_t test_count;
585 boot_t boot;
586 int i = 0, intermediate_boot = 0;
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530587 boot_state_t boot_state[] = {BOOT_NOT_EXPECTED,
588 BOOT_EXPECTED_NS,
589 BOOT_EXPECTED_S,
590 BOOT_EXPECTED_BUT_FAILED,
Gowtham Siddarthb8926262019-08-05 12:59:35 +0530591 BOOT_EXPECTED_REENTER_TEST,
592 BOOT_EXPECTED_CONT_TEST_EXEC
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530593 };
jaypit02ea3cd062018-10-05 12:22:38 +0530594
595 status = val_get_boot_flag(&boot.state);
596 if (VAL_ERROR(status))
597 {
598 return status;
599 }
600
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530601 val_print(PRINT_INFO, "\n\tboot.state=0x%x", boot.state);
602
Vinay Kumar Kotegowder59a21912020-06-14 19:51:54 +0530603 for (i = 0; i < (int)(sizeof(boot_state)/sizeof(boot_state[0])); i++)
jaypit02ea3cd062018-10-05 12:22:38 +0530604 {
605 if (boot.state == boot_state[i])
606 {
607 intermediate_boot = 1;
608 break;
609 }
610 }
611
612 if (!intermediate_boot)
613 {
614 /* First boot. Initiliase necessary data structure */
615 status = val_set_boot_flag(BOOT_UNKNOWN);
616 if (VAL_ERROR(status))
617 {
618 return status;
619 }
620
621 *test_id = VAL_INVALID_TEST_ID;
622 status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_TEST_ID_PREVIOUS),
623 test_id, sizeof(test_id_t));
624 if (VAL_ERROR(status))
625 {
626 val_print(PRINT_ALWAYS, "\n\tNVMEM write error", 0);
627 return status;
628 }
629
630 test_count.pass_cnt = 0;
631 test_count.fail_cnt = 0;
632 test_count.skip_cnt = 0;
633 test_count.sim_error_cnt = 0;
634
635 status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_TEST_CNT),
636 &test_count, sizeof(test_count_t));
637 if (VAL_ERROR(status))
638 {
639 val_print(PRINT_ERROR, "\n\tNVMEM write error", 0);
640 return status;
641 }
642 }
643
644 status = val_nvmem_read(VAL_NVMEM_OFFSET(NV_TEST_ID_PREVIOUS), test_id, sizeof(test_id_t));
645 if (VAL_ERROR(status))
646 {
647 val_print(PRINT_ERROR, "\n\tNVMEM read error", 0);
648 }
649
650 val_print(PRINT_INFO, "In val_get_last_run_test_id, test_id=%x\n", *test_id);
651 return status;
652}
653
654/**
655 @brief - This function sets the given boot.state value to corresponding
656 boot NVMEM location
657 @param - state: boot_state_t
658 @return - val_status_t
659**/
660val_status_t val_set_boot_flag(boot_state_t state)
661{
662 boot_t boot;
663 val_status_t status;
664
665 boot.state = state;
666 status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_BOOT), &boot, sizeof(boot_t));
667 if (VAL_ERROR(status))
668 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530669 val_print(PRINT_ERROR, "\tval_nvmem_write failed. Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530670 return status;
671 }
672 return status;
673}
674
675/**
676 @brief - This function returns boot.state value available in boot NVMEM location
677 @param - state address
678 @return - val_status_t
679**/
680val_status_t val_get_boot_flag(boot_state_t *state)
681{
682 boot_t boot;
683 val_status_t status;
684
685 status = val_nvmem_read(VAL_NVMEM_OFFSET(NV_BOOT), &boot, sizeof(boot_t));
686 if (VAL_ERROR(status))
687 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530688 val_print(PRINT_ERROR, "\tval_nvmem_read failed. Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530689 return status;
690 }
691 *state = boot.state;
692 return status;
693}