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/asm-offsets.h> 9#include <asm/kexec.h> 10 11 .align 3 /* not needed for this code, but keeps fncpy() happy */ 12 13ENTRY(relocate_new_kernel) 14 15 adr r7, relocate_new_kernel_end 16 ldr r0, [r7, #KEXEC_INDIR_PAGE] 17 ldr r1, [r7, #KEXEC_START_ADDR] 18 19 /* 20 * If there is no indirection page (we are doing crashdumps) 21 * skip any relocation. 22 */ 23 cmp r0, #0 24 beq 2f 25 260: /* top, read another word for the indirection page */ 27 ldr r3, [r0],#4 28 29 /* Is it a destination page. Put destination address to r4 */ 30 tst r3,#1 31 beq 1f 32 bic r4,r3,#1 33 b 0b 341: 35 /* Is it an indirection page */ 36 tst r3,#2 37 beq 1f 38 bic r0,r3,#2 39 b 0b 401: 41 42 /* are we done ? */ 43 tst r3,#4 44 beq 1f 45 b 2f 46 471: 48 /* is it source ? */ 49 tst r3,#8 50 beq 0b 51 bic r3,r3,#8 52 mov r6,#1024 539: 54 ldr r5,[r3],#4 55 str r5,[r4],#4 56 subs r6,r6,#1 57 bne 9b 58 b 0b 59 602: 61 /* Jump to relocated kernel */ 62 mov lr, r1 63 mov r0, #0 64 ldr r1, [r7, #KEXEC_MACH_TYPE] 65 ldr r2, [r7, #KEXEC_R2] 66 ARM( ret lr ) 67 THUMB( bx lr ) 68 69ENDPROC(relocate_new_kernel) 70 71 .align 3 72relocate_new_kernel_end: 73 74 .globl relocate_new_kernel_size 75relocate_new_kernel_size: 76 .long relocate_new_kernel_end - relocate_new_kernel 77 78 79