/** EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs. @param InterruptType Defines the type of interrupt or exception that occurred on the processor.This parameter is processor architecture specific. @param SystemContext A pointer to the processor context when the interrupt occurred on the processor. @return None **/ VOID EFIAPI GicV2IrqInterruptHandler ( IN EFI_EXCEPTION_TYPE InterruptType, IN EFI_SYSTEM_CONTEXT SystemContext ) { UINT32 GicInterrupt; HARDWARE_INTERRUPT_HANDLER InterruptHandler; GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase); // Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the number of interrupt (ie: Spurious interrupt). if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) >= mGicNumInterrupts) { // The special interrupt do not need to be acknowledge return; } InterruptHandler = gRegisteredInterruptHandlers[GicInterrupt]; if (InterruptHandler != NULL) { // Call the registered interrupt handler. InterruptHandler (GicInterrupt, SystemContext); } else { DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt)); } GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt); }
/** Shutdown our hardware DXE Core will disable interrupts and turn off the timer and disable interrupts after all the event handlers have run. @param[in] Event The Event that is being processed @param[in] Context Event Context **/ VOID EFIAPI GicV2ExitBootServicesEvent ( IN EFI_EVENT Event, IN VOID *Context ) { UINTN Index; UINT32 GicInterrupt; // Disable all the interrupts for (Index = 0; Index < mGicNumInterrupts; Index++) { GicV2DisableInterruptSource (&gHardwareInterruptV2Protocol, Index); } // Acknowledge all pending interrupts do { GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase); if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) < mGicNumInterrupts) { GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt); } } while (!ARM_GIC_IS_SPECIAL_INTERRUPTS (GicInterrupt)); // Disable Gic Interface ArmGicV2DisableInterruptInterface (mGicInterruptInterfaceBase); // Disable Gic Distributor ArmGicDisableDistributor (mGicDistributorBase); }
/* * Acknowledge and return the value of the Interrupt Acknowledge Register * * InterruptId is returned separately from the register value because in * the GICv2 the register value contains the CpuId and InterruptId while * in the GICv3 the register value is only the InterruptId. * * @param GicInterruptInterfaceBase Base Address of the GIC CPU Interface * @param InterruptId InterruptId read from the Interrupt Acknowledge Register * * @retval value returned by the Interrupt Acknowledge Register * */ UINTN EFIAPI ArmGicAcknowledgeInterrupt ( IN UINTN GicInterruptInterfaceBase, OUT UINTN *InterruptId ) { UINTN Value; Value = ArmGicV2AcknowledgeInterrupt (GicInterruptInterfaceBase); // InterruptId is required for the caller to know if a valid or spurious // interrupt has been read ASSERT (InterruptId != NULL); if (InterruptId != NULL) { *InterruptId = Value & ARM_GIC_ICCIAR_ACKINTID; } return Value; }