preload.ASM 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * Copyright (c) 2006-2020, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Date Author Notes
  7. * 2021-06-29 Wayne the first version
  8. */
  9. /* GICv2 - Distributor Registers */
  10. #define GICD_CTLR 0x0000
  11. #define GICD_TYPER 0x0004
  12. #define GICD_IIDR 0x0008
  13. #define GICD_STATUSR 0x0010
  14. #define GICD_SETSPI_NSR 0x0040
  15. #define GICD_CLRSPI_NSR 0x0048
  16. #define GICD_SETSPI_SR 0x0050
  17. #define GICD_CLRSPI_SR 0x0058
  18. #define GICD_SEIR 0x0068
  19. #define GICD_IGROUPRn 0x0080
  20. #define GICD_ISENABLERn 0x0100
  21. #define GICD_ICENABLERn 0x0180
  22. #define GICD_ISPENDRn 0x0200
  23. #define GICD_ICPENDRn 0x0280
  24. #define GICD_ISACTIVERn 0x0300
  25. #define GICD_ICACTIVERn 0x0380
  26. #define GICD_IPRIORITYRn 0x0400
  27. #define GICD_ITARGETSRn 0x0800
  28. #define GICD_ICFGR 0x0c00
  29. #define GICD_IGROUPMODRn 0x0d00
  30. #define GICD_NSACRn 0x0e00
  31. #define GICD_SGIR 0x0f00
  32. #define GICD_CPENDSGIRn 0x0f10
  33. #define GICD_SPENDSGIRn 0x0f20
  34. #define GICD_IROUTERn 0x6000
  35. /* GICv2 - CPU Interface Memory Mapped Registers */
  36. #define GICC_CTLR 0x0000
  37. #define GICC_PMR 0x0004
  38. #define GICC_BPR 0x0008
  39. #define GICC_IAR 0x000C
  40. #define GICC_EOIR 0x0010
  41. #define GICC_RPR 0x0014
  42. #define GICC_HPPIR 0x0018
  43. #define GICC_ABPR 0x001c
  44. #define GICC_AIAR 0x0020
  45. #define GICC_AEOIR 0x0024
  46. #define GICC_AHPPIR 0x0028
  47. #define GICC_APRn 0x00d0
  48. #define GICC_NSAPRn 0x00e0
  49. #define GICC_IIDR 0x00fc
  50. #define GICC_DIR 0x1000
  51. .section ".text.entrypoint"
  52. .global _start
  53. _start:
  54. /* Give execution address for secondary CPU */
  55. adr x20, .
  56. mov sp, x20
  57. /*=============================================================*/
  58. /* Enable the SMP bit. */
  59. /*=============================================================*/
  60. mrs x0, S3_1_C15_C2_1
  61. orr x0, x0, #(1<<6)
  62. msr S3_1_C15_C2_1, x0
  63. /*=============================================================*/
  64. /* Read CPU id */
  65. /* Primary core(id=0): Help Secondary core leaving. */
  66. /* Secondary core(id>0): Notice 'Ready' to Primary core. */
  67. /*=============================================================*/
  68. /* MPIDR_EL1: Multi-Processor Affinity Register */
  69. mrs x1, mpidr_el1
  70. and x1, x1, #3
  71. cbz x1, .L__cpu_0
  72. .L__current_cpu_idle:
  73. /*=============================================================*/
  74. /* Secondary CPU notification */
  75. /*=============================================================*/
  76. wfe /* Wait for Primary CPU's notification */
  77. mov x0, #0x48 /* if (*(0x40460048)==0) */
  78. movk x0, #0x4046, LSL #16 /* goto L__current_cpu_idle */
  79. ldr x1, [x0] /* else */
  80. cmp x1, #0 /* *(0x4046004C)=_start */
  81. b.eq .L__current_cpu_idle /* goto L__cpus_trans_state */
  82. add x0, x0, #4
  83. str w1, [x0]
  84. b .L__cpus_trans_state
  85. .L__cpu_0:
  86. // *(0x4046004C) = 0
  87. mov x0, #0x4C
  88. movk x0, #0x4046, LSL #16
  89. mov x1, xzr
  90. str w1, [x0]
  91. mov x10, #0x1000 /* 4096 times looping */
  92. .L__cpu_0_loop:
  93. sub x10, x10, #0x1
  94. cmp x10, #0
  95. b.eq .L__cpus_trans_state
  96. /*=============================================================*/
  97. /* Help CPU-1 to leave IBR. */
  98. /*=============================================================*/
  99. mov x0, #0x48 /* *(0x40460048) = _start */
  100. movk x0, #0x4046, LSL #16
  101. mov x1, x20
  102. str w1, [x0]
  103. sev /* Wakeup Secondary CPU */
  104. add x0, x0, #4 /* if(*(0x4046004C)!=_start) */
  105. ldr w2, [x0] /* goto L__cpu_0_loop */
  106. cmp x1, x2
  107. bne .L__cpu_0_loop
  108. .L__cpus_trans_state:
  109. /*=============================================================*/
  110. /* Initialize Gtimer. Set frequency to 12MHz. */
  111. /*=============================================================*/
  112. mov x0, #0x1B00
  113. movk x0, #0xB7, LSL #16
  114. msr CNTFRQ_EL0, x0
  115. /*=============================================================*/
  116. /* Enable GICv2. */
  117. /* Assign all IRQs to secure group. */
  118. /*=============================================================*/
  119. /* Route to secure Group */
  120. mov x0, #0x1000
  121. movk x0, #0x5080, LSL #16
  122. mov w9, #0x3
  123. str w9, [x0, GICD_CTLR]
  124. ldr w9, [x0, GICD_TYPER]
  125. and w10, w9, #0x1f
  126. cbz w10, 1f
  127. add x11, x0, GICD_IGROUPRn
  128. mov w9, #0
  129. str w9, [x11], #0x04
  130. 0: str w9, [x11], #0x04
  131. sub w10, w10, #0x1
  132. cbnz w10, 0b
  133. mov x1, #0x2000
  134. movk x1, #0x5080, LSL #16
  135. mov w0, #3
  136. str w0, [x1]
  137. mov w0, #1 << 7
  138. str w0, [x1, #4]
  139. 1:
  140. mov x0, #0x1000
  141. movk x0, #0x5080, LSL #16
  142. mov x1, #0x2000
  143. movk x1, #0x5080, LSL #16
  144. mov w9, #0
  145. str w9, [x0, GICD_IGROUPRn]
  146. mov w9, #0x1
  147. str w9, [x0, GICD_ISENABLERn]
  148. mov w9, #0x1e7
  149. str w9, [x1, GICC_CTLR]
  150. mov w9, #0x1 << 7
  151. str w9, [x1, GICC_PMR]
  152. /*=============================================================*/
  153. /* Enable FP/SIMD at EL1 */
  154. /*=============================================================*/
  155. mov x0, #(3 << 20)
  156. msr cpacr_el1, x0 /* Enable FP/SIMD at EL1 */
  157. /*=============================================================*/
  158. /* Initialize sctlr_el1 */
  159. /*=============================================================*/
  160. mov x0, xzr
  161. orr x0, x0, #(1 << 29) /* Enable LSMAOE at EL1 */
  162. orr x0, x0, #(1 << 28) /* Enable nTLSMD at EL1 */
  163. orr x0, x0, #(1 << 23) /* Enable SPAN at EL1 */
  164. orr x0, x0, #(1 << 22) /* Enable EIS at EL1 */
  165. orr x0, x0, #(1 << 20) /* Enable TSCXT at EL1 */
  166. orr x0, x0, #(1 << 11) /* Enable EOS at EL1 */
  167. msr sctlr_el1, x0
  168. /*=============================================================*/
  169. /* Initialize scr_el3 */
  170. /*=============================================================*/
  171. mov x0, xzr
  172. /* RW, Lower levels are all AArch32. */
  173. orr x0, x0, #(1 << 9) /* Enable SIF */
  174. orr x0, x0, #(1 << 8) /* Enable HCE */
  175. orr x0, x0, #(1 << 7) /* Enable SMD */
  176. orr x0, x0, #(1 << 5) /* RES1[5:4] */
  177. orr x0, x0, #(1 << 4)
  178. /* Disable FIQ routing */
  179. /* Disable IRQ routing */
  180. /* Disable NS */
  181. msr scr_el3, x0
  182. /*=============================================================*/
  183. /* Initialize spsr_el3 */
  184. /*=============================================================*/
  185. mov x0, xzr
  186. mov x0, #0b00011 /* AARCH32_SVC */
  187. orr x0, x0, #(1 << 8) /* Enable SError and External Abort. */
  188. orr x0, x0, #(1 << 7) /* IRQ interrupt Process state mask. */
  189. orr x0, x0, #(1 << 6) /* FIQ interrupt Process state mask. */
  190. orr x0, x0, #(1 << 4) /* FIQ interrupt Process state mask. */
  191. msr spsr_el3, x0
  192. /*=============================================================*/
  193. /* Initialize elr_el3 */
  194. /* Jump to Secure AARCH32_SVC from EL3. */
  195. /*=============================================================*/
  196. adr x0, .aarch32_code /* Exception return to aarch32_code */
  197. msr elr_el3, x0
  198. eret
  199. .aarch32_code: