diff --git a/ArmPkg/Drivers/TimerDxe/TimerDxe.c b/ArmPkg/Drivers/TimerDxe/TimerDxe.c index 37859e178e..b7f5ecca56 100644 --- a/ArmPkg/Drivers/TimerDxe/TimerDxe.c +++ b/ArmPkg/Drivers/TimerDxe/TimerDxe.c @@ -22,6 +22,8 @@ #include #include +#include "TimerDxe.h" + // The notification function to call on every timer interrupt. EFI_TIMER_NOTIFY mTimerNotifyFunction = (EFI_TIMER_NOTIFY)NULL; EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL; @@ -359,6 +361,9 @@ TimerInitialize ( EFI_STATUS Status; UINTN TimerCtrlReg; UINT32 TimerHypIntrNum; + UINT32 TimerVirtIntrNum; + UINT32 TimerSecIntrNum; + UINT32 TimerIntrNum; if (ArmIsArchTimerImplemented () == 0) { DEBUG ((DEBUG_ERROR, "ARM Architectural Timer is not available in the CPU, hence can't use this Driver \n")); @@ -377,27 +382,38 @@ TimerInitialize ( Status = TimerDriverSetTimerPeriod (&gTimer, 0); ASSERT_EFI_ERROR (Status); + if (ArmHasGicV5SystemRegisters ()) { + TimerSecIntrNum = GICV5_ARCH_TIMER_SEC_INTID; + TimerIntrNum = GICV5_ARCH_TIMER_INTID; + TimerHypIntrNum = GICV5_ARCH_TIMER_HYP_INTID; + TimerVirtIntrNum = GICV5_ARCH_TIMER_VIRT_INTID; + } else { + TimerVirtIntrNum = PcdGet32 (PcdArmArchTimerVirtIntrNum); + TimerHypIntrNum = PcdGet32 (PcdArmArchTimerHypIntrNum); + TimerSecIntrNum = PcdGet32 (PcdArmArchTimerSecIntrNum); + TimerIntrNum = PcdGet32 (PcdArmArchTimerIntrNum); + } + // Install secure and Non-secure interrupt handlers // Note: Because it is not possible to determine the security state of the // CPU dynamically, we just install interrupt handler for both sec and non-sec // timer PPI - Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerVirtIntrNum), TimerInterruptHandler); + Status = gInterrupt->RegisterInterruptSource (gInterrupt, TimerVirtIntrNum, TimerInterruptHandler); ASSERT_EFI_ERROR (Status); // // The hypervisor timer interrupt may be omitted by implementations that // execute under virtualization. // - TimerHypIntrNum = PcdGet32 (PcdArmArchTimerHypIntrNum); if (TimerHypIntrNum != 0) { Status = gInterrupt->RegisterInterruptSource (gInterrupt, TimerHypIntrNum, TimerInterruptHandler); ASSERT_EFI_ERROR (Status); } - Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerSecIntrNum), TimerInterruptHandler); + Status = gInterrupt->RegisterInterruptSource (gInterrupt, TimerSecIntrNum, TimerInterruptHandler); ASSERT_EFI_ERROR (Status); - Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerIntrNum), TimerInterruptHandler); + Status = gInterrupt->RegisterInterruptSource (gInterrupt, TimerIntrNum, TimerInterruptHandler); ASSERT_EFI_ERROR (Status); // Set up default timer diff --git a/ArmPkg/Drivers/TimerDxe/TimerDxe.h b/ArmPkg/Drivers/TimerDxe/TimerDxe.h new file mode 100644 index 0000000000..98b2f9f74b --- /dev/null +++ b/ArmPkg/Drivers/TimerDxe/TimerDxe.h @@ -0,0 +1,18 @@ +/** @file +* +* Copyright (c) 2025, ARM Limited. All rights reserved. +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef TIMER_DXE_H_ +#define TIMER_DXE_H_ + +// Timer IntIDs are architecturally defined for GICv5 +#define GICV5_ARCH_TIMER_HYP_INTID 0x2000001a +#define GICV5_ARCH_TIMER_VIRT_INTID 0x2000001b +#define GICV5_ARCH_TIMER_HYP_VIRT_INTID 0x2000001c +#define GICV5_ARCH_TIMER_SEC_INTID 0x2000001d +#define GICV5_ARCH_TIMER_INTID 0x2000001e + +#endif // TIMER_DXE_H_