aarch64: create an SPMC boot flow
Create an SPMC boot flow and skip initialization of a primary VM
in the secure world (SPMC). The PVM initialization remains in the
normal world (Hypervisor). Secure Partitions share same properties
as secondary VMs in the NWd.
Change-Id: Ic9d0c407ae1413eaecd4427b02bcb15d02374e02
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/src/arch/aarch64/hypervisor/cpu.c b/src/arch/aarch64/hypervisor/cpu.c
index 0f6710e0..a59b055 100644
--- a/src/arch/aarch64/hypervisor/cpu.c
+++ b/src/arch/aarch64/hypervisor/cpu.c
@@ -65,11 +65,7 @@
{
ffa_vm_id_t vm_id = vcpu->vm->id;
bool is_primary = vm_id == HF_PRIMARY_VM_ID;
-#if SECURE_WORLD == 0
cpu_id_t vcpu_id = is_primary ? vcpu->cpu->id : vcpu_index(vcpu);
-#else
- cpu_id_t vcpu_id = vcpu_index(vcpu);
-#endif
paddr_t table = vcpu->vm->ptable.root;
struct arch_regs *r = &vcpu->regs;
diff --git a/src/boot_flow/BUILD.gn b/src/boot_flow/BUILD.gn
index 884c22d..5f44f11 100644
--- a/src/boot_flow/BUILD.gn
+++ b/src/boot_flow/BUILD.gn
@@ -40,3 +40,13 @@
"//src/arch/${plat_arch}/boot_flow:linux",
]
}
+
+source_set("spmc") {
+ sources = [
+ "spmc.c",
+ ]
+ deps = [
+ ":common",
+ "//src/arch/${plat_arch}/boot_flow:linux",
+ ]
+}
diff --git a/src/boot_flow/spmc.c b/src/boot_flow/spmc.c
new file mode 100644
index 0000000..3f29eca
--- /dev/null
+++ b/src/boot_flow/spmc.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2020 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/plat/boot_flow.h"
+#include "hf/std.h"
+
+/* Set by arch-specific boot-time hook. */
+uintreg_t plat_boot_flow_fdt_addr;
+
+/**
+ * Returns the physical address of SPMC manifest FDT blob. This was passed to
+ * SPMC cold boot entry by the SPMD.
+ */
+paddr_t plat_boot_flow_get_fdt_addr(void)
+{
+ return pa_init((uintpaddr_t)plat_boot_flow_fdt_addr);
+}
+
+/**
+ * The value returned by this function is not meaningful in context of the SPMC
+ * as there is no primary VM.
+ */
+uintreg_t plat_boot_flow_get_kernel_arg(void)
+{
+ return 0;
+}
+
+/**
+ * The value returned by this function is not meaningful in context of the SPMC
+ * as there is no initrd.
+ */
+bool plat_boot_flow_get_initrd_range(const struct fdt *fdt, paddr_t *begin,
+ paddr_t *end)
+{
+ (void)fdt;
+ (void)begin;
+ (void)end;
+
+ return true;
+}
+
+/**
+ * This wrapper is unused in context of the SPMC.
+ */
+bool plat_boot_flow_update(struct mm_stage1_locked stage1_locked,
+ const struct manifest *manifest,
+ struct boot_params_update *update,
+ struct memiter *cpio, struct mpool *ppool)
+{
+ (void)stage1_locked;
+ (void)manifest;
+ (void)update;
+ (void)cpio;
+ (void)ppool;
+
+ return true;
+}
diff --git a/src/manifest.c b/src/manifest.c
index ab61b12..0425f68 100644
--- a/src/manifest.c
+++ b/src/manifest.c
@@ -810,7 +810,7 @@
}
}
- if (!found_primary_vm) {
+ if (!found_primary_vm && vm_id_is_current_world(HF_PRIMARY_VM_ID)) {
return MANIFEST_ERROR_NO_PRIMARY_VM;
}