refactor(ff-a): direct messaging

Some functions from `src/ffa/{hypervisor,spmc}.c` were missed in the
refactoring.
Move them to `src/ffa/{hypervisor,spmc}/direct_messaging.c`.

Change-Id: Ic0a238fe676c8aa77110f539ccf9cdb9638b85e9
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/inc/hf/ffa.h b/inc/hf/ffa.h
index 1a33d6c..936e2eb 100644
--- a/inc/hf/ffa.h
+++ b/inc/hf/ffa.h
@@ -15,9 +15,4 @@
 void plat_ffa_set_tee_enabled(bool tee_enabled);
 void plat_ffa_init(struct mpool *ppool);
 
-bool plat_ffa_is_spmd_lp_id(ffa_id_t vm_id);
-
 void plat_save_ns_simd_context(struct vcpu *vcpu);
-
-bool plat_ffa_handle_framework_msg(struct ffa_value args,
-				   struct ffa_value *ret);
diff --git a/inc/hf/ffa/direct_messaging.h b/inc/hf/ffa/direct_messaging.h
index eb87da8..968a2e9 100644
--- a/inc/hf/ffa/direct_messaging.h
+++ b/inc/hf/ffa/direct_messaging.h
@@ -35,3 +35,8 @@
 
 void ffa_direct_msg_unwind_call_chain_ffa_direct_resp(
 	struct vcpu_locked current_locked, struct vcpu_locked next_locked);
+
+bool plat_ffa_handle_framework_msg(struct ffa_value args,
+				   struct ffa_value *ret);
+
+bool plat_ffa_is_spmd_lp_id(ffa_id_t vm_id);
diff --git a/src/ffa/hypervisor.c b/src/ffa/hypervisor.c
index 1b87bca..07adb9b 100644
--- a/src/ffa/hypervisor.c
+++ b/src/ffa/hypervisor.c
@@ -116,17 +116,3 @@
 
 	dlog_verbose("TEE finished setting up buffers.\n");
 }
-
-bool plat_ffa_is_spmd_lp_id(ffa_id_t vm_id)
-{
-	(void)vm_id;
-	return false;
-}
-
-bool plat_ffa_handle_framework_msg(struct ffa_value args, struct ffa_value *ret)
-{
-	(void)args;
-	(void)ret;
-
-	return false;
-}
diff --git a/src/ffa/hypervisor/direct_messaging.c b/src/ffa/hypervisor/direct_messaging.c
index c5b5292..cfa663f 100644
--- a/src/ffa/hypervisor/direct_messaging.c
+++ b/src/ffa/hypervisor/direct_messaging.c
@@ -119,3 +119,17 @@
 	(void)current_locked;
 	(void)next_locked;
 }
+
+bool plat_ffa_handle_framework_msg(struct ffa_value args, struct ffa_value *ret)
+{
+	(void)args;
+	(void)ret;
+
+	return false;
+}
+
+bool plat_ffa_is_spmd_lp_id(ffa_id_t vm_id)
+{
+	(void)vm_id;
+	return false;
+}
diff --git a/src/ffa/spmc.c b/src/ffa/spmc.c
index 6d28b77..ff69e29 100644
--- a/src/ffa/spmc.c
+++ b/src/ffa/spmc.c
@@ -7,17 +7,14 @@
  */
 
 #include "hf/arch/ffa.h"
-#include "hf/arch/gicv3.h"
 #include "hf/arch/sve.h"
 
 #include "hf/api.h"
 #include "hf/bits.h"
-#include "hf/check.h"
 #include "hf/dlog.h"
 #include "hf/ffa.h"
 #include "hf/ffa/vm.h"
 #include "hf/ffa_internal.h"
-#include "hf/plat/interrupts.h"
 #include "hf/vcpu.h"
 #include "hf/vm.h"
 
@@ -40,212 +37,3 @@
 	arch_ffa_init();
 	ffa_vm_init(ppool);
 }
