GNU Linux-libre 4.19.264-gnu1
[releases.git] / arch / powerpc / kernel / swsusp_asm64.S
1 /*
2  * PowerPC 64-bit swsusp implementation
3  *
4  * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5  *
6  * GPLv2
7  */
8
9 #include <linux/threads.h>
10 #include <asm/processor.h>
11 #include <asm/page.h>
12 #include <asm/cputable.h>
13 #include <asm/thread_info.h>
14 #include <asm/ppc_asm.h>
15 #include <asm/asm-offsets.h>
16 #include <asm/feature-fixups.h>
17
18 /*
19  * Structure for storing CPU registers on the save area.
20  */
21 #define SL_r1           0x00    /* stack pointer */
22 #define SL_PC           0x08
23 #define SL_MSR          0x10
24 #define SL_SDR1         0x18
25 #define SL_XER          0x20
26 #define SL_TB           0x40
27 #define SL_r2           0x48
28 #define SL_CR           0x50
29 #define SL_LR           0x58
30 #define SL_r12          0x60
31 #define SL_r13          0x68
32 #define SL_r14          0x70
33 #define SL_r15          0x78
34 #define SL_r16          0x80
35 #define SL_r17          0x88
36 #define SL_r18          0x90
37 #define SL_r19          0x98
38 #define SL_r20          0xa0
39 #define SL_r21          0xa8
40 #define SL_r22          0xb0
41 #define SL_r23          0xb8
42 #define SL_r24          0xc0
43 #define SL_r25          0xc8
44 #define SL_r26          0xd0
45 #define SL_r27          0xd8
46 #define SL_r28          0xe0
47 #define SL_r29          0xe8
48 #define SL_r30          0xf0
49 #define SL_r31          0xf8
50 #define SL_SPRG1        0x100
51 #define SL_TCR          0x108
52 #define SL_SIZE         SL_TCR+8
53
54 /* these macros rely on the save area being
55  * pointed to by r11 */
56
57 #define SAVE_SPR(register)              \
58         mfspr   r0, SPRN_##register     ;\
59         std     r0, SL_##register(r11)
60 #define RESTORE_SPR(register)           \
61         ld      r0, SL_##register(r11)  ;\
62         mtspr   SPRN_##register, r0
63 #define SAVE_SPECIAL(special)           \
64         mf##special     r0              ;\
65         std     r0, SL_##special(r11)
66 #define RESTORE_SPECIAL(special)        \
67         ld      r0, SL_##special(r11)   ;\
68         mt##special     r0
69 #define SAVE_REGISTER(reg)              \
70         std     reg, SL_##reg(r11)
71 #define RESTORE_REGISTER(reg)           \
72         ld      reg, SL_##reg(r11)
73
74 /* space for storing cpu state */
75         .section .data
76         .align  5
77 swsusp_save_area:
78         .space SL_SIZE
79
80         .section ".toc","aw"
81 swsusp_save_area_ptr:
82         .tc     swsusp_save_area[TC],swsusp_save_area
83 restore_pblist_ptr:
84         .tc     restore_pblist[TC],restore_pblist
85
86         .section .text
87         .align  5
88 _GLOBAL(swsusp_arch_suspend)
89         ld      r11,swsusp_save_area_ptr@toc(r2)
90         SAVE_SPECIAL(LR)
91         SAVE_REGISTER(r1)
92         SAVE_SPECIAL(CR)
93         SAVE_SPECIAL(TB)
94         SAVE_REGISTER(r2)
95         SAVE_REGISTER(r12)
96         SAVE_REGISTER(r13)
97         SAVE_REGISTER(r14)
98         SAVE_REGISTER(r15)
99         SAVE_REGISTER(r16)
100         SAVE_REGISTER(r17)
101         SAVE_REGISTER(r18)
102         SAVE_REGISTER(r19)
103         SAVE_REGISTER(r20)
104         SAVE_REGISTER(r21)
105         SAVE_REGISTER(r22)
106         SAVE_REGISTER(r23)
107         SAVE_REGISTER(r24)
108         SAVE_REGISTER(r25)
109         SAVE_REGISTER(r26)
110         SAVE_REGISTER(r27)
111         SAVE_REGISTER(r28)
112         SAVE_REGISTER(r29)
113         SAVE_REGISTER(r30)
114         SAVE_REGISTER(r31)
115         SAVE_SPECIAL(MSR)
116         SAVE_SPECIAL(XER)
117 #ifdef CONFIG_PPC_BOOK3S_64
118 BEGIN_FW_FTR_SECTION
119         SAVE_SPECIAL(SDR1)
120 END_FW_FTR_SECTION_IFCLR(FW_FEATURE_LPAR)
121 #else
122         SAVE_SPR(TCR)
123
124         /* Save SPRG1, SPRG1 be used save paca */
125         SAVE_SPR(SPRG1)
126 #endif
127
128         /* we push the stack up 128 bytes but don't store the
129          * stack pointer on the stack like a real stackframe */
130         addi    r1,r1,-128
131
132         bl _iommu_save
133         bl swsusp_save
134
135         /* restore LR */
136         ld      r11,swsusp_save_area_ptr@toc(r2)
137         RESTORE_SPECIAL(LR)
138         addi    r1,r1,128
139
140         blr
141
142 /* Resume code */
143 _GLOBAL(swsusp_arch_resume)
144         /* Stop pending alitvec streams and memory accesses */
145 BEGIN_FTR_SECTION
146         PPC_DSSALL
147 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
148         sync
149
150         ld      r12,restore_pblist_ptr@toc(r2)
151         ld      r12,0(r12)
152
153         cmpdi   r12,0
154         beq-    nothing_to_copy
155         li      r15,PAGE_SIZE>>3
156 copyloop:
157         ld      r13,pbe_address(r12)
158         ld      r14,pbe_orig_address(r12)
159
160         mtctr   r15
161         li      r10,0
162 copy_page_loop:
163         ldx     r0,r10,r13
164         stdx    r0,r10,r14
165         addi    r10,r10,8
166         bdnz copy_page_loop
167
168         ld      r12,pbe_next(r12)
169         cmpdi   r12,0
170         bne+    copyloop
171 nothing_to_copy:
172
173 #ifdef CONFIG_PPC_BOOK3S_64
174         /* flush caches */
175         lis     r3, 0x10
176         mtctr   r3
177         li      r3, 0
178         ori     r3, r3, CONFIG_KERNEL_START>>48
179         li      r0, 48
180         sld     r3, r3, r0
181         li      r0, 0
182 1:
183         dcbf    0,r3
184         addi    r3,r3,0x20
185         bdnz    1b
186
187         sync
188
189         tlbia
190 #endif
191
192         ld      r11,swsusp_save_area_ptr@toc(r2)
193
194         RESTORE_SPECIAL(CR)
195
196         /* restore timebase */
197         /* load saved tb */
198         ld      r1, SL_TB(r11)
199         /* get upper 32 bits of it */
200         srdi    r2, r1, 32
201         /* clear tb lower to avoid wrap */
202         li      r0, 0
203         mttbl   r0
204         /* set tb upper */
205         mttbu   r2
206         /* set tb lower */
207         mttbl   r1
208
209         /* restore registers */
210         RESTORE_REGISTER(r1)
211         RESTORE_REGISTER(r2)
212         RESTORE_REGISTER(r12)
213         RESTORE_REGISTER(r13)
214         RESTORE_REGISTER(r14)
215         RESTORE_REGISTER(r15)
216         RESTORE_REGISTER(r16)
217         RESTORE_REGISTER(r17)
218         RESTORE_REGISTER(r18)
219         RESTORE_REGISTER(r19)
220         RESTORE_REGISTER(r20)
221         RESTORE_REGISTER(r21)
222         RESTORE_REGISTER(r22)
223         RESTORE_REGISTER(r23)
224         RESTORE_REGISTER(r24)
225         RESTORE_REGISTER(r25)
226         RESTORE_REGISTER(r26)
227         RESTORE_REGISTER(r27)
228         RESTORE_REGISTER(r28)
229         RESTORE_REGISTER(r29)
230         RESTORE_REGISTER(r30)
231         RESTORE_REGISTER(r31)
232
233 #ifdef CONFIG_PPC_BOOK3S_64
234         /* can't use RESTORE_SPECIAL(MSR) */
235         ld      r0, SL_MSR(r11)
236         mtmsrd  r0, 0
237 BEGIN_FW_FTR_SECTION
238         RESTORE_SPECIAL(SDR1)
239 END_FW_FTR_SECTION_IFCLR(FW_FEATURE_LPAR)
240 #else
241         /* Restore SPRG1, be used to save paca */
242         ld      r0, SL_SPRG1(r11)
243         mtsprg  1, r0
244
245         RESTORE_SPECIAL(MSR)
246
247         /* Restore TCR and clear any pending bits in TSR. */
248         RESTORE_SPR(TCR)
249         lis     r0, (TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS)@h
250         mtspr   SPRN_TSR, r0
251
252         /* Kick decrementer */
253         li      r0, 1
254         mtdec   r0
255
256         /* Invalidate all tlbs */
257         bl      _tlbil_all
258 #endif
259         RESTORE_SPECIAL(XER)
260
261         sync
262
263         addi    r1,r1,-128
264 #ifdef CONFIG_PPC_BOOK3S_64
265         bl      slb_flush_and_rebolt
266 #endif
267         bl      do_after_copyback
268         addi    r1,r1,128
269
270         ld      r11,swsusp_save_area_ptr@toc(r2)
271         RESTORE_SPECIAL(LR)
272
273         li      r3, 0
274         blr