refactor(ff-a): init
Move `plat_ffa_init` and `plat_ffa_log_init` to new `init.c` file.
Change-Id: I65484c6d5cd868de01c5bb8fb3edd103a0d61262
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/inc/hf/ffa.h b/inc/hf/ffa.h
index 936e2eb..2d92ef1 100644
--- a/inc/hf/ffa.h
+++ b/inc/hf/ffa.h
@@ -8,11 +8,6 @@
#pragma once
-#include "hf/mpool.h"
#include "hf/vcpu.h"
-void plat_ffa_log_init(void);
-void plat_ffa_set_tee_enabled(bool tee_enabled);
-void plat_ffa_init(struct mpool *ppool);
-
void plat_save_ns_simd_context(struct vcpu *vcpu);
diff --git a/src/ffa/inc/hypervisor.h b/inc/hf/ffa/init.h
similarity index 66%
rename from src/ffa/inc/hypervisor.h
rename to inc/hf/ffa/init.h
index eba52f3..5fef405 100644
--- a/src/ffa/inc/hypervisor.h
+++ b/inc/hf/ffa/init.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Hafnium Authors.
+ * Copyright 2025 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
@@ -8,8 +8,10 @@
#pragma once
-#include <stdbool.h>
+#include "hf/mpool.h"
+
+void plat_ffa_log_init(void);
+void plat_ffa_init(struct mpool *ppool);
bool plat_ffa_is_tee_enabled(void);
-
void plat_ffa_set_tee_enabled(bool tee_enabled);
diff --git a/src/ffa/BUILD.gn b/src/ffa/BUILD.gn
index 3b077bf..5af2a1f 100644
--- a/src/ffa/BUILD.gn
+++ b/src/ffa/BUILD.gn
@@ -28,6 +28,7 @@
"hypervisor/direct_messaging.c",
"hypervisor/ffa_memory.c",
"hypervisor/indirect_messaging.c",
+ "hypervisor/init.c",
"hypervisor/interrupts.c",
"hypervisor/notifications.c",
"hypervisor/setup_and_discovery.c",
@@ -50,6 +51,7 @@
"spmc/direct_messaging.c",
"spmc/ffa_memory.c",
"spmc/indirect_messaging.c",
+ "spmc/init.c",
"spmc/interrupts.c",
"spmc/notifications.c",
"spmc/setup_and_discovery.c",
diff --git a/src/ffa/hypervisor.c b/src/ffa/hypervisor.c
index 07adb9b..94fd9a2 100644
--- a/src/ffa/hypervisor.c
+++ b/src/ffa/hypervisor.c
@@ -15,104 +15,3 @@
#include "hf/ffa_internal.h"
#include "hf/vcpu.h"
#include "hf/vm.h"
-
-static bool ffa_tee_enabled = false;
-
-bool plat_ffa_is_tee_enabled(void)
-{
- return ffa_tee_enabled;
-}
-
-void plat_ffa_set_tee_enabled(bool tee_enabled)
-{
- ffa_tee_enabled = tee_enabled;
-}
-
-void plat_ffa_log_init(void)
-{
- dlog_info("Initializing Hafnium (Hypervisor)\n");
-}
-
-void plat_ffa_init(struct mpool *ppool)
-{
- struct vm *other_world_vm = vm_find(HF_OTHER_WORLD_ID);
- struct ffa_value ret;
- struct mm_stage1_locked mm_stage1_locked;
-
- /* This is a segment from TDRAM for the NS memory in the FVP platform.
- *
- * TODO: We ought to provide a better way to do this, if porting the
- * hypervisor to other platforms. One option would be to provide this
- * via DTS.
- */
- const uint64_t start = 0x90000000;
- const uint64_t len = 0x60000000;
- const paddr_t send_addr = pa_init(start + len - PAGE_SIZE * 1);
- const paddr_t recv_addr = pa_init(start + len - PAGE_SIZE * 2);
-
- (void)ppool;
-
- if (!plat_ffa_is_tee_enabled()) {
- return;
- }
-
- CHECK(other_world_vm != NULL);
-
- arch_ffa_init();
-
- /*
- * Call FFA_VERSION so the SPMC can store the hypervisor's
- * version. This may be useful if there is a mismatch of
- * versions.
- */
- ret = arch_other_world_call((struct ffa_value){
- .func = FFA_VERSION_32, .arg1 = FFA_VERSION_COMPILED});
- if (ret.func == (uint32_t)FFA_NOT_SUPPORTED) {
- panic("Hypervisor and SPMC versions are not compatible.\n");
- }
-
- /*
- * Setup TEE VM RX/TX buffers.
- * Using the following hard-coded addresses, as they must be within the
- * NS memory node in the SPMC manifest. From that region we should
- * exclude the Hypervisor's address space to prevent SPs from using that
- * memory in memory region nodes, or for the NWd to misuse that memory
- * in runtime via memory sharing interfaces.
- */
-
- // NOLINTNEXTLINE(performance-no-int-to-ptr)
- other_world_vm->mailbox.send = (void *)pa_addr(send_addr);
- // NOLINTNEXTLINE(performance-no-int-to-ptr)
- other_world_vm->mailbox.recv = (void *)pa_addr(recv_addr);
-
- /*
- * 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");
- ffa_setup_rxtx_map_spmc(
- pa_from_va(va_from_ptr(other_world_vm->mailbox.recv)),
- pa_from_va(va_from_ptr(other_world_vm->mailbox.send)),
- HF_MAILBOX_SIZE / FFA_PAGE_SIZE);
-
- plat_ffa_set_tee_enabled(true);
-
- /*
- * Hypervisor will write to secure world receive buffer, and will read
- * from the secure world send buffer.
- *
- * Mapping operation is necessary because the ranges are outside of the
- * hypervisor's binary.
- */
- mm_stage1_locked = mm_lock_stage1();
- CHECK(mm_identity_map(mm_stage1_locked, send_addr,
- pa_add(send_addr, PAGE_SIZE),
- MM_MODE_R | MM_MODE_SHARED, ppool) != NULL);
- CHECK(mm_identity_map(
- mm_stage1_locked, recv_addr, pa_add(recv_addr, PAGE_SIZE),
- MM_MODE_R | MM_MODE_W | MM_MODE_SHARED, ppool) != NULL);
- mm_unlock_stage1(&mm_stage1_locked);
-
- dlog_verbose("TEE finished setting up buffers.\n");
-}
diff --git a/src/ffa/hypervisor/direct_messaging.c b/src/ffa/hypervisor/direct_messaging.c
index cfa663f..2555545 100644
--- a/src/ffa/hypervisor/direct_messaging.c
+++ b/src/ffa/hypervisor/direct_messaging.c
@@ -10,11 +10,10 @@
#include "hf/arch/other_world.h"
+#include "hf/ffa/init.h"
#include "hf/vcpu.h"
#include "hf/vm.h"
-#include "hypervisor.h"
-
/**
* Check validity of a FF-A direct message request.
*/
diff --git a/src/ffa/hypervisor/ffa_memory.c b/src/ffa/hypervisor/ffa_memory.c
index 84cbcd4..f41378b 100644
--- a/src/ffa/hypervisor/ffa_memory.c
+++ b/src/ffa/hypervisor/ffa_memory.c
@@ -10,12 +10,12 @@
#include "hf/arch/other_world.h"
+#include "hf/ffa/init.h"
#include "hf/ffa_internal.h"
#include "hf/ffa_memory_internal.h"
#include "hf/std.h"
#include "hf/vm.h"
-#include "hypervisor.h"
#include "sysregs.h"
enum ffa_memory_handle_allocator ffa_memory_get_handle_allocator(void)
diff --git a/src/ffa/hypervisor/indirect_messaging.c b/src/ffa/hypervisor/indirect_messaging.c
index c1da53f..a1a5d4a 100644
--- a/src/ffa/hypervisor/indirect_messaging.c
+++ b/src/ffa/hypervisor/indirect_messaging.c
@@ -11,6 +11,7 @@
#include "hf/arch/other_world.h"
#include "hf/api.h"
+#include "hf/ffa/init.h"
#include "hf/ffa_internal.h"
#include "hf/vm.h"
diff --git a/src/ffa/hypervisor/init.c b/src/ffa/hypervisor/init.c
new file mode 100644
index 0000000..0b53d6a
--- /dev/null
+++ b/src/ffa/hypervisor/init.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2025 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.h"
+#include "hf/arch/other_world.h"
+
+#include "hf/check.h"
+#include "hf/dlog.h"
+#include "hf/ffa/setup_and_discovery.h"
+#include "hf/vcpu.h"
+#include "hf/vm.h"
+
+static bool ffa_tee_enabled = false;
+
+bool plat_ffa_is_tee_enabled(void)
+{
+ return ffa_tee_enabled;
+}
+
+void plat_ffa_set_tee_enabled(bool tee_enabled)
+{
+ ffa_tee_enabled = tee_enabled;
+}
+
+void plat_ffa_log_init(void)
+{
+ dlog_info("Initializing Hafnium (Hypervisor)\n");
+}
+
+void plat_ffa_init(struct mpool *ppool)
+{
+ struct vm *other_world_vm = vm_find(HF_OTHER_WORLD_ID);
+ struct ffa_value ret;
+ struct mm_stage1_locked mm_stage1_locked;
+
+ /* This is a segment from TDRAM for the NS memory in the FVP platform.
+ *
+ * TODO: We ought to provide a better way to do this, if porting the
+ * hypervisor to other platforms. One option would be to provide this
+ * via DTS.
+ */
+ const uint64_t start = 0x90000000;
+ const uint64_t len = 0x60000000;
+ const paddr_t send_addr = pa_init(start + len - PAGE_SIZE * 1);
+ const paddr_t recv_addr = pa_init(start + len - PAGE_SIZE * 2);
+
+ (void)ppool;
+
+ if (!plat_ffa_is_tee_enabled()) {
+ return;
+ }
+
+ CHECK(other_world_vm != NULL);
+
+ arch_ffa_init();
+
+ /*
+ * Call FFA_VERSION so the SPMC can store the hypervisor's
+ * version. This may be useful if there is a mismatch of
+ * versions.
+ */
+ ret = arch_other_world_call((struct ffa_value){
+ .func = FFA_VERSION_32, .arg1 = FFA_VERSION_COMPILED});
+ if (ret.func == (uint32_t)FFA_NOT_SUPPORTED) {
+ panic("Hypervisor and SPMC versions are not compatible.\n");
+ }
+
+ /*
+ * Setup TEE VM RX/TX buffers.
+ * Using the following hard-coded addresses, as they must be within the
+ * NS memory node in the SPMC manifest. From that region we should
+ * exclude the Hypervisor's address space to prevent SPs from using that
+ * memory in memory region nodes, or for the NWd to misuse that memory
+ * in runtime via memory sharing interfaces.
+ */
+
+ // NOLINTNEXTLINE(performance-no-int-to-ptr)
+ other_world_vm->mailbox.send = (void *)pa_addr(send_addr);
+ // NOLINTNEXTLINE(performance-no-int-to-ptr)
+ other_world_vm->mailbox.recv = (void *)pa_addr(recv_addr);
+
+ /*
+ * 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");
+ ffa_setup_rxtx_map_spmc(
+ pa_from_va(va_from_ptr(other_world_vm->mailbox.recv)),
+ pa_from_va(va_from_ptr(other_world_vm->mailbox.send)),
+ HF_MAILBOX_SIZE / FFA_PAGE_SIZE);
+
+ plat_ffa_set_tee_enabled(true);
+
+ /*
+ * Hypervisor will write to secure world receive buffer, and will read
+ * from the secure world send buffer.
+ *
+ * Mapping operation is necessary because the ranges are outside of the
+ * hypervisor's binary.
+ */
+ mm_stage1_locked = mm_lock_stage1();
+ CHECK(mm_identity_map(mm_stage1_locked, send_addr,
+ pa_add(send_addr, PAGE_SIZE),
+ MM_MODE_R | MM_MODE_SHARED, ppool) != NULL);
+ CHECK(mm_identity_map(
+ mm_stage1_locked, recv_addr, pa_add(recv_addr, PAGE_SIZE),
+ MM_MODE_R | MM_MODE_W | MM_MODE_SHARED, ppool) != NULL);
+ mm_unlock_stage1(&mm_stage1_locked);
+
+ dlog_verbose("TEE finished setting up buffers.\n");
+}
diff --git a/src/ffa/hypervisor/notifications.c b/src/ffa/hypervisor/notifications.c
index f03f378..82a42a8 100644
--- a/src/ffa/hypervisor/notifications.c
+++ b/src/ffa/hypervisor/notifications.c
@@ -10,12 +10,11 @@
#include "hf/arch/other_world.h"
+#include "hf/ffa/init.h"
#include "hf/ffa_internal.h"
#include "hf/std.h"
#include "hf/vm.h"
-#include "hypervisor.h"
-
/**
* Check validity of the calls:
* FFA_NOTIFICATION_BITMAP_CREATE/FFA_NOTIFICATION_BITMAP_DESTROY.
diff --git a/src/ffa/hypervisor/setup_and_discovery.c b/src/ffa/hypervisor/setup_and_discovery.c
index 74afa60..8c7c8e4 100644
--- a/src/ffa/hypervisor/setup_and_discovery.c
+++ b/src/ffa/hypervisor/setup_and_discovery.c
@@ -11,11 +11,11 @@
#include "hf/arch/other_world.h"
#include "hf/check.h"
+#include "hf/ffa/init.h"
#include "hf/ffa/vm.h"
#include "hf/manifest.h"
#include "hf/vm.h"
-#include "hypervisor.h"
#include "smc.h"
struct ffa_value ffa_setup_spmc_id_get(void)
diff --git a/src/ffa/spmc.c b/src/ffa/spmc.c
index ff69e29..3f4870c 100644
--- a/src/ffa/spmc.c
+++ b/src/ffa/spmc.c
@@ -21,19 +21,3 @@
#include "vmapi/hf/ffa.h"
#include "./spmc/vm.h"
-
-void plat_ffa_log_init(void)
-{
- dlog_info("Initializing Hafnium (SPMC)\n");
-}
-
-void plat_ffa_set_tee_enabled(bool tee_enabled)
-{
- (void)tee_enabled;
-}
-
-void plat_ffa_init(struct mpool *ppool)
-{
- arch_ffa_init();
- ffa_vm_init(ppool);
-}
diff --git a/src/ffa/spmc/init.c b/src/ffa/spmc/init.c
new file mode 100644
index 0000000..c32bbaf
--- /dev/null
+++ b/src/ffa/spmc/init.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2025 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.h"
+
+#include "hf/dlog.h"
+#include "hf/ffa/vm.h"
+#include "hf/mpool.h"
+
+void plat_ffa_log_init(void)
+{
+ dlog_info("Initializing Hafnium (SPMC)\n");
+}
+
+void plat_ffa_init(struct mpool *ppool)
+{
+ arch_ffa_init();
+ ffa_vm_init(ppool);
+}
+
+void plat_ffa_set_tee_enabled(bool tee_enabled)
+{
+ (void)tee_enabled;
+}
diff --git a/src/init.c b/src/init.c
index 957392d..e4362bf 100644
--- a/src/init.c
+++ b/src/init.c
@@ -19,6 +19,7 @@
#include "hf/dlog.h"
#include "hf/fdt_handler.h"
#include "hf/ffa.h"
+#include "hf/ffa/init.h"
#include "hf/load.h"
#include "hf/manifest.h"
#include "hf/mm.h"