Tests: Two secure partitions

Test set-up with two secure partitions, communicating via direct
messaging.

Change-Id: I0eb631ebcf20eb192d6934e66acdac585d38da06
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/test/hftest/BUILD.gn b/test/hftest/BUILD.gn
index 9f04bd8..86a9ec2 100644
--- a/test/hftest/BUILD.gn
+++ b/test/hftest/BUILD.gn
@@ -54,6 +54,30 @@
   ]
 }
 
+source_set("hftest_secure_service") {
+  testonly = true
+
+  public_configs = [
+    "//src/arch/aarch64:arch_config",
+    ":hftest_config",
+  ]
+
+  sources = [
+    "secure_service.c",
+  ]
+
+  deps = [
+    ":mm",
+    "//src:dlog",
+    "//src:panic",
+    "//src:std",
+    "//src/arch/${plat_arch}:entry",
+    "//src/arch/${plat_arch}/hftest:entry",
+    "//src/arch/${plat_arch}/hftest:power_mgmt",
+    "//vmlib/${plat_arch}:call",
+  ]
+}
+
 # Testing framework for a secondary VM. This framework doesn't provide services
 # and expects that secondary VMs will be passed the memory size in register x0
 # instead of a pointer to the FDT.
diff --git a/test/hftest/secure_service.c b/test/hftest/secure_service.c
new file mode 100644
index 0000000..4cd1fbf
--- /dev/null
+++ b/test/hftest/secure_service.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2021 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 <stdalign.h>
+#include <stdint.h>
+
+#include "hf/ffa.h"
+#include "hf/mm.h"
+#include "hf/std.h"
+
+#include "vmapi/hf/call.h"
+
+#include "test/hftest.h"
+
+alignas(4096) uint8_t kstack[4096];
+
+HFTEST_ENABLE();
+
+static struct hftest_context global_context;
+
+struct hftest_context *hftest_get_context(void)
+{
+	return &global_context;
+}
+
+void test_main_sp(void);
+
+noreturn void abort(void)
+{
+	HFTEST_LOG("Service contained failures.");
+	/* Cause a fault, as a secondary can't power down the machine. */
+	*((volatile uint8_t *)1) = 1;
+
+	/* This should never be reached, but to make the compiler happy... */
+	for (;;) {
+	}
+}
+
+noreturn void kmain(void)
+{
+	/*
+	 * Initialize the stage-1 MMU and identity-map the entire address space.
+	 */
+	if (!hftest_mm_init()) {
+		HFTEST_LOG_FAILURE();
+		HFTEST_LOG(HFTEST_LOG_INDENT "Memory initialization failed");
+		abort();
+	}
+
+	test_main_sp();
+
+	/* Do not expect to get to this point, so abort. */
+	abort();
+}