linux/arch/powerpc/kernel/swsusp_booke.S
<<
>>
Prefs
   1/*
   2 * Based on swsusp_32.S, modified for FSL BookE by
   3 * Anton Vorontsov <avorontsov@ru.mvista.com>
   4 * Copyright (c) 2009-2010 MontaVista Software, LLC.
   5 */
   6
   7#include <linux/threads.h>
   8#include <asm/processor.h>
   9#include <asm/page.h>
  10#include <asm/cputable.h>
  11#include <asm/thread_info.h>
  12#include <asm/ppc_asm.h>
  13#include <asm/asm-offsets.h>
  14#include <asm/mmu.h>
  15
  16/*
  17 * Structure for storing CPU registers on the save area.
  18 */
  19#define SL_SP           0
  20#define SL_PC           4
  21#define SL_MSR          8
  22#define SL_TCR          0xc
  23#define SL_SPRG0        0x10
  24#define SL_SPRG1        0x14
  25#define SL_SPRG2        0x18
  26#define SL_SPRG3        0x1c
  27#define SL_SPRG4        0x20
  28#define SL_SPRG5        0x24
  29#define SL_SPRG6        0x28
  30#define SL_SPRG7        0x2c
  31#define SL_TBU          0x30
  32#define SL_TBL          0x34
  33#define SL_R2           0x38
  34#define SL_CR           0x3c
  35#define SL_LR           0x40
  36#define SL_R12          0x44    /* r12 to r31 */
  37#define SL_SIZE         (SL_R12 + 80)
  38
  39        .section .data
  40        .align  5
  41
  42_GLOBAL(swsusp_save_area)
  43        .space  SL_SIZE
  44
  45
  46        .section .text
  47        .align  5
  48
  49_GLOBAL(swsusp_arch_suspend)
  50        lis     r11,swsusp_save_area@h
  51        ori     r11,r11,swsusp_save_area@l
  52
  53        mflr    r0
  54        stw     r0,SL_LR(r11)
  55        mfcr    r0
  56        stw     r0,SL_CR(r11)
  57        stw     r1,SL_SP(r11)
  58        stw     r2,SL_R2(r11)
  59        stmw    r12,SL_R12(r11)
  60
  61        /* Save MSR & TCR */
  62        mfmsr   r4
  63        stw     r4,SL_MSR(r11)
  64        mfspr   r4,SPRN_TCR
  65        stw     r4,SL_TCR(r11)
  66
  67        /* Get a stable timebase and save it */
  681:      mfspr   r4,SPRN_TBRU
  69        stw     r4,SL_TBU(r11)
  70        mfspr   r5,SPRN_TBRL
  71        stw     r5,SL_TBL(r11)
  72        mfspr   r3,SPRN_TBRU
  73        cmpw    r3,r4
  74        bne     1b
  75
  76        /* Save SPRGs */
  77        mfsprg  r4,0
  78        stw     r4,SL_SPRG0(r11)
  79        mfsprg  r4,1
  80        stw     r4,SL_SPRG1(r11)
  81        mfsprg  r4,2
  82        stw     r4,SL_SPRG2(r11)
  83        mfsprg  r4,3
  84        stw     r4,SL_SPRG3(r11)
  85        mfsprg  r4,4
  86        stw     r4,SL_SPRG4(r11)
  87        mfsprg  r4,5
  88        stw     r4,SL_SPRG5(r11)
  89        mfsprg  r4,6
  90        stw     r4,SL_SPRG6(r11)
  91        mfsprg  r4,7
  92        stw     r4,SL_SPRG7(r11)
  93
  94        /* Call the low level suspend stuff (we should probably have made
  95         * a stackframe...
  96         */
  97        bl      swsusp_save
  98
  99        /* Restore LR from the save area */
 100        lis     r11,swsusp_save_area@h
 101        ori     r11,r11,swsusp_save_area@l
 102        lwz     r0,SL_LR(r11)
 103        mtlr    r0
 104
 105        blr
 106
 107_GLOBAL(swsusp_arch_resume)
 108        sync
 109
 110        /* Load ptr the list of pages to copy in r3 */
 111        lis     r11,(restore_pblist)@h
 112        ori     r11,r11,restore_pblist@l
 113        lwz     r3,0(r11)
 114
 115        /* Copy the pages. This is a very basic implementation, to
 116         * be replaced by something more cache efficient */
 1171:
 118        li      r0,256
 119        mtctr   r0
 120        lwz     r5,pbe_address(r3)      /* source */
 121        lwz     r6,pbe_orig_address(r3) /* destination */
 1222:
 123        lwz     r8,0(r5)
 124        lwz     r9,4(r5)
 125        lwz     r10,8(r5)
 126        lwz     r11,12(r5)
 127        addi    r5,r5,16
 128        stw     r8,0(r6)
 129        stw     r9,4(r6)
 130        stw     r10,8(r6)
 131        stw     r11,12(r6)
 132        addi    r6,r6,16
 133        bdnz    2b
 134        lwz     r3,pbe_next(r3)
 135        cmpwi   0,r3,0
 136        bne     1b
 137
 138        bl flush_dcache_L1
 139        bl flush_instruction_cache
 140
 141        lis     r11,swsusp_save_area@h
 142        ori     r11,r11,swsusp_save_area@l
 143
 144        /*
 145         * Mappings from virtual addresses to physical addresses may be
 146         * different than they were prior to restoring hibernation state. 
 147         * Invalidate the TLB so that the boot CPU is using the new
 148         * mappings.
 149         */
 150        bl      _tlbil_all
 151
 152        lwz     r4,SL_SPRG0(r11)
 153        mtsprg  0,r4
 154        lwz     r4,SL_SPRG1(r11)
 155        mtsprg  1,r4
 156        lwz     r4,SL_SPRG2(r11)
 157        mtsprg  2,r4
 158        lwz     r4,SL_SPRG3(r11)
 159        mtsprg  3,r4
 160        lwz     r4,SL_SPRG4(r11)
 161        mtsprg  4,r4
 162        lwz     r4,SL_SPRG5(r11)
 163        mtsprg  5,r4
 164        lwz     r4,SL_SPRG6(r11)
 165        mtsprg  6,r4
 166        lwz     r4,SL_SPRG7(r11)
 167        mtsprg  7,r4
 168
 169        /* restore the MSR */
 170        lwz     r3,SL_MSR(r11)
 171        mtmsr   r3
 172
 173        /* Restore TB */
 174        li      r3,0
 175        mtspr   SPRN_TBWL,r3
 176        lwz     r3,SL_TBU(r11)
 177        lwz     r4,SL_TBL(r11)
 178        mtspr   SPRN_TBWU,r3
 179        mtspr   SPRN_TBWL,r4
 180
 181        /* Restore TCR and clear any pending bits in TSR. */
 182        lwz     r4,SL_TCR(r11)
 183        mtspr   SPRN_TCR,r4
 184        lis     r4, (TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS)@h
 185        mtspr   SPRN_TSR,r4
 186
 187        /* Kick decrementer */
 188        li      r0,1
 189        mtdec   r0
 190
 191        /* Restore the callee-saved registers and return */
 192        lwz     r0,SL_CR(r11)
 193        mtcr    r0
 194        lwz     r2,SL_R2(r11)
 195        lmw     r12,SL_R12(r11)
 196        lwz     r1,SL_SP(r11)
 197        lwz     r0,SL_LR(r11)
 198        mtlr    r0
 199
 200        li      r3,0
 201        blr
 202