mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-26 14:55:16 +00:00
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
This commit is contained in:
parent
ea7aee20c1
commit
b41b082464
3 changed files with 20 additions and 45 deletions
|
@ -156,25 +156,26 @@ void psci_query_sys_suspend_pwrstate(psci_power_state_t *state_info)
|
|||
/*******************************************************************************
|
||||
* 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 @@ int psci_stop_other_cores(unsigned int wait_ms,
|
|||
|
||||
/* 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 @@ int psci_stop_other_cores(unsigned int wait_ms,
|
|||
*
|
||||
* 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_get_parent_pwr_domain_nodes(this_core, PLAT_MAX_PWR_LVL, parent_nodes);
|
||||
|
||||
psci_acquire_pwr_domain_locks(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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
psci_acquire_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 @@ int psci_system_suspend(uintptr_t entrypoint, u_register_t context_id)
|
|||
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 */
|
||||
|
|
|
@ -294,7 +294,7 @@ unsigned int psci_find_max_off_lvl(const psci_power_state_t *state_info);
|
|||
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);
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Reference in a new issue