NMSIS-Core  Version 1.4.0
NMSIS-Core support for Nuclei processor-based devices
system_Device.c
1 /*
2  * Copyright (c) 2009-2018 Arm Limited. All rights reserved.
3  * Copyright (c) 2019 Nuclei Limited. All rights reserved.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  * Licensed under the Apache License, Version 2.0 (the License); you may
8  * not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
15  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 /******************************************************************************
20  * @file system_evalsoc.c
21  * @brief NMSIS Nuclei Core Device Peripheral Access Layer Source File for
22  * Nuclei Eval SoC which support Nuclei N/NX class cores
23  * @version V1.00
24  * @date 22. Nov 2019
25  ******************************************************************************/
26 #include <stdint.h>
27 #include <stdio.h>
28 #include "nuclei_sdk_hal.h"
29 
30 // TODO: This implementation contains many extra code controlled by macros
31 // which may be not suitable for your SoC, you can directly remove the code
32 
33 /*----------------------------------------------------------------------------
34  Define clocks
35  *----------------------------------------------------------------------------*/
36 /* ToDo: add here your necessary defines for device initialization
37  following is an example for different system frequencies */
38 #ifndef SYSTEM_CLOCK
39 #define SYSTEM_CLOCK (16000000UL)
40 #endif
41 
75 #if (defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1))
76 extern void exc_entry_s(void);
77 /* default s-mode exception handler, which user can modify it at your need */
78 static void system_default_exception_handler_s(unsigned long scause, unsigned long sp);
79 #endif
80 static void system_default_exception_handler(unsigned long mcause, unsigned long sp);
81 
82 #if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1)
83 
84 /* for the following variables, see intexc_evalsoc.S and intexc_evalsoc_s.S */
86 extern void irq_entry_s(void);
89 extern void default_intexc_handler(void);
90 
91 #ifndef __ICCRISCV__
93 extern void eclic_ssip_handler(void) __WEAK;
95 extern void eclic_stip_handler(void) __WEAK;
96 #else
98 __WEAK __SUPERVISOR_INTERRUPT void eclic_ssip_handler(void) { }
100 __WEAK __SUPERVISOR_INTERRUPT __WEAK void eclic_stip_handler(void) { }
101 #endif
102 
103 // TODO: change the aligned(512) to match stvt alignment requirement according to your eclic max interrupt number
104 // TODO: place your interrupt handler into this vector table, important if your vector table is in flash
105 #ifndef __ICCRISCV__
106 #define __SMODE_VECTOR_ATTR __attribute__((section (".text.vtable_s"), aligned(512)))
107 #else
108 #define __SMODE_VECTOR_ATTR __attribute__((section (".sintvec"), aligned(512)))
109 #endif
126 const unsigned long vector_table_s[SOC_INT_MAX] __SMODE_VECTOR_ATTR =
127 {
128  (unsigned long)(default_intexc_handler), /* 0: Reserved */
129 #if defined(__SSTC_PRESENT) && __SSTC_PRESENT == 1
130  (unsigned long)(eclic_ssip_handler), /* 1: supervisor software interrupt triggered by SSIP */
131 #else
132  (unsigned long)(default_intexc_handler), /* 1: Reserved */
133 #endif
134  (unsigned long)(default_intexc_handler), /* 2: Reserved */
135 
136  (unsigned long)(eclic_ssip_handler), /* 3: machine software interrupt triggered by MSIP but handled in S-Mode */
137 
138  (unsigned long)(default_intexc_handler), /* 4: Reserved */
139 #if defined(__SSTC_PRESENT) && __SSTC_PRESENT == 1
140  (unsigned long)(eclic_stip_handler), /* 5: supervisor timer interrupt triggered by stimecmp(SSTC) */
141 #else
142  (unsigned long)(default_intexc_handler), /* 5: Reserved */
143 #endif
144 
145  (unsigned long)(default_intexc_handler), /* 6: Reserved */
146 
147  (unsigned long)(eclic_stip_handler), /* 7: machine timer interrupt triggered by mtimecmp but handled in S-Mode */
148 
149  (unsigned long)(default_intexc_handler), /* 8: Reserved */
150  (unsigned long)(default_intexc_handler), /* 9: Reserved */
151  (unsigned long)(default_intexc_handler), /* 10: Reserved */
152  (unsigned long)(default_intexc_handler), /* 11: Reserved */
153 
154  (unsigned long)(default_intexc_handler), /* 12: Reserved */
155  (unsigned long)(default_intexc_handler), /* 13: Reserved */
156  (unsigned long)(default_intexc_handler), /* 14: Reserved */
157  (unsigned long)(default_intexc_handler), /* 15: Reserved */
158 
159  (unsigned long)(default_intexc_handler), /* 16: Reserved */
160  (unsigned long)(default_intexc_handler), /* 17: Reserved */
161  (unsigned long)(default_intexc_handler), /* 18: Reserved */
162 /* TODO other external interrupt handler don't provide default value, if you want to provide default value, please do it by yourself */
163 };
164 #endif
165 
166 /*----------------------------------------------------------------------------
167  System Core Clock Variable
168  *----------------------------------------------------------------------------*/
169 /* ToDo: initialize SystemCoreClock with the system core clock frequency value
170  achieved after system intitialization.
171  This means system core clock frequency after call to SystemInit() */
184 volatile uint32_t SystemCoreClock = SYSTEM_CLOCK; /* System Clock Frequency (Core Clock) */
185 
186 /*----------------------------------------------------------------------------
187  Clock functions
188  *----------------------------------------------------------------------------*/
189 
197 void SystemCoreClockUpdate(void) /* Get Core Clock Frequency */
198 {
199  /* ToDo: add code to calculate the system frequency based upon the current
200  * register settings.
201  * Note: This function can be used to retrieve the system core clock frequeny
202  * after user changed register settings.
203  */
204 }
205 
214 void SystemInit(void)
215 {
216  /* ToDo: add code to initialize the system
217  * Warn: do not use global variables because this function is called before
218  * reaching pre-main. RW section maybe overwritten afterwards.
219  */
220 }
221 
239 typedef void (*EXC_HANDLER)(unsigned long cause, unsigned long sp);
240 typedef void (*INT_HANDLER)(unsigned long cause, unsigned long sp);
241 
243 #define MAX_SYSTEM_EXCEPTION_NUM 20
253 
254 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
255 static unsigned long SystemMExtInterruptHandlers[__PLIC_INTNUM];
256 #endif
257 
258 #define SYSTEM_CORE_INTNUM 16 // >=16 Designated for platform use
259 
260 static void system_mmode_extirq_handler(unsigned long exccode, unsigned long sp);
261 static void core_interrupt_handler(unsigned long exccode, unsigned long sp);
263 
264 uint32_t core_exception_handler(unsigned long mcause, unsigned long sp);
266 
274 #if (defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1))
276 
277 static void system_default_interrupt_handler_s(unsigned long scause, unsigned long sp);
278 static void system_smode_extirq_handler(unsigned long exccode, unsigned long sp);
279 static void core_interrupt_handler_s(unsigned long exccode, unsigned long sp);
282 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
283 static unsigned long SystemSExtInterruptHandlers[__PLIC_INTNUM];
284 #endif
285 #endif
286 
294 void Exception_DumpFrame(unsigned long sp, uint8_t mode)
295 {
296 #if defined(CODESIZE) && (CODESIZE == 1)
297 
298 #else
299  EXC_Frame_Type *exc_frame = (EXC_Frame_Type *)sp;
300 
301 #ifndef __riscv_32e
302  NSDK_DEBUG("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" \
303  "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" \
304  "cause: 0x%lx, epc: 0x%lx\n", exc_frame->ra, exc_frame->tp, exc_frame->t0, \
305  exc_frame->t1, exc_frame->t2, exc_frame->t3, exc_frame->t4, exc_frame->t5, exc_frame->t6, \
306  exc_frame->a0, exc_frame->a1, exc_frame->a2, exc_frame->a3, exc_frame->a4, exc_frame->a5, \
307  exc_frame->a6, exc_frame->a7, exc_frame->cause, exc_frame->epc);
308 #else
309  NSDK_DEBUG("ra: 0x%lx, tp: 0x%lx, t0: 0x%lx, t1: 0x%lx, t2: 0x%lx\n" \
310  "a0: 0x%lx, a1: 0x%lx, a2: 0x%lx, a3: 0x%lx, a4: 0x%lx, a5: 0x%lx\n" \
311  "cause: 0x%lx, epc: 0x%lx\n", exc_frame->ra, exc_frame->tp, exc_frame->t0, \
312  exc_frame->t1, exc_frame->t2, exc_frame->a0, exc_frame->a1, exc_frame->a2, exc_frame->a3, \
313  exc_frame->a4, exc_frame->a5, exc_frame->cause, exc_frame->epc);
314 #endif
315 
316  if (PRV_M == mode) {
317  /* msubm is exclusive to machine mode */
318  NSDK_DEBUG("msubm: 0x%lx\n", exc_frame->msubm);
319  }
320 #endif
321 }
322 
331 static void system_default_exception_handler(unsigned long mcause, unsigned long sp)
332 {
333 #if defined(CODESIZE) && (CODESIZE == 1)
334 
335 #else
336  NSDK_DEBUG("MCAUSE : 0x%lx\r\n", mcause);
337  NSDK_DEBUG("MDCAUSE: 0x%lx\r\n", __RV_CSR_READ(CSR_MDCAUSE));
338  NSDK_DEBUG("MEPC : 0x%lx\r\n", __RV_CSR_READ(CSR_MEPC));
339  NSDK_DEBUG("MTVAL : 0x%lx\r\n", __RV_CSR_READ(CSR_MTVAL));
340  NSDK_DEBUG("HARTID : %u\r\n", (unsigned int)__get_hart_id());
342 #if defined(SIMULATION_MODE)
343  // directly exit if in SIMULATION
344  extern void simulation_exit(int status);
345  simulation_exit(1);
346 #else
347  while (1);
348 #endif
349 #endif
350 }
351 
357 static void system_default_interrupt_handler(unsigned long mcause, unsigned long sp)
358 {
359 #if defined(CODESIZE) && (CODESIZE == 1)
360 
361 #else
362  NSDK_DEBUG("Trap in Interrupt\r\n");
363  NSDK_DEBUG("MCAUSE: 0x%lx\r\n", mcause);
364  NSDK_DEBUG("MEPC : 0x%lx\r\n", __RV_CSR_READ(CSR_MEPC));
365  NSDK_DEBUG("MTVAL : 0x%lx\r\n", __RV_CSR_READ(CSR_MTVAL));
366 #endif
367 }
368 
381 static void core_interrupt_handler(unsigned long exccode, unsigned long sp)
382 {
383  INT_HANDLER int_handler = NULL;
384  int_handler = (INT_HANDLER)(SystemCoreInterruptHandlers[exccode]);
385  if (int_handler != NULL) {
386  int_handler(exccode, sp);
387  }
388 }
389 
406 uint32_t core_exception_handler(unsigned long mcause, unsigned long sp)
407 {
408 #if defined(CODESIZE) && (CODESIZE == 1)
409  // TODO when CODESIZE macro is defined
410  // Exception_xxx APIs will not be used, all the m-mode exception handlers
411  // will goto this function, and you can handle it here by yourself
412  while (1);
413 #else
414 
415  unsigned long exccode = (mcause & MCAUSE_CAUSE);
416  EXC_HANDLER exc_handler;
417 
418  if (mcause & MCAUSE_INTR) {
419  if (system_core_interrupt_handler != NULL) {
420  system_core_interrupt_handler(exccode, sp);
421  }
422  } else {
423  if (exccode < MAX_SYSTEM_EXCEPTION_NUM) {
424  exc_handler = (EXC_HANDLER)SystemExceptionHandlers[exccode];
425  } else if (exccode == NMI_EXCn) {
427  } else {
429  }
430  if (exc_handler != NULL) {
431  exc_handler(mcause, sp);
432  }
433  }
434 
435  return 0;
436 #endif
437 }
438 
446 static void system_mmode_extirq_handler(unsigned long exccode, unsigned long sp)
447 {
448 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
449  uint32_t irqn = PLIC_ClaimInterrupt();
450  INT_HANDLER int_handler = NULL;
451  if (irqn < __PLIC_INTNUM) {
452  int_handler = (INT_HANDLER)(SystemMExtInterruptHandlers[irqn]);
453  if (int_handler != NULL) {
454  int_handler(exccode, sp);
455  }
456  }
458 #endif
459 }
460 
470 void Interrupt_Register_CoreIRQ(uint32_t irqn, unsigned long int_handler)
471 {
472  if ((irqn < SYSTEM_CORE_INTNUM) && (irqn >= 0)) {
473  SystemCoreInterruptHandlers[irqn] = int_handler;
474  }
475 }
476 
485 unsigned long Interrupt_Get_CoreIRQ(uint32_t irqn)
486 {
487  if ((irqn < SYSTEM_CORE_INTNUM) && (irqn >= 0)) {
488  return SystemCoreInterruptHandlers[irqn];
489  }
490  return 0;
491 }
492 
502 void Interrupt_Register_ExtIRQ(uint32_t irqn, unsigned long int_handler)
503 {
504 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
505  if ((irqn < __PLIC_INTNUM) && (irqn >= 0)) {
506  SystemMExtInterruptHandlers[irqn] = int_handler;
507  }
508 #endif
509 }
510 
519 unsigned long Interrupt_Get_ExtIRQ(uint32_t irqn)
520 {
521 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
522  if ((irqn < __PLIC_INTNUM) && (irqn >= 0)) {
523  return SystemMExtInterruptHandlers[irqn];
524  }
525 #endif
526  return 0;
527 }
528 
529 
538 void Exception_Register_EXC(uint32_t EXCn, unsigned long exc_handler)
539 {
540 #if defined(CODESIZE) && (CODESIZE == 1)
541 
542 #else
543  if (EXCn < MAX_SYSTEM_EXCEPTION_NUM) {
544  SystemExceptionHandlers[EXCn] = exc_handler;
545  } else if (EXCn == NMI_EXCn) {
547  }
548 #endif
549 }
550 
559 unsigned long Exception_Get_EXC(uint32_t EXCn)
560 {
561 #if defined(CODESIZE) && (CODESIZE == 1)
562  return 0;
563 #else
564  if (EXCn < MAX_SYSTEM_EXCEPTION_NUM) {
565  return SystemExceptionHandlers[EXCn];
566  } else if (EXCn == NMI_EXCn) {
568  } else {
569  return 0;
570  }
571 #endif
572 }
573 
582 static void Exception_Init(void)
583 {
584 #if defined(CODESIZE) && (CODESIZE == 1)
585  // TODO when CODESIZE macro is defined
586  // the exception handler table for m/s mode will not be initialized
587  // since all the exception handlers will not be classified, and just
588  // goto core_exception_handler or core_exception_handler_s for m/s exception
589 #else
590  for (int i = 0; i < MAX_SYSTEM_EXCEPTION_NUM; i++) {
592 #if (defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1))
594 #endif
595  }
597 #endif
598 }
599 
600 #if (defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1))
609 static void system_default_exception_handler_s(unsigned long scause, unsigned long sp)
610 {
611 #if defined(CODESIZE) && (CODESIZE == 1)
612 #else
613  /* TODO: Uncomment this if you have implement NSDK_DEBUG function */
614  NSDK_DEBUG("SCAUSE : 0x%lx\r\n", scause);
615  NSDK_DEBUG("SDCAUSE: 0x%lx\r\n", __RV_CSR_READ(CSR_SDCAUSE));
616  NSDK_DEBUG("SEPC : 0x%lx\r\n", __RV_CSR_READ(CSR_SEPC));
617  NSDK_DEBUG("STVAL : 0x%lx\r\n", __RV_CSR_READ(CSR_STVAL));
619 #if defined(SIMULATION_MODE)
620  // directly exit if in SIMULATION
621  extern void simulation_exit(int status);
622  simulation_exit(1);
623 #else
624  while (1);
625 #endif
626 #endif
627 }
628 
634 static void system_default_interrupt_handler_s(unsigned long scause, unsigned long sp)
635 {
636 #if defined(CODESIZE) && (CODESIZE == 1)
637 
638 #else
639  NSDK_DEBUG("Trap in S-Mode Interrupt\r\n");
640  NSDK_DEBUG("SCAUSE: 0x%lx\r\n", scause);
641  NSDK_DEBUG("SEPC : 0x%lx\r\n", __RV_CSR_READ(CSR_SEPC));
642  NSDK_DEBUG("STVAL : 0x%lx\r\n", __RV_CSR_READ(CSR_STVAL));
643 #endif
644 }
645 
658 static void core_interrupt_handler_s(unsigned long exccode, unsigned long sp)
659 {
660 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
661  INT_HANDLER int_handler = NULL;
662  int_handler = (INT_HANDLER)(SystemCoreInterruptHandlers_S[exccode]);
663  if (int_handler != NULL) {
664  int_handler(exccode, sp);
665  }
666 #endif
667 }
668 
676 static void system_smode_extirq_handler(unsigned long exccode, unsigned long sp)
677 {
678 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
679  uint32_t irqn = PLIC_ClaimInterrupt_S();
680  INT_HANDLER int_handler = NULL;
681  if (irqn < __PLIC_INTNUM) {
682  int_handler = (INT_HANDLER)(SystemSExtInterruptHandlers[irqn]);
683  if (int_handler != NULL) {
684  int_handler(exccode, sp);
685  }
686  }
688 #endif
689 }
690 
704 uint32_t core_exception_handler_s(unsigned long scause, unsigned long sp)
705 {
706 #if defined(CODESIZE) && (CODESIZE == 1)
707  // TODO when CODESIZE macro is defined
708  // Exception_xxx_S APIs will not be used, all the s-mode exception handlers
709  // will goto this function, and you can handle it here by yourself
710  while(1);
711 #else
712  unsigned long exccode = (scause & SCAUSE_CAUSE);
713  EXC_HANDLER exc_handler;
714  if (scause & MCAUSE_INTR) {
715  if (system_core_interrupt_handler_s != NULL) {
716  system_core_interrupt_handler_s(exccode, sp);
717  }
718  } else {
719  if (exccode < MAX_SYSTEM_EXCEPTION_NUM) {
720  exc_handler = (EXC_HANDLER)SystemExceptionHandlers_S[exccode];
721  } else {
723  }
724  if (exc_handler != NULL) {
725  exc_handler(scause, sp);
726  }
727  }
728  return 0;
729 #endif
730 }
731 
741 void Exception_Register_EXC_S(uint32_t EXCn, unsigned long exc_handler)
742 {
743 #if defined(CODESIZE) && (CODESIZE == 1)
744 #else
745  if (EXCn < MAX_SYSTEM_EXCEPTION_NUM) {
746  SystemExceptionHandlers_S[EXCn] = exc_handler;
747  }
748 #endif
749 }
750 
758 unsigned long Exception_Get_EXC_S(uint32_t EXCn)
759 {
760 #if defined(CODESIZE) && (CODESIZE == 1)
761  return 0;
762 #else
763  if (EXCn < MAX_SYSTEM_EXCEPTION_NUM) {
764  return SystemExceptionHandlers_S[EXCn];
765  } else {
766  return 0;
767  }
768 #endif
769 }
770 
780 void Interrupt_Register_CoreIRQ_S(uint32_t irqn, unsigned long int_handler)
781 {
782  if ((irqn < SYSTEM_CORE_INTNUM) && (irqn >= 0)) {
783  SystemCoreInterruptHandlers_S[irqn] = int_handler;
784  }
785 }
786 
795 unsigned long Interrupt_Get_CoreIRQ_S(uint32_t irqn)
796 {
797  if ((irqn < SYSTEM_CORE_INTNUM) && (irqn >= 0)) {
798  return SystemCoreInterruptHandlers_S[irqn];
799  }
800  return 0;
801 }
802 
812 void Interrupt_Register_ExtIRQ_S(uint32_t irqn, unsigned long int_handler)
813 {
814 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
815 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
816  if ((irqn < __PLIC_INTNUM) && (irqn >= 0)) {
817  SystemSExtInterruptHandlers[irqn] = int_handler;
818  }
819 #endif
820 #endif
821 }
822 
831 unsigned long Interrupt_Get_ExtIRQ_S(uint32_t irqn)
832 {
833 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
834 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
835  if ((irqn < __PLIC_INTNUM) && (irqn >= 0)) {
836  return SystemSExtInterruptHandlers[irqn];
837  }
838 #endif
839 #endif
840  return 0;
841 }
842 #endif
843  /* End of Doxygen Group NMSIS_Core_ExceptionAndNMI */
845 
848 {
849 #if defined(NUCLEI_BANNER) && (NUCLEI_BANNER == 1)
850  NSDK_DEBUG("Nuclei SDK Build Time: %s, %s\r\n", __DATE__, __TIME__);
851 #ifdef DOWNLOAD_MODE_STRING
852  NSDK_DEBUG("Download Mode: %s\r\n", DOWNLOAD_MODE_STRING);
853 #endif
854  NSDK_DEBUG("CPU Frequency %u Hz\r\n", (unsigned int)SystemCoreClock);
855  NSDK_DEBUG("CPU HartID: %u\r\n", (unsigned int)__get_hart_id());
856 #endif
857 }
858 
859 
860 #if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1)
861 extern unsigned long vector_base[];
862 extern void irq_entry(void);
863 #endif
864 extern void exc_entry(void);
865 
880 {
881 #if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1)
882  unsigned long mcfg_info;
883 
884  mcfg_info = __RV_CSR_READ(CSR_MCFG_INFO);
885  if (mcfg_info & MCFG_INFO_CLIC) {
886  /* Set ECLIC vector interrupt base address to vector_base */
887  __RV_CSR_WRITE(CSR_MTVT, (unsigned long)vector_base);
888  /* Set ECLIC non-vector entry to irq_entry */
889  __RV_CSR_WRITE(CSR_MTVT2, (unsigned long)irq_entry | 0x1);
890  /* Set as CLIC interrupt mode */
891  __RV_CSR_WRITE(CSR_MTVEC, (unsigned long)exc_entry | 0x3);
892  /* Global Configuration about MTH and NLBits.
893  * TODO: Please adapt it according to your system requirement.
894  * This function is called in _init function */
895  ECLIC_SetMth(0);
896  ECLIC_SetCfgNlbits(__ECLIC_INTCTLBITS);
897 
898 #if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1)
899  if (mcfg_info & MCFG_INFO_TEE) {
900  /*
901  * Intialize ECLIC supervisor mode vector interrupt
902  * base address stvt to vector_table_s
903  */
904  __RV_CSR_WRITE(CSR_STVT, (unsigned long)vector_table_s);
905  /*
906  * Set ECLIC supervisor mode non-vector entry to be controlled
907  * by stvt2 CSR register.
908  * Intialize supervisor mode ECLIC non-vector interrupt
909  * base address stvt2 to irq_entry_s.
910  */
911  __RV_CSR_WRITE(CSR_STVT2, (unsigned long)irq_entry_s);
912  __RV_CSR_SET(CSR_STVT2, 0x01);
913  /*
914  * Set supervisor exception entry stvec to exc_entry_s */
915  __RV_CSR_WRITE(CSR_STVEC, (unsigned long)exc_entry_s);
916  /* Global Configuration about STH */
917  ECLIC_SetSth(0);
918  }
919 #endif
920  } else {
921  /* Set as CLINT interrupt mode */
922  __RV_CSR_WRITE(CSR_MTVEC, (unsigned long)exc_entry);
923  }
924 #endif
925 }
926 
936 {
937  /* Register core interrupt handler for clint/plic interrupt mode */
939  /* Set as CLINT interrupt mode */
940  __RV_CSR_WRITE(CSR_MTVEC, (unsigned long)exc_entry);
941 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
942  /*
943  * Set supervisor exception entry stvec to exc_entry_s
944  */
945  __RV_CSR_WRITE(CSR_STVEC, (unsigned long)exc_entry_s);
947 #endif
948  for (int i = 0; i < SYSTEM_CORE_INTNUM; i++) {
950 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
952 #endif
953  }
954 }
955 
964 {
966 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
967  int i;
968  for (i = 0; i < __PLIC_INTNUM; i++) {
970 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
972 #endif
973  }
974 
977 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
980 #endif
981 #endif
982 }
983 
997 void Interrupt_Init(void)
998 {
999 #if defined(CODESIZE) && (CODESIZE == 1)
1000 #else
1001  /* Set as CLINT interrupt mode */
1002  __RV_CSR_WRITE(CSR_MTVEC, (unsigned long)exc_entry);
1003 
1004  /* Init interrupt as eclic mode when ECLIC present
1005  * Otherwise will init interrupt as plic mode when PLIC present
1006  * Only initialize necessary ones to reduce initialization code size usage */
1007 #if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1)
1009 #elif defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
1011 #endif
1012 
1013 #endif
1014 }
1015 
1016 #if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1)
1033 int32_t ECLIC_Register_IRQ(IRQn_Type IRQn, uint8_t shv, ECLIC_TRIGGER_Type trig_mode, uint8_t lvl, uint8_t priority, void* handler)
1034 {
1035  if ((IRQn > SOC_INT_MAX) || (shv > ECLIC_VECTOR_INTERRUPT) \
1036  || (trig_mode > ECLIC_NEGTIVE_EDGE_TRIGGER)) {
1037  return -1;
1038  }
1039 
1040  /* set interrupt vector mode */
1041  ECLIC_SetShvIRQ(IRQn, shv);
1042  /* set interrupt trigger mode and polarity */
1043  ECLIC_SetTrigIRQ(IRQn, trig_mode);
1044  /* set interrupt level */
1045  ECLIC_SetLevelIRQ(IRQn, lvl);
1046  /* set interrupt priority */
1047  ECLIC_SetPriorityIRQ(IRQn, priority);
1048  if (handler != NULL) {
1049  /* set interrupt handler entry to vector table */
1050  ECLIC_SetVector(IRQn, (rv_csr_t)handler);
1051  }
1052  /* enable interrupt */
1053  ECLIC_EnableIRQ(IRQn);
1054  return 0;
1055 }
1056 #endif
1057 
1069 int32_t Core_Register_IRQ(uint32_t irqn, void *handler)
1070 {
1071  if ((irqn > SYSTEM_CORE_INTNUM)) {
1072  return -1;
1073  }
1074 
1075  if (handler != NULL) {
1076  /* register interrupt handler entry to core handlers */
1077  Interrupt_Register_CoreIRQ(irqn, (unsigned long)handler);
1078  }
1079  switch (irqn) {
1080  case SysTimerSW_IRQn:
1081  __enable_sw_irq();
1082  break;
1083  case SysTimer_IRQn:
1085  break;
1086  default:
1087  break;
1088  }
1089 
1090  return 0;
1091 }
1092 
1093 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
1105 int32_t Core_Register_IRQ_S(uint32_t irqn, void *handler)
1106 {
1107  if ((irqn > SYSTEM_CORE_INTNUM)) {
1108  return -1;
1109  }
1110 
1111  if (handler != NULL) {
1112  /* register interrupt handler entry to core handlers */
1113  Interrupt_Register_CoreIRQ_S(irqn, (unsigned long)handler);
1114  }
1115  switch (irqn) {
1116  case SysTimerSW_S_IRQn:
1118  break;
1119  case SysTimer_S_IRQn:
1121  break;
1122  default:
1123  break;
1124  }
1125 
1126  return 0;
1127 }
1128 #endif
1129 
1130 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
1143 int32_t PLIC_Register_IRQ(uint32_t source, uint8_t priority, void *handler)
1144 {
1145  if ((source >= __PLIC_INTNUM)) {
1146  return -1;
1147  }
1148 
1149  /* set interrupt priority */
1150  PLIC_SetPriority(source, priority);
1151  if (handler != NULL) {
1152  /* register interrupt handler entry to external handlers */
1153  Interrupt_Register_ExtIRQ(source, (unsigned long)handler);
1154  }
1155  /* enable interrupt */
1156  PLIC_EnableInterrupt(source);
1157  __enable_ext_irq();
1158  return 0;
1159 }
1160 
1161 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
1174 int32_t PLIC_Register_IRQ_S(uint32_t source, uint8_t priority, void *handler)
1175 {
1176  if ((source >= __PLIC_INTNUM)) {
1177  return -1;
1178  }
1179 
1180  /* set interrupt priority */
1181  PLIC_SetPriority(source, priority);
1182  if (handler != NULL) {
1183  /* register interrupt handler entry to external handlers */
1184  Interrupt_Register_ExtIRQ_S(source, (unsigned long)handler);
1185  }
1186  /* enable interrupt */
1187  PLIC_EnableInterrupt_S(source);
1189  return 0;
1190 }
1191 #endif
1192 #endif
1193 
1194 #if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1)
1211 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)
1212 {
1213  if ((IRQn > SOC_INT_MAX) || (shv > ECLIC_VECTOR_INTERRUPT) \
1214  || (trig_mode > ECLIC_NEGTIVE_EDGE_TRIGGER)) {
1215  return -1;
1216  }
1217 
1218  /* set interrupt vector mode */
1219  ECLIC_SetShvIRQ_S(IRQn, shv);
1220  /* set interrupt trigger mode and polarity */
1221  ECLIC_SetTrigIRQ_S(IRQn, trig_mode);
1222  /* set interrupt level */
1223  ECLIC_SetLevelIRQ_S(IRQn, lvl);
1224  /* set interrupt priority */
1225  ECLIC_SetPriorityIRQ_S(IRQn, priority);
1226  if (handler != NULL) {
1227  /* set interrupt handler entry to vector table */
1228  ECLIC_SetVector_S(IRQn, (rv_csr_t)handler);
1229  }
1230  /* enable interrupt */
1231  ECLIC_EnableIRQ_S(IRQn);
1232  return 0;
1233 }
1234 #endif
1235 
1236 // NOTE: FALLBACK_DEFAULT_ECLIC_BASE/FALLBACK_DEFAULT_SYSTIMER_BASE macros are removed
1237 // No longer support for cpu without iregion feature
1238 
1239 #ifndef CFG_IREGION_BASE_ADDR
1241 volatile unsigned long CpuIRegionBase = 0xFFFFFFFF;
1242 #endif
1243 
1244 #define CLINT_MSIP(base, hartid) (*(volatile uint32_t *)((uintptr_t)((base) + ((hartid) * 4))))
1245 #define SMP_CTRLREG(base, ofs) (*(volatile uint32_t *)((uintptr_t)((base) + (ofs))))
1246 
1247 void __sync_harts(void) __attribute__((section(".text.init")));
1259 void __sync_harts(void)
1260 {
1261 // Only do synchronize when SMP_CPU_CNT is defined and number > 0
1262 // TODO: If you don't need to support SMP, you can directly remove code in it
1263 #if defined(SMP_CPU_CNT) && (SMP_CPU_CNT > 1)
1264  unsigned long hartid = __get_hart_id();
1265  unsigned long tmr_hartid = __get_hart_index();
1266  unsigned long clint_base, irgb_base, smp_base;
1267  unsigned long mcfg_info;
1268 
1269  // NOTE: we should avoid to use global variable such as CpuIRegionBase before smp cpu are configured
1270  mcfg_info = __RV_CSR_READ(CSR_MCFG_INFO);
1271  // Assume IREGION feature present
1272  if (mcfg_info & MCFG_INFO_IREGION_EXIST) { // IRegion Info present
1273  // clint base = system timer base + 0x1000
1274  irgb_base = (__RV_CSR_READ(CSR_MIRGB_INFO) >> 10) << 10;
1275  clint_base = irgb_base + IREGION_TIMER_OFS + 0x1000;
1276  smp_base = irgb_base + IREGION_SMP_OFS;
1277  } else {
1278  // Should not enter to here if iregion feature present
1279  while(1);
1280  }
1281  // Enable SMP
1282  SMP_CTRLREG(smp_base, 0xc) = 0xFFFFFFFF;
1283  // Enaable L2, disable cluster local memory
1284  if (SMP_CTRLREG(smp_base, 0x4) & 0x1) {
1285  SMP_CTRLREG(smp_base, 0x10) = 0x1;
1286  SMP_CTRLREG(smp_base, 0xd8) = 0x0;
1287  }
1288  __SMP_RWMB();
1289 
1290  // pre-condition: interrupt must be disabled, this is done before calling this function
1291  // BOOT_HARTID is defined <Device.h>
1292  if (hartid == BOOT_HARTID) { // boot hart
1293  // clear msip pending
1294  for (int i = 0; i < SMP_CPU_CNT; i ++) {
1295  CLINT_MSIP(clint_base, i) = 0;
1296  }
1297  __SMP_RWMB();
1298  } else {
1299  // Set machine software interrupt pending to 1
1300  CLINT_MSIP(clint_base, tmr_hartid) = 1;
1301  __SMP_RWMB();
1302  // wait for pending bit cleared by boot hart
1303  while (CLINT_MSIP(clint_base, tmr_hartid) == 1);
1304  }
1305 #endif
1306 }
1307 
1312 static void Trap_Init(void)
1313 {
1314 }
1315 
1324 void _premain_init(void)
1325 {
1326 #if defined(CODESIZE) && (CODESIZE == 1)
1327  // TODO to reduce the code size of application
1328  // No need to do so complex premain initialization steps
1329  // You just need to initialize the cpu resource you need to use in your
1330  // application code.
1331 
1332 #ifndef CFG_IREGION_BASE_ADDR // Need to probe the cpu iregion base address
1333  // Probe CPUIRegionBase for other cpu internal peripheral to use
1334  CpuIRegionBase = (__RV_CSR_READ(CSR_MIRGB_INFO) >> 10) << 10;
1335 #endif
1336  // TODO Still need to initialize uart for other code need to do printf
1337  // If you want to reduce more code, you can comment below code
1338  uart_init(SOC_DEBUG_UART, 115200);
1339 
1340 #else
1341  // TODO to make it possible for configurable boot hartid
1342  unsigned long hartid = __get_hart_id();
1343  unsigned long mcfginfo = __RV_CSR_READ(CSR_MCFG_INFO);
1344 
1345  /* TODO: Add your own initialization code here, called before main */
1346  // TODO This code controlled by macros RUNMODE_* are only used internally by Nuclei
1347  // You can remove it if you don't want it
1348  // No need to use in your code
1349 #if defined(RUNMODE_ILM_EN) || defined(RUNMODE_ECC_EN)
1350  // Only disable ilm when it is present
1351  if (mcfginfo & MCFG_INFO_ILM) {
1352 #if defined(RUNMODE_ECC_EN)
1353 #if RUNMODE_ECC_EN == 0
1355 #else
1357 #endif
1358 #endif
1359 #if defined(RUNMODE_ILM_EN)
1360 #if RUNMODE_ILM_EN == 0
1362 #else
1364 #endif
1365 #endif
1366  }
1367 #endif
1368 
1369 #if defined(RUNMODE_DLM_EN) || defined(RUNMODE_ECC_EN)
1370  // Only disable dlm when it is present
1371  if (mcfginfo & MCFG_INFO_DLM) {
1372 #if defined(RUNMODE_ECC_EN)
1373 #if RUNMODE_ECC_EN == 0
1375 #else
1377 #endif
1378 #endif
1379 #if defined(RUNMODE_DLM_EN)
1380 #if RUNMODE_DLM_EN == 0
1382 #else
1384 #endif
1385 #endif
1386  }
1387 #endif
1388 
1389 #if defined(RUNMODE_LDSPEC_EN)
1390 #if RUNMODE_LDSPEC_EN == 1
1392 #else
1394 #endif
1395 #endif
1396 
1397  /* __ICACHE_PRESENT and __DCACHE_PRESENT are defined in evalsoc.h */
1398  // For our internal cpu testing, they want to set evalsoc __ICACHE_PRESENT/__DCACHE_PRESENT to be 1
1399  // __CCM_PRESENT is still default to 0 in evalsoc.h, since it is used in core_feature_eclic.h to register interrupt, if set to 1, it might cause exception
1400  // but in the cpu, icache or dcache might not exist due to cpu configuration, so here
1401  // we need to check whether icache/dcache really exist, if yes, then turn on it
1402 #if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1)
1403  if (ICachePresent()) { // Check whether icache real present or not
1404 #if defined(RUNMODE_ECC_EN)
1405 #if RUNMODE_ECC_EN == 0
1407 #else
1409 #endif
1410 #endif
1411  EnableICache();
1412  }
1413 #endif
1414 #if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1)
1415  if (DCachePresent()) { // Check whether dcache real present or not
1416 #if defined(RUNMODE_ECC_EN)
1417 #if RUNMODE_ECC_EN == 0
1419 #else
1421 #endif
1422 #endif
1423  EnableDCache();
1424  }
1425 #endif
1426 
1427  /* Do fence and fence.i to make sure previous ilm/dlm/icache/dcache control done */
1428  __RWMB();
1429  __FENCE_I();
1430 
1431  // BOOT_HARTID is defined <Device.h> and also controlled by BOOT_HARTID in conf/evalsoc/build.mk
1432 #ifndef CFG_IREGION_BASE_ADDR // Need to probe the cpu iregion base address
1433  if (hartid == BOOT_HARTID) { // only done in boot hart
1434  // IREGION INFO MUST BE AFTER L1/L2 Cache enabled and SMP enabled if SMP present
1435  CpuIRegionBase = (__RV_CSR_READ(CSR_MIRGB_INFO) >> 10) << 10;
1436  } else {
1437  // wait for correct iregion base addr is set by boot hart
1438  while (CpuIRegionBase == 0xFFFFFFFF);
1439  }
1440 #endif
1441 
1442 #if defined(RUNMODE_L2_EN)
1443  if ((mcfginfo & (0x1 << 11)) && SMP_CTRLREG(__SMPCC_BASEADDR, 0x4) & 0x1 ) { // L2 Cache present
1444 #if RUNMODE_L2_EN == 1
1445  // Enable L2, disable cluster local memory
1446  SMP_CTRLREG(__SMPCC_BASEADDR, 0x10) = 0x1;
1447  SMP_CTRLREG(__SMPCC_BASEADDR, 0xd8) = 0x0;
1448  __SMP_RWMB();
1449 #else
1450  // Disable L2, enable cluster local memory
1451  SMP_CTRLREG(__SMPCC_BASEADDR, 0x10) = 0x0;
1452  // use as clm or cache, when l2 disable, the affect to ddr is the same, l2 is really disabled
1453  SMP_CTRLREG(__SMPCC_BASEADDR, 0xd8) = 0;//0xFFFFFFFF;
1454  __SMP_RWMB();
1455 #endif
1456  }
1457 #endif
1458 
1459 #if defined(RUNMODE_BPU_EN)
1460 #if RUNMODE_BPU_EN == 1
1462 #else
1464 #endif
1465 #endif
1466 
1467 #if defined(__CCM_PRESENT) && (__CCM_PRESENT == 1)
1468  // NOTE: CFG_HAS_SMODE and CFG_HAS_UMODE are defined in auto generated cpufeature.h if present in cpu
1469 #if defined(CFG_HAS_SMODE) || defined(CFG_HAS_UMODE)
1470  EnableSUCCM();
1471 #endif
1472 #endif
1473 
1474  if (hartid == BOOT_HARTID) { // only required for boot hartid
1475  // TODO implement get_cpu_freq function to get real cpu clock freq in HZ or directly give the real cpu HZ
1476  // TODO you can directly give the correct cpu frequency here, if you know it without call get_cpu_freq function
1477  SystemCoreClock = get_cpu_freq();
1478  uart_init(SOC_DEBUG_UART, 115200);
1479  /* Display banner after UART initialized */
1481  /* Initialize exception default handlers */
1482  Exception_Init();
1483  /* Interrupt initialization */
1484  Interrupt_Init();
1485  // TODO: internal usage for Nuclei
1486 #ifdef RUNMODE_CONTROL
1487  NSDK_DEBUG("Current RUNMODE=%s, ilm:%d, dlm %d, icache %d, dcache %d, ccm %d\n", \
1488  RUNMODE_STRING, RUNMODE_ILM_EN, RUNMODE_DLM_EN, \
1489  RUNMODE_IC_EN, RUNMODE_DC_EN, RUNMODE_CCM_EN);
1490  // ILM and DLM need to be present
1491  if (mcfginfo & 0x180 == 0x180) {
1492  NSDK_DEBUG("CSR: MILM_CTL 0x%x, MDLM_CTL 0x%x\n", \
1494  }
1495  // I/D cache need to be present
1496  if (mcfginfo & 0x600) {
1497  NSDK_DEBUG("CSR: MCACHE_CTL 0x%x\n", __RV_CSR_READ(CSR_MCACHE_CTL));
1498  }
1499  NSDK_DEBUG("CSR: MMISC_CTL 0x%x\n", __RV_CSR_READ(CSR_MMISC_CTL));
1500 #endif
1501  } else {
1502  /* Interrupt initialization */
1503  Interrupt_Init();
1504  }
1505 
1506 #endif
1507 }
1508 
1518 void _postmain_fini(int status)
1519 {
1520 #if defined(CODESIZE) && (CODESIZE == 1)
1521 #ifdef CFG_SIMULATION
1522  SIMULATION_EXIT(status);
1523 #endif
1524 #else
1525  /* TODO: Add your own finishing code here, called after main */
1526  extern void simulation_exit(int status);
1527  simulation_exit(status);
1528 #endif
1529 }
1530 
1540 void _init(void)
1541 {
1542  /* Don't put any code here, please use _premain_init now */
1543 }
1544 
1554 void _fini(void)
1555 {
1556  /* Don't put any code here, please use _postmain_fini now */
1557 }
1558  /* End of Doxygen Group NMSIS_Core_SystemConfig */
#define __SMP_RWMB()
SMP Read & Write Memory barrier.
__STATIC_FORCEINLINE void __FENCE_I(void)
Fence.i Instruction.
#define __RWMB()
Read & Write Memory barrier.
#define MILM_CTL_ILM_ECC_EN
#define MCACHE_CTL_DC_ECC_CHK_EN
#define MDLM_CTL_DLM_ECC_CHK_EN
#define SCAUSE_CAUSE
#define MCACHE_CTL_DC_ECC_EN
#define MILM_CTL_ILM_ECC_EXCP_EN
#define PRV_S
#define MCFG_INFO_IREGION_EXIST
#define MILM_CTL_ILM_ECC_CHK_EN
#define MMISC_CTL_LDSPEC_ENABLE
#define MCAUSE_INTR
#define MILM_CTL_ILM_EN
#define MCFG_INFO_DLM
#define MDLM_CTL_DLM_EN
#define MCACHE_CTL_IC_ECC_EXCP_EN
#define MCACHE_CTL_IC_ECC_CHK_EN
#define IREGION_TIMER_OFS
#define MCFG_INFO_TEE
#define MCFG_INFO_CLIC
#define MCACHE_CTL_DC_ECC_EXCP_EN
#define MCFG_INFO_ILM
#define MCACHE_CTL_IC_ECC_EN
#define MCAUSE_CAUSE
#define MMISC_CTL_BPU
#define IREGION_SMP_OFS
#define MDLM_CTL_DLM_ECC_EXCP_EN
#define MDLM_CTL_DLM_ECC_EN
#define PRV_M
__STATIC_FORCEINLINE void __enable_ext_irq_s(void)
Enable External IRQ Interrupts in supervisor mode.
#define __RV_CSR_CLEAR(csr, val)
CSR operation Macro for csrc instruction.
__STATIC_FORCEINLINE void __enable_ext_irq(void)
Enable External IRQ Interrupts.
#define __RV_CSR_READ(csr)
CSR operation Macro for csrr instruction.
__STATIC_FORCEINLINE void __enable_timer_irq_s(void)
Enable Timer IRQ Interrupts in supervisor mode.
__STATIC_FORCEINLINE unsigned long __get_hart_id(void)
Get hart id of current cluster.
__STATIC_FORCEINLINE unsigned long __get_hart_index(void)
Get hart index of current cluster.
#define __RV_CSR_WRITE(csr, val)
CSR operation Macro for csrw instruction.
__STATIC_FORCEINLINE void __enable_sw_irq(void)
Enable software IRQ Interrupts.
__STATIC_FORCEINLINE void __enable_timer_irq(void)
Enable Timer IRQ Interrupts.
__STATIC_FORCEINLINE void __enable_sw_irq_s(void)
Enable software IRQ Interrupts in supervisor mode.
#define __RV_CSR_SET(csr, val)
CSR operation Macro for csrs instruction.
#define CSR_MTVEC
#define CSR_SEPC
#define CSR_MDLM_CTL
#define CSR_MEPC
#define CSR_MTVT
#define CSR_MCACHE_CTL
#define CSR_STVAL
#define CSR_MILM_CTL
#define CSR_MTVT2
#define CSR_MTVAL
#define CSR_MCFG_INFO
#define CSR_MIRGB_INFO
#define CSR_STVT2
#define CSR_SDCAUSE
#define CSR_STVEC
#define CSR_MDCAUSE
#define CSR_MMISC_CTL
#define CSR_STVT
__STATIC_FORCEINLINE void EnableSUCCM(void)
Enable CCM operation in Supervisor/User Mode.
#define __SUPERVISOR_INTERRUPT
Use this attribute to indicate that the specified function is an interrupt handler run in Supervisor ...
Definition: nmsis_gcc.h:197
#define __WEAK
restrict pointer qualifier to enable additional optimizations.
Definition: nmsis_gcc.h:85
__STATIC_FORCEINLINE int32_t DCachePresent(void)
Check DCache Unit Present or Not.
__STATIC_FORCEINLINE void EnableDCache(void)
Enable DCache.
ECLIC_TRIGGER_Type
ECLIC Trigger Enum for different Trigger Type.
#define ECLIC_VECTOR_INTERRUPT
Vector Interrupt Mode of ECLIC.
@ ECLIC_NEGTIVE_EDGE_TRIGGER
Negtive/Falling Edge Triggered, trig[0] = 1, trig[1] = 1.
__STATIC_FORCEINLINE int32_t ICachePresent(void)
Check ICache Unit Present or Not.
__STATIC_FORCEINLINE void EnableICache(void)
Enable ICache.
void Exception_Register_EXC_S(uint32_t EXCn, unsigned long exc_handler)
Register an exception handler for exception code EXCn of supervisor mode.
static unsigned long SystemExceptionHandlers_S[MAX_SYSTEM_EXCEPTION_NUM]
Store the exception handlers for each exception ID in supervisor mode.
static unsigned long SystemCoreInterruptHandlers_S[SYSTEM_CORE_INTNUM]
static void system_smode_extirq_handler(unsigned long exccode, unsigned long sp)
S-Mode external interrupt handler common entry for plic interrupt mode.
static void system_default_interrupt_handler_s(unsigned long scause, unsigned long sp)
s-mode System Default Interrupt Handler for CLINT/PLIC Interrupt Mode
#define MAX_SYSTEM_EXCEPTION_NUM
Max exception handler number, don't include the NMI(0xFFF) one.
#define SYSTEM_CORE_INTNUM
static unsigned long SystemCoreInterruptHandlers[SYSTEM_CORE_INTNUM]
void Interrupt_Register_ExtIRQ(uint32_t irqn, unsigned long int_handler)
Register a m-mode external interrupt handler for plic external interrupt number.
static INT_HANDLER system_core_interrupt_handler_s
static unsigned long SystemSExtInterruptHandlers[__PLIC_INTNUM]
static void core_interrupt_handler_s(unsigned long exccode, unsigned long sp)
S-Mode Common Interrupt handler entry when in clint/plic mode.
static void system_default_exception_handler_s(unsigned long scause, unsigned long sp)
Supervisor mode system Default Exception Handler.
void Interrupt_Register_CoreIRQ_S(uint32_t irqn, unsigned long int_handler)
Register an s-mode core interrupt handler for core interrupt number.
static INT_HANDLER system_core_interrupt_handler
unsigned long Exception_Get_EXC(uint32_t EXCn)
Get current m-mode exception handler for exception code EXCn.
unsigned long Interrupt_Get_CoreIRQ(uint32_t irqn)
Get a m-mode core interrupt handler for core interrupt number.
uint32_t core_exception_handler_s(unsigned long scause, unsigned long sp)
common Exception handler entry of supervisor mode
void Exception_DumpFrame(unsigned long sp, uint8_t mode)
Dump Exception Frame.
static void system_default_exception_handler(unsigned long mcause, unsigned long sp)
M-Mode System Default Exception Handler.
unsigned long Interrupt_Get_ExtIRQ_S(uint32_t irqn)
Get an s-mode external interrupt handler for external interrupt number.
static void system_mmode_extirq_handler(unsigned long exccode, unsigned long sp)
M-Mode external interrupt handler common entry for plic interrupt mode.
void Interrupt_Register_ExtIRQ_S(uint32_t irqn, unsigned long int_handler)
Register an s-mode external interrupt handler for plic external interrupt number.
void Exception_Register_EXC(uint32_t EXCn, unsigned long exc_handler)
Register a m-mode exception handler for exception code EXCn.
void Interrupt_Register_CoreIRQ(uint32_t irqn, unsigned long int_handler)
Register a m-mode core interrupt handler for core interrupt number.
void(* INT_HANDLER)(unsigned long cause, unsigned long sp)
static void system_default_interrupt_handler(unsigned long mcause, unsigned long sp)
M-Mode System Default Interrupt Handler for CLINT/PLIC Interrupt Mode.
static void Exception_Init(void)
Initialize all the default core exception handlers.
uint32_t core_exception_handler(unsigned long mcause, unsigned long sp)
M-Mode Common NMI/Exception/Interrupt handler entry.
unsigned long Interrupt_Get_CoreIRQ_S(uint32_t irqn)
Get a s-mode core interrupt handler for core interrupt number.
static unsigned long SystemMExtInterruptHandlers[__PLIC_INTNUM]
static void core_interrupt_handler(unsigned long exccode, unsigned long sp)
M-Mode Common Interrupt handler entry when in clint/plic mode.
unsigned long Interrupt_Get_ExtIRQ(uint32_t irqn)
Get a m-mode external interrupt handler for external interrupt number.
static unsigned long SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM+1]
Store the exception handlers for each exception ID.
unsigned long Exception_Get_EXC_S(uint32_t EXCn)
Get current exception handler for exception code EXCn of supervisor mode.
void(* EXC_HANDLER)(unsigned long cause, unsigned long sp)
Exception Handler Function Typedef.
#define ECLIC_SetShvIRQ
#define ECLIC_SetPriorityIRQ_S
#define ECLIC_SetTrigIRQ_S
#define ECLIC_SetMth
#define ECLIC_SetPriorityIRQ
IRQn_Type
Definition of IRQn numbers.
#define ECLIC_SetSth
#define ECLIC_SetVector
#define ECLIC_SetShvIRQ_S
#define ECLIC_SetTrigIRQ
#define ECLIC_SetCfgNlbits
#define ECLIC_SetLevelIRQ
#define ECLIC_SetVector_S
#define ECLIC_EnableIRQ_S
#define ECLIC_EnableIRQ
#define ECLIC_SetLevelIRQ_S
@ SysTimerSW_IRQn
System Timer SW interrupt.
@ SysTimer_IRQn
System Timer Interrupt.
@ SOC_INT_MAX
Number of total interrupts.
#define PLIC_EnableInterrupt(source)
__STATIC_FORCEINLINE void PLIC_SetPriority(uint32_t source, uint32_t priority)
Set interrupt priority for selected source plic.
#define PLIC_CompleteInterrupt(source)
#define PLIC_CompleteInterrupt_S(source)
#define PLIC_ClaimInterrupt()
#define PLIC_ClaimInterrupt_S()
#define PLIC_EnableInterrupt_S(source)
unsigned long rv_csr_t
Type of Control and Status Register(CSR), depends on the XLEN defined in RISC-V.
volatile uint32_t SystemCoreClock
Variable to hold the system core clock value.
unsigned long vector_base[]
void _fini(void)
_fini function called in __libc_fini_array()
#define CLINT_MSIP(base, hartid)
void irq_entry(void)
void irq_entry_s(void)
default entry for s-mode non-vector irq entry
void exc_entry_s(void)
void CLINT_Interrupt_Init(void)
Do CLINT Interrupt configuration.
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)
Initialize a specific IRQ and register the handler for supervisor mode.
int32_t ECLIC_Register_IRQ(IRQn_Type IRQn, uint8_t shv, ECLIC_TRIGGER_Type trig_mode, uint8_t lvl, uint8_t priority, void *handler)
Initialize a specific IRQ and register the handler.
void SystemBannerPrint(void)
Banner Print for Nuclei SDK.
void _postmain_fini(int status)
finish function after main
void ECLIC_Interrupt_Init(void)
Do ECLIC Interrupt configuration.
int32_t Core_Register_IRQ_S(uint32_t irqn, void *handler)
Register a riscv s-mode core interrupt and register the handler.
void __sync_harts(void)
Synchronize all harts.
volatile unsigned long CpuIRegionBase
Nuclei RISC-V CPU IRegion Base Address Probed, you should avoid to use it in your application code,...
void default_intexc_handler(void)
default entry for s-mode exception entry
void SystemInit(void)
Function to Initialize the system.
void PLIC_Interrupt_Init(void)
Do PLIC Interrupt configuration.
#define SMP_CTRLREG(base, ofs)
int32_t PLIC_Register_IRQ(uint32_t source, uint8_t priority, void *handler)
Register a m-mode specific plic interrupt and register the handler.
int32_t Core_Register_IRQ(uint32_t irqn, void *handler)
Register a m-mode riscv core interrupt and register the handler.
void exc_entry(void)
void _premain_init(void)
early init function before main
void _init(void)
_init function called in __libc_init_array()
int32_t PLIC_Register_IRQ_S(uint32_t source, uint8_t priority, void *handler)
Register a s-mode specific plic interrupt and register the handler.
void SystemCoreClockUpdate(void)
Function to update the variable SystemCoreClock.
static void Trap_Init(void)
do the init for trap
void Interrupt_Init(void)
initialize interrupt controller