linux/arch/arm/kernel/relocate_kernel.S
<<
>>
Prefs
   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
  12ENTRY(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
  240:      /* 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
  321:
  33        /* Is it an indirection page */
  34        tst     r3,#2,0
  35        beq     1f
  36        bic     r0,r3,#2
  37        b       0b
  381:
  39
  40        /* are we done ? */
  41        tst     r3,#4,0
  42        beq     1f
  43        b       2f
  44
  451:
  46        /* is it source ? */
  47        tst     r3,#8,0
  48        beq     0b
  49        bic r3,r3,#8
  50        mov r6,#1024
  519:
  52        ldr r5,[r3],#4
  53        str r5,[r4],#4
  54        subs r6,r6,#1
  55        bne 9b
  56        b 0b
  57
  582:
  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
  70kexec_start_address:
  71        .long   0x0
  72
  73        .globl kexec_indirection_page
  74kexec_indirection_page:
  75        .long   0x0
  76
  77        .globl kexec_mach_type
  78kexec_mach_type:
  79        .long   0x0
  80
  81        /* phy addr of the atags for the new kernel */
  82        .globl kexec_boot_atags
  83kexec_boot_atags:
  84        .long   0x0
  85
  86ENDPROC(relocate_new_kernel)
  87
  88relocate_new_kernel_end:
  89
  90        .globl relocate_new_kernel_size
  91relocate_new_kernel_size:
  92        .long relocate_new_kernel_end - relocate_new_kernel
  93
  94
  95