startup_gcc.S 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018/10/01 Bernard The first version
  9. * 2018/12/27 Jesven Add SMP support
  10. * 2020/6/12 Xim Port to QEMU and remove SMP support
  11. * 2024-06-30 Shell Support of kernel remapping
  12. */
  13. #include <encoding.h>
  14. #include <cpuport.h>
  15. .data
  16. .global boot_hartid /* global varible rt_boot_hartid in .data section */
  17. boot_hartid:
  18. .word 0xdeadbeef
  19. .global _start
  20. .section ".start", "ax"
  21. _start:
  22. j 1f
  23. .word 0xdeadbeef
  24. .align 3
  25. .global g_wake_up
  26. g_wake_up:
  27. .dword 1
  28. .dword 0
  29. 1:
  30. /* save hartid */
  31. la t0, boot_hartid /* global varible rt_boot_hartid */
  32. #ifdef RT_USING_SMP
  33. lw t2, (t0)
  34. li t3, 0xdeadbeef /* Sentinel value indicating uninitialized boot_hartid */
  35. li t4, 0xffffffff
  36. and t2, t2, t4 /* Extract the lower 32 bits. */
  37. bne t2, t3, system_init /* If the current value is 0xdeadbeef, skip the boot_hartid assignment operation. */
  38. #endif
  39. mv t1, a0 /* get hartid in S-mode frome a0 register */
  40. sw t1, (t0) /* store t1 register low 4 bits in memory address which is stored in t0 */
  41. #ifdef RT_USING_SMP
  42. system_init:
  43. #endif
  44. /*
  45. * When ARCH_MM_MMU is not enabled or pvoff==0:
  46. * Store hartid temporarily in the satp register because:
  47. * 1. satp is not used for address translation when MMU is disabled or pvoff==0.
  48. * 2. This value will be moved to percpu_hartid once MMU is initialized.
  49. * This approach avoids using extra memory or registers during the critical boot phase,
  50. * but developers should be aware that satp is overloaded for this purpose until MMU setup.
  51. */
  52. csrw satp, a0
  53. /* clear Interrupt Registers */
  54. csrw sie, 0
  55. csrw sip, 0
  56. /* set Trap Vector Base Address Register */
  57. la t0, trap_entry
  58. csrw stvec, t0
  59. li x1, 0
  60. li x2, 0
  61. li x3, 0
  62. li x4, 0
  63. li x5, 0
  64. li x6, 0
  65. li x7, 0
  66. li x8, 0
  67. li x9, 0
  68. #ifndef RT_USING_SMP
  69. /* In the SMP architecture, a0 will be used again later */
  70. li x10,0
  71. #endif
  72. li x11,0
  73. li x12,0
  74. li x13,0
  75. li x14,0
  76. li x15,0
  77. li x16,0
  78. li x17,0
  79. li x18,0
  80. li x19,0
  81. li x20,0
  82. li x21,0
  83. li x22,0
  84. li x23,0
  85. li x24,0
  86. li x25,0
  87. li x26,0
  88. li x27,0
  89. li x28,0
  90. li x29,0
  91. li x30,0
  92. li x31,0
  93. /* set to disable FPU */
  94. li t0, SSTATUS_FS + SSTATUS_VS
  95. csrc sstatus, t0
  96. li t0, SSTATUS_SUM
  97. csrs sstatus, t0
  98. .option push
  99. .option norelax
  100. la gp, __global_pointer$
  101. .option pop
  102. #ifndef RT_USING_SMP
  103. /* removed SMP support here */
  104. la sp, __stack_start__
  105. li t0, __STACKSIZE__
  106. add sp, sp, t0
  107. #else
  108. /* Initialize the sp pointer according to different hartids. */
  109. mv t0, a0
  110. /* calculate stack offset: hartid * __STACKSIZE__ */
  111. li t1, __STACKSIZE__
  112. mul t0, t0, t1 /* t0 = hartid * __STACKSIZE__ */
  113. /* set stack pointer */
  114. la sp, __stack_start__
  115. add sp, sp, t0 /* sp = __stack_start__ + hartid * __STACKSIZE__ */
  116. add sp, sp, t1 /* sp += __STACKSIZE__ (point to stack top) */
  117. mv t0, a0
  118. lw t1, boot_hartid
  119. mv tp, a0
  120. bne t0, t1, early_secondary_cpu_entry
  121. #endif /* RT_USING_SMP */
  122. /**
  123. * sscratch is always zero on kernel mode
  124. */
  125. csrw sscratch, zero
  126. call init_bss
  127. early_secondary_cpu_entry:
  128. #ifdef ARCH_MM_MMU
  129. // Manually manage pages in the early stage
  130. la a0, .early_page_array
  131. call set_free_page
  132. la a0, .early_tbl_page
  133. mv a1, tp
  134. call rt_hw_mem_setup_early
  135. call rt_kmem_pvoff
  136. /* a0 := pvoff */
  137. beq a0, zero, 1f
  138. /* relocate pc */
  139. la x1, _after_pc_relocation
  140. sub x1, x1, a0
  141. ret
  142. _after_pc_relocation:
  143. #if defined(RT_USING_SMP)
  144. /* If the MMU is enabled, save the hartid in percpu_hartid.
  145. * -> .percpu_hartid (hartid_0)
  146. * ...... align(2MB)
  147. * -> (hartid_1)
  148. * ......
  149. */
  150. la a0, .percpu_hartid
  151. mv a1, tp
  152. call rt_hw_percpu_hartid_init
  153. #endif
  154. /* relocate gp */
  155. sub gp, gp, a0
  156. #ifndef RT_USING_SMP
  157. /* relocate context: sp */
  158. la sp, __stack_start__
  159. li t0, __STACKSIZE__
  160. add sp, sp, t0
  161. #else
  162. /* Initialize the sp pointer according to different hartids. */
  163. mv t0, tp
  164. /* calculate stack offset: hartid * __STACKSIZE__ */
  165. li t1, __STACKSIZE__
  166. mul t0, t0, t1 /* t0 = hartid * __STACKSIZE__ */
  167. /* set stack pointer */
  168. la sp, __stack_start__
  169. add sp, sp, t0 /* sp = __stack_start__ + hartid * __STACKSIZE__ */
  170. add sp, sp, t1 /* sp += __STACKSIZE__ (point to stack top) */
  171. #endif /* RT_USING_SMP */
  172. /* reset s0-fp */
  173. mv s0, zero
  174. /* relocate stvec */
  175. la t0, trap_entry
  176. csrw stvec, t0
  177. 1:
  178. #ifdef RT_USING_SMP
  179. mv t0, tp
  180. lw t1, boot_hartid
  181. bne t0, t1, secondary_cpu_entry
  182. #endif
  183. #endif /* ARCH_MM_MMU */
  184. call sbi_init
  185. call primary_cpu_entry
  186. _never_return_here:
  187. j .
  188. .global _start_link_addr
  189. _start_link_addr:
  190. .dword __text_start
  191. #ifdef ARCH_MM_MMU
  192. #ifdef RT_USING_SMP
  193. /*
  194. * CPU stack builtin
  195. */
  196. .section ".percpu"
  197. .percpu_hartid:
  198. .space 16
  199. #endif
  200. .section ".bss"
  201. .equ page_size, 4096
  202. .balign page_size
  203. .early_tbl_page:
  204. .space 1 * page_size
  205. #if defined(RT_USING_SMP) && RT_CPUS_NR > 1
  206. .space (RT_CPUS_NR - 1) * page_size
  207. #endif
  208. .early_page_array:
  209. .space (8 + 8) * page_size
  210. #ifdef RT_USING_SMP
  211. .space RT_CPUS_NR * 5 * page_size
  212. #endif
  213. #endif /* ARCH_MM_MMU */