1/*
2 * relocate_kernel.S - put the kernel image in place to boot
3 */
4
5#include <asm/kexec.h>
6
7	.globl relocate_new_kernel
8relocate_new_kernel:
9
10	/* Move boot params back to where the kernel expects them */
11
12	ldr	r0,kexec_boot_params_address
13	teq	r0,#0
14	beq	8f
15
16	ldr	r1,kexec_boot_params_copy
17	mov	r6,#KEXEC_BOOT_PARAMS_SIZE/4
187:
19	ldr	r5,[r1],#4
20	str	r5,[r0],#4
21	subs	r6,r6,#1
22	bne	7b
23
248:
25	/* Boot params moved, now go on with the kernel */
26
27	ldr	r0,kexec_indirection_page
28	ldr	r1,kexec_start_address
29
30
310:	/* top, read another word for the indirection page */
32	ldr	r3, [r0],#4
33
34	/* Is it a destination page. Put destination address to r4 */
35	tst	r3,#1,0
36	beq	1f
37	bic	r4,r3,#1
38	b	0b
391:
40	/* Is it an indirection page */
41	tst	r3,#2,0
42	beq	1f
43	bic	r0,r3,#2
44	b	0b
451:
46
47	/* are we done ? */
48	tst	r3,#4,0
49	beq	1f
50	b	2f
51
521:
53	/* is it source ? */
54	tst	r3,#8,0
55	beq	0b
56	bic r3,r3,#8
57	mov r6,#1024
589:
59	ldr r5,[r3],#4
60	str r5,[r4],#4
61	subs r6,r6,#1
62	bne 9b
63	b 0b
64
652:
66	/* Jump to relocated kernel */
67	mov lr,r1
68	mov r0,#0
69	ldr r1,kexec_mach_type
70	ldr r2,kexec_boot_params_address
71	mov pc,lr
72
73	.globl kexec_start_address
74kexec_start_address:
75	.long	0x0
76
77	.globl kexec_indirection_page
78kexec_indirection_page:
79	.long	0x0
80
81	.globl kexec_mach_type
82kexec_mach_type:
83	.long	0x0
84
85	/* phy addr where new kernel will expect to find boot params */
86	.globl kexec_boot_params_address
87kexec_boot_params_address:
88	.long	0x0
89
90	/* phy addr where old kernel put a copy of orig boot params */
91	.globl kexec_boot_params_copy
92kexec_boot_params_copy:
93	.long	0x0
94
95relocate_new_kernel_end:
96
97	.globl relocate_new_kernel_size
98relocate_new_kernel_size:
99	.long relocate_new_kernel_end - relocate_new_kernel
100
101
102