blob: f52c34038d64d71c7cf23a43125fa7f7123d93ec [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/* Note- This file contains the functions and variables definition which are common to
jaypit02ac23b5b2018-11-02 13:10:19 +053019 all partitions defined by test suite. These functions and variables are declared with static
jaypit02ea3cd062018-10-05 12:22:38 +053020 keyword because some fully isolated system may not allow to share code and data segment
21 between partitions and static will help each partition to have its own copy of code and data.
22 Moreover it can prevents symbol names conflict if these functions are separately compiled and
23 linked with each of partitions in fully isolated environment.
24*/
25
26#ifndef _VAL_COMMON_SP_APIS_H_
27#define _VAL_COMMON_SP_APIS_H_
28
Gowtham Siddarth47223082019-01-17 09:59:50 +053029#include "val.h"
30#include "val_target.c"
jaypit02ea3cd062018-10-05 12:22:38 +053031#include "val_service_defs.h"
32
jaypit02ea3cd062018-10-05 12:22:38 +053033__UNUSED STATIC_DECLARE val_status_t val_print
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +053034 (print_verbosity_t verbosity, char *string, int32_t data);
jaypit02ea3cd062018-10-05 12:22:38 +053035__UNUSED STATIC_DECLARE val_status_t val_ipc_connect
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +053036 (uint32_t sid, uint32_t version, psa_handle_t *handle );
37__UNUSED STATIC_DECLARE val_status_t val_ipc_call(psa_handle_t handle,
38 int32_t type,
39 const psa_invec *in_vec,
40 size_t in_len,
41 psa_outvec *out_vec,
42 size_t out_len);
jaypit02ea3cd062018-10-05 12:22:38 +053043__UNUSED STATIC_DECLARE void val_ipc_close
44 (psa_handle_t handle);
45__UNUSED STATIC_DECLARE val_status_t val_process_connect_request(psa_signal_t sig, psa_msg_t *msg);
46__UNUSED STATIC_DECLARE val_status_t val_process_call_request(psa_signal_t sig, psa_msg_t *msg);
47__UNUSED STATIC_DECLARE val_status_t val_process_disconnect_request
48 (psa_signal_t sig, psa_msg_t *msg);
49__UNUSED STATIC_DECLARE val_status_t val_execute_secure_tests
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +053050 (test_info_t test_info, client_test_t *tests_list);
jaypit02ea3cd062018-10-05 12:22:38 +053051__UNUSED STATIC_DECLARE val_status_t val_execute_secure_test_func
52 (psa_handle_t *handle, test_info_t test_info, uint32_t sid);
53__UNUSED STATIC_DECLARE val_status_t val_get_secure_test_result(psa_handle_t *handle);
54__UNUSED STATIC_DECLARE val_status_t val_err_check_set(uint32_t checkpoint, val_status_t status);
55__UNUSED STATIC_DECLARE val_status_t val_nvmem_write(uint32_t offset, void *buffer, int size);
56__UNUSED STATIC_DECLARE val_status_t val_set_boot_flag(boot_state_t state);
57
58__UNUSED static val_api_t val_api = {
59 .print = val_print,
60 .err_check_set = val_err_check_set,
61 .execute_secure_test_func = val_execute_secure_test_func,
62 .get_secure_test_result = val_get_secure_test_result,
63 .ipc_connect = val_ipc_connect,
64 .ipc_call = val_ipc_call,
65 .ipc_close = val_ipc_close,
66 .set_boot_flag = val_set_boot_flag,
jaypit02ac23b5b2018-11-02 13:10:19 +053067 .target_get_config = val_target_get_config,
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +053068 .process_connect_request = val_process_connect_request,
69 .process_call_request = val_process_call_request,
70 .process_disconnect_request= val_process_disconnect_request,
jaypit02ea3cd062018-10-05 12:22:38 +053071};
72
73__UNUSED static psa_api_t psa_api = {
74 .framework_version = psa_framework_version,
75 .version = psa_version,
76 .connect = psa_connect,
77 .call = psa_call,
78 .close = psa_close,
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +053079 .wait = psa_wait,
80 .set_rhandle = psa_set_rhandle,
81 .get = psa_get,
82 .read = psa_read,
83 .skip = psa_skip,
84 .write = psa_write,
85 .reply = psa_reply,
86 .notify = psa_notify,
87 .clear = psa_clear,
88 .eoi = psa_eoi,
89 .rot_lifecycle_state = psa_rot_lifecycle_state,
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +053090 .panic = psa_panic,
jaypit02ea3cd062018-10-05 12:22:38 +053091};
92
93/**
94 @brief - Print module. This is client interface API of secure partition
95 val_print_sf API for spe world
96 @param - verbosity: Print verbosity level
97 - string : Input string
98 - data : Value for format specifier
99 @return - val_status_t
100**/
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530101STATIC_DECLARE val_status_t val_print(print_verbosity_t verbosity, char *string, int32_t data)
jaypit02ea3cd062018-10-05 12:22:38 +0530102{
103 int string_len = 0;
104 char *p = string;
jk-arm957cfea2021-06-18 15:52:12 +0530105
jaypit02ea3cd062018-10-05 12:22:38 +0530106 psa_status_t status_of_call = PSA_SUCCESS;
107 val_status_t status = VAL_STATUS_SUCCESS;
jaypit02ac23b5b2018-11-02 13:10:19 +0530108 uart_fn_type_t uart_fn = UART_PRINT;
109
110 if (verbosity < VERBOSE)
111 {
112 return VAL_STATUS_SUCCESS;
113 }
jaypit02ea3cd062018-10-05 12:22:38 +0530114
115 while (*p != '\0')
116 {
117 string_len++;
118 p++;
119 }
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530120 psa_invec data1[3] = {{&uart_fn, sizeof(uart_fn)}, {string, string_len+1}, {&data, sizeof(data)}};
jk-arm957cfea2021-06-18 15:52:12 +0530121#if STATELESS_ROT == 1
122
123 status_of_call = psa_call(DRIVER_UART_HANDLE, 0, data1, 3, NULL, 0);
124 if (status_of_call != PSA_SUCCESS)
125 {
126 status = VAL_STATUS_CALL_FAILED;
127 }
128 return status;
129#else
130 psa_handle_t print_handle = 0;
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530131 print_handle = psa_connect(DRIVER_UART_SID, DRIVER_UART_VERSION);
jaypit02ea3cd062018-10-05 12:22:38 +0530132
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530133 if (PSA_HANDLE_IS_VALID(print_handle))
jaypit02ea3cd062018-10-05 12:22:38 +0530134 {
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530135 status_of_call = psa_call(print_handle, 0, data1, 3, NULL, 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530136 if (status_of_call != PSA_SUCCESS)
137 {
138 status = VAL_STATUS_CALL_FAILED;
139 }
140 }
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530141 else
142 {
143 return VAL_STATUS_CONNECTION_FAILED;
144 }
jaypit02ea3cd062018-10-05 12:22:38 +0530145 psa_close(print_handle);
146 return status;
jk-arm957cfea2021-06-18 15:52:12 +0530147#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530148}
149
150/**
151 * @brief Connect to given sid
152 @param -sid : RoT service id
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530153 @param -version : version of RoT service
jaypit02ea3cd062018-10-05 12:22:38 +0530154 @param -handle - return connection handle
155 * @return val_status_t
156 */
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530157STATIC_DECLARE val_status_t val_ipc_connect(uint32_t sid, uint32_t version,
jaypit02ea3cd062018-10-05 12:22:38 +0530158 psa_handle_t *handle )
159{
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530160 *handle = psa_connect(sid, version);
jaypit02ea3cd062018-10-05 12:22:38 +0530161
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530162 if (PSA_HANDLE_IS_VALID(*handle))
163 return VAL_STATUS_SUCCESS;
jaypit02ea3cd062018-10-05 12:22:38 +0530164
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530165 return VAL_STATUS_CONNECTION_FAILED;
jaypit02ea3cd062018-10-05 12:22:38 +0530166}
167
168/**
169 * @brief Call a connected Root of Trust Service.@n
170 * The caller must provide an array of ::psa_invec_t structures as the input payload.
171 * @param handle: Handle for the connection.
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530172 * @param type: Request type.
jaypit02ea3cd062018-10-05 12:22:38 +0530173 * @param in_vec: Array of psa_invec structures.
174 * @param in_len: Number of psa_invec structures in in_vec.
175 * @param out_vec: Array of psa_outvec structures for optional Root of Trust Service response.
176 * @param out_len: Number of psa_outvec structures in out_vec.
177 * @return val_status_t
178 */
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530179STATIC_DECLARE val_status_t val_ipc_call(psa_handle_t handle,
180 int32_t type,
181 const psa_invec *in_vec,
182 size_t in_len,
183 psa_outvec *out_vec,
184 size_t out_len)
jaypit02ea3cd062018-10-05 12:22:38 +0530185{
186 psa_status_t call_status = PSA_SUCCESS;
187
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530188 call_status = psa_call(handle, type, in_vec, in_len, out_vec, out_len);
jaypit02ea3cd062018-10-05 12:22:38 +0530189
190 if (call_status != PSA_SUCCESS)
191 {
192 return(VAL_STATUS_CALL_FAILED);
193 }
194
195 return VAL_STATUS_SUCCESS;
196}
197
198/**
199 * @brief Close a connection to a Root of Trust Service.
200 * Sends the PSA_IPC_DISCONNECT message to the Root of Trust Service so
201 it can clean up resources.
202 * @param handle: Handle for the connection.
203 * @return void
204 */
205STATIC_DECLARE void val_ipc_close(psa_handle_t handle)
206{
207 psa_close(handle);
208}
209
210/**
211 * @brief Proccess a generic connect message to given rot signal.
212 @param -sig : signal to be processed
213 @param -msg : return msg info of given signal
214 * @return val_status_t.
215 */
216STATIC_DECLARE val_status_t val_process_connect_request(psa_signal_t sig, psa_msg_t *msg)
217{
218 val_status_t res = VAL_STATUS_ERROR;
219 psa_signal_t signals;
220
221wait1:
jaypit02ac23b5b2018-11-02 13:10:19 +0530222 signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
jaypit02ea3cd062018-10-05 12:22:38 +0530223 if (signals & sig)
224 {
225 if (psa_get(sig, msg) != PSA_SUCCESS)
226 {
227 goto wait1;
228 }
229
230 if ((msg->type != PSA_IPC_CONNECT) || (msg->handle <= 0))
231 {
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530232 val_print(PRINT_ERROR, "\tpsa_get failed for connect message\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530233 res = VAL_STATUS_ERROR;
234 }
235 else
236 {
237 res = VAL_STATUS_SUCCESS;
238 }
239 }
240 else
241 {
Gowtham Siddarth47223082019-01-17 09:59:50 +0530242 val_print(PRINT_ERROR, "\tpsa_wait returned with invalid signal value = 0x%x\n", signals);
jaypit02ea3cd062018-10-05 12:22:38 +0530243 res = VAL_STATUS_ERROR;
244 }
245 return res;
246}
247
248/**
249 * @brief Proccess a generic call message to given rot signal.
250 @param -sig : signal to be processed
251 @param -msg : return msg info of given signal
252 * @return val_status_t
253 */
254STATIC_DECLARE val_status_t val_process_call_request(psa_signal_t sig, psa_msg_t *msg)
255{
256 val_status_t res = VAL_STATUS_ERROR;
257 psa_signal_t signals;
258
259wait2:
jaypit02ac23b5b2018-11-02 13:10:19 +0530260 signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
jaypit02ea3cd062018-10-05 12:22:38 +0530261 if (signals & sig)
262 {
263 if (psa_get(sig, msg) != PSA_SUCCESS)
264 {
265 goto wait2;
266 }
267
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530268 if ((msg->type < PSA_IPC_CALL) || (msg->handle <= 0))
jaypit02ea3cd062018-10-05 12:22:38 +0530269 {
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530270 val_print(PRINT_ERROR, "\tpsa_get failed for request message\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530271 res = VAL_STATUS_ERROR;
272 }
273 else
274 {
275 res = VAL_STATUS_SUCCESS;
276 }
277 }
278 else
279 {
Gowtham Siddarth47223082019-01-17 09:59:50 +0530280 val_print(PRINT_ERROR, "\tpsa_wait returned with invalid signal value = 0x%x\n", signals);
jaypit02ea3cd062018-10-05 12:22:38 +0530281 res = VAL_STATUS_ERROR;
282 }
283 return res;
284}
285
286/**
287 * @brief Proccess a generic disconnect message to given rot signal.
288 @param -sig : signal to be processed
289 @param -msg : return msg info of given signal
290 * @return val_status_t
291 */
292STATIC_DECLARE val_status_t val_process_disconnect_request(psa_signal_t sig, psa_msg_t *msg)
293{
294 val_status_t res = VAL_STATUS_ERROR;
295 psa_signal_t signals;
296
297wait3:
jaypit02ac23b5b2018-11-02 13:10:19 +0530298 signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
jaypit02ea3cd062018-10-05 12:22:38 +0530299 if (signals & sig)
300 {
301 if (psa_get(sig, msg) != PSA_SUCCESS)
302 {
303 goto wait3;
304 }
305
306 if ((msg->type != PSA_IPC_DISCONNECT) || (msg->handle <= 0))
307 {
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530308 val_print(PRINT_ERROR, "\tpsa_get failed for disconnect massage\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530309 res = VAL_STATUS_ERROR;
310 }
311 else
312 {
313 res = VAL_STATUS_SUCCESS;
314 }
315 }
316 else
317 {
Gowtham Siddarth47223082019-01-17 09:59:50 +0530318 val_print(PRINT_ERROR, "\tpsa_wait returned with invalid signal value = 0x%x\n", signals);
jaypit02ea3cd062018-10-05 12:22:38 +0530319 res = VAL_STATUS_ERROR;
320 }
321 return res;
322}
323
324/**
325 @brief - This function executes given list of tests from secure sequentially
326 This covers secure to secure IPC API scenario
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530327 @param - test_info_t : test_num and block_num
jaypit02ea3cd062018-10-05 12:22:38 +0530328 @param - tests_list : list of tests to be executed
329 @return - val_status_t
330**/
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530331STATIC_DECLARE val_status_t val_execute_secure_tests(test_info_t test_info, client_test_t *tests_list)
jaypit02ea3cd062018-10-05 12:22:38 +0530332{
333 val_status_t status = VAL_STATUS_SUCCESS;
334 val_status_t test_status = VAL_STATUS_SUCCESS;
335 psa_handle_t handle;
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530336 int i = test_info.block_num;
jaypit02ea3cd062018-10-05 12:22:38 +0530337
338 while (tests_list[i] != NULL)
339 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530340 if (i == 1)
341 val_print(PRINT_TEST, "[Info] Executing tests from secure\n", 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530342
343 /* Handshake with server tests */
344 test_info.block_num = i;
jk-arm957cfea2021-06-18 15:52:12 +0530345#if STATELESS_ROT == 1
346 status = val_execute_secure_test_func(&handle, test_info, SERVER_TEST_DISPATCHER_HANDLE);
347 handle = (int32_t)SERVER_TEST_DISPATCHER_HANDLE;
348#else
jaypit02ea3cd062018-10-05 12:22:38 +0530349 status = val_execute_secure_test_func(&handle, test_info, SERVER_TEST_DISPATCHER_SID);
jk-arm957cfea2021-06-18 15:52:12 +0530350#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530351 if (VAL_ERROR(status))
352 {
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530353 val_print(PRINT_ERROR, "[Check %d] START\n", i);
jaypit02ea3cd062018-10-05 12:22:38 +0530354 return status;
355 }
356 else
357 {
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530358 val_print(PRINT_DEBUG, "[Check %d] START\n", i);
jaypit02ea3cd062018-10-05 12:22:38 +0530359 }
360
361 /* Execute client tests */
Gowtham Siddarthb1cd50f2019-08-21 11:50:26 +0530362 test_status = tests_list[i](CALLER_SECURE);
jaypit02ea3cd062018-10-05 12:22:38 +0530363
364 /* Retrive Server test status */
365 status = val_get_secure_test_result(&handle);
366
367 status = test_status ? test_status:status;
Gowtham Siddarth47223082019-01-17 09:59:50 +0530368 if (IS_TEST_SKIP(status))
369 {
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530370 val_print(PRINT_DEBUG, "[Check %d] SKIPPED\n", i);
Gowtham Siddarth47223082019-01-17 09:59:50 +0530371 return status;
372 }
jaypit02ea3cd062018-10-05 12:22:38 +0530373 if (VAL_ERROR(status))
374 {
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530375 val_print(PRINT_DEBUG, "[Check %d] FAILED\n", i);
jaypit02ea3cd062018-10-05 12:22:38 +0530376 return status;
377 }
378 else
379 {
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530380 val_print(PRINT_DEBUG, "[Check %d] PASSED\n", i);
jaypit02ea3cd062018-10-05 12:22:38 +0530381 }
382 i++;
383 }
384 return status;
385}
386
387/**
388 @brief - This function is used to handshake between:
389 - nonsecure client to server test fn
390 - secure client and server test fn
391 - nonsecure client to secure client test fn
392 @param - handle : handle returned while connecting given sid
393 @param - test_info : Test_num and block_num to be executed
394 @param - sid : RoT service to be connected. Partition dispatcher sid
395 @return - val_status_t
396**/
jk-arm957cfea2021-06-18 15:52:12 +0530397STATIC_DECLARE val_status_t val_execute_secure_test_func
398 (__attribute__((unused)) psa_handle_t *handle, test_info_t test_info, uint32_t sid)
jaypit02ea3cd062018-10-05 12:22:38 +0530399{
400 uint32_t test_data;
401 val_status_t status = VAL_STATUS_SUCCESS;
402 psa_status_t status_of_call = PSA_SUCCESS;
jk-arm957cfea2021-06-18 15:52:12 +0530403#if STATELESS_ROT == 1
404 test_data = ((uint32_t)(test_info.test_num) | ((uint32_t)(test_info.block_num) << BLOCK_NUM_POS)
405 | ((uint32_t)(TEST_EXECUTE_FUNC) << ACTION_POS));
406 psa_invec data[1] = { {&test_data, sizeof(test_data)} };
jaypit02ea3cd062018-10-05 12:22:38 +0530407
jk-arm957cfea2021-06-18 15:52:12 +0530408 status_of_call = psa_call(sid, 0, data, 1, NULL, 0);
409
410 if (status_of_call != PSA_SUCCESS)
411 {
412 status = VAL_STATUS_CALL_FAILED;
413 val_print(PRINT_ERROR, "Call to dispatch SF failed. Status=%x\n", status_of_call);
414 }
415 return status;
416#else
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530417 *handle = psa_connect(sid, 1);
jaypit02ea3cd062018-10-05 12:22:38 +0530418
419 if (*handle < 0)
420 {
421 val_print(PRINT_ERROR, "Could not connect SID. Handle=%x\n", *handle);
422 status = VAL_STATUS_CONNECTION_FAILED;
423 }
424
425 test_data = ((uint32_t)(test_info.test_num) | ((uint32_t)(test_info.block_num) << BLOCK_NUM_POS)
426 | ((uint32_t)(TEST_EXECUTE_FUNC) << ACTION_POS));
427 psa_invec data[1] = {{&test_data, sizeof(test_data)}};
428
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530429 status_of_call = psa_call(*handle, 0, data, 1, NULL, 0);
jaypit02ea3cd062018-10-05 12:22:38 +0530430
431 if (status_of_call != PSA_SUCCESS)
432 {
433 status = VAL_STATUS_CALL_FAILED;
434 val_print(PRINT_ERROR, "Call to dispatch SF failed. Status=%x\n", status_of_call);
435 psa_close(*handle);
436 }
437 return status;
jk-arm957cfea2021-06-18 15:52:12 +0530438#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530439}
440
441/**
442 @brief - This function is used to retrive the status of previously connected test function
443 using val_execute_secure_test_func
444 @param - handle : handle of server function. Handle of Partition dispatcher sid
445 @return - The status of test functions
446**/
447STATIC_DECLARE val_status_t val_get_secure_test_result(psa_handle_t *handle)
448{
449 uint32_t test_data;
450 val_status_t status = VAL_STATUS_SUCCESS;
451 psa_status_t status_of_call = PSA_SUCCESS;
452
453 test_data = (TEST_RETURN_RESULT << ACTION_POS);
454
455 psa_outvec resp = {&status, sizeof(status)};
456 psa_invec data[1] = {{&test_data, sizeof(test_data)}};
457
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530458 status_of_call = psa_call(*handle, 0, data, 1, &resp, 1);
jaypit02ea3cd062018-10-05 12:22:38 +0530459 if (status_of_call != PSA_SUCCESS)
460 {
461 status = VAL_STATUS_CALL_FAILED;
462 val_print(PRINT_ERROR, "Call to dispatch SF failed. Status=%x\n", status_of_call);
463 }
jk-arm957cfea2021-06-18 15:52:12 +0530464#if STATELESS_ROT != 1
jaypit02ea3cd062018-10-05 12:22:38 +0530465 psa_close(*handle);
jk-arm957cfea2021-06-18 15:52:12 +0530466#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530467 return status;
468}
469
470/*
471 @brief - This function checks if the input status argument is an error.
472 On error, print the checkpoint value
473 @param - checkpoint : Test debug checkpoint
474 - val_status_t : Test status
475 @return - returns the input status back to the program.
476*/
477STATIC_DECLARE val_status_t val_err_check_set(uint32_t checkpoint, val_status_t status)
478{
479 if (VAL_ERROR(status))
480 {
481 val_print(PRINT_ERROR, "\tCheckpoint %d : ", checkpoint);
482 val_print(PRINT_ERROR, "Error Code=0x%x \n", status);
483 }
484 else
485 {
486 val_print(PRINT_DEBUG, "\tCheckpoint %d \n", checkpoint);
487 }
488 return status;
489}
490
491/*
492 @brief - Writes 'size' bytes from buffer into non-volatile memory at a given
493 'base + offset'. This is client interface API of secure partition
494 val_nvmem_write_sf API for spe world
495 - offset : Offset
496 - buffer : Pointer to source address
497 - size : Number of bytes
498 @return - val_status_t
499*/
500STATIC_DECLARE val_status_t val_nvmem_write(uint32_t offset, void *buffer, int size)
501{
jaypit02ac23b5b2018-11-02 13:10:19 +0530502 nvmem_param_t nvmem_param;
jk-arm957cfea2021-06-18 15:52:12 +0530503
jaypit02ac23b5b2018-11-02 13:10:19 +0530504 psa_status_t status_of_call = PSA_SUCCESS;
505 val_status_t status = VAL_STATUS_SUCCESS;
506 memory_desc_t *memory_desc;
jaypit02ea3cd062018-10-05 12:22:38 +0530507
jaypit02ac23b5b2018-11-02 13:10:19 +0530508 status = val_target_get_config(TARGET_CONFIG_CREATE_ID(GROUP_MEMORY, MEMORY_NVMEM, 0),
509 (uint8_t **)&memory_desc,
510 (uint32_t *)sizeof(memory_desc_t));
jaypit02ea3cd062018-10-05 12:22:38 +0530511
jaypit02ac23b5b2018-11-02 13:10:19 +0530512 if (VAL_ERROR(status))
513 {
514 return status;
515 }
516
517 nvmem_param.nvmem_fn_type = NVMEM_WRITE;
518 nvmem_param.base = memory_desc->start;
519 nvmem_param.offset = offset;
520 nvmem_param.size = size;
521 psa_invec invec[2] = {{&nvmem_param, sizeof(nvmem_param)}, {buffer, size}};
522
jk-arm957cfea2021-06-18 15:52:12 +0530523#if STATELESS_ROT == 1
524 status_of_call = psa_call(DRIVER_NVMEM_HANDLE, 0, invec, 2, NULL, 0);
525 if (status_of_call != PSA_SUCCESS)
526 {
527 return VAL_STATUS_CALL_FAILED;
528 }
529 return VAL_STATUS_SUCCESS;
530
531#else
532 psa_handle_t handle = 0;
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530533 handle = psa_connect(DRIVER_NVMEM_SID, DRIVER_NVMEM_VERSION);
534 if (PSA_HANDLE_IS_VALID(handle))
jaypit02ac23b5b2018-11-02 13:10:19 +0530535 {
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530536 status_of_call = psa_call(handle, 0, invec, 2, NULL, 0);
jaypit02ac23b5b2018-11-02 13:10:19 +0530537 if (status_of_call != PSA_SUCCESS)
538 {
539 psa_close(handle);
540 return VAL_STATUS_CALL_FAILED;
541 }
542 }
Jaykumar Pitambarbhai Patelccf5bf22019-12-06 11:58:32 +0530543 else
544 {
545 return VAL_STATUS_CONNECTION_FAILED;
546 }
jaypit02ea3cd062018-10-05 12:22:38 +0530547 psa_close(handle);
548 return VAL_STATUS_SUCCESS;
jk-arm957cfea2021-06-18 15:52:12 +0530549#endif
jaypit02ea3cd062018-10-05 12:22:38 +0530550}
551
552/**
553 @brief - This function sets the given boot.state value to corresponding
554 boot NVMEM location
555 @param - state: boot_state_t
556 @return - val_status_t
557**/
558STATIC_DECLARE val_status_t val_set_boot_flag(boot_state_t state)
559{
560 boot_t boot;
561 val_status_t status;
562
563 boot.state = state;
564 status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_BOOT), &boot, sizeof(boot_t));
565 if (VAL_ERROR(status))
566 {
Jaykumar Pitambarbhai Patelf97bc882019-06-03 11:57:48 +0530567 val_print(PRINT_ERROR, "\tval_nvmem_write failed Error=0x%x\n", status);
jaypit02ea3cd062018-10-05 12:22:38 +0530568 return status;
569 }
570 return status;
571}
572#endif