1
0
mirror of https://git.yoctoproject.org/meta-arm synced 2026-05-07 04:58:57 +00:00

arm-bsp/tc0: update Hafnium to 2.5

Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: I2da38cff515cb543a31c7d8e2c50b51ff94ca8d3
Signed-off-by: Jon Mason <jon.mason@arm.com>
This commit is contained in:
Arunachalam Ganapathy
2021-07-22 12:32:49 +01:00
committed by Jon Mason
parent 001668e2ac
commit c17dfab3aa
6 changed files with 0 additions and 529 deletions
@@ -1,276 +0,0 @@
Upstream-Status: Pending [https://review.trustedfirmware.org/c/hafnium/hafnium/+/6009/27]
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
From 06e7602ddb383e0f88c19feaa216c24cf032a136 Mon Sep 17 00:00:00 2001
From: Max Shvetsov <maksims.svecovs@arm.com>
Date: Thu, 27 Aug 2020 12:37:57 +0100
Subject: [PATCH 2/5] FF-A: Register secondary core entry point at SPMC init.
When the primary physical core boots the SPMC registers its secondary
physical core entry points to the SPMD. All Secure Partition are then
initialized on their primary Execution Contexts. A Secure Partition
calls PSCI_CPU_ON from its first EC (trapped to the SPMC) passing
entry point addresses of secondary ECs. ECs are turned "on" in their
SPMC internal states, although they do not run yet (the service call
does not reach the EL3 PSCI layer). Later, when the NWd (Hypervisor
or OS Kernel) boots, it calls PSCI_CPU_ON for waking up physical cores
down to EL3. The PSCI layer calls into SPMD PM hooks, then the SPMD
calls into the SPMC by an exception return to the registered secondary
entry point. The target secondary core then reaches Hafnium vcpu_main.
Change-Id: I2bd42ea54e1a7feebff20e878345ec196ff352e9
Signed-off-by: Max Shvetsov <maksims.svecovs@arm.com>
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
---
inc/hf/arch/init.h | 7 ++++
inc/hf/arch/other_world.h | 2 ++
src/arch/aarch64/hypervisor/other_world.c | 29 +++++++++++++++
src/arch/aarch64/hypervisor/psci_handler.c | 40 +++++++++++++++++++++
src/arch/aarch64/inc/hf/arch/spmd_helpers.h | 15 ++++++++
src/cpu.c | 2 +-
src/init.c | 2 ++
src/load.c | 3 ++
src/main.c | 12 ++++---
9 files changed, 106 insertions(+), 6 deletions(-)
create mode 100644 src/arch/aarch64/inc/hf/arch/spmd_helpers.h
diff --git a/inc/hf/arch/init.h b/inc/hf/arch/init.h
index 5205e4e..ef0e48f 100644
--- a/inc/hf/arch/init.h
+++ b/inc/hf/arch/init.h
@@ -8,6 +8,8 @@
#pragma once
+#include "hf/boot_params.h"
+
/**
* Performs arch specific boot time initialization.
*
@@ -15,3 +17,8 @@
* possible.
*/
void arch_one_time_init(void);
+
+/**
+ * Sets up secondary cores.
+ */
+void arch_psci_secondary_core_init(const struct boot_params *params);
diff --git a/inc/hf/arch/other_world.h b/inc/hf/arch/other_world.h
index 68c0b45..860a142 100644
--- a/inc/hf/arch/other_world.h
+++ b/inc/hf/arch/other_world.h
@@ -20,3 +20,5 @@ bool arch_other_world_is_direct_request_valid(struct vcpu *current,
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 arch_other_world_init_ffa_id(void);
+ffa_vm_id_t arch_other_world_get_ffa_id(void);
diff --git a/src/arch/aarch64/hypervisor/other_world.c b/src/arch/aarch64/hypervisor/other_world.c
index 74a2bb1..6b5bb16 100644
--- a/src/arch/aarch64/hypervisor/other_world.c
+++ b/src/arch/aarch64/hypervisor/other_world.c
@@ -23,6 +23,10 @@
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];
+#else
+
+static ffa_vm_id_t physical_ffa_id;
+
#endif
void arch_other_world_init(void)
@@ -181,3 +185,28 @@ struct ffa_value arch_other_world_call(struct ffa_value args)
{
return smc_ffa_call(args);
}
+
+#if SECURE_WORLD == 1
+
+ffa_vm_id_t arch_other_world_get_ffa_id(void)
+{
+ return physical_ffa_id;
+}
+
+void arch_other_world_init_ffa_id(void)
+{
+ struct ffa_value res =
+ smc_ffa_call((struct ffa_value){.func = FFA_ID_GET_32});
+
+ if (res.func != FFA_SUCCESS_32) {
+ dlog_error("%s Failed to get SPMC's FFA-ID from SPMD.\n",
+ __func__);
+ physical_ffa_id = HF_INVALID_VM_ID;
+ return;
+ }
+ physical_ffa_id = res.arg2 & 0xFFFF;
+
+ CHECK(physical_ffa_id == HF_TEE_VM_ID);
+}
+
+#endif
diff --git a/src/arch/aarch64/hypervisor/psci_handler.c b/src/arch/aarch64/hypervisor/psci_handler.c
index f89a00b..b323faa 100644
--- a/src/arch/aarch64/hypervisor/psci_handler.c
+++ b/src/arch/aarch64/hypervisor/psci_handler.c
@@ -10,10 +10,13 @@
#include <stdint.h>
+#include "hf/arch/other_world.h"
#include "hf/arch/plat/psci.h"
+#include "hf/arch/spmd_helpers.h"
#include "hf/arch/types.h"
#include "hf/api.h"
+#include "hf/boot_params.h"
#include "hf/cpu.h"
#include "hf/dlog.h"
#include "hf/ffa.h"
@@ -53,6 +56,41 @@ void arch_one_time_init(void)
}
#else
el3_psci_version = PSCI_VERSION_1_1;
+
+ arch_other_world_init_ffa_id();
+#endif
+}
+
+/**
+ * Register secondary physical core entry points to the SPMD.
+ */
+void arch_psci_secondary_core_init(const struct boot_params *params)
+{
+#if SECURE_WORLD == 1
+ struct ffa_value res;
+
+ for (uint32_t count = 0; count < params->cpu_count; count++) {
+ uint32_t id = params->cpu_ids[count];
+ struct cpu *cpu = cpu_find(id);
+ const ffa_vm_id_t ffa_id = arch_other_world_get_ffa_id();
+
+ res = smc_ffa_call((struct ffa_value){
+ .func = FFA_MSG_SEND_DIRECT_REQ_32,
+ .arg1 = ((uint64_t)ffa_id << 16) | SPMD_ID,
+ .arg3 = SPMD_DIRECT_MSG_SET_ENTRY_POINT,
+ .arg4 = params->cpu_ids[count],
+ .arg5 = (uintreg_t)&cpu_entry,
+ .arg6 = (uintreg_t)cpu});
+
+ if (res.func != FFA_SUCCESS_32) {
+ dlog_warning(
+ "%s Failed to initialize secondary core ID: "
+ "%u\n",
+ __func__, id);
+ }
+
+ dlog_verbose("SPMD EP register returned %#x\n", res.func);
+ }
#endif
}
@@ -353,11 +391,13 @@ bool psci_secondary_vm_handler(struct vcpu *vcpu, uint32_t func, uintreg_t arg0,
if (vcpu_secondary_reset_and_start(
target_vcpu, entry_point_address, context_id)) {
+#if SECURE_WORLD == 0
/*
* Tell the scheduler that it can start running the new
* vCPU now.
*/
*next = api_wake_up(vcpu, target_vcpu);
+#endif
*ret = PSCI_RETURN_SUCCESS;
} else {
*ret = PSCI_ERROR_ALREADY_ON;
diff --git a/src/arch/aarch64/inc/hf/arch/spmd_helpers.h b/src/arch/aarch64/inc/hf/arch/spmd_helpers.h
new file mode 100644
index 0000000..6e11c36
--- /dev/null
+++ b/src/arch/aarch64/inc/hf/arch/spmd_helpers.h
@@ -0,0 +1,15 @@
+/*
+ * 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.
+ */
+
+#define SPMD_ID 0xFFFF
+#define SPMD_DIRECT_MSG_SET_ENTRY_POINT 1
+
+/**
+ * Get SPMC ID stored in the manifest.
+ */
+ffa_vm_id_t get_ffa_id(void);
diff --git a/src/cpu.c b/src/cpu.c
index 0a3fc6f..0e0ee9a 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -138,7 +138,7 @@ bool cpu_on(struct cpu *c, ipaddr_t entry, uintreg_t arg)
c->is_on = true;
sl_unlock(&c->lock);
- if (!prev) {
+ if (!prev && vm_id_is_current_world(HF_PRIMARY_VM_ID)) {
struct vm *vm = vm_find(HF_PRIMARY_VM_ID);
struct vcpu *vcpu = vm_get_vcpu(vm, cpu_index(c));
struct vcpu_locked vcpu_locked;
diff --git a/src/init.c b/src/init.c
index a5b48ab..0121213 100644
--- a/src/init.c
+++ b/src/init.c
@@ -146,6 +146,8 @@ void one_time_init(void)
cpu_module_init(params.cpu_ids, params.cpu_count);
+ arch_psci_secondary_core_init(&params);
+
/* Load all VMs. */
update.reserved_ranges_count = 0;
if (!load_vms(mm_stage1_locked, &manifest, &cpio, &params, &update,
diff --git a/src/load.c b/src/load.c
index 660d77c..7accc65 100644
--- a/src/load.c
+++ b/src/load.c
@@ -286,6 +286,9 @@ static bool load_primary(struct mm_stage1_locked stage1_locked,
dlog_info("Loaded primary VM with %u vCPUs, entry at %#x.\n",
vm->vcpu_count, pa_addr(primary_begin));
+ /* Mark the primary to be the first booted VM */
+ vm_update_boot(vm);
+
vcpu_locked = vcpu_lock(vm_get_vcpu(vm, 0));
vcpu_on(vcpu_locked, primary_entry, params->kernel_arg);
vcpu_unlock(&vcpu_locked);
diff --git a/src/main.c b/src/main.c
index 5f30aac..3cc932e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -15,14 +15,16 @@
*/
struct vcpu *cpu_main(struct cpu *c)
{
+ struct vm *first_boot;
struct vcpu *vcpu;
-#if SECURE_WORLD == 1
- struct vm *first_boot = vm_get_first_boot();
+
+ /*
+ * This returns the PVM in the normal worls and the first
+ * booted Secure Partition in the secure world.
+ */
+ first_boot = vm_get_first_boot();
vcpu = vm_get_vcpu(first_boot, cpu_index(c));
-#else
- vcpu = vm_get_vcpu(vm_find(HF_PRIMARY_VM_ID), cpu_index(c));
-#endif
vcpu->cpu = c;
--
2.29.2
@@ -1,95 +0,0 @@
Upstream-Status: Pending [https://review.trustedfirmware.org/c/hafnium/hafnium/+/6010/29]
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
From ebd568637627fa895e6e7f479675c650414cc240 Mon Sep 17 00:00:00 2001
From: Max Shvetsov <maksims.svecovs@arm.com>
Date: Thu, 27 Aug 2020 12:39:50 +0100
Subject: [PATCH 3/5] FF-A: Cold boot and wake up from suspend.
WIP: Currently there is zero entry-point passed with no arguments, This
will be reworked once a proper way to pass this information will be
defined.
Change-Id: Ic6050af16d4081ca31729744995fbb999b170e11
Signed-off-by: Max Shvetsov <maksims.svecovs@arm.com>
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
---
inc/hf/vcpu.h | 2 ++
src/arch/aarch64/hypervisor/psci_handler.c | 2 ++
src/main.c | 20 ++++++++++++++++++++
3 files changed, 24 insertions(+)
diff --git a/inc/hf/vcpu.h b/inc/hf/vcpu.h
index 5439719..98f3a50 100644
--- a/inc/hf/vcpu.h
+++ b/inc/hf/vcpu.h
@@ -86,6 +86,8 @@ struct vcpu {
* a result of a prior FFA_MSG_SEND_DIRECT_REQ invocation.
*/
ffa_vm_id_t direct_request_origin_vm_id;
+
+ ipaddr_t psci_handler[1];
};
/** Encapsulates a vCPU whose lock is held. */
diff --git a/src/arch/aarch64/hypervisor/psci_handler.c b/src/arch/aarch64/hypervisor/psci_handler.c
index b323faa..c892385 100644
--- a/src/arch/aarch64/hypervisor/psci_handler.c
+++ b/src/arch/aarch64/hypervisor/psci_handler.c
@@ -389,6 +389,8 @@ bool psci_secondary_vm_handler(struct vcpu *vcpu, uint32_t func, uintreg_t arg0,
target_vcpu = vm_get_vcpu(vm, target_vcpu_index);
+ target_vcpu->psci_handler[0] = entry_point_address;
+
if (vcpu_secondary_reset_and_start(
target_vcpu, entry_point_address, context_id)) {
#if SECURE_WORLD == 0
diff --git a/src/main.c b/src/main.c
index 3cc932e..2c3d1a5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -7,6 +7,7 @@
*/
#include "hf/cpu.h"
+#include "hf/dlog.h"
#include "hf/vm.h"
/**
@@ -18,6 +19,18 @@ struct vcpu *cpu_main(struct cpu *c)
struct vm *first_boot;
struct vcpu *vcpu;
+#if SECURE_WORLD == 1
+ if (c->is_on == false) {
+ /*
+ * This is the PSCI warm reset path (svc_cpu_on_finish
+ * handler relayed by SPMD). Notice currenty the "first_boot"
+ * VM is resumed on any CPU on event.
+ */
+ (void)cpu_on(c, ipa_init(0UL), 0UL);
+ dlog_verbose("%s: cpu mpidr 0x%x on\n", __func__, c->id);
+ }
+#endif
+
/*
* This returns the PVM in the normal worls and the first
* booted Secure Partition in the secure world.
@@ -26,6 +39,13 @@ struct vcpu *cpu_main(struct cpu *c)
vcpu = vm_get_vcpu(first_boot, cpu_index(c));
+ if (vcpu->psci_handler[0].ipa) {
+ struct vcpu_locked vcpu_locked = vcpu_lock(vcpu);
+
+ vcpu_on(vcpu_locked, vcpu->psci_handler[0], 0);
+ vcpu_unlock(&vcpu_locked);
+ }
+
vcpu->cpu = c;
arch_cpu_init();
--
2.29.2
@@ -1,115 +0,0 @@
Upstream-Status: Pending [https://review.trustedfirmware.org/c/hafnium/hafnium/+/6011/29]
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
From 6a836b380265876a12b2edfb7f013523af89e754 Mon Sep 17 00:00:00 2001
From: Max Shvetsov <maksims.svecovs@arm.com>
Date: Fri, 18 Sep 2020 13:52:20 +0100
Subject: [PATCH 4/5] FF-A: Respond to PSCI_CPU_OFF from SPMD.
At run-time when a PSCI call is made from NWd, the corresponding SPMD PM
hooks gets called and is eventually routed to the SPMC. This change
implements a generic "SPMD handler" processing PM events that may be
conveyed from SPMD to SPMC such as core suspend, core off.
Change-Id: Id288e26d9fbb8328acc71f5cf68c39e095a0e3da
Signed-off-by: Max Shvetsov <maksims.svecovs@arm.com>
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
---
src/arch/aarch64/hypervisor/handler.c | 49 +++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 2 deletions(-)
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index b33298c..43a1404 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -13,6 +13,7 @@
#include "hf/arch/mmu.h"
#include "hf/arch/other_world.h"
#include "hf/arch/plat/smc.h"
+#include "hf/arch/spmd_helpers.h"
#include "hf/api.h"
#include "hf/check.h"
@@ -261,6 +262,7 @@ static void set_virtual_interrupt_current(bool enable)
}
#if SECURE_WORLD == 1
+
static bool sp_boot_next(struct vcpu *current, struct vcpu **next,
struct ffa_value *ffa_ret)
{
@@ -303,6 +305,41 @@ out:
vm_unlock(&current_vm_locked);
return ret;
}
+
+/**
+ * Handle special direct messages from SPMD to SPMC. For now related to power
+ * management only.
+ */
+static bool spmd_handler(struct ffa_value *args, struct vcpu *current)
+{
+ ffa_vm_id_t spmc_ffa_id = arch_other_world_get_ffa_id();
+ ffa_vm_id_t sender = ffa_msg_send_sender(*args);
+ ffa_vm_id_t receiver = ffa_msg_send_receiver(*args);
+ ffa_vm_id_t current_vm_id = current->vm->id;
+
+ if (!((sender == SPMD_ID) && (receiver == spmc_ffa_id) &&
+ (current_vm_id == HF_OTHER_WORLD_ID))) {
+ return false;
+ }
+
+ switch (args->arg3) {
+ case PSCI_CPU_OFF:
+ dlog_verbose("%s cpu off notification\n", __func__);
+ args->func = FFA_MSG_SEND_DIRECT_RESP_32;
+ args->arg1 = ((uint64_t)spmc_ffa_id << 16) | SPMD_ID;
+ args->arg2 = 0U;
+
+ cpu_off(current->cpu);
+ break;
+ default:
+ dlog_verbose("%s message not handled %#x\n", __func__,
+ args->arg3);
+ return false;
+ }
+
+ return true;
+}
+
#endif
/**
@@ -461,11 +498,17 @@ static bool ffa_handler(struct ffa_value *args, struct vcpu *current,
(args->arg4 >> 16) & 0xffff,
current);
return true;
- case FFA_MSG_SEND_DIRECT_REQ_32:
+ case FFA_MSG_SEND_DIRECT_REQ_32: {
+#if SECURE_WORLD == 1
+ if (spmd_handler(args, current)) {
+ return true;
+ }
+#endif
*args = api_ffa_msg_send_direct_req(
ffa_msg_send_sender(*args),
ffa_msg_send_receiver(*args), *args, current, next);
return true;
+ }
case FFA_MSG_SEND_DIRECT_RESP_32:
*args = api_ffa_msg_send_direct_resp(
ffa_msg_send_sender(*args),
@@ -510,7 +553,9 @@ static void other_world_switch_loop(struct vcpu *other_world_vcpu,
* the result of the call back to EL3 unless the API handler
* sets *next to something different.
*/
- if (!ffa_handler(&other_world_args, other_world_vcpu, next)) {
+
+ if (!spmd_handler(&other_world_args, other_world_vcpu) &&
+ !ffa_handler(&other_world_args, other_world_vcpu, next)) {
other_world_args.func = SMCCC_ERROR_UNKNOWN;
}
}
--
2.29.2
@@ -1,30 +0,0 @@
From e8042fda56aa470cdda723757a957a81cd95dde8 Mon Sep 17 00:00:00 2001
From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Date: Tue, 2 Feb 2021 12:12:32 +0000
Subject: [PATCH] tc0: Add Theodul DSU support
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Upstream-Status: Pending [Not submitted to upstream yet]
Change-Id: I4a9b7e4350410fdacccd8c12ff03a61b7e64e98b
---
project/reference/BUILD.gn | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/project/reference/BUILD.gn b/project/reference/BUILD.gn
index 5596009..ffcaab7 100644
--- a/project/reference/BUILD.gn
+++ b/project/reference/BUILD.gn
@@ -159,8 +159,8 @@ aarch64_toolchains("secure_tc0") {
gic_version = 3
gicd_base_address = "0x30000000"
gicr_base_address = "0x30140000"
- heap_pages = 60
- max_cpus = 4
+ heap_pages = 80
+ max_cpus = 8
max_vms = 16
toolchain_args = {
secure_world = "1"
--
2.29.2
@@ -1,18 +1,5 @@
# TC0 specific configuration
# Intermediate SHA with 2.4 baseline version, required for OP-TEE SEL1 support
SRCREV = "fe7f737ec20add15d49c587ebeb55f7ea0118226"
PV = "2.4+git${SRCPV}"
FILESEXTRAPATHS_prepend_tc0 := "${THISDIR}/files/tc0:"
SRC_URI_append = " \
file://0001-FF-A-Register-secondary-core-entry-point-at-SPMC-ini.patch \
file://0002-FF-A-Cold-boot-and-wake-up-from-suspend.patch \
file://0003-FF-A-Respond-to-PSCI_CPU_OFF-from-SPMD.patch \
file://0004-tc0-Add-Theodul-DSU-support.patch \
"
COMPATIBLE_MACHINE = "tc0"
HAFNIUM_PROJECT = "reference"