1 /*
2 * Copyright (C) 2017-2019 Alibaba Group Holding Limited
3 */
4
5
6 /******************************************************************************
7 * @file core_rv32.h
8 * @brief CSI RV32 Core Peripheral Access Layer Header File
9 * @version V1.0
10 * @date 01. Sep 2018
11 ******************************************************************************/
12
13 #ifndef __CORE_RV32_H_GENERIC
14 #define __CORE_RV32_H_GENERIC
15
16 #include <stdint.h>
17
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21
22 /*******************************************************************************
23 * CSI definitions
24 ******************************************************************************/
25 /**
26 \ingroup RV32
27 @{
28 */
29
30 #ifndef __RV32
31 #define __RV32 (0x01U)
32 #endif
33
34 /** __FPU_USED indicates whether an FPU is used or not.
35 This core does not support an FPU at all
36 */
37 #define __FPU_USED 0U
38
39 #if defined ( __GNUC__ )
40 #if defined (__VFP_FP__) && !defined(__SOFTFP__)
41 #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
42 #endif
43 #endif
44
45 #ifdef __cplusplus
46 }
47 #endif
48
49 #endif /* __CORE_RV32_H_GENERIC */
50
51 #ifndef __CSI_GENERIC
52
53 #ifndef __CORE_RV32_H_DEPENDANT
54 #define __CORE_RV32_H_DEPENDANT
55
56 #ifdef __cplusplus
57 extern "C" {
58 #endif
59
60 /* check device defines and use defaults */
61 #ifndef __RV32_REV
62 #define __RV32_REV 0x0000U
63 #endif
64
65 #ifndef __VIC_PRIO_BITS
66 #define __VIC_PRIO_BITS 2U
67 #endif
68
69 #ifndef __Vendor_SysTickConfig
70 #define __Vendor_SysTickConfig 1U
71 #endif
72
73 #ifndef __MPU_PRESENT
74 #define __MPU_PRESENT 1U
75 #endif
76
77 #ifndef __ICACHE_PRESENT
78 #define __ICACHE_PRESENT 1U
79 #endif
80
81 #ifndef __DCACHE_PRESENT
82 #define __DCACHE_PRESENT 1U
83 #endif
84
85 #include <csi_rv32_gcc.h>
86
87 /* IO definitions (access restrictions to peripheral registers) */
88 /**
89 \defgroup CSI_glob_defs CSI Global Defines
90
91 <strong>IO Type Qualifiers</strong> are used
92 \li to specify the access to peripheral variables.
93 \li for automatic generation of peripheral register debug information.
94 */
95 #ifdef __cplusplus
96 #define __I volatile /*!< Defines 'read only' permissions */
97 #else
98 #define __I volatile const /*!< Defines 'read only' permissions */
99 #endif
100 #define __O volatile /*!< Defines 'write only' permissions */
101 #define __IO volatile /*!< Defines 'read / write' permissions */
102
103 /* following defines should be used for structure members */
104 #define __IM volatile const /*! Defines 'read only' structure member permissions */
105 #define __OM volatile /*! Defines 'write only' structure member permissions */
106 #define __IOM volatile /*! Defines 'read / write' structure member permissions */
107
108 /*@} end of group CK802 */
109
110 /*******************************************************************************
111 * Register Abstraction
112 Core Register contain:
113 - Core Register
114 - Core CLIC Register
115 ******************************************************************************/
116 /**
117 \defgroup CSI_core_register Defines and Type Definitions
118 \brief Type definitions and defines for CK80X processor based devices.
119 */
120
121 /**
122 \ingroup CSI_core_register
123 \defgroup CSI_CORE Status and Control Registers
124 \brief Core Register type definitions.
125 @{
126 */
127
128 /**
129 \ingroup CSI_core_register
130 \defgroup CSI_CLIC Core-Local Interrupt Controller (CLIC)
131 \brief Type definitions for the CLIC Registers
132 @{
133 */
134
135 /**
136 \brief Access to the structure of a vector interrupt controller.
137 */
138 typedef struct {
139 __IOM uint8_t IP; /*!< Offset: 0x000 (R/W) Interrupt set pending register */
140 __IOM uint8_t IE; /*!< Offset: 0x004 (R/W) Interrupt set enable register */
141 __IOM uint8_t ATTR; /*!< Offset: 0x008 (R/W) Interrupt set attribute register */
142 __IOM uint8_t CTL; /*!< Offset: 0x00C (R/W) Interrupt control register */
143 } CLIC_INT_Control;
144
145 typedef struct {
146 __IOM uint32_t CLICCFG:8; /*!< Offset: 0x000 (R/W) CLIC configure register */
147 __IM uint32_t CLICINFO;
148 __IOM uint32_t MINTTHRESH;
149 uint32_t RESERVED[1021];
150 CLIC_INT_Control CLICINT[4096];
151 } CLIC_Type;
152
153 #define CLIC_INFO_CLICINTCTLBITS_Pos 21U
154 #define CLIC_INFO_CLICINTCTLBITS_Msk (0xFUL << CLIC_INFO_CLICINTCTLBITS_Pos)
155
156 #define CLIC_INTIP_IP_Pos 0U /*!< CLIC INTIP: IP Position */
157 #define CLIC_INTIP_IP_Msk (0x1UL << CLIC_INTIP_IP_Pos) /*!< CLIC INTIP: IP Mask */
158
159 #define CLIC_INTIE_IE_Pos 0U /*!< CLIC INTIE: IE Position */
160 #define CLIC_INTIE_IE_Msk (0x1UL << CLIC_INTIE_IE_Pos) /*!< CLIC INTIE: IE Mask */
161
162 #define CLIC_INTIE_T_Pos 7U /*!< CLIC INTIE: T Position */
163 #define CLIC_INTIE_T_Msk (0x1UL << CLIC_INTIE_T_Pos) /*!< CLIC INTIE: T Mask */
164
165 #define CLIC_INTATTR_TRIG_Pos 1U /*!< CLIC INTATTR: TRIG Position */
166 #define CLIC_INTATTR_TRIG_Msk (0x3UL << CLIC_INTATTR_TRIG_Pos) /*!< CLIC INTATTR: TRIG Mask */
167
168 #define CLIC_INTATTR_SHV_Pos 0U /*!< CLIC INTATTR: SHV Position */
169 #define CLIC_INTATTR_SHV_Msk (0x1UL << CLIC_INTATTR_SHV_Pos) /*!< CLIC INTATTR: SHV Mask */
170
171 #define CLIC_INTCFG_NVBIT_Pos 5U /*!< CLIC INTCFG: NVBIT Position */
172 #define CLIC_INTCFG_NVBIT_Msk (0x1UL << CLIC_INTCFG_NVBIT_Pos) /*!< CLIC INTCFG: NVBIT Mask */
173
174 #define CLIC_INTCFG_PRIO_Pos 5U /*!< CLIC INTCFG: INTCFG Position */
175 #define CLIC_INTCFG_PRIO_Msk (0x7UL << CLIC_INTCFG_PRIO_Pos) /*!< CLIC INTCFG: INTCFG Mask */
176
177 #define CLIC_CLICCFG_NVBIT_Pos 0U /*!< CLIC CLICCFG: NVBIT Position */
178 #define CLIC_CLICCFG_NVBIT_Msk (0x1UL << CLIC_CLICCFG_NVBIT_Pos) /*!< CLIC CLICCFG: NVBIT Mask */
179
180 #define CLIC_CLICCFG_NLBIT_Pos 1U /*!< CLIC CLICCFG: NLBIT Position */
181 #define CLIC_CLICCFG_NLBIT_Msk (0xFUL << CLIC_CLICCFG_NLBIT_Pos) /*!< CLIC CLICCFG: NLBIT Mask */
182
183 #define CLIC_CLICCFG_NMBIT_Pos 5U /*!< CLIC CLICCFG: NMBIT Position */
184 #define CLIC_CLICCFG_NMBIT_Msk (0x3UL << CLIC_CLICCFG_NMBIT_Pos) /*!< CLIC CLICCFG: NMBIT Mask */
185
186 /*@} end of group CSI_CLIC */
187
188 /**
189 \ingroup CSI_core_register
190 \defgroup CSI_PMP Physical Memory Protection (PMP)
191 \brief Type definitions for the PMP Registers
192 @{
193 */
194
195 #define PMP_PMPCFG_R_Pos 0U /*!< PMP PMPCFG: R Position */
196 #define PMP_PMPCFG_R_Msk (0x1UL << PMP_PMPCFG_R_Pos) /*!< PMP PMPCFG: R Mask */
197
198 #define PMP_PMPCFG_W_Pos 1U /*!< PMP PMPCFG: W Position */
199 #define PMP_PMPCFG_W_Msk (0x1UL << PMP_PMPCFG_W_Pos) /*!< PMP PMPCFG: W Mask */
200
201 #define PMP_PMPCFG_X_Pos 2U /*!< PMP PMPCFG: X Position */
202 #define PMP_PMPCFG_X_Msk (0x1UL << PMP_PMPCFG_X_Pos) /*!< PMP PMPCFG: X Mask */
203
204 #define PMP_PMPCFG_A_Pos 3U /*!< PMP PMPCFG: A Position */
205 #define PMP_PMPCFG_A_Msk (0x3UL << PMP_PMPCFG_A_Pos) /*!< PMP PMPCFG: A Mask */
206
207 #define PMP_PMPCFG_L_Pos 7U /*!< PMP PMPCFG: L Position */
208 #define PMP_PMPCFG_L_Msk (0x1UL << PMP_PMPCFG_L_Pos) /*!< PMP PMPCFG: L Mask */
209
210 typedef enum {
211 REGION_SIZE_4B = -1,
212 REGION_SIZE_8B = 0,
213 REGION_SIZE_16B = 1,
214 REGION_SIZE_32B = 2,
215 REGION_SIZE_64B = 3,
216 REGION_SIZE_128B = 4,
217 REGION_SIZE_256B = 5,
218 REGION_SIZE_512B = 6,
219 REGION_SIZE_1KB = 7,
220 REGION_SIZE_2KB = 8,
221 REGION_SIZE_4KB = 9,
222 REGION_SIZE_8KB = 10,
223 REGION_SIZE_16KB = 11,
224 REGION_SIZE_32KB = 12,
225 REGION_SIZE_64KB = 13,
226 REGION_SIZE_128KB = 14,
227 REGION_SIZE_256KB = 15,
228 REGION_SIZE_512KB = 16,
229 REGION_SIZE_1MB = 17,
230 REGION_SIZE_2MB = 18,
231 REGION_SIZE_4MB = 19,
232 REGION_SIZE_8MB = 20,
233 REGION_SIZE_16MB = 21,
234 REGION_SIZE_32MB = 22,
235 REGION_SIZE_64MB = 23,
236 REGION_SIZE_128MB = 24,
237 REGION_SIZE_256MB = 25,
238 REGION_SIZE_512MB = 26,
239 REGION_SIZE_1GB = 27,
240 REGION_SIZE_2GB = 28,
241 REGION_SIZE_4GB = 29,
242 REGION_SIZE_8GB = 30,
243 REGION_SIZE_16GB = 31
244 } region_size_e;
245
246 typedef enum {
247 ADDRESS_MATCHING_TOR = 1,
248 ADDRESS_MATCHING_NAPOT = 3
249 } address_matching_e;
250
251 typedef struct {
252 uint32_t r: 1; /* readable enable */
253 uint32_t w: 1; /* writeable enable */
254 uint32_t x: 1; /* execable enable */
255 address_matching_e a: 2; /* address matching mode */
256 uint32_t reserved: 2; /* reserved */
257 uint32_t l: 1; /* lock enable */
258 } mpu_region_attr_t;
259
260 /*@} end of group CSI_PMP */
261
262 /* CACHE Register Definitions */
263 #define CACHE_MHCR_L0BTB_Pos 12U /*!< CACHE MHCR: L0BTB Position */
264 #define CACHE_MHCR_L0BTB_Msk (0x1UL << CACHE_MHCR_L0BTB_Pos) /*!< CACHE MHCR: WA Mask */
265
266 #define CACHE_MHCR_BPE_Pos 5U /*!< CACHE MHCR: BPE Position */
267 #define CACHE_MHCR_BPE_Msk (0x1UL << CACHE_MHCR_BPE_Pos) /*!< CACHE MHCR: BPE Mask */
268
269 #define CACHE_MHCR_RS_Pos 4U /*!< CACHE MHCR: RS Position */
270 #define CACHE_MHCR_RS_Msk (0x1UL << CACHE_MHCR_RS_Pos) /*!< CACHE MHCR: RS Mask */
271
272 #define CACHE_MHCR_WA_Pos 3U /*!< CACHE MHCR: WA Position */
273 #define CACHE_MHCR_WA_Msk (0x1UL << CACHE_MHCR_WA_Pos) /*!< CACHE MHCR: WA Mask */
274
275 #define CACHE_MHCR_WB_Pos 2U /*!< CACHE MHCR: WB Position */
276 #define CACHE_MHCR_WB_Msk (0x1UL << CACHE_MHCR_WB_Pos) /*!< CACHE MHCR: WB Mask */
277
278 #define CACHE_MHCR_DE_Pos 1U /*!< CACHE MHCR: DE Position */
279 #define CACHE_MHCR_DE_Msk (0x1UL << CACHE_MHCR_DE_Pos) /*!< CACHE MHCR: DE Mask */
280
281 #define CACHE_MHCR_IE_Pos 0U /*!< CACHE MHCR: IE Position */
282 #define CACHE_MHCR_IE_Msk (0x1UL << CACHE_MHCR_IE_Pos) /*!< CACHE MHCR: IE Mask */
283
284 #define CACHE_INV_ADDR_Pos 5U
285 #define CACHE_INV_ADDR_Msk (0xFFFFFFFFUL << CACHE_INV_ADDR_Pos)
286
287 /*@} end of group CSI_CACHE */
288
289
290 /**
291 \ingroup CSI_core_register
292 \defgroup CSI_SysTick System Tick Timer (CORET)
293 \brief Type definitions for the System Timer Registers.
294 @{
295 */
296
297 /**
298 \brief The data structure of the access system timer.
299 */
300 typedef struct {
301 __IOM unsigned long long MTIMECMP; /*!< Offset: 0x000 (R/W) Timer compare register */
302 uint32_t RESERVED[8187];
303 __IM unsigned long long MTIME; /*!< Offset: 0x7FFC (R) Timer current register */
304 } CORET_Type;
305
306 /*@} end of group CSI_SysTick */
307
308 /**
309 \ingroup CSI_core_register
310 \defgroup CSI_DCC
311 \brief Type definitions for the DCC.
312 @{
313 */
314
315 /**
316 \brief Access to the data structure of DCC.
317 */
318 typedef struct {
319 uint32_t RESERVED0[13U];
320 __IOM uint32_t HCR; /*!< Offset: 0x034 (R/W) */
321 __IM uint32_t EHSR; /*!< Offset: 0x03C (R/ ) */
322 uint32_t RESERVED1[6U];
323 union {
324 __IM uint32_t DERJW; /*!< Offset: 0x058 (R/ ) Data exchange register CPU read*/
325 __OM uint32_t DERJR; /*!< Offset: 0x058 ( /W) Data exchange register CPU writer*/
326 };
327
328 } DCC_Type;
329
330 #define DCC_HCR_JW_Pos 18U /*!< DCC HCR: jw_int_en Position */
331 #define DCC_HCR_JW_Msk (1UL << DCC_HCR_JW_Pos) /*!< DCC HCR: jw_int_en Mask */
332
333 #define DCC_HCR_JR_Pos 19U /*!< DCC HCR: jr_int_en Position */
334 #define DCC_HCR_JR_Msk (1UL << DCC_HCR_JR_Pos) /*!< DCC HCR: jr_int_en Mask */
335
336 #define DCC_EHSR_JW_Pos 1U /*!< DCC EHSR: jw_vld Position */
337 #define DCC_EHSR_JW_Msk (1UL << DCC_EHSR_JW_Pos) /*!< DCC EHSR: jw_vld Mask */
338
339 #define DCC_EHSR_JR_Pos 2U /*!< DCC EHSR: jr_vld Position */
340 #define DCC_EHSR_JR_Msk (1UL << DCC_EHSR_JR_Pos) /*!< DCC EHSR: jr_vld Mask */
341
342 /*@} end of group CSI_DCC */
343
344
345 /**
346 \ingroup CSI_core_register
347 \defgroup CSI_core_bitfield Core register bit field macros
348 \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
349 @{
350 */
351
352 /**
353 \brief Mask and shift a bit field value for use in a register bit range.
354 \param[in] field Name of the register bit field.
355 \param[in] value Value of the bit field.
356 \return Masked and shifted value.
357 */
358 #define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
359
360 /**
361 \brief Mask and shift a register value to extract a bit filed value.
362 \param[in] field Name of the register bit field.
363 \param[in] value Value of register.
364 \return Masked and shifted bit field value.
365 */
366 #define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
367
368 /*@} end of group CSI_core_bitfield */
369
370 /**
371 \ingroup CSI_core_register
372 \defgroup CSI_core_base Core Definitions
373 \brief Definitions for base addresses, unions, and structures.
374 @{
375 */
376
377 /* Memory mapping of CK802 Hardware */
378 #define TCIP_BASE (0xE000E000UL) /*!< Titly Coupled IP Base Address */
379 #define CORET_BASE (0xE4004000UL) /*!< CORET Base Address */
380 #define CLIC_BASE (0xE0000000UL) /*!< CLIC Base Address */
381 #define DCC_BASE (0xE0011000UL) /*!< DCC Base Address */
382 #define CACHE_BASE (TCIP_BASE + 0x1000UL) /*!< CACHE Base Address */
383
384 #define CORET ((CORET_Type *) CORET_BASE ) /*!< SysTick configuration struct */
385 #define CLIC ((CLIC_Type *) CLIC_BASE ) /*!< CLIC configuration struct */
386 #define DCC ((DCC_Type *) DCC_BASE ) /*!< DCC configuration struct */
387 #define CACHE ((CACHE_Type *) CACHE_BASE ) /*!< cache configuration struct */
388
389 /*@} */
390
391 /*******************************************************************************
392 * Hardware Abstraction Layer
393 Core Function Interface contains:
394 - Core VIC Functions
395 - Core CORET Functions
396 - Core Register Access Functions
397 ******************************************************************************/
398 /**
399 \defgroup CSI_Core_FunctionInterface Functions and Instructions Reference
400 */
401
402 /* ########################## VIC functions #################################### */
403 /**
404 \ingroup CSI_Core_FunctionInterface
405 \defgroup CSI_Core_VICFunctions VIC Functions
406 \brief Functions that manage interrupts and exceptions via the VIC.
407 @{
408 */
409
410 /* The following MACROS handle generation of the register offset and byte masks */
411 #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
412 #define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 5UL) )
413 #define _IP2_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
414
415 /**
416 \brief Enable External Interrupt
417 \details Enable a device-specific interrupt in the VIC interrupt controller.
418 \param [in] IRQn External interrupt number. Value cannot be negative.
419 */
csi_vic_enable_irq(int32_t IRQn)420 __STATIC_INLINE void csi_vic_enable_irq(int32_t IRQn)
421 {
422 CLIC->CLICINT[IRQn].IE |= CLIC_INTIE_IE_Msk;
423 }
424
425 /**
426 \brief Disable External Interrupt
427 \details Disable a device-specific interrupt in the VIC interrupt controller.
428 \param [in] IRQn External interrupt number. Value cannot be negative.
429 */
csi_vic_disable_irq(int32_t IRQn)430 __STATIC_INLINE void csi_vic_disable_irq(int32_t IRQn)
431 {
432 CLIC->CLICINT[IRQn].IE &= ~CLIC_INTIE_IE_Msk;
433 }
434
435 /**
436 \brief Enable External Secure Interrupt
437 \details Enable a secure device-specific interrupt in the VIC interrupt controller.
438 \param [in] IRQn External interrupt number. Value cannot be negative.
439 */
csi_vic_enable_sirq(int32_t IRQn)440 __STATIC_INLINE void csi_vic_enable_sirq(int32_t IRQn)
441 {
442 CLIC->CLICINT[IRQn].IE |= (CLIC_INTIE_IE_Msk | CLIC_INTIE_T_Msk);
443 }
444
445 /**
446 \brief Disable External Secure Interrupt
447 \details Disable a secure device-specific interrupt in the VIC interrupt controller.
448 \param [in] IRQn External interrupt number. Value cannot be negative.
449 */
csi_vic_disable_sirq(int32_t IRQn)450 __STATIC_INLINE void csi_vic_disable_sirq(int32_t IRQn)
451 {
452 CLIC->CLICINT[IRQn].IE &= ~(CLIC_INTIE_IE_Msk | CLIC_INTIE_T_Msk);
453 }
454
455 /**
456 \brief Check Interrupt is Enabled or not
457 \details Read the enabled register in the VIC and returns the pending bit for the specified interrupt.
458 \param [in] IRQn Interrupt number.
459 \return 0 Interrupt status is not enabled.
460 \return 1 Interrupt status is enabled.
461 */
csi_vic_get_enabled_irq(int32_t IRQn)462 __STATIC_INLINE uint32_t csi_vic_get_enabled_irq(int32_t IRQn)
463 {
464 return (uint32_t)(CLIC->CLICINT[IRQn].IE & CLIC_INTIE_IE_Msk);
465 }
466
467 /**
468 \brief Check Interrupt is Pending or not
469 \details Read the pending register in the VIC and returns the pending bit for the specified interrupt.
470 \param [in] IRQn Interrupt number.
471 \return 0 Interrupt status is not pending.
472 \return 1 Interrupt status is pending.
473 */
csi_vic_get_pending_irq(int32_t IRQn)474 __STATIC_INLINE uint32_t csi_vic_get_pending_irq(int32_t IRQn)
475 {
476 return (uint32_t)(CLIC->CLICINT[IRQn].IP & CLIC_INTIP_IP_Msk);
477 }
478
479 /**
480 \brief Set Pending Interrupt
481 \details Set the pending bit of an external interrupt.
482 \param [in] IRQn Interrupt number. Value cannot be negative.
483 */
csi_vic_set_pending_irq(int32_t IRQn)484 __STATIC_INLINE void csi_vic_set_pending_irq(int32_t IRQn)
485 {
486 CLIC->CLICINT[IRQn].IP |= CLIC_INTIP_IP_Msk;
487 }
488
489 /**
490 \brief Clear Pending Interrupt
491 \details Clear the pending bit of an external interrupt.
492 \param [in] IRQn External interrupt number. Value cannot be negative.
493 */
csi_vic_clear_pending_irq(int32_t IRQn)494 __STATIC_INLINE void csi_vic_clear_pending_irq(int32_t IRQn)
495 {
496 CLIC->CLICINT[IRQn].IP &= ~CLIC_INTIP_IP_Msk;
497 }
498
499 /**
500 \brief Set Interrupt Priority
501 \details Set the priority of an interrupt.
502 \note The priority cannot be set for every core interrupt.
503 \param [in] IRQn Interrupt number.
504 \param [in] priority Priority to set.
505 */
csi_vic_set_prio(int32_t IRQn,uint32_t priority)506 __STATIC_INLINE void csi_vic_set_prio(int32_t IRQn, uint32_t priority)
507 {
508 uint8_t nlbits = (CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos;
509 CLIC->CLICINT[IRQn].CTL = (CLIC->CLICINT[IRQn].CTL & (~CLIC_INTCFG_PRIO_Msk)) | (priority << (8 - nlbits));
510 }
511
512 /**
513 \brief Get Interrupt Priority
514 \details Read the priority of an interrupt.
515 The interrupt number can be positive to specify an external (device specific) interrupt,
516 or negative to specify an internal (core) interrupt.
517 \param [in] IRQn Interrupt number.
518 \return Interrupt Priority.
519 Value is aligned automatically to the implemented priority bits of the microcontroller.
520 */
csi_vic_get_prio(int32_t IRQn)521 __STATIC_INLINE uint32_t csi_vic_get_prio(int32_t IRQn)
522 {
523 uint8_t nlbits = (CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos;
524 return CLIC->CLICINT[IRQn].CTL >> (8 - nlbits);
525 }
526
527 /**
528 \brief Set interrupt handler
529 \details Set the interrupt handler according to the interrupt num, the handler will be filled in irq vectors.
530 \param [in] IRQn Interrupt number.
531 \param [in] handler Interrupt handler.
532 */
csi_vic_set_vector(int32_t IRQn,uint32_t handler)533 __STATIC_INLINE void csi_vic_set_vector(int32_t IRQn, uint32_t handler)
534 {
535 if (IRQn >= 0 && IRQn < 1024) {
536 uint32_t *vectors = (uint32_t *)__get_MTVT();
537 vectors[IRQn] = handler;
538 }
539 }
540
541 /**
542 \brief Get interrupt handler
543 \details Get the address of interrupt handler function.
544 \param [in] IRQn Interrupt number.
545 */
csi_vic_get_vector(int32_t IRQn)546 __STATIC_INLINE uint32_t csi_vic_get_vector(int32_t IRQn)
547 {
548 if (IRQn >= 0 && IRQn < 1024) {
549 uint32_t *vectors = (uint32_t *)__get_MTVT();
550 return (uint32_t)vectors[IRQn];
551 }
552
553 return 0;
554 }
555
556 /*@} end of CSI_Core_VICFunctions */
557
558 /* ########################## PMP functions #################################### */
559 /**
560 \ingroup CSI_Core_FunctionInterface
561 \defgroup CSI_Core_PMPFunctions PMP Functions
562 \brief Functions that manage interrupts and exceptions via the VIC.
563 @{
564 */
565
566 /**
567 \brief configure memory protected region.
568 \details
569 \param [in] idx memory protected region (0, 1, 2, ..., 15).
570 \param [in] base_addr base address must be aligned with page size.
571 \param [in] size \ref region_size_e. memory protected region size.
572 \param [in] attr \ref region_size_t. memory protected region attribute.
573 \param [in] enable enable or disable memory protected region.
574 */
csi_mpu_config_region(uint32_t idx,uint32_t base_addr,region_size_e size,mpu_region_attr_t attr,uint32_t enable)575 __STATIC_INLINE void csi_mpu_config_region(uint32_t idx, uint32_t base_addr, region_size_e size,
576 mpu_region_attr_t attr, uint32_t enable)
577 {
578 uint8_t pmpxcfg = 0;
579 uint32_t addr = 0;
580
581 if (idx > 15) {
582 return;
583 }
584
585 if (!enable) {
586 attr.a = 0;
587 }
588
589 if (attr.a == ADDRESS_MATCHING_TOR) {
590 addr = base_addr >> 2;
591 } else {
592 if (size == REGION_SIZE_4B) {
593 addr = base_addr >> 2;
594 attr.a = 2;
595 } else {
596 addr = ((base_addr >> 2) & (0xFFFFFFFFU - ((1 << (size + 1)) - 1))) | ((1 << size) - 1);
597 }
598 }
599
600 __set_PMPADDRx(idx, addr);
601
602 pmpxcfg |= (attr.r << PMP_PMPCFG_R_Pos) | (attr.w << PMP_PMPCFG_W_Pos) |
603 (attr.x << PMP_PMPCFG_X_Pos) | (attr.a << PMP_PMPCFG_A_Pos) |
604 (attr.l << PMP_PMPCFG_L_Pos);
605
606 __set_PMPxCFG(idx, pmpxcfg);
607 }
608
609 /**
610 \brief disable mpu region by idx.
611 \details
612 \param [in] idx memory protected region (0, 1, 2, ..., 15).
613 */
csi_mpu_disable_region(uint32_t idx)614 __STATIC_INLINE void csi_mpu_disable_region(uint32_t idx)
615 {
616 __set_PMPxCFG(idx, __get_PMPxCFG(idx) & (~PMP_PMPCFG_A_Msk));
617 }
618
619 /*@} end of CSI_Core_PMPFunctions */
620
621 /* ################################## SysTick function ############################################ */
622 /**
623 \ingroup CSI_Core_FunctionInterface
624 \defgroup CSI_Core_SysTickFunctions SysTick Functions
625 \brief Functions that configure the System.
626 @{
627 */
628
629
630 /**
631 \brief CORE timer Configuration
632 \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
633 Counter is in free running mode to generate periodic interrupts.
634 \param [in] ticks Number of ticks between two interrupts.
635 \param [in] IRQn core timer Interrupt number.
636 \return 0 Function succeeded.
637 \return 1 Function failed.
638 \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
639 function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
640 must contain a vendor-specific implementation of this function.
641 */
csi_coret_config(uint32_t ticks,int32_t IRQn)642 __STATIC_INLINE uint32_t csi_coret_config(uint32_t ticks, int32_t IRQn)
643 {
644 CORET->MTIMECMP = CORET->MTIME + ticks;
645 return (0UL);
646 }
647
648 /**
649 \brief get CORE timer reload value
650 \return CORE timer counter value.
651 */
csi_coret_get_load(void)652 __STATIC_INLINE uint32_t csi_coret_get_load(void)
653 {
654 return CORET->MTIMECMP & 0xFFFFFFFF;
655 }
656
657 /**
658 \brief get CORE timer reload high value
659 \return CORE timer counter value.
660 */
csi_coret_get_loadh(void)661 __STATIC_INLINE uint32_t csi_coret_get_loadh(void)
662 {
663 return (CORET->MTIMECMP >> 32) & 0xFFFFFFFF;
664 }
665
666 /**
667 \brief get CORE timer counter value
668 \return CORE timer counter value.
669 */
csi_coret_get_value(void)670 __STATIC_INLINE uint32_t csi_coret_get_value(void)
671 {
672 return CORET->MTIME & 0xFFFFFFFF;
673 }
674
675 /**
676 \brief get CORE timer counter high value
677 \return CORE timer counter value.
678 */
csi_coret_get_valueh(void)679 __STATIC_INLINE uint32_t csi_coret_get_valueh(void)
680 {
681 return (CORET->MTIME >> 32) & 0xFFFFFFFF;
682 }
683
684 /*@} end of CSI_Core_SysTickFunctions */
685
686 /* ##################################### DCC function ########################################### */
687 /**
688 \ingroup CSI_Core_FunctionInterface
689 \defgroup CSI_core_DebugFunctions HAD Functions
690 \brief Functions that access the HAD debug interface.
691 @{
692 */
693
694 /**
695 \brief HAD Send Character
696 \details Transmits a character via the HAD channel 0, and
697 \li Just returns when no debugger is connected that has booked the output.
698 \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
699 \param [in] ch Character to transmit.
700 \returns Character to transmit.
701 */
csi_had_send_char(uint32_t ch)702 __STATIC_INLINE uint32_t csi_had_send_char(uint32_t ch)
703 {
704 DCC->DERJR = (uint8_t)ch;
705
706 return (ch);
707 }
708
709
710 /**
711 \brief HAD Receive Character
712 \details Inputs a character via the external variable \ref HAD_RxBuffer.
713 \return Received character.
714 \return -1 No character pending.
715 */
csi_had_receive_char(void)716 __STATIC_INLINE int32_t csi_had_receive_char(void)
717 {
718 int32_t ch = -1; /* no character available */
719
720 if (_FLD2VAL(DCC_EHSR_JW, DCC->EHSR)) {
721 ch = DCC->DERJW;
722 }
723
724 return (ch);
725 }
726
727
728 /**
729 \brief HAD Check Character
730 \details Check whether a character is pending for reading in the variable \ref HAD_RxBuffer.
731 \return 0 No character available.
732 \return 1 Character available.
733 */
csi_had_check_char(void)734 __STATIC_INLINE int32_t csi_had_check_char(void)
735 {
736 return _FLD2VAL(DCC_EHSR_JW, DCC->EHSR); /* no character available */
737 }
738
739 /*@} end of CSI_core_DebugFunctions */
740
741 /* ########################## Cache functions #################################### */
742 /**
743 \ingroup CSI_Core_FunctionInterface
744 \defgroup CSI_Core_CacheFunctions Cache Functions
745 \brief Functions that configure Instruction and Data cache.
746 @{
747 */
748
749 /**
750 \brief Enable I-Cache
751 \details Turns on I-Cache
752 */
csi_icache_enable(void)753 __STATIC_INLINE void csi_icache_enable (void)
754 {
755 #if (__ICACHE_PRESENT == 1U)
756 uint32_t cache;
757 __DSB();
758 __ISB();
759 __ICACHE_IALL();
760 cache = __get_MHCR();
761 cache |= CACHE_MHCR_IE_Msk;
762 __set_MHCR(cache);
763 __DSB();
764 __ISB();
765 #endif
766 }
767
768
769 /**
770 \brief Disable I-Cache
771 \details Turns off I-Cache
772 */
csi_icache_disable(void)773 __STATIC_INLINE void csi_icache_disable (void)
774 {
775 #if (__ICACHE_PRESENT == 1U)
776 uint32_t cache;
777 __DSB();
778 __ISB();
779 cache = __get_MHCR();
780 cache |= ~CACHE_MHCR_IE_Msk; /* disable icache */
781 __set_MHCR(cache);
782 __ICACHE_IALL(); /* invalidate all icache */
783 __DSB();
784 __ISB();
785 #endif
786 }
787
788
789 /**
790 \brief Invalidate I-Cache
791 \details Invalidates I-Cache
792 */
csi_icache_invalid(void)793 __STATIC_INLINE void csi_icache_invalid (void)
794 {
795 #if (__ICACHE_PRESENT == 1U)
796 __DSB();
797 __ISB();
798 __ICACHE_IALL(); /* invalidate all icache */
799 __DSB();
800 __ISB();
801 #endif
802 }
803
804
805 /**
806 \brief Enable D-Cache
807 \details Turns on D-Cache
808 \note I-Cache also turns on.
809 */
csi_dcache_enable(void)810 __STATIC_INLINE void csi_dcache_enable (void)
811 {
812 #if (__DCACHE_PRESENT == 1U)
813 uint32_t cache;
814 __DSB();
815 __ISB();
816 __DCACHE_IALL(); /* invalidate all dcache */
817 cache = __get_MHCR();
818 cache |= (CACHE_MHCR_DE_Msk | CACHE_MHCR_WB_Msk | CACHE_MHCR_WA_Msk | CACHE_MHCR_RS_Msk | CACHE_MHCR_BPE_Msk | CACHE_MHCR_L0BTB_Msk); /* enable all Cache */
819 __set_MHCR(cache);
820
821 __DSB();
822 __ISB();
823 #endif
824 }
825
826
827 /**
828 \brief Disable D-Cache
829 \details Turns off D-Cache
830 \note I-Cache also turns off.
831 */
csi_dcache_disable(void)832 __STATIC_INLINE void csi_dcache_disable (void)
833 {
834 #if (__DCACHE_PRESENT == 1U)
835 uint32_t cache;
836 __DSB();
837 __ISB();
838 cache = __get_MHCR();
839 cache &= ~(uint32_t)CACHE_MHCR_DE_Msk; /* disable all Cache */
840 __set_MHCR(cache);
841 __DCACHE_IALL(); /* invalidate all Cache */
842 __DSB();
843 __ISB();
844 #endif
845 }
846
847
848 /**
849 \brief Invalidate D-Cache
850 \details Invalidates D-Cache
851 \note I-Cache also invalid
852 */
csi_dcache_invalid(void)853 __STATIC_INLINE void csi_dcache_invalid (void)
854 {
855 #if (__DCACHE_PRESENT == 1U)
856 __DSB();
857 __ISB();
858 __DCACHE_IALL(); /* invalidate all Cache */
859 __DSB();
860 __ISB();
861 #endif
862 }
863
864
865 /**
866 \brief Clean D-Cache
867 \details Cleans D-Cache
868 \note I-Cache also cleans
869 */
csi_dcache_clean(void)870 __STATIC_INLINE void csi_dcache_clean (void)
871 {
872 #if (__DCACHE_PRESENT == 1U)
873 __DSB();
874 __ISB();
875 __DCACHE_CALL(); /* clean all Cache */
876 __DSB();
877 __ISB();
878 #endif
879 }
880
881
882 /**
883 \brief Clean & Invalidate D-Cache
884 \details Cleans and Invalidates D-Cache
885 \note I-Cache also flush.
886 */
csi_dcache_clean_invalid(void)887 __STATIC_INLINE void csi_dcache_clean_invalid (void)
888 {
889 #if (__DCACHE_PRESENT == 1U)
890 __DSB();
891 __ISB();
892 __DCACHE_CIALL(); /* clean and inv all Cache */
893 __DSB();
894 __ISB();
895 #endif
896 }
897
898
899 /**
900 \brief D-Cache Invalidate by address
901 \details Invalidates D-Cache for the given address
902 \param[in] addr address (aligned to 32-byte boundary)
903 \param[in] dsize size of memory block (in number of bytes)
904 */
csi_dcache_invalid_range(uint32_t * addr,int32_t dsize)905 __STATIC_INLINE void csi_dcache_invalid_range (uint32_t *addr, int32_t dsize)
906 {
907 #if (__DCACHE_PRESENT == 1U)
908 int32_t op_size = dsize + (uint32_t)addr % 32;
909 uint32_t op_addr = (uint32_t)addr;
910 int32_t linesize = 32;
911
912 __DSB();
913
914 while (op_size > 0) {
915 __DCACHE_IPA(op_addr);
916 op_addr += linesize;
917 op_size -= linesize;
918 }
919
920 __DSB();
921 __ISB();
922 #endif
923 }
924
925
926 /**
927 \brief D-Cache Clean by address
928 \details Cleans D-Cache for the given address
929 \param[in] addr address (aligned to 32-byte boundary)
930 \param[in] dsize size of memory block (in number of bytes)
931 */
csi_dcache_clean_range(uint32_t * addr,int32_t dsize)932 __STATIC_INLINE void csi_dcache_clean_range (uint32_t *addr, int32_t dsize)
933 {
934 #if (__DCACHE_PRESENT == 1)
935 int32_t op_size = dsize + (uint32_t)addr % 32;
936 uint32_t op_addr = (uint32_t) addr & CACHE_INV_ADDR_Msk;
937 int32_t linesize = 32;
938
939 __DSB();
940
941 while (op_size > 0) {
942 __DCACHE_CPA(op_addr);
943 op_addr += linesize;
944 op_size -= linesize;
945 }
946
947 __DSB();
948 __ISB();
949 #endif
950 }
951
952
953 /**
954 \brief D-Cache Clean and Invalidate by address
955 \details Cleans and invalidates D_Cache for the given address
956 \param[in] addr address (aligned to 16-byte boundary)
957 \param[in] dsize size of memory block (aligned to 16-byte boundary)
958 */
csi_dcache_clean_invalid_range(uint32_t * addr,int32_t dsize)959 __STATIC_INLINE void csi_dcache_clean_invalid_range (uint32_t *addr, int32_t dsize)
960 {
961 #if (__DCACHE_PRESENT == 1U)
962 int32_t op_size = dsize + (uint32_t)addr % 32;
963 uint32_t op_addr = (uint32_t) addr;
964 int32_t linesize = 32;
965
966 __DSB();
967
968 while (op_size > 0) {
969 __DCACHE_CIPA(op_addr);
970 op_addr += linesize;
971 op_size -= linesize;
972 }
973
974 __DSB();
975 __ISB();
976 #endif
977 }
978
979 /**
980 \brief setup cacheable range Cache
981 \details setup Cache range
982 */
csi_cache_set_range(uint32_t index,uint32_t baseAddr,uint32_t size,uint32_t enable)983 __STATIC_INLINE void csi_cache_set_range (uint32_t index, uint32_t baseAddr, uint32_t size, uint32_t enable)
984 {
985 ;
986 }
987
988 /**
989 \brief Enable cache profile
990 \details Turns on Cache profile
991 */
csi_cache_enable_profile(void)992 __STATIC_INLINE void csi_cache_enable_profile (void)
993 {
994 ;
995 }
996
997 /**
998 \brief Disable cache profile
999 \details Turns off Cache profile
1000 */
csi_cache_disable_profile(void)1001 __STATIC_INLINE void csi_cache_disable_profile (void)
1002 {
1003 ;
1004 }
1005
1006 /**
1007 \brief Reset cache profile
1008 \details Reset Cache profile
1009 */
csi_cache_reset_profile(void)1010 __STATIC_INLINE void csi_cache_reset_profile (void)
1011 {
1012 ;
1013 }
1014
1015 /**
1016 \brief cache access times
1017 \details Cache access times
1018 \note every 256 access add 1.
1019 \return cache access times, actual times should be multiplied by 256
1020 */
csi_cache_get_access_time(void)1021 __STATIC_INLINE uint32_t csi_cache_get_access_time (void)
1022 {
1023 return 0;
1024 }
1025
1026 /**
1027 \brief cache miss times
1028 \details Cache miss times
1029 \note every 256 miss add 1.
1030 \return cache miss times, actual times should be multiplied by 256
1031 */
csi_cache_get_miss_time(void)1032 __STATIC_INLINE uint32_t csi_cache_get_miss_time (void)
1033 {
1034 return 0;
1035 }
1036
1037 /*@} end of CSI_Core_CacheFunctions */
1038
1039 /*@} end of CSI_core_DebugFunctions */
1040
1041 /* ################################## IRQ Functions ############################################ */
1042
1043 /**
1044 \brief Save the Irq context
1045 \details save the psr result before disable irq.
1046 */
csi_irq_save(void)1047 __STATIC_INLINE uint32_t csi_irq_save(void)
1048 {
1049 uint32_t result;
1050 result = __get_MSTATUS();
1051 __disable_irq();
1052 return(result);
1053 }
1054
1055 /**
1056 \brief Restore the Irq context
1057 \details restore saved primask state.
1058 \param [in] irq_state psr irq state.
1059 */
csi_irq_restore(uint32_t irq_state)1060 __STATIC_INLINE void csi_irq_restore(uint32_t irq_state)
1061 {
1062 __set_MSTATUS(irq_state);
1063 }
1064
1065 /*@} end of IRQ Functions */
1066
1067
1068 #ifdef __cplusplus
1069 }
1070 #endif
1071
1072 #endif /* __CORE_RV32_H_DEPENDANT */
1073
1074 #endif /* __CSI_GENERIC */
1075