trampoline.S 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. * kexec trampoline
  3. *
  4. * Based on code taken from kexec-tools and kexec-lite.
  5. *
  6. * Copyright (C) 2004 - 2005, Milton D Miller II, IBM Corporation
  7. * Copyright (C) 2006, Mohan Kumar M, IBM Corporation
  8. * Copyright (C) 2013, Anton Blanchard, IBM Corporation
  9. *
  10. * This program is free software; you can redistribute it and/or modify it under
  11. * the terms of the GNU General Public License as published by the Free
  12. * Software Foundation (version 2 of the License).
  13. */
  14. #include <asm/asm-compat.h>
  15. .machine ppc64
  16. .balign 256
  17. .globl purgatory_start
  18. purgatory_start:
  19. b master
  20. /* ABI: possible run_at_load flag at 0x5c */
  21. .org purgatory_start + 0x5c
  22. .globl run_at_load
  23. run_at_load:
  24. .long 0
  25. .size run_at_load, . - run_at_load
  26. /* ABI: slaves start at 60 with r3=phys */
  27. .org purgatory_start + 0x60
  28. slave:
  29. b .
  30. /* ABI: end of copied region */
  31. .org purgatory_start + 0x100
  32. .size purgatory_start, . - purgatory_start
  33. /*
  34. * The above 0x100 bytes at purgatory_start are replaced with the
  35. * code from the kernel (or next stage) by setup_purgatory().
  36. */
  37. master:
  38. or %r1,%r1,%r1 /* low priority to let other threads catchup */
  39. isync
  40. mr %r17,%r3 /* save cpu id to r17 */
  41. mr %r15,%r4 /* save physical address in reg15 */
  42. or %r3,%r3,%r3 /* ok now to high priority, lets boot */
  43. lis %r6,0x1
  44. mtctr %r6 /* delay a bit for slaves to catch up */
  45. bdnz . /* before we overwrite 0-100 again */
  46. bl 0f /* Work out where we're running */
  47. 0: mflr %r18
  48. /* load device-tree address */
  49. ld %r3, (dt_offset - 0b)(%r18)
  50. mr %r16,%r3 /* save dt address in reg16 */
  51. li %r4,20
  52. LWZX_BE %r6,%r3,%r4 /* fetch __be32 version number at byte 20 */
  53. cmpwi %cr0,%r6,2 /* v2 or later? */
  54. blt 1f
  55. li %r4,28
  56. STWX_BE %r17,%r3,%r4 /* Store my cpu as __be32 at byte 28 */
  57. 1:
  58. /* load the kernel address */
  59. ld %r4,(kernel - 0b)(%r18)
  60. /* load the run_at_load flag */
  61. /* possibly patched by kexec */
  62. ld %r6,(run_at_load - 0b)(%r18)
  63. /* and patch it into the kernel */
  64. stw %r6,(0x5c)(%r4)
  65. mr %r3,%r16 /* restore dt address */
  66. li %r5,0 /* r5 will be 0 for kernel */
  67. mfmsr %r11
  68. andi. %r10,%r11,1 /* test MSR_LE */
  69. bne .Little_endian
  70. mtctr %r4 /* prepare branch to */
  71. bctr /* start kernel */
  72. .Little_endian:
  73. mtsrr0 %r4 /* prepare branch to */
  74. clrrdi %r11,%r11,1 /* clear MSR_LE */
  75. mtsrr1 %r11
  76. rfid /* update MSR and start kernel */
  77. .balign 8
  78. .globl kernel
  79. kernel:
  80. .8byte 0x0
  81. .size kernel, . - kernel
  82. .balign 8
  83. .globl dt_offset
  84. dt_offset:
  85. .8byte 0x0
  86. .size dt_offset, . - dt_offset
  87. .data
  88. .balign 8
  89. .globl purgatory_sha256_digest
  90. purgatory_sha256_digest:
  91. .skip 32
  92. .size purgatory_sha256_digest, . - purgatory_sha256_digest
  93. .balign 8
  94. .globl purgatory_sha_regions
  95. purgatory_sha_regions:
  96. .skip 8 * 2 * 16
  97. .size purgatory_sha_regions, . - purgatory_sha_regions