Platform: Add NS NV counters

Add a configurable amount of NS NV counters (up to 3), and expose them
to the NS caller.

Change-Id: I8adda25c1fae49c4dae36ccb562360f45ecbfc0a
Signed-off-by: Raef Coles <raef.coles@arm.com>
diff --git a/interface/src/tfm_platform_ipc_api.c b/interface/src/tfm_platform_ipc_api.c
index 0c1edf4..072e243 100644
--- a/interface/src/tfm_platform_ipc_api.c
+++ b/interface/src/tfm_platform_ipc_api.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -27,7 +27,7 @@
     if (status < PSA_SUCCESS) {
         return TFM_PLATFORM_ERR_SYSTEM_ERROR;
     } else {
-        return (enum tfm_platform_err_t) status;
+        return (enum tfm_platform_err_t)status;
     }
 
 }
@@ -72,7 +72,67 @@
     if (status < PSA_SUCCESS) {
         return TFM_PLATFORM_ERR_SYSTEM_ERROR;
     } else {
-        return (enum tfm_platform_err_t) status;
+        return (enum tfm_platform_err_t)status;
     }
 }
 
+enum tfm_platform_err_t
+tfm_platform_nv_counter_increment(uint32_t counter_id)
+{
+    psa_status_t status = PSA_ERROR_CONNECTION_REFUSED;
+    psa_handle_t handle = PSA_NULL_HANDLE;
+    struct psa_invec in_vec[1];
+
+    in_vec[0].base = &counter_id;
+    in_vec[0].len = sizeof(counter_id);
+
+    handle = psa_connect(TFM_SP_PLATFORM_NV_COUNTER_SID,
+                         TFM_SP_PLATFORM_NV_COUNTER_VERSION);
+    if (handle <= 0) {
+        return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+    }
+
+    status = psa_call(handle, TFM_PLATFORM_API_ID_NV_INCREMENT,
+                      in_vec, 1, (psa_outvec *)NULL, 0);
+
+    psa_close(handle);
+
+    if (status < PSA_SUCCESS) {
+        return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+    } else {
+        return (enum tfm_platform_err_t)status;
+    }
+}
+
+enum tfm_platform_err_t
+tfm_platform_nv_counter_read(uint32_t counter_id,
+                             uint32_t size, uint8_t *val)
+{
+    psa_status_t status = PSA_ERROR_CONNECTION_REFUSED;
+    psa_handle_t handle = PSA_NULL_HANDLE;
+    struct psa_invec in_vec[1];
+    struct psa_outvec out_vec[1];
+
+    in_vec[0].base = &counter_id;
+    in_vec[0].len = sizeof(counter_id);
+
+    out_vec[0].base = val;
+    out_vec[0].len = size;
+
+    handle = psa_connect(TFM_SP_PLATFORM_NV_COUNTER_SID,
+                         TFM_SP_PLATFORM_NV_COUNTER_VERSION);
+    if (handle <= 0) {
+        return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+    }
+
+    status = psa_call(handle, TFM_PLATFORM_API_ID_NV_READ,
+                      in_vec, 1, out_vec, 1);
+
+    psa_close(handle);
+
+    if (status < PSA_SUCCESS) {
+        return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+    } else {
+        return (enum tfm_platform_err_t)status;
+    }
+}