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