blob: 57cb0b6b3f032e5d9d5d67e7dc2af05090739830 [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
Gowtham Siddarthb8926262019-08-05 12:59:35 +0530114 if (boot.state == BOOT_NOT_EXPECTED || boot.state == BOOT_EXPECTED_REENTER_TEST
115 || boot.state == BOOT_EXPECTED_CONT_TEST_EXEC)
jaypit02ea3cd062018-10-05 12:22:38 +0530116 {
jaypit02ea3cd062018-10-05 12:22:38 +0530117 while (tests_list[i] != NULL)
118 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530119 /*
120 * Reboot have been expected by test in previous ns run,
121 * consider previous run pass and jump to second test function
122 * of the same test if available.
123 */
124 if ((boot.state == BOOT_EXPECTED_REENTER_TEST) && (i == 1))
125 {
126 val_print(PRINT_DEBUG, "[Check1] PASSED\n", 0);
127 i++;
128 continue;
129 }
130
Gowtham Siddarthb8926262019-08-05 12:59:35 +0530131 if (boot.state != BOOT_EXPECTED_CONT_TEST_EXEC)
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530132 {
Gowtham Siddarthb8926262019-08-05 12:59:35 +0530133 status = val_set_boot_flag(BOOT_NOT_EXPECTED);
134 if (VAL_ERROR(status))
135 {
136 return status;
137 }
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530138 }
139
140 if (i == 1)
141 val_print(PRINT_TEST,"[Info] Executing tests from non-secure\n", 0);
142
jaypit02ea3cd062018-10-05 12:22:38 +0530143 if (server_hs == TRUE)
144 {
145 /* Handshake with server tests */
146 test_info.block_num = i;
147 status = val_execute_secure_test_func(&handle, test_info,
148 SERVER_TEST_DISPATCHER_SID);
149 if (VAL_ERROR(status))
150 {
151 val_set_status(RESULT_FAIL(status));
Gowtham Siddarth47223082019-01-17 09:59:50 +0530152 val_print(PRINT_DEBUG,"[Check%d] START\n", i);
jaypit02ea3cd062018-10-05 12:22:38 +0530153 return status;
154 }
155 else
156 {
157 val_print(PRINT_DEBUG,"[Check%d] START\n", i);
158 }
159 }
160
161 /* Execute client tests */
Gowtham Siddarthb1cd50f2019-08-21 11:50:26 +0530162 test_status = tests_list[i](CALLER_NONSECURE);
jaypit02ea3cd062018-10-05 12:22:38 +0530163
164 if (server_hs == TRUE)
165 {
166 /* Retrive Server test status */
167 status = val_get_secure_test_result(&handle);
168 }
169
170 status = test_status ? test_status:status;
Gowtham Siddarth47223082019-01-17 09:59:50 +0530171 if (IS_TEST_SKIP(status))
172 {
173 val_set_status(status);
174 if (server_hs == TRUE)
175 val_print(PRINT_DEBUG, "[Check%d] SKIPPED\n", i);
176 return status;
177 }
178 else if (VAL_ERROR(status))
jaypit02ea3cd062018-10-05 12:22:38 +0530179 {
180 val_set_status(RESULT_FAIL(status));
jaypit02ac23b5b2018-11-02 13:10:19 +0530181 if (server_hs == TRUE)
Gowtham Siddarth47223082019-01-17 09:59:50 +0530182 val_print(PRINT_DEBUG, "[Check%d] FAILED\n", i);
183
jaypit02ea3cd062018-10-05 12:22:38 +0530184 return status;
185 }
186 else
187 {
jaypit02ac23b5b2018-11-02 13:10:19 +0530188 if (server_hs == TRUE)
Gowtham Siddarth47223082019-01-17 09:59:50 +0530189 val_print(PRINT_DEBUG, "[Check%d] PASSED\n", i);
jaypit02ea3cd062018-10-05 12:22:38 +0530190 }
Gowtham Siddarth47223082019-01-17 09:59:50 +0530191
jaypit02ea3cd062018-10-05 12:22:38 +0530192 i++;
193 }
194 }
195 else
196 {
197 /* If we are here means, we are in second run of this test */
198 status = VAL_STATUS_SUCCESS;
199 if (boot.state != BOOT_EXPECTED_S)
200 {
Gowtham Siddarth47223082019-01-17 09:59:50 +0530201 val_print(PRINT_DEBUG, "[Check1] PASSED\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530202 }
203 }
204 return status;
205}
206/**
207 @brief - This function is used to switch to client_partition.c
208 where client tests will be executed to cover secure to secure
209 IPC scenario.
210 @param - test_num : Test_num
211 @return - val_status_t
212**/
213val_status_t val_switch_to_secure_client(uint32_t test_num)
214{
215 val_status_t status = VAL_STATUS_SUCCESS;
216 boot_t boot;
217 psa_handle_t handle;
218 test_info_t test_info;
219
220 test_info.test_num = test_num;
221 test_info.block_num = 1;
222
223 status = val_get_boot_flag(&boot.state);
224 if (VAL_ERROR(status))
225 {
226 goto exit;
227 }
228
229 if (boot.state != BOOT_EXPECTED_S)
230 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530231 /*
232 * Reboot have been expected by test in previous s run,
233 * consider previous run pass and jump to second test function
234 * of the same test if available.
235 */
236 if (boot.state == BOOT_EXPECTED_REENTER_TEST)
237 {
238 test_info.block_num++;
239 val_print(PRINT_DEBUG, "[Check1] PASSED\n", 0);
240 }
241
jaypit02ea3cd062018-10-05 12:22:38 +0530242 status = val_set_boot_flag(BOOT_NOT_EXPECTED);
243 if (VAL_ERROR(status))
244 {
245 goto exit;
246 }
247
248 /* switch to secure client */
249 status = val_execute_secure_test_func(&handle, test_info, CLIENT_TEST_DISPATCHER_SID);
250 if (VAL_ERROR(status))
251 {
252 goto exit;
253 }
254
255 /* Retrive secure client test status */
256 status = val_get_secure_test_result(&handle);
Gowtham Siddarth47223082019-01-17 09:59:50 +0530257 if (IS_TEST_SKIP(status))
258 {
259 val_set_status(status);
260 return status;
261 }
jaypit02ea3cd062018-10-05 12:22:38 +0530262 if (VAL_ERROR(status))
263 {
264 goto exit;
265 }
266 return status;
267 }
268 else
269 {
270 /* If we are here means, we are in third run of this test */
Gowtham Siddarth47223082019-01-17 09:59:50 +0530271 val_print(PRINT_DEBUG, "[Check1] PASSED\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530272 return VAL_STATUS_SUCCESS;
273 }
274
275exit:
276 val_set_status(RESULT_FAIL(status));
277 return status;
278}
279
280/**
281 @brief - This function is used to handshake between:
282 - nonsecure client fn to server test fn
283 - secure client fn and server test fn
284 - nonsecure client fn to secure client test fn
285 @param - handle : handle returned while connecting given sid
286 @param - test_info : Test_num and block_num to be executed
287 @param - sid : RoT service to be connected. Partition dispatcher sid
288 @return - val_status_t
289**/
290val_status_t val_execute_secure_test_func(psa_handle_t *handle, test_info_t test_info, uint32_t sid)
291{
292 uint32_t test_data;
293 val_status_t status = VAL_STATUS_SUCCESS;
294 psa_status_t status_of_call = PSA_SUCCESS;
295
jaypit02ac23b5b2018-11-02 13:10:19 +0530296 *handle = pal_ipc_connect(sid, 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530297 if (*handle < 0)
298 {
299 val_print(PRINT_ERROR, "Could not connect SID. Handle=%x\n", *handle);
300 return VAL_STATUS_CONNECTION_FAILED;
301 }
302
303 test_data = ((uint32_t)(test_info.test_num) |((uint32_t)(test_info.block_num) << BLOCK_NUM_POS)
304 | ((uint32_t)(TEST_EXECUTE_FUNC) << ACTION_POS));
305 psa_invec data[1] = {{&test_data, sizeof(test_data)}};
306
jaypit02ac23b5b2018-11-02 13:10:19 +0530307 status_of_call = pal_ipc_call(*handle, data, 1, NULL, 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530308 if (status_of_call != PSA_SUCCESS)
309 {
310 status = VAL_STATUS_CALL_FAILED;
311 val_print(PRINT_ERROR, "Call to dispatch SF failed. Status=%x\n", status_of_call);
jaypit02ac23b5b2018-11-02 13:10:19 +0530312 pal_ipc_close(*handle);
jaypit02ea3cd062018-10-05 12:22:38 +0530313 }
Gowtham Siddarth47223082019-01-17 09:59:50 +0530314
jaypit02ea3cd062018-10-05 12:22:38 +0530315 return status;
316}
317
318/**
319 @brief - This function is used to retrive the status of previously connected test function
320 using val_execute_secure_test_func
321 @param - handle : handle of server function. Handle of Partition dispatcher sid
322 @return - The status of test functions
323**/
324val_status_t val_get_secure_test_result(psa_handle_t *handle)
325{
326 uint32_t test_data;
327 val_status_t status = VAL_STATUS_SUCCESS;
328 psa_status_t status_of_call = PSA_SUCCESS;
329
330 test_data = (TEST_RETURN_RESULT << ACTION_POS);
331
332 psa_outvec resp = {&status, sizeof(status)};
333 psa_invec data[1] = {{&test_data, sizeof(test_data)}};
334
jaypit02ac23b5b2018-11-02 13:10:19 +0530335 status_of_call = pal_ipc_call(*handle, data, 1, &resp, 1);
jaypit02ea3cd062018-10-05 12:22:38 +0530336 if (status_of_call != PSA_SUCCESS)
337 {
338 status = VAL_STATUS_CALL_FAILED;
339 val_print(PRINT_ERROR, "Call to dispatch SF failed. Status=%x\n", status_of_call);
340 }
341
jaypit02ac23b5b2018-11-02 13:10:19 +0530342 pal_ipc_close(*handle);
jaypit02ea3cd062018-10-05 12:22:38 +0530343 return status;
344}
345
346
347/**
348 @brief - Parses input status for a given test and
349 outputs appropriate information on the console
350 @return - Test state
351**/
352uint32_t val_report_status(void)
353{
354 uint32_t status, state;
355
356 status = val_get_status();
357
358 state = (status >> TEST_STATE_BIT) & TEST_STATE_MASK;
359 status = status & TEST_STATUS_MASK;
360
361 switch (state)
362 {
363 case TEST_START:
364 state = TEST_FAIL;
365 val_print(PRINT_ALWAYS, "TEST RESULT: FAILED (Error Code=0x%x)\n",
366 VAL_STATUS_INIT_FAILED);
367 break;
368
369 case TEST_END:
370 state = TEST_PASS;
371 val_print(PRINT_ALWAYS, "TEST RESULT: PASSED \n", 0);
372 break;
373
374 case TEST_FAIL:
375 val_print(PRINT_ALWAYS, "TEST RESULT: FAILED (Error Code=0x%x) \n", status);
376 break;
377
378 case TEST_SKIP:
Gowtham Siddarth47223082019-01-17 09:59:50 +0530379 state = TEST_SKIP;
jaypit02ea3cd062018-10-05 12:22:38 +0530380 val_print(PRINT_ALWAYS, "TEST RESULT: SKIPPED (Skip Code=0x%x)\n", status);
381 break;
382
383 case TEST_PENDING:
384 val_print(PRINT_ALWAYS, "TEST RESULT: SIM ERROR (Error Code=0x%x)\n", status);
385 break;
386
387 default:
388 state = TEST_FAIL;
389 val_print(PRINT_ALWAYS, "TEST RESULT: FAILED(Error Code=0x%x)\n", VAL_STATUS_INVALID);
390 break;
391
392 }
393
394 val_print(PRINT_ALWAYS, "\n******************************************\n", 0);
395 return state;
396}
397
398/**
399 @brief - Records the state and status of test
400 @return - val_status_t
401**/
402val_status_t val_set_status(uint32_t status)
403{
404 g_status_buffer.state = ((status >> TEST_STATE_BIT) & TEST_STATE_MASK);
405 g_status_buffer.status = (status & TEST_STATUS_MASK);
406
407 return VAL_STATUS_SUCCESS;
408}
409
410/**
411 @brief - Updates the state and status for a given test
412 @return - test status
413**/
414uint32_t val_get_status(void)
415{
416 return ((g_status_buffer.state) << TEST_STATE_BIT) | (g_status_buffer.status);
417}
418
419/*
420 @brief - This function checks if the input status argument is an error.
421 On error, we print the checkpoint value and set the status.
422 @param - checkpoint : Test debug checkpoint
423 - val_status_t : Test status
424 @return - returns the input status back to the program.
425*/
426
427val_status_t val_err_check_set(uint32_t checkpoint, val_status_t status)
428{
429 if (VAL_ERROR(status))
430 {
431 val_print(PRINT_ERROR, "\tCheckpoint %d : ", checkpoint);
432 val_print(PRINT_ERROR, "Error Code=0x%x \n", status);
433 val_set_status(RESULT_FAIL(status));
434 }
435 else
436 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530437 status = (val_get_status() & TEST_STATUS_MASK);
jaypit02ea3cd062018-10-05 12:22:38 +0530438 if (VAL_ERROR(status))
439 {
440 val_print(PRINT_ERROR, "\tCheckpoint %d : ", checkpoint);
441 val_print(PRINT_ERROR, "Error Code=0x%x \n", status);
442 }
443 else
444 {
445 val_print(PRINT_DEBUG, "\tCheckpoint %d \n", checkpoint);
446 }
447 }
448 return status;
449}
450
451/**
452 @brief This API prints the test number, description and
453 sets the test state to TEST_START on successful execution.
454 @param test_num :unique number identifying this test
455 @param desc :brief description of the test
456 @param test_bitfield :Addition test info such as
457 - test isolation level requirement
458 - Watchdog timeout type
459 @return void
460**/
461
462void val_test_init(uint32_t test_num, char8_t *desc, uint32_t test_bitfield)
463{
464 val_status_t status = VAL_STATUS_SUCCESS;
465 miscellaneous_desc_t *misc_desc;
466
467 /*global init*/
cherat013f028722019-02-18 14:50:37 +0530468 g_status_buffer.state = TEST_FAIL;
jaypit02ea3cd062018-10-05 12:22:38 +0530469 g_status_buffer.status = VAL_STATUS_INVALID;
470
471 val_print(PRINT_ALWAYS, "\nTEST: %d | DESCRIPTION: ", test_num);
472 val_print(PRINT_ALWAYS, desc, 0);
473
474 /* common skip logic */
475 status = val_target_get_config(TARGET_CONFIG_CREATE_ID(GROUP_MISCELLANEOUS,
476 MISCELLANEOUS_DUT, 0),
477 (uint8_t **)&misc_desc,
478 (uint32_t *)sizeof(miscellaneous_desc_t));
479 if (VAL_ERROR(status))
480 {
Gowtham Siddarth47223082019-01-17 09:59:50 +0530481 val_print(PRINT_ERROR, "val_target_get_config failed Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530482 return;
483 }
484
485 if (misc_desc->implemented_psa_firmware_isolation_level <
486 GET_TEST_ISOLATION_LEVEL(test_bitfield))
487 {
488 val_set_status(RESULT_SKIP(VAL_STATUS_ISOLATION_LEVEL_NOT_SUPP));
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530489 val_print(PRINT_ALWAYS, "\tSkipping test. Required isolation level is not supported\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530490 return;
491 }
492
Vinay Kumar Kotegowder9982f902019-07-15 09:13:54 +0530493#ifdef WATCHDOG_AVAILABLE
jaypit02ea3cd062018-10-05 12:22:38 +0530494 /* Initialise watchdog */
495 status = val_wd_timer_init(GET_WD_TIMOUT_TYPE(test_bitfield));
496 if (VAL_ERROR(status))
497 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530498 val_print(PRINT_ERROR, "\tval_wd_timer_init failed Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530499 return;
500 }
501
502 /* Enable watchdog Timer */
503 status = val_wd_timer_enable();
504 if (VAL_ERROR(status))
505 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530506 val_print(PRINT_ERROR, "\tval_wd_timer_enable failed Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530507 return;
508 }
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530509#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530510
511 val_set_status(RESULT_START(VAL_STATUS_SUCCESS));
512 return;
513}
514
515/**
516 @brief This API sets the test state to TEST_END if test is successfuly passed.
517 @param none
518 @return none
519**/
520
521void val_test_exit(void)
522{
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530523 val_status_t status = VAL_STATUS_SUCCESS;
jaypit02ea3cd062018-10-05 12:22:38 +0530524
Vinay Kumar Kotegowder9982f902019-07-15 09:13:54 +0530525#ifdef WATCHDOG_AVAILABLE
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530526 status = val_wd_timer_disable();
527 if (VAL_ERROR(status))
528 {
529 val_print(PRINT_ERROR, "\tval_wd_timer_disable failed Error=0x%x\n", status);
530 val_set_status(RESULT_FAIL(status));
531 return;
532 }
533#endif
534
Gowtham Siddarth47223082019-01-17 09:59:50 +0530535 status = val_get_status();
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530536
jaypit02ea3cd062018-10-05 12:22:38 +0530537 /* return if test skipped or failed */
Gowtham Siddarth47223082019-01-17 09:59:50 +0530538 if (IS_TEST_FAIL(status) || IS_TEST_SKIP(status))
jaypit02ea3cd062018-10-05 12:22:38 +0530539 {
Gowtham Siddarth47223082019-01-17 09:59:50 +0530540 return;
jaypit02ea3cd062018-10-05 12:22:38 +0530541 }
Gowtham Siddarth47223082019-01-17 09:59:50 +0530542 else
543 {
544 val_set_status(RESULT_END(VAL_STATUS_SUCCESS));
545 }
jaypit02ea3cd062018-10-05 12:22:38 +0530546}
547
548/**
549 @brief - This function returns the test ID of the last test that was run
550 @param - test_id address
551 @return - val_status_t
552**/
553val_status_t val_get_last_run_test_id(test_id_t *test_id)
554{
555 val_status_t status;
556 test_count_t test_count;
557 boot_t boot;
558 int i = 0, intermediate_boot = 0;
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530559 boot_state_t boot_state[] = {BOOT_NOT_EXPECTED,
560 BOOT_EXPECTED_NS,
561 BOOT_EXPECTED_S,
562 BOOT_EXPECTED_BUT_FAILED,
Gowtham Siddarthb8926262019-08-05 12:59:35 +0530563 BOOT_EXPECTED_REENTER_TEST,
564 BOOT_EXPECTED_CONT_TEST_EXEC
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530565 };
jaypit02ea3cd062018-10-05 12:22:38 +0530566
567 status = val_get_boot_flag(&boot.state);
568 if (VAL_ERROR(status))
569 {
570 return status;
571 }
572
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530573 val_print(PRINT_INFO, "\n\tboot.state=0x%x", boot.state);
574
jaypit02ea3cd062018-10-05 12:22:38 +0530575 for (i = 0; i < (sizeof(boot_state)/sizeof(boot_state[0])); i++)
576 {
577 if (boot.state == boot_state[i])
578 {
579 intermediate_boot = 1;
580 break;
581 }
582 }
583
584 if (!intermediate_boot)
585 {
586 /* First boot. Initiliase necessary data structure */
587 status = val_set_boot_flag(BOOT_UNKNOWN);
588 if (VAL_ERROR(status))
589 {
590 return status;
591 }
592
593 *test_id = VAL_INVALID_TEST_ID;
594 status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_TEST_ID_PREVIOUS),
595 test_id, sizeof(test_id_t));
596 if (VAL_ERROR(status))
597 {
598 val_print(PRINT_ALWAYS, "\n\tNVMEM write error", 0);
599 return status;
600 }
601
602 test_count.pass_cnt = 0;
603 test_count.fail_cnt = 0;
604 test_count.skip_cnt = 0;
605 test_count.sim_error_cnt = 0;
606
607 status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_TEST_CNT),
608 &test_count, sizeof(test_count_t));
609 if (VAL_ERROR(status))
610 {
611 val_print(PRINT_ERROR, "\n\tNVMEM write error", 0);
612 return status;
613 }
614 }
615
616 status = val_nvmem_read(VAL_NVMEM_OFFSET(NV_TEST_ID_PREVIOUS), test_id, sizeof(test_id_t));
617 if (VAL_ERROR(status))
618 {
619 val_print(PRINT_ERROR, "\n\tNVMEM read error", 0);
620 }
621
622 val_print(PRINT_INFO, "In val_get_last_run_test_id, test_id=%x\n", *test_id);
623 return status;
624}
625
626/**
627 @brief - This function sets the given boot.state value to corresponding
628 boot NVMEM location
629 @param - state: boot_state_t
630 @return - val_status_t
631**/
632val_status_t val_set_boot_flag(boot_state_t state)
633{
634 boot_t boot;
635 val_status_t status;
636
637 boot.state = state;
638 status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_BOOT), &boot, sizeof(boot_t));
639 if (VAL_ERROR(status))
640 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530641 val_print(PRINT_ERROR, "\tval_nvmem_write failed. Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530642 return status;
643 }
644 return status;
645}
646
647/**
648 @brief - This function returns boot.state value available in boot NVMEM location
649 @param - state address
650 @return - val_status_t
651**/
652val_status_t val_get_boot_flag(boot_state_t *state)
653{
654 boot_t boot;
655 val_status_t status;
656
657 status = val_nvmem_read(VAL_NVMEM_OFFSET(NV_BOOT), &boot, sizeof(boot_t));
658 if (VAL_ERROR(status))
659 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530660 val_print(PRINT_ERROR, "\tval_nvmem_read failed. Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530661 return status;
662 }
663 *state = boot.state;
664 return status;
665}