1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * Copyright 2018, IBM Corporation.
5 * This file contains general idle entry/exit functions to save
6 * and restore stack and NVGPRs which allows C code to call idle
7 * states that lose GPRs, and it will return transparently with
8 * SRR1 wakeup reason return value.
10 * The platform / CPU caller must ensure SPRs and any other non-GPR
11 * state is saved and restored correctly, handle KVM, interrupts, etc.
14 #include <asm/ppc_asm.h>
15 #include <asm/asm-offsets.h>
16 #include <asm/ppc-opcode.h>
17 #include <asm/cpuidle.h>
18 #include <asm/thread_info.h> /* TLF_NAPPING */
20 #ifdef CONFIG_PPC_P7_NAP
24 * No state will be lost regardless of wakeup mechanism (interrupt or NIA).
26 * An EC=0 type wakeup will return with a value of 0. SRESET wakeup (which can
27 * happen with xscom SRESET and possibly MCE) may clobber volatiles except LR,
28 * and must blr, to return to caller with r3 set according to caller's expected
29 * return code (for Book3S/64 that is SRR1).
31 _GLOBAL(isa300_idle_stop_noloss)
40 * GPRs may be lost, so they are saved here. Wakeup is by interrupt only.
41 * The SRESET wakeup returns to this function's caller by calling
42 * idle_return_gpr_loss with r3 set to desired return value.
44 * A wakeup without GPR loss may alteratively be handled as in
45 * isa300_idle_stop_noloss and blr directly, as an optimisation.
47 * The caller is responsible for saving/restoring SPRs, MSR, timebase,
50 _GLOBAL(isa300_idle_stop_mayloss)
55 /* use stack red zone rather than a new frame for saving regs */
82 * Desired return value in r3
84 * The idle wakeup SRESET interrupt can call this after calling
85 * to return to the idle sleep function caller with r3 as the return code.
87 * This must not be used if idle was entered via a _noloss function (use
88 * a simple blr instead).
90 _GLOBAL(idle_return_gpr_loss)
97 * KVM nap requires r2 to be saved, rather than just restoring it
98 * from PACATOC. This could be avoided for that less common case
99 * if KVM saved its r2.
123 * This is the sequence required to execute idle instructions, as
124 * specified in ISA v2.07 (and earlier). MSR[IR] and MSR[DR] must be 0.
126 * The 0(r1) slot is used to save r2 in isa206, so use that here.
128 #define IDLE_STATE_ENTER_SEQ_NORET(IDLE_INST) \
129 /* Magic NAP/SLEEP/WINKLE mode enter sequence */ \
133 236: cmpd cr0,r2,r2; \
139 * Desired instruction type in r3
141 * GPRs may be lost, so they are saved here. Wakeup is by interrupt only.
142 * The SRESET wakeup returns to this function's caller by calling
143 * idle_return_gpr_loss with r3 set to desired return value.
145 * A wakeup without GPR loss may alteratively be handled as in
146 * isa300_idle_stop_noloss and blr directly, as an optimisation.
148 * The caller is responsible for saving/restoring SPRs, MSR, timebase,
151 * This must be called in real-mode (MSR_IDLE).
153 _GLOBAL(isa206_idle_insn_mayloss)
157 /* use stack red zone rather than a new frame for saving regs */
179 cmpwi r3,PNV_THREAD_NAP
181 IDLE_STATE_ENTER_SEQ_NORET(PPC_NAP)
182 1: cmpwi r3,PNV_THREAD_SLEEP
184 IDLE_STATE_ENTER_SEQ_NORET(PPC_SLEEP)
185 2: IDLE_STATE_ENTER_SEQ_NORET(PPC_WINKLE)
188 #ifdef CONFIG_PPC_970_NAP
189 _GLOBAL(power4_idle_nap)
190 LOAD_REG_IMMEDIATE(r7, MSR_KERNEL|MSR_EE|MSR_POW)
191 ld r9,PACA_THREAD_INFO(r13)
192 ld r8,TI_LOCAL_FLAGS(r9)
193 ori r8,r8,_TLF_NAPPING
194 std r8,TI_LOCAL_FLAGS(r9)
196 * NAPPING bit is set, from this point onward power4_fixup_nap
197 * will cause exceptions to return to power4_idle_nap_return.