System Device Configuration

group NMSIS_Core_SystemConfig

Functions for system and clock setup available in system_<device>.c.

Nuclei provides a template file system_Device.c that must be adapted by the silicon vendor to match their actual device. As a minimum requirement, this file must provide:

The file configures the device and, typically, initializes the oscillator (PLL) that is part of the microcontroller device. This file might export other functions or variables that provide a more flexible configuration of the microcontroller system.

And this file also provided common interrupt, exception and NMI exception handling framework template, Silicon vendor can customize these template code as they want.

Attention

Be aware that a value stored to SystemCoreClock during low level initialization (i.e. SystemInit()) might get overwritten by C libray startup code and/or .bss section initialization. Thus its highly recommended to call SystemCoreClockUpdate at the beginning of the user main() routine.

Note

Please pay special attention to the static variable SystemCoreClock. This variable might be used throughout the whole system initialization and runtime to calculate frequency/time related values. Thus one must assure that the variable always reflects the actual system clock speed.

Defines

FALLBACK_DEFAULT_ECLIC_BASE 0x0C000000UL
FALLBACK_DEFAULT_SYSTIMER_BASE 0x02000000UL
CLINT_MSIP(base, hartid) (*(volatile uint32_t *)((uintptr_t)((base) + ((hartid) * 4))))
SMP_CTRLREG(base, ofs) (*(volatile uint32_t *)((uintptr_t)((base) + (ofs))))

Typedefs

typedef void (*fnptr)(void)

Functions

void default_intexc_handler(void)

default eclic interrupt or exception interrupt handler

void SystemCoreClockUpdate(void)

Function to update the variable SystemCoreClock.

Updates the variable SystemCoreClock and must be called whenever the core clock is changed during program execution. The function evaluates the clock register settings and calculates the current core clock.

void SystemInit(void)

Function to Initialize the system.

Initializes the microcontroller system. Typically, this function configures the oscillator (PLL) that is part of the microcontroller device. For systems with a variable clock speed, it updates the variable SystemCoreClock. SystemInit is called from the file startup.

void SystemBannerPrint(void)

Banner Print for Nuclei SDK.

void ECLIC_Init(void)

initialize eclic config

ECLIC needs be initialized after boot up, Vendor could also change the initialization configuration.

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.

This function set vector mode, trigger mode and polarity, interrupt level and priority, assign handler for specific IRQn.

Remark

  • This function use to configure specific eclic interrupt and register its interrupt handler and enable its interrupt.

  • If the vector table is placed in read-only section(FLASHXIP mode), handler could not be installed

Parameters
  • IRQn[in] NMI interrupt handler address

  • shv[in] ECLIC_NON_VECTOR_INTERRUPT means non-vector mode, and ECLIC_VECTOR_INTERRUPT is vector mode

  • trig_mode[in] see ECLIC_TRIGGER_Type

  • lvl[in] interupt level

  • priority[in] interrupt priority

  • handler[in] interrupt handler, if NULL, handler will not be installed

Returns

-1 means invalid input parameter. 0 means successful.

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.

This function set vector mode, trigger mode and polarity, interrupt level and priority, assign handler for specific IRQn.

Remark

  • This function use to configure specific eclic S-mode interrupt and register its interrupt handler and enable its interrupt.

  • If the vector table is placed in read-only section (FLASHXIP mode), handler could not be installed.

Parameters
  • IRQn[in] NMI interrupt handler address

  • shv[in] ECLIC_NON_VECTOR_INTERRUPT means non-vector mode, and ECLIC_VECTOR_INTERRUPT is vector mode

  • trig_mode[in] see ECLIC_TRIGGER_Type

  • lvl[in] interupt level

  • priority[in] interrupt priority

  • handler[in] interrupt handler, if NULL, handler will not be installed

Returns

-1 means invalid input parameter. 0 means successful.

static void _get_iregion_info(IRegion_Info_Type *iregion)

Get Nuclei Internal Region Information.

This function is used to get nuclei cpu internal region information, such as iregion base, eclic base, smp base, timer base and idu base, and fallback to old evalsoc timer and eclic base if no iregion feature found

