NMSIS-Core  Version 1.5.0
NMSIS-Core support for Nuclei processor-based devices
core_feature_eclic.h
1 /*
2  * Copyright (c) 2019 Nuclei Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the License); you may
7  * not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 #ifndef __CORE_FEATURE_ECLIC__
19 #define __CORE_FEATURE_ECLIC__
24 /*
25  * ECLIC Feature Configuration Macro:
26  * 1. __ECLIC_PRESENT: Define whether Enhanced Core Local Interrupt Controller (ECLIC) Unit is present or not
27  * * 0: Not present
28  * * 1: Present
29  * 2. __ECLIC_BASEADDR: Base address of the ECLIC unit.
30  * 3. __ECLIC_INTCTLBITS: Optional, if defined, it should set to the value of ECLIC_GetInfoCtlbits(), define the number of hardware bits are actually implemented in the clicintctl registers.
31  * Valid number is 1 - 8.
32  * 4. __ECLIC_INTNUM: Define the external interrupt number of ECLIC Unit
33  * 5. __SMODE_PRESENT: Define whether S-Mode present, if present, ECLIC will present with S-Mode ECLIC feature
34  * * 0: Not present
35  * * 1: Present
36  *
37  */
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 #include "core_feature_base.h"
43 
44 #if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1)
56 typedef union
57 {
58  struct {
59  __IM uint8_t _reserved0:1;
60  __IOM uint8_t nlbits:4;
61  __IM uint8_t nmbits:2;
62  __IM uint8_t _reserved1:1;
63  } b;
64  uint8_t w;
65 } CLICCFG_Type;
66 
70 typedef union {
71  struct {
72  __IM uint32_t numint:13;
73  __IM uint32_t version:8;
74  __IM uint32_t intctlbits:4;
75  __IM uint32_t shd_num:4;
76  __IM uint32_t _reserved0:3;
77  } b;
78  __IM uint32_t w;
80 
84 typedef struct {
85  __IOM uint8_t INTIP;
86  __IOM uint8_t INTIE;
87  __IOM uint8_t INTATTR;
88  __IOM uint8_t INTCTRL;
90 
94 typedef struct {
95  __IOM uint8_t CFG;
96  __IM uint8_t RESERVED0[3];
97  __IM uint32_t INFO;
98  __IM uint8_t RESERVED1;
99 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
100  __IOM uint8_t STH;
101 #else
102  __IM uint8_t RESERVED2;
103 #endif
104  __IM uint8_t RESERVED3;
105  __IOM uint8_t MTH;
106  uint32_t RESERVED4[1021];
107 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
108  CLIC_CTRL_Type CTRL[1024];
109  __IM uint32_t RESERVED5[2];
110  __IM uint8_t RESERVED6;
111  __IOM uint8_t SSTH;
112  __IM uint8_t RESERVED7;
113  __IM uint8_t RESERVED8;
114  __IM uint32_t RESERVED9[1021];
115  CLIC_CTRL_Type SCTRL[1024];
116 #else
117  CLIC_CTRL_Type CTRL[4096];
118 #endif
119 } CLIC_Type;
120 
121 #define CLIC_CLICCFG_NLBIT_Pos 1U
122 #define CLIC_CLICCFG_NLBIT_Msk (0xFUL << CLIC_CLICCFG_NLBIT_Pos)
124 #define CLIC_CLICINFO_CTLBIT_Pos 21U
125 #define CLIC_CLICINFO_CTLBIT_Msk (0xFUL << CLIC_CLICINFO_CTLBIT_Pos)
127 #define CLIC_CLICINFO_VER_Pos 13U
128 #define CLIC_CLICINFO_VER_Msk (0xFFUL << CLIC_CLICINFO_VER_Pos)
130 #define CLIC_CLICINFO_NUM_Pos 0U
131 #define CLIC_CLICINFO_NUM_Msk (0x1FFFUL << CLIC_CLICINFO_NUM_Pos)
133 #define CLIC_CLICINFO_SHD_NUM_Pos 25U
134 #define CLIC_CLICINFO_SHD_NUM_Msk (0xFUL << CLIC_CLICINFO_SHD_NUM_Pos)
136 #define CLIC_INTIP_IP_Pos 0U
137 #define CLIC_INTIP_IP_Msk (0x1UL << CLIC_INTIP_IP_Pos)
139 #define CLIC_INTIE_IE_Pos 0U
140 #define CLIC_INTIE_IE_Msk (0x1UL << CLIC_INTIE_IE_Pos)
142 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
143 #define CLIC_INTATTR_MODE_Pos 6U
144 #define CLIC_INTATTR_MODE_Msk (0x3U << CLIC_INTATTR_MODE_Pos)
145 #endif
146 
147 #define CLIC_INTATTR_TRIG_Pos 1U
148 #define CLIC_INTATTR_TRIG_Msk (0x3UL << CLIC_INTATTR_TRIG_Pos)
150 #define CLIC_INTATTR_SHV_Pos 0U
151 #define CLIC_INTATTR_SHV_Msk (0x1UL << CLIC_INTATTR_SHV_Pos)
153 #define ECLIC_MAX_NLBITS 8U
154 #define ECLIC_MODE_MTVEC_Msk 3U
156 #define ECLIC_NON_VECTOR_INTERRUPT 0x0
157 #define ECLIC_VECTOR_INTERRUPT 0x1
160 typedef enum ECLIC_TRIGGER {
164  ECLIC_MAX_TRIGGER = 0x3
166 
167 #ifndef __ECLIC_BASEADDR
168 /* Base address of ECLIC(__ECLIC_BASEADDR) should be defined in <Device.h> */
169 #error "__ECLIC_BASEADDR is not defined, please check!"
170 #endif
171 
172 #ifndef __ECLIC_INTCTLBITS
173 /* Define __ECLIC_INTCTLBITS to get via ECLIC->INFO if not defined */
174 #define __ECLIC_INTCTLBITS (__ECLIC_GetInfoCtlbits())
175 #endif
176 
177 /* ECLIC Memory mapping of Device */
178 #define ECLIC_BASE __ECLIC_BASEADDR
179 #define ECLIC ((CLIC_Type *) ECLIC_BASE) /* end of group NMSIS_Core_ECLIC_Registers */
182 
183 /* ########################## ECLIC functions #################################### */
201 /* The following enum IRQn definition in this file
202  * is only used for doxygen documentation generation,
203  * The <Device>.h is the real file to define it by vendor
204  */
205 #if defined(__ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__)
206 typedef enum IRQn {
207  /* ========= Nuclei N/NX Core Specific Interrupt Numbers =========== */
208  /* Core Internal Interrupt IRQn definitions */
229  /* ========= Device Specific Interrupt Numbers =================== */
230  /* ToDo: add here your device specific external interrupt numbers.
231  * 19~max(NUM_INTERRUPT, 1023) is reserved number for user.
232  * Maxmum interrupt supported could get from clicinfo.NUM_INTERRUPT.
233  * According the interrupt handlers defined in startup_Device.S
234  * eg.: Interrupt for Timer#1 eclic_tim1_handler -> TIM1_IRQn */
237 } IRQn_Type;
238 #endif /* __ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__ */
239 
240 #ifdef NMSIS_ECLIC_VIRTUAL
241  #ifndef NMSIS_ECLIC_VIRTUAL_HEADER_FILE
242  #define NMSIS_ECLIC_VIRTUAL_HEADER_FILE "nmsis_eclic_virtual.h"
243  #endif
244  #include NMSIS_ECLIC_VIRTUAL_HEADER_FILE
245 #else
246  #define ECLIC_SetCfgNlbits __ECLIC_SetCfgNlbits
247  #define ECLIC_GetCfgNlbits __ECLIC_GetCfgNlbits
248  #define ECLIC_GetInfoVer __ECLIC_GetInfoVer
249  #define ECLIC_GetInfoCtlbits __ECLIC_GetInfoCtlbits
250  #define ECLIC_GetInfoNum __ECLIC_GetInfoNum
251  #define ECLIC_GetInfoShadowNum __ECLIC_GetInfoShadowNum
252  #define ECLIC_SetMth __ECLIC_SetMth
253  #define ECLIC_GetMth __ECLIC_GetMth
254  #define ECLIC_EnableIRQ __ECLIC_EnableIRQ
255  #define ECLIC_GetEnableIRQ __ECLIC_GetEnableIRQ
256  #define ECLIC_DisableIRQ __ECLIC_DisableIRQ
257  #define ECLIC_SetPendingIRQ __ECLIC_SetPendingIRQ
258  #define ECLIC_GetPendingIRQ __ECLIC_GetPendingIRQ
259  #define ECLIC_ClearPendingIRQ __ECLIC_ClearPendingIRQ
260  #define ECLIC_SetTrigIRQ __ECLIC_SetTrigIRQ
261  #define ECLIC_GetTrigIRQ __ECLIC_GetTrigIRQ
262  #define ECLIC_SetShvIRQ __ECLIC_SetShvIRQ
263  #define ECLIC_GetShvIRQ __ECLIC_GetShvIRQ
264  #define ECLIC_SetCtrlIRQ __ECLIC_SetCtrlIRQ
265  #define ECLIC_GetCtrlIRQ __ECLIC_GetCtrlIRQ
266  #define ECLIC_SetLevelIRQ __ECLIC_SetLevelIRQ
267  #define ECLIC_GetLevelIRQ __ECLIC_GetLevelIRQ
268  #define ECLIC_SetPriorityIRQ __ECLIC_SetPriorityIRQ
269  #define ECLIC_GetPriorityIRQ __ECLIC_GetPriorityIRQ
270 #if __ECLIC_VER == 2
271  #define ECLIC_EnableShadow __ECLIC_EnableShadow
272  #define ECLIC_DisableShadow __ECLIC_DisableShadow
273  #define ECLIC_SetShadowLevel __ECLIC_SetShadowLevel
274  #define ECLIC_GetShadowLevel __ECLIC_GetShadowLevel
275  #define ECLIC_SetShadowLevelReg __ECLIC_SetShadowLevelReg
276  #define ECLIC_GetShadowLevelReg __ECLIC_GetShadowLevelReg
277 #endif
278 
279  /* For S-Mode */
280 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
281  #define ECLIC_SetModeIRQ __ECLIC_SetModeIRQ
282  #define ECLIC_SetSth __ECLIC_SetSth
283  #define ECLIC_GetSth __ECLIC_GetSth
284  #define ECLIC_SetPendingIRQ_S __ECLIC_SetPendingIRQ_S
285  #define ECLIC_GetPendingIRQ_S __ECLIC_GetPendingIRQ_S
286  #define ECLIC_ClearPendingIRQ_S __ECLIC_ClearPendingIRQ_S
287  #define ECLIC_SetTrigIRQ_S __ECLIC_SetTrigIRQ_S
288  #define ECLIC_GetTrigIRQ_S __ECLIC_GetTrigIRQ_S
289  #define ECLIC_SetShvIRQ_S __ECLIC_SetShvIRQ_S
290  #define ECLIC_GetShvIRQ_S __ECLIC_GetShvIRQ_S
291  #define ECLIC_SetCtrlIRQ_S __ECLIC_SetCtrlIRQ_S
292  #define ECLIC_GetCtrlIRQ_S __ECLIC_GetCtrlIRQ_S
293  #define ECLIC_SetLevelIRQ_S __ECLIC_SetLevelIRQ_S
294  #define ECLIC_GetLevelIRQ_S __ECLIC_GetLevelIRQ_S
295  #define ECLIC_SetPriorityIRQ_S __ECLIC_SetPriorityIRQ_S
296  #define ECLIC_GetPriorityIRQ_S __ECLIC_GetPriorityIRQ_S
297  #define ECLIC_EnableIRQ_S __ECLIC_EnableIRQ_S
298  #define ECLIC_GetEnableIRQ_S __ECLIC_GetEnableIRQ_S
299  #define ECLIC_DisableIRQ_S __ECLIC_DisableIRQ_S
300 #if __ECLIC_VER == 2
301  #define ECLIC_EnableShadow_S __ECLIC_EnableShadow_S
302  #define ECLIC_DisableShadow_S __ECLIC_DisableShadow_S
303  #define ECLIC_SetShadowLevel_S __ECLIC_SetShadowLevel_S
304  #define ECLIC_GetShadowLevel_S __ECLIC_GetShadowLevel_S
305  #define ECLIC_SetShadowLevelReg_S __ECLIC_SetShadowLevelReg_S
306  #define ECLIC_GetShadowLevelReg_S __ECLIC_GetShadowLevelReg_S
307 #endif
308 
309 #endif
310 #endif /* NMSIS_ECLIC_VIRTUAL */
311 
312 #ifdef NMSIS_VECTAB_VIRTUAL
313  #ifndef NMSIS_VECTAB_VIRTUAL_HEADER_FILE
314  #define NMSIS_VECTAB_VIRTUAL_HEADER_FILE "nmsis_vectab_virtual.h"
315  #endif
316  #include NMSIS_VECTAB_VIRTUAL_HEADER_FILE
317 #else
318  #define ECLIC_SetVector __ECLIC_SetVector
319  #define ECLIC_GetVector __ECLIC_GetVector
320 
321 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
322  #define ECLIC_SetVector_S __ECLIC_SetVector_S
323  #define ECLIC_GetVector_S __ECLIC_GetVector_S
324 #endif
325 #endif /* (NMSIS_VECTAB_VIRTUAL) */
326 
338 {
339  uint8_t temp = ECLIC->CFG;
340 
341  ECLIC->CFG = (temp & ~CLIC_CLICCFG_NLBIT_Msk) | \
342  ((uint8_t)((nlbits << CLIC_CLICCFG_NLBIT_Pos) & CLIC_CLICCFG_NLBIT_Msk));
343 }
344 
356 {
357  return ((uint32_t)((ECLIC->CFG & CLIC_CLICCFG_NLBIT_Msk) >> CLIC_CLICCFG_NLBIT_Pos));
358 }
359 
372 {
373  return ((uint32_t)((ECLIC->INFO & CLIC_CLICINFO_VER_Msk) >> CLIC_CLICINFO_VER_Pos));
374 }
375 
389 {
390  return ((uint32_t)((ECLIC->INFO & CLIC_CLICINFO_CTLBIT_Msk) >> CLIC_CLICINFO_CTLBIT_Pos));
391 }
392 
405 {
406  return ((uint32_t)((ECLIC->INFO & CLIC_CLICINFO_NUM_Msk) >> CLIC_CLICINFO_NUM_Pos));
407 }
408 
425 {
426  return ((uint32_t)((ECLIC->INFO & (CLIC_CLICINFO_SHD_NUM_Msk)) >> CLIC_CLICINFO_SHD_NUM_Pos));
427 }
428 
441 {
442  ECLIC->MTH = mth;
443 }
444 
454 {
455  return (ECLIC->MTH);
456 }
457 
458 
470 {
471  ECLIC->CTRL[IRQn].INTIE |= CLIC_INTIE_IE_Msk;
472 }
473 
489 {
490  return ((uint32_t) (ECLIC->CTRL[IRQn].INTIE) & CLIC_INTIE_IE_Msk);
491 }
492 
504 {
505  ECLIC->CTRL[IRQn].INTIE &= ~CLIC_INTIE_IE_Msk;
506 }
507 
523 {
524  return ((uint32_t)(ECLIC->CTRL[IRQn].INTIP) & CLIC_INTIP_IP_Msk);
525 }
526 
539 {
540  ECLIC->CTRL[IRQn].INTIP |= CLIC_INTIP_IP_Msk;
541 }
542 
556 {
557  ECLIC->CTRL[IRQn].INTIP &= ~CLIC_INTIP_IP_Msk;
558 }
559 
577 {
578  uint8_t temp = ECLIC->CTRL[IRQn].INTATTR;
579 
580  ECLIC->CTRL[IRQn].INTATTR = (temp & ~CLIC_INTATTR_TRIG_Msk) | \
581  ((uint8_t)(trig << CLIC_INTATTR_TRIG_Pos));
582 }
583 
600 {
601  return ((uint32_t)(((ECLIC->CTRL[IRQn].INTATTR) & CLIC_INTATTR_TRIG_Msk) >> CLIC_INTATTR_TRIG_Pos));
602 }
603 
618 {
619  uint8_t temp = ECLIC->CTRL[IRQn].INTATTR;
620 
621  ECLIC->CTRL[IRQn].INTATTR = (temp & ~CLIC_INTATTR_SHV_Msk) | \
622  ((uint8_t)(shv << CLIC_INTATTR_SHV_Pos));
623 }
624 
639 {
640  return ((uint32_t)(((ECLIC->CTRL[IRQn].INTATTR) & CLIC_INTATTR_SHV_Msk) >> CLIC_INTATTR_SHV_Pos));
641 }
642 
655 {
656  ECLIC->CTRL[IRQn].INTCTRL = intctrl;
657 }
658 
671 {
672  return (ECLIC->CTRL[IRQn].INTCTRL);
673 }
674 
690 __STATIC_INLINE void __ECLIC_SetLevelIRQ(IRQn_Type IRQn, uint8_t lvl_abs)
691 {
692  uint8_t nlbits = __ECLIC_GetCfgNlbits();
693  uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS;
694 
695  if (nlbits == 0) {
696  return;
697  }
698 
699  if (nlbits > intctlbits) {
700  nlbits = intctlbits;
701  }
702  uint8_t maxlvl = ((1UL << nlbits) - 1);
703  if (lvl_abs > maxlvl) {
704  lvl_abs = maxlvl;
705  }
706  uint8_t lvl = lvl_abs << (ECLIC_MAX_NLBITS - nlbits);
707  uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ(IRQn);
708  cur_ctrl = cur_ctrl << nlbits;
709  cur_ctrl = cur_ctrl >> nlbits;
710  __ECLIC_SetCtrlIRQ(IRQn, (cur_ctrl | lvl));
711 }
712 
725 {
726  uint8_t nlbits = __ECLIC_GetCfgNlbits();
727  uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS;
728 
729  if (nlbits == 0) {
730  return 0;
731  }
732 
733  if (nlbits > intctlbits) {
734  nlbits = intctlbits;
735  }
736  uint8_t intctrl = __ECLIC_GetCtrlIRQ(IRQn);
737  uint8_t lvl_abs = intctrl >> (ECLIC_MAX_NLBITS - nlbits);
738  return lvl_abs;
739 }
740 
756 {
757  uint8_t nlbits = __ECLIC_GetCfgNlbits();
758  uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS;
759  if (nlbits < intctlbits) {
760  uint8_t maxpri = ((1UL << (intctlbits - nlbits)) - 1);
761  if (pri > maxpri) {
762  pri = maxpri;
763  }
764  pri = pri << (ECLIC_MAX_NLBITS - intctlbits);
765  uint8_t mask = ((uint8_t)(-1)) >> intctlbits;
766  pri = pri | mask;
767  uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ(IRQn);
768  cur_ctrl = cur_ctrl >> (ECLIC_MAX_NLBITS - nlbits);
769  cur_ctrl = cur_ctrl << (ECLIC_MAX_NLBITS - nlbits);
770  __ECLIC_SetCtrlIRQ(IRQn, (cur_ctrl | pri));
771  }
772 }
773 
786 {
787  uint8_t nlbits = __ECLIC_GetCfgNlbits();
788  uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS;
789  if (nlbits < intctlbits) {
790  uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ(IRQn);
791  uint8_t pri = cur_ctrl << nlbits;
792  pri = pri >> nlbits;
793  pri = pri >> (ECLIC_MAX_NLBITS - intctlbits);
794  return pri;
795  } else {
796  return 0;
797  }
798 }
799 
800 #if __ECLIC_VER == 2
812 __STATIC_FORCEINLINE void __ECLIC_EnableShadow(void)
813 {
815 }
816 
828 __STATIC_FORCEINLINE void __ECLIC_DisableShadow(void)
829 {
831 }
832 
851 __STATIC_INLINE void __ECLIC_SetShadowLevel(unsigned long idx, uint8_t level)
852 {
853  /* Check if idx is valid (0-7) */
854  if (idx > 7) {
855  return;
856  }
857 
858  uint8_t nlbits = (uint8_t)__ECLIC_GetCfgNlbits();
859  /* Limit the level value to the available number of bits */
860  uint8_t max_level = (1U << nlbits) - 1;
861  if (level > max_level) {
862  level = max_level;
863  }
864 
865  /* Position the level value in the upper nlbits of the 8-bit field and set the low (8-nlbits) bits to 1 */
866  uint8_t level_shifted = (uint8_t)((level << (8 - nlbits)) | ((1U << (8 - nlbits)) - 1));
867 
868 #if __RISCV_XLEN == 64
869  /* For RV64, all 8 shadow registers are in CSR_MSHADGPRLVL0 */
870  /* Calculate the bit position for the 8-bit field of the specified index */
871  uint32_t bit_pos = idx << 3; /* idx * 8 using bit shift */
872  /* Create mask to clear the 8-bit field for the specified index */
873  uint64_t mask = (uint64_t)0xFFUL << bit_pos;
874  /* Read, modify, and write the CSR register */
875  uint64_t current_val = __RV_CSR_READ(CSR_MSHADGPRLVL0);
876  current_val = (current_val & ~mask) | (((uint64_t)level_shifted) << bit_pos);
877  __RV_CSR_WRITE(CSR_MSHADGPRLVL0, current_val);
878 #else
879  /* For RV32, calculate bit position and select appropriate register */
880  if (idx < 4) {
881  /* Shadow registers 1-4 are in CSR_MSHADGPRLVL0 */
882  uint32_t bit_pos = idx << 3; /* idx * 8 using bit shift */
883  uint32_t mask = 0xFFUL << bit_pos;
884  uint32_t current_val = __RV_CSR_READ(CSR_MSHADGPRLVL0);
885  current_val = (current_val & ~mask) | (((uint32_t)level_shifted) << bit_pos);
886  __RV_CSR_WRITE(CSR_MSHADGPRLVL0, current_val);
887  } else {
888  /* Shadow registers 5-8 are in CSR_MSHADGPRLVL1 */
889  uint32_t bit_pos = (idx - 4) << 3; /* (idx - 4) * 8 using bit shift */
890  uint32_t mask = 0xFFUL << bit_pos;
891  uint32_t current_val = __RV_CSR_READ(CSR_MSHADGPRLVL1);
892  current_val = (current_val & ~mask) | (((uint32_t)level_shifted) << bit_pos);
893  __RV_CSR_WRITE(CSR_MSHADGPRLVL1, current_val);
894  }
895 #endif
896 }
897 
916 __STATIC_INLINE uint8_t __ECLIC_GetShadowLevel(unsigned long idx)
917 {
918  /* Check if idx is valid (0-7) */
919  if (idx > 7) {
920  return 0;
921  }
922 
923  uint8_t nlbits = (uint8_t)__ECLIC_GetCfgNlbits();
924 
925 #if __RISCV_XLEN == 64
926  /* For RV64, all 8 shadow registers are in CSR_MSHADGPRLVL0 */
927  /* Calculate the bit position for the 8-bit field of the specified index */
928  uint32_t bit_pos = idx << 3; /* idx * 8 using bit shift */
929  /* Read the CSR register and extract the 8-bit field */
930  uint64_t current_val = __RV_CSR_READ(CSR_MSHADGPRLVL0);
931  uint8_t extracted_val = (uint8_t)((current_val >> bit_pos) & 0xFF);
932  /* Extract the level from the upper nlbits of the 8-bit field */
933  uint8_t level = (extracted_val >> (8 - nlbits));
934  return level;
935 #else
936  /* For RV32, calculate bit position and select appropriate register */
937  if (idx < 4) {
938  /* Shadow registers 1-4 are in CSR_MSHADGPRLVL0 */
939  uint32_t bit_pos = idx << 3; /* idx * 8 using bit shift */
940  /* Read the CSR register and extract the 8-bit field */
941  uint32_t current_val = __RV_CSR_READ(CSR_MSHADGPRLVL0);
942  uint8_t extracted_val = (uint8_t)((current_val >> bit_pos) & 0xFF);
943  /* Extract the level from the upper nlbits of the 8-bit field */
944  uint8_t level = (extracted_val >> (8 - nlbits));
945  return level;
946  } else {
947  /* Shadow registers 5-8 are in CSR_MSHADGPRLVL1 */
948  uint32_t bit_pos = (idx - 4) << 3; /* (idx - 4) * 8 using bit shift */
949  /* Read the CSR register and extract the 8-bit field */
950  uint32_t current_val = __RV_CSR_READ(CSR_MSHADGPRLVL1);
951  uint8_t extracted_val = (uint8_t)((current_val >> bit_pos) & 0xFF);
952  /* Extract the level from the upper nlbits of the 8-bit field */
953  uint8_t level = (extracted_val >> (8 - nlbits));
954  return level;
955  }
956 #endif
957 }
958 
974 __STATIC_INLINE void __ECLIC_SetShadowLevelReg(uint64_t value)
975 {
976 #if __RISCV_XLEN == 64
978 #else
979  __RV_CSR_WRITE(CSR_MSHADGPRLVL0, (uint32_t)value);
980  __RV_CSR_WRITE(CSR_MSHADGPRLVL1, (uint32_t)(value >> 32));
981 #endif
982 }
983 
999 __STATIC_INLINE uint64_t __ECLIC_GetShadowLevelReg(void)
1000 {
1001 #if __RISCV_XLEN == 64
1003 #else
1004  uint64_t value = __RV_CSR_READ(CSR_MSHADGPRLVL1);
1005  value <<= 32;
1006  value |= __RV_CSR_READ(CSR_MSHADGPRLVL0);
1007  return value;
1008 #endif
1009 }
1010 #endif
1011 
1029 {
1030  unsigned long vec_base;
1031  vec_base = ((unsigned long)__RV_CSR_READ(CSR_MTVT));
1032  vec_base += ((unsigned long)IRQn) * sizeof(unsigned long);
1033  (* (unsigned long *) vec_base) = vector;
1034 #if (defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1))
1035 #if (defined(__CCM_PRESENT) && (__CCM_PRESENT == 1))
1036  MFlushDCacheLine((unsigned long)vec_base);
1037 #endif
1038 #endif
1039 #if (defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1))
1040 #if (defined(__CCM_PRESENT) && (__CCM_PRESENT == 1))
1041  MInvalICacheLine((unsigned long)vec_base);
1042 #else
1043  __FENCE_I();
1044 #endif
1045 #endif
1046 }
1047 
1061 {
1062 #if __RISCV_XLEN == 32
1063  return (*(uint32_t *)(__RV_CSR_READ(CSR_MTVT) + IRQn * 4));
1064 #elif __RISCV_XLEN == 64
1065  return (*(uint64_t *)(__RV_CSR_READ(CSR_MTVT) + IRQn * 8));
1066 #else // TODO Need cover for XLEN=128 case in future
1067  return (*(uint64_t *)(__RV_CSR_READ(CSR_MTVT) + IRQn * 8));
1068 #endif
1069 }
1070 
1071 #if defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1)
1087 {
1088  /*
1089  * only 1 or 3 can be assigned to mode in one step.the default value of mode is 3,
1090  * which can't be clear to 0 firstly, then OR it to 1
1091  */
1092  ECLIC->CTRL[IRQn].INTATTR = (uint8_t)(mode << CLIC_INTATTR_MODE_Pos) + \
1093  (ECLIC->SCTRL[IRQn].INTATTR & (~CLIC_INTATTR_MODE_Msk));
1094 }
1095 
1110 {
1111  ECLIC->STH = sth;
1112 }
1113 
1126 {
1127  return (ECLIC->STH);
1128 }
1129 
1142 {
1143  ECLIC->SCTRL[IRQn].INTIP |= CLIC_INTIP_IP_Msk;
1144 }
1145 
1161 {
1162  return ((uint32_t)(ECLIC->SCTRL[IRQn].INTIP) & CLIC_INTIP_IP_Msk);
1163 }
1164 
1178 {
1179  ECLIC->SCTRL[IRQn].INTIP &= ~CLIC_INTIP_IP_Msk;
1180 }
1181 
1199 {
1200  uint8_t temp = ECLIC->SCTRL[IRQn].INTATTR;
1201 
1202  ECLIC->SCTRL[IRQn].INTATTR = (temp & ~CLIC_INTATTR_TRIG_Msk) | \
1203  ((uint8_t)(trig << CLIC_INTATTR_TRIG_Pos));
1204 }
1205 
1222 {
1223  return ((uint8_t)(((ECLIC->SCTRL[IRQn].INTATTR) & CLIC_INTATTR_TRIG_Msk) >> CLIC_INTATTR_TRIG_Pos));
1224 }
1225 
1226 
1241 {
1242  uint8_t temp = ECLIC->SCTRL[IRQn].INTATTR;
1243 
1244  ECLIC->SCTRL[IRQn].INTATTR = (temp & ~CLIC_INTATTR_SHV_Msk) | \
1245  ((uint8_t)(shv << CLIC_INTATTR_SHV_Pos));
1246 }
1247 
1262 {
1263  return ((uint8_t)(((ECLIC->SCTRL[IRQn].INTATTR) & CLIC_INTATTR_SHV_Msk) >> CLIC_INTATTR_SHV_Pos));
1264 }
1265 
1278 {
1279  ECLIC->SCTRL[IRQn].INTCTRL = intctrl;
1280 }
1281 
1294 {
1295  return (ECLIC->SCTRL[IRQn].INTCTRL);
1296 }
1297 
1314 {
1315  uint8_t nlbits = __ECLIC_GetCfgNlbits();
1316  uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS;
1317 
1318  if (nlbits == 0) {
1319  return;
1320  }
1321 
1322  if (nlbits > intctlbits) {
1323  nlbits = intctlbits;
1324  }
1325  uint8_t maxlvl = ((1UL << nlbits) - 1);
1326  if (lvl_abs > maxlvl) {
1327  lvl_abs = maxlvl;
1328  }
1329  uint8_t lvl = lvl_abs << (ECLIC_MAX_NLBITS - nlbits);
1330  uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ_S(IRQn);
1331  cur_ctrl = cur_ctrl << nlbits;
1332  cur_ctrl = cur_ctrl >> nlbits;
1333  __ECLIC_SetCtrlIRQ_S(IRQn, (cur_ctrl | lvl));
1334 }
1335 
1336 
1349 {
1350  uint8_t nlbits = __ECLIC_GetCfgNlbits();
1351  uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS;
1352 
1353  if (nlbits == 0) {
1354  return 0;
1355  }
1356 
1357  if (nlbits > intctlbits) {
1358  nlbits = intctlbits;
1359  }
1360  uint8_t intctrl = __ECLIC_GetCtrlIRQ_S(IRQn);
1361  uint8_t lvl_abs = intctrl >> (ECLIC_MAX_NLBITS - nlbits);
1362  return lvl_abs;
1363 }
1364 
1380 {
1381  uint8_t nlbits = __ECLIC_GetCfgNlbits();
1382  uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS;
1383  if (nlbits < intctlbits) {
1384  uint8_t maxpri = ((1UL << (intctlbits - nlbits)) - 1);
1385  if (pri > maxpri) {
1386  pri = maxpri;
1387  }
1388  pri = pri << (ECLIC_MAX_NLBITS - intctlbits);
1389  uint8_t mask = ((uint8_t)(-1)) >> intctlbits;
1390  pri = pri | mask;
1391  uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ_S(IRQn);
1392  cur_ctrl = cur_ctrl >> (ECLIC_MAX_NLBITS - nlbits);
1393  cur_ctrl = cur_ctrl << (ECLIC_MAX_NLBITS - nlbits);
1394  __ECLIC_SetCtrlIRQ_S(IRQn, (cur_ctrl | pri));
1395  }
1396 }
1397 
1410 {
1411  uint8_t nlbits = __ECLIC_GetCfgNlbits();
1412  uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS;
1413  if (nlbits < intctlbits) {
1414  uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ_S(IRQn);
1415  uint8_t pri = cur_ctrl << nlbits;
1416  pri = pri >> nlbits;
1417  pri = pri >> (ECLIC_MAX_NLBITS - intctlbits);
1418  return pri;
1419  } else {
1420  return 0;
1421  }
1422 }
1423 
1435 {
1436  ECLIC->SCTRL[IRQn].INTIE |= CLIC_INTIE_IE_Msk;
1437 }
1438 
1454 {
1455  return ((uint8_t) (ECLIC->SCTRL[IRQn].INTIE) & CLIC_INTIE_IE_Msk);
1456 }
1457 
1469 {
1470  ECLIC->SCTRL[IRQn].INTIE &= ~CLIC_INTIE_IE_Msk;
1471 }
1472 
1490 {
1491  volatile unsigned long vec_base;
1492  vec_base = ((unsigned long)__RV_CSR_READ(CSR_STVT));
1493  vec_base += ((unsigned long)IRQn) * sizeof(unsigned long);
1494  (* (unsigned long *) vec_base) = vector;
1495 #if (defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1))
1496 #if (defined(__CCM_PRESENT) && (__CCM_PRESENT == 1))
1497  SFlushDCacheLine((unsigned long)vec_base);
1498 #endif
1499 #endif
1500 #if (defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1))
1501 #if (defined(__CCM_PRESENT) && (__CCM_PRESENT == 1))
1502  SInvalICacheLine((unsigned long)vec_base);
1503 #else
1504  __FENCE_I();
1505 #endif
1506 #endif
1507 }
1508 
1522 {
1523 #if __RISCV_XLEN == 32
1524  return (*(uint32_t *)(__RV_CSR_READ(CSR_STVT) + IRQn * 4));
1525 #elif __RISCV_XLEN == 64
1526  return (*(uint64_t *)(__RV_CSR_READ(CSR_STVT) + IRQn * 8));
1527 #else // TODO Need cover for XLEN=128 case in future
1528  return (*(uint64_t *)(__RV_CSR_READ(CSR_STVT) + IRQn * 8));
1529 #endif
1530 }
1531 
1532 #if __ECLIC_VER == 2
1544 __STATIC_FORCEINLINE void __ECLIC_EnableShadow_S(void)
1545 {
1547 }
1548 
1560 __STATIC_FORCEINLINE void __ECLIC_DisableShadow_S(void)
1561 {
1563 }
1564 
1583 __STATIC_INLINE void __ECLIC_SetShadowLevel_S(unsigned long idx, uint8_t level)
1584 {
1585  /* Check if idx is valid (0-7) */
1586  if (idx > 7) {
1587  return;
1588  }
1589 
1590  uint8_t nlbits = (uint8_t)__ECLIC_GetCfgNlbits();
1591  /* Limit the level value to the available number of bits */
1592  uint8_t max_level = (1U << nlbits) - 1;
1593  if (level > max_level) {
1594  level = max_level;
1595  }
1596 
1597  /* Position the level value in the upper nlbits of the 8-bit field and set the low (8-nlbits) bits to 1 */
1598  uint8_t level_shifted = (uint8_t)((level << (8 - nlbits)) | ((1U << (8 - nlbits)) - 1));
1599 
1600 #if __RISCV_XLEN == 64
1601  /* For RV64, all 8 shadow registers are in CSR_SSHADGPRLVL0 */
1602  /* Calculate the bit position for the 8-bit field of the specified index */
1603  uint32_t bit_pos = idx << 3; /* idx * 8 using bit shift */
1604  /* Create mask to clear the 8-bit field for the specified index */
1605  uint64_t mask = (uint64_t)0xFFUL << bit_pos;
1606  /* Read, modify, and write the CSR register */
1607  uint64_t current_val = __RV_CSR_READ(CSR_SSHADGPRLVL0);
1608  current_val = (current_val & ~mask) | (((uint64_t)level_shifted) << bit_pos);
1609  __RV_CSR_WRITE(CSR_SSHADGPRLVL0, current_val);
1610 #else
1611  /* For RV32, calculate bit position and select appropriate register */
1612  if (idx < 4) {
1613  /* Shadow registers 1-4 are in CSR_SSHADGPRLVL0 */
1614  uint32_t bit_pos = idx << 3; /* idx * 8 using bit shift */
1615  uint32_t mask = 0xFFUL << bit_pos;
1616  uint32_t current_val = __RV_CSR_READ(CSR_SSHADGPRLVL0);
1617  current_val = (current_val & ~mask) | (((uint32_t)level_shifted) << bit_pos);
1618  __RV_CSR_WRITE(CSR_SSHADGPRLVL0, current_val);
1619  } else {
1620  /* Shadow registers 5-8 are in CSR_SSHADGPRLVL1 */
1621  uint32_t bit_pos = (idx - 4) << 3; /* (idx - 4) * 8 using bit shift */
1622  uint32_t mask = 0xFFUL << bit_pos;
1623  uint32_t current_val = __RV_CSR_READ(CSR_SSHADGPRLVL1);
1624  current_val = (current_val & ~mask) | (((uint32_t)level_shifted) << bit_pos);
1625  __RV_CSR_WRITE(CSR_SSHADGPRLVL1, current_val);
1626  }
1627 #endif
1628 }
1629 
1648 __STATIC_INLINE uint8_t __ECLIC_GetShadowLevel_S(unsigned long idx)
1649 {
1650  /* Check if idx is valid (0-7) */
1651  if (idx > 7) {
1652  return 0;
1653  }
1654 
1655  uint8_t nlbits = (uint8_t)__ECLIC_GetCfgNlbits();
1656 
1657 #if __RISCV_XLEN == 64
1658  /* For RV64, all 8 shadow registers are in CSR_SSHADGPRLVL0 */
1659  /* Calculate the bit position for the 8-bit field of the specified index */
1660  uint32_t bit_pos = idx << 3; /* idx * 8 using bit shift */
1661  /* Read the CSR register and extract the 8-bit field */
1662  uint64_t current_val = __RV_CSR_READ(CSR_SSHADGPRLVL0);
1663  uint8_t extracted_val = (uint8_t)((current_val >> bit_pos) & 0xFF);
1664  /* Extract the level from the upper nlbits of the 8-bit field */
1665  uint8_t level = (extracted_val >> (8 - nlbits));
1666  return level;
1667 #else
1668  /* For RV32, calculate bit position and select appropriate register */
1669  if (idx < 4) {
1670  /* Shadow registers 1-4 are in CSR_SSHADGPRLVL0 */
1671  uint32_t bit_pos = idx << 3; /* idx * 8 using bit shift */
1672  /* Read the CSR register and extract the 8-bit field */
1673  uint32_t current_val = __RV_CSR_READ(CSR_SSHADGPRLVL0);
1674  uint8_t extracted_val = (uint8_t)((current_val >> bit_pos) & 0xFF);
1675  /* Extract the level from the upper nlbits of the 8-bit field */
1676  uint8_t level = (extracted_val >> (8 - nlbits));
1677  return level;
1678  } else {
1679  /* Shadow registers 5-8 are in CSR_SSHADGPRLVL1 */
1680  uint32_t bit_pos = (idx - 4) << 3; /* (idx - 4) * 8 using bit shift */
1681  /* Read the CSR register and extract the 8-bit field */
1682  uint32_t current_val = __RV_CSR_READ(CSR_SSHADGPRLVL1);
1683  uint8_t extracted_val = (uint8_t)((current_val >> bit_pos) & 0xFF);
1684  /* Extract the level from the upper nlbits of the 8-bit field */
1685  uint8_t level = (extracted_val >> (8 - nlbits));
1686  return level;
1687  }
1688 #endif
1689 }
1690 
1706 __STATIC_INLINE void __ECLIC_SetShadowLevelReg_S(uint64_t value)
1707 {
1708 #if __RISCV_XLEN == 64
1710 #else
1711  __RV_CSR_WRITE(CSR_SSHADGPRLVL0, (uint32_t)value);
1712  __RV_CSR_WRITE(CSR_SSHADGPRLVL1, (uint32_t)(value >> 32));
1713 #endif
1714 }
1715 
1731 __STATIC_INLINE uint64_t __ECLIC_GetShadowLevelReg_S(void)
1732 {
1733 #if __RISCV_XLEN == 64
1735 #else
1736  uint64_t value = __RV_CSR_READ(CSR_SSHADGPRLVL1);
1737  value <<= 32;
1738  value |= __RV_CSR_READ(CSR_SSHADGPRLVL0);
1739  return value;
1740 #endif
1741 }
1742 
1743 #endif
1744 
1745 #endif /* defined(__SMODE_PRESENT) && (__SMODE_PRESENT == 1) */
1746 
1759 {
1760  addr &= (rv_csr_t)(~0x3F);
1761  addr |= ECLIC_MODE_MTVEC_Msk;
1762  __RV_CSR_WRITE(CSR_MTVEC, addr);
1763 }
1764 
1777 {
1778  unsigned long addr = __RV_CSR_READ(CSR_MTVEC);
1779  return (addr & ~ECLIC_MODE_MTVEC_Msk);
1780 }
1781 
1794 {
1795  if (__RV_CSR_READ(CSR_MTVT2) & 0x1) {
1796  __RV_CSR_WRITE(CSR_MTVT2, addr | 0x01);
1797  } else {
1798  addr &= (rv_csr_t)(~0x3F);
1799  addr |= ECLIC_MODE_MTVEC_Msk;
1800  __RV_CSR_WRITE(CSR_MTVEC, addr);
1801  }
1802 }
1803 
1816 {
1817  if (__RV_CSR_READ(CSR_MTVT2) & 0x1) {
1818  return __RV_CSR_READ(CSR_MTVT2) & (~(rv_csr_t)(0x1));
1819  } else {
1821  return (addr & ~ECLIC_MODE_MTVEC_Msk);
1822  }
1823 }
1824 
1836 {
1837  return __RV_CSR_READ(CSR_MNVEC);
1838 }
1839 
1840 /* NOTE: SSUBM CSR is introduced in ECLIC v2, without this the S_Mode vector interrupt nesting
1841  * and non-vector interrupt nesting will not work properly */
1842 #if __ECLIC_VER == 2
1843 #define SAVE_SSUBM_VAR() rv_csr_t __ssubm = __RV_CSR_READ(CSR_SSUBM);
1844 #define RESTORE_SSUBM_VAR() __RV_CSR_WRITE(CSR_SSUBM, __ssubm);
1845 #else
1846 #define SAVE_SSUBM_VAR()
1847 #define RESTORE_SSUBM_VAR()
1848 #endif
1849 
1880 #define SAVE_IRQ_CSR_CONTEXT() \
1881  rv_csr_t __mcause = __RV_CSR_READ(CSR_MCAUSE); \
1882  rv_csr_t __mepc = __RV_CSR_READ(CSR_MEPC); \
1883  rv_csr_t __msubm = __RV_CSR_READ(CSR_MSUBM); \
1884  __enable_irq();
1885 
1887 #define SAVE_IRQ_CSR_CONTEXT_S() \
1888  rv_csr_t __scause = __RV_CSR_READ(CSR_SCAUSE); \
1889  rv_csr_t __sepc = __RV_CSR_READ(CSR_SEPC); \
1890  SAVE_SSUBM_VAR(); \
1891  __enable_irq_s();
1892 
1893 
1903 #define RESTORE_IRQ_CSR_CONTEXT() \
1904  __disable_irq(); \
1905  __RV_CSR_WRITE(CSR_MSUBM, __msubm); \
1906  __RV_CSR_WRITE(CSR_MEPC, __mepc); \
1907  __RV_CSR_WRITE(CSR_MCAUSE, __mcause);
1908 
1910 #define RESTORE_IRQ_CSR_CONTEXT_S() \
1911  __disable_irq_s(); \
1912  RESTORE_SSUBM_VAR(); \
1913  __RV_CSR_WRITE(CSR_SEPC, __sepc); \
1914  __RV_CSR_WRITE(CSR_SCAUSE, __scause); /* End of Doxygen Group NMSIS_Core_IntExc */
1916 
1917 #endif /* defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1) */
1918 
1919 #ifdef __cplusplus
1920 }
1921 #endif
1922 #endif /* __CORE_FEATURE_ECLIC__ */
#define SECLIC_CTL_SHADOW_EN
#define MECLIC_CTL_SHADOW_EN
#define __RV_CSR_CLEAR(csr, val)
CSR operation Macro for csrc instruction.
#define __RV_CSR_READ(csr)
CSR operation Macro for csrr instruction.
__STATIC_FORCEINLINE void __FENCE_I(void)
Fence.i Instruction.
#define __RV_CSR_WRITE(csr, val)
CSR operation Macro for csrw instruction.
#define __RV_CSR_SET(csr, val)
CSR operation Macro for csrs instruction.
#define CSR_MECLIC_CTL
#define CSR_MNVEC
#define CSR_MTVEC
#define CSR_SSHADGPRLVL0
#define CSR_SECLIC_CTL
#define CSR_MTVT
#define CSR_MTVT2
#define CSR_MSHADGPRLVL0
#define CSR_MSHADGPRLVL1
#define CSR_SSHADGPRLVL1
#define CSR_STVT
#define __STATIC_FORCEINLINE
Define a static function that should be always inlined by the compiler.
Definition: nmsis_gcc.h:70
#define __STATIC_INLINE
Define a static function that may be inlined by the compiler.
Definition: nmsis_gcc.h:65
__STATIC_INLINE void MFlushDCacheLine(unsigned long addr)
Flush one D-Cache line specified by address in M-Mode.
__STATIC_INLINE void SFlushDCacheLine(unsigned long addr)
Flush one D-Cache line specified by address in S-Mode.
#define CLIC_CLICCFG_NLBIT_Pos
CLIC CLICCFG: NLBIT Position.
#define CLIC_CLICINFO_CTLBIT_Msk
CLIC INTINFO: CLICINTCTLBITS Mask.
#define CLIC_CLICINFO_SHD_NUM_Msk
CLIC CLICINFO: SHD_NUM Mask.
#define CLIC_CLICINFO_VER_Msk
CLIC CLICINFO: VERSION Mask.
#define CLIC_INTATTR_SHV_Msk
CLIC INTATTR: SHV Mask.
#define ECLIC_MODE_MTVEC_Msk
ECLIC Mode mask for MTVT CSR Register.
#define CLIC_CLICINFO_VER_Pos
CLIC CLICINFO: VERSION Position.
#define ECLIC_MAX_NLBITS
Max nlbit of the CLICINTCTLBITS.
ECLIC_TRIGGER_Type
ECLIC Trigger Enum for different Trigger Type.
#define CLIC_CLICINFO_NUM_Pos
CLIC CLICINFO: NUM_INTERRUPT Position.
#define CLIC_INTATTR_TRIG_Msk
CLIC INTATTR: TRIG Mask.
#define CLIC_INTATTR_SHV_Pos
CLIC INTATTR: SHV Position.
#define CLIC_INTATTR_MODE_Msk
CLIC INTATTA: Mode Mask.
#define CLIC_CLICCFG_NLBIT_Msk
CLIC CLICCFG: NLBIT Mask.
#define CLIC_INTIE_IE_Msk
CLIC INTIE: IE Mask.
#define CLIC_CLICINFO_NUM_Msk
CLIC CLICINFO: NUM_INTERRUPT Mask.
#define CLIC_INTATTR_MODE_Pos
CLIC INTATTA: Mode Position.
#define ECLIC
CLIC configuration struct.
#define CLIC_INTATTR_TRIG_Pos
CLIC INTATTR: TRIG Position.
#define CLIC_CLICINFO_CTLBIT_Pos
CLIC INTINFO: CLICINTCTLBITS Position.
#define CLIC_CLICINFO_SHD_NUM_Pos
CLIC CLICINFO: SHD_NUM Position.
#define CLIC_INTIP_IP_Msk
CLIC INTIP: IP Mask.
@ ECLIC_POSTIVE_EDGE_TRIGGER
Postive/Rising Edge Triggered, trig[0] = 1, trig[1] = 0.
@ ECLIC_LEVEL_TRIGGER
Level Triggerred, trig[0] = 0.
@ ECLIC_MAX_TRIGGER
MAX Supported Trigger Mode.
@ ECLIC_NEGTIVE_EDGE_TRIGGER
Negtive/Falling Edge Triggered, trig[0] = 1, trig[1] = 1.
__STATIC_INLINE void SInvalICacheLine(unsigned long addr)
Invalidate one I-Cache line specified by address in S-Mode.
__STATIC_INLINE void MInvalICacheLine(unsigned long addr)
Invalidate one I-Cache line specified by address in M-Mode.
__STATIC_FORCEINLINE rv_csr_t __get_exc_entry(void)
Get Exception entry address.
__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoVer(void)
Get the ECLIC version number.
__STATIC_FORCEINLINE uint8_t __ECLIC_GetCtrlIRQ(IRQn_Type IRQn)
Get ECLIC Interrupt Input Control Register value for a specific interrupt.
__STATIC_INLINE void __ECLIC_SetVector_S(IRQn_Type IRQn, rv_csr_t vector)
Set Interrupt Vector of a specific interrupt in supervisor mode.
__STATIC_INLINE uint8_t __ECLIC_GetPriorityIRQ_S(IRQn_Type IRQn)
Get ECLIC Interrupt priority of a specific interrupt in supervisor mode.
__STATIC_FORCEINLINE void __ECLIC_SetTrigIRQ_S(IRQn_Type IRQn, uint32_t trig)
Set trigger mode and polarity for a specific interrupt in supervisor mode.
__STATIC_FORCEINLINE uint8_t __ECLIC_GetSth(void)
Get supervisor-mode Interrupt Level Threshold in supervisor mode.
__STATIC_FORCEINLINE uint32_t __ECLIC_GetCfgNlbits(void)
Get nlbits value.
__STATIC_FORCEINLINE void __ECLIC_SetShvIRQ(IRQn_Type IRQn, uint32_t shv)
Set interrupt working mode for a specific interrupt.
__STATIC_FORCEINLINE void __ECLIC_SetCtrlIRQ_S(IRQn_Type IRQn, uint8_t intctrl)
Modify ECLIC Interrupt Input Control Register for a specific interrupt in supervisor mode.
__STATIC_FORCEINLINE uint8_t __ECLIC_GetShvIRQ_S(IRQn_Type IRQn)
Get interrupt working mode for a specific interrupt in supervisor mode.
__STATIC_INLINE void __ECLIC_SetVector(IRQn_Type IRQn, rv_csr_t vector)
Set Interrupt Vector of a specific interrupt.
__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoNum(void)
Get number of maximum interrupt inputs supported.
__STATIC_FORCEINLINE void __ECLIC_SetCtrlIRQ(IRQn_Type IRQn, uint8_t intctrl)
Modify ECLIC Interrupt Input Control Register for a specific interrupt.
__STATIC_INLINE void __ECLIC_SetLevelIRQ(IRQn_Type IRQn, uint8_t lvl_abs)
Set ECLIC Interrupt level of a specific interrupt.
__STATIC_FORCEINLINE uint8_t __ECLIC_GetMth(void)
Get Machine Mode Interrupt Level Threshold.
__STATIC_FORCEINLINE void __ECLIC_ClearPendingIRQ_S(IRQn_Type IRQn)
Clear a specific interrupt from pending in supervisor mode.
__STATIC_FORCEINLINE void __ECLIC_SetCfgNlbits(uint32_t nlbits)
Set nlbits value.
__STATIC_FORCEINLINE void __ECLIC_SetSth(uint8_t sth)
Set supervisor-mode Interrupt Level Threshold in supervisor mode.
__STATIC_INLINE void __ECLIC_SetLevelIRQ_S(IRQn_Type IRQn, uint8_t lvl_abs)
Set ECLIC Interrupt level of a specific interrupt in supervisor mode.
__STATIC_INLINE rv_csr_t __get_nonvec_entry(void)
Get Non-vector interrupt entry address.
__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoShadowNum(void)
Get number of shadow register groups.
__STATIC_INLINE void __ECLIC_SetPriorityIRQ_S(IRQn_Type IRQn, uint8_t pri)
Set ECLIC Interrupt priority of a specific interrupt in supervisor mode.
__STATIC_INLINE uint8_t __ECLIC_GetLevelIRQ_S(IRQn_Type IRQn)
Get ECLIC Interrupt level of a specific interrupt.
__STATIC_FORCEINLINE int32_t __ECLIC_GetPendingIRQ_S(IRQn_Type IRQn)
Get the pending specific interrupt in supervisor mode.
__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoCtlbits(void)
Get CLICINTCTLBITS.
__STATIC_FORCEINLINE void __ECLIC_ClearPendingIRQ(IRQn_Type IRQn)
Clear a specific interrupt from pending.
__STATIC_FORCEINLINE rv_csr_t __ECLIC_GetVector(IRQn_Type IRQn)
Get Interrupt Vector of a specific interrupt.
IRQn_Type
Definition of IRQn numbers.
__STATIC_FORCEINLINE void __ECLIC_SetModeIRQ(IRQn_Type IRQn, uint32_t mode)
Set privilege mode of a specific interrupt.
__STATIC_INLINE uint8_t __ECLIC_GetPriorityIRQ(IRQn_Type IRQn)
Get ECLIC Interrupt priority of a specific interrupt.
__STATIC_FORCEINLINE void __ECLIC_EnableIRQ_S(IRQn_Type IRQn)
Enable a specific interrupt in supervisor mode.
__STATIC_FORCEINLINE int32_t __ECLIC_GetPendingIRQ(IRQn_Type IRQn)
Get the pending specific interrupt.
__STATIC_FORCEINLINE void __ECLIC_DisableIRQ(IRQn_Type IRQn)
Disable a specific interrupt.
__STATIC_INLINE void __ECLIC_SetPriorityIRQ(IRQn_Type IRQn, uint8_t pri)
Get ECLIC Interrupt priority of a specific interrupt.
__STATIC_FORCEINLINE uint8_t __ECLIC_GetEnableIRQ_S(IRQn_Type IRQn)
Get a specific interrupt enable status in supervisor mode.
__STATIC_FORCEINLINE uint8_t __ECLIC_GetTrigIRQ_S(IRQn_Type IRQn)
Get trigger mode and polarity for a specific interrupt in supervisor mode.
__STATIC_FORCEINLINE uint32_t __ECLIC_GetTrigIRQ(IRQn_Type IRQn)
Get trigger mode and polarity for a specific interrupt.
__STATIC_FORCEINLINE void __ECLIC_SetPendingIRQ_S(IRQn_Type IRQn)
Set a specific interrupt to pending in supervisor mode.
__STATIC_INLINE void __set_nonvec_entry(rv_csr_t addr)
Set Non-vector interrupt entry address.
__STATIC_FORCEINLINE rv_csr_t __get_nmi_entry(void)
Get NMI interrupt entry from 'CSR_MNVEC'.
__STATIC_FORCEINLINE void __ECLIC_DisableIRQ_S(IRQn_Type IRQn)
Disable a specific interrupt in supervisor mode.
__STATIC_FORCEINLINE uint8_t __ECLIC_GetCtrlIRQ_S(IRQn_Type IRQn)
Get ECLIC Interrupt Input Control Register value for a specific interrupt in supervisor mode.
__STATIC_FORCEINLINE uint32_t __ECLIC_GetShvIRQ(IRQn_Type IRQn)
Get interrupt working mode for a specific interrupt.
__STATIC_FORCEINLINE uint32_t __ECLIC_GetEnableIRQ(IRQn_Type IRQn)
Get a specific interrupt enable status.
__STATIC_INLINE uint8_t __ECLIC_GetLevelIRQ(IRQn_Type IRQn)
Get ECLIC Interrupt level of a specific interrupt.
__STATIC_FORCEINLINE void __ECLIC_SetPendingIRQ(IRQn_Type IRQn)
Set a specific interrupt to pending.
__STATIC_FORCEINLINE void __ECLIC_EnableIRQ(IRQn_Type IRQn)
Enable a specific interrupt.
__STATIC_FORCEINLINE void __ECLIC_SetShvIRQ_S(IRQn_Type IRQn, uint32_t shv)
Set interrupt working mode for a specific interrupt in supervisor mode.
__STATIC_FORCEINLINE void __set_exc_entry(rv_csr_t addr)
Set Exception entry address.
__STATIC_FORCEINLINE void __ECLIC_SetTrigIRQ(IRQn_Type IRQn, uint32_t trig)
Set trigger mode and polarity for a specific interrupt.
__STATIC_FORCEINLINE void __ECLIC_SetMth(uint8_t mth)
Set Machine Mode Interrupt Level Threshold.
__STATIC_FORCEINLINE rv_csr_t __ECLIC_GetVector_S(IRQn_Type IRQn)
Get Interrupt Vector of a specific interrupt in supervisor mode.
@ SysTimerSW_IRQn
System Timer SW interrupt.
@ Reserved10_IRQn
Internal reserved.
@ Reserved2_IRQn
Internal reserved.
@ Reserved15_IRQn
Internal reserved.
@ Reserved14_IRQn
Internal reserved.
@ SysTimer_IRQn
System Timer Interrupt.
@ Reserved0_IRQn
Internal reserved.
@ Reserved16_IRQn
Internal reserved.
@ Reserved9_IRQn
Internal reserved.
@ Reserved11_IRQn
Internal reserved.
@ Reserved6_IRQn
Internal reserved.
@ Reserved12_IRQn
Internal reserved.
@ Reserved13_IRQn
Internal reserved.
@ Reserved5_IRQn
Internal reserved.
@ Reserved4_IRQn
Internal reserved.
@ Reserved8_IRQn
Internal reserved.
@ FirstDeviceSpecificInterrupt_IRQn
First Device Specific Interrupt.
@ Reserved1_IRQn
Internal reserved.
@ SOC_INT_MAX
Number of total interrupts.
@ Reserved7_IRQn
Internal reserved.
@ Reserved3_IRQn
Internal reserved.
#define __IM
Defines 'read only' structure member permissions.
#define __IOM
Defines 'read/write' structure member permissions.
unsigned long rv_csr_t
Type of Control and Status Register(CSR), depends on the XLEN defined in RISC-V.
Access to the machine mode register structure of INTIP, INTIE, INTATTR, INTCTL.
__IOM uint8_t INTIP
Offset: 0x000 (R/W) Interrupt set pending register.
__IOM uint8_t INTIE
Offset: 0x001 (R/W) Interrupt set enable register.
__IOM uint8_t INTATTR
Offset: 0x002 (R/W) Interrupt set attributes register.
__IOM uint8_t INTCTRL
Offset: 0x003 (R/W) Interrupt configure register.
Access to the structure of ECLIC Memory Map.
__IM uint8_t RESERVED7
__IM uint8_t RESERVED3
__IOM uint8_t SSTH
Offset: 0x2009 (R) CLIC supervisor mode threshold register, which is a mirror to mintthresh....
__IM uint32_t INFO
Offset: 0x004 (R/ ) CLIC information register.
__IM uint8_t RESERVED1
__IM uint8_t RESERVED8
__IOM uint8_t CFG
Offset: 0x000 (R/W) CLIC configuration register.
__IOM uint8_t STH
Offset: 0x009 (R/W ) CLIC supervisor mode interrupt-level threshold.
__IM uint8_t RESERVED6
__IOM uint8_t MTH
Offset: 0x00B(R/W) CLIC machine mode interrupt-level threshold.
Union type to access CLICFG configure register.
__IM uint8_t nmbits
bit: 5..6 ties to 1 if supervisor-level interrupt supported, or else it's reserved
__IM uint8_t _reserved0
__IM uint8_t _reserved1
uint8_t w
Type used for byte access.
__IOM uint8_t nlbits
bit: 1..4 specified the bit-width of level and priority in the register clicintctl[i]
Union type to access CLICINFO information register.
__IM uint32_t _reserved0
bit: 29..31 Reserved
__IM uint32_t intctlbits
bit: 21..24 specifies how many hardware bits are actually implemented in the clicintctl registers
__IM uint32_t w
Type used for word access.
__IM uint32_t version
bit: 13..20 Hardware implementation version number.
__IM uint32_t shd_num
bit: 25..28 number of shadow register groups for single mode(M/S mode)
__IM uint32_t numint
bit: 0..12 number of maximum interrupt inputs supported