/* SPDX-License-Identifier: GPL-2.0 */ /* * relocate_kernel.S - put the kernel image in place to boot */ #include <linux/linkage.h> #include <asm/assembler.h> #include <asm/asm-offsets.h> #include <asm/kexec.h> .align 3 /* not needed for this code, but keeps fncpy() happy */ ENTRY(relocate_new_kernel) adr r7, relocate_new_kernel_end ldr r0, [r7, #KEXEC_INDIR_PAGE] ldr r1, [r7, #KEXEC_START_ADDR] /* * If there is no indirection page (we are doing crashdumps) * skip any relocation. */ cmp r0, #0 beq 2f 0: /* top, read another word for the indirection page */ ldr r3, [r0],#4 /* Is it a destination page. Put destination address to r4 */ tst r3,#1 beq 1f bic r4,r3,#1 b 0b 1: /* Is it an indirection page */ tst r3,#2 beq 1f bic r0,r3,#2 b 0b 1: /* are we done ? */ tst r3,#4 beq 1f b 2f 1: /* is it source ? */ tst r3,#8 beq 0b bic r3,r3,#8 mov r6,#1024 9: ldr r5,[r3],#4 str r5,[r4],#4 subs r6,r6,#1 bne 9b b 0b 2: /* Jump to relocated kernel */ mov lr, r1 mov r0, #0 ldr r1, [r7, #KEXEC_MACH_TYPE] ldr r2, [r7, #KEXEC_R2] ARM( ret lr ) THUMB( bx lr ) ENDPROC(relocate_new_kernel) .align 3 relocate_new_kernel_end: .globl relocate_new_kernel_size relocate_new_kernel_size: .long relocate_new_kernel_end - relocate_new_kernel