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;
/*