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  */
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/feature-fixups.h>
16 
17 /*
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
52 
53 /* these macros rely on the save area being
54  * pointed to by r11 */
55 
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)
72 
73 /* space for storing cpu state */
74 	.section .data
75 	.align  5
76 swsusp_save_area:
77 	.space SL_SIZE
78 
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
84 
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)
122 
123 	/* Save SPRG1, SPRG1 be used save paca */
124 	SAVE_SPR(SPRG1)
125 #endif
126 
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
130 
131 	bl _iommu_save
132 	bl swsusp_save
133 
134 	/* restore LR */
135 	ld	r11,swsusp_save_area_ptr@toc(r2)
136 	RESTORE_SPECIAL(LR)
137 	addi	r1,r1,128
138 
139 	blr
140 
141 /* Resume code */
142 _GLOBAL(swsusp_arch_resume)
143 	/* Stop pending alitvec streams and memory accesses */
144 BEGIN_FTR_SECTION
145 	PPC_DSSALL
146 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
147 	sync
148 
149 	ld	r12,restore_pblist_ptr@toc(r2)
150 	ld	r12,0(r12)
151 
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)
158 
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
166 
167 	ld	r12,pbe_next(r12)
168 	cmpdi	r12,0
169 	bne+	copyloop
170 nothing_to_copy:
171 
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
181 1:
182 	dcbf	0,r3
183 	addi	r3,r3,0x20
184 	bdnz	1b
185 
186 	sync
187 
188 	tlbia
189 #endif
190 
191 	ld	r11,swsusp_save_area_ptr@toc(r2)
192 
193 	RESTORE_SPECIAL(CR)
194 
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
207 
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)
231 
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
243 
244 	RESTORE_SPECIAL(MSR)
245 
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
250 
251 	/* Kick decrementer */
252 	li	r0, 1
253 	mtdec	r0
254 
255 	/* Invalidate all tlbs */
256 	bl	_tlbil_all
257 #endif
258 	RESTORE_SPECIAL(XER)
259 
260 	sync
261 
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
268 
269 	ld	r11,swsusp_save_area_ptr@toc(r2)
270 	RESTORE_SPECIAL(LR)
271 
272 	li	r3, 0
273 	blr
274