relocate_kernel.S 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * relocate_kernel.S - put the kernel image in place to boot
  4. */
  5. #include <linux/linkage.h>
  6. #include <asm/assembler.h>
  7. #include <asm/asm-offsets.h>
  8. #include <asm/kexec.h>
  9. .align 3 /* not needed for this code, but keeps fncpy() happy */
  10. ENTRY(relocate_new_kernel)
  11. adr r7, relocate_new_kernel_end
  12. ldr r0, [r7, #KEXEC_INDIR_PAGE]
  13. ldr r1, [r7, #KEXEC_START_ADDR]
  14. /*
  15. * If there is no indirection page (we are doing crashdumps)
  16. * skip any relocation.
  17. */
  18. cmp r0, #0
  19. beq 2f
  20. 0: /* top, read another word for the indirection page */
  21. ldr r3, [r0],#4
  22. /* Is it a destination page. Put destination address to r4 */
  23. tst r3,#1
  24. beq 1f
  25. bic r4,r3,#1
  26. b 0b
  27. 1:
  28. /* Is it an indirection page */
  29. tst r3,#2
  30. beq 1f
  31. bic r0,r3,#2
  32. b 0b
  33. 1:
  34. /* are we done ? */
  35. tst r3,#4
  36. beq 1f
  37. b 2f
  38. 1:
  39. /* is it source ? */
  40. tst r3,#8
  41. beq 0b
  42. bic r3,r3,#8
  43. mov r6,#1024
  44. 9:
  45. ldr r5,[r3],#4
  46. str r5,[r4],#4
  47. subs r6,r6,#1
  48. bne 9b
  49. b 0b
  50. 2:
  51. /* Jump to relocated kernel */
  52. mov lr, r1
  53. mov r0, #0
  54. ldr r1, [r7, #KEXEC_MACH_TYPE]
  55. ldr r2, [r7, #KEXEC_R2]
  56. ARM( ret lr )
  57. THUMB( bx lr )
  58. ENDPROC(relocate_new_kernel)
  59. .align 3
  60. relocate_new_kernel_end:
  61. .globl relocate_new_kernel_size
  62. relocate_new_kernel_size:
  63. .long relocate_new_kernel_end - relocate_new_kernel