ArmPkg: TimerDxe: Add support for GICv5 PPIs
GICv5 uses a different ID scheme for interrupt numbers to previous GICs; the top bits indicate the type of interrupt (PPI/SPI/LPI). Update TimerDxe to use the new ID scheme for GICv5. As the timer PPIs are architected for GICv5 they should be the same on all GICv5 platforms. Signed-off-by: Sarah Walker <Sarah.Walker2@arm.com>
This commit is contained in:
committed by
mergify[bot]
parent
b7fdcbbeb8
commit
b762965bda
@@ -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
|
||||
|
||||
18
ArmPkg/Drivers/TimerDxe/TimerDxe.h
Normal file
18
ArmPkg/Drivers/TimerDxe/TimerDxe.h
Normal file
@@ -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_
|
||||
Reference in New Issue
Block a user