Use attributes rather than header for legacy memory sharing.

This removes the architected message header.

Bug: 132420445
Change-Id: Id568f379be194bca552506a470355c018a611c2b
diff --git a/inc/hf/spci_internal.h b/inc/hf/spci_internal.h
index 1382669..1fc226f 100644
--- a/inc/hf/spci_internal.h
+++ b/inc/hf/spci_internal.h
@@ -63,6 +63,5 @@
 
 struct spci_value spci_msg_handle_architected_message(
 	struct vm_locked to_locked, struct vm_locked from_locked,
-	const struct spci_architected_message_header
-		*architected_message_replica,
-	uint32_t size, struct mpool *api_page_pool);
+	struct spci_memory_region *memory_region, uint32_t size,
+	uint32_t attributes, struct mpool *api_page_pool);
diff --git a/inc/vmapi/hf/call.h b/inc/vmapi/hf/call.h
index 2e4a506..bd1c0bd 100644
--- a/inc/vmapi/hf/call.h
+++ b/inc/vmapi/hf/call.h
@@ -111,7 +111,7 @@
  *
  * Attributes may include:
  *  - SPCI_MSG_SEND_NOTIFY, to notify the caller when it should try again.
- *  - SPCI_MSG_SEND_LEGACY_MEMORY, to send a legacy architected memory sharing
+ *  - SPCI_MSG_SEND_LEGACY_MEMORY_*, to send a legacy architected memory sharing
  *    message.
  *
  * Returns SPCI_SUCCESS if the message is sent, or an error code otherwise:
diff --git a/inc/vmapi/hf/spci.h b/inc/vmapi/hf/spci.h
index 812865b..2181799 100644
--- a/inc/vmapi/hf/spci.h
+++ b/inc/vmapi/hf/spci.h
@@ -54,22 +54,17 @@
 #define SPCI_RETRY              INT32_C(-7)
 #define SPCI_ABORTED            INT32_C(-8)
 
-/* Architected memory sharing message IDs. */
-enum spci_memory_share {
-	SPCI_MEMORY_DONATE = 0x0,
-	SPCI_MEMORY_LEND = 0x1,
-	SPCI_MEMORY_SHARE = 0x2,
-	SPCI_MEMORY_RELINQUISH = 0x3,
-};
-
 /* SPCI function specific constants. */
 #define SPCI_MSG_RECV_BLOCK  0x1
 #define SPCI_MSG_RECV_BLOCK_MASK  0x1
 
 #define SPCI_MSG_SEND_NOTIFY 0x1
 #define SPCI_MSG_SEND_NOTIFY_MASK 0x1
-#define SPCI_MSG_SEND_LEGACY_MEMORY      0x2
-#define SPCI_MSG_SEND_LEGACY_MEMORY_MASK 0x2
+#define SPCI_MSG_SEND_LEGACY_MEMORY_DONATE 0x10
+#define SPCI_MSG_SEND_LEGACY_MEMORY_LEND 0x20
+#define SPCI_MSG_SEND_LEGACY_MEMORY_SHARE 0x30
+#define SPCI_MSG_SEND_LEGACY_MEMORY_RELINQUISH 0x40
+#define SPCI_MSG_SEND_LEGACY_MEMORY_MASK 0x70
 
 #define SPCI_SLEEP_INDEFINITE 0
 
@@ -230,18 +225,6 @@
 	return ((uint32_t)vm_id << 16) | vcpu_index;
 }
 
-struct spci_architected_message_header {
-	uint16_t type;
-
-	/*
-	 * TODO: Padding is present to ensure that the field
-	 * payload is aligned on a 64B boundary. SPCI
-	 * spec must be updated to reflect this.
-	 */
-	uint16_t reserved[3];
-	uint8_t payload[];
-};
-
 struct spci_memory_region_constituent {
 	/**
 	 * The base IPA of the constituent memory region, aligned to 4 kiB page
@@ -322,16 +305,6 @@
 			   memory_region->constituent_offset);
 }
 
-void spci_architected_message_init(void *message, enum spci_memory_share type);
-
-/** Gets the spci_memory_region within an architected message. */
-static inline struct spci_memory_region *spci_get_memory_region(void *message)
-{
-	struct spci_architected_message_header *architected_header =
-		(struct spci_architected_message_header *)message;
-	return (struct spci_memory_region *)architected_header->payload;
-}
-
 uint32_t spci_memory_region_init(
 	struct spci_memory_region *memory_region, spci_vm_id_t receiver,
 	const struct spci_memory_region_constituent constituents[],
@@ -339,73 +312,3 @@
 	spci_memory_region_flags_t flags, enum spci_memory_access access,
 	enum spci_memory_type type, enum spci_memory_cacheability cacheability,
 	enum spci_memory_shareability shareability);
-
-uint32_t spci_memory_init(
-	void *message, enum spci_memory_share share_type, spci_vm_id_t receiver,
-	struct spci_memory_region_constituent *region_constituents,
-	uint32_t constituent_count, uint32_t tag,
-	spci_memory_region_flags_t flags, enum spci_memory_access access,
-	enum spci_memory_type type, enum spci_memory_cacheability cacheability,
-	enum spci_memory_shareability shareability);
-
-/** Constructs an SPCI donate memory region message. */
-static inline uint32_t spci_memory_donate_init(
-	void *message, spci_vm_id_t receiver,
-	struct spci_memory_region_constituent *region_constituents,
-	uint32_t constituent_count, uint32_t tag,
-	enum spci_memory_access access, enum spci_memory_type type,
-	enum spci_memory_cacheability cacheability,
-	enum spci_memory_shareability shareability)
-{
-	return spci_memory_init(message, SPCI_MEMORY_DONATE, receiver,
-				region_constituents, constituent_count, tag, 0,
-				access, type, cacheability, shareability);
-}
-
-/**
- * Constructs an SPCI memory region lend message.
- */
-static inline uint32_t spci_memory_lend_init(
-	void *message, spci_vm_id_t receiver,
-	struct spci_memory_region_constituent *region_constituents,
-	uint32_t constituent_count, uint32_t tag,
-	enum spci_memory_access access, enum spci_memory_type type,
-	enum spci_memory_cacheability cacheability,
-	enum spci_memory_shareability shareability)
-{
-	return spci_memory_init(message, SPCI_MEMORY_LEND, receiver,
-				region_constituents, constituent_count, tag, 0,
-				access, type, cacheability, shareability);
-}
-
-/**
- * Constructs an SPCI memory region share message.
- */
-static inline uint32_t spci_memory_share_init(
-	void *message, spci_vm_id_t receiver,
-	struct spci_memory_region_constituent *region_constituents,
-	uint32_t constituent_count, uint32_t tag,
-	enum spci_memory_access access, enum spci_memory_type type,
-	enum spci_memory_cacheability cacheability,
-	enum spci_memory_shareability shareability)
-{
-	return spci_memory_init(message, SPCI_MEMORY_SHARE, receiver,
-				region_constituents, constituent_count, tag, 0,
-				access, type, cacheability, shareability);
-}
-
-/**
- * Constructs an SPCI memory region relinquish message.
- * A set of memory regions can be given back to the owner.
- */
-static inline uint32_t spci_memory_relinquish_init(
-	void *message, spci_vm_id_t receiver,
-	struct spci_memory_region_constituent *region_constituents,
-	uint32_t constituent_count, uint32_t tag)
-{
-	return spci_memory_init(message, SPCI_MEMORY_RELINQUISH, receiver,
-				region_constituents, constituent_count, tag, 0,
-				SPCI_MEMORY_RW_X, SPCI_MEMORY_DEVICE_MEM,
-				SPCI_MEMORY_DEV_NGNRNE,
-				SPCI_MEMORY_SHARE_NON_SHAREABLE);
-}
diff --git a/src/api.c b/src/api.c
index 210359b..d7e1eac 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1002,35 +1002,22 @@
 	}
 
 	/* Handle legacy memory sharing messages. */
