Blame view

arch/sh/kernel/relocate_kernel.S 4.08 KB
9d44190ea   kogiidena   [PATCH] sh: kexec...
1
2
3
4
5
6
  /*
   * relocate_kernel.S - put the kernel image in place to boot
   * 2005.9.17 kogiidena@eggplant.ddo.jp
   *
   * LANDISK/sh4 is supported. Maybe, SH archtecture works well.
   *
b7cf6ddc1   Magnus Damm   sh: add kexec jum...
7
8
   * 2009-03-18 Magnus Damm - Added Kexec Jump support
   *
9d44190ea   kogiidena   [PATCH] sh: kexec...
9
10
11
   * This source code is licensed under the GNU General Public License,
   * Version 2.  See the file COPYING for more details.
   */
9d44190ea   kogiidena   [PATCH] sh: kexec...
12
  #include <linux/linkage.h>
510c72ad2   Paul Mundt   sh: Fixup various...
13
14
  #include <asm/addrspace.h>
  #include <asm/page.h>
9d44190ea   kogiidena   [PATCH] sh: kexec...
15
16
17
18
19
20
  
  		.globl relocate_new_kernel
  relocate_new_kernel:
  	/* r4 = indirection_page   */
  	/* r5 = reboot_code_buffer */
  	/* r6 = start_address      */
9d44190ea   kogiidena   [PATCH] sh: kexec...
21

b7cf6ddc1   Magnus Damm   sh: add kexec jum...
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
  	mov.l	10f, r0		/* PAGE_SIZE */
  	add	r5, r0		/* setup new stack at end of control page */
  
  	/* save r15->r8 to new stack */
  	mov.l	r15, @-r0
  	mov	r0, r15
  	mov.l	r14, @-r15
  	mov.l	r13, @-r15
  	mov.l	r12, @-r15
  	mov.l	r11, @-r15
  	mov.l	r10, @-r15
  	mov.l	r9, @-r15
  	mov.l	r8, @-r15
  
  	/* save other random registers */
  	sts.l	macl, @-r15
  	sts.l	mach, @-r15
  	stc.l	gbr, @-r15
  	stc.l	ssr, @-r15
  	stc.l	sr, @-r15
  	sts.l	pr, @-r15
  	stc.l	spc, @-r15
  
  	/* switch to bank1 and save r7->r0 */
  	mov.l	12f, r9
  	stc	sr, r8
  	or	r9, r8
  	ldc	r8, sr
  	mov.l	r7, @-r15
  	mov.l	r6, @-r15
  	mov.l	r5, @-r15
  	mov.l	r4, @-r15
  	mov.l	r3, @-r15
  	mov.l	r2, @-r15
  	mov.l	r1, @-r15
  	mov.l	r0, @-r15
  
  	/* switch to bank0 and save r7->r0 */
  	mov.l	12f, r9
  	not	r9, r9
  	stc	sr, r8
  	and	r9, r8
  	ldc	r8, sr
  	mov.l	r7, @-r15
  	mov.l	r6, @-r15
  	mov.l	r5, @-r15
  	mov.l	r4, @-r15
  	mov.l	r3, @-r15
  	mov.l	r2, @-r15
  	mov.l	r1, @-r15
  	mov.l	r0, @-r15
  
  	mov.l	r4, @-r15	/* save indirection page again */
  
  	bsr	swap_pages	/* swap pages before jumping to new kernel */
  	 nop
  
  	mova	11f, r0
  	mov.l	r15, @r0	/* save pointer to stack */
  
  	jsr	@r6		/* hand over control to new kernel */
  	 nop
  
  	mov.l	11f, r15	/* get pointer to stack */
  	mov.l	@r15+, r4	/* restore r4 to get indirection page */
9d44190ea   kogiidena   [PATCH] sh: kexec...
87

b7cf6ddc1   Magnus Damm   sh: add kexec jum...
88
89
  	bsr	swap_pages	/* swap pages back to previous state */
  	 nop
9d44190ea   kogiidena   [PATCH] sh: kexec...
90

b7cf6ddc1   Magnus Damm   sh: add kexec jum...
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  	/* make sure bank0 is active and restore r0->r7 */
  	mov.l	12f, r9
  	not	r9, r9
  	stc	sr, r8
  	and	r9, r8
  	ldc	r8, sr
  	mov.l	@r15+, r0
  	mov.l	@r15+, r1
  	mov.l	@r15+, r2
  	mov.l	@r15+, r3
  	mov.l	@r15+, r4
  	mov.l	@r15+, r5
  	mov.l	@r15+, r6
  	mov.l	@r15+, r7
  
  	/* switch to bank1 and restore r0->r7 */
  	mov.l	12f, r9
  	stc	sr, r8
  	or	r9, r8
  	ldc	r8, sr
  	mov.l	@r15+, r0
  	mov.l	@r15+, r1
  	mov.l	@r15+, r2
  	mov.l	@r15+, r3
  	mov.l	@r15+, r4
  	mov.l	@r15+, r5
  	mov.l	@r15+, r6
  	mov.l	@r15+, r7
  
  	/* switch back to bank0 */
  	mov.l	12f, r9
  	not	r9, r9
  	stc	sr, r8
  	and	r9, r8
  	ldc	r8, sr
  
  	/* restore other random registers */
  	ldc.l	@r15+, spc
  	lds.l	@r15+, pr
  	ldc.l	@r15+, sr
  	ldc.l	@r15+, ssr
  	ldc.l	@r15+, gbr
  	lds.l	@r15+, mach
  	lds.l	@r15+, macl
  
  	/* restore r8->r15 */
  	mov.l	@r15+, r8
  	mov.l	@r15+, r9
  	mov.l	@r15+, r10
  	mov.l	@r15+, r11
  	mov.l	@r15+, r12
  	mov.l	@r15+, r13
  	mov.l	@r15+, r14
  	mov.l	@r15+, r15
  	rts
  	 nop
  
  swap_pages:
