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