-	if ((attributes & SPCI_MSG_SEND_LEGACY_MEMORY_MASK) ==
-	    SPCI_MSG_SEND_LEGACY_MEMORY) {
+	if ((attributes & SPCI_MSG_SEND_LEGACY_MEMORY_MASK) != 0) {
 		/*
 		 * Buffer holding the internal copy of the shared memory
 		 * regions.
 		 */
-		struct spci_architected_message_header
-			*architected_message_replica =
-				(struct spci_architected_message_header *)
-					cpu_get_buffer(current->cpu->id);
+		uint8_t *message_replica = cpu_get_buffer(current->cpu->id);
 		uint32_t message_buffer_size =
 			cpu_get_buffer_size(current->cpu->id);
 
-		struct spci_architected_message_header *architected_header =
-			(struct spci_architected_message_header *)from_msg;
-
 		if (size > message_buffer_size) {
 			ret = spci_error(SPCI_INVALID_PARAMETERS);
 			goto out;
 		}
 
-		if (size < sizeof(struct spci_architected_message_header)) {
-			ret = spci_error(SPCI_INVALID_PARAMETERS);
-			goto out;
-		}
-
 		/* Copy the architected message into the internal buffer. */
-		memcpy_s(architected_message_replica, message_buffer_size,
-			 architected_header, size);
+		memcpy_s(message_replica, message_buffer_size, from_msg, size);
 
 		/*
 		 * Note that architected_message_replica is passed as the third
@@ -1043,7 +1030,8 @@
 		 */
 		ret = spci_msg_handle_architected_message(
 			vm_to_from_lock.vm1, vm_to_from_lock.vm2,
-			architected_message_replica, size, &api_page_pool);
+			(struct spci_memory_region *)message_replica, size,
+			attributes, &api_page_pool);
 
 		if (ret.func != SPCI_SUCCESS_32) {
 			goto out;
diff --git a/src/spci_architected_message.c b/src/spci_architected_message.c
index 2c3ff89..d427cd2 100644
--- a/src/spci_architected_message.c
+++ b/src/spci_architected_message.c
@@ -71,7 +71,7 @@
  *
  */
 static bool spci_msg_check_transition(struct vm *to, struct vm *from,
-				      enum spci_memory_share share,
+				      uint32_t share_type,
 				      uint32_t *orig_from_mode,
 				      struct spci_memory_region *memory_region,
 				      uint32_t memory_to_attributes,
@@ -267,23 +267,23 @@
 		return false;
 	}
 
-	switch (share) {
-	case SPCI_MEMORY_DONATE:
+	switch (share_type) {
+	case SPCI_MSG_SEND_LEGACY_MEMORY_DONATE:
 		mem_transition_table = donate_transitions;
 		transition_table_size = size_donate_transitions;
 		break;
 
-	case SPCI_MEMORY_LEND:
+	case SPCI_MSG_SEND_LEGACY_MEMORY_LEND:
 		mem_transition_table = lend_transitions;
 		transition_table_size = size_lend_transitions;
 		break;
 
-	case SPCI_MEMORY_SHARE:
+	case SPCI_MSG_SEND_LEGACY_MEMORY_SHARE:
 		mem_transition_table = share_transitions;
 		transition_table_size = size_share_transitions;
 		break;
 
-	case SPCI_MEMORY_RELINQUISH:
+	case SPCI_MSG_SEND_LEGACY_MEMORY_RELINQUISH:
 		mem_transition_table = relinquish_transitions;
 		transition_table_size = size_relinquish_transitions;
 		break;
@@ -452,7 +452,7 @@
 static struct spci_value spci_share_memory(
 	struct vm_locked to_locked, struct vm_locked from_locked,
 	struct spci_memory_region *memory_region, uint32_t memory_to_attributes,
-	enum spci_memory_share share, struct mpool *api_page_pool)
+	uint32_t share_type, struct mpool *api_page_pool)
 {
 	struct vm *to = to_locked.vm;
 	struct vm *from = from_locked.vm;
@@ -483,7 +483,7 @@
 	 * in the memory exchange, ensure that all constituents of a memory
 	 * region being shared are at the same state.
 	 */
-	if (!spci_msg_check_transition(to, from, share, &orig_from_mode,
+	if (!spci_msg_check_transition(to, from, share_type, &orig_from_mode,
 				       memory_region, memory_to_attributes,
 				       &from_mode, &to_mode)) {
 		return spci_error(SPCI_INVALID_PARAMETERS);
@@ -567,7 +567,7 @@
 static struct spci_value spci_validate_call_share_memory(
 	struct vm_locked to_locked, struct vm_locked from_locked,
 	struct spci_memory_region *memory_region, uint32_t memory_share_size,
-	enum spci_memory_share share, struct mpool *api_page_pool)
+	uint32_t share_type, struct mpool *api_page_pool)
 {
 	uint32_t memory_to_attributes;
 	uint32_t attributes_size;
@@ -598,14 +598,14 @@
 		return spci_error(SPCI_INVALID_PARAMETERS);
 	}
 
-	switch (share) {
-	case SPCI_MEMORY_DONATE:
-	case SPCI_MEMORY_LEND:
-	case SPCI_MEMORY_SHARE:
+	switch (share_type) {
+	case SPCI_MSG_SEND_LEGACY_MEMORY_DONATE:
+	case SPCI_MSG_SEND_LEGACY_MEMORY_LEND:
+	case SPCI_MSG_SEND_LEGACY_MEMORY_SHARE:
 		memory_to_attributes = spci_memory_attrs_to_mode(
 			memory_region->attributes[0].memory_attributes);
 		break;
-	case SPCI_MEMORY_RELINQUISH:
+	case SPCI_MSG_SEND_LEGACY_MEMORY_RELINQUISH:
 		memory_to_attributes = MM_MODE_R | MM_MODE_W | MM_MODE_X;
 		break;
 	default:
@@ -614,7 +614,8 @@
 	}
 
 	return spci_share_memory(to_locked, from_locked, memory_region,
-				 memory_to_attributes, share, api_page_pool);
+				 memory_to_attributes, share_type,
+				 api_page_pool);
 }
 
 /**
@@ -624,21 +625,13 @@
  */
 struct spci_value spci_msg_handle_architected_message(
 	struct vm_locked to_locked, struct vm_locked from_locked,
-	const struct spci_architected_message_header
-		*architected_message_replica,
-	uint32_t size, struct mpool *api_page_pool)
+	struct spci_memory_region *memory_region, uint32_t size,
+	uint32_t attributes, struct mpool *api_page_pool)
 {
-	struct spci_value ret;
-	struct spci_memory_region *memory_region =
-		(struct spci_memory_region *)
-			architected_message_replica->payload;
-	uint32_t message_type = architected_message_replica->type;
-	uint32_t memory_share_size =
-		size - sizeof(struct spci_architected_message_header);
-
-	ret = spci_validate_call_share_memory(to_locked, from_locked,
-					      memory_region, memory_share_size,
-					      message_type, api_page_pool);
+	uint32_t share_type = attributes & SPCI_MSG_SEND_LEGACY_MEMORY_MASK;
+	struct spci_value ret = spci_validate_call_share_memory(
+		to_locked, from_locked, memory_region, size, share_type,
+		api_page_pool);
 
 	/* Copy data to the destination Rx. */
 	/*
@@ -651,11 +644,10 @@
 	 */
 	if (ret.func == SPCI_SUCCESS_32) {
 		memcpy_s(to_locked.vm->mailbox.recv, SPCI_MSG_PAYLOAD_MAX,
-			 architected_message_replica, size);
+			 memory_region, size);
 		to_locked.vm->mailbox.recv_size = size;
 		to_locked.vm->mailbox.recv_sender = from_locked.vm->id;
-		to_locked.vm->mailbox.recv_attributes =
-			SPCI_MSG_SEND_LEGACY_MEMORY;
+		to_locked.vm->mailbox.recv_attributes = share_type;
 	}
 
 	return ret;
diff --git a/test/vmapi/primary_with_secondaries/memory_sharing.c b/test/vmapi/primary_with_secondaries/memory_sharing.c
index 7e88fdc..78938af 100644
--- a/test/vmapi/primary_with_secondaries/memory_sharing.c
+++ b/test/vmapi/primary_with_secondaries/memory_sharing.c
@@ -31,7 +31,7 @@
  * Helper function to test sending memory in the different configurations.
  */
 static void check_cannot_send_memory(
-	struct mailbox_buffers mb, enum spci_memory_share mode,
+	struct mailbox_buffers mb, uint32_t mode,
 	struct spci_memory_region_constituent constituents[],
 	int num_constituents, int32_t avoid_vm)
 
@@ -63,32 +63,35 @@
 		for (j = 0; j < ARRAY_SIZE(access); ++j) {
 			for (k = 0; k < ARRAY_SIZE(shareability); ++k) {
 				for (l = 0; l < ARRAY_SIZE(cacheability); ++l) {
-					uint32_t msg_size = spci_memory_init(
-						mb.send, mode, vms[i],
-						constituents, num_constituents,
-						0, 0, access[j],
-						SPCI_MEMORY_NORMAL_MEM,
-						cacheability[l],
-						shareability[k]);
+					uint32_t msg_size =
+						spci_memory_region_init(
+							mb.send, vms[i],
+							constituents,
+							num_constituents, 0, 0,
+							access[j],
+							SPCI_MEMORY_NORMAL_MEM,
+							cacheability[l],
+							shareability[k]);
 					EXPECT_SPCI_ERROR(
-						spci_msg_send(
-							HF_PRIMARY_VM_ID,
-							vms[i], msg_size,
-							SPCI_MSG_SEND_LEGACY_MEMORY),
+						spci_msg_send(HF_PRIMARY_VM_ID,
+							      vms[i], msg_size,
+							      mode),
 						SPCI_INVALID_PARAMETERS);
 				}
 				for (l = 0; l < ARRAY_SIZE(device); ++l) {
-					uint32_t msg_size = spci_memory_init(
-						mb.send, mode, vms[i],
-						constituents, num_constituents,
-						0, 0, access[j],
-						SPCI_MEMORY_DEVICE_MEM,
-						device[l], shareability[k]);
+					uint32_t msg_size =
+						spci_memory_region_init(
+							mb.send, vms[i],
+							constituents,
+							num_constituents, 0, 0,
+							access[j],
+							SPCI_MEMORY_DEVICE_MEM,
+							device[l],
+							shareability[k]);
 					EXPECT_SPCI_ERROR(
-						spci_msg_send(
-							HF_PRIMARY_VM_ID,
-							vms[i], msg_size,
-							SPCI_MSG_SEND_LEGACY_MEMORY),
+						spci_msg_send(HF_PRIMARY_VM_ID,
+							      vms[i], msg_size,
+							      mode),
 						SPCI_INVALID_PARAMETERS);
 				}
 			}
@@ -105,8 +108,8 @@
 	int num_constituents, int32_t avoid_vm)
 
 {
-	check_cannot_send_memory(mb, SPCI_MEMORY_LEND, constituents,
-				 num_constituents, avoid_vm);
+	check_cannot_send_memory(mb, SPCI_MSG_SEND_LEGACY_MEMORY_LEND,
+				 constituents, num_constituents, avoid_vm);
 }
 
 /**
@@ -118,8 +121,8 @@
 	int num_constituents, int32_t avoid_vm)
 
 {
-	check_cannot_send_memory(mb, SPCI_MEMORY_SHARE, constituents,
-				 num_constituents, avoid_vm);
+	check_cannot_send_memory(mb, SPCI_MSG_SEND_LEGACY_MEMORY_SHARE,
+				 constituents, num_constituents, avoid_vm);
 }
 
 /**
@@ -141,14 +144,14 @@
 		if (vms[i] == avoid_vm) {
 			continue;
 		}
-		msg_size = spci_memory_donate_init(
-			mb.send, vms[i], constituents, num_constituents, 0,
+		msg_size = spci_memory_region_init(
+			mb.send, vms[i], constituents, num_constituents, 0, 0,
 			SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 			SPCI_MEMORY_CACHE_WRITE_BACK,
 			SPCI_MEMORY_OUTER_SHAREABLE);
 		EXPECT_SPCI_ERROR(
 			spci_msg_send(HF_PRIMARY_VM_ID, vms[i], msg_size,
-				      SPCI_MSG_SEND_LEGACY_MEMORY),
+				      SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
 			SPCI_INVALID_PARAMETERS);
 	}
 }
@@ -168,12 +171,15 @@
 	size_t j;
 	for (i = 0; i < ARRAY_SIZE(vms); ++i) {
 		for (j = 0; j < ARRAY_SIZE(vms); ++j) {
-			uint32_t msg_size = spci_memory_relinquish_init(
+			uint32_t msg_size = spci_memory_region_init(
 				mb.send, vms[i], constituents, num_constituents,
-				0);
+				0, 0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+				SPCI_MEMORY_CACHE_WRITE_BACK,
+				SPCI_MEMORY_OUTER_SHAREABLE);
 			EXPECT_SPCI_ERROR(
-				spci_msg_send(vms[j], vms[i], msg_size,
-					      SPCI_MSG_SEND_LEGACY_MEMORY),
+				spci_msg_send(
+					vms[j], vms[i], msg_size,
+					SPCI_MSG_SEND_LEGACY_MEMORY_RELINQUISH),
 				SPCI_INVALID_PARAMETERS);
 		}
 	}
@@ -197,14 +203,14 @@
 
 	memset_s(ptr, sizeof(pages), 'a', PAGE_SIZE);
 
-	msg_size = spci_memory_init(
-		mb.send, SPCI_MEMORY_SHARE, SERVICE_VM1, constituents,
-		ARRAY_SIZE(constituents), 0, SPCI_MEMORY_REGION_FLAG_CLEAR,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
-		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
+	msg_size = spci_memory_region_init(
+		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
+		SPCI_MEMORY_REGION_FLAG_CLEAR, SPCI_MEMORY_RW_X,
+		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
+		SPCI_MEMORY_OUTER_SHAREABLE);
 
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -243,12 +249,12 @@
 	/* Dirty the memory before sharing it. */
 	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 
-	msg_size = spci_memory_share_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -305,13 +311,13 @@
 		{.address = (uint64_t)pages + PAGE_SIZE, .page_count = 2},
 	};
 
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -349,13 +355,13 @@
 		{.address = (uint64_t)pages + PAGE_SIZE, .page_count = 2},
 	};
 
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -384,12 +390,12 @@
 	/* Dirty the memory before giving it. */
 	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -423,12 +429,12 @@
 	/* Dirty the memory before lending it. */
 	memset_s(ptr, sizeof(pages), 'c', PAGE_SIZE);
 
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -459,12 +465,12 @@
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_lend_relinquish", mb.send);
 
 	/* Share the memory initially. */
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -474,12 +480,12 @@
 	spci_rx_release();
 
 	/* Share the memory again after it has been returned. */
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -504,12 +510,12 @@
 	SERVICE_SELECT(SERVICE_VM2, "spci_memory_lend_relinquish", mb.send);
 
 	/* Share the memory initially. */
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -518,12 +524,12 @@
 	EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
 
 	/* Share the memory with a different VM after it has been returned. */
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM2, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -549,10 +555,10 @@
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
 	EXPECT_EQ(spci_msg_send_attributes(run_res),
-		  SPCI_MSG_SEND_LEGACY_MEMORY);
+		  SPCI_MSG_SEND_LEGACY_MEMORY_DONATE);
 
 	/* Check the memory was cleared. */
-	memory_region = spci_get_memory_region(mb.recv);
+	memory_region = (struct spci_memory_region *)mb.recv;
 	constituents = spci_memory_region_get_constituents(memory_region);
 	ptr = (uint8_t *)constituents[0].address;
 	for (int i = 0; i < PAGE_SIZE; ++i) {
@@ -581,10 +587,10 @@
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
 	EXPECT_EQ(spci_msg_send_attributes(run_res),
-		  SPCI_MSG_SEND_LEGACY_MEMORY);
+		  SPCI_MSG_SEND_LEGACY_MEMORY_LEND);
 
 	/* Check the memory was cleared. */
-	memory_region = spci_get_memory_region(mb.recv);
+	memory_region = (struct spci_memory_region *)mb.recv;
 	constituents = spci_memory_region_get_constituents(memory_region);
 	ptr = (uint8_t *)constituents[0].address;
 	for (int i = 0; i < PAGE_SIZE; ++i) {
@@ -624,12 +630,12 @@
 	 */
 	pages[0] = 0;
 
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -648,12 +654,12 @@
 	pages[PAGE_SIZE] = 1;
 
 	/* Use the secondary VM for this test as the first is now aborted. */
-	msg_size = spci_memory_donate_init(
-		mb.send, SERVICE_VM2, constituents, 2, 0, SPCI_MEMORY_RW_X,
-		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
-		SPCI_MEMORY_OUTER_SHAREABLE);
+	msg_size = spci_memory_region_init(
+		mb.send, SERVICE_VM2, constituents, ARRAY_SIZE(constituents), 0,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -690,12 +696,12 @@
 	 */
 	pages[0] = 0;
 
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -714,12 +720,12 @@
 	pages[PAGE_SIZE] = 1;
 
 	/* Use the secondary VM for this test as the first is now aborted. */
-	msg_size = spci_memory_donate_init(
-		mb.send, SERVICE_VM2, constituents, 2, 0, SPCI_MEMORY_RW_X,
-		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
-		SPCI_MEMORY_OUTER_SHAREABLE);
+	msg_size = spci_memory_region_init(
+		mb.send, SERVICE_VM2, constituents, ARRAY_SIZE(constituents), 0,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -749,13 +755,13 @@
 		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -764,12 +770,12 @@
 	EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
 
 	/* Share the memory with another VM. */
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM2, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -804,12 +810,12 @@
 	EXPECT_EQ(run_res.func, SPCI_MSG_WAIT_32);
 
 	/* Donate memory. */
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -851,12 +857,12 @@
 	};
 
 	/* Donate memory to VM1. */
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -902,15 +908,16 @@
 		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		mb.send, HF_PRIMARY_VM_ID, constituents,
-		ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RW_X,
+		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 
-	EXPECT_SPCI_ERROR(spci_msg_send(HF_PRIMARY_VM_ID, HF_PRIMARY_VM_ID,
-					msg_size, SPCI_MSG_SEND_LEGACY_MEMORY),
-			  SPCI_INVALID_PARAMETERS);
+	EXPECT_SPCI_ERROR(
+		spci_msg_send(HF_PRIMARY_VM_ID, HF_PRIMARY_VM_ID, msg_size,
+			      SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
+		SPCI_INVALID_PARAMETERS);
 }
 
 /**
@@ -928,14 +935,15 @@
 		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, HF_PRIMARY_VM_ID, constituents,
-		ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RW_X,
+		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_SPCI_ERROR(spci_msg_send(HF_PRIMARY_VM_ID, HF_PRIMARY_VM_ID,
-					msg_size, SPCI_MSG_SEND_LEGACY_MEMORY),
-			  SPCI_INVALID_PARAMETERS);
+	EXPECT_SPCI_ERROR(
+		spci_msg_send(HF_PRIMARY_VM_ID, HF_PRIMARY_VM_ID, msg_size,
+			      SPCI_MSG_SEND_LEGACY_MEMORY_LEND),
+		SPCI_INVALID_PARAMETERS);
 }
 
 /**
@@ -953,14 +961,15 @@
 		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
-	msg_size = spci_memory_share_init(
+	msg_size = spci_memory_region_init(
 		mb.send, HF_PRIMARY_VM_ID, constituents,
-		ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RW_X,
+		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
-	EXPECT_SPCI_ERROR(spci_msg_send(HF_PRIMARY_VM_ID, HF_PRIMARY_VM_ID,
-					msg_size, SPCI_MSG_SEND_LEGACY_MEMORY),
-			  SPCI_INVALID_PARAMETERS);
+	EXPECT_SPCI_ERROR(
+		spci_msg_send(HF_PRIMARY_VM_ID, HF_PRIMARY_VM_ID, msg_size,
+			      SPCI_MSG_SEND_LEGACY_MEMORY_SHARE),
+		SPCI_INVALID_PARAMETERS);
 }
 
 /**
@@ -983,38 +992,38 @@
 	};
 
 	/* Try invalid configurations. */
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		mb.send, HF_PRIMARY_VM_ID, constituents,
-		ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RW_X,
+		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_SPCI_ERROR(spci_msg_send(SERVICE_VM1, HF_PRIMARY_VM_ID, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY),
+					SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
 			  SPCI_INVALID_PARAMETERS);
 
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_SPCI_ERROR(spci_msg_send(SERVICE_VM1, SERVICE_VM1, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY),
+					SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
 			  SPCI_INVALID_PARAMETERS);
 
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_SPCI_ERROR(spci_msg_send(SERVICE_VM2, SERVICE_VM1, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY),
+					SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
 			  SPCI_INVALID_PARAMETERS);
 
 	/* Successfully donate to VM1. */
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1049,27 +1058,27 @@
 				{.address = (uint64_t)pages + PAGE_SIZE + j,
 				 .page_count = 1},
 			};
-			uint32_t msg_size = spci_memory_donate_init(
+			uint32_t msg_size = spci_memory_region_init(
 				mb.send, SERVICE_VM1, constituents,
-				ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RW_X,
-				SPCI_MEMORY_NORMAL_MEM,
+				ARRAY_SIZE(constituents), 0, 0,
+				SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 				SPCI_MEMORY_CACHE_WRITE_BACK,
 				SPCI_MEMORY_OUTER_SHAREABLE);
 			EXPECT_SPCI_ERROR(
-				spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1,
-					      msg_size,
-					      SPCI_MSG_SEND_LEGACY_MEMORY),
+				spci_msg_send(
+					HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
+					SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
 				SPCI_INVALID_PARAMETERS);
-			msg_size = spci_memory_lend_init(
+			msg_size = spci_memory_region_init(
 				mb.send, SERVICE_VM1, constituents,
-				ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RW_X,
-				SPCI_MEMORY_NORMAL_MEM,
+				ARRAY_SIZE(constituents), 0, 0,
+				SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 				SPCI_MEMORY_CACHE_WRITE_BACK,
 				SPCI_MEMORY_OUTER_SHAREABLE);
 			EXPECT_SPCI_ERROR(
 				spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1,
 					      msg_size,
-					      SPCI_MSG_SEND_LEGACY_MEMORY),
+					      SPCI_MSG_SEND_LEGACY_MEMORY_LEND),
 				SPCI_INVALID_PARAMETERS);
 		}
 	}