9d44190ea   kogiidena   [PATCH] sh: kexec...
149
  	bra	1f
b7cf6ddc1   Magnus Damm   sh: add kexec jum...
150
  	 mov	r4,r0	  /* cmd = indirection_page */
9d44190ea   kogiidena   [PATCH] sh: kexec...
151
152
  0:
  	mov.l	@r4+,r0	  /* cmd = *ind++ */
e4e063d0c   Magnus Damm   sh: rework kexec ...
153
  1:	/* addr = cmd & 0xfffffff0 */
9d44190ea   kogiidena   [PATCH] sh: kexec...
154
  	mov	r0,r2
9d44190ea   kogiidena   [PATCH] sh: kexec...
155
156
157
158
159
160
161
  	mov	#-16,r1
  	and	r1,r2
  
  	/* if(cmd & IND_DESTINATION) dst = addr  */
  	tst	#1,r0
  	bt	2f
  	bra	0b
b7cf6ddc1   Magnus Damm   sh: add kexec jum...
162
  	 mov	r2,r5
9d44190ea   kogiidena   [PATCH] sh: kexec...
163
164
165
166
167
  
  2:	/* else if(cmd & IND_INDIRECTION) ind = addr  */
  	tst	#2,r0
  	bt	3f
  	bra	0b
b7cf6ddc1   Magnus Damm   sh: add kexec jum...
168
  	 mov	r2,r4
9d44190ea   kogiidena   [PATCH] sh: kexec...
169

b7cf6ddc1   Magnus Damm   sh: add kexec jum...
170
  3:	/* else if(cmd & IND_DONE) return */
9d44190ea   kogiidena   [PATCH] sh: kexec...
171
172
  	tst	#4,r0
  	bt	4f
b7cf6ddc1   Magnus Damm   sh: add kexec jum...
173
174
  	rts
  	 nop
9d44190ea   kogiidena   [PATCH] sh: kexec...
175
176
177
178
  
  4:	/* else if(cmd & IND_SOURCE) memcpy(dst,addr,PAGE_SIZE) */
  	tst	#8,r0
  	bt	0b
b7cf6ddc1   Magnus Damm   sh: add kexec jum...
179
  	mov.l	10f,r3	  /* PAGE_SIZE */
9d44190ea   kogiidena   [PATCH] sh: kexec...
180
181
182
183
  	shlr2	r3
  	shlr2	r3
  5:
  	dt	r3
b7cf6ddc1   Magnus Damm   sh: add kexec jum...
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
  
  	/* regular kexec just overwrites the destination page
  	 * with the contents of the source page.
  	 * for the kexec jump case we need to swap the contents
  	 * of the pages.
  	 * to keep it simple swap the contents for both cases.
  	 */
  	mov.l	@(0, r2), r8
  	mov.l	@(0, r5), r1
  	mov.l	r8, @(0, r5)
  	mov.l	r1, @(0, r2)
  
  	mov.l	@(4, r2), r8
  	mov.l	@(4, r5), r1
  	mov.l	r8, @(4, r5)
  	mov.l	r1, @(4, r2)
  
  	mov.l	@(8, r2), r8
  	mov.l	@(8, r5), r1
  	mov.l	r8, @(8, r5)
  	mov.l	r1, @(8, r2)
  
  	mov.l	@(12, r2), r8
  	mov.l	@(12, r5), r1
  	mov.l	r8, @(12, r5)
  	mov.l	r1, @(12, r2)
  
  	add	#16,r5
  	add	#16,r2
9d44190ea   kogiidena   [PATCH] sh: kexec...
213
214
215
  	bf	5b
  
  	bra	0b
b7cf6ddc1   Magnus Damm   sh: add kexec jum...
216
  	 nop
9d44190ea   kogiidena   [PATCH] sh: kexec...
217
218
219
220
  
  	.align 2
  10:
  	.long	PAGE_SIZE
b7cf6ddc1   Magnus Damm   sh: add kexec jum...
221
222
223
224
  11:
  	.long	0
  12:
  	.long	0x20000000 ! RB=1
9d44190ea   kogiidena   [PATCH] sh: kexec...
225
226
227
228
229
230
  
  relocate_new_kernel_end:
  
  	.globl relocate_new_kernel_size
  relocate_new_kernel_size:
  	.long relocate_new_kernel_end - relocate_new_kernel