fix(ff-a): dispatch other world functions

Move FF-A related functions from other world module to plat ffa module
with different implementations based upon building the Hypervisor, SPMC,
or standalone image.

Change-Id: I85bedf58ddc074d41bb25ae2dcbcdaa407821562
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/src/api.c b/src/api.c
index 01c91b5..5d9e32f 100644
--- a/src/api.c
+++ b/src/api.c
@@ -10,9 +10,9 @@
 
 #include "hf/arch/cpu.h"
 #include "hf/arch/ffa.h"
-#include "hf/arch/ffa_memory_handle.h"
 #include "hf/arch/mm.h"
 #include "hf/arch/other_world.h"
+#include "hf/arch/plat/ffa.h"
 #include "hf/arch/timer.h"
 #include "hf/arch/vm.h"
 
@@ -1788,13 +1788,12 @@
 		return ffa_error(FFA_INVALID_PARAMETERS);
 	}
 
-	if (!arch_other_world_is_direct_request_valid(current, sender_vm_id,
-						      receiver_vm_id)) {
+	if (!plat_ffa_is_direct_request_valid(current, sender_vm_id,
+					      receiver_vm_id)) {
 		return ffa_error(FFA_INVALID_PARAMETERS);
 	}
 
-	if (arch_other_world_direct_request_forward(receiver_vm_id, args,
-						    &ret)) {
+	if (plat_ffa_direct_request_forward(receiver_vm_id, args, &ret)) {
 		return ret;
 	}
 
@@ -1912,8 +1911,8 @@
 
 	struct ffa_value to_ret = api_ffa_dir_msg_value(args);
 
-	if (!arch_other_world_is_direct_response_valid(current, sender_vm_id,
-						       receiver_vm_id)) {
+	if (!plat_ffa_is_direct_response_valid(current, sender_vm_id,
+					       receiver_vm_id)) {
 		return ffa_error(FFA_INVALID_PARAMETERS);
 	}
 
@@ -2247,7 +2246,7 @@
 	struct vm *to = current->vm;
 	struct ffa_value ret;
 
-	if (ffa_memory_handle_allocated_by_current_world(handle)) {
+	if (plat_ffa_memory_handle_allocated_by_current_world(handle)) {
 		struct vm_locked to_locked = vm_lock(to);
 
 		ret = ffa_memory_reclaim(to_locked, handle, flags,
diff --git a/src/arch/aarch64/hypervisor/BUILD.gn b/src/arch/aarch64/hypervisor/BUILD.gn
index 4a366fa..6068d1e 100644
--- a/src/arch/aarch64/hypervisor/BUILD.gn
+++ b/src/arch/aarch64/hypervisor/BUILD.gn
@@ -17,7 +17,6 @@
 source_set("other_world") {
   public_configs = [ "//src/arch/aarch64:config" ]
   sources = [
-    "ffa_memory_handle.c",
     "other_world.c",
   ]
   deps = [
diff --git a/src/arch/aarch64/hypervisor/exceptions.S b/src/arch/aarch64/hypervisor/exceptions.S
index 1779ca5..7de43a8 100644
--- a/src/arch/aarch64/hypervisor/exceptions.S
+++ b/src/arch/aarch64/hypervisor/exceptions.S
@@ -450,8 +450,8 @@
 
 	/* Restore the other world SVE context from internal buffer. */
 sve_context_restore:
-	adrp x18, sve_other_world_context
-	add x18, x18, :lo12: sve_other_world_context
+	adrp x18, sve_context
+	add x18, x18, :lo12: sve_context
 	ldr x0, [x19, #VCPU_CPU]
 	bl cpu_index
 	mov x20, #SVE_CTX_SIZE
@@ -522,8 +522,8 @@
 
 	/* Save the other world SVE context to internal buffer. */
 sve_context_save:
-	adrp x18, sve_other_world_context
-	add x18, x18, :lo12: sve_other_world_context
+	adrp x18, sve_context
+	add x18, x18, :lo12: sve_context
 	ldr x0, [x19, #VCPU_CPU]
 	bl cpu_index
 	mov x20, #SVE_CTX_SIZE
diff --git a/src/arch/aarch64/hypervisor/ffa_memory_handle.c b/src/arch/aarch64/hypervisor/ffa_memory_handle.c
deleted file mode 100644
index 647186d..0000000
--- a/src/arch/aarch64/hypervisor/ffa_memory_handle.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2021 The Hafnium Authors.
- *
- * Use of this source code is governed by a BSD-style
- * license that can be found in the LICENSE file or at
- * https://opensource.org/licenses/BSD-3-Clause.
- */
-
-#include "hf/arch/ffa_memory_handle.h"
-
-ffa_memory_handle_t ffa_memory_handle_make(uint64_t index)
-{
-#if SECURE_WORLD == 1
-	return (index & ~FFA_MEMORY_HANDLE_ALLOCATOR_MASK) |
-	       FFA_MEMORY_HANDLE_ALLOCATOR_SPMC;
-#else
-	return index | FFA_MEMORY_HANDLE_ALLOCATOR_HYPERVISOR;
-#endif
-}
-
-bool ffa_memory_handle_allocated_by_current_world(ffa_memory_handle_t handle)
-{
-	return (handle & FFA_MEMORY_HANDLE_ALLOCATOR_MASK) ==
-#if SECURE_WORLD == 1
-	       FFA_MEMORY_HANDLE_ALLOCATOR_SPMC;
-#else
-	       FFA_MEMORY_HANDLE_ALLOCATOR_HYPERVISOR;
-#endif
-}
diff --git a/src/arch/aarch64/hypervisor/offsets.c b/src/arch/aarch64/hypervisor/offsets.c
index f795bd9..f09fa17 100644
--- a/src/arch/aarch64/hypervisor/offsets.c
+++ b/src/arch/aarch64/hypervisor/offsets.c
@@ -6,7 +6,7 @@
  * https://opensource.org/licenses/BSD-3-Clause.
  */
 
-#include "hf/arch/other_world.h"
+#include "hf/arch/sve.h"
 
 #include "hf/cpu.h"
 #include "hf/offset_size_header.h"
@@ -31,7 +31,6 @@
 DEFINE_OFFSETOF(VCPU_GIC, struct vcpu, regs.gic)
 #endif
 
-DEFINE_SIZEOF(SVE_CTX_SIZE, struct sve_other_world_context_t)
-DEFINE_OFFSETOF(SVE_CTX_FFR, struct sve_other_world_context_t, ffr)
-DEFINE_OFFSETOF(SVE_CTX_PREDICATES, struct sve_other_world_context_t,
-		predicates)
+DEFINE_SIZEOF(SVE_CTX_SIZE, struct sve_context_t)
+DEFINE_OFFSETOF(SVE_CTX_FFR, struct sve_context_t, ffr)
+DEFINE_OFFSETOF(SVE_CTX_PREDICATES, struct sve_context_t, predicates)
diff --git a/src/arch/aarch64/hypervisor/other_world.c b/src/arch/aarch64/hypervisor/other_world.c
index 2e1aebc..775f33c 100644
--- a/src/arch/aarch64/hypervisor/other_world.c
+++ b/src/arch/aarch64/hypervisor/other_world.c
@@ -10,93 +10,15 @@
 
 #include "hf/arch/mmu.h"
 
-#include "hf/check.h"
 #include "hf/dlog.h"
 #include "hf/ffa.h"
-#include "hf/panic.h"
+#include "hf/vcpu.h"
 #include "hf/vm.h"
 
-#include "msr.h"
 #include "smc.h"
 
-#if SECURE_WORLD == 0
-
-alignas(PAGE_SIZE) static uint8_t other_world_send_buffer[HF_MAILBOX_SIZE];
-alignas(PAGE_SIZE) static uint8_t other_world_recv_buffer[HF_MAILBOX_SIZE];
-
-#endif
-#if SECURE_WORLD == 1
-
-/** Other world SVE context (accessed from other_world_loop). */
-struct sve_other_world_context_t sve_other_world_context[MAX_CPUS];
-
-#endif
-
-void arch_other_world_log_init(void)
-{
-#if SECURE_WORLD == 0
-	dlog_info("Initializing Hafnium (Hypervisor)\n");
-#else
-	dlog_info("Initializing Hafnium (SPMC)\n");
-#endif
-}
-
-void arch_other_world_init(void)
-{
-#if SECURE_WORLD == 0
-
-	struct vm *other_world_vm = vm_find(HF_OTHER_WORLD_ID);
-	struct ffa_value ret;
-	uint32_t func;
-
-	CHECK(other_world_vm != NULL);
-
-	/* Setup TEE VM RX/TX buffers */
-	other_world_vm->mailbox.send = &other_world_send_buffer;
-	other_world_vm->mailbox.recv = &other_world_recv_buffer;
-
-	/*
-	 * Note that send and recv are swapped around, as the send buffer from
-	 * Hafnium's perspective is the recv buffer from the EL3 dispatcher's
-	 * perspective and vice-versa.
-	 */
-	dlog_verbose("Setting up buffers for TEE.\n");
-	ret = arch_other_world_call((struct ffa_value){
-		.func = FFA_RXTX_MAP_64,
-		.arg1 = pa_addr(
-			pa_from_va(va_from_ptr(other_world_vm->mailbox.recv))),
-		.arg2 = pa_addr(
-			pa_from_va(va_from_ptr(other_world_vm->mailbox.send))),
-		.arg3 = HF_MAILBOX_SIZE / FFA_PAGE_SIZE});
-	func = ret.func & ~SMCCC_CONVENTION_MASK;
-	if (ret.func == SMCCC_ERROR_UNKNOWN) {
-		dlog_error(
-			"Unknown function setting up TEE message buffers. "
-			"Memory sharing with TEE will not work.\n");
-		return;
-	}
-	if (func == FFA_ERROR_32) {
-		panic("Error %d setting up TEE message buffers.", ret.arg2);
-	} else if (func != FFA_SUCCESS_32) {
-		panic("Unexpected function %#x returned setting up TEE message "
-		      "buffers.",
-		      ret.func);
-	}
-	dlog_verbose("TEE finished setting up buffers.\n");
-#endif
-}
-
 bool arch_other_world_vm_init(struct vm *other_world_vm, struct mpool *ppool)
 {
-#if SECURE_WORLD == 0
-
-	(void)other_world_vm;
-	(void)ppool;
-
-	return true;
-
-#else
-
 	struct vm_locked other_world_vm_locked;
 	bool ret = false;
 
@@ -119,103 +41,6 @@
 	vm_unlock(&other_world_vm_locked);
 
 	return ret;
-
-#endif
-}
-
-/**
- * Check validity of a FF-A direct message request.
- */
-bool arch_other_world_is_direct_request_valid(struct vcpu *current,
-					      ffa_vm_id_t sender_vm_id,
-					      ffa_vm_id_t receiver_vm_id)
-{
-	ffa_vm_id_t current_vm_id = current->vm->id;
-
-#if SECURE_WORLD == 1
-
-	/*
-	 * The normal world can send direct message requests
-	 * via the Hypervisor to any SP. SPs can also send direct messages
-	 * to each other.
-	 */
-	return sender_vm_id != receiver_vm_id &&
-	       (sender_vm_id == current_vm_id ||
-		(current_vm_id == HF_HYPERVISOR_VM_ID &&
-		 !vm_id_is_current_world(sender_vm_id)));
-#else
-
-	/*
-	 * The primary VM can send direct message request to
-	 * any other VM (but itself) or SP, but can't spoof
-	 * a different sender.
-	 */
-	return sender_vm_id != receiver_vm_id &&
-	       sender_vm_id == current_vm_id &&
-	       current_vm_id == HF_PRIMARY_VM_ID;
-
-#endif
-
-	return false;
-}
-
-/**
- * Check validity of a FF-A direct message response.
- */
-bool arch_other_world_is_direct_response_valid(struct vcpu *current,
-					       ffa_vm_id_t sender_vm_id,
-					       ffa_vm_id_t receiver_vm_id)
-{
-	ffa_vm_id_t current_vm_id = current->vm->id;
-
-#if SECURE_WORLD == 1
-
-	/*
-	 * Direct message responses emitted from a SP target either the NWd
-	 * or another SP.
-	 */
-	return sender_vm_id != receiver_vm_id &&
-	       sender_vm_id == current_vm_id &&
-	       vm_id_is_current_world(sender_vm_id);
-
-#else
-
-	/*
-	 * Secondary VMs can send direct message responses to
-	 * the PVM, but can't spoof a different sender.
-	 */
-	return sender_vm_id != receiver_vm_id &&
-	       sender_vm_id == current_vm_id &&
-	       receiver_vm_id == HF_PRIMARY_VM_ID;
-
-#endif
-
-	return false;
-}
-
-bool arch_other_world_direct_request_forward(ffa_vm_id_t receiver_vm_id,
-					     struct ffa_value args,
-					     struct ffa_value *ret)
-{
-#if SECURE_WORLD == 1
-	/*
-	 * SPs are not supposed to issue requests to VMs.
-	 */
-	(void)receiver_vm_id;
-	(void)args;
-	(void)ret;
-
-#else
-	/*
-	 * VM's requests should be forwarded to the SPMC, if receiver is an SP.
-	 */
-	if (!vm_id_is_current_world(receiver_vm_id)) {
-		*ret = arch_other_world_call(args);
-		return true;
-	}
-#endif
-
-	return false;
 }
 
 struct ffa_value arch_other_world_call(struct ffa_value args)
diff --git a/src/arch/aarch64/inc/hf/arch/sve.h b/src/arch/aarch64/inc/hf/arch/sve.h
new file mode 100644
index 0000000..cc8c6a1
--- /dev/null
+++ b/src/arch/aarch64/inc/hf/arch/sve.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2021 The Hafnium Authors.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/BSD-3-Clause.
+ */
+
+#include "hf/arch/types.h"
+
+/** SVE vector size supported. */
+#define HF_SVE_VECTOR_LENGTH 512
+
+struct sve_context_t {
+	uint8_t vectors[32][HF_SVE_VECTOR_LENGTH / 8];
+
+	/* FFR and predicates are one-eigth of the SVE vector length */
+	uint8_t ffr[HF_SVE_VECTOR_LENGTH / 64];
+
+	uint8_t predicates[16][HF_SVE_VECTOR_LENGTH / 64];
+} __attribute__((aligned(16)));
diff --git a/src/arch/aarch64/plat/ffa/BUILD.gn b/src/arch/aarch64/plat/ffa/BUILD.gn
index 8b278fd..358cf2d 100644
--- a/src/arch/aarch64/plat/ffa/BUILD.gn
+++ b/src/arch/aarch64/plat/ffa/BUILD.gn
@@ -7,8 +7,10 @@
 import("//build/toolchain/platform.gni")
 
 source_set("absent") {
+  public_configs = [ "//src/arch/${plat_arch}:config" ]
   sources = [
     "absent.c",
+    "hypervisor_common.c",
   ]
 }
 
@@ -16,6 +18,7 @@
   public_configs = [ "//src/arch/${plat_arch}:config" ]
   sources = [
     "hypervisor.c",
+    "hypervisor_common.c",
   ]
 }
 
diff --git a/src/arch/aarch64/plat/ffa/hypervisor_common.c b/src/arch/aarch64/plat/ffa/hypervisor_common.c
new file mode 100644
index 0000000..3c518a5
--- /dev/null
+++ b/src/arch/aarch64/plat/ffa/hypervisor_common.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2021 The Hafnium Authors.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/BSD-3-Clause.
+ */
+
+#include "hf/arch/other_world.h"
+
+#include "hf/dlog.h"
+#include "hf/ffa.h"
+#include "hf/vm.h"
+
+#include "smc.h"
+
+alignas(FFA_PAGE_SIZE) static uint8_t other_world_send_buffer[HF_MAILBOX_SIZE];
+alignas(FFA_PAGE_SIZE) static uint8_t other_world_recv_buffer[HF_MAILBOX_SIZE];
+
+void plat_ffa_log_init(void)
+{
+	dlog_info("Initializing Hafnium (Hypervisor)\n");
+}
+
+void plat_ffa_init(bool tee_enabled)
+{
+	struct vm *other_world_vm = vm_find(HF_OTHER_WORLD_ID);
+	struct ffa_value ret;
+	uint32_t func;
+
+	if (!tee_enabled) {
+		return;
+	}
+
+	CHECK(other_world_vm != NULL);
+
+	/* Setup TEE VM RX/TX buffers */
+	other_world_vm->mailbox.send = &other_world_send_buffer;
+	other_world_vm->mailbox.recv = &other_world_recv_buffer;
+
+	/*
+	 * Note that send and recv are swapped around, as the send buffer from
+	 * Hafnium's perspective is the recv buffer from the EL3 dispatcher's
+	 * perspective and vice-versa.
+	 */
+	dlog_verbose("Setting up buffers for TEE.\n");
+	ret = arch_other_world_call((struct ffa_value){
+		.func = FFA_RXTX_MAP_64,
+		.arg1 = pa_addr(
+			pa_from_va(va_from_ptr(other_world_vm->mailbox.recv))),
+		.arg2 = pa_addr(
+			pa_from_va(va_from_ptr(other_world_vm->mailbox.send))),
+		.arg3 = HF_MAILBOX_SIZE / FFA_PAGE_SIZE});
+	func = ret.func & ~SMCCC_CONVENTION_MASK;
+	if (ret.func == SMCCC_ERROR_UNKNOWN) {
+		dlog_error(
+			"Unknown function setting up TEE message buffers. "
+			"Memory sharing with TEE will not work.\n");
+		return;
+	}
+	if (func == FFA_ERROR_32) {
+		panic("Error %d setting up TEE message buffers.", ret.arg2);
+	} else if (func != FFA_SUCCESS_32) {
+		panic("Unexpected function %#x returned setting up TEE message "
+		      "buffers.",
+		      ret.func);
+	}
+	dlog_verbose("TEE finished setting up buffers.\n");
+}
+
+/**
+ * Check validity of a FF-A direct message request.
+ */
+bool plat_ffa_is_direct_request_valid(struct vcpu *current,
+				      ffa_vm_id_t sender_vm_id,
+				      ffa_vm_id_t receiver_vm_id)
+{
+	ffa_vm_id_t current_vm_id = current->vm->id;
+
+	/*
+	 * The primary VM can send direct message request to
+	 * any other VM (but itself) or SP, but can't spoof
+	 * a different sender.
+	 */
+	return sender_vm_id != receiver_vm_id &&
+	       sender_vm_id == current_vm_id &&
+	       current_vm_id == HF_PRIMARY_VM_ID;
+}
+
+/**
+ * Check validity of a FF-A direct message response.
+ */
+bool plat_ffa_is_direct_response_valid(struct vcpu *current,
+				       ffa_vm_id_t sender_vm_id,
+				       ffa_vm_id_t receiver_vm_id)
+{
+	ffa_vm_id_t current_vm_id = current->vm->id;
+
+	/*
+	 * Secondary VMs can send direct message responses to
+	 * the PVM, but can't spoof a different sender.
+	 */
+	return sender_vm_id != receiver_vm_id &&
+	       sender_vm_id == current_vm_id &&
+	       receiver_vm_id == HF_PRIMARY_VM_ID;
+}
+
+bool plat_ffa_direct_request_forward(ffa_vm_id_t receiver_vm_id,
+				     struct ffa_value args,
+				     struct ffa_value *ret)
+{
+	/*
+	 * VM's requests should be forwarded to the SPMC, if receiver is an SP.
+	 */
+	dlog_verbose("%s calling SPMC %#x %#x %#x %#x %#x\n", __func__,
+		     args.func, args.arg1, args.arg2, args.arg3, args.arg4);
+	if (!vm_id_is_current_world(receiver_vm_id)) {
+		*ret = arch_other_world_call(args);
+		return true;
+	}
+
+	return false;
+}
+
+ffa_memory_handle_t plat_ffa_memory_handle_make(uint64_t index)
+{
+	return index | FFA_MEMORY_HANDLE_ALLOCATOR_HYPERVISOR;
+}
+
+bool plat_ffa_memory_handle_allocated_by_current_world(
+	ffa_memory_handle_t handle)
+{
+	return (handle & FFA_MEMORY_HANDLE_ALLOCATOR_MASK) ==
+	       FFA_MEMORY_HANDLE_ALLOCATOR_HYPERVISOR;
+}
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index 8cd65c4..fae06f1 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -6,10 +6,24 @@
  * https://opensource.org/licenses/BSD-3-Clause.
  */
 
+#include "hf/arch/mmu.h"
+#include "hf/arch/other_world.h"
+#include "hf/arch/sve.h"
+
+#include "hf/dlog.h"
 #include "hf/ffa.h"
+#include "hf/vm.h"
 
 #include "smc.h"
 
+/** Other world SVE context (accessed from other_world_loop). */
+struct sve_context_t sve_context[MAX_CPUS];
+
+void plat_ffa_log_init(void)
+{
+	dlog_info("Initializing Hafnium (SPMC)\n");
+}
+
 struct ffa_value plat_ffa_spmc_id_get(void)
 {
 	/*
@@ -18,3 +32,73 @@
 	 */
 	return smc_ffa_call((struct ffa_value){.func = FFA_ID_GET_32});
 }
+
+void plat_ffa_init(bool tee_enabled)
+{
+	(void)tee_enabled;
+}
+
+/**
+ * Check validity of a FF-A direct message request.
+ */
+bool plat_ffa_is_direct_request_valid(struct vcpu *current,
+				      ffa_vm_id_t sender_vm_id,
+				      ffa_vm_id_t receiver_vm_id)
+{
+	ffa_vm_id_t current_vm_id = current->vm->id;
+
+	/*
+	 * The normal world can send direct message requests
+	 * via the Hypervisor to any SP. SPs can also send direct messages
+	 * to each other.
+	 */
+	return sender_vm_id != receiver_vm_id &&
+	       (sender_vm_id == current_vm_id ||
+		(current_vm_id == HF_HYPERVISOR_VM_ID &&
+		 !vm_id_is_current_world(sender_vm_id)));
+}
+
+/**
+ * Check validity of a FF-A direct message response.
+ */
+bool plat_ffa_is_direct_response_valid(struct vcpu *current,
+				       ffa_vm_id_t sender_vm_id,
+				       ffa_vm_id_t receiver_vm_id)
+{
+	ffa_vm_id_t current_vm_id = current->vm->id;
+
+	/*
+	 * Direct message responses emitted from a SP target either the NWd
+	 * or another SP.
+	 */
+	return sender_vm_id != receiver_vm_id &&
+	       sender_vm_id == current_vm_id &&
+	       vm_id_is_current_world(sender_vm_id);
+}
+
+bool plat_ffa_direct_request_forward(ffa_vm_id_t receiver_vm_id,
+				     struct ffa_value args,
+				     struct ffa_value *ret)
+{
+	/*
+	 * SPs are not supposed to issue requests to VMs.
+	 */
+	(void)receiver_vm_id;
+	(void)args;
+	(void)ret;
+
+	return false;
+}
+
+ffa_memory_handle_t plat_ffa_memory_handle_make(uint64_t index)
+{
+	return (index & ~FFA_MEMORY_HANDLE_ALLOCATOR_MASK) |
+	       FFA_MEMORY_HANDLE_ALLOCATOR_SPMC;
+}
+
+bool plat_ffa_memory_handle_allocated_by_current_world(
+	ffa_memory_handle_t handle)
+{
+	return (handle & FFA_MEMORY_HANDLE_ALLOCATOR_MASK) ==
+	       FFA_MEMORY_HANDLE_ALLOCATOR_SPMC;
+}
diff --git a/src/arch/fake/hypervisor/BUILD.gn b/src/arch/fake/hypervisor/BUILD.gn
index 4c6f2c2..cd0db5f 100644
--- a/src/arch/fake/hypervisor/BUILD.gn
+++ b/src/arch/fake/hypervisor/BUILD.gn
@@ -17,7 +17,6 @@
 
 source_set("other_world") {
   sources = [
-    "ffa_memory_handle.c",
     "other_world.c",
   ]
 }
diff --git a/src/arch/fake/hypervisor/ffa.c b/src/arch/fake/hypervisor/ffa.c
index 08183e8..cacc1b2 100644
--- a/src/arch/fake/hypervisor/ffa.c
+++ b/src/arch/fake/hypervisor/ffa.c
@@ -8,9 +8,57 @@
 
 #include "hf/ffa.h"
 
-#include "hf/vm_ids.h"
+#include "hf/vcpu.h"
 
 ffa_vm_id_t arch_ffa_spmc_id_get(void)
 {
 	return HF_SPMC_VM_ID;
 }
+
+void plat_ffa_log_init(void)
+{
+}
+
+bool plat_ffa_is_direct_request_valid(struct vcpu *current,
+				      ffa_vm_id_t sender_vm_id,
+				      ffa_vm_id_t receiver_vm_id)
+{
+	(void)current;
+	(void)sender_vm_id;
+	(void)receiver_vm_id;
+
+	return true;
+}
+
+bool plat_ffa_is_direct_response_valid(struct vcpu *current,
+				       ffa_vm_id_t sender_vm_id,
+				       ffa_vm_id_t receiver_vm_id)
+{
+	(void)current;
+	(void)sender_vm_id;
+	(void)receiver_vm_id;
+
+	return true;
+}
+
+bool plat_ffa_direct_request_forward(ffa_vm_id_t receiver_vm_id,
+				     struct ffa_value args,
+				     struct ffa_value *ret)
+{
+	(void)receiver_vm_id;
+	(void)args;
+	(void)ret;
+	return false;
+}
+
+ffa_memory_handle_t plat_ffa_memory_handle_make(uint64_t index)
+{
+	return index;
+}
+
+bool plat_ffa_memory_handle_allocated_by_current_world(
+	ffa_memory_handle_t handle)
+{
+	(void)handle;
+	return false;
+}
diff --git a/src/arch/fake/hypervisor/ffa_memory_handle.c b/src/arch/fake/hypervisor/ffa_memory_handle.c
deleted file mode 100644
index 9091295..0000000
--- a/src/arch/fake/hypervisor/ffa_memory_handle.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2021 The Hafnium Authors.
- *
- * Use of this source code is governed by a BSD-style
- * license that can be found in the LICENSE file or at
- * https://opensource.org/licenses/BSD-3-Clause.
- */
-
-#include "hf/arch/ffa_memory_handle.h"
-
-ffa_memory_handle_t ffa_memory_handle_make(uint64_t index)
-{
-	return index;
-}
-
-bool ffa_memory_handle_allocated_by_current_world(ffa_memory_handle_t handle)
-{
-	(void)handle;
-	return true;
-}
diff --git a/src/arch/fake/hypervisor/other_world.c b/src/arch/fake/hypervisor/other_world.c
index ddba66a..57df952 100644
--- a/src/arch/fake/hypervisor/other_world.c
+++ b/src/arch/fake/hypervisor/other_world.c
@@ -12,45 +12,8 @@
 #include "hf/ffa.h"
 #include "hf/ffa_internal.h"
 
-void arch_other_world_log_init(void)
-{
-	dlog_info("Initializing Hafnium\n");
-}
-
 struct ffa_value arch_other_world_call(struct ffa_value args)
 {
 	dlog_error("Attempted to call TEE function %#x\n", args.func);
 	return ffa_error(FFA_NOT_SUPPORTED);
 }
-
-bool arch_other_world_is_direct_request_valid(struct vcpu *current,
-					      ffa_vm_id_t sender_vm_id,
-					      ffa_vm_id_t receiver_vm_id)
-{
-	(void)current;
-	(void)sender_vm_id;
-	(void)receiver_vm_id;
-
-	return true;
-}
-
-bool arch_other_world_is_direct_response_valid(struct vcpu *current,
-					       ffa_vm_id_t sender_vm_id,
-					       ffa_vm_id_t receiver_vm_id)
-{
-	(void)current;
-	(void)sender_vm_id;
-	(void)receiver_vm_id;
-
-	return true;
-}
-
-bool arch_other_world_direct_request_forward(ffa_vm_id_t receiver_vm_id,
-					     struct ffa_value args,
-					     struct ffa_value *ret)
-{
-	(void)receiver_vm_id;
-	(void)args;
-	(void)ret;
-	return false;
-}
diff --git a/src/ffa_memory.c b/src/ffa_memory.c
index 8b28191..f92957b 100644
--- a/src/ffa_memory.c
+++ b/src/ffa_memory.c
@@ -8,8 +8,8 @@
 
 #include "hf/ffa_memory.h"
 
-#include "hf/arch/ffa_memory_handle.h"
 #include "hf/arch/other_world.h"
+#include "hf/arch/plat/ffa.h"
 
 #include "hf/api.h"
 #include "hf/check.h"
@@ -159,7 +159,7 @@
 
 			if (handle == FFA_MEMORY_HANDLE_INVALID) {
 				memory_region->handle =
-					ffa_memory_handle_make(i);
+					plat_ffa_memory_handle_make(i);
 			} else {
 				memory_region->handle = handle;
 			}
@@ -222,7 +222,7 @@
 	 * First look for a share_state allocated by us, in which case the
 	 * handle is based on the index.
 	 */
-	if (ffa_memory_handle_allocated_by_current_world(handle)) {
+	if (plat_ffa_memory_handle_allocated_by_current_world(handle)) {
 		index = ffa_memory_handle_get_index(handle);
 		if (index < MAX_MEM_SHARES) {
 			share_state = &share_states.share_states[index];
diff --git a/src/init.c b/src/init.c
index 09d503e..d9cb1d7 100644
--- a/src/init.c
+++ b/src/init.c
@@ -12,6 +12,7 @@
 #include <stddef.h>
 
 #include "hf/arch/other_world.h"
+#include "hf/arch/plat/ffa.h"
 
 #include "hf/api.h"
 #include "hf/boot_flow.h"
@@ -48,7 +49,7 @@
 	/* Make sure the console is initialised before calling dlog. */
 	plat_console_init();
 
-	arch_other_world_log_init();
+	plat_ffa_log_init();
 
 	mpool_init(&ppool, MM_PPOOL_ENTRY_SIZE);
 	mpool_add_chunk(&ppool, ptable_buf, sizeof(ptable_buf));
@@ -167,10 +168,8 @@
 	/* Enable TLB invalidation for VM page table updates. */
 	mm_vm_enable_invalidation();
 
-	if (manifest.ffa_tee_enabled) {
-		/* Set up message buffers for TEE dispatcher. */
-		arch_other_world_init();
-	}
+	/* Set up message buffers for TEE dispatcher. */
+	plat_ffa_init(manifest.ffa_tee_enabled);
 
 	dlog_info("Hafnium initialisation completed\n");
 }