From: Mirela Simonovic <mirela.simonovic@aggios.com>
PSCI system suspend function shall be invoked to finalize Xen suspend
procedure. Resume entry point, which needs to be passed via 1st argument
of PSCI system suspend call to the EL3, is hyp_resume. For now, hyp_resume
is just a placeholder that will be implemented in assembly. Context ID,
which is 2nd argument of system suspend PSCI call, is unused, as in Linux.
Signed-off-by: Mirela Simonovic <mirela.simonovic@aggios.com>
Signed-off-by: Saeed Nowshadi <saeed.nowshadi@xilinx.com>
Signed-off-by: Mykyta Poturai <mykyta_poturai@epam.com>
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
---
Changes introduced in v3:
- return PSCI_NOT_SUPPORTED instead of 1 for arm32
- add checking of PSCI version for psci suspend call
---
xen/arch/arm/arm64/head.S | 8 ++++++++
xen/arch/arm/include/asm/psci.h | 1 +
xen/arch/arm/include/asm/suspend.h | 1 +
xen/arch/arm/psci.c | 19 +++++++++++++++++++
xen/arch/arm/suspend.c | 4 ++++
5 files changed, 33 insertions(+)
diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S
index 72c7b24498..3522c497c5 100644
--- a/xen/arch/arm/arm64/head.S
+++ b/xen/arch/arm/arm64/head.S
@@ -561,6 +561,14 @@ END(efi_xen_start)
#endif /* CONFIG_ARM_EFI */
+#ifdef CONFIG_SYSTEM_SUSPEND
+
+FUNC(hyp_resume)
+ b .
+END(hyp_resume)
+
+#endif /* CONFIG_SYSTEM_SUSPEND */
+
/*
* Local variables:
* mode: ASM
diff --git a/xen/arch/arm/include/asm/psci.h b/xen/arch/arm/include/asm/psci.h
index 48a93e6b79..15eb2c6013 100644
--- a/xen/arch/arm/include/asm/psci.h
+++ b/xen/arch/arm/include/asm/psci.h
@@ -20,6 +20,7 @@ extern uint32_t psci_ver;
int psci_init(void);
int call_psci_cpu_on(int cpu);
+int call_psci_system_suspend(void);
void call_psci_cpu_off(void);
void call_psci_system_off(void);
void call_psci_system_reset(void);
diff --git a/xen/arch/arm/include/asm/suspend.h b/xen/arch/arm/include/asm/suspend.h
index 745377dbcf..0d2f0da0ad 100644
--- a/xen/arch/arm/include/asm/suspend.h
+++ b/xen/arch/arm/include/asm/suspend.h
@@ -4,6 +4,7 @@
#define __ASM_ARM_SUSPEND_H__
int32_t domain_suspend(register_t epoint, register_t cid);
+void hyp_resume(void);
#endif
diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
index b6860a7760..8e9c571467 100644
--- a/xen/arch/arm/psci.c
+++ b/xen/arch/arm/psci.c
@@ -17,6 +17,7 @@
#include <asm/cpufeature.h>
#include <asm/psci.h>
#include <asm/acpi.h>
+#include <asm/suspend.h>
/*
* While a 64-bit OS can make calls with SMC32 calling conventions, for
@@ -60,6 +61,24 @@ void call_psci_cpu_off(void)
}
}
+int call_psci_system_suspend(void)
+{
+#ifdef CONFIG_SYSTEM_SUSPEND
+ struct arm_smccc_res res;
+
+ if ( psci_ver < PSCI_VERSION(1, 0) )
+ return PSCI_NOT_SUPPORTED;
+
+ /* 2nd argument (context ID) is not used */
+ arm_smccc_smc(PSCI_1_0_FN64_SYSTEM_SUSPEND, __pa(hyp_resume), &res);
+
+ return PSCI_RET(res);
+#else
+ /* not supported */
+ return PSCI_NOT_SUPPORTED;
+#endif
+}
+
void call_psci_system_off(void)
{
if ( psci_ver > PSCI_VERSION(0, 1) )
diff --git a/xen/arch/arm/suspend.c b/xen/arch/arm/suspend.c
index fa81be5a4f..ac88faee2e 100644
--- a/xen/arch/arm/suspend.c
+++ b/xen/arch/arm/suspend.c
@@ -170,6 +170,10 @@ static long system_suspend(void *data)
*/
update_boot_mapping(true);
+ status = call_psci_system_suspend();
+ if ( status )
+ dprintk(XENLOG_ERR, "PSCI system suspend failed, err=%d\n", status);
+
system_state = SYS_STATE_resume;
update_boot_mapping(false);
--
2.43.0