/** Register Handler for the specified interrupt source. @param This Instance pointer for this protocol @param Source Hardware source of the interrupt @param Handler Callback for interrupt. NULL to unregister @retval EFI_SUCCESS Source was updated to support Handler. @retval EFI_DEVICE_ERROR Hardware could not be programmed. **/ EFI_STATUS EFIAPI RegisterInterruptSource ( IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This, IN HARDWARE_INTERRUPT_SOURCE Source, IN HARDWARE_INTERRUPT_HANDLER Handler ) { if (Source > MAX_VECTOR) { ASSERT(FALSE); return EFI_UNSUPPORTED; } if ((MmioRead32 (INTCPS_ILR(Source)) & INTCPS_ILR_FIQ) == INTCPS_ILR_FIQ) { // This vector has been programmed as FIQ so we can't use it for IRQ // EFI does not use FIQ, but the debugger can use it to check for // ctrl-c. So this ASSERT means you have a conflict with the debug agent ASSERT (FALSE); return EFI_UNSUPPORTED; } if ((Handler == NULL) && (gRegisteredInterruptHandlers[Source] == NULL)) { return EFI_INVALID_PARAMETER; } if ((Handler != NULL) && (gRegisteredInterruptHandlers[Source] != NULL)) { return EFI_ALREADY_STARTED; } gRegisteredInterruptHandlers[Source] = Handler; return This->EnableInterruptSource(This, Source); }
VOID EnableInterruptSource ( VOID ) { UINTN Bank; UINTN Bit; // Map vector to FIQ, IRQ is default MmioWrite32 (INTCPS_ILR (gVector), 1); Bank = gVector / 32; Bit = 1UL << (gVector % 32); MmioWrite32 (INTCPS_MIR_CLEAR(Bank), Bit); }