Merge tag 'microblaze-v5.15' of git://git.monstr.eu/linux-2.6-microblaze
[linux-2.6-microblaze.git] / arch / powerpc / kernel / swsusp_booke.S
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