1 /******************************************************************************
3 * Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
31 ******************************************************************************/
32 /*****************************************************************************/
36 * @addtogroup scugic_v3_8
40 * The generic interrupt controller driver component.
42 * The interrupt controller driver uses the idea of priority for the various
43 * handlers. Priority is an integer within the range of 1 and 31 inclusive with
44 * default of 1 being the highest priority interrupt source. The priorities
45 * of the various sources can be dynamically altered as needed through
46 * hardware configuration.
48 * The generic interrupt controller supports the following
51 * - specific individual interrupt enabling/disabling
52 * - specific individual interrupt acknowledging
53 * - attaching specific callback function to handle interrupt source
54 * - assigning desired priority to interrupt source if default is not
57 * Details about connecting the interrupt handler of the driver are contained
58 * in the source file specific to interrupt processing, xscugic_intr.c.
60 * This driver is intended to be RTOS and processor independent. It works with
61 * physical addresses only. Any needs for dynamic memory management, threads
62 * or thread mutual exclusion, virtual memory, or cache control must be
63 * satisfied by the layer above this driver.
65 * <b>Interrupt Vector Tables</b>
67 * The device ID of the interrupt controller device is used by the driver as a
68 * direct index into the configuration data table. The user should populate the
69 * vector table with handlers and callbacks at run-time using the
70 * XScuGic_Connect() and XScuGic_Disconnect() functions.
72 * Each vector table entry corresponds to a device that can generate an
73 * interrupt. Each entry contains an interrupt handler function and an
74 * argument to be passed to the handler when an interrupt occurs. The
75 * user must use XScuGic_Connect() when the interrupt handler takes an
76 * argument other than the base address.
78 * <b>Nested Interrupts Processing</b>
80 * Nested interrupts are not supported by this driver.
83 * The generic interrupt controller is not a part of the snoop control unit
84 * as indicated by the prefix "scu" in the name of the driver.
85 * It is an independent module in APU.
88 * MODIFICATION HISTORY:
90 * Ver Who Date Changes
91 * ----- ---- -------- ---------------------------------------------------------
92 * 1.00a drg 01/19/00 First release
93 * 1.01a sdm 11/09/11 The XScuGic and XScuGic_Config structures have changed.
94 * The HandlerTable (of type XScuGic_VectorTableEntry) is
95 * moved to XScuGic_Config structure from XScuGic structure.
97 * The "Config" entry in XScuGic structure is made as
98 * pointer for better efficiency.
100 * A new file named as xscugic_hw.c is now added. It is
101 * to implement low level driver routines without using
102 * any xscugic instance pointer. They are useful when the
103 * user wants to use xscugic through device id or
104 * base address. The driver routines provided are explained
106 * XScuGic_DeviceInitialize that takes device id as
107 * argument and initializes the device (without calling
108 * XScuGic_CfgInitialize).
109 * XScuGic_DeviceInterruptHandler that takes device id
110 * as argument and calls appropriate handlers from the
112 * XScuGic_RegisterHandler that registers a new handler
113 * by taking xscugic hardware base address as argument.
114 * LookupConfigByBaseAddress is used to return the
115 * corresponding config structure from XScuGic_ConfigTable
116 * based on the scugic base address passed.
117 * 1.02a sdm 12/20/11 Removed AckBeforeService from the XScuGic_Config
119 * 1.03a srt 02/27/13 Moved Offset calculation macros from *.c and *_hw.c to
122 * - XScuGic_SetPriTrigTypeByDistAddr()
123 * - XScuGic_GetPriTrigTypeByDistAddr()
125 * Added support to direct interrupts to the appropriate CPU. Earlier
126 * interrupts were directed to CPU1 (hard coded). Now depending
127 * upon the CPU selected by the user (xparameters.h), interrupts
128 * will be directed to the relevant CPU. This fixes CR 699688.
129 * 1.04a hk 05/04/13 Assigned EffectiveAddr to CpuBaseAddress in
130 * XScuGic_CfgInitialize. Fix for CR#704400 to remove warnings.
131 * Moved functions XScuGic_SetPriTrigTypeByDistAddr and
132 * XScuGic_GetPriTrigTypeByDistAddr to xscugic_hw.c.
133 * This is fix for CR#705621.
134 * 1.05a hk 06/26/13 Modified tcl to export external interrupts correctly to
135 * xparameters.h. Fix for CR's 690505, 708928 & 719359.
136 * 2.0 adk 12/10/13 Updated as per the New Tcl API's
137 * 2.1 adk 25/04/14 Fixed the CR:789373 changes are made in the driver tcl file.
138 * 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
139 * 3.2 asa 02/29/16 Modified DistributorInit function for Zynq AMP case. The
140 * distributor is left uninitialized for Zynq AMP. It is assumed
141 * that the distributor will be initialized by Linux master. However
142 * for CortexR5 case, the earlier code is left unchanged where the
143 * the interrupt processor target registers in the distributor is
144 * initialized with the corresponding CPU ID on which the application
145 * built over the scugic driver runs.
146 * These changes fix CR#937243.
148 * 3.4 asa 04/07/16 Created a new static function DoDistributorInit to simplify
149 * the flow and avoid code duplication. Changes are made for
150 * USE_AMP use case for R5. In a scenario (in R5 split mode) when
151 * one R5 is operating with A53 in open amp config and other
152 * R5 running baremetal app, the existing code
153 * had the potential to stop the whole AMP solution to work (if
154 * for some reason the R5 running the baremetal app tasked to
155 * initialize the Distributor hangs or crashes before initializing).
156 * Changes are made so that the R5 under AMP first checks if
157 * the distributor is enabled or not and if not, it does the
158 * standard Distributor initialization.
159 * This fixes the CR#952962.
160 * 3.6 ms 01/23/17 Modified xil_printf statement in main function for all
161 * examples to ensure that "Successfully ran" and "Failed"
162 * strings are available in all examples. This is a fix
164 * kvn 02/17/17 Add support for changing GIC CPU master at run time.
165 * kvn 02/28/17 Make the CpuId as static variable and Added new
166 * XScugiC_GetCpuId to access CpuId.
167 * ms 03/17/17 Added readme.txt file in examples folder for doxygen
169 * 3.7 ms 04/11/17 Modified tcl file to add suffix U for all macro
170 * definitions of scugic in xparameters.h
171 * 3.8 mus 07/05/17 Updated scugic.tcl to add support for intrrupts connected
172 * through util_reduced_vector IP(OR gate)
173 * mus 07/05/17 Updated xdefine_zynq_canonical_xpars proc to initialize
174 * the HandlerTable in XScuGic_ConfigTable to 0, it removes
175 * the compilation warning in xscugic_g.c. Fix for CR#978736.
176 * mus 07/25/17 Updated xdefine_gic_params proc to export correct canonical
177 * definitions for pl to ps interrupts.Fix for CR#980534
178 * 3.9 mus 02/21/18 Added new API's XScuGic_UnmapAllInterruptsFromCpu and
179 * XScuGic_InterruptUnmapFromCpu, These API's can be used
180 * by applications to unmap specific/all interrupts from
185 ******************************************************************************/
187 #ifndef XSCUGIC_H /* prevent circular inclusions */
188 #define XSCUGIC_H /* by using protection macros */
195 /***************************** Include Files *********************************/
199 #include "xscugic_hw.h"
200 #include "xil_exception.h"
202 /************************** Constant Definitions *****************************/
204 #define EFUSE_STATUS_OFFSET 0x10
205 #define EFUSE_STATUS_CPU_MASK 0x80
207 #if !defined (ARMR5) && !defined (__aarch64__) && !defined (ARMA53_32)
210 /**************************** Type Definitions *******************************/
212 /* The following data type defines each entry in an interrupt vector table.
213 * The callback reference is the base address of the interrupting device
214 * for the low level driver and an instance pointer for the high level driver.
218 Xil_InterruptHandler Handler;
220 } XScuGic_VectorTableEntry;
223 * This typedef contains configuration information for the device.
227 u16 DeviceId; /**< Unique ID of device */
228 u32 CpuBaseAddress; /**< CPU Interface Register base address */
229 u32 DistBaseAddress; /**< Distributor Register base address */
230 XScuGic_VectorTableEntry HandlerTable[XSCUGIC_MAX_NUM_INTR_INPUTS];/**<
231 Vector table of interrupt handlers */
235 * The XScuGic driver instance data. The user is required to allocate a
236 * variable of this type for every intc device in the system. A pointer
237 * to a variable of this type is then passed to the driver API functions.
241 XScuGic_Config *Config; /**< Configuration table entry */
242 u32 IsReady; /**< Device is initialized and ready */
243 u32 UnhandledInterrupts; /**< Intc Statistics */
246 /***************** Macros (Inline Functions) Definitions *********************/
248 /****************************************************************************/
251 * Write the given CPU Interface register
253 * @param InstancePtr is a pointer to the instance to be worked on.
254 * @param RegOffset is the register offset to be written
255 * @param Data is the 32-bit value to write to the register
261 * void XScuGic_CPUWriteReg(XScuGic *InstancePtr, u32 RegOffset, u32 Data)
263 *****************************************************************************/
264 #define XScuGic_CPUWriteReg(InstancePtr, RegOffset, Data) \
265 (XScuGic_WriteReg(((InstancePtr)->Config->CpuBaseAddress), (RegOffset), \
268 /****************************************************************************/
271 * Read the given CPU Interface register
273 * @param InstancePtr is a pointer to the instance to be worked on.
274 * @param RegOffset is the register offset to be read
276 * @return The 32-bit value of the register
280 * u32 XScuGic_CPUReadReg(XScuGic *InstancePtr, u32 RegOffset)
282 *****************************************************************************/
283 #define XScuGic_CPUReadReg(InstancePtr, RegOffset) \
284 (XScuGic_ReadReg(((InstancePtr)->Config->CpuBaseAddress), (RegOffset)))
286 /****************************************************************************/
289 * Write the given Distributor Interface register
291 * @param InstancePtr is a pointer to the instance to be worked on.
292 * @param RegOffset is the register offset to be written
293 * @param Data is the 32-bit value to write to the register
299 * void XScuGic_DistWriteReg(XScuGic *InstancePtr, u32 RegOffset, u32 Data)
301 *****************************************************************************/
302 #define XScuGic_DistWriteReg(InstancePtr, RegOffset, Data) \
303 (XScuGic_WriteReg(((InstancePtr)->Config->DistBaseAddress), (RegOffset), \
306 /****************************************************************************/
309 * Read the given Distributor Interface register
311 * @param InstancePtr is a pointer to the instance to be worked on.
312 * @param RegOffset is the register offset to be read
314 * @return The 32-bit value of the register
318 * u32 XScuGic_DistReadReg(XScuGic *InstancePtr, u32 RegOffset)
320 *****************************************************************************/
321 #define XScuGic_DistReadReg(InstancePtr, RegOffset) \
322 (XScuGic_ReadReg(((InstancePtr)->Config->DistBaseAddress), (RegOffset)))
324 /************************** Function Prototypes ******************************/
327 * Required functions in xscugic.c
330 s32 XScuGic_Connect(XScuGic *InstancePtr, u32 Int_Id,
331 Xil_InterruptHandler Handler, void *CallBackRef);
332 void XScuGic_Disconnect(XScuGic *InstancePtr, u32 Int_Id);
334 void XScuGic_Enable(XScuGic *InstancePtr, u32 Int_Id);
335 void XScuGic_Disable(XScuGic *InstancePtr, u32 Int_Id);
337 s32 XScuGic_CfgInitialize(XScuGic *InstancePtr, XScuGic_Config *ConfigPtr,
340 s32 XScuGic_SoftwareIntr(XScuGic *InstancePtr, u32 Int_Id, u32 Cpu_Id);
342 void XScuGic_GetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id,
343 u8 *Priority, u8 *Trigger);
344 void XScuGic_SetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id,
345 u8 Priority, u8 Trigger);
346 void XScuGic_InterruptMaptoCpu(XScuGic *InstancePtr, u8 Cpu_Id, u32 Int_Id);
347 void XScuGic_InterruptUnmapFromCpu(XScuGic *InstancePtr, u8 Cpu_Id, u32 Int_Id);
348 void XScuGic_UnmapAllInterruptsFromCpu(XScuGic *InstancePtr, u8 Cpu_Id);
349 void XScuGic_Stop(XScuGic *InstancePtr);
350 void XScuGic_SetCpuID(u32 CpuCoreId);
351 u32 XScuGic_GetCpuID(void);
353 * Initialization functions in xscugic_sinit.c
355 XScuGic_Config *XScuGic_LookupConfig(u16 DeviceId);
358 * Interrupt functions in xscugic_intr.c
360 void XScuGic_InterruptHandler(XScuGic *InstancePtr);
363 * Self-test functions in xscugic_selftest.c
365 s32 XScuGic_SelfTest(XScuGic *InstancePtr);
371 #endif /* end of protection macro */