b2bd6453998945dcc59b4d992524a896aa3f979c
[platform/core/security/tef-optee_os.git] / core / arch / arm / sm / psci.c
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_off();
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 }