1b4315306SDan Handley /* 2b4315306SDan Handley * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 3b4315306SDan Handley * 4b4315306SDan Handley * Redistribution and use in source and binary forms, with or without 5b4315306SDan Handley * modification, are permitted provided that the following conditions are met: 6b4315306SDan Handley * 7b4315306SDan Handley * Redistributions of source code must retain the above copyright notice, this 8b4315306SDan Handley * list of conditions and the following disclaimer. 9b4315306SDan Handley * 10b4315306SDan Handley * Redistributions in binary form must reproduce the above copyright notice, 11b4315306SDan Handley * this list of conditions and the following disclaimer in the documentation 12b4315306SDan Handley * and/or other materials provided with the distribution. 13b4315306SDan Handley * 14b4315306SDan Handley * Neither the name of ARM nor the names of its contributors may be used 15b4315306SDan Handley * to endorse or promote products derived from this software without specific 16b4315306SDan Handley * prior written permission. 17b4315306SDan Handley * 18b4315306SDan Handley * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19b4315306SDan Handley * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20b4315306SDan Handley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21b4315306SDan Handley * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22b4315306SDan Handley * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23b4315306SDan Handley * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24b4315306SDan Handley * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25b4315306SDan Handley * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26b4315306SDan Handley * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27b4315306SDan Handley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28b4315306SDan Handley * POSSIBILITY OF SUCH DAMAGE. 29b4315306SDan Handley */ 30b4315306SDan Handley 31b4315306SDan Handley #include <arch_helpers.h> 32*f9e858b1SSoby Mathew #include <arm_def.h> 33b4315306SDan Handley #include <assert.h> 34b4315306SDan Handley #include <errno.h> 352204afdeSSoby Mathew #include <plat_arm.h> 36b4315306SDan Handley #include <psci.h> 37b4315306SDan Handley 382204afdeSSoby Mathew #if ARM_RECOM_STATE_ID_ENC 392204afdeSSoby Mathew extern unsigned int arm_pm_idle_states[]; 402204afdeSSoby Mathew #endif /* __ARM_RECOM_STATE_ID_ENC__ */ 412204afdeSSoby Mathew 422204afdeSSoby Mathew 432204afdeSSoby Mathew #if !ARM_RECOM_STATE_ID_ENC 44b4315306SDan Handley /******************************************************************************* 45b4315306SDan Handley * ARM standard platform handler called to check the validity of the power state 46b4315306SDan Handley * parameter. 47b4315306SDan Handley ******************************************************************************/ 4838dce70fSSoby Mathew int arm_validate_power_state(unsigned int power_state, 4938dce70fSSoby Mathew psci_power_state_t *req_state) 50b4315306SDan Handley { 5138dce70fSSoby Mathew int pstate = psci_get_pstate_type(power_state); 5238dce70fSSoby Mathew int pwr_lvl = psci_get_pstate_pwrlvl(power_state); 5338dce70fSSoby Mathew int i; 5438dce70fSSoby Mathew 5538dce70fSSoby Mathew assert(req_state); 5638dce70fSSoby Mathew 5738dce70fSSoby Mathew if (pwr_lvl > PLAT_MAX_PWR_LVL) 58b4315306SDan Handley return PSCI_E_INVALID_PARAMS; 5938dce70fSSoby Mathew 6038dce70fSSoby Mathew /* Sanity check the requested state */ 6138dce70fSSoby Mathew if (pstate == PSTATE_TYPE_STANDBY) { 6238dce70fSSoby Mathew /* 6338dce70fSSoby Mathew * It's possible to enter standby only on power level 0 6438dce70fSSoby Mathew * Ignore any other power level. 6538dce70fSSoby Mathew */ 6638dce70fSSoby Mathew if (pwr_lvl != ARM_PWR_LVL0) 6738dce70fSSoby Mathew return PSCI_E_INVALID_PARAMS; 6838dce70fSSoby Mathew 6938dce70fSSoby Mathew req_state->pwr_domain_state[ARM_PWR_LVL0] = 7038dce70fSSoby Mathew ARM_LOCAL_STATE_RET; 7138dce70fSSoby Mathew } else { 7238dce70fSSoby Mathew for (i = ARM_PWR_LVL0; i <= pwr_lvl; i++) 7338dce70fSSoby Mathew req_state->pwr_domain_state[i] = 7438dce70fSSoby Mathew ARM_LOCAL_STATE_OFF; 75b4315306SDan Handley } 76b4315306SDan Handley 77b4315306SDan Handley /* 78b4315306SDan Handley * We expect the 'state id' to be zero. 79b4315306SDan Handley */ 80b4315306SDan Handley if (psci_get_pstate_id(power_state)) 81b4315306SDan Handley return PSCI_E_INVALID_PARAMS; 82b4315306SDan Handley 83b4315306SDan Handley return PSCI_E_SUCCESS; 84b4315306SDan Handley } 852204afdeSSoby Mathew 862204afdeSSoby Mathew #else 872204afdeSSoby Mathew /******************************************************************************* 882204afdeSSoby Mathew * ARM standard platform handler called to check the validity of the power 892204afdeSSoby Mathew * state parameter. The power state parameter has to be a composite power 902204afdeSSoby Mathew * state. 912204afdeSSoby Mathew ******************************************************************************/ 922204afdeSSoby Mathew int arm_validate_power_state(unsigned int power_state, 932204afdeSSoby Mathew psci_power_state_t *req_state) 942204afdeSSoby Mathew { 952204afdeSSoby Mathew unsigned int state_id; 962204afdeSSoby Mathew int i; 972204afdeSSoby Mathew 982204afdeSSoby Mathew assert(req_state); 992204afdeSSoby Mathew 1002204afdeSSoby Mathew /* 1012204afdeSSoby Mathew * Currently we are using a linear search for finding the matching 1022204afdeSSoby Mathew * entry in the idle power state array. This can be made a binary 1032204afdeSSoby Mathew * search if the number of entries justify the additional complexity. 1042204afdeSSoby Mathew */ 1052204afdeSSoby Mathew for (i = 0; !!arm_pm_idle_states[i]; i++) { 1062204afdeSSoby Mathew if (power_state == arm_pm_idle_states[i]) 1072204afdeSSoby Mathew break; 1082204afdeSSoby Mathew } 1092204afdeSSoby Mathew 1102204afdeSSoby Mathew /* Return error if entry not found in the idle state array */ 1112204afdeSSoby Mathew if (!arm_pm_idle_states[i]) 1122204afdeSSoby Mathew return PSCI_E_INVALID_PARAMS; 1132204afdeSSoby Mathew 1142204afdeSSoby Mathew i = 0; 1152204afdeSSoby Mathew state_id = psci_get_pstate_id(power_state); 1162204afdeSSoby Mathew 1172204afdeSSoby Mathew /* Parse the State ID and populate the state info parameter */ 1182204afdeSSoby Mathew while (state_id) { 1192204afdeSSoby Mathew req_state->pwr_domain_state[i++] = state_id & 1202204afdeSSoby Mathew ARM_LOCAL_PSTATE_MASK; 1212204afdeSSoby Mathew state_id >>= ARM_LOCAL_PSTATE_WIDTH; 1222204afdeSSoby Mathew } 1232204afdeSSoby Mathew 1242204afdeSSoby Mathew return PSCI_E_SUCCESS; 1252204afdeSSoby Mathew } 1262204afdeSSoby Mathew #endif /* __ARM_RECOM_STATE_ID_ENC__ */ 127*f9e858b1SSoby Mathew 128*f9e858b1SSoby Mathew /******************************************************************************* 129*f9e858b1SSoby Mathew * ARM standard platform handler called to check the validity of the non secure 130*f9e858b1SSoby Mathew * entrypoint. 131*f9e858b1SSoby Mathew ******************************************************************************/ 132*f9e858b1SSoby Mathew int arm_validate_ns_entrypoint(uintptr_t entrypoint) 133*f9e858b1SSoby Mathew { 134*f9e858b1SSoby Mathew /* 135*f9e858b1SSoby Mathew * Check if the non secure entrypoint lies within the non 136*f9e858b1SSoby Mathew * secure DRAM. 137*f9e858b1SSoby Mathew */ 138*f9e858b1SSoby Mathew if ((entrypoint >= ARM_NS_DRAM1_BASE) && (entrypoint < 139*f9e858b1SSoby Mathew (ARM_NS_DRAM1_BASE + ARM_NS_DRAM1_SIZE))) 140*f9e858b1SSoby Mathew return PSCI_E_SUCCESS; 141*f9e858b1SSoby Mathew if ((entrypoint >= ARM_DRAM2_BASE) && (entrypoint < 142*f9e858b1SSoby Mathew (ARM_DRAM2_BASE + ARM_DRAM2_SIZE))) 143*f9e858b1SSoby Mathew return PSCI_E_SUCCESS; 144*f9e858b1SSoby Mathew 145*f9e858b1SSoby Mathew return PSCI_E_INVALID_ADDRESS; 146*f9e858b1SSoby Mathew } 147