source: rtems/bsps/include/xil/arm/cortexa9/xil_exception.h @ 77e7bd9

Last change on this file since 77e7bd9 was c0fad60, checked in by Kinsey Moore <kinsey.moore@…>, on 02/02/23 at 20:58:56

bsps/xil: Import full xil_exception.h

This imports the full xil_exception.h instead of an empty stub. This is
required for some Xilinx drivers. The imported files adhere to the
current VERSION file.

  • Property mode set to 100644
File size: 16.7 KB
Line 
1/******************************************************************************
2* Copyright (c) 2015 - 2022 Xilinx, Inc.  All rights reserved.
3* SPDX-License-Identifier: MIT
4******************************************************************************/
5
6/*****************************************************************************/
7/**
8*
9* @file xil_exception.h
10*
11* This header file contains ARM Cortex A53,A9,R5 specific exception related APIs.
12* For exception related functions that can be used across all Xilinx supported
13* processors, please use xil_exception.h.
14*
15* @addtogroup arm_exception_apis ARM Processor Exception Handling
16* @{
17* ARM processors specific exception related APIs for cortex A53,A9 and R5 can
18* utilized for enabling/disabling IRQ, registering/removing handler for
19* exceptions or initializing exception vector table with null handler.
20*
21* <pre>
22* MODIFICATION HISTORY:
23*
24* Ver   Who      Date     Changes
25* ----- -------- -------- -----------------------------------------------
26* 5.2   pkp      28/05/15 First release
27* 6.0   mus      27/07/16 Consolidated file for a53,a9 and r5 processors
28* 6.7   mna      26/04/18 Add API Xil_GetExceptionRegisterHandler.
29* 6.7   asa      18/05/18 Update signature of API Xil_GetExceptionRegisterHandler.
30* 7.0   mus      01/03/19 Tweak Xil_ExceptionEnableMask and
31*                         Xil_ExceptionDisableMask macros to support legacy
32*                         examples for Cortexa72 EL3 exception level.
33* 7.3   mus      04/15/20 Added Xil_EnableNestedInterrupts and
34*                         Xil_DisableNestedInterrupts macros for ARMv8.
35*                         For Cortexa72, these macro's would not be supported
36*                         at EL3, as Cortexa72 is using GIC-500(GICv3),  which
37*                         triggeres only FIQ at EL3. Fix for CR#1062506
38* 7.6   mus      09/17/21 Updated flag checking to fix warning reported with
39*                         -Wundef compiler option CR#1110261
40* 7.7   mus      01/31/22 Few of the #defines in xil_exception.h in are treated
41*                         in different way based on "versal" flag. In existing
42*                         flow, this flag is defined only in xparameters.h and
43*                         BSP compiler flags, it is not defined in application
44*                         compiler flags. So, including xil_exception.h in
45*                         application source file, without including
46*                         xparameters.h results  in incorrect behavior.
47*                         Including xparameters.h in xil_exception.h to avoid
48*                         such issues. It fixes CR#1120498.
49* 7.7   sk       03/02/22 Define XExc_VectorTableEntry structure to fix
50*                         misra_c_2012_rule_5_6 violation.
51* 7.7   sk       03/02/22 Add XExc_VectorTable as extern to fix misra_c_2012_
52*                         rule_8_4 violation.
53* </pre>
54*
55******************************************************************************/
56
57/**
58 *@cond nocomments
59 */
60
61#ifndef XIL_EXCEPTION_H /* prevent circular inclusions */
62#define XIL_EXCEPTION_H /* by using protection macros */
63
64/***************************** Include Files ********************************/
65
66#include "xil_types.h"
67#include "xpseudo_asm.h"
68#include "bspconfig.h"
69#include "xparameters.h"
70
71#ifdef __cplusplus
72extern "C" {
73#endif
74
75/************************** Constant Definitions ****************************/
76
77#define XIL_EXCEPTION_FIQ       XREG_CPSR_FIQ_ENABLE
78#define XIL_EXCEPTION_IRQ       XREG_CPSR_IRQ_ENABLE
79#define XIL_EXCEPTION_ALL       (XREG_CPSR_FIQ_ENABLE | XREG_CPSR_IRQ_ENABLE)
80
81#define XIL_EXCEPTION_ID_FIRST                  0U
82#if defined (__aarch64__)
83#define XIL_EXCEPTION_ID_SYNC_INT               1U
84#define XIL_EXCEPTION_ID_IRQ_INT                2U
85#define XIL_EXCEPTION_ID_FIQ_INT                3U
86#define XIL_EXCEPTION_ID_SERROR_ABORT_INT               4U
87#define XIL_EXCEPTION_ID_LAST                   5U
88#else
89#define XIL_EXCEPTION_ID_RESET                  0U
90#define XIL_EXCEPTION_ID_UNDEFINED_INT          1U
91#define XIL_EXCEPTION_ID_SWI_INT                2U
92#define XIL_EXCEPTION_ID_PREFETCH_ABORT_INT     3U
93#define XIL_EXCEPTION_ID_DATA_ABORT_INT         4U
94#define XIL_EXCEPTION_ID_IRQ_INT                5U
95#define XIL_EXCEPTION_ID_FIQ_INT                6U
96#define XIL_EXCEPTION_ID_LAST                   6U
97#endif
98
99/*
100 * XIL_EXCEPTION_ID_INT is defined for all Xilinx processors.
101 */
102#if defined (versal) && !defined(ARMR5) && EL3
103#define XIL_EXCEPTION_ID_INT    XIL_EXCEPTION_ID_FIQ_INT
104#else
105#define XIL_EXCEPTION_ID_INT    XIL_EXCEPTION_ID_IRQ_INT
106#endif
107
108/**************************** Type Definitions ******************************/
109
110/**
111 * This typedef is the exception handler function.
112 */
113typedef void (*Xil_ExceptionHandler)(void *data);
114typedef void (*Xil_InterruptHandler)(void *data);
115
116typedef struct {
117        Xil_ExceptionHandler Handler;
118        void *Data;
119} XExc_VectorTableEntry;
120
121extern XExc_VectorTableEntry XExc_VectorTable[];
122
123/**
124*@endcond
125*/
126
127/***************** Macros (Inline Functions) Definitions ********************/
128
129/****************************************************************************/
130/**
131* @brief        Enable Exceptions.
132*
133* @param        Mask: Value for enabling the exceptions.
134*
135* @return       None.
136*
137* @note         If bit is 0, exception is enabled.
138*                       C-Style signature: void Xil_ExceptionEnableMask(Mask)
139*
140******************************************************************************/
141#if defined (versal) && !defined(ARMR5) && EL3
142/*
143 * Cortexa72 processor in versal is coupled with GIC-500, and GIC-500 supports
144 * only FIQ at EL3. Hence, tweaking this macro to always enable FIQ
145 * ignoring argument passed by user.
146 */
147#define Xil_ExceptionEnableMask(Mask)   \
148                mtcpsr(mfcpsr() & ~ ((XIL_EXCEPTION_FIQ) & XIL_EXCEPTION_ALL))
149#elif defined (__GNUC__) || defined (__ICCARM__)
150#define Xil_ExceptionEnableMask(Mask)   \
151                mtcpsr(mfcpsr() & ~ ((Mask) & XIL_EXCEPTION_ALL))
152#else
153#define Xil_ExceptionEnableMask(Mask)   \
154                {                                                               \
155                  register u32 Reg __asm("cpsr"); \
156                  mtcpsr((Reg) & (~((Mask) & XIL_EXCEPTION_ALL))); \
157                }
158#endif
159/****************************************************************************/
160/**
161* @brief        Enable the IRQ exception.
162*
163* @return   None.
164*
165* @note     None.
166*
167******************************************************************************/
168#if defined (versal) && !defined(ARMR5) && EL3
169#define Xil_ExceptionEnable() \
170                Xil_ExceptionEnableMask(XIL_EXCEPTION_FIQ)
171#else
172#define Xil_ExceptionEnable() \
173                Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ)
174#endif
175
176/****************************************************************************/
177/**
178* @brief        Disable Exceptions.
179*
180* @param        Mask: Value for disabling the exceptions.
181*
182* @return       None.
183*
184* @note         If bit is 1, exception is disabled.
185*                       C-Style signature: Xil_ExceptionDisableMask(Mask)
186*
187******************************************************************************/
188#if defined (versal) && !defined(ARMR5) && EL3
189/*
190 * Cortexa72 processor in versal is coupled with GIC-500, and GIC-500 supports
191 * only FIQ at EL3. Hence, tweaking this macro to always disable FIQ
192 * ignoring argument passed by user.
193 */
194#define Xil_ExceptionDisableMask(Mask)  \
195                mtcpsr(mfcpsr() | ((XIL_EXCEPTION_FIQ) & XIL_EXCEPTION_ALL))
196#elif defined (__GNUC__) || defined (__ICCARM__)
197#define Xil_ExceptionDisableMask(Mask)  \
198                mtcpsr(mfcpsr() | ((Mask) & XIL_EXCEPTION_ALL))
199#else
200#define Xil_ExceptionDisableMask(Mask)  \
201                {                                                                       \
202                  register u32 Reg __asm("cpsr"); \
203                  mtcpsr((Reg) | ((Mask) & XIL_EXCEPTION_ALL)); \
204                }
205#endif
206/****************************************************************************/
207/**
208* Disable the IRQ exception.
209*
210* @return   None.
211*
212* @note     None.
213*
214******************************************************************************/
215#define Xil_ExceptionDisable() \
216                Xil_ExceptionDisableMask(XIL_EXCEPTION_IRQ)
217
218#if ( defined (PLATFORM_ZYNQMP) && defined (EL3) && (EL3==1) )
219/****************************************************************************/
220/**
221* @brief        Enable nested interrupts by clearing the I bit in DAIF.This
222*                       macro is defined for Cortex-A53 64 bit mode BSP configured to run
223*                       at EL3.. However,it is not defined for Versal Cortex-A72 BSP
224*                       configured to run at EL3. Reason is, Cortex-A72 is coupled
225*                       with GIC-500(GICv3 specifications) and it triggers only FIQ at EL3.
226*
227* @return   None.
228*
229* @note     This macro is supposed to be used from interrupt handlers. In the
230*                       interrupt handler the interrupts are disabled by default (I bit
231*                       is set as 1). To allow nesting of interrupts, this macro should be
232*                       used. It clears the I bit. Once that bit is cleared and provided the
233*                       preemption of interrupt conditions are met in the GIC, nesting of
234*                       interrupts will start happening.
235*                       Caution: This macro must be used with caution. Before calling this
236*                       macro, the user must ensure that the source of the current IRQ
237*                       is appropriately cleared. Otherwise, as soon as we clear the I
238*                       bit, there can be an infinite loop of interrupts with an
239*                       eventual crash (all the stack space getting consumed).
240******************************************************************************/
241#define Xil_EnableNestedInterrupts() \
242                __asm__ __volatile__ ("mrs    X1, ELR_EL3"); \
243                __asm__ __volatile__ ("mrs    X2, SPSR_EL3");  \
244                __asm__ __volatile__ ("stp    X1,X2, [sp,#-0x10]!"); \
245                __asm__ __volatile__ ("mrs    X1, DAIF");  \
246                __asm__ __volatile__ ("bic    X1,X1,#(0x1<<7)");  \
247                __asm__ __volatile__ ("msr    DAIF, X1");  \
248
249/****************************************************************************/
250/**
251* @brief        Disable the nested interrupts by setting the I bit in DAIF. This
252*                       macro is defined for Cortex-A53 64 bit mode BSP configured to run
253*                       at EL3.
254*
255* @return   None.
256*
257* @note     This macro is meant to be called in the interrupt service routines.
258*                       This macro cannot be used independently. It can only be used when
259*                       nesting of interrupts have been enabled by using the macro
260*                       Xil_EnableNestedInterrupts(). In a typical flow, the user first
261*                       calls the Xil_EnableNestedInterrupts in the ISR at the appropriate
262*                       point. The user then must call this macro before exiting the interrupt
263*                       service routine. This macro puts the ARM back in IRQ mode and
264*                       hence sets back the I bit.
265******************************************************************************/
266#define Xil_DisableNestedInterrupts() \
267                __asm__ __volatile__ ("ldp    X1,X2, [sp,#0x10]!"); \
268                __asm__ __volatile__ ("msr    ELR_EL3, X1"); \
269                __asm__ __volatile__ ("msr    SPSR_EL3, X2"); \
270                __asm__ __volatile__ ("mrs    X1, DAIF");  \
271                __asm__ __volatile__ ("orr    X1, X1, #(0x1<<7)"); \
272                __asm__ __volatile__ ("msr    DAIF, X1");  \
273
274#elif (defined (EL1_NONSECURE) && (EL1_NONSECURE==1))
275/****************************************************************************/
276/**
277* @brief        Enable nested interrupts by clearing the I bit in DAIF.This
278*                       macro is defined for Cortex-A53 64 bit mode and Cortex-A72 64 bit
279*                       BSP configured to run at EL1 NON SECURE
280*
281* @return   None.
282*
283* @note     This macro is supposed to be used from interrupt handlers. In the
284*                       interrupt handler the interrupts are disabled by default (I bit
285*                       is set as 1). To allow nesting of interrupts, this macro should be
286*                       used. It clears the I bit. Once that bit is cleared and provided the
287*                       preemption of interrupt conditions are met in the GIC, nesting of
288*                       interrupts will start happening.
289*                       Caution: This macro must be used with caution. Before calling this
290*                       macro, the user must ensure that the source of the current IRQ
291*                       is appropriately cleared. Otherwise, as soon as we clear the I
292*                       bit, there can be an infinite loop of interrupts with an
293*                       eventual crash (all the stack space getting consumed).
294******************************************************************************/
295#define Xil_EnableNestedInterrupts() \
296                __asm__ __volatile__ ("mrs    X1, ELR_EL1"); \
297                __asm__ __volatile__ ("mrs    X2, SPSR_EL1");  \
298                __asm__ __volatile__ ("stp    X1,X2, [sp,#-0x10]!"); \
299                __asm__ __volatile__ ("mrs    X1, DAIF");  \
300                __asm__ __volatile__ ("bic    X1,X1,#(0x1<<7)");  \
301                __asm__ __volatile__ ("msr    DAIF, X1");  \
302
303/****************************************************************************/
304/**
305* @brief        Disable the nested interrupts by setting the I bit in DAIF. This
306*                       macro is defined for Cortex-A53 64 bit mode and Cortex-A72 64 bit
307*                       BSP configured to run at EL1 NON SECURE
308*
309* @return   None.
310*
311* @note     This macro is meant to be called in the interrupt service routines.
312*                       This macro cannot be used independently. It can only be used when
313*                       nesting of interrupts have been enabled by using the macro
314*                       Xil_EnableNestedInterrupts(). In a typical flow, the user first
315*                       calls the Xil_EnableNestedInterrupts in the ISR at the appropriate
316*                       point. The user then must call this macro before exiting the interrupt
317*                       service routine. This macro puts the ARM back in IRQ mode and
318*                       hence sets back the I bit.
319******************************************************************************/
320#define Xil_DisableNestedInterrupts() \
321                __asm__ __volatile__ ("ldp    X1,X2, [sp,#0x10]!"); \
322                __asm__ __volatile__ ("msr    ELR_EL1, X1"); \
323                __asm__ __volatile__ ("msr    SPSR_EL1, X2"); \
324                __asm__ __volatile__ ("mrs    X1, DAIF");  \
325                __asm__ __volatile__ ("orr    X1, X1, #(0x1<<7)"); \
326                __asm__ __volatile__ ("msr    DAIF, X1");  \
327
328#elif (!defined (__aarch64__) && !defined (ARMA53_32))
329/****************************************************************************/
330/**
331* @brief        Enable nested interrupts by clearing the I and F bits in CPSR. This
332*                       API is defined for cortex-a9 and cortex-r5.
333*
334* @return   None.
335*
336* @note     This macro is supposed to be used from interrupt handlers. In the
337*                       interrupt handler the interrupts are disabled by default (I and F
338*                       are 1). To allow nesting of interrupts, this macro should be
339*                       used. It clears the I and F bits by changing the ARM mode to
340*                       system mode. Once these bits are cleared and provided the
341*                       preemption of interrupt conditions are met in the GIC, nesting of
342*                       interrupts will start happening.
343*                       Caution: This macro must be used with caution. Before calling this
344*                       macro, the user must ensure that the source of the current IRQ
345*                       is appropriately cleared. Otherwise, as soon as we clear the I and
346*                       F bits, there can be an infinite loop of interrupts with an
347*                       eventual crash (all the stack space getting consumed).
348******************************************************************************/
349#define Xil_EnableNestedInterrupts() \
350                __asm__ __volatile__ ("stmfd   sp!, {lr}"); \
351                __asm__ __volatile__ ("mrs     lr, spsr");  \
352                __asm__ __volatile__ ("stmfd   sp!, {lr}"); \
353                __asm__ __volatile__ ("msr     cpsr_c, #0x1F"); \
354                __asm__ __volatile__ ("stmfd   sp!, {lr}");
355/****************************************************************************/
356/**
357* @brief        Disable the nested interrupts by setting the I and F bits. This API
358*                       is defined for cortex-a9 and cortex-r5.
359*
360* @return   None.
361*
362* @note     This macro is meant to be called in the interrupt service routines.
363*                       This macro cannot be used independently. It can only be used when
364*                       nesting of interrupts have been enabled by using the macro
365*                       Xil_EnableNestedInterrupts(). In a typical flow, the user first
366*                       calls the Xil_EnableNestedInterrupts in the ISR at the appropriate
367*                       point. The user then must call this macro before exiting the interrupt
368*                       service routine. This macro puts the ARM back in IRQ/FIQ mode and
369*                       hence sets back the I and F bits.
370******************************************************************************/
371#define Xil_DisableNestedInterrupts() \
372                __asm__ __volatile__ ("ldmfd   sp!, {lr}");   \
373                __asm__ __volatile__ ("msr     cpsr_c, #0x92"); \
374                __asm__ __volatile__ ("ldmfd   sp!, {lr}"); \
375                __asm__ __volatile__ ("msr     spsr_cxsf, lr"); \
376                __asm__ __volatile__ ("ldmfd   sp!, {lr}"); \
377
378#endif
379/************************** Variable Definitions ****************************/
380
381/************************** Function Prototypes *****************************/
382
383extern void Xil_ExceptionRegisterHandler(u32 Exception_id,
384                                         Xil_ExceptionHandler Handler,
385                                         void *Data);
386
387extern void Xil_ExceptionRemoveHandler(u32 Exception_id);
388extern void Xil_GetExceptionRegisterHandler(u32 Exception_id,
389                                        Xil_ExceptionHandler *Handler, void **Data);
390
391extern void Xil_ExceptionInit(void);
392#if defined (__aarch64__)
393void Xil_SyncAbortHandler(void *CallBackRef);
394void Xil_SErrorAbortHandler(void *CallBackRef);
395#else
396extern void Xil_DataAbortHandler(void *CallBackRef);
397extern void Xil_PrefetchAbortHandler(void *CallBackRef);
398extern void Xil_UndefinedExceptionHandler(void *CallBackRef);
399#endif
400
401#ifdef __cplusplus
402}
403#endif /* __cplusplus */
404
405#endif /* XIL_EXCEPTION_H */
406/**
407* @} End of "addtogroup arm_exception_apis".
408*/
Note: See TracBrowser for help on using the repository browser.