trampoline_64.S 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * kexec trampoline
  4. *
  5. * Based on code taken from kexec-tools and kexec-lite.
  6. *
  7. * Copyright (C) 2004 - 2005, Milton D Miller II, IBM Corporation
  8. * Copyright (C) 2006, Mohan Kumar M, IBM Corporation
  9. * Copyright (C) 2013, Anton Blanchard, IBM Corporation
  10. */
  11. #include <asm/asm-compat.h>
  12. #include <asm/crashdump-ppc64.h>
  13. .balign 256
  14. .globl purgatory_start
  15. purgatory_start:
  16. b master
  17. /* ABI: possible run_at_load flag at 0x5c */
  18. .org purgatory_start + 0x5c
  19. .globl run_at_load
  20. run_at_load:
  21. .long 0
  22. .size run_at_load, . - run_at_load
  23. /* ABI: slaves start at 60 with r3=phys */
  24. .org purgatory_start + 0x60
  25. slave:
  26. b .
  27. /* ABI: end of copied region */
  28. .org purgatory_start + 0x100
  29. .size purgatory_start, . - purgatory_start
  30. /*
  31. * The above 0x100 bytes at purgatory_start are replaced with the
  32. * code from the kernel (or next stage) by setup_purgatory().
  33. */
  34. master:
  35. or %r1,%r1,%r1 /* low priority to let other threads catchup */
  36. isync
  37. mr %r17,%r3 /* save cpu id to r17 */
  38. mr %r15,%r4 /* save physical address in reg15 */
  39. /* Work out where we're running */
  40. bcl 20, 31, 0f
  41. 0: mflr %r18
  42. /*
  43. * Copy BACKUP_SRC_SIZE bytes from BACKUP_SRC_START to
  44. * backup_start 8 bytes at a time.
  45. *
  46. * Use r3 = dest, r4 = src, r5 = size, r6 = count
  47. */
  48. ld %r3, (backup_start - 0b)(%r18)
  49. cmpdi %cr0, %r3, 0
  50. beq .Lskip_copy /* skip if there is no backup region */
  51. lis %r5, BACKUP_SRC_SIZE@h
  52. ori %r5, %r5, BACKUP_SRC_SIZE@l
  53. cmpdi %cr0, %r5, 0
  54. beq .Lskip_copy /* skip if copy size is zero */
  55. lis %r4, BACKUP_SRC_START@h
  56. ori %r4, %r4, BACKUP_SRC_START@l
  57. li %r6, 0
  58. .Lcopy_loop:
  59. ldx %r0, %r6, %r4
  60. stdx %r0, %r6, %r3
  61. addi %r6, %r6, 8
  62. cmpld %cr0, %r6, %r5
  63. blt .Lcopy_loop
  64. .Lskip_copy:
  65. or %r3,%r3,%r3 /* ok now to high priority, lets boot */
  66. lis %r6,0x1
  67. mtctr %r6 /* delay a bit for slaves to catch up */
  68. bdnz . /* before we overwrite 0-100 again */
  69. /* load device-tree address */
  70. ld %r3, (dt_offset - 0b)(%r18)
  71. mr %r16,%r3 /* save dt address in reg16 */
  72. li %r4,20
  73. LWZX_BE %r6,%r3,%r4 /* fetch __be32 version number at byte 20 */
  74. cmpwi %cr0,%r6,2 /* v2 or later? */
  75. blt 1f
  76. li %r4,28
  77. STWX_BE %r17,%r3,%r4 /* Store my cpu as __be32 at byte 28 */
  78. 1:
  79. /* Load opal base and entry values in r8 & r9 respectively */
  80. ld %r8,(opal_base - 0b)(%r18)
  81. ld %r9,(opal_entry - 0b)(%r18)
  82. /* load the kernel address */
  83. ld %r4,(kernel - 0b)(%r18)
  84. /* load the run_at_load flag */
  85. /* possibly patched by kexec */
  86. ld %r6,(run_at_load - 0b)(%r18)
  87. /* and patch it into the kernel */
  88. stw %r6,(0x5c)(%r4)
  89. mr %r3,%r16 /* restore dt address */
  90. li %r5,0 /* r5 will be 0 for kernel */
  91. mfmsr %r11
  92. andi. %r10,%r11,1 /* test MSR_LE */
  93. bne .Little_endian
  94. mtctr %r4 /* prepare branch to */
  95. bctr /* start kernel */
  96. .Little_endian:
  97. mtsrr0 %r4 /* prepare branch to */
  98. clrrdi %r11,%r11,1 /* clear MSR_LE */
  99. mtsrr1 %r11
  100. rfid /* update MSR and start kernel */
  101. .balign 8
  102. .globl kernel
  103. kernel:
  104. .8byte 0x0
  105. .size kernel, . - kernel
  106. .balign 8
  107. .globl dt_offset
  108. dt_offset:
  109. .8byte 0x0
  110. .size dt_offset, . - dt_offset
  111. .balign 8
  112. .globl backup_start
  113. backup_start:
  114. .8byte 0x0
  115. .size backup_start, . - backup_start
  116. .balign 8
  117. .globl opal_base
  118. opal_base:
  119. .8byte 0x0
  120. .size opal_base, . - opal_base
  121. .balign 8
  122. .globl opal_entry
  123. opal_entry:
  124. .8byte 0x0
  125. .size opal_entry, . - opal_entry
  126. .data
  127. .balign 8
  128. .globl purgatory_sha256_digest
  129. purgatory_sha256_digest:
  130. .skip 32
  131. .size purgatory_sha256_digest, . - purgatory_sha256_digest
  132. .balign 8
  133. .globl purgatory_sha_regions
  134. purgatory_sha_regions:
  135. .skip 8 * 2 * 16
  136. .size purgatory_sha_regions, . - purgatory_sha_regions