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