@@ -1094,21 +1103,21 @@
 	};
 
 	/* Check cannot swap VM IDs. */
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_SPCI_ERROR(spci_msg_send(SERVICE_VM1, HF_PRIMARY_VM_ID, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY),
+					SPCI_MSG_SEND_LEGACY_MEMORY_LEND),
 			  SPCI_INVALID_PARAMETERS);
 
 	/* Lend memory to VM1. */
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1141,13 +1150,13 @@
 		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1162,13 +1171,13 @@
 	/* Re-initialise the memory before giving it. */
 	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RO_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RO_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1201,13 +1210,13 @@
 		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
-	msg_size = spci_memory_share_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1228,13 +1237,13 @@
 	/* Re-initialise the memory before giving it. */
 	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 
-	msg_size = spci_memory_share_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RO_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RO_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1273,13 +1282,13 @@
 		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
-	msg_size = spci_memory_share_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_NX, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_NX, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1299,13 +1308,13 @@
 	/* Re-initialise the memory before giving it. */
 	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 
-	msg_size = spci_memory_share_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RO_NX, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RO_NX, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1347,12 +1356,12 @@
 		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1360,12 +1369,12 @@
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
 
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_NX, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_NX, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1397,12 +1406,12 @@
 		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RO_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RO_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1410,12 +1419,12 @@
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
 
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RO_NX, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RO_NX, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1444,13 +1453,13 @@
 		{.address = (uint64_t)pages, .page_count = 2},
 	};
 
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RO_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RO_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1462,24 +1471,24 @@
 	constituents[0].page_count = 1;
 	for (int i = 1; i < PAGE_SIZE * 2; i++) {
 		constituents[0].address = (uint64_t)pages + PAGE_SIZE;
-		msg_size = spci_memory_donate_init(
+		msg_size = spci_memory_region_init(
 			mb.send, SERVICE_VM2, constituents,
-			ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RW_X,
+			ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 			SPCI_MEMORY_OUTER_SHAREABLE);
 		EXPECT_SPCI_ERROR(
 			spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				      SPCI_MSG_SEND_LEGACY_MEMORY),
+				      SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
 			SPCI_INVALID_PARAMETERS);
 	}
 
 	/* Ensure we can donate to the only borrower. */
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 }
@@ -1505,13 +1514,13 @@
 		{.address = (uint64_t)pages + PAGE_SIZE * 2, .page_count = 2},
 	};
 
