]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Drivers/ArmGic/ArmGicLib.c
ArmPkg/ArmGic: Added GICv3 specific definitions
[mirror_edk2.git] / ArmPkg / Drivers / ArmGic / ArmGicLib.c
CommitLineData
397bdc99
OM
1/** @file\r
2*\r
3* Copyright (c) 2011-2014, ARM Limited. All rights reserved.\r
4*\r
5* This program and the accompanying materials\r
6* are licensed and made available under the terms and conditions of the BSD License\r
7* which accompanies this distribution. The full text of the license may be found at\r
8* http://opensource.org/licenses/bsd-license.php\r
9*\r
10* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12*\r
13**/\r
14\r
60775c51 15#include <Base.h>\r
397bdc99 16#include <Library/ArmGicLib.h>\r
1b0ac0de 17#include <Library/DebugLib.h>\r
60775c51 18#include <Library/IoLib.h>\r
397bdc99 19\r
793ca69f 20#include "GicV2/ArmGicV2Lib.h"\r
d7133859 21#include "GicV3/ArmGicV3Lib.h"\r
793ca69f 22\r
397bdc99
OM
23UINTN\r
24EFIAPI\r
25ArmGicGetInterfaceIdentification (\r
26 IN INTN GicInterruptInterfaceBase\r
27 )\r
28{\r
29 // Read the GIC Identification Register\r
30 return MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIIDR);\r
31}\r
32\r
33UINTN\r
34EFIAPI\r
35ArmGicGetMaxNumInterrupts (\r
36 IN INTN GicDistributorBase\r
37 )\r
38{\r
39 return 32 * ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDICTR) & 0x1F) + 1);\r
40}\r
41\r
42VOID\r
43EFIAPI\r
44ArmGicSendSgiTo (\r
45 IN INTN GicDistributorBase,\r
46 IN INTN TargetListFilter,\r
47 IN INTN CPUTargetList,\r
48 IN INTN SgiId\r
49 )\r
50{\r
51 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId);\r
52}\r
53\r
1b0ac0de
OM
54/*\r
55 * Acknowledge and return the value of the Interrupt Acknowledge Register\r
56 *\r
57 * InterruptId is returned separately from the register value because in\r
58 * the GICv2 the register value contains the CpuId and InterruptId while\r
59 * in the GICv3 the register value is only the InterruptId.\r
60 *\r
61 * @param GicInterruptInterfaceBase Base Address of the GIC CPU Interface\r
62 * @param InterruptId InterruptId read from the Interrupt Acknowledge Register\r
63 *\r
64 * @retval value returned by the Interrupt Acknowledge Register\r
65 *\r
66 */\r
397bdc99
OM
67UINTN\r
68EFIAPI\r
69ArmGicAcknowledgeInterrupt (\r
1b0ac0de
OM
70 IN UINTN GicInterruptInterfaceBase,\r
71 OUT UINTN *InterruptId\r
397bdc99
OM
72 )\r
73{\r
1b0ac0de 74 UINTN Value;\r
d5c6b7fc
OM
75 ARM_GIC_ARCH_REVISION Revision;\r
76\r
77 Revision = ArmGicGetSupportedArchRevision ();\r
78 if (Revision == ARM_GIC_ARCH_REVISION_2) {\r
79 Value = ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase);\r
80 // InterruptId is required for the caller to know if a valid or spurious\r
81 // interrupt has been read\r
82 ASSERT (InterruptId != NULL);\r
83 if (InterruptId != NULL) {\r
84 *InterruptId = Value & ARM_GIC_ICCIAR_ACKINTID;\r
85 }\r
d7133859
OM
86 } else if (Revision == ARM_GIC_ARCH_REVISION_3) {\r
87 Value = ArmGicV3AcknowledgeInterrupt ();\r
d5c6b7fc
OM
88 } else {\r
89 ASSERT_EFI_ERROR (EFI_UNSUPPORTED);\r
90 // Report Spurious interrupt which is what the above controllers would\r
91 // return if no interrupt was available\r
92 Value = 1023;\r
1b0ac0de
OM
93 }\r
94\r
95 return Value;\r
397bdc99
OM
96}\r
97\r
98VOID\r
99EFIAPI\r
100ArmGicEndOfInterrupt (\r
101 IN UINTN GicInterruptInterfaceBase,\r
102 IN UINTN Source\r
103 )\r
104{\r
d5c6b7fc
OM
105 ARM_GIC_ARCH_REVISION Revision;\r
106\r
107 Revision = ArmGicGetSupportedArchRevision ();\r
108 if (Revision == ARM_GIC_ARCH_REVISION_2) {\r
109 ArmGicV2EndOfInterrupt (GicInterruptInterfaceBase, Source);\r
d7133859
OM
110 } else if (Revision == ARM_GIC_ARCH_REVISION_3) {\r
111 ArmGicV3EndOfInterrupt (Source);\r
d5c6b7fc
OM
112 } else {\r
113 ASSERT_EFI_ERROR (EFI_UNSUPPORTED);\r
114 }\r
397bdc99
OM
115}\r
116\r
117VOID\r
118EFIAPI\r
119ArmGicEnableInterrupt (\r
120 IN UINTN GicDistributorBase,\r
121 IN UINTN Source\r
122 )\r
123{\r
124 UINT32 RegOffset;\r
125 UINTN RegShift;\r
126\r
127 // Calculate enable register offset and bit position\r
128 RegOffset = Source / 32;\r
129 RegShift = Source % 32;\r
130\r
131 // Write set-enable register\r
132 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), 1 << RegShift);\r
133}\r
134\r
135VOID\r
136EFIAPI\r
137ArmGicDisableInterrupt (\r
138 IN UINTN GicDistributorBase,\r
139 IN UINTN Source\r
140 )\r
141{\r
142 UINT32 RegOffset;\r
143 UINTN RegShift;\r
144\r
145 // Calculate enable register offset and bit position\r
146 RegOffset = Source / 32;\r
147 RegShift = Source % 32;\r
148\r
149 // Write clear-enable register\r
150 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), 1 << RegShift);\r
151}\r
152\r
153BOOLEAN\r
154EFIAPI\r
155ArmGicIsInterruptEnabled (\r
156 IN UINTN GicDistributorBase,\r
157 IN UINTN Source\r
158 )\r
159{\r
160 UINT32 RegOffset;\r
161 UINTN RegShift;\r
162\r
163 // Calculate enable register offset and bit position\r
164 RegOffset = Source / 32;\r
165 RegShift = Source % 32;\r
166\r
167 return ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)) & (1 << RegShift)) != 0);\r
168}\r
60775c51
OM
169\r
170VOID\r
171EFIAPI\r
172ArmGicDisableDistributor (\r
173 IN INTN GicDistributorBase\r
174 )\r
175{\r
176 // Disable Gic Distributor\r
177 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x0);\r
178}\r
62d441fb 179\r
793ca69f
OM
180VOID\r
181EFIAPI\r
182ArmGicEnableInterruptInterface (\r
183 IN INTN GicInterruptInterfaceBase\r
184 )\r
185{\r
d5c6b7fc
OM
186 ARM_GIC_ARCH_REVISION Revision;\r
187\r
188 Revision = ArmGicGetSupportedArchRevision ();\r
189 if (Revision == ARM_GIC_ARCH_REVISION_2) {\r
190 ArmGicV2EnableInterruptInterface (GicInterruptInterfaceBase);\r
d7133859
OM
191 } else if (Revision == ARM_GIC_ARCH_REVISION_3) {\r
192 ArmGicV3EnableInterruptInterface ();\r
d5c6b7fc
OM
193 } else {\r
194 ASSERT_EFI_ERROR (EFI_UNSUPPORTED);\r
195 }\r
793ca69f
OM
196}\r
197\r
198VOID\r
199EFIAPI\r
200ArmGicDisableInterruptInterface (\r
201 IN INTN GicInterruptInterfaceBase\r
202 )\r
203{\r
d5c6b7fc
OM
204 ARM_GIC_ARCH_REVISION Revision;\r
205\r
206 Revision = ArmGicGetSupportedArchRevision ();\r
207 if (Revision == ARM_GIC_ARCH_REVISION_2) {\r
208 ArmGicV2DisableInterruptInterface (GicInterruptInterfaceBase);\r
d7133859
OM
209 } else if (Revision == ARM_GIC_ARCH_REVISION_3) {\r
210 ArmGicV3DisableInterruptInterface ();\r
d5c6b7fc
OM
211 } else {\r
212 ASSERT_EFI_ERROR (EFI_UNSUPPORTED);\r
213 }\r
793ca69f 214}\r