refactor(ff-a): use bitfields for memory access bitmaps

Instead of doing the bit-manipulation manually, these types can be
declared as structs where the fields are given explicit bitwidths. The
compiler will generate the appropriate bit-manipulation automatically.

Change-Id: Ifb66ac6904b8c216ccc18f6f86bbf7c051178f6d
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/inc/hf/ffa_memory_internal.h b/inc/hf/ffa_memory_internal.h
index f240ca2..4df08c9 100644
--- a/inc/hf/ffa_memory_internal.h
+++ b/inc/hf/ffa_memory_internal.h
@@ -20,6 +20,7 @@
 
 #include "hf/check.h"
 #include "hf/ffa_memory.h"
+#include "hf/ffa_v1_0.h"
 #include "hf/mpool.h"
 #include "hf/vm.h"
 
@@ -53,6 +54,13 @@
 	      "struct ffa_features_rxtx_map_params must be 4 "
 	      "bytes long");
 
+static_assert(sizeof(ffa_memory_access_permissions_t) == 1,
+	      "ffa_memory_access_permissions_t must be 1 byte wide");
+static_assert(sizeof(ffa_memory_attributes_t) == 2,
+	      "ffa_memory_attributes_t must be 2 bytes wide");
+static_assert(sizeof(ffa_memory_attributes_v1_0) == 1,
+	      "ffa_memory_attributes_v1_0 must be 1 byte wide");
+
 struct ffa_memory_share_state {
 	/**
 	 * The memory region being shared, or NULL if this share state is
diff --git a/inc/vmapi/hf/ffa.h b/inc/vmapi/hf/ffa.h
index 3293957..438f631 100644
--- a/inc/vmapi/hf/ffa.h
+++ b/inc/vmapi/hf/ffa.h
@@ -447,79 +447,26 @@
 	FFA_MEMORY_SECURITY_NON_SECURE,
 };
 
-typedef uint8_t ffa_memory_access_permissions_t;
+typedef struct {
+	uint8_t data_access : 2;
+	uint8_t instruction_access : 2;
+} ffa_memory_access_permissions_t;
 
 /**
  * This corresponds to table 10.18 of the FF-A v1.1 EAC0 specification, "Memory
  * region attributes descriptor".
  */
-typedef uint16_t ffa_memory_attributes_t;
+typedef struct {
+	uint8_t shareability : 2;
+	uint8_t cacheability : 2;
+	uint8_t type : 2;
+	uint8_t security : 2;
+	uint8_t : 8;
+} ffa_memory_attributes_t;
 
 /* FF-A v1.1 EAC0 states bit [15:7] Must Be Zero. */
 #define FFA_MEMORY_ATTRIBUTES_MBZ_MASK 0xFF80U
 
-#define FFA_DATA_ACCESS_OFFSET (0x0U)
-#define FFA_DATA_ACCESS_MASK ((0x3U) << FFA_DATA_ACCESS_OFFSET)
-
-#define FFA_INSTRUCTION_ACCESS_OFFSET (0x2U)
-#define FFA_INSTRUCTION_ACCESS_MASK ((0x3U) << FFA_INSTRUCTION_ACCESS_OFFSET)
-
-#define FFA_MEMORY_TYPE_OFFSET (0x4U)
-#define FFA_MEMORY_TYPE_MASK ((0x3U) << FFA_MEMORY_TYPE_OFFSET)
-
-#define FFA_MEMORY_SECURITY_OFFSET (0x6U)
-#define FFA_MEMORY_SECURITY_MASK ((0x1U) << FFA_MEMORY_SECURITY_OFFSET)
-
-#define FFA_MEMORY_CACHEABILITY_OFFSET (0x2U)
-#define FFA_MEMORY_CACHEABILITY_MASK ((0x3U) << FFA_MEMORY_CACHEABILITY_OFFSET)
-
-#define FFA_MEMORY_SHAREABILITY_OFFSET (0x0U)
-#define FFA_MEMORY_SHAREABILITY_MASK ((0x3U) << FFA_MEMORY_SHAREABILITY_OFFSET)
-
-#define ATTR_FUNCTION_SET(name, container_type, offset, mask)                \
-	static inline void ffa_set_##name##_attr(container_type *attr,       \
-						 const enum ffa_##name perm) \
-	{                                                                    \
-		*attr = (*attr & ~(mask)) | ((perm << offset) & mask);       \
-	}
-
-#define ATTR_FUNCTION_GET(name, container_type, offset, mask)      \
-	static inline enum ffa_##name ffa_get_##name##_attr(       \
-		container_type attr)                               \
-	{                                                          \
-		return (enum ffa_##name)((attr & mask) >> offset); \
-	}
-
-ATTR_FUNCTION_SET(data_access, ffa_memory_access_permissions_t,
-		  FFA_DATA_ACCESS_OFFSET, FFA_DATA_ACCESS_MASK)
-ATTR_FUNCTION_GET(data_access, ffa_memory_access_permissions_t,
-		  FFA_DATA_ACCESS_OFFSET, FFA_DATA_ACCESS_MASK)
-
-ATTR_FUNCTION_SET(instruction_access, ffa_memory_access_permissions_t,
-		  FFA_INSTRUCTION_ACCESS_OFFSET, FFA_INSTRUCTION_ACCESS_MASK)
-ATTR_FUNCTION_GET(instruction_access, ffa_memory_access_permissions_t,
-		  FFA_INSTRUCTION_ACCESS_OFFSET, FFA_INSTRUCTION_ACCESS_MASK)
-
-ATTR_FUNCTION_SET(memory_type, ffa_memory_attributes_t, FFA_MEMORY_TYPE_OFFSET,
-		  FFA_MEMORY_TYPE_MASK)
-ATTR_FUNCTION_GET(memory_type, ffa_memory_attributes_t, FFA_MEMORY_TYPE_OFFSET,
-		  FFA_MEMORY_TYPE_MASK)
-
-ATTR_FUNCTION_SET(memory_cacheability, ffa_memory_attributes_t,
-		  FFA_MEMORY_CACHEABILITY_OFFSET, FFA_MEMORY_CACHEABILITY_MASK)
-ATTR_FUNCTION_GET(memory_cacheability, ffa_memory_attributes_t,
-		  FFA_MEMORY_CACHEABILITY_OFFSET, FFA_MEMORY_CACHEABILITY_MASK)
-
-ATTR_FUNCTION_SET(memory_shareability, ffa_memory_attributes_t,
-		  FFA_MEMORY_SHAREABILITY_OFFSET, FFA_MEMORY_SHAREABILITY_MASK)
-ATTR_FUNCTION_GET(memory_shareability, ffa_memory_attributes_t,
-		  FFA_MEMORY_SHAREABILITY_OFFSET, FFA_MEMORY_SHAREABILITY_MASK)
-
-ATTR_FUNCTION_SET(memory_security, ffa_memory_attributes_t,
-		  FFA_MEMORY_SECURITY_OFFSET, FFA_MEMORY_SECURITY_MASK)
-ATTR_FUNCTION_GET(memory_security, ffa_memory_attributes_t,
-		  FFA_MEMORY_SECURITY_OFFSET, FFA_MEMORY_SECURITY_MASK)
-
 /**
  * A globally-unique ID assigned by the hypervisor for a region of memory being
  * sent between VMs.
diff --git a/inc/vmapi/hf/ffa_v1_0.h b/inc/vmapi/hf/ffa_v1_0.h
index a5315bf..0b7c937 100644
--- a/inc/vmapi/hf/ffa_v1_0.h
+++ b/inc/vmapi/hf/ffa_v1_0.h
@@ -44,6 +44,19 @@
 	uint64_t reserved_0;
 };
 
+typedef struct {
+	uint8_t shareability : 2;
+	uint8_t cacheability : 2;
+	uint8_t type : 2;
+	uint8_t security : 2;
+} ffa_memory_attributes_v1_0;
+
+ffa_memory_attributes_v1_0 ffa_memory_attributes_truncate(
+	ffa_memory_attributes_t attrs);
+
+ffa_memory_attributes_t ffa_memory_attributes_extend(
+	ffa_memory_attributes_v1_0 attrs);
+
 /**
  * Information about a set of pages which are being shared. This corresponds to
  * table 45 of the FF-A 1.0 EAC specification, "Lend, donate or share memory
@@ -56,7 +69,7 @@
 	 * owner.
 	 */
 	ffa_id_t sender;
-	uint8_t attributes;
+	ffa_memory_attributes_v1_0 attributes;
 	/** Reserved field, must be 0. */
 	uint8_t reserved_0;
 	/** Flags to control behaviour of the transaction. */