feat(FF-A): create ffa_init to prefetch the SPMC ID
Prefetch the SPMC ID to prevent unnecessary SMC calls. Also group
SPMC initialization code into an arch specific initialization file.
Signed-off-by: Daniel Boulby <daniel.boulby@arm.com>
Change-Id: I0be0be95a8eea9d39eaf8b5ddc3600bcc7d66ebe
diff --git a/src/arch/aarch64/hypervisor/BUILD.gn b/src/arch/aarch64/hypervisor/BUILD.gn
index 4473cd2..4a366fa 100644
--- a/src/arch/aarch64/hypervisor/BUILD.gn
+++ b/src/arch/aarch64/hypervisor/BUILD.gn
@@ -38,6 +38,7 @@
]
sources += [
+ "arch_init.c",
"cpu.c",
"debug_el1.c",
"feature_id.c",
diff --git a/src/arch/aarch64/hypervisor/arch_init.c b/src/arch/aarch64/hypervisor/arch_init.c
new file mode 100644
index 0000000..bcadd60
--- /dev/null
+++ b/src/arch/aarch64/hypervisor/arch_init.c
@@ -0,0 +1,19 @@
+/*
+ * 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.h"
+#include "hf/arch/plat/psci.h"
+
+/**
+ * Performs arch specific boot time initialization.
+ */
+void arch_one_time_init(void)
+{
+ plat_psci_init();
+ arch_ffa_init();
+}
diff --git a/src/arch/aarch64/hypervisor/ffa.c b/src/arch/aarch64/hypervisor/ffa.c
index 33786cc..e036659 100644
--- a/src/arch/aarch64/hypervisor/ffa.c
+++ b/src/arch/aarch64/hypervisor/ffa.c
@@ -8,24 +8,41 @@
#include "hf/arch/plat/ffa.h"
+#include "hf/check.h"
#include "hf/ffa.h"
#include "hf/panic.h"
#include "hf/vm_ids.h"
+static ffa_vm_id_t spmc_id = HF_INVALID_VM_ID;
+
/**
* Returns the SPMC ID returned from the SPMD.
*/
ffa_vm_id_t arch_ffa_spmc_id_get(void)
{
+ return spmc_id;
+}
+
+/**
+ * Initialize the platform FF-A module in the context of running the SPMC.
+ * In particular it fetches the SPMC ID to prevent SMC calls everytime
+ * FFA_SPM_ID_GET is invoked.
+ */
+void arch_ffa_init(void)
+{
struct ffa_value ret = plat_ffa_spmc_id_get();
if (ret.func == FFA_SUCCESS_32) {
- return (ffa_vm_id_t)ret.arg2;
- }
- if (ret.func == FFA_ERROR_32 &&
- ffa_error_code(ret) != FFA_NOT_SUPPORTED) {
+ spmc_id = ret.arg2;
+ } else if (ret.func == FFA_ERROR_32 &&
+ ffa_error_code(ret) == FFA_NOT_SUPPORTED) {
+ spmc_id = HF_SPMC_VM_ID;
+ } else {
panic("Failed to get SPMC ID\n");
}
- return HF_SPMC_VM_ID;
+ /*
+ * Check that spmc_id is equal to HF_SPMC_VM_ID.
+ */
+ CHECK(spmc_id == HF_SPMC_VM_ID);
}
diff --git a/src/arch/aarch64/hypervisor/psci_handler.c b/src/arch/aarch64/hypervisor/psci_handler.c
index 358c827..3c78e57 100644
--- a/src/arch/aarch64/hypervisor/psci_handler.c
+++ b/src/arch/aarch64/hypervisor/psci_handler.c
@@ -24,12 +24,6 @@
void cpu_entry(struct cpu *c);
-/* Performs arch specific boot time initialisation. */
-void arch_one_time_init(void)
-{
- plat_psci_init();
-}
-
/**
* Handles PSCI requests received via HVC or SMC instructions from the primary
* VM.