/** @file * * Copyright (c) 2011-2013, 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/AArch64.h> #include <Library/BaseMemoryLib.h> #include <Library/ArmLib.h> #include <Library/BaseLib.h> #include <Library/DebugLib.h> #include "AArch64Lib.h" #include "ArmLibPrivate.h" #include <Library/ArmArchTimer.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 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 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); } }