Save 'power_state' early in PSCI CPU_SUSPEND call
authorSoby Mathew <soby.mathew@arm.com>
Tue, 30 Sep 2014 10:19:51 +0000 (11:19 +0100)
committerSoby Mathew <soby.mathew@arm.com>
Fri, 23 Jan 2015 15:14:36 +0000 (15:14 +0000)
This patch adds support to save the "power state" parameter before the
affinity level specific handlers are called in a CPU_SUSPEND call.
This avoids the need to pass the power_state as a parameter to the
handlers and Secure Payload Dispatcher (SPD) suspend spd_pm_ops.
The power_state arguments in the spd_pm_ops operations are now reserved
and must not be used. The SPD can query the relevant power_state fields
by using the psci_get_suspend_afflvl() & psci_get_suspend_stateid() APIs.

NOTE: THIS PATCH WILL BREAK THE SPD_PM_OPS INTERFACE. HENCE THE SECURE
PAYLOAD DISPATCHERS WILL NEED TO BE REWORKED TO USE THE NEW INTERFACE.

Change-Id: I1293d7dc8cf29cfa6a086a009eee41bcbf2f238e

bl32/tsp/tsp_main.c
include/bl31/services/psci.h
services/spd/opteed/opteed_pm.c
services/spd/tspd/tspd_pm.c
services/std_svc/psci/psci_afflvl_suspend.c
services/std_svc/psci/psci_main.c
services/std_svc/psci/psci_private.h

