startup.s 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  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. #if !defined(USE_NONVECTOR_MODE)
  223. /* Initial machine trap-vector Base */
  224. la t0, __vector_table
  225. csrw mtvec, t0
  226. #if defined (USE_S_MODE_IRQ)
  227. la t0, __vector_s_table
  228. csrw stvec, t0
  229. #endif
  230. /* Enable vectored external PLIC interrupt */
  231. csrsi CSR_MMISC_CTL, 2
  232. #else
  233. /* Initial machine trap-vector Base */
  234. la t0, HANDLER_TRAP
  235. csrw mtvec, t0
  236. #if defined (USE_S_MODE_IRQ)
  237. la t0, HANDLER_S_TRAP
  238. csrw stvec, t0
  239. #endif
  240. /* Disable vectored external PLIC interrupt */
  241. csrci CSR_MMISC_CTL, 2
  242. #endif
  243. MARK_FUNC start
  244. #ifndef FULL_LIBRARY
  245. //
  246. // In a real embedded application ("Free-standing environment"),
  247. // main() does not get any arguments,
  248. // which means it is not necessary to init a0 and a1.
  249. //
  250. call APP_ENTRY_POINT
  251. tail exit
  252. END_FUNC _start
  253. //
  254. // end of _start
  255. // Fall-through to exit if main ever returns.
  256. //
  257. MARK_FUNC exit
  258. //
  259. // In a free-standing environment, if returned from application:
  260. // Loop forever.
  261. //
  262. j .
  263. .size exit,.-exit
  264. #else
  265. //
  266. // In a hosted environment,
  267. // we need to load a0 and a1 with argc and argv, in order to handle
  268. // the command line arguments.
  269. // This is required for some programs running under control of a
  270. // debugger, such as automated tests.
  271. //
  272. li a0, ARGSSPACE
  273. la a1, args
  274. call debug_getargs
  275. li a0, ARGSSPACE
  276. la a1, args
  277. call APP_ENTRY_POINT // Call to application entry point (usually main())
  278. call exit // Call exit function
  279. j . // If we unexpectedly return from exit, hang.
  280. END_FUNC _start
  281. #endif
  282. #ifdef FULL_LIBRARY
  283. li a0, ARGSSPACE
  284. la a1, args
  285. call debug_getargs
  286. li a0, ARGSSPACE
  287. la a1, args
  288. #else
  289. li a0, 0
  290. li a1, 0
  291. #endif
  292. call APP_ENTRY_POINT
  293. tail exit
  294. END_FUNC _start
  295. //
  296. #ifdef FULL_LIBRARY
  297. /*********************************************************************
  298. *
  299. * exit
  300. *
  301. * Function description
  302. * Exit of the system.
  303. * Called on return from application entry point or explicit call
  304. * to exit.
  305. *
  306. * Additional information
  307. * In a hosted environment exit gracefully, by
  308. * saving the return value,
  309. * calling destructurs of global objects,
  310. * calling registered atexit functions,
  311. * and notifying the host/debugger.
  312. */
  313. #undef L
  314. #define L(label) .L_exit_##label
  315. WEAK_FUNC exit
  316. mv s1, a0 // Save the exit parameter/return result
  317. //
  318. // Call destructors
  319. //
  320. la s0, __dtors_start__
  321. L(Loop):
  322. la t0, __dtors_end__
  323. beq s0, t0, L(End)
  324. lw t1, 0(s0)
  325. addi s0, s0, 4
  326. jalr t1
  327. j L(Loop)
  328. L(End):
  329. //
  330. // Call atexit functions
  331. //
  332. call _execute_at_exit_fns
  333. //
  334. // Call debug_exit with return result/exit parameter
  335. //
  336. mv a0, s1
  337. call debug_exit
  338. //
  339. // If execution is not terminated, loop forever
  340. //
  341. L(ExitLoop):
  342. j L(ExitLoop) // Loop forever.
  343. END_FUNC exit
  344. #endif
  345. #ifdef FULL_LIBRARY
  346. .bss
  347. args:
  348. .space ARGSSPACE
  349. .size args, .-args
  350. .type args, %object
  351. #endif
  352. .section .isr_vector, "ax"
  353. .weak nmi_handler
  354. nmi_handler:
  355. 1: j 1b
  356. #include "../vectors.h"
  357. /*************************** End of file ****************************/