summaryrefslogtreecommitdiff
path: root/ArmPkg/Drivers/TimerDxe
diff options
context:
space:
mode:
Diffstat (limited to 'ArmPkg/Drivers/TimerDxe')
-rw-r--r--ArmPkg/Drivers/TimerDxe/TimerDxe.c24
-rw-r--r--ArmPkg/Drivers/TimerDxe/TimerDxe.h18
2 files changed, 38 insertions, 4 deletions
diff --git a/ArmPkg/Drivers/TimerDxe/TimerDxe.c b/ArmPkg/Drivers/TimerDxe/TimerDxe.c
index 37859e1..b7f5ecc 100644
--- a/ArmPkg/Drivers/TimerDxe/TimerDxe.c
+++ b/ArmPkg/Drivers/TimerDxe/TimerDxe.c
@@ -22,6 +22,8 @@
#include <Protocol/Timer.h>
#include <Protocol/HardwareInterrupt.h>
+#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 0000000..98b2f9f
--- /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_