root/arch/powerpc/kernel/swsusp_booke.S

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

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