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; \
} \