72 lines
2.1 KiB
Diff
72 lines
2.1 KiB
Diff
From 9da48e3433b919868650cd60e28827273a42c63b Mon Sep 17 00:00:00 2001
|
|
From: Jaxson Han <jaxson.han@arm.com>
|
|
Date: Tue, 25 Jan 2022 14:56:36 +0800
|
|
Subject: [PATCH] PSCI: Add function call entry point
|
|
|
|
The max exception level of Armv8R AArch64 is EL2, which means it has no
|
|
exclusive EL for firmware. That is, firmware and hypervisors have to share
|
|
the EL2. Also, hypervisors cannot call firmware services via a 'smc'
|
|
instruction. Thus, boot-wrapper has to provide a function entry point
|
|
for Armv8R AArch64.
|
|
|
|
Issue-Id: SCM-3816
|
|
Upstream-Status: Inappropriate [other]
|
|
Implementation pending further discussion
|
|
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
|
Change-Id: I06ec8e50298603155c6d8ae2330e71db2f111182
|
|
---
|
|
common/psci.c | 24 ++++++++++++++++++++----
|
|
1 file changed, 20 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/common/psci.c b/common/psci.c
|
|
index 6efc695..8fdefb5 100644
|
|
--- a/common/psci.c
|
|
+++ b/common/psci.c
|
|
@@ -20,6 +20,8 @@
|
|
|
|
extern unsigned int spsr_to_elx;
|
|
|
|
+unsigned long flag_from_smc_fn[NR_CPUS];
|
|
+
|
|
static unsigned long branch_table[NR_CPUS];
|
|
|
|
bakery_ticket_t branch_table_lock[NR_CPUS];
|
|
@@ -49,12 +51,14 @@ static int psci_cpu_on(unsigned long target_mpidr, unsigned long address)
|
|
return PSCI_RET_INVALID_PARAMETERS;
|
|
|
|
bakery_lock(branch_table_lock, this_cpu);
|
|
- ret = psci_store_address(cpu, address);
|
|
- bakery_unlock(branch_table_lock, this_cpu);
|
|
-
|
|
#ifdef KEEP_EL
|
|
- spsr_to_elx = SPSR_KERNEL_EL1;
|
|
+ if (!flag_from_smc_fn[this_cpu]) {
|
|
+ spsr_to_elx = SPSR_KERNEL_EL1;
|
|
+ flush_per_cpu_data((void*)&(spsr_to_elx));
|
|
+ }
|
|
#endif
|
|
+ ret = psci_store_address(cpu, address);
|
|
+ bakery_unlock(branch_table_lock, this_cpu);
|
|
|
|
return ret;
|
|
}
|
|
@@ -90,6 +94,18 @@ long psci_call(unsigned long fid, unsigned long arg1, unsigned long arg2)
|
|
}
|
|
}
|
|
|
|
+long smc_fn_entry(unsigned long fid, unsigned long arg1, unsigned long arg2)
|
|
+{
|
|
+ long ret;
|
|
+ unsigned int this_cpu = this_cpu_logical_id();
|
|
+
|
|
+ flag_from_smc_fn[this_cpu] = 1;
|
|
+ ret = psci_call(fid, arg1, arg2);
|
|
+ flag_from_smc_fn[this_cpu] = 0;
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
void __noreturn psci_first_spin(unsigned int cpu)
|
|
{
|
|
if (cpu == MPIDR_INVALID)
|