Merge branch 'fixes' of git://git.armlinux.org.uk/~rmk/linux-arm
[sfrench/cifs-2.6.git] / arch / arm / kernel / relocate_kernel.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * relocate_kernel.S - put the kernel image in place to boot
4  */
5
6 #include <linux/linkage.h>
7 #include <asm/assembler.h>
8 #include <asm/kexec.h>
9
10         .align  3       /* not needed for this code, but keeps fncpy() happy */
11
12 ENTRY(relocate_new_kernel)
13
14         ldr     r0,kexec_indirection_page
15         ldr     r1,kexec_start_address
16
17         /*
18          * If there is no indirection page (we are doing crashdumps)
19          * skip any relocation.
20          */
21         cmp     r0, #0
22         beq     2f
23
24 0:      /* top, read another word for the indirection page */
25         ldr     r3, [r0],#4
26
27         /* Is it a destination page. Put destination address to r4 */
28         tst     r3,#1,0
29         beq     1f
30         bic     r4,r3,#1
31         b       0b
32 1:
33         /* Is it an indirection page */
34         tst     r3,#2,0
35         beq     1f
36         bic     r0,r3,#2
37         b       0b
38 1:
39
40         /* are we done ? */
41         tst     r3,#4,0
42         beq     1f
43         b       2f
44
45 1:
46         /* is it source ? */
47         tst     r3,#8,0
48         beq     0b
49         bic r3,r3,#8
50         mov r6,#1024
51 9:
52         ldr r5,[r3],#4
53         str r5,[r4],#4
54         subs r6,r6,#1
55         bne 9b
56         b 0b
57
58 2:
59         /* Jump to relocated kernel */
60         mov lr,r1
61         mov r0,#0
62         ldr r1,kexec_mach_type
63         ldr r2,kexec_boot_atags
64  ARM(   ret lr  )
65  THUMB( bx lr           )
66
67         .align
68
69         .globl kexec_start_address
70 kexec_start_address:
71         .long   0x0
72
73         .globl kexec_indirection_page
74 kexec_indirection_page:
75         .long   0x0
76
77         .globl kexec_mach_type
78 kexec_mach_type:
79         .long   0x0
80
81         /* phy addr of the atags for the new kernel */
82         .globl kexec_boot_atags
83 kexec_boot_atags:
84         .long   0x0
85
86 ENDPROC(relocate_new_kernel)
87
88 relocate_new_kernel_end:
89
90         .globl relocate_new_kernel_size
91 relocate_new_kernel_size:
92         .long relocate_new_kernel_end - relocate_new_kernel
93
94