refactor: FFA_VERSION related refactors

* Use an enum for FF-A versions.
* Replace `MAKE_FFA_VERSION` macro with `make_ffa_version` function.
* Add `ffa_version_is_valid` helper function.
* Add `ffa_version_get_major` and `ffa_version_get_minor` helper
  functions.

Change-Id: Icbc4b1fa16e826c2ec541add65aa7c14fb397f95
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/include/runtime_services/ffa_helpers.h b/include/runtime_services/ffa_helpers.h
index 08befd0..917885f 100644
--- a/include/runtime_services/ffa_helpers.h
+++ b/include/runtime_services/ffa_helpers.h
@@ -13,6 +13,61 @@
 
 #include <xlat_tables_defs.h>
 
+/* FFA_VERSION helpers */
+/**
+ * The version number of a Firmware Framework implementation is a 31-bit
+ * unsigned integer, with the upper 15 bits denoting the major revision,
+ * and the lower 16 bits denoting the minor revision.
+ */
+enum ffa_version {
+	FFA_VERSION_1_0 = 0x10000,
+	FFA_VERSION_1_1 = 0x10001,
+	FFA_VERSION_1_2 = 0x10002,
+	FFA_VERSION_COMPILED = FFA_VERSION_1_2,
+};
+
+#define FFA_VERSION_MBZ_BIT (1U << 31U)
+#define FFA_VERSION_MAJOR_SHIFT (16U)
+#define FFA_VERSION_MAJOR_MASK (0x7FFFU)
+#define FFA_VERSION_MINOR_SHIFT (0U)
+#define FFA_VERSION_MINOR_MASK (0xFFFFU)
+
+/** Return true if the version is valid (i.e. bit 31 is 0). */
+static inline bool ffa_version_is_valid(uint32_t version)
+{
+	return (version & FFA_VERSION_MBZ_BIT) == 0;
+}
+
+/** Construct a version from a pair of major and minor components. */
+static inline enum ffa_version make_ffa_version(uint16_t major, uint16_t minor)
+{
+	return (enum ffa_version)((major << FFA_VERSION_MAJOR_SHIFT) |
+				  (minor << FFA_VERSION_MINOR_SHIFT));
+}
+
+/** Get the major component of the version. */
+static inline uint16_t ffa_version_get_major(enum ffa_version version)
+{
+	return (version >> FFA_VERSION_MAJOR_SHIFT) & FFA_VERSION_MAJOR_MASK;
+}
+
+/** Get the minor component of the version. */
+static inline uint16_t ffa_version_get_minor(enum ffa_version version)
+{
+	return (version >> FFA_VERSION_MINOR_SHIFT) & FFA_VERSION_MINOR_MASK;
+}
+
+/**
+ * Check major versions are equal and the minor version of the caller is
+ * less than or equal to the minor version of the callee.
+ */
+static inline bool ffa_versions_are_compatible(enum ffa_version caller,
+					       enum ffa_version callee)
+{
+	return ffa_version_get_major(caller) == ffa_version_get_major(callee) &&
+	       ffa_version_get_minor(caller) <= ffa_version_get_minor(callee);
+}
+
 /* This error code must be different to the ones used by FFA */
 #define FFA_TFTF_ERROR		-42
 
diff --git a/include/runtime_services/ffa_svc.h b/include/runtime_services/ffa_svc.h
index 87a9c28..ddf4559 100644
--- a/include/runtime_services/ffa_svc.h
+++ b/include/runtime_services/ffa_svc.h
@@ -60,21 +60,6 @@
 	((GET_SMC_NUM(_fid) >= FFA_FNUM_MIN_VALUE) &&	\
 	 (GET_SMC_NUM(_fid) <= FFA_FNUM_MAX_VALUE)); })
 
-/* FFA_VERSION helpers */
-#define FFA_VERSION_MAJOR		U(1)
-#define FFA_VERSION_MAJOR_SHIFT	16
-#define FFA_VERSION_MAJOR_MASK		U(0x7FFF)
-#define FFA_VERSION_MINOR		U(2)
-#define FFA_VERSION_MINOR_SHIFT	0
-#define FFA_VERSION_MINOR_MASK		U(0xFFFF)
-#define FFA_VERSION_BIT31_MASK		U(1 << 31)
-
-#define MAKE_FFA_VERSION(major, minor) \
-	((((major) & FFA_VERSION_MAJOR_MASK) <<  FFA_VERSION_MAJOR_SHIFT) | \
-	 (((minor) & FFA_VERSION_MINOR_MASK) << FFA_VERSION_MINOR_SHIFT))
-#define FFA_VERSION_COMPILED		MAKE_FFA_VERSION(FFA_VERSION_MAJOR, \
-							  FFA_VERSION_MINOR)
-
 /* FFA_MSG_SEND helpers */
 #define FFA_MSG_SEND_ATTRS_BLK_SHIFT	U(0)
 #define FFA_MSG_SEND_ATTRS_BLK_MASK	U(0x1)