void __sync_harts(void)

Synchronize all harts.

This function is used to synchronize all the harts, especially to wait the boot hart finish initialization of data section, bss section and c runtines initialization This function must be placed in .text.init section, since section initialization is not ready, global variable and static variable should be avoid to use in this function, and avoid to call other functions

static void Trap_Init(void)

do the init for trap(interrupt and exception) entry for supervisor mode

This function provide initialization of CSR_STVT CSR_STVT2 and CSR_STVEC.

void _premain_init(void)

early init function before main

This function is executed right before main function. For RISC-V gnu toolchain, _init function might not be called by __libc_init_array function, so we defined a new function to do initialization.

void _postmain_fini(int status)

finish function after main

This function is executed right after main function. For RISC-V gnu toolchain, _fini function might not be called by __libc_fini_array function, so we defined a new function to do initialization

Parameters

status[in] status code return from main

void _init(void)

_init function called in __libc_init_array()

This __libc_init_array() function is called during startup code, user need to implement this function, otherwise when link it will error init.c:(.text.__libc_init_array+0x26): undefined reference to _init

Note

Please use _premain_init function now

void _fini(void)

_fini function called in __libc_fini_array()

This __libc_fini_array() function is called when exit main. user need to implement this function, otherwise when link it will error fini.c:(.text.__libc_fini_array+0x28): undefined reference to _fini

Note

Please use _postmain_fini function now

Variables

fnptr irq_entry_s

default entry for s-mode non-vector irq entry

fnptr exc_entry_s

default entry for s-mode exception entry

uint32_t SystemCoreClock = SYSTEM_CLOCK

Variable to hold the system core clock value.

Holds the system core clock, which is the system clock frequency supplied to the SysTick timer and the processor core clock. This variable can be used by debuggers to query the frequency of the debug timer or to configure the trace clock speed.

Attention

Compilers must be configured to avoid removing this variable in case the application program is not using it. Debugging systems require the variable to be physically present in memory so that it can be examined to configure the debugger.

IRegion_Info_Type SystemIRegionInfo

Nuclei RISC-V CPU IRegion Information Variable used to store probed info.

Interrupt Exception NMI Handling

group NMSIS_Core_IntExcNMI_Handling

Functions for interrupt, exception and nmi handle available in system_<device>.c.

Nuclei provide a template for interrupt, exception and NMI handling. Silicon Vendor could adapat according to their requirement. Silicon vendor could implement interface for different exception code and replace current implementation.

Defines

MAX_SYSTEM_EXCEPTION_NUM 26

Max exception handler number, don’t include the NMI(0xFFF) one.

Typedefs

typedef void (*EXC_HANDLER)(unsigned long cause, unsigned long sp)

Exception Handler Function Typedef.

Note

This typedef is only used internal in this system_<Device>.c file. It is used to do type conversion for registered exception handler before calling it.

Functions

static void system_default_exception_handler(unsigned long mcause, unsigned long sp)

System Default Exception Handler.

This function provides a default exception and NMI handler for all exception ids. By default, It will just print some information for debug, Vendor can customize it according to its requirements.

Parameters
  • mcause[in] code indicating the reason that caused the trap in machine mode

  • sp[in] stack pointer

static void Exception_Init(void)

Initialize all the default core exception handlers.

The core exception handler for each exception id will be initialized to system_default_exception_handler.

Note

Called in _init function, used to initialize default exception handlers for all exception IDs SystemExceptionHandlers contains NMI, but SystemExceptionHandlers_S not, because NMI can’t be delegated to S-mode.

void Exception_DumpFrame(unsigned long sp, uint8_t mode)

Dump Exception Frame.

This function provided feature to dump exception frame stored in stack.

Parameters
  • sp[in] stackpoint

  • mode[in] privileged mode to decide whether to dump msubm CSR

void Exception_Register_EXC(uint32_t EXCn, unsigned long exc_handler)

Register an exception handler for exception code EXCn.

  • For EXCn < MAX_SYSTEM_EXCEPTION_NUM, it will be registered into SystemExceptionHandlers[EXCn-1].

  • For EXCn == NMI_EXCn, it will be registered into SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM].

