relocate_64.S 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /* SPDX-License-Identifier: GPL-2.0+ */
  2. /*
  3. * relocate - common relocation function for AArch64 U-Boot
  4. *
  5. * (C) Copyright 2013
  6. * Albert ARIBAUD <albert.u.boot@aribaud.net>
  7. * David Feng <fenghua@phytium.com.cn>
  8. */
  9. #include <asm-offsets.h>
  10. #include <config.h>
  11. #include <elf.h>
  12. #include <linux/linkage.h>
  13. #include <asm/macro.h>
  14. /*
  15. * void relocate_code (addr_moni)
  16. *
  17. * This function relocates the monitor code.
  18. * x0 holds the destination address.
  19. */
  20. ENTRY(relocate_code)
  21. stp x29, x30, [sp, #-32]! /* create a stack frame */
  22. mov x29, sp
  23. str x0, [sp, #16]
  24. /*
  25. * Copy u-boot from flash to RAM
  26. */
  27. adr x1, __image_copy_start /* x1 <- Run &__image_copy_start */
  28. subs x9, x0, x1 /* x8 <- Run to copy offset */
  29. b.eq relocate_done /* skip relocation */
  30. /*
  31. * Don't ldr x1, __image_copy_start here, since if the code is already
  32. * running at an address other than it was linked to, that instruction
  33. * will load the relocated value of __image_copy_start. To
  34. * correctly apply relocations, we need to know the linked value.
  35. *
  36. * Linked &__image_copy_start, which we know was at
  37. * CONFIG_SYS_TEXT_BASE, which is stored in _TEXT_BASE, as a non-
  38. * relocated value, since it isn't a symbol reference.
  39. */
  40. ldr x1, _TEXT_BASE /* x1 <- Linked &__image_copy_start */
  41. subs x9, x0, x1 /* x9 <- Link to copy offset */
  42. adr x1, __image_copy_start /* x1 <- Run &__image_copy_start */
  43. adr x2, __image_copy_end /* x2 <- Run &__image_copy_end */
  44. copy_loop:
  45. ldp x10, x11, [x1], #16 /* copy from source address [x1] */
  46. stp x10, x11, [x0], #16 /* copy to target address [x0] */
  47. cmp x1, x2 /* until source end address [x2] */
  48. b.lo copy_loop
  49. str x0, [sp, #24]
  50. /*
  51. * Fix .rela.dyn relocations
  52. */
  53. adr x2, __rel_dyn_start /* x2 <- Run &__rel_dyn_start */
  54. adr x3, __rel_dyn_end /* x3 <- Run &__rel_dyn_end */
  55. fixloop:
  56. ldp x0, x1, [x2], #16 /* (x0,x1) <- (SRC location, fixup) */
  57. ldr x4, [x2], #8 /* x4 <- addend */
  58. and x1, x1, #0xffffffff
  59. cmp x1, #R_AARCH64_RELATIVE
  60. bne fixnext
  61. /* relative fix: store addend plus offset at dest location */
  62. add x0, x0, x9
  63. add x4, x4, x9
  64. str x4, [x0]
  65. fixnext:
  66. cmp x2, x3
  67. b.lo fixloop
  68. relocate_done:
  69. switch_el x1, 3f, 2f, 1f
  70. bl hang
  71. 3: mrs x0, sctlr_el3
  72. b 0f
  73. 2: mrs x0, sctlr_el2
  74. b 0f
  75. 1: mrs x0, sctlr_el1
  76. 0: tbz w0, #2, 5f /* skip flushing cache if disabled */
  77. tbz w0, #12, 4f /* skip invalidating i-cache if disabled */
  78. ic iallu /* i-cache invalidate all */
  79. isb sy
  80. 4: ldp x0, x1, [sp, #16]
  81. bl __asm_flush_dcache_range
  82. 5: ldp x29, x30, [sp],#32
  83. ret
  84. ENDPROC(relocate_code)