From e5564a98723563f235508a255debeb725b3aed37 Mon Sep 17 00:00:00 2001 From: qinwei1 Date: Tue, 28 Feb 2023 14:23:02 +0800 Subject: [PATCH] arm64: PSCI config support Summory This Power State Coordination Interface (PSCI) defines a standard interface for power management. the PCSI need to implement handling firmware at EL2 or EL3 for ARM64. the PSCI maybe not applicable for arm core without PCSI firmware interface implement. Add configure option for it. Note: 1. ostest is PASSED at qemu and fvp ( single core and SMP) Signed-off-by: qinwei1 --- arch/arm64/Kconfig | 12 ++++++++++++ arch/arm64/src/a64/a64_boot.c | 2 +- arch/arm64/src/common/Make.defs | 8 ++++++-- arch/arm64/src/common/arm64_cpu_psci.c | 6 +++--- arch/arm64/src/common/arm64_cpu_psci.h | 6 +++--- arch/arm64/src/common/arm64_cpustart.c | 15 +++++---------- arch/arm64/src/common/arm64_systemreset.c | 2 +- arch/arm64/src/qemu/Kconfig | 3 +++ arch/arm64/src/qemu/qemu_boot.c | 2 +- 9 files changed, 35 insertions(+), 21 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 4136e5a09d..c50519b064 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -31,6 +31,7 @@ config ARCH_CHIP_A64 select ARCH_CORTEX_A53 select ARCH_HAVE_ADDRENV select ARCH_HAVE_RESET + select ARCH_HAVE_PSCI select ARCH_NEED_ADDRENV_MAPPING ---help--- Allwinner A64 SoC @@ -53,6 +54,17 @@ config ARCH_ARMV8R bool default n +config ARCH_HAVE_PSCI + bool "ARM PCSI (Power State Coordination Interface) Support" + default n + ---help--- + This Power State Coordination Interface (PSCI) defines + a standard interface for power management. the PCSI need + to implement handling firmware at EL2 or EL3. The option + maybe not applicable for arm core without PCSI firmware + interface implement + + config ARCH_CORTEX_A53 bool default n diff --git a/arch/arm64/src/a64/a64_boot.c b/arch/arm64/src/a64/a64_boot.c index ffb66fdf7a..02777e120e 100644 --- a/arch/arm64/src/a64/a64_boot.c +++ b/arch/arm64/src/a64/a64_boot.c @@ -84,7 +84,7 @@ void arm64_chip_boot(void) arm64_mmu_init(true); -#if defined(CONFIG_SMP) || defined(CONFIG_ARCH_HAVE_RESET) +#if defined(CONFIG_SMP) || defined(CONFIG_ARCH_HAVE_PSCI) arm64_psci_init("smc"); #endif diff --git a/arch/arm64/src/common/Make.defs b/arch/arm64/src/common/Make.defs index e076f888dd..cc4aecdfc6 100644 --- a/arch/arm64/src/common/Make.defs +++ b/arch/arm64/src/common/Make.defs @@ -46,17 +46,21 @@ CMN_CSRCS = arm64_initialize.c arm64_initialstate.c arm64_boot.c CMN_CSRCS += arm64_nputs.c arm64_idle.c arm64_copystate.c arm64_createstack.c CMN_CSRCS += arm64_releasestack.c arm64_stackframe.c arm64_usestack.c CMN_CSRCS += arm64_task_sched.c arm64_exit.c arm64_vfork.c arm64_switchcontext.c -CMN_CSRCS += arm64_schedulesigaction.c arm64_sigdeliver.c arm64_systemreset.c +CMN_CSRCS += arm64_schedulesigaction.c arm64_sigdeliver.c CMN_CSRCS += arm64_backtrace.c arm64_getintstack.c arm64_registerdump.c # Common C source files ( hardware BSP ) CMN_CSRCS += arm64_mmu.c arm64_arch_timer.c arm64_cache.c CMN_CSRCS += arm64_doirq.c arm64_gicv2.c arm64_gicv3.c arm64_fatal.c -CMN_CSRCS += arm64_syscall.c arm64_cpu_psci.c +CMN_CSRCS += arm64_syscall.c # Use common heap allocation for now (may need to be customized later) CMN_CSRCS += arm64_allocateheap.c +ifeq ($(CONFIG_ARCH_HAVE_PSCI),y) +CMN_CSRCS += arm64_cpu_psci.c arm64_systemreset.c +endif + ifeq ($(CONFIG_SMP),y) CMN_CSRCS += arm64_cpuidlestack.c arm64_cpustart.c arm64_cpuindex.c CMN_CSRCS += arm64_cpupause.c diff --git a/arch/arm64/src/common/arm64_cpu_psci.c b/arch/arm64/src/common/arm64_cpu_psci.c index 25ff69746a..f8c066f465 100644 --- a/arch/arm64/src/common/arm64_cpu_psci.c +++ b/arch/arm64/src/common/arm64_cpu_psci.c @@ -150,7 +150,7 @@ uint32_t psci_version(void) return psci_data.version; } -int pcsi_cpu_off(void) +int psci_cpu_off(void) { int ret; @@ -164,7 +164,7 @@ int pcsi_cpu_off(void) return psci_to_dev_err(ret); } -int pcsi_cpu_reset(void) +int psci_cpu_reset(void) { int ret; @@ -178,7 +178,7 @@ int pcsi_cpu_reset(void) return psci_to_dev_err(ret); } -int pcsi_cpu_on(unsigned long cpuid, uintptr_t entry_point) +int psci_cpu_on(unsigned long cpuid, uintptr_t entry_point) { int ret; diff --git a/arch/arm64/src/common/arm64_cpu_psci.h b/arch/arm64/src/common/arm64_cpu_psci.h index eeb3801bd5..66e6e7445e 100644 --- a/arch/arm64/src/common/arm64_cpu_psci.h +++ b/arch/arm64/src/common/arm64_cpu_psci.h @@ -98,8 +98,8 @@ struct psci_interface ****************************************************************************/ uint32_t psci_version(void); -int pcsi_cpu_off(void); -int pcsi_cpu_reset(void); -int pcsi_cpu_on(unsigned long cpuid, uintptr_t entry_point); +int psci_cpu_off(void); +int psci_cpu_reset(void); +int psci_cpu_on(unsigned long cpuid, uintptr_t entry_point); #endif /* __ARCH_ARM64_SRC_COMMON_ARM64_CPU_PSCI_H */ diff --git a/arch/arm64/src/common/arm64_cpustart.c b/arch/arm64/src/common/arm64_cpustart.c index fcfcb209cc..53262c7b39 100644 --- a/arch/arm64/src/common/arm64_cpustart.c +++ b/arch/arm64/src/common/arm64_cpustart.c @@ -153,21 +153,16 @@ static void arm64_start_cpu(int cpu_num, char *stack, int stack_sz, flush_end = flush_start + sizeof(cpu_boot_params); up_flush_dcache(flush_start, flush_end); - if (pcsi_cpu_on(cpu_mpid, (uint64_t)__start)) +#ifdef CONFIG_ARCH_HAVE_PSCI + if (psci_cpu_on(cpu_mpid, (uint64_t)__start)) { sinfo("Failed to boot secondary CPU core %d (MPID:%#lx)\n", cpu_num, cpu_mpid); return; } - - /* Wait secondary cores up, see z_arm64_secondary_start */ - - while (cpu_boot_params.func) - { - SP_WFE(); - } - - sinfo("Secondary CPU core %d (MPID:%#lx) is up\n", cpu_num, cpu_mpid); +#else + SP_SEV(); +#endif } /**************************************************************************** diff --git a/arch/arm64/src/common/arm64_systemreset.c b/arch/arm64/src/common/arm64_systemreset.c index 1076d99c18..86c97ca198 100644 --- a/arch/arm64/src/common/arm64_systemreset.c +++ b/arch/arm64/src/common/arm64_systemreset.c @@ -51,7 +51,7 @@ void up_systemreset(void) /* Set up for the system reset */ - ret = pcsi_cpu_reset(); + ret = psci_cpu_reset(); if (ret) { sinfo("Failed to reset CPU, error code: %d\n", ret); diff --git a/arch/arm64/src/qemu/Kconfig b/arch/arm64/src/qemu/Kconfig index f5d4720ebb..32e6b6959d 100644 --- a/arch/arm64/src/qemu/Kconfig +++ b/arch/arm64/src/qemu/Kconfig @@ -15,16 +15,19 @@ config ARCH_CHIP_QEMU_A53 bool "Qemu virtual Processor (cortex-a53)" select ARCH_HAVE_MULTICPU select ARMV8A_HAVE_GICv3 + select ARCH_HAVE_PSCI config ARCH_CHIP_QEMU_A57 bool "Qemu virtual Processor (cortex-a57)" select ARCH_HAVE_MULTICPU select ARMV8A_HAVE_GICv3 + select ARCH_HAVE_PCSI config ARCH_CHIP_QEMU_A72 bool "Qemu virtual Processor (cortex-a72)" select ARCH_HAVE_MULTICPU select ARMV8A_HAVE_GICv3 + select ARCH_HAVE_PCSI endchoice # Qemu Chip Selection diff --git a/arch/arm64/src/qemu/qemu_boot.c b/arch/arm64/src/qemu/qemu_boot.c index b8f7caec4e..3859e37f55 100644 --- a/arch/arm64/src/qemu/qemu_boot.c +++ b/arch/arm64/src/qemu/qemu_boot.c @@ -84,7 +84,7 @@ void arm64_chip_boot(void) arm64_mmu_init(true); -#ifdef CONFIG_SMP +#if defined(CONFIG_SMP) || defined(CONFIG_ARCH_HAVE_PSCI) arm64_psci_init("smc"); #endif