]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Drivers/ArmGic/ArmGicCommonDxe.c
ArmPkg/ArmGic: Move the installation and the registration to InstallAndRegisterInterr...
[mirror_edk2.git] / ArmPkg / Drivers / ArmGic / ArmGicCommonDxe.c
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicCommonDxe.c b/ArmPkg/Drivers/ArmGic/ArmGicCommonDxe.c
new file mode 100644 (file)
index 0000000..346d0bc
--- /dev/null
@@ -0,0 +1,99 @@
+/*++\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