blob: 322f166dc7f222ed575b5226d888e6e3ecc2fb91 [file] [log] [blame]
jaypit02ea3cd062018-10-05 12:22:38 +05301/** @file
Gowtham Siddarth47223082019-01-17 09:59:50 +05302 * Copyright (c) 2018-2019, 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
31/**
32 * @brief Connect to given sid
33 @param -sid : RoT service id
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +053034 @param -version : version of RoT service
jaypit02ea3cd062018-10-05 12:22:38 +053035 @param -handle - return connection handle
36 * @return val_status_t
37 */
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +053038val_status_t val_ipc_connect(uint32_t sid, uint32_t version, psa_handle_t *handle )
jaypit02ea3cd062018-10-05 12:22:38 +053039{
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +053040 *handle = pal_ipc_connect(sid, version);
jaypit02ea3cd062018-10-05 12:22:38 +053041
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +053042 if (*handle > 0)
43 return VAL_STATUS_SUCCESS;
jaypit02ea3cd062018-10-05 12:22:38 +053044
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +053045 return VAL_STATUS_CONNECTION_FAILED;
jaypit02ea3cd062018-10-05 12:22:38 +053046}
47
48/**
49 * @brief Call a connected Root of Trust Service.@n
50 * The caller must provide an array of ::psa_invec_t structures as the input payload.
51 *
52 * @param handle Handle for the connection.
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +053053 * @param type Request type
jaypit02ea3cd062018-10-05 12:22:38 +053054 * @param in_vec Array of psa_invec structures.
55 * @param in_len Number of psa_invec structures in in_vec.
56 * @param out_vec Array of psa_outvec structures for optional Root of Trust Service response.
57 * @param out_len Number of psa_outvec structures in out_vec.
58 * @return val_status_t
59 */
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +053060val_status_t val_ipc_call(psa_handle_t handle,
61 int32_t type,
62 const psa_invec *in_vec,
63 size_t in_len,
64 psa_outvec *out_vec,
65 size_t out_len)
jaypit02ea3cd062018-10-05 12:22:38 +053066{
67 psa_status_t call_status = PSA_SUCCESS;
68
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +053069 call_status = pal_ipc_call(handle, type, in_vec, in_len, out_vec, out_len);
jaypit02ea3cd062018-10-05 12:22:38 +053070
71 if (call_status != PSA_SUCCESS)
72 {
73 return VAL_STATUS_CALL_FAILED;
74 }
75
76 return VAL_STATUS_SUCCESS;
77}
78
79/**
80 * @brief Close a connection to a Root of Trust Service.
81 * Sends the PSA_IPC_DISCONNECT message to the Root of Trust Service so it can clean up resources.
82 *
83 * @param handle Handle for the connection.
84 * @return void
85 */
86void val_ipc_close(psa_handle_t handle)
87{
jaypit02ac23b5b2018-11-02 13:10:19 +053088 pal_ipc_close(handle);
jaypit02ea3cd062018-10-05 12:22:38 +053089}
90/**
91 @brief - This function executes given list of tests from non-secure sequentially
92 This covers non-secure to secure IPC API scenario
93 @param - test_num : Test_num
94 @param - tests_list : list of tests to be executed
95 @param - server_hs : Initiate a server handshake
96 @return - val_status_t
97**/
98val_status_t val_execute_non_secure_tests(uint32_t test_num, client_test_t *tests_list,
99 bool_t server_hs)
100{
101 val_status_t status = VAL_STATUS_SUCCESS;
102 val_status_t test_status = VAL_STATUS_SUCCESS;
103 boot_t boot;
104 psa_handle_t handle;
105 uint32_t i = 1;
106 test_info_t test_info;
107
108 test_info.test_num = test_num;
109
110 status = val_get_boot_flag(&boot.state);
111 if (VAL_ERROR(status))
112 {
113 val_set_status(RESULT_FAIL(status));
114 return status;
115 }
116
Gowtham Siddarthb8926262019-08-05 12:59:35 +0530117 if (boot.state == BOOT_NOT_EXPECTED || boot.state == BOOT_EXPECTED_REENTER_TEST
118 || boot.state == BOOT_EXPECTED_CONT_TEST_EXEC)
jaypit02ea3cd062018-10-05 12:22:38 +0530119 {
jaypit02ea3cd062018-10-05 12:22:38 +0530120 while (tests_list[i] != NULL)
121 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530122 /*
123 * Reboot have been expected by test in previous ns run,
124 * consider previous run pass and jump to second test function
125 * of the same test if available.
126 */
127 if ((boot.state == BOOT_EXPECTED_REENTER_TEST) && (i == 1))
128 {
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530129 val_print(PRINT_DEBUG, "[Check 1] PASSED\n", 0);
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530130 i++;
131 continue;
132 }
133
Gowtham Siddarthb8926262019-08-05 12:59:35 +0530134 if (boot.state != BOOT_EXPECTED_CONT_TEST_EXEC)
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530135 {
Gowtham Siddarthb8926262019-08-05 12:59:35 +0530136 status = val_set_boot_flag(BOOT_NOT_EXPECTED);
137 if (VAL_ERROR(status))
138 {
139 return status;
140 }
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530141 }
142
143 if (i == 1)
144 val_print(PRINT_TEST,"[Info] Executing tests from non-secure\n", 0);
145
jaypit02ea3cd062018-10-05 12:22:38 +0530146 if (server_hs == TRUE)
147 {
148 /* Handshake with server tests */
149 test_info.block_num = i;
150 status = val_execute_secure_test_func(&handle, test_info,
151 SERVER_TEST_DISPATCHER_SID);
152 if (VAL_ERROR(status))
153 {
154 val_set_status(RESULT_FAIL(status));
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530155 val_print(PRINT_DEBUG, "[Check %d] START\n", i);
jaypit02ea3cd062018-10-05 12:22:38 +0530156 return status;
157 }
158 else
159 {
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530160 val_print(PRINT_DEBUG, "[Check %d] START\n", i);
jaypit02ea3cd062018-10-05 12:22:38 +0530161 }
162 }
163
164 /* Execute client tests */
Gowtham Siddarthb1cd50f2019-08-21 11:50:26 +0530165 test_status = tests_list[i](CALLER_NONSECURE);
jaypit02ea3cd062018-10-05 12:22:38 +0530166
167 if (server_hs == TRUE)
168 {
169 /* Retrive Server test status */
170 status = val_get_secure_test_result(&handle);
171 }
172
173 status = test_status ? test_status:status;
Gowtham Siddarth47223082019-01-17 09:59:50 +0530174 if (IS_TEST_SKIP(status))
175 {
176 val_set_status(status);
177 if (server_hs == TRUE)
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530178 val_print(PRINT_DEBUG, "[Check %d] SKIPPED\n", i);
Gowtham Siddarth47223082019-01-17 09:59:50 +0530179 return status;
180 }
181 else if (VAL_ERROR(status))
jaypit02ea3cd062018-10-05 12:22:38 +0530182 {
183 val_set_status(RESULT_FAIL(status));
jaypit02ac23b5b2018-11-02 13:10:19 +0530184 if (server_hs == TRUE)
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530185 val_print(PRINT_DEBUG, "[Check %d] FAILED\n", i);
Gowtham Siddarth47223082019-01-17 09:59:50 +0530186
jaypit02ea3cd062018-10-05 12:22:38 +0530187 return status;
188 }
189 else
190 {
jaypit02ac23b5b2018-11-02 13:10:19 +0530191 if (server_hs == TRUE)
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530192 val_print(PRINT_DEBUG, "[Check %d] PASSED\n", i);
jaypit02ea3cd062018-10-05 12:22:38 +0530193 }
Gowtham Siddarth47223082019-01-17 09:59:50 +0530194
jaypit02ea3cd062018-10-05 12:22:38 +0530195 i++;
196 }
197 }
198 else
199 {
200 /* If we are here means, we are in second run of this test */
201 status = VAL_STATUS_SUCCESS;
202 if (boot.state != BOOT_EXPECTED_S)
203 {
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530204 val_print(PRINT_DEBUG, "[Check 1] PASSED\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530205 }
206 }
207 return status;
208}
209/**
210 @brief - This function is used to switch to client_partition.c
211 where client tests will be executed to cover secure to secure
212 IPC scenario.
213 @param - test_num : Test_num
214 @return - val_status_t
215**/
216val_status_t val_switch_to_secure_client(uint32_t test_num)
217{
218 val_status_t status = VAL_STATUS_SUCCESS;
219 boot_t boot;
220 psa_handle_t handle;
221 test_info_t test_info;
222
223 test_info.test_num = test_num;
224 test_info.block_num = 1;
225
226 status = val_get_boot_flag(&boot.state);
227 if (VAL_ERROR(status))
228 {
229 goto exit;
230 }
231
232 if (boot.state != BOOT_EXPECTED_S)
233 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530234 /*
235 * Reboot have been expected by test in previous s run,
236 * consider previous run pass and jump to second test function
237 * of the same test if available.
238 */
239 if (boot.state == BOOT_EXPECTED_REENTER_TEST)
240 {
241 test_info.block_num++;
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530242 val_print(PRINT_DEBUG, "[Check 1] PASSED\n", 0);
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530243 }
244
jaypit02ea3cd062018-10-05 12:22:38 +0530245 status = val_set_boot_flag(BOOT_NOT_EXPECTED);
246 if (VAL_ERROR(status))
247 {
248 goto exit;
249 }
250
251 /* switch to secure client */
252 status = val_execute_secure_test_func(&handle, test_info, CLIENT_TEST_DISPATCHER_SID);
253 if (VAL_ERROR(status))
254 {
255 goto exit;
256 }
257
258 /* Retrive secure client test status */
259 status = val_get_secure_test_result(&handle);
Gowtham Siddarth47223082019-01-17 09:59:50 +0530260 if (IS_TEST_SKIP(status))
261 {
262 val_set_status(status);
263 return status;
264 }
jaypit02ea3cd062018-10-05 12:22:38 +0530265 if (VAL_ERROR(status))
266 {
267 goto exit;
268 }
269 return status;
270 }
271 else
272 {
273 /* If we are here means, we are in third run of this test */
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530274 val_print(PRINT_DEBUG, "[Check 1] PASSED\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530275 return VAL_STATUS_SUCCESS;
276 }
277
278exit:
279 val_set_status(RESULT_FAIL(status));
280 return status;
281}
282
283/**
284 @brief - This function is used to handshake between:
285 - nonsecure client fn to server test fn
286 - secure client fn and server test fn
287 - nonsecure client fn to secure client test fn
288 @param - handle : handle returned while connecting given sid
289 @param - test_info : Test_num and block_num to be executed
290 @param - sid : RoT service to be connected. Partition dispatcher sid
291 @return - val_status_t
292**/
293val_status_t val_execute_secure_test_func(psa_handle_t *handle, test_info_t test_info, uint32_t sid)
294{
295 uint32_t test_data;
296 val_status_t status = VAL_STATUS_SUCCESS;
297 psa_status_t status_of_call = PSA_SUCCESS;
298
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530299 *handle = pal_ipc_connect(sid, 1);
300 if (*handle > 0)
301 {
302 test_data = ((uint32_t)(test_info.test_num) |((uint32_t)(test_info.block_num) << BLOCK_NUM_POS)
303 | ((uint32_t)(TEST_EXECUTE_FUNC) << ACTION_POS));
304 psa_invec data[1] = {{&test_data, sizeof(test_data)}};
305
306 status_of_call = pal_ipc_call(*handle, 0, data, 1, NULL, 0);
307 if (status_of_call != PSA_SUCCESS)
308 {
309 status = VAL_STATUS_CALL_FAILED;
310 val_print(PRINT_ERROR, "Call to dispatch SF failed. Status=%x\n", status_of_call);
311 pal_ipc_close(*handle);
312 }
313 }
314 else
jaypit02ea3cd062018-10-05 12:22:38 +0530315 {
316 val_print(PRINT_ERROR, "Could not connect SID. Handle=%x\n", *handle);
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530317 status = VAL_STATUS_CONNECTION_FAILED;
jaypit02ea3cd062018-10-05 12:22:38 +0530318 }
Gowtham Siddarth47223082019-01-17 09:59:50 +0530319
jaypit02ea3cd062018-10-05 12:22:38 +0530320 return status;
321}
322
323/**
324 @brief - This function is used to retrive the status of previously connected test function
325 using val_execute_secure_test_func
326 @param - handle : handle of server function. Handle of Partition dispatcher sid
327 @return - The status of test functions
328**/
329val_status_t val_get_secure_test_result(psa_handle_t *handle)
330{
331 uint32_t test_data;
332 val_status_t status = VAL_STATUS_SUCCESS;
333 psa_status_t status_of_call = PSA_SUCCESS;
334
335 test_data = (TEST_RETURN_RESULT << ACTION_POS);
336
337 psa_outvec resp = {&status, sizeof(status)};
338 psa_invec data[1] = {{&test_data, sizeof(test_data)}};
339
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530340 status_of_call = pal_ipc_call(*handle, 0, data, 1, &resp, 1);
jaypit02ea3cd062018-10-05 12:22:38 +0530341 if (status_of_call != PSA_SUCCESS)
342 {
343 status = VAL_STATUS_CALL_FAILED;
344 val_print(PRINT_ERROR, "Call to dispatch SF failed. Status=%x\n", status_of_call);
345 }
346
jaypit02ac23b5b2018-11-02 13:10:19 +0530347 pal_ipc_close(*handle);
jaypit02ea3cd062018-10-05 12:22:38 +0530348 return status;
349}
350
351
352/**
353 @brief - Parses input status for a given test and
354 outputs appropriate information on the console
355 @return - Test state
356**/
357uint32_t val_report_status(void)
358{
359 uint32_t status, state;
360
361 status = val_get_status();
362
363 state = (status >> TEST_STATE_BIT) & TEST_STATE_MASK;
364 status = status & TEST_STATUS_MASK;
365
366 switch (state)
367 {
368 case TEST_START:
369 state = TEST_FAIL;
370 val_print(PRINT_ALWAYS, "TEST RESULT: FAILED (Error Code=0x%x)\n",
371 VAL_STATUS_INIT_FAILED);
372 break;
373
374 case TEST_END:
375 state = TEST_PASS;
376 val_print(PRINT_ALWAYS, "TEST RESULT: PASSED \n", 0);
377 break;
378
379 case TEST_FAIL:
380 val_print(PRINT_ALWAYS, "TEST RESULT: FAILED (Error Code=0x%x) \n", status);
381 break;
382
383 case TEST_SKIP:
Gowtham Siddarth47223082019-01-17 09:59:50 +0530384 state = TEST_SKIP;
jaypit02ea3cd062018-10-05 12:22:38 +0530385 val_print(PRINT_ALWAYS, "TEST RESULT: SKIPPED (Skip Code=0x%x)\n", status);
386 break;
387
388 case TEST_PENDING:
389 val_print(PRINT_ALWAYS, "TEST RESULT: SIM ERROR (Error Code=0x%x)\n", status);
390 break;
391
392 default:
393 state = TEST_FAIL;
394 val_print(PRINT_ALWAYS, "TEST RESULT: FAILED(Error Code=0x%x)\n", VAL_STATUS_INVALID);
395 break;
396
397 }
398
399 val_print(PRINT_ALWAYS, "\n******************************************\n", 0);
400 return state;
401}
402
403/**
404 @brief - Records the state and status of test
405 @return - val_status_t
406**/
407val_status_t val_set_status(uint32_t status)
408{
409 g_status_buffer.state = ((status >> TEST_STATE_BIT) & TEST_STATE_MASK);
410 g_status_buffer.status = (status & TEST_STATUS_MASK);
411
412 return VAL_STATUS_SUCCESS;
413}
414
415/**
416 @brief - Updates the state and status for a given test
417 @return - test status
418**/
419uint32_t val_get_status(void)
420{
421 return ((g_status_buffer.state) << TEST_STATE_BIT) | (g_status_buffer.status);
422}
423
424/*
425 @brief - This function checks if the input status argument is an error.
426 On error, we print the checkpoint value and set the status.
427 @param - checkpoint : Test debug checkpoint
428 - val_status_t : Test status
429 @return - returns the input status back to the program.
430*/
431
432val_status_t val_err_check_set(uint32_t checkpoint, val_status_t status)
433{
434 if (VAL_ERROR(status))
435 {
436 val_print(PRINT_ERROR, "\tCheckpoint %d : ", checkpoint);
437 val_print(PRINT_ERROR, "Error Code=0x%x \n", status);
438 val_set_status(RESULT_FAIL(status));
439 }
440 else
441 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530442 status = (val_get_status() & TEST_STATUS_MASK);
jaypit02ea3cd062018-10-05 12:22:38 +0530443 if (VAL_ERROR(status))
444 {
445 val_print(PRINT_ERROR, "\tCheckpoint %d : ", checkpoint);
446 val_print(PRINT_ERROR, "Error Code=0x%x \n", status);
447 }
448 else
449 {
450 val_print(PRINT_DEBUG, "\tCheckpoint %d \n", checkpoint);
451 }
452 }
453 return status;
454}
455
456/**
457 @brief This API prints the test number, description and
458 sets the test state to TEST_START on successful execution.
459 @param test_num :unique number identifying this test
460 @param desc :brief description of the test
461 @param test_bitfield :Addition test info such as
462 - test isolation level requirement
463 - Watchdog timeout type
464 @return void
465**/
466
467void val_test_init(uint32_t test_num, char8_t *desc, uint32_t test_bitfield)
468{
469 val_status_t status = VAL_STATUS_SUCCESS;
jaypit02ea3cd062018-10-05 12:22:38 +0530470
471 /*global init*/
cherat013f028722019-02-18 14:50:37 +0530472 g_status_buffer.state = TEST_FAIL;
jaypit02ea3cd062018-10-05 12:22:38 +0530473 g_status_buffer.status = VAL_STATUS_INVALID;
474
475 val_print(PRINT_ALWAYS, "\nTEST: %d | DESCRIPTION: ", test_num);
476 val_print(PRINT_ALWAYS, desc, 0);
477
478 /* common skip logic */
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530479 if (PLATFORM_PSA_ISOLATION_LEVEL < GET_TEST_ISOLATION_LEVEL(test_bitfield))
jaypit02ea3cd062018-10-05 12:22:38 +0530480 {
481 val_set_status(RESULT_SKIP(VAL_STATUS_ISOLATION_LEVEL_NOT_SUPP));
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530482 val_print(PRINT_ALWAYS, "\tSkipping test. Required isolation level is not supported\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530483 return;
484 }
485
Vinay Kumar Kotegowder9982f902019-07-15 09:13:54 +0530486#ifdef WATCHDOG_AVAILABLE
jaypit02ea3cd062018-10-05 12:22:38 +0530487 /* Initialise watchdog */
488 status = val_wd_timer_init(GET_WD_TIMOUT_TYPE(test_bitfield));
489 if (VAL_ERROR(status))
490 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530491 val_print(PRINT_ERROR, "\tval_wd_timer_init failed Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530492 return;
493 }
494
495 /* Enable watchdog Timer */
496 status = val_wd_timer_enable();
497 if (VAL_ERROR(status))
498 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530499 val_print(PRINT_ERROR, "\tval_wd_timer_enable failed Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530500 return;
501 }
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530502#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530503
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530504 val_set_status(RESULT_START(status));
jaypit02ea3cd062018-10-05 12:22:38 +0530505 return;
506}
507
508/**
509 @brief This API sets the test state to TEST_END if test is successfuly passed.
510 @param none
511 @return none
512**/
513
514void val_test_exit(void)
515{
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530516 val_status_t status = VAL_STATUS_SUCCESS;
jaypit02ea3cd062018-10-05 12:22:38 +0530517
Vinay Kumar Kotegowder9982f902019-07-15 09:13:54 +0530518#ifdef WATCHDOG_AVAILABLE
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530519 status = val_wd_timer_disable();
520 if (VAL_ERROR(status))
521 {
522 val_print(PRINT_ERROR, "\tval_wd_timer_disable failed Error=0x%x\n", status);
523 val_set_status(RESULT_FAIL(status));
524 return;
525 }
526#endif
527
Gowtham Siddarth47223082019-01-17 09:59:50 +0530528 status = val_get_status();
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530529
jaypit02ea3cd062018-10-05 12:22:38 +0530530 /* return if test skipped or failed */
Gowtham Siddarth47223082019-01-17 09:59:50 +0530531 if (IS_TEST_FAIL(status) || IS_TEST_SKIP(status))
jaypit02ea3cd062018-10-05 12:22:38 +0530532 {
Gowtham Siddarth47223082019-01-17 09:59:50 +0530533 return;
jaypit02ea3cd062018-10-05 12:22:38 +0530534 }
Gowtham Siddarth47223082019-01-17 09:59:50 +0530535 else
536 {
537 val_set_status(RESULT_END(VAL_STATUS_SUCCESS));
538 }
jaypit02ea3cd062018-10-05 12:22:38 +0530539}
540
541/**
542 @brief - This function returns the test ID of the last test that was run
543 @param - test_id address
544 @return - val_status_t
545**/
546val_status_t val_get_last_run_test_id(test_id_t *test_id)
547{
548 val_status_t status;
549 test_count_t test_count;
550 boot_t boot;
551 int i = 0, intermediate_boot = 0;
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530552 boot_state_t boot_state[] = {BOOT_NOT_EXPECTED,
553 BOOT_EXPECTED_NS,
554 BOOT_EXPECTED_S,
555 BOOT_EXPECTED_BUT_FAILED,
Gowtham Siddarthb8926262019-08-05 12:59:35 +0530556 BOOT_EXPECTED_REENTER_TEST,
557 BOOT_EXPECTED_CONT_TEST_EXEC
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530558 };
jaypit02ea3cd062018-10-05 12:22:38 +0530559
560 status = val_get_boot_flag(&boot.state);
561 if (VAL_ERROR(status))
562 {
563 return status;
564 }
565
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530566 val_print(PRINT_INFO, "\n\tboot.state=0x%x", boot.state);
567
jaypit02ea3cd062018-10-05 12:22:38 +0530568 for (i = 0; i < (sizeof(boot_state)/sizeof(boot_state[0])); i++)
569 {
570 if (boot.state == boot_state[i])
571 {
572 intermediate_boot = 1;
573 break;
574 }
575 }
576
577 if (!intermediate_boot)
578 {
579 /* First boot. Initiliase necessary data structure */
580 status = val_set_boot_flag(BOOT_UNKNOWN);
581 if (VAL_ERROR(status))
582 {
583 return status;
584 }
585
586 *test_id = VAL_INVALID_TEST_ID;
587 status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_TEST_ID_PREVIOUS),
588 test_id, sizeof(test_id_t));
589 if (VAL_ERROR(status))
590 {
591 val_print(PRINT_ALWAYS, "\n\tNVMEM write error", 0);
592 return status;
593 }
594
595 test_count.pass_cnt = 0;
596 test_count.fail_cnt = 0;
597 test_count.skip_cnt = 0;
598 test_count.sim_error_cnt = 0;
599
600 status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_TEST_CNT),
601 &test_count, sizeof(test_count_t));
602 if (VAL_ERROR(status))
603 {
604 val_print(PRINT_ERROR, "\n\tNVMEM write error", 0);
605 return status;
606 }
607 }
608
609 status = val_nvmem_read(VAL_NVMEM_OFFSET(NV_TEST_ID_PREVIOUS), test_id, sizeof(test_id_t));
610 if (VAL_ERROR(status))
611 {
612 val_print(PRINT_ERROR, "\n\tNVMEM read error", 0);
613 }
614
615 val_print(PRINT_INFO, "In val_get_last_run_test_id, test_id=%x\n", *test_id);
616 return status;
617}
618
619/**
620 @brief - This function sets the given boot.state value to corresponding
621 boot NVMEM location
622 @param - state: boot_state_t
623 @return - val_status_t
624**/
625val_status_t val_set_boot_flag(boot_state_t state)
626{
627 boot_t boot;
628 val_status_t status;
629
630 boot.state = state;
631 status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_BOOT), &boot, sizeof(boot_t));
632 if (VAL_ERROR(status))
633 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530634 val_print(PRINT_ERROR, "\tval_nvmem_write failed. Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530635 return status;
636 }
637 return status;
638}
639
640/**
641 @brief - This function returns boot.state value available in boot NVMEM location
642 @param - state address
643 @return - val_status_t
644**/
645val_status_t val_get_boot_flag(boot_state_t *state)
646{
647 boot_t boot;
648 val_status_t status;
649
650 status = val_nvmem_read(VAL_NVMEM_OFFSET(NV_BOOT), &boot, sizeof(boot_t));
651 if (VAL_ERROR(status))
652 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530653 val_print(PRINT_ERROR, "\tval_nvmem_read failed. Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530654 return status;
655 }
656 *state = boot.state;
657 return status;
658}