linux/arch/powerpc/kernel/idle_book3s.S
<<
>>
Prefs
   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);                                       \
 131236:    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)
 1801:      cmpwi   r3,PNV_THREAD_SLEEP
 181        bne     2f
 182        IDLE_STATE_ENTER_SEQ_NORET(PPC_SLEEP)
 1832:      IDLE_STATE_ENTER_SEQ_NORET(PPC_WINKLE)
 184
 185