12874c5fdSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */ 283289f90SShreyas B. Prabhu/* 310d91611SNicholas Piggin * Copyright 2018, IBM Corporation. 483289f90SShreyas B. Prabhu * 510d91611SNicholas Piggin * This file contains general idle entry/exit functions to save 610d91611SNicholas Piggin * and restore stack and NVGPRs which allows C code to call idle 710d91611SNicholas Piggin * states that lose GPRs, and it will return transparently with 810d91611SNicholas Piggin * SRR1 wakeup reason return value. 910d91611SNicholas Piggin * 1010d91611SNicholas Piggin * The platform / CPU caller must ensure SPRs and any other non-GPR 1110d91611SNicholas Piggin * state is saved and restored correctly, handle KVM, interrupts, etc. 1283289f90SShreyas B. Prabhu */ 1383289f90SShreyas B. Prabhu 1483289f90SShreyas B. Prabhu#include <asm/ppc_asm.h> 1583289f90SShreyas B. Prabhu#include <asm/asm-offsets.h> 1683289f90SShreyas B. Prabhu#include <asm/ppc-opcode.h> 1783289f90SShreyas B. Prabhu#include <asm/cpuidle.h> 18ed0bc98fSNicholas Piggin#include <asm/thread_info.h> /* TLF_NAPPING */ 1983289f90SShreyas B. Prabhu 20ed0bc98fSNicholas Piggin#ifdef CONFIG_PPC_P7_NAP 2183289f90SShreyas B. Prabhu/* 2210d91611SNicholas Piggin * Desired PSSCR in r3 23e1c1cfedSGautham R. Shenoy * 2410d91611SNicholas Piggin * No state will be lost regardless of wakeup mechanism (interrupt or NIA). 2583289f90SShreyas B. Prabhu * 2610d91611SNicholas Piggin * An EC=0 type wakeup will return with a value of 0. SRESET wakeup (which can 2710d91611SNicholas Piggin * happen with xscom SRESET and possibly MCE) may clobber volatiles except LR, 2810d91611SNicholas Piggin * and must blr, to return to caller with r3 set according to caller's expected 2910d91611SNicholas Piggin * return code (for Book3S/64 that is SRR1). 3083289f90SShreyas B. Prabhu */ 3110d91611SNicholas Piggin_GLOBAL(isa300_idle_stop_noloss) 3210d91611SNicholas Piggin mtspr SPRN_PSSCR,r3 3310d91611SNicholas Piggin PPC_STOP 3410d91611SNicholas Piggin li r3,0 3510d91611SNicholas Piggin blr 3610d91611SNicholas Piggin 3710d91611SNicholas Piggin/* 3810d91611SNicholas Piggin * Desired PSSCR in r3 3910d91611SNicholas Piggin * 4010d91611SNicholas Piggin * GPRs may be lost, so they are saved here. Wakeup is by interrupt only. 4110d91611SNicholas Piggin * The SRESET wakeup returns to this function's caller by calling 4210d91611SNicholas Piggin * idle_return_gpr_loss with r3 set to desired return value. 4310d91611SNicholas Piggin * 4410d91611SNicholas Piggin * A wakeup without GPR loss may alteratively be handled as in 4510d91611SNicholas Piggin * isa300_idle_stop_noloss and blr directly, as an optimisation. 4610d91611SNicholas Piggin * 4710d91611SNicholas Piggin * The caller is responsible for saving/restoring SPRs, MSR, timebase, 4810d91611SNicholas Piggin * etc. 4983289f90SShreyas B. Prabhu */ 5010d91611SNicholas Piggin_GLOBAL(isa300_idle_stop_mayloss) 5110d91611SNicholas Piggin mtspr SPRN_PSSCR,r3 5283289f90SShreyas B. Prabhu std r1,PACAR1(r13) 5310d91611SNicholas Piggin mflr r4 5410d91611SNicholas Piggin mfcr r5 5573287caaSChristopher M. Riedl /* 5673287caaSChristopher M. Riedl * Use the stack red zone rather than a new frame for saving regs since 5773287caaSChristopher M. Riedl * in the case of no GPR loss the wakeup code branches directly back to 5873287caaSChristopher M. Riedl * the caller without deallocating the stack frame first. 5973287caaSChristopher M. Riedl */ 6073287caaSChristopher M. Riedl std r2,-8*1(r1) 6173287caaSChristopher M. Riedl std r14,-8*2(r1) 6273287caaSChristopher M. Riedl std r15,-8*3(r1) 6373287caaSChristopher M. Riedl std r16,-8*4(r1) 6473287caaSChristopher M. Riedl std r17,-8*5(r1) 6573287caaSChristopher M. Riedl std r18,-8*6(r1) 6673287caaSChristopher M. Riedl std r19,-8*7(r1) 6773287caaSChristopher M. Riedl std r20,-8*8(r1) 6873287caaSChristopher M. Riedl std r21,-8*9(r1) 6973287caaSChristopher M. Riedl std r22,-8*10(r1) 7073287caaSChristopher M. Riedl std r23,-8*11(r1) 7173287caaSChristopher M. Riedl std r24,-8*12(r1) 7273287caaSChristopher M. Riedl std r25,-8*13(r1) 7373287caaSChristopher M. Riedl std r26,-8*14(r1) 7473287caaSChristopher M. Riedl std r27,-8*15(r1) 7573287caaSChristopher M. Riedl std r28,-8*16(r1) 7673287caaSChristopher M. Riedl std r29,-8*17(r1) 7773287caaSChristopher M. Riedl std r30,-8*18(r1) 7873287caaSChristopher M. Riedl std r31,-8*19(r1) 7973287caaSChristopher M. Riedl std r4,-8*20(r1) 8073287caaSChristopher M. Riedl std r5,-8*21(r1) 8110d91611SNicholas Piggin /* 168 bytes */ 8210d91611SNicholas Piggin PPC_STOP 8310d91611SNicholas Piggin b . /* catch bugs */ 8483289f90SShreyas B. Prabhu 8583289f90SShreyas B. Prabhu/* 8610d91611SNicholas Piggin * Desired return value in r3 8710d91611SNicholas Piggin * 8810d91611SNicholas Piggin * The idle wakeup SRESET interrupt can call this after calling 8910d91611SNicholas Piggin * to return to the idle sleep function caller with r3 as the return code. 9010d91611SNicholas Piggin * 9110d91611SNicholas Piggin * This must not be used if idle was entered via a _noloss function (use 9210d91611SNicholas Piggin * a simple blr instead). 9372b0d51dSNicholas Piggin */ 9410d91611SNicholas Piggin_GLOBAL(idle_return_gpr_loss) 9510d91611SNicholas Piggin ld r1,PACAR1(r13) 9673287caaSChristopher M. Riedl ld r4,-8*20(r1) 9773287caaSChristopher M. Riedl ld r5,-8*21(r1) 9810d91611SNicholas Piggin mtlr r4 9910d91611SNicholas Piggin mtcr r5 10072b0d51dSNicholas Piggin /* 10110d91611SNicholas Piggin * KVM nap requires r2 to be saved, rather than just restoring it 10210d91611SNicholas Piggin * from PACATOC. This could be avoided for that less common case 10310d91611SNicholas Piggin * if KVM saved its r2. 10483289f90SShreyas B. Prabhu */ 10573287caaSChristopher M. Riedl ld r2,-8*1(r1) 10673287caaSChristopher M. Riedl ld r14,-8*2(r1) 10773287caaSChristopher M. Riedl ld r15,-8*3(r1) 10873287caaSChristopher M. Riedl ld r16,-8*4(r1) 10973287caaSChristopher M. Riedl ld r17,-8*5(r1) 11073287caaSChristopher M. Riedl ld r18,-8*6(r1) 11173287caaSChristopher M. Riedl ld r19,-8*7(r1) 11273287caaSChristopher M. Riedl ld r20,-8*8(r1) 11373287caaSChristopher M. Riedl ld r21,-8*9(r1) 11473287caaSChristopher M. Riedl ld r22,-8*10(r1) 11573287caaSChristopher M. Riedl ld r23,-8*11(r1) 11673287caaSChristopher M. Riedl ld r24,-8*12(r1) 11773287caaSChristopher M. Riedl ld r25,-8*13(r1) 11873287caaSChristopher M. Riedl ld r26,-8*14(r1) 11973287caaSChristopher M. Riedl ld r27,-8*15(r1) 12073287caaSChristopher M. Riedl ld r28,-8*16(r1) 12173287caaSChristopher M. Riedl ld r29,-8*17(r1) 12273287caaSChristopher M. Riedl ld r30,-8*18(r1) 12373287caaSChristopher M. Riedl ld r31,-8*19(r1) 12410d91611SNicholas Piggin blr 12583289f90SShreyas B. Prabhu 126aafc8a83SNicholas Piggin/* 127aafc8a83SNicholas Piggin * This is the sequence required to execute idle instructions, as 128aafc8a83SNicholas Piggin * specified in ISA v2.07 (and earlier). MSR[IR] and MSR[DR] must be 0. 129*496c5fe2SMichael Ellerman * We have to store a GPR somewhere, ptesync, then reload it, and create 130*496c5fe2SMichael Ellerman * a false dependency on the result of the load. It doesn't matter which 131*496c5fe2SMichael Ellerman * GPR we store, or where we store it. We have already stored r2 to the 132*496c5fe2SMichael Ellerman * stack at -8(r1) in isa206_idle_insn_mayloss, so use that. 133aafc8a83SNicholas Piggin */ 13465dbbe81SNicholas Piggin#define IDLE_STATE_ENTER_SEQ_NORET(IDLE_INST) \ 135aafc8a83SNicholas Piggin /* Magic NAP/SLEEP/WINKLE mode enter sequence */ \ 136*496c5fe2SMichael Ellerman std r2,-8(r1); \ 137aafc8a83SNicholas Piggin ptesync; \ 138*496c5fe2SMichael Ellerman ld r2,-8(r1); \ 13910d91611SNicholas Piggin236: cmpd cr0,r2,r2; \ 140aafc8a83SNicholas Piggin bne 236b; \ 14110d91611SNicholas Piggin IDLE_INST; \ 14210d91611SNicholas Piggin b . /* catch bugs */ 14383289f90SShreyas B. Prabhu 14483289f90SShreyas B. Prabhu/* 14510d91611SNicholas Piggin * Desired instruction type in r3 146a67cc594SMichael Ellerman * 14710d91611SNicholas Piggin * GPRs may be lost, so they are saved here. Wakeup is by interrupt only. 14810d91611SNicholas Piggin * The SRESET wakeup returns to this function's caller by calling 14910d91611SNicholas Piggin * idle_return_gpr_loss with r3 set to desired return value. 150a67cc594SMichael Ellerman * 15110d91611SNicholas Piggin * A wakeup without GPR loss may alteratively be handled as in 15210d91611SNicholas Piggin * isa300_idle_stop_noloss and blr directly, as an optimisation. 153d0b791c0SMichael Ellerman * 15410d91611SNicholas Piggin * The caller is responsible for saving/restoring SPRs, MSR, timebase, 15510d91611SNicholas Piggin * etc. 15610d91611SNicholas Piggin * 15710d91611SNicholas Piggin * This must be called in real-mode (MSR_IDLE). 158bcef83a0SShreyas B. Prabhu */ 15910d91611SNicholas Piggin_GLOBAL(isa206_idle_insn_mayloss) 16010d91611SNicholas Piggin std r1,PACAR1(r13) 16110d91611SNicholas Piggin mflr r4 16210d91611SNicholas Piggin mfcr r5 16373287caaSChristopher M. Riedl /* 16473287caaSChristopher M. Riedl * Use the stack red zone rather than a new frame for saving regs since 16573287caaSChristopher M. Riedl * in the case of no GPR loss the wakeup code branches directly back to 16673287caaSChristopher M. Riedl * the caller without deallocating the stack frame first. 16773287caaSChristopher M. Riedl */ 16873287caaSChristopher M. Riedl std r2,-8*1(r1) 16973287caaSChristopher M. Riedl std r14,-8*2(r1) 17073287caaSChristopher M. Riedl std r15,-8*3(r1) 17173287caaSChristopher M. Riedl std r16,-8*4(r1) 17273287caaSChristopher M. Riedl std r17,-8*5(r1) 17373287caaSChristopher M. Riedl std r18,-8*6(r1) 17473287caaSChristopher M. Riedl std r19,-8*7(r1) 17573287caaSChristopher M. Riedl std r20,-8*8(r1) 17673287caaSChristopher M. Riedl std r21,-8*9(r1) 17773287caaSChristopher M. Riedl std r22,-8*10(r1) 17873287caaSChristopher M. Riedl std r23,-8*11(r1) 17973287caaSChristopher M. Riedl std r24,-8*12(r1) 18073287caaSChristopher M. Riedl std r25,-8*13(r1) 18173287caaSChristopher M. Riedl std r26,-8*14(r1) 18273287caaSChristopher M. Riedl std r27,-8*15(r1) 18373287caaSChristopher M. Riedl std r28,-8*16(r1) 18473287caaSChristopher M. Riedl std r29,-8*17(r1) 18573287caaSChristopher M. Riedl std r30,-8*18(r1) 18673287caaSChristopher M. Riedl std r31,-8*19(r1) 18773287caaSChristopher M. Riedl std r4,-8*20(r1) 18873287caaSChristopher M. Riedl std r5,-8*21(r1) 18910d91611SNicholas Piggin cmpwi r3,PNV_THREAD_NAP 190a67cc594SMichael Ellerman bne 1f 19110d91611SNicholas Piggin IDLE_STATE_ENTER_SEQ_NORET(PPC_NAP) 19210d91611SNicholas Piggin1: cmpwi r3,PNV_THREAD_SLEEP 1930d7720a2SNicholas Piggin bne 2f 19410d91611SNicholas Piggin IDLE_STATE_ENTER_SEQ_NORET(PPC_SLEEP) 19510d91611SNicholas Piggin2: IDLE_STATE_ENTER_SEQ_NORET(PPC_WINKLE) 196ed0bc98fSNicholas Piggin#endif 1970d7720a2SNicholas Piggin 198ed0bc98fSNicholas Piggin#ifdef CONFIG_PPC_970_NAP 199ed0bc98fSNicholas Piggin_GLOBAL(power4_idle_nap) 200ed0bc98fSNicholas Piggin LOAD_REG_IMMEDIATE(r7, MSR_KERNEL|MSR_EE|MSR_POW) 201ed0bc98fSNicholas Piggin ld r9,PACA_THREAD_INFO(r13) 202ed0bc98fSNicholas Piggin ld r8,TI_LOCAL_FLAGS(r9) 203ed0bc98fSNicholas Piggin ori r8,r8,_TLF_NAPPING 204ed0bc98fSNicholas Piggin std r8,TI_LOCAL_FLAGS(r9) 205ed0bc98fSNicholas Piggin /* 206ed0bc98fSNicholas Piggin * NAPPING bit is set, from this point onward power4_fixup_nap 207ed0bc98fSNicholas Piggin * will cause exceptions to return to power4_idle_nap_return. 208ed0bc98fSNicholas Piggin */ 209ed0bc98fSNicholas Piggin1: sync 210ed0bc98fSNicholas Piggin isync 211ed0bc98fSNicholas Piggin mtmsrd r7 212ed0bc98fSNicholas Piggin isync 213ed0bc98fSNicholas Piggin b 1b 21498db179aSNicholas Piggin 21598db179aSNicholas Piggin .globl power4_idle_nap_return 21698db179aSNicholas Pigginpower4_idle_nap_return: 21798db179aSNicholas Piggin blr 218ed0bc98fSNicholas Piggin#endif 219