3 Copyright (c) 2013-2017, ARM Ltd. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
14 IN EFI_EXCEPTION_TYPE InterruptType
,
15 IN EFI_SYSTEM_CONTEXT SystemContext
20 ExitBootServicesEvent (
25 // Making this global saves a few bytes in image size
26 EFI_HANDLE gHardwareInterruptHandle
= NULL
;
29 EFI_EVENT EfiExitBootServicesEvent
= (EFI_EVENT
)NULL
;
31 // Maximum Number of Interrupts
32 UINTN mGicNumInterrupts
= 0;
34 HARDWARE_INTERRUPT_HANDLER
*gRegisteredInterruptHandlers
= NULL
;
37 Calculate GICD_ICFGRn base address and corresponding bit
38 field Int_config[1] of the GIC distributor register.
40 @param Source Hardware source of the interrupt.
41 @param RegAddress Corresponding GICD_ICFGRn base address.
42 @param Config1Bit Bit number of F Int_config[1] bit in the register.
44 @retval EFI_SUCCESS Source interrupt supported.
45 @retval EFI_UNSUPPORTED Source interrupt is not supported.
48 GicGetDistributorIcfgBaseAndBit (
49 IN HARDWARE_INTERRUPT_SOURCE Source
,
50 OUT UINTN
*RegAddress
,
57 if (Source
>= mGicNumInterrupts
) {
58 ASSERT (Source
< mGicNumInterrupts
);
59 return EFI_UNSUPPORTED
;
62 RegIndex
= Source
/ ARM_GIC_ICDICFR_F_STRIDE
; // NOTE: truncation is significant
63 Field
= Source
% ARM_GIC_ICDICFR_F_STRIDE
;
64 *RegAddress
= PcdGet64 (PcdGicDistributorBase
)
66 + (ARM_GIC_ICDICFR_BYTES
* RegIndex
);
67 *Config1Bit
= ((Field
* ARM_GIC_ICDICFR_F_WIDTH
)
68 + ARM_GIC_ICDICFR_F_CONFIG1_BIT
);
74 Register Handler for the specified interrupt source.
76 @param This Instance pointer for this protocol
77 @param Source Hardware source of the interrupt
78 @param Handler Callback for interrupt. NULL to unregister
80 @retval EFI_SUCCESS Source was updated to support Handler.
81 @retval EFI_DEVICE_ERROR Hardware could not be programmed.
86 RegisterInterruptSource (
87 IN EFI_HARDWARE_INTERRUPT_PROTOCOL
*This
,
88 IN HARDWARE_INTERRUPT_SOURCE Source
,
89 IN HARDWARE_INTERRUPT_HANDLER Handler
92 if (Source
>= mGicNumInterrupts
) {
94 return EFI_UNSUPPORTED
;
97 if ((Handler
== NULL
) && (gRegisteredInterruptHandlers
[Source
] == NULL
)) {
98 return EFI_INVALID_PARAMETER
;
101 if ((Handler
!= NULL
) && (gRegisteredInterruptHandlers
[Source
] != NULL
)) {
102 return EFI_ALREADY_STARTED
;
105 gRegisteredInterruptHandlers
[Source
] = Handler
;
107 // If the interrupt handler is unregistered then disable the interrupt
108 if (NULL
== Handler
) {
109 return This
->DisableInterruptSource (This
, Source
);
111 return This
->EnableInterruptSource (This
, Source
);
115 STATIC VOID
*mCpuArchProtocolNotifyEventRegistration
;
120 CpuArchEventProtocolNotify (
125 EFI_CPU_ARCH_PROTOCOL
*Cpu
;
128 // Get the CPU protocol that this driver requires.
129 Status
= gBS
->LocateProtocol (&gEfiCpuArchProtocolGuid
, NULL
, (VOID
**)&Cpu
);
130 if (EFI_ERROR (Status
)) {
134 // Unregister the default exception handler.
135 Status
= Cpu
->RegisterInterruptHandler (Cpu
, ARM_ARCH_EXCEPTION_IRQ
, NULL
);
136 if (EFI_ERROR (Status
)) {
139 "%a: Cpu->RegisterInterruptHandler() - %r\n",
146 // Register to receive interrupts
147 Status
= Cpu
->RegisterInterruptHandler (
149 ARM_ARCH_EXCEPTION_IRQ
,
152 if (EFI_ERROR (Status
)) {
155 "%a: Cpu->RegisterInterruptHandler() - %r\n",
161 gBS
->CloseEvent (Event
);
165 InstallAndRegisterInterruptService (
166 IN EFI_HARDWARE_INTERRUPT_PROTOCOL
*InterruptProtocol
,
167 IN EFI_HARDWARE_INTERRUPT2_PROTOCOL
*Interrupt2Protocol
,
168 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
,
169 IN EFI_EVENT_NOTIFY ExitBootServicesEvent
173 CONST UINTN RihArraySize
=
174 (sizeof (HARDWARE_INTERRUPT_HANDLER
) * mGicNumInterrupts
);
176 // Initialize the array for the Interrupt Handlers
177 gRegisteredInterruptHandlers
= AllocateZeroPool (RihArraySize
);
178 if (gRegisteredInterruptHandlers
== NULL
) {
179 return EFI_OUT_OF_RESOURCES
;
182 Status
= gBS
->InstallMultipleProtocolInterfaces (
183 &gHardwareInterruptHandle
,
184 &gHardwareInterruptProtocolGuid
,
186 &gHardwareInterrupt2ProtocolGuid
,
190 if (EFI_ERROR (Status
)) {
195 // Install the interrupt handler as soon as the CPU arch protocol appears.
197 EfiCreateProtocolNotifyEvent (
198 &gEfiCpuArchProtocolGuid
,
200 CpuArchEventProtocolNotify
,
202 &mCpuArchProtocolNotifyEventRegistration
205 // Register for an ExitBootServicesEvent
206 Status
= gBS
->CreateEvent (
207 EVT_SIGNAL_EXIT_BOOT_SERVICES
,
209 ExitBootServicesEvent
,
211 &EfiExitBootServicesEvent