79 lines
1.3 KiB
ArmAsm
79 lines
1.3 KiB
ArmAsm
/* 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,0
|
|
beq 1f
|
|
bic r4,r3,#1
|
|
b 0b
|
|
1:
|
|
/* Is it an indirection page */
|
|
tst r3,#2,0
|
|
beq 1f
|
|
bic r0,r3,#2
|
|
b 0b
|
|
1:
|
|
|
|
/* are we done ? */
|
|
tst r3,#4,0
|
|
beq 1f
|
|
b 2f
|
|
|
|
1:
|
|
/* is it source ? */
|
|
tst r3,#8,0
|
|
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
|
|
|
|
|