--- /dev/null
+/*++\r
+\r
+Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+--*/\r
+\r
+#include "ArmGicDxe.h"\r
+\r
+VOID\r
+EFIAPI\r
+IrqInterruptHandler (\r
+ IN EFI_EXCEPTION_TYPE InterruptType,\r
+ IN EFI_SYSTEM_CONTEXT SystemContext\r
+ );\r
+\r
+VOID\r
+EFIAPI\r
+ExitBootServicesEvent (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ );\r
+\r
+//\r
+// Making this global saves a few bytes in image size\r
+//\r
+EFI_HANDLE gHardwareInterruptHandle = NULL;\r
+\r
+//\r
+// Notifications\r
+//\r
+EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;\r
+\r
+// Maximum Number of Interrupts\r
+UINTN mGicNumInterrupts = 0;\r
+\r
+HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers = NULL;\r
+\r
+EFI_STATUS\r
+InstallAndRegisterInterruptService (\r
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *InterruptProtocol,\r
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler,\r
+ IN EFI_EVENT_NOTIFY ExitBootServicesEvent\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_CPU_ARCH_PROTOCOL *Cpu;\r
+\r
+ // Initialize the array for the Interrupt Handlers\r
+ gRegisteredInterruptHandlers = (HARDWARE_INTERRUPT_HANDLER*)AllocateZeroPool (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);\r
+ if (gRegisteredInterruptHandlers == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &gHardwareInterruptHandle,\r
+ &gHardwareInterruptProtocolGuid, InterruptProtocol,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get the CPU protocol that this driver requires.\r
+ //\r
+ Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Unregister the default exception handler.\r
+ //\r
+ Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, NULL);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Register to receive interrupts\r
+ //\r
+ Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, InterruptHandler);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ // Register for an ExitBootServicesEvent\r
+ Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);\r
+\r
+ return Status;\r
+}\r