Commit | Line | Data |
---|---|---|
2874c5fd | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
948cf67c | 2 | /* |
10d91611 | 3 | * Copyright 2018, IBM Corporation. |
948cf67c | 4 | * |
10d91611 NP |
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. | |
9 | * | |
10 | * The platform / CPU caller must ensure SPRs and any other non-GPR | |
11 | * state is saved and restored correctly, handle KVM, interrupts, etc. | |
948cf67c BH |
12 | */ |
13 | ||
948cf67c BH |
14 | #include <asm/ppc_asm.h> |
15 | #include <asm/asm-offsets.h> | |
16 | #include <asm/ppc-opcode.h> | |
7cba160a | 17 | #include <asm/cpuidle.h> |
ed0bc98f | 18 | #include <asm/thread_info.h> /* TLF_NAPPING */ |
77b54e9f | 19 | |
ed0bc98f | 20 | #ifdef CONFIG_PPC_P7_NAP |
e1c1cfed | 21 | /* |
10d91611 | 22 | * Desired PSSCR in r3 |
e1c1cfed | 23 | * |
10d91611 NP |
24 | * No state will be lost regardless of wakeup mechanism (interrupt or NIA). |
25 | * | |
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). | |
e1c1cfed | 30 | */ |
10d91611 NP |
31 | _GLOBAL(isa300_idle_stop_noloss) |
32 | mtspr SPRN_PSSCR,r3 | |
33 | PPC_STOP | |
34 | li r3,0 | |
0dfffb48 SP |
35 | blr |
36 | ||
b32aadc1 | 37 | /* |
10d91611 NP |
38 | * Desired PSSCR in r3 |
39 | * | |
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. | |
43 | * | |
44 | * A wakeup without GPR loss may alteratively be handled as in | |
45 | * isa300_idle_stop_noloss and blr directly, as an optimisation. | |
46 | * | |
47 | * The caller is responsible for saving/restoring SPRs, MSR, timebase, | |
48 | * etc. | |
b32aadc1 | 49 | */ |
10d91611 NP |
50 | _GLOBAL(isa300_idle_stop_mayloss) |
51 | mtspr SPRN_PSSCR,r3 | |
52 | std r1,PACAR1(r13) | |
53 | mflr r4 | |
54 | mfcr r5 | |
55 | /* use stack red zone rather than a new frame for saving regs */ | |
56 | std r2,-8*0(r1) | |
57 | std r14,-8*1(r1) | |
58 | std r15,-8*2(r1) | |
59 | std r16,-8*3(r1) | |
60 | std r17,-8*4(r1) | |
61 | std r18,-8*5(r1) | |
62 | std r19,-8*6(r1) | |
63 | std r20,-8*7(r1) | |
64 | std r21,-8*8(r1) | |
65 | std r22,-8*9(r1) | |
66 | std r23,-8*10(r1) | |
67 | std r24,-8*11(r1) | |
68 | std r25,-8*12(r1) | |
69 | std r26,-8*13(r1) | |
70 | std r27,-8*14(r1) | |
71 | std r28,-8*15(r1) | |
72 | std r29,-8*16(r1) | |
73 | std r30,-8*17(r1) | |
74 | std r31,-8*18(r1) | |
75 | std r4,-8*19(r1) | |
76 | std r5,-8*20(r1) | |
77 | /* 168 bytes */ | |
78 | PPC_STOP | |
79 | b . /* catch bugs */ | |
b32aadc1 | 80 | |
aca79d2b | 81 | /* |
10d91611 NP |
82 | * Desired return value in r3 |
83 | * | |
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. | |
8d6f7c5a | 86 | * |
10d91611 NP |
87 | * This must not be used if idle was entered via a _noloss function (use |
88 | * a simple blr instead). | |
aca79d2b | 89 | */ |
10d91611 NP |
90 | _GLOBAL(idle_return_gpr_loss) |
91 | ld r1,PACAR1(r13) | |
92 | ld r4,-8*19(r1) | |
93 | ld r5,-8*20(r1) | |
94 | mtlr r4 | |
95 | mtcr r5 | |
96 | /* | |
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. | |
100 | */ | |
101 | ld r2,-8*0(r1) | |
102 | ld r14,-8*1(r1) | |
103 | ld r15,-8*2(r1) | |
104 | ld r16,-8*3(r1) | |
105 | ld r17,-8*4(r1) | |
106 | ld r18,-8*5(r1) | |
107 | ld r19,-8*6(r1) | |
108 | ld r20,-8*7(r1) | |
109 | ld r21,-8*8(r1) | |
110 | ld r22,-8*9(r1) | |
111 | ld r23,-8*10(r1) | |
112 | ld r24,-8*11(r1) | |
113 | ld r25,-8*12(r1) | |
114 | ld r26,-8*13(r1) | |
115 | ld r27,-8*14(r1) | |
116 | ld r28,-8*15(r1) | |
117 | ld r29,-8*16(r1) | |
118 | ld r30,-8*17(r1) | |
119 | ld r31,-8*18(r1) | |
120 | blr | |
8117ac6a | 121 | |
aafc8a83 NP |
122 | /* |
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. | |
10d91611 NP |
125 | * |
126 | * The 0(r1) slot is used to save r2 in isa206, so use that here. | |
aafc8a83 | 127 | */ |
65dbbe81 | 128 | #define IDLE_STATE_ENTER_SEQ_NORET(IDLE_INST) \ |
aafc8a83 | 129 | /* Magic NAP/SLEEP/WINKLE mode enter sequence */ \ |
10d91611 | 130 | std r2,0(r1); \ |
aafc8a83 | 131 | ptesync; \ |
10d91611 NP |
132 | ld r2,0(r1); \ |
133 | 236: cmpd cr0,r2,r2; \ | |
aafc8a83 | 134 | bne 236b; \ |
10d91611 NP |
135 | IDLE_INST; \ |
136 | b . /* catch bugs */ | |
101dd590 | 137 | |
bcef83a0 | 138 | /* |
10d91611 | 139 | * Desired instruction type in r3 |
d0b791c0 | 140 | * |
10d91611 NP |
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. | |
1945bc45 | 144 | * |
10d91611 NP |
145 | * A wakeup without GPR loss may alteratively be handled as in |
146 | * isa300_idle_stop_noloss and blr directly, as an optimisation. | |
17065671 | 147 | * |
10d91611 NP |
148 | * The caller is responsible for saving/restoring SPRs, MSR, timebase, |
149 | * etc. | |
0d7720a2 | 150 | * |
10d91611 | 151 | * This must be called in real-mode (MSR_IDLE). |
bcef83a0 | 152 | */ |
10d91611 NP |
153 | _GLOBAL(isa206_idle_insn_mayloss) |
154 | std r1,PACAR1(r13) | |
155 | mflr r4 | |
156 | mfcr r5 | |
157 | /* use stack red zone rather than a new frame for saving regs */ | |
158 | std r2,-8*0(r1) | |
159 | std r14,-8*1(r1) | |
160 | std r15,-8*2(r1) | |
161 | std r16,-8*3(r1) | |
162 | std r17,-8*4(r1) | |
163 | std r18,-8*5(r1) | |
164 | std r19,-8*6(r1) | |
165 | std r20,-8*7(r1) | |
166 | std r21,-8*8(r1) | |
167 | std r22,-8*9(r1) | |
168 | std r23,-8*10(r1) | |
169 | std r24,-8*11(r1) | |
170 | std r25,-8*12(r1) | |
171 | std r26,-8*13(r1) | |
172 | std r27,-8*14(r1) | |
173 | std r28,-8*15(r1) | |
174 | std r29,-8*16(r1) | |
175 | std r30,-8*17(r1) | |
176 | std r31,-8*18(r1) | |
177 | std r4,-8*19(r1) | |
178 | std r5,-8*20(r1) | |
179 | cmpwi r3,PNV_THREAD_NAP | |
180 | bne 1f | |
181 | IDLE_STATE_ENTER_SEQ_NORET(PPC_NAP) | |
182 | 1: cmpwi r3,PNV_THREAD_SLEEP | |
0d7720a2 | 183 | bne 2f |
10d91611 NP |
184 | IDLE_STATE_ENTER_SEQ_NORET(PPC_SLEEP) |
185 | 2: IDLE_STATE_ENTER_SEQ_NORET(PPC_WINKLE) | |
ed0bc98f | 186 | #endif |
948cf67c | 187 | |
ed0bc98f NP |
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) | |
195 | /* | |
196 | * NAPPING bit is set, from this point onward power4_fixup_nap | |
197 | * will cause exceptions to return to power4_idle_nap_return. | |
198 | */ | |
199 | 1: sync | |
200 | isync | |
201 | mtmsrd r7 | |
202 | isync | |
203 | b 1b | |
204 | #endif |