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