startup_evalsoc.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. * Copyright (c) 2023 Nuclei Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. /******************************************************************************
  19. * \file startup_evalsoc.c
  20. * \brief NMSIS Nuclei N/NX Class Core based Core Device Startup File for
  21. * Nuclei Eval SoC which support Nuclei N/NX class cores using IAR compiler
  22. * \version V1.0.0
  23. * \date 19 Dec 2023
  24. *
  25. ******************************************************************************/
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include "evalsoc.h"
  29. extern __weak void eclic_msip_handler(void);
  30. extern __weak void eclic_mtip_handler(void);
  31. extern void default_intexc_handler(void);
  32. /*
  33. * TODO: Uncomment it if your vector table is placed in readonly section,
  34. * and you have defined .mintvec_rw section in a writable section in iar
  35. * linker icf file
  36. * In this implementation, when use with iar_evalsoc_flashxip.icf, you can
  37. * try this FLASH_RAM_VECTOR
  38. */
  39. // #define FLASH_RAM_VECTOR 1
  40. typedef void(*__fp)(void);
  41. /* If .mintvec section is placed in real readonly section,
  42. * if you want to register vector interrupt with new entry,
  43. * you need to place it in writable section or create a ram vector
  44. * after bootup.
  45. * TODO: This data_alignment is set to 512(rv32) or 1024(rv64) byte for up to 128 interrupts,
  46. * If you have more interrupts, you need to adjust the data_alignment
  47. * to other value, for details, please check mtvt csr documented
  48. * in Nuclei RISC-V ISA Spec
  49. */
  50. // TODO: change the data_alignment = 1024 to match mtvt alignment requirement according to your eclic max interrupt number
  51. // TODO: place your interrupt handler into this vector table, important if your vector table is in flash
  52. #pragma data_alignment = 1024
  53. const __fp vector_base[SOC_INT_MAX] __attribute__((section (".mintvec"))) = {
  54. default_intexc_handler,
  55. default_intexc_handler,
  56. default_intexc_handler,
  57. eclic_msip_handler,
  58. default_intexc_handler,
  59. default_intexc_handler,
  60. default_intexc_handler,
  61. eclic_mtip_handler,
  62. default_intexc_handler,
  63. default_intexc_handler,
  64. default_intexc_handler,
  65. default_intexc_handler,
  66. default_intexc_handler,
  67. default_intexc_handler,
  68. default_intexc_handler,
  69. default_intexc_handler,
  70. default_intexc_handler,
  71. default_intexc_handler
  72. /* TODO other external interrupt handler don't provide default value, if you want to provide default value, please do it by yourself */
  73. };
  74. #if defined(FLASH_RAM_VECTOR)
  75. // TODO: change the data_alignment = 1024 to match mtvt alignment requirement according to your eclic max interrupt number
  76. #pragma data_alignment = 1024
  77. static __fp vector_base_ram[SOC_INT_MAX] __attribute__((section (".mintvec_rw")));
  78. #if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1)
  79. // TODO: change the data_alignment = 1024 to match stvt alignment requirement according to your eclic max interrupt number
  80. #pragma data_alignment = 1024
  81. static unsigned long vector_base_s_ram[SOC_INT_MAX] __attribute__((section (".sintvec_rw")));
  82. extern const unsigned long vector_table_s[SOC_INT_MAX];
  83. #endif
  84. static void copy_vector_table(void *dst, const void *src, size_t cnt)
  85. {
  86. memcpy((void *)dst, (const void *)src, cnt);
  87. #if (defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1))
  88. #if (defined(__CCM_PRESENT) && (__CCM_PRESENT == 1))
  89. MFlushDCache();
  90. #endif
  91. #endif
  92. #if (defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1))
  93. #if (defined(__CCM_PRESENT) && (__CCM_PRESENT == 1))
  94. MInvalICache();
  95. #else
  96. __FENCE_I();
  97. #endif
  98. #endif
  99. }
  100. static void prepare_ram_vector(void)
  101. {
  102. copy_vector_table((void *)vector_base_ram, (const void *)vector_base, (size_t)(sizeof(__fp) * SOC_INT_MAX));
  103. __RV_CSR_WRITE(CSR_MTVT, (unsigned long)(&vector_base_ram));
  104. #if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1)
  105. copy_vector_table((void *)vector_base_s_ram, (const void *)vector_table_s, (size_t)(sizeof(unsigned long) * SOC_INT_MAX));
  106. __RV_CSR_WRITE(CSR_STVT, (unsigned long)(&vector_base_s_ram));
  107. #endif
  108. }
  109. #endif
  110. extern void exc_entry(void);
  111. extern void irq_entry(void);
  112. extern void _premain_init(void);
  113. extern void early_exc_entry(void);
  114. #ifndef IAR_DATA_INIT
  115. #define IAR_DATA_INIT _GLUE(__iar_data_init, _DLIB_ELF_INIT_INTERFACE_VERSION)
  116. #endif
  117. extern void IAR_DATA_INIT(void);
  118. extern void __sync_harts(void);
  119. extern int main(void);
  120. extern void exit(int arg);
  121. // TODO: for smp you can override this smp_main as your multicore main function entry
  122. __weak int smp_main(void)
  123. {
  124. unsigned long hartid = __get_hart_id();
  125. int ret = 0;
  126. if (hartid == BOOT_HARTID) {
  127. #ifdef RTOS_RTTHREAD
  128. /* Directly jump to rtthread startup process, no longer return */
  129. extern int rtthread_startup(void);
  130. rtthread_startup();
  131. #else
  132. ret = main();
  133. exit(ret);
  134. while(1);
  135. #endif
  136. } else {
  137. while(1) {
  138. __WFI();
  139. }
  140. }
  141. return 0;
  142. }
  143. // NOTE: __lower_level_init will directly call main or smp_main and not return
  144. int __low_level_init(void)
  145. {
  146. unsigned long hartid = __get_hart_id();
  147. __disable_interrupt();
  148. /* Set the the NMI base to share with mtvec by setting CSR_MMISC_CTL */
  149. __RV_CSR_SET(CSR_MMISC_CTL, MMISC_CTL_NMI_CAUSE_FFF);
  150. #if defined(__riscv_zcmp) || defined(__riscv_zcmt)
  151. /* Enable Zc feature when compiled zcmp & zcmt */
  152. __RV_CSR_SET(CSR_MMISC_CTL, MMISC_CTL_ZC);
  153. #endif
  154. /* Enable FPU and Vector Unit if f/d/v exist in march */
  155. #if defined(__riscv_flen) && __riscv_flen > 0
  156. /* Enable FPU, and set state to initial */
  157. __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_FS);
  158. __RV_CSR_SET(CSR_MSTATUS, MSTATUS_FS_INITIAL);
  159. #endif
  160. #if defined(__riscv_vector)
  161. /* Enable Vector, and set state to initial */
  162. __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_VS);
  163. __RV_CSR_SET(CSR_MSTATUS, MSTATUS_VS_INITIAL);
  164. #endif
  165. /* Enable mcycle and minstret counter */
  166. __RV_CSR_CLEAR(CSR_MCOUNTINHIBIT, 0x5);
  167. /* Call IAR Internal data initial function for only boot hart */
  168. if (hartid == BOOT_HARTID) {
  169. IAR_DATA_INIT();
  170. }
  171. /* Enable BPU before enter to main, for 900, by default is off */
  172. __RV_CSR_SET(CSR_MMISC_CTL, MMISC_CTL_BPU);
  173. /* Sync multiple harts */
  174. __sync_harts();
  175. /*
  176. * You can place it before calling IAR_DATA_INIT
  177. * if in this SystemInit function use no global variable.
  178. * Call vendor defined SystemInit to
  179. * initialize the micro-controller system
  180. * SystemInit will just be called by boot cpu
  181. */
  182. SystemInit();
  183. /* Get CPU frequency and initialize uart for print */
  184. _premain_init();
  185. /* Prepare ram vector table for initial vector table located in readonly section case */
  186. #if defined(FLASH_RAM_VECTOR) && (defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1))
  187. prepare_ram_vector();
  188. #endif
  189. smp_main();
  190. /* No need to call it again, since it is initialized */
  191. return 0;
  192. }