Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/sh/kernel/relocate_kernel.S
26442 views
1
/* SPDX-License-Identifier: GPL-2.0
2
*
3
* relocate_kernel.S - put the kernel image in place to boot
4
* 2005.9.17 [email protected]
5
*
6
* LANDISK/sh4 is supported. Maybe, SH archtecture works well.
7
*
8
* 2009-03-18 Magnus Damm - Added Kexec Jump support
9
*/
10
#include <linux/linkage.h>
11
#include <asm/addrspace.h>
12
#include <asm/page.h>
13
14
.globl relocate_new_kernel
15
relocate_new_kernel:
16
/* r4 = indirection_page */
17
/* r5 = reboot_code_buffer */
18
/* r6 = start_address */
19
20
mov.l 10f, r0 /* PAGE_SIZE */
21
add r5, r0 /* setup new stack at end of control page */
22
23
/* save r15->r8 to new stack */
24
mov.l r15, @-r0
25
mov r0, r15
26
mov.l r14, @-r15
27
mov.l r13, @-r15
28
mov.l r12, @-r15
29
mov.l r11, @-r15
30
mov.l r10, @-r15
31
mov.l r9, @-r15
32
mov.l r8, @-r15
33
34
/* save other random registers */
35
sts.l macl, @-r15
36
sts.l mach, @-r15
37
stc.l gbr, @-r15
38
stc.l ssr, @-r15
39
stc.l sr, @-r15
40
sts.l pr, @-r15
41
stc.l spc, @-r15
42
43
/* switch to bank1 and save r7->r0 */
44
mov.l 12f, r9
45
stc sr, r8
46
or r9, r8
47
ldc r8, sr
48
mov.l r7, @-r15
49
mov.l r6, @-r15
50
mov.l r5, @-r15
51
mov.l r4, @-r15
52
mov.l r3, @-r15
53
mov.l r2, @-r15
54
mov.l r1, @-r15
55
mov.l r0, @-r15
56
57
/* switch to bank0 and save r7->r0 */
58
mov.l 12f, r9
59
not r9, r9
60
stc sr, r8
61
and r9, r8
62
ldc r8, sr
63
mov.l r7, @-r15
64
mov.l r6, @-r15
65
mov.l r5, @-r15
66
mov.l r4, @-r15
67
mov.l r3, @-r15
68
mov.l r2, @-r15
69
mov.l r1, @-r15
70
mov.l r0, @-r15
71
72
mov.l r4, @-r15 /* save indirection page again */
73
74
bsr swap_pages /* swap pages before jumping to new kernel */
75
nop
76
77
mova 11f, r0
78
mov.l r15, @r0 /* save pointer to stack */
79
80
jsr @r6 /* hand over control to new kernel */
81
nop
82
83
mov.l 11f, r15 /* get pointer to stack */
84
mov.l @r15+, r4 /* restore r4 to get indirection page */
85
86
bsr swap_pages /* swap pages back to previous state */
87
nop
88
89
/* make sure bank0 is active and restore r0->r7 */
90
mov.l 12f, r9
91
not r9, r9
92
stc sr, r8
93
and r9, r8
94
ldc r8, sr
95
mov.l @r15+, r0
96
mov.l @r15+, r1
97
mov.l @r15+, r2
98
mov.l @r15+, r3
99
mov.l @r15+, r4
100
mov.l @r15+, r5
101
mov.l @r15+, r6
102
mov.l @r15+, r7
103
104
/* switch to bank1 and restore r0->r7 */
105
mov.l 12f, r9
106
stc sr, r8
107
or r9, r8
108
ldc r8, sr
109
mov.l @r15+, r0
110
mov.l @r15+, r1
111
mov.l @r15+, r2
112
mov.l @r15+, r3
113
mov.l @r15+, r4
114
mov.l @r15+, r5
115
mov.l @r15+, r6
116
mov.l @r15+, r7
117
118
/* switch back to bank0 */
119
mov.l 12f, r9
120
not r9, r9
121
stc sr, r8
122
and r9, r8
123
ldc r8, sr
124
125
/* restore other random registers */
126
ldc.l @r15+, spc
127
lds.l @r15+, pr
128
ldc.l @r15+, sr
129
ldc.l @r15+, ssr
130
ldc.l @r15+, gbr
131
lds.l @r15+, mach
132
lds.l @r15+, macl
133
134
/* restore r8->r15 */
135
mov.l @r15+, r8
136
mov.l @r15+, r9
137
mov.l @r15+, r10
138
mov.l @r15+, r11
139
mov.l @r15+, r12
140
mov.l @r15+, r13
141
mov.l @r15+, r14
142
mov.l @r15+, r15
143
rts
144
nop
145
146
swap_pages:
147
bra 1f
148
mov r4,r0 /* cmd = indirection_page */
149
0:
150
mov.l @r4+,r0 /* cmd = *ind++ */
151
152
1: /* addr = cmd & 0xfffffff0 */
153
mov r0,r2
154
mov #-16,r1
155
and r1,r2
156
157
/* if(cmd & IND_DESTINATION) dst = addr */
158
tst #1,r0
159
bt 2f
160
bra 0b
161
mov r2,r5
162
163
2: /* else if(cmd & IND_INDIRECTION) ind = addr */
164
tst #2,r0
165
bt 3f
166
bra 0b
167
mov r2,r4
168
169
3: /* else if(cmd & IND_DONE) return */
170
tst #4,r0
171
bt 4f
172
rts
173
nop
174
175
4: /* else if(cmd & IND_SOURCE) memcpy(dst,addr,PAGE_SIZE) */
176
tst #8,r0
177
bt 0b
178
179
mov.l 10f,r3 /* PAGE_SIZE */
180
shlr2 r3
181
shlr2 r3
182
5:
183
dt r3
184
185
/* regular kexec just overwrites the destination page
186
* with the contents of the source page.
187
* for the kexec jump case we need to swap the contents
188
* of the pages.
189
* to keep it simple swap the contents for both cases.
190
*/
191
mov.l @(0, r2), r8
192
mov.l @(0, r5), r1
193
mov.l r8, @(0, r5)
194
mov.l r1, @(0, r2)
195
196
mov.l @(4, r2), r8
197
mov.l @(4, r5), r1
198
mov.l r8, @(4, r5)
199
mov.l r1, @(4, r2)
200
201
mov.l @(8, r2), r8
202
mov.l @(8, r5), r1
203
mov.l r8, @(8, r5)
204
mov.l r1, @(8, r2)
205
206
mov.l @(12, r2), r8
207
mov.l @(12, r5), r1
208
mov.l r8, @(12, r5)
209
mov.l r1, @(12, r2)
210
211
add #16,r5
212
add #16,r2
213
bf 5b
214
215
bra 0b
216
nop
217
218
.align 2
219
10:
220
.long PAGE_SIZE
221
11:
222
.long 0
223
12:
224
.long 0x20000000 ! RB=1
225
226
relocate_new_kernel_end:
227
228
.globl relocate_new_kernel_size
229
relocate_new_kernel_size:
230
.long relocate_new_kernel_end - relocate_new_kernel
231
232