Add FF-A v1.1 format FFA_PARTITION_INFO_GET support

FF-A v1.0 and v1.1 functions are conditionally compiled based on the
selected FF-A version macro value.

Signed-off-by: Imre Kis <imre.kis@arm.com>
Change-Id: I03fbdaa14202134066e693f74103a2a3be765a10
diff --git a/components/messaging/ffa/libsp/sp_discovery.c b/components/messaging/ffa/libsp/sp_discovery.c
index 7f92b6b..cbe66ce 100644
--- a/components/messaging/ffa/libsp/sp_discovery.c
+++ b/components/messaging/ffa/libsp/sp_discovery.c
@@ -51,13 +51,22 @@
 		props & FFA_PARTITION_CAN_SEND_DIRECT_REQUESTS;
 	sp_info->supports_indirect_requests =
 		props & FFA_PARTITION_SUPPORTS_INDIRECT_REQUESTS;
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+	sp_info->partition_id_type =
+		(props >> FFA_PARTITION_PART_ID_SHIFT) & FFA_PARTITION_PART_ID_MASK;
+	sp_info->inform_vm_create = props & FFA_PARTITION_INFORM_VM_CREATE;
+	sp_info->inform_vm_destroy = props & FFA_PARTITION_INFORM_VM_DESTROY;
+	if (props & FFA_PARTITION_AARCH64_EXECUTION_STATE)
+		sp_info->execution_state = sp_execution_state_aarch64;
+	else
+		sp_info->execution_state = sp_execution_state_aarch32;
+	memcpy(sp_info->uuid.uuid, ffa_info->uuid.uuid, sizeof(sp_info->uuid.uuid));
+
+#endif /* CFG_FFA_VERSION */
 }
 
-static sp_result
-partition_info_get(const struct sp_uuid *uuid,
-		   struct sp_partition_info info[],
-		   uint32_t *count,
-		   bool allow_nil_uuid)
+static sp_result partition_info_get(const struct sp_uuid *uuid, struct sp_partition_info info[],
+				    uint32_t *count, bool allow_nil_uuid)
 {
 	const struct ffa_partition_information *ffa_info = NULL;
 	uint32_t ffa_count = 0;
@@ -67,6 +76,7 @@
 	size_t buffer_size = 0;
 	struct ffa_uuid ffa_uuid = { 0 };
 	ffa_result ffa_res = FFA_OK;
+	uint32_t __maybe_unused ffa_size = 0;
 
 	if (count == NULL)
 		return SP_RESULT_INVALID_PARAMETERS;
@@ -90,17 +100,28 @@
 	/* Safely convert to FF-A UUID format */
 	memcpy(&ffa_uuid.uuid, uuid->uuid, sizeof(ffa_uuid.uuid));
 
+#if CFG_FFA_VERSION == FFA_VERSION_1_0
 	ffa_res = ffa_partition_info_get(&ffa_uuid, &ffa_count);
 	if (ffa_res != FFA_OK) {
 		sp_res = SP_RESULT_FFA(ffa_res);
 		goto out;
 	}
+#elif CFG_FFA_VERSION >= FFA_VERSION_1_1
+	ffa_res = ffa_partition_info_get(&ffa_uuid, 0, &ffa_count, &ffa_size);
+	if (ffa_res != FFA_OK) {
+		sp_res = SP_RESULT_FFA(ffa_res);
+		goto out;
+	}
+
+	if (ffa_size != sizeof(struct ffa_partition_information)) {
+		/* Non-matching structure size, this may happen in future FF-A versions */
+		sp_res = SP_RESULT_INTERNAL_ERROR;
+		goto out;
+	}
+#endif
 
 	if ((ffa_count * sizeof(struct ffa_partition_information)) > buffer_size) {
-		/*
-		 * The indicated amount of info structures doesn't fit into the
-		 * RX buffer.
-		 */
+		/* The indicated amount of info structures doesn't fit into the RX buffer */
 		sp_res = SP_RESULT_INTERNAL_ERROR;
 		goto out;
 	}
@@ -162,3 +183,34 @@
 {
 	return partition_info_get(&uuid_nil, info, count, true);
 }
+
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+sp_result sp_discovery_partition_info_get_count(const struct sp_uuid *uuid, uint32_t *count)
+{
+	struct ffa_uuid ffa_uuid = { 0 };
+	ffa_result ffa_res = FFA_OK;
+	uint32_t ffa_size = 0;
+
+	if (count == NULL)
+		return SP_RESULT_INVALID_PARAMETERS;
+
+	*count = 0;
+
+	if (uuid == NULL)
+		return SP_RESULT_INVALID_PARAMETERS;
+
+	/* Safely convert to FF-A UUID format */
+	memcpy(&ffa_uuid.uuid, uuid->uuid, sizeof(ffa_uuid.uuid));
+
+	ffa_res = ffa_partition_info_get(&ffa_uuid, FFA_PARTITION_INFO_GET_FLAG_COUNT_ONLY, count,
+					 &ffa_size);
+	if (ffa_res != FFA_OK)
+		return SP_RESULT_FFA(ffa_res);
+
+	if (ffa_size != 0)
+		/* Size is MBZ if FFA_PARTITION_INFO_GET_FLAG_COUNT_ONLY is set */
+		return SP_RESULT_INTERNAL_ERROR;
+
+	return SP_RESULT_OK;
+}
+#endif /* CFG_FFA_VERSION */