xref: /openbmc/linux/arch/arm/kernel/relocate_kernel.S (revision b7f8f259896f669f131713b0c74ba4d008daa71d)
1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */
2c587e4a6SRichard Purdie/*
3c587e4a6SRichard Purdie * relocate_kernel.S - put the kernel image in place to boot
4c587e4a6SRichard Purdie */
5c587e4a6SRichard Purdie
6e2ccba49SDave Martin#include <linux/linkage.h>
76ebbf2ceSRussell King#include <asm/assembler.h>
8*4d62e81bSRussell King#include <asm/asm-offsets.h>
9c587e4a6SRichard Purdie#include <asm/kexec.h>
10c587e4a6SRichard Purdie
11e2ccba49SDave Martin	.align	3	/* not needed for this code, but keeps fncpy() happy */
12e2ccba49SDave Martin
13e2ccba49SDave MartinENTRY(relocate_new_kernel)
14c587e4a6SRichard Purdie
15*4d62e81bSRussell King	adr	r7, relocate_new_kernel_end
16*4d62e81bSRussell King	ldr	r0, [r7, #KEXEC_INDIR_PAGE]
17*4d62e81bSRussell King	ldr	r1, [r7, #KEXEC_START_ADDR]
18c587e4a6SRichard Purdie
198594a0c3SMika Westerberg	/*
208594a0c3SMika Westerberg	 * If there is no indirection page (we are doing crashdumps)
218594a0c3SMika Westerberg	 * skip any relocation.
228594a0c3SMika Westerberg	 */
238594a0c3SMika Westerberg	cmp	r0, #0
248594a0c3SMika Westerberg	beq	2f
25c587e4a6SRichard Purdie
26c587e4a6SRichard Purdie0:	/* top, read another word for the indirection page */
27c587e4a6SRichard Purdie	ldr	r3, [r0],#4
28c587e4a6SRichard Purdie
29c587e4a6SRichard Purdie	/* Is it a destination page. Put destination address to r4 */
3091274f96SStefan Agner	tst	r3,#1
31c587e4a6SRichard Purdie	beq	1f
32c587e4a6SRichard Purdie	bic	r4,r3,#1
33c587e4a6SRichard Purdie	b	0b
34c587e4a6SRichard Purdie1:
35c587e4a6SRichard Purdie	/* Is it an indirection page */
3691274f96SStefan Agner	tst	r3,#2
37c587e4a6SRichard Purdie	beq	1f
38c587e4a6SRichard Purdie	bic	r0,r3,#2
39c587e4a6SRichard Purdie	b	0b
40c587e4a6SRichard Purdie1:
41c587e4a6SRichard Purdie
42c587e4a6SRichard Purdie	/* are we done ? */
4391274f96SStefan Agner	tst	r3,#4
44c587e4a6SRichard Purdie	beq	1f
45c587e4a6SRichard Purdie	b	2f
46c587e4a6SRichard Purdie
47c587e4a6SRichard Purdie1:
48c587e4a6SRichard Purdie	/* is it source ? */
4991274f96SStefan Agner	tst	r3,#8
50c587e4a6SRichard Purdie	beq	0b
51c587e4a6SRichard Purdie	bic r3,r3,#8
52c587e4a6SRichard Purdie	mov r6,#1024
53c587e4a6SRichard Purdie9:
54c587e4a6SRichard Purdie	ldr r5,[r3],#4
55c587e4a6SRichard Purdie	str r5,[r4],#4
56c587e4a6SRichard Purdie	subs r6,r6,#1
57c587e4a6SRichard Purdie	bne 9b
58c587e4a6SRichard Purdie	b 0b
59c587e4a6SRichard Purdie
60c587e4a6SRichard Purdie2:
61c587e4a6SRichard Purdie	/* Jump to relocated kernel */
62c587e4a6SRichard Purdie	mov	lr, r1
63c587e4a6SRichard Purdie	mov	r0, #0
64*4d62e81bSRussell King	ldr	r1, [r7, #KEXEC_MACH_TYPE]
65*4d62e81bSRussell King	ldr	r2, [r7, #KEXEC_R2]
666ebbf2ceSRussell King ARM(	ret	lr	)
67552e0c8dSWill Deacon THUMB(	bx	lr	)
68c587e4a6SRichard Purdie
69e2ccba49SDave MartinENDPROC(relocate_new_kernel)
70e2ccba49SDave Martin
71*4d62e81bSRussell King	.align	3
72c587e4a6SRichard Purdierelocate_new_kernel_end:
73c587e4a6SRichard Purdie
74c587e4a6SRichard Purdie	.globl relocate_new_kernel_size
75c587e4a6SRichard Purdierelocate_new_kernel_size:
76c587e4a6SRichard Purdie	.long relocate_new_kernel_end - relocate_new_kernel
77c587e4a6SRichard Purdie
78c587e4a6SRichard Purdie
79