Parameters
  • EXCn[in] See EXCn_Type

  • exc_handler[in] The exception handler for this exception code EXCn

unsigned long Exception_Get_EXC(uint32_t EXCn)

Get current exception handler for exception code EXCn.

  • For EXCn < MAX_SYSTEM_EXCEPTION_NUM, it will return SystemExceptionHandlers[EXCn-1].

  • For EXCn == NMI_EXCn, it will return SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM].

Parameters

EXCn[in] See EXCn_Type

Returns

Current exception handler for exception code EXCn, if not found, return 0.

uint32_t core_exception_handler(unsigned long mcause, unsigned long sp)

Common NMI and Exception handler entry.

This function provided a command entry for NMI and exception. Silicon Vendor could modify this template implementation according to requirement.

Remark

  • RISCV provided common entry for all types of exception. This is proposed code template for exception entry function, Silicon Vendor could modify the implementation.

  • For the core_exception_handler template, we provided exception register function Exception_Register_EXC which can help developer to register your exception handler for specific exception number.

Parameters
  • mcause[in] code indicating the reason that caused the trap in machine mode

  • sp[in] stack pointer

static void system_default_exception_handler_s(unsigned long scause, unsigned long sp)

Supervisor mode system Default Exception Handler.

This function provided a default supervisor mode exception and NMI handling code for all exception ids. By default, It will just print some information for debug, Vendor can customize it according to its requirements.

Parameters
  • scause[in] code indicating the reason that caused the trap in supervisor mode

  • sp[in] stack pointer

void Exception_Register_EXC_S(uint32_t EXCn, unsigned long exc_handler)

Register an exception handler for exception code EXCn of supervisor mode.

-For EXCn < MAX_SYSTEM_EXCEPTION_NUM, it will be registered into SystemExceptionHandlers_S[EXCn-1]. -For EXCn == NMI_EXCn, The NMI (Non-maskable-interrupt) cannot be trapped to the supervisor-mode or user-mode for any configuration, so NMI won’t be registered into SystemExceptionHandlers_S.

Parameters
  • EXCn[in] See EXCn_Type

  • exc_handler[in] The exception handler for this exception code EXCn

unsigned long Exception_Get_EXC_S(uint32_t EXCn)

Get current exception handler for exception code EXCn of supervisor mode.

Parameters

EXCn[in] See EXCn_Type

Returns

Current exception handler for exception code EXCn, if not found, return 0.

uint32_t core_exception_handler_s(unsigned long scause, unsigned long sp)

common Exception handler entry of supervisor mode

This function provided a supervisor mode common entry for exception. Silicon Vendor could modify this template implementation according to requirement.

Remark

  • RISCV provided supervisor mode common entry for all types of exception. This is proposed code template for exception entry function, Silicon Vendor could modify the implementation.

  • For the core_exception_handler_s template, we provided exception register function Exception_Register_EXC_S which can help developer to register your exception handler for specific exception number.

Parameters
  • scause[in] code indicating the reason that caused the trap in supervisor mode

  • sp[in] stack pointer

Variables

static unsigned long SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM + 1]

Store the exception handlers for each exception ID.

Note

  • This SystemExceptionHandlers are used to store all the handlers for all the exception codes Nuclei N/NX core provided.

  • Exception code 0 - 25, totally 26 exceptions are mapped to SystemExceptionHandlers[0:25]

  • Exception for NMI is also re-routed to exception handling(exception code 0xFFF) in startup code configuration, the handler itself is mapped to SystemExceptionHandlers[MAX_SYSTEM_EXCEPTION_NUM]

static unsigned long SystemExceptionHandlers_S[MAX_SYSTEM_EXCEPTION_NUM]

Store the exception handlers for each exception ID in supervisor mode.

Note

  • This SystemExceptionHandlers_S are used to store all the handlers for all the exception codes Nuclei N/NX core provided.

  • Exception code 0 - 11, totally 12 exceptions are mapped to SystemExceptionHandlers_S[0:11]

  • The NMI (Non-maskable-interrupt) cannot be trapped to the supervisor-mode or user-mode for any configuration