test(dir_msg): extend multiple uuids test
Extend test case `ffa_send_direct_message_req2_multiple_uuids`
to send a request to each of the target partition's UUIDs.
To enable this test, add parsing of `uuid` field to test service
manifest parsing.
Signed-off-by: Kathleen Capella <kathleen.capella@arm.com>
Change-Id: Ib6f3f86e5350143a624a555f5c0da98df4415ba8
diff --git a/test/hftest/service_common.c b/test/hftest/service_common.c
index 510fc77..214aefd 100644
--- a/test/hftest/service_common.c
+++ b/test/hftest/service_common.c
@@ -31,6 +31,23 @@
return &global_context;
}
+static bool uint32list_has_next(const struct memiter *list)
+{
+ return memiter_size(list) > 0;
+}
+
+static void uint32list_get_next(struct memiter *list, uint32_t *out)
+{
+ uint64_t num;
+
+ CHECK(uint32list_has_next(list));
+ if (!fdt_parse_number(list, sizeof(uint32_t), &num)) {
+ return;
+ }
+
+ *out = (uint32_t)num;
+}
+
noreturn void abort(void)
{
HFTEST_LOG("Service contained failures.");
@@ -83,6 +100,10 @@
struct fdt_node ffa_node;
struct string mem_region_node_name = STRING_INIT("memory-regions");
struct string dev_region_node_name = STRING_INIT("device-regions");
+ struct memiter uuid;
+ uint32_t uuid_word = 0;
+ uint16_t j = 0;
+ uint16_t i = 0;
uint64_t number;
CHECK(ctx != NULL);
@@ -94,6 +115,30 @@
&ctx->partition_manifest.load_addr));
EXPECT_TRUE(fdt_read_number(&root, "ffa-version", &number));
+ EXPECT_TRUE(fdt_read_property(&root, "uuid", &uuid));
+
+ /* Parse UUIDs and populate uuid count.*/
+ while (uint32list_has_next(&uuid) && j < PARTITION_MAX_UUIDS) {
+ while (uint32list_has_next(&uuid) && i < 4) {
+ uint32list_get_next(&uuid, &uuid_word);
+ ctx->partition_manifest.uuids[j].uuid[i] = uuid_word;
+ i++;
+ }
+
+ EXPECT_FALSE(
+ ffa_uuid_is_null(&ctx->partition_manifest.uuids[j]));
+
+ dlog_verbose(" UUID %#x-%x-%x-%x\n",
+ ctx->partition_manifest.uuids[j].uuid[0],
+ ctx->partition_manifest.uuids[j].uuid[1],
+ ctx->partition_manifest.uuids[j].uuid[2],
+ ctx->partition_manifest.uuids[j].uuid[3]);
+ j++;
+ i = 0;
+ }
+
+ ctx->partition_manifest.uuid_count = j;
+
ffa_node = root;
/* Look for the memory region node. */
diff --git a/test/vmapi/primary_with_secondaries/dir_msg.c b/test/vmapi/primary_with_secondaries/dir_msg.c
index 9d4a33e..972849b 100644
--- a/test/vmapi/primary_with_secondaries/dir_msg.c
+++ b/test/vmapi/primary_with_secondaries/dir_msg.c
@@ -688,10 +688,11 @@
}
/**
- * Send direct message via FFA_MSG_SEND_DIR_REQ2, verify that sent info is
- * echoed back.
+ * Send a direct message request via FFA_MSG_SEND_DIR_REQ2 to each of the target
+ * partition's UUIDs and verify that sent info is echoed back.
*/
-TEST(direct_message, ffa_send_direct_message_req2_multiple_uuids)
+TEST_PRECONDITION(direct_message, ffa_send_direct_message_req2_multiple_uuids,
+ service1_and_service2_are_secure)
{
const uint64_t msg[] = {0x00001111, 0x22223333, 0x44445555, 0x66667777,
0x88889999, 0x01010101, 0x23232323, 0x45454545,
@@ -703,7 +704,7 @@
struct ffa_uuid uuid = SERVICE2_UUID2;
SERVICE_SELECT(service2_info->vm_id,
- "ffa_direct_message_req2_resp_echo", mb.send);
+ "ffa_direct_message_req2_resp_loop", mb.send);
ffa_run(service2_info->vm_id, 0);
res = ffa_msg_send_direct_req2(HF_PRIMARY_VM_ID, service2_info->vm_id,
@@ -726,6 +727,29 @@
EXPECT_EQ(res.extended_val.arg15, msg[11]);
EXPECT_EQ(res.extended_val.arg16, msg[12]);
EXPECT_EQ(res.extended_val.arg17, msg[13]);
+
+ uuid = SERVICE2;
+
+ res = ffa_msg_send_direct_req2(HF_PRIMARY_VM_ID, service2_info->vm_id,
+ &uuid, (const uint64_t *)&msg,
+ ARRAY_SIZE(msg));
+
+ EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP2_64);
+
+ EXPECT_EQ(res.arg4, msg[0]);
+ EXPECT_EQ(res.arg5, msg[1]);
+ EXPECT_EQ(res.arg6, msg[2]);
+ EXPECT_EQ(res.arg7, msg[3]);
+ EXPECT_EQ(res.extended_val.arg8, msg[4]);
+ EXPECT_EQ(res.extended_val.arg9, msg[5]);
+ EXPECT_EQ(res.extended_val.arg10, msg[6]);
+ EXPECT_EQ(res.extended_val.arg11, msg[7]);
+ EXPECT_EQ(res.extended_val.arg12, msg[8]);
+ EXPECT_EQ(res.extended_val.arg13, msg[9]);
+ EXPECT_EQ(res.extended_val.arg14, msg[10]);
+ EXPECT_EQ(res.extended_val.arg15, msg[11]);
+ EXPECT_EQ(res.extended_val.arg16, msg[12]);
+ EXPECT_EQ(res.extended_val.arg17, msg[13]);
}
/**
diff --git a/test/vmapi/primary_with_secondaries/services/dir_msg.c b/test/vmapi/primary_with_secondaries/services/dir_msg.c
index 1807def..a433fe8 100644
--- a/test/vmapi/primary_with_secondaries/services/dir_msg.c
+++ b/test/vmapi/primary_with_secondaries/services/dir_msg.c
@@ -17,6 +17,46 @@
#define MAX_RESP_REGS (MAX_MSG_SIZE / sizeof(uint64_t))
+static uint16_t get_uuid_count(struct hftest_context *ctx)
+{
+ if (ctx->is_ffa_manifest_parsed) {
+ return ctx->partition_manifest.uuid_count;
+ }
+
+ return 0;
+}
+
+static struct ffa_uuid *get_uuids(struct hftest_context *ctx)
+{
+ if (ctx->is_ffa_manifest_parsed) {
+ return (struct ffa_uuid *)&ctx->partition_manifest.uuids;
+ }
+
+ return NULL;
+}
+
+static bool is_uuid_in_list(uint16_t uuid_count, struct ffa_uuid target_uuid,
+ struct ffa_uuid *uuid_list)
+{
+ uint16_t i;
+
+ /* Allow for nil uuid usage. */
+ if (ffa_uuid_is_null(&target_uuid)) {
+ return true;
+ }
+
+ for (i = 0; i < uuid_count; i++) {
+ if (ffa_uuid_is_null(&target_uuid)) {
+ break;
+ }
+ if (ffa_uuid_equal(&uuid_list[i], &target_uuid)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
TEST_SERVICE(ffa_direct_message_resp_echo)
{
struct ffa_value args = ffa_msg_wait();
@@ -687,3 +727,44 @@
EXPECT_FFA_ERROR(res, FFA_DENIED);
ffa_yield();
}
+
+/**
+ * Service traps execution in a loop, and expects to always wake up with a
+ * FFA_MSG_SEND_DIRECT_REQ2. Verify that target UUID was specified in the target
+ * partition's manifest before echoing message back to sender.
+ */
+TEST_SERVICE(ffa_direct_message_req2_resp_loop)
+{
+ struct hftest_context *ctx = hftest_get_context();
+ struct ffa_uuid *uuids = get_uuids(ctx);
+ uint16_t uuid_count = get_uuid_count(ctx);
+ struct ffa_value res;
+
+ if (!ctx->is_ffa_manifest_parsed) {
+ FAIL("Manifest not parsed");
+ }
+
+ res = ffa_msg_wait();
+
+ while (true) {
+ uint64_t msg[MAX_RESP_REGS];
+ struct ffa_uuid target_uuid;
+
+ EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_REQ2_64);
+
+ ffa_uuid_unpack_from_uint64(res.arg2, res.arg3, &target_uuid);
+
+ HFTEST_LOG("Target UUID: %X-%X-%X-%X", target_uuid.uuid[0],
+ target_uuid.uuid[1], target_uuid.uuid[2],
+ target_uuid.uuid[3]);
+
+ EXPECT_TRUE(is_uuid_in_list(uuid_count, target_uuid, uuids));
+
+ memcpy_s(&msg, sizeof(uint64_t) * MAX_RESP_REGS, &res.arg4,
+ MAX_RESP_REGS * sizeof(uint64_t));
+
+ res = ffa_msg_send_direct_resp2(
+ ffa_receiver(res), ffa_sender(res),
+ (const uint64_t *)msg, MAX_RESP_REGS);
+ }
+}