-	msg_size = spci_memory_share_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RO_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RO_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1527,24 +1536,24 @@
 	constituents[0].page_count = 1;
 	for (int i = 1; i < PAGE_SIZE * 2; i++) {
 		constituents[0].address = (uint64_t)pages + PAGE_SIZE;
-		msg_size = spci_memory_donate_init(
+		msg_size = spci_memory_region_init(
 			mb.send, SERVICE_VM2, constituents,
-			ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RW_X,
+			ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 			SPCI_MEMORY_OUTER_SHAREABLE);
 		EXPECT_SPCI_ERROR(
 			spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				      SPCI_MSG_SEND_LEGACY_MEMORY),
+				      SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
 			SPCI_INVALID_PARAMETERS);
 	}
 
 	/* Ensure we can donate to the only borrower. */
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 }
@@ -1570,13 +1579,13 @@
 		{.address = (uint64_t)pages + PAGE_SIZE * 3, .page_count = 1},
 	};
 
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1613,14 +1622,14 @@
 	constituents[0].page_count = 1;
 	for (int i = 0; i < 2; i++) {
 		constituents[0].address = (uint64_t)pages + i * PAGE_SIZE;
-		msg_size = spci_memory_lend_init(
+		msg_size = spci_memory_region_init(
 			mb.send, SERVICE_VM1, constituents,
-			ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RO_X,
+			ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RO_X,
 			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 			SPCI_MEMORY_OUTER_SHAREABLE);
 		EXPECT_SPCI_ERROR(
 			spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				      SPCI_MSG_SEND_LEGACY_MEMORY),
+				      SPCI_MSG_SEND_LEGACY_MEMORY_LEND),
 			SPCI_INVALID_PARAMETERS);
 	}
 }
