1 /* 2 * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <platform_def.h> 9 10 #include <arch_helpers.h> 11 #include <common/debug.h> 12 #include <lib/psci/psci.h> 13 #include <plat/common/platform.h> 14 15 #include "qemu_private.h" 16 17 /* 18 * The secure entry point to be used on warm reset. 19 */ 20 static unsigned long secure_entrypoint; 21 22 /* Make composite power state parameter till power level 0 */ 23 #if PSCI_EXTENDED_STATE_ID 24 25 #define qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \ 26 (((lvl0_state) << PSTATE_ID_SHIFT) | \ 27 ((type) << PSTATE_TYPE_SHIFT)) 28 #else 29 #define qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \ 30 (((lvl0_state) << PSTATE_ID_SHIFT) | \ 31 ((pwr_lvl) << PSTATE_PWR_LVL_SHIFT) | \ 32 ((type) << PSTATE_TYPE_SHIFT)) 33 #endif /* PSCI_EXTENDED_STATE_ID */ 34 35 36 #define qemu_make_pwrstate_lvl1(lvl1_state, lvl0_state, pwr_lvl, type) \ 37 (((lvl1_state) << PLAT_LOCAL_PSTATE_WIDTH) | \ 38 qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type)) 39 40 41 42 /* 43 * The table storing the valid idle power states. Ensure that the 44 * array entries are populated in ascending order of state-id to 45 * enable us to use binary search during power state validation. 46 * The table must be terminated by a NULL entry. 47 */ 48 static const unsigned int qemu_pm_idle_states[] = { 49 /* State-id - 0x01 */ 50 qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_RUN, PLAT_LOCAL_STATE_RET, 51 MPIDR_AFFLVL0, PSTATE_TYPE_STANDBY), 52 /* State-id - 0x02 */ 53 qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_RUN, PLAT_LOCAL_STATE_OFF, 54 MPIDR_AFFLVL0, PSTATE_TYPE_POWERDOWN), 55 /* State-id - 0x22 */ 56 qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_OFF, PLAT_LOCAL_STATE_OFF, 57 MPIDR_AFFLVL1, PSTATE_TYPE_POWERDOWN), 58 0, 59 }; 60 61 /******************************************************************************* 62 * Platform handler called to check the validity of the power state 63 * parameter. The power state parameter has to be a composite power state. 64 ******************************************************************************/ 65 static int qemu_validate_power_state(unsigned int power_state, 66 psci_power_state_t *req_state) 67 { 68 unsigned int state_id; 69 int i; 70 71 assert(req_state); 72 73 /* 74 * Currently we are using a linear search for finding the matching 75 * entry in the idle power state array. This can be made a binary 76 * search if the number of entries justify the additional complexity. 77 */ 78 for (i = 0; !!qemu_pm_idle_states[i]; i++) { 79 if (power_state == qemu_pm_idle_states[i]) 80 break; 81 } 82 83 /* Return error if entry not found in the idle state array */ 84 if (!qemu_pm_idle_states[i]) 85 return PSCI_E_INVALID_PARAMS; 86 87 i = 0; 88 state_id = psci_get_pstate_id(power_state); 89 90 /* Parse the State ID and populate the state info parameter */ 91 while (state_id) { 92 req_state->pwr_domain_state[i++] = state_id & 93 PLAT_LOCAL_PSTATE_MASK; 94 state_id >>= PLAT_LOCAL_PSTATE_WIDTH; 95 } 96 97 return PSCI_E_SUCCESS; 98 } 99 100 /******************************************************************************* 101 * Platform handler called to check the validity of the non secure 102 * entrypoint. 103 ******************************************************************************/ 104 static int qemu_validate_ns_entrypoint(uintptr_t entrypoint) 105 { 106 /* 107 * Check if the non secure entrypoint lies within the non 108 * secure DRAM. 109 */ 110 if ((entrypoint >= NS_DRAM0_BASE) && 111 (entrypoint < (NS_DRAM0_BASE + NS_DRAM0_SIZE))) 112 return PSCI_E_SUCCESS; 113 return PSCI_E_INVALID_ADDRESS; 114 } 115 116 /******************************************************************************* 117 * Platform handler called when a CPU is about to enter standby. 118 ******************************************************************************/ 119 static void qemu_cpu_standby(plat_local_state_t cpu_state) 120 { 121 122 assert(cpu_state == PLAT_LOCAL_STATE_RET); 123 124 /* 125 * Enter standby state 126 * dsb is good practice before using wfi to enter low power states 127 */ 128 dsb(); 129 wfi(); 130 } 131 132 /******************************************************************************* 133 * Platform handler called when a power domain is about to be turned on. The 134 * mpidr determines the CPU to be turned on. 135 ******************************************************************************/ 136 static int qemu_pwr_domain_on(u_register_t mpidr) 137 { 138 int rc = PSCI_E_SUCCESS; 139 unsigned pos = plat_core_pos_by_mpidr(mpidr); 140 uint64_t *hold_base = (uint64_t *)PLAT_QEMU_HOLD_BASE; 141 142 hold_base[pos] = PLAT_QEMU_HOLD_STATE_GO; 143 sev(); 144 145 return rc; 146 } 147 148 /******************************************************************************* 149 * Platform handler called when a power domain is about to be turned off. The 150 * target_state encodes the power state that each level should transition to. 151 ******************************************************************************/ 152 void qemu_pwr_domain_off(const psci_power_state_t *target_state) 153 { 154 assert(0); 155 } 156 157 /******************************************************************************* 158 * Platform handler called when a power domain is about to be suspended. The 159 * target_state encodes the power state that each level should transition to. 160 ******************************************************************************/ 161 void qemu_pwr_domain_suspend(const psci_power_state_t *target_state) 162 { 163 assert(0); 164 } 165 166 /******************************************************************************* 167 * Platform handler called when a power domain has just been powered on after 168 * being turned off earlier. The target_state encodes the low power state that 169 * each level has woken up from. 170 ******************************************************************************/ 171 void qemu_pwr_domain_on_finish(const psci_power_state_t *target_state) 172 { 173 assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] == 174 PLAT_LOCAL_STATE_OFF); 175 176 qemu_pwr_gic_on_finish(); 177 } 178 179 /******************************************************************************* 180 * Platform handler called when a power domain has just been powered on after 181 * having been suspended earlier. The target_state encodes the low power state 182 * that each level has woken up from. 183 ******************************************************************************/ 184 void qemu_pwr_domain_suspend_finish(const psci_power_state_t *target_state) 185 { 186 assert(0); 187 } 188 189 /******************************************************************************* 190 * Platform handlers to shutdown/reboot the system 191 ******************************************************************************/ 192 static void __dead2 qemu_system_off(void) 193 { 194 ERROR("QEMU System Off: operation not handled.\n"); 195 panic(); 196 } 197 198 static void __dead2 qemu_system_reset(void) 199 { 200 ERROR("QEMU System Reset: operation not handled.\n"); 201 panic(); 202 } 203 204 static const plat_psci_ops_t plat_qemu_psci_pm_ops = { 205 .cpu_standby = qemu_cpu_standby, 206 .pwr_domain_on = qemu_pwr_domain_on, 207 .pwr_domain_off = qemu_pwr_domain_off, 208 .pwr_domain_suspend = qemu_pwr_domain_suspend, 209 .pwr_domain_on_finish = qemu_pwr_domain_on_finish, 210 .pwr_domain_suspend_finish = qemu_pwr_domain_suspend_finish, 211 .system_off = qemu_system_off, 212 .system_reset = qemu_system_reset, 213 .validate_power_state = qemu_validate_power_state, 214 .validate_ns_entrypoint = qemu_validate_ns_entrypoint 215 }; 216 217 int plat_setup_psci_ops(uintptr_t sec_entrypoint, 218 const plat_psci_ops_t **psci_ops) 219 { 220 uintptr_t *mailbox = (void *) PLAT_QEMU_TRUSTED_MAILBOX_BASE; 221 222 *mailbox = sec_entrypoint; 223 secure_entrypoint = (unsigned long) sec_entrypoint; 224 *psci_ops = &plat_qemu_psci_pm_ops; 225 226 return 0; 227 } 228