3 * Copyright (c) 2011-2014, ARM Limited. All rights reserved.
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Library/ArmGicLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/IoLib.h>
20 #include "GicV2/ArmGicV2Lib.h"
24 ArmGicGetSupportedArchRevision (
28 return ARM_GIC_ARCH_REVISION_2
;
33 ArmGicGetInterfaceIdentification (
34 IN INTN GicInterruptInterfaceBase
37 // Read the GIC Identification Register
38 return MmioRead32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCIIDR
);
43 ArmGicGetMaxNumInterrupts (
44 IN INTN GicDistributorBase
47 return 32 * ((MmioRead32 (GicDistributorBase
+ ARM_GIC_ICDICTR
) & 0x1F) + 1);
53 IN INTN GicDistributorBase
,
54 IN INTN TargetListFilter
,
55 IN INTN CPUTargetList
,
59 MmioWrite32 (GicDistributorBase
+ ARM_GIC_ICDSGIR
, ((TargetListFilter
& 0x3) << 24) | ((CPUTargetList
& 0xFF) << 16) | SgiId
);
63 * Acknowledge and return the value of the Interrupt Acknowledge Register
65 * InterruptId is returned separately from the register value because in
66 * the GICv2 the register value contains the CpuId and InterruptId while
67 * in the GICv3 the register value is only the InterruptId.
69 * @param GicInterruptInterfaceBase Base Address of the GIC CPU Interface
70 * @param InterruptId InterruptId read from the Interrupt Acknowledge Register
72 * @retval value returned by the Interrupt Acknowledge Register
77 ArmGicAcknowledgeInterrupt (
78 IN UINTN GicInterruptInterfaceBase
,
79 OUT UINTN
*InterruptId
83 ARM_GIC_ARCH_REVISION Revision
;
85 Revision
= ArmGicGetSupportedArchRevision ();
86 if (Revision
== ARM_GIC_ARCH_REVISION_2
) {
87 Value
= ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase
);
88 // InterruptId is required for the caller to know if a valid or spurious
89 // interrupt has been read
90 ASSERT (InterruptId
!= NULL
);
91 if (InterruptId
!= NULL
) {
92 *InterruptId
= Value
& ARM_GIC_ICCIAR_ACKINTID
;
95 ASSERT_EFI_ERROR (EFI_UNSUPPORTED
);
96 // Report Spurious interrupt which is what the above controllers would
97 // return if no interrupt was available
106 ArmGicEndOfInterrupt (
107 IN UINTN GicInterruptInterfaceBase
,
111 ARM_GIC_ARCH_REVISION Revision
;
113 Revision
= ArmGicGetSupportedArchRevision ();
114 if (Revision
== ARM_GIC_ARCH_REVISION_2
) {
115 ArmGicV2EndOfInterrupt (GicInterruptInterfaceBase
, Source
);
117 ASSERT_EFI_ERROR (EFI_UNSUPPORTED
);
123 ArmGicEnableInterrupt (
124 IN UINTN GicDistributorBase
,
131 // Calculate enable register offset and bit position
132 RegOffset
= Source
/ 32;
133 RegShift
= Source
% 32;
135 // Write set-enable register
136 MmioWrite32 (GicDistributorBase
+ ARM_GIC_ICDISER
+ (4 * RegOffset
), 1 << RegShift
);
141 ArmGicDisableInterrupt (
142 IN UINTN GicDistributorBase
,
149 // Calculate enable register offset and bit position
150 RegOffset
= Source
/ 32;
151 RegShift
= Source
% 32;
153 // Write clear-enable register
154 MmioWrite32 (GicDistributorBase
+ ARM_GIC_ICDICER
+ (4 * RegOffset
), 1 << RegShift
);
159 ArmGicIsInterruptEnabled (
160 IN UINTN GicDistributorBase
,
167 // Calculate enable register offset and bit position
168 RegOffset
= Source
/ 32;
169 RegShift
= Source
% 32;
171 return ((MmioRead32 (GicDistributorBase
+ ARM_GIC_ICDISER
+ (4 * RegOffset
)) & (1 << RegShift
)) != 0);
176 ArmGicDisableDistributor (
177 IN INTN GicDistributorBase
180 // Disable Gic Distributor
181 MmioWrite32 (GicDistributorBase
+ ARM_GIC_ICDDCR
, 0x0);
186 ArmGicEnableInterruptInterface (
187 IN INTN GicInterruptInterfaceBase
190 ARM_GIC_ARCH_REVISION Revision
;
192 Revision
= ArmGicGetSupportedArchRevision ();
193 if (Revision
== ARM_GIC_ARCH_REVISION_2
) {
194 ArmGicV2EnableInterruptInterface (GicInterruptInterfaceBase
);
196 ASSERT_EFI_ERROR (EFI_UNSUPPORTED
);
202 ArmGicDisableInterruptInterface (
203 IN INTN GicInterruptInterfaceBase
206 ARM_GIC_ARCH_REVISION Revision
;
208 Revision
= ArmGicGetSupportedArchRevision ();
209 if (Revision
== ARM_GIC_ARCH_REVISION_2
) {
210 ArmGicV2DisableInterruptInterface (GicInterruptInterfaceBase
);
212 ASSERT_EFI_ERROR (EFI_UNSUPPORTED
);