diff options
author | oliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524> | 2011-09-27 16:35:16 +0000 |
---|---|---|
committer | oliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524> | 2011-09-27 16:35:16 +0000 |
commit | da9675a241ab9856377b9bd63504b2d5333b3c7a (patch) | |
tree | 15c8f64a5dbb56ef78dc059bbaa436c6e374ce2f /ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimer.c | |
parent | 0c0e7ef451a3f74d6756d6ec65685114b3dacea8 (diff) | |
download | edk2-platforms-da9675a241ab9856377b9bd63504b2d5333b3c7a.tar.xz |
ArmPkg: Add ARM Architectural Timer support
ARM Architectural Timer support is defined by the ARM Generic Timer Specification.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12455 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimer.c')
-rw-r--r-- | ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimer.c | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimer.c b/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimer.c new file mode 100644 index 0000000000..1cba12d300 --- /dev/null +++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7ArchTimer.c @@ -0,0 +1,275 @@ +/** @file +* +* Copyright (c) 2011, ARM Limited. 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 <Uefi.h> +#include <Chipset/ArmV7.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/ArmLib.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include "ArmV7Lib.h" +#include "ArmLibPrivate.h" +#include <Library/ArmV7ArchTimerLib.h> + +VOID +EFIAPI +ArmArchTimerReadReg ( + IN ARM_ARCH_TIMER_REGS Reg, + OUT VOID *DstBuf + ) +{ + // Check if the Generic/Architecture timer is implemented + if (ArmIsArchTimerImplemented ()) { + + switch (Reg) { + + case CntFrq: + *((UINTN *)DstBuf) = ArmReadCntFrq (); + break; + + case CntPct: + *((UINT64 *)DstBuf) = ArmReadCntPct (); + break; + + case CntkCtl: + *((UINTN *)DstBuf) = ArmReadCntkCtl(); + break; + + case CntpTval: + *((UINTN *)DstBuf) = ArmReadCntpTval (); + break; + + case CntpCtl: + *((UINTN *)DstBuf) = ArmReadCntpCtl (); + break; + + case CntvTval: + *((UINTN *)DstBuf) = ArmReadCntvTval (); + break; + + case CntvCtl: + *((UINTN *)DstBuf) = ArmReadCntvCtl (); + break; + + case CntvCt: + *((UINT64 *)DstBuf) = ArmReadCntvCt (); + break; + + case CntpCval: + *((UINT64 *)DstBuf) = ArmReadCntpCval (); + break; + + case CntvCval: + *((UINT64 *)DstBuf) = ArmReadCntvCval (); + break; + + case CntvOff: + *((UINT64 *)DstBuf) = ArmReadCntvOff (); + break; + + case CnthCtl: + case CnthpTval: + case CnthpCtl: + case CnthpCval: + DEBUG ((EFI_D_ERROR, "The register is related to Hyperviser Mode. Can't perform requested operation\n ")); + break; + + default: + DEBUG ((EFI_D_ERROR, "Unknown ARM Generic Timer register %x. \n ", Reg)); + } + } else { + DEBUG ((EFI_D_ERROR, "Attempt to read ARM Generic Timer registers. But ARM Generic Timer extension is not implemented \n ")); + ASSERT (0); + } +} + +VOID +EFIAPI +ArmArchTimerWriteReg ( + IN ARM_ARCH_TIMER_REGS Reg, + IN VOID *SrcBuf + ) +{ + // Check if the Generic/Architecture timer is implemented + if (ArmIsArchTimerImplemented ()) { + + switch (Reg) { + + case CntFrq: + ArmWriteCntFrq (*((UINTN *)SrcBuf)); + break; + + case CntPct: + DEBUG ((EFI_D_ERROR, "Can't write to Read Only Register: CNTPCT \n")); + break; + + case CntkCtl: + ArmWriteCntkCtl (*((UINTN *)SrcBuf)); + break; + + case CntpTval: + ArmWriteCntpTval (*((UINTN *)SrcBuf)); + break; + + case CntpCtl: + ArmWriteCntpCtl (*((UINTN *)SrcBuf)); + break; + + case CntvTval: + ArmWriteCntvTval (*((UINTN *)SrcBuf)); + break; + + case CntvCtl: + ArmWriteCntvCtl (*((UINTN *)SrcBuf)); + break; + + case CntvCt: + DEBUG ((EFI_D_ERROR, "Can't write to Read Only Register: CNTVCT \n")); + break; + + case CntpCval: + ArmWriteCntpCval (*((UINT64 *)SrcBuf) ); + break; + + case CntvCval: + ArmWriteCntvCval (*((UINT64 *)SrcBuf) ); + break; + + case CntvOff: + ArmWriteCntvOff (*((UINT64 *)SrcBuf)); + break; + + case CnthCtl: + case CnthpTval: + case CnthpCtl: + case CnthpCval: + DEBUG ((EFI_D_ERROR, "The register is related to Hypervisor Mode. Can't perform requested operation\n ")); + break; + + default: + DEBUG ((EFI_D_ERROR, "Unknown ARM Generic Timer register %x. \n ", Reg)); + } + } else { + DEBUG ((EFI_D_ERROR, "Attempt to write to ARM Generic Timer registers. But ARM Generic Timer extension is not implemented \n ")); + ASSERT (0); + } +} + +VOID +EFIAPI +ArmArchTimerEnableTimer ( + VOID + ) +{ + UINTN TimerCtrlReg; + + ArmArchTimerReadReg (CntpCtl, (VOID *)&TimerCtrlReg); + TimerCtrlReg |= ARM_ARCH_TIMER_ENABLE; + ArmArchTimerWriteReg (CntpCtl, (VOID *)&TimerCtrlReg); +} + +VOID +EFIAPI +ArmArchTimerDisableTimer ( + VOID + ) +{ + UINTN TimerCtrlReg; + + ArmArchTimerReadReg (CntpCtl, (VOID *)&TimerCtrlReg); + TimerCtrlReg &= ~ARM_ARCH_TIMER_ENABLE; + ArmArchTimerWriteReg (CntpCtl, (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 (CntpTval, (VOID *)&ArchTimerVal); + return ArchTimerVal; +} + + +VOID +EFIAPI +ArmArchTimerSetTimerVal ( + IN UINTN Val + ) +{ + ArmArchTimerWriteReg (CntpTval, (VOID *)&Val); +} + +UINT64 +EFIAPI +ArmArchTimerGetSystemCount ( + VOID + ) +{ + UINT64 SystemCount; + ArmArchTimerReadReg (CntPct, (VOID *)&SystemCount); + return SystemCount; +} + +UINTN +EFIAPI +ArmArchTimerGetTimerCtrlReg ( + VOID + ) +{ + UINTN Val; + ArmArchTimerReadReg (CntpCtl, (VOID *)&Val); + return Val; +} + +VOID +EFIAPI +ArmArchTimerSetTimerCtrlReg ( + UINTN Val + ) +{ + ArmArchTimerWriteReg (CntpCtl, (VOID *)&Val); +} + +VOID +EFIAPI +ArmArchTimerSetCompareVal ( + IN UINT64 Val + ) +{ + ArmArchTimerWriteReg (CntpCval, (VOID *)&Val); +} |