From: Ard Biesheuvel Date: Tue, 9 Sep 2014 16:07:43 +0000 (+0000) Subject: ArmPkg: add ArmGenericTimerCounterLib implementation using virtual timer X-Git-Tag: edk2-stable201903~10919 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=bcf37cf6002ba538b63172a496b142ab322eff95 ArmPkg: add ArmGenericTimerCounterLib implementation using virtual timer This adds an implementation of ArmGenericTimerCounterLib using the virtual architected generic timer. Contributed-under: TianoCore Contribution Agreement 1.0 Acked-by: Laszlo Ersek Signed-off-by: Ard Biesheuvel Signed-off-by: Olivier Martin git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16076 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index c031f21e7c..4a02517c4b 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -125,6 +125,7 @@ ArmPkg/Drivers/TimerDxe/TimerDxe.inf ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf + ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf diff --git a/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.c b/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.c new file mode 100644 index 0000000000..f99c8525b9 --- /dev/null +++ b/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.c @@ -0,0 +1,149 @@ +/** @file + + Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.
+ Copyright (c) 2014, 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 + +VOID +EFIAPI +ArmGenericTimerEnableTimer ( + 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 +ArmGenericTimerDisableTimer ( + VOID + ) +{ + UINTN TimerCtrlReg; + + ArmArchTimerReadReg (CntvCtl, (VOID *)&TimerCtrlReg); + TimerCtrlReg &= ~ARM_ARCH_TIMER_ENABLE; + ArmArchTimerWriteReg (CntvCtl, (VOID *)&TimerCtrlReg); +} + +VOID +EFIAPI +ArmGenericTimerSetTimerFreq ( + IN UINTN FreqInHz + ) +{ + ArmArchTimerWriteReg (CntFrq, (VOID *)&FreqInHz); +} + +UINTN +EFIAPI +ArmGenericTimerGetTimerFreq ( + VOID + ) +{ + UINTN ArchTimerFreq = 0; + ArmArchTimerReadReg (CntFrq, (VOID *)&ArchTimerFreq); + return ArchTimerFreq; +} + +UINTN +EFIAPI +ArmGenericTimerGetTimerVal ( + VOID + ) +{ + UINTN ArchTimerValue; + ArmArchTimerReadReg (CntvTval, (VOID *)&ArchTimerValue); + + return ArchTimerValue; +} + + +VOID +EFIAPI +ArmGenericTimerSetTimerVal ( + IN UINTN Value + ) +{ + ArmArchTimerWriteReg (CntvTval, (VOID *)&Value); +} + +UINT64 +EFIAPI +ArmGenericTimerGetSystemCount ( + VOID + ) +{ + UINT64 SystemCount; + ArmArchTimerReadReg (CntvCt, (VOID *)&SystemCount); + + return SystemCount; +} + +UINTN +EFIAPI +ArmGenericTimerGetTimerCtrlReg ( + VOID + ) +{ + UINTN Value; + ArmArchTimerReadReg (CntvCtl, (VOID *)&Value); + + return Value; +} + +VOID +EFIAPI +ArmGenericTimerSetTimerCtrlReg ( + UINTN Value + ) +{ + ArmArchTimerWriteReg (CntvCtl, (VOID *)&Value); +} + +UINT64 +EFIAPI +ArmGenericTimerGetCompareVal ( + VOID + ) +{ + UINT64 Value; + ArmArchTimerReadReg (CntvCval, (VOID *)&Value); + + return Value; +} + +VOID +EFIAPI +ArmGenericTimerSetCompareVal ( + IN UINT64 Value + ) +{ + ArmArchTimerWriteReg (CntvCval, (VOID *)&Value); +} diff --git a/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf b/ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf new file mode 100644 index 0000000000..9267dc3434 --- /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.
+# +# 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