ArmPkg/ArmGicDxe: Replace CpuArch registration event with DEPEX

Instead of relying on a protocol notification event to register the core IRQ
interrupt handler with CPU arch protocol once it becomes available, use
a DEPEX to ensure that the GIC driver is not dispatched at all until the
CPU arch protocol has turned up.

This will allow the GIC driver to use other CPU arch protocol methods,
such as the ones needed to map the GIC MMIO regions at driver startup.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
Ard Biesheuvel 2025-01-28 15:55:07 +01:00 committed by mergify[bot]
parent fb7497cbf9
commit 387fcf4fa1
5 changed files with 20 additions and 66 deletions

View File

@ -18,6 +18,7 @@ EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
UINTN mGicNumInterrupts = 0; UINTN mGicNumInterrupts = 0;
HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers = NULL; HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers = NULL;
EFI_CPU_ARCH_PROTOCOL *gCpuArch;
/** /**
Calculate GICD_ICFGRn base address and corresponding bit Calculate GICD_ICFGRn base address and corresponding bit
@ -98,55 +99,6 @@ RegisterInterruptSource (
} }
} }
STATIC VOID *mCpuArchProtocolNotifyEventRegistration;
STATIC
VOID
EFIAPI
CpuArchEventProtocolNotify (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_CPU_ARCH_PROTOCOL *Cpu;
EFI_STATUS Status;
// Get the CPU protocol that this driver requires.
Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
if (EFI_ERROR (Status)) {
return;
}
// Unregister the default exception handler.
Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, NULL);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: Cpu->RegisterInterruptHandler() - %r\n",
__func__,
Status
));
return;
}
// Register to receive interrupts
Status = Cpu->RegisterInterruptHandler (
Cpu,
ARM_ARCH_EXCEPTION_IRQ,
Context
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: Cpu->RegisterInterruptHandler() - %r\n",
__func__,
Status
));
}
gBS->CloseEvent (Event);
}
EFI_STATUS EFI_STATUS
InstallAndRegisterInterruptService ( InstallAndRegisterInterruptService (
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *InterruptProtocol, IN EFI_HARDWARE_INTERRUPT_PROTOCOL *InterruptProtocol,
@ -159,12 +111,24 @@ InstallAndRegisterInterruptService (
CONST UINTN RihArraySize = CONST UINTN RihArraySize =
(sizeof (HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts); (sizeof (HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);
// Locate the CPU arch protocol - cannot fail because of DEPEX
Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpuArch);
ASSERT_EFI_ERROR (Status);
// Initialize the array for the Interrupt Handlers // Initialize the array for the Interrupt Handlers
gRegisteredInterruptHandlers = AllocateZeroPool (RihArraySize); gRegisteredInterruptHandlers = AllocateZeroPool (RihArraySize);
if (gRegisteredInterruptHandlers == NULL) { if (gRegisteredInterruptHandlers == NULL) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
// Register to receive interrupts
Status = gCpuArch->RegisterInterruptHandler (gCpuArch, ARM_ARCH_EXCEPTION_IRQ, InterruptHandler);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: Cpu->RegisterInterruptHandler() - %r\n", __func__, Status));
FreePool (gRegisteredInterruptHandlers);
return Status;
}
Status = gBS->InstallMultipleProtocolInterfaces ( Status = gBS->InstallMultipleProtocolInterfaces (
&gHardwareInterruptHandle, &gHardwareInterruptHandle,
&gHardwareInterruptProtocolGuid, &gHardwareInterruptProtocolGuid,
@ -177,17 +141,6 @@ InstallAndRegisterInterruptService (
return Status; return Status;
} }
//
// Install the interrupt handler as soon as the CPU arch protocol appears.
//
EfiCreateProtocolNotifyEvent (
&gEfiCpuArchProtocolGuid,
TPL_CALLBACK,
CpuArchEventProtocolNotify,
InterruptHandler,
&mCpuArchProtocolNotifyEventRegistration
);
// Register for an ExitBootServicesEvent // Register for an ExitBootServicesEvent
Status = gBS->CreateEvent ( Status = gBS->CreateEvent (
EVT_SIGNAL_EXIT_BOOT_SERVICES, EVT_SIGNAL_EXIT_BOOT_SERVICES,

View File

@ -23,6 +23,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
extern UINTN mGicNumInterrupts; extern UINTN mGicNumInterrupts;
extern HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers; extern HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers;
extern EFI_CPU_ARCH_PROTOCOL *gCpuArch;
// Common API // Common API
EFI_STATUS EFI_STATUS

View File

@ -51,7 +51,7 @@
[Protocols] [Protocols]
gHardwareInterruptProtocolGuid ## PRODUCES gHardwareInterruptProtocolGuid ## PRODUCES
gHardwareInterrupt2ProtocolGuid ## PRODUCES gHardwareInterrupt2ProtocolGuid ## PRODUCES
gEfiCpuArchProtocolGuid ## CONSUMES ## NOTIFY gEfiCpuArchProtocolGuid ## CONSUMES
[Pcd.common] [Pcd.common]
gArmTokenSpaceGuid.PcdGicDistributorBase gArmTokenSpaceGuid.PcdGicDistributorBase
@ -59,4 +59,4 @@
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
[Depex] [Depex]
TRUE gEfiCpuArchProtocolGuid

View File

@ -41,11 +41,11 @@
[Protocols] [Protocols]
gHardwareInterruptProtocolGuid ## PRODUCES gHardwareInterruptProtocolGuid ## PRODUCES
gHardwareInterrupt2ProtocolGuid ## PRODUCES gHardwareInterrupt2ProtocolGuid ## PRODUCES
gEfiCpuArchProtocolGuid ## CONSUMES ## NOTIFY gEfiCpuArchProtocolGuid ## CONSUMES
[Pcd.common] [Pcd.common]
gArmTokenSpaceGuid.PcdGicDistributorBase gArmTokenSpaceGuid.PcdGicDistributorBase
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
[Depex] [Depex]
TRUE gEfiCpuArchProtocolGuid

View File

@ -47,11 +47,11 @@
[Protocols] [Protocols]
gHardwareInterruptProtocolGuid ## PRODUCES gHardwareInterruptProtocolGuid ## PRODUCES
gHardwareInterrupt2ProtocolGuid ## PRODUCES gHardwareInterrupt2ProtocolGuid ## PRODUCES
gEfiCpuArchProtocolGuid ## CONSUMES ## NOTIFY gEfiCpuArchProtocolGuid ## CONSUMES
[Pcd.common] [Pcd.common]
gArmTokenSpaceGuid.PcdGicDistributorBase gArmTokenSpaceGuid.PcdGicDistributorBase
gArmTokenSpaceGuid.PcdGicRedistributorsBase gArmTokenSpaceGuid.PcdGicRedistributorsBase
[Depex] [Depex]
TRUE gEfiCpuArchProtocolGuid