#### plat_pm_ops.affinst_on()
Perform the platform specific setup to power on an affinity instance, specified
-by the `MPIDR` (first argument) and `affinity level` (fourth argument). The
-`state` (fifth argument) contains the current state of that affinity instance
+by the `MPIDR` (first argument) and `affinity level` (third argument). The
+`state` (fourth argument) contains the current state of that affinity instance
(ON or OFF). This is useful to determine whether any action must be taken. For
example, while powering on a CPU, the cluster that contains this CPU might
already be in the ON state. The platform decides what actions must be taken to
#### plat_pm_ops.affinst_off()
-Perform the platform specific setup to power off an affinity instance in the
-`MPIDR` of the calling CPU. It is called by the PSCI `CPU_OFF` API
-implementation.
+Perform the platform specific setup to power off an affinity instance of the
+calling CPU. It is called by the PSCI `CPU_OFF` API implementation.
-The `MPIDR` (first argument), `affinity level` (second argument) and `state`
-(third argument) have a similar meaning as described in the `affinst_on()`
-operation. They are used to identify the affinity instance on which the call
-is made and its current state. This gives the platform port an indication of the
+The `affinity level` (first argument) and `state` (second argument) have
+a similar meaning as described in the `affinst_on()` operation. They are
+used to identify the affinity instance on which the call is made and its
+current state. This gives the platform port an indication of the
state transition it must make to perform the requested action. For example, if
the calling CPU is the last powered on CPU in the cluster, after powering down
affinity level 0 (CPU), the platform port should power down affinity level 1
#### plat_pm_ops.affinst_suspend()
-Perform the platform specific setup to power off an affinity instance in the
-`MPIDR` of the calling CPU. It is called by the PSCI `CPU_SUSPEND` API
+Perform the platform specific setup to power off an affinity instance of the
+calling CPU. It is called by the PSCI `CPU_SUSPEND` API
implementation.
-The `MPIDR` (first argument), `affinity level` (third argument) and `state`
-(fifth argument) have a similar meaning as described in the `affinst_on()`
-operation. They are used to identify the affinity instance on which the call
-is made and its current state. This gives the platform port an indication of the
-state transition it must make to perform the requested action. For example, if
-the calling CPU is the last powered on CPU in the cluster, after powering down
-affinity level 0 (CPU), the platform port should power down affinity level 1
-(the cluster) as well.
+The `affinity level` (second argument) and `state` (third argument) have a
+similar meaning as described in the `affinst_on()` operation. They are used to
+identify the affinity instance on which the call is made and its current state.
+This gives the platform port an indication of the state transition it must
+make to perform the requested action. For example, if the calling CPU is the
+last powered on CPU in the cluster, after powering down affinity level 0 (CPU),
+the platform port should power down affinity level 1 (the cluster) as well.
The difference between turning an affinity instance off versus suspending it
is that in the former case, the affinity instance is expected to re-initialize
this CPU to enter the normal world and also provide secure runtime firmware
services.
-The `MPIDR` (first argument), `affinity level` (second argument) and `state`
-(third argument) have a similar meaning as described in the previous operations.
+The `affinity level` (first argument) and `state` (second argument) have a
+similar meaning as described in the previous operations.
#### plat_pm_ops.affinst_on_suspend()
restore the saved state for this CPU to resume execution in the normal world
and also provide secure runtime firmware services.
-The `MPIDR` (first argument), `affinity level` (second argument) and `state`
-(third argument) have a similar meaning as described in the previous operations.
+The `affinity level` (first argument) and `state` (second argument) have a
+similar meaning as described in the previous operations.
BL3-1 platform initialization code must also detect the system topology and
the state of each affinity instance in the topology. This information is
* perform common low level pm functions
******************************************************************************/
typedef struct plat_pm_ops {
- int (*affinst_standby)(unsigned int);
- int (*affinst_on)(unsigned long,
- unsigned long,
- unsigned long,
- unsigned int,
- unsigned int);
- int (*affinst_off)(unsigned long, unsigned int, unsigned int);
- int (*affinst_suspend)(unsigned long,
- unsigned long,
- unsigned long,
- unsigned int,
- unsigned int);
- int (*affinst_on_finish)(unsigned long, unsigned int, unsigned int);
- int (*affinst_suspend_finish)(unsigned long,
- unsigned int,
- unsigned int);
+ int (*affinst_standby)(unsigned int power_state);
+ int (*affinst_on)(unsigned long mpidr,
+ unsigned long sec_entrypoint,
+ unsigned int afflvl,
+ unsigned int state);
+ int (*affinst_off)(unsigned int afflvl, unsigned int state);
+ int (*affinst_suspend)(unsigned long sec_entrypoint,
+ unsigned int afflvl,
+ unsigned int state);
+ int (*affinst_on_finish)(unsigned int afflvl, unsigned int state);
+ int (*affinst_suspend_finish)(unsigned int afflvl,
+ unsigned int state);
void (*system_off)(void) __dead2;
void (*system_reset)(void) __dead2;
} plat_pm_ops_t;
******************************************************************************/
int fvp_affinst_on(unsigned long mpidr,
unsigned long sec_entrypoint,
- unsigned long ns_entrypoint,
unsigned int afflvl,
unsigned int state)
{
* global variables across calls. It will be wise to do flush a write to the
* global to prevent unpredictable results.
******************************************************************************/
-int fvp_affinst_off(unsigned long mpidr,
- unsigned int afflvl,
+int fvp_affinst_off(unsigned int afflvl,
unsigned int state)
{
/* Determine if any platform actions need to be executed */
* global variables across calls. It will be wise to do flush a write to the
* global to prevent unpredictable results.
******************************************************************************/
-int fvp_affinst_suspend(unsigned long mpidr,
- unsigned long sec_entrypoint,
- unsigned long ns_entrypoint,
+int fvp_affinst_suspend(unsigned long sec_entrypoint,
unsigned int afflvl,
unsigned int state)
{
+ unsigned long mpidr;
+
/* Determine if any platform actions need to be executed. */
if (fvp_do_plat_actions(afflvl, state) == -EAGAIN)
return PSCI_E_SUCCESS;
- /* Program the jump address for the target cpu */
- fvp_program_mailbox(read_mpidr_el1(), sec_entrypoint);
+ /* Get the mpidr for this cpu */
+ mpidr = read_mpidr_el1();
+
+ /* Program the jump address for the this cpu */
+ fvp_program_mailbox(mpidr, sec_entrypoint);
/* Program the power controller to enable wakeup interrupts. */
fvp_pwrc_set_wen(mpidr);
* was turned off prior to wakeup and do what's necessary to setup it up
* correctly.
******************************************************************************/
-int fvp_affinst_on_finish(unsigned long mpidr,
- unsigned int afflvl,
+int fvp_affinst_on_finish(unsigned int afflvl,
unsigned int state)
{
int rc = PSCI_E_SUCCESS;
+ unsigned long mpidr;
/* Determine if any platform actions need to be executed. */
if (fvp_do_plat_actions(afflvl, state) == -EAGAIN)
return PSCI_E_SUCCESS;
+ /* Get the mpidr for this cpu */
+ mpidr = read_mpidr_el1();
+
/* Perform the common cluster specific operations */
if (afflvl != MPIDR_AFFLVL0) {
/*
fvp_pwrc_clr_wen(mpidr);
/* Zero the jump address in the mailbox for this cpu */
- fvp_program_mailbox(read_mpidr_el1(), 0);
+ fvp_program_mailbox(mpidr, 0);
/* Enable the gic cpu interface */
arm_gic_cpuif_setup();
* TODO: At the moment we reuse the on finisher and reinitialize the secure
* context. Need to implement a separate suspend finisher.
******************************************************************************/
-int fvp_affinst_suspend_finish(unsigned long mpidr,
- unsigned int afflvl,
+int fvp_affinst_suspend_finish(unsigned int afflvl,
unsigned int state)
{
- return fvp_affinst_on_finish(mpidr, afflvl, state);
+ return fvp_affinst_on_finish(afflvl, state);
}
/*******************************************************************************
******************************************************************************/
int32_t juno_affinst_on(uint64_t mpidr,
uint64_t sec_entrypoint,
- uint64_t ns_entrypoint,
uint32_t afflvl,
uint32_t state)
{
* was turned off prior to wakeup and do what's necessary to setup it up
* correctly.
******************************************************************************/
-int32_t juno_affinst_on_finish(uint64_t mpidr, uint32_t afflvl, uint32_t state)
+int32_t juno_affinst_on_finish(uint32_t afflvl, uint32_t state)
{
+ unsigned long mpidr;
+
/* Determine if any platform actions need to be executed. */
if (juno_do_plat_actions(afflvl, state) == -EAGAIN)
return PSCI_E_SUCCESS;
+ /* Get the mpidr for this cpu */
+ mpidr = read_mpidr_el1();
+
/*
* Perform the common cluster specific operations i.e enable coherency
* if this cluster was off.
* global variables across calls. It will be wise to do flush a write to the
* global to prevent unpredictable results.
******************************************************************************/
-static int32_t juno_affinst_off(uint64_t mpidr, uint32_t afflvl, uint32_t state)
+static int32_t juno_affinst_off(uint32_t afflvl, uint32_t state)
{
/* Determine if any platform actions need to be executed */
if (juno_do_plat_actions(afflvl, state) == -EAGAIN)
* global variables across calls. It will be wise to do flush a write to the
* global to prevent unpredictable results.
******************************************************************************/
-static int32_t juno_affinst_suspend(uint64_t mpidr,
- uint64_t sec_entrypoint,
- uint64_t ns_entrypoint,
+static int32_t juno_affinst_suspend(uint64_t sec_entrypoint,
uint32_t afflvl,
uint32_t state)
{
/*
* Setup mailbox with address for CPU entrypoint when it next powers up.
*/
- juno_program_mailbox(mpidr, sec_entrypoint);
+ juno_program_mailbox(read_mpidr_el1(), sec_entrypoint);
return juno_power_down_common(afflvl);
}
* TODO: At the moment we reuse the on finisher and reinitialize the secure
* context. Need to implement a separate suspend finisher.
******************************************************************************/
-static int32_t juno_affinst_suspend_finish(uint64_t mpidr,
- uint32_t afflvl,
+static int32_t juno_affinst_suspend_finish(uint32_t afflvl,
uint32_t state)
{
- return juno_affinst_on_finish(mpidr, afflvl, state);
+ return juno_affinst_on_finish(afflvl, state);
}
/*******************************************************************************
#include <string.h>
#include "psci_private.h"
-typedef int (*afflvl_off_handler_t)(aff_map_node_t *);
+typedef int (*afflvl_off_handler_t)(aff_map_node_t *node);
/*******************************************************************************
* The next three functions implement a handler for each supported affinity
* Plat. management: Perform platform specific actions to turn this
* cpu off e.g. exit cpu coherency, program the power controller etc.
*/
- return psci_plat_pm_ops->affinst_off(read_mpidr_el1(),
- cpu_node->level,
+ return psci_plat_pm_ops->affinst_off(cpu_node->level,
psci_get_phys_state(cpu_node));
}
* specific bookeeping e.g. turn off interconnect coherency,
* program the power controller etc.
*/
- return psci_plat_pm_ops->affinst_off(read_mpidr_el1(),
- cluster_node->level,
+ return psci_plat_pm_ops->affinst_off(cluster_node->level,
psci_get_phys_state(cluster_node));
}
* Plat. Management : Allow the platform to do its bookeeping
* at this affinity level
*/
- return psci_plat_pm_ops->affinst_off(read_mpidr_el1(),
- system_node->level,
+ return psci_plat_pm_ops->affinst_off(system_node->level,
psci_get_phys_state(system_node));
}
#include <stddef.h>
#include "psci_private.h"
-typedef int (*afflvl_on_handler_t)(unsigned long,
- aff_map_node_t *,
- unsigned long,
- unsigned long);
+typedef int (*afflvl_on_handler_t)(unsigned long target_cpu,
+ aff_map_node_t *node,
+ unsigned long ns_entrypoint,
+ unsigned long context_id);
/*******************************************************************************
* This function checks whether a cpu which has been requested to be turned on
*/
return psci_plat_pm_ops->affinst_on(target_cpu,
psci_entrypoint,
- ns_entrypoint,
cpu_node->level,
psci_get_phys_state(cpu_node));
}
psci_entrypoint = (unsigned long) psci_aff_on_finish_entry;
return psci_plat_pm_ops->affinst_on(target_cpu,
psci_entrypoint,
- ns_entrypoint,
cluster_node->level,
psci_get_phys_state(cluster_node));
}
psci_entrypoint = (unsigned long) psci_aff_on_finish_entry;
return psci_plat_pm_ops->affinst_on(target_cpu,
psci_entrypoint,
- ns_entrypoint,
system_node->level,
psci_get_phys_state(system_node));
}
*
* The affinity level specific handlers are called in descending order i.e. from
* the highest to the lowest affinity level implemented by the platform because
- * to turn on affinity level X it is neccesary to turn on affinity level X + 1
+ * to turn on affinity level X it is necessary to turn on affinity level X + 1
* first.
******************************************************************************/
int psci_afflvl_on(unsigned long target_cpu,
/* Get the physical state of this cpu */
plat_state = get_phys_state(state);
- rc = psci_plat_pm_ops->affinst_on_finish(read_mpidr_el1(),
- cpu_node->level,
+ rc = psci_plat_pm_ops->affinst_on_finish(cpu_node->level,
plat_state);
assert(rc == PSCI_E_SUCCESS);
}
* situation.
*/
plat_state = psci_get_phys_state(cluster_node);
- return psci_plat_pm_ops->affinst_on_finish(read_mpidr_el1(),
- cluster_node->level,
+ return psci_plat_pm_ops->affinst_on_finish(cluster_node->level,
plat_state);
}
* situation.
*/
plat_state = psci_get_phys_state(system_node);
- return psci_plat_pm_ops->affinst_on_finish(read_mpidr_el1(),
- system_node->level,
+ return psci_plat_pm_ops->affinst_on_finish(system_node->level,
plat_state);
}
#include <stddef.h>
#include "psci_private.h"
-typedef int (*afflvl_suspend_handler_t)(aff_map_node_t *,
- unsigned long,
- unsigned long,
- unsigned int);
+typedef int (*afflvl_suspend_handler_t)(aff_map_node_t *node,
+ unsigned long ns_entrypoint,
+ unsigned long context_id,
+ unsigned int power_state);
/*******************************************************************************
* This function saves the power state parameter passed in the current PSCI
* platform defined mailbox with the psci entrypoint,
* program the power controller etc.
*/
- return psci_plat_pm_ops->affinst_suspend(read_mpidr_el1(),
- psci_entrypoint,
- ns_entrypoint,
+ return psci_plat_pm_ops->affinst_suspend(psci_entrypoint,
cpu_node->level,
psci_get_phys_state(cpu_node));
}
*/
plat_state = psci_get_phys_state(cluster_node);
psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry;
- return psci_plat_pm_ops->affinst_suspend(read_mpidr_el1(),
- psci_entrypoint,
- ns_entrypoint,
+ return psci_plat_pm_ops->affinst_suspend(psci_entrypoint,
cluster_node->level,
plat_state);
}
*/
plat_state = psci_get_phys_state(system_node);
psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry;
- return psci_plat_pm_ops->affinst_suspend(read_mpidr_el1(),
- psci_entrypoint,
- ns_entrypoint,
+ return psci_plat_pm_ops->affinst_suspend(psci_entrypoint,
system_node->level,
plat_state);
}
/* Get the physical state of this cpu */
plat_state = get_phys_state(state);
- rc = psci_plat_pm_ops->affinst_suspend_finish(read_mpidr_el1(),
- cpu_node->level,
+ rc = psci_plat_pm_ops->affinst_suspend_finish(cpu_node->level,
plat_state);
assert(rc == PSCI_E_SUCCESS);
}
/* Get the physical state of this cpu */
plat_state = psci_get_phys_state(cluster_node);
- rc = psci_plat_pm_ops->affinst_suspend_finish(read_mpidr_el1(),
- cluster_node->level,
+ rc = psci_plat_pm_ops->affinst_suspend_finish(cluster_node->level,
plat_state);
assert(rc == PSCI_E_SUCCESS);
}
/* Get the physical state of the system */
plat_state = psci_get_phys_state(system_node);
- rc = psci_plat_pm_ops->affinst_suspend_finish(read_mpidr_el1(),
- system_node->level,
+ rc = psci_plat_pm_ops->affinst_suspend_finish(system_node->level,
plat_state);
assert(rc == PSCI_E_SUCCESS);
}