23#define ARM_GIC_DEFAULT_PRIORITY 0x80
44GicV2EnableInterruptSource (
46 IN HARDWARE_INTERRUPT_SOURCE Source
49 if (Source >= mGicNumInterrupts) {
51 return EFI_UNSUPPORTED;
54 ArmGicEnableInterrupt (mGicDistributorBase, 0, Source);
72GicV2DisableInterruptSource (
74 IN HARDWARE_INTERRUPT_SOURCE Source
77 if (Source >= mGicNumInterrupts) {
79 return EFI_UNSUPPORTED;
82 ArmGicDisableInterrupt (mGicDistributorBase, 0, Source);
101GicV2GetInterruptSourceState (
103 IN HARDWARE_INTERRUPT_SOURCE Source,
104 IN BOOLEAN *InterruptState
107 if (Source >= mGicNumInterrupts) {
109 return EFI_UNSUPPORTED;
112 *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, 0, Source);
133 IN HARDWARE_INTERRUPT_SOURCE Source
136 if (Source >= mGicNumInterrupts) {
138 return EFI_UNSUPPORTED;
141 ArmGicV2EndOfInterrupt (mGicInterruptInterfaceBase, Source);
160GicV2IrqInterruptHandler (
168 GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase);
172 if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) >= mGicNumInterrupts) {
177 InterruptHandler = gRegisteredInterruptHandlers[GicInterrupt];
178 if (InterruptHandler !=
NULL) {
180 InterruptHandler (GicInterrupt, SystemContext);
182 DEBUG ((DEBUG_ERROR,
"Spurious GIC interrupt: 0x%x\n", (UINT32)GicInterrupt));
183 GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);
189 RegisterInterruptSource,
190 GicV2EnableInterruptSource,
191 GicV2DisableInterruptSource,
192 GicV2GetInterruptSourceState,
211 IN HARDWARE_INTERRUPT_SOURCE Source,
212 OUT EFI_HARDWARE_INTERRUPT2_TRIGGER_TYPE *TriggerType
219 Status = GicGetDistributorIcfgBaseAndBit (
225 if (EFI_ERROR (Status)) {
229 if ((
MmioRead32 (RegAddress) & (1 << Config1Bit)) == 0) {
230 *TriggerType = EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH;
232 *TriggerType = EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING;
253 IN HARDWARE_INTERRUPT_SOURCE Source,
254 IN EFI_HARDWARE_INTERRUPT2_TRIGGER_TYPE TriggerType
261 BOOLEAN SourceEnabled;
263 if ( (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING)
264 && (TriggerType != EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH))
268 "Invalid interrupt trigger type: %d\n", \
272 return EFI_UNSUPPORTED;
275 Status = GicGetDistributorIcfgBaseAndBit (
281 if (EFI_ERROR (Status)) {
285 Status = GicV2GetInterruptSourceState (
291 if (EFI_ERROR (Status)) {
295 Value = (TriggerType == EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING)
296 ? ARM_GIC_ICDICFR_EDGE_TRIGGERED
297 : ARM_GIC_ICDICFR_LEVEL_TRIGGERED;
302 GicV2DisableInterruptSource (
310 ~(0x1 << Config1Bit),
316 GicV2EnableInterruptSource (
347GicV2ExitBootServicesEvent (
356 for (Index = 0; Index < mGicNumInterrupts; Index++) {
357 GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index);
362 GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase);
364 if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) < mGicNumInterrupts) {
365 GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);
367 }
while (!ARM_GIC_IS_SPECIAL_INTERRUPTS (GicInterrupt));
370 ArmGicV2DisableInterruptInterface (mGicInterruptInterfaceBase);
373 ArmGicDisableDistributor (mGicDistributorBase);
403 ASSERT (
PcdGet64 (PcdGicInterruptInterfaceBase) <= MAX_UINTN);
404 ASSERT (
PcdGet64 (PcdGicDistributorBase) <= MAX_UINTN);
406 mGicInterruptInterfaceBase = (
UINTN)
PcdGet64 (PcdGicInterruptInterfaceBase);
407 mGicDistributorBase = (
UINTN)
PcdGet64 (PcdGicDistributorBase);
408 mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase);
410 for (Index = 0; Index < mGicNumInterrupts; Index++) {
411 GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index);
414 RegOffset = (UINT32)(Index / 4);
415 RegShift = (UINT8)((Index % 4) * 8);
417 mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
419 ARM_GIC_DEFAULT_PRIORITY << RegShift
433 CpuTarget =
MmioRead32 (mGicDistributorBase + ARM_GIC_ICDIPTR);
437 if (CpuTarget != 0) {
439 for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) {
441 mGicDistributorBase + ARM_GIC_ICDIPTR + (Index * 4),
448 MmioWrite32 (mGicInterruptInterfaceBase + ARM_GIC_ICCBPR, 0x7);
451 MmioWrite32 (mGicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0xff);
454 ArmGicEnableInterruptInterface (mGicInterruptInterfaceBase);
457 ArmGicEnableDistributor (mGicDistributorBase);
459 Status = InstallAndRegisterInterruptService (
460 &gHardwareInterruptV2Protocol,
461 &gHardwareInterrupt2V2Protocol,
462 GicV2IrqInterruptHandler,
463 GicV2ExitBootServicesEvent
EFI_STATUS(EFIAPI * HARDWARE_INTERRUPT2_DISABLE)(IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *This, IN HARDWARE_INTERRUPT_SOURCE Source)
EFI_STATUS(EFIAPI * HARDWARE_INTERRUPT2_REGISTER)(IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *This, IN HARDWARE_INTERRUPT_SOURCE Source, IN HARDWARE_INTERRUPT_HANDLER Handler)
EFI_STATUS(EFIAPI * HARDWARE_INTERRUPT2_END_OF_INTERRUPT)(IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *This, IN HARDWARE_INTERRUPT_SOURCE Source)
EFI_STATUS(EFIAPI * HARDWARE_INTERRUPT2_ENABLE)(IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *This, IN HARDWARE_INTERRUPT_SOURCE Source)
EFI_STATUS(EFIAPI * HARDWARE_INTERRUPT2_INTERRUPT_STATE)(IN EFI_HARDWARE_INTERRUPT2_PROTOCOL *This, IN HARDWARE_INTERRUPT_SOURCE Source, IN BOOLEAN *InterruptState)
VOID(EFIAPI * HARDWARE_INTERRUPT_HANDLER)(IN HARDWARE_INTERRUPT_SOURCE Source, IN EFI_SYSTEM_CONTEXT SystemContext)
UINT32 EFIAPI MmioRead32(IN UINTN Address)
UINT32 EFIAPI MmioAndThenOr32(IN UINTN Address, IN UINT32 AndData, IN UINT32 OrData)
UINT32 EFIAPI MmioWrite32(IN UINTN Address, IN UINT32 Value)
#define DEBUG(Expression)
#define ASSERT_PROTOCOL_ALREADY_INSTALLED(Handle, Guid)
#define PcdGet64(TokenName)