1 /******************************************************************************
3 * Copyright (C) 2010 - 2015 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_1
39 * Contains required functions for the XScuGic driver for the Interrupt
40 * Controller. See xscugic.h for a detailed description of the driver.
43 * MODIFICATION HISTORY:
45 * Ver Who Date Changes
46 * ----- ---- -------- --------------------------------------------------------
47 * 1.00a drg 01/19/10 First release
48 * 1.01a sdm 11/09/11 Changes are made in function XScuGic_CfgInitialize. Since
49 * "Config" entry is now made as pointer in the XScuGic
50 * structure, necessary changes are made.
51 * The HandlerTable can now be populated through the low
52 * level routine XScuGic_RegisterHandler added in this
53 * release. Hence necessary checks are added not to
54 * overwrite the HandlerTable entriesin function
55 * XScuGic_CfgInitialize.
56 * 1.03a srt 02/27/13 Added APIs
57 * - XScuGic_SetPriTrigTypeByDistAddr()
58 * - XScuGic_GetPriTrigTypeByDistAddr()
59 * Removed Offset calculation macros, defined in _hw.h
61 * Added support to direct interrupts to the appropriate CPU. Earlier
62 * interrupts were directed to CPU1 (hard coded). Now depending
63 * upon the CPU selected by the user (xparameters.h), interrupts
64 * will be directed to the relevant CPU. This fixes CR 699688.
66 * 1.04a hk 05/04/13 Assigned EffectiveAddr to CpuBaseAddress in
67 * XScuGic_CfgInitialize. Fix for CR#704400 to remove warnings.
68 * Moved functions XScuGic_SetPriTrigTypeByDistAddr and
69 * XScuGic_GetPriTrigTypeByDistAddr to xscugic_hw.c.
70 * This is fix for CR#705621.
71 * 1.06a asa 16/11/13 Fix for CR#749178. Assignment for EffectiveAddr
72 * in function XScuGic_CfgInitialize is removed as it was
74 * 3.00 kvn 02/13/14 Modified code for MISRA-C:2012 compliance.
75 * 3.01 pkp 06/19/15 Added XScuGic_InterruptMaptoCpu API for an interrupt
77 * 3.02 pkp 11/09/15 Modified DistributorInit function for AMP case to add
78 * the current cpu to interrupt processor targets registers
79 * 3.2 asa 02/29/16 Modified DistributorInit function for Zynq AMP case. The
80 * distributor is left uninitialized for Zynq AMP. It is assumed
81 * that the distributor will be initialized by Linux master. However
82 * for CortexR5 case, the earlier code is left unchanged where the
83 * the interrupt processor target registers in the distributor is
84 * initialized with the corresponding CPU ID on which the application
85 * built over the scugic driver runs.
86 * These changes fix CR#937243.
91 ******************************************************************************/
93 /***************************** Include Files *********************************/
94 #include "xil_types.h"
95 #include "xil_assert.h"
97 #include "xparameters.h"
99 /************************** Constant Definitions *****************************/
102 /**************************** Type Definitions *******************************/
105 /***************** Macros (Inline Functions) Definitions *********************/
107 /************************** Variable Definitions *****************************/
109 /************************** Function Prototypes ******************************/
111 static void StubHandler(void *CallBackRef);
113 /*****************************************************************************/
116 * DistributorInit initializes the distributor of the GIC. The
117 * initialization entails:
119 * - Write the trigger mode, priority and target CPU
120 * - All interrupt sources are disabled
121 * - Enable the distributor
123 * @param InstancePtr is a pointer to the XScuGic instance.
124 * @param CpuID is the Cpu ID to be initialized.
130 ******************************************************************************/
131 static void DistributorInit(XScuGic *InstancePtr, u32 CpuID)
134 u32 LocalCpuID = CpuID;
137 #warning "Building GIC for AMP"
142 * The overall distributor should not be initialized in AMP case where
143 * another CPU is taking care of it.
145 LocalCpuID |= LocalCpuID << 8U;
146 LocalCpuID |= LocalCpuID << 16U;
147 for (Int_Id = 32U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id=Int_Id+4U) {
148 RegValue = XScuGic_DistReadReg(InstancePtr,
149 XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id));
150 RegValue |= LocalCpuID;
151 XScuGic_DistWriteReg(InstancePtr,
152 XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id),
159 Xil_AssertVoid(InstancePtr != NULL);
160 XScuGic_DistWriteReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET, 0U);
163 * Set the security domains in the int_security registers for
164 * non-secure interrupts
165 * All are secure, so leave at the default. Set to 1 for non-secure
170 * For the Shared Peripheral Interrupts INT_ID[MAX..32], set:
174 * 1. The trigger mode in the int_config register
175 * Only write to the SPI interrupts, so start at 32
177 for (Int_Id = 32U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id=Int_Id+16U) {
179 * Each INT_ID uses two bits, or 16 INT_ID per register
180 * Set them all to be level sensitive, active HIGH.
182 XScuGic_DistWriteReg(InstancePtr,
183 XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id),
188 #define DEFAULT_PRIORITY 0xa0a0a0a0U
189 for (Int_Id = 0U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id=Int_Id+4U) {
191 * 2. The priority using int the priority_level register
192 * The priority_level and spi_target registers use one byte per
194 * Write a default value that can be changed elsewhere.
196 XScuGic_DistWriteReg(InstancePtr,
197 XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id),
201 for (Int_Id = 32U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id=Int_Id+4U) {
203 * 3. The CPU interface in the spi_target register
204 * Only write to the SPI interrupts, so start at 32
206 LocalCpuID |= LocalCpuID << 8U;
207 LocalCpuID |= LocalCpuID << 16U;
209 XScuGic_DistWriteReg(InstancePtr,
210 XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id),
214 for (Int_Id = 0U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id=Int_Id+32U) {
216 * 4. Enable the SPI using the enable_set register. Leave all
219 XScuGic_DistWriteReg(InstancePtr,
220 XSCUGIC_EN_DIS_OFFSET_CALC(XSCUGIC_DISABLE_OFFSET, Int_Id),
225 XScuGic_DistWriteReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET,
226 XSCUGIC_EN_INT_MASK);
230 /*****************************************************************************/
233 * CPUInitialize initializes the CPU Interface of the GIC. The initialization entails:
235 * - Set the priority of the CPU
236 * - Enable the CPU interface
238 * @param InstancePtr is a pointer to the XScuGic instance.
244 ******************************************************************************/
245 static void CPUInitialize(XScuGic *InstancePtr)
248 * Program the priority mask of the CPU using the Priority mask register
250 XScuGic_CPUWriteReg(InstancePtr, XSCUGIC_CPU_PRIOR_OFFSET, 0xF0U);
254 * If the CPU operates in both security domains, set parameters in the
255 * control_s register.
256 * 1. Set FIQen=1 to use FIQ for secure interrupts,
257 * 2. Program the AckCtl bit
258 * 3. Program the SBPR bit to select the binary pointer behavior
259 * 4. Set EnableS = 1 to enable secure interrupts
260 * 5. Set EnbleNS = 1 to enable non secure interrupts
264 * If the CPU operates only in the secure domain, setup the
265 * control_s register.
267 * 2. Set EnableS=1, to enable the CPU interface to signal secure interrupts.
268 * Only enable the IRQ output unless secure interrupts are needed.
270 XScuGic_CPUWriteReg(InstancePtr, XSCUGIC_CONTROL_OFFSET, 0x07U);
274 /*****************************************************************************/
277 * CfgInitialize a specific interrupt controller instance/driver. The
278 * initialization entails:
280 * - Initialize fields of the XScuGic structure
281 * - Initial vector table with stub function calls
282 * - All interrupt sources are disabled
284 * @param InstancePtr is a pointer to the XScuGic instance.
285 * @param ConfigPtr is a pointer to a config table for the particular
286 * device this driver is associated with.
287 * @param EffectiveAddr is the device base address in the virtual memory
288 * address space. The caller is responsible for keeping the address
289 * mapping from EffectiveAddr to the device physical base address
290 * unchanged once this function is invoked. Unexpected errors may
291 * occur if the address mapping changes after this function is
292 * called. If address translation is not used, use
293 * Config->BaseAddress for this parameters, passing the physical
297 * - XST_SUCCESS if initialization was successful
301 ******************************************************************************/
302 s32 XScuGic_CfgInitialize(XScuGic *InstancePtr,
303 XScuGic_Config *ConfigPtr,
307 u32 Cpu_Id = (u32)XPAR_CPU_ID + (u32)1;
308 (void) EffectiveAddr;
310 Xil_AssertNonvoid(InstancePtr != NULL);
311 Xil_AssertNonvoid(ConfigPtr != NULL);
313 if(InstancePtr->IsReady != XIL_COMPONENT_IS_READY) {
315 InstancePtr->IsReady = 0;
316 InstancePtr->Config = ConfigPtr;
319 for (Int_Id = 0U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id++) {
321 * Initalize the handler to point to a stub to handle an
322 * interrupt which has not been connected to a handler. Only
323 * initialize it if the handler is 0 which means it was not
324 * initialized statically by the tools/user. Set the callback
325 * reference to this instance so that unhandled interrupts
328 if ((InstancePtr->Config->HandlerTable[Int_Id].Handler == NULL)) {
329 InstancePtr->Config->HandlerTable[Int_Id].Handler =
332 InstancePtr->Config->HandlerTable[Int_Id].CallBackRef =
336 DistributorInit(InstancePtr, Cpu_Id);
337 CPUInitialize(InstancePtr);
339 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
345 /*****************************************************************************/
348 * Makes the connection between the Int_Id of the interrupt source and the
349 * associated handler that is to run when the interrupt is recognized. The
350 * argument provided in this call as the Callbackref is used as the argument
351 * for the handler when it is called.
353 * @param InstancePtr is a pointer to the XScuGic instance.
354 * @param Int_Id contains the ID of the interrupt source and should be
355 * in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
356 * @param Handler to the handler for that interrupt.
357 * @param CallBackRef is the callback reference, usually the instance
358 * pointer of the connecting driver.
362 * - XST_SUCCESS if the handler was connected correctly.
366 * WARNING: The handler provided as an argument will overwrite any handler
367 * that was previously connected.
369 ****************************************************************************/
370 s32 XScuGic_Connect(XScuGic *InstancePtr, u32 Int_Id,
371 Xil_InterruptHandler Handler, void *CallBackRef)
374 * Assert the arguments
376 Xil_AssertNonvoid(InstancePtr != NULL);
377 Xil_AssertNonvoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
378 Xil_AssertNonvoid(Handler != NULL);
379 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
382 * The Int_Id is used as an index into the table to select the proper
385 InstancePtr->Config->HandlerTable[Int_Id].Handler = Handler;
386 InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = CallBackRef;
391 /*****************************************************************************/
394 * Updates the interrupt table with the Null Handler and NULL arguments at the
395 * location pointed at by the Int_Id. This effectively disconnects that interrupt
396 * source from any handler. The interrupt is disabled also.
398 * @param InstancePtr is a pointer to the XScuGic instance to be worked on.
399 * @param Int_Id contains the ID of the interrupt source and should
400 * be in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
406 ****************************************************************************/
407 void XScuGic_Disconnect(XScuGic *InstancePtr, u32 Int_Id)
412 * Assert the arguments
414 Xil_AssertVoid(InstancePtr != NULL);
415 Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
416 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
419 * The Int_Id is used to create the appropriate mask for the
420 * desired bit position. Int_Id currently limited to 0 - 31
422 Mask = 0x00000001U << (Int_Id % 32U);
425 * Disable the interrupt such that it won't occur while disconnecting
426 * the handler, only disable the specified interrupt id without modifying
427 * the other interrupt ids
429 XScuGic_DistWriteReg(InstancePtr, (u32)XSCUGIC_DISABLE_OFFSET +
430 ((Int_Id / 32U) * 4U), Mask);
433 * Disconnect the handler and connect a stub, the callback reference
434 * must be set to this instance to allow unhandled interrupts to be
437 InstancePtr->Config->HandlerTable[Int_Id].Handler = StubHandler;
438 InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = InstancePtr;
441 /*****************************************************************************/
444 * Enables the interrupt source provided as the argument Int_Id. Any pending
445 * interrupt condition for the specified Int_Id will occur after this function is
448 * @param InstancePtr is a pointer to the XScuGic instance.
449 * @param Int_Id contains the ID of the interrupt source and should be
450 * in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
456 ****************************************************************************/
457 void XScuGic_Enable(XScuGic *InstancePtr, u32 Int_Id)
462 * Assert the arguments
464 Xil_AssertVoid(InstancePtr != NULL);
465 Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
466 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
469 * The Int_Id is used to create the appropriate mask for the
470 * desired bit position. Int_Id currently limited to 0 - 31
472 Mask = 0x00000001U << (Int_Id % 32U);
475 * Enable the selected interrupt source by setting the
476 * corresponding bit in the Enable Set register.
478 XScuGic_DistWriteReg(InstancePtr, (u32)XSCUGIC_ENABLE_SET_OFFSET +
479 ((Int_Id / 32U) * 4U), Mask);
482 /*****************************************************************************/
485 * Disables the interrupt source provided as the argument Int_Id such that the
486 * interrupt controller will not cause interrupts for the specified Int_Id. The
487 * interrupt controller will continue to hold an interrupt condition for the
488 * Int_Id, but will not cause an interrupt.
490 * @param InstancePtr is a pointer to the XScuGic instance.
491 * @param Int_Id contains the ID of the interrupt source and should be
492 * in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
498 ****************************************************************************/
499 void XScuGic_Disable(XScuGic *InstancePtr, u32 Int_Id)
504 * Assert the arguments
506 Xil_AssertVoid(InstancePtr != NULL);
507 Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
508 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
511 * The Int_Id is used to create the appropriate mask for the
512 * desired bit position. Int_Id currently limited to 0 - 31
514 Mask = 0x00000001U << (Int_Id % 32U);
517 * Disable the selected interrupt source by setting the
518 * corresponding bit in the IDR.
520 XScuGic_DistWriteReg(InstancePtr, (u32)XSCUGIC_DISABLE_OFFSET +
521 ((Int_Id / 32U) * 4U), Mask);
524 /*****************************************************************************/
527 * Allows software to simulate an interrupt in the interrupt controller. This
528 * function will only be successful when the interrupt controller has been
529 * started in simulation mode. A simulated interrupt allows the interrupt
530 * controller to be tested without any device to drive an interrupt input
533 * @param InstancePtr is a pointer to the XScuGic instance.
534 * @param Int_Id is the software interrupt ID to simulate an interrupt.
535 * @param Cpu_Id is the list of CPUs to send the interrupt.
539 * XST_SUCCESS if successful, or XST_FAILURE if the interrupt could not be
544 ******************************************************************************/
545 s32 XScuGic_SoftwareIntr(XScuGic *InstancePtr, u32 Int_Id, u32 Cpu_Id)
550 * Assert the arguments
552 Xil_AssertNonvoid(InstancePtr != NULL);
553 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
554 Xil_AssertNonvoid(Int_Id <= 15U) ;
555 Xil_AssertNonvoid(Cpu_Id <= 255U) ;
559 * The Int_Id is used to create the appropriate mask for the
560 * desired interrupt. Int_Id currently limited to 0 - 15
561 * Use the target list for the Cpu ID.
563 Mask = ((Cpu_Id << 16U) | Int_Id) &
564 (XSCUGIC_SFI_TRIG_CPU_MASK | XSCUGIC_SFI_TRIG_INTID_MASK);
567 * Write to the Software interrupt trigger register. Use the appropriate
570 XScuGic_DistWriteReg(InstancePtr, XSCUGIC_SFI_TRIG_OFFSET, Mask);
572 /* Indicate the interrupt was successfully simulated */
577 /*****************************************************************************/
580 * A stub for the asynchronous callback. The stub is here in case the upper
581 * layers forget to set the handler.
583 * @param CallBackRef is a pointer to the upper layer callback reference
589 ******************************************************************************/
590 static void StubHandler(void *CallBackRef) {
592 * verify that the inputs are valid
594 Xil_AssertVoid(CallBackRef != NULL);
597 * Indicate another unhandled interrupt for stats
599 ((XScuGic *)((void *)CallBackRef))->UnhandledInterrupts++;
602 /****************************************************************************/
604 * Sets the interrupt priority and trigger type for the specificd IRQ source.
606 * @param InstancePtr is a pointer to the instance to be worked on.
607 * @param Int_Id is the IRQ source number to modify
608 * @param Priority is the new priority for the IRQ source. 0 is highest
609 * priority, 0xF8 (248) is lowest. There are 32 priority levels
610 * supported with a step of 8. Hence the supported priorities are
611 * 0, 8, 16, 32, 40 ..., 248.
612 * @param Trigger is the new trigger type for the IRQ source.
613 * Each bit pair describes the configuration for an INT_ID.
614 * SFI Read Only b10 always
615 * PPI Read Only depending on how the PPIs are configured.
616 * b01 Active HIGH level sensitive
617 * b11 Rising edge sensitive
618 * SPI LSB is read only.
619 * b01 Active HIGH level sensitive
620 * b11 Rising edge sensitive/
626 *****************************************************************************/
627 void XScuGic_SetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id,
628 u8 Priority, u8 Trigger)
632 LocalPriority = Priority;
634 Xil_AssertVoid(InstancePtr != NULL);
635 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
636 Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
637 Xil_AssertVoid(Trigger <= (u8)XSCUGIC_INT_CFG_MASK);
638 Xil_AssertVoid(LocalPriority <= (u8)XSCUGIC_MAX_INTR_PRIO_VAL);
641 * Determine the register to write to using the Int_Id.
643 RegValue = XScuGic_DistReadReg(InstancePtr,
644 XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id));
647 * The priority bits are Bits 7 to 3 in GIC Priority Register. This
648 * means the number of priority levels supported are 32 and they are
649 * in steps of 8. The priorities can be 0, 8, 16, 32, 48, ... etc.
650 * The lower order 3 bits are masked before putting it in the register.
652 LocalPriority = LocalPriority & (u8)XSCUGIC_INTR_PRIO_MASK;
654 * Shift and Mask the correct bits for the priority and trigger in the
657 RegValue &= ~(XSCUGIC_PRIORITY_MASK << ((Int_Id%4U)*8U));
658 RegValue |= (u32)LocalPriority << ((Int_Id%4U)*8U);
661 * Write the value back to the register.
663 XScuGic_DistWriteReg(InstancePtr, XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id),
667 * Determine the register to write to using the Int_Id.
669 RegValue = XScuGic_DistReadReg(InstancePtr,
670 XSCUGIC_INT_CFG_OFFSET_CALC (Int_Id));
673 * Shift and Mask the correct bits for the priority and trigger in the
676 RegValue &= ~(XSCUGIC_INT_CFG_MASK << ((Int_Id%16U)*2U));
677 RegValue |= (u32)Trigger << ((Int_Id%16U)*2U);
680 * Write the value back to the register.
682 XScuGic_DistWriteReg(InstancePtr, XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id),
687 /****************************************************************************/
689 * Gets the interrupt priority and trigger type for the specificd IRQ source.
691 * @param InstancePtr is a pointer to the instance to be worked on.
692 * @param Int_Id is the IRQ source number to modify
693 * @param Priority is a pointer to the value of the priority of the IRQ
694 * source. This is a return value.
695 * @param Trigger is pointer to the value of the trigger of the IRQ
696 * source. This is a return value.
702 *****************************************************************************/
703 void XScuGic_GetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id,
704 u8 *Priority, u8 *Trigger)
708 Xil_AssertVoid(InstancePtr != NULL);
709 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
710 Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
711 Xil_AssertVoid(Priority != NULL);
712 Xil_AssertVoid(Trigger != NULL);
715 * Determine the register to read to using the Int_Id.
717 RegValue = XScuGic_DistReadReg(InstancePtr,
718 XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id));
721 * Shift and Mask the correct bits for the priority and trigger in the
724 RegValue = RegValue >> ((Int_Id%4U)*8U);
725 *Priority = (u8)(RegValue & XSCUGIC_PRIORITY_MASK);
728 * Determine the register to read to using the Int_Id.
730 RegValue = XScuGic_DistReadReg(InstancePtr,
731 XSCUGIC_INT_CFG_OFFSET_CALC (Int_Id));
734 * Shift and Mask the correct bits for the priority and trigger in the
737 RegValue = RegValue >> ((Int_Id%16U)*2U);
739 *Trigger = (u8)(RegValue & XSCUGIC_INT_CFG_MASK);
741 /****************************************************************************/
743 * Sets the target CPU for the interrupt of a peripheral
745 * @param InstancePtr is a pointer to the instance to be worked on.
746 * @param Cpu_Id is a CPU number for which the interrupt has to be targeted
747 * @param Int_Id is the IRQ source number to modify
753 *****************************************************************************/
754 void XScuGic_InterruptMaptoCpu(XScuGic *InstancePtr, u8 Cpu_Id, u32 Int_Id)
756 u32 RegValue, Offset;
757 RegValue = XScuGic_DistReadReg(InstancePtr,
758 XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id));
760 Offset = (Int_Id & 0x3);
762 RegValue = (RegValue | (~(0xFF << (Offset*8))) );
763 RegValue |= ((Cpu_Id) << (Offset*8));
765 XScuGic_DistWriteReg(InstancePtr,
766 XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id),