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