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