Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
[sfrench/cifs-2.6.git] / arch / powerpc / kernel / swsusp_32.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #include <linux/threads.h>
3 #include <asm/processor.h>
4 #include <asm/page.h>
5 #include <asm/cputable.h>
6 #include <asm/thread_info.h>
7 #include <asm/ppc_asm.h>
8 #include <asm/asm-offsets.h>
9 #include <asm/mmu.h>
10 #include <asm/feature-fixups.h>
11
12 /*
13  * Structure for storing CPU registers on the save area.
14  */
15 #define SL_SP           0
16 #define SL_PC           4
17 #define SL_MSR          8
18 #define SL_SDR1         0xc
19 #define SL_SPRG0        0x10    /* 4 sprg's */
20 #define SL_DBAT0        0x20
21 #define SL_IBAT0        0x28
22 #define SL_DBAT1        0x30
23 #define SL_IBAT1        0x38
24 #define SL_DBAT2        0x40
25 #define SL_IBAT2        0x48
26 #define SL_DBAT3        0x50
27 #define SL_IBAT3        0x58
28 #define SL_DBAT4        0x60
29 #define SL_IBAT4        0x68
30 #define SL_DBAT5        0x70
31 #define SL_IBAT5        0x78
32 #define SL_DBAT6        0x80
33 #define SL_IBAT6        0x88
34 #define SL_DBAT7        0x90
35 #define SL_IBAT7        0x98
36 #define SL_TB           0xa0
37 #define SL_R2           0xa8
38 #define SL_CR           0xac
39 #define SL_LR           0xb0
40 #define SL_R12          0xb4    /* r12 to r31 */
41 #define SL_SIZE         (SL_R12 + 80)
42
43         .section .data
44         .align  5
45
46 _GLOBAL(swsusp_save_area)
47         .space  SL_SIZE
48
49
50         .section .text
51         .align  5
52
53 _GLOBAL(swsusp_arch_suspend)
54
55         lis     r11,swsusp_save_area@h
56         ori     r11,r11,swsusp_save_area@l
57
58         mflr    r0
59         stw     r0,SL_LR(r11)
60         mfcr    r0
61         stw     r0,SL_CR(r11)
62         stw     r1,SL_SP(r11)
63         stw     r2,SL_R2(r11)
64         stmw    r12,SL_R12(r11)
65
66         /* Save MSR & SDR1 */
67         mfmsr   r4
68         stw     r4,SL_MSR(r11)
69         mfsdr1  r4
70         stw     r4,SL_SDR1(r11)
71
72         /* Get a stable timebase and save it */
73 1:      mftbu   r4
74         stw     r4,SL_TB(r11)
75         mftb    r5
76         stw     r5,SL_TB+4(r11)
77         mftbu   r3
78         cmpw    r3,r4
79         bne     1b
80
81         /* Save SPRGs */
82         mfsprg  r4,0
83         stw     r4,SL_SPRG0(r11)
84         mfsprg  r4,1
85         stw     r4,SL_SPRG0+4(r11)
86         mfsprg  r4,2
87         stw     r4,SL_SPRG0+8(r11)
88         mfsprg  r4,3
89         stw     r4,SL_SPRG0+12(r11)
90
91         /* Save BATs */
92         mfdbatu r4,0
93         stw     r4,SL_DBAT0(r11)
94         mfdbatl r4,0
95         stw     r4,SL_DBAT0+4(r11)
96         mfdbatu r4,1
97         stw     r4,SL_DBAT1(r11)
98         mfdbatl r4,1
99         stw     r4,SL_DBAT1+4(r11)
100         mfdbatu r4,2
101         stw     r4,SL_DBAT2(r11)
102         mfdbatl r4,2
103         stw     r4,SL_DBAT2+4(r11)
104         mfdbatu r4,3
105         stw     r4,SL_DBAT3(r11)
106         mfdbatl r4,3
107         stw     r4,SL_DBAT3+4(r11)
108         mfibatu r4,0
109         stw     r4,SL_IBAT0(r11)
110         mfibatl r4,0
111         stw     r4,SL_IBAT0+4(r11)
112         mfibatu r4,1
113         stw     r4,SL_IBAT1(r11)
114         mfibatl r4,1
115         stw     r4,SL_IBAT1+4(r11)
116         mfibatu r4,2
117         stw     r4,SL_IBAT2(r11)
118         mfibatl r4,2
119         stw     r4,SL_IBAT2+4(r11)
120         mfibatu r4,3
121         stw     r4,SL_IBAT3(r11)
122         mfibatl r4,3
123         stw     r4,SL_IBAT3+4(r11)
124
125 BEGIN_MMU_FTR_SECTION
126         mfspr   r4,SPRN_DBAT4U
127         stw     r4,SL_DBAT4(r11)
128         mfspr   r4,SPRN_DBAT4L
129         stw     r4,SL_DBAT4+4(r11)
130         mfspr   r4,SPRN_DBAT5U
131         stw     r4,SL_DBAT5(r11)
132         mfspr   r4,SPRN_DBAT5L
133         stw     r4,SL_DBAT5+4(r11)
134         mfspr   r4,SPRN_DBAT6U
135         stw     r4,SL_DBAT6(r11)
136         mfspr   r4,SPRN_DBAT6L
137         stw     r4,SL_DBAT6+4(r11)
138         mfspr   r4,SPRN_DBAT7U
139         stw     r4,SL_DBAT7(r11)
140         mfspr   r4,SPRN_DBAT7L
141         stw     r4,SL_DBAT7+4(r11)
142         mfspr   r4,SPRN_IBAT4U
143         stw     r4,SL_IBAT4(r11)
144         mfspr   r4,SPRN_IBAT4L
145         stw     r4,SL_IBAT4+4(r11)
146         mfspr   r4,SPRN_IBAT5U
147         stw     r4,SL_IBAT5(r11)
148         mfspr   r4,SPRN_IBAT5L
149         stw     r4,SL_IBAT5+4(r11)
150         mfspr   r4,SPRN_IBAT6U
151         stw     r4,SL_IBAT6(r11)
152         mfspr   r4,SPRN_IBAT6L
153         stw     r4,SL_IBAT6+4(r11)
154         mfspr   r4,SPRN_IBAT7U
155         stw     r4,SL_IBAT7(r11)
156         mfspr   r4,SPRN_IBAT7L
157         stw     r4,SL_IBAT7+4(r11)
158 END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
159
160 #if  0
161         /* Backup various CPU config stuffs */
162         bl      __save_cpu_setup
163 #endif
164         /* Call the low level suspend stuff (we should probably have made
165          * a stackframe...
166          */
167         bl      swsusp_save
168
169         /* Restore LR from the save area */
170         lis     r11,swsusp_save_area@h
171         ori     r11,r11,swsusp_save_area@l
172         lwz     r0,SL_LR(r11)
173         mtlr    r0
174
175         blr
176
177
178 /* Resume code */
179 _GLOBAL(swsusp_arch_resume)
180
181 #ifdef CONFIG_ALTIVEC
182         /* Stop pending alitvec streams and memory accesses */
183 BEGIN_FTR_SECTION
184         DSSALL
185 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
186 #endif
187         sync
188
189         /* Disable MSR:DR to make sure we don't take a TLB or
190          * hash miss during the copy, as our hash table will
191          * for a while be unusable. For .text, we assume we are
192          * covered by a BAT. This works only for non-G5 at this
193          * point. G5 will need a better approach, possibly using
194          * a small temporary hash table filled with large mappings,
195          * disabling the MMU completely isn't a good option for
196          * performance reasons.
197          * (Note that 750's may have the same performance issue as
198          * the G5 in this case, we should investigate using moving
199          * BATs for these CPUs)
200          */
201         mfmsr   r0
202         sync
203         rlwinm  r0,r0,0,28,26           /* clear MSR_DR */
204         mtmsr   r0
205         sync
206         isync
207
208         /* Load ptr the list of pages to copy in r3 */
209         lis     r11,(restore_pblist - KERNELBASE)@h
210         ori     r11,r11,restore_pblist@l
211         lwz     r10,0(r11)
212
213         /* Copy the pages. This is a very basic implementation, to
214          * be replaced by something more cache efficient */
215 1:
216         tophys(r3,r10)
217         li      r0,256
218         mtctr   r0
219         lwz     r11,pbe_address(r3)     /* source */
220         tophys(r5,r11)
221         lwz     r10,pbe_orig_address(r3)        /* destination */
222         tophys(r6,r10)
223 2:
224         lwz     r8,0(r5)
225         lwz     r9,4(r5)
226         lwz     r10,8(r5)
227         lwz     r11,12(r5)
228         addi    r5,r5,16
229         stw     r8,0(r6)
230         stw     r9,4(r6)
231         stw     r10,8(r6)
232         stw     r11,12(r6)
233         addi    r6,r6,16
234         bdnz    2b
235         lwz             r10,pbe_next(r3)
236         cmpwi   0,r10,0
237         bne     1b
238
239         /* Do a very simple cache flush/inval of the L1 to ensure
240          * coherency of the icache
241          */
242         lis     r3,0x0002
243         mtctr   r3
244         li      r3, 0
245 1:
246         lwz     r0,0(r3)
247         addi    r3,r3,0x0020
248         bdnz    1b
249         isync
250         sync
251
252         /* Now flush those cache lines */
253         lis     r3,0x0002
254         mtctr   r3
255         li      r3, 0
256 1:
257         dcbf    0,r3
258         addi    r3,r3,0x0020
259         bdnz    1b
260         sync
261
262         /* Ok, we are now running with the kernel data of the old
263          * kernel fully restored. We can get to the save area
264          * easily now. As for the rest of the code, it assumes the
265          * loader kernel and the booted one are exactly identical
266          */
267         lis     r11,swsusp_save_area@h
268         ori     r11,r11,swsusp_save_area@l
269         tophys(r11,r11)
270
271 #if 0
272         /* Restore various CPU config stuffs */
273         bl      __restore_cpu_setup
274 #endif
275         /* Restore the BATs, and SDR1.  Then we can turn on the MMU.
276          * This is a bit hairy as we are running out of those BATs,
277          * but first, our code is probably in the icache, and we are
278          * writing the same value to the BAT, so that should be fine,
279          * though a better solution will have to be found long-term
280          */
281         lwz     r4,SL_SDR1(r11)
282         mtsdr1  r4
283         lwz     r4,SL_SPRG0(r11)
284         mtsprg  0,r4
285         lwz     r4,SL_SPRG0+4(r11)
286         mtsprg  1,r4
287         lwz     r4,SL_SPRG0+8(r11)
288         mtsprg  2,r4
289         lwz     r4,SL_SPRG0+12(r11)
290         mtsprg  3,r4
291
292 #if 0
293         lwz     r4,SL_DBAT0(r11)
294         mtdbatu 0,r4
295         lwz     r4,SL_DBAT0+4(r11)
296         mtdbatl 0,r4
297         lwz     r4,SL_DBAT1(r11)
298         mtdbatu 1,r4
299         lwz     r4,SL_DBAT1+4(r11)
300         mtdbatl 1,r4
301         lwz     r4,SL_DBAT2(r11)
302         mtdbatu 2,r4
303         lwz     r4,SL_DBAT2+4(r11)
304         mtdbatl 2,r4
305         lwz     r4,SL_DBAT3(r11)
306         mtdbatu 3,r4
307         lwz     r4,SL_DBAT3+4(r11)
308         mtdbatl 3,r4
309         lwz     r4,SL_IBAT0(r11)
310         mtibatu 0,r4
311         lwz     r4,SL_IBAT0+4(r11)
312         mtibatl 0,r4
313         lwz     r4,SL_IBAT1(r11)
314         mtibatu 1,r4
315         lwz     r4,SL_IBAT1+4(r11)
316         mtibatl 1,r4
317         lwz     r4,SL_IBAT2(r11)
318         mtibatu 2,r4
319         lwz     r4,SL_IBAT2+4(r11)
320         mtibatl 2,r4
321         lwz     r4,SL_IBAT3(r11)
322         mtibatu 3,r4
323         lwz     r4,SL_IBAT3+4(r11)
324         mtibatl 3,r4
325 BEGIN_MMU_FTR_SECTION
326         lwz     r4,SL_DBAT4(r11)
327         mtspr   SPRN_DBAT4U,r4
328         lwz     r4,SL_DBAT4+4(r11)
329         mtspr   SPRN_DBAT4L,r4
330         lwz     r4,SL_DBAT5(r11)
331         mtspr   SPRN_DBAT5U,r4
332         lwz     r4,SL_DBAT5+4(r11)
333         mtspr   SPRN_DBAT5L,r4
334         lwz     r4,SL_DBAT6(r11)
335         mtspr   SPRN_DBAT6U,r4
336         lwz     r4,SL_DBAT6+4(r11)
337         mtspr   SPRN_DBAT6L,r4
338         lwz     r4,SL_DBAT7(r11)
339         mtspr   SPRN_DBAT7U,r4
340         lwz     r4,SL_DBAT7+4(r11)
341         mtspr   SPRN_DBAT7L,r4
342         lwz     r4,SL_IBAT4(r11)
343         mtspr   SPRN_IBAT4U,r4
344         lwz     r4,SL_IBAT4+4(r11)
345         mtspr   SPRN_IBAT4L,r4
346         lwz     r4,SL_IBAT5(r11)
347         mtspr   SPRN_IBAT5U,r4
348         lwz     r4,SL_IBAT5+4(r11)
349         mtspr   SPRN_IBAT5L,r4
350         lwz     r4,SL_IBAT6(r11)
351         mtspr   SPRN_IBAT6U,r4
352         lwz     r4,SL_IBAT6+4(r11)
353         mtspr   SPRN_IBAT6L,r4
354         lwz     r4,SL_IBAT7(r11)
355         mtspr   SPRN_IBAT7U,r4
356         lwz     r4,SL_IBAT7+4(r11)
357         mtspr   SPRN_IBAT7L,r4
358 END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
359 #endif
360
361         /* Flush all TLBs */
362         lis     r4,0x1000
363 1:      addic.  r4,r4,-0x1000
364         tlbie   r4
365         bgt     1b
366         sync
367
368         /* restore the MSR and turn on the MMU */
369         lwz     r3,SL_MSR(r11)
370         bl      turn_on_mmu
371         tovirt(r11,r11)
372
373         /* Restore TB */
374         li      r3,0
375         mttbl   r3
376         lwz     r3,SL_TB(r11)
377         lwz     r4,SL_TB+4(r11)
378         mttbu   r3
379         mttbl   r4
380
381         /* Kick decrementer */
382         li      r0,1
383         mtdec   r0
384
385         /* Restore the callee-saved registers and return */
386         lwz     r0,SL_CR(r11)
387         mtcr    r0
388         lwz     r2,SL_R2(r11)
389         lmw     r12,SL_R12(r11)
390         lwz     r1,SL_SP(r11)
391         lwz     r0,SL_LR(r11)
392         mtlr    r0
393
394         // XXX Note: we don't really need to call swsusp_resume
395
396         li      r3,0
397         blr
398
399 /* FIXME:This construct is actually not useful since we don't shut
400  * down the instruction MMU, we could just flip back MSR-DR on.
401  */
402 turn_on_mmu:
403         mflr    r4
404         mtsrr0  r4
405         mtsrr1  r3
406         sync
407         isync
408         rfi
409