crt0.S 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. /******************************************************************************
  2. * *
  3. * License Agreement *
  4. * *
  5. * Copyright (c) 2006 Altera Corporation, San Jose, California, USA. *
  6. * All rights reserved. *
  7. * *
  8. * Permission is hereby granted, free of charge, to any person obtaining a *
  9. * copy of this software and associated documentation files (the "Software"), *
  10. * to deal in the Software without restriction, including without limitation *
  11. * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
  12. * and/or sell copies of the Software, and to permit persons to whom the *
  13. * Software is furnished to do so, subject to the following conditions: *
  14. * *
  15. * The above copyright notice and this permission notice shall be included in *
  16. * all copies or substantial portions of the Software. *
  17. * *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
  23. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
  24. * DEALINGS IN THE SOFTWARE. *
  25. * *
  26. * This agreement shall be governed in all respects by the laws of the State *
  27. * of California and by the laws of the United States of America. *
  28. * *
  29. ******************************************************************************/
  30. #include "system.h"
  31. #include "nios2.h"
  32. /* Setup header files to work with assembler code. */
  33. #define ALT_ASM_SRC
  34. /* Debug logging facility */
  35. #include "sys/alt_log_printf.h"
  36. /*************************************************************************\
  37. | MACROS |
  38. \*************************************************************************/
  39. /*
  40. * The new build tools explicitly define macros when alt_load()
  41. * must be called. The define ALT_LOAD_EXPLICITLY_CONTROLLED tells us that
  42. * those macros are controlling if alt_load() needs to be called.
  43. */
  44. #ifdef ALT_LOAD_EXPLICITLY_CONTROLLED
  45. /* Need to call alt_load() if any of these sections are being copied. */
  46. #if defined(ALT_LOAD_COPY_RODATA) || defined(ALT_LOAD_COPY_RWDATA) || defined(ALT_LOAD_COPY_EXCEPTIONS)
  47. #define CALL_ALT_LOAD
  48. #endif
  49. #else /* !ALT_LOAD_EXPLICITLY_CONTROLLED */
  50. /*
  51. * The legacy build tools use the following macros to detect when alt_load()
  52. * needs to be called.
  53. */
  54. #define __ALT_LOAD_SECTIONS(res, text, rodata, exc) \
  55. ((res##_BASE != rodata##_BASE) || \
  56. (res##_BASE != rwdata##_BASE) || \
  57. (res##_BASE != exc##_BASE))
  58. #define _ALT_LOAD_SECTIONS(res, text, rodata, exc) \
  59. __ALT_LOAD_SECTIONS(res, text, rodata, exc)
  60. #define ALT_LOAD_SECTIONS _ALT_LOAD_SECTIONS(ALT_RESET_DEVICE, \
  61. ALT_RODATA_DEVICE, \
  62. ALT_RWDATA_DEVICE, \
  63. ALT_EXCEPTIONS_DEVICE)
  64. /* Call alt_load() if there is no bootloader and ALT_LOAD_SECTIONS isn't 0. */
  65. #if defined(ALT_NO_BOOTLOADER) && ALT_LOAD_SECTIONS
  66. #define CALL_ALT_LOAD
  67. #endif
  68. #endif /* !ALT_LOAD_EXPLICITLY_CONTROLLED */
  69. /*
  70. * When the legacy build tools define a macro called ALT_NO_BOOTLOADER,
  71. * it indicates that initialization code is allowed at the reset address.
  72. * The new build tools define a macro called ALT_ALLOW_CODE_AT_RESET for
  73. * the same purpose.
  74. */
  75. #ifdef ALT_NO_BOOTLOADER
  76. #define ALT_ALLOW_CODE_AT_RESET
  77. #endif
  78. /*************************************************************************\
  79. | EXTERNAL REFERENCES |
  80. \*************************************************************************/
  81. /*
  82. * The entry point for user code is either "main" in hosted mode, or
  83. * "alt_main" in standalone mode. These are explicitly referenced here,
  84. * to ensure they are built into the executable. This allows the user
  85. * to build them into libraries, rather than supplying them in object
  86. * files at link time.
  87. */
  88. .globl main
  89. .globl alt_main
  90. /*
  91. * Create a reference to the software multiply/divide and trap handers,
  92. * so that if they are provided, they will appear in the executable.
  93. */
  94. #ifndef ALT_NO_INSTRUCTION_EMULATION
  95. .globl alt_exception_muldiv
  96. #endif
  97. #ifdef ALT_TRAP_HANDLER
  98. .globl alt_exception_trap
  99. #endif
  100. /*
  101. * Linker defined symbols used to initialize bss.
  102. */
  103. .globl __bss_start
  104. .globl __bss_end
  105. /*************************************************************************\
  106. | RESET SECTION (.entry) |
  107. \*************************************************************************/
  108. /*
  109. * This is the reset entry point for Nios II.
  110. *
  111. * At reset, only the cache line which contain the reset vector is
  112. * initialized by the hardware. The code within the first cache line
  113. * initializes the remainder of the instruction cache.
  114. */
  115. .section .entry, "xa"
  116. .align 5
  117. /*
  118. * Explicitly allow the use of r1 (the assembler temporary register)
  119. * within this code. This register is normally reserved for the use of
  120. * the assembler.
  121. */
  122. .set noat
  123. /*
  124. * Some tools want to know where the reset vector is.
  125. * Code isn't always provided at the reset vector but at least the
  126. * __reset label always contains the reset vector address because
  127. * it is defined at the start of the .entry section.
  128. */
  129. .globl __reset
  130. .type __reset, @function
  131. __reset:
  132. /*
  133. * Initialize the instruction cache if present (i.e. size > 0) and
  134. * reset code is allowed unless optimizing for RTL simulation.
  135. * RTL simulations can ensure the instruction cache is already initialized
  136. * so skipping this loop speeds up RTL simulation.
  137. *
  138. * When ECC is present, need to execute initi for each word address
  139. * to ensure ECC parity bits in cache RAM get initialized.
  140. */
  141. #if NIOS2_ICACHE_SIZE > 0 && defined(ALT_ALLOW_CODE_AT_RESET) && (!defined(ALT_SIM_OPTIMIZE) || defined(NIOS2_ECC_PRESENT))
  142. /* Assume the instruction cache size is always a power of two. */
  143. #if NIOS2_ICACHE_SIZE > 0x8000
  144. movhi r2, %hi(NIOS2_ICACHE_SIZE)
  145. #else
  146. movui r2, NIOS2_ICACHE_SIZE
  147. #endif
  148. 0:
  149. initi r2
  150. addi r2, r2, -NIOS2_ICACHE_LINE_SIZE
  151. bgt r2, zero, 0b
  152. 1:
  153. /*
  154. * The following debug information tells the ISS not to run the loop above
  155. * but to perform its actions using faster internal code.
  156. */
  157. .pushsection .debug_alt_sim_info
  158. .int 1, 1, 0b, 1b
  159. .popsection
  160. #endif /* Initialize Instruction Cache */
  161. /*
  162. * Jump to the _start entry point in the .text section if reset code
  163. * is allowed or if optimizing for RTL simulation.
  164. */
  165. #if defined(ALT_ALLOW_CODE_AT_RESET) || defined(ALT_SIM_OPTIMIZE)
  166. /* Jump to the _start entry point in the .text section. */
  167. movhi r1, %hi(_start)
  168. ori r1, r1, %lo(_start)
  169. jmp r1
  170. .size __reset, . - __reset
  171. #endif /* Jump to _start */
  172. /*
  173. * When not using exit, provide an _exit symbol to prevent unresolved
  174. * references to _exit from the linker script.
  175. */
  176. #ifdef ALT_NO_EXIT
  177. .globl _exit
  178. _exit:
  179. #endif
  180. /*************************************************************************\
  181. | TEXT SECTION (.text) |
  182. \*************************************************************************/
  183. /*
  184. * Start of the .text section, and also the code entry point when
  185. * the code is executed by a bootloader rather than directly from reset.
  186. */
  187. .section .text
  188. .align 2
  189. .globl _start
  190. .type _start, @function
  191. _start:
  192. #if (NIOS2_NUM_OF_SHADOW_REG_SETS > 0)
  193. /*
  194. * Ensure that the current register set is 0 upon
  195. * entry to this code. Switch register set to 0 by
  196. * writing zero to SSTATUS register and executing an ERET instruction
  197. * to set STATUS.CRS to 0.
  198. */
  199. /* Get the current register set number (STATUS.CRS). */
  200. rdctl r2, status
  201. andi r2, r2, NIOS2_STATUS_CRS_MSK
  202. /* Skip switching register set if STATUS.CRS is 0. */
  203. beq r2, zero, 0f
  204. /* Set SSTATUS to 0 to get to set SSTATUS.PRS to 0. */
  205. .set nobreak
  206. movui sstatus, 0
  207. .set break
  208. /* Switch to register set 0 and jump to label. */
  209. movhi ea, %hi(0f)
  210. ori ea, ea, %lo(0f)
  211. eret
  212. 0:
  213. #endif /* NIOS2_NUM_OF_SHADOW_REG_SETS > 0 */
  214. /*
  215. * Initialize the data cache if present (i.e. size > 0).
  216. * Skip initialization if optimizing for RTL simulation and ECC isn't present.
  217. * RTL simulations can ensure the data cache tag RAM is already initialized
  218. * (but not the data RAM for ECC) so skipping this speeds up RTL simulation.
  219. *
  220. * When ECC is present, need to execute initd for each word address
  221. * to ensure ECC parity bits in data RAM get initialized.
  222. * Otherwise, only need to execute initd for each line address.
  223. */
  224. #if NIOS2_DCACHE_SIZE > 0 && (!defined(ALT_SIM_OPTIMIZE) || defined(NIOS2_ECC_PRESENT))
  225. /* Assume the data cache size is always a power of two. */
  226. #if NIOS2_DCACHE_SIZE > 0x8000
  227. movhi r2, %hi(NIOS2_DCACHE_SIZE)
  228. #else
  229. movui r2, NIOS2_DCACHE_SIZE
  230. #endif
  231. 0:
  232. initd 0(r2)
  233. #ifdef NIOS2_ECC_PRESENT
  234. addi r2, r2, -4
  235. #else
  236. addi r2, r2, -NIOS2_DCACHE_LINE_SIZE
  237. #endif
  238. bgt r2, zero, 0b
  239. 1:
  240. /*
  241. * The following debug information tells the ISS not to run the loop above
  242. * but to perform its actions using faster internal code.
  243. */
  244. .pushsection .debug_alt_sim_info
  245. .int 2, 1, 0b, 1b
  246. .popsection
  247. #endif /* Initialize Data Cache */
  248. /* Log that caches have been initialized. */
  249. ALT_LOG_PUTS(alt_log_msg_cache)
  250. /* Log that the stack pointer is about to be setup. */
  251. ALT_LOG_PUTS(alt_log_msg_stackpointer)
  252. /*
  253. * Now that the caches are initialized, set up the stack pointer and global pointer.
  254. * The values provided by the linker are assumed to be correctly aligned.
  255. */
  256. movhi sp, %hi(__alt_stack_pointer)
  257. ori sp, sp, %lo(__alt_stack_pointer)
  258. movhi gp, %hi(_gp)
  259. ori gp, gp, %lo(_gp)
  260. #ifdef NIOS2_ECC_PRESENT
  261. /*
  262. * Initialize all general-purpose registers so that ECC can be enabled
  263. * later without accidentally triggering a spurious ECC error.
  264. */
  265. movui r1, 0
  266. movui r2, 0
  267. movui r3, 0
  268. movui r4, 0
  269. movui r5, 0
  270. movui r6, 0
  271. movui r7, 0
  272. movui r8, 0
  273. movui r9, 0
  274. movui r10, 0
  275. movui r11, 0
  276. movui r12, 0
  277. movui r13, 0
  278. movui r14, 0
  279. movui r15, 0
  280. movui r16, 0
  281. movui r17, 0
  282. movui r18, 0
  283. movui r19, 0
  284. movui r20, 0
  285. movui r21, 0
  286. movui r22, 0
  287. movui r23, 0
  288. /* Skip r24 (et) because only exception handler should write it. */
  289. /* Skip r25 (bt) because only debugger should write it. */
  290. /* Skip r26 (gp) because it is already been initialized. */
  291. /* Skip r27 (sp) because it is already been initialized. */
  292. movui r28, 0 /* fp */
  293. movui r29, 0 /* ea */
  294. .set nobreak
  295. movui r30, 0 /* sstatus */
  296. .set break
  297. movui r31, 0 /* ra */
  298. #endif /* NIOS2_ECC_PRESENT */
  299. #if (NIOS2_NUM_OF_SHADOW_REG_SETS > 0)
  300. /*
  301. * Setup registers in shadow register sets
  302. * from 1 to NIOS2_NUM_OF_SHADOW_REG_SETS.
  303. */
  304. movui r2, 0 /* Contains value written into STATUS */
  305. movui r3, NIOS2_NUM_OF_SHADOW_REG_SETS /* counter */
  306. movhi r4, 1 /* Constant to increment STATUS.PRS */
  307. .Linitialize_shadow_registers:
  308. /* Increment STATUS.PRS */
  309. add r2, r2, r4
  310. wrctl status, r2
  311. /* Clear r0 in the shadow register set (not done by hardware) */
  312. wrprs r0, r0
  313. /* Write the GP in previous register set */
  314. wrprs gp, gp
  315. /*
  316. * Only write the SP in previous register set
  317. * if using the separate exception stack. For normal case (single stack),
  318. * funnel code would read the SP from previous register set with a RDPRS.
  319. */
  320. #ifdef ALT_INTERRUPT_STACK
  321. movhi et, %hiadj(__alt_interrupt_stack_pointer)
  322. addi et, et, %lo(__alt_interrupt_stack_pointer)
  323. wrprs sp, et
  324. #endif /* ALT_INTERRUPT_STACK */
  325. #ifdef NIOS2_ECC_PRESENT
  326. /*
  327. * Initialize all general-purpose registers so that ECC can be enabled
  328. * later without accidentally triggering a spurious ECC error.
  329. */
  330. wrprs r1, r0
  331. wrprs r2, r0
  332. wrprs r3, r0
  333. wrprs r4, r0
  334. wrprs r5, r0
  335. wrprs r6, r0
  336. wrprs r7, r0
  337. wrprs r8, r0
  338. wrprs r9, r0
  339. wrprs r10, r0
  340. wrprs r11, r0
  341. wrprs r12, r0
  342. wrprs r13, r0
  343. wrprs r14, r0
  344. wrprs r15, r0
  345. wrprs r16, r0
  346. wrprs r17, r0
  347. wrprs r18, r0
  348. wrprs r19, r0
  349. wrprs r20, r0
  350. wrprs r21, r0
  351. wrprs r22, r0
  352. wrprs r23, r0
  353. /* Skip r24 (et) because only exception handler should write it. */
  354. /* Skip r25 (bt) because only debugger should write it. */
  355. /* Skip r26 (gp) because it is already been initialized. */
  356. /* Skip r27 (sp) because it was initialized above or will be by a rdprs if not above */
  357. wrprs r28, r0 /* fp */
  358. wrprs r29, r0 /* ea */
  359. wrprs r30, r0 /* ba */
  360. wrprs r31, r0 /* ra */
  361. #endif /* NIOS2_ECC_PRESENT */
  362. /* Decrement shadow register set counter */
  363. addi r3, r3, -1
  364. /* Done if index is 0. */
  365. bne r3, zero, .Linitialize_shadow_registers
  366. #endif /* (NIOS2_NUM_OF_SHADOW_REG_SETS > 0) */
  367. /*
  368. * Clear the BSS if not optimizing for RTL simulation.
  369. *
  370. * This uses the symbols: __bss_start and __bss_end, which are defined
  371. * by the linker script. They mark the begining and the end of the bss
  372. * region. The linker script guarantees that these values are word aligned.
  373. */
  374. #ifndef ALT_SIM_OPTIMIZE
  375. /* Log that the BSS is about to be cleared. */
  376. ALT_LOG_PUTS(alt_log_msg_bss)
  377. movhi r2, %hi(__bss_start)
  378. ori r2, r2, %lo(__bss_start)
  379. movhi r3, %hi(__bss_end)
  380. ori r3, r3, %lo(__bss_end)
  381. beq r2, r3, 1f
  382. 0:
  383. stw zero, (r2)
  384. addi r2, r2, 4
  385. bltu r2, r3, 0b
  386. 1:
  387. /*
  388. * The following debug information tells the ISS not to run the loop above
  389. * but to perform its actions using faster internal code.
  390. */
  391. .pushsection .debug_alt_sim_info
  392. .int 3, 1, 0b, 1b
  393. .popsection
  394. #endif /* ALT_SIM_OPTIMIZE */
  395. /*
  396. * Turn off the use of r1 (the assembler temporary register)
  397. * so that call instructions can be safely relaxed across a
  398. * 256MB boundary if needed
  399. */
  400. .set at
  401. /*
  402. * The alt_load() facility is normally used when there is no bootloader.
  403. * It copies some sections into RAM so it acts like a mini-bootloader.
  404. */
  405. #ifdef CALL_ALT_LOAD
  406. #ifdef ALT_STACK_CHECK
  407. /*
  408. * If the user has selected stack checking then we need to set up a safe
  409. * value in the stack limit register so that the relocation functions
  410. * don't think the stack has overflowed (the contents of the rwdata
  411. * section aren't defined until alt_load() has been called).
  412. */
  413. mov et, zero
  414. #endif
  415. call alt_load
  416. #endif /* CALL_ALT_LOAD */
  417. #ifdef ALT_STACK_CHECK
  418. /*
  419. * Set up the stack limit (if required). The linker has set up the
  420. * copy of the variable which is in memory.
  421. */
  422. ldw et, %gprel(alt_stack_limit_value)(gp)
  423. #endif
  424. /* Log that alt_main is about to be called. */
  425. ALT_LOG_PUTS(alt_log_msg_alt_main)
  426. /* Call the C entry point. It should never return. */
  427. call alt_main
  428. /* Wait in infinite loop in case alt_main does return. */
  429. alt_after_alt_main:
  430. br alt_after_alt_main
  431. .size _start, . - _start
  432. /*
  433. * Add information about the stack base if stack overflow checking is enabled.
  434. */
  435. #ifdef ALT_STACK_CHECK
  436. .globl alt_stack_limit_value
  437. .section .sdata,"aws",@progbits
  438. .align 2
  439. .type alt_stack_limit_value, @object
  440. .size alt_stack_limit_value, 4
  441. alt_stack_limit_value:
  442. .long __alt_stack_limit
  443. #endif