refactor: add explicit underlying types to enums
* Set the underlying type of `ffa_error` to `uint32_t`. This reduces the
need for explicit casts in most cases.
* Set the underlying types for other enums to `uint32_t`, where they are
specified as such in the FF-A specification (`ffa_version`,
`ffa_feature_id`, `ffa_mem_perm`, `ffa_framework_msg_func`).
* Set the underlying types of `ffa_data_access`,
`ffa_instruction_access`, `ffa_memory_type`,
`ffa_memory_cacheability`, `ffa_memory_shareability`,
`ffa_memory_security` to `uint8_t`. This allows them to be stored
directly in the `ffa_data_access_t` and `ffa_memory_attributes_t`
structs without increasing their size.
Change-Id: I7da103f7507929ffb2e66914daa3cd9e67186300
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/inc/vmapi/hf/ffa.h b/inc/vmapi/hf/ffa.h
index eca1a51..240de5e 100644
--- a/inc/vmapi/hf/ffa.h
+++ b/inc/vmapi/hf/ffa.h
@@ -17,7 +17,7 @@
*
* See FF-A specification v1.2 ALP1, section 13.2.1.
*/
-enum ffa_version {
+enum ffa_version : uint32_t {
FFA_VERSION_1_0 = 0x10000,
FFA_VERSION_1_1 = 0x10001,
FFA_VERSION_1_2 = 0x10002,
@@ -155,18 +155,24 @@
/**
* FF-A error codes.
* Don't forget to update `ffa_error_name` if you add a new one.
+ *
+ * NOTE: Error codes have negative values, but we set the underlying type of the
+ * enum to `uint32_t` because it is more convenient to treat them as unsigned
+ * values: the SMCC calling convention specifies that signed 32 bit values must
+ * be zero-extended when passed in 64-bit registers (ie the upper 32 bits must
+ * be zero).
*/
-enum ffa_error {
- FFA_NOT_SUPPORTED = -1,
- FFA_INVALID_PARAMETERS = -2,
- FFA_NO_MEMORY = -3,
- FFA_BUSY = -4,
- FFA_INTERRUPTED = -5,
- FFA_DENIED = -6,
- FFA_RETRY = -7,
- FFA_ABORTED = -8,
- FFA_NO_DATA = -9,
- FFA_NOT_READY = -10,
+enum ffa_error : uint32_t {
+ FFA_NOT_SUPPORTED = UINT32_C(-1),
+ FFA_INVALID_PARAMETERS = UINT32_C(-2),
+ FFA_NO_MEMORY = UINT32_C(-3),
+ FFA_BUSY = UINT32_C(-4),
+ FFA_INTERRUPTED = UINT32_C(-5),
+ FFA_DENIED = UINT32_C(-6),
+ FFA_RETRY = UINT32_C(-7),
+ FFA_ABORTED = UINT32_C(-8),
+ FFA_NO_DATA = UINT32_C(-9),
+ FFA_NOT_READY = UINT32_C(-10),
};
/* clang-format on */
@@ -341,7 +347,7 @@
#define FFA_FEATURES_MEM_RETRIEVE_REQ_MBZ_LO_BIT (2U)
#define FFA_FEATURES_MEM_RETRIEVE_REQ_MBZ_BIT (0U)
-enum ffa_feature_id {
+enum ffa_feature_id : uint32_t {
/* Query interrupt ID of Notification Pending Interrupt. */
FFA_FEATURE_NPI = 1,
@@ -374,7 +380,7 @@
* The type of memory permissions used by `FFA_MEM_PERM_GET` and
* `FFA_MEM_PERM_SET`.
*/
-enum ffa_mem_perm {
+enum ffa_mem_perm : uint32_t {
FFA_MEM_PERM_RO = 0x7,
FFA_MEM_PERM_RW = 0x5,
FFA_MEM_PERM_RX = 0x3,
@@ -592,7 +598,7 @@
/* The maximum length possible for a single message. */
#define FFA_MSG_PAYLOAD_MAX HF_MAILBOX_SIZE
-enum ffa_data_access {
+enum ffa_data_access : uint8_t {
FFA_DATA_ACCESS_NOT_SPECIFIED,
FFA_DATA_ACCESS_RO,
FFA_DATA_ACCESS_RW,
@@ -613,7 +619,7 @@
}
}
-enum ffa_instruction_access {
+enum ffa_instruction_access : uint8_t {
FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
FFA_INSTRUCTION_ACCESS_NX,
FFA_INSTRUCTION_ACCESS_X,
@@ -635,7 +641,7 @@
}
}
-enum ffa_memory_type {
+enum ffa_memory_type : uint8_t {
FFA_MEMORY_NOT_SPECIFIED_MEM,
FFA_MEMORY_DEVICE_MEM,
FFA_MEMORY_NORMAL_MEM,
@@ -653,7 +659,7 @@
}
}
-enum ffa_memory_cacheability {
+enum ffa_memory_cacheability : uint8_t {
FFA_MEMORY_CACHE_RESERVED = 0x0,
FFA_MEMORY_CACHE_NON_CACHEABLE = 0x1,
FFA_MEMORY_CACHE_RESERVED_1 = 0x2,
@@ -694,7 +700,7 @@
}
}
-enum ffa_memory_shareability {
+enum ffa_memory_shareability : uint8_t {
FFA_MEMORY_SHARE_NON_SHAREABLE,
FFA_MEMORY_SHARE_RESERVED,
FFA_MEMORY_OUTER_SHAREABLE,
@@ -721,7 +727,7 @@
* Per section 10.10.4.1, NS bit is reserved for FFA_MEM_DONATE/LEND/SHARE
* and FFA_MEM_RETRIEVE_REQUEST.
*/
-enum ffa_memory_security {
+enum ffa_memory_security : uint8_t {
FFA_MEMORY_SECURITY_UNSPECIFIED = 0,
FFA_MEMORY_SECURITY_SECURE = 0,
FFA_MEMORY_SECURITY_NON_SECURE,
@@ -739,22 +745,28 @@
}
typedef struct {
- uint8_t data_access : 2;
- uint8_t instruction_access : 2;
+ enum ffa_data_access data_access : 2;
+ enum ffa_instruction_access instruction_access : 2;
} ffa_memory_access_permissions_t;
+static_assert(sizeof(ffa_memory_access_permissions_t) == sizeof(uint8_t),
+ "ffa_memory_access_permissions_t must be 8 bits wide");
+
/**
* This corresponds to table 10.18 of the FF-A v1.1 EAC0 specification, "Memory
* region attributes descriptor".
*/
typedef struct {
- uint8_t shareability : 2;
- uint8_t cacheability : 2;
- uint8_t type : 2;
- uint8_t security : 2;
+ enum ffa_memory_shareability shareability : 2;
+ enum ffa_memory_cacheability cacheability : 2;
+ enum ffa_memory_type type : 2;
+ enum ffa_memory_security security : 2;
uint8_t : 8;
} ffa_memory_attributes_t;
+static_assert(sizeof(ffa_memory_attributes_t) == sizeof(uint16_t),
+ "ffa_memory_attributes_t must be 16 bits wide");
+
/* FF-A v1.1 EAC0 states bit [15:7] Must Be Zero. */
#define FFA_MEMORY_ATTRIBUTES_MBZ_MASK 0xFF80U
@@ -947,7 +959,7 @@
* Identifies FF-A framework messages. See sections 18.2 and 18.3 of v1.2 FF-A
* specification.
*/
-enum ffa_framework_msg_func {
+enum ffa_framework_msg_func : uint32_t {
/* Power management framework messages. */
FFA_FRAMEWORK_MSG_PSCI_REQ = 0,
FFA_FRAMEWORK_MSG_PSCI_RESP = 2,
diff --git a/src/api.c b/src/api.c
index ebb6561..9a183a8 100644
--- a/src/api.c
+++ b/src/api.c
@@ -2408,7 +2408,7 @@
static_assert(sizeof(enum ffa_version) == 4,
"enum ffa_version must be 4 bytes wide");
- const struct ffa_value error = {.func = (uint32_t)FFA_NOT_SUPPORTED};
+ const struct ffa_value error = {.func = FFA_NOT_SUPPORTED};
struct vm_locked current_vm_locked;
uint16_t compiled_major = ffa_version_get_major(FFA_VERSION_COMPILED);
@@ -2456,7 +2456,7 @@
current_vm_locked.vm->ffa_version = requested_version;
vm_unlock(¤t_vm_locked);
- return (struct ffa_value){.func = (uint32_t)FFA_VERSION_COMPILED};
+ return (struct ffa_value){.func = FFA_VERSION_COMPILED};
}
/**
diff --git a/src/arch/aarch64/hftest/power_mgmt.c b/src/arch/aarch64/hftest/power_mgmt.c
index 68a2c33..aefa120 100644
--- a/src/arch/aarch64/hftest/power_mgmt.c
+++ b/src/arch/aarch64/hftest/power_mgmt.c
@@ -46,6 +46,7 @@
}
}
+/* NOLINTBEGIN(readability-redundant-casting) */
static_assert((uint32_t)POWER_STATUS_ON == (uint32_t)PSCI_RETURN_ON,
"power_status enum values must match PSCI return values.");
static_assert((uint32_t)POWER_STATUS_OFF == (uint32_t)PSCI_RETURN_OFF,
@@ -53,6 +54,7 @@
static_assert((uint32_t)POWER_STATUS_ON_PENDING ==
(uint32_t)PSCI_RETURN_ON_PENDING,
"power_status enum values must match PSCI return values.");
+/* NOLINTEND(readability-redundant-casting) */
/**
* Returns the power status of the given CPU.
diff --git a/src/arch/aarch64/inc/hf/arch/vm/power_mgmt.h b/src/arch/aarch64/inc/hf/arch/vm/power_mgmt.h
index 7bf8d4b..e41edf6 100644
--- a/src/arch/aarch64/inc/hf/arch/vm/power_mgmt.h
+++ b/src/arch/aarch64/inc/hf/arch/vm/power_mgmt.h
@@ -13,7 +13,7 @@
#include "hf/arch/types.h"
-enum power_status {
+enum power_status : uint32_t {
POWER_STATUS_ON,
POWER_STATUS_OFF,
POWER_STATUS_ON_PENDING,
diff --git a/src/arch/aarch64/psci.h b/src/arch/aarch64/psci.h
index 55fc17d..c90ec94 100644
--- a/src/arch/aarch64/psci.h
+++ b/src/arch/aarch64/psci.h
@@ -13,7 +13,7 @@
/* clang-format off */
/* The following are PSCI version codes. */
-enum psci_version {
+enum psci_version : uint32_t {
PSCI_VERSION_0_2 = 0x00000002,
PSCI_VERSION_1_0 = 0x00010000,
PSCI_VERSION_1_1 = 0x00010001,
@@ -43,7 +43,7 @@
#define PSCI_MEM_PROTECT_CHECK_RANGE 0x84000014
/* The following are return codes for PSCI. */
-enum psci_return_code {
+enum psci_return_code : uint32_t {
PSCI_RETURN_ON_PENDING = 2,
PSCI_RETURN_OFF = 1,
PSCI_RETURN_ON = 0,
diff --git a/src/ffa/hypervisor/init.c b/src/ffa/hypervisor/init.c
index b87ca54..f9c98e8 100644
--- a/src/ffa/hypervisor/init.c
+++ b/src/ffa/hypervisor/init.c
@@ -66,7 +66,7 @@
*/
ret = arch_other_world_call((struct ffa_value){
.func = FFA_VERSION_32, .arg1 = FFA_VERSION_COMPILED});
- if (ret.func == (uint32_t)FFA_NOT_SUPPORTED) {
+ if (ret.func == FFA_NOT_SUPPORTED) {
panic("Hypervisor and SPMC versions are not compatible.\n");
}
diff --git a/test/vmapi/ffa_secure_partitions/notifications.c b/test/vmapi/ffa_secure_partitions/notifications.c
index 47a8f8e..93f9b96 100644
--- a/test/vmapi/ffa_secure_partitions/notifications.c
+++ b/test/vmapi/ffa_secure_partitions/notifications.c
@@ -241,7 +241,7 @@
FFA_NOTIFICATION_MASK(1));
EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
EXPECT_EQ(sp_resp(res), SP_ERROR);
- EXPECT_EQ((int32_t)sp_resp_value(res), FFA_INVALID_PARAMETERS);
+ EXPECT_EQ(sp_resp_value(res), FFA_INVALID_PARAMETERS);
}
/**
@@ -265,7 +265,7 @@
FFA_NOTIFICATION_MASK(1));
EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
EXPECT_EQ(sp_resp(res), SP_ERROR);
- EXPECT_EQ((int32_t)sp_resp_value(res), FFA_INVALID_PARAMETERS);
+ EXPECT_EQ(sp_resp_value(res), FFA_INVALID_PARAMETERS);
}
TEST(ffa_notifications, fail_if_global_notif_set_as_per_vcpu)
@@ -285,7 +285,7 @@
FFA_NOTIFICATION_MASK(1));
EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
EXPECT_EQ(sp_resp(res), SP_ERROR);
- EXPECT_EQ((int32_t)sp_resp_value(res), FFA_INVALID_PARAMETERS);
+ EXPECT_EQ(sp_resp_value(res), FFA_INVALID_PARAMETERS);
}
TEST(ffa_notifications, fail_if_per_vcpu_notif_set_as_global)
@@ -305,7 +305,7 @@
FFA_NOTIFICATION_MASK(1));
EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
EXPECT_EQ(sp_resp(res), SP_ERROR);
- EXPECT_EQ((int32_t)sp_resp_value(res), FFA_INVALID_PARAMETERS);
+ EXPECT_EQ(sp_resp_value(res), FFA_INVALID_PARAMETERS);
}
TEST(ffa_notifications, fail_if_mbz_set_in_notifications_bind)
diff --git a/test/vmapi/ffa_secure_partitions/setup_and_discovery.c b/test/vmapi/ffa_secure_partitions/setup_and_discovery.c
index e68079a..1d5f18f 100644
--- a/test/vmapi/ffa_secure_partitions/setup_and_discovery.c
+++ b/test/vmapi/ffa_secure_partitions/setup_and_discovery.c
@@ -363,7 +363,7 @@
res = sp_ffa_features_cmd_send(own_id, receiver_id, FFA_FEATURE_NPI);
EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
EXPECT_EQ(res.arg3, FFA_ERROR_32);
- EXPECT_EQ((int32_t)res.arg4, FFA_NOT_SUPPORTED);
+ EXPECT_EQ(res.arg4, FFA_NOT_SUPPORTED);
}
TEST_PRECONDITION(ffa, secondary_ep_register_supported, service2_is_mp_sp)
@@ -390,5 +390,5 @@
FFA_SECONDARY_EP_REGISTER_64);
EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
EXPECT_EQ(res.arg3, FFA_ERROR_32);
- EXPECT_EQ((int32_t)res.arg4, FFA_NOT_SUPPORTED);
+ EXPECT_EQ(res.arg4, FFA_NOT_SUPPORTED);
}
diff --git a/test/vmapi/primary_only/primary_only.c b/test/vmapi/primary_only/primary_only.c
index 70f50e4..7edcb6b 100644
--- a/test/vmapi/primary_only/primary_only.c
+++ b/test/vmapi/primary_only/primary_only.c
@@ -185,19 +185,17 @@
EXPECT_EQ(ffa_version(current_version), current_version);
EXPECT_EQ(ffa_version(older_compatible_version_0), current_version);
EXPECT_EQ(ffa_version(older_compatible_version_1), current_version);
- EXPECT_EQ((int32_t)ffa_version(0x0), FFA_NOT_SUPPORTED);
- EXPECT_EQ((int32_t)ffa_version(0x1), FFA_NOT_SUPPORTED);
- EXPECT_EQ((int32_t)ffa_version(0x10003), FFA_NOT_SUPPORTED);
- EXPECT_EQ((int32_t)ffa_version(0xffff), FFA_NOT_SUPPORTED);
- EXPECT_EQ((int32_t)ffa_version(0xfffffff), FFA_NOT_SUPPORTED);
+ EXPECT_EQ(ffa_version(0x0), FFA_NOT_SUPPORTED);
+ EXPECT_EQ(ffa_version(0x1), FFA_NOT_SUPPORTED);
+ EXPECT_EQ(ffa_version(0x10003), FFA_NOT_SUPPORTED);
+ EXPECT_EQ(ffa_version(0xffff), FFA_NOT_SUPPORTED);
+ EXPECT_EQ(ffa_version(0xfffffff), FFA_NOT_SUPPORTED);
}
/** Ensures that an invalid call to FFA_VERSION gets an error back. */
TEST(ffa, ffa_version_invalid)
{
- int32_t ret = (int32_t)ffa_version(0x80000000);
-
- EXPECT_EQ(ret, FFA_NOT_SUPPORTED);
+ EXPECT_EQ(ffa_version(0x80000000), FFA_NOT_SUPPORTED);
}
static bool v1_0_or_later(void)
diff --git a/test/vmapi/primary_with_secondaries/dir_msg.c b/test/vmapi/primary_with_secondaries/dir_msg.c
index 5273ae3..f134548 100644
--- a/test/vmapi/primary_with_secondaries/dir_msg.c
+++ b/test/vmapi/primary_with_secondaries/dir_msg.c
@@ -1178,9 +1178,9 @@
ffa_id_t sender_id, ffa_id_t receiver_id, ffa_id_t vm_id,
enum ffa_framework_msg_func framework_func)
{
- assert_vm_availability_message(sender_id, receiver_id, vm_id,
- framework_func, FFA_ERROR_32, 0, 0,
- FFA_INVALID_PARAMETERS, 0);
+ assert_vm_availability_message(
+ sender_id, receiver_id, vm_id, framework_func, FFA_ERROR_32, 0,
+ 0, (enum ffa_framework_msg_func)FFA_INVALID_PARAMETERS, 0);
}
/**