root/arch/powerpc/kernel/idle_book3s.S

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

/* [<][>][^][v][top][bottom][index][help] */