startup.s 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. /*********************************************************************
  2. * SEGGER Microcontroller GmbH *
  3. * The Embedded Experts *
  4. **********************************************************************
  5. * *
  6. * (c) 2014 - 2021 SEGGER Microcontroller GmbH *
  7. * *
  8. * www.segger.com Support: support@segger.com *
  9. * *
  10. **********************************************************************
  11. * *
  12. * All rights reserved. *
  13. * *
  14. * Redistribution and use in source and binary forms, with or *
  15. * without modification, are permitted provided that the following *
  16. * condition is met: *
  17. * *
  18. * - Redistributions of source code must retain the above copyright *
  19. * notice, this condition and the following disclaimer. *
  20. * *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
  22. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
  23. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
  24. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
  25. * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
  26. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
  27. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
  28. * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
  29. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
  30. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
  31. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
  32. * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
  33. * DAMAGE. *
  34. * *
  35. **********************************************************************
  36. -------------------------- END-OF-HEADER -----------------------------
  37. File : SEGGER_RISCV_crt0.s
  38. Purpose : Generic runtime init startup code for RISC-V CPUs.
  39. Designed to work with the SEGGER linker to produce
  40. smallest possible executables.
  41. This file does not normally require any customization.
  42. Additional information:
  43. Preprocessor Definitions
  44. FULL_LIBRARY
  45. If defined then
  46. - argc, argv are set up by calling SEGGER_SEMIHOST_GetArgs().
  47. - the exit symbol is defined and executes on return from main.
  48. - the exit symbol calls destructors, atexit functions and then
  49. calls SEGGER_SEMIHOST_Exit().
  50. If not defined then
  51. - argc and argv are not valid (main is assumed to not take parameters)
  52. - the exit symbol is defined, executes on return from main and
  53. halts in a loop.
  54. */
  55. #include "hpm_csr_regs.h"
  56. /*********************************************************************
  57. *
  58. * Defines, configurable
  59. *
  60. **********************************************************************
  61. */
  62. #ifndef APP_ENTRY_POINT
  63. #define APP_ENTRY_POINT reset_handler
  64. #endif
  65. #ifndef ARGSSPACE
  66. #define ARGSSPACE 128
  67. #endif
  68. /*********************************************************************
  69. *
  70. * Macros
  71. *
  72. **********************************************************************
  73. */
  74. //
  75. // Declare a label as function symbol (without switching sections)
  76. //
  77. .macro MARK_FUNC Name
  78. .global \Name
  79. .type \Name, function
  80. \Name:
  81. .endm
  82. //
  83. // Declare a regular function.
  84. // Functions from the startup are placed in the init section.
  85. //
  86. .macro START_FUNC Name
  87. .section .init.\Name, "ax"
  88. .global \Name
  89. #if __riscv_compressed
  90. .balign 2
  91. #else
  92. .balign 4
  93. #endif
  94. .type \Name, function
  95. \Name:
  96. .endm
  97. //
  98. // Declare a weak function
  99. //
  100. .macro WEAK_FUNC Name
  101. .section .init.\Name, "ax", %progbits
  102. .global \Name
  103. .weak \Name
  104. #if __riscv_compressed
  105. .balign 2
  106. #else
  107. .balign 4
  108. #endif
  109. .type \Name, function
  110. \Name:
  111. .endm
  112. //
  113. // Mark the end of a function and calculate its size
  114. //
  115. .macro END_FUNC name
  116. .size \name,.-\name
  117. .endm
  118. /*********************************************************************
  119. *
  120. * Externals
  121. *
  122. **********************************************************************
  123. */
  124. .extern APP_ENTRY_POINT // typically main
  125. /*********************************************************************
  126. *
  127. * Global functions
  128. *
  129. **********************************************************************
  130. */
  131. /*********************************************************************
  132. *
  133. * _start
  134. *
  135. * Function description
  136. * Entry point for the startup code.
  137. * Usually called by the reset handler.
  138. * Performs all initialisation, based on the entries in the
  139. * linker-generated init table, then calls main().
  140. * It is device independent, so there should not be any need for an
  141. * end-user to modify it.
  142. *
  143. * Additional information
  144. * At this point, the stack pointer should already have been
  145. * initialized
  146. * - by hardware (such as on Cortex-M),
  147. * - by the device-specific reset handler,
  148. * - or by the debugger (such as for RAM Code).
  149. */
  150. #undef L
  151. #define L(label) .L_start_##label
  152. START_FUNC _start
  153. .option push
  154. .option norelax
  155. lui gp, %hi(__global_pointer$)
  156. addi gp, gp, %lo(__global_pointer$)
  157. lui tp, %hi(__thread_pointer$)
  158. addi tp, tp, %lo(__thread_pointer$)
  159. .option pop
  160. csrw mstatus, zero
  161. csrw mcause, zero
  162. #ifdef __riscv_flen
  163. /* Enable FPU */
  164. li t0, CSR_MSTATUS_FS_MASK
  165. csrrs t0, mstatus, t0
  166. /* Initialize FCSR */
  167. fscsr zero
  168. #endif
  169. #ifdef INIT_EXT_RAM_FOR_DATA
  170. la t0, _stack_safe
  171. mv sp, t0
  172. call _init_ext_ram
  173. #endif
  174. lui t0, %hi(__stack_end__)
  175. addi sp, t0, %lo(__stack_end__)
  176. #ifndef __NO_SYSTEM_INIT
  177. //
  178. // Call _init
  179. //
  180. call _init
  181. #endif
  182. //
  183. // Call linker init functions which in turn performs the following:
  184. // * Perform segment init
  185. // * Perform heap init (if used)
  186. // * Call constructors of global Objects (if any exist)
  187. //
  188. la s0, __SEGGER_init_table__ // Set table pointer to start of initialization table
  189. L(RunInit):
  190. lw a0, (s0) // Get next initialization function from table
  191. add s0, s0, 4 // Increment table pointer to point to function arguments
  192. jalr a0 // Call initialization function
  193. j L(RunInit)
  194. //
  195. MARK_FUNC __SEGGER_init_done
  196. //
  197. // Time to call main(), the application entry point.
  198. //
  199. #ifndef NO_CLEANUP_AT_START
  200. /* clean up */
  201. call _clean_up
  202. #endif
  203. #if defined(CONFIG_FREERTOS) && CONFIG_FREERTOS
  204. #define HANDLER_TRAP freertos_risc_v_trap_handler
  205. #define HANDLER_S_TRAP freertos_risc_v_trap_handler
  206. /* Use mscratch to store isr level */
  207. csrw mscratch, 0
  208. #elif defined(CONFIG_UCOS_III) && CONFIG_UCOS_III
  209. #define HANDLER_TRAP ucos_risc_v_trap_handler
  210. #define HANDLER_S_TRAP ucos_risc_v_trap_handler
  211. /* Use mscratch to store isr level */
  212. csrw mscratch, 0
  213. #elif defined(CONFIG_THREADX) && CONFIG_THREADX
  214. #define HANDLER_TRAP tx_risc_v_trap_handler
  215. #define HANDLER_S_TRAP tx_risc_v_trap_handler
  216. /* Use mscratch to store isr level */
  217. csrw mscratch, 0
  218. #else
  219. #define HANDLER_TRAP irq_handler_trap
  220. #define HANDLER_S_TRAP irq_handler_s_trap
  221. #endif
  222. #ifndef USE_NONVECTOR_MODE
  223. /* Initial machine trap-vector Base */
  224. la t0, __vector_table
  225. csrw mtvec, t0
  226. /* Enable vectored external PLIC interrupt */
  227. csrsi CSR_MMISC_CTL, 2
  228. #else
  229. /* Initial machine trap-vector Base */
  230. la t0, HANDLER_TRAP
  231. csrw mtvec, t0
  232. /* Disable vectored external PLIC interrupt */
  233. csrci CSR_MMISC_CTL, 2
  234. #endif
  235. MARK_FUNC start
  236. #ifndef FULL_LIBRARY
  237. //
  238. // In a real embedded application ("Free-standing environment"),
  239. // main() does not get any arguments,
  240. // which means it is not necessary to init a0 and a1.
  241. //
  242. call APP_ENTRY_POINT
  243. tail exit
  244. END_FUNC _start
  245. //
  246. // end of _start
  247. // Fall-through to exit if main ever returns.
  248. //
  249. MARK_FUNC exit
  250. //
  251. // In a free-standing environment, if returned from application:
  252. // Loop forever.
  253. //
  254. j .
  255. .size exit,.-exit
  256. #else
  257. //
  258. // In a hosted environment,
  259. // we need to load a0 and a1 with argc and argv, in order to handle
  260. // the command line arguments.
  261. // This is required for some programs running under control of a
  262. // debugger, such as automated tests.
  263. //
  264. li a0, ARGSSPACE
  265. la a1, args
  266. call debug_getargs
  267. li a0, ARGSSPACE
  268. la a1, args
  269. call APP_ENTRY_POINT // Call to application entry point (usually main())
  270. call exit // Call exit function
  271. j . // If we unexpectedly return from exit, hang.
  272. END_FUNC _start
  273. #endif
  274. #ifdef FULL_LIBRARY
  275. li a0, ARGSSPACE
  276. la a1, args
  277. call debug_getargs
  278. li a0, ARGSSPACE
  279. la a1, args
  280. #else
  281. li a0, 0
  282. li a1, 0
  283. #endif
  284. call APP_ENTRY_POINT
  285. tail exit
  286. END_FUNC _start
  287. //
  288. #ifdef FULL_LIBRARY
  289. /*********************************************************************
  290. *
  291. * exit
  292. *
  293. * Function description
  294. * Exit of the system.
  295. * Called on return from application entry point or explicit call
  296. * to exit.
  297. *
  298. * Additional information
  299. * In a hosted environment exit gracefully, by
  300. * saving the return value,
  301. * calling destructurs of global objects,
  302. * calling registered atexit functions,
  303. * and notifying the host/debugger.
  304. */
  305. #undef L
  306. #define L(label) .L_exit_##label
  307. WEAK_FUNC exit
  308. mv s1, a0 // Save the exit parameter/return result
  309. //
  310. // Call destructors
  311. //
  312. la s0, __dtors_start__
  313. L(Loop):
  314. la t0, __dtors_end__
  315. beq s0, t0, L(End)
  316. lw t1, 0(s0)
  317. addi s0, s0, 4
  318. jalr t1
  319. j L(Loop)
  320. L(End):
  321. //
  322. // Call atexit functions
  323. //
  324. call _execute_at_exit_fns
  325. //
  326. // Call debug_exit with return result/exit parameter
  327. //
  328. mv a0, s1
  329. call debug_exit
  330. //
  331. // If execution is not terminated, loop forever
  332. //
  333. L(ExitLoop):
  334. j L(ExitLoop) // Loop forever.
  335. END_FUNC exit
  336. #endif
  337. #ifdef FULL_LIBRARY
  338. .bss
  339. args:
  340. .space ARGSSPACE
  341. .size args, .-args
  342. .type args, %object
  343. #endif
  344. .section .isr_vector, "ax"
  345. .weak nmi_handler
  346. nmi_handler:
  347. 1: j 1b
  348. #include "../vectors.h"
  349. /*************************** End of file ****************************/