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