aarch32_boot.S 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Email: opensource_embedded@phytium.com.cn
  7. *
  8. * Change Logs:
  9. * Date Author Notes
  10. * 2022-10-26 huanghe first commit
  11. * 2023-07-27 zhugengyu flush cache in aarch64-el2
  12. *
  13. */
  14. .global _boot
  15. .set FPEXC_EN, 0x40000000 /* FPU enable bit, (1 << 30) */
  16. .org 0
  17. .text
  18. .section .boot,"ax"
  19. _boot:
  20. /* hard code aarch64 instruction to flush dcache, refer to rt-thread __asm_flush_dcache_all */
  21. .long 0xd2800000 /* mov x0, #0x0 // clean and invaildate d-cache */
  22. .long 0x1400001a /* b <InvalidateFlushDcaches> */
  23. InvalidateFlushDcacheLevel:
  24. .long 0xd37ff80c /* lsl x12, x0, #1 */
  25. .long 0xd51a000c /* msr csselr_el1, x12 */
  26. .long 0xd5033fdf /* isb */
  27. .long 0xd5390006 /* mrs x6, ccsidr_el1 */
  28. .long 0x924008c2 /* and x2, x6, #0x7 */
  29. .long 0x91001042 /* add x2, x2, #0x4 */
  30. .long 0xd2807fe3 /* mov x3, #0x3ff */
  31. .long 0x8a460c63 /* and x3, x3, x6, lsr #3 */
  32. .long 0x5ac01065 /* clz w5, w3 */
  33. .long 0xd28fffe4 /* mov x4, #0x7fff */
  34. .long 0x8a463484 /* and x4, x4, x6, lsr #13 */
  35. InvalidateFlushCacheSet:
  36. .long 0xaa0303e6 /* mov x6, x3 */
  37. InvalidateFlushCacheWay:
  38. .long 0x9ac520c7 /* lsl x7, x6, x5 */
  39. .long 0xaa070189 /* orr x9, x12, x7 */
  40. .long 0x9ac22087 /* lsl x7, x4, x2 */
  41. .long 0xaa070129 /* orr x9, x9, x7 */
  42. .long 0x36000061 /* tbz w1, #0, <InvalidateFlushCacheWay+0x1c> */
  43. .long 0xd5087649 /* dc isw, x9 */
  44. .long 0x14000002 /* b <InvalidateFlushCacheWay+0x20> */
  45. .long 0xd5087e49 /* dc cisw, x9 */
  46. .long 0xf10004c6 /* subs x6, x6, #0x1 */
  47. .long 0x54fffeea /* b.ge <InvalidateFlushCacheWay> */
  48. .long 0xf1000484 /* subs x4, x4, #0x1 */
  49. .long 0x54fffe8a /* b.ge <InvalidateFlushCacheSet> */
  50. .long 0xd65f03c0 /* ret */
  51. InvalidateFlushDcaches:
  52. .long 0xaa0003e1 /* mov x1, x0 */
  53. .long 0xd5033f9f /* dsb sy */
  54. .long 0xd539002a /* mrs x10, clidr_el1 */
  55. .long 0xd358fd4b /* lsr x11, x10, #24 */
  56. .long 0x9240096b /* and x11, x11, #0x7 */
  57. .long 0xb400024b /* cbz x11, <InvalidateFlushDcacheEnd> */
  58. .long 0xaa1e03ef /* mov x15, x30 */
  59. .long 0xd2800000 /* mov x0, #0x0 */
  60. InvalidateFlushCachesLoopLevel:
  61. .long 0xd37ff80c /* lsl x12, x0, #1 */
  62. .long 0x8b00018c /* add x12, x12, x0 */
  63. .long 0x9acc254c /* lsr x12, x10, x12 */
  64. .long 0x9240098c /* and x12, x12, #0x7 */
  65. .long 0xf100099f /* cmp x12, #0x2 */
  66. .long 0x5400004b /* b.lt <InvalidateFlushCachesSkipLevel> */
  67. .long 0x97ffffd9 /* bl <InvalidateFlushDcacheLevel> */
  68. InvalidateFlushCachesSkipLevel:
  69. .long 0x91000400 /* add x0, x0, #0x1 */
  70. .long 0xeb00017f /* cmp x11, x0 */
  71. .long 0x54fffeec /* b.gt <InvalidateFlushCachesLoopLevel> */
  72. .long 0xd2800000 /* mov x0, #0x0 */
  73. .long 0xd51a0000 /* msr csselr_el1, x0 */
  74. .long 0xd5033f9f /* dsb sy */
  75. .long 0xd5033fdf /* isb */
  76. .long 0xaa0f03fe /* mov x30, x15 */
  77. InvalidateFlushDcacheEnd:
  78. /***************************************************************/
  79. /* switch from aarch64-el2 to aarch32-el1 */
  80. Startup_Aarch32:
  81. .long 0xd5384240 /* mrs x0, currentel */
  82. .long 0xd342fc00 /* lsr x0, x0, #2 */
  83. .long 0x92400400 /* and x0, x0, #0x3 */
  84. .long 0xf1000c1f /* cmp x0, #0x3 */
  85. .long 0x540003a1 /* b.ne 1d0080c4 <el2_mode> */
  86. el3_mode:
  87. .long 0xd53ecca0 /* mrs x0, s3_6_c12_c12_5 - ICC_SRE_EL3 */
  88. .long 0xb2400c00 /* orr x0, x0, #0xf */
  89. .long 0xd51ecca0 /* msr s3_6_c12_c12_5, x0 */
  90. .long 0xd5033fdf /* isb */
  91. .long 0xd53cc9a0 /* mrs x0, s3_4_c12_c9_5 - ICC_SRE_EL2 */
  92. .long 0xb2400c00 /* orr x0, x0, #0xf */
  93. .long 0xd51cc9a0 /* msr s3_4_c12_c9_5, x0 */
  94. .long 0xd5033fdf /* isb */
  95. .long 0xd538cca0 /* mrs x0, s3_0_c12_c12_5 - ICC_SRE_EL1 */
  96. .long 0xb2400000 /* orr x0, x0, #0x1 */
  97. .long 0xd518cca0 /* msr s3_0_c12_c12_5, x0 */
  98. .long 0xd5033fdf /* isb */
  99. .long 0xd2803620 /* mov x0, #0x1b1 */
  100. .long 0xd51e1100 /* msr scr_el3, x0 */
  101. .long 0xd2867fe0 /* mov x0, #0x33ff */
  102. .long 0xd51c1140 /* msr cptr_el2, x0 */
  103. .long 0xd2810000 /* mov x0, #0x800 */
  104. .long 0xf2a61a00 /* movk x0, #0x30d0, lsl #16 */
  105. .long 0xd5181000 /* msr sctlr_el1, x0 */
  106. .long 0x910003e0 /* mov x0, sp */
  107. .long 0xd51c4100 /* msr sp_el1, x0 */
  108. .long 0xd53ec000 /* mrs x0, vbar_el3 */
  109. .long 0xd518c000 /* msr vbar_el1, x0 */
  110. .long 0xd2803a60 /* mov x0, #0x1d3 */
  111. .long 0xd51e4000 /* msr spsr_el3, x0 */
  112. .long 0x10000500 /* adr x0, 1d008158 <el1_mode> */
  113. .long 0xd51e4020 /* msr elr_el3, x0 */
  114. .long 0xd69f03e0 /* eret */
  115. el2_mode:
  116. .long 0xd53cc9a0 /* mrs x0, s3_4_c12_c9_5 - ICC_SRE_EL2 */
  117. .long 0xb2400c00 /* orr x0, x0, #0xf */
  118. .long 0xd51cc9a0 /* msr s3_4_c12_c9_5, x0 */
  119. .long 0xd5033fdf /* isb */
  120. .long 0xd538cca0 /* mrs x0, s3_0_c12_c12_5 - ICC_SRE_EL1 */
  121. .long 0xb2400000 /* orr x0, x0, #0x1 */
  122. .long 0xd518cca0 /* msr s3_0_c12_c12_5, x0 */
  123. .long 0xd5033fdf /* isb */
  124. .long 0xd53ce100 /* mrs x0, cnthctl_el2 */
  125. .long 0xb2400400 /* orr x0, x0, #0x3 */
  126. .long 0xd51ce100 /* msr cnthctl_el2, x0 */
  127. .long 0xd51ce07f /* msr cntvoff_el2, xzr */
  128. .long 0xd5380000 /* mrs x0, midr_el1 */
  129. .long 0xd53800a1 /* mrs x1, mpidr_el1 */
  130. .long 0xd51c0000 /* msr vpidr_el2, x0 */
  131. .long 0xd51c00a1 /* msr vmpidr_el2, x1 */
  132. .long 0xd2867fe0 /* mov x0, #0x33ff */
  133. .long 0xd51c1140 /* msr cptr_el2, x0 */
  134. .long 0xd51c117f /* msr hstr_el2, xzr */
  135. .long 0xd2a00600 /* mov x0, #0x300000 */
  136. .long 0xd5181040 /* msr cpacr_el1, x0 */
  137. .long 0xd2800000 /* mov x0, #0x0 */
  138. .long 0xb2630000 /* orr x0, x0, #0x20000000 */
  139. .long 0xd51c1100 /* msr hcr_el2, x0 */
  140. .long 0xd53c1100 /* mrs x0, hcr_el2 */
  141. .long 0xd2810000 /* mov x0, #0x800 */
  142. .long 0xf2a61a00 /* movk x0, #0x30d0, lsl #16 */
  143. .long 0xd5181000 /* msr sctlr_el1, x0 */
  144. .long 0x910003e0 /* mov x0, sp */
  145. .long 0xd51c4100 /* msr sp_el1, x0 */
  146. .long 0xd53cc000 /* mrs x0, vbar_el2 */
  147. .long 0xd518c000 /* msr vbar_el1, x0 */
  148. .long 0xd2803a60 /* mov x0, #0x1d3 */
  149. .long 0xd51c4000 /* msr spsr_el2, x0 */
  150. .long 0x10000060 /* adr x0, 1d008158 <el1_mode> */
  151. .long 0xd51c4020 /* msr elr_el2, x0 */
  152. .long 0xd69f03e0 /* eret */
  153. el1_mode:
  154. mov r0, #0
  155. mov r1, #0
  156. mov r2, #0
  157. mov r3, #0
  158. mov r4, #0
  159. mov r5, #0
  160. mov r6, #0
  161. mov r7, #0
  162. mov r8, #0
  163. mov r9, #0
  164. mov r10, #0
  165. mov r11, #0
  166. mov r12, #0
  167. mcr p15, 0, r0, c1, c0, 0 /* reset control register */
  168. isb
  169. /* enable vfp, therefore f_prink workable */
  170. vmrs r1, FPEXC /* read the exception register */
  171. orr r1,r1, #FPEXC_EN /* set VFP enable bit, leave the others in orig state */
  172. vmsr FPEXC, r1 /* write back the exception register */
  173. bl system_vectors /* jump to libcpu/arm/cortex-a/vector_gcc.S */