28 #include "nuclei_sdk_hal.h"
39 #define SYSTEM_CLOCK (16000000UL)
75 #if (defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1))
82 #if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1)
93 extern void eclic_ssip_handler(
void)
__WEAK;
95 extern void eclic_stip_handler(
void)
__WEAK;
106 #define __SMODE_VECTOR_ATTR __attribute__((section (".text.vtable_s"), aligned(512)))
108 #define __SMODE_VECTOR_ATTR __attribute__((section (".sintvec"), aligned(512)))
126 const unsigned long vector_table_s[
SOC_INT_MAX] __SMODE_VECTOR_ATTR =
129 #if defined(__SSTC_PRESENT) && __SSTC_PRESENT == 1
130 (
unsigned long)(eclic_ssip_handler),
136 (
unsigned long)(eclic_ssip_handler),
139 #if defined(__SSTC_PRESENT) && __SSTC_PRESENT == 1
140 (
unsigned long)(eclic_stip_handler),
147 (
unsigned long)(eclic_stip_handler),
239 typedef void (*
EXC_HANDLER)(
unsigned long cause,
unsigned long sp);
240 typedef void (*
INT_HANDLER)(
unsigned long cause,
unsigned long sp);
243 #define MAX_SYSTEM_EXCEPTION_NUM 20
254 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
258 #define SYSTEM_CORE_INTNUM 16
274 #if (defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1))
282 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
296 #if defined(CODESIZE) && (CODESIZE == 1)
299 EXC_Frame_Type *exc_frame = (EXC_Frame_Type *)sp;
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);
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);
318 NSDK_DEBUG(
"msubm: 0x%lx\n", exc_frame->msubm);
333 #if defined(CODESIZE) && (CODESIZE == 1)
336 NSDK_DEBUG(
"MCAUSE : 0x%lx\r\n", mcause);
340 NSDK_DEBUG(
"HARTID : %u\r\n", (
unsigned int)
__get_hart_id());
342 #if defined(SIMULATION_MODE)
344 extern void simulation_exit(
int status);
359 #if defined(CODESIZE) && (CODESIZE == 1)
362 NSDK_DEBUG(
"Trap in Interrupt\r\n");
363 NSDK_DEBUG(
"MCAUSE: 0x%lx\r\n", mcause);
385 if (int_handler != NULL) {
386 int_handler(exccode, sp);
408 #if defined(CODESIZE) && (CODESIZE == 1)
425 }
else if (exccode == NMI_EXCn) {
430 if (exc_handler != NULL) {
431 exc_handler(mcause, sp);
448 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
451 if (irqn < __PLIC_INTNUM) {
453 if (int_handler != NULL) {
454 int_handler(exccode, sp);
504 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
505 if ((irqn < __PLIC_INTNUM) && (irqn >= 0)) {
521 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
522 if ((irqn < __PLIC_INTNUM) && (irqn >= 0)) {
540 #if defined(CODESIZE) && (CODESIZE == 1)
545 }
else if (EXCn == NMI_EXCn) {
561 #if defined(CODESIZE) && (CODESIZE == 1)
566 }
else if (EXCn == NMI_EXCn) {
584 #if defined(CODESIZE) && (CODESIZE == 1)
592 #if (defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1))
600 #if (defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1))
611 #if defined(CODESIZE) && (CODESIZE == 1)
614 NSDK_DEBUG(
"SCAUSE : 0x%lx\r\n", scause);
619 #if defined(SIMULATION_MODE)
621 extern void simulation_exit(
int status);
636 #if defined(CODESIZE) && (CODESIZE == 1)
639 NSDK_DEBUG(
"Trap in S-Mode Interrupt\r\n");
640 NSDK_DEBUG(
"SCAUSE: 0x%lx\r\n", scause);
660 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
663 if (int_handler != NULL) {
664 int_handler(exccode, sp);
678 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
681 if (irqn < __PLIC_INTNUM) {
683 if (int_handler != NULL) {
684 int_handler(exccode, sp);
706 #if defined(CODESIZE) && (CODESIZE == 1)
724 if (exc_handler != NULL) {
725 exc_handler(scause, sp);
743 #if defined(CODESIZE) && (CODESIZE == 1)
760 #if defined(CODESIZE) && (CODESIZE == 1)
814 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
815 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
816 if ((irqn < __PLIC_INTNUM) && (irqn >= 0)) {
833 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
834 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
835 if ((irqn < __PLIC_INTNUM) && (irqn >= 0)) {
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);
855 NSDK_DEBUG(
"CPU HartID: %u\r\n", (
unsigned int)
__get_hart_id());
860 #if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1)
881 #if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1)
882 unsigned long mcfg_info;
898 #if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1)
941 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
950 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
966 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
968 for (i = 0; i < __PLIC_INTNUM; i++) {
970 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
977 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
999 #if defined(CODESIZE) && (CODESIZE == 1)
1007 #if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1)
1009 #elif defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
1016 #if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1)
1048 if (handler != NULL) {
1075 if (handler != NULL) {
1093 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
1111 if (handler != NULL) {
1116 case SysTimerSW_S_IRQn:
1119 case SysTimer_S_IRQn:
1130 #if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1)
1145 if ((source >= __PLIC_INTNUM)) {
1151 if (handler != NULL) {
1161 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
1176 if ((source >= __PLIC_INTNUM)) {
1182 if (handler != NULL) {
1194 #if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1)
1226 if (handler != NULL) {
1239 #ifndef CFG_IREGION_BASE_ADDR
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))))
1263 #if defined(SMP_CPU_CNT) && (SMP_CPU_CNT > 1)
1266 unsigned long clint_base, irgb_base, smp_base;
1267 unsigned long mcfg_info;
1292 if (hartid == BOOT_HARTID) {
1294 for (
int i = 0; i < SMP_CPU_CNT; i ++) {
1303 while (
CLINT_MSIP(clint_base, tmr_hartid) == 1);
1326 #if defined(CODESIZE) && (CODESIZE == 1)
1332 #ifndef CFG_IREGION_BASE_ADDR
1338 uart_init(SOC_DEBUG_UART, 115200);
1349 #if defined(RUNMODE_ILM_EN) || defined(RUNMODE_ECC_EN)
1352 #if defined(RUNMODE_ECC_EN)
1353 #if RUNMODE_ECC_EN == 0
1359 #if defined(RUNMODE_ILM_EN)
1360 #if RUNMODE_ILM_EN == 0
1369 #if defined(RUNMODE_DLM_EN) || defined(RUNMODE_ECC_EN)
1372 #if defined(RUNMODE_ECC_EN)
1373 #if RUNMODE_ECC_EN == 0
1379 #if defined(RUNMODE_DLM_EN)
1380 #if RUNMODE_DLM_EN == 0
1389 #if defined(RUNMODE_LDSPEC_EN)
1390 #if RUNMODE_LDSPEC_EN == 1
1402 #if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1)
1404 #if defined(RUNMODE_ECC_EN)
1405 #if RUNMODE_ECC_EN == 0
1414 #if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1)
1416 #if defined(RUNMODE_ECC_EN)
1417 #if RUNMODE_ECC_EN == 0
1432 #ifndef CFG_IREGION_BASE_ADDR
1433 if (hartid == BOOT_HARTID) {
1442 #if defined(RUNMODE_L2_EN)
1443 if ((mcfginfo & (0x1 << 11)) &&
SMP_CTRLREG(__SMPCC_BASEADDR, 0x4) & 0x1 ) {
1444 #if RUNMODE_L2_EN == 1
1459 #if defined(RUNMODE_BPU_EN)
1460 #if RUNMODE_BPU_EN == 1
1467 #if defined(__CCM_PRESENT) && (__CCM_PRESENT == 1)
1469 #if defined(CFG_HAS_SMODE) || defined(CFG_HAS_UMODE)
1474 if (hartid == BOOT_HARTID) {
1478 uart_init(SOC_DEBUG_UART, 115200);
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);
1491 if (mcfginfo & 0x180 == 0x180) {
1492 NSDK_DEBUG(
"CSR: MILM_CTL 0x%x, MDLM_CTL 0x%x\n", \
1496 if (mcfginfo & 0x600) {
1520 #if defined(CODESIZE) && (CODESIZE == 1)
1521 #ifdef CFG_SIMULATION
1522 SIMULATION_EXIT(status);
1526 extern void simulation_exit(
int status);
1527 simulation_exit(status);
#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 MCACHE_CTL_DC_ECC_EN
#define MILM_CTL_ILM_ECC_EXCP_EN
#define MCFG_INFO_IREGION_EXIST
#define MILM_CTL_ILM_ECC_CHK_EN
#define MMISC_CTL_LDSPEC_ENABLE
#define MCACHE_CTL_IC_ECC_EXCP_EN
#define MCACHE_CTL_IC_ECC_CHK_EN
#define IREGION_TIMER_OFS
#define MCACHE_CTL_DC_ECC_EXCP_EN
#define MCACHE_CTL_IC_ECC_EN
#define MDLM_CTL_DLM_ECC_EXCP_EN
#define MDLM_CTL_DLM_ECC_EN
__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.
__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 ...
#define __WEAK
restrict pointer qualifier to enable additional optimizations.
__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_SetPriorityIRQ_S
#define ECLIC_SetTrigIRQ_S
#define ECLIC_SetPriorityIRQ
IRQn_Type
Definition of IRQn numbers.
#define ECLIC_SetShvIRQ_S
#define ECLIC_SetCfgNlbits
#define ECLIC_SetLevelIRQ
#define ECLIC_SetVector_S
#define ECLIC_EnableIRQ_S
#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_s(void)
default entry for s-mode non-vector irq entry
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 _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