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
19 /********************************************************************************************************
20 * @file plic.h
21 *
22 * @brief This is the header file for B91
23 *
24 * @author Driver Group
25 *
26 *******************************************************************************************************/
27 /** @page PLIC
28 *
29 * Introduction
30 * ===============
31 * platform-level interrupt controller (PLIC)
32 *
33 * API Reference
34 * ===============
35 * Header File: plic.h
36 */
37
38 #ifndef INTERRUPT_H
39 #define INTERRUPT_H
40 #include "core.h"
41
42 #include "reg_include/register_b91.h"
43 #include "compiler.h"
44
45 typedef struct
46 {
47 unsigned char preempt_en;
48 unsigned char threshold;
49 }preempt_config_t ;
50
51
52 extern unsigned char g_plic_preempt_en;
53
54 typedef enum{
55 IRQ0_EXCEPTION ,
56 IRQ1_SYSTIMER,
57 IRQ2_ALG,
58 IRQ3_TIMER1,
59 IRQ4_TIMER0,
60 IRQ5_DMA,
61 IRQ6_BMC,
62 IRQ7_USB_CTRL_EP_SETUP,
63 IRQ8_USB_CTRL_EP_DATA,
64 IRQ9_USB_CTRL_EP_STATUS,
65 IRQ10_USB_CTRL_EP_SETINF,
66 IRQ11_USB_ENDPOINT,
67 IRQ12_ZB_DM,
68 IRQ13_ZB_BLE,
69 IRQ14_ZB_BT,
70 IRQ15_ZB_RT,
71 IRQ16_PWM,
72 IRQ17_PKE,
73 IRQ18_UART1,
74 IRQ19_UART0,
75 IRQ20_DFIFO,
76 IRQ21_I2C,
77 IRQ22_SPI_AHB,
78 IRQ23_SPI_APB,
79 IRQ24_USB_PWDN,
80 IRQ25_GPIO,
81 IRQ26_GPIO2RISC0,
82 IRQ27_GPIO2RISC1,
83 IRQ28_SOFT,
84
85 IRQ29_NPE_BUS0,
86 IRQ30_NPE_BUS1,
87 IRQ31_NPE_BUS2,
88 IRQ32_NPE_BUS3,
89 IRQ33_NPE_BUS4,
90
91 IRQ34_USB_250US,
92 IRQ35_USB_RESET,
93 IRQ36_NPE_BUS7,
94 IRQ37_NPE_BUS8,
95
96 IRQ42_NPE_BUS13=42,
97 IRQ43_NPE_BUS14,
98 IRQ44_NPE_BUS15,
99
100 IRQ46_NPE_BUS17=46,
101
102 IRQ50_NPE_BUS21=50,
103 IRQ51_NPE_BUS22,
104 IRQ52_NPE_BUS23,
105 IRQ53_NPE_BUS24,
106 IRQ54_NPE_BUS25,
107 IRQ55_NPE_BUS26,
108 IRQ56_NPE_BUS27,
109 IRQ57_NPE_BUS28,
110 IRQ58_NPE_BUS29,
111 IRQ59_NPE_BUS30,
112 IRQ60_NPE_BUS31,
113
114 IRQ61_NPE_COMB,
115 IRQ62_PM_TM,
116 IRQ63_EOC,
117
118 } irq_source_e;
119
120 typedef enum{
121 IRQ_PRI_LEV0,//Never interrupt
122 IRQ_PRI_LEV1,
123 IRQ_PRI_LEV2,
124 IRQ_PRI_LEV3,
125 }irq_priority_e;
126
127
128 /**
129 * @brief This function serves to set plic feature.
130 * @param[in] feature - preemptive priority interrupt feature and the vector mode.
131 * @return none
132 */
plic_set_feature(feature_e feature)133 static inline void plic_set_feature (feature_e feature)
134 {
135 reg_irq_feature = feature;//enable vectored in PLIC
136 }
137
138 /**
139 * @brief This function serves to enable preemptive priority interrupt feature.
140 * @return none
141 */
plic_preempt_feature_en(void)142 static inline void plic_preempt_feature_en (void)
143 {
144 reg_irq_feature |= FLD_FEATURE_PREEMPT_PRIORITY_INT_EN;
145 g_plic_preempt_en=1;
146 }
147
148 /**
149 * @brief This function serves to enable preemptive priority interrupt feature.
150 * @return none
151 */
plic_preempt_feature_dis(void)152 static inline void plic_preempt_feature_dis (void)
153 {
154 reg_irq_feature &=(~ FLD_FEATURE_PREEMPT_PRIORITY_INT_EN);
155 g_plic_preempt_en=0;
156 }
157
158
159 /**
160 * @brief This function serves to set plic pending.
161 * @param[in] src - interrupt source.
162 * @return none
163 */
plic_set_pending(irq_source_e src)164 static inline void plic_set_pending (irq_source_e src)
165 {
166 reg_irq_pending(src)=BIT(src%32);
167 }
168
169 /**
170 * @brief This function serves to set Priority Threshold,Only active interrupts with priorities strictly greater than the threshold will cause interrupt.
171 * @param[in] threshold - threshold level.
172 * @return none
173 */
plic_set_threshold(unsigned char threshold)174 static inline void plic_set_threshold (unsigned char threshold)
175 {
176 reg_irq_threshold=threshold;
177 }
178
179 /**
180 * @brief This function serves to set preemptive priority level,The priority value 0 is reserved to mean "never interrupt".
181 * the larger the priority value, the higher the interrupt priority.
182 * @param[in] src- interrupt source.
183 * @param[in] priority- priority level.
184 * @return none
185 */
plic_set_priority(irq_source_e src,irq_priority_e priority)186 static inline void plic_set_priority (irq_source_e src, irq_priority_e priority)
187 {
188 reg_irq_src_priority(src)=priority;
189 }
190
191
192 /**
193 * @brief This function serves to enable plic interrupt source.
194 * @param[in] src - interrupt source.
195 * @return none
196 */
plic_interrupt_enable(irq_source_e src)197 static inline void plic_interrupt_enable(irq_source_e src)
198 {
199 reg_irq_src(src) |= BIT(src%32);
200
201 }
202
203 /**
204 * @brief This function serves to disable plic interrupt source.
205 * @param[in] src - interrupt source.
206 * @return none
207 */
plic_interrupt_disable(irq_source_e src)208 static inline void plic_interrupt_disable(irq_source_e src)
209 {
210 reg_irq_src(src) &= (~ BIT(src%32));
211 }
212
213 /**
214 * @brief This function serves to clear interrupt source has completed.
215 * @param[in] src - interrupt source.
216 * @return none
217 */
plic_interrupt_complete(irq_source_e src)218 static inline void plic_interrupt_complete(irq_source_e src)
219 {
220 reg_irq_done = src;
221 }
222
223 /**
224 * @brief This function serves to claim interrupt.
225 * @return it return the source id which interrupted in irq_source_e enum .
226 */
plic_interrupt_claim(void)227 static inline unsigned int plic_interrupt_claim(void)
228 {
229 return reg_irq_done;
230 }
231
232
233
234 /**
235 * @brief This function serves to config plic when enter some function process such as flash.
236 * @param[in] preempt_en - 1 can disturb by interrupt, 0 can't disturb by interrupt.
237 * @param[in] threshold - interrupt threshold.when the interrupt priority> interrupt threshold,the function process will be disturb by interrupt.
238 * @return none
239 */
240 _attribute_ram_code_sec_noinline_ unsigned int plic_enter_critical_sec(unsigned char preempt_en ,unsigned char threshold);
241
242
243
244 /**
245 * @brief This function serves to config plic when exit some function process such as flash.
246 * @param[in] preempt_en - 1 can disturb by interrupt, 0 can disturb by interrupt.
247 * @param[in] r - the value of mie register to restore.
248 * @return none
249 */
250 _attribute_ram_code_sec_noinline_ void plic_exit_critical_sec(unsigned char preempt_en ,unsigned int r);
251
252
253 #endif
254