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