feat(FF-A): implement FFA_SPM_ID_GET interface
If FFA_SPM_ID_GET is invoked at the secure virtual FF-A instance
(a secure partition) return the SPMC id. The SPMC id is queried by
the SPMC to the SPMD by calling FFA_ID_GET or by the Hypervisor to
the SPMD by calling FFA_SPM_ID_GET. Introduce plat_ffa module to
allow for the SPMC and hypervisor specific code.
Signed-off-by: Daniel Boulby <daniel.boulby@arm.com>
Change-Id: I892fa034ac00a1c0ada7ac13e9384a8c5ccfc507
diff --git a/inc/hf/api.h b/inc/hf/api.h
index 8af07ee..2714735 100644
--- a/inc/hf/api.h
+++ b/inc/hf/api.h
@@ -56,6 +56,7 @@
struct ffa_value api_ffa_partition_info_get(struct vcpu *current,
const struct ffa_uuid *uuid);
struct ffa_value api_ffa_id_get(const struct vcpu *current);
+struct ffa_value api_ffa_spm_id_get(void);
struct ffa_value api_ffa_features(uint32_t function_id);
struct ffa_value api_ffa_run(ffa_vm_id_t vm_id, ffa_vcpu_index_t vcpu_idx,
const struct vcpu *current, struct vcpu **next);
diff --git a/inc/hf/arch/ffa.h b/inc/hf/arch/ffa.h
new file mode 100644
index 0000000..1a6ae22
--- /dev/null
+++ b/inc/hf/arch/ffa.h
@@ -0,0 +1,14 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "hf/ffa.h"
+
+/** Returns the SPMC ID. */
+ffa_vm_id_t arch_ffa_spmc_id_get(void);
diff --git a/inc/hf/arch/plat/ffa.h b/inc/hf/arch/plat/ffa.h
new file mode 100644
index 0000000..19c8e45
--- /dev/null
+++ b/inc/hf/arch/plat/ffa.h
@@ -0,0 +1,14 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "hf/ffa.h"
+
+/** Returns the SPMC ID. */
+struct ffa_value plat_ffa_spmc_id_get(void);
diff --git a/inc/vmapi/hf/ffa.h b/inc/vmapi/hf/ffa.h
index 17c3ab6..25b1bf9 100644
--- a/inc/vmapi/hf/ffa.h
+++ b/inc/vmapi/hf/ffa.h
@@ -63,6 +63,7 @@
#define FFA_MEM_FRAG_TX_32 0x8400007B
#define FFA_SECONDARY_EP_REGISTER_32 0x84000084
#define FFA_SECONDARY_EP_REGISTER_64 0xC4000084
+#define FFA_SPM_ID_GET_32 0x84000085
/* FF-A error codes. */
#define FFA_NOT_SUPPORTED INT32_C(-1)
diff --git a/project/reference b/project/reference
index 16fc50e..0029f48 160000
--- a/project/reference
+++ b/project/reference
@@ -1 +1 @@
-Subproject commit 16fc50ea3fd7f2e53905c6a3628621fa6ade4c21
+Subproject commit 0029f4812915ee7bb3d3fbf1df3105a1547b1422
diff --git a/src/api.c b/src/api.c
index 38475a7..01c91b5 100644
--- a/src/api.c
+++ b/src/api.c
@@ -9,6 +9,7 @@
#include "hf/api.h"
#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"
@@ -436,6 +437,24 @@
}
/**
+ * Returns the ID of the SPMC.
+ */
+struct ffa_value api_ffa_spm_id_get(void)
+{
+ struct ffa_value ret = ffa_error(FFA_NOT_SUPPORTED);
+
+ if (MAKE_FFA_VERSION(1, 1) <= FFA_VERSION_COMPILED) {
+ /*
+ * Return the SPMC ID that was fetched during FF-A
+ * initialization.
+ */
+ ret = (struct ffa_value){.func = FFA_SUCCESS_32,
+ .arg2 = arch_ffa_spmc_id_get()};
+ }
+ return ret;
+}
+
+/**
* This function is called by the architecture-specific context switching
* function to indicate that register state for the given vCPU has been saved
* and can therefore be used by other pCPUs.
@@ -1692,6 +1711,11 @@
case FFA_MSG_SEND_DIRECT_REQ_64:
case FFA_MSG_SEND_DIRECT_REQ_32:
return (struct ffa_value){.func = FFA_SUCCESS_32};
+ /* FF-A v1.1 features. */
+ case FFA_SPM_ID_GET_32:
+ if (MAKE_FFA_VERSION(1, 1) <= FFA_VERSION_COMPILED) {
+ return (struct ffa_value){.func = FFA_SUCCESS_32};
+ }
default:
return ffa_error(FFA_NOT_SUPPORTED);
}
diff --git a/src/arch/aarch64/args.gni b/src/arch/aarch64/args.gni
index e51f164..f42d228 100644
--- a/src/arch/aarch64/args.gni
+++ b/src/arch/aarch64/args.gni
@@ -5,6 +5,9 @@
# https://opensource.org/licenses/BSD-3-Clause.
declare_args() {
+ # FF-A hooks to be used for the platform, specified as build target.
+ plat_ffa = "//src/arch/aarch64/plat/ffa:absent"
+
# PSCI hooks to be used for the platform, specified as build target.
plat_psci = "//src/arch/aarch64/plat/psci:hypervisor"
diff --git a/src/arch/aarch64/hypervisor/BUILD.gn b/src/arch/aarch64/hypervisor/BUILD.gn
index 3648cba..4473cd2 100644
--- a/src/arch/aarch64/hypervisor/BUILD.gn
+++ b/src/arch/aarch64/hypervisor/BUILD.gn
@@ -41,6 +41,7 @@
"cpu.c",
"debug_el1.c",
"feature_id.c",
+ "ffa.c",
"handler.c",
"perfmon.c",
"psci_handler.c",
@@ -52,6 +53,7 @@
"//src/arch/aarch64:arch",
"//src/arch/aarch64:entry",
"//src/arch/aarch64:smc",
+ plat_ffa,
plat_interrupts,
plat_prng,
plat_psci,
diff --git a/src/arch/aarch64/hypervisor/ffa.c b/src/arch/aarch64/hypervisor/ffa.c
new file mode 100644
index 0000000..33786cc
--- /dev/null
+++ b/src/arch/aarch64/hypervisor/ffa.c
@@ -0,0 +1,31 @@
+/*
+ * 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/plat/ffa.h"
+
+#include "hf/ffa.h"
+#include "hf/panic.h"
+#include "hf/vm_ids.h"
+
+/**
+ * Returns the SPMC ID returned from the SPMD.
+ */
+ffa_vm_id_t arch_ffa_spmc_id_get(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) {
+ panic("Failed to get SPMC ID\n");
+ }
+
+ return HF_SPMC_VM_ID;
+}
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index cd98722..fc82b1b 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -473,6 +473,9 @@
case FFA_ID_GET_32:
*args = api_ffa_id_get(current);
return true;
+ case FFA_SPM_ID_GET_32:
+ *args = api_ffa_spm_id_get();
+ return true;
case FFA_FEATURES_32:
*args = api_ffa_features(args->arg1);
return true;
diff --git a/src/arch/aarch64/plat/ffa/BUILD.gn b/src/arch/aarch64/plat/ffa/BUILD.gn
new file mode 100644
index 0000000..8b278fd
--- /dev/null
+++ b/src/arch/aarch64/plat/ffa/BUILD.gn
@@ -0,0 +1,27 @@
+# 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.
+
+import("//build/toolchain/platform.gni")
+
+source_set("absent") {
+ sources = [
+ "absent.c",
+ ]
+}
+
+source_set("hypervisor") {
+ public_configs = [ "//src/arch/${plat_arch}:config" ]
+ sources = [
+ "hypervisor.c",
+ ]
+}
+
+source_set("spmc") {
+ public_configs = [ "//src/arch/${plat_arch}:config" ]
+ sources = [
+ "spmc.c",
+ ]
+}
diff --git a/src/arch/aarch64/plat/ffa/absent.c b/src/arch/aarch64/plat/ffa/absent.c
new file mode 100644
index 0000000..141e97e
--- /dev/null
+++ b/src/arch/aarch64/plat/ffa/absent.c
@@ -0,0 +1,15 @@
+/*
+ * 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/ffa.h"
+
+struct ffa_value plat_ffa_spmc_id_get(void)
+{
+ return (struct ffa_value){.func = FFA_ERROR_32,
+ .arg2 = FFA_NOT_SUPPORTED};
+}
diff --git a/src/arch/aarch64/plat/ffa/hypervisor.c b/src/arch/aarch64/plat/ffa/hypervisor.c
new file mode 100644
index 0000000..9bdf0ab
--- /dev/null
+++ b/src/arch/aarch64/plat/ffa/hypervisor.c
@@ -0,0 +1,17 @@
+/*
+ * 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/ffa.h"
+
+#include "smc.h"
+
+struct ffa_value plat_ffa_spmc_id_get(void)
+{
+ /* Fetch the SPMC ID from the SPMD using FFA_SPM_ID_GET. */
+ return smc_ffa_call((struct ffa_value){.func = FFA_SPM_ID_GET_32});
+}
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
new file mode 100644
index 0000000..8cd65c4
--- /dev/null
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -0,0 +1,20 @@
+/*
+ * 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/ffa.h"
+
+#include "smc.h"
+
+struct ffa_value plat_ffa_spmc_id_get(void)
+{
+ /*
+ * Since we are running in the SPMC use FFA_ID_GET to fetch our
+ * ID from the SPMD.
+ */
+ return smc_ffa_call((struct ffa_value){.func = FFA_ID_GET_32});
+}
diff --git a/src/arch/fake/hypervisor/BUILD.gn b/src/arch/fake/hypervisor/BUILD.gn
index 8f28802..4c6f2c2 100644
--- a/src/arch/fake/hypervisor/BUILD.gn
+++ b/src/arch/fake/hypervisor/BUILD.gn
@@ -7,6 +7,7 @@
source_set("hypervisor") {
sources = [
"cpu.c",
+ "ffa.c",
"vm.c",
]
deps = [
diff --git a/src/arch/fake/hypervisor/ffa.c b/src/arch/fake/hypervisor/ffa.c
new file mode 100644
index 0000000..08183e8
--- /dev/null
+++ b/src/arch/fake/hypervisor/ffa.c
@@ -0,0 +1,16 @@
+/*
+ * 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/ffa.h"
+
+#include "hf/vm_ids.h"
+
+ffa_vm_id_t arch_ffa_spmc_id_get(void)
+{
+ return HF_SPMC_VM_ID;
+}