Device Header File <Device.h>
Caution
Please be informed that the NMSIS-Core Device Templates may not be updated in a timely manner and thus could become outdated. We suggest referring to the specific implementation of evalsoc in the Nuclei SDK for the latest reference template. This reference template may not be actively maintained in the future.
- The Device Header File <Device.h> contains the following sections that are device specific:
Interrupt Number Definition provides interrupt numbers (IRQn) for all exceptions and interrupts of the device.
Configuration of the Processor and Core Peripherals reflect the features of the device.
Device Peripheral Access Layer provides definitions for the Peripheral Access to all device peripherals. It contains all data structures and the address mapping for device-specific peripherals.
Access Functions for Peripherals (optional) provide additional helper functions for peripherals that are useful for programming of these peripherals. Access Functions may be provided as inline functions or can be extern references to a device-specific library provided by the silicon vendor.
NMSIS Core API describes the standard features and functions of the Device Header File <Device.h> in detail.
Interrupt Number Definition
- Device Header File <Device.h> contains the enumeration
IRQn_Type
that defines all exceptions and interrupts of the device. Negative IRQn values represent processor core exceptions (internal interrupts).
Positive IRQn values represent device-specific exceptions (external interrupts). The first device-specific interrupt has the IRQn value 0. The IRQn values needs extension to reflect the device-specific interrupt vector table in the Startup File startup_<Device>.S.
The following example shows the extension of the interrupt vector table for the GD32VF103 device family.
1typedef enum IRQn {
2 /****** N200 Processor Exceptions Numbers *********************************************/
3 Reserved0_IRQn = 0, /*!< Internal reserved */
4 Reserved1_IRQn = 1, /*!< Internal reserved */
5 Reserved2_IRQn = 2, /*!< Internal reserved */
6 SysTimerSW_IRQn = 3, /*!< System Timer SW interrupt */
7 Reserved3_IRQn = 4, /*!< Internal reserved */
8 Reserved4_IRQn = 5, /*!< Internal reserved */
9 Reserved5_IRQn = 6, /*!< Internal reserved */
10 SysTimer_IRQn = 7, /*!< System Timer Interrupt */
11 Reserved6_IRQn = 8, /*!< Internal reserved */
12 Reserved7_IRQn = 9, /*!< Internal reserved */
13 Reserved8_IRQn = 10, /*!< Internal reserved */
14 Reserved9_IRQn = 11, /*!< Internal reserved */
15 Reserved10_IRQn = 12, /*!< Internal reserved */
16 Reserved11_IRQn = 13, /*!< Internal reserved */
17 Reserved12_IRQn = 14, /*!< Internal reserved */
18 Reserved13_IRQn = 15, /*!< Internal reserved */
19 Reserved14_IRQn = 16, /*!< Internal reserved */
20 HardFault_IRQn = 17, /*!< Hard Fault, storage access error */
21 Reserved15_IRQn = 18, /*!< Internal reserved */
22
23 /****** GD32VF103 Specific Interrupt Numbers ******************************************/
24 WWDGT_IRQn = 19, /*!< window watchDog timer interrupt */
25 LVD_IRQn = 20, /*!< LVD through EXTI line detect interrupt */
26 TAMPER_IRQn = 21, /*!< tamper through EXTI line detect */
27 : :
28 : :
29 CAN1_EWMC_IRQn = 85, /*!< CAN1 EWMC interrupt */
30 USBFS_IRQn = 86, /*!< USBFS global interrupt */
31 SOC_INT_MAX, /*!< Number of total Interrupts */
32} IRQn_Type;
Configuration of the Processor and Core Peripherals
The Device Header File <Device.h> configures the Nuclei N/NX/UX Class Processors and the core peripherals with
#define
that are set prior to including the file nmsis_core.h.
For recently released Nuclei 200/300/600/900 RISC-V CPU, the cpu private peripherals are also called internal regions(IREGION) and the address spaces are continuous with fixed size, cpu will be configured with only the base address of IREGION, such as ECLIC, TIMER, SMP, Cluster Cache, CIDU, PLIC unit, for more details, please check Nuclei ISA Spec and related CPU databook.
The following tables list the #define
along with the possible values for N200, N300, N600, NX600, UX600, N900, NX900, UX900, UX1000.
If these #define
are missing default values are used.
nmsis_core.h
Note
__NUCLEI_N_REV
and__NUCLEI_NX_REV
are deprecated since 1.2.0, please use__NUCLEI_CPU_REV
and__NUCLEI_CPU_SERIES
now.__HARTID_OFFSET
and__SYSTIMER_HARTID
is added since 1.2.0Please check Nuclei SDK evalsoc header file
evalsoc.h
for latest cpu macros.
#define |
Value Range |
Default |
Description |
__NUCLEI_N_REV OR
__NUCLEI_NX_REV
|
0x0100 |
0x0104
|
0x0100 |
|
__NUCLEI_CPU_REV |
Define Nuclei CPU Revision Number, such as 0x030A01 means v3.10.1. |
||
__NUCLEI_CPU_SERIES |
Define Nuclei CPU Series, such as 0x0200, 0x0300, 0x0600, 0x0900 for 200/300/600/900 series. |
||
__IREGION_BASEADDR |
Define Nuclei CPU Internal Region Base Address. |
||
__HARTID_OFFSET |
Define the offset of the first cpu hart’s hartid vs hart index, eg, cpu first hartid is 3, set it to 3. |
||
__SYSTIMER_PRESENT |
0 .. 1 |
1 |
Define whether Priviate System Timer is present or not. This SysTimer is a Memory Mapped Unit. |
__SYSTIMER_BASEADDR |
0x18030000 |
Base address of the System Timer Unit. |
|
__CLINT_TIMER_BASEADDR |
0x18040000 |
Base address of the CLINT compatiable timer in System Timer Unit. |
|
__SYSTIMER_HARTID |
Optional, if you cpu system only has one hart, and the timer hartid is known, you can set it to known value |
||
__SSTC_PRESENT |
0 .. 1 |
1 |
Define whether Sstc(Supervisor-mode Timer Interrupts) extension is present or not |
__ECLIC_PRESENT |
0 .. 1 |
1 |
Define whether Enhanced Core Local Interrupt Controller (ECLIC) Unit is present or not |
__ECLIC_BASEADDR |
0x18020000 |
Base address of the ECLIC unit. |
|
__CIDU_PRESENT |
0 .. 1 |
0 |
Define whether Cluster Interrupt Distribution Unit (CIDU) is present or not |
__CIDU_BASEADDR |
0x18050000 |
Base address of the CIDU unit. |
|
__ECLIC_INTCTLBITS |
1 .. 8 |
1 |
Define the number of hardware bits are actually implemented in the clicintctl registers. |
__ECLIC_INTNUM |
1 .. 1024 |
1 |
Define the total interrupt number(including the internal core interrupts) of ECLIC Unit |
__PLIC_PRESENT |
0 .. 1 |
0 |
Define whether Platform-Level Interrupt Controller (PLIC) Unit is present or not |
__PLIC_BASEADDR |
0x1C000000 |
Base address of the PLIC unit. |
|
__SMPCC_PRESENT |
0 .. 1 |
0 |
Define whether SMP and Cluster Cache Unit is present or not |
__SMPCC_BASEADDR |
0x18040000 |
Base address of the SMPCC unit. |
|
__PLIC_INTNUM |
1 .. 1024 |
1 |
Define the total external interrupt number of PLIC Unit |
__PMP_PRESENT |
0 .. 1 |
0 |
Define whether Physical Memory Protection (PMP) Unit is present or not. |
__PMP_ENTRY_NUM |
8 or 16 |
8 |
Define the numbers of PMP entries. |
__TEE_PRESENT |
0 .. 1 |
0 |
Define whether TEE Unit is present or not. |
__SPMP_PRESENT |
0 .. 1 |
0 |
Define whether SMode Physical Memory Protection (sPMP) Unit is present or not. |
__SPMP_ENTRY_NUM |
8 or 16 |
8 |
Define the numbers of sPMP entries. |
__SMPU_PRESENT |
0 .. 1 |
0 |
Define whether SMode Memory Protection Unit (sMPU) Unit is present or not. |
__SMPU_ENTRY_NUM |
8 or 16 |
8 |
Define the numbers of sMPU entries. |
__FPU_PRESENT |
0 .. 2 |
0 |
Define whether Floating Point Unit (FPU) is present or not.
|
__BITMANIP_PRESENT |
0 .. 1 |
0 |
Define whether Bitmainp Unit is present or not. |
__DSP_PRESENT |
0 .. 1 |
0 |
Define whether Digital Signal Processing Unit (DSP) is present or not. |
__VECTOR_PRESENT |
0 .. 1 |
0 |
Define whether Vector Unit is present or not. |
__ICACHE_PRESENT |
0 .. 1 |
0 |
Define whether I-Cache Unit is present or not. |
__DCACHE_PRESENT |
0 .. 1 |
0 |
Define whether D-Cache Unit is present or not. |
__CCM_PRESENT |
0 .. 1 |
0 |
Define whether Nuclei Cache Control and Mantainence Unit is present or not. |
__PMA_PRESENT |
0 .. 1 |
0 |
Define whether Physical memory attribute Unit is present or not. |
__PMA_CSR_NUM |
0 |
Define the numbers of PMA CSR Number. |
|
__PMA_SEC_CSR_NUM |
0 |
Define the numbers of PMA Secure CSR Number. |
|
__PMA_MACRO_PRESENT |
0 .. 1 |
0 |
Define whether Physical memory attribute rtl configuration macro is present or not. |
__HPM_PRESENT |
0 .. 1 |
0 |
Define whether High Performance Monitor(PMU) is present or not. |
__HPM_VER |
1 |
Define High Performance Monitor(PMU) version. |
|
__NICE_PRESENT |
0 .. 1 |
0 |
Define whether NICE is present or not. |
__VNICE_PRESENT |
0 .. 1 |
0 |
Define whether Vector NICE is present or not. |
__INC_INTRINSIC_API |
0 .. 1 |
0 |
Define whether toolchain provided intrinsic api headers are included or not. |
__Vendor_SysTickConfig |
0 .. 1 |
0 |
If __SYSTIMER_PRESENT is 1, then the __Vendor_SysTickConfig can be set to 0, otherwise it can only set to 1. If this define is set to 1, then the default SysTick_Config and SysTick_Reload function is excluded. In this case, the file Device.h must contain a vendor specific implementation of this function. |
NMSIS Version and Processor Information
The following shows the defines in the nmsis_core.h file that may be used in the NMSIS-Core Device Templates to verify a minimum version or ensure that the right Nuclei N/NX/U/UX class is used.
Device Peripheral Access Layer
- The Device Header File <Device.h> contains for each peripheral:
Register Layout Typedef
Base Address
Access Definitions
The section Peripheral Access shows examples for peripheral definitions.
Device.h Template File
Here we provided Device.h
template file as below:
1/******************************************************************************
2 * @file <Device>.h
3 * @brief NMSIS Core Peripheral Access Layer Header File for
4 * Nuclei Eval SoC which support Nuclei N/NX class cores
5 * @version V1.00
6 * @date 22. Nov 2019
7 ******************************************************************************/
8/*
9 * Copyright (c) 2019 Nuclei Limited. All rights reserved.
10 *
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the License); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 */
25
26#ifndef __<Device>_H__
27#define __<Device>_H__
28
29#include <stddef.h>
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35// NOTE: this cpufeature.h header file is introduced in Nuclei SDK 0.6.0
36#include "cpufeature.h"
37
38/** @addtogroup Nuclei
39 * @{
40 */
41
42
43/** @addtogroup <Device>
44 * @{
45 */
46
47
48/** @addtogroup Configuration_of_NMSIS
49 * @{
50 */
51
52/** \brief SoC Download mode definition */
53typedef enum {
54 DOWNLOAD_MODE_FLASHXIP = 0, /*!< Flashxip download mode */
55 DOWNLOAD_MODE_FLASH = 1, /*!< Flash download mode */
56 DOWNLOAD_MODE_ILM = 2, /*!< ilm download mode */
57 DOWNLOAD_MODE_DDR = 3, /*!< ddr download mode */
58 DOWNLOAD_MODE_SRAM = 4, /*!< sram download mode */
59 DOWNLOAD_MODE_SRAMXIP = 5, /*!< sramxip download mode */
60 DOWNLOAD_MODE_MAX,
61} DownloadMode_Type;
62
63// IRegion_Info_Type structure is removed in Nuclei SDK 0.6.0 release
64
65/* Simulation mode macros */
66#define SIMULATION_MODE_XLSPIKE 0 /*!< xlspike simulation mode */
67#define SIMULATION_MODE_QEMU 1 /*!< qemu simulation mode */
68
69/* =========================================================================================================================== */
70/* ================ Interrupt Number Definition ================ */
71/* =========================================================================================================================== */
72
73/* <Device>'s External IRQn ID is from the hard-wired persperctive, which has an offset mapped to the ECLIC IRQn.
74 eg.: uart0's external interrupt id in <Device> is 32, while its ECLIC IRQn is 51 */
75#define SOC_EXTERNAL_MAP_TO_ECLIC_IRQn_OFFSET 19
76/* get <Device>'s External IRQn from ECLIC external IRQn which indexs from 19 */
77#define IRQn_MAP_TO_EXT_ID(IRQn) (IRQn - SOC_EXTERNAL_MAP_TO_ECLIC_IRQn_OFFSET)
78
79typedef enum IRQn {
80 /* ======================================= Nuclei Core Specific Interrupt Numbers ======================================== */
81
82 Reserved0_IRQn = 0, /*!< Internal reserved */
83 SysTimerSW_S_IRQn = 1, /*!< System Timer supervisor mode SW interrupt triggered by ssip */
84 Reserved2_IRQn = 2, /*!< Internal reserved */
85 SysTimerSW_IRQn = 3, /*!< System Timer machine mode SW interrupt triggered by msip */
86 Reserved3_IRQn = 4, /*!< Internal reserved */
87 SysTimer_S_IRQn = 5, /*!< System Timer supervisor mode interrupt triggered by stimecmp csr */
88 Reserved5_IRQn = 6, /*!< Internal reserved */
89 SysTimer_IRQn = 7, /*!< System Timer machine mode interrupt triggered by mtimecmp */
90 Reserved6_IRQn = 8, /*!< Internal reserved */
91 Reserved7_IRQn = 9, /*!< Internal reserved */
92 Reserved8_IRQn = 10, /*!< Internal reserved */
93 Reserved9_IRQn = 11, /*!< Internal reserved */
94 Reserved10_IRQn = 12, /*!< Internal reserved */
95 Reserved11_IRQn = 13, /*!< Internal reserved */
96 Reserved12_IRQn = 14, /*!< Internal reserved */
97 Reserved13_IRQn = 15, /*!< Internal reserved */
98 InterCore_IRQn = 16, /*!< CIDU Inter Core Interrupt */
99 Reserved15_IRQn = 17, /*!< Internal reserved */
100 Reserved16_IRQn = 18, /*!< Internal reserved */
101
102 /* =========================================== <Device> Specific Interrupt Numbers ========================================= */
103 /* ToDo: add here your device specific external interrupt numbers. 19~1023 is reserved number for user. Maxmum interrupt supported
104 could get from clicinfo.NUM_INTERRUPT. According the interrupt handlers defined in startup_Device.s
105 eg.: Interrupt for Timer#1 eclic_tim1_handler -> TIM1_IRQn */
106 SOC_INT19_IRQn = 19, /*!< Device Interrupt */
107 SOC_INT20_IRQn = 20, /*!< Device Interrupt */
108 SOC_INT21_IRQn = 21, /*!< Device Interrupt */
109 SOC_INT22_IRQn = 22, /*!< Device Interrupt */
110 SOC_INT23_IRQn = 23, /*!< Device Interrupt */
111 SOC_INT24_IRQn = 24, /*!< Device Interrupt */
112 SOC_INT25_IRQn = 25, /*!< Device Interrupt */
113 SOC_INT26_IRQn = 26, /*!< Device Interrupt */
114 SOC_INT27_IRQn = 27, /*!< Device Interrupt */
115 SOC_INT28_IRQn = 28, /*!< Device Interrupt */
116 SOC_INT29_IRQn = 29, /*!< Device Interrupt */
117 SOC_INT30_IRQn = 30, /*!< Device Interrupt */
118 SOC_INT31_IRQn = 31, /*!< Device Interrupt */
119 SOC_INT32_IRQn = 32, /*!< Device Interrupt */
120 SOC_INT33_IRQn = 33, /*!< Device Interrupt */
121 SOC_INT34_IRQn = 34, /*!< Device Interrupt */
122 SOC_INT35_IRQn = 35, /*!< Device Interrupt */
123 SOC_INT36_IRQn = 36, /*!< Device Interrupt */
124 SOC_INT37_IRQn = 37, /*!< Device Interrupt */
125 SOC_INT38_IRQn = 38, /*!< Device Interrupt */
126 SOC_INT39_IRQn = 39, /*!< Device Interrupt */
127 SOC_INT40_IRQn = 40, /*!< Device Interrupt */
128 SOC_INT41_IRQn = 41, /*!< Device Interrupt */
129 SOC_INT42_IRQn = 42, /*!< Device Interrupt */
130 SOC_INT43_IRQn = 43, /*!< Device Interrupt */
131 SOC_INT44_IRQn = 44, /*!< Device Interrupt */
132 SOC_INT45_IRQn = 45, /*!< Device Interrupt */
133 SOC_INT46_IRQn = 46, /*!< Device Interrupt */
134 SOC_INT47_IRQn = 47, /*!< Device Interrupt */
135 SOC_INT48_IRQn = 48, /*!< Device Interrupt */
136 SOC_INT49_IRQn = 49, /*!< Device Interrupt */
137 SOC_INT50_IRQn = 50, /*!< Device Interrupt */
138 SOC_INT51_IRQn = 51, /*!< Device Interrupt */
139 SOC_INT52_IRQn = 52, /*!< Device Interrupt */
140 SOC_INT53_IRQn = 53, /*!< Device Interrupt */
141 SOC_INT54_IRQn = 54, /*!< Device Interrupt */
142 SOC_INT55_IRQn = 55, /*!< Device Interrupt */
143 SOC_INT56_IRQn = 56, /*!< Device Interrupt */
144 SOC_INT57_IRQn = 57, /*!< Device Interrupt */
145 SOC_INT58_IRQn = 58, /*!< Device Interrupt */
146 SOC_INT59_IRQn = 59, /*!< Device Interrupt */
147 SOC_INT60_IRQn = 60, /*!< Device Interrupt */
148 SOC_INT61_IRQn = 61, /*!< Device Interrupt */
149 SOC_INT62_IRQn = 62, /*!< Device Interrupt */
150 SOC_INT63_IRQn = 63, /*!< Device Interrupt */
151#if defined(CFG_IRQ_NUM)
152 SOC_INT_MAX = CFG_IRQ_NUM + SOC_EXTERNAL_MAP_TO_ECLIC_IRQn_OFFSET,
153#else
154 SOC_INT_MAX,
155#endif
156
157 PLIC_INT0_IRQn = 0,
158 PLIC_INT1_IRQn = 1,
159 PLIC_INT2_IRQn = 2,
160 PLIC_INT3_IRQn = 3,
161 PLIC_INT4_IRQn = 4,
162 PLIC_INT5_IRQn = 5,
163 PLIC_INT6_IRQn = 6,
164 PLIC_INT7_IRQn = 7,
165 PLIC_INT8_IRQn = 8,
166 PLIC_INT9_IRQn = 9,
167 PLIC_INT10_IRQn = 10,
168 PLIC_INT11_IRQn = 11,
169 PLIC_INT12_IRQn = 12,
170 PLIC_INT13_IRQn = 13,
171 PLIC_INT14_IRQn = 14,
172 PLIC_INT15_IRQn = 15,
173 PLIC_INT16_IRQn = 16,
174 PLIC_INT17_IRQn = 17,
175 PLIC_INT18_IRQn = 18,
176 PLIC_INT19_IRQn = 19,
177 PLIC_INT20_IRQn = 20,
178 PLIC_INT21_IRQn = 21,
179 PLIC_INT22_IRQn = 22,
180 PLIC_INT23_IRQn = 23,
181 PLIC_INT24_IRQn = 24,
182 PLIC_INT25_IRQn = 25,
183 PLIC_INT26_IRQn = 26,
184 PLIC_INT27_IRQn = 27,
185 PLIC_INT28_IRQn = 28,
186 PLIC_INT29_IRQn = 29,
187 PLIC_INT30_IRQn = 30,
188 PLIC_INT31_IRQn = 31,
189 PLIC_INT32_IRQn = 32,
190 PLIC_INT33_IRQn = 33,
191 PLIC_INT34_IRQn = 34,
192 PLIC_INT35_IRQn = 35,
193 PLIC_INT36_IRQn = 36,
194 PLIC_INT37_IRQn = 37,
195 PLIC_INT38_IRQn = 38,
196 PLIC_INT39_IRQn = 39,
197 PLIC_INT40_IRQn = 40,
198 PLIC_INT41_IRQn = 41,
199 PLIC_INT42_IRQn = 42,
200 PLIC_INT43_IRQn = 43,
201#if defined(CFG_IRQ_NUM)
202 PLIC_INIT_MAX = CFG_IRQ_NUM + 1,
203#else
204 PLIC_INIT_MAX,
205#endif
206} IRQn_Type;
207
208#if defined(CFG_IRQ_NUM) && (CFG_IRQ_NUM > 38)
209#define IRQn_OFFSET 0
210#else
211#define IRQn_OFFSET 32
212#endif
213
214#ifdef CFG_HAS_CLIC
215/* UART0 Interrupt */
216/* NOTE: Take care the external uart irq may not work, it require a correct <Device> cpu configuration */
217/* NOTE: For latest 200/300 cpu, this UART0_IRQn maybe SOC_INT19_IRQn */
218/* Please check Interrupts of Eval_SoC section in Nuclei_Processor_Integration_Guide.pdf */
219#define UART0_IRQn (SOC_INT51_IRQn - IRQn_OFFSET)
220/* QSPI Interrupt */
221#define QSPI0_IRQn (SOC_INT53_IRQn - IRQn_OFFSET)
222#define QSPI1_IRQn (SOC_INT54_IRQn - IRQn_OFFSET)
223#define QSPI2_IRQn (SOC_INT55_IRQn - IRQn_OFFSET)
224#else
225/* UART0 Interrupt */
226#define UART0_IRQn (PLIC_INT33_IRQn - IRQn_OFFSET)
227/* QSPI Interrupt */
228#define QSPI0_IRQn (PLIC_INT35_IRQn - IRQn_OFFSET)
229#define QSPI1_IRQn (PLIC_INT36_IRQn - IRQn_OFFSET)
230#define QSPI2_IRQn (PLIC_INT37_IRQn - IRQn_OFFSET)
231#endif
232
233#define PLIC_UART0_IRQn (PLIC_INT33_IRQn - IRQn_OFFSET)
234
235
236/* =========================================================================================================================== */
237/* ================ Exception Code Definition ================ */
238/* =========================================================================================================================== */
239
240typedef enum EXCn {
241 /* ======================================= Nuclei N/NX Specific Exception Code ======================================== */
242 InsUnalign_EXCn = 0, /*!< Instruction address misaligned */
243 InsAccFault_EXCn = 1, /*!< Instruction access fault */
244 IlleIns_EXCn = 2, /*!< Illegal instruction */
245 Break_EXCn = 3, /*!< Beakpoint */
246 LdAddrUnalign_EXCn = 4, /*!< Load address misaligned */
247 LdFault_EXCn = 5, /*!< Load access fault */
248 StAddrUnalign_EXCn = 6, /*!< Store or AMO address misaligned */
249 StAccessFault_EXCn = 7, /*!< Store or AMO access fault */
250 UmodeEcall_EXCn = 8, /*!< Environment call from User mode */
251 SmodeEcall_EXCn = 9, /*!< Environment call from S-mode */
252 MmodeEcall_EXCn = 11, /*!< Environment call from Machine mode */
253 InsPageFault_EXCn = 12, /*!< Instruction page fault */
254 LdPageFault_EXCn = 13, /*!< Load page fault */
255 StPageFault_EXCn = 15, /*!< Store or AMO page fault */
256 StackOverflow_EXCn = 24, /*!< Stack overflow fault */
257 StackUnderflow_EXCn = 25, /*!< Stack underflow fault */
258 NMI_EXCn = 0xfff, /*!< NMI interrupt */
259} EXCn_Type;
260
261/* =========================================================================================================================== */
262/* ================ Processor and Core Peripheral Section ================ */
263/* =========================================================================================================================== */
264// NOTE: macros __NUCLEI_CORE_REV/__NUCLEI_N_REV/__NUCLEI_NX_REV are removed now
265
266// NOTE: __FPU_PRESENT/__BITMANIP_PRESENT/__DSP_PRESENT/__VECTOR_PRESENT can be probed by compiler's -march= option
267// See https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Options.html
268
269/*!< Set to 0, 1, or 2, 0 not present, 1 single floating point unit present, 2 double floating point unit present */
270#if !defined(__riscv_flen)
271#define __FPU_PRESENT 0
272#elif __riscv_flen == 32
273#define __FPU_PRESENT 1
274#else
275#define __FPU_PRESENT 2
276#endif
277
278#if defined(__riscv_bitmanip)
279#define __BITMANIP_PRESENT 1 /*!< Set to 1 if Bitmainpulation extension is present */
280#else
281#define __BITMANIP_PRESENT 0 /*!< Set to 1 if Bitmainpulation extension is present */
282#endif
283#if defined(__riscv_dsp)
284#define __DSP_PRESENT 1 /*!< Set to 1 if Partial SIMD(DSP) extension is present */
285#else
286#define __DSP_PRESENT 0 /*!< Set to 1 if Partial SIMD(DSP) extension is present */
287#endif
288#if defined(__riscv_vector)
289#define __VECTOR_PRESENT 1 /*!< Set to 1 if Vector extension is present */
290#else
291#define __VECTOR_PRESENT 0 /*!< Set to 1 if Vector extension is present */
292#endif
293
294
295// CPU IREGION Private Peripherals Offset against IREGION base specified by mirgb_info CSR
296// These offset information can be found in selected cpu series databook's IREGION section.
297// mirgb_info CSR can be found in Nuclei RISC-V ISA Spec
298// You can also probe the cpu information using the general application/baremetal/cpuinfo case
299// You can find the offset macros(IREGION_*_OFS) in riscv_encoding.h via search IREGION Offsets
300
301// NORMAL CPU Configuration: From Nuclei SDK 0.6.0, we recommend you to update the CPU configuration macros defined in cpufeature.h
302// Please don't modify the macros below directly
303
304// NOTE: We use macros defined in cpufeature.h
305// WARNING: Please dont modify macros directly below, you can change in cpufeature.h
306
307// CPU Series and Version Configuration
308// To set CPU REV and SERIES, just define CFG_CPU_VER/CFG_CPU_SERIES macros in cpufeature.h
309#define __NUCLEI_CPU_REV CFG_CPU_VER /*!< Nuclei CPU Core Revision, version X.Y.Z, this is for the CPU Core Version, you get from Nuclei, eg. N300 v3.10.1, it should be 0x030A01 */
310#define __NUCLEI_CPU_SERIES CFG_CPU_SERIES /*!< Nuclei CPU Series, such as 200/300/600/900, eg. 900 will be 0x0900 */
311
312// CPU IREGION Base Address
313// To set IREGION base, just define macro CFG_IREGION_BASE_ADDR in cpufeature.h
314#ifndef CFG_IREGION_BASE_ADDR
315// it is defined in system_<Device>.c, you should not use this variable CpuIRegionBase
316// SystemIRegionInfo variable in previous release is removed, you should avoid to use it
317// you should use macro __IREGION_BASEADDR defined in <Device>.h
318extern volatile unsigned long CpuIRegionBase;
319#define CPU_IREGION_BASE CpuIRegionBase
320#else
321#define CPU_IREGION_BASE CFG_IREGION_BASE_ADDR
322#endif
323#define __IREGION_BASEADDR (CPU_IREGION_BASE)
324#define __IINFO_BASEADDR (__IREGION_BASEADDR + IREGION_IINFO_OFS)
325#define __IINFO_MPASIZE_OFS 0
326#define __IINFO_MPASIZE_ADDR (__IINFO_BASEADDR + __IINFO_MPASIZE_OFS)
327
328// ECLIC Configuration
329// To enable ECLIC, just define macro CFG_HAS_CLIC/CFG_CLICINTCTLBITS/CFG_IRQ_NUM in cpufeature.h
330#ifdef CFG_HAS_CLIC
331#define __ECLIC_PRESENT 1
332#ifdef CFG_CLICINTCTLBITS
333#define __ECLIC_INTCTLBITS CFG_CLICINTCTLBITS
334#endif
335#define __ECLIC_INTNUM (CFG_IRQ_NUM + SOC_EXTERNAL_MAP_TO_ECLIC_IRQn_OFFSET)
336#else
337#define __ECLIC_PRESENT 0
338#endif
339#define __ECLIC_BASEADDR (__IREGION_BASEADDR + IREGION_ECLIC_OFS)
340
341// PLIC Configuration
342// To enable PLIC, just define macro CFG_HAS_PLIC/CFG_IRQ_NUM in cpufeature.h
343#ifdef CFG_HAS_PLIC
344#define __PLIC_PRESENT 1
345#define __PLIC_INTNUM (CFG_IRQ_NUM + 1)
346#else
347#define __PLIC_PRESENT 0
348#endif
349#define __PLIC_BASEADDR (__IREGION_BASEADDR + IREGION_PLIC_OFS)
350
351// CPU System Timer Configuration
352// To enable CPU System Timer, just define macro CFG_TMR_PRIVATE in cpufeature.h
353#if defined(CFG_TMR_PRIVATE) || defined(CFG_TMR_BASE_ADDR)
354#define __SYSTIMER_PRESENT 1
355#else
356#define __SYSTIMER_PRESENT 0
357#endif
358#ifdef CFG_TMR_BASE_ADDR // Maybe using timer out of cpu for <Device>
359#define __SYSTIMER_BASEADDR (CFG_TMR_BASE_ADDR)
360#else
361#define __SYSTIMER_BASEADDR (__IREGION_BASEADDR + IREGION_TIMER_OFS)
362#endif
363#define __CLINT_TIMER_BASEADDR (__SYSTIMER_BASEADDR + 0x1000)
364
365// CPU System Timer SSTC Configuration
366#if defined(CFG_HAS_ISA_SSTC)
367#define __SSTC_PRESENT 1
368#else
369#define __SSTC_PRESENT 0
370#endif
371
372// CIDU Configuration
373// To enable CIDU, just define macro CFG_HAS_IDU in cpufeature.h
374#ifdef CFG_HAS_IDU
375#define __CIDU_PRESENT 1
376#else
377#define __CIDU_PRESENT 0
378#endif
379
380#define __CIDU_BASEADDR (__IREGION_BASEADDR + IREGION_IDU_OFS)
381
382// SMP & CC Configuration
383// To enable SMP & CC, just define macro CFG_HAS_SMP in cpufeature.h
384#ifdef CFG_HAS_SMP
385#define __SMPCC_PRESENT 1
386#else
387#define __SMPCC_PRESENT 0
388#endif
389
390#define __SMPCC_BASEADDR (__IREGION_BASEADDR + IREGION_SMP_OFS)
391
392// PMP Configuration
393// To enable PMP, just define macro CFG_HAS_PMP/__PMP_ENTRY_NUM in cpufeature.h
394#ifdef CFG_HAS_PMP
395#define __PMP_PRESENT 1
396#define __PMP_ENTRY_NUM CFG_PMP_ENTRY_NUM
397#else
398#define __PMP_PRESENT 0
399#define __PMP_ENTRY_NUM 0
400#endif
401
402// TEE/sPMP Configuration
403// To enable TEE, just define macro CFG_HAS_TEE in cpufeature.h
404// TEE required PMP, please also make sure CFG_HAS_PMP defined
405#ifdef CFG_HAS_TEE
406#define __TEE_PRESENT 1
407#define __SPMP_PRESENT 1
408#define __SPMP_ENTRY_NUM CFG_PMP_ENTRY_NUM
409#ifdef CFG_HAS_SMPU
410#define __SMPU_PRESENT 1
411#define __SMPU_ENTRY_NUM __SPMP_ENTRY_NUM
412#endif
413#else
414#define __TEE_PRESENT 0
415#define __SPMP_PRESENT 0
416#define __SMPU_PRESENT 0
417#define __SPMP_ENTRY_NUM 0
418#endif
419
420// ICache Configuration
421// To enable ICACHE, just define macro CFG_HAS_ICACHE in cpufeature.h
422#ifdef CFG_HAS_ICACHE
423#define __ICACHE_PRESENT 1
424#else
425#define __ICACHE_PRESENT 0
426#endif
427
428// DCache Configuration
429// To enable DCACHE, just define macro CFG_HAS_DCACHE in cpufeature.h
430#ifdef CFG_HAS_DCACHE
431#define __DCACHE_PRESENT 1
432#else
433#define __DCACHE_PRESENT 0
434#endif
435
436// CCM Configuration
437// To enable CCM, just define macro CFG_HAS_IOCC in cpufeature.h
438#ifdef CFG_HAS_IOCC
439#define __CCM_PRESENT 1
440#else
441#define __CCM_PRESENT 0
442#endif
443
444// PMA Configuration
445// To enable PMA, just define macro CFG_HAS_PMA in cpufeature.h
446#ifdef CFG_HAS_PMA
447#define __PMA_PRESENT 1
448#define __PMA_CSR_NUM CFG_PMA_CSR_NUM
449#define __PMA_SEC_CSR_NUM CFG_PMA_SEC_CSR_NUM
450
451#ifdef CFG_HAS_PMA_MACRO
452#define __PMA_MACRO_PRESENT 1
453#else
454#define __PMA_MACRO_PRESENT 0
455#endif
456#else
457#define __PMA_PRESENT 0
458#define __PMA_MACRO_PRESENT 0
459#endif
460
461// HPM Configuration
462// To enable HPM, just define macro CFG_HAS_HPM in cpufeature.h
463#ifdef CFG_HAS_HPM
464#define __HPM_PRESENT 1
465#define __HPM_VER CFG_HPM_VER
466#endif
467
468// SMODE Configuration
469// To enable S-Mode, just define macro CFG_HAS_SMODE in cpufeature.h
470#ifdef CFG_HAS_SMODE
471#define __SMODE_PRESENT 1
472#endif
473
474// NICE Configuration
475// To enable NICE, just define macro CFG_HAS_NICE in cpufeature.h
476#ifdef CFG_HAS_NICE
477#define __NICE_PRESENT 1
478#else
479#define __NICE_PRESENT 0
480#endif
481
482// VNICE Configuration
483// To enable Vector NICE, just define macro CFG_HAS_VNICE in cpufeature.h
484#ifdef CFG_HAS_VNICE
485#define __VNICE_PRESENT 1
486#else
487#define __VNICE_PRESENT 0
488#endif
489
490#ifndef __INC_INTRINSIC_API
491#define __INC_INTRINSIC_API 0 /*!< Set to 1 if intrinsic api header files need to be included */
492#endif
493
494#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
495#define __Vendor_EXCEPTION 0 /*!< Set to 1 if vendor exception hander is present */
496
497
498/*!< Set this timer hartid if you have only 1 hart in your cpu, and you know the timer hartid, just set it */
499//#define __SYSTIMER_HARTID 0
500
501
502#ifndef __HARTID_OFFSET
503/**
504 * If your hart index is different to your hartid, you must define this __HARTID_OFFSET macro.
505 * For example, if your cpu has 4 harts, and hartid start from 3, so the __HARTID_OFFSET should set to 3.
506 * Which means hartid 3-6 means hart index 0-3, this is useful for the timer software interrupt and timer interrupt trigger register location
507 */
508#define __HARTID_OFFSET 0
509#endif
510
511/* Define boot hart id */
512#ifndef BOOT_HARTID
513/**
514 * Choosen boot hart id in current cluster when in soc system, need to align with the value defined in startup_<Device>.S,
515 * should start from 0, taken the mhartid bit 0-7 value
516 */
517#define BOOT_HARTID 0
518#endif
519
520/** @} */ /* End of group Configuration_of_NMSIS */
521
522// NOTE: Run Mode Control internally used Nuclei
523// RUNMODE_* macros are defined in SoC/<Device>/runmode.mk, for internal usage not intend for widely usage
524#ifdef RUNMODE_IC_EN
525#undef __ICACHE_PRESENT
526#define __ICACHE_PRESENT RUNMODE_IC_EN /*!< Controlled by macro RUNMODE_IC_EN */
527#endif
528
529#ifdef RUNMODE_DC_EN
530#undef __DCACHE_PRESENT
531#define __DCACHE_PRESENT RUNMODE_DC_EN /*!< Controlled by macro RUNMODE_DC_EN */
532#endif
533
534#ifdef RUNMODE_CCM_EN
535#undef __CCM_PRESENT
536#define __CCM_PRESENT RUNMODE_CCM_EN /*!< Controlled by macro RUNMODE_CCM_EN */
537#endif
538
539#include <nmsis_core.h> /*!< Nuclei N/NX class processor and core peripherals */
540#include "system_<Device>.h" /*!< <Device> System */
541
542/* ======================================== Start of section using anonymous unions ======================================== */
543
544#ifdef <Device>_RTC_FREQ
545#define RTC_FREQ <Device>_RTC_FREQ
546#else
547#define RTC_FREQ 32768
548#endif
549// The TIMER frequency is just the RTC frequency
550#define SOC_TIMER_FREQ RTC_FREQ
551
552
553/* =========================================================================================================================== */
554/* ================ Device Specific Peripheral Section ================ */
555/* =========================================================================================================================== */
556
557
558/** @addtogroup Device_Peripheral_peripherals
559 * @{
560 */
561
562/****************************************************************************
563 * Platform definitions
564 *****************************************************************************/
565// Interrupt Numbers, will be removed in future, please use SOC_INT_MAX - SOC_EXTERNAL_MAP_TO_ECLIC_IRQn_OFFSET
566#define SOC_ECLIC_NUM_INTERRUPTS (SOC_INT_MAX - SOC_EXTERNAL_MAP_TO_ECLIC_IRQn_OFFSET)
567
568// Interrupt Handler Definitions
569#define SOC_MTIMER_HANDLER eclic_mtip_handler
570#define SOC_SOFTINT_HANDLER eclic_msip_handler
571
572/**
573 * @brief UART
574 */
575typedef struct {
576 __IOM uint32_t TXFIFO;
577 __IOM uint32_t RXFIFO;
578 __IOM uint32_t TXCTRL;
579 __IOM uint32_t RXCTRL;
580 __IOM uint32_t IE;
581 __IOM uint32_t IP;
582 __IOM uint32_t DIV;
583} UART_TypeDef;
584
585/**
586 * @brief QSPI
587 */
588typedef struct {
589 __IOM uint32_t SCKDIV;
590 __IOM uint32_t SCKMODE;
591 __IOM uint32_t RESERVED0[1];
592 __IOM uint32_t FORCE;
593 __IOM uint32_t CSID;
594 __IOM uint32_t CSDEF;
595 __IOM uint32_t CSMODE;
596 __IOM uint32_t VERSION;
597 __IOM uint32_t RESERVED1[2];
598 __IOM uint32_t DELAY0;
599 __IOM uint32_t DELAY1;
600 __IOM uint32_t RESERVED2[4];
601 __IOM uint32_t FMT;
602 __IOM uint32_t RESERVED3;
603 __IOM uint32_t TXDATA;
604 __IOM uint32_t RXDATA;
605 __IOM uint32_t TXMARK;
606 __IOM uint32_t RXMARK;
607 __IOM uint32_t RESERVED4[2];
608 __IOM uint32_t FCTRL;
609 __IOM uint32_t FFMT;
610 __IOM uint32_t RESERVED5[2];
611 __IOM uint32_t IE;
612 __IOM uint32_t IP;
613 __IOM uint32_t FFMT1;
614 __IOM uint32_t STATUS;
615} QSPI_TypeDef;
616
617/*@}*/ /* end of group <Device>_Peripherals */
618
619
620/* ========================================= End of section using anonymous unions ========================================= */
621
622/* Macros for memory access operations */
623#define _REG8P(p, i) ((volatile uint8_t *) ((uintptr_t)((p) + (i))))
624#define _REG16P(p, i) ((volatile uint16_t *) ((uintptr_t)((p) + (i))))
625#define _REG32P(p, i) ((volatile uint32_t *) ((uintptr_t)((p) + (i))))
626#define _REG64P(p, i) ((volatile uint64_t *) ((uintptr_t)((p) + (i))))
627#define _REG8(p, i) (*(_REG8P(p, i)))
628#define _REG16(p, i) (*(_REG16P(p, i)))
629#define _REG32(p, i) (*(_REG32P(p, i)))
630#define _REG64(p, i) (*(_REG64P(p, i)))
631#define REG8(addr) _REG8((addr), 0)
632#define REG16(addr) _REG16((addr), 0)
633#define REG32(addr) _REG32((addr), 0)
634#define REG64(addr) _REG64((addr), 0)
635
636/* Macros for address type convert and access operations */
637#define ADDR16(addr) ((uint16_t)(uintptr_t)(addr))
638#define ADDR32(addr) ((uint32_t)(uintptr_t)(addr))
639#define ADDR64(addr) ((uint64_t)(uintptr_t)(addr))
640#define ADDR8P(addr) ((uint8_t *)(uintptr_t)(addr))
641#define ADDR16P(addr) ((uint16_t *)(uintptr_t)(addr))
642#define ADDR32P(addr) ((uint32_t *)(uintptr_t)(addr))
643#define ADDR64P(addr) ((uint64_t *)(uintptr_t)(addr))
644
645/* Macros for Bit Operations */
646#if __riscv_xlen == 32
647#define BITMASK_MAX 0xFFFFFFFFUL
648#define BITOFS_MAX 31
649#else
650#define BITMASK_MAX 0xFFFFFFFFFFFFFFFFULL
651#define BITOFS_MAX 63
652#endif
653
654// BIT/BITS only support bit mask for __riscv_xlen
655// For RISC-V 32 bit, it support mask 32 bit wide
656// For RISC-V 64 bit, it support mask 64 bit wide
657#define BIT(ofs) (0x1UL << (ofs))
658#define BITS(start, end) ((BITMASK_MAX) << (start) & (BITMASK_MAX) >> (BITOFS_MAX - (end)))
659#define GET_BIT(regval, bitofs) (((regval) >> (bitofs)) & 0x1)
660#define SET_BIT(regval, bitofs) ((regval) |= BIT(bitofs))
661#define CLR_BIT(regval, bitofs) ((regval) &= (~BIT(bitofs)))
662#define FLIP_BIT(regval, bitofs) ((regval) ^= BIT(bitofs))
663#define WRITE_BIT(regval, bitofs, val) CLR_BIT(regval, bitofs); ((regval) |= ((val) << bitofs) & BIT(bitofs))
664#define CHECK_BIT(regval, bitofs) (!!((regval) & (0x1UL<<(bitofs))))
665#define GET_BITS(regval, start, end) (((regval) & BITS((start), (end))) >> (start))
666#define SET_BITS(regval, start, end) ((regval) |= BITS((start), (end)))
667#define CLR_BITS(regval, start, end) ((regval) &= (~BITS((start), (end))))
668#define FLIP_BITS(regval, start, end) ((regval) ^= BITS((start), (end)))
669#define WRITE_BITS(regval, start, end, val) CLR_BITS(regval, start, end); ((regval) |= ((val) << start) & BITS((start), (end)))
670#define CHECK_BITS_ALL(regval, start, end) (!((~(regval)) & BITS((start), (end))))
671#define CHECK_BITS_ANY(regval, start, end) ((regval) & BITS((start), (end)))
672
673#define BITMASK_SET(regval, mask) ((regval) |= (mask))
674#define BITMASK_CLR(regval, mask) ((regval) &= (~(mask)))
675#define BITMASK_FLIP(regval, mask) ((regval) ^= (mask))
676#define BITMASK_CHECK_ALL(regval, mask) (!((~(regval)) & (mask)))
677#define BITMASK_CHECK_ANY(regval, mask) ((regval) & (mask))
678
679/* =========================================================================================================================== */
680/* ================ Device Specific Peripheral Address Map ================ */
681/* =========================================================================================================================== */
682
683/* ToDo: add here your device peripherals base addresses
684 following is an example for timer */
685/** @addtogroup Device_Peripheral_peripheralAddr
686 * @{
687 */
688/* ILM/DLM/FLASHXIP and Peripheral base address */
689#ifndef <Device>_FLASH_XIP_BASE
690#define QSPI_FLASH_BASE (0x20000000UL) /*!< (FLASH ) Base Address */
691#else
692#define QSPI_FLASH_BASE (<Device>_FLASH_XIP_BASE) /*!< (FLASH ) Base Address */
693#endif
694
695#ifndef CFG_ILM_BASE_ADDR
696#define ONCHIP_ILM_BASE (0x80000000UL) /*!< (ILM ) Base Address */
697#else
698#define ONCHIP_ILM_BASE (CFG_ILM_BASE_ADDR) /*!< (ILM ) Base Address */
699#endif
700
701#ifndef CFG_DLM_BASE_ADDR
702#define ONCHIP_DLM_BASE (0x90000000UL) /*!< (DLM ) Base Address */
703#else
704#define ONCHIP_DLM_BASE (CFG_DLM_BASE_ADDR) /*!< (DLM ) Base Address */
705#endif
706
707#ifndef <Device>_SYSMEM_BASE
708#define ONCHIP_SRAM_BASE (0xA0000000UL) /*!< (SRAM ) Base Address */
709#else
710#define ONCHIP_SRAM_BASE (<Device>_SYSMEM_BASE) /*!< (SRAM ) Base Address */
711#endif
712
713#ifndef <Device>_PERIPS_BASE
714#define <Device>_PERIPH_BASE (0x10000000UL) /*!< (Peripheral) Base Address */
715#else
716#define <Device>_PERIPH_BASE (<Device>_PERIPS_BASE) /*!< (Peripheral) Base Address */
717#endif
718
719/* Peripheral memory map */
720#define UART0_BASE (<Device>_PERIPH_BASE + 0x13000) /*!< (UART0) Base Address */
721#define QSPI0_BASE (<Device>_PERIPH_BASE + 0x14000) /*!< (QSPI0) Base Address */
722#define UART1_BASE (<Device>_PERIPH_BASE + 0x23000) /*!< (UART1) Base Address */
723#define QSPI1_BASE (<Device>_PERIPH_BASE + 0x24000) /*!< (QSPI1) Base Address */
724#define QSPI2_BASE (<Device>_PERIPH_BASE + 0x34000) /*!< (QSPI2) Base Address */
725
726/** @} */ /* End of group Device_Peripheral_peripheralAddr */
727
728
729/* =========================================================================================================================== */
730/* ================ Peripheral declaration ================ */
731/* =========================================================================================================================== */
732
733
734/* ToDo: add here your device peripherals pointer definitions
735 following is an example for timer */
736/** @addtogroup Device_Peripheral_declaration
737 * @{
738 */
739#define UART0 ((UART_TypeDef *) UART0_BASE)
740#define QSPI0 ((QSPI_TypeDef *) QSPI0_BASE)
741#define UART1 ((UART_TypeDef *) UART1_BASE)
742#define QSPI1 ((QSPI_TypeDef *) QSPI1_BASE)
743#define QSPI2 ((QSPI_TypeDef *) QSPI2_BASE)
744
745#define SPI0_REG(offset) _REG32(QSPI0_BASE, offset)
746#define SPI1_REG(offset) _REG32(QSPI1_BASE, offset)
747#define SPI2_REG(offset) _REG32(QSPI2_BASE, offset)
748#define UART0_REG(offset) _REG32(UART0_BASE, offset)
749#define UART1_REG(offset) _REG32(UART1_BASE, offset)
750
751// Misc
752
753// Only used by Nuclei Internally, please dont use it
754#define SIMULATION_EXIT(ret) { __WMB(); UART0->RXFIFO = (ret); \
755 while (UART0->TXFIFO & (1<<31)); \
756 UART0->TXFIFO = 4; }
757
758extern uint32_t get_cpu_freq(void);
759extern void delay_1ms(uint32_t count);
760
761/** @} */ /* End of group <Device> */
762
763/** @} */ /* End of group Nuclei */
764
765#ifdef __cplusplus
766}
767#endif
768
769#endif /* __<Device>_H__ */