31 /*----------------------------------------------------------------------------
33 *----------------------------------------------------------------------------*/
34 /* ToDo: add here your necessary defines for device initialization
35 following is an example for different system frequencies */
37 #define SYSTEM_CLOCK (80000000UL)
72 #if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1)
74 typedef void (*fnptr)(void);
76 /* for the following variables, see intexc_evalsoc.S and intexc_evalsoc_s.S */
78 extern fnptr irq_entry_s;
80 extern fnptr exc_entry_s;
82 extern void default_intexc_handler(void);
85 extern void eclic_ssip_handler(void) __WEAK;
87 extern void eclic_stip_handler(void) __WEAK;
89 /* default s-mode exception handler, which user can modify it at your need */
90 static void system_default_exception_handler_s(unsigned long scause, unsigned long sp);
93 #define __SMODE_VECTOR_ATTR __attribute__((section (".text.vtable_s
"), aligned(512)))
95 #define __SMODE_VECTOR_ATTR __attribute__((section (".sintvec
"), aligned(512)))
97 // TODO: change the aligned(512) to match stvt alignment requirement according to your eclic max interrupt number
98 // TODO: place your interrupt handler into this vector table, important if your vector table is in flash
115 const unsigned long vector_table_s[SOC_INT_MAX] __SMODE_VECTOR_ATTR =
117 (unsigned long)(default_intexc_handler), /* 0: Reserved */
118 (unsigned long)(default_intexc_handler), /* 1: Reserved */
119 (unsigned long)(default_intexc_handler), /* 2: Reserved */
121 (unsigned long)(eclic_ssip_handler), /* 3: supervisor software interrupt in eclic mode */
123 (unsigned long)(default_intexc_handler), /* 4: Reserved */
124 (unsigned long)(default_intexc_handler), /* 5: Reserved */
125 (unsigned long)(default_intexc_handler), /* 6: Reserved */
127 (unsigned long)(eclic_stip_handler), /* 7: supervisor timer interrupt in eclic mode */
129 (unsigned long)(default_intexc_handler), /* 8: Reserved */
130 (unsigned long)(default_intexc_handler), /* 9: Reserved */
131 (unsigned long)(default_intexc_handler), /* 10: Reserved */
132 (unsigned long)(default_intexc_handler), /* 11: Reserved */
134 (unsigned long)(default_intexc_handler), /* 12: Reserved */
135 (unsigned long)(default_intexc_handler), /* 13: Reserved */
136 (unsigned long)(default_intexc_handler), /* 14: Reserved */
137 (unsigned long)(default_intexc_handler), /* 15: Reserved */
139 (unsigned long)(default_intexc_handler), /* 16: Reserved */
140 (unsigned long)(default_intexc_handler), /* 17: Reserved */
141 (unsigned long)(default_intexc_handler), /* 18: Reserved */
142 (unsigned long)(default_intexc_handler), /* 19: Interrupt 19 */
144 (unsigned long)(default_intexc_handler), /* 20: Interrupt 20 */
145 (unsigned long)(default_intexc_handler), /* 21: Interrupt 21 */
146 (unsigned long)(default_intexc_handler), /* 22: Interrupt 22 */
147 (unsigned long)(default_intexc_handler), /* 23: Interrupt 23 */
149 (unsigned long)(default_intexc_handler), /* 24: Interrupt 24 */
150 (unsigned long)(default_intexc_handler), /* 25: Interrupt 25 */
151 (unsigned long)(default_intexc_handler), /* 26: Interrupt 26 */
152 (unsigned long)(default_intexc_handler), /* 27: Interrupt 27 */
154 (unsigned long)(default_intexc_handler), /* 28: Interrupt 28 */
155 (unsigned long)(default_intexc_handler), /* 29: Interrupt 29 */
156 (unsigned long)(default_intexc_handler), /* 30: Interrupt 30 */
157 (unsigned long)(default_intexc_handler), /* 31: Interrupt 31 */
159 (unsigned long)(default_intexc_handler), /* 32: Interrupt 32 */
160 (unsigned long)(default_intexc_handler), /* 33: Interrupt 33 */
161 (unsigned long)(default_intexc_handler), /* 34: Interrupt 34 */
162 (unsigned long)(default_intexc_handler), /* 35: Interrupt 35 */
164 (unsigned long)(default_intexc_handler), /* 36: Interrupt 36 */
165 (unsigned long)(default_intexc_handler), /* 37: Interrupt 37 */
166 (unsigned long)(default_intexc_handler), /* 38: Interrupt 38 */
167 (unsigned long)(default_intexc_handler), /* 39: Interrupt 39 */
169 (unsigned long)(default_intexc_handler), /* 40: Interrupt 40 */
170 (unsigned long)(default_intexc_handler), /* 41: Interrupt 41 */
171 (unsigned long)(default_intexc_handler), /* 42: Interrupt 42 */
172 (unsigned long)(default_intexc_handler), /* 43: Interrupt 43 */
174 (unsigned long)(default_intexc_handler), /* 44: Interrupt 44 */
175 (unsigned long)(default_intexc_handler), /* 45: Interrupt 45 */
176 (unsigned long)(default_intexc_handler), /* 46: Interrupt 46 */
177 (unsigned long)(default_intexc_handler), /* 47: Interrupt 47 */
179 (unsigned long)(default_intexc_handler), /* 48: Interrupt 48 */
180 (unsigned long)(default_intexc_handler), /* 49: Interrupt 49 */
181 (unsigned long)(default_intexc_handler), /* 50: Interrupt 50 */
182 (unsigned long)(default_intexc_handler), /* 51: Interrupt 51 */
184 (unsigned long)(default_intexc_handler), /* 52: Interrupt 52 */
185 (unsigned long)(default_intexc_handler), /* 53: Interrupt 53 */
186 (unsigned long)(default_intexc_handler), /* 54: Interrupt 54 */
187 (unsigned long)(default_intexc_handler), /* 55: Interrupt 55 */
189 (unsigned long)(default_intexc_handler), /* 56: Interrupt 56 */
190 (unsigned long)(default_intexc_handler), /* 57: Interrupt 57 */
191 (unsigned long)(default_intexc_handler), /* 58: Interrupt 58 */
192 (unsigned long)(default_intexc_handler), /* 59: Interrupt 59 */
194 (unsigned long)(default_intexc_handler), /* 60: Interrupt 60 */
195 (unsigned long)(default_intexc_handler), /* 61: Interrupt 61 */
196 (unsigned long)(default_intexc_handler), /* 62: Interrupt 62 */
197 (unsigned long)(default_intexc_handler), /* 63: Interrupt 63 */
200 /*----------------------------------------------------------------------------
201 System Core Clock Variable
202 *----------------------------------------------------------------------------*/
203 /* ToDo: initialize SystemCoreClock with the system core clock frequency value
204 achieved after system intitialization.
205 This means system core clock frequency after call to SystemInit() */
218 volatile uint32_t SystemCoreClock = SYSTEM_CLOCK; /* System Clock Frequency (Core Clock) */
220 /*----------------------------------------------------------------------------
222 *----------------------------------------------------------------------------*/
231 void SystemCoreClockUpdate(void) /* Get Core Clock Frequency */
233 /* ToDo: add code to calculate the system frequency based upon the current
235 * Note: This function can be used to retrieve the system core clock frequeny
236 * after user changed register settings.
238 SystemCoreClock = SYSTEM_CLOCK;
249 void SystemInit(void)
251 /* ToDo: add code to initialize the system
252 * Warn: do not use global variables because this function is called before
253 * reaching pre-main. RW section maybe overwritten afterwards.
255 SystemCoreClock = SYSTEM_CLOCK;
269 #define MAX_SYSTEM_EXCEPTION_NUM 26
278 static unsigned long SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM + 1];
288 #if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1)
289 static unsigned long SystemExceptionHandlers_S[MAX_SYSTEM_EXCEPTION_NUM];
297 typedef void (*EXC_HANDLER)(unsigned long cause, unsigned long sp);
307 static void system_default_exception_handler(unsigned long mcause, unsigned long sp)
309 /* TODO: Uncomment this if you have implement printf function */
310 printf("MCAUSE : 0x%lx\r\n
", mcause);
311 printf("MDCAUSE: 0x%lx\r\n
", __RV_CSR_READ(CSR_MDCAUSE));
312 printf("MEPC : 0x%lx\r\n
", __RV_CSR_READ(CSR_MEPC));
313 printf("MTVAL : 0x%lx\r\n
", __RV_CSR_READ(CSR_MTVAL));
314 printf("HARTID : %u\r\n
", (unsigned int)__get_hart_id());
315 Exception_DumpFrame(sp, PRV_M);
316 #if defined(SIMULATION_MODE)
317 // directly exit if in SIMULATION
318 extern void simulation_exit(int status);
333 static void Exception_Init(void)
335 for (int i = 0; i < MAX_SYSTEM_EXCEPTION_NUM; i++) {
336 SystemExceptionHandlers[i] = (unsigned long)system_default_exception_handler;
337 #if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1)
338 SystemExceptionHandlers_S[i] = (unsigned long)system_default_exception_handler_s;
341 SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM] = (unsigned long)system_default_exception_handler;
351 void Exception_DumpFrame(unsigned long sp, uint8_t mode)
353 EXC_Frame_Type *exc_frame = (EXC_Frame_Type *)sp;
356 printf("ra: 0x%lx, tp: 0x%lx, t0: 0x%lx, t1: 0x%lx, t2: 0x%lx, t3: 0x%lx, t4: 0x%lx, t5: 0x%lx, t6: 0x%lx\n
" \
357 "a0: 0x%lx, a1: 0x%lx, a2: 0x%lx, a3: 0x%lx, a4: 0x%lx, a5: 0x%lx, a6: 0x%lx, a7: 0x%lx\n
" \
358 "cause: 0x%lx, epc: 0x%lx\n
", exc_frame->ra, exc_frame->tp, exc_frame->t0, \
359 exc_frame->t1, exc_frame->t2, exc_frame->t3, exc_frame->t4, exc_frame->t5, exc_frame->t6, \
360 exc_frame->a0, exc_frame->a1, exc_frame->a2, exc_frame->a3, exc_frame->a4, exc_frame->a5, \
361 exc_frame->a6, exc_frame->a7, exc_frame->cause, exc_frame->epc);
363 printf("ra: 0x%lx, tp: 0x%lx, t0: 0x%lx, t1: 0x%lx, t2: 0x%lx\n
" \
364 "a0: 0x%lx, a1: 0x%lx, a2: 0x%lx, a3: 0x%lx, a4: 0x%lx, a5: 0x%lx\n
" \
365 "cause: 0x%lx, epc: 0x%lx\n
", exc_frame->ra, exc_frame->tp, exc_frame->t0, \
366 exc_frame->t1, exc_frame->t2, exc_frame->a0, exc_frame->a1, exc_frame->a2, exc_frame->a3, \
367 exc_frame->a4, exc_frame->a5, exc_frame->cause, exc_frame->epc);
371 /* msubm is exclusive to machine mode */
372 printf("msubm: 0x%lx\n
", exc_frame->msubm);
384 void Exception_Register_EXC(uint32_t EXCn, unsigned long exc_handler)
386 if (EXCn < MAX_SYSTEM_EXCEPTION_NUM) {
387 SystemExceptionHandlers[EXCn] = exc_handler;
388 } else if (EXCn == NMI_EXCn) {
389 SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM] = exc_handler;
401 unsigned long Exception_Get_EXC(uint32_t EXCn)
403 if (EXCn < MAX_SYSTEM_EXCEPTION_NUM) {
404 return SystemExceptionHandlers[EXCn];
405 } else if (EXCn == NMI_EXCn) {
406 return SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM];
425 uint32_t core_exception_handler(unsigned long mcause, unsigned long sp)
427 uint32_t EXCn = (uint32_t)(mcause & 0X00000fff);
428 EXC_HANDLER exc_handler;
430 if (EXCn < MAX_SYSTEM_EXCEPTION_NUM) {
431 exc_handler = (EXC_HANDLER)SystemExceptionHandlers[EXCn];
432 } else if (EXCn == NMI_EXCn) {
433 exc_handler = (EXC_HANDLER)SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM];
435 exc_handler = (EXC_HANDLER)system_default_exception_handler;
437 if (exc_handler != NULL) {
438 exc_handler(mcause, sp);
443 #if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1)
452 static void system_default_exception_handler_s(unsigned long scause, unsigned long sp)
454 /* TODO: Uncomment this if you have implement printf function */
455 printf("SCAUSE : 0x%lx\r\n
", scause);
456 printf("SDCAUSE: 0x%lx\r\n
", __RV_CSR_READ(CSR_SDCAUSE));
457 printf("SEPC : 0x%lx\r\n
", __RV_CSR_READ(CSR_SEPC));
458 printf("STVAL : 0x%lx\r\n
", __RV_CSR_READ(CSR_STVAL));
459 Exception_DumpFrame(sp, PRV_S);
460 #if defined(SIMULATION_MODE)
461 // directly exit if in SIMULATION
462 extern void simulation_exit(int status);
478 void Exception_Register_EXC_S(uint32_t EXCn, unsigned long exc_handler)
480 if (EXCn < MAX_SYSTEM_EXCEPTION_NUM) {
481 SystemExceptionHandlers_S[EXCn] = exc_handler;
492 unsigned long Exception_Get_EXC_S(uint32_t EXCn)
494 if (EXCn < MAX_SYSTEM_EXCEPTION_NUM) {
495 return SystemExceptionHandlers[EXCn];
514 uint32_t core_exception_handler_s(unsigned long scause, unsigned long sp)
516 uint32_t EXCn = (uint32_t)(scause & 0X00000fff);
517 EXC_HANDLER exc_handler;
519 if (EXCn < MAX_SYSTEM_EXCEPTION_NUM) {
520 exc_handler = (EXC_HANDLER)SystemExceptionHandlers_S[EXCn];
522 exc_handler = (EXC_HANDLER)system_default_exception_handler_s;
524 if (exc_handler != NULL) {
525 exc_handler(scause, sp);
530 /* End of Doxygen Group NMSIS_Core_ExceptionAndNMI */
534 void SystemBannerPrint(void)
536 #if defined(NUCLEI_BANNER) && (NUCLEI_BANNER == 1)
537 printf("Nuclei SDK Build Time: %s, %s\r\n
", __DATE__, __TIME__);
538 #ifdef DOWNLOAD_MODE_STRING
539 printf("Download Mode: %s\r\n
", DOWNLOAD_MODE_STRING);
541 printf("CPU Frequency %u Hz\r\n
", (unsigned int)SystemCoreClock);
542 printf("CPU HartID: %u\r\n
", (unsigned int)__get_hart_id());
553 void ECLIC_Init(void)
555 /* Global Configuration about MTH and NLBits.
556 * TODO: Please adapt it according to your system requirement.
557 * This function is called in _init function */
559 ECLIC_SetCfgNlbits(__ECLIC_INTCTLBITS);
561 #if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1)
562 /* Global Configuration about STH */
583 int32_t ECLIC_Register_IRQ(IRQn_Type IRQn, uint8_t shv, ECLIC_TRIGGER_Type trig_mode, uint8_t lvl, uint8_t priority, void* handler)
585 if ((IRQn > SOC_INT_MAX) || (shv > ECLIC_VECTOR_INTERRUPT) \
586 || (trig_mode > ECLIC_NEGTIVE_EDGE_TRIGGER)) {
590 /* set interrupt vector mode */
591 ECLIC_SetShvIRQ(IRQn, shv);
592 /* set interrupt trigger mode and polarity */
593 ECLIC_SetTrigIRQ(IRQn, trig_mode);
594 /* set interrupt level */
595 ECLIC_SetLevelIRQ(IRQn, lvl);
596 /* set interrupt priority */
597 ECLIC_SetPriorityIRQ(IRQn, priority);
598 if (handler != NULL) {
599 /* set interrupt handler entry to vector table */
600 ECLIC_SetVector(IRQn, (rv_csr_t)handler);
602 /* enable interrupt */
603 ECLIC_EnableIRQ(IRQn);
607 #if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1)
624 int32_t ECLIC_Register_IRQ_S(IRQn_Type IRQn, uint8_t shv, ECLIC_TRIGGER_Type trig_mode, uint8_t lvl, uint8_t priority, void* handler)
626 if ((IRQn > SOC_INT_MAX) || (shv > ECLIC_VECTOR_INTERRUPT) \
627 || (trig_mode > ECLIC_NEGTIVE_EDGE_TRIGGER)) {
631 /* set interrupt vector mode */
632 ECLIC_SetShvIRQ_S(IRQn, shv);
633 /* set interrupt trigger mode and polarity */
634 ECLIC_SetTrigIRQ_S(IRQn, trig_mode);
635 /* set interrupt level */
636 ECLIC_SetLevelIRQ_S(IRQn, lvl);
637 /* set interrupt priority */
638 ECLIC_SetPriorityIRQ_S(IRQn, priority);
639 if (handler != NULL) {
640 /* set interrupt handler entry to vector table */
641 ECLIC_SetVector_S(IRQn, (rv_csr_t)handler);
643 /* enable interrupt */
644 ECLIC_EnableIRQ_S(IRQn);
649 #define FALLBACK_DEFAULT_ECLIC_BASE 0x0C000000UL
650 #define FALLBACK_DEFAULT_SYSTIMER_BASE 0x02000000UL
653 volatile IRegion_Info_Type SystemIRegionInfo;
662 static void _get_iregion_info(IRegion_Info_Type *iregion)
664 unsigned long mcfg_info;
665 if (iregion == NULL) {
668 mcfg_info = __RV_CSR_READ(CSR_MCFG_INFO);
669 if (mcfg_info & MCFG_INFO_IREGION_EXIST) { // IRegion Info present
670 iregion->iregion_base = (__RV_CSR_READ(CSR_MIRGB_INFO) >> 10) << 10;
671 iregion->eclic_base = iregion->iregion_base + IREGION_ECLIC_OFS;
672 iregion->systimer_base = iregion->iregion_base + IREGION_TIMER_OFS;
673 iregion->smp_base = iregion->iregion_base + IREGION_SMP_OFS;
674 iregion->idu_base = iregion->iregion_base + IREGION_IDU_OFS;
676 iregion->eclic_base = FALLBACK_DEFAULT_ECLIC_BASE;
677 iregion->systimer_base = FALLBACK_DEFAULT_SYSTIMER_BASE;
681 #define CLINT_MSIP(base, hartid) (*(volatile uint32_t *)((uintptr_t)((base) + ((hartid) * 4))))
682 #define SMP_CTRLREG(base, ofs) (*(volatile uint32_t *)((uintptr_t)((base) + (ofs))))
684 void __sync_harts(void) __attribute__((section(".text.init
")));
696 void __sync_harts(void)
698 // Only do synchronize when SMP_CPU_CNT is defined and number > 0
699 #if defined(SMP_CPU_CNT) && (SMP_CPU_CNT > 1)
700 unsigned long hartid = __get_hart_id();
701 unsigned long tmr_hartid = __get_hart_index();
702 unsigned long clint_base, irgb_base, smp_base;
703 unsigned long mcfg_info;
705 mcfg_info = __RV_CSR_READ(CSR_MCFG_INFO);
706 if (mcfg_info & MCFG_INFO_IREGION_EXIST) { // IRegion Info present
707 // clint base = system timer base + 0x1000
708 irgb_base = (__RV_CSR_READ(CSR_MIRGB_INFO) >> 10) << 10;
709 clint_base = irgb_base + IREGION_TIMER_OFS + 0x1000;
710 smp_base = irgb_base + IREGION_SMP_OFS;
712 clint_base = FALLBACK_DEFAULT_SYSTIMER_BASE + 0x1000;
713 smp_base = (__RV_CSR_READ(CSR_MSMPCFG_INFO) >> 4) << 4;
715 // Enable SMP and L2, disable cluster local memory
716 SMP_CTRLREG(smp_base, 0xc) = 0xFFFFFFFF;
717 SMP_CTRLREG(smp_base, 0x10) = 0x1;
718 SMP_CTRLREG(smp_base, 0xd8) = 0x0;
721 // pre-condition: interrupt must be disabled, this is done before calling this function
722 // BOOT_HARTID is defined <Device.h>
723 if (hartid == BOOT_HARTID) { // boot hart
724 // clear msip pending
725 for (int i = 0; i < SMP_CPU_CNT; i ++) {
726 CLINT_MSIP(clint_base, i) = 0;
730 // Set machine software interrupt pending to 1
731 CLINT_MSIP(clint_base, tmr_hartid) = 1;
733 // wait for pending bit cleared by boot hart
734 while (CLINT_MSIP(clint_base, tmr_hartid) == 1);
744 static void Trap_Init(void)
746 #if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1)
748 * Intialize ECLIC supervisor mode vector interrupt
749 * base address stvt to vector_table_s
751 __RV_CSR_WRITE(CSR_STVT, (unsigned long)&vector_table_s);
753 * Set ECLIC supervisor mode non-vector entry to be controlled
754 * by stvt2 CSR register.
755 * Intialize supervisor mode ECLIC non-vector interrupt
756 * base address stvt2 to irq_entry_s.
758 __RV_CSR_WRITE(CSR_STVT2, (unsigned long)&irq_entry_s);
759 __RV_CSR_SET(CSR_STVT2, 0x01);
761 * Set supervisor exception entry stvec to exc_entry_s */
762 __RV_CSR_WRITE(CSR_STVEC, (unsigned long)&exc_entry_s);
774 void _premain_init(void)
776 // TODO to make it possible for configurable boot hartid
777 unsigned long hartid = __get_hart_id();
779 // BOOT_HARTID is defined <Device.h>
780 if (hartid == BOOT_HARTID) { // only done in boot hart
781 // IREGION INFO MUST BE SET BEFORE ANY PREMAIN INIT STEPS
782 _get_iregion_info((IRegion_Info_Type *)(&SystemIRegionInfo));
784 /* TODO: Add your own initialization code here, called before main */
785 // This code located in RUNMODE_CONTROL ifdef endif block just for internal usage
786 // No need to use in your code
787 #ifdef RUNMODE_CONTROL
788 #if defined(RUNMODE_ILM_EN) && RUNMODE_ILM_EN == 0
789 // Only disable ilm when it is present
790 if (__RV_CSR_READ(CSR_MCFG_INFO) & MCFG_INFO_ILM) {
791 __RV_CSR_CLEAR(CSR_MILM_CTL, MILM_CTL_ILM_EN);
794 #if defined(RUNMODE_DLM_EN) && RUNMODE_DLM_EN == 0
795 // Only disable dlm when it is present
796 if (__RV_CSR_READ(CSR_MCFG_INFO) & MCFG_INFO_DLM) {
797 __RV_CSR_CLEAR(CSR_MDLM_CTL, MDLM_CTL_DLM_EN);
802 /* __ICACHE_PRESENT and __DCACHE_PRESENT are defined in demosoc.h */
803 // For our internal cpu testing, they want to set demosoc __ICACHE_PRESENT/__DCACHE_PRESENT to be 1
804 // __CCM_PRESENT is still default to 0 in demosoc.h, since it is used in core_feature_eclic.h to register interrupt, if set to 1, it might cause exception
805 // but in the cpu, icache or dcache might not exist due to cpu configuration, so here
806 // we need to check whether icache/dcache really exist, if yes, then turn on it
807 #if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1)
808 if (ICachePresent()) { // Check whether icache real present or not
812 #if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1)
813 if (DCachePresent()) { // Check whether dcache real present or not
818 /* Do fence and fence.i to make sure previous ilm/dlm/icache/dcache control done */
822 if (hartid == BOOT_HARTID) { // only required for boot hartid
823 // TODO implement get_cpu_freq function to get real cpu clock freq in HZ or directly give the real cpu HZ
824 SystemCoreClock = get_cpu_freq();
825 uart_init(SOC_DEBUG_UART, 115200);
826 /* Display banner after UART initialized */
828 /* Initialize exception default handlers */
830 /* ECLIC initialization, mainly MTH and NLBIT */
833 // TODO: internal usage for Nuclei
834 #ifdef RUNMODE_CONTROL
835 printf("Current RUNMODE=%s, ilm:%d, dlm %d, icache %d, dcache %d, ccm %d\n
", \
836 RUNMODE_STRING, RUNMODE_ILM_EN, RUNMODE_DLM_EN, \
837 RUNMODE_IC_EN, RUNMODE_DC_EN, RUNMODE_CCM_EN);
838 printf("CSR: MILM_CTL 0x%x, MDLM_CTL 0x%x, MCACHE_CTL 0x%x\n
", \
839 __RV_CSR_READ(CSR_MILM_CTL), __RV_CSR_READ(CSR_MDLM_CTL), \
840 __RV_CSR_READ(CSR_MCACHE_CTL));
854 void _postmain_fini(int status)
856 /* TODO: Add your own finishing code here, called after main */
857 extern void simulation_exit(int status);
858 simulation_exit(status);
872 /* Don't put any code here, please use _premain_init now */
886 /* Don't put any code here, please use _postmain_fini now */
888 /* End of Doxygen Group NMSIS_Core_SystemConfig */