-
-bool plat_ffa_is_spmd_lp_id(ffa_id_t vm_id)
-{
-	return (vm_id >= EL3_SPMD_LP_ID_START && vm_id <= EL3_SPMD_LP_ID_END);
-}
-
-/**
- * Enforce action of an SP in response to non-secure or other-secure interrupt
- * by changing the priority mask. Effectively, physical interrupts shall not
- * trigger which has the same effect as queueing interrupts.
- */
-static void plat_ffa_vcpu_queue_interrupts(
-	struct vcpu_locked receiver_vcpu_locked)
-{
-	struct vcpu *receiver_vcpu = receiver_vcpu_locked.vcpu;
-	uint8_t current_priority;
-
-	/* Save current value of priority mask. */
-	current_priority = plat_interrupts_get_priority_mask();
-	receiver_vcpu->prev_interrupt_priority = current_priority;
-
-	if (receiver_vcpu->vm->other_s_interrupts_action ==
-		    OTHER_S_INT_ACTION_QUEUED ||
-	    receiver_vcpu->scheduling_mode == SPMC_MODE) {
-		/*
-		 * If secure interrupts not masked yet, mask them now. We could
-		 * enter SPMC scheduled mode when an EL3 SPMD Logical partition
-		 * sends a direct request, and we are making the IMPDEF choice
-		 * to mask interrupts when such a situation occurs. This keeps
-		 * design simple.
-		 */
-		if (current_priority > SWD_MASK_ALL_INT) {
-			plat_interrupts_set_priority_mask(SWD_MASK_ALL_INT);
-		}
-	} else if (receiver_vcpu->vm->ns_interrupts_action ==
-		   NS_ACTION_QUEUED) {
-		/* If non secure interrupts not masked yet, mask them now. */
-		if (current_priority > SWD_MASK_NS_INT) {
-			plat_interrupts_set_priority_mask(SWD_MASK_NS_INT);
-		}
-	}
-}
-
-/**
- * If the interrupts were indeed masked by SPMC before an SP's vCPU was resumed,
- * restore the priority mask thereby allowing the interrupts to be delivered.
- */
-void plat_ffa_vcpu_allow_interrupts(struct vcpu *current)
-{
-	plat_interrupts_set_priority_mask(current->prev_interrupt_priority);
-}
-
-/*
- * Start winding the call chain or continue to wind the present one upon the
- * invocation of FFA_MSG_SEND_DIRECT_REQ or FFA_MSG_SEND_DIRECT_REQ2 (FF-A v1.2)
- * ABI.
- */
-void ffa_direct_msg_wind_call_chain_ffa_direct_req(
-	struct vcpu_locked current_locked,
-	struct vcpu_locked receiver_vcpu_locked, ffa_id_t sender_vm_id)
-{
-	struct vcpu *current = current_locked.vcpu;
-	struct vcpu *receiver_vcpu = receiver_vcpu_locked.vcpu;
-
-	CHECK(receiver_vcpu->scheduling_mode == NONE);
-	CHECK(receiver_vcpu->call_chain.prev_node == NULL);
-	CHECK(receiver_vcpu->call_chain.next_node == NULL);
-	CHECK(receiver_vcpu->rt_model == RTM_NONE);
-
-	receiver_vcpu->rt_model = RTM_FFA_DIR_REQ;
-
-	if (!vm_id_is_current_world(sender_vm_id)) {
-		/* Start of NWd scheduled call chain. */
-		receiver_vcpu->scheduling_mode = NWD_MODE;
-	} else if (plat_ffa_is_spmd_lp_id(sender_vm_id)) {
-		receiver_vcpu->scheduling_mode = SPMC_MODE;
-	} else {
-		/* Adding a new node to an existing call chain. */
-		vcpu_call_chain_extend(current_locked, receiver_vcpu_locked);
-		receiver_vcpu->scheduling_mode = current->scheduling_mode;
-	}
-	plat_ffa_vcpu_queue_interrupts(receiver_vcpu_locked);
-}
-
-/*
- * Unwind the present call chain upon the invocation of
- * FFA_MSG_SEND_DIRECT_RESP ABI. The function also returns
- * the partition ID to which the caller must return to. In
- * case the call chain was started by an SPMD logical
- * partition direct message, at the end of the call chain,
- * we need to return other world's id so that the SPMC can
- * return to the SPMD.
- */
-void ffa_direct_msg_unwind_call_chain_ffa_direct_resp(
-	struct vcpu_locked current_locked, struct vcpu_locked next_locked)
-{
-	struct vcpu *next = next_locked.vcpu;
-	ffa_id_t receiver_vm_id = next->vm->id;
-	struct vcpu *current = current_locked.vcpu;
-
-	assert(current->call_chain.next_node == NULL);
-	current->scheduling_mode = NONE;
-	current->rt_model = RTM_NONE;
-
-	/* Allow interrupts if they were masked earlier. */
-	plat_ffa_vcpu_allow_interrupts(current);
-
-	if (!vm_id_is_current_world(receiver_vm_id)) {
-		/* End of NWd scheduled call chain. */
-		assert(current->call_chain.prev_node == NULL);
-	} else {
-		/* Removing a node from an existing call chain. */
-		vcpu_call_chain_remove_node(current_locked, next_locked);
-	}
-}
-
-/**
- * Check that the arguments to a VM availability message are correct.
- * Returns `FFA_SUCCESS_32` if the arguments are correct.
- * Returns `FFA_INVALID_PARAMETERS` if:
- * - the receiver is not a valid VM
- * - the receiver has not subscribed to the message type
- */
-static struct ffa_value check_vm_availability_message(struct ffa_value args)
-{
-	struct ffa_value ret = ffa_error(FFA_INVALID_PARAMETERS);
-	enum ffa_framework_msg_func func = ffa_framework_msg_func(args);
-	ffa_id_t receiver_id = ffa_receiver(args);
-	struct vm_locked receiver = vm_find_locked(receiver_id);
-
-	if (receiver.vm == NULL) {
-		dlog_verbose(
-			"VM availability messaging: could not find SP %#x\n",
-			receiver_id);
-		return ret;
-	}
-
-	/* only valid if receiver has subscribed */
-	if (func == FFA_FRAMEWORK_MSG_VM_CREATION_REQ &&
-	    !receiver.vm->vm_availability_messages.vm_created) {
-		dlog_verbose(
-			"VM availability messaging: SP %#x is not subscribed "
-			"to VM creation messages\n",
-			receiver_id);
-		goto out;
-	}
-
-	if (func == FFA_FRAMEWORK_MSG_VM_DESTRUCTION_REQ &&
-	    !receiver.vm->vm_availability_messages.vm_destroyed) {
-		dlog_verbose(
-			"VM availability messaging: SP %#x is not subscribed "
-			"to VM destruction messages\n",
-			receiver_id);
-		goto out;
-	}
-
-	if (ANY_BITS_SET(args.arg5, FFA_VM_AVAILABILITY_MESSAGE_SBZ_HI,
-			 FFA_VM_AVAILABILITY_MESSAGE_SBZ_LO)) {
-		dlog_warning(
-			"VM availability messaging: bits[%u:%u] of w5 are "
-			"reserved and should be zero (w5=%#lx)\n",
-			FFA_VM_AVAILABILITY_MESSAGE_SBZ_HI,
-			FFA_VM_AVAILABILITY_MESSAGE_SBZ_LO, args.arg5);
-	}
-
-	if (args.arg6 != 0) {
-		dlog_warning(
-			"VM availability messaging: w6 is reserved and should "
-			"be zero (w6=%#lx)\n",
-			args.arg6);
-	}
-
-	if (args.arg7 != 0) {
-		dlog_warning(
-			"VM availability messaging: w7 is reserved and should "
-			"be zero (w7=%#lx)\n",
-			args.arg7);
-	}
-
-	ret = (struct ffa_value){.func = FFA_SUCCESS_32};
-
-out:
-
-	vm_unlock(&receiver);
-	return ret;
-}
-
-/**
- * Handle framework messages: in particular, check VM availability messages are
- * valid.
- */
-bool plat_ffa_handle_framework_msg(struct ffa_value args, struct ffa_value *ret)
-{
-	enum ffa_framework_msg_func func = ffa_framework_msg_func(args);
-
-	switch (func) {
-	case FFA_FRAMEWORK_MSG_VM_CREATION_REQ:
-	case FFA_FRAMEWORK_MSG_VM_DESTRUCTION_REQ:
-		*ret = check_vm_availability_message(args);
-		if (ret->func != FFA_SUCCESS_32) {
-			return true;
-		}
-		break;
-	default:
-		break;
-	}
-
-	return false;
-}
diff --git a/src/ffa/spmc/direct_messaging.c b/src/ffa/spmc/direct_messaging.c
index f76987b..79473bc 100644
--- a/src/ffa/spmc/direct_messaging.c
+++ b/src/ffa/spmc/direct_messaging.c
@@ -8,8 +8,11 @@
 
 #include "hf/ffa/direct_messaging.h"
 
