linux/arch/powerpc/kernel/swsusp_asm64.S
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * PowerPC 64-bit swsusp implementation
   4 *
   5 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
   6 */
   7
   8#include <linux/threads.h>
   9#include <asm/processor.h>
  10#include <asm/page.h>
  11#include <asm/cputable.h>
  12#include <asm/thread_info.h>
  13#include <asm/ppc_asm.h>
  14#include <asm/asm-offsets.h>
  15#include <asm/feature-fixups.h>
  16
  17/*
  18 * Structure for storing CPU registers on the save area.
  19 */
  20#define SL_r1           0x00    /* stack pointer */
  21#define SL_PC           0x08
  22#define SL_MSR          0x10
  23#define SL_SDR1         0x18
  24#define SL_XER          0x20
  25#define SL_TB           0x40
  26#define SL_r2           0x48
  27#define SL_CR           0x50
  28#define SL_LR           0x58
  29#define SL_r12          0x60
  30#define SL_r13          0x68
  31#define SL_r14          0x70
  32#define SL_r15          0x78
  33#define SL_r16          0x80
  34#define SL_r17          0x88
  35#define SL_r18          0x90
  36#define SL_r19          0x98
  37#define SL_r20          0xa0
  38#define SL_r21          0xa8
  39#define SL_r22          0xb0
  40#define SL_r23          0xb8
  41#define SL_r24          0xc0
  42#define SL_r25          0xc8
  43#define SL_r26          0xd0
  44#define SL_r27          0xd8
  45#define SL_r28          0xe0
  46#define SL_r29          0xe8
  47#define SL_r30          0xf0
  48#define SL_r31          0xf8
  49#define SL_SPRG1        0x100
  50#define SL_TCR          0x108
  51#define SL_SIZE         SL_TCR+8
  52
  53/* these macros rely on the save area being
  54 * pointed to by r11 */
  55
  56#define SAVE_SPR(register)              \
  57        mfspr   r0, SPRN_##register     ;\
  58        std     r0, SL_##register(r11)
  59#define RESTORE_SPR(register)           \
  60        ld      r0, SL_##register(r11)  ;\
  61        mtspr   SPRN_##register, r0
  62#define SAVE_SPECIAL(special)           \
  63        mf##special     r0              ;\
  64        std     r0, SL_##special(r11)
  65#define RESTORE_SPECIAL(special)        \
  66        ld      r0, SL_##special(r11)   ;\
  67        mt##special     r0
  68#define SAVE_REGISTER(reg)              \
  69        std     reg, SL_##reg(r11)
  70#define RESTORE_REGISTER(reg)           \
  71        ld      reg, SL_##reg(r11)
  72
  73/* space for storing cpu state */
  74        .section .data
  75        .align  5
  76swsusp_save_area:
  77        .space SL_SIZE
  78
  79        .section ".toc","aw"
  80swsusp_save_area_ptr:
  81        .tc     swsusp_save_area[TC],swsusp_save_area
  82restore_pblist_ptr:
  83        .tc     restore_pblist[TC],restore_pblist
  84
  85        .section .text
  86        .align  5
  87_GLOBAL(swsusp_arch_suspend)
  88        ld      r11,swsusp_save_area_ptr@toc(r2)
  89        SAVE_SPECIAL(LR)
  90        SAVE_REGISTER(r1)
  91        SAVE_SPECIAL(CR)
  92        SAVE_SPECIAL(TB)
  93        SAVE_REGISTER(r2)
  94        SAVE_REGISTER(r12)
  95        SAVE_REGISTER(r13)
  96        SAVE_REGISTER(r14)
  97        SAVE_REGISTER(r15)
  98        SAVE_REGISTER(r16)
  99        SAVE_REGISTER(r17)
 100        SAVE_REGISTER(r18)
 101        SAVE_REGISTER(r19)
 102        SAVE_REGISTER(r20)
 103        SAVE_REGISTER(r21)
 104        SAVE_REGISTER(r22)
 105        SAVE_REGISTER(r23)
 106        SAVE_REGISTER(r24)
 107        SAVE_REGISTER(r25)
 108        SAVE_REGISTER(r26)
 109        SAVE_REGISTER(r27)
 110        SAVE_REGISTER(r28)
 111        SAVE_REGISTER(r29)
 112        SAVE_REGISTER(r30)
 113        SAVE_REGISTER(r31)
 114        SAVE_SPECIAL(MSR)
 115        SAVE_SPECIAL(XER)
 116#ifdef CONFIG_PPC_BOOK3S_64
 117BEGIN_FW_FTR_SECTION
 118        SAVE_SPECIAL(SDR1)
 119END_FW_FTR_SECTION_IFCLR(FW_FEATURE_LPAR)
 120#else
 121        SAVE_SPR(TCR)
 122
 123        /* Save SPRG1, SPRG1 be used save paca */
 124        SAVE_SPR(SPRG1)
 125#endif
 126
 127        /* we push the stack up 128 bytes but don't store the
 128         * stack pointer on the stack like a real stackframe */
 129        addi    r1,r1,-128
 130
 131        bl _iommu_save
 132        bl swsusp_save
 133
 134        /* restore LR */
 135        ld      r11,swsusp_save_area_ptr@toc(r2)
 136        RESTORE_SPECIAL(LR)
 137        addi    r1,r1,128
 138
 139        blr
 140
 141/* Resume code */
 142_GLOBAL(swsusp_arch_resume)
 143        /* Stop pending alitvec streams and memory accesses */
 144BEGIN_FTR_SECTION
 145        DSSALL
 146END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 147        sync
 148
 149        ld      r12,restore_pblist_ptr@toc(r2)
 150        ld      r12,0(r12)
 151
 152        cmpdi   r12,0
 153        beq-    nothing_to_copy
 154        li      r15,PAGE_SIZE>>3
 155copyloop:
 156        ld      r13,pbe_address(r12)
 157        ld      r14,pbe_orig_address(r12)
 158
 159        mtctr   r15
 160        li      r10,0
 161copy_page_loop:
 162        ldx     r0,r10,r13
 163        stdx    r0,r10,r14
 164        addi    r10,r10,8
 165        bdnz copy_page_loop
 166
 167        ld      r12,pbe_next(r12)
 168        cmpdi   r12,0
 169        bne+    copyloop
 170nothing_to_copy:
 171
 172#ifdef CONFIG_PPC_BOOK3S_64
 173        /* flush caches */
 174        lis     r3, 0x10
 175        mtctr   r3
 176        li      r3, 0
 177        ori     r3, r3, CONFIG_KERNEL_START>>48
 178        li      r0, 48
 179        sld     r3, r3, r0
 180        li      r0, 0
 1811:
 182        dcbf    0,r3
 183        addi    r3,r3,0x20
 184        bdnz    1b
 185
 186        sync
 187
 188        tlbia
 189#endif
 190
 191        ld      r11,swsusp_save_area_ptr@toc(r2)
 192
 193        RESTORE_SPECIAL(CR)
 194
 195        /* restore timebase */
 196        /* load saved tb */
 197        ld      r1, SL_TB(r11)
 198        /* get upper 32 bits of it */
 199        srdi    r2, r1, 32
 200        /* clear tb lower to avoid wrap */
 201        li      r0, 0
 202        mttbl   r0
 203        /* set tb upper */
 204        mttbu   r2
 205        /* set tb lower */
 206        mttbl   r1
 207
 208        /* restore registers */
 209        RESTORE_REGISTER(r1)
 210        RESTORE_REGISTER(r2)
 211        RESTORE_REGISTER(r12)
 212        RESTORE_REGISTER(r13)
 213        RESTORE_REGISTER(r14)
 214        RESTORE_REGISTER(r15)
 215        RESTORE_REGISTER(r16)
 216        RESTORE_REGISTER(r17)
 217        RESTORE_REGISTER(r18)
 218        RESTORE_REGISTER(r19)
 219        RESTORE_REGISTER(r20)
 220        RESTORE_REGISTER(r21)
 221        RESTORE_REGISTER(r22)
 222        RESTORE_REGISTER(r23)
 223        RESTORE_REGISTER(r24)
 224        RESTORE_REGISTER(r25)
 225        RESTORE_REGISTER(r26)
 226        RESTORE_REGISTER(r27)
 227        RESTORE_REGISTER(r28)
 228        RESTORE_REGISTER(r29)
 229        RESTORE_REGISTER(r30)
 230        RESTORE_REGISTER(r31)
 231
 232#ifdef CONFIG_PPC_BOOK3S_64
 233        /* can't use RESTORE_SPECIAL(MSR) */
 234        ld      r0, SL_MSR(r11)
 235        mtmsrd  r0, 0
 236BEGIN_FW_FTR_SECTION
 237        RESTORE_SPECIAL(SDR1)
 238END_FW_FTR_SECTION_IFCLR(FW_FEATURE_LPAR)
 239#else
 240        /* Restore SPRG1, be used to save paca */
 241        ld      r0, SL_SPRG1(r11)
 242        mtsprg  1, r0
 243
 244        RESTORE_SPECIAL(MSR)
 245
 246        /* Restore TCR and clear any pending bits in TSR. */
 247        RESTORE_SPR(TCR)
 248        lis     r0, (TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS)@h
 249        mtspr   SPRN_TSR, r0
 250
 251        /* Kick decrementer */
 252        li      r0, 1
 253        mtdec   r0
 254
 255        /* Invalidate all tlbs */
 256        bl      _tlbil_all
 257#endif
 258        RESTORE_SPECIAL(XER)
 259
 260        sync
 261
 262        addi    r1,r1,-128
 263#ifdef CONFIG_PPC_BOOK3S_64
 264        bl      slb_flush_and_restore_bolted
 265#endif
 266        bl      do_after_copyback
 267        addi    r1,r1,128
 268
 269        ld      r11,swsusp_save_area_ptr@toc(r2)
 270        RESTORE_SPECIAL(LR)
 271
 272        li      r3, 0
 273        blr
 274