relocate_kernel.S 1.5 KB

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