2 * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
4 * SPDX-License-Identifier: BSD-3-Clause
7 #include <arch_helpers.h>
12 #include <platform_def.h>
16 * The secure entry point to be used on warm reset.
18 static unsigned long secure_entrypoint
;
20 /* Make composite power state parameter till power level 0 */
21 #if PSCI_EXTENDED_STATE_ID
23 #define qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \
24 (((lvl0_state) << PSTATE_ID_SHIFT) | \
25 ((type) << PSTATE_TYPE_SHIFT))
27 #define qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \
28 (((lvl0_state) << PSTATE_ID_SHIFT) | \
29 ((pwr_lvl) << PSTATE_PWR_LVL_SHIFT) | \
30 ((type) << PSTATE_TYPE_SHIFT))
31 #endif /* PSCI_EXTENDED_STATE_ID */
34 #define qemu_make_pwrstate_lvl1(lvl1_state, lvl0_state, pwr_lvl, type) \
35 (((lvl1_state) << PLAT_LOCAL_PSTATE_WIDTH) | \
36 qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type))
41 * The table storing the valid idle power states. Ensure that the
42 * array entries are populated in ascending order of state-id to
43 * enable us to use binary search during power state validation.
44 * The table must be terminated by a NULL entry.
46 static const unsigned int qemu_pm_idle_states
[] = {
48 qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_RUN
, PLAT_LOCAL_STATE_RET
,
49 MPIDR_AFFLVL0
, PSTATE_TYPE_STANDBY
),
51 qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_RUN
, PLAT_LOCAL_STATE_OFF
,
52 MPIDR_AFFLVL0
, PSTATE_TYPE_POWERDOWN
),
54 qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_OFF
, PLAT_LOCAL_STATE_OFF
,
55 MPIDR_AFFLVL1
, PSTATE_TYPE_POWERDOWN
),
59 /*******************************************************************************
60 * Platform handler called to check the validity of the power state
61 * parameter. The power state parameter has to be a composite power state.
62 ******************************************************************************/
63 static int qemu_validate_power_state(unsigned int power_state
,
64 psci_power_state_t
*req_state
)
66 unsigned int state_id
;
72 * Currently we are using a linear search for finding the matching
73 * entry in the idle power state array. This can be made a binary
74 * search if the number of entries justify the additional complexity.
76 for (i
= 0; !!qemu_pm_idle_states
[i
]; i
++) {
77 if (power_state
== qemu_pm_idle_states
[i
])
81 /* Return error if entry not found in the idle state array */
82 if (!qemu_pm_idle_states
[i
])
83 return PSCI_E_INVALID_PARAMS
;
86 state_id
= psci_get_pstate_id(power_state
);
88 /* Parse the State ID and populate the state info parameter */
90 req_state
->pwr_domain_state
[i
++] = state_id
&
91 PLAT_LOCAL_PSTATE_MASK
;
92 state_id
>>= PLAT_LOCAL_PSTATE_WIDTH
;
95 return PSCI_E_SUCCESS
;
98 /*******************************************************************************
99 * Platform handler called to check the validity of the non secure
101 ******************************************************************************/
102 static int qemu_validate_ns_entrypoint(uintptr_t entrypoint
)
105 * Check if the non secure entrypoint lies within the non
108 if ((entrypoint
>= NS_DRAM0_BASE
) &&
109 (entrypoint
< (NS_DRAM0_BASE
+ NS_DRAM0_SIZE
)))
110 return PSCI_E_SUCCESS
;
111 return PSCI_E_INVALID_ADDRESS
;
114 /*******************************************************************************
115 * Platform handler called when a CPU is about to enter standby.
116 ******************************************************************************/
117 static void qemu_cpu_standby(plat_local_state_t cpu_state
)
120 assert(cpu_state
== PLAT_LOCAL_STATE_RET
);
123 * Enter standby state
124 * dsb is good practice before using wfi to enter low power states
130 /*******************************************************************************
131 * Platform handler called when a power domain is about to be turned on. The
132 * mpidr determines the CPU to be turned on.
133 ******************************************************************************/
134 static int qemu_pwr_domain_on(u_register_t mpidr
)
136 int rc
= PSCI_E_SUCCESS
;
137 unsigned pos
= plat_core_pos_by_mpidr(mpidr
);
138 uint64_t *hold_base
= (uint64_t *)PLAT_QEMU_HOLD_BASE
;
140 hold_base
[pos
] = PLAT_QEMU_HOLD_STATE_GO
;
146 /*******************************************************************************
147 * Platform handler called when a power domain is about to be turned off. The
148 * target_state encodes the power state that each level should transition to.
149 ******************************************************************************/
150 void qemu_pwr_domain_off(const psci_power_state_t
*target_state
)
155 /*******************************************************************************
156 * Platform handler called when a power domain is about to be suspended. The
157 * target_state encodes the power state that each level should transition to.
158 ******************************************************************************/
159 void qemu_pwr_domain_suspend(const psci_power_state_t
*target_state
)
164 /*******************************************************************************
165 * Platform handler called when a power domain has just been powered on after
166 * being turned off earlier. The target_state encodes the low power state that
167 * each level has woken up from.
168 ******************************************************************************/
169 void qemu_pwr_domain_on_finish(const psci_power_state_t
*target_state
)
171 assert(target_state
->pwr_domain_state
[MPIDR_AFFLVL0
] ==
172 PLAT_LOCAL_STATE_OFF
);
174 /* TODO: This setup is needed only after a cold boot */
175 gicv2_pcpu_distif_init();
177 /* Enable the gic cpu interface */
178 gicv2_cpuif_enable();
181 /*******************************************************************************
182 * Platform handler called when a power domain has just been powered on after
183 * having been suspended earlier. The target_state encodes the low power state
184 * that each level has woken up from.
185 ******************************************************************************/
186 void qemu_pwr_domain_suspend_finish(const psci_power_state_t
*target_state
)
191 /*******************************************************************************
192 * Platform handlers to shutdown/reboot the system
193 ******************************************************************************/
194 static void __dead2
qemu_system_off(void)
196 ERROR("QEMU System Off: operation not handled.\n");
200 static void __dead2
qemu_system_reset(void)
202 ERROR("QEMU System Reset: operation not handled.\n");
206 static const plat_psci_ops_t plat_qemu_psci_pm_ops
= {
207 .cpu_standby
= qemu_cpu_standby
,
208 .pwr_domain_on
= qemu_pwr_domain_on
,
209 .pwr_domain_off
= qemu_pwr_domain_off
,
210 .pwr_domain_suspend
= qemu_pwr_domain_suspend
,
211 .pwr_domain_on_finish
= qemu_pwr_domain_on_finish
,
212 .pwr_domain_suspend_finish
= qemu_pwr_domain_suspend_finish
,
213 .system_off
= qemu_system_off
,
214 .system_reset
= qemu_system_reset
,
215 .validate_power_state
= qemu_validate_power_state
,
216 .validate_ns_entrypoint
= qemu_validate_ns_entrypoint
219 int plat_setup_psci_ops(uintptr_t sec_entrypoint
,
220 const plat_psci_ops_t
**psci_ops
)
222 uintptr_t *mailbox
= (void *) PLAT_QEMU_TRUSTED_MAILBOX_BASE
;
224 *mailbox
= sec_entrypoint
;
225 secure_entrypoint
= (unsigned long) sec_entrypoint
;
226 *psci_ops
= &plat_qemu_psci_pm_ops
;