psci: rectify and homogenise generic code
This patch performs a major rework of the psci generic implementation
to achieve the following:
1. replace recursion with iteration where possible to aid code
readability e.g. affinity instance states are changed iteratively
instead of recursively.
2. acquire pointers to affinity instance nodes at the beginning of a
psci operation. All subsequent actions use these pointers instead
of calling psci_get_aff_map_node() repeatedly e.g. management of
locks has been abstracted under functions which use these pointers
to ensure correct ordering. Helper functions have been added to
create these abstractions.
3. assertions have been added to cpu level handlers to ensure correct
state transition
4. the affinity level extents specified to various functions have the
same meaning i.e. start level is always less than the end level.
Change-Id: If0508c3a7b20ea3ddda2a66128429382afc3dfc8
diff --git a/common/psci/psci_main.c b/common/psci/psci_main.c
index fbf864b..f73fc49 100644
--- a/common/psci/psci_main.c
+++ b/common/psci/psci_main.c
@@ -45,7 +45,7 @@
{
int rc;
- unsigned int start_afflvl, target_afflvl;
+ unsigned int start_afflvl, end_afflvl;
/* Determine if the cpu exists of not */
rc = psci_validate_mpidr(target_cpu, MPIDR_AFFLVL0);
@@ -53,13 +53,17 @@
goto exit;
}
- start_afflvl = get_max_afflvl();
- target_afflvl = MPIDR_AFFLVL0;
+ /*
+ * To turn this cpu on, specify which affinity
+ * levels need to be turned on
+ */
+ start_afflvl = MPIDR_AFFLVL0;
+ end_afflvl = get_max_afflvl();
rc = psci_afflvl_on(target_cpu,
entrypoint,
context_id,
start_afflvl,
- target_afflvl);
+ end_afflvl);
exit:
return rc;
@@ -76,7 +80,7 @@
{
int rc;
unsigned long mpidr;
- unsigned int tgt_afflvl, pstate_type;
+ unsigned int target_afflvl, pstate_type;
/* TODO: Standby states are not supported at the moment */
pstate_type = psci_get_pstate_type(power_state);
@@ -86,8 +90,8 @@
}
/* Sanity check the requested state */
- tgt_afflvl = psci_get_pstate_afflvl(power_state);
- if (tgt_afflvl > MPIDR_MAX_AFFLVL) {
+ target_afflvl = psci_get_pstate_afflvl(power_state);
+ if (target_afflvl > MPIDR_MAX_AFFLVL) {
rc = PSCI_E_INVALID_PARAMS;
goto exit;
}
@@ -97,8 +101,8 @@
entrypoint,
context_id,
power_state,
- tgt_afflvl,
- MPIDR_AFFLVL0);
+ MPIDR_AFFLVL0,
+ target_afflvl);
exit:
if (rc != PSCI_E_SUCCESS)
@@ -120,7 +124,7 @@
* management is done immediately followed by cpu, cluster ...
* ..target_afflvl specific actions as this function unwinds back.
*/
- rc = psci_afflvl_off(mpidr, target_afflvl, MPIDR_AFFLVL0);
+ rc = psci_afflvl_off(mpidr, MPIDR_AFFLVL0, target_afflvl);
/*
* The only error cpu_off can return is E_DENIED. So check if that's