linux/arch/powerpc/kernel/swsusp_booke.S
<<
>>
Prefs
   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 */
  691:      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 */
 1181:
 119        li      r0,256
 120        mtctr   r0
 121        lwz     r5,pbe_address(r3)      /* source */
 122        lwz     r6,pbe_orig_address(r3) /* destination */
 1232:
 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
 203