1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #ifndef BSP_IRQ_CORE_H
8 #define BSP_IRQ_CORE_H
9
10 /***********************************************************************************************************************
11 * Includes <System Includes> , "Project Includes"
12 **********************************************************************************************************************/
13
14 /** Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */
15 FSP_HEADER
16
17 /***********************************************************************************************************************
18 * Macro definitions
19 **********************************************************************************************************************/
20 #define BSP_ICU_VECTOR_MAX_ENTRIES (BSP_VECTOR_TABLE_MAX_ENTRIES)
21
22 #if (0 == BSP_CFG_CORE_CR52)
23 #define BSP_PRV_GICD_ADDRESS (GICD0)
24 #define BSP_PRV_GICR_TARGET0_INTREG_ADDRESS (GICR0_TARGET0_INTREG)
25 #define BSP_PRV_GICR_TARGET0_IFREG_ADDRESS (GICR0_TARGET0_IFREG)
26
27 #elif (1 == BSP_CFG_CORE_CR52)
28 #define BSP_PRV_GICD_ADDRESS (GICD1)
29 #define BSP_PRV_GICR_TARGET0_INTREG_ADDRESS (GICR1_TARGET0_INTREG)
30 #define BSP_PRV_GICR_TARGET0_IFREG_ADDRESS (GICR1_TARGET0_IFREG)
31
32 #endif
33
34 #define BSP_EVENT_SGI_PPI_ARRAY_NUM (2U)
35 #define BSP_NON_SELECTABLE_ICFGR_MAX (BSP_FEATURE_BSP_NON_SELECTABLE_INTERRUPT_EVENT_NUM / \
36 BSP_INTERRUPT_TYPE_OFFSET)
37
38 #define BSP_ICFGR_MAX ((BSP_FEATURE_BSP_SELECTABLE_INTERRUPT_START + \
39 BSP_FEATURE_BSP_SELECTABLE_INTERRUPT_EVENT_NUM) / \
40 BSP_INTERRUPT_TYPE_OFFSET)
41 #define BSP_EVENT_ARRAY_NUM (BSP_FEATURE_BSP_EVENT_NUM_MAX / \
42 BSP_INTERRUPT_TYPE_OFFSET + 1U)
43
44 #define BSP_PRV_IRQ_CONFIG_MASK (0x000000FFU)
45 #define BSP_PRV_GICD_ICFGR_INT_CONFIG_MASK (1UL << 1UL)
46
47 #define BSP_PRV_GIC_REG_STRIDE04 (4U)
48 #define BSP_PRV_GIC_REG_STRIDE16 (16U)
49 #define BSP_PRV_GIC_REG_STRIDE32 (32U)
50
51 #define BSP_PRV_GIC_REG_BITS1 (1U)
52 #define BSP_PRV_GIC_REG_BITS2 (2U)
53 #define BSP_PRV_GIC_REG_BITS8 (8U)
54
55 #define BSP_PRV_GIC_REG_MASK_1BIT (1U)
56
57 #define BSP_PRV_GIC_LOWEST_PPI_INTERRUPT_NUM (-17)
58
59 /***********************************************************************************************************************
60 * Typedef definitions
61 **********************************************************************************************************************/
62
63 /***********************************************************************************************************************
64 * Exported global variables
65 **********************************************************************************************************************/
66 extern void * gp_renesas_isr_context[BSP_ICU_VECTOR_MAX_ENTRIES + BSP_CORTEX_VECTOR_TABLE_ENTRIES];
67
68 /***********************************************************************************************************************
69 * Exported global functions (to be accessed by other files)
70 **********************************************************************************************************************/
71
72 /***********************************************************************************************************************
73 * Inline Functions
74 **********************************************************************************************************************/
75
76 /*******************************************************************************************************************//**
77 * @brief Sets the ISR context associated with the requested IRQ.
78 *
79 * @param[in] irq IRQ number (parameter checking must ensure the IRQ number is valid before calling this
80 * function.
81 * @param[in] p_context ISR context for IRQ.
82 **********************************************************************************************************************/
r_fsp_irq_context_set(IRQn_Type const irq,void * p_context)83 __STATIC_INLINE void r_fsp_irq_context_set (IRQn_Type const irq, void * p_context)
84 {
85 /* This provides access to the ISR context array defined in bsp_irq.c. This is an inline function instead of
86 * being part of bsp_irq.c for performance considerations because it is used in interrupt service routines. */
87 gp_renesas_isr_context[irq + BSP_VECTOR_NUM_OFFSET] = p_context;
88 }
89
90 /*******************************************************************************************************************//**
91 * Clear the GIC pending interrupt.
92 *
93 * @param[in] irq Interrupt for which to clear the Pending bit. Note that the enums listed for IRQn_Type are
94 * only those for the Cortex Processor Exceptions Numbers.
95 **********************************************************************************************************************/
r_bsp_irq_clear_pending(IRQn_Type irq)96 __STATIC_INLINE void r_bsp_irq_clear_pending (IRQn_Type irq)
97 {
98 GICD_Type * GICD;
99 GICR_SGI_PPI_Type * GICR_TARGET0_INTREG;
100
101 GICD = BSP_PRV_GICD_ADDRESS;
102 GICR_TARGET0_INTREG = BSP_PRV_GICR_TARGET0_INTREG_ADDRESS;
103
104 if (irq >= 0)
105 {
106 uint32_t _irq = (uint32_t) irq;
107 GICD->GICD_ICPENDR[_irq / BSP_PRV_GIC_REG_STRIDE32] =
108 (uint32_t) (BSP_PRV_GIC_REG_BITS1 << (_irq % BSP_PRV_GIC_REG_STRIDE32));
109 }
110 else
111 {
112 uint32_t _irq = (uint32_t) (irq + BSP_VECTOR_NUM_OFFSET);
113 GICR_TARGET0_INTREG->GICR_ICPENDR0 = (uint32_t) (BSP_PRV_GIC_REG_BITS1 << _irq);
114 }
115 }
116
117 /*******************************************************************************************************************//**
118 * Get the GIC pending interrupt.
119 *
120 * @param[in] irq Interrupt that gets a pending bit.. Note that the enums listed for IRQn_Type are
121 * only those for the Cortex Processor Exceptions Numbers.
122 *
123 * @return Value indicating the status of the level interrupt.
124 **********************************************************************************************************************/
r_bsp_irq_pending_get(IRQn_Type irq)125 __STATIC_INLINE uint32_t r_bsp_irq_pending_get (IRQn_Type irq)
126 {
127 GICD_Type * GICD;
128 GICR_SGI_PPI_Type * GICR_TARGET0_INTREG;
129 uint32_t value = 0;
130
131 GICD = BSP_PRV_GICD_ADDRESS;
132 GICR_TARGET0_INTREG = BSP_PRV_GICR_TARGET0_INTREG_ADDRESS;
133
134 if (irq >= 0)
135 {
136 uint32_t _irq = (uint32_t) irq;
137 uint32_t shift = (_irq % BSP_PRV_GIC_REG_STRIDE32);
138 value = (GICD->GICD_ISPENDR[_irq / BSP_PRV_GIC_REG_STRIDE32] >> shift) & (uint32_t) (BSP_PRV_GIC_REG_MASK_1BIT);
139 }
140 else
141 {
142 uint32_t _irq = (uint32_t) (irq + BSP_VECTOR_NUM_OFFSET);
143 uint32_t shift = _irq;
144 value = (GICR_TARGET0_INTREG->GICR_ISPENDR0 >> shift) & (uint32_t) (BSP_PRV_GIC_REG_MASK_1BIT);
145 }
146
147 return value;
148 }
149
150 /*******************************************************************************************************************//**
151 * Sets the interrupt priority and context.
152 *
153 * @param[in] irq The IRQ number to configure.
154 * @param[in] priority GIC priority of the interrupt
155 **********************************************************************************************************************/
r_bsp_irq_cfg(IRQn_Type const irq,uint32_t priority)156 __STATIC_INLINE void r_bsp_irq_cfg (IRQn_Type const irq, uint32_t priority)
157 {
158 #if (52U == __CORTEX_R)
159 GICD_Type * GICD;
160 GICR_SGI_PPI_Type * GICR_TARGET0_INTREG;
161
162 GICD = BSP_PRV_GICD_ADDRESS;
163 GICR_TARGET0_INTREG = BSP_PRV_GICR_TARGET0_INTREG_ADDRESS;
164
165 if (irq >= 0)
166 {
167 uint32_t _irq = (uint32_t) irq;
168
169 /* Set the interrupt group to 1 (IRQ) */
170 GICD->GICD_IGROUPR[_irq / BSP_PRV_GIC_REG_STRIDE32] |=
171 (uint32_t) (BSP_PRV_GIC_REG_BITS1 << (_irq % BSP_PRV_GIC_REG_STRIDE32));
172
173 /* Set the interrupt priority */
174 GICD->GICD_IPRIORITYR[_irq / BSP_PRV_GIC_REG_STRIDE04] &=
175 (uint32_t) (~(BSP_PRV_IRQ_CONFIG_MASK << (BSP_PRV_GIC_REG_BITS8 * (_irq % BSP_PRV_GIC_REG_STRIDE04))));
176 GICD->GICD_IPRIORITYR[_irq / BSP_PRV_GIC_REG_STRIDE04] |=
177 (priority <<
178 (BSP_FEATURE_BSP_IRQ_PRIORITY_POS_BIT + (BSP_PRV_GIC_REG_BITS8 * (_irq % BSP_PRV_GIC_REG_STRIDE04))));
179 }
180 else
181 {
182 uint32_t _irq = (uint32_t) (irq + BSP_VECTOR_NUM_OFFSET);
183
184 /* Set the interrupt group to 1 (IRQ) */
185 GICR_TARGET0_INTREG->GICR_IGROUPR0 |= (uint32_t) (BSP_PRV_GIC_REG_BITS1 << _irq);
186
187 /* Set the interrupt priority */
188 GICR_TARGET0_INTREG->GICR_IPRIORITYR[_irq / BSP_PRV_GIC_REG_STRIDE04] &=
189 (uint32_t) (~(BSP_PRV_IRQ_CONFIG_MASK << (BSP_PRV_GIC_REG_BITS8 * (_irq % BSP_PRV_GIC_REG_STRIDE04))));
190 GICR_TARGET0_INTREG->GICR_IPRIORITYR[_irq / BSP_PRV_GIC_REG_STRIDE04] |=
191 (priority <<
192 (BSP_FEATURE_BSP_IRQ_PRIORITY_POS_BIT + (BSP_PRV_GIC_REG_BITS8 * (_irq % BSP_PRV_GIC_REG_STRIDE04))));
193 }
194 #endif
195 }
196
197 /*******************************************************************************************************************//**
198 * Enable the IRQ in the GIC (Without clearing the pending bit).
199 *
200 * @param[in] irq The IRQ number to enable. Note that the enums listed for IRQn_Type are only those for the
201 * Cortex Processor Exceptions Numbers.
202 **********************************************************************************************************************/
r_bsp_irq_enable_no_clear(IRQn_Type const irq)203 __STATIC_INLINE void r_bsp_irq_enable_no_clear (IRQn_Type const irq)
204 {
205 GICD_Type * GICD;
206 GICR_SGI_PPI_Type * GICR_TARGET0_INTREG;
207
208 GICD = BSP_PRV_GICD_ADDRESS;
209 GICR_TARGET0_INTREG = BSP_PRV_GICR_TARGET0_INTREG_ADDRESS;
210
211 if (irq >= 0)
212 {
213 uint32_t _irq = (uint32_t) irq;
214 GICD->GICD_ISENABLER[_irq / BSP_PRV_GIC_REG_STRIDE32] |=
215 (uint32_t) (BSP_PRV_GIC_REG_BITS1 << (_irq % BSP_PRV_GIC_REG_STRIDE32));
216 }
217 else
218 {
219 uint32_t _irq = (uint32_t) (irq + BSP_VECTOR_NUM_OFFSET);
220 GICR_TARGET0_INTREG->GICR_ISENABLER0 |= (uint32_t) (BSP_PRV_GIC_REG_BITS1 << _irq);
221 }
222 }
223
224 /*******************************************************************************************************************//**
225 * Disables interrupts in the GIC.
226 *
227 * @param[in] irq The IRQ number to disable in the GIC. Note that the enums listed for IRQn_Type are
228 * only those for the Cortex Processor Exceptions Numbers.
229 **********************************************************************************************************************/
r_bsp_irq_disable(IRQn_Type const irq)230 __STATIC_INLINE void r_bsp_irq_disable (IRQn_Type const irq)
231 {
232 GICD_Type * GICD;
233 GICR_SGI_PPI_Type * GICR_TARGET0_INTREG;
234
235 GICD = BSP_PRV_GICD_ADDRESS;
236 GICR_TARGET0_INTREG = BSP_PRV_GICR_TARGET0_INTREG_ADDRESS;
237
238 if (irq >= 0)
239 {
240 uint32_t _irq = (uint32_t) irq;
241 GICD->GICD_ICENABLER[_irq / BSP_PRV_GIC_REG_STRIDE32] =
242 (uint32_t) (BSP_PRV_GIC_REG_BITS1 << (_irq % BSP_PRV_GIC_REG_STRIDE32));
243 }
244 else
245 {
246 uint32_t _irq = (uint32_t) (irq + BSP_VECTOR_NUM_OFFSET);
247 GICR_TARGET0_INTREG->GICR_ICENABLER0 = (uint32_t) (BSP_PRV_GIC_REG_BITS1 << _irq);
248 }
249
250 __DSB();
251 __ISB();
252 }
253
254 /*******************************************************************************************************************//**
255 * Sets the interrupt detect type.
256 *
257 * @param[in] irq The IRQ number to configure.
258 * @param[in] detect_type GIC detect type of the interrupt (0 : active-HIGH level, 1 : rising edge-triggerd).
259 **********************************************************************************************************************/
r_bsp_irq_detect_type_set(IRQn_Type const irq,uint32_t detect_type)260 __STATIC_INLINE void r_bsp_irq_detect_type_set (IRQn_Type const irq, uint32_t detect_type)
261 {
262 GICD_Type * GICD;
263 GICR_SGI_PPI_Type * GICR_TARGET0_INTREG;
264
265 GICD = BSP_PRV_GICD_ADDRESS;
266 GICR_TARGET0_INTREG = BSP_PRV_GICR_TARGET0_INTREG_ADDRESS;
267
268 if (irq >= 0)
269 {
270 uint32_t _irq = (uint32_t) irq;
271 if (0 != detect_type)
272 {
273 GICD->GICD_ICFGR[_irq / BSP_PRV_GIC_REG_STRIDE16] |=
274 (uint32_t) (BSP_PRV_GICD_ICFGR_INT_CONFIG_MASK <<
275 (BSP_PRV_GIC_REG_BITS2 * (_irq % BSP_PRV_GIC_REG_STRIDE16)));
276 }
277 else
278 {
279 GICD->GICD_ICFGR[_irq / BSP_PRV_GIC_REG_STRIDE16] &=
280 ~((uint32_t) (BSP_PRV_GICD_ICFGR_INT_CONFIG_MASK <<
281 (BSP_PRV_GIC_REG_BITS2 * (_irq % BSP_PRV_GIC_REG_STRIDE16))));
282 }
283 }
284 else if (irq >= BSP_PRV_GIC_LOWEST_PPI_INTERRUPT_NUM)
285 {
286 uint32_t _irq = (uint32_t) (irq + BSP_VECTOR_NUM_OFFSET);
287 if (0 != detect_type)
288 {
289 GICR_TARGET0_INTREG->GICR_ICFGR1 |=
290 (uint32_t) (BSP_PRV_GICD_ICFGR_INT_CONFIG_MASK <<
291 (BSP_PRV_GIC_REG_BITS2 * (_irq % BSP_PRV_GIC_REG_STRIDE16)));
292 }
293 else
294 {
295 GICR_TARGET0_INTREG->GICR_ICFGR1 &=
296 ~((uint32_t) (BSP_PRV_GICD_ICFGR_INT_CONFIG_MASK <<
297 (BSP_PRV_GIC_REG_BITS2 * (_irq % BSP_PRV_GIC_REG_STRIDE16))));
298 }
299 }
300 else
301 {
302 /* The register that sets the SGI interrupt type (GICR_ICFGR0) is read-only, so do not set it. */
303 }
304 }
305
306 /*******************************************************************************************************************//**
307 * Sets the interrupt Group.
308 *
309 * @param[in] irq The IRQ number to configure.
310 * @param[in] interrupt_group GIC interrupt group number ( 0 : FIQ, 1 : IRQ ).
311 **********************************************************************************************************************/
r_bsp_irq_group_set(IRQn_Type const irq,uint32_t interrupt_group)312 __STATIC_INLINE void r_bsp_irq_group_set (IRQn_Type const irq, uint32_t interrupt_group)
313 {
314 GICD_Type * GICD;
315 GICR_SGI_PPI_Type * GICR_TARGET0_INTREG;
316
317 GICD = BSP_PRV_GICD_ADDRESS;
318 GICR_TARGET0_INTREG = BSP_PRV_GICR_TARGET0_INTREG_ADDRESS;
319
320 if (irq >= 0)
321 {
322 uint32_t _irq = (uint32_t) irq;
323 GICD->GICD_IGROUPR[_irq / BSP_PRV_GIC_REG_STRIDE32] |= (interrupt_group << (_irq % BSP_PRV_GIC_REG_STRIDE32));
324 }
325 else
326 {
327 uint32_t _irq = (uint32_t) (irq + BSP_VECTOR_NUM_OFFSET);
328 GICR_TARGET0_INTREG->GICR_IGROUPR0 |= interrupt_group << _irq;
329 }
330 }
331
332 /*******************************************************************************************************************//**
333 * @internal
334 * @addtogroup BSP_MCU_PRV Internal BSP Documentation
335 * @ingroup RENESAS_INTERNAL
336 * @{
337 **********************************************************************************************************************/
338
339 /* Public functions defined in bsp.h */
340 void bsp_irq_core_cfg(void); // Used internally by BSP
341 void bsp_common_interrupt_handler(uint32_t id);
342
343 /** @} (end addtogroup BSP_MCU_PRV) */
344
345 /** Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */
346 FSP_FOOTER
347
348 #endif
349