This adds an implementation of ArmGenericTimerCounterLib using the virtual architected generic timer.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org> --- .../ArmGenericTimerVirtCounterLib.c | 150 +++++++++++++++++++++ .../ArmGenericTimerVirtCounterLib.inf | 33 +++++ 2 files changed, 183 insertions(+) create mode 100644 ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.c create mode 100644 ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf diff --git a/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.c b/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.c new file mode 100644 index 000000000000..a3828f6dff0f --- /dev/null +++ b/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.c @@ -0,0 +1,150 @@ +/** @file + + Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR> + Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR> + + 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 <Library/ArmGenericTimerCounterLib.h> +#include <Library/ArmArchTimer.h> + +VOID +EFIAPI +ArmArchTimerEnableTimer ( + VOID + ) +{ + UINTN TimerCtrlReg; + + ArmArchTimerReadReg (CntvCtl, (VOID *)&TimerCtrlReg); + TimerCtrlReg |= ARM_ARCH_TIMER_ENABLE; + + // + // When running under KVM, we need to unmask the interrupt on the timer side + // as KVM will mask it when servicing the interrupt at the hypervisor level + // and delivering the virtual timer interrupt to the guest. Otherwise, the + // interrupt will fire again, trapping into the hypervisor again, etc. etc. + // This is scheduled to be fixed on the KVM side, but there is no harm in + // leaving this in once KVM gets fixed. + // + TimerCtrlReg &= ~ARM_ARCH_TIMER_IMASK; + ArmArchTimerWriteReg (CntvCtl, (VOID *)&TimerCtrlReg); +} + +VOID +EFIAPI +ArmArchTimerDisableTimer ( + VOID + ) +{ + UINTN TimerCtrlReg; + + ArmArchTimerReadReg (CntvCtl, (VOID *)&TimerCtrlReg); + TimerCtrlReg &= ~ARM_ARCH_TIMER_ENABLE; + ArmArchTimerWriteReg (CntvCtl, (VOID *)&TimerCtrlReg); +} + +VOID +EFIAPI +ArmArchTimerSetTimerFreq ( + IN UINTN FreqInHz + ) +{ + ArmArchTimerWriteReg (CntFrq, (VOID *)&FreqInHz); +} + +UINTN +EFIAPI +ArmArchTimerGetTimerFreq ( + VOID + ) +{ + UINTN ArchTimerFreq = 0; + ArmArchTimerReadReg (CntFrq, (VOID *)&ArchTimerFreq); + return ArchTimerFreq; +} + +UINTN +EFIAPI +ArmArchTimerGetTimerVal ( + VOID + ) +{ + UINTN ArchTimerVal; + ArmArchTimerReadReg (CntvTval, (VOID *)&ArchTimerVal); + + return ArchTimerVal; +} + + +VOID +EFIAPI +ArmArchTimerSetTimerVal ( + IN UINTN Val + ) +{ + ArmArchTimerWriteReg (CntvTval, (VOID *)&Val); +} + +UINT64 +EFIAPI +ArmArchTimerGetSystemCount ( + VOID + ) +{ + UINT64 SystemCount; + ArmArchTimerReadReg (CntvCt, (VOID *)&SystemCount); + + return SystemCount; +} + +UINTN +EFIAPI +ArmArchTimerGetTimerCtrlReg ( + VOID + ) +{ + UINTN Val; + + ArmArchTimerReadReg (CntvCtl, (VOID *)&Val); + + return Val; +} + +VOID +EFIAPI +ArmArchTimerSetTimerCtrlReg ( + UINTN Val + ) +{ + ArmArchTimerWriteReg (CntvCtl, (VOID *)&Val); +} + +UINT64 +EFIAPI +ArmArchTimerGetCompareVal ( + VOID + ) +{ + UINT64 Val; + ArmArchTimerReadReg (CntvCval, (VOID *)&Val); + + return Val; +} + +VOID +EFIAPI +ArmArchTimerSetCompareVal ( + IN UINT64 Val + ) +{ + ArmArchTimerWriteReg (CntvCval, (VOID *)&Val); +} diff --git a/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf b/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf new file mode 100644 index 000000000000..f2c015de3cce --- /dev/null +++ b/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf @@ -0,0 +1,33 @@ +#/** @file +# Implement ArmGenericTimerCounterLib using the virtual timer +# +# Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR> +# +# 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 = ArmGenericTimerVirtCounterLib + FILE_GUID = 3C0D77CC-4F27-49C8-B25C-2D01D81ED4D8 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmGenericTimerCounterLib + +[Sources] + ArmGenericTimerVirtCounterLib.c + +[Packages] + MdePkg/MdePkg.dec + ArmPkg/ArmPkg.dec + +[LibraryClasses] + ArmLib + BaseLib -- 1.8.3.2 ------------------------------------------------------------------------------ Slashdot TV. Video for Nerds. Stuff that matters. http://tv.slashdot.org/ _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel