• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************/
18 /**	@page PLIC
19  *
20  *	Introduction
21  *	===============
22  *   platform-level interrupt controller (PLIC)
23  *
24  *	API Reference
25  *	===============
26  *	Header File: plic.h
27  */
28 
29 #ifndef INTERRUPT_H
30 #define INTERRUPT_H
31 #include "core.h"
32 
33 #include "compiler.h"
34 #include "reg_include/register_b91.h"
35 
36 typedef struct {
37     unsigned char preempt_en;
38     unsigned char threshold;
39 } preempt_config_t;
40 
41 extern unsigned char g_plic_preempt_en;
42 
43 typedef enum {
44     IRQ0_EXCEPTION,
45     IRQ1_SYSTIMER,
46     IRQ2_ALG,
47     IRQ3_TIMER1,
48     IRQ4_TIMER0,
49     IRQ5_DMA,
50     IRQ6_BMC,
51     IRQ7_USB_CTRL_EP_SETUP,
52     IRQ8_USB_CTRL_EP_DATA,
53     IRQ9_USB_CTRL_EP_STATUS,
54     IRQ10_USB_CTRL_EP_SETINF,
55     IRQ11_USB_ENDPOINT,
56     IRQ12_ZB_DM,
57     IRQ13_ZB_BLE,
58     IRQ14_ZB_BT,
59     IRQ15_ZB_RT,
60     IRQ16_PWM,
61     IRQ17_PKE,
62     IRQ18_UART1,
63     IRQ19_UART0,
64     IRQ20_DFIFO,
65     IRQ21_I2C,
66     IRQ22_SPI_AHB,
67     IRQ23_SPI_APB,
68     IRQ24_USB_PWDN,
69     IRQ25_GPIO,
70     IRQ26_GPIO2RISC0,
71     IRQ27_GPIO2RISC1,
72     IRQ28_SOFT,
73 
74     IRQ29_NPE_BUS0,
75     IRQ30_NPE_BUS1,
76     IRQ31_NPE_BUS2,
77     IRQ32_NPE_BUS3,
78     IRQ33_NPE_BUS4,
79 
80     IRQ34_USB_250US,
81     IRQ35_USB_RESET,
82     IRQ36_NPE_BUS7,
83     IRQ37_NPE_BUS8,
84 
85     IRQ42_NPE_BUS13 = 42,
86     IRQ43_NPE_BUS14,
87     IRQ44_NPE_BUS15,
88 
89     IRQ46_NPE_BUS17 = 46,
90 
91     IRQ50_NPE_BUS21 = 50,
92     IRQ51_NPE_BUS22,
93     IRQ52_NPE_BUS23,
94     IRQ53_NPE_BUS24,
95     IRQ54_NPE_BUS25,
96     IRQ55_NPE_BUS26,
97     IRQ56_NPE_BUS27,
98     IRQ57_NPE_BUS28,
99     IRQ58_NPE_BUS29,
100     IRQ59_NPE_BUS30,
101     IRQ60_NPE_BUS31,
102 
103     IRQ61_NPE_COMB,
104     IRQ62_PM_TM,
105     IRQ63_EOC,
106 } irq_source_e;
107 
108 typedef enum {
109     IRQ_PRI_LEV0,  // Never interrupt
110     IRQ_PRI_LEV1,
111     IRQ_PRI_LEV2,
112     IRQ_PRI_LEV3,
113 } irq_priority_e;
114 
115 /**
116  * @brief    This function serves to set plic feature.
117  * @param[in]   feature - preemptive priority interrupt feature and the vector mode.
118  * @return  none
119  */
plic_set_feature(feature_e feature)120 static inline void plic_set_feature(feature_e feature)
121 {
122     reg_irq_feature = feature;  // enable vectored in PLIC
123 }
124 
125 /**
126  * @brief    This function serves to enable preemptive priority interrupt feature.
127  * @return  none
128  */
plic_preempt_feature_en(void)129 static inline void plic_preempt_feature_en(void)
130 {
131     reg_irq_feature |= FLD_FEATURE_PREEMPT_PRIORITY_INT_EN;
132     g_plic_preempt_en = 1;
133 }
134 
135 /**
136  * @brief    This function serves to enable preemptive priority interrupt feature.
137  * @return  none
138  */
plic_preempt_feature_dis(void)139 static inline void plic_preempt_feature_dis(void)
140 {
141     reg_irq_feature &= (~FLD_FEATURE_PREEMPT_PRIORITY_INT_EN);
142     g_plic_preempt_en = 0;
143 }
144 
145 /**
146  * @brief    This function serves to set plic pending.
147  * @param[in]  src - interrupt source.
148  * @return  none
149  */
plic_set_pending(irq_source_e src)150 static inline void plic_set_pending(irq_source_e src)
151 {
152     reg_irq_pending(src) = BIT(src % 32);
153 }
154 
155 /**
156  * @brief    This function serves to set Priority Threshold,
157  *           Only active interrupts with priorities strictly greater than the threshold will cause interrupt.
158  * @param[in]   threshold -  threshold level.
159  * @return  none
160  */
plic_set_threshold(unsigned char threshold)161 static inline void plic_set_threshold(unsigned char threshold)
162 {
163     reg_irq_threshold = threshold;
164 }
165 
166 /**
167  * @brief    This function serves to set preemptive priority level,
168  *           the priority value 0 is reserved to mean "never interrupt".
169  *           The larger the priority value, the higher the interrupt priority.
170  * @param[in]   src- interrupt source.
171  * @param[in]   priority-  priority level.
172  * @return  none
173  */
plic_set_priority(irq_source_e src,irq_priority_e priority)174 static inline void plic_set_priority(irq_source_e src, irq_priority_e priority)
175 {
176     reg_irq_src_priority(src) = priority;
177 }
178 
179 /**
180  * @brief    This function serves to enable plic interrupt source.
181  * @param[in]   src - interrupt source.
182  * @return  none
183  */
plic_interrupt_enable(irq_source_e src)184 static inline void plic_interrupt_enable(irq_source_e src)
185 {
186     reg_irq_src(src) |= BIT(src % 32);
187 }
188 
189 /**
190  * @brief    This function serves to disable plic interrupt source.
191  * @param[in]   src - interrupt source.
192  * @return  none
193  */
plic_interrupt_disable(irq_source_e src)194 static inline void plic_interrupt_disable(irq_source_e src)
195 {
196     reg_irq_src(src) &= (~BIT(src % 32));
197 }
198 
199 /**
200  * @brief    This function serves to clear interrupt source has completed.
201  * @param[in] src - interrupt source.
202  * @return  none
203  */
plic_interrupt_complete(irq_source_e src)204 static inline void plic_interrupt_complete(irq_source_e src)
205 {
206     reg_irq_done = src;
207 }
208 
209 /**
210  * @brief    This function serves to claim  interrupt.
211  * @return   it return the source id which interrupted in irq_source_e enum .
212  */
plic_interrupt_claim(void)213 static inline unsigned int plic_interrupt_claim(void)
214 {
215     return reg_irq_done;
216 }
217 
218 /**
219  * @brief    This function serves to config plic when enter some function process such as flash.
220  * @param[in]   preempt_en - 1 can disturb by interrupt, 0 can't disturb by interrupt.
221  * @param[in]   threshold  - interrupt threshold.when the interrupt priority> interrupt threshold,
222  *                           the function process will be disturb by interrupt.
223  * @return  none
224 */
225 _attribute_ram_code_sec_noinline_ unsigned int plic_enter_critical_sec(unsigned char preempt_en,
226                                                                        unsigned char threshold);
227 
228 /**
229  * @brief    This function serves to config plic when exit some function process such as flash.
230  * @param[in]   preempt_en - 1 can disturb by interrupt, 0 can disturb by interrupt.
231  * @param[in]    r         - the value of mie register to restore.
232  * @return  none
233 */
234 _attribute_ram_code_sec_noinline_ void plic_exit_critical_sec(unsigned char preempt_en, unsigned int r);
235 
236 #endif
237