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/kokoro/test_spmc.sh b/kokoro/test_spmc.sh
index 6c8cc6e..809b9da 100755
--- a/kokoro/test_spmc.sh
+++ b/kokoro/test_spmc.sh
@@ -18,3 +18,4 @@
 HFTEST+=(--log "$LOG_DIR_BASE")
 
 ${HFTEST[@]} hafnium --secure --driver=fvp --partitions_json test/vmapi/ffa_secure_partition_only/ffa_secure_partition_only_test.json
+${HFTEST[@]} hafnium --secure --driver=fvp --partitions_json test/vmapi/ffa_secure_partitions/ffa_secure_partitions_test.json
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();
+}
diff --git a/test/vmapi/BUILD.gn b/test/vmapi/BUILD.gn
index ac523d8..acdaa1b 100644
--- a/test/vmapi/BUILD.gn
+++ b/test/vmapi/BUILD.gn
@@ -14,6 +14,7 @@
     "arch/${plat_arch}:arch",
     "common:common",
     "ffa_secure_partition_only:ffa_secure_partition_only_test",
+    "ffa_secure_partitions:ffa_secure_partitions_test",
     "primary_only:primary_only_test",
     "primary_only_ffa:primary_only_ffa_test",
     "primary_with_secondaries:primary_with_secondaries_no_fdt",
