^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright 2018, IBM Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This file contains general idle entry/exit functions to save
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * and restore stack and NVGPRs which allows C code to call idle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * states that lose GPRs, and it will return transparently with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * SRR1 wakeup reason return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * The platform / CPU caller must ensure SPRs and any other non-GPR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * state is saved and restored correctly, handle KVM, interrupts, etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/ppc_asm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/asm-offsets.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/ppc-opcode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/cpuidle.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/thread_info.h> /* TLF_NAPPING */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #ifdef CONFIG_PPC_P7_NAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Desired PSSCR in r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * No state will be lost regardless of wakeup mechanism (interrupt or NIA).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * An EC=0 type wakeup will return with a value of 0. SRESET wakeup (which can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * happen with xscom SRESET and possibly MCE) may clobber volatiles except LR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * and must blr, to return to caller with r3 set according to caller's expected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * return code (for Book3S/64 that is SRR1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) _GLOBAL(isa300_idle_stop_noloss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) mtspr SPRN_PSSCR,r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) PPC_STOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) li r3,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) blr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * Desired PSSCR in r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * GPRs may be lost, so they are saved here. Wakeup is by interrupt only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * The SRESET wakeup returns to this function's caller by calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * idle_return_gpr_loss with r3 set to desired return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * A wakeup without GPR loss may alteratively be handled as in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * isa300_idle_stop_noloss and blr directly, as an optimisation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * The caller is responsible for saving/restoring SPRs, MSR, timebase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) _GLOBAL(isa300_idle_stop_mayloss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) mtspr SPRN_PSSCR,r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) std r1,PACAR1(r13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) mflr r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) mfcr r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * Use the stack red zone rather than a new frame for saving regs since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * in the case of no GPR loss the wakeup code branches directly back to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * the caller without deallocating the stack frame first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) std r2,-8*1(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) std r14,-8*2(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) std r15,-8*3(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) std r16,-8*4(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) std r17,-8*5(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) std r18,-8*6(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) std r19,-8*7(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) std r20,-8*8(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) std r21,-8*9(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) std r22,-8*10(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) std r23,-8*11(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) std r24,-8*12(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) std r25,-8*13(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) std r26,-8*14(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) std r27,-8*15(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) std r28,-8*16(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) std r29,-8*17(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) std r30,-8*18(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) std r31,-8*19(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) std r4,-8*20(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) std r5,-8*21(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* 168 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) PPC_STOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) b . /* catch bugs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * Desired return value in r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * The idle wakeup SRESET interrupt can call this after calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * to return to the idle sleep function caller with r3 as the return code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * This must not be used if idle was entered via a _noloss function (use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * a simple blr instead).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) _GLOBAL(idle_return_gpr_loss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ld r1,PACAR1(r13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ld r4,-8*20(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ld r5,-8*21(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) mtlr r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) mtcr r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * KVM nap requires r2 to be saved, rather than just restoring it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * from PACATOC. This could be avoided for that less common case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * if KVM saved its r2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ld r2,-8*1(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) ld r14,-8*2(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) ld r15,-8*3(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) ld r16,-8*4(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ld r17,-8*5(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ld r18,-8*6(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ld r19,-8*7(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ld r20,-8*8(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ld r21,-8*9(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ld r22,-8*10(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ld r23,-8*11(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) ld r24,-8*12(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ld r25,-8*13(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ld r26,-8*14(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ld r27,-8*15(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ld r28,-8*16(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) ld r29,-8*17(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) ld r30,-8*18(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ld r31,-8*19(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) blr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * This is the sequence required to execute idle instructions, as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * specified in ISA v2.07 (and earlier). MSR[IR] and MSR[DR] must be 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * We have to store a GPR somewhere, ptesync, then reload it, and create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * a false dependency on the result of the load. It doesn't matter which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * GPR we store, or where we store it. We have already stored r2 to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * stack at -8(r1) in isa206_idle_insn_mayloss, so use that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define IDLE_STATE_ENTER_SEQ_NORET(IDLE_INST) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* Magic NAP/SLEEP/WINKLE mode enter sequence */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) std r2,-8(r1); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ptesync; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) ld r2,-8(r1); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 236: cmpd cr0,r2,r2; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) bne 236b; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) IDLE_INST; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) b . /* catch bugs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * Desired instruction type in r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * GPRs may be lost, so they are saved here. Wakeup is by interrupt only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * The SRESET wakeup returns to this function's caller by calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * idle_return_gpr_loss with r3 set to desired return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * A wakeup without GPR loss may alteratively be handled as in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * isa300_idle_stop_noloss and blr directly, as an optimisation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * The caller is responsible for saving/restoring SPRs, MSR, timebase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * This must be called in real-mode (MSR_IDLE).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) _GLOBAL(isa206_idle_insn_mayloss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) std r1,PACAR1(r13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) mflr r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) mfcr r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * Use the stack red zone rather than a new frame for saving regs since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * in the case of no GPR loss the wakeup code branches directly back to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * the caller without deallocating the stack frame first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) std r2,-8*1(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) std r14,-8*2(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) std r15,-8*3(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) std r16,-8*4(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) std r17,-8*5(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) std r18,-8*6(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) std r19,-8*7(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) std r20,-8*8(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) std r21,-8*9(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) std r22,-8*10(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) std r23,-8*11(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) std r24,-8*12(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) std r25,-8*13(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) std r26,-8*14(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) std r27,-8*15(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) std r28,-8*16(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) std r29,-8*17(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) std r30,-8*18(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) std r31,-8*19(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) std r4,-8*20(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) std r5,-8*21(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) cmpwi r3,PNV_THREAD_NAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) bne 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) IDLE_STATE_ENTER_SEQ_NORET(PPC_NAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 1: cmpwi r3,PNV_THREAD_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) bne 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) IDLE_STATE_ENTER_SEQ_NORET(PPC_SLEEP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 2: IDLE_STATE_ENTER_SEQ_NORET(PPC_WINKLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #ifdef CONFIG_PPC_970_NAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) _GLOBAL(power4_idle_nap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) LOAD_REG_IMMEDIATE(r7, MSR_KERNEL|MSR_EE|MSR_POW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ld r9,PACA_THREAD_INFO(r13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) ld r8,TI_LOCAL_FLAGS(r9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ori r8,r8,_TLF_NAPPING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) std r8,TI_LOCAL_FLAGS(r9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * NAPPING bit is set, from this point onward power4_fixup_nap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * will cause exceptions to return to power4_idle_nap_return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 1: sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) isync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) mtmsrd r7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) isync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) b 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #endif