]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A53_64-bit_UltraScale_MPSoC/RTOSDemo_A53_bsp/psu_cortexa53_0/libsrc/scugic_v3_0/src/xscugic.c
Completely re-generate the Zynq 7000 demo using the 2016.1 SDK tools.
[freertos] / FreeRTOS / Demo / CORTEX_A53_64-bit_UltraScale_MPSoC / RTOSDemo_A53_bsp / psu_cortexa53_0 / libsrc / scugic_v3_0 / src / xscugic.c
1 /******************************************************************************
2 *
3 * Copyright (C) 2010 - 2015 Xilinx, Inc.  All rights reserved.
4 *
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:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
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.
18 *
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
25 * SOFTWARE.
26 *
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.
30 *
31 ******************************************************************************/
32 /*****************************************************************************/
33 /**
34 *
35 * @file xscugic.c
36 *
37 * Contains required functions for the XScuGic driver for the Interrupt
38 * Controller. See xscugic.h for a detailed description of the driver.
39 *
40 * <pre>
41 * MODIFICATION HISTORY:
42 *
43 * Ver   Who  Date     Changes
44 * ----- ---- -------- --------------------------------------------------------
45 * 1.00a drg  01/19/10 First release
46 * 1.01a sdm  11/09/11 Changes are made in function XScuGic_CfgInitialize. Since
47 *                     "Config" entry is now made as pointer in the XScuGic
48 *                     structure, necessary changes are made.
49 *                     The HandlerTable can now be populated through the low
50 *                     level routine XScuGic_RegisterHandler added in this
51 *                     release. Hence necessary checks are added not to
52 *                     overwrite the HandlerTable entriesin function
53 *                     XScuGic_CfgInitialize.
54 * 1.03a srt  02/27/13 Added APIs
55 *                       - XScuGic_SetPriTrigTypeByDistAddr()
56 *                       - XScuGic_GetPriTrigTypeByDistAddr()
57 *                     Removed Offset calculation macros, defined in _hw.h
58 *                     (CR 702687)
59 *                         Added support to direct interrupts to the appropriate CPU. Earlier
60 *                         interrupts were directed to CPU1 (hard coded). Now depending
61 *                         upon the CPU selected by the user (xparameters.h), interrupts
62 *                         will be directed to the relevant CPU. This fixes CR 699688.
63 *
64 * 1.04a hk   05/04/13 Assigned EffectiveAddr to CpuBaseAddress in
65 *                         XScuGic_CfgInitialize. Fix for CR#704400 to remove warnings.
66 *                         Moved functions XScuGic_SetPriTrigTypeByDistAddr and
67 *             XScuGic_GetPriTrigTypeByDistAddr to xscugic_hw.c.
68 *                         This is fix for CR#705621.
69 * 1.06a asa  16/11/13 Fix for CR#749178. Assignment for EffectiveAddr
70 *                         in function XScuGic_CfgInitialize is removed as it was
71 *                     a bug.
72 * 3.00  kvn  02/13/14 Modified code for MISRA-C:2012 compliance.
73 *
74 * </pre>
75 *
76 ******************************************************************************/
77
78 /***************************** Include Files *********************************/
79 #include "xil_types.h"
80 #include "xil_assert.h"
81 #include "xscugic.h"
82 #include "xparameters.h"
83
84 /************************** Constant Definitions *****************************/
85
86
87 /**************************** Type Definitions *******************************/
88
89
90 /***************** Macros (Inline Functions) Definitions *********************/
91
92 /************************** Variable Definitions *****************************/
93
94 /************************** Function Prototypes ******************************/
95
96 static void StubHandler(void *CallBackRef);
97
98 /*****************************************************************************/
99 /**
100 *
101 * DistributorInit initializes the distributor of the GIC. The
102 * initialization entails:
103 *
104 * - Write the trigger mode, priority and target CPU
105 * - All interrupt sources are disabled
106 * - Enable the distributor
107 *
108 * @param        InstancePtr is a pointer to the XScuGic instance.
109 * @param        CpuID is the Cpu ID to be initialized.
110 *
111 * @return       None
112 *
113 * @note         None.
114 *
115 ******************************************************************************/
116 static void DistributorInit(XScuGic *InstancePtr, u32 CpuID)
117 {
118         u32 Int_Id;
119         u32 LocalCpuID = CpuID;
120
121 #if USE_AMP==1
122         #warning "Building GIC for AMP"
123
124         /*
125          * The distrubutor should not be initialized by FreeRTOS in the case of
126          * AMP -- it is assumed that Linux is the master of this device in that
127          * case.
128          */
129         return;
130 #endif
131         Xil_AssertVoid(InstancePtr != NULL);
132         XScuGic_DistWriteReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET, 0U);
133
134         /*
135          * Set the security domains in the int_security registers for
136          * non-secure interrupts
137          * All are secure, so leave at the default. Set to 1 for non-secure
138          * interrupts.
139          */
140
141         /*
142          * For the Shared Peripheral Interrupts INT_ID[MAX..32], set:
143          */
144
145         /*
146          * 1. The trigger mode in the int_config register
147          * Only write to the SPI interrupts, so start at 32
148          */
149         for (Int_Id = 32U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id=Int_Id+16U) {
150                 /*
151                  * Each INT_ID uses two bits, or 16 INT_ID per register
152                  * Set them all to be level sensitive, active HIGH.
153                  */
154                 XScuGic_DistWriteReg(InstancePtr,
155                                         XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id),
156                                         0U);
157         }
158
159
160 #define DEFAULT_PRIORITY    0xa0a0a0a0U
161         for (Int_Id = 0U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id=Int_Id+4U) {
162                 /*
163                  * 2. The priority using int the priority_level register
164                  * The priority_level and spi_target registers use one byte per
165                  * INT_ID.
166                  * Write a default value that can be changed elsewhere.
167                  */
168                 XScuGic_DistWriteReg(InstancePtr,
169                                         XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id),
170                                         DEFAULT_PRIORITY);
171         }
172
173         for (Int_Id = 32U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id=Int_Id+4U) {
174                 /*
175                  * 3. The CPU interface in the spi_target register
176                  * Only write to the SPI interrupts, so start at 32
177                  */
178                 LocalCpuID |= LocalCpuID << 8U;
179                 LocalCpuID |= LocalCpuID << 16U;
180
181                 XScuGic_DistWriteReg(InstancePtr,
182                                      XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id),
183                                      LocalCpuID);
184         }
185
186         for (Int_Id = 0U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id=Int_Id+32U) {
187                 /*
188                  * 4. Enable the SPI using the enable_set register. Leave all
189                  * disabled for now.
190                  */
191                 XScuGic_DistWriteReg(InstancePtr,
192                 XSCUGIC_EN_DIS_OFFSET_CALC(XSCUGIC_DISABLE_OFFSET, Int_Id),
193                         0xFFFFFFFFU);
194
195         }
196
197         XScuGic_DistWriteReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET,
198                                                 XSCUGIC_EN_INT_MASK);
199
200 }
201
202 /*****************************************************************************/
203 /**
204 *
205 * CPUInitialize initializes the CPU Interface of the GIC. The initialization entails:
206 *
207 *       - Set the priority of the CPU
208 *       - Enable the CPU interface
209 *
210 * @param        InstancePtr is a pointer to the XScuGic instance.
211 *
212 * @return       None
213 *
214 * @note         None.
215 *
216 ******************************************************************************/
217 static void CPUInitialize(XScuGic *InstancePtr)
218 {
219         /*
220          * Program the priority mask of the CPU using the Priority mask register
221          */
222         XScuGic_CPUWriteReg(InstancePtr, XSCUGIC_CPU_PRIOR_OFFSET, 0xF0U);
223
224
225         /*
226          * If the CPU operates in both security domains, set parameters in the
227          * control_s register.
228          * 1. Set FIQen=1 to use FIQ for secure interrupts,
229          * 2. Program the AckCtl bit
230          * 3. Program the SBPR bit to select the binary pointer behavior
231          * 4. Set EnableS = 1 to enable secure interrupts
232          * 5. Set EnbleNS = 1 to enable non secure interrupts
233          */
234
235         /*
236          * If the CPU operates only in the secure domain, setup the
237          * control_s register.
238          * 1. Set FIQen=1,
239          * 2. Set EnableS=1, to enable the CPU interface to signal secure interrupts.
240          * Only enable the IRQ output unless secure interrupts are needed.
241          */
242         XScuGic_CPUWriteReg(InstancePtr, XSCUGIC_CONTROL_OFFSET, 0x07U);
243
244 }
245
246 /*****************************************************************************/
247 /**
248 *
249 * CfgInitialize a specific interrupt controller instance/driver. The
250 * initialization entails:
251 *
252 * - Initialize fields of the XScuGic structure
253 * - Initial vector table with stub function calls
254 * - All interrupt sources are disabled
255 *
256 * @param        InstancePtr is a pointer to the XScuGic instance.
257 * @param        ConfigPtr is a pointer to a config table for the particular
258 *               device this driver is associated with.
259 * @param        EffectiveAddr is the device base address in the virtual memory
260 *               address space. The caller is responsible for keeping the address
261 *               mapping from EffectiveAddr to the device physical base address
262 *               unchanged once this function is invoked. Unexpected errors may
263 *               occur if the address mapping changes after this function is
264 *               called. If address translation is not used, use
265 *               Config->BaseAddress for this parameters, passing the physical
266 *               address instead.
267 *
268 * @return
269 *               - XST_SUCCESS if initialization was successful
270 *
271 * @note         None.
272 *
273 ******************************************************************************/
274 s32  XScuGic_CfgInitialize(XScuGic *InstancePtr,
275                                 XScuGic_Config *ConfigPtr,
276                                 u32 EffectiveAddr)
277 {
278         u32 Int_Id;
279         u32 Cpu_Id = (u32)XPAR_CPU_ID + (u32)1;
280         (void) EffectiveAddr;
281
282         Xil_AssertNonvoid(InstancePtr != NULL);
283         Xil_AssertNonvoid(ConfigPtr != NULL);
284
285         if(InstancePtr->IsReady != XIL_COMPONENT_IS_READY) {
286
287                 InstancePtr->IsReady = 0;
288                 InstancePtr->Config = ConfigPtr;
289
290
291                 for (Int_Id = 0U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id++) {
292                         /*
293                         * Initalize the handler to point to a stub to handle an
294                         * interrupt which has not been connected to a handler. Only
295                         * initialize it if the handler is 0 which means it was not
296                         * initialized statically by the tools/user. Set the callback
297                         * reference to this instance so that unhandled interrupts
298                         * can be tracked.
299                         */
300                         if      ((InstancePtr->Config->HandlerTable[Int_Id].Handler == NULL)) {
301                                 InstancePtr->Config->HandlerTable[Int_Id].Handler =
302                                                                         StubHandler;
303                         }
304                         InstancePtr->Config->HandlerTable[Int_Id].CallBackRef =
305                                                                 InstancePtr;
306                 }
307
308                 DistributorInit(InstancePtr, Cpu_Id);
309                 CPUInitialize(InstancePtr);
310
311                 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
312         }
313
314         return XST_SUCCESS;
315 }
316
317 /*****************************************************************************/
318 /**
319 *
320 * Makes the connection between the Int_Id of the interrupt source and the
321 * associated handler that is to run when the interrupt is recognized. The
322 * argument provided in this call as the Callbackref is used as the argument
323 * for the handler when it is called.
324 *
325 * @param        InstancePtr is a pointer to the XScuGic instance.
326 * @param        Int_Id contains the ID of the interrupt source and should be
327 *               in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
328 * @param        Handler to the handler for that interrupt.
329 * @param        CallBackRef is the callback reference, usually the instance
330 *               pointer of the connecting driver.
331 *
332 * @return
333 *
334 *               - XST_SUCCESS if the handler was connected correctly.
335 *
336 * @note
337 *
338 * WARNING: The handler provided as an argument will overwrite any handler
339 * that was previously connected.
340 *
341 ****************************************************************************/
342 s32  XScuGic_Connect(XScuGic *InstancePtr, u32 Int_Id,
343                       Xil_InterruptHandler Handler, void *CallBackRef)
344 {
345         /*
346          * Assert the arguments
347          */
348         Xil_AssertNonvoid(InstancePtr != NULL);
349         Xil_AssertNonvoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
350         Xil_AssertNonvoid(Handler != NULL);
351         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
352
353         /*
354          * The Int_Id is used as an index into the table to select the proper
355          * handler
356          */
357         InstancePtr->Config->HandlerTable[Int_Id].Handler = Handler;
358         InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = CallBackRef;
359
360         return XST_SUCCESS;
361 }
362
363 /*****************************************************************************/
364 /**
365 *
366 * Updates the interrupt table with the Null Handler and NULL arguments at the
367 * location pointed at by the Int_Id. This effectively disconnects that interrupt
368 * source from any handler. The interrupt is disabled also.
369 *
370 * @param        InstancePtr is a pointer to the XScuGic instance to be worked on.
371 * @param        Int_Id contains the ID of the interrupt source and should
372 *               be in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
373 *
374 * @return       None.
375 *
376 * @note         None.
377 *
378 ****************************************************************************/
379 void XScuGic_Disconnect(XScuGic *InstancePtr, u32 Int_Id)
380 {
381         u32 Mask;
382
383         /*
384          * Assert the arguments
385          */
386         Xil_AssertVoid(InstancePtr != NULL);
387         Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
388         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
389
390         /*
391          * The Int_Id is used to create the appropriate mask for the
392          * desired bit position. Int_Id currently limited to 0 - 31
393          */
394         Mask = 0x00000001U << (Int_Id % 32U);
395
396         /*
397          * Disable the interrupt such that it won't occur while disconnecting
398          * the handler, only disable the specified interrupt id without modifying
399          * the other interrupt ids
400          */
401         XScuGic_DistWriteReg(InstancePtr, (u32)XSCUGIC_DISABLE_OFFSET +
402                                                 ((Int_Id / 32U) * 4U), Mask);
403
404         /*
405          * Disconnect the handler and connect a stub, the callback reference
406          * must be set to this instance to allow unhandled interrupts to be
407          * tracked
408          */
409         InstancePtr->Config->HandlerTable[Int_Id].Handler = StubHandler;
410         InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = InstancePtr;
411 }
412
413 /*****************************************************************************/
414 /**
415 *
416 * Enables the interrupt source provided as the argument Int_Id. Any pending
417 * interrupt condition for the specified Int_Id will occur after this function is
418 * called.
419 *
420 * @param        InstancePtr is a pointer to the XScuGic instance.
421 * @param        Int_Id contains the ID of the interrupt source and should be
422 *               in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
423 *
424 * @return       None.
425 *
426 * @note         None.
427 *
428 ****************************************************************************/
429 void XScuGic_Enable(XScuGic *InstancePtr, u32 Int_Id)
430 {
431         u32 Mask;
432
433         /*
434          * Assert the arguments
435          */
436         Xil_AssertVoid(InstancePtr != NULL);
437         Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
438         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
439
440         /*
441          * The Int_Id is used to create the appropriate mask for the
442          * desired bit position. Int_Id currently limited to 0 - 31
443          */
444         Mask = 0x00000001U << (Int_Id % 32U);
445
446         /*
447          * Enable the selected interrupt source by setting the
448          * corresponding bit in the Enable Set register.
449          */
450         XScuGic_DistWriteReg(InstancePtr, (u32)XSCUGIC_ENABLE_SET_OFFSET +
451                                                 ((Int_Id / 32U) * 4U), Mask);
452 }
453
454 /*****************************************************************************/
455 /**
456 *
457 * Disables the interrupt source provided as the argument Int_Id such that the
458 * interrupt controller will not cause interrupts for the specified Int_Id. The
459 * interrupt controller will continue to hold an interrupt condition for the
460 * Int_Id, but will not cause an interrupt.
461 *
462 * @param        InstancePtr is a pointer to the XScuGic instance.
463 * @param        Int_Id contains the ID of the interrupt source and should be
464 *               in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
465 *
466 * @return       None.
467 *
468 * @note         None.
469 *
470 ****************************************************************************/
471 void XScuGic_Disable(XScuGic *InstancePtr, u32 Int_Id)
472 {
473         u32 Mask;
474
475         /*
476          * Assert the arguments
477          */
478         Xil_AssertVoid(InstancePtr != NULL);
479         Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
480         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
481
482         /*
483          * The Int_Id is used to create the appropriate mask for the
484          * desired bit position. Int_Id currently limited to 0 - 31
485          */
486         Mask = 0x00000001U << (Int_Id % 32U);
487
488         /*
489          * Disable the selected interrupt source by setting the
490          * corresponding bit in the IDR.
491          */
492         XScuGic_DistWriteReg(InstancePtr, (u32)XSCUGIC_DISABLE_OFFSET +
493                                                 ((Int_Id / 32U) * 4U), Mask);
494 }
495
496 /*****************************************************************************/
497 /**
498 *
499 * Allows software to simulate an interrupt in the interrupt controller.  This
500 * function will only be successful when the interrupt controller has been
501 * started in simulation mode.  A simulated interrupt allows the interrupt
502 * controller to be tested without any device to drive an interrupt input
503 * signal into it.
504 *
505 * @param        InstancePtr is a pointer to the XScuGic instance.
506 * @param        Int_Id is the software interrupt ID to simulate an interrupt.
507 * @param        Cpu_Id is the list of CPUs to send the interrupt.
508 *
509 * @return
510 *
511 * XST_SUCCESS if successful, or XST_FAILURE if the interrupt could not be
512 * simulated
513 *
514 * @note         None.
515 *
516 ******************************************************************************/
517 s32  XScuGic_SoftwareIntr(XScuGic *InstancePtr, u32 Int_Id, u32 Cpu_Id)
518 {
519         u32 Mask;
520
521         /*
522          * Assert the arguments
523          */
524         Xil_AssertNonvoid(InstancePtr != NULL);
525         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
526         Xil_AssertNonvoid(Int_Id <= 15U) ;
527         Xil_AssertNonvoid(Cpu_Id <= 255U) ;
528
529
530         /*
531          * The Int_Id is used to create the appropriate mask for the
532          * desired interrupt. Int_Id currently limited to 0 - 15
533          * Use the target list for the Cpu ID.
534          */
535         Mask = ((Cpu_Id << 16U) | Int_Id) &
536                 (XSCUGIC_SFI_TRIG_CPU_MASK | XSCUGIC_SFI_TRIG_INTID_MASK);
537
538         /*
539          * Write to the Software interrupt trigger register. Use the appropriate
540          * CPU Int_Id.
541          */
542         XScuGic_DistWriteReg(InstancePtr, XSCUGIC_SFI_TRIG_OFFSET, Mask);
543
544         /* Indicate the interrupt was successfully simulated */
545
546         return XST_SUCCESS;
547 }
548
549 /*****************************************************************************/
550 /**
551 *
552 * A stub for the asynchronous callback. The stub is here in case the upper
553 * layers forget to set the handler.
554 *
555 * @param        CallBackRef is a pointer to the upper layer callback reference
556 *
557 * @return       None.
558 *
559 * @note         None.
560 *
561 ******************************************************************************/
562 static void StubHandler(void *CallBackRef) {
563         /*
564          * verify that the inputs are valid
565          */
566         Xil_AssertVoid(CallBackRef != NULL);
567
568         /*
569          * Indicate another unhandled interrupt for stats
570          */
571         ((XScuGic *)((void *)CallBackRef))->UnhandledInterrupts++;
572 }
573
574 /****************************************************************************/
575 /**
576 * Sets the interrupt priority and trigger type for the specificd IRQ source.
577 *
578 * @param        InstancePtr is a pointer to the instance to be worked on.
579 * @param        Int_Id is the IRQ source number to modify
580 * @param        Priority is the new priority for the IRQ source. 0 is highest
581 *                       priority, 0xF8 (248) is lowest. There are 32 priority levels
582 *                       supported with a step of 8. Hence the supported priorities are
583 *                       0, 8, 16, 32, 40 ..., 248.
584 * @param        Trigger is the new trigger type for the IRQ source.
585 * Each bit pair describes the configuration for an INT_ID.
586 * SFI    Read Only    b10 always
587 * PPI    Read Only    depending on how the PPIs are configured.
588 *                    b01    Active HIGH level sensitive
589 *                    b11 Rising edge sensitive
590 * SPI                LSB is read only.
591 *                    b01    Active HIGH level sensitive
592 *                    b11 Rising edge sensitive/
593 *
594 * @return       None.
595 *
596 * @note         None.
597 *
598 *****************************************************************************/
599 void XScuGic_SetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id,
600                                         u8 Priority, u8 Trigger)
601 {
602         u32 RegValue;
603         u8 LocalPriority;
604         LocalPriority = Priority;
605
606         Xil_AssertVoid(InstancePtr != NULL);
607         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
608         Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
609         Xil_AssertVoid(Trigger <= (u8)XSCUGIC_INT_CFG_MASK);
610         Xil_AssertVoid(LocalPriority <= (u8)XSCUGIC_MAX_INTR_PRIO_VAL);
611
612         /*
613          * Determine the register to write to using the Int_Id.
614          */
615         RegValue = XScuGic_DistReadReg(InstancePtr,
616                         XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id));
617
618         /*
619          * The priority bits are Bits 7 to 3 in GIC Priority Register. This
620          * means the number of priority levels supported are 32 and they are
621          * in steps of 8. The priorities can be 0, 8, 16, 32, 48, ... etc.
622          * The lower order 3 bits are masked before putting it in the register.
623          */
624         LocalPriority = LocalPriority & (u8)XSCUGIC_INTR_PRIO_MASK;
625         /*
626          * Shift and Mask the correct bits for the priority and trigger in the
627          * register
628          */
629         RegValue &= ~(XSCUGIC_PRIORITY_MASK << ((Int_Id%4U)*8U));
630         RegValue |= (u32)LocalPriority << ((Int_Id%4U)*8U);
631
632         /*
633          * Write the value back to the register.
634          */
635         XScuGic_DistWriteReg(InstancePtr, XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id),
636                                 RegValue);
637
638         /*
639          * Determine the register to write to using the Int_Id.
640          */
641         RegValue = XScuGic_DistReadReg(InstancePtr,
642                         XSCUGIC_INT_CFG_OFFSET_CALC (Int_Id));
643
644         /*
645          * Shift and Mask the correct bits for the priority and trigger in the
646          * register
647          */
648         RegValue &= ~(XSCUGIC_INT_CFG_MASK << ((Int_Id%16U)*2U));
649         RegValue |= (u32)Trigger << ((Int_Id%16U)*2U);
650
651         /*
652          * Write the value back to the register.
653          */
654         XScuGic_DistWriteReg(InstancePtr, XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id),
655                                 RegValue);
656
657 }
658
659 /****************************************************************************/
660 /**
661 * Gets the interrupt priority and trigger type for the specificd IRQ source.
662 *
663 * @param        InstancePtr is a pointer to the instance to be worked on.
664 * @param        Int_Id is the IRQ source number to modify
665 * @param        Priority is a pointer to the value of the priority of the IRQ
666 *               source. This is a return value.
667 * @param        Trigger is pointer to the value of the trigger of the IRQ
668 *               source. This is a return value.
669 *
670 * @return       None.
671 *
672 * @note         None
673 *
674 *****************************************************************************/
675 void XScuGic_GetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id,
676                                         u8 *Priority, u8 *Trigger)
677 {
678         u32 RegValue;
679
680         Xil_AssertVoid(InstancePtr != NULL);
681         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
682         Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
683         Xil_AssertVoid(Priority != NULL);
684         Xil_AssertVoid(Trigger != NULL);
685
686         /*
687          * Determine the register to read to using the Int_Id.
688          */
689         RegValue = XScuGic_DistReadReg(InstancePtr,
690             XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id));
691
692         /*
693          * Shift and Mask the correct bits for the priority and trigger in the
694          * register
695          */
696         RegValue = RegValue >> ((Int_Id%4U)*8U);
697         *Priority = (u8)(RegValue & XSCUGIC_PRIORITY_MASK);
698
699         /*
700          * Determine the register to read to using the Int_Id.
701          */
702         RegValue = XScuGic_DistReadReg(InstancePtr,
703         XSCUGIC_INT_CFG_OFFSET_CALC (Int_Id));
704
705         /*
706          * Shift and Mask the correct bits for the priority and trigger in the
707          * register
708          */
709         RegValue = RegValue >> ((Int_Id%16U)*2U);
710
711         *Trigger = (u8)(RegValue & XSCUGIC_INT_CFG_MASK);
712 }