]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Drivers/ArmGic/ArmGicCommonDxe.c
ArmPkg/ArmGic: Move RegisterInterruptSource() to the common GicDxe file
[mirror_edk2.git] / ArmPkg / Drivers / ArmGic / ArmGicCommonDxe.c
CommitLineData
69b5dc9f
OM
1/*++\r
2\r
3Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>\r
4\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13--*/\r
14\r
15#include "ArmGicDxe.h"\r
16\r
17VOID\r
18EFIAPI\r
19IrqInterruptHandler (\r
20 IN EFI_EXCEPTION_TYPE InterruptType,\r
21 IN EFI_SYSTEM_CONTEXT SystemContext\r
22 );\r
23\r
24VOID\r
25EFIAPI\r
26ExitBootServicesEvent (\r
27 IN EFI_EVENT Event,\r
28 IN VOID *Context\r
29 );\r
30\r
31//\r
32// Making this global saves a few bytes in image size\r
33//\r
34EFI_HANDLE gHardwareInterruptHandle = NULL;\r
35\r
36//\r
37// Notifications\r
38//\r
39EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;\r
40\r
41// Maximum Number of Interrupts\r
42UINTN mGicNumInterrupts = 0;\r
43\r
44HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers = NULL;\r
45\r
0458b423
OM
46/**\r
47 Register Handler for the specified interrupt source.\r
48\r
49 @param This Instance pointer for this protocol\r
50 @param Source Hardware source of the interrupt\r
51 @param Handler Callback for interrupt. NULL to unregister\r
52\r
53 @retval EFI_SUCCESS Source was updated to support Handler.\r
54 @retval EFI_DEVICE_ERROR Hardware could not be programmed.\r
55\r
56**/\r
57EFI_STATUS\r
58EFIAPI\r
59RegisterInterruptSource (\r
60 IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,\r
61 IN HARDWARE_INTERRUPT_SOURCE Source,\r
62 IN HARDWARE_INTERRUPT_HANDLER Handler\r
63 )\r
64{\r
65 if (Source > mGicNumInterrupts) {\r
66 ASSERT(FALSE);\r
67 return EFI_UNSUPPORTED;\r
68 }\r
69\r
70 if ((Handler == NULL) && (gRegisteredInterruptHandlers[Source] == NULL)) {\r
71 return EFI_INVALID_PARAMETER;\r
72 }\r
73\r
74 if ((Handler != NULL) && (gRegisteredInterruptHandlers[Source] != NULL)) {\r
75 return EFI_ALREADY_STARTED;\r
76 }\r
77\r
78 gRegisteredInterruptHandlers[Source] = Handler;\r
79\r
80 // If the interrupt handler is unregistered then disable the interrupt\r
81 if (NULL == Handler){\r
82 return This->DisableInterruptSource (This, Source);\r
83 } else {\r
84 return This->EnableInterruptSource (This, Source);\r
85 }\r
86}\r
87\r
69b5dc9f
OM
88EFI_STATUS\r
89InstallAndRegisterInterruptService (\r
90 IN EFI_HARDWARE_INTERRUPT_PROTOCOL *InterruptProtocol,\r
91 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler,\r
92 IN EFI_EVENT_NOTIFY ExitBootServicesEvent\r
93 )\r
94{\r
95 EFI_STATUS Status;\r
96 EFI_CPU_ARCH_PROTOCOL *Cpu;\r
97\r
98 // Initialize the array for the Interrupt Handlers\r
99 gRegisteredInterruptHandlers = (HARDWARE_INTERRUPT_HANDLER*)AllocateZeroPool (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);\r
100 if (gRegisteredInterruptHandlers == NULL) {\r
101 return EFI_OUT_OF_RESOURCES;\r
102 }\r
103\r
104 Status = gBS->InstallMultipleProtocolInterfaces (\r
105 &gHardwareInterruptHandle,\r
106 &gHardwareInterruptProtocolGuid, InterruptProtocol,\r
107 NULL\r
108 );\r
109 if (EFI_ERROR (Status)) {\r
110 return Status;\r
111 }\r
112\r
113 //\r
114 // Get the CPU protocol that this driver requires.\r
115 //\r
116 Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);\r
117 if (EFI_ERROR (Status)) {\r
118 return Status;\r
119 }\r
120\r
121 //\r
122 // Unregister the default exception handler.\r
123 //\r
124 Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, NULL);\r
125 if (EFI_ERROR (Status)) {\r
126 return Status;\r
127 }\r
128\r
129 //\r
130 // Register to receive interrupts\r
131 //\r
132 Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, InterruptHandler);\r
133 if (EFI_ERROR (Status)) {\r
134 return Status;\r
135 }\r
136\r
137 // Register for an ExitBootServicesEvent\r
138 Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);\r
139\r
140 return Status;\r
141}\r