From 967efdcdc3a3a22550563acb9ec77f565b3dbee0 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sat, 28 Feb 2015 20:24:57 +0000 Subject: [PATCH] ArmPkg: allow HYP timer interrupt to be omitted The DT binding for the ARM generic timer describes the secure, non-secure, virtual and hypervisor timer interrupts, respectively. However, under virtualization, only the virtual timer is usable, and the device tree may omit the hypervisor timer interrupt. (Other timer interrupts cannot be omitted simply due to the fact that the virtual timer is listed third) Contributed-under: TianoCore Contribution Agreement 1.0 Reviewed-by: Olivier Martin Reviewed-by: Laszlo Ersek Signed-off-by: Ard Biesheuvel Signed-off-by: Laszlo Ersek git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16953 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPkg/Drivers/TimerDxe/TimerDxe.c | 14 +++++++++++--- .../ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c | 6 +++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/ArmPkg/Drivers/TimerDxe/TimerDxe.c b/ArmPkg/Drivers/TimerDxe/TimerDxe.c index d0a819fc27..1169d426b2 100644 --- a/ArmPkg/Drivers/TimerDxe/TimerDxe.c +++ b/ArmPkg/Drivers/TimerDxe/TimerDxe.c @@ -369,7 +369,8 @@ TimerInitialize ( { EFI_HANDLE Handle = NULL; EFI_STATUS Status; - UINTN TimerCtrlReg; + UINTN TimerCtrlReg; + UINT32 TimerHypIntrNum; if (ArmIsArchTimerImplemented () == 0) { DEBUG ((EFI_D_ERROR, "ARM Architectural Timer is not available in the CPU, hence cann't use this Driver \n")); @@ -395,8 +396,15 @@ TimerInitialize ( Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerVirtIntrNum), TimerInterruptHandler); ASSERT_EFI_ERROR (Status); - Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerHypIntrNum), 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); ASSERT_EFI_ERROR (Status); diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c index be74d62ad7..274cdeb8c8 100644 --- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c +++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c @@ -452,7 +452,7 @@ InitializeVirtFdtDxe ( // hypervisor timers, in that order. // InterruptProp = fdt_getprop (DeviceTreeBase, Node, "interrupts", &Len); - ASSERT (Len == 48); + ASSERT (Len == 36 || Len == 48); SecIntrNum = fdt32_to_cpu (InterruptProp[0].Number) + (InterruptProp[0].Type ? 16 : 0); @@ -460,8 +460,8 @@ InitializeVirtFdtDxe ( + (InterruptProp[1].Type ? 16 : 0); VirtIntrNum = fdt32_to_cpu (InterruptProp[2].Number) + (InterruptProp[2].Type ? 16 : 0); - HypIntrNum = fdt32_to_cpu (InterruptProp[3].Number) - + (InterruptProp[3].Type ? 16 : 0); + HypIntrNum = Len < 48 ? 0 : fdt32_to_cpu (InterruptProp[3].Number) + + (InterruptProp[3].Type ? 16 : 0); DEBUG ((EFI_D_INFO, "Found Timer interrupts %d, %d, %d, %d\n", SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum)); -- 2.39.2