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