-#include "hf/ffa.h"
-#include "hf/vm.h"
+#include "hf/arch/gicv3.h"
+
+#include "hf/bits.h"
+#include "hf/ffa_internal.h"
+#include "hf/plat/interrupts.h"
 
 bool ffa_direct_msg_is_direct_request_valid(struct vcpu *current,
 					    ffa_id_t sender_vm_id,
@@ -121,3 +124,212 @@
 
 	return false;
 }
+
+/**
+ * If the interrupts were indeed masked by SPMC before an SP's vCPU was resumed,
+ * restore the priority mask thereby allowing the interrupts to be delivered.
+ */
+void plat_ffa_vcpu_allow_interrupts(struct vcpu *current)
+{
+	plat_interrupts_set_priority_mask(current->prev_interrupt_priority);
+}
+
+/*
+ * Unwind the present call chain upon the invocation of
+ * FFA_MSG_SEND_DIRECT_RESP ABI. The function also returns
+ * the partition ID to which the caller must return to. In
+ * case the call chain was started by an SPMD logical
+ * partition direct message, at the end of the call chain,
+ * we need to return other world's id so that the SPMC can
+ * return to the SPMD.
+ */
+void ffa_direct_msg_unwind_call_chain_ffa_direct_resp(
+	struct vcpu_locked current_locked, struct vcpu_locked next_locked)
+{
+	struct vcpu *next = next_locked.vcpu;
+	ffa_id_t receiver_vm_id = next->vm->id;
+	struct vcpu *current = current_locked.vcpu;
+
+	assert(current->call_chain.next_node == NULL);
+	current->scheduling_mode = NONE;
+	current->rt_model = RTM_NONE;
+
+	/* Allow interrupts if they were masked earlier. */
+	plat_ffa_vcpu_allow_interrupts(current);
+
+	if (!vm_id_is_current_world(receiver_vm_id)) {
+		/* End of NWd scheduled call chain. */
+		assert(current->call_chain.prev_node == NULL);
+	} else {
+		/* Removing a node from an existing call chain. */
+		vcpu_call_chain_remove_node(current_locked, next_locked);
+	}
+}
+
+/**
+ * Enforce action of an SP in response to non-secure or other-secure interrupt
+ * by changing the priority mask. Effectively, physical interrupts shall not
+ * trigger which has the same effect as queueing interrupts.
+ */
+static void plat_ffa_vcpu_queue_interrupts(
+	struct vcpu_locked receiver_vcpu_locked)
+{
+	struct vcpu *receiver_vcpu = receiver_vcpu_locked.vcpu;
+	uint8_t current_priority;
+
+	/* Save current value of priority mask. */
+	current_priority = plat_interrupts_get_priority_mask();
+	receiver_vcpu->prev_interrupt_priority = current_priority;
+
+	if (receiver_vcpu->vm->other_s_interrupts_action ==
+		    OTHER_S_INT_ACTION_QUEUED ||
+	    receiver_vcpu->scheduling_mode == SPMC_MODE) {
+		/*
+		 * If secure interrupts not masked yet, mask them now. We could
+		 * enter SPMC scheduled mode when an EL3 SPMD Logical partition
+		 * sends a direct request, and we are making the IMPDEF choice
+		 * to mask interrupts when such a situation occurs. This keeps
+		 * design simple.
+		 */
+		if (current_priority > SWD_MASK_ALL_INT) {
+			plat_interrupts_set_priority_mask(SWD_MASK_ALL_INT);
+		}
+	} else if (receiver_vcpu->vm->ns_interrupts_action ==
+		   NS_ACTION_QUEUED) {
+		/* If non secure interrupts not masked yet, mask them now. */
+		if (current_priority > SWD_MASK_NS_INT) {
+			plat_interrupts_set_priority_mask(SWD_MASK_NS_INT);
+		}
+	}
+}
+
+/*
+ * Start winding the call chain or continue to wind the present one upon the
+ * invocation of FFA_MSG_SEND_DIRECT_REQ or FFA_MSG_SEND_DIRECT_REQ2 (FF-A v1.2)
+ * ABI.
+ */
+void ffa_direct_msg_wind_call_chain_ffa_direct_req(
+	struct vcpu_locked current_locked,
+	struct vcpu_locked receiver_vcpu_locked, ffa_id_t sender_vm_id)
+{
+	struct vcpu *current = current_locked.vcpu;
+	struct vcpu *receiver_vcpu = receiver_vcpu_locked.vcpu;
+
+	CHECK(receiver_vcpu->scheduling_mode == NONE);
+	CHECK(receiver_vcpu->call_chain.prev_node == NULL);
+	CHECK(receiver_vcpu->call_chain.next_node == NULL);
+	CHECK(receiver_vcpu->rt_model == RTM_NONE);
+
+	receiver_vcpu->rt_model = RTM_FFA_DIR_REQ;
+
+	if (!vm_id_is_current_world(sender_vm_id)) {
+		/* Start of NWd scheduled call chain. */
+		receiver_vcpu->scheduling_mode = NWD_MODE;
+	} else if (plat_ffa_is_spmd_lp_id(sender_vm_id)) {
+		receiver_vcpu->scheduling_mode = SPMC_MODE;
+	} else {
+		/* Adding a new node to an existing call chain. */
+		vcpu_call_chain_extend(current_locked, receiver_vcpu_locked);
+		receiver_vcpu->scheduling_mode = current->scheduling_mode;
+	}
+	plat_ffa_vcpu_queue_interrupts(receiver_vcpu_locked);
+}
+
+/**
+ * Check that the arguments to a VM availability message are correct.
+ * Returns `FFA_SUCCESS_32` if the arguments are correct.
+ * Returns `FFA_INVALID_PARAMETERS` if:
+ * - the receiver is not a valid VM
+ * - the receiver has not subscribed to the message type
+ */
+static struct ffa_value check_vm_availability_message(struct ffa_value args)
+{
+	struct ffa_value ret = ffa_error(FFA_INVALID_PARAMETERS);
+	enum ffa_framework_msg_func func = ffa_framework_msg_func(args);
+	ffa_id_t receiver_id = ffa_receiver(args);
+	struct vm_locked receiver = vm_find_locked(receiver_id);
+
+	if (receiver.vm == NULL) {
+		dlog_verbose(
+			"VM availability messaging: could not find SP %#x\n",
+			receiver_id);
+		return ret;
+	}
+
+	/* only valid if receiver has subscribed */
+	if (func == FFA_FRAMEWORK_MSG_VM_CREATION_REQ &&
+	    !receiver.vm->vm_availability_messages.vm_created) {
+		dlog_verbose(
+			"VM availability messaging: SP %#x is not subscribed "
+			"to VM creation messages\n",
+			receiver_id);
+		goto out;
+	}
+
+	if (func == FFA_FRAMEWORK_MSG_VM_DESTRUCTION_REQ &&
+	    !receiver.vm->vm_availability_messages.vm_destroyed) {
+		dlog_verbose(
+			"VM availability messaging: SP %#x is not subscribed "
+			"to VM destruction messages\n",
+			receiver_id);
+		goto out;
+	}
+
+	if (ANY_BITS_SET(args.arg5, FFA_VM_AVAILABILITY_MESSAGE_SBZ_HI,
+			 FFA_VM_AVAILABILITY_MESSAGE_SBZ_LO)) {
+		dlog_warning(
+			"VM availability messaging: bits[%u:%u] of w5 are "
+			"reserved and should be zero (w5=%#lx)\n",
+			FFA_VM_AVAILABILITY_MESSAGE_SBZ_HI,
+			FFA_VM_AVAILABILITY_MESSAGE_SBZ_LO, args.arg5);
+	}
+
+	if (args.arg6 != 0) {
+		dlog_warning(
+			"VM availability messaging: w6 is reserved and should "
+			"be zero (w6=%#lx)\n",
+			args.arg6);
+	}
+
+	if (args.arg7 != 0) {
+		dlog_warning(
+			"VM availability messaging: w7 is reserved and should "
+			"be zero (w7=%#lx)\n",
+			args.arg7);
+	}
+
+	ret = (struct ffa_value){.func = FFA_SUCCESS_32};
+
+out:
+
+	vm_unlock(&receiver);
+	return ret;
+}
+
+/**
+ * Handle framework messages: in particular, check VM availability messages are
+ * valid.
+ */
+bool plat_ffa_handle_framework_msg(struct ffa_value args, struct ffa_value *ret)
+{
+	enum ffa_framework_msg_func func = ffa_framework_msg_func(args);
+
+	switch (func) {
+	case FFA_FRAMEWORK_MSG_VM_CREATION_REQ:
+	case FFA_FRAMEWORK_MSG_VM_DESTRUCTION_REQ:
+		*ret = check_vm_availability_message(args);
+		if (ret->func != FFA_SUCCESS_32) {
+			return true;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return false;
+}
+
+bool plat_ffa_is_spmd_lp_id(ffa_id_t vm_id)
+{
+	return (vm_id >= EL3_SPMD_LP_ID_START && vm_id <= EL3_SPMD_LP_ID_END);
+}
diff --git a/src/ffa/spmc/notifications.c b/src/ffa/spmc/notifications.c
index d27c76b..a055e5e 100644
--- a/src/ffa/spmc/notifications.c
+++ b/src/ffa/spmc/notifications.c
@@ -13,6 +13,7 @@
 #include "hf/check.h"
 #include "hf/cpu.h"
 #include "hf/ffa.h"
+#include "hf/ffa/direct_messaging.h"
 #include "hf/ffa/vm.h"
 #include "hf/ffa_internal.h"
 #include "hf/plat/interrupts.h"