]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Drivers/ArmGic/ArmGicLib.c
ArmPkg/ArmGic: Added GicV3 detection
[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
OM
20#include "GicV2/ArmGicV2Lib.h"\r
21\r
397bdc99
OM
22UINTN\r
23EFIAPI\r
24ArmGicGetInterfaceIdentification (\r
25 IN INTN GicInterruptInterfaceBase\r
26 )\r
27{\r
28 // Read the GIC Identification Register\r
29 return MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIIDR);\r
30}\r
31\r
32UINTN\r
33EFIAPI\r
34ArmGicGetMaxNumInterrupts (\r
35 IN INTN GicDistributorBase\r
36 )\r
37{\r
38 return 32 * ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDICTR) & 0x1F) + 1);\r
39}\r
40\r
41VOID\r
42EFIAPI\r
43ArmGicSendSgiTo (\r
44 IN INTN GicDistributorBase,\r
45 IN INTN TargetListFilter,\r
46 IN INTN CPUTargetList,\r
47 IN INTN SgiId\r
48 )\r
49{\r
50 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId);\r
51}\r
52\r
1b0ac0de
OM
53/*\r
54 * Acknowledge and return the value of the Interrupt Acknowledge Register\r
55 *\r
56 * InterruptId is returned separately from the register value because in\r
57 * the GICv2 the register value contains the CpuId and InterruptId while\r
58 * in the GICv3 the register value is only the InterruptId.\r
59 *\r
60 * @param GicInterruptInterfaceBase Base Address of the GIC CPU Interface\r
61 * @param InterruptId InterruptId read from the Interrupt Acknowledge Register\r
62 *\r
63 * @retval value returned by the Interrupt Acknowledge Register\r
64 *\r
65 */\r
397bdc99
OM
66UINTN\r
67EFIAPI\r
68ArmGicAcknowledgeInterrupt (\r
1b0ac0de
OM
69 IN UINTN GicInterruptInterfaceBase,\r
70 OUT UINTN *InterruptId\r
397bdc99
OM
71 )\r
72{\r
1b0ac0de 73 UINTN Value;\r
d5c6b7fc
OM
74 ARM_GIC_ARCH_REVISION Revision;\r
75\r
76 Revision = ArmGicGetSupportedArchRevision ();\r
77 if (Revision == ARM_GIC_ARCH_REVISION_2) {\r
78 Value = ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase);\r
79 // InterruptId is required for the caller to know if a valid or spurious\r
80 // interrupt has been read\r
81 ASSERT (InterruptId != NULL);\r
82 if (InterruptId != NULL) {\r
83 *InterruptId = Value & ARM_GIC_ICCIAR_ACKINTID;\r
84 }\r
85 } else {\r
86 ASSERT_EFI_ERROR (EFI_UNSUPPORTED);\r
87 // Report Spurious interrupt which is what the above controllers would\r
88 // return if no interrupt was available\r
89 Value = 1023;\r
1b0ac0de
OM
90 }\r
91\r
92 return Value;\r
397bdc99
OM
93}\r
94\r
95VOID\r
96EFIAPI\r
97ArmGicEndOfInterrupt (\r
98 IN UINTN GicInterruptInterfaceBase,\r
99 IN UINTN Source\r
100 )\r
101{\r
d5c6b7fc
OM
102 ARM_GIC_ARCH_REVISION Revision;\r
103\r
104 Revision = ArmGicGetSupportedArchRevision ();\r
105 if (Revision == ARM_GIC_ARCH_REVISION_2) {\r
106 ArmGicV2EndOfInterrupt (GicInterruptInterfaceBase, Source);\r
107 } else {\r
108 ASSERT_EFI_ERROR (EFI_UNSUPPORTED);\r
109 }\r
397bdc99
OM
110}\r
111\r
112VOID\r
113EFIAPI\r
114ArmGicEnableInterrupt (\r
115 IN UINTN GicDistributorBase,\r
116 IN UINTN Source\r
117 )\r
118{\r
119 UINT32 RegOffset;\r
120 UINTN RegShift;\r
121\r
122 // Calculate enable register offset and bit position\r
123 RegOffset = Source / 32;\r
124 RegShift = Source % 32;\r
125\r
126 // Write set-enable register\r
127 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), 1 << RegShift);\r
128}\r
129\r
130VOID\r
131EFIAPI\r
132ArmGicDisableInterrupt (\r
133 IN UINTN GicDistributorBase,\r
134 IN UINTN Source\r
135 )\r
136{\r
137 UINT32 RegOffset;\r
138 UINTN RegShift;\r
139\r
140 // Calculate enable register offset and bit position\r
141 RegOffset = Source / 32;\r
142 RegShift = Source % 32;\r
143\r
144 // Write clear-enable register\r
145 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), 1 << RegShift);\r
146}\r
147\r
148BOOLEAN\r
149EFIAPI\r
150ArmGicIsInterruptEnabled (\r
151 IN UINTN GicDistributorBase,\r
152 IN UINTN Source\r
153 )\r
154{\r
155 UINT32 RegOffset;\r
156 UINTN RegShift;\r
157\r
158 // Calculate enable register offset and bit position\r
159 RegOffset = Source / 32;\r
160 RegShift = Source % 32;\r
161\r
162 return ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)) & (1 << RegShift)) != 0);\r
163}\r
60775c51
OM
164\r
165VOID\r
166EFIAPI\r
167ArmGicDisableDistributor (\r
168 IN INTN GicDistributorBase\r
169 )\r
170{\r
171 // Disable Gic Distributor\r
172 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x0);\r
173}\r
62d441fb 174\r
793ca69f
OM
175VOID\r
176EFIAPI\r
177ArmGicEnableInterruptInterface (\r
178 IN INTN GicInterruptInterfaceBase\r
179 )\r
180{\r
d5c6b7fc
OM
181 ARM_GIC_ARCH_REVISION Revision;\r
182\r
183 Revision = ArmGicGetSupportedArchRevision ();\r
184 if (Revision == ARM_GIC_ARCH_REVISION_2) {\r
185 ArmGicV2EnableInterruptInterface (GicInterruptInterfaceBase);\r
186 } else {\r
187 ASSERT_EFI_ERROR (EFI_UNSUPPORTED);\r
188 }\r
793ca69f
OM
189}\r
190\r
191VOID\r
192EFIAPI\r
193ArmGicDisableInterruptInterface (\r
194 IN INTN GicInterruptInterfaceBase\r
195 )\r
196{\r
d5c6b7fc
OM
197 ARM_GIC_ARCH_REVISION Revision;\r
198\r
199 Revision = ArmGicGetSupportedArchRevision ();\r
200 if (Revision == ARM_GIC_ARCH_REVISION_2) {\r
201 ArmGicV2DisableInterruptInterface (GicInterruptInterfaceBase);\r
202 } else {\r
203 ASSERT_EFI_ERROR (EFI_UNSUPPORTED);\r
204 }\r
793ca69f 205}\r