blob: 2a6644b68837a55fa963eea8b2607bb96e1eed6d [file] [log] [blame]
Achin Gupta4f6ad662013-10-25 09:08:21 +01001/*
dp-arm66abfbe2017-01-31 13:01:04 +00002 * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
Achin Gupta4f6ad662013-10-25 09:08:21 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Achin Gupta4f6ad662013-10-25 09:08:21 +01005 */
6
Dan Handley2bd4ef22014-04-09 13:14:54 +01007#include <arch.h>
Achin Gupta4f6ad662013-10-25 09:08:21 +01008#include <arch_helpers.h>
Dan Handley2bd4ef22014-04-09 13:14:54 +01009#include <assert.h>
Soby Mathew96168382014-12-17 14:47:57 +000010#include <debug.h>
11#include <platform.h>
dp-arm3cac7862016-09-19 11:18:44 +010012#include <pmf.h>
13#include <runtime_instr.h>
Soby Mathewd0194872016-04-29 19:01:30 +010014#include <smcc.h>
Soby Mathew981487a2015-07-13 14:10:57 +010015#include <string.h>
Dan Handley714a0d22014-04-09 13:13:04 +010016#include "psci_private.h"
Achin Gupta4f6ad662013-10-25 09:08:21 +010017
18/*******************************************************************************
19 * PSCI frontend api for servicing SMCs. Described in the PSCI spec.
20 ******************************************************************************/
Soby Mathew011ca182015-07-29 17:05:03 +010021int psci_cpu_on(u_register_t target_cpu,
22 uintptr_t entrypoint,
23 u_register_t context_id)
Achin Gupta4f6ad662013-10-25 09:08:21 +010024
25{
26 int rc;
Soby Mathew8595b872015-01-06 15:36:38 +000027 entry_point_info_t ep;
Achin Gupta4f6ad662013-10-25 09:08:21 +010028
29 /* Determine if the cpu exists of not */
Soby Mathew981487a2015-07-13 14:10:57 +010030 rc = psci_validate_mpidr(target_cpu);
31 if (rc != PSCI_E_SUCCESS)
Soby Mathew74e52a72014-10-02 16:56:51 +010032 return PSCI_E_INVALID_PARAMS;
Soby Mathew74e52a72014-10-02 16:56:51 +010033
Soby Mathewf1f97a12015-07-15 12:13:26 +010034 /* Validate the entry point and get the entry_point_info */
35 rc = psci_validate_entry_point(&ep, entrypoint, context_id);
Soby Mathew8595b872015-01-06 15:36:38 +000036 if (rc != PSCI_E_SUCCESS)
37 return rc;
38
Soby Mathew8595b872015-01-06 15:36:38 +000039 /*
Soby Mathew981487a2015-07-13 14:10:57 +010040 * To turn this cpu on, specify which power
Achin Gupta0959db52013-12-02 17:33:04 +000041 * levels need to be turned on
42 */
Sandrine Bailleux7497bff2016-04-25 09:28:43 +010043 return psci_cpu_on_start(target_cpu, &ep);
Achin Gupta4f6ad662013-10-25 09:08:21 +010044}
45
46unsigned int psci_version(void)
47{
48 return PSCI_MAJOR_VER | PSCI_MINOR_VER;
49}
50
51int psci_cpu_suspend(unsigned int power_state,
Soby Mathew011ca182015-07-29 17:05:03 +010052 uintptr_t entrypoint,
53 u_register_t context_id)
Achin Gupta4f6ad662013-10-25 09:08:21 +010054{
55 int rc;
Soby Mathew981487a2015-07-13 14:10:57 +010056 unsigned int target_pwrlvl, is_power_down_state;
Soby Mathew8595b872015-01-06 15:36:38 +000057 entry_point_info_t ep;
Soby Mathew981487a2015-07-13 14:10:57 +010058 psci_power_state_t state_info = { {PSCI_LOCAL_STATE_RUN} };
59 plat_local_state_t cpu_pd_state;
Achin Gupta4f6ad662013-10-25 09:08:21 +010060
Soby Mathew981487a2015-07-13 14:10:57 +010061 /* Validate the power_state parameter */
62 rc = psci_validate_power_state(power_state, &state_info);
63 if (rc != PSCI_E_SUCCESS) {
64 assert(rc == PSCI_E_INVALID_PARAMS);
65 return rc;
66 }
Vikram Kanigirif100f412014-04-01 19:26:26 +010067
Soby Mathew981487a2015-07-13 14:10:57 +010068 /*
69 * Get the value of the state type bit from the power state parameter.
70 */
71 is_power_down_state = psci_get_pstate_type(power_state);
Achin Gupta4f6ad662013-10-25 09:08:21 +010072
Soby Mathew981487a2015-07-13 14:10:57 +010073 /* Sanity check the requested suspend levels */
Soby Mathew24ab34f2016-05-03 17:11:42 +010074 assert(psci_validate_suspend_req(&state_info, is_power_down_state)
Soby Mathew981487a2015-07-13 14:10:57 +010075 == PSCI_E_SUCCESS);
Soby Mathew74e52a72014-10-02 16:56:51 +010076
Soby Mathew981487a2015-07-13 14:10:57 +010077 target_pwrlvl = psci_find_target_suspend_lvl(&state_info);
Sandrine Bailleuxf9f3bbf2016-06-22 16:35:01 +010078 if (target_pwrlvl == PSCI_INVALID_PWR_LVL) {
79 ERROR("Invalid target power level for suspend operation\n");
80 panic();
81 }
Soby Mathew981487a2015-07-13 14:10:57 +010082
83 /* Fast path for CPU standby.*/
84 if (is_cpu_standby_req(is_power_down_state, target_pwrlvl)) {
85 if (!psci_plat_pm_ops->cpu_standby)
Soby Mathew74e52a72014-10-02 16:56:51 +010086 return PSCI_E_INVALID_PARAMS;
Soby Mathew74e52a72014-10-02 16:56:51 +010087
Soby Mathew981487a2015-07-13 14:10:57 +010088 /*
89 * Set the state of the CPU power domain to the platform
90 * specific retention state and enter the standby state.
91 */
92 cpu_pd_state = state_info.pwr_domain_state[PSCI_CPU_PWR_LVL];
93 psci_set_cpu_local_state(cpu_pd_state);
Yatharth Kochar241ec6c2016-05-09 18:26:35 +010094
95#if ENABLE_PSCI_STAT
dp-arm66abfbe2017-01-31 13:01:04 +000096 plat_psci_stat_accounting_start(&state_info);
Yatharth Kochar241ec6c2016-05-09 18:26:35 +010097#endif
98
dp-arm3cac7862016-09-19 11:18:44 +010099#if ENABLE_RUNTIME_INSTRUMENTATION
100 PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
101 RT_INSTR_ENTER_HW_LOW_PWR,
102 PMF_NO_CACHE_MAINT);
103#endif
104
Soby Mathew981487a2015-07-13 14:10:57 +0100105 psci_plat_pm_ops->cpu_standby(cpu_pd_state);
Achin Gupta42c52802014-05-09 19:32:25 +0100106
Soby Mathew981487a2015-07-13 14:10:57 +0100107 /* Upon exit from standby, set the state back to RUN. */
108 psci_set_cpu_local_state(PSCI_LOCAL_STATE_RUN);
Achin Gupta42c52802014-05-09 19:32:25 +0100109
dp-arm3cac7862016-09-19 11:18:44 +0100110#if ENABLE_RUNTIME_INSTRUMENTATION
111 PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
112 RT_INSTR_EXIT_HW_LOW_PWR,
113 PMF_NO_CACHE_MAINT);
114#endif
115
Yatharth Kochar241ec6c2016-05-09 18:26:35 +0100116#if ENABLE_PSCI_STAT
dp-arm66abfbe2017-01-31 13:01:04 +0000117 plat_psci_stat_accounting_stop(&state_info);
Yatharth Kochar241ec6c2016-05-09 18:26:35 +0100118
119 /* Update PSCI stats */
dp-arm66abfbe2017-01-31 13:01:04 +0000120 psci_stats_update_pwr_up(PSCI_CPU_PWR_LVL, &state_info);
Yatharth Kochar241ec6c2016-05-09 18:26:35 +0100121#endif
122
Soby Mathew74e52a72014-10-02 16:56:51 +0100123 return PSCI_E_SUCCESS;
Vikram Kanigiri3b7c59b2014-03-21 11:57:10 +0000124 }
Achin Gupta4f6ad662013-10-25 09:08:21 +0100125
Achin Gupta42c52802014-05-09 19:32:25 +0100126 /*
Soby Mathew981487a2015-07-13 14:10:57 +0100127 * If a power down state has been requested, we need to verify entry
128 * point and program entry information.
Soby Mathew8595b872015-01-06 15:36:38 +0000129 */
Soby Mathew981487a2015-07-13 14:10:57 +0100130 if (is_power_down_state) {
Soby Mathewf1f97a12015-07-15 12:13:26 +0100131 rc = psci_validate_entry_point(&ep, entrypoint, context_id);
Soby Mathew981487a2015-07-13 14:10:57 +0100132 if (rc != PSCI_E_SUCCESS)
133 return rc;
134 }
Soby Mathewf5121572014-09-30 11:19:51 +0100135
Soby Mathew8595b872015-01-06 15:36:38 +0000136 /*
Achin Gupta42c52802014-05-09 19:32:25 +0100137 * Do what is needed to enter the power down state. Upon success,
Soby Mathew981487a2015-07-13 14:10:57 +0100138 * enter the final wfi which will power down this CPU. This function
139 * might return if the power down was abandoned for any reason, e.g.
140 * arrival of an interrupt
Achin Gupta42c52802014-05-09 19:32:25 +0100141 */
Soby Mathew981487a2015-07-13 14:10:57 +0100142 psci_cpu_suspend_start(&ep,
143 target_pwrlvl,
144 &state_info,
145 is_power_down_state);
Soby Mathew74e52a72014-10-02 16:56:51 +0100146
Soby Mathew74e52a72014-10-02 16:56:51 +0100147 return PSCI_E_SUCCESS;
Achin Gupta4f6ad662013-10-25 09:08:21 +0100148}
149
Soby Mathew011ca182015-07-29 17:05:03 +0100150
151int psci_system_suspend(uintptr_t entrypoint, u_register_t context_id)
Soby Mathew96168382014-12-17 14:47:57 +0000152{
153 int rc;
Soby Mathew981487a2015-07-13 14:10:57 +0100154 psci_power_state_t state_info;
Soby Mathew96168382014-12-17 14:47:57 +0000155 entry_point_info_t ep;
156
Soby Mathew96168382014-12-17 14:47:57 +0000157 /* Check if the current CPU is the last ON CPU in the system */
158 if (!psci_is_last_on_cpu())
159 return PSCI_E_DENIED;
160
Soby Mathewf1f97a12015-07-15 12:13:26 +0100161 /* Validate the entry point and get the entry_point_info */
162 rc = psci_validate_entry_point(&ep, entrypoint, context_id);
Soby Mathew96168382014-12-17 14:47:57 +0000163 if (rc != PSCI_E_SUCCESS)
164 return rc;
165
Soby Mathew981487a2015-07-13 14:10:57 +0100166 /* Query the psci_power_state for system suspend */
167 psci_query_sys_suspend_pwrstate(&state_info);
Soby Mathew96168382014-12-17 14:47:57 +0000168
Soby Mathew981487a2015-07-13 14:10:57 +0100169 /* Ensure that the psci_power_state makes sense */
170 assert(psci_find_target_suspend_lvl(&state_info) == PLAT_MAX_PWR_LVL);
171 assert(psci_validate_suspend_req(&state_info, PSTATE_TYPE_POWERDOWN)
172 == PSCI_E_SUCCESS);
173 assert(is_local_state_off(state_info.pwr_domain_state[PLAT_MAX_PWR_LVL]));
Soby Mathew96168382014-12-17 14:47:57 +0000174
175 /*
Soby Mathew981487a2015-07-13 14:10:57 +0100176 * Do what is needed to enter the system suspend state. This function
177 * might return if the power down was abandoned for any reason, e.g.
178 * arrival of an interrupt
Soby Mathew96168382014-12-17 14:47:57 +0000179 */
Soby Mathew981487a2015-07-13 14:10:57 +0100180 psci_cpu_suspend_start(&ep,
181 PLAT_MAX_PWR_LVL,
182 &state_info,
183 PSTATE_TYPE_POWERDOWN);
Soby Mathew96168382014-12-17 14:47:57 +0000184
Soby Mathew96168382014-12-17 14:47:57 +0000185 return PSCI_E_SUCCESS;
186}
187
Achin Gupta4f6ad662013-10-25 09:08:21 +0100188int psci_cpu_off(void)
189{
190 int rc;
Soby Mathew011ca182015-07-29 17:05:03 +0100191 unsigned int target_pwrlvl = PLAT_MAX_PWR_LVL;
Achin Gupta4f6ad662013-10-25 09:08:21 +0100192
Achin Gupta4f6ad662013-10-25 09:08:21 +0100193 /*
Soby Mathew981487a2015-07-13 14:10:57 +0100194 * Do what is needed to power off this CPU and possible higher power
195 * levels if it able to do so. Upon success, enter the final wfi
196 * which will power down this CPU.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100197 */
Soby Mathew981487a2015-07-13 14:10:57 +0100198 rc = psci_do_cpu_off(target_pwrlvl);
Achin Gupta4f6ad662013-10-25 09:08:21 +0100199
Achin Gupta3140a9e2013-12-02 16:23:12 +0000200 /*
201 * The only error cpu_off can return is E_DENIED. So check if that's
202 * indeed the case.
203 */
Soby Mathew24ab34f2016-05-03 17:11:42 +0100204 assert(rc == PSCI_E_DENIED);
Achin Gupta4f6ad662013-10-25 09:08:21 +0100205
206 return rc;
207}
208
Soby Mathew011ca182015-07-29 17:05:03 +0100209int psci_affinity_info(u_register_t target_affinity,
Achin Gupta4f6ad662013-10-25 09:08:21 +0100210 unsigned int lowest_affinity_level)
211{
Soby Mathew981487a2015-07-13 14:10:57 +0100212 unsigned int target_idx;
Achin Gupta4f6ad662013-10-25 09:08:21 +0100213
Soby Mathew981487a2015-07-13 14:10:57 +0100214 /* We dont support level higher than PSCI_CPU_PWR_LVL */
215 if (lowest_affinity_level > PSCI_CPU_PWR_LVL)
216 return PSCI_E_INVALID_PARAMS;
Achin Gupta4f6ad662013-10-25 09:08:21 +0100217
Soby Mathew981487a2015-07-13 14:10:57 +0100218 /* Calculate the cpu index of the target */
219 target_idx = plat_core_pos_by_mpidr(target_affinity);
220 if (target_idx == -1)
221 return PSCI_E_INVALID_PARAMS;
Achin Gupta75f73672013-12-05 16:33:10 +0000222
Soby Mathew981487a2015-07-13 14:10:57 +0100223 return psci_get_aff_info_state_by_idx(target_idx);
Achin Gupta4f6ad662013-10-25 09:08:21 +0100224}
225
Soby Mathew011ca182015-07-29 17:05:03 +0100226int psci_migrate(u_register_t target_cpu)
Achin Gupta4f6ad662013-10-25 09:08:21 +0100227{
Soby Mathew110fe362014-10-23 10:35:34 +0100228 int rc;
Soby Mathew011ca182015-07-29 17:05:03 +0100229 u_register_t resident_cpu_mpidr;
Soby Mathew110fe362014-10-23 10:35:34 +0100230
231 rc = psci_spd_migrate_info(&resident_cpu_mpidr);
232 if (rc != PSCI_TOS_UP_MIG_CAP)
233 return (rc == PSCI_TOS_NOT_UP_MIG_CAP) ?
234 PSCI_E_DENIED : PSCI_E_NOT_SUPPORTED;
235
236 /*
237 * Migrate should only be invoked on the CPU where
238 * the Secure OS is resident.
239 */
240 if (resident_cpu_mpidr != read_mpidr_el1())
241 return PSCI_E_NOT_PRESENT;
242
243 /* Check the validity of the specified target cpu */
Soby Mathew981487a2015-07-13 14:10:57 +0100244 rc = psci_validate_mpidr(target_cpu);
Soby Mathew110fe362014-10-23 10:35:34 +0100245 if (rc != PSCI_E_SUCCESS)
246 return PSCI_E_INVALID_PARAMS;
247
248 assert(psci_spd_pm && psci_spd_pm->svc_migrate);
249
250 rc = psci_spd_pm->svc_migrate(read_mpidr_el1(), target_cpu);
251 assert(rc == PSCI_E_SUCCESS || rc == PSCI_E_INTERN_FAIL);
252
253 return rc;
Achin Gupta4f6ad662013-10-25 09:08:21 +0100254}
255
Soby Mathew110fe362014-10-23 10:35:34 +0100256int psci_migrate_info_type(void)
Achin Gupta4f6ad662013-10-25 09:08:21 +0100257{
Soby Mathew011ca182015-07-29 17:05:03 +0100258 u_register_t resident_cpu_mpidr;
Soby Mathew110fe362014-10-23 10:35:34 +0100259
260 return psci_spd_migrate_info(&resident_cpu_mpidr);
Achin Gupta4f6ad662013-10-25 09:08:21 +0100261}
262
Soby Mathew110fe362014-10-23 10:35:34 +0100263long psci_migrate_info_up_cpu(void)
Achin Gupta4f6ad662013-10-25 09:08:21 +0100264{
Soby Mathew011ca182015-07-29 17:05:03 +0100265 u_register_t resident_cpu_mpidr;
Soby Mathew110fe362014-10-23 10:35:34 +0100266 int rc;
267
Achin Gupta4f6ad662013-10-25 09:08:21 +0100268 /*
Soby Mathew110fe362014-10-23 10:35:34 +0100269 * Return value of this depends upon what
270 * psci_spd_migrate_info() returns.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100271 */
Soby Mathew110fe362014-10-23 10:35:34 +0100272 rc = psci_spd_migrate_info(&resident_cpu_mpidr);
273 if (rc != PSCI_TOS_NOT_UP_MIG_CAP && rc != PSCI_TOS_UP_MIG_CAP)
274 return PSCI_E_INVALID_PARAMS;
275
276 return resident_cpu_mpidr;
Achin Gupta4f6ad662013-10-25 09:08:21 +0100277}
278
Jeenu Viswambharan7f03e9d92016-08-03 15:54:50 +0100279int psci_node_hw_state(u_register_t target_cpu,
280 unsigned int power_level)
281{
282 int rc;
283
284 /* Validate target_cpu */
285 rc = psci_validate_mpidr(target_cpu);
286 if (rc != PSCI_E_SUCCESS)
287 return PSCI_E_INVALID_PARAMS;
288
289 /* Validate power_level against PLAT_MAX_PWR_LVL */
290 if (power_level > PLAT_MAX_PWR_LVL)
291 return PSCI_E_INVALID_PARAMS;
292
293 /*
294 * Dispatch this call to platform to query power controller, and pass on
295 * to the caller what it returns
296 */
297 assert(psci_plat_pm_ops->get_node_hw_state);
298 rc = psci_plat_pm_ops->get_node_hw_state(target_cpu, power_level);
299 assert((rc >= HW_ON && rc <= HW_STANDBY) || rc == PSCI_E_NOT_SUPPORTED
300 || rc == PSCI_E_INVALID_PARAMS);
301 return rc;
302}
303
Soby Mathew6cdddaf2015-01-07 11:10:22 +0000304int psci_features(unsigned int psci_fid)
305{
Soby Mathew011ca182015-07-29 17:05:03 +0100306 unsigned int local_caps = psci_caps;
Soby Mathew6cdddaf2015-01-07 11:10:22 +0000307
308 /* Check if it is a 64 bit function */
309 if (((psci_fid >> FUNCID_CC_SHIFT) & FUNCID_CC_MASK) == SMC_64)
310 local_caps &= PSCI_CAP_64BIT_MASK;
311
312 /* Check for invalid fid */
313 if (!(is_std_svc_call(psci_fid) && is_valid_fast_smc(psci_fid)
314 && is_psci_fid(psci_fid)))
315 return PSCI_E_NOT_SUPPORTED;
316
317
318 /* Check if the psci fid is supported or not */
319 if (!(local_caps & define_psci_cap(psci_fid)))
320 return PSCI_E_NOT_SUPPORTED;
321
322 /* Format the feature flags */
323 if (psci_fid == PSCI_CPU_SUSPEND_AARCH32 ||
324 psci_fid == PSCI_CPU_SUSPEND_AARCH64) {
325 /*
Soby Mathew981487a2015-07-13 14:10:57 +0100326 * The trusted firmware does not support OS Initiated Mode.
Soby Mathew6cdddaf2015-01-07 11:10:22 +0000327 */
Soby Mathew981487a2015-07-13 14:10:57 +0100328 return (FF_PSTATE << FF_PSTATE_SHIFT) |
Soby Mathew6cdddaf2015-01-07 11:10:22 +0000329 ((!FF_SUPPORTS_OS_INIT_MODE) << FF_MODE_SUPPORT_SHIFT);
330 }
331
332 /* Return 0 for all other fid's */
333 return PSCI_E_SUCCESS;
334}
335
Jeenu Viswambharancaa84932014-02-06 10:36:15 +0000336/*******************************************************************************
337 * PSCI top level handler for servicing SMCs.
338 ******************************************************************************/
Soby Mathewd0194872016-04-29 19:01:30 +0100339u_register_t psci_smc_handler(uint32_t smc_fid,
Soby Mathewa0fedc42016-06-16 14:52:04 +0100340 u_register_t x1,
341 u_register_t x2,
342 u_register_t x3,
343 u_register_t x4,
Jeenu Viswambharancaa84932014-02-06 10:36:15 +0000344 void *cookie,
345 void *handle,
Soby Mathewa0fedc42016-06-16 14:52:04 +0100346 u_register_t flags)
Jeenu Viswambharancaa84932014-02-06 10:36:15 +0000347{
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100348 if (is_caller_secure(flags))
Soby Mathewd0194872016-04-29 19:01:30 +0100349 return SMC_UNK;
Jeenu Viswambharancaa84932014-02-06 10:36:15 +0000350
Soby Mathew61e615b2015-01-15 11:49:49 +0000351 /* Check the fid against the capabilities */
352 if (!(psci_caps & define_psci_cap(smc_fid)))
Soby Mathewd0194872016-04-29 19:01:30 +0100353 return SMC_UNK;
Soby Mathew61e615b2015-01-15 11:49:49 +0000354
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100355 if (((smc_fid >> FUNCID_CC_SHIFT) & FUNCID_CC_MASK) == SMC_32) {
356 /* 32-bit PSCI function, clear top parameter bits */
Jeenu Viswambharancaa84932014-02-06 10:36:15 +0000357
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100358 x1 = (uint32_t)x1;
359 x2 = (uint32_t)x2;
360 x3 = (uint32_t)x3;
Jeenu Viswambharancaa84932014-02-06 10:36:15 +0000361
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100362 switch (smc_fid) {
363 case PSCI_VERSION:
Soby Mathewd0194872016-04-29 19:01:30 +0100364 return psci_version();
Jeenu Viswambharancaa84932014-02-06 10:36:15 +0000365
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100366 case PSCI_CPU_OFF:
Soby Mathewd0194872016-04-29 19:01:30 +0100367 return psci_cpu_off();
Jeenu Viswambharancaa84932014-02-06 10:36:15 +0000368
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100369 case PSCI_CPU_SUSPEND_AARCH32:
Soby Mathewd0194872016-04-29 19:01:30 +0100370 return psci_cpu_suspend(x1, x2, x3);
Jeenu Viswambharancaa84932014-02-06 10:36:15 +0000371
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100372 case PSCI_CPU_ON_AARCH32:
Soby Mathewd0194872016-04-29 19:01:30 +0100373 return psci_cpu_on(x1, x2, x3);
Jeenu Viswambharancaa84932014-02-06 10:36:15 +0000374
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100375 case PSCI_AFFINITY_INFO_AARCH32:
Soby Mathewd0194872016-04-29 19:01:30 +0100376 return psci_affinity_info(x1, x2);
Jeenu Viswambharancaa84932014-02-06 10:36:15 +0000377
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100378 case PSCI_MIG_AARCH32:
Soby Mathewd0194872016-04-29 19:01:30 +0100379 return psci_migrate(x1);
Jeenu Viswambharancaa84932014-02-06 10:36:15 +0000380
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100381 case PSCI_MIG_INFO_TYPE:
Soby Mathewd0194872016-04-29 19:01:30 +0100382 return psci_migrate_info_type();
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100383
384 case PSCI_MIG_INFO_UP_CPU_AARCH32:
Soby Mathewd0194872016-04-29 19:01:30 +0100385 return psci_migrate_info_up_cpu();
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100386
Jeenu Viswambharan7f03e9d92016-08-03 15:54:50 +0100387 case PSCI_NODE_HW_STATE_AARCH32:
388 return psci_node_hw_state(x1, x2);
389
Soby Mathew96168382014-12-17 14:47:57 +0000390 case PSCI_SYSTEM_SUSPEND_AARCH32:
Soby Mathewd0194872016-04-29 19:01:30 +0100391 return psci_system_suspend(x1, x2);
Soby Mathew96168382014-12-17 14:47:57 +0000392
Juan Castillo4dc4a472014-08-12 11:17:06 +0100393 case PSCI_SYSTEM_OFF:
394 psci_system_off();
395 /* We should never return from psci_system_off() */
396
397 case PSCI_SYSTEM_RESET:
398 psci_system_reset();
399 /* We should never return from psci_system_reset() */
400
Soby Mathew6cdddaf2015-01-07 11:10:22 +0000401 case PSCI_FEATURES:
Soby Mathewd0194872016-04-29 19:01:30 +0100402 return psci_features(x1);
Soby Mathew6cdddaf2015-01-07 11:10:22 +0000403
Yatharth Kochar241ec6c2016-05-09 18:26:35 +0100404#if ENABLE_PSCI_STAT
405 case PSCI_STAT_RESIDENCY_AARCH32:
Soby Mathewd0194872016-04-29 19:01:30 +0100406 return psci_stat_residency(x1, x2);
Yatharth Kochar241ec6c2016-05-09 18:26:35 +0100407
408 case PSCI_STAT_COUNT_AARCH32:
Soby Mathewd0194872016-04-29 19:01:30 +0100409 return psci_stat_count(x1, x2);
Yatharth Kochar241ec6c2016-05-09 18:26:35 +0100410#endif
411
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100412 default:
413 break;
414 }
415 } else {
416 /* 64-bit PSCI function */
417
418 switch (smc_fid) {
419 case PSCI_CPU_SUSPEND_AARCH64:
Soby Mathewd0194872016-04-29 19:01:30 +0100420 return psci_cpu_suspend(x1, x2, x3);
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100421
422 case PSCI_CPU_ON_AARCH64:
Soby Mathewd0194872016-04-29 19:01:30 +0100423 return psci_cpu_on(x1, x2, x3);
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100424
425 case PSCI_AFFINITY_INFO_AARCH64:
Soby Mathewd0194872016-04-29 19:01:30 +0100426 return psci_affinity_info(x1, x2);
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100427
428 case PSCI_MIG_AARCH64:
Soby Mathewd0194872016-04-29 19:01:30 +0100429 return psci_migrate(x1);
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100430
431 case PSCI_MIG_INFO_UP_CPU_AARCH64:
Soby Mathewd0194872016-04-29 19:01:30 +0100432 return psci_migrate_info_up_cpu();
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100433
Jeenu Viswambharan7f03e9d92016-08-03 15:54:50 +0100434 case PSCI_NODE_HW_STATE_AARCH64:
435 return psci_node_hw_state(x1, x2);
436
Soby Mathew96168382014-12-17 14:47:57 +0000437 case PSCI_SYSTEM_SUSPEND_AARCH64:
Soby Mathewd0194872016-04-29 19:01:30 +0100438 return psci_system_suspend(x1, x2);
Soby Mathew96168382014-12-17 14:47:57 +0000439
Yatharth Kochar241ec6c2016-05-09 18:26:35 +0100440#if ENABLE_PSCI_STAT
441 case PSCI_STAT_RESIDENCY_AARCH64:
Soby Mathewd0194872016-04-29 19:01:30 +0100442 return psci_stat_residency(x1, x2);
Yatharth Kochar241ec6c2016-05-09 18:26:35 +0100443
444 case PSCI_STAT_COUNT_AARCH64:
Soby Mathewd0194872016-04-29 19:01:30 +0100445 return psci_stat_count(x1, x2);
Yatharth Kochar241ec6c2016-05-09 18:26:35 +0100446#endif
447
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100448 default:
449 break;
450 }
Jeenu Viswambharancaa84932014-02-06 10:36:15 +0000451 }
452
Andrew Thoelke89a3c842014-06-10 16:37:37 +0100453 WARN("Unimplemented PSCI Call: 0x%x \n", smc_fid);
Soby Mathewd0194872016-04-29 19:01:30 +0100454 return SMC_UNK;
Jeenu Viswambharancaa84932014-02-06 10:36:15 +0000455}