mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-05-08 18:41:22 +00:00
feat(psci): add support for OS-initiated mode
This patch adds a `psci_validate_state_coordination` function that is called by `psci_cpu_suspend_start` in OS-initiated mode. This function validates the request per sections 4.2.3.2, 5.4.5, and 6.3 of the PSCI spec (DEN0022D.b): - The requested power states are consistent with the system's state - The calling core is the last running core at the requested power level This function differs from `psci_do_state_coordination` in that: - The `psci_req_local_pwr_states` map is not modified if the request were to be denied - The `state_info` argument is never modified since it contains the power states requested by the calling OS This is conditionally compiled into the build depending on the value of the `PSCI_OS_INIT_MODE` build option. Change-Id: I667041c842d2856e9d128c98db4d5ae4e4552df3 Signed-off-by: Wing Li <wingers@google.com>
This commit is contained in:
parent
b88a4416b5
commit
606b743007
6 changed files with 317 additions and 28 deletions
|
@ -60,6 +60,10 @@ int psci_cpu_suspend(unsigned int power_state,
|
|||
entry_point_info_t ep;
|
||||
psci_power_state_t state_info = { {PSCI_LOCAL_STATE_RUN} };
|
||||
plat_local_state_t cpu_pd_state;
|
||||
#if PSCI_OS_INIT_MODE
|
||||
unsigned int cpu_idx = plat_my_core_pos();
|
||||
plat_local_state_t prev[PLAT_MAX_PWR_LVL];
|
||||
#endif
|
||||
|
||||
/* Validate the power_state parameter */
|
||||
rc = psci_validate_power_state(power_state, &state_info);
|
||||
|
@ -95,6 +99,18 @@ int psci_cpu_suspend(unsigned int power_state,
|
|||
cpu_pd_state = state_info.pwr_domain_state[PSCI_CPU_PWR_LVL];
|
||||
psci_set_cpu_local_state(cpu_pd_state);
|
||||
|
||||
#if PSCI_OS_INIT_MODE
|
||||
/*
|
||||
* If in OS-initiated mode, save a copy of the previous
|
||||
* requested local power states and update the new requested
|
||||
* local power states for this CPU.
|
||||
*/
|
||||
if (psci_suspend_mode == OS_INIT) {
|
||||
psci_update_req_local_pwr_states(target_pwrlvl, cpu_idx,
|
||||
&state_info, prev);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_PSCI_STAT
|
||||
plat_psci_stat_accounting_start(&state_info);
|
||||
#endif
|
||||
|
@ -110,6 +126,16 @@ int psci_cpu_suspend(unsigned int power_state,
|
|||
/* Upon exit from standby, set the state back to RUN. */
|
||||
psci_set_cpu_local_state(PSCI_LOCAL_STATE_RUN);
|
||||
|
||||
#if PSCI_OS_INIT_MODE
|
||||
/*
|
||||
* If in OS-initiated mode, restore the previous requested
|
||||
* local power states for this CPU.
|
||||
*/
|
||||
if (psci_suspend_mode == OS_INIT) {
|
||||
psci_restore_req_local_pwr_states(cpu_idx, prev);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_RUNTIME_INSTRUMENTATION
|
||||
PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
|
||||
RT_INSTR_EXIT_HW_LOW_PWR,
|
||||
|
@ -142,12 +168,12 @@ int psci_cpu_suspend(unsigned int power_state,
|
|||
* might return if the power down was abandoned for any reason, e.g.
|
||||
* arrival of an interrupt
|
||||
*/
|
||||
psci_cpu_suspend_start(&ep,
|
||||
target_pwrlvl,
|
||||
&state_info,
|
||||
is_power_down_state);
|
||||
rc = psci_cpu_suspend_start(&ep,
|
||||
target_pwrlvl,
|
||||
&state_info,
|
||||
is_power_down_state);
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -187,12 +213,12 @@ int psci_system_suspend(uintptr_t entrypoint, u_register_t context_id)
|
|||
* might return if the power down was abandoned for any reason, e.g.
|
||||
* arrival of an interrupt
|
||||
*/
|
||||
psci_cpu_suspend_start(&ep,
|
||||
PLAT_MAX_PWR_LVL,
|
||||
&state_info,
|
||||
PSTATE_TYPE_POWERDOWN);
|
||||
rc = psci_cpu_suspend_start(&ep,
|
||||
PLAT_MAX_PWR_LVL,
|
||||
&state_info,
|
||||
PSTATE_TYPE_POWERDOWN);
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int psci_cpu_off(void)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue