xref: /optee_os/core/arch/arm/sm/psci.c (revision 4a9b7e83ba329b163708097c9c00e0b796ffdad1)
1 /*
2  * Copyright (C) 2016 Freescale Semiconductor, Inc.
3  * All rights reserved.
4  *
5  * Peng Fan <peng.fan@nxp.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <console.h>
31 #include <kernel/generic_boot.h>
32 #include <kernel/thread.h>
33 #include <stdint.h>
34 #include <sm/optee_smc.h>
35 #include <sm/psci.h>
36 #include <sm/sm.h>
37 #include <trace.h>
38 
39 __weak uint32_t psci_version(void)
40 {
41 	return PSCI_VERSION_0_2;
42 }
43 
44 __weak int psci_cpu_suspend(uint32_t power_state __unused,
45 			    uintptr_t entry __unused,
46 			    uint32_t context_id __unused)
47 {
48 	return PSCI_RET_NOT_SUPPORTED;
49 }
50 
51 __weak int psci_cpu_off(void)
52 {
53 	return PSCI_RET_NOT_SUPPORTED;
54 }
55 
56 __weak int psci_cpu_on(uint32_t cpu_id __unused, uint32_t entry __unused,
57 		       uint32_t context_id __unused)
58 {
59 	return PSCI_RET_NOT_SUPPORTED;
60 }
61 
62 __weak int psci_affinity_info(uint32_t affinity __unused,
63 			      uint32_t lowest_affnity_level __unused)
64 {
65 	return PSCI_RET_NOT_SUPPORTED;
66 }
67 
68 __weak int psci_migrate(uint32_t cpu_id __unused)
69 {
70 	return PSCI_RET_NOT_SUPPORTED;
71 }
72 
73 __weak int psci_migrate_info_type(void)
74 {
75 	return PSCI_RET_NOT_SUPPORTED;
76 }
77 
78 __weak int psci_migrate_info_up_cpu(void)
79 {
80 	return PSCI_RET_NOT_SUPPORTED;
81 }
82 
83 __weak void psci_system_off(void)
84 {
85 }
86 
87 __weak void psci_system_reset(void)
88 {
89 }
90 
91 __weak int psci_features(uint32_t psci_fid __unused)
92 {
93 	return PSCI_RET_NOT_SUPPORTED;
94 }
95 
96 __weak int psci_node_hw_state(uint32_t cpu_id __unused,
97 			      uint32_t power_level __unused)
98 {
99 	return PSCI_RET_NOT_SUPPORTED;
100 }
101 
102 __weak int psci_stat_residency(uint32_t cpu_id __unused,
103 			       uint32_t power_state __unused)
104 {
105 	return PSCI_RET_NOT_SUPPORTED;
106 }
107 
108 __weak int psci_stat_count(uint32_t cpu_id __unused,
109 			   uint32_t power_state __unused)
110 {
111 	return PSCI_RET_NOT_SUPPORTED;
112 }
113 
114 void tee_psci_handler(struct thread_smc_args *args)
115 {
116 	uint32_t smc_fid = args->a0;
117 	uint32_t a1 = args->a1;
118 	uint32_t a2 = args->a2;
119 	uint32_t a3 = args->a3;
120 
121 	switch (smc_fid) {
122 	case PSCI_VERSION:
123 		args->a0 = psci_version();
124 		break;
125 	case PSCI_CPU_SUSPEND:
126 		args->a0 = psci_cpu_suspend(a1, a2, a3);
127 		break;
128 	case PSCI_CPU_OFF:
129 		args->a0 = psci_cpu_off();
130 		break;
131 	case PSCI_CPU_ON:
132 		args->a0 = psci_cpu_on(a1, a2, a3);
133 		break;
134 	case PSCI_AFFINITY_INFO:
135 		args->a0 = psci_affinity_info(a1, a2);
136 		break;
137 	case PSCI_MIGRATE:
138 		args->a0 = psci_migrate(a1);
139 		break;
140 	case PSCI_MIGRATE_INFO_TYPE:
141 		args->a0 = psci_migrate_info_type();
142 		break;
143 	case PSCI_MIGRATE_INFO_UP_CPU:
144 		args->a0 = psci_migrate_info_up_cpu();
145 		break;
146 	case PSCI_SYSTEM_OFF:
147 		psci_system_off();
148 		while (1)
149 			;
150 		break;
151 	case PSCI_SYSTEM_RESET:
152 		psci_system_reset();
153 		while (1)
154 			;
155 		break;
156 	case PSCI_PSCI_FEATURES:
157 		args->a0 = psci_features(a1);
158 		break;
159 	case PSCI_NODE_HW_STATE:
160 		args->a0 = psci_node_hw_state(a1, a2);
161 		break;
162 	default:
163 		args->a0 = OPTEE_SMC_RETURN_UNKNOWN_FUNCTION;
164 		break;
165 	}
166 }
167