1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Based on swsusp_32.S, modified for FSL BookE by
4 * Anton Vorontsov <avorontsov@ru.mvista.com>
5 * Copyright (c) 2009-2010 MontaVista Software, LLC.
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/mmu.h>
16
17/*
18 * Structure for storing CPU registers on the save area.
19 */
20#define SL_SP 0
21#define SL_PC 4
22#define SL_MSR 8
23#define SL_TCR 0xc
24#define SL_SPRG0 0x10
25#define SL_SPRG1 0x14
26#define SL_SPRG2 0x18
27#define SL_SPRG3 0x1c
28#define SL_SPRG4 0x20
29#define SL_SPRG5 0x24
30#define SL_SPRG6 0x28
31#define SL_SPRG7 0x2c
32#define SL_TBU 0x30
33#define SL_TBL 0x34
34#define SL_R2 0x38
35#define SL_CR 0x3c
36#define SL_LR 0x40
37#define SL_R12 0x44 /* r12 to r31 */
38#define SL_SIZE (SL_R12 + 80)
39
40 .section .data
41 .align 5
42
43_GLOBAL(swsusp_save_area)
44 .space SL_SIZE
45
46
47 .section .text
48 .align 5
49
50_GLOBAL(swsusp_arch_suspend)
51 lis r11,swsusp_save_area@h
52 ori r11,r11,swsusp_save_area@l
53
54 mflr r0
55 stw r0,SL_LR(r11)
56 mfcr r0
57 stw r0,SL_CR(r11)
58 stw r1,SL_SP(r11)
59 stw r2,SL_R2(r11)
60 stmw r12,SL_R12(r11)
61
62 /* Save MSR & TCR */
63 mfmsr r4
64 stw r4,SL_MSR(r11)
65 mfspr r4,SPRN_TCR
66 stw r4,SL_TCR(r11)
67
68 /* Get a stable timebase and save it */
691: mfspr r4,SPRN_TBRU
70 stw r4,SL_TBU(r11)
71 mfspr r5,SPRN_TBRL
72 stw r5,SL_TBL(r11)
73 mfspr r3,SPRN_TBRU
74 cmpw r3,r4
75 bne 1b
76
77 /* Save SPRGs */
78 mfspr r4,SPRN_SPRG0
79 stw r4,SL_SPRG0(r11)
80 mfspr r4,SPRN_SPRG1
81 stw r4,SL_SPRG1(r11)
82 mfspr r4,SPRN_SPRG2
83 stw r4,SL_SPRG2(r11)
84 mfspr r4,SPRN_SPRG3
85 stw r4,SL_SPRG3(r11)
86 mfspr r4,SPRN_SPRG4
87 stw r4,SL_SPRG4(r11)
88 mfspr r4,SPRN_SPRG5
89 stw r4,SL_SPRG5(r11)
90 mfspr r4,SPRN_SPRG6
91 stw r4,SL_SPRG6(r11)
92 mfspr r4,SPRN_SPRG7
93 stw r4,SL_SPRG7(r11)
94
95 /* Call the low level suspend stuff (we should probably have made
96 * a stackframe...
97 */
98 bl swsusp_save
99
100 /* Restore LR from the save area */
101 lis r11,swsusp_save_area@h
102 ori r11,r11,swsusp_save_area@l
103 lwz r0,SL_LR(r11)
104 mtlr r0
105
106 blr
107
108_GLOBAL(swsusp_arch_resume)
109 sync
110
111 /* Load ptr the list of pages to copy in r3 */
112 lis r11,(restore_pblist)@h
113 ori r11,r11,restore_pblist@l
114 lwz r3,0(r11)
115
116 /* Copy the pages. This is a very basic implementation, to
117 * be replaced by something more cache efficient */
1181:
119 li r0,256
120 mtctr r0
121 lwz r5,pbe_address(r3) /* source */
122 lwz r6,pbe_orig_address(r3) /* destination */
1232:
124 lwz r8,0(r5)
125 lwz r9,4(r5)
126 lwz r10,8(r5)
127 lwz r11,12(r5)
128 addi r5,r5,16
129 stw r8,0(r6)
130 stw r9,4(r6)
131 stw r10,8(r6)
132 stw r11,12(r6)
133 addi r6,r6,16
134 bdnz 2b
135 lwz r3,pbe_next(r3)
136 cmpwi 0,r3,0
137 bne 1b
138
139 bl flush_dcache_L1
140 bl flush_instruction_cache
141
142 lis r11,swsusp_save_area@h
143 ori r11,r11,swsusp_save_area@l
144
145 /*
146 * Mappings from virtual addresses to physical addresses may be
147 * different than they were prior to restoring hibernation state.
148 * Invalidate the TLB so that the boot CPU is using the new
149 * mappings.
150 */
151 bl _tlbil_all
152
153 lwz r4,SL_SPRG0(r11)
154 mtspr SPRN_SPRG0,r4
155 lwz r4,SL_SPRG1(r11)
156 mtspr SPRN_SPRG1,r4
157 lwz r4,SL_SPRG2(r11)
158 mtspr SPRN_SPRG2,r4
159 lwz r4,SL_SPRG3(r11)
160 mtspr SPRN_SPRG3,r4
161 lwz r4,SL_SPRG4(r11)
162 mtspr SPRN_SPRG4,r4
163 lwz r4,SL_SPRG5(r11)
164 mtspr SPRN_SPRG5,r4
165 lwz r4,SL_SPRG6(r11)
166 mtspr SPRN_SPRG6,r4
167 lwz r4,SL_SPRG7(r11)
168 mtspr SPRN_SPRG7,r4
169
170 /* restore the MSR */
171 lwz r3,SL_MSR(r11)
172 mtmsr r3
173
174 /* Restore TB */
175 li r3,0
176 mtspr SPRN_TBWL,r3
177 lwz r3,SL_TBU(r11)
178 lwz r4,SL_TBL(r11)
179 mtspr SPRN_TBWU,r3
180 mtspr SPRN_TBWL,r4
181
182 /* Restore TCR and clear any pending bits in TSR. */
183 lwz r4,SL_TCR(r11)
184 mtspr SPRN_TCR,r4
185 lis r4, (TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS)@h
186 mtspr SPRN_TSR,r4
187
188 /* Kick decrementer */
189 li r0,1
190 mtdec r0
191
192 /* Restore the callee-saved registers and return */
193 lwz r0,SL_CR(r11)
194 mtcr r0
195 lwz r2,SL_R2(r11)
196 lmw r12,SL_R12(r11)
197 lwz r1,SL_SP(r11)
198 lwz r0,SL_LR(r11)
199 mtlr r0
200
201 li r3,0
202 blr
203

source code of linux/arch/powerpc/kernel/swsusp_85xx.S