diff --git a/include/runtime_services/spm_test_helpers.h b/include/runtime_services/spm_test_helpers.h
index fede4ad..a79b6dd 100644
--- a/include/runtime_services/spm_test_helpers.h
+++ b/include/runtime_services/spm_test_helpers.h
@@ -15,25 +15,25 @@
 #define SKIP_TEST_IF_FFA_VERSION_LESS_THAN(major, minor)			\
 	do {									\
 		struct ffa_value ret = ffa_version(				\
-					MAKE_FFA_VERSION(major, minor));	\
-		uint32_t version = ret.fid;					\
+					make_ffa_version(major, minor));	\
+		enum ffa_version version = ret.fid;				\
 										\
 		if (version == FFA_ERROR_NOT_SUPPORTED) {			\
 			tftf_testcase_printf("FFA_VERSION not supported.\n");	\
 			return TEST_RESULT_SKIPPED;				\
 		}								\
 										\
-		if ((version & FFA_VERSION_BIT31_MASK) != 0U) {			\
+		if (!ffa_version_is_valid(version)) {			\
 			tftf_testcase_printf("FFA_VERSION bad response: %x\n",	\
 					version);				\
 			return TEST_RESULT_FAIL;				\
 		}								\
 										\
-		if (version < MAKE_FFA_VERSION(major, minor)) {			\
+		if (version < make_ffa_version(major, minor)) {			\
 			tftf_testcase_printf("FFA_VERSION returned %u.%u\n"	\
 					"The required version is %u.%u\n",	\
-					version >> FFA_VERSION_MAJOR_SHIFT,	\
-					version & FFA_VERSION_MINOR_MASK,	\
+					ffa_version_get_major(version), 	\
+					ffa_version_get_minor(version), 	\
 					major, minor);				\
 			return TEST_RESULT_SKIPPED;				\
 		}								\
diff --git a/spm/common/sp_tests/sp_test_ffa.c b/spm/common/sp_tests/sp_test_ffa.c
index e8905a2..c3774f9 100644
--- a/spm/common/sp_tests/sp_test_ffa.c
+++ b/spm/common/sp_tests/sp_test_ffa.c
@@ -86,11 +86,11 @@
 		get_ffa_feature_test_target(&func_id_targets);
 	const struct ffa_features_test feature_id_targets[] = {
 		{"FFA_FEATURE_MEI", FFA_FEATURE_MEI, FFA_SUCCESS_SMC32, 0,
-			MAKE_FFA_VERSION(1, 1)},
+			FFA_VERSION_1_1},
 		{"FFA_FEATURE_SRI", FFA_FEATURE_SRI, FFA_ERROR, 0,
-			MAKE_FFA_VERSION(1, 1)},
+			FFA_VERSION_1_1},
 		{"FFA_FEATURE_NPI", FFA_FEATURE_NPI, FFA_SUCCESS_SMC32, 0,
-			MAKE_FFA_VERSION(1, 1)},
+			FFA_VERSION_1_1},
 	};
 
 	INFO("Test FFA_FEATURES.\n");
@@ -117,7 +117,7 @@
 	struct ffa_value ret = { 0 };
 
 	VERBOSE("FF-A Partition Info regs interface tests\n");
