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