diff --git a/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.c b/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.c new file mode 100644 index 0000000000..6e7461c6b2 --- /dev/null +++ b/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.c @@ -0,0 +1,87 @@ +/** @file + FDT client library for ARM's TimerDxe + + Copyright (c) 2016, Linaro Ltd. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include +#include +#include + +#include + +#pragma pack (1) +typedef struct { + UINT32 Type; + UINT32 Number; + UINT32 Flags; +} INTERRUPT_PROPERTY; +#pragma pack () + +RETURN_STATUS +EFIAPI +ArmVirtTimerFdtClientLibConstructor ( + VOID + ) +{ + EFI_STATUS Status; + FDT_CLIENT_PROTOCOL *FdtClient; + CONST INTERRUPT_PROPERTY *InterruptProp; + UINT32 PropSize; + INT32 SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum; + + Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL, + (VOID **)&FdtClient); + ASSERT_EFI_ERROR (Status); + + Status = FdtClient->FindCompatibleNodeProperty (FdtClient, "arm,armv7-timer", + "interrupts", (CONST VOID **)&InterruptProp, + &PropSize); + if (Status == EFI_NOT_FOUND) { + Status = FdtClient->FindCompatibleNodeProperty (FdtClient, + "arm,armv8-timer", "interrupts", + (CONST VOID **)&InterruptProp, + &PropSize); + } + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // - interrupts : Interrupt list for secure, non-secure, virtual and + // hypervisor timers, in that order. + // + ASSERT (PropSize == 36 || PropSize == 48); + + SecIntrNum = SwapBytes32 (InterruptProp[0].Number) + + (InterruptProp[0].Type ? 16 : 0); + IntrNum = SwapBytes32 (InterruptProp[1].Number) + + (InterruptProp[1].Type ? 16 : 0); + VirtIntrNum = SwapBytes32 (InterruptProp[2].Number) + + (InterruptProp[2].Type ? 16 : 0); + HypIntrNum = PropSize < 48 ? 0 : SwapBytes32 (InterruptProp[3].Number) + + (InterruptProp[3].Type ? 16 : 0); + + DEBUG ((EFI_D_INFO, "Found Timer interrupts %d, %d, %d, %d\n", + SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum)); + + PcdSet32 (PcdArmArchTimerSecIntrNum, SecIntrNum); + PcdSet32 (PcdArmArchTimerIntrNum, IntrNum); + PcdSet32 (PcdArmArchTimerVirtIntrNum, VirtIntrNum); + PcdSet32 (PcdArmArchTimerHypIntrNum, HypIntrNum); + + return EFI_SUCCESS; +} diff --git a/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.inf b/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.inf new file mode 100644 index 0000000000..bc7089f103 --- /dev/null +++ b/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.inf @@ -0,0 +1,49 @@ +#/** @file +# FDT client library for ARM's TimerDxe +# +# Copyright (c) 2016, Linaro Ltd. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ArmVirtTimerFdtClientLib + FILE_GUID = 77EA80CA-2EFB-4AB4-8567-230D968F6B37 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmVirtTimerFdtClientLib|DXE_DRIVER + CONSTRUCTOR = ArmVirtTimerFdtClientLibConstructor + +[Sources] + ArmVirtTimerFdtClientLib.c + +[Packages] + ArmPkg/ArmPkg.dec + ArmVirtPkg/ArmVirtPkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + PcdLib + UefiBootServicesTableLib + +[Protocols] + gFdtClientProtocolGuid ## CONSUMES + +[Pcd] + gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum + gArmTokenSpaceGuid.PcdArmArchTimerIntrNum + gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum + gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum + +[Depex] + gFdtClientProtocolGuid