diff --git a/test/vmapi/ffa_secure_partitions/BUILD.gn b/test/vmapi/ffa_secure_partitions/BUILD.gn
new file mode 100644
index 0000000..e45044c
--- /dev/null
+++ b/test/vmapi/ffa_secure_partitions/BUILD.gn
@@ -0,0 +1,88 @@
+# 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.
+
+import("//build/image/image.gni")
+import("//test/hftest/args.gni")
+
+# SP that will control execution of tests
+vm_kernel("secure_partitions_control") {
+  testonly = true
+
+  sources = [
+    "secure_partition_control.c",
+  ]
+
+  deps = [
+    "//test/hftest:hftest_standalone_secure",
+  ]
+}
+
+# SP that will be controlled via communication/scheduling primitives by the
+# former SP
+vm_kernel("secure_partitions_services") {
+  testonly = true
+
+  sources = [
+    "secure_partition_services.c",
+  ]
+
+  deps = [
+    "//test/hftest:hftest_secure_service",
+  ]
+}
+
+manifest("partition_manifest_control_sp") {
+  source = "partition_manifest_control_sp.dts"
+  output = "partition_manifest_control_sp.dtb"
+}
+
+manifest("secure_partition_services_manifest") {
+  source = "partition_manifest_services_sp.dts"
+  output = "partition_manifest_services_sp.dtb"
+}
+
+partition_package("secure_partition_control_test_package") {
+  testonly = true
+  files = [ [
+        "partition_manifest_control_sp.dtb",
+        "secure_partitions_control.bin",
+        ":partition_manifest_control_sp",
+        ":secure_partitions_control",
+      ] ]
+  output = "secure_partition_control_test_package.img"
+}
+
+partition_package("secure_partition_services_test_package") {
+  testonly = true
+  files = [ [
+        "partition_manifest_services_sp.dtb",
+        "secure_partitions_services.bin",
+        ":secure_partition_services_manifest",
+        ":secure_partitions_services",
+      ] ]
+  output = "secure_partition_services_test_package.img"
+}
+
+partitions_json("ffa_secure_partitions_test") {
+  testonly = true
+
+  sps = [
+    [
+      "secure_partition_control_test_package.img",
+      "manifest_control_sp.dts",
+      ":secure_partition_control_test_package",
+      ":partition_manifest_control_sp",
+    ],
+    [
+      "secure_partition_services_test_package.img",
+      "manifest_services_sp.dts",
+      ":secure_partition_services_test_package",
+      ":secure_partition_services_manifest",
+    ],
+  ]
+  vms = []
+  json_file = "ffa_secure_partitions_test.json"
+}
diff --git a/test/vmapi/ffa_secure_partitions/manifest_control_sp.dts b/test/vmapi/ffa_secure_partitions/manifest_control_sp.dts
new file mode 100644
index 0000000..e624764
--- /dev/null
+++ b/test/vmapi/ffa_secure_partitions/manifest_control_sp.dts
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/ {
+	hypervisor {
+		compatible = "hafnium,hafnium";
+		vm1 {
+			is_ffa_partition;
+			load_address = <0x6280000>;
+			debug_name = "ffa_secure_partition_control";
+			vcpu_count = <8>;
+			mem_size = <0x100000>;
+		};
+	};
+};
diff --git a/test/vmapi/ffa_secure_partitions/manifest_services_sp.dts b/test/vmapi/ffa_secure_partitions/manifest_services_sp.dts
new file mode 100644
index 0000000..5e5080d
--- /dev/null
+++ b/test/vmapi/ffa_secure_partitions/manifest_services_sp.dts
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/ {
+	hypervisor {
+		compatible = "hafnium,hafnium";
+		vm2 {
+			is_ffa_partition;
+			load_address = <0x6380000>;
+			debug_name = "ffa_secure_partition_services";
+			vcpu_count = <8>;
+			mem_size = <0x100000>;
+		};
+	};
+};
diff --git a/test/vmapi/ffa_secure_partitions/partition_manifest_control_sp.dts b/test/vmapi/ffa_secure_partitions/partition_manifest_control_sp.dts
new file mode 100644
index 0000000..ede9757
--- /dev/null
+++ b/test/vmapi/ffa_secure_partitions/partition_manifest_control_sp.dts
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/dts-v1/;
+
+/ {
+	compatible = "arm,ffa-manifest-1.0";
+	debug_name = "partition-manifest";
+
+	/* Properties */
+	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	uuid = <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>;
+	execution-ctx-count = <8>;
+	exception-level = <2>; /* S-EL1 */
+	execution-state = <0>; /* AARCH64 */
+	load-address = <0x6280000>;
+	entrypoint-offset = <0x1000>;
+	xlat-granule = <0>; /* 4KiB */
+	messaging-method = <0>; /* Direct messaging only */
+	boot-order = <1>; /* This partition is intended to be controlling the tests execution */
+
+	device-regions {
+		compatible = "arm,ffa-manifest-device-regions";
+
+		uart0 {
+			base-address = <0x00000000 0x1c090000>;
+			pages-count = <1>;
+			attributes = <0x3>; /* read-write */
+		};
+	};
+};
diff --git a/test/vmapi/ffa_secure_partitions/partition_manifest_services_sp.dts b/test/vmapi/ffa_secure_partitions/partition_manifest_services_sp.dts
new file mode 100644
index 0000000..eb33468
--- /dev/null
+++ b/test/vmapi/ffa_secure_partitions/partition_manifest_services_sp.dts
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+/dts-v1/;
+
+/ {
+	compatible = "arm,ffa-manifest-1.0";
+	debug_name = "partition-manifest";
+
+	/* Properties */
+	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	uuid = <0xa609f132 0x6b4f 0x4c14 0x9489 0x798457>;
+	execution-ctx-count = <8>;
+	exception-level = <2>; /* S-EL1 */
+	execution-state = <0>; /* AARCH64 */
+	load-address = <0x6380000>;
+	entrypoint-offset = <0x1000>;
+	xlat-granule = <0>; /* 4KiB */
+	messaging-method = <0>; /* Direct messaging only */
+	boot-order = <2>; /* This should be the highest priority partition */
+};
diff --git a/test/vmapi/ffa_secure_partitions/secure_partition_control.c b/test/vmapi/ffa_secure_partitions/secure_partition_control.c
new file mode 100644
index 0000000..1be0c40
--- /dev/null
+++ b/test/vmapi/ffa_secure_partitions/secure_partition_control.c
@@ -0,0 +1,41 @@
+/*
+ * 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 "hf/dlog.h"
+#include "hf/ffa.h"
+
+#include "vmapi/hf/call.h"
+
+#include "test/hftest.h"
+
+#define RECEIVER (HF_VM_ID_BASE + 2)
+
+/**
+ * Communicates with partition via direct messaging to validate functioning of
+ * Direct Message interfaces.
+ */
+TEST(ffa_sp_to_sp_comm, dir_msg_req)
+{
+	const uint32_t msg[] = {0x00001111, 0x22223333, 0x44445555, 0x66667777,
+				0x88889999};
+	struct ffa_value res;
+	ffa_vm_id_t own_id = hf_vm_get_id();
+
+	dlog_verbose("HF_VM_ID_BASE: %x\n", HF_VM_ID_BASE);
+
+	res = ffa_msg_send_direct_req(own_id, RECEIVER, msg[0], msg[1], msg[2],
+				      msg[3], msg[4]);
+
+	EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
+
+	EXPECT_EQ(res.arg3, msg[0]);
+	EXPECT_EQ(res.arg4, msg[1]);
+	EXPECT_EQ(res.arg5, msg[2]);
+	EXPECT_EQ(res.arg6, msg[3]);
+	EXPECT_EQ(res.arg7, msg[4]);
+}
diff --git a/test/vmapi/ffa_secure_partitions/secure_partition_services.c b/test/vmapi/ffa_secure_partitions/secure_partition_services.c
new file mode 100644
index 0000000..fe534d2
--- /dev/null
+++ b/test/vmapi/ffa_secure_partitions/secure_partition_services.c
@@ -0,0 +1,33 @@
+/*
+ * 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 "vmapi/hf/call.h"
+
+#include "test/hftest.h"
+
+/**
+ * Message loop to add tests to be controlled by the control partition(depends
+ * on the test set-up).
+ * TODO: Extend/refactor function below to cater for other tests, in addition to
+ * the current simple 'echo' via direct message.
+ */
+noreturn void test_main_sp(void)
+{
+	struct ffa_value res;
+
+	res = ffa_msg_wait();
+
+	while (1) {
+		HFTEST_LOG("Received direct message request");
+		EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_REQ_32);
+
+		ffa_msg_send_direct_resp(
+			ffa_msg_send_receiver(res), ffa_msg_send_sender(res),
+			res.arg3, res.arg4, res.arg5, res.arg6, res.arg7);
+	}
+}