Commit | Line | Data |
---|---|---|
543b9fd3 JB |
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 | ||
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_SIZE SL_r31+8 | |
50 | ||
51 | /* these macros rely on the save area being | |
52 | * pointed to by r11 */ | |
53 | #define SAVE_SPECIAL(special) \ | |
54 | mf##special r0 ;\ | |
55 | std r0, SL_##special(r11) | |
56 | #define RESTORE_SPECIAL(special) \ | |
57 | ld r0, SL_##special(r11) ;\ | |
58 | mt##special r0 | |
59 | #define SAVE_REGISTER(reg) \ | |
60 | std reg, SL_##reg(r11) | |
61 | #define RESTORE_REGISTER(reg) \ | |
62 | ld reg, SL_##reg(r11) | |
63 | ||
64 | /* space for storing cpu state */ | |
65 | .section .data | |
66 | .align 5 | |
67 | swsusp_save_area: | |
68 | .space SL_SIZE | |
69 | ||
70 | .section ".toc","aw" | |
71 | swsusp_save_area_ptr: | |
72 | .tc swsusp_save_area[TC],swsusp_save_area | |
73 | restore_pblist_ptr: | |
74 | .tc restore_pblist[TC],restore_pblist | |
75 | ||
76 | .section .text | |
77 | .align 5 | |
78 | _GLOBAL(swsusp_arch_suspend) | |
79 | ld r11,swsusp_save_area_ptr@toc(r2) | |
80 | SAVE_SPECIAL(LR) | |
81 | SAVE_REGISTER(r1) | |
82 | SAVE_SPECIAL(CR) | |
83 | SAVE_SPECIAL(TB) | |
84 | SAVE_REGISTER(r2) | |
85 | SAVE_REGISTER(r12) | |
86 | SAVE_REGISTER(r13) | |
87 | SAVE_REGISTER(r14) | |
88 | SAVE_REGISTER(r15) | |
89 | SAVE_REGISTER(r16) | |
90 | SAVE_REGISTER(r17) | |
91 | SAVE_REGISTER(r18) | |
92 | SAVE_REGISTER(r19) | |
93 | SAVE_REGISTER(r20) | |
94 | SAVE_REGISTER(r21) | |
95 | SAVE_REGISTER(r22) | |
96 | SAVE_REGISTER(r23) | |
97 | SAVE_REGISTER(r24) | |
98 | SAVE_REGISTER(r25) | |
99 | SAVE_REGISTER(r26) | |
100 | SAVE_REGISTER(r27) | |
101 | SAVE_REGISTER(r28) | |
102 | SAVE_REGISTER(r29) | |
103 | SAVE_REGISTER(r30) | |
104 | SAVE_REGISTER(r31) | |
105 | SAVE_SPECIAL(MSR) | |
106 | SAVE_SPECIAL(SDR1) | |
107 | SAVE_SPECIAL(XER) | |
108 | ||
109 | /* we push the stack up 128 bytes but don't store the | |
110 | * stack pointer on the stack like a real stackframe */ | |
111 | addi r1,r1,-128 | |
112 | ||
113 | bl _iommu_save | |
114 | bl swsusp_save | |
115 | ||
116 | /* restore LR */ | |
117 | ld r11,swsusp_save_area_ptr@toc(r2) | |
118 | RESTORE_SPECIAL(LR) | |
119 | addi r1,r1,128 | |
120 | ||
121 | blr | |
122 | ||
123 | /* Resume code */ | |
124 | _GLOBAL(swsusp_arch_resume) | |
125 | /* Stop pending alitvec streams and memory accesses */ | |
126 | BEGIN_FTR_SECTION | |
127 | DSSALL | |
128 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |
129 | sync | |
130 | ||
131 | ld r12,restore_pblist_ptr@toc(r2) | |
132 | ld r12,0(r12) | |
133 | ||
134 | cmpdi r12,0 | |
135 | beq- nothing_to_copy | |
136 | li r15,512 | |
137 | copyloop: | |
138 | ld r13,pbe_address(r12) | |
139 | ld r14,pbe_orig_address(r12) | |
140 | ||
141 | mtctr r15 | |
142 | li r10,0 | |
143 | copy_page_loop: | |
144 | ldx r0,r10,r13 | |
145 | stdx r0,r10,r14 | |
146 | addi r10,r10,8 | |
147 | bdnz copy_page_loop | |
148 | ||
149 | ld r12,pbe_next(r12) | |
150 | cmpdi r12,0 | |
151 | bne+ copyloop | |
152 | nothing_to_copy: | |
153 | ||
154 | /* flush caches */ | |
155 | lis r3, 0x10 | |
156 | mtctr r3 | |
157 | li r3, 0 | |
158 | ori r3, r3, CONFIG_KERNEL_START>>48 | |
159 | li r0, 48 | |
160 | sld r3, r3, r0 | |
161 | li r0, 0 | |
162 | 1: | |
163 | dcbf r0,r3 | |
164 | addi r3,r3,0x20 | |
165 | bdnz 1b | |
166 | ||
167 | sync | |
168 | ||
169 | tlbia | |
170 | ||
171 | ld r11,swsusp_save_area_ptr@toc(r2) | |
172 | ||
173 | RESTORE_SPECIAL(CR) | |
174 | ||
175 | /* restore timebase */ | |
176 | /* load saved tb */ | |
177 | ld r1, SL_TB(r11) | |
178 | /* get upper 32 bits of it */ | |
179 | srdi r2, r1, 32 | |
180 | /* clear tb lower to avoid wrap */ | |
181 | li r0, 0 | |
182 | mttbl r0 | |
183 | /* set tb upper */ | |
184 | mttbu r2 | |
185 | /* set tb lower */ | |
186 | mttbl r1 | |
187 | ||
188 | /* restore registers */ | |
189 | RESTORE_REGISTER(r1) | |
190 | RESTORE_REGISTER(r2) | |
191 | RESTORE_REGISTER(r12) | |
192 | RESTORE_REGISTER(r13) | |
193 | RESTORE_REGISTER(r14) | |
194 | RESTORE_REGISTER(r15) | |
195 | RESTORE_REGISTER(r16) | |
196 | RESTORE_REGISTER(r17) | |
197 | RESTORE_REGISTER(r18) | |
198 | RESTORE_REGISTER(r19) | |
199 | RESTORE_REGISTER(r20) | |
200 | RESTORE_REGISTER(r21) | |
201 | RESTORE_REGISTER(r22) | |
202 | RESTORE_REGISTER(r23) | |
203 | RESTORE_REGISTER(r24) | |
204 | RESTORE_REGISTER(r25) | |
205 | RESTORE_REGISTER(r26) | |
206 | RESTORE_REGISTER(r27) | |
207 | RESTORE_REGISTER(r28) | |
208 | RESTORE_REGISTER(r29) | |
209 | RESTORE_REGISTER(r30) | |
210 | RESTORE_REGISTER(r31) | |
211 | /* can't use RESTORE_SPECIAL(MSR) */ | |
212 | ld r0, SL_MSR(r11) | |
213 | mtmsrd r0, 0 | |
214 | RESTORE_SPECIAL(SDR1) | |
215 | RESTORE_SPECIAL(XER) | |
216 | ||
217 | sync | |
218 | ||
219 | addi r1,r1,-128 | |
220 | bl slb_flush_and_rebolt | |
221 | bl do_after_copyback | |
222 | addi r1,r1,128 | |
223 | ||
224 | ld r11,swsusp_save_area_ptr@toc(r2) | |
225 | RESTORE_SPECIAL(LR) | |
226 | ||
227 | li r3, 0 | |
228 | blr |