feat(hftest): add service endpoint helpers

Several helper utilities are added for service SPs. These will be
leveraged to build tests to exercise secure interrupt handling in
upcoming patches.

Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
Change-Id: I6368984a707c0ac35bc6a291849db183258ec16d
diff --git a/inc/vmapi/hf/call.h b/inc/vmapi/hf/call.h
index 3ec64dd..66e00a2 100644
--- a/inc/vmapi/hf/call.h
+++ b/inc/vmapi/hf/call.h
@@ -364,6 +364,16 @@
 }
 
 /**
+ * Deactivate the physical interrupt.
+ *
+ * Returns 0 on success, or -1 otherwise.
+ */
+static inline int64_t hf_interrupt_deactivate(uint32_t intid)
+{
+	return hf_call(HF_INTERRUPT_DEACTIVATE, intid, intid, 0);
+}
+
+/**
  * Injects a virtual interrupt of the given ID into the given target vCPU.
  * This doesn't cause the vCPU to actually be run immediately; it will be taken
  * when the vCPU is next run, which is up to the scheduler.
diff --git a/test/inc/test/vmapi/ffa.h b/test/inc/test/vmapi/ffa.h
index d02a0cc..c3bd68f 100644
--- a/test/inc/test/vmapi/ffa.h
+++ b/test/inc/test/vmapi/ffa.h
@@ -24,6 +24,19 @@
 		EXPECT_EQ(ffa_error_code(v), (ffa_error)); \
 	} while (0)
 
+#define SERVICE_PARTITION_INFO_GET(service_name, uuid)                         \
+	struct ffa_partition_info *service_name(void)                          \
+	{                                                                      \
+		static struct ffa_partition_info partition;                    \
+		static bool is_set = false;                                    \
+		if (!is_set) {                                                 \
+			ASSERT_EQ(get_ffa_partition_info(uuid, &partition, 1), \
+				  1);                                          \
+			is_set = true;                                         \
+		}                                                              \
+		return &partition;                                             \
+	}
+
 /*
  * The bit 15 of the FF-A ID indicates whether the partition is executing
  * in the normal world, in case it is a Virtual Machine (VM); or in the
diff --git a/test/vmapi/ffa_secure_partitions/BUILD.gn b/test/vmapi/ffa_secure_partitions/BUILD.gn
index fb70919..02394d7 100644
--- a/test/vmapi/ffa_secure_partitions/BUILD.gn
+++ b/test/vmapi/ffa_secure_partitions/BUILD.gn
@@ -8,10 +8,31 @@
 import("//test/hftest/args.gni")
 import("//src/arch/${plat_arch}/args.gni")
 
+config("config") {
+  include_dirs = [ "inc" ]
+}
+
+source_set("ffa_secure_partitions") {
+  testonly = true
+  public_configs = [
+    ":config",
+    "//src/arch/${plat_arch}:config",
+  ]
+
+  sources = [
+    "ffa_secure_partitions.c",
+  ]
+
+  deps = [
+    "//test/vmapi/common",
+  ]
+}
+
 # VM that will control execution of tests in a VM-to-SP set-up
 vm_kernel("vm_primary") {
   testonly = true
   public_configs = [
+    ":config",
     "services/arch/${plat_arch}/secure:config",
     "//src/arch/${plat_arch}:arch_config",
   ]
@@ -26,6 +47,7 @@
   ]
 
   deps = [
+    ":ffa_secure_partitions",
     "//src/arch/${plat_arch}/hftest:interrupts_gicv3",
     "//src/arch/${plat_arch}/hftest:power_mgmt",
     "//test/hftest:hftest_primary_vm",
diff --git a/test/vmapi/ffa_secure_partitions/ffa_secure_partitions.c b/test/vmapi/ffa_secure_partitions/ffa_secure_partitions.c
new file mode 100644
index 0000000..8770803
--- /dev/null
+++ b/test/vmapi/ffa_secure_partitions/ffa_secure_partitions.c
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2023 The Hafnium Authors.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/BSD-3-Clause.
+ */
+
+#include "ffa_secure_partitions.h"
+
+SERVICE_PARTITION_INFO_GET(service1, SERVICE1)
+SERVICE_PARTITION_INFO_GET(service2, SERVICE2)
diff --git a/test/vmapi/ffa_secure_partitions/inc/ffa_secure_partitions.h b/test/vmapi/ffa_secure_partitions/inc/ffa_secure_partitions.h
new file mode 100644
index 0000000..918705d
--- /dev/null
+++ b/test/vmapi/ffa_secure_partitions/inc/ffa_secure_partitions.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 The Hafnium Authors.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/BSD-3-Clause.
+ */
+
+#pragma once
+
+#include "test/hftest.h"
+#include "test/vmapi/ffa.h"
+
+/*
+ * FF-A UUIDs related to the test partitions providing test services to the
+ * Primary VM. These service partitions can either be SPs or VMs, and should
+ * be used only once for either an SP or VM.
+ * This allows for the PVM to communicate with the service partition, regardless
+ * of the ID, which has a bit related to the security state of the partition.
+ * The PVM should use the UUID to retrieve the FF-A ID of the partition, before
+ * attempting to communicate with it. Thus, the code for the PVM becomes
+ * portable between setups where the test service is either a VM or an SP.
+ */
+#define SERVICE1                                                        \
+	&(struct ffa_uuid)                                              \
+	{                                                               \
+		{                                                       \
+			0x9458bb2d, 0x353b4ee2, 0xaa25710c, 0x99b73ddc, \
+		}                                                       \
+	}
+
+#define SERVICE2                                            \
+	&(struct ffa_uuid)                                  \
+	{                                                   \
+		{                                           \
+			0xa609f132, 0x6b4f, 0x4c14, 0x9489, \
+		}                                           \
+	}
+
+/*
+ * Helpers to get services information.
+ * Defined with SERVICE_PARTITION_INFO_GET macro.
+ */
+struct ffa_partition_info* service1(void);
+struct ffa_partition_info* service2(void);
diff --git a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/BUILD.gn b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/BUILD.gn
index 0b94be5..2f26bab 100644
--- a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/BUILD.gn
+++ b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/BUILD.gn
@@ -96,6 +96,17 @@
   ]
 }
 