-	ret = ffa_version(MAKE_FFA_VERSION(1, 2));
+	ret = ffa_version(FFA_VERSION_1_2);
 	uint32_t version = ret.fid;
 
 	if (version == FFA_ERROR_NOT_SUPPORTED) {
@@ -197,26 +197,24 @@
 
 void ffa_version_test(void)
 {
-	struct ffa_value ret = ffa_version(MAKE_FFA_VERSION(FFA_MAJOR,
-							    FFA_MINOR));
+	struct ffa_value ret = ffa_version(FFA_VERSION_COMPILED);
 
 	spm_version = (uint32_t)ret.fid;
+	EXPECT(spm_version, FFA_VERSION_COMPILED);
 
-	bool ffa_version_compatible =
-		((spm_version >> FFA_VERSION_MAJOR_SHIFT) == FFA_MAJOR &&
-		 (spm_version & FFA_VERSION_MINOR_MASK) >= FFA_MINOR);
+	bool compatible = ffa_versions_are_compatible(spm_version, FFA_VERSION_COMPILED);
 
 	INFO("Test FFA_VERSION. Return %u.%u; Compatible: %i\n",
-		spm_version >> FFA_VERSION_MAJOR_SHIFT,
-		spm_version & FFA_VERSION_MINOR_MASK,
-		(int)ffa_version_compatible);
+		ffa_version_get_major(spm_version),
+		ffa_version_get_minor(spm_version),
+		(int)compatible);
 
-	EXPECT((int)ffa_version_compatible, (int)true);
+	EXPECT((int)compatible, (int)true);
 }
 
 void ffa_spm_id_get_test(void)
 {
-	if (spm_version >= MAKE_FFA_VERSION(1, 1)) {
+	if (spm_version >= FFA_VERSION_1_1) {
 		struct ffa_value ret = ffa_spm_id_get();
 
 		EXPECT(ffa_func_id(ret), FFA_SUCCESS_SMC32);
diff --git a/tftf/tests/runtime_services/secure_service/spm_common.c b/tftf/tests/runtime_services/secure_service/spm_common.c
index 6b4ec73..53f4981 100644
--- a/tftf/tests/runtime_services/secure_service/spm_common.c
+++ b/tftf/tests/runtime_services/secure_service/spm_common.c
@@ -174,7 +174,7 @@
 	{"FFA_PARTITION_INFO_GET_32", FFA_PARTITION_INFO_GET, FFA_SUCCESS_SMC32},
 	{"FFA_ID_GET_32", FFA_ID_GET, FFA_SUCCESS_SMC32},
 	{"FFA_SPM_ID_GET_32", FFA_SPM_ID_GET, FFA_SUCCESS_SMC32, 0,
-		MAKE_FFA_VERSION(1, 1)},
+		FFA_VERSION_1_1},
 	{"FFA_MSG_WAIT_32", FFA_MSG_WAIT, FFA_SUCCESS_SMC32},
 	{"FFA_RUN_32", FFA_RUN, FFA_SUCCESS_SMC32},
 	{"FFA_MEM_DONATE_32", FFA_MEM_DONATE_SMC32, FFA_SUCCESS_SMC32},
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c b/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
index 92ae661..6041472 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
@@ -79,7 +79,7 @@
 /*
  * Using FFA version expected for SPM.
  */
-#define SPM_VERSION MAKE_FFA_VERSION(FFA_VERSION_MAJOR, FFA_VERSION_MINOR)
+#define SPM_VERSION FFA_VERSION_COMPILED
 
 /******************************************************************************
  * FF-A Features ABI Tests
@@ -90,11 +90,11 @@
 	const struct ffa_features_test *func_ids_target;
 	const struct ffa_features_test feature_ids_target[] = {
 		{"FFA_FEATURE_MEI", FFA_FEATURE_MEI, FFA_ERROR, 0,
-			MAKE_FFA_VERSION(1, 1)},
+			FFA_VERSION_1_1},
 		{"FFA_FEATURE_SRI", FFA_FEATURE_SRI, FFA_SUCCESS_SMC32, 0,
-			MAKE_FFA_VERSION(1, 1)},
+			FFA_VERSION_1_1},
 		{"FFA_FEATURE_NPI", FFA_FEATURE_NPI, FFA_ERROR, 0,
-			MAKE_FFA_VERSION(1, 1)},
+			FFA_VERSION_1_1},
 	};
 	unsigned int test_target_size =
 		get_ffa_feature_test_target(&func_ids_target);
@@ -214,7 +214,7 @@
  */
 test_result_t test_ffa_version_bit31(void)
 {
-	return test_ffa_version(FFA_VERSION_BIT31_MASK | SPM_VERSION,
+	return test_ffa_version(FFA_VERSION_MBZ_BIT | SPM_VERSION,
 				FFA_ERROR_NOT_SUPPORTED);
 }
 
@@ -223,7 +223,7 @@
  */
 test_result_t test_ffa_version_bigger(void)
 {
-	return test_ffa_version(MAKE_FFA_VERSION(FFA_VERSION_MAJOR + 1, 0),
+	return test_ffa_version(make_ffa_version(2, 0),
 				FFA_ERROR_NOT_SUPPORTED);
 }
 
@@ -232,7 +232,7 @@
  */
 test_result_t test_ffa_version_smaller(void)
 {
-	return test_ffa_version(MAKE_FFA_VERSION(0, 9),
+	return test_ffa_version(make_ffa_version(0, 9),
 				FFA_ERROR_NOT_SUPPORTED);
 }