xref: /optee_os/core/arch/arm/sm/psci.c (revision 9daed40c66d662b6b696d1d2b735f37e234502bf)
11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2319556cdSPeng Fan /*
3319556cdSPeng Fan  * Copyright (C) 2016 Freescale Semiconductor, Inc.
4319556cdSPeng Fan  * All rights reserved.
5319556cdSPeng Fan  *
6319556cdSPeng Fan  * Peng Fan <peng.fan@nxp.com>
7319556cdSPeng Fan  *
8319556cdSPeng Fan  * Redistribution and use in source and binary forms, with or without
9319556cdSPeng Fan  * modification, are permitted provided that the following conditions are met:
10319556cdSPeng Fan  *
11319556cdSPeng Fan  * 1. Redistributions of source code must retain the above copyright notice,
12319556cdSPeng Fan  * this list of conditions and the following disclaimer.
13319556cdSPeng Fan  *
14319556cdSPeng Fan  * 2. Redistributions in binary form must reproduce the above copyright notice,
15319556cdSPeng Fan  * this list of conditions and the following disclaimer in the documentation
16319556cdSPeng Fan  * and/or other materials provided with the distribution.
17319556cdSPeng Fan  *
18319556cdSPeng Fan  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19319556cdSPeng Fan  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20319556cdSPeng Fan  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21319556cdSPeng Fan  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22319556cdSPeng Fan  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23319556cdSPeng Fan  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24319556cdSPeng Fan  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25319556cdSPeng Fan  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26319556cdSPeng Fan  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27319556cdSPeng Fan  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28319556cdSPeng Fan  * POSSIBILITY OF SUCH DAMAGE.
29319556cdSPeng Fan  */
30319556cdSPeng Fan 
31319556cdSPeng Fan #include <console.h>
3265401337SJens Wiklander #include <kernel/boot.h>
33319556cdSPeng Fan #include <kernel/thread.h>
34319556cdSPeng Fan #include <stdint.h>
35319556cdSPeng Fan #include <sm/optee_smc.h>
36319556cdSPeng Fan #include <sm/psci.h>
37319556cdSPeng Fan #include <sm/sm.h>
38319556cdSPeng Fan #include <trace.h>
39319556cdSPeng Fan 
psci_version(void)40319556cdSPeng Fan __weak uint32_t psci_version(void)
41319556cdSPeng Fan {
42*9daed40cSIgor Opaniuk 	return PSCI_VERSION_1_1;
43319556cdSPeng Fan }
44319556cdSPeng Fan 
psci_cpu_suspend(uint32_t power_state __unused,uintptr_t entry __unused,uint32_t context_id __unused,struct sm_nsec_ctx * nsec __unused)45319556cdSPeng Fan __weak int psci_cpu_suspend(uint32_t power_state __unused,
46319556cdSPeng Fan 			    uintptr_t entry __unused,
471b181fb2SPeng Fan 			    uint32_t context_id __unused,
481b181fb2SPeng Fan 			    struct sm_nsec_ctx *nsec __unused)
49319556cdSPeng Fan {
50319556cdSPeng Fan 	return PSCI_RET_NOT_SUPPORTED;
51319556cdSPeng Fan }
52319556cdSPeng Fan 
psci_cpu_off(void)53319556cdSPeng Fan __weak int psci_cpu_off(void)
54319556cdSPeng Fan {
55319556cdSPeng Fan 	return PSCI_RET_NOT_SUPPORTED;
56319556cdSPeng Fan }
57319556cdSPeng Fan 
psci_cpu_on(uint32_t cpu_id __unused,uint32_t entry __unused,uint32_t context_id __unused)58319556cdSPeng Fan __weak int psci_cpu_on(uint32_t cpu_id __unused, uint32_t entry __unused,
59319556cdSPeng Fan 		       uint32_t context_id __unused)
60319556cdSPeng Fan {
61319556cdSPeng Fan 	return PSCI_RET_NOT_SUPPORTED;
62319556cdSPeng Fan }
63319556cdSPeng Fan 
psci_affinity_info(uint32_t affinity __unused,uint32_t lowest_affnity_level __unused)64319556cdSPeng Fan __weak int psci_affinity_info(uint32_t affinity __unused,
65319556cdSPeng Fan 			      uint32_t lowest_affnity_level __unused)
66319556cdSPeng Fan {
67319556cdSPeng Fan 	return PSCI_RET_NOT_SUPPORTED;
68319556cdSPeng Fan }
69319556cdSPeng Fan 
psci_migrate(uint32_t cpu_id __unused)70319556cdSPeng Fan __weak int psci_migrate(uint32_t cpu_id __unused)
71319556cdSPeng Fan {
72319556cdSPeng Fan 	return PSCI_RET_NOT_SUPPORTED;
73319556cdSPeng Fan }
74319556cdSPeng Fan 
psci_migrate_info_type(void)75319556cdSPeng Fan __weak int psci_migrate_info_type(void)
76319556cdSPeng Fan {
77319556cdSPeng Fan 	return PSCI_RET_NOT_SUPPORTED;
78319556cdSPeng Fan }
79319556cdSPeng Fan 
psci_migrate_info_up_cpu(void)80319556cdSPeng Fan __weak int psci_migrate_info_up_cpu(void)
81319556cdSPeng Fan {
82319556cdSPeng Fan 	return PSCI_RET_NOT_SUPPORTED;
83319556cdSPeng Fan }
84319556cdSPeng Fan 
psci_system_off(void)85319556cdSPeng Fan __weak void psci_system_off(void)
86319556cdSPeng Fan {
87319556cdSPeng Fan }
88319556cdSPeng Fan 
psci_system_reset(void)89319556cdSPeng Fan __weak void psci_system_reset(void)
90319556cdSPeng Fan {
91319556cdSPeng Fan }
92319556cdSPeng Fan 
psci_features(uint32_t psci_fid __unused)93319556cdSPeng Fan __weak int psci_features(uint32_t psci_fid __unused)
94319556cdSPeng Fan {
95319556cdSPeng Fan 	return PSCI_RET_NOT_SUPPORTED;
96319556cdSPeng Fan }
97319556cdSPeng Fan 
psci_mem_protect(uint32_t enable __unused)98*9daed40cSIgor Opaniuk __weak int psci_mem_protect(uint32_t enable __unused)
99*9daed40cSIgor Opaniuk {
100*9daed40cSIgor Opaniuk 	return PSCI_RET_NOT_SUPPORTED;
101*9daed40cSIgor Opaniuk }
102*9daed40cSIgor Opaniuk 
psci_mem_chk_range(paddr_t base __unused,size_t length __unused)103*9daed40cSIgor Opaniuk __weak int psci_mem_chk_range(paddr_t base __unused,
104*9daed40cSIgor Opaniuk 			      size_t length __unused)
105*9daed40cSIgor Opaniuk {
106*9daed40cSIgor Opaniuk 	return PSCI_RET_NOT_SUPPORTED;
107*9daed40cSIgor Opaniuk }
108*9daed40cSIgor Opaniuk 
psci_system_reset2(uint32_t reset_type __unused,uint32_t cookie __unused)109*9daed40cSIgor Opaniuk __weak int psci_system_reset2(uint32_t reset_type __unused,
110*9daed40cSIgor Opaniuk 			      uint32_t cookie __unused)
111*9daed40cSIgor Opaniuk {
112*9daed40cSIgor Opaniuk 	return PSCI_RET_NOT_SUPPORTED;
113*9daed40cSIgor Opaniuk }
114*9daed40cSIgor Opaniuk 
psci_node_hw_state(uint32_t cpu_id __unused,uint32_t power_level __unused)115319556cdSPeng Fan __weak int psci_node_hw_state(uint32_t cpu_id __unused,
116319556cdSPeng Fan 			      uint32_t power_level __unused)
117319556cdSPeng Fan {
118319556cdSPeng Fan 	return PSCI_RET_NOT_SUPPORTED;
119319556cdSPeng Fan }
120319556cdSPeng Fan 
psci_system_suspend(uintptr_t entry __unused,uint32_t context_id __unused,struct sm_nsec_ctx * nsec __unused)12181637626SJoseph Chen __weak int psci_system_suspend(uintptr_t entry __unused,
122789e38a6SZeng Tao 			       uint32_t context_id __unused,
123789e38a6SZeng Tao 			       struct sm_nsec_ctx *nsec __unused)
12481637626SJoseph Chen {
12581637626SJoseph Chen 	return PSCI_RET_NOT_SUPPORTED;
12681637626SJoseph Chen }
12781637626SJoseph Chen 
psci_stat_residency(uint32_t cpu_id __unused,uint32_t power_state __unused)128319556cdSPeng Fan __weak int psci_stat_residency(uint32_t cpu_id __unused,
129319556cdSPeng Fan 			       uint32_t power_state __unused)
130319556cdSPeng Fan {
131319556cdSPeng Fan 	return PSCI_RET_NOT_SUPPORTED;
132319556cdSPeng Fan }
133319556cdSPeng Fan 
psci_stat_count(uint32_t cpu_id __unused,uint32_t power_state __unused)134319556cdSPeng Fan __weak int psci_stat_count(uint32_t cpu_id __unused,
135319556cdSPeng Fan 			   uint32_t power_state __unused)
136319556cdSPeng Fan {
137319556cdSPeng Fan 	return PSCI_RET_NOT_SUPPORTED;
138319556cdSPeng Fan }
139319556cdSPeng Fan 
tee_psci_handler(struct thread_smc_args * args,struct sm_nsec_ctx * nsec)1401b181fb2SPeng Fan void tee_psci_handler(struct thread_smc_args *args, struct sm_nsec_ctx *nsec)
141319556cdSPeng Fan {
142319556cdSPeng Fan 	uint32_t smc_fid = args->a0;
143319556cdSPeng Fan 	uint32_t a1 = args->a1;
144319556cdSPeng Fan 	uint32_t a2 = args->a2;
145319556cdSPeng Fan 	uint32_t a3 = args->a3;
146319556cdSPeng Fan 
147319556cdSPeng Fan 	switch (smc_fid) {
148319556cdSPeng Fan 	case PSCI_VERSION:
149319556cdSPeng Fan 		args->a0 = psci_version();
150319556cdSPeng Fan 		break;
151319556cdSPeng Fan 	case PSCI_CPU_SUSPEND:
1521b181fb2SPeng Fan 		args->a0 = psci_cpu_suspend(a1, a2, a3, nsec);
153319556cdSPeng Fan 		break;
154319556cdSPeng Fan 	case PSCI_CPU_OFF:
155319556cdSPeng Fan 		args->a0 = psci_cpu_off();
156319556cdSPeng Fan 		break;
157319556cdSPeng Fan 	case PSCI_CPU_ON:
158319556cdSPeng Fan 		args->a0 = psci_cpu_on(a1, a2, a3);
159319556cdSPeng Fan 		break;
160319556cdSPeng Fan 	case PSCI_AFFINITY_INFO:
161319556cdSPeng Fan 		args->a0 = psci_affinity_info(a1, a2);
162319556cdSPeng Fan 		break;
163319556cdSPeng Fan 	case PSCI_MIGRATE:
164319556cdSPeng Fan 		args->a0 = psci_migrate(a1);
165319556cdSPeng Fan 		break;
166319556cdSPeng Fan 	case PSCI_MIGRATE_INFO_TYPE:
167319556cdSPeng Fan 		args->a0 = psci_migrate_info_type();
168319556cdSPeng Fan 		break;
169319556cdSPeng Fan 	case PSCI_MIGRATE_INFO_UP_CPU:
170319556cdSPeng Fan 		args->a0 = psci_migrate_info_up_cpu();
171319556cdSPeng Fan 		break;
172319556cdSPeng Fan 	case PSCI_SYSTEM_OFF:
173319556cdSPeng Fan 		psci_system_off();
174319556cdSPeng Fan 		while (1)
175319556cdSPeng Fan 			;
176319556cdSPeng Fan 		break;
177319556cdSPeng Fan 	case PSCI_SYSTEM_RESET:
1784a9b7e83SPeng Fan 		psci_system_reset();
179319556cdSPeng Fan 		while (1)
180319556cdSPeng Fan 			;
181319556cdSPeng Fan 		break;
182319556cdSPeng Fan 	case PSCI_PSCI_FEATURES:
183319556cdSPeng Fan 		args->a0 = psci_features(a1);
184319556cdSPeng Fan 		break;
185*9daed40cSIgor Opaniuk 	case PSCI_SYSTEM_RESET2:
186*9daed40cSIgor Opaniuk 		args->a0 = psci_system_reset2(a1, a2);
187*9daed40cSIgor Opaniuk 		break;
188*9daed40cSIgor Opaniuk 	case PSCI_MEM_PROTECT:
189*9daed40cSIgor Opaniuk 		args->a0 = psci_mem_protect(a1);
190*9daed40cSIgor Opaniuk 		break;
191*9daed40cSIgor Opaniuk 	case PSCI_MEM_PROTECT_CHECK_RANGE:
192*9daed40cSIgor Opaniuk 		args->a0 = psci_mem_chk_range(a1, a2);
193*9daed40cSIgor Opaniuk 		break;
194319556cdSPeng Fan 	case PSCI_NODE_HW_STATE:
195319556cdSPeng Fan 		args->a0 = psci_node_hw_state(a1, a2);
196319556cdSPeng Fan 		break;
19781637626SJoseph Chen 	case PSCI_SYSTEM_SUSPEND:
198789e38a6SZeng Tao 		args->a0 = psci_system_suspend(a1, a2, nsec);
19981637626SJoseph Chen 		break;
200319556cdSPeng Fan 	default:
201319556cdSPeng Fan 		args->a0 = OPTEE_SMC_RETURN_UNKNOWN_FUNCTION;
202319556cdSPeng Fan 		break;
203319556cdSPeng Fan 	}
204319556cdSPeng Fan }
205