1/* 2 * Copyright 2018, IBM Corporation. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 * 9 * This file contains general idle entry/exit functions to save 10 * and restore stack and NVGPRs which allows C code to call idle 11 * states that lose GPRs, and it will return transparently with 12 * SRR1 wakeup reason return value. 13 * 14 * The platform / CPU caller must ensure SPRs and any other non-GPR 15 * state is saved and restored correctly, handle KVM, interrupts, etc. 16 */ 17 18#include <asm/ppc_asm.h> 19#include <asm/asm-offsets.h> 20#include <asm/ppc-opcode.h> 21#include <asm/cpuidle.h> 22 23/* 24 * Desired PSSCR in r3 25 * 26 * No state will be lost regardless of wakeup mechanism (interrupt or NIA). 27 * 28 * An EC=0 type wakeup will return with a value of 0. SRESET wakeup (which can 29 * happen with xscom SRESET and possibly MCE) may clobber volatiles except LR, 30 * and must blr, to return to caller with r3 set according to caller's expected 31 * return code (for Book3S/64 that is SRR1). 32 */ 33_GLOBAL(isa300_idle_stop_noloss) 34 mtspr SPRN_PSSCR,r3 35 PPC_STOP 36 li r3,0 37 blr 38 39/* 40 * Desired PSSCR in r3 41 * 42 * GPRs may be lost, so they are saved here. Wakeup is by interrupt only. 43 * The SRESET wakeup returns to this function's caller by calling 44 * idle_return_gpr_loss with r3 set to desired return value. 45 * 46 * A wakeup without GPR loss may alteratively be handled as in 47 * isa300_idle_stop_noloss and blr directly, as an optimisation. 48 * 49 * The caller is responsible for saving/restoring SPRs, MSR, timebase, 50 * etc. 51 */ 52_GLOBAL(isa300_idle_stop_mayloss) 53 mtspr SPRN_PSSCR,r3 54 std r1,PACAR1(r13) 55 mflr r4 56 mfcr r5 57 /* use stack red zone rather than a new frame for saving regs */ 58 std r2,-8*0(r1) 59 std r14,-8*1(r1) 60 std r15,-8*2(r1) 61 std r16,-8*3(r1) 62 std r17,-8*4(r1) 63 std r18,-8*5(r1) 64 std r19,-8*6(r1) 65 std r20,-8*7(r1) 66 std r21,-8*8(r1) 67 std r22,-8*9(r1) 68 std r23,-8*10(r1) 69 std r24,-8*11(r1) 70 std r25,-8*12(r1) 71 std r26,-8*13(r1) 72 std r27,-8*14(r1) 73 std r28,-8*15(r1) 74 std r29,-8*16(r1) 75 std r30,-8*17(r1) 76 std r31,-8*18(r1) 77 std r4,-8*19(r1) 78 std r5,-8*20(r1) 79 /* 168 bytes */ 80 PPC_STOP 81 b . /* catch bugs */ 82 83/* 84 * Desired return value in r3 85 * 86 * The idle wakeup SRESET interrupt can call this after calling 87 * to return to the idle sleep function caller with r3 as the return code. 88 * 89 * This must not be used if idle was entered via a _noloss function (use 90 * a simple blr instead). 91 */ 92_GLOBAL(idle_return_gpr_loss) 93 ld r1,PACAR1(r13) 94 ld r4,-8*19(r1) 95 ld r5,-8*20(r1) 96 mtlr r4 97 mtcr r5 98 /* 99 * KVM nap requires r2 to be saved, rather than just restoring it 100 * from PACATOC. This could be avoided for that less common case 101 * if KVM saved its r2. 102 */ 103 ld r2,-8*0(r1) 104 ld r14,-8*1(r1) 105 ld r15,-8*2(r1) 106 ld r16,-8*3(r1) 107 ld r17,-8*4(r1) 108 ld r18,-8*5(r1) 109 ld r19,-8*6(r1) 110 ld r20,-8*7(r1) 111 ld r21,-8*8(r1) 112 ld r22,-8*9(r1) 113 ld r23,-8*10(r1) 114 ld r24,-8*11(r1) 115 ld r25,-8*12(r1) 116 ld r26,-8*13(r1) 117 ld r27,-8*14(r1) 118 ld r28,-8*15(r1) 119 ld r29,-8*16(r1) 120 ld r30,-8*17(r1) 121 ld r31,-8*18(r1) 122 blr 123 124/* 125 * This is the sequence required to execute idle instructions, as 126 * specified in ISA v2.07 (and earlier). MSR[IR] and MSR[DR] must be 0. 127 * 128 * The 0(r1) slot is used to save r2 in isa206, so use that here. 129 */ 130#define IDLE_STATE_ENTER_SEQ_NORET(IDLE_INST) \ 131 /* Magic NAP/SLEEP/WINKLE mode enter sequence */ \ 132 std r2,0(r1); \ 133 ptesync; \ 134 ld r2,0(r1); \ 135236: cmpd cr0,r2,r2; \ 136 bne 236b; \ 137 IDLE_INST; \ 138 b . /* catch bugs */ 139 140/* 141 * Desired instruction type in r3 142 * 143 * GPRs may be lost, so they are saved here. Wakeup is by interrupt only. 144 * The SRESET wakeup returns to this function's caller by calling 145 * idle_return_gpr_loss with r3 set to desired return value. 146 * 147 * A wakeup without GPR loss may alteratively be handled as in 148 * isa300_idle_stop_noloss and blr directly, as an optimisation. 149 * 150 * The caller is responsible for saving/restoring SPRs, MSR, timebase, 151 * etc. 152 * 153 * This must be called in real-mode (MSR_IDLE). 154 */ 155_GLOBAL(isa206_idle_insn_mayloss) 156 std r1,PACAR1(r13) 157 mflr r4 158 mfcr r5 159 /* use stack red zone rather than a new frame for saving regs */ 160 std r2,-8*0(r1) 161 std r14,-8*1(r1) 162 std r15,-8*2(r1) 163 std r16,-8*3(r1) 164 std r17,-8*4(r1) 165 std r18,-8*5(r1) 166 std r19,-8*6(r1) 167 std r20,-8*7(r1) 168 std r21,-8*8(r1) 169 std r22,-8*9(r1) 170 std r23,-8*10(r1) 171 std r24,-8*11(r1) 172 std r25,-8*12(r1) 173 std r26,-8*13(r1) 174 std r27,-8*14(r1) 175 std r28,-8*15(r1) 176 std r29,-8*16(r1) 177 std r30,-8*17(r1) 178 std r31,-8*18(r1) 179 std r4,-8*19(r1) 180 std r5,-8*20(r1) 181 cmpwi r3,PNV_THREAD_NAP 182 bne 1f 183 IDLE_STATE_ENTER_SEQ_NORET(PPC_NAP) 1841: cmpwi r3,PNV_THREAD_SLEEP 185 bne 2f 186 IDLE_STATE_ENTER_SEQ_NORET(PPC_SLEEP) 1872: IDLE_STATE_ENTER_SEQ_NORET(PPC_WINKLE) 188 189