index 2eaca7c9aacd9a275d7d6c4ef9ba645c45f0a96c..c6000e19ecc3e9e7f59441225d1b0437999836bf 100644 (file)
@@ -216,7 +216,7 @@ tsp_args_t *tsp_cpu_off_main(uint64_t arg0,
  * this cpu's architectural state is saved in response to an earlier psci
  * cpu_suspend request.
  ******************************************************************************/
-tsp_args_t *tsp_cpu_suspend_main(uint64_t power_state,
+tsp_args_t *tsp_cpu_suspend_main(uint64_t arg0,
                               uint64_t arg1,
                               uint64_t arg2,
                               uint64_t arg3,
@@ -242,8 +242,6 @@ tsp_args_t *tsp_cpu_suspend_main(uint64_t power_state,
 
 #if LOG_LEVEL >= LOG_LEVEL_INFO
        spin_lock(&console_lock);
-       INFO("TSP: cpu 0x%x suspend request. power state: 0x%x\n",
-               mpidr, power_state);
        INFO("TSP: cpu 0x%x: %d smcs, %d erets %d cpu suspend requests\n",
                mpidr,
                tsp_stats[linear_id].smc_count,
index 26b607c0c9db7d9ed516fe3ed2272d753c5db727..7513326ff00d239fab85099d07789432cdf49a88 100644 (file)
@@ -186,7 +186,7 @@ typedef struct plat_pm_ops {
 typedef struct spd_pm_ops {
        void (*svc_on)(uint64_t target_cpu);
        int32_t (*svc_off)(uint64_t __unused);
-       void (*svc_suspend)(uint64_t power_state);
+       void (*svc_suspend)(uint64_t __unused);
        void (*svc_on_finish)(uint64_t __unused);
        void (*svc_suspend_finish)(uint64_t suspend_level);
        void (*svc_migrate)(uint64_t __unused1, uint64_t __unused2);
index 552d7a0c99af51ac321284bd2a50d171d47e5ed5..37419ec77c35ebc208138be8c8b2f83ed4e2eb4f 100644 (file)
@@ -48,7 +48,7 @@ static void opteed_cpu_on_handler(uint64_t target_cpu)
  * This cpu is being turned off. Allow the OPTEED/OPTEE to perform any actions
  * needed
  ******************************************************************************/
-static int32_t opteed_cpu_off_handler(uint64_t cookie)
+static int32_t opteed_cpu_off_handler(uint64_t unused)
 {
        int32_t rc = 0;
        uint64_t mpidr = read_mpidr();
@@ -82,7 +82,7 @@ static int32_t opteed_cpu_off_handler(uint64_t cookie)
  * This cpu is being suspended. S-EL1 state must have been saved in the
  * resident cpu (mpidr format) if it is a UP/UP migratable OPTEE.
  ******************************************************************************/
-static void opteed_cpu_suspend_handler(uint64_t power_state)
+static void opteed_cpu_suspend_handler(uint64_t unused)
 {
        int32_t rc = 0;
        uint64_t mpidr = read_mpidr();
@@ -92,10 +92,7 @@ static void opteed_cpu_suspend_handler(uint64_t power_state)
        assert(optee_vectors);
        assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
-       /* Program the entry point, power_state parameter and enter OPTEE */
-       write_ctx_reg(get_gpregs_ctx(&optee_ctx->cpu_ctx),
-                     CTX_GPREG_X0,
-                     power_state);
+       /* Program the entry point and enter OPTEE */
        cm_set_elr_el3(SECURE, (uint64_t) &optee_vectors->cpu_suspend_entry);
        rc = opteed_synchronous_sp_entry(optee_ctx);
 
@@ -116,7 +113,7 @@ static void opteed_cpu_suspend_handler(uint64_t power_state)
  * after initialising minimal architectural state that guarantees safe
  * execution.
  ******************************************************************************/
-static void opteed_cpu_on_finish_handler(uint64_t cookie)
+static void opteed_cpu_on_finish_handler(uint64_t unused)
 {
        int32_t rc = 0;
        uint64_t mpidr = read_mpidr();
index 165528537e059bdcad5859bdf92a86808747de35..17abaea6832d7e7b5aea07dd867c4f839a6e48aa 100644 (file)
@@ -49,7 +49,7 @@ static void tspd_cpu_on_handler(uint64_t target_cpu)
  * This cpu is being turned off. Allow the TSPD/TSP to perform any actions
  * needed
  ******************************************************************************/
-static int32_t tspd_cpu_off_handler(uint64_t cookie)
+static int32_t tspd_cpu_off_handler(uint64_t unused)
 {
        int32_t rc = 0;
        uint64_t mpidr = read_mpidr();
@@ -83,7 +83,7 @@ static int32_t tspd_cpu_off_handler(uint64_t cookie)
  * This cpu is being suspended. S-EL1 state must have been saved in the
  * resident cpu (mpidr format) if it is a UP/UP migratable TSP.
  ******************************************************************************/
-static void tspd_cpu_suspend_handler(uint64_t power_state)
+static void tspd_cpu_suspend_handler(uint64_t unused)
 {
        int32_t rc = 0;
        uint64_t mpidr = read_mpidr();
@@ -93,10 +93,7 @@ static void tspd_cpu_suspend_handler(uint64_t power_state)
        assert(tsp_vectors);
        assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_ON);
 
-       /* Program the entry point, power_state parameter and enter the TSP */
-       write_ctx_reg(get_gpregs_ctx(&tsp_ctx->cpu_ctx),
-                     CTX_GPREG_X0,
-                     power_state);
+       /* Program the entry point and enter the TSP */
        cm_set_elr_el3(SECURE, (uint64_t) &tsp_vectors->cpu_suspend_entry);
        rc = tspd_synchronous_sp_entry(tsp_ctx);
 
@@ -117,7 +114,7 @@ static void tspd_cpu_suspend_handler(uint64_t power_state)
  * after initialising minimal architectural state that guarantees safe
  * execution.
  ******************************************************************************/
-static void tspd_cpu_on_finish_handler(uint64_t cookie)
+static void tspd_cpu_on_finish_handler(uint64_t unused)
 {
        int32_t rc = 0;
        uint64_t mpidr = read_mpidr();
index 4988e677af28c5072229f9db685a9bde34ad0d07..942e9a122fcdd9388f3cedcee5f41175b33cc12c 100644 (file)
@@ -40,8 +40,7 @@
 #include <stddef.h>
 #include "psci_private.h"
 
-typedef int (*afflvl_suspend_handler_t)(aff_map_node_t *node,
-                                     unsigned int power_state);
+typedef int (*afflvl_suspend_handler_t)(aff_map_node_t *node);
 
 /*******************************************************************************
  * This function saves the power state parameter passed in the current PSCI
@@ -103,17 +102,13 @@ int psci_get_suspend_stateid_by_mpidr(unsigned long mpidr)
  * The next three functions implement a handler for each supported affinity
  * level which is called when that affinity level is about to be suspended.
  ******************************************************************************/
-static int psci_afflvl0_suspend(aff_map_node_t *cpu_node,
-                               unsigned int power_state)
+static int psci_afflvl0_suspend(aff_map_node_t *cpu_node)
 {
        unsigned long psci_entrypoint;
 
        /* Sanity check to safeguard against data corruption */
        assert(cpu_node->level == MPIDR_AFFLVL0);
 
-       /* Save PSCI power state parameter for the core in suspend context */
-       psci_set_suspend_power_state(power_state);
-
        /*
         * Generic management: Allow the Secure world to suspend itself
         */
@@ -124,8 +119,7 @@ static int psci_afflvl0_suspend(aff_map_node_t *cpu_node,
         * error, it's expected to assert within
         */
        if (psci_spd_pm && psci_spd_pm->svc_suspend)
-               psci_spd_pm->svc_suspend(power_state);
-
+               psci_spd_pm->svc_suspend(0);
 
        /* Set the secure world (EL3) re-entry point after BL1 */
        psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry;
@@ -150,8 +144,7 @@ static int psci_afflvl0_suspend(aff_map_node_t *cpu_node,
                                                 psci_get_phys_state(cpu_node));
 }
 
-static int psci_afflvl1_suspend(aff_map_node_t *cluster_node,
-                               unsigned int power_state)
+static int psci_afflvl1_suspend(aff_map_node_t *cluster_node)
 {
        unsigned int plat_state;
        unsigned long psci_entrypoint;
@@ -184,8 +177,7 @@ static int psci_afflvl1_suspend(aff_map_node_t *cluster_node,
 }
 
 
-static int psci_afflvl2_suspend(aff_map_node_t *system_node,
-                               unsigned int power_state)
+static int psci_afflvl2_suspend(aff_map_node_t *system_node)
 {
        unsigned int plat_state;
        unsigned long psci_entrypoint;
@@ -238,8 +230,7 @@ static const afflvl_suspend_handler_t psci_afflvl_suspend_handlers[] = {
  ******************************************************************************/
 static int psci_call_suspend_handlers(aff_map_node_t *mpidr_nodes[],
                                      int start_afflvl,
-                                     int end_afflvl,
-                                     unsigned int power_state)
+                                     int end_afflvl)
 {
        int rc = PSCI_E_INVALID_PARAMS, level;
        aff_map_node_t *node;
@@ -254,8 +245,7 @@ static int psci_call_suspend_handlers(aff_map_node_t *mpidr_nodes[],
                 * of restoring what we might have torn down at
                 * lower affinity levels.
                 */
-               rc = psci_afflvl_suspend_handlers[level](node,
-                                                        power_state);
+               rc = psci_afflvl_suspend_handlers[level](node);
                if (rc != PSCI_E_SUCCESS)
                        break;
        }
@@ -283,7 +273,6 @@ static int psci_call_suspend_handlers(aff_map_node_t *mpidr_nodes[],
  * first.
  ******************************************************************************/
 int psci_afflvl_suspend(entry_point_info_t *ep,
-                       unsigned int power_state,
                        int start_afflvl,
                        int end_afflvl)
 {
@@ -339,8 +328,7 @@ int psci_afflvl_suspend(entry_point_info_t *ep,
        /* Perform generic, architecture and platform specific handling */
        rc = psci_call_suspend_handlers(mpidr_nodes,
                                        start_afflvl,
-                                       end_afflvl,
-                                       power_state);
+                                       end_afflvl);
 
        /*
         * Invalidate the entry for the highest affinity level stashed earlier.
index 7fce5faf06b91ec699882957084ecf0b77f3c9ce..506f5920da142afdc704c77985dfa431d0add73a 100644 (file)
@@ -125,18 +125,23 @@ int psci_cpu_suspend(unsigned int power_state,
        if (rc != PSCI_E_SUCCESS)
                return rc;
 
+       /* Save PSCI power state parameter for the core in suspend context */
+       psci_set_suspend_power_state(power_state);
+
        /*
         * Do what is needed to enter the power down state. Upon success,
         * enter the final wfi which will power down this cpu else return
         * an error.
         */
        rc = psci_afflvl_suspend(&ep,
-                                power_state,
                                 MPIDR_AFFLVL0,
                                 target_afflvl);
        if (rc == PSCI_E_SUCCESS)
                psci_power_down_wfi();
        assert(rc == PSCI_E_INVALID_PARAMS);
+
+       /* Reset PSCI power state parameter for the core. */
+       psci_set_suspend_power_state(PSCI_INVALID_DATA);
        return rc;
 }
 
index 3a4ee3c8d8acb71f9b215f91014ab37701bbddab..98d5d92a8c7f283fb5ffbc25500a6502164a042f 100644 (file)
@@ -139,7 +139,6 @@ int psci_afflvl_off(int, int);
 
 /* Private exported functions from psci_affinity_suspend.c */
 int psci_afflvl_suspend(entry_point_info_t *ep,
-                       unsigned int power_state,
                        int start_afflvl,
                        int end_afflvl);