refactor(ff-a): `FFA_VERSION` related refactorings

* Replace some macros with constants/functions.
* Use an enum for FF-A version.

Change-Id: Ieb4746f85878c33c6b814ce47cbe7faf86abbc5c
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/src/api.c b/src/api.c
index ae5d202..0794a79 100644
--- a/src/api.c
+++ b/src/api.c
@@ -422,7 +422,7 @@
 	uint32_t vm_count)
 {
 	struct vm *vm = vm_locked.vm;
-	uint32_t version = vm->ffa_version;
+	enum ffa_version version = vm->ffa_version;
 	uint32_t partition_info_size;
 	uint32_t buffer_size;
 	struct ffa_value ret;
@@ -442,7 +442,7 @@
 		return ffa_error(FFA_BUSY);
 	}
 
-	if (version == MAKE_FFA_VERSION(1, 0)) {
+	if (version == FFA_VERSION_1_0) {
 		struct ffa_partition_info_v1_0 *recv_mailbox = vm->mailbox.recv;
 
 		partition_info_size = sizeof(struct ffa_partition_info_v1_0);
@@ -930,16 +930,16 @@
  */
 struct ffa_value api_ffa_spm_id_get(void)
 {
-#if (MAKE_FFA_VERSION(1, 1) <= FFA_VERSION_COMPILED)
-	/*
-	 * Return the SPMC ID that was fetched during FF-A
-	 * initialization.
-	 */
-	return (struct ffa_value){.func = FFA_SUCCESS_32,
-				  .arg2 = arch_ffa_spmc_id_get()};
-#else
+	if (FFA_VERSION_1_1 <= FFA_VERSION_COMPILED) {
+		/*
+		 * Return the SPMC ID that was fetched during FF-A
+		 * initialization.
+		 */
+		return (struct ffa_value){.func = FFA_SUCCESS_32,
+					  .arg2 = arch_ffa_spmc_id_get()};
+	}
+
 	return ffa_error(FFA_NOT_SUPPORTED);
-#endif
 }
 
 /**
@@ -1125,7 +1125,7 @@
 		return ffa_error(FFA_INVALID_PARAMETERS);
 	}
 
-	if (current->vm->ffa_version >= MAKE_FFA_VERSION(1, 2) &&
+	if (current->vm->ffa_version >= FFA_VERSION_1_2 &&
 	    !api_extended_args_are_zero(args)) {
 		return ffa_error(FFA_INVALID_PARAMETERS);
 	}
@@ -2441,26 +2441,23 @@
 
 /** Returns the version of the implemented FF-A specification. */
 struct ffa_value api_ffa_version(struct vcpu *current,
-				 uint32_t requested_version)
+				 enum ffa_version requested_version)
 {
+	static_assert(sizeof(enum ffa_version) == 4,
+		      "enum ffa_version must be 4 bytes wide");
+
 	struct vm_locked current_vm_locked;
 
-	/*
-	 * Ensure that both major and minor revision representation occupies at
-	 * most 15 bits.
-	 */
-	static_assert(0x8000 > FFA_VERSION_MAJOR,
-		      "Major revision representation takes more than 15 bits.");
-	static_assert(0x10000 > FFA_VERSION_MINOR,
-		      "Minor revision representation takes more than 16 bits.");
-	if (requested_version & FFA_VERSION_RESERVED_BIT) {
-		/* Invalid encoding, return an error. */
+	if (!ffa_version_is_valid(requested_version)) {
+		dlog_error(
+			"FFA_VERSION: requested version %#x is invalid "
+			"(highest bit must be zero)\n",
+			requested_version);
 		return (struct ffa_value){.func = (uint32_t)FFA_NOT_SUPPORTED};
 	}
 
-	if ((requested_version >> FFA_VERSION_MAJOR_OFFSET) !=
-		    FFA_VERSION_MAJOR ||
-	    requested_version > FFA_VERSION_COMPILED) {
+	if (!ffa_versions_are_compatible(requested_version,
+					 FFA_VERSION_COMPILED)) {
 		dlog_verbose("Version %x incompatible with %x\n",
 			     requested_version, FFA_VERSION_COMPILED);
 		return (struct ffa_value){.func = (uint32_t)FFA_NOT_SUPPORTED};
@@ -2500,7 +2497,7 @@
 struct ffa_value api_ffa_features(uint32_t function_or_feature_id,
 				  uint32_t input_property, struct vcpu *current)
 {
-	const uint32_t ffa_version = current->vm->ffa_version;
+	const enum ffa_version ffa_version = current->vm->ffa_version;
 	const bool el0_partition = current->vm->el0_partition;
 	const bool is_feature =
 		IS_BIT_UNSET(function_or_feature_id, FFA_FEATURES_FEATURE_BIT);
@@ -2554,7 +2551,7 @@
 	case FFA_MSG_SEND_DIRECT_RESP_32:
 	case FFA_MSG_SEND_DIRECT_REQ_64:
 	case FFA_MSG_SEND_DIRECT_REQ_32:
-#if (MAKE_FFA_VERSION(1, 1) <= FFA_VERSION_COMPILED)
+
 	/* FF-A v1.1 features. */
 	case FFA_SPM_ID_GET_32:
 	case FFA_NOTIFICATION_BITMAP_CREATE_32:
@@ -2569,24 +2566,33 @@
 	case FFA_MEM_PERM_GET_64:
 	case FFA_MEM_PERM_SET_64:
 	case FFA_MSG_SEND2_32:
-#endif
-#if (MAKE_FFA_VERSION(1, 2) <= FFA_VERSION_COMPILED)
+		if (FFA_VERSION_1_1 > FFA_VERSION_COMPILED) {
+			return arch_ffa_features(function_or_feature_id);
+		}
+
 	/* FF-A v1.2 features. */
 	case FFA_CONSOLE_LOG_32:
 	case FFA_CONSOLE_LOG_64:
 	case FFA_PARTITION_INFO_GET_REGS_64:
 	case FFA_MSG_SEND_DIRECT_REQ2_64:
 	case FFA_MSG_SEND_DIRECT_RESP2_64:
-#endif
+		if (FFA_VERSION_1_2 > FFA_VERSION_COMPILED) {
+			return arch_ffa_features(function_or_feature_id);
+		}
+
 		return api_ffa_feature_success(0);
 
 	case FFA_RXTX_MAP_64: {
+		if (FFA_VERSION_1_2 > FFA_VERSION_COMPILED) {
+			return arch_ffa_features(function_or_feature_id);
+		}
+
 		uint32_t arg2 = 0;
 		struct ffa_features_rxtx_map_params params = {
 			.min_buf_size = FFA_RXTX_MAP_MIN_BUF_4K,
 			.mbz = 0,
 			.max_buf_size =
-				(ffa_version >= MAKE_FFA_VERSION(1, 2))
+				(ffa_version >= FFA_VERSION_1_2)
 					? FFA_RXTX_MAP_MAX_BUF_PAGE_COUNT
 					: 0,
 		};
@@ -2597,6 +2603,10 @@
 
 	case FFA_MEM_RETRIEVE_REQ_64:
 	case FFA_MEM_RETRIEVE_REQ_32: {
+		if (FFA_VERSION_1_2 > FFA_VERSION_COMPILED) {
+			return arch_ffa_features(function_or_feature_id);
+		}
+
 		if (ANY_BITS_SET(input_property,
 				 FFA_FEATURES_MEM_RETRIEVE_REQ_MBZ_HI_BIT,
 				 FFA_FEATURES_MEM_RETRIEVE_REQ_MBZ_LO_BIT) ||
@@ -2612,8 +2622,9 @@
 				input_property);
 		}
 
-		if (ffa_version >= MAKE_FFA_VERSION(1, 1) &&
-		    IS_BIT_UNSET(input_property, FFA_FEATURES_NS_SUPPORT_BIT)) {
+		if (ffa_version >= FFA_VERSION_1_1 &&
+		    (input_property &
+		     FFA_FEATURES_MEM_RETRIEVE_REQ_NS_SUPPORT) == 0U) {
 			dlog_error("FFA_FEATURES: NS bit support must be 1\n");
 			return ffa_error(FFA_NOT_SUPPORTED);
 		}
@@ -2624,7 +2635,6 @@
 			FFA_FEATURES_MEM_RETRIEVE_REQ_HYPERVISOR_SUPPORT);
 	}
 
-#if (MAKE_FFA_VERSION(1, 1) <= FFA_VERSION_COMPILED)
 	/* Check support of a feature provided respective feature ID. */
 
 	/*
@@ -2632,6 +2642,10 @@
 	 * the virtual FF-A instances.
 	 */
 	case FFA_FEATURE_NPI:
+		if (FFA_VERSION_1_2 > FFA_VERSION_COMPILED) {
+			return arch_ffa_features(function_or_feature_id);
+		}
+
 		if (el0_partition) {
 			return ffa_error(FFA_NOT_SUPPORTED);
 		}
@@ -2641,17 +2655,25 @@
 		return api_ffa_feature_success(HF_NOTIFICATION_PENDING_INTID);
 
 	case FFA_FEATURE_MEI:
+		if (FFA_VERSION_1_2 > FFA_VERSION_COMPILED) {
+			return arch_ffa_features(function_or_feature_id);
+		}
+
 		if (!vm_id_is_current_world(current->vm->id)) {
 			return ffa_error(FFA_NOT_SUPPORTED);
 		}
 		return api_ffa_feature_success(HF_MANAGED_EXIT_INTID);
 
 	case FFA_FEATURE_SRI:
+		if (FFA_VERSION_1_2 > FFA_VERSION_COMPILED) {
+			return arch_ffa_features(function_or_feature_id);
+		}
+
 		if (!ffa_is_vm_id(current->vm->id)) {
 			return ffa_error(FFA_NOT_SUPPORTED);
 		}
 		return api_ffa_feature_success(HF_SCHEDULE_RECEIVER_INTID);
-#endif
+
 	/* Platform specific feature support. */
 	default:
 		return arch_ffa_features(function_or_feature_id);
@@ -3007,7 +3029,7 @@
 			return ffa_error(FFA_INVALID_PARAMETERS);
 		}
 
-		if (current->vm->ffa_version >= MAKE_FFA_VERSION(1, 2) &&
+		if (current->vm->ffa_version >= FFA_VERSION_1_2 &&
 		    !api_extended_args_are_zero(&args)) {
 			return ffa_error(FFA_INVALID_PARAMETERS);
 		}
@@ -3198,7 +3220,7 @@
  */
 static struct ffa_value api_ffa_memory_transaction_descriptor_v1_1_from_v1_0(
 	void *allocated, uint32_t *fragment_length, uint32_t *total_length,
-	uint32_t ffa_version, bool send_transaction)
+	enum ffa_version ffa_version, bool send_transaction)
 {
 	struct ffa_memory_region_v1_0 *memory_region_v1_0;
 	struct ffa_memory_region *memory_region_v1_1 = NULL;
@@ -3215,11 +3237,11 @@
 	assert(fragment_length != NULL);
 	assert(total_length != NULL);
 
-	if (ffa_version >= MAKE_FFA_VERSION(1, 1)) {
+	if (ffa_version >= FFA_VERSION_1_1) {
 		return (struct ffa_value){.func = FFA_SUCCESS_32};
 	}
 
-	if (ffa_version != MAKE_FFA_VERSION(1, 0)) {
+	if (ffa_version != FFA_VERSION_1_0) {
 		dlog_verbose("%s: Unsupported FF-A version %x\n", __func__,
 			     ffa_version);
 		return ffa_error(FFA_NOT_SUPPORTED);
@@ -3362,7 +3384,7 @@
 	struct ffa_memory_region *memory_region = NULL;
 	struct ffa_value ret;
 	bool targets_other_world = false;
-	uint32_t ffa_version;
+	enum ffa_version ffa_version;
 
 	if (ipa_addr(address) != 0 || page_count != 0) {
 		/*
@@ -3534,7 +3556,7 @@
 	struct ffa_memory_region *retrieve_request = NULL;
 	uint32_t message_buffer_size;
 	struct ffa_value ret;
-	uint32_t ffa_version;
+	enum ffa_version ffa_version;
 
 	if (ipa_addr(address) != 0 || page_count != 0) {
 		/*
@@ -4552,7 +4574,7 @@
 {
 	/* Maximum number of characters is 128: 16 registers of 8 bytes each. */
 	char chars[128] = {0};
-	const bool v1_2 = current->vm->ffa_version >= MAKE_FFA_VERSION(1, 2);
+	const bool v1_2 = current->vm->ffa_version >= FFA_VERSION_1_2;
 	const bool log32 = args.func == FFA_CONSOLE_LOG_32;
 
 	/*
diff --git a/src/arch/aarch64/hypervisor/cpu.c b/src/arch/aarch64/hypervisor/cpu.c
index 2bfd496..cc7d9bd 100644
--- a/src/arch/aarch64/hypervisor/cpu.c
+++ b/src/arch/aarch64/hypervisor/cpu.c
@@ -266,7 +266,7 @@
 	if (func_id == FFA_MSG_SEND_DIRECT_REQ2_64 ||
 	    func_id == FFA_MSG_SEND_DIRECT_RESP2_64 ||
 	    (func_id == FFA_CONSOLE_LOG_64 &&
-	     MAKE_FFA_VERSION(1, 2) <= FFA_VERSION_COMPILED)) {
+	     FFA_VERSION_1_2 <= FFA_VERSION_COMPILED)) {
 		return arch_regs_get_args_ext(regs);
 	}
 
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index 97d9c7e..311c075 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -653,7 +653,7 @@
 		 * runtime state of the calling partition by setting
 		 * the extended registers (x8-x17) to zero.
 		 */
-		if (current->vm->ffa_version >= MAKE_FFA_VERSION(1, 2) &&
+		if (current->vm->ffa_version >= FFA_VERSION_1_2 &&
 		    !api_extended_args_are_zero(args)) {
 			*args = ffa_error(FFA_INVALID_PARAMETERS);
 			return false;
diff --git a/src/arch/aarch64/plat/ffa/hypervisor.c b/src/arch/aarch64/plat/ffa/hypervisor.c
index 066eac0..b1d7ce9 100644
--- a/src/arch/aarch64/plat/ffa/hypervisor.c
+++ b/src/arch/aarch64/plat/ffa/hypervisor.c
@@ -30,7 +30,7 @@
 
 bool vm_supports_indirect_messages(struct vm *vm)
 {
-	return vm->ffa_version >= MAKE_FFA_VERSION(1, 1) &&
+	return vm->ffa_version >= FFA_VERSION_1_1 &&
 	       vm_supports_messaging_method(vm, FFA_PARTITION_INDIRECT_MSG);
 }
 
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index 4e5596d..9be1d3f 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -179,24 +179,17 @@
 /** Returns information on features specific to the SWd. */
 struct ffa_value plat_ffa_features(uint32_t function_feature_id)
 {
-	struct ffa_value ret;
-
-	switch (function_feature_id) {
-#if (MAKE_FFA_VERSION(1, 1) <= FFA_VERSION_COMPILED)
-	case FFA_SECONDARY_EP_REGISTER_64:
-		ret = (struct ffa_value){.func = FFA_SUCCESS_32};
-		break;
-	case FFA_FEATURE_MEI:
-		ret = api_ffa_feature_success(HF_MANAGED_EXIT_INTID);
-		break;
-#endif
-	default:
-		ret = ffa_error(FFA_NOT_SUPPORTED);
-		break;
+	if (FFA_VERSION_1_1 <= FFA_VERSION_COMPILED) {
+		switch (function_feature_id) {
+		case FFA_SECONDARY_EP_REGISTER_64:
+			return (struct ffa_value){.func = FFA_SUCCESS_32};
+		case FFA_FEATURE_MEI:
+			return api_ffa_feature_success(HF_MANAGED_EXIT_INTID);
+		}
 	}
 
 	/* There are no features only supported in the SWd */
-	return ret;
+	return ffa_error(FFA_NOT_SUPPORTED);
 }
 
 struct ffa_value plat_ffa_spmc_id_get(void)
@@ -578,12 +571,12 @@
 {
 	uint16_t sender_method;
 	uint16_t receiver_method;
-	uint32_t sender_ffa_version = sender_vm->ffa_version;
-	uint32_t receiver_ffa_version = receiver_vm->ffa_version;
+	enum ffa_version sender_ffa_version = sender_vm->ffa_version;
+	enum ffa_version receiver_ffa_version = receiver_vm->ffa_version;
 
 	/* Check if version supports messaging function. */
-	if ((func == FFA_MSG_SEND_DIRECT_REQ2_64) &&
-	    (sender_ffa_version < MAKE_FFA_VERSION(1, 2))) {
+	if (func == FFA_MSG_SEND_DIRECT_REQ2_64 &&
+	    sender_ffa_version < FFA_VERSION_1_2) {
 		dlog_verbose(
 			"Sender version does not allow usage of func id "
 			"0x%x.\n",
@@ -591,8 +584,8 @@
 		return false;
 	}
 
-	if ((func == FFA_MSG_SEND_DIRECT_REQ2_64) &&
-	    (receiver_ffa_version < MAKE_FFA_VERSION(1, 2))) {
+	if (func == FFA_MSG_SEND_DIRECT_REQ2_64 &&
+	    receiver_ffa_version < FFA_VERSION_1_2) {
 		dlog_verbose(
 			"Receiver version does not allow usage of func id "
 			"0x%x.\n",
diff --git a/src/ffa_memory.c b/src/ffa_memory.c
index 11864ca..b35cd40 100644
--- a/src/ffa_memory.c
+++ b/src/ffa_memory.c
@@ -308,7 +308,7 @@
 		/* The impdef field is only present from v1.2 and later */
 		if (ffa_version_from_memory_access_desc_size(
 			    memory_region->memory_access_desc_size) >=
-		    MAKE_FFA_VERSION(1, 2)) {
+		    FFA_VERSION_1_2) {
 			dlog(", impdef: %#lx %#lx", receiver->impdef.val[0],
 			     receiver->impdef.val[1]);
 		}
@@ -474,7 +474,7 @@
 	return (struct ffa_value){.func = FFA_SUCCESS_32};
 }
 
-uint32_t ffa_version_from_memory_access_desc_size(
+enum ffa_version ffa_version_from_memory_access_desc_size(
 	uint32_t memory_access_desc_size)
 {
 	switch (memory_access_desc_size) {
@@ -484,9 +484,9 @@
 	 * size field so return v1.1.
 	 */
 	case sizeof(struct ffa_memory_access_v1_0):
-		return MAKE_FFA_VERSION(1, 1);
+		return FFA_VERSION_1_1;
 	case sizeof(struct ffa_memory_access):
-		return MAKE_FFA_VERSION(1, 2);
+		return FFA_VERSION_1_2;
 	}
 	return 0;
 }
@@ -497,15 +497,15 @@
  */
 static bool receiver_size_and_offset_valid_for_version(
 	uint32_t receivers_size, uint32_t receivers_offset,
-	uint32_t ffa_version)
+	enum ffa_version ffa_version)
 {
 	/*
 	 * Check that the version that the memory access descriptor size belongs
 	 * to is compatible with the FF-A version we believe the sender to be.
 	 */
-	uint32_t expected_ffa_version =
+	enum ffa_version expected_ffa_version =
 		ffa_version_from_memory_access_desc_size(receivers_size);
-	if (!FFA_VERSIONS_ARE_COMPATIBLE(expected_ffa_version, ffa_version)) {
+	if (!ffa_versions_are_compatible(expected_ffa_version, ffa_version)) {
 		return false;
 	}
 
@@ -514,8 +514,8 @@
 	 * memory access descriptor size.
 	 */
 	switch (expected_ffa_version) {
-	case MAKE_FFA_VERSION(1, 1):
-	case MAKE_FFA_VERSION(1, 2):
+	case FFA_VERSION_1_1:
+	case FFA_VERSION_1_2:
 		return receivers_offset == sizeof(struct ffa_memory_region);
 	default:
 		return false;
@@ -528,7 +528,7 @@
  * and reserved fields are 0.
  */
 bool ffa_memory_region_sanity_check(struct ffa_memory_region *memory_region,
-				    uint32_t ffa_version,
+				    enum ffa_version ffa_version,
 				    uint32_t fragment_length,
 				    bool send_transaction)
 {
@@ -538,7 +538,7 @@
 	struct ffa_memory_region_v1_0 *memory_region_v1_0 =
 		(struct ffa_memory_region_v1_0 *)memory_region;
 
-	if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
+	if (ffa_version == FFA_VERSION_1_0) {
 		/* Check the reserved fields are 0. */
 		if (memory_region_v1_0->reserved_0 != 0 ||
 		    memory_region_v1_0->reserved_1 != 0) {
@@ -591,7 +591,7 @@
 	 * The composite offset values must be the same for all recievers so
 	 * check the first one is valid and then they are all the same.
 	 */
-	receiver = ffa_version == MAKE_FFA_VERSION(1, 0)
+	receiver = ffa_version == FFA_VERSION_1_0
 			   ? (struct ffa_memory_access *)&memory_region_v1_0
 				     ->receivers[0]
 			   : ffa_memory_region_get_receiver(memory_region, 0);
@@ -632,7 +632,7 @@
 	for (size_t i = 0; i < memory_region->receiver_count; i++) {
 		uint32_t composite_offset;
 
-		if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
+		if (ffa_version == FFA_VERSION_1_0) {
 			struct ffa_memory_access_v1_0 *receiver_v1_0 =
 				&memory_region_v1_0->receivers[i];
 			/* Check reserved fields are 0 */
@@ -2477,7 +2477,7 @@
  * the first fragment.
  */
 static bool ffa_retrieved_memory_region_init(
-	void *response, uint32_t ffa_version, size_t response_max_size,
+	void *response, enum ffa_version ffa_version, size_t response_max_size,
 	ffa_id_t sender, ffa_memory_attributes_t attributes,
 	ffa_memory_region_flags_t flags, ffa_memory_handle_t handle,
 	ffa_memory_access_permissions_t permissions,
@@ -2495,7 +2495,7 @@
 
 	assert(response != NULL);
 
-	if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
+	if (ffa_version == FFA_VERSION_1_0) {
 		struct ffa_memory_region_v1_0 *retrieve_response =
 			(struct ffa_memory_region_v1_0 *)response;
 		struct ffa_memory_access_v1_0 *receiver;
@@ -2896,10 +2896,10 @@
 		 */
 		if (ffa_version_from_memory_access_desc_size(
 			    memory_region->memory_access_desc_size) >=
-			    MAKE_FFA_VERSION(1, 2) &&
+			    FFA_VERSION_1_2 &&
 		    ffa_version_from_memory_access_desc_size(
 			    retrieve_request->memory_access_desc_size) >=
-			    MAKE_FFA_VERSION(1, 2)) {
+			    FFA_VERSION_1_2) {
 			if (receiver->impdef.val[0] !=
 				    retrieve_request_receiver->impdef.val[0] ||
 			    receiver->impdef.val[1] !=
@@ -3309,11 +3309,11 @@
 	assert(to_locked.vm->id == HF_HYPERVISOR_VM_ID);
 
 	switch (to_locked.vm->ffa_version) {
-	case MAKE_FFA_VERSION(1, 2):
+	case FFA_VERSION_1_2:
 		memory_access_desc_size = sizeof(struct ffa_memory_access);
 		break;
-	case MAKE_FFA_VERSION(1, 0):
-	case MAKE_FFA_VERSION(1, 1):
+	case FFA_VERSION_1_0:
+	case FFA_VERSION_1_1:
 		memory_access_desc_size = sizeof(struct ffa_memory_access_v1_0);
 		break;
 	default:
@@ -3420,19 +3420,19 @@
  */
 static uint32_t ffa_memory_retrieve_expected_offset_per_ffa_version(
 	struct ffa_memory_region *memory_region,
-	uint32_t retrieved_constituents_count, uint32_t ffa_version)
+	uint32_t retrieved_constituents_count, enum ffa_version ffa_version)
 {
 	uint32_t expected_fragment_offset;
 	uint32_t composite_constituents_offset;
 
-	if (ffa_version >= MAKE_FFA_VERSION(1, 1)) {
+	if (ffa_version >= FFA_VERSION_1_1) {
 		/*
 		 * Hafnium operates memory regions in FF-A v1.1 format, so we
 		 * can retrieve the constituents offset from descriptor.
 		 */
 		composite_constituents_offset =
 			ffa_composite_constituent_offset(memory_region, 0);
-	} else if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
+	} else if (ffa_version == FFA_VERSION_1_0) {
 		/*
 		 * If retriever is FF-A v1.0, determine the composite offset
 		 * as it is expected to have been configured in the
diff --git a/src/manifest.c b/src/manifest.c
index 628b137..a78118b 100644
--- a/src/manifest.c
+++ b/src/manifest.c
@@ -21,6 +21,7 @@
 #include "hf/check.h"
 #include "hf/dlog.h"
 #include "hf/fdt.h"
+#include "hf/ffa.h"
 #include "hf/mm.h"
 #include "hf/mpool.h"
 #include "hf/sp_pkg.h"
@@ -1029,8 +1030,7 @@
 static enum manifest_return_code sanity_check_ffa_manifest(
 	struct manifest_vm *vm)
 {
-	uint16_t ffa_version_major;
-	uint16_t ffa_version_minor;
+	enum ffa_version ffa_version;
 	enum manifest_return_code ret_code = MANIFEST_SUCCESS;
 	const char *error_string = "specified in manifest is unsupported";
 	uint32_t k = 0;
@@ -1039,14 +1039,11 @@
 			    FFA_PARTITION_DIRECT_REQ2_SEND)) != 0;
 
 	/* ensure that the SPM version is compatible */
-	ffa_version_major = (vm->partition.ffa_version & 0xffff0000) >>
-			    FFA_VERSION_MAJOR_OFFSET;
-	ffa_version_minor = vm->partition.ffa_version & 0xffff;
-
-	if (ffa_version_major != FFA_VERSION_MAJOR ||
-	    ffa_version_minor > FFA_VERSION_MINOR) {
+	ffa_version = vm->partition.ffa_version;
+	if (!ffa_versions_are_compatible(ffa_version, FFA_VERSION_COMPILED)) {
 		dlog_error("FF-A partition manifest version %s: %u.%u\n",
-			   error_string, ffa_version_major, ffa_version_minor);
+			   error_string, ffa_version_get_major(ffa_version),
+			   ffa_version_get_minor(ffa_version));
 		ret_code = MANIFEST_ERROR_NOT_COMPATIBLE;
 	}
 
@@ -1071,7 +1068,7 @@
 		ret_code = MANIFEST_ERROR_NOT_COMPATIBLE;
 	}
 
-	if (vm->partition.ffa_version < MAKE_FFA_VERSION(1, 2) && using_req2) {
+	if (vm->partition.ffa_version < FFA_VERSION_1_2 && using_req2) {
 		dlog_error("Messaging method %s: %x\n", error_string,
 			   vm->partition.messaging_method);
 		ret_code = MANIFEST_ERROR_NOT_COMPATIBLE;
@@ -1239,8 +1236,8 @@
 
 	TRY(read_uint32(&root, "ffa-version", &vm->partition.ffa_version));
 	dlog_verbose("  Expected FF-A version %u.%u\n",
-		     vm->partition.ffa_version >> 16,
-		     vm->partition.ffa_version & 0xffff);
+		     ffa_version_get_major(vm->partition.ffa_version),
+		     ffa_version_get_minor(vm->partition.ffa_version));
 
 	TRY(read_uint16(&root, "execution-ctx-count",
 			&vm->partition.execution_ctx_count));