refactor(psci): unify psci_is_last_on_cpu and psci_is_last_on_cpu_safe
"psci_is_last_on_cpu" and "psci_is_last_on_cpu_safe" modules perform
mostly similar functionalities, verifying whether the current CPU
is the only active core and other cores have been turned off.
However, psci_is_last_on_cpu_safe function differs from the other with:
1. Safe API locks the power domain
This patch removes the section duplicating the functionality
and ensures that "psci_is_last_on_cpu api",is reused in
"psci_is_last_on_cpu_safe" procedure.
Signed-off-by: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>
Change-Id: Ie372519e423898d7afa5427cdd77a7f9d3369587
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index efcfed8..8d736cc 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -156,25 +156,26 @@
/*******************************************************************************
* This function verifies that the all the other cores in the system have been
* turned OFF and the current CPU is the last running CPU in the system.
- * Returns 1 (true) if the current CPU is the last ON CPU or 0 (false)
- * otherwise.
+ * Returns true, if the current CPU is the last ON CPU or false otherwise.
******************************************************************************/
-unsigned int psci_is_last_on_cpu(void)
+bool psci_is_last_on_cpu(void)
{
unsigned int cpu_idx, my_idx = plat_my_core_pos();
- for (cpu_idx = 0; cpu_idx < psci_plat_core_count;
- cpu_idx++) {
+ for (cpu_idx = 0; cpu_idx < psci_plat_core_count; cpu_idx++) {
if (cpu_idx == my_idx) {
assert(psci_get_aff_info_state() == AFF_STATE_ON);
continue;
}
- if (psci_get_aff_info_state_by_idx(cpu_idx) != AFF_STATE_OFF)
- return 0;
+ if (psci_get_aff_info_state_by_idx(cpu_idx) != AFF_STATE_OFF) {
+ VERBOSE("core=%u other than current core=%u %s\n",
+ cpu_idx, my_idx, "running in the system");
+ return false;
+ }
}
- return 1;
+ return true;
}
/*******************************************************************************
@@ -1009,11 +1010,11 @@
/* Need to wait for other cores to shutdown */
if (wait_ms != 0U) {
- while ((wait_ms-- != 0U) && (psci_is_last_on_cpu() != 0U)) {
+ while ((wait_ms-- != 0U) && (!psci_is_last_on_cpu())) {
mdelay(1U);
}
- if (psci_is_last_on_cpu() != 0U) {
+ if (!psci_is_last_on_cpu()) {
WARN("Failed to stop all cores!\n");
psci_print_power_domain_map();
return PSCI_E_DENIED;
@@ -1030,48 +1031,22 @@
*
* This API has following differences with psci_is_last_on_cpu
* 1. PSCI states are locked
- * 2. It caters for "forest" topology instead of just "tree"
- * TODO : Revisit both API's and unify them
******************************************************************************/
bool psci_is_last_on_cpu_safe(void)
{
unsigned int this_core = plat_my_core_pos();
unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
- unsigned int i = 0;
-
- /*
- * Traverse the forest of PSCI nodes, nodes with no parents
- * (invalid-nodes) are the root nodes.
- */
- while ((i < PSCI_NUM_NON_CPU_PWR_DOMAINS) &&
- (psci_non_cpu_pd_nodes[i].parent_node ==
- PSCI_PARENT_NODE_INVALID)) {
- psci_get_parent_pwr_domain_nodes(
- psci_non_cpu_pd_nodes[i].cpu_start_idx,
- PLAT_MAX_PWR_LVL, parent_nodes);
- psci_acquire_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
+ psci_get_parent_pwr_domain_nodes(this_core, PLAT_MAX_PWR_LVL, parent_nodes);
- for (unsigned int core = 0U;
- core < psci_non_cpu_pd_nodes[i].ncpus; core++) {
- if (core == this_core) {
- continue;
- }
+ psci_acquire_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
- if (psci_get_aff_info_state_by_idx(core) !=
- AFF_STATE_OFF) {
- psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL,
- parent_nodes);
- VERBOSE("core=%u other than boot core=%u %s\n",
- core, this_core, "running in the system");
-
- return false;
- }
- }
-
+ if (!psci_is_last_on_cpu()) {
psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
- i++;
+ return false;
}
+ psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
+
return true;
}
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index 52a8b8a..a631f3f 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -158,7 +158,7 @@
entry_point_info_t ep;
/* Check if the current CPU is the last ON CPU in the system */
- if (psci_is_last_on_cpu() == 0U)
+ if (!psci_is_last_on_cpu())
return PSCI_E_DENIED;
/* Validate the entry point and get the entry_point_info */
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index caade9c..1901c17 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -294,7 +294,7 @@
unsigned int psci_find_target_suspend_lvl(const psci_power_state_t *state_info);
void psci_set_pwr_domains_to_run(unsigned int end_pwrlvl);
void psci_print_power_domain_map(void);
-unsigned int psci_is_last_on_cpu(void);
+bool psci_is_last_on_cpu(void);
int psci_spd_migrate_info(u_register_t *mpidr);
/*