From 0f9406277d5b4eeacddac6b1686810f3ecd6a4df Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Mon, 1 Mar 2021 08:57:15 +0100 Subject: [PATCH] aarch64: pm_cpu_ops: Introduce pm_cpu_ops subsystem AArch64 has support for PSCI. This is especially useful for SMP because PSCI is used to power on the secordary cores. When the PSCI driver was introduced in Zephyr it was designed to rely on a very PSCI-centric subsystem / interface. There are two kinds of problems with this choice: 1. PSCI is only defined for the non-secure world and it is designed to boot CPU cores into non-secure state (that means that PSCI is only supposed to work if Zephyr is running in non-secure state) 2. There can be other ways or standards used to start / stop a core different from PSCI This patch is trying to fix the original wrong assumption by making the interface / subsystem a generic one, called 'pm_cpu_ops', and using PSCI only as an actual driver that is a user of this new interface / subsystem. For now the new subsystem is only exposing two methods: cpu_on and cpu_off, others will probably follow according to the needs. Signed-off-by: Carlo Caione --- CODEOWNERS | 7 +- MAINTAINERS.yml | 9 +- .../qemu_cortex_a53/qemu_cortex_a53_defconfig | 2 +- drivers/CMakeLists.txt | 2 +- drivers/Kconfig | 4 +- drivers/pm_cpu_ops/CMakeLists.txt | 5 + drivers/{psci => pm_cpu_ops}/Kconfig | 30 +++- .../psci.c => pm_cpu_ops/pm_cpu_ops_psci.c} | 88 +++++----- .../psci.h => pm_cpu_ops/pm_cpu_ops_psci.h} | 5 +- drivers/pm_cpu_ops/pm_cpu_ops_weak_impl.c | 17 ++ drivers/psci/CMakeLists.txt | 6 - drivers/psci/psci_handlers.c | 45 ----- .../{psci => pm_cpu_ops}/arm,psci.yaml | 0 include/drivers/pm_cpu_ops.h | 63 +++++++ include/drivers/pm_cpu_ops/psci.h | 36 ++++ include/drivers/psci.h | 160 ------------------ tests/arch/arm64/arm_psci/src/main.c | 24 +-- tests/arch/arm64/arm_psci/testcase.yaml | 2 +- 18 files changed, 204 insertions(+), 301 deletions(-) create mode 100644 drivers/pm_cpu_ops/CMakeLists.txt rename drivers/{psci => pm_cpu_ops}/Kconfig (52%) rename drivers/{psci/psci.c => pm_cpu_ops/pm_cpu_ops_psci.c} (55%) rename drivers/{psci/psci.h => pm_cpu_ops/pm_cpu_ops_psci.h} (97%) create mode 100644 drivers/pm_cpu_ops/pm_cpu_ops_weak_impl.c delete mode 100644 drivers/psci/CMakeLists.txt delete mode 100644 drivers/psci/psci_handlers.c rename dts/bindings/{psci => pm_cpu_ops}/arm,psci.yaml (100%) create mode 100644 include/drivers/pm_cpu_ops.h create mode 100644 include/drivers/pm_cpu_ops/psci.h delete mode 100644 include/drivers/psci.h diff --git a/CODEOWNERS b/CODEOWNERS index eed4be770ba..9269ac78ed3 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -244,7 +244,7 @@ /drivers/peci/ @albertofloyd @franciscomunoz @scottwcpg /drivers/pinmux/*hsdk* @iriszzw /drivers/pinmux/*it8xxx2* @ite -/drivers/psci/ @carlocaione +/drivers/pm_cpu_ops/ @carlocaione /drivers/ps2/ @albertofloyd @franciscomunoz @scottwcpg /drivers/pwm/*rv32m1* @henrikbrixandersen /drivers/pwm/*sam0* @nzmichaelh @@ -365,7 +365,7 @@ /dts/bindings/*/sifive* @mateusz-holenko @kgugala @pgielda /dts/bindings/*/litex* @mateusz-holenko @kgugala @pgielda /dts/bindings/*/vexriscv* @mateusz-holenko @kgugala @pgielda -/dts/bindings/psci/* @carlocaione +/dts/bindings/pm_cpu_ops/* @carlocaione /dts/posix/ @aescolar @vanwinkeljan @daor-oti /dts/bindings/sensor/*bme680* @BoschSensortec /dts/bindings/sensor/st* @avisconti @@ -392,7 +392,8 @@ /include/drivers/spi.h @tbursztyka /include/drivers/lora.h @Mani-Sadhasivam /include/drivers/peci.h @albertofloyd @franciscomunoz @scottwcpg -/include/drivers/psci.h @carlocaione +/include/drivers/pm_cpu_ops.h @carlocaione +/include/drivers/pm_cpu_ops/ @carlocaione /include/app_memory/ @dcpleung /include/arch/arc/ @abrodkin @ruuddw /include/arch/arc/arch.h @abrodkin @ruuddw diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 52068cebaa9..bf50f52b4e7 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -729,16 +729,17 @@ Documentation: labels: - "area: Clocks" -"Drivers: PSCI": +"Drivers: PM CPU ops": status: maintained maintainers: - carlocaione files: - - drivers/psci/ - - include/drivers/psci.h + - drivers/pm_cpu_ops/ + - include/drivers/pm_cpu_ops/ + - include/drivers/pm_cpu_ops.h - include/arch/arm/arm-smccc.h labels: - - "area: PSCI" + - "area: PM CPU ops" "Drivers: PWM": status: maintained diff --git a/boards/arm/qemu_cortex_a53/qemu_cortex_a53_defconfig b/boards/arm/qemu_cortex_a53/qemu_cortex_a53_defconfig index 8fdb00d54f6..0da1621c067 100644 --- a/boards/arm/qemu_cortex_a53/qemu_cortex_a53_defconfig +++ b/boards/arm/qemu_cortex_a53/qemu_cortex_a53_defconfig @@ -12,7 +12,7 @@ CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y # PSCI is supported -CONFIG_ARM_PSCI=y +CONFIG_PM_CPU_OPS=y # Enable serial port CONFIG_UART_PL011=y diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index 284fe0c4760..972a91d1e99 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -42,7 +42,7 @@ add_subdirectory_ifdef(CONFIG_PECI peci) add_subdirectory_ifdef(CONFIG_REGULATOR regulator) add_subdirectory_ifdef(CONFIG_MEMC memc) add_subdirectory_ifdef(CONFIG_VIRTUALIZATION virtualization) -add_subdirectory_ifdef(CONFIG_ARM_PSCI psci) +add_subdirectory_ifdef(CONFIG_PM_CPU_OPS pm_cpu_ops) add_subdirectory_ifdef(CONFIG_FLASH_HAS_DRIVER_ENABLED flash) add_subdirectory_ifdef(CONFIG_SERIAL_HAS_DRIVER serial) diff --git a/drivers/Kconfig b/drivers/Kconfig index 079790875c1..c8cdc01f31f 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -105,8 +105,8 @@ source "drivers/memc/Kconfig" source "drivers/virtualization/Kconfig" -source "drivers/psci/Kconfig" - source "drivers/edac/Kconfig" +source "drivers/pm_cpu_ops/Kconfig" + endmenu diff --git a/drivers/pm_cpu_ops/CMakeLists.txt b/drivers/pm_cpu_ops/CMakeLists.txt new file mode 100644 index 00000000000..15f17a83ce8 --- /dev/null +++ b/drivers/pm_cpu_ops/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources_ifdef(CONFIG_PM_CPU_OPS pm_cpu_ops_weak_impl.c) + +zephyr_sources_ifdef(CONFIG_PM_CPU_OPS_PSCI pm_cpu_ops_psci.c) diff --git a/drivers/psci/Kconfig b/drivers/pm_cpu_ops/Kconfig similarity index 52% rename from drivers/psci/Kconfig rename to drivers/pm_cpu_ops/Kconfig index 736c14a0f8c..e87a27ff317 100644 --- a/drivers/psci/Kconfig +++ b/drivers/pm_cpu_ops/Kconfig @@ -1,12 +1,30 @@ -# PSCI driver configuration options +# CPU power management driver configuration options -# Copyright (c) 2020 Carlo Caione +# Copyright (c) 2021 Carlo Caione # SPDX-License-Identifier: Apache-2.0 -config ARM_PSCI +menuconfig PM_CPU_OPS + bool "CPU power management drivers" + help + Enable CPU power management drivers configuration + +if PM_CPU_OPS + +module = PM_CPU_OPS +module-str = pm_cpu_ops +source "subsys/logging/Kconfig.template.log_config" + +DT_COMPAT_ARM_PSCI := arm,psci-0.2 + +config PM_CPU_OPS_HAS_DRIVER + bool + +config PM_CPU_OPS_PSCI bool "Support for the ARM Power State Coordination Interface (PSCI)" depends on ARMV8_A depends on HAS_ARM_SMCCC + select PM_CPU_OPS_HAS_DRIVER + default $(dt_compat_enabled,$(DT_COMPAT_ARM_PSCI)) help Say Y here if you want Zephyr to communicate with system firmware implementing the PSCI specification for CPU-centric power @@ -14,10 +32,4 @@ config ARM_PSCI 0022A ("Power State Coordination Interface System Software on ARM processors"). -if ARM_PSCI - -module = PSCI -module-str = psci -source "subsys/logging/Kconfig.template.log_config" - endif diff --git a/drivers/psci/psci.c b/drivers/pm_cpu_ops/pm_cpu_ops_psci.c similarity index 55% rename from drivers/psci/psci.c rename to drivers/pm_cpu_ops/pm_cpu_ops_psci.c index 91eb52f411d..63672c2aeaf 100644 --- a/drivers/psci/psci.c +++ b/drivers/pm_cpu_ops/pm_cpu_ops_psci.c @@ -6,7 +6,7 @@ #define DT_DRV_COMPAT arm_psci_0_2 -#define LOG_LEVEL CONFIG_PSCI_LOG_LEVEL +#define LOG_LEVEL CONFIG_PM_CPU_OPS_LOG_LEVEL #include LOG_MODULE_REGISTER(psci); @@ -17,8 +17,10 @@ LOG_MODULE_REGISTER(psci); #include #include -#include -#include "psci.h" +#include +#include "pm_cpu_ops_psci.h" + +static struct psci psci_data; static int psci_to_dev_err(int ret) { @@ -37,45 +39,32 @@ static int psci_to_dev_err(int ret) return -EINVAL; } -static uint32_t psci_api_get_version(const struct device *dev) +int pm_cpu_off(void) { - struct psci *data = dev->data; - - return data->invoke_psci_fn(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0); -} - -static int psci_api_cpu_off(const struct device *dev, uint32_t state) -{ - struct psci *data = dev->data; int ret; - ret = data->invoke_psci_fn(PSCI_0_2_FN_CPU_OFF, state, 0, 0); + if (psci_data.conduit == SMCCC_CONDUIT_NONE) + return -EINVAL; + + ret = psci_data.invoke_psci_fn(PSCI_0_2_FN_CPU_OFF, 0, 0, 0); return psci_to_dev_err(ret); } -static int psci_api_cpu_on(const struct device *dev, unsigned long cpuid, - unsigned long entry_point) +int pm_cpu_on(unsigned long cpuid, + uintptr_t entry_point) { - struct psci *data = dev->data; int ret; - ret = data->invoke_psci_fn(PSCI_FN_NATIVE(0_2, CPU_ON), cpuid, - entry_point, 0); + if (psci_data.conduit == SMCCC_CONDUIT_NONE) + return -EINVAL; + + ret = psci_data.invoke_psci_fn(PSCI_FN_NATIVE(0_2, CPU_ON), cpuid, + (unsigned long) entry_point, 0); return psci_to_dev_err(ret); } -static int psci_api_affinity_info(const struct device *dev, - unsigned long target_affinity, - unsigned long lowest_affinity_level) -{ - struct psci *data = dev->data; - - return data->invoke_psci_fn(PSCI_FN_NATIVE(0_2, AFFINITY_INFO), - target_affinity, lowest_affinity_level, 0); -} - static unsigned long __invoke_psci_fn_hvc(unsigned long function_id, unsigned long arg0, unsigned long arg1, @@ -98,18 +87,23 @@ static unsigned long __invoke_psci_fn_smc(unsigned long function_id, return res.a0; } -static int set_conduit_method(struct psci *data) +static uint32_t psci_get_version(void) +{ + return psci_data.invoke_psci_fn(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0); +} + +static int set_conduit_method(void) { const char *method; method = DT_PROP(DT_INST(0, DT_DRV_COMPAT), method); if (!strcmp("hvc", method)) { - data->conduit = SMCCC_CONDUIT_HVC; - data->invoke_psci_fn = __invoke_psci_fn_hvc; + psci_data.conduit = SMCCC_CONDUIT_HVC; + psci_data.invoke_psci_fn = __invoke_psci_fn_hvc; } else if (!strcmp("smc", method)) { - data->conduit = SMCCC_CONDUIT_SMC; - data->invoke_psci_fn = __invoke_psci_fn_smc; + psci_data.conduit = SMCCC_CONDUIT_SMC; + psci_data.invoke_psci_fn = __invoke_psci_fn_smc; } else { LOG_ERR("Invalid conduit method"); return -EINVAL; @@ -118,9 +112,9 @@ static int set_conduit_method(struct psci *data) return 0; } -static int psci_detect(const struct device *dev) +static int psci_detect(void) { - uint32_t ver = psci_api_get_version(dev); + uint32_t ver = psci_get_version(); LOG_DBG("Detected PSCIv%d.%d", PSCI_VERSION_MAJOR(ver), @@ -131,29 +125,27 @@ static int psci_detect(const struct device *dev) return -ENOTSUP; } + psci_data.ver = ver; + return 0; } +uint32_t psci_version(void) +{ + return psci_data.ver; +} + static int psci_init(const struct device *dev) { - struct psci *data = dev->data; + psci_data.conduit = SMCCC_CONDUIT_NONE; - if (set_conduit_method(data)) { + if (set_conduit_method()) { return -ENOTSUP; } - return psci_detect(dev); + return psci_detect(); } -static const struct psci_driver_api psci_api = { - .get_version = psci_api_get_version, - .cpu_off = psci_api_cpu_off, - .cpu_on = psci_api_cpu_on, - .affinity_info = psci_api_affinity_info, -}; - -static struct psci psci_data; - DEVICE_DT_INST_DEFINE(0, psci_init, device_pm_control_nop, &psci_data, NULL, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, - &psci_api); + NULL); diff --git a/drivers/psci/psci.h b/drivers/pm_cpu_ops/pm_cpu_ops_psci.h similarity index 97% rename from drivers/psci/psci.h rename to drivers/pm_cpu_ops/pm_cpu_ops_psci.h index 8271180e97c..388af524bb6 100644 --- a/drivers/psci/psci.h +++ b/drivers/pm_cpu_ops/pm_cpu_ops_psci.h @@ -7,7 +7,7 @@ #ifndef ZEPHYR_DRIVERS_PSCI_PSCI_H_ #define ZEPHYR_DRIVERS_PSCI_PSCI_H_ -#include +#include #ifdef CONFIG_64BIT #define PSCI_FN_NATIVE(version, name) PSCI_##version##_FN64_##name @@ -56,8 +56,9 @@ typedef unsigned long (psci_fn)(unsigned long, unsigned long, unsigned long, unsigned long); struct psci { - psci_fn *invoke_psci_fn; enum arm_smccc_conduit conduit; + psci_fn *invoke_psci_fn; + uint32_t ver; }; #endif /* ZEPHYR_DRIVERS_PSCI_PSCI_H_ */ diff --git a/drivers/pm_cpu_ops/pm_cpu_ops_weak_impl.c b/drivers/pm_cpu_ops/pm_cpu_ops_weak_impl.c new file mode 100644 index 00000000000..fc88c0fa10f --- /dev/null +++ b/drivers/pm_cpu_ops/pm_cpu_ops_weak_impl.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2021 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +int __weak pm_cpu_on(unsigned long cpuid, uintptr_t entry_point) +{ + return -ENOTSUP; +} + +int __weak pm_cpu_off(void) +{ + return -ENOTSUP; +} diff --git a/drivers/psci/CMakeLists.txt b/drivers/psci/CMakeLists.txt deleted file mode 100644 index 98afb5ce09b..00000000000 --- a/drivers/psci/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -zephyr_library() - -zephyr_library_sources_ifdef(CONFIG_ARM_PSCI psci.c) -zephyr_library_sources_ifdef(CONFIG_USERSPACE psci_handlers.c) diff --git a/drivers/psci/psci_handlers.c b/drivers/psci/psci_handlers.c deleted file mode 100644 index 9149889049b..00000000000 --- a/drivers/psci/psci_handlers.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2020 Carlo Caione - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -static inline uint32_t z_vrfy_psci_get_version(const struct device *dev) -{ - Z_OOPS(Z_SYSCALL_DRIVER_PSCI(dev, get_version)); - - return z_impl_psci_get_version(dev); -} -#include - -static inline int z_vrfy_psci_cpu_off(const struct device *dev, uint32_t state) -{ - Z_OOPS(Z_SYSCALL_DRIVER_PSCI(dev, cpu_off)); - - return z_impl_psci_cpu_off(dev, state); -} -#include - -static inline int z_vrfy_psci_cpu_on(const struct device *dev, - unsigned long cpuid, - unsigned long entry_point) { - Z_OOPS(Z_SYSCALL_DRIVER_PSCI(dev, cpu_on)); - - return z_impl_psci_cpu_on(dev, cpuid, entry_point); -} -#include - -static inline int z_vrfy_psci_affinity_info(const struct device *dev, - unsigned long target_affinity, - unsigned long lowest_affinity_level) -{ - Z_OOPS(Z_SYSCALL_DRIVER_PSCI(dev, affinity_info)); - - return z_impl_psci_affinity_info(dev, target_affinity, - lowest_affinity_level); -} -#include diff --git a/dts/bindings/psci/arm,psci.yaml b/dts/bindings/pm_cpu_ops/arm,psci.yaml similarity index 100% rename from dts/bindings/psci/arm,psci.yaml rename to dts/bindings/pm_cpu_ops/arm,psci.yaml diff --git a/include/drivers/pm_cpu_ops.h b/include/drivers/pm_cpu_ops.h new file mode 100644 index 00000000000..980c7aa6790 --- /dev/null +++ b/include/drivers/pm_cpu_ops.h @@ -0,0 +1,63 @@ +/* + * Copyright 2021 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_PM_CPU_OPS_H_ +#define ZEPHYR_INCLUDE_DRIVERS_PM_CPU_OPS_H_ + +/** + * @file + * @brief Public API for CPU Power Management + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup power_management_cpu_api CPU Power Management + * @{ + */ + +/** + * @brief Power down the calling core + * + * This call is intended for use in hotplug. A core that is powered down by + * cpu_off can only be powered up again in response to a cpu_on + * + * @retval The call does not return when successful + * @retval -ENOTSUP If the operation is not supported + */ +int pm_cpu_off(void); + +/** + * @brief Power up a core + * + * This call is used to power up cores that either have not yet been booted + * into the calling supervisory software or have been previously powered down + * with a cpu_off call + * + * @param cpuid CPU id to power on + * @param entry_point Address at which the core must commence execution + * + * @retval 0 on success, a negative errno otherwise + * @retval -ENOTSUP If the operation is not supported + */ +int pm_cpu_on(unsigned long cpuid, uintptr_t entry_point); + + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_DRIVERS_PM_CPU_OPS_H_ */ diff --git a/include/drivers/pm_cpu_ops/psci.h b/include/drivers/pm_cpu_ops/psci.h new file mode 100644 index 00000000000..902e9e3713d --- /dev/null +++ b/include/drivers/pm_cpu_ops/psci.h @@ -0,0 +1,36 @@ +/* + * Copyright 2020 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_PM_CPU_OPS_PSCI_H_ +#define ZEPHYR_INCLUDE_DRIVERS_PM_CPU_OPS_PSCI_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* PSCI version decoding (independent of PSCI version) */ +#define PSCI_VERSION_MAJOR_SHIFT 16 +#define PSCI_VERSION_MINOR_MASK \ + ((1U << PSCI_VERSION_MAJOR_SHIFT) - 1) +#define PSCI_VERSION_MAJOR_MASK ~PSCI_VERSION_MINOR_MASK + +#define PSCI_VERSION_MAJOR(ver) \ + (((ver) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT) +#define PSCI_VERSION_MINOR(ver) \ + ((ver) & PSCI_VERSION_MINOR_MASK) + +uint32_t psci_version(void); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_PM_CPU_OPS_PSCI_H_ */ diff --git a/include/drivers/psci.h b/include/drivers/psci.h deleted file mode 100644 index 10dfc5c20cf..00000000000 --- a/include/drivers/psci.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2020 Carlo Caione - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_DRIVERS_PSCI_H_ -#define ZEPHYR_INCLUDE_DRIVERS_PSCI_H_ - -/** - * @file - * @brief Public API for ARM PSCI - */ - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* PSCI version decoding (independent of PSCI version) */ -#define PSCI_VERSION_MAJOR_SHIFT 16 -#define PSCI_VERSION_MINOR_MASK \ - ((1U << PSCI_VERSION_MAJOR_SHIFT) - 1) -#define PSCI_VERSION_MAJOR_MASK ~PSCI_VERSION_MINOR_MASK - -#define PSCI_VERSION_MAJOR(ver) \ - (((ver) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT) -#define PSCI_VERSION_MINOR(ver) \ - ((ver) & PSCI_VERSION_MINOR_MASK) - -/** - * @brief ARM PSCI Driver API - * @defgroup arm_psci ARM PSCI Driver API - * @{ - */ - -typedef uint32_t (*psci_get_version_f)(const struct device *dev); - -typedef int (*psci_cpu_off_f)(const struct device *dev, uint32_t state); - -typedef int (*psci_cpu_on_f)(const struct device *dev, unsigned long cpuid, - unsigned long entry_point); - -typedef int (*psci_affinity_info_f)(const struct device *dev, - unsigned long target_affinity, - unsigned long lowest_affinity_level); - -__subsystem struct psci_driver_api { - psci_get_version_f get_version; - psci_cpu_off_f cpu_off; - psci_cpu_on_f cpu_on; - psci_affinity_info_f affinity_info; -}; - -/** - * @brief Return the version of PSCI implemented - * - * @param dev Pointer to the device structure for the driver instance - * - * @return The PSCI version - */ -__syscall uint32_t psci_get_version(const struct device *dev); - -static inline uint32_t z_impl_psci_get_version(const struct device *dev) -{ - const struct psci_driver_api *api = - (const struct psci_driver_api *)dev->api; - - return api->get_version(dev); -} - -/** - * @brief Power down the calling core - * - * This call is intended foruse in hotplug. A core that is powered down by - * CPU_OFF can only be powered up again in response to a CPU_ON - * - * @param dev Pointer to the device structure for the driver instance - * @param state Not used - * - * @return The call does not return when successful - */ -__syscall int psci_cpu_off(const struct device *dev, uint32_t state); - -static inline int z_impl_psci_cpu_off(const struct device *dev, uint32_t state) -{ - const struct psci_driver_api *api = - (const struct psci_driver_api *)dev->api; - - return api->cpu_off(dev, state); -} - -/** - * @brief Power up a core - * - * This call is used to power up cores that either have not yet been booted - * into the calling supervisory software or have been previously powered down - * with a CPU_OFF call - * - * @param dev Pointer to the device structure for the driver instance - * @param cpuid This parameter contains a copy of the affinity fields of the - * MPIDR register - * @param entry_point Address at which the core must commence execution, when - * it enters the return Non-secure Exception level. - * - * @return 0 on success, a negative errno otherwise - */ -__syscall int psci_cpu_on(const struct device *dev, unsigned long cpuid, - unsigned long entry_point); - -static inline int z_impl_psci_cpu_on(const struct device *dev, - unsigned long cpuid, - unsigned long entry_point) { - const struct psci_driver_api *api = - (const struct psci_driver_api *)dev->api; - - return api->cpu_on(dev, cpuid, entry_point); -} - -/** - * @brief Enable the caller to request status of an affinity instance - * - * @param dev Pointer to the device structure for the driver instance - * @param target_affinity This parameter contains a copy of the affinity fields - * of the MPIDR register - * @param lowest_affinity_level Denotes the lowest affinity level field that is - * valid in the target_affinity parameter - * - * @return 2 if the affinity instance is transitioning to an ON sate, 1 off, 0 - * on, a negative errno otherwise - */ -__syscall int psci_affinity_info(const struct device *dev, - unsigned long target_affinity, - unsigned long lowest_affinity_level); - -static inline int z_impl_psci_affinity_info(const struct device *dev, - unsigned long target_affinity, - unsigned long lowest_affinity_level) -{ - const struct psci_driver_api *api = - (const struct psci_driver_api *)dev->api; - - return api->affinity_info(dev, target_affinity, lowest_affinity_level); -} - -#ifdef __cplusplus -} -#endif - -/** - * @} - */ - -#include - -#endif /* ZEPHYR_INCLUDE_DRIVERS_PSCI_H_ */ diff --git a/tests/arch/arm64/arm_psci/src/main.c b/tests/arch/arm64/arm_psci/src/main.c index 932260772da..a1953f4dae7 100644 --- a/tests/arch/arm64/arm_psci/src/main.c +++ b/tests/arch/arm64/arm_psci/src/main.c @@ -5,42 +5,28 @@ */ #include -#include - -#define PSCI_DEV_NAME "PSCI" +#include +#include void test_psci_func(void) { - const struct device *psci; uint32_t ver; int ret; - psci = device_get_binding(PSCI_DEV_NAME); - zassert_not_null(psci, "Could not get psci device"); - /* This should return 2 for v0.2 */ - ver = psci_get_version(psci); + ver = psci_version(); zassert_false((PSCI_VERSION_MAJOR(ver) == 0 && PSCI_VERSION_MINOR(ver) < 2), "Wrong PSCI firware version"); - /* This should return 0: (one core in the affinity instance is ON) */ - ret = psci_affinity_info(psci, 0, 0); - zassert_true(ret == 0, "Wrong return code from psci_affinity_info"); - /* This should return -PSCI_RET_ALREADY_ON that is mapped to -EINVAL */ - ret = psci_cpu_on(psci, 0, 0); + ret = pm_cpu_on(0, 0); zassert_true(ret == -EINVAL, "Wrong return code from psci_cpu_on"); } void test_main(void) { - const struct device *psci = device_get_binding(PSCI_DEV_NAME); - zassert_not_null(psci, "Could not get psci device"); - - k_object_access_grant(psci, k_current_get()); - ztest_test_suite(psci_func, - ztest_user_unit_test(test_psci_func)); + ztest_unit_test(test_psci_func)); ztest_run_test_suite(psci_func); } diff --git a/tests/arch/arm64/arm_psci/testcase.yaml b/tests/arch/arm64/arm_psci/testcase.yaml index 8be71bd3a2d..239b80e18bc 100644 --- a/tests/arch/arm64/arm_psci/testcase.yaml +++ b/tests/arch/arm64/arm_psci/testcase.yaml @@ -2,4 +2,4 @@ tests: arch.arm64.psci: arch_allow: arm tags: arm psci drivers userspace - filter: CONFIG_ARM_PSCI + filter: PM_CPU_OPS_PSCI