+source_set("sp_helpers") {
+  testonly = true
+  public_configs = [
+    ":config",
+    "//src/arch/aarch64:arch_config",
+  ]
+  sources = [
+    "sp_helpers.c",
+  ]
+}
+
 # SP that will be controlled via communication/scheduling primitives by the
 # former SP
 vm_kernel("secure_partitions_services") {
@@ -105,6 +116,7 @@
   deps = [
     ":message_loop",
     ":sp805",
+    ":sp_helpers",
     "//src/arch/aarch64/hftest:interrupts",
     "//test/hftest:hftest_secure_service",
   ]
diff --git a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/el0/BUILD.gn b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/el0/BUILD.gn
index 2db73c7..7341342 100644
--- a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/el0/BUILD.gn
+++ b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/el0/BUILD.gn
@@ -13,10 +13,22 @@
   ]
 }
 
+source_set("sp_helpers") {
+  testonly = true
+  public_configs = [
+    ":config",
+    "//src/arch/aarch64:arch_config",
+  ]
+  sources = [
+    "sp_helpers.c",
+  ]
+}
+
 vm_kernel("sel0_partition") {
   testonly = true
 
   deps = [
+    ":sp_helpers",
     "//src/arch/aarch64/hftest/el0:interrupts",
     "//test/hftest:hftest_sel0_partition_base",
     "//test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure:message_loop",
diff --git a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/el0/sp_helpers.c b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/el0/sp_helpers.c
new file mode 100644
index 0000000..262fcf8
--- /dev/null
+++ b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/el0/sp_helpers.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2023 The Hafnium Authors.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/BSD-3-Clause.
+ */
+
+#include "sp_helpers.h"
+
+#include "partition_services.h"
+
+#define ITERATIONS_PER_MS 15000
+
+uint64_t sp_sleep_active_wait(uint32_t ms)
+{
+	sp_wait_loop(ms * ITERATIONS_PER_MS);
+	return ms;
+}
diff --git a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/inc/partition_services.h b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/inc/partition_services.h
index b0491ec..a2640e9 100644
--- a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/inc/partition_services.h
+++ b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/inc/partition_services.h
@@ -299,3 +299,10 @@
 
 struct ffa_value sp_check_state_transitions_cmd(ffa_vm_id_t test_source,
 						ffa_vm_id_t companion_sp);
+
+static inline void sp_wait_loop(uint32_t iterations)
+{
+	for (volatile uint64_t loop = 0; loop < iterations; loop++) {
+		/* Wait */
+	}
+}
diff --git a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/inc/sp_helpers.h b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/inc/sp_helpers.h
new file mode 100644
index 0000000..6bbbd42
--- /dev/null
+++ b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/inc/sp_helpers.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2023 The Hafnium Authors.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/BSD-3-Clause.
+ */
+
+#include <stdint.h>
+
+uint64_t sp_sleep_active_wait(uint32_t ms);
diff --git a/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/sp_helpers.c b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/sp_helpers.c
new file mode 100644
index 0000000..3ffd7fc
--- /dev/null
+++ b/test/vmapi/ffa_secure_partitions/services/arch/aarch64/secure/sp_helpers.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2023 The Hafnium Authors.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/BSD-3-Clause.
+ */
+
+#include "sp_helpers.h"
+
+#include "hf/arch/barriers.h"
+#include "hf/arch/irq.h"
+#include "hf/arch/vm/timer.h"
+
+static inline uint64_t virtualcounter_read(void)
+{
+	isb();
+	return read_msr(cntvct_el0);
+}
+
+uint64_t sp_sleep_active_wait(uint32_t ms)
+{
+	uint64_t timer_freq = read_msr(cntfrq_el0);
+
+	uint64_t time1 = virtualcounter_read();
+	volatile uint64_t time2 = time1;
+
+	while ((time2 - time1) < ((ms * timer_freq) / 1000U)) {
+		time2 = virtualcounter_read();
+	}
+
+	return ((time2 - time1) * 1000) / timer_freq;
+}
diff --git a/test/vmapi/primary_with_secondaries/inc/primary_with_secondary.h b/test/vmapi/primary_with_secondaries/inc/primary_with_secondary.h
index 2705170..af05048 100644
--- a/test/vmapi/primary_with_secondaries/inc/primary_with_secondary.h
+++ b/test/vmapi/primary_with_secondaries/inc/primary_with_secondary.h
@@ -44,19 +44,6 @@
 		}                                            \
 	}
 
-#define SERVICE_PARTITION_INFO_GET(service_name, uuid)                         \
-	struct ffa_partition_info* service_name(void)                          \
-	{                                                                      \
-		static struct ffa_partition_info partition;                    \
-		static bool is_set = false;                                    \
-		if (!is_set) {                                                 \
-			ASSERT_EQ(get_ffa_partition_info(uuid, &partition, 1), \
-				  1);                                          \
-			is_set = true;                                         \
-		}                                                              \
-		return &partition;                                             \
-	}
-
 /*
  * Helpers to get services information.
  * Defined with SERVICE_PARTITION_INFO_GET macro.