Linux Audio

Check our new training course

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