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_system_suspend(uintptr_t entry __unused, 103 uint32_t context_id __unused) 104 { 105 return PSCI_RET_NOT_SUPPORTED; 106 } 107 108 __weak int psci_stat_residency(uint32_t cpu_id __unused, 109 uint32_t power_state __unused) 110 { 111 return PSCI_RET_NOT_SUPPORTED; 112 } 113 114 __weak int psci_stat_count(uint32_t cpu_id __unused, 115 uint32_t power_state __unused) 116 { 117 return PSCI_RET_NOT_SUPPORTED; 118 } 119 120 void tee_psci_handler(struct thread_smc_args *args) 121 { 122 uint32_t smc_fid = args->a0; 123 uint32_t a1 = args->a1; 124 uint32_t a2 = args->a2; 125 uint32_t a3 = args->a3; 126 127 switch (smc_fid) { 128 case PSCI_VERSION: 129 args->a0 = psci_version(); 130 break; 131 case PSCI_CPU_SUSPEND: 132 args->a0 = psci_cpu_suspend(a1, a2, a3); 133 break; 134 case PSCI_CPU_OFF: 135 args->a0 = psci_cpu_off(); 136 break; 137 case PSCI_CPU_ON: 138 args->a0 = psci_cpu_on(a1, a2, a3); 139 break; 140 case PSCI_AFFINITY_INFO: 141 args->a0 = psci_affinity_info(a1, a2); 142 break; 143 case PSCI_MIGRATE: 144 args->a0 = psci_migrate(a1); 145 break; 146 case PSCI_MIGRATE_INFO_TYPE: 147 args->a0 = psci_migrate_info_type(); 148 break; 149 case PSCI_MIGRATE_INFO_UP_CPU: 150 args->a0 = psci_migrate_info_up_cpu(); 151 break; 152 case PSCI_SYSTEM_OFF: 153 psci_system_off(); 154 while (1) 155 ; 156 break; 157 case PSCI_SYSTEM_RESET: 158 psci_system_reset(); 159 while (1) 160 ; 161 break; 162 case PSCI_PSCI_FEATURES: 163 args->a0 = psci_features(a1); 164 break; 165 case PSCI_NODE_HW_STATE: 166 args->a0 = psci_node_hw_state(a1, a2); 167 break; 168 case PSCI_SYSTEM_SUSPEND: 169 args->a0 = psci_system_suspend(a1, a2); 170 break; 171 default: 172 args->a0 = OPTEE_SMC_RETURN_UNKNOWN_FUNCTION; 173 break; 174 } 175 } 176