Support for PSA Firmware Framework Test Suite. (#14)
- PSA IPC tests
- PSA Crypto tests
Signed-off-by: Jaykumar Pitambarbhai Patel <jaykumar.pitambarbhaipatel@arm.com>
diff --git a/psa-ff/val/common/val.h b/psa-ff/val/common/val.h
new file mode 100644
index 0000000..b3e66f1
--- /dev/null
+++ b/psa-ff/val/common/val.h
@@ -0,0 +1,258 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#ifndef _VAL_COMMON_H_
+#define _VAL_COMMON_H_
+
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/* typedef's */
+typedef uint8_t bool_t;
+typedef uint32_t addr_t;
+typedef uint32_t test_id_t;
+typedef uint32_t block_id_t;
+typedef char char8_t;
+typedef uint32_t cfg_id_t;
+
+
+#ifndef VAL_NSPE_BUILD
+#define STATIC_DECLARE static
+#else
+#define STATIC_DECLARE
+#endif
+
+#ifndef __WEAK
+#define __WEAK __attribute__((weak))
+#endif
+
+#ifndef __UNUSED
+#define __UNUSED __attribute__((unused))
+#endif
+
+#ifndef TRUE
+#define TRUE 0
+#endif
+#ifndef FALSE
+#define FALSE 1
+#endif
+
+/* test status defines */
+#define TEST_START 0x01
+#define TEST_END 0x02
+#define TEST_PASS 0x04
+#define TEST_FAIL 0x08
+#define TEST_SKIP 0x10
+#define TEST_PENDING 0x20
+
+#define TEST_NUM_BIT 32
+#define TEST_STATE_BIT 8
+#define TEST_STATUS_BIT 0
+
+#define TEST_NUM_MASK 0xFFFFFFFF
+#define TEST_STATE_MASK 0xFF
+#define TEST_STATUS_MASK 0xFF
+
+#define RESULT_START(status) (((TEST_START) << TEST_STATE_BIT) | ((status) << TEST_STATUS_BIT))
+#define RESULT_END(status) (((TEST_END) << TEST_STATE_BIT) | ((status) << TEST_STATUS_BIT))
+#define RESULT_PASS(status) (((TEST_PASS) << TEST_STATE_BIT) | ((status) << TEST_STATUS_BIT))
+#define RESULT_FAIL(status) (((TEST_FAIL) << TEST_STATE_BIT) | ((status) << TEST_STATUS_BIT))
+#define RESULT_SKIP(status) (((TEST_SKIP) << TEST_STATE_BIT) | ((status) << TEST_STATUS_BIT))
+#define RESULT_PENDING(status) (((TEST_PENDING) << TEST_STATE_BIT) | ((status) << TEST_STATUS_BIT))
+
+#define IS_TEST_FAIL(status) (((status >> TEST_STATE_BIT) & TEST_STATE_MASK) == TEST_FAIL)
+#define IS_TEST_PASS(status) (((status >> TEST_STATE_BIT) & TEST_STATE_MASK) == TEST_PASS)
+#define IS_TEST_SKIP(status) (((status >> TEST_STATE_BIT) & TEST_STATE_MASK) == TEST_SKIP)
+#define IS_TEST_PENDING(status) (((status >> TEST_STATE_BIT) & TEST_STATE_MASK) == TEST_PENDING)
+#define IS_TEST_START(status) (((status >> TEST_STATE_BIT) & TEST_STATE_MASK) == TEST_START)
+#define IS_TEST_END(status) (((status >> TEST_STATE_BIT) & TEST_STATE_MASK) == TEST_END)
+#define VAL_ERROR(status) (status?1:0)
+
+
+
+/* Test Defines */
+#define TEST_PUBLISH(test_id, entry) \
+ const val_test_info_t __attribute__((section(".acs_test_info"))) acs_test_info = {test_id, entry}
+
+#define VAL_MAX_TEST_PER_COMP 200
+#define VAL_FF_BASE 0
+#define VAL_CRYPTO_BASE 1
+#define VAL_GET_COMP_NUM(test_id) \
+ ((test_id - (test_id % VAL_MAX_TEST_PER_COMP)) / VAL_MAX_TEST_PER_COMP)
+#define VAL_GET_TEST_NUM(test_id) (test_id % VAL_MAX_TEST_PER_COMP)
+#define VAL_CREATE_TEST_ID(comp,num) ((comp*VAL_MAX_TEST_PER_COMP) + num)
+
+#define TEST_FIELD(num1,num2) (num2 << 8 | num1)
+#define GET_TEST_ISOLATION_LEVEL(num) (num & 0x3)
+#define GET_WD_TIMOUT_TYPE(num) ((num >> 8) & 0x3)
+
+#define TEST_CHECKPOINT_NUM(n) n
+#define TEST(n) n
+#define BLOCK(n) n
+
+#define BLOCK_NUM_POS 8
+#define ACTION_POS 16
+#define GET_TEST_NUM(n) (0xff & n)
+#define GET_BLOCK_NUM(n) ((n >> BLOCK_NUM_POS) & 0xff)
+
+#define GET_ACTION_NUM(n) ((n >> ACTION_POS) & 0xff)
+#define TEST_EXECUTE_FUNC 1
+#define TEST_RETURN_RESULT 2
+#define INVALID_HANDLE 0x1234DEAD
+
+#define VAL_NVMEM_BLOCK_SIZE 4
+#define VAL_NVMEM_OFFSET(nvmem_idx) (nvmem_idx * VAL_NVMEM_BLOCK_SIZE)
+
+#define UART_INIT_SIGN 0xff
+
+/* enums */
+typedef enum {
+ NONSECURE = 0x0,
+ SECURE = 0x1,
+} security_t;
+
+typedef enum {
+ TEST_ISOLATION_L1 = 0x1,
+ TEST_ISOLATION_L2 = 0x2,
+ TEST_ISOLATION_L3 = 0x3,
+} test_isolation_level_t;
+
+typedef enum {
+ BOOT_UNKNOWN = 0x1,
+ BOOT_NOT_EXPECTED = 0x2,
+ BOOT_EXPECTED_NS = 0x3,
+ BOOT_EXPECTED_S = 0x4,
+ BOOT_EXPECTED_BUT_FAILED = 0x5,
+ BOOT_EXPECTED_CRYPTO = 0x6,
+} boot_state_t;
+
+typedef enum {
+ NV_BOOT = 0x0,
+ NV_TEST_ID_PREVIOUS = 0x1,
+ NV_TEST_ID_CURRENT = 0x2,
+ NV_TEST_CNT = 0x3,
+} nvmem_index_t;
+
+typedef enum {
+ WD_INIT_SEQ = 0x1,
+ WD_ENABLE_SEQ = 0x2,
+ WD_DISABLE_SEQ = 0x3,
+ WD_STATUS_SEQ = 0x4,
+} wd_fn_type_t;
+
+typedef enum {
+ WD_LOW_TIMEOUT = 0x1,
+ WD_MEDIUM_TIMEOUT = 0x2,
+ WD_HIGH_TIMEOUT = 0x3,
+} wd_timeout_type_t;
+
+typedef enum {
+ NVMEM_READ = 0x1,
+ NVMEM_WRITE = 0x2,
+} nvmem_fn_type_t;
+
+/* enums to report test sub-state */
+typedef enum {
+ VAL_STATUS_SUCCESS = 0x0,
+ VAL_STATUS_INVALID = 0x10,
+ VAL_STATUS_ERROR = 0x11,
+ VAL_STATUS_NOT_FOUND = 0x12,
+ VAL_STATUS_LOAD_ERROR = 0x13,
+ VAL_STATUS_INSUFFICIENT_SIZE = 0x14,
+ VAL_STATUS_CONNECTION_FAILED = 0x15,
+ VAL_STATUS_CALL_FAILED = 0x16,
+ VAL_STATUS_READ_FAILED = 0x17,
+ VAL_STATUS_WRITE_FAILED = 0x18,
+ VAL_STATUS_ISOLATION_LEVEL_NOT_SUPP = 0x19,
+ VAL_STATUS_INIT_FAILED = 0x1A,
+ VAL_STATUS_SPM_FAILED = 0x1B,
+ VAL_STATUS_SPM_UNEXPECTED_BEH = 0x1C,
+ VAL_STATUS_FRAMEWORK_VERSION_FAILED = 0x1D,
+ VAL_STATUS_VERSION_API_FAILED = 0x1E,
+ VAL_STATUS_INVALID_HANDLE = 0x1F,
+ VAL_STATUS_INVALID_MSG_TYPE = 0x20,
+ VAL_STATUS_WRONG_IDENTITY = 0x21,
+ VAL_STATUS_MSG_INSIZE_FAILED = 0x22,
+ VAL_STATUS_MSG_OUTSIZE_FAILED = 0x23,
+ VAL_STATUS_SKIP_FAILED = 0x24,
+ VAL_STATUS_CRYPTO_FAILURE = 0x25,
+ VAL_STATUS_INVALID_SIZE = 0x26,
+ VAL_STATUS_DATA_MISMATCH = 0x27,
+ VAL_STATUS_BOOT_EXPECTED_BUT_FAILED = 0x28,
+} val_status_t;
+
+/* verbosity enums */
+typedef enum {
+ PRINT_INFO = 1,
+ PRINT_DEBUG = 2,
+ PRINT_TEST = 3,
+ PRINT_WARN = 4,
+ PRINT_ERROR = 5,
+ PRINT_ALWAYS = 9
+} print_verbosity_t;
+
+/* typedef's */
+typedef struct {
+ boot_state_t state;
+} boot_t;
+
+typedef struct {
+ uint32_t pass_cnt:8;
+ uint32_t skip_cnt:8;
+ uint32_t fail_cnt:8;
+ uint32_t sim_error_cnt:8;
+} test_count_t;
+
+typedef struct {
+ wd_fn_type_t wd_fn_type;
+ wd_timeout_type_t wd_timeout_type;
+} wd_param_t;
+
+typedef struct {
+ nvmem_fn_type_t nvmem_fn_type;
+ uint32_t offset;
+ int size;
+} nvmem_param_t;
+
+typedef struct {
+ addr_t wd_base_addr;
+ uint32_t wd_time_us_low;
+ uint32_t wd_time_us_medium;
+ uint32_t wd_time_us_high;
+ uint32_t wd_timer_tick_us;
+ addr_t nvmem_base_addr;
+ addr_t uart_base_addr;
+} target_param_t;
+
+
+typedef struct {
+ uint16_t test_num;
+ uint8_t block_num;
+} test_info_t;
+
+
+/* struture to capture test state */
+typedef struct {
+ uint16_t reserved;
+ uint8_t state;
+ uint8_t status;
+} test_status_buffer_t;
+
+typedef int32_t (*client_test_t)(security_t caller);
+typedef int32_t (*server_test_t)(void);
+#endif /* VAL_COMMON_H */
diff --git a/psa-ff/val/common/val_client_defs.h b/psa-ff/val/common/val_client_defs.h
new file mode 100644
index 0000000..c18d8a7
--- /dev/null
+++ b/psa-ff/val/common/val_client_defs.h
@@ -0,0 +1,81 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#ifndef _VAL_CLIENT_H_
+#define _VAL_CLIENT_H_
+
+/****************** PSA Client API *****************/
+
+/* Note - This header file containts the declaration of PSA defined client API elements.
+ * Ideally, These elements must be defined in a header file <psa_client.h> by SPM implemented
+ * library and provided to clients operation in NSPE and SPE as per the specification.
+ * If this is available in the platform, the elements declared as part of this
+ * file can be overwritten by passing --include <path_to_psa_client_h> to setup.sh script.
+ */
+
+#if ((PSA_API_ELEMENTS_AVAILABLE) || (!VAL_NSPE_BUILD))
+/* <psa_client.h>: Contains the Client API elements. Accessible to all applications */
+#include "psa_client.h"
+
+#else
+
+#include "val.h"
+#define PSA_FRAMEWORK_VERSION (0x000A)
+#define PSA_VERSION_NONE (0)
+#define PSA_SUCCESS (0)
+#define PSA_CONNECTION_REFUSED (INT32_MIN + 1)
+#define PSA_CONNECTION_BUSY (INT32_MIN + 2)
+#define PSA_DROP_CONNECTION (INT32_MIN)
+#define PSA_NULL_HANDLE ((psa_handle_t)0)
+
+typedef int32_t psa_status_t;
+typedef int32_t psa_handle_t;
+
+typedef struct psa_invec {
+ const void *base;
+ size_t len;
+} psa_invec;
+
+typedef struct psa_outvec {
+ void *base;
+ size_t len;
+} psa_outvec;
+
+uint32_t psa_framework_version(void);
+uint32_t psa_version(uint32_t sid);
+psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version);
+psa_status_t psa_call(psa_handle_t handle,
+ const psa_invec *in_vec, size_t in_len,
+ psa_outvec *out_vec, size_t out_len);
+psa_status_t psa_close(psa_handle_t handle);
+#endif /* #if ((PSA_API_ELEMENTS_AVAILABLE) || (!VAL_NSPE_BUILD)) */
+
+#ifndef VAL_NSPE_BUILD
+/* <psa_sid.h>: Macro definitions derived from manifest files that provides a mapping
+ * from RoT service names to Service IDs (SIDs) for use with the Client API.
+ * Partition manifest parse build tool must provide the implementation of this file.
+*/
+#include "psa_sid.h"
+
+#else
+
+#include "pal_sid.h"
+
+#endif /* VAL_NSPE_BUILD */
+
+#define INVALID_SID 0x0000FA20
+#endif /* _VAL_CLIENT_H_ */
diff --git a/psa-ff/val/nspe/pal_interfaces_ns.h b/psa-ff/val/nspe/pal_interfaces_ns.h
new file mode 100644
index 0000000..0fe60fa
--- /dev/null
+++ b/psa-ff/val/nspe/pal_interfaces_ns.h
@@ -0,0 +1,47 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+#ifndef _PAL_INTERFACES_NS_H_
+#define _PAL_INTERFACES_NS_H_
+
+#include "val.h"
+#include <stdarg.h>
+
+/**
+ @brief - This function will read peripherals using SPI commands
+ @param - addr : address of the peripheral
+ data : read buffer
+ len : length of the read buffer in bytes
+ @return - error status
+**/
+int pal_spi_read(addr_t addr, uint8_t *data, uint32_t len);
+
+/* Target Config API */
+/**
+ @brief - provides the database source location.
+ @param - void
+ @return - Returns base address of database
+**/
+void *pal_target_get_cfg_start(void);
+
+/**
+ @brief - This API will call the requested crypto function
+ @param - type : function code
+ valist : variable argument list
+ @return - error status
+**/
+uint32_t pal_crypto_function(int type, va_list valist);
+#endif
diff --git a/psa-ff/val/nspe/val_crypto.c b/psa-ff/val/nspe/val_crypto.c
new file mode 100644
index 0000000..8843b77
--- /dev/null
+++ b/psa-ff/val/nspe/val_crypto.c
@@ -0,0 +1,53 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#include "val_crypto.h"
+#include "val_target.h"
+#include "pal_interfaces_ns.h"
+#include "val_framework.h"
+#include "val_client_defs.h"
+
+/**
+ @brief - This API will call the requested crypto function
+ @param - type : function code
+ ... : variable number of arguments
+ @return - Error status
+**/
+val_status_t val_crypto_function(int type, ...)
+{
+ va_list valist;
+ val_status_t status;
+
+ va_start(valist, type);
+ status = pal_crypto_function(type, valist);
+ va_end(valist);
+ return status;
+}
+
+/**
+ @brief - Checks if the key type is of raw bits
+ @param - type : type of the key
+ @return - True : If key type is raw bits
+ False: If key type is not raw bits
+**/
+int32_t val_crypto_key_type_is_raw(psa_key_type_t type)
+{
+ psa_key_type_t category = type & PSA_KEY_TYPE_CATEGORY_MASK;
+
+ return (category == PSA_KEY_TYPE_RAW_DATA ||
+ category == PSA_KEY_TYPE_CATEGORY_SYMMETRIC);
+}
diff --git a/psa-ff/val/nspe/val_crypto.h b/psa-ff/val/nspe/val_crypto.h
new file mode 100644
index 0000000..7b96da0
--- /dev/null
+++ b/psa-ff/val/nspe/val_crypto.h
@@ -0,0 +1,305 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#ifndef _VAL_CRYPTO_H_
+#define _VAL_CRYPTO_H_
+
+#include "val.h"
+#include <stdarg.h>
+
+#define BYTES_TO_BITS(byte) (byte * 8)
+/* Size */
+#define AES_16B_KEY_SIZE 16
+#define AES_24B_KEY_SIZE 24
+#define AES_32B_KEY_SIZE 32
+#define AES_18B_KEY_SIZE 18
+#define AES_34B_KEY_SIZE 34
+#define DES_8B_KEY_SIZE 8
+#define DES3_2KEY_SIZE 16
+#define DES3_3KEY_SIZE 24
+#define SIZE_128B 128
+#define SIZE_256B 256
+#define SIZE_512B 512
+#define BUFFER_SIZE 1200
+#define HASH_64B 64
+
+/* Key Slot */
+#define INVALID_KEY_SLOT 0xDEAD
+#define ZERO_KEY_SLOT 0
+#define OCCUPIED_KEY_SLOT 1
+#define MAX_KEY_SLOT 32
+
+/* Key Type */
+#define PSA_KEY_TYPE_RAW_DATA ((psa_key_type_t)0x50000001)
+#define PSA_KEY_TYPE_CATEGORY_MASK ((psa_key_type_t)0x70000000)
+#define PSA_KEY_TYPE_CATEGORY_SYMMETRIC ((psa_key_type_t)0x40000000)
+#define PSA_KEY_TYPE_PAIR_FLAG ((psa_key_type_t)0x10000000)
+#define PSA_KEY_TYPE_AES ((psa_key_type_t)0x40000001)
+#define PSA_KEY_TYPE_DES ((psa_key_type_t)0x40000002)
+#define PSA_KEY_TYPE_RSA_PUBLIC_KEY ((psa_key_type_t)0x60010000)
+#define PSA_KEY_TYPE_RSA_KEYPAIR ((psa_key_type_t)0x70010000)
+#define PSA_KEY_TYPE_VENDOR_FLAG ((psa_key_type_t)0x80000000)
+#define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE ((psa_key_type_t)0x60030000)
+#define PSA_KEY_TYPE_ECC_KEYPAIR_BASE ((psa_key_type_t)0x70030000)
+#define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t)0x0000ffff)
+
+/* Key Lifetime */
+#define PSA_KEY_LIFETIME_VOLATILE ((psa_key_lifetime_t)0x00000000)
+#define PSA_KEY_LIFETIME_PERSISTENT ((psa_key_lifetime_t)0x00000001)
+#define PSA_KEY_LIFETIME_WRITE_ONCE ((psa_key_lifetime_t)0x7fffffff)
+#define PSA_KEY_LIFETIME_INVALID ((psa_key_lifetime_t)0xffffffff)
+
+/* Algorithm */
+#define PSA_ALG_BLOCK_CIPHER_PAD_NONE ((psa_algorithm_t)0x00000000)
+#define PSA_ALG_BLOCK_CIPHER_BASE ((psa_algorithm_t)0x04000000)
+#define PSA_KEY_USAGE_EXPORT ((psa_key_usage_t)0x00000001)
+#define PSA_KEY_USAGE_ENCRYPT ((psa_key_usage_t)0x00000100)
+#define PSA_KEY_USAGE_DECRYPT ((psa_key_usage_t)0x00000200)
+#define PSA_KEY_USAGE_SIGN ((psa_key_usage_t)0x00000400)
+#define PSA_KEY_USAGE_VERIFY ((psa_key_usage_t)0x00000800)
+#define PSA_KEY_USAGE_DERIVE ((psa_key_usage_t)0x00001000)
+#define PSA_ALG_RSA_PKCS1V15_SIGN_BASE ((psa_algorithm_t)0x10020000)
+#define PSA_ALG_ECDSA_BASE ((psa_algorithm_t)0x10060000)
+#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION ((psa_algorithm_t)0x12000000)
+#define PSA_ALG_RSA_PKCS1V15_SIGN_RAW PSA_ALG_RSA_PKCS1V15_SIGN_BASE
+#define PSA_KEY_USAGE_INVALID 0xFFFFFFFF
+#define PSA_ALG_INVALID 0xFFFFFFFF
+
+/* Hash Algorithm */
+#define PSA_ALG_CATEGORY_HASH ((psa_algorithm_t)0x01000000)
+#define PSA_ALG_HASH_MASK ((psa_algorithm_t)0x000000ff)
+#define PSA_ALG_MD2 ((psa_algorithm_t)0x01000001)
+#define PSA_ALG_MD4 ((psa_algorithm_t)0x01000002)
+#define PSA_ALG_MD5 ((psa_algorithm_t)0x01000003)
+#define PSA_ALG_RIPEMD160 ((psa_algorithm_t)0x01000004)
+#define PSA_ALG_SHA_1 ((psa_algorithm_t)0x01000005)
+#define PSA_ALG_SHA_224 ((psa_algorithm_t)0x01000008)
+#define PSA_ALG_SHA_256 ((psa_algorithm_t)0x01000009)
+#define PSA_ALG_SHA_384 ((psa_algorithm_t)0x0100000a)
+#define PSA_ALG_SHA_512 ((psa_algorithm_t)0x0100000b)
+#define PSA_ALG_SHA_512_224 ((psa_algorithm_t)0x0100000c)
+#define PSA_ALG_SHA_512_256 ((psa_algorithm_t)0x0100000d)
+#define PSA_ALG_SHA3_224 ((psa_algorithm_t)0x01000010)
+#define PSA_ALG_SHA3_256 ((psa_algorithm_t)0x01000011)
+#define PSA_ALG_SHA3_384 ((psa_algorithm_t)0x01000012)
+#define PSA_ALG_SHA3_512 ((psa_algorithm_t)0x01000013)
+
+/* Error codes */
+#define PSA_ERROR_UNKNOWN_ERROR ((psa_status_t)1)
+#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)2)
+#define PSA_ERROR_NOT_PERMITTED ((psa_status_t)3)
+#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)4)
+#define PSA_ERROR_OCCUPIED_SLOT ((psa_status_t)5)
+#define PSA_ERROR_EMPTY_SLOT ((psa_status_t)6)
+#define PSA_ERROR_BAD_STATE ((psa_status_t)7)
+#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)8)
+#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)9)
+#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)10)
+#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)11)
+#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)12)
+#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)13)
+#define PSA_ERROR_TAMPERING_DETECTED ((psa_status_t)14)
+#define PSA_ERROR_INSUFFICIENT_ENTROPY ((psa_status_t)15)
+#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)16)
+#define PSA_ERROR_INVALID_PADDING ((psa_status_t)17)
+#define PSA_ERROR_INSUFFICIENT_CAPACITY ((psa_status_t)18)
+
+/* Encoding of curve identifiers */
+#define PSA_ECC_CURVE_SECT163K1 ((psa_ecc_curve_t) 0x0001)
+#define PSA_ECC_CURVE_SECT163R1 ((psa_ecc_curve_t) 0x0002)
+#define PSA_ECC_CURVE_SECT163R2 ((psa_ecc_curve_t) 0x0003)
+#define PSA_ECC_CURVE_SECT193R1 ((psa_ecc_curve_t) 0x0004)
+#define PSA_ECC_CURVE_SECT193R2 ((psa_ecc_curve_t) 0x0005)
+#define PSA_ECC_CURVE_SECT233K1 ((psa_ecc_curve_t) 0x0006)
+#define PSA_ECC_CURVE_SECT233R1 ((psa_ecc_curve_t) 0x0007)
+#define PSA_ECC_CURVE_SECT239K1 ((psa_ecc_curve_t) 0x0008)
+#define PSA_ECC_CURVE_SECT283K1 ((psa_ecc_curve_t) 0x0009)
+#define PSA_ECC_CURVE_SECT283R1 ((psa_ecc_curve_t) 0x000a)
+#define PSA_ECC_CURVE_SECT409K1 ((psa_ecc_curve_t) 0x000b)
+#define PSA_ECC_CURVE_SECT409R1 ((psa_ecc_curve_t) 0x000c)
+#define PSA_ECC_CURVE_SECT571K1 ((psa_ecc_curve_t) 0x000d)
+#define PSA_ECC_CURVE_SECT571R1 ((psa_ecc_curve_t) 0x000e)
+#define PSA_ECC_CURVE_SECP160K1 ((psa_ecc_curve_t) 0x000f)
+#define PSA_ECC_CURVE_SECP160R1 ((psa_ecc_curve_t) 0x0010)
+#define PSA_ECC_CURVE_SECP160R2 ((psa_ecc_curve_t) 0x0011)
+#define PSA_ECC_CURVE_SECP192K1 ((psa_ecc_curve_t) 0x0012)
+#define PSA_ECC_CURVE_SECP192R1 ((psa_ecc_curve_t) 0x0013)
+#define PSA_ECC_CURVE_SECP224K1 ((psa_ecc_curve_t) 0x0014)
+#define PSA_ECC_CURVE_SECP224R1 ((psa_ecc_curve_t) 0x0015)
+#define PSA_ECC_CURVE_SECP256K1 ((psa_ecc_curve_t) 0x0016)
+#define PSA_ECC_CURVE_SECP256R1 ((psa_ecc_curve_t) 0x0017)
+#define PSA_ECC_CURVE_SECP384R1 ((psa_ecc_curve_t) 0x0018)
+#define PSA_ECC_CURVE_SECP521R1 ((psa_ecc_curve_t) 0x0019)
+#define PSA_ECC_CURVE_BRAINPOOL_P256R1 ((psa_ecc_curve_t) 0x001a)
+#define PSA_ECC_CURVE_BRAINPOOL_P384R1 ((psa_ecc_curve_t) 0x001b)
+#define PSA_ECC_CURVE_BRAINPOOL_P512R1 ((psa_ecc_curve_t) 0x001c)
+#define PSA_ECC_CURVE_CURVE25519 ((psa_ecc_curve_t) 0x001d)
+#define PSA_ECC_CURVE_CURVE448 ((psa_ecc_curve_t) 0x001e)
+#define PSA_ECC_CURVE_FFDHE_2048 ((psa_ecc_curve_t) 0x0100)
+#define PSA_ECC_CURVE_FFDHE_3072 ((psa_ecc_curve_t) 0x0101)
+#define PSA_ECC_CURVE_FFDHE_4096 ((psa_ecc_curve_t) 0x0102)
+#define PSA_ECC_CURVE_FFDHE_6144 ((psa_ecc_curve_t) 0x0103)
+#define PSA_ECC_CURVE_FFDHE_8192 ((psa_ecc_curve_t) 0x0104)
+
+#define PSA_ALG_HMAC_HASH(hmac_alg) \
+ (PSA_ALG_CATEGORY_HASH | ((hmac_alg) & PSA_ALG_HASH_MASK))
+
+/* The size of the output hash */
+#define PSA_HASH_SIZE(alg) \
+ ( \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_MD2 ? 16 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_MD4 ? 16 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_MD5 ? 16 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_RIPEMD160 ? 20 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA_1 ? 20 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA_224 ? 28 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA_256 ? 32 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA_384 ? 48 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA_512 ? 64 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA_512_224 ? 28 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA_512_256 ? 32 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA3_224 ? 28 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA3_256 ? 32 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA3_384 ? 48 : \
+ PSA_ALG_HMAC_HASH(alg) == PSA_ALG_SHA3_512 ? 64 : \
+ 0)
+
+/** The public key type corresponding to a key pair type. */
+#define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) \
+ ((type) & ~PSA_KEY_TYPE_PAIR_FLAG)
+
+/** Whether a key type is an RSA key (pair or public-only). */
+#define PSA_KEY_TYPE_IS_RSA(type) \
+ (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY)
+
+/** Whether a key type is an elliptic curve key (pair or public-only). */
+#define PSA_KEY_TYPE_IS_ECC(type) \
+ ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) & \
+ ~PSA_KEY_TYPE_ECC_CURVE_MASK) == PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE)
+#define PSA_KEY_TYPE_IS_ECC_KEYPAIR(type) \
+ (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \
+ PSA_KEY_TYPE_ECC_KEYPAIR_BASE)
+#define PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type) \
+ (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \
+ PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE)
+
+typedef uint16_t psa_ecc_curve_t;
+typedef uint32_t psa_key_usage_t;
+typedef uint32_t psa_algorithm_t;
+typedef int32_t psa_status_t;
+typedef uint32_t psa_key_type_t;
+typedef uint32_t psa_key_slot_t;
+typedef uint32_t psa_key_lifetime_t;
+
+enum crypto_function_code {
+ VAL_CRYPTO_INIT = 0x1,
+ VAL_CRYPTO_GENERATE_RANDOM = 0x2,
+ VAL_CRYPTO_IMPORT_KEY = 0x3,
+ VAL_CRYPTO_EXPORT_KEY = 0x4,
+ VAL_CRYPTO_EXPORT_PUBLIC_KEY = 0x5,
+ VAL_CRYPTO_DESTROY_KEY = 0x6,
+ VAL_CRYPTO_GET_KEY_INFO = 0x7,
+ VAL_CRYPTO_KEY_POLICY_INIT = 0x8,
+ VAL_CRYPTO_KEY_POLICY_SET_USAGE = 0x9,
+ VAL_CRYPTO_KEY_POLICY_GET_USAGE = 0xA,
+ VAL_CRYPTO_KEY_POLICY_GET_ALGORITHM = 0xB,
+ VAL_CRYPTO_SET_KEY_POLICY = 0xC,
+ VAL_CRYPTO_GET_KEY_POLICY = 0xD,
+ VAL_CRYPTO_GET_KEY_INFORMATION = 0xE,
+ VAL_CRYPTO_GET_KEY_LIFETIME = 0xF,
+ VAL_CRYPTO_SET_KEY_LIFETIME = 0x10,
+ VAL_CRYPTO_HASH_SETUP = 0x11,
+ VAL_CRYPTO_HASH_UPDATE = 0x12,
+ VAL_CRYPTO_HASH_VERIFY = 0x13,
+ VAL_CRYPTO_HASH_FINISH = 0x14,
+ VAL_CRYPTO_HASH_ABORT = 0x15,
+};
+
+struct psa_key_policy_s {
+ psa_key_usage_t usage;
+ psa_algorithm_t alg;
+};
+
+typedef struct {
+ unsigned char cksum[16]; /*!< checksum of the data block */
+ unsigned char state[48]; /*!< intermediate digest state */
+ unsigned char buffer[16]; /*!< data block being processed */
+ size_t left; /*!< amount of data in buffer */
+} mbedtls_md2_context;
+
+typedef struct {
+ uint32_t total[2]; /*!< number of bytes processed */
+ uint32_t state[4]; /*!< intermediate digest state */
+ unsigned char buffer[64]; /*!< data block being processed */
+} mbedtls_md4_context;
+
+typedef struct {
+ uint32_t total[2]; /*!< number of bytes processed */
+ uint32_t state[4]; /*!< intermediate digest state */
+ unsigned char buffer[64]; /*!< data block being processed */
+} mbedtls_md5_context;
+
+typedef struct {
+ uint32_t total[2]; /*!< number of bytes processed */
+ uint32_t state[5]; /*!< intermediate digest state */
+ unsigned char buffer[64]; /*!< data block being processed */
+} mbedtls_ripemd160_context;
+
+typedef struct {
+ uint32_t total[2]; /*!< The number of Bytes processed. */
+ uint32_t state[5]; /*!< The intermediate digest state. */
+ unsigned char buffer[64]; /*!< The data block being processed. */
+} mbedtls_sha1_context;
+
+typedef struct {
+ uint32_t total[2]; /*!< The number of Bytes processed. */
+ uint32_t state[8]; /*!< The intermediate digest state. */
+ unsigned char buffer[64]; /*!< The data block being processed. */
+ int is224; /*!< Determines which function to use:
+ 0: Use SHA-256, or 1: Use SHA-224. */
+} mbedtls_sha256_context;
+
+typedef struct {
+ uint64_t total[2]; /*!< The number of Bytes processed. */
+ uint64_t state[8]; /*!< The intermediate digest state. */
+ unsigned char buffer[128]; /*!< The data block being processed. */
+ int is384; /*!< Determines which function to use:
+ 0: Use SHA-512, or 1: Use SHA-384. */
+} mbedtls_sha512_context;
+
+struct psa_hash_operation_s
+{
+ psa_algorithm_t alg;
+ union
+ {
+ unsigned dummy; /* Make the union non-empty even with no supported algorithms. */
+ mbedtls_md2_context md2;
+ mbedtls_md4_context md4;
+ mbedtls_md5_context md5;
+ mbedtls_ripemd160_context ripemd160;
+ mbedtls_sha1_context sha1;
+ mbedtls_sha256_context sha256;
+ mbedtls_sha512_context sha512;
+ } ctx;
+};
+
+typedef struct psa_hash_operation_s psa_hash_operation_t;
+typedef struct psa_key_policy_s psa_key_policy_t;
+
+val_status_t val_crypto_function(int type, ...);
+int32_t val_crypto_key_type_is_raw(psa_key_type_t type);
+#endif /* _VAL_CRYPTO_H_ */
diff --git a/psa-ff/val/nspe/val_dispatcher.c b/psa-ff/val/nspe/val_dispatcher.c
new file mode 100644
index 0000000..ae222cb
--- /dev/null
+++ b/psa-ff/val/nspe/val_dispatcher.c
@@ -0,0 +1,436 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#include "val_framework.h"
+#include "val_dispatcher.h"
+#include "val_interfaces.h"
+#include "val_peripherals.h"
+#include "val_target.h"
+
+extern val_api_t val_api;
+extern psa_api_t psa_api;
+
+/* gloabls */
+addr_t g_test_info_addr;
+uint32_t combine_test_binary_in_ram;
+addr_t combine_test_binary_addr;
+
+static const unsigned char elf_magic_header[ELF_IDENT] = {
+ /* 0x7f, 'E', 'L', 'F' */
+ 0x7f, 0x45, 0x4c, 0x46,
+ /* Only 32-bit objects */
+ 0x01,
+ /* Only LSB data. */
+ 0x01,
+ /* Only ELF version 1. */
+ 0x01,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0
+};
+
+/**
+ @brief - This API will copy the length of data from addr to *data
+ @param - addr : address to be read
+ data pointer : address to which data will be copied
+ len : length of data to be copy in bytes
+ @return - error status
+**/
+val_status_t val_mem_copy(addr_t addr, uint8_t *data, uint32_t len)
+{
+ if (combine_test_binary_in_ram)
+ {
+ memcpy((void*)data, (void *)addr, len);
+ return VAL_STATUS_SUCCESS;
+ }
+ else
+ {
+ return val_spi_read(addr, data, len);
+ }
+}
+
+
+/**
+ @brief - This function parses ELF header, entry address(test info addreess)
+ and program headers. Copies the loadable segments to system memory.
+ @return - Returns Success/Failure
+**/
+int val_copy_elf(uint32_t saddr, uint32_t *info_addr)
+{
+ elf_header_t test_elfh;
+ elf_pheader_t test_ph;
+ int i;
+
+ if (0 != val_mem_copy(saddr, (uint8_t *)&test_elfh, sizeof(elf_header_t)))
+ {
+ val_print(PRINT_ERROR, "Error: read failure for Test ELF header\n", 0);
+ return -1;
+ }
+
+ /* validate ELF header */
+ if (0 != memcmp(&test_elfh.e_ident, &elf_magic_header, ELF_IDENT))
+ {
+ val_print(PRINT_ERROR, "Fail: Test ELF header validation\n", 0);
+ return -1;
+ }
+
+ for (i = 0; i < test_elfh.e_phnum; i++)
+ {
+ /* Read the program header */
+ if (0 != val_mem_copy((saddr + test_elfh.e_phoff + (sizeof(elf_pheader_t)*i)),
+ (uint8_t *)&test_ph, sizeof(elf_pheader_t)))
+ {
+ val_print(PRINT_ERROR, "Error: reading Test program header\n", 0);
+ return -1;
+ }
+
+ /* Load the program to physical RAM */
+ if (0 != val_mem_copy((saddr + test_ph.p_offset),
+ (uint8_t *)test_ph.p_paddr, test_ph.p_filesz))
+ {
+ val_print(PRINT_ERROR, "Error: reading Test program header\n", 0);
+ return -1;
+ }
+ }
+
+ *info_addr = test_elfh.e_entry;
+ return 0;
+}
+
+/**
+ @brief - This function reads the test ELFs from RAM or secondary storage and loads into
+ system memory
+ @param - test_id : Returns the current test ID
+ - test_id_prev : Previous test ID.
+ @return - Error code
+**/
+val_status_t val_test_load(test_id_t *test_id, test_id_t test_id_prev)
+{
+ test_header_t test_header;
+ addr_t flash_addr = combine_test_binary_addr;
+
+ /*
+ * The combined Test ELF binary:
+ *
+ * ----------------------
+ * | Custom Test Header*|
+ * |--------------------|
+ * | Test-1 Image |
+ * ----------------------
+ * | Custom Test Header*|
+ * ----------------------
+ * | Test-2 Image |
+ * |--------------------|
+ * | Custom Test Header*|
+ * :
+ * :
+ * ----------------------
+ * | END Marker |
+ * ----------------------
+ *
+ */
+
+ if (test_id_prev != VAL_INVALID_TEST_ID)
+ {
+ /* Jump to last test run + 1 */
+ do
+ {
+ if (val_mem_copy(flash_addr, (uint8_t *)&test_header, sizeof(test_header_t)))
+ {
+ val_print(PRINT_ERROR, "Error: reading Test program header\n", 0);
+ return VAL_STATUS_LOAD_ERROR;
+ }
+
+ if (test_header.start_marker == VAL_TEST_END_MARKER)
+ {
+ val_print(PRINT_ERROR, "\n\nNo more valid tests found. Exiting..", 0);
+ *test_id = VAL_INVALID_TEST_ID;
+ return VAL_STATUS_SUCCESS;
+ }
+
+ if (test_header.start_marker != VAL_TEST_START_MARKER)
+ {
+ flash_addr += 0x4;
+ continue;
+ }
+
+ if ((test_header.start_marker == VAL_TEST_START_MARKER)
+ && (test_header.test_id == test_id_prev))
+ {
+ flash_addr += (sizeof(test_header_t) + test_header.elf_size);
+ break;
+ }
+
+ flash_addr += (sizeof(test_header_t) + test_header.elf_size);
+ } while(1);
+ }
+
+ if (val_mem_copy(flash_addr, (uint8_t *)&test_header, sizeof(test_header_t)))
+ {
+ val_print(PRINT_ERROR, "\n\nError: reading custom Test header", 0);
+ return VAL_STATUS_LOAD_ERROR;
+ }
+
+ if (test_header.start_marker == VAL_TEST_END_MARKER)
+ {
+ val_print(PRINT_ERROR, "\n\nNo more valid tests found. Exiting.", 0);
+ *test_id = VAL_INVALID_TEST_ID;
+ return VAL_STATUS_SUCCESS;
+ }
+
+ if (test_header.start_marker != VAL_TEST_START_MARKER)
+ {
+ val_print(PRINT_ERROR, "\n\nNo valid test binary found. Exiting.", 0);
+ *test_id = VAL_INVALID_TEST_ID;
+ return VAL_STATUS_LOAD_ERROR;
+ }
+
+ flash_addr += sizeof(test_header_t);
+ if (val_copy_elf(flash_addr, &g_test_info_addr))
+ {
+ val_print(PRINT_ERROR, "Error: loading Test program\n", 0);
+ return VAL_STATUS_LOAD_ERROR;
+ }
+
+ *test_id = test_header.test_id;
+ return VAL_STATUS_SUCCESS;
+}
+
+/**
+ @brief - This function reads the function pointer addresses for
+ test_entry
+ @param - paddr : Returns the Test function address
+ @return - Returns val_status_t
+**/
+val_status_t val_get_test_entry_addr(addr_t *paddr)
+{
+ *paddr = (addr_t)(((val_test_info_t *)g_test_info_addr)->entry_addr);
+ return VAL_STATUS_SUCCESS;
+}
+
+/**
+ @brief - Execute the function pointer which was given to us by the test
+ @param - void
+**/
+void val_execute_test_fn(void)
+{
+ test_fptr_t fn_ptr;
+ addr_t addr;
+
+ val_get_test_entry_addr(&addr);
+ fn_ptr = (test_fptr_t)addr;
+ fn_ptr(&val_api, &psa_api);
+ return;
+}
+
+/*
+ @brief - Reads the pre-defined component name against given test_id
+ @param - test_id : Current Test ID
+ @return - Component name
+*/
+char * val_get_comp_name(test_id_t test_id)
+{
+ switch (VAL_GET_COMP_NUM(test_id))
+ {
+ case VAL_FF_BASE:
+ return "\nRunning... IPC Suite";
+ case VAL_CRYPTO_BASE:
+ return "\nRunning... Crypto Suite";
+ default:
+ return "No Component";
+ }
+}
+
+/**
+ @brief - This function is responsible for setting up VAL infrastructure.
+ Loads test one by one from combine binary and calls test_entry
+ function of each test image.
+ @return - none
+**/
+void val_dispatcher(test_id_t test_id_prev)
+{
+
+ test_id_t test_id;
+ val_status_t status;
+ miscellaneous_desc_t *misc_desc;
+ boot_t boot;
+ test_count_t test_count;
+ uint32_t test_result;
+
+ status = val_target_get_config(TARGET_CONFIG_CREATE_ID(GROUP_MISCELLANEOUS,
+ MISCELLANEOUS_DUT, 0),
+ (uint8_t **)&misc_desc,
+ (uint32_t *)sizeof(miscellaneous_desc_t));
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "\n\ttarget config read failed", 0);
+ return;
+ }
+
+ combine_test_binary_addr = misc_desc->ns_start_addr_of_combine_test_binary;
+ combine_test_binary_in_ram = misc_desc->combine_test_binary_in_ram;
+ do
+ {
+ status = val_get_boot_flag(&boot.state);
+ if (VAL_ERROR(status))
+ {
+ break;
+ }
+
+ /* Did last run test hang and system re-booted due to watchdog timeout and
+ boot.state was set to BOOT_NOT_EXPECTED ? If yes, set the test status
+ to SIM ERROR and go to next test. */
+ if (boot.state == BOOT_NOT_EXPECTED)
+ {
+ val_set_status(RESULT_PENDING(VAL_STATUS_ERROR));
+ status = val_nvmem_read(VAL_NVMEM_OFFSET(NV_TEST_ID_CURRENT),
+ &test_id, sizeof(test_id_t));
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "\n\tNVMEM read error", 0);
+ }
+ }
+ /* Did last run test hang and system reset due to watchdog timeout but
+ boot.state was set to BOOT_EXPECTED_BUT_FAILED ? If yes, set the test status
+ to FAIL and go to next test. This condition will hit when test was expecting
+ re-boot on perticular scenario but it didn't happen and system re-booted due
+ to other reason. */
+ else if (boot.state == BOOT_EXPECTED_BUT_FAILED)
+ {
+ val_set_status(RESULT_FAIL(VAL_STATUS_BOOT_EXPECTED_BUT_FAILED));
+ status = val_nvmem_read(VAL_NVMEM_OFFSET(NV_TEST_ID_CURRENT),
+ &test_id, sizeof(test_id_t));
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "\n\tNVMEM read error", 0);
+ }
+ }
+ else
+ {
+ status = val_test_load(&test_id, test_id_prev);
+
+ if (test_id == VAL_INVALID_TEST_ID || VAL_ERROR(status))
+ {
+ break;
+ }
+
+ status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_TEST_ID_CURRENT),
+ &test_id, sizeof(test_id_t));
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "\n\tNVMEM write error", 0);
+ break;
+ }
+
+ if (VAL_GET_COMP_NUM(test_id_prev) != VAL_GET_COMP_NUM(test_id))
+ {
+ val_print(PRINT_ALWAYS, val_get_comp_name(test_id), 0);
+ val_print(PRINT_ALWAYS, "\n******************************************\n", 0);
+ }
+
+ if (boot.state == BOOT_UNKNOWN)
+ {
+ /* Set boot.state to BOOT_NOT_EXPECTED to catch unexpected test hang */
+ status = val_set_boot_flag(BOOT_NOT_EXPECTED);
+ if (VAL_ERROR(status))
+ {
+ break;
+ }
+ }
+ val_execute_test_fn();
+ }
+
+ test_result = val_report_status();
+
+ /* Reset boot.state to UNKNOWN before lunching next test */
+ status = val_set_boot_flag(BOOT_UNKNOWN);
+ if (VAL_ERROR(status))
+ {
+ break;
+ }
+
+ /* Prepare suite summary data structure */
+ status = val_nvmem_read(VAL_NVMEM_OFFSET(NV_TEST_CNT), &test_count, sizeof(test_count_t));
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "\n\tNVMEM read error", 0);
+ break;
+ }
+
+ switch (test_result)
+ {
+ case TEST_PASS:
+ test_count.pass_cnt += 1;
+ break;
+ case TEST_FAIL:
+ test_count.fail_cnt += 1;
+ break;
+ case TEST_SKIP:
+ test_count.skip_cnt += 1;
+ break;
+ case TEST_PENDING:
+ test_count.sim_error_cnt += 1;
+ break;
+ }
+
+ status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_TEST_CNT), &test_count, sizeof(test_count_t));
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "\n\tNVMEM write error", 0);
+ break;
+ }
+
+ test_id_prev = test_id;
+ status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_TEST_ID_PREVIOUS),
+ &test_id, sizeof(test_id_t));
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "\n\tNVMEM write error", 0);
+ break;
+ }
+
+ } while(1);
+
+ status = val_nvmem_read(VAL_NVMEM_OFFSET(NV_TEST_CNT), &test_count, sizeof(test_count_t));
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "\n\tNVMEM read error", 0);
+ return;
+ }
+
+ val_print(PRINT_ALWAYS, "\n\n************ REGRESSION SUMMARY **********\n", 0);
+ val_print(PRINT_ALWAYS, "TOTAL TESTS : %d\n", test_count.pass_cnt + test_count.fail_cnt
+ + test_count.skip_cnt + test_count.sim_error_cnt);
+ val_print(PRINT_ALWAYS, "TOTAL PASSED : %d\n", test_count.pass_cnt);
+ val_print(PRINT_ALWAYS, "TOTAL SIM ERROR : %d\n", test_count.sim_error_cnt);
+ val_print(PRINT_ALWAYS, "TOTAL FAILED : %d\n", test_count.fail_cnt);
+ val_print(PRINT_ALWAYS, "TOTAL SKIPPED : %d\n", test_count.skip_cnt);
+ val_print(PRINT_ALWAYS, "\n******************************************\n", 0);
+}
+
+
+
+
+
+
+
diff --git a/psa-ff/val/nspe/val_dispatcher.h b/psa-ff/val/nspe/val_dispatcher.h
new file mode 100644
index 0000000..9adc98f
--- /dev/null
+++ b/psa-ff/val/nspe/val_dispatcher.h
@@ -0,0 +1,70 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#ifndef _VAL_DISPATCHER_H_
+#define _VAL_DISPATCHER_H_
+
+#include "val.h"
+
+#define ELF_IDENT 16
+#define VAL_INVALID_TEST_ID 0xffffffff
+#define VAL_TEST_START_MARKER 0xfaceface
+#define VAL_TEST_END_MARKER 0xc3c3c3c3
+
+/* typedef's */
+typedef uint32_t elf32_word;
+typedef int32_t elf32_sword;
+typedef uint16_t elf32_half;
+typedef uint32_t elf32_off;
+typedef uint32_t elf32_addr;
+
+typedef struct {
+ unsigned char e_ident[ELF_IDENT]; /* ident bytes */
+ elf32_half e_type; /* file type */
+ elf32_half e_machine; /* target machine */
+ elf32_word e_version; /* file version */
+ elf32_addr e_entry; /* start address */
+ elf32_off e_phoff; /* phdr file offset */
+ elf32_off e_shoff; /* shdr file offset */
+ elf32_word e_flags; /* file flags */
+ elf32_half e_ehsize; /* sizeof ehdr */
+ elf32_half e_phentsize; /* sizeof phdr */
+ elf32_half e_phnum; /* number phdrs */
+ elf32_half e_shentsize; /* sizeof shdr */
+ elf32_half e_shnum; /* number shdrs */
+ elf32_half e_shstrndx; /* shdr string index */
+} elf_header_t;
+
+typedef struct {
+ elf32_word p_type; /* Segment type */
+ elf32_off p_offset; /* Segment file offset */
+ elf32_addr p_vaddr; /* Segment virtual address */
+ elf32_addr p_paddr; /* Segment physical address */
+ elf32_word p_filesz; /* Segment size in file */
+ elf32_word p_memsz; /* Segment size in memory */
+ elf32_word p_flags; /* Segment flags */
+ elf32_word p_align; /* Segment alignment */
+} elf_pheader_t;
+
+typedef struct {
+ uint32_t start_marker;
+ test_id_t test_id;
+ uint32_t elf_size;
+} test_header_t;
+
+void val_dispatcher(test_id_t);
+#endif
diff --git a/psa-ff/val/nspe/val_entry.c b/psa-ff/val/nspe/val_entry.c
new file mode 100644
index 0000000..3f9d119
--- /dev/null
+++ b/psa-ff/val/nspe/val_entry.c
@@ -0,0 +1,63 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#include "val_entry.h"
+#include "val_framework.h"
+#include "val_peripherals.h"
+#include "val_dispatcher.h"
+
+/**
+ @brief - PSA C main function, does VAL init and calls test dispatcher
+ @param - None
+ @return - void
+**/
+void val_entry(void)
+{
+ test_id_t test_id;
+
+ if (VAL_ERROR(val_target_init()))
+ {
+ goto exit;
+ }
+
+ if (VAL_ERROR(val_uart_init()))
+ {
+ goto exit;
+ }
+
+ if (VAL_ERROR(val_get_last_run_test_id(&test_id)))
+ {
+ goto exit;
+ }
+
+ /* Compliance header print */
+ if (test_id == VAL_INVALID_TEST_ID)
+ {
+ val_print(PRINT_ALWAYS, "\n***** PSA Compliance Suite - Version %d.", PSA_ACS_MAJOR_VER);
+ val_print(PRINT_ALWAYS, "%d *****\n", PSA_ACS_MINOR_VER);
+ }
+
+ /* Call dispatcher routine*/
+ val_dispatcher(test_id);
+
+exit:
+ val_print(PRINT_ALWAYS, "\n\nEntering standby\n", 0);
+ while(1)
+ {
+ asm volatile("WFI");
+ }
+}
diff --git a/psa-ff/val/nspe/val_entry.h b/psa-ff/val/nspe/val_entry.h
new file mode 100644
index 0000000..0293113
--- /dev/null
+++ b/psa-ff/val/nspe/val_entry.h
@@ -0,0 +1,32 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#ifndef _VAL_ENTRY_H_
+#define _VAL_ENTRY_H_
+
+#include "val_framework.h"
+
+#define PSA_ACS_MAJOR_VER 0
+#define PSA_ACS_MINOR_VER 5
+
+/**
+ @brief - PSA C main function, does VAL init and calls test dispatcher
+ @param - None
+ @return - void
+**/
+extern void val_entry(void);
+#endif
diff --git a/psa-ff/val/nspe/val_framework.c b/psa-ff/val/nspe/val_framework.c
new file mode 100644
index 0000000..bb50d80
--- /dev/null
+++ b/psa-ff/val/nspe/val_framework.c
@@ -0,0 +1,590 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#include "val_framework.h"
+#include "val_interfaces.h"
+#include "val_dispatcher.h"
+#include "val_peripherals.h"
+#include "pal_interfaces_ns.h"
+#include "val_target.h"
+
+extern val_api_t val_api;
+extern psa_api_t psa_api;
+
+/* globals */
+test_status_buffer_t g_status_buffer;
+
+/**
+ * @brief Connect to given sid
+ @param -sid : RoT service id
+ @param -minor_version : minor_version of RoT service
+ @param -handle - return connection handle
+ * @return val_status_t
+ */
+val_status_t val_ipc_connect(uint32_t sid, uint32_t minor_version, psa_handle_t *handle )
+{
+ *handle = psa_connect(sid, minor_version);
+
+ if (*handle < 0)
+ {
+ return VAL_STATUS_CONNECTION_FAILED;
+ }
+
+ return VAL_STATUS_SUCCESS;
+}
+
+/**
+ * @brief Call a connected Root of Trust Service.@n
+ * The caller must provide an array of ::psa_invec_t structures as the input payload.
+ *
+ * @param handle Handle for the connection.
+ * @param in_vec Array of psa_invec structures.
+ * @param in_len Number of psa_invec structures in in_vec.
+ * @param out_vec Array of psa_outvec structures for optional Root of Trust Service response.
+ * @param out_len Number of psa_outvec structures in out_vec.
+ * @return val_status_t
+ */
+val_status_t val_ipc_call(psa_handle_t handle, psa_invec *in_vec, size_t in_len,
+ psa_outvec *out_vec, size_t out_len)
+{
+ psa_status_t call_status = PSA_SUCCESS;
+
+ call_status = psa_call(handle, in_vec, in_len, out_vec, out_len);
+
+ if (call_status != PSA_SUCCESS)
+ {
+ return VAL_STATUS_CALL_FAILED;
+ }
+
+ return VAL_STATUS_SUCCESS;
+}
+
+/**
+ * @brief Close a connection to a Root of Trust Service.
+ * Sends the PSA_IPC_DISCONNECT message to the Root of Trust Service so it can clean up resources.
+ *
+ * @param handle Handle for the connection.
+ * @return void
+ */
+void val_ipc_close(psa_handle_t handle)
+{
+ psa_close(handle);
+}
+/**
+ @brief - This function executes given list of tests from non-secure sequentially
+ This covers non-secure to secure IPC API scenario
+ @param - test_num : Test_num
+ @param - tests_list : list of tests to be executed
+ @param - server_hs : Initiate a server handshake
+ @return - val_status_t
+**/
+val_status_t val_execute_non_secure_tests(uint32_t test_num, client_test_t *tests_list,
+ bool_t server_hs)
+{
+ val_status_t status = VAL_STATUS_SUCCESS;
+ val_status_t test_status = VAL_STATUS_SUCCESS;
+ boot_t boot;
+ psa_handle_t handle;
+ uint32_t i = 1;
+ test_info_t test_info;
+
+ test_info.test_num = test_num;
+
+ status = val_get_boot_flag(&boot.state);
+ if (VAL_ERROR(status))
+ {
+ val_set_status(RESULT_FAIL(status));
+ return status;
+ }
+
+ if (boot.state == BOOT_NOT_EXPECTED || boot.state == BOOT_EXPECTED_CRYPTO)
+ {
+ val_print(PRINT_TEST,"[Info] Executing tests form non-secure\n", 0);
+ while (tests_list[i] != NULL)
+ {
+ if (server_hs == TRUE)
+ {
+ /* Handshake with server tests */
+ test_info.block_num = i;
+ status = val_execute_secure_test_func(&handle, test_info,
+ SERVER_TEST_DISPATCHER_SID);
+ if (VAL_ERROR(status))
+ {
+ val_set_status(RESULT_FAIL(status));
+ val_print(PRINT_ERROR,"[Check%d] START\n", i);
+ return status;
+ }
+ else
+ {
+ val_print(PRINT_DEBUG,"[Check%d] START\n", i);
+ }
+ }
+
+ /* Execute client tests */
+ test_status = tests_list[i](NONSECURE);
+
+ if (server_hs == TRUE)
+ {
+ /* Retrive Server test status */
+ status = val_get_secure_test_result(&handle);
+ }
+
+ status = test_status ? test_status:status;
+ if (VAL_ERROR(status))
+ {
+ val_set_status(RESULT_FAIL(status));
+ val_print(PRINT_ERROR,"[Check%d] FAILED\n", i);
+ return status;
+ }
+ else
+ {
+ val_print(PRINT_DEBUG,"[Check%d] PASSED\n", i);
+ }
+ i++;
+ }
+ }
+ else
+ {
+ /* If we are here means, we are in second run of this test */
+ status = VAL_STATUS_SUCCESS;
+ if (boot.state != BOOT_EXPECTED_S)
+ {
+ val_print(PRINT_DEBUG,"[Check1] PASSED\n", 0);
+ }
+ }
+ return status;
+}
+/**
+ @brief - This function is used to switch to client_partition.c
+ where client tests will be executed to cover secure to secure
+ IPC scenario.
+ @param - test_num : Test_num
+ @return - val_status_t
+**/
+val_status_t val_switch_to_secure_client(uint32_t test_num)
+{
+ val_status_t status = VAL_STATUS_SUCCESS;
+ boot_t boot;
+ psa_handle_t handle;
+ test_info_t test_info;
+
+ test_info.test_num = test_num;
+ test_info.block_num = 1;
+
+ status = val_get_boot_flag(&boot.state);
+ if (VAL_ERROR(status))
+ {
+ goto exit;
+ }
+
+ if (boot.state != BOOT_EXPECTED_S)
+ {
+ status = val_set_boot_flag(BOOT_NOT_EXPECTED);
+ if (VAL_ERROR(status))
+ {
+ goto exit;
+ }
+
+ /* switch to secure client */
+ status = val_execute_secure_test_func(&handle, test_info, CLIENT_TEST_DISPATCHER_SID);
+ if (VAL_ERROR(status))
+ {
+ goto exit;
+ }
+
+ /* Retrive secure client test status */
+ status = val_get_secure_test_result(&handle);
+ if (VAL_ERROR(status))
+ {
+ goto exit;
+ }
+ return status;
+ }
+ else
+ {
+ /* If we are here means, we are in third run of this test */
+ val_print(PRINT_DEBUG,"[Check1] PASSED\n", 0);
+ return VAL_STATUS_SUCCESS;
+ }
+
+exit:
+ val_set_status(RESULT_FAIL(status));
+ return status;
+}
+
+/**
+ @brief - This function is used to handshake between:
+ - nonsecure client fn to server test fn
+ - secure client fn and server test fn
+ - nonsecure client fn to secure client test fn
+ @param - handle : handle returned while connecting given sid
+ @param - test_info : Test_num and block_num to be executed
+ @param - sid : RoT service to be connected. Partition dispatcher sid
+ @return - val_status_t
+**/
+val_status_t val_execute_secure_test_func(psa_handle_t *handle, test_info_t test_info, uint32_t sid)
+{
+ uint32_t test_data;
+ val_status_t status = VAL_STATUS_SUCCESS;
+ psa_status_t status_of_call = PSA_SUCCESS;
+
+ *handle = psa_connect(sid, 0);
+
+ if (*handle < 0)
+ {
+ val_print(PRINT_ERROR, "Could not connect SID. Handle=%x\n", *handle);
+ return VAL_STATUS_CONNECTION_FAILED;
+ }
+
+ test_data = ((uint32_t)(test_info.test_num) |((uint32_t)(test_info.block_num) << BLOCK_NUM_POS)
+ | ((uint32_t)(TEST_EXECUTE_FUNC) << ACTION_POS));
+ psa_invec data[1] = {{&test_data, sizeof(test_data)}};
+
+ status_of_call = psa_call(*handle, data, 1, NULL, 0);
+
+ if (status_of_call != PSA_SUCCESS)
+ {
+ status = VAL_STATUS_CALL_FAILED;
+ val_print(PRINT_ERROR, "Call to dispatch SF failed. Status=%x\n", status_of_call);
+ psa_close(*handle);
+ }
+ return status;
+}
+
+/**
+ @brief - This function is used to retrive the status of previously connected test function
+ using val_execute_secure_test_func
+ @param - handle : handle of server function. Handle of Partition dispatcher sid
+ @return - The status of test functions
+**/
+val_status_t val_get_secure_test_result(psa_handle_t *handle)
+{
+ uint32_t test_data;
+ val_status_t status = VAL_STATUS_SUCCESS;
+ psa_status_t status_of_call = PSA_SUCCESS;
+
+ test_data = (TEST_RETURN_RESULT << ACTION_POS);
+
+ psa_outvec resp = {&status, sizeof(status)};
+ psa_invec data[1] = {{&test_data, sizeof(test_data)}};
+
+ status_of_call = psa_call(*handle, data, 1, &resp, 1);
+ if (status_of_call != PSA_SUCCESS)
+ {
+ status = VAL_STATUS_CALL_FAILED;
+ val_print(PRINT_ERROR, "Call to dispatch SF failed. Status=%x\n", status_of_call);
+ }
+
+ psa_close(*handle);
+ return status;
+}
+
+
+/**
+ @brief - Parses input status for a given test and
+ outputs appropriate information on the console
+ @return - Test state
+**/
+uint32_t val_report_status(void)
+{
+ uint32_t status, state;
+
+ status = val_get_status();
+
+ state = (status >> TEST_STATE_BIT) & TEST_STATE_MASK;
+ status = status & TEST_STATUS_MASK;
+
+ switch (state)
+ {
+ case TEST_START:
+ state = TEST_FAIL;
+ val_print(PRINT_ALWAYS, "TEST RESULT: FAILED (Error Code=0x%x)\n",
+ VAL_STATUS_INIT_FAILED);
+ break;
+
+ case TEST_END:
+ state = TEST_PASS;
+ val_print(PRINT_ALWAYS, "TEST RESULT: PASSED \n", 0);
+ break;
+
+ case TEST_FAIL:
+ val_print(PRINT_ALWAYS, "TEST RESULT: FAILED (Error Code=0x%x) \n", status);
+ break;
+
+ case TEST_SKIP:
+ val_print(PRINT_ALWAYS, "TEST RESULT: SKIPPED (Skip Code=0x%x)\n", status);
+ break;
+
+ case TEST_PENDING:
+ val_print(PRINT_ALWAYS, "TEST RESULT: SIM ERROR (Error Code=0x%x)\n", status);
+ break;
+
+ default:
+ state = TEST_FAIL;
+ val_print(PRINT_ALWAYS, "TEST RESULT: FAILED(Error Code=0x%x)\n", VAL_STATUS_INVALID);
+ break;
+
+ }
+
+ val_print(PRINT_ALWAYS, "\n******************************************\n", 0);
+ return state;
+}
+
+/**
+ @brief - Records the state and status of test
+ @return - val_status_t
+**/
+val_status_t val_set_status(uint32_t status)
+{
+ g_status_buffer.state = ((status >> TEST_STATE_BIT) & TEST_STATE_MASK);
+ g_status_buffer.status = (status & TEST_STATUS_MASK);
+
+ return VAL_STATUS_SUCCESS;
+}
+
+/**
+ @brief - Updates the state and status for a given test
+ @return - test status
+**/
+uint32_t val_get_status(void)
+{
+ return ((g_status_buffer.state) << TEST_STATE_BIT) | (g_status_buffer.status);
+}
+
+/*
+ @brief - This function checks if the input status argument is an error.
+ On error, we print the checkpoint value and set the status.
+ @param - checkpoint : Test debug checkpoint
+ - val_status_t : Test status
+ @return - returns the input status back to the program.
+*/
+
+val_status_t val_err_check_set(uint32_t checkpoint, val_status_t status)
+{
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "\tCheckpoint %d : ", checkpoint);
+ val_print(PRINT_ERROR, "Error Code=0x%x \n", status);
+ val_set_status(RESULT_FAIL(status));
+ }
+ else
+ {
+ status = val_get_status();
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "\tCheckpoint %d : ", checkpoint);
+ val_print(PRINT_ERROR, "Error Code=0x%x \n", status);
+ }
+ else
+ {
+ val_print(PRINT_DEBUG, "\tCheckpoint %d \n", checkpoint);
+ }
+ }
+ return status;
+}
+
+/**
+ @brief This API prints the test number, description and
+ sets the test state to TEST_START on successful execution.
+ @param test_num :unique number identifying this test
+ @param desc :brief description of the test
+ @param test_bitfield :Addition test info such as
+ - test isolation level requirement
+ - Watchdog timeout type
+ @return void
+**/
+
+void val_test_init(uint32_t test_num, char8_t *desc, uint32_t test_bitfield)
+{
+ val_status_t status = VAL_STATUS_SUCCESS;
+ miscellaneous_desc_t *misc_desc;
+
+ /*global init*/
+ g_status_buffer.state = 0;
+ g_status_buffer.status = VAL_STATUS_INVALID;
+
+ val_print(PRINT_ALWAYS, "\nTEST: %d | DESCRIPTION: ", test_num);
+ val_print(PRINT_ALWAYS, desc, 0);
+
+ /* common skip logic */
+ status = val_target_get_config(TARGET_CONFIG_CREATE_ID(GROUP_MISCELLANEOUS,
+ MISCELLANEOUS_DUT, 0),
+ (uint8_t **)&misc_desc,
+ (uint32_t *)sizeof(miscellaneous_desc_t));
+ if (VAL_ERROR(status))
+ {
+ return;
+ }
+
+ if (misc_desc->implemented_psa_firmware_isolation_level <
+ GET_TEST_ISOLATION_LEVEL(test_bitfield))
+ {
+ val_set_status(RESULT_SKIP(VAL_STATUS_ISOLATION_LEVEL_NOT_SUPP));
+ val_print(PRINT_ALWAYS, "Skipping test. Required isolation level is not supported\n", 0);
+ return;
+ }
+
+ /* Initialise watchdog */
+ status = val_wd_timer_init(GET_WD_TIMOUT_TYPE(test_bitfield));
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "val_wd_timer_init failed Error=0x%x\n", status);
+ return;
+ }
+
+ /* Enable watchdog Timer */
+ status = val_wd_timer_enable();
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "val_wd_timer_enable failed Error=0x%x\n", status);
+ return;
+ }
+
+ val_set_status(RESULT_START(VAL_STATUS_SUCCESS));
+ return;
+}
+
+/**
+ @brief This API sets the test state to TEST_END if test is successfuly passed.
+ @param none
+ @return none
+**/
+
+void val_test_exit(void)
+{
+ val_wd_timer_disable();
+
+ /* return if test skipped or failed */
+ if (IS_TEST_SKIP(val_get_status()) || IS_TEST_FAIL(val_get_status()))
+ {
+ return;
+ }
+ val_set_status(RESULT_END(VAL_STATUS_SUCCESS));
+}
+
+/**
+ @brief - This function returns the test ID of the last test that was run
+ @param - test_id address
+ @return - val_status_t
+**/
+val_status_t val_get_last_run_test_id(test_id_t *test_id)
+{
+ val_status_t status;
+ test_count_t test_count;
+ boot_t boot;
+ int i = 0, intermediate_boot = 0;
+ boot_state_t boot_state[] = {BOOT_NOT_EXPECTED, BOOT_EXPECTED_NS,
+ BOOT_EXPECTED_S, BOOT_EXPECTED_BUT_FAILED,
+ BOOT_EXPECTED_CRYPTO};
+
+ status = val_get_boot_flag(&boot.state);
+ if (VAL_ERROR(status))
+ {
+ return status;
+ }
+
+ for (i = 0; i < (sizeof(boot_state)/sizeof(boot_state[0])); i++)
+ {
+ if (boot.state == boot_state[i])
+ {
+ intermediate_boot = 1;
+ break;
+ }
+ }
+
+ if (!intermediate_boot)
+ {
+ /* First boot. Initiliase necessary data structure */
+ status = val_set_boot_flag(BOOT_UNKNOWN);
+ if (VAL_ERROR(status))
+ {
+ return status;
+ }
+
+ *test_id = VAL_INVALID_TEST_ID;
+ status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_TEST_ID_PREVIOUS),
+ test_id, sizeof(test_id_t));
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ALWAYS, "\n\tNVMEM write error", 0);
+ return status;
+ }
+
+ test_count.pass_cnt = 0;
+ test_count.fail_cnt = 0;
+ test_count.skip_cnt = 0;
+ test_count.sim_error_cnt = 0;
+
+ status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_TEST_CNT),
+ &test_count, sizeof(test_count_t));
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "\n\tNVMEM write error", 0);
+ return status;
+ }
+ }
+
+ status = val_nvmem_read(VAL_NVMEM_OFFSET(NV_TEST_ID_PREVIOUS), test_id, sizeof(test_id_t));
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "\n\tNVMEM read error", 0);
+ }
+
+ val_print(PRINT_INFO, "In val_get_last_run_test_id, test_id=%x\n", *test_id);
+ return status;
+}
+
+/**
+ @brief - This function sets the given boot.state value to corresponding
+ boot NVMEM location
+ @param - state: boot_state_t
+ @return - val_status_t
+**/
+val_status_t val_set_boot_flag(boot_state_t state)
+{
+ boot_t boot;
+ val_status_t status;
+
+ boot.state = state;
+ status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_BOOT), &boot, sizeof(boot_t));
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "val_nvmem_write failed. Error=0x%x\n", status);
+ return status;
+ }
+ return status;
+}
+
+/**
+ @brief - This function returns boot.state value available in boot NVMEM location
+ @param - state address
+ @return - val_status_t
+**/
+val_status_t val_get_boot_flag(boot_state_t *state)
+{
+ boot_t boot;
+ val_status_t status;
+
+ status = val_nvmem_read(VAL_NVMEM_OFFSET(NV_BOOT), &boot, sizeof(boot_t));
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "val_nvmem_read failed. Error=0x%x\n", status);
+ return status;
+ }
+ *state = boot.state;
+ return status;
+}
diff --git a/psa-ff/val/nspe/val_framework.h b/psa-ff/val/nspe/val_framework.h
new file mode 100644
index 0000000..84e2bd0
--- /dev/null
+++ b/psa-ff/val/nspe/val_framework.h
@@ -0,0 +1,46 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+
+#ifndef _VAL_INFRA_H_
+#define _VAL_INFRA_H_
+
+#include "val.h"
+#include "val_client_defs.h"
+#include "val_interfaces.h"
+
+/* prototypes */
+uint32_t val_report_status(void);
+val_status_t val_set_status(uint32_t status);
+uint32_t val_get_status(void);
+val_status_t val_err_check_set(uint32_t checkpoint, val_status_t status);
+void val_test_init(uint32_t test_num, char8_t *desc, uint32_t test_bitfield);
+void val_test_exit(void);
+val_status_t val_get_last_run_test_id(test_id_t *test_id);
+val_status_t val_execute_non_secure_tests(uint32_t test_num, client_test_t *tests_list,
+ bool_t server_hs);
+val_status_t val_switch_to_secure_client(uint32_t test_num);
+val_status_t val_execute_secure_test_func(psa_handle_t *handle, test_info_t test_info,
+ uint32_t sid);
+val_status_t val_get_secure_test_result(psa_handle_t *handle);
+val_status_t val_ipc_connect(uint32_t sid, uint32_t minor_version, psa_handle_t *handle);
+val_status_t val_ipc_call(psa_handle_t handle, psa_invec *in_vec, size_t in_len,
+ psa_outvec *out_vec, size_t out_len);
+void val_ipc_close(psa_handle_t handle);
+val_status_t val_set_boot_flag(boot_state_t state);
+val_status_t val_get_boot_flag(boot_state_t *state);
+#endif
diff --git a/psa-ff/val/nspe/val_interfaces.c b/psa-ff/val/nspe/val_interfaces.c
new file mode 100644
index 0000000..34b325c
--- /dev/null
+++ b/psa-ff/val/nspe/val_interfaces.c
@@ -0,0 +1,59 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+
+#include "val_framework.h"
+#include "val_interfaces.h"
+#include "val_peripherals.h"
+#include "val_target.h"
+#include "val_crypto.h"
+
+/*VAL APIs to be used by test */
+const val_api_t val_api = {
+ .print = val_print,
+ .set_status = val_set_status,
+ .get_status = val_get_status,
+ .test_init = val_test_init,
+ .test_exit = val_test_exit,
+ .err_check_set = val_err_check_set,
+ .target_get_config = val_target_get_config,
+ .execute_non_secure_tests = val_execute_non_secure_tests,
+ .switch_to_secure_client = val_switch_to_secure_client,
+ .execute_secure_test_func = val_execute_secure_test_func,
+ .get_secure_test_result = val_get_secure_test_result,
+ .ipc_connect = val_ipc_connect,
+ .ipc_call = val_ipc_call,
+ .ipc_close = val_ipc_close,
+ .nvmem_read = val_nvmem_read,
+ .nvmem_write = val_nvmem_write,
+ .wd_timer_init = val_wd_timer_init,
+ .wd_timer_enable = val_wd_timer_enable,
+ .wd_timer_disable = val_wd_timer_disable,
+ .is_wd_timer_enabled = val_is_wd_timer_enabled,
+ .set_boot_flag = val_set_boot_flag,
+ .get_boot_flag = val_get_boot_flag,
+ .crypto_function = val_crypto_function,
+ .crypto_key_type_is_raw = val_crypto_key_type_is_raw,
+};
+
+const psa_api_t psa_api = {
+ .framework_version = psa_framework_version,
+ .version = psa_version,
+ .connect = psa_connect,
+ .call = psa_call,
+ .close = psa_close,
+};
diff --git a/psa-ff/val/nspe/val_interfaces.h b/psa-ff/val/nspe/val_interfaces.h
new file mode 100644
index 0000000..74362bb
--- /dev/null
+++ b/psa-ff/val/nspe/val_interfaces.h
@@ -0,0 +1,82 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#ifndef _VAL_INTERFACES_H_
+#define _VAL_INTERFACES_H_
+
+#include "val.h"
+#include "val_client_defs.h"
+
+/* typedef's */
+typedef struct {
+ val_status_t (*print) (print_verbosity_t verbosity,
+ char *string, uint32_t data);
+ val_status_t (*set_status) (uint32_t status);
+ uint32_t (*get_status) (void);
+ void (*test_init) (uint32_t test_num, char8_t *desc,
+ uint32_t test_bitfield);
+ void (*test_exit) (void);
+ val_status_t (*err_check_set) (uint32_t checkpoint, val_status_t status);
+ val_status_t (*target_get_config) (cfg_id_t cfg_id, uint8_t **data, uint32_t *size);
+ val_status_t (*execute_non_secure_tests) (uint32_t test_num, client_test_t *tests_list,
+ bool_t server_hs);
+ val_status_t (*switch_to_secure_client) (uint32_t test_num);
+ val_status_t (*execute_secure_test_func) (psa_handle_t *handle, test_info_t test_info,
+ uint32_t sid);
+ val_status_t (*ipc_connect) (uint32_t sid, uint32_t minor_version,
+ psa_handle_t *handle );
+ val_status_t (*ipc_call) (psa_handle_t handle, psa_invec *in_vec,
+ size_t in_len, psa_outvec *out_vec,
+ size_t out_len);
+ void (*ipc_close) (psa_handle_t handle);
+ val_status_t (*get_secure_test_result) (psa_handle_t *handle);
+ val_status_t (*nvmem_read) (uint32_t offset, void *buffer, int size);
+ val_status_t (*nvmem_write) (uint32_t offset, void *buffer, int size);
+ val_status_t (*wd_timer_init) (wd_timeout_type_t timeout_type);
+ val_status_t (*wd_timer_enable) (void);
+ val_status_t (*wd_timer_disable) (void);
+ val_status_t (*is_wd_timer_enabled) (void);
+ val_status_t (*set_boot_flag) (boot_state_t state);
+ val_status_t (*get_boot_flag) (boot_state_t *state);
+ val_status_t (*crypto_function) (int type, ...);
+ int32_t (*crypto_key_type_is_raw) (uint32_t type);
+} val_api_t;
+
+typedef struct {
+ uint32_t (*framework_version) (void);
+ uint32_t (*version) (uint32_t sid);
+ psa_handle_t (*connect) (uint32_t sid, uint32_t minor_version);
+ psa_status_t (*call) (psa_handle_t handle,
+ const psa_invec *in_vec,
+ size_t in_len,
+ psa_outvec *out_vec,
+ size_t out_len
+ );
+ psa_status_t (*close) (psa_handle_t handle);
+} psa_api_t;
+
+typedef void (*test_fptr_t)(val_api_t *val, psa_api_t *psa);
+
+typedef struct {
+ test_id_t test_id;
+ test_fptr_t entry_addr;
+} val_test_info_t;
+
+void test_entry(val_api_t *val, psa_api_t *psa);
+void test_payload(val_api_t *val, psa_api_t *psa);
+
+#endif
diff --git a/psa-ff/val/nspe/val_peripherals.c b/psa-ff/val/nspe/val_peripherals.c
new file mode 100644
index 0000000..3ffbe57
--- /dev/null
+++ b/psa-ff/val/nspe/val_peripherals.c
@@ -0,0 +1,395 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#include "val_peripherals.h"
+#include "val_target.h"
+#include "pal_interfaces_ns.h"
+#include "val_framework.h"
+#include "val_client_defs.h"
+
+/* Global */
+uint32_t is_uart_init_done = 0;
+
+/**
+ @brief - This API will read the necessary target config info
+ and pass it to driver partition to initialise the driver partition
+ global variables
+ @param - void
+ @return - error status
+**/
+val_status_t val_target_init(void)
+{
+ target_param_t target_param;
+ val_status_t status = VAL_STATUS_SUCCESS;
+ psa_handle_t handle = 0;
+ psa_status_t status_of_call = PSA_SUCCESS;
+ soc_peripheral_desc_t *uart_desc;
+ soc_peripheral_desc_t *soc_per_desc;
+ memory_desc_t *memory_desc;
+
+ status = val_target_get_config(TARGET_CONFIG_CREATE_ID(GROUP_SOC_PERIPHERAL,
+ SOC_PERIPHERAL_UART, 0),
+ (uint8_t **)&uart_desc,
+ (uint32_t *)sizeof(soc_peripheral_desc_t));
+ if (VAL_ERROR(status))
+ {
+ return status;
+ }
+
+ target_param.uart_base_addr = uart_desc->base;
+
+ status = val_target_get_config(TARGET_CONFIG_CREATE_ID(GROUP_SOC_PERIPHERAL,
+ SOC_PERIPHERAL_WATCHDOG, 0),
+ (uint8_t **)&soc_per_desc,
+ (uint32_t *)sizeof(soc_peripheral_desc_t));
+ if (VAL_ERROR(status))
+ {
+ return status;
+ }
+ target_param.wd_base_addr = soc_per_desc->base;
+ target_param.wd_time_us_low = soc_per_desc->timeout_in_micro_sec_low;
+ target_param.wd_time_us_medium = soc_per_desc->timeout_in_micro_sec_medium;
+ target_param.wd_time_us_high = soc_per_desc->timeout_in_micro_sec_high;
+ target_param.wd_timer_tick_us = soc_per_desc->num_of_tick_per_micro_sec;
+
+ status = val_target_get_config(TARGET_CONFIG_CREATE_ID(GROUP_MEMORY, MEMORY_NVMEM, 0),
+ (uint8_t **)&memory_desc,
+ (uint32_t *)sizeof(memory_desc_t));
+
+ target_param.nvmem_base_addr = memory_desc->start;
+
+ if (VAL_ERROR(status))
+ {
+ return status;
+ }
+
+ psa_invec invec[1] = {{&target_param, sizeof(target_param)}};
+ handle = psa_connect(DRIVER_TARGET_INIT_SID, 0);
+ if (handle < 0)
+ {
+ return VAL_STATUS_CONNECTION_FAILED;
+ }
+ else
+ {
+ status_of_call = psa_call(handle, invec, 1, NULL, 0);
+ if (status_of_call != PSA_SUCCESS)
+ {
+ psa_close(handle);
+ return VAL_STATUS_CALL_FAILED;
+ }
+ }
+ psa_close(handle);
+ return VAL_STATUS_SUCCESS;
+}
+
+/*
+ @brief - Initialize UART.
+ This is client interface API of secure partition UART INIT API.
+ @param - None
+ @return - val_status_t
+*/
+val_status_t val_uart_init(void)
+{
+ psa_handle_t print_handle = 0;
+ psa_status_t status_of_call = PSA_SUCCESS;
+ uint32_t uart_init_sign = UART_INIT_SIGN;
+ uint32_t verbosity = VERBOSE;
+
+ psa_invec data[3] = {{&uart_init_sign, sizeof(uart_init_sign)},
+ {&verbosity, sizeof(verbosity)}};
+
+ print_handle = psa_connect(DRIVER_UART_SID, 0);
+ if (print_handle < 0)
+ {
+ return(VAL_STATUS_CONNECTION_FAILED);
+ }
+
+ status_of_call = psa_call(print_handle, data, 3, NULL, 0);
+ if (status_of_call != PSA_SUCCESS)
+ {
+ return(VAL_STATUS_CALL_FAILED);
+ }
+
+ is_uart_init_done = 1;
+ psa_close(print_handle);
+ return VAL_STATUS_SUCCESS;
+}
+
+/**
+ @brief - Print module. This is client interface API of secure partition
+ val_print_sf API for nspe world
+ @param - verbosity: Print verbosity level
+ - string : Input string
+ - data : Value for format specifier
+ @return - val_status_t
+**/
+val_status_t val_print(print_verbosity_t verbosity, char *string, uint32_t data)
+{
+ int string_len = 0;
+ char *p = string;
+ psa_handle_t print_handle = 0;
+ psa_status_t status_of_call = PSA_SUCCESS;
+ val_status_t status = VAL_STATUS_SUCCESS;
+
+ if ((is_uart_init_done == 0) || (verbosity < VERBOSE))
+ {
+ return 0;
+ }
+ while (*p != '\0')
+ {
+ string_len++;
+ p++;
+ }
+
+ psa_invec data1[3] = {{&verbosity, 4}, {string, string_len+1}, {&data, 4}};
+ print_handle = psa_connect(DRIVER_UART_SID, 0);
+
+ if (print_handle < 0)
+ {
+ return VAL_STATUS_CONNECTION_FAILED;
+ }
+ else
+ {
+ status_of_call = psa_call(print_handle, data1, 3, NULL, 0);
+ if (status_of_call != PSA_SUCCESS)
+ {
+ status = VAL_STATUS_CALL_FAILED;
+ }
+ }
+ psa_close(print_handle);
+ return status;
+}
+
+/**
+ @brief - This API will read from slave address via SPI
+ @param - addr : Slave address
+ data : value read from Slave address
+ len : length of data to be read in bytes
+ @return - error status
+**/
+val_status_t val_spi_read(addr_t addr, uint8_t *data, uint32_t len)
+{
+ return pal_spi_read(addr, data, len);
+}
+
+/* Watchdog APIs */
+/**
+ @brief - Initializes the WatchDog Timer instance. This is client interface API of
+ secure partition val_wd_timer_init_sf API for nspe world.
+ @param timeout: watchdog timeout value to be programmed
+ Defines to be used are WD_LOW_TIMEOUT, WD_MEDIUM_TIMEOUT and WD_HIGH_TIMEOUT
+ @return - error status
+**/
+val_status_t val_wd_timer_init(wd_timeout_type_t timeout_type)
+{
+ wd_param_t wd_param;
+ psa_handle_t handle = 0;
+ psa_status_t status_of_call = PSA_SUCCESS;
+
+ wd_param.wd_fn_type = WD_INIT_SEQ;
+ wd_param.wd_timeout_type = timeout_type;
+ psa_invec invec[1] = {{&wd_param, sizeof(wd_param)}};
+
+ handle = psa_connect(DRIVER_WATCHDOG_SID, 0);
+ if (handle < 0)
+ {
+ return VAL_STATUS_CONNECTION_FAILED;
+ }
+ else
+ {
+ status_of_call = psa_call(handle, invec, 1, NULL, 0);
+ if (status_of_call != PSA_SUCCESS)
+ {
+ psa_close(handle);
+ return VAL_STATUS_CALL_FAILED;
+ }
+ }
+ psa_close(handle);
+ return VAL_STATUS_SUCCESS;
+}
+
+/**
+ @brief - Enable WatchDog Timer instance. This is client interface API of
+ secure partition val_wd_timer_enable_sf API for nspe world.
+ @return - error status
+**/
+val_status_t val_wd_timer_enable(void)
+{
+ wd_param_t wd_param;
+ psa_handle_t handle = 0;
+ psa_status_t status_of_call = PSA_SUCCESS;
+
+ wd_param.wd_fn_type = WD_ENABLE_SEQ;
+ psa_invec invec[1] = {{&wd_param, sizeof(wd_param)}};
+
+ handle = psa_connect(DRIVER_WATCHDOG_SID, 0);
+ if (handle < 0)
+ {
+ return VAL_STATUS_CONNECTION_FAILED;
+ }else
+ {
+ status_of_call = psa_call(handle, invec, 1, NULL, 0);
+ if (status_of_call != PSA_SUCCESS)
+ {
+ psa_close(handle);
+ return VAL_STATUS_CALL_FAILED;
+ }
+ }
+ psa_close(handle);
+ return VAL_STATUS_SUCCESS;
+}
+
+/**
+ @brief - Disable Watch Dog Timer instance. This is client interface API of
+ secure partition val_wd_timer_disable_sf API for nspe world.
+ @return - error status
+**/
+val_status_t val_wd_timer_disable(void)
+{
+ wd_param_t wd_param;
+ psa_handle_t handle = 0;
+ psa_status_t status_of_call = PSA_SUCCESS;
+
+ wd_param.wd_fn_type = WD_DISABLE_SEQ;
+ psa_invec invec[1] = {{&wd_param, sizeof(wd_param)}};
+
+ handle = psa_connect(DRIVER_WATCHDOG_SID, 0);
+ if (handle < 0)
+ {
+ return VAL_STATUS_CONNECTION_FAILED;
+ }
+ else
+ {
+ status_of_call = psa_call(handle, invec, 1, NULL, 0);
+ if (status_of_call != PSA_SUCCESS)
+ {
+ psa_close(handle);
+ return VAL_STATUS_CALL_FAILED;
+ }
+ }
+ psa_close(handle);
+ return VAL_STATUS_SUCCESS;
+}
+
+/**
+ @brief - Checks if watchdog enabled. This is client interface API of
+ secure partition val_is_wd_timer_enabled_sf API for nspe world.
+ @return - error status
+**/
+val_status_t val_is_wd_timer_enabled(void)
+{
+ wd_param_t wd_param;
+ psa_handle_t handle = 0;
+ psa_status_t status_of_call = PSA_SUCCESS;
+
+ wd_param.wd_fn_type = WD_STATUS_SEQ;
+ psa_invec invec[1] = {{&wd_param, sizeof(wd_param)}};
+
+ handle = psa_connect(DRIVER_WATCHDOG_SID, 0);
+ if (handle < 0)
+ {
+ return VAL_STATUS_CONNECTION_FAILED;
+ }
+ else
+ {
+ status_of_call = psa_call(handle, invec, 1, NULL, 0);
+ if (status_of_call != PSA_SUCCESS)
+ {
+ psa_close(handle);
+ return VAL_STATUS_CALL_FAILED;
+ }
+ }
+ psa_close(handle);
+ return VAL_STATUS_SUCCESS;
+}
+
+/*
+ @brief - Reads 'size' bytes from Non-volatile memory at a given. This is client interface
+ API of secure partition val_nvmem_read_sf API for nspe world.
+ 'base + offset' into given buffer.
+ - offset : Offset from NV MEM base address
+ - buffer : Pointer to source address
+ - size : Number of bytes
+ @return - val_status_t
+*/
+val_status_t val_nvmem_read(uint32_t offset, void *buffer, int size)
+{
+ nvmem_param_t nvmem_param;
+ psa_handle_t handle = 0;
+ psa_status_t status_of_call = PSA_SUCCESS;
+
+ nvmem_param.nvmem_fn_type = NVMEM_READ;
+ nvmem_param.offset = offset;
+ nvmem_param.size = size;
+ psa_invec invec[1] = {{&nvmem_param, sizeof(nvmem_param)}};
+ psa_outvec outvec[1] = {{buffer, size}};
+
+ handle = psa_connect(DRIVER_NVMEM_SID, 0);
+ if (handle < 0)
+ {
+ return VAL_STATUS_CONNECTION_FAILED;
+ }
+ else
+ {
+ status_of_call = psa_call(handle, invec, 1, outvec, 1);
+ if (status_of_call != PSA_SUCCESS)
+ {
+ psa_close(handle);
+ return VAL_STATUS_CALL_FAILED;
+ }
+ }
+ psa_close(handle);
+ return VAL_STATUS_SUCCESS;
+}
+
+/*
+ @brief - Writes 'size' bytes from buffer into non-volatile memory at a given
+ 'base + offset'. This is client interface API of secure partition
+ val_nvmem_write_sf API for nspe world.
+ - offset : Offset
+ - buffer : Pointer to source address
+ - size : Number of bytes
+ @return - val_status_t
+*/
+val_status_t val_nvmem_write(uint32_t offset, void *buffer, int size)
+{
+ nvmem_param_t nvmem_param;
+ psa_handle_t handle = 0;
+ psa_status_t status_of_call = PSA_SUCCESS;
+
+ nvmem_param.nvmem_fn_type = NVMEM_WRITE;
+ nvmem_param.offset = offset;
+ nvmem_param.size = size;
+ psa_invec invec[2] = {{&nvmem_param, sizeof(nvmem_param)}, {buffer, size}};
+
+ handle = psa_connect(DRIVER_NVMEM_SID, 0);
+ if (handle < 0)
+ {
+ return VAL_STATUS_CONNECTION_FAILED;
+ }
+ else
+ {
+ status_of_call = psa_call(handle, invec, 2, NULL, 0);
+ if (status_of_call != PSA_SUCCESS)
+ {
+ psa_close(handle);
+ return VAL_STATUS_CALL_FAILED;
+ }
+ }
+ psa_close(handle);
+ return VAL_STATUS_SUCCESS;
+}
diff --git a/psa-ff/val/nspe/val_peripherals.h b/psa-ff/val/nspe/val_peripherals.h
new file mode 100644
index 0000000..f3db9f6
--- /dev/null
+++ b/psa-ff/val/nspe/val_peripherals.h
@@ -0,0 +1,33 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#ifndef _VAL_PERIPHERALS_H_
+#define _VAL_PERIPHERALS_H_
+
+#include "val.h"
+
+val_status_t val_uart_init(void);
+val_status_t val_print(print_verbosity_t verbosity, char *string, uint32_t data);
+val_status_t val_spi_read(addr_t addr, uint8_t *data, uint32_t len);
+val_status_t val_target_init(void);
+val_status_t val_nvmem_read(uint32_t offset, void *buffer, int size);
+val_status_t val_nvmem_write(uint32_t offset, void *buffer, int size);
+val_status_t val_wd_timer_init(wd_timeout_type_t timeout_type);
+val_status_t val_wd_timer_enable(void);
+val_status_t val_wd_timer_disable(void);
+val_status_t val_is_wd_timer_enabled(void);
+#endif
diff --git a/psa-ff/val/nspe/val_target.c b/psa-ff/val/nspe/val_target.c
new file mode 100644
index 0000000..fe69759
--- /dev/null
+++ b/psa-ff/val/nspe/val_target.c
@@ -0,0 +1,146 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#include "val_framework.h"
+#include "val_target.h"
+#include "val_peripherals.h"
+#include "pal_interfaces_ns.h"
+
+/**
+ @brief - Returns the base address of target configuration block database.
+ @param - blob : Populates the base address
+ @return - val_status_t
+**/
+val_status_t val_target_cfg_get_next(void **blob)
+{
+ val_status_t status = VAL_STATUS_SUCCESS;
+ target_cfg_hdr_t *hdr;
+ uint32_t size;
+
+ if (*blob == NULL)
+ {
+ *blob = pal_target_get_cfg_start();
+ if (blob == NULL)
+ {
+ return VAL_STATUS_NOT_FOUND;
+ }
+ hdr = *blob;
+
+ /* Sanity check signature and version here */
+ if ((hdr->version != 1) || (hdr->size == 0))
+ {
+ val_print(PRINT_ERROR, "Target config database Error. \n", 0);
+ return status;
+ }
+ hdr++;
+ *blob = hdr; // skip the header. start with the first record.
+ return status;
+ }
+
+ size = (((cfg_type_t *)*blob)->size) & 0xFFFFFF;
+ if (size)
+ {
+ *blob = (void *)((uint8_t *)*blob + size);
+ return VAL_STATUS_SUCCESS;
+ }
+ return VAL_STATUS_ERROR;
+}
+
+/**
+ @brief - This function checks for the given configuration ID with the block in
+ target configuration database.
+ @param - cfg_id : Configuration ID of a block
+ - data : Returns block base address
+ - size : Block size
+ @return - val_status_t
+**/
+val_status_t val_target_get_cfg_blob(cfg_id_t cfg_id, uint8_t **data, uint32_t *size)
+{
+ val_status_t status;
+ void *config_blob = NULL;
+
+ val_print(PRINT_INFO, "Input id is %x \n", cfg_id);
+ do
+ {
+
+ status = val_target_cfg_get_next(&config_blob);
+
+ if (VAL_ERROR(status))
+ {
+ break;
+ }
+
+ if (((cfg_type_t *)config_blob)->cfg_id == cfg_id)
+ {
+ *data = (uint8_t *)config_blob;
+ status = VAL_STATUS_SUCCESS;
+ break;
+ }
+ else if (((((cfg_type_t *)config_blob)->cfg_id & VAL_TEST_MAJOR_GROUP_MASK) == \
+ (cfg_id & VAL_TEST_MAJOR_GROUP_MASK)) && \
+ !(((cfg_type_t *)config_blob)->cfg_id & \
+ (VAL_TEST_MINOR_GROUP_MASK | VAL_TEST_CFG_INSTANCE_MASK)))
+ {
+ config_blob = (void *)((uint8_t *)config_blob + sizeof(memory_hdr_t));
+ if (((cfg_type_t *)config_blob)->cfg_id == cfg_id)
+ {
+ *data = (uint8_t *)config_blob;
+ status = VAL_STATUS_SUCCESS;
+ break;
+ }
+ }
+ else if (((cfg_type_t *)config_blob)->cfg_id == VAL_TEST_INVALID_CFG_ID)
+ {
+ status = VAL_STATUS_NOT_FOUND;
+ break;
+ }
+ } while(1);
+
+ return status;
+}
+
+/**
+
+ @brief - This function returns the data associated with a given
+ config ID.
+ @param - size - if the input size is less than the data size to
+ returned, the size is updated with the actual data size and
+ error is returned.
+ @return - data contains the information of type specific to a
+ config id.
+**/
+val_status_t val_target_get_config(cfg_id_t cfg_id, uint8_t **data, uint32_t *size)
+{
+ val_status_t status;
+
+ if ((cfg_id < TARGET_MIN_CFG_ID) || (cfg_id > TARGET_MAX_CFG_ID))
+ {
+ val_print(PRINT_ERROR, "Invalid Target data config ID = %x \n", cfg_id);
+ return VAL_STATUS_INSUFFICIENT_SIZE;
+ }
+
+ status = val_target_get_cfg_blob(cfg_id, data, size);
+
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "\n Get Config failed with status = %x", status);
+ val_print(PRINT_ERROR, " for cfg_id = %x", cfg_id);
+ return status;
+ }
+ return VAL_STATUS_SUCCESS;
+}
+
diff --git a/psa-ff/val/nspe/val_target.h b/psa-ff/val/nspe/val_target.h
new file mode 100644
index 0000000..50a7e3f
--- /dev/null
+++ b/psa-ff/val/nspe/val_target.h
@@ -0,0 +1,198 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#ifndef _TARGET_INFO_DATA_H_
+#define _TARGET_INFO_DATA_H_
+
+#include "val.h"
+
+#define TARGET_CONFIG_CREATE_ID(major, minor, index) \
+ (((major & 0xFF) << 24) | ((minor & 0xFF) << 16) | (index & 0xFFFF))
+#define TARGET_CONFIG_GET_MAJOR(config_id) ((config_id >> 24) & 0xFF)
+#define TARGET_CONFIG_GET_MINOR(config_id) ((config_id >> 16) & 0xFF)
+#define TARGET_CONFIG_INCREMENT_INDEX(config_id) \
+ ((config_id & 0xFFFF0000) | ((config_id & 0xFFFF) + 1))
+#define GET_NUM_INSTANCE(struct_type) (struct_type->cfg_type.size >> 24)
+#define VAL_TEST_MAJOR_GROUP_MASK 0xFF000000UL
+#define VAL_TEST_MINOR_GROUP_MASK 0x00FF0000UL
+#define VAL_TEST_CFG_INSTANCE_MASK 0x0000FFFFUL
+#define VAL_TEST_INVALID_CFG_ID 0xFFFFFFFFUL
+#define TARGET_MIN_CFG_ID TARGET_CONFIG_CREATE_ID(GROUP_SOC_PERIPHERAL, 0, 0)
+#define TARGET_MAX_CFG_ID TARGET_CONFIG_CREATE_ID(GROUP_MAX, 0, 0)
+
+/**
+ Config IDs for each group/component
+ 31:24 : MAJOR (group)
+ 23:16 : MINOR (component)
+ 16:8 : SUB-component
+ 7:0 : INSTANCE (instance of same component)
+**/
+
+/*
+ MAJOR IDs
+*/
+typedef enum _GROUP_CONFIG_ID_ {
+ GROUP_SOC_PERIPHERAL = 0x1,
+ GROUP_MEMORY = 0x2,
+ GROUP_MISCELLANEOUS = 0x3,
+ GROUP_MAX = 0xFF,
+} group_cfg_id_t;
+
+/*
+ MINOR IDs
+ */
+typedef enum _SOC_PERIPHERAL_CONFIG_ID_ {
+ SOC_PERIPHERAL_UART = 0x1,
+ SOC_PERIPHERAL_TIMER = 0x2,
+ SOC_PERIPHERAL_WATCHDOG = 0x3,
+} soc_peripheral_cfg_id_t;
+
+typedef enum _MEMORY_CONFIG_ID_ {
+ MEMORY_NVMEM = 0x2
+} memory_cfg_id_t;
+
+typedef enum _MISCELLANEOUS_CONFIG_ID_ {
+ MISCELLANEOUS_BOOT = 0x1,
+ MISCELLANEOUS_DUT = 0x2
+} miscellaneous_cfg_id_t;
+
+/**
+ Assign group type to each system component
+**/
+typedef enum _COMPONENT_GROUPING_{
+ UART = GROUP_SOC_PERIPHERAL,
+ TIMER = GROUP_SOC_PERIPHERAL,
+ WATCHDOG = GROUP_SOC_PERIPHERAL,
+ NVMEM = GROUP_MEMORY,
+ BOOT = GROUP_MISCELLANEOUS,
+ DUT = GROUP_MISCELLANEOUS,
+} comp_group_assign_t;
+
+/**
+ Target Configuration Header
+**/
+typedef struct _TARGET_CFG_HDR_ {
+ /* PSA_CFG */
+ uint32_t signature[2];
+ /* 8 byte String describing the Target platform */
+ uint32_t target_string[2];
+ /* version = 1 for now */
+ uint32_t version;
+ /* Header Size */
+ uint32_t size;
+}target_cfg_hdr_t;
+
+typedef enum {
+ LEVEL1 = 0x1,
+ LEVEL2,
+ LEVEL3,
+} firmware_level_t;
+
+typedef enum {
+ NOT_AVAILABLE = 0x0,
+ AVAILABLE = 0x1,
+} is_available_t;
+
+typedef enum {
+ SECURE_ACCESS = 0x100,
+ NONSECURE_ACCESS,
+ SECURE_PROGRAMMABLE,
+ NONSECURE_PROGRAMMABLE
+} dev_attr_t;
+
+typedef enum {
+ MEM_SECURE = 0x100,
+ MEM_NONSECURE,
+ MEM_NSC,
+} mem_tgt_attr_t;
+
+typedef enum {
+ TYPE_READ_ONLY = 0x10,
+ TYPE_WRITE_ONLY,
+ TYPE_READ_WRITE,
+ TYPE_EXECUTE,
+ TYPE_RESERVED,
+} perm_type_t;
+
+typedef struct _CFG_HDR_TYPE_ {
+ cfg_id_t cfg_id;
+ /* size inclusive of this header */
+ uint32_t size;
+} cfg_type_t;
+
+/**
+ Memory Information
+**/
+typedef struct _MEM_INFO_DESC_ {
+ cfg_type_t cfg_type;
+ uint32_t num;
+} memory_hdr_t;
+
+typedef struct _MEM_REGION_ {
+ cfg_type_t cfg_type;
+ addr_t start;
+ addr_t end;
+ mem_tgt_attr_t attribute;
+ perm_type_t permission;
+} memory_desc_t;
+
+/*
+ SOC Peripheral description structures
+*/
+typedef struct _SOC_PER_INFO_NUM_ {
+ cfg_type_t cfg_type;
+ uint32_t num;
+} soc_peripheral_hdr_t;
+
+typedef struct _SOC_PER_INFO_DESC_ {
+ cfg_type_t cfg_type;
+ uint32_t vendor_id;
+ uint32_t device_id;
+ addr_t base;
+ uint32_t size;
+ uint32_t intr_id;
+ perm_type_t permission;
+ uint32_t timeout_in_micro_sec_low;
+ uint32_t timeout_in_micro_sec_medium;
+ uint32_t timeout_in_micro_sec_high;
+ uint32_t num_of_tick_per_micro_sec;
+ dev_attr_t attribute;
+} soc_peripheral_desc_t;
+
+/**
+ System Miscellaneous Information
+**/
+
+typedef struct _MISCELLANEOUS_INFO_HDR_ {
+ cfg_type_t cfg_type;
+ uint32_t num;
+} miscellaneous_hdr_t;
+
+typedef struct _MISCELLANEOUS_INFO_DESC_ {
+ cfg_type_t cfg_type;
+ firmware_level_t implemented_psa_firmware_isolation_level;
+ addr_t ns_start_addr_of_combine_test_binary;
+ is_available_t combine_test_binary_in_ram;
+ addr_t ns_test_addr;
+} miscellaneous_desc_t;
+
+/*val target config read apis */
+val_status_t val_target_get_config(cfg_id_t cfg_id, uint8_t **data, uint32_t *size);
+val_status_t val_target_cfg_get_next(void **blob);
+val_status_t val_target_get_cfg_blob(cfg_id_t cfg_id, uint8_t **data, uint32_t *size);
+val_status_t val_target_get_config(cfg_id_t cfg_id, uint8_t **data, uint32_t *size);
+#endif
diff --git a/psa-ff/val/spe/pal_interfaces_s.h b/psa-ff/val/spe/pal_interfaces_s.h
new file mode 100644
index 0000000..a9edd70
--- /dev/null
+++ b/psa-ff/val/spe/pal_interfaces_s.h
@@ -0,0 +1,93 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#ifndef _VAL_PAL_INTERFACE_APIS_H_
+#define _VAL_PAL_INTERFACE_APIS_H_
+
+
+#include "val/common/val.h"
+
+/* Peripherals APIs */
+
+/*
+ @brief - This function initializes the uart
+ @param - uart_base_addr : Base address of the UART
+ @return -
+*/
+void pal_uart_init(addr_t uart_base_addr);
+
+/*
+ @brief - This function parses the input string and writes byte by byte to print
+ the input string
+ @param - str : Input String
+ - data : Value for Format specifier
+ @return - void
+ */
+void pal_print(char *str, uint32_t data);
+
+/**
+ @brief - Initializes an hardware watchdog timer
+ @param - base_addr : Base address of the watchdog module
+ - time_us : Time in micro seconds
+ - timer_tick_us : Number of ticks per micro second
+ @return - SUCCESS/FAILURE
+**/
+int pal_wd_timer_init(addr_t base_addr, uint32_t time_us, uint32_t timer_tick_us);
+
+/**
+ @brief - Enables a hardware watchdog timer
+ @param - base_addr : Base address of the watchdog module
+ @return - SUCCESS/FAILURE
+**/
+int pal_wd_timer_enable(addr_t base_addr);
+
+/**
+ @brief - Disables a hardware watchdog timer
+ @param - base_addr : Base address of the watchdog module
+ @return - SUCCESS/FAILURE
+**/
+int pal_wd_timer_disable(addr_t base_addr);
+
+
+/**
+ @brief - Checks whether hardware watchdog timer is enabled
+ @param - base_addr : Base address of the watchdog module
+ @return - Enabled : 1, Disabled : 0
+**/
+int pal_wd_timer_is_enabled(addr_t base_addr);
+
+/*
+ @brief - Writes 'size' bytes from buffer into non-volatile memory at a given 'base + offset'
+ @param - base : Base address of NV MEM
+ - offset : Offset
+ - buffer : Pointer to source address
+ - size : Number of bytes
+ @return - error status 0:SUCCESS, 1:FAIL
+*/
+int pal_nvmem_write(addr_t base, uint32_t offset, void *buffer, int size);
+
+/*
+ @brief - Reads 'size' bytes from non-volatile memory at a given
+ 'base + offset' into given buffer
+ @param - base : Base address of NV MEM
+ - offset : Offset
+ - buffer : Pointer to source address
+ - size : Number of bytes
+ @return - error status 0:SUCCESS, 1:FAIL
+*/
+int pal_nvmem_read(addr_t base, uint32_t offset, void *buffer, int size);
+#endif
diff --git a/psa-ff/val/spe/val_driver_service_apis.c b/psa-ff/val/spe/val_driver_service_apis.c
new file mode 100644
index 0000000..ba56f3d
--- /dev/null
+++ b/psa-ff/val/spe/val_driver_service_apis.c
@@ -0,0 +1,142 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+
+#include "val_driver_service_apis.h"
+
+print_verbosity_t g_print_level = PRINT_INFO;
+
+/* UART APIs */
+/*
+ @brief - Initialise the UART
+ @param - uart_base_addr: address of the uart base
+ @param - print_level: g_print_level verbosity
+ @return - val_status_t
+*/
+val_status_t val_uart_init_sf(addr_t uart_base_addr, print_verbosity_t print_level)
+{
+ val_status_t status;
+
+ g_print_level = print_level;
+ status = VAL_STATUS_SUCCESS;
+ pal_uart_init(uart_base_addr);
+ return status;
+}
+/*
+ @brief - This function parses the input string and writes byte by byte to
+ print the input string
+ @param - pointer : Input String
+ - data : Value for Format specifier
+ @return - error status
+ */
+val_status_t val_print_sf(print_verbosity_t verbosity, char *string, uint32_t data)
+{
+ if (verbosity >= g_print_level)
+ {
+ pal_print(string, data);
+ }
+ return VAL_STATUS_SUCCESS;
+}
+
+/* Watchdog APIs */
+/**
+ @brief - Initializes the WatchDog Timer instance
+ @param - base address of the given timer instance
+ - time_us : Time in micro seconds
+ - timer_tick_us : Number of ticks per micro second
+ @return - error status
+**/
+val_status_t val_wd_timer_init_sf(addr_t base_addr, uint32_t time_us, uint32_t timer_tick_us)
+{
+ return pal_wd_timer_init(base_addr, time_us, timer_tick_us);
+}
+
+/**
+ @brief - Enable WatchDog Timer instance
+ @param - base address of the given timer instance
+ @return - error status
+**/
+val_status_t val_wd_timer_enable_sf(addr_t base_addr)
+{
+ return pal_wd_timer_enable(base_addr);
+}
+
+/**
+ @brief - Disable Watch Dog Timer instance
+ @param - base address of the given timer instance
+ @return - error status
+**/
+val_status_t val_wd_timer_disable_sf(addr_t base_addr)
+{
+ return pal_wd_timer_disable(base_addr);
+}
+
+/**
+ @brief - Checks if watchdog enabled
+ @param - base address of the given timer instance
+ @return - error status
+**/
+val_status_t val_is_wd_timer_enabled_sf(addr_t base_addr)
+{
+ if (pal_wd_timer_is_enabled(base_addr))
+ {
+ return VAL_STATUS_SUCCESS;
+ }
+ else
+ {
+ return VAL_STATUS_ERROR;
+ }
+}
+
+/*
+ @brief - Reads 'size' bytes from Non-volatile memory at a given 'base + offset'
+ into given buffer.
+ - offset : Offset from NV MEM base address
+ - buffer : Pointer to source address
+ - size : Number of bytes
+ @return - val_status_t
+*/
+val_status_t val_nvmem_read_sf(addr_t base, uint32_t offset, void *buffer, int size)
+{
+ if (pal_nvmem_read(base, offset, buffer, size))
+ {
+ return VAL_STATUS_SUCCESS;
+ }
+ else
+ {
+ return VAL_STATUS_ERROR;
+ }
+}
+
+/*
+ @brief - Writes 'size' bytes from buffer into non-volatile memory at a given 'base + offset'
+ - offset : Offset
+ - buffer : Pointer to source address
+ - size : Number of bytes
+ @return - val_status_t
+*/
+val_status_t val_nvmem_write_sf(addr_t base, uint32_t offset, void *buffer, int size)
+{
+ if (pal_nvmem_write(base, offset, buffer, size))
+ {
+ return VAL_STATUS_SUCCESS;
+ }
+ else
+ {
+ return VAL_STATUS_ERROR;
+ }
+}
diff --git a/psa-ff/val/spe/val_driver_service_apis.h b/psa-ff/val/spe/val_driver_service_apis.h
new file mode 100644
index 0000000..066a859
--- /dev/null
+++ b/psa-ff/val/spe/val_driver_service_apis.h
@@ -0,0 +1,41 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#ifndef _VAL_DRIVER_PARTITION_APIS_H_
+#define _VAL_DRIVER_PARTITION_APIS_H_
+
+#include "val/common/val.h"
+#include "val/common/val_client_defs.h"
+#include "val_service_defs.h"
+#include "pal_interfaces_s.h"
+
+/* <manifestfilename.h> Manifest definitions. Only accessible to Secure Partition.
+ * The file name is based on the name of the Secure Partitions manifest file.
+ * The name must not collide with other header files.
+ * Compliance tests expect the below manifest output files implementation from build tool.
+ */
+#include "driver_partition_psa.h"
+
+val_status_t val_uart_init_sf(addr_t uart_base_addr, print_verbosity_t print_level);
+val_status_t val_print_sf(print_verbosity_t verbosity, char *string, uint32_t data);
+val_status_t val_wd_timer_init_sf(addr_t base_addr, uint32_t time_us, uint32_t timer_tick_us);
+val_status_t val_wd_timer_enable_sf(addr_t base_addr);
+val_status_t val_wd_timer_disable_sf(addr_t base_addr);
+val_status_t val_is_wd_timer_enabled_sf(addr_t base_addr);
+val_status_t val_nvmem_read_sf(addr_t base, uint32_t offset, void *buffer, int size);
+val_status_t val_nvmem_write_sf(addr_t base, uint32_t offset, void *buffer, int size);
+#endif
diff --git a/psa-ff/val/spe/val_partition_common.h b/psa-ff/val/spe/val_partition_common.h
new file mode 100644
index 0000000..25a32c9
--- /dev/null
+++ b/psa-ff/val/spe/val_partition_common.h
@@ -0,0 +1,496 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+/* Note- This file contains the functions and variables definition which are common to
+ all partitions defined by acs. These functions and variables are declared with static
+ keyword because some fully isolated system may not allow to share code and data segment
+ between partitions and static will help each partition to have its own copy of code and data.
+ Moreover it can prevents symbol names conflict if these functions are separately compiled and
+ linked with each of partitions in fully isolated environment.
+*/
+
+#ifndef _VAL_COMMON_SP_APIS_H_
+#define _VAL_COMMON_SP_APIS_H_
+
+#include "val/common/val.h"
+#include "val_service_defs.h"
+
+/* <manifestfilename.h> Manifest definitions. Only accessible to Secure Partition.
+ * The file name is based on the name of the Secure Partitions manifest file.
+ * The name must not collide with other header files.
+ * Compliance tests expect the below manifest output files implementation from build tool.
+ */
+#include "client_partition_psa.h"
+#include "server_partition_psa.h"
+
+__UNUSED STATIC_DECLARE val_status_t val_print
+ (print_verbosity_t verbosity, char *string, uint32_t data);
+__UNUSED STATIC_DECLARE val_status_t val_ipc_connect
+ (uint32_t sid, uint32_t minor_version, psa_handle_t *handle );
+__UNUSED STATIC_DECLARE val_status_t val_ipc_call
+ (psa_handle_t handle, psa_invec *in_vec, size_t in_len,
+ psa_outvec *out_vec, size_t out_len);
+__UNUSED STATIC_DECLARE void val_ipc_close
+ (psa_handle_t handle);
+__UNUSED STATIC_DECLARE val_status_t val_process_connect_request(psa_signal_t sig, psa_msg_t *msg);
+__UNUSED STATIC_DECLARE val_status_t val_process_call_request(psa_signal_t sig, psa_msg_t *msg);
+__UNUSED STATIC_DECLARE val_status_t val_process_disconnect_request
+ (psa_signal_t sig, psa_msg_t *msg);
+__UNUSED STATIC_DECLARE val_status_t val_execute_secure_tests
+ (uint32_t test_num, client_test_t *tests_list);
+__UNUSED STATIC_DECLARE val_status_t val_execute_secure_test_func
+ (psa_handle_t *handle, test_info_t test_info, uint32_t sid);
+__UNUSED STATIC_DECLARE val_status_t val_get_secure_test_result(psa_handle_t *handle);
+__UNUSED STATIC_DECLARE val_status_t val_err_check_set(uint32_t checkpoint, val_status_t status);
+__UNUSED STATIC_DECLARE val_status_t val_nvmem_write(uint32_t offset, void *buffer, int size);
+__UNUSED STATIC_DECLARE val_status_t val_set_boot_flag(boot_state_t state);
+
+__UNUSED static val_api_t val_api = {
+ .print = val_print,
+ .err_check_set = val_err_check_set,
+ .execute_secure_test_func = val_execute_secure_test_func,
+ .get_secure_test_result = val_get_secure_test_result,
+ .ipc_connect = val_ipc_connect,
+ .ipc_call = val_ipc_call,
+ .ipc_close = val_ipc_close,
+ .set_boot_flag = val_set_boot_flag,
+};
+
+__UNUSED static psa_api_t psa_api = {
+ .framework_version = psa_framework_version,
+ .version = psa_version,
+ .connect = psa_connect,
+ .call = psa_call,
+ .close = psa_close,
+};
+
+/**
+ @brief - Print module. This is client interface API of secure partition
+ val_print_sf API for spe world
+ @param - verbosity: Print verbosity level
+ - string : Input string
+ - data : Value for format specifier
+ @return - val_status_t
+**/
+STATIC_DECLARE val_status_t val_print(print_verbosity_t verbosity, char *string, uint32_t data)
+{
+ int string_len = 0;
+ char *p = string;
+ psa_handle_t print_handle = 0;
+ psa_status_t status_of_call = PSA_SUCCESS;
+ val_status_t status = VAL_STATUS_SUCCESS;
+
+ while (*p != '\0')
+ {
+ string_len++;
+ p++;
+ }
+
+ psa_invec data1[3] = {{&verbosity, 4}, {string, string_len+1}, {&data, 4}};
+ print_handle = psa_connect(DRIVER_UART_SID, 0);
+
+ if (print_handle < 0)
+ {
+ return VAL_STATUS_CONNECTION_FAILED;
+ }
+ else
+ {
+ status_of_call = psa_call(print_handle, data1, 3, NULL, 0);
+ if (status_of_call != PSA_SUCCESS)
+ {
+ status = VAL_STATUS_CALL_FAILED;
+ }
+ }
+ psa_close(print_handle);
+ return status;
+}
+
+/**
+ * @brief Connect to given sid
+ @param -sid : RoT service id
+ @param -minor_version : minor_version of RoT service
+ @param -handle - return connection handle
+ * @return val_status_t
+ */
+STATIC_DECLARE val_status_t val_ipc_connect(uint32_t sid, uint32_t minor_version,
+ psa_handle_t *handle )
+{
+ *handle = psa_connect(sid, minor_version);
+
+ if (*handle < 0)
+ {
+ return(VAL_STATUS_CONNECTION_FAILED);
+ }
+
+ return VAL_STATUS_SUCCESS;
+}
+
+/**
+ * @brief Call a connected Root of Trust Service.@n
+ * The caller must provide an array of ::psa_invec_t structures as the input payload.
+ * @param handle: Handle for the connection.
+ * @param in_vec: Array of psa_invec structures.
+ * @param in_len: Number of psa_invec structures in in_vec.
+ * @param out_vec: Array of psa_outvec structures for optional Root of Trust Service response.
+ * @param out_len: Number of psa_outvec structures in out_vec.
+ * @return val_status_t
+ */
+STATIC_DECLARE val_status_t val_ipc_call(psa_handle_t handle, psa_invec *in_vec, size_t in_len,
+ psa_outvec *out_vec, size_t out_len)
+{
+ psa_status_t call_status = PSA_SUCCESS;
+
+ call_status = psa_call(handle, in_vec, in_len, out_vec, out_len);
+
+ if (call_status != PSA_SUCCESS)
+ {
+ return(VAL_STATUS_CALL_FAILED);
+ }
+
+ return VAL_STATUS_SUCCESS;
+}
+
+/**
+ * @brief Close a connection to a Root of Trust Service.
+ * Sends the PSA_IPC_DISCONNECT message to the Root of Trust Service so
+ it can clean up resources.
+ * @param handle: Handle for the connection.
+ * @return void
+ */
+STATIC_DECLARE void val_ipc_close(psa_handle_t handle)
+{
+ psa_close(handle);
+}
+
+/**
+ * @brief Proccess a generic connect message to given rot signal.
+ @param -sig : signal to be processed
+ @param -msg : return msg info of given signal
+ * @return val_status_t.
+ */
+STATIC_DECLARE val_status_t val_process_connect_request(psa_signal_t sig, psa_msg_t *msg)
+{
+ val_status_t res = VAL_STATUS_ERROR;
+ psa_signal_t signals;
+
+wait1:
+ signals = psa_wait_any(PSA_BLOCK);
+ if (signals & sig)
+ {
+ if (psa_get(sig, msg) != PSA_SUCCESS)
+ {
+ goto wait1;
+ }
+
+ if ((msg->type != PSA_IPC_CONNECT) || (msg->handle <= 0))
+ {
+ val_print(PRINT_ERROR, "\npsa_get failed for PSA_IPC_CONNECT", 0);
+ res = VAL_STATUS_ERROR;
+ }
+ else
+ {
+ res = VAL_STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ val_print(PRINT_ERROR, "\npsa_wait_any returned with invalid signal value = 0x%x", signals);
+ res = VAL_STATUS_ERROR;
+ }
+ return res;
+}
+
+/**
+ * @brief Proccess a generic call message to given rot signal.
+ @param -sig : signal to be processed
+ @param -msg : return msg info of given signal
+ * @return val_status_t
+ */
+STATIC_DECLARE val_status_t val_process_call_request(psa_signal_t sig, psa_msg_t *msg)
+{
+ val_status_t res = VAL_STATUS_ERROR;
+ psa_signal_t signals;
+
+wait2:
+ signals = psa_wait_any(PSA_BLOCK);
+ if (signals & sig)
+ {
+ if (psa_get(sig, msg) != PSA_SUCCESS)
+ {
+ goto wait2;
+ }
+
+ if ((msg->type != PSA_IPC_CALL) || (msg->handle <= 0))
+ {
+ val_print(PRINT_ERROR, "\npsa_get failed for PSA_IPC_CALL", 0);
+ res = VAL_STATUS_ERROR;
+ }
+ else
+ {
+ res = VAL_STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ val_print(PRINT_ERROR, "\npsa_wait_any returned with invalid signal value = 0x%x", signals);
+ res = VAL_STATUS_ERROR;
+ }
+ return res;
+}
+
+/**
+ * @brief Proccess a generic disconnect message to given rot signal.
+ @param -sig : signal to be processed
+ @param -msg : return msg info of given signal
+ * @return val_status_t
+ */
+STATIC_DECLARE val_status_t val_process_disconnect_request(psa_signal_t sig, psa_msg_t *msg)
+{
+ val_status_t res = VAL_STATUS_ERROR;
+ psa_signal_t signals;
+
+wait3:
+ signals = psa_wait_any(PSA_BLOCK);
+ if (signals & sig)
+ {
+ if (psa_get(sig, msg) != PSA_SUCCESS)
+ {
+ goto wait3;
+ }
+
+ if ((msg->type != PSA_IPC_DISCONNECT) || (msg->handle <= 0))
+ {
+ val_print(PRINT_ERROR, "\npsa_get failed for PSA_IPC_DISCONNECT", 0);
+ res = VAL_STATUS_ERROR;
+ }
+ else
+ {
+ res = VAL_STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ val_print(PRINT_ERROR, "\npsa_wait_any returned with invalid signal value = 0x%x", signals);
+ res = VAL_STATUS_ERROR;
+ }
+ return res;
+}
+
+/**
+ @brief - This function executes given list of tests from secure sequentially
+ This covers secure to secure IPC API scenario
+ @param - test_num : Test_num
+ @param - tests_list : list of tests to be executed
+ @return - val_status_t
+**/
+STATIC_DECLARE val_status_t val_execute_secure_tests(uint32_t test_num, client_test_t *tests_list)
+{
+ val_status_t status = VAL_STATUS_SUCCESS;
+ val_status_t test_status = VAL_STATUS_SUCCESS;
+ psa_handle_t handle;
+ int i = 1;
+ test_info_t test_info;
+
+ test_info.test_num = test_num;
+ val_print(PRINT_TEST, "[Info] Executing tests form secure\n", 0);
+
+ while (tests_list[i] != NULL)
+ {
+
+ /* Handshake with server tests */
+ test_info.block_num = i;
+ status = val_execute_secure_test_func(&handle, test_info, SERVER_TEST_DISPATCHER_SID);
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR,"[Check%d] START\n", i);
+ return status;
+ }
+ else
+ {
+ val_print(PRINT_DEBUG,"[Check%d] START\n", i);
+ }
+
+ /* Execute client tests */
+ test_status = tests_list[i](SECURE);
+
+ /* Retrive Server test status */
+ status = val_get_secure_test_result(&handle);
+
+ status = test_status ? test_status:status;
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR,"[Check%d] FAILED\n", i);
+ return status;
+ }
+ else
+ {
+ val_print(PRINT_DEBUG,"[Check%d] PASSED\n", i);
+ }
+ i++;
+ }
+ return status;
+}
+
+/**
+ @brief - This function is used to handshake between:
+ - nonsecure client to server test fn
+ - secure client and server test fn
+ - nonsecure client to secure client test fn
+ @param - handle : handle returned while connecting given sid
+ @param - test_info : Test_num and block_num to be executed
+ @param - sid : RoT service to be connected. Partition dispatcher sid
+ @return - val_status_t
+**/
+STATIC_DECLARE val_status_t val_execute_secure_test_func(psa_handle_t *handle,
+ test_info_t test_info,
+ uint32_t sid)
+{
+ uint32_t test_data;
+ val_status_t status = VAL_STATUS_SUCCESS;
+ psa_status_t status_of_call = PSA_SUCCESS;
+
+ *handle = psa_connect(sid, 0);
+
+ if (*handle < 0)
+ {
+ val_print(PRINT_ERROR, "Could not connect SID. Handle=%x\n", *handle);
+ status = VAL_STATUS_CONNECTION_FAILED;
+ }
+
+ test_data = ((uint32_t)(test_info.test_num) | ((uint32_t)(test_info.block_num) << BLOCK_NUM_POS)
+ | ((uint32_t)(TEST_EXECUTE_FUNC) << ACTION_POS));
+ psa_invec data[1] = {{&test_data, sizeof(test_data)}};
+
+ status_of_call = psa_call(*handle, data, 1, NULL, 0);
+
+ if (status_of_call != PSA_SUCCESS)
+ {
+ status = VAL_STATUS_CALL_FAILED;
+ val_print(PRINT_ERROR, "Call to dispatch SF failed. Status=%x\n", status_of_call);
+ psa_close(*handle);
+ }
+ return status;
+}
+
+/**
+ @brief - This function is used to retrive the status of previously connected test function
+ using val_execute_secure_test_func
+ @param - handle : handle of server function. Handle of Partition dispatcher sid
+ @return - The status of test functions
+**/
+STATIC_DECLARE val_status_t val_get_secure_test_result(psa_handle_t *handle)
+{
+ uint32_t test_data;
+ val_status_t status = VAL_STATUS_SUCCESS;
+ psa_status_t status_of_call = PSA_SUCCESS;
+
+ test_data = (TEST_RETURN_RESULT << ACTION_POS);
+
+ psa_outvec resp = {&status, sizeof(status)};
+ psa_invec data[1] = {{&test_data, sizeof(test_data)}};
+
+ status_of_call = psa_call(*handle, data, 1, &resp, 1);
+ if (status_of_call != PSA_SUCCESS)
+ {
+ status = VAL_STATUS_CALL_FAILED;
+ val_print(PRINT_ERROR, "Call to dispatch SF failed. Status=%x\n", status_of_call);
+ }
+
+ psa_close(*handle);
+ return status;
+}
+
+/*
+ @brief - This function checks if the input status argument is an error.
+ On error, print the checkpoint value
+ @param - checkpoint : Test debug checkpoint
+ - val_status_t : Test status
+ @return - returns the input status back to the program.
+*/
+STATIC_DECLARE val_status_t val_err_check_set(uint32_t checkpoint, val_status_t status)
+{
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "\tCheckpoint %d : ", checkpoint);
+ val_print(PRINT_ERROR, "Error Code=0x%x \n", status);
+ }
+ else
+ {
+ val_print(PRINT_DEBUG, "\tCheckpoint %d \n", checkpoint);
+ }
+ return status;
+}
+
+/*
+ @brief - Writes 'size' bytes from buffer into non-volatile memory at a given
+ 'base + offset'. This is client interface API of secure partition
+ val_nvmem_write_sf API for spe world
+ - offset : Offset
+ - buffer : Pointer to source address
+ - size : Number of bytes
+ @return - val_status_t
+*/
+STATIC_DECLARE val_status_t val_nvmem_write(uint32_t offset, void *buffer, int size)
+{
+ nvmem_param_t nvmem_param;
+ psa_handle_t handle = 0;
+ psa_status_t status_of_call = PSA_SUCCESS;
+
+ nvmem_param.nvmem_fn_type = NVMEM_WRITE;
+ nvmem_param.offset = offset;
+ nvmem_param.size = size;
+ psa_invec invec[2] = {{&nvmem_param, sizeof(nvmem_param)}, {buffer, size}};
+
+ handle = psa_connect(DRIVER_NVMEM_SID, 0);
+ if (handle < 0)
+ {
+ return VAL_STATUS_CONNECTION_FAILED;
+ }
+ else
+ {
+ status_of_call = psa_call(handle, invec, 2, NULL, 0);
+ if (status_of_call != PSA_SUCCESS)
+ {
+ psa_close(handle);
+ return VAL_STATUS_CALL_FAILED;
+ }
+ }
+ psa_close(handle);
+ return VAL_STATUS_SUCCESS;
+}
+
+/**
+ @brief - This function sets the given boot.state value to corresponding
+ boot NVMEM location
+ @param - state: boot_state_t
+ @return - val_status_t
+**/
+STATIC_DECLARE val_status_t val_set_boot_flag(boot_state_t state)
+{
+ boot_t boot;
+ val_status_t status;
+
+ boot.state = state;
+ status = val_nvmem_write(VAL_NVMEM_OFFSET(NV_BOOT), &boot, sizeof(boot_t));
+ if (VAL_ERROR(status))
+ {
+ val_print(PRINT_ERROR, "val_nvmem_write failed Error=0x%x\n", status);
+ return status;
+ }
+ return status;
+}
+#endif
diff --git a/psa-ff/val/spe/val_service_defs.h b/psa-ff/val/spe/val_service_defs.h
new file mode 100644
index 0000000..6a0e03d
--- /dev/null
+++ b/psa-ff/val/spe/val_service_defs.h
@@ -0,0 +1,104 @@
+/** @file
+ * Copyright (c) 2018, Arm Limited or its affiliates. All rights reserved.
+ * SPDX-License-Identifier : Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+**/
+
+#ifndef _VAL_PSA_SERVICE_H_
+#define _VAL_PSA_SERVICE_H_
+
+/***************** PSA Secure Function API *****************/
+
+/* Note - This header file containts the declaration of PSA defined secure partition service API
+ elements. Ideally, These elements must be defined in a header file <psa_service.h> by SPM
+ implemented library and provided to clients operation in NSPE and SPE as per the specification.
+ If this is available in the platform, the elements declared as part of this
+ file can be overwritten by passing --include <path_to_psa_service_h> to setup.sh script.
+ */
+
+#if 1
+/* <psa_service.h>: Secure Partition API elements. Only accessible to Secure Partition */
+#include "psa_service.h"
+
+#else
+#include "val/common/val.h"
+
+#define PSA_POLL 0x00000000U
+#define PSA_BLOCK 0x80000000U
+#define PSA_DOORBELL 0x00000008U
+#define PSA_IPC_CONNECT 1
+#define PSA_IPC_CALL 2
+#define PSA_IPC_DISCONNECT 3
+#define PSA_MAX_IOVEC 4
+#define PSA_ERR_NOMSG (INT32_MIN + 3)
+
+typedef uint32_t psa_signal_t;
+typedef struct psa_msg_t psa_msg_t;
+
+typedef struct psa_msg_t {
+ uint32_t type;
+ psa_handle_t handle;
+ int32_t client_id;
+ void *rhandle;
+ size_t in_size[PSA_MAX_IOVEC];
+ size_t out_size[PSA_MAX_IOVEC];
+} psa_msg_t;
+
+
+/* The implementation for following PSA service APIs should come from SPM */
+psa_signal_t psa_wait_any(uint32_t timeout);
+psa_signal_t psa_wait_interrupt(psa_signal_t signal_mask, uint32_t timeout);
+void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle);
+psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg);
+size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
+ void *buffer, size_t num_bytes);
+size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx,
+ size_t num_bytes);
+void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
+ const void *buffer, size_t num_bytes);
+void psa_reply(psa_handle_t msg_handle, psa_status_t status);
+void psa_notify(int32_t partition_id);
+void psa_clear(psa_signal_t doorbell_signal);
+void psa_eoi(psa_signal_t irq_signal);
+#endif /* #if 1 */
+
+/* struct of function pointers to uniqify nspe and spe client interface for test */
+typedef struct {
+ uint32_t (*framework_version) (void);
+ uint32_t (*version) (uint32_t sid);
+ psa_handle_t (*connect) (uint32_t sid, uint32_t minor_version);
+ psa_status_t (*call) (psa_handle_t handle,
+ const psa_invec *in_vec,
+ size_t in_len,
+ psa_outvec *out_vec,
+ size_t out_len
+ );
+ psa_status_t (*close) (psa_handle_t handle);
+} psa_api_t;
+
+typedef struct {
+ val_status_t (*print) (print_verbosity_t verbosity,
+ char *string, uint32_t data);
+ val_status_t (*err_check_set) (uint32_t checkpoint, val_status_t status);
+ val_status_t (*execute_secure_test_func) (psa_handle_t *handle, test_info_t test_info,
+ uint32_t sid);
+ val_status_t (*get_secure_test_result) (psa_handle_t *handle);
+ val_status_t (*ipc_connect) (uint32_t sid, uint32_t minor_version,
+ psa_handle_t *handle );
+ val_status_t (*ipc_call) (psa_handle_t handle, psa_invec *in_vec,
+ size_t in_len, psa_outvec *out_vec, size_t out_len);
+ void (*ipc_close) (psa_handle_t handle);
+ val_status_t (*set_boot_flag) (boot_state_t state);
+} val_api_t;
+#endif