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