linux/arch/powerpc/kernel/swsusp_asm64.S
<<
>>
Prefs
   1/*
   2 * PowerPC 64-bit swsusp implementation
   3 *
   4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
   5 *
   6 * GPLv2
   7 */
   8
   9#include <linux/threads.h>
  10#include <asm/processor.h>
  11#include <asm/page.h>
  12#include <asm/cputable.h>
  13#include <asm/thread_info.h>
  14#include <asm/ppc_asm.h>
  15#include <asm/asm-offsets.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
 117        SAVE_SPECIAL(SDR1)
 118#else
 119        SAVE_SPR(TCR)
 120
 121        /* Save SPRG1, SPRG1 be used save paca */
 122        SAVE_SPR(SPRG1)
 123#endif
 124
 125        /* we push the stack up 128 bytes but don't store the
 126         * stack pointer on the stack like a real stackframe */
 127        addi    r1,r1,-128
 128
 129        bl _iommu_save
 130        bl swsusp_save
 131
 132        /* restore LR */
 133        ld      r11,swsusp_save_area_ptr@toc(r2)
 134        RESTORE_SPECIAL(LR)
 135        addi    r1,r1,128
 136
 137        blr
 138
 139/* Resume code */
 140_GLOBAL(swsusp_arch_resume)
 141        /* Stop pending alitvec streams and memory accesses */
 142BEGIN_FTR_SECTION
 143        DSSALL
 144END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 145        sync
 146
 147        ld      r12,restore_pblist_ptr@toc(r2)
 148        ld      r12,0(r12)
 149
 150        cmpdi   r12,0
 151        beq-    nothing_to_copy
 152        li      r15,PAGE_SIZE>>3
 153copyloop:
 154        ld      r13,pbe_address(r12)
 155        ld      r14,pbe_orig_address(r12)
 156
 157        mtctr   r15
 158        li      r10,0
 159copy_page_loop:
 160        ldx     r0,r10,r13
 161        stdx    r0,r10,r14
 162        addi    r10,r10,8
 163        bdnz copy_page_loop
 164
 165        ld      r12,pbe_next(r12)
 166        cmpdi   r12,0
 167        bne+    copyloop
 168nothing_to_copy:
 169
 170#ifdef CONFIG_PPC_BOOK3S_64
 171        /* flush caches */
 172        lis     r3, 0x10
 173        mtctr   r3
 174        li      r3, 0
 175        ori     r3, r3, CONFIG_KERNEL_START>>48
 176        li      r0, 48
 177        sld     r3, r3, r0
 178        li      r0, 0
 1791:
 180        dcbf    r0,r3
 181        addi    r3,r3,0x20
 182        bdnz    1b
 183
 184        sync
 185
 186        tlbia
 187#endif
 188
 189        ld      r11,swsusp_save_area_ptr@toc(r2)
 190
 191        RESTORE_SPECIAL(CR)
 192
 193        /* restore timebase */
 194        /* load saved tb */
 195        ld      r1, SL_TB(r11)
 196        /* get upper 32 bits of it */
 197        srdi    r2, r1, 32
 198        /* clear tb lower to avoid wrap */
 199        li      r0, 0
 200        mttbl   r0
 201        /* set tb upper */
 202        mttbu   r2
 203        /* set tb lower */
 204        mttbl   r1
 205
 206        /* restore registers */
 207        RESTORE_REGISTER(r1)
 208        RESTORE_REGISTER(r2)
 209        RESTORE_REGISTER(r12)
 210        RESTORE_REGISTER(r13)
 211        RESTORE_REGISTER(r14)
 212        RESTORE_REGISTER(r15)
 213        RESTORE_REGISTER(r16)
 214        RESTORE_REGISTER(r17)
 215        RESTORE_REGISTER(r18)
 216        RESTORE_REGISTER(r19)
 217        RESTORE_REGISTER(r20)
 218        RESTORE_REGISTER(r21)
 219        RESTORE_REGISTER(r22)
 220        RESTORE_REGISTER(r23)
 221        RESTORE_REGISTER(r24)
 222        RESTORE_REGISTER(r25)
 223        RESTORE_REGISTER(r26)
 224        RESTORE_REGISTER(r27)
 225        RESTORE_REGISTER(r28)
 226        RESTORE_REGISTER(r29)
 227        RESTORE_REGISTER(r30)
 228        RESTORE_REGISTER(r31)
 229
 230#ifdef CONFIG_PPC_BOOK3S_64
 231        /* can't use RESTORE_SPECIAL(MSR) */
 232        ld      r0, SL_MSR(r11)
 233        mtmsrd  r0, 0
 234        RESTORE_SPECIAL(SDR1)
 235#else
 236        /* Restore SPRG1, be used to save paca */
 237        ld      r0, SL_SPRG1(r11)
 238        mtsprg  1, r0
 239
 240        RESTORE_SPECIAL(MSR)
 241
 242        /* Restore TCR and clear any pending bits in TSR. */
 243        RESTORE_SPR(TCR)
 244        lis     r0, (TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS)@h
 245        mtspr   SPRN_TSR, r0
 246
 247        /* Kick decrementer */
 248        li      r0, 1
 249        mtdec   r0
 250
 251        /* Invalidate all tlbs */
 252        bl      _tlbil_all
 253#endif
 254        RESTORE_SPECIAL(XER)
 255
 256        sync
 257
 258        addi    r1,r1,-128
 259#ifdef CONFIG_PPC_BOOK3S_64
 260        bl      slb_flush_and_rebolt
 261#endif
 262        bl      do_after_copyback
 263        addi    r1,r1,128
 264
 265        ld      r11,swsusp_save_area_ptr@toc(r2)
 266        RESTORE_SPECIAL(LR)
 267
 268        li      r3, 0
 269        blr
 270