blob: dad52d61e929fa9e45dd553faa5f028354ba4837 [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
34 @param -minor_version : minor_version of RoT service
35 @param -handle - return connection handle
36 * @return val_status_t
37 */
38val_status_t val_ipc_connect(uint32_t sid, uint32_t minor_version, psa_handle_t *handle )
39{
jaypit02ac23b5b2018-11-02 13:10:19 +053040 *handle = pal_ipc_connect(sid, minor_version);
jaypit02ea3cd062018-10-05 12:22:38 +053041
42 if (*handle < 0)
43 {
44 return VAL_STATUS_CONNECTION_FAILED;
45 }
46
47 return VAL_STATUS_SUCCESS;
48}
49
50/**
51 * @brief Call a connected Root of Trust Service.@n
52 * The caller must provide an array of ::psa_invec_t structures as the input payload.
53 *
54 * @param handle Handle for the connection.
55 * @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 */
61val_status_t val_ipc_call(psa_handle_t handle, psa_invec *in_vec, size_t in_len,
62 psa_outvec *out_vec, size_t out_len)
63{
64 psa_status_t call_status = PSA_SUCCESS;
65
jaypit02ac23b5b2018-11-02 13:10:19 +053066 call_status = pal_ipc_call(handle, in_vec, in_len, out_vec, out_len);
jaypit02ea3cd062018-10-05 12:22:38 +053067
68 if (call_status != PSA_SUCCESS)
69 {
70 return VAL_STATUS_CALL_FAILED;
71 }
72
73 return VAL_STATUS_SUCCESS;
74}
75
76/**
77 * @brief Close a connection to a Root of Trust Service.
78 * Sends the PSA_IPC_DISCONNECT message to the Root of Trust Service so it can clean up resources.
79 *
80 * @param handle Handle for the connection.
81 * @return void
82 */
83void val_ipc_close(psa_handle_t handle)
84{
jaypit02ac23b5b2018-11-02 13:10:19 +053085 pal_ipc_close(handle);
jaypit02ea3cd062018-10-05 12:22:38 +053086}
87/**
88 @brief - This function executes given list of tests from non-secure sequentially
89 This covers non-secure to secure IPC API scenario
90 @param - test_num : Test_num
91 @param - tests_list : list of tests to be executed
92 @param - server_hs : Initiate a server handshake
93 @return - val_status_t
94**/
95val_status_t val_execute_non_secure_tests(uint32_t test_num, client_test_t *tests_list,
96 bool_t server_hs)
97{
98 val_status_t status = VAL_STATUS_SUCCESS;
99 val_status_t test_status = VAL_STATUS_SUCCESS;
100 boot_t boot;
101 psa_handle_t handle;
102 uint32_t i = 1;
103 test_info_t test_info;
104
105 test_info.test_num = test_num;
106
107 status = val_get_boot_flag(&boot.state);
108 if (VAL_ERROR(status))
109 {
110 val_set_status(RESULT_FAIL(status));
111 return status;
112 }
113
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530114 if (boot.state == BOOT_NOT_EXPECTED || boot.state == BOOT_EXPECTED_REENTER_TEST)
jaypit02ea3cd062018-10-05 12:22:38 +0530115 {
jaypit02ea3cd062018-10-05 12:22:38 +0530116 while (tests_list[i] != NULL)
117 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530118 /*
119 * Reboot have been expected by test in previous ns run,
120 * consider previous run pass and jump to second test function
121 * of the same test if available.
122 */
123 if ((boot.state == BOOT_EXPECTED_REENTER_TEST) && (i == 1))
124 {
125 val_print(PRINT_DEBUG, "[Check1] PASSED\n", 0);
126 i++;
127 continue;
128 }
129
130 status = val_set_boot_flag(BOOT_NOT_EXPECTED);
131 if (VAL_ERROR(status))
132 {
133 return status;
134 }
135
136 if (i == 1)
137 val_print(PRINT_TEST,"[Info] Executing tests from non-secure\n", 0);
138
jaypit02ea3cd062018-10-05 12:22:38 +0530139 if (server_hs == TRUE)
140 {
141 /* Handshake with server tests */
142 test_info.block_num = i;
143 status = val_execute_secure_test_func(&handle, test_info,
144 SERVER_TEST_DISPATCHER_SID);
145 if (VAL_ERROR(status))
146 {
147 val_set_status(RESULT_FAIL(status));
Gowtham Siddarth47223082019-01-17 09:59:50 +0530148 val_print(PRINT_DEBUG,"[Check%d] START\n", i);
jaypit02ea3cd062018-10-05 12:22:38 +0530149 return status;
150 }
151 else
152 {
153 val_print(PRINT_DEBUG,"[Check%d] START\n", i);
154 }
155 }
156
157 /* Execute client tests */
158 test_status = tests_list[i](NONSECURE);
159
160 if (server_hs == TRUE)
161 {
162 /* Retrive Server test status */
163 status = val_get_secure_test_result(&handle);
164 }
165
166 status = test_status ? test_status:status;
Gowtham Siddarth47223082019-01-17 09:59:50 +0530167 if (IS_TEST_SKIP(status))
168 {
169 val_set_status(status);
170 if (server_hs == TRUE)
171 val_print(PRINT_DEBUG, "[Check%d] SKIPPED\n", i);
172 return status;
173 }
174 else if (VAL_ERROR(status))
jaypit02ea3cd062018-10-05 12:22:38 +0530175 {
176 val_set_status(RESULT_FAIL(status));
jaypit02ac23b5b2018-11-02 13:10:19 +0530177 if (server_hs == TRUE)
Gowtham Siddarth47223082019-01-17 09:59:50 +0530178 val_print(PRINT_DEBUG, "[Check%d] FAILED\n", i);
179
jaypit02ea3cd062018-10-05 12:22:38 +0530180 return status;
181 }
182 else
183 {
jaypit02ac23b5b2018-11-02 13:10:19 +0530184 if (server_hs == TRUE)
Gowtham Siddarth47223082019-01-17 09:59:50 +0530185 val_print(PRINT_DEBUG, "[Check%d] PASSED\n", i);
jaypit02ea3cd062018-10-05 12:22:38 +0530186 }
Gowtham Siddarth47223082019-01-17 09:59:50 +0530187
jaypit02ea3cd062018-10-05 12:22:38 +0530188 i++;
189 }
190 }
191 else
192 {
193 /* If we are here means, we are in second run of this test */
194 status = VAL_STATUS_SUCCESS;
195 if (boot.state != BOOT_EXPECTED_S)
196 {
Gowtham Siddarth47223082019-01-17 09:59:50 +0530197 val_print(PRINT_DEBUG, "[Check1] PASSED\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530198 }
199 }
200 return status;
201}
202/**
203 @brief - This function is used to switch to client_partition.c
204 where client tests will be executed to cover secure to secure
205 IPC scenario.
206 @param - test_num : Test_num
207 @return - val_status_t
208**/
209val_status_t val_switch_to_secure_client(uint32_t test_num)
210{
211 val_status_t status = VAL_STATUS_SUCCESS;
212 boot_t boot;
213 psa_handle_t handle;
214 test_info_t test_info;
215
216 test_info.test_num = test_num;
217 test_info.block_num = 1;
218
219 status = val_get_boot_flag(&boot.state);
220 if (VAL_ERROR(status))
221 {
222 goto exit;
223 }
224
225 if (boot.state != BOOT_EXPECTED_S)
226 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530227 /*
228 * Reboot have been expected by test in previous s run,
229 * consider previous run pass and jump to second test function
230 * of the same test if available.
231 */
232 if (boot.state == BOOT_EXPECTED_REENTER_TEST)
233 {
234 test_info.block_num++;
235 val_print(PRINT_DEBUG, "[Check1] PASSED\n", 0);
236 }
237
jaypit02ea3cd062018-10-05 12:22:38 +0530238 status = val_set_boot_flag(BOOT_NOT_EXPECTED);
239 if (VAL_ERROR(status))
240 {
241 goto exit;
242 }
243
244 /* switch to secure client */
245 status = val_execute_secure_test_func(&handle, test_info, CLIENT_TEST_DISPATCHER_SID);
246 if (VAL_ERROR(status))
247 {
248 goto exit;
249 }
250
251 /* Retrive secure client test status */
252 status = val_get_secure_test_result(&handle);
Gowtham Siddarth47223082019-01-17 09:59:50 +0530253 if (IS_TEST_SKIP(status))
254 {
255 val_set_status(status);
256 return status;
257 }
jaypit02ea3cd062018-10-05 12:22:38 +0530258 if (VAL_ERROR(status))
259 {
260 goto exit;
261 }
262 return status;
263 }
264 else
265 {
266 /* If we are here means, we are in third run of this test */
Gowtham Siddarth47223082019-01-17 09:59:50 +0530267 val_print(PRINT_DEBUG, "[Check1] PASSED\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530268 return VAL_STATUS_SUCCESS;
269 }
270
271exit:
272 val_set_status(RESULT_FAIL(status));
273 return status;
274}
275
276/**
277 @brief - This function is used to handshake between:
278 - nonsecure client fn to server test fn
279 - secure client fn and server test fn
280 - nonsecure client fn to secure client test fn
281 @param - handle : handle returned while connecting given sid
282 @param - test_info : Test_num and block_num to be executed
283 @param - sid : RoT service to be connected. Partition dispatcher sid
284 @return - val_status_t
285**/
286val_status_t val_execute_secure_test_func(psa_handle_t *handle, test_info_t test_info, uint32_t sid)
287{
288 uint32_t test_data;
289 val_status_t status = VAL_STATUS_SUCCESS;
290 psa_status_t status_of_call = PSA_SUCCESS;
291
jaypit02ac23b5b2018-11-02 13:10:19 +0530292 *handle = pal_ipc_connect(sid, 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530293 if (*handle < 0)
294 {
295 val_print(PRINT_ERROR, "Could not connect SID. Handle=%x\n", *handle);
296 return VAL_STATUS_CONNECTION_FAILED;
297 }
298
299 test_data = ((uint32_t)(test_info.test_num) |((uint32_t)(test_info.block_num) << BLOCK_NUM_POS)
300 | ((uint32_t)(TEST_EXECUTE_FUNC) << ACTION_POS));
301 psa_invec data[1] = {{&test_data, sizeof(test_data)}};
302
jaypit02ac23b5b2018-11-02 13:10:19 +0530303 status_of_call = pal_ipc_call(*handle, data, 1, NULL, 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530304 if (status_of_call != PSA_SUCCESS)
305 {
306 status = VAL_STATUS_CALL_FAILED;
307 val_print(PRINT_ERROR, "Call to dispatch SF failed. Status=%x\n", status_of_call);
jaypit02ac23b5b2018-11-02 13:10:19 +0530308 pal_ipc_close(*handle);
jaypit02ea3cd062018-10-05 12:22:38 +0530309 }
Gowtham Siddarth47223082019-01-17 09:59:50 +0530310
jaypit02ea3cd062018-10-05 12:22:38 +0530311 return status;
312}
313
314/**
315 @brief - This function is used to retrive the status of previously connected test function
316 using val_execute_secure_test_func
317 @param - handle : handle of server function. Handle of Partition dispatcher sid
318 @return - The status of test functions
319**/
320val_status_t val_get_secure_test_result(psa_handle_t *handle)
321{
322 uint32_t test_data;
323 val_status_t status = VAL_STATUS_SUCCESS;
324 psa_status_t status_of_call = PSA_SUCCESS;
325
326 test_data = (TEST_RETURN_RESULT << ACTION_POS);
327
328 psa_outvec resp = {&status, sizeof(status)};
329 psa_invec data[1] = {{&test_data, sizeof(test_data)}};
330
jaypit02ac23b5b2018-11-02 13:10:19 +0530331 status_of_call = pal_ipc_call(*handle, data, 1, &resp, 1);
jaypit02ea3cd062018-10-05 12:22:38 +0530332 if (status_of_call != PSA_SUCCESS)
333 {
334 status = VAL_STATUS_CALL_FAILED;
335 val_print(PRINT_ERROR, "Call to dispatch SF failed. Status=%x\n", status_of_call);
336 }
337
jaypit02ac23b5b2018-11-02 13:10:19 +0530338 pal_ipc_close(*handle);
jaypit02ea3cd062018-10-05 12:22:38 +0530339 return status;
340}
341
342
343/**
344 @brief - Parses input status for a given test and
345 outputs appropriate information on the console
346 @return - Test state
347**/
348uint32_t val_report_status(void)
349{
350 uint32_t status, state;
351
352 status = val_get_status();
353
354 state = (status >> TEST_STATE_BIT) & TEST_STATE_MASK;
355 status = status & TEST_STATUS_MASK;
356
357 switch (state)
358 {
359 case TEST_START:
360 state = TEST_FAIL;
361 val_print(PRINT_ALWAYS, "TEST RESULT: FAILED (Error Code=0x%x)\n",
362 VAL_STATUS_INIT_FAILED);
363 break;
364
365 case TEST_END:
366 state = TEST_PASS;
367 val_print(PRINT_ALWAYS, "TEST RESULT: PASSED \n", 0);
368 break;
369
370 case TEST_FAIL:
371 val_print(PRINT_ALWAYS, "TEST RESULT: FAILED (Error Code=0x%x) \n", status);
372 break;
373
374 case TEST_SKIP:
Gowtham Siddarth47223082019-01-17 09:59:50 +0530375 state = TEST_SKIP;
jaypit02ea3cd062018-10-05 12:22:38 +0530376 val_print(PRINT_ALWAYS, "TEST RESULT: SKIPPED (Skip Code=0x%x)\n", status);
377 break;
378
379 case TEST_PENDING:
380 val_print(PRINT_ALWAYS, "TEST RESULT: SIM ERROR (Error Code=0x%x)\n", status);
381 break;
382
383 default:
384 state = TEST_FAIL;
385 val_print(PRINT_ALWAYS, "TEST RESULT: FAILED(Error Code=0x%x)\n", VAL_STATUS_INVALID);
386 break;
387
388 }
389
390 val_print(PRINT_ALWAYS, "\n******************************************\n", 0);
391 return state;
392}
393
394/**
395 @brief - Records the state and status of test
396 @return - val_status_t
397**/
398val_status_t val_set_status(uint32_t status)
399{
400 g_status_buffer.state = ((status >> TEST_STATE_BIT) & TEST_STATE_MASK);
401 g_status_buffer.status = (status & TEST_STATUS_MASK);
402
403 return VAL_STATUS_SUCCESS;
404}
405
406/**
407 @brief - Updates the state and status for a given test
408 @return - test status
409**/
410uint32_t val_get_status(void)
411{
412 return ((g_status_buffer.state) << TEST_STATE_BIT) | (g_status_buffer.status);
413}
414
415/*
416 @brief - This function checks if the input status argument is an error.
417 On error, we print the checkpoint value and set the status.
418 @param - checkpoint : Test debug checkpoint
419 - val_status_t : Test status
420 @return - returns the input status back to the program.
421*/
422
423val_status_t val_err_check_set(uint32_t checkpoint, val_status_t status)
424{
425 if (VAL_ERROR(status))
426 {
427 val_print(PRINT_ERROR, "\tCheckpoint %d : ", checkpoint);
428 val_print(PRINT_ERROR, "Error Code=0x%x \n", status);
429 val_set_status(RESULT_FAIL(status));
430 }
431 else
432 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530433 status = (val_get_status() & TEST_STATUS_MASK);
jaypit02ea3cd062018-10-05 12:22:38 +0530434 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 }
439 else
440 {
441 val_print(PRINT_DEBUG, "\tCheckpoint %d \n", checkpoint);
442 }
443 }
444 return status;
445}
446
447/**
448 @brief This API prints the test number, description and
449 sets the test state to TEST_START on successful execution.
450 @param test_num :unique number identifying this test
451 @param desc :brief description of the test
452 @param test_bitfield :Addition test info such as
453 - test isolation level requirement
454 - Watchdog timeout type
455 @return void
456**/
457
458void val_test_init(uint32_t test_num, char8_t *desc, uint32_t test_bitfield)
459{
460 val_status_t status = VAL_STATUS_SUCCESS;
461 miscellaneous_desc_t *misc_desc;
462
463 /*global init*/
cherat013f028722019-02-18 14:50:37 +0530464 g_status_buffer.state = TEST_FAIL;
jaypit02ea3cd062018-10-05 12:22:38 +0530465 g_status_buffer.status = VAL_STATUS_INVALID;
466
467 val_print(PRINT_ALWAYS, "\nTEST: %d | DESCRIPTION: ", test_num);
468 val_print(PRINT_ALWAYS, desc, 0);
469
470 /* common skip logic */
471 status = val_target_get_config(TARGET_CONFIG_CREATE_ID(GROUP_MISCELLANEOUS,
472 MISCELLANEOUS_DUT, 0),
473 (uint8_t **)&misc_desc,
474 (uint32_t *)sizeof(miscellaneous_desc_t));
475 if (VAL_ERROR(status))
476 {
Gowtham Siddarth47223082019-01-17 09:59:50 +0530477 val_print(PRINT_ERROR, "val_target_get_config failed Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530478 return;
479 }
480
481 if (misc_desc->implemented_psa_firmware_isolation_level <
482 GET_TEST_ISOLATION_LEVEL(test_bitfield))
483 {
484 val_set_status(RESULT_SKIP(VAL_STATUS_ISOLATION_LEVEL_NOT_SUPP));
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530485 val_print(PRINT_ALWAYS, "\tSkipping test. Required isolation level is not supported\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530486 return;
487 }
488
Vinay Kumar Kotegowder9982f902019-07-15 09:13:54 +0530489#ifdef WATCHDOG_AVAILABLE
jaypit02ea3cd062018-10-05 12:22:38 +0530490 /* Initialise watchdog */
491 status = val_wd_timer_init(GET_WD_TIMOUT_TYPE(test_bitfield));
492 if (VAL_ERROR(status))
493 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530494 val_print(PRINT_ERROR, "\tval_wd_timer_init failed Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530495 return;
496 }
497
498 /* Enable watchdog Timer */
499 status = val_wd_timer_enable();
500 if (VAL_ERROR(status))
501 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530502 val_print(PRINT_ERROR, "\tval_wd_timer_enable failed Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530503 return;
504 }
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530505#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530506
507 val_set_status(RESULT_START(VAL_STATUS_SUCCESS));
508 return;
509}
510
511/**
512 @brief This API sets the test state to TEST_END if test is successfuly passed.
513 @param none
514 @return none
515**/
516
517void val_test_exit(void)
518{
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530519 val_status_t status = VAL_STATUS_SUCCESS;
jaypit02ea3cd062018-10-05 12:22:38 +0530520
Vinay Kumar Kotegowder9982f902019-07-15 09:13:54 +0530521#ifdef WATCHDOG_AVAILABLE
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530522 status = val_wd_timer_disable();
523 if (VAL_ERROR(status))
524 {
525 val_print(PRINT_ERROR, "\tval_wd_timer_disable failed Error=0x%x\n", status);
526 val_set_status(RESULT_FAIL(status));
527 return;
528 }
529#endif
530
Gowtham Siddarth47223082019-01-17 09:59:50 +0530531 status = val_get_status();
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530532
jaypit02ea3cd062018-10-05 12:22:38 +0530533 /* return if test skipped or failed */
Gowtham Siddarth47223082019-01-17 09:59:50 +0530534 if (IS_TEST_FAIL(status) || IS_TEST_SKIP(status))
jaypit02ea3cd062018-10-05 12:22:38 +0530535 {
Gowtham Siddarth47223082019-01-17 09:59:50 +0530536 return;
jaypit02ea3cd062018-10-05 12:22:38 +0530537 }
Gowtham Siddarth47223082019-01-17 09:59:50 +0530538 else
539 {
540 val_set_status(RESULT_END(VAL_STATUS_SUCCESS));
541 }
jaypit02ea3cd062018-10-05 12:22:38 +0530542}
543
544/**
545 @brief - This function returns the test ID of the last test that was run
546 @param - test_id address
547 @return - val_status_t
548**/
549val_status_t val_get_last_run_test_id(test_id_t *test_id)
550{
551 val_status_t status;
552 test_count_t test_count;
553 boot_t boot;
554 int i = 0, intermediate_boot = 0;
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530555 boot_state_t boot_state[] = {BOOT_NOT_EXPECTED,
556 BOOT_EXPECTED_NS,
557 BOOT_EXPECTED_S,
558 BOOT_EXPECTED_BUT_FAILED,
559 BOOT_EXPECTED_REENTER_TEST
560 };
jaypit02ea3cd062018-10-05 12:22:38 +0530561
562 status = val_get_boot_flag(&boot.state);
563 if (VAL_ERROR(status))
564 {
565 return status;
566 }
567
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530568 val_print(PRINT_INFO, "\n\tboot.state=0x%x", boot.state);
569
jaypit02ea3cd062018-10-05 12:22:38 +0530570 for (i = 0; i < (sizeof(boot_state)/sizeof(boot_state[0])); i++)
571 {
572 if (boot.state == boot_state[i])
573 {
574 intermediate_boot = 1;
575 break;
576 }
577 }
578
579 if (!intermediate_boot)
580 {
581 /* First boot. Initiliase necessary data structure */
582 status = val_set_boot_flag(BOOT_UNKNOWN);
583 if (VAL_ERROR(status))
584 {
585 return status;
586 }
587
588 *test_id = VAL_INVALID_TEST_ID;
589 status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_TEST_ID_PREVIOUS),
590 test_id, sizeof(test_id_t));
591 if (VAL_ERROR(status))
592 {
593 val_print(PRINT_ALWAYS, "\n\tNVMEM write error", 0);
594 return status;
595 }
596
597 test_count.pass_cnt = 0;
598 test_count.fail_cnt = 0;
599 test_count.skip_cnt = 0;
600 test_count.sim_error_cnt = 0;
601
602 status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_TEST_CNT),
603 &test_count, sizeof(test_count_t));
604 if (VAL_ERROR(status))
605 {
606 val_print(PRINT_ERROR, "\n\tNVMEM write error", 0);
607 return status;
608 }
609 }
610
611 status = val_nvmem_read(VAL_NVMEM_OFFSET(NV_TEST_ID_PREVIOUS), test_id, sizeof(test_id_t));
612 if (VAL_ERROR(status))
613 {
614 val_print(PRINT_ERROR, "\n\tNVMEM read error", 0);
615 }
616
617 val_print(PRINT_INFO, "In val_get_last_run_test_id, test_id=%x\n", *test_id);
618 return status;
619}
620
621/**
622 @brief - This function sets the given boot.state value to corresponding
623 boot NVMEM location
624 @param - state: boot_state_t
625 @return - val_status_t
626**/
627val_status_t val_set_boot_flag(boot_state_t state)
628{
629 boot_t boot;
630 val_status_t status;
631
632 boot.state = state;
633 status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_BOOT), &boot, sizeof(boot_t));
634 if (VAL_ERROR(status))
635 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530636 val_print(PRINT_ERROR, "\tval_nvmem_write failed. Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530637 return status;
638 }
639 return status;
640}
641
642/**
643 @brief - This function returns boot.state value available in boot NVMEM location
644 @param - state address
645 @return - val_status_t
646**/
647val_status_t val_get_boot_flag(boot_state_t *state)
648{
649 boot_t boot;
650 val_status_t status;
651
652 status = val_nvmem_read(VAL_NVMEM_OFFSET(NV_BOOT), &boot, sizeof(boot_t));
653 if (VAL_ERROR(status))
654 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530655 val_print(PRINT_ERROR, "\tval_nvmem_read failed. Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530656 return status;
657 }
658 *state = boot.state;
659 return status;
660}