@@ -1645,13 +1654,13 @@
 		{.address = (uint64_t)pages, .page_count = 2},
 	};
 
-	msg_size = spci_memory_share_init(
+	msg_size = spci_memory_region_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
-		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1678,14 +1687,14 @@
 	constituents[0].page_count = 1;
 	for (int i = 0; i < 2; i++) {
 		constituents[0].address = (uint64_t)pages + i * PAGE_SIZE;
-		msg_size = spci_memory_share_init(
+		msg_size = spci_memory_region_init(
 			mb.send, SERVICE_VM1, constituents,
-			ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RO_X,
+			ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RO_X,
 			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 			SPCI_MEMORY_OUTER_SHAREABLE);
 		EXPECT_SPCI_ERROR(
 			spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				      SPCI_MSG_SEND_LEGACY_MEMORY),
+				      SPCI_MSG_SEND_LEGACY_MEMORY_SHARE),
 			SPCI_INVALID_PARAMETERS);
 	}
 }
@@ -1709,13 +1718,13 @@
 		{.address = (uint64_t)pages, .page_count = 2},
 	};
 
-	msg_size = spci_memory_init(
-		mb.send, SPCI_MEMORY_SHARE, SERVICE_VM1, constituents,
-		ARRAY_SIZE(constituents), 0, SPCI_MEMORY_REGION_FLAG_CLEAR,
-		SPCI_MEMORY_RO_X, SPCI_MEMORY_NORMAL_MEM,
-		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
+	msg_size = spci_memory_region_init(
+		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
+		SPCI_MEMORY_REGION_FLAG_CLEAR, SPCI_MEMORY_RO_X,
+		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
+		SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_SHARE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1753,12 +1762,12 @@
 	 */
 	pages[0] = 0;
 
-	msg_size = spci_memory_lend_init(
-		mb.send, SERVICE_VM1, constituents, 2, 0, SPCI_MEMORY_RW_X,
-		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
-		SPCI_MEMORY_OUTER_SHAREABLE);
+	msg_size = spci_memory_region_init(
+		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1777,12 +1786,12 @@
 	pages[PAGE_SIZE] = 1;
 
 	/* Use the secondary VM for this test as the first is now aborted. */
-	msg_size = spci_memory_lend_init(
-		mb.send, SERVICE_VM2, constituents, 2, 0, SPCI_MEMORY_RW_X,
-		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
-		SPCI_MEMORY_OUTER_SHAREABLE);
+	msg_size = spci_memory_region_init(
+		mb.send, SERVICE_VM2, constituents, ARRAY_SIZE(constituents), 0,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1819,12 +1828,12 @@
 	 */
 	pages[0] = 0;
 
-	msg_size = spci_memory_lend_init(
-		mb.send, SERVICE_VM1, constituents, 2, 0, SPCI_MEMORY_RW_X,
-		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
-		SPCI_MEMORY_OUTER_SHAREABLE);
+	msg_size = spci_memory_region_init(
+		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -1843,12 +1852,12 @@
 	pages[PAGE_SIZE] = 1;
 
 	/* Use the secondary VM for this test as the first is now aborted. */
-	msg_size = spci_memory_lend_init(
-		mb.send, SERVICE_VM2, constituents, 2, 0, SPCI_MEMORY_RW_X,
-		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
-		SPCI_MEMORY_OUTER_SHAREABLE);
+	msg_size = spci_memory_region_init(
+		mb.send, SERVICE_VM2, constituents, ARRAY_SIZE(constituents), 0,
+		0, SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
diff --git a/test/vmapi/primary_with_secondaries/services/abort.c b/test/vmapi/primary_with_secondaries/services/abort.c
index a4c445e..23649f2 100644
--- a/test/vmapi/primary_with_secondaries/services/abort.c
+++ b/test/vmapi/primary_with_secondaries/services/abort.c
@@ -37,13 +37,13 @@
 	struct spci_memory_region_constituent constituents[] = {
 		{.address = (uint64_t)(&pages[PAGE_SIZE]), .page_count = 1},
 	};
-	uint32_t msg_size = spci_memory_donate_init(
+	uint32_t msg_size = spci_memory_region_init(
 		send_buf, HF_PRIMARY_VM_ID, constituents,
-		ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RW_X,
+		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(hf_vm_get_id(), HF_PRIMARY_VM_ID, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -71,13 +71,13 @@
 	struct spci_memory_region_constituent constituents[] = {
 		{.address = (uint64_t)(&pages[PAGE_SIZE]), .page_count = 1},
 	};
-	uint32_t msg_size = spci_memory_donate_init(
+	uint32_t msg_size = spci_memory_region_init(
 		send_buf, HF_PRIMARY_VM_ID, constituents,
-		ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RW_X,
+		ARRAY_SIZE(constituents), 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(hf_vm_get_id(), HF_PRIMARY_VM_ID, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
diff --git a/test/vmapi/primary_with_secondaries/services/memory.c b/test/vmapi/primary_with_secondaries/services/memory.c
index 24d3cdd..0f65749 100644
--- a/test/vmapi/primary_with_secondaries/services/memory.c
+++ b/test/vmapi/primary_with_secondaries/services/memory.c
@@ -34,13 +34,13 @@
 		size_t i;
 		void *recv_buf = SERVICE_RECV_BUFFER();
 		struct spci_memory_region *memory_region =
-			spci_get_memory_region(recv_buf);
+			(struct spci_memory_region *)recv_buf;
 		struct spci_memory_region_constituent *constituents =
 			spci_memory_region_get_constituents(memory_region);
 
 		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 		EXPECT_EQ(spci_msg_send_attributes(ret),
-			  SPCI_MSG_SEND_LEGACY_MEMORY);
+			  SPCI_MSG_SEND_LEGACY_MEMORY_SHARE);
 
 		ptr = (uint8_t *)constituents[0].address;
 
@@ -72,13 +72,13 @@
 	struct spci_memory_region_constituent constituents[] = {
 		{.address = (uint64_t)&page, .page_count = 1},
 	};
-	uint32_t msg_size = spci_memory_init(
-		send_buf, SPCI_MEMORY_DONATE, HF_PRIMARY_VM_ID, constituents,
+	uint32_t msg_size = spci_memory_region_init(
+		send_buf, HF_PRIMARY_VM_ID, constituents,
 		ARRAY_SIZE(constituents), 0, SPCI_MEMORY_REGION_FLAG_CLEAR,
 		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(hf_vm_get_id(), HF_PRIMARY_VM_ID, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -94,13 +94,13 @@
 	struct spci_memory_region_constituent constituents[] = {
 		{.address = (uint64_t)&page, .page_count = 1},
 	};
-	uint32_t msg_size = spci_memory_init(
-		send_buf, SPCI_MEMORY_LEND, HF_PRIMARY_VM_ID, constituents,
+	uint32_t msg_size = spci_memory_region_init(
+		send_buf, HF_PRIMARY_VM_ID, constituents,
 		ARRAY_SIZE(constituents), 0, SPCI_MEMORY_REGION_FLAG_CLEAR,
 		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(hf_vm_get_id(), HF_PRIMARY_VM_ID, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_LEND)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -122,10 +122,19 @@
 		struct spci_memory_region_constituent *constituents;
 
 		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
-		EXPECT_EQ(spci_msg_send_attributes(ret),
-			  SPCI_MSG_SEND_LEGACY_MEMORY);
+		/*
+		 * The memory may have been sent in one of several different
+		 * ways, but there shouldn't be any other attributes to the
+		 * message.
+		 */
+		EXPECT_NE(spci_msg_send_attributes(ret) &
+				  SPCI_MSG_SEND_LEGACY_MEMORY_MASK,
+			  0);
+		EXPECT_EQ(spci_msg_send_attributes(ret) &
+				  ~SPCI_MSG_SEND_LEGACY_MEMORY_MASK,
+			  0);
 
-		memory_region = spci_get_memory_region(recv_buf);
+		memory_region = (struct spci_memory_region *)recv_buf;
 		constituents =
 			spci_memory_region_get_constituents(memory_region);
 		ptr = (uint8_t *)constituents[0].address;
@@ -136,15 +145,16 @@
 		}
 
 		/* Give the memory back and notify the sender. */
-		msg_size = spci_memory_donate_init(
+		msg_size = spci_memory_region_init(
 			send_buf, HF_PRIMARY_VM_ID, constituents,
-			memory_region->constituent_count, 0, SPCI_MEMORY_RW_X,
-			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
+			memory_region->constituent_count, 0, 0,
+			SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+			SPCI_MEMORY_CACHE_WRITE_BACK,
 			SPCI_MEMORY_OUTER_SHAREABLE);
 		spci_rx_release();
 		EXPECT_EQ(spci_msg_send(spci_msg_send_receiver(ret),
 					spci_msg_send_sender(ret), msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY)
+					SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 				  .func,
 			  SPCI_SUCCESS_32);
 
@@ -166,8 +176,9 @@
 	struct spci_memory_region_constituent *constituents;
 
 	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
-	EXPECT_EQ(spci_msg_send_attributes(ret), SPCI_MSG_SEND_LEGACY_MEMORY);
-	memory_region = spci_get_memory_region(recv_buf);
+	EXPECT_EQ(spci_msg_send_attributes(ret),
+		  SPCI_MSG_SEND_LEGACY_MEMORY_DONATE);
+	memory_region = (struct spci_memory_region *)recv_buf;
 	constituents = spci_memory_region_get_constituents(memory_region);
 
 	/* Choose which constituent we want to test. */
@@ -187,12 +198,13 @@
 	uint8_t index;
 	void *recv_buf = SERVICE_RECV_BUFFER();
 	struct spci_memory_region *memory_region =
-		spci_get_memory_region(recv_buf);
+		(struct spci_memory_region *)recv_buf;
 	struct spci_memory_region_constituent *constituents =
 		spci_memory_region_get_constituents(memory_region);
 
 	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
-	EXPECT_EQ(spci_msg_send_attributes(ret), SPCI_MSG_SEND_LEGACY_MEMORY);
+	EXPECT_EQ(spci_msg_send_attributes(ret),
+		  SPCI_MSG_SEND_LEGACY_MEMORY_DONATE);
 
 	/* Choose which constituent we want to test. */
 	index = *(uint8_t *)constituents[0].address;
@@ -214,24 +226,25 @@
 	void *recv_buf = SERVICE_RECV_BUFFER();
 	void *send_buf = SERVICE_SEND_BUFFER();
 	struct spci_memory_region *memory_region =
-		spci_get_memory_region(recv_buf);
+		(struct spci_memory_region *)recv_buf;
 	struct spci_memory_region_constituent *constituents =
 		spci_memory_region_get_constituents(memory_region);
 
 	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
-	EXPECT_EQ(spci_msg_send_attributes(ret), SPCI_MSG_SEND_LEGACY_MEMORY);
+	EXPECT_EQ(spci_msg_send_attributes(ret),
+		  SPCI_MSG_SEND_LEGACY_MEMORY_DONATE);
 
 	ptr = (uint8_t *)constituents[0].address;
 
 	/* Donate memory to next VM. */
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		send_buf, SERVICE_VM2, constituents,
-		memory_region->constituent_count, 0, SPCI_MEMORY_RW_X,
+		memory_region->constituent_count, 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 	spci_rx_release();
 	EXPECT_EQ(spci_msg_send(spci_msg_send_receiver(ret), SERVICE_VM2,
-				msg_size, SPCI_MSG_SEND_LEGACY_MEMORY)
+				msg_size, SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
@@ -251,35 +264,36 @@
 	void *recv_buf = SERVICE_RECV_BUFFER();
 	void *send_buf = SERVICE_SEND_BUFFER();
 	struct spci_memory_region *memory_region =
-		spci_get_memory_region(recv_buf);
+		(struct spci_memory_region *)recv_buf;
 	struct spci_memory_region_constituent constituent =
 		spci_memory_region_get_constituents(memory_region)[0];
 
 	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
-	EXPECT_EQ(spci_msg_send_attributes(ret), SPCI_MSG_SEND_LEGACY_MEMORY);
+	EXPECT_EQ(spci_msg_send_attributes(ret),
+		  SPCI_MSG_SEND_LEGACY_MEMORY_DONATE);
 	spci_rx_release();
 
 	/* Yield to allow attempt to re donate from primary. */
 	spci_yield();
 
 	/* Give the memory back and notify the sender. */
-	msg_size = spci_memory_donate_init(
-		send_buf, HF_PRIMARY_VM_ID, &constituent, 1, 0,
+	msg_size = spci_memory_region_init(
+		send_buf, HF_PRIMARY_VM_ID, &constituent, 1, 0, 0,
 		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(SERVICE_VM1, HF_PRIMARY_VM_ID, msg_size,
-				SPCI_MSG_SEND_LEGACY_MEMORY)
+				SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
 	/* Attempt to donate the memory to another VM. */
-	msg_size = spci_memory_donate_init(
-		send_buf, SERVICE_VM2, &constituent, 1, 0, SPCI_MEMORY_RW_X,
+	msg_size = spci_memory_region_init(
+		send_buf, SERVICE_VM2, &constituent, 1, 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_SPCI_ERROR(
 		spci_msg_send(spci_msg_send_receiver(ret), SERVICE_VM2,
-			      msg_size, SPCI_MSG_SEND_LEGACY_MEMORY),
+			      msg_size, SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
 		SPCI_INVALID_PARAMETERS);
 
 	spci_yield();
@@ -296,13 +310,13 @@
 		uint8_t *ptr;
 		void *recv_buf = SERVICE_RECV_BUFFER();
 		struct spci_memory_region *memory_region =
-			spci_get_memory_region(recv_buf);
+			(struct spci_memory_region *)recv_buf;
 		struct spci_memory_region_constituent *constituents =
 			spci_memory_region_get_constituents(memory_region);
 
 		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 		EXPECT_EQ(spci_msg_send_attributes(ret),
-			  SPCI_MSG_SEND_LEGACY_MEMORY);
+			  SPCI_MSG_SEND_LEGACY_MEMORY_DONATE);
 
 		ptr = (uint8_t *)constituents[0].address;
 		spci_rx_release();
@@ -325,33 +339,34 @@
 	void *recv_buf = SERVICE_RECV_BUFFER();
 	void *send_buf = SERVICE_SEND_BUFFER();
 	struct spci_memory_region *memory_region =
-		spci_get_memory_region(recv_buf);
+		(struct spci_memory_region *)recv_buf;
 	struct spci_memory_region_constituent *constituents =
 		spci_memory_region_get_constituents(memory_region);
 
 	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
-	EXPECT_EQ(spci_msg_send_attributes(ret), SPCI_MSG_SEND_LEGACY_MEMORY);
+	EXPECT_EQ(spci_msg_send_attributes(ret),
+		  SPCI_MSG_SEND_LEGACY_MEMORY_DONATE);
 
 	/* Give the memory back and notify the sender. */
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		send_buf, HF_PRIMARY_VM_ID, constituents,
-		memory_region->constituent_count, 0, SPCI_MEMORY_RW_X,
+		memory_region->constituent_count, 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_EQ(spci_msg_send(spci_msg_send_receiver(ret), HF_PRIMARY_VM_ID,
-				msg_size, SPCI_MSG_SEND_LEGACY_MEMORY)
+				msg_size, SPCI_MSG_SEND_LEGACY_MEMORY_DONATE)
 			  .func,
 		  SPCI_SUCCESS_32);
 
 	/* Fail to donate the memory from the primary to VM2. */
-	msg_size = spci_memory_donate_init(
+	msg_size = spci_memory_region_init(
 		send_buf, SERVICE_VM2, constituents,
-		memory_region->constituent_count, 0, SPCI_MEMORY_RW_X,
+		memory_region->constituent_count, 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 	spci_rx_release();
 	EXPECT_SPCI_ERROR(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY),
+					SPCI_MSG_SEND_LEGACY_MEMORY_DONATE),
 			  SPCI_INVALID_PARAMETERS);
 	spci_yield();
 }
@@ -371,13 +386,23 @@
 		void *recv_buf = SERVICE_RECV_BUFFER();
 		void *send_buf = SERVICE_SEND_BUFFER();
 		struct spci_memory_region *memory_region =
-			spci_get_memory_region(recv_buf);
+			(struct spci_memory_region *)recv_buf;
 		struct spci_memory_region_constituent *constituents =
 			spci_memory_region_get_constituents(memory_region);
 
 		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
-		EXPECT_EQ(spci_msg_send_attributes(ret),
-			  SPCI_MSG_SEND_LEGACY_MEMORY);
+		/*
+		 * The memory may have been sent in one of several different
+		 * ways, but there shouldn't be any other attributes to the
+		 * message.
+		 */
+		EXPECT_NE(spci_msg_send_attributes(ret) &
+				  SPCI_MSG_SEND_LEGACY_MEMORY_MASK,
+			  0);
+		EXPECT_EQ(spci_msg_send_attributes(ret) &
+				  ~SPCI_MSG_SEND_LEGACY_MEMORY_MASK,
+			  0);
+
 		ptr = (uint8_t *)constituents[0].address;
 		count = constituents[0].page_count;
 		ptr2 = (uint8_t *)constituents[1].address;
@@ -392,14 +417,17 @@
 		}
 
 		/* Give the memory back and notify the sender. */
-		msg_size = spci_memory_relinquish_init(
+		msg_size = spci_memory_region_init(
 			send_buf, HF_PRIMARY_VM_ID, constituents,
-			memory_region->constituent_count, 0);
+			memory_region->constituent_count, 0, 0,
+			SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+			SPCI_MEMORY_CACHE_WRITE_BACK,
+			SPCI_MEMORY_OUTER_SHAREABLE);
 		/* Relevant information read, mailbox can be cleared. */
 		spci_rx_release();
 		EXPECT_EQ(spci_msg_send(spci_msg_send_receiver(ret),
 					spci_msg_send_sender(ret), msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY)
+					SPCI_MSG_SEND_LEGACY_MEMORY_RELINQUISH)
 				  .func,
 			  SPCI_SUCCESS_32);
 
@@ -425,13 +453,13 @@
 		void *recv_buf = SERVICE_RECV_BUFFER();
 		void *send_buf = SERVICE_SEND_BUFFER();
 		struct spci_memory_region *memory_region =
-			spci_get_memory_region(recv_buf);
+			(struct spci_memory_region *)recv_buf;
 		struct spci_memory_region_constituent *constituents =
 			spci_memory_region_get_constituents(memory_region);
 
 		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 		EXPECT_EQ(spci_msg_send_attributes(ret),
-			  SPCI_MSG_SEND_LEGACY_MEMORY);
+			  SPCI_MSG_SEND_LEGACY_MEMORY_DONATE);
 
 		ptr = (uint8_t *)constituents[0].address;
 
@@ -440,14 +468,18 @@
 			ptr[i]++;
 		}
 		/* Give the memory back and notify the sender. */
-		msg_size = spci_memory_relinquish_init(
+		msg_size = spci_memory_region_init(
 			send_buf, HF_PRIMARY_VM_ID, constituents,
-			memory_region->constituent_count, 0);
+			memory_region->constituent_count, 0, 0,
+			SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+			SPCI_MEMORY_CACHE_WRITE_BACK,
+			SPCI_MEMORY_OUTER_SHAREABLE);
 		spci_rx_release();
-		EXPECT_SPCI_ERROR(spci_msg_send(spci_msg_send_receiver(ret),
-						HF_PRIMARY_VM_ID, msg_size,
-						SPCI_MSG_SEND_LEGACY_MEMORY),
-				  SPCI_INVALID_PARAMETERS);
+		EXPECT_SPCI_ERROR(
+			spci_msg_send(spci_msg_send_receiver(ret),
+				      HF_PRIMARY_VM_ID, msg_size,
+				      SPCI_MSG_SEND_LEGACY_MEMORY_RELINQUISH),
+			SPCI_INVALID_PARAMETERS);
 
 		/* Ensure we still have access to the memory. */
 		ptr[0] = 123;
@@ -467,50 +499,56 @@
 	void *recv_buf = SERVICE_RECV_BUFFER();
 	void *send_buf = SERVICE_SEND_BUFFER();
 	struct spci_memory_region *memory_region =
-		spci_get_memory_region(recv_buf);
+		(struct spci_memory_region *)recv_buf;
 	struct spci_memory_region_constituent *constituents =
 		spci_memory_region_get_constituents(memory_region);
 
 	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
-	EXPECT_EQ(spci_msg_send_attributes(ret), SPCI_MSG_SEND_LEGACY_MEMORY);
+	EXPECT_EQ(spci_msg_send_attributes(ret),
+		  SPCI_MSG_SEND_LEGACY_MEMORY_LEND);
 
 	/* Attempt to relinquish from primary VM. */
-	msg_size = spci_memory_relinquish_init(
+	msg_size = spci_memory_region_init(
 		send_buf, spci_msg_send_receiver(ret), constituents,
-		memory_region->constituent_count, 0);
+		memory_region->constituent_count, 0, 0, SPCI_MEMORY_RW_X,
+		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
+		SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_SPCI_ERROR(
 		spci_msg_send(HF_PRIMARY_VM_ID, spci_msg_send_receiver(ret),
-			      msg_size, SPCI_MSG_SEND_LEGACY_MEMORY),
+			      msg_size, SPCI_MSG_SEND_LEGACY_MEMORY_RELINQUISH),
 		SPCI_INVALID_PARAMETERS);
 
 	/* Give the memory back and notify the sender. */
-	msg_size = spci_memory_relinquish_init(
+	msg_size = spci_memory_region_init(
 		send_buf, HF_PRIMARY_VM_ID, constituents,
-		memory_region->constituent_count, 0);
-	EXPECT_EQ(spci_msg_send(spci_msg_send_receiver(ret), HF_PRIMARY_VM_ID,
-				msg_size, SPCI_MSG_SEND_LEGACY_MEMORY)
-			  .func,
-		  SPCI_SUCCESS_32);
+		memory_region->constituent_count, 0, 0, SPCI_MEMORY_RW_X,
+		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
+		SPCI_MEMORY_OUTER_SHAREABLE);
+	EXPECT_EQ(
+		spci_msg_send(spci_msg_send_receiver(ret), HF_PRIMARY_VM_ID,
+			      msg_size, SPCI_MSG_SEND_LEGACY_MEMORY_RELINQUISH)
+			.func,
+		SPCI_SUCCESS_32);
 
 	/* Ensure we cannot lend from the primary to another secondary. */
-	msg_size = spci_memory_lend_init(
+	msg_size = spci_memory_region_init(
 		send_buf, SERVICE_VM2, constituents,
-		memory_region->constituent_count, 0, SPCI_MEMORY_RW_X,
+		memory_region->constituent_count, 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 	EXPECT_SPCI_ERROR(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY),
+					SPCI_MSG_SEND_LEGACY_MEMORY_LEND),
 			  SPCI_INVALID_PARAMETERS);
 
 	/* Ensure we cannot share from the primary to another secondary. */
-	msg_size = spci_memory_share_init(
+	msg_size = spci_memory_region_init(
 		send_buf, SERVICE_VM2, constituents,
-		memory_region->constituent_count, 0, SPCI_MEMORY_RW_X,
+		memory_region->constituent_count, 0, 0, SPCI_MEMORY_RW_X,
 		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
 		SPCI_MEMORY_OUTER_SHAREABLE);
 	spci_rx_release();
 	EXPECT_SPCI_ERROR(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY),
+					SPCI_MSG_SEND_LEGACY_MEMORY_SHARE),
 			  SPCI_INVALID_PARAMETERS);
 
 	spci_yield();
@@ -529,13 +567,13 @@
 		void *recv_buf = SERVICE_RECV_BUFFER();
 		void *send_buf = SERVICE_SEND_BUFFER();
 		struct spci_memory_region *memory_region =
-			spci_get_memory_region(recv_buf);
+			(struct spci_memory_region *)recv_buf;
 		struct spci_memory_region_constituent *constituents =
 			spci_memory_region_get_constituents(memory_region);
 
 		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 		EXPECT_EQ(spci_msg_send_attributes(ret),
-			  SPCI_MSG_SEND_LEGACY_MEMORY);
+			  SPCI_MSG_SEND_LEGACY_MEMORY_LEND);
 
 		ptr = (uint64_t *)constituents[0].address;
 		/*
@@ -547,13 +585,16 @@
 		__asm__ volatile("blr %0" ::"r"(ptr));
 
 		/* Release the memory again. */
-		msg_size = spci_memory_relinquish_init(
+		msg_size = spci_memory_region_init(
 			send_buf, HF_PRIMARY_VM_ID, constituents,
-			memory_region->constituent_count, 0);
+			memory_region->constituent_count, 0, 0,
+			SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+			SPCI_MEMORY_CACHE_WRITE_BACK,
+			SPCI_MEMORY_OUTER_SHAREABLE);
 		spci_rx_release();
 		EXPECT_EQ(spci_msg_send(spci_msg_send_receiver(ret),
 					HF_PRIMARY_VM_ID, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY)
+					SPCI_MSG_SEND_LEGACY_MEMORY_RELINQUISH)
 				  .func,
 			  SPCI_SUCCESS_32);
 	}
@@ -573,15 +614,25 @@
 		void *recv_buf = SERVICE_RECV_BUFFER();
 		void *send_buf = SERVICE_SEND_BUFFER();
 		struct spci_memory_region *memory_region =
-			spci_get_memory_region(recv_buf);
+			(struct spci_memory_region *)recv_buf;
 		struct spci_memory_region_constituent *constituents =
 			spci_memory_region_get_constituents(memory_region);
 		struct spci_memory_region_constituent constituent_copy =
 			constituents[0];
 
 		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
-		EXPECT_EQ(spci_msg_send_attributes(ret),
-			  SPCI_MSG_SEND_LEGACY_MEMORY);
+		/*
+		 * The memory may have been sent in one of several different
+		 * ways, but there shouldn't be any other attributes to the
+		 * message.
+		 */
+		EXPECT_NE(spci_msg_send_attributes(ret) &
+				  SPCI_MSG_SEND_LEGACY_MEMORY_MASK,
+			  0);
+		EXPECT_EQ(spci_msg_send_attributes(ret) &
+				  ~SPCI_MSG_SEND_LEGACY_MEMORY_MASK,
+			  0);
+
 		spci_rx_release();
 
 		ptr = (uint8_t *)constituent_copy.address;
@@ -599,11 +650,14 @@
 			ptr[i]++;
 		}
 
-		msg_size = spci_memory_relinquish_init(
-			send_buf, HF_PRIMARY_VM_ID, &constituent_copy, 1, 0);
+		msg_size = spci_memory_region_init(
+			send_buf, HF_PRIMARY_VM_ID, &constituent_copy, 1, 0, 0,
+			SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
+			SPCI_MEMORY_CACHE_WRITE_BACK,
+			SPCI_MEMORY_OUTER_SHAREABLE);
 		EXPECT_EQ(spci_msg_send(spci_msg_send_receiver(ret),
 					HF_PRIMARY_VM_ID, msg_size,
-					SPCI_MSG_SEND_LEGACY_MEMORY)
+					SPCI_MSG_SEND_LEGACY_MEMORY_RELINQUISH)
 				  .func,
 			  SPCI_SUCCESS_32);
 	}
@@ -620,12 +674,13 @@
 
 	void *recv_buf = SERVICE_RECV_BUFFER();
 	struct spci_memory_region *memory_region =
-		spci_get_memory_region(recv_buf);
+		(struct spci_memory_region *)recv_buf;
 	struct spci_memory_region_constituent *constituents =
 		spci_memory_region_get_constituents(memory_region);
 
 	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
-	EXPECT_EQ(spci_msg_send_attributes(ret), SPCI_MSG_SEND_LEGACY_MEMORY);
+	EXPECT_EQ(spci_msg_send_attributes(ret),
+		  SPCI_MSG_SEND_LEGACY_MEMORY_LEND);
 
 	/* Choose which constituent we want to test. */
 	index = *(uint8_t *)constituents[0].address;
@@ -647,12 +702,13 @@
 
 	void *recv_buf = SERVICE_RECV_BUFFER();
 	struct spci_memory_region *memory_region =
-		spci_get_memory_region(recv_buf);
+		(struct spci_memory_region *)recv_buf;
 	struct spci_memory_region_constituent *constituents =
 		spci_memory_region_get_constituents(memory_region);
 
 	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
-	EXPECT_EQ(spci_msg_send_attributes(ret), SPCI_MSG_SEND_LEGACY_MEMORY);
+	EXPECT_EQ(spci_msg_send_attributes(ret),
+		  SPCI_MSG_SEND_LEGACY_MEMORY_LEND);
 
 	/* Choose which constituent we want to test. */
 	index = *(uint8_t *)constituents[0].address;
@@ -674,14 +730,24 @@
 	void *recv_buf = SERVICE_RECV_BUFFER();
 	void *send_buf = SERVICE_SEND_BUFFER();
 	struct spci_memory_region *memory_region =
-		spci_get_memory_region(recv_buf);
+		(struct spci_memory_region *)recv_buf;
 	struct spci_memory_region_constituent *constituents =
 		spci_memory_region_get_constituents(memory_region);
 	struct spci_memory_region_constituent constituent_copy =
 		constituents[0];
 
 	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
-	EXPECT_EQ(spci_msg_send_attributes(ret), SPCI_MSG_SEND_LEGACY_MEMORY);
+	/*
+	 * The memory may have been sent in one of several different ways, but
+	 * there shouldn't be any other attributes to the message.
+	 */
+	EXPECT_NE(spci_msg_send_attributes(ret) &
+			  SPCI_MSG_SEND_LEGACY_MEMORY_MASK,
+		  0);
+	EXPECT_EQ(spci_msg_send_attributes(ret) &
+			  ~SPCI_MSG_SEND_LEGACY_MEMORY_MASK,
+		  0);
+
 	spci_rx_release();
 
 	ptr = (uint8_t *)constituent_copy.address;
@@ -700,23 +766,23 @@
 		constituent_copy.address = (uint64_t)ptr + i;
 
 		/* Fail to lend or share the memory back to the primary. */
-		msg_size = spci_memory_lend_init(
-			send_buf, SERVICE_VM2, &constituent_copy, 1, 0,
+		msg_size = spci_memory_region_init(
+			send_buf, SERVICE_VM2, &constituent_copy, 1, 0, 0,
 			SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 			SPCI_MEMORY_CACHE_WRITE_BACK,
 			SPCI_MEMORY_OUTER_SHAREABLE);
 		EXPECT_SPCI_ERROR(
 			spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				      SPCI_MSG_SEND_LEGACY_MEMORY),
+				      SPCI_MSG_SEND_LEGACY_MEMORY_LEND),
 			SPCI_INVALID_PARAMETERS);
-		msg_size = spci_memory_share_init(
-			send_buf, SERVICE_VM2, &constituent_copy, 1, 0,
+		msg_size = spci_memory_region_init(
+			send_buf, SERVICE_VM2, &constituent_copy, 1, 0, 0,
 			SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
 			SPCI_MEMORY_CACHE_WRITE_BACK,
 			SPCI_MEMORY_OUTER_SHAREABLE);
 		EXPECT_SPCI_ERROR(
 			spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
-				      SPCI_MSG_SEND_LEGACY_MEMORY),
+				      SPCI_MSG_SEND_LEGACY_MEMORY_SHARE),
 			SPCI_INVALID_PARAMETERS);
 	}
 
diff --git a/vmlib/spci.c b/vmlib/spci.c
index 19da8d7..4da01fe 100644
--- a/vmlib/spci.c
+++ b/vmlib/spci.c
@@ -27,20 +27,6 @@
 #endif
 
 /**
- * Helper method to fill in the information about the architected message.
- */
-void spci_architected_message_init(void *message, enum spci_memory_share type)
-{
-	/* Fill the architected header. */
-	struct spci_architected_message_header *architected_header =
-		(struct spci_architected_message_header *)message;
-	architected_header->type = type;
-	architected_header->reserved[0] = 0;
-	architected_header->reserved[1] = 0;
-	architected_header->reserved[2] = 0;
-}
-
-/**
  * Initialises the given `spci_memory_region` and copies the constituent
  * information to it. Returns the length in bytes occupied by the data copied to
  * `memory_region` (attributes, constituents and memory region header size).
@@ -99,30 +85,3 @@
 
 	return memory_region->constituent_offset + constituents_length;
 }
-
-/**
- * Constructs an 'architected message' for SPCI memory sharing of the given
- * type.
- */
-uint32_t spci_memory_init(
-	void *message, enum spci_memory_share share_type, spci_vm_id_t receiver,
-	struct spci_memory_region_constituent *region_constituents,
-	uint32_t constituent_count, uint32_t tag, spci_memory_region_flags_t flags,
-	enum spci_memory_access access, enum spci_memory_type type,
-	enum spci_memory_cacheability cacheability,
-	enum spci_memory_shareability shareability)
-{
-	uint32_t message_length =
-		sizeof(struct spci_architected_message_header);
-	struct spci_memory_region *memory_region =
-		spci_get_memory_region(message);
-
-	/* Fill in the details on the common message header. */
-	spci_architected_message_init(message, share_type);
-
-	/* Fill in memory region. */
-	message_length += spci_memory_region_init(
-		memory_region, receiver, region_constituents, constituent_count,
-		tag, flags, access, type, cacheability, shareability);